This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[16/21] Add AIX weak support
This patch adds support for AIX C_WEAKEXT symbols.
Unfortunately, there seems to be some historical baggage here.
The AIX port was originally developed before AIX 5.2 came out,
and at that time AIX did not support weak symbols. We had this
GNU-specific C_WEAKEXT definition instead:
#define C_WEAKEXT 127 /* weak symbol -- GNU extension. */
We wrote out BSF_WEAK symbols using this C_WEAKEXT, and read C_WEAKEXT
symbols as BSF_WEAK, but for XCOFF we did little else. The linker didn't
even enter weak symbols into the hash table, so a simple test like:
--------------------------------------------------------------------------
#!/bin/bash
set -eu
cat <<EOF >f1.s
.weak foo
.csect foo[RW]
foo:
.long 1
EOF
cat <<EOF >f2.s
.globl bar
.csect bar[RW]
bar:
.long foo
EOF
cat <<EOF >exports
bar
EOF
./gas/as-new f1.s -o f1.o
./gas/as-new f2.s -o f2.o
./ld/ld-new f1.o f2.o -o f.so -shared -bnogc -bE:exports
--------------------------------------------------------------------------
failed with:
f2.o:fake:(.rw+0x0): undefined reference to `foo'
Weak support was added in AIX 5.2, which used a C_WEAKEXT value of 111
instead of 127. The following patch added this alternative value:
2003-12-02 Graham Reed <grahamr@algorithmics.com>
* internal.h (C_WEAKEXT): Add alternative value for AIX 5.2
based targets.
However, no other changes were made, so weak symbols were still
essentially unsupported. The testcase above still fails for AIX 5.2.
The AIX semantics of C_WEAKEXT are very different from what we implement
at the moment. The symbols behave similarly to C_EXT and C_HIDEXT,
in that:
(a) they should have auxillary csect information
(b) they may have auxillary function information
But despite the problems above, I don't think it's appropriate to
change the meaning of GNU C_WEAKEXT symbols. The new behaviour
should apply to AIX C_WEAKEXT only. I've therefore added a new
C_AIX_WEAKEXT symbol type and made the new code use that instead
of C_WEAKEXT. The general principle (which I think is used quite
a lot in binutils) is that:
- We should handle existing C_AIX_WEAKEXT symbols without trying
to be puritanical about the configured AIX version. That is,
we shouldn't refuse to handle existing C_AIX_WEAKEXT symbols
simply because we were configured for AIX 5.1 or below.
- We should only use the new features if they're supported.
As well as C_WEAKEXT, AIX 5.2 added a new L_WEAK flag for dynamic
(.loader) symbols. The patch handles that too.
The main non-obvious change is to xcoff_link_add_dynamic_symbols.
This function looks at each symbol S defined by dynamic object D
and currently does the following:
(1) If S was previously unknown, the function assumes that D defines S.
It indicates this by setting S's symbol type to bfd_link_hash_undefined
and pointing undef.abfd at D.
(2) If S was previously undefined, and no dynamic definition has yet
been found, the function again assumes that D defines S. It indicates
this by leaving S's type as-is (bfd_link_hash_undefined or _undefweak)
and pointing undef.abfd at D.
(3) If S previously had an unknown symbol class (XMC_UA), or was
previously marked as _undefined or _undefweak, the function sets
its symbol class to the one found in B.
(1) and (2) are sensible enough, but I take issue with (3). If D doesn't
define S, I don't think it's right to copy the symbol class found in D to S.
We should stick with whatever the defining bfd said.
I think it makes more sense to skip any symbols that D doesn't define.
This makes the current logic more obvious, but more importantly,
it's then easier to see how weak support should fit in.
OK to install?
Richard
include/coff/
* 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.
bfd/
* 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.
gas/
* config/tc-ppc.c (ppc_frob_symbol): Add csect information for
C_AIX_WEAKEXT too.
ld/testsuite/
* 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.
Index: include/coff/internal.h
===================================================================
--- include/coff/internal.h 2009-03-10 13:38:52.000000000 +0000
+++ include/coff/internal.h 2009-03-10 13:51:47.000000000 +0000
@@ -273,12 +273,7 @@ #define C_FILE 103 /* file name */
#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 @@ #define C_VERSION 108 /* coff
#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 @@ #define C_THUMBLABEL (128 + C_LABEL)
#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)
Index: include/coff/xcoff.h
===================================================================
--- include/coff/xcoff.h 2009-03-10 13:49:33.000000000 +0000
+++ include/coff/xcoff.h 2009-03-10 13:51:47.000000000 +0000
@@ -214,6 +214,8 @@ #define L_IMPORT (0x40)
#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 @@ #define arch_xhdr(bfd) \
#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 */
Index: bfd/coffcode.h
===================================================================
--- bfd/coffcode.h 2009-03-10 13:38:52.000000000 +0000
+++ bfd/coffcode.h 2009-03-10 13:51:47.000000000 +0000
@@ -2416,7 +2416,7 @@ #define symname_in_debug_hook \
#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 ATTR
{
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_UNUS
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. */
Index: bfd/coff-rs6000.c
===================================================================
--- bfd/coff-rs6000.c 2009-03-10 13:46:23.000000000 +0000
+++ bfd/coff-rs6000.c 2009-03-10 13:51:47.000000000 +0000
@@ -422,6 +422,7 @@ _bfd_xcoff_swap_aux_in (abfd, ext1, type
/* 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
/* 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_se
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_se
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)
{
Index: bfd/coff64-rs6000.c
===================================================================
--- bfd/coff64-rs6000.c 2009-03-10 13:46:23.000000000 +0000
+++ bfd/coff64-rs6000.c 2009-03-10 13:51:47.000000000 +0000
@@ -381,6 +381,7 @@ _bfd_xcoff64_swap_aux_in (abfd, ext1, ty
/* 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, ty
/* 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_
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_
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)
{
Index: bfd/coffgen.c
===================================================================
--- bfd/coffgen.c 2009-03-10 13:38:52.000000000 +0000
+++ bfd/coffgen.c 2009-03-10 13:51:47.000000000 +0000
@@ -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;
Index: bfd/xcofflink.c
===================================================================
--- bfd/xcofflink.c 2009-03-10 13:49:33.000000000 +0000
+++ bfd/xcofflink.c 2009-03-10 13:51:47.000000000 +0000
@@ -258,7 +258,12 @@ _bfd_xcoff_canonicalize_dynamic_symtab (
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 *abf
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 *abf
if (hds == NULL)
return FALSE;
- if (hds->root.type == bfd_link_hash_new)
+ hds->descriptor = h;
+ h->descriptor = hds;
+ }
+
+ if (xcoff_dynamic_definition_p (hds, &ldsym))
+ {
+ hds->root.type = h->root.type;
+ hds->flags |= XCOFF_DEF_DYNAMIC;
+ if (h->smclas == XMC_XO)
{
- hds->root.type = bfd_link_hash_undefined;
+ /* 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. */
}
-
- 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))
- {
- 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;
}
}
}
@@ -1087,7 +1109,6 @@ #define N_BTSHFT n_btshft
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 @@ #define N_BTSHFT n_btshft
/* 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 @@ #define N_BTSHFT n_btshft
smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp);
- flags = BSF_GLOBAL;
section = NULL;
value = 0;
set_toc = NULL;
@@ -1327,7 +1347,7 @@ #define N_BTSHFT n_btshft
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 @@ #define N_BTSHFT n_btshft
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 @@ #define N_BTSHFT n_btshft
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 @@ #define N_BTSHFT n_btshft
/* 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 @@ #define N_BTSHFT n_btshft
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 @@ #define N_BTSHFT n_btshft
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 @@ #define N_BTSHFT n_btshft
}
}
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 @@ #define N_BTSHFT n_btshft
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_inf
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_inf
/* 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_inf
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 *ou
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 @@ #define N_BTSHFT n_btshft
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 @@ #define N_BTSHFT n_btshft
.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 @@ #define N_BTSHFT n_btshft
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 @@ #define N_BTSHFT n_btshft
/* 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 @@ #define N_BTSHFT n_btshft
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 @@ #define N_BTSHFT n_btshft
/* 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_
{
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_
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_
/* 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);
Index: gas/config/tc-ppc.c
===================================================================
--- gas/config/tc-ppc.c 2009-03-10 13:46:12.000000000 +0000
+++ gas/config/tc-ppc.c 2009-03-10 13:51:47.000000000 +0000
@@ -5046,6 +5046,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;
Index: ld/testsuite/ld-powerpc/aix-glink-2a.s
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-glink-2a.s 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-glink-2a.ex
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-glink-2a.ex 2009-03-10 13:51:47.000000000 +0000
@@ -0,0 +1,9 @@
+a1
+a2
+a3
+b1
+b2
+b3
+c1
+c2
+c3
Index: ld/testsuite/ld-powerpc/aix-glink-2b.s
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-glink-2b.s 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-glink-2c.s
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-glink-2c.s 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-glink-2c.ex
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-glink-2c.ex 2009-03-10 13:51:47.000000000 +0000
@@ -0,0 +1,6 @@
+a1
+a2
+a3
+c1
+c2
+c3
Index: ld/testsuite/ld-powerpc/aix-glink-2d.s
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-glink-2d.s 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-glink-2-32.dd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-glink-2-32.dd 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-glink-2-64.dd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-glink-2-64.dd 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-1a.s
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-1a.s 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-1b.s
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-1b.s 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-1-rel.hd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-1-rel.hd 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-1-rel.nd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-1-rel.nd 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-1-dso.hd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-1-dso.hd 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-1-dso.nd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-1-dso.nd 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-1-dso.dnd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-1-dso.dnd 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-1.ex
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-1.ex 2009-03-10 13:51:47.000000000 +0000
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+e
+f
+g
+h
Index: ld/testsuite/ld-powerpc/aix-weak-2a.s
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-2a.s 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-2a.ex
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-2a.ex 2009-03-10 13:51:47.000000000 +0000
@@ -0,0 +1,8 @@
+c1
+c2
+c3
+c4
+d1
+d2
+d3
+d4
Index: ld/testsuite/ld-powerpc/aix-weak-2a.nd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-2a.nd 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-2b.s
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-2b.s 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-2b.nd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-2b.nd 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-2c.s
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-2c.s 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-2c.ex
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-2c.ex 2009-03-10 13:51:47.000000000 +0000
@@ -0,0 +1,1 @@
+foo
Index: ld/testsuite/ld-powerpc/aix-weak-2c.nd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-2c.nd 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-2c.od
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-2c.od 2009-03-10 13:51:47.000000000 +0000
@@ -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 .*
Index: ld/testsuite/ld-powerpc/aix-weak-3a.s
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-3a.s 2009-03-10 13:51:47.000000000 +0000
@@ -0,0 +1,8 @@
+ .globl x1
+ x1 = 0x11223344
+ .globl x2
+ x2 = 0x55667788
+ .globl x3
+ .csect x3[RW]
+x3:
+ .long 42
Index: ld/testsuite/ld-powerpc/aix-weak-3a.ex
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-3a.ex 2009-03-10 13:51:47.000000000 +0000
@@ -0,0 +1,3 @@
+x1
+x2
+x3
Index: ld/testsuite/ld-powerpc/aix-weak-3b.s
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-3b.s 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-3b.ex
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-3b.ex 2009-03-10 13:51:47.000000000 +0000
@@ -0,0 +1,1 @@
+y
Index: ld/testsuite/ld-powerpc/aix-weak-3-32.d
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-3-32.d 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-3-32.dd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-3-32.dd 2009-03-10 13:51:47.000000000 +0000
@@ -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 .*
Index: ld/testsuite/ld-powerpc/aix-weak-3-64.d
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-3-64.d 2009-03-10 13:51:47.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-weak-3-64.dd
===================================================================
--- /dev/null 2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-3-64.dd 2009-03-10 13:51:47.000000000 +0000
@@ -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 .*
Index: ld/testsuite/ld-powerpc/aix52.exp
===================================================================
--- ld/testsuite/ld-powerpc/aix52.exp 2009-03-10 13:49:33.000000000 +0000
+++ ld/testsuite/ld-powerpc/aix52.exp 2009-03-10 13:51:47.000000000 +0000
@@ -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"