13842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz/* libunwind - a platform-independent unwind library
23842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz   Copyright (C) 2008 CodeSourcery
33842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
43842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzThis file is part of libunwind.
53842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
63842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzPermission is hereby granted, free of charge, to any person obtaining
73842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitza copy of this software and associated documentation files (the
83842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz"Software"), to deal in the Software without restriction, including
93842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzwithout limitation the rights to use, copy, modify, merge, publish,
103842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdistribute, sublicense, and/or sell copies of the Software, and to
113842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzpermit persons to whom the Software is furnished to do so, subject to
123842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzthe following conditions:
133842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
143842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzThe above copyright notice and this permission notice shall be
153842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzincluded in all copies or substantial portions of the Software.
163842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
173842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
183842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
193842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
203842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
213842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
223842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
233842dac7333e42aa44531eda34ba55200b99ccf8Daniel JacobowitzWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
243842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
253842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#ifndef ARM_LIBUNWIND_I_H
263842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#define ARM_LIBUNWIND_I_H
273842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
283842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz/* Target-dependent definitions that are internal to libunwind but need
293842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz   to be shared with target-independent code.  */
303842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
313842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#include <stdlib.h>
323842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#include <libunwind.h>
333842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
343842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#include "elf32.h"
357d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris/* ANDROID support update. */
367d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris#include "map_info.h"
377d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris/* End of ANDROID update. */
383842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#include "mempool.h"
393842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#include "dwarf.h"
40ffc474b8c8972200642acaef3e5aa10ee853609aZachary T Welch#include "ex_tables.h"
413842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
425f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuuratypedef struct
435f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  {
445f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura    /* no arm-specific fast trace */
455f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  }
465f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuuraunw_tdep_frame_t;
475f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura
483842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstruct unw_addr_space
493842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  {
503842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    struct unw_accessors acc;
513842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    int big_endian;
523842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    unw_caching_policy_t caching_policy;
533842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#ifdef HAVE_ATOMIC_OPS_H
543842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    AO_t cache_generation;
553842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#else
563842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    uint32_t cache_generation;
573842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#endif
583842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    unw_word_t dyn_generation;		/* see dyn-common.h */
593842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    unw_word_t dyn_info_list_addr;	/* (cached) dyn_info_list_addr */
603842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    struct dwarf_rs_cache global_cache;
613842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    struct unw_debug_frame_list *debug_frames;
627d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris    /* ANDROID support update. */
637d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris    struct map_info *map_list;
647d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris    /* End of ANDROID update. */
653842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  };
663842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
673842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstruct cursor
683842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  {
693842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    struct dwarf_cursor dwarf;		/* must be first */
7036511d3d1f040bbf778094e907725ad0617326c8Ken Werner    enum
7136511d3d1f040bbf778094e907725ad0617326c8Ken Werner      {
7236511d3d1f040bbf778094e907725ad0617326c8Ken Werner        ARM_SCF_NONE,                   /* no signal frame */
7336511d3d1f040bbf778094e907725ad0617326c8Ken Werner        ARM_SCF_LINUX_SIGFRAME,         /* non-RT signal frame, kernel >=2.6.18 */
7436511d3d1f040bbf778094e907725ad0617326c8Ken Werner        ARM_SCF_LINUX_RT_SIGFRAME,      /* RT signal frame, kernel >=2.6.18 */
7536511d3d1f040bbf778094e907725ad0617326c8Ken Werner        ARM_SCF_LINUX_OLD_SIGFRAME,     /* non-RT signal frame, kernel < 2.6.18 */
7636511d3d1f040bbf778094e907725ad0617326c8Ken Werner        ARM_SCF_LINUX_OLD_RT_SIGFRAME   /* RT signal frame, kernel < 2.6.18 */
7736511d3d1f040bbf778094e907725ad0617326c8Ken Werner      }
7836511d3d1f040bbf778094e907725ad0617326c8Ken Werner    sigcontext_format;
793842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    unw_word_t sigcontext_addr;
8036511d3d1f040bbf778094e907725ad0617326c8Ken Werner    unw_word_t sigcontext_sp;
8136511d3d1f040bbf778094e907725ad0617326c8Ken Werner    unw_word_t sigcontext_pc;
823842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  };
833842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
843842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#define DWARF_GET_LOC(l)	((l).val)
853842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
863842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#ifdef UNW_LOCAL_ONLY
873842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_NULL_LOC		DWARF_LOC (0, 0)
883842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_IS_NULL_LOC(l)	(DWARF_GET_LOC (l) == 0)
893842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_LOC(r, t)	((dwarf_loc_t) { .val = (r) })
903842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_IS_REG_LOC(l)	0
913842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_REG_LOC(c,r)	(DWARF_LOC((unw_word_t)			     \
923842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				 tdep_uc_addr((c)->as_arg, (r)), 0))
933842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_MEM_LOC(c,m)	DWARF_LOC ((m), 0)
943842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_FPREG_LOC(c,r)	(DWARF_LOC((unw_word_t)			     \
953842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				 tdep_uc_addr((c)->as_arg, (r)), 0))
963842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
973842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic inline int
983842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
993842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{
100f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris/* ANDROID support update. */
101f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris  unw_fpreg_t *addr = (unw_fpreg_t *) (uintptr_t) DWARF_GET_LOC (loc);
102f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris  if (!addr || !map_local_is_readable ((unw_word_t) (uintptr_t) addr))
1033842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return -1;
104f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris
105f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris  *val = *addr;
1063842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  return 0;
107f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris/* End of ANDROID update. */
1083842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz}
1093842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1103842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic inline int
1113842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
1123842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{
113f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris/* ANDROID support update. */
114f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris  unw_fpreg_t *addr = (unw_fpreg_t *) (uintptr_t) DWARF_GET_LOC (loc);
115f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris  if (!addr || !map_local_is_writable ((unw_word_t) (uintptr_t) addr))
1163842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return -1;
117f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris
118f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris  *addr = val;
1193842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  return 0;
120f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris/* End of ANDROID update. */
1213842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz}
1223842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1233842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic inline int
1243842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
1253842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{
126f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris/* ANDROID support update. */
1273842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if (!DWARF_GET_LOC (loc))
1283842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return -1;
129f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris  return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
130f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris				   0, c->as_arg);
131f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris/* End of ANDROID update. */
1323842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz}
1333842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1343842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic inline int
1353842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
1363842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{
137f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris/* ANDROID support update. */
1383842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if (!DWARF_GET_LOC (loc))
1393842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return -1;
140f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris  return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
141f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris				   1, c->as_arg);
142f622936d6c5239b3d5ccafdf38189cec8bca55c0Christopher Ferris/* End of ANDROID update. */
1433842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz}
1443842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1453842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#else /* !UNW_LOCAL_ONLY */
1463842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_LOC_TYPE_FP	(1 << 0)
1473842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_LOC_TYPE_REG	(1 << 1)
1483842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_NULL_LOC		DWARF_LOC (0, 0)
1493842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_IS_NULL_LOC(l)						\
1503842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz		({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; })
1513842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_LOC(r, t)	((dwarf_loc_t) { .val = (r), .type = (t) })
1523842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_IS_REG_LOC(l)	(((l).type & DWARF_LOC_TYPE_REG) != 0)
1533842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_IS_FP_LOC(l)	(((l).type & DWARF_LOC_TYPE_FP) != 0)
1543842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_REG_LOC(c,r)	DWARF_LOC((r), DWARF_LOC_TYPE_REG)
1553842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_MEM_LOC(c,m)	DWARF_LOC ((m), 0)
1563842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define DWARF_FPREG_LOC(c,r)	DWARF_LOC((r), (DWARF_LOC_TYPE_REG	\
1573842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz						| DWARF_LOC_TYPE_FP))
1583842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1593842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic inline int
1603842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
1613842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{
1623842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  char *valp = (char *) &val;
1633842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  unw_word_t addr;
1643842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  int ret;
1653842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1663842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if (DWARF_IS_NULL_LOC (loc))
1673842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return -UNW_EBADREG;
1683842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1693842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if (DWARF_IS_REG_LOC (loc))
1703842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
1713842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				       val, 0, c->as_arg);
1723842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1733842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  addr = DWARF_GET_LOC (loc);
1743842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
1753842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				       0, c->as_arg)) < 0)
1763842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return ret;
1773842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1783842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1, 0,
1793842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				   c->as_arg);
1803842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz}
1813842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1823842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic inline int
1833842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
1843842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{
1853842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  char *valp = (char *) &val;
1863842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  unw_word_t addr;
1873842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  int ret;
1883842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1893842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if (DWARF_IS_NULL_LOC (loc))
1903842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return -UNW_EBADREG;
1913842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1923842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if (DWARF_IS_REG_LOC (loc))
1933842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc),
1943842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				       &val, 1, c->as_arg);
1953842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
1963842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  addr = DWARF_GET_LOC (loc);
1973842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if ((ret = (*c->as->acc.access_mem) (c->as, addr + 0, (unw_word_t *) valp,
1983842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				       1, c->as_arg)) < 0)
1993842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return ret;
2003842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2013842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  return (*c->as->acc.access_mem) (c->as, addr + 4, (unw_word_t *) valp + 1,
2023842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				   1, c->as_arg);
2033842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz}
2043842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2053842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic inline int
2063842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
2073842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{
2083842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if (DWARF_IS_NULL_LOC (loc))
2093842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return -UNW_EBADREG;
2103842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2113842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  /* If a code-generator were to save a value of type unw_word_t in a
2123842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz     floating-point register, we would have to support this case.  I
2133842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz     suppose it could happen with MMX registers, but does it really
2143842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz     happen?  */
2153842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  assert (!DWARF_IS_FP_LOC (loc));
2163842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2173842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if (DWARF_IS_REG_LOC (loc))
2183842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val,
2193842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				     0, c->as_arg);
2203842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  else
2213842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val,
2223842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				     0, c->as_arg);
2233842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz}
2243842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2253842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic inline int
2263842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
2273842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{
2283842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if (DWARF_IS_NULL_LOC (loc))
2293842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return -UNW_EBADREG;
2303842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2313842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  /* If a code-generator were to save a value of type unw_word_t in a
2323842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz     floating-point register, we would have to support this case.  I
2333842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz     suppose it could happen with MMX registers, but does it really
2343842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz     happen?  */
2353842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  assert (!DWARF_IS_FP_LOC (loc));
2363842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2373842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  if (DWARF_IS_REG_LOC (loc))
2383842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val,
2393842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				     1, c->as_arg);
2403842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz  else
2413842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz    return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val,
2423842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				     1, c->as_arg);
2433842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz}
2443842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2453842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#endif /* !UNW_LOCAL_ONLY */
2463842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
247e2962af9d31266761700b431da894421c0d757ecArun Sharma#define tdep_getcontext_trace           unw_getcontext
2485d0f376b08126b51a001d7cdfba1ec4e0d644f54Tommi Rantala#define tdep_init_done			UNW_OBJ(init_done)
2493842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#define tdep_init			UNW_OBJ(init)
250545023c2072975c6b85a09d5faf2cf05db10e064Ken Werner#define arm_find_proc_info		UNW_OBJ(find_proc_info)
251545023c2072975c6b85a09d5faf2cf05db10e064Ken Werner#define arm_put_unwind_info		UNW_OBJ(put_unwind_info)
2523842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
2533842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz   tdep_search_unwind_table.  */
254545023c2072975c6b85a09d5faf2cf05db10e064Ken Werner#define tdep_search_unwind_table	UNW_OBJ(search_unwind_table)
255d93d96ad833390519ea68a2df22dd55dd26a3214Martin Milata#define tdep_find_unwind_table		dwarf_find_unwind_table
2563842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#define tdep_uc_addr			UNW_ARCH_OBJ(uc_addr)
2573842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#define tdep_get_elf_image		UNW_ARCH_OBJ(get_elf_image)
2583842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#define tdep_access_reg			UNW_OBJ(access_reg)
2593842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#define tdep_access_fpreg		UNW_OBJ(access_fpreg)
260dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura#define tdep_fetch_frame(c,ip,n)	do {} while(0)
261dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura#define tdep_cache_frame(c,rs)		do {} while(0)
262dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura#define tdep_reuse_frame(c,rs)		do {} while(0)
2639e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura#define tdep_stash_frame(c,rs)		do {} while(0)
2645f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura#define tdep_trace(cur,addr,n)		(-UNW_ENOINFO)
2653842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2663842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#ifdef UNW_LOCAL_ONLY
2673842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define tdep_find_proc_info(c,ip,n)				\
268545023c2072975c6b85a09d5faf2cf05db10e064Ken Werner	arm_find_proc_info((c)->as, (ip), &(c)->pi, (n),	\
2693842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				       (c)->as_arg)
2703842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define tdep_put_unwind_info(as,pi,arg)		\
271545023c2072975c6b85a09d5faf2cf05db10e064Ken Werner	arm_put_unwind_info((as), (pi), (arg))
2723842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#else
2733842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define tdep_find_proc_info(c,ip,n)					\
2743842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz	(*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n),	\
2753842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				       (c)->as_arg)
2763842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz# define tdep_put_unwind_info(as,pi,arg)		\
2773842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz	(*(as)->acc.put_unwind_info)((as), (pi), (arg))
2783842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#endif
2793842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2803842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#define tdep_get_as(c)			((c)->dwarf.as)
2813842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#define tdep_get_as_arg(c)		((c)->dwarf.as_arg)
2823842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#define tdep_get_ip(c)			((c)->dwarf.ip)
2833842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#define tdep_big_endian(as)		((as)->big_endian)
2843842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2855d0f376b08126b51a001d7cdfba1ec4e0d644f54Tommi Rantalaextern int tdep_init_done;
2863842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
2873842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzextern void tdep_init (void);
288545023c2072975c6b85a09d5faf2cf05db10e064Ken Wernerextern int arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
289545023c2072975c6b85a09d5faf2cf05db10e064Ken Werner			       unw_proc_info_t *pi, int need_unwind_info,
290545023c2072975c6b85a09d5faf2cf05db10e064Ken Werner			       void *arg);
291545023c2072975c6b85a09d5faf2cf05db10e064Ken Wernerextern void arm_put_unwind_info (unw_addr_space_t as,
292545023c2072975c6b85a09d5faf2cf05db10e064Ken Werner				  unw_proc_info_t *pi, void *arg);
2933842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzextern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
2943842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				     unw_dyn_info_t *di, unw_proc_info_t *pi,
2953842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz				     int need_unwind_info, void *arg);
2960eba2169fb19ef0707a2c96201e33769001b5f11Ken Wernerextern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg);
29716b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris/* ANDROID support update. */
298f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferrisextern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
299f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris			       pid_t pid, unw_word_t ip,
300f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris			       unsigned long *segbase, unsigned long *mapoff,
301f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris			       char **path);
30216b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris/* End of ANDROID update. */
3033842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzextern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
3043842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz			    unw_word_t *valp, int write);
3053842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzextern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
3063842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz			      unw_fpreg_t *valp, int write);
3073842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz
30800aed9631b112d7aa7adc98054b62549cfc857daArun Sharma/* unwinding method selection support */
30900aed9631b112d7aa7adc98054b62549cfc857daArun Sharma#define UNW_ARM_METHOD_ALL          0xFF
31000aed9631b112d7aa7adc98054b62549cfc857daArun Sharma#define UNW_ARM_METHOD_DWARF        0x01
31100aed9631b112d7aa7adc98054b62549cfc857daArun Sharma#define UNW_ARM_METHOD_FRAME        0x02
3126a671546741e8355dd9f821f171e4a3c895d28ecZachary T Welch#define UNW_ARM_METHOD_EXIDX        0x04
313efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris/* ANDROID support update. */
314efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#define UNW_ARM_METHOD_LR           0x08
315efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris/* End of ANDROID update. */
31600aed9631b112d7aa7adc98054b62549cfc857daArun Sharma
317ec633a1911e365ba6016fa9fcbd81cad72f7afdbKen Werner#define unwi_unwind_method   UNW_OBJ(unwind_method)
31800aed9631b112d7aa7adc98054b62549cfc857daArun Sharmaextern int unwi_unwind_method;
31900aed9631b112d7aa7adc98054b62549cfc857daArun Sharma
32000aed9631b112d7aa7adc98054b62549cfc857daArun Sharma#define UNW_TRY_METHOD(x)   (unwi_unwind_method & x)
32100aed9631b112d7aa7adc98054b62549cfc857daArun Sharma
3223842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#endif /* ARM_LIBUNWIND_I_H */
323