Add support for R_ARM_XPC25 and R_ARM_THM_XPC22 relocs

This commit is contained in:
Nick Clifton 2000-04-08 00:10:49 +00:00
parent 8725b940b2
commit dfc5f959f3
6 changed files with 118 additions and 51 deletions

View file

@ -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,

View file

@ -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;

View file

@ -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},

View file

@ -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"

View file

@ -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",

View file

@ -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