/* 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.
#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 };
/* 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>";
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;
-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) */
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)
{
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
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
/* 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)
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);
free (copy);
}
}
+
update_xmltarget ();
}
*size_p = 4;
}
-struct emit_ops amd64_emit_ops =
+static emit_ops amd64_emit_ops =
{
amd64_emit_prologue,
amd64_emit_epilogue,
*size_p = 4;
}
-struct emit_ops i386_emit_ops =
+static emit_ops i386_emit_ops =
{
i386_emit_prologue,
i386_emit_epilogue,
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);
/* 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;