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.
+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
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,
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
0, /* special_function */
"R_TOC", /* name */
TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
+ 0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
0, /* special_function */
"R_TRL", /* name */
TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
+ 0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
0, /* special_function */
"R_GL", /* name */
TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
+ 0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
0, /* special_function */
"R_TCL", /* name */
TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
+ 0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
0, /* special_function */
"R_TRLA", /* name */
TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
+ 0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
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 */
};
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:
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,
+ 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;
}
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
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
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. */
0, /* special_function */
"R_TOC", /* name */
TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
+ 0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
0, /* special_function */
"R_TRL", /* name */
TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
+ 0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
0, /* special_function */
"R_GL", /* name */
TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
+ 0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
0, /* special_function */
"R_TCL", /* name */
TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
+ 0, /* src_mask */
0xffff, /* dst_mask */
FALSE), /* pcrel_offset */
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 */
};
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:
"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",
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
+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,
}
}
#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 */
\f
#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
/* See whether a symbol is in the TOC section. */
{
#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
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:
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
}
}
#endif /* OBJ_ELF */
+#ifdef OBJ_XCOFF
+ reloc = ppc_xcoff_suffix (&str);
+#endif /* OBJ_XCOFF */
if (reloc != BFD_RELOC_NONE)
;
case XMC_RW:
case XMC_TC0:
case XMC_TC:
+ case XMC_TE:
case XMC_DS:
case XMC_UA:
case XMC_BS:
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);
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)
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;
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)
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))
{
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
&& (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;
if (fixP->fx_r_type == BFD_RELOC_16
&& fixP->fx_addsy != NULL
&& ppc_is_toc_sym (fixP->fx_addsy))
- fixP->fx_r_type = BFD_RELOC_PPC_TOC16;
+ fixP->fx_r_type = BFD_RELOC_PPC_TOC16;
#endif
}
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:
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
{
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;
}
+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
*(.tc0)
*(.tc)
*(.td)
+ *(.te)
${RELOCATING+PROVIDE (_edata = .);}
}
.bss : {
--- /dev/null
+#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-.*
+#...
--- /dev/null
+#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-.*
+#...
--- /dev/null
+ .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)
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
+ }
+}