* tilegx-tdep.c (INT_SWINT_1_SIGRETURN): New macro.

(tilegx_write_pc): New function.
        (tilegx_cannot_reference_register): Return zero if REGNO
        is TILEGX_FAULTNUM_REGNUM.
        (tilegx_gdbarch_init): Add call to set_gdbarch_write_pc.
        (tilegx_register_name): Add handling of "faultnum" register.
        * tilegx-tdep.h (enum tilegx_regnum): Add TILEGX_FAULTNUM_REGNUM.
        * tilegx-linux-tdep.c (tilegx_linux_supply_regset): Add
        handling of TILEGX_FAULTNUM_REGNUM.
        * tilegx-linux-nat.c (regmap): Add entry for TILEGX_FAULTNUM_REGNUM.
This commit is contained in:
Walter Lee 2013-02-19 16:19:33 +00:00
parent bc23a95694
commit 4aaf25031b
5 changed files with 54 additions and 7 deletions

View File

@ -1,3 +1,16 @@
2013-02-19 Jiong Wang <jiwang@tilera.com>
* tilegx-tdep.c (INT_SWINT_1_SIGRETURN): New macro.
(tilegx_write_pc): New function.
(tilegx_cannot_reference_register): Return zero if REGNO
is TILEGX_FAULTNUM_REGNUM.
(tilegx_gdbarch_init): Add call to set_gdbarch_write_pc.
(tilegx_register_name): Add handling of "faultnum" register.
* tilegx-tdep.h (enum tilegx_regnum): Add TILEGX_FAULTNUM_REGNUM.
* tilegx-linux-tdep.c (tilegx_linux_supply_regset): Add
handling of TILEGX_FAULTNUM_REGNUM.
* tilegx-linux-nat.c (regmap): Add entry for TILEGX_FAULTNUM_REGNUM.
2013-02-19 Jiong Wang <jiwang@tilera.com>
* tilegx-tdep.c (tilegx_push_dummy_call): args pushed on stack

View File

@ -65,7 +65,7 @@ static const int regmap[] =
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
-1, -1, -1, -1, -1, -1, -1, -1,
56
56, 58
};
/* Transfering the general-purpose registers between GDB, inferiors

View File

@ -85,9 +85,11 @@ tilegx_linux_supply_regset (const struct regset *regset,
int i;
/* This logic must match that of struct pt_regs in "ptrace.h". */
for (i = 0; i < TILEGX_NUM_EASY_REGS + 1; i++, ptr += tilegx_reg_size)
for (i = 0; i < TILEGX_NUM_EASY_REGS + 2; i++, ptr += tilegx_reg_size)
{
int gri = (i < TILEGX_NUM_EASY_REGS) ? i : TILEGX_PC_REGNUM;
int gri = (i < TILEGX_NUM_EASY_REGS)
? i : (i == TILEGX_NUM_EASY_REGS)
? TILEGX_PC_REGNUM : TILEGX_FAULTNUM_REGNUM;
if (regnum == gri || regnum == -1)
regcache_raw_supply (regcache, gri, ptr);

View File

@ -155,7 +155,7 @@ tilegx_register_name (struct gdbarch *gdbarch, int regnum)
"r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
"r48", "r49", "r50", "r51", "r52", "tp", "sp", "lr",
"sn", "idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero",
"pc"
"pc", "faultnum",
};
if (regnum < 0 || regnum >= TILEGX_NUM_REGS)
@ -772,6 +772,36 @@ tilegx_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
return 0;
}
/* by assigning the 'faultnum' reg in kernel pt_regs with this value,
kernel do_signal will not check r0. see tilegx kernel/signal.c
for details. */
#define INT_SWINT_1_SIGRETURN (~0)
/* Implement the "write_pc" gdbarch method. */
static void
tilegx_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
regcache_cooked_write_unsigned (regcache, TILEGX_PC_REGNUM, pc);
/* We must be careful with modifying the program counter. If we
just interrupted a system call, the kernel might try to restart
it when we resume the inferior. On restarting the system call,
the kernel will try backing up the program counter even though it
no longer points at the system call. This typically results in a
SIGSEGV or SIGILL. We can prevent this by writing INT_SWINT_1_SIGRETURN
in the "faultnum" pseudo-register.
Note that "faultnum" is saved when setting up a dummy call frame.
This means that it is properly restored when that frame is
popped, and that the interrupted system call will be restarted
when we resume the inferior on return from a function call from
within GDB. In all other cases the system call will not be
restarted. */
regcache_cooked_write_unsigned (regcache, TILEGX_FAULTNUM_REGNUM,
INT_SWINT_1_SIGRETURN);
}
/* This is the implementation of gdbarch method breakpoint_from_pc. */
static const unsigned char *
@ -903,7 +933,8 @@ tilegx_cannot_reference_register (struct gdbarch *gdbarch, int regno)
{
if (regno >= 0 && regno < TILEGX_NUM_EASY_REGS)
return 0;
else if (regno == TILEGX_PC_REGNUM)
else if (regno == TILEGX_PC_REGNUM
|| regno == TILEGX_FAULTNUM_REGNUM)
return 0;
else
return 1;
@ -986,6 +1017,7 @@ tilegx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* These values and methods are used when gdb calls a target function. */
set_gdbarch_push_dummy_call (gdbarch, tilegx_push_dummy_call);
set_gdbarch_write_pc (gdbarch, tilegx_write_pc);
set_gdbarch_breakpoint_from_pc (gdbarch, tilegx_breakpoint_from_pc);
set_gdbarch_return_value (gdbarch, tilegx_return_value);

View File

@ -100,8 +100,8 @@ enum tilegx_regnum
TILEGX_PC_REGNUM,
TILEGX_NUM_PHYS_REGS = TILEGX_PC_REGNUM, /* 64 */
TILEGX_NUM_REGS /* 65 */
TILEGX_FAULTNUM_REGNUM,
TILEGX_NUM_REGS, /* 66 */
};
enum { tilegx_reg_size = 8 };