| Index: gdb/mips-linux-tdep.c
|
| diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
|
| index 272e8d99acad5a27b5eab298cf6625ab10e112e2..37a37c195c453c9d1f967c17abcbebb02ca62a30 100644
|
| --- a/gdb/mips-linux-tdep.c
|
| +++ b/gdb/mips-linux-tdep.c
|
| @@ -1,6 +1,6 @@
|
| /* Target-dependent code for GNU/Linux on MIPS processors.
|
|
|
| - Copyright (C) 2001-2002, 2004-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -23,13 +23,14 @@
|
| #include "solib-svr4.h"
|
| #include "osabi.h"
|
| #include "mips-tdep.h"
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
| #include "gdb_assert.h"
|
| #include "frame.h"
|
| #include "regcache.h"
|
| #include "trad-frame.h"
|
| #include "tramp-frame.h"
|
| #include "gdbtypes.h"
|
| +#include "objfiles.h"
|
| #include "solib.h"
|
| #include "solib-svr4.h"
|
| #include "solist.h"
|
| @@ -44,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 <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.
|
| 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
|
| @@ -59,12 +96,12 @@ mips_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
|
| CORE_ADDR jb_addr;
|
| struct gdbarch *gdbarch = get_frame_arch (frame);
|
| enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
| - char buf[gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT];
|
| + gdb_byte buf[gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT];
|
|
|
| jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);
|
|
|
| - if (target_read_memory (jb_addr
|
| - + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE,
|
| + if (target_read_memory ((jb_addr
|
| + + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE),
|
| buf, gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT))
|
| return 0;
|
|
|
| @@ -86,7 +123,7 @@ supply_32bit_reg (struct regcache *regcache, int regnum, const void *addr)
|
| enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
| gdb_byte buf[MAX_REGISTER_SIZE];
|
| store_signed_integer (buf, register_size (gdbarch, regnum), byte_order,
|
| - extract_signed_integer (addr, 4, byte_order));
|
| + extract_signed_integer (addr, 4, byte_order));
|
| regcache_raw_supply (regcache, regnum, buf);
|
| }
|
|
|
| @@ -126,8 +163,8 @@ mips_supply_gregset (struct regcache *regcache,
|
|
|
| static void
|
| mips_supply_gregset_wrapper (const struct regset *regset,
|
| - struct regcache *regcache,
|
| - int regnum, const void *gregs, size_t len)
|
| + struct regcache *regcache,
|
| + int regnum, const void *gregs, size_t len)
|
| {
|
| gdb_assert (len == sizeof (mips_elf_gregset_t));
|
|
|
| @@ -231,8 +268,8 @@ mips_supply_fpregset (struct regcache *regcache,
|
|
|
| static void
|
| mips_supply_fpregset_wrapper (const struct regset *regset,
|
| - struct regcache *regcache,
|
| - int regnum, const void *gregs, size_t len)
|
| + struct regcache *regcache,
|
| + int regnum, const void *gregs, size_t len)
|
| {
|
| gdb_assert (len == sizeof (mips_elf_fpregset_t));
|
|
|
| @@ -350,11 +387,11 @@ mips64_supply_gregset (struct regcache *regcache,
|
|
|
| for (regi = MIPS64_EF_REG0 + 1; regi <= MIPS64_EF_REG31; regi++)
|
| supply_64bit_reg (regcache, regi - MIPS64_EF_REG0,
|
| - (const gdb_byte *)(regp + regi));
|
| + (const gdb_byte *) (regp + regi));
|
|
|
| if (mips_linux_restart_reg_p (gdbarch))
|
| supply_64bit_reg (regcache, MIPS_RESTART_REGNUM,
|
| - (const gdb_byte *)(regp + MIPS64_EF_REG0));
|
| + (const gdb_byte *) (regp + MIPS64_EF_REG0));
|
|
|
| supply_64bit_reg (regcache, mips_regnum (gdbarch)->lo,
|
| (const gdb_byte *) (regp + MIPS64_EF_LO));
|
| @@ -376,8 +413,8 @@ mips64_supply_gregset (struct regcache *regcache,
|
|
|
| static void
|
| mips64_supply_gregset_wrapper (const struct regset *regset,
|
| - struct regcache *regcache,
|
| - int regnum, const void *gregs, size_t len)
|
| + struct regcache *regcache,
|
| + int regnum, const void *gregs, size_t len)
|
| {
|
| gdb_assert (len == sizeof (mips64_elf_gregset_t));
|
|
|
| @@ -400,7 +437,7 @@ mips64_fill_gregset (const struct regcache *regcache,
|
| {
|
| memset (regp, 0, sizeof (mips64_elf_gregset_t));
|
| for (regi = 1; regi < 32; regi++)
|
| - mips64_fill_gregset (regcache, gregsetp, regi);
|
| + mips64_fill_gregset (regcache, gregsetp, regi);
|
| mips64_fill_gregset (regcache, gregsetp, mips_regnum (gdbarch)->lo);
|
| mips64_fill_gregset (regcache, gregsetp, mips_regnum (gdbarch)->hi);
|
| mips64_fill_gregset (regcache, gregsetp, mips_regnum (gdbarch)->pc);
|
| @@ -469,7 +506,8 @@ mips64_supply_fpregset (struct regcache *regcache,
|
| if (register_size (gdbarch, gdbarch_fp0_regnum (gdbarch)) == 4)
|
| for (regi = 0; regi < 32; regi++)
|
| {
|
| - const gdb_byte *reg_ptr = (const gdb_byte *)(*fpregsetp + (regi & ~1));
|
| + const gdb_byte *reg_ptr
|
| + = (const gdb_byte *) (*fpregsetp + (regi & ~1));
|
| if ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) != (regi & 1))
|
| reg_ptr += 4;
|
| regcache_raw_supply (regcache,
|
| @@ -480,23 +518,23 @@ mips64_supply_fpregset (struct regcache *regcache,
|
| for (regi = 0; regi < 32; regi++)
|
| regcache_raw_supply (regcache,
|
| gdbarch_fp0_regnum (gdbarch) + regi,
|
| - (const char *)(*fpregsetp + regi));
|
| + (const char *) (*fpregsetp + regi));
|
|
|
| supply_32bit_reg (regcache, mips_regnum (gdbarch)->fp_control_status,
|
| - (const gdb_byte *)(*fpregsetp + 32));
|
| + (const gdb_byte *) (*fpregsetp + 32));
|
|
|
| /* The ABI doesn't tell us how to supply FCRIR, and core dumps don't
|
| include it - but the result of PTRACE_GETFPREGS does. The best we
|
| can do is to assume that its value is present. */
|
| supply_32bit_reg (regcache,
|
| mips_regnum (gdbarch)->fp_implementation_revision,
|
| - (const gdb_byte *)(*fpregsetp + 32) + 4);
|
| + (const gdb_byte *) (*fpregsetp + 32) + 4);
|
| }
|
|
|
| static void
|
| mips64_supply_fpregset_wrapper (const struct regset *regset,
|
| - struct regcache *regcache,
|
| - int regnum, const void *gregs, size_t len)
|
| + struct regcache *regcache,
|
| + int regnum, const void *gregs, size_t len)
|
| {
|
| gdb_assert (len == sizeof (mips64_elf_fpregset_t));
|
|
|
| @@ -567,8 +605,7 @@ mips64_fill_fpregset (const struct regcache *regcache,
|
| mips64_fill_fpregset (regcache, fpregsetp,
|
| mips_regnum (gdbarch)->fp_control_status);
|
| mips64_fill_fpregset (regcache, fpregsetp,
|
| - (mips_regnum (gdbarch)
|
| - ->fp_implementation_revision));
|
| + mips_regnum (gdbarch)->fp_implementation_revision);
|
| }
|
| }
|
|
|
| @@ -584,7 +621,7 @@ mips64_fill_fpregset_wrapper (const struct regset *regset,
|
|
|
| static const struct regset *
|
| mips_linux_regset_from_core_section (struct gdbarch *gdbarch,
|
| - const char *sect_name, size_t sect_size)
|
| + const char *sect_name, size_t sect_size)
|
| {
|
| struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
| mips_elf_gregset_t gregset;
|
| @@ -598,16 +635,16 @@ mips_linux_regset_from_core_section (struct gdbarch *gdbarch,
|
| {
|
| if (tdep->gregset == NULL)
|
| tdep->gregset = regset_alloc (gdbarch,
|
| - mips_supply_gregset_wrapper,
|
| - mips_fill_gregset_wrapper);
|
| + mips_supply_gregset_wrapper,
|
| + mips_fill_gregset_wrapper);
|
| return tdep->gregset;
|
| }
|
| else if (sect_size == sizeof (gregset64))
|
| {
|
| if (tdep->gregset64 == NULL)
|
| tdep->gregset64 = regset_alloc (gdbarch,
|
| - mips64_supply_gregset_wrapper,
|
| - mips64_fill_gregset_wrapper);
|
| + mips64_supply_gregset_wrapper,
|
| + mips64_fill_gregset_wrapper);
|
| return tdep->gregset64;
|
| }
|
| else
|
| @@ -621,16 +658,16 @@ mips_linux_regset_from_core_section (struct gdbarch *gdbarch,
|
| {
|
| if (tdep->fpregset == NULL)
|
| tdep->fpregset = regset_alloc (gdbarch,
|
| - mips_supply_fpregset_wrapper,
|
| - mips_fill_fpregset_wrapper);
|
| + mips_supply_fpregset_wrapper,
|
| + mips_fill_fpregset_wrapper);
|
| return tdep->fpregset;
|
| }
|
| else if (sect_size == sizeof (fpregset64))
|
| {
|
| if (tdep->fpregset64 == NULL)
|
| tdep->fpregset64 = regset_alloc (gdbarch,
|
| - mips64_supply_fpregset_wrapper,
|
| - mips64_fill_fpregset_wrapper);
|
| + mips64_supply_fpregset_wrapper,
|
| + mips64_fill_fpregset_wrapper);
|
| return tdep->fpregset64;
|
| }
|
| else
|
| @@ -666,24 +703,33 @@ mips_linux_core_read_description (struct gdbarch *gdbarch,
|
|
|
|
|
| /* Check the code at PC for a dynamic linker lazy resolution stub.
|
| - Because they aren't in the .plt section, we pattern-match on the
|
| - code generated by GNU ld. They look like this:
|
| + GNU ld for MIPS has put lazy resolution stubs into a ".MIPS.stubs"
|
| + section uniformly since version 2.15. If the pc is in that section,
|
| + then we are in such a stub. Before that ".stub" was used in 32-bit
|
| + ELF binaries, however we do not bother checking for that since we
|
| + have never had and that case should be extremely rare these days.
|
| + Instead we pattern-match on the code generated by GNU ld. They look
|
| + like this:
|
|
|
| lw t9,0x8010(gp)
|
| addu t7,ra
|
| jalr t9,ra
|
| addiu t8,zero,INDEX
|
|
|
| - (with the appropriate doubleword instructions for N64). Also
|
| - return the dynamic symbol index used in the last instruction. */
|
| + (with the appropriate doubleword instructions for N64). As any lazy
|
| + resolution stubs in microMIPS binaries will always be in a
|
| + ".MIPS.stubs" section we only ever verify standard MIPS patterns. */
|
|
|
| static int
|
| -mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name)
|
| +mips_linux_in_dynsym_stub (CORE_ADDR pc)
|
| {
|
| - unsigned char buf[28], *p;
|
| + gdb_byte buf[28], *p;
|
| ULONGEST insn, insn1;
|
| - int n64 = (mips_abi (target_gdbarch) == MIPS_ABI_N64);
|
| - enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
|
| + int n64 = (mips_abi (target_gdbarch ()) == MIPS_ABI_N64);
|
| + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
|
| +
|
| + if (in_mips_stubs_section (pc))
|
| + return 1;
|
|
|
| read_memory (pc - 12, buf, 28);
|
|
|
| @@ -742,7 +788,7 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name)
|
| return 0;
|
| }
|
|
|
| - return (insn & 0xffff);
|
| + return 1;
|
| }
|
|
|
| /* Return non-zero iff PC belongs to the dynamic linker resolution
|
| @@ -756,9 +802,10 @@ mips_linux_in_dynsym_resolve_code (CORE_ADDR pc)
|
| if (svr4_in_dynsym_resolve_code (pc))
|
| return 1;
|
|
|
| - /* Pattern match for the stub. It would be nice if there were a
|
| - more efficient way to avoid this check. */
|
| - if (mips_linux_in_dynsym_stub (pc, NULL))
|
| + /* Likewise for the stubs. They live in the .MIPS.stubs section these
|
| + days, so we check if the PC is within, than fall back to a pattern
|
| + match. */
|
| + if (mips_linux_in_dynsym_stub (pc))
|
| return 1;
|
|
|
| return 0;
|
| @@ -999,10 +1046,10 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
|
|
|
| for (ireg = 1; ireg < 32; ireg++)
|
| trad_frame_set_reg_addr (this_cache,
|
| - ireg + MIPS_ZERO_REGNUM
|
| - + gdbarch_num_regs (gdbarch),
|
| - regs_base + SIGCONTEXT_REGS
|
| - + ireg * SIGCONTEXT_REG_SIZE);
|
| + (ireg + MIPS_ZERO_REGNUM
|
| + + gdbarch_num_regs (gdbarch)),
|
| + (regs_base + SIGCONTEXT_REGS
|
| + + ireg * SIGCONTEXT_REG_SIZE));
|
|
|
| /* The way that floating point registers are saved, unfortunately,
|
| depends on the architecture the kernel is built for. For the r3000 and
|
| @@ -1015,24 +1062,22 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
|
| for (ireg = 0; ireg < 32; ireg++)
|
| if ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) != (ireg & 1))
|
| trad_frame_set_reg_addr (this_cache,
|
| - ireg + regs->fp0 +
|
| - gdbarch_num_regs (gdbarch),
|
| - sigcontext_base + SIGCONTEXT_FPREGS + 4
|
| - + (ireg & ~1) * SIGCONTEXT_REG_SIZE);
|
| + ireg + regs->fp0 + gdbarch_num_regs (gdbarch),
|
| + (sigcontext_base + SIGCONTEXT_FPREGS + 4
|
| + + (ireg & ~1) * SIGCONTEXT_REG_SIZE));
|
| else
|
| trad_frame_set_reg_addr (this_cache,
|
| - ireg + regs->fp0
|
| - + gdbarch_num_regs (gdbarch),
|
| - sigcontext_base + SIGCONTEXT_FPREGS
|
| - + (ireg & ~1) * SIGCONTEXT_REG_SIZE);
|
| + ireg + regs->fp0 + gdbarch_num_regs (gdbarch),
|
| + (sigcontext_base + SIGCONTEXT_FPREGS
|
| + + (ireg & ~1) * SIGCONTEXT_REG_SIZE));
|
|
|
| trad_frame_set_reg_addr (this_cache,
|
| regs->pc + gdbarch_num_regs (gdbarch),
|
| regs_base + SIGCONTEXT_PC);
|
|
|
| trad_frame_set_reg_addr (this_cache,
|
| - regs->fp_control_status
|
| - + gdbarch_num_regs (gdbarch),
|
| + (regs->fp_control_status
|
| + + gdbarch_num_regs (gdbarch)),
|
| sigcontext_base + SIGCONTEXT_FPCSR);
|
|
|
| if (regs->dspctl != -1)
|
| @@ -1192,25 +1237,24 @@ mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
|
|
|
| for (ireg = 1; ireg < 32; ireg++)
|
| trad_frame_set_reg_addr (this_cache,
|
| - ireg + MIPS_ZERO_REGNUM
|
| - + gdbarch_num_regs (gdbarch),
|
| - sigcontext_base + N64_SIGCONTEXT_REGS
|
| - + ireg * N64_SIGCONTEXT_REG_SIZE);
|
| + (ireg + MIPS_ZERO_REGNUM
|
| + + gdbarch_num_regs (gdbarch)),
|
| + (sigcontext_base + N64_SIGCONTEXT_REGS
|
| + + ireg * N64_SIGCONTEXT_REG_SIZE));
|
|
|
| for (ireg = 0; ireg < 32; ireg++)
|
| trad_frame_set_reg_addr (this_cache,
|
| - ireg + regs->fp0
|
| - + gdbarch_num_regs (gdbarch),
|
| - sigcontext_base + N64_SIGCONTEXT_FPREGS
|
| - + ireg * N64_SIGCONTEXT_REG_SIZE);
|
| + ireg + regs->fp0 + gdbarch_num_regs (gdbarch),
|
| + (sigcontext_base + N64_SIGCONTEXT_FPREGS
|
| + + ireg * N64_SIGCONTEXT_REG_SIZE));
|
|
|
| trad_frame_set_reg_addr (this_cache,
|
| regs->pc + gdbarch_num_regs (gdbarch),
|
| sigcontext_base + N64_SIGCONTEXT_PC);
|
|
|
| trad_frame_set_reg_addr (this_cache,
|
| - regs->fp_control_status
|
| - + gdbarch_num_regs (gdbarch),
|
| + (regs->fp_control_status
|
| + + gdbarch_num_regs (gdbarch)),
|
| sigcontext_base + N64_SIGCONTEXT_FPCSR);
|
|
|
| trad_frame_set_reg_addr (this_cache,
|
| @@ -1331,94 +1375,184 @@ mips_linux_get_syscall_number (struct gdbarch *gdbarch,
|
| return ret;
|
| }
|
|
|
| -/* Translate signals based on MIPS signal values.
|
| +/* 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.
|
| 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. */
|
| @@ -1440,7 +1574,7 @@ mips_linux_init_abi (struct gdbarch_info info,
|
| {
|
| case MIPS_ABI_O32:
|
| set_gdbarch_get_longjmp_target (gdbarch,
|
| - mips_linux_get_longjmp_target);
|
| + mips_linux_get_longjmp_target);
|
| set_solib_svr4_fetch_link_map_offsets
|
| (gdbarch, svr4_ilp32_fetch_link_map_offsets);
|
| tramp_frame_prepend_unwinder (gdbarch, &mips_linux_o32_sigframe);
|
| @@ -1449,7 +1583,7 @@ mips_linux_init_abi (struct gdbarch_info info,
|
| break;
|
| case MIPS_ABI_N32:
|
| set_gdbarch_get_longjmp_target (gdbarch,
|
| - mips_linux_get_longjmp_target);
|
| + mips_linux_get_longjmp_target);
|
| set_solib_svr4_fetch_link_map_offsets
|
| (gdbarch, svr4_ilp32_fetch_link_map_offsets);
|
| set_gdbarch_long_double_bit (gdbarch, 128);
|
| @@ -1463,7 +1597,7 @@ mips_linux_init_abi (struct gdbarch_info info,
|
| break;
|
| case MIPS_ABI_N64:
|
| set_gdbarch_get_longjmp_target (gdbarch,
|
| - mips64_linux_get_longjmp_target);
|
| + mips64_linux_get_longjmp_target);
|
| set_solib_svr4_fetch_link_map_offsets
|
| (gdbarch, svr4_lp64_fetch_link_map_offsets);
|
| set_gdbarch_long_double_bit (gdbarch, 128);
|
| @@ -1485,7 +1619,7 @@ mips_linux_init_abi (struct gdbarch_info info,
|
|
|
| /* Enable TLS support. */
|
| set_gdbarch_fetch_tls_load_module_address (gdbarch,
|
| - svr4_fetch_objfile_link_map);
|
| + svr4_fetch_objfile_link_map);
|
|
|
| /* Initialize this lazily, to avoid an initialization order
|
| dependency on solib-svr4.c's _initialize routine. */
|
| @@ -1508,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)
|
|
|