// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <elf.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/status.h>

#include "inspector/inspector.h"
#include "utils-impl.h"

namespace inspector {

int verbosity_level = 0;

extern "C" __EXPORT void inspector_set_verbosity(int level) { verbosity_level = level; }

// Same as basename, except will not modify |path|.
// Returns "" if |path| has a trailing /.

const char* path_basename(const char* path) {
  const char* base = strrchr(path, '/');
  if (base == nullptr)
    return path;
  return base + 1;
}

void do_print_debug(const char* file, int line, const char* func, const char* fmt, ...) {
  fflush(stdout);
  const char* base = path_basename(file);
  va_list args;
  va_start(args, fmt);
  fprintf(stderr, "%s:%d: %s: ", base, line, func);
  vfprintf(stderr, fmt, args);
  va_end(args);
  fflush(stderr);  // TODO: output is getting lost
}

void do_print_error(const char* file, int line, const char* fmt, ...) {
  const char* base = path_basename(file);
  va_list args;
  va_start(args, fmt);
  fprintf(stderr, "inspector: %s:%d: ", base, line);
  vfprintf(stderr, fmt, args);
  fprintf(stderr, "\n");
  va_end(args);
}

void do_print_zx_error(const char* file, int line, const char* what, zx_status_t status) {
  do_print_error(file, line, "%s: %d (%s)", what, status, zx_status_get_string(status));
}

zx_status_t read_mem(zx_handle_t h, zx_vaddr_t vaddr, void* ptr, size_t len) {
  size_t actual;
  zx_status_t status = zx_process_read_memory(h, vaddr, ptr, len, &actual);
  if (status < 0) {
    printf("read_mem @%p FAILED %zd\n", (void*)vaddr, len);
    return status;
  }
  if (len != actual) {
    printf("read_mem @%p FAILED, short read %zd\n", (void*)vaddr, len);
    return ZX_ERR_IO;
  }
  return ZX_OK;
}

zx_status_t fetch_string(zx_handle_t h, zx_vaddr_t vaddr, char* ptr, size_t max) {
  while (max > 1) {
    zx_status_t status;
    if ((status = read_mem(h, vaddr, ptr, 1)) < 0) {
      *ptr = 0;
      return status;
    }
    ptr++;
    vaddr++;
    max--;
  }
  *ptr = 0;
  return ZX_OK;
}

#if UINT_MAX == ULONG_MAX

#define ehdr_off_phoff offsetof(Elf32_Ehdr, e_phoff)
#define ehdr_off_phnum offsetof(Elf32_Ehdr, e_phnum)

#define phdr_off_type offsetof(Elf32_Phdr, p_type)
#define phdr_off_offset offsetof(Elf32_Phdr, p_offset)
#define phdr_off_filesz offsetof(Elf32_Phdr, p_filesz)

typedef Elf32_Half elf_half_t;
typedef Elf32_Off elf_off_t;
// ELF used "word" for 32 bits, sigh.
typedef Elf32_Word elf_word_t;
typedef Elf32_Word elf_native_word_t;
typedef Elf32_Phdr elf_phdr_t;

#else

#define ehdr_off_phoff offsetof(Elf64_Ehdr, e_phoff)
#define ehdr_off_phnum offsetof(Elf64_Ehdr, e_phnum)

#define phdr_off_type offsetof(Elf64_Phdr, p_type)
#define phdr_off_offset offsetof(Elf64_Phdr, p_offset)
#define phdr_off_filesz offsetof(Elf64_Phdr, p_filesz)

typedef Elf64_Half elf_half_t;
typedef Elf64_Off elf_off_t;
typedef Elf64_Word elf_word_t;
typedef Elf64_Xword elf_native_word_t;
typedef Elf64_Phdr elf_phdr_t;

#endif

zx_status_t fetch_build_id(zx_handle_t h, zx_vaddr_t base, char* buf, size_t buf_size) {
  zx_vaddr_t vaddr = base;
  uint8_t tmp[4];
  zx_status_t status;

  if (buf_size < MAX_BUILDID_SIZE * 2 + 1)
    return ZX_ERR_INVALID_ARGS;

  status = read_mem(h, vaddr, tmp, 4);
  if (status != ZX_OK)
    return status;
  if (memcmp(tmp, ELFMAG, SELFMAG))
    return ZX_ERR_WRONG_TYPE;

  elf_off_t phoff;
  elf_half_t num;
  status = read_mem(h, vaddr + ehdr_off_phoff, &phoff, sizeof(phoff));
  if (status != ZX_OK)
    return status;
  status = read_mem(h, vaddr + ehdr_off_phnum, &num, sizeof(num));
  if (status != ZX_OK)
    return status;

  for (unsigned n = 0; n < num; n++) {
    zx_vaddr_t phaddr = vaddr + phoff + (n * sizeof(elf_phdr_t));
    elf_word_t type;
    status = read_mem(h, phaddr + phdr_off_type, &type, sizeof(type));
    if (status != ZX_OK)
      return status;
    if (type != PT_NOTE)
      continue;

    elf_off_t off;
    elf_native_word_t size;
    status = read_mem(h, phaddr + phdr_off_offset, &off, sizeof(off));
    if (status != ZX_OK)
      return status;
    status = read_mem(h, phaddr + phdr_off_filesz, &size, sizeof(size));
    if (status != ZX_OK)
      return status;

    struct {
      Elf32_Nhdr hdr;
      char name[sizeof("GNU")];
    } hdr;
    while (size > sizeof(hdr)) {
      status = read_mem(h, vaddr + off, &hdr, sizeof(hdr));
      if (status != ZX_OK)
        return status;
      size_t header_size = sizeof(Elf32_Nhdr) + ((hdr.hdr.n_namesz + 3) & -4);
      size_t payload_size = (hdr.hdr.n_descsz + 3) & -4;
      off += header_size;
      size -= header_size;
      zx_vaddr_t payload_vaddr = vaddr + off;
      off += payload_size;
      size -= payload_size;
      if (hdr.hdr.n_type != NT_GNU_BUILD_ID || hdr.hdr.n_namesz != sizeof("GNU") ||
          memcmp(hdr.name, "GNU", sizeof("GNU")) != 0) {
        continue;
      }
      if (hdr.hdr.n_descsz > MAX_BUILDID_SIZE) {
        snprintf(buf, buf_size, "build_id_too_large_%u", hdr.hdr.n_descsz);
      } else {
        uint8_t buildid[MAX_BUILDID_SIZE];
        status = read_mem(h, payload_vaddr, buildid, hdr.hdr.n_descsz);
        if (status != ZX_OK)
          return status;
        for (uint32_t i = 0; i < hdr.hdr.n_descsz; ++i) {
          snprintf(&buf[i * 2], 3, "%02x", buildid[i]);
        }
      }
      return ZX_OK;
    }
  }

  return ZX_ERR_NOT_FOUND;
}

}  // namespace inspector
