18d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala/* libunwind - a platform-independent unwind library
28d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala   Copyright (C) 2008 CodeSourcery
38d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala   Copyright 2011 Linaro Limited
48d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
58d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
68d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaThis file is part of libunwind.
78d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
88d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaPermission is hereby granted, free of charge, to any person obtaining
98d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantalaa copy of this software and associated documentation files (the
108d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala"Software"), to deal in the Software without restriction, including
118d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantalawithout limitation the rights to use, copy, modify, merge, publish,
128d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantaladistribute, sublicense, and/or sell copies of the Software, and to
138d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantalapermit persons to whom the Software is furnished to do so, subject to
148d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantalathe following conditions:
158d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
168d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaThe above copyright notice and this permission notice shall be
178d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantalaincluded in all copies or substantial portions of the Software.
188d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
198d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
208d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
218d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
228d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
238d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
248d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
258d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
268d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
278d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala#include "unwind_i.h"
288d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala#include "offsets.h"
298d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
308d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaPROTECTED int
318d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantalaunw_handle_signal_frame (unw_cursor_t *cursor)
328d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala{
338d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  struct cursor *c = (struct cursor *) cursor;
348d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  int ret;
358d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  unw_word_t sc_addr, sp, sp_addr = c->dwarf.cfa;
368d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  struct dwarf_loc sp_loc = DWARF_LOC (sp_addr, 0);
378d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
388d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  if ((ret = dwarf_get (&c->dwarf, sp_loc, &sp)) < 0)
398d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala    return -UNW_EUNSPEC;
408d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
418d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  ret = unw_is_signal_frame (cursor);
428d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  Debug(1, "unw_is_signal_frame()=%d\n", ret);
438d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
448d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  /* Save the SP and PC to be able to return execution at this point
458d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala     later in time (unw_resume).  */
468d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->sigcontext_sp = c->dwarf.cfa;
478d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->sigcontext_pc = c->dwarf.ip;
488d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
498d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  if (ret == 1)
508d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala    {
518d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala      /* Handle non-RT signal frame. */
528d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala      c->sigcontext_format = SH_SCF_LINUX_SIGFRAME;
538d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala      sc_addr = sp_addr;
548d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala    }
558d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  else if (ret == 2)
568d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala    {
578d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala      /* Handle RT signal frame. */
588d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala      c->sigcontext_format = SH_SCF_LINUX_RT_SIGFRAME;
598d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala      sc_addr = sp_addr + sizeof (siginfo_t) + LINUX_UC_MCONTEXT_OFF;
608d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala    }
618d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  else
628d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala    return -UNW_EUNSPEC;
638d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
648d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->sigcontext_addr = sc_addr;
658d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
668d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  /* Update the dwarf cursor.
678d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala     Set the location of the registers to the corresponding addresses of the
688d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala     uc_mcontext / sigcontext structure contents.  */
698d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R0]  = DWARF_LOC (sc_addr + LINUX_SC_R0_OFF, 0);
708d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R1]  = DWARF_LOC (sc_addr + LINUX_SC_R1_OFF, 0);
718d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R2]  = DWARF_LOC (sc_addr + LINUX_SC_R2_OFF, 0);
728d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R3]  = DWARF_LOC (sc_addr + LINUX_SC_R3_OFF, 0);
738d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R4]  = DWARF_LOC (sc_addr + LINUX_SC_R4_OFF, 0);
748d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R5]  = DWARF_LOC (sc_addr + LINUX_SC_R5_OFF, 0);
758d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R6]  = DWARF_LOC (sc_addr + LINUX_SC_R6_OFF, 0);
768d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R7]  = DWARF_LOC (sc_addr + LINUX_SC_R7_OFF, 0);
778d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R8]  = DWARF_LOC (sc_addr + LINUX_SC_R8_OFF, 0);
788d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R9]  = DWARF_LOC (sc_addr + LINUX_SC_R9_OFF, 0);
798d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R10] = DWARF_LOC (sc_addr + LINUX_SC_R10_OFF, 0);
808d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R11] = DWARF_LOC (sc_addr + LINUX_SC_R11_OFF, 0);
818d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R12] = DWARF_LOC (sc_addr + LINUX_SC_R12_OFF, 0);
828d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R13] = DWARF_LOC (sc_addr + LINUX_SC_R13_OFF, 0);
838d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R14] = DWARF_LOC (sc_addr + LINUX_SC_R14_OFF, 0);
848d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_R15] = DWARF_LOC (sc_addr + LINUX_SC_R15_OFF, 0);
858d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_PR]  = DWARF_LOC (sc_addr + LINUX_SC_PR_OFF, 0);
868d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.loc[UNW_SH_PC]  = DWARF_LOC (sc_addr + LINUX_SC_PC_OFF, 0);
878d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
888d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  /* Set SP/CFA and PC/IP.  */
898d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_R15], &c->dwarf.cfa);
908d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  dwarf_get (&c->dwarf, c->dwarf.loc[UNW_SH_PC], &c->dwarf.ip);
918d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
928d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  c->dwarf.pi_valid = 0;
938d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
948d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  return 1;
958d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala}
968d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
978d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi RantalaPROTECTED int
988d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantalaunw_step (unw_cursor_t *cursor)
998d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala{
1008d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  struct cursor *c = (struct cursor *) cursor;
1018d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  int ret;
1028d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
1038d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  Debug (1, "(cursor=%p)\n", c);
1048d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
1058d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  if (unw_is_signal_frame (cursor))
1068d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala    return unw_handle_signal_frame (cursor);
1078d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
1088d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  ret = dwarf_step (&c->dwarf);
1098d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
1108d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  if (unlikely (ret == -UNW_ESTOPUNWIND))
1118d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala    return ret;
1128d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
1138d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  if (unlikely (ret < 0))
1148d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala    return 0;
1158d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala
1168d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  return (c->dwarf.ip == 0) ? 0 : 1;
1178d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala}
118