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