/* libunwind - a platform-independent unwind library
   Copyright (c) 2001-2005 Hewlett-Packard Development Company, L.P.
	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>

This file is part of libunwind.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */

#include <assert.h>
#include <stdlib.h>
#include <stddef.h>

#include "unwind_i.h"

#ifdef HAVE_IA64INTRIN_H
# include <ia64intrin.h>
#endif

extern unw_addr_space_t _ULia64_local_addr_space;

struct ia64_table_entry
  {
    uint64_t start_offset;
    uint64_t end_offset;
    uint64_t info_offset;
  };

#ifdef UNW_LOCAL_ONLY

static inline int
is_local_addr_space (unw_addr_space_t as)
{
  return 1;
}

static inline int
read_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *valp, void *arg)
{
  *valp = *(unw_word_t *) addr;
  return 0;
}

#else /* !UNW_LOCAL_ONLY */

static inline int
is_local_addr_space (unw_addr_space_t as)
{
  return as == unw_local_addr_space;
}

static inline int
read_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *valp, void *arg)
{
  unw_accessors_t *a = unw_get_accessors (as);

  return (*a->access_mem) (as, addr, valp, 0, arg);
}

/* Helper macro for reading an ia64_table_entry from remote memory.  */
#define remote_read(addr, member)					     \
	(*a->access_mem) (as, (addr) + offsetof (struct ia64_table_entry,    \
						 member), &member, 0, arg)

/* Lookup an unwind-table entry in remote memory.  Returns 1 if an
   entry is found, 0 if no entry is found, negative if an error
   occurred reading remote memory.  */
static int
remote_lookup (unw_addr_space_t as,
	       unw_word_t table, size_t table_size, unw_word_t rel_ip,
	       struct ia64_table_entry *e, void *arg)
{
  unw_word_t e_addr = 0, start_offset, end_offset, info_offset;
  unw_accessors_t *a = unw_get_accessors (as);
  unsigned long lo, hi, mid;
  int ret;

  /* do a binary search for right entry: */
  for (lo = 0, hi = table_size / sizeof (struct ia64_table_entry); lo < hi;)
    {
      mid = (lo + hi) / 2;
      e_addr = table + mid * sizeof (struct ia64_table_entry);
      if ((ret = remote_read (e_addr, start_offset)) < 0)
	return ret;

      if (rel_ip < start_offset)
	hi = mid;
      else
	{
	  if ((ret = remote_read (e_addr, end_offset)) < 0)
	    return ret;

	  if (rel_ip >= end_offset)
	    lo = mid + 1;
	  else
	    break;
	}
    }
  if (rel_ip < start_offset || rel_ip >= end_offset)
    return 0;
  e->start_offset = start_offset;
  e->end_offset = end_offset;

  if ((ret = remote_read (e_addr, info_offset)) < 0)
    return ret;
  e->info_offset = info_offset;
  return 1;
}

HIDDEN void
tdep_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg)
{
  if (!pi->unwind_info)
    return;

  if (is_local_addr_space (as))
    {
      free (pi->unwind_info);
      pi->unwind_info = NULL;
    }
}

PROTECTED unw_word_t
_Uia64_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg)
{
  unw_word_t hdr_addr, info_addr, hdr, directives, pers, cookie, off;
  unw_word_t start_offset, end_offset, info_offset, segbase;
  struct ia64_table_entry *e;
  size_t table_size;
  unw_word_t gp = di->gp;
  int ret;

  switch (di->format)
    {
    case UNW_INFO_FORMAT_DYNAMIC:
    default:
      return 0;

    case UNW_INFO_FORMAT_TABLE:
      e = (struct ia64_table_entry *) di->u.ti.table_data;
      table_size = di->u.ti.table_len * sizeof (di->u.ti.table_data[0]);
      segbase = di->u.ti.segbase;
      if (table_size < sizeof (struct ia64_table_entry))
	return 0;
      start_offset = e[0].start_offset;
      end_offset = e[0].end_offset;
      info_offset = e[0].info_offset;
      break;

    case UNW_INFO_FORMAT_REMOTE_TABLE:
      {
	unw_accessors_t *a = unw_get_accessors (as);
	unw_word_t e_addr = di->u.rti.table_data;

	table_size = di->u.rti.table_len * sizeof (unw_word_t);
	segbase = di->u.rti.segbase;
	if (table_size < sizeof (struct ia64_table_entry))
	  return 0;

	if (   (ret = remote_read (e_addr, start_offset) < 0)
	    || (ret = remote_read (e_addr, end_offset) < 0)
	    || (ret = remote_read (e_addr, info_offset) < 0))
	  return ret;
      }
      break;
    }

  if (start_offset != end_offset)
    /* dyn-list entry cover a zero-length "procedure" and should be
       first entry (note: technically a binary could contain code
       below the segment base, but this doesn't happen for normal
       binaries and certainly doesn't happen when libunwind is a
       separate shared object.  For weird cases, the application may
       have to provide its own (slower) version of this routine.  */
    return 0;

  hdr_addr = info_offset + segbase;
  info_addr = hdr_addr + 8;

  /* read the header word: */
  if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0)
    return ret;

  if (IA64_UNW_VER (hdr) != 1
      || IA64_UNW_FLAG_EHANDLER (hdr) || IA64_UNW_FLAG_UHANDLER (hdr))
    /* dyn-list entry must be version 1 and doesn't have ehandler
       or uhandler */
    return 0;

  if (IA64_UNW_LENGTH (hdr) != 1)
    /* dyn-list entry must consist of a single word of NOP directives */
    return 0;

  if (   ((ret = read_mem (as, info_addr, &directives, arg)) < 0)
      || ((ret = read_mem (as, info_addr + 0x08, &pers, arg)) < 0)
      || ((ret = read_mem (as, info_addr + 0x10, &cookie, arg)) < 0)
      || ((ret = read_mem (as, info_addr + 0x18, &off, arg)) < 0))
    return 0;

  if (directives != 0 || pers != 0
      || (!as->big_endian && cookie != 0x7473696c2d6e7964ULL)
      || ( as->big_endian && cookie != 0x64796e2d6c697374ULL))
    return 0;

  /* OK, we ran the gauntlet and found it: */
  return off + gp;
}

#endif /* !UNW_LOCAL_ONLY */

static inline const struct ia64_table_entry *
lookup (struct ia64_table_entry *table, size_t table_size, unw_word_t rel_ip)
{
  const struct ia64_table_entry *e = 0;
  unsigned long lo, hi, mid;

  /* do a binary search for right entry: */
  for (lo = 0, hi = table_size / sizeof (struct ia64_table_entry); lo < hi;)
    {
      mid = (lo + hi) / 2;
      e = table + mid;
      if (rel_ip < e->start_offset)
	hi = mid;
      else if (rel_ip >= e->end_offset)
	lo = mid + 1;
      else
	break;
    }
  if (rel_ip < e->start_offset || rel_ip >= e->end_offset)
    return NULL;
  return e;
}

PROTECTED int
unw_search_ia64_unwind_table (unw_addr_space_t as, unw_word_t ip,
			      unw_dyn_info_t *di, unw_proc_info_t *pi,
			      int need_unwind_info, void *arg)
{
  unw_word_t addr, hdr_addr, info_addr, info_end_addr, hdr, *wp;
  const struct ia64_table_entry *e = NULL;
  unw_word_t handler_offset, segbase = 0;
  int ret, is_local;
#ifndef UNW_LOCAL_ONLY
  struct ia64_table_entry ent;
#endif

  assert ((di->format == UNW_INFO_FORMAT_TABLE
	   || di->format == UNW_INFO_FORMAT_REMOTE_TABLE)
	  && (ip >= di->start_ip && ip < di->end_ip));

  pi->flags = 0;
  pi->unwind_info = 0;
  pi->handler = 0;

  if (likely (di->format == UNW_INFO_FORMAT_TABLE))
    {
      segbase = di->u.ti.segbase;
      e = lookup ((struct ia64_table_entry *) di->u.ti.table_data,
		  di->u.ti.table_len * sizeof (unw_word_t),
		  ip - segbase);
    }
#ifndef UNW_LOCAL_ONLY
  else
    {
      segbase = di->u.rti.segbase;
      if ((ret = remote_lookup (as, di->u.rti.table_data,
				di->u.rti.table_len * sizeof (unw_word_t),
				ip - segbase, &ent, arg)) < 0)
	return ret;
      if (ret)
	e = &ent;
    }
#endif
  if (!e)
    {
      /* IP is inside this table's range, but there is no explicit
	 unwind info => use default conventions (i.e., this is NOT an
	 error).  */
      memset (pi, 0, sizeof (*pi));
      pi->start_ip = 0;
      pi->end_ip = 0;
      pi->gp = di->gp;
      pi->lsda = 0;
      return 0;
    }

  pi->start_ip = e->start_offset + segbase;
  pi->end_ip = e->end_offset + segbase;

  hdr_addr = e->info_offset + segbase;
  info_addr = hdr_addr + 8;

  /* Read the header word.  Note: the actual unwind-info is always
     assumed to reside in memory, independent of whether di->format is
     UNW_INFO_FORMAT_TABLE or UNW_INFO_FORMAT_REMOTE_TABLE.  */

  if ((ret = read_mem (as, hdr_addr, &hdr, arg)) < 0)
    return ret;

  if (IA64_UNW_VER (hdr) != 1)
    {
      Debug (1, "Unknown header version %ld (hdr word=0x%lx @ 0x%lx)\n",
	     IA64_UNW_VER (hdr), (unsigned long) hdr,
	     (unsigned long) hdr_addr);
      return -UNW_EBADVERSION;
    }

  info_end_addr = info_addr + 8 * IA64_UNW_LENGTH (hdr);

  is_local = is_local_addr_space (as);

  /* If we must have the unwind-info, return it.  Also, if we are in
     the local address-space, return the unwind-info because it's so
     cheap to do so and it may come in handy later on.  */
  if (need_unwind_info || is_local)
    {
      pi->unwind_info_size = 8 * IA64_UNW_LENGTH (hdr);

      if (is_local)
	pi->unwind_info = (void *) (uintptr_t) info_addr;
      else
	{
	  /* Internalize unwind info.  Note: since we're doing this
	     only for non-local address spaces, there is no
	     signal-safety issue and it is OK to use malloc()/free().  */
	  pi->unwind_info = malloc (8 * IA64_UNW_LENGTH (hdr));
	  if (!pi->unwind_info)
	    return -UNW_ENOMEM;

	  wp = (unw_word_t *) pi->unwind_info;
	  for (addr = info_addr; addr < info_end_addr; addr += 8, ++wp)
	    {
	      if ((ret = read_mem (as, addr, wp, arg)) < 0)
		{
		  free (pi->unwind_info);
		  return ret;
		}
	    }
	}
    }

  if (IA64_UNW_FLAG_EHANDLER (hdr) || IA64_UNW_FLAG_UHANDLER (hdr))
    {
      /* read the personality routine address (address is gp-relative): */
      if ((ret = read_mem (as, info_end_addr, &handler_offset, arg)) < 0)
	return ret;
      Debug (4, "handler ptr @ offset=%lx, gp=%lx\n", handler_offset, di->gp);
      if ((read_mem (as, handler_offset + di->gp, &pi->handler, arg)) < 0)
	return ret;
    }
  pi->lsda = info_end_addr + 8;
  pi->gp = di->gp;
  pi->format = di->format;
  return 0;
}

#ifndef UNW_REMOTE_ONLY

# if defined(HAVE_DL_ITERATE_PHDR)
#  include <link.h>
#  include <stdlib.h>

#  if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) \
      || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && !defined(DT_CONFIG))
#    error You need GLIBC 2.2.4 or later on IA-64 Linux
#  endif

#  if defined(HAVE_GETUNWIND)
     extern unsigned long getunwind (void *buf, size_t len);
#  else /* HAVE_GETUNWIND */
#   include <unistd.h>
#   include <sys/syscall.h>
#   ifndef __NR_getunwind
#     define __NR_getunwind	1215
#   endif

static unsigned long
getunwind (void *buf, size_t len)
{
  return syscall (SYS_getunwind, buf, len);
}

#  endif /* HAVE_GETUNWIND */

static unw_dyn_info_t kernel_table;

static int
get_kernel_table (unw_dyn_info_t *di)
{
  struct ia64_table_entry *ktab, *etab;
  size_t size;

  Debug (16, "getting kernel table");

  size = getunwind (NULL, 0);
  ktab = sos_alloc (size);
  if (!ktab)
    {
      Dprintf (__FILE__".%s: failed to allocate %zu bytes",
	       __FUNCTION__, size);
      return -UNW_ENOMEM;
    }
  getunwind (ktab, size);

  /* Determine length of kernel's unwind table & relocate its entries.  */
  for (etab = ktab; etab->start_offset; ++etab)
    etab->info_offset += (uint64_t) ktab;

  di->format = UNW_INFO_FORMAT_TABLE;
  di->gp = 0;
  di->start_ip = ktab[0].start_offset;
  di->end_ip = etab[-1].end_offset;
  di->u.ti.name_ptr = (unw_word_t) "<kernel>";
  di->u.ti.segbase = 0;
  di->u.ti.table_len = ((char *) etab - (char *) ktab) / sizeof (unw_word_t);
  di->u.ti.table_data = (unw_word_t *) ktab;

  Debug (16, "found table `%s': [%lx-%lx) segbase=%lx len=%lu\n",
	 (char *) di->u.ti.name_ptr, di->start_ip, di->end_ip,
	 di->u.ti.segbase, di->u.ti.table_len);
  return 0;
}

#  ifndef UNW_LOCAL_ONLY

/* This is exported for the benefit of libunwind-ptrace.a.  */
PROTECTED int
_Uia64_get_kernel_table (unw_dyn_info_t *di)
{
  int ret;

  if (!kernel_table.u.ti.table_data)
    if ((ret = get_kernel_table (&kernel_table)) < 0)
      return ret;

  memcpy (di, &kernel_table, sizeof (*di));
  return 0;
}

#  endif /* !UNW_LOCAL_ONLY */

static inline unsigned long
current_gp (void)
{
#  if defined(__GNUC__) && !defined(__INTEL_COMPILER)
      register unsigned long gp __asm__("gp");
      return gp;
#  elif HAVE_IA64INTRIN_H
      return __getReg (_IA64_REG_GP);
#  else
#    error Implement me.
#  endif
}

static int
callback (struct dl_phdr_info *info, size_t size, void *ptr)
{
  unw_dyn_info_t *di = ptr;
  const Elf64_Phdr *phdr, *p_unwind, *p_dynamic, *p_text;
  long n;
  Elf64_Addr load_base, segbase = 0;

  /* Make sure struct dl_phdr_info is at least as big as we need.  */
  if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
	     + sizeof (info->dlpi_phnum))
    return -1;

  Debug (16, "checking `%s' (load_base=%lx)\n",
	 info->dlpi_name, info->dlpi_addr);

  phdr = info->dlpi_phdr;
  load_base = info->dlpi_addr;
  p_text = NULL;
  p_unwind = NULL;
  p_dynamic = NULL;

  /* See if PC falls into one of the loaded segments.  Find the unwind
     segment at the same time.  */
  for (n = info->dlpi_phnum; --n >= 0; phdr++)
    {
      if (phdr->p_type == PT_LOAD)
	{
	  Elf64_Addr vaddr = phdr->p_vaddr + load_base;
	  if (di->u.ti.segbase >= vaddr
	      && di->u.ti.segbase < vaddr + phdr->p_memsz)
	    p_text = phdr;
	}
      else if (phdr->p_type == PT_IA_64_UNWIND)
	p_unwind = phdr;
      else if (phdr->p_type == PT_DYNAMIC)
	p_dynamic = phdr;
    }
  if (!p_text || !p_unwind)
    return 0;

  if (likely (p_unwind->p_vaddr >= p_text->p_vaddr
	      && p_unwind->p_vaddr < p_text->p_vaddr + p_text->p_memsz))
    /* normal case: unwind table is inside text segment */
    segbase = p_text->p_vaddr + load_base;
  else
    {
      /* Special case: unwind table is in some other segment; this
	 happens for the Linux kernel's gate DSO, for example.  */
      phdr = info->dlpi_phdr;
      for (n = info->dlpi_phnum; --n >= 0; phdr++)
	{
	  if (phdr->p_type == PT_LOAD && p_unwind->p_vaddr >= phdr->p_vaddr
	      && p_unwind->p_vaddr < phdr->p_vaddr + phdr->p_memsz)
	    {
	      segbase = phdr->p_vaddr + load_base;
	      break;
	    }
	}
    }

  if (p_dynamic)
    {
      /* For dynamicly linked executables and shared libraries,
	 DT_PLTGOT is the gp value for that object.  */
      Elf64_Dyn *dyn = (Elf64_Dyn *)(p_dynamic->p_vaddr + load_base);
      for (; dyn->d_tag != DT_NULL; ++dyn)
	if (dyn->d_tag == DT_PLTGOT)
	  {
	    /* On IA-64, _DYNAMIC is writable and GLIBC has relocated it.  */
	    di->gp = dyn->d_un.d_ptr;
	    break;
	  }
    }
  else
    /* Otherwise this is a static executable with no _DYNAMIC.
       The gp is constant program-wide.  */
    di->gp = current_gp();
  di->format = UNW_INFO_FORMAT_TABLE;
  di->start_ip = p_text->p_vaddr + load_base;
  di->end_ip = p_text->p_vaddr + load_base + p_text->p_memsz;
  di->u.ti.name_ptr = (unw_word_t) info->dlpi_name;
  di->u.ti.table_data = (void *) (p_unwind->p_vaddr + load_base);
  di->u.ti.table_len = p_unwind->p_memsz / sizeof (unw_word_t);
  di->u.ti.segbase = segbase;

  Debug (16, "found table `%s': segbase=%lx, len=%lu, gp=%lx, "
	 "table_data=%p\n", (char *) di->u.ti.name_ptr, di->u.ti.segbase,
	 di->u.ti.table_len, di->gp, di->u.ti.table_data);
  return 1;
}

#  ifdef HAVE_DL_PHDR_REMOVALS_COUNTER

static inline int
validate_cache (unw_addr_space_t as)
{
  /* Note: we don't need to serialize here with respect to
     dl_iterate_phdr() because if somebody were to remove an object
     that is required to complete the unwind on whose behalf we're
     validating the cache here, we'd be hosed anyhow.  What we're
     guarding against here is the case where library FOO gets mapped,
     unwind info for FOO gets cached, FOO gets unmapped, BAR gets
     mapped in the place where FOO was and then we unwind across a
     function in FOO.  Since no thread can execute in BAR before FOO
     has been removed, we are guaranteed that
     dl_phdr_removals_counter() would have been incremented before we
     get here.  */
  unsigned long long removals = dl_phdr_removals_counter ();

  if (removals == as->shared_object_removals)
    return 1;

  as->shared_object_removals = removals;
  unw_flush_cache (as, 0, 0);
  return -1;
}

#  else /* !HAVE_DL_PHDR_REMOVALS_COUNTER */

/* Check whether any phdrs have been removed since we last flushed the
   cache.  If so we flush the cache and return -1, if not, we do
   nothing and return 1.  */

static int
check_callback (struct dl_phdr_info *info, size_t size, void *ptr)
{
#   ifdef HAVE_STRUCT_DL_PHDR_INFO_DLPI_SUBS
  unw_addr_space_t as = ptr;

  if (size <
      offsetof (struct dl_phdr_info, dlpi_subs) + sizeof (info->dlpi_subs))
    /* It would be safer to flush the cache here, but that would
       disable caching for older libc's which would be incompatible
       with the behavior of older versions of libunwind so we return 1
       instead and hope nobody runs into stale cache info...  */
    return 1;

  if (info->dlpi_subs == as->shared_object_removals)
    return 1;

  as->shared_object_removals = info->dlpi_subs;
  unw_flush_cache (as, 0, 0);
  return -1;		/* indicate that there were removals */
#   else
  return 1;
#   endif
}

static inline int
validate_cache (unw_addr_space_t as)
{
  intrmask_t saved_mask;
  int ret;

  SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask);
  ret = dl_iterate_phdr (check_callback, as);
  SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
  return ret;
}

#  endif /* HAVE_DL_PHDR_REMOVALS_COUNTER */

# elif defined(HAVE_DLMODINFO)
  /* Support for HP-UX-style dlmodinfo() */
#  include <dlfcn.h>

static inline int
validate_cache (unw_addr_space_t as)
{
  return 1;
}

# endif /* !HAVE_DLMODINFO */

HIDDEN int
tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip,
		     unw_proc_info_t *pi, int need_unwind_info, void *arg)
{
# if defined(HAVE_DL_ITERATE_PHDR)
  unw_dyn_info_t di, *dip = &di;
  intrmask_t saved_mask;
  int ret;

  di.u.ti.segbase = ip;	/* this is cheap... */

  SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask);
  ret = dl_iterate_phdr (callback, &di);
  SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);

  if (ret <= 0)
    {
      if (!kernel_table.u.ti.table_data)
	{
	  if ((ret = get_kernel_table (&kernel_table)) < 0)
	    return ret;
	}
      if (ip < kernel_table.start_ip || ip >= kernel_table.end_ip)
	return -UNW_ENOINFO;
      dip = &kernel_table;
    }
# elif defined(HAVE_DLMODINFO)
# define UNWIND_TBL_32BIT	0x8000000000000000
  struct load_module_desc lmd;
  unw_dyn_info_t di, *dip = &di;
  struct unwind_header
    {
      uint64_t header_version;
      uint64_t start_offset;
      uint64_t end_offset;
    }
  *uhdr;

  if (!dlmodinfo (ip, &lmd, sizeof (lmd), NULL, 0, 0))
    return -UNW_ENOINFO;

  di.format = UNW_INFO_FORMAT_TABLE;
  di.start_ip = lmd.text_base;
  di.end_ip = lmd.text_base + lmd.text_size;
  di.gp = lmd.linkage_ptr;
  di.u.ti.name_ptr = 0;	/* no obvious table-name available */
  di.u.ti.segbase = lmd.text_base;

  uhdr = (struct unwind_header *) lmd.unwind_base;

  if ((uhdr->header_version & ~UNWIND_TBL_32BIT) != 1
      && (uhdr->header_version & ~UNWIND_TBL_32BIT) != 2)
    {
      Debug (1, "encountered unknown unwind header version %ld\n",
 	     (long) (uhdr->header_version & ~UNWIND_TBL_32BIT));
      return -UNW_EBADVERSION;
    }
  if (uhdr->header_version & UNWIND_TBL_32BIT)
    {
      Debug (1, "32-bit unwind tables are not supported yet\n");
      return -UNW_EINVAL;
    }

  di.u.ti.table_data = (unw_word_t *) (di.u.ti.segbase + uhdr->start_offset);
  di.u.ti.table_len = ((uhdr->end_offset - uhdr->start_offset)
		       / sizeof (unw_word_t));

  Debug (16, "found table `%s': segbase=%lx, len=%lu, gp=%lx, "
 	 "table_data=%p\n", (char *) di.u.ti.name_ptr, di.u.ti.segbase,
 	 di.u.ti.table_len, di.gp, di.u.ti.table_data);
# endif

  /* now search the table: */
  return tdep_search_unwind_table (as, ip, dip, pi, need_unwind_info, arg);
}

/* Returns 1 if the cache is up-to-date or -1 if the cache contained
   stale data and had to be flushed.  */

HIDDEN int
ia64_local_validate_cache (unw_addr_space_t as, void *arg)
{
  return validate_cache (as);
}

#endif /* !UNW_REMOTE_ONLY */
