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. */
|
not stored in the instruction. */
|
||||||
BFD_RELOC_ARM_PCREL_BRANCH,
|
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
|
/* These relocs are only used within the ARM assembler. They are not
|
||||||
(at present) written to any object files. */
|
(at present) written to any object files. */
|
||||||
BFD_RELOC_ARM_IMMEDIATE,
|
BFD_RELOC_ARM_IMMEDIATE,
|
||||||
|
@ -2305,7 +2315,6 @@ significant 7 bits of a 23-bit extended address are placed into
|
||||||
the opcode. */
|
the opcode. */
|
||||||
BFD_RELOC_TIC54X_MS7_OF_23,
|
BFD_RELOC_TIC54X_MS7_OF_23,
|
||||||
|
|
||||||
|
|
||||||
/* This is a 48 bit reloc for the FR30 that stores 32 bits. */
|
/* This is a 48 bit reloc for the FR30 that stores 32 bits. */
|
||||||
BFD_RELOC_FR30_48,
|
BFD_RELOC_FR30_48,
|
||||||
|
|
||||||
|
|
|
@ -775,10 +775,10 @@ error_return:
|
||||||
moves the computed address into the PC, so it must be the second one
|
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
|
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
|
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 LOW_HI_ORDER 0xF800F000
|
||||||
#define HI_LOW_ORDER 0xF000F800
|
#define HI_LOW_ORDER 0xF000F800
|
||||||
|
|
||||||
static insn32
|
static insn32
|
||||||
insert_thumb_branch (br_insn, rel_off)
|
insert_thumb_branch (br_insn, rel_off)
|
||||||
|
@ -791,9 +791,9 @@ insert_thumb_branch (br_insn, rel_off)
|
||||||
|
|
||||||
BFD_ASSERT ((rel_off & 1) != 1);
|
BFD_ASSERT ((rel_off & 1) != 1);
|
||||||
|
|
||||||
rel_off >>= 1; /* half word aligned address */
|
rel_off >>= 1; /* Half word aligned address. */
|
||||||
low_bits = rel_off & 0x000007FF; /* the bottom 11 bits */
|
low_bits = rel_off & 0x000007FF; /* The bottom 11 bits. */
|
||||||
high_bits = (rel_off >> 11) & 0x000007FF; /* the top 11 bits */
|
high_bits = (rel_off >> 11) & 0x000007FF; /* The top 11 bits. */
|
||||||
|
|
||||||
if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
|
if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
|
||||||
br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
|
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 */
|
abort (); /* error - not a valid branch instruction form */
|
||||||
|
|
||||||
/* FIXME: abort is probably not the right call. krk@cygnus.com */
|
/* FIXME: abort is probably not the right call. krk@cygnus.com */
|
||||||
|
|
||||||
return br_insn;
|
return br_insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1062,6 +1062,9 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
case R_ARM_PC24:
|
case R_ARM_PC24:
|
||||||
case R_ARM_ABS32:
|
case R_ARM_ABS32:
|
||||||
case R_ARM_REL32:
|
case R_ARM_REL32:
|
||||||
|
#ifndef OLD_ARM_ABI
|
||||||
|
case R_ARM_XPC25:
|
||||||
|
#endif
|
||||||
/* When generating a shared object, these relocations are copied
|
/* When generating a shared object, these relocations are copied
|
||||||
into the output file to be resolved at run time. */
|
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)
|
else switch (r_type)
|
||||||
{
|
{
|
||||||
case R_ARM_PC24:
|
#ifndef OLD_ARM_ABI
|
||||||
/* Arm B/BL instruction */
|
case R_ARM_XPC25: /* Arm BLX instruction. */
|
||||||
|
#endif
|
||||||
/* Check for arm calling thumb function. */
|
case R_ARM_PC24: /* Arm B/BL instruction */
|
||||||
if (sym_flags == STT_ARM_TFUNC)
|
#ifndef OLD_ARM_ABI
|
||||||
|
if (r_type == R_ARM_XPC25)
|
||||||
{
|
{
|
||||||
elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
|
/* Check for Arm calling Arm function. */
|
||||||
input_section, hit_data, sym_sec, rel->r_offset,
|
/* FIXME: Should we translate the instruction into a BL
|
||||||
signed_addend, value);
|
instruction instead ? */
|
||||||
return bfd_reloc_ok;
|
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
|
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);
|
bfd_put_16 (input_bfd, value, hit_data);
|
||||||
return bfd_reloc_ok;
|
return bfd_reloc_ok;
|
||||||
|
|
||||||
|
#ifndef OLD_ARM_ABI
|
||||||
|
case R_ARM_THM_XPC22:
|
||||||
|
#endif
|
||||||
case R_ARM_THM_PC22:
|
case R_ARM_THM_PC22:
|
||||||
/* Thumb BL (branch long instruction). */
|
/* Thumb BL (branch long instruction). */
|
||||||
{
|
{
|
||||||
bfd_vma relocation;
|
bfd_vma relocation;
|
||||||
boolean overflow = false;
|
boolean overflow = false;
|
||||||
|
@ -1344,18 +1367,33 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
signed_addend = addend;
|
signed_addend = addend;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef OLD_ARM_ABI
|
||||||
/* If it is not a call to thumb, assume call to arm.
|
if (r_type == R_ARM_THM_XPC22)
|
||||||
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
|
/* Check for Thumb to Thumb call. */
|
||||||
(info, sym_name, input_bfd, output_bfd, input_section,
|
/* FIXME: Should we translate the instruction into a BL
|
||||||
hit_data, sym_sec, rel->r_offset, signed_addend, value))
|
instruction instead ? */
|
||||||
return bfd_reloc_ok;
|
if (sym_flags == STT_ARM_TFUNC)
|
||||||
else
|
_bfd_error_handler (_("\
|
||||||
return bfd_reloc_dangerous;
|
%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;
|
relocation = value + signed_addend;
|
||||||
|
|
|
@ -43,6 +43,10 @@
|
||||||
static reloc_howto_type * elf32_arm_reloc_type_lookup
|
static reloc_howto_type * elf32_arm_reloc_type_lookup
|
||||||
PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
|
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[] =
|
static reloc_howto_type elf32_arm_howto_table[] =
|
||||||
{
|
{
|
||||||
/* No relocation */
|
/* No relocation */
|
||||||
|
@ -262,35 +266,35 @@ static reloc_howto_type elf32_arm_howto_table[] =
|
||||||
0x00000000, /* dst_mask */
|
0x00000000, /* dst_mask */
|
||||||
false), /* pcrel_offset */
|
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 */
|
HOWTO (R_ARM_XPC25, /* type */
|
||||||
0, /* rightshift */
|
2, /* rightshift */
|
||||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
0, /* bitsize */
|
25, /* bitsize */
|
||||||
false, /* pc_relative */
|
true, /* pc_relative */
|
||||||
0, /* bitpos */
|
0, /* bitpos */
|
||||||
complain_overflow_signed,/* complain_on_overflow */
|
complain_overflow_signed,/* complain_on_overflow */
|
||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_ARM_XPC25", /* name */
|
"R_ARM_XPC25", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0x00000000, /* src_mask */
|
0x00ffffff, /* src_mask */
|
||||||
0x00000000, /* dst_mask */
|
0x00ffffff, /* dst_mask */
|
||||||
false), /* pcrel_offset */
|
true), /* pcrel_offset */
|
||||||
|
|
||||||
|
/* BLX instruction for the Thumb. */
|
||||||
HOWTO (R_ARM_THM_XPC22, /* type */
|
HOWTO (R_ARM_THM_XPC22, /* type */
|
||||||
0, /* rightshift */
|
2, /* rightshift */
|
||||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
0, /* bitsize */
|
22, /* bitsize */
|
||||||
false, /* pc_relative */
|
true, /* pc_relative */
|
||||||
0, /* bitpos */
|
0, /* bitpos */
|
||||||
complain_overflow_signed,/* complain_on_overflow */
|
complain_overflow_signed,/* complain_on_overflow */
|
||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_ARM_THM_XPC22", /* name */
|
"R_ARM_THM_XPC22", /* name */
|
||||||
false, /* partial_inplace */
|
false, /* partial_inplace */
|
||||||
0x00000000, /* src_mask */
|
0x07ff07ff, /* src_mask */
|
||||||
0x00000000, /* dst_mask */
|
0x07ff07ff, /* dst_mask */
|
||||||
false), /* pcrel_offset */
|
true), /* pcrel_offset */
|
||||||
|
|
||||||
/* These next three relocs are not defined, but we need to fill the space. */
|
/* 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_NONE, R_ARM_NONE},
|
||||||
{BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24},
|
{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, R_ARM_ABS32},
|
||||||
{BFD_RELOC_32_PCREL, R_ARM_REL32},
|
{BFD_RELOC_32_PCREL, R_ARM_REL32},
|
||||||
{BFD_RELOC_8, R_ARM_ABS8},
|
{BFD_RELOC_8, R_ARM_ABS8},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* 32-bit ELF support for ARM old abi option.
|
/* 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.
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
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 "bfd.h"
|
||||||
#include "sysdep.h"
|
#include "sysdep.h"
|
||||||
#include "libbfd.h"
|
#include "libbfd.h"
|
||||||
|
|
|
@ -765,6 +765,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
||||||
"BFD_RELOC_I370_D12",
|
"BFD_RELOC_I370_D12",
|
||||||
"BFD_RELOC_CTOR",
|
"BFD_RELOC_CTOR",
|
||||||
"BFD_RELOC_ARM_PCREL_BRANCH",
|
"BFD_RELOC_ARM_PCREL_BRANCH",
|
||||||
|
"BFD_RELOC_ARM_PCREL_BLX",
|
||||||
|
"BFD_RELOC_THUMB_PCREL_BLX",
|
||||||
"BFD_RELOC_ARM_IMMEDIATE",
|
"BFD_RELOC_ARM_IMMEDIATE",
|
||||||
"BFD_RELOC_ARM_ADRL_IMMEDIATE",
|
"BFD_RELOC_ARM_ADRL_IMMEDIATE",
|
||||||
"BFD_RELOC_ARM_OFFSET_IMM",
|
"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
|
BFD maintains relocations in much the same way it maintains
|
||||||
symbols: they are left alone until required, then read in
|
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
|
routine <<bfd_perform_relocation>> acts upon the
|
||||||
canonical form to do the fixup.
|
canonical form to do the fixup.
|
||||||
|
|
||||||
|
@ -2201,6 +2201,18 @@ ENUM
|
||||||
ENUMDOC
|
ENUMDOC
|
||||||
ARM 26 bit pc-relative branch. The lowest two bits must be zero and are
|
ARM 26 bit pc-relative branch. The lowest two bits must be zero and are
|
||||||
not stored in the instruction.
|
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
|
ENUM
|
||||||
BFD_RELOC_ARM_IMMEDIATE
|
BFD_RELOC_ARM_IMMEDIATE
|
||||||
ENUMX
|
ENUMX
|
||||||
|
@ -2539,7 +2551,6 @@ ENUMDOC
|
||||||
significant 8 bits of a 24 bit word are placed into the least
|
significant 8 bits of a 24 bit word are placed into the least
|
||||||
significant 8 bits of the opcode.
|
significant 8 bits of the opcode.
|
||||||
|
|
||||||
COMMENT
|
|
||||||
ENUM
|
ENUM
|
||||||
BFD_RELOC_TIC54X_PARTLS7
|
BFD_RELOC_TIC54X_PARTLS7
|
||||||
ENUMDOC
|
ENUMDOC
|
||||||
|
@ -2572,7 +2583,6 @@ ENUMDOC
|
||||||
This is a reloc for the tms320c54x, where the most
|
This is a reloc for the tms320c54x, where the most
|
||||||
significant 7 bits of a 23-bit extended address are placed into
|
significant 7 bits of a 23-bit extended address are placed into
|
||||||
the opcode.
|
the opcode.
|
||||||
COMMENT
|
|
||||||
|
|
||||||
ENUM
|
ENUM
|
||||||
BFD_RELOC_FR30_48
|
BFD_RELOC_FR30_48
|
||||||
|
|
Loading…
Reference in a new issue