This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[17/21] Suppor garbage collection without an entry point
- From: Richard Sandiford <richards at transitive dot com>
- To: binutils at sourceware dot org
- Date: Tue, 10 Mar 2009 14:46:07 +0000
- Subject: [17/21] Suppor garbage collection without an entry point
- References: <g4y6vd7a4x.fsf@richards-desktop.transitives.com>
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}}