X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Famd64fbsd-tdep.c;h=062fc9ac6b7eb005bf577b223aa9ea4b132f4dc1;hb=be85b69fc61880e3bde8d4df2bf6b4189c25d143;hp=bb44ec032b2a92e6fab1faa6408cde8a62ed43a3;hpb=dac9410586f447f37c64eba43a72c7dfd5625629;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/amd64fbsd-tdep.c b/gdb/amd64fbsd-tdep.c index bb44ec032b..062fc9ac6b 100644 --- a/gdb/amd64fbsd-tdep.c +++ b/gdb/amd64fbsd-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for FreeBSD/amd64. - Copyright 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GDB. @@ -16,8 +16,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #include "defs.h" #include "arch-utils.h" @@ -26,9 +26,12 @@ #include "regcache.h" #include "osabi.h" +#include "gdb_assert.h" #include "gdb_string.h" -#include "x86-64-tdep.h" +#include "amd64-tdep.h" +#include "bsd-uthread.h" +#include "solib-svr4.h" /* Support for signal handlers. */ @@ -43,7 +46,7 @@ amd64fbsd_sigcontext_addr (struct frame_info *next_frame) /* The `struct sigcontext' (which really is an `ucontext_t' on FreeBSD/amd64) lives at a fixed offset in the signal frame. See . */ - sp = frame_unwind_register_unsigned (next_frame, X86_64_RSP_REGNUM); + sp = frame_unwind_register_unsigned (next_frame, AMD64_RSP_REGNUM); return sp + 16; } @@ -58,23 +61,38 @@ amd64fbsd_sigcontext_addr (struct frame_info *next_frame) /* From . */ static int amd64fbsd_r_reg_offset[] = { - 14 * 8, 11 * 8, /* %rax, %rbx */ - 13 * 8, 12 * 8, /* %rcx, %rdx */ - 9 * 8, 8 * 8, /* %rsi, %rdi */ - 10 * 8, 20 * 8, /* %rbp, %rsp */ - 7 * 8, 6 * 8, 5 * 8, 4 * 8, /* %r8 ... */ - 3 * 8, 2 * 8, 1 * 8, 0 * 8, /* ... %r15 */ - 17 * 8, 19 * 8, /* %rip, %eflags */ - -1, -1, /* %ds, %es */ - -1, -1 /* %fs, %gs */ + 14 * 8, /* %rax */ + 11 * 8, /* %rbx */ + 13 * 8, /* %rcx */ + 12 * 8, /* %rdx */ + 9 * 8, /* %rsi */ + 8 * 8, /* %rdi */ + 10 * 8, /* %rbp */ + 20 * 8, /* %rsp */ + 7 * 8, /* %r8 ... */ + 6 * 8, + 5 * 8, + 4 * 8, + 3 * 8, + 2 * 8, + 1 * 8, + 0 * 8, /* ... %r15 */ + 17 * 8, /* %rip */ + 19 * 8, /* %eflags */ + 18 * 8, /* %cs */ + 21 * 8, /* %ss */ + -1, /* %ds */ + -1, /* %es */ + -1, /* %fs */ + -1 /* %gs */ }; /* Location of the signal trampoline. */ -CORE_ADDR amd64fbsd_sigtramp_start = 0x7fffffffffc0; -CORE_ADDR amd64fbsd_sigtramp_end = 0x7fffffffffe0; +CORE_ADDR amd64fbsd_sigtramp_start_addr = 0x7fffffffffc0; +CORE_ADDR amd64fbsd_sigtramp_end_addr = 0x7fffffffffe0; /* From . */ -int amd64fbsd_sc_reg_offset[X86_64_NUM_GREGS] = +int amd64fbsd_sc_reg_offset[] = { 24 + 6 * 8, /* %rax */ 24 + 7 * 8, /* %rbx */ @@ -84,22 +102,86 @@ int amd64fbsd_sc_reg_offset[X86_64_NUM_GREGS] = 24 + 0 * 8, /* %rdi */ 24 + 8 * 8, /* %rbp */ 24 + 22 * 8, /* %rsp */ - 24 + 4 * 8, /* %r8 */ - 24 + 5 * 8, /* %r9 */ - 24 + 9 * 8, /* %r10 */ - 24 + 10 * 8, /* %r11 */ - 24 + 11 * 8, /* %r12 */ - 24 + 12 * 8, /* %r13 */ - 24 + 13 * 8, /* %r14 */ - 24 + 14 * 8, /* %r15 */ + 24 + 4 * 8, /* %r8 ... */ + 24 + 5 * 8, + 24 + 9 * 8, + 24 + 10 * 8, + 24 + 11 * 8, + 24 + 12 * 8, + 24 + 13 * 8, + 24 + 14 * 8, /* ... %r15 */ 24 + 19 * 8, /* %rip */ 24 + 21 * 8, /* %eflags */ + 24 + 20 * 8, /* %cs */ + 24 + 23 * 8, /* %ss */ -1, /* %ds */ -1, /* %es */ -1, /* %fs */ -1 /* %gs */ }; +/* From /usr/src/lib/libc/amd64/gen/_setjmp.S. */ +static int amd64fbsd_jmp_buf_reg_offset[] = +{ + -1, /* %rax */ + 1 * 8, /* %rbx */ + -1, /* %rcx */ + -1, /* %rdx */ + -1, /* %rsi */ + -1, /* %rdi */ + 3 * 8, /* %rbp */ + 2 * 8, /* %rsp */ + -1, /* %r8 ... */ + -1, + -1, + -1, /* ... %r11 */ + 4 * 8, /* %r12 ... */ + 5 * 8, + 6 * 8, + 7 * 8, /* ... %r15 */ + 0 * 8 /* %rip */ +}; + +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) { @@ -112,13 +194,21 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset); tdep->sizeof_gregset = 22 * 8; - x86_64_init_abi (info, gdbarch); + amd64_init_abi (info, gdbarch); - tdep->sigtramp_start = amd64fbsd_sigtramp_start; - tdep->sigtramp_end = amd64fbsd_sigtramp_end; + 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); + + /* FreeBSD provides a user-level threads implementation. */ + bsd_uthread_set_supply_uthread (gdbarch, amd64fbsd_supply_uthread); + bsd_uthread_set_collect_uthread (gdbarch, amd64fbsd_collect_uthread); + + /* FreeBSD uses SVR4-style shared libraries. */ + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_lp64_fetch_link_map_offsets); }