diff options
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r-- | bfd/elf32-arm.c | 291 |
1 files changed, 7 insertions, 284 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index c913f2b..b5d1866 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -25,7 +25,6 @@ #include "libiberty.h" #include "libbfd.h" #include "elf-bfd.h" -#include "elf-nacl.h" #include "elf-vxworks.h" #include "elf/arm.h" #include "elf32-arm.h" @@ -2497,45 +2496,6 @@ static const bfd_vma elf32_arm_plt_thumb_stub [] = 0xe7fd /* b .-2 */ }; -/* The first entry in a procedure linkage table looks like - this. It is set up so that any shared library function that is - called before the relocation has been set up calls the dynamic - linker first. */ -static const bfd_vma elf32_arm_nacl_plt0_entry [] = -{ - /* First bundle: */ - 0xe300c000, /* movw ip, #:lower16:&GOT[2]-.+8 */ - 0xe340c000, /* movt ip, #:upper16:&GOT[2]-.+8 */ - 0xe08cc00f, /* add ip, ip, pc */ - 0xe52dc008, /* str ip, [sp, #-8]! */ - /* Second bundle: */ - 0xe3ccc103, /* bic ip, ip, #0xc0000000 */ - 0xe59cc000, /* ldr ip, [ip] */ - 0xe3ccc13f, /* bic ip, ip, #0xc000000f */ - 0xe12fff1c, /* bx ip */ - /* Third bundle: */ - 0xe320f000, /* nop */ - 0xe320f000, /* nop */ - 0xe320f000, /* nop */ - /* .Lplt_tail: */ - 0xe50dc004, /* str ip, [sp, #-4] */ - /* Fourth bundle: */ - 0xe3ccc103, /* bic ip, ip, #0xc0000000 */ - 0xe59cc000, /* ldr ip, [ip] */ - 0xe3ccc13f, /* bic ip, ip, #0xc000000f */ - 0xe12fff1c, /* bx ip */ -}; -#define ARM_NACL_PLT_TAIL_OFFSET (11 * 4) - -/* Subsequent entries in a procedure linkage table look like this. */ -static const bfd_vma elf32_arm_nacl_plt_entry [] = -{ - 0xe300c000, /* movw ip, #:lower16:&GOT[n]-.+8 */ - 0xe340c000, /* movt ip, #:upper16:&GOT[n]-.+8 */ - 0xe08cc00f, /* add ip, ip, pc */ - 0xea000000, /* b .Lplt_tail */ -}; - /* PR 28924: There was a bug due to too high values of THM_MAX_FWD_BRANCH_OFFSET and THM2_MAX_FWD_BRANCH_OFFSET. The first macro concerns the case when Thumb-2 @@ -2749,32 +2709,6 @@ static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_tls_pic[] = DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X) */ }; -/* NaCl ARM -> ARM long branch stub. */ -static const insn_sequence elf32_arm_stub_long_branch_arm_nacl[] = -{ - ARM_INSN (0xe59fc00c), /* ldr ip, [pc, #12] */ - ARM_INSN (0xe3ccc13f), /* bic ip, ip, #0xc000000f */ - ARM_INSN (0xe12fff1c), /* bx ip */ - ARM_INSN (0xe320f000), /* nop */ - ARM_INSN (0xe125be70), /* bkpt 0x5be0 */ - DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ - DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */ - DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */ -}; - -/* NaCl ARM -> ARM long branch stub, PIC. */ -static const insn_sequence elf32_arm_stub_long_branch_arm_nacl_pic[] = -{ - ARM_INSN (0xe59fc00c), /* ldr ip, [pc, #12] */ - ARM_INSN (0xe08cc00f), /* add ip, ip, pc */ - ARM_INSN (0xe3ccc13f), /* bic ip, ip, #0xc000000f */ - ARM_INSN (0xe12fff1c), /* bx ip */ - ARM_INSN (0xe125be70), /* bkpt 0x5be0 */ - DATA_WORD (0, R_ARM_REL32, 8), /* dcd R_ARM_REL32(X+8) */ - DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */ - DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */ -}; - /* Stub used for transition to secure state (aka SG veneer). */ static const insn_sequence elf32_arm_stub_cmse_branch_thumb_only[] = { @@ -2859,8 +2793,6 @@ static const insn_sequence elf32_arm_stub_a8_veneer_blx[] = DEF_STUB (long_branch_thumb_only_pic) \ DEF_STUB (long_branch_any_tls_pic) \ DEF_STUB (long_branch_v4t_thumb_tls_pic) \ - DEF_STUB (long_branch_arm_nacl) \ - DEF_STUB (long_branch_arm_nacl_pic) \ DEF_STUB (cmse_branch_thumb_only) \ DEF_STUB (a8_veneer_b_cond) \ DEF_STUB (a8_veneer_b) \ @@ -4524,13 +4456,9 @@ arm_type_of_stub (struct bfd_link_info *info, ? (r_type == R_ARM_TLS_CALL /* TLS PIC Stub. */ ? arm_stub_long_branch_any_tls_pic - : (globals->root.target_os == is_nacl - ? arm_stub_long_branch_arm_nacl_pic - : arm_stub_long_branch_any_arm_pic)) + : arm_stub_long_branch_any_arm_pic) /* non-PIC stubs. */ - : (globals->root.target_os == is_nacl - ? arm_stub_long_branch_arm_nacl - : arm_stub_long_branch_any_any); + : arm_stub_long_branch_any_any; } } } @@ -4793,7 +4721,7 @@ elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section, stub_sec_p = &htab->stub_group[link_sec->id].stub_sec; stub_sec_prefix = link_sec->name; out_sec = link_sec->output_section; - align = htab->root.target_os == is_nacl ? 4 : 3; + align = 3; } if (*stub_sec_p == NULL) @@ -4974,10 +4902,6 @@ arm_stub_required_alignment (enum elf32_arm_stub_type stub_type) case arm_stub_a8_veneer_blx: return 4; - case arm_stub_long_branch_arm_nacl: - case arm_stub_long_branch_arm_nacl_pic: - return 16; - default: abort (); /* Should be unreachable. */ } @@ -6527,16 +6451,15 @@ elf32_arm_size_stubs (bfd *output_bfd, while (1) { bfd *input_bfd; - unsigned int bfd_indx; asection *stub_sec; enum elf32_arm_stub_type stub_type; bool stub_changed = false; unsigned prev_num_a8_fixes = num_a8_fixes; num_a8_fixes = 0; - for (input_bfd = info->input_bfds, bfd_indx = 0; + for (input_bfd = info->input_bfds; input_bfd != NULL; - input_bfd = input_bfd->link.next, bfd_indx++) + input_bfd = input_bfd->link.next) { Elf_Internal_Shdr *symtab_hdr; asection *section; @@ -9572,10 +9495,6 @@ elf32_arm_allocate_plt_entry (struct bfd_link_info *info, splt = htab->root.iplt; sgotplt = htab->root.igotplt; - /* NaCl uses a special first entry in .iplt too. */ - if (htab->root.target_os == is_nacl && splt->size == 0) - splt->size += htab->plt_header_size; - /* Allocate room for an R_ARM_IRELATIVE relocation in .rel.iplt. */ elf32_arm_allocate_irelocs (info, htab->root.irelplt, 1); } @@ -9628,18 +9547,6 @@ elf32_arm_allocate_plt_entry (struct bfd_link_info *info, sgotplt->size += 4; } -static bfd_vma -arm_movw_immediate (bfd_vma value) -{ - return (value & 0x00000fff) | ((value & 0x0000f000) << 4); -} - -static bfd_vma -arm_movt_immediate (bfd_vma value) -{ - return ((value & 0x0fff0000) >> 16) | ((value & 0xf0000000) >> 12); -} - /* Fill in a PLT entry and its associated GOT slot. If DYNINDX == -1, the entry lives in .iplt and resolves to (*SYM_VALUE)(). Otherwise, DYNINDX is the index of the symbol in the dynamic @@ -9777,45 +9684,6 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info, rel.r_addend = 0; SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc); } - else if (htab->root.target_os == is_nacl) - { - /* Calculate the displacement between the PLT slot and the - common tail that's part of the special initial PLT slot. */ - int32_t tail_displacement - = ((splt->output_section->vma + splt->output_offset - + ARM_NACL_PLT_TAIL_OFFSET) - - (plt_address + htab->plt_entry_size + 4)); - BFD_ASSERT ((tail_displacement & 3) == 0); - tail_displacement >>= 2; - - BFD_ASSERT ((tail_displacement & 0xff000000) == 0 - || (-tail_displacement & 0xff000000) == 0); - - /* Calculate the displacement between the PLT slot and the entry - in the GOT. The offset accounts for the value produced by - adding to pc in the penultimate instruction of the PLT stub. */ - got_displacement = (got_address - - (plt_address + htab->plt_entry_size)); - - /* NaCl does not support interworking at all. */ - BFD_ASSERT (!elf32_arm_plt_needs_thumb_stub_p (info, arm_plt)); - - put_arm_insn (htab, output_bfd, - elf32_arm_nacl_plt_entry[0] - | arm_movw_immediate (got_displacement), - ptr + 0); - put_arm_insn (htab, output_bfd, - elf32_arm_nacl_plt_entry[1] - | arm_movt_immediate (got_displacement), - ptr + 4); - put_arm_insn (htab, output_bfd, - elf32_arm_nacl_plt_entry[2], - ptr + 8); - put_arm_insn (htab, output_bfd, - elf32_arm_nacl_plt_entry[3] - | (tail_displacement & 0x00ffffff), - ptr + 12); - } else if (htab->fdpic_p) { const bfd_vma *plt_entry = using_thumb_only (htab) @@ -13379,7 +13247,8 @@ elf32_arm_relocate_section (bfd * output_bfd, if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, - rel, 1, relend, howto, 0, contents); + rel, 1, relend, R_ARM_NONE, + howto, 0, contents); if (bfd_link_relocatable (info)) { @@ -17344,38 +17213,6 @@ arm_put_trampoline (struct elf32_arm_link_hash_table *htab, bfd *output_bfd, } } -/* Install the special first PLT entry for elf32-arm-nacl. Unlike - other variants, NaCl needs this entry in a static executable's - .iplt too. When we're handling that case, GOT_DISPLACEMENT is - zero. For .iplt really only the last bundle is useful, and .iplt - could have a shorter first entry, with each individual PLT entry's - relative branch calculated differently so it targets the last - bundle instead of the instruction before it (labelled .Lplt_tail - above). But it's simpler to keep the size and layout of PLT0 - consistent with the dynamic case, at the cost of some dead code at - the start of .iplt and the one dead store to the stack at the start - of .Lplt_tail. */ -static void -arm_nacl_put_plt0 (struct elf32_arm_link_hash_table *htab, bfd *output_bfd, - asection *plt, bfd_vma got_displacement) -{ - unsigned int i; - - put_arm_insn (htab, output_bfd, - elf32_arm_nacl_plt0_entry[0] - | arm_movw_immediate (got_displacement), - plt->contents + 0); - put_arm_insn (htab, output_bfd, - elf32_arm_nacl_plt0_entry[1] - | arm_movt_immediate (got_displacement), - plt->contents + 4); - - for (i = 2; i < ARRAY_SIZE (elf32_arm_nacl_plt0_entry); ++i) - put_arm_insn (htab, output_bfd, - elf32_arm_nacl_plt0_entry[i], - plt->contents + (i * 4)); -} - /* Finish up the dynamic sections. */ static bool @@ -17541,9 +17378,6 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info SWAP_RELOC_OUT (htab) (output_bfd, &rel, htab->srelplt2->contents); } - else if (htab->root.target_os == is_nacl) - arm_nacl_put_plt0 (htab, output_bfd, splt, - got_address + 8 - (plt_address + 16)); else if (using_thumb_only (htab)) { got_displacement = got_address - (plt_address + 12); @@ -17652,12 +17486,6 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info } } - if (htab->root.target_os == is_nacl - && htab->root.iplt != NULL - && htab->root.iplt->size > 0) - /* NaCl uses a special first entry in .iplt too. */ - arm_nacl_put_plt0 (htab, output_bfd, htab->root.iplt, 0); - /* Fill in the first three entries in the global offset table. */ if (sgot) { @@ -17971,11 +17799,6 @@ elf32_arm_output_plt_map_1 (output_arch_syminfo *osi, if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 20)) return false; } - else if (htab->root.target_os == is_nacl) - { - if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr)) - return false; - } else if (htab->fdpic_p) { enum map_symbol_type type = using_thumb_only (htab) @@ -18348,11 +18171,6 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd, return false; } } - else if (htab->root.target_os == is_nacl) - { - if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0)) - return false; - } else if (using_thumb_only (htab) && !htab->fdpic_p) { if (!elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, 0)) @@ -18372,17 +18190,6 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd, #endif } } - if (htab->root.target_os == is_nacl - && htab->root.iplt - && htab->root.iplt->size > 0) - { - /* NaCl uses a special first entry in .iplt too. */ - osi.sec = htab->root.iplt; - osi.sec_shndx = (_bfd_elf_section_from_bfd_section - (output_bfd, osi.sec->output_section)); - if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0)) - return false; - } if ((htab->root.splt && htab->root.splt->size > 0) || (htab->root.iplt && htab->root.iplt->size > 0)) { @@ -20440,90 +20247,6 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym) #include "elf32-target.h" -/* Native Client targets. */ - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM arm_elf32_nacl_le_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf32-littlearm-nacl" -#undef TARGET_BIG_SYM -#define TARGET_BIG_SYM arm_elf32_nacl_be_vec -#undef TARGET_BIG_NAME -#define TARGET_BIG_NAME "elf32-bigarm-nacl" - -/* Like elf32_arm_link_hash_table_create -- but overrides - appropriately for NaCl. */ - -static struct bfd_link_hash_table * -elf32_arm_nacl_link_hash_table_create (bfd *abfd) -{ - struct bfd_link_hash_table *ret; - - ret = elf32_arm_link_hash_table_create (abfd); - if (ret) - { - struct elf32_arm_link_hash_table *htab - = (struct elf32_arm_link_hash_table *) ret; - - htab->plt_header_size = 4 * ARRAY_SIZE (elf32_arm_nacl_plt0_entry); - htab->plt_entry_size = 4 * ARRAY_SIZE (elf32_arm_nacl_plt_entry); - } - return ret; -} - -/* Since NaCl doesn't use the ARM-specific unwind format, we don't - really need to use elf32_arm_modify_segment_map. But we do it - anyway just to reduce gratuitous differences with the stock ARM backend. */ - -static bool -elf32_arm_nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info) -{ - return (elf32_arm_modify_segment_map (abfd, info) - && nacl_modify_segment_map (abfd, info)); -} - -static bool -elf32_arm_nacl_final_write_processing (bfd *abfd) -{ - arm_final_write_processing (abfd); - return nacl_final_write_processing (abfd); -} - -static bfd_vma -elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt, - const arelent *rel ATTRIBUTE_UNUSED) -{ - return plt->vma - + 4 * (ARRAY_SIZE (elf32_arm_nacl_plt0_entry) + - i * ARRAY_SIZE (elf32_arm_nacl_plt_entry)); -} - -#undef elf32_bed -#define elf32_bed elf32_arm_nacl_bed -#undef bfd_elf32_bfd_link_hash_table_create -#define bfd_elf32_bfd_link_hash_table_create \ - elf32_arm_nacl_link_hash_table_create -#undef elf_backend_plt_alignment -#define elf_backend_plt_alignment 4 -#undef elf_backend_modify_segment_map -#define elf_backend_modify_segment_map elf32_arm_nacl_modify_segment_map -#undef elf_backend_modify_headers -#define elf_backend_modify_headers nacl_modify_headers -#undef elf_backend_final_write_processing -#define elf_backend_final_write_processing elf32_arm_nacl_final_write_processing -#undef bfd_elf32_get_synthetic_symtab -#undef elf_backend_plt_sym_val -#define elf_backend_plt_sym_val elf32_arm_nacl_plt_sym_val -#undef elf_backend_copy_special_section_fields - -#undef ELF_MINPAGESIZE -#undef ELF_COMMONPAGESIZE - -#undef ELF_TARGET_OS -#define ELF_TARGET_OS is_nacl - -#include "elf32-target.h" - /* Reset to defaults. */ #undef elf_backend_plt_alignment #undef elf_backend_modify_segment_map |