aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog13
-rw-r--r--bfd/elf32-arm.c85
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/config/tc-arm.c4
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/arm-tdep.c4
-rw-r--r--include/ChangeLog12
-rw-r--r--include/elf/arm.h25
-rw-r--r--ld/ChangeLog5
-rw-r--r--ld/emultempl/armelf.em3
-rw-r--r--opcodes/ChangeLog6
-rw-r--r--opcodes/arm-dis.c9
12 files changed, 129 insertions, 47 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 5acc4d0b5a7..73fb2ad40a8 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,18 @@
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.
* bfd-in2.h: Regenerated.
* elf32-arm.c (struct elf32_arm_link_hash_table): Add an output section
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index e1ee67315f8..76ad7e003c5 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -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)
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 73fa0831129..0012cd7b73d 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,10 @@
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.
* config/tc-arm.c (arm_ext_dsp): New feature for Thumb DSP
instructions.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index e8619b67052..b5f378661e5 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -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);
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 35119af4bdc..519c6d1d7c4 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index c7d84be5d87..157f8a12fb9 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -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);
}
diff --git a/include/ChangeLog b/include/ChangeLog
index 63d68c39ecf..3d178491761 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,4 +1,16 @@
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.
diff --git a/include/elf/arm.h b/include/elf/arm.h
index bd9fd8bcf54..bafc03c52ee 100644
--- a/include/elf/arm.h
+++ b/include/elf/arm.h
@@ -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 */
diff --git a/ld/ChangeLog b/ld/ChangeLog
index e7a43168557..9e0e7fbb6e4 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,10 @@
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
parameter and rename input_section parameter to after_input_section.
Append input stub section to the output section if after_input_section
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index bfb7ee498a8..caa2fbfff36 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -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;
}
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 2e2aaf5cb21..2472fd51758 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,11 @@
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
Mainline Security Extensions instructions.
(thumb_opcodes): Add entries for narrow ARMv8-M Security
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 3d69c7d89b7..688981598cb 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -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)