From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 56495 invoked by alias); 8 Sep 2015 16:38:33 -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 56482 invoked by uid 89); 8 Sep 2015 16:38:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.5 required=5.0 tests=AWL,BAYES_99,BAYES_999,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS,UNSUBSCRIBE_BODY autolearn=no version=3.3.2 X-HELO: mail-la0-f52.google.com Received: from mail-la0-f52.google.com (HELO mail-la0-f52.google.com) (209.85.215.52) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 08 Sep 2015 16:38:31 +0000 Received: by lagj9 with SMTP id j9so74001278lag.2 for ; Tue, 08 Sep 2015 09:38:28 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.152.120.198 with SMTP id le6mr23619719lab.38.1441730307882; Tue, 08 Sep 2015 09:38:27 -0700 (PDT) Received: by 10.25.160.197 with HTTP; Tue, 8 Sep 2015 09:38:27 -0700 (PDT) In-Reply-To: <1441729817-17413-1-git-send-email-yao.qi@linaro.org> References: <1441729817-17413-1-git-send-email-yao.qi@linaro.org> Date: Tue, 08 Sep 2015 16:38:00 -0000 Message-ID: Subject: Re: [PATCH] aarch64 multi-arch support (part 2): siginfo fixup From: Andrew Pinski To: Yao Qi Cc: "gdb-patches@sourceware.org" Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2015-09/txt/msg00097.txt.bz2 On Wed, Sep 9, 2015 at 12:30 AM, Yao Qi wrote: > This patch is to fixup the siginfo_t when aarch64 gdb or gdbserver > read from or write to the arm inferior. It is to convert the > "struct siginfo_t" between aarch64(64-bit) and arm(32-bit), which is > quite mechanical. > > Regression tested on aarch64-linux, both native and gdbserver. > > gdb/gdbserver: > > 2015-09-08 Yao Qi > > * linux-aarch64-low.c (aarch64_linux_siginfo_fixup): New > function. > (struct linux_target_ops the_low_target): Install > aarch64_linux_siginfo_fixup. > > gdb: > > 2015-09-08 Yao Qi > > * aarch64-linux-nat.c (aarch64_linux_siginfo_fixup): New function. > (_initialize_aarch64_linux_nat): Call linux_nat_set_siginfo_fixup. > * nat/aarch64-linux.c (aarch64_compat_siginfo_from_siginfo): > New function. > (aarch64_siginfo_from_compat_siginfo): New function. > * nat/aarch64-linux.h: Include signal.h. > (compat_int_t, compat_uptr_t, compat_time_t): Typedef. > (compat_timer_t, compat_clock_t): Likewise. > (struct compat_timeval): New. > (union compat_sigval): New. > (struct compat_siginfo): New. > (cpt_si_pid, cpt_si_uid, cpt_si_timerid): New macros. > (cpt_si_overrun, cpt_si_status, cpt_si_utime): Likewise. > (cpt_si_stime, cpt_si_ptr, cpt_si_addr): Likewise. > (cpt_si_band, cpt_si_fd): Likewise. > --- > gdb/aarch64-linux-nat.c | 31 ++++++++++ > gdb/gdbserver/linux-aarch64-low.c | 23 +++++++- > gdb/nat/aarch64-linux.c | 117 ++++++++++++++++++++++++++++++++++++++ > gdb/nat/aarch64-linux.h | 96 +++++++++++++++++++++++++++++++ > 4 files changed, 266 insertions(+), 1 deletion(-) > > diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c > index 673817e..d7ac19e 100644 > --- a/gdb/aarch64-linux-nat.c > +++ b/gdb/aarch64-linux-nat.c > @@ -543,6 +543,34 @@ aarch64_linux_read_description (struct target_ops *ops) > return tdesc_aarch64; > } > > +/* 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 > + from INF to NATIVE. If DIRECTION is 0, copy from NATIVE to > + INF. */ > + > +static int > +aarch64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction) > +{ > + struct gdbarch *gdbarch = get_frame_arch (get_current_frame ()); > + > + /* Is the inferior 32-bit? If so, then do fixup the siginfo > + object. */ > + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32) > + { > + if (direction == 0) > + aarch64_compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, > + native); > + else > + aarch64_siginfo_from_compat_siginfo (native, > + (struct compat_siginfo *) inf); > + > + return 1; > + } This might fix the issue I having with ILP32 and siginfo. Though it might be still broken since time_t is 64bit for ILP32 (at least the current definition). Thanks, Andrew > + > + return 0; > +} > + > /* Returns the number of hardware watchpoints of type TYPE that we can > set. Value is positive if we can set CNT watchpoints, zero if > setting watchpoints of type TYPE is not supported, and negative if > @@ -850,4 +878,7 @@ _initialize_aarch64_linux_nat (void) > linux_nat_set_new_fork (t, aarch64_linux_new_fork); > linux_nat_set_forget_process (t, aarch64_forget_process); > linux_nat_set_prepare_to_resume (t, aarch64_linux_prepare_to_resume); > + > + /* Add our siginfo layout converter. */ > + linux_nat_set_siginfo_fixup (t, aarch64_linux_siginfo_fixup); > } > diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c > index aebf1e3..73b248c 100644 > --- a/gdb/gdbserver/linux-aarch64-low.c > +++ b/gdb/gdbserver/linux-aarch64-low.c > @@ -430,6 +430,27 @@ ps_get_thread_area (const struct ps_prochandle *ph, > return PS_OK; > } > > +/* Implementation of linux_target_ops method "siginfo_fixup". */ > + > +static int > +aarch64_linux_siginfo_fixup (siginfo_t *native, void *inf, int direction) > +{ > + /* Is the inferior 32-bit? If so, then fixup the siginfo object. */ > + if (!is_64bit_tdesc ()) > + { > + if (direction == 0) > + aarch64_compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, > + native); > + else > + aarch64_siginfo_from_compat_siginfo (native, > + (struct compat_siginfo *) inf); > + > + return 1; > + } > + > + return 0; > +} > + > /* Implementation of linux_target_ops method "linux_new_process". */ > > static struct arch_process_info * > @@ -581,7 +602,7 @@ struct linux_target_ops the_low_target = > aarch64_stopped_data_address, > NULL, /* collect_ptrace_register */ > NULL, /* supply_ptrace_register */ > - NULL, /* siginfo_fixup */ > + aarch64_linux_siginfo_fixup, > aarch64_linux_new_process, > aarch64_linux_new_thread, > aarch64_linux_new_fork, > diff --git a/gdb/nat/aarch64-linux.c b/gdb/nat/aarch64-linux.c > index ba94b00..0634094 100644 > --- a/gdb/nat/aarch64-linux.c > +++ b/gdb/nat/aarch64-linux.c > @@ -78,3 +78,120 @@ aarch64_linux_new_thread (struct lwp_info *lwp) > > lwp_set_arch_private_info (lwp, info); > } > + > +/* Convert native siginfo FROM to the siginfo in the layout of the > + inferior's architecture TO. */ > + > +void > +aarch64_compat_siginfo_from_siginfo (compat_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; > + } > + } > +} > + > +/* Convert inferior's architecture siginfo FROM to native siginfo TO. */ > + > +void > +aarch64_siginfo_from_compat_siginfo (siginfo_t *to, compat_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; > + } > + } > +} > diff --git a/gdb/nat/aarch64-linux.h b/gdb/nat/aarch64-linux.h > index 5cb432c..89eb4e3 100644 > --- a/gdb/nat/aarch64-linux.h > +++ b/gdb/nat/aarch64-linux.h > @@ -19,6 +19,102 @@ > #ifndef AARCH64_LINUX_H > #define AARCH64_LINUX_H 1 > > +#include > + > +typedef int compat_int_t; > +typedef unsigned int compat_uptr_t; > + > +typedef int compat_time_t; > +typedef int compat_timer_t; > +typedef int compat_clock_t; > + > +struct compat_timeval > +{ > + compat_time_t tv_sec; > + int tv_usec; > +}; > + > +typedef union compat_sigval > +{ > + compat_int_t sival_int; > + compat_uptr_t sival_ptr; > +} compat_sigval_t; > + > +typedef struct compat_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_clock_t _utime; > + compat_clock_t _stime; > + } _sigchld; > + > + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ > + struct > + { > + unsigned int _addr; > + } _sigfault; > + > + /* SIGPOLL */ > + struct > + { > + int _band; > + int _fd; > + } _sigpoll; > + } _sifields; > +} compat_siginfo_t; > + > +#define cpt_si_pid _sifields._kill._pid > +#define cpt_si_uid _sifields._kill._uid > +#define cpt_si_timerid _sifields._timer._tid > +#define cpt_si_overrun _sifields._timer._overrun > +#define cpt_si_status _sifields._sigchld._status > +#define cpt_si_utime _sifields._sigchld._utime > +#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_band _sifields._sigpoll._band > +#define cpt_si_fd _sifields._sigpoll._fd > + > +void aarch64_siginfo_from_compat_siginfo (siginfo_t *to, > + compat_siginfo_t *from); > +void aarch64_compat_siginfo_from_siginfo (compat_siginfo_t *to, > + siginfo_t *from); > + > void aarch64_linux_prepare_to_resume (struct lwp_info *lwp); > > void aarch64_linux_new_thread (struct lwp_info *lwp); > -- > 1.9.1 >