/* 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;
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;
_bfd_error_handler (_("Invalid TARGET2 relocation type '%s'."),
target2_type);
}
+ globals->fix_v4bx = fix_v4bx;
}
#endif
(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))
break;
case R_ARM_THM_PC11:
+ case R_ARM_THM_PC9:
/* Thumb B (branch) instruction). */
{
bfd_signed_vma relocation;
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;
}
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);
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
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
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. */
/* 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
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
{
#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
/* 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 }
};
#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
+#define elf_backend_default_use_rela_p 0
#undef elf_backend_rela_normal
#define elf_backend_rela_normal 0