From: Walfred Tedeschi <walfred.tedeschi@intel.com>
To: palves@redhat.com, brobecker@adacore.com
Cc: gdb-patches@sourceware.org,
Walfred Tedeschi <walfred.tedeschi@intel.com>
Subject: [PATCH V2 5/5] Adapt siginfo fixup for the new bnd fields.
Date: Thu, 17 Dec 2015 16:57:00 -0000 [thread overview]
Message-ID: <1450371416-24270-5-git-send-email-walfred.tedeschi@intel.com> (raw)
In-Reply-To: <1450371416-24270-1-git-send-email-walfred.tedeschi@intel.com>
New bnds fields will be always present for x86 architecture.
Fixup for compatibility layer 32bits has to be fixed.
It was added the nat_siginfo to serving as intermediate step
between kernel provided siginfo and the fix up routine.
When executing compat_siginfo_from_siginfo or
compat_x32_siginfo_from_siginfo first the buffer read from the kernel are
converted into the nat_signfo for homogenization, then the fields of
nat_siginfo are use to set the compat and compat_x32 siginfo structures.
When executing siginfo_from_compat_siginfo or
siginfo_from_compat_x32_siginfo the process happens in oposite order.
In doing this the fixups become more independent of the system underneath.
Caveat: No support for MPX on x32.
2015-12-08 Walfred Tedeschi <walfred.tedeschi@intel.com>
* amd64-linux-siginfo.c (nat_siginfo_t, nat_sigval_t, nat_timeval):
New types.
(compat_siginfo): New bnd fields added.
(compat_x32_siginfo): New field added.
(cpt_si_addr_lsb): New define.
(compat_siginfo_from_siginfo): Use nat_siginfo.
(siginfo_from_compat_siginfo): Use nat_siginfo.
(compat_x32_siginfo_from_siginfo): Likewise.
(siginfo_from_compat_x32_siginfo): Likewise.
---
gdb/nat/amd64-linux-siginfo.c | 311 ++++++++++++++++++++++++++++--------------
1 file changed, 211 insertions(+), 100 deletions(-)
diff --git a/gdb/nat/amd64-linux-siginfo.c b/gdb/nat/amd64-linux-siginfo.c
index 22e3552..8f0f486 100644
--- a/gdb/nat/amd64-linux-siginfo.c
+++ b/gdb/nat/amd64-linux-siginfo.c
@@ -30,6 +30,92 @@
Also, the first step is to make a copy from the original bits to the
internal structure which is the super set. */
+/* These types below (native_*) define a siginfo type that is layout
+ the most complete siginfo available for the architecture. */
+
+typedef int nat_int_t;
+typedef void* nat_uptr_t;
+
+typedef int nat_time_t;
+typedef int nat_timer_t;
+
+/* For native 64-bit, clock_t in _sigchld is 64bit aligned at 4 bytes. */
+typedef long __attribute__ ((__aligned__ (4))) nat_clock_t;
+
+struct nat_timeval
+{
+ nat_time_t tv_sec;
+ int tv_usec;
+};
+
+typedef union nat_sigval
+{
+ nat_int_t sival_int;
+ nat_uptr_t sival_ptr;
+} nat_sigval_t;
+
+typedef struct nat_siginfo
+{
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union
+ {
+ int _pad[((128 / sizeof (int)) - 4)];
+ /* kill() */
+ struct
+ {
+ unsigned int _pid;
+ unsigned int _uid;
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct
+ {
+ nat_timer_t _tid;
+ int _overrun;
+ nat_sigval_t _sigval;
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct
+ {
+ unsigned int _pid;
+ unsigned int _uid;
+ nat_sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct
+ {
+ unsigned int _pid;
+ unsigned int _uid;
+ int _status;
+ nat_clock_t _utime;
+ nat_clock_t _stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct
+ {
+ nat_uptr_t _addr;
+ short int _addr_lsb;
+ struct
+ {
+ nat_uptr_t _lower;
+ nat_uptr_t _upper;
+ } si_addr_bnd;
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct
+ {
+ int _band;
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} nat_siginfo_t __attribute__ ((__aligned__ (8)));
/* These types below (compat_*) define a siginfo type that is layout
compatible with the siginfo type exported by the 32-bit userspace
@@ -101,6 +187,12 @@ typedef struct compat_siginfo
struct
{
unsigned int _addr;
+ short int _addr_lsb;
+ struct
+ {
+ unsigned int _lower;
+ unsigned int _upper;
+ } si_addr_bnd;
} _sigfault;
/* SIGPOLL */
@@ -162,6 +254,7 @@ typedef struct compat_x32_siginfo
struct
{
unsigned int _addr;
+ unsigned int _addr_lsb;
} _sigfault;
/* SIGPOLL */
@@ -184,6 +277,7 @@ typedef struct compat_x32_siginfo
#define cpt_si_stime _sifields._sigchld._stime
#define cpt_si_ptr _sifields._rt._sigval.sival_ptr
#define cpt_si_addr _sifields._sigfault._addr
+#define cpt_si_addr_lsb _sifields._sigfault._addr_lsb
#define cpt_si_band _sifields._sigpoll._band
#define cpt_si_fd _sifields._sigpoll._fd
@@ -200,54 +294,58 @@ typedef struct compat_x32_siginfo
static void
compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
{
+ nat_siginfo_t from_nat;
+
+ gdb_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t));
+ memcpy (&from_nat, from, sizeof (from_nat));
memset (to, 0, sizeof (*to));
- to->si_signo = from->si_signo;
- to->si_errno = from->si_errno;
- to->si_code = from->si_code;
+ to->si_signo = from_nat.si_signo;
+ to->si_errno = from_nat.si_errno;
+ to->si_code = from_nat.si_code;
if (to->si_code == SI_TIMER)
{
- to->cpt_si_timerid = from->si_timerid;
- to->cpt_si_overrun = from->si_overrun;
- to->cpt_si_ptr = (intptr_t) from->si_ptr;
+ to->cpt_si_timerid = from_nat.cpt_si_timerid;
+ to->cpt_si_overrun = from_nat.cpt_si_overrun;
+ to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
}
else if (to->si_code == SI_USER)
{
- to->cpt_si_pid = from->si_pid;
- to->cpt_si_uid = from->si_uid;
+ to->cpt_si_pid = from_nat.cpt_si_pid;
+ to->cpt_si_uid = from_nat.cpt_si_uid;
}
else if (to->si_code < 0)
{
- to->cpt_si_pid = from->si_pid;
- to->cpt_si_uid = from->si_uid;
- to->cpt_si_ptr = (intptr_t) from->si_ptr;
+ to->cpt_si_pid = from_nat.cpt_si_pid;
+ to->cpt_si_uid = from_nat.cpt_si_uid;
+ to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
}
else
{
switch (to->si_signo)
{
case SIGCHLD:
- to->cpt_si_pid = from->si_pid;
- to->cpt_si_uid = from->si_uid;
- to->cpt_si_status = from->si_status;
- to->cpt_si_utime = from->si_utime;
- to->cpt_si_stime = from->si_stime;
+ to->cpt_si_pid = from_nat.cpt_si_pid;
+ to->cpt_si_uid = from_nat.cpt_si_uid;
+ to->cpt_si_status = from_nat.cpt_si_status;
+ to->cpt_si_utime = from_nat.cpt_si_utime;
+ to->cpt_si_stime = from_nat.cpt_si_stime;
break;
case SIGILL:
case SIGFPE:
case SIGSEGV:
case SIGBUS:
- to->cpt_si_addr = (intptr_t) from->si_addr;
+ to->cpt_si_addr = (intptr_t) from_nat.cpt_si_addr;
break;
case SIGPOLL:
- to->cpt_si_band = from->si_band;
- to->cpt_si_fd = from->si_fd;
+ to->cpt_si_band = from_nat.cpt_si_band;
+ to->cpt_si_fd = from_nat.cpt_si_fd;
break;
default:
- to->cpt_si_pid = from->si_pid;
- to->cpt_si_uid = from->si_uid;
- to->cpt_si_ptr = (intptr_t) from->si_ptr;
+ to->cpt_si_pid = from_nat.cpt_si_pid;
+ to->cpt_si_uid = from_nat.cpt_si_uid;
+ to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
break;
}
}
@@ -257,57 +355,62 @@ compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
static void
siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from)
{
- memset (to, 0, sizeof (*to));
+ nat_siginfo_t to_nat;
- to->si_signo = from->si_signo;
- to->si_errno = from->si_errno;
- to->si_code = from->si_code;
+ gdb_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t));
+ memset (&to_nat, 0, sizeof (to_nat));
- if (to->si_code == SI_TIMER)
+ to_nat.si_signo = from->si_signo;
+ to_nat.si_errno = from->si_errno;
+ to_nat.si_code = from->si_code;
+
+ if (to_nat.si_code == SI_TIMER)
{
- to->si_timerid = from->cpt_si_timerid;
- to->si_overrun = from->cpt_si_overrun;
- to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+ to_nat.cpt_si_timerid = from->cpt_si_timerid;
+ to_nat.cpt_si_overrun = from->cpt_si_overrun;
+ to_nat.cpt_si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
}
- else if (to->si_code == SI_USER)
+ else if (to_nat.si_code == SI_USER)
{
- to->si_pid = from->cpt_si_pid;
- to->si_uid = from->cpt_si_uid;
+ to_nat.cpt_si_pid = from->cpt_si_pid;
+ to_nat.cpt_si_uid = from->cpt_si_uid;
}
- if (to->si_code < 0)
+ if (to_nat.si_code < 0)
{
- to->si_pid = from->cpt_si_pid;
- to->si_uid = from->cpt_si_uid;
- to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+ to_nat.cpt_si_pid = from->cpt_si_pid;
+ to_nat.cpt_si_uid = from->cpt_si_uid;
+ to_nat.cpt_si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
}
else
{
- switch (to->si_signo)
+ switch (to_nat.si_signo)
{
case SIGCHLD:
- to->si_pid = from->cpt_si_pid;
- to->si_uid = from->cpt_si_uid;
- to->si_status = from->cpt_si_status;
- to->si_utime = from->cpt_si_utime;
- to->si_stime = from->cpt_si_stime;
+ to_nat.cpt_si_pid = from->cpt_si_pid;
+ to_nat.cpt_si_uid = from->cpt_si_uid;
+ to_nat.cpt_si_status = from->cpt_si_status;
+ to_nat.cpt_si_utime = from->cpt_si_utime;
+ to_nat.cpt_si_stime = from->cpt_si_stime;
break;
case SIGILL:
case SIGFPE:
case SIGSEGV:
case SIGBUS:
- to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
+ to_nat.cpt_si_addr = (void *) (intptr_t) from->cpt_si_addr;
+ to_nat.cpt_si_addr_lsb = (short) from->cpt_si_addr_lsb;
break;
case SIGPOLL:
- to->si_band = from->cpt_si_band;
- to->si_fd = from->cpt_si_fd;
+ to_nat.cpt_si_band = from->cpt_si_band;
+ to_nat.cpt_si_fd = from->cpt_si_fd;
break;
default:
- to->si_pid = from->cpt_si_pid;
- to->si_uid = from->cpt_si_uid;
- to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
+ to_nat.cpt_si_pid = from->cpt_si_pid;
+ to_nat.cpt_si_uid = from->cpt_si_uid;
+ to_nat.cpt_si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
break;
}
}
+ memcpy (to, &to_nat, sizeof (to_nat));
}
/* Converts the system provided siginfo into compatible x32 siginfo. */
@@ -315,56 +418,60 @@ static void
compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
siginfo_t *from)
{
+ nat_siginfo_t from_nat;
+
+ gdb_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t));
+ memcpy (&from_nat, from, sizeof (from_nat));
memset (to, 0, sizeof (*to));
- to->si_signo = from->si_signo;
- to->si_errno = from->si_errno;
- to->si_code = from->si_code;
+ to->si_signo = from_nat.si_signo;
+ to->si_errno = from_nat.si_errno;
+ to->si_code = from_nat.si_code;
if (to->si_code == SI_TIMER)
{
- to->cpt_si_timerid = from->si_timerid;
- to->cpt_si_overrun = from->si_overrun;
- to->cpt_si_ptr = (intptr_t) from->si_ptr;
+ to->cpt_si_timerid = from_nat.cpt_si_timerid;
+ to->cpt_si_overrun = from_nat.cpt_si_overrun;
+ to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
}
else if (to->si_code == SI_USER)
{
- to->cpt_si_pid = from->si_pid;
- to->cpt_si_uid = from->si_uid;
+ to->cpt_si_pid = from_nat.cpt_si_pid;
+ to->cpt_si_uid = from_nat.cpt_si_uid;
}
else if (to->si_code < 0)
{
- to->cpt_si_pid = from->si_pid;
- to->cpt_si_uid = from->si_uid;
- to->cpt_si_ptr = (intptr_t) from->si_ptr;
+ to->cpt_si_pid = from_nat.cpt_si_pid;
+ to->cpt_si_uid = from_nat.cpt_si_uid;
+ to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
}
else
{
switch (to->si_signo)
{
case SIGCHLD:
- to->cpt_si_pid = from->si_pid;
- to->cpt_si_uid = from->si_uid;
- to->cpt_si_status = from->si_status;
- memcpy (&to->cpt_si_utime, &from->si_utime,
+ to->cpt_si_pid = from_nat.cpt_si_pid;
+ to->cpt_si_uid = from_nat.cpt_si_uid;
+ to->cpt_si_status = from_nat.cpt_si_status;
+ memcpy (&to->cpt_si_utime, &from_nat.cpt_si_utime,
sizeof (to->cpt_si_utime));
- memcpy (&to->cpt_si_stime, &from->si_stime,
+ memcpy (&to->cpt_si_stime, &from_nat.cpt_si_stime,
sizeof (to->cpt_si_stime));
break;
case SIGILL:
case SIGFPE:
case SIGSEGV:
case SIGBUS:
- to->cpt_si_addr = (intptr_t) from->si_addr;
+ to->cpt_si_addr = (intptr_t) from_nat.cpt_si_addr;
break;
case SIGPOLL:
- to->cpt_si_band = from->si_band;
- to->cpt_si_fd = from->si_fd;
+ to->cpt_si_band = from_nat.cpt_si_band;
+ to->cpt_si_fd = from_nat.cpt_si_fd;
break;
default:
- to->cpt_si_pid = from->si_pid;
- to->cpt_si_uid = from->si_uid;
- to->cpt_si_ptr = (intptr_t) from->si_ptr;
+ to->cpt_si_pid = from_nat.cpt_si_pid;
+ to->cpt_si_uid = from_nat.cpt_si_uid;
+ to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
break;
}
}
@@ -375,59 +482,63 @@ static void
siginfo_from_compat_x32_siginfo (siginfo_t *to,
compat_x32_siginfo_t *from)
{
- memset (to, 0, sizeof (*to));
+ nat_siginfo_t to_nat;
- to->si_signo = from->si_signo;
- to->si_errno = from->si_errno;
- to->si_code = from->si_code;
+ gdb_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t));
+ memset (&to_nat, 0, sizeof (to_nat));
- if (to->si_code == SI_TIMER)
+ to_nat.si_signo = from->si_signo;
+ to_nat.si_errno = from->si_errno;
+ to_nat.si_code = from->si_code;
+
+ if (to_nat.si_code == SI_TIMER)
{
- to->si_timerid = from->cpt_si_timerid;
- to->si_overrun = from->cpt_si_overrun;
- to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+ to_nat.cpt_si_timerid = from->cpt_si_timerid;
+ to_nat.cpt_si_overrun = from->cpt_si_overrun;
+ to_nat.cpt_si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
}
- else if (to->si_code == SI_USER)
+ else if (to_nat.si_code == SI_USER)
{
- to->si_pid = from->cpt_si_pid;
- to->si_uid = from->cpt_si_uid;
+ to_nat.cpt_si_pid = from->cpt_si_pid;
+ to_nat.cpt_si_uid = from->cpt_si_uid;
}
- if (to->si_code < 0)
+ if (to_nat.si_code < 0)
{
- to->si_pid = from->cpt_si_pid;
- to->si_uid = from->cpt_si_uid;
- to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+ to_nat.cpt_si_pid = from->cpt_si_pid;
+ to_nat.cpt_si_uid = from->cpt_si_uid;
+ to_nat.cpt_si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
}
else
{
- switch (to->si_signo)
+ switch (to_nat.si_signo)
{
case SIGCHLD:
- to->si_pid = from->cpt_si_pid;
- to->si_uid = from->cpt_si_uid;
- to->si_status = from->cpt_si_status;
- memcpy (&to->si_utime, &from->cpt_si_utime,
- sizeof (to->si_utime));
- memcpy (&to->si_stime, &from->cpt_si_stime,
- sizeof (to->si_stime));
+ to_nat.cpt_si_pid = from->cpt_si_pid;
+ to_nat.cpt_si_uid = from->cpt_si_uid;
+ to_nat.cpt_si_status = from->cpt_si_status;
+ memcpy (&to_nat.cpt_si_utime, &from->cpt_si_utime,
+ sizeof (to_nat.cpt_si_utime));
+ memcpy (&to_nat.cpt_si_stime, &from->cpt_si_stime,
+ sizeof (to_nat.cpt_si_stime));
break;
case SIGILL:
case SIGFPE:
case SIGSEGV:
case SIGBUS:
- to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
+ to_nat.cpt_si_addr = (void *) (intptr_t) from->cpt_si_addr;
break;
case SIGPOLL:
- to->si_band = from->cpt_si_band;
- to->si_fd = from->cpt_si_fd;
+ to_nat.cpt_si_band = from->cpt_si_band;
+ to_nat.cpt_si_fd = from->cpt_si_fd;
break;
default:
- to->si_pid = from->cpt_si_pid;
- to->si_uid = from->cpt_si_uid;
- to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
+ to_nat.cpt_si_pid = from->cpt_si_pid;
+ to_nat.cpt_si_uid = from->cpt_si_uid;
+ to_nat.cpt_si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
break;
}
}
+ memcpy (to, &to_nat, sizeof (to_nat));
}
/* Convert a native/host siginfo object, into/from the siginfo in the
--
2.1.4
next prev parent reply other threads:[~2015-12-17 16:57 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-17 16:57 [PATCH V2 1/5] Merges gdb and gdbserver implementation for siginfo Walfred Tedeschi
2015-12-17 16:57 ` [PATCH V2 3/5] Use linux_get_siginfo_type_with_fields for x86 Walfred Tedeschi
2015-12-18 12:55 ` Pedro Alves
2015-12-17 16:57 ` Walfred Tedeschi [this message]
2015-12-18 14:43 ` [PATCH V2 5/5] Adapt siginfo fixup for the new bnd fields Pedro Alves
2015-12-18 14:53 ` Tedeschi, Walfred
2015-12-17 16:57 ` [PATCH V2 4/5] Add bound related fields to the siginfo structure Walfred Tedeschi
2015-12-18 13:11 ` Pedro Alves
2015-12-17 16:57 ` [PATCH V2 2/5] Preparation for new siginfo on Linux Walfred Tedeschi
2015-12-18 12:39 ` Pedro Alves
2015-12-18 12:25 ` [PATCH V2 1/5] Merges gdb and gdbserver implementation for siginfo Pedro Alves
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1450371416-24270-5-git-send-email-walfred.tedeschi@intel.com \
--to=walfred.tedeschi@intel.com \
--cc=brobecker@adacore.com \
--cc=gdb-patches@sourceware.org \
--cc=palves@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox