mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-12-23 03:53:43 +01:00
Support walk over freebsd sigframes
This commit is contained in:
parent
d0d5f9979b
commit
c64723835c
5 changed files with 27 additions and 10 deletions
|
@ -62,7 +62,8 @@ struct cursor
|
|||
enum
|
||||
{
|
||||
X86_64_SCF_NONE, /* no signal frame encountered */
|
||||
X86_64_SCF_LINUX_RT_SIGFRAME /* POSIX ucontext_t */
|
||||
X86_64_SCF_LINUX_RT_SIGFRAME, /* Linux ucontext_t */
|
||||
X86_64_SCF_FREEBSD_SIGFRAME, /* FreeBSD ucontext_t */
|
||||
}
|
||||
sigcontext_format;
|
||||
unw_word_t sigcontext_addr;
|
||||
|
|
|
@ -82,3 +82,6 @@
|
|||
#define LINUX_FPSTATE_XMM5_OFF 0x160
|
||||
#define LINUX_FPSTATE_XMM6_OFF 0x170
|
||||
#define LINUX_FPSTATE_XMM7_OFF 0x180
|
||||
|
||||
/* FreeBSD specific definitions */
|
||||
#define FREEBSD_UC_MCONTEXT_OFF 0x10
|
||||
|
|
|
@ -97,17 +97,14 @@ eb fd jmp 0b
|
|||
|| (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0
|
||||
|| (ret = (*a->access_mem) (as, ip + 16, &w2, 0, arg)) < 0)
|
||||
return 0;
|
||||
#if 0
|
||||
fprintf(stderr, "is_signal_frame: ip %lx w0 %lx w1 %lx w2 %lx\n",
|
||||
ip, w0, w1, w2);
|
||||
#endif
|
||||
w2 &= 0xffffff;
|
||||
return (w0 == 0x48006a10247c8d48 &&
|
||||
ret = w0 == 0x48006a10247c8d48 &&
|
||||
w1 == 0x050f000001a1c0c7 &&
|
||||
w2 == 0x0000000000fdebf4);
|
||||
w2 == 0x0000000000fdebf4;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else /* __linux__ */
|
||||
#else /* !__linux__ && !__FreeBSD__ */
|
||||
|
||||
PROTECTED int
|
||||
unw_is_signal_frame (unw_cursor_t *cursor)
|
||||
|
@ -115,4 +112,4 @@ unw_is_signal_frame (unw_cursor_t *cursor)
|
|||
printf ("%s: implement me\n", __FUNCTION__);
|
||||
return -UNW_ENOINFO;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,10 @@ linux_scratch_loc (struct cursor *c, unw_regnum_t reg)
|
|||
case X86_64_SCF_LINUX_RT_SIGFRAME:
|
||||
addr += LINUX_UC_MCONTEXT_OFF;
|
||||
break;
|
||||
|
||||
case X86_64_SCF_FREEBSD_SIGFRAME:
|
||||
addr += FREEBSD_UC_MCONTEXT_OFF;
|
||||
break;
|
||||
}
|
||||
|
||||
return DWARF_REG_LOC (&c->dwarf, reg);
|
||||
|
|
|
@ -28,6 +28,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||
#include "unwind_i.h"
|
||||
#include "ucontext_i.h"
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined __FreeBSD__
|
||||
#include <sys/ucontext.h>
|
||||
#include <machine/sigframe.h>
|
||||
#endif
|
||||
|
||||
PROTECTED int
|
||||
unw_step (unw_cursor_t *cursor)
|
||||
|
@ -79,11 +85,17 @@ unw_step (unw_cursor_t *cursor)
|
|||
|
||||
if (unw_is_signal_frame (cursor))
|
||||
{
|
||||
unw_word_t ucontext = c->dwarf.cfa;
|
||||
unw_word_t ucontext;
|
||||
|
||||
Debug(1, "signal frame, skip over trampoline\n");
|
||||
|
||||
#if defined __linux__
|
||||
ucontext = c->dwarf.cfa;
|
||||
c->sigcontext_format = X86_64_SCF_LINUX_RT_SIGFRAME;
|
||||
#elif defined __FreeBSD__
|
||||
ucontext = c->dwarf.cfa + offsetof(struct sigframe, sf_uc);
|
||||
c->sigcontext_format = X86_64_SCF_FREEBSD_SIGFRAME;
|
||||
#endif
|
||||
c->sigcontext_addr = c->dwarf.cfa;
|
||||
|
||||
rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0);
|
||||
|
|
Loading…
Reference in a new issue