16525714c270c6521389b657793bd7147eeffa4f0Arun Sharma/* libunwind - a platform-independent unwind library
26525714c270c6521389b657793bd7147eeffa4f0Arun Sharma   Copyright (C) 2003-2004 Hewlett-Packard Co
36525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
46525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
56525714c270c6521389b657793bd7147eeffa4f0Arun SharmaThis file is part of libunwind.
66525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
76525714c270c6521389b657793bd7147eeffa4f0Arun SharmaPermission is hereby granted, free of charge, to any person obtaining
86525714c270c6521389b657793bd7147eeffa4f0Arun Sharmaa copy of this software and associated documentation files (the
96525714c270c6521389b657793bd7147eeffa4f0Arun Sharma"Software"), to deal in the Software without restriction, including
106525714c270c6521389b657793bd7147eeffa4f0Arun Sharmawithout limitation the rights to use, copy, modify, merge, publish,
116525714c270c6521389b657793bd7147eeffa4f0Arun Sharmadistribute, sublicense, and/or sell copies of the Software, and to
126525714c270c6521389b657793bd7147eeffa4f0Arun Sharmapermit persons to whom the Software is furnished to do so, subject to
136525714c270c6521389b657793bd7147eeffa4f0Arun Sharmathe following conditions:
146525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
156525714c270c6521389b657793bd7147eeffa4f0Arun SharmaThe above copyright notice and this permission notice shall be
166525714c270c6521389b657793bd7147eeffa4f0Arun Sharmaincluded in all copies or substantial portions of the Software.
176525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
186525714c270c6521389b657793bd7147eeffa4f0Arun SharmaTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
196525714c270c6521389b657793bd7147eeffa4f0Arun SharmaEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
206525714c270c6521389b657793bd7147eeffa4f0Arun SharmaMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
216525714c270c6521389b657793bd7147eeffa4f0Arun SharmaNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
226525714c270c6521389b657793bd7147eeffa4f0Arun SharmaLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
236525714c270c6521389b657793bd7147eeffa4f0Arun SharmaOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
246525714c270c6521389b657793bd7147eeffa4f0Arun SharmaWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
256525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
266525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#include <fcntl.h>
276525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#include <string.h>
286525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#include <unistd.h>
296525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
306525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#include <sys/mman.h>
316525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
326525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#include "libunwind_i.h"
336525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#include "dwarf-eh.h"
346525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#include "dwarf_i.h"
356525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
3616b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris/* ANDROID support update. */
376525714c270c6521389b657793bd7147eeffa4f0Arun Sharmaint
3816b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferrisdwarf_find_unwind_table (struct elf_dyn_info *edi, struct elf_image *ei,
3916b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris			 unw_addr_space_t as, char *path,
4016b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris			 unw_word_t segbase, unw_word_t mapoff, unw_word_t ip)
4116b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris/* End of ANDROID update. */
426525714c270c6521389b657793bd7147eeffa4f0Arun Sharma{
436525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL;
446525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  unw_word_t addr, eh_frame_start, fde_count, load_base;
456525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  unw_word_t max_load_addr = 0;
466525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  unw_word_t start_ip = (unw_word_t) -1;
476525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  unw_word_t end_ip = 0;
486525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  struct dwarf_eh_frame_hdr *hdr;
496525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  unw_proc_info_t pi;
506525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  unw_accessors_t *a;
516525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  Elf_W(Ehdr) *ehdr;
526525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#if UNW_TARGET_ARM
536525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  const Elf_W(Phdr) *parm_exidx = NULL;
546525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#endif
556525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  int i, ret, found = 0;
566525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
576525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  /* XXX: Much of this code is Linux/LSB-specific.  */
586525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
5916b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  /* ANDROID support update. */
6016b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  if (!elf_w(valid_object) (ei))
6116b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  /* End of ANDROID update. */
626525714c270c6521389b657793bd7147eeffa4f0Arun Sharma    return -UNW_ENOINFO;
636525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
6416b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  /* ANDROID support update. */
6516b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  ehdr = ei->image;
6616b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  phdr = (Elf_W(Phdr) *) ((char *) ei->image + ehdr->e_phoff);
6716b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  /* End of ANDROID update. */
686525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
696525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  for (i = 0; i < ehdr->e_phnum; ++i)
706525714c270c6521389b657793bd7147eeffa4f0Arun Sharma    {
716525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      switch (phdr[i].p_type)
726525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	{
736525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	case PT_LOAD:
746525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  if (phdr[i].p_vaddr < start_ip)
756525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	    start_ip = phdr[i].p_vaddr;
766525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
776525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip)
786525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	    end_ip = phdr[i].p_vaddr + phdr[i].p_memsz;
796525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
806525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  if (phdr[i].p_offset == mapoff)
816525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	    ptxt = phdr + i;
8216b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris
8316b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris          /* ANDROID support update. */
8416b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris	  if ((uintptr_t) ei->image + phdr->p_filesz > max_load_addr)
8516b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris	    max_load_addr = (uintptr_t) ei->image + phdr->p_filesz;
866525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  break;
8716b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris          /* End of ANDROID update. */
886525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
896525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	case PT_GNU_EH_FRAME:
906525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  peh_hdr = phdr + i;
916525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  break;
926525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
936525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	case PT_DYNAMIC:
946525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  pdyn = phdr + i;
956525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  break;
966525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
976525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#if UNW_TARGET_ARM
986525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	case PT_ARM_EXIDX:
996525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  parm_exidx = phdr + i;
1006525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  break;
1016525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#endif
1026525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1036525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	default:
1046525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  break;
1056525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	}
1066525714c270c6521389b657793bd7147eeffa4f0Arun Sharma    }
1076525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1086525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  if (!ptxt)
1096525714c270c6521389b657793bd7147eeffa4f0Arun Sharma    return 0;
1106525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1116525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  load_base = segbase - ptxt->p_vaddr;
1126525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  start_ip += load_base;
1136525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  end_ip += load_base;
1146525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1156525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  if (peh_hdr)
1166525714c270c6521389b657793bd7147eeffa4f0Arun Sharma    {
1176525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      if (pdyn)
1186525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	{
1196525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  /* For dynamicly linked executables and shared libraries,
1206525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	     DT_PLTGOT is the value that data-relative addresses are
1216525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	     relative to for that object.  We call this the "gp".  */
12216b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris		/* ANDROID support update. */
1236525714c270c6521389b657793bd7147eeffa4f0Arun Sharma		Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset
12416b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris						 + (char *) ei->image);
12516b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris		/* End of ANDROID update. */
1266525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  for (; dyn->d_tag != DT_NULL; ++dyn)
1276525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	    if (dyn->d_tag == DT_PLTGOT)
1286525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	      {
1296525714c270c6521389b657793bd7147eeffa4f0Arun Sharma		/* Assume that _DYNAMIC is writable and GLIBC has
1306525714c270c6521389b657793bd7147eeffa4f0Arun Sharma		   relocated it (true for x86 at least).  */
1316525714c270c6521389b657793bd7147eeffa4f0Arun Sharma		edi->di_cache.gp = dyn->d_un.d_ptr;
1326525714c270c6521389b657793bd7147eeffa4f0Arun Sharma		break;
1336525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	      }
1346525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	}
1356525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      else
1366525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	/* Otherwise this is a static executable with no _DYNAMIC.  Assume
1376525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	   that data-relative addresses are relative to 0, i.e.,
1386525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	   absolute.  */
1396525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	edi->di_cache.gp = 0;
1406525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
14116b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris      /* ANDROID support update. */
1426525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset
14316b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris					   + (char *) ei->image);
14416b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris      /* End of ANDROID update. */
1456525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      if (hdr->version != DW_EH_VERSION)
1466525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	{
1476525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  Debug (1, "table `%s' has unexpected version %d\n",
1486525714c270c6521389b657793bd7147eeffa4f0Arun Sharma		 path, hdr->version);
1496525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  return -UNW_ENOINFO;
1506525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	}
1516525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1526525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      a = unw_get_accessors (unw_local_addr_space);
153d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      /* ANDROID support update. */
154d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      addr = (unw_word_t) (uintptr_t) (hdr + 1);
155d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      /* End of ANDROID update. */
1566525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1576525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      /* Fill in a dummy proc_info structure.  We just need to fill in
1586525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	 enough to ensure that dwarf_read_encoded_pointer() can do it's
1596525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	 job.  Since we don't have a procedure-context at this point, all
1606525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	 we have to do is fill in the global-pointer.  */
1616525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      memset (&pi, 0, sizeof (pi));
1626525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      pi.gp = edi->di_cache.gp;
1636525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1646525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      /* (Optionally) read eh_frame_ptr: */
1656525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
1666525714c270c6521389b657793bd7147eeffa4f0Arun Sharma					     &addr, hdr->eh_frame_ptr_enc, &pi,
1676525714c270c6521389b657793bd7147eeffa4f0Arun Sharma					     &eh_frame_start, NULL)) < 0)
1686525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	return -UNW_ENOINFO;
1696525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1706525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      /* (Optionally) read fde_count: */
1716525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
1726525714c270c6521389b657793bd7147eeffa4f0Arun Sharma					     &addr, hdr->fde_count_enc, &pi,
1736525714c270c6521389b657793bd7147eeffa4f0Arun Sharma					     &fde_count, NULL)) < 0)
1746525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	return -UNW_ENOINFO;
1756525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1766525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4))
1776525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	{
1786525714c270c6521389b657793bd7147eeffa4f0Arun Sharma    #if 1
1796525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  abort ();
1806525714c270c6521389b657793bd7147eeffa4f0Arun Sharma    #else
1816525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  unw_word_t eh_frame_end;
1826525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1836525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  /* If there is no search table or it has an unsupported
1846525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	     encoding, fall back on linear search.  */
1856525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  if (hdr->table_enc == DW_EH_PE_omit)
1866525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	    Debug (4, "EH lacks search table; doing linear search\n");
1876525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  else
1886525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	    Debug (4, "EH table has encoding 0x%x; doing linear search\n",
1896525714c270c6521389b657793bd7147eeffa4f0Arun Sharma		   hdr->table_enc);
1906525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1916525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  eh_frame_end = max_load_addr;	/* XXX can we do better? */
1926525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1936525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  if (hdr->fde_count_enc == DW_EH_PE_omit)
1946525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	    fde_count = ~0UL;
1956525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit)
1966525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	    abort ();
1976525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
1986525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	  return linear_search (unw_local_addr_space, ip,
1996525714c270c6521389b657793bd7147eeffa4f0Arun Sharma				eh_frame_start, eh_frame_end, fde_count,
2006525714c270c6521389b657793bd7147eeffa4f0Arun Sharma				pi, need_unwind_info, NULL);
2016525714c270c6521389b657793bd7147eeffa4f0Arun Sharma    #endif
2026525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	}
2036525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
2046525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_cache.start_ip = start_ip;
2056525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_cache.end_ip = end_ip;
2066525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE;
2076525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_cache.u.rti.name_ptr = 0;
2086525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      /* two 32-bit values (ip_offset/fde_offset) per table-entry: */
2096525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t);
210d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      /* ANDROID support update. */
2116525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr)
212d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris				       + (addr - (uintptr_t) ei->image
2136525714c270c6521389b657793bd7147eeffa4f0Arun Sharma					  - peh_hdr->p_offset));
214d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      /* End of ANDROID update. */
2156525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
2166525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      /* For the binary-search table in the eh_frame_hdr, data-relative
2176525714c270c6521389b657793bd7147eeffa4f0Arun Sharma	 means relative to the start of that section... */
21816b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris
21916b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris      /* ANDROID support update. */
2206525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr)
221d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris				    + ((uintptr_t) hdr - (uintptr_t) ei->image
2226525714c270c6521389b657793bd7147eeffa4f0Arun Sharma				       - peh_hdr->p_offset));
22316b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris      /* End of ANDROID update. */
2246525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      found = 1;
2256525714c270c6521389b657793bd7147eeffa4f0Arun Sharma    }
2266525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
2276525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#if UNW_TARGET_ARM
2286525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  if (parm_exidx)
2296525714c270c6521389b657793bd7147eeffa4f0Arun Sharma    {
2306525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX;
2316525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_arm.start_ip = start_ip;
2326525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_arm.end_ip = end_ip;
2336525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_arm.u.rti.name_ptr = (unw_word_t) path;
2346525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_arm.u.rti.table_data = load_base + parm_exidx->p_vaddr;
2356525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      edi->di_arm.u.rti.table_len = parm_exidx->p_memsz;
2366525714c270c6521389b657793bd7147eeffa4f0Arun Sharma      found = 1;
2376525714c270c6521389b657793bd7147eeffa4f0Arun Sharma    }
2386525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#endif
2396525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
2406525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#ifdef CONFIG_DEBUG_FRAME
2416525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  /* Try .debug_frame. */
242a6f2a7a2a871d88402dc28c02bee672f8321b7bbTommi Rantala  found = dwarf_find_debug_frame (found, &edi->di_debug, ip, load_base, path,
2436525714c270c6521389b657793bd7147eeffa4f0Arun Sharma				  start_ip, end_ip);
2446525714c270c6521389b657793bd7147eeffa4f0Arun Sharma#endif
2456525714c270c6521389b657793bd7147eeffa4f0Arun Sharma
2466525714c270c6521389b657793bd7147eeffa4f0Arun Sharma  return found;
2476525714c270c6521389b657793bd7147eeffa4f0Arun Sharma}
248