Fix interworking problems.

This commit is contained in:
Nick Clifton 1999-08-12 08:37:15 +00:00
parent 183df869b6
commit bcbdc74cb2
2 changed files with 51 additions and 34 deletions

View file

@ -1,3 +1,13 @@
1999-08-12 Nick Clifton <nickc@cygnus.com>
* elf32-arm.h (elf32_arm_to_thumb_stub): Make 'offset' parameter
into a bfd_vma and 'addend' parameter a 'bfd_signed_vma'.
(elf32_thumb_to_arm_stub): Make 'offset' parameter into a bfd_vma
and 'addend' parameter a 'bfd_signed_vma'.
(elf32_arm_final_link_relocate): Do not involve stubs in
R_ARM_THM_PC22 relocs relative to section symbols, they are long
jumps, not function calls.
1999-08-11 Robin Farine <advanc@dial.eunet.ch>
* elf32-arm.h (elf32_arm_final_link_relocate): Check for overflow

View file

@ -50,6 +50,12 @@ static void record_thumb_to_arm_glue
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
static void elf32_arm_post_process_headers
PARAMS ((bfd *, struct bfd_link_info *));
static int elf32_arm_to_thumb_stub
PARAMS ((struct bfd_link_info *, const char *, bfd *, bfd *, asection *,
bfd_byte *, asection *, bfd_vma, bfd_signed_vma, bfd_vma));
static int elf32_thumb_to_arm_stub
PARAMS ((struct bfd_link_info *, const char *, bfd *, bfd *, asection *,
bfd_byte *, asection *, bfd_vma, bfd_signed_vma, bfd_vma));
/* The linker script knows the section names for placement.
The entry_names are used to do simple name mangling on the stubs.
@ -709,7 +715,7 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
case R_ARM_THM_PC22:
/* 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. */
target, we insert glue. */
if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC)
record_thumb_to_arm_glue (link_info, h);
@ -795,23 +801,23 @@ insert_thumb_branch (br_insn, rel_off)
static int
elf32_thumb_to_arm_stub (info, name, input_bfd, output_bfd, input_section,
hit_data, sym_sec, offset, addend, val)
struct bfd_link_info *info;
char *name;
bfd *input_bfd;
bfd *output_bfd;
asection *input_section;
bfd_byte *hit_data;
asection *sym_sec;
int offset;
int addend;
bfd_vma val;
struct bfd_link_info * info;
const char * name;
bfd * input_bfd;
bfd * output_bfd;
asection * input_section;
bfd_byte * hit_data;
asection * sym_sec;
bfd_vma offset;
bfd_signed_vma addend;
bfd_vma val;
{
asection *s = 0;
asection * s = 0;
long int my_offset;
unsigned long int tmp;
long int ret_offset;
struct elf_link_hash_entry *myh;
struct elf32_arm_link_hash_table *globals;
struct elf_link_hash_entry * myh;
struct elf32_arm_link_hash_table * globals;
myh = find_thumb_glue (info, name, input_bfd);
if (myh == NULL)
@ -895,24 +901,23 @@ elf32_thumb_to_arm_stub (info, name, input_bfd, output_bfd, input_section,
static int
elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,
hit_data, sym_sec, offset, addend, val)
struct bfd_link_info *info;
char *name;
bfd *input_bfd;
bfd *output_bfd;
asection *input_section;
bfd_byte *hit_data;
asection *sym_sec;
int offset;
int addend;
bfd_vma val;
struct bfd_link_info * info;
const char * name;
bfd * input_bfd;
bfd * output_bfd;
asection * input_section;
bfd_byte * hit_data;
asection * sym_sec;
bfd_vma offset;
bfd_signed_vma addend;
bfd_vma val;
{
unsigned long int tmp;
long int my_offset;
asection *s;
asection * s;
long int ret_offset;
struct elf_link_hash_entry *myh;
struct elf32_arm_link_hash_table *globals;
struct elf_link_hash_entry * myh;
struct elf32_arm_link_hash_table * globals;
myh = find_arm_glue (info, name, input_bfd);
if (myh == NULL)
@ -970,13 +975,12 @@ elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,
+ input_section->output_section->vma
+ offset + addend)
- 8;
tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
bfd_put_32 (output_bfd, tmp, hit_data
- input_section->vma);
return true;
}
@ -1164,7 +1168,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
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, addend, value);
input_section, hit_data, sym_sec, rel->r_offset,
signed_addend, value);
return bfd_reloc_ok;
}
@ -1323,12 +1328,14 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
}
#endif
/* If it's not a call to thumb, assume call to arm */
if (sym_flags != STT_ARM_TFUNC)
/* 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, addend, value))
hit_data, sym_sec, rel->r_offset, signed_addend, value))
return bfd_reloc_ok;
else
return bfd_reloc_dangerous;