Use getters/setters to access ARM branch type
authorThomas Preud'homme <thomas.preudhomme@arm.com>
Tue, 10 May 2016 15:14:23 +0000 (16:14 +0100)
committerThomas Preud'homme <thomas.preudhomme@arm.com>
Tue, 10 May 2016 15:17:04 +0000 (16:17 +0100)
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.

12 files changed:
bfd/ChangeLog
bfd/elf32-arm.c
gas/ChangeLog
gas/config/tc-arm.c
gdb/ChangeLog
gdb/arm-tdep.c
include/ChangeLog
include/elf/arm.h
ld/ChangeLog
ld/emultempl/armelf.em
opcodes/ChangeLog
opcodes/arm-dis.c

index 5acc4d0b5a7598600f8b99397213e5eb2ce319de..73fb2ad40a85bd48f4d25d696475169930732fe8 100644 (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.
index e1ee67315f84f59ea11d62015e8ffa0e0530ebcf..76ad7e003c5ce63241cbad1d613278617c9d9642 100644 (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)
index 73fa083112935888711fac0bc202b60c879b74e5..0012cd7b73d485a0fd0d970f872066a9334106f8 100644 (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.
index e8619b67052dd3038bf29702d8b99e42e37f2cb9..b5f378661e5b850c1081ef0d1f4fcb8f2584157e 100644 (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);
index 35119af4bdc6a670350fdf7abbf46cf32e8fdd8f..519c6d1d7c49de77c9d1fe51d0c9215e6bf84b31 100644 (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
index c7d84be5d873d2c7d401e9cca2d4e84fe233fe56..157f8a12fb9e02f16a71e4a9fb94e7de7b01fd94 100644 (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);
 }
index 63d68c39ecfe296e33a1abeb60f2552ac479cc0d..3d178491761fdad7df98bcf63953c47bab24e709 100644 (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.
index bd9fd8bcf540933cf99957e1c138b479a83958ca..bafc03c52ee686671e847eff272ab5cc8a79398c 100644 (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 */
index e7a431685577147bdd80b1cf801d2feb85202dd4..9e0e7fbb6e4ac070524568c699d53255fcd354e8 100644 (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
index bfb7ee498a8d4206e89ed127efcc6aa4c5bf836b..caa2fbfff3633f2a7f69a7b197574eed8279d6c4 100644 (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;
     }
 
index 2e2aaf5cb21fcd30cad6448bbb6f5b13534dd818..2472fd51758742b667e5dda57409e9d42a4fa605 100644 (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
index 3d69c7d89b781c0c64f6f885b8dc84d875a7e9e8..688981598cbeda924d5b0cefe2901d2c33d8d31c 100644 (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)