summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgaas.c96
-rw-r--r--cgcode.c20
2 files changed, 107 insertions, 9 deletions
diff --git a/cgaas.c b/cgaas.c
index 0114891..bbf6c77 100644
--- a/cgaas.c
+++ b/cgaas.c
@@ -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");
diff --git a/cgcode.c b/cgcode.c
index 857aa3f..b756f63 100644
--- a/cgcode.c
+++ b/cgcode.c
@@ -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