summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgaas.c623
1 files changed, 478 insertions, 145 deletions
diff --git a/cgaas.c b/cgaas.c
index 626650d..69320d2 100644
--- a/cgaas.c
+++ b/cgaas.c
@@ -21,6 +21,7 @@
#ifdef LINUX_ELF
# define ELF
+# define ELF_RELA
#endif
#if defined (_WINDOWS_) || defined (ELF)
@@ -81,12 +82,12 @@
struct object_label {
struct object_label * next;
union {
- unsigned long offset; /* CODE_CONTROL_SECTION,DATA_CONTROL_SECTION */
+ ULONG offset; /* CODE_CONTROL_SECTION,DATA_CONTROL_SECTION */
struct label * label; /* IMPORTED_LABEL,EXPORTED_CODE_LABEL */
} object_label_u1;
union {
- unsigned long length; /* CODE_CONTROL_SECTION,DATA_CONTROL_SECTION */
- unsigned long string_offset; /* IMPORTED_LABEL,EXPORTED_CODE_LABEL */
+ ULONG length; /* CODE_CONTROL_SECTION,DATA_CONTROL_SECTION */
+ ULONG string_offset; /* IMPORTED_LABEL,EXPORTED_CODE_LABEL */
} object_label_u2;
int object_label_number;
#ifdef FUNCTION_LEVEL_LINKING
@@ -169,6 +170,25 @@ static void write_l (int c)
fputc (c>>24,output_file);
}
+static void write_q (int c)
+{
+ fputc (c,output_file);
+ fputc (c>>8,output_file);
+ fputc (c>>16,output_file);
+ fputc (c>>24,output_file);
+ if (c>=0){
+ fputc (0,output_file);
+ fputc (0,output_file);
+ fputc (0,output_file);
+ fputc (0,output_file);
+ } else {
+ fputc (-1,output_file);
+ fputc (-1,output_file);
+ fputc (-1,output_file);
+ fputc (-1,output_file);
+ }
+}
+
#define LONG_WORD_RELOCATION 0
#define CALL_RELOCATION 1
#define BRANCH_RELOCATION 2
@@ -184,7 +204,10 @@ static void write_l (int c)
struct relocation {
struct relocation * next;
- unsigned long relocation_offset;
+ ULONG relocation_offset;
+#ifdef ELF_RELA
+ LONG relocation_addend;
+#endif
union {
struct {
WORD s_align1;
@@ -568,7 +591,29 @@ static void store_label_in_code_section (struct label *label)
new_relocation->relocation_label=label;
new_relocation->relocation_offset=CURRENT_CODE_OFFSET-4;
new_relocation->relocation_kind=LONG_WORD_RELOCATION;
+#ifdef ELF_RELA
+ new_relocation->relocation_addend=0;
+#endif
+}
+
+#ifdef ELF_RELA
+static void store_label_plus_offset_in_code_section (struct label *label,int offset)
+{
+ struct relocation *new_relocation;
+
+ new_relocation=fast_memory_allocate_type (struct relocation);
+ ++n_code_relocations;
+
+ *last_code_relocation_l=new_relocation;
+ last_code_relocation_l=&new_relocation->next;
+ new_relocation->next=NULL;
+
+ new_relocation->relocation_label=label;
+ new_relocation->relocation_offset=CURRENT_CODE_OFFSET-4;
+ new_relocation->relocation_kind=LONG_WORD_RELOCATION;
+ new_relocation->relocation_addend=offset;
}
+#endif
static void store_relative_label_offset_in_code_section (struct label *label)
{
@@ -584,13 +629,39 @@ static void store_relative_label_offset_in_code_section (struct label *label)
new_relocation->relocation_label=label;
new_relocation->relocation_offset=CURRENT_CODE_OFFSET-4;
new_relocation->relocation_kind=PC_RELATIVE_LONG_WORD_RELOCATION;
+#ifdef ELF_RELA
+ new_relocation->relocation_addend=0;
+#endif
+}
+
+#ifdef ELF_RELA
+static void store_relative_label_plus_offset_offset_in_code_section (struct label *label,int offset)
+{
+ struct relocation *new_relocation;
+
+ new_relocation=fast_memory_allocate_type (struct relocation);
+ ++n_code_relocations;
+
+ *last_code_relocation_l=new_relocation;
+ last_code_relocation_l=&new_relocation->next;
+ new_relocation->next=NULL;
+
+ new_relocation->relocation_label=label;
+ new_relocation->relocation_offset=CURRENT_CODE_OFFSET-4;
+ new_relocation->relocation_kind=PC_RELATIVE_LONG_WORD_RELOCATION;
+ new_relocation->relocation_addend=offset;
}
+#endif
static void store_label_plus_offset_in_data_section (LABEL *label,int offset)
{
struct relocation *new_relocation;
+#ifdef ELF_RELA
+ store_long_word_in_data_section (0);
+#else
store_long_word_in_data_section (offset);
+#endif
new_relocation=fast_memory_allocate_type (struct relocation);
++n_data_relocations;
@@ -602,6 +673,9 @@ static void store_label_plus_offset_in_data_section (LABEL *label,int offset)
new_relocation->relocation_label=label;
new_relocation->relocation_offset=CURRENT_DATA_OFFSET-4;
new_relocation->relocation_kind=LONG_WORD_RELOCATION;
+#ifdef ELF_RELA
+ new_relocation->relocation_addend=offset;
+#endif
}
#define reg_num(r) (real_reg_num[(r)+8])
@@ -673,8 +747,13 @@ static void as_move_d_r (LABEL *label,int arity,int reg1)
store_c (0x48 | ((reg1_n & 8)>>1));
store_c (0x8d);
store_c (5 | ((reg1_n & 7)<<3));
+#ifdef ELF_RELA
+ store_l (0);
+ store_relative_label_plus_offset_offset_in_code_section (label,arity);
+#else
store_l (arity);
store_relative_label_offset_in_code_section (label);
+#endif
}
static void as_move_l_r (LABEL *label,int reg1)
@@ -719,8 +798,13 @@ static void as_d_r2 (int code1,int code2,int code3,LABEL *label,int arity,int re
store_c (code1);
store_c (0300 | code2 | (reg1_n & 7));
}
+#ifdef ELF_RELA
+ store_l (0);
+ store_label_plus_offset_in_code_section (label,arity);
+#else
store_l (arity);
store_label_in_code_section (label);
+#endif
}
static void as_r_r (int code,int reg1,int reg2)
@@ -1190,8 +1274,13 @@ static void as_i_id2 (int code1,int code2,int i,int offset,int reg1)
static void as_d_id (int code1,int code2,LABEL *label,int arity,int offset,int reg1)
{
+#ifdef ELF_RELA
+ as_i_id (code1,code2,0,offset,reg1);
+ store_label_plus_offset_in_code_section (label,arity);
+#else
as_i_id (code1,code2,arity,offset,reg1);
store_label_in_code_section (label);
+#endif
}
static void as_i_x (int code1,int code2,int i,int offset,struct index_registers *index_registers)
@@ -1270,8 +1359,13 @@ static void as_i_x2 (int code1,int code2,int i,int offset,struct index_registers
static void as_d_x (int code1,int code2,LABEL *label,int arity,int offset,struct index_registers *index_registers)
{
+#ifdef ELF_RELA
+ as_i_x (code1,code2,0,offset,index_registers);
+ store_label_plus_offset_in_code_section (label,arity);
+#else
as_i_x (code1,code2,arity,offset,index_registers);
store_label_in_code_section (label);
+#endif
}
static void as_r_a (int code,int reg1,LABEL *label)
@@ -1403,8 +1497,14 @@ static void as_move_instruction (struct instruction *instruction)
switch (instruction->instruction_parameters[0].parameter_type){
case P_DESCRIPTOR_NUMBER:
store_c (0150);
+#ifdef ELF_RELA
+ store_l (0);
+ store_label_plus_offset_in_code_section (instruction->instruction_parameters[0].parameter_data.l,
+ instruction->instruction_parameters[0].parameter_offset);
+#else
store_l (instruction->instruction_parameters[0].parameter_offset);
store_label_in_code_section (instruction->instruction_parameters[0].parameter_data.l);
+#endif
return;
case P_IMMEDIATE:
if ((int)instruction->instruction_parameters[0].parameter_data.imm!=instruction->instruction_parameters[0].parameter_data.imm){
@@ -1995,7 +2095,31 @@ static void as_branch_label (struct label *label,int relocation_kind)
new_relocation->relocation_object_label=code_object_label;
#endif
new_relocation->relocation_kind=relocation_kind;
+#ifdef ELF_RELA
+ new_relocation->relocation_addend=0;
+#endif
+}
+
+#ifdef ELF_RELA
+static void as_branch_label_plus_offset (struct label *label,int offset,int relocation_kind)
+{
+ struct relocation *new_relocation;
+
+ new_relocation=fast_memory_allocate_type (struct relocation);
+
+ *last_code_relocation_l=new_relocation;
+ last_code_relocation_l=&new_relocation->next;
+ new_relocation->next=NULL;
+
+ new_relocation->relocation_label=label;
+ new_relocation->relocation_offset=CURRENT_CODE_OFFSET-4;
+#ifdef FUNCTION_LEVEL_LINKING
+ new_relocation->relocation_object_label=code_object_label;
+#endif
+ new_relocation->relocation_kind=relocation_kind;
+ new_relocation->relocation_addend=offset;
}
+#endif
static void as_jmp_instruction (struct instruction *instruction)
{
@@ -2048,8 +2172,13 @@ static void as_jmpp_instruction (struct instruction *instruction)
}
store_c (0351);
+#ifdef ELF_RELA
+ store_l (0);
+ as_branch_label_plus_offset (instruction->instruction_parameters[0].parameter_data.l,offset,JUMP_RELOCATION);
+#else
store_l (offset);
as_branch_label (instruction->instruction_parameters[0].parameter_data.l,JUMP_RELOCATION);
+#endif
break;
}
case P_INDIRECT:
@@ -2172,6 +2301,58 @@ static void as_shift_instruction (struct instruction *instruction,int shift_code
}
}
+static void as_shift_s_instruction (struct instruction *instruction,int shift_code)
+{
+ int r,reg_n;
+
+ if (instruction->instruction_parameters[0].parameter_type!=P_REGISTER){
+ if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){
+ int r,reg_n;
+
+ r=instruction->instruction_parameters[1].parameter_data.reg.r;
+ reg_n=reg_num (r);
+ store_c (0x48 | ((reg_n & 8)>>3));
+ store_c (0301);
+ store_c (0300 | (shift_code<<3) | (reg_n & 7));
+ store_c (instruction->instruction_parameters[0].parameter_data.i & 31);
+ } else
+ internal_error_in_function ("as_shift_s_instruction");
+ } else {
+ int r0,r1,reg_n1;
+
+ r0=instruction->instruction_parameters[0].parameter_data.reg.r;
+ r1=instruction->instruction_parameters[1].parameter_data.reg.r;
+ reg_n1=reg_num (r1);
+ if (r0==REGISTER_A0){
+ store_c (0x48 | ((reg_n1 & 8)>>3));
+ store_c (0323);
+ store_c (0300 | (shift_code<<3) | (reg_n1 & 7));
+ } else {
+ int scratch_register;
+
+ scratch_register=instruction->instruction_parameters[2].parameter_data.reg.r;
+ if (scratch_register==REGISTER_A0){
+ as_move_r_r (r0,REGISTER_A0);
+
+ store_c (0x48 | ((reg_n1 & 8)>>3));
+ store_c (0323);
+ store_c (0300 | (shift_code<<3) | (reg_n1 & 7));
+ } else {
+ as_move_r_r (REGISTER_A0,scratch_register);
+ as_move_r_r (r0,REGISTER_A0);
+
+ if (r1==REGISTER_A0)
+ r1=scratch_register;
+ store_c (0x48 | ((reg_n1 & 8)>>3));
+ store_c (0323);
+ store_c (0300 | (shift_code<<3) | (reg_n1 & 7));
+
+ as_move_r_r (scratch_register,REGISTER_A0);
+ }
+ }
+ }
+}
+
static void as_logic_instruction (struct instruction *instruction,int code1,int code2,int code3)
{
switch (instruction->instruction_parameters[0].parameter_type){
@@ -3807,6 +3988,15 @@ static void as_instructions (struct instruction *instruction)
case IASR:
as_shift_instruction (instruction,7);
break;
+ case ILSL_S:
+ as_shift_s_instruction (instruction,4);
+ break;
+ case ILSR_S:
+ as_shift_s_instruction (instruction,5);
+ break;
+ case IASR_S:
+ as_shift_s_instruction (instruction,7);
+ break;
case IMUL:
as_mul_instruction (instruction);
break;
@@ -4272,9 +4462,13 @@ static void write_code (void)
as_move_l_r (block->block_profile_function_label,REGISTER_A4);
store_c (0351);
+# ifdef ELF_RELA
+ store_l (0);
+ as_branch_label_plus_offset (eval_upd_labels[n_node_arguments],-8,JUMP_RELOCATION);
+# else
store_l (-8);
as_branch_label (eval_upd_labels[n_node_arguments],JUMP_RELOCATION);
-
+#endif
as_move_l_r (block->block_ea_label,REGISTER_D0);
store_c (0xeb);
@@ -4410,6 +4604,14 @@ static int n_digits (int n)
static int n_sections;
#endif
+#ifdef ELF_RELA
+# define ELF_RELOCATION_SIZE 24
+# define ELF_RELOCATION_SECTION_NAME_LENGTH_PREFIX 13
+#else
+# define ELF_RELOCATION_SIZE 16
+# define ELF_RELOCATION_SECTION_NAME_LENGTH_PREFIX 12
+#endif
+
static void write_file_header_and_section_headers (void)
{
#ifndef ELF
@@ -4673,7 +4875,7 @@ static void write_file_header_and_section_headers (void)
code_offset+=code_section_length;
if (n_code_relocations_in_section>0){
- section_strings_size+=12+n_digits (previous_code_object_label->object_label_section_n);
+ section_strings_size+=ELF_RELOCATION_SECTION_NAME_LENGTH_PREFIX+n_digits (previous_code_object_label->object_label_section_n);
++n_code_relocation_sections;
}
}
@@ -4698,7 +4900,7 @@ static void write_file_header_and_section_headers (void)
data_offset+=data_section_length;
if (n_data_relocations_in_section>0){
- section_strings_size+=12+n_digits (previous_data_object_label->object_label_section_n);
+ section_strings_size+=ELF_RELOCATION_SECTION_NAME_LENGTH_PREFIX+n_digits (previous_data_object_label->object_label_section_n);
++n_data_relocation_sections;
}
}
@@ -4724,7 +4926,7 @@ static void write_file_header_and_section_headers (void)
previous_code_object_label->object_label_length=code_section_length;
if (n_code_relocations_in_section>0){
- section_strings_size+=12+n_digits (previous_code_object_label->object_label_section_n);
+ section_strings_size+=ELF_RELOCATION_SECTION_NAME_LENGTH_PREFIX+n_digits (previous_code_object_label->object_label_section_n);
++n_code_relocation_sections;
}
}
@@ -4746,7 +4948,7 @@ static void write_file_header_and_section_headers (void)
previous_data_object_label->object_label_length=data_section_length;
if (n_data_relocations_in_section>0){
- section_strings_size+=12+n_digits (previous_data_object_label->object_label_section_n);
+ section_strings_size+=ELF_RELOCATION_SECTION_NAME_LENGTH_PREFIX+n_digits (previous_data_object_label->object_label_section_n);
++n_data_relocation_sections;
}
}
@@ -4757,17 +4959,17 @@ static void write_file_header_and_section_headers (void)
# endif
write_l (0x464c457f);
- write_l (0x00010101);
+ write_l (0x00010102);
write_l (0);
write_l (0);
- write_l (0x00030001);
+ write_l (0x003e0001);
write_l (1);
+ write_q (0);
+ write_q (0);
+ write_q (0x40);
write_l (0);
- write_l (0);
- write_l (0x34);
- write_l (0);
- write_l (0x00000034);
- write_l (0x00280000);
+ write_l (0x00000040);
+ write_l (0x00400000);
# ifdef FUNCTION_LEVEL_LINKING
write_l (0x00010000 | (n_sections+n_code_relocation_sections+n_data_relocation_sections+4));
# else
@@ -4776,34 +4978,34 @@ static void write_file_header_and_section_headers (void)
write_l (0);
write_l (0);
+ write_q (0);
+ write_q (0);
+ write_q (0);
+ write_q (0);
write_l (0);
write_l (0);
- write_l (0);
- write_l (0);
- write_l (0);
- write_l (0);
- write_l (0);
- write_l (0);
+ write_q (0);
+ write_q (0);
# ifdef FUNCTION_LEVEL_LINKING
- offset=0xd4+40*(n_sections+n_code_relocation_sections+n_data_relocation_sections);
+ offset=0x40+64*(4+n_sections+n_code_relocation_sections+n_data_relocation_sections);
# else
offset=0x174;
# endif
write_l (1);
write_l (SHT_STRTAB);
- write_l (0);
- write_l (0);
- write_l (offset);
+ write_q (0);
+ write_q (0);
+ write_q (offset);
# ifdef FUNCTION_LEVEL_LINKING
- write_l ((27+section_strings_size+3) & -4);
+ write_q ((27+section_strings_size+3) & -4);
# else
- write_l (60);
+ write_q (60);
# endif
write_l (0);
write_l (0);
- write_l (1);
- write_l (0);
+ write_q (1);
+ write_q (0);
# ifdef FUNCTION_LEVEL_LINKING
offset+=(27+section_strings_size+3) & -4;
# else
@@ -4825,14 +5027,14 @@ static void write_file_header_and_section_headers (void)
write_l (section_string_offset);
write_l (SHT_PROGBITS);
- write_l (SHF_ALLOC | SHF_EXECINSTR);
- write_l (0);
- write_l (offset+code_offset);
- write_l (code_section_length);
- write_l (0);
+ write_q (SHF_ALLOC | SHF_EXECINSTR);
+ write_q (0);
+ write_q (offset+code_offset);
+ write_q (code_section_length);
write_l (0);
- write_l (4);
write_l (0);
+ write_q (4);
+ write_q (0);
section_string_offset+=8+n_digits (object_label->object_label_section_n);
code_offset+=code_section_length;
@@ -4850,14 +5052,14 @@ static void write_file_header_and_section_headers (void)
write_l (section_string_offset);
write_l (SHT_PROGBITS);
- write_l (SHF_ALLOC | SHF_WRITE);
+ write_q (SHF_ALLOC | SHF_WRITE);
+ write_q (0);
+ write_q (offset+data_offset);
+ write_q (data_section_length);
write_l (0);
- write_l (offset+data_offset);
- write_l (data_section_length);
- write_l (0);
- write_l (0);
- write_l (1<<object_label->object_section_align);
write_l (0);
+ write_q (1<<object_label->object_section_align);
+ write_q (0);
section_string_offset+=8+n_digits (object_label->object_label_section_n);
data_offset+=data_section_length;
@@ -4876,21 +5078,25 @@ static void write_file_header_and_section_headers (void)
if (n_code_relocations_in_section>0){
write_l (section_string_offset);
+# ifdef ELF_RELA
+ write_l (SHT_RELA);
+# else
write_l (SHT_REL);
- write_l (0);
- write_l (0);
- write_l (offset+code_relocations_offset);
- write_l (8*n_code_relocations_in_section);
+# endif
+ write_q (0);
+ write_q (0);
+ write_q (offset+code_relocations_offset);
+ write_q (ELF_RELOCATION_SIZE*n_code_relocations_in_section);
write_l (n_sections+n_code_relocation_sections+n_data_relocation_sections+2);
write_l (2+object_label->object_label_section_n);
- write_l (4);
- write_l (8);
- section_string_offset+=12+n_digits (object_label->object_label_section_n);
- code_relocations_offset+=8*n_code_relocations_in_section;
+ write_q (4);
+ write_q (ELF_RELOCATION_SIZE);
+ section_string_offset+=ELF_RELOCATION_SECTION_NAME_LENGTH_PREFIX+n_digits (object_label->object_label_section_n);
+ code_relocations_offset+=ELF_RELOCATION_SIZE*n_code_relocations_in_section;
}
}
}
- offset+=8*n_code_relocations;
+ offset+=ELF_RELOCATION_SIZE*n_code_relocations;
data_relocations_offset=0;
@@ -4902,70 +5108,82 @@ static void write_file_header_and_section_headers (void)
if (n_data_relocations_in_section>0){
write_l (section_string_offset);
+# ifdef ELF_RELA
+ write_l (SHT_RELA);
+# else
write_l (SHT_REL);
- write_l (0);
- write_l (0);
- write_l (offset+data_relocations_offset);
- write_l (8*n_data_relocations_in_section);
+# endif
+ write_q (0);
+ write_q (0);
+ write_q (offset+data_relocations_offset);
+ write_q (ELF_RELOCATION_SIZE*n_data_relocations_in_section);
write_l (n_sections+n_code_relocation_sections+n_data_relocation_sections+2);
write_l (2+n_code_sections+object_label->object_label_section_n);
- write_l (4);
- write_l (8);
- section_string_offset+=12+n_digits (object_label->object_label_section_n);
- data_relocations_offset+=8*n_data_relocations_in_section;
+ write_q (4);
+ write_q (ELF_RELOCATION_SIZE);
+ section_string_offset+=ELF_RELOCATION_SECTION_NAME_LENGTH_PREFIX+n_digits (object_label->object_label_section_n);
+ data_relocations_offset+=ELF_RELOCATION_SIZE*n_data_relocations_in_section;
}
}
}
- offset+=8*n_data_relocations;
+ offset+=ELF_RELOCATION_SIZE*n_data_relocations;
}
# else
write_l (11);
write_l (SHT_PROGBITS);
- write_l (SHF_ALLOC | SHF_EXECINSTR);
- write_l (0);
- write_l (offset);
- write_l (code_buffer_offset);
+ write_q (SHF_ALLOC | SHF_EXECINSTR);
+ write_q (0);
+ write_q (offset);
+ write_q (code_buffer_offset);
write_l (0);
write_l (0);
- write_l (4);
- write_l (0);
+ write_q (4);
+ write_q (0);
offset+=(code_buffer_offset+3 ) & ~3;
write_l (17);
write_l (SHT_PROGBITS);
- write_l (SHF_ALLOC | SHF_WRITE);
+ write_q (SHF_ALLOC | SHF_WRITE);
+ write_q (0);
+ write_q (offset);
+ write_q (data_buffer_offset);
write_l (0);
- write_l (offset);
- write_l (data_buffer_offset);
- write_l (0);
- write_l (0);
- write_l (4);
write_l (0);
+ write_q (4);
+ write_q (0);
offset+=(data_buffer_offset+3) & ~3;
write_l (23);
+# ifdef ELF_RELA
+ write_l (SHT_RELA);
+# else
write_l (SHT_REL);
- write_l (0);
- write_l (0);
- write_l (offset);
- write_l (8*n_code_relocations);
+# endif
+ write_q (0);
+ write_q (0);
+ write_q (offset);
+ write_q (ELF_RELOCATION_SIZE*n_code_relocations);
write_l (6);
write_l (2);
- write_l (4);
- write_l (8);
- offset+=8*n_code_relocations;
+ write_q (4);
+ write_q (ELF_RELOCATION_SIZE);
+ offset+=ELF_RELOCATION_SIZE*n_code_relocations;
write_l (33);
+# ifdef ELF_RELA
+ write_l (SHT_RELA);
+# else
write_l (SHT_REL);
- write_l (0);
- write_l (0);
- write_l (offset);
- write_l (8*n_data_relocations);
+# endif
+ write_q (0);
+ write_q (0);
+ write_q (offset);
+ write_q (ELF_RELOCATION_SIZE*n_data_relocations);
write_l (6);
write_l (3);
- write_l (4);
- write_l (8);
- offset+=8*n_data_relocations;
+ write_q (4);
+ write_q (ELF_RELOCATION_SIZE);
+ offset+=ELF_RELOCATION_SIZE*n_data_relocations;
# endif
# ifdef FUNCTION_LEVEL_LINKING
@@ -4974,24 +5192,24 @@ static void write_file_header_and_section_headers (void)
write_l (43);
# endif
write_l (SHT_SYMTAB);
- write_l (0);
- write_l (0);
- write_l (offset);
+ write_q (0);
+ write_q (0);
+ write_q (offset);
# ifdef FUNCTION_LEVEL_LINKING
- write_l (16*(n_object_labels+n_sections));
+ write_q (24*(n_object_labels+n_sections));
write_l (n_sections+n_code_relocation_sections+n_data_relocation_sections+3);
write_l (1+n_sections);
# else
- write_l (16*n_object_labels);
+ write_q (24*n_object_labels);
write_l (7);
write_l (3);
# endif
- write_l (4);
- write_l (16);
+ write_q (4);
+ write_q (24);
# ifdef FUNCTION_LEVEL_LINKING
- offset+=16*(n_object_labels+n_sections);
+ offset+=24*(n_object_labels+n_sections);
# else
- offset+=16*n_object_labels;
+ offset+=24*n_object_labels;
# endif
# ifdef FUNCTION_LEVEL_LINKING
@@ -5000,14 +5218,14 @@ static void write_file_header_and_section_headers (void)
write_l (51);
# endif
write_l (SHT_STRTAB);
+ write_q (0);
+ write_q (0);
+ write_q (offset);
+ write_q (string_table_offset);
write_l (0);
write_l (0);
- write_l (offset);
- write_l (string_table_offset);
- write_l (0);
- write_l (0);
- write_l (0);
- write_l (0);
+ write_q (0);
+ write_q (0);
write_c (0);
write_zstring (".shstrtab");
@@ -5028,22 +5246,35 @@ static void write_file_header_and_section_headers (void)
}
for_l (object_label,first_object_label,next)
- if (object_label->object_label_kind==CODE_CONTROL_SECTION && object_label->object_label_n_relocations>0){
+ if (object_label->object_label_kind==CODE_CONTROL_SECTION && object_label->object_label_n_relocations>0){
+# ifdef ELF_RELA
+ sprintf (section_name,".rela.text.m%d",object_label->object_label_section_n);
+# else
sprintf (section_name,".rel.text.m%d",object_label->object_label_section_n);
+# endif
write_zstring (section_name);
}
for_l (object_label,first_object_label,next)
if (object_label->object_label_kind==DATA_CONTROL_SECTION && object_label->object_label_n_relocations>0){
+# ifdef ELF_RELA
+ sprintf (section_name,".rela.data.m%d",object_label->object_label_section_n);
+# else
sprintf (section_name,".rel.data.m%d",object_label->object_label_section_n);
+# endif
write_zstring (section_name);
}
}
# else
write_zstring (".text");
write_zstring (".data");
+# ifdef ELF_RELA
+ write_zstring (".rela.text");
+ write_zstring (".rela.data");
+# else
write_zstring (".rel.text");
write_zstring (".rel.data");
+# endif
# endif
write_zstring (".symtab");
write_zstring (".strtab");
@@ -5494,7 +5725,6 @@ static void relocate_short_branches_and_move_code (void)
if (source_buffer_offset<=BUFFER_SIZE-5){
v += *(LONG*)(source_object_buffer->data+(source_buffer_offset+1));
-
} else {
unsigned char *p1,*p2,*p3,*p4,*end_buffer;
@@ -5687,10 +5917,18 @@ static void relocate_code (void)
# endif
++n_code_relocations;
relocation_p=&relocation->next;
+# ifdef ELF_RELA
+ relocation->relocation_addend+=v;
+ continue;
+# else
break;
+# endif
}
#endif
v=label->label_offset-(instruction_offset+4);
+#ifdef ELF_RELA
+ v+=relocation->relocation_addend;
+#endif
*relocation_p=relocation->next;
break;
} else {
@@ -5699,13 +5937,57 @@ static void relocate_code (void)
#ifdef ELF
instruction_offset=relocation->relocation_offset;
v= -4;
+# ifdef ELF_RELA
+ relocation->relocation_addend+=v;
+ continue;
+# else
break;
+# endif
#else
continue;
#endif
}
+#ifdef ELF
+ case PC_RELATIVE_LONG_WORD_RELOCATION:
+ relocation_p=&relocation->next;
+
+ label=relocation->relocation_label;
+
+ if (label->label_id==TEXT_LABEL_ID || (label->label_id==DATA_LABEL_ID
+# if defined (RELOCATIONS_RELATIVE_TO_EXPORTED_DATA_LABEL) && defined (FUNCTION_LEVEL_LINKING)
+ && !((label->label_flags & EXPORT_LABEL) && label->label_object_label->object_label_kind==EXPORTED_DATA_LABEL)
+# endif
+ ))
+ {
+ instruction_offset=relocation->relocation_offset;
+ v=label->label_offset;
+
+ v -= 4;
+
+# ifdef FUNCTION_LEVEL_LINKING
+ v -= label->label_object_label->object_label_offset;
+# endif
+# ifdef ELF_RELA
+ relocation->relocation_addend+=v;
+ continue;
+# else
+ break;
+# endif
+ } else {
+ instruction_offset=relocation->relocation_offset;
+ v= -4;
+# ifdef ELF_RELA
+ relocation->relocation_addend+=v;
+ continue;
+# else
+ break;
+# endif
+ }
+ case LONG_WORD_RELOCATION:
+#else
case LONG_WORD_RELOCATION:
case PC_RELATIVE_LONG_WORD_RELOCATION:
+#endif
relocation_p=&relocation->next;
label=relocation->relocation_label;
@@ -5721,7 +6003,12 @@ static void relocate_code (void)
#ifdef FUNCTION_LEVEL_LINKING
v -= label->label_object_label->object_label_offset;
#endif
+#ifdef ELF_RELA
+ relocation->relocation_addend+=v;
+ continue;
+#else
break;
+#endif
} else
continue;
#ifdef FUNCTION_LEVEL_LINKING
@@ -5781,6 +6068,32 @@ static void relocate_code (void)
static void relocate_data (void)
{
+#ifdef ELF_RELA
+ struct relocation *relocation;
+
+ for_l (relocation,first_data_relocation,next){
+ struct label *label;
+
+ label=relocation->relocation_label;
+
+ if (relocation->relocation_kind==LONG_WORD_RELOCATION){
+ if (label->label_id==TEXT_LABEL_ID || (label->label_id==DATA_LABEL_ID
+#if defined (RELOCATIONS_RELATIVE_TO_EXPORTED_DATA_LABEL) && defined (FUNCTION_LEVEL_LINKING)
+ && !((label->label_flags & EXPORT_LABEL) && label->label_object_label->object_label_kind==EXPORTED_DATA_LABEL)
+#endif
+ ))
+ {
+ int v;
+
+ v = label->label_offset;
+#ifdef FUNCTION_LEVEL_LINKING
+ v -= label->label_object_label->object_label_offset;
+#endif
+ relocation->relocation_addend += v;
+ }
+ }
+ }
+#else
struct relocation *relocation;
struct object_buffer *object_buffer;
int data_buffer_offset;
@@ -5842,6 +6155,7 @@ static void relocate_data (void)
}
}
}
+#endif
}
static void as_import_labels (struct label_node *label_node)
@@ -5902,42 +6216,42 @@ static void write_object_labels (void)
#ifdef ELF
write_l (0);
write_l (0);
- write_l (0);
- write_l (0);
+ write_q (0);
+ write_q (0);
# ifndef FUNCTION_LEVEL_LINKING
write_l (1);
- write_l (0);
- write_l (0);
write_c (ELF32_ST_INFO (STB_LOCAL,STT_SECTION));
write_c (0);
write_w (2);
+ write_q (0);
+ write_q (0);
write_l (7);
- write_l (0);
- write_l (0);
write_c (ELF32_ST_INFO (STB_LOCAL,STT_SECTION));
write_c (0);
write_w (3);
+ write_q (0);
+ write_q (0);
# else
{
int section_n;
for (section_n=0; section_n<n_code_sections; ++section_n){
write_l (0);
- write_l (0);
- write_l (0);
write_c (ELF32_ST_INFO (STB_LOCAL,STT_SECTION));
write_c (0);
write_w (2+section_n);
+ write_q (0);
+ write_q (0);
}
for (section_n=0; section_n<n_data_sections; ++section_n){
write_l (0);
- write_l (0);
- write_l (0);
write_c (ELF32_ST_INFO (STB_LOCAL,STT_SECTION));
write_c (0);
write_w (2+n_code_sections+section_n);
+ write_q (0);
+ write_q (0);
}
}
# endif
@@ -6013,11 +6327,11 @@ static void write_object_labels (void)
label=object_label->object_label_label;
#ifdef ELF
write_l (object_label->object_label_string_offset);
- write_l (0);
- write_l (0);
write_c (ELF32_ST_INFO (STB_GLOBAL,STT_NOTYPE));
write_c (0);
write_w (0);
+ write_q (0);
+ write_q (0);
#else
if (object_label->object_label_string_offset==0)
write_string_8 (label->label_name);
@@ -6041,19 +6355,16 @@ static void write_object_labels (void)
label=object_label->object_label_label;
#ifdef ELF
write_l (object_label->object_label_string_offset);
-# ifdef FUNCTION_LEVEL_LINKING
- write_l (label->label_offset - label->label_object_label->object_label_offset);
-# else
- write_l (label->label_offset);
-# endif
- write_l (0);
write_c (ELF32_ST_INFO (STB_GLOBAL,STT_FUNC));
write_c (0);
# ifdef FUNCTION_LEVEL_LINKING
write_w (2+label->label_object_label->object_label_section_n);
+ write_q (label->label_offset - label->label_object_label->object_label_offset);
# else
write_w (2);
+ write_q (label->label_offset);
# endif
+ write_q (0);
#else
if (object_label->object_label_string_offset==0)
write_string_8 (label->label_name);
@@ -6082,23 +6393,20 @@ static void write_object_labels (void)
label=object_label->object_label_label;
#ifdef ELF
write_l (object_label->object_label_string_offset);
-# ifdef FUNCTION_LEVEL_LINKING
-# ifdef RELOCATIONS_RELATIVE_TO_EXPORTED_DATA_LABEL
- write_l (label->label_offset - current_text_or_data_object_label->object_label_offset);
-# else
- write_l (label->label_offset - label->label_object_label->object_label_offset);
-# endif
-# else
- write_l (label->label_offset);
-# endif
- write_l (0);
write_c (ELF32_ST_INFO (STB_GLOBAL,STT_OBJECT));
write_c (0);
# ifdef FUNCTION_LEVEL_LINKING
write_w (2+n_code_sections+label->label_object_label->object_label_section_n);
+# ifdef RELOCATIONS_RELATIVE_TO_EXPORTED_DATA_LABEL
+ write_q (label->label_offset - current_text_or_data_object_label->object_label_offset);
+# else
+ write_q (label->label_offset - label->label_object_label->object_label_offset);
+# endif
# else
write_w (3);
+ write_q (label->label_offset);
# endif
+ write_q (0);
#else
if (object_label->object_label_string_offset==0)
write_string_8 (label->label_name);
@@ -6211,14 +6519,19 @@ static void write_code_relocations (void)
#endif
internal_error_in_function ("write_code_relocations");
- write_l (relocation->relocation_offset);
#ifdef ELF
+ write_q (relocation->relocation_offset);
+ write_l (R_X86_64_PC32);
# ifdef FUNCTION_LEVEL_LINKING
- write_l (ELF32_R_INFO (elf_label_number (label),R_386_PC32));
+ write_l (elf_label_number (label));
# else
- write_l (ELF32_R_INFO (label->label_id,R_386_PC32));
+ write_l (label->label_id);
+# endif
+# ifdef ELF_RELA
+ write_q (relocation->relocation_addend);
# endif
#else
+ write_l (relocation->relocation_offset);
# ifdef FUNCTION_LEVEL_LINKING
if (label->label_id==TEXT_LABEL_ID || label->label_id==DATA_LABEL_ID)
write_l (label->label_object_label->object_label_number);
@@ -6241,14 +6554,19 @@ static void write_code_relocations (void)
#endif
internal_error_in_function ("write_code_relocations");
- write_l (relocation->relocation_offset);
#ifdef ELF
+ write_q (relocation->relocation_offset);
+ write_l (R_X86_64_32S);
# ifdef FUNCTION_LEVEL_LINKING
- write_l (ELF32_R_INFO (elf_label_number (label),R_386_32));
+ write_l (elf_label_number (label));
# else
- write_l (ELF32_R_INFO (label->label_id,R_386_32));
+ write_l (label->label_id);
+# endif
+# ifdef ELF_RELA
+ write_q (relocation->relocation_addend);
# endif
#else
+ write_l (relocation->relocation_offset);
# ifdef FUNCTION_LEVEL_LINKING
if (label->label_id==TEXT_LABEL_ID || label->label_id==DATA_LABEL_ID)
write_l (label->label_object_label->object_label_number);
@@ -6271,14 +6589,19 @@ static void write_code_relocations (void)
#endif
internal_error_in_function ("write_code_relocations");
- write_l (relocation->relocation_offset);
#ifdef ELF
+ write_q (relocation->relocation_offset);
+ write_l (R_X86_64_PC32);
# ifdef FUNCTION_LEVEL_LINKING
- write_l (ELF32_R_INFO (elf_label_number (label),R_386_32));
+ write_l (elf_label_number (label));
# else
- write_l (ELF32_R_INFO (label->label_id,R_386_32));
+ write_l (label->label_id);
+# endif
+# ifdef ELF_RELA
+ write_q (relocation->relocation_addend);
# endif
#else
+ write_l (relocation->relocation_offset);
# ifdef FUNCTION_LEVEL_LINKING
if (label->label_id==TEXT_LABEL_ID || label->label_id==DATA_LABEL_ID)
write_l (label->label_object_label->object_label_number);
@@ -6298,10 +6621,15 @@ static void write_code_relocations (void)
if (label->label_id==-1)
internal_error_in_function ("write_code_relocations");
- write_l (relocation->relocation_offset - 4);
#ifdef ELF
- write_l (ELF32_R_INFO (elf_label_number (label),R_386_NONE));
+ write_q (relocation->relocation_offset - 4);
+ write_l (R_X86_64_NONE);
+ write_l (elf_label_number (label));
+# ifdef ELF_RELA
+ write_q (relocation->relocation_addend);
+# endif
#else
+ write_l (relocation->relocation_offset - 4);
if (label->label_id==TEXT_LABEL_ID || label->label_id==DATA_LABEL_ID)
write_l (label->label_object_label->object_label_number);
else
@@ -6339,14 +6667,19 @@ static void write_data_relocations (void)
#endif
internal_error_in_function ("write_data_relocations");
- write_l (relocation->relocation_offset);
#ifdef ELF
+ write_q (relocation->relocation_offset);
+ write_l (R_X86_64_32S);
# ifdef FUNCTION_LEVEL_LINKING
- write_l (ELF32_R_INFO (elf_label_number (label),R_386_32));
+ write_l (elf_label_number (label));
# else
- write_l (ELF32_R_INFO (label->label_id,R_386_32));
+ write_l (label->label_id);
+# endif
+# ifdef ELF_RELA
+ write_q (relocation->relocation_addend);
# endif
#else
+ write_l (relocation->relocation_offset);
# ifdef FUNCTION_LEVEL_LINKING
if (label->label_id==TEXT_LABEL_ID || label->label_id==DATA_LABEL_ID)
write_l (label->label_object_label->object_label_number);