/* libunwind - a platform-independent unwind library
   Copyright (C) 2003-2004 Hewlett-Packard Co
	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 <fcntl.h>
#include <string.h>
#include <unistd.h>

#include <sys/mman.h>

#include "libunwind_i.h"
#include "dwarf-eh.h"
#include "dwarf_i.h"

static bool get_dyn_gp(struct elf_image* ei, Elf_W(Off) dyn_phdr_offset, unw_word_t* gp) {
  Elf_W(Phdr) phdr;
  GET_PHDR_FIELD(ei, dyn_phdr_offset, &phdr, p_offset);
  Elf_W(Dyn) dyn;
  Elf_W(Off) dyn_offset = phdr.p_offset;
  unw_word_t map_size = ei->u.memory.map->end - ei->u.memory.map->start;
  while (dyn_offset + sizeof(dyn) < map_size) {
    GET_DYN_FIELD(ei, dyn_offset, &dyn, d_tag);
    if (dyn.d_tag == DT_NULL) {
      break;
    }
    if (dyn.d_tag == DT_PLTGOT) {
      // Assume that _DYNAMIC is writable and GLIBC has
      // relocated it (true for x86 at least).
      GET_DYN_FIELD(ei, dyn_offset, &dyn, d_un.d_ptr);
      *gp = dyn.d_un.d_ptr;
      return true;
    }
    dyn_offset += sizeof(dyn);
  }
  Debug(1, "DT_PLTGOT not found in dynamic header\n");
  return false;
}

static bool get_eh_frame_info(
    struct elf_image* ei, unw_word_t phdr_offset, unw_word_t load_base, unw_dyn_info_t* di_cache) {
  Elf_W(Phdr) phdr;
  GET_PHDR_FIELD(ei, phdr_offset, &phdr, p_offset);
  unw_word_t hdr_offset = phdr.p_offset;
  struct dwarf_eh_frame_hdr hdr;
  // Read the entire hdr since we are going to use every value in the struct.
  if (sizeof(hdr) != elf_w (memory_read) (ei, ei->u.memory.map->start +phdr.p_offset,
                            (uint8_t*) &hdr, sizeof(hdr), false)) {
    Debug(1, "Failed to read dwarf_eh_frame_hdr from in memory elf image.\n");
    return false;
  }

  if (hdr.version != DW_EH_VERSION) {
    Debug (1, "table has unexpected version %d\n", hdr.version);
    return false;
  }

  // Fill in a dummy proc_info structure.  We just need to fill in
  // enough to ensure that dwarf_read_encoded_pointer() can do its
  // job.  Since we don't have a procedure-context at this point, all
  // we have to do is fill in the global-pointer.
  unw_proc_info_t pi;
  memset (&pi, 0, sizeof (pi));
  pi.gp = di_cache->gp;

  unw_accessors_t* a = unw_get_accessors (ei->u.memory.as);
  unw_word_t addr = (unw_word_t) (uintptr_t) (hdr_offset + sizeof(struct dwarf_eh_frame_hdr));
  addr += ei->u.memory.map->start;

  unw_word_t eh_frame_start;
  if (dwarf_read_encoded_pointer (ei->u.memory.as, a, &addr, hdr.eh_frame_ptr_enc, &pi,
                                  &eh_frame_start, ei->u.memory.as_arg) < 0) {
    Debug(1, "Failed to read encoded frame start.\n");
    return false;
  }

  unw_word_t fde_count;
  if (dwarf_read_encoded_pointer (ei->u.memory.as, a, &addr, hdr.fde_count_enc, &pi,
                                  &fde_count, ei->u.memory.as_arg) < 0) {
    Debug(1, "Failed to read fde count.\n");
    return false;
  }

  if (hdr.table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) {
    // Unsupported table format.
    Debug(1, "Unsupported header table format %d\n", hdr.table_enc);
    return false;
  }

  di_cache->u.rti.name_ptr = 0;
  // two 32-bit values (ip_offset/fde_offset) per table-entry:
  di_cache->u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t);

  GET_PHDR_FIELD(ei, phdr_offset, &phdr, p_vaddr);
  GET_PHDR_FIELD(ei, phdr_offset, &phdr, p_offset);
  di_cache->u.rti.table_data =
      load_base + phdr.p_vaddr + addr - (uintptr_t) ei->u.memory.map->start - phdr.p_offset;

  // For the binary-search table in the eh_frame_hdr, data-relative
  // means relative to the start of that section...
  di_cache->u.rti.segbase = ((load_base + phdr.p_vaddr) + (hdr_offset - phdr.p_offset));

  return true;
}

static bool dwarf_find_unwind_table_memory (
    struct elf_dyn_info *edi, struct elf_image *ei, unw_addr_space_t as, char *path,
    unw_word_t segbase, unw_word_t ip) {
  Elf_W(Ehdr) ehdr;
  GET_EHDR_FIELD(ei, &ehdr, e_phoff, false);
  GET_EHDR_FIELD(ei, &ehdr, e_phnum, false);

  Elf_W(Off) offset = ehdr.e_phoff;
  Elf_W(Off) txt_phdr_offset = 0;
  Elf_W(Addr) txt_pvaddr = 0;
  Elf_W(Off) dyn_phdr_offset = 0;
#if UNW_TARGET_ARM
  Elf_W(Off) arm_exidx_phdr_offset = 0;
#endif
  int i;
  unw_word_t start_ip = (unw_word_t) -1;
  unw_word_t end_ip = 0;
  Elf_W(Off) eh_frame_phdr_offset = 0;
  for (i = 0; i < ehdr.e_phnum; ++i) {
    Elf_W(Phdr) phdr;
    GET_PHDR_FIELD(ei, offset, &phdr, p_type);
    switch (phdr.p_type) {
      case PT_LOAD:
        GET_PHDR_FIELD(ei, offset, &phdr, p_vaddr);
        if (phdr.p_vaddr < start_ip) {
          start_ip = phdr.p_vaddr;
        }

        GET_PHDR_FIELD(ei, offset, &phdr, p_memsz);
        if (phdr.p_vaddr + phdr.p_memsz > end_ip) {
          end_ip = phdr.p_vaddr + phdr.p_memsz;
        }

        GET_PHDR_FIELD(ei, offset, &phdr, p_offset);
        /* Always use zero as the map offset to match. The dlopen of a shared
         * library from an APK will result in a non-zero offset so it won't
         * match anything and cause unwinds to fail. There is no case where
         * the ANDROID linker will create an executable map that has a non-zero
         * map offset.
         */
        if (phdr.p_offset == 0) {
          txt_phdr_offset = offset;
          txt_pvaddr = phdr.p_vaddr;
        }
        break;

      case PT_GNU_EH_FRAME:
        eh_frame_phdr_offset = offset;
        break;

      case PT_DYNAMIC:
        dyn_phdr_offset = offset;
        break;

#if UNW_TARGET_ARM
      case PT_ARM_EXIDX:
        arm_exidx_phdr_offset = offset;
        break;
#endif

      default:
        break;
    }
    offset += sizeof(phdr);
  }

  if (txt_phdr_offset == 0) {
    Debug(1, "PT_LOAD section not found.\n");
    return false;
  }

  unw_word_t load_base = segbase - txt_pvaddr;
  start_ip += load_base;
  end_ip += load_base;

  bool found = false;
  if (eh_frame_phdr_offset) {
    // For dynamicly linked executables and shared libraries,
    // DT_PLTGOT is the value that data-relative addresses are
    // relative to for that object.  We call this the "gp".
    // Otherwise this is a static executable with no _DYNAMIC.  Assume
    // that data-relative addresses are relative to 0, i.e.,
    // absolute.
    edi->di_cache.gp = 0;
    if (dyn_phdr_offset) {
      // Ignore failures, we'll attempt to keep going with a zero gp.
      get_dyn_gp(ei, dyn_phdr_offset, &edi->di_cache.gp);
    }

    found = get_eh_frame_info(ei, eh_frame_phdr_offset, load_base, &edi->di_cache);
    if (found) {
      edi->di_cache.start_ip = start_ip;
      edi->di_cache.end_ip = end_ip;
      edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE;
    }
  }

#if UNW_TARGET_ARM
  // Verify that the map contains enough space for the arm unwind data.
  if (arm_exidx_phdr_offset &&
    arm_exidx_phdr_offset + sizeof(Elf_W(Phdr)) < ei->u.memory.map->end - ei->u.memory.map->start) {
    Elf_W(Phdr) phdr;
    GET_PHDR_FIELD(ei, arm_exidx_phdr_offset, &phdr, p_vaddr);
    GET_PHDR_FIELD(ei, arm_exidx_phdr_offset, &phdr, p_memsz);
    edi->di_arm.u.rti.table_data = load_base + phdr.p_vaddr;
    edi->di_arm.u.rti.table_len = phdr.p_memsz;

    edi->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX;
    edi->di_arm.start_ip = start_ip;
    edi->di_arm.end_ip = end_ip;
    edi->di_arm.u.rti.name_ptr = (unw_word_t) path;
    found = true;
  }
#endif

  return found;
}

int
dwarf_find_unwind_table (struct elf_dyn_info *edi, struct elf_image *ei,
			 unw_addr_space_t as, char *path,
			 unw_word_t segbase, unw_word_t ip)
{
  Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL;
  unw_word_t addr, eh_frame_start, fde_count, load_base;
#if 0
  // Not currently used.
  unw_word_t max_load_addr = 0;
#endif
  unw_word_t start_ip = (unw_word_t) -1;
  unw_word_t end_ip = 0;
  struct dwarf_eh_frame_hdr *hdr;
  unw_proc_info_t pi;
  unw_accessors_t *a;
  Elf_W(Ehdr) *ehdr;
#if UNW_TARGET_ARM
  const Elf_W(Phdr) *parm_exidx = NULL;
#endif
  int i, ret, found = 0;

  /* XXX: Much of this code is Linux/LSB-specific.  */

  if (!ei->valid)
    return -UNW_ENOINFO;

  if (!ei->mapped) {
    if (dwarf_find_unwind_table_memory (edi, ei, as, path, segbase, ip)) {
      return 1;
    }
    return -UNW_ENOINFO;
  }

  /* ANDROID support update. */
  ehdr = ei->u.mapped.image;
  phdr = (Elf_W(Phdr) *) ((char *) ei->u.mapped.image + ehdr->e_phoff);
  /* End of ANDROID update. */

  for (i = 0; i < ehdr->e_phnum; ++i)
    {
      switch (phdr[i].p_type)
	{
	case PT_LOAD:
	  if (phdr[i].p_vaddr < start_ip)
	    start_ip = phdr[i].p_vaddr;

	  if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip)
	    end_ip = phdr[i].p_vaddr + phdr[i].p_memsz;

	  /* Always use zero as the map offset to match. The dlopen of a shared
	   * library from an APK will result in a non-zero offset so it won't
	   * match anything and cause unwinds to fail. There is no case where
	   * the ANDROID linker will create an executable map that has a non-zero
	   * map offset.
	   */
	  if (phdr[i].p_offset == 0)
	    ptxt = phdr + i;

#if 0
	  // Not currently used.
	  if ((uintptr_t) ei->u.mapped.image + phdr->p_filesz > max_load_addr)
	    max_load_addr = (uintptr_t) ei->u.mapped.image + phdr->p_filesz;
#endif
	  break;

	case PT_GNU_EH_FRAME:
	  peh_hdr = phdr + i;
	  break;

	case PT_DYNAMIC:
	  pdyn = phdr + i;
	  break;

#if UNW_TARGET_ARM
	case PT_ARM_EXIDX:
	  parm_exidx = phdr + i;
	  break;
#endif

	default:
	  break;
	}
    }

  if (!ptxt)
    return 0;

  load_base = segbase - ptxt->p_vaddr;
  start_ip += load_base;
  end_ip += load_base;

  if (peh_hdr)
    {
      // For dynamicly linked executables and shared libraries,
      // DT_PLTGOT is the value that data-relative addresses are
      // relative to for that object.  We call this the "gp".
      // Otherwise this is a static executable with no _DYNAMIC.  Assume
      // that data-relative addresses are relative to 0, i.e.,
      // absolute.
      edi->di_cache.gp = 0;
      if (pdyn) {
        Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(pdyn->p_offset + (char *) ei->u.mapped.image);
        while ((char*) dyn - (char*) ei->u.mapped.image + sizeof(Elf_W(Dyn)) < ei->u.mapped.size
               && dyn->d_tag != DT_NULL) {
          if (dyn->d_tag == DT_PLTGOT) {
            // Assume that _DYNAMIC is writable and GLIBC has
            // relocated it (true for x86 at least).
            edi->di_cache.gp = dyn->d_un.d_ptr;
            break;
          }
          dyn++;
        }
      }

      /* ANDROID support update. */
      hdr = (struct dwarf_eh_frame_hdr *) (peh_hdr->p_offset
					   + (char *) ei->u.mapped.image);
      /* End of ANDROID update. */
      if (hdr->version != DW_EH_VERSION)
	{
	  Debug (1, "table `%s' has unexpected version %d\n",
		 path, hdr->version);
	  return -UNW_ENOINFO;
	}

      a = unw_get_accessors (unw_local_addr_space);
      /* ANDROID support update. */
      addr = (unw_word_t) (uintptr_t) (hdr + 1);
      /* End of ANDROID update. */

      /* Fill in a dummy proc_info structure.  We just need to fill in
	 enough to ensure that dwarf_read_encoded_pointer() can do its
	 job.  Since we don't have a procedure-context at this point, all
	 we have to do is fill in the global-pointer.  */
      memset (&pi, 0, sizeof (pi));
      pi.gp = edi->di_cache.gp;

      if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
					     &addr, hdr->eh_frame_ptr_enc, &pi,
					     &eh_frame_start, NULL)) < 0)
	return -UNW_ENOINFO;

      if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
					     &addr, hdr->fde_count_enc, &pi,
					     &fde_count, NULL)) < 0)
	return -UNW_ENOINFO;

      if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4))
	{
#if 1
          // Right now do nothing.
	  //abort ();
#else
	  unw_word_t eh_frame_end;

	  /* If there is no search table or it has an unsupported
	     encoding, fall back on linear search.  */
	  if (hdr->table_enc == DW_EH_PE_omit)
	    Debug (4, "EH lacks search table; doing linear search\n");
	  else
	    Debug (4, "EH table has encoding 0x%x; doing linear search\n",
		   hdr->table_enc);

	  eh_frame_end = max_load_addr;	/* XXX can we do better? */

	  if (hdr->fde_count_enc == DW_EH_PE_omit)
	    fde_count = ~0UL;
	  if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit)
	    abort ();

	  return linear_search (unw_local_addr_space, ip,
				eh_frame_start, eh_frame_end, fde_count,
				pi, need_unwind_info, NULL);
#endif
	}
      else
        {
          edi->di_cache.start_ip = start_ip;
          edi->di_cache.end_ip = end_ip;
          edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE;
          edi->di_cache.u.rti.name_ptr = 0;
          /* two 32-bit values (ip_offset/fde_offset) per table-entry: */
          edi->di_cache.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t);
          /* ANDROID support update. */
          edi->di_cache.u.rti.table_data = ((load_base + peh_hdr->p_vaddr)
                                           + (addr - (uintptr_t) ei->u.mapped.image
                                           - peh_hdr->p_offset));
          /* End of ANDROID update. */

          /* For the binary-search table in the eh_frame_hdr, data-relative
             means relative to the start of that section... */

          /* ANDROID support update. */
          edi->di_cache.u.rti.segbase = ((load_base + peh_hdr->p_vaddr)
                                        + ((uintptr_t) hdr - (uintptr_t) ei->u.mapped.image
                                        - peh_hdr->p_offset));
          /* End of ANDROID update. */
          found = 1;
        }
    }

#if UNW_TARGET_ARM
  if (parm_exidx)
    {
      edi->di_arm.format = UNW_INFO_FORMAT_ARM_EXIDX;
      edi->di_arm.start_ip = start_ip;
      edi->di_arm.end_ip = end_ip;
      edi->di_arm.u.rti.name_ptr = (unw_word_t) path;
      edi->di_arm.u.rti.table_data = load_base + parm_exidx->p_vaddr;
      edi->di_arm.u.rti.table_len = parm_exidx->p_memsz;
      found = 1;
    }
#endif

#ifdef CONFIG_DEBUG_FRAME
  /* Try .debug_frame. */
  found = dwarf_find_debug_frame (found, &edi->di_debug, ip, load_base, path,
				  start_ip, end_ip);
#endif

  return found;
}
