2010-03-02 Christophe Lyon <christophe.lyon@st.com>

Alan Modra  <amodra@gmail.com>

	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.
This commit is contained in:
Christophe Lyon 2010-03-02 08:19:54 +00:00
parent 679b7c76e5
commit fe33d2fa46
21 changed files with 530 additions and 267 deletions

View file

@ -1,3 +1,31 @@
2010-03-02 Christophe Lyon <christophe.lyon@st.com>
Alan Modra <amodra@gmail.com>
* 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 <davem@davemloft.net> 2010-03-01 David S. Miller <davem@davemloft.net>
* elfxx-sparc.c (_bfd_sparc_elf_check_relocs): When STT_GNU_IFUNC and * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): When STT_GNU_IFUNC and

View file

@ -2399,6 +2399,7 @@ struct a8_erratum_fix {
unsigned long orig_insn; unsigned long orig_insn;
char *stub_name; char *stub_name;
enum elf32_arm_stub_type stub_type; enum elf32_arm_stub_type stub_type;
int st_type;
}; };
/* A table of relocs applied to branches which might trigger Cortex-A8 /* 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. */ information on stub grouping. */
struct map_stub *stub_group; struct map_stub *stub_group;
/* Number of elements in stub_group. */
int top_id;
/* Assorted information used by elf32_arm_size_stubs. */ /* Assorted information used by elf32_arm_size_stubs. */
unsigned int bfd_count; unsigned int bfd_count;
int top_index; int top_index;
@ -2944,6 +2948,7 @@ elf32_arm_link_hash_table_create (bfd *abfd)
ret->add_stub_section = NULL; ret->add_stub_section = NULL;
ret->layout_sections_again = NULL; ret->layout_sections_again = NULL;
ret->stub_group = NULL; ret->stub_group = NULL;
ret->top_id = 0;
ret->bfd_count = 0; ret->bfd_count = 0;
ret->top_index = 0; ret->top_index = 0;
ret->input_list = NULL; ret->input_list = NULL;
@ -3046,7 +3051,7 @@ static enum elf32_arm_stub_type
arm_type_of_stub (struct bfd_link_info *info, arm_type_of_stub (struct bfd_link_info *info,
asection *input_sec, asection *input_sec,
const Elf_Internal_Rela *rel, const Elf_Internal_Rela *rel,
unsigned char st_type, int *actual_st_type,
struct elf32_arm_link_hash_entry *hash, struct elf32_arm_link_hash_entry *hash,
bfd_vma destination, bfd_vma destination,
asection *sym_sec, asection *sym_sec,
@ -3061,6 +3066,7 @@ arm_type_of_stub (struct bfd_link_info *info,
int thumb_only; int thumb_only;
enum elf32_arm_stub_type stub_type = arm_stub_none; enum elf32_arm_stub_type stub_type = arm_stub_none;
int use_plt = 0; int use_plt = 0;
int st_type = *actual_st_type;
/* 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. */
@ -3080,14 +3086,15 @@ arm_type_of_stub (struct bfd_link_info *info,
+ input_sec->output_section->vma + input_sec->output_section->vma
+ rel->r_offset); + rel->r_offset);
branch_offset = (bfd_signed_vma)(destination - location);
r_type = ELF32_R_TYPE (rel->r_info); r_type = ELF32_R_TYPE (rel->r_info);
/* Keep a simpler condition, for the sake of clarity. */ /* 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; use_plt = 1;
/* Note when dealing with PLT entries: the main PLT stub is in /* Note when dealing with PLT entries: the main PLT stub is in
ARM mode, so if the branch is in Thumb mode, another ARM mode, so if the branch is in Thumb mode, another
Thumb->ARM stub will be inserted later just before the ARM 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 Thumb->Arm one and branch directly to the ARM PLT entry
because it avoids spreading offset corrections in several because it avoids spreading offset corrections in several
places. */ 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) if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
{ {
/* Handle cases where: /* 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) 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; return stub_type;
} }
@ -3255,31 +3277,34 @@ static char *
elf32_arm_stub_name (const asection *input_section, elf32_arm_stub_name (const asection *input_section,
const asection *sym_sec, const asection *sym_sec,
const struct elf32_arm_link_hash_entry *hash, 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; char *stub_name;
bfd_size_type len; bfd_size_type len;
if (hash) 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); stub_name = (char *) bfd_malloc (len);
if (stub_name != NULL) if (stub_name != NULL)
sprintf (stub_name, "%08x_%s+%x", sprintf (stub_name, "%08x_%s+%x_%d",
input_section->id & 0xffffffff, input_section->id & 0xffffffff,
hash->root.root.root.string, hash->root.root.root.string,
(int) rel->r_addend & 0xffffffff); (int) rel->r_addend & 0xffffffff,
(int) stub_type);
} }
else 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); stub_name = (char *) bfd_malloc (len);
if (stub_name != NULL) if (stub_name != NULL)
sprintf (stub_name, "%08x_%x:%x+%x", sprintf (stub_name, "%08x_%x:%x+%x_%d",
input_section->id & 0xffffffff, input_section->id & 0xffffffff,
sym_sec->id & 0xffffffff, sym_sec->id & 0xffffffff,
(int) ELF32_R_SYM (rel->r_info) & 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; return stub_name;
@ -3293,7 +3318,8 @@ elf32_arm_get_stub_entry (const asection *input_section,
const asection *sym_sec, const asection *sym_sec,
struct elf_link_hash_entry *hash, struct elf_link_hash_entry *hash,
const Elf_Internal_Rela *rel, 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_stub_hash_entry *stub_entry;
struct elf32_arm_link_hash_entry *h = (struct elf32_arm_link_hash_entry *) hash; 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 if (h != NULL && h->stub_cache != NULL
&& h->stub_cache->h == h && 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; stub_entry = h->stub_cache;
} }
@ -3319,7 +3346,7 @@ elf32_arm_get_stub_entry (const asection *input_section,
{ {
char *stub_name; 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) if (stub_name == NULL)
return 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 /* We have to do the a8 fixes last, as they are less aligned than
the other veneers. */ the other veneers. */
return TRUE; return TRUE;
/* Make a note of the offset within the stubs for this entry. */ /* Make a note of the offset within the stubs for this entry. */
stub_entry->stub_offset = stub_sec->size; stub_entry->stub_offset = stub_sec->size;
loc = stub_sec->contents + stub_entry->stub_offset; 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); BFD_ASSERT ((data & 0xff00) == 0xd000);
data |= ((stub_entry->orig_insn >> 22) & 0xf) << 8; 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; size += 2;
} }
break; break;
case THUMB32_TYPE: case THUMB32_TYPE:
put_thumb_insn (globals, stub_bfd, bfd_put_16 (stub_bfd,
(template_sequence[i].data >> 16) & 0xffff, (template_sequence[i].data >> 16) & 0xffff,
loc + size); loc + size);
put_thumb_insn (globals, stub_bfd, template_sequence[i].data & 0xffff, bfd_put_16 (stub_bfd, template_sequence[i].data & 0xffff,
loc + size + 2); loc + size + 2);
if (template_sequence[i].r_type != R_ARM_NONE) if (template_sequence[i].r_type != R_ARM_NONE)
{ {
stub_reloc_idx[nrelocs] = i; stub_reloc_idx[nrelocs] = i;
@ -3534,8 +3561,8 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
break; break;
case ARM_TYPE: case ARM_TYPE:
put_arm_insn (globals, stub_bfd, template_sequence[i].data, bfd_put_32 (stub_bfd, template_sequence[i].data,
loc + size); loc + size);
/* Handle cases where the target is encoded within the /* Handle cases where the target is encoded within the
instruction. */ instruction. */
if (template_sequence[i].r_type == R_ARM_JUMP24) if (template_sequence[i].r_type == R_ARM_JUMP24)
@ -3614,11 +3641,23 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
} }
else else
{ {
_bfd_final_link_relocate (elf32_arm_howto_from_type Elf_Internal_Rela rel;
(template_sequence[stub_reloc_idx[i]].r_type), stub_bfd, stub_sec, bfd_boolean unresolved_reloc;
stub_sec->contents, stub_entry->stub_offset + stub_reloc_offset[i], char *error_message;
sym_value + stub_entry->target_addend, bfd_vma points_to = sym_value + stub_entry->target_addend
template_sequence[stub_reloc_idx[i]].reloc_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; return TRUE;
@ -3745,6 +3784,7 @@ elf32_arm_setup_section_lists (bfd *output_bfd,
htab->stub_group = (struct map_stub *) bfd_zmalloc (amt); htab->stub_group = (struct map_stub *) bfd_zmalloc (amt);
if (htab->stub_group == NULL) if (htab->stub_group == NULL)
return -1; return -1;
htab->top_id = top_id;
/* We can't use output_bfd->section_count here to find the top output /* We can't use output_bfd->section_count here to find the top output
section index as some sections may have been removed, and 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; is_32bit_branch = is_b || is_bl || is_blx || is_bcc;
if (((base_vma + i) & 0xfff) == 0xffe if (((base_vma + i) & 0xfff) == 0xffe
&& insn_32bit && insn_32bit
&& is_32bit_branch && 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].orig_insn = insn;
a8_fixes[num_a8_fixes].stub_name = stub_name; a8_fixes[num_a8_fixes].stub_name = stub_name;
a8_fixes[num_a8_fixes].stub_type = stub_type; 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++; num_a8_fixes++;
} }
@ -4219,11 +4261,11 @@ cortex_a8_erratum_scan (bfd *input_bfd,
if (elf_section_data (section)->this_hdr.contents == NULL) if (elf_section_data (section)->this_hdr.contents == NULL)
free (contents); free (contents);
} }
*a8_fixes_p = a8_fixes; *a8_fixes_p = a8_fixes;
*num_a8_fixes_p = num_a8_fixes; *num_a8_fixes_p = num_a8_fixes;
*a8_fix_table_size_p = a8_fix_table_size; *a8_fix_table_size_p = a8_fix_table_size;
return FALSE; return FALSE;
} }
@ -4374,7 +4416,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
const char *sym_name; const char *sym_name;
char *stub_name; char *stub_name;
const asection *id_sec; const asection *id_sec;
unsigned char st_type; int st_type;
bfd_boolean created_stub = FALSE; bfd_boolean created_stub = FALSE;
r_type = ELF32_R_TYPE (irela->r_info); 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 /* This is an undefined symbol. It can never
be resolved. */ be resolved. */
continue; continue;
if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
sym_value = sym->st_value; sym_value = sym->st_value;
destination = (sym_value + irela->r_addend 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. */ /* Determine what (if any) linker stub is needed. */
stub_type = arm_type_of_stub (info, section, irela, stub_type = arm_type_of_stub (info, section, irela,
st_type, hash, &st_type, hash,
destination, sym_sec, destination, sym_sec,
input_bfd, sym_name); input_bfd, sym_name);
if (stub_type == arm_stub_none) if (stub_type == arm_stub_none)
@ -4537,7 +4579,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
/* Get the name of this stub. */ /* Get the name of this stub. */
stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash, stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash,
irela); irela, stub_type);
if (!stub_name) if (!stub_name)
goto error_ret_free_internal; 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_value = a8_fixes[i].offset;
stub_entry->target_addend = a8_fixes[i].addend; stub_entry->target_addend = a8_fixes[i].addend;
stub_entry->orig_insn = a8_fixes[i].orig_insn; 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, size = find_stub_size_and_template (a8_fixes[i].stub_type,
&template_sequence, &template_sequence,
@ -6918,6 +6960,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
".tls_vars") == 0) ".tls_vars") == 0)
&& ((r_type != R_ARM_REL32 && r_type != R_ARM_REL32_NOI) && ((r_type != R_ARM_REL32 && r_type != R_ARM_REL32_NOI)
|| !SYMBOL_CALLS_LOCAL (info, h)) || !SYMBOL_CALLS_LOCAL (info, h))
&& (!strstr (input_section->name, STUB_SUFFIX))
&& (h == NULL && (h == NULL
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak) || 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_PC24: /* Arm B/BL instruction. */
case R_ARM_PLT32: case R_ARM_PLT32:
{ {
bfd_signed_vma branch_offset;
struct elf32_arm_stub_hash_entry *stub_entry = NULL; struct elf32_arm_stub_hash_entry *stub_entry = NULL;
if (r_type == R_ARM_XPC25) 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_JUMP24
|| r_type == R_ARM_PLT32) || r_type == R_ARM_PLT32)
{ {
bfd_vma from; enum elf32_arm_stub_type stub_type = arm_stub_none;
struct elf32_arm_link_hash_entry *hash;
/* 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;
}
from = (input_section->output_section->vma hash = (struct elf32_arm_link_hash_entry *) h;
+ input_section->output_offset stub_type = arm_type_of_stub (info, input_section, rel,
+ rel->r_offset); &sym_flags, hash,
branch_offset = (bfd_signed_vma)(value - from); value, sym_sec,
input_bfd, sym_name);
if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET if (stub_type != arm_stub_none)
|| 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) ))
)
{ {
/* The target is out of reach, so redirect the /* The target is out of reach, so redirect the
branch to the local stub for this function. */ branch to the local stub for this function. */
stub_entry = elf32_arm_get_stub_entry (input_section, stub_entry = elf32_arm_get_stub_entry (input_section,
sym_sec, h, sym_sec, h,
rel, globals); rel, globals,
stub_type);
if (stub_entry != NULL) if (stub_entry != NULL)
value = (stub_entry->stub_offset value = (stub_entry->stub_offset
+ stub_entry->stub_sec->output_offset + stub_entry->stub_sec->output_offset
+ stub_entry->stub_sec->output_section->vma); + 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 /* 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. */ enum elf32_arm_stub_type stub_type = arm_stub_none;
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;
}
if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24) if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
{ {
/* 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; struct elf32_arm_stub_hash_entry *stub_entry;
bfd_signed_vma branch_offset; struct elf32_arm_link_hash_entry *hash;
struct elf32_arm_stub_hash_entry *stub_entry = NULL;
from = (input_section->output_section->vma hash = (struct elf32_arm_link_hash_entry *) h;
+ input_section->output_offset
+ rel->r_offset);
branch_offset = (bfd_signed_vma)(value - from);
if ((!thumb2 stub_type = arm_type_of_stub (info, input_section, rel,
&& (branch_offset > THM_MAX_FWD_BRANCH_OFFSET &sym_flags, hash, value, sym_sec,
|| (branch_offset < THM_MAX_BWD_BRANCH_OFFSET))) input_bfd, sym_name);
||
(thumb2 if (stub_type != arm_stub_none)
&& (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)))
{ {
/* The target is out of reach or we are changing modes, so /* The target is out of reach or we are changing modes, so
redirect the branch to the local stub for this redirect the branch to the local stub for this
function. */ function. */
stub_entry = elf32_arm_get_stub_entry (input_section, stub_entry = elf32_arm_get_stub_entry (input_section,
sym_sec, h, sym_sec, h,
rel, globals); rel, globals,
stub_type);
if (stub_entry != NULL) if (stub_entry != NULL)
value = (stub_entry->stub_offset value = (stub_entry->stub_offset
+ stub_entry->stub_sec->output_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 = value + signed_addend;
relocation -= (input_section->output_section->vma relocation -= (input_section->output_section->vma
@ -9357,6 +9398,7 @@ static bfd_boolean
elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info) elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info)
{ {
struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (info); struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (info);
asection *sec, *osec;
if (globals == NULL) if (globals == NULL)
return FALSE; return FALSE;
@ -9365,6 +9407,20 @@ elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info)
if (!bfd_elf_final_link (abfd, info)) if (!bfd_elf_final_link (abfd, info))
return FALSE; 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; i<htab->top_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 /* Write out any glue sections now that we have created all the
stubs. */ stubs. */
if (globals->bfd_of_glue_owner != NULL) 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_other = 0;
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE); sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
sym.st_shndx = osi->sec_shndx; 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; return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1;
} }

View file

@ -1,3 +1,28 @@
2010-03-02 Christophe Lyon <christophe.lyon@st.com>
Alan Modra <amodra@gmail.com>
* 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 <hongjiu.lu@intel.com> 2010-02-27 H.J. Lu <hongjiu.lu@intel.com>
* ld-elf/init-fini-arrays.d: Pass --wide to readelf. * ld-elf/init-fini-arrays.d: Pass --wide to readelf.

View file

@ -10,10 +10,10 @@ Disassembly of section .text:
800c: fb00000d blx 804a <t5> 800c: fb00000d blx 804a <t5>
8010: fa00000a blx 8040 <t1> 8010: fa00000a blx 8040 <t1>
8014: fb000009 blx 8042 <t2> 8014: fb000009 blx 8042 <t2>
8018: ea000012 b 8068 <__t1_from_arm> 8018: ea000010 b 8060 <__t1_from_arm>
801c: ea00000f b 8060 <__t2_from_arm> 801c: ea000011 b 8068 <__t2_from_arm>
8020: 1b000010 blne 8068 <__t1_from_arm> 8020: 1b00000e blne 8060 <__t1_from_arm>
8024: 1b00000d blne 8060 <__t2_from_arm> 8024: 1b00000f blne 8068 <__t2_from_arm>
8028: 1b000003 blne 803c <arm> 8028: 1b000003 blne 803c <arm>
802c: eb000002 bl 803c <arm> 802c: eb000002 bl 803c <arm>
8030: faffffff blx 8034 <thumblocal> 8030: faffffff blx 8034 <thumblocal>
@ -49,10 +49,10 @@ Disassembly of section .text:
805c: 0000 lsls r0, r0, #0 805c: 0000 lsls r0, r0, #0
... ...
00008060 <__t2_from_arm>: 00008060 <__t1_from_arm>:
8060: e51ff004 ldr pc, \[pc, #-4\] ; 8064 <__t2_from_arm\+0x4> 8060: e51ff004 ldr pc, \[pc, #-4\] ; 8064 <__t1_from_arm\+0x4>
8064: 00008043 .word 0x00008043 8064: 00008041 .word 0x00008041
00008068 <__t1_from_arm>: 00008068 <__t2_from_arm>:
8068: e51ff004 ldr pc, \[pc, #-4\] ; 806c <__t1_from_arm\+0x4> 8068: e51ff004 ldr pc, \[pc, #-4\] ; 806c <__t2_from_arm\+0x4>
806c: 00008041 .word 0x00008041 806c: 00008043 .word 0x00008043

View file

@ -387,25 +387,25 @@ set armeabitests {
{{objdump -d farcall-thumb-thumb-pic-veneer.d}} {{objdump -d farcall-thumb-thumb-pic-veneer.d}}
"farcall-thumb-thumb-pic-veneer"} "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}} {{objdump -d farcall-thumb-arm.d}}
"farcall-thumb-arm"} "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}} {{objdump -d farcall-thumb-arm.d}}
"farcall-thumb-arm-be8"} "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}} {{objdump -d farcall-thumb-arm.d}}
"farcall-thumb-arm-be"} "farcall-thumb-arm-be"}
{"Thumb-ARM (short) call" "-Ttext 0x1000 --section-start .foo=0x0002014" "-W" {farcall-thumb-arm-short.s} {"Thumb-ARM (short) call" "-Ttext 0x1000 --section-start .foo=0x0002014" "-W" {farcall-thumb-arm-short.s}
{{objdump -d farcall-thumb-arm-short.d}} {{objdump -d farcall-thumb-arm-short.d}}
"farcall-thumb-arm-short"} "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}} {{objdump -d farcall-thumb-arm-blx.d}}
"farcall-thumb-arm-blx"} "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}} {{objdump -d farcall-thumb-arm-blx-pic-veneer.d}}
"farcall-thumb-arm-blx-pic-veneer"} "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}} {{objdump -d farcall-thumb-arm-pic-veneer.d}}
"farcall-thumb-arm-pic-veneer"} "farcall-thumb-arm-pic-veneer"}
@ -437,7 +437,12 @@ set armeabitests {
{readelf -Ds farcall-mixed-app.sym}} {readelf -Ds farcall-mixed-app.sym}}
"farcall-mixed-app-v5"} "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} {farcall-mixed-lib1.s farcall-mixed-lib2.s}
{{objdump -fdw farcall-mixed-lib.d}} {{objdump -fdw farcall-mixed-lib.d}}
"farcall-mixed-lib.so"} "farcall-mixed-lib.so"}

View file

@ -13,14 +13,14 @@ Disassembly of section \.text:
80000c: 7fff0000 .word 0x7fff0000 80000c: 7fff0000 .word 0x7fff0000
00800010 <three>: 00800010 <three>:
800010: f001 e806 blx 801020 <__far_fn1_from_thumb> 800010: f001 e802 blx 801018 <__far_fn1_from_thumb>
800014: f001 e800 blx 801018 <__far_fn2_from_thumb> 800014: f001 e804 blx 801020 <__far_fn2_from_thumb>
... ...
800ff8: bf00 nop 800ff8: bf00 nop
00800ffa <label1>: 00800ffa <label1>:
800ffa: ea81 0002 eor.w r0, r1, r2 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 801002: ea81 0002 eor.w r0, r1, r2
801006: ea81 0002 eor.w r0, r1, r2 801006: ea81 0002 eor.w r0, r1, r2
80100a: f7ff bff6 b.w 800ffa <label1> 80100a: f7ff bff6 b.w 800ffa <label1>
@ -28,13 +28,13 @@ Disassembly of section \.text:
801012: ea81 0002 eor.w r0, r1, r2 801012: ea81 0002 eor.w r0, r1, r2
... ...
00801018 <__far_fn2_from_thumb>: 00801018 <__far_fn1_from_thumb>:
801018: e51ff004 ldr pc, \[pc, #-4\] ; 80101c <__far_fn2_from_thumb\+0x4> 801018: e51ff004 ldr pc, \[pc, #-4\] ; 80101c <__far_fn1_from_thumb\+0x4>
80101c: 80000004 .word 0x80000004 80101c: 80000000 .word 0x80000000
00801020 <__far_fn1_from_thumb>: 00801020 <__far_fn2_from_thumb>:
801020: e51ff004 ldr pc, \[pc, #-4\] ; 801024 <__far_fn1_from_thumb\+0x4> 801020: e51ff004 ldr pc, \[pc, #-4\] ; 801024 <__far_fn2_from_thumb\+0x4>
801024: 80000000 .word 0x80000000 801024: 80000004 .word 0x80000004
801028: d001 beq.n 80102e <__far_fn1_from_thumb\+0xe> 801028: d001 beq.n 80102e <__far_fn2_from_thumb\+0xe>
80102a: f7ff bfea b.w 801002 <label1\+0x8> 80102a: f7ff bfea b.w 801002 <label1\+0x8>
80102e: f7ff bfe4 b.w 800ffa <label1> 80102e: f7ff bfe4 b.w 800ffa <label1>

View file

@ -6,27 +6,33 @@ Disassembly of section .text:
00001000 <_start>: 00001000 <_start>:
1000: eb000000 bl 1008 <__bar_from_arm> 1000: eb000000 bl 1008 <__bar_from_arm>
1004: eb000002 bl 1014 <__bar2_veneer> 1004: eb000002 bl 1014 <__bar2_veneer>
00001008 <__bar_from_arm>: 00001008 <__bar_from_arm>:
1008: e59fc000 ldr ip, \[pc, #0\] ; 1010 <__bar_from_arm\+0x8> 1008: e59fc000 ldr ip, \[pc, #0\] ; 1010 <__bar_from_arm\+0x8>
100c: e12fff1c bx ip 100c: e12fff1c bx ip
1010: 02003021 .word 0x02003021 1010: 02003021 .word 0x02003021
00001014 <__bar2_veneer>: 00001014 <__bar2_veneer>:
1014: e51ff004 ldr pc, \[pc, #-4\] ; 1018 <__bar2_veneer\+0x4> 1014: e51ff004 ldr pc, \[pc, #-4\] ; 1018 <__bar2_veneer\+0x4>
1018: 02003024 .word 0x02003024 1018: 02003024 .word 0x02003024
101c: 00000000 .word 0x00000000 101c: 00000000 .word 0x00000000
00001020 <myfunc>: 00001020 <myfunc>:
1020: eb000008 bl 1048 <__bar3_veneer> 1020: eb000008 bl 1048 <__bar3_veneer>
1024: eb000004 bl 103c <__bar4_from_arm> 1024: eb000001 bl 1030 <__bar4_from_arm>
1028: eb000000 bl 1030 <__bar5_from_arm> 1028: eb000003 bl 103c <__bar5_from_arm>
102c: 00000000 andeq r0, r0, r0 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 1034: e12fff1c bx ip
1038: 0200302f .word 0x0200302f 1038: 0200302d .word 0x0200302d
0000103c <__bar4_from_arm>:
103c: e59fc000 ldr ip, \[pc, #0\] ; 1044 <__bar4_from_arm\+0x8> 0000103c <__bar5_from_arm>:
103c: e59fc000 ldr ip, \[pc, #0\] ; 1044 <__bar5_from_arm\+0x8>
1040: e12fff1c bx ip 1040: e12fff1c bx ip
1044: 0200302d .word 0x0200302d 1044: 0200302f .word 0x0200302f
00001048 <__bar3_veneer>: 00001048 <__bar3_veneer>:
1048: e51ff004 ldr pc, \[pc, #-4\] ; 104c <__bar3_veneer\+0x4> 1048: e51ff004 ldr pc, \[pc, #-4\] ; 104c <__bar3_veneer\+0x4>
104c: 02003028 .word 0x02003028 104c: 02003028 .word 0x02003028

View file

@ -4,34 +4,39 @@
Disassembly of section .text: Disassembly of section .text:
00001000 <_start>: 00001000 <_start>:
1000: eb00000c bl 1038 <__bar_from_arm> 1000: eb000009 bl 102c <__bar_from_arm>
1004: eb00000e bl 1044 <__bar2_veneer> 1004: eb000006 bl 1024 <__bar2_veneer>
00001008 <myfunc>: 00001008 <myfunc>:
1008: eb000008 bl 1030 <__bar3_veneer> 1008: eb00000d bl 1044 <__bar3_veneer>
100c: eb000004 bl 1024 <__bar4_from_arm> 100c: eb000001 bl 1018 <__bar4_from_arm>
1010: eb000000 bl 1018 <__bar5_from_arm> 1010: eb000008 bl 1038 <__bar5_from_arm>
1014: 00000000 andeq r0, r0, r0 1014: 00000000 andeq r0, r0, r0
00001018 <__bar5_from_arm>: 00001018 <__bar4_from_arm>:
1018: e59fc000 ldr ip, \[pc, #0\] ; 1020 <__bar5_from_arm\+0x8> 1018: e59fc000 ldr ip, \[pc, #0\] ; 1020 <__bar4_from_arm\+0x8>
101c: e12fff1c bx ip 101c: e12fff1c bx ip
1020: 0200302f .word 0x0200302f 1020: 0200302d .word 0x0200302d
00001024 <__bar4_from_arm>:
1024: e59fc000 ldr ip, \[pc, #0\] ; 102c <__bar4_from_arm\+0x8> 00001024 <__bar2_veneer>:
1028: e12fff1c bx ip 1024: e51ff004 ldr pc, \[pc, #-4\] ; 1028 <__bar2_veneer\+0x4>
102c: 0200302d .word 0x0200302d 1028: 02003024 .word 0x02003024
00001030 <__bar3_veneer>:
1030: e51ff004 ldr pc, \[pc, #-4\] ; 1034 <__bar3_veneer\+0x4> 0000102c <__bar_from_arm>:
1034: 02003028 .word 0x02003028 102c: e59fc000 ldr ip, \[pc, #0\] ; 1034 <__bar_from_arm\+0x8>
00001038 <__bar_from_arm>: 1030: e12fff1c bx ip
1038: e59fc000 ldr ip, \[pc, #0\] ; 1040 <__bar_from_arm\+0x8> 1034: 02003021 .word 0x02003021
00001038 <__bar5_from_arm>:
1038: e59fc000 ldr ip, \[pc, #0\] ; 1040 <__bar5_from_arm\+0x8>
103c: e12fff1c bx ip 103c: e12fff1c bx ip
1040: 02003021 .word 0x02003021 1040: 0200302f .word 0x0200302f
00001044 <__bar2_veneer>:
1044: e51ff004 ldr pc, \[pc, #-4\] ; 1048 <__bar2_veneer\+0x4> 00001044 <__bar3_veneer>:
1048: 02003024 .word 0x02003024 1044: e51ff004 ldr pc, \[pc, #-4\] ; 1048 <__bar3_veneer\+0x4>
1048: 02003028 .word 0x02003028
... ...
Disassembly of section .foo: Disassembly of section .foo:
02003020 <bar>: 02003020 <bar>:

View file

@ -4,32 +4,34 @@
Disassembly of section .text: Disassembly of section .text:
00001000 <_start>: 00001000 <_start>:
1000: eb000009 bl 102c <__bar_from_arm> 1000: eb000004 bl 1018 <__bar_from_arm>
1004: eb00000b bl 1038 <__bar2_veneer> 1004: eb00000e bl 1044 <__bar2_veneer>
1008: eb000005 bl 1024 <__bar3_veneer> 1008: eb000005 bl 1024 <__bar3_veneer>
100c: eb00000b bl 1040 <__bar4_from_arm> 100c: eb000009 bl 1038 <__bar4_from_arm>
1010: eb000000 bl 1018 <__bar5_from_arm> 1010: eb000005 bl 102c <__bar5_from_arm>
1014: 00000000 andeq r0, r0, r0 1014: 00000000 andeq r0, r0, r0
00001018 <__bar5_from_arm>: 00001018 <__bar_from_arm>:
1018: e59fc000 ldr ip, \[pc, #0\] ; 1020 <__bar5_from_arm\+0x8> 1018: e59fc000 ldr ip, \[pc, #0\] ; 1020 <__bar_from_arm\+0x8>
101c: e12fff1c bx ip 101c: e12fff1c bx ip
1020: 0200202f .word 0x0200202f 1020: 02002021 .word 0x02002021
00001024 <__bar3_veneer>: 00001024 <__bar3_veneer>:
1024: e51ff004 ldr pc, \[pc, #-4\] ; 1028 <__bar3_veneer\+0x4> 1024: e51ff004 ldr pc, \[pc, #-4\] ; 1028 <__bar3_veneer\+0x4>
1028: 02002028 .word 0x02002028 1028: 02002028 .word 0x02002028
0000102c <__bar_from_arm>: 0000102c <__bar5_from_arm>:
102c: e59fc000 ldr ip, \[pc, #0\] ; 1034 <__bar_from_arm\+0x8> 102c: e59fc000 ldr ip, \[pc, #0\] ; 1034 <__bar5_from_arm\+0x8>
1030: e12fff1c bx ip 1030: e12fff1c bx ip
1034: 02002021 .word 0x02002021 1034: 0200202f .word 0x0200202f
00001038 <__bar2_veneer>: 00001038 <__bar4_from_arm>:
1038: e51ff004 ldr pc, \[pc, #-4\] ; 103c <__bar2_veneer\+0x4> 1038: e59fc000 ldr ip, \[pc, #0\] ; 1040 <__bar4_from_arm\+0x8>
103c: 02002024 .word 0x02002024 103c: e12fff1c bx ip
00001040 <__bar4_from_arm>: 1040: 0200202d .word 0x0200202d
1040: e59fc000 ldr ip, \[pc, #0\] ; 1048 <__bar4_from_arm\+0x8>
1044: e12fff1c bx ip 00001044 <__bar2_veneer>:
1048: 0200202d .word 0x0200202d 1044: e51ff004 ldr pc, \[pc, #-4\] ; 1048 <__bar2_veneer\+0x4>
1048: 02002024 .word 0x02002024
... ...
Disassembly of section .foo: Disassembly of section .foo:
02002020 <bar>: 02002020 <bar>:

View file

@ -17,22 +17,25 @@ Disassembly of section .text:
101c: 00000000 .word 0x00000000 101c: 00000000 .word 0x00000000
Disassembly of section .mytext: Disassembly of section .mytext:
00002000 <__bar5_from_arm-0x10>: 00002000 <__bar3_veneer-0x10>:
2000: eb000008 bl 2028 <__bar3_veneer> 2000: eb000002 bl 2010 <__bar3_veneer>
2004: eb000004 bl 201c <__bar4_from_arm> 2004: eb000003 bl 2018 <__bar4_from_arm>
2008: eb000000 bl 2010 <__bar5_from_arm> 2008: eb000005 bl 2024 <__bar5_from_arm>
200c: 00000000 andeq r0, r0, r0 200c: 00000000 andeq r0, r0, r0
00002010 <__bar5_from_arm>:
2010: e59fc000 ldr ip, \[pc, #0\] ; 2018 <__bar5_from_arm\+0x8> 00002010 <__bar3_veneer>:
2014: e12fff1c bx ip 2010: e51ff004 ldr pc, \[pc, #-4\] ; 2014 <__bar3_veneer\+0x4>
2018: 0200302f .word 0x0200302f 2014: 02003028 .word 0x02003028
0000201c <__bar4_from_arm>:
201c: e59fc000 ldr ip, \[pc, #0\] ; 2024 <__bar4_from_arm\+0x8> 00002018 <__bar4_from_arm>:
2020: e12fff1c bx ip 2018: e59fc000 ldr ip, \[pc, #0\] ; 2020 <__bar4_from_arm\+0x8>
2024: 0200302d .word 0x0200302d 201c: e12fff1c bx ip
00002028 <__bar3_veneer>: 2020: 0200302d .word 0x0200302d
2028: e51ff004 ldr pc, \[pc, #-4\] ; 202c <__bar3_veneer\+0x4>
202c: 02003028 .word 0x02003028 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: Disassembly of section .foo:

View file

@ -49,8 +49,8 @@ Disassembly of section .far_arm:
.* <app_func>: .* <app_func>:
.*: e1a0c00d mov ip, sp .*: e1a0c00d mov ip, sp
.*: e92dd800 push {fp, ip, lr, pc} .*: e92dd800 push {fp, ip, lr, pc}
.*: eb00000a bl .* <__lib_func1_veneer> .*: eb000008 bl .* <__lib_func1_veneer>
.*: eb000007 bl .* <__lib_func2_veneer> .*: eb000009 bl .* <__lib_func2_veneer>
.*: e89d6800 ldm sp, {fp, sp, lr} .*: e89d6800 ldm sp, {fp, sp, lr}
.*: e12fff1e bx lr .*: e12fff1e bx lr
.*: e1a00000 nop ; \(mov r0, r0\) .*: e1a00000 nop ; \(mov r0, r0\)
@ -62,12 +62,12 @@ Disassembly of section .far_arm:
.*: e1a00000 nop ; \(mov r0, r0\) .*: e1a00000 nop ; \(mov r0, r0\)
.*: 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>: .* <__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 .*: 000081e8 .word 0x000081e8
.* <__lib_func2_veneer>:
.*: e51ff004 ldr pc, \[pc, #-4\] ; 210003c <__lib_func2_veneer\+0x4>
.*: 000081dc .word 0x000081dc
Disassembly of section .far_thumb: Disassembly of section .far_thumb:

View file

@ -51,8 +51,8 @@ Disassembly of section .far_arm:
.* <app_func>: .* <app_func>:
.*: e1a0c00d mov ip, sp .*: e1a0c00d mov ip, sp
.*: e92dd800 push {fp, ip, lr, pc} .*: e92dd800 push {fp, ip, lr, pc}
.*: eb00000a bl .* <__lib_func1_veneer> .*: eb000008 bl .* <__lib_func1_veneer>
.*: eb000007 bl .* <__lib_func2_veneer> .*: eb000009 bl .* <__lib_func2_veneer>
.*: e89d6800 ldm sp, {fp, sp, lr} .*: e89d6800 ldm sp, {fp, sp, lr}
.*: e12fff1e bx lr .*: e12fff1e bx lr
.*: e1a00000 nop ; \(mov r0, r0\) .*: e1a00000 nop ; \(mov r0, r0\)
@ -64,12 +64,12 @@ Disassembly of section .far_arm:
.*: e1a00000 nop ; \(mov r0, r0\) .*: e1a00000 nop ; \(mov r0, r0\)
.*: 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>: .* <__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 .*: 000081ec .word 0x000081ec
.* <__lib_func2_veneer>:
.*: e51ff004 ldr pc, \[pc, #-4\] ; 210003c <__lib_func2_veneer\+0x4>
.*: 000081e0 .word 0x000081e0
Disassembly of section .far_thumb: Disassembly of section .far_thumb:

View file

@ -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\] ; .* <lib_func1-0x.*>
.*: 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:
.* <lib_func1>:
.*: e1a0c00d mov ip, sp
.*: e92dd800 push {fp, ip, lr, pc}
.*: ebffff.. bl .* <lib_func1-0x.*>
.*: ebffff.. bl .* <lib_func1-0x.*>
.*: ebffff.. bl .* <lib_func1-0x.*>
.*: ebffff.. bl .* <lib_func1-0x.*>
.*: 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
.* <lib_func3>:
.*: e59fc004 ldr ip, \[pc, #4\] ; 20003ac <lib_func3\+0xc>
.*: e08cc00f add ip, ip, pc
.*: e12fff1c bx ip
.*: ffffffc5 .word 0xffffffc5
.* <lib_func2>:
.*: e59fc004 ldr ip, \[pc, #4\] ; 20003bc <lib_func2\+0xc>
.*: e08cc00f add ip, ip, pc
.*: e12fff1c bx ip
.*: feffff55 .word 0xfeffff55

View file

@ -38,10 +38,10 @@ Disassembly of section .text:
... ...
.* <lib_func2>: .* <lib_func2>:
.*: f000 e80e blx 1000320 <__app_func_from_thumb> .*: f000 e820 blx 1000344 <__app_func_from_thumb>
.*: f000 e81a blx 100033c <__app_func_weak_from_thumb> .*: f000 e812 blx 100032c <__app_func_weak_from_thumb>
.*: f000 e810 blx 100032c <__lib_func3_veneer> .*: f000 e80a blx 1000320 <__lib_func3_from_thumb>
.*: f000 e81c blx 1000348 <__lib_func4_from_thumb> .*: f000 e814 blx 1000338 <__lib_func4_from_thumb>
.*: 4770 bx lr .*: 4770 bx lr
.*: 46c0 nop ; \(mov r8, r8\) .*: 46c0 nop ; \(mov r8, r8\)
.*: 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\)
.*: 46c0 nop ; \(mov r8, r8\) .*: 46c0 nop ; \(mov r8, r8\)
.* <__app_func_from_thumb>: .* <__lib_func3_from_thumb>:
.*: e59fc000 ldr ip, \[pc, #0\] ; 1000328 <__app_func_from_thumb\+0x8> .*: e59fc000 ldr ip, \[pc, #0\] ; 1000328 <__lib_func3_from_thumb\+0x8>
.*: e08ff00c add pc, pc, ip
.*: feffff90 .word 0xfeffff90
.* <__app_func_weak_from_thumb>:
.*: e59fc000 ldr ip, \[pc, #0\] ; 1000334 <__app_func_weak_from_thumb\+0x8>
.*: e08ff00c add pc, pc, ip .*: e08ff00c add pc, pc, ip
.*: feffff78 .word 0xfeffff78 .*: 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
.* <__app_func_weak_from_thumb>:
.*: e59fc000 ldr ip, \[pc, #0\] ; 1000344 <__app_func_weak_from_thumb\+0x8>
.*: e08ff00c add pc, pc, ip
.*: feffff68 .word 0xfeffff68
.* <__lib_func4_from_thumb>: .* <__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 .*: 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
... ...
.* <lib_func3>: .* <lib_func3>:
.*: f000 e80c blx 200037c <__app_func_from_thumb> .*: f000 e806 blx 2000370 <__app_func_from_thumb>
.*: f000 e804 blx 2000370 <__app_func_weak_from_thumb> .*: f000 e80a blx 200037c <__app_func_weak_from_thumb>
.*: 4770 bx lr .*: 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\)
.* <__app_func_weak_from_thumb>:
.*: e59fc000 ldr ip, \[pc, #0\] ; 2000378 <__app_func_weak_from_thumb\+0x8>
.*: e08ff00c add pc, pc, ip
.*: fdffff34 .word 0xfdffff34
.* <__app_func_from_thumb>: .* <__app_func_from_thumb>:
.*: e59fc000 ldr ip, \[pc, #0\] ; 2000384 <__app_func_from_thumb\+0x8> .*: e59fc000 ldr ip, \[pc, #0\] ; 2000378 <__app_func_from_thumb\+0x8>
.*: e08ff00c add pc, pc, ip .*: e08ff00c add pc, pc, ip
.*: fdffff1c .word 0xfdffff1c .*: fdffff28 .word 0xfdffff28
.* <__app_func_weak_from_thumb>:
.*: e59fc000 ldr ip, \[pc, #0\] ; 2000384 <__app_func_weak_from_thumb\+0x8>
.*: e08ff00c add pc, pc, ip
.*: fdffff28 .word 0xfdffff28
... ...

View file

@ -3,7 +3,6 @@
@ Check also calls to an undef weak symbol. @ Check also calls to an undef weak symbol.
.text .text
.arch armv5t
.p2align 4 .p2align 4
.globl lib_func1 .globl lib_func1

View file

@ -3,7 +3,6 @@
@ Check also calls to an undef weak symbol. @ Check also calls to an undef weak symbol.
.text .text
.arch armv5t
.space 0x1000000 .space 0x1000000
.p2align 4 .p2align 4

View file

@ -2,16 +2,16 @@
Disassembly of section .text: Disassembly of section .text:
00001000 <_start>: 01c01010 <_start>:
1000: f000 e802 blx 1008 <__bar_from_thumb> 1c01010: f300 e802 blx 1f01018 <__bar_from_thumb>
1004: 0000 lsls r0, r0, #0
\.\.\. \.\.\.
1f01014: f0ff effe blx 2001014 <bar>
00001008 <__bar_from_thumb>: 01f01018 <__bar_from_thumb>:
1008: e59fc000 ldr ip, \[pc, #0\] ; 1010 <__bar_from_thumb\+0x8> 1f01018: e59fc000 ldr ip, \[pc, #0\] ; 1f01020 <__bar_from_thumb\+0x8>
100c: e08ff00c add pc, pc, ip 1f0101c: e08ff00c add pc, pc, ip
1010: 02000000 .word 0x02000000 1f01020: 000ffff0 .word 0x000ffff0
1014: 00000000 .word 0x00000000 1f01024: 00000000 .word 0x00000000
Disassembly of section .foo: Disassembly of section .foo:
02001014 <bar>: 02001014 <bar>:

View file

@ -2,14 +2,14 @@
Disassembly of section .text: Disassembly of section .text:
00001000 <_start>: 01c01010 <_start>:
1000: f000 e802 blx 1008 <__bar_from_thumb> 1c01010: f300 e802 blx 1f01018 <__bar_from_thumb>
1004: 0000 lsls r0, r0, #0
\.\.\. \.\.\.
1f01014: f0ff effe blx 2001014 <bar>
00001008 <__bar_from_thumb>: 01f01018 <__bar_from_thumb>:
1008: e51ff004 ldr pc, \[pc, #-4\] ; 100c <__bar_from_thumb\+0x4> 1f01018: e51ff004 ldr pc, \[pc, #-4\] ; 1f0101c <__bar_from_thumb\+0x4>
100c: 02001014 .word 0x02001014 1f0101c: 02001014 .word 0x02001014
Disassembly of section .foo: Disassembly of section .foo:
02001014 <bar>: 02001014 <bar>:

View file

@ -2,17 +2,17 @@
Disassembly of section .text: Disassembly of section .text:
00001000 <_start>: 01c01010 <_start>:
1000: f000 f802 bl 1008 <__bar_from_thumb> 1c01010: f300 f802 bl 1f01018 <__bar_from_thumb>
1004: 0000 lsls r0, r0, #0
... ...
1f01014: f000 f800 bl 1f01018 <__bar_from_thumb>
00001008 <__bar_from_thumb>: 01f01018 <__bar_from_thumb>:
1008: 4778 bx pc 1f01018: 4778 bx pc
100a: 46c0 nop ; \(mov r8, r8\) 1f0101a: 46c0 nop ; \(mov r8, r8\)
100c: e59fc000 ldr ip, \[pc, #0\] ; 1014 <__bar_from_thumb\+0xc> 1f0101c: e59fc000 ldr ip, \[pc, #0\] ; 1f01024 <__bar_from_thumb\+0xc>
1010: e08cf00f add pc, ip, pc 1f01020: e08cf00f add pc, ip, pc
1014: 01fffffc .word 0x01fffffc 1f01024: 000fffec .word 0x000fffec
Disassembly of section .foo: Disassembly of section .foo:

View file

@ -2,17 +2,23 @@
Disassembly of section .text: Disassembly of section .text:
00001000 <_start>: 01c01010 <_start>:
1000: f000 f802 bl 1008 <__bar_from_thumb> 1c01010: f300 f802 bl 1f01018 <__bar_from_thumb>
1004: 0000 lsls r0, r0, #0
\.\.\. \.\.\.
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 <bar>
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: Disassembly of section .foo:
02001014 <bar>: 02001014 <bar>:

View file

@ -1,13 +1,19 @@
@ Test to ensure that a Thumb to ARM call exceeding 4Mb generates a stub. @ 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 .global _start
.syntax unified .syntax unified
@ We will place the section .text at 0x1000. @ We will place the section .text at 0x1c01010.
.text .text
.thumb_func .thumb_func
_start: _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 bl bar
@ We will place the section .foo at 0x2001014. @ We will place the section .foo at 0x2001014.