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.
This commit is contained in:
Clément Chigot 2021-03-11 11:08:19 +01:00 committed by Alan Modra
parent 2c1bef53de
commit 4a403be0c1
15 changed files with 376 additions and 31 deletions

View File

@ -1,3 +1,22 @@
2021-03-12 Clément Chigot <clement.chigot@atos.net>
* 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.
2021-03-12 Clément Chigot <clement.chigot@atos.net>
* coff-rs6000.c (xcoff_calculate_relocation): Correct and

View File

@ -2899,6 +2899,8 @@ instruction. */
BFD_RELOC_PPC_B26,
BFD_RELOC_PPC_BA26,
BFD_RELOC_PPC_TOC16,
BFD_RELOC_PPC_TOC16_LO,
BFD_RELOC_PPC_TOC16_HI,
BFD_RELOC_PPC_B16,
BFD_RELOC_PPC_B16_BRTAKEN,
BFD_RELOC_PPC_B16_BRNTAKEN,

View File

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

View File

@ -228,8 +228,8 @@ xcoff64_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) */
};
/* coffcode.h needs these to be defined. */
@ -899,7 +899,7 @@ reloc_howto_type xcoff64_howto_table[] =
0, /* special_function */
"R_TOC", /* name */
TRUE, /* partial_inplace */
0xffff, /* src_mask */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
@ -914,7 +914,7 @@ reloc_howto_type xcoff64_howto_table[] =
0, /* special_function */
"R_TRL", /* name */
TRUE, /* partial_inplace */
0xffff, /* src_mask */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
@ -929,7 +929,7 @@ reloc_howto_type xcoff64_howto_table[] =
0, /* special_function */
"R_GL", /* name */
TRUE, /* partial_inplace */
0xffff, /* src_mask */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
@ -944,7 +944,7 @@ reloc_howto_type xcoff64_howto_table[] =
0, /* special_function */
"R_TCL", /* name */
TRUE, /* partial_inplace */
0xffff, /* src_mask */
0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
@ -1260,11 +1260,34 @@ reloc_howto_type xcoff64_howto_table[] =
EMPTY_HOWTO(0x2e),
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 */
};
@ -1319,6 +1342,10 @@ xcoff64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
return &xcoff64_howto_table[8];
case BFD_RELOC_PPC_TOC16:
return &xcoff64_howto_table[3];
case BFD_RELOC_PPC_TOC16_HI:
return &xcoff64_howto_table[0x30];
case BFD_RELOC_PPC_TOC16_LO:
return &xcoff64_howto_table[0x31];
case BFD_RELOC_PPC_B16:
return &xcoff64_howto_table[0x1e];
case BFD_RELOC_32:

View File

@ -1462,6 +1462,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_PPC_B26",
"BFD_RELOC_PPC_BA26",
"BFD_RELOC_PPC_TOC16",
"BFD_RELOC_PPC_TOC16_LO",
"BFD_RELOC_PPC_TOC16_HI",
"BFD_RELOC_PPC_B16",
"BFD_RELOC_PPC_B16_BRTAKEN",
"BFD_RELOC_PPC_B16_BRNTAKEN",

View File

@ -2736,6 +2736,10 @@ ENUMX
BFD_RELOC_PPC_BA26
ENUMX
BFD_RELOC_PPC_TOC16
ENUMX
BFD_RELOC_PPC_TOC16_LO
ENUMX
BFD_RELOC_PPC_TOC16_HI
ENUMX
BFD_RELOC_PPC_B16
ENUMX

View File

@ -1,3 +1,21 @@
2021-03-12 Clément Chigot <clement.chigot@atos.net>
* 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.
2021-03-10 Jan Beulich <jbeulich@suse.com>
* testsuite/gas/i386/avx512f-intel.d,

View File

@ -2646,6 +2646,87 @@ ppc_elf_adjust_symtab (void)
}
}
#endif /* OBJ_ELF */
#ifdef OBJ_XCOFF
/* Parse XCOFF relocations. */
static bfd_reloc_code_real_type
ppc_xcoff_suffix (char **str_p)
{
struct map_bfd {
const char *string;
unsigned int length : 8;
unsigned int valid32 : 1;
unsigned int valid64 : 1;
unsigned int reloc;
};
char ident[20];
char *str = *str_p;
char *str2;
int ch;
int len;
const struct map_bfd *ptr;
#define MAP(str, reloc) { str, sizeof (str) - 1, 1, 1, reloc }
#define MAP32(str, reloc) { str, sizeof (str) - 1, 1, 0, reloc }
#define MAP64(str, reloc) { str, sizeof (str) - 1, 0, 1, reloc }
static const struct map_bfd mapping[] = {
MAP ("l", BFD_RELOC_PPC_TOC16_LO),
MAP ("u", BFD_RELOC_PPC_TOC16_HI),
};
if (*str++ != '@')
return BFD_RELOC_NONE;
for (ch = *str, str2 = ident;
(str2 < ident + sizeof (ident) - 1
&& (ISALNUM (ch) || ch == '@'));
ch = *++str)
{
*str2++ = TOLOWER (ch);
}
*str2 = '\0';
len = str2 - ident;
ch = ident[0];
for (ptr = &mapping[0]; ptr->length > 0; ptr++)
if (ch == ptr->string[0]
&& len == ptr->length
&& memcmp (ident, ptr->string, ptr->length) == 0
&& (ppc_obj64 ? ptr->valid64 : ptr->valid32))
{
*str_p = str;
return (bfd_reloc_code_real_type) ptr->reloc;
}
return BFD_RELOC_NONE;
}
/* Restore XCOFF addis instruction to ELF format.
AIX often generates addis instructions using "addis RT,D(RA)"
format instead of the ELF "addis RT,RA,SI" one.
On entry RT_E is at the comma after RT, D_E is at the open
parenthesis after D, and RA_E is at the close parenthesis after RA. */
static void
ppc_xcoff_fixup_addis (char *rt_e, char *d_e, char *ra_e)
{
size_t ra_size = ra_e - d_e - 1;
char *save_ra = xmalloc (ra_size);
/* Copy RA. */
memcpy (save_ra, d_e + 1, ra_size);
/* Shuffle D to make room for RA, copying the comma too. */
memmove (rt_e + ra_size + 1, rt_e, d_e - rt_e);
/* Erase the trailing ')', keeping any rubbish for potential errors. */
memmove (ra_e, ra_e + 1, strlen (ra_e));
/* Write RA back. */
memcpy (rt_e + 1, save_ra, ra_size);
free (save_ra);
}
#endif /* OBJ_XCOFF */
#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
/* See whether a symbol is in the TOC section. */
@ -2655,6 +2736,7 @@ ppc_is_toc_sym (symbolS *sym)
{
#ifdef OBJ_XCOFF
return (symbol_get_tc (sym)->symbol_class == XMC_TC
|| symbol_get_tc (sym)->symbol_class == XMC_TE
|| symbol_get_tc (sym)->symbol_class == XMC_TC0);
#endif
#ifdef OBJ_ELF
@ -2920,6 +3002,8 @@ fixup_size (bfd_reloc_code_real_type reloc, bfd_boolean *pc_relative)
case BFD_RELOC_PPC_GOT_TPREL16_HI:
case BFD_RELOC_PPC_GOT_TPREL16_LO:
case BFD_RELOC_PPC_TOC16:
case BFD_RELOC_PPC_TOC16_HI:
case BFD_RELOC_PPC_TOC16_LO:
case BFD_RELOC_PPC_TPREL16:
case BFD_RELOC_PPC_TPREL16_HA:
case BFD_RELOC_PPC_TPREL16_HI:
@ -3162,6 +3246,28 @@ md_assemble (char *str)
while (ISSPACE (*str))
++str;
#ifdef OBJ_XCOFF
/* AIX often generates addis instructions using "addis RT, D(RA)"
format instead of the classic "addis RT, RA, SI" one.
Restore it to the default format as it's the one encoded
in ppc opcodes. */
if (!strcmp (opcode->name, "addis"))
{
char *rt_e = strchr (str, ',');
if (rt_e != NULL
&& strchr (rt_e + 1, ',') == NULL)
{
char *d_e = strchr (rt_e + 1, '(');
if (d_e != NULL && d_e != rt_e + 1)
{
char *ra_e = strrchr (d_e + 1, ')');
if (ra_e != NULL && ra_e != d_e + 1)
ppc_xcoff_fixup_addis (rt_e, d_e, ra_e);
}
}
}
#endif
/* PowerPC operands are just expressions. The only real issue is
that a few operand types are optional. If an instruction has
multiple optional operands and one is omitted, then all optional
@ -3558,6 +3664,9 @@ md_assemble (char *str)
}
}
#endif /* OBJ_ELF */
#ifdef OBJ_XCOFF
reloc = ppc_xcoff_suffix (&str);
#endif /* OBJ_XCOFF */
if (reloc != BFD_RELOC_NONE)
;
@ -4336,6 +4445,7 @@ ppc_change_csect (symbolS *sym, offsetT align)
case XMC_RW:
case XMC_TC0:
case XMC_TC:
case XMC_TE:
case XMC_DS:
case XMC_UA:
case XMC_BS:
@ -5383,7 +5493,21 @@ ppc_tc (int ignore ATTRIBUTE_UNUSED)
S_SET_SEGMENT (sym, now_seg);
symbol_set_frag (sym, frag_now);
S_SET_VALUE (sym, (valueT) frag_now_fix ());
symbol_get_tc (sym)->symbol_class = XMC_TC;
/* AIX assembler seems to allow any storage class to be set in .tc.
But for now, only XMC_TC and XMC_TE are supported by us. */
switch (symbol_get_tc (sym)->symbol_class)
{
case XMC_TC:
case XMC_TE:
break;
default:
as_bad (_(".tc with storage class %d not yet supported"),
symbol_get_tc (sym)->symbol_class);
ignore_rest_of_line ();
return;
}
symbol_get_tc (sym)->output = 1;
ppc_frob_label (sym);
@ -5585,6 +5709,8 @@ ppc_symbol_new_hook (symbolS *sym)
tc->symbol_class = XMC_TB;
else if (strcmp (s, "TC0]") == 0 || strcmp (s, "T0]") == 0)
tc->symbol_class = XMC_TC0;
else if (strcmp (s, "TE]") == 0)
tc->symbol_class = XMC_TE;
break;
case 'U':
if (strcmp (s, "UA]") == 0)
@ -5757,7 +5883,7 @@ ppc_frob_symbol (symbolS *sym)
a->x_csect.x_scnlen.l = 0;
a->x_csect.x_smtyp = XTY_ER;
}
else if (symbol_get_tc (sym)->symbol_class == XMC_TC)
else if (ppc_is_toc_sym (sym))
{
symbolS *next;
@ -5767,7 +5893,7 @@ ppc_frob_symbol (symbolS *sym)
while (symbol_get_tc (next)->symbol_class == XMC_TC0)
next = symbol_next (next);
if (next == (symbolS *) NULL
|| symbol_get_tc (next)->symbol_class != XMC_TC)
|| (!ppc_is_toc_sym (next)))
{
if (ppc_after_toc_frag == (fragS *) NULL)
a->x_csect.x_scnlen.l = (bfd_section_size (data_section)
@ -6053,7 +6179,8 @@ ppc_fix_adjustable (fixS *fix)
if (sy_tc->symbol_class == XMC_TC0)
continue;
if (sy_tc->symbol_class != XMC_TC)
if (sy_tc->symbol_class != XMC_TC
&& sy_tc->symbol_class != XMC_TE)
break;
if (val == resolve_symbol_value (sy))
{
@ -6072,6 +6199,7 @@ ppc_fix_adjustable (fixS *fix)
if (tc->subseg == 0
&& tc->symbol_class != XMC_TC0
&& tc->symbol_class != XMC_TC
&& tc->symbol_class != XMC_TE
&& symseg != bss_section
/* Don't adjust if this is a reloc in the toc section. */
&& (symseg != data_section
@ -6516,8 +6644,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
&& (operand->insert == NULL || ppc_obj64)
&& fixP->fx_addsy != NULL
&& symbol_get_tc (fixP->fx_addsy)->subseg != 0
&& symbol_get_tc (fixP->fx_addsy)->symbol_class != XMC_TC
&& symbol_get_tc (fixP->fx_addsy)->symbol_class != XMC_TC0
&& !ppc_is_toc_sym (fixP->fx_addsy)
&& S_GET_SEGMENT (fixP->fx_addsy) != bss_section)
{
value = fixP->fx_offset;
@ -6984,6 +7111,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
case BFD_RELOC_PPC_EMB_RELSDA:
case BFD_RELOC_PPC64_TOC:
case BFD_RELOC_PPC_TOC16:
case BFD_RELOC_PPC_TOC16_LO:
case BFD_RELOC_PPC_TOC16_HI:
case BFD_RELOC_PPC64_TOC16_LO:
case BFD_RELOC_PPC64_TOC16_HI:
case BFD_RELOC_PPC64_TOC16_HA:
@ -7061,7 +7190,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
symbol_get_bfdsym (fixP->fx_addsy)->flags |= BSF_KEEP;
}
#else
if (fixP->fx_r_type != BFD_RELOC_PPC_TOC16)
if (fixP->fx_r_type != BFD_RELOC_PPC_TOC16
&& fixP->fx_r_type != BFD_RELOC_PPC_TOC16_HI
&& fixP->fx_r_type != BFD_RELOC_PPC_TOC16_LO)
fixP->fx_addnumber = 0;
else
{
@ -7069,6 +7200,12 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
of the symbol. */
fixP->fx_addnumber = (- bfd_section_vma (S_GET_SEGMENT (fixP->fx_addsy))
- S_GET_VALUE (ppc_toc_csect));
/* The high bits must be adjusted for the low bits being signed. */
if (fixP->fx_r_type == BFD_RELOC_PPC_TOC16_HI) {
fixP->fx_addnumber += 0x8000;
}
/* Set *valP to avoid errors. */
*valP = value;
}

View File

@ -1,3 +1,13 @@
2021-03-12 Clément Chigot <clement.chigot@atos.net>
* 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.
2021-03-12 Alan Modra <amodra@gmail.com>
* testsuite/ld-gc/gc.exp: Pass "-image-base 0" to ld for PE, and

View File

@ -52,6 +52,7 @@ SECTIONS
*(.tc0)
*(.tc)
*(.td)
*(.te)
${RELOCATING+PROVIDE (_edata = .);}
}
.bss : {

View File

@ -0,0 +1,20 @@
#source: aix-largetoc-1.s
#as: -a32
#ld: -b32 -shared -bE:aix-largetoc-1.ex
#objdump: -dr
#target: [is_xcoff_format]
.*
Disassembly of section \.text:
.* <\.foo>:
.*: 3d 22 00 00 cau r9,r2,0
.*: R_TOCU a-.*
.*: 39 29 00 00 cal r9,0\(r9\)
.*: R_TOCL a-.*
.*: 3d 22 00 00 cau r9,r2,0
.*: R_TOCU b-.*
.*: 39 29 00 04 cal r9,4\(r9\)
.*: R_TOCL b-.*
#...

View File

@ -0,0 +1,20 @@
#source: aix-largetoc-1.s
#as: -a64
#ld: -b64 -shared -bE:aix-largetoc-1.ex
#objdump: -dr
#target: [is_xcoff_format]
.*
Disassembly of section \.text:
.* <\.foo>:
.*: 3d 22 00 00 addis r9,r2,0
.*: R_TOCU a-.*
.*: 39 29 00 00 addi r9,r9,0
.*: R_TOCL a-.*
.*: 3d 22 00 00 addis r9,r2,0
.*: R_TOCU b-.*
.*: 39 29 00 08 addi r9,r9,8
.*: R_TOCL b-.*
#...

View File

@ -0,0 +1 @@
foo

View File

@ -0,0 +1,25 @@
.globl a
.csect .data[RW]
a:
.long 1
.toc
.tc a[TE],a
.tc b[TE],a
.globl foo
.globl .foo
.csect foo[DS],3
foo:
.if size == 32
.long .foo, TOC[tc0], 0
.else
.llong .foo, TOC[tc0], 0
.endif
.csect .text[PR]
.foo:
addis 9,a[TE]@u(2)
la 9,a[TE]@l(9)
addis 9,b[TE]@u(2)
la 9,b[TE]@l(9)

View File

@ -266,3 +266,20 @@ run_dump_test "aix-glink-3-32"
run_dump_test "aix-glink-3-64"
run_dump_test "aix-weak-3-32"
run_dump_test "aix-weak-3-64"
# Tests added for features in AIX 7+.
set aix7tests {
{"Large TOC test 1" "-shared -bE:aix-largetoc-1.ex"
"" {aix-largetoc-1.s}
{{objdump -dr aix-largetoc-1-SIZE.d}}
"aix-largetoc-1.so"}
}
foreach test $aix7tests {
foreach { name ldopts asopts sources tools output } $test {
run_aix_test 32 $name $ldopts $asopts $sources $tools $output
run_aix_test 64 $name $ldopts $asopts $sources $tools $output
}
}