/* 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.map->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);

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];
  struct map_info* map = ei->u.memory.map;
  if (SELFMAG != elf_w (memory_read) (ei, map->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, map->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;

  // 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.map = map;
        map->ei.u.memory.as = as;
        map->ei.u.memory.as_arg = as_arg;
        map->ei.valid = elf_w (valid_object_memory) (&map->ei);
      }
    }
    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;
}
