Use gdb_bfd_sections in dwarf2/read.c
[deliverable/binutils-gdb.git] / gdb / amd64-tdep.c
index d4c96de571648258365819fe8b780179f590e77d..e801f83ddbc7d3b787aec621db8c28079c9a4846 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for AMD64.
 
-   Copyright (C) 2001-2019 Free Software Foundation, Inc.
+   Copyright (C) 2001-2020 Free Software Foundation, Inc.
 
    Contributed by Jiri Smid, SuSE Labs.
 
 #include "disasm.h"
 #include "amd64-tdep.h"
 #include "i387-tdep.h"
-#include "common/x86-xstate.h"
+#include "gdbsupport/x86-xstate.h"
 #include <algorithm>
 #include "target-descriptions.h"
 #include "arch/amd64.h"
 #include "producer.h"
 #include "ax.h"
 #include "ax-gdb.h"
-#include "common/byte-vector.h"
+#include "gdbsupport/byte-vector.h"
 #include "osabi.h"
 #include "x86-tdep.h"
 
@@ -59,7 +59,7 @@
 
 /* Register information.  */
 
-static const char *amd64_register_names[] = 
+static const char * const amd64_register_names[] = 
 {
   "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "rsp",
 
@@ -77,7 +77,7 @@ static const char *amd64_register_names[] =
   "mxcsr",
 };
 
-static const char *amd64_ymm_names[] = 
+static const char * const amd64_ymm_names[] = 
 {
   "ymm0", "ymm1", "ymm2", "ymm3",
   "ymm4", "ymm5", "ymm6", "ymm7",
@@ -85,7 +85,7 @@ static const char *amd64_ymm_names[] =
   "ymm12", "ymm13", "ymm14", "ymm15"
 };
 
-static const char *amd64_ymm_avx512_names[] =
+static const char * const amd64_ymm_avx512_names[] =
 {
   "ymm16", "ymm17", "ymm18", "ymm19",
   "ymm20", "ymm21", "ymm22", "ymm23",
@@ -93,7 +93,7 @@ static const char *amd64_ymm_avx512_names[] =
   "ymm28", "ymm29", "ymm30", "ymm31"
 };
 
-static const char *amd64_ymmh_names[] = 
+static const char * const amd64_ymmh_names[] = 
 {
   "ymm0h", "ymm1h", "ymm2h", "ymm3h",
   "ymm4h", "ymm5h", "ymm6h", "ymm7h",
@@ -101,7 +101,7 @@ static const char *amd64_ymmh_names[] =
   "ymm12h", "ymm13h", "ymm14h", "ymm15h"
 };
 
-static const char *amd64_ymmh_avx512_names[] =
+static const char * const amd64_ymmh_avx512_names[] =
 {
   "ymm16h", "ymm17h", "ymm18h", "ymm19h",
   "ymm20h", "ymm21h", "ymm22h", "ymm23h",
@@ -109,18 +109,18 @@ static const char *amd64_ymmh_avx512_names[] =
   "ymm28h", "ymm29h", "ymm30h", "ymm31h"
 };
 
-static const char *amd64_mpx_names[] =
+static const char * const amd64_mpx_names[] =
 {
   "bnd0raw", "bnd1raw", "bnd2raw", "bnd3raw", "bndcfgu", "bndstatus"
 };
 
-static const char *amd64_k_names[] =
+static const char * const amd64_k_names[] =
 {
   "k0", "k1", "k2", "k3",
   "k4", "k5", "k6", "k7"
 };
 
-static const char *amd64_zmmh_names[] =
+static const char * const amd64_zmmh_names[] =
 {
   "zmm0h", "zmm1h", "zmm2h", "zmm3h",
   "zmm4h", "zmm5h", "zmm6h", "zmm7h",
@@ -132,7 +132,7 @@ static const char *amd64_zmmh_names[] =
   "zmm28h", "zmm29h", "zmm30h", "zmm31h"
 };
 
-static const char *amd64_zmm_names[] =
+static const char * const amd64_zmm_names[] =
 {
   "zmm0", "zmm1", "zmm2", "zmm3",
   "zmm4", "zmm5", "zmm6", "zmm7",
@@ -144,14 +144,14 @@ static const char *amd64_zmm_names[] =
   "zmm28", "zmm29", "zmm30", "zmm31"
 };
 
-static const char *amd64_xmm_avx512_names[] = {
+static const char * const amd64_xmm_avx512_names[] = {
     "xmm16",  "xmm17",  "xmm18",  "xmm19",
     "xmm20",  "xmm21",  "xmm22",  "xmm23",
     "xmm24",  "xmm25",  "xmm26",  "xmm27",
     "xmm28",  "xmm29",  "xmm30",  "xmm31"
 };
 
-static const char *amd64_pkeys_names[] = {
+static const char * const amd64_pkeys_names[] = {
     "pkru"
 };
 
@@ -298,7 +298,7 @@ amd64_arch_reg_to_regnum (int reg)
 
 /* Register names for byte pseudo-registers.  */
 
-static const char *amd64_byte_names[] =
+static const char * const amd64_byte_names[] =
 {
   "al", "bl", "cl", "dl", "sil", "dil", "bpl", "spl",
   "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l",
@@ -310,7 +310,7 @@ static const char *amd64_byte_names[] =
 
 /* Register names for word pseudo-registers.  */
 
-static const char *amd64_word_names[] =
+static const char * const amd64_word_names[] =
 {
   "ax", "bx", "cx", "dx", "si", "di", "bp", "", 
   "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
@@ -318,7 +318,7 @@ static const char *amd64_word_names[] =
 
 /* Register names for dword pseudo-registers.  */
 
-static const char *amd64_dword_names[] =
+static const char * const amd64_dword_names[] =
 {
   "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp", 
   "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d",
@@ -546,20 +546,22 @@ static void amd64_classify (struct type *type, enum amd64_reg_class theclass[2])
 static bool
 amd64_has_unaligned_fields (struct type *type)
 {
-  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
-      || TYPE_CODE (type) == TYPE_CODE_UNION)
+  if (type->code () == TYPE_CODE_STRUCT
+      || type->code () == TYPE_CODE_UNION)
     {
-      for (int i = 0; i < TYPE_NFIELDS (type); i++)
+      for (int i = 0; i < type->num_fields (); i++)
        {
-         struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
+         struct type *subtype = check_typedef (type->field (i).type ());
          int bitpos = TYPE_FIELD_BITPOS (type, i);
          int align = type_align(subtype);
 
-         /* Ignore static fields, or empty fields, for example nested
-            empty structures.  */
-         if (field_is_static (&TYPE_FIELD (type, i))
+         /* Ignore static fields, empty fields (for example nested
+            empty structures), and bitfields (these are handled by
+            the caller).  */
+         if (field_is_static (&type->field (i))
              || (TYPE_FIELD_BITSIZE (type, i) == 0
-                 && TYPE_LENGTH (subtype) == 0))
+                 && TYPE_LENGTH (subtype) == 0)
+             || TYPE_FIELD_PACKED (type, i))
            continue;
 
          if (bitpos % 8 != 0)
@@ -569,7 +571,7 @@ amd64_has_unaligned_fields (struct type *type)
          if (bytepos % align != 0)
            return true;
 
-         if (amd64_has_unaligned_fields(subtype))
+         if (amd64_has_unaligned_fields (subtype))
            return true;
        }
     }
@@ -577,6 +579,72 @@ amd64_has_unaligned_fields (struct type *type)
   return false;
 }
 
+/* Classify field I of TYPE starting at BITOFFSET according to the rules for
+   structures and union types, and store the result in THECLASS.  */
+
+static void
+amd64_classify_aggregate_field (struct type *type, int i,
+                               enum amd64_reg_class theclass[2],
+                               unsigned int bitoffset)
+{
+  struct type *subtype = check_typedef (type->field (i).type ());
+  int bitpos = bitoffset + TYPE_FIELD_BITPOS (type, i);
+  int pos = bitpos / 64;
+  enum amd64_reg_class subclass[2];
+  int bitsize = TYPE_FIELD_BITSIZE (type, i);
+  int endpos;
+
+  if (bitsize == 0)
+    bitsize = TYPE_LENGTH (subtype) * 8;
+  endpos = (bitpos + bitsize - 1) / 64;
+
+  /* Ignore static fields, or empty fields, for example nested
+     empty structures.*/
+  if (field_is_static (&type->field (i)) || bitsize == 0)
+    return;
+
+  if (subtype->code () == TYPE_CODE_STRUCT
+      || subtype->code () == TYPE_CODE_UNION)
+    {
+      /* Each field of an object is classified recursively.  */
+      int j;
+      for (j = 0; j < subtype->num_fields (); j++)
+       amd64_classify_aggregate_field (subtype, j, theclass, bitpos);
+      return;
+    }
+
+  gdb_assert (pos == 0 || pos == 1);
+
+  amd64_classify (subtype, subclass);
+  theclass[pos] = amd64_merge_classes (theclass[pos], subclass[0]);
+  if (bitsize <= 64 && pos == 0 && endpos == 1)
+    /* This is a bit of an odd case:  We have a field that would
+       normally fit in one of the two eightbytes, except that
+       it is placed in a way that this field straddles them.
+       This has been seen with a structure containing an array.
+
+       The ABI is a bit unclear in this case, but we assume that
+       this field's class (stored in subclass[0]) must also be merged
+       into class[1].  In other words, our field has a piece stored
+       in the second eight-byte, and thus its class applies to
+       the second eight-byte as well.
+
+       In the case where the field length exceeds 8 bytes,
+       it should not be necessary to merge the field class
+       into class[1].  As LEN > 8, subclass[1] is necessarily
+       different from AMD64_NO_CLASS.  If subclass[1] is equal
+       to subclass[0], then the normal class[1]/subclass[1]
+       merging will take care of everything.  For subclass[1]
+       to be different from subclass[0], I can only see the case
+       where we have a SSE/SSEUP or X87/X87UP pair, which both
+       use up all 16 bytes of the aggregate, and are already
+       handled just fine (because each portion sits on its own
+       8-byte).  */
+    theclass[1] = amd64_merge_classes (theclass[1], subclass[0]);
+  if (pos == 0)
+    theclass[1] = amd64_merge_classes (theclass[1], subclass[1]);
+}
+
 /* Classify TYPE according to the rules for aggregate (structures and
    arrays) and union types, and store the result in CLASS.  */
 
@@ -599,7 +667,7 @@ amd64_classify_aggregate (struct type *type, enum amd64_reg_class theclass[2])
         calculated according to the classes of the fields in the
         eightbyte: */
 
-  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+  if (type->code () == TYPE_CODE_ARRAY)
     {
       struct type *subtype = check_typedef (TYPE_TARGET_TYPE (type));
 
@@ -613,57 +681,11 @@ amd64_classify_aggregate (struct type *type, enum amd64_reg_class theclass[2])
       int i;
 
       /* Structure or union.  */
-      gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
-                 || TYPE_CODE (type) == TYPE_CODE_UNION);
+      gdb_assert (type->code () == TYPE_CODE_STRUCT
+                 || type->code () == TYPE_CODE_UNION);
 
-      for (i = 0; i < TYPE_NFIELDS (type); i++)
-       {
-         struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
-         int pos = TYPE_FIELD_BITPOS (type, i) / 64;
-         enum amd64_reg_class subclass[2];
-         int bitsize = TYPE_FIELD_BITSIZE (type, i);
-         int endpos;
-
-         if (bitsize == 0)
-           bitsize = TYPE_LENGTH (subtype) * 8;
-         endpos = (TYPE_FIELD_BITPOS (type, i) + bitsize - 1) / 64;
-
-         /* Ignore static fields, or empty fields, for example nested
-            empty structures.*/
-         if (field_is_static (&TYPE_FIELD (type, i)) || bitsize == 0)
-           continue;
-
-         gdb_assert (pos == 0 || pos == 1);
-
-         amd64_classify (subtype, subclass);
-         theclass[pos] = amd64_merge_classes (theclass[pos], subclass[0]);
-         if (bitsize <= 64 && pos == 0 && endpos == 1)
-           /* This is a bit of an odd case:  We have a field that would
-              normally fit in one of the two eightbytes, except that
-              it is placed in a way that this field straddles them.
-              This has been seen with a structure containing an array.
-
-              The ABI is a bit unclear in this case, but we assume that
-              this field's class (stored in subclass[0]) must also be merged
-              into class[1].  In other words, our field has a piece stored
-              in the second eight-byte, and thus its class applies to
-              the second eight-byte as well.
-
-              In the case where the field length exceeds 8 bytes,
-              it should not be necessary to merge the field class
-              into class[1].  As LEN > 8, subclass[1] is necessarily
-              different from AMD64_NO_CLASS.  If subclass[1] is equal
-              to subclass[0], then the normal class[1]/subclass[1]
-              merging will take care of everything.  For subclass[1]
-              to be different from subclass[0], I can only see the case
-              where we have a SSE/SSEUP or X87/X87UP pair, which both
-              use up all 16 bytes of the aggregate, and are already
-              handled just fine (because each portion sits on its own
-              8-byte).  */
-           theclass[1] = amd64_merge_classes (theclass[1], subclass[0]);
-         if (pos == 0)
-           theclass[1] = amd64_merge_classes (theclass[1], subclass[1]);
-       }
+      for (i = 0; i < type->num_fields (); i++)
+       amd64_classify_aggregate_field (type, i, theclass, 0);
     }
 
   /* 4. Then a post merger cleanup is done:  */
@@ -686,7 +708,7 @@ amd64_classify_aggregate (struct type *type, enum amd64_reg_class theclass[2])
 static void
 amd64_classify (struct type *type, enum amd64_reg_class theclass[2])
 {
-  enum type_code code = TYPE_CODE (type);
+  enum type_code code = type->code ();
   int len = TYPE_LENGTH (type);
 
   theclass[0] = theclass[1] = AMD64_NO_CLASS;
@@ -976,6 +998,9 @@ if (return_method == return_method_struct)
                  offset = 8;
                  break;
 
+               case AMD64_NO_CLASS:
+                 continue;
+
                default:
                  gdb_assert (!"Unexpected register class.");
                }
@@ -1440,7 +1465,7 @@ fixup_displaced_copy (struct gdbarch *gdbarch,
     }
 }
 
-struct displaced_step_closure *
+displaced_step_closure_up
 amd64_displaced_step_copy_insn (struct gdbarch *gdbarch,
                                CORE_ADDR from, CORE_ADDR to,
                                struct regcache *regs)
@@ -1449,8 +1474,8 @@ amd64_displaced_step_copy_insn (struct gdbarch *gdbarch,
   /* Extra space for sentinels so fixup_{riprel,displaced_copy} don't have to
      continually watch for running off the end of the buffer.  */
   int fixup_sentinel_space = len;
-  amd64_displaced_step_closure *dsc
-    = new amd64_displaced_step_closure (len + fixup_sentinel_space);
+  std::unique_ptr<amd64_displaced_step_closure> dsc
+    (new amd64_displaced_step_closure (len + fixup_sentinel_space));
   gdb_byte *buf = &dsc->insn_buf[0];
   struct amd64_insn *details = &dsc->insn_details;
 
@@ -1475,7 +1500,7 @@ amd64_displaced_step_copy_insn (struct gdbarch *gdbarch,
 
   /* Modify the insn to cope with the address where it will be executed from.
      In particular, handle any rip-relative addressing.         */
-  fixup_displaced_copy (gdbarch, dsc, from, to, regs);
+  fixup_displaced_copy (gdbarch, dsc.get (), from, to, regs);
 
   write_memory (to, buf, len);
 
@@ -1486,7 +1511,8 @@ amd64_displaced_step_copy_insn (struct gdbarch *gdbarch,
       displaced_step_dump_bytes (gdb_stdlog, buf, len);
     }
 
-  return dsc;
+  /* This is a work around for a problem with g++ 4.8.  */
+  return displaced_step_closure_up (dsc.release ());
 }
 
 static int
@@ -2336,6 +2362,9 @@ amd64_x32_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
       pushq %rbp        0x55
       movl %esp, %ebp   0x89 0xe5 (or 0x8b 0xec)
 
+   The `endbr64` instruction can be found before these sequences, and will be
+   skipped if found.
+
    Any function that doesn't start with one of these sequences will be
    assumed to have no prologue and thus no valid frame pointer in
    %rbp.  */
@@ -2346,6 +2375,8 @@ amd64_analyze_prologue (struct gdbarch *gdbarch,
                        struct amd64_frame_cache *cache)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  /* The `endbr64` instruction.  */
+  static const gdb_byte endbr64[4] = { 0xf3, 0x0f, 0x1e, 0xfa };
   /* There are two variations of movq %rsp, %rbp.  */
   static const gdb_byte mov_rsp_rbp_1[3] = { 0x48, 0x89, 0xe5 };
   static const gdb_byte mov_rsp_rbp_2[3] = { 0x48, 0x8b, 0xec };
@@ -2366,6 +2397,20 @@ amd64_analyze_prologue (struct gdbarch *gdbarch,
 
   op = read_code_unsigned_integer (pc, 1, byte_order);
 
+  /* Check for the `endbr64` instruction, skip it if found.  */
+  if (op == endbr64[0])
+    {
+      read_code (pc + 1, buf, 3);
+
+      if (memcmp (buf, &endbr64[1], 3) == 0)
+       pc += 4;
+
+      op = read_code_unsigned_integer (pc, 1, byte_order);
+    }
+
+  if (current_pc <= pc)
+    return current_pc;
+
   if (op == 0x55)              /* pushq %rbp */
     {
       /* Take into account that we've executed the `pushq %rbp' that
@@ -2388,7 +2433,7 @@ amd64_analyze_prologue (struct gdbarch *gdbarch,
          return pc + 4;
        }
 
-      /* For X32, also check for `movq %esp, %ebp'.  */
+      /* For X32, also check for `movl %esp, %ebp'.  */
       if (gdbarch_ptr_bit (gdbarch) == 32)
        {
          if (memcmp (buf, mov_esp_ebp_1, 2) == 0
@@ -2502,12 +2547,13 @@ amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
        = skip_prologue_using_sal (gdbarch, func_addr);
       struct compunit_symtab *cust = find_pc_compunit_symtab (func_addr);
 
-      /* Clang always emits a line note before the prologue and another
-        one after.  We trust clang to emit usable line notes.  */
+      /* LLVM backend (Clang/Flang) always emits a line note before the
+         prologue and another one after.  We trust clang to emit usable
+         line notes.  */
       if (post_prologue_pc
          && (cust != NULL
              && COMPUNIT_PRODUCER (cust) != NULL
-             && startswith (COMPUNIT_PRODUCER (cust), "clang ")))
+             && producer_is_llvm (COMPUNIT_PRODUCER (cust))))
         return std::max (start_pc, post_prologue_pc);
     }
 
@@ -3309,36 +3355,14 @@ amd64_target_description (uint64_t xcr0, bool segments)
   return *tdesc;
 }
 
+void _initialize_amd64_tdep ();
 void
-_initialize_amd64_tdep (void)
+_initialize_amd64_tdep ()
 {
   gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_NONE,
                          amd64_none_init_abi);
   gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x64_32, GDB_OSABI_NONE,
                          amd64_x32_none_init_abi);
-
-#if GDB_SELF_TEST
-  struct
-  {
-    const char *xml;
-    uint64_t mask;
-  } xml_masks[] = {
-    { "i386/amd64.xml", X86_XSTATE_SSE_MASK },
-    { "i386/amd64-avx.xml", X86_XSTATE_AVX_MASK },
-    { "i386/amd64-mpx.xml", X86_XSTATE_MPX_MASK },
-    { "i386/amd64-avx-mpx.xml", X86_XSTATE_AVX_MPX_MASK },
-    { "i386/amd64-avx-avx512.xml", X86_XSTATE_AVX_AVX512_MASK },
-    { "i386/amd64-avx-mpx-avx512-pku.xml",
-      X86_XSTATE_AVX_MPX_AVX512_PKU_MASK },
-  };
-
-  for (auto &a : xml_masks)
-    {
-      auto tdesc = amd64_target_description (a.mask, true);
-
-      selftests::record_xml_tdesc (a.xml, tdesc);
-    }
-#endif /* GDB_SELF_TEST */
 }
 \f
 
This page took 0.029791 seconds and 4 git commands to generate.