1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <private/bionic_asm.h> 30#include <private/bionic_asm_dwarf_exprs.h> 31 32// In the signal trampoline frame, rsp points to a ucontext_t struct. 33 34// Offsets into struct ucontext_t of uc_mcontext.gregs[x]. 35#define OFFSET_R8 40 36#define OFFSET_R9 48 37#define OFFSET_R10 56 38#define OFFSET_R11 64 39#define OFFSET_R12 72 40#define OFFSET_R13 80 41#define OFFSET_R14 88 42#define OFFSET_R15 96 43#define OFFSET_RDI 104 44#define OFFSET_RSI 112 45#define OFFSET_RBP 120 46#define OFFSET_RBX 128 47#define OFFSET_RDX 136 48#define OFFSET_RAX 144 49#define OFFSET_RCX 152 50#define OFFSET_RSP 160 51#define OFFSET_RIP 168 52 53// Non-standard DWARF constants for the x86-64 registers. 54#define DW_x86_64_RAX 0 55#define DW_x86_64_RDX 1 56#define DW_x86_64_RCX 2 57#define DW_x86_64_RBX 3 58#define DW_x86_64_RSI 4 59#define DW_x86_64_RDI 5 60#define DW_x86_64_RBP 6 61#define DW_x86_64_RSP 7 62#define DW_x86_64_R8 8 63#define DW_x86_64_R9 9 64#define DW_x86_64_R10 10 65#define DW_x86_64_R11 11 66#define DW_x86_64_R12 12 67#define DW_x86_64_R13 13 68#define DW_x86_64_R14 14 69#define DW_x86_64_R15 15 70#define DW_x86_64_RIP 16 71 72// Insert a nop between .cfi_startproc and the trampoline symbol so that unwinders can find the FDE. 73// A function's last instruction can be a call instruction (e.g. to __cxa_throw), in which case the 74// return address (e.g. from __cxa_throw to the caller) will be just after the function. This 75// address may also be the start of the next function, so to avoid ambiguity, unwinders assume that 76// a return address PC can refer to the address just after a function, but never to the start of a 77// function. (This is implemented by subtracting 1 from the return address PC before looking it up.) 78// This is fine for ordinary functions, but breaks on trampolines. Inserting a nop fixes it. 79// 80// N.B. Unwinders have two other strategies for recognizing the signal trampoline: 81// - Read the instructions that the return address PC points at and look for a sigreturn syscall. 82// (Hence, the instructions must not change at all.) 83// - Do a symbol table lookup and check that against the PC (e.g. LLDB looks for 84// __kernel_rt_sigreturn and __restore_rt.) 85// Either way, the nop is needed to avoid ambiguity if the function before the trampoline could end 86// with a call. 87 88#define RESTORE_GPR(reg) m_cfi_breg_offset DW_x86_64_ ## reg, DW_x86_64_RSP, OFFSET_ ## reg; 89 90 .text 91 .cfi_startproc 92 .cfi_signal_frame 93 m_cfi_def_cfa_deref DW_x86_64_RSP, OFFSET_RSP 94 RESTORE_GPR(R8) 95 RESTORE_GPR(R9) 96 RESTORE_GPR(R10) 97 RESTORE_GPR(R11) 98 RESTORE_GPR(R12) 99 RESTORE_GPR(R13) 100 RESTORE_GPR(R14) 101 RESTORE_GPR(R15) 102 RESTORE_GPR(RDI) 103 RESTORE_GPR(RSI) 104 RESTORE_GPR(RBP) 105 RESTORE_GPR(RBX) 106 RESTORE_GPR(RDX) 107 RESTORE_GPR(RAX) 108 RESTORE_GPR(RCX) 109 // Restoring RSP is unnecessary as the unwinder simply uses the CFA value. 110 RESTORE_GPR(RIP) 111 nop 112ENTRY_NO_DWARF_PRIVATE(__restore_rt) 113 mov $__NR_rt_sigreturn, %rax 114 syscall 115END(__restore_rt) 116