Use getters/setters to access ARM branch type

2016-05-10  Thomas Preud'homme  <thomas.preudhomme@arm.com>

bfd/
	* elf32-arm.c (elf32_arm_size_stubs): Use new macros
	ARM_GET_SYM_BRANCH_TYPE and ARM_SET_SYM_BRANCH_TYPE to respectively get
	and set branch type of a symbol.
	(bfd_elf32_arm_process_before_allocation): Likewise.
	(elf32_arm_relocate_section): Likewise and fix identation along the
	way.
	(allocate_dynrelocs_for_symbol): Likewise.
	(elf32_arm_finish_dynamic_symbol): Likewise.
	(elf32_arm_swap_symbol_in): Likewise.
	(elf32_arm_swap_symbol_out): Likewise.

gas/
	* config/tc-arm.c (arm_adjust_symtab): Use ARM_SET_SYM_BRANCH_TYPE to
	set branch type of a symbol.

gdb/
	* arm-tdep.c (arm_elf_make_msymbol_special): Use
	ARM_GET_SYM_BRANCH_TYPE to get branch type of a symbol.

include/
	* arm.h (enum arm_st_branch_type): Add new ST_BRANCH_ENUM_SIZE
	enumerator.
	(NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS): New macro.
	(ENUM_ARM_ST_BRANCH_TYPE_BITMASK): Likewise.
	(ARM_SYM_BRANCH_TYPE): Replace by ...
	(ARM_GET_SYM_BRANCH_TYPE): This and ...
	(ARM_SET_SYM_BRANCH_TYPE): This in two versions depending on whether
	BFD_ASSERT is defined or not.

ld/
	* emultempl/armelf.em (gld${EMULATION_NAME}_finish): Use
	ARM_GET_SYM_BRANCH_TYPE to get branch type of a symbol.

opcodes/
	* arm-dis.c (get_sym_code_type): Use ARM_GET_SYM_BRANCH_TYPE to get
	branch type of a symbol.
	(print_insn): Likewise.
This commit is contained in:
Thomas Preud'homme 2016-05-10 16:14:23 +01:00
parent 6bde4c52fb
commit 39d911fc3c
12 changed files with 129 additions and 47 deletions

View File

@ -1,3 +1,16 @@
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
* elf32-arm.c (elf32_arm_size_stubs): Use new macros
ARM_GET_SYM_BRANCH_TYPE and ARM_SET_SYM_BRANCH_TYPE to respectively get
and set branch type of a symbol.
(bfd_elf32_arm_process_before_allocation): Likewise.
(elf32_arm_relocate_section): Likewise and fix identation along the
way.
(allocate_dynrelocs_for_symbol): Likewise.
(elf32_arm_finish_dynamic_symbol): Likewise.
(elf32_arm_swap_symbol_in): Likewise.
(elf32_arm_swap_symbol_out): Likewise.
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
* bfd-in.h (elf32_arm_size_stubs): Add an output section parameter.

View File

@ -5465,7 +5465,8 @@ elf32_arm_size_stubs (bfd *output_bfd,
+ sym_sec->output_offset
+ sym_sec->output_section->vma);
st_type = ELF_ST_TYPE (sym->st_info);
branch_type = ARM_SYM_BRANCH_TYPE (sym);
branch_type =
ARM_GET_SYM_BRANCH_TYPE (sym->st_target_internal);
sym_name
= bfd_elf_string_from_elf_section (input_bfd,
symtab_hdr->sh_link,
@ -5540,7 +5541,8 @@ elf32_arm_size_stubs (bfd *output_bfd,
goto error_ret_free_internal;
}
st_type = hash->root.type;
branch_type = hash->root.target_internal;
branch_type =
ARM_GET_SYM_BRANCH_TYPE (hash->root.target_internal);
sym_name = hash->root.root.root.string;
}
@ -6629,7 +6631,8 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
/* This one is a call from arm code. We need to look up
the target of the call. If it is a thumb target, we
insert glue. */
if (h->target_internal == ST_BRANCH_TO_THUMB)
if (ARM_GET_SYM_BRANCH_TYPE (h->target_internal)
== ST_BRANCH_TO_THUMB)
record_arm_to_thumb_glue (link_info, h);
break;
@ -11490,28 +11493,34 @@ elf32_arm_relocate_section (bfd * output_bfd,
and we won't let anybody mess with it. Also, we have to do
addend adjustments in case of a R_ARM_TLS_GOTDESC relocation
both in relaxed and non-relaxed cases. */
if ((elf32_arm_tls_transition (info, r_type, h) != (unsigned)r_type)
|| (IS_ARM_TLS_GNU_RELOC (r_type)
&& !((h ? elf32_arm_hash_entry (h)->tls_type :
elf32_arm_local_got_tls_type (input_bfd)[r_symndx])
& GOT_TLS_GDESC)))
{
r = elf32_arm_tls_relax (globals, input_bfd, input_section,
contents, rel, h == NULL);
/* This may have been marked unresolved because it came from
a shared library. But we've just dealt with that. */
unresolved_reloc = 0;
}
else
r = bfd_reloc_continue;
if ((elf32_arm_tls_transition (info, r_type, h) != (unsigned)r_type)
|| (IS_ARM_TLS_GNU_RELOC (r_type)
&& !((h ? elf32_arm_hash_entry (h)->tls_type :
elf32_arm_local_got_tls_type (input_bfd)[r_symndx])
& GOT_TLS_GDESC)))
{
r = elf32_arm_tls_relax (globals, input_bfd, input_section,
contents, rel, h == NULL);
/* This may have been marked unresolved because it came from
a shared library. But we've just dealt with that. */
unresolved_reloc = 0;
}
else
r = bfd_reloc_continue;
if (r == bfd_reloc_continue)
r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
input_section, contents, rel,
relocation, info, sec, name, sym_type,
(h ? h->target_internal
: ARM_SYM_BRANCH_TYPE (sym)), h,
&unresolved_reloc, &error_message);
if (r == bfd_reloc_continue)
{
unsigned char branch_type =
h ? ARM_GET_SYM_BRANCH_TYPE (h->target_internal)
: ARM_GET_SYM_BRANCH_TYPE (sym->st_target_internal);
r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
input_section, contents, rel,
relocation, info, sec, name,
sym_type, branch_type, h,
&unresolved_reloc,
&error_message);
}
/* Dynamic relocs are not propagated for SEC_DEBUGGING sections
because such sections are not SEC_ALLOC and thus ld.so will
@ -14254,7 +14263,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
/* Make sure the function is not marked as Thumb, in case
it is the target of an ABS32 relocation, which will
point to the PLT entry. */
h->target_internal = ST_BRANCH_TO_ARM;
ARM_SET_SYM_BRANCH_TYPE (h->target_internal, ST_BRANCH_TO_ARM);
}
/* VxWorks executables have a second set of relocations for
@ -14402,7 +14411,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
/* Allocate stubs for exported Thumb functions on v4t. */
if (!htab->use_blx && h->dynindx != -1
&& h->def_regular
&& h->target_internal == ST_BRANCH_TO_THUMB
&& ARM_GET_SYM_BRANCH_TYPE (h->target_internal) == ST_BRANCH_TO_THUMB
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
{
struct elf_link_hash_entry * th;
@ -14422,12 +14431,12 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
myh = (struct elf_link_hash_entry *) bh;
myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
myh->forced_local = 1;
myh->target_internal = ST_BRANCH_TO_THUMB;
ARM_SET_SYM_BRANCH_TYPE (myh->target_internal, ST_BRANCH_TO_THUMB);
eh->export_glue = myh;
th = record_arm_to_thumb_glue (info, h);
/* Point the symbol at the stub. */
h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC);
h->target_internal = ST_BRANCH_TO_ARM;
ARM_SET_SYM_BRANCH_TYPE (h->target_internal, ST_BRANCH_TO_ARM);
h->root.u.def.section = th->root.u.def.section;
h->root.u.def.value = th->root.u.def.value & ~1;
}
@ -15082,7 +15091,7 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd,
/* At least one non-call relocation references this .iplt entry,
so the .iplt entry is the function's canonical address. */
sym->st_info = ELF_ST_INFO (ELF_ST_BIND (sym->st_info), STT_FUNC);
sym->st_target_internal = ST_BRANCH_TO_ARM;
ARM_SET_SYM_BRANCH_TYPE (sym->st_target_internal, ST_BRANCH_TO_ARM);
sym->st_shndx = (_bfd_elf_section_from_bfd_section
(output_bfd, htab->root.iplt->output_section));
sym->st_value = (h->plt.offset
@ -15366,7 +15375,9 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
eh = elf_link_hash_lookup (elf_hash_table (info), name,
FALSE, FALSE, TRUE);
if (eh != NULL && eh->target_internal == ST_BRANCH_TO_THUMB)
if (eh != NULL
&& ARM_GET_SYM_BRANCH_TYPE (eh->target_internal)
== ST_BRANCH_TO_THUMB)
{
dyn.d_un.d_val |= 1;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
@ -17542,6 +17553,7 @@ elf32_arm_swap_symbol_in (bfd * abfd,
{
if (!bfd_elf32_swap_symbol_in (abfd, psrc, pshn, dst))
return FALSE;
dst->st_target_internal = 0;
/* New EABI objects mark thumb function symbols by setting the low bit of
the address. */
@ -17551,20 +17563,21 @@ elf32_arm_swap_symbol_in (bfd * abfd,
if (dst->st_value & 1)
{
dst->st_value &= ~(bfd_vma) 1;
dst->st_target_internal = ST_BRANCH_TO_THUMB;
ARM_SET_SYM_BRANCH_TYPE (dst->st_target_internal,
ST_BRANCH_TO_THUMB);
}
else
dst->st_target_internal = ST_BRANCH_TO_ARM;
ARM_SET_SYM_BRANCH_TYPE (dst->st_target_internal, ST_BRANCH_TO_ARM);
}
else if (ELF_ST_TYPE (dst->st_info) == STT_ARM_TFUNC)
{
dst->st_info = ELF_ST_INFO (ELF_ST_BIND (dst->st_info), STT_FUNC);
dst->st_target_internal = ST_BRANCH_TO_THUMB;
ARM_SET_SYM_BRANCH_TYPE (dst->st_target_internal, ST_BRANCH_TO_THUMB);
}
else if (ELF_ST_TYPE (dst->st_info) == STT_SECTION)
dst->st_target_internal = ST_BRANCH_LONG;
ARM_SET_SYM_BRANCH_TYPE (dst->st_target_internal, ST_BRANCH_LONG);
else
dst->st_target_internal = ST_BRANCH_UNKNOWN;
ARM_SET_SYM_BRANCH_TYPE (dst->st_target_internal, ST_BRANCH_UNKNOWN);
return TRUE;
}
@ -17584,7 +17597,7 @@ elf32_arm_swap_symbol_out (bfd *abfd,
of the address set, as per the new EABI. We do this unconditionally
because objcopy does not set the elf header flags until after
it writes out the symbol table. */
if (src->st_target_internal == ST_BRANCH_TO_THUMB)
if (ARM_GET_SYM_BRANCH_TYPE (src->st_target_internal) == ST_BRANCH_TO_THUMB)
{
newsym = *src;
if (ELF_ST_TYPE (src->st_info) != STT_GNU_IFUNC)

View File

@ -1,3 +1,8 @@
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
* config/tc-arm.c (arm_adjust_symtab): Use ARM_SET_SYM_BRANCH_TYPE to
set branch type of a symbol.
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
* NEWS: Document ARMv8-M and ARMv8-M Security and DSP Extensions.

View File

@ -24694,8 +24694,8 @@ arm_adjust_symtab (void)
/* If it's a .thumb_func, declare it as so,
otherwise tag label as .code 16. */
if (THUMB_IS_FUNC (sym))
elf_sym->internal_elf_sym.st_target_internal
= ST_BRANCH_TO_THUMB;
ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
ST_BRANCH_TO_THUMB);
else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
elf_sym->internal_elf_sym.st_info =
ELF_ST_INFO (bind, STT_ARM_16BIT);

View File

@ -1,3 +1,8 @@
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
* arm-tdep.c (arm_elf_make_msymbol_special): Use
ARM_GET_SYM_BRANCH_TYPE to get branch type of a symbol.
2016-05-07 Trevor Saunders <tbsaunde+binutils@tbsaunde.org>
* aarch64-linux-tdep.c (aarch64_linux_sigframe_init): Remove unused

View File

@ -8538,7 +8538,9 @@ coff_sym_is_thumb (int val)
static void
arm_elf_make_msymbol_special(asymbol *sym, struct minimal_symbol *msym)
{
if (ARM_SYM_BRANCH_TYPE (&((elf_symbol_type *)sym)->internal_elf_sym)
elf_symbol_type *elfsym = (elf_symbol_type *) sym;
if (ARM_GET_SYM_BRANCH_TYPE (elfsym->internal_elf_sym.st_target_internal)
== ST_BRANCH_TO_THUMB)
MSYMBOL_SET_SPECIAL (msym);
}

View File

@ -1,3 +1,15 @@
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
Nick Clifton <nickc@redhat.com>
* arm.h (enum arm_st_branch_type): Add new ST_BRANCH_ENUM_SIZE
enumerator.
(NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS): New macro.
(ENUM_ARM_ST_BRANCH_TYPE_BITMASK): Likewise.
(ARM_SYM_BRANCH_TYPE): Replace by ...
(ARM_GET_SYM_BRANCH_TYPE): This and ...
(ARM_SET_SYM_BRANCH_TYPE): This in two versions depending on whether
BFD_ASSERT is defined or not.
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
* elf/arm.h (Tag_DSP_extension): Define.

View File

@ -359,10 +359,29 @@ enum arm_st_branch_type {
ST_BRANCH_TO_ARM,
ST_BRANCH_TO_THUMB,
ST_BRANCH_LONG,
ST_BRANCH_UNKNOWN
ST_BRANCH_UNKNOWN,
ST_BRANCH_ENUM_SIZE
};
#define ARM_SYM_BRANCH_TYPE(SYM) \
((enum arm_st_branch_type) (SYM)->st_target_internal)
#define NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS 2
#define ENUM_ARM_ST_BRANCH_TYPE_BITMASK \
((1 << NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS) - 1)
#define ARM_GET_SYM_BRANCH_TYPE(STI) \
((enum arm_st_branch_type) ((STI) & ENUM_ARM_ST_BRANCH_TYPE_BITMASK))
#ifdef BFD_ASSERT
#define ARM_SET_SYM_BRANCH_TYPE(STI, TYPE) \
do { \
BFD_ASSERT (TYPE <= ST_BRANCH_ENUM_SIZE); \
BFD_ASSERT ((1 << NUM_ENUM_ARM_ST_BRANCH_TYPE_BITS) \
>= ST_BRANCH_ENUM_SIZE); \
(STI) = (((STI) & ~ENUM_ARM_ST_BRANCH_TYPE_BITMASK) \
| ((TYPE) & ENUM_ARM_ST_BRANCH_TYPE_BITMASK)); \
} while (0)
#else
#define ARM_SET_SYM_BRANCH_TYPE(STI, TYPE) \
(STI) = (((STI) & ~ENUM_ARM_ST_BRANCH_TYPE_BITMASK) \
| ((TYPE) & ENUM_ARM_ST_BRANCH_TYPE_BITMASK))
#endif
#endif /* _ELF_ARM_H */

View File

@ -1,3 +1,8 @@
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
* emultempl/armelf.em (gld${EMULATION_NAME}_finish): Use
ARM_GET_SYM_BRANCH_TYPE to get branch type of a symbol.
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
* emultempl/armelf.em (elf32_arm_add_stub_section): Add output_section

View File

@ -447,7 +447,8 @@ gld${EMULATION_NAME}_finish (void)
h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name,
FALSE, FALSE, TRUE);
eh = (struct elf_link_hash_entry *)h;
if (!h || eh->target_internal != ST_BRANCH_TO_THUMB)
if (!h || ARM_GET_SYM_BRANCH_TYPE (eh->target_internal)
!= ST_BRANCH_TO_THUMB)
return;
}

View File

@ -1,3 +1,9 @@
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
* arm-dis.c (get_sym_code_type): Use ARM_GET_SYM_BRANCH_TYPE to get
branch type of a symbol.
(print_insn): Likewise.
2016-05-10 Thomas Preud'homme <thomas.preudhomme@arm.com>
* arm-dis.c (coprocessor_opcodes): Add entries for VFP ARMv8-M

View File

@ -6288,7 +6288,8 @@ get_sym_code_type (struct disassemble_info *info,
/* If the symbol has function type then use that. */
if (type == STT_FUNC || type == STT_GNU_IFUNC)
{
if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
if (ARM_GET_SYM_BRANCH_TYPE (es->internal_elf_sym.st_target_internal)
== ST_BRANCH_TO_THUMB)
*map_type = MAP_THUMB;
else
*map_type = MAP_ARM;
@ -6655,9 +6656,9 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
es = *(elf_symbol_type **)(info->symbols);
type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
== ST_BRANCH_TO_THUMB)
|| type == STT_ARM_16BIT);
is_thumb =
((ARM_GET_SYM_BRANCH_TYPE (es->internal_elf_sym.st_target_internal)
== ST_BRANCH_TO_THUMB) || type == STT_ARM_16BIT);
}
else if (bfd_asymbol_flavour (*info->symbols)
== bfd_target_mach_o_flavour)