Verified Commit 64986e36 authored by Camil Staps's avatar Camil Staps 🚀

Add magic number and version number to bytecode format (#60)

parent 183e15d7
Pipeline #17877 passed with stages
in 17 minutes and 31 seconds
......@@ -4486,6 +4486,13 @@ static void print_local_labels(struct label_node *node, FILE *program_file) {
}
void write_program(FILE *program_file) {
uint32_t temp;
temp=ABC_MAGIC_NUMBER;
fwrite(&temp, sizeof(temp), 1, program_file);
temp=10*4;
fwrite(&temp, sizeof(temp), 1, program_file);
temp=ABC_VERSION;
fwrite(&temp, sizeof(temp), 1, program_file);
fwrite(&pgrm.code_size, sizeof(pgrm.code_size), 1, program_file);
fwrite(&pgrm.words_in_strings, sizeof(pgrm.words_in_strings), 1, program_file);
fwrite(&pgrm.strings_size, sizeof(pgrm.strings_size), 1, program_file);
......@@ -4502,8 +4509,8 @@ void write_program(FILE *program_file) {
if (start_label!=NULL) {
fwrite(&start_label->label_id, sizeof(uint32_t), 1, program_file);
} else {
uint32_t nil=-1;
fwrite(&nil, sizeof(nil), 1, program_file);
temp=-1;
fwrite(&temp, sizeof(temp), 1, program_file);
}
print_code(pgrm.code_size,pgrm.code,program_file);
......@@ -4564,7 +4571,7 @@ char *write_program_to_string(uint32_t *bytes_needed) {
count_and_renumber_labels(labels, &start, &end);
*bytes_needed =
9*sizeof(uint32_t) +
12*sizeof(uint32_t) +
pgrm.code_byte_size +
sizeof(uint32_t)*pgrm.strings_size +
sizeof(uint64_t)*pgrm.data_size +
......@@ -4573,17 +4580,20 @@ char *write_program_to_string(uint32_t *bytes_needed) {
sizeof(uint32_t)*2*(pgrm.code_reloc_size+pgrm.data_reloc_size);
char *bytecode=safe_malloc(*bytes_needed);
((uint32_t*)bytecode)[0]=pgrm.code_size;
((uint32_t*)bytecode)[1]=pgrm.words_in_strings;
((uint32_t*)bytecode)[2]=pgrm.strings_size;
((uint32_t*)bytecode)[3]=pgrm.data_size;
((uint32_t*)bytecode)[4]=label_id;
((uint32_t*)bytecode)[5]=global_label_string_count;
((uint32_t*)bytecode)[6]=pgrm.code_reloc_size;
((uint32_t*)bytecode)[7]=pgrm.data_reloc_size;
((uint32_t*)bytecode)[8]=start_label==NULL ? -1 : start_label->label_id;
char *ptr=(char*)&((uint32_t*)bytecode)[9];
((uint32_t*)bytecode)[ 0]=ABC_MAGIC_NUMBER;
((uint32_t*)bytecode)[ 1]=10*4;
((uint32_t*)bytecode)[ 2]=ABC_VERSION;
((uint32_t*)bytecode)[ 3]=pgrm.code_size;
((uint32_t*)bytecode)[ 4]=pgrm.words_in_strings;
((uint32_t*)bytecode)[ 5]=pgrm.strings_size;
((uint32_t*)bytecode)[ 6]=pgrm.data_size;
((uint32_t*)bytecode)[ 7]=label_id;
((uint32_t*)bytecode)[ 8]=global_label_string_count;
((uint32_t*)bytecode)[ 9]=pgrm.code_reloc_size;
((uint32_t*)bytecode)[10]=pgrm.data_reloc_size;
((uint32_t*)bytecode)[11]=start_label==NULL ? -1 : start_label->label_id;
char *ptr=(char*)&((uint32_t*)bytecode)[12];
for (int i=0; i<pgrm.code_size; i++) {
memcpy(ptr, &pgrm.code[i].value, pgrm.code[i].width);
ptr+=pgrm.code[i].width;
......
......@@ -169,7 +169,9 @@ void shift_address(BC_WORD *addr) {
* 0: success
* 1: unexpected end of string/file
* 2: illegal instruction
* 3: internal state machine error */
* 3: internal state machine error
* 4: wrong magic number
* 5: wrong version number */
int parse_program(struct parser *state, struct char_provider *cp) {
char elem8;
int16_t elem16;
......@@ -207,8 +209,26 @@ int parse_program(struct parser *state, struct char_provider *cp) {
while (state->state != PS_end) {
switch (state->state) {
case PS_init:
{
uint32_t header_length;
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
if (elem32 != ABC_MAGIC_NUMBER)
return 4;
if (provide_chars(&header_length, sizeof(header_length), 1, cp) < 0)
return 1;
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
header_length-=4;
if (elem32 != ABC_VERSION)
return 5;
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
header_length-=4;
#ifdef LINKER
state->code_size = elem32;
#else
......@@ -218,6 +238,7 @@ int parse_program(struct parser *state, struct char_provider *cp) {
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
header_length-=4;
#ifdef LINKER
add_words_in_strings(elem32);
#elif defined(INTERPRETER) && WORD_WIDTH==32
......@@ -226,6 +247,7 @@ int parse_program(struct parser *state, struct char_provider *cp) {
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
header_length-=4;
state->strings_size = elem32;
#if defined(INTERPRETER) && WORD_WIDTH == 32
/* Allocate one more to prevent reading out of bounds in PS_data */
......@@ -235,6 +257,7 @@ int parse_program(struct parser *state, struct char_provider *cp) {
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
header_length-=4;
#ifdef LINKER
state->data_size = elem32;
#else
......@@ -250,26 +273,40 @@ int parse_program(struct parser *state, struct char_provider *cp) {
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
header_length-=4;
state->program->symbol_table_size = elem32;
state->program->symbol_table = safe_malloc(elem32 * sizeof(struct symbol));
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
header_length-=4;
state->program->symbols = safe_malloc(elem32 + state->program->symbol_table_size);
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
header_length-=4;
state->code_reloc_size = elem32;
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
header_length-=4;
state->data_reloc_size = elem32;
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
header_length-=4;
state->program->start_symbol_id = elem32;
while (header_length >= sizeof(elem32)) {
if (provide_chars(&elem32, sizeof(elem32), 1, cp) < 0)
return 1;
header_length -= sizeof(elem32);
}
if (header_length > 0 && provide_chars(&elem32, header_length, 1, cp) < 0)
return 1;
next_state(state);
break;
}
case PS_code: {
if (provide_chars(&elem16, sizeof(elem16), 1, cp) < 0)
return 1;
......
......@@ -25,3 +25,6 @@
typedef int64_t CleanInt;
#define BCGEN_INSTRUCTION_TABLE_SIZE 512
#define ABC_MAGIC_NUMBER 0x2a434241
#define ABC_VERSION 1
......@@ -437,18 +437,27 @@ static struct s_label *find_label_by_name(const char *name) {
void prepare_strip_bytecode(uint32_t *bytecode, int activate_start_label) {
export_exported_labels=0;
uint32_t code_size=bytecode[0];
/*uint32_t words_in_strings=bytecode[1];*/
uint32_t strings_size=bytecode[2];
uint32_t data_size=bytecode[3];
n_labels=bytecode[4];
/*uint32_t global_label_string_count=bytecode[5];*/
code_reloc_size=bytecode[6];
data_reloc_size=bytecode[7];
uint32_t start_label_id=bytecode[8];
if (bytecode[0]!=ABC_MAGIC_NUMBER) {
EPRINTF("file to strip does not start with right magic number\n");
EXIT(NULL,-1);
}
code=&((uint8_t*)bytecode)[bytecode[1]+8];
if (bytecode[2]!=ABC_VERSION) {
EPRINTF("file to strip ABC* version does not match\n");
EXIT(NULL,-1);
}
uint32_t code_size=bytecode[3];
/*uint32_t words_in_strings=bytecode[4];*/
uint32_t strings_size=bytecode[5];
uint32_t data_size=bytecode[6];
n_labels=bytecode[7];
/*uint32_t global_label_string_count=bytecode[8];*/
code_reloc_size=bytecode[9];
data_reloc_size=bytecode[10];
uint32_t start_label_id=bytecode[11];
code_indices=safe_malloc(sizeof(struct code_index)*code_size);
code=(uint8_t*)&bytecode[9];
int ci=0;
int i=0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment