* 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:
Nick Clifton 2008-08-17 20:48:21 +00:00
parent 8ad82227d0
commit 8029a119ee
2 changed files with 157 additions and 217 deletions

View File

@ -1,5 +1,13 @@
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
where the sym_hashes are not available.

View File

@ -67,7 +67,7 @@ static struct elf_backend_data elf32_arm_vxworks_bed;
static reloc_howto_type elf32_arm_howto_table_1[] =
{
/* No relocation */
/* No relocation. */
HOWTO (R_ARM_NONE, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
@ -1347,7 +1347,7 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
0x040f70ff, /* dst_mask */
FALSE), /* pcrel_offset */
EMPTY_HOWTO (90), /* unallocated */
EMPTY_HOWTO (90), /* Unallocated. */
EMPTY_HOWTO (91),
EMPTY_HOWTO (92),
EMPTY_HOWTO (93),
@ -1778,6 +1778,7 @@ elf32_arm_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
bfd_reloc_code_real_type code)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE (elf32_arm_reloc_map); i ++)
if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
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:
return FALSE;
case 148: /* Linux/ARM 32-bit*/
case 148: /* Linux/ARM 32-bit. */
/* pr_cursig */
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:
return FALSE;
case 124: /* Linux/ARM elf_prpsinfo */
case 124: /* Linux/ARM elf_prpsinfo. */
elf_tdata (abfd)->core_program
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
elf_tdata (abfd)->core_command
@ -2766,7 +2767,7 @@ arm_type_of_stub (struct bfd_link_info *info,
enum elf32_arm_stub_type stub_type = arm_stub_none;
/* 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)
return stub_type;
@ -3716,7 +3717,7 @@ elf32_arm_build_stubs (struct bfd_link_info *info)
{
bfd_size_type size;
/* Ignore non-stub sections */
/* Ignore non-stub sections. */
if (!strstr (stub_sec->name, STUB_SUFFIX))
continue;
@ -3826,8 +3827,7 @@ find_arm_glue (struct bfd_link_info *link_info,
add r12, r12, pc
bx r12
__func_offset:
.word func - .
*/
.word func - . */
#define ARM2THUMB_STATIC_GLUE_SIZE 12
static const insn32 a2t1_ldr_insn = 0xe59fc000;
@ -3851,11 +3851,10 @@ static const insn32 a2t3p_bx_r12_insn = 0xe12fff1c;
bx pc push {r6, lr}
nop ldr r6, __func_addr
.arm mov lr, pc
__func_change_to_arm: bx r6
b func .arm
__func_back_to_thumb:
ldmia r13! {r6, lr}
bx lr
b func bx r6
;; back_to_thumb .arm
ldmia r13! {r6, lr} ldmia r13! {r6, lr}
bx lr bx lr
__func_addr:
.word func */
@ -3872,78 +3871,50 @@ static const insn32 armbx2_moveq_insn = 0x01a0f000;
static const insn32 armbx3_bx_insn = 0xe12fff10;
#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_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info)
{
asection * s;
bfd_byte * foo;
struct elf32_arm_link_hash_table * globals;
globals = elf32_arm_hash_table (info);
BFD_ASSERT (globals != NULL);
if (globals->arm_glue_size != 0)
{
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
globals->arm_glue_size,
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);
s->contents = foo;
}
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_allocate_glue_section_space (globals->bfd_of_glue_owner,
globals->bx_glue_size,
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;
}
@ -4096,8 +4067,6 @@ record_thumb_to_arm_glue (struct bfd_link_info *link_info,
s->size += THUMB2ARM_GLUE_SIZE;
hash_table->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
return;
}
@ -4311,38 +4280,25 @@ record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
return val;
}
/* Add the glue sections to ABFD. This function is called from the
linker scripts in ld/emultempl/{armelf}.em. */
/* 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)
bfd_boolean
bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
struct bfd_link_info *info)
/* 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)
{
flagword flags;
asection * sec;
/* If we are only performing a partial
link do not bother adding the glue. */
if (info->relocatable)
sec = bfd_get_section_by_name (abfd, name);
if (sec != NULL)
/* Already made. */
return TRUE;
/* linker stubs don't need glue */
if (!strcmp (abfd->filename, "linker stubs"))
return TRUE;
sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
if (sec == NULL)
{
/* 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);
sec = bfd_make_section_with_flags (abfd, name, ARM_GLUE_SECTION_FLAGS);
if (sec == NULL
|| !bfd_set_section_alignment (abfd, sec, 2))
@ -4351,68 +4307,35 @@ bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
/* 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;
}
/* Add the glue sections to ABFD. This function is called from the
linker scripts in ld/emultempl/{armelf}.em. */
bfd_boolean
bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
struct bfd_link_info *info)
{
/* If we are only performing a partial
link do not bother adding the glue. */
if (info->relocatable)
return TRUE;
/* Linker stubs don't need glue. */
if (!strcmp (abfd->filename, "linker stubs"))
return TRUE;
return arm_make_glue_section (abfd, ARM2THUMB_GLUE_SECTION_NAME)
&& arm_make_glue_section (abfd, THUMB2ARM_GLUE_SECTION_NAME)
&& arm_make_glue_section (abfd, VFP11_ERRATUM_VENEER_SECTION_NAME)
&& arm_make_glue_section (abfd, ARM_BX_GLUE_SECTION_NAME);
}
/* 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/
{armelf/pe}.em */
{armelf/pe}.em. */
bfd_boolean
bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
@ -5515,6 +5438,8 @@ elf32_arm_create_thumb_stub (struct bfd_link_info * info,
/* It's a thumb address. Add the low order bit. */
bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
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
+ sec->output_section->vma;
myh = elf32_arm_create_thumb_stub (info, h->root.root.string,
h->root.u.def.section->owner,
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;
if (!link_info)
if (link_info == NULL)
/* Ignore this if we are not called by the ELF backend linker. */
return;
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
target. Return the real relocation. */
static int
arm_real_reloc_type (struct elf32_arm_link_hash_table * globals,
int r_type)
@ -6082,7 +6010,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
case R_ARM_XPC25: /* Arm BLX instruction. */
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PC24: /* Arm B/BL instruction */
case R_ARM_PC24: /* Arm B/BL instruction. */
case R_ARM_PLT32:
{
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
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 (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET
@ -6247,7 +6175,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
value += signed_addend;
if (! h || h->root.type != bfd_link_hash_undefweak)
{
/* Check for overflow */
/* Check for overflow. */
if ((value ^ (value >> 1)) & (1 << 30))
return bfd_reloc_overflow;
}
@ -6444,7 +6372,8 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
/* Convert BL to BLX. */
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,
hit_data, sym_sec, rel->r_offset, signed_addend, value,
@ -8007,7 +7936,7 @@ elf32_arm_relocate_section (bfd * output_bfd,
default:
error_message = _("unknown error");
/* fall through */
/* Fall through. */
common_error:
BFD_ASSERT (error_message != NULL);
@ -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;
}
}
/* Fall through */
/* Fall through. */
case R_ARM_TLS_LDM32:
if (r_type == R_ARM_TLS_LDM32)
htab->tls_ldm_got.refcount++;
/* Fall through */
/* Fall through. */
case R_ARM_GOTOFF32:
case R_ARM_GOTPC:
@ -9120,7 +9049,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
ldr __GOTT_INDEX__ offsets. */
if (!htab->vxworks_p)
break;
/* Fall through */
/* Fall through. */
case R_ARM_PC24:
case R_ARM_PLT32:
@ -9960,7 +9889,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
/* Find any dynamic relocs that apply to read-only sections. */
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_relocs_copied * p;
@ -10249,7 +10178,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
then we need a DT_TEXTREL entry. */
if ((info->flags & DF_TEXTREL) == 0)
elf_link_hash_traverse (& htab->root, elf32_arm_readonly_dynrelocs,
(PTR) info);
info);
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);
break;
}
/* Fall through */
/* Fall through. */
case DT_REL:
case DT_RELA:
@ -11213,7 +11142,7 @@ elf32_arm_output_stub_sym (output_arch_syminfo *osi, const char *name,
static bfd_boolean
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 bfd_link_info *info;
@ -11367,13 +11296,15 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
}
/* Long calls stubs. */
if (htab->stub_bfd && htab->stub_bfd->sections) {
if (htab->stub_bfd && htab->stub_bfd->sections)
{
asection* stub_sec;
for (stub_sec = htab->stub_bfd->sections;
stub_sec != NULL;
stub_sec = stub_sec->next) {
/* Ignore non-stub sections */
stub_sec = stub_sec->next)
{
/* Ignore non-stub sections. */
if (!strstr (stub_sec->name, STUB_SUFFIX))
continue;
@ -11471,7 +11402,8 @@ elf32_arm_compare_mapping (const void * a, const void * b)
static bfd_boolean
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)
{
int mapcount, errcount;