forked from Imagelibrary/binutils-gdb
* amd64-linux-nat.c (compat_int_t, compat_uptr_t, compat_time_t)
(compat_timer_t, compat_clock_t, struct compat_timeval) (compat_sigval_t, compat_siginfo_t): New types. (cpt_si_pid, cpt_si_uid, cpt_si_timerid, cpt_si_overrun) (cpt_si_status, cpt_si_utime, cpt_si_stime, cpt_si_ptr) (cpt_si_addr, cpt_si_band, cpt_si_fd): New defines. (compat_siginfo_from_siginfo, siginfo_from_compat_siginfo) (amd64_linux_siginfo_fixup): New. * linux-nat.c (linux_nat_siginfo_fixup): New. (siginfo_fixup): New. (linux_xfer_siginfo): Use siginfo_fixup to convert between the siginfo layout expected by ptrace and the siginfo layout of the inferior. (linux_nat_set_siginfo_fixup): New. * linux-nat.h (linux_nat_set_siginfo_fixup): Declare.
This commit is contained in:
@@ -205,6 +205,13 @@ static struct target_ops linux_ops_saved;
|
||||
/* The method to call, if any, when a new thread is attached. */
|
||||
static void (*linux_nat_new_thread) (ptid_t);
|
||||
|
||||
/* The method to call, if any, when the siginfo object needs to be
|
||||
converted between the layout returned by ptrace, and the layout in
|
||||
the architecture of the inferior. */
|
||||
static int (*linux_nat_siginfo_fixup) (struct siginfo *,
|
||||
gdb_byte *,
|
||||
int);
|
||||
|
||||
/* The saved to_xfer_partial method, inherited from inf-ptrace.c.
|
||||
Called by our to_xfer_partial. */
|
||||
static LONGEST (*super_xfer_partial) (struct target_ops *,
|
||||
@@ -3223,6 +3230,28 @@ linux_nat_mourn_inferior (struct target_ops *ops)
|
||||
linux_fork_mourn_inferior ();
|
||||
}
|
||||
|
||||
/* Convert a native/host siginfo object, into/from the siginfo in the
|
||||
layout of the inferiors' architecture. */
|
||||
|
||||
static void
|
||||
siginfo_fixup (struct siginfo *siginfo, gdb_byte *inf_siginfo, int direction)
|
||||
{
|
||||
int done = 0;
|
||||
|
||||
if (linux_nat_siginfo_fixup != NULL)
|
||||
done = linux_nat_siginfo_fixup (siginfo, inf_siginfo, direction);
|
||||
|
||||
/* If there was no callback, or the callback didn't do anything,
|
||||
then just do a straight memcpy. */
|
||||
if (!done)
|
||||
{
|
||||
if (direction == 1)
|
||||
memcpy (siginfo, inf_siginfo, sizeof (struct siginfo));
|
||||
else
|
||||
memcpy (inf_siginfo, siginfo, sizeof (struct siginfo));
|
||||
}
|
||||
}
|
||||
|
||||
static LONGEST
|
||||
linux_xfer_siginfo (struct target_ops *ops, enum target_object object,
|
||||
const char *annex, gdb_byte *readbuf,
|
||||
@@ -3232,6 +3261,7 @@ linux_xfer_siginfo (struct target_ops *ops, enum target_object object,
|
||||
LONGEST n;
|
||||
int pid;
|
||||
struct siginfo siginfo;
|
||||
gdb_byte inf_siginfo[sizeof (struct siginfo)];
|
||||
|
||||
gdb_assert (object == TARGET_OBJECT_SIGNAL_INFO);
|
||||
gdb_assert (readbuf || writebuf);
|
||||
@@ -3248,14 +3278,26 @@ linux_xfer_siginfo (struct target_ops *ops, enum target_object object,
|
||||
if (errno != 0)
|
||||
return -1;
|
||||
|
||||
/* When GDB is built as a 64-bit application, ptrace writes into
|
||||
SIGINFO an object with 64-bit layout. Since debugging a 32-bit
|
||||
inferior with a 64-bit GDB should look the same as debugging it
|
||||
with a 32-bit GDB, we need to convert it. GDB core always sees
|
||||
the converted layout, so any read/write will have to be done
|
||||
post-conversion. */
|
||||
siginfo_fixup (&siginfo, inf_siginfo, 0);
|
||||
|
||||
if (offset + len > sizeof (siginfo))
|
||||
len = sizeof (siginfo) - offset;
|
||||
|
||||
if (readbuf != NULL)
|
||||
memcpy (readbuf, (char *)&siginfo + offset, len);
|
||||
memcpy (readbuf, inf_siginfo + offset, len);
|
||||
else
|
||||
{
|
||||
memcpy ((char *)&siginfo + offset, writebuf, len);
|
||||
memcpy (inf_siginfo + offset, writebuf, len);
|
||||
|
||||
/* Convert back to ptrace layout before flushing it out. */
|
||||
siginfo_fixup (&siginfo, inf_siginfo, 1);
|
||||
|
||||
errno = 0;
|
||||
ptrace (PTRACE_SETSIGINFO, pid, (PTRACE_TYPE_ARG3) 0, &siginfo);
|
||||
if (errno != 0)
|
||||
@@ -4720,6 +4762,19 @@ linux_nat_set_new_thread (struct target_ops *t, void (*new_thread) (ptid_t))
|
||||
linux_nat_new_thread = new_thread;
|
||||
}
|
||||
|
||||
/* Register a method that converts a siginfo object between the layout
|
||||
that ptrace returns, and the layout in the architecture of the
|
||||
inferior. */
|
||||
void
|
||||
linux_nat_set_siginfo_fixup (struct target_ops *t,
|
||||
int (*siginfo_fixup) (struct siginfo *,
|
||||
gdb_byte *,
|
||||
int))
|
||||
{
|
||||
/* Save the pointer. */
|
||||
linux_nat_siginfo_fixup = siginfo_fixup;
|
||||
}
|
||||
|
||||
/* Return the saved siginfo associated with PTID. */
|
||||
struct siginfo *
|
||||
linux_nat_get_siginfo (ptid_t ptid)
|
||||
|
||||
Reference in New Issue
Block a user