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:

	<http://sourceware.org/ml/gdb-patches/2013-06/msg00452.html>
	<http://sourceware.org/ml/gdb-patches/2013-06/msg00352.html>

What I did was to investigate, on the Linux kernel, which targets shared
the signal numbers definition with the generic definition, present at
<include/uapi/asm-generic/signal.h>.  For the record, I used linux-3.10-rc7
as the main source of information, always looking at
<arch/<ARCH_NAME>/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  <sergiodj@redhat.com>

	* 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.
This commit is contained in:
Sergio Durigan Junior 2013-08-09 16:54:43 +00:00
parent 156d08c82a
commit eb14d40688
12 changed files with 1053 additions and 115 deletions

View File

@ -1,3 +1,45 @@
2013-08-09 Sergio Durigan Junior <sergiodj@redhat.com>
* 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 <palves@redhat.com> 2013-08-09 Pedro Alves <palves@redhat.com>
* avr-tdep.c (XMALLOC): Delete macro. * avr-tdep.c (XMALLOC): Delete macro.

View File

@ -28,6 +28,35 @@
#include "linux-tdep.h" #include "linux-tdep.h"
#include "alpha-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 <arch/alpha/include/uapi/asm/signal.h>,
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 /* Under GNU/Linux, signal handler invocations can be identified by
the designated code sequence that is used to return from a signal the designated code sequence that is used to return from a signal
handler. In particular, the return address of a signal handler 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; 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 static void
alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 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 set_gdbarch_regset_from_core_section
(gdbarch, alpha_linux_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. */ /* Provide a prototype to silence -Wmissing-prototypes. */

View File

@ -36,6 +36,7 @@
#include "regcache.h" #include "regcache.h"
#include "gdb_string.h" #include "gdb_string.h"
#include "dis-asm.h" #include "dis-asm.h"
#include "linux-tdep.h"
/* AVR Background: /* AVR Background:
@ -190,6 +191,19 @@ struct gdbarch_tdep
struct type *pc_type; 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 <arch/avr32/include/uapi/asm/signal.h>,
from the Linux kernel tree. */
enum
{
AVR_LINUX_SIGRTMIN = 32,
AVR_LINUX_SIGRTMAX = 63,
};
/* Lookup the name of a register given it's number. */ /* Lookup the name of a register given it's number. */
static const char * static const char *
@ -1341,6 +1355,60 @@ avr_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
return -1; 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 <gdb/signals.def>,
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. */ /* Initialize the gdbarch structure for the AVR's. */
static struct gdbarch * 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_pc (gdbarch, avr_unwind_pc);
set_gdbarch_unwind_sp (gdbarch, avr_unwind_sp); 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; return gdbarch;
} }

View File

@ -261,6 +261,7 @@ struct gdbarch
gdbarch_process_record_ftype *process_record; gdbarch_process_record_ftype *process_record;
gdbarch_process_record_signal_ftype *process_record_signal; gdbarch_process_record_signal_ftype *process_record_signal;
gdbarch_gdb_signal_from_target_ftype *gdb_signal_from_target; 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_get_siginfo_type_ftype *get_siginfo_type;
gdbarch_record_special_symbol_ftype *record_special_symbol; gdbarch_record_special_symbol_ftype *record_special_symbol;
gdbarch_get_syscall_number_ftype *get_syscall_number; gdbarch_get_syscall_number_ftype *get_syscall_number;
@ -433,6 +434,7 @@ struct gdbarch startup_gdbarch =
0, /* process_record */ 0, /* process_record */
0, /* process_record_signal */ 0, /* process_record_signal */
0, /* gdb_signal_from_target */ 0, /* gdb_signal_from_target */
0, /* gdb_signal_to_target */
0, /* get_siginfo_type */ 0, /* get_siginfo_type */
0, /* record_special_symbol */ 0, /* record_special_symbol */
0, /* get_syscall_number */ 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, has predicate. */
/* Skip verify of process_record_signal, has predicate. */ /* Skip verify of process_record_signal, has predicate. */
/* Skip verify of gdb_signal_from_target, 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 get_siginfo_type, has predicate. */
/* Skip verify of record_special_symbol, has predicate. */ /* Skip verify of record_special_symbol, has predicate. */
/* Skip verify of get_syscall_number, 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, fprintf_unfiltered (file,
"gdbarch_dump: gdb_signal_from_target = <%s>\n", "gdbarch_dump: gdb_signal_from_target = <%s>\n",
host_address_to_string (gdbarch->gdb_signal_from_target)); 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, fprintf_unfiltered (file,
"gdbarch_dump: gen_return_address = <%s>\n", "gdbarch_dump: gen_return_address = <%s>\n",
host_address_to_string (gdbarch->gen_return_address)); 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; 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 int
gdbarch_get_siginfo_type_p (struct gdbarch *gdbarch) gdbarch_get_siginfo_type_p (struct gdbarch *gdbarch)
{ {

View File

@ -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 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); 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 <signal.h>
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. /* Extra signal info inspection.
Return a type suitable to inspect extra signal information. */ Return a type suitable to inspect extra signal information. */

View File

@ -799,6 +799,15 @@ M:int:process_record_signal:struct regcache *regcache, enum gdb_signal signal:re
# (target_wait, target_resume, etc.). # (target_wait, target_resume, etc.).
M:enum gdb_signal:gdb_signal_from_target:int signo:signo 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 <signal.h>
# 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. # Extra signal info inspection.
# #
# Return a type suitable to inspect extra signal information. # Return a type suitable to inspect extra signal information.

View File

@ -36,6 +36,71 @@
#include <ctype.h> #include <ctype.h>
/* This enum represents the signals' numbers on a generic architecture
running the Linux kernel. The definition of "generic" comes from
the file <include/uapi/asm-generic/signal.h>, 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
<arch/arm/include/uapi/asm/signal.h>, 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
<include/uapi/asm-generic/signal.h>, 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; static struct gdbarch_data *linux_gdbarch_data_handle;
struct linux_gdbarch_data 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); 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 <gdb/signals.def>,
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 <gdb/signals.def>,
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 /* To be called from the various GDB_OSABI_LINUX handlers for the
various GNU/Linux architectures and machine types. */ 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_make_corefile_notes (gdbarch, linux_make_corefile_notes_1);
set_gdbarch_has_shared_address_space (gdbarch, set_gdbarch_has_shared_address_space (gdbarch,
linux_has_shared_address_space); 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. */ /* Provide a prototype to silence -Wmissing-prototypes. */

View File

@ -34,6 +34,12 @@ char *linux_make_corefile_notes (struct gdbarch *, bfd *, int *,
struct type *linux_get_siginfo_type (struct gdbarch *); 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); extern void linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
#endif /* linux-tdep.h */ #endif /* linux-tdep.h */

View File

@ -45,6 +45,42 @@
static struct target_so_ops mips_svr4_so_ops; 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 <arch/mips/include/uapi/asm/signal.h>,
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. /* Figure out where the longjmp will land.
We expect the first arg to be a pointer to the jmp_buf structure 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 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; 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 <gdb/signals.def>,
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. /* Translate signals based on MIPS signal values.
Adapted from gdb/common/signals.c. */ Adapted from gdb/common/signals.c. */
static enum gdb_signal 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: case MIPS_LINUX_SIGEMT:
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:
return GDB_SIGNAL_EMT; return GDB_SIGNAL_EMT;
case MIPS_SIGFPE:
return GDB_SIGNAL_FPE;
case MIPS_SIGKILL:
return GDB_SIGNAL_KILL;
case MIPS_SIGBUS:
return GDB_SIGNAL_BUS;
case MIPS_SIGSEGV:
return GDB_SIGNAL_SEGV;
case MIPS_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:
return GDB_SIGNAL_USR1;
case MIPS_SIGUSR2:
return GDB_SIGNAL_USR2;
case MIPS_SIGCHLD:
return GDB_SIGNAL_CHLD;
case MIPS_SIGPWR:
return GDB_SIGNAL_PWR;
case MIPS_SIGWINCH:
return GDB_SIGNAL_WINCH;
case MIPS_SIGURG:
return GDB_SIGNAL_URG;
case MIPS_SIGPOLL:
return GDB_SIGNAL_POLL;
case MIPS_SIGSTOP:
return GDB_SIGNAL_STOP;
case MIPS_SIGTSTP:
return GDB_SIGNAL_TSTP;
case MIPS_SIGCONT:
return GDB_SIGNAL_CONT;
case MIPS_SIGTTIN:
return GDB_SIGNAL_TTIN;
case MIPS_SIGTTOU:
return GDB_SIGNAL_TTOU;
case MIPS_SIGVTALRM:
return GDB_SIGNAL_VTALRM;
case MIPS_SIGPROF:
return GDB_SIGNAL_PROF;
case MIPS_SIGXCPU:
return GDB_SIGNAL_XCPU;
case MIPS_SIGXFSZ:
return GDB_SIGNAL_XFSZ;
}
if (signo >= MIPS_SIGRTMIN && signo <= MIPS_SIGRTMAX) case MIPS_LINUX_SIGBUS:
return GDB_SIGNAL_BUS;
case MIPS_LINUX_SIGSYS:
return GDB_SIGNAL_SYS;
case MIPS_LINUX_SIGUSR1:
return GDB_SIGNAL_USR1;
case MIPS_LINUX_SIGUSR2:
return GDB_SIGNAL_USR2;
case MIPS_LINUX_SIGCHLD:
return GDB_SIGNAL_CHLD;
case MIPS_LINUX_SIGPWR:
return GDB_SIGNAL_PWR;
case MIPS_LINUX_SIGWINCH:
return GDB_SIGNAL_WINCH;
case MIPS_LINUX_SIGURG:
return GDB_SIGNAL_URG;
/* 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_LINUX_SIGTSTP:
return GDB_SIGNAL_TSTP;
case MIPS_LINUX_SIGCONT:
return GDB_SIGNAL_CONT;
case MIPS_LINUX_SIGTTIN:
return GDB_SIGNAL_TTIN;
case MIPS_LINUX_SIGTTOU:
return GDB_SIGNAL_TTOU;
case MIPS_LINUX_SIGVTALRM:
return GDB_SIGNAL_VTALRM;
case MIPS_LINUX_SIGPROF:
return GDB_SIGNAL_PROF;
case MIPS_LINUX_SIGXCPU:
return GDB_SIGNAL_XCPU;
case MIPS_LINUX_SIGXFSZ:
return GDB_SIGNAL_XFSZ;
}
if (signal >= MIPS_LINUX_SIGRTMIN && signal <= MIPS_LINUX_SIGRTMAX)
{ {
/* GDB_SIGNAL_REALTIME values are not contiguous, map parts of /* GDB_SIGNAL_REALTIME values are not contiguous, map parts of
the MIPS block to the respective GDB_SIGNAL_REALTIME blocks. */ the MIPS block to the respective GDB_SIGNAL_REALTIME blocks. */
signo -= MIPS_SIGRTMIN; int offset = signal - MIPS_LINUX_SIGRTMIN;
if (signo == 0)
if (offset == 0)
return GDB_SIGNAL_REALTIME_32; return GDB_SIGNAL_REALTIME_32;
else if (signo < 32) else if (offset < 32)
return ((enum gdb_signal) (signo - 1 + (int) GDB_SIGNAL_REALTIME_33)); return (enum gdb_signal) (offset - 1
+ (int) GDB_SIGNAL_REALTIME_33);
else 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. */ /* 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, set_gdbarch_gdb_signal_from_target (gdbarch,
mips_gdb_signal_from_target); 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; tdep->syscall_next_pc = mips_linux_syscall_next_pc;
if (tdesc_data) if (tdesc_data)

View File

@ -105,45 +105,3 @@ enum {
/* Return 1 if MIPS_RESTART_REGNUM is usable. */ /* Return 1 if MIPS_RESTART_REGNUM is usable. */
int mips_linux_restart_reg_p (struct gdbarch *gdbarch); 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. */
};

View File

@ -90,6 +90,31 @@ static const struct tramp_frame sparc32_linux_rt_sigframe =
sparc32_linux_sigframe_init 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 <arch/sparc/include/uapi/asm/signal.h>,
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 static void
sparc32_linux_sigframe_init (const struct tramp_frame *self, sparc32_linux_sigframe_init (const struct tramp_frame *self,
struct frame_info *this_frame, struct frame_info *this_frame,
@ -268,6 +293,114 @@ sparc32_linux_get_syscall_number (struct gdbarch *gdbarch,
return ret; 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 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_xml_syscall_file_name (XML_SYSCALL_FILENAME_SPARC32);
set_gdbarch_get_syscall_number (gdbarch, set_gdbarch_get_syscall_number (gdbarch,
sparc32_linux_get_syscall_number); 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. */ /* Provide a prototype to silence -Wmissing-prototypes. */

View File

@ -23,6 +23,75 @@
#include "solib-svr4.h" #include "solib-svr4.h"
#include "symtab.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 <arch/xtensa/include/uapi/asm/signal.h>,
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 <gdb/signals.def>,
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. */ /* OS specific initialization of gdbarch. */
static void static void
@ -32,6 +101,11 @@ xtensa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_solib_svr4_fetch_link_map_offsets set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_ilp32_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. */ /* Provide a prototype to silence -Wmissing-prototypes. */