diff options
-rw-r--r-- | cgaas.c | 96 | ||||
-rw-r--r-- | cgcode.c | 20 |
2 files changed, 107 insertions, 9 deletions
@@ -205,8 +205,11 @@ static void write_q (int c) #define DUMMY_BRANCH_RELOCATION 9 #define PC_RELATIVE_LONG_WORD_RELOCATION 10 #define BRANCH_SKIP_BRANCH_RELOCATION 11 +#if defined (MACH_O64) || defined (LINUX) +# define WORD64_RELOCATION 12 +#endif #ifdef LINUX -# define GOT_PC_RELATIVE_RELOCATION 12 +# define GOT_PC_RELATIVE_RELOCATION 13 #endif struct relocation { @@ -712,10 +715,25 @@ static void store_label_plus_offset_in_data_section (LABEL *label,int offset) { struct relocation *new_relocation; -#ifdef ELF_RELA +#if defined (MACH_O64) || defined (LINUX) +# ifdef LINUX + if (pic_flag) +# endif +# ifdef ELF_RELA + store_word64_in_data_section (0); +# else + store_word64_in_data_section (offset); +# endif +# ifdef LINUX + else +# endif +#endif +#ifndef MACH_O64 +# ifdef ELF_RELA store_long_word_in_data_section (0); -#else +# else store_long_word_in_data_section (offset); +# endif #endif new_relocation=fast_memory_allocate_type (struct relocation); @@ -726,8 +744,26 @@ static void store_label_plus_offset_in_data_section (LABEL *label,int offset) new_relocation->next=NULL; new_relocation->relocation_label=label; - new_relocation->relocation_offset=CURRENT_DATA_OFFSET-4; - new_relocation->relocation_kind=LONG_WORD_RELOCATION; + +#if defined (MACH_O64) || defined (LINUX) +# ifdef LINUX + if (pic_flag) +# endif + { + new_relocation->relocation_offset=CURRENT_DATA_OFFSET-8; + new_relocation->relocation_kind=WORD64_RELOCATION; + } +# ifdef LINUX + else +# endif +#endif +#ifndef MACH_O64 + { + new_relocation->relocation_offset=CURRENT_DATA_OFFSET-4; + new_relocation->relocation_kind=LONG_WORD_RELOCATION; + } +#endif + #ifdef ELF_RELA new_relocation->relocation_addend=offset; #endif @@ -6649,6 +6685,21 @@ static void relocate_data (void) # endif relocation->relocation_addend += v; } + } else if (relocation->relocation_kind==WORD64_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; + } } #endif } @@ -7329,6 +7380,41 @@ static void write_data_relocations (void) # endif break; } + case WORD64_RELOCATION: + { + struct label *label; + + label=relocation->relocation_label; +#ifdef FUNCTION_LEVEL_LINKING + if (label->label_id==-1) +#else + if (label->label_id<0) +#endif + internal_error_in_function ("write_data_relocations"); + +#ifdef ELF + write_q (relocation->relocation_offset); + write_l (R_X86_64_64); +# ifdef FUNCTION_LEVEL_LINKING + write_l (elf_label_number (label)); +# else + 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); + else +# endif + write_l (label->label_id); + write_w (R_ADDR64); +#endif + break; + } #endif default: internal_error_in_function ("write_data_relocations"); @@ -8803,6 +8803,12 @@ static void write_descriptor_curry_table (int arity,LABEL *code_label) add_arg_label->label_id=next_label_id++; #ifdef GEN_OBJ +# if defined (MACH_O64) || (defined (G_A64) && defined (LINUX)) +# if defined (G_A64) && defined (LINUX) + if (pic_flag) +# endif + store_long_word_in_data_section (0); +# endif store_label_in_data_section (add_arg_label); #endif if (assembly_flag){ @@ -8814,6 +8820,12 @@ static void write_descriptor_curry_table (int arity,LABEL *code_label) } else if (n==arity-1){ #ifdef GEN_OBJ +# if defined (MACH_O64) || (defined (G_A64) && defined (LINUX)) +# if defined (G_A64) && defined (LINUX) + if (pic_flag) +# endif + store_long_word_in_data_section (0); +# endif store_label_in_data_section (code_label); #endif if (assembly_flag){ @@ -8923,7 +8935,7 @@ static void code_new_descriptor (int arity,int lazy_record_flag) # ifdef MACH_O64 store_label_offset_in_data_section (module_label); # else -# ifdef LINUX +# if defined (G_A64) && defined (LINUX) if (pic_flag) store_label_offset_in_data_section (module_label); else @@ -9248,7 +9260,7 @@ void code_record (char record_label_name[],char type[],int a_size,int b_size,cha # ifdef MACH_O64 store_label_offset_in_data_section (module_label); # else -# ifdef LINUX +# if defined (G_A64) && defined (LINUX) if (pic_flag) store_label_offset_in_data_section (module_label); else @@ -9485,7 +9497,7 @@ void code_pb (char string[],int string_length) # ifdef MACH_O64 store_label_offset_in_data_section (module_label); # else -# ifdef LINUX +# if defined (G_A64) && defined (LINUX) if (pic_flag) store_label_offset_in_data_section (module_label); else @@ -9561,7 +9573,7 @@ void write_profile_table (void) # ifdef MACH_O64 store_label_offset_in_data_section (module_label); # else -# ifdef LINUX +# if defined (G_A64) && defined (LINUX) if (pic_flag) store_label_offset_in_data_section (module_label); else |