#include "defs.h"
#include "ia64-tdep.h"
#include "arch-utils.h"
#include "gdbcore.h"
#include "regcache.h"
#include "osabi.h"
#include "solib-svr4.h"
#define GATE_AREA_START 0xa000000000000100LL
#define GATE_AREA_END 0xa000000000020000LL
#define IA64_LINUX_SIGCONTEXT_OFFSET 192
int
ia64_linux_in_sigtramp (CORE_ADDR pc, char *func_name)
{
return (pc >= (CORE_ADDR) GATE_AREA_START && pc < (CORE_ADDR) GATE_AREA_END);
}
static CORE_ADDR
ia64_linux_sigcontext_register_address (CORE_ADDR sp, int regno)
{
char buf[8];
CORE_ADDR sigcontext_addr = 0;
read_memory (sp + 16, buf, 8);
sigcontext_addr = extract_unsigned_integer (buf, 8);
if (IA64_GR0_REGNUM <= regno && regno <= IA64_GR31_REGNUM)
return sigcontext_addr + 200 + 8 * (regno - IA64_GR0_REGNUM);
else if (IA64_BR0_REGNUM <= regno && regno <= IA64_BR7_REGNUM)
return sigcontext_addr + 136 + 8 * (regno - IA64_BR0_REGNUM);
else if (IA64_FR0_REGNUM <= regno && regno <= IA64_FR127_REGNUM)
return sigcontext_addr + 464 + 16 * (regno - IA64_FR0_REGNUM);
else
switch (regno)
{
case IA64_IP_REGNUM :
return sigcontext_addr + 40;
case IA64_CFM_REGNUM :
return sigcontext_addr + 48;
case IA64_PSR_REGNUM :
return sigcontext_addr + 56;
case IA64_BSP_REGNUM :
return sigcontext_addr + 72;
case IA64_RNAT_REGNUM :
return sigcontext_addr + 80;
case IA64_CCV_REGNUM :
return sigcontext_addr + 88;
case IA64_UNAT_REGNUM :
return sigcontext_addr + 96;
case IA64_FPSR_REGNUM :
return sigcontext_addr + 104;
case IA64_PFS_REGNUM :
return sigcontext_addr + 112;
case IA64_LC_REGNUM :
return sigcontext_addr + 120;
case IA64_PR_REGNUM :
return sigcontext_addr + 128;
default :
return 0;
}
}
static void
ia64_linux_write_pc (CORE_ADDR pc, ptid_t ptid)
{
ia64_write_pc (pc, ptid);
write_register_pid (IA64_GR10_REGNUM, 0, ptid);
}
static void
ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
tdep->sigcontext_register_address = ia64_linux_sigcontext_register_address;
set_gdbarch_write_pc (gdbarch, ia64_linux_write_pc);
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
}
void
_initialize_ia64_linux_tdep (void)
{
gdbarch_register_osabi (bfd_arch_ia64, 0, GDB_OSABI_LINUX,
ia64_linux_init_abi);
}