/* Target-dependent code for GNU/Linux running on PA-RISC, for GDB.
- Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
This file is part of GDB.
#include "regset.h"
#include "regcache.h"
#include "hppa-tdep.h"
-
+#include "linux-tdep.h"
#include "elf/common.h"
/* Map DWARF DBX register numbers to GDB register numbers. */
{
/* Probably this should be done by the kernel, but it isn't. */
regcache_cooked_write_unsigned (regcache, HPPA_PCOQ_HEAD_REGNUM, v | 0x3);
- regcache_cooked_write_unsigned (regcache, HPPA_PCOQ_TAIL_REGNUM, (v + 4) | 0x3);
+ regcache_cooked_write_unsigned (regcache,
+ HPPA_PCOQ_TAIL_REGNUM, (v + 4) | 0x3);
}
/* An instruction to match. */
When the match is successful, fill INSN[i] with what PATTERN[i]
matched. */
static int
-insns_match_pattern (CORE_ADDR pc,
+insns_match_pattern (struct gdbarch *gdbarch, CORE_ADDR pc,
struct insn_pattern *pattern,
unsigned int *insn)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int i;
CORE_ADDR npc = pc;
for (i = 0; pattern[i].mask; i++)
{
- char buf[4];
+ gdb_byte buf[4];
target_read_memory (npc, buf, 4);
- insn[i] = extract_unsigned_integer (buf, 4);
+ insn[i] = extract_unsigned_integer (buf, 4, byte_order);
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 pc)
+hppa_linux_sigtramp_find_sigcontext (struct gdbarch *gdbarch, CORE_ADDR pc)
{
unsigned int dummy[HPPA_MAX_INSN_PATTERN_LEN];
int offs = 0;
for (try = 0; try < ARRAY_SIZE (pcoffs); try++)
{
- if (insns_match_pattern (sp + pcoffs[try], hppa_sigtramp, dummy))
+ if (insns_match_pattern (gdbarch, sp + pcoffs[try],
+ hppa_sigtramp, dummy))
{
offs = sfoffs[try];
break;
if (offs == 0)
{
- if (insns_match_pattern (pc, hppa_sigtramp, dummy))
+ if (insns_match_pattern (gdbarch, 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
+ use in this case; default to new kernel handling. If this is
wrong the unwinding will fail. */
try = 2;
sp = pc - pcoffs[try];
/* sp + sfoffs[try] points to a struct rt_sigframe, which contains
a struct siginfo and a struct ucontext. struct ucontext contains
- a struct sigcontext. Return an offset to this sigcontext here. Too
- bad we cannot include system specific headers :-(.
+ a struct sigcontext. Return an offset to this sigcontext here. Too
+ bad we cannot include system specific headers :-(.
sizeof(struct siginfo) == 128
offsetof(struct ucontext, uc_mcontext) == 24. */
return sp + sfoffs[try] + 128 + 24;
info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
pc = get_frame_pc (this_frame);
- scptr = hppa_linux_sigtramp_find_sigcontext (pc);
+ scptr = hppa_linux_sigtramp_find_sigcontext (gdbarch, pc);
/* structure of struct sigcontext:
/* Skip sc_flags. */
scptr += 4;
- /* GR[0] is the psw, we don't restore that. */
+ /* GR[0] is the psw. */
+ info->saved_regs[HPPA_IPSW_REGNUM].addr = scptr;
scptr += 4;
/* General registers. */
scptr += 4;
}
- /* Pad. */
+ /* Pad to long long boundary. */
scptr += 4;
/* FP regs; FP0-3 are not restored. */
scptr += 4;
}
- /* IASQ/IAOQ. */
+ /* IASQ/IAOQ. */
info->saved_regs[HPPA_PCSQ_HEAD_REGNUM].addr = scptr;
scptr += 4;
info->saved_regs[HPPA_PCSQ_TAIL_REGNUM].addr = scptr;
info->saved_regs[HPPA_PCOQ_TAIL_REGNUM].addr = scptr;
scptr += 4;
+ info->saved_regs[HPPA_SAR_REGNUM].addr = scptr;
+
info->base = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM);
return info;
struct frame_info *this_frame,
void **this_prologue_cache)
{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
CORE_ADDR pc = get_frame_pc (this_frame);
- if (hppa_linux_sigtramp_find_sigcontext (pc))
+ if (hppa_linux_sigtramp_find_sigcontext (gdbarch, pc))
return 1;
return 0;
static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
hppa_linux_sigtramp_frame_this_id,
hppa_linux_sigtramp_frame_prev_register,
NULL,
d_un.d_ptr value is the global pointer. */
static CORE_ADDR
-hppa_linux_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
+hppa_linux_find_global_pointer (struct gdbarch *gdbarch,
+ struct value *function)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct obj_section *faddr_sect;
CORE_ADDR faddr;
if (faddr & 2)
{
int status;
- char buf[4];
+ gdb_byte buf[4];
faddr &= ~3;
status = target_read_memory (faddr + 4, buf, sizeof (buf));
if (status == 0)
- return extract_unsigned_integer (buf, sizeof (buf));
+ return extract_unsigned_integer (buf, sizeof (buf), byte_order);
}
/* If the address is in the plt section, then the real function hasn't
yet been fixed up by the linker so we cannot determine the gp of
that function. */
- if (in_plt_section (faddr, NULL))
+ if (in_plt_section (faddr))
return 0;
faddr_sect = find_pc_section (faddr);
{
int status;
LONGEST tag;
- char buf[4];
+ gdb_byte buf[4];
status = target_read_memory (addr, buf, sizeof (buf));
if (status != 0)
break;
- tag = extract_signed_integer (buf, sizeof (buf));
+ tag = extract_signed_integer (buf, sizeof (buf), byte_order);
if (tag == DT_PLTGOT)
{
status = target_read_memory (addr + 4, buf, sizeof (buf));
if (status != 0)
break;
- global_pointer = extract_unsigned_integer (buf, sizeof (buf));
-
- /* The payoff... */
+ global_pointer = extract_unsigned_integer (buf, sizeof (buf),
+ byte_order);
+ /* The payoff... */
return global_pointer;
}
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ linux_init_abi (info, gdbarch);
+
/* GNU/Linux is always ELF. */
tdep->is_elf = 1;
void
_initialize_hppa_linux_tdep (void)
{
- gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_LINUX, hppa_linux_init_abi);
- gdbarch_register_osabi (bfd_arch_hppa, bfd_mach_hppa20w, GDB_OSABI_LINUX, hppa_linux_init_abi);
+ gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_LINUX,
+ hppa_linux_init_abi);
+ gdbarch_register_osabi (bfd_arch_hppa, bfd_mach_hppa20w,
+ GDB_OSABI_LINUX, hppa_linux_init_abi);
}