* 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:
parent
bc23a95694
commit
4aaf25031b
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 };
|
||||
|
|
Loading…
Reference in New Issue