mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-01-09 19:03:43 +01:00
Move x86 porting further.
This commit is contained in:
parent
71c4161247
commit
e9cd30040e
7 changed files with 248 additions and 44 deletions
|
@ -60,8 +60,12 @@ struct cursor
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
X86_SCF_NONE, /* no signal frame encountered */
|
X86_SCF_NONE, /* no signal frame encountered */
|
||||||
X86_SCF_LINUX_SIGFRAME, /* classic x86 sigcontext */
|
X86_SCF_LINUX_SIGFRAME, /* Linux x86 sigcontext */
|
||||||
X86_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
|
X86_SCF_LINUX_RT_SIGFRAME, /* POSIX ucontext_t */
|
||||||
|
X86_SCF_FREEBSD_SIGFRAME, /* FreeBSD x86 sigcontext */
|
||||||
|
X86_SCF_FREEBSD_SIGFRAME4, /* FreeBSD 4.x x86 sigcontext */
|
||||||
|
X86_SCF_FREEBSD_OSIGFRAME, /* FreeBSD pre-4.x x86 sigcontext */
|
||||||
|
X86_SCF_FREEBSD_SYSCALL, /* FreeBSD x86 syscall */
|
||||||
}
|
}
|
||||||
sigcontext_format;
|
sigcontext_format;
|
||||||
unw_word_t sigcontext_addr;
|
unw_word_t sigcontext_addr;
|
||||||
|
|
|
@ -59,9 +59,12 @@ unw_is_signal_frame (unw_cursor_t *cursor)
|
||||||
ip = c->dwarf.ip;
|
ip = c->dwarf.ip;
|
||||||
if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0
|
if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0
|
||||||
|| (ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0)
|
|| (ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = ((w0 == 0x0077b858 && w1 == 0x80cd0000)
|
ret = X86_SCF_NONE;
|
||||||
|| (w0 == 0x0000adb8 && w1 == 0x9080cd00));
|
if (w0 == 0x0077b858 && w1 == 0x80cd0000)
|
||||||
|
ret = X86_SCF_LINUX_SIGFRAME;
|
||||||
|
else if (w0 == 0x0000adb8 && w1 == 0x9080cd00)
|
||||||
|
ret = X86_SCF_LINUX_RT_SIGFRAME;
|
||||||
Debug (16, "returning %d\n", ret);
|
Debug (16, "returning %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
#elif defined __FreeBSD__
|
#elif defined __FreeBSD__
|
||||||
|
@ -100,12 +103,12 @@ XXX
|
||||||
(ret = (*a->access_mem) (as, ip + 20, &w4, 0, arg)) < 0 ||
|
(ret = (*a->access_mem) (as, ip + 20, &w4, 0, arg)) < 0 ||
|
||||||
(ret = (*a->access_mem) (as, ip + 24, &w5, 0, arg)) < 0)
|
(ret = (*a->access_mem) (as, ip + 24, &w5, 0, arg)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = (w0 == 0x2024448d && w1 == 0x5440f750 && w2 == 0x75000200 &&
|
ret = X86_SCF_NONE;
|
||||||
w3 == 0x14688e03 && w4 == 0x0001a1b8 && w5 == 0x80cd5000);
|
if (w0 == 0x2024448d && w1 == 0x5440f750 && w2 == 0x75000200 &&
|
||||||
if (ret != 0)
|
w3 == 0x14688e03 && w4 == 0x0001a1b8 && w5 == 0x80cd5000)
|
||||||
return (1);
|
ret = X86_SCF_FREEBSD_SIGFRAME;
|
||||||
Debug (16, "returning %d\n", ret);
|
Debug (16, "returning %d\n", ret);
|
||||||
return (0);
|
return (ret);
|
||||||
#else
|
#else
|
||||||
#error Port me
|
#error Port me
|
||||||
#endif
|
#endif
|
||||||
|
|
131
src/x86/Gregs.c
131
src/x86/Gregs.c
|
@ -26,8 +26,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
#include "offsets.h"
|
#include "offsets.h"
|
||||||
#include "unwind_i.h"
|
#include "unwind_i.h"
|
||||||
|
|
||||||
|
#if defined __linux__
|
||||||
static inline dwarf_loc_t
|
static inline dwarf_loc_t
|
||||||
linux_scratch_loc (struct cursor *c, unw_regnum_t reg)
|
get_scratch_loc (struct cursor *c, unw_regnum_t reg)
|
||||||
{
|
{
|
||||||
unw_word_t addr = c->sigcontext_addr, fpstate_addr, off;
|
unw_word_t addr = c->sigcontext_addr, fpstate_addr, off;
|
||||||
int ret, is_fpstate = 0;
|
int ret, is_fpstate = 0;
|
||||||
|
@ -132,12 +133,138 @@ linux_scratch_loc (struct cursor *c, unw_regnum_t reg)
|
||||||
else
|
else
|
||||||
return DWARF_MEM_LOC (c, addr + off);
|
return DWARF_MEM_LOC (c, addr + off);
|
||||||
}
|
}
|
||||||
|
#elif defined __FreeBSD__
|
||||||
|
static inline dwarf_loc_t
|
||||||
|
get_scratch_loc (struct cursor *c, unw_regnum_t reg)
|
||||||
|
{
|
||||||
|
unw_word_t addr = c->sigcontext_addr, fpstate_addr, off;
|
||||||
|
int ret, is_fpstate = 0;
|
||||||
|
|
||||||
|
switch (c->sigcontext_format)
|
||||||
|
{
|
||||||
|
case X86_SCF_NONE:
|
||||||
|
return DWARF_REG_LOC (&c->dwarf, reg);
|
||||||
|
|
||||||
|
case X86_SCF_FREEBSD_SIGFRAME:
|
||||||
|
addr += FREEBSD_UC_MCONTEXT_OFF;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case X86_SCF_FREEBSD_SIGFRAME4:
|
||||||
|
abort();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case X86_SCF_FREEBSD_OSIGFRAME:
|
||||||
|
/* XXXKIB */
|
||||||
|
abort();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case X86_SCF_FREEBSD_SYSCALL:
|
||||||
|
/* XXXKIB */
|
||||||
|
abort();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* XXXKIB */
|
||||||
|
abort();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (reg)
|
||||||
|
{
|
||||||
|
case UNW_X86_GS: off = FREEBSD_UC_MCONTEXT_GS_OFF; break;
|
||||||
|
case UNW_X86_FS: off = FREEBSD_UC_MCONTEXT_FS_OFF; break;
|
||||||
|
case UNW_X86_ES: off = FREEBSD_UC_MCONTEXT_ES_OFF; break;
|
||||||
|
case UNW_X86_DS: off = FREEBSD_UC_MCONTEXT_SS_OFF; break;
|
||||||
|
case UNW_X86_EDI: off = FREEBSD_UC_MCONTEXT_EDI_OFF; break;
|
||||||
|
case UNW_X86_ESI: off = FREEBSD_UC_MCONTEXT_ESI_OFF; break;
|
||||||
|
case UNW_X86_EBP: off = FREEBSD_UC_MCONTEXT_EBP_OFF; break;
|
||||||
|
case UNW_X86_ESP: off = FREEBSD_UC_MCONTEXT_ESP_OFF; break;
|
||||||
|
case UNW_X86_EBX: off = FREEBSD_UC_MCONTEXT_EBX_OFF; break;
|
||||||
|
case UNW_X86_EDX: off = FREEBSD_UC_MCONTEXT_EDX_OFF; break;
|
||||||
|
case UNW_X86_ECX: off = FREEBSD_UC_MCONTEXT_ECX_OFF; break;
|
||||||
|
case UNW_X86_EAX: off = FREEBSD_UC_MCONTEXT_EAX_OFF; break;
|
||||||
|
case UNW_X86_TRAPNO: off = FREEBSD_UC_MCONTEXT_TRAPNO_OFF; break;
|
||||||
|
case UNW_X86_EIP: off = FREEBSD_UC_MCONTEXT_EIP_OFF; break;
|
||||||
|
case UNW_X86_CS: off = FREEBSD_UC_MCONTEXT_CS_OFF; break;
|
||||||
|
case UNW_X86_EFLAGS: off = FREEBSD_UC_MCONTEXT_EFLAGS_OFF; break;
|
||||||
|
case UNW_X86_SS: off = FREEBSD_UC_MCONTEXT_SS_OFF; break;
|
||||||
|
|
||||||
|
/* The following is probably not correct for all possible cases.
|
||||||
|
Somebody who understands this better should review this for
|
||||||
|
correctness. */
|
||||||
|
|
||||||
|
case UNW_X86_FCW: is_fpstate = 1; off = LINUX_FPSTATE_CW_OFF; break;
|
||||||
|
case UNW_X86_FSW: is_fpstate = 1; off = LINUX_FPSTATE_SW_OFF; break;
|
||||||
|
case UNW_X86_FTW: is_fpstate = 1; off = LINUX_FPSTATE_TAG_OFF; break;
|
||||||
|
case UNW_X86_FCS: is_fpstate = 1; off = LINUX_FPSTATE_CSSEL_OFF; break;
|
||||||
|
case UNW_X86_FIP: is_fpstate = 1; off = LINUX_FPSTATE_IPOFF_OFF; break;
|
||||||
|
case UNW_X86_FEA: is_fpstate = 1; off = LINUX_FPSTATE_DATAOFF_OFF; break;
|
||||||
|
case UNW_X86_FDS: is_fpstate = 1; off = LINUX_FPSTATE_DATASEL_OFF; break;
|
||||||
|
case UNW_X86_MXCSR: is_fpstate = 1; off = LINUX_FPSTATE_MXCSR_OFF; break;
|
||||||
|
|
||||||
|
/* stacked fp registers */
|
||||||
|
case UNW_X86_ST0: case UNW_X86_ST1: case UNW_X86_ST2: case UNW_X86_ST3:
|
||||||
|
case UNW_X86_ST4: case UNW_X86_ST5: case UNW_X86_ST6: case UNW_X86_ST7:
|
||||||
|
is_fpstate = 1;
|
||||||
|
off = LINUX_FPSTATE_ST0_OFF + 10*(reg - UNW_X86_ST0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* SSE fp registers */
|
||||||
|
case UNW_X86_XMM0_lo: case UNW_X86_XMM0_hi:
|
||||||
|
case UNW_X86_XMM1_lo: case UNW_X86_XMM1_hi:
|
||||||
|
case UNW_X86_XMM2_lo: case UNW_X86_XMM2_hi:
|
||||||
|
case UNW_X86_XMM3_lo: case UNW_X86_XMM3_hi:
|
||||||
|
case UNW_X86_XMM4_lo: case UNW_X86_XMM4_hi:
|
||||||
|
case UNW_X86_XMM5_lo: case UNW_X86_XMM5_hi:
|
||||||
|
case UNW_X86_XMM6_lo: case UNW_X86_XMM6_hi:
|
||||||
|
case UNW_X86_XMM7_lo: case UNW_X86_XMM7_hi:
|
||||||
|
is_fpstate = 1;
|
||||||
|
off = LINUX_FPSTATE_XMM0_OFF + 8*(reg - UNW_X86_XMM0_lo);
|
||||||
|
break;
|
||||||
|
case UNW_X86_XMM0:
|
||||||
|
case UNW_X86_XMM1:
|
||||||
|
case UNW_X86_XMM2:
|
||||||
|
case UNW_X86_XMM3:
|
||||||
|
case UNW_X86_XMM4:
|
||||||
|
case UNW_X86_XMM5:
|
||||||
|
case UNW_X86_XMM6:
|
||||||
|
case UNW_X86_XMM7:
|
||||||
|
is_fpstate = 1;
|
||||||
|
off = LINUX_FPSTATE_XMM0_OFF + 16*(reg - UNW_X86_XMM0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UNW_X86_FOP:
|
||||||
|
case UNW_X86_TSS:
|
||||||
|
case UNW_X86_LDT:
|
||||||
|
default:
|
||||||
|
return DWARF_REG_LOC (&c->dwarf, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_fpstate)
|
||||||
|
{
|
||||||
|
if ((ret = dwarf_get (&c->dwarf,
|
||||||
|
DWARF_MEM_LOC (&c->dwarf,
|
||||||
|
addr + LINUX_SC_FPSTATE_OFF),
|
||||||
|
&fpstate_addr)) < 0)
|
||||||
|
return DWARF_NULL_LOC;
|
||||||
|
|
||||||
|
if (!fpstate_addr)
|
||||||
|
return DWARF_NULL_LOC;
|
||||||
|
|
||||||
|
return DWARF_MEM_LOC (c, fpstate_addr + off);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return DWARF_MEM_LOC (c, addr + off);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error Port me
|
||||||
|
#endif
|
||||||
|
|
||||||
HIDDEN dwarf_loc_t
|
HIDDEN dwarf_loc_t
|
||||||
x86_scratch_loc (struct cursor *c, unw_regnum_t reg)
|
x86_scratch_loc (struct cursor *c, unw_regnum_t reg)
|
||||||
{
|
{
|
||||||
if (c->sigcontext_addr)
|
if (c->sigcontext_addr)
|
||||||
return linux_scratch_loc (c, reg);
|
return get_scratch_loc (c, reg);
|
||||||
else
|
else
|
||||||
return DWARF_REG_LOC (&c->dwarf, reg);
|
return DWARF_REG_LOC (&c->dwarf, reg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "unwind_i.h"
|
#include "unwind_i.h"
|
||||||
|
#include "offsets.h"
|
||||||
|
|
||||||
#ifndef UNW_REMOTE_ONLY
|
#ifndef UNW_REMOTE_ONLY
|
||||||
|
|
||||||
|
@ -67,13 +68,16 @@ x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
||||||
if (c->sigcontext_format == X86_SCF_NONE) {
|
if (c->sigcontext_format == X86_SCF_NONE) {
|
||||||
Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip);
|
Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip);
|
||||||
setcontext (uc);
|
setcontext (uc);
|
||||||
} else if (c->sigcontext_format == XXX) {
|
} else if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) {
|
||||||
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||||
|
|
||||||
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
|
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
|
||||||
sigreturn(sc);
|
sigreturn((const char *)sc + FREEBSD_UC_MCONTEXT_OFF);
|
||||||
|
} else {
|
||||||
|
Debug (8, "resuming at ip=%x for sigcontext format %d not implemented\n",
|
||||||
|
c->sigcontext_format);
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#else
|
#else
|
||||||
# warning Implement me!
|
# warning Implement me!
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,17 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <ucontext.h>
|
||||||
|
#include <machine/sigframe.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "unwind_i.h"
|
#include "unwind_i.h"
|
||||||
#include "offsets.h"
|
#include "offsets.h"
|
||||||
|
|
||||||
|
@ -30,7 +41,7 @@ PROTECTED int
|
||||||
unw_step (unw_cursor_t *cursor)
|
unw_step (unw_cursor_t *cursor)
|
||||||
{
|
{
|
||||||
struct cursor *c = (struct cursor *) cursor;
|
struct cursor *c = (struct cursor *) cursor;
|
||||||
int ret, i;
|
int ret, i, format;
|
||||||
|
|
||||||
Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip);
|
Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip);
|
||||||
|
|
||||||
|
@ -55,8 +66,10 @@ unw_step (unw_cursor_t *cursor)
|
||||||
|
|
||||||
Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);
|
Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);
|
||||||
|
|
||||||
if (unw_is_signal_frame (cursor))
|
format = unw_is_signal_frame (cursor);
|
||||||
|
if (format != X86_SCF_NONE)
|
||||||
{
|
{
|
||||||
|
#if defined __linux__
|
||||||
/* XXX This code is Linux-specific! */
|
/* XXX This code is Linux-specific! */
|
||||||
|
|
||||||
/* c->esp points at the arguments to the handler. Without
|
/* c->esp points at the arguments to the handler. Without
|
||||||
|
@ -119,6 +132,51 @@ unw_step (unw_cursor_t *cursor)
|
||||||
c->dwarf.loc[EFLAGS] = DWARF_NULL_LOC;
|
c->dwarf.loc[EFLAGS] = DWARF_NULL_LOC;
|
||||||
c->dwarf.loc[TRAPNO] = DWARF_NULL_LOC;
|
c->dwarf.loc[TRAPNO] = DWARF_NULL_LOC;
|
||||||
c->dwarf.loc[ST0] = DWARF_NULL_LOC;
|
c->dwarf.loc[ST0] = DWARF_NULL_LOC;
|
||||||
|
#elif defined __FreeBSD__
|
||||||
|
if (format == X86_SCF_FREEBSD_SIGFRAME) {
|
||||||
|
struct sigframe *sf;
|
||||||
|
uintptr_t uc_addr;
|
||||||
|
struct dwarf_loc esp_loc;
|
||||||
|
|
||||||
|
sf = (struct sigframe *)c->dwarf.cfa;
|
||||||
|
uc_addr = (uintptr_t)&(sf->sf_uc);
|
||||||
|
|
||||||
|
esp_loc = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_ESP_OFF, 0);
|
||||||
|
ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
Debug (2, "returning 0\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ebp_loc = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EBP_OFF, 0);
|
||||||
|
eip_loc = DWARF_LOC (uc_addr + FREEBSD_UC_MCONTEXT_EIP_OFF, 0);
|
||||||
|
|
||||||
|
c->dwarf.loc[EAX] = DWARF_LOC (uc_addr +
|
||||||
|
FREEBSD_UC_MCONTEXT_EAX_OFF, 0);
|
||||||
|
c->dwarf.loc[ECX] = DWARF_LOC (uc_addr +
|
||||||
|
FREEBSD_UC_MCONTEXT_ECX_OFF, 0);
|
||||||
|
c->dwarf.loc[EDX] = DWARF_LOC (uc_addr +
|
||||||
|
FREEBSD_UC_MCONTEXT_EDX_OFF, 0);
|
||||||
|
c->dwarf.loc[EBX] = DWARF_LOC (uc_addr +
|
||||||
|
FREEBSD_UC_MCONTEXT_EBX_OFF, 0);
|
||||||
|
c->dwarf.loc[EBP] = DWARF_LOC (uc_addr +
|
||||||
|
FREEBSD_UC_MCONTEXT_EBP_OFF, 0);
|
||||||
|
c->dwarf.loc[ESI] = DWARF_LOC (uc_addr +
|
||||||
|
FREEBSD_UC_MCONTEXT_ESI_OFF, 0);
|
||||||
|
c->dwarf.loc[EDI] = DWARF_LOC (uc_addr +
|
||||||
|
FREEBSD_UC_MCONTEXT_EDI_OFF, 0);
|
||||||
|
c->dwarf.loc[EFLAGS] = DWARF_LOC (uc_addr +
|
||||||
|
FREEBSD_UC_MCONTEXT_EFLAGS_OFF, 0);
|
||||||
|
c->dwarf.loc[TRAPNO] = DWARF_LOC (uc_addr +
|
||||||
|
FREEBSD_UC_MCONTEXT_EFLAGS_OFF, 0);
|
||||||
|
c->dwarf.loc[ST0] = DWARF_NULL_LOC;
|
||||||
|
} else {
|
||||||
|
Debug (8, "Gstep: not handling frame format %d\n", format);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error Port me
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,37 +76,41 @@ _Ux86_getcontext:
|
||||||
movl %ebp, FREEBSD_UC_MCONTEXT_EBP_OFF(%eax)
|
movl %ebp, FREEBSD_UC_MCONTEXT_EBP_OFF(%eax)
|
||||||
|
|
||||||
movl (%esp), %ecx
|
movl (%esp), %ecx
|
||||||
movl %ecx, FREEBSD_UC_MCONTEXT_OFF_EIP(%eax)
|
movl %ecx, FREEBSD_UC_MCONTEXT_EIP_OFF(%eax)
|
||||||
|
|
||||||
leal 4(%esp), %ecx /* Exclude the return address. */
|
leal 4(%esp), %ecx /* Exclude the return address. */
|
||||||
movl %ecx, FREEBSD_UC_MCONTEXT_OFF_ESP(%eax)
|
movl %ecx, FREEBSD_UC_MCONTEXT_ESP_OFF(%eax)
|
||||||
|
|
||||||
xorl %ecx, %ecx
|
xorl %ecx, %ecx
|
||||||
movw %fs, %cx
|
movw %fs, %cx
|
||||||
movl %ecx, FREEBSD_UC_MCONTEXT_OFF_FS(%eax)
|
movl %ecx, FREEBSD_UC_MCONTEXT_FS_OFF(%eax)
|
||||||
movw %gs, %cx
|
movw %gs, %cx
|
||||||
movl %ecx, FREEBSD_UC_MCONTEXT_OFF_GS(%eax)
|
movl %ecx, FREEBSD_UC_MCONTEXT_GS_OFF(%eax)
|
||||||
movw %ds, %cx
|
movw %ds, %cx
|
||||||
movl %ecx, FREEBSD_UC_MCONTEXT_OFF_DS(%eax)
|
movl %ecx, FREEBSD_UC_MCONTEXT_DS_OFF(%eax)
|
||||||
movw %es, %cx
|
movw %es, %cx
|
||||||
movl %ecx, FREEBSD_UC_MCONTEXT_OFF_ES(%eax)
|
movl %ecx, FREEBSD_UC_MCONTEXT_ES_OFF(%eax)
|
||||||
movw %ss, %cx
|
movw %ss, %cx
|
||||||
movl %ecx, FREEBSD_UC_MCONTEXT_OFF_SS(%eax)
|
movl %ecx, FREEBSD_UC_MCONTEXT_SS_OFF(%eax)
|
||||||
movw %cs, %cx
|
movw %cs, %cx
|
||||||
movl %ecx, FREEBSD_UC_MCONTEXT_OFF_CS(%eax)
|
movl %ecx, FREEBSD_UC_MCONTEXT_CS_OFF(%eax)
|
||||||
|
|
||||||
pushfl
|
pushfl
|
||||||
popl FREEBSD_UC_MCONTEXT_OFF_EFLAGS(%eax)
|
popl FREEBSD_UC_MCONTEXT_EFLAGS_OFF(%eax)
|
||||||
|
|
||||||
movl $FREEBSD_UC_MCONTEXT_FPOWNED_FPU,FREEBSD_UC_MCONTEXT_OWNEDFP(%eax)
|
|
||||||
movl $FREEBSD_UC_MCONTEXT_FPFMT_XMM,FREEBSD_UC_MCONTEXT_FPFORMAT(%eax)
|
|
||||||
|
|
||||||
|
movl $0, FREEBSD_UC_MCONTEXT_TRAPNO_OFF(%eax)
|
||||||
|
movl $FREEBSD_UC_MCONTEXT_FPOWNED_FPU,\
|
||||||
|
FREEBSD_UC_MCONTEXT_OWNEDFP_OFF(%eax)
|
||||||
|
movl $FREEBSD_UC_MCONTEXT_FPFMT_XMM,\
|
||||||
|
FREEBSD_UC_MCONTEXT_FPFORMAT_OFF(%eax)
|
||||||
|
/*
|
||||||
leal LINUX_UC_FPREGS_MEM_OFF(%eax), %ecx
|
leal LINUX_UC_FPREGS_MEM_OFF(%eax), %ecx
|
||||||
movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FPSTATE_OFF)(%eax)
|
movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FPSTATE_OFF)(%eax)
|
||||||
fnstenv (%ecx)
|
fnstenv (%ecx)
|
||||||
fldenv (%ecx)
|
fldenv (%ecx)
|
||||||
|
*/
|
||||||
movl $FREEBSD_UC_MCONTEXT_MC_LEN_VAL, FREEBSD_UC_MCONTEXT_MC_LEN(%eax)
|
movl $FREEBSD_UC_MCONTEXT_MC_LEN_VAL,\
|
||||||
|
FREEBSD_UC_MCONTEXT_MC_LEN_OFF(%eax)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xor %eax, %eax
|
xor %eax, %eax
|
||||||
|
|
|
@ -83,6 +83,9 @@
|
||||||
#define LINUX_FPSTATE_XMM6_OFF 0x170
|
#define LINUX_FPSTATE_XMM6_OFF 0x170
|
||||||
#define LINUX_FPSTATE_XMM7_OFF 0x180
|
#define LINUX_FPSTATE_XMM7_OFF 0x180
|
||||||
|
|
||||||
|
#define FREEBSD_SC_UCONTEXT_OFF 0x14
|
||||||
|
#define FREEBSD_UC_MCONTEXT_OFF 0x10
|
||||||
|
|
||||||
#define FREEBSD_UC_MCONTEXT_EAX_OFF 0x40
|
#define FREEBSD_UC_MCONTEXT_EAX_OFF 0x40
|
||||||
#define FREEBSD_UC_MCONTEXT_EBX_OFF 0x34
|
#define FREEBSD_UC_MCONTEXT_EBX_OFF 0x34
|
||||||
#define FREEBSD_UC_MCONTEXT_ECX_OFF 0x3c
|
#define FREEBSD_UC_MCONTEXT_ECX_OFF 0x3c
|
||||||
|
@ -90,19 +93,20 @@
|
||||||
#define FREEBSD_UC_MCONTEXT_EDI_OFF 0x24
|
#define FREEBSD_UC_MCONTEXT_EDI_OFF 0x24
|
||||||
#define FREEBSD_UC_MCONTEXT_ESI_OFF 0x28
|
#define FREEBSD_UC_MCONTEXT_ESI_OFF 0x28
|
||||||
#define FREEBSD_UC_MCONTEXT_EBP_OFF 0x2c
|
#define FREEBSD_UC_MCONTEXT_EBP_OFF 0x2c
|
||||||
#define FREEBSD_UC_MCONTEXT_OFF_EIP 0x4c
|
#define FREEBSD_UC_MCONTEXT_EIP_OFF 0x4c
|
||||||
#define FREEBSD_UC_MCONTEXT_OFF_ESP 0x58
|
#define FREEBSD_UC_MCONTEXT_ESP_OFF 0x58
|
||||||
#define FREEBSD_UC_MCONTEXT_OFF_FS 0x18
|
#define FREEBSD_UC_MCONTEXT_FS_OFF 0x18
|
||||||
#define FREEBSD_UC_MCONTEXT_OFF_GS 0x14
|
#define FREEBSD_UC_MCONTEXT_GS_OFF 0x14
|
||||||
#define FREEBSD_UC_MCONTEXT_OFF_DS 0x20
|
#define FREEBSD_UC_MCONTEXT_DS_OFF 0x20
|
||||||
#define FREEBSD_UC_MCONTEXT_OFF_ES 0x1c
|
#define FREEBSD_UC_MCONTEXT_ES_OFF 0x1c
|
||||||
#define FREEBSD_UC_MCONTEXT_OFF_SS 0x5c
|
#define FREEBSD_UC_MCONTEXT_SS_OFF 0x5c
|
||||||
#define FREEBSD_UC_MCONTEXT_OFF_CS 0x50
|
#define FREEBSD_UC_MCONTEXT_CS_OFF 0x50
|
||||||
#define FREEBSD_UC_MCONTEXT_OFF_EFLAGS 0x54
|
#define FREEBSD_UC_MCONTEXT_EFLAGS_OFF 0x54
|
||||||
#define FREEBSD_UC_MCONTEXT_OWNEDFP 0x68
|
#define FREEBSD_UC_MCONTEXT_OWNEDFP_OFF 0x68
|
||||||
#define FREEBSD_UC_MCONTEXT_FPFORMAT 0x64
|
#define FREEBSD_UC_MCONTEXT_FPFORMAT_OFF 0x64
|
||||||
#define FREEBSD_UC_MCONTEXT_FPSTATE 0x70
|
#define FREEBSD_UC_MCONTEXT_FPSTATE_OFF 0x70
|
||||||
#define FREEBSD_UC_MCONTEXT_MC_LEN 0x60
|
#define FREEBSD_UC_MCONTEXT_MC_LEN_OFF 0x60
|
||||||
|
#define FREEBSD_UC_MCONTEXT_TRAPNO_OFF 0x44
|
||||||
|
|
||||||
#define FREEBSD_UC_MCONTEXT_MC_LEN_VAL 0x280
|
#define FREEBSD_UC_MCONTEXT_MC_LEN_VAL 0x280
|
||||||
#define FREEBSD_UC_MCONTEXT_FPOWNED_FPU 0x20001
|
#define FREEBSD_UC_MCONTEXT_FPOWNED_FPU 0x20001
|
||||||
|
|
Loading…
Reference in a new issue