From fb7466900ad67c9adfe1fb67ebb215cd78829046 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 29 Mar 2016 19:08:02 +0100 Subject: [PATCH] Use getters/setters to access ARM branch type 2016-03-29 Thomas Preud'homme 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/elf/ * arm.h (ARM_SYM_BRANCH_TYPE): Replace by ... (ARM_GET_SYM_BRANCH_TYPE): ... this ... (ARM_SET_SYM_BRANCH_TYPE): ... and this. ld/ (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. --- bfd/ChangeLog.arm | 13 ++++++ bfd/elf32-arm.c | 85 ++++++++++++++++++++++----------------- gas/ChangeLog.arm | 5 +++ gas/config/tc-arm.c | 4 +- gdb/ChangeLog.arm | 4 ++ gdb/arm-tdep.c | 3 +- include/elf/ChangeLog.arm | 6 +++ include/elf/arm.h | 6 ++- ld/ChangeLog.arm | 5 +++ ld/emultempl/armelf.em | 3 +- opcodes/ChangeLog.arm | 6 +++ opcodes/arm-dis.c | 9 +++-- 12 files changed, 103 insertions(+), 46 deletions(-) create mode 100644 gdb/ChangeLog.arm diff --git a/bfd/ChangeLog.arm b/bfd/ChangeLog.arm index d468f1e44ab..5bc7598a398 100644 --- a/bfd/ChangeLog.arm +++ b/bfd/ChangeLog.arm @@ -1,3 +1,16 @@ +2016-03-29 Thomas Preud'homme + + * 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-03-29 Thomas Preud'homme * bfd-in.h (elf32_arm_size_stubs): Add an output section parameter. diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index f1dd54b0d60..2b7c3f5a8da 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -5396,7 +5396,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, @@ -5471,7 +5472,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; } @@ -6564,7 +6566,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; @@ -11395,28 +11398,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 @@ -14139,7 +14148,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 @@ -14287,7 +14296,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; @@ -14307,12 +14316,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; } @@ -14967,7 +14976,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 @@ -15251,7 +15260,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); @@ -17341,6 +17352,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. */ @@ -17350,20 +17362,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; } @@ -17383,7 +17396,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.arm b/gas/ChangeLog.arm index a6b4ea5d75b..3e2f33a3a40 100644 --- a/gas/ChangeLog.arm +++ b/gas/ChangeLog.arm @@ -1,3 +1,8 @@ +2016-03-29 Thomas Preud'homme + + * config/tc-arm.c (arm_adjust_symtab): Use ARM_SET_SYM_BRANCH_TYPE to + set branch type of a symbol. + 2016-03-29 Thomas Preud'homme * config/tc-arm.c (arm_ext_dsp): New feature for Thumb DSP diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 91625e55bca..453e2c531d2 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -24198,8 +24198,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.arm b/gdb/ChangeLog.arm new file mode 100644 index 00000000000..39f5d0e982e --- /dev/null +++ b/gdb/ChangeLog.arm @@ -0,0 +1,4 @@ +2016-03-29 Thomas Preud'homme + + * arm-tdep.c (arm_elf_make_msymbol_special): Use + ARM_GET_SYM_BRANCH_TYPE to get branch type of a symbol. diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 4a8d03b25a1..32ee07cb82e 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -9566,7 +9566,8 @@ 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/elf/ChangeLog.arm b/include/elf/ChangeLog.arm index 73fd4adb647..77205bd9e83 100644 --- a/include/elf/ChangeLog.arm +++ b/include/elf/ChangeLog.arm @@ -1,3 +1,9 @@ +2016-03-29 Thomas Preud'homme + + * arm.h (ARM_SYM_BRANCH_TYPE): Replace by ... + (ARM_GET_SYM_BRANCH_TYPE): ... this ... + (ARM_SET_SYM_BRANCH_TYPE): ... and this. + 2016-03-29 Thomas Preud'homme * arm.h (Tag_DSP_extension): Define. diff --git a/include/elf/arm.h b/include/elf/arm.h index 63c5aacf143..8ec6fa34904 100644 --- a/include/elf/arm.h +++ b/include/elf/arm.h @@ -356,7 +356,9 @@ enum arm_st_branch_type { ST_BRANCH_UNKNOWN }; -#define ARM_SYM_BRANCH_TYPE(SYM) \ - ((enum arm_st_branch_type) (SYM)->st_target_internal) +#define ARM_GET_SYM_BRANCH_TYPE(SYM_TARGET_INTERNAL) \ + ((enum arm_st_branch_type) ((SYM_TARGET_INTERNAL) & 3)) +#define ARM_SET_SYM_BRANCH_TYPE(SYM_TARGET_INTERNAL,TYPE) \ + ((SYM_TARGET_INTERNAL) = ((SYM_TARGET_INTERNAL) & ~3) | ((TYPE) & 3)) #endif /* _ELF_ARM_H */ diff --git a/ld/ChangeLog.arm b/ld/ChangeLog.arm index ec4557e50ab..7c5047d6f39 100644 --- a/ld/ChangeLog.arm +++ b/ld/ChangeLog.arm @@ -1,3 +1,8 @@ +2016-03-29 Thomas Preud'homme + + (gld${EMULATION_NAME}_finish): Use ARM_GET_SYM_BRANCH_TYPE to get + branch type of a symbol. + 2016-03-29 Thomas Preud'homme * emultempl/armelf.em (elf32_arm_add_stub_section): Add output_section diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index b6a02405efc..5efc5126a1b 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -437,7 +437,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.arm b/opcodes/ChangeLog.arm index d7cf97ba483..8ab50679342 100644 --- a/opcodes/ChangeLog.arm +++ b/opcodes/ChangeLog.arm @@ -1,3 +1,9 @@ +2016-03-29 Thomas Preud'homme + + * arm-dis.c (get_sym_code_type): Use ARM_GET_SYM_BRANCH_TYPE to get + branch type of a symbol. + (print_insn): Likewise. + 2016-03-29 Thomas Preud'homme * arm-dis.c (coprocessor_opcodes): Add entries for VFP ARMv8-M diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 3f87bbadcdf..714184696ec 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -6093,7 +6093,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; @@ -6395,9 +6396,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); } } -- 2.47.3