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.
This commit is contained in:
Cl?ment Chigot
2021-04-20 14:40:43 +01:00
committed by Nick Clifton
parent d549b029d6
commit c5df7e442e
16 changed files with 255 additions and 33 deletions

View File

@@ -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: