From 979af4502fe19b0d98459633731d004a4a010a0e Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 5 Apr 2010 23:00:27 +0300 Subject: [PATCH] Move local_resume to os-specific file. --- src/x86/Gos-freebsd.c | 29 ++++++++++++++++++++ src/x86/Gos-linux.c | 27 +++++++++++++++++++ src/x86/Gresume.c | 58 ---------------------------------------- src/x86_64/Gos-freebsd.c | 11 ++++++++ src/x86_64/Gos-linux.c | 19 +++++++++++++ src/x86_64/Gresume.c | 30 +-------------------- src/x86_64/unwind_i.h | 2 ++ 7 files changed, 89 insertions(+), 87 deletions(-) diff --git a/src/x86/Gos-freebsd.c b/src/x86/Gos-freebsd.c index f3f04bcf..0dd3b437 100644 --- a/src/x86/Gos-freebsd.c +++ b/src/x86/Gos-freebsd.c @@ -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 diff --git a/src/x86/Gos-linux.c b/src/x86/Gos-linux.c index 99f585ea..b31f96a1 100644 --- a/src/x86/Gos-linux.c +++ b/src/x86/Gos-linux.c @@ -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 diff --git a/src/x86/Gresume.c b/src/x86/Gresume.c index 40ab82b2..c39c5884 100644 --- a/src/x86/Gresume.c +++ b/src/x86/Gresume.c @@ -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. */ diff --git a/src/x86_64/Gos-freebsd.c b/src/x86_64/Gos-freebsd.c index a2b13bb7..91d60a18 100644 --- a/src/x86_64/Gos-freebsd.c +++ b/src/x86_64/Gos-freebsd.c @@ -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 diff --git a/src/x86_64/Gos-linux.c b/src/x86_64/Gos-linux.c index aa13e031..b37ea4c5 100644 --- a/src/x86_64/Gos-linux.c +++ b/src/x86_64/Gos-linux.c @@ -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 + 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 diff --git a/src/x86_64/Gresume.c b/src/x86_64/Gresume.c index 13c8059a..d5239fc1 100644 --- a/src/x86_64/Gresume.c +++ b/src/x86_64/Gresume.c @@ -32,22 +32,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef UNW_REMOTE_ONLY -#include - -#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 diff --git a/src/x86_64/unwind_i.h b/src/x86_64/unwind_i.h index f45f5ead..699a6b38 100644 --- a/src/x86_64/unwind_i.h +++ b/src/x86_64/unwind_i.h @@ -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 */