* hppa-tdep.h (hppa_read_pc, hppa_write_pc, hppa_unwind_pc): New
prototypes. * hppa-tdep.c (hppa_read_pc): Rename from hppa_target_read_pc. Make global. Remove HP-UX specific code. Use frame_unwind_register_unsigned instead of frame_unwind_register_signed. (hppa_write_pc): Rename from hppa_target_write_pc. Make global. Remove HP-UX specific code. (hppa_unwind_pc): Make global. Remove HP-UX specific code. (hppa_frame_prev_register_helper): Set "flags" register to zero for all unwound frames. (hppa_gdbarch_init): Adjust. * hppa-hpux-tdep.c (HPPA_HPUX_SS_INSYSCALL): New define. (hppa_hpux_read_pc, hppa_hpux_write_pc) (hppa_hpux_unwind_pc): New functions. (hppa_hpux_init_abi): Set read_pc, write_pc and unwind_pc.
This commit is contained in:
parent
cb9faf63f8
commit
cc72850f95
4 changed files with 114 additions and 45 deletions
|
@ -1,3 +1,22 @@
|
||||||
|
2004-12-07 Mark Kettenis <kettenis@gnu.org>
|
||||||
|
|
||||||
|
* hppa-tdep.h (hppa_read_pc, hppa_write_pc, hppa_unwind_pc): New
|
||||||
|
prototypes.
|
||||||
|
* hppa-tdep.c (hppa_read_pc): Rename from hppa_target_read_pc.
|
||||||
|
Make global. Remove HP-UX specific code. Use
|
||||||
|
frame_unwind_register_unsigned instead of
|
||||||
|
frame_unwind_register_signed.
|
||||||
|
(hppa_write_pc): Rename from hppa_target_write_pc. Make global.
|
||||||
|
Remove HP-UX specific code.
|
||||||
|
(hppa_unwind_pc): Make global. Remove HP-UX specific code.
|
||||||
|
(hppa_frame_prev_register_helper): Set "flags" register to zero
|
||||||
|
for all unwound frames.
|
||||||
|
(hppa_gdbarch_init): Adjust.
|
||||||
|
* hppa-hpux-tdep.c (HPPA_HPUX_SS_INSYSCALL): New define.
|
||||||
|
(hppa_hpux_read_pc, hppa_hpux_write_pc)
|
||||||
|
(hppa_hpux_unwind_pc): New functions.
|
||||||
|
(hppa_hpux_init_abi): Set read_pc, write_pc and unwind_pc.
|
||||||
|
|
||||||
2004-12-07 Andreas Schwab <schwab@suse.de>
|
2004-12-07 Andreas Schwab <schwab@suse.de>
|
||||||
|
|
||||||
* main.c (long_options): Add entry for "-l".
|
* main.c (long_options): Add entry for "-l".
|
||||||
|
|
|
@ -1415,6 +1415,52 @@ hppa_hpux_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
|
||||||
|
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Bit in the `ss_flag' member of `struct save_state' that indicates
|
||||||
|
the state was saved from a system call. From
|
||||||
|
<machine/save_state.h>. */
|
||||||
|
#define HPPA_HPUX_SS_INSYSCALL 0x02
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
hppa_hpux_read_pc (ptid_t ptid)
|
||||||
|
{
|
||||||
|
ULONGEST flags;
|
||||||
|
|
||||||
|
/* If we're currently in a system call return the contents of %r31. */
|
||||||
|
flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid);
|
||||||
|
if (flags & HPPA_HPUX_SS_INSYSCALL)
|
||||||
|
return read_register_pid (HPPA_R31_REGNUM, ptid) & ~0x3;
|
||||||
|
|
||||||
|
return hppa_read_pc (ptid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
hppa_hpux_write_pc (CORE_ADDR pc, ptid_t ptid)
|
||||||
|
{
|
||||||
|
ULONGEST flags;
|
||||||
|
|
||||||
|
/* If we're currently in a system call also write PC into %r31. */
|
||||||
|
flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid);
|
||||||
|
if (flags & HPPA_HPUX_SS_INSYSCALL)
|
||||||
|
write_register_pid (HPPA_R31_REGNUM, pc | 0x3, ptid);
|
||||||
|
|
||||||
|
return hppa_write_pc (pc, ptid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
hppa_hpux_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
|
||||||
|
{
|
||||||
|
ULONGEST flags;
|
||||||
|
|
||||||
|
/* If we're currently in a system call return the contents of %r31. */
|
||||||
|
flags = frame_unwind_register_unsigned (next_frame, HPPA_FLAGS_REGNUM);
|
||||||
|
if (flags & HPPA_HPUX_SS_INSYSCALL)
|
||||||
|
return frame_unwind_register_unsigned (next_frame, HPPA_R31_REGNUM) & ~0x3;
|
||||||
|
|
||||||
|
return hppa_unwind_pc (gdbarch, next_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hppa_hpux_inferior_created (struct target_ops *objfile, int from_tty)
|
hppa_hpux_inferior_created (struct target_ops *objfile, int from_tty)
|
||||||
|
@ -1442,6 +1488,10 @@ hppa_hpux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
set_gdbarch_push_dummy_code (gdbarch, hppa_hpux_push_dummy_code);
|
set_gdbarch_push_dummy_code (gdbarch, hppa_hpux_push_dummy_code);
|
||||||
set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
|
set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
|
||||||
|
|
||||||
|
set_gdbarch_read_pc (gdbarch, hppa_hpux_read_pc);
|
||||||
|
set_gdbarch_write_pc (gdbarch, hppa_hpux_write_pc);
|
||||||
|
set_gdbarch_unwind_pc (gdbarch, hppa_hpux_unwind_pc);
|
||||||
|
|
||||||
frame_unwind_append_sniffer (gdbarch, hppa_hpux_sigtramp_unwind_sniffer);
|
frame_unwind_append_sniffer (gdbarch, hppa_hpux_sigtramp_unwind_sniffer);
|
||||||
|
|
||||||
observer_attach_inferior_created (hppa_hpux_inferior_created);
|
observer_attach_inferior_created (hppa_hpux_inferior_created);
|
||||||
|
|
|
@ -1034,54 +1034,31 @@ hppa64_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
|
||||||
return align_up (addr, 16);
|
return align_up (addr, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CORE_ADDR
|
||||||
/* Get the PC from %r31 if currently in a syscall. Also mask out privilege
|
hppa_read_pc (ptid_t ptid)
|
||||||
bits. */
|
|
||||||
|
|
||||||
static CORE_ADDR
|
|
||||||
hppa_target_read_pc (ptid_t ptid)
|
|
||||||
{
|
{
|
||||||
int flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid);
|
ULONGEST ipsw;
|
||||||
ULONGEST ipsw = read_register_pid (HPPA_IPSW_REGNUM, ptid);
|
|
||||||
CORE_ADDR pc;
|
CORE_ADDR pc;
|
||||||
|
|
||||||
/* The following test does not belong here. It is OS-specific, and belongs
|
ipsw = read_register_pid (HPPA_IPSW_REGNUM, ptid);
|
||||||
in native code. */
|
pc = read_register_pid (HPPA_PCOQ_HEAD_REGNUM, ptid);
|
||||||
/* Test SS_INSYSCALL */
|
|
||||||
if (flags & 2)
|
|
||||||
return read_register_pid (31, ptid) & ~0x3;
|
|
||||||
|
|
||||||
pc = read_register_pid (HPPA_PCOQ_HEAD_REGNUM, ptid) & ~0x3;
|
|
||||||
|
|
||||||
/* If the current instruction is nullified, then we are effectively
|
/* If the current instruction is nullified, then we are effectively
|
||||||
still executing the previous instruction. Pretend we are still
|
still executing the previous instruction. Pretend we are still
|
||||||
there. This is needed when single stepping; if the nullified instruction
|
there. This is needed when single stepping; if the nullified
|
||||||
is on a different line, we don't want gdb to think we've stepped onto
|
instruction is on a different line, we don't want GDB to think
|
||||||
that line. */
|
we've stepped onto that line. */
|
||||||
if (ipsw & 0x00200000)
|
if (ipsw & 0x00200000)
|
||||||
pc -= 4;
|
pc -= 4;
|
||||||
|
|
||||||
return pc;
|
return pc & ~0x3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out the PC. If currently in a syscall, then also write the new
|
void
|
||||||
PC value into %r31. */
|
hppa_write_pc (CORE_ADDR pc, ptid_t ptid)
|
||||||
|
|
||||||
static void
|
|
||||||
hppa_target_write_pc (CORE_ADDR v, ptid_t ptid)
|
|
||||||
{
|
{
|
||||||
int flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid);
|
write_register_pid (HPPA_PCOQ_HEAD_REGNUM, pc, ptid);
|
||||||
|
write_register_pid (HPPA_PCOQ_TAIL_REGNUM, pc + 4, ptid);
|
||||||
/* The following test does not belong here. It is OS-specific, and belongs
|
|
||||||
in native code. */
|
|
||||||
/* If in a syscall, then set %r31. Also make sure to get the
|
|
||||||
privilege bits set correctly. */
|
|
||||||
/* Test SS_INSYSCALL */
|
|
||||||
if (flags & 2)
|
|
||||||
write_register_pid (31, v | 0x3, ptid);
|
|
||||||
|
|
||||||
write_register_pid (HPPA_PCOQ_HEAD_REGNUM, v, ptid);
|
|
||||||
write_register_pid (HPPA_PCOQ_TAIL_REGNUM, v + 4, ptid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the alignment of a type in bytes. Structures have the maximum
|
/* return the alignment of a type in bytes. Structures have the maximum
|
||||||
|
@ -2194,24 +2171,24 @@ hppa_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
|
||||||
frame_pc_unwind (next_frame));
|
frame_pc_unwind (next_frame));
|
||||||
}
|
}
|
||||||
|
|
||||||
static CORE_ADDR
|
CORE_ADDR
|
||||||
hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
|
hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
|
||||||
{
|
{
|
||||||
ULONGEST ipsw;
|
ULONGEST ipsw;
|
||||||
CORE_ADDR pc;
|
CORE_ADDR pc;
|
||||||
|
|
||||||
ipsw = frame_unwind_register_signed (next_frame, HPPA_IPSW_REGNUM);
|
ipsw = frame_unwind_register_unsigned (next_frame, HPPA_IPSW_REGNUM);
|
||||||
pc = frame_unwind_register_signed (next_frame, HPPA_PCOQ_HEAD_REGNUM) & ~3;
|
pc = frame_unwind_register_unsigned (next_frame, HPPA_PCOQ_HEAD_REGNUM);
|
||||||
|
|
||||||
/* If the current instruction is nullified, then we are effectively
|
/* If the current instruction is nullified, then we are effectively
|
||||||
still executing the previous instruction. Pretend we are still
|
still executing the previous instruction. Pretend we are still
|
||||||
there. This is needed when single stepping; if the nullified instruction
|
there. This is needed when single stepping; if the nullified
|
||||||
is on a different line, we don't want gdb to think we've stepped onto
|
instruction is on a different line, we don't want GDB to think
|
||||||
that line. */
|
we've stepped onto that line. */
|
||||||
if (ipsw & 0x00200000)
|
if (ipsw & 0x00200000)
|
||||||
pc -= 4;
|
pc -= 4;
|
||||||
|
|
||||||
return pc;
|
return pc & ~0x3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Instead of this nasty cast, add a method pvoid() that prints out a
|
/* Instead of this nasty cast, add a method pvoid() that prints out a
|
||||||
|
@ -2449,6 +2426,24 @@ hppa_frame_prev_register_helper (struct frame_info *next_frame,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure the "flags" register is zero in all unwound frames.
|
||||||
|
The "flags" registers is a HP-UX specific wart, and only the code
|
||||||
|
in hppa-hpux-tdep.c depends on it. However, it is easier to deal
|
||||||
|
with it here. This shouldn't affect other systems since those
|
||||||
|
should provide zero for the "flags" register anyway. */
|
||||||
|
if (regnum == HPPA_FLAGS_REGNUM)
|
||||||
|
{
|
||||||
|
if (valuep)
|
||||||
|
store_unsigned_integer (valuep, 4, 0);
|
||||||
|
|
||||||
|
/* It's a computed value. */
|
||||||
|
*optimizedp = 0;
|
||||||
|
*lvalp = not_lval;
|
||||||
|
*addrp = 0;
|
||||||
|
*realnump = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
trad_frame_get_prev_register (next_frame, saved_regs, regnum,
|
trad_frame_get_prev_register (next_frame, saved_regs, regnum,
|
||||||
optimizedp, lvalp, addrp, realnump, valuep);
|
optimizedp, lvalp, addrp, realnump, valuep);
|
||||||
}
|
}
|
||||||
|
@ -2562,8 +2557,8 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
set_gdbarch_addr_bits_remove (gdbarch, hppa_smash_text_address);
|
set_gdbarch_addr_bits_remove (gdbarch, hppa_smash_text_address);
|
||||||
set_gdbarch_smash_text_address (gdbarch, hppa_smash_text_address);
|
set_gdbarch_smash_text_address (gdbarch, hppa_smash_text_address);
|
||||||
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
|
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
|
||||||
set_gdbarch_read_pc (gdbarch, hppa_target_read_pc);
|
set_gdbarch_read_pc (gdbarch, hppa_read_pc);
|
||||||
set_gdbarch_write_pc (gdbarch, hppa_target_write_pc);
|
set_gdbarch_write_pc (gdbarch, hppa_write_pc);
|
||||||
|
|
||||||
/* Helper for function argument information. */
|
/* Helper for function argument information. */
|
||||||
set_gdbarch_fetch_pointer_argument (gdbarch, hppa_fetch_pointer_argument);
|
set_gdbarch_fetch_pointer_argument (gdbarch, hppa_fetch_pointer_argument);
|
||||||
|
|
|
@ -209,4 +209,9 @@ hppa_frame_prev_register_helper (struct frame_info *next_frame,
|
||||||
enum lval_type *lvalp, CORE_ADDR *addrp,
|
enum lval_type *lvalp, CORE_ADDR *addrp,
|
||||||
int *realnump, void *valuep);
|
int *realnump, void *valuep);
|
||||||
|
|
||||||
|
extern CORE_ADDR hppa_read_pc (ptid_t ptid);
|
||||||
|
extern void hppa_write_pc (CORE_ADDR pc, ptid_t ptid);
|
||||||
|
extern CORE_ADDR hppa_unwind_pc (struct gdbarch *gdbarch,
|
||||||
|
struct frame_info *next_frame);
|
||||||
|
|
||||||
#endif /* HPPA_TDEP_H */
|
#endif /* HPPA_TDEP_H */
|
||||||
|
|
Loading…
Add table
Reference in a new issue