aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog34
-rw-r--r--bfd/coff-rs6000.c8
-rw-r--r--bfd/coff64-rs6000.c8
-rw-r--r--bfd/coffcode.h7
-rw-r--r--bfd/coffgen.c1
-rw-r--r--bfd/xcofflink.c207
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/config/tc-ppc.c1
-rw-r--r--include/coff/ChangeLog10
-rw-r--r--include/coff/internal.h15
-rw-r--r--include/coff/xcoff.h6
-rw-r--r--ld/testsuite/ChangeLog22
-rw-r--r--ld/testsuite/ld-powerpc/aix-glink-2-32.dd69
-rw-r--r--ld/testsuite/ld-powerpc/aix-glink-2-64.dd73
-rw-r--r--ld/testsuite/ld-powerpc/aix-glink-2a.ex9
-rw-r--r--ld/testsuite/ld-powerpc/aix-glink-2a.s41
-rw-r--r--ld/testsuite/ld-powerpc/aix-glink-2b.s12
-rw-r--r--ld/testsuite/ld-powerpc/aix-glink-2c.ex6
-rw-r--r--ld/testsuite/ld-powerpc/aix-glink-2c.s33
-rw-r--r--ld/testsuite/ld-powerpc/aix-glink-2d.s12
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-1-dso.dnd17
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-1-dso.hd12
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-1-dso.nd25
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-1-rel.hd12
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-1-rel.nd25
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-1.ex8
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-1a.s24
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-1b.s24
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-2a.ex8
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-2a.nd8
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-2a.s21
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-2b.nd8
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-2b.s21
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-2c.ex1
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-2c.nd10
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-2c.od13
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-2c.s11
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-3-32.d5
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-3-32.dd24
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-3-64.d5
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-3-64.dd26
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-3a.ex3
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-3a.s8
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-3b.ex1
-rw-r--r--ld/testsuite/ld-powerpc/aix-weak-3b.s30
-rw-r--r--ld/testsuite/ld-powerpc/aix52.exp61
46 files changed, 892 insertions, 98 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a734dfe..25c2fde 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,39 @@
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+ * coffcode.h (coff_pointerize_aux_hook): Update CSECT_SYM_P to
+ check whether a symbol has csect information.
+ (coff_print_aux): Likewise.
+ * coff-rs6000.c (_bfd_xcoff_swap_aux_in): Handle auxillary csect
+ information for C_AIX_WEAKEXT too.
+ (_bfd_xcoff_swap_aux_out): Likewise.
+ (xcoff_reloc_type_br): Handle defweak symbols too.
+ * coff64-rs6000.c (_bfd_xcoff64_swap_aux_in): Handle auxillary csect
+ information for C_AIX_WEAKEXT too.
+ (_bfd_xcoff64_swap_aux_out): Likewise.
+ (xcoff64_reloc_type_br): Handle defweak symbols too.
+ * coffgen.c (coff_print_symbol): Handle auxillary function
+ information for C_AIX_WEAKEXT too.
+ * xcofflink.c (_bfd_xcoff_canonicalize_dynamic_symtab): Set BSF_WEAK
+ instead of BSF_GLOBAL if the L_WEAK flag is set.
+ (xcoff_dynamic_definition_p): New function.
+ (xcoff_link_add_dynamic_symbols): Use it to decide whether ldsym
+ defines h. Don't change h if ldsym isn't the definition. Otherwise,
+ always take the symbol class from the ldsym. Use weak bfd symbol
+ types for weak ldsyms.
+ (xcoff_link_add_symbols): Use CSECT_SYM_P and EXTERN_SYM_P.
+ Fix the check for whether a definition is from a shared object.
+ Allow redefinitions of weak symbols.
+ (xcoff_link_check_ar_symbols): Use EXTERN_SYM_P.
+ (xcoff_keep_symbol_p): Likewise.
+ (bfd_xcoff_size_dynamic_sections): Use CSECT_SYM_P.
+ (xcoff_link_input_bfd): Use CSECT_SYM_P and EXTERN_SYM_P.
+ Add .loader entries for C_AIX_WEAKEXT as well as C_EXT symbols,
+ but mark them as L_WEAK.
+ (xcoff_write_global_symbol): Treat weak symbols as C_AIX_WEAKEXT
+ instead of C_EXT if C_AIX_WEAKEXT == C_WEAKEXT.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
* xcofflink.c (xcoff_mark): When walking the relocations,
only mark the target symbol or the target section, not both.
(xcoff_final_definition_p): New function.
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 7002485..3343530 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -422,6 +422,7 @@ _bfd_xcoff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
/* RS/6000 "csect" auxents */
case C_EXT:
+ case C_AIX_WEAKEXT:
case C_HIDEXT:
if (indx + 1 == numaux)
{
@@ -531,6 +532,7 @@ _bfd_xcoff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
/* RS/6000 "csect" auxents */
case C_EXT:
+ case C_AIX_WEAKEXT:
case C_HIDEXT:
if (indx + 1 == numaux)
{
@@ -2963,7 +2965,8 @@ xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
going to global linkage code, we can replace the load with a
cror. */
if (NULL != h
- && bfd_link_hash_defined == h->root.type
+ && (bfd_link_hash_defined == h->root.type
+ || bfd_link_hash_defweak == h->root.type)
&& section_offset + 8 <= input_section->size)
{
bfd_byte *pnext;
@@ -3008,7 +3011,8 @@ xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
howto->dst_mask = howto->src_mask;
if (h != NULL
- && h->root.type == bfd_link_hash_defined
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
&& bfd_is_abs_section (h->root.u.def.section)
&& section_offset + 4 <= input_section->size)
{
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index 6be1583..1a0ff59 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -381,6 +381,7 @@ _bfd_xcoff64_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
/* RS/6000 "csect" auxents */
case C_EXT:
+ case C_AIX_WEAKEXT:
case C_HIDEXT:
if (indx + 1 == numaux)
{
@@ -473,6 +474,7 @@ _bfd_xcoff64_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
/* RS/6000 "csect" auxents */
case C_EXT:
+ case C_AIX_WEAKEXT:
case C_HIDEXT:
if (indx + 1 == numaux)
{
@@ -1133,7 +1135,8 @@ xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
going to global linkage code, we can replace the load with a
cror. */
if (NULL != h
- && bfd_link_hash_defined == h->root.type
+ && (bfd_link_hash_defined == h->root.type
+ || bfd_link_hash_defweak == h->root.type)
&& section_offset + 8 <= input_section->size)
{
bfd_byte *pnext;
@@ -1176,7 +1179,8 @@ xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
howto->dst_mask = howto->src_mask;
if (h != NULL
- && h->root.type == bfd_link_hash_defined
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
&& bfd_is_abs_section (h->root.u.def.section)
&& section_offset + 4 <= input_section->size)
{
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 59bb223..44ac080 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -2416,7 +2416,7 @@ symname_in_debug_hook (bfd * abfd ATTRIBUTE_UNUSED, struct internal_syment *sym)
#define FORCE_SYMNAMES_IN_STRINGS
#endif
-/* Handle the csect auxent of a C_EXT or C_HIDEXT symbol. */
+/* Handle the csect auxent of a C_EXT, C_AIX_WEAKEXT or C_HIDEXT symbol. */
static bfd_boolean
coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED,
@@ -2427,7 +2427,7 @@ coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED,
{
int class = symbol->u.syment.n_sclass;
- if ((class == C_EXT || class == C_HIDEXT)
+ if (CSECT_SYM_P (class)
&& indaux + 1 == symbol->u.syment.n_numaux)
{
if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD)
@@ -2485,8 +2485,7 @@ coff_print_aux (bfd *abfd ATTRIBUTE_UNUSED,
unsigned int indaux ATTRIBUTE_UNUSED)
{
#ifdef RS6000COFF_C
- if ((symbol->u.syment.n_sclass == C_EXT
- || symbol->u.syment.n_sclass == C_HIDEXT)
+ if (CSECT_SYM_P (symbol->u.syment.n_sclass)
&& indaux + 1 == symbol->u.syment.n_numaux)
{
/* This is a csect entry. */
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 0a1c97c..0faaede 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -2006,6 +2006,7 @@ coff_print_symbol (bfd *abfd,
}
/* Otherwise fall through. */
case C_EXT:
+ case C_AIX_WEAKEXT:
if (ISFCN (combined->u.syment.n_type))
{
long next, llnos;
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index cbc750c..d87940c 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -258,7 +258,12 @@ _bfd_xcoff_canonicalize_dynamic_symtab (bfd *abfd, asymbol **psyms)
symbuf->symbol.flags = BSF_NO_FLAGS;
if ((ldsym.l_smtype & L_EXPORT) != 0)
- symbuf->symbol.flags |= BSF_GLOBAL;
+ {
+ if ((ldsym.l_smtype & L_WEAK) != 0)
+ symbuf->symbol.flags |= BSF_WEAK;
+ else
+ symbuf->symbol.flags |= BSF_GLOBAL;
+ }
/* FIXME: We have no way to record the other information stored
with the loader symbol. */
@@ -540,6 +545,36 @@ xcoff_read_internal_relocs (bfd *abfd,
require_internal, internal_relocs);
}
+/* H is the bfd symbol associated with exported .loader symbol LDSYM.
+ Return true if LDSYM defines H. */
+
+static bfd_boolean
+xcoff_dynamic_definition_p (struct xcoff_link_hash_entry *h,
+ struct internal_ldsym *ldsym)
+{
+ /* If we didn't know about H before processing LDSYM, LDSYM
+ definitely defines H. */
+ if (h->root.type == bfd_link_hash_new)
+ return TRUE;
+
+ /* If H is currently a weak dynamic symbol, and if LDSYM is a strong
+ dynamic symbol, LDSYM trumps the current definition of H. */
+ if ((ldsym->l_smtype & L_WEAK) == 0
+ && (h->flags & XCOFF_DEF_DYNAMIC) != 0
+ && (h->flags & XCOFF_DEF_REGULAR) == 0
+ && (h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_undefweak))
+ return TRUE;
+
+ /* If H is currently undefined, LDSYM defines it. */
+ if ((h->flags & XCOFF_DEF_DYNAMIC) == 0
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak))
+ return TRUE;
+
+ return FALSE;
+}
+
/* This function is used to add symbols from a dynamic object to the
global symbol table. */
@@ -638,43 +673,33 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
if (h == NULL)
return FALSE;
- h->flags |= XCOFF_DEF_DYNAMIC;
-
- /* If the symbol is undefined, and the BFD it was found in is
- not a dynamic object, change the BFD to this dynamic object,
- so that we can get the correct import file ID. */
- if ((h->root.type == bfd_link_hash_undefined
- || h->root.type == bfd_link_hash_undefweak)
- && (h->root.u.undef.abfd == NULL
- || (h->root.u.undef.abfd->flags & DYNAMIC) == 0))
- h->root.u.undef.abfd = abfd;
-
- if (h->root.type == bfd_link_hash_new)
- {
- h->root.type = bfd_link_hash_undefined;
- h->root.u.undef.abfd = abfd;
- /* We do not want to add this to the undefined symbol list. */
- }
-
- if (h->smclas == XMC_UA
- || h->root.type == bfd_link_hash_undefined
- || h->root.type == bfd_link_hash_undefweak)
- h->smclas = ldsym.l_smclas;
-
- /* Unless this is an XMC_XO symbol, we don't bother to actually
- define it, since we don't have a section to put it in anyhow.
- Instead, the relocation routines handle the DEF_DYNAMIC flag
- correctly. */
+ if (!xcoff_dynamic_definition_p (h, &ldsym))
+ continue;
- if (h->smclas == XMC_XO
- && (h->root.type == bfd_link_hash_undefined
- || h->root.type == bfd_link_hash_undefweak))
+ h->flags |= XCOFF_DEF_DYNAMIC;
+ h->smclas = ldsym.l_smclas;
+ if (h->smclas == XMC_XO)
{
/* This symbol has an absolute value. */
- h->root.type = bfd_link_hash_defined;
+ if ((ldsym.l_smtype & L_WEAK) != 0)
+ h->root.type = bfd_link_hash_defweak;
+ else
+ h->root.type = bfd_link_hash_defined;
h->root.u.def.section = bfd_abs_section_ptr;
h->root.u.def.value = ldsym.l_value;
}
+ else
+ {
+ /* Otherwise, we don't bother to actually define the symbol,
+ since we don't have a section to put it in anyhow.
+ We assume instead that an undefined XCOFF_DEF_DYNAMIC symbol
+ should be imported from the symbol's undef.abfd. */
+ if ((ldsym.l_smtype & L_WEAK) != 0)
+ h->root.type = bfd_link_hash_undefweak;
+ else
+ h->root.type = bfd_link_hash_undefined;
+ h->root.u.undef.abfd = abfd;
+ }
/* If this symbol defines a function descriptor, then it
implicitly defines the function code as well. */
@@ -701,33 +726,30 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
if (hds == NULL)
return FALSE;
- if (hds->root.type == bfd_link_hash_new)
- {
- hds->root.type = bfd_link_hash_undefined;
- hds->root.u.undef.abfd = abfd;
- /* We do not want to add this to the undefined
- symbol list. */
- }
-
hds->descriptor = h;
h->descriptor = hds;
}
- hds->flags |= XCOFF_DEF_DYNAMIC;
- if (hds->smclas == XMC_UA)
- hds->smclas = XMC_PR;
-
- /* An absolute symbol appears to actually define code, not a
- function descriptor. This is how some math functions are
- implemented on AIX 4.1. */
- if (h->smclas == XMC_XO
- && (hds->root.type == bfd_link_hash_undefined
- || hds->root.type == bfd_link_hash_undefweak))
+ if (xcoff_dynamic_definition_p (hds, &ldsym))
{
- hds->smclas = XMC_XO;
- hds->root.type = bfd_link_hash_defined;
- hds->root.u.def.section = bfd_abs_section_ptr;
- hds->root.u.def.value = ldsym.l_value;
+ hds->root.type = h->root.type;
+ hds->flags |= XCOFF_DEF_DYNAMIC;
+ if (h->smclas == XMC_XO)
+ {
+ /* An absolute symbol appears to actually define code, not a
+ function descriptor. This is how some math functions are
+ implemented on AIX 4.1. */
+ hds->smclas = XMC_XO;
+ hds->root.u.def.section = bfd_abs_section_ptr;
+ hds->root.u.def.value = ldsym.l_value;
+ }
+ else
+ {
+ hds->smclas = XMC_PR;
+ hds->root.u.undef.abfd = abfd;
+ /* We do not want to add this to the undefined
+ symbol list. */
+ }
}
}
}
@@ -1087,7 +1109,6 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
const char *name;
char buf[SYMNMLEN + 1];
int smtyp;
- flagword flags;
asection *section;
bfd_vma value;
struct xcoff_link_hash_entry *set_toc;
@@ -1096,7 +1117,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
/* In this pass we are only interested in symbols with csect
information. */
- if (sym.n_sclass != C_EXT && sym.n_sclass != C_HIDEXT)
+ if (!CSECT_SYM_P (sym.n_sclass))
{
/* Set csect_cache,
Normally csect is a .pr, .rw etc. created in the loop
@@ -1216,7 +1237,6 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp);
- flags = BSF_GLOBAL;
section = NULL;
value = 0;
set_toc = NULL;
@@ -1327,7 +1347,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
erelsym = ((bfd_byte *) obj_coff_external_syms (abfd)
+ rel->r_symndx * symesz);
bfd_coff_swap_sym_in (abfd, (void *) erelsym, (void *) &relsym);
- if (relsym.n_sclass == C_EXT)
+ if (EXTERN_SYM_P (relsym.n_sclass))
{
const char *relname;
char relbuf[SYMNMLEN + 1];
@@ -1482,9 +1502,9 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
if (first_csect == NULL)
first_csect = csect;
- /* If this symbol is C_EXT, we treat it as starting at the
+ /* If this symbol is external, we treat it as starting at the
beginning of the newly created section. */
- if (sym.n_sclass == C_EXT)
+ if (EXTERN_SYM_P (sym.n_sclass))
{
section = csect;
value = 0;
@@ -1573,7 +1593,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
if (first_csect == NULL)
first_csect = csect;
- if (sym.n_sclass == C_EXT)
+ if (EXTERN_SYM_P (sym.n_sclass))
{
csect->flags |= SEC_IS_COMMON;
csect->size = 0;
@@ -1614,9 +1634,10 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
/* Now we have enough information to add the symbol to the
linker hash table. */
- if (sym.n_sclass == C_EXT)
+ if (EXTERN_SYM_P (sym.n_sclass))
{
bfd_boolean copy;
+ flagword flags;
BFD_ASSERT (section != NULL);
@@ -1687,8 +1708,8 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
section = bfd_und_section_ptr;
value = 0;
}
- else if (((*sym_hash)->root.u.def.section->owner->flags
- & DYNAMIC) != 0)
+ else if (((*sym_hash)->flags & XCOFF_DEF_REGULAR) == 0
+ && ((*sym_hash)->flags & XCOFF_DEF_DYNAMIC) != 0)
{
/* The existing symbol is from a shared library.
Replace it. */
@@ -1704,6 +1725,12 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
section = bfd_und_section_ptr;
value = 0;
}
+ else if (sym.n_sclass == C_AIX_WEAKEXT
+ || (*sym_hash)->root.type == bfd_link_hash_defweak)
+ {
+ /* At least one of the definitions is weak.
+ Allow the normal rules to take effect. */
+ }
else if ((*sym_hash)->root.u.undef.next != NULL
|| info->hash->undefs_tail == &(*sym_hash)->root)
{
@@ -1723,8 +1750,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
}
}
else if (((*sym_hash)->flags & XCOFF_MULTIPLY_DEFINED) != 0
- && ((*sym_hash)->root.type == bfd_link_hash_defined
- || (*sym_hash)->root.type == bfd_link_hash_defweak)
+ && (*sym_hash)->root.type == bfd_link_hash_defined
&& (bfd_is_und_section (section)
|| bfd_is_com_section (section)))
{
@@ -1759,6 +1785,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
a second time from the csects. */
BFD_ASSERT (last_real->next == first_csect);
last_real->next = NULL;
+ flags = (sym.n_sclass == C_EXT ? BSF_GLOBAL : BSF_WEAK);
if (! (_bfd_generic_link_add_one_symbol
(info, abfd, name, flags, section, value,
NULL, copy, TRUE,
@@ -2073,7 +2100,7 @@ xcoff_link_check_ar_symbols (bfd *abfd,
bfd_coff_swap_sym_in (abfd, (void *) esym, (void *) &sym);
- if (sym.n_sclass == C_EXT && sym.n_scnum != N_UNDEF)
+ if (EXTERN_SYM_P (sym.n_sclass) && sym.n_scnum != N_UNDEF)
{
const char *name;
char buf[SYMNMLEN + 1];
@@ -3070,7 +3097,7 @@ xcoff_keep_symbol_p (struct bfd_link_info *info, bfd *input_bfd,
return 0;
/* Discard symbols that are defined elsewhere. */
- if (isym->n_sclass == C_EXT)
+ if (EXTERN_SYM_P (isym->n_sclass))
{
if ((h->flags & XCOFF_ALLOCATED) != 0)
return 0;
@@ -3081,7 +3108,7 @@ xcoff_keep_symbol_p (struct bfd_link_info *info, bfd *input_bfd,
/* If we're discarding local symbols, check whether ISYM is local. */
smtyp = SMTYP_SMTYP (aux->x_csect.x_smtyp);
if (info->discard == discard_all
- && isym->n_sclass != C_EXT
+ && !EXTERN_SYM_P (isym->n_sclass)
&& (isym->n_sclass != C_HIDEXT || smtyp != XTY_SD))
return 0;
@@ -3109,7 +3136,7 @@ xcoff_keep_symbol_p (struct bfd_link_info *info, bfd *input_bfd,
return 0;
if (info->discard == discard_l
- && isym->n_sclass != C_EXT
+ && !EXTERN_SYM_P (isym->n_sclass)
&& (isym->n_sclass != C_HIDEXT || smtyp != XTY_SD)
&& bfd_is_local_label_name (input_bfd, name))
return 0;
@@ -3495,9 +3522,8 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd,
bfd_coff_swap_sym_in (sub, esym, &sym);
- /* If this is a C_EXT or C_HIDEXT symbol, we need the csect
- information too. */
- if (sym.n_sclass == C_EXT || sym.n_sclass == C_HIDEXT)
+ /* Read in the csect information, if any. */
+ if (CSECT_SYM_P (sym.n_sclass))
{
BFD_ASSERT (sym.n_numaux > 0);
bfd_coff_swap_aux_in (sub, esym + symesz * sym.n_numaux,
@@ -3698,9 +3724,8 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
bfd_coff_swap_sym_in (input_bfd, (void *) esym, (void *) isymp);
- /* If this is a C_EXT or C_HIDEXT symbol, we need the csect
- information. */
- if (isymp->n_sclass == C_EXT || isymp->n_sclass == C_HIDEXT)
+ /* Read in the csect information, if any. */
+ if (CSECT_SYM_P (isymp->n_sclass))
{
BFD_ASSERT (isymp->n_numaux > 0);
bfd_coff_swap_aux_in (input_bfd,
@@ -3716,7 +3741,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
.loader symbol information. If this is an external symbol
reference to a defined symbol, though, then wait until we get
to the definition. */
- if (isymp->n_sclass == C_EXT
+ if (EXTERN_SYM_P (isymp->n_sclass)
&& *sym_hash != NULL
&& (*sym_hash)->ldsym != NULL
&& xcoff_final_definition_p (input_bfd, *sym_hash, *csectpp))
@@ -3751,6 +3776,8 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
ldsym->l_smtype |= L_EXPORT;
if ((h->flags & XCOFF_ENTRY) != 0)
ldsym->l_smtype |= L_ENTRY;
+ if (isymp->n_sclass == C_AIX_WEAKEXT)
+ ldsym->l_smtype |= L_WEAK;
ldsym->l_smclas = aux.x_csect.x_smclas;
@@ -3812,7 +3839,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
/* Assign the next unused index to this symbol. */
*indexp = output_index;
- if (isymp->n_sclass == C_EXT)
+ if (EXTERN_SYM_P (isymp->n_sclass))
{
BFD_ASSERT (*sym_hash != NULL);
(*sym_hash)->indx = output_index;
@@ -4018,8 +4045,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
aux.x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
}
}
- else if ((isymp->n_sclass == C_EXT
- || isymp->n_sclass == C_HIDEXT)
+ else if (CSECT_SYM_P (isymp->n_sclass)
&& i + 1 == isymp->n_numaux)
{
@@ -4098,8 +4124,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
/* Copy over the line numbers, unless we are stripping
them. We do this on a symbol by symbol basis in
order to more easily handle garbage collection. */
- if ((isymp->n_sclass == C_EXT
- || isymp->n_sclass == C_HIDEXT)
+ if (CSECT_SYM_P (isymp->n_sclass)
&& i == 0
&& isymp->n_numaux > 1
&& ISFCN (isymp->n_type)
@@ -5194,7 +5219,11 @@ xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf)
{
isym.n_value = 0;
isym.n_scnum = N_UNDEF;
- isym.n_sclass = C_EXT;
+ if (h->root.type == bfd_link_hash_undefweak
+ && C_WEAKEXT == C_AIX_WEAKEXT)
+ isym.n_sclass = C_WEAKEXT;
+ else
+ isym.n_sclass = C_EXT;
aux.x_csect.x_smtyp = XTY_ER;
}
else if ((h->root.type == bfd_link_hash_defined
@@ -5204,7 +5233,11 @@ xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf)
BFD_ASSERT (bfd_is_abs_section (h->root.u.def.section));
isym.n_value = h->root.u.def.value;
isym.n_scnum = N_UNDEF;
- isym.n_sclass = C_EXT;
+ if (h->root.type == bfd_link_hash_undefweak
+ && C_WEAKEXT == C_AIX_WEAKEXT)
+ isym.n_sclass = C_WEAKEXT;
+ else
+ isym.n_sclass = C_EXT;
aux.x_csect.x_smtyp = XTY_ER;
}
else if (h->root.type == bfd_link_hash_defined
@@ -5266,7 +5299,11 @@ xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf)
/* We just output an SD symbol. Now output an LD symbol. */
h->indx += 2;
- isym.n_sclass = C_EXT;
+ if (h->root.type == bfd_link_hash_undefweak
+ && C_WEAKEXT == C_AIX_WEAKEXT)
+ isym.n_sclass = C_WEAKEXT;
+ else
+ isym.n_sclass = C_EXT;
bfd_coff_swap_sym_out (output_bfd, (void *) &isym, (void *) outsym);
outsym += bfd_coff_symesz (output_bfd);
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 5056d8d..360dc0d 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,10 @@
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+ * config/tc-ppc.c (ppc_frob_symbol): Add csect information for
+ C_AIX_WEAKEXT too.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
* config/tc-ppc.c (md_apply_fix): On COFF targets, always reread
"value" from fx_offset. Manually resubtract md_pcrel_from_section
where necessary.
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index c3803b3..537b676 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -5170,6 +5170,7 @@ ppc_frob_symbol (symbolS *sym)
S_SET_STORAGE_CLASS (sym, C_HIDEXT);
if (S_GET_STORAGE_CLASS (sym) == C_EXT
+ || S_GET_STORAGE_CLASS (sym) == C_AIX_WEAKEXT
|| S_GET_STORAGE_CLASS (sym) == C_HIDEXT)
{
int i;
diff --git a/include/coff/ChangeLog b/include/coff/ChangeLog
index d96ae1c..09cd873 100644
--- a/include/coff/ChangeLog
+++ b/include/coff/ChangeLog
@@ -1,5 +1,15 @@
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+ * internal.h (C_AIX_WEAKEXT): New macro.
+ (C_WEAKEXT): Use the GNU definition in the generic part of the file,
+ and conditionally reset it to C_AIX_WEAKEXT in the XCOFF part of
+ the file.
+ (CSECT_SYM_P): New macro.
+ * xcoff.h (L_WEAK): Define.
+ (EXTERN_SYM_P): New macro.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
* xcoff.h (XCOFF_ALLOCATED): New flag.
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
diff --git a/include/coff/internal.h b/include/coff/internal.h
index 2c9ae46..c5d6cd1 100644
--- a/include/coff/internal.h
+++ b/include/coff/internal.h
@@ -273,12 +273,7 @@ struct internal_aouthdr
#define C_LINE 104 /* line # reformatted as symbol table entry */
#define C_ALIAS 105 /* duplicate tag */
#define C_HIDDEN 106 /* ext symbol in dmert public lib */
-
-#if defined _AIX52 || defined AIX_WEAK_SUPPORT
-#define C_WEAKEXT 111 /* weak symbol -- AIX standard. */
-#else
#define C_WEAKEXT 127 /* weak symbol -- GNU extension. */
-#endif
/* New storage classes for TI COFF */
#define C_UEXT 19 /* Tentative external definition */
@@ -311,6 +306,12 @@ struct internal_aouthdr
#define C_HIDEXT 107 /* Un-named external symbol */
#define C_BINCL 108 /* Marks beginning of include file */
#define C_EINCL 109 /* Marks ending of include file */
+#define C_AIX_WEAKEXT 111 /* AIX definition of C_WEAKEXT. */
+
+#if defined _AIX52 || defined AIX_WEAK_SUPPORT
+#undef C_WEAKEXT
+#define C_WEAKEXT C_AIX_WEAKEXT
+#endif
/* storage classes for stab symbols for RS/6000 */
#define C_GSYM (0x80)
@@ -336,6 +337,10 @@ struct internal_aouthdr
#define C_THUMBEXTFUNC (C_THUMBEXT + 20) /* 150 */
#define C_THUMBSTATFUNC (C_THUMBSTAT + 20) /* 151 */
+/* True if XCOFF symbols of class CLASS have auxillary csect information. */
+#define CSECT_SYM_P(CLASS) \
+ ((CLASS) == C_EXT || (CLASS) == C_AIX_WEAKEXT || (CLASS) == C_HIDEXT)
+
/********************** SECTION HEADER **********************/
#define SCNNMLEN (8)
diff --git a/include/coff/xcoff.h b/include/coff/xcoff.h
index 3c3c8e9..4f9f7ed 100644
--- a/include/coff/xcoff.h
+++ b/include/coff/xcoff.h
@@ -214,6 +214,8 @@ struct internal_ldsym
#define L_ENTRY (0x20)
/* Exported symbol. */
#define L_EXPORT (0x10)
+/* Weak symbol. */
+#define L_WEAK (0x08)
/* The ldrel structure. This is used to represent a reloc in the
.loader section. */
@@ -644,4 +646,8 @@ struct xcoff_ar_hdr_big
#define arch_xhdr_big(bfd) \
((struct xcoff_ar_hdr_big *) arch_eltdata (bfd)->arch_header)
+/* True if symbols of class CLASS are external. */
+#define EXTERN_SYM_P(CLASS) \
+ ((CLASS) == C_EXT || (CLASS) == C_AIX_WEAKEXT)
+
#endif /* _INTERNAL_XCOFF_H */
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 81a6599..18b8bece 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,5 +1,27 @@
2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+ * ld-powerpc/aix-glink-2a.s, ld-powerpc/aix-glink-2a.ex,
+ ld-powerpc/aix-glink-2b.s, ld-powerpc/aix-glink-2c.s,
+ ld-powerpc/aix-glink-2c.ex, ld-powerpc/aix-glink-2d.s,
+ ld-powerpc/aix-glink-2-32.dd, ld-powerpc/aix-glink-2-64.dd,
+ ld-powerpc/aix-weak-1a.s, ld-powerpc/aix-weak-1b.s,
+ ld-powerpc/aix-weak-1-rel.hd, ld-powerpc/aix-weak-1-rel.nd,
+ ld-powerpc/aix-weak-1-dso.hd, ld-powerpc/aix-weak-1-dso.nd,
+ ld-powerpc/aix-weak-1-dso.dnd, ld-powerpc/aix-weak-1.ex,
+ ld-powerpc/aix-weak-2a.s, ld-powerpc/aix-weak-2a.ex,
+ ld-powerpc/aix-weak-2a.nd, ld-powerpc/aix-weak-2b.s,
+ ld-powerpc/aix-weak-2b.nd, ld-powerpc/aix-weak-2c.s,
+ ld-powerpc/aix-weak-2c.ex, ld-powerpc/aix-weak-2c.nd,
+ ld-powerpc/aix-weak-2c.od, ld-powerpc/aix-weak-3a.s,
+ ld-powerpc/aix-weak-3a.ex, ld-powerpc/aix-weak-3b.s,
+ ld-powerpc/aix-weak-3b.ex, ld-powerpc/aix-weak-3-32.d,
+ ld-powerpc/aix-weak-3-32.dd, ld-powerpc/aix-weak-3-64.d,
+ ld-powerpc/aix-weak-3-64.dd: New tests.
+ * ld-powerpc/aix52.exp: Run them. Replace tmp/aix-* with
+ tmp/aix64-* in 64-bit ld options.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
* ld-powerpc/aix-no-dup-syms-1a.s, ld-powerpc/aix-no-dup-syms-1b.s,
ld-powerpc/aix-no-dup-syms-1.ex, ld-powerpc/aix-no-dup-syms-1.im,
ld-powerpc/aix-no-dup-syms-1-dso.dnd,
diff --git a/ld/testsuite/ld-powerpc/aix-glink-2-32.dd b/ld/testsuite/ld-powerpc/aix-glink-2-32.dd
new file mode 100644
index 0000000..2c91d23
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-glink-2-32.dd
@@ -0,0 +1,69 @@
+
+tmpdir/aix-glink-2: file format aixcoff-rs6000
+
+
+Disassembly of section \.text:
+
+10000000 <\.b1>:
+10000000: 60 00 00 00 oril r0,r0,0
+
+10000004 <\.b2>:
+10000004: 60 00 00 00 oril r0,r0,0
+
+10000008 <\.b3>:
+10000008: 60 00 00 00 oril r0,r0,0
+
+1000000c <\.main>:
+1000000c: 48 00 f1 03 bla f100 <.*>
+10000010: 48 00 00 21 bl 10000030 <\.a2>
+10000014: 48 00 00 41 bl 10000054 <\.a3>
+10000018: 4b ff ff e9 bl 10000000 <\.b1>
+1000001c: 4b ff ff e9 bl 10000004 <\.b2>
+10000020: 4b ff ff e9 bl 10000008 <\.b3>
+10000024: 48 00 f5 03 bla f500 <.*>
+10000028: 48 00 00 51 bl 10000078 <\.c2>
+1000002c: 48 00 00 71 bl 1000009c <\.c3>
+
+10000030 <\.a2>:
+10000030: 81 82 00 00 l r12,0\(r2\)
+10000034: 90 41 00 14 st r2,20\(r1\)
+10000038: 80 0c 00 00 l r0,0\(r12\)
+1000003c: 80 4c 00 04 l r2,4\(r12\)
+10000040: 7c 09 03 a6 mtctr r0
+10000044: 4e 80 04 20 bctr
+10000048: 00 00 00 00 \.long 0x0
+1000004c: 00 0c 80 00 \.long 0xc8000
+10000050: 00 00 00 00 \.long 0x0
+
+10000054 <\.a3>:
+10000054: 81 82 00 04 l r12,4\(r2\)
+10000058: 90 41 00 14 st r2,20\(r1\)
+1000005c: 80 0c 00 00 l r0,0\(r12\)
+10000060: 80 4c 00 04 l r2,4\(r12\)
+10000064: 7c 09 03 a6 mtctr r0
+10000068: 4e 80 04 20 bctr
+1000006c: 00 00 00 00 \.long 0x0
+10000070: 00 0c 80 00 \.long 0xc8000
+10000074: 00 00 00 00 \.long 0x0
+
+10000078 <\.c2>:
+10000078: 81 82 00 08 l r12,8\(r2\)
+1000007c: 90 41 00 14 st r2,20\(r1\)
+10000080: 80 0c 00 00 l r0,0\(r12\)
+10000084: 80 4c 00 04 l r2,4\(r12\)
+10000088: 7c 09 03 a6 mtctr r0
+1000008c: 4e 80 04 20 bctr
+10000090: 00 00 00 00 \.long 0x0
+10000094: 00 0c 80 00 \.long 0xc8000
+10000098: 00 00 00 00 \.long 0x0
+
+1000009c <\.c3>:
+1000009c: 81 82 00 0c l r12,12\(r2\)
+100000a0: 90 41 00 14 st r2,20\(r1\)
+100000a4: 80 0c 00 00 l r0,0\(r12\)
+100000a8: 80 4c 00 04 l r2,4\(r12\)
+100000ac: 7c 09 03 a6 mtctr r0
+100000b0: 4e 80 04 20 bctr
+100000b4: 00 00 00 00 \.long 0x0
+100000b8: 00 0c 80 00 \.long 0xc8000
+100000bc: 00 00 00 00 \.long 0x0
diff --git a/ld/testsuite/ld-powerpc/aix-glink-2-64.dd b/ld/testsuite/ld-powerpc/aix-glink-2-64.dd
new file mode 100644
index 0000000..5a34f0a
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-glink-2-64.dd
@@ -0,0 +1,73 @@
+
+tmpdir/aix64-glink-2: file format aix5coff64-rs6000
+
+
+Disassembly of section \.text:
+
+0000000010000000 <\.b1>:
+ 10000000: 60 00 00 00 nop
+
+0000000010000004 <\.b2>:
+ 10000004: 60 00 00 00 nop
+
+0000000010000008 <\.b3>:
+ 10000008: 60 00 00 00 nop
+
+000000001000000c <\.main>:
+ 1000000c: 48 00 f1 03 bla f100 <.*>
+ 10000010: 48 00 00 21 bl 10000030 <\.a2>
+ 10000014: 48 00 00 45 bl 10000058 <\.a3>
+ 10000018: 4b ff ff e9 bl 10000000 <\.b1>
+ 1000001c: 4b ff ff e9 bl 10000004 <\.b2>
+ 10000020: 4b ff ff e9 bl 10000008 <\.b3>
+ 10000024: 48 00 f5 03 bla f500 <.*>
+ 10000028: 48 00 00 59 bl 10000080 <\.c2>
+ 1000002c: 48 00 00 7d bl 100000a8 <\.c3>
+
+0000000010000030 <\.a2>:
+ 10000030: e9 82 00 00 ld r12,0\(r2\)
+ 10000034: f8 41 00 28 std r2,40\(r1\)
+ 10000038: e8 0c 00 00 ld r0,0\(r12\)
+ 1000003c: e8 4c 00 08 ld r2,8\(r12\)
+ 10000040: 7c 09 03 a6 mtctr r0
+ 10000044: 4e 80 04 20 bctr
+ 10000048: 00 00 00 00 \.long 0x0
+ 1000004c: 00 0c a0 00 \.long 0xca000
+ 10000050: 00 00 00 00 \.long 0x0
+ 10000054: 00 00 00 18 \.long 0x18
+
+0000000010000058 <\.a3>:
+ 10000058: e9 82 00 08 ld r12,8\(r2\)
+ 1000005c: f8 41 00 28 std r2,40\(r1\)
+ 10000060: e8 0c 00 00 ld r0,0\(r12\)
+ 10000064: e8 4c 00 08 ld r2,8\(r12\)
+ 10000068: 7c 09 03 a6 mtctr r0
+ 1000006c: 4e 80 04 20 bctr
+ 10000070: 00 00 00 00 \.long 0x0
+ 10000074: 00 0c a0 00 \.long 0xca000
+ 10000078: 00 00 00 00 \.long 0x0
+ 1000007c: 00 00 00 18 \.long 0x18
+
+0000000010000080 <\.c2>:
+ 10000080: e9 82 00 10 ld r12,16\(r2\)
+ 10000084: f8 41 00 28 std r2,40\(r1\)
+ 10000088: e8 0c 00 00 ld r0,0\(r12\)
+ 1000008c: e8 4c 00 08 ld r2,8\(r12\)
+ 10000090: 7c 09 03 a6 mtctr r0
+ 10000094: 4e 80 04 20 bctr
+ 10000098: 00 00 00 00 \.long 0x0
+ 1000009c: 00 0c a0 00 \.long 0xca000
+ 100000a0: 00 00 00 00 \.long 0x0
+ 100000a4: 00 00 00 18 \.long 0x18
+
+00000000100000a8 <\.c3>:
+ 100000a8: e9 82 00 18 ld r12,24\(r2\)
+ 100000ac: f8 41 00 28 std r2,40\(r1\)
+ 100000b0: e8 0c 00 00 ld r0,0\(r12\)
+ 100000b4: e8 4c 00 08 ld r2,8\(r12\)
+ 100000b8: 7c 09 03 a6 mtctr r0
+ 100000bc: 4e 80 04 20 bctr
+ 100000c0: 00 00 00 00 \.long 0x0
+ 100000c4: 00 0c a0 00 \.long 0xca000
+ 100000c8: 00 00 00 00 \.long 0x0
+ 100000cc: 00 00 00 18 \.long 0x18
diff --git a/ld/testsuite/ld-powerpc/aix-glink-2a.ex b/ld/testsuite/ld-powerpc/aix-glink-2a.ex
new file mode 100644
index 0000000..406cabb
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-glink-2a.ex
@@ -0,0 +1,9 @@
+a1
+a2
+a3
+b1
+b2
+b3
+c1
+c2
+c3
diff --git a/ld/testsuite/ld-powerpc/aix-glink-2a.s b/ld/testsuite/ld-powerpc/aix-glink-2a.s
new file mode 100644
index 0000000..fafbe43
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-glink-2a.s
@@ -0,0 +1,41 @@
+ .toc
+
+ .macro defabs,type,name,value
+ \type \name
+ \name = \value
+ .endm
+
+ .macro deffun,type,name,fn
+ \type \name
+ .csect \name\()[DS]
+\name\():
+ .if size == 32
+ .long .\name\()[PR],TOC[TC0],0
+ .else
+ .llong .\name\()[PR],TOC[TC0],0
+ .endif
+
+ .globl .\name
+ .csect .\name\()[PR]
+.\name\():
+ nop
+ .endm
+
+ .macro defdata,type,name,contents
+ \type \name
+ .csect \name\()[RW]
+\name\():
+ .long \contents
+ .endm
+
+ defabs .globl,a1,0xf100
+ deffun .globl,a2
+ defdata .globl,a3,0x1100
+
+ defabs .globl,b1,0xf200
+ deffun .globl,b2
+ defdata .globl,b3,0x2200
+
+ defabs .weak,c1,0xf300
+ deffun .weak,c2
+ defdata .weak,c3,0x3300
diff --git a/ld/testsuite/ld-powerpc/aix-glink-2b.s b/ld/testsuite/ld-powerpc/aix-glink-2b.s
new file mode 100644
index 0000000..9c06d48
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-glink-2b.s
@@ -0,0 +1,12 @@
+ .toc
+
+ .macro deffun,type,name
+ .globl .\name
+ .csect .\name\()[PR]
+.\name\():
+ nop
+ .endm
+
+ deffun .globl,b1
+ deffun .globl,b2
+ deffun .globl,b3
diff --git a/ld/testsuite/ld-powerpc/aix-glink-2c.ex b/ld/testsuite/ld-powerpc/aix-glink-2c.ex
new file mode 100644
index 0000000..4e16c9b
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-glink-2c.ex
@@ -0,0 +1,6 @@
+a1
+a2
+a3
+c1
+c2
+c3
diff --git a/ld/testsuite/ld-powerpc/aix-glink-2c.s b/ld/testsuite/ld-powerpc/aix-glink-2c.s
new file mode 100644
index 0000000..7dd6dad
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-glink-2c.s
@@ -0,0 +1,33 @@
+ .toc
+
+ .macro defabs,type,name,value
+ \type \name
+ \name = \value
+ .endm
+
+ .macro deffun,type,name
+ \type \name
+ .csect \name\()[DS]
+\name\():
+ .long \name\()[PR],TOC[TC0],0
+
+ .globl .\name
+ .csect .\name\()[PR]
+.\name\():
+ nop
+ .endm
+
+ .macro defdata,type,name,contents
+ \type \name
+ .csect \name\()[RW]
+\name\():
+ .long \contents
+ .endm
+
+ defabs .globl,a1,0xf400
+ deffun .globl,a2
+ defdata .globl,a3,0x4400
+
+ defabs .globl,c1,0xf500
+ deffun .globl,c2
+ defdata .globl,c3,0x5500
diff --git a/ld/testsuite/ld-powerpc/aix-glink-2d.s b/ld/testsuite/ld-powerpc/aix-glink-2d.s
new file mode 100644
index 0000000..ba78609
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-glink-2d.s
@@ -0,0 +1,12 @@
+ .globl .main
+ .csect .main[PR]
+.main:
+ bl .a1
+ bl .a2
+ bl .a3
+ bl .b1
+ bl .b2
+ bl .b3
+ bl .c1
+ bl .c2
+ bl .c3
diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-dso.dnd b/ld/testsuite/ld-powerpc/aix-weak-1-dso.dnd
new file mode 100644
index 0000000..3105fa3
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-1-dso.dnd
@@ -0,0 +1,17 @@
+# Comments are (aix-weak-1a.s type) wins over/loses to (aix-weak-1b.s type)
+# (strong common) loses to (strong data)
+0*10000010 D a
+# (strong common) wins over (weak data)
+0*10000020 B b
+# (strong data) wins over (strong common)
+0*10000000 D c
+# (weak data) loses to (strong common)
+0*10000028 B d
+# (weak common) loses to (strong data)
+0*10000018 D e
+# (weak common) wins over (weak data)
+0*10000024 W f
+# (strong data) wins over (weak common)
+0*10000008 D g
+# (weak data) wins over (weak common)
+0*1000000c W h
diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-dso.hd b/ld/testsuite/ld-powerpc/aix-weak-1-dso.hd
new file mode 100644
index 0000000..7368a5a
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-1-dso.hd
@@ -0,0 +1,12 @@
+.*
+
+Sections:
+Idx Name * Size * VMA * LMA * File off *Algn
+ *0 \.text * 0+00 * 0*10000000 * 0*10000000 * [^ ]+ * 2\*\*2
+ *ALLOC, LOAD, CODE
+ *1 \.data * 0+20 * 0*10000000 * 0*10000000 * [^ ]+ * 2\*\*3
+ *CONTENTS, ALLOC, LOAD, DATA
+# Should only have 3 three common symbols.
+ *2 \.bss * 0+0c * 0*10000020 * 0*10000020 * [^ ]+ * 2\*\*3
+ *ALLOC
+#pass
diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-dso.nd b/ld/testsuite/ld-powerpc/aix-weak-1-dso.nd
new file mode 100644
index 0000000..3289e25
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-1-dso.nd
@@ -0,0 +1,25 @@
+# Comments are (aix-weak-1a.s type) wins over/loses to (aix-weak-1b.s type)
+# (strong common) loses to (strong data)
+0*10000010 d a
+0*10000010 D a
+# (strong common) wins over (weak data)
+0*10000020 B b
+0*10000014 d b
+# (strong data) wins over (strong common)
+0*10000000 d c
+0*10000000 D c
+# (weak data) loses to (strong common)
+0*10000004 d d
+0*10000028 B d
+# (weak common) loses to (strong data)
+0*10000018 d e
+0*10000018 D e
+# (weak common) wins over (weak data)
+0*10000024 W f
+0*1000001c d f
+# (strong data) wins over (weak common)
+0*10000008 d g
+0*10000008 D g
+# (weak data) wins over (weak common)
+0*1000000c d h
+0*1000000c W h
diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-rel.hd b/ld/testsuite/ld-powerpc/aix-weak-1-rel.hd
new file mode 100644
index 0000000..9ae4d47
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-1-rel.hd
@@ -0,0 +1,12 @@
+.*
+
+Sections:
+Idx Name * Size * VMA * LMA * File off *Algn
+ *0 \.text * 0+00 * 0+00 * 0+00 * [^ ]+ * 2\*\*2
+ *ALLOC, LOAD, CODE
+ *1 \.data * 0+20 * 0+00 * 0+00 * [^ ]+ * 2\*\*3
+ *CONTENTS, ALLOC, LOAD, DATA
+# Should only have 3 three common symbols.
+ *2 \.bss * 0+0c * 0+20 * 0+20 * [^ ]+ * 2\*\*3
+ *ALLOC
+#pass
diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-rel.nd b/ld/testsuite/ld-powerpc/aix-weak-1-rel.nd
new file mode 100644
index 0000000..73cfe90
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-1-rel.nd
@@ -0,0 +1,25 @@
+# Comments are (aix-weak-1a.s type) wins over/loses to (aix-weak-1b.s type)
+# (strong common) loses to (strong data)
+0+10 d a
+0+10 D a
+# (strong common) wins over (weak data)
+0+20 B b
+0+14 d b
+# (strong data) wins over (strong common)
+0+00 d c
+0+00 D c
+# (weak data) loses to (strong common)
+0+04 d d
+0+28 B d
+# (weak common) loses to (strong data)
+0+18 d e
+0+18 D e
+# (weak common) wins over (weak data)
+0+24 W f
+0+1c d f
+# (strong data) wins over (weak common)
+0+08 d g
+0+08 D g
+# (weak data) wins over (weak common)
+0+0c d h
+0+0c W h
diff --git a/ld/testsuite/ld-powerpc/aix-weak-1.ex b/ld/testsuite/ld-powerpc/aix-weak-1.ex
new file mode 100644
index 0000000..71ac1b5
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-1.ex
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+e
+f
+g
+h
diff --git a/ld/testsuite/ld-powerpc/aix-weak-1a.s b/ld/testsuite/ld-powerpc/aix-weak-1a.s
new file mode 100644
index 0000000..da529ca
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-1a.s
@@ -0,0 +1,24 @@
+ .comm a,4
+ .comm b,4
+ .globl c
+ .csect c[RW],2
+c:
+ .long 0x11111111
+ .weak d
+ .csect d[RW],2
+d:
+ .long 0x22222222
+
+ # Same again, with weak common symbols
+ .weak e
+ .comm e,4
+ .weak f
+ .comm f,4
+ .globl g
+ .csect g[RW],2
+g:
+ .long 0x33333333
+ .weak h
+ .csect h[RW],2
+h:
+ .long 0x44444444
diff --git a/ld/testsuite/ld-powerpc/aix-weak-1b.s b/ld/testsuite/ld-powerpc/aix-weak-1b.s
new file mode 100644
index 0000000..e6c2429
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-1b.s
@@ -0,0 +1,24 @@
+ .globl a
+ .csect a[RW],2
+a:
+ .long 0x55555555
+ .weak b
+ .csect b[RW],2
+b:
+ .long 0x66666666
+ .comm c,4
+ .comm d,4
+
+ # Same again, with weak common symbols
+ .globl e
+ .csect e[RW],2
+e:
+ .long 0x77777777
+ .weak f
+ .csect f[RW],2
+f:
+ .long 0x88888888
+ .weak g
+ .comm g,4
+ .weak h
+ .comm h,4
diff --git a/ld/testsuite/ld-powerpc/aix-weak-2a.ex b/ld/testsuite/ld-powerpc/aix-weak-2a.ex
new file mode 100644
index 0000000..0e65a8f
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-2a.ex
@@ -0,0 +1,8 @@
+c1
+c2
+c3
+c4
+d1
+d2
+d3
+d4
diff --git a/ld/testsuite/ld-powerpc/aix-weak-2a.nd b/ld/testsuite/ld-powerpc/aix-weak-2a.nd
new file mode 100644
index 0000000..2c2ea1c
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-2a.nd
@@ -0,0 +1,8 @@
+0*cccc1111 W c1
+0*cccc2222 W c2
+0*cccc3333 A c3
+0*cccc4444 A c4
+0*ffff1111 W d1
+0*ffff2222 W d2
+0*10000000 D d3
+0*10000004 D d4
diff --git a/ld/testsuite/ld-powerpc/aix-weak-2a.s b/ld/testsuite/ld-powerpc/aix-weak-2a.s
new file mode 100644
index 0000000..e4d8a04
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-2a.s
@@ -0,0 +1,21 @@
+ .weak c1
+ c1 = 0xcccc1111
+ .weak c2
+ c2 = 0xcccc2222
+ .globl c3
+ c3 = 0xcccc3333
+ .globl c4
+ c4 = 0xcccc4444
+
+ .weak d1
+ d1 = 0xffff1111
+ .weak d2
+ d2 = 0xffff2222
+ .globl d3
+ .csect d3[DS]
+d3:
+ .long 0xffff3333
+ .globl d4
+ .csect d4[DS]
+d4:
+ .long 0xffff4444
diff --git a/ld/testsuite/ld-powerpc/aix-weak-2b.nd b/ld/testsuite/ld-powerpc/aix-weak-2b.nd
new file mode 100644
index 0000000..d54b35b
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-2b.nd
@@ -0,0 +1,8 @@
+0*dddd1111 A c1
+0*dddd2222 W c2
+0*dddd3333 A c3
+0*dddd4444 W c4
+0*10000000 D d1
+0*eeee2222 W d2
+0*10000004 D d3
+0*eeee4444 W d4
diff --git a/ld/testsuite/ld-powerpc/aix-weak-2b.s b/ld/testsuite/ld-powerpc/aix-weak-2b.s
new file mode 100644
index 0000000..84885ab
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-2b.s
@@ -0,0 +1,21 @@
+ .globl c1
+ c1 = 0xdddd1111
+ .weak c2
+ c2 = 0xdddd2222
+ .globl c3
+ c3 = 0xdddd3333
+ .weak c4
+ c4 = 0xdddd4444
+
+ .globl d1
+ .csect d1[DS]
+d1:
+ .long 0xeeee1111
+ .weak d2
+ d2 = 0xeeee2222
+ .globl d3
+ .csect d3[DS]
+d3:
+ .long 0xeeee3333
+ .weak d4
+ d4 = 0xeeee4444
diff --git a/ld/testsuite/ld-powerpc/aix-weak-2c.ex b/ld/testsuite/ld-powerpc/aix-weak-2c.ex
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-2c.ex
@@ -0,0 +1 @@
+foo
diff --git a/ld/testsuite/ld-powerpc/aix-weak-2c.nd b/ld/testsuite/ld-powerpc/aix-weak-2c.nd
new file mode 100644
index 0000000..d42034b
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-2c.nd
@@ -0,0 +1,10 @@
+0*dddd1111 C c1
+0*cccc2222 C c2
+0*cccc3333 C c3
+0*cccc4444 C c4
+ * U d1
+0*ffff2222 C d2
+ * U d3
+ * U d4
+0*10000000 d foo
+0*10000000 D foo
diff --git a/ld/testsuite/ld-powerpc/aix-weak-2c.od b/ld/testsuite/ld-powerpc/aix-weak-2c.od
new file mode 100644
index 0000000..272c80e
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-2c.od
@@ -0,0 +1,13 @@
+
+.*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET * TYPE * VALUE
+0*10000010 R_POS * d1
+0*10000018 R_POS * d3
+0*1000001c R_POS * d4
+
+
+Contents of section \.data:
+ 0*10000000 dddd1111 cccc2222 cccc3333 cccc4444 .*
+ 0*10000010 00000000 ffff2222 00000000 00000000 .*
diff --git a/ld/testsuite/ld-powerpc/aix-weak-2c.s b/ld/testsuite/ld-powerpc/aix-weak-2c.s
new file mode 100644
index 0000000..5ca93d3
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-2c.s
@@ -0,0 +1,11 @@
+ .globl foo
+ .csect foo[DS]
+foo:
+ .long c1
+ .long c2
+ .long c3
+ .long c4
+ .long d1
+ .long d2
+ .long d3
+ .long d4
diff --git a/ld/testsuite/ld-powerpc/aix-weak-3-32.d b/ld/testsuite/ld-powerpc/aix-weak-3-32.d
new file mode 100644
index 0000000..45976c9
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-3-32.d
@@ -0,0 +1,5 @@
+#name: Weak test 3 (main, static) (32-bit)
+#source: aix-weak-3b.s
+#as: -a32 --defsym size=32
+#ld: -b32 -e.main -bnoautoimp tmpdir/aix-weak-3a.so
+#error: .*multiple definition of `x1'\n[^\n]*first defined here
diff --git a/ld/testsuite/ld-powerpc/aix-weak-3-32.dd b/ld/testsuite/ld-powerpc/aix-weak-3-32.dd
new file mode 100644
index 0000000..c52b735a
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-3-32.dd
@@ -0,0 +1,24 @@
+
+.*
+
+
+Disassembly of section \.data:
+
+20000000 <x1>:
+20000000: 00 00 01 02 .*
+
+20000004 <x2>:
+20000004: 00 00 03 04 .*
+
+20000008 <TOC>:
+20000008: 20 00 00 00 .*
+ 20000008: R_POS x1\+.*
+
+2000000c <x2>:
+2000000c: 20 00 00 04 .*
+ 2000000c: R_POS x2\+.*
+
+20000010 <x3>:
+20000010: 00 00 00 00 .*
+ 20000010: R_POS x3
+20000014: 00 00 00 00 .*
diff --git a/ld/testsuite/ld-powerpc/aix-weak-3-64.d b/ld/testsuite/ld-powerpc/aix-weak-3-64.d
new file mode 100644
index 0000000..4673175
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-3-64.d
@@ -0,0 +1,5 @@
+#name: Weak test 3 (main, static) (64-bit)
+#source: aix-weak-3b.s
+#as: -a64 --defsym size=64
+#ld: -b64 -e.main -bnoautoimp tmpdir/aix64-weak-3a.so
+#error: .*multiple definition of `x1'\n[^\n]*first defined here
diff --git a/ld/testsuite/ld-powerpc/aix-weak-3-64.dd b/ld/testsuite/ld-powerpc/aix-weak-3-64.dd
new file mode 100644
index 0000000..7c10f6c
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-3-64.dd
@@ -0,0 +1,26 @@
+
+.*
+
+
+Disassembly of section \.data:
+
+0000000020000000 <x1>:
+ 20000000: 00 00 01 02 .*
+
+0000000020000004 <x2>:
+ 20000004: 00 00 03 04 .*
+
+0000000020000008 <TOC>:
+ 20000008: 00 00 00 00 .*
+ 20000008: R_POS_64 x1\+.*
+ 2000000c: 20 00 00 00 .*
+
+0000000020000010 <x2>:
+ 20000010: 00 00 00 00 .*
+ 20000010: R_POS_64 x2\+.*
+ 20000014: 20 00 00 04 .*
+
+0000000020000018 <x3>:
+ 20000018: 00 00 00 00 .*
+ 20000018: R_POS_64 x3
+ 2000001c: 00 00 00 00 .*
diff --git a/ld/testsuite/ld-powerpc/aix-weak-3a.ex b/ld/testsuite/ld-powerpc/aix-weak-3a.ex
new file mode 100644
index 0000000..589f40b
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-3a.ex
@@ -0,0 +1,3 @@
+x1
+x2
+x3
diff --git a/ld/testsuite/ld-powerpc/aix-weak-3a.s b/ld/testsuite/ld-powerpc/aix-weak-3a.s
new file mode 100644
index 0000000..e8b9d96
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-3a.s
@@ -0,0 +1,8 @@
+ .globl x1
+ x1 = 0x11223344
+ .globl x2
+ x2 = 0x55667788
+ .globl x3
+ .csect x3[RW]
+x3:
+ .long 42
diff --git a/ld/testsuite/ld-powerpc/aix-weak-3b.ex b/ld/testsuite/ld-powerpc/aix-weak-3b.ex
new file mode 100644
index 0000000..975fbec
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-3b.ex
@@ -0,0 +1 @@
+y
diff --git a/ld/testsuite/ld-powerpc/aix-weak-3b.s b/ld/testsuite/ld-powerpc/aix-weak-3b.s
new file mode 100644
index 0000000..4e69082
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/aix-weak-3b.s
@@ -0,0 +1,30 @@
+ .globl x1
+ .csect x1[RW]
+x1:
+ .long 0x0102
+
+ .weak x2
+ .csect x2[RW]
+x2:
+ .long 0x0304
+
+ .toc
+Tx1:
+ .tc x1[TC],x1
+Tx2:
+ .tc x2[TC],x2
+Tx3:
+ .tc x3[TC],x3
+
+ .globl .main
+ .csect .main[PR]
+.main:
+ .if size == 32
+ lwz 1,Tx1(2)
+ lwz 1,Tx2(2)
+ lwz 1,Tx3(2)
+ .else
+ ld 1,Tx1(2)
+ ld 1,Tx2(2)
+ ld 1,Tx3(2)
+ .endif
diff --git a/ld/testsuite/ld-powerpc/aix52.exp b/ld/testsuite/ld-powerpc/aix52.exp
index 6cd26fe..98bbda3 100644
--- a/ld/testsuite/ld-powerpc/aix52.exp
+++ b/ld/testsuite/ld-powerpc/aix52.exp
@@ -124,6 +124,64 @@ set aix52tests {
{{objdump -dS aix-lineno-1b.dd} {nm {} aix-lineno-1b.nd}}
"aix-lineno-1b.exe"}
+ {"Glink test 2 (part a)" "-shared -bE:aix-glink-2a.ex"
+ "" {aix-glink-2a.s}
+ {}
+ "aix-glink-2a.so"}
+
+ {"Glink test 2 (part b)" "-r"
+ "" {aix-glink-2b.s}
+ {}
+ "aix-glink-2b.ro"}
+
+ {"Glink test 2 (part c)" "-shared -bE:aix-glink-2c.ex"
+ "" {aix-glink-2c.s}
+ {}
+ "aix-glink-2c.so"}
+
+ {"Glink test 2"
+ "-e.main tmpdir/aix-glink-2a.so tmpdir/aix-glink-2b.ro tmpdir/aix-glink-2c.so"
+ "" {aix-glink-2d.s}
+ {{objdump -d aix-glink-2-SIZE.dd}}
+ "aix-glink-2"}
+
+ {"Weak test 1 (rel)" "-r"
+ "" {aix-weak-1a.s aix-weak-1b.s}
+ {{nm {} aix-weak-1-rel.nd} {objdump -h aix-weak-1-rel.hd}}
+ "aix-weak-1.o"}
+
+ {"Weak test 1 (shared, nogc)" "-shared -bE:aix-weak-1.ex -bnogc"
+ "" {aix-weak-1a.s aix-weak-1b.s}
+ {{nm {} aix-weak-1-dso.nd} {objdump -h aix-weak-1-dso.hd}
+ {nm -D aix-weak-1-dso.dnd}}
+ "aix-weak-1-nogc.so"}
+
+ {"Weak test 2 (library 1)" "-shared -bE:aix-weak-2a.ex"
+ "" {aix-weak-2a.s}
+ {{nm -D aix-weak-2a.nd}}
+ "aix-weak-2a.so"}
+
+ {"Weak test 2 (library 2)" "-shared -bE:aix-weak-2a.ex"
+ "" {aix-weak-2b.s}
+ {{nm -D aix-weak-2b.nd}}
+ "aix-weak-2b.so"}
+
+ {"Weak test 2 (main library)"
+ "-shared -bE:aix-weak-2c.ex tmpdir/aix-weak-2a.so tmpdir/aix-weak-2b.so"
+ "" {aix-weak-2c.s}
+ {{nm {} aix-weak-2c.nd} {objdump {-sj.data -R} aix-weak-2c.od}}
+ "aix-weak-2c.so"}
+
+ {"Weak test 3 (library)" "-shared -bE:aix-weak-3a.ex"
+ "" {aix-weak-3a.s}
+ {}
+ "aix-weak-3a.so"}
+
+ {"Weak test 3 (main, dynamic)" "-e.main tmpdir/aix-weak-3a.so"
+ "" {aix-weak-3b.s}
+ {{objdump -Dzrj.data aix-weak-3-SIZE.dd}}
+ "aix-weak-3"}
+
{"TOC test 1" "-shared -bE:aix-toc-1.ex"
"" {aix-toc-1a.s aix-toc-1b.s}
{{objdump -dr aix-toc-1-SIZE.dd}}
@@ -136,3 +194,6 @@ foreach test $aix52tests {
run_aix_test 64 $name $ldopts $asopts $sources $tools $output
}
}
+
+run_dump_test "aix-weak-3-32"
+run_dump_test "aix-weak-3-64"