#include "defs.h"
#include "arch-utils.h"
#include "frame.h"
#include "gdbcore.h"
#include "regcache.h"
#include "osabi.h"
#include "gdb_assert.h"
#include "gdb_string.h"
#include "amd64-tdep.h"
#include "bsd-uthread.h"
#include "solib-svr4.h"
static CORE_ADDR
amd64fbsd_sigcontext_addr (struct frame_info *next_frame)
{
CORE_ADDR sp;
sp = frame_unwind_register_unsigned (next_frame, AMD64_RSP_REGNUM);
return sp + 16;
}
static int amd64fbsd_r_reg_offset[] =
{
14 * 8,
11 * 8,
13 * 8,
12 * 8,
9 * 8,
8 * 8,
10 * 8,
20 * 8,
7 * 8,
6 * 8,
5 * 8,
4 * 8,
3 * 8,
2 * 8,
1 * 8,
0 * 8,
17 * 8,
19 * 8,
18 * 8,
21 * 8,
-1,
-1,
-1,
-1
};
CORE_ADDR amd64fbsd_sigtramp_start_addr = 0x7fffffffffc0;
CORE_ADDR amd64fbsd_sigtramp_end_addr = 0x7fffffffffe0;
int amd64fbsd_sc_reg_offset[] =
{
24 + 6 * 8,
24 + 7 * 8,
24 + 3 * 8,
24 + 2 * 8,
24 + 1 * 8,
24 + 0 * 8,
24 + 8 * 8,
24 + 22 * 8,
24 + 4 * 8,
24 + 5 * 8,
24 + 9 * 8,
24 + 10 * 8,
24 + 11 * 8,
24 + 12 * 8,
24 + 13 * 8,
24 + 14 * 8,
24 + 19 * 8,
24 + 21 * 8,
24 + 20 * 8,
24 + 23 * 8,
-1,
-1,
-1,
-1
};
static int amd64fbsd_jmp_buf_reg_offset[] =
{
-1,
1 * 8,
-1,
-1,
-1,
-1,
3 * 8,
2 * 8,
-1,
-1,
-1,
-1,
4 * 8,
5 * 8,
6 * 8,
7 * 8,
0 * 8
};
static void
amd64fbsd_supply_uthread (struct regcache *regcache,
int regnum, CORE_ADDR addr)
{
gdb_byte buf[8];
int i;
gdb_assert (regnum >= -1);
for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
{
if (amd64fbsd_jmp_buf_reg_offset[i] != -1
&& (regnum == -1 || regnum == i))
{
read_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
regcache_raw_supply (regcache, i, buf);
}
}
}
static void
amd64fbsd_collect_uthread (const struct regcache *regcache,
int regnum, CORE_ADDR addr)
{
gdb_byte buf[8];
int i;
gdb_assert (regnum >= -1);
for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
{
if (amd64fbsd_jmp_buf_reg_offset[i] != -1
&& (regnum == -1 || regnum == i))
{
regcache_raw_collect (regcache, i, buf);
write_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
}
}
}
void
amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
i386bsd_init_abi (info, gdbarch);
tdep->gregset_reg_offset = amd64fbsd_r_reg_offset;
tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset);
tdep->sizeof_gregset = 22 * 8;
amd64_init_abi (info, gdbarch);
tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr;
tdep->sigtramp_end = amd64fbsd_sigtramp_end_addr;
tdep->sigcontext_addr = amd64fbsd_sigcontext_addr;
tdep->sc_reg_offset = amd64fbsd_sc_reg_offset;
tdep->sc_num_regs = ARRAY_SIZE (amd64fbsd_sc_reg_offset);
bsd_uthread_set_supply_uthread (gdbarch, amd64fbsd_supply_uthread);
bsd_uthread_set_collect_uthread (gdbarch, amd64fbsd_collect_uthread);
set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_lp64_fetch_link_map_offsets);
}
void _initialize_amd64fbsd_tdep (void);
void
_initialize_amd64fbsd_tdep (void)
{
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
GDB_OSABI_FREEBSD_ELF, amd64fbsd_init_abi);
}