/* libunwind - a platform-independent unwind library
   Copyright (C) 2003, 2005 Hewlett-Packard Co
   Copyright (C) 2007 David Mosberger-Tang
	Contributed by David Mosberger-Tang <dmosberger@gmail.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 <stddef.h>
#include <unistd.h>

#include <sys/mman.h>
#include <sys/stat.h>

#include "libunwind_i.h"
#include "map_info.h"

#if ELF_CLASS == ELFCLASS32
# define ELF_W(x)	ELF32_##x
# define Elf_W(x)	Elf32_##x
# define elf_w(x)	_Uelf32_##x
#else
# define ELF_W(x)	ELF64_##x
# define Elf_W(x)	Elf64_##x
# define elf_w(x)	_Uelf64_##x
#endif

#define GET_FIELD(ei, offset, struct_name, elf_struct, field, check_cached) \
  { \
    if (!check_cached || (elf_struct)->field == 0) { \
      if (sizeof((elf_struct)->field) != elf_w (memory_read) ( \
          ei, ei->u.memory.start + offset + offsetof(struct_name, field), \
          (uint8_t*) &((elf_struct)->field), sizeof((elf_struct)->field), false)) { \
        return false; \
      } \
    } \
  }

#define GET_EHDR_FIELD(ei, ehdr, field, check_cached) \
  GET_FIELD(ei, 0, Elf_W(Ehdr), ehdr, field, check_cached)

#define GET_PHDR_FIELD(ei, offset, phdr, field) \
  GET_FIELD(ei, offset, Elf_W(Phdr), phdr, field, false)

#define GET_SHDR_FIELD(ei, offset, shdr, field) \
  GET_FIELD(ei, offset, Elf_W(Shdr), shdr, field, false)

#define GET_SYM_FIELD(ei, offset, sym, field) \
  GET_FIELD(ei, offset, Elf_W(Sym), sym, field, false)

#define GET_DYN_FIELD(ei, offset, dyn, field) \
  GET_FIELD(ei, offset, Elf_W(Dyn), dyn, field, false)

extern bool elf_w (get_proc_name) (
    unw_addr_space_t as, pid_t pid, unw_word_t ip, char* buf, size_t len,
    unw_word_t* offp, void* as_arg);

extern bool elf_w (get_proc_name_in_image) (
    unw_addr_space_t as, struct elf_image* ei, unsigned long segbase,
    unsigned long mapoff, unw_word_t ip, char* buf, size_t buf_len, unw_word_t* offp);

extern bool elf_w (get_load_base) (struct elf_image* ei, unw_word_t mapoff, unw_word_t* load_base);

extern size_t elf_w (memory_read) (
    struct elf_image* ei, unw_word_t addr, uint8_t* buffer, size_t bytes, bool string_read);

extern bool elf_w (xz_decompress) (uint8_t* src, size_t src_size,
                                   uint8_t** dst, size_t* dst_size);

extern bool elf_w (find_section_mapped) (struct elf_image *ei, const char* name,
                                         uint8_t** section, size_t* size, Elf_W(Addr)* vaddr);

static inline bool elf_w (valid_object_mapped) (struct elf_image* ei) {
  if (ei->u.mapped.size <= EI_VERSION) {
    return false;
  }

  uint8_t* e_ident = (uint8_t*) ei->u.mapped.image;
  return (memcmp (ei->u.mapped.image, ELFMAG, SELFMAG) == 0
          && e_ident[EI_CLASS] == ELF_CLASS && e_ident[EI_VERSION] != EV_NONE
          && e_ident[EI_VERSION] <= EV_CURRENT);
}

static inline bool elf_w (valid_object_memory) (struct elf_image* ei) {
  uint8_t e_ident[EI_NIDENT];
  uintptr_t start = ei->u.memory.start;
  if (SELFMAG != elf_w (memory_read) (ei, start, e_ident, SELFMAG, false)) {
    return false;
  }
  if (memcmp (e_ident, ELFMAG, SELFMAG) != 0) {
    return false;
  }
  // Read the rest of the ident data.
  if (EI_NIDENT - SELFMAG != elf_w (memory_read) (
      ei, start + SELFMAG, e_ident + SELFMAG, EI_NIDENT - SELFMAG, false)) {
    return false;
  }
  return e_ident[EI_CLASS] == ELF_CLASS && e_ident[EI_VERSION] != EV_NONE
         && e_ident[EI_VERSION] <= EV_CURRENT;
}

static inline bool elf_map_image (struct elf_image* ei, const char* path) {
  struct stat stat;
  int fd;

  fd = open (path, O_RDONLY);
  if (fd < 0) {
    return false;
  }

  if (fstat (fd, &stat) == -1) {
    close (fd);
    return false;
  }

  ei->u.mapped.size = stat.st_size;
  ei->u.mapped.image = mmap (NULL, ei->u.mapped.size, PROT_READ, MAP_PRIVATE, fd, 0);
  close (fd);
  if (ei->u.mapped.image == MAP_FAILED) {
    return false;
  }

  ei->valid = elf_w (valid_object_mapped) (ei);
  if (!ei->valid) {
    munmap (ei->u.mapped.image, ei->u.mapped.size);
    return false;
  }

  ei->mapped = true;
  // Set to true for cases where this is called outside of elf_map_cached.
  ei->load_attempted = true;

  return true;
}

static inline bool elf_map_cached_image (
    unw_addr_space_t as, void* as_arg, struct map_info* map, unw_word_t ip) {
  intrmask_t saved_mask;

  // Don't even try and cache this unless the map is readable and executable.
  if ((map->flags & (PROT_READ | PROT_EXEC)) != (PROT_READ | PROT_EXEC)) {
    return false;
  }

  // Do not try and cache the map if it's a file from /dev/ that is not
  // /dev/ashmem/.
  if (map->path != NULL && strncmp ("/dev/", map->path, 5) == 0
      && strncmp ("ashmem/", map->path + 5, 7) != 0) {
    return false;
  }

  // Lock while loading the cached elf image.
  lock_acquire (&map->ei_lock, saved_mask);
  if (!map->ei.load_attempted) {
    map->ei.load_attempted = true;

    if (!elf_map_image (&map->ei, map->path)) {
      // If the image cannot be loaded, we'll read data directly from
      // the process using the access_mem function.
      if (map->flags & PROT_READ) {
        map->ei.u.memory.start = map->start;
        map->ei.u.memory.end = map->end;
        map->ei.u.memory.as = as;
        map->ei.u.memory.as_arg = as_arg;
        map->ei.valid = elf_w (valid_object_memory) (&map->ei);
      }
    } else {
      // Try to cache the minidebuginfo data.
      uint8_t *compressed = NULL;
      size_t compressed_len;
      if (elf_w (find_section_mapped) (&map->ei, ".gnu_debugdata", &compressed,
          &compressed_len, NULL)) {
        if (elf_w (xz_decompress) (compressed, compressed_len,
            (uint8_t**) &map->ei.mini_debug_info_data, &map->ei.mini_debug_info_size)) {
          Debug (1, "Decompressed and cached .gnu_debugdata");
        } else {
          map->ei.mini_debug_info_data = NULL;
          map->ei.mini_debug_info_size = 0;
        }
      }
    }
    unw_word_t load_base;
    if (map->ei.valid && elf_w (get_load_base) (&map->ei, map->offset, &load_base)) {
      map->load_base = load_base;
    }
  }
  lock_release (&map->ei_lock, saved_mask);
  return map->ei.valid;
}
