aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2009-08-10 15:56:30 +0000
committerNathan Sidwell <nathan@codesourcery.com>2009-08-10 15:56:30 +0000
commitffcb4889e2287ae39a7ff8eeaeb061fe968f1cc5 (patch)
tree7c11ccf10be2e2f1f60d93f25dc37380aa8edd3f
parent7f6fed8735705879ad514beb15101d2b990047dd (diff)
downloadfsf-binutils-gdb-ffcb4889e2287ae39a7ff8eeaeb061fe968f1cc5.zip
fsf-binutils-gdb-ffcb4889e2287ae39a7ff8eeaeb061fe968f1cc5.tar.gz
fsf-binutils-gdb-ffcb4889e2287ae39a7ff8eeaeb061fe968f1cc5.tar.bz2
* elf32-arm.c (elf32_arm_size_stubs): Don't die on undefined local
symbols. (elf32_arm_final_link_relocate): Treat local undefined symbols the same as global undefined symbols. (elf32_arm_relocate_section): Give an error for local undefined non-weak symbols, unless the reloc will not use the symbol.
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf32-arm.c35
2 files changed, 40 insertions, 4 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b2a331c..779768c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,14 @@
2009-08-10 Nathan Sidwell <nathan@codesourcery.com>
+ * elf32-arm.c (elf32_arm_size_stubs): Don't die on undefined local
+ symbols.
+ (elf32_arm_final_link_relocate): Treat local undefined symbols the
+ same as global undefined symbols.
+ (elf32_arm_relocate_section): Give an error for local undefined
+ non-weak symbols, unless the reloc will not use the symbol.
+
+2009-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
* elf32-ppc.c (shared_stub_entry, stub_entry): Use r12, not r11.
(ppc_elf_relax_section): Use symbol index to distinguish
relocatable stubs.
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index fbb4454..49c80ad 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -4376,6 +4376,11 @@ elf32_arm_size_stubs (bfd *output_bfd,
sym = local_syms + r_indx;
hdr = elf_elfsections (input_bfd)[sym->st_shndx];
sym_sec = hdr->bfd_section;
+ if (!sym_sec)
+ /* This is an undefined symbol. It can never
+ be resolved. */
+ continue;
+
if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
sym_value = sym->st_value;
destination = (sym_value + irela->r_addend
@@ -6961,7 +6966,6 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
case R_ARM_PC24: /* Arm B/BL instruction. */
case R_ARM_PLT32:
{
- bfd_vma from;
bfd_signed_vma branch_offset;
struct elf32_arm_stub_hash_entry *stub_entry = NULL;
@@ -6998,6 +7002,8 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|| r_type == R_ARM_JUMP24
|| r_type == R_ARM_PLT32)
{
+ bfd_vma from;
+
/* If the call goes through a PLT entry, make sure to
check distance to the right destination address. */
if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
@@ -7066,9 +7072,11 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
signed_addend >>= howto->rightshift;
/* A branch to an undefined weak symbol is turned into a jump to
- the next instruction unless a PLT entry will be created. */
- if (h && h->root.type == bfd_link_hash_undefweak
- && !(splt != NULL && h->plt.offset != (bfd_vma) -1))
+ the next instruction unless a PLT entry will be created.
+ Do the same for local undefined symbols. */
+ if (h ? (h->root.type == bfd_link_hash_undefweak
+ && !(splt != NULL && h->plt.offset != (bfd_vma) -1))
+ : bfd_is_und_section (sym_sec))
{
value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000)
| 0x0affffff;
@@ -8714,6 +8722,25 @@ elf32_arm_relocate_section (bfd * output_bfd,
sym = local_syms + r_symndx;
sym_type = ELF32_ST_TYPE (sym->st_info);
sec = local_sections[r_symndx];
+
+ /* An object file might have a reference to a local
+ undefined symbol. This is a daft object file, but we
+ should at least do something about it. V4BX & NONE
+ relocations do not use the symbol and are explicitly
+ allowed to use the undefined symbol, so allow those. */
+ if (r_type != R_ARM_V4BX
+ && r_type != R_ARM_NONE
+ && bfd_is_und_section (sec)
+ && ELF_ST_BIND (sym->st_info) != STB_WEAK)
+ {
+ if (!info->callbacks->undefined_symbol
+ (info, bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name),
+ input_bfd, input_section,
+ rel->r_offset, TRUE))
+ return FALSE;
+ }
+
if (globals->use_rel)
{
relocation = (sec->output_section->vma