Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(532)

Unified Diff: gdb/gdbserver/linux-x86-low.c

Issue 124383005: GDB 7.6.50 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@upstream
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gdb/gdbserver/linux-tile-low.c ('k') | gdb/gdbserver/linux-xtensa-low.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gdb/gdbserver/linux-x86-low.c
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 4ea284eebafd16fea56c1ea5165dbe203ece2e30..e8505bf0e83b65aad4f4fab7e6ae6d46646a5477 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -1,6 +1,6 @@
/* GNU/Linux/x86-64 specific low level interface, for the remote server
for GDB.
- Copyright (C) 2002, 2004-2012 Free Software Foundation, Inc.
+ Copyright (C) 2002-2013 Free Software Foundation, Inc.
This file is part of GDB.
@@ -30,21 +30,54 @@
#include "gdb_proc_service.h"
#include "agent.h"
+#include "tdesc.h"
+#include "tracepoint.h"
+#include "ax.h"
-/* Defined in auto-generated file i386-linux.c. */
-void init_registers_i386_linux (void);
+#ifdef __x86_64__
/* Defined in auto-generated file amd64-linux.c. */
void init_registers_amd64_linux (void);
-/* Defined in auto-generated file i386-avx-linux.c. */
-void init_registers_i386_avx_linux (void);
+extern const struct target_desc *tdesc_amd64_linux;
+
/* Defined in auto-generated file amd64-avx-linux.c. */
void init_registers_amd64_avx_linux (void);
-/* Defined in auto-generated file i386-mmx-linux.c. */
-void init_registers_i386_mmx_linux (void);
+extern const struct target_desc *tdesc_amd64_avx_linux;
+
+/* Defined in auto-generated file amd64-mpx-linux.c. */
+void init_registers_amd64_mpx_linux (void);
+extern const struct target_desc *tdesc_amd64_mpx_linux;
+
/* Defined in auto-generated file x32-linux.c. */
void init_registers_x32_linux (void);
+extern const struct target_desc *tdesc_x32_linux;
+
/* Defined in auto-generated file x32-avx-linux.c. */
void init_registers_x32_avx_linux (void);
+extern const struct target_desc *tdesc_x32_avx_linux;
+
+#endif
+
+/* Defined in auto-generated file i386-linux.c. */
+void init_registers_i386_linux (void);
+extern const struct target_desc *tdesc_i386_linux;
+
+/* Defined in auto-generated file i386-mmx-linux.c. */
+void init_registers_i386_mmx_linux (void);
+extern const struct target_desc *tdesc_i386_mmx_linux;
+
+/* Defined in auto-generated file i386-avx-linux.c. */
+void init_registers_i386_avx_linux (void);
+extern const struct target_desc *tdesc_i386_avx_linux;
+
+/* Defined in auto-generated file i386-mpx-linux.c. */
+void init_registers_i386_mpx_linux (void);
+extern const struct target_desc *tdesc_i386_mpx_linux;
+
+#ifdef __x86_64__
+static struct target_desc *tdesc_amd64_linux_no_xml;
+#endif
+static struct target_desc *tdesc_i386_linux_no_xml;
+
static unsigned char jump_insn[] = { 0xe9, 0, 0, 0, 0 };
static unsigned char small_jump_insn[] = { 0x66, 0xe9, 0, 0 };
@@ -139,8 +172,11 @@ static const int x86_64_regmap[] =
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1,
- ORIG_RAX * 8
+ -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ ORIG_RAX * 8,
+ -1, -1, -1, -1, /* MPX registers BND0 ... BND3. */
+ -1, -1 /* MPX registers BNDCFGU, BNDSTATUS. */
};
#define X86_64_NUM_REGS (sizeof (x86_64_regmap) / sizeof (x86_64_regmap[0]))
@@ -160,6 +196,22 @@ static /*const*/ int i386_regmap[] =
#define I386_NUM_REGS (sizeof (i386_regmap) / sizeof (i386_regmap[0]))
#endif
+
+#ifdef __x86_64__
+
+/* Returns true if the current inferior belongs to a x86-64 process,
+ per the tdesc. */
+
+static int
+is_64bit_tdesc (void)
+{
+ struct regcache *regcache = get_thread_regcache (current_inferior, 0);
+
+ return register_size (regcache->tdesc, 0) == 8;
+}
+
+#endif
+
/* Called by libthread_db. */
@@ -168,7 +220,7 @@ ps_get_thread_area (const struct ps_prochandle *ph,
lwpid_t lwpid, int idx, void **base)
{
#ifdef __x86_64__
- int use_64bit = register_size (0) == 8;
+ int use_64bit = is_64bit_tdesc ();
if (use_64bit)
{
@@ -196,7 +248,8 @@ ps_get_thread_area (const struct ps_prochandle *ph,
(void *) (intptr_t) idx, (unsigned long) &desc) < 0)
return PS_ERR;
- *(int *)base = desc[1];
+ /* Ensure we properly extend the value to 64-bits for x86_64. */
+ *base = (void *) (uintptr_t) desc[1];
return PS_OK;
}
}
@@ -210,7 +263,7 @@ static int
x86_get_thread_area (int lwpid, CORE_ADDR *addr)
{
#ifdef __x86_64__
- int use_64bit = register_size (0) == 8;
+ int use_64bit = is_64bit_tdesc ();
if (use_64bit)
{
@@ -250,14 +303,24 @@ x86_get_thread_area (int lwpid, CORE_ADDR *addr)
static int
-i386_cannot_store_register (int regno)
+x86_cannot_store_register (int regno)
{
+#ifdef __x86_64__
+ if (is_64bit_tdesc ())
+ return 0;
+#endif
+
return regno >= I386_NUM_REGS;
}
static int
-i386_cannot_fetch_register (int regno)
+x86_cannot_fetch_register (int regno)
{
+#ifdef __x86_64__
+ if (is_64bit_tdesc ())
+ return 0;
+#endif
+
return regno >= I386_NUM_REGS;
}
@@ -267,7 +330,7 @@ x86_fill_gregset (struct regcache *regcache, void *buf)
int i;
#ifdef __x86_64__
- if (register_size (0) == 8)
+ if (register_size (regcache->tdesc, 0) == 8)
{
for (i = 0; i < X86_64_NUM_REGS; i++)
if (x86_64_regmap[i] != -1)
@@ -289,7 +352,7 @@ x86_store_gregset (struct regcache *regcache, const void *buf)
int i;
#ifdef __x86_64__
- if (register_size (0) == 8)
+ if (register_size (regcache->tdesc, 0) == 8)
{
for (i = 0; i < X86_64_NUM_REGS; i++)
if (x86_64_regmap[i] != -1)
@@ -358,11 +421,9 @@ x86_store_xstateregset (struct regcache *regcache, const void *buf)
This is, presumably, to handle the case where PTRACE_[GS]ETFPXREGS
doesn't work. IWBN to avoid the duplication in the case where it
does work. Maybe the arch_setup routine could check whether it works
- and update target_regsets accordingly, maybe by moving target_regsets
- to linux_target_ops and set the right one there, rather than having to
- modify the target_regsets global. */
+ and update the supported regsets accordingly. */
-struct regset_info target_regsets[] =
+static struct regset_info x86_regsets[] =
{
#ifdef HAVE_PTRACE_GETREGS
{ PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t),
@@ -387,7 +448,7 @@ struct regset_info target_regsets[] =
static CORE_ADDR
x86_get_pc (struct regcache *regcache)
{
- int use_64bit = register_size (0) == 8;
+ int use_64bit = register_size (regcache->tdesc, 0) == 8;
if (use_64bit)
{
@@ -406,7 +467,7 @@ x86_get_pc (struct regcache *regcache)
static void
x86_set_pc (struct regcache *regcache, CORE_ADDR pc)
{
- int use_64bit = register_size (0) == 8;
+ int use_64bit = register_size (regcache->tdesc, 0) == 8;
if (use_64bit)
{
@@ -561,7 +622,7 @@ x86_insert_point (char type, CORE_ADDR addr, int len)
struct process_info *proc = current_process ();
switch (type)
{
- case '0':
+ case '0': /* software-breakpoint */
{
int ret;
@@ -572,11 +633,13 @@ x86_insert_point (char type, CORE_ADDR addr, int len)
done_accessing_memory ();
return ret;
}
- case '2':
- case '3':
- case '4':
+ case '1': /* hardware-breakpoint */
+ case '2': /* write watchpoint */
+ case '3': /* read watchpoint */
+ case '4': /* access watchpoint */
return i386_low_insert_watchpoint (&proc->private->arch_private->debug_reg_state,
type, addr, len);
+
default:
/* Unsupported. */
return 1;
@@ -589,7 +652,7 @@ x86_remove_point (char type, CORE_ADDR addr, int len)
struct process_info *proc = current_process ();
switch (type)
{
- case '0':
+ case '0': /* software-breakpoint */
{
int ret;
@@ -600,9 +663,10 @@ x86_remove_point (char type, CORE_ADDR addr, int len)
done_accessing_memory ();
return ret;
}
- case '2':
- case '3':
- case '4':
+ case '1': /* hardware-breakpoint */
+ case '2': /* write watchpoint */
+ case '3': /* read watchpoint */
+ case '4': /* access watchpoint */
return i386_low_remove_watchpoint (&proc->private->arch_private->debug_reg_state,
type, addr, len);
default:
@@ -1088,8 +1152,6 @@ siginfo_from_compat_x32_siginfo (siginfo_t *to,
}
}
-/* Is this process 64-bit? */
-static int linux_is_elf64;
#endif /* __x86_64__ */
/* Convert a native/host siginfo object, into/from the siginfo in the
@@ -1102,8 +1164,12 @@ static int
x86_siginfo_fixup (siginfo_t *native, void *inf, int direction)
{
#ifdef __x86_64__
+ unsigned int machine;
+ int tid = lwpid_of (get_thread_lwp (current_inferior));
+ int is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);
+
/* Is the inferior 32-bit? If so, then fixup the siginfo object. */
- if (register_size (0) == 4)
+ if (!is_64bit_tdesc ())
{
if (sizeof (siginfo_t) != sizeof (compat_siginfo_t))
fatal ("unexpected difference in siginfo");
@@ -1116,7 +1182,7 @@ x86_siginfo_fixup (siginfo_t *native, void *inf, int direction)
return 1;
}
/* No fixup for native x32 GDB. */
- else if (!linux_is_elf64 && sizeof (void *) == 8)
+ else if (!is_elf64 && sizeof (void *) == 8)
{
if (sizeof (siginfo_t) != sizeof (compat_x32_siginfo_t))
fatal ("unexpected difference in siginfo");
@@ -1137,138 +1203,240 @@ x86_siginfo_fixup (siginfo_t *native, void *inf, int direction)
static int use_xml;
-/* Update gdbserver_xmltarget. */
+/* Format of XSAVE extended state is:
+ struct
+ {
+ fxsave_bytes[0..463]
+ sw_usable_bytes[464..511]
+ xstate_hdr_bytes[512..575]
+ avx_bytes[576..831]
+ future_state etc
+ };
+
+ Same memory layout will be used for the coredump NT_X86_XSTATE
+ representing the XSAVE extended state registers.
+
+ The first 8 bytes of the sw_usable_bytes[464..467] is the OS enabled
+ extended state mask, which is the same as the extended control register
+ 0 (the XFEATURE_ENABLED_MASK register), XCR0. We can use this mask
+ together with the mask saved in the xstate_hdr_bytes to determine what
+ states the processor/OS supports and what state, used or initialized,
+ the process/thread is in. */
+#define I386_LINUX_XSAVE_XCR0_OFFSET 464
+
+/* Does the current host support the GETFPXREGS request? The header
+ file may or may not define it, and even if it is defined, the
+ kernel will return EIO if it's running on a pre-SSE processor. */
+int have_ptrace_getfpxregs =
+#ifdef HAVE_PTRACE_GETFPXREGS
+ -1
+#else
+ 0
+#endif
+;
-static void
-x86_linux_update_xmltarget (void)
+/* Does the current host support PTRACE_GETREGSET? */
+static int have_ptrace_getregset = -1;
+
+/* Get Linux/x86 target description from running target. */
+
+static const struct target_desc *
+x86_linux_read_description (void)
{
- int pid;
+ unsigned int machine;
+ int is_elf64;
+ int xcr0_features;
+ int tid;
+ static uint64_t xcr0;
struct regset_info *regset;
- static unsigned long long xcr0;
- static int have_ptrace_getregset = -1;
-#if !defined(__x86_64__) && defined(HAVE_PTRACE_GETFPXREGS)
- static int have_ptrace_getfpxregs = -1;
-#endif
- if (!current_inferior)
- return;
+ tid = lwpid_of (get_thread_lwp (current_inferior));
- /* Before changing the register cache internal layout or the target
- regsets, flush the contents of the current valid caches back to
- the threads. */
- regcache_invalidate ();
+ is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);
- pid = pid_of (get_thread_lwp (current_inferior));
-#ifdef __x86_64__
- if (num_xmm_registers == 8)
- init_registers_i386_linux ();
- else if (linux_is_elf64)
- init_registers_amd64_linux ();
- else
- init_registers_x32_linux ();
-#else
+ if (sizeof (void *) == 4)
{
-# ifdef HAVE_PTRACE_GETFPXREGS
- if (have_ptrace_getfpxregs == -1)
- {
- elf_fpxregset_t fpxregs;
+ if (is_elf64 > 0)
+ error (_("Can't debug 64-bit process with 32-bit GDBserver"));
+#ifndef __x86_64__
+ else if (machine == EM_X86_64)
+ error (_("Can't debug x86-64 process with 32-bit GDBserver"));
+#endif
+ }
- if (ptrace (PTRACE_GETFPXREGS, pid, 0, (int) &fpxregs) < 0)
- {
- have_ptrace_getfpxregs = 0;
- x86_xcr0 = I386_XSTATE_X87_MASK;
-
- /* Disable PTRACE_GETFPXREGS. */
- for (regset = target_regsets;
- regset->fill_function != NULL; regset++)
- if (regset->get_request == PTRACE_GETFPXREGS)
- {
- regset->size = 0;
- break;
- }
- }
- else
- have_ptrace_getfpxregs = 1;
- }
+#if !defined __x86_64__ && defined HAVE_PTRACE_GETFPXREGS
+ if (machine == EM_386 && have_ptrace_getfpxregs == -1)
+ {
+ elf_fpxregset_t fpxregs;
- if (!have_ptrace_getfpxregs)
+ if (ptrace (PTRACE_GETFPXREGS, tid, 0, (long) &fpxregs) < 0)
{
- init_registers_i386_mmx_linux ();
- return;
+ have_ptrace_getfpxregs = 0;
+ have_ptrace_getregset = 0;
+ return tdesc_i386_mmx_linux;
}
-# endif
- init_registers_i386_linux ();
+ else
+ have_ptrace_getfpxregs = 1;
}
#endif
if (!use_xml)
{
+ x86_xcr0 = I386_XSTATE_SSE_MASK;
+
/* Don't use XML. */
#ifdef __x86_64__
- if (num_xmm_registers == 8)
- gdbserver_xmltarget = xmltarget_i386_linux_no_xml;
+ if (machine == EM_X86_64)
+ return tdesc_amd64_linux_no_xml;
else
- gdbserver_xmltarget = xmltarget_amd64_linux_no_xml;
-#else
- gdbserver_xmltarget = xmltarget_i386_linux_no_xml;
#endif
-
- x86_xcr0 = I386_XSTATE_SSE_MASK;
-
- return;
+ return tdesc_i386_linux_no_xml;
}
- /* Check if XSAVE extended state is supported. */
if (have_ptrace_getregset == -1)
{
- unsigned long long xstateregs[I386_XSTATE_SSE_SIZE / sizeof (long long)];
+ uint64_t xstateregs[(I386_XSTATE_SSE_SIZE / sizeof (uint64_t))];
struct iovec iov;
iov.iov_base = xstateregs;
iov.iov_len = sizeof (xstateregs);
/* Check if PTRACE_GETREGSET works. */
- if (ptrace (PTRACE_GETREGSET, pid, (unsigned int) NT_X86_XSTATE,
- &iov) < 0)
+ if (ptrace (PTRACE_GETREGSET, tid,
+ (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
+ have_ptrace_getregset = 0;
+ else
{
- have_ptrace_getregset = 0;
- return;
+ have_ptrace_getregset = 1;
+
+ /* Get XCR0 from XSAVE extended state. */
+ xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET
+ / sizeof (uint64_t))];
+
+ /* Use PTRACE_GETREGSET if it is available. */
+ for (regset = x86_regsets;
+ regset->fill_function != NULL; regset++)
+ if (regset->get_request == PTRACE_GETREGSET)
+ regset->size = I386_XSTATE_SIZE (xcr0);
+ else if (regset->type != GENERAL_REGS)
+ regset->size = 0;
}
- else
- have_ptrace_getregset = 1;
-
- /* Get XCR0 from XSAVE extended state at byte 464. */
- xcr0 = xstateregs[464 / sizeof (long long)];
-
- /* Use PTRACE_GETREGSET if it is available. */
- for (regset = target_regsets;
- regset->fill_function != NULL; regset++)
- if (regset->get_request == PTRACE_GETREGSET)
- regset->size = I386_XSTATE_SIZE (xcr0);
- else if (regset->type != GENERAL_REGS)
- regset->size = 0;
}
- if (have_ptrace_getregset)
+ /* Check the native XCR0 only if PTRACE_GETREGSET is available. */
+ xcr0_features = (have_ptrace_getregset
+ && (xcr0 & I386_XSTATE_ALL_MASK));
+
+ if (xcr0_features)
+ x86_xcr0 = xcr0;
+
+ if (machine == EM_X86_64)
{
- /* AVX is the highest feature we support. */
- if ((xcr0 & I386_XSTATE_AVX_MASK) == I386_XSTATE_AVX_MASK)
+#ifdef __x86_64__
+ if (is_elf64)
{
- x86_xcr0 = xcr0;
+ if (xcr0_features)
+ {
+ switch (xcr0 & I386_XSTATE_ALL_MASK)
+ {
+ case I386_XSTATE_MPX_MASK:
+ return tdesc_amd64_mpx_linux;
-#ifdef __x86_64__
- /* I386 has 8 xmm regs. */
- if (num_xmm_registers == 8)
- init_registers_i386_avx_linux ();
- else if (linux_is_elf64)
- init_registers_amd64_avx_linux ();
+ case I386_XSTATE_AVX_MASK:
+ return tdesc_amd64_avx_linux;
+
+ default:
+ return tdesc_amd64_linux;
+ }
+ }
else
- init_registers_x32_avx_linux ();
-#else
- init_registers_i386_avx_linux ();
+ return tdesc_amd64_linux;
+ }
+ else
+ {
+ if (xcr0_features)
+ {
+ switch (xcr0 & I386_XSTATE_ALL_MASK)
+ {
+ case I386_XSTATE_MPX_MASK: /* No MPX on x32. */
+ case I386_XSTATE_AVX_MASK:
+ return tdesc_x32_avx_linux;
+
+ default:
+ return tdesc_x32_linux;
+ }
+ }
+ else
+ return tdesc_x32_linux;
+ }
#endif
+ }
+ else
+ {
+ if (xcr0_features)
+ {
+ switch (xcr0 & I386_XSTATE_ALL_MASK)
+ {
+ case (I386_XSTATE_MPX_MASK):
+ return tdesc_i386_mpx_linux;
+
+ case (I386_XSTATE_AVX_MASK):
+ return tdesc_i386_avx_linux;
+
+ default:
+ return tdesc_i386_linux;
+ }
}
+ else
+ return tdesc_i386_linux;
}
+
+ gdb_assert_not_reached ("failed to return tdesc");
+}
+
+/* Callback for find_inferior. Stops iteration when a thread with a
+ given PID is found. */
+
+static int
+same_process_callback (struct inferior_list_entry *entry, void *data)
+{
+ int pid = *(int *) data;
+
+ return (ptid_get_pid (entry->id) == pid);
+}
+
+/* Callback for for_each_inferior. Calls the arch_setup routine for
+ each process. */
+
+static void
+x86_arch_setup_process_callback (struct inferior_list_entry *entry)
+{
+ int pid = ptid_get_pid (entry->id);
+
+ /* Look up any thread of this processes. */
+ current_inferior
+ = (struct thread_info *) find_inferior (&all_threads,
+ same_process_callback, &pid);
+
+ the_low_target.arch_setup ();
+}
+
+/* Update all the target description of all processes; a new GDB
+ connected, and it may or not support xml target descriptions. */
+
+static void
+x86_linux_update_xmltarget (void)
+{
+ struct thread_info *save_inferior = current_inferior;
+
+ /* Before changing the register cache's internal layout, flush the
+ contents of the current valid caches back to the threads, and
+ release the current regcache objects. */
+ regcache_release ();
+
+ for_each_inferior (&all_processes, x86_arch_setup_process_callback);
+
+ current_inferior = save_inferior;
}
/* Process qSupported query, "xmlRegisters=". Update the buffer size for
@@ -1301,62 +1469,54 @@ x86_linux_process_qsupported (const char *query)
x86_linux_update_xmltarget ();
}
-/* Initialize gdbserver for the architecture of the inferior. */
-
-static void
-x86_arch_setup (void)
-{
- int pid = pid_of (get_thread_lwp (current_inferior));
- unsigned int machine;
- int is_elf64 = linux_pid_exe_is_elf_64_file (pid, &machine);
+/* Common for x86/x86-64. */
- if (sizeof (void *) == 4)
- {
- if (is_elf64 > 0)
- error (_("Can't debug 64-bit process with 32-bit GDBserver"));
-#ifndef __x86_64__
- else if (machine == EM_X86_64)
- error (_("Can't debug x86-64 process with 32-bit GDBserver"));
-#endif
- }
+static struct regsets_info x86_regsets_info =
+ {
+ x86_regsets, /* regsets */
+ 0, /* num_regsets */
+ NULL, /* disabled_regsets */
+ };
#ifdef __x86_64__
- if (is_elf64 < 0)
- {
- /* This can only happen if /proc/<pid>/exe is unreadable,
- but "that can't happen" if we've gotten this far.
- Fall through and assume this is a 32-bit program. */
- }
- else if (machine == EM_X86_64)
- {
- /* Amd64 doesn't have HAVE_LINUX_USRREGS. */
- the_low_target.num_regs = -1;
- the_low_target.regmap = NULL;
- the_low_target.cannot_fetch_register = NULL;
- the_low_target.cannot_store_register = NULL;
-
- /* Amd64 has 16 xmm regs. */
- num_xmm_registers = 16;
-
- linux_is_elf64 = is_elf64;
- x86_linux_update_xmltarget ();
- return;
- }
-
- linux_is_elf64 = 0;
+static struct regs_info amd64_linux_regs_info =
+ {
+ NULL, /* regset_bitmap */
+ NULL, /* usrregs_info */
+ &x86_regsets_info
+ };
#endif
+static struct usrregs_info i386_linux_usrregs_info =
+ {
+ I386_NUM_REGS,
+ i386_regmap,
+ };
- /* Ok we have a 32-bit inferior. */
+static struct regs_info i386_linux_regs_info =
+ {
+ NULL, /* regset_bitmap */
+ &i386_linux_usrregs_info,
+ &x86_regsets_info
+ };
- the_low_target.num_regs = I386_NUM_REGS;
- the_low_target.regmap = i386_regmap;
- the_low_target.cannot_fetch_register = i386_cannot_fetch_register;
- the_low_target.cannot_store_register = i386_cannot_store_register;
+const struct regs_info *
+x86_linux_regs_info (void)
+{
+#ifdef __x86_64__
+ if (is_64bit_tdesc ())
+ return &amd64_linux_regs_info;
+ else
+#endif
+ return &i386_linux_regs_info;
+}
- /* I386 has 8 xmm regs. */
- num_xmm_registers = 8;
+/* Initialize the target description for the architecture of the
+ inferior. */
- x86_linux_update_xmltarget ();
+static void
+x86_arch_setup (void)
+{
+ current_process ()->tdesc = x86_linux_read_description ();
}
static int
@@ -1786,7 +1946,7 @@ x86_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint, CORE_ADDR tpaddr,
char *err)
{
#ifdef __x86_64__
- if (register_size (0) == 8)
+ if (is_64bit_tdesc ())
return amd64_install_fast_tracepoint_jump_pad (tpoint, tpaddr,
collector, lockaddr,
orig_size, jump_entry,
@@ -1820,7 +1980,7 @@ x86_get_min_fast_tracepoint_insn_len (void)
#ifdef __x86_64__
/* On x86-64, 5-byte jump instructions with a 4-byte offset are always
used for fast tracepoints. */
- if (register_size (0) == 8)
+ if (is_64bit_tdesc ())
return 5;
#endif
@@ -3163,26 +3323,28 @@ static struct emit_ops *
x86_emit_ops (void)
{
#ifdef __x86_64__
- int use_64bit = register_size (0) == 8;
-
- if (use_64bit)
+ if (is_64bit_tdesc ())
return &amd64_emit_ops;
else
#endif
return &i386_emit_ops;
}
+static int
+x86_supports_range_stepping (void)
+{
+ return 1;
+}
+
/* This is initialized assuming an amd64 target.
x86_arch_setup will correct it for i386 or amd64 targets. */
struct linux_target_ops the_low_target =
{
x86_arch_setup,
- -1,
- NULL,
- NULL,
- NULL,
- NULL,
+ x86_linux_regs_info,
+ x86_cannot_fetch_register,
+ x86_cannot_store_register,
NULL, /* fetch_register */
x86_get_pc,
x86_set_pc,
@@ -3211,4 +3373,33 @@ struct linux_target_ops the_low_target =
x86_install_fast_tracepoint_jump_pad,
x86_emit_ops,
x86_get_min_fast_tracepoint_insn_len,
+ x86_supports_range_stepping,
};
+
+void
+initialize_low_arch (void)
+{
+ /* Initialize the Linux target descriptions. */
+#ifdef __x86_64__
+ init_registers_amd64_linux ();
+ init_registers_amd64_avx_linux ();
+ init_registers_amd64_mpx_linux ();
+
+ init_registers_x32_linux ();
+ init_registers_x32_avx_linux ();
+
+ tdesc_amd64_linux_no_xml = xmalloc (sizeof (struct target_desc));
+ copy_target_description (tdesc_amd64_linux_no_xml, tdesc_amd64_linux);
+ tdesc_amd64_linux_no_xml->xmltarget = xmltarget_amd64_linux_no_xml;
+#endif
+ init_registers_i386_linux ();
+ init_registers_i386_mmx_linux ();
+ init_registers_i386_avx_linux ();
+ init_registers_i386_mpx_linux ();
+
+ tdesc_i386_linux_no_xml = xmalloc (sizeof (struct target_desc));
+ copy_target_description (tdesc_i386_linux_no_xml, tdesc_i386_linux);
+ tdesc_i386_linux_no_xml->xmltarget = xmltarget_i386_linux_no_xml;
+
+ initialize_regsets_info (&x86_regsets_info);
+}
« no previous file with comments | « gdb/gdbserver/linux-tile-low.c ('k') | gdb/gdbserver/linux-xtensa-low.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698