Ginit.c revision cdf9ee587b78148c5d48dae1b5ea72ec8df64c96
170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* libunwind - a platform-independent unwind library
270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   Copyright (C) 2008 CodeSourcery
370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
470a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineThis file is part of libunwind.
570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
670a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkinePermission is hereby granted, free of charge, to any person obtaining
770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinea copy of this software and associated documentation files (the
870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine"Software"), to deal in the Software without restriction, including
970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinewithout limitation the rights to use, copy, modify, merge, publish,
1070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinedistribute, sublicense, and/or sell copies of the Software, and to
1170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinepermit persons to whom the Software is furnished to do so, subject to
1270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinethe following conditions:
1370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
1470a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineThe above copyright notice and this permission notice shall be
1570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineincluded in all copies or substantial portions of the Software.
1670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
1770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
2170a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
2270a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2370a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
2470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
2570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include <stdlib.h>
2670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include <string.h>
2770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
2870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "unwind_i.h"
2970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
3070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef UNW_REMOTE_ONLY
3170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
3270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* unw_local_addr_space is a NULL pointer in this case.  */
3370a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkinePROTECTED unw_addr_space_t unw_local_addr_space;
3470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
3570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#else /* !UNW_REMOTE_ONLY */
3670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
3770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestatic struct unw_addr_space local_addr_space;
3870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
3970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkinePROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space;
4070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
4170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Return the address of the 64-bit slot in UC for REG (even for o32,
4270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   where registers are 32-bit, the slots are still 64-bit).  */
4370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
4470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestatic inline void *
4570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineuc_addr (ucontext_t *uc, int reg)
4670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
4770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (reg >= UNW_MIPS_R0 && reg < UNW_MIPS_R0 + 32)
4870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#if defined(__ANDROID__)
4970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return &uc->uc_mcontext.sc_regs[reg - UNW_MIPS_R0];
5070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#else
5170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return &uc->uc_mcontext.gregs[reg - UNW_MIPS_R0];
5270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
5370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  else if (reg == UNW_MIPS_PC)
5470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#if defined(__ANDROID__)
5570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return &uc->uc_mcontext.sc_pc;
5670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#else
5770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return &uc->uc_mcontext.pc;
5870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
5970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  else
6070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return NULL;
6170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
6270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
6370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine# ifdef UNW_LOCAL_ONLY
6470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
6570a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineHIDDEN void *
6670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetdep_uc_addr (ucontext_t *uc, int reg)
6770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
6870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  char *addr = uc_addr (uc, reg);
6970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
7070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (reg >= UNW_MIPS_R0 && reg <= UNW_MIPS_R31
7170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      && tdep_big_endian (unw_local_addr_space)
7270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      && unw_local_addr_space->abi == UNW_MIPS_ABI_O32)
7370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    addr += 4;
7470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
7570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return addr;
7670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
7770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
7870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine# endif /* UNW_LOCAL_ONLY */
7970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
8070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineHIDDEN unw_dyn_info_list_t _U_dyn_info_list;
8170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
8270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* XXX fix me: there is currently no way to locate the dyn-info list
8370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine       by a remote unwinder.  On ia64, this is done via a special
8470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine       unwind-table entry.  Perhaps something similar can be done with
8570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine       DWARF2 unwind info.  */
8670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
8770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestatic void
8870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineput_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
8970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
9070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* it's a no-op */
9170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
9270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
9370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestatic int
9470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
9570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine			void *arg)
9670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
9770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list;
9870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return 0;
9970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
10070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
10170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestatic int
10270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineaccess_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write,
10370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	    void *arg)
10470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
10570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (write)
10670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    {
10770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* ANDROID support update. */
10870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef UNW_LOCAL_ONLY
10970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (maps_is_writable(as->map_list, addr))
11070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine        {
11170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
11270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine          Debug (16, "mem[%llx] <- %llx\n", (long long) addr, (long long) *val);
11370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine          *(unw_word_t *) addr = *val;
11470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef UNW_LOCAL_ONLY
11570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine        }
11670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      else
11770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine        {
11870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine          Debug (16, "Unwritable memory mem[%llx] <- %llx\n", (long long) addr,
11970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine                 (long long) *val);
12070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine          return -1;
12170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine        }
12270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
12370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* End of ANDROID update. */
12470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
12570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  else
12670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    {
12770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* ANDROID support update. */
12870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef UNW_LOCAL_ONLY
12970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (maps_is_readable(as->map_list, addr))
13070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine        {
13170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
13270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine          *val = *(unw_word_t *) addr;
13370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine          Debug (16, "mem[%llx] -> %llx\n", (long long) addr, (long long) *val);
13470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef UNW_LOCAL_ONLY
13570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine        }
13670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      else
13770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine        {
13870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine          Debug (16, "Unreadable memory mem[%llx] -> XXX\n", (long long) addr);
13970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine          return -1;
14070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine        }
14170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
14270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* End of ANDROID update. */
14370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
14470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return 0;
14570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
14670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
14770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestatic int
14870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineaccess_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write,
14970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	    void *arg)
15070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
15170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  unw_word_t *addr;
15270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ucontext_t *uc = arg;
15370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
15470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (unw_is_fpreg (reg))
15570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    goto badreg;
15670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
15770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  Debug (16, "reg = %s\n", unw_regname (reg));
15870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (!(addr = uc_addr (uc, reg)))
15970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    goto badreg;
16070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
16170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (write)
16270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    {
16370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      *(unw_word_t *) (intptr_t) addr = (mips_reg_t) *val;
16470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      Debug (12, "%s <- %llx\n", unw_regname (reg), (long long) *val);
16570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
16670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  else
16770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    {
16870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      *val = (mips_reg_t) *(unw_word_t *) (intptr_t) addr;
16970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      Debug (12, "%s -> %llx\n", unw_regname (reg), (long long) *val);
17070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
17170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return 0;
17270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
17370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine badreg:
17470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  Debug (1, "bad register number %u\n", reg);
17570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return -UNW_EBADREG;
17670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
17770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
17870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestatic int
17970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineaccess_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
18070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	      int write, void *arg)
18170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
18270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ucontext_t *uc = arg;
18370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  unw_fpreg_t *addr;
18470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
18570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (!unw_is_fpreg (reg))
18670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    goto badreg;
18770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
18870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (!(addr = uc_addr (uc, reg)))
18970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    goto badreg;
19070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
19170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (write)
19270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    {
19370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg),
19470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
19570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      *(unw_fpreg_t *) (intptr_t) addr = *val;
19670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
19770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  else
19870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    {
19970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      *val = *(unw_fpreg_t *) (intptr_t) addr;
20070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg),
20170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
20270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
203  return 0;
204
205 badreg:
206  Debug (1, "bad register number %u\n", reg);
207  /* attempt to access a non-preserved register */
208  return -UNW_EBADREG;
209}
210
211static int
212get_static_proc_name (unw_addr_space_t as, unw_word_t ip,
213		      char *buf, size_t buf_len, unw_word_t *offp,
214		      void *arg)
215{
216
217  return elf_w (get_proc_name) (as, getpid (), ip, buf, buf_len, offp);
218}
219
220/* ANDROID support update. */
221static define_lock (_U_map_init_lock);
222static struct map_info *_U_map_list = NULL;
223/* End of ANDROID update. */
224
225HIDDEN void
226mips_local_addr_space_init (void)
227{
228  memset (&local_addr_space, 0, sizeof (local_addr_space));
229  local_addr_space.big_endian = (__BYTE_ORDER == __BIG_ENDIAN);
230#if _MIPS_SIM == _ABIO32
231  local_addr_space.abi = UNW_MIPS_ABI_O32;
232#elif _MIPS_SIM == _ABIN32
233  local_addr_space.abi = UNW_MIPS_ABI_N32;
234#elif _MIPS_SIM == _ABI64
235  local_addr_space.abi = UNW_MIPS_ABI_N64;
236#else
237# error Unsupported ABI
238#endif
239  local_addr_space.addr_size = sizeof (void *);
240  local_addr_space.caching_policy = UNW_CACHE_GLOBAL;
241  local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
242  local_addr_space.acc.put_unwind_info = put_unwind_info;
243  local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;
244  local_addr_space.acc.access_mem = access_mem;
245  local_addr_space.acc.access_reg = access_reg;
246  local_addr_space.acc.access_fpreg = access_fpreg;
247  local_addr_space.acc.resume = NULL;  /* mips_local_resume?  FIXME!  */
248  local_addr_space.acc.get_proc_name = get_static_proc_name;
249  unw_flush_cache (&local_addr_space, 0, 0);
250
251  /* ANDROID support update. */
252  mutex_lock (&_U_map_init_lock);
253  if (_U_map_list == NULL)
254    {
255      _U_map_list = maps_create_list(getpid());
256    }
257  mutex_unlock (&_U_map_init_lock);
258  local_addr_space.map_list = _U_map_list;
259  /* End of ANDROID update. */
260}
261
262#endif /* !UNW_REMOTE_ONLY */
263