/* libunwind - a platform-independent unwind library

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 <elf.h>

#include "_UCD_lib.h"
#include "_UCD_internal.h"

static int
get_unwind_info(struct UCD_info *ui, unw_addr_space_t as, unw_word_t ip)
{
  unsigned long segbase, mapoff;

#if UNW_TARGET_IA64 && defined(__linux)
  if (!ui->edi.ktab.start_ip && _Uia64_get_kernel_table (&ui->edi.ktab) < 0)
    return -UNW_ENOINFO;

  if (ui->edi.ktab.format != -1 && ip >= ui->edi.ktab.start_ip && ip < ui->edi.ktab.end_ip)
    return 0;
#endif

  if ((ui->edi.di_cache.format != -1
       && ip >= ui->edi.di_cache.start_ip && ip < ui->edi.di_cache.end_ip)
#if UNW_TARGET_ARM
      || (ui->edi.di_debug.format != -1
       && ip >= ui->edi.di_arm.start_ip && ip < ui->edi.di_arm.end_ip)
#endif
      || (ui->edi.di_debug.format != -1
       && ip >= ui->edi.di_debug.start_ip && ip < ui->edi.di_debug.end_ip))
    return 0;

  invalidate_edi (&ui->edi);

  /* Used to be tdep_get_elf_image() in ptrace unwinding code */
  coredump_phdr_t *phdr = _UCD_get_elf_image(ui, ip);
  if (!phdr)
    {
      Debug(1, "returns error: _UCD_get_elf_image failed\n");
      return -UNW_ENOINFO;
    }
  /* segbase: where it is mapped in virtual memory */
  /* mapoff: offset in the file */
  segbase = phdr->p_vaddr;
  /*mapoff  = phdr->p_offset; WRONG! phdr->p_offset is the offset in COREDUMP file */
  mapoff  = 0;
///FIXME. text segment is USUALLY, not always, at offset 0 in the binary/.so file.
// ensure that at initialization.

  /* Here, SEGBASE is the starting-address of the (mmap'ped) segment
     which covers the IP we're looking for.  */
  if (tdep_find_unwind_table(&ui->edi, as, phdr->backing_filename, segbase, mapoff, ip) < 0)
    {
      Debug(1, "returns error: tdep_find_unwind_table failed\n");
      return -UNW_ENOINFO;
    }

  /* This can happen in corner cases where dynamically generated
     code falls into the same page that contains the data-segment
     and the page-offset of the code is within the first page of
     the executable.  */
  if (ui->edi.di_cache.format != -1
      && (ip < ui->edi.di_cache.start_ip || ip >= ui->edi.di_cache.end_ip))
     ui->edi.di_cache.format = -1;

  if (ui->edi.di_debug.format != -1
      && (ip < ui->edi.di_debug.start_ip || ip >= ui->edi.di_debug.end_ip))
     ui->edi.di_debug.format = -1;

  if (ui->edi.di_cache.format == -1
#if UNW_TARGET_ARM
      && ui->edi.di_arm.format == -1
#endif
      && ui->edi.di_debug.format == -1)
  {
    Debug(1, "returns error: all formats are -1\n");
    return -UNW_ENOINFO;
  }

  Debug(1, "returns success\n");
  return 0;
}

int
_UCD_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
		     int need_unwind_info, void *arg)
{
  struct UCD_info *ui = arg;

  Debug(1, "entering\n");

  int ret = -UNW_ENOINFO;

  if (get_unwind_info(ui, as, ip) < 0) {
    Debug(1, "returns error: get_unwind_info failed\n");
    return -UNW_ENOINFO;
  }

#if UNW_TARGET_IA64
  if (ui->edi.ktab.format != -1)
    {
      /* The kernel unwind table resides in local memory, so we have
	 to use the local address space to search it.  Since
	 _UCD_put_unwind_info() has no easy way of detecting this
	 case, we simply make a copy of the unwind-info, so
	 _UCD_put_unwind_info() can always free() the unwind-info
	 without ill effects.  */
      ret = tdep_search_unwind_table (unw_local_addr_space, ip, &ui->edi.ktab, pi,
				      need_unwind_info, arg);
      if (ret >= 0)
	{
	  if (!need_unwind_info)
	    pi->unwind_info = NULL;
	  else
	    {
	      void *mem = malloc (pi->unwind_info_size);

	      if (!mem)
		return -UNW_ENOMEM;
	      memcpy (mem, pi->unwind_info, pi->unwind_info_size);
	      pi->unwind_info = mem;
	    }
	}
    }
#endif

  if (ret == -UNW_ENOINFO && ui->edi.di_cache.format != -1)
    ret = tdep_search_unwind_table (as, ip, &ui->edi.di_cache,
				    pi, need_unwind_info, arg);

#if UNW_TARGET_ARM
  if (ret == -UNW_ENOINFO && ui->edi.di_arm.format != -1)
    ret = tdep_search_unwind_table (as, ip, &ui->edi.di_arm, pi,
                                    need_unwind_info, arg);
#endif

  if (ret == -UNW_ENOINFO && ui->edi.di_debug.format != -1)
    ret = tdep_search_unwind_table (as, ip, &ui->edi.di_debug, pi,
				    need_unwind_info, arg);

  Debug(1, "returns %d\n", ret);

  return ret;
}
