Verified Commit 236f6570 authored by Camil Staps's avatar Camil Staps 🙂

Resolve bug with pushD: add label_specials struct to keep track of string addresses of descriptors

parent cd225fb2
Pipeline #43193 passed with stages
in 13 minutes and 51 seconds
......@@ -183,6 +183,7 @@ struct label *enter_label(char *label_name) {
new_label_p->label_id=label_id++;
new_label_p->label_module_n=module_n;
new_label_p->label_offset=-1;
new_label_p->label_specials=NULL;
label_node_p->label_node_label_p=new_label_p;
return new_label_p;
......@@ -210,11 +211,35 @@ struct label *enter_label(char *label_name) {
strcpy(new_label_p->label_name, label_name);
new_label_p->label_module_n = module_n;
new_label_p->label_offset = -1;
new_label_p->label_specials=NULL;
*label_node_pp = new_label_node_p;
return new_label_p;
}
void add_label_special_offset_to (struct label *label,int32_t flags,int32_t location)
{
struct label_specials *specials=safe_malloc (sizeof (struct label_specials));
specials->label_specials_flags=flags;
specials->label_specials_offset=location - (label->label_offset & -2);
specials->label_specials_next=label->label_specials;
label->label_specials=specials;
}
int32_t find_label_special_offset (struct label *label,int32_t flags)
{
struct label_specials *specials=label->label_specials;
while (specials!=NULL){
if (specials->label_specials_flags & flags)
return specials->label_specials_offset;
specials=specials->label_specials_next;
}
EPRINTF ("internal error: find_label_special_offset (%s,%d) not found\n",label->label_name,flags);
exit (-1);
}
#ifdef LINKER
struct label *find_label(char *label_name) {
struct label_node *label_node_p=labels;
......@@ -359,6 +384,7 @@ struct relocation *add_code_relocation(struct label *label, uint32_t offset) {
relocation_p=&pgrm.code_relocations[pgrm.code_reloc_size++];
relocation_p->relocation_offset=offset;
relocation_p->relocation_flags=0;
relocation_p->relocation_label=label;
return relocation_p;
......@@ -374,6 +400,7 @@ struct relocation *add_data_relocation(struct label *label, uint32_t offset) {
relocation_p=&pgrm.data_relocations[pgrm.data_reloc_size++];
relocation_p->relocation_offset=offset;
relocation_p->relocation_flags=0;
relocation_p->relocation_label=label;
return relocation_p;
......@@ -395,6 +422,14 @@ void store_code_label_value(char *label_name,int32_t offset) {
store_code_elem(2, offset);
}
void store_code_label_value_with_flags (char *label_name,int32_t flags,int32_t offset)
{
struct label *label=enter_label (label_name);
struct relocation *relocation=add_code_relocation (label,pgrm.code_size);
relocation->relocation_flags=flags;
store_code_elem (2,offset);
}
static void store_data_label_value_of_label(struct label *label,uint32_t offset) {
add_data_relocation(label, pgrm.data_size);
store_data_l(offset);
......@@ -461,6 +496,14 @@ void add_instruction_label(uint16_t i,char *label_name) {
store_code_label_value(label_name,0);
}
void add_instruction_label_flags (uint16_t i,char *label_name,int32_t flags) {
if (list_code || i>max_implemented_instruction_n)
printf ("%d\t%s %s\n",pgrm.code_size,instruction_name (i),label_name);
store_code_elem (BYTEWIDTH_INSTRUCTION,i);
store_code_label_value_with_flags (label_name,flags,0);
}
void add_instruction_label_offset(uint16_t i,char *label_name,uint32_t offset) {
if (list_code || i>max_implemented_instruction_n)
printf("%d\t%s %s%+d\n",pgrm.code_size,instruction_name (i),label_name,offset);
......@@ -2823,7 +2866,7 @@ void code_pushC0_pop_a1() {
}
void code_pushD(char *descriptor) {
add_instruction_label(CpushD,descriptor);
add_instruction_label_flags (CpushD,descriptor,LABEL_SPECIAL_STRING);
}
void code_pushD_a(int a_offset) {
......@@ -4432,6 +4475,8 @@ struct label *code_descriptor
if (list_code)
printf("%d\t.data4 0\n",pgrm.data_size<<2);
store_data_l(0);
add_label_special_offset_to (label,LABEL_SPECIAL_STRING,pgrm.data_size<<2);
store_string(descriptor_name,descriptor_name_length,0);
if (list_code)
......@@ -4481,6 +4526,7 @@ void code_desc0(char label_name[],int desc0_number,char descriptor_name[],int de
if (list_code)
printf("%d\t.data4 0\n",pgrm.data_size<<2);
store_data_l(0);
add_label_special_offset_to (label,LABEL_SPECIAL_STRING,pgrm.data_size<<2);
store_string(descriptor_name,descriptor_name_length,0);
if (list_code)
......@@ -4517,6 +4563,7 @@ void code_descn(char label_name[],char node_entry_label_name[],int arity,int laz
if (list_code)
printf("%d\t.data4 0\n",pgrm.data_size<<2);
store_data_l(0);
add_label_special_offset_to (label,LABEL_SPECIAL_STRING,pgrm.data_size<<2);
store_string(descriptor_name,descriptor_name_length,0);
if (list_code)
......@@ -4561,6 +4608,7 @@ void code_descs(char label_name[],char node_entry_label_name[],char *result_desc
if (list_code)
printf("%d\t.data4 0\n",pgrm.data_size<<2);
store_data_l(0);
add_label_special_offset_to (label,LABEL_SPECIAL_STRING,pgrm.data_size<<2);
store_string(descriptor_name,descriptor_name_length,0);
if (list_code)
......@@ -4625,6 +4673,7 @@ void code_module(char label_name[],char string[],uint32_t string_length) {
}
label->label_offset=(pgrm.data_size<<2)+1;
add_label_special_offset_to (label,LABEL_SPECIAL_STRING,pgrm.data_size<<2);
store_string(string,string_length,0);
if (list_code)
......@@ -4825,6 +4874,7 @@ void code_string(char label_name[],char string[],int string_length) {
}
label->label_offset=(pgrm.data_size<<2)+1;
add_label_special_offset_to (label,LABEL_SPECIAL_STRING,pgrm.data_size<<2);
store_string(string,string_length,0);
if (list_code)
......@@ -4857,6 +4907,30 @@ static void count_and_renumber_labels(struct label_node *node, int *start, int *
count_and_renumber_labels(node->label_node_right, start, end);
}
static void resolve_flagged_code_relocations (void)
{
unsigned int i;
for (i=0; i<pgrm.code_reloc_size; i++){
struct relocation *relocation=&pgrm.code_relocations[i];
if (relocation->relocation_flags==0)
continue;
int offset=find_label_special_offset (relocation->relocation_label,relocation->relocation_flags);
pgrm.code[relocation->relocation_offset].value+=offset;
}
}
static void resolve_flagged_data_relocations (void)
{
unsigned int i;
for (i=0; i<pgrm.data_reloc_size; i++){
struct relocation *relocation=&pgrm.data_relocations[i];
if (relocation->relocation_flags==0)
continue;
int offset=find_label_special_offset (relocation->relocation_label,relocation->relocation_flags);
pgrm.data[relocation->relocation_offset]+=offset;
}
}
#ifndef LINK_CLEAN_RUNTIME
static void print_code(int segment_size,struct word *segment,FILE *program_file) {
if (segment_size <= 0)
......@@ -4961,6 +5035,9 @@ void write_program(FILE *program_file) {
fwrite(&temp, sizeof(temp), 1, program_file);
}
resolve_flagged_code_relocations();
resolve_flagged_data_relocations();
print_code(pgrm.code_size,pgrm.code,program_file);
print_strings(pgrm.strings_size,pgrm.strings,program_file);
print_data(pgrm.data_size,pgrm.data,program_file);
......@@ -5059,6 +5136,9 @@ char *write_program_to_string(uint32_t *bytes_needed) {
ptr=print_global_labels_to_string(labels, ptr);
ptr=print_local_labels_to_string(labels, ptr);
resolve_flagged_code_relocations();
resolve_flagged_data_relocations();
for (int i=0; i<pgrm.code_reloc_size; i++) {
memcpy(ptr, &pgrm.code_relocations[i].relocation_offset, sizeof(uint32_t));
memcpy(ptr+4, &pgrm.code_relocations[i].relocation_label->label_id, sizeof(uint32_t));
......
......@@ -7,11 +7,20 @@
extern int is_32_bit;
#define LABEL_SPECIAL_STRING 1
struct label_specials {
int32_t label_specials_flags;
int32_t label_specials_offset;
struct label_specials *label_specials_next;
};
struct label {
char *label_name;
int32_t label_offset; /* multiple of 2, lowest bit indicates code(0) or data(1) */
int32_t label_id;
int32_t label_module_n;
struct label_specials *label_specials;
};
struct label_node {
......@@ -22,6 +31,7 @@ struct label_node {
typedef struct relocation {
uint32_t relocation_offset;
uint32_t relocation_flags;
struct label *relocation_label;
} relocation;
......
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