#define ARM_ELF_ABI_VERSION 0
#define ARM_ELF_OS_ABI_VERSION ELFOSABI_ARM
-static reloc_howto_type * elf32_arm_reloc_type_lookup
- PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
-static bfd_boolean elf32_arm_nabi_grok_prstatus
- PARAMS ((bfd *abfd, Elf_Internal_Note *note));
-static bfd_boolean elf32_arm_nabi_grok_psinfo
- PARAMS ((bfd *abfd, Elf_Internal_Note *note));
-
/* 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[] =
+static reloc_howto_type elf32_arm_howto_table_1[] =
{
/* No relocation */
HOWTO (R_ARM_NONE, /* type */
0xffffffff, /* dst_mask */
TRUE), /* pcrel_offset */
- /* 8 bit absolute */
+ /* 8 bit absolute - R_ARM_LDR_PC_G0 in AAELF */
HOWTO (R_ARM_PC13, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
- HOWTO (R_ARM_THM_PC22, /* type */
+ /* FIXME: Has two more bits of offset in Thumb32. */
+ HOWTO (R_ARM_THM_CALL, /* type */
1, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
23, /* bitsize */
0, /* bitpos */
complain_overflow_signed,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_ARM_THM_PC22", /* name */
+ "R_ARM_THM_CALL", /* name */
FALSE, /* partial_inplace */
0x07ff07ff, /* src_mask */
0x07ff07ff, /* dst_mask */
0x000000ff, /* dst_mask */
TRUE), /* pcrel_offset */
- HOWTO (R_ARM_AMP_VCALL9, /* type */
+ HOWTO (R_ARM_BREL_ADJ, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
- 8, /* bitsize */
- TRUE, /* pc_relative */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_ARM_AMP_VCALL9", /* name */
+ "R_ARM_BREL_ADJ", /* name */
FALSE, /* partial_inplace */
- 0x000000ff, /* src_mask */
- 0x000000ff, /* dst_mask */
- TRUE), /* pcrel_offset */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
HOWTO (R_ARM_SWI24, /* type */
0, /* rightshift */
0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
- HOWTO (R_ARM_GOTOFF, /* type */
+ HOWTO (R_ARM_GOTOFF32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
0, /* bitpos */
complain_overflow_bitfield,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_ARM_GOTOFF", /* name */
+ "R_ARM_GOTOFF32", /* name */
TRUE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
0x00ffffff, /* dst_mask */
TRUE), /* pcrel_offset */
- HOWTO (R_ARM_NONE, /* type */
- 0, /* rightshift */
- 0, /* size (0 = byte, 1 = short, 2 = long) */
- 0, /* bitsize */
- FALSE, /* pc_relative */
+ 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_dont,/* complain_on_overflow */
+ complain_overflow_signed,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_ARM_unknown_30", /* name */
+ "R_ARM_THM_JUMP24", /* name */
FALSE, /* partial_inplace */
- 0, /* src_mask */
- 0, /* dst_mask */
- FALSE), /* pcrel_offset */
+ 0x07ff2fff, /* src_mask */
+ 0x07ff2fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
- HOWTO (R_ARM_NONE, /* type */
+ HOWTO (R_ARM_BASE_ABS, /* type */
0, /* rightshift */
- 0, /* size (0 = byte, 1 = short, 2 = long) */
- 0, /* bitsize */
+ 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_unknown_31", /* name */
+ "R_ARM_BASE_ABS", /* name */
FALSE, /* partial_inplace */
- 0, /* src_mask */
- 0, /* dst_mask */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
FALSE), /* pcrel_offset */
HOWTO (R_ARM_ALU_PCREL7_0, /* type */
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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_ALU_PREL_11_0",/* name */
+ FALSE, /* partial_inplace */
+ 0x040070ff, /* src_mask */
+ 0x040070ff, /* 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_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_PC12", /* name */
+ FALSE, /* partial_inplace */
+ 0x040070ff, /* src_mask */
+ 0x040070ff, /* 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 */
};
-static reloc_howto_type elf32_arm_tls_gd32_howto =
- HOWTO (R_ARM_TLS_GD32, /* type */
+/* Relocations 57 .. 83 are the "group relocations" which we do not
+ support. */
+
+static reloc_howto_type elf32_arm_howto_table_2[] =
+{
+ 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 */
+
+ EMPTY_HOWTO (90), /* unallocated */
+ EMPTY_HOWTO (91),
+ EMPTY_HOWTO (92),
+ EMPTY_HOWTO (93),
+
+ 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) */
- 32, /* bitsize */
+ 0, /* 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 */
+ 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 */
-static reloc_howto_type elf32_arm_tls_ldo32_howto =
- HOWTO (R_ARM_TLS_LDO32, /* type */
+ /* 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 */
- bfd_elf_generic_reloc, /* special_function */
- "R_ARM_TLS_LDO32", /* name */
+ NULL, /* special_function */
+ "R_ARM_TLS_GD32", /* name */
TRUE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE); /* pcrel_offset */
+ FALSE), /* pcrel_offset */
-static reloc_howto_type elf32_arm_tls_ldm32_howto =
HOWTO (R_ARM_TLS_LDM32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
TRUE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE); /* pcrel_offset */
+ FALSE), /* pcrel_offset */
-static reloc_howto_type elf32_arm_tls_le32_howto =
- HOWTO (R_ARM_TLS_LE32, /* type */
+ HOWTO (R_ARM_TLS_LDO32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
0, /* bitpos */
complain_overflow_bitfield,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_ARM_TLS_LE32", /* name */
+ "R_ARM_TLS_LDO32", /* name */
TRUE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE); /* pcrel_offset */
+ FALSE), /* pcrel_offset */
-static reloc_howto_type elf32_arm_tls_ie32_howto =
HOWTO (R_ARM_TLS_IE32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
TRUE, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
- FALSE); /* pcrel_offset */
-
- /* GNU extension to record C++ vtable hierarchy */
-static reloc_howto_type elf32_arm_vtinherit_howto =
- 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 */
+ FALSE), /* pcrel_offset */
- /* GNU extension to record C++ vtable member usage */
-static reloc_howto_type elf32_arm_vtentry_howto =
- HOWTO (R_ARM_GNU_VTENTRY, /* type */
+ HOWTO (R_ARM_TLS_LE32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
- 0, /* bitsize */
+ 32, /* 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 */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_TLS_LE32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
- /* 12 bit pc relative */
-static reloc_howto_type elf32_arm_thm_pc11_howto =
- HOWTO (R_ARM_THM_PC11, /* type */
- 1, /* rightshift */
- 1, /* size (0 = byte, 1 = short, 2 = long) */
- 11, /* bitsize */
- TRUE, /* pc_relative */
+ 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_signed, /* complain_on_overflow */
+ complain_overflow_bitfield,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_ARM_THM_PC11", /* name */
+ "R_ARM_TLS_LDO12", /* name */
FALSE, /* partial_inplace */
- 0x000007ff, /* src_mask */
- 0x000007ff, /* dst_mask */
- TRUE); /* pcrel_offset */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
- /* 12 bit pc relative */
-static reloc_howto_type elf32_arm_thm_pc9_howto =
- HOWTO (R_ARM_THM_PC9, /* type */
- 1, /* rightshift */
- 1, /* size (0 = byte, 1 = short, 2 = long) */
- 8, /* bitsize */
- TRUE, /* pc_relative */
+ 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_signed, /* complain_on_overflow */
+ complain_overflow_bitfield,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_ARM_THM_PC9", /* name */
+ "R_ARM_TLS_LE12", /* name */
FALSE, /* partial_inplace */
- 0x000000ff, /* src_mask */
- 0x000000ff, /* dst_mask */
- TRUE); /* pcrel_offset */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
-/* Place relative GOT-indirect. */
-static reloc_howto_type elf32_arm_got_prel =
- HOWTO (R_ARM_GOT_PREL, /* type */
+ HOWTO (R_ARM_TLS_IE12GP, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
- TRUE, /* pc_relative */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
+ complain_overflow_bitfield,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
- "R_ARM_GOT_PREL", /* name */
+ "R_ARM_TLS_IE12GP", /* name */
FALSE, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
- TRUE); /* pcrel_offset */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
-/* Currently unused relocations. */
-static reloc_howto_type elf32_arm_r_howto[4] =
+/* 112-127 private relocations
+ 128 R_ARM_ME_TOO, obsolete
+ 129-255 unallocated in AAELF.
+
+ 249-255 extended, currently unused, relocations: */
+
+static reloc_howto_type elf32_arm_howto_table_3[4] =
{
HOWTO (R_ARM_RREL32, /* type */
0, /* rightshift */
static reloc_howto_type *
elf32_arm_howto_from_type (unsigned int r_type)
{
- if (r_type < NUM_ELEM (elf32_arm_howto_table))
- return &elf32_arm_howto_table[r_type];
-
- switch (r_type)
- {
- case R_ARM_GOT_PREL:
- return &elf32_arm_got_prel;
-
- case R_ARM_GNU_VTINHERIT:
- return &elf32_arm_vtinherit_howto;
-
- case R_ARM_GNU_VTENTRY:
- return &elf32_arm_vtentry_howto;
-
- case R_ARM_THM_PC11:
- return &elf32_arm_thm_pc11_howto;
-
- case R_ARM_THM_PC9:
- return &elf32_arm_thm_pc9_howto;
-
- case R_ARM_TLS_GD32:
- return &elf32_arm_tls_gd32_howto;
- break;
-
- case R_ARM_TLS_LDO32:
- return &elf32_arm_tls_ldo32_howto;
- break;
-
- case R_ARM_TLS_LDM32:
- return &elf32_arm_tls_ldm32_howto;
- break;
-
- case R_ARM_TLS_IE32:
- return &elf32_arm_tls_ie32_howto;
- break;
+ if (r_type < NUM_ELEM (elf32_arm_howto_table_1))
+ return &elf32_arm_howto_table_1[r_type];
- case R_ARM_TLS_LE32:
- return &elf32_arm_tls_le32_howto;
- break;
+ if (r_type >= R_ARM_MOVW_BREL_NC
+ && r_type < R_ARM_MOVW_BREL_NC + NUM_ELEM (elf32_arm_howto_table_2))
+ return &elf32_arm_howto_table_2[r_type - R_ARM_MOVW_BREL_NC];
- case R_ARM_RREL32:
- case R_ARM_RABS32:
- case R_ARM_RPC24:
- case R_ARM_RBASE:
- return &elf32_arm_r_howto[r_type - R_ARM_RREL32];
+ if (r_type >= R_ARM_RREL32
+ && r_type < R_ARM_RREL32 + NUM_ELEM (elf32_arm_howto_table_2))
+ return &elf32_arm_howto_table_3[r_type - R_ARM_RREL32];
- default:
- return NULL;
- }
+ return NULL;
}
static void
{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_BRANCH23, R_ARM_THM_PC22},
- {BFD_RELOC_ARM_COPY, R_ARM_COPY},
+ {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_GOTOFF},
+ {BFD_RELOC_ARM_GOTOFF, R_ARM_GOTOFF32},
{BFD_RELOC_ARM_GOTPC, R_ARM_GOTPC},
{BFD_RELOC_ARM_GOT32, R_ARM_GOT32},
{BFD_RELOC_ARM_PLT32, R_ARM_PLT32},
{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_VTABLE_INHERIT, R_ARM_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_ARM_GNU_VTENTRY},
};
static reloc_howto_type *
-elf32_arm_reloc_type_lookup (abfd, code)
- bfd *abfd ATTRIBUTE_UNUSED;
- bfd_reloc_code_real_type code;
+elf32_arm_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
{
unsigned int i;
+ for (i = 0; i < NUM_ELEM (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);
- switch (code)
- {
- case BFD_RELOC_VTABLE_INHERIT:
- return & elf32_arm_vtinherit_howto;
-
- case BFD_RELOC_VTABLE_ENTRY:
- return & elf32_arm_vtentry_howto;
-
- case BFD_RELOC_THUMB_PCREL_BRANCH12:
- return & elf32_arm_thm_pc11_howto;
-
- case BFD_RELOC_THUMB_PCREL_BRANCH9:
- return & elf32_arm_thm_pc9_howto;
-
- case BFD_RELOC_ARM_TLS_GD32:
- return & elf32_arm_tls_gd32_howto;
-
- case BFD_RELOC_ARM_TLS_LDO32:
- return & elf32_arm_tls_ldo32_howto;
-
- case BFD_RELOC_ARM_TLS_LDM32:
- return & elf32_arm_tls_ldm32_howto;
-
- case BFD_RELOC_ARM_TLS_IE32:
- return & elf32_arm_tls_ie32_howto;
-
- case BFD_RELOC_ARM_TLS_LE32:
- return & elf32_arm_tls_le32_howto;
-
- default:
- for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
- if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
- return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
-
- return NULL;
- }
+ return NULL;
}
/* Support for core dump NOTE sections */
static bfd_boolean
-elf32_arm_nabi_grok_prstatus (abfd, note)
- bfd *abfd;
- Elf_Internal_Note *note;
+elf32_arm_nabi_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
int offset;
size_t size;
}
static bfd_boolean
-elf32_arm_nabi_grok_psinfo (abfd, note)
- bfd *abfd;
- Elf_Internal_Note *note;
+elf32_arm_nabi_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
switch (note->descsz)
{
/* These are the only relocation types we care about. */
if ( r_type != R_ARM_PC24
&& r_type != R_ARM_PLT32
-#ifndef OLD_ARM_ABI
&& r_type != R_ARM_CALL
&& r_type != R_ARM_JUMP24
-#endif
- && r_type != R_ARM_THM_PC22)
+ && r_type != R_ARM_THM_CALL)
continue;
/* Get the section contents if we haven't done so already. */
{
case R_ARM_PC24:
case R_ARM_PLT32:
-#ifndef OLD_ARM_ABI
case R_ARM_CALL:
case R_ARM_JUMP24:
-#endif
/* This one is a call from arm code. We need to look up
the target of the call. If it is a thumb target, we
insert glue. */
record_arm_to_thumb_glue (link_info, h);
break;
- case R_ARM_THM_PC22:
+ case R_ARM_THM_CALL:
/* This one is a call from thumb code. We look
up the target of the call. If it is not a thumb
target, we insert glue. */
#endif
-#ifndef OLD_ARM_ABI
/* Set target relocation values needed during linking. */
void
globals->fix_v4bx = fix_v4bx;
globals->use_blx |= use_blx;
}
-#endif
/* The thumb form of a long branch is a bit finicky, because the offset
encoding is split over two fields, each in it's own instruction. They
return TRUE;
}
-
-#ifndef OLD_ARM_ABI
/* Some relocations map to different relocations depending on the
target. Return the real relocation. */
static int
return r_type;
}
}
-#endif /* OLD_ARM_ABI */
-
/* Return the base VMA address which should be subtracted from real addresses
when resolving @dtpoff relocation.
globals = elf32_arm_hash_table (info);
-#ifndef OLD_ARM_ABI
/* Some relocation type map to different relocations depending on the
target. We pick the right one here. */
r_type = arm_real_reloc_type (globals, r_type);
if (r_type != howto->type)
howto = elf32_arm_howto_from_type (r_type);
-#endif /* OLD_ARM_ABI */
/* If the start address has been set, then set the EF_ARM_HASENTRY
flag. Setting this more than once is redundant, but the cost is
case R_ARM_PC24:
case R_ARM_ABS32:
case R_ARM_REL32:
-#ifndef OLD_ARM_ABI
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_XPC25:
case R_ARM_PREL31:
-#endif
case R_ARM_PLT32:
/* r_symndx will be zero only for relocs against symbols
from removed linkonce sections, or sections discarded by
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
&& r_type != R_ARM_PC24
-#ifndef OLD_ARM_ABI
&& r_type != R_ARM_CALL
&& r_type != R_ARM_JUMP24
&& r_type != R_ARM_PREL31
-#endif
&& r_type != R_ARM_PLT32)
{
Elf_Internal_Rela outrel;
the section symbol as it is convenient. (We
cannot use the symbol given by "h" directly as it
will not appear in the dynamic symbol table.) */
- symbol = elf_section_data (sym_sec->output_section)->dynindx;
+ if (sym_sec)
+ symbol = elf_section_data (sym_sec->output_section)->dynindx;
+ else
+ symbol = elf_section_data (input_section->output_section)->dynindx;
BFD_ASSERT (symbol != 0);
}
else
}
else switch (r_type)
{
-#ifndef OLD_ARM_ABI
case R_ARM_XPC25: /* Arm BLX instruction. */
case R_ARM_CALL:
case R_ARM_JUMP24:
-#endif
case R_ARM_PC24: /* Arm B/BL instruction */
case R_ARM_PLT32:
-#ifndef OLD_ARM_ABI
if (r_type == R_ARM_XPC25)
{
/* Check for Arm calling Arm function. */
h ? h->root.root.string : "(local)");
}
else
-#endif
{
/* Check for Arm calling Thumb function. */
if (sym_flags == STT_ARM_TFUNC)
return bfd_reloc_overflow;
}
-#ifndef OLD_ARM_ABI
/* If necessary set the H bit in the BLX instruction. */
if (r_type == R_ARM_XPC25 && ((value & 2) == 2))
value = (signed_addend & howto->dst_mask)
| (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask))
| (1 << 24);
else
-#endif
value = (signed_addend & howto->dst_mask)
| (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
break;
value += addend;
break;
-#ifndef OLD_ARM_ABI
case R_ARM_PREL31:
value -= (input_section->output_section->vma
+ input_section->output_offset + rel->r_offset);
if (sym_flags == STT_ARM_TFUNC)
value |= 1;
break;
-#endif
}
bfd_put_32 (input_bfd, value, hit_data);
bfd_put_16 (input_bfd, value, hit_data);
return bfd_reloc_ok;
-#ifndef OLD_ARM_ABI
case R_ARM_THM_XPC22:
-#endif
- case R_ARM_THM_PC22:
+ case R_ARM_THM_CALL:
/* Thumb BL (branch long instruction). */
{
bfd_vma relocation;
addend = (upper << 12) | (lower << 1);
signed_addend = addend;
}
-#ifndef OLD_ARM_ABI
+
if (r_type == R_ARM_THM_XPC22)
{
/* Check for Thumb to Thumb call. */
h ? h->root.root.string : "(local)");
}
else
-#endif
{
/* If it is not a call to Thumb, assume call to Arm.
If it is a call relative to a section name, then it is not a
if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
overflow = TRUE;
-#ifndef OLD_ARM_ABI
if ((r_type == R_ARM_THM_XPC22
&& ((lower_insn & 0x1800) == 0x0800))
|| thumb_plt_call)
which specifies that bit 1 of the target address will come from bit
1 of the base address. */
relocation = (relocation + 2) & ~ 3;
-#endif
+
/* Put RELOCATION back into the insn. */
upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff);
lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff);
}
break;
- case R_ARM_THM_PC11:
- case R_ARM_THM_PC9:
+ case R_ARM_THM_JUMP24:
+ /* Thumb32 unconditional branch instruction. */
+ {
+ bfd_vma relocation;
+ bfd_boolean overflow = FALSE;
+ bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
+ bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
+ bfd_signed_vma reloc_signed_max = ((1 << (howto->bitsize - 1)) - 1) >> howto->rightshift;
+ bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
+ bfd_vma check;
+ bfd_signed_vma signed_check;
+
+ /* Need to refetch the addend, reconstruct the top three bits, and glue the
+ two pieces together. */
+ if (globals->use_rel)
+ {
+ bfd_vma S = (upper_insn & 0x0400) >> 10;
+ bfd_vma hi = (upper_insn & 0x03ff);
+ bfd_vma I1 = (lower_insn & 0x2000) >> 13;
+ bfd_vma I2 = (lower_insn & 0x0800) >> 11;
+ bfd_vma lo = (lower_insn & 0x07ff);
+
+ I1 = !(I1 ^ S);
+ I2 = !(I2 ^ S);
+ S = !S;
+
+ signed_addend = (S << 24) | (I1 << 23) | (I2 << 22) | (hi << 12) | (lo << 1);
+ signed_addend -= (1 << 24); /* Sign extend. */
+ }
+
+ /* ??? Should handle interworking? GCC might someday try to
+ use this for tail calls. */
+
+ relocation = value + signed_addend;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ check = relocation >> howto->rightshift;
+
+ /* If this is a signed value, the rightshift just dropped
+ leading 1 bits (assuming twos complement). */
+ if ((bfd_signed_vma) relocation >= 0)
+ signed_check = check;
+ else
+ signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
+
+ /* Assumes two's complement. */
+ if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
+ overflow = TRUE;
+
+ /* Put RELOCATION back into the insn. */
+ {
+ bfd_vma S = (relocation & 0x01000000) >> 24;
+ bfd_vma I1 = (relocation & 0x00800000) >> 23;
+ bfd_vma I2 = (relocation & 0x00400000) >> 22;
+ bfd_vma hi = (relocation & 0x003ff000) >> 12;
+ bfd_vma lo = (relocation & 0x00000ffe) >> 1;
+
+ I1 = !(I1 ^ S);
+ I2 = !(I2 ^ S);
+
+ upper_insn = (upper_insn & (bfd_vma) 0xf800) | (S << 10) | hi;
+ lower_insn = (lower_insn & (bfd_vma) 0xd000) | (I1 << 13) | (I2 << 11) | lo;
+ }
+
+ /* Put the relocated value back in the object file: */
+ bfd_put_16 (input_bfd, upper_insn, hit_data);
+ bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
+
+ return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
+ }
+
+ case R_ARM_THM_JUMP19:
+ /* Thumb32 conditional branch instruction. */
+ {
+ bfd_vma relocation;
+ bfd_boolean overflow = FALSE;
+ bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
+ bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
+ bfd_signed_vma reloc_signed_max = ((1 << (howto->bitsize - 1)) - 1) >> howto->rightshift;
+ bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
+ bfd_vma check;
+ bfd_signed_vma signed_check;
+
+ /* Need to refetch the addend, reconstruct the top three bits,
+ and squish the two 11 bit pieces together. */
+ if (globals->use_rel)
+ {
+ bfd_vma S = (upper_insn & 0x0400) >> 10;
+ bfd_vma upper = (upper_insn & 0x001f);
+ bfd_vma J1 = (lower_insn & 0x2000) >> 13;
+ bfd_vma J2 = (lower_insn & 0x0800) >> 11;
+ bfd_vma lower = (lower_insn & 0x07ff);
+
+ upper |= J2 << 6;
+ upper |= J1 << 7;
+ upper |= ~S << 8;
+ upper -= 0x0100; /* Sign extend. */
+
+ addend = (upper << 12) | (lower << 1);
+ signed_addend = addend;
+ }
+
+ /* ??? Should handle interworking? GCC might someday try to
+ use this for tail calls. */
+
+ relocation = value + signed_addend;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ check = relocation >> howto->rightshift;
+
+ /* If this is a signed value, the rightshift just dropped
+ leading 1 bits (assuming twos complement). */
+ if ((bfd_signed_vma) relocation >= 0)
+ signed_check = check;
+ else
+ signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
+
+ /* Assumes two's complement. */
+ if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
+ overflow = TRUE;
+
+ /* Put RELOCATION back into the insn. */
+ {
+ bfd_vma S = (relocation & 0x00100000) >> 20;
+ bfd_vma J2 = (relocation & 0x00080000) >> 19;
+ bfd_vma J1 = (relocation & 0x00040000) >> 18;
+ bfd_vma hi = (relocation & 0x0003f000) >> 12;
+ bfd_vma lo = (relocation & 0x00000ffe) >> 1;
+
+ upper_insn = (upper_insn & 0xfb30) | (S << 10) | hi;
+ lower_insn = (lower_insn & 0xd000) | (J1 << 13) | (J2 << 11) | lo;
+ }
+
+ /* Put the relocated value back in the object file: */
+ bfd_put_16 (input_bfd, upper_insn, hit_data);
+ bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
+
+ return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
+ }
+
+ case R_ARM_THM_JUMP11:
+ case R_ARM_THM_JUMP8:
+ case R_ARM_THM_JUMP6:
/* Thumb B (branch) instruction). */
{
bfd_signed_vma relocation;
bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
bfd_signed_vma signed_check;
+ /* CZB cannot jump backward. */
+ if (r_type == R_ARM_THM_JUMP6)
+ reloc_signed_min = 0;
+
if (globals->use_rel)
{
/* Need to refetch addend. */
relocation >>= howto->rightshift;
signed_check = relocation;
- relocation &= howto->dst_mask;
+
+ if (r_type == R_ARM_THM_JUMP6)
+ relocation = ((relocation & 0x0020) << 4) | ((relocation & 0x001f) << 3);
+ else
+ relocation &= howto->dst_mask;
relocation |= (bfd_get_16 (input_bfd, hit_data) & (~ howto->dst_mask));
bfd_put_16 (input_bfd, relocation, hit_data);
return bfd_reloc_ok;
}
-#ifndef OLD_ARM_ABI
case R_ARM_ALU_PCREL7_0:
case R_ARM_ALU_PCREL15_8:
case R_ARM_ALU_PCREL23_15:
bfd_put_32 (input_bfd, value, hit_data);
}
return bfd_reloc_ok;
-#endif
case R_ARM_GNU_VTINHERIT:
case R_ARM_GNU_VTENTRY:
return bfd_reloc_ok;
- case R_ARM_COPY:
- return bfd_reloc_notsupported;
-
- case R_ARM_GLOB_DAT:
- return bfd_reloc_notsupported;
-
- case R_ARM_JUMP_SLOT:
- return bfd_reloc_notsupported;
-
- case R_ARM_RELATIVE:
- return bfd_reloc_notsupported;
-
- case R_ARM_GOTOFF:
+ case R_ARM_GOTOFF32:
/* Relocation is relative to the start of the
global offset table. */
(bfd_vma) 0);
case R_ARM_GOT32:
-#ifndef OLD_ARM_ABI
case R_ARM_GOT_PREL:
-#endif
/* Relocation is to the entry for this symbol in the
global offset table. */
if (sgot == NULL)
return _bfd_final_link_relocate (howto, input_bfd, input_section,
contents, rel->r_offset, value, (bfd_vma) 0);
- case R_ARM_SBREL32:
- return bfd_reloc_notsupported;
-
- case R_ARM_AMP_VCALL9:
- return bfd_reloc_notsupported;
-
- case R_ARM_RSBREL32:
- return bfd_reloc_notsupported;
-
- case R_ARM_THM_RPC22:
- return bfd_reloc_notsupported;
-
- case R_ARM_RREL32:
- return bfd_reloc_notsupported;
-
- case R_ARM_RABS32:
- return bfd_reloc_notsupported;
-
- case R_ARM_RPC24:
- return bfd_reloc_notsupported;
-
- case R_ARM_RBASE:
- return bfd_reloc_notsupported;
-
case R_ARM_V4BX:
if (globals->fix_v4bx)
{
{
bfd_signed_vma addend;
- if (howto->type == R_ARM_THM_PC22)
+ if (howto->type == R_ARM_THM_CALL)
{
int upper_insn, lower_insn;
int upper, lower;
case R_ARM_PC24:
case R_ARM_PLT32:
-#ifndef OLD_ARM_ABI
case R_ARM_CALL:
case R_ARM_JUMP24:
-#endif
addend <<= howto->size;
addend += increment;
}
r_type = ELF32_R_TYPE (rel->r_info);
-#ifndef OLD_ARM_ABI
r_type = arm_real_reloc_type (globals, r_type);
-#endif
switch (r_type)
{
case R_ARM_GOT32:
-#ifndef OLD_ARM_ABI
case R_ARM_GOT_PREL:
-#endif
case R_ARM_TLS_GD32:
case R_ARM_TLS_IE32:
if (h != NULL)
case R_ARM_REL32:
case R_ARM_PC24:
case R_ARM_PLT32:
-#ifndef OLD_ARM_ABI
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PREL31:
-#endif
- case R_ARM_THM_PC22:
+ case R_ARM_THM_CALL:
/* Should the interworking branches be here also? */
if (h != NULL)
if (h->plt.refcount > 0)
{
h->plt.refcount -= 1;
- if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_PC22)
+ if (ELF32_R_TYPE (rel->r_info) == R_ARM_THM_CALL)
eh->plt_thumb_refcount--;
}
r_symndx = ELF32_R_SYM (rel->r_info);
r_type = ELF32_R_TYPE (rel->r_info);
-#ifndef OLD_ARM_ABI
r_type = arm_real_reloc_type (htab, r_type);
-#endif
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
{
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
eh = (struct elf32_arm_link_hash_entry *) h;
switch (r_type)
{
case R_ARM_GOT32:
-#ifndef OLD_ARM_ABI
case R_ARM_GOT_PREL:
-#endif
case R_ARM_TLS_GD32:
case R_ARM_TLS_IE32:
/* This symbol requires a global offset table entry. */
htab->tls_ldm_got.refcount++;
/* Fall through */
- case R_ARM_GOTOFF:
+ case R_ARM_GOTOFF32:
case R_ARM_GOTPC:
if (htab->sgot == NULL)
{
case R_ARM_REL32:
case R_ARM_PC24:
case R_ARM_PLT32:
-#ifndef OLD_ARM_ABI
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PREL31:
-#endif
- case R_ARM_THM_PC22:
+ case R_ARM_THM_CALL:
/* Should the interworking branches be listed here? */
if (h != NULL)
{
sure yet, because something later might force the
symbol local. */
if (r_type == R_ARM_PC24
-#ifndef OLD_ARM_ABI
|| r_type == R_ARM_CALL
|| r_type == R_ARM_JUMP24
|| r_type == R_ARM_PREL31
-#endif
|| r_type == R_ARM_PLT32
- || r_type == R_ARM_THM_PC22)
+ || r_type == R_ARM_THM_CALL)
h->needs_plt = 1;
/* If we create a PLT entry, this relocation will reference
it, even if it's an ABS32 relocation. */
h->plt.refcount += 1;
- if (r_type == R_ARM_THM_PC22)
+ if (r_type == R_ARM_THM_CALL)
eh->plt_thumb_refcount += 1;
}
return TRUE;
}
+static bfd_boolean
+elf32_arm_find_inliner_info (bfd * abfd,
+ const char ** filename_ptr,
+ const char ** functionname_ptr,
+ unsigned int * line_ptr)
+{
+ bfd_boolean found;
+ found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
+ functionname_ptr, line_ptr,
+ & elf_tdata (abfd)->dwarf2_find_line_info);
+ return found;
+}
+
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object. The current definition is in some section of the
dynamic object, but we're not including those sections. We have to
for (s = dynobj->sections; s != NULL; s = s->next)
{
const char * name;
- bfd_boolean strip;
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
of the dynobj section names depend upon the input files. */
name = bfd_get_section_name (dynobj, s);
- strip = FALSE;
-
if (strcmp (name, ".plt") == 0)
{
- if (s->size == 0)
- {
- /* Strip this section if we don't need it; see the
- comment below. */
- strip = TRUE;
- }
- else
- {
- /* Remember whether there is a PLT. */
- plt = TRUE;
- }
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
}
else if (strncmp (name, ".rel", 4) == 0)
{
- if (s->size == 0)
- {
- /* If we don't need this section, strip it from the
- output file. This is mostly to handle .rel.bss and
- .rel.plt. We must create both sections in
- create_dynamic_sections, because they must be created
- before the linker maps input sections to output
- sections. The linker does that before
- adjust_dynamic_symbol is called, and it is that
- function which decides whether anything needs to go
- into these sections. */
- strip = TRUE;
- }
- else
+ if (s->size != 0)
{
/* Remember whether there are any reloc sections other
than .rel.plt. */
s->reloc_count = 0;
}
}
- else if (strncmp (name, ".got", 4) != 0)
+ else if (strncmp (name, ".got", 4) != 0
+ && strcmp (name, ".dynbss") != 0)
{
/* It's not one of our sections, so don't allocate space. */
continue;
}
- if (strip)
+ if (s->size == 0)
{
+ /* If we don't need this section, strip it from the
+ output file. This is mostly to handle .rel.bss and
+ .rel.plt. We must create both sections in
+ create_dynamic_sections, because they must be created
+ before the linker maps input sections to output
+ sections. The linker does that before
+ adjust_dynamic_symbol is called, and it is that
+ function which decides whether anything needs to go
+ into these sections. */
s->flags |= SEC_EXCLUDE;
continue;
}
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
/* Allocate memory for the section contents. */
s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
- if (s->contents == NULL && s->size != 0)
+ if (s->contents == NULL)
return FALSE;
}
#define add_dynamic_entry(TAG, VAL) \
_bfd_elf_add_dynamic_entry (info, TAG, VAL)
- if (!info->shared)
+ if (info->executable)
{
if (!add_dynamic_entry (DT_DEBUG, 0))
return FALSE;
{
if (!add_dynamic_entry (DT_TEXTREL, 0))
return FALSE;
- info->flags |= DF_TEXTREL;
}
}
-#undef add_synamic_entry
+#undef add_dynamic_entry
return TRUE;
}
#define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create
#define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup
#define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line
+#define bfd_elf32_find_inliner_info elf32_arm_find_inliner_info
#define bfd_elf32_new_section_hook elf32_arm_new_section_hook
#define bfd_elf32_bfd_is_target_special_symbol elf32_arm_is_target_special_symbol
return ret;
}
-static struct bfd_elf_special_section const
- elf32_arm_symbian_special_sections[]=
+static const struct bfd_elf_special_section
+elf32_arm_symbian_special_sections[] =
{
/* In a BPABI executable, the dynamic linking sections do not go in
the loadable read-only segment. The post-linker may wish to