1ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux/* libunwind - a platform-independent unwind library 2ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux Copyright (C) 2008 CodeSourcery 3ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux Copyright (C) 2011-2013 Linaro Limited 4ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com> 5ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 6ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxThis file is part of libunwind. 7ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 8ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxPermission is hereby granted, free of charge, to any person obtaining 9ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Rouxa copy of this software and associated documentation files (the 10ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux"Software"), to deal in the Software without restriction, including 11ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Rouxwithout limitation the rights to use, copy, modify, merge, publish, 12ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Rouxdistribute, sublicense, and/or sell copies of the Software, and to 13ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Rouxpermit persons to whom the Software is furnished to do so, subject to 14ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Rouxthe following conditions: 15ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 16ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxThe above copyright notice and this permission notice shall be 17ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Rouxincluded in all copies or substantial portions of the Software. 18ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 19ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 23ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 26ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 27ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux#include "unwind_i.h" 28ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux#include "offsets.h" 29ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 30ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux#ifndef UNW_REMOTE_ONLY 31ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 32ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxHIDDEN inline int 33ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Rouxaarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) 34ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux{ 35ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux#ifdef __linux__ 36ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux struct cursor *c = (struct cursor *) cursor; 37ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux unw_tdep_context_t *uc = c->dwarf.as_arg; 38ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 39ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux if (c->sigcontext_format == AARCH64_SCF_NONE) 40ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux { 41ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux /* Since there are no signals involved here we restore the non scratch 42ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux registers only. */ 43ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux unsigned long regs[11]; 44ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux regs[0] = uc->uc_mcontext.regs[19]; 45ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux regs[1] = uc->uc_mcontext.regs[20]; 46ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux regs[2] = uc->uc_mcontext.regs[21]; 47ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux regs[3] = uc->uc_mcontext.regs[22]; 48ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux regs[4] = uc->uc_mcontext.regs[23]; 49ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux regs[5] = uc->uc_mcontext.regs[24]; 50ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux regs[6] = uc->uc_mcontext.regs[25]; 51ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux regs[7] = uc->uc_mcontext.regs[26]; 52ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux regs[8] = uc->uc_mcontext.regs[27]; 53ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux regs[9] = uc->uc_mcontext.regs[28]; 54ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux regs[10] = uc->uc_mcontext.regs[30]; /* LR */ 55ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux unsigned long sp = uc->uc_mcontext.sp; 56ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 57ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux struct regs_overlay { 58ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux char x[sizeof(regs)]; 59ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux }; 60ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 61ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux asm volatile ( 62ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "ldp x19, x20, [%0]\n" 63ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "ldp x21, x22, [%0,16]\n" 64ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "ldp x23, x24, [%0,32]\n" 65ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "ldp x25, x26, [%0,48]\n" 66ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "ldp x27, x28, [%0,64]\n" 67ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "ldr x30, [%0,80]\n" 68ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "mov sp, %1\n" 69ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "ret \n" 70ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux : 71ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux : "r" (regs), 72ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "r" (sp), 73ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "m" (*(struct regs_overlay *)regs) 74ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux ); 75ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux } 76ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux else 77ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux { 78ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; 79ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 80ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux if (c->dwarf.eh_valid_mask & 0x1) sc->regs[0] = c->dwarf.eh_args[0]; 81ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux if (c->dwarf.eh_valid_mask & 0x2) sc->regs[1] = c->dwarf.eh_args[1]; 82ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux if (c->dwarf.eh_valid_mask & 0x4) sc->regs[2] = c->dwarf.eh_args[2]; 83ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux if (c->dwarf.eh_valid_mask & 0x8) sc->regs[3] = c->dwarf.eh_args[3]; 84ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 85ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[4] = uc->uc_mcontext.regs[4]; 86ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[5] = uc->uc_mcontext.regs[5]; 87ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[6] = uc->uc_mcontext.regs[6]; 88ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[7] = uc->uc_mcontext.regs[7]; 89ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[8] = uc->uc_mcontext.regs[8]; 90ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[9] = uc->uc_mcontext.regs[9]; 91ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[10] = uc->uc_mcontext.regs[10]; 92ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[11] = uc->uc_mcontext.regs[11]; 93ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[12] = uc->uc_mcontext.regs[12]; 94ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[13] = uc->uc_mcontext.regs[13]; 95ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[14] = uc->uc_mcontext.regs[14]; 96ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[15] = uc->uc_mcontext.regs[15]; 97ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[16] = uc->uc_mcontext.regs[16]; 98ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[17] = uc->uc_mcontext.regs[17]; 99ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[18] = uc->uc_mcontext.regs[18]; 100ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[19] = uc->uc_mcontext.regs[19]; 101ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[20] = uc->uc_mcontext.regs[20]; 102ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[21] = uc->uc_mcontext.regs[21]; 103ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[22] = uc->uc_mcontext.regs[22]; 104ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[23] = uc->uc_mcontext.regs[23]; 105ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[24] = uc->uc_mcontext.regs[24]; 106ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[25] = uc->uc_mcontext.regs[25]; 107ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[26] = uc->uc_mcontext.regs[26]; 108ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[27] = uc->uc_mcontext.regs[27]; 109ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[28] = uc->uc_mcontext.regs[28]; 110ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[29] = uc->uc_mcontext.regs[29]; 111ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->regs[30] = uc->uc_mcontext.regs[30]; 112ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->sp = uc->uc_mcontext.sp; 113ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->pc = uc->uc_mcontext.pc; 114ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux sc->pstate = uc->uc_mcontext.pstate; 115ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 116ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux asm volatile ( 117ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "mov sp, %0\n" 118ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux "ret %1\n" 119ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) 120ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux ); 121ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux } 122ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux unreachable(); 123ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux#else 124ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux printf ("%s: implement me\n", __FUNCTION__); 125ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux#endif 126ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux return -UNW_EINVAL; 127ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux} 128ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 129ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux#endif /* !UNW_REMOTE_ONLY */ 130ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 131ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Rouxstatic inline void 132ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Rouxestablish_machine_state (struct cursor *c) 133ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux{ 134ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux unw_addr_space_t as = c->dwarf.as; 135ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux void *arg = c->dwarf.as_arg; 136ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux unw_fpreg_t fpval; 137ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux unw_word_t val; 138ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux int reg; 139ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 140ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux Debug (8, "copying out cursor state\n"); 141ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 142ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux for (reg = 0; reg <= UNW_AARCH64_PSTATE; ++reg) 143ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux { 144ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux Debug (16, "copying %s %d\n", unw_regname (reg), reg); 145ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux if (unw_is_fpreg (reg)) 146ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux { 147ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) 148ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux as->acc.access_fpreg (as, reg, &fpval, 1, arg); 149ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux } 150ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux else 151ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux { 152ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux if (tdep_access_reg (c, reg, &val, 0) >= 0) 153ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux as->acc.access_reg (as, reg, &val, 1, arg); 154ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux } 155ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux } 156ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux} 157ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 158ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan RouxPROTECTED int 159ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Rouxunw_resume (unw_cursor_t *cursor) 160ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux{ 161ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux struct cursor *c = (struct cursor *) cursor; 162ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 163ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux Debug (1, "(cursor=%p)\n", c); 164ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 165ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux if (!c->dwarf.ip) 166ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux { 167ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux /* This can happen easily when the frame-chain gets truncated 168ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux due to bad or missing unwind-info. */ 169ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux Debug (1, "refusing to resume execution at address 0\n"); 170ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux return -UNW_EINVAL; 171ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux } 172ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 173ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux establish_machine_state (c); 174ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux 175ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, 176ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux c->dwarf.as_arg); 177ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux} 178