| /* 32-bit ELF support for ARM |
| Copyright (C) 1998-2024 Free Software Foundation, Inc. |
| |
| This file is part of BFD, the Binary File Descriptor library. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
| MA 02110-1301, USA. */ |
| |
| #include "sysdep.h" |
| #include <limits.h> |
| |
| #include "bfd.h" |
| #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" |
| #include "cpu-arm.h" |
| |
| /* Return the relocation section associated with NAME. HTAB is the |
| bfd's elf32_arm_link_hash_entry. */ |
| #define RELOC_SECTION(HTAB, NAME) \ |
| ((HTAB)->use_rel ? ".rel" NAME : ".rela" NAME) |
| |
| /* Return size of a relocation entry. HTAB is the bfd's |
| elf32_arm_link_hash_entry. */ |
| #define RELOC_SIZE(HTAB) \ |
| ((HTAB)->use_rel \ |
| ? sizeof (Elf32_External_Rel) \ |
| : sizeof (Elf32_External_Rela)) |
| |
| /* Return function to swap relocations in. HTAB is the bfd's |
| elf32_arm_link_hash_entry. */ |
| #define SWAP_RELOC_IN(HTAB) \ |
| ((HTAB)->use_rel \ |
| ? bfd_elf32_swap_reloc_in \ |
| : bfd_elf32_swap_reloca_in) |
| |
| /* Return function to swap relocations out. HTAB is the bfd's |
| elf32_arm_link_hash_entry. */ |
| #define SWAP_RELOC_OUT(HTAB) \ |
| ((HTAB)->use_rel \ |
| ? bfd_elf32_swap_reloc_out \ |
| : bfd_elf32_swap_reloca_out) |
| |
| #define elf_info_to_howto NULL |
| #define elf_info_to_howto_rel elf32_arm_info_to_howto |
| |
| #define ARM_ELF_ABI_VERSION 0 |
| #define ARM_ELF_OS_ABI_VERSION ELFOSABI_ARM |
| |
| /* The Adjusted Place, as defined by AAELF. */ |
| #define Pa(X) ((X) & 0xfffffffc) |
| |
| static bool elf32_arm_write_section (bfd *output_bfd, |
| struct bfd_link_info *link_info, |
| asection *sec, |
| bfd_byte *contents); |
| |
| /* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g. |
| R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO |
| in that slot. */ |
| |
| static reloc_howto_type elf32_arm_howto_table_1[] = |
| { |
| /* No relocation. */ |
| HOWTO (R_ARM_NONE, /* type */ |
| 0, /* rightshift */ |
| 0, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_NONE", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_PC24, /* type */ |
| 2, /* rightshift */ |
| 4, /* size */ |
| 24, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_PC24", /* name */ |
| false, /* partial_inplace */ |
| 0x00ffffff, /* src_mask */ |
| 0x00ffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| /* 32 bit absolute */ |
| HOWTO (R_ARM_ABS32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ABS32", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| /* standard 32bit pc-relative reloc */ |
| HOWTO (R_ARM_REL32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_REL32", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| /* 8 bit absolute - R_ARM_LDR_PC_G0 in AAELF */ |
| HOWTO (R_ARM_LDR_PC_G0, /* type */ |
| 0, /* rightshift */ |
| 1, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDR_PC_G0", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| /* 16 bit absolute */ |
| HOWTO (R_ARM_ABS16, /* type */ |
| 0, /* rightshift */ |
| 2, /* size */ |
| 16, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ABS16", /* name */ |
| false, /* partial_inplace */ |
| 0x0000ffff, /* src_mask */ |
| 0x0000ffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| /* 12 bit absolute */ |
| HOWTO (R_ARM_ABS12, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 12, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ABS12", /* name */ |
| false, /* partial_inplace */ |
| 0x00000fff, /* src_mask */ |
| 0x00000fff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_ABS5, /* type */ |
| 6, /* rightshift */ |
| 2, /* size */ |
| 5, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_ABS5", /* name */ |
| false, /* partial_inplace */ |
| 0x000007e0, /* src_mask */ |
| 0x000007e0, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| /* 8 bit absolute */ |
| HOWTO (R_ARM_ABS8, /* type */ |
| 0, /* rightshift */ |
| 1, /* size */ |
| 8, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ABS8", /* name */ |
| false, /* partial_inplace */ |
| 0x000000ff, /* src_mask */ |
| 0x000000ff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_SBREL32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_SBREL32", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_CALL, /* type */ |
| 1, /* rightshift */ |
| 4, /* size */ |
| 24, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_CALL", /* name */ |
| false, /* partial_inplace */ |
| 0x07ff2fff, /* src_mask */ |
| 0x07ff2fff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_PC8, /* type */ |
| 1, /* rightshift */ |
| 2, /* size */ |
| 8, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_PC8", /* name */ |
| false, /* partial_inplace */ |
| 0x000000ff, /* src_mask */ |
| 0x000000ff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_BREL_ADJ, /* type */ |
| 1, /* rightshift */ |
| 2, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_BREL_ADJ", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_DESC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_DESC", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_SWI8, /* type */ |
| 0, /* rightshift */ |
| 0, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_SWI8", /* name */ |
| false, /* partial_inplace */ |
| 0x00000000, /* src_mask */ |
| 0x00000000, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| /* BLX instruction for the ARM. */ |
| HOWTO (R_ARM_XPC25, /* type */ |
| 2, /* rightshift */ |
| 4, /* size */ |
| 24, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_XPC25", /* name */ |
| false, /* partial_inplace */ |
| 0x00ffffff, /* src_mask */ |
| 0x00ffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| /* BLX instruction for the Thumb. */ |
| HOWTO (R_ARM_THM_XPC22, /* type */ |
| 2, /* rightshift */ |
| 4, /* size */ |
| 24, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_XPC22", /* name */ |
| false, /* partial_inplace */ |
| 0x07ff2fff, /* src_mask */ |
| 0x07ff2fff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| /* Dynamic TLS relocations. */ |
| |
| HOWTO (R_ARM_TLS_DTPMOD32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_DTPMOD32", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_DTPOFF32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_DTPOFF32", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_TPOFF32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_TPOFF32", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| /* Relocs used in ARM Linux */ |
| |
| HOWTO (R_ARM_COPY, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_COPY", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_GLOB_DAT, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_GLOB_DAT", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_JUMP_SLOT, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_JUMP_SLOT", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_RELATIVE, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_RELATIVE", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_GOTOFF32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_GOTOFF32", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_GOTPC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_GOTPC", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_GOT32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_GOT32", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_PLT32, /* type */ |
| 2, /* rightshift */ |
| 4, /* size */ |
| 24, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_PLT32", /* name */ |
| false, /* partial_inplace */ |
| 0x00ffffff, /* src_mask */ |
| 0x00ffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_CALL, /* type */ |
| 2, /* rightshift */ |
| 4, /* size */ |
| 24, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_CALL", /* name */ |
| false, /* partial_inplace */ |
| 0x00ffffff, /* src_mask */ |
| 0x00ffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_JUMP24, /* type */ |
| 2, /* rightshift */ |
| 4, /* size */ |
| 24, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_JUMP24", /* name */ |
| false, /* partial_inplace */ |
| 0x00ffffff, /* src_mask */ |
| 0x00ffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_JUMP24, /* type */ |
| 1, /* rightshift */ |
| 4, /* size */ |
| 24, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_JUMP24", /* name */ |
| false, /* partial_inplace */ |
| 0x07ff2fff, /* src_mask */ |
| 0x07ff2fff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_BASE_ABS, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_BASE_ABS", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_PCREL7_0, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 12, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_PCREL_7_0", /* name */ |
| false, /* partial_inplace */ |
| 0x00000fff, /* src_mask */ |
| 0x00000fff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_PCREL15_8, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 12, /* bitsize */ |
| true, /* pc_relative */ |
| 8, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_PCREL_15_8",/* name */ |
| false, /* partial_inplace */ |
| 0x00000fff, /* src_mask */ |
| 0x00000fff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_PCREL23_15, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 12, /* bitsize */ |
| true, /* pc_relative */ |
| 16, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_PCREL_23_15",/* name */ |
| false, /* partial_inplace */ |
| 0x00000fff, /* src_mask */ |
| 0x00000fff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDR_SBREL_11_0, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 12, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDR_SBREL_11_0",/* name */ |
| false, /* partial_inplace */ |
| 0x00000fff, /* src_mask */ |
| 0x00000fff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_SBREL_19_12, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 8, /* bitsize */ |
| false, /* pc_relative */ |
| 12, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_SBREL_19_12",/* name */ |
| false, /* partial_inplace */ |
| 0x000ff000, /* src_mask */ |
| 0x000ff000, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_SBREL_27_20, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 8, /* bitsize */ |
| false, /* pc_relative */ |
| 20, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_SBREL_27_20",/* name */ |
| false, /* partial_inplace */ |
| 0x0ff00000, /* src_mask */ |
| 0x0ff00000, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TARGET1, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TARGET1", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ROSEGREL32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ROSEGREL32", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_V4BX, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_V4BX", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TARGET2, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TARGET2", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_PREL31, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 31, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_PREL31", /* name */ |
| false, /* partial_inplace */ |
| 0x7fffffff, /* src_mask */ |
| 0x7fffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_MOVW_ABS_NC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_MOVW_ABS_NC", /* name */ |
| false, /* partial_inplace */ |
| 0x000f0fff, /* src_mask */ |
| 0x000f0fff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_MOVT_ABS, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_MOVT_ABS", /* name */ |
| false, /* partial_inplace */ |
| 0x000f0fff, /* src_mask */ |
| 0x000f0fff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_MOVW_PREL_NC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_MOVW_PREL_NC", /* name */ |
| false, /* partial_inplace */ |
| 0x000f0fff, /* src_mask */ |
| 0x000f0fff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_MOVT_PREL, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_MOVT_PREL", /* name */ |
| false, /* partial_inplace */ |
| 0x000f0fff, /* src_mask */ |
| 0x000f0fff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_MOVW_ABS_NC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_MOVW_ABS_NC",/* name */ |
| false, /* partial_inplace */ |
| 0x040f70ff, /* src_mask */ |
| 0x040f70ff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_MOVT_ABS, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_MOVT_ABS", /* name */ |
| false, /* partial_inplace */ |
| 0x040f70ff, /* src_mask */ |
| 0x040f70ff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_MOVW_PREL_NC,/* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_MOVW_PREL_NC",/* name */ |
| false, /* partial_inplace */ |
| 0x040f70ff, /* src_mask */ |
| 0x040f70ff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_MOVT_PREL, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_MOVT_PREL", /* name */ |
| false, /* partial_inplace */ |
| 0x040f70ff, /* src_mask */ |
| 0x040f70ff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_JUMP19, /* type */ |
| 1, /* rightshift */ |
| 4, /* size */ |
| 19, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_JUMP19", /* name */ |
| false, /* partial_inplace */ |
| 0x043f2fff, /* src_mask */ |
| 0x043f2fff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_JUMP6, /* type */ |
| 1, /* rightshift */ |
| 2, /* size */ |
| 6, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_unsigned,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_JUMP6", /* name */ |
| false, /* partial_inplace */ |
| 0x02f8, /* src_mask */ |
| 0x02f8, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| /* These are declared as 13-bit signed relocations because we can |
| address -4095 .. 4095(base) by altering ADDW to SUBW or vice |
| versa. */ |
| HOWTO (R_ARM_THM_ALU_PREL_11_0,/* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 13, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_ALU_PREL_11_0",/* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_PC12, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 13, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_PC12", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ABS32_NOI, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ABS32_NOI", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_REL32_NOI, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_REL32_NOI", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| /* Group relocations. */ |
| |
| HOWTO (R_ARM_ALU_PC_G0_NC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_PC_G0_NC", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_PC_G0, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_PC_G0", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_PC_G1_NC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_PC_G1_NC", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_PC_G1, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_PC_G1", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_PC_G2, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_PC_G2", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDR_PC_G1, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDR_PC_G1", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDR_PC_G2, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDR_PC_G2", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDRS_PC_G0, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDRS_PC_G0", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDRS_PC_G1, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDRS_PC_G1", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDRS_PC_G2, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDRS_PC_G2", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDC_PC_G0, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDC_PC_G0", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDC_PC_G1, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDC_PC_G1", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDC_PC_G2, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDC_PC_G2", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_SB_G0_NC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_SB_G0_NC", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_SB_G0, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_SB_G0", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_SB_G1_NC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_SB_G1_NC", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_SB_G1, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_SB_G1", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_ALU_SB_G2, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_ALU_SB_G2", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDR_SB_G0, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDR_SB_G0", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDR_SB_G1, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDR_SB_G1", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDR_SB_G2, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDR_SB_G2", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDRS_SB_G0, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDRS_SB_G0", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDRS_SB_G1, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDRS_SB_G1", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDRS_SB_G2, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDRS_SB_G2", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDC_SB_G0, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDC_SB_G0", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDC_SB_G1, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDC_SB_G1", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_LDC_SB_G2, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_LDC_SB_G2", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| /* End of group relocations. */ |
| |
| HOWTO (R_ARM_MOVW_BREL_NC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_MOVW_BREL_NC", /* name */ |
| false, /* partial_inplace */ |
| 0x0000ffff, /* src_mask */ |
| 0x0000ffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_MOVT_BREL, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_MOVT_BREL", /* name */ |
| false, /* partial_inplace */ |
| 0x0000ffff, /* src_mask */ |
| 0x0000ffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_MOVW_BREL, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_MOVW_BREL", /* name */ |
| false, /* partial_inplace */ |
| 0x0000ffff, /* src_mask */ |
| 0x0000ffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_MOVW_BREL_NC,/* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_MOVW_BREL_NC",/* name */ |
| false, /* partial_inplace */ |
| 0x040f70ff, /* src_mask */ |
| 0x040f70ff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_MOVT_BREL, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_MOVT_BREL", /* name */ |
| false, /* partial_inplace */ |
| 0x040f70ff, /* src_mask */ |
| 0x040f70ff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_MOVW_BREL, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 16, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_MOVW_BREL", /* name */ |
| false, /* partial_inplace */ |
| 0x040f70ff, /* src_mask */ |
| 0x040f70ff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_GOTDESC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| NULL, /* special_function */ |
| "R_ARM_TLS_GOTDESC", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_CALL, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 24, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_CALL", /* name */ |
| false, /* partial_inplace */ |
| 0x00ffffff, /* src_mask */ |
| 0x00ffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_DESCSEQ, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_DESCSEQ", /* name */ |
| false, /* partial_inplace */ |
| 0x00000000, /* src_mask */ |
| 0x00000000, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_TLS_CALL, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 24, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_TLS_CALL", /* name */ |
| false, /* partial_inplace */ |
| 0x07ff07ff, /* src_mask */ |
| 0x07ff07ff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_PLT32_ABS, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_PLT32_ABS", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_GOT_ABS, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_GOT_ABS", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_GOT_PREL, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_GOT_PREL", /* name */ |
| false, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_GOT_BREL12, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 12, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_GOT_BREL12", /* name */ |
| false, /* partial_inplace */ |
| 0x00000fff, /* src_mask */ |
| 0x00000fff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_GOTOFF12, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 12, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_GOTOFF12", /* name */ |
| false, /* partial_inplace */ |
| 0x00000fff, /* src_mask */ |
| 0x00000fff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| EMPTY_HOWTO (R_ARM_GOTRELAX), /* reserved for future GOT-load optimizations */ |
| |
| /* GNU extension to record C++ vtable member usage */ |
| HOWTO (R_ARM_GNU_VTENTRY, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| _bfd_elf_rel_vtable_reloc_fn, /* special_function */ |
| "R_ARM_GNU_VTENTRY", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| /* GNU extension to record C++ vtable hierarchy */ |
| HOWTO (R_ARM_GNU_VTINHERIT, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont, /* complain_on_overflow */ |
| NULL, /* special_function */ |
| "R_ARM_GNU_VTINHERIT", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_JUMP11, /* type */ |
| 1, /* rightshift */ |
| 2, /* size */ |
| 11, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_JUMP11", /* name */ |
| false, /* partial_inplace */ |
| 0x000007ff, /* src_mask */ |
| 0x000007ff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_THM_JUMP8, /* type */ |
| 1, /* rightshift */ |
| 2, /* size */ |
| 8, /* bitsize */ |
| true, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_signed, /* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_JUMP8", /* name */ |
| false, /* partial_inplace */ |
| 0x000000ff, /* src_mask */ |
| 0x000000ff, /* dst_mask */ |
| true), /* pcrel_offset */ |
| |
| /* TLS relocations */ |
| HOWTO (R_ARM_TLS_GD32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| NULL, /* special_function */ |
| "R_ARM_TLS_GD32", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_LDM32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_LDM32", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_LDO32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_LDO32", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_IE32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| NULL, /* special_function */ |
| "R_ARM_TLS_IE32", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_LE32, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| NULL, /* special_function */ |
| "R_ARM_TLS_LE32", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_LDO12, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 12, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_LDO12", /* name */ |
| false, /* partial_inplace */ |
| 0x00000fff, /* src_mask */ |
| 0x00000fff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_LE12, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 12, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_LE12", /* name */ |
| false, /* partial_inplace */ |
| 0x00000fff, /* src_mask */ |
| 0x00000fff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_TLS_IE12GP, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 12, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_IE12GP", /* name */ |
| false, /* partial_inplace */ |
| 0x00000fff, /* src_mask */ |
| 0x00000fff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| /* 112-127 private relocations. */ |
| EMPTY_HOWTO (112), |
| EMPTY_HOWTO (113), |
| EMPTY_HOWTO (114), |
| EMPTY_HOWTO (115), |
| EMPTY_HOWTO (116), |
| EMPTY_HOWTO (117), |
| EMPTY_HOWTO (118), |
| EMPTY_HOWTO (119), |
| EMPTY_HOWTO (120), |
| EMPTY_HOWTO (121), |
| EMPTY_HOWTO (122), |
| EMPTY_HOWTO (123), |
| EMPTY_HOWTO (124), |
| EMPTY_HOWTO (125), |
| EMPTY_HOWTO (126), |
| EMPTY_HOWTO (127), |
| |
| /* R_ARM_ME_TOO, obsolete. */ |
| EMPTY_HOWTO (128), |
| |
| HOWTO (R_ARM_THM_TLS_DESCSEQ, /* type */ |
| 0, /* rightshift */ |
| 2, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_THM_TLS_DESCSEQ",/* name */ |
| false, /* partial_inplace */ |
| 0x00000000, /* src_mask */ |
| 0x00000000, /* dst_mask */ |
| false), /* pcrel_offset */ |
| EMPTY_HOWTO (130), |
| EMPTY_HOWTO (131), |
| HOWTO (R_ARM_THM_ALU_ABS_G0_NC,/* type. */ |
| 0, /* rightshift. */ |
| 2, /* size. */ |
| 16, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_bitfield,/* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_ARM_THM_ALU_ABS_G0_NC",/* name. */ |
| false, /* partial_inplace. */ |
| 0x00000000, /* src_mask. */ |
| 0x00000000, /* dst_mask. */ |
| false), /* pcrel_offset. */ |
| HOWTO (R_ARM_THM_ALU_ABS_G1_NC,/* type. */ |
| 0, /* rightshift. */ |
| 2, /* size. */ |
| 16, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_bitfield,/* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_ARM_THM_ALU_ABS_G1_NC",/* name. */ |
| false, /* partial_inplace. */ |
| 0x00000000, /* src_mask. */ |
| 0x00000000, /* dst_mask. */ |
| false), /* pcrel_offset. */ |
| HOWTO (R_ARM_THM_ALU_ABS_G2_NC,/* type. */ |
| 0, /* rightshift. */ |
| 2, /* size. */ |
| 16, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_bitfield,/* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_ARM_THM_ALU_ABS_G2_NC",/* name. */ |
| false, /* partial_inplace. */ |
| 0x00000000, /* src_mask. */ |
| 0x00000000, /* dst_mask. */ |
| false), /* pcrel_offset. */ |
| HOWTO (R_ARM_THM_ALU_ABS_G3_NC,/* type. */ |
| 0, /* rightshift. */ |
| 2, /* size. */ |
| 16, /* bitsize. */ |
| false, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_bitfield,/* complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_ARM_THM_ALU_ABS_G3_NC",/* name. */ |
| false, /* partial_inplace. */ |
| 0x00000000, /* src_mask. */ |
| 0x00000000, /* dst_mask. */ |
| false), /* pcrel_offset. */ |
| /* Relocations for Armv8.1-M Mainline. */ |
| HOWTO (R_ARM_THM_BF16, /* type. */ |
| 0, /* rightshift. */ |
| 2, /* size. */ |
| 16, /* bitsize. */ |
| true, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont,/* do not complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_ARM_THM_BF16", /* name. */ |
| false, /* partial_inplace. */ |
| 0x001f0ffe, /* src_mask. */ |
| 0x001f0ffe, /* dst_mask. */ |
| true), /* pcrel_offset. */ |
| HOWTO (R_ARM_THM_BF12, /* type. */ |
| 0, /* rightshift. */ |
| 2, /* size. */ |
| 12, /* bitsize. */ |
| true, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont,/* do not complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_ARM_THM_BF12", /* name. */ |
| false, /* partial_inplace. */ |
| 0x00010ffe, /* src_mask. */ |
| 0x00010ffe, /* dst_mask. */ |
| true), /* pcrel_offset. */ |
| HOWTO (R_ARM_THM_BF18, /* type. */ |
| 0, /* rightshift. */ |
| 2, /* size. */ |
| 18, /* bitsize. */ |
| true, /* pc_relative. */ |
| 0, /* bitpos. */ |
| complain_overflow_dont,/* do not complain_on_overflow. */ |
| bfd_elf_generic_reloc, /* special_function. */ |
| "R_ARM_THM_BF18", /* name. */ |
| false, /* partial_inplace. */ |
| 0x007f0ffe, /* src_mask. */ |
| 0x007f0ffe, /* dst_mask. */ |
| true), /* pcrel_offset. */ |
| }; |
| |
| /* 160 onwards: */ |
| static reloc_howto_type elf32_arm_howto_table_2[8] = |
| { |
| HOWTO (R_ARM_IRELATIVE, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_IRELATIVE", /* name */ |
| true, /* partial_inplace */ |
| 0xffffffff, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| HOWTO (R_ARM_GOTFUNCDESC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_GOTFUNCDESC", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| HOWTO (R_ARM_GOTOFFFUNCDESC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_GOTOFFFUNCDESC",/* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| HOWTO (R_ARM_FUNCDESC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_FUNCDESC", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| HOWTO (R_ARM_FUNCDESC_VALUE, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 64, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_FUNCDESC_VALUE",/* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| HOWTO (R_ARM_TLS_GD32_FDPIC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_GD32_FDPIC",/* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| HOWTO (R_ARM_TLS_LDM32_FDPIC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_LDM32_FDPIC",/* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| HOWTO (R_ARM_TLS_IE32_FDPIC, /* type */ |
| 0, /* rightshift */ |
| 4, /* size */ |
| 32, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_bitfield,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_TLS_IE32_FDPIC",/* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0xffffffff, /* dst_mask */ |
| false), /* pcrel_offset */ |
| }; |
| |
| /* 249-255 extended, currently unused, relocations: */ |
| static reloc_howto_type elf32_arm_howto_table_3[4] = |
| { |
| HOWTO (R_ARM_RREL32, /* type */ |
| 0, /* rightshift */ |
| 0, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_RREL32", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_RABS32, /* type */ |
| 0, /* rightshift */ |
| 0, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_RABS32", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_RPC24, /* type */ |
| 0, /* rightshift */ |
| 0, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_RPC24", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false), /* pcrel_offset */ |
| |
| HOWTO (R_ARM_RBASE, /* type */ |
| 0, /* rightshift */ |
| 0, /* size */ |
| 0, /* bitsize */ |
| false, /* pc_relative */ |
| 0, /* bitpos */ |
| complain_overflow_dont,/* complain_on_overflow */ |
| bfd_elf_generic_reloc, /* special_function */ |
| "R_ARM_RBASE", /* name */ |
| false, /* partial_inplace */ |
| 0, /* src_mask */ |
| 0, /* dst_mask */ |
| false) /* pcrel_offset */ |
| }; |
| |
| static reloc_howto_type * |
| elf32_arm_howto_from_type (unsigned int r_type) |
| { |
| if (r_type < ARRAY_SIZE (elf32_arm_howto_table_1)) |
| return &elf32_arm_howto_table_1[r_type]; |
| |
| if (r_type >= R_ARM_IRELATIVE |
| && r_type < R_ARM_IRELATIVE + ARRAY_SIZE (elf32_arm_howto_table_2)) |
| return &elf32_arm_howto_table_2[r_type - R_ARM_IRELATIVE]; |
| |
| if (r_type >= R_ARM_RREL32 |
| && r_type < R_ARM_RREL32 + ARRAY_SIZE (elf32_arm_howto_table_3)) |
| return &elf32_arm_howto_table_3[r_type - R_ARM_RREL32]; |
| |
| return NULL; |
| } |
| |
| static bool |
| elf32_arm_info_to_howto (bfd * abfd, arelent * bfd_reloc, |
| Elf_Internal_Rela * elf_reloc) |
| { |
| unsigned int r_type; |
| |
| r_type = ELF32_R_TYPE (elf_reloc->r_info); |
| if ((bfd_reloc->howto = elf32_arm_howto_from_type (r_type)) == NULL) |
| { |
| /* xgettext:c-format */ |
| _bfd_error_handler (_("%pB: unsupported relocation type %#x"), |
| abfd, r_type); |
| bfd_set_error (bfd_error_bad_value); |
| return false; |
| } |
| return true; |
| } |
| |
| struct elf32_arm_reloc_map |
| { |
| bfd_reloc_code_real_type bfd_reloc_val; |
| unsigned char elf_reloc_val; |
| }; |
| |
| /* All entries in this list must also be present in elf32_arm_howto_table. */ |
| static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] = |
| { |
| {BFD_RELOC_NONE, R_ARM_NONE}, |
| {BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24}, |
| {BFD_RELOC_ARM_PCREL_CALL, R_ARM_CALL}, |
| {BFD_RELOC_ARM_PCREL_JUMP, R_ARM_JUMP24}, |
| {BFD_RELOC_ARM_PCREL_BLX, R_ARM_XPC25}, |
| {BFD_RELOC_THUMB_PCREL_BLX, R_ARM_THM_XPC22}, |
| {BFD_RELOC_32, R_ARM_ABS32}, |
| {BFD_RELOC_32_PCREL, R_ARM_REL32}, |
| {BFD_RELOC_8, R_ARM_ABS8}, |
| {BFD_RELOC_16, R_ARM_ABS16}, |
| {BFD_RELOC_ARM_OFFSET_IMM, R_ARM_ABS12}, |
| {BFD_RELOC_ARM_THUMB_OFFSET, R_ARM_THM_ABS5}, |
| {BFD_RELOC_THUMB_PCREL_BRANCH25, R_ARM_THM_JUMP24}, |
| {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_CALL}, |
| {BFD_RELOC_THUMB_PCREL_BRANCH12, R_ARM_THM_JUMP11}, |
| {BFD_RELOC_THUMB_PCREL_BRANCH20, R_ARM_THM_JUMP19}, |
| {BFD_RELOC_THUMB_PCREL_BRANCH9, R_ARM_THM_JUMP8}, |
| {BFD_RELOC_THUMB_PCREL_BRANCH7, R_ARM_THM_JUMP6}, |
| {BFD_RELOC_ARM_GLOB_DAT, R_ARM_GLOB_DAT}, |
| {BFD_RELOC_ARM_JUMP_SLOT, R_ARM_JUMP_SLOT}, |
| {BFD_RELOC_ARM_RELATIVE, R_ARM_RELATIVE}, |
| {BFD_RELOC_ARM_GOTOFF, R_ARM_GOTOFF32}, |
| {BFD_RELOC_ARM_GOTPC, R_ARM_GOTPC}, |
| {BFD_RELOC_ARM_GOT_PREL, R_ARM_GOT_PREL}, |
| {BFD_RELOC_ARM_GOT32, R_ARM_GOT32}, |
| {BFD_RELOC_ARM_PLT32, R_ARM_PLT32}, |
| {BFD_RELOC_ARM_TARGET1, R_ARM_TARGET1}, |
| {BFD_RELOC_ARM_ROSEGREL32, R_ARM_ROSEGREL32}, |
| {BFD_RELOC_ARM_SBREL32, R_ARM_SBREL32}, |
| {BFD_RELOC_ARM_PREL31, R_ARM_PREL31}, |
| {BFD_RELOC_ARM_TARGET2, R_ARM_TARGET2}, |
| {BFD_RELOC_ARM_PLT32, R_ARM_PLT32}, |
| {BFD_RELOC_ARM_TLS_GOTDESC, R_ARM_TLS_GOTDESC}, |
| {BFD_RELOC_ARM_TLS_CALL, R_ARM_TLS_CALL}, |
| {BFD_RELOC_ARM_THM_TLS_CALL, R_ARM_THM_TLS_CALL}, |
| {BFD_RELOC_ARM_TLS_DESCSEQ, R_ARM_TLS_DESCSEQ}, |
| {BFD_RELOC_ARM_THM_TLS_DESCSEQ, R_ARM_THM_TLS_DESCSEQ}, |
| {BFD_RELOC_ARM_TLS_DESC, R_ARM_TLS_DESC}, |
| {BFD_RELOC_ARM_TLS_GD32, R_ARM_TLS_GD32}, |
| {BFD_RELOC_ARM_TLS_LDO32, R_ARM_TLS_LDO32}, |
| {BFD_RELOC_ARM_TLS_LDM32, R_ARM_TLS_LDM32}, |
| {BFD_RELOC_ARM_TLS_DTPMOD32, R_ARM_TLS_DTPMOD32}, |
| {BFD_RELOC_ARM_TLS_DTPOFF32, R_ARM_TLS_DTPOFF32}, |
| {BFD_RELOC_ARM_TLS_TPOFF32, R_ARM_TLS_TPOFF32}, |
| {BFD_RELOC_ARM_TLS_IE32, R_ARM_TLS_IE32}, |
| {BFD_RELOC_ARM_TLS_LE32, R_ARM_TLS_LE32}, |
| {BFD_RELOC_ARM_IRELATIVE, R_ARM_IRELATIVE}, |
| {BFD_RELOC_ARM_GOTFUNCDESC, R_ARM_GOTFUNCDESC}, |
| {BFD_RELOC_ARM_GOTOFFFUNCDESC, R_ARM_GOTOFFFUNCDESC}, |
| {BFD_RELOC_ARM_FUNCDESC, R_ARM_FUNCDESC}, |
| {BFD_RELOC_ARM_FUNCDESC_VALUE, R_ARM_FUNCDESC_VALUE}, |
| {BFD_RELOC_ARM_TLS_GD32_FDPIC, R_ARM_TLS_GD32_FDPIC}, |
| {BFD_RELOC_ARM_TLS_LDM32_FDPIC, R_ARM_TLS_LDM32_FDPIC}, |
| {BFD_RELOC_ARM_TLS_IE32_FDPIC, R_ARM_TLS_IE32_FDPIC}, |
| {BFD_RELOC_VTABLE_INHERIT, R_ARM_GNU_VTINHERIT}, |
| {BFD_RELOC_VTABLE_ENTRY, R_ARM_GNU_VTENTRY}, |
| {BFD_RELOC_ARM_MOVW, R_ARM_MOVW_ABS_NC}, |
| {BFD_RELOC_ARM_MOVT, R_ARM_MOVT_ABS}, |
| {BFD_RELOC_ARM_MOVW_PCREL, R_ARM_MOVW_PREL_NC}, |
| {BFD_RELOC_ARM_MOVT_PCREL, R_ARM_MOVT_PREL}, |
| {BFD_RELOC_ARM_THUMB_MOVW, R_ARM_THM_MOVW_ABS_NC}, |
| {BFD_RELOC_ARM_THUMB_MOVT, R_ARM_THM_MOVT_ABS}, |
| {BFD_RELOC_ARM_THUMB_MOVW_PCREL, R_ARM_THM_MOVW_PREL_NC}, |
| {BFD_RELOC_ARM_THUMB_MOVT_PCREL, R_ARM_THM_MOVT_PREL}, |
| {BFD_RELOC_ARM_ALU_PC_G0_NC, R_ARM_ALU_PC_G0_NC}, |
| {BFD_RELOC_ARM_ALU_PC_G0, R_ARM_ALU_PC_G0}, |
| {BFD_RELOC_ARM_ALU_PC_G1_NC, R_ARM_ALU_PC_G1_NC}, |
| {BFD_RELOC_ARM_ALU_PC_G1, R_ARM_ALU_PC_G1}, |
| {BFD_RELOC_ARM_ALU_PC_G2, R_ARM_ALU_PC_G2}, |
| {BFD_RELOC_ARM_LDR_PC_G0, R_ARM_LDR_PC_G0}, |
| {BFD_RELOC_ARM_LDR_PC_G1, R_ARM_LDR_PC_G1}, |
| {BFD_RELOC_ARM_LDR_PC_G2, R_ARM_LDR_PC_G2}, |
| {BFD_RELOC_ARM_LDRS_PC_G0, R_ARM_LDRS_PC_G0}, |
| {BFD_RELOC_ARM_LDRS_PC_G1, R_ARM_LDRS_PC_G1}, |
| {BFD_RELOC_ARM_LDRS_PC_G2, R_ARM_LDRS_PC_G2}, |
| {BFD_RELOC_ARM_LDC_PC_G0, R_ARM_LDC_PC_G0}, |
| {BFD_RELOC_ARM_LDC_PC_G1, R_ARM_LDC_PC_G1}, |
| {BFD_RELOC_ARM_LDC_PC_G2, R_ARM_LDC_PC_G2}, |
| {BFD_RELOC_ARM_ALU_SB_G0_NC, R_ARM_ALU_SB_G0_NC}, |
| {BFD_RELOC_ARM_ALU_SB_G0, R_ARM_ALU_SB_G0}, |
| {BFD_RELOC_ARM_ALU_SB_G1_NC, R_ARM_ALU_SB_G1_NC}, |
| {BFD_RELOC_ARM_ALU_SB_G1, R_ARM_ALU_SB_G1}, |
| {BFD_RELOC_ARM_ALU_SB_G2, R_ARM_ALU_SB_G2}, |
| {BFD_RELOC_ARM_LDR_SB_G0, R_ARM_LDR_SB_G0}, |
| {BFD_RELOC_ARM_LDR_SB_G1, R_ARM_LDR_SB_G1}, |
| {BFD_RELOC_ARM_LDR_SB_G2, R_ARM_LDR_SB_G2}, |
| {BFD_RELOC_ARM_LDRS_SB_G0, R_ARM_LDRS_SB_G0}, |
| {BFD_RELOC_ARM_LDRS_SB_G1, R_ARM_LDRS_SB_G1}, |
| {BFD_RELOC_ARM_LDRS_SB_G2, R_ARM_LDRS_SB_G2}, |
| {BFD_RELOC_ARM_LDC_SB_G0, R_ARM_LDC_SB_G0}, |
| {BFD_RELOC_ARM_LDC_SB_G1, R_ARM_LDC_SB_G1}, |
| {BFD_RELOC_ARM_LDC_SB_G2, R_ARM_LDC_SB_G2}, |
| {BFD_RELOC_ARM_V4BX, R_ARM_V4BX}, |
| {BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC, R_ARM_THM_ALU_ABS_G3_NC}, |
| {BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC, R_ARM_THM_ALU_ABS_G2_NC}, |
| {BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC, R_ARM_THM_ALU_ABS_G1_NC}, |
| {BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G0_NC}, |
| {BFD_RELOC_ARM_THUMB_BF17, R_ARM_THM_BF16}, |
| {BFD_RELOC_ARM_THUMB_BF13, R_ARM_THM_BF12}, |
| {BFD_RELOC_ARM_THUMB_BF19, R_ARM_THM_BF18} |
| }; |
| |
| static reloc_howto_type * |
| elf32_arm_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
| bfd_reloc_code_real_type code) |
| { |
| unsigned int i; |
| |
| for (i = 0; i < ARRAY_SIZE (elf32_arm_reloc_map); i ++) |
| if (elf32_arm_reloc_map[i].bfd_reloc_val == code) |
| return elf32_arm_howto_from_type (elf32_arm_reloc_map[i].elf_reloc_val); |
| |
| return NULL; |
| } |
| |
| static reloc_howto_type * |
| elf32_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
| const char *r_name) |
| { |
| unsigned int i; |
| |
| for (i = 0; i < ARRAY_SIZE (elf32_arm_howto_table_1); i++) |
| if (elf32_arm_howto_table_1[i].name != NULL |
| && strcasecmp (elf32_arm_howto_table_1[i].name, r_name) == 0) |
| return &elf32_arm_howto_table_1[i]; |
| |
| for (i = 0; i < ARRAY_SIZE (elf32_arm_howto_table_2); i++) |
| if (elf32_arm_howto_table_2[i].name != NULL |
| && strcasecmp (elf32_arm_howto_table_2[i].name, r_name) == 0) |
| return &elf32_arm_howto_table_2[i]; |
| |
| for (i = 0; i < ARRAY_SIZE (elf32_arm_howto_table_3); i++) |
| if (elf32_arm_howto_table_3[i].name != NULL |
| && strcasecmp (elf32_arm_howto_table_3[i].name, r_name) == 0) |
| return &elf32_arm_howto_table_3[i]; |
| |
| return NULL; |
| } |
| |
| /* Support for core dump NOTE sections. */ |
| |
| static bool |
| elf32_arm_nabi_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) |
| { |
| int offset; |
| size_t size; |
| |
| switch (note->descsz) |
| { |
| default: |
| return false; |
| |
| case 148: /* Linux/ARM 32-bit. */ |
| /* pr_cursig */ |
| elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12); |
| |
| /* pr_pid */ |
| elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24); |
| |
| /* pr_reg */ |
| offset = 72; |
| size = 72; |
| |
| break; |
| } |
| |
| /* Make a ".reg/999" section. */ |
| return _bfd_elfcore_make_pseudosection (abfd, ".reg", |
| size, note->descpos + offset); |
| } |
| |
| static bool |
| elf32_arm_nabi_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) |
| { |
| switch (note->descsz) |
| { |
| default: |
| return false; |
| |
| case 124: /* Linux/ARM elf_prpsinfo. */ |
| elf_tdata (abfd)->core->pid |
| = bfd_get_32 (abfd, note->descdata + 12); |
| elf_tdata (abfd)->core->program |
| = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16); |
| elf_tdata (abfd)->core->command |
| = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80); |
| } |
| |
| /* Note that for some reason, a spurious space is tacked |
| onto the end of the args in some (at least one anyway) |
| implementations, so strip it off if it exists. */ |
| { |
| char *command = elf_tdata (abfd)->core->command; |
| int n = strlen (command); |
| |
| if (0 < n && command[n - 1] == ' ') |
| command[n - 1] = '\0'; |
| } |
| |
| return true; |
| } |
| |
| static char * |
| elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz, |
| int note_type, ...) |
| { |
| switch (note_type) |
| { |
| default: |
| return NULL; |
| |
| case NT_PRPSINFO: |
| { |
| char data[124] ATTRIBUTE_NONSTRING; |
| va_list ap; |
| |
| va_start (ap, note_type); |
| memset (data, 0, sizeof (data)); |
| strncpy (data + 28, va_arg (ap, const char *), 16); |
| #if GCC_VERSION == 8000 || GCC_VERSION == 8001 |
| DIAGNOSTIC_PUSH; |
| /* GCC 8.0 and 8.1 warn about 80 equals destination size with |
| -Wstringop-truncation: |
| https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85643 |
| */ |
| DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION; |
| #endif |
| strncpy (data + 44, va_arg (ap, const char *), 80); |
| #if GCC_VERSION == 8000 || GCC_VERSION == 8001 |
| DIAGNOSTIC_POP; |
| #endif |
| va_end (ap); |
| |
| return elfcore_write_note (abfd, buf, bufsiz, |
| "CORE", note_type, data, sizeof (data)); |
| } |
| |
| case NT_PRSTATUS: |
| { |
| char data[148]; |
| va_list ap; |
| long pid; |
| int cursig; |
| const void *greg; |
| |
| va_start (ap, note_type); |
| memset (data, 0, sizeof (data)); |
| pid = va_arg (ap, long); |
| bfd_put_32 (abfd, pid, data + 24); |
| cursig = va_arg (ap, int); |
| bfd_put_16 (abfd, cursig, data + 12); |
| greg = va_arg (ap, const void *); |
| memcpy (data + 72, greg, 72); |
| va_end (ap); |
| |
| return elfcore_write_note (abfd, buf, bufsiz, |
| "CORE", note_type, data, sizeof (data)); |
| } |
| } |
| } |
| |
| #define TARGET_LITTLE_SYM arm_elf32_le_vec |
| #define TARGET_LITTLE_NAME "elf32-littlearm" |
| #define TARGET_BIG_SYM arm_elf32_be_vec |
| #define TARGET_BIG_NAME "elf32-bigarm" |
| |
| #define elf_backend_grok_prstatus elf32_arm_nabi_grok_prstatus |
| #define elf_backend_grok_psinfo elf32_arm_nabi_grok_psinfo |
| #define elf_backend_write_core_note elf32_arm_nabi_write_core_note |
| |
| typedef unsigned long int insn32; |
| typedef unsigned short int insn16; |
| |
| /* In lieu of proper flags, assume all EABIv4 or later objects are |
| interworkable. */ |
| #define INTERWORK_FLAG(abfd) \ |
| (EF_ARM_EABI_VERSION (elf_elfheader (abfd)->e_flags) >= EF_ARM_EABI_VER4 \ |
| || (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK) \ |
| || ((abfd)->flags & BFD_LINKER_CREATED)) |
| |
| /* The linker script knows the section names for placement. |
| The entry_names are used to do simple name mangling on the stubs. |
| Given a function name, and its type, the stub can be found. The |
| name can be changed. The only requirement is the %s be present. */ |
| #define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t" |
| #define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb" |
| |
| #define ARM2THUMB_GLUE_SECTION_NAME ".glue_7" |
| #define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm" |
| |
| #define VFP11_ERRATUM_VENEER_SECTION_NAME ".vfp11_veneer" |
| #define VFP11_ERRATUM_VENEER_ENTRY_NAME "__vfp11_veneer_%x" |
| |
| #define STM32L4XX_ERRATUM_VENEER_SECTION_NAME ".text.stm32l4xx_veneer" |
| #define STM32L4XX_ERRATUM_VENEER_ENTRY_NAME "__stm32l4xx_veneer_%x" |
| |
| #define ARM_BX_GLUE_SECTION_NAME ".v4_bx" |
| #define ARM_BX_GLUE_ENTRY_NAME "__bx_r%d" |
| |
| #define STUB_ENTRY_NAME "__%s_veneer" |
| |
| #define CMSE_PREFIX "__acle_se_" |
| |
| #define CMSE_STUB_NAME ".gnu.sgstubs" |
| |
| /* The name of the dynamic interpreter. This is put in the .interp |
| section. */ |
| #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" |
| |
| /* FDPIC default stack size. */ |
| #define DEFAULT_STACK_SIZE 0x8000 |
| |
| static const unsigned long tls_trampoline [] = |
| { |
| 0xe08e0000, /* add r0, lr, r0 */ |
| 0xe5901004, /* ldr r1, [r0,#4] */ |
| 0xe12fff11, /* bx r1 */ |
| }; |
| |
| static const unsigned long dl_tlsdesc_lazy_trampoline [] = |
| { |
| 0xe52d2004, /* push {r2} */ |
| 0xe59f200c, /* ldr r2, [pc, #3f - . - 8] */ |
| 0xe59f100c, /* ldr r1, [pc, #4f - . - 8] */ |
| 0xe79f2002, /* 1: ldr r2, [pc, r2] */ |
| 0xe081100f, /* 2: add r1, pc */ |
| 0xe12fff12, /* bx r2 */ |
| 0x00000014, /* 3: .word _GLOBAL_OFFSET_TABLE_ - 1b - 8 |
| + dl_tlsdesc_lazy_resolver(GOT) */ |
| 0x00000018, /* 4: .word _GLOBAL_OFFSET_TABLE_ - 2b - 8 */ |
| }; |
| |
| /* NOTE: [Thumb nop sequence] |
| When adding code that transitions from Thumb to Arm the instruction that |
| should be used for the alignment padding should be 0xe7fd (b .-2) instead of |
| a nop for performance reasons. */ |
| |
| /* ARM FDPIC PLT entry. */ |
| /* The last 5 words contain PLT lazy fragment code and data. */ |
| static const bfd_vma elf32_arm_fdpic_plt_entry [] = |
| { |
| 0xe59fc008, /* ldr r12, .L1 */ |
| 0xe08cc009, /* add r12, r12, r9 */ |
| 0xe59c9004, /* ldr r9, [r12, #4] */ |
| 0xe59cf000, /* ldr pc, [r12] */ |
| 0x00000000, /* L1. .word foo(GOTOFFFUNCDESC) */ |
| 0x00000000, /* L1. .word foo(funcdesc_value_reloc_offset) */ |
| 0xe51fc00c, /* ldr r12, [pc, #-12] */ |
| 0xe92d1000, /* push {r12} */ |
| 0xe599c004, /* ldr r12, [r9, #4] */ |
| 0xe599f000, /* ldr pc, [r9] */ |
| }; |
| |
| /* Thumb FDPIC PLT entry. */ |
| /* The last 5 words contain PLT lazy fragment code and data. */ |
| static const bfd_vma elf32_arm_fdpic_thumb_plt_entry [] = |
| { |
| 0xc00cf8df, /* ldr.w r12, .L1 */ |
| 0x0c09eb0c, /* add.w r12, r12, r9 */ |
| 0x9004f8dc, /* ldr.w r9, [r12, #4] */ |
| 0xf000f8dc, /* ldr.w pc, [r12] */ |
| 0x00000000, /* .L1 .word foo(GOTOFFFUNCDESC) */ |
| 0x00000000, /* .L2 .word foo(funcdesc_value_reloc_offset) */ |
| 0xc008f85f, /* ldr.w r12, .L2 */ |
| 0xcd04f84d, /* push {r12} */ |
| 0xc004f8d9, /* ldr.w r12, [r9, #4] */ |
| 0xf000f8d9, /* ldr.w pc, [r9] */ |
| }; |
| |
| #ifdef FOUR_WORD_PLT |
| |
| /* 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_plt0_entry [] = |
| { |
| 0xe52de004, /* str lr, [sp, #-4]! */ |
| 0xe59fe010, /* ldr lr, [pc, #16] */ |
| 0xe08fe00e, /* add lr, pc, lr */ |
| 0xe5bef008, /* ldr pc, [lr, #8]! */ |
| }; |
| |
| /* Subsequent entries in a procedure linkage table look like |
| this. */ |
| static const bfd_vma elf32_arm_plt_entry [] = |
| { |
| 0xe28fc600, /* add ip, pc, #NN */ |
| 0xe28cca00, /* add ip, ip, #NN */ |
| 0xe5bcf000, /* ldr pc, [ip, #NN]! */ |
| 0x00000000, /* unused */ |
| }; |
| |
| #else /* not FOUR_WORD_PLT */ |
| |
| /* 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_plt0_entry [] = |
| { |
| 0xe52de004, /* str lr, [sp, #-4]! */ |
| 0xe59fe004, /* ldr lr, [pc, #4] */ |
| 0xe08fe00e, /* add lr, pc, lr */ |
| 0xe5bef008, /* ldr pc, [lr, #8]! */ |
| 0x00000000, /* &GOT[0] - . */ |
| }; |
| |
| /* By default subsequent entries in a procedure linkage table look like |
| this. Offsets that don't fit into 28 bits will cause link error. */ |
| static const bfd_vma elf32_arm_plt_entry_short [] = |
| { |
| 0xe28fc600, /* add ip, pc, #0xNN00000 */ |
| 0xe28cca00, /* add ip, ip, #0xNN000 */ |
| 0xe5bcf000, /* ldr pc, [ip, #0xNNN]! */ |
| }; |
| |
| /* When explicitly asked, we'll use this "long" entry format |
| which can cope with arbitrary displacements. */ |
| static const bfd_vma elf32_arm_plt_entry_long [] = |
| { |
| 0xe28fc200, /* add ip, pc, #0xN0000000 */ |
| 0xe28cc600, /* add ip, ip, #0xNN00000 */ |
| 0xe28cca00, /* add ip, ip, #0xNN000 */ |
| 0xe5bcf000, /* ldr pc, [ip, #0xNNN]! */ |
| }; |
| |
| static bool elf32_arm_use_long_plt_entry = false; |
| |
| #endif /* not FOUR_WORD_PLT */ |
| |
| /* 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_thumb2_plt0_entry [] = |
| { |
| /* NOTE: As this is a mixture of 16-bit and 32-bit instructions, |
| an instruction maybe encoded to one or two array elements. */ |
| 0xf8dfb500, /* push {lr} */ |
| 0x44fee008, /* ldr.w lr, [pc, #8] */ |
| /* add lr, pc */ |
| 0xff08f85e, /* ldr.w pc, [lr, #8]! */ |
| 0x00000000, /* &GOT[0] - . */ |
| }; |
| |
| /* Subsequent entries in a procedure linkage table for thumb only target |
| look like this. */ |
| static const bfd_vma elf32_thumb2_plt_entry [] = |
| { |
| /* NOTE: As this is a mixture of 16-bit and 32-bit instructions, |
| an instruction maybe encoded to one or two array elements. */ |
| 0x0c00f240, /* movw ip, #0xNNNN */ |
| 0x0c00f2c0, /* movt ip, #0xNNNN */ |
| 0xf8dc44fc, /* add ip, pc */ |
| 0xe7fcf000 /* ldr.w pc, [ip] */ |
| /* b .-4 */ |
| }; |
| |
| /* The format of the first entry in the procedure linkage table |
| for a VxWorks executable. */ |
| static const bfd_vma elf32_arm_vxworks_exec_plt0_entry[] = |
| { |
| 0xe52dc008, /* str ip,[sp,#-8]! */ |
| 0xe59fc000, /* ldr ip,[pc] */ |
| 0xe59cf008, /* ldr pc,[ip,#8] */ |
| 0x00000000, /* .long _GLOBAL_OFFSET_TABLE_ */ |
| }; |
| |
| /* The format of subsequent entries in a VxWorks executable. */ |
| static const bfd_vma elf32_arm_vxworks_exec_plt_entry[] = |
| { |
| 0xe59fc000, /* ldr ip,[pc] */ |
| 0xe59cf000, /* ldr pc,[ip] */ |
| 0x00000000, /* .long @got */ |
| 0xe59fc000, /* ldr ip,[pc] */ |
| 0xea000000, /* b _PLT */ |
| 0x00000000, /* .long @pltindex*sizeof(Elf32_Rela) */ |
| }; |
| |
| /* The format of entries in a VxWorks shared library. */ |
| static const bfd_vma elf32_arm_vxworks_shared_plt_entry[] = |
| { |
| 0xe59fc000, /* ldr ip,[pc] */ |
| 0xe79cf009, /* ldr pc,[ip,r9] */ |
| 0x00000000, /* .long @got */ |
| 0xe59fc000, /* ldr ip,[pc] */ |
| 0xe599f008, /* ldr pc,[r9,#8] */ |
| 0x00000000, /* .long @pltindex*sizeof(Elf32_Rela) */ |
| }; |
| |
| /* An initial stub used if the PLT entry is referenced from Thumb code. */ |
| #define PLT_THUMB_STUB_SIZE 4 |
| static const bfd_vma elf32_arm_plt_thumb_stub [] = |
| { |
| 0x4778, /* bx pc */ |
| 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 |
| is not available, and second macro when Thumb-2 is available. Among other |
| things, they affect the range of branches represented as BLX instructions |
| in Encoding T2 defined in Section A8.8.25 of the ARM Architecture |
| Reference Manual ARMv7-A and ARMv7-R edition issue C.d. Such branches are |
| specified there to have a maximum forward offset that is a multiple of 4. |
| Previously, the respective values defined here were multiples of 2 but not |
| 4 and they are included in comments for reference. */ |
| #define ARM_MAX_FWD_BRANCH_OFFSET ((((1 << 23) - 1) << 2) + 8) |
| #define ARM_MAX_BWD_BRANCH_OFFSET ((-((1 << 23) << 2)) + 8) |
| #define THM_MAX_FWD_BRANCH_OFFSET ((1 << 22) - 4 + 4) |
| /* #def THM_MAX_FWD_BRANCH_OFFSET ((1 << 22) - 2 + 4) */ |
| #define THM_MAX_BWD_BRANCH_OFFSET (-(1 << 22) + 4) |
| #define THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 4) + 4) |
| /* #def THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 2) + 4) */ |
| #define THM2_MAX_BWD_BRANCH_OFFSET (-(1 << 24) + 4) |
| #define THM2_MAX_FWD_COND_BRANCH_OFFSET (((1 << 20) -2) + 4) |
| #define THM2_MAX_BWD_COND_BRANCH_OFFSET (-(1 << 20) + 4) |
| |
| enum stub_insn_type |
| { |
| THUMB16_TYPE = 1, |
| THUMB32_TYPE, |
| ARM_TYPE, |
| DATA_TYPE |
| }; |
| |
| #define THUMB16_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 0} |
| /* A bit of a hack. A Thumb conditional branch, in which the proper condition |
| is inserted in arm_build_one_stub(). */ |
| #define THUMB16_BCOND_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 1} |
| #define THUMB32_INSN(X) {(X), THUMB32_TYPE, R_ARM_NONE, 0} |
| #define THUMB32_MOVT(X) {(X), THUMB32_TYPE, R_ARM_THM_MOVT_ABS, 0} |
| #define THUMB32_MOVW(X) {(X), THUMB32_TYPE, R_ARM_THM_MOVW_ABS_NC, 0} |
| #define THUMB32_B_INSN(X, Z) {(X), THUMB32_TYPE, R_ARM_THM_JUMP24, (Z)} |
| #define ARM_INSN(X) {(X), ARM_TYPE, R_ARM_NONE, 0} |
| #define ARM_REL_INSN(X, Z) {(X), ARM_TYPE, R_ARM_JUMP24, (Z)} |
| #define DATA_WORD(X,Y,Z) {(X), DATA_TYPE, (Y), (Z)} |
| |
| typedef struct |
| { |
| bfd_vma data; |
| enum stub_insn_type type; |
| unsigned int r_type; |
| int reloc_addend; |
| } insn_sequence; |
| |
| /* See note [Thumb nop sequence] when adding a veneer. */ |
| |
| /* Arm/Thumb -> Arm/Thumb long branch stub. On V5T and above, use blx |
| to reach the stub if necessary. */ |
| static const insn_sequence elf32_arm_stub_long_branch_any_any[] = |
| { |
| ARM_INSN (0xe51ff004), /* ldr pc, [pc, #-4] */ |
| DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ |
| }; |
| |
| /* V4T Arm -> Thumb long branch stub. Used on V4T where blx is not |
| available. */ |
| static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb[] = |
| { |
| ARM_INSN (0xe59fc000), /* ldr ip, [pc, #0] */ |
| ARM_INSN (0xe12fff1c), /* bx ip */ |
| DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ |
| }; |
| |
| /* Thumb -> Thumb long branch stub. Used on M-profile architectures. */ |
| static const insn_sequence elf32_arm_stub_long_branch_thumb_only[] = |
| { |
| THUMB16_INSN (0xb401), /* push {r0} */ |
| THUMB16_INSN (0x4802), /* ldr r0, [pc, #8] */ |
| THUMB16_INSN (0x4684), /* mov ip, r0 */ |
| THUMB16_INSN (0xbc01), /* pop {r0} */ |
| THUMB16_INSN (0x4760), /* bx ip */ |
| THUMB16_INSN (0xbf00), /* nop */ |
| DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ |
| }; |
| |
| /* Thumb -> Thumb long branch stub in thumb2 encoding. Used on armv7. */ |
| static const insn_sequence elf32_arm_stub_long_branch_thumb2_only[] = |
| { |
| THUMB32_INSN (0xf85ff000), /* ldr.w pc, [pc, #-0] */ |
| DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(x) */ |
| }; |
| |
| /* Thumb -> Thumb long branch stub. Used for PureCode sections on Thumb2 |
| M-profile architectures. */ |
| static const insn_sequence elf32_arm_stub_long_branch_thumb2_only_pure[] = |
| { |
| THUMB32_MOVW (0xf2400c00), /* mov.w ip, R_ARM_MOVW_ABS_NC */ |
| THUMB32_MOVT (0xf2c00c00), /* movt ip, R_ARM_MOVT_ABS << 16 */ |
| THUMB16_INSN (0x4760), /* bx ip */ |
| }; |
| |
| /* V4T Thumb -> Thumb long branch stub. Using the stack is not |
| allowed. */ |
| static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb[] = |
| { |
| THUMB16_INSN (0x4778), /* bx pc */ |
| THUMB16_INSN (0xe7fd), /* b .-2 */ |
| ARM_INSN (0xe59fc000), /* ldr ip, [pc, #0] */ |
| ARM_INSN (0xe12fff1c), /* bx ip */ |
| DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ |
| }; |
| |
| /* V4T Thumb -> ARM long branch stub. Used on V4T where blx is not |
| available. */ |
| static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm[] = |
| { |
| THUMB16_INSN (0x4778), /* bx pc */ |
| THUMB16_INSN (0xe7fd), /* b .-2 */ |
| ARM_INSN (0xe51ff004), /* ldr pc, [pc, #-4] */ |
| DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */ |
| }; |
| |
| /* V4T Thumb -> ARM short branch stub. Shorter variant of the above |
| one, when the destination is close enough. */ |
| static const insn_sequence elf32_arm_stub_short_branch_v4t_thumb_arm[] = |
| { |
| THUMB16_INSN (0x4778), /* bx pc */ |
| THUMB16_INSN (0xe7fd), /* b .-2 */ |
| ARM_REL_INSN (0xea000000, -8), /* b (X-8) */ |
| }; |
| |
| /* ARM/Thumb -> ARM long branch stub, PIC. On V5T and above, use |
| blx to reach the stub if necessary. */ |
| static const insn_sequence elf32_arm_stub_long_branch_any_arm_pic[] = |
| { |
| ARM_INSN (0xe59fc000), /* ldr ip, [pc] */ |
| ARM_INSN (0xe08ff00c), /* add pc, pc, ip */ |
| DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X-4) */ |
| }; |
| |
| /* ARM/Thumb -> Thumb long branch stub, PIC. On V5T and above, use |
| blx to reach the stub if necessary. We can not add into pc; |
| it is not guaranteed to mode switch (different in ARMv6 and |
| ARMv7). */ |
| static const insn_sequence elf32_arm_stub_long_branch_any_thumb_pic[] = |
| { |
| ARM_INSN (0xe59fc004), /* ldr ip, [pc, #4] */ |
| ARM_INSN (0xe08fc00c), /* add ip, pc, ip */ |
| ARM_INSN (0xe12fff1c), /* bx ip */ |
| DATA_WORD (0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ |
| }; |
| |
| /* V4T ARM -> ARM long branch stub, PIC. */ |
| static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] = |
| { |
| ARM_INSN (0xe59fc004), /* ldr ip, [pc, #4] */ |
| ARM_INSN (0xe08fc00c), /* add ip, pc, ip */ |
| ARM_INSN (0xe12fff1c), /* bx ip */ |
| DATA_WORD (0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ |
| }; |
| |
| /* V4T Thumb -> ARM long branch stub, PIC. */ |
| static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] = |
| { |
| THUMB16_INSN (0x4778), /* bx pc */ |
| THUMB16_INSN (0xe7fd), /* b .-2 */ |
| ARM_INSN (0xe59fc000), /* ldr ip, [pc, #0] */ |
| ARM_INSN (0xe08cf00f), /* add pc, ip, pc */ |
| DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X) */ |
| }; |
| |
| /* Thumb -> Thumb long branch stub, PIC. Used on M-profile |
| architectures. */ |
| static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] = |
| { |
| THUMB16_INSN (0xb401), /* push {r0} */ |
| THUMB16_INSN (0x4802), /* ldr r0, [pc, #8] */ |
| THUMB16_INSN (0x46fc), /* mov ip, pc */ |
| THUMB16_INSN (0x4484), /* add ip, r0 */ |
| THUMB16_INSN (0xbc01), /* pop {r0} */ |
| THUMB16_INSN (0x4760), /* bx ip */ |
| DATA_WORD (0, R_ARM_REL32, 4), /* dcd R_ARM_REL32(X) */ |
| }; |
| |
| /* V4T Thumb -> Thumb long branch stub, PIC. Using the stack is not |
| allowed. */ |
| static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb_pic[] = |
| { |
| THUMB16_INSN (0x4778), /* bx pc */ |
| THUMB16_INSN (0xe7fd), /* b .-2 */ |
| ARM_INSN (0xe59fc004), /* ldr ip, [pc, #4] */ |
| ARM_INSN (0xe08fc00c), /* add ip, pc, ip */ |
| ARM_INSN (0xe12fff1c), /* bx ip */ |
| DATA_WORD (0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */ |
| }; |
| |
| /* Thumb2/ARM -> TLS trampoline. Lowest common denominator, which is a |
| long PIC stub. We can use r1 as a scratch -- and cannot use ip. */ |
| static const insn_sequence elf32_arm_stub_long_branch_any_tls_pic[] = |
| { |
| ARM_INSN (0xe59f1000), /* ldr r1, [pc] */ |
| ARM_INSN (0xe08ff001), /* add pc, pc, r1 */ |
| DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X-4) */ |
| }; |
| |
| /* V4T Thumb -> TLS trampoline. lowest common denominator, which is a |
| long PIC stub. We can use r1 as a scratch -- and cannot use ip. */ |
| static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_tls_pic[] = |
| { |
| THUMB16_INSN (0x4778), /* bx pc */ |
| THUMB16_INSN (0xe7fd), /* b .-2 */ |
| ARM_INSN (0xe59f1000), /* ldr r1, [pc, #0] */ |
| ARM_INSN (0xe081f00f), /* add pc, r1, pc */ |
| 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[] = |
| { |
| THUMB32_INSN (0xe97fe97f), /* sg. */ |
| THUMB32_B_INSN (0xf000b800, -4), /* b.w original_branch_dest. */ |
| }; |
| |
| |
| /* Cortex-A8 erratum-workaround stubs. */ |
| |
| /* Stub used for conditional branches (which may be beyond +/-1MB away, so we |
| can't use a conditional branch to reach this stub). */ |
| |
| static const insn_sequence elf32_arm_stub_a8_veneer_b_cond[] = |
| { |
| THUMB16_BCOND_INSN (0xd001), /* b<cond>.n true. */ |
| THUMB32_B_INSN (0xf000b800, -4), /* b.w insn_after_original_branch. */ |
| THUMB32_B_INSN (0xf000b800, -4) /* true: b.w original_branch_dest. */ |
| }; |
| |
| /* Stub used for b.w and bl.w instructions. */ |
| |
| static const insn_sequence elf32_arm_stub_a8_veneer_b[] = |
| { |
| THUMB32_B_INSN (0xf000b800, -4) /* b.w original_branch_dest. */ |
| }; |
| |
| static const insn_sequence elf32_arm_stub_a8_veneer_bl[] = |
| { |
| THUMB32_B_INSN (0xf000b800, -4) /* b.w original_branch_dest. */ |
| }; |
| |
| /* Stub used for Thumb-2 blx.w instructions. We modified the original blx.w |
| instruction (which switches to ARM mode) to point to this stub. Jump to the |
| real destination using an ARM-mode branch. */ |
| |
| static const insn_sequence elf32_arm_stub_a8_veneer_blx[] = |
| { |
| ARM_REL_INSN (0xea000000, -8) /* b original_branch_dest. */ |
| }; |
| |
| /* For each section group there can be a specially created linker section |
| to hold the stubs for that group. The name of the stub section is based |
| upon the name of another section within that group with the suffix below |
| applied. |
| |
| PR 13049: STUB_SUFFIX used to be ".stub", but this allowed the user to |
| create what appeared to be a linker stub section when it actually |
| contained user code/data. For example, consider this fragment: |
| |
| const char * stubborn_problems[] = { "np" }; |
| |
| If this is compiled with "-fPIC -fdata-sections" then gcc produces a |
| section called: |
| |
| .data.rel.local.stubborn_problems |
| |
| This then causes problems in arm32_arm_build_stubs() as it triggers: |
| |
| // Ignore non-stub sections. |
| if (!strstr (stub_sec->name, STUB_SUFFIX)) |
| continue; |
| |
| And so the section would be ignored instead of being processed. Hence |
| the change in definition of STUB_SUFFIX to a name that cannot be a valid |
| C identifier. */ |
| #define STUB_SUFFIX ".__stub" |
| |
| /* One entry per long/short branch stub defined above. */ |
| #define DEF_STUBS \ |
| DEF_STUB (long_branch_any_any) \ |
| DEF_STUB (long_branch_v4t_arm_thumb) \ |
| DEF_STUB (long_branch_thumb_only) \ |
| DEF_STUB (long_branch_v4t_thumb_thumb) \ |
| DEF_STUB (long_branch_v4t_thumb_arm) \ |
| DEF_STUB (short_branch_v4t_thumb_arm) \ |
| DEF_STUB (long_branch_any_arm_pic) \ |
| DEF_STUB (long_branch_any_thumb_pic) \ |
| DEF_STUB (long_branch_v4t_thumb_thumb_pic) \ |
| DEF_STUB (long_branch_v4t_arm_thumb_pic) \ |
| DEF_STUB (long_branch_v4t_thumb_arm_pic) \ |
| 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) \ |
| DEF_STUB (a8_veneer_bl) \ |
| DEF_STUB (a8_veneer_blx) \ |
| DEF_STUB (long_branch_thumb2_only) \ |
| DEF_STUB (long_branch_thumb2_only_pure) |
| |
| #define DEF_STUB(x) arm_stub_##x, |
| enum elf32_arm_stub_type |
| { |
| arm_stub_none, |
| DEF_STUBS |
| max_stub_type |
| }; |
| #undef DEF_STUB |
| |
| /* Note the first a8_veneer type. */ |
| const unsigned arm_stub_a8_veneer_lwm = arm_stub_a8_veneer_b_cond; |
| |
| typedef struct |
| { |
| const insn_sequence* template_sequence; |
| int template_size; |
| } stub_def; |
| |
| #define DEF_STUB(x) {elf32_arm_stub_##x, ARRAY_SIZE(elf32_arm_stub_##x)}, |
| static const stub_def stub_definitions[] = |
| { |
| {NULL, 0}, |
| DEF_STUBS |
| }; |
| |
| struct elf32_arm_stub_hash_entry |
| { |
| /* Base hash table entry structure. */ |
| struct bfd_hash_entry root; |
| |
| /* The stub section. */ |
| asection *stub_sec; |
| |
| /* Offset within stub_sec of the beginning of this stub. */ |
| bfd_vma stub_offset; |
| |
| /* Given the symbol's value and its section we can determine its final |
| value when building the stubs (so the stub knows where to jump). */ |
| bfd_vma target_value; |
| asection *target_section; |
| |
| /* Same as above but for the source of the branch to the stub. Used for |
| Cortex-A8 erratum workaround to patch it to branch to the stub. As |
| such, source section does not need to be recorded since Cortex-A8 erratum |
| workaround stubs are only generated when both source and target are in the |
| same section. */ |
| bfd_vma source_value; |
| |
| /* The instruction which caused this stub to be generated (only valid for |
| Cortex-A8 erratum workaround stubs at present). */ |
| unsigned long orig_insn; |
| |
| /* The stub type. */ |
| enum elf32_arm_stub_type stub_type; |
| /* Its encoding size in bytes. */ |
| int stub_size; |
| /* Its template. */ |
| const insn_sequence *stub_template; |
| /* The size of the template (number of entries). */ |
| int stub_template_size; |
| |
| /* The symbol table entry, if any, that this was derived from. */ |
| struct elf32_arm_link_hash_entry *h; |
| |
| /* Type of branch. */ |
| enum arm_st_branch_type branch_type; |
| |
| /* Where this stub is being called from, or, in the case of combined |
| stub sections, the first input section in the group. */ |
| asection *id_sec; |
| |
| /* The name for the local symbol at the start of this stub. The |
| stub name in the hash table has to be unique; this does not, so |
| it can be friendlier. */ |
| char *output_name; |
| }; |
| |
| /* Used to build a map of a section. This is required for mixed-endian |
| code/data. */ |
| |
| typedef struct elf32_elf_section_map |
| { |
| bfd_vma vma; |
| char type; |
| } |
| elf32_arm_section_map; |
| |
| /* Information about a VFP11 erratum veneer, or a branch to such a veneer. */ |
| |
| typedef enum |
| { |
| VFP11_ERRATUM_BRANCH_TO_ARM_VENEER, |
| VFP11_ERRATUM_BRANCH_TO_THUMB_VENEER, |
| VFP11_ERRATUM_ARM_VENEER, |
| VFP11_ERRATUM_THUMB_VENEER |
| } |
| elf32_vfp11_erratum_type; |
| |
| typedef struct elf32_vfp11_erratum_list |
| { |
| struct elf32_vfp11_erratum_list *next; |
| bfd_vma vma; |
| union |
| { |
| struct |
| { |
| struct elf32_vfp11_erratum_list *veneer; |
| unsigned int vfp_insn; |
| } b; |
| struct |
| { |
| struct elf32_vfp11_erratum_list *branch; |
| unsigned int id; |
| } v; |
| } u; |
| elf32_vfp11_erratum_type type; |
| } |
| elf32_vfp11_erratum_list; |
| |
| /* Information about a STM32L4XX erratum veneer, or a branch to such a |
| veneer. */ |
| typedef enum |
| { |
| STM32L4XX_ERRATUM_BRANCH_TO_VENEER, |
| STM32L4XX_ERRATUM_VENEER |
| } |
| elf32_stm32l4xx_erratum_type; |
| |
| typedef struct elf32_stm32l4xx_erratum_list |
| { |
| struct elf32_stm32l4xx_erratum_list *next; |
| bfd_vma vma; |
| union |
| { |
| struct |
| { |
| struct elf32_stm32l4xx_erratum_list *veneer; |
| unsigned int insn; |
| } b; |
| struct |
| { |
| struct elf32_stm32l4xx_erratum_list *branch; |
| unsigned int id; |
| } v; |
| } u; |
| elf32_stm32l4xx_erratum_type type; |
| } |
| elf32_stm32l4xx_erratum_list; |
| |
| typedef enum |
| { |
| DELETE_EXIDX_ENTRY, |
| INSERT_EXIDX_CANTUNWIND_AT_END |
| } |
| arm_unwind_edit_type; |
| |
| /* A (sorted) list of edits to apply to an unwind table. */ |
| typedef struct arm_unwind_table_edit |
| { |
| arm_unwind_edit_type type; |
| /* Note: we sometimes want to insert an unwind entry corresponding to a |
| section different from the one we're currently writing out, so record the |
| (text) section this edit relates to here. */ |
| asection *linked_section; |
| unsigned int index; |
| struct arm_unwind_table_edit *next; |
| } |
| arm_unwind_table_edit; |
| |
| typedef struct _arm_elf_section_data |
| { |
| /* Information about mapping symbols. */ |
| struct bfd_elf_section_data elf; |
| unsigned int mapcount; |
| unsigned int mapsize; |
| elf32_arm_section_map *map; |
| /* Information about CPU errata. */ |
| unsigned int erratumcount; |
| elf32_vfp11_erratum_list *erratumlist; |
| unsigned int stm32l4xx_erratumcount; |
| elf32_stm32l4xx_erratum_list *stm32l4xx_erratumlist; |
| unsigned int additional_reloc_count; |
| /* Information about unwind tables. */ |
| union |
| { |
| /* Unwind info attached to a text section. */ |
| struct |
| { |
| asection *arm_exidx_sec; |
| } text; |
| |
| /* Unwind info attached to an .ARM.exidx section. */ |
| struct |
| { |
| arm_unwind_table_edit *unwind_edit_list; |
| arm_unwind_table_edit *unwind_edit_tail; |
| } exidx; |
| } u; |
| } |
| _arm_elf_section_data; |
| |
| #define elf32_arm_section_data(sec) \ |
| ((_arm_elf_section_data *) elf_section_data (sec)) |
| |
| /* A fix which might be required for Cortex-A8 Thumb-2 branch/TLB erratum. |
| These fixes are subject to a relaxation procedure (in elf32_arm_size_stubs), |
| so may be created multiple times: we use an array of these entries whilst |
| relaxing which we can refresh easily, then create stubs for each potentially |
| erratum-triggering instruction once we've settled on a solution. */ |
| |
| struct a8_erratum_fix |
| { |
| bfd *input_bfd; |
| asection *section; |
| bfd_vma offset; |
| bfd_vma target_offset; |
| unsigned long orig_insn; |
| char *stub_name; |
| enum elf32_arm_stub_type stub_type; |
| enum arm_st_branch_type branch_type; |
| }; |
| |
| /* A table of relocs applied to branches which might trigger Cortex-A8 |
| erratum. */ |
| |
| struct a8_erratum_reloc |
| { |
| bfd_vma from; |
| bfd_vma destination; |
| struct elf32_arm_link_hash_entry *hash; |
| const char *sym_name; |
| unsigned int r_type; |
| enum arm_st_branch_type branch_type; |
| bool non_a8_stub; |
| }; |
| |
| /* The size of the thread control block. */ |
| #define TCB_SIZE 8 |
| |
| /* ARM-specific information about a PLT entry, over and above the usual |
| gotplt_union. */ |
| struct arm_plt_info |
| { |
| /* We reference count Thumb references to a PLT entry separately, |
| so that we can emit the Thumb trampoline only if needed. */ |
| bfd_signed_vma thumb_refcount; |
| |
| /* Some references from Thumb code may be eliminated by BL->BLX |
| conversion, so record them separately. */ |
| bfd_signed_vma maybe_thumb_refcount; |
| |
| /* How many of the recorded PLT accesses were from non-call relocations. |
| This information is useful when deciding whether anything takes the |
| address of an STT_GNU_IFUNC PLT. A value of 0 means that all |
| non-call references to the function should resolve directly to the |
| real runtime target. */ |
| unsigned int noncall_refcount; |
| |
| /* Since PLT entries have variable size if the Thumb prologue is |
| used, we need to record the index into .got.plt instead of |
| recomputing it from the PLT offset. */ |
| bfd_signed_vma got_offset; |
| }; |
| |
| /* Information about an .iplt entry for a local STT_GNU_IFUNC symbol. */ |
| struct arm_local_iplt_info |
| { |
| /* The information that is usually found in the generic ELF part of |
| the hash table entry. */ |
| union gotplt_union root; |
| |
| /* The information that is usually found in the ARM-specific part of |
| the hash table entry. */ |
| struct arm_plt_info arm; |
| |
| /* A list of all potential dynamic relocations against this symbol. */ |
| struct elf_dyn_relocs *dyn_relocs; |
| }; |
| |
| /* Structure to handle FDPIC support for local functions. */ |
| struct fdpic_local |
| { |
| unsigned int funcdesc_cnt; |
| unsigned int gotofffuncdesc_cnt; |
| int funcdesc_offset; |
| }; |
| |
| struct elf_arm_obj_tdata |
| { |
| struct elf_obj_tdata root; |
| |
| /* Zero to warn when linking objects with incompatible enum sizes. */ |
| int no_enum_size_warning; |
| |
| /* Zero to warn when linking objects with incompatible wchar_t sizes. */ |
| int no_wchar_size_warning; |
| |
| /* The number of entries in each of the arrays in this strcuture. |
| Used to avoid buffer overruns. */ |
| bfd_size_type num_entries; |
| |
| /* tls_type for each local got entry. */ |
| char *local_got_tls_type; |
| |
| /* GOTPLT entries for TLS descriptors. */ |
| bfd_vma *local_tlsdesc_gotent; |
| |
| /* Information for local symbols that need entries in .iplt. */ |
| struct arm_local_iplt_info **local_iplt; |
| |
| /* Maintains FDPIC counters and funcdesc info. */ |
| struct fdpic_local *local_fdpic_cnts; |
| }; |
| |
| #define elf_arm_tdata(bfd) \ |
| ((struct elf_arm_obj_tdata *) (bfd)->tdata.any) |
| |
| #define elf32_arm_num_entries(bfd) \ |
| (elf_arm_tdata (bfd)->num_entries) |
| |
| #define elf32_arm_local_got_tls_type(bfd) \ |
| (elf_arm_tdata (bfd)->local_got_tls_type) |
| |
| #define elf32_arm_local_tlsdesc_gotent(bfd) \ |
| (elf_arm_tdata (bfd)->local_tlsdesc_gotent) |
| |
| #define elf32_arm_local_iplt(bfd) \ |
| (elf_arm_tdata (bfd)->local_iplt) |
| |
| #define elf32_arm_local_fdpic_cnts(bfd) \ |
| (elf_arm_tdata (bfd)->local_fdpic_cnts) |
| |
| #define is_arm_elf(bfd) \ |
| (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ |
| && elf_tdata (bfd) != NULL \ |
| && elf_object_id (bfd) == ARM_ELF_DATA) |
| |
| static bool |
| elf32_arm_mkobject (bfd *abfd) |
| { |
| return bfd_elf_allocate_object (abfd, sizeof (struct elf_arm_obj_tdata), |
| ARM_ELF_DATA); |
| } |
| |
| #define elf32_arm_hash_entry(ent) ((struct elf32_arm_link_hash_entry *)(ent)) |
| |
| /* Structure to handle FDPIC support for extern functions. */ |
| struct fdpic_global { |
| unsigned int gotofffuncdesc_cnt; |
| unsigned int gotfuncdesc_cnt; |
| unsigned int funcdesc_cnt; |
| int funcdesc_offset; |
| int gotfuncdesc_offset; |
| }; |
| |
| /* Arm ELF linker hash entry. */ |
| struct elf32_arm_link_hash_entry |
| { |
| struct elf_link_hash_entry root; |
| |
| /* ARM-specific PLT information. */ |
| struct arm_plt_info plt; |
| |
| #define GOT_UNKNOWN 0 |
| #define GOT_NORMAL 1 |
| #define GOT_TLS_GD 2 |
| #define GOT_TLS_IE 4 |
| #define GOT_TLS_GDESC 8 |
| #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLS_GDESC)) |
| unsigned int tls_type : 8; |
| |
|