diff options
author | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2018-07-21 15:00:40 +0200 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2018-07-21 15:00:40 +0200 |
commit | 2376f038d10f901d3e1a2777407f350e4e54d284 (patch) | |
tree | 7d80c2fc6aa6cfda5fdb5db70403420070de27d1 /bfd | |
parent | 0ee6c332f36222a73abee41bc5168bacf78c9189 (diff) | |
download | gdb-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')
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elf32-arm.c | 66 |
2 files changed, 45 insertions, 28 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 645a2ef..5b79a25 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2018-07-21 Eric Botcazou <ebotcazou@adacore.com> + + * 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. + 2018-07-20 H.J. Lu <hongjiu.lu@intel.com> PR ld/23428 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; } |