From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10965 invoked by alias); 13 May 2012 02:25:46 -0000 Received: (qmail 10950 invoked by uid 22791); 13 May 2012 02:25:44 -0000 X-SWARE-Spam-Status: No, hits=-4.9 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,KHOP_RCVD_TRUST,KHOP_THREADED,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE,TW_CP,T_FRT_SLUT X-Spam-Check-By: sourceware.org Received: from mail-qa0-f48.google.com (HELO mail-qa0-f48.google.com) (209.85.216.48) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 13 May 2012 02:25:30 +0000 Received: by qady23 with SMTP id y23so2867033qad.14 for ; Sat, 12 May 2012 19:25:29 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.137.20 with SMTP id u20mr1669322qct.9.1336875929586; Sat, 12 May 2012 19:25:29 -0700 (PDT) Received: by 10.229.169.130 with HTTP; Sat, 12 May 2012 19:25:29 -0700 (PDT) In-Reply-To: References: <20120511192133.GA4947@intel.com> <201205112011.q4BKB5Mi012054@glazunov.sibelius.xs4all.nl> <201205122116.q4CLG6lN019181@glazunov.sibelius.xs4all.nl> Date: Sun, 13 May 2012 02:25:00 -0000 Message-ID: Subject: Re: PATCH: Support x32 siginfo_t conversion From: "H.J. Lu" To: Mark Kettenis Cc: gdb-patches@sourceware.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes 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/msg00489.txt.bz2 On Sat, May 12, 2012 at 4:15 PM, H.J. Lu wrote: > On Sat, May 12, 2012 at 2:16 PM, Mark Kettenis = wrote: >>> Date: Fri, 11 May 2012 13:55:29 -0700 >>> From: "H.J. Lu" >>> >>> On Fri, May 11, 2012 at 1:11 PM, Mark Kettenis wrote: >>> >> Date: Fri, 11 May 2012 12:21:33 -0700 >>> >> From: "H.J. Lu" >>> >> >>> >> Hi, >>> >> >>> >> This patch implements x32 siginfo_t conversion. =A0Tested on Linux/x= 86-64. >>> >> OK to install? >>> >> >>> >> Thanks. >>> >> >>> >> >>> >> H.J. >>> >>> X32 ABI choice is done on purpose. =A0X32 siginfo_t has >>> >>> typedef long __attribute__ ((__aligned__ (4))) compat_x32_clock_t; >>> >>> typedef struct compat_x32_siginfo >>> { >>> =A0 int si_signo; >>> =A0 int si_errno; >>> =A0 int si_code; >>> >>> =A0 union >>> =A0 { >>> ... >>> =A0 =A0 /* SIGCHLD */ >>> =A0 =A0 struct >>> =A0 =A0 { >>> =A0 =A0 =A0 unsigned int _pid; >>> =A0 =A0 =A0 unsigned int _uid; >>> =A0 =A0 =A0 int _status; >>> =A0 =A0 =A0 compat_x32_clock_t _utime; >>> =A0 =A0 =A0 compat_x32_clock_t _stime; >>> =A0 =A0 } _sigchld; >>> ... >>> } compat_x32_siginfo_t __attribute__ ((__aligned__ (8))); >>> >>> struct info is aligned at 8 bytes and type of _utime/_stime is aligned >>> at 4 bytes. =A0However, =A0_utime offset is 3 * 4 + 3 * 4 =3D=3D 24 byt= es. So >>> in reality, the addresses of _utime/_stime are 8 bytes aligned. =A0There >>> are no needs to split _utime and _stime into two 32-bit variables >>> since their addresses are 64bits aligned. >> >> But there is no way you can easily express that syntax with standard C >> syntax[1]. =A0That's why you had to resort to using GCC's __attribute__ >> syntax. =A0For GDB you'll have to figure out a way to do this without >> using __attribute__ ((__aligned__ (...))). >> >> My recommendation would be to define a compat_x32 structure just for >> SIGCHLD (without using a union) and use the normal 32-bit comap >> structure for all the other conversions. >> > > This is in amd64-linux-nat.c. =A0All native Linux/amd64 compilers support > __attribute__ ((__aligned__ (...))). =A0 =A0In any case, I will use a str= uct with > 2 ints. > > Thanks. > Here is the updated patch. OK to install? Thanks. --=20 H.J. --- diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index 5ebba3a..bc28d54 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -591,6 +591,71 @@ typedef struct compat_siginfo } _sifields; } compat_siginfo_t; +/* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes. */ +typedef struct compat_x32_clock +{ + int lower; + int upper; +} compat_x32_clock_t; + +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; + #define cpt_si_pid _sifields._kill._pid #define cpt_si_uid _sifields._kill._uid #define cpt_si_timerid _sifields._timer._tid @@ -724,6 +789,124 @@ 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 =3D from->si_signo; + to->si_errno =3D from->si_errno; + to->si_code =3D from->si_code; + + if (to->si_code =3D=3D SI_TIMER) + { + to->cpt_si_timerid =3D from->si_timerid; + to->cpt_si_overrun =3D from->si_overrun; + to->cpt_si_ptr =3D (intptr_t) from->si_ptr; + } + else if (to->si_code =3D=3D SI_USER) + { + to->cpt_si_pid =3D from->si_pid; + to->cpt_si_uid =3D from->si_uid; + } + else if (to->si_code < 0) + { + to->cpt_si_pid =3D from->si_pid; + to->cpt_si_uid =3D from->si_uid; + to->cpt_si_ptr =3D (intptr_t) from->si_ptr; + } + else + { + switch (to->si_signo) + { + case SIGCHLD: + to->cpt_si_pid =3D from->si_pid; + to->cpt_si_uid =3D from->si_uid; + to->cpt_si_status =3D from->si_status; + memcpy (&to->cpt_si_utime, &from->si_utime, + sizeof (to->cpt_si_utime)); + memcpy (&to->cpt_si_stime, &from->si_stime, + sizeof (to->cpt_si_stime)); + break; + case SIGILL: + case SIGFPE: + case SIGSEGV: + case SIGBUS: + to->cpt_si_addr =3D (intptr_t) from->si_addr; + break; + case SIGPOLL: + to->cpt_si_band =3D from->si_band; + to->cpt_si_fd =3D from->si_fd; + break; + default: + to->cpt_si_pid =3D from->si_pid; + to->cpt_si_uid =3D from->si_uid; + to->cpt_si_ptr =3D (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 =3D from->si_signo; + to->si_errno =3D from->si_errno; + to->si_code =3D from->si_code; + + if (to->si_code =3D=3D SI_TIMER) + { + to->si_timerid =3D from->cpt_si_timerid; + to->si_overrun =3D from->cpt_si_overrun; + to->si_ptr =3D (void *) (intptr_t) from->cpt_si_ptr; + } + else if (to->si_code =3D=3D SI_USER) + { + to->si_pid =3D from->cpt_si_pid; + to->si_uid =3D from->cpt_si_uid; + } + if (to->si_code < 0) + { + to->si_pid =3D from->cpt_si_pid; + to->si_uid =3D from->cpt_si_uid; + to->si_ptr =3D (void *) (intptr_t) from->cpt_si_ptr; + } + else + { + switch (to->si_signo) + { + case SIGCHLD: + to->si_pid =3D from->cpt_si_pid; + to->si_uid =3D from->cpt_si_uid; + to->si_status =3D 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)); + break; + case SIGILL: + case SIGFPE: + case SIGSEGV: + case SIGBUS: + to->si_addr =3D (void *) (intptr_t) from->cpt_si_addr; + break; + case SIGPOLL: + to->si_band =3D from->cpt_si_band; + to->si_fd =3D from->cpt_si_fd; + break; + default: + to->si_pid =3D from->cpt_si_pid; + to->si_uid =3D from->cpt_si_uid; + to->si_ptr =3D (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 @@ -733,9 +916,10 @@ siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from) static int amd64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction) { + struct gdbarch *gdbarch =3D get_frame_arch (get_current_frame ()); /* Is the inferior 32-bit? If so, then do fixup the siginfo object. */ - if (gdbarch_addr_bit (get_frame_arch (get_current_frame ())) =3D=3D 32) + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word =3D=3D 32) { gdb_assert (sizeof (siginfo_t) =3D=3D sizeof (compat_siginfo_t)); @@ -746,6 +930,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) =3D=3D 32 && sizeof (void *) =3D=3D = 8) + { + gdb_assert (sizeof (siginfo_t) =3D=3D sizeof (compat_x32_siginfo_t)); + + if (direction =3D=3D 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; }