From fe33d2fa468504c7c7790f1247e280aae9cd930d Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 2 Mar 2010 08:19:54 +0000 Subject: [PATCH] 2010-03-02 Christophe Lyon Alan Modra bfd/ * elf32-arm.c (a8_erratum_fix): Add st_type field to record the destination mode of the a8 stub. (elf32_arm_link_hash_table): Add top_id field. (elf32_arm_link_hash_table_create): Initialize top_id. (arm_type_of_stub): Update prototype, st_type can now be updated by this function. Actual destination address in case of PLT is computed here, to help factorizing code. (elf32_arm_stub_name): Update prototype, use stub_type additional parameter to build stub name. (elf32_arm_get_stub_entry): Update prototype, use stub_type additional parameter to build stub entry. (arm_build_one_stub): Use bfd_put_16/bfd_put_32 instead of put_thumb_insn/put_arm_insn as BE8 encoding is now handled later. Call elf32_arm_final_link_relocate to process all in-stub relocations. (elf32_arm_setup_section_lists): Update top_id. (cortex_a8_erratum_scan): Record stub destination mode. (elf32_arm_size_stubs): Update call to arm_type_of_stub according to new prototype. (elf32_arm_final_link_relocate): Enable processing of in-stub REL32 relocations. Rely on arm_type_of_stub to detect if a stub is needed, enabling code factorization. (elf32_arm_final_link): Process stub sections. (elf32_arm_output_map_sym): Add entry to code/data map. ld/testsuite/ * ld-arm/arm-elf.exp: Change .text start address for farcall-thumb-arm tests. Add v4t variant for farcall-mixed-lib test. * ld-arm/farcall-mixed-lib-v4t.d: New test. * ld-arm/farcall-mixed-lib1.s: Don't force armv5t. * ld-arm/farcall-mixed-lib2.s: Likewise. * ld-arm/arm-call.d: Update expected results. * ld-arm/cortex-a8-far.d: Likewise. * ld-arm/farcall-group-size2.d: Likewise. * ld-arm/farcall-group.d: Likewise. * ld-arm/farcall-mix.d: Likewise. * ld-arm/farcall-mix2.d: Likewise. * ld-arm/farcall-mixed-app-v5.d: Likewise. * ld-arm/farcall-mixed-app.d: Likewise. * ld-arm/farcall-mixed-lib.d: Likewise. * ld-arm/farcall-thumb-arm.d: Likewise. * ld-arm/farcall-thumb-arm-blx.d: Likewise. * ld-arm/farcall-thumb-arm-pic-veneer.d: Likewise. * ld-arm/farcall-thumb-arm-blx-pic-veneer.d: Likewise. * ld-arm/farcall-thumb-arm.s: Update test. Add a new call to potentially generate different types of stubs. --- bfd/ChangeLog | 28 ++ bfd/elf32-arm.c | 271 +++++++++++------- ld/testsuite/ChangeLog | 25 ++ ld/testsuite/ld-arm/arm-call.d | 20 +- ld/testsuite/ld-arm/arm-elf.exp | 19 +- ld/testsuite/ld-arm/cortex-a8-far.d | 20 +- ld/testsuite/ld-arm/farcall-group-size2.d | 22 +- ld/testsuite/ld-arm/farcall-group.d | 47 +-- ld/testsuite/ld-arm/farcall-mix.d | 36 +-- ld/testsuite/ld-arm/farcall-mix2.d | 33 ++- ld/testsuite/ld-arm/farcall-mixed-app-v5.d | 12 +- ld/testsuite/ld-arm/farcall-mixed-app.d | 12 +- ld/testsuite/ld-arm/farcall-mixed-lib-v4t.d | 123 ++++++++ ld/testsuite/ld-arm/farcall-mixed-lib.d | 49 ++-- ld/testsuite/ld-arm/farcall-mixed-lib1.s | 1 - ld/testsuite/ld-arm/farcall-mixed-lib2.s | 1 - .../ld-arm/farcall-thumb-arm-blx-pic-veneer.d | 16 +- ld/testsuite/ld-arm/farcall-thumb-arm-blx.d | 12 +- .../ld-arm/farcall-thumb-arm-pic-veneer.d | 18 +- ld/testsuite/ld-arm/farcall-thumb-arm.d | 24 +- ld/testsuite/ld-arm/farcall-thumb-arm.s | 8 +- 21 files changed, 530 insertions(+), 267 deletions(-) create mode 100644 ld/testsuite/ld-arm/farcall-mixed-lib-v4t.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5e17dbee336..1c080543697 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,31 @@ +2010-03-02 Christophe Lyon + Alan Modra + + * elf32-arm.c (a8_erratum_fix): Add st_type field to record the + destination mode of the a8 stub. + (elf32_arm_link_hash_table): Add top_id field. + (elf32_arm_link_hash_table_create): Initialize top_id. + (arm_type_of_stub): Update prototype, st_type can now be updated + by this function. Actual destination address in case of PLT is + computed here, to help factorizing code. + (elf32_arm_stub_name): Update prototype, use stub_type additional + parameter to build stub name. + (elf32_arm_get_stub_entry): Update prototype, use stub_type + additional parameter to build stub entry. + (arm_build_one_stub): Use bfd_put_16/bfd_put_32 instead of + put_thumb_insn/put_arm_insn as BE8 encoding is now handled later. + Call elf32_arm_final_link_relocate to process all in-stub + relocations. + (elf32_arm_setup_section_lists): Update top_id. + (cortex_a8_erratum_scan): Record stub destination mode. + (elf32_arm_size_stubs): Update call to arm_type_of_stub according + to new prototype. + (elf32_arm_final_link_relocate): Enable processing of in-stub + REL32 relocations. Rely on arm_type_of_stub to detect if a stub is + needed, enabling code factorization. + (elf32_arm_final_link): Process stub sections. + (elf32_arm_output_map_sym): Add entry to code/data map. + 2010-03-01 David S. Miller * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): When STT_GNU_IFUNC and diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index a0694c10e0b..fd4031568d5 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2399,6 +2399,7 @@ struct a8_erratum_fix { unsigned long orig_insn; char *stub_name; enum elf32_arm_stub_type stub_type; + int st_type; }; /* A table of relocs applied to branches which might trigger Cortex-A8 @@ -2650,6 +2651,9 @@ struct elf32_arm_link_hash_table information on stub grouping. */ struct map_stub *stub_group; + /* Number of elements in stub_group. */ + int top_id; + /* Assorted information used by elf32_arm_size_stubs. */ unsigned int bfd_count; int top_index; @@ -2944,6 +2948,7 @@ elf32_arm_link_hash_table_create (bfd *abfd) ret->add_stub_section = NULL; ret->layout_sections_again = NULL; ret->stub_group = NULL; + ret->top_id = 0; ret->bfd_count = 0; ret->top_index = 0; ret->input_list = NULL; @@ -3046,7 +3051,7 @@ static enum elf32_arm_stub_type arm_type_of_stub (struct bfd_link_info *info, asection *input_sec, const Elf_Internal_Rela *rel, - unsigned char st_type, + int *actual_st_type, struct elf32_arm_link_hash_entry *hash, bfd_vma destination, asection *sym_sec, @@ -3061,6 +3066,7 @@ arm_type_of_stub (struct bfd_link_info *info, int thumb_only; enum elf32_arm_stub_type stub_type = arm_stub_none; int use_plt = 0; + int st_type = *actual_st_type; /* We don't know the actual type of destination in case it is of type STT_SECTION: give up. */ @@ -3080,14 +3086,15 @@ arm_type_of_stub (struct bfd_link_info *info, + input_sec->output_section->vma + rel->r_offset); - branch_offset = (bfd_signed_vma)(destination - location); - r_type = ELF32_R_TYPE (rel->r_info); /* Keep a simpler condition, for the sake of clarity. */ - if (globals->splt != NULL && hash != NULL && hash->root.plt.offset != (bfd_vma) -1) + if (globals->splt != NULL + && hash != NULL + && hash->root.plt.offset != (bfd_vma) -1) { use_plt = 1; + /* Note when dealing with PLT entries: the main PLT stub is in ARM mode, so if the branch is in Thumb mode, another Thumb->ARM stub will be inserted later just before the ARM @@ -3096,8 +3103,15 @@ arm_type_of_stub (struct bfd_link_info *info, Thumb->Arm one and branch directly to the ARM PLT entry because it avoids spreading offset corrections in several places. */ + + destination = (globals->splt->output_section->vma + + globals->splt->output_offset + + hash->root.plt.offset); + st_type = STT_FUNC; } + branch_offset = (bfd_signed_vma)(destination - location); + if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24) { /* Handle cases where: @@ -3191,7 +3205,9 @@ arm_type_of_stub (struct bfd_link_info *info, } } } - else if (r_type == R_ARM_CALL || r_type == R_ARM_JUMP24 || r_type == R_ARM_PLT32) + else if (r_type == R_ARM_CALL + || r_type == R_ARM_JUMP24 + || r_type == R_ARM_PLT32) { if (st_type == STT_ARM_TFUNC) { @@ -3246,6 +3262,12 @@ arm_type_of_stub (struct bfd_link_info *info, } } + /* If a stub is needed, record the actual destination type. */ + if (stub_type != arm_stub_none) + { + *actual_st_type = st_type; + } + return stub_type; } @@ -3255,31 +3277,34 @@ static char * elf32_arm_stub_name (const asection *input_section, const asection *sym_sec, const struct elf32_arm_link_hash_entry *hash, - const Elf_Internal_Rela *rel) + const Elf_Internal_Rela *rel, + enum elf32_arm_stub_type stub_type) { char *stub_name; bfd_size_type len; if (hash) { - len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 8 + 1; + len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 8 + 1 + 2 + 1; stub_name = (char *) bfd_malloc (len); if (stub_name != NULL) - sprintf (stub_name, "%08x_%s+%x", + sprintf (stub_name, "%08x_%s+%x_%d", input_section->id & 0xffffffff, hash->root.root.root.string, - (int) rel->r_addend & 0xffffffff); + (int) rel->r_addend & 0xffffffff, + (int) stub_type); } else { - len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1; + len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1 + 2 + 1; stub_name = (char *) bfd_malloc (len); if (stub_name != NULL) - sprintf (stub_name, "%08x_%x:%x+%x", + sprintf (stub_name, "%08x_%x:%x+%x_%d", input_section->id & 0xffffffff, sym_sec->id & 0xffffffff, (int) ELF32_R_SYM (rel->r_info) & 0xffffffff, - (int) rel->r_addend & 0xffffffff); + (int) rel->r_addend & 0xffffffff, + (int) stub_type); } return stub_name; @@ -3293,7 +3318,8 @@ elf32_arm_get_stub_entry (const asection *input_section, const asection *sym_sec, struct elf_link_hash_entry *hash, const Elf_Internal_Rela *rel, - struct elf32_arm_link_hash_table *htab) + struct elf32_arm_link_hash_table *htab, + enum elf32_arm_stub_type stub_type) { struct elf32_arm_stub_hash_entry *stub_entry; struct elf32_arm_link_hash_entry *h = (struct elf32_arm_link_hash_entry *) hash; @@ -3311,7 +3337,8 @@ elf32_arm_get_stub_entry (const asection *input_section, if (h != NULL && h->stub_cache != NULL && h->stub_cache->h == h - && h->stub_cache->id_sec == id_sec) + && h->stub_cache->id_sec == id_sec + && h->stub_cache->stub_type == stub_type) { stub_entry = h->stub_cache; } @@ -3319,7 +3346,7 @@ elf32_arm_get_stub_entry (const asection *input_section, { char *stub_name; - stub_name = elf32_arm_stub_name (id_sec, sym_sec, h, rel); + stub_name = elf32_arm_stub_name (id_sec, sym_sec, h, rel, stub_type); if (stub_name == NULL) return NULL; @@ -3479,7 +3506,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, /* We have to do the a8 fixes last, as they are less aligned than the other veneers. */ return TRUE; - + /* Make a note of the offset within the stubs for this entry. */ stub_entry->stub_offset = stub_sec->size; loc = stub_sec->contents + stub_entry->stub_offset; @@ -3514,17 +3541,17 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, BFD_ASSERT ((data & 0xff00) == 0xd000); data |= ((stub_entry->orig_insn >> 22) & 0xf) << 8; } - put_thumb_insn (globals, stub_bfd, data, loc + size); + bfd_put_16 (stub_bfd, data, loc + size); size += 2; } break; case THUMB32_TYPE: - put_thumb_insn (globals, stub_bfd, - (template_sequence[i].data >> 16) & 0xffff, - loc + size); - put_thumb_insn (globals, stub_bfd, template_sequence[i].data & 0xffff, - loc + size + 2); + bfd_put_16 (stub_bfd, + (template_sequence[i].data >> 16) & 0xffff, + loc + size); + bfd_put_16 (stub_bfd, template_sequence[i].data & 0xffff, + loc + size + 2); if (template_sequence[i].r_type != R_ARM_NONE) { stub_reloc_idx[nrelocs] = i; @@ -3534,8 +3561,8 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, break; case ARM_TYPE: - put_arm_insn (globals, stub_bfd, template_sequence[i].data, - loc + size); + bfd_put_32 (stub_bfd, template_sequence[i].data, + loc + size); /* Handle cases where the target is encoded within the instruction. */ if (template_sequence[i].r_type == R_ARM_JUMP24) @@ -3614,11 +3641,23 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, } else { - _bfd_final_link_relocate (elf32_arm_howto_from_type - (template_sequence[stub_reloc_idx[i]].r_type), stub_bfd, stub_sec, - stub_sec->contents, stub_entry->stub_offset + stub_reloc_offset[i], - sym_value + stub_entry->target_addend, - template_sequence[stub_reloc_idx[i]].reloc_addend); + Elf_Internal_Rela rel; + bfd_boolean unresolved_reloc; + char *error_message; + bfd_vma points_to = sym_value + stub_entry->target_addend + + template_sequence[stub_reloc_idx[i]].reloc_addend; + + rel.r_offset = stub_entry->stub_offset + stub_reloc_offset[i]; + rel.r_info = ELF32_R_INFO (0, + template_sequence[stub_reloc_idx[i]].r_type); + rel.r_addend = 0; + + elf32_arm_final_link_relocate (elf32_arm_howto_from_type + (template_sequence[stub_reloc_idx[i]].r_type), + stub_bfd, info->output_bfd, stub_sec, stub_sec->contents, &rel, + points_to, info, stub_entry->target_section, "", stub_entry->st_type, + (struct elf_link_hash_entry *) stub_entry->h, &unresolved_reloc, + &error_message); } return TRUE; @@ -3745,6 +3784,7 @@ elf32_arm_setup_section_lists (bfd *output_bfd, htab->stub_group = (struct map_stub *) bfd_zmalloc (amt); if (htab->stub_group == NULL) return -1; + htab->top_id = top_id; /* We can't use output_bfd->section_count here to find the top output section index as some sections may have been removed, and @@ -4033,7 +4073,7 @@ cortex_a8_erratum_scan (bfd *input_bfd, } is_32bit_branch = is_b || is_bl || is_blx || is_bcc; - + if (((base_vma + i) & 0xfff) == 0xffe && insn_32bit && is_32bit_branch @@ -4204,6 +4244,8 @@ cortex_a8_erratum_scan (bfd *input_bfd, a8_fixes[num_a8_fixes].orig_insn = insn; a8_fixes[num_a8_fixes].stub_name = stub_name; a8_fixes[num_a8_fixes].stub_type = stub_type; + a8_fixes[num_a8_fixes].st_type = + is_blx ? STT_FUNC : STT_ARM_TFUNC; num_a8_fixes++; } @@ -4219,11 +4261,11 @@ cortex_a8_erratum_scan (bfd *input_bfd, if (elf_section_data (section)->this_hdr.contents == NULL) free (contents); } - + *a8_fixes_p = a8_fixes; *num_a8_fixes_p = num_a8_fixes; *a8_fix_table_size_p = a8_fix_table_size; - + return FALSE; } @@ -4374,7 +4416,7 @@ elf32_arm_size_stubs (bfd *output_bfd, const char *sym_name; char *stub_name; const asection *id_sec; - unsigned char st_type; + int st_type; bfd_boolean created_stub = FALSE; r_type = ELF32_R_TYPE (irela->r_info); @@ -4432,7 +4474,7 @@ elf32_arm_size_stubs (bfd *output_bfd, /* This is an undefined symbol. It can never be resolved. */ continue; - + if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) sym_value = sym->st_value; destination = (sym_value + irela->r_addend @@ -4526,7 +4568,7 @@ elf32_arm_size_stubs (bfd *output_bfd, { /* Determine what (if any) linker stub is needed. */ stub_type = arm_type_of_stub (info, section, irela, - st_type, hash, + &st_type, hash, destination, sym_sec, input_bfd, sym_name); if (stub_type == arm_stub_none) @@ -4537,7 +4579,7 @@ elf32_arm_size_stubs (bfd *output_bfd, /* Get the name of this stub. */ stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash, - irela); + irela, stub_type); if (!stub_name) goto error_ret_free_internal; @@ -4737,7 +4779,7 @@ elf32_arm_size_stubs (bfd *output_bfd, stub_entry->target_value = a8_fixes[i].offset; stub_entry->target_addend = a8_fixes[i].addend; stub_entry->orig_insn = a8_fixes[i].orig_insn; - stub_entry->st_type = STT_ARM_TFUNC; + stub_entry->st_type = a8_fixes[i].st_type; size = find_stub_size_and_template (a8_fixes[i].stub_type, &template_sequence, @@ -6918,6 +6960,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, ".tls_vars") == 0) && ((r_type != R_ARM_REL32 && r_type != R_ARM_REL32_NOI) || !SYMBOL_CALLS_LOCAL (info, h)) + && (!strstr (input_section->name, STUB_SUFFIX)) && (h == NULL || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT || h->root.type != bfd_link_hash_undefweak) @@ -7042,7 +7085,6 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, case R_ARM_PC24: /* Arm B/BL instruction. */ case R_ARM_PLT32: { - bfd_signed_vma branch_offset; struct elf32_arm_stub_hash_entry *stub_entry = NULL; if (r_type == R_ARM_XPC25) @@ -7078,45 +7120,46 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, || r_type == R_ARM_JUMP24 || r_type == R_ARM_PLT32) { - bfd_vma from; - - /* If the call goes through a PLT entry, make sure to - check distance to the right destination address. */ - if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1) - { - value = (splt->output_section->vma - + splt->output_offset - + h->plt.offset); - *unresolved_reloc_p = FALSE; - /* The PLT entry is in ARM mode, regardless of the - target function. */ - sym_flags = STT_FUNC; - } + enum elf32_arm_stub_type stub_type = arm_stub_none; + struct elf32_arm_link_hash_entry *hash; + + hash = (struct elf32_arm_link_hash_entry *) h; + stub_type = arm_type_of_stub (info, input_section, rel, + &sym_flags, hash, + value, sym_sec, + input_bfd, sym_name); - from = (input_section->output_section->vma - + input_section->output_offset - + rel->r_offset); - branch_offset = (bfd_signed_vma)(value - from); - - if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET - || branch_offset < ARM_MAX_BWD_BRANCH_OFFSET - || ((sym_flags == STT_ARM_TFUNC) - && (((r_type == R_ARM_CALL) && !globals->use_blx) - || (r_type == R_ARM_JUMP24) - || (r_type == R_ARM_PLT32) )) - ) + if (stub_type != arm_stub_none) { /* The target is out of reach, so redirect the branch to the local stub for this function. */ stub_entry = elf32_arm_get_stub_entry (input_section, sym_sec, h, - rel, globals); + rel, globals, + stub_type); if (stub_entry != NULL) value = (stub_entry->stub_offset + stub_entry->stub_sec->output_offset + stub_entry->stub_sec->output_section->vma); } + else + { + /* If the call goes through a PLT entry, make sure to + check distance to the right destination address. */ + if (h != NULL + && splt != NULL + && h->plt.offset != (bfd_vma) -1) + { + value = (splt->output_section->vma + + splt->output_offset + + h->plt.offset); + *unresolved_reloc_p = FALSE; + /* The PLT entry is in ARM mode, regardless of the + target function. */ + sym_flags = STT_FUNC; + } + } } /* The ARM ELF ABI says that this reloc is computed as: S - P + A @@ -7501,58 +7544,29 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, } } - /* Handle calls via the PLT. */ - if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1) - { - value = (splt->output_section->vma - + splt->output_offset - + h->plt.offset); - if (globals->use_blx && r_type == R_ARM_THM_CALL) - { - /* If the Thumb BLX instruction is available, convert the - BL to a BLX instruction to call the ARM-mode PLT entry. */ - lower_insn = (lower_insn & ~0x1000) | 0x0800; - sym_flags = STT_FUNC; - } - else - { - /* Target the Thumb stub before the ARM PLT entry. */ - value -= PLT_THUMB_STUB_SIZE; - sym_flags = STT_ARM_TFUNC; - } - *unresolved_reloc_p = FALSE; - } - + enum elf32_arm_stub_type stub_type = arm_stub_none; if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24) { /* Check if a stub has to be inserted because the destination is too far. */ - bfd_vma from; - bfd_signed_vma branch_offset; - struct elf32_arm_stub_hash_entry *stub_entry = NULL; - - from = (input_section->output_section->vma - + input_section->output_offset - + rel->r_offset); - branch_offset = (bfd_signed_vma)(value - from); - - if ((!thumb2 - && (branch_offset > THM_MAX_FWD_BRANCH_OFFSET - || (branch_offset < THM_MAX_BWD_BRANCH_OFFSET))) - || - (thumb2 - && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET - || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET))) - || ((sym_flags != STT_ARM_TFUNC) - && (((r_type == R_ARM_THM_CALL) && !globals->use_blx) - || r_type == R_ARM_THM_JUMP24))) + struct elf32_arm_stub_hash_entry *stub_entry; + struct elf32_arm_link_hash_entry *hash; + + hash = (struct elf32_arm_link_hash_entry *) h; + + stub_type = arm_type_of_stub (info, input_section, rel, + &sym_flags, hash, value, sym_sec, + input_bfd, sym_name); + + if (stub_type != arm_stub_none) { /* The target is out of reach or we are changing modes, so redirect the branch to the local stub for this function. */ stub_entry = elf32_arm_get_stub_entry (input_section, sym_sec, h, - rel, globals); + rel, globals, + stub_type); if (stub_entry != NULL) value = (stub_entry->stub_offset + stub_entry->stub_sec->output_offset @@ -7569,6 +7583,33 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, } } + /* Handle calls via the PLT. */ + if (stub_type == arm_stub_none + && h != NULL + && splt != NULL + && h->plt.offset != (bfd_vma) -1) + { + value = (splt->output_section->vma + + splt->output_offset + + h->plt.offset); + + if (globals->use_blx && r_type == R_ARM_THM_CALL) + { + /* If the Thumb BLX instruction is available, convert + the BL to a BLX instruction to call the ARM-mode + PLT entry. */ + lower_insn = (lower_insn & ~0x1000) | 0x0800; + sym_flags = STT_FUNC; + } + else + { + /* Target the Thumb stub before the ARM PLT entry. */ + value -= PLT_THUMB_STUB_SIZE; + sym_flags = STT_ARM_TFUNC; + } + *unresolved_reloc_p = FALSE; + } + relocation = value + signed_addend; relocation -= (input_section->output_section->vma @@ -9357,6 +9398,7 @@ static bfd_boolean elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info) { struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (info); + asection *sec, *osec; if (globals == NULL) return FALSE; @@ -9365,6 +9407,20 @@ elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info) if (!bfd_elf_final_link (abfd, info)) return FALSE; + /* Process stub sections (eg BE8 encoding, ...). */ + struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info); + int i; + for(i=0; itop_id; i++) { + sec = htab->stub_group[i].stub_sec; + if (sec) { + osec = sec->output_section; + elf32_arm_write_section (abfd, info, sec, sec->contents); + if (! bfd_set_section_contents (abfd, osec, sec->contents, + sec->output_offset, sec->size)) + return FALSE; + } + } + /* Write out any glue sections now that we have created all the stubs. */ if (globals->bfd_of_glue_owner != NULL) @@ -12866,6 +12922,7 @@ elf32_arm_output_map_sym (output_arch_syminfo *osi, sym.st_other = 0; sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE); sym.st_shndx = osi->sec_shndx; + elf32_arm_section_map_add (osi->sec, names[type][1], offset); return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1; } diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index d9f5b82f71c..165261115cf 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,28 @@ +2010-03-02 Christophe Lyon + Alan Modra + + * ld-arm/arm-elf.exp: Change .text start address for + farcall-thumb-arm tests. Add v4t variant for farcall-mixed-lib + test. + * ld-arm/farcall-mixed-lib-v4t.d: New test. + * ld-arm/farcall-mixed-lib1.s: Don't force armv5t. + * ld-arm/farcall-mixed-lib2.s: Likewise. + * ld-arm/arm-call.d: Update expected results. + * ld-arm/cortex-a8-far.d: Likewise. + * ld-arm/farcall-group-size2.d: Likewise. + * ld-arm/farcall-group.d: Likewise. + * ld-arm/farcall-mix.d: Likewise. + * ld-arm/farcall-mix2.d: Likewise. + * ld-arm/farcall-mixed-app-v5.d: Likewise. + * ld-arm/farcall-mixed-app.d: Likewise. + * ld-arm/farcall-mixed-lib.d: Likewise. + * ld-arm/farcall-thumb-arm.d: Likewise. + * ld-arm/farcall-thumb-arm-blx.d: Likewise. + * ld-arm/farcall-thumb-arm-pic-veneer.d: Likewise. + * ld-arm/farcall-thumb-arm-blx-pic-veneer.d: Likewise. + * ld-arm/farcall-thumb-arm.s: Update test. Add a new call to + potentially generate different types of stubs. + 2010-02-27 H.J. Lu * ld-elf/init-fini-arrays.d: Pass --wide to readelf. diff --git a/ld/testsuite/ld-arm/arm-call.d b/ld/testsuite/ld-arm/arm-call.d index 891208d074c..fa452ab47ed 100644 --- a/ld/testsuite/ld-arm/arm-call.d +++ b/ld/testsuite/ld-arm/arm-call.d @@ -10,10 +10,10 @@ Disassembly of section .text: 800c: fb00000d blx 804a 8010: fa00000a blx 8040 8014: fb000009 blx 8042 - 8018: ea000012 b 8068 <__t1_from_arm> - 801c: ea00000f b 8060 <__t2_from_arm> - 8020: 1b000010 blne 8068 <__t1_from_arm> - 8024: 1b00000d blne 8060 <__t2_from_arm> + 8018: ea000010 b 8060 <__t1_from_arm> + 801c: ea000011 b 8068 <__t2_from_arm> + 8020: 1b00000e blne 8060 <__t1_from_arm> + 8024: 1b00000f blne 8068 <__t2_from_arm> 8028: 1b000003 blne 803c 802c: eb000002 bl 803c 8030: faffffff blx 8034 @@ -49,10 +49,10 @@ Disassembly of section .text: 805c: 0000 lsls r0, r0, #0 ... -00008060 <__t2_from_arm>: - 8060: e51ff004 ldr pc, \[pc, #-4\] ; 8064 <__t2_from_arm\+0x4> - 8064: 00008043 .word 0x00008043 +00008060 <__t1_from_arm>: + 8060: e51ff004 ldr pc, \[pc, #-4\] ; 8064 <__t1_from_arm\+0x4> + 8064: 00008041 .word 0x00008041 -00008068 <__t1_from_arm>: - 8068: e51ff004 ldr pc, \[pc, #-4\] ; 806c <__t1_from_arm\+0x4> - 806c: 00008041 .word 0x00008041 +00008068 <__t2_from_arm>: + 8068: e51ff004 ldr pc, \[pc, #-4\] ; 806c <__t2_from_arm\+0x4> + 806c: 00008043 .word 0x00008043 diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp index 40e78b86865..87ea1875139 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -387,25 +387,25 @@ set armeabitests { {{objdump -d farcall-thumb-thumb-pic-veneer.d}} "farcall-thumb-thumb-pic-veneer"} - {"Thumb-ARM farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W" {farcall-thumb-arm.s} + {"Thumb-ARM farcall" "-Ttext 0x1c01010 --section-start .foo=0x2001014" "-W" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm.d}} "farcall-thumb-arm"} - {"Thumb-ARM farcall (BE8)" "-Ttext 0x1000 --section-start .foo=0x2001014 -EB --be8" "-W -EB" {farcall-thumb-arm.s} + {"Thumb-ARM farcall (BE8)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 -EB --be8" "-W -EB" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm.d}} "farcall-thumb-arm-be8"} - {"Thumb-ARM farcall (BE)" "-Ttext 0x1000 --section-start .foo=0x2001014 -EB" "-W -EB" {farcall-thumb-arm.s} + {"Thumb-ARM farcall (BE)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 -EB" "-W -EB" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm.d}} "farcall-thumb-arm-be"} {"Thumb-ARM (short) call" "-Ttext 0x1000 --section-start .foo=0x0002014" "-W" {farcall-thumb-arm-short.s} {{objdump -d farcall-thumb-arm-short.d}} "farcall-thumb-arm-short"} - {"Thumb-ARM farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s} + {"Thumb-ARM farcall with BLX" "-Ttext 0x1c01010 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm-blx.d}} "farcall-thumb-arm-blx"} - {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s} + {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm-blx-pic-veneer.d}} "farcall-thumb-arm-blx-pic-veneer"} - {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s} + {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s} {{objdump -d farcall-thumb-arm-pic-veneer.d}} "farcall-thumb-arm-pic-veneer"} @@ -437,7 +437,12 @@ set armeabitests { {readelf -Ds farcall-mixed-app.sym}} "farcall-mixed-app-v5"} - {"Mixed ARM/Thumb shared library with long branches" "-shared -T arm-lib.ld" "" + {"Mixed ARM/Thumb shared library with long branches (v4t)" "-shared -T arm-lib.ld" "-march=armv4t" + {farcall-mixed-lib1.s farcall-mixed-lib2.s} + {{objdump -fdw farcall-mixed-lib-v4t.d}} + "farcall-mixed-lib.so"} + + {"Mixed ARM/Thumb shared library with long branches (v5t)" "-shared -T arm-lib.ld" "-march=armv5t" {farcall-mixed-lib1.s farcall-mixed-lib2.s} {{objdump -fdw farcall-mixed-lib.d}} "farcall-mixed-lib.so"} diff --git a/ld/testsuite/ld-arm/cortex-a8-far.d b/ld/testsuite/ld-arm/cortex-a8-far.d index 3d9059d3450..e327ac1e12b 100644 --- a/ld/testsuite/ld-arm/cortex-a8-far.d +++ b/ld/testsuite/ld-arm/cortex-a8-far.d @@ -13,14 +13,14 @@ Disassembly of section \.text: 80000c: 7fff0000 .word 0x7fff0000 00800010 : - 800010: f001 e806 blx 801020 <__far_fn1_from_thumb> - 800014: f001 e800 blx 801018 <__far_fn2_from_thumb> + 800010: f001 e802 blx 801018 <__far_fn1_from_thumb> + 800014: f001 e804 blx 801020 <__far_fn2_from_thumb> ... 800ff8: bf00 nop 00800ffa : 800ffa: ea81 0002 eor.w r0, r1, r2 - 800ffe: f000 b813 b.w 801028 <__far_fn1_from_thumb\+0x8> + 800ffe: f000 b813 b.w 801028 <__far_fn2_from_thumb\+0x8> 801002: ea81 0002 eor.w r0, r1, r2 801006: ea81 0002 eor.w r0, r1, r2 80100a: f7ff bff6 b.w 800ffa @@ -28,13 +28,13 @@ Disassembly of section \.text: 801012: ea81 0002 eor.w r0, r1, r2 ... -00801018 <__far_fn2_from_thumb>: - 801018: e51ff004 ldr pc, \[pc, #-4\] ; 80101c <__far_fn2_from_thumb\+0x4> - 80101c: 80000004 .word 0x80000004 +00801018 <__far_fn1_from_thumb>: + 801018: e51ff004 ldr pc, \[pc, #-4\] ; 80101c <__far_fn1_from_thumb\+0x4> + 80101c: 80000000 .word 0x80000000 -00801020 <__far_fn1_from_thumb>: - 801020: e51ff004 ldr pc, \[pc, #-4\] ; 801024 <__far_fn1_from_thumb\+0x4> - 801024: 80000000 .word 0x80000000 - 801028: d001 beq.n 80102e <__far_fn1_from_thumb\+0xe> +00801020 <__far_fn2_from_thumb>: + 801020: e51ff004 ldr pc, \[pc, #-4\] ; 801024 <__far_fn2_from_thumb\+0x4> + 801024: 80000004 .word 0x80000004 + 801028: d001 beq.n 80102e <__far_fn2_from_thumb\+0xe> 80102a: f7ff bfea b.w 801002 80102e: f7ff bfe4 b.w 800ffa diff --git a/ld/testsuite/ld-arm/farcall-group-size2.d b/ld/testsuite/ld-arm/farcall-group-size2.d index 79306eeb5f8..8a35313ea1b 100644 --- a/ld/testsuite/ld-arm/farcall-group-size2.d +++ b/ld/testsuite/ld-arm/farcall-group-size2.d @@ -6,27 +6,33 @@ Disassembly of section .text: 00001000 <_start>: 1000: eb000000 bl 1008 <__bar_from_arm> 1004: eb000002 bl 1014 <__bar2_veneer> + 00001008 <__bar_from_arm>: 1008: e59fc000 ldr ip, \[pc, #0\] ; 1010 <__bar_from_arm\+0x8> 100c: e12fff1c bx ip 1010: 02003021 .word 0x02003021 + 00001014 <__bar2_veneer>: 1014: e51ff004 ldr pc, \[pc, #-4\] ; 1018 <__bar2_veneer\+0x4> 1018: 02003024 .word 0x02003024 101c: 00000000 .word 0x00000000 + 00001020 : 1020: eb000008 bl 1048 <__bar3_veneer> - 1024: eb000004 bl 103c <__bar4_from_arm> - 1028: eb000000 bl 1030 <__bar5_from_arm> + 1024: eb000001 bl 1030 <__bar4_from_arm> + 1028: eb000003 bl 103c <__bar5_from_arm> 102c: 00000000 andeq r0, r0, r0 -00001030 <__bar5_from_arm>: - 1030: e59fc000 ldr ip, \[pc, #0\] ; 1038 <__bar5_from_arm\+0x8> + +00001030 <__bar4_from_arm>: + 1030: e59fc000 ldr ip, \[pc, #0\] ; 1038 <__bar4_from_arm\+0x8> 1034: e12fff1c bx ip - 1038: 0200302f .word 0x0200302f -0000103c <__bar4_from_arm>: - 103c: e59fc000 ldr ip, \[pc, #0\] ; 1044 <__bar4_from_arm\+0x8> + 1038: 0200302d .word 0x0200302d + +0000103c <__bar5_from_arm>: + 103c: e59fc000 ldr ip, \[pc, #0\] ; 1044 <__bar5_from_arm\+0x8> 1040: e12fff1c bx ip - 1044: 0200302d .word 0x0200302d + 1044: 0200302f .word 0x0200302f + 00001048 <__bar3_veneer>: 1048: e51ff004 ldr pc, \[pc, #-4\] ; 104c <__bar3_veneer\+0x4> 104c: 02003028 .word 0x02003028 diff --git a/ld/testsuite/ld-arm/farcall-group.d b/ld/testsuite/ld-arm/farcall-group.d index 10e983e4154..a72c14ffdcc 100644 --- a/ld/testsuite/ld-arm/farcall-group.d +++ b/ld/testsuite/ld-arm/farcall-group.d @@ -4,34 +4,39 @@ Disassembly of section .text: 00001000 <_start>: - 1000: eb00000c bl 1038 <__bar_from_arm> - 1004: eb00000e bl 1044 <__bar2_veneer> + 1000: eb000009 bl 102c <__bar_from_arm> + 1004: eb000006 bl 1024 <__bar2_veneer> 00001008 : - 1008: eb000008 bl 1030 <__bar3_veneer> - 100c: eb000004 bl 1024 <__bar4_from_arm> - 1010: eb000000 bl 1018 <__bar5_from_arm> + 1008: eb00000d bl 1044 <__bar3_veneer> + 100c: eb000001 bl 1018 <__bar4_from_arm> + 1010: eb000008 bl 1038 <__bar5_from_arm> 1014: 00000000 andeq r0, r0, r0 -00001018 <__bar5_from_arm>: - 1018: e59fc000 ldr ip, \[pc, #0\] ; 1020 <__bar5_from_arm\+0x8> +00001018 <__bar4_from_arm>: + 1018: e59fc000 ldr ip, \[pc, #0\] ; 1020 <__bar4_from_arm\+0x8> 101c: e12fff1c bx ip - 1020: 0200302f .word 0x0200302f -00001024 <__bar4_from_arm>: - 1024: e59fc000 ldr ip, \[pc, #0\] ; 102c <__bar4_from_arm\+0x8> - 1028: e12fff1c bx ip - 102c: 0200302d .word 0x0200302d -00001030 <__bar3_veneer>: - 1030: e51ff004 ldr pc, \[pc, #-4\] ; 1034 <__bar3_veneer\+0x4> - 1034: 02003028 .word 0x02003028 -00001038 <__bar_from_arm>: - 1038: e59fc000 ldr ip, \[pc, #0\] ; 1040 <__bar_from_arm\+0x8> + 1020: 0200302d .word 0x0200302d + +00001024 <__bar2_veneer>: + 1024: e51ff004 ldr pc, \[pc, #-4\] ; 1028 <__bar2_veneer\+0x4> + 1028: 02003024 .word 0x02003024 + +0000102c <__bar_from_arm>: + 102c: e59fc000 ldr ip, \[pc, #0\] ; 1034 <__bar_from_arm\+0x8> + 1030: e12fff1c bx ip + 1034: 02003021 .word 0x02003021 + +00001038 <__bar5_from_arm>: + 1038: e59fc000 ldr ip, \[pc, #0\] ; 1040 <__bar5_from_arm\+0x8> 103c: e12fff1c bx ip - 1040: 02003021 .word 0x02003021 -00001044 <__bar2_veneer>: - 1044: e51ff004 ldr pc, \[pc, #-4\] ; 1048 <__bar2_veneer\+0x4> - 1048: 02003024 .word 0x02003024 + 1040: 0200302f .word 0x0200302f + +00001044 <__bar3_veneer>: + 1044: e51ff004 ldr pc, \[pc, #-4\] ; 1048 <__bar3_veneer\+0x4> + 1048: 02003028 .word 0x02003028 ... + Disassembly of section .foo: 02003020 : diff --git a/ld/testsuite/ld-arm/farcall-mix.d b/ld/testsuite/ld-arm/farcall-mix.d index 669a79b586d..97e062c804c 100644 --- a/ld/testsuite/ld-arm/farcall-mix.d +++ b/ld/testsuite/ld-arm/farcall-mix.d @@ -4,32 +4,34 @@ Disassembly of section .text: 00001000 <_start>: - 1000: eb000009 bl 102c <__bar_from_arm> - 1004: eb00000b bl 1038 <__bar2_veneer> + 1000: eb000004 bl 1018 <__bar_from_arm> + 1004: eb00000e bl 1044 <__bar2_veneer> 1008: eb000005 bl 1024 <__bar3_veneer> - 100c: eb00000b bl 1040 <__bar4_from_arm> - 1010: eb000000 bl 1018 <__bar5_from_arm> + 100c: eb000009 bl 1038 <__bar4_from_arm> + 1010: eb000005 bl 102c <__bar5_from_arm> 1014: 00000000 andeq r0, r0, r0 -00001018 <__bar5_from_arm>: - 1018: e59fc000 ldr ip, \[pc, #0\] ; 1020 <__bar5_from_arm\+0x8> +00001018 <__bar_from_arm>: + 1018: e59fc000 ldr ip, \[pc, #0\] ; 1020 <__bar_from_arm\+0x8> 101c: e12fff1c bx ip - 1020: 0200202f .word 0x0200202f + 1020: 02002021 .word 0x02002021 00001024 <__bar3_veneer>: 1024: e51ff004 ldr pc, \[pc, #-4\] ; 1028 <__bar3_veneer\+0x4> 1028: 02002028 .word 0x02002028 -0000102c <__bar_from_arm>: - 102c: e59fc000 ldr ip, \[pc, #0\] ; 1034 <__bar_from_arm\+0x8> +0000102c <__bar5_from_arm>: + 102c: e59fc000 ldr ip, \[pc, #0\] ; 1034 <__bar5_from_arm\+0x8> 1030: e12fff1c bx ip - 1034: 02002021 .word 0x02002021 -00001038 <__bar2_veneer>: - 1038: e51ff004 ldr pc, \[pc, #-4\] ; 103c <__bar2_veneer\+0x4> - 103c: 02002024 .word 0x02002024 -00001040 <__bar4_from_arm>: - 1040: e59fc000 ldr ip, \[pc, #0\] ; 1048 <__bar4_from_arm\+0x8> - 1044: e12fff1c bx ip - 1048: 0200202d .word 0x0200202d + 1034: 0200202f .word 0x0200202f +00001038 <__bar4_from_arm>: + 1038: e59fc000 ldr ip, \[pc, #0\] ; 1040 <__bar4_from_arm\+0x8> + 103c: e12fff1c bx ip + 1040: 0200202d .word 0x0200202d + +00001044 <__bar2_veneer>: + 1044: e51ff004 ldr pc, \[pc, #-4\] ; 1048 <__bar2_veneer\+0x4> + 1048: 02002024 .word 0x02002024 ... + Disassembly of section .foo: 02002020 : diff --git a/ld/testsuite/ld-arm/farcall-mix2.d b/ld/testsuite/ld-arm/farcall-mix2.d index 059803e4597..c79ddea24a8 100644 --- a/ld/testsuite/ld-arm/farcall-mix2.d +++ b/ld/testsuite/ld-arm/farcall-mix2.d @@ -17,22 +17,25 @@ Disassembly of section .text: 101c: 00000000 .word 0x00000000 Disassembly of section .mytext: -00002000 <__bar5_from_arm-0x10>: - 2000: eb000008 bl 2028 <__bar3_veneer> - 2004: eb000004 bl 201c <__bar4_from_arm> - 2008: eb000000 bl 2010 <__bar5_from_arm> +00002000 <__bar3_veneer-0x10>: + 2000: eb000002 bl 2010 <__bar3_veneer> + 2004: eb000003 bl 2018 <__bar4_from_arm> + 2008: eb000005 bl 2024 <__bar5_from_arm> 200c: 00000000 andeq r0, r0, r0 -00002010 <__bar5_from_arm>: - 2010: e59fc000 ldr ip, \[pc, #0\] ; 2018 <__bar5_from_arm\+0x8> - 2014: e12fff1c bx ip - 2018: 0200302f .word 0x0200302f -0000201c <__bar4_from_arm>: - 201c: e59fc000 ldr ip, \[pc, #0\] ; 2024 <__bar4_from_arm\+0x8> - 2020: e12fff1c bx ip - 2024: 0200302d .word 0x0200302d -00002028 <__bar3_veneer>: - 2028: e51ff004 ldr pc, \[pc, #-4\] ; 202c <__bar3_veneer\+0x4> - 202c: 02003028 .word 0x02003028 + +00002010 <__bar3_veneer>: + 2010: e51ff004 ldr pc, \[pc, #-4\] ; 2014 <__bar3_veneer\+0x4> + 2014: 02003028 .word 0x02003028 + +00002018 <__bar4_from_arm>: + 2018: e59fc000 ldr ip, \[pc, #0\] ; 2020 <__bar4_from_arm\+0x8> + 201c: e12fff1c bx ip + 2020: 0200302d .word 0x0200302d + +00002024 <__bar5_from_arm>: + 2024: e59fc000 ldr ip, \[pc, #0\] ; 202c <__bar5_from_arm\+0x8> + 2028: e12fff1c bx ip + 202c: 0200302f .word 0x0200302f ... Disassembly of section .foo: diff --git a/ld/testsuite/ld-arm/farcall-mixed-app-v5.d b/ld/testsuite/ld-arm/farcall-mixed-app-v5.d index fe57a35eeff..ec8312f9c25 100644 --- a/ld/testsuite/ld-arm/farcall-mixed-app-v5.d +++ b/ld/testsuite/ld-arm/farcall-mixed-app-v5.d @@ -49,8 +49,8 @@ Disassembly of section .far_arm: .* : .*: e1a0c00d mov ip, sp .*: e92dd800 push {fp, ip, lr, pc} - .*: eb00000a bl .* <__lib_func1_veneer> - .*: eb000007 bl .* <__lib_func2_veneer> + .*: eb000008 bl .* <__lib_func1_veneer> + .*: eb000009 bl .* <__lib_func2_veneer> .*: e89d6800 ldm sp, {fp, sp, lr} .*: e12fff1e bx lr .*: e1a00000 nop ; \(mov r0, r0\) @@ -62,12 +62,12 @@ Disassembly of section .far_arm: .*: e1a00000 nop ; \(mov r0, r0\) .*: e1a00000 nop ; \(mov r0, r0\) -.* <__lib_func2_veneer>: - .*: e51ff004 ldr pc, \[pc, #-4\] ; 2100034 <__lib_func2_veneer\+0x4> - .*: 000081dc .word 0x000081dc .* <__lib_func1_veneer>: - .*: e51ff004 ldr pc, \[pc, #-4\] ; 210003c <__lib_func1_veneer\+0x4> + .*: e51ff004 ldr pc, \[pc, #-4\] ; 2100034 <__lib_func1_veneer\+0x4> .*: 000081e8 .word 0x000081e8 +.* <__lib_func2_veneer>: + .*: e51ff004 ldr pc, \[pc, #-4\] ; 210003c <__lib_func2_veneer\+0x4> + .*: 000081dc .word 0x000081dc Disassembly of section .far_thumb: diff --git a/ld/testsuite/ld-arm/farcall-mixed-app.d b/ld/testsuite/ld-arm/farcall-mixed-app.d index 9a09ebcb520..c7aff3e6c05 100644 --- a/ld/testsuite/ld-arm/farcall-mixed-app.d +++ b/ld/testsuite/ld-arm/farcall-mixed-app.d @@ -51,8 +51,8 @@ Disassembly of section .far_arm: .* : .*: e1a0c00d mov ip, sp .*: e92dd800 push {fp, ip, lr, pc} - .*: eb00000a bl .* <__lib_func1_veneer> - .*: eb000007 bl .* <__lib_func2_veneer> + .*: eb000008 bl .* <__lib_func1_veneer> + .*: eb000009 bl .* <__lib_func2_veneer> .*: e89d6800 ldm sp, {fp, sp, lr} .*: e12fff1e bx lr .*: e1a00000 nop ; \(mov r0, r0\) @@ -64,12 +64,12 @@ Disassembly of section .far_arm: .*: e1a00000 nop ; \(mov r0, r0\) .*: e1a00000 nop ; \(mov r0, r0\) -.* <__lib_func2_veneer>: - .*: e51ff004 ldr pc, \[pc, #-4\] ; 2100034 <__lib_func2_veneer\+0x4> - .*: 000081e0 .word 0x000081e0 .* <__lib_func1_veneer>: - .*: e51ff004 ldr pc, \[pc, #-4\] ; 210003c <__lib_func1_veneer\+0x4> + .*: e51ff004 ldr pc, \[pc, #-4\] ; 2100034 <__lib_func1_veneer\+0x4> .*: 000081ec .word 0x000081ec +.* <__lib_func2_veneer>: + .*: e51ff004 ldr pc, \[pc, #-4\] ; 210003c <__lib_func2_veneer\+0x4> + .*: 000081e0 .word 0x000081e0 Disassembly of section .far_thumb: diff --git a/ld/testsuite/ld-arm/farcall-mixed-lib-v4t.d b/ld/testsuite/ld-arm/farcall-mixed-lib-v4t.d new file mode 100644 index 00000000000..b6729b200b2 --- /dev/null +++ b/ld/testsuite/ld-arm/farcall-mixed-lib-v4t.d @@ -0,0 +1,123 @@ +tmpdir/farcall-mixed-lib.so: file format elf32-(little|big)arm +architecture: arm, flags 0x00000150: +HAS_SYMS, DYNAMIC, D_PAGED +start address 0x.* + +Disassembly of section .plt: + +.* <.plt>: + .*: e52de004 push {lr} ; \(str lr, \[sp, #-4\]!\) + .*: e59fe004 ldr lr, \[pc, #4\] ; .* + .*: e08fe00e add lr, pc, lr + .*: e5bef008 ldr pc, \[lr, #8\]! + .*: .* .word .* + .*: 4778 bx pc + .*: 46c0 nop ; \(mov r8, r8\) + .*: e28fc6.* add ip, pc, #.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! ; .* + .*: 4778 bx pc + .*: 46c0 nop ; \(mov r8, r8\) + .*: e28fc6.* add ip, pc, #.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! ; 0x.* + .*: 4778 bx pc + .*: 46c0 nop ; \(mov r8, r8\) + .*: e28fc6.* add ip, pc, #.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! ; 0x.* + .*: 4778 bx pc + .*: 46c0 nop ; \(mov r8, r8\) + .*: e28fc6.* add ip, pc, #.* + .*: e28cca.* add ip, ip, #.* ; 0x.* + .*: e5bcf.* ldr pc, \[ip, #.*\]! ; 0x.* + +Disassembly of section .text: + +.* : + .*: e1a0c00d mov ip, sp + .*: e92dd800 push {fp, ip, lr, pc} + .*: ebffff.. bl .* + .*: ebffff.. bl .* + .*: ebffff.. bl .* + .*: ebffff.. bl .* + .*: e89d6800 ldm sp, {fp, sp, lr} + .*: e12fff1e bx lr + ... + +.* <__real_lib_func2>: + .*: f000 f80e bl 1000330 <__app_func_from_thumb> + .*: f000 f81c bl 1000350 <__app_func_weak_from_thumb> + .*: f000 f822 bl 1000360 <__lib_func3_from_thumb> + .*: f000 f810 bl 1000340 <__lib_func4_from_thumb> + .*: 4770 bx lr + .*: 46c0 nop ; \(mov r8, r8\) + .*: 46c0 nop ; \(mov r8, r8\) + .*: 46c0 nop ; \(mov r8, r8\) + .*: 46c0 nop ; \(mov r8, r8\) + .*: 46c0 nop ; \(mov r8, r8\) + .*: 46c0 nop ; \(mov r8, r8\) + .*: 46c0 nop ; \(mov r8, r8\) + +.* <__app_func_from_thumb>: + .*: 4778 bx pc + .*: 46c0 nop ; \(mov r8, r8\) + .*: e59fc000 ldr ip, \[pc, #0\] ; 100033c <__app_func_from_thumb\+0xc> + .*: e08cf00f add pc, ip, pc + .*: feffff68 .word 0xfeffff68 + +.* <__lib_func4_from_thumb>: + .*: 4778 bx pc + .*: 46c0 nop ; \(mov r8, r8\) + .*: e59fc000 ldr ip, \[pc, #0\] ; 100034c <__lib_func4_from_thumb\+0xc> + .*: e08cf00f add pc, ip, pc + .*: feffff88 .word 0xfeffff88 + +.* <__app_func_weak_from_thumb>: + .*: 4778 bx pc + .*: 46c0 nop ; \(mov r8, r8\) + .*: e59fc000 ldr ip, \[pc, #0\] ; 100035c <__app_func_weak_from_thumb\+0xc> + .*: e08cf00f add pc, ip, pc + .*: feffff58 .word 0xfeffff58 + +.* <__lib_func3_from_thumb>: + .*: 4778 bx pc + .*: 46c0 nop ; \(mov r8, r8\) + .*: e59fc000 ldr ip, \[pc, #0\] ; 100036c <__lib_func3_from_thumb\+0xc> + .*: e08cf00f add pc, ip, pc + .*: feffff58 .word 0xfeffff58 + ... + +.* <__real_lib_func3>: + .*: f000 f806 bl 2000380 <__app_func_from_thumb> + .*: f000 f80c bl 2000390 <__app_func_weak_from_thumb> + .*: 4770 bx lr + .*: 46c0 nop ; \(mov r8, r8\) + .*: 46c0 nop ; \(mov r8, r8\) + .*: 46c0 nop ; \(mov r8, r8\) + +.* <__app_func_from_thumb>: + .*: 4778 bx pc + .*: 46c0 nop ; \(mov r8, r8\) + .*: e59fc000 ldr ip, \[pc, #0\] ; 200038c <__app_func_from_thumb\+0xc> + .*: e08cf00f add pc, ip, pc + .*: fdffff18 .word 0xfdffff18 + +.* <__app_func_weak_from_thumb>: + .*: 4778 bx pc + .*: 46c0 nop ; \(mov r8, r8\) + .*: e59fc000 ldr ip, \[pc, #0\] ; 200039c <__app_func_weak_from_thumb\+0xc> + .*: e08cf00f add pc, ip, pc + .*: fdffff18 .word 0xfdffff18 + +.* : + .*: e59fc004 ldr ip, \[pc, #4\] ; 20003ac + .*: e08cc00f add ip, ip, pc + .*: e12fff1c bx ip + .*: ffffffc5 .word 0xffffffc5 + +.* : + .*: e59fc004 ldr ip, \[pc, #4\] ; 20003bc + .*: e08cc00f add ip, ip, pc + .*: e12fff1c bx ip + .*: feffff55 .word 0xfeffff55 diff --git a/ld/testsuite/ld-arm/farcall-mixed-lib.d b/ld/testsuite/ld-arm/farcall-mixed-lib.d index 4e529a47d65..9df3933bc20 100644 --- a/ld/testsuite/ld-arm/farcall-mixed-lib.d +++ b/ld/testsuite/ld-arm/farcall-mixed-lib.d @@ -38,10 +38,10 @@ Disassembly of section .text: ... .* : - .*: f000 e80e blx 1000320 <__app_func_from_thumb> - .*: f000 e81a blx 100033c <__app_func_weak_from_thumb> - .*: f000 e810 blx 100032c <__lib_func3_veneer> - .*: f000 e81c blx 1000348 <__lib_func4_from_thumb> + .*: f000 e820 blx 1000344 <__app_func_from_thumb> + .*: f000 e812 blx 100032c <__app_func_weak_from_thumb> + .*: f000 e80a blx 1000320 <__lib_func3_from_thumb> + .*: f000 e814 blx 1000338 <__lib_func4_from_thumb> .*: 4770 bx lr .*: 46c0 nop ; \(mov r8, r8\) .*: 46c0 nop ; \(mov r8, r8\) @@ -51,43 +51,42 @@ Disassembly of section .text: .*: 46c0 nop ; \(mov r8, r8\) .*: 46c0 nop ; \(mov r8, r8\) -.* <__app_func_from_thumb>: - .*: e59fc000 ldr ip, \[pc, #0\] ; 1000328 <__app_func_from_thumb\+0x8> +.* <__lib_func3_from_thumb>: + .*: e59fc000 ldr ip, \[pc, #0\] ; 1000328 <__lib_func3_from_thumb\+0x8> .*: e08ff00c add pc, pc, ip - .*: feffff78 .word 0xfeffff78 - -.* <__lib_func3_veneer>: - .*: e59fc004 ldr ip, \[pc, #4\] ; 1000338 <__lib_func3_veneer\+0xc> - .*: e08fc00c add ip, pc, ip - .*: e12fff1c bx ip - .*: feffff85 .word 0xfeffff85 + .*: feffff90 .word 0xfeffff90 .* <__app_func_weak_from_thumb>: - .*: e59fc000 ldr ip, \[pc, #0\] ; 1000344 <__app_func_weak_from_thumb\+0x8> + .*: e59fc000 ldr ip, \[pc, #0\] ; 1000334 <__app_func_weak_from_thumb\+0x8> .*: e08ff00c add pc, pc, ip - .*: feffff68 .word 0xfeffff68 + .*: feffff78 .word 0xfeffff78 .* <__lib_func4_from_thumb>: - .*: e59fc000 ldr ip, \[pc, #0\] ; 1000350 <__lib_func4_from_thumb\+0x8> + .*: e59fc000 ldr ip, \[pc, #0\] ; 1000340 <__lib_func4_from_thumb\+0x8> .*: e08ff00c add pc, pc, ip - .*: feffff74 .word 0xfeffff74 + .*: feffff84 .word 0xfeffff84 + +.* <__app_func_from_thumb>: + .*: e59fc000 ldr ip, \[pc, #0\] ; 100034c <__app_func_from_thumb\+0x8> + .*: e08ff00c add pc, pc, ip + .*: feffff54 .word 0xfeffff54 ... .* : - .*: f000 e80c blx 200037c <__app_func_from_thumb> - .*: f000 e804 blx 2000370 <__app_func_weak_from_thumb> + .*: f000 e806 blx 2000370 <__app_func_from_thumb> + .*: f000 e80a blx 200037c <__app_func_weak_from_thumb> .*: 4770 bx lr .*: 46c0 nop ; \(mov r8, r8\) .*: 46c0 nop ; \(mov r8, r8\) .*: 46c0 nop ; \(mov r8, r8\) -.* <__app_func_weak_from_thumb>: - .*: e59fc000 ldr ip, \[pc, #0\] ; 2000378 <__app_func_weak_from_thumb\+0x8> +.* <__app_func_from_thumb>: + .*: e59fc000 ldr ip, \[pc, #0\] ; 2000378 <__app_func_from_thumb\+0x8> .*: e08ff00c add pc, pc, ip - .*: fdffff34 .word 0xfdffff34 + .*: fdffff28 .word 0xfdffff28 -.* <__app_func_from_thumb>: - .*: e59fc000 ldr ip, \[pc, #0\] ; 2000384 <__app_func_from_thumb\+0x8> +.* <__app_func_weak_from_thumb>: + .*: e59fc000 ldr ip, \[pc, #0\] ; 2000384 <__app_func_weak_from_thumb\+0x8> .*: e08ff00c add pc, pc, ip - .*: fdffff1c .word 0xfdffff1c + .*: fdffff28 .word 0xfdffff28 ... diff --git a/ld/testsuite/ld-arm/farcall-mixed-lib1.s b/ld/testsuite/ld-arm/farcall-mixed-lib1.s index f13e7172715..dea26b96917 100644 --- a/ld/testsuite/ld-arm/farcall-mixed-lib1.s +++ b/ld/testsuite/ld-arm/farcall-mixed-lib1.s @@ -3,7 +3,6 @@ @ Check also calls to an undef weak symbol. .text - .arch armv5t .p2align 4 .globl lib_func1 diff --git a/ld/testsuite/ld-arm/farcall-mixed-lib2.s b/ld/testsuite/ld-arm/farcall-mixed-lib2.s index cd5a71f5278..b75c5347b82 100644 --- a/ld/testsuite/ld-arm/farcall-mixed-lib2.s +++ b/ld/testsuite/ld-arm/farcall-mixed-lib2.s @@ -3,7 +3,6 @@ @ Check also calls to an undef weak symbol. .text - .arch armv5t .space 0x1000000 .p2align 4 diff --git a/ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d b/ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d index b2ec457b32d..a0d1f36abc4 100644 --- a/ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d +++ b/ld/testsuite/ld-arm/farcall-thumb-arm-blx-pic-veneer.d @@ -2,16 +2,16 @@ Disassembly of section .text: -00001000 <_start>: - 1000: f000 e802 blx 1008 <__bar_from_thumb> - 1004: 0000 lsls r0, r0, #0 +01c01010 <_start>: + 1c01010: f300 e802 blx 1f01018 <__bar_from_thumb> \.\.\. + 1f01014: f0ff effe blx 2001014 -00001008 <__bar_from_thumb>: - 1008: e59fc000 ldr ip, \[pc, #0\] ; 1010 <__bar_from_thumb\+0x8> - 100c: e08ff00c add pc, pc, ip - 1010: 02000000 .word 0x02000000 - 1014: 00000000 .word 0x00000000 +01f01018 <__bar_from_thumb>: + 1f01018: e59fc000 ldr ip, \[pc, #0\] ; 1f01020 <__bar_from_thumb\+0x8> + 1f0101c: e08ff00c add pc, pc, ip + 1f01020: 000ffff0 .word 0x000ffff0 + 1f01024: 00000000 .word 0x00000000 Disassembly of section .foo: 02001014 : diff --git a/ld/testsuite/ld-arm/farcall-thumb-arm-blx.d b/ld/testsuite/ld-arm/farcall-thumb-arm-blx.d index 9f70091fa06..4a2b36aeb5d 100644 --- a/ld/testsuite/ld-arm/farcall-thumb-arm-blx.d +++ b/ld/testsuite/ld-arm/farcall-thumb-arm-blx.d @@ -2,14 +2,14 @@ Disassembly of section .text: -00001000 <_start>: - 1000: f000 e802 blx 1008 <__bar_from_thumb> - 1004: 0000 lsls r0, r0, #0 +01c01010 <_start>: + 1c01010: f300 e802 blx 1f01018 <__bar_from_thumb> \.\.\. + 1f01014: f0ff effe blx 2001014 -00001008 <__bar_from_thumb>: - 1008: e51ff004 ldr pc, \[pc, #-4\] ; 100c <__bar_from_thumb\+0x4> - 100c: 02001014 .word 0x02001014 +01f01018 <__bar_from_thumb>: + 1f01018: e51ff004 ldr pc, \[pc, #-4\] ; 1f0101c <__bar_from_thumb\+0x4> + 1f0101c: 02001014 .word 0x02001014 Disassembly of section .foo: 02001014 : diff --git a/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d b/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d index e22824adbea..eb8da174519 100644 --- a/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d +++ b/ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d @@ -2,17 +2,17 @@ Disassembly of section .text: -00001000 <_start>: - 1000: f000 f802 bl 1008 <__bar_from_thumb> - 1004: 0000 lsls r0, r0, #0 +01c01010 <_start>: + 1c01010: f300 f802 bl 1f01018 <__bar_from_thumb> ... + 1f01014: f000 f800 bl 1f01018 <__bar_from_thumb> -00001008 <__bar_from_thumb>: - 1008: 4778 bx pc - 100a: 46c0 nop ; \(mov r8, r8\) - 100c: e59fc000 ldr ip, \[pc, #0\] ; 1014 <__bar_from_thumb\+0xc> - 1010: e08cf00f add pc, ip, pc - 1014: 01fffffc .word 0x01fffffc +01f01018 <__bar_from_thumb>: + 1f01018: 4778 bx pc + 1f0101a: 46c0 nop ; \(mov r8, r8\) + 1f0101c: e59fc000 ldr ip, \[pc, #0\] ; 1f01024 <__bar_from_thumb\+0xc> + 1f01020: e08cf00f add pc, ip, pc + 1f01024: 000fffec .word 0x000fffec Disassembly of section .foo: diff --git a/ld/testsuite/ld-arm/farcall-thumb-arm.d b/ld/testsuite/ld-arm/farcall-thumb-arm.d index fb12cf03557..5dc377a0b06 100644 --- a/ld/testsuite/ld-arm/farcall-thumb-arm.d +++ b/ld/testsuite/ld-arm/farcall-thumb-arm.d @@ -2,17 +2,23 @@ Disassembly of section .text: -00001000 <_start>: - 1000: f000 f802 bl 1008 <__bar_from_thumb> - 1004: 0000 lsls r0, r0, #0 +01c01010 <_start>: + 1c01010: f300 f802 bl 1f01018 <__bar_from_thumb> \.\.\. + 1f01014: f000 f806 bl 1f01024 <__bar_from_thumb> + +01f01018 <__bar_from_thumb>: + 1f01018: 4778 bx pc + 1f0101a: 46c0 nop ; \(mov r8, r8\) + 1f0101c: e51ff004 ldr pc, \[pc, #-4\] ; 1f01020 <__bar_from_thumb\+0x8> + 1f01020: 02001014 .word 0x02001014 + +01f01024 <__bar_from_thumb>: + 1f01024: 4778 bx pc + 1f01026: 46c0 nop ; \(mov r8, r8\) + 1f01028: ea03fff9 b 2001014 + 1f0102c: 00000000 andeq r0, r0, r0 -00001008 <__bar_from_thumb>: - 1008: 4778 bx pc - 100a: 46c0 nop ; \(mov r8, r8\) - 100c: e51ff004 ldr pc, \[pc, #-4\] ; 1010 <__bar_from_thumb\+0x8> - 1010: 02001014 .word 0x02001014 - 1014: 00000000 .word 0x00000000 Disassembly of section .foo: 02001014 : diff --git a/ld/testsuite/ld-arm/farcall-thumb-arm.s b/ld/testsuite/ld-arm/farcall-thumb-arm.s index 6fcdbfc37a0..1fd6a078f50 100644 --- a/ld/testsuite/ld-arm/farcall-thumb-arm.s +++ b/ld/testsuite/ld-arm/farcall-thumb-arm.s @@ -1,13 +1,19 @@ @ Test to ensure that a Thumb to ARM call exceeding 4Mb generates a stub. +@ Check that we can generate two types of stub in the same section. .global _start .syntax unified -@ We will place the section .text at 0x1000. +@ We will place the section .text at 0x1c01010. .text .thumb_func _start: + .global bar + bl bar +@ This call is close enough to generate a "short branch" stub +@ or no stub if blx is available. + .space 0x0300000 bl bar @ We will place the section .foo at 0x2001014. -- 2.30.2