* elf32-arm.c: Tidy up the code.
(bfd_elf32_arm_allocate_interworking_sections): Move common code into... (arm_allocate_glue_section_space): ... New function. (bfd_elf32_arm_add_glue_sections_to_bfd): Move common code into... (arm_make_glue_section): ... New function.
This commit is contained in:
parent
8ad82227d0
commit
8029a119ee
|
@ -1,5 +1,13 @@
|
||||||
2008-08-17 Nick Clifton <nickc@redhat.com>
|
2008-08-17 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* elf32-arm.c: Tidy up the code.
|
||||||
|
(bfd_elf32_arm_allocate_interworking_sections): Move common code
|
||||||
|
into...
|
||||||
|
(arm_allocate_glue_section_space): ... New function.
|
||||||
|
(bfd_elf32_arm_add_glue_sections_to_bfd): Move common code
|
||||||
|
into...
|
||||||
|
(arm_make_glue_section): ... New function.
|
||||||
|
|
||||||
* elfxx-mips.c (_bfd_mips_elf_check_relocs): Handle the situation
|
* elfxx-mips.c (_bfd_mips_elf_check_relocs): Handle the situation
|
||||||
where the sym_hashes are not available.
|
where the sym_hashes are not available.
|
||||||
|
|
||||||
|
|
366
bfd/elf32-arm.c
366
bfd/elf32-arm.c
|
@ -67,7 +67,7 @@ static struct elf_backend_data elf32_arm_vxworks_bed;
|
||||||
|
|
||||||
static reloc_howto_type elf32_arm_howto_table_1[] =
|
static reloc_howto_type elf32_arm_howto_table_1[] =
|
||||||
{
|
{
|
||||||
/* No relocation */
|
/* No relocation. */
|
||||||
HOWTO (R_ARM_NONE, /* type */
|
HOWTO (R_ARM_NONE, /* type */
|
||||||
0, /* rightshift */
|
0, /* rightshift */
|
||||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
@ -1347,7 +1347,7 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
|
||||||
0x040f70ff, /* dst_mask */
|
0x040f70ff, /* dst_mask */
|
||||||
FALSE), /* pcrel_offset */
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
EMPTY_HOWTO (90), /* unallocated */
|
EMPTY_HOWTO (90), /* Unallocated. */
|
||||||
EMPTY_HOWTO (91),
|
EMPTY_HOWTO (91),
|
||||||
EMPTY_HOWTO (92),
|
EMPTY_HOWTO (92),
|
||||||
EMPTY_HOWTO (93),
|
EMPTY_HOWTO (93),
|
||||||
|
@ -1778,6 +1778,7 @@ elf32_arm_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
||||||
bfd_reloc_code_real_type code)
|
bfd_reloc_code_real_type code)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE (elf32_arm_reloc_map); i ++)
|
for (i = 0; i < ARRAY_SIZE (elf32_arm_reloc_map); i ++)
|
||||||
if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
|
if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
|
||||||
return elf32_arm_howto_from_type (elf32_arm_reloc_map[i].elf_reloc_val);
|
return elf32_arm_howto_from_type (elf32_arm_reloc_map[i].elf_reloc_val);
|
||||||
|
@ -1817,7 +1818,7 @@ elf32_arm_nabi_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
case 148: /* Linux/ARM 32-bit*/
|
case 148: /* Linux/ARM 32-bit. */
|
||||||
/* pr_cursig */
|
/* pr_cursig */
|
||||||
elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
|
elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
|
||||||
|
|
||||||
|
@ -1844,7 +1845,7 @@ elf32_arm_nabi_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
case 124: /* Linux/ARM elf_prpsinfo */
|
case 124: /* Linux/ARM elf_prpsinfo. */
|
||||||
elf_tdata (abfd)->core_program
|
elf_tdata (abfd)->core_program
|
||||||
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
|
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
|
||||||
elf_tdata (abfd)->core_command
|
elf_tdata (abfd)->core_command
|
||||||
|
@ -2244,7 +2245,7 @@ struct elf32_arm_link_hash_entry
|
||||||
struct elf_link_hash_entry *export_glue;
|
struct elf_link_hash_entry *export_glue;
|
||||||
|
|
||||||
/* A pointer to the most recently used stub hash entry against this
|
/* A pointer to the most recently used stub hash entry against this
|
||||||
symbol. */
|
symbol. */
|
||||||
struct elf32_arm_stub_hash_entry *stub_cache;
|
struct elf32_arm_stub_hash_entry *stub_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2766,7 +2767,7 @@ arm_type_of_stub (struct bfd_link_info *info,
|
||||||
enum elf32_arm_stub_type stub_type = arm_stub_none;
|
enum elf32_arm_stub_type stub_type = arm_stub_none;
|
||||||
|
|
||||||
/* We don't know the actual type of destination in case it is of
|
/* We don't know the actual type of destination in case it is of
|
||||||
type STT_SECTION: give up */
|
type STT_SECTION: give up. */
|
||||||
if (st_type == STT_SECTION)
|
if (st_type == STT_SECTION)
|
||||||
return stub_type;
|
return stub_type;
|
||||||
|
|
||||||
|
@ -3015,8 +3016,8 @@ elf32_arm_add_stub (const char *stub_name,
|
||||||
elf32_arm_write_section. */
|
elf32_arm_write_section. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_arm_insn (struct elf32_arm_link_hash_table *htab,
|
put_arm_insn (struct elf32_arm_link_hash_table * htab,
|
||||||
bfd * output_bfd, bfd_vma val, void * ptr)
|
bfd * output_bfd, bfd_vma val, void * ptr)
|
||||||
{
|
{
|
||||||
if (htab->byteswap_code != bfd_little_endian (output_bfd))
|
if (htab->byteswap_code != bfd_little_endian (output_bfd))
|
||||||
bfd_putl32 (val, ptr);
|
bfd_putl32 (val, ptr);
|
||||||
|
@ -3028,8 +3029,8 @@ put_arm_insn (struct elf32_arm_link_hash_table *htab,
|
||||||
elf32_arm_write_section. */
|
elf32_arm_write_section. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
put_thumb_insn (struct elf32_arm_link_hash_table *htab,
|
put_thumb_insn (struct elf32_arm_link_hash_table * htab,
|
||||||
bfd * output_bfd, bfd_vma val, void * ptr)
|
bfd * output_bfd, bfd_vma val, void * ptr)
|
||||||
{
|
{
|
||||||
if (htab->byteswap_code != bfd_little_endian (output_bfd))
|
if (htab->byteswap_code != bfd_little_endian (output_bfd))
|
||||||
bfd_putl16 (val, ptr);
|
bfd_putl16 (val, ptr);
|
||||||
|
@ -3716,7 +3717,7 @@ elf32_arm_build_stubs (struct bfd_link_info *info)
|
||||||
{
|
{
|
||||||
bfd_size_type size;
|
bfd_size_type size;
|
||||||
|
|
||||||
/* Ignore non-stub sections */
|
/* Ignore non-stub sections. */
|
||||||
if (!strstr (stub_sec->name, STUB_SUFFIX))
|
if (!strstr (stub_sec->name, STUB_SUFFIX))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -3826,8 +3827,7 @@ find_arm_glue (struct bfd_link_info *link_info,
|
||||||
add r12, r12, pc
|
add r12, r12, pc
|
||||||
bx r12
|
bx r12
|
||||||
__func_offset:
|
__func_offset:
|
||||||
.word func - .
|
.word func - . */
|
||||||
*/
|
|
||||||
|
|
||||||
#define ARM2THUMB_STATIC_GLUE_SIZE 12
|
#define ARM2THUMB_STATIC_GLUE_SIZE 12
|
||||||
static const insn32 a2t1_ldr_insn = 0xe59fc000;
|
static const insn32 a2t1_ldr_insn = 0xe59fc000;
|
||||||
|
@ -3845,19 +3845,18 @@ static const insn32 a2t3p_bx_r12_insn = 0xe12fff1c;
|
||||||
|
|
||||||
/* Thumb->ARM: Thumb->(non-interworking aware) ARM
|
/* Thumb->ARM: Thumb->(non-interworking aware) ARM
|
||||||
|
|
||||||
.thumb .thumb
|
.thumb .thumb
|
||||||
.align 2 .align 2
|
.align 2 .align 2
|
||||||
__func_from_thumb: __func_from_thumb:
|
__func_from_thumb: __func_from_thumb:
|
||||||
bx pc push {r6, lr}
|
bx pc push {r6, lr}
|
||||||
nop ldr r6, __func_addr
|
nop ldr r6, __func_addr
|
||||||
.arm mov lr, pc
|
.arm mov lr, pc
|
||||||
__func_change_to_arm: bx r6
|
b func bx r6
|
||||||
b func .arm
|
;; back_to_thumb .arm
|
||||||
__func_back_to_thumb:
|
ldmia r13! {r6, lr} ldmia r13! {r6, lr}
|
||||||
ldmia r13! {r6, lr}
|
bx lr bx lr
|
||||||
bx lr
|
__func_addr:
|
||||||
__func_addr:
|
.word func */
|
||||||
.word func */
|
|
||||||
|
|
||||||
#define THUMB2ARM_GLUE_SIZE 8
|
#define THUMB2ARM_GLUE_SIZE 8
|
||||||
static const insn16 t2a1_bx_pc_insn = 0x4778;
|
static const insn16 t2a1_bx_pc_insn = 0x4778;
|
||||||
|
@ -3872,78 +3871,50 @@ static const insn32 armbx2_moveq_insn = 0x01a0f000;
|
||||||
static const insn32 armbx3_bx_insn = 0xe12fff10;
|
static const insn32 armbx3_bx_insn = 0xe12fff10;
|
||||||
|
|
||||||
#ifndef ELFARM_NABI_C_INCLUDED
|
#ifndef ELFARM_NABI_C_INCLUDED
|
||||||
|
static void
|
||||||
|
arm_allocate_glue_section_space (bfd * abfd, bfd_size_type size, const char * name)
|
||||||
|
{
|
||||||
|
asection * s;
|
||||||
|
bfd_byte * contents;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BFD_ASSERT (abfd != NULL);
|
||||||
|
|
||||||
|
s = bfd_get_section_by_name (abfd, name);
|
||||||
|
BFD_ASSERT (s != NULL);
|
||||||
|
|
||||||
|
contents = bfd_alloc (abfd, size);
|
||||||
|
|
||||||
|
BFD_ASSERT (s->size == size);
|
||||||
|
s->contents = contents;
|
||||||
|
}
|
||||||
|
|
||||||
bfd_boolean
|
bfd_boolean
|
||||||
bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info)
|
bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info)
|
||||||
{
|
{
|
||||||
asection * s;
|
|
||||||
bfd_byte * foo;
|
|
||||||
struct elf32_arm_link_hash_table * globals;
|
struct elf32_arm_link_hash_table * globals;
|
||||||
|
|
||||||
globals = elf32_arm_hash_table (info);
|
globals = elf32_arm_hash_table (info);
|
||||||
|
|
||||||
BFD_ASSERT (globals != NULL);
|
BFD_ASSERT (globals != NULL);
|
||||||
|
|
||||||
if (globals->arm_glue_size != 0)
|
arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
|
||||||
{
|
globals->arm_glue_size,
|
||||||
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
|
|
||||||
|
|
||||||
s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
|
|
||||||
ARM2THUMB_GLUE_SECTION_NAME);
|
ARM2THUMB_GLUE_SECTION_NAME);
|
||||||
|
|
||||||
BFD_ASSERT (s != NULL);
|
arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
|
||||||
|
globals->thumb_glue_size,
|
||||||
|
THUMB2ARM_GLUE_SECTION_NAME);
|
||||||
|
|
||||||
foo = bfd_alloc (globals->bfd_of_glue_owner, globals->arm_glue_size);
|
arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
|
||||||
|
globals->vfp11_erratum_glue_size,
|
||||||
|
VFP11_ERRATUM_VENEER_SECTION_NAME);
|
||||||
|
|
||||||
BFD_ASSERT (s->size == globals->arm_glue_size);
|
arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
|
||||||
s->contents = foo;
|
globals->bx_glue_size,
|
||||||
}
|
|
||||||
|
|
||||||
if (globals->thumb_glue_size != 0)
|
|
||||||
{
|
|
||||||
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
|
|
||||||
|
|
||||||
s = bfd_get_section_by_name
|
|
||||||
(globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
|
|
||||||
|
|
||||||
BFD_ASSERT (s != NULL);
|
|
||||||
|
|
||||||
foo = bfd_alloc (globals->bfd_of_glue_owner, globals->thumb_glue_size);
|
|
||||||
|
|
||||||
BFD_ASSERT (s->size == globals->thumb_glue_size);
|
|
||||||
s->contents = foo;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (globals->vfp11_erratum_glue_size != 0)
|
|
||||||
{
|
|
||||||
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
|
|
||||||
|
|
||||||
s = bfd_get_section_by_name
|
|
||||||
(globals->bfd_of_glue_owner, VFP11_ERRATUM_VENEER_SECTION_NAME);
|
|
||||||
|
|
||||||
BFD_ASSERT (s != NULL);
|
|
||||||
|
|
||||||
foo = bfd_alloc (globals->bfd_of_glue_owner,
|
|
||||||
globals->vfp11_erratum_glue_size);
|
|
||||||
|
|
||||||
BFD_ASSERT (s->size == globals->vfp11_erratum_glue_size);
|
|
||||||
s->contents = foo;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (globals->bx_glue_size != 0)
|
|
||||||
{
|
|
||||||
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
|
|
||||||
|
|
||||||
s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
|
|
||||||
ARM_BX_GLUE_SECTION_NAME);
|
ARM_BX_GLUE_SECTION_NAME);
|
||||||
|
|
||||||
BFD_ASSERT (s != NULL);
|
|
||||||
|
|
||||||
foo = bfd_alloc (globals->bfd_of_glue_owner, globals->bx_glue_size);
|
|
||||||
|
|
||||||
BFD_ASSERT (s->size == globals->bx_glue_size);
|
|
||||||
s->contents = foo;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4096,8 +4067,6 @@ record_thumb_to_arm_glue (struct bfd_link_info *link_info,
|
||||||
|
|
||||||
s->size += THUMB2ARM_GLUE_SIZE;
|
s->size += THUMB2ARM_GLUE_SIZE;
|
||||||
hash_table->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
|
hash_table->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4311,6 +4280,37 @@ record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note: we do not include the flag SEC_LINKER_CREATED, as that
|
||||||
|
would prevent elf_link_input_bfd() from processing the contents
|
||||||
|
of the section. */
|
||||||
|
#define ARM_GLUE_SECTION_FLAGS \
|
||||||
|
(SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY)
|
||||||
|
|
||||||
|
/* Create a fake section for use by the ARM backend of the linker. */
|
||||||
|
|
||||||
|
static bfd_boolean
|
||||||
|
arm_make_glue_section (bfd * abfd, const char * name)
|
||||||
|
{
|
||||||
|
asection * sec;
|
||||||
|
|
||||||
|
sec = bfd_get_section_by_name (abfd, name);
|
||||||
|
if (sec != NULL)
|
||||||
|
/* Already made. */
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
sec = bfd_make_section_with_flags (abfd, name, ARM_GLUE_SECTION_FLAGS);
|
||||||
|
|
||||||
|
if (sec == NULL
|
||||||
|
|| !bfd_set_section_alignment (abfd, sec, 2))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Set the gc mark to prevent the section from being removed by garbage
|
||||||
|
collection, despite the fact that no relocs refer to this section. */
|
||||||
|
sec->gc_mark = 1;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add the glue sections to ABFD. This function is called from the
|
/* Add the glue sections to ABFD. This function is called from the
|
||||||
linker scripts in ld/emultempl/{armelf}.em. */
|
linker scripts in ld/emultempl/{armelf}.em. */
|
||||||
|
|
||||||
|
@ -4318,101 +4318,24 @@ bfd_boolean
|
||||||
bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
|
bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
|
||||||
struct bfd_link_info *info)
|
struct bfd_link_info *info)
|
||||||
{
|
{
|
||||||
flagword flags;
|
|
||||||
asection *sec;
|
|
||||||
|
|
||||||
/* If we are only performing a partial
|
/* If we are only performing a partial
|
||||||
link do not bother adding the glue. */
|
link do not bother adding the glue. */
|
||||||
if (info->relocatable)
|
if (info->relocatable)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* linker stubs don't need glue */
|
/* Linker stubs don't need glue. */
|
||||||
if (!strcmp (abfd->filename, "linker stubs"))
|
if (!strcmp (abfd->filename, "linker stubs"))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
|
return arm_make_glue_section (abfd, ARM2THUMB_GLUE_SECTION_NAME)
|
||||||
|
&& arm_make_glue_section (abfd, THUMB2ARM_GLUE_SECTION_NAME)
|
||||||
if (sec == NULL)
|
&& arm_make_glue_section (abfd, VFP11_ERRATUM_VENEER_SECTION_NAME)
|
||||||
{
|
&& arm_make_glue_section (abfd, ARM_BX_GLUE_SECTION_NAME);
|
||||||
/* Note: we do not include the flag SEC_LINKER_CREATED, as this
|
|
||||||
will prevent elf_link_input_bfd() from processing the contents
|
|
||||||
of this section. */
|
|
||||||
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
|
|
||||||
| SEC_CODE | SEC_READONLY);
|
|
||||||
|
|
||||||
sec = bfd_make_section_with_flags (abfd,
|
|
||||||
ARM2THUMB_GLUE_SECTION_NAME,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
if (sec == NULL
|
|
||||||
|| !bfd_set_section_alignment (abfd, sec, 2))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Set the gc mark to prevent the section from being removed by garbage
|
|
||||||
collection, despite the fact that no relocs refer to this section. */
|
|
||||||
sec->gc_mark = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
|
|
||||||
|
|
||||||
if (sec == NULL)
|
|
||||||
{
|
|
||||||
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
|
|
||||||
| SEC_CODE | SEC_READONLY);
|
|
||||||
|
|
||||||
sec = bfd_make_section_with_flags (abfd,
|
|
||||||
THUMB2ARM_GLUE_SECTION_NAME,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
if (sec == NULL
|
|
||||||
|| !bfd_set_section_alignment (abfd, sec, 2))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
sec->gc_mark = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sec = bfd_get_section_by_name (abfd, VFP11_ERRATUM_VENEER_SECTION_NAME);
|
|
||||||
|
|
||||||
if (sec == NULL)
|
|
||||||
{
|
|
||||||
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
|
|
||||||
| SEC_CODE | SEC_READONLY);
|
|
||||||
|
|
||||||
sec = bfd_make_section_with_flags (abfd,
|
|
||||||
VFP11_ERRATUM_VENEER_SECTION_NAME,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
if (sec == NULL
|
|
||||||
|| !bfd_set_section_alignment (abfd, sec, 2))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
sec->gc_mark = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sec = bfd_get_section_by_name (abfd, ARM_BX_GLUE_SECTION_NAME);
|
|
||||||
|
|
||||||
if (sec == NULL)
|
|
||||||
{
|
|
||||||
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
|
|
||||||
| SEC_CODE | SEC_READONLY);
|
|
||||||
|
|
||||||
sec = bfd_make_section_with_flags (abfd,
|
|
||||||
ARM_BX_GLUE_SECTION_NAME,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
if (sec == NULL
|
|
||||||
|| !bfd_set_section_alignment (abfd, sec, 2))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
sec->gc_mark = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select a BFD to be used to hold the sections used by the glue code.
|
/* Select a BFD to be used to hold the sections used by the glue code.
|
||||||
This function is called from the linker scripts in ld/emultempl/
|
This function is called from the linker scripts in ld/emultempl/
|
||||||
{armelf/pe}.em */
|
{armelf/pe}.em. */
|
||||||
|
|
||||||
bfd_boolean
|
bfd_boolean
|
||||||
bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
|
bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
|
||||||
|
@ -5439,8 +5362,8 @@ elf32_arm_create_thumb_stub (struct bfd_link_info * info,
|
||||||
bfd * output_bfd,
|
bfd * output_bfd,
|
||||||
asection * sym_sec,
|
asection * sym_sec,
|
||||||
bfd_vma val,
|
bfd_vma val,
|
||||||
asection *s,
|
asection * s,
|
||||||
char **error_message)
|
char ** error_message)
|
||||||
{
|
{
|
||||||
bfd_vma my_offset;
|
bfd_vma my_offset;
|
||||||
long int ret_offset;
|
long int ret_offset;
|
||||||
|
@ -5515,6 +5438,8 @@ elf32_arm_create_thumb_stub (struct bfd_link_info * info,
|
||||||
/* It's a thumb address. Add the low order bit. */
|
/* It's a thumb address. Add the low order bit. */
|
||||||
bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
|
bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
|
||||||
s->contents + my_offset + 8);
|
s->contents + my_offset + 8);
|
||||||
|
|
||||||
|
my_offset += 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5617,6 +5542,7 @@ elf32_arm_to_thumb_export_stub (struct elf_link_hash_entry *h, void * inf)
|
||||||
|
|
||||||
val = eh->export_glue->root.u.def.value + sec->output_offset
|
val = eh->export_glue->root.u.def.value + sec->output_offset
|
||||||
+ sec->output_section->vma;
|
+ sec->output_section->vma;
|
||||||
|
|
||||||
myh = elf32_arm_create_thumb_stub (info, h->root.root.string,
|
myh = elf32_arm_create_thumb_stub (info, h->root.root.string,
|
||||||
h->root.u.def.section->owner,
|
h->root.u.def.section->owner,
|
||||||
globals->obfd, sec, val, s,
|
globals->obfd, sec, val, s,
|
||||||
|
@ -5669,7 +5595,8 @@ elf32_arm_begin_write_processing (bfd *abfd ATTRIBUTE_UNUSED,
|
||||||
{
|
{
|
||||||
struct elf32_arm_link_hash_table * globals;
|
struct elf32_arm_link_hash_table * globals;
|
||||||
|
|
||||||
if (!link_info)
|
if (link_info == NULL)
|
||||||
|
/* Ignore this if we are not called by the ELF backend linker. */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
globals = elf32_arm_hash_table (link_info);
|
globals = elf32_arm_hash_table (link_info);
|
||||||
|
@ -5684,6 +5611,7 @@ elf32_arm_begin_write_processing (bfd *abfd ATTRIBUTE_UNUSED,
|
||||||
|
|
||||||
/* Some relocations map to different relocations depending on the
|
/* Some relocations map to different relocations depending on the
|
||||||
target. Return the real relocation. */
|
target. Return the real relocation. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
arm_real_reloc_type (struct elf32_arm_link_hash_table * globals,
|
arm_real_reloc_type (struct elf32_arm_link_hash_table * globals,
|
||||||
int r_type)
|
int r_type)
|
||||||
|
@ -5832,7 +5760,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||||
int sym_flags,
|
int sym_flags,
|
||||||
struct elf_link_hash_entry * h,
|
struct elf_link_hash_entry * h,
|
||||||
bfd_boolean * unresolved_reloc_p,
|
bfd_boolean * unresolved_reloc_p,
|
||||||
char **error_message)
|
char ** error_message)
|
||||||
{
|
{
|
||||||
unsigned long r_type = howto->type;
|
unsigned long r_type = howto->type;
|
||||||
unsigned long r_symndx;
|
unsigned long r_symndx;
|
||||||
|
@ -6082,7 +6010,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||||
case R_ARM_XPC25: /* Arm BLX instruction. */
|
case R_ARM_XPC25: /* Arm BLX instruction. */
|
||||||
case R_ARM_CALL:
|
case R_ARM_CALL:
|
||||||
case R_ARM_JUMP24:
|
case R_ARM_JUMP24:
|
||||||
case R_ARM_PC24: /* Arm B/BL instruction */
|
case R_ARM_PC24: /* Arm B/BL instruction. */
|
||||||
case R_ARM_PLT32:
|
case R_ARM_PLT32:
|
||||||
{
|
{
|
||||||
bfd_vma from;
|
bfd_vma from;
|
||||||
|
@ -6122,7 +6050,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if a stub has to be inserted because the
|
/* Check if a stub has to be inserted because the
|
||||||
destination is too far or we are changing mode */
|
destination is too far or we are changing mode. */
|
||||||
if (r_type == R_ARM_CALL)
|
if (r_type == R_ARM_CALL)
|
||||||
{
|
{
|
||||||
if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET
|
if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET
|
||||||
|
@ -6204,7 +6132,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||||
{
|
{
|
||||||
/* Select the correct instruction (BL or BLX). */
|
/* Select the correct instruction (BL or BLX). */
|
||||||
/* Only if we are not handling a BL to a stub. In this
|
/* Only if we are not handling a BL to a stub. In this
|
||||||
case, mode switching is performed by the stub. */
|
case, mode switching is performed by the stub. */
|
||||||
if (sym_flags == STT_ARM_TFUNC && !stub_entry)
|
if (sym_flags == STT_ARM_TFUNC && !stub_entry)
|
||||||
value |= (1 << 28);
|
value |= (1 << 28);
|
||||||
else
|
else
|
||||||
|
@ -6247,7 +6175,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||||
value += signed_addend;
|
value += signed_addend;
|
||||||
if (! h || h->root.type != bfd_link_hash_undefweak)
|
if (! h || h->root.type != bfd_link_hash_undefweak)
|
||||||
{
|
{
|
||||||
/* Check for overflow */
|
/* Check for overflow. */
|
||||||
if ((value ^ (value >> 1)) & (1 << 30))
|
if ((value ^ (value >> 1)) & (1 << 30))
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
}
|
}
|
||||||
|
@ -6444,15 +6372,16 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||||
/* Convert BL to BLX. */
|
/* Convert BL to BLX. */
|
||||||
lower_insn = (lower_insn & ~0x1000) | 0x0800;
|
lower_insn = (lower_insn & ~0x1000) | 0x0800;
|
||||||
}
|
}
|
||||||
else if (r_type != R_ARM_THM_CALL) {
|
else if (r_type != R_ARM_THM_CALL)
|
||||||
if (elf32_thumb_to_arm_stub
|
{
|
||||||
(info, sym_name, input_bfd, output_bfd, input_section,
|
if (elf32_thumb_to_arm_stub
|
||||||
hit_data, sym_sec, rel->r_offset, signed_addend, value,
|
(info, sym_name, input_bfd, output_bfd, input_section,
|
||||||
error_message))
|
hit_data, sym_sec, rel->r_offset, signed_addend, value,
|
||||||
return bfd_reloc_ok;
|
error_message))
|
||||||
else
|
return bfd_reloc_ok;
|
||||||
return bfd_reloc_dangerous;
|
else
|
||||||
}
|
return bfd_reloc_dangerous;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (sym_flags == STT_ARM_TFUNC && globals->use_blx
|
else if (sym_flags == STT_ARM_TFUNC && globals->use_blx
|
||||||
&& r_type == R_ARM_THM_CALL)
|
&& r_type == R_ARM_THM_CALL)
|
||||||
|
@ -6483,7 +6412,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||||
if (r_type == R_ARM_THM_CALL)
|
if (r_type == R_ARM_THM_CALL)
|
||||||
{
|
{
|
||||||
/* Check if a stub has to be inserted because the destination
|
/* Check if a stub has to be inserted because the destination
|
||||||
is too far. */
|
is too far. */
|
||||||
bfd_vma from;
|
bfd_vma from;
|
||||||
bfd_signed_vma branch_offset;
|
bfd_signed_vma branch_offset;
|
||||||
struct elf32_arm_stub_hash_entry *stub_entry = NULL;
|
struct elf32_arm_stub_hash_entry *stub_entry = NULL;
|
||||||
|
@ -8007,7 +7936,7 @@ elf32_arm_relocate_section (bfd * output_bfd,
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error_message = _("unknown error");
|
error_message = _("unknown error");
|
||||||
/* fall through */
|
/* Fall through. */
|
||||||
|
|
||||||
common_error:
|
common_error:
|
||||||
BFD_ASSERT (error_message != NULL);
|
BFD_ASSERT (error_message != NULL);
|
||||||
|
@ -8466,7 +8395,7 @@ elf32_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
|
||||||
&& !(ibfd->flags & DYNAMIC)
|
&& !(ibfd->flags & DYNAMIC)
|
||||||
&& (in_flags & EF_ARM_BE8))
|
&& (in_flags & EF_ARM_BE8))
|
||||||
{
|
{
|
||||||
_bfd_error_handler (_("ERROR: %B is already in final BE8 format"),
|
_bfd_error_handler (_("ERROR: %B is already in final BE8 format"),
|
||||||
ibfd);
|
ibfd);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -9097,12 +9026,12 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||||
elf32_arm_local_got_tls_type (abfd) [r_symndx] = tls_type;
|
elf32_arm_local_got_tls_type (abfd) [r_symndx] = tls_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through. */
|
||||||
|
|
||||||
case R_ARM_TLS_LDM32:
|
case R_ARM_TLS_LDM32:
|
||||||
if (r_type == R_ARM_TLS_LDM32)
|
if (r_type == R_ARM_TLS_LDM32)
|
||||||
htab->tls_ldm_got.refcount++;
|
htab->tls_ldm_got.refcount++;
|
||||||
/* Fall through */
|
/* Fall through. */
|
||||||
|
|
||||||
case R_ARM_GOTOFF32:
|
case R_ARM_GOTOFF32:
|
||||||
case R_ARM_GOTPC:
|
case R_ARM_GOTPC:
|
||||||
|
@ -9120,7 +9049,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||||
ldr __GOTT_INDEX__ offsets. */
|
ldr __GOTT_INDEX__ offsets. */
|
||||||
if (!htab->vxworks_p)
|
if (!htab->vxworks_p)
|
||||||
break;
|
break;
|
||||||
/* Fall through */
|
/* Fall through. */
|
||||||
|
|
||||||
case R_ARM_PC24:
|
case R_ARM_PC24:
|
||||||
case R_ARM_PLT32:
|
case R_ARM_PLT32:
|
||||||
|
@ -9960,10 +9889,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
||||||
/* Find any dynamic relocs that apply to read-only sections. */
|
/* Find any dynamic relocs that apply to read-only sections. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf32_arm_readonly_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
|
elf32_arm_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
|
||||||
{
|
{
|
||||||
struct elf32_arm_link_hash_entry *eh;
|
struct elf32_arm_link_hash_entry * eh;
|
||||||
struct elf32_arm_relocs_copied *p;
|
struct elf32_arm_relocs_copied * p;
|
||||||
|
|
||||||
if (h->root.type == bfd_link_hash_warning)
|
if (h->root.type == bfd_link_hash_warning)
|
||||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||||
|
@ -10248,8 +10177,8 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||||||
/* If any dynamic relocs apply to a read-only section,
|
/* If any dynamic relocs apply to a read-only section,
|
||||||
then we need a DT_TEXTREL entry. */
|
then we need a DT_TEXTREL entry. */
|
||||||
if ((info->flags & DF_TEXTREL) == 0)
|
if ((info->flags & DF_TEXTREL) == 0)
|
||||||
elf_link_hash_traverse (&htab->root, elf32_arm_readonly_dynrelocs,
|
elf_link_hash_traverse (& htab->root, elf32_arm_readonly_dynrelocs,
|
||||||
(PTR) info);
|
info);
|
||||||
|
|
||||||
if ((info->flags & DF_TEXTREL) != 0)
|
if ((info->flags & DF_TEXTREL) != 0)
|
||||||
{
|
{
|
||||||
|
@ -10678,7 +10607,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
|
||||||
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
|
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through. */
|
||||||
|
|
||||||
case DT_REL:
|
case DT_REL:
|
||||||
case DT_RELA:
|
case DT_RELA:
|
||||||
|
@ -10767,7 +10696,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
|
||||||
splt->contents + 8);
|
splt->contents + 8);
|
||||||
bfd_put_32 (output_bfd, got_address, splt->contents + 12);
|
bfd_put_32 (output_bfd, got_address, splt->contents + 12);
|
||||||
|
|
||||||
/* Generate a relocation for _GLOBAL_OFFSET_TABLE_. */
|
/* Generate a relocation for _GLOBAL_OFFSET_TABLE_. */
|
||||||
rel.r_offset = plt_address + 12;
|
rel.r_offset = plt_address + 12;
|
||||||
rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32);
|
rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32);
|
||||||
rel.r_addend = 0;
|
rel.r_addend = 0;
|
||||||
|
@ -11212,8 +11141,8 @@ elf32_arm_output_stub_sym (output_arch_syminfo *osi, const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
arm_map_one_stub (struct bfd_hash_entry *gen_entry,
|
arm_map_one_stub (struct bfd_hash_entry * gen_entry,
|
||||||
PTR in_arg)
|
void * in_arg)
|
||||||
{
|
{
|
||||||
struct elf32_arm_stub_hash_entry *stub_entry;
|
struct elf32_arm_stub_hash_entry *stub_entry;
|
||||||
struct bfd_link_info *info;
|
struct bfd_link_info *info;
|
||||||
|
@ -11366,32 +11295,34 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
|
||||||
elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0);
|
elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Long calls stubs. */
|
/* Long calls stubs. */
|
||||||
if (htab->stub_bfd && htab->stub_bfd->sections) {
|
if (htab->stub_bfd && htab->stub_bfd->sections)
|
||||||
|
{
|
||||||
asection* stub_sec;
|
asection* stub_sec;
|
||||||
|
|
||||||
for (stub_sec = htab->stub_bfd->sections;
|
for (stub_sec = htab->stub_bfd->sections;
|
||||||
stub_sec != NULL;
|
stub_sec != NULL;
|
||||||
stub_sec = stub_sec->next) {
|
stub_sec = stub_sec->next)
|
||||||
|
{
|
||||||
|
/* Ignore non-stub sections. */
|
||||||
|
if (!strstr (stub_sec->name, STUB_SUFFIX))
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Ignore non-stub sections */
|
osi.sec = stub_sec;
|
||||||
if (!strstr(stub_sec->name, STUB_SUFFIX))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
osi.sec = stub_sec;
|
osi.sec_shndx = _bfd_elf_section_from_bfd_section
|
||||||
|
(output_bfd, osi.sec->output_section);
|
||||||
|
|
||||||
osi.sec_shndx = _bfd_elf_section_from_bfd_section
|
bfd_hash_traverse (&htab->stub_hash_table, arm_map_one_stub, &osi);
|
||||||
(output_bfd, osi.sec->output_section);
|
}
|
||||||
|
}
|
||||||
bfd_hash_traverse (&htab->stub_hash_table, arm_map_one_stub, &osi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally, output mapping symbols for the PLT. */
|
/* Finally, output mapping symbols for the PLT. */
|
||||||
if (!htab->splt || htab->splt->size == 0)
|
if (!htab->splt || htab->splt->size == 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
osi.sec_shndx = _bfd_elf_section_from_bfd_section (output_bfd,
|
osi.sec_shndx = _bfd_elf_section_from_bfd_section (output_bfd,
|
||||||
htab->splt->output_section);
|
htab->splt->output_section);
|
||||||
osi.sec = htab->splt;
|
osi.sec = htab->splt;
|
||||||
/* Output mapping symbols for the plt header. SymbianOS does not have a
|
/* Output mapping symbols for the plt header. SymbianOS does not have a
|
||||||
plt header. */
|
plt header. */
|
||||||
|
@ -11471,7 +11402,8 @@ elf32_arm_compare_mapping (const void * a, const void * b)
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf32_arm_write_section (bfd *output_bfd,
|
elf32_arm_write_section (bfd *output_bfd,
|
||||||
struct bfd_link_info *link_info, asection *sec,
|
struct bfd_link_info *link_info,
|
||||||
|
asection *sec,
|
||||||
bfd_byte *contents)
|
bfd_byte *contents)
|
||||||
{
|
{
|
||||||
int mapcount, errcount;
|
int mapcount, errcount;
|
||||||
|
@ -12075,7 +12007,7 @@ elf32_arm_symbian_plt_sym_val (bfd_vma i, const asection *plt,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#undef elf32_bed
|
#undef elf32_bed
|
||||||
#define elf32_bed elf32_arm_symbian_bed
|
#define elf32_bed elf32_arm_symbian_bed
|
||||||
|
|
||||||
/* The dynamic sections are not allocated on SymbianOS; the postlinker
|
/* The dynamic sections are not allocated on SymbianOS; the postlinker
|
||||||
|
|
Loading…
Reference in New Issue