From: Sergio Durigan Junior Date: Fri, 9 Aug 2013 16:54:43 +0000 (+0000) Subject: This patch implements the new gdbarch method gdbarch_gdb_signal_to_target. X-Git-Tag: binutils-2_24-branchpoint~309 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eb14d4068893a301911485d732b4ae961c34e532;p=thirdparty%2Fbinutils-gdb.git This patch implements the new gdbarch method gdbarch_gdb_signal_to_target. It will be used when one wants to convert between the internal GDB signal representation (enum gdb_signal) and the target's representation. The idea of this patch came from a chat between Pedro and I on IRC, plus the discussion of my patches to add the new $_exitsignal convenience variable: What I did was to investigate, on the Linux kernel, which targets shared the signal numbers definition with the generic definition, present at . For the record, I used linux-3.10-rc7 as the main source of information, always looking at /include/uapi/asm/signal.h>. For SIGRTMAX (which defaults to _NSIG in most cases), I had to look at different signal-related files, but most of them (except MIPS) were defined to 64 anyway. Then, with all the differences in hand, I implemented the bits on each target. 2013-08-09 Sergio Durigan Junior * linux-tdep.c: Define enum with generic signal numbers. (linux_gdb_signal_from_target): New function. (linux_gdb_signal_to_target): Likewise. (linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target methods to the functions above. * linux-tdep.h (linux_gdb_signal_from_target): New prototype. (linux_gdb_signal_to_target): Likewise. * alpha-linux-tdep.c: Define new enum with signals different from generic Linux kernel. (alpha_linux_gdb_signal_from_target): New function. (alpha_linux_gdb_signal_to_target): Likewise. (alpha_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target with the functions mentioned above. * avr-tdep.c: Define enum with differences between Linux kernel and AVR signals. (avr_linux_gdb_signal_from_target): New function. (avr_linux_gdb_signal_to_target): Likewise. (avr_gdbarch_init): Set gdbarch_gdb_signal_{to,from}_target to the functions mentioned above. * sparc-linux-tdep.c: Define enum with differences between SPARC and generic Linux kernel signal numbers. (sparc32_linux_gdb_signal_from_target): New function. (sparc32_linux_gdb_signal_to_target): Likewise. (sparc32_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target to the functions defined above. * xtensa-linux-tdep.c: Define enum with differences between Xtensa and Linux kernel generic signals. (xtensa_linux_gdb_signal_from_target): New function. (xtensa_linux_gdb_signal_to_target): Likewise. (xtensa_linux_init_abi): Set gdbarch_gdb_signal_to_target to the functions defined above. * mips-linux-tdep.c: Define enum with differences between signals in MIPS and Linux kernel generic ones. (mips_gdb_signal_to_target): New function. (mips_gdb_signal_from_target): Redefine to use new enum, handle only different signals from the Linux kernel generic. (mips_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target the functions defined above. * mips-linux-tdep.h (enum mips_signals): Remove. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 469678f0e56..9e99003ca65 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,45 @@ +2013-08-09 Sergio Durigan Junior + + * linux-tdep.c: Define enum with generic signal numbers. + (linux_gdb_signal_from_target): New function. + (linux_gdb_signal_to_target): Likewise. + (linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target + methods to the functions above. + * linux-tdep.h (linux_gdb_signal_from_target): New prototype. + (linux_gdb_signal_to_target): Likewise. + * alpha-linux-tdep.c: Define new enum with signals different + from generic Linux kernel. + (alpha_linux_gdb_signal_from_target): New function. + (alpha_linux_gdb_signal_to_target): Likewise. + (alpha_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target + with the functions mentioned above. + * avr-tdep.c: Define enum with differences between Linux kernel + and AVR signals. + (avr_linux_gdb_signal_from_target): New function. + (avr_linux_gdb_signal_to_target): Likewise. + (avr_gdbarch_init): Set gdbarch_gdb_signal_{to,from}_target to + the functions mentioned above. + * sparc-linux-tdep.c: Define enum with differences between SPARC + and generic Linux kernel signal numbers. + (sparc32_linux_gdb_signal_from_target): New function. + (sparc32_linux_gdb_signal_to_target): Likewise. + (sparc32_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target + to the functions defined above. + * xtensa-linux-tdep.c: Define enum with differences between + Xtensa and Linux kernel generic signals. + (xtensa_linux_gdb_signal_from_target): New function. + (xtensa_linux_gdb_signal_to_target): Likewise. + (xtensa_linux_init_abi): Set gdbarch_gdb_signal_to_target + to the functions defined above. + * mips-linux-tdep.c: Define enum with differences between + signals in MIPS and Linux kernel generic ones. + (mips_gdb_signal_to_target): New function. + (mips_gdb_signal_from_target): Redefine to use new enum, handle + only different signals from the Linux kernel generic. + (mips_linux_init_abi): Set gdbarch_gdb_signal_{to,from}_target + the functions defined above. + * mips-linux-tdep.h (enum mips_signals): Remove. + 2013-08-09 Pedro Alves * avr-tdep.c (XMALLOC): Delete macro. diff --git a/gdb/alpha-linux-tdep.c b/gdb/alpha-linux-tdep.c index 9efc5bd6fe9..8cb087ee476 100644 --- a/gdb/alpha-linux-tdep.c +++ b/gdb/alpha-linux-tdep.c @@ -28,6 +28,35 @@ #include "linux-tdep.h" #include "alpha-tdep.h" +/* This enum represents the signals' numbers on the Alpha + architecture. It just contains the signal definitions which are + different from the generic implementation. + + It is derived from the file , + from the Linux kernel tree. */ + +enum + { + /* SIGABRT is the same as in the generic implementation, but is + defined here because SIGIOT depends on it. */ + ALPHA_LINUX_SIGABRT = 6, + ALPHA_LINUX_SIGEMT = 7, + ALPHA_LINUX_SIGBUS = 10, + ALPHA_LINUX_SIGSYS = 12, + ALPHA_LINUX_SIGURG = 16, + ALPHA_LINUX_SIGSTOP = 17, + ALPHA_LINUX_SIGTSTP = 18, + ALPHA_LINUX_SIGCONT = 19, + ALPHA_LINUX_SIGCHLD = 20, + ALPHA_LINUX_SIGIO = 23, + ALPHA_LINUX_SIGINFO = 29, + ALPHA_LINUX_SIGUSR1 = 30, + ALPHA_LINUX_SIGUSR2 = 31, + ALPHA_LINUX_SIGPOLL = ALPHA_LINUX_SIGIO, + ALPHA_LINUX_SIGPWR = ALPHA_LINUX_SIGINFO, + ALPHA_LINUX_SIGIOT = ALPHA_LINUX_SIGABRT, + }; + /* Under GNU/Linux, signal handler invocations can be identified by the designated code sequence that is used to return from a signal handler. In particular, the return address of a signal handler @@ -205,6 +234,114 @@ alpha_linux_regset_from_core_section (struct gdbarch *gdbarch, return NULL; } +/* Implementation of `gdbarch_gdb_signal_from_target', as defined in + gdbarch.h. */ + +static enum gdb_signal +alpha_linux_gdb_signal_from_target (struct gdbarch *gdbarch, + int signal) +{ + switch (signal) + { + case ALPHA_LINUX_SIGEMT: + return GDB_SIGNAL_EMT; + + case ALPHA_LINUX_SIGBUS: + return GDB_SIGNAL_BUS; + + case ALPHA_LINUX_SIGSYS: + return GDB_SIGNAL_SYS; + + case ALPHA_LINUX_SIGURG: + return GDB_SIGNAL_URG; + + case ALPHA_LINUX_SIGSTOP: + return GDB_SIGNAL_STOP; + + case ALPHA_LINUX_SIGTSTP: + return GDB_SIGNAL_TSTP; + + case ALPHA_LINUX_SIGCONT: + return GDB_SIGNAL_CONT; + + case ALPHA_LINUX_SIGCHLD: + return GDB_SIGNAL_CHLD; + + /* No way to differentiate between SIGIO and SIGPOLL. + Therefore, we just handle the first one. */ + case ALPHA_LINUX_SIGIO: + return GDB_SIGNAL_IO; + + /* No way to differentiate between SIGINFO and SIGPWR. + Therefore, we just handle the first one. */ + case ALPHA_LINUX_SIGINFO: + return GDB_SIGNAL_INFO; + + case ALPHA_LINUX_SIGUSR1: + return GDB_SIGNAL_USR1; + + case ALPHA_LINUX_SIGUSR2: + return GDB_SIGNAL_USR2; + } + + return linux_gdb_signal_from_target (gdbarch, signal); +} + +/* Implementation of `gdbarch_gdb_signal_to_target', as defined in + gdbarch.h. */ + +static int +alpha_linux_gdb_signal_to_target (struct gdbarch *gdbarch, + enum gdb_signal signal) +{ + switch (signal) + { + case GDB_SIGNAL_EMT: + return ALPHA_LINUX_SIGEMT; + + case GDB_SIGNAL_BUS: + return ALPHA_LINUX_SIGBUS; + + case GDB_SIGNAL_SYS: + return ALPHA_LINUX_SIGSYS; + + case GDB_SIGNAL_URG: + return ALPHA_LINUX_SIGURG; + + case GDB_SIGNAL_STOP: + return ALPHA_LINUX_SIGSTOP; + + case GDB_SIGNAL_TSTP: + return ALPHA_LINUX_SIGTSTP; + + case GDB_SIGNAL_CONT: + return ALPHA_LINUX_SIGCONT; + + case GDB_SIGNAL_CHLD: + return ALPHA_LINUX_SIGCHLD; + + case GDB_SIGNAL_IO: + return ALPHA_LINUX_SIGIO; + + case GDB_SIGNAL_INFO: + return ALPHA_LINUX_SIGINFO; + + case GDB_SIGNAL_USR1: + return ALPHA_LINUX_SIGUSR1; + + case GDB_SIGNAL_USR2: + return ALPHA_LINUX_SIGUSR2; + + case GDB_SIGNAL_POLL: + return ALPHA_LINUX_SIGPOLL; + + case GDB_SIGNAL_PWR: + return ALPHA_LINUX_SIGPWR; + } + + return linux_gdb_signal_to_target (gdbarch, signal); +} + static void alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -236,6 +373,11 @@ alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_regset_from_core_section (gdbarch, alpha_linux_regset_from_core_section); + + set_gdbarch_gdb_signal_from_target (gdbarch, + alpha_linux_gdb_signal_from_target); + set_gdbarch_gdb_signal_to_target (gdbarch, + alpha_linux_gdb_signal_to_target); } /* Provide a prototype to silence -Wmissing-prototypes. */ diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index fc4e0f062df..6beac3d1bbb 100644 --- a/gdb/avr-tdep.c +++ b/gdb/avr-tdep.c @@ -36,6 +36,7 @@ #include "regcache.h" #include "gdb_string.h" #include "dis-asm.h" +#include "linux-tdep.h" /* AVR Background: @@ -190,6 +191,19 @@ struct gdbarch_tdep struct type *pc_type; }; +/* This enum represents the signals' numbers on the AVR + architecture. It just contains the signal definitions which are + different from the generic implementation. + + It is derived from the file , + from the Linux kernel tree. */ + +enum + { + AVR_LINUX_SIGRTMIN = 32, + AVR_LINUX_SIGRTMAX = 63, + }; + /* Lookup the name of a register given it's number. */ static const char * @@ -1341,6 +1355,60 @@ avr_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) return -1; } +/* Implementation of `gdbarch_gdb_signal_from_target', as defined in + gdbarch.h. */ + +static enum gdb_signal +avr_linux_gdb_signal_from_target (struct gdbarch *gdbarch, int signal) +{ + if (signal >= AVR_LINUX_SIGRTMIN && signal <= AVR_LINUX_SIGRTMAX) + { + int offset = signal - AVR_LINUX_SIGRTMIN; + + if (offset == 0) + return GDB_SIGNAL_REALTIME_32; + else + return (enum gdb_signal) (offset - 1 + + (int) GDB_SIGNAL_REALTIME_33); + } + else if (signal > AVR_LINUX_SIGRTMAX) + return GDB_SIGNAL_UNKNOWN; + + return linux_gdb_signal_from_target (gdbarch, signal); +} + +/* Implementation of `gdbarch_gdb_signal_to_target', as defined in + gdbarch.h. */ + +static int +avr_linux_gdb_signal_to_target (struct gdbarch *gdbarch, + enum gdb_signal signal) +{ + switch (signal) + { + /* GDB_SIGNAL_REALTIME_32 is not continuous in , + therefore we have to handle it here. */ + case GDB_SIGNAL_REALTIME_32: + return AVR_LINUX_SIGRTMIN; + + /* GDB_SIGNAL_REALTIME_64 is not valid on AVR. */ + case GDB_SIGNAL_REALTIME_64: + return -1; + } + + /* GDB_SIGNAL_REALTIME_33 to _63 are continuous. + AVR does not have _64. */ + if (signal >= GDB_SIGNAL_REALTIME_33 + && signal <= GDB_SIGNAL_REALTIME_63) + { + int offset = signal - GDB_SIGNAL_REALTIME_33; + + return AVR_LINUX_SIGRTMIN + 1 + offset; + } + + return linux_gdb_signal_to_target (gdbarch, signal); +} + /* Initialize the gdbarch structure for the AVR's. */ static struct gdbarch * @@ -1444,6 +1512,11 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_unwind_pc (gdbarch, avr_unwind_pc); set_gdbarch_unwind_sp (gdbarch, avr_unwind_sp); + set_gdbarch_gdb_signal_from_target (gdbarch, + avr_linux_gdb_signal_from_target); + set_gdbarch_gdb_signal_to_target (gdbarch, + avr_linux_gdb_signal_to_target); + return gdbarch; } diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index db35b40fae8..1f3380ed58f 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -261,6 +261,7 @@ struct gdbarch gdbarch_process_record_ftype *process_record; gdbarch_process_record_signal_ftype *process_record_signal; gdbarch_gdb_signal_from_target_ftype *gdb_signal_from_target; + gdbarch_gdb_signal_to_target_ftype *gdb_signal_to_target; gdbarch_get_siginfo_type_ftype *get_siginfo_type; gdbarch_record_special_symbol_ftype *record_special_symbol; gdbarch_get_syscall_number_ftype *get_syscall_number; @@ -433,6 +434,7 @@ struct gdbarch startup_gdbarch = 0, /* process_record */ 0, /* process_record_signal */ 0, /* gdb_signal_from_target */ + 0, /* gdb_signal_to_target */ 0, /* get_siginfo_type */ 0, /* record_special_symbol */ 0, /* get_syscall_number */ @@ -738,6 +740,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of process_record, has predicate. */ /* Skip verify of process_record_signal, has predicate. */ /* Skip verify of gdb_signal_from_target, has predicate. */ + /* Skip verify of gdb_signal_to_target, has predicate. */ /* Skip verify of get_siginfo_type, has predicate. */ /* Skip verify of record_special_symbol, has predicate. */ /* Skip verify of get_syscall_number, has predicate. */ @@ -1032,6 +1035,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) fprintf_unfiltered (file, "gdbarch_dump: gdb_signal_from_target = <%s>\n", host_address_to_string (gdbarch->gdb_signal_from_target)); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_gdb_signal_to_target_p() = %d\n", + gdbarch_gdb_signal_to_target_p (gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: gdb_signal_to_target = <%s>\n", + host_address_to_string (gdbarch->gdb_signal_to_target)); fprintf_unfiltered (file, "gdbarch_dump: gen_return_address = <%s>\n", host_address_to_string (gdbarch->gen_return_address)); @@ -3899,6 +3908,30 @@ set_gdbarch_gdb_signal_from_target (struct gdbarch *gdbarch, gdbarch->gdb_signal_from_target = gdb_signal_from_target; } +int +gdbarch_gdb_signal_to_target_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->gdb_signal_to_target != NULL; +} + +int +gdbarch_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->gdb_signal_to_target != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_gdb_signal_to_target called\n"); + return gdbarch->gdb_signal_to_target (gdbarch, signal); +} + +void +set_gdbarch_gdb_signal_to_target (struct gdbarch *gdbarch, + gdbarch_gdb_signal_to_target_ftype gdb_signal_to_target) +{ + gdbarch->gdb_signal_to_target = gdb_signal_to_target; +} + int gdbarch_get_siginfo_type_p (struct gdbarch *gdbarch) { diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index e1959c39182..013f0717b74 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -993,6 +993,20 @@ typedef enum gdb_signal (gdbarch_gdb_signal_from_target_ftype) (struct gdbarch * extern enum gdb_signal gdbarch_gdb_signal_from_target (struct gdbarch *gdbarch, int signo); extern void set_gdbarch_gdb_signal_from_target (struct gdbarch *gdbarch, gdbarch_gdb_signal_from_target_ftype *gdb_signal_from_target); +/* Signal translation: translate the GDB's internal signal number into + the inferior's signal (target's) representation. The implementation + of this method must be host independent. IOW, don't rely on symbols + of the NAT_FILE header (the nm-*.h files), the host + header, or similar headers. + Return the target signal number if found, or -1 if the GDB internal + signal number is invalid. */ + +extern int gdbarch_gdb_signal_to_target_p (struct gdbarch *gdbarch); + +typedef int (gdbarch_gdb_signal_to_target_ftype) (struct gdbarch *gdbarch, enum gdb_signal signal); +extern int gdbarch_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal); +extern void set_gdbarch_gdb_signal_to_target (struct gdbarch *gdbarch, gdbarch_gdb_signal_to_target_ftype *gdb_signal_to_target); + /* Extra signal info inspection. Return a type suitable to inspect extra signal information. */ diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index c92a857b70c..04ca38c0940 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -799,6 +799,15 @@ M:int:process_record_signal:struct regcache *regcache, enum gdb_signal signal:re # (target_wait, target_resume, etc.). M:enum gdb_signal:gdb_signal_from_target:int signo:signo +# Signal translation: translate the GDB's internal signal number into +# the inferior's signal (target's) representation. The implementation +# of this method must be host independent. IOW, don't rely on symbols +# of the NAT_FILE header (the nm-*.h files), the host +# header, or similar headers. +# Return the target signal number if found, or -1 if the GDB internal +# signal number is invalid. +M:int:gdb_signal_to_target:enum gdb_signal signal:signal + # Extra signal info inspection. # # Return a type suitable to inspect extra signal information. diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index bfb64049bc4..fbdca463510 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -36,6 +36,71 @@ #include +/* This enum represents the signals' numbers on a generic architecture + running the Linux kernel. The definition of "generic" comes from + the file , from the Linux kernel + tree, which is the "de facto" implementation of signal numbers to + be used by new architecture ports. + + For those architectures which have differences between the generic + standard (e.g., Alpha), we define the different signals (and *only* + those) in the specific target-dependent file (e.g., + alpha-linux-tdep.c, for Alpha). Please refer to the architecture's + tdep file for more information. + + ARM deserves a special mention here. On the file + , it defines only one different + (and ARM-only) signal, which is SIGSWI, with the same number as + SIGRTMIN. This signal is used only for a very specific target, + called ArthurOS (from RISCOS). Therefore, we do not handle it on + the ARM-tdep file, and we can safely use the generic signal handler + here for ARM targets. + + As stated above, this enum is derived from + , from the Linux kernel + tree. */ + +enum + { + LINUX_SIGHUP = 1, + LINUX_SIGINT = 2, + LINUX_SIGQUIT = 3, + LINUX_SIGILL = 4, + LINUX_SIGTRAP = 5, + LINUX_SIGABRT = 6, + LINUX_SIGIOT = 6, + LINUX_SIGBUS = 7, + LINUX_SIGFPE = 8, + LINUX_SIGKILL = 9, + LINUX_SIGUSR1 = 10, + LINUX_SIGSEGV = 11, + LINUX_SIGUSR2 = 12, + LINUX_SIGPIPE = 13, + LINUX_SIGALRM = 14, + LINUX_SIGTERM = 15, + LINUX_SIGSTKFLT = 16, + LINUX_SIGCHLD = 17, + LINUX_SIGCONT = 18, + LINUX_SIGSTOP = 19, + LINUX_SIGTSTP = 20, + LINUX_SIGTTIN = 21, + LINUX_SIGTTOU = 22, + LINUX_SIGURG = 23, + LINUX_SIGXCPU = 24, + LINUX_SIGXFSZ = 25, + LINUX_SIGVTALRM = 26, + LINUX_SIGPROF = 27, + LINUX_SIGWINCH = 28, + LINUX_SIGIO = 29, + LINUX_SIGPOLL = LINUX_SIGIO, + LINUX_SIGPWR = 30, + LINUX_SIGSYS = 31, + LINUX_SIGUNUSED = 31, + + LINUX_SIGRTMIN = 32, + LINUX_SIGRTMAX = 64, + }; + static struct gdbarch_data *linux_gdbarch_data_handle; struct linux_gdbarch_data @@ -1447,6 +1512,257 @@ linux_make_corefile_notes_1 (struct gdbarch *gdbarch, bfd *obfd, int *note_size) linux_collect_thread_registers); } +/* Implementation of `gdbarch_gdb_signal_from_target', as defined in + gdbarch.h. This function is not static because it is exported to + other -tdep files. */ + +enum gdb_signal +linux_gdb_signal_from_target (struct gdbarch *gdbarch, int signal) +{ + switch (signal) + { + case 0: + return GDB_SIGNAL_0; + + case LINUX_SIGHUP: + return GDB_SIGNAL_HUP; + + case LINUX_SIGINT: + return GDB_SIGNAL_INT; + + case LINUX_SIGQUIT: + return GDB_SIGNAL_QUIT; + + case LINUX_SIGILL: + return GDB_SIGNAL_ILL; + + case LINUX_SIGTRAP: + return GDB_SIGNAL_TRAP; + + case LINUX_SIGABRT: + return GDB_SIGNAL_ABRT; + + case LINUX_SIGBUS: + return GDB_SIGNAL_BUS; + + case LINUX_SIGFPE: + return GDB_SIGNAL_FPE; + + case LINUX_SIGKILL: + return GDB_SIGNAL_KILL; + + case LINUX_SIGUSR1: + return GDB_SIGNAL_USR1; + + case LINUX_SIGSEGV: + return GDB_SIGNAL_SEGV; + + case LINUX_SIGUSR2: + return GDB_SIGNAL_USR2; + + case LINUX_SIGPIPE: + return GDB_SIGNAL_PIPE; + + case LINUX_SIGALRM: + return GDB_SIGNAL_ALRM; + + case LINUX_SIGTERM: + return GDB_SIGNAL_TERM; + + case LINUX_SIGCHLD: + return GDB_SIGNAL_CHLD; + + case LINUX_SIGCONT: + return GDB_SIGNAL_CONT; + + case LINUX_SIGSTOP: + return GDB_SIGNAL_STOP; + + case LINUX_SIGTSTP: + return GDB_SIGNAL_TSTP; + + case LINUX_SIGTTIN: + return GDB_SIGNAL_TTIN; + + case LINUX_SIGTTOU: + return GDB_SIGNAL_TTOU; + + case LINUX_SIGURG: + return GDB_SIGNAL_URG; + + case LINUX_SIGXCPU: + return GDB_SIGNAL_XCPU; + + case LINUX_SIGXFSZ: + return GDB_SIGNAL_XFSZ; + + case LINUX_SIGVTALRM: + return GDB_SIGNAL_VTALRM; + + case LINUX_SIGPROF: + return GDB_SIGNAL_PROF; + + case LINUX_SIGWINCH: + return GDB_SIGNAL_WINCH; + + /* No way to differentiate between SIGIO and SIGPOLL. + Therefore, we just handle the first one. */ + case LINUX_SIGIO: + return GDB_SIGNAL_IO; + + case LINUX_SIGPWR: + return GDB_SIGNAL_PWR; + + case LINUX_SIGSYS: + return GDB_SIGNAL_SYS; + + /* SIGRTMIN and SIGRTMAX are not continuous in , + therefore we have to handle them here. */ + case LINUX_SIGRTMIN: + return GDB_SIGNAL_REALTIME_32; + + case LINUX_SIGRTMAX: + return GDB_SIGNAL_REALTIME_64; + } + + if (signal >= LINUX_SIGRTMIN + 1 && signal <= LINUX_SIGRTMAX - 1) + { + int offset = signal - LINUX_SIGRTMIN + 1; + + return (enum gdb_signal) ((int) GDB_SIGNAL_REALTIME_33 + offset); + } + + return GDB_SIGNAL_UNKNOWN; +} + +/* Implementation of `gdbarch_gdb_signal_to_target', as defined in + gdbarch.h. This function is not static because it is exported to + other -tdep files. */ + +int +linux_gdb_signal_to_target (struct gdbarch *gdbarch, + enum gdb_signal signal) +{ + switch (signal) + { + case GDB_SIGNAL_0: + return 0; + + case GDB_SIGNAL_HUP: + return LINUX_SIGHUP; + + case GDB_SIGNAL_INT: + return LINUX_SIGINT; + + case GDB_SIGNAL_QUIT: + return LINUX_SIGQUIT; + + case GDB_SIGNAL_ILL: + return LINUX_SIGILL; + + case GDB_SIGNAL_TRAP: + return LINUX_SIGTRAP; + + case GDB_SIGNAL_ABRT: + return LINUX_SIGABRT; + + case GDB_SIGNAL_FPE: + return LINUX_SIGFPE; + + case GDB_SIGNAL_KILL: + return LINUX_SIGKILL; + + case GDB_SIGNAL_BUS: + return LINUX_SIGBUS; + + case GDB_SIGNAL_SEGV: + return LINUX_SIGSEGV; + + case GDB_SIGNAL_SYS: + return LINUX_SIGSYS; + + case GDB_SIGNAL_PIPE: + return LINUX_SIGPIPE; + + case GDB_SIGNAL_ALRM: + return LINUX_SIGALRM; + + case GDB_SIGNAL_TERM: + return LINUX_SIGTERM; + + case GDB_SIGNAL_URG: + return LINUX_SIGURG; + + case GDB_SIGNAL_STOP: + return LINUX_SIGSTOP; + + case GDB_SIGNAL_TSTP: + return LINUX_SIGTSTP; + + case GDB_SIGNAL_CONT: + return LINUX_SIGCONT; + + case GDB_SIGNAL_CHLD: + return LINUX_SIGCHLD; + + case GDB_SIGNAL_TTIN: + return LINUX_SIGTTIN; + + case GDB_SIGNAL_TTOU: + return LINUX_SIGTTOU; + + case GDB_SIGNAL_IO: + return LINUX_SIGIO; + + case GDB_SIGNAL_XCPU: + return LINUX_SIGXCPU; + + case GDB_SIGNAL_XFSZ: + return LINUX_SIGXFSZ; + + case GDB_SIGNAL_VTALRM: + return LINUX_SIGVTALRM; + + case GDB_SIGNAL_PROF: + return LINUX_SIGPROF; + + case GDB_SIGNAL_WINCH: + return LINUX_SIGWINCH; + + case GDB_SIGNAL_USR1: + return LINUX_SIGUSR1; + + case GDB_SIGNAL_USR2: + return LINUX_SIGUSR2; + + case GDB_SIGNAL_PWR: + return LINUX_SIGPWR; + + case GDB_SIGNAL_POLL: + return LINUX_SIGPOLL; + + /* GDB_SIGNAL_REALTIME_32 is not continuous in , + therefore we have to handle it here. */ + case GDB_SIGNAL_REALTIME_32: + return LINUX_SIGRTMIN; + + /* Same comment applies to _64. */ + case GDB_SIGNAL_REALTIME_64: + return LINUX_SIGRTMAX; + } + + /* GDB_SIGNAL_REALTIME_33 to _64 are continuous. */ + if (signal >= GDB_SIGNAL_REALTIME_33 + && signal <= GDB_SIGNAL_REALTIME_63) + { + int offset = signal - GDB_SIGNAL_REALTIME_33; + + return LINUX_SIGRTMIN + 1 + offset; + } + + return -1; +} + /* To be called from the various GDB_OSABI_LINUX handlers for the various GNU/Linux architectures and machine types. */ @@ -1460,6 +1776,10 @@ linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_make_corefile_notes (gdbarch, linux_make_corefile_notes_1); set_gdbarch_has_shared_address_space (gdbarch, linux_has_shared_address_space); + set_gdbarch_gdb_signal_from_target (gdbarch, + linux_gdb_signal_from_target); + set_gdbarch_gdb_signal_to_target (gdbarch, + linux_gdb_signal_to_target); } /* Provide a prototype to silence -Wmissing-prototypes. */ diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h index 380507e9674..5841f296b12 100644 --- a/gdb/linux-tdep.h +++ b/gdb/linux-tdep.h @@ -34,6 +34,12 @@ char *linux_make_corefile_notes (struct gdbarch *, bfd *, int *, struct type *linux_get_siginfo_type (struct gdbarch *); +extern enum gdb_signal linux_gdb_signal_from_target (struct gdbarch *gdbarch, + int signal); + +extern int linux_gdb_signal_to_target (struct gdbarch *gdbarch, + enum gdb_signal signal); + extern void linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch); #endif /* linux-tdep.h */ diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c index 484b39f7fe5..8d17839c6ef 100644 --- a/gdb/mips-linux-tdep.c +++ b/gdb/mips-linux-tdep.c @@ -45,6 +45,42 @@ static struct target_so_ops mips_svr4_so_ops; +/* This enum represents the signals' numbers on the MIPS + architecture. It just contains the signal definitions which are + different from the generic implementation. + + It is derived from the file , + from the Linux kernel tree. */ + +enum + { + MIPS_LINUX_SIGEMT = 7, + MIPS_LINUX_SIGBUS = 10, + MIPS_LINUX_SIGSYS = 12, + MIPS_LINUX_SIGUSR1 = 16, + MIPS_LINUX_SIGUSR2 = 17, + MIPS_LINUX_SIGCHLD = 18, + MIPS_LINUX_SIGCLD = MIPS_LINUX_SIGCHLD, + MIPS_LINUX_SIGPWR = 19, + MIPS_LINUX_SIGWINCH = 20, + MIPS_LINUX_SIGURG = 21, + MIPS_LINUX_SIGIO = 22, + MIPS_LINUX_SIGPOLL = MIPS_LINUX_SIGIO, + MIPS_LINUX_SIGSTOP = 23, + MIPS_LINUX_SIGTSTP = 24, + MIPS_LINUX_SIGCONT = 25, + MIPS_LINUX_SIGTTIN = 26, + MIPS_LINUX_SIGTTOU = 27, + MIPS_LINUX_SIGVTALRM = 28, + MIPS_LINUX_SIGPROF = 29, + MIPS_LINUX_SIGXCPU = 30, + MIPS_LINUX_SIGXFSZ = 31, + + MIPS_LINUX_SIGRTMIN = 32, + MIPS_LINUX_SIGRT64 = 64, + MIPS_LINUX_SIGRTMAX = 127, + }; + /* Figure out where the longjmp will land. We expect the first arg to be a pointer to the jmp_buf structure from which we extract the pc (MIPS_LINUX_JB_PC) that we will land @@ -1339,94 +1375,184 @@ mips_linux_get_syscall_number (struct gdbarch *gdbarch, return ret; } +/* Implementation of `gdbarch_gdb_signal_to_target', as defined in + gdbarch.h. */ + +static int +mips_gdb_signal_to_target (struct gdbarch *gdbarch, + enum gdb_signal signal) +{ + switch (signal) + { + case GDB_SIGNAL_EMT: + return MIPS_LINUX_SIGEMT; + + case GDB_SIGNAL_BUS: + return MIPS_LINUX_SIGBUS; + + case GDB_SIGNAL_SYS: + return MIPS_LINUX_SIGSYS; + + case GDB_SIGNAL_USR1: + return MIPS_LINUX_SIGUSR1; + + case GDB_SIGNAL_USR2: + return MIPS_LINUX_SIGUSR2; + + case GDB_SIGNAL_CHLD: + return MIPS_LINUX_SIGCHLD; + + case GDB_SIGNAL_PWR: + return MIPS_LINUX_SIGPWR; + + case GDB_SIGNAL_WINCH: + return MIPS_LINUX_SIGWINCH; + + case GDB_SIGNAL_URG: + return MIPS_LINUX_SIGURG; + + case GDB_SIGNAL_IO: + return MIPS_LINUX_SIGIO; + + case GDB_SIGNAL_POLL: + return MIPS_LINUX_SIGPOLL; + + case GDB_SIGNAL_STOP: + return MIPS_LINUX_SIGSTOP; + + case GDB_SIGNAL_TSTP: + return MIPS_LINUX_SIGTSTP; + + case GDB_SIGNAL_CONT: + return MIPS_LINUX_SIGCONT; + + case GDB_SIGNAL_TTIN: + return MIPS_LINUX_SIGTTIN; + + case GDB_SIGNAL_TTOU: + return MIPS_LINUX_SIGTTOU; + + case GDB_SIGNAL_VTALRM: + return MIPS_LINUX_SIGVTALRM; + + case GDB_SIGNAL_PROF: + return MIPS_LINUX_SIGPROF; + + case GDB_SIGNAL_XCPU: + return MIPS_LINUX_SIGXCPU; + + case GDB_SIGNAL_XFSZ: + return MIPS_LINUX_SIGXFSZ; + + /* GDB_SIGNAL_REALTIME_32 is not continuous in , + therefore we have to handle it here. */ + case GDB_SIGNAL_REALTIME_32: + return MIPS_LINUX_SIGRTMIN; + } + + if (signal >= GDB_SIGNAL_REALTIME_33 + && signal <= GDB_SIGNAL_REALTIME_63) + { + int offset = signal - GDB_SIGNAL_REALTIME_33; + + return MIPS_LINUX_SIGRTMIN + 1 + offset; + } + else if (signal >= GDB_SIGNAL_REALTIME_64 + && signal <= GDB_SIGNAL_REALTIME_127) + { + int offset = signal - GDB_SIGNAL_REALTIME_64; + + return MIPS_LINUX_SIGRT64 + offset; + } + + return linux_gdb_signal_to_target (gdbarch, signal); +} + /* Translate signals based on MIPS signal values. Adapted from gdb/common/signals.c. */ static enum gdb_signal -mips_gdb_signal_from_target (struct gdbarch *gdbarch, int signo) +mips_gdb_signal_from_target (struct gdbarch *gdbarch, int signal) { - switch (signo) + switch (signal) { - case 0: - return GDB_SIGNAL_0; - case MIPS_SIGHUP: - return GDB_SIGNAL_HUP; - case MIPS_SIGINT: - return GDB_SIGNAL_INT; - case MIPS_SIGQUIT: - return GDB_SIGNAL_QUIT; - case MIPS_SIGILL: - return GDB_SIGNAL_ILL; - case MIPS_SIGTRAP: - return GDB_SIGNAL_TRAP; - case MIPS_SIGABRT: - return GDB_SIGNAL_ABRT; - case MIPS_SIGEMT: + case MIPS_LINUX_SIGEMT: return GDB_SIGNAL_EMT; - case MIPS_SIGFPE: - return GDB_SIGNAL_FPE; - case MIPS_SIGKILL: - return GDB_SIGNAL_KILL; - case MIPS_SIGBUS: + + case MIPS_LINUX_SIGBUS: return GDB_SIGNAL_BUS; - case MIPS_SIGSEGV: - return GDB_SIGNAL_SEGV; - case MIPS_SIGSYS: + + case MIPS_LINUX_SIGSYS: return GDB_SIGNAL_SYS; - case MIPS_SIGPIPE: - return GDB_SIGNAL_PIPE; - case MIPS_SIGALRM: - return GDB_SIGNAL_ALRM; - case MIPS_SIGTERM: - return GDB_SIGNAL_TERM; - case MIPS_SIGUSR1: + + case MIPS_LINUX_SIGUSR1: return GDB_SIGNAL_USR1; - case MIPS_SIGUSR2: + + case MIPS_LINUX_SIGUSR2: return GDB_SIGNAL_USR2; - case MIPS_SIGCHLD: + + case MIPS_LINUX_SIGCHLD: return GDB_SIGNAL_CHLD; - case MIPS_SIGPWR: + + case MIPS_LINUX_SIGPWR: return GDB_SIGNAL_PWR; - case MIPS_SIGWINCH: + + case MIPS_LINUX_SIGWINCH: return GDB_SIGNAL_WINCH; - case MIPS_SIGURG: + + case MIPS_LINUX_SIGURG: return GDB_SIGNAL_URG; - case MIPS_SIGPOLL: - return GDB_SIGNAL_POLL; - case MIPS_SIGSTOP: + + /* No way to differentiate between SIGIO and SIGPOLL. + Therefore, we just handle the first one. */ + case MIPS_LINUX_SIGIO: + return GDB_SIGNAL_IO; + + case MIPS_LINUX_SIGSTOP: return GDB_SIGNAL_STOP; - case MIPS_SIGTSTP: + + case MIPS_LINUX_SIGTSTP: return GDB_SIGNAL_TSTP; - case MIPS_SIGCONT: + + case MIPS_LINUX_SIGCONT: return GDB_SIGNAL_CONT; - case MIPS_SIGTTIN: + + case MIPS_LINUX_SIGTTIN: return GDB_SIGNAL_TTIN; - case MIPS_SIGTTOU: + + case MIPS_LINUX_SIGTTOU: return GDB_SIGNAL_TTOU; - case MIPS_SIGVTALRM: + + case MIPS_LINUX_SIGVTALRM: return GDB_SIGNAL_VTALRM; - case MIPS_SIGPROF: + + case MIPS_LINUX_SIGPROF: return GDB_SIGNAL_PROF; - case MIPS_SIGXCPU: + + case MIPS_LINUX_SIGXCPU: return GDB_SIGNAL_XCPU; - case MIPS_SIGXFSZ: + + case MIPS_LINUX_SIGXFSZ: return GDB_SIGNAL_XFSZ; - } + } - if (signo >= MIPS_SIGRTMIN && signo <= MIPS_SIGRTMAX) + if (signal >= MIPS_LINUX_SIGRTMIN && signal <= MIPS_LINUX_SIGRTMAX) { /* GDB_SIGNAL_REALTIME values are not contiguous, map parts of the MIPS block to the respective GDB_SIGNAL_REALTIME blocks. */ - signo -= MIPS_SIGRTMIN; - if (signo == 0) + int offset = signal - MIPS_LINUX_SIGRTMIN; + + if (offset == 0) return GDB_SIGNAL_REALTIME_32; - else if (signo < 32) - return ((enum gdb_signal) (signo - 1 + (int) GDB_SIGNAL_REALTIME_33)); + else if (offset < 32) + return (enum gdb_signal) (offset - 1 + + (int) GDB_SIGNAL_REALTIME_33); else - return ((enum gdb_signal) (signo - 32 + (int) GDB_SIGNAL_REALTIME_64)); + return (enum gdb_signal) (offset - 32 + + (int) GDB_SIGNAL_REALTIME_64); } - return GDB_SIGNAL_UNKNOWN; + return linux_gdb_signal_from_target (gdbarch, signal); } /* Initialize one of the GNU/Linux OS ABIs. */ @@ -1516,6 +1642,9 @@ mips_linux_init_abi (struct gdbarch_info info, set_gdbarch_gdb_signal_from_target (gdbarch, mips_gdb_signal_from_target); + set_gdbarch_gdb_signal_to_target (gdbarch, + mips_gdb_signal_to_target); + tdep->syscall_next_pc = mips_linux_syscall_next_pc; if (tdesc_data) diff --git a/gdb/mips-linux-tdep.h b/gdb/mips-linux-tdep.h index 09cbc131146..482d3c5329f 100644 --- a/gdb/mips-linux-tdep.h +++ b/gdb/mips-linux-tdep.h @@ -105,45 +105,3 @@ enum { /* Return 1 if MIPS_RESTART_REGNUM is usable. */ int mips_linux_restart_reg_p (struct gdbarch *gdbarch); - -/* MIPS Signals -- adapted from linux/arch/mips/include/asm/signal.h. */ - -enum mips_signals - { - MIPS_SIGHUP = 1, /* Hangup (POSIX). */ - MIPS_SIGINT = 2, /* Interrupt (ANSI). */ - MIPS_SIGQUIT = 3, /* Quit (POSIX). */ - MIPS_SIGILL = 4, /* Illegal instruction (ANSI). */ - MIPS_SIGTRAP = 5, /* Trace trap (POSIX). */ - MIPS_SIGIOT = 6, /* IOT trap (4.2 BSD). */ - MIPS_SIGABRT = MIPS_SIGIOT, /* Abort (ANSI). */ - MIPS_SIGEMT = 7, - MIPS_SIGFPE = 8, /* Floating-point exception (ANSI). */ - MIPS_SIGKILL = 9, /* Kill, unblockable (POSIX). */ - MIPS_SIGBUS = 10, /* BUS error (4.2 BSD). */ - MIPS_SIGSEGV = 11, /* Segmentation violation (ANSI). */ - MIPS_SIGSYS = 12, - MIPS_SIGPIPE = 13, /* Broken pipe (POSIX). */ - MIPS_SIGALRM = 14, /* Alarm clock (POSIX). */ - MIPS_SIGTERM = 15, /* Termination (ANSI). */ - MIPS_SIGUSR1 = 16, /* User-defined signal 1 (POSIX). */ - MIPS_SIGUSR2 = 17, /* User-defined signal 2 (POSIX). */ - MIPS_SIGCHLD = 18, /* Child status has changed (POSIX). */ - MIPS_SIGCLD = MIPS_SIGCHLD, /* Same as SIGCHLD (System V). */ - MIPS_SIGPWR = 19, /* Power failure restart (System V). */ - MIPS_SIGWINCH = 20, /* Window size change (4.3 BSD, Sun). */ - MIPS_SIGURG = 21, /* Urgent condition on socket (4.2 BSD). */ - MIPS_SIGIO = 22, /* I/O now possible (4.2 BSD). */ - MIPS_SIGPOLL = MIPS_SIGIO, /* Pollable event occurred (System V). */ - MIPS_SIGSTOP = 23, /* Stop, unblockable (POSIX). */ - MIPS_SIGTSTP = 24, /* Keyboard stop (POSIX). */ - MIPS_SIGCONT = 25, /* Continue (POSIX). */ - MIPS_SIGTTIN = 26, /* Background read from tty (POSIX). */ - MIPS_SIGTTOU = 27, /* Background write to tty (POSIX). */ - MIPS_SIGVTALRM = 28, /* Virtual alarm clock (4.2 BSD). */ - MIPS_SIGPROF = 29, /* Profiling alarm clock (4.2 BSD). */ - MIPS_SIGXCPU = 30, /* CPU limit exceeded (4.2 BSD). */ - MIPS_SIGXFSZ = 31, /* File size limit exceeded (4.2 BSD). */ - MIPS_SIGRTMIN = 32, /* Minimum RT signal. */ - MIPS_SIGRTMAX = 128 - 1 /* Maximum RT signal. */ - }; diff --git a/gdb/sparc-linux-tdep.c b/gdb/sparc-linux-tdep.c index 02c4137a3b6..75d40a64e8a 100644 --- a/gdb/sparc-linux-tdep.c +++ b/gdb/sparc-linux-tdep.c @@ -90,6 +90,31 @@ static const struct tramp_frame sparc32_linux_rt_sigframe = sparc32_linux_sigframe_init }; +/* This enum represents the signals' numbers on the SPARC + architecture. It just contains the signal definitions which are + different from the generic implementation. + + It is derived from the file , + from the Linux kernel tree. */ + +enum + { + SPARC_LINUX_SIGEMT = 7, + SPARC_LINUX_SIGBUS = 10, + SPARC_LINUX_SIGSYS = 12, + SPARC_LINUX_SIGURG = 16, + SPARC_LINUX_SIGSTOP = 17, + SPARC_LINUX_SIGTSTP = 18, + SPARC_LINUX_SIGCONT = 19, + SPARC_LINUX_SIGCHLD = 20, + SPARC_LINUX_SIGIO = 23, + SPARC_LINUX_SIGPOLL = SPARC_LINUX_SIGIO, + SPARC_LINUX_SIGLOST = 29, + SPARC_LINUX_SIGPWR = SPARC_LINUX_SIGLOST, + SPARC_LINUX_SIGUSR1 = 30, + SPARC_LINUX_SIGUSR2 = 31, + }; + static void sparc32_linux_sigframe_init (const struct tramp_frame *self, struct frame_info *this_frame, @@ -268,6 +293,114 @@ sparc32_linux_get_syscall_number (struct gdbarch *gdbarch, return ret; } +/* Implementation of `gdbarch_gdb_signal_from_target', as defined in + gdbarch.h. */ + +static enum gdb_signal +sparc32_linux_gdb_signal_from_target (struct gdbarch *gdbarch, + int signal) +{ + switch (signal) + { + case SPARC_LINUX_SIGEMT: + return GDB_SIGNAL_EMT; + + case SPARC_LINUX_SIGBUS: + return GDB_SIGNAL_BUS; + + case SPARC_LINUX_SIGSYS: + return GDB_SIGNAL_SYS; + + case SPARC_LINUX_SIGURG: + return GDB_SIGNAL_URG; + + case SPARC_LINUX_SIGSTOP: + return GDB_SIGNAL_STOP; + + case SPARC_LINUX_SIGTSTP: + return GDB_SIGNAL_TSTP; + + case SPARC_LINUX_SIGCONT: + return GDB_SIGNAL_CONT; + + case SPARC_LINUX_SIGCHLD: + return GDB_SIGNAL_CHLD; + + /* No way to differentiate between SIGIO and SIGPOLL. + Therefore, we just handle the first one. */ + case SPARC_LINUX_SIGIO: + return GDB_SIGNAL_IO; + + /* No way to differentiate between SIGLOST and SIGPWR. + Therefore, we just handle the first one. */ + case SPARC_LINUX_SIGLOST: + return GDB_SIGNAL_LOST; + + case SPARC_LINUX_SIGUSR1: + return GDB_SIGNAL_USR1; + + case SPARC_LINUX_SIGUSR2: + return GDB_SIGNAL_USR2; + } + + return linux_gdb_signal_from_target (gdbarch, signal); +} + +/* Implementation of `gdbarch_gdb_signal_to_target', as defined in + gdbarch.h. */ + +static int +sparc32_linux_gdb_signal_to_target (struct gdbarch *gdbarch, + enum gdb_signal signal) +{ + switch (signal) + { + case GDB_SIGNAL_EMT: + return SPARC_LINUX_SIGEMT; + + case GDB_SIGNAL_BUS: + return SPARC_LINUX_SIGBUS; + + case GDB_SIGNAL_SYS: + return SPARC_LINUX_SIGSYS; + + case GDB_SIGNAL_URG: + return SPARC_LINUX_SIGURG; + + case GDB_SIGNAL_STOP: + return SPARC_LINUX_SIGSTOP; + + case GDB_SIGNAL_TSTP: + return SPARC_LINUX_SIGTSTP; + + case GDB_SIGNAL_CONT: + return SPARC_LINUX_SIGCONT; + + case GDB_SIGNAL_CHLD: + return SPARC_LINUX_SIGCHLD; + + case GDB_SIGNAL_IO: + return SPARC_LINUX_SIGIO; + + case GDB_SIGNAL_POLL: + return SPARC_LINUX_SIGPOLL; + + case GDB_SIGNAL_LOST: + return SPARC_LINUX_SIGLOST; + + case GDB_SIGNAL_PWR: + return SPARC_LINUX_SIGPWR; + + case GDB_SIGNAL_USR1: + return SPARC_LINUX_SIGUSR1; + + case GDB_SIGNAL_USR2: + return SPARC_LINUX_SIGUSR2; + } + + return linux_gdb_signal_to_target (gdbarch, signal); +} + static void @@ -313,6 +446,11 @@ sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_xml_syscall_file_name (XML_SYSCALL_FILENAME_SPARC32); set_gdbarch_get_syscall_number (gdbarch, sparc32_linux_get_syscall_number); + + set_gdbarch_gdb_signal_from_target (gdbarch, + sparc32_linux_gdb_signal_from_target); + set_gdbarch_gdb_signal_to_target (gdbarch, + sparc32_linux_gdb_signal_to_target); } /* Provide a prototype to silence -Wmissing-prototypes. */ diff --git a/gdb/xtensa-linux-tdep.c b/gdb/xtensa-linux-tdep.c index b7f11b97741..e7c62875710 100644 --- a/gdb/xtensa-linux-tdep.c +++ b/gdb/xtensa-linux-tdep.c @@ -23,6 +23,75 @@ #include "solib-svr4.h" #include "symtab.h" +/* This enum represents the signals' numbers on the Xtensa + architecture. It just contains the signal definitions which are + different from the generic implementation. + + It is derived from the file , + from the Linux kernel tree. */ + +enum + { + XTENSA_LINUX_SIGRTMIN = 32, + XTENSA_LINUX_SIGRTMAX = 63, + }; + +/* Implementation of `gdbarch_gdb_signal_from_target', as defined in + gdbarch.h. */ + +static enum gdb_signal +xtensa_linux_gdb_signal_from_target (struct gdbarch *gdbarch, + int signal) +{ + if (signal >= XTENSA_LINUX_SIGRTMIN && signal <= XTENSA_LINUX_SIGRTMAX) + { + int offset = signal - XTENSA_LINUX_SIGRTMIN; + + if (offset == 0) + return GDB_SIGNAL_REALTIME_32; + else + return (enum gdb_signal) (offset - 1 + + (int) GDB_SIGNAL_REALTIME_33); + } + else if (signal > XTENSA_LINUX_SIGRTMAX) + return GDB_SIGNAL_UNKNOWN; + + return linux_gdb_signal_from_target (gdbarch, signal); +} + +/* Implementation of `gdbarch_gdb_signal_to_target', as defined in + gdbarch.h. */ + +static int +xtensa_linux_gdb_signal_to_target (struct gdbarch *gdbarch, + enum gdb_signal signal) +{ + switch (signal) + { + /* GDB_SIGNAL_REALTIME_32 is not continuous in , + therefore we have to handle it here. */ + case GDB_SIGNAL_REALTIME_32: + return XTENSA_LINUX_SIGRTMIN; + + /* GDB_SIGNAL_REALTIME_64 is not valid on Xtensa. */ + case GDB_SIGNAL_REALTIME_64: + return -1; + } + + /* GDB_SIGNAL_REALTIME_33 to _63 are continuous. + + Xtensa does not have _64. */ + if (signal >= GDB_SIGNAL_REALTIME_33 + && signal <= GDB_SIGNAL_REALTIME_63) + { + int offset = signal - GDB_SIGNAL_REALTIME_33; + + return XTENSA_LINUX_SIGRTMIN + 1 + offset; + } + + return linux_gdb_signal_to_target (gdbarch, signal); +} + /* OS specific initialization of gdbarch. */ static void @@ -32,6 +101,11 @@ xtensa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_ilp32_fetch_link_map_offsets); + + set_gdbarch_gdb_signal_from_target (gdbarch, + xtensa_linux_gdb_signal_from_target); + set_gdbarch_gdb_signal_to_target (gdbarch, + xtensa_linux_gdb_signal_to_target); } /* Provide a prototype to silence -Wmissing-prototypes. */