/* dwarf regs 32 to 85 are fpregs 4 - 31 */
if (reg >= 32 && reg <= 85)
- return FP4_REGNUM + (reg - 32);
+ return HPPA_FP4_REGNUM + (reg - 32);
warning ("Unmapped DWARF Register #%d encountered\n", reg);
return -1;
hppa_linux_target_write_pc (CORE_ADDR v, ptid_t ptid)
{
/* Probably this should be done by the kernel, but it isn't. */
- write_register_pid (PCOQ_HEAD_REGNUM, v | 0x3, ptid);
- write_register_pid (PCOQ_TAIL_REGNUM, (v + 4) | 0x3, ptid);
+ write_register_pid (HPPA_PCOQ_HEAD_REGNUM, v | 0x3, ptid);
+ write_register_pid (HPPA_PCOQ_TAIL_REGNUM, (v + 4) | 0x3, ptid);
}
/* An instruction to match. */
for (i = 0; pattern[i].mask; i++)
{
- insn[i] = read_memory_unsigned_integer (npc, 4);
+ char buf[4];
+
+ read_memory_nobpt (npc, buf, 4);
+ insn[i] = extract_unsigned_integer (buf, 4);
if ((insn[i] & pattern[i].mask) == pattern[i].data)
npc += 4;
else
Note that with a 2.4 64-bit kernel, the signal context is not properly
passed back to userspace so the unwind will not work correctly. */
static CORE_ADDR
-hppa_linux_sigtramp_find_sigcontext (CORE_ADDR sp)
+hppa_linux_sigtramp_find_sigcontext (CORE_ADDR pc)
{
unsigned int dummy[HPPA_MAX_INSN_PATTERN_LEN];
int offs = 0;
static int pcoffs[] = { 0, 4*4, 5*4 };
/* offsets to the rt_sigframe structure */
static int sfoffs[] = { 4*4, 10*4, 10*4 };
+ CORE_ADDR sp;
+
+ /* Most of the time, this will be correct. The one case when this will
+ fail is if the user defined an alternate stack, in which case the
+ beginning of the stack will not be align_down (pc, 64). */
+ sp = align_down (pc, 64);
/* rt_sigreturn trampoline:
3419000x ldi 0, %r25 or ldi 1, %r25 (x = 0 or 2)
}
if (offs == 0)
- return 0;
+ {
+ if (insns_match_pattern (pc, hppa_sigtramp, dummy))
+ {
+ /* sigaltstack case: we have no way of knowing which offset to
+ use in this case; default to new kernel handling. If this is
+ wrong the unwinding will fail. */
+ try = 2;
+ sp = pc - pcoffs[try];
+ }
+ else
+ {
+ return 0;
+ }
+ }
/* sp + sfoffs[try] points to a struct rt_sigframe, which contains
a struct siginfo and a struct ucontext. struct ucontext contains
{
struct gdbarch *gdbarch = get_frame_arch (next_frame);
struct hppa_linux_sigtramp_unwind_cache *info;
- CORE_ADDR sp, pc, scptr;
+ CORE_ADDR pc, scptr;
int i;
if (*this_cache)
info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
pc = frame_pc_unwind (next_frame);
- sp = (pc & ~63);
- scptr = hppa_linux_sigtramp_find_sigcontext (sp);
+ scptr = hppa_linux_sigtramp_find_sigcontext (pc);
/* structure of struct sigcontext:
/* General registers. */
for (i = 1; i < 32; i++)
{
- info->saved_regs[R0_REGNUM + i].addr = scptr;
+ info->saved_regs[HPPA_R0_REGNUM + i].addr = scptr;
scptr += 4;
}
}
/* IASQ/IAOQ. */
- info->saved_regs[PCSQ_HEAD_REGNUM].addr = scptr;
+ info->saved_regs[HPPA_PCSQ_HEAD_REGNUM].addr = scptr;
scptr += 4;
- info->saved_regs[PCSQ_TAIL_REGNUM].addr = scptr;
+ info->saved_regs[HPPA_PCSQ_TAIL_REGNUM].addr = scptr;
scptr += 4;
- info->saved_regs[PCOQ_HEAD_REGNUM].addr = scptr;
+ info->saved_regs[HPPA_PCOQ_HEAD_REGNUM].addr = scptr;
scptr += 4;
- info->saved_regs[PCOQ_TAIL_REGNUM].addr = scptr;
+ info->saved_regs[HPPA_PCOQ_TAIL_REGNUM].addr = scptr;
scptr += 4;
- info->base = read_memory_unsigned_integer (
- info->saved_regs[HPPA_SP_REGNUM].addr, 4);
+ info->base = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM);
return info;
}
int regnum, int *optimizedp,
enum lval_type *lvalp,
CORE_ADDR *addrp,
- int *realnump, void *bufferp)
+ int *realnump, void *valuep)
{
struct hppa_linux_sigtramp_unwind_cache *info
= hppa_linux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
- int pcoqt = (regnum == PCOQ_TAIL_REGNUM);
-
- if (pcoqt)
- regnum = PCOQ_HEAD_REGNUM;
-
- trad_frame_prev_register (next_frame, info->saved_regs, regnum,
- optimizedp, lvalp, addrp, realnump, bufferp);
-
- if (pcoqt)
- store_unsigned_integer (bufferp, 4,
- extract_unsigned_integer (bufferp, 4) + 4);
+ hppa_frame_prev_register_helper (next_frame, info->saved_regs, regnum,
+ optimizedp, lvalp, addrp, realnump, valuep);
}
static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
hppa_linux_sigtramp_unwind_sniffer (struct frame_info *next_frame)
{
CORE_ADDR pc = frame_pc_unwind (next_frame);
- CORE_ADDR sp = (pc & ~63);
- if (hppa_linux_sigtramp_find_sigcontext (sp))
+ if (hppa_linux_sigtramp_find_sigcontext (pc))
return &hppa_linux_sigtramp_frame_unwind;
return NULL;