This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
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: Sat, 15 Mar 2008 13:00:44 -0700
- Subject: PATCH: PR ld/5789 and ld/5943
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.
--- bfd/elf32-i386.c.bad 2008-03-15 07:28:10.000000000 -0700
+++ bfd/elf32-i386.c 2008-03-15 12:09:25.000000000 -0700
@@ -2773,19 +2773,39 @@ 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)
- {
- (*_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;
+ as function address. We also need to make sure that a
+ local symbol is defined. */
+ if (info->shared && h)
+ {
+ if (!info->executable
+ && h->def_regular
+ && 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;
+ }
+ else if (!h->def_regular
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ const char *v;
+
+ if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL)
+ v = "internal";
+ else if (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
+ v = "hidden";
+ else
+ abort ();
+
+ (*_bfd_error_handler)
+ (_("%B: relocation R_386_GOTOFF against undefined %s symbol `%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;
+ }
}
/* Note that sgot is not involved in this
--- bfd/elf64-x86-64.c.bad 2008-03-15 07:28:10.000000000 -0700
+++ bfd/elf64-x86-64.c 2008-03-15 12:13:02.000000000 -0700
@@ -2615,9 +2615,9 @@ 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 != NULL
&& (!h->def_regular
|| r_type != R_X86_64_PC32
|| h->type != STT_FUNC
@@ -2625,20 +2625,47 @@ elf64_x86_64_relocate_section (bfd *outp
|| !is_32bit_relative_branch (contents,
rel->r_offset)))
{
- if (h->def_regular
+ bfd_boolean local = SYMBOL_REFERENCES_LOCAL (info, h);
+
+ if (!local
+ && 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);
- 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;
+ {
+ (*_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_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else if (!local && h->def_regular)
+ {
+ (*_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;
+ }
+ else if (local && !h->def_regular)
+ {
+ const char *v;
+
+ if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL)
+ v = "internal";
+ else if (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
+ v = "hidden";
+ else
+ abort ();
+
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against undefined %s symbol `%s' can not be used when making a shared object"),
+ input_bfd, x86_64_elf_howto_table[r_type].name,
+ v, h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
}
/* Fall through. */
@@ -3363,6 +3390,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