X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-arm.c;h=f438f03e7071cc754c707c65cad32e2e013550ab;hb=b294bdf8d04c8a3da769f895128cfbb0828ae43d;hp=0b031e0a08bdcec4066796a19299d24c2904436d;hpb=dea514f51da1051f9f3cd7a746e3b68085aa1a72;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 0b031e0a08..f438f03e70 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; @@ -1075,7 +1069,7 @@ static const bfd_vma elf32_arm_plt_thumb_stub [] = address spaces. */ static const bfd_vma elf32_arm_symbian_plt_entry [] = { - 0xe51ff004, /* ldr pr, [pc, #-4] */ + 0xe51ff004, /* ldr pc, [pc, #-4] */ 0x00000000, /* dcd R_ARM_GLOB_DAT(X) */ }; @@ -1171,6 +1165,9 @@ struct elf32_arm_link_hash_table /* The relocation to use for R_ARM_TARGET2 relocations. */ int target2_reloc; + /* Nonzero to fix BX instructions for ARMv4 targets. */ + int fix_v4bx; + /* The number of bytes in the initial entry in the PLT. */ bfd_size_type plt_header_size; @@ -1180,6 +1177,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 +1389,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; @@ -1933,7 +1934,8 @@ error_return: void bfd_elf32_arm_set_target_relocs (struct bfd_link_info *link_info, int target1_is_rel, - char * target2_type) + char * target2_type, + int fix_v4bx) { struct elf32_arm_link_hash_table *globals; @@ -1951,6 +1953,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd_link_info *link_info, _bfd_error_handler (_("Invalid TARGET2 relocation type '%s'."), target2_type); } + globals->fix_v4bx = fix_v4bx; } #endif @@ -2288,20 +2291,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) { @@ -2346,9 +2350,10 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, (bfd_vma) 0); } - /* When generating a shared object, these relocations are copied - into the output file to be resolved at run time. */ - if (info->shared + /* When generating a shared object or relocatable executable, these + relocations are copied into the output file to be resolved at + run time. */ + if ((info->shared || globals->root.is_relocatable_executable) && (input_section->flags & SEC_ALLOC) && (r_type != R_ARM_REL32 || !SYMBOL_CALLS_LOCAL (info, h)) @@ -2508,7 +2513,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 +2611,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 +2644,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) { @@ -2728,6 +2737,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, break; case R_ARM_THM_PC11: + case R_ARM_THM_PC9: /* Thumb B (branch) instruction). */ { bfd_signed_vma relocation; @@ -2735,22 +2745,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 +2791,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 @@ -2980,12 +2992,27 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, case R_ARM_RBASE: return bfd_reloc_notsupported; + case R_ARM_V4BX: + if (globals->fix_v4bx) + { + bfd_vma insn = bfd_get_32 (input_bfd, hit_data); + + /* Ensure that we have a BX instruction. */ + BFD_ASSERT ((insn & 0x0ffffff0) == 0x012fff10); + + /* Preserve Rm (lowest four bits) and the condition code + (highest four bits). Other bits encode MOV PC,Rm. */ + insn = (insn & 0xf000000f) | 0x01a0f000; + + bfd_put_32 (input_bfd, insn, hit_data); + } + return bfd_reloc_ok; + default: return bfd_reloc_notsupported; } } -#if USE_REL /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. */ static void arm_add_to_rel (bfd * abfd, @@ -3059,7 +3086,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 +3105,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 +3137,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 +3158,6 @@ elf32_arm_relocate_section (bfd * output_bfd, continue; } -#endif /* This is a final link. */ h = NULL; @@ -3146,48 +3168,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 { @@ -3428,6 +3451,10 @@ elf32_arm_copy_private_bfd_data (bfd *ibfd, bfd *obfd) elf_elfheader (obfd)->e_flags = in_flags; elf_flags_init (obfd) = TRUE; + /* Also copy the EI_OSABI field. */ + elf_elfheader (obfd)->e_ident[EI_OSABI] = + elf_elfheader (ibfd)->e_ident[EI_OSABI]; + return TRUE; } @@ -3839,8 +3866,6 @@ elf32_arm_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED, struct elf_link_hash_entry **sym_hashes; bfd_signed_vma *local_got_refcounts; const Elf_Internal_Rela *rel, *relend; - unsigned long r_symndx; - struct elf_link_hash_entry *h; struct elf32_arm_link_hash_table * globals; globals = elf32_arm_hash_table (info); @@ -3854,8 +3879,19 @@ elf32_arm_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED, relend = relocs + sec->reloc_count; for (rel = relocs; rel < relend; rel++) { + unsigned long r_symndx; + struct elf_link_hash_entry *h = NULL; int r_type; + r_symndx = ELF32_R_SYM (rel->r_info); + if (r_symndx >= symtab_hdr->sh_info) + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + } + r_type = ELF32_R_TYPE (rel->r_info); #ifndef OLD_ARM_ABI r_type = arm_real_reloc_type (globals, r_type); @@ -3866,10 +3902,8 @@ elf32_arm_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED, #ifndef OLD_ARM_ABI case R_ARM_GOT_PREL: #endif - r_symndx = ELF32_R_SYM (rel->r_info); - if (r_symndx >= symtab_hdr->sh_info) + if (h != NULL) { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; if (h->got.refcount > 0) h->got.refcount -= 1; } @@ -3892,14 +3926,12 @@ elf32_arm_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED, case R_ARM_THM_PC22: /* Should the interworking branches be here also? */ - r_symndx = ELF32_R_SYM (rel->r_info); - if (r_symndx >= symtab_hdr->sh_info) + if (h != NULL) { struct elf32_arm_link_hash_entry *eh; struct elf32_arm_relocs_copied **pp; struct elf32_arm_relocs_copied *p; - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; eh = (struct elf32_arm_link_hash_entry *) h; if (h->plt.refcount > 0) @@ -3955,6 +3987,15 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, htab = elf32_arm_hash_table (info); sreloc = NULL; + /* Create dynamic sections for relocatable executables so that we can + copy relocations. */ + if (htab->root.is_relocatable_executable + && ! htab->root.dynamic_sections_created) + { + if (! _bfd_elf_link_create_dynamic_sections (abfd, info)) + return FALSE; + } + dynobj = elf_hash_table (info)->dynobj; local_got_offsets = elf_local_got_offsets (abfd); @@ -4075,11 +4116,11 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, eh->plt_thumb_refcount += 1; } - /* If we are creating a shared library, and this is a reloc - against a global symbol, or a non PC relative reloc - against a local symbol, then we need to copy the reloc - into the shared library. However, if we are linking with - -Bsymbolic, we do not need to copy a reloc against a + /* If we are creating a shared library or relocatable executable, + and this is a reloc against a global symbol, or a non PC + relative reloc against a local symbol, then we need to copy + the reloc into the shared library. However, if we are linking + with -Bsymbolic, we do not need to copy a reloc against a global symbol which is defined in an object we are including in the link (i.e., DEF_REGULAR is set). At this point we have not seen all the input files, so it is @@ -4087,7 +4128,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, later (it is never cleared). We account for that possibility below by storing information in the relocs_copied field of the hash table entry. */ - if (info->shared + if ((info->shared || htab->root.is_relocatable_executable) && (sec->flags & SEC_ALLOC) != 0 && ((r_type != R_ARM_PC24 && r_type != R_ARM_PLT32 @@ -4347,7 +4388,9 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info, asection * s; unsigned int power_of_two; struct elf32_arm_link_hash_entry * eh; + struct elf32_arm_link_hash_table *globals; + globals = elf32_arm_hash_table (info); dynobj = elf_hash_table (info)->dynobj; /* Make sure we know what is going on here. */ @@ -4412,8 +4455,10 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info, /* If we are creating a shared library, we must presume that the only references to the symbol are via the global offset table. For such cases we need not do anything here; the relocations will - be handled correctly by relocate_section. */ - if (info->shared) + be handled correctly by relocate_section. Relocatable executables + can reference data in shared objects directly, so we don't need to + do anything here. */ + if (info->shared || globals->root.is_relocatable_executable) return TRUE; /* We must allocate the symbol in our .dynbss section, which will @@ -4606,13 +4651,23 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) space for pc-relative relocs that have become local due to symbol visibility changes. */ - if (info->shared) + if (info->shared || htab->root.is_relocatable_executable) { /* Discard relocs on undefined weak syms with non-default visibility. */ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT && h->root.type == bfd_link_hash_undefweak) eh->relocs_copied = NULL; + else if (htab->root.is_relocatable_executable && h->dynindx == -1 + && h->root.type == bfd_link_hash_new) + { + /* Output absolute symbols so that we can create relocations + against them. For normal symbols we output a relocation + against the section that contains them. */ + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + } else { @@ -5352,7 +5407,10 @@ elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATT i_ehdrp = elf_elfheader (abfd); - i_ehdrp->e_ident[EI_OSABI] = ARM_ELF_OS_ABI_VERSION; + if (EF_ARM_EABI_VERSION (i_ehdrp->e_flags) == EF_ARM_EABI_UNKNOWN) + i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_ARM; + else + i_ehdrp->e_ident[EI_OSABI] = 0; i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION; if (link_info) @@ -5652,6 +5710,55 @@ elf32_arm_swap_symbol_out (bfd *abfd, bfd_elf32_swap_symbol_out (abfd, src, cdst, shndx); } +/* Add the PT_ARM_EXIDX program header. */ + +static bfd_boolean +elf32_arm_modify_segment_map (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED) +{ + struct elf_segment_map *m; + asection *sec; + + sec = bfd_get_section_by_name (abfd, ".ARM.exidx"); + if (sec != NULL && (sec->flags & SEC_LOAD) != 0) + { + /* If there is already a PT_ARM_EXIDX header, then we do not + want to add another one. This situation arises when running + "strip"; the input binary already has the header. */ + m = elf_tdata (abfd)->segment_map; + while (m && m->p_type != PT_ARM_EXIDX) + m = m->next; + if (!m) + { + m = bfd_zalloc (abfd, sizeof (struct elf_segment_map)); + if (m == NULL) + return FALSE; + m->p_type = PT_ARM_EXIDX; + m->count = 1; + m->sections[0] = sec; + + m->next = elf_tdata (abfd)->segment_map; + elf_tdata (abfd)->segment_map = m; + } + } + + return TRUE; +} + +/* We may add a PT_ARM_EXIDX program header. */ + +static int +elf32_arm_additional_program_headers (bfd *abfd) +{ + asection *sec; + + sec = bfd_get_section_by_name (abfd, ".ARM.exidx"); + if (sec != NULL && (sec->flags & SEC_LOAD) != 0) + return 1; + else + return 0; +} + /* We use this to override swap_symbol_in and swap_symbol_out. */ const struct elf_size_info elf32_arm_size_info = { sizeof (Elf32_External_Ehdr), @@ -5688,6 +5795,7 @@ const struct elf_size_info elf32_arm_size_info = { #else #define ELF_MAXPAGESIZE 0x8000 #endif +#define ELF_MINPAGESIZE 0x1000 #define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data #define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data @@ -5721,20 +5829,71 @@ const struct elf_size_info elf32_arm_size_info = { #define elf_backend_copy_indirect_symbol elf32_arm_copy_indirect_symbol #define elf_backend_symbol_processing elf32_arm_symbol_processing #define elf_backend_size_info elf32_arm_size_info +#define elf_backend_modify_segment_map elf32_arm_modify_segment_map +#define elf_backend_additional_program_headers \ + elf32_arm_additional_program_headers #define elf_backend_can_refcount 1 #define elf_backend_can_gc_sections 1 #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 @@ -5763,22 +5922,29 @@ elf32_arm_symbian_link_hash_table_create (bfd *abfd) /* The PLT entries are each three instructions. */ htab->plt_entry_size = 4 * NUM_ELEM (elf32_arm_symbian_plt_entry); htab->symbian_p = 1; + htab->root.is_relocatable_executable = 1; } return ret; } -/* In a BPABI executable, the dynamic linking sections do not go in - the loadable read-only segment. The post-linker may wish to refer - to these sections, but they are not part of the final program - image. */ static struct bfd_elf_special_section const elf32_arm_symbian_special_sections[]= { + /* In a BPABI executable, the dynamic linking sections do not go in + the loadable read-only segment. The post-linker may wish to + refer to these sections, but they are not part of the final + program image. */ { ".dynamic", 8, 0, SHT_DYNAMIC, 0 }, { ".dynstr", 7, 0, SHT_STRTAB, 0 }, { ".dynsym", 7, 0, SHT_DYNSYM, 0 }, { ".got", 4, 0, SHT_PROGBITS, 0 }, { ".hash", 5, 0, SHT_HASH, 0 }, + /* These sections do not need to be writable as the SymbianOS + postlinker will arrange things so that no dynamic relocation is + required. */ + { ".init_array", 11, 0, SHT_INIT_ARRAY, SHF_ALLOC }, + { ".fini_array", 11, 0, SHT_FINI_ARRAY, SHF_ALLOC }, + { ".preinit_array", 14, 0, SHT_PREINIT_ARRAY, SHF_ALLOC }, { NULL, 0, 0, 0, 0 } }; @@ -5800,8 +5966,7 @@ elf32_arm_symbian_begin_write_processing (bfd *abfd, static bfd_boolean elf32_arm_symbian_modify_segment_map (bfd *abfd, - struct bfd_link_info *info - ATTRIBUTE_UNUSED) + struct bfd_link_info *info) { struct elf_segment_map *m; asection *dynsec; @@ -5818,7 +5983,8 @@ elf32_arm_symbian_modify_segment_map (bfd *abfd, elf_tdata (abfd)->segment_map = m; } - return TRUE; + /* Also call the generic arm routine. */ + return elf32_arm_modify_segment_map (abfd, info); } #undef elf32_bed @@ -5852,4 +6018,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 0 +#undef elf_backend_rela_normal +#define elf_backend_rela_normal 0 + #include "elf32-target.h"