bfd/
authorRichard Sandiford <rdsandiford@googlemail.com>
Sat, 14 Mar 2009 09:35:06 +0000 (09:35 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Sat, 14 Mar 2009 09:35:06 +0000 (09:35 +0000)
* xcofflink.c (xcoff_mark_symbol_by_name): New function.
(bfd_xcoff_size_dynamic_sections): Use it to mark the entry,
init and fini functions.  Do garbage collection for objects
without an entry point too.

ld/testsuite/
* ld-powerpc/aix-gc-1.s, ld-powerpc/aix-gc-1.ex,
ld-powerpc/aix-gc-1-32.dd, ld-powerpc/aix-gc-1-64.dd,
ld-powerpc/aix-weak-1-gcdso.dnd, ld-powerpc/aix-weak-1-gcdso.hd,
ld-powerpc/aix-weak-1-gcdso.nd: New tests.
* ld-powerpc/aix52.exp: Run them.

bfd/ChangeLog
bfd/xcofflink.c
ld/testsuite/ChangeLog
ld/testsuite/ld-powerpc/aix-gc-1-32.dd [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-gc-1-64.dd [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-gc-1.ex [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-gc-1.s [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-weak-1-gcdso.dnd [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-weak-1-gcdso.hd [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix-weak-1-gcdso.nd [new file with mode: 0644]
ld/testsuite/ld-powerpc/aix52.exp

index 25c2fde0e995c1a8e315270a0d5a4094aad94610..4bad45e1e6c9b780b45b37bd8fcf60d8ae7c81de 100644 (file)
@@ -1,3 +1,10 @@
+2009-03-14  Richard Sandiford  <r.sandiford@uk.ibm.com>
+
+       * xcofflink.c (xcoff_mark_symbol_by_name): New function.
+       (bfd_xcoff_size_dynamic_sections): Use it to mark the entry,
+       init and fini functions.  Do garbage collection for objects
+       without an entry point too.
+
 2009-03-14  Richard Sandiford  <r.sandiford@uk.ibm.com>
 
        * coffcode.h (coff_pointerize_aux_hook): Update CSECT_SYM_P to
index d87940c39552efeffda4511c0de9e1f6a811d515..3ca9b7287ada123acd780a0a5defa1ae1648e4a8 100644 (file)
@@ -2482,6 +2482,30 @@ xcoff_mark_symbol (struct bfd_link_info *info, struct xcoff_link_hash_entry *h)
   return TRUE;
 }
 
+/* Look for a symbol called NAME.  If the symbol is defined, mark it.
+   If the symbol exists, set FLAGS.  */
+
+static bfd_boolean
+xcoff_mark_symbol_by_name (struct bfd_link_info *info,
+                          const char *name, unsigned int flags)
+{
+  struct xcoff_link_hash_entry *h;
+
+  h = xcoff_link_hash_lookup (xcoff_hash_table (info), name,
+                             FALSE, FALSE, TRUE);
+  if (h != NULL)
+    {
+      h->flags |= flags;
+      if (h->root.type == bfd_link_hash_defined
+         || h->root.type == bfd_link_hash_defweak)
+       {
+         if (!xcoff_mark (info, h->root.u.def.section))
+           return FALSE;
+       }
+    }
+  return TRUE;
+}
+
 /* The mark phase of garbage collection.  For a given section, mark
    it, and all the sections which define symbols to which it refers.
    Because this function needs to look at the relocs, we also count
@@ -3177,7 +3201,6 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd,
                                 asection **special_sections,
                                 bfd_boolean rtld)
 {
-  struct xcoff_link_hash_entry *hentry;
   asection *lsec;
   struct xcoff_loader_info ldinfo;
   int i;
@@ -3216,15 +3239,6 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd,
   xcoff_hash_table (info)->textro = textro;
   xcoff_hash_table (info)->rtld = rtld;
 
-  hentry = NULL;
-  if (entry != NULL)
-    {
-      hentry = xcoff_link_hash_lookup (xcoff_hash_table (info), entry,
-                                      FALSE, FALSE, TRUE);
-      if (hentry != NULL)
-       hentry->flags |= XCOFF_ENTRY;
-    }
-
   /* __rtinit */
   if (info->init_function || info->fini_function || rtld)
     {
@@ -3277,11 +3291,7 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd,
     }
 
   /* Garbage collect unused sections.  */
-  if (info->relocatable
-      || ! gc
-      || hentry == NULL
-      || (hentry->root.type != bfd_link_hash_defined
-         && hentry->root.type != bfd_link_hash_defweak))
+  if (info->relocatable || !gc)
     {
       gc = FALSE;
       xcoff_hash_table (info)->gc = FALSE;
@@ -3309,7 +3319,14 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd,
     }
   else
     {
-      if (! xcoff_mark (info, hentry->root.u.def.section))
+      if (entry != NULL
+         && !xcoff_mark_symbol_by_name (info, entry, XCOFF_ENTRY))
+       goto error_return;
+      if (info->init_function != NULL
+         && !xcoff_mark_symbol_by_name (info, info->init_function, 0))
+       goto error_return;
+      if (info->fini_function != NULL
+         && !xcoff_mark_symbol_by_name (info, info->fini_function, 0))
        goto error_return;
       xcoff_sweep (info);
       xcoff_hash_table (info)->gc = TRUE;
index 18b8beceecce794b76ef88a73a4e99669b1f55f0..a2cdc378e692dafaf5a8c5d669740b3113eab45e 100644 (file)
@@ -1,3 +1,11 @@
+2009-03-14  Richard Sandiford  <r.sandiford@uk.ibm.com>
+
+       * ld-powerpc/aix-gc-1.s, ld-powerpc/aix-gc-1.ex,
+       ld-powerpc/aix-gc-1-32.dd, ld-powerpc/aix-gc-1-64.dd,
+       ld-powerpc/aix-weak-1-gcdso.dnd, ld-powerpc/aix-weak-1-gcdso.hd,
+       ld-powerpc/aix-weak-1-gcdso.nd: New tests.
+       * ld-powerpc/aix52.exp: Run them.
+
 2009-03-14  Richard Sandiford  <r.sandiford@uk.ibm.com>
 
        * ld-powerpc/aix-glink-2a.s, ld-powerpc/aix-glink-2a.ex,
diff --git a/ld/testsuite/ld-powerpc/aix-gc-1-32.dd b/ld/testsuite/ld-powerpc/aix-gc-1-32.dd
new file mode 100644 (file)
index 0000000..324b298
--- /dev/null
@@ -0,0 +1,67 @@
+
+.*
+
+
+Disassembly of section \.text:
+
+10000000 <\.init_function>:
+10000000:      80 22 00 00     l       r1,0\(r2\)
+
+10000004 <\.fini_function>:
+10000004:      80 22 00 04     l       r1,4\(r2\)
+
+10000008 <\.exported_global>:
+10000008:      48 00 00 09     bl      10000010 <\.indirect2>
+
+1000000c <\.indirect1>:
+1000000c:      81 08 00 04     l       r8,4\(r8\)
+
+10000010 <\.indirect2>:
+10000010:      81 08 00 08     l       r8,8\(r8\)
+
+10000014 <\.indirect3>:
+10000014:      81 08 00 0c     l       r8,12\(r8\)
+
+Disassembly of section \.data:
+
+20000000 <block>:
+# Pointer to indirect3.
+20000000:      20 00 00 98     .*
+20000004:      11 22 33 44     .*
+
+20000008 <__rtinit>:
+#...
+
+20000068 <exported_global>:
+20000068:      10 00 00 08     .*
+2000006c:      20 00 00 a4     .*
+20000070:      00 00 00 00     .*
+
+20000074 <init_function>:
+20000074:      10 00 00 00     .*
+20000078:      20 00 00 a4     .*
+2000007c:      00 00 00 00     .*
+
+20000080 <indirect1>:
+20000080:      10 00 00 0c     .*
+20000084:      20 00 00 a4     .*
+20000088:      00 00 00 00     .*
+
+2000008c <fini_function>:
+2000008c:      10 00 00 04     .*
+20000090:      20 00 00 a4     .*
+20000094:      00 00 00 00     .*
+
+20000098 <indirect3>:
+20000098:      10 00 00 14     .*
+2000009c:      20 00 00 a4     .*
+200000a0:      00 00 00 00     .*
+
+200000a4 <TOC>:
+# TOC entry for indirect1.
+200000a4:      20 00 00 80     .*
+
+200000a8 <block>:
+# TOC entry for block.
+200000a8:      20 00 00 00     .*
+200000ac:      00 00 00 00     .*
diff --git a/ld/testsuite/ld-powerpc/aix-gc-1-64.dd b/ld/testsuite/ld-powerpc/aix-gc-1-64.dd
new file mode 100644 (file)
index 0000000..00e9a88
--- /dev/null
@@ -0,0 +1,81 @@
+
+.*
+
+
+Disassembly of section \.text:
+
+0000000010000000 <\.init_function>:
+    10000000:  e8 22 00 00     ld      r1,0\(r2\)
+
+0000000010000004 <\.fini_function>:
+    10000004:  e8 22 00 08     ld      r1,8\(r2\)
+
+0000000010000008 <\.exported_global>:
+    10000008:  48 00 00 09     bl      10000010 <\.indirect2>
+
+000000001000000c <\.indirect1>:
+    1000000c:  81 08 00 04     lwz     r8,4\(r8\)
+
+0000000010000010 <\.indirect2>:
+    10000010:  81 08 00 08     lwz     r8,8\(r8\)
+
+0000000010000014 <\.indirect3>:
+    10000014:  81 08 00 0c     lwz     r8,12\(r8\)
+
+Disassembly of section \.data:
+
+0000000020000000 <block>:
+# Pointer to indirect3.
+    20000000:  20 00 00 e0     .*
+    20000004:  11 22 33 44     .*
+
+0000000020000008 <__rtinit>:
+#...
+
+0000000020000080 <exported_global>:
+    20000080:  00 00 00 00     .*
+    20000084:  10 00 00 08     .*
+    20000088:  00 00 00 00     .*
+    2000008c:  20 00 00 f8     .*
+    20000090:  00 00 00 00     .*
+    20000094:  00 00 00 00     .*
+
+0000000020000098 <init_function>:
+    20000098:  00 00 00 00     .*
+    2000009c:  10 00 00 00     .*
+    200000a0:  00 00 00 00     .*
+    200000a4:  20 00 00 f8     .*
+    200000a8:  00 00 00 00     .*
+    200000ac:  00 00 00 00     .*
+
+00000000200000b0 <indirect1>:
+    200000b0:  00 00 00 00     .*
+    200000b4:  10 00 00 0c     .*
+    200000b8:  00 00 00 00     .*
+    200000bc:  20 00 00 f8     .*
+    200000c0:  00 00 00 00     .*
+    200000c4:  00 00 00 00     .*
+
+00000000200000c8 <fini_function>:
+    200000c8:  00 00 00 00     .*
+    200000cc:  10 00 00 04     .*
+    200000d0:  00 00 00 00     .*
+    200000d4:  20 00 00 f8     .*
+    200000d8:  00 00 00 00     .*
+    200000dc:  00 00 00 00     .*
+
+00000000200000e0 <indirect3>:
+    200000e0:  00 00 00 00     .*
+    200000e4:  10 00 00 14     .*
+    200000e8:  00 00 00 00     .*
+    200000ec:  20 00 00 f8     .*
+    200000f0:  00 00 00 00     .*
+    200000f4:  00 00 00 00     .*
+
+00000000200000f8 <TOC>:
+    200000f8:  00 00 00 00     .*
+    200000fc:  20 00 00 b0     .*
+
+0000000020000100 <block>:
+    20000100:  00 00 00 00     .*
+    20000104:  20 00 00 00     .*
diff --git a/ld/testsuite/ld-powerpc/aix-gc-1.ex b/ld/testsuite/ld-powerpc/aix-gc-1.ex
new file mode 100644 (file)
index 0000000..c7a82ec
--- /dev/null
@@ -0,0 +1 @@
+exported_global
diff --git a/ld/testsuite/ld-powerpc/aix-gc-1.s b/ld/testsuite/ld-powerpc/aix-gc-1.s
new file mode 100644 (file)
index 0000000..821fd5c
--- /dev/null
@@ -0,0 +1,55 @@
+       .macro  loadtoc,sym
+       .if     size == 32
+       lwz     1,\sym(2)
+       .else
+       ld      1,\sym(2)
+       .endif
+       .endm
+
+       .toc
+LC01:  .tc     indirect1[TC],indirect1[RW]
+LC02:  .tc     block[TC],block[RW]
+
+       .csect  .unused_local[PR]
+.unused_local:
+       bl      .unused_global
+
+       .globl  .init_function
+       .csect  .init_function[PR]
+.init_function:
+       loadtoc LC01
+
+       .globl  .fini_function
+       .csect  .fini_function[PR]
+.fini_function:
+       loadtoc LC02
+
+       .globl  .unused_global
+       .csect  .unused_global[PR]
+.unused_global:
+       bl      .unused_local
+
+       .globl  .exported_global
+       .csect  .exported_global[PR]
+.exported_global:
+       bl      .indirect2
+
+       .globl  .indirect1
+       .csect  .indirect1[PR]
+.indirect1:
+       lwz     8,4(8)
+
+       .csect  .indirect2[PR]
+.indirect2:
+       lwz     8,8(8)
+
+       .globl  .indirect3
+       .csect  .indirect3[PR]
+.indirect3:
+       lwz     8,12(8)
+
+       .globl  block
+       .csect  block[RW]
+block:
+       .long   indirect3
+       .long   0x11223344
diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-gcdso.dnd b/ld/testsuite/ld-powerpc/aix-weak-1-gcdso.dnd
new file mode 100644 (file)
index 0000000..ba82e27
--- /dev/null
@@ -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*1000000c D a
+# (strong common) wins over (weak data)
+0*10000018 B b
+# (strong data) wins over (strong common)
+0*10000000 D c
+# (weak data) loses to (strong common)
+0*10000020 B d
+# (weak common) loses to (strong data)
+0*10000010 D e
+# (weak common) wins over (weak data)
+0*1000001c W f
+# (strong data) wins over (weak common)
+0*10000004 D g
+# (weak data) wins over (weak common)
+0*10000008 W h
diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-gcdso.hd b/ld/testsuite/ld-powerpc/aix-weak-1-gcdso.hd
new file mode 100644 (file)
index 0000000..6afe1be
--- /dev/null
@@ -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+18 * 0*10000000 * 0*10000000 * [^ ]+ * 2\*\*3
+ *CONTENTS, ALLOC, LOAD, DATA
+# Should only have 3 three common symbols.
+ *2 \.bss  * 0+0c * 0*10000018 * 0*10000018 * [^ ]+ * 2\*\*3
+ *ALLOC
+#pass
diff --git a/ld/testsuite/ld-powerpc/aix-weak-1-gcdso.nd b/ld/testsuite/ld-powerpc/aix-weak-1-gcdso.nd
new file mode 100644 (file)
index 0000000..d8d9a78
--- /dev/null
@@ -0,0 +1,22 @@
+# Comments are (aix-weak-1a.s type) wins over/loses to (aix-weak-1b.s type)
+# (strong common) loses to (strong data)
+0*1000000c d a
+0*1000000c D a
+# (strong common) wins over (weak data)
+0*10000018 B b
+# (strong data) wins over (strong common)
+0*10000000 d c
+0*10000000 D c
+# (weak data) loses to (strong common)
+0*10000020 B d
+# (weak common) loses to (strong data)
+0*10000010 d e
+0*10000010 D e
+# (weak common) wins over (weak data)
+0*1000001c W f
+# (strong data) wins over (weak common)
+0*10000004 d g
+0*10000004 D g
+# (weak data) wins over (weak common)
+0*10000008 d h
+0*10000008 W h
index 98bbda3d7e1cf58aa37ea7532ffbc69e7d6aef60..330de2778521a27cd790684e1c92ecd9cb15485b 100644 (file)
@@ -108,6 +108,12 @@ set aix52tests {
       {nm -D aix-no-dup-syms-1-dso.dnd} {objdump -R aix-no-dup-syms-1-dso.drd}}
      "aix-no-dup-syms-1.so"}
 
+    {"Garbage collection test 1"
+     "-shared -binitfini:init_function:fini_function -bE:aix-gc-1.ex"
+     "" {aix-gc-1.s}
+     {{objdump {-dz -j.text -j.data} aix-gc-1-SIZE.dd}}
+     "aix-gc-1.so"}
+
     {"Glink test 1"
      "-shared -bE:aix-glink-1.ex --unresolved-symbols=ignore-all"
      "" {aix-glink-1.s}
@@ -156,6 +162,12 @@ set aix52tests {
       {nm -D aix-weak-1-dso.dnd}}
      "aix-weak-1-nogc.so"}
 
+    {"Weak test 1 (shared, gc)" "-shared -bE:aix-weak-1.ex"
+     "" {aix-weak-1a.s aix-weak-1b.s}
+     {{nm {} aix-weak-1-gcdso.nd} {objdump -h aix-weak-1-gcdso.hd}
+      {nm -D aix-weak-1-gcdso.dnd}}
+     "aix-weak-1-gc.so"}
+
     {"Weak test 2 (library 1)" "-shared -bE:aix-weak-2a.ex"
      "" {aix-weak-2a.s}
      {{nm -D aix-weak-2a.nd}}