diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2008-03-16 22:26:23 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2008-03-16 22:26:23 +0000 |
commit | 41bed6dd8a0e8e81d94fa4d1e552ed3b3c7f206f (patch) | |
tree | 4bedfd82ca5af4b5edaf96e2e066f13a2bcc5b48 /bfd/elf64-x86-64.c | |
parent | f01be29bbc6ef5fd011675bd0da09ab1f7aea030 (diff) | |
download | gdb-41bed6dd8a0e8e81d94fa4d1e552ed3b3c7f206f.zip gdb-41bed6dd8a0e8e81d94fa4d1e552ed3b3c7f206f.tar.gz gdb-41bed6dd8a0e8e81d94fa4d1e552ed3b3c7f206f.tar.bz2 |
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.
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r-- | bfd/elf64-x86-64.c | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 3e508e0..71c10a7 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -2595,30 +2595,63 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, 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. */ @@ -3343,6 +3376,8 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_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 |