Add support for R_ARM_XPC25 and R_ARM_THM_XPC22 relocs
This commit is contained in:
parent
8725b940b2
commit
dfc5f959f3
6 changed files with 118 additions and 51 deletions
|
@ -2049,6 +2049,16 @@ It generally does map to one of the other relocation types. */
|
|||
not stored in the instruction. */
|
||||
BFD_RELOC_ARM_PCREL_BRANCH,
|
||||
|
||||
/* ARM 26 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. */
|
||||
BFD_RELOC_ARM_PCREL_BLX,
|
||||
|
||||
/* 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. */
|
||||
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,
|
||||
|
@ -2305,7 +2315,6 @@ significant 7 bits of a 23-bit extended address are placed into
|
|||
the opcode. */
|
||||
BFD_RELOC_TIC54X_MS7_OF_23,
|
||||
|
||||
|
||||
/* This is a 48 bit reloc for the FR30 that stores 32 bits. */
|
||||
BFD_RELOC_FR30_48,
|
||||
|
||||
|
|
|
@ -775,10 +775,10 @@ error_return:
|
|||
moves the computed address into the PC, so it must be the second one
|
||||
in the sequence. The problem, however is that whilst little endian code
|
||||
stores the instructions in HI then LOW order, big endian code does the
|
||||
reverse. nickc@cygnus.com */
|
||||
reverse. nickc@cygnus.com. */
|
||||
|
||||
#define LOW_HI_ORDER 0xF800F000
|
||||
#define HI_LOW_ORDER 0xF000F800
|
||||
#define LOW_HI_ORDER 0xF800F000
|
||||
#define HI_LOW_ORDER 0xF000F800
|
||||
|
||||
static insn32
|
||||
insert_thumb_branch (br_insn, rel_off)
|
||||
|
@ -791,9 +791,9 @@ insert_thumb_branch (br_insn, rel_off)
|
|||
|
||||
BFD_ASSERT ((rel_off & 1) != 1);
|
||||
|
||||
rel_off >>= 1; /* half word aligned address */
|
||||
low_bits = rel_off & 0x000007FF; /* the bottom 11 bits */
|
||||
high_bits = (rel_off >> 11) & 0x000007FF; /* the top 11 bits */
|
||||
rel_off >>= 1; /* Half word aligned address. */
|
||||
low_bits = rel_off & 0x000007FF; /* The bottom 11 bits. */
|
||||
high_bits = (rel_off >> 11) & 0x000007FF; /* The top 11 bits. */
|
||||
|
||||
if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
|
||||
br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
|
||||
|
@ -803,7 +803,7 @@ insert_thumb_branch (br_insn, rel_off)
|
|||
abort (); /* error - not a valid branch instruction form */
|
||||
|
||||
/* FIXME: abort is probably not the right call. krk@cygnus.com */
|
||||
|
||||
|
||||
return br_insn;
|
||||
}
|
||||
|
||||
|
@ -1062,6 +1062,9 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
|||
case R_ARM_PC24:
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_REL32:
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_XPC25:
|
||||
#endif
|
||||
/* When generating a shared object, these relocations are copied
|
||||
into the output file to be resolved at run time. */
|
||||
|
||||
|
@ -1171,16 +1174,33 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
|||
}
|
||||
else switch (r_type)
|
||||
{
|
||||
case R_ARM_PC24:
|
||||
/* Arm B/BL instruction */
|
||||
|
||||
/* Check for arm calling thumb function. */
|
||||
if (sym_flags == STT_ARM_TFUNC)
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_XPC25: /* Arm BLX instruction. */
|
||||
#endif
|
||||
case R_ARM_PC24: /* Arm B/BL instruction */
|
||||
#ifndef OLD_ARM_ABI
|
||||
if (r_type == R_ARM_XPC25)
|
||||
{
|
||||
elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
|
||||
input_section, hit_data, sym_sec, rel->r_offset,
|
||||
signed_addend, value);
|
||||
return bfd_reloc_ok;
|
||||
/* Check for Arm calling Arm function. */
|
||||
/* FIXME: Should we translate the instruction into a BL
|
||||
instruction instead ? */
|
||||
if (sym_flags != STT_ARM_TFUNC)
|
||||
_bfd_error_handler (_("\
|
||||
%s: Warning: Arm BLX instruction targets Arm function '%s'."),
|
||||
bfd_get_filename (input_bfd),
|
||||
h->root.root.string);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Check for Arm calling Thumb function. */
|
||||
if (sym_flags == STT_ARM_TFUNC)
|
||||
{
|
||||
elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
|
||||
input_section, hit_data, sym_sec, rel->r_offset,
|
||||
signed_addend, value);
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
}
|
||||
|
||||
if ( strcmp (bfd_get_target (input_bfd), "elf32-littlearm-oabi") == 0
|
||||
|
@ -1321,8 +1341,11 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
|||
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:
|
||||
/* Thumb BL (branch long instruction). */
|
||||
/* Thumb BL (branch long instruction). */
|
||||
{
|
||||
bfd_vma relocation;
|
||||
boolean overflow = false;
|
||||
|
@ -1344,18 +1367,33 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
|||
signed_addend = addend;
|
||||
}
|
||||
#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
|
||||
function call at all, but rather a long jump. */
|
||||
if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION)
|
||||
#ifndef OLD_ARM_ABI
|
||||
if (r_type == R_ARM_THM_XPC22)
|
||||
{
|
||||
if (elf32_thumb_to_arm_stub
|
||||
(info, sym_name, input_bfd, output_bfd, input_section,
|
||||
hit_data, sym_sec, rel->r_offset, signed_addend, value))
|
||||
return bfd_reloc_ok;
|
||||
else
|
||||
return bfd_reloc_dangerous;
|
||||
/* Check for Thumb to Thumb call. */
|
||||
/* FIXME: Should we translate the instruction into a BL
|
||||
instruction instead ? */
|
||||
if (sym_flags == STT_ARM_TFUNC)
|
||||
_bfd_error_handler (_("\
|
||||
%s: Warning: Thumb BLX instruction targets thumb function '%s'."),
|
||||
bfd_get_filename (input_bfd),
|
||||
h->root.root.string);
|
||||
}
|
||||
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
|
||||
function call at all, but rather a long jump. */
|
||||
if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION)
|
||||
{
|
||||
if (elf32_thumb_to_arm_stub
|
||||
(info, sym_name, input_bfd, output_bfd, input_section,
|
||||
hit_data, sym_sec, rel->r_offset, signed_addend, value))
|
||||
return bfd_reloc_ok;
|
||||
else
|
||||
return bfd_reloc_dangerous;
|
||||
}
|
||||
}
|
||||
|
||||
relocation = value + signed_addend;
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
static reloc_howto_type * elf32_arm_reloc_type_lookup
|
||||
PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
|
||||
|
||||
/* 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[] =
|
||||
{
|
||||
/* No relocation */
|
||||
|
@ -262,35 +266,35 @@ static reloc_howto_type elf32_arm_howto_table[] =
|
|||
0x00000000, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* These next two relocs are defined, but I do not know what they do. */
|
||||
|
||||
/* BLX instruction for the ARM. */
|
||||
HOWTO (R_ARM_XPC25, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
2, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
25, /* bitsize */
|
||||
true, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_signed,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_XPC25", /* name */
|
||||
false, /* partial_inplace */
|
||||
0x00000000, /* src_mask */
|
||||
0x00000000, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
0x00ffffff, /* src_mask */
|
||||
0x00ffffff, /* dst_mask */
|
||||
true), /* pcrel_offset */
|
||||
|
||||
/* BLX instruction for the Thumb. */
|
||||
HOWTO (R_ARM_THM_XPC22, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
2, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
22, /* bitsize */
|
||||
true, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_signed,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_THM_XPC22", /* name */
|
||||
false, /* partial_inplace */
|
||||
0x00000000, /* src_mask */
|
||||
0x00000000, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
0x07ff07ff, /* src_mask */
|
||||
0x07ff07ff, /* dst_mask */
|
||||
true), /* pcrel_offset */
|
||||
|
||||
/* These next three relocs are not defined, but we need to fill the space. */
|
||||
|
||||
|
@ -622,6 +626,8 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
|
|||
{
|
||||
{BFD_RELOC_NONE, R_ARM_NONE},
|
||||
{BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24},
|
||||
{BFD_RELOC_ARM_PCREL_BLX, R_ARM_XPC25},
|
||||
{BFD_RELOC_THUMB_PCREL_BLX, R_ARM_THM_XPC22},
|
||||
{BFD_RELOC_32, R_ARM_ABS32},
|
||||
{BFD_RELOC_32_PCREL, R_ARM_REL32},
|
||||
{BFD_RELOC_8, R_ARM_ABS8},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* 32-bit ELF support for ARM old abi option.
|
||||
Copyright 1999 Free Software Foundation, Inc.
|
||||
Copyright 1999, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
|
@ -17,7 +17,9 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "elf/arm-oabi.h"
|
||||
#define OLD_ARM_ABI
|
||||
|
||||
#include "elf/arm.h"
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
|
|
@ -765,6 +765,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
|||
"BFD_RELOC_I370_D12",
|
||||
"BFD_RELOC_CTOR",
|
||||
"BFD_RELOC_ARM_PCREL_BRANCH",
|
||||
"BFD_RELOC_ARM_PCREL_BLX",
|
||||
"BFD_RELOC_THUMB_PCREL_BLX",
|
||||
"BFD_RELOC_ARM_IMMEDIATE",
|
||||
"BFD_RELOC_ARM_ADRL_IMMEDIATE",
|
||||
"BFD_RELOC_ARM_OFFSET_IMM",
|
||||
|
|
16
bfd/reloc.c
16
bfd/reloc.c
|
@ -25,7 +25,7 @@ SECTION
|
|||
|
||||
BFD maintains relocations in much the same way it maintains
|
||||
symbols: they are left alone until required, then read in
|
||||
en-masse and translated into an internal form. A common
|
||||
en-mass and translated into an internal form. A common
|
||||
routine <<bfd_perform_relocation>> acts upon the
|
||||
canonical form to do the fixup.
|
||||
|
||||
|
@ -2201,6 +2201,18 @@ ENUM
|
|||
ENUMDOC
|
||||
ARM 26 bit pc-relative branch. The lowest two bits must be zero and are
|
||||
not stored in the instruction.
|
||||
ENUM
|
||||
BFD_RELOC_ARM_PCREL_BLX
|
||||
ENUMDOC
|
||||
ARM 26 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_THUMB_PCREL_BLX
|
||||
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
|
||||
ENUMX
|
||||
|
@ -2539,7 +2551,6 @@ ENUMDOC
|
|||
significant 8 bits of a 24 bit word are placed into the least
|
||||
significant 8 bits of the opcode.
|
||||
|
||||
COMMENT
|
||||
ENUM
|
||||
BFD_RELOC_TIC54X_PARTLS7
|
||||
ENUMDOC
|
||||
|
@ -2572,7 +2583,6 @@ ENUMDOC
|
|||
This is a reloc for the tms320c54x, where the most
|
||||
significant 7 bits of a 23-bit extended address are placed into
|
||||
the opcode.
|
||||
COMMENT
|
||||
|
||||
ENUM
|
||||
BFD_RELOC_FR30_48
|
||||
|
|
Loading…
Reference in a new issue