brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · 13bb473 Raw
136 lines · plain
1// This is assembly code that needs to be run2// through the preprocessor, for simplicity of3// preprocessing it's named .c to start with.4//5// clang-format off6 7 8#define DW_CFA_register 0x99#define ehframe_x0  010#define ehframe_x20  2011#define ehframe_x22  2212#define ehframe_x23  2313#define ehframe_pc 3214 15#if defined(__APPLE__)16#define TO_BE_INTERRUPTED _to_be_interrupted17#define TRAP _trap18#define BREAK_TO_DEBUGGER _break_to_debugger19#else20#define TO_BE_INTERRUPTED to_be_interrupted21#define TRAP trap22#define BREAK_TO_DEBUGGER break_to_debugger23#endif24 25  .text26//--------------------------------------27// to_be_interrupted() a frameless function that does a non-ABI28// function call to trap(), simulating an async signal/interrup/exception/fault.29// Before it branches to trap(), put the return address in x23.30// trap() knows to branch back to $x23 when it has finished.31//--------------------------------------32  .globl  TO_BE_INTERRUPTED33#if defined(__APPLE__)34  .p2align 235#endif36TO_BE_INTERRUPTED:37  .cfi_startproc38 39  // This is a garbage entry to ensure that eh_frame is emitted.40  // If there's no eh_frame, lldb can use the assembly emulation scan,41  // which always includes a rule for $lr, and we won't replicate the42  // bug we're testing for.43  .cfi_escape DW_CFA_register, ehframe_x22, ehframe_x2344  mov x24, x045  add x24, x24, #146 47#if defined(__APPLE__)48  adrp x23, L_.return@PAGE        // put return address in x2349  add x23, x23, L_.return@PAGEOFF50#else51  adrp x23, .L.return52  add  x23, x23, :lo12:.L.return53#endif54 55  b TRAP                     // branch to trap handler, fake async interrupt56 57#if defined(__APPLE__)58L_.return:59#else60.L.return:61#endif62  mov x0, x2463  ret64  .cfi_endproc65  66 67 68//--------------------------------------69// trap() trap handler function, sets up stack frame70// with special unwind rule for the pc value of the71// "interrupted" stack frame (it's in x23), then calls72// break_to_debugger().73//--------------------------------------74  .globl  TRAP75#if defined(__APPLE__)76  .p2align 277#endif78TRAP:79  .cfi_startproc80  .cfi_signal_frame81 82  // The pc value when we were interrupted is in x2383  .cfi_escape DW_CFA_register, ehframe_pc, ehframe_x2384 85  // For fun, mark x0 as unmodified so the caller can86  // retrieve the value if it wants.87  .cfi_same_value ehframe_x088 89  // Mark x20 as undefined.  This is a callee-preserved90  // (non-volatile) register by the SysV AArch64 ABI, but91  // it'll be fun to see lldb not passing a value past this92  // point on the stack.93  .cfi_undefined ehframe_x2094 95  // standard prologue save of fp & lr so we can call 96  // break_to_debugger()97  sub sp, sp, #3298  stp x29, x30, [sp, #16]99  add x29, sp, #16100  .cfi_def_cfa w29, 16101  .cfi_offset w30, -8102  .cfi_offset w29, -16103 104  bl BREAK_TO_DEBUGGER105 106  ldp x29, x30, [sp, #16]107  .cfi_same_value x29108  .cfi_same_value x30109  .cfi_def_cfa sp, 32110  add sp, sp, #32111  .cfi_same_value sp112  .cfi_def_cfa sp, 0113 114  // jump back to $x23 to resume execution of to_be_interrupted115  br x23116  .cfi_endproc117 118//--------------------------------------119// break_to_debugger() executes a BRK instruction120//--------------------------------------121  .globl BREAK_TO_DEBUGGER122#if defined(__APPLE__)123  .p2align 2124#endif125BREAK_TO_DEBUGGER:126  .cfi_startproc127 128  // For fun, mark x0 as unmodified so the caller can129  // retrieve the value if it wants.130  .cfi_same_value ehframe_x0131 132  brk #0xf000   // __builtin_debugtrap aarch64 instruction133 134  ret135  .cfi_endproc136