blob: 2cb8768868b30ce1a228f8bd73e4e416b9de4b9b [file] [log] [blame]
/* 32-bit ELF support for ARM
Copyright (C) 1998-2021 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 */
3, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
0, /* size (0 = byte, 1 = short, 2 = long) */
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 */
1, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
1, /* size (0 = byte, 1 = short, 2 = long) */
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 */
0, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
1, /* size (0 = byte, 1 = short, 2 = long) */
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 */
1, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
1, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
1, /* size (0 = byte, 1 = short, 2 = long) */
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 */
1, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
1, /* size (0 = byte, 1 = short, 2 = long) */
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. */
1, /* size (0 = byte, 1 = short, 2 = long). */
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. */
1, /* size (0 = byte, 1 = short, 2 = long). */
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. */
1, /* size (0 = byte, 1 = short, 2 = long). */
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. */
1, /* size (0 = byte, 1 = short, 2 = long). */
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. */
1, /* size (0 = byte, 1 = short, 2 = long). */
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. */
1, /* size (0 = byte, 1 = short, 2 = long). */
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. */
1, /* size (0 = byte, 1 = short, 2 = long). */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 */
2, /* size (0 = byte, 1 = short, 2 = long) */
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 = byte, 1 = short, 2 = long) */
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 = byte, 1 = short, 2 = long) */
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 = byte, 1 = short, 2 = long) */
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 = byte, 1 = short, 2 = long) */
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 */
};
#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) -2 + 4)
#define THM_MAX_BWD_BRANCH_OFFSET (-(1 << 22) + 4)
#define 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<