summaryrefslogtreecommitdiff
path: root/cgaas.c
diff options
context:
space:
mode:
Diffstat (limited to 'cgaas.c')
-rw-r--r--cgaas.c905
1 files changed, 652 insertions, 253 deletions
diff --git a/cgaas.c b/cgaas.c
index ad519ea..0de444c 100644
--- a/cgaas.c
+++ b/cgaas.c
@@ -22,6 +22,12 @@
#ifdef LINUX_ELF
# define ELF
# define ELF_RELA
+#elif defined (MACH_O64)
+# define G_MACH_O64
+# include </usr/include/mach-o/loader.h>
+# include </usr/include/mach-o/nlist.h>
+# include </usr/include/mach-o/x86_64/reloc.h>
+#else
#endif
#if defined (_WINDOWS_) || defined (ELF)
@@ -59,8 +65,6 @@
int sse_128=1;
-#ifndef MACH_O64
-
#ifdef FUNCTION_LEVEL_LINKING
# define TEXT_LABEL_ID (-2)
# define DATA_LABEL_ID (-3)
@@ -69,8 +73,13 @@ int sse_128=1;
# define TEXT_LABEL_ID 1
# define DATA_LABEL_ID 2
# else
-# define TEXT_LABEL_ID 0
-# define DATA_LABEL_ID 2
+# ifdef G_MACH_O64
+# define TEXT_LABEL_ID (-2)
+# define DATA_LABEL_ID (-1)
+# else
+# define TEXT_LABEL_ID 0
+# define DATA_LABEL_ID 2
+# endif
# endif
#endif
@@ -124,6 +133,10 @@ static struct object_buffer *first_data_buffer,*current_data_buffer;
static int data_buffer_free,data_buffer_offset;
static unsigned char *data_buffer_p;
+#ifdef G_MACH_O64
+static int data_section_begin;
+#endif
+
static void initialize_buffers (void)
{
struct object_buffer *new_code_buffer,*new_data_buffer;
@@ -264,10 +277,15 @@ static int n_object_labels;
static unsigned long string_table_offset;
+#ifndef G_MACH_O64
static struct object_label *code_object_label,*data_object_label;
+#endif
#ifdef FUNCTION_LEVEL_LINKING
static int n_code_sections,n_data_sections;
#endif
+#ifdef G_MACH_O64
+static int n_section_object_labels,n_exported_object_labels;
+#endif
struct call_and_jump {
struct call_and_jump *cj_next;
@@ -325,13 +343,14 @@ void initialize_assembler (FILE *output_file_d)
data_object_label=NULL;
n_data_sections=0;
-#else
+#else
+# ifndef G_MACH_O64
code_object_label=fast_memory_allocate_type (struct object_label);
-# ifdef ELF
+# ifdef ELF
++n_object_labels;
-# else
+# else
n_object_labels+=2;
-# endif
+# endif
*last_object_label_l=code_object_label;
last_object_label_l=&code_object_label->next;
code_object_label->next=NULL;
@@ -341,11 +360,11 @@ void initialize_assembler (FILE *output_file_d)
code_object_label->object_label_kind=CODE_CONTROL_SECTION;
data_object_label=fast_memory_allocate_type (struct object_label);
-# ifdef ELF
+# ifdef ELF
++n_object_labels;
-# else
+# else
n_object_labels+=2;
-# endif
+# endif
*last_object_label_l=data_object_label;
last_object_label_l=&data_object_label->next;
data_object_label->next=NULL;
@@ -354,6 +373,7 @@ void initialize_assembler (FILE *output_file_d)
data_object_label->object_label_length=0;
data_object_label->object_label_kind=DATA_CONTROL_SECTION;
data_object_label->object_section_align=2;
+# endif
#endif
}
@@ -601,6 +621,14 @@ static void as_new_code_module (void)
}
#endif
+#ifdef G_MACH_O64
+void as_data_align_quad (void)
+{
+ if ((data_buffer_p-current_data_buffer->data) & 4)
+ store_long_word_in_data_section (0);
+}
+#endif
+
static void store_label_in_code_section (struct label *label)
{
struct relocation *new_relocation;
@@ -722,7 +750,7 @@ static void store_relative_to_next_byte_label_plus_offset_offset_in_code_section
}
#endif
-#if defined (MACH_O64) || defined (LINUX)
+#if defined (G_MACH_O64) || defined (LINUX)
static void store_relative_label_plus_offset_in_data_section (struct label *label,int offset)
{
struct relocation *new_relocation;
@@ -734,7 +762,9 @@ static void store_relative_label_plus_offset_in_data_section (struct label *labe
# endif
new_relocation=fast_memory_allocate_type (struct relocation);
+# ifndef G_MACH_O64
++n_data_relocations;
+#endif
*last_data_relocation_l=new_relocation;
last_data_relocation_l=&new_relocation->next;
@@ -753,8 +783,8 @@ static void store_label_plus_offset_in_data_section (LABEL *label,int offset)
{
struct relocation *new_relocation;
-#if defined (MACH_O64) || defined (LINUX)
-# ifdef LINUX
+#if defined (LINUX) || defined (G_MACH_O64)
+# ifndef G_MACH_O64
if (pic_flag)
# endif
# ifdef ELF_RELA
@@ -762,11 +792,11 @@ static void store_label_plus_offset_in_data_section (LABEL *label,int offset)
# else
store_word64_in_data_section (offset);
# endif
-# ifdef LINUX
+# ifndef G_MACH_O64
else
# endif
#endif
-#ifndef MACH_O64
+#ifndef G_MACH_O64
# ifdef ELF_RELA
store_long_word_in_data_section (0);
# else
@@ -783,15 +813,15 @@ static void store_label_plus_offset_in_data_section (LABEL *label,int offset)
new_relocation->relocation_label=label;
-#if defined (MACH_O64) || defined (LINUX)
-# ifdef LINUX
+#if defined (LINUX) || defined (G_MACH_O64)
+# ifndef G_MACH_O64
if (pic_flag)
# endif
{
new_relocation->relocation_offset=CURRENT_DATA_OFFSET-8;
new_relocation->relocation_kind=WORD64_RELOCATION;
}
-# ifdef LINUX
+# ifndef G_MACH_O64
else
# endif
#endif
@@ -874,8 +904,11 @@ static void as_move_d_r (LABEL *label,int arity,int reg1)
reg1_n=reg_num (reg1);
store_c (0x48 | ((reg1_n & 8)>>1));
-#ifdef LINUX
- if (pic_flag && label->label_flags & USE_GOT_LABEL && arity==0){
+#if defined (LINUX) || defined (G_MACH_O64)
+# ifndef G_MACH_O64
+ if (pic_flag)
+# endif
+ if (label->label_flags & USE_GOT_LABEL && arity==0){
store_c (0x8b); /* movq */
store_c (5 | ((reg1_n & 7)<<3));
store_l (0);
@@ -1618,19 +1651,27 @@ static void as_move_instruction (struct instruction *instruction)
instruction->instruction_parameters[1].parameter_data.reg.r);
return;
case P_DESCRIPTOR_NUMBER:
-#ifdef LINUX
- if (pic_flag){
+#if defined (LINUX) || defined (G_MACH_O64)
+# ifndef G_MACH_O64
+ if (pic_flag)
+# endif
+ {
as_move_d_r (instruction->instruction_parameters[0].parameter_data.l,
instruction->instruction_parameters[0].parameter_offset,REGISTER_O0);
as_r_id (0211,REGISTER_O0,
instruction->instruction_parameters[1].parameter_offset,
instruction->instruction_parameters[1].parameter_data.reg.r);
- } else
+ }
+# ifndef G_MACH_O64
+ else
+# endif
#endif
+#ifndef G_MACH_O64
as_d_id (0307,0,instruction->instruction_parameters[0].parameter_data.l,
instruction->instruction_parameters[0].parameter_offset,
instruction->instruction_parameters[1].parameter_offset,
instruction->instruction_parameters[1].parameter_data.reg.r);
+#endif
return;
case P_IMMEDIATE:
if ((int)instruction->instruction_parameters[0].parameter_data.imm!=instruction->instruction_parameters[0].parameter_data.imm){
@@ -2257,8 +2298,11 @@ static void as_cmp_instruction (struct instruction *instruction)
switch (parameter_0.parameter_type){
case P_DESCRIPTOR_NUMBER:
-#ifdef LINUX
- if (pic_flag){
+#if defined (LINUX) || defined (G_MACH_O64)
+# ifndef G_MACH_O64
+ if (pic_flag)
+# endif
+ {
as_move_d_r (parameter_0.parameter_data.l,parameter_0.parameter_offset,REGISTER_O0);
switch (parameter_1.parameter_type){
@@ -2272,8 +2316,12 @@ static void as_cmp_instruction (struct instruction *instruction)
as_x_r (0071,parameter_1.parameter_offset,parameter_1.parameter_data.ir,REGISTER_O0);
return;
}
- } else
+ }
+# ifndef G_MACH_O64
+ else
+# endif
#endif
+#ifndef G_MACH_O64
switch (parameter_1.parameter_type){
case P_REGISTER:
as_d_r2 (0201,0070,0075,parameter_0.parameter_data.l,parameter_0.parameter_offset,
@@ -2288,6 +2336,7 @@ static void as_cmp_instruction (struct instruction *instruction)
parameter_1.parameter_offset,parameter_1.parameter_data.ir);
return;
}
+#endif
break;
case P_IMMEDIATE:
as_cmp_i_parameter (parameter_0.parameter_data.i,&parameter_1);
@@ -2375,6 +2424,9 @@ static void as_cmpw_instruction (struct instruction *instruction)
void store_label_in_data_section (LABEL *label)
{
+#ifdef G_MACH_O64
+ as_data_align_quad();
+#endif
store_label_plus_offset_in_data_section (label,0);
}
@@ -2387,6 +2439,9 @@ void store_label_offset_in_data_section (LABEL *label)
void store_descriptor_in_data_section (LABEL *label)
{
+#ifdef G_MACH_O64
+ as_data_align_quad();
+#endif
store_label_plus_offset_in_data_section (label,2);
#ifndef MACH_O64
@@ -2447,8 +2502,11 @@ static void as_jmp_instruction (struct instruction *instruction)
LABEL *label;
label = instruction->instruction_parameters[0].parameter_data.l;
-#ifdef LINUX
- if (pic_flag && label->label_flags & USE_GOT_LABEL){
+#if defined (LINUX) || defined (G_MACH_O64)
+# ifndef G_MACH_O64
+ if (pic_flag)
+# endif
+ if (label->label_flags & USE_GOT_LABEL){
store_c (0xff);
store_c (0x25);
store_l (0);
@@ -2835,7 +2893,6 @@ static void as_parameter (int code1,int code2,struct parameter *parameter)
}
}
-#endif
/*
From The PowerPC Compiler Writers Guide,
@@ -2885,8 +2942,6 @@ struct ms magic (int_64 d)
return mag;
}
-#ifndef MACH_O64
-
static void as_div_rem_i_instruction (struct instruction *instruction,int compute_remainder)
{
int s_reg1,s_reg2,s_reg3,sd_reg,i_reg,tmp_reg;
@@ -3926,11 +3981,15 @@ static void as_f_i (int code1,int code2,DOUBLE *r_p,int d_freg)
if (data_object_label==NULL)
as_new_data_module();
#endif
-
+#ifndef G_MACH_O64
if (data_object_label->object_section_align<3)
data_object_label->object_section_align=3;
if ((data_buffer_p-current_data_buffer->data-data_object_label->object_label_offset) & 4)
store_long_word_in_data_section (0);
+#else
+ if ((data_buffer_p-current_data_buffer->data) & 4)
+ store_long_word_in_data_section (0);
+#endif
define_data_label (new_label);
store_long_word_in_data_section (((LONG*)r_p)[0]);
@@ -4130,11 +4189,15 @@ static void as_float_neg_instruction (struct instruction *instruction)
if (data_object_label==NULL)
as_new_data_module();
#endif
-
+#ifndef G_MACH_O64
if (data_object_label->object_section_align<4)
data_object_label->object_section_align=4;
while ((data_buffer_p-current_data_buffer->data-data_object_label->object_label_offset) & 0xc)
store_long_word_in_data_section (0);
+#else
+ while ((data_buffer_p-current_data_buffer->data) & 0xc)
+ store_long_word_in_data_section (0);
+#endif
define_data_label (new_label);
store_long_word_in_data_section (0);
@@ -4203,12 +4266,15 @@ static void as_float_abs_instruction (struct instruction *instruction)
if (data_object_label==NULL)
as_new_data_module();
#endif
-
+#ifndef G_MACH_O64
if (data_object_label->object_section_align<4)
data_object_label->object_section_align=4;
while ((data_buffer_p-current_data_buffer->data-data_object_label->object_label_offset) & 0xc)
store_long_word_in_data_section (0);
-
+#else
+ while ((data_buffer_p-current_data_buffer->data) & 0xc)
+ store_long_word_in_data_section (0);
+#endif
define_data_label (new_label);
store_long_word_in_data_section (0xffffffff);
store_long_word_in_data_section (0x7fffffff);
@@ -4357,7 +4423,7 @@ static void create_new_data_object_label (LABEL *label)
++n_object_labels;
string_length=strlen (label->label_name);
-#ifndef ELF
+#if !(defined (ELF) || defined (G_MACH_O64))
if (string_length<8)
new_object_label->object_label_string_offset=0;
else
@@ -4530,7 +4596,7 @@ static void as_labels (struct block_label *labels)
++n_object_labels;
string_length=strlen (label->label_name);
-#ifndef ELF
+#if !(defined (ELF) || defined (G_MACH_O64))
if (string_length<8)
new_object_label->object_label_string_offset=0;
else
@@ -4996,11 +5062,70 @@ static void as_profile_call (struct basic_block *block)
as_branch_label (profile_label,CALL_RELOCATION);
}
+static void align_4 (void)
+{
+#if defined (OPTIMISE_BRANCHES)
+ struct relocation *new_relocation;
+ int align;
+
+ 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;
+
+# ifdef FUNCTION_LEVEL_LINKING
+ align=3 & -(CURRENT_CODE_OFFSET-code_object_label->object_label_offset);
+
+ U5 (new_relocation,
+ relocation_offset=CURRENT_CODE_OFFSET,
+ relocation_kind=ALIGN_RELOCATION,
+ relocation_align1=align,
+ relocation_align2=align,
+ relocation_object_label=code_object_label);
+# else
+ align=3 & code_buffer_free;
+
+ U4 (new_relocation,
+ relocation_offset=CURRENT_CODE_OFFSET,
+ relocation_kind=ALIGN_RELOCATION,
+ relocation_align1=align,
+ relocation_align2=align);
+# endif
+#endif
+
+#if 1
+ switch (3 & code_buffer_free){
+ case 0:
+ break;
+ case 1:
+ store_c (0x90);
+ break;
+ case 2:
+ store_c (0x48);
+ store_c (0x90);
+ break;
+ case 3:
+ store_c (0x48);
+ store_c (0213);
+ store_c (0300 | (reg_num (EBP)<<3) | reg_num (EBP));
+ break;
+ }
+#else
+ while ((code_buffer_free & 3)!=0)
+ store_c (0x90);
+#endif
+}
+
#ifdef NEW_APPLY
extern LABEL *add_empty_node_labels[];
static void as_apply_update_entry (struct basic_block *block)
{
+#if defined (OPTIMISE_BRANCHES) && !defined (FUNCTION_LEVEL_LINKING)
+ align_4();
+#endif
+
if (block->block_profile)
as_profile_call (block);
@@ -5016,6 +5141,25 @@ static void as_apply_update_entry (struct basic_block *block)
store_c (0x90);
store_c (0x90);
+#if defined (OPTIMISE_BRANCHES) && !defined (FUNCTION_LEVEL_LINKING)
+ store_c (0x90);
+ {
+ 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;
+
+ U4 (new_relocation,
+ relocation_offset=CURRENT_CODE_OFFSET,
+ relocation_kind=ALIGN_RELOCATION,
+ relocation_align1=0,
+ relocation_align2=0);
+ }
+ return;
+#endif
} else {
#ifdef LINUX
if (rts_got_flag){
@@ -5061,48 +5205,8 @@ static void write_code (void)
if (block->block_begin_module){
if (block->block_link_module){
if (code_object_label!=NULL && CURRENT_CODE_OFFSET!=code_object_label->object_label_offset && block->block_labels){
-#ifdef OPTIMISE_BRANCHES
- {
- struct relocation *new_relocation;
- int align;
-
- 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;
-
- align=3 & -(CURRENT_CODE_OFFSET-code_object_label->object_label_offset);
+ align_4();
- U5 (new_relocation,
- relocation_offset=CURRENT_CODE_OFFSET,
- relocation_kind=ALIGN_RELOCATION,
- relocation_align1=align,
- relocation_align2=align,
- relocation_object_label=code_object_label);
- }
-#endif
-#if 1
- switch (3 & -(CURRENT_CODE_OFFSET-code_object_label->object_label_offset)){
- case 0:
- break;
- case 1:
- store_c (0x90);
- break;
- case 2:
- store_c (0x48);
- store_c (0x90);
- break;
- case 3:
- store_c (0x48);
- store_c (0213);
- store_c (0300 | (reg_num (EBP)<<3) | reg_num (EBP));
- break;
- }
-#else
- while (((CURRENT_CODE_OFFSET-code_object_label->object_label_offset) & 3)!=0)
- store_c (0x90);
-#endif
{
struct relocation *new_relocation;
@@ -5136,31 +5240,8 @@ static void write_code (void)
if (block->block_n_node_arguments>-100){
#ifndef FUNCTION_LEVEL_LINKING
-# ifdef OPTIMISE_BRANCHES
- {
- struct relocation *new_relocation;
- int align;
-
- 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;
-
- align=code_buffer_free & 3;
-
- U4 (new_relocation,
- relocation_offset=CURRENT_CODE_OFFSET,
- relocation_kind=ALIGN_RELOCATION,
- relocation_align1=align,
- relocation_align2=align);
- }
-# endif
-
- while ((code_buffer_free & 3)!=0)
- store_c (0x90);
+ align_4();
#endif
-
if (block->block_ea_label!=NULL){
extern LABEL *eval_fill_label,*eval_upd_labels[];
int n_node_arguments;
@@ -5186,12 +5267,18 @@ static void write_code (void)
} else
#endif
{
-#ifdef LINUX
+#if defined (LINUX) || defined (G_MACH_O64)
+# ifndef G_MACH_O64
if (pic_flag)
+# endif
as_move_d_r (block->block_ea_label,0,REGISTER_A4);
+# ifndef G_MACH_O64
else
+# endif
#endif
+#ifndef G_MACH_O64
as_move_l_r (block->block_ea_label,REGISTER_A4);
+#endif
store_c (0351);
store_l (0);
@@ -5218,12 +5305,18 @@ static void write_code (void)
store_c (0x90);
}
} else {
-#ifdef LINUX
+#if defined (LINUX) || defined (G_MACH_O64)
+# ifndef G_MACH_O64
if (pic_flag)
+# endif
as_move_d_r (block->block_ea_label,0,REGISTER_D0);
+# ifndef G_MACH_O64
else
+# endif
#endif
+#ifndef G_MACH_O64
as_move_l_r (block->block_ea_label,REGISTER_D0);
+#endif
store_c (0377);
store_c (0340 | reg_num (REGISTER_D0)); /* jmp d0 */
@@ -5234,24 +5327,44 @@ static void write_code (void)
}
if (block->block_descriptor!=NULL && (block->block_n_node_arguments<0 || parallel_flag || module_info_flag)){
+#ifdef G_MACH_O64
+ store_l (4);
+#else
store_l (0);
-#ifdef LINUX
+#endif
+#if defined (LINUX) || defined (G_MACH_O64)
+# ifndef G_MACH_O64
if (pic_flag)
+# endif
store_relative_to_first_byte_label_offset_in_code_section (block->block_descriptor);
+# ifndef G_MACH_O64
else
+# endif
#endif
+#ifndef G_MACH_O64
store_label_in_code_section (block->block_descriptor);
+#endif
} else
store_l (0);
} else
if (block->block_descriptor!=NULL && (block->block_n_node_arguments<0 || parallel_flag || module_info_flag)){
+#ifdef G_MACH_O64
+ store_l (4);
+#else
store_l (0);
-#ifdef LINUX
+#endif
+#if defined (LINUX) || defined (G_MACH_O64)
+# ifndef G_MACH_O64
if (pic_flag)
+# endif
store_relative_to_first_byte_label_offset_in_code_section (block->block_descriptor);
+# ifndef G_MACH_O64
else
+# endif
#endif
+#ifndef G_MACH_O64
store_label_in_code_section (block->block_descriptor);
+#endif
}
/* else
store_l (0);
@@ -5379,9 +5492,69 @@ static int n_sections;
# define ELF_RELOCATION_SECTION_NAME_LENGTH_PREFIX 12
#endif
+#ifdef G_MACH_O64
+static void write_string_16 (char *string)
+{
+ int i;
+
+ i=0;
+
+ while (i<16){
+ char c;
+
+ c=string[i++];
+ write_c (c);
+
+ if (c=='\0'){
+ while (i<16){
+ write_c ('\0');
+ ++i;
+ }
+ return;
+ }
+ }
+}
+
+static void renumber_object_labels (void)
+{
+ struct object_label *object_label;
+ int object_label_n;
+
+ object_label_n=0;
+
+ for_l (object_label,first_object_label,next){
+ switch (object_label->object_label_kind){
+ case EXPORTED_CODE_LABEL:
+ case EXPORTED_DATA_LABEL:
+ {
+ struct label *label;
+
+ label=object_label->object_label_label;
+ label->label_id=object_label_n;
+ object_label->object_label_number=object_label_n;
+ ++object_label_n;
+ }
+ }
+ }
+
+ n_exported_object_labels=object_label_n;
+
+ for_l (object_label,first_object_label,next){
+ if (object_label->object_label_kind==IMPORTED_LABEL){
+ struct label *label;
+
+ label=object_label->object_label_label;
+ label->label_id=object_label_n;
+ object_label->object_label_number=object_label_n;
+ ++object_label_n;
+ }
+ }
+}
+#endif
+
static void write_file_header_and_section_headers (void)
{
-#ifndef ELF
+#if !defined (ELF) && !defined (G_MACH_O64)
int end_section_headers_offset;
write_w (0x8664);
@@ -5595,11 +5768,12 @@ static void write_file_header_and_section_headers (void)
write_l (0x40);
# endif
#else
+# ifdef ELF
unsigned int offset;
int n_code_relocation_sections,n_data_relocation_sections;
int section_strings_size;
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
n_sections=n_code_sections+n_data_sections;
{
@@ -5723,7 +5897,7 @@ static void write_file_header_and_section_headers (void)
section_strings_size+=compute_section_strings_size (7,n_code_sections)+
compute_section_strings_size (7,n_data_sections);
-# endif
+# endif
write_l (0x464c457f);
write_l (0x00010102);
@@ -5737,11 +5911,11 @@ static void write_file_header_and_section_headers (void)
write_l (0);
write_l (0x00000040);
write_l (0x00400000);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
write_l (0x00010000 | (n_sections+n_code_relocation_sections+n_data_relocation_sections+4));
-# else
+# else
write_l (0x00010008);
-# endif
+# endif
write_l (0);
write_l (0);
@@ -5753,32 +5927,32 @@ static void write_file_header_and_section_headers (void)
write_l (0);
write_q (0);
write_q (0);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
offset=0x40+64*(4+n_sections+n_code_relocation_sections+n_data_relocation_sections);
-# else
+# else
offset=0x174;
-# endif
+# endif
write_l (1);
write_l (SHT_STRTAB);
write_q (0);
write_q (0);
write_q (offset);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
write_q ((27+section_strings_size+3) & -4);
-# else
+# else
write_q (60);
-# endif
+# endif
write_l (0);
write_l (0);
write_q (1);
write_q (0);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
offset+=(27+section_strings_size+3) & -4;
-# else
+# else
offset+=60;
-# endif
-# ifdef FUNCTION_LEVEL_LINKING
+# endif
+# ifdef FUNCTION_LEVEL_LINKING
{
struct object_label *object_label;
int code_offset,data_offset,code_relocations_offset,data_relocations_offset,section_string_offset;
@@ -5845,11 +6019,11 @@ static void write_file_header_and_section_headers (void)
if (n_code_relocations_in_section>0){
write_l (section_string_offset);
-# ifdef ELF_RELA
+# ifdef ELF_RELA
write_l (SHT_RELA);
-# else
+# else
write_l (SHT_REL);
-# endif
+# endif
write_q (0);
write_q (0);
write_q (offset+code_relocations_offset);
@@ -5875,11 +6049,11 @@ static void write_file_header_and_section_headers (void)
if (n_data_relocations_in_section>0){
write_l (section_string_offset);
-# ifdef ELF_RELA
+# ifdef ELF_RELA
write_l (SHT_RELA);
-# else
+# else
write_l (SHT_REL);
-# endif
+# endif
write_q (0);
write_q (0);
write_q (offset+data_relocations_offset);
@@ -5895,7 +6069,7 @@ static void write_file_header_and_section_headers (void)
}
offset+=ELF_RELOCATION_SIZE*n_data_relocations;
}
-# else
+# else
write_l (11);
write_l (SHT_PROGBITS);
write_q (SHF_ALLOC | SHF_EXECINSTR);
@@ -5921,11 +6095,11 @@ static void write_file_header_and_section_headers (void)
offset+=(data_buffer_offset+3) & ~3;
write_l (23);
-# ifdef ELF_RELA
+# ifdef ELF_RELA
write_l (SHT_RELA);
-# else
+# else
write_l (SHT_REL);
-# endif
+# endif
write_q (0);
write_q (0);
write_q (offset);
@@ -5937,11 +6111,11 @@ static void write_file_header_and_section_headers (void)
offset+=ELF_RELOCATION_SIZE*n_code_relocations;
write_l (33);
-# ifdef ELF_RELA
+# ifdef ELF_RELA
write_l (SHT_RELA);
-# else
+# else
write_l (SHT_REL);
-# endif
+# endif
write_q (0);
write_q (0);
write_q (offset);
@@ -5951,39 +6125,39 @@ static void write_file_header_and_section_headers (void)
write_q (4);
write_q (ELF_RELOCATION_SIZE);
offset+=ELF_RELOCATION_SIZE*n_data_relocations;
-# endif
+# endif
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
write_l (11+section_strings_size);
-# else
+# else
write_l (43);
-# endif
+# endif
write_l (SHT_SYMTAB);
write_q (0);
write_q (0);
write_q (offset);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
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
+# else
write_q (24*n_object_labels);
write_l (7);
write_l (3);
-# endif
+# endif
write_q (4);
write_q (24);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
offset+=24*(n_object_labels+n_sections);
-# else
+# else
offset+=24*n_object_labels;
-# endif
+# endif
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
write_l (19+section_strings_size);
-# else
+# else
write_l (51);
-# endif
+# endif
write_l (SHT_STRTAB);
write_q (0);
write_q (0);
@@ -5996,7 +6170,7 @@ static void write_file_header_and_section_headers (void)
write_c (0);
write_zstring (".shstrtab");
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
{
struct object_label *object_label;
int section_n;
@@ -6014,35 +6188,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){
-# ifdef ELF_RELA
+# ifdef ELF_RELA
sprintf (section_name,".rela.text.m%d",object_label->object_label_section_n);
-# else
+# else
sprintf (section_name,".rel.text.m%d",object_label->object_label_section_n);
-# endif
+# 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
+# ifdef ELF_RELA
sprintf (section_name,".rela.data.m%d",object_label->object_label_section_n);
-# else
+# else
sprintf (section_name,".rel.data.m%d",object_label->object_label_section_n);
-# endif
+# endif
write_zstring (section_name);
}
}
-# else
+# else
write_zstring (".text");
write_zstring (".data");
-# ifdef ELF_RELA
+# ifdef ELF_RELA
write_zstring (".rela.text");
write_zstring (".rela.data");
-# else
+# else
write_zstring (".rel.text");
write_zstring (".rel.data");
+# endif
# endif
-# endif
write_zstring (".symtab");
write_zstring (".strtab");
@@ -6054,6 +6228,94 @@ static void write_file_header_and_section_headers (void)
write_c (0);
} while (--n);
}
+# else
+ /* G_MACH_O64 */
+ int segment_command_size,text_section_offset,text_section_relocation_offset;
+
+ segment_command_size = sizeof (struct segment_command_64)+2*sizeof (struct section_64);
+
+ write_l (MH_MAGIC_64);
+ write_l (CPU_TYPE_X86_64);
+ write_l (CPU_SUBTYPE_X86_64_ALL);
+ write_l (MH_OBJECT);
+ write_l (3);
+ write_l (segment_command_size+sizeof (struct symtab_command)+sizeof (struct dysymtab_command));
+ write_l (0);
+ write_l (0);
+
+ text_section_offset=sizeof (struct mach_header_64)+segment_command_size+sizeof (struct symtab_command)+sizeof (struct dysymtab_command);
+
+ write_l (LC_SEGMENT_64);
+ write_l (segment_command_size);
+ write_string_16 ("\0");
+ write_q (0);
+ write_q (data_section_begin+data_buffer_offset);
+ write_q (text_section_offset);
+ write_q (code_buffer_offset+data_buffer_offset);
+ write_l (VM_PROT_ALL);
+ write_l (VM_PROT_ALL);
+ write_l (2);
+ write_l (0);
+
+ text_section_relocation_offset=text_section_offset+code_buffer_offset+data_buffer_offset;
+
+ write_string_16 ("__text");
+ write_string_16 ("__TEXT");
+ write_q (0);
+ write_q (code_buffer_offset);
+ write_l (text_section_offset);
+ write_l (2);
+ write_l (text_section_relocation_offset);
+ write_l (n_code_relocations);
+ write_l (S_REGULAR | S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS);
+ write_l (0);
+ write_l (0);
+ write_l (0);
+
+ write_string_16 ("__data");
+ write_string_16 ("__DATA");
+ write_q (data_section_begin);
+ write_q (data_buffer_offset);
+ write_l (text_section_offset+code_buffer_offset);
+ write_l (3);
+ write_l (text_section_relocation_offset+8*n_code_relocations);
+ write_l (n_data_relocations);
+ write_l (S_REGULAR);
+ write_l (0);
+ write_l (0);
+ write_l (0);
+
+ write_l (LC_SYMTAB);
+ write_l (sizeof (struct symtab_command));
+ write_l (text_section_relocation_offset+8*(n_code_relocations+n_data_relocations));
+ write_l (n_object_labels);
+ write_l (text_section_relocation_offset+8*(n_code_relocations+n_data_relocations)+16*n_object_labels);
+ write_l (string_table_offset);
+
+ write_l (LC_DYSYMTAB);
+ write_l (sizeof (struct dysymtab_command));
+
+ write_l (0);
+ write_l (n_section_object_labels);
+ write_l (n_section_object_labels);
+ write_l (n_exported_object_labels);
+ write_l (n_section_object_labels+n_exported_object_labels);
+ write_l (n_object_labels-n_section_object_labels-n_exported_object_labels);
+
+ write_l (0);
+ write_l (0);
+ write_l (0);
+ write_l (0);
+ write_l (0);
+ write_l (0);
+ write_l (text_section_relocation_offset+8*(n_code_relocations+n_data_relocations));
+ write_l (0);
+ write_l (0);
+ write_l (0);
+ write_l (0);
+ write_l (0);
+
+# endif
#endif
}
@@ -6443,7 +6705,7 @@ static void relocate_short_branches_and_move_code (void)
#ifdef FUNCTION_LEVEL_LINKING
new_align= 3 & -(instruction_offset-offset_difference-relocation->relocation_object_label->object_label_offset);
-#else
+#else
new_align= 3 & -(instruction_offset-offset_difference);
#endif
old_align=relocation->relocation_align1;
@@ -6754,7 +7016,7 @@ static void relocate_code (void)
continue;
#endif
}
-#ifdef ELF
+#if defined (ELF) || defined (G_MACH_O64)
case PC_RELATIVE_LONG_WORD_RELOCATION:
relocation_p=&relocation->next;
@@ -6767,11 +7029,15 @@ static void relocate_code (void)
))
{
instruction_offset=relocation->relocation_offset;
- v=label->label_offset;
-
+ v=label->label_offset;
# ifdef FUNCTION_LEVEL_LINKING
v -= label->label_object_label->object_label_offset;
# endif
+# ifdef G_MACH_O64
+ v -= instruction_offset+4;
+ if (label->label_id==DATA_LABEL_ID)
+ v += data_section_begin;
+# endif
# ifdef ELF_RELA
relocation->relocation_addend+=v;
continue;
@@ -6808,6 +7074,10 @@ static void relocate_code (void)
#ifdef FUNCTION_LEVEL_LINKING
v -= label->label_object_label->object_label_offset;
#endif
+#ifdef G_MACH_O64
+ if (label->label_id==DATA_LABEL_ID)
+ v += data_section_begin;
+#endif
#ifdef ELF_RELA
relocation->relocation_addend+=v;
continue;
@@ -6897,53 +7167,53 @@ static void relocate_data (void)
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)
+# 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
+# endif
))
{
int v;
v = label->label_offset;
-#ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
v -= label->label_object_label->object_label_offset;
-#endif
+# endif
relocation->relocation_addend += v;
}
}
-#ifdef LINUX
+# ifdef LINUX
else if (relocation->relocation_kind==PC_RELATIVE_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)
+# 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
+# endif
))
{
int v;
v = label->label_offset;
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
v -= label->label_object_label->object_label_offset;
-# endif
+# 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)
+# 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
+# endif
))
{
int v;
v = label->label_offset;
-#ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
v -= label->label_object_label->object_label_offset;
-#endif
+# endif
relocation->relocation_addend += v;
}
}
-#endif
+# endif
}
#else
struct relocation *relocation;
@@ -6955,28 +7225,59 @@ static void relocate_data (void)
for_l (relocation,first_data_relocation,next){
struct label *label;
-
+# ifdef G_MACH_O64
+ int data_offset,v;
+# endif
+
label=relocation->relocation_label;
- if (relocation->relocation_kind==LONG_WORD_RELOCATION){
+ if (relocation->relocation_kind==LONG_WORD_RELOCATION
+# ifdef G_MACH_O64
+ || relocation->relocation_kind==WORD64_RELOCATION
+# endif
+ ){
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)
+# 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
+# endif
))
{
+# ifndef G_MACH_O64
int data_offset,v;
-
+# endif
+
data_offset=relocation->relocation_offset;
+
+ v = label->label_offset;
+# ifdef FUNCTION_LEVEL_LINKING
+ v -= label->label_object_label->object_label_offset;
+# endif
+# ifdef G_MACH_O64
+ if (label->label_id==DATA_LABEL_ID)
+ v += data_section_begin;
+ } else
+ continue;
+ } else if (relocation->relocation_kind==PC_RELATIVE_LONG_WORD_RELOCATION){
+ if (label->label_id!=DATA_LABEL_ID)
+ internal_error_in_function ("relocate_data");
+
+ data_offset=relocation->relocation_offset;
+
+ v=label->label_offset;
+# ifdef FUNCTION_LEVEL_LINKING
+ v -= label->label_object_label->object_label_offset;
+# endif
+ v -= data_offset;
+ if (label->label_id!=DATA_LABEL_ID)
+ v -= data_section_begin;
+ } else
+ continue;
+# endif
while (data_offset >= data_buffer_offset+BUFFER_SIZE){
object_buffer=object_buffer->next;
data_buffer_offset+=BUFFER_SIZE;
}
-
- v = label->label_offset;
-#ifdef FUNCTION_LEVEL_LINKING
- v -= label->label_object_label->object_label_offset;
-#endif
+
if (data_offset-data_buffer_offset<=BUFFER_SIZE-4){
LONG *data_p;
@@ -7004,8 +7305,10 @@ static void relocate_data (void)
*p2=v>>16;
*p3=v>>24;
}
+# ifndef G_MACH_O64
}
}
+# endif
}
#endif
}
@@ -7036,7 +7339,7 @@ static void as_import_labels (struct label_node *label_node)
label->label_offset=0;
string_length=strlen (label->label_name);
-#ifndef ELF
+#if !(defined (ELF) || defined (G_MACH_O64))
if (string_length<8)
new_object_label->object_label_string_offset=0;
else
@@ -7113,7 +7416,7 @@ static void write_object_labels (void)
switch (object_label->object_label_kind){
case CODE_CONTROL_SECTION:
{
-#ifndef ELF
+#if !(defined (ELF) || defined (MACH_O64))
write_string_8 (".text");
# ifdef FUNCTION_LEVEL_LINKING
@@ -7145,7 +7448,7 @@ static void write_object_labels (void)
#if defined (RELOCATIONS_RELATIVE_TO_EXPORTED_DATA_LABEL) && defined (FUNCTION_LEVEL_LINKING)
current_text_or_data_object_label=object_label;
#endif
-#ifndef ELF
+#if !(defined (ELF) || defined (MACH_O64))
write_string_8 (".data");
# ifdef FUNCTION_LEVEL_LINKING
@@ -7174,22 +7477,23 @@ static void write_object_labels (void)
}
case IMPORTED_LABEL:
{
+#ifndef G_MACH_O64
struct label *label;
label=object_label->object_label_label;
-#ifdef ELF
+# ifdef ELF
write_l (object_label->object_label_string_offset);
write_c (ELF32_ST_INFO (STB_GLOBAL,STT_NOTYPE));
-# ifdef LINUX
+# ifdef LINUX
if (!rts_got_flag)
write_c (STV_PROTECTED);
else
-# endif
+# endif
write_c (0);
write_w (0);
write_q (0);
write_q (0);
-#else
+# else
if (object_label->object_label_string_offset==0)
write_string_8 (label->label_name);
else {
@@ -7202,6 +7506,7 @@ static void write_object_labels (void)
write_w (0);
write_c (C_EXT);
write_c (0);
+# endif
#endif
break;
}
@@ -7231,6 +7536,13 @@ static void write_object_labels (void)
# endif
write_q (0);
#else
+# ifdef G_MACH_O64
+ write_l (object_label->object_label_string_offset);
+ write_c (N_SECT | N_EXT);
+ write_c (1);
+ write_w (0);
+ write_q (label->label_offset);
+# else
if (object_label->object_label_string_offset==0)
write_string_8 (label->label_name);
else {
@@ -7238,16 +7550,17 @@ static void write_object_labels (void)
write_l (object_label->object_label_string_offset);
}
-#ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
write_l (label->label_offset - label->label_object_label->object_label_offset);
write_w (1+label->label_object_label->object_label_section_n);
-#else
+# else
write_l (label->label_offset);
write_w (1);
-#endif
+# endif
write_w (0);
write_c (C_EXT);
write_c (0);
+# endif
#endif
break;
}
@@ -7278,6 +7591,13 @@ static void write_object_labels (void)
# endif
write_q (0);
#else
+# ifdef G_MACH_O64
+ write_l (object_label->object_label_string_offset);
+ write_c (N_SECT | N_EXT);
+ write_c (2);
+ write_w (0);
+ write_q (label->label_offset + data_section_begin);
+# else
if (object_label->object_label_string_offset==0)
write_string_8 (label->label_name);
else {
@@ -7285,20 +7605,21 @@ static void write_object_labels (void)
write_l (object_label->object_label_string_offset);
}
-#ifdef FUNCTION_LEVEL_LINKING
-# ifdef RELOCATIONS_RELATIVE_TO_EXPORTED_DATA_LABEL
+# 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
+# else
write_l (label->label_offset - label->label_object_label->object_label_offset);
-# endif
+# endif
write_w (1+n_code_sections+label->label_object_label->object_label_section_n);
-#else
+# else
write_l (label->label_offset);
write_w (2);
-#endif
+# endif
write_w (0);
write_c (C_EXT);
write_c (0);
+# endif
#endif
break;
}
@@ -7306,6 +7627,21 @@ static void write_object_labels (void)
internal_error_in_function ("write_object_labels");
}
}
+
+#ifdef G_MACH_O64
+ for_l (object_label,first_object_label,next){
+ if (object_label->object_label_kind==IMPORTED_LABEL){
+ struct label *label;
+
+ label=object_label->object_label_label;
+ write_l (object_label->object_label_string_offset);
+ write_c (N_UNDF | N_EXT);
+ write_c (NO_SECT);
+ write_w (0);
+ write_q (label->label_offset);
+ }
+ }
+#endif
}
static void write_string_table (void)
@@ -7369,6 +7705,25 @@ static int elf_label_number (struct label *label)
}
#endif
+#ifdef G_MACH_O64
+static void write_relocation_symbol_number_and_kind (struct label *label,int relocation_type)
+{
+ int label_or_section_number;
+
+ label_or_section_number=label->label_id;
+
+ if (label_or_section_number>=0)
+ relocation_type |= 1<<3;
+ else
+ label_or_section_number += 1-TEXT_LABEL_ID;
+
+ fputc (label_or_section_number,output_file);
+ fputc (label_or_section_number>>8,output_file);
+ fputc (label_or_section_number>>16,output_file);
+ fputc (relocation_type,output_file);
+}
+#endif
+
static void write_code_relocations (void)
{
struct relocation *relocation;
@@ -7384,6 +7739,8 @@ static void write_code_relocations (void)
label=relocation->relocation_label;
#ifdef FUNCTION_LEVEL_LINKING
if (label->label_id==-1)
+#elif defined (G_MACH_O64)
+ if (label->label_id<TEXT_LABEL_ID)
#else
if (label->label_id<0)
#endif
@@ -7402,13 +7759,17 @@ static void write_code_relocations (void)
# endif
#else
write_l (relocation->relocation_offset);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef MACH_O64
+ write_relocation_symbol_number_and_kind (label,(X86_64_RELOC_BRANCH<<4) | (2<<1) | 1);
+# else
+# 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
+# endif
write_l (label->label_id);
write_w (R_REL32);
+# endif
#endif
break;
}
@@ -7419,6 +7780,8 @@ static void write_code_relocations (void)
label=relocation->relocation_label;
#ifdef FUNCTION_LEVEL_LINKING
if (label->label_id==-1)
+#elif defined (G_MACH_O64)
+ if (label->label_id<TEXT_LABEL_ID)
#else
if (label->label_id<0)
#endif
@@ -7437,13 +7800,17 @@ static void write_code_relocations (void)
# endif
#else
write_l (relocation->relocation_offset);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef MACH_O64
+ write_relocation_symbol_number_and_kind (label,(X86_64_RELOC_UNSIGNED<<4) | (2<<1));
+# else
+# 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
+# endif
write_l (label->label_id);
write_w (R_ADDR32);
+# endif
#endif
break;
}
@@ -7454,6 +7821,8 @@ static void write_code_relocations (void)
label=relocation->relocation_label;
#ifdef FUNCTION_LEVEL_LINKING
if (label->label_id==-1)
+#elif defined (G_MACH_O64)
+ if (label->label_id<TEXT_LABEL_ID)
#else
if (label->label_id<0)
#endif
@@ -7472,13 +7841,17 @@ static void write_code_relocations (void)
# endif
#else
write_l (relocation->relocation_offset);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef MACH_O64
+ write_relocation_symbol_number_and_kind (label,(X86_64_RELOC_SIGNED<<4) | (2<<1) | 1);
+# else
+# 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
+# endif
write_l (label->label_id);
write_w (R_REL32);
+# endif
#endif
break;
}
@@ -7491,29 +7864,29 @@ static void write_code_relocations (void)
if (label->label_id==-1)
internal_error_in_function ("write_code_relocations");
-#ifdef ELF
+# ifdef ELF
write_q (relocation->relocation_offset - 4);
write_l (R_X86_64_NONE);
write_l (elf_label_number (label));
-# ifdef ELF_RELA
+# ifdef ELF_RELA
write_q (relocation->relocation_addend);
-# endif
-#else
+# 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
write_l (label->label_id);
-# if 1
+# if 1
write_w (R_ABSOLUTE);
-# else
+# else
write_w (R_REL32);
+# endif
# endif
-#endif
break;
}
#endif
-#ifdef LINUX
+#if defined (LINUX) && !defined (MACH_O64)
case GOT_PC_RELATIVE_RELOCATION:
{
struct label *label;
@@ -7582,6 +7955,8 @@ static void write_data_relocations (void)
label=relocation->relocation_label;
#ifdef FUNCTION_LEVEL_LINKING
if (label->label_id==-1)
+#elif defined (G_MACH_O64)
+ if (label->label_id<TEXT_LABEL_ID)
#else
if (label->label_id<0)
#endif
@@ -7600,49 +7975,61 @@ static void write_data_relocations (void)
# endif
#else
write_l (relocation->relocation_offset);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef MACH_O64
+ write_relocation_symbol_number_and_kind (label,(X86_64_RELOC_UNSIGNED<<4) | (2<<1));
+# else
+# 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
+# endif
write_l (label->label_id);
write_w (R_ADDR32);
+# endif
#endif
break;
}
#ifdef LINUX
case PC_RELATIVE_LONG_WORD_RELOCATION:
{
+# ifndef MACH_O64
struct label *label;
label=relocation->relocation_label;
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
if (label->label_id==-1)
-# else
+# elif defined (G_MACH_O64) /* not used */
+ if (label->label_id<TEXT_LABEL_ID)
+# else
if (label->label_id<0)
-# endif
+# endif
internal_error_in_function ("write_data_relocations");
-# ifdef ELF
+# ifdef ELF
write_q (relocation->relocation_offset);
write_l (R_X86_64_PC32);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
write_l (elf_label_number (label));
-# else
+# else
write_l (label->label_id);
-# endif
-# ifdef ELF_RELA
+# endif
+# ifdef ELF_RELA
write_q (relocation->relocation_addend);
-# endif
-# else
+# endif
+# else
write_l (relocation->relocation_offset);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef G_MACH_O64 /* not used */
+ write_relocation_symbol_number_and_kind (label,(X86_64_RELOC_SIGNED<<4) | (2<<1) | 1);
+# else
+# 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
+# endif
write_l (label->label_id);
write_w (R_REL32);
+# endif
+# endif
# endif
break;
}
@@ -7651,34 +8038,44 @@ static void write_data_relocations (void)
struct label *label;
label=relocation->relocation_label;
-#ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
if (label->label_id==-1)
-#else
+# elif defined (G_MACH_O64)
+ if (label->label_id<TEXT_LABEL_ID)
+# else
if (label->label_id<0)
-#endif
+# endif
internal_error_in_function ("write_data_relocations");
-#ifdef ELF
+# ifdef ELF
write_q (relocation->relocation_offset);
write_l (R_X86_64_64);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef FUNCTION_LEVEL_LINKING
write_l (elf_label_number (label));
-# else
+# else
write_l (label->label_id);
-# endif
-# ifdef ELF_RELA
+# endif
+# ifdef ELF_RELA
write_q (relocation->relocation_addend);
-# endif
-#else
+# endif
+# else
write_l (relocation->relocation_offset);
-# ifdef FUNCTION_LEVEL_LINKING
+# ifdef MACH_O64
+ write_relocation_symbol_number_and_kind (label,(X86_64_RELOC_UNSIGNED<<4) | (3<<1));
+# else
+# 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
+# endif
write_l (label->label_id);
+# if 1
+ write_w (-1);
+# else
write_w (R_ADDR64);
-#endif
+# endif
+# endif
+# endif
break;
}
#endif
@@ -7700,13 +8097,23 @@ void assemble_code (void)
flush_data_buffer();
flush_code_buffer();
+#ifdef G_MACH_O64
+ renumber_object_labels();
+#endif
+
#if defined (OPTIMISE_BRANCHES)
optimise_branches();
#endif
#ifndef FUNCTION_LEVEL_LINKING
+# ifndef G_MACH_O64
code_object_label->object_label_length=code_buffer_offset;
data_object_label->object_label_length=data_buffer_offset;
+# endif
+#endif
+
+#ifdef G_MACH_O64
+ data_section_begin = (code_buffer_offset+7) & -8;
#endif
relocate_code();
@@ -7745,11 +8152,3 @@ void assemble_code (void)
write_object_labels();
write_string_table();
}
-
-#else
-
-void define_exported_data_label_with_offset (LABEL *label,int offset)
-{
-}
-
-#endif