diff options
author | Cl?ment Chigot <clement.chigot@atos.net> | 2021-04-20 14:40:43 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2021-04-20 14:40:43 +0100 |
commit | c5df7e442e6cdc9303b7373842370d6ee8f67ea5 (patch) | |
tree | 28e1442062fdbb13b5c46d98ceeba9c556e6f3b0 /bfd | |
parent | d549b029d6d622af531211ef4c7bc48cb5011d93 (diff) | |
download | gdb-c5df7e442e6cdc9303b7373842370d6ee8f67ea5.zip gdb-c5df7e442e6cdc9303b7373842370d6ee8f67ea5.tar.gz gdb-c5df7e442e6cdc9303b7373842370d6ee8f67ea5.tar.bz2 |
Rework the R_NEG support on both gas and ld for the PowerPC AIX targets, in order to manage C++ exceptions built with GCC.
bfd PR binutils/21700
* reloc.c (BFD_RELOC_PPC_NEG): New relocation.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
* coff-rs6000.c (_bfd_xcoff_reloc_type_lookup): Add
BFD_RELOC_PPC_NEG handler.
(xcoff_reloc_type_neg): Correctly substract addend.
* coff64-rs6000.c (xcoff64_howto_table): Add R_NEG_32
howto.
(xcoff64_rtype2howto): Add handler for R_NEG_32.
(xcoff64_reloc_type_lookup): Add BFD_RELOC_PPC_NEG handler.
* xcofflink.c (xcoff_need_ldrel_p): Check output section
for R_POS-like relocations. New argument added.
(xcoff_mark): Adapt to new xcoff_need_ldrel_p argument.
(xcoff_link_input_bfd): Likewise.
gas * config/tc-ppc.c (ppc_get_csect_to_adjust): New function.
(ppc_fix_adjustable): Manage fx_subsy part.
(tc_gen_reloc): Create second relocation when both
fx_addsy and fx_subsy are provided.
* config/tc-ppc.h (RELOC_EXPANSION_POSSIBLE): New define.
(MAX_RELOC_EXPANSION): Likewise.
(TC_FORCE_RELOCATION_SUB_SAME): Likewise
(UNDEFINED_DIFFERENCE_OK): Likewise
* testsuite/gas/all/gas.exp: Skip difference between two
undefined symbols test.
ld * testsuite/ld-powerpc/aix52.exp: Add new test.
* testsuite/ld-powerpc/aix-neg-reloc-32.d: New test.
* testsuite/ld-powerpc/aix-neg-reloc-64.d: New test.
* testsuite/ld-powerpc/aix-neg-reloc.ex: New test.
* testsuite/ld-powerpc/aix-neg-reloc.s: New test.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 18 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 1 | ||||
-rw-r--r-- | bfd/coff-rs6000.c | 4 | ||||
-rw-r--r-- | bfd/coff64-rs6000.c | 21 | ||||
-rw-r--r-- | bfd/libbfd.h | 1 | ||||
-rw-r--r-- | bfd/reloc.c | 2 | ||||
-rw-r--r-- | bfd/xcofflink.c | 14 |
7 files changed, 56 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 513d6e9..972311b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,21 @@ +2021-04-20 Clément Chigot <clement.chigot@atos.net> + + PR binutils/21700 + * reloc.c (BFD_RELOC_PPC_NEG): New relocation. + * bfd-in2.h: Regenerate. + * libbfd.h: Regenerate. + * coff-rs6000.c (_bfd_xcoff_reloc_type_lookup): Add + BFD_RELOC_PPC_NEG handler. + (xcoff_reloc_type_neg): Correctly substract addend. + * coff64-rs6000.c (xcoff64_howto_table): Add R_NEG_32 + howto. + (xcoff64_rtype2howto): Add handler for R_NEG_32. + (xcoff64_reloc_type_lookup): Add BFD_RELOC_PPC_NEG handler. + * xcofflink.c (xcoff_need_ldrel_p): Check output section + for R_POS-like relocations. New argument added. + (xcoff_mark): Adapt to new xcoff_need_ldrel_p argument. + (xcoff_link_input_bfd): Likewise. + 2021-04-16 Alan Modra <amodra@gmail.com> PR 27567 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index cdfb933..d5780e4 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2921,6 +2921,7 @@ instruction. */ BFD_RELOC_PPC_VLE_SDAREL_HA16D, BFD_RELOC_PPC_16DX_HA, BFD_RELOC_PPC_REL16DX_HA, + BFD_RELOC_PPC_NEG, BFD_RELOC_PPC64_HIGHER, BFD_RELOC_PPC64_HIGHER_S, BFD_RELOC_PPC64_HIGHEST, diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 237c7ed..7cfe404 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -1253,6 +1253,8 @@ _bfd_xcoff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, return &xcoff_howto_table[0]; case BFD_RELOC_NONE: return &xcoff_howto_table[0xf]; + case BFD_RELOC_PPC_NEG: + return &xcoff_howto_table[0x1]; case BFD_RELOC_PPC_TLSGD: return &xcoff_howto_table[0x20]; case BFD_RELOC_PPC_TLSIE: @@ -2985,7 +2987,7 @@ xcoff_reloc_type_neg (bfd *input_bfd ATTRIBUTE_UNUSED, bfd_vma *relocation, bfd_byte *contents ATTRIBUTE_UNUSED) { - *relocation = addend - val; + *relocation = - val - addend; return true; } diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index cc671b2..8895340 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -1320,7 +1320,21 @@ reloc_howto_type xcoff64_howto_table[] = MINUS_ONE, /* dst_mask */ false), /* pcrel_offset */ - EMPTY_HOWTO(0x26), + /* 0x26: 32 bit relocation, but store negative value. */ + HOWTO (R_NEG, /* type */ + 0, /* rightshift */ + -2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_NEG_32", /* name */ + true, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + EMPTY_HOWTO(0x27), EMPTY_HOWTO(0x28), EMPTY_HOWTO(0x29), @@ -1386,6 +1400,9 @@ xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal) { if (R_POS == internal->r_type) relent->howto = &xcoff64_howto_table[0x1c]; + + if (R_NEG == internal->r_type) + relent->howto = &xcoff64_howto_table[0x26]; } /* The r_size field of an XCOFF reloc encodes the bitsize of the @@ -1426,6 +1443,8 @@ xcoff64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, return &xcoff64_howto_table[0]; case BFD_RELOC_NONE: return &xcoff64_howto_table[0xf]; + case BFD_RELOC_PPC_NEG: + return &xcoff64_howto_table[0x1]; case BFD_RELOC_PPC64_TLSGD: return &xcoff64_howto_table[0x20]; case BFD_RELOC_PPC64_TLSIE: diff --git a/bfd/libbfd.h b/bfd/libbfd.h index f1d25d0..bee1a1f 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1510,6 +1510,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_PPC_VLE_SDAREL_HA16D", "BFD_RELOC_PPC_16DX_HA", "BFD_RELOC_PPC_REL16DX_HA", + "BFD_RELOC_PPC_NEG", "BFD_RELOC_PPC64_HIGHER", "BFD_RELOC_PPC64_HIGHER_S", "BFD_RELOC_PPC64_HIGHEST", diff --git a/bfd/reloc.c b/bfd/reloc.c index 2eb0758a..674b075 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2833,6 +2833,8 @@ ENUMX ENUMX BFD_RELOC_PPC_REL16DX_HA ENUMX + BFD_RELOC_PPC_NEG +ENUMX BFD_RELOC_PPC64_HIGHER ENUMX BFD_RELOC_PPC64_HIGHER_S diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index f0e0fe7..1607cd5 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -2653,7 +2653,7 @@ xcoff_auto_export_p (struct bfd_link_info *info, static bool xcoff_need_ldrel_p (struct bfd_link_info *info, struct internal_reloc *rel, - struct xcoff_link_hash_entry *h) + struct xcoff_link_hash_entry *h, asection *ssec) { if (!xcoff_hash_table (info)->loader_section) return false; @@ -2701,6 +2701,14 @@ xcoff_need_ldrel_p (struct bfd_link_info *info, struct internal_reloc *rel, && bfd_is_abs_section (sec->output_section))) return false; } + + /* Absolute relocations from read-only sections are forbidden + by AIX loader. However, they can appear in their section's + relocations. */ + if (ssec != NULL + && (ssec->output_section->flags & SEC_READONLY) != 0) + return false; + return true; case R_TLS: @@ -2989,7 +2997,7 @@ xcoff_mark (struct bfd_link_info *info, asection *sec) /* See if this reloc needs to be copied into the .loader section. */ - if (xcoff_need_ldrel_p (info, rel, h)) + if (xcoff_need_ldrel_p (info, rel, h, sec)) { ++xcoff_hash_table (info)->ldrel_count; if (h != NULL) @@ -4982,7 +4990,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo, } if ((o->flags & SEC_DEBUGGING) == 0 - && xcoff_need_ldrel_p (flinfo->info, irel, h)) + && xcoff_need_ldrel_p (flinfo->info, irel, h, o)) { asection *sec; |