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

Unified Diff: gdb/amd64-linux-nat.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/amd64-dicos-tdep.c ('k') | gdb/amd64-linux-tdep.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gdb/amd64-linux-nat.c
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 01982acf17c26fd840eeafcc281db0ec9a429c5c..b1676ac32ea676bd0d046ce35c05decf6687968c 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -1,6 +1,6 @@
/* Native-dependent code for GNU/Linux x86-64.
- Copyright (C) 2001-2012 Free Software Foundation, Inc.
+ Copyright (C) 2001-2013 Free Software Foundation, Inc.
Contributed by Jiri Smid, SuSE Labs.
This file is part of GDB.
@@ -25,9 +25,11 @@
#include "regset.h"
#include "linux-nat.h"
#include "amd64-linux-tdep.h"
+#include "linux-btrace.h"
+#include "btrace.h"
#include "gdb_assert.h"
-#include "gdb_string.h"
+#include <string.h>
#include "elf/common.h"
#include <sys/uio.h>
#include <sys/ptrace.h>
@@ -98,7 +100,9 @@ static int amd64_linux_gregset32_reg_offset[] =
-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 /* "orig_eax" */
+ -1, -1, -1, -1, /* MPX registers BND0 ... BND3. */
+ -1, -1, /* MPX registers BNDCFGU, BNDSTATUS. */
+ ORIG_RAX * 8, /* "orig_eax" */
};
@@ -162,9 +166,9 @@ amd64_linux_fetch_inferior_registers (struct target_ops *ops,
int tid;
/* GNU/Linux LWP ID's are process ID's. */
- tid = TIDGET (inferior_ptid);
+ tid = ptid_get_lwp (inferior_ptid);
if (tid == 0)
- tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+ tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
{
@@ -217,9 +221,9 @@ amd64_linux_store_inferior_registers (struct target_ops *ops,
int tid;
/* GNU/Linux LWP ID's are process ID's. */
- tid = TIDGET (inferior_ptid);
+ tid = ptid_get_lwp (inferior_ptid);
if (tid == 0)
- tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+ tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
{
@@ -279,9 +283,9 @@ amd64_linux_dr_get (ptid_t ptid, int regnum)
int tid;
unsigned long value;
- tid = TIDGET (ptid);
+ tid = ptid_get_lwp (ptid);
if (tid == 0)
- tid = PIDGET (ptid);
+ tid = ptid_get_pid (ptid);
errno = 0;
value = ptrace (PTRACE_PEEKUSER, tid,
@@ -299,9 +303,9 @@ amd64_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
{
int tid;
- tid = TIDGET (ptid);
+ tid = ptid_get_lwp (ptid);
if (tid == 0)
- tid = PIDGET (ptid);
+ tid = ptid_get_pid (ptid);
errno = 0;
ptrace (PTRACE_POKEUSER, tid,
@@ -337,8 +341,8 @@ amd64_linux_dr_get_status (void)
return amd64_linux_dr_get (inferior_ptid, DR_STATUS);
}
-/* Callback for linux_nat_iterate_watchpoint_lwps. Update the debug registers
- of LWP. */
+/* Callback for iterate_over_lwps. Update the debug registers of
+ LWP. */
static int
update_debug_registers_callback (struct lwp_info *lwp, void *arg)
@@ -364,7 +368,9 @@ update_debug_registers_callback (struct lwp_info *lwp, void *arg)
static void
amd64_linux_dr_set_control (unsigned long control)
{
- linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL);
+ ptid_t pid_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
+
+ iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL);
}
/* Set address REGNUM (zero based) to ADDR in all LWPs of the current
@@ -373,9 +379,11 @@ amd64_linux_dr_set_control (unsigned long control)
static void
amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
{
+ ptid_t pid_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
+
gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
- linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL);
+ iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL);
}
/* Called when resuming a thread.
@@ -394,7 +402,8 @@ amd64_linux_prepare_to_resume (struct lwp_info *lwp)
if (lwp->arch_private->debug_registers_changed)
{
- struct i386_debug_reg_state *state = i386_debug_reg_state ();
+ struct i386_debug_reg_state *state
+ = i386_debug_reg_state (ptid_get_pid (lwp->ptid));
int i;
/* On Linux kernel before 2.6.33 commit
@@ -434,6 +443,41 @@ amd64_linux_new_thread (struct lwp_info *lp)
lp->arch_private = info;
}
+
+/* linux_nat_new_fork hook. */
+
+static void
+amd64_linux_new_fork (struct lwp_info *parent, pid_t child_pid)
+{
+ pid_t parent_pid;
+ struct i386_debug_reg_state *parent_state;
+ struct i386_debug_reg_state *child_state;
+
+ /* NULL means no watchpoint has ever been set in the parent. In
+ that case, there's nothing to do. */
+ if (parent->arch_private == NULL)
+ return;
+
+ /* Linux kernel before 2.6.33 commit
+ 72f674d203cd230426437cdcf7dd6f681dad8b0d
+ will inherit hardware debug registers from parent
+ on fork/vfork/clone. Newer Linux kernels create such tasks with
+ zeroed debug registers.
+
+ GDB core assumes the child inherits the watchpoints/hw
+ breakpoints of the parent, and will remove them all from the
+ forked off process. Copy the debug registers mirrors into the
+ new process so that all breakpoints and watchpoints can be
+ removed together. The debug registers mirror will become zeroed
+ in the end before detaching the forked off process, thus making
+ this compatible with older Linux kernels too. */
+
+ parent_pid = ptid_get_pid (parent->ptid);
+ parent_state = i386_debug_reg_state (parent_pid);
+ child_state = i386_debug_reg_state (child_pid);
+ *child_state = *parent_state;
+}
+
/* This function is called by libthread_db as part of its handling of
@@ -443,7 +487,7 @@ ps_err_e
ps_get_thread_area (const struct ps_prochandle *ph,
lwpid_t lwpid, int idx, void **base)
{
- if (gdbarch_bfd_arch_info (target_gdbarch)->bits_per_word == 32)
+ if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32)
{
/* The full structure is found in <asm-i386/ldt.h>. The second
integer is the LDT's base_address and that is used to locate
@@ -1004,9 +1048,9 @@ amd64_linux_read_description (struct target_ops *ops)
static uint64_t xcr0;
/* GNU/Linux LWP ID's are process ID's. */
- tid = TIDGET (inferior_ptid);
+ tid = ptid_get_lwp (inferior_ptid);
if (tid == 0)
- tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+ tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
/* Get CS register. */
errno = 0;
@@ -1052,18 +1096,41 @@ amd64_linux_read_description (struct target_ops *ops)
}
/* Check the native XCR0 only if PTRACE_GETREGSET is available. */
- if (have_ptrace_getregset
- && (xcr0 & I386_XSTATE_AVX_MASK) == I386_XSTATE_AVX_MASK)
+ if (have_ptrace_getregset && (xcr0 & I386_XSTATE_ALL_MASK))
{
- if (is_64bit)
+ switch (xcr0 & I386_XSTATE_ALL_MASK)
{
- if (is_x32)
- return tdesc_x32_avx_linux;
+ case I386_XSTATE_MPX_MASK:
+ if (is_64bit)
+ {
+ if (is_x32)
+ return tdesc_x32_avx_linux; /* No MPX on x32 using AVX. */
+ else
+ return tdesc_amd64_mpx_linux;
+ }
+ else
+ return tdesc_i386_mpx_linux;
+ case I386_XSTATE_AVX_MASK:
+ if (is_64bit)
+ {
+ if (is_x32)
+ return tdesc_x32_avx_linux;
+ else
+ return tdesc_amd64_avx_linux;
+ }
+ else
+ return tdesc_i386_avx_linux;
+ default:
+ if (is_64bit)
+ {
+ if (is_x32)
+ return tdesc_x32_linux;
+ else
+ return tdesc_amd64_linux;
+ }
else
- return tdesc_amd64_avx_linux;
+ return tdesc_i386_linux;
}
- else
- return tdesc_i386_avx_linux;
}
else
{
@@ -1079,6 +1146,48 @@ amd64_linux_read_description (struct target_ops *ops)
}
}
+/* Enable branch tracing. */
+
+static struct btrace_target_info *
+amd64_linux_enable_btrace (ptid_t ptid)
+{
+ struct btrace_target_info *tinfo;
+ struct gdbarch *gdbarch;
+
+ errno = 0;
+ tinfo = linux_enable_btrace (ptid);
+
+ if (tinfo == NULL)
+ error (_("Could not enable branch tracing for %s: %s."),
+ target_pid_to_str (ptid), safe_strerror (errno));
+
+ /* Fill in the size of a pointer in bits. */
+ gdbarch = target_thread_architecture (ptid);
+ tinfo->ptr_bits = gdbarch_ptr_bit (gdbarch);
+
+ return tinfo;
+}
+
+/* Disable branch tracing. */
+
+static void
+amd64_linux_disable_btrace (struct btrace_target_info *tinfo)
+{
+ int errcode = linux_disable_btrace (tinfo);
+
+ if (errcode != 0)
+ error (_("Could not disable branch tracing: %s."), safe_strerror (errcode));
+}
+
+/* Teardown branch tracing. */
+
+static void
+amd64_linux_teardown_btrace (struct btrace_target_info *tinfo)
+{
+ /* Ignore errors. */
+ linux_disable_btrace (tinfo);
+}
+
/* Provide a prototype to silence -Wmissing-prototypes. */
void _initialize_amd64_linux_nat (void);
@@ -1117,9 +1226,18 @@ _initialize_amd64_linux_nat (void)
t->to_read_description = amd64_linux_read_description;
+ /* Add btrace methods. */
+ t->to_supports_btrace = linux_supports_btrace;
+ t->to_enable_btrace = amd64_linux_enable_btrace;
+ t->to_disable_btrace = amd64_linux_disable_btrace;
+ t->to_teardown_btrace = amd64_linux_teardown_btrace;
+ t->to_read_btrace = linux_read_btrace;
+
/* Register the target. */
linux_nat_add_target (t);
linux_nat_set_new_thread (t, amd64_linux_new_thread);
+ linux_nat_set_new_fork (t, amd64_linux_new_fork);
+ linux_nat_set_forget_process (t, i386_forget_process);
linux_nat_set_siginfo_fixup (t, amd64_linux_siginfo_fixup);
linux_nat_set_prepare_to_resume (t, amd64_linux_prepare_to_resume);
}
« no previous file with comments | « gdb/amd64-dicos-tdep.c ('k') | gdb/amd64-linux-tdep.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698