1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-06-25 02:41:45 +02:00

Move local_resume to os-specific file.

This commit is contained in:
Konstantin Belousov 2010-04-05 23:00:27 +03:00
parent 0dbeeeb08d
commit 979af4502f
7 changed files with 89 additions and 87 deletions

View file

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

View file

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

View file

@ -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. */

View file

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

View file

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

View file

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

View file

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