1
0
Fork 0
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:
Konstantin Belousov 2010-03-07 21:53:01 +02:00
parent d0d5f9979b
commit c64723835c
5 changed files with 27 additions and 10 deletions

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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);