gdb: resume ongoing step after handling fork or vfork
[deliverable/binutils-gdb.git] / gdbserver / linux-x86-low.cc
index f6a399e0982379ae41ead2b62bac06b42b01642b..3efbca160f6059c3ab084f59dce4b7f1b9e70f7b 100644 (file)
@@ -1,6 +1,6 @@
 /* GNU/Linux/x86-64 specific low level interface, for the remote server
    for GDB.
-   Copyright (C) 2002-2020 Free Software Foundation, Inc.
+   Copyright (C) 2002-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -48,9 +48,9 @@
 #include "linux-x86-tdesc.h"
 
 #ifdef __x86_64__
-static struct target_desc *tdesc_amd64_linux_no_xml;
+static target_desc_up tdesc_amd64_linux_no_xml;
 #endif
-static struct target_desc *tdesc_i386_linux_no_xml;
+static target_desc_up tdesc_i386_linux_no_xml;
 
 
 static unsigned char jump_insn[] = { 0xe9, 0, 0, 0, 0 };
@@ -58,13 +58,13 @@ static unsigned char small_jump_insn[] = { 0x66, 0xe9, 0, 0 };
 
 /* Backward compatibility for gdb without XML support.  */
 
-static const char *xmltarget_i386_linux_no_xml = "@<target>\
+static const char xmltarget_i386_linux_no_xml[] = "@<target>\
 <architecture>i386</architecture>\
 <osabi>GNU/Linux</osabi>\
 </target>";
 
 #ifdef __x86_64__
-static const char *xmltarget_amd64_linux_no_xml = "@<target>\
+static const char xmltarget_amd64_linux_no_xml[] = "@<target>\
 <architecture>i386:x86-64</architecture>\
 <osabi>GNU/Linux</osabi>\
 </target>";
@@ -106,7 +106,7 @@ public:
 
   bool supports_z_point_type (char z_type) override;
 
-  void process_qsupported (char **features, int count) override;
+  void process_qsupported (gdb::array_view<const char * const> features) override;
 
   bool supports_tracepoints () override;
 
@@ -233,11 +233,7 @@ static const int x86_64_regmap[] =
   -1,
   -1, -1, -1, -1, -1, -1, -1, -1,
   ORIG_RAX * 8,
-#ifdef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
   21 * 8,  22 * 8,
-#else
-  -1, -1,
-#endif
   -1, -1, -1, -1,                      /* MPX registers BND0 ... BND3.  */
   -1, -1,                              /* MPX registers BNDCFGU, BNDSTATUS.  */
   -1, -1, -1, -1, -1, -1, -1, -1,       /* xmm16 ... xmm31 (AVX512)  */
@@ -401,6 +397,35 @@ x86_target::low_cannot_fetch_register (int regno)
   return regno >= I386_NUM_REGS;
 }
 
+static void
+collect_register_i386 (struct regcache *regcache, int regno, void *buf)
+{
+  collect_register (regcache, regno, buf);
+
+#ifdef __x86_64__
+  /* In case of x86_64 -m32, collect_register only writes 4 bytes, but the
+     space reserved in buf for the register is 8 bytes.  Make sure the entire
+     reserved space is initialized.  */
+
+  gdb_assert (register_size (regcache->tdesc, regno) == 4);
+
+  if (regno == RAX)
+    {
+      /* Sign extend EAX value to avoid potential syscall restart
+        problems.
+
+        See amd64_linux_collect_native_gregset() in
+        gdb/amd64-linux-nat.c for a detailed explanation.  */
+      *(int64_t *) buf = *(int32_t *) buf;
+    }
+  else
+    {
+      /* Zero-extend.  */
+      *(uint64_t *) buf = *(uint32_t *) buf;
+    }
+#endif
+}
+
 static void
 x86_fill_gregset (struct regcache *regcache, void *buf)
 {
@@ -413,47 +438,16 @@ x86_fill_gregset (struct regcache *regcache, void *buf)
        if (x86_64_regmap[i] != -1)
          collect_register (regcache, i, ((char *) buf) + x86_64_regmap[i]);
 
-#ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
-      {
-        unsigned long base;
-        int lwpid = lwpid_of (current_thread);
-
-        collect_register_by_name (regcache, "fs_base", &base);
-        ptrace (PTRACE_ARCH_PRCTL, lwpid, &base, ARCH_SET_FS);
-
-        collect_register_by_name (regcache, "gs_base", &base);
-        ptrace (PTRACE_ARCH_PRCTL, lwpid, &base, ARCH_SET_GS);
-      }
-#endif
-
       return;
     }
-
-  /* 32-bit inferior registers need to be zero-extended.
-     Callers would read uninitialized memory otherwise.  */
-  memset (buf, 0x00, X86_64_USER_REGS * 8);
 #endif
 
   for (i = 0; i < I386_NUM_REGS; i++)
-    collect_register (regcache, i, ((char *) buf) + i386_regmap[i]);
-
-  collect_register_by_name (regcache, "orig_eax",
-                           ((char *) buf) + ORIG_EAX * REGSIZE);
-
-#ifdef __x86_64__
-  /* Sign extend EAX value to avoid potential syscall restart
-     problems. 
-
-     See amd64_linux_collect_native_gregset() in gdb/amd64-linux-nat.c
-     for a detailed explanation.  */
-  if (register_size (regcache->tdesc, 0) == 4)
-    {
-      void *ptr = ((gdb_byte *) buf
-                   + i386_regmap[find_regno (regcache->tdesc, "eax")]);
+    collect_register_i386 (regcache, i, ((char *) buf) + i386_regmap[i]);
 
-      *(int64_t *) ptr = *(int32_t *) ptr;
-    }
-#endif
+  /* Handle ORIG_EAX, which is not in i386_regmap.  */
+  collect_register_i386 (regcache, find_regno (regcache->tdesc, "orig_eax"),
+                        ((char *) buf) + ORIG_EAX * REGSIZE);
 }
 
 static void
@@ -468,18 +462,6 @@ x86_store_gregset (struct regcache *regcache, const void *buf)
        if (x86_64_regmap[i] != -1)
          supply_register (regcache, i, ((char *) buf) + x86_64_regmap[i]);
 
-#ifndef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
-      {
-        unsigned long base;
-        int lwpid = lwpid_of (current_thread);
-
-        if (ptrace (PTRACE_ARCH_PRCTL, lwpid, &base, ARCH_GET_FS) == 0)
-          supply_register_by_name (regcache, "fs_base", &base);
-
-        if (ptrace (PTRACE_ARCH_PRCTL, lwpid, &base, ARCH_GET_GS) == 0)
-          supply_register_by_name (regcache, "gs_base", &base);
-      }
-#endif
       return;
     }
 #endif
@@ -928,10 +910,10 @@ x86_linux_read_description (void)
       /* Don't use XML.  */
 #ifdef __x86_64__
       if (machine == EM_X86_64)
-       return tdesc_amd64_linux_no_xml;
+       return tdesc_amd64_linux_no_xml.get ();
       else
 #endif
-       return tdesc_i386_linux_no_xml;
+       return tdesc_i386_linux_no_xml.get ();
     }
 
   if (have_ptrace_getregset == -1)
@@ -1032,18 +1014,15 @@ x86_target::update_xmltarget ()
    PTRACE_GETREGSET.  */
 
 void
-x86_target::process_qsupported (char **features, int count)
+x86_target::process_qsupported (gdb::array_view<const char * const> features)
 {
-  int i;
-
   /* Return if gdb doesn't support XML.  If gdb sends "xmlRegisters="
      with "i386" in qSupported query, it supports x86 XML target
      descriptions.  */
   use_xml = 0;
-  for (i = 0; i < count; i++)
-    {
-      const char *feature = features[i];
 
+  for (const char *feature : features)
+    {
       if (startswith (feature, "xmlRegisters="))
        {
          char *copy = xstrdup (feature + 13);
@@ -1063,6 +1042,7 @@ x86_target::process_qsupported (char **features, int count)
          free (copy);
        }
     }
+
   update_xmltarget ();
 }
 
@@ -2239,7 +2219,7 @@ amd64_emit_ge_goto (int *offset_p, int *size_p)
     *size_p = 4;
 }
 
-struct emit_ops amd64_emit_ops =
+static emit_ops amd64_emit_ops =
   {
     amd64_emit_prologue,
     amd64_emit_epilogue,
@@ -2908,7 +2888,7 @@ i386_emit_ge_goto (int *offset_p, int *size_p)
     *size_p = 4;
 }
 
-struct emit_ops i386_emit_ops =
+static emit_ops i386_emit_ops =
   {
     i386_emit_prologue,
     i386_emit_epilogue,
@@ -2986,7 +2966,7 @@ x86_target::get_ipa_tdesc_idx ()
   return amd64_get_ipa_tdesc_idx (tdesc);
 #endif
 
-  if (tdesc == tdesc_i386_linux_no_xml)
+  if (tdesc == tdesc_i386_linux_no_xml.get ())
     return X86_TDESC_SSE;
 
   return i386_get_ipa_tdesc_idx (tdesc);
@@ -3002,14 +2982,14 @@ initialize_low_arch (void)
   /* Initialize the Linux target descriptions.  */
 #ifdef __x86_64__
   tdesc_amd64_linux_no_xml = allocate_target_description ();
-  copy_target_description (tdesc_amd64_linux_no_xml,
+  copy_target_description (tdesc_amd64_linux_no_xml.get (),
                           amd64_linux_read_description (X86_XSTATE_SSE_MASK,
                                                         false));
   tdesc_amd64_linux_no_xml->xmltarget = xmltarget_amd64_linux_no_xml;
 #endif
 
   tdesc_i386_linux_no_xml = allocate_target_description ();
-  copy_target_description (tdesc_i386_linux_no_xml,
+  copy_target_description (tdesc_i386_linux_no_xml.get (),
                           i386_linux_read_description (X86_XSTATE_SSE_MASK));
   tdesc_i386_linux_no_xml->xmltarget = xmltarget_i386_linux_no_xml;
 
This page took 0.040919 seconds and 4 git commands to generate.