mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-30 12:44:10 +08:00
Allow veneers to claim veneered symbols
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com> bfd/ * elf32-arm.c (enum elf32_arm_stub_type): New max_stub_type enumerator. (arm_stub_sym_claimed): New function. (elf32_arm_create_stub): Use veneered symbol name and section if veneer needs to claim its symbol, and keep logic unchanged otherwise. (arm_stub_claim_sym): New function. (arm_map_one_stub): Call arm_stub_claim_sym if veneer needs to claim veneered symbol, otherwise create local symbol as before.
This commit is contained in:
parent
39d911fc3c
commit
4f4faa4d43
@ -1,3 +1,14 @@
|
||||
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
* elf32-arm.c (enum elf32_arm_stub_type): New max_stub_type
|
||||
enumerator.
|
||||
(arm_stub_sym_claimed): New function.
|
||||
(elf32_arm_create_stub): Use veneered symbol name and section if
|
||||
veneer needs to claim its symbol, and keep logic unchanged otherwise.
|
||||
(arm_stub_claim_sym): New function.
|
||||
(arm_map_one_stub): Call arm_stub_claim_sym if veneer needs to claim
|
||||
veneered symbol, otherwise create local symbol as before.
|
||||
|
||||
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
* elf32-arm.c (elf32_arm_size_stubs): Use new macros
|
||||
|
147
bfd/elf32-arm.c
147
bfd/elf32-arm.c
@ -2632,6 +2632,7 @@ enum elf32_arm_stub_type
|
||||
{
|
||||
arm_stub_none,
|
||||
DEF_STUBS
|
||||
max_stub_type
|
||||
};
|
||||
#undef DEF_STUB
|
||||
|
||||
@ -4335,6 +4336,18 @@ arm_stub_required_alignment (enum elf32_arm_stub_type stub_type)
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns whether stubs of type STUB_TYPE take over the symbol they are
|
||||
veneering (TRUE) or have their own symbol (FALSE). */
|
||||
|
||||
static bfd_boolean
|
||||
arm_stub_sym_claimed (enum elf32_arm_stub_type stub_type)
|
||||
{
|
||||
if (stub_type >= max_stub_type)
|
||||
abort (); /* Should be unreachable. */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
arm_build_one_stub (struct bfd_hash_entry *gen_entry,
|
||||
void * in_arg)
|
||||
@ -5141,27 +5154,35 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table *htab,
|
||||
char *stub_name;
|
||||
struct elf32_arm_stub_hash_entry *stub_entry;
|
||||
unsigned int r_type;
|
||||
bfd_boolean sym_claimed = arm_stub_sym_claimed (stub_type);
|
||||
|
||||
BFD_ASSERT (stub_type != arm_stub_none);
|
||||
*new_stub = FALSE;
|
||||
|
||||
BFD_ASSERT (irela);
|
||||
BFD_ASSERT (section);
|
||||
if (sym_claimed)
|
||||
stub_name = sym_name;
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (irela);
|
||||
BFD_ASSERT (section);
|
||||
|
||||
/* Support for grouping stub sections. */
|
||||
id_sec = htab->stub_group[section->id].link_sec;
|
||||
/* Support for grouping stub sections. */
|
||||
id_sec = htab->stub_group[section->id].link_sec;
|
||||
|
||||
/* Get the name of this stub. */
|
||||
stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash, irela, stub_type);
|
||||
if (!stub_name)
|
||||
return FALSE;
|
||||
/* Get the name of this stub. */
|
||||
stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash, irela,
|
||||
stub_type);
|
||||
if (!stub_name)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name, FALSE,
|
||||
FALSE);
|
||||
/* The proper stub has already been created, just update its value. */
|
||||
if (stub_entry != NULL)
|
||||
{
|
||||
free (stub_name);
|
||||
if (!sym_claimed)
|
||||
free (stub_name);
|
||||
stub_entry->target_value = sym_value;
|
||||
return TRUE;
|
||||
}
|
||||
@ -5169,7 +5190,8 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table *htab,
|
||||
stub_entry = elf32_arm_add_stub (stub_name, section, htab);
|
||||
if (stub_entry == NULL)
|
||||
{
|
||||
free (stub_name);
|
||||
if (!sym_claimed)
|
||||
free (stub_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -5179,31 +5201,36 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table *htab,
|
||||
stub_entry->h = hash;
|
||||
stub_entry->branch_type = branch_type;
|
||||
|
||||
if (sym_name == NULL)
|
||||
sym_name = "unnamed";
|
||||
stub_entry->output_name = (char *)
|
||||
bfd_alloc (htab->stub_bfd, sizeof (THUMB2ARM_GLUE_ENTRY_NAME)
|
||||
+ strlen (sym_name));
|
||||
if (stub_entry->output_name == NULL)
|
||||
{
|
||||
free (stub_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* For historical reasons, use the existing names for ARM-to-Thumb and
|
||||
Thumb-to-ARM stubs. */
|
||||
r_type = ELF32_R_TYPE (irela->r_info);
|
||||
if ((r_type == (unsigned int) R_ARM_THM_CALL
|
||||
|| r_type == (unsigned int) R_ARM_THM_JUMP24
|
||||
|| r_type == (unsigned int) R_ARM_THM_JUMP19)
|
||||
&& branch_type == ST_BRANCH_TO_ARM)
|
||||
sprintf (stub_entry->output_name, THUMB2ARM_GLUE_ENTRY_NAME, sym_name);
|
||||
else if ((r_type == (unsigned int) R_ARM_CALL
|
||||
|| r_type == (unsigned int) R_ARM_JUMP24)
|
||||
&& branch_type == ST_BRANCH_TO_THUMB)
|
||||
sprintf (stub_entry->output_name, ARM2THUMB_GLUE_ENTRY_NAME, sym_name);
|
||||
if (sym_claimed)
|
||||
stub_entry->output_name = sym_name;
|
||||
else
|
||||
sprintf (stub_entry->output_name, STUB_ENTRY_NAME, sym_name);
|
||||
{
|
||||
if (sym_name == NULL)
|
||||
sym_name = "unnamed";
|
||||
stub_entry->output_name = (char *)
|
||||
bfd_alloc (htab->stub_bfd, sizeof (THUMB2ARM_GLUE_ENTRY_NAME)
|
||||
+ strlen (sym_name));
|
||||
if (stub_entry->output_name == NULL)
|
||||
{
|
||||
free (stub_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* For historical reasons, use the existing names for ARM-to-Thumb and
|
||||
Thumb-to-ARM stubs. */
|
||||
r_type = ELF32_R_TYPE (irela->r_info);
|
||||
if ((r_type == (unsigned int) R_ARM_THM_CALL
|
||||
|| r_type == (unsigned int) R_ARM_THM_JUMP24
|
||||
|| r_type == (unsigned int) R_ARM_THM_JUMP19)
|
||||
&& branch_type == ST_BRANCH_TO_ARM)
|
||||
sprintf (stub_entry->output_name, THUMB2ARM_GLUE_ENTRY_NAME, sym_name);
|
||||
else if ((r_type == (unsigned int) R_ARM_CALL
|
||||
|| r_type == (unsigned int) R_ARM_JUMP24)
|
||||
&& branch_type == ST_BRANCH_TO_THUMB)
|
||||
sprintf (stub_entry->output_name, ARM2THUMB_GLUE_ENTRY_NAME, sym_name);
|
||||
else
|
||||
sprintf (stub_entry->output_name, STUB_ENTRY_NAME, sym_name);
|
||||
}
|
||||
|
||||
*new_stub = TRUE;
|
||||
return TRUE;
|
||||
@ -15861,6 +15888,20 @@ elf32_arm_output_plt_map (struct elf_link_hash_entry *h, void *inf)
|
||||
&h->plt, &eh->plt);
|
||||
}
|
||||
|
||||
/* Bind a veneered symbol to its veneer identified by its hash entry
|
||||
STUB_ENTRY. The veneered location thus loose its symbol. */
|
||||
|
||||
static void
|
||||
arm_stub_claim_sym (struct elf32_arm_stub_hash_entry *stub_entry)
|
||||
{
|
||||
struct elf32_arm_link_hash_entry *hash = stub_entry->h;
|
||||
|
||||
BFD_ASSERT (hash);
|
||||
hash->root.root.u.def.section = stub_entry->stub_sec;
|
||||
hash->root.root.u.def.value = stub_entry->stub_offset;
|
||||
hash->root.size = stub_entry->stub_size;
|
||||
}
|
||||
|
||||
/* Output a single local symbol for a generated stub. */
|
||||
|
||||
static bfd_boolean
|
||||
@ -15907,24 +15948,30 @@ arm_map_one_stub (struct bfd_hash_entry * gen_entry,
|
||||
return TRUE;
|
||||
|
||||
addr = (bfd_vma) stub_entry->stub_offset;
|
||||
stub_name = stub_entry->output_name;
|
||||
|
||||
template_sequence = stub_entry->stub_template;
|
||||
switch (template_sequence[0].type)
|
||||
|
||||
if (arm_stub_sym_claimed (stub_entry->stub_type))
|
||||
arm_stub_claim_sym (stub_entry);
|
||||
else
|
||||
{
|
||||
case ARM_TYPE:
|
||||
if (!elf32_arm_output_stub_sym (osi, stub_name, addr, stub_entry->stub_size))
|
||||
return FALSE;
|
||||
break;
|
||||
case THUMB16_TYPE:
|
||||
case THUMB32_TYPE:
|
||||
if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1,
|
||||
stub_entry->stub_size))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
BFD_FAIL ();
|
||||
return 0;
|
||||
stub_name = stub_entry->output_name;
|
||||
switch (template_sequence[0].type)
|
||||
{
|
||||
case ARM_TYPE:
|
||||
if (!elf32_arm_output_stub_sym (osi, stub_name, addr,
|
||||
stub_entry->stub_size))
|
||||
return FALSE;
|
||||
break;
|
||||
case THUMB16_TYPE:
|
||||
case THUMB32_TYPE:
|
||||
if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1,
|
||||
stub_entry->stub_size))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
BFD_FAIL ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
prev_type = DATA_TYPE;
|
||||
|
Loading…
Reference in New Issue
Block a user