This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: PR ld/5789 and ld/5943
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: binutils at sources dot redhat dot com
- Date: Sun, 16 Mar 2008 10:02:02 -0700
- Subject: Re: PATCH: PR ld/5789 and ld/5943
- References: <20080315200044.GA30184@lucon.org>
On Sat, Mar 15, 2008 at 01:00:44PM -0700, H.J. Lu wrote:
> This patch fixes 2 bugs, ld/5789 and ld/5943. x86-64 linker shouldn't
> crash on undefined hidden/internal symbols. i386/x86-64 linker
> shouldn't generate incorrect executables/shared libraries with
> undefined hidden/internal symbols.
>
> 2008-03-15 H.J. Lu <hongjiu.lu@intel.com>
>
> PR ld/5789
> PR ld/5943
> * elf32-i386.c (elf_i386_relocate_section): Issue an error
> for R_386_GOTOFF relocaton against undefined hidden/internal
> symbols when building a shared object.
>
> * elf64-x86-64.c (elf64_x86_64_relocate_section): Issue an
> error for R_X86_64_PC8/R_X86_64_PC16/R_X86_64_PC32
> relocaton against undefined hidden/internal symbols when
> building a shared object.
> (elf64_x86_64_finish_dynamic_symbol): Return FALSE when symbol
> is referenced locally, but isn't defined in a regular file.
>
Here is the updated patch with testcases. I will check it if I
don't find any problems with gcc and glibc.
H.J.
----
bfd/
2008-03-16 H.J. Lu <hongjiu.lu@intel.com>
PR ld/5789
PR ld/5943
* elf32-i386.c (elf_i386_relocate_section): Issue an error
for R_386_GOTOFF relocaton against undefined hidden/internal
symbols when building a shared object.
* elf64-x86-64.c (elf64_x86_64_relocate_section): Issue an
error for R_X86_64_PC8/R_X86_64_PC16/R_X86_64_PC32
relocaton against undefined hidden/internal symbols when
building a shared object.
(elf64_x86_64_finish_dynamic_symbol): Return FALSE when symbol
is referenced locally, but isn't defined in a regular file.
ld/testsuite/
2008-03-16 H.J. Lu <hongjiu.lu@intel.com>
PR ld/5789
PR ld/5943
* ld-i386/hidden1.d: New.
* ld-i386/hidden1.s: Likewise.
* ld-i386/hidden2.d: Likewise.
* ld-i386/hidden2.s: Likewise.
* ld-i386/hidden3.d: Likewise.
* ld-i386/hidden4.s: Likewise.
* ld-i386/protected1.d: Likewise.
* ld-i386/protected1.s: Likewise.
* ld-i386/protected2.d: Likewise.
* ld-i386/protected2.s: Likewise.
* ld-i386/protected3.d: Likewise.
* ld-i386/protected3.s: Likewise.
* ld-x86-64/hidden1.d: Likewise.
* ld-x86-64/hidden1.s: Likewise.
* ld-x86-64/hidden2.d: Likewise.
* ld-x86-64/hidden2.s: Likewise.
* ld-x86-64/hidden3.d: Likewise.
* ld-x86-64/hidden3.s: Likewise.
* ld-x86-64/protected1.d: Likewise.
* ld-x86-64/protected1.s: Likewise.
* ld-x86-64/protected2.d: Likewise.
* ld-x86-64/protected2.s: Likewise.
* ld-x86-64/protected3.d: Likewise.
* ld-x86-64/protected3.s: Likewise.
* ld-i386/i386.exp: Run hidden1, hidden2, hidden3, protected1,
protected2 and protected3.
* ld-x86-64/x86-64.exp: Likewise.
--- binutils/bfd/elf32-i386.c.bad 2008-03-15 07:28:10.000000000 -0700
+++ binutils/bfd/elf32-i386.c 2008-03-16 09:54:26.000000000 -0700
@@ -2773,19 +2773,46 @@ elf_i386_relocate_section (bfd *output_b
/* Check to make sure it isn't a protected function symbol
for shared library since it may not be local when used
- as function address. */
- if (info->shared
- && !info->executable
- && h
- && h->def_regular
- && h->type == STT_FUNC
- && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
+ as function address. We also need to make sure that a
+ symbol is defined locally. */
+ if (info->shared && h)
{
- (*_bfd_error_handler)
- (_("%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"),
- input_bfd, h->root.root.string);
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ if (!h->def_regular)
+ {
+ const char *v;
+
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_HIDDEN:
+ v = _("hidden symbol");
+ break;
+ case STV_INTERNAL:
+ v = _("internal symbol");
+ break;
+ case STV_PROTECTED:
+ v = _("protected symbol");
+ break;
+ default:
+ v = _("symbol");
+ break;
+ }
+
+ (*_bfd_error_handler)
+ (_("%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"),
+ input_bfd, v, h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else if (!info->executable
+ && h->type == STT_FUNC
+ && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
+ {
+ (*_bfd_error_handler)
+ (_("%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"),
+ input_bfd, h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
}
/* Note that sgot is not involved in this
--- binutils/bfd/elf64-x86-64.c.bad 2008-03-15 07:28:10.000000000 -0700
+++ binutils/bfd/elf64-x86-64.c 2008-03-16 09:53:21.000000000 -0700
@@ -2615,30 +2615,63 @@ elf64_x86_64_relocate_section (bfd *outp
case R_X86_64_PC16:
case R_X86_64_PC32:
if (info->shared
- && !SYMBOL_REFERENCES_LOCAL (info, h)
&& (input_section->flags & SEC_ALLOC) != 0
&& (input_section->flags & SEC_READONLY) != 0
- && (!h->def_regular
- || r_type != R_X86_64_PC32
- || h->type != STT_FUNC
- || ELF_ST_VISIBILITY (h->other) != STV_PROTECTED
- || !is_32bit_relative_branch (contents,
- rel->r_offset)))
+ && h != NULL)
{
- if (h->def_regular
- && r_type == R_X86_64_PC32
- && h->type == STT_FUNC
- && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
- (*_bfd_error_handler)
- (_("%B: relocation R_X86_64_PC32 against protected function `%s' can not be used when making a shared object"),
- input_bfd, h->root.root.string);
+ bfd_boolean fail = FALSE;
+ bfd_boolean branch
+ = (r_type == R_X86_64_PC32
+ && is_32bit_relative_branch (contents, rel->r_offset));
+
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ /* Symbol is referenced locally. Make sure it is
+ defined locally or for a branch. */
+ fail = !h->def_regular && !branch;
+ }
else
- (*_bfd_error_handler)
- (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
- input_bfd, x86_64_elf_howto_table[r_type].name,
- h->root.root.string);
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ {
+ /* Symbol isn't referenced locally. We only allow
+ branch to symbol with non-default visibility. */
+ fail = (!branch
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT);
+ }
+
+ if (fail)
+ {
+ const char *fmt;
+ const char *v;
+ const char *pic = "";
+
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_HIDDEN:
+ v = _("hidden symbol");
+ break;
+ case STV_INTERNAL:
+ v = _("internal symbol");
+ break;
+ case STV_PROTECTED:
+ v = _("protected symbol");
+ break;
+ default:
+ v = _("symbol");
+ pic = _("; recompile with -fPIC");
+ break;
+ }
+
+ if (h->def_regular)
+ fmt = _("%B: relocation %s against %s `%s' can not be used when making a shared object%s");
+ else
+ fmt = _("%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s");
+
+ (*_bfd_error_handler) (fmt, input_bfd,
+ x86_64_elf_howto_table[r_type].name,
+ v, h->root.root.string, pic);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
}
/* Fall through. */
@@ -3363,6 +3396,8 @@ elf64_x86_64_finish_dynamic_symbol (bfd
if (info->shared
&& SYMBOL_REFERENCES_LOCAL (info, h))
{
+ if (!h->def_regular)
+ return FALSE;
BFD_ASSERT((h->got.offset & 1) != 0);
rela.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
rela.r_addend = (h->root.u.def.value
--- binutils/ld/testsuite/ld-i386/hidden1.d.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/hidden1.d 2008-03-16 09:21:52.000000000 -0700
@@ -0,0 +1,3 @@
+#as: --32
+#ld: -shared -melf_i386
+#error: .*relocation R_386_GOTOFF against undefined hidden symbol `foo' can not be used when making a shared object
--- binutils/ld/testsuite/ld-i386/hidden1.s.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/hidden1.s 2008-03-16 09:15:16.000000000 -0700
@@ -0,0 +1,9 @@
+ .text
+.globl bar
+ .type bar, @function
+bar:
+ leal foo@GOTOFF(%ecx), %eax
+ ret
+ .size bar, .-bar
+ .weak foo
+ .hidden foo
--- binutils/ld/testsuite/ld-i386/hidden2.d.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/hidden2.d 2008-03-16 09:24:45.000000000 -0700
@@ -0,0 +1,13 @@
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -drw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <bar>:
+[ ]*[a-f0-9]+: e8 cf fe ff ff call 0 <bar-0x[a-f0-9]+>
+[ ]*[a-f0-9]+: c3 ret
+#pass
--- binutils/ld/testsuite/ld-i386/hidden2.s.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/hidden2.s 2008-03-16 09:15:28.000000000 -0700
@@ -0,0 +1,9 @@
+ .text
+.globl bar
+ .type bar, @function
+bar:
+ call foo
+ ret
+ .size bar, .-bar
+ .weak foo
+ .hidden foo
--- binutils/ld/testsuite/ld-i386/hidden3.d.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/hidden3.d 2008-03-16 09:22:31.000000000 -0700
@@ -0,0 +1,3 @@
+#as: --32
+#ld: -shared -melf_i386
+#error: .*relocation R_386_GOTOFF against undefined hidden symbol `foo' can not be used when making a shared object
--- binutils/ld/testsuite/ld-i386/hidden3.s.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/hidden3.s 2008-03-16 09:15:44.000000000 -0700
@@ -0,0 +1,8 @@
+ .text
+.globl bar
+ .type bar, @function
+bar:
+ leal foo@GOTOFF(%ecx), %eax
+ ret
+ .size bar, .-bar
+ .hidden foo
--- binutils/ld/testsuite/ld-i386/i386.exp.bad 2007-08-25 07:35:38.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/i386.exp 2008-03-16 09:29:49.000000000 -0700
@@ -132,3 +132,9 @@ run_dump_test "tlsie2"
run_dump_test "tlsie3"
run_dump_test "tlsie4"
run_dump_test "tlsie5"
+run_dump_test "hidden1"
+run_dump_test "hidden2"
+run_dump_test "hidden3"
+run_dump_test "protected1"
+run_dump_test "protected2"
+run_dump_test "protected3"
--- binutils/ld/testsuite/ld-i386/protected1.d.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/protected1.d 2008-03-16 09:25:29.000000000 -0700
@@ -0,0 +1,3 @@
+#as: --32
+#ld: -shared -melf_i386
+#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
--- binutils/ld/testsuite/ld-i386/protected1.s.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/protected1.s 2008-03-16 09:16:13.000000000 -0700
@@ -0,0 +1,13 @@
+ .text
+.globl foo
+ .protected foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ leal foo@GOTOFF(%ecx), %eax
+ ret
+ .size bar, .-bar
--- binutils/ld/testsuite/ld-i386/protected2.d.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/protected2.d 2008-03-16 09:25:50.000000000 -0700
@@ -0,0 +1,16 @@
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -drw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+[a-f0-9]+ <foo>:
+[ ]*[a-f0-9]+: c3 ret
+
+0+[a-f0-9]+ <bar>:
+[ ]*[a-f0-9]+: e8 fa ff ff ff call [a-f0-9]+ <foo>
+[ ]*[a-f0-9]+: c3 ret
+#pass
--- binutils/ld/testsuite/ld-i386/protected2.s.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/protected2.s 2008-03-16 09:16:23.000000000 -0700
@@ -0,0 +1,13 @@
+ .text
+.globl foo
+ .protected foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ call foo
+ ret
+ .size bar, .-bar
--- binutils/ld/testsuite/ld-i386/protected3.d.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/protected3.d 2008-03-16 09:27:44.000000000 -0700
@@ -0,0 +1,13 @@
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -drw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+[a-f0-9]+ <bar>:
+[ ]*[a-f0-9]+: 8b 81 0c 00 00 00 mov 0x[a-f0-9]+\(%ecx\),%eax
+[ ]*[a-f0-9]+: c3 ret
+#pass
--- binutils/ld/testsuite/ld-i386/protected3.s.bad 2008-03-16 09:29:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/protected3.s 2008-03-16 09:23:40.000000000 -0700
@@ -0,0 +1,15 @@
+ .protected foo
+.globl foo
+ .data
+ .align 4
+ .type foo, @object
+ .size foo, 4
+foo:
+ .long 1
+ .text
+.globl bar
+ .type bar, @function
+bar:
+ movl foo@GOTOFF(%ecx), %eax
+ ret
+ .size bar, .-bar
--- binutils/ld/testsuite/ld-x86-64/hidden1.d.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/hidden1.d 2008-03-16 08:30:02.000000000 -0700
@@ -0,0 +1,3 @@
+#as: --64
+#ld: -shared -melf_x86_64
+#error: .*relocation R_X86_64_PC32 against undefined hidden symbol `foo' can not be used when making a shared object
--- binutils/ld/testsuite/ld-x86-64/hidden1.s.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/hidden1.s 2008-03-16 08:26:19.000000000 -0700
@@ -0,0 +1,9 @@
+ .text
+.globl bar
+ .type bar, @function
+bar:
+ leaq foo(%rip), %rax
+ ret
+ .size bar, .-bar
+ .weak foo
+ .hidden foo
--- binutils/ld/testsuite/ld-x86-64/hidden2.d.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/hidden2.d 2008-03-16 08:37:01.000000000 -0700
@@ -0,0 +1,13 @@
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <bar>:
+[ ]*[a-f0-9]+: e8 33 fe ff ff callq 0 <bar-0x[a-f0-9]+>
+[ ]*[a-f0-9]+: c3 retq
+#pass
--- binutils/ld/testsuite/ld-x86-64/hidden2.s.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/hidden2.s 2008-03-16 08:26:28.000000000 -0700
@@ -0,0 +1,9 @@
+ .text
+.globl bar
+ .type bar, @function
+bar:
+ call foo
+ ret
+ .size bar, .-bar
+ .weak foo
+ .hidden foo
--- binutils/ld/testsuite/ld-x86-64/hidden3.d.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/hidden3.d 2008-03-16 08:30:14.000000000 -0700
@@ -0,0 +1,3 @@
+#as: --64
+#ld: -shared -melf_x86_64
+#error: .*relocation R_X86_64_PC32 against undefined hidden symbol `foo' can not be used when making a shared object
--- binutils/ld/testsuite/ld-x86-64/hidden3.s.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/hidden3.s 2008-03-16 08:26:37.000000000 -0700
@@ -0,0 +1,8 @@
+ .text
+.globl bar
+ .type bar, @function
+bar:
+ leaq foo(%rip), %rax
+ ret
+ .size bar, .-bar
+ .hidden foo
--- binutils/ld/testsuite/ld-x86-64/protected1.d.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/protected1.d 2008-03-16 08:38:21.000000000 -0700
@@ -0,0 +1,3 @@
+#as: --64
+#ld: -shared -melf_x86_64
+#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
--- binutils/ld/testsuite/ld-x86-64/protected1.s.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/protected1.s 2008-03-16 08:27:04.000000000 -0700
@@ -0,0 +1,13 @@
+ .text
+.globl foo
+ .protected foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ leaq foo(%rip), %rax
+ ret
+ .size bar, .-bar
--- binutils/ld/testsuite/ld-x86-64/protected2.d.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/protected2.d 2008-03-16 08:40:09.000000000 -0700
@@ -0,0 +1,16 @@
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+[a-f0-9]+ <foo>:
+[ ]*[a-f0-9]+: c3 retq
+
+0+[a-f0-9]+ <bar>:
+[ ]*[a-f0-9]+: e8 fa ff ff ff callq [a-f0-9]+ <foo>
+[ ]*[a-f0-9]+: c3 retq
+#pass
--- binutils/ld/testsuite/ld-x86-64/protected2.s.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/protected2.s 2008-03-16 08:27:15.000000000 -0700
@@ -0,0 +1,13 @@
+ .text
+.globl foo
+ .protected foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ call foo
+ ret
+ .size bar, .-bar
--- binutils/ld/testsuite/ld-x86-64/protected3.d.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/protected3.d 2008-03-16 08:42:03.000000000 -0700
@@ -0,0 +1,13 @@
+#as: --64
+#ld: -shared -melf_x86_64
+#objdump: -drw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+[a-f0-9]+ <bar>:
+[ ]*[a-f0-9]+: 8b 05 ce 00 20 00 mov 0x[a-f0-9]+\(%rip\),%eax # [a-f0-9]+ <foo>
+[ ]*[a-f0-9]+: c3 retq
+#pass
--- binutils/ld/testsuite/ld-x86-64/protected3.s.bad 2008-03-16 08:42:41.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/protected3.s 2008-03-16 08:27:29.000000000 -0700
@@ -0,0 +1,15 @@
+ .protected foo
+.globl foo
+ .data
+ .align 4
+ .type foo, @object
+ .size foo, 4
+foo:
+ .long 1
+ .text
+.globl bar
+ .type bar, @function
+bar:
+ movl foo(%rip), %eax
+ ret
+ .size bar, .-bar
--- binutils/ld/testsuite/ld-x86-64/x86-64.exp.bad 2007-08-25 07:35:38.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/x86-64.exp 2008-03-16 09:30:07.000000000 -0700
@@ -86,3 +86,9 @@ run_dump_test "tlsgd2"
run_dump_test "tlsgd3"
run_dump_test "tlsie2"
run_dump_test "tlsie3"
+run_dump_test "hidden1"
+run_dump_test "hidden2"
+run_dump_test "hidden3"
+run_dump_test "protected1"
+run_dump_test "protected2"
+run_dump_test "protected3"