Skip to content

Commit 1d90aa4

Browse files
committed
Add unwind rules for x0 (volatile) and x20 (non-voltile)
to trap() and break_to_debugger() for fun, and add unwind instructions for the epilogue of trap(). When stopped in `break_to_debugger`, ``` * frame #0: 0x00000001000003e8 a.out`break_to_debugger + 4 frame swiftlang#1: 0x00000001000003d8 a.out`trap + 16 frame swiftlang#2: 0x00000001000003c0 a.out`to_be_interrupted + 20 frame swiftlang#3: 0x0000000100000398 a.out`main + 32 ``` Normally we can't provide a volatile register (e.g. x0) up the stack. And we can provide a non-volatile register (e.g. x20) up the stack. I added an IsSame rule for trap() and break_to_debugger() for x0, so it CAN be passed up the stack. And I added an Undefined rule for x20 to trap() so it CAN'T be provided up the stack. If a user selects `to_be_interrupted` and does `register read`, they'll get x0 and they won't get x20. From `main`, they will not get x0 or x20 (x0 because `to_be_interrupted` doesn't have an IsSame rule).
1 parent d8843fe commit 1d90aa4

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

lldb/test/API/macosx/unwind-frameless-faulted/interrupt-and-trap-funcs.s

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#define DW_CFA_register 0x9
2+
#define ehframe_x0 0
3+
#define ehframe_x20 20
24
#define ehframe_x22 22
35
#define ehframe_x23 23
46
#define ehframe_pc 32
@@ -7,9 +9,9 @@
79

810
//--------------------------------------
911
// to_be_interrupted() a frameless function that does a non-ABI
10-
// function call ("is interrupted/traps" simulated) to trap().
11-
// Before it branches to trap(), it puts its return address in
12-
// x23. trap() knows to branch back to $x23 when it has finished.
12+
// function call to trap(), simulating an async signal/interrup/exception/fault.
13+
// Before it branches to trap(), put the return address in x23.
14+
// trap() knows to branch back to $x23 when it has finished.
1315
//--------------------------------------
1416
.globl _to_be_interrupted
1517
.p2align 2
@@ -51,6 +53,15 @@ _trap:
5153
// The pc value when we were interrupted is in x23
5254
.cfi_escape DW_CFA_register, ehframe_pc, ehframe_x23
5355

56+
// For fun, mark x0 as unmodified so the caller can
57+
// retrieve the value if it wants.
58+
.cfi_same_value ehframe_x0
59+
60+
// Mark x20 as undefined. This is a callee-preserved
61+
// (non-volatile) register by the SysV AArch64 ABI, but
62+
// it's be fun to see lldb not passing a value past this.
63+
.cfi_undefined ehframe_x20
64+
5465
// standard prologue save of fp & lr so we can call
5566
// break_to_debugger()
5667
sub sp, sp, #32
@@ -63,7 +74,11 @@ _trap:
6374
bl _break_to_debugger
6475

6576
ldp x29, x30, [sp, #16]
77+
.cfi_same_value x29
78+
.cfi_same_value x30
79+
.cfi_def_cfa sp, 32
6680
add sp, sp, #32
81+
.cfi_same_value sp
6782

6883
// jump back to $x23 to resume execution of to_be_interrupted
6984
br x23
@@ -77,6 +92,10 @@ _trap:
7792
_break_to_debugger:
7893
.cfi_startproc
7994

95+
// For fun, mark x0 as unmodified so the caller can
96+
// retrieve the value if it wants.
97+
.cfi_same_value ehframe_x0
98+
8099
brk #0xf000 ;; __builtin_debugtrap aarch64 instruction
81100

82101
ret

0 commit comments

Comments
 (0)