mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-05 01:09:27 +01:00
Move local_resume to os-specific file.
This commit is contained in:
parent
0dbeeeb08d
commit
979af4502f
7 changed files with 89 additions and 87 deletions
|
@ -287,4 +287,33 @@ x86_r_uc_addr (ucontext_t *uc, int reg)
|
|||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
HIDDEN int
|
||||
x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
||||
{
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
ucontext_t *uc = c->uc;
|
||||
|
||||
/* Ensure c->pi is up-to-date. On x86, it's relatively common to be
|
||||
missing DWARF unwind info. We don't want to fail in that case,
|
||||
because the frame-chain still would let us do a backtrace at
|
||||
least. */
|
||||
dwarf_make_proc_info (&c->dwarf);
|
||||
|
||||
if (c->sigcontext_format == X86_SCF_NONE) {
|
||||
Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip);
|
||||
setcontext (uc);
|
||||
} else if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) {
|
||||
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||
|
||||
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, 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();
|
||||
}
|
||||
return -UNW_EINVAL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -275,4 +275,31 @@ x86_r_uc_addr (ucontext_t *uc, int reg)
|
|||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
HIDDEN int
|
||||
x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
||||
{
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
ucontext_t *uc = c->uc;
|
||||
|
||||
/* Ensure c->pi is up-to-date. On x86, it's relatively common to be
|
||||
missing DWARF unwind info. We don't want to fail in that case,
|
||||
because the frame-chain still would let us do a backtrace at
|
||||
least. */
|
||||
dwarf_make_proc_info (&c->dwarf);
|
||||
|
||||
if (unlikely (c->sigcontext_format != X86_SCF_NONE))
|
||||
{
|
||||
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||
|
||||
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
|
||||
sigreturn (sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip);
|
||||
setcontext (uc);
|
||||
}
|
||||
return -UNW_EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -28,64 +28,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||
#include "unwind_i.h"
|
||||
#include "offsets.h"
|
||||
|
||||
#ifndef UNW_REMOTE_ONLY
|
||||
|
||||
HIDDEN inline int
|
||||
x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
||||
{
|
||||
#if defined(__linux)
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
ucontext_t *uc = c->uc;
|
||||
|
||||
/* Ensure c->pi is up-to-date. On x86, it's relatively common to be
|
||||
missing DWARF unwind info. We don't want to fail in that case,
|
||||
because the frame-chain still would let us do a backtrace at
|
||||
least. */
|
||||
dwarf_make_proc_info (&c->dwarf);
|
||||
|
||||
if (unlikely (c->sigcontext_format != X86_SCF_NONE))
|
||||
{
|
||||
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||
|
||||
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
|
||||
sigreturn (sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip);
|
||||
setcontext (uc);
|
||||
}
|
||||
#elif defined __FreeBSD__
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
ucontext_t *uc = c->uc;
|
||||
|
||||
/* Ensure c->pi is up-to-date. On x86, it's relatively common to be
|
||||
missing DWARF unwind info. We don't want to fail in that case,
|
||||
because the frame-chain still would let us do a backtrace at
|
||||
least. */
|
||||
dwarf_make_proc_info (&c->dwarf);
|
||||
|
||||
if (c->sigcontext_format == X86_SCF_NONE) {
|
||||
Debug (8, "resuming at ip=%x via setcontext()\n", c->dwarf.ip);
|
||||
setcontext (uc);
|
||||
} else if (c->sigcontext_format == X86_SCF_FREEBSD_SIGFRAME) {
|
||||
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||
|
||||
Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, 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
|
||||
# warning Implement me!
|
||||
#endif
|
||||
return -UNW_EINVAL;
|
||||
}
|
||||
|
||||
#endif /* !UNW_REMOTE_ONLY */
|
||||
|
||||
/* This routine is responsible for copying the register values in
|
||||
cursor C and establishing them as the current machine state. */
|
||||
|
||||
|
|
|
@ -180,4 +180,15 @@ x86_64_r_uc_addr (ucontext_t *uc, int reg)
|
|||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
HIDDEN NORETURN void
|
||||
x86_64_sigreturn (unw_cursor_t *cursor)
|
||||
{
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
ucontext_t *uc = c->uc;
|
||||
|
||||
Debug (8, "resuming at ip=%llx via sigreturn(%p)\n",
|
||||
(unsigned long long) c->dwarf.ip, uc);
|
||||
sigreturn(uc);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -28,6 +28,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||
#include "unwind_i.h"
|
||||
#include "ucontext_i.h"
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
PROTECTED int
|
||||
unw_is_signal_frame (unw_cursor_t *cursor)
|
||||
{
|
||||
|
@ -129,4 +131,21 @@ x86_64_r_uc_addr (ucontext_t *uc, int reg)
|
|||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* sigreturn() is a no-op on x86_64 glibc. */
|
||||
HIDDEN NORETURN void
|
||||
x86_64_sigreturn (unw_cursor_t *cursor)
|
||||
{
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||
|
||||
Debug (8, "resuming at ip=%llx via sigreturn(%p)\n",
|
||||
(unsigned long long) c->dwarf.ip, sc);
|
||||
__asm__ __volatile__ ("mov %0, %%rsp;"
|
||||
"mov %1, %%rax;"
|
||||
"syscall"
|
||||
:: "r"(sc), "i"(SYS_rt_sigreturn)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,22 +32,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||
|
||||
#ifndef UNW_REMOTE_ONLY
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#if defined __linux
|
||||
/* sigreturn() is a no-op on x86_64 glibc. */
|
||||
|
||||
static NORETURN inline long
|
||||
my_rt_sigreturn (void *new_sp)
|
||||
{
|
||||
__asm__ __volatile__ ("mov %0, %%rsp;"
|
||||
"mov %1, %%rax;"
|
||||
"syscall"
|
||||
:: "r"(new_sp), "i"(SYS_rt_sigreturn)
|
||||
: "memory");
|
||||
}
|
||||
#endif
|
||||
|
||||
HIDDEN inline int
|
||||
x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
||||
{
|
||||
|
@ -62,19 +46,7 @@ x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg)
|
|||
|
||||
if (unlikely (c->sigcontext_format != X86_64_SCF_NONE))
|
||||
{
|
||||
#if defined __linux__
|
||||
struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
|
||||
|
||||
Debug (8, "resuming at ip=%llx via sigreturn(%p)\n",
|
||||
(unsigned long long) c->dwarf.ip, sc);
|
||||
my_rt_sigreturn (sc);
|
||||
#elif defined __FreeBSD__
|
||||
Debug (8, "resuming at ip=%llx via sigreturn(%p)\n",
|
||||
(unsigned long long) c->dwarf.ip, uc);
|
||||
sigreturn(uc);
|
||||
#else
|
||||
#error Port me
|
||||
#endif
|
||||
x86_64_sigreturn(cursor);
|
||||
abort();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -63,6 +63,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|||
#define x86_64_scratch_loc UNW_OBJ(scratch_loc)
|
||||
#endif
|
||||
#define x86_64_r_uc_addr UNW_OBJ(r_uc_addr)
|
||||
#define x86_64_sigreturn UNW_OBJ(sigreturn)
|
||||
|
||||
extern void x86_64_local_addr_space_init (void);
|
||||
extern int x86_64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
|
||||
|
@ -74,5 +75,6 @@ extern dwarf_loc_t x86_64_scratch_loc (struct cursor *c, unw_regnum_t reg);
|
|||
#endif
|
||||
|
||||
extern void *x86_64_r_uc_addr (ucontext_t *uc, int reg);
|
||||
extern NORETURN void x86_64_sigreturn (unw_cursor_t *cursor);
|
||||
|
||||
#endif /* unwind_i_h */
|
||||
|
|
Loading…
Reference in a new issue