Skip to content

Commit

Permalink
Decorate the aarch64 signal trampoline with CFI attributes easing unw…
Browse files Browse the repository at this point in the history
…inding

Now, the unwinders (in backtrace(3) and similar) can unwind properly
the stack from a signal handler.
  • Loading branch information
krytarowski committed Oct 13, 2020
1 parent f6bb4c9 commit e5e90f1
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 2 deletions.
32 changes: 31 additions & 1 deletion lib/libc/arch/aarch64/genassym.cf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.2 2020/05/10 14:05:59 skrll Exp $
# $NetBSD: genassym.cf,v 1.3 2020/10/13 01:59:55 kamil Exp $

#-
# Copyright (c) 2014 The NetBSD Foundation, Inc.
Expand Down Expand Up @@ -34,6 +34,36 @@ include <ucontext.h>
include <setjmp.h>

define _UC_REGS_X0 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X0])
define _UC_REGS_X1 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X1])
define _UC_REGS_X2 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X2])
define _UC_REGS_X3 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X3])
define _UC_REGS_X4 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X4])
define _UC_REGS_X5 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X5])
define _UC_REGS_X6 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X6])
define _UC_REGS_X7 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X7])
define _UC_REGS_X8 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X8])
define _UC_REGS_X9 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X9])
define _UC_REGS_X10 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X10])
define _UC_REGS_X11 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X11])
define _UC_REGS_X12 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X12])
define _UC_REGS_X13 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X13])
define _UC_REGS_X14 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X14])
define _UC_REGS_X15 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X15])
define _UC_REGS_X16 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X16])
define _UC_REGS_X17 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X17])
define _UC_REGS_X18 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X18])
define _UC_REGS_X19 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X19])
define _UC_REGS_X20 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X20])
define _UC_REGS_X21 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X21])
define _UC_REGS_X22 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X22])
define _UC_REGS_X23 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X23])
define _UC_REGS_X24 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X24])
define _UC_REGS_X25 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X25])
define _UC_REGS_X26 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X26])
define _UC_REGS_X27 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X27])
define _UC_REGS_X28 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X28])
define _UC_REGS_X29 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X29])
define _UC_REGS_X30 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_X30])
define _UC_REGS_SP offsetof(ucontext_t, uc_mcontext.__gregs[_REG_SP])
define _UC_REGS_PC offsetof(ucontext_t, uc_mcontext.__gregs[_REG_PC])

Expand Down
46 changes: 45 additions & 1 deletion lib/libc/arch/aarch64/sys/__sigtramp2.S
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: __sigtramp2.S,v 1.1 2014/08/10 05:47:37 matt Exp $ */
/* $NetBSD: __sigtramp2.S,v 1.2 2020/10/13 01:59:55 kamil Exp $ */

/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
Expand Down Expand Up @@ -30,6 +30,7 @@
*/

#include "SYS.h"
#include "assym.h"

/*
* The ARM signal trampoline is invoked only to return from
Expand All @@ -40,11 +41,54 @@
* ucontext structure
* sp-> siginfo structure
* and x28 points to the ucontext
*
* The unwind entry includes the one byte prior to the trampoline
* because the unwinder will look up (return PC - 1) while unwinding.
* Normally (return PC - 1) computes an address inside the call
* instruction that created the child frame, but here there is no call
* instruction so we have to manually add padding.
*/
.cfi_startproc simple
.cfi_signal_frame
.cfi_def_cfa x28, 0
.cfi_offset x0, _UC_REGS_X0
.cfi_offset x1, _UC_REGS_X1
.cfi_offset x2, _UC_REGS_X2
.cfi_offset x3, _UC_REGS_X3
.cfi_offset x4, _UC_REGS_X4
.cfi_offset x5, _UC_REGS_X5
.cfi_offset x6, _UC_REGS_X6
.cfi_offset x7, _UC_REGS_X7
.cfi_offset x8, _UC_REGS_X8
.cfi_offset x9, _UC_REGS_X9
.cfi_offset x10, _UC_REGS_X10
.cfi_offset x11, _UC_REGS_X11
.cfi_offset x12, _UC_REGS_X12
.cfi_offset x13, _UC_REGS_X13
.cfi_offset x14, _UC_REGS_X14
.cfi_offset x15, _UC_REGS_X15
.cfi_offset x16, _UC_REGS_X16
.cfi_offset x17, _UC_REGS_X17
.cfi_offset x18, _UC_REGS_X18
.cfi_offset x19, _UC_REGS_X19
.cfi_offset x20, _UC_REGS_X20
.cfi_offset x21, _UC_REGS_X21
.cfi_offset x22, _UC_REGS_X22
.cfi_offset x23, _UC_REGS_X23
.cfi_offset x24, _UC_REGS_X24
.cfi_offset x25, _UC_REGS_X25
.cfi_offset x26, _UC_REGS_X26
.cfi_offset x27, _UC_REGS_X27
.cfi_offset x28, _UC_REGS_X28
.cfi_offset x29, _UC_REGS_X29
.cfi_offset x30, _UC_REGS_X30
/* The unwinder will use the CFA to restore X31 (SP). */
nop
ENTRY_NP(__sigtramp_siginfo_2)
mov x0, x28 /* set the arg */
SYSTRAP(setcontext) /* and call setcontext */

/* If that failed, exit with the error code. */
SYSTRAP(exit)
.cfi_endproc
END(__sigtramp_siginfo_2)

0 comments on commit e5e90f1

Please sign in to comment.