From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 81688 invoked by alias); 18 Jan 2016 08:26:11 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 81612 invoked by uid 89); 18 Jan 2016 08:26:10 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.3 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=H*r:sk:wtedesc, intptr_t, sk:ptrace_, sk:PTRACE_ X-HELO: mga03.intel.com Received: from mga03.intel.com (HELO mga03.intel.com) (134.134.136.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 18 Jan 2016 08:25:57 +0000 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP; 18 Jan 2016 00:25:54 -0800 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga003.jf.intel.com with ESMTP; 18 Jan 2016 00:25:52 -0800 Received: from ulvlx001.iul.intel.com (ulvlx001.iul.intel.com [172.28.207.17]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id u0I8PpOk009202; Mon, 18 Jan 2016 08:25:52 GMT Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id u0I8PpHd031058; Mon, 18 Jan 2016 09:25:51 +0100 Received: (from wtedesch@localhost) by ulvlx001.iul.intel.com with œ id u0I8PpAO031054; Mon, 18 Jan 2016 09:25:51 +0100 From: Walfred Tedeschi To: palves@redhat.com, eliz@gnu.org, brobecker@adacore.com Cc: gdb-patches@sourceware.org, Walfred Tedeschi Subject: [PATCH V3 5/6] Adaptation of siginfo fixup for the new bnd fields. Date: Mon, 18 Jan 2016 08:26:00 -0000 Message-Id: <1453105544-30866-6-git-send-email-walfred.tedeschi@intel.com> In-Reply-To: <1453105544-30866-1-git-send-email-walfred.tedeschi@intel.com> References: <1453105544-30866-1-git-send-email-walfred.tedeschi@intel.com> X-IsSubscribed: yes X-SW-Source: 2016-01/txt/msg00366.txt.bz2 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-01-15 Walfred Tedeschi gdb/ChangeLog: * amd64-linux-siginfo.c (nat_siginfo_t, nat_sigval_t, nat_timeval): New types. (compat_siginfo): New bound 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 | 312 ++++++++++++++++++++++++++++-------------- gdb/nat/amd64-linux-siginfo.h | 16 ++- 2 files changed, 226 insertions(+), 102 deletions(-) diff --git a/gdb/nat/amd64-linux-siginfo.c b/gdb/nat/amd64-linux-siginfo.c index 7045ff2..ac5c138 100644 --- a/gdb/nat/amd64-linux-siginfo.c +++ b/gdb/nat/amd64-linux-siginfo.c @@ -21,6 +21,93 @@ #include "common-defs.h" #include "amd64-linux-siginfo.h" +/* 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 support. */ @@ -91,6 +178,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 */ @@ -152,6 +245,7 @@ typedef struct compat_x32_siginfo struct { unsigned int _addr; + unsigned int _addr_lsb; } _sigfault; /* SIGPOLL */ @@ -174,6 +268,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 @@ -190,54 +285,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; } } @@ -247,57 +346,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. */ @@ -305,56 +409,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; } } @@ -365,59 +473,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 diff --git a/gdb/nat/amd64-linux-siginfo.h b/gdb/nat/amd64-linux-siginfo.h index 11738fb..e6de70b 100644 --- a/gdb/nat/amd64-linux-siginfo.h +++ b/gdb/nat/amd64-linux-siginfo.h @@ -20,12 +20,24 @@ #ifndef AMD64_LINUX_SIGINFO_H #define AMD64_LINUX_SIGINFO_H 1 - /* When GDB is built as a 64-bit application on linux, the PTRACE_GETSIGINFO data is always presented in 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 do the 32-bit <-> 64-bit - conversion in-place ourselves. */ + conversion in-place ourselves. + In other to make this conversion independent of the system where gdb + is compiled the most complete version of the siginfo, named as native + siginfo, is used internally as an intermediate step. + + Conversion using nat_siginfo is exemplified below: + compat_siginfo_from_siginfo or compat_x32_siginfo_from_siginfo + + buffer (from the kernel) -> nat_siginfo -> 32 / X32 siginfo + + siginfo_from_compat_x32_siginfo or siginfo_from_compat_siginfo + + 32 / X32 siginfo -> nat_siginfo -> buffer (to the kernel) */ + /* Kind of siginfo fixup to be performed. */ -- 2.1.4