diff options
-rw-r--r-- | gdb/amd64-fbsd-nat.c | 58 | ||||
-rw-r--r-- | gdb/amd64-fbsd-tdep.c | 185 | ||||
-rw-r--r-- | gdb/amd64-tdep.h | 3 | ||||
-rw-r--r-- | gdb/i386-bsd-nat.c | 4 | ||||
-rw-r--r-- | gdb/i386-fbsd-tdep.c | 243 | ||||
-rw-r--r-- | gdb/i386-tdep.h | 1 |
6 files changed, 266 insertions, 228 deletions
diff --git a/gdb/amd64-fbsd-nat.c b/gdb/amd64-fbsd-nat.c index 3c79a40..f9bd45d 100644 --- a/gdb/amd64-fbsd-nat.c +++ b/gdb/amd64-fbsd-nat.c @@ -213,8 +213,6 @@ void _initialize_amd64fbsd_nat (); void _initialize_amd64fbsd_nat () { - int offset; - amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset; amd64_native_gregset64_reg_offset = amd64fbsd64_r_reg_offset; @@ -222,60 +220,4 @@ _initialize_amd64fbsd_nat () /* Support debugging kernel virtual memory images. */ bsd_kvm_add_target (amd64fbsd_supply_pcb); - - /* To support the recognition of signal handlers, i386-bsd-tdep.c - hardcodes some constants. Inclusion of this file means that we - are compiling a native debugger, which means that we can use the - system header files and sysctl(3) to get at the relevant - information. */ - -#define SC_REG_OFFSET amd64fbsd_sc_reg_offset - - /* We only check the program counter, stack pointer and frame - pointer since these members of `struct sigcontext' are essential - for providing backtraces. */ - -#define SC_RIP_OFFSET SC_REG_OFFSET[AMD64_RIP_REGNUM] -#define SC_RSP_OFFSET SC_REG_OFFSET[AMD64_RSP_REGNUM] -#define SC_RBP_OFFSET SC_REG_OFFSET[AMD64_RBP_REGNUM] - - /* Override the default value for the offset of the program counter - in the sigcontext structure. */ - offset = offsetof (struct sigcontext, sc_rip); - - if (SC_RIP_OFFSET != offset) - { - warning (_("\ -offsetof (struct sigcontext, sc_rip) yields %d instead of %d.\n\ -Please report this to <bug-gdb@gnu.org>."), - offset, SC_RIP_OFFSET); - } - - SC_RIP_OFFSET = offset; - - /* Likewise for the stack pointer. */ - offset = offsetof (struct sigcontext, sc_rsp); - - if (SC_RSP_OFFSET != offset) - { - warning (_("\ -offsetof (struct sigcontext, sc_rsp) yields %d instead of %d.\n\ -Please report this to <bug-gdb@gnu.org>."), - offset, SC_RSP_OFFSET); - } - - SC_RSP_OFFSET = offset; - - /* And the frame pointer. */ - offset = offsetof (struct sigcontext, sc_rbp); - - if (SC_RBP_OFFSET != offset) - { - warning (_("\ -offsetof (struct sigcontext, sc_rbp) yields %d instead of %d.\n\ -Please report this to <bug-gdb@gnu.org>."), - offset, SC_RBP_OFFSET); - } - - SC_RBP_OFFSET = offset; } diff --git a/gdb/amd64-fbsd-tdep.c b/gdb/amd64-fbsd-tdep.c index f61ca74..fa36377 100644 --- a/gdb/amd64-fbsd-tdep.c +++ b/gdb/amd64-fbsd-tdep.c @@ -18,12 +18,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "defs.h" -#include "arch-utils.h" -#include "frame.h" -#include "gdbcore.h" -#include "regcache.h" #include "osabi.h" #include "regset.h" +#include "target.h" +#include "trad-frame.h" +#include "tramp-frame.h" #include "i386-fbsd-tdep.h" #include "gdbsupport/x86-xstate.h" @@ -70,6 +69,49 @@ static const struct regcache_map_entry amd64_fbsd_gregmap[] = { 0 } }; +/* This layout including fsbase and gsbase was adopted in FreeBSD + 8.0. */ + +static const struct regcache_map_entry amd64_fbsd_mcregmap[] = +{ + { 1, REGCACHE_MAP_SKIP, 8 }, /* mc_onstack */ + { 1, AMD64_RDI_REGNUM, 0 }, + { 1, AMD64_RSI_REGNUM, 0 }, + { 1, AMD64_RDX_REGNUM, 0 }, + { 1, AMD64_RCX_REGNUM, 0 }, + { 1, AMD64_R8_REGNUM, 0 }, + { 1, AMD64_R9_REGNUM, 0 }, + { 1, AMD64_RAX_REGNUM, 0 }, + { 1, AMD64_RBX_REGNUM, 0 }, + { 1, AMD64_RBP_REGNUM, 0 }, + { 1, AMD64_R10_REGNUM, 0 }, + { 1, AMD64_R11_REGNUM, 0 }, + { 1, AMD64_R12_REGNUM, 0 }, + { 1, AMD64_R13_REGNUM, 0 }, + { 1, AMD64_R14_REGNUM, 0 }, + { 1, AMD64_R15_REGNUM, 0 }, + { 1, REGCACHE_MAP_SKIP, 4 }, /* mc_trapno */ + { 1, AMD64_FS_REGNUM, 2 }, + { 1, AMD64_GS_REGNUM, 2 }, + { 1, REGCACHE_MAP_SKIP, 8 }, /* mc_addr */ + { 1, REGCACHE_MAP_SKIP, 4 }, /* mc_flags */ + { 1, AMD64_ES_REGNUM, 2 }, + { 1, AMD64_DS_REGNUM, 2 }, + { 1, REGCACHE_MAP_SKIP, 8 }, /* mc_err */ + { 1, AMD64_RIP_REGNUM, 0 }, + { 1, AMD64_CS_REGNUM, 8 }, + { 1, AMD64_EFLAGS_REGNUM, 8 }, + { 1, AMD64_RSP_REGNUM, 0 }, + { 1, AMD64_SS_REGNUM, 8 }, + { 1, REGCACHE_MAP_SKIP, 8 }, /* mc_len */ + { 1, REGCACHE_MAP_SKIP, 8 }, /* mc_fpformat */ + { 1, REGCACHE_MAP_SKIP, 8 }, /* mc_ownedfp */ + { 64, REGCACHE_MAP_SKIP, 8 }, /* mc_fpstate */ + { 1, AMD64_FSBASE_REGNUM, 0 }, + { 1, AMD64_GSBASE_REGNUM, 0 }, + { 0 } +}; + /* Register set definitions. */ const struct regset amd64_fbsd_gregset = @@ -79,80 +121,86 @@ const struct regset amd64_fbsd_gregset = /* Support for signal handlers. */ -/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp - routine. */ +/* In a signal frame, rsp points to a 'struct sigframe' which is + defined as: -static const gdb_byte amd64fbsd_sigtramp_code[] = -{ - 0x48, 0x8d, 0x7c, 0x24, 0x10, /* lea SIGF_UC(%rsp),%rdi */ - 0x6a, 0x00, /* pushq $0 */ - 0x48, 0xc7, 0xc0, 0xa1, 0x01, 0x00, 0x00, - /* movq $SYS_sigreturn,%rax */ - 0x0f, 0x05 /* syscall */ -}; + struct sigframe { + union { + __siginfohandler_t *sf_action; + __sighandler_t *sf_handler; + } sf_ahu; + ucontext_t sf_uc; + ... + } -static int -amd64fbsd_sigtramp_p (struct frame_info *this_frame) -{ - CORE_ADDR pc = get_frame_pc (this_frame); - gdb_byte buf[sizeof amd64fbsd_sigtramp_code]; + ucontext_t is defined as: - if (!safe_frame_unwind_memory (this_frame, pc, buf)) - return 0; - if (memcmp (buf, amd64fbsd_sigtramp_code, sizeof amd64fbsd_sigtramp_code) - != 0) - return 0; + struct __ucontext { + sigset_t uc_sigmask; + mcontext_t uc_mcontext; + ... + }; - return 1; -} + The mcontext_t contains the general purpose register set as well + as the floating point or XSAVE state. */ -/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the - address of the associated sigcontext structure. */ +/* NB: There is an 8 byte padding hole between sf_ahu and sf_uc. */ +#define AMD64_SIGFRAME_UCONTEXT_OFFSET 16 +#define AMD64_UCONTEXT_MCONTEXT_OFFSET 16 +#define AMD64_SIZEOF_MCONTEXT_T 800 -static CORE_ADDR -amd64fbsd_sigcontext_addr (struct frame_info *this_frame) +/* Implement the "init" method of struct tramp_frame. */ + +static void +amd64_fbsd_sigframe_init (const struct tramp_frame *self, + struct frame_info *this_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - CORE_ADDR sp; - gdb_byte buf[8]; - - /* The `struct sigcontext' (which really is an `ucontext_t' on - FreeBSD/amd64) lives at a fixed offset in the signal frame. See - <machine/sigframe.h>. */ - get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); - sp = extract_unsigned_integer (buf, 8, byte_order); - return sp + 16; + CORE_ADDR sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM); + CORE_ADDR mcontext_addr + = (sp + + AMD64_SIGFRAME_UCONTEXT_OFFSET + + AMD64_UCONTEXT_MCONTEXT_OFFSET); + + trad_frame_set_reg_regmap (this_cache, amd64_fbsd_mcregmap, mcontext_addr, + AMD64_SIZEOF_MCONTEXT_T); + + /* Don't bother with floating point or XSAVE state for now. The + current helper routines for parsing FXSAVE and XSAVE state only + work with regcaches. This could perhaps create a temporary + regcache, collect the register values from mc_fpstate and + mc_xfpustate, and then set register values in the trad_frame. */ + + trad_frame_set_id (this_cache, frame_id_build (sp, func)); } - -/* From <machine/signal.h>. */ -int amd64fbsd_sc_reg_offset[] = +static const struct tramp_frame amd64_fbsd_sigframe = { - 24 + 6 * 8, /* %rax */ - 24 + 7 * 8, /* %rbx */ - 24 + 3 * 8, /* %rcx */ - 24 + 2 * 8, /* %rdx */ - 24 + 1 * 8, /* %rsi */ - 24 + 0 * 8, /* %rdi */ - 24 + 8 * 8, /* %rbp */ - 24 + 22 * 8, /* %rsp */ - 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 */ + SIGTRAMP_FRAME, + 1, + { + {0x48, ULONGEST_MAX}, /* lea SIGF_UC(%rsp),%rdi */ + {0x8d, ULONGEST_MAX}, + {0x7c, ULONGEST_MAX}, + {0x24, ULONGEST_MAX}, + {0x10, ULONGEST_MAX}, + {0x6a, ULONGEST_MAX}, /* pushq $0 */ + {0x00, ULONGEST_MAX}, + {0x48, ULONGEST_MAX}, /* movq $SYS_sigreturn,%rax */ + {0xc7, ULONGEST_MAX}, + {0xc0, ULONGEST_MAX}, + {0xa1, ULONGEST_MAX}, + {0x01, ULONGEST_MAX}, + {0x00, ULONGEST_MAX}, + {0x00, ULONGEST_MAX}, + {0x0f, ULONGEST_MAX}, /* syscall */ + {0x05, ULONGEST_MAX}, + {TRAMP_SENTINEL_INSN, ULONGEST_MAX} + }, + amd64_fbsd_sigframe_init }; /* Implement the core_read_description gdbarch method. */ @@ -245,10 +293,7 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) amd64_init_abi (info, gdbarch, amd64_target_description (X86_XSTATE_SSE_MASK, true)); - tdep->sigtramp_p = amd64fbsd_sigtramp_p; - tdep->sigcontext_addr = amd64fbsd_sigcontext_addr; - tdep->sc_reg_offset = amd64fbsd_sc_reg_offset; - tdep->sc_num_regs = ARRAY_SIZE (amd64fbsd_sc_reg_offset); + tramp_frame_prepend_unwinder (gdbarch, &amd64_fbsd_sigframe); tdep->xsave_xcr0_offset = I386_FBSD_XSAVE_XCR0_OFFSET; diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h index cdc1d6f..c18766e 100644 --- a/gdb/amd64-tdep.h +++ b/gdb/amd64-tdep.h @@ -144,7 +144,4 @@ extern int amd64nbsd_r_reg_offset[]; /* Variables exported from amd64-obsd-tdep.c. */ extern int amd64obsd_r_reg_offset[]; -/* Variables exported from amd64-fbsd-tdep.c. */ -extern int amd64fbsd_sc_reg_offset[]; - #endif /* amd64-tdep.h */ diff --git a/gdb/i386-bsd-nat.c b/gdb/i386-bsd-nat.c index a04478a..c112b02 100644 --- a/gdb/i386-bsd-nat.c +++ b/gdb/i386-bsd-nat.c @@ -350,9 +350,7 @@ _initialize_i386bsd_nat () system header files and sysctl(3) to get at the relevant information. */ -#if defined (__FreeBSD_version) -#define SC_REG_OFFSET i386fbsd_sc_reg_offset -#elif defined (OpenBSD) +#if defined (OpenBSD) #define SC_REG_OFFSET i386obsd_sc_reg_offset #endif diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c index 6d720d8..6a656dd 100644 --- a/gdb/i386-fbsd-tdep.c +++ b/gdb/i386-fbsd-tdep.c @@ -18,11 +18,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "defs.h" -#include "arch-utils.h" -#include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "regset.h" +#include "trad-frame.h" +#include "tramp-frame.h" #include "i386-fbsd-tdep.h" #include "gdbsupport/x86-xstate.h" @@ -61,6 +61,41 @@ static const struct regcache_map_entry i386_fbsd_gregmap[] = { 0 } }; +/* This layout including fsbase and gsbase was adopted in FreeBSD + 8.0. */ + +static const struct regcache_map_entry i386_fbsd_mcregmap[] = +{ + { 1, REGCACHE_MAP_SKIP, 4 }, /* mc_onstack */ + { 1, I386_GS_REGNUM, 4 }, + { 1, I386_FS_REGNUM, 4 }, + { 1, I386_ES_REGNUM, 4 }, + { 1, I386_DS_REGNUM, 4 }, + { 1, I386_EDI_REGNUM, 0 }, + { 1, I386_ESI_REGNUM, 0 }, + { 1, I386_EBP_REGNUM, 0 }, + { 1, REGCACHE_MAP_SKIP, 4 }, /* isp */ + { 1, I386_EBX_REGNUM, 0 }, + { 1, I386_EDX_REGNUM, 0 }, + { 1, I386_ECX_REGNUM, 0 }, + { 1, I386_EAX_REGNUM, 0 }, + { 1, REGCACHE_MAP_SKIP, 4 }, /* mc_trapno */ + { 1, REGCACHE_MAP_SKIP, 4 }, /* mc_err */ + { 1, I386_EIP_REGNUM, 0 }, + { 1, I386_CS_REGNUM, 4 }, + { 1, I386_EFLAGS_REGNUM, 0 }, + { 1, I386_ESP_REGNUM, 0 }, + { 1, I386_SS_REGNUM, 4 }, + { 1, REGCACHE_MAP_SKIP, 4 }, /* mc_len */ + { 1, REGCACHE_MAP_SKIP, 4 }, /* mc_fpformat */ + { 1, REGCACHE_MAP_SKIP, 4 }, /* mc_ownedfp */ + { 1, REGCACHE_MAP_SKIP, 4 }, /* mc_flags */ + { 128, REGCACHE_MAP_SKIP, 4 },/* mc_fpstate */ + { 1, I386_FSBASE_REGNUM, 0 }, + { 1, I386_GSBASE_REGNUM, 0 }, + { 0 } +}; + /* Register set definitions. */ const struct regset i386_fbsd_gregset = @@ -70,102 +105,127 @@ const struct regset i386_fbsd_gregset = /* Support for signal handlers. */ -/* Return whether THIS_FRAME corresponds to a FreeBSD sigtramp - routine. */ +/* In a signal frame, esp points to a 'struct sigframe' which is + defined as: -/* FreeBSD/i386 binaries running under an amd64 kernel use a different - trampoline This trampoline differs from the i386 kernel trampoline - in that it omits a middle section that conditionally restores - %gs. */ + struct sigframe { + register_t sf_signum; + register_t sf_siginfo; + register_t sf_ucontext; + register_t sf_addr; + union { + __siginfohandler_t *sf_action; + __sighandler_t *sf_handler; + } sf_ahu; + ucontext_t sf_uc; + ... + } -static const gdb_byte i386fbsd_sigtramp_start[] = -{ - 0x8d, 0x44, 0x24, 0x20, /* lea SIGF_UC(%esp),%eax */ - 0x50 /* pushl %eax */ -}; + ucontext_t is defined as: -static const gdb_byte i386fbsd_sigtramp_middle[] = -{ - 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x00, - /* testl $PSL_VM,UC_EFLAGS(%eax) */ - 0x75, 0x03, /* jne +3 */ - 0x8e, 0x68, 0x14 /* mov UC_GS(%eax),%gs */ -}; + struct __ucontext { + sigset_t uc_sigmask; + mcontext_t uc_mcontext; + ... + }; -static const gdb_byte i386fbsd_sigtramp_end[] = -{ - 0xb8, 0xa1, 0x01, 0x00, 0x00, /* movl $SYS_sigreturn,%eax */ - 0x50, /* pushl %eax */ - 0xcd, 0x80 /* int $0x80 */ -}; + The mcontext_t contains the general purpose register set as well + as the floating point or XSAVE state. */ -/* We assume that the middle is the largest chunk below. */ -gdb_static_assert (sizeof i386fbsd_sigtramp_middle - > sizeof i386fbsd_sigtramp_start); -gdb_static_assert (sizeof i386fbsd_sigtramp_middle - > sizeof i386fbsd_sigtramp_end); +/* NB: There is a 12 byte padding hole between sf_ahu and sf_uc. */ +#define I386_SIGFRAME_UCONTEXT_OFFSET 32 +#define I386_UCONTEXT_MCONTEXT_OFFSET 16 +#define I386_SIZEOF_MCONTEXT_T 640 -static int -i386fbsd_sigtramp_p (struct frame_info *this_frame) +/* Implement the "init" method of struct tramp_frame. */ + +static void +i386_fbsd_sigframe_init (const struct tramp_frame *self, + struct frame_info *this_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func) { - CORE_ADDR pc = get_frame_pc (this_frame); - gdb_byte buf[sizeof i386fbsd_sigtramp_middle]; - - /* Look for a matching start. */ - if (!safe_frame_unwind_memory (this_frame, pc, - {buf, sizeof i386fbsd_sigtramp_start})) - return 0; - if (memcmp (buf, i386fbsd_sigtramp_start, sizeof i386fbsd_sigtramp_start) - != 0) - return 0; - - /* Since the end is shorter than the middle, check for a matching end - next. */ - pc += sizeof i386fbsd_sigtramp_start; - if (!safe_frame_unwind_memory (this_frame, pc, - {buf, sizeof i386fbsd_sigtramp_end})) - return 0; - if (memcmp (buf, i386fbsd_sigtramp_end, sizeof i386fbsd_sigtramp_end) == 0) - return 1; - - /* If the end didn't match, check for a matching middle. */ - if (!safe_frame_unwind_memory (this_frame, pc, - {buf, sizeof i386fbsd_sigtramp_middle})) - return 0; - if (memcmp (buf, i386fbsd_sigtramp_middle, sizeof i386fbsd_sigtramp_middle) - != 0) - return 0; - - /* The middle matched, check for a matching end. */ - pc += sizeof i386fbsd_sigtramp_middle; - if (!safe_frame_unwind_memory (this_frame, pc, - {buf, sizeof i386fbsd_sigtramp_end})) - return 0; - if (memcmp (buf, i386fbsd_sigtramp_end, sizeof i386fbsd_sigtramp_end) != 0) - return 0; - - return 1; + struct gdbarch *gdbarch = get_frame_arch (this_frame); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + CORE_ADDR sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM); + CORE_ADDR mcontext_addr + = (sp + + I386_SIGFRAME_UCONTEXT_OFFSET + + I386_UCONTEXT_MCONTEXT_OFFSET); + + trad_frame_set_reg_regmap (this_cache, i386_fbsd_mcregmap, mcontext_addr, + I386_SIZEOF_MCONTEXT_T); + + /* Don't bother with floating point or XSAVE state for now. The + current helper routines for parsing FXSAVE and XSAVE state only + work with regcaches. This could perhaps create a temporary + regcache, collect the register values from mc_fpstate and + mc_xfpustate, and then set register values in the trad_frame. */ + + trad_frame_set_id (this_cache, frame_id_build (sp, func)); } -/* From <machine/signal.h>. */ -int i386fbsd_sc_reg_offset[] = +static const struct tramp_frame i386_fbsd_sigframe = { - 20 + 11 * 4, /* %eax */ - 20 + 10 * 4, /* %ecx */ - 20 + 9 * 4, /* %edx */ - 20 + 8 * 4, /* %ebx */ - 20 + 17 * 4, /* %esp */ - 20 + 6 * 4, /* %ebp */ - 20 + 5 * 4, /* %esi */ - 20 + 4 * 4, /* %edi */ - 20 + 14 * 4, /* %eip */ - 20 + 16 * 4, /* %eflags */ - 20 + 15 * 4, /* %cs */ - 20 + 18 * 4, /* %ss */ - 20 + 3 * 4, /* %ds */ - 20 + 2 * 4, /* %es */ - 20 + 1 * 4, /* %fs */ - 20 + 0 * 4 /* %gs */ + SIGTRAMP_FRAME, + 1, + { + {0x8d, ULONGEST_MAX}, /* lea SIGF_UC(%esp),%eax */ + {0x44, ULONGEST_MAX}, + {0x24, ULONGEST_MAX}, + {0x20, ULONGEST_MAX}, + {0x50, ULONGEST_MAX}, /* pushl %eax */ + {0xf7, ULONGEST_MAX}, /* testl $PSL_VM,UC_EFLAGS(%eax) */ + {0x40, ULONGEST_MAX}, + {0x54, ULONGEST_MAX}, + {0x00, ULONGEST_MAX}, + {0x00, ULONGEST_MAX}, + {0x02, ULONGEST_MAX}, + {0x00, ULONGEST_MAX}, + {0x75, ULONGEST_MAX}, /* jne +3 */ + {0x03, ULONGEST_MAX}, + {0x8e, ULONGEST_MAX}, /* mov UC_GS(%eax),%gs */ + {0x68, ULONGEST_MAX}, + {0x14, ULONGEST_MAX}, + {0xb8, ULONGEST_MAX}, /* movl $SYS_sigreturn,%eax */ + {0xa1, ULONGEST_MAX}, + {0x01, ULONGEST_MAX}, + {0x00, ULONGEST_MAX}, + {0x00, ULONGEST_MAX}, + {0x50, ULONGEST_MAX}, /* pushl %eax */ + {0xcd, ULONGEST_MAX}, /* int $0x80 */ + {0x80, ULONGEST_MAX}, + {TRAMP_SENTINEL_INSN, ULONGEST_MAX} + }, + i386_fbsd_sigframe_init +}; + +/* FreeBSD/i386 binaries running under an amd64 kernel use a different + trampoline. This trampoline differs from the i386 kernel trampoline + in that it omits a middle section that conditionally restores + %gs. */ + +static const struct tramp_frame i386_fbsd64_sigframe = +{ + SIGTRAMP_FRAME, + 1, + { + {0x8d, ULONGEST_MAX}, /* lea SIGF_UC(%esp),%eax */ + {0x44, ULONGEST_MAX}, + {0x24, ULONGEST_MAX}, + {0x20, ULONGEST_MAX}, + {0x50, ULONGEST_MAX}, /* pushl %eax */ + {0xb8, ULONGEST_MAX}, /* movl $SYS_sigreturn,%eax */ + {0xa1, ULONGEST_MAX}, + {0x01, ULONGEST_MAX}, + {0x00, ULONGEST_MAX}, + {0x00, ULONGEST_MAX}, + {0x50, ULONGEST_MAX}, /* pushl %eax */ + {0xcd, ULONGEST_MAX}, /* int $0x80 */ + {0x80, ULONGEST_MAX}, + {TRAMP_SENTINEL_INSN, ULONGEST_MAX} + }, + i386_fbsd_sigframe_init }; /* Get XSAVE extended state xcr0 from core dump. */ @@ -308,11 +368,8 @@ i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* FreeBSD uses -freg-struct-return by default. */ tdep->struct_return = reg_struct_return; - tdep->sigtramp_p = i386fbsd_sigtramp_p; - - /* FreeBSD has a more complete `struct sigcontext'. */ - tdep->sc_reg_offset = i386fbsd_sc_reg_offset; - tdep->sc_num_regs = ARRAY_SIZE (i386fbsd_sc_reg_offset); + tramp_frame_prepend_unwinder (gdbarch, &i386_fbsd_sigframe); + tramp_frame_prepend_unwinder (gdbarch, &i386_fbsd64_sigframe); i386_elf_init_abi (info, gdbarch); diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index 62d94da..eb58dd6 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -474,7 +474,6 @@ extern int i386_mpx_enabled (void); extern void i386bsd_init_abi (struct gdbarch_info, struct gdbarch *); extern CORE_ADDR i386obsd_sigtramp_start_addr; extern CORE_ADDR i386obsd_sigtramp_end_addr; -extern int i386fbsd_sc_reg_offset[]; extern int i386obsd_sc_reg_offset[]; extern int i386bsd_sc_reg_offset[]; |