This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] VAX/BFD: Omit PLT slots for local symbols
- From: "Maciej W. Rozycki" <macro at linux-mips dot org>
- To: binutils at sourceware dot org
- Date: Tue, 8 May 2012 00:30:15 +0100 (BST)
- Subject: [PATCH] VAX/BFD: Omit PLT slots for local symbols
Hi,
The change below fixes a problem with the creation of the PLT on the VAX
target, where entries are made where they should not for local symbols,
leading to unneeded or even empty slots. The conditions for the latters
are a bit obscure, for such a slot to be created a dynamic symbol has to
be preempted in the link with a static hidden symbol referred to by a PLT
relocation (i.e. from a PIC relocatable). This is covered by the test
case provided. Executables with empty PLT slots are invalid and rejected
by the dynamic linker.
There is some code duplication in the area affected, so I have merged the
two pieces (that deal with local and garbage-collected symbols,
respectively) into one, similarly to how some other targets do it. Also
the attempt to make a symbol whose h->dynindx is -1 dynamic is incorrect
here -- such symbols will have qualified as local in SYMBOL_CALLS_LOCAL
and shouldn't be produced.
No regressions with this change. OK to apply?
2012-05-08 Maciej W. Rozycki <macro@linux-mips.org>
bfd/
* elf32-vax.c (elf_vax_adjust_dynamic_symbol): Don't allocate
PLT slots for local symbols.
ld/testsuite/
* ld-vax-elf/plt-local-lib.dd: New test.
* ld-vax-elf/plt-local-lib.ld: New test linker script.
* ld-vax-elf/plt-local-lib.s: New test source.
* ld-vax-elf/plt-local.dd: New test.
* ld-vax-elf/plt-local.ld:New test linker script.
* ld-vax-elf/plt-local.s: New test source.
* ld-vax-elf/plt-local-hidden-pic.s: New test source.
* ld-vax-elf/plt-local-rehidden-pic.s: New test source.
* ld-vax-elf/vax-elf.exp: New test script.
Maciej
binutils-vax-plt-local.patch
Index: binutils/bfd/elf32-vax.c
===================================================================
--- binutils.orig/bfd/elf32-vax.c
+++ binutils/bfd/elf32-vax.c
@@ -934,39 +934,21 @@ elf_vax_adjust_dynamic_symbol (info, h)
if (h->type == STT_FUNC
|| h->needs_plt)
{
- if (! info->shared
- && !h->def_dynamic
- && !h->ref_dynamic
- /* We must always create the plt entry if it was referenced
- by a PLTxxO relocation. In this case we already recorded
- it as a dynamic symbol. */
- && h->dynindx == -1)
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
{
/* This case can occur if we saw a PLTxx reloc in an input
file, but the symbol was never referred to by a dynamic
- object. In such a case, we don't actually need to build
- a procedure linkage table, and we can just do a PCxx
- reloc instead. */
- BFD_ASSERT (h->needs_plt);
+ object, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PCxx reloc instead. */
h->plt.offset = (bfd_vma) -1;
- return TRUE;
- }
-
- /* GC may have rendered this entry unused. */
- if (h->plt.refcount <= 0)
- {
h->needs_plt = 0;
- h->plt.offset = (bfd_vma) -1;
return TRUE;
}
- /* Make sure this symbol is output as a dynamic symbol. */
- if (h->dynindx == -1)
- {
- if (! bfd_elf_link_record_dynamic_symbol (info, h))
- return FALSE;
- }
-
s = bfd_get_section_by_name (dynobj, ".plt");
BFD_ASSERT (s != NULL);
Index: binutils/ld/testsuite/ld-vax-elf/plt-local-hidden-pic.s
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-vax-elf/plt-local-hidden-pic.s
@@ -0,0 +1,14 @@
+ .text
+
+ .hidden foo_hidden
+ .globl foo_hidden
+ .type foo_hidden, @function
+foo_hidden:
+ .word 0
+ calls $0, foo_extern
+ calls $0, foo_global
+ calls $0, foo_local
+ calls $0, foo_hidden
+ calls $0, foo_rehidden
+ ret
+ .size foo_hidden, . - foo_hidden
Index: binutils/ld/testsuite/ld-vax-elf/plt-local-lib.dd
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-vax-elf/plt-local-lib.dd
@@ -0,0 +1,91 @@
+.*: +file format .*vax.*
+
+Disassembly of section \.plt:
+
+00001000 <foo_local@plt-0xc>:
+ 1000: dd ef 76 20 pushl 307c <_GLOBAL_OFFSET_TABLE_\+0x4>
+ 1004: 00 00
+ 1006: 17 ff 74 20 jmp \*3080 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ 100a: 00 00
+
+0000100c <foo_local@plt>:
+ 100c: fc 0f \.word 0x0ffc # Entry mask: < r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 >
+ 100e: 16 ef ec ff jsb 1000 <foo_local@plt-0xc>
+ 1012: ff ff
+ 1014: 00 00 00 00 \.long 0x00000000
+
+00001018 <foo_extern@plt>:
+ 1018: fc 0f \.word 0x0ffc # Entry mask: < r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 >
+ 101a: 16 ef e0 ff jsb 1000 <foo_local@plt-0xc>
+ 101e: ff ff
+ 1020: 0c 00 00 00 \.long 0x0000000c
+
+00001024 <foo_rehidden@plt>:
+ 1024: fc 0f \.word 0x0ffc # Entry mask: < r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 >
+ 1026: 16 ef d4 ff jsb 1000 <foo_local@plt-0xc>
+ 102a: ff ff
+ 102c: 18 00 00 00 \.long 0x00000018
+
+00001030 <foo_global@plt>:
+ 1030: fc 0f \.word 0x0ffc # Entry mask: < r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 >
+ 1032: 16 ef c8 ff jsb 1000 <foo_local@plt-0xc>
+ 1036: ff ff
+ 1038: 24 00 00 00 \.long 0x00000024
+
+Disassembly of section \.text:
+
+00002000 <foo_extern>:
+ 2000: 00 00 \.word 0x0000 # Entry mask: < >
+ 2002: fb 00 ff 7f calls \$0x0,\*3088 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ 2006: 10 00 00
+ 2009: fb 00 ff 80 calls \$0x0,\*3090 <_GLOBAL_OFFSET_TABLE_\+0x18>
+ 200d: 10 00 00
+ 2010: fb 00 ff 6d calls \$0x0,\*3084 <_GLOBAL_OFFSET_TABLE_\+0xc>
+ 2014: 10 00 00
+ 2017: fb 00 ef 2e calls \$0x0,204c <foo_hidden>
+ 201b: 00 00 00
+ 201e: fb 00 ff 67 calls \$0x0,\*308c <_GLOBAL_OFFSET_TABLE_\+0x14>
+ 2022: 10 00 00
+ 2025: 04 ret
+
+00002026 <foo_local>:
+ 2026: 00 00 \.word 0x0000 # Entry mask: < >
+ 2028: fb 00 ff 59 calls \$0x0,\*3088 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ 202c: 10 00 00
+ 202f: fb 00 ff 5a calls \$0x0,\*3090 <_GLOBAL_OFFSET_TABLE_\+0x18>
+ 2033: 10 00 00
+ 2036: fb 00 ff 47 calls \$0x0,\*3084 <_GLOBAL_OFFSET_TABLE_\+0xc>
+ 203a: 10 00 00
+ 203d: fb 00 ef 08 calls \$0x0,204c <foo_hidden>
+ 2041: 00 00 00
+ 2044: fb 00 ff 41 calls \$0x0,\*308c <_GLOBAL_OFFSET_TABLE_\+0x14>
+ 2048: 10 00 00
+ 204b: 04 ret
+
+0000204c <foo_hidden>:
+ 204c: 00 00 \.word 0x0000 # Entry mask: < >
+ 204e: fb 00 ff 33 calls \$0x0,\*3088 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ 2052: 10 00 00
+ 2055: fb 00 ff 34 calls \$0x0,\*3090 <_GLOBAL_OFFSET_TABLE_\+0x18>
+ 2059: 10 00 00
+ 205c: fb 00 ff 21 calls \$0x0,\*3084 <_GLOBAL_OFFSET_TABLE_\+0xc>
+ 2060: 10 00 00
+ 2063: fb 00 ef e2 calls \$0x0,204c <foo_hidden>
+ 2067: ff ff ff
+ 206a: fb 00 ff 1b calls \$0x0,\*308c <_GLOBAL_OFFSET_TABLE_\+0x14>
+ 206e: 10 00 00
+ 2071: 04 ret
+
+00002072 <foo_rehidden>:
+ 2072: 00 00 \.word 0x0000 # Entry mask: < >
+ 2074: fb 00 ff 0d calls \$0x0,\*3088 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ 2078: 10 00 00
+ 207b: fb 00 ff 0e calls \$0x0,\*3090 <_GLOBAL_OFFSET_TABLE_\+0x18>
+ 207f: 10 00 00
+ 2082: fb 00 ff fb calls \$0x0,\*3084 <_GLOBAL_OFFSET_TABLE_\+0xc>
+ 2086: 0f 00 00
+ 2089: fb 00 ef bc calls \$0x0,204c <foo_hidden>
+ 208d: ff ff ff
+ 2090: fb 00 ff f5 calls \$0x0,\*308c <_GLOBAL_OFFSET_TABLE_\+0x14>
+ 2094: 0f 00 00
+ 2097: 04 ret
Index: binutils/ld/testsuite/ld-vax-elf/plt-local-lib.ld
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-vax-elf/plt-local-lib.ld
@@ -0,0 +1,18 @@
+SECTIONS
+{
+ . = 0;
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rela.plt : { *(.rela.plt) }
+
+ . = 0x1000;
+ .plt : { *(.plt) }
+
+ . = 0x2000;
+ .text : { *(.text) }
+
+ . = 0x3000;
+ .dynamic : { *(.dynamic) }
+ .got : { *(.got.plt) }
+}
Index: binutils/ld/testsuite/ld-vax-elf/plt-local-lib.s
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-vax-elf/plt-local-lib.s
@@ -0,0 +1,50 @@
+ .text
+
+ .globl foo_extern
+ .type foo_extern, @function
+foo_extern:
+ .word 0
+ calls $0, foo_extern
+ calls $0, foo_global
+ calls $0, foo_local
+ calls $0, foo_hidden
+ calls $0, foo_rehidden
+ ret
+ .size foo_extern, . - foo_extern
+
+ .globl foo_local
+ .type foo_local, @function
+foo_local:
+ .word 0
+ calls $0, foo_extern
+ calls $0, foo_global
+ calls $0, foo_local
+ calls $0, foo_hidden
+ calls $0, foo_rehidden
+ ret
+ .size foo_local, . - foo_local
+
+ .hidden foo_hidden
+ .globl foo_hidden
+ .type foo_hidden, @function
+foo_hidden:
+ .word 0
+ calls $0, foo_extern
+ calls $0, foo_global
+ calls $0, foo_local
+ calls $0, foo_hidden
+ calls $0, foo_rehidden
+ ret
+ .size foo_hidden, . - foo_hidden
+
+ .globl foo_rehidden
+ .type foo_rehidden, @function
+foo_rehidden:
+ .word 0
+ calls $0, foo_extern
+ calls $0, foo_global
+ calls $0, foo_local
+ calls $0, foo_hidden
+ calls $0, foo_rehidden
+ ret
+ .size foo_rehidden, . - foo_rehidden
Index: binutils/ld/testsuite/ld-vax-elf/plt-local-rehidden-pic.s
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-vax-elf/plt-local-rehidden-pic.s
@@ -0,0 +1,14 @@
+ .text
+
+ .hidden foo_rehidden
+ .globl foo_rehidden
+ .type foo_rehidden, @function
+foo_rehidden:
+ .word 0
+ calls $0, foo_extern
+ calls $0, foo_global
+ calls $0, foo_local
+ calls $0, foo_hidden
+ calls $0, foo_rehidden
+ ret
+ .size foo_rehidden, . - foo_rehidden
Index: binutils/ld/testsuite/ld-vax-elf/plt-local.dd
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-vax-elf/plt-local.dd
@@ -0,0 +1,73 @@
+.*: +file format .*vax.*
+
+Disassembly of section \.plt:
+
+00001000 <foo_extern@plt-0xc>:
+ 1000: dd ef 86 20 pushl 308c <_GLOBAL_OFFSET_TABLE_\+0x4>
+ 1004: 00 00
+ 1006: 17 ff 84 20 jmp \*3090 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ 100a: 00 00
+
+0000100c <foo_extern@plt>:
+ 100c: fc 0f \.word 0x0ffc # Entry mask: < r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 >
+ 100e: 16 ef ec ff jsb 1000 <foo_extern@plt-0xc>
+ 1012: ff ff
+ 1014: 00 00 00 00 \.long 0x00000000
+
+Disassembly of section \.text:
+
+00002000 <foo_hidden>:
+ 2000: 00 00 \.word 0x0000 # Entry mask: < >
+ 2002: fb 00 ff 8b calls \$0x0,\*3094 <_GLOBAL_OFFSET_TABLE_\+0xc>
+ 2006: 10 00 00
+ 2009: fb 00 ef 3c calls \$0x0,204c <foo_global>
+ 200d: 00 00 00
+ 2010: fb 00 ef 5b calls \$0x0,2072 <foo_local>
+ 2014: 00 00 00
+ 2017: fb 00 ef e2 calls \$0x0,2000 <foo_hidden>
+ 201b: ff ff ff
+ 201e: fb 00 ef 01 calls \$0x0,2026 <foo_rehidden>
+ 2022: 00 00 00
+ 2025: 04 ret
+
+00002026 <foo_rehidden>:
+ 2026: 00 00 \.word 0x0000 # Entry mask: < >
+ 2028: fb 00 ff 65 calls \$0x0,\*3094 <_GLOBAL_OFFSET_TABLE_\+0xc>
+ 202c: 10 00 00
+ 202f: fb 00 ef 16 calls \$0x0,204c <foo_global>
+ 2033: 00 00 00
+ 2036: fb 00 ef 35 calls \$0x0,2072 <foo_local>
+ 203a: 00 00 00
+ 203d: fb 00 ef bc calls \$0x0,2000 <foo_hidden>
+ 2041: ff ff ff
+ 2044: fb 00 ef db calls \$0x0,2026 <foo_rehidden>
+ 2048: ff ff ff
+ 204b: 04 ret
+
+0000204c <foo_global>:
+ 204c: 00 00 \.word 0x0000 # Entry mask: < >
+ 204e: fb 00 ff 3f calls \$0x0,\*3094 <_GLOBAL_OFFSET_TABLE_\+0xc>
+ 2052: 10 00 00
+ 2055: fb 00 ef f0 calls \$0x0,204c <foo_global>
+ 2059: ff ff ff
+ 205c: fb 00 ef 0f calls \$0x0,2072 <foo_local>
+ 2060: 00 00 00
+ 2063: fb 00 ef 96 calls \$0x0,2000 <foo_hidden>
+ 2067: ff ff ff
+ 206a: fb 00 ef b5 calls \$0x0,2026 <foo_rehidden>
+ 206e: ff ff ff
+ 2071: 04 ret
+
+00002072 <foo_local>:
+ 2072: 00 00 \.word 0x0000 # Entry mask: < >
+ 2074: fb 00 ff 19 calls \$0x0,\*3094 <_GLOBAL_OFFSET_TABLE_\+0xc>
+ 2078: 10 00 00
+ 207b: fb 00 ef ca calls \$0x0,204c <foo_global>
+ 207f: ff ff ff
+ 2082: fb 00 ef e9 calls \$0x0,2072 <foo_local>
+ 2086: ff ff ff
+ 2089: fb 00 ef 70 calls \$0x0,2000 <foo_hidden>
+ 208d: ff ff ff
+ 2090: fb 00 ef 8f calls \$0x0,2026 <foo_rehidden>
+ 2094: ff ff ff
+ 2097: 04 ret
Index: binutils/ld/testsuite/ld-vax-elf/plt-local.ld
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-vax-elf/plt-local.ld
@@ -0,0 +1,34 @@
+ENTRY (foo_global)
+SECTIONS
+{
+ . = 0;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .rela.plt : { *(.rela.plt) }
+
+ . = 0x1000;
+ .plt : { *(.plt) }
+
+ . = 0x2000;
+ .text : { *(.text) }
+
+ . = 0x3000;
+ .dynamic : { *(.dynamic) }
+ .got : { *(.got.plt) }
+};
+VERSION
+{
+ {
+ global:
+ foo_extern;
+ foo_global;
+ foo_hidden;
+ foo_rehidden;
+ local:
+ foo_local;
+ };
+}
Index: binutils/ld/testsuite/ld-vax-elf/plt-local.s
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-vax-elf/plt-local.s
@@ -0,0 +1,25 @@
+ .text
+
+ .globl foo_global
+ .type foo_global, @function
+foo_global:
+ .word 0
+ calls $0, foo_extern
+ calls $0, foo_global
+ calls $0, foo_local
+ calls $0, foo_hidden
+ calls $0, foo_rehidden
+ ret
+ .size foo_global, . - foo_global
+
+ .globl foo_local
+ .type foo_local, @function
+foo_local:
+ .word 0
+ calls $0, foo_extern
+ calls $0, foo_global
+ calls $0, foo_local
+ calls $0, foo_hidden
+ calls $0, foo_rehidden
+ ret
+ .size foo_local, . - foo_local
Index: binutils/ld/testsuite/ld-vax-elf/vax-elf.exp
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-vax-elf/vax-elf.exp
@@ -0,0 +1,50 @@
+# Expect script for VAX ELF linker tests
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+if { ![istarget vax-*-*] || ![is_elf_format] } {
+ return
+}
+
+run_ld_link_tests [list \
+ [list "PLT test (shared library)" \
+ "-shared -T plt-local-lib.ld" \
+ "-k" \
+ { plt-local-lib.s } \
+ { { objdump -d plt-local-lib.dd } } \
+ "plt-local-lib.so"] \
+ [list "PLT test (object 1)" \
+ "-r" \
+ "-k" \
+ { plt-local-hidden-pic.s } \
+ {} \
+ "plt-local-hidden-pic-r.o"] \
+ [list "PLT test (object 2)" \
+ "-r" \
+ "-k" \
+ { plt-local-rehidden-pic.s } \
+ {} \
+ "plt-local-rehidden-pic-r.o"] \
+ [list "PLT test (executable)" \
+ "-T plt-local.ld tmpdir/plt-local-hidden-pic-r.o tmpdir/plt-local-rehidden-pic-r.o tmpdir/plt-local-lib.so" \
+ "" \
+ { plt-local.s } \
+ { { objdump -d plt-local.dd } } \
+ "plt-local"]]