libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libunwind-devel] [PATCH] x86: Add sigreturn asm stub


From: Dave Watson
Subject: [Libunwind-devel] [PATCH] x86: Add sigreturn asm stub
Date: Fri, 18 Aug 2017 08:15:59 -0700
User-agent: Mutt/1.6.0 (2016-04-01)

glibc no longer defines sigreturn, but we want to use it
when unwinding through signal stacks to resture the signal mask,
without forcing all uses of getcontext/setcontext to save and
restore the signal mask
---
 src/x86/Gos-linux.c | 25 +++++++++++++++++++++++--
 src/x86/unwind_i.h  |  3 +++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/x86/Gos-linux.c b/src/x86/Gos-linux.c
index 17aebc29..37a22b97 100644
--- a/src/x86/Gos-linux.c
+++ b/src/x86/Gos-linux.c
@@ -52,7 +52,7 @@ unw_is_signal_frame (unw_cursor_t *cursor)
     __restore_rt:
        0xb8 0xad 0x00 0x00 0x00        movl 0xad,%eax
        0xcd 0x80                       int 0x80
-       0x00                            
+       0x00
 
      if SA_SIGINFO is specified.
   */
@@ -296,7 +296,7 @@ x86_local_resume (unw_addr_space_t as, unw_cursor_t 
*cursor, void *arg)
       struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
 
       Debug (8, "resuming at ip=%x via sigreturn(%p)\n", c->dwarf.ip, sc);
-      sigreturn (sc);
+      x86_sigreturn (sc);
     }
   else
     {
@@ -305,4 +305,25 @@ x86_local_resume (unw_addr_space_t as, unw_cursor_t 
*cursor, void *arg)
     }
   return -UNW_EINVAL;
 }
+
+/* sigreturn() is a no-op on x86 glibc.  */
+HIDDEN void
+x86_sigreturn (unw_cursor_t *cursor)
+{
+  struct cursor *c = (struct cursor *) cursor;
+  struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr;
+  mcontext_t *sc_mcontext = &((struct ucontext*)sc)->uc_mcontext;
+  /* Copy in saved uc - all preserved regs are at the start of sigcontext */
+  memcpy(sc_mcontext, &c->uc->uc_mcontext,
+         DWARF_NUM_PRESERVED_REGS * sizeof(unw_word_t));
+
+  Debug (8, "resuming at ip=%llx via sigreturn(%p)\n",
+             (unsigned long long) c->dwarf.ip, sc);
+  __asm__ __volatile__ ("mov %0, %%esp;"
+                        "mov %1, %%eax;"
+                        "syscall"
+                        :: "r"(sc), "i"(SYS_rt_sigreturn)
+                        : "memory");
+  abort();
+}
 #endif
diff --git a/src/x86/unwind_i.h b/src/x86/unwind_i.h
index cd528242..d2aed609 100644
--- a/src/x86/unwind_i.h
+++ b/src/x86/unwind_i.h
@@ -52,6 +52,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.  */
 #define x86_scratch_loc                 UNW_OBJ(scratch_loc)
 #define x86_get_scratch_loc             UNW_OBJ(get_scratch_loc)
 #define x86_r_uc_addr                   UNW_OBJ(r_uc_addr)
+#define x86_sigreturn                   UNW_OBJ(sigreturn)
 
 extern void x86_local_addr_space_init (void);
 extern int x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
@@ -60,4 +61,6 @@ extern dwarf_loc_t x86_scratch_loc (struct cursor *c, 
unw_regnum_t reg);
 extern dwarf_loc_t x86_get_scratch_loc (struct cursor *c, unw_regnum_t reg);
 extern void *x86_r_uc_addr (ucontext_t *uc, int reg);
 
+extern void x86_sigreturn (unw_cursor_t *cursor);
+
 #endif /* unwind_i_h */
-- 
2.13.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]