Use malloc/free in the dbgapi callbacks
[deliverable/binutils-gdb.git] / gdb / amd64-tdep.c
index 5b8a94002d576d2351de9ab91105f4648cabc62f..157a5d0c334847e7f9fe96742e492fc136ffd5e5 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"
 
@@ -541,17 +541,108 @@ amd64_merge_classes (enum amd64_reg_class class1, enum amd64_reg_class class2)
 
 static void amd64_classify (struct type *type, enum amd64_reg_class theclass[2]);
 
-/* Return non-zero if TYPE is a non-POD structure or union type.  */
+/* Return true if TYPE is a structure or union with unaligned fields.  */
 
-static int
-amd64_non_pod_p (struct type *type)
+static bool
+amd64_has_unaligned_fields (struct type *type)
 {
-  /* ??? A class with a base class certainly isn't POD, but does this
-     catch all non-POD structure types?  */
-  if (TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_N_BASECLASSES (type) > 0)
-    return 1;
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+      || TYPE_CODE (type) == TYPE_CODE_UNION)
+    {
+      for (int i = 0; i < TYPE_NFIELDS (type); i++)
+       {
+         struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
+         int bitpos = TYPE_FIELD_BITPOS (type, i);
+         int align = type_align(subtype);
+
+         /* Ignore static fields, empty fields (for example nested
+            empty structures), and bitfields (these are handled by
+            the caller).  */
+         if (field_is_static (&TYPE_FIELD (type, i))
+             || (TYPE_FIELD_BITSIZE (type, i) == 0
+                 && TYPE_LENGTH (subtype) == 0)
+             || TYPE_FIELD_PACKED (type, i))
+           continue;
 
-  return 0;
+         if (bitpos % 8 != 0)
+           return true;
+
+         int bytepos = bitpos / 8;
+         if (bytepos % align != 0)
+           return true;
+
+         if (amd64_has_unaligned_fields (subtype))
+           return true;
+       }
+    }
+
+  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_TYPE (type, i));
+  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 (type, i)) || bitsize == 0)
+    return;
+
+  if (TYPE_CODE (subtype) == TYPE_CODE_STRUCT
+      || TYPE_CODE (subtype) == TYPE_CODE_UNION)
+    {
+      /* Each field of an object is classified recursively.  */
+      int j;
+      for (j = 0; j < TYPE_NFIELDS (subtype); 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
@@ -560,10 +651,9 @@ amd64_non_pod_p (struct type *type)
 static void
 amd64_classify_aggregate (struct type *type, enum amd64_reg_class theclass[2])
 {
-  /* 1. If the size of an object is larger than two eightbytes, or in
-        C++, is a non-POD structure or union type, or contains
+  /* 1. If the size of an object is larger than two eightbytes, or it has
         unaligned fields, it has class memory.  */
-  if (TYPE_LENGTH (type) > 16 || amd64_non_pod_p (type))
+  if (TYPE_LENGTH (type) > 16 || amd64_has_unaligned_fields (type))
     {
       theclass[0] = theclass[1] = AMD64_MEMORY;
       return;
@@ -595,53 +685,7 @@ amd64_classify_aggregate (struct type *type, enum amd64_reg_class theclass[2])
                  || TYPE_CODE (type) == 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]);
-       }
+       amd64_classify_aggregate_field (type, i, theclass, 0);
     }
 
   /* 4. Then a post merger cleanup is done:  */
@@ -954,6 +998,9 @@ if (return_method == return_method_struct)
                  offset = 8;
                  break;
 
+               case AMD64_NO_CLASS:
+                 continue;
+
                default:
                  gdb_assert (!"Unexpected register class.");
                }
@@ -2588,7 +2635,7 @@ amd64_frame_cache (struct frame_info *this_frame, void **this_cache)
   catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
     }
 
   return cache;
@@ -2715,7 +2762,7 @@ amd64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
   catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
     }
 
   *this_cache = cache;
@@ -2895,7 +2942,7 @@ amd64_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
   catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
     }
 
   return cache;
@@ -3294,29 +3341,6 @@ _initialize_amd64_tdep (void)
                          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.029566 seconds and 4 git commands to generate.