13842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz/* libunwind - a platform-independent unwind library 23842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz Copyright (C) 2008 CodeSourcery 31e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner Copyright 2011 Linaro Limited 414fc15928b31c18c06f6c075ba0394c0000d3981Tommi Rantala Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com> 53842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 63842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzThis file is part of libunwind. 73842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 83842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzPermission is hereby granted, free of charge, to any person obtaining 93842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitza copy of this software and associated documentation files (the 103842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz"Software"), to deal in the Software without restriction, including 113842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzwithout limitation the rights to use, copy, modify, merge, publish, 123842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdistribute, sublicense, and/or sell copies of the Software, and to 133842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzpermit persons to whom the Software is furnished to do so, subject to 143842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzthe following conditions: 153842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 163842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzThe above copyright notice and this permission notice shall be 173842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzincluded in all copies or substantial portions of the Software. 183842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 193842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 203842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 213842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 223842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 233842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 243842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 253842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 263842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 271c82a52129ceced9f271dd782057351275c38a41Christopher Ferris#if defined(__ANDROID__) 281c82a52129ceced9f271dd782057351275c38a41Christopher Ferris#include <asm/sigcontext.h> 291c82a52129ceced9f271dd782057351275c38a41Christopher Ferris#endif 301c82a52129ceced9f271dd782057351275c38a41Christopher Ferris 313842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#include "unwind_i.h" 3236511d3d1f040bbf778094e907725ad0617326c8Ken Werner#include "offsets.h" 333842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 343842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#ifndef UNW_REMOTE_ONLY 353842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 363842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzHIDDEN inline int 373842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzarm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) 383842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{ 391e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner#ifdef __linux__ 401e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner struct cursor *c = (struct cursor *) cursor; 410eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner unw_tdep_context_t *uc = c->dwarf.as_arg; 421e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner 4336511d3d1f040bbf778094e907725ad0617326c8Ken Werner if (c->sigcontext_format == ARM_SCF_NONE) 4436511d3d1f040bbf778094e907725ad0617326c8Ken Werner { 4536511d3d1f040bbf778094e907725ad0617326c8Ken Werner /* Since there are no signals involved here we restore the non scratch 4636511d3d1f040bbf778094e907725ad0617326c8Ken Werner registers only. */ 4736511d3d1f040bbf778094e907725ad0617326c8Ken Werner unsigned long regs[10]; 480eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner regs[0] = uc->regs[4]; 490eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner regs[1] = uc->regs[5]; 500eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner regs[2] = uc->regs[6]; 510eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner regs[3] = uc->regs[7]; 520eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner regs[4] = uc->regs[8]; 530eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner regs[5] = uc->regs[9]; 540eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner regs[6] = uc->regs[10]; 550eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner regs[7] = uc->regs[11]; /* FP */ 560eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner regs[8] = uc->regs[13]; /* SP */ 570eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner regs[9] = uc->regs[14]; /* LR */ 581e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner 5914fc15928b31c18c06f6c075ba0394c0000d3981Tommi Rantala struct regs_overlay { 6014fc15928b31c18c06f6c075ba0394c0000d3981Tommi Rantala char x[sizeof(regs)]; 6114fc15928b31c18c06f6c075ba0394c0000d3981Tommi Rantala }; 6214fc15928b31c18c06f6c075ba0394c0000d3981Tommi Rantala 6336511d3d1f040bbf778094e907725ad0617326c8Ken Werner asm __volatile__ ( 6436511d3d1f040bbf778094e907725ad0617326c8Ken Werner "ldmia %0, {r4-r12, lr}\n" 6536511d3d1f040bbf778094e907725ad0617326c8Ken Werner "mov sp, r12\n" 6636511d3d1f040bbf778094e907725ad0617326c8Ken Werner "bx lr\n" 6714fc15928b31c18c06f6c075ba0394c0000d3981Tommi Rantala : : "r" (regs), 6814fc15928b31c18c06f6c075ba0394c0000d3981Tommi Rantala "m" (*(struct regs_overlay *)regs) 6936511d3d1f040bbf778094e907725ad0617326c8Ken Werner ); 7036511d3d1f040bbf778094e907725ad0617326c8Ken Werner } 7136511d3d1f040bbf778094e907725ad0617326c8Ken Werner else 7236511d3d1f040bbf778094e907725ad0617326c8Ken Werner { 7336511d3d1f040bbf778094e907725ad0617326c8Ken Werner /* In case a signal frame is involved, we're using its trampoline which 7436511d3d1f040bbf778094e907725ad0617326c8Ken Werner calls sigreturn. */ 7536511d3d1f040bbf778094e907725ad0617326c8Ken Werner struct sigcontext *sc = (struct sigcontext *) c->sigcontext_addr; 760eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_r0 = uc->regs[0]; 770eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_r1 = uc->regs[1]; 780eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_r2 = uc->regs[2]; 790eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_r3 = uc->regs[3]; 800eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_r4 = uc->regs[4]; 810eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_r5 = uc->regs[5]; 820eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_r6 = uc->regs[6]; 830eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_r7 = uc->regs[7]; 840eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_r8 = uc->regs[8]; 850eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_r9 = uc->regs[9]; 860eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_r10 = uc->regs[10]; 870eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_fp = uc->regs[11]; /* FP */ 880eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_ip = uc->regs[12]; /* IP */ 890eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_sp = uc->regs[13]; /* SP */ 900eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_lr = uc->regs[14]; /* LR */ 910eba2169fb19ef0707a2c96201e33769001b5f11Ken Werner sc->arm_pc = uc->regs[15]; /* PC */ 9236511d3d1f040bbf778094e907725ad0617326c8Ken Werner /* clear the ITSTATE bits. */ 9336511d3d1f040bbf778094e907725ad0617326c8Ken Werner sc->arm_cpsr &= 0xf9ff03ffUL; 9436511d3d1f040bbf778094e907725ad0617326c8Ken Werner 9536511d3d1f040bbf778094e907725ad0617326c8Ken Werner /* Set the SP and the PC in order to continue execution at the modified 9636511d3d1f040bbf778094e907725ad0617326c8Ken Werner trampoline which restores the signal mask and the registers. */ 9736511d3d1f040bbf778094e907725ad0617326c8Ken Werner asm __volatile__ ( 9836511d3d1f040bbf778094e907725ad0617326c8Ken Werner "mov sp, %0\n" 9936511d3d1f040bbf778094e907725ad0617326c8Ken Werner "bx %1\n" 100b28335b5a59ff5909d816ff539c1e5c246e40baaKen Werner : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) 10136511d3d1f040bbf778094e907725ad0617326c8Ken Werner ); 10236511d3d1f040bbf778094e907725ad0617326c8Ken Werner } 10310b064ffe902d5af31bb49bd8e4f03c545f8d462Ladislav Michl unreachable(); 1041e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner#else 1051e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner printf ("%s: implement me\n", __FUNCTION__); 1061e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner#endif 1073842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return -UNW_EINVAL; 1083842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz} 1093842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1103842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#endif /* !UNW_REMOTE_ONLY */ 1113842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1121e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Wernerstatic inline void 1131e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Wernerestablish_machine_state (struct cursor *c) 1141e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner{ 1151e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner unw_addr_space_t as = c->dwarf.as; 1161e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner void *arg = c->dwarf.as_arg; 1171e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner unw_fpreg_t fpval; 1181e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner unw_word_t val; 1191e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner int reg; 1201e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner 1211e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner Debug (8, "copying out cursor state\n"); 1221e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner 1231e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner for (reg = 0; reg <= UNW_REG_LAST; ++reg) 1241e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner { 1251e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner Debug (16, "copying %s %d\n", unw_regname (reg), reg); 1261e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner if (unw_is_fpreg (reg)) 1271e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner { 1281e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) 1291e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner as->acc.access_fpreg (as, reg, &fpval, 1, arg); 1301e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner } 1311e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner else 1321e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner { 1331e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner if (tdep_access_reg (c, reg, &val, 0) >= 0) 1341e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner as->acc.access_reg (as, reg, &val, 1, arg); 1351e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner } 1361e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner } 1371e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner} 1381e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner 1393842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzPROTECTED int 1403842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzunw_resume (unw_cursor_t *cursor) 1413842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{ 1421e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner struct cursor *c = (struct cursor *) cursor; 1431e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner 1441e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner Debug (1, "(cursor=%p)\n", c); 1451e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner 1461e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner if (!c->dwarf.ip) 1471e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner { 1481e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner /* This can happen easily when the frame-chain gets truncated 1491e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner due to bad or missing unwind-info. */ 1501e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner Debug (1, "refusing to resume execution at address 0\n"); 1511e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner return -UNW_EINVAL; 1521e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner } 1531e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner 1541e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner establish_machine_state (c); 1551e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner 1561e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, 1571e10c2931d970d0ae5426bba6ba9e1c2998c7451Ken Werner c->dwarf.as_arg); 1583842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz} 159