From 5b49f6dc399d611d8d8a10e2e2c922f38e6bb038 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sat, 14 Mar 2009 09:33:39 +0000 Subject: [PATCH] include/coff/ * xcoff.h (XCOFF_ALLOCATED): New flag. bfd/ * 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. (xcoff_keep_symbol_p): Use it to check whether an external XCOFF symbol is a valid definition of the associated output symbol. Use XCOFF_ALLOCATED to stop the same hash table entry having two output symbols. (bfd_xcoff_size_dynamic_sections): Set XCOFF_ALLOCATED when keeping a symbol. (xcoff_link_input_bfd): Use xcoff_final_definition_p. ld/testsuite/ * 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, ld-powerpc/aix-no-dup-syms-1-dso.drd, ld-powerpc/aix-no-dup-syms-1-dso.nd, ld-powerpc/aix-no-dup-syms-1-dso.rd, ld-powerpc/aix-no-dup-syms-1-rel.nd, ld-powerpc/aix-no-dup-syms-1-rel.rd: New tests. * ld-powerpc/aix52.exp: Run them. --- bfd/ChangeLog | 13 +++ bfd/xcofflink.c | 88 ++++++++++++------- include/coff/ChangeLog | 4 + include/coff/xcoff.h | 2 + ld/testsuite/ChangeLog | 12 +++ .../ld-powerpc/aix-no-dup-syms-1-dso.dnd | 4 + .../ld-powerpc/aix-no-dup-syms-1-dso.drd | 9 ++ .../ld-powerpc/aix-no-dup-syms-1-dso.nd | 8 ++ .../ld-powerpc/aix-no-dup-syms-1-dso.rd | 9 ++ .../ld-powerpc/aix-no-dup-syms-1-rel.nd | 8 ++ .../ld-powerpc/aix-no-dup-syms-1-rel.rd | 9 ++ ld/testsuite/ld-powerpc/aix-no-dup-syms-1.ex | 3 + ld/testsuite/ld-powerpc/aix-no-dup-syms-1.im | 1 + ld/testsuite/ld-powerpc/aix-no-dup-syms-1a.s | 9 ++ ld/testsuite/ld-powerpc/aix-no-dup-syms-1b.s | 9 ++ ld/testsuite/ld-powerpc/aix52.exp | 12 +++ 16 files changed, 170 insertions(+), 30 deletions(-) create mode 100644 ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.dnd create mode 100644 ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.drd create mode 100644 ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.nd create mode 100644 ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.rd create mode 100644 ld/testsuite/ld-powerpc/aix-no-dup-syms-1-rel.nd create mode 100644 ld/testsuite/ld-powerpc/aix-no-dup-syms-1-rel.rd create mode 100644 ld/testsuite/ld-powerpc/aix-no-dup-syms-1.ex create mode 100644 ld/testsuite/ld-powerpc/aix-no-dup-syms-1.im create mode 100644 ld/testsuite/ld-powerpc/aix-no-dup-syms-1a.s create mode 100644 ld/testsuite/ld-powerpc/aix-no-dup-syms-1b.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6f9011a1541..a734dfe3981 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2009-03-14 Richard Sandiford + + * 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. + (xcoff_keep_symbol_p): Use it to check whether an external XCOFF + symbol is a valid definition of the associated output symbol. + Use XCOFF_ALLOCATED to stop the same hash table entry having + two output symbols. + (bfd_xcoff_size_dynamic_sections): Set XCOFF_ALLOCATED when + keeping a symbol. + (xcoff_link_input_bfd): Use xcoff_final_definition_p. + 2009-03-14 Richard Sandiford * xcofflink.c (bfd_xcoff_import_symbol): Treat imported absolute diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index 39d278ec6dd..cbc750c16d1 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -2504,7 +2504,6 @@ xcoff_mark (struct bfd_link_info *info, asection *sec) relend = rel + sec->reloc_count; for (; rel < relend; rel++) { - asection *rsec; struct xcoff_link_hash_entry *h; if ((unsigned int) rel->r_symndx @@ -2512,21 +2511,25 @@ xcoff_mark (struct bfd_link_info *info, asection *sec) continue; h = obj_xcoff_sym_hashes (sec->owner)[rel->r_symndx]; - if (h != NULL - && (h->flags & XCOFF_MARK) == 0) + if (h != NULL) { - if (! xcoff_mark_symbol (info, h)) - return FALSE; + if ((h->flags & XCOFF_MARK) == 0) + { + if (!xcoff_mark_symbol (info, h)) + return FALSE; + } } - - rsec = xcoff_data (sec->owner)->csects[rel->r_symndx]; - if (rsec != NULL - && !bfd_is_und_section (rsec) - && !bfd_is_abs_section (rsec) - && (rsec->flags & SEC_MARK) == 0) + else { - if (! xcoff_mark (info, rsec)) - return FALSE; + asection *rsec; + + rsec = xcoff_data (sec->owner)->csects[rel->r_symndx]; + if (rsec != NULL + && (rsec->flags & SEC_MARK) == 0) + { + if (!xcoff_mark (info, rsec)) + return FALSE; + } } /* See if this reloc needs to be copied into the .loader @@ -2826,6 +2829,36 @@ bfd_xcoff_record_link_assignment (bfd *output_bfd, /* Add a symbol to the .loader symbols, if necessary. */ +/* INPUT_BFD has an external symbol associated with hash table entry H + and csect CSECT. Return true if INPUT_BFD defines H. */ + +static bfd_boolean +xcoff_final_definition_p (bfd *input_bfd, struct xcoff_link_hash_entry *h, + asection *csect) +{ + switch (h->root.type) + { + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + /* No input bfd owns absolute symbols. They are written by + xcoff_write_global_symbol instead. */ + return (!bfd_is_abs_section (csect) + && h->root.u.def.section == csect); + + case bfd_link_hash_common: + return h->root.u.c.p->section->owner == input_bfd; + + case bfd_link_hash_undefined: + case bfd_link_hash_undefweak: + /* We can't treat undef.abfd as the owner because that bfd + might be a dynamic object. Allow any bfd to claim it. */ + return TRUE; + + default: + abort (); + } +} + static bfd_boolean xcoff_build_ldsyms (struct xcoff_link_hash_entry *h, void * p) { @@ -3036,23 +3069,17 @@ xcoff_keep_symbol_p (struct bfd_link_info *info, bfd *input_bfd, if (info->strip == strip_all) return 0; - /* We can ignore external references that were resolved by the link. */ - smtyp = SMTYP_SMTYP (aux->x_csect.x_smtyp); - if (isym->n_sclass == C_EXT - && smtyp == XTY_ER - && h->root.type != bfd_link_hash_undefined) - return 0; - - /* We can ignore common symbols if they got defined somewhere else. */ - if (isym->n_sclass == C_EXT - && smtyp == XTY_CM - && (h->root.type != bfd_link_hash_common - || h->root.u.c.p->section != csect) - && (h->root.type != bfd_link_hash_defined - || h->root.u.def.section != csect)) - return 0; + /* Discard symbols that are defined elsewhere. */ + if (isym->n_sclass == C_EXT) + { + if ((h->flags & XCOFF_ALLOCATED) != 0) + return 0; + if (!xcoff_final_definition_p (input_bfd, h, csect)) + return 0; + } /* 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 && (isym->n_sclass != C_HIDEXT || smtyp != XTY_SD)) @@ -3513,6 +3540,8 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd, } else *debug_index = -1; + if (*sym_hash != 0) + (*sym_hash)->flags |= XCOFF_ALLOCATED; if (*lineno_counts > 0) csect->output_section->lineno_count += *lineno_counts; } @@ -3690,8 +3719,7 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *finfo, if (isymp->n_sclass == C_EXT && *sym_hash != NULL && (*sym_hash)->ldsym != NULL - && (smtyp != XTY_ER - || (*sym_hash)->root.type == bfd_link_hash_undefined)) + && xcoff_final_definition_p (input_bfd, *sym_hash, *csectpp)) { struct xcoff_link_hash_entry *h; struct internal_ldsym *ldsym; diff --git a/include/coff/ChangeLog b/include/coff/ChangeLog index 91118a1a75a..d96ae1ca141 100644 --- a/include/coff/ChangeLog +++ b/include/coff/ChangeLog @@ -1,3 +1,7 @@ +2009-03-14 Richard Sandiford + + * xcoff.h (XCOFF_ALLOCATED): New flag. + 2009-03-14 Richard Sandiford * xcoff.h (XCOFF_CALLED, XCOFF_IMPORT): Update comments. diff --git a/include/coff/xcoff.h b/include/coff/xcoff.h index 7e32d7a7805..3c3c8e9ead5 100644 --- a/include/coff/xcoff.h +++ b/include/coff/xcoff.h @@ -318,6 +318,8 @@ struct xcoff_link_hash_entry #define XCOFF_SYSCALL64 0x00010000 /* Symbol was not explicitly defined by the time it was marked. */ #define XCOFF_WAS_UNDEFINED 0x00020000 +/* We have assigned an output XCOFF entry to this symbol. */ +#define XCOFF_ALLOCATED 0x00040000 /* The XCOFF linker hash table. */ diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 0edc58b31cf..81a65990b83 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2009-03-14 Richard Sandiford + + * 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, + ld-powerpc/aix-no-dup-syms-1-dso.drd, + ld-powerpc/aix-no-dup-syms-1-dso.nd, + ld-powerpc/aix-no-dup-syms-1-dso.rd, + ld-powerpc/aix-no-dup-syms-1-rel.nd, + ld-powerpc/aix-no-dup-syms-1-rel.rd: New tests. + * ld-powerpc/aix52.exp: Run them. + 2009-03-14 Richard Sandiford * ld-powerpc/aix-abs-branch-1.nd, diff --git a/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.dnd b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.dnd new file mode 100644 index 00000000000..1fccdeb839e --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.dnd @@ -0,0 +1,4 @@ + * U foo +0*10000000 D x +0*10000004 D x1 +0*10000014 D x2 diff --git a/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.drd b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.drd new file mode 100644 index 00000000000..f262febd427 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.drd @@ -0,0 +1,9 @@ + +.* + +DYNAMIC RELOCATION RECORDS +OFFSET * TYPE * VALUE +0*10000004 R_POS(|_32) * \.data +0*10000008 R_POS(|_32) * foo +0*10000014 R_POS(|_32) * \.data +0*10000018 R_POS(|_32) * foo diff --git a/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.nd b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.nd new file mode 100644 index 00000000000..be25ff37c35 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.nd @@ -0,0 +1,8 @@ + * U foo +0*10000000 d x +0*10000000 D x +0*10000010 d x +0*10000004 d x1 +0*10000004 D x1 +0*10000014 d x2 +0*10000014 D x2 diff --git a/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.rd b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.rd new file mode 100644 index 00000000000..d17151ba414 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.rd @@ -0,0 +1,9 @@ + +.* + +RELOCATION RECORDS FOR \[\.data\]: +OFFSET * TYPE * VALUE +0+04 R_POS(|_32) * x\+0xf*f0000000 +0+08 R_POS(|_32) * foo +0+14 R_POS(|_32) * x\+0xf*effffff0 +0+18 R_POS(|_32) * foo diff --git a/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-rel.nd b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-rel.nd new file mode 100644 index 00000000000..e2bdbc4b8ab --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-rel.nd @@ -0,0 +1,8 @@ + + U foo +0+00 d x +0+00 D x +0+10 d x +0+04 d x1 +0+04 D x1 +0+14 d x2 +0+14 D x2 diff --git a/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-rel.rd b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-rel.rd new file mode 100644 index 00000000000..436ad9841d9 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1-rel.rd @@ -0,0 +1,9 @@ + +.* + +RELOCATION RECORDS FOR \[\.data\]: +OFFSET * TYPE * VALUE +0+04 R_POS(|_32) * x +0+08 R_POS(|_32) * foo +0+14 R_POS(|_32) * x\+0xf+0 +0+18 R_POS(|_32) * foo diff --git a/ld/testsuite/ld-powerpc/aix-no-dup-syms-1.ex b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1.ex new file mode 100644 index 00000000000..8f1fe4d696f --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1.ex @@ -0,0 +1,3 @@ +x +x1 +x2 diff --git a/ld/testsuite/ld-powerpc/aix-no-dup-syms-1.im b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1.im new file mode 100644 index 00000000000..257cc5642cb --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1.im @@ -0,0 +1 @@ +foo diff --git a/ld/testsuite/ld-powerpc/aix-no-dup-syms-1a.s b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1a.s new file mode 100644 index 00000000000..31386707718 --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1a.s @@ -0,0 +1,9 @@ + .globl x + .csect x[RW] +x: + .long 4 + .globl x1 + .csect x1[RW] +x1: + .long x + .long foo diff --git a/ld/testsuite/ld-powerpc/aix-no-dup-syms-1b.s b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1b.s new file mode 100644 index 00000000000..c5fcf38df9c --- /dev/null +++ b/ld/testsuite/ld-powerpc/aix-no-dup-syms-1b.s @@ -0,0 +1,9 @@ + .globl x + .csect x[RW] +x: + .long 8 + .globl x2 + .csect x2[RW] +x2: + .long x + .long foo diff --git a/ld/testsuite/ld-powerpc/aix52.exp b/ld/testsuite/ld-powerpc/aix52.exp index 10e20311955..6cd26fe8f53 100644 --- a/ld/testsuite/ld-powerpc/aix52.exp +++ b/ld/testsuite/ld-powerpc/aix52.exp @@ -96,6 +96,18 @@ set aix52tests { {{objdump -h aix-core-sec-3.hd}} "aix-core-sec-3.so"} + {"Duplicate symbol check 1 (rel)" "-r" + "" {aix-no-dup-syms-1a.s aix-no-dup-syms-1b.s} + {{nm {} aix-no-dup-syms-1-rel.nd} {objdump -r aix-no-dup-syms-1-rel.rd}} + "aix-no-dup-syms-1.o"} + + {"Duplicate symbol check 1 (shared)" + "-shared --allow-multiple-definition -bI:aix-no-dup-syms-1.im -bE:aix-no-dup-syms-1.ex" + "" {aix-no-dup-syms-1a.s aix-no-dup-syms-1b.s} + {{nm {} aix-no-dup-syms-1-dso.nd} {objdump -r aix-no-dup-syms-1-dso.rd} + {nm -D aix-no-dup-syms-1-dso.dnd} {objdump -R aix-no-dup-syms-1-dso.drd}} + "aix-no-dup-syms-1.so"} + {"Glink test 1" "-shared -bE:aix-glink-1.ex --unresolved-symbols=ignore-all" "" {aix-glink-1.s} -- 2.30.2