15a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm/* libunwind - a platform-independent unwind library
2bf832fc29e9e9141c1886d8d0d2123766a9aeb4cmostang.com!davidm   Copyright (C) 2001-2003, 2005 Hewlett-Packard Co
35a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
45a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
55a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmThis file is part of libunwind.
65a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
75a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmPermission is hereby granted, free of charge, to any person obtaining
85a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidma copy of this software and associated documentation files (the
95a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm"Software"), to deal in the Software without restriction, including
105a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmwithout limitation the rights to use, copy, modify, merge, publish,
115a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmdistribute, sublicense, and/or sell copies of the Software, and to
125a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmpermit persons to whom the Software is furnished to do so, subject to
135a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmthe following conditions:
145a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
155a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmThe above copyright notice and this permission notice shall be
165a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmincluded in all copies or substantial portions of the Software.
175a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
185a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
195a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
205a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
215a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
225a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
235a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
245a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
255a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
265a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm#include "init.h"
275a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm#include "unwind_i.h"
285a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
295a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm#ifdef UNW_REMOTE_ONLY
305a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
315a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmPROTECTED int
325a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmunw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
335a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm{
345a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm  return -UNW_EINVAL;
355a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm}
365a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
375a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm#else /* !UNW_REMOTE_ONLY */
385a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
3950bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidmstatic inline void
4050bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidmset_as_arg (struct cursor *c, unw_context_t *uc)
4150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm{
4250bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm#if defined(__linux) && defined(__KERNEL__)
4350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  c->task = current;
4450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  c->as_arg = &uc->sw;
4550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm#else
4650bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  c->as_arg = uc;
4750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm#endif
4850bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm}
4950bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
5050bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidmstatic inline int
5150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidmget_initial_stack_pointers (struct cursor *c, unw_context_t *uc,
5250bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm			    unw_word_t *sp, unw_word_t *bsp)
5350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm{
5450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm#if defined(__linux)
5550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  unw_word_t sol, bspstore;
5650bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
5750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm#ifdef __KERNEL__
5850bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  sol = (uc->sw.ar_pfs >> 7) & 0x7f;
5950bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  bspstore = uc->sw.ar_bspstore;
6050bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  *sp = uc->ksp;
6150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm# else
6250bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  sol = (uc->uc_mcontext.sc_ar_pfs >> 7) & 0x7f;
6350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  bspstore = uc->uc_mcontext.sc_ar_bsp;
6450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  *sp = uc->uc_mcontext.sc_gr[12];
6550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm# endif
6650bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  *bsp = rse_skip_regs (bspstore, -sol);
6750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm#elif defined(__hpux)
6850bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  int ret;
6950bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
7050bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  if ((ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_GR + 12), sp)) < 0
7150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm      || (ret = ia64_get (c, IA64_REG_LOC (c, UNW_IA64_AR_BSP), bsp)) < 0)
7250bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    return ret;
7350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm#else
7450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm# error Fix me.
7550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm#endif
7650bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  return 0;
7750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm}
7850bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
795a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmPROTECTED int
805a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidmunw_init_local (unw_cursor_t *cursor, unw_context_t *uc)
815a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm{
825a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm  struct cursor *c = (struct cursor *) cursor;
8350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  unw_word_t sp, bsp;
8450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  int ret;
855a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
865d0f376b08126b51a001d7cdfba1ec4e0d644f54Tommi Rantala  if (!tdep_init_done)
875a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm    tdep_init ();
885a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
89f576cce7480d6acee537cecfeb5530187e50f785hp.com!davidm  Debug (1, "(cursor=%p)\n", c);
905a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
9150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  c->as = unw_local_addr_space;
9250bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  set_as_arg (c, uc);
9350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
9450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  if ((ret = get_initial_stack_pointers (c, uc, &sp, &bsp)) < 0)
9550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    return ret;
9650bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
9750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  Debug (4, "initial bsp=%lx, sp=%lx\n", bsp, sp);
9850bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
9950bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  if ((ret = common_init (c, sp, bsp)) < 0)
10050bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm    return ret;
10150bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm
1025a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm#ifdef __hpux
10350bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  /* On HP-UX, the context created by getcontext() points to the
10450bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm     getcontext() system call stub.  Step over it: */
10550bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  ret = unw_step (cursor);
1065a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm#endif
10750bbc1fe3dcac021b201445e4e7a158a8d199604hp.com!davidm  return ret;
1085a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm}
1095a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm
1105a0713e6ab28e67ea9b4e9cfecd394a66038ad42homeip.net!davidm#endif /* !UNW_REMOTE_ONLY */
111