diff options
author | Paul Brook <paul@codesourcery.com> | 2005-01-06 16:18:25 +0000 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2005-01-06 16:18:25 +0000 |
commit | 4e7fd91e3e0087cccd56dd0ebfbc5e4c5407e1ac (patch) | |
tree | 5814dd042aba6e7422fd6e32edecdb6a536cdb27 /bfd/elf32-arm.c | |
parent | * configure.tgt: Set em=vxworks for *-*-vxworks. (diff) | |
download | binutils-gdb-4e7fd91e3e0087cccd56dd0ebfbc5e4c5407e1ac.tar.gz binutils-gdb-4e7fd91e3e0087cccd56dd0ebfbc5e4c5407e1ac.tar.bz2 binutils-gdb-4e7fd91e3e0087cccd56dd0ebfbc5e4c5407e1ac.zip |
2005-01-06 Paul Brook <paul@codesourcery.com>
bfd/
* config.bfd: Add entry for arm-*-vxworks and arm-*-windiss.
* configure.in: Add bfd_elf32_{big,little}arm_vxworks_vec.
* configure: Regenerate.
* elf32-arm.c: Add VxWorks target bfd.
(USE_REL): Remove.
(elf32_arm_link_hash_table): Add use_rel.
(elf32_arm_link_hash_table_create, elf32_arm_final_link_relocate,
elf32_arm_relocate_section): Replace USE_REL with runtime check.
Correct offset calculation for RELA case.
(elf_backend_may_use_rel_p, elf_backend_may_use_rela_p,
elf_backend_default_use_rela_p, elf_backend_rela_normal): Define.
(elf32_arm_vxworks_link_hash_table_create): New function.
* targets.c (bfd_elf32_bigarm_vxworks_vec): Add declaration.
(bfd_elf32_littlearm_vxworks_vec): Ditto.
(_bfd_target_vector): Add bfd_elf32_{big,little}arm_vxworks_vec.
gas/
* config/tc-arm.c (FPU_DEFAULT): Define for TE_VXWORKS.
(md_begin): Handle TE_VXWORKS for FP defaults.
(md_apply_fix3): Correct rela offsets.
(elf32_arm_target_format): Add VxWorks targets.
ld/
* Makefie.am: Add earmelf_vxworks.
* Makefile.in: Regenerate.
* configure.tgt: Make arm-*-vxworks a separate case.
* emulparams/armelf_vxworks.sh: New function.
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r-- | bfd/elf32-arm.c | 257 |
1 files changed, 157 insertions, 100 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index af3a4a99ce6..1f113e2d1f1 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -1,5 +1,5 @@ /* 32-bit ELF support for ARM - Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -28,8 +28,6 @@ #define NUM_ELEM(a) (sizeof (a) / (sizeof (a)[0])) #endif -#define USE_REL 1 - #define elf_info_to_howto 0 #define elf_info_to_howto_rel elf32_arm_info_to_howto @@ -987,10 +985,6 @@ elf32_arm_nabi_grok_psinfo (abfd, note) #define elf_backend_grok_prstatus elf32_arm_nabi_grok_prstatus #define elf_backend_grok_psinfo elf32_arm_nabi_grok_psinfo -#ifndef USE_REL -#define USE_REL 0 -#endif - typedef unsigned long int insn32; typedef unsigned short int insn16; @@ -1180,6 +1174,9 @@ struct elf32_arm_link_hash_table /* True if the target system is Symbian OS. */ int symbian_p; + /* True if the target uses REL relocations. */ + int use_rel; + /* Short-cuts to get to dynamic linker sections. */ asection *sgot; asection *sgotplt; @@ -1389,6 +1386,7 @@ elf32_arm_link_hash_table_create (bfd *abfd) ret->plt_entry_size = 12; #endif ret->symbian_p = 0; + ret->use_rel = 1; ret->sym_sec.abfd = NULL; ret->obfd = abfd; @@ -2288,20 +2286,21 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, local_got_offsets = elf_local_got_offsets (input_bfd); r_symndx = ELF32_R_SYM (rel->r_info); -#if USE_REL - addend = bfd_get_32 (input_bfd, hit_data) & howto->src_mask; - - if (addend & ((howto->src_mask + 1) >> 1)) + if (globals->use_rel) { - signed_addend = -1; - signed_addend &= ~ howto->src_mask; - signed_addend |= addend; + addend = bfd_get_32 (input_bfd, hit_data) & howto->src_mask; + + if (addend & ((howto->src_mask + 1) >> 1)) + { + signed_addend = -1; + signed_addend &= ~ howto->src_mask; + signed_addend |= addend; + } + else + signed_addend = addend; } else - signed_addend = addend; -#else - addend = signed_addend = rel->r_addend; -#endif + addend = signed_addend = rel->r_addend; switch (r_type) { @@ -2508,7 +2507,11 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, value -= (input_section->output_section->vma + input_section->output_offset); value -= rel->r_offset; - value += (signed_addend << howto->size); + if (globals->use_rel) + value += (signed_addend << howto->size); + else + /* RELA addends do not have to be adjusted by howto->size. */ + value += signed_addend; signed_addend = value; signed_addend >>= howto->rightshift; @@ -2602,12 +2605,13 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, case R_ARM_THM_ABS5: /* Support ldr and str instructions for the thumb. */ -#if USE_REL - /* Need to refetch addend. */ - addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask; - /* ??? Need to determine shift amount from operand size. */ - addend >>= howto->rightshift; -#endif + if (globals->use_rel) + { + /* Need to refetch addend. */ + addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask; + /* ??? Need to determine shift amount from operand size. */ + addend >>= howto->rightshift; + } value += addend; /* ??? Isn't value unsigned? */ @@ -2634,17 +2638,16 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, bfd_vma check; bfd_signed_vma signed_check; -#if USE_REL /* Need to refetch the addend and squish the two 11 bit pieces together. */ - { - bfd_vma upper = upper_insn & 0x7ff; - bfd_vma lower = lower_insn & 0x7ff; - upper = (upper ^ 0x400) - 0x400; /* Sign extend. */ - addend = (upper << 12) | (lower << 1); - signed_addend = addend; - } -#endif + if (globals->use_rel) + { + bfd_vma upper = upper_insn & 0x7ff; + bfd_vma lower = lower_insn & 0x7ff; + upper = (upper ^ 0x400) - 0x400; /* Sign extend. */ + addend = (upper << 12) | (lower << 1); + signed_addend = addend; + } #ifndef OLD_ARM_ABI if (r_type == R_ARM_THM_XPC22) { @@ -2735,22 +2738,23 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, bfd_signed_vma reloc_signed_min = ~ reloc_signed_max; bfd_signed_vma signed_check; -#if USE_REL - /* Need to refetch addend. */ - addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask; - if (addend & ((howto->src_mask + 1) >> 1)) + if (globals->use_rel) { - signed_addend = -1; - signed_addend &= ~ howto->src_mask; - signed_addend |= addend; + /* Need to refetch addend. */ + addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask; + if (addend & ((howto->src_mask + 1) >> 1)) + { + signed_addend = -1; + signed_addend &= ~ howto->src_mask; + signed_addend |= addend; + } + else + signed_addend = addend; + /* The value in the insn has been right shifted. We need to + undo this, so that we can perform the address calculation + in terms of bytes. */ + signed_addend <<= howto->rightshift; } - else - signed_addend = addend; - /* The value in the insn has been right shifted. We need to - undo this, so that we can perform the address calculation - in terms of bytes. */ - signed_addend <<= howto->rightshift; -#endif relocation = value + signed_addend; relocation -= (input_section->output_section->vma @@ -2780,11 +2784,12 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, bfd_vma relocation; insn = bfd_get_32 (input_bfd, hit_data); -#if USE_REL - /* Extract the addend. */ - addend = (insn & 0xff) << ((insn & 0xf00) >> 7); - signed_addend = addend; -#endif + if (globals->use_rel) + { + /* Extract the addend. */ + addend = (insn & 0xff) << ((insn & 0xf00) >> 7); + signed_addend = addend; + } relocation = value + signed_addend; relocation -= (input_section->output_section->vma @@ -2985,7 +2990,6 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, } } -#if USE_REL /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. */ static void arm_add_to_rel (bfd * abfd, @@ -3059,7 +3063,6 @@ arm_add_to_rel (bfd * abfd, bfd_put_32 (abfd, contents, address); } } -#endif /* USE_REL */ /* Relocate an ARM ELF section. */ static bfd_boolean @@ -3079,12 +3082,10 @@ elf32_arm_relocate_section (bfd * output_bfd, const char *name; struct elf32_arm_link_hash_table * globals; -#if !USE_REL - if (info->relocatable) + globals = elf32_arm_hash_table (info); + if (info->relocatable && !globals->use_rel) return TRUE; -#endif - globals = elf32_arm_hash_table (info); symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; sym_hashes = elf_sym_hashes (input_bfd); @@ -3113,8 +3114,7 @@ elf32_arm_relocate_section (bfd * output_bfd, bfd_reloc.howto = elf32_arm_howto_from_type (r_type); howto = bfd_reloc.howto; -#if USE_REL - if (info->relocatable) + if (info->relocatable && globals->use_rel) { /* This is a relocatable link. We don't have to change anything, unless the reloc is against a section symbol, @@ -3135,7 +3135,6 @@ elf32_arm_relocate_section (bfd * output_bfd, continue; } -#endif /* This is a final link. */ h = NULL; @@ -3146,48 +3145,49 @@ elf32_arm_relocate_section (bfd * output_bfd, { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; -#if USE_REL - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - if ((sec->flags & SEC_MERGE) - && ELF_ST_TYPE (sym->st_info) == STT_SECTION) + if (globals->use_rel) { - asection *msec; - bfd_vma addend, value; - - if (howto->rightshift) + relocation = (sec->output_section->vma + + sec->output_offset + + sym->st_value); + if ((sec->flags & SEC_MERGE) + && ELF_ST_TYPE (sym->st_info) == STT_SECTION) { - (*_bfd_error_handler) - (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"), - input_bfd, input_section, - (long) rel->r_offset, howto->name); - return FALSE; - } + asection *msec; + bfd_vma addend, value; + + if (howto->rightshift) + { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"), + input_bfd, input_section, + (long) rel->r_offset, howto->name); + return FALSE; + } - value = bfd_get_32 (input_bfd, contents + rel->r_offset); + value = bfd_get_32 (input_bfd, contents + rel->r_offset); - /* Get the (signed) value from the instruction. */ - addend = value & howto->src_mask; - if (addend & ((howto->src_mask + 1) >> 1)) - { - bfd_signed_vma mask; + /* Get the (signed) value from the instruction. */ + addend = value & howto->src_mask; + if (addend & ((howto->src_mask + 1) >> 1)) + { + bfd_signed_vma mask; - mask = -1; - mask &= ~ howto->src_mask; - addend |= mask; + mask = -1; + mask &= ~ howto->src_mask; + addend |= mask; + } + msec = sec; + addend = + _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) + - relocation; + addend += msec->output_section->vma + msec->output_offset; + value = (value & ~ howto->dst_mask) | (addend & howto->dst_mask); + bfd_put_32 (input_bfd, value, contents + rel->r_offset); } - msec = sec; - addend = - _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - - relocation; - addend += msec->output_section->vma + msec->output_offset; - value = (value & ~ howto->dst_mask) | (addend & howto->dst_mask); - bfd_put_32 (input_bfd, value, contents + rel->r_offset); } -#else - relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); -#endif + else + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); } else { @@ -5734,14 +5734,62 @@ const struct elf_size_info elf32_arm_size_info = { #define elf_backend_plt_readonly 1 #define elf_backend_want_got_plt 1 #define elf_backend_want_plt_sym 0 -#if !USE_REL -#define elf_backend_rela_normal 1 -#endif +#define elf_backend_may_use_rel_p 1 +#define elf_backend_may_use_rela_p 0 +#define elf_backend_default_use_rela_p 0 +#define elf_backend_rela_normal 0 #define elf_backend_got_header_size 12 #include "elf32-target.h" +/* VxWorks Targets */ + +#undef TARGET_LITTLE_SYM +#define TARGET_LITTLE_SYM bfd_elf32_littlearm_vxworks_vec +#undef TARGET_LITTLE_NAME +#define TARGET_LITTLE_NAME "elf32-littlearm-vxworks" +#undef TARGET_BIG_SYM +#define TARGET_BIG_SYM bfd_elf32_bigarm_vxworks_vec +#undef TARGET_BIG_NAME +#define TARGET_BIG_NAME "elf32-bigarm-vxworks" + +/* Like elf32_arm_link_hash_table_create -- but overrides + appropriately for VxWorks. */ +static struct bfd_link_hash_table * +elf32_arm_vxworks_link_hash_table_create (bfd *abfd) +{ + struct bfd_link_hash_table *ret; + + ret = elf32_arm_link_hash_table_create (abfd); + if (ret) + { + struct elf32_arm_link_hash_table *htab + = (struct elf32_arm_link_hash_table *)ret; + htab->use_rel = 0; + } + return ret; +} + +#undef elf32_bed +#define elf32_bed elf32_arm_vxworks_bed + +#undef bfd_elf32_bfd_link_hash_table_create +#define bfd_elf32_bfd_link_hash_table_create \ + elf32_arm_vxworks_link_hash_table_create + +#undef elf_backend_may_use_rel_p +#define elf_backend_may_use_rel_p 0 +#undef elf_backend_may_use_rela_p +#define elf_backend_may_use_rela_p 1 +#undef elf_backend_default_use_rela_p +#define elf_backend_default_use_rela_p 1 +#undef elf_backend_rela_normal +#define elf_backend_rela_normal 1 + +#include "elf32-target.h" + + /* Symbian OS Targets */ #undef TARGET_LITTLE_SYM @@ -5859,4 +5907,13 @@ elf32_arm_symbian_modify_segment_map (bfd *abfd, #undef elf_backend_want_got_plt #define elf_backend_want_got_plt 0 +#undef elf_backend_may_use_rel_p +#define elf_backend_may_use_rel_p 1 +#undef elf_backend_may_use_rela_p +#define elf_backend_may_use_rela_p 0 +#undef elf_backend_default_use_rela_p +#define elf_backend_default_use_rela_p 1 +#undef elf_backend_rela_normal +#define elf_backend_rela_normal 0 + #include "elf32-target.h" |