From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23087 invoked by alias); 11 May 2012 20:11:38 -0000 Received: (qmail 23072 invoked by uid 22791); 11 May 2012 20:11:36 -0000 X-SWARE-Spam-Status: No, hits=-2.8 required=5.0 tests=AWL,BAYES_00,KHOP_THREADED,T_FRT_SLUT,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from sibelius.xs4all.nl (HELO glazunov.sibelius.xs4all.nl) (83.163.83.176) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 11 May 2012 20:11:11 +0000 Received: from glazunov.sibelius.xs4all.nl (kettenis@localhost [127.0.0.1]) by glazunov.sibelius.xs4all.nl (8.14.5/8.14.3) with ESMTP id q4BKB7Oa007022; Fri, 11 May 2012 22:11:07 +0200 (CEST) Received: (from kettenis@localhost) by glazunov.sibelius.xs4all.nl (8.14.5/8.14.3/Submit) id q4BKB5Mi012054; Fri, 11 May 2012 22:11:05 +0200 (CEST) Date: Fri, 11 May 2012 20:11:00 -0000 Message-Id: <201205112011.q4BKB5Mi012054@glazunov.sibelius.xs4all.nl> From: Mark Kettenis To: hjl.tools@gmail.com CC: gdb-patches@sourceware.org In-reply-to: <20120511192133.GA4947@intel.com> (hongjiu.lu@intel.com) Subject: Re: PATCH: Support x32 siginfo_t conversion References: <20120511192133.GA4947@intel.com> 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 X-SW-Source: 2012-05/txt/msg00444.txt.bz2 > Date: Fri, 11 May 2012 12:21:33 -0700 > From: "H.J. Lu" > > Hi, > > This patch implements x32 siginfo_t conversion. Tested on Linux/x86-64. > OK to install? > > Thanks. > > > H.J. > -- > * amd64-linux-nat.c (compat_x32_clock_t): New. > (compat_x32_siginfo_t): Likewise. > (compat_x32_siginfo_from_siginfo): Likewise. > (siginfo_from_compat_x32_siginfo): Likewise. > (amd64_linux_siginfo_fixup): Call compat_x32_siginfo_from_siginfo > and siginfo_from_compat_x32_siginfo for x32. > > diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c > index 3be8404..97c9a49 100644 > --- a/gdb/amd64-linux-nat.c > +++ b/gdb/amd64-linux-nat.c > @@ -591,6 +591,67 @@ typedef struct compat_siginfo > } _sifields; > } compat_siginfo_t; > > +/* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes. */ > +typedef long __attribute__ ((__aligned__ (4))) compat_x32_clock_t; Sorry, but that isn't acceptable. Is your X32 ABI really that broken? > +typedef struct compat_x32_siginfo > +{ > + int si_signo; > + int si_errno; > + int si_code; > + > + union > + { > + int _pad[((128 / sizeof (int)) - 3)]; > + > + /* kill() */ > + struct > + { > + unsigned int _pid; > + unsigned int _uid; > + } _kill; > + > + /* POSIX.1b timers */ > + struct > + { > + compat_timer_t _tid; > + int _overrun; > + compat_sigval_t _sigval; > + } _timer; > + > + /* POSIX.1b signals */ > + struct > + { > + unsigned int _pid; > + unsigned int _uid; > + compat_sigval_t _sigval; > + } _rt; > + > + /* SIGCHLD */ > + struct > + { > + unsigned int _pid; > + unsigned int _uid; > + int _status; > + compat_x32_clock_t _utime; > + compat_x32_clock_t _stime; > + } _sigchld; > + > + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ > + struct > + { > + unsigned int _addr; > + } _sigfault; > + > + /* SIGPOLL */ > + struct > + { > + int _band; > + int _fd; > + } _sigpoll; > + } _sifields; > +} compat_x32_siginfo_t __attribute__ ((__aligned__ (8))); Same here. I don't think you need alignment here, even with the broken ABI. If it really is too late to fix the X32 ABI, you'll have to write this portably by splitting _utime and _stime into two 32-bit variables and write code that correctly sets the upper and lower 32-bits. > + > #define cpt_si_pid _sifields._kill._pid > #define cpt_si_uid _sifields._kill._uid > #define cpt_si_timerid _sifields._timer._tid > @@ -724,6 +785,120 @@ siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from) > } > } > > +static void > +compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to, > + siginfo_t *from) > +{ > + memset (to, 0, sizeof (*to)); > + > + to->si_signo = from->si_signo; > + to->si_errno = from->si_errno; > + to->si_code = from->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; > + } > + else if (to->si_code == SI_USER) > + { > + to->cpt_si_pid = from->si_pid; > + to->cpt_si_uid = from->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; > + } > + 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; > + break; > + case SIGILL: > + case SIGFPE: > + case SIGSEGV: > + case SIGBUS: > + to->cpt_si_addr = (intptr_t) from->si_addr; > + break; > + case SIGPOLL: > + to->cpt_si_band = from->si_band; > + to->cpt_si_fd = from->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; > + break; > + } > + } > +} > + > +static void > +siginfo_from_compat_x32_siginfo (siginfo_t *to, > + compat_x32_siginfo_t *from) > +{ > + memset (to, 0, sizeof (*to)); > + > + to->si_signo = from->si_signo; > + to->si_errno = from->si_errno; > + to->si_code = from->si_code; > + > + if (to->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; > + } > + else if (to->si_code == SI_USER) > + { > + to->si_pid = from->cpt_si_pid; > + to->si_uid = from->cpt_si_uid; > + } > + if (to->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; > + } > + else > + { > + switch (to->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; > + break; > + case SIGILL: > + case SIGFPE: > + case SIGSEGV: > + case SIGBUS: > + to->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; > + 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; > + break; > + } > + } > +} > + > /* Convert a native/host siginfo object, into/from the siginfo in the > layout of the inferiors' architecture. Returns true if any > conversion was done; false otherwise. If DIRECTION is 1, then copy > @@ -747,6 +922,20 @@ amd64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction) > > return 1; > } > + /* No fixup for native x32 GDB. */ > + else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8) > + { > + gdb_assert (sizeof (siginfo_t) == sizeof (compat_x32_siginfo_t)); > + > + if (direction == 0) > + compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo *) inf, > + native); > + else > + siginfo_from_compat_x32_siginfo (native, > + (struct compat_x32_siginfo *) inf); > + > + return 1; > + } > else > return 0; > } >