| 1 |
/* BFD back-end for IBM RS/6000 "XCOFF64" files. |
/* BFD back-end for IBM RS/6000 "XCOFF64" files. |
| 2 |
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 |
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
| 3 |
Free Software Foundation, Inc. |
Free Software Foundation, Inc. |
| 4 |
Written Clinton Popetz. |
Written Clinton Popetz. |
| 5 |
Contributed by Cygnus Support. |
Contributed by Cygnus Support. |
| 381 |
|
|
| 382 |
/* RS/6000 "csect" auxents */ |
/* RS/6000 "csect" auxents */ |
| 383 |
case C_EXT: |
case C_EXT: |
| 384 |
|
case C_AIX_WEAKEXT: |
| 385 |
case C_HIDEXT: |
case C_HIDEXT: |
| 386 |
if (indx + 1 == numaux) |
if (indx + 1 == numaux) |
| 387 |
{ |
{ |
| 474 |
|
|
| 475 |
/* RS/6000 "csect" auxents */ |
/* RS/6000 "csect" auxents */ |
| 476 |
case C_EXT: |
case C_EXT: |
| 477 |
|
case C_AIX_WEAKEXT: |
| 478 |
case C_HIDEXT: |
case C_HIDEXT: |
| 479 |
if (indx + 1 == numaux) |
if (indx + 1 == numaux) |
| 480 |
{ |
{ |
| 769 |
file_ptr sym_base; |
file_ptr sym_base; |
| 770 |
unsigned long reloc_size = 0; |
unsigned long reloc_size = 0; |
| 771 |
unsigned long lnno_size = 0; |
unsigned long lnno_size = 0; |
|
bfd_boolean long_section_names; |
|
| 772 |
asection *text_sec = ((void *) 0); |
asection *text_sec = ((void *) 0); |
| 773 |
asection *data_sec = ((void *) 0); |
asection *data_sec = ((void *) 0); |
| 774 |
asection *bss_sec = ((void *) 0); |
asection *bss_sec = ((void *) 0); |
| 838 |
if (bfd_seek (abfd, scn_base, SEEK_SET) != 0) |
if (bfd_seek (abfd, scn_base, SEEK_SET) != 0) |
| 839 |
return FALSE; |
return FALSE; |
| 840 |
|
|
|
long_section_names = FALSE; |
|
| 841 |
for (current = abfd->sections; current != NULL; current = current->next) |
for (current = abfd->sections; current != NULL; current = current->next) |
| 842 |
{ |
{ |
| 843 |
struct internal_scnhdr section; |
struct internal_scnhdr section; |
| 1050 |
case bfd_arch_powerpc: |
case bfd_arch_powerpc: |
| 1051 |
if (bfd_get_mach (abfd) == bfd_mach_ppc) |
if (bfd_get_mach (abfd) == bfd_mach_ppc) |
| 1052 |
internal_a.o_cputype = 3; |
internal_a.o_cputype = 3; |
| 1053 |
|
else if (bfd_get_mach (abfd) == bfd_mach_ppc_620) |
| 1054 |
|
internal_a.o_cputype = 2; |
| 1055 |
else |
else |
| 1056 |
internal_a.o_cputype = 1; |
internal_a.o_cputype = 1; |
| 1057 |
break; |
break; |
| 1119 |
bfd_byte *contents; |
bfd_byte *contents; |
| 1120 |
{ |
{ |
| 1121 |
struct xcoff_link_hash_entry *h; |
struct xcoff_link_hash_entry *h; |
| 1122 |
|
bfd_vma section_offset; |
| 1123 |
|
|
| 1124 |
if (0 > rel->r_symndx) |
if (0 > rel->r_symndx) |
| 1125 |
return FALSE; |
return FALSE; |
| 1126 |
|
|
| 1127 |
h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx]; |
h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx]; |
| 1128 |
|
section_offset = rel->r_vaddr - input_section->vma; |
| 1129 |
|
|
| 1130 |
/* If we see an R_BR or R_RBR reloc which is jumping to global |
/* If we see an R_BR or R_RBR reloc which is jumping to global |
| 1131 |
linkage code, and it is followed by an appropriate cror nop |
linkage code, and it is followed by an appropriate cror nop |
| 1135 |
going to global linkage code, we can replace the load with a |
going to global linkage code, we can replace the load with a |
| 1136 |
cror. */ |
cror. */ |
| 1137 |
if (NULL != h |
if (NULL != h |
| 1138 |
&& bfd_link_hash_defined == h->root.type |
&& (bfd_link_hash_defined == h->root.type |
| 1139 |
&& rel->r_vaddr - input_section->vma + 8 <= input_section->size) |
|| bfd_link_hash_defweak == h->root.type) |
| 1140 |
|
&& section_offset + 8 <= input_section->size) |
| 1141 |
{ |
{ |
| 1142 |
bfd_byte *pnext; |
bfd_byte *pnext; |
| 1143 |
unsigned long next; |
unsigned long next; |
| 1144 |
|
|
| 1145 |
pnext = contents + (rel->r_vaddr - input_section->vma) + 4; |
pnext = contents + section_offset + 4; |
| 1146 |
next = bfd_get_32 (input_bfd, pnext); |
next = bfd_get_32 (input_bfd, pnext); |
| 1147 |
|
|
| 1148 |
/* The _ptrgl function is magic. It is used by the AIX compiler to call |
/* The _ptrgl function is magic. It is used by the AIX compiler to call |
| 1171 |
howto->complain_on_overflow = complain_overflow_dont; |
howto->complain_on_overflow = complain_overflow_dont; |
| 1172 |
} |
} |
| 1173 |
|
|
| 1174 |
howto->pc_relative = TRUE; |
/* The original PC-relative relocation is biased by -r_vaddr, so adding |
| 1175 |
|
the value below will give the absolute target address. */ |
| 1176 |
|
*relocation = val + addend + rel->r_vaddr; |
| 1177 |
|
|
| 1178 |
howto->src_mask &= ~3; |
howto->src_mask &= ~3; |
| 1179 |
howto->dst_mask = howto->src_mask; |
howto->dst_mask = howto->src_mask; |
| 1180 |
|
|
| 1181 |
/* A PC relative reloc includes the section address. */ |
if (h != NULL |
| 1182 |
addend += input_section->vma; |
&& (h->root.type == bfd_link_hash_defined |
| 1183 |
|
|| h->root.type == bfd_link_hash_defweak) |
| 1184 |
*relocation = val + addend; |
&& bfd_is_abs_section (h->root.u.def.section) |
| 1185 |
*relocation -= (input_section->output_section->vma |
&& section_offset + 4 <= input_section->size) |
| 1186 |
+ input_section->output_offset); |
{ |
| 1187 |
|
bfd_byte *ptr; |
| 1188 |
|
bfd_vma insn; |
| 1189 |
|
|
| 1190 |
|
/* Turn the relative branch into an absolute one by setting the |
| 1191 |
|
AA bit. */ |
| 1192 |
|
ptr = contents + section_offset; |
| 1193 |
|
insn = bfd_get_32 (input_bfd, ptr); |
| 1194 |
|
insn |= 2; |
| 1195 |
|
bfd_put_32 (input_bfd, insn, ptr); |
| 1196 |
|
|
| 1197 |
|
/* Make the howto absolute too. */ |
| 1198 |
|
howto->pc_relative = FALSE; |
| 1199 |
|
howto->complain_on_overflow = complain_overflow_bitfield; |
| 1200 |
|
} |
| 1201 |
|
else |
| 1202 |
|
{ |
| 1203 |
|
/* Use a PC-relative howto and subtract the instruction's address |
| 1204 |
|
from the target address we calculated above. */ |
| 1205 |
|
howto->pc_relative = TRUE; |
| 1206 |
|
*relocation -= (input_section->output_section->vma |
| 1207 |
|
+ input_section->output_offset |
| 1208 |
|
+ section_offset); |
| 1209 |
|
} |
| 1210 |
return TRUE; |
return TRUE; |
| 1211 |
} |
} |
| 1212 |
|
|
| 1297 |
} |
} |
| 1298 |
else |
else |
| 1299 |
{ |
{ |
| 1300 |
|
if (info->unresolved_syms_in_objects != RM_IGNORE |
| 1301 |
|
&& (h->flags & XCOFF_WAS_UNDEFINED) != 0) |
| 1302 |
|
{ |
| 1303 |
|
if (! ((*info->callbacks->undefined_symbol) |
| 1304 |
|
(info, h->root.root.string, |
| 1305 |
|
input_bfd, input_section, |
| 1306 |
|
rel->r_vaddr - input_section->vma, |
| 1307 |
|
(info->unresolved_syms_in_objects |
| 1308 |
|
== RM_GENERATE_ERROR)))) |
| 1309 |
|
return FALSE; |
| 1310 |
|
} |
| 1311 |
if (h->root.type == bfd_link_hash_defined |
if (h->root.type == bfd_link_hash_defined |
| 1312 |
|| h->root.type == bfd_link_hash_defweak) |
|| h->root.type == bfd_link_hash_defweak) |
| 1313 |
{ |
{ |
| 1322 |
val = (sec->output_section->vma |
val = (sec->output_section->vma |
| 1323 |
+ sec->output_offset); |
+ sec->output_offset); |
| 1324 |
} |
} |
| 1325 |
else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT))) |
else |
|
&& ! info->relocatable) |
|
| 1326 |
{ |
{ |
| 1327 |
if (! ((*info->callbacks->undefined_symbol) |
BFD_ASSERT (info->relocatable |
| 1328 |
(info, h->root.root.string, input_bfd, input_section, |
|| (h->flags & XCOFF_DEF_DYNAMIC) != 0 |
| 1329 |
rel->r_vaddr - input_section->vma, TRUE))) |
|| (h->flags & XCOFF_IMPORT) != 0); |
|
return FALSE; |
|
|
|
|
|
/* Don't try to process the reloc. It can't help, and |
|
|
it may generate another error. */ |
|
|
continue; |
|
| 1330 |
} |
} |
| 1331 |
} |
} |
| 1332 |
} |
} |
| 2597 |
LINESZ, |
LINESZ, |
| 2598 |
FILNMLEN, |
FILNMLEN, |
| 2599 |
TRUE, /* _bfd_coff_long_filenames */ |
TRUE, /* _bfd_coff_long_filenames */ |
| 2600 |
FALSE, /* _bfd_coff_long_section_names */ |
XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */ |
| 2601 |
3, /* _bfd_coff_default_section_alignment_power */ |
3, /* _bfd_coff_default_section_alignment_power */ |
| 2602 |
TRUE, /* _bfd_coff_force_symnames_in_strings */ |
TRUE, /* _bfd_coff_force_symnames_in_strings */ |
| 2603 |
4, /* _bfd_coff_debug_string_prefix_length */ |
4, /* _bfd_coff_debug_string_prefix_length */ |
| 2805 |
bfd_generic_is_group_section, |
bfd_generic_is_group_section, |
| 2806 |
bfd_generic_discard_group, |
bfd_generic_discard_group, |
| 2807 |
_bfd_generic_section_already_linked, |
_bfd_generic_section_already_linked, |
| 2808 |
|
_bfd_xcoff_define_common_symbol, |
| 2809 |
|
|
| 2810 |
/* Dynamic */ |
/* Dynamic */ |
| 2811 |
_bfd_xcoff_get_dynamic_symtab_upper_bound, |
_bfd_xcoff_get_dynamic_symtab_upper_bound, |
| 2852 |
LINESZ, |
LINESZ, |
| 2853 |
FILNMLEN, |
FILNMLEN, |
| 2854 |
TRUE, /* _bfd_coff_long_filenames */ |
TRUE, /* _bfd_coff_long_filenames */ |
| 2855 |
FALSE, /* _bfd_coff_long_section_names */ |
XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */ |
| 2856 |
3, /* _bfd_coff_default_section_alignment_power */ |
3, /* _bfd_coff_default_section_alignment_power */ |
| 2857 |
TRUE, /* _bfd_coff_force_symnames_in_strings */ |
TRUE, /* _bfd_coff_force_symnames_in_strings */ |
| 2858 |
4, /* _bfd_coff_debug_string_prefix_length */ |
4, /* _bfd_coff_debug_string_prefix_length */ |
| 3059 |
bfd_generic_is_group_section, |
bfd_generic_is_group_section, |
| 3060 |
bfd_generic_discard_group, |
bfd_generic_discard_group, |
| 3061 |
_bfd_generic_section_already_linked, |
_bfd_generic_section_already_linked, |
| 3062 |
|
_bfd_xcoff_define_common_symbol, |
| 3063 |
|
|
| 3064 |
/* Dynamic */ |
/* Dynamic */ |
| 3065 |
_bfd_xcoff_get_dynamic_symtab_upper_bound, |
_bfd_xcoff_get_dynamic_symtab_upper_bound, |