This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[17/21] Suppor garbage collection without an entry point


Although the AIX linker has a -bnogc option, I don't think it's expected
to be used much.  Garbage collection is the default, and the system
libraries tend to put several independent functions in the same archive
object.  (For example, as mentioned in a previous message, the libc.a
file that defines setjmp also defines a bunch of other less well-used
functions like ukey_setjmp.)

The GNU AIX linker also garbage-collects by default, but only for objects
with a defined entry point.  We ought to do garbage collection for shared
libraries too.

We're actually almost there.  We already mark all exported symbols and
the entry point.  We simply need to mark any init and fini functions too.

OK to install?

Richard


bfd/
	* 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.

Index: bfd/xcofflink.c
===================================================================
--- bfd/xcofflink.c	2009-03-10 13:51:47.000000000 +0000
+++ bfd/xcofflink.c	2009-03-10 13:52:29.000000000 +0000
@@ -2482,6 +2482,30 @@ xcoff_mark_symbol (struct bfd_link_info 
   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 *ou
 				 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 *ou
   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 *ou
     }
 
   /* 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 *ou
     }
   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: ld/testsuite/ld-powerpc/aix-gc-1.s
===================================================================
--- /dev/null	2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-gc-1.s	2009-03-10 13:52:29.000000000 +0000
@@ -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
Index: ld/testsuite/ld-powerpc/aix-gc-1.ex
===================================================================
--- /dev/null	2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-gc-1.ex	2009-03-10 13:52:29.000000000 +0000
@@ -0,0 +1,1 @@
+exported_global
Index: ld/testsuite/ld-powerpc/aix-gc-1-32.dd
===================================================================
--- /dev/null	2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-gc-1-32.dd	2009-03-10 13:52:29.000000000 +0000
@@ -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 	.*
Index: ld/testsuite/ld-powerpc/aix-gc-1-64.dd
===================================================================
--- /dev/null	2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-gc-1-64.dd	2009-03-10 13:52:29.000000000 +0000
@@ -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 	.*
Index: ld/testsuite/ld-powerpc/aix-weak-1-gcdso.dnd
===================================================================
--- /dev/null	2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-1-gcdso.dnd	2009-03-10 13:52:29.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*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
Index: ld/testsuite/ld-powerpc/aix-weak-1-gcdso.hd
===================================================================
--- /dev/null	2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-1-gcdso.hd	2009-03-10 13:52:29.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+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
Index: ld/testsuite/ld-powerpc/aix-weak-1-gcdso.nd
===================================================================
--- /dev/null	2009-02-06 09:11:03.343159000 +0000
+++ ld/testsuite/ld-powerpc/aix-weak-1-gcdso.nd	2009-03-10 13:52:29.000000000 +0000
@@ -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: ld/testsuite/ld-powerpc/aix52.exp
===================================================================
--- ld/testsuite/ld-powerpc/aix52.exp	2009-03-10 13:51:47.000000000 +0000
+++ ld/testsuite/ld-powerpc/aix52.exp	2009-03-10 13:52:29.000000000 +0000
@@ -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}}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]