diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 29 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 101 | ||||
-rw-r--r-- | bfd/elf32-arm.c | 942 | ||||
-rw-r--r-- | bfd/libbfd.h | 58 | ||||
-rw-r--r-- | bfd/reloc.c | 163 |
5 files changed, 904 insertions, 389 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ed035b7..76f3f26 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,32 @@ +2005-05-17 Zack Weinberg <zack@codesourcery.com> + + * elf32-arm.c: Wherever possible, use official reloc names + from AAELF. + (elf32_arm_howto_table, elf32_arm_tls_gd32_howto) + (elf32_arm_tls_ldo32_howto, elf32_arm_tls_ldm32_howto) + (elf32_arm_tls_le32_howto, elf32_arm_tls_ie32_howto) + (elf32_arm_vtinherit_howto, elf32_arm_vtentry_howto) + (elf32_arm_pc11_howto, elf32_arm_thm_pc9_howto, elf32_arm_got_prel) + (elf32_arm_r_howto): Replace with elf32_arm_howto_table_1, + elf32_arm_howto_table_2, and elf32_arm_howto_table_3. + Add many new relocations from AAELF. + (elf32_arm_howto_from_type): Update to match. + (elf32_arm_reloc_map): Add entries for R_ARM_THM_JUMP24, + R_ARM_THM_JUMP11, R_ARM_THM_JUMP19, R_ARM_THM_JUMP8, + R_ARM_THM_JUMP6, R_ARM_GNU_VTINHERIT, and R_ARM_GNU_VTENTRY. + (elf32_arm_reloc_type_lookup): Use elf32_arm_howto_from_type. + (elf32_arm_final_link_relocate): Add support for + R_ARM_THM_JUMP24, R_ARM_THM_JUMP19, R_ARM_THM_JUMP6. Remove + case entries redundant with default. + + * reloc.c: Reorganize ARM relocations. Add Thumb + assembler-internal relocations BFD_RELOC_ARM_T32_OFFSET_U8, + BFD_RELOC_ARM_T32_OFFSET_IMM, BFD_RELOC_ARM_T32_IMMEDIATE. + Add visible relocations BFD_RELOC_THUMB_PCREL_BRANCH7, + BFD_RELOC_THUMB_BRANCH20, BFD_RELOC_THUMB_BRANCH25. + Delete unused relocations BFD_RELOC_ARM_GOT12, BFD_RELOC_ARM_COPY. + * bfd-in2.h, libbfd.h: Regenerate. + 2005-05-17 Daniel Jacobowitz <dan@codesourcery.com> * elf.c (_bfd_elf_write_object_contents): Check for non-NULL diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 6a648be..b166475 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2757,44 +2757,23 @@ not stored in the instruction. The 2nd lowest bit comes from a 1 bit field in the instruction. */ BFD_RELOC_THUMB_PCREL_BLX, -/* These relocs are only used within the ARM assembler. They are not -(at present) written to any object files. */ - BFD_RELOC_ARM_IMMEDIATE, - BFD_RELOC_ARM_ADRL_IMMEDIATE, +/* Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches. +The lowest bit must be zero and is not stored in the instruction. +Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an +"nn" one smaller in all cases. Note further that BRANCH23 +corresponds to R_ARM_THM_CALL. */ + BFD_RELOC_THUMB_PCREL_BRANCH7, + BFD_RELOC_THUMB_PCREL_BRANCH9, + BFD_RELOC_THUMB_PCREL_BRANCH12, + BFD_RELOC_THUMB_PCREL_BRANCH20, + BFD_RELOC_THUMB_PCREL_BRANCH23, + BFD_RELOC_THUMB_PCREL_BRANCH25, + +/* 12-bit immediate offset, used in ARM-format ldr and str instructions. */ BFD_RELOC_ARM_OFFSET_IMM, - BFD_RELOC_ARM_SHIFT_IMM, - BFD_RELOC_ARM_SMI, - BFD_RELOC_ARM_SWI, - BFD_RELOC_ARM_MULTI, - BFD_RELOC_ARM_CP_OFF_IMM, - BFD_RELOC_ARM_CP_OFF_IMM_S2, - BFD_RELOC_ARM_ADR_IMM, - BFD_RELOC_ARM_LDR_IMM, - BFD_RELOC_ARM_LITERAL, - BFD_RELOC_ARM_IN_POOL, - BFD_RELOC_ARM_OFFSET_IMM8, - BFD_RELOC_ARM_HWLITERAL, - BFD_RELOC_ARM_THUMB_ADD, - BFD_RELOC_ARM_THUMB_IMM, - BFD_RELOC_ARM_THUMB_SHIFT, + +/* 5-bit immediate offset, used in Thumb-format ldr and str instructions. */ BFD_RELOC_ARM_THUMB_OFFSET, - BFD_RELOC_ARM_GOT12, - BFD_RELOC_ARM_GOT32, - BFD_RELOC_ARM_JUMP_SLOT, - BFD_RELOC_ARM_COPY, - BFD_RELOC_ARM_GLOB_DAT, - BFD_RELOC_ARM_PLT32, - BFD_RELOC_ARM_RELATIVE, - BFD_RELOC_ARM_GOTOFF, - BFD_RELOC_ARM_GOTPC, - BFD_RELOC_ARM_TLS_GD32, - BFD_RELOC_ARM_TLS_LDO32, - BFD_RELOC_ARM_TLS_LDM32, - BFD_RELOC_ARM_TLS_DTPOFF32, - BFD_RELOC_ARM_TLS_DTPMOD32, - BFD_RELOC_ARM_TLS_TPOFF32, - BFD_RELOC_ARM_TLS_IE32, - BFD_RELOC_ARM_TLS_LE32, /* Pc-relative or absolute relocation depending on target. Used for entries in .init_array sections. */ @@ -2806,7 +2785,7 @@ entries in .init_array sections. */ /* Data segment base relative address. */ BFD_RELOC_ARM_SBREL32, -/* This reloc is used for References to RTTI dta from exception handling +/* This reloc is used for references to RTTI data from exception handling tables. The actual definition depends on the target. It may be a pc-relative or some form of GOT-indirect relocation. */ BFD_RELOC_ARM_TARGET2, @@ -2814,6 +2793,48 @@ pc-relative or some form of GOT-indirect relocation. */ /* 31-bit PC relative address. */ BFD_RELOC_ARM_PREL31, +/* Relocations for setting up GOTs and PLTs for shared libraries. */ + BFD_RELOC_ARM_JUMP_SLOT, + BFD_RELOC_ARM_GLOB_DAT, + BFD_RELOC_ARM_GOT32, + BFD_RELOC_ARM_PLT32, + BFD_RELOC_ARM_RELATIVE, + BFD_RELOC_ARM_GOTOFF, + BFD_RELOC_ARM_GOTPC, + +/* ARM thread-local storage relocations. */ + BFD_RELOC_ARM_TLS_GD32, + BFD_RELOC_ARM_TLS_LDO32, + BFD_RELOC_ARM_TLS_LDM32, + BFD_RELOC_ARM_TLS_DTPOFF32, + BFD_RELOC_ARM_TLS_DTPMOD32, + BFD_RELOC_ARM_TLS_TPOFF32, + BFD_RELOC_ARM_TLS_IE32, + BFD_RELOC_ARM_TLS_LE32, + +/* These relocs are only used within the ARM assembler. They are not +(at present) written to any object files. */ + BFD_RELOC_ARM_IMMEDIATE, + BFD_RELOC_ARM_ADRL_IMMEDIATE, + BFD_RELOC_ARM_T32_IMMEDIATE, + BFD_RELOC_ARM_SHIFT_IMM, + BFD_RELOC_ARM_SMI, + BFD_RELOC_ARM_SWI, + BFD_RELOC_ARM_MULTI, + BFD_RELOC_ARM_CP_OFF_IMM, + BFD_RELOC_ARM_CP_OFF_IMM_S2, + BFD_RELOC_ARM_ADR_IMM, + BFD_RELOC_ARM_LDR_IMM, + BFD_RELOC_ARM_LITERAL, + BFD_RELOC_ARM_IN_POOL, + BFD_RELOC_ARM_OFFSET_IMM8, + BFD_RELOC_ARM_T32_OFFSET_U8, + BFD_RELOC_ARM_T32_OFFSET_IMM, + BFD_RELOC_ARM_HWLITERAL, + BFD_RELOC_ARM_THUMB_ADD, + BFD_RELOC_ARM_THUMB_IMM, + BFD_RELOC_ARM_THUMB_SHIFT, + /* Renesas / SuperH SH relocs. Not all of these appear in object files. */ BFD_RELOC_SH_PCDISP8BY2, BFD_RELOC_SH_PCDISP12BY2, @@ -2906,12 +2927,6 @@ pc-relative or some form of GOT-indirect relocation. */ BFD_RELOC_SH_TLS_DTPOFF32, BFD_RELOC_SH_TLS_TPOFF32, -/* Thumb 23-, 12- and 9-bit pc-relative branches. The lowest bit must -be zero and is not stored in the instruction. */ - BFD_RELOC_THUMB_PCREL_BRANCH9, - BFD_RELOC_THUMB_PCREL_BRANCH12, - BFD_RELOC_THUMB_PCREL_BRANCH23, - /* ARC Cores relocs. ARC 22 bit pc-relative branch. The lowest two bits must be zero and are not stored in the instruction. The high 20 bits are installed in bits 26 diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 73554cf..f5feeaf 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -45,7 +45,7 @@ static bfd_boolean elf32_arm_nabi_grok_psinfo 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 */ @@ -106,7 +106,7 @@ static reloc_howto_type elf32_arm_howto_table[] = 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) */ @@ -194,7 +194,8 @@ static reloc_howto_type elf32_arm_howto_table[] = 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 */ @@ -202,7 +203,7 @@ static reloc_howto_type elf32_arm_howto_table[] = 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 */ @@ -222,19 +223,19 @@ static reloc_howto_type elf32_arm_howto_table[] = 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 */ @@ -396,7 +397,7 @@ static reloc_howto_type elf32_arm_howto_table[] = 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 */ @@ -404,7 +405,7 @@ static reloc_howto_type elf32_arm_howto_table[] = 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 */ @@ -480,32 +481,32 @@ static reloc_howto_type elf32_arm_howto_table[] = 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 */ @@ -661,39 +662,446 @@ static reloc_howto_type elf32_arm_howto_table[] = 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) */ @@ -706,10 +1114,9 @@ static reloc_howto_type elf32_arm_tls_ldm32_howto = 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 */ @@ -717,13 +1124,12 @@ static reloc_howto_type elf32_arm_tls_le32_howto = 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) */ @@ -736,90 +1142,72 @@ static reloc_howto_type elf32_arm_tls_ie32_howto = 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 */ +}; + +/* 112-127 private relocations + 128 R_ARM_ME_TOO, obsolete + 129-255 unallocated in AAELF. -/* Currently unused relocations. */ -static reloc_howto_type elf32_arm_r_howto[4] = + 249-255 extended, currently unused, relocations: */ + +static reloc_howto_type elf32_arm_howto_table_3[4] = { HOWTO (R_ARM_RREL32, /* type */ 0, /* rightshift */ @@ -881,55 +1269,18 @@ static reloc_howto_type elf32_arm_r_howto[4] = 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; + if (r_type < NUM_ELEM (elf32_arm_howto_table_1)) + return &elf32_arm_howto_table_1[r_type]; - case R_ARM_THM_PC11: - return &elf32_arm_thm_pc11_howto; + 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_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; - - case R_ARM_TLS_LE32: - return &elf32_arm_tls_le32_howto; - break; + 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]; - 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]; - - default: - return NULL; - } + return NULL; } static void @@ -961,12 +1312,16 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] = {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}, @@ -984,6 +1339,8 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] = {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 * @@ -992,43 +1349,11 @@ elf32_arm_reloc_type_lookup (abfd, code) 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 */ @@ -2034,7 +2359,7 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd, && 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. */ @@ -2088,7 +2413,7 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd, 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. */ @@ -2896,7 +3221,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, #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; @@ -3014,8 +3339,153 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, } 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; @@ -3023,6 +3493,10 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, 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. */ @@ -3048,7 +3522,11 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, 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); @@ -3092,19 +3570,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, 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. */ @@ -3465,30 +3931,6 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, 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) { @@ -3519,7 +3961,7 @@ arm_add_to_rel (bfd * abfd, { 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; @@ -4414,7 +4856,7 @@ elf32_arm_gc_sweep_hook (bfd * abfd, 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) @@ -4428,7 +4870,7 @@ elf32_arm_gc_sweep_hook (bfd * abfd, 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--; } @@ -4598,7 +5040,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, htab->tls_ldm_got.refcount++; /* Fall through */ - case R_ARM_GOTOFF: + case R_ARM_GOTOFF32: case R_ARM_GOTPC: if (htab->sgot == NULL) { @@ -4618,7 +5060,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, 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) { @@ -4642,14 +5084,14 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, || 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; } diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 4706f16..5b83a81 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1152,9 +1152,37 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_ARM_PCREL_BRANCH", "BFD_RELOC_ARM_PCREL_BLX", "BFD_RELOC_THUMB_PCREL_BLX", + "BFD_RELOC_THUMB_PCREL_BRANCH7", + "BFD_RELOC_THUMB_PCREL_BRANCH9", + "BFD_RELOC_THUMB_PCREL_BRANCH12", + "BFD_RELOC_THUMB_PCREL_BRANCH20", + "BFD_RELOC_THUMB_PCREL_BRANCH23", + "BFD_RELOC_THUMB_PCREL_BRANCH25", + "BFD_RELOC_ARM_OFFSET_IMM", + "BFD_RELOC_ARM_THUMB_OFFSET", + "BFD_RELOC_ARM_TARGET1", + "BFD_RELOC_ARM_ROSEGREL32", + "BFD_RELOC_ARM_SBREL32", + "BFD_RELOC_ARM_TARGET2", + "BFD_RELOC_ARM_PREL31", + "BFD_RELOC_ARM_JUMP_SLOT", + "BFD_RELOC_ARM_GLOB_DAT", + "BFD_RELOC_ARM_GOT32", + "BFD_RELOC_ARM_PLT32", + "BFD_RELOC_ARM_RELATIVE", + "BFD_RELOC_ARM_GOTOFF", + "BFD_RELOC_ARM_GOTPC", + "BFD_RELOC_ARM_TLS_GD32", + "BFD_RELOC_ARM_TLS_LDO32", + "BFD_RELOC_ARM_TLS_LDM32", + "BFD_RELOC_ARM_TLS_DTPOFF32", + "BFD_RELOC_ARM_TLS_DTPMOD32", + "BFD_RELOC_ARM_TLS_TPOFF32", + "BFD_RELOC_ARM_TLS_IE32", + "BFD_RELOC_ARM_TLS_LE32", "BFD_RELOC_ARM_IMMEDIATE", "BFD_RELOC_ARM_ADRL_IMMEDIATE", - "BFD_RELOC_ARM_OFFSET_IMM", + "BFD_RELOC_ARM_T32_IMMEDIATE", "BFD_RELOC_ARM_SHIFT_IMM", "BFD_RELOC_ARM_SMI", "BFD_RELOC_ARM_SWI", @@ -1166,33 +1194,12 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_ARM_LITERAL", "BFD_RELOC_ARM_IN_POOL", "BFD_RELOC_ARM_OFFSET_IMM8", + "BFD_RELOC_ARM_T32_OFFSET_U8", + "BFD_RELOC_ARM_T32_OFFSET_IMM", "BFD_RELOC_ARM_HWLITERAL", "BFD_RELOC_ARM_THUMB_ADD", "BFD_RELOC_ARM_THUMB_IMM", "BFD_RELOC_ARM_THUMB_SHIFT", - "BFD_RELOC_ARM_THUMB_OFFSET", - "BFD_RELOC_ARM_GOT12", - "BFD_RELOC_ARM_GOT32", - "BFD_RELOC_ARM_JUMP_SLOT", - "BFD_RELOC_ARM_COPY", - "BFD_RELOC_ARM_GLOB_DAT", - "BFD_RELOC_ARM_PLT32", - "BFD_RELOC_ARM_RELATIVE", - "BFD_RELOC_ARM_GOTOFF", - "BFD_RELOC_ARM_GOTPC", - "BFD_RELOC_ARM_TLS_GD32", - "BFD_RELOC_ARM_TLS_LDO32", - "BFD_RELOC_ARM_TLS_LDM32", - "BFD_RELOC_ARM_TLS_DTPOFF32", - "BFD_RELOC_ARM_TLS_DTPMOD32", - "BFD_RELOC_ARM_TLS_TPOFF32", - "BFD_RELOC_ARM_TLS_IE32", - "BFD_RELOC_ARM_TLS_LE32", - "BFD_RELOC_ARM_TARGET1", - "BFD_RELOC_ARM_ROSEGREL32", - "BFD_RELOC_ARM_SBREL32", - "BFD_RELOC_ARM_TARGET2", - "BFD_RELOC_ARM_PREL31", "BFD_RELOC_SH_PCDISP8BY2", "BFD_RELOC_SH_PCDISP12BY2", "BFD_RELOC_SH_IMM3", @@ -1283,9 +1290,6 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_SH_TLS_DTPMOD32", "BFD_RELOC_SH_TLS_DTPOFF32", "BFD_RELOC_SH_TLS_TPOFF32", - "BFD_RELOC_THUMB_PCREL_BRANCH9", - "BFD_RELOC_THUMB_PCREL_BRANCH12", - "BFD_RELOC_THUMB_PCREL_BRANCH23", "BFD_RELOC_ARC_B22_PCREL", "BFD_RELOC_ARC_B26", "BFD_RELOC_D10V_10_PCREL_R", diff --git a/bfd/reloc.c b/bfd/reloc.c index e2e8a52..078529d 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2635,104 +2635,139 @@ ENUMDOC Thumb 22 bit pc-relative branch. The lowest bit must be zero and is not stored in the instruction. The 2nd lowest bit comes from a 1 bit field in the instruction. + ENUM - BFD_RELOC_ARM_IMMEDIATE + BFD_RELOC_THUMB_PCREL_BRANCH7 ENUMX - BFD_RELOC_ARM_ADRL_IMMEDIATE + BFD_RELOC_THUMB_PCREL_BRANCH9 ENUMX - BFD_RELOC_ARM_OFFSET_IMM + BFD_RELOC_THUMB_PCREL_BRANCH12 ENUMX - BFD_RELOC_ARM_SHIFT_IMM + BFD_RELOC_THUMB_PCREL_BRANCH20 ENUMX - BFD_RELOC_ARM_SMI + BFD_RELOC_THUMB_PCREL_BRANCH23 ENUMX - BFD_RELOC_ARM_SWI + BFD_RELOC_THUMB_PCREL_BRANCH25 +ENUMDOC + Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches. + The lowest bit must be zero and is not stored in the instruction. + Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an + "nn" one smaller in all cases. Note further that BRANCH23 + corresponds to R_ARM_THM_CALL. + +ENUM + BFD_RELOC_ARM_OFFSET_IMM +ENUMDOC + 12-bit immediate offset, used in ARM-format ldr and str instructions. + +ENUM + BFD_RELOC_ARM_THUMB_OFFSET +ENUMDOC + 5-bit immediate offset, used in Thumb-format ldr and str instructions. + +ENUM + BFD_RELOC_ARM_TARGET1 +ENUMDOC + Pc-relative or absolute relocation depending on target. Used for + entries in .init_array sections. +ENUM + BFD_RELOC_ARM_ROSEGREL32 +ENUMDOC + Read-only segment base relative address. +ENUM + BFD_RELOC_ARM_SBREL32 +ENUMDOC + Data segment base relative address. +ENUM + BFD_RELOC_ARM_TARGET2 +ENUMDOC + This reloc is used for references to RTTI data from exception handling + tables. The actual definition depends on the target. It may be a + pc-relative or some form of GOT-indirect relocation. +ENUM + BFD_RELOC_ARM_PREL31 +ENUMDOC + 31-bit PC relative address. + +ENUM + BFD_RELOC_ARM_JUMP_SLOT ENUMX - BFD_RELOC_ARM_MULTI + BFD_RELOC_ARM_GLOB_DAT ENUMX - BFD_RELOC_ARM_CP_OFF_IMM + BFD_RELOC_ARM_GOT32 ENUMX - BFD_RELOC_ARM_CP_OFF_IMM_S2 + BFD_RELOC_ARM_PLT32 ENUMX - BFD_RELOC_ARM_ADR_IMM + BFD_RELOC_ARM_RELATIVE ENUMX - BFD_RELOC_ARM_LDR_IMM + BFD_RELOC_ARM_GOTOFF ENUMX - BFD_RELOC_ARM_LITERAL + BFD_RELOC_ARM_GOTPC +ENUMDOC + Relocations for setting up GOTs and PLTs for shared libraries. + +ENUM + BFD_RELOC_ARM_TLS_GD32 ENUMX - BFD_RELOC_ARM_IN_POOL + BFD_RELOC_ARM_TLS_LDO32 ENUMX - BFD_RELOC_ARM_OFFSET_IMM8 + BFD_RELOC_ARM_TLS_LDM32 ENUMX - BFD_RELOC_ARM_HWLITERAL + BFD_RELOC_ARM_TLS_DTPOFF32 ENUMX - BFD_RELOC_ARM_THUMB_ADD + BFD_RELOC_ARM_TLS_DTPMOD32 ENUMX - BFD_RELOC_ARM_THUMB_IMM + BFD_RELOC_ARM_TLS_TPOFF32 ENUMX - BFD_RELOC_ARM_THUMB_SHIFT + BFD_RELOC_ARM_TLS_IE32 ENUMX - BFD_RELOC_ARM_THUMB_OFFSET + BFD_RELOC_ARM_TLS_LE32 +ENUMDOC + ARM thread-local storage relocations. + +ENUM + BFD_RELOC_ARM_IMMEDIATE ENUMX - BFD_RELOC_ARM_GOT12 + BFD_RELOC_ARM_ADRL_IMMEDIATE ENUMX - BFD_RELOC_ARM_GOT32 + BFD_RELOC_ARM_T32_IMMEDIATE ENUMX - BFD_RELOC_ARM_JUMP_SLOT + BFD_RELOC_ARM_SHIFT_IMM ENUMX - BFD_RELOC_ARM_COPY + BFD_RELOC_ARM_SMI ENUMX - BFD_RELOC_ARM_GLOB_DAT + BFD_RELOC_ARM_SWI ENUMX - BFD_RELOC_ARM_PLT32 + BFD_RELOC_ARM_MULTI ENUMX - BFD_RELOC_ARM_RELATIVE + BFD_RELOC_ARM_CP_OFF_IMM ENUMX - BFD_RELOC_ARM_GOTOFF + BFD_RELOC_ARM_CP_OFF_IMM_S2 ENUMX - BFD_RELOC_ARM_GOTPC + BFD_RELOC_ARM_ADR_IMM ENUMX - BFD_RELOC_ARM_TLS_GD32 + BFD_RELOC_ARM_LDR_IMM ENUMX - BFD_RELOC_ARM_TLS_LDO32 + BFD_RELOC_ARM_LITERAL ENUMX - BFD_RELOC_ARM_TLS_LDM32 + BFD_RELOC_ARM_IN_POOL ENUMX - BFD_RELOC_ARM_TLS_DTPOFF32 + BFD_RELOC_ARM_OFFSET_IMM8 ENUMX - BFD_RELOC_ARM_TLS_DTPMOD32 + BFD_RELOC_ARM_T32_OFFSET_U8 ENUMX - BFD_RELOC_ARM_TLS_TPOFF32 + BFD_RELOC_ARM_T32_OFFSET_IMM ENUMX - BFD_RELOC_ARM_TLS_IE32 + BFD_RELOC_ARM_HWLITERAL ENUMX - BFD_RELOC_ARM_TLS_LE32 + BFD_RELOC_ARM_THUMB_ADD +ENUMX + BFD_RELOC_ARM_THUMB_IMM +ENUMX + BFD_RELOC_ARM_THUMB_SHIFT ENUMDOC These relocs are only used within the ARM assembler. They are not (at present) written to any object files. -ENUM - BFD_RELOC_ARM_TARGET1 -ENUMDOC - Pc-relative or absolute relocation depending on target. Used for - entries in .init_array sections. -ENUM - BFD_RELOC_ARM_ROSEGREL32 -ENUMDOC - Read-only segment base relative address. -ENUM - BFD_RELOC_ARM_SBREL32 -ENUMDOC - Data segment base relative address. -ENUM - BFD_RELOC_ARM_TARGET2 -ENUMDOC - This reloc is used for References to RTTI dta from exception handling - tables. The actual definition depends on the target. It may be a - pc-relative or some form of GOT-indirect relocation. -ENUM - BFD_RELOC_ARM_PREL31 -ENUMDOC - 31-bit PC relative address. ENUM BFD_RELOC_SH_PCDISP8BY2 @@ -2918,16 +2953,6 @@ ENUMDOC Renesas / SuperH SH relocs. Not all of these appear in object files. ENUM - BFD_RELOC_THUMB_PCREL_BRANCH9 -ENUMX - BFD_RELOC_THUMB_PCREL_BRANCH12 -ENUMX - BFD_RELOC_THUMB_PCREL_BRANCH23 -ENUMDOC - Thumb 23-, 12- and 9-bit pc-relative branches. The lowest bit must - be zero and is not stored in the instruction. - -ENUM BFD_RELOC_ARC_B22_PCREL ENUMDOC ARC Cores relocs. |