include/coff/
authorRichard Sandiford <rdsandiford@googlemail.com>
Sat, 14 Mar 2009 09:33:39 +0000 (09:33 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Sat, 14 Mar 2009 09:33:39 +0000 (09:33 +0000)
* 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.

16 files changed:
bfd/ChangeLog
bfd/xcofflink.c
include/coff/ChangeLog
include/coff/xcoff.h
ld/testsuite/ChangeLog
ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.dnd [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.drd [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.nd [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-no-dup-syms-1-dso.rd [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-no-dup-syms-1-rel.nd [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-no-dup-syms-1-rel.rd [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-no-dup-syms-1.ex [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-no-dup-syms-1.im [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-no-dup-syms-1a.s [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-no-dup-syms-1b.s [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix52.exp

index 6f9011a..a734dfe 100644 (file)
@@ -1,5 +1,18 @@
 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.
+       (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  <r.sandiford@uk.ibm.com>
+
        * xcofflink.c (bfd_xcoff_import_symbol): Treat imported absolute
        symbols as XMC_XO.
 
index 39d278e..cbc750c 100644 (file)
@@ -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;
index 91118a1..d96ae1c 100644 (file)
@@ -1,5 +1,9 @@
 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>
+
        * xcoff.h (XCOFF_CALLED, XCOFF_IMPORT): Update comments.
        (XCOFF_WAS_UNDEFINED): New flag.
        (xcoff_link_hash_table): Add an "rtld" field.
index 7e32d7a..3c3c8e9 100644 (file)
@@ -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.  */
 
index 0edc58b..81a6599 100644 (file)
@@ -1,5 +1,17 @@
 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,
+       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  <r.sandiford@uk.ibm.com>
+
        * ld-powerpc/aix-abs-branch-1.nd,
        ld-powerpc/aix-abs-reloc-1.nd: New tests.
        * ld-powerpc/aix52.exp: Run them.
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 (file)
index 0000000..1fccdeb
--- /dev/null
@@ -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 (file)
index 0000000..f262feb
--- /dev/null
@@ -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 (file)
index 0000000..be25ff3
--- /dev/null
@@ -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 (file)
index 0000000..d17151b
--- /dev/null
@@ -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 (file)
index 0000000..e2bdbc4
--- /dev/null
@@ -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 (file)
index 0000000..436ad98
--- /dev/null
@@ -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 (file)
index 0000000..8f1fe4d
--- /dev/null
@@ -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 (file)
index 0000000..257cc56
--- /dev/null
@@ -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 (file)
index 0000000..3138670
--- /dev/null
@@ -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 (file)
index 0000000..c5fcf38
--- /dev/null
@@ -0,0 +1,9 @@
+       .globl  x
+       .csect  x[RW]
+x:
+       .long   8
+       .globl  x2
+       .csect  x2[RW]
+x2:
+       .long   x
+       .long   foo
index 10e2031..6cd26fe 100644 (file)
@@ -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}