From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17279 invoked by alias); 10 Mar 2009 14:46:30 -0000 Received: (qmail 17266 invoked by uid 22791); 10 Mar 2009 14:46:28 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_73 X-Spam-Check-By: sourceware.org Received: from mx.transitive.com (HELO mx.transitive.com) (85.91.225.206) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 10 Mar 2009 14:46:17 +0000 Received: by mx.transitive.com (Postfix, from userid 65534) id 0D4EB140DA; Tue, 10 Mar 2009 14:43:18 +0000 (GMT) X-Spam-Score: -2.4 Received: from richards-desktop.transitives.com (richards-desktop.transitives.com [192.168.2.43]) by mx.transitive.com (Postfix) with ESMTP id 3F20013A68 for ; Tue, 10 Mar 2009 14:43:11 +0000 (GMT) Received: from richards-desktop.transitives.com (localhost.localdomain [127.0.0.1]) by richards-desktop.transitives.com (8.13.8/8.13.8) with ESMTP id n2AEk7L6032299 for ; Tue, 10 Mar 2009 14:46:07 GMT Received: (from richards@localhost) by richards-desktop.transitives.com (8.13.8/8.13.8/Submit) id n2AEk7qJ032298; Tue, 10 Mar 2009 14:46:07 GMT From: Richard Sandiford To: binutils@sourceware.org Mail-Followup-To: binutils@sourceware.org, richards@transitive.com Subject: [17/21] Suppor garbage collection without an entry point References: Date: Tue, 10 Mar 2009 14:46:00 -0000 In-Reply-To: (Richard Sandiford's message of "Tue\, 10 Mar 2009 13\:58\:06 +0000") Message-ID: User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2009-03/txt/msg00190.txt.bz2 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 : +# Pointer to indirect3. +20000000: 20 00 00 98 .* +20000004: 11 22 33 44 .* + +20000008 <__rtinit>: +#... + +20000068 : +20000068: 10 00 00 08 .* +2000006c: 20 00 00 a4 .* +20000070: 00 00 00 00 .* + +20000074 : +20000074: 10 00 00 00 .* +20000078: 20 00 00 a4 .* +2000007c: 00 00 00 00 .* + +20000080 : +20000080: 10 00 00 0c .* +20000084: 20 00 00 a4 .* +20000088: 00 00 00 00 .* + +2000008c : +2000008c: 10 00 00 04 .* +20000090: 20 00 00 a4 .* +20000094: 00 00 00 00 .* + +20000098 : +20000098: 10 00 00 14 .* +2000009c: 20 00 00 a4 .* +200000a0: 00 00 00 00 .* + +200000a4 : +# TOC entry for indirect1. +200000a4: 20 00 00 80 .* + +200000a8 : +# 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 : +# Pointer to indirect3. + 20000000: 20 00 00 e0 .* + 20000004: 11 22 33 44 .* + +0000000020000008 <__rtinit>: +#... + +0000000020000080 : + 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 : + 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 : + 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 : + 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 : + 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 : + 200000f8: 00 00 00 00 .* + 200000fc: 20 00 00 b0 .* + +0000000020000100 : + 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}}