aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-arm.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@gcc.gnu.org>2018-07-21 15:00:40 +0200
committerEric Botcazou <ebotcazou@gcc.gnu.org>2018-07-21 15:00:40 +0200
commit2376f038d10f901d3e1a2777407f350e4e54d284 (patch)
tree7d80c2fc6aa6cfda5fdb5db70403420070de27d1 /bfd/elf32-arm.c
parent0ee6c332f36222a73abee41bc5168bacf78c9189 (diff)
downloadgdb-2376f038d10f901d3e1a2777407f350e4e54d284.zip
gdb-2376f038d10f901d3e1a2777407f350e4e54d284.tar.gz
gdb-2376f038d10f901d3e1a2777407f350e4e54d284.tar.bz2
Initialize GOT slot for local symbol in non-PIC link.
On ARM/VxWorks 7, the R_ARM_TARGET2 relocation used for exception handling is R_ARM_GOT_PREL; moreover in Ada you can define local exceptions. In this case, you may end up with a GOT relocation against a local symbol in a non-PIC link and the ARM linker leaves the GOT slot uninitialized, unlike for example the i386 or the SPARC linkers in the same situation. bfd/ * elf32-arm.c (elf32_arm_final_link_relocate) <R_ARM_GOT32>: Small cleanup for the case of a global symbol that binds locally. Also install a value in the GOT slot in the case of a local symbol in a non-PIC link.
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r--bfd/elf32-arm.c66
1 files changed, 38 insertions, 28 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 9c61181..c5077a5 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -11502,37 +11502,39 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak))
outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
- else if (globals->fdpic_p)
- isrofixup = 1;
else
- outrel.r_info = 0;
+ {
+ outrel.r_info = 0;
+ if (globals->fdpic_p)
+ isrofixup = 1;
+ }
outrel.r_addend = dynreloc_value;
}
/* The GOT entry is initialized to zero by default.
See if we should install a different value. */
if (outrel.r_addend != 0
- && (outrel.r_info == 0 || globals->use_rel || isrofixup))
+ && (globals->use_rel || outrel.r_info == 0))
{
bfd_put_32 (output_bfd, outrel.r_addend,
sgot->contents + off);
outrel.r_addend = 0;
}
- if (outrel.r_info != 0 && !isrofixup)
+ if (isrofixup)
+ arm_elf_add_rofixup (output_bfd,
+ elf32_arm_hash_table(info)->srofixup,
+ sgot->output_section->vma
+ + sgot->output_offset + off);
+
+ else if (outrel.r_info != 0)
{
outrel.r_offset = (sgot->output_section->vma
+ sgot->output_offset
+ off);
elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
}
- else if (isrofixup)
- {
- arm_elf_add_rofixup(output_bfd,
- elf32_arm_hash_table(info)->srofixup,
- sgot->output_section->vma
- + sgot->output_offset + off);
- }
+
h->got.offset |= 1;
}
value = sgot->output_offset + off;
@@ -11553,31 +11555,39 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
off &= ~1;
else
{
- if (globals->use_rel)
- bfd_put_32 (output_bfd, dynreloc_value, sgot->contents + off);
+ Elf_Internal_Rela outrel;
+ int isrofixup = 0;
- if (bfd_link_pic (info) || dynreloc_st_type == STT_GNU_IFUNC)
+ if (dynreloc_st_type == STT_GNU_IFUNC)
+ outrel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
+ else if (bfd_link_pic (info))
+ outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+ else
{
- Elf_Internal_Rela outrel;
+ outrel.r_info = 0;
+ if (globals->fdpic_p)
+ isrofixup = 1;
+ }
+
+ /* The GOT entry is initialized to zero by default.
+ See if we should install a different value. */
+ if (globals->use_rel || outrel.r_info == 0)
+ bfd_put_32 (output_bfd, dynreloc_value, sgot->contents + off);
+
+ if (isrofixup)
+ arm_elf_add_rofixup (output_bfd,
+ globals->srofixup,
+ sgot->output_section->vma
+ + sgot->output_offset + off);
+ else if (outrel.r_info != 0)
+ {
outrel.r_addend = addend + dynreloc_value;
outrel.r_offset = (sgot->output_section->vma
+ sgot->output_offset
+ off);
- if (dynreloc_st_type == STT_GNU_IFUNC)
- outrel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
- else
- outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
}
- else if (globals->fdpic_p)
- {
- /* For FDPIC executables, we use rofixup to fix
- address at runtime. */
- arm_elf_add_rofixup(output_bfd, globals->srofixup,
- sgot->output_section->vma + sgot->output_offset
- + off);
- }
local_got_offsets[r_symndx] |= 1;
}