diff options
author | Clément Chigot <clement.chigot@atos.net> | 2021-03-11 11:08:19 +0100 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-03-12 22:47:23 +1030 |
commit | 4a403be0c1b4540e22c8c608ea0bfecbf0f85e51 (patch) | |
tree | 3908b8d38af9e56e3fd960da596c4d600f5915c5 /bfd/coff-rs6000.c | |
parent | 2c1bef53dee85aede31e6de6fa8276d6869f6512 (diff) | |
download | gdb-4a403be0c1b4540e22c8c608ea0bfecbf0f85e51.zip gdb-4a403be0c1b4540e22c8c608ea0bfecbf0f85e51.tar.gz gdb-4a403be0c1b4540e22c8c608ea0bfecbf0f85e51.tar.bz2 |
aix: implement R_TOCU and R_TOCL relocations
Implement support for largetoc on XCOFF.
R_TOCU and R_TOCL are referenced by the new BFD defines:
BFD_RELOC_PPC_TOC16_HI and BFD_RELOC_PPC_TOC16_LO.
A new toc storage class is added XMC_TE.
In order to correctly handle R_TOCU, the logic behind
xcoff_reloc_type_toc is changed to compute the whole TOC offset
instead of just the difference between the "link" offset and the
"assembly" offset.
In gas, add a function to transform addis format used by AIX
"addis RT, D(RA)" into the ELF format "addis RT, RA, SI".
bfd/
* reloc.c (BFD_RELOC_PPC_TOC16_HI, BFD_RELOC_PPC_TOC16_LO):
New relocations.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
* coff-rs6000.c (xcoff_calculate_relocation): Call
xcoff_reloc_type_toc for R_TOCU and R_TOCL.
(xcoff_howto_table): Remove src_mask for TOC relocations.
Add R_TOCU and R_TOCL howtos.
(_bfd_xcoff_reloc_type_lookup): Add cases for
BFD_RELOC_PPC_TOC16_HI and BFD_RELOC_PPC_TOC16_LO.
(xcoff_reloc_type_toc): Compute the whole offset.
Implement R_TOCU and R_TOCL.
* coff64-rs6000.c (xcoff64_calculate_relocation):
Likewise.
(xcoff64_howto_table): Likewise.
(xcoff64_reloc_type_lookup): Likewise.
gas/
* config/tc-ppc.c (ppc_xcoff_suffix): New function.
(MAP, MAP32, MAP64): New macros for XCOFF.
(ppc_xcoff_fixup_addis): New function.
(ppc_is_toc_sym): Handle XMC_TE.
(fixup_size): Add cases for BFD_RELOC_PPC_TOC16_HI and
BFD_RELOC_PPC_TOC16_LO.
(md_assemble): Call ppc_xcoff_fixup_addis for XCOFF.
(ppc_change_csect): Handle XMC_TE.
(ppc_tc): Enable .tc symbols to have only a XMC_TC or XMC_TE
storage class.
(ppc_symbol_new_hook): Handle XMC_TE.
(ppc_frob_symbol): Likewise.
(ppc_fix_adjustable): Likewise.
(md_apply_fix): Handle BFD_RELOC_PPC_TOC16_HI and
BFD_RELOC_PPC_TOC16_LO.
ld/
* scripttempl/aix.sc: Add .te to .data section.
* testsuite/ld-powerpc/aix52.exp: Add test structure for AIX7+.
Add aix-largetoc-1 test.
* testsuite/ld-powerpc/aix-largetoc-1-32.d: New test.
* testsuite/ld-powerpc/aix-largetoc-1-64.d: New test.
* testsuite/ld-powerpc/aix-largetoc-1.ex: New test.
* testsuite/ld-powerpc/aix-largetoc-1.s: New test.
Diffstat (limited to 'bfd/coff-rs6000.c')
-rw-r--r-- | bfd/coff-rs6000.c | 70 |
1 files changed, 56 insertions, 14 deletions
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 2cae299..b77ff0c 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -206,8 +206,8 @@ xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = xcoff_reloc_type_fail, /* (0x2d) */ xcoff_reloc_type_fail, /* (0x2e) */ xcoff_reloc_type_fail, /* (0x2f) */ - xcoff_reloc_type_fail, /* R_TOCU (0x30) */ - xcoff_reloc_type_fail, /* R_TOCL (0x31) */ + xcoff_reloc_type_toc, /* R_TOCU (0x30) */ + xcoff_reloc_type_toc, /* R_TOCL (0x31) */ }; xcoff_complain_function *const @@ -745,7 +745,7 @@ reloc_howto_type xcoff_howto_table[] = 0, /* special_function */ "R_TOC", /* name */ TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ + 0, /* src_mask */ 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ @@ -760,7 +760,7 @@ reloc_howto_type xcoff_howto_table[] = 0, /* special_function */ "R_TRL", /* name */ TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ + 0, /* src_mask */ 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ @@ -775,7 +775,7 @@ reloc_howto_type xcoff_howto_table[] = 0, /* special_function */ "R_GL", /* name */ TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ + 0, /* src_mask */ 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ @@ -790,7 +790,7 @@ reloc_howto_type xcoff_howto_table[] = 0, /* special_function */ "R_TCL", /* name */ TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ + 0, /* src_mask */ 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ @@ -892,7 +892,7 @@ reloc_howto_type xcoff_howto_table[] = 0, /* special_function */ "R_TRLA", /* name */ TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ + 0, /* src_mask */ 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ @@ -1093,10 +1093,34 @@ reloc_howto_type xcoff_howto_table[] = EMPTY_HOWTO(0x2f), /* 0x30: High-order 16 bit TOC relative relocation. */ - EMPTY_HOWTO (R_TOCU), + HOWTO (R_TOCU, /* type */ + 16, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_TOCU", /* name */ + TRUE, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ /* 0x31: Low-order 16 bit TOC relative relocation. */ - EMPTY_HOWTO (R_TOCL), + HOWTO (R_TOCL, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + 0, /* special_function */ + "R_TOCL", /* name */ + TRUE, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; @@ -1145,6 +1169,10 @@ _bfd_xcoff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, return &xcoff_howto_table[8]; case BFD_RELOC_PPC_TOC16: return &xcoff_howto_table[3]; + case BFD_RELOC_PPC_TOC16_HI: + return &xcoff_howto_table[0x30]; + case BFD_RELOC_PPC_TOC16_LO: + return &xcoff_howto_table[0x31]; case BFD_RELOC_PPC_B16: return &xcoff_howto_table[0x1d]; case BFD_RELOC_32: @@ -2904,7 +2932,7 @@ xcoff_reloc_type_toc (bfd *input_bfd, asection *input_section ATTRIBUTE_UNUSED, bfd *output_bfd, struct internal_reloc *rel, - struct internal_syment *sym, + struct internal_syment *sym ATTRIBUTE_UNUSED, struct reloc_howto_struct *howto ATTRIBUTE_UNUSED, bfd_vma val, bfd_vma addend ATTRIBUTE_UNUSED, @@ -2935,8 +2963,16 @@ xcoff_reloc_type_toc (bfd *input_bfd, + h->toc_section->output_offset); } - *relocation = ((val - xcoff_data (output_bfd)->toc) - - (sym->n_value - xcoff_data (input_bfd)->toc)); + /* We can't use the preexisting value written down by the + assembly, as R_TOCU needs to be adjusted when the final + R_TOCL value is signed. */ + *relocation = val - xcoff_data (output_bfd)->toc; + + if (rel->r_type == R_TOCU) + *relocation = ((*relocation + 0x8000) >> 16) & 0xffff; + if (rel->r_type == R_TOCL) + *relocation = *relocation & 0x0000ffff; + return TRUE; } @@ -3299,8 +3335,6 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd, quite figure out when this is useful. These relocs are not defined by the PowerOpen ABI. - R_TOCU - R_TOCL R_TLS R_TLS_IE R_TLS_LD @@ -3402,6 +3436,14 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd, The PowerPC ABI defines this as an absolute branch to a fixed address which may be modified to a relative branch. The PowerOpen ABI does not define this relocation type. + + R_TOCU: + Upper TOC relative relocation. The value is the + high-order 16 bit of a TOC relative relocation. + + R_TOCL: + Lower TOC relative relocation. The value is the + low-order 16 bit of a TOC relative relocation. */ bfd_boolean |