1d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm/* libunwind - a platform-independent unwind library
2d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm   Copyright (C) 2003-2004 Hewlett-Packard Co
3d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
5d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmThis file is part of libunwind.
6d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
7d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmPermission is hereby granted, free of charge, to any person obtaining
8d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidma copy of this software and associated documentation files (the
9d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm"Software"), to deal in the Software without restriction, including
10d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmwithout limitation the rights to use, copy, modify, merge, publish,
11d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to
12d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmpermit persons to whom the Software is furnished to do so, subject to
13d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmthe following conditions:
14d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
15d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmThe above copyright notice and this permission notice shall be
16d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmincluded in all copies or substantial portions of the Software.
17d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
18d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
25d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
26d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm#include "unwind-internal.h"
27d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
282319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris/* ANDROID support update. */
29d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidmPROTECTED _Unwind_Reason_Code
30d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm_Unwind_RaiseException (struct _Unwind_Exception *exception_object)
31d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm{
32752076789fdeec16827ddd846485182d4c3cd11fStefan Demharter  uint64_t exception_class = exception_object->exception_class;
33d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  _Unwind_Personality_Fn personality;
34d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  struct _Unwind_Context context;
35d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  _Unwind_Reason_Code reason;
36d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  unw_proc_info_t pi;
37d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  unw_context_t uc;
38d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  unw_word_t ip;
39d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  int ret;
402319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris  int destroy_map = 1;
41d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
42d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  Debug (1, "(exception_object=%p)\n", exception_object);
43d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
442319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris  unw_map_local_create ();
452319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris
46d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  if (_Unwind_InitContext (&context, &uc) < 0)
472319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris    {
482319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris      ret = _URC_FATAL_PHASE1_ERROR;
492319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris      goto done;
502319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris    }
51d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
52d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  /* Phase 1 (search phase) */
53d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
54d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  while (1)
55d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm    {
562319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris      if (unw_step (&context.cursor) <= 0)
57d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm	{
582319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris	  Debug (1, "no handler found\n");
592319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris	  ret = _URC_END_OF_STACK;
602319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris	  goto done;
61d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm	}
62d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
63d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm      if (unw_get_proc_info (&context.cursor, &pi) < 0)
642319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris        {
652319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris	  ret = _URC_FATAL_PHASE1_ERROR;
662319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris	  goto done;
672319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris        }
68d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
693842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz      personality = (_Unwind_Personality_Fn) (uintptr_t) pi.handler;
70d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm      if (personality)
71d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm	{
72d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm	  reason = (*personality) (_U_VERSION, _UA_SEARCH_PHASE,
73d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm				   exception_class, exception_object,
74d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm				   &context);
75d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm	  if (reason != _URC_CONTINUE_UNWIND)
76d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm	    {
77d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm	      if (reason == _URC_HANDLER_FOUND)
78d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm		break;
79d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm	      else
80d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm		{
81d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm		  Debug (1, "personality returned %d\n", reason);
822319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris		  ret = _URC_FATAL_PHASE1_ERROR;
832319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris		  goto done;
84d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm		}
85d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm	    }
86d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm	}
87d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm    }
88d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
89d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  /* Exceptions are associated with IP-ranges.  If a given exception
90d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm     is handled at a particular IP, it will _always_ be handled at
91d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm     that IP.  If this weren't true, we'd have to track the tuple
92d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm     (IP,SP,BSP) to uniquely identify the stack frame that's handling
93d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm     the exception.  */
94d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm  if (unw_get_reg (&context.cursor, UNW_REG_IP, &ip) < 0)
952319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris    ret = _URC_FATAL_PHASE1_ERROR;
962319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris  else
972319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris    {
982319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris      exception_object->private_1 = 0;	/* clear "stop" pointer */
992319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris      exception_object->private_2 = ip;	/* save frame marker */
100d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
1012319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris      Debug (1, "found handler for IP=%lx; entering cleanup phase\n", (long) ip);
1022319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris
1032319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris      /* Reset the cursor to the first frame: */
1042319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris      if (unw_init_local (&context.cursor, &uc) < 0)
1052319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris        ret = _URC_FATAL_PHASE1_ERROR;
1062319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris      else
1072319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris        ret = _Unwind_Phase2 (exception_object, &context, &destroy_map);
1082319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris    }
109d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
1102319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferrisdone:
1112319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris  if (destroy_map)
1122319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris    unw_map_local_destroy ();
113d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm
1142319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris  return ret;
115d3ff45603da7c23199e905088ced02cf5ebe0aa5hp.com!davidm}
1162319e0f1aec9e1f716eff88987b0023c5b2f6c07Christopher Ferris/* End ANDROID support. */
11766100609bb7fb01811e64318bec3018d0bc9abd5homeip.net!davidm
11866100609bb7fb01811e64318bec3018d0bc9abd5homeip.net!davidm_Unwind_Reason_Code
11966100609bb7fb01811e64318bec3018d0bc9abd5homeip.net!davidm__libunwind_Unwind_RaiseException (struct _Unwind_Exception *)
12066100609bb7fb01811e64318bec3018d0bc9abd5homeip.net!davidm     ALIAS (_Unwind_RaiseException);
121