// 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.

// TODO: Taken from crashlogger. Revisit.

#include <fcntl.h>
#include <link.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <zircon/syscalls.h>
#include <zircon/types.h>

#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/strings/string_printf.h"

#include "dso_list.h"
#include "util.h"

namespace debugger_utils {

const char kDebugDirectory[] = "/boot/debug";
const char kDebugSuffix[] = ".debug";

static dsoinfo_t* dsolist_add(dsoinfo_t** list, const char* name,
                              uintptr_t base) {
  size_t len = strlen(name);
  size_t alloc_bytes = sizeof(dsoinfo_t) + len + 1;
  auto dso = reinterpret_cast<dsoinfo_t*>(calloc(1, alloc_bytes));
  if (dso == nullptr) {
    FXL_LOG(FATAL) << "OOM allocating " << alloc_bytes << " bytes";
    exit(1);
  }
  memcpy(dso->name, name, len + 1);
  memset(dso->buildid, 'x', sizeof(dso->buildid) - 1);
  dso->base = base;
  dso->debug_file_tried = false;
  dso->debug_file_status = ZX_ERR_BAD_STATE;
  while (*list != nullptr) {
    if ((*list)->base < dso->base) {
      dso->next = *list;
      *list = dso;
      return dso;
    }
    list = &((*list)->next);
  }
  *list = dso;
  dso->next = nullptr;
  return dso;
}

dsoinfo_t* dso_fetch_list(std::shared_ptr<ByteBlock> bb, zx_vaddr_t lmap_addr,
                          const char* name) {
  dsoinfo_t* dsolist = nullptr;
  // The first dso we see is the main executable.
  bool is_main_exec = true;

  while (lmap_addr != 0) {
    char dsoname[64];
    struct link_map lmap;

    // If there's a failure here, say because the internal data structures got
    // corrupted, just bail and return what we've collected so far.

    if (!bb->Read(lmap_addr, &lmap, sizeof(lmap)))
      break;
    if (!ReadString(*bb, reinterpret_cast<zx_vaddr_t>(lmap.l_name), dsoname,
                    sizeof(dsoname)))
      break;

    const char* file_name = dsoname[0] ? dsoname : name;
    dsoinfo_t* dso = dsolist_add(&dsolist, file_name, lmap.l_addr);

    std::unique_ptr<ElfReader> elf_reader;
    ElfError rc = ElfReader::Create(file_name, bb, 0, dso->base, &elf_reader);
    if (rc != ElfError::OK) {
      FXL_LOG(ERROR) << "Unable to read ELF file: " << file_name
                     << ": " << ElfErrorName(rc);
      break;
    }

    auto hdr = elf_reader->header();
    rc = elf_reader->ReadSegmentHeaders();
    if (rc != ElfError::OK) {
      FXL_LOG(ERROR) << "Error reading ELF segment headers: "
                     << ElfErrorName(rc);
    } else {
      size_t num_segments = elf_reader->GetNumSegments();
      uint32_t num_loadable_phdrs = 0;
      for (size_t i = 0; i < num_segments; ++i) {
        const ElfSegmentHeader& phdr = elf_reader->GetSegmentHeader(i);
        if (phdr.p_type == PT_LOAD)
          ++num_loadable_phdrs;
      }
      // malloc may, or may not, return NULL for a zero byte request.
      // Remove the ambiguity for consumers and always use NULL if there no
      // loadable phdrs.
      ElfSegmentHeader* loadable_phdrs = NULL;
      if (num_loadable_phdrs > 0) {
        loadable_phdrs = reinterpret_cast<ElfSegmentHeader*>(
            malloc(num_loadable_phdrs * hdr.e_phentsize));
      }
      if (loadable_phdrs || num_loadable_phdrs == 0) {
        size_t j = 0;
        for (size_t i = 0; i < num_segments; ++i) {
          const ElfSegmentHeader& phdr = elf_reader->GetSegmentHeader(i);
          if (phdr.p_type == PT_LOAD)
            loadable_phdrs[j++] = phdr;
        }
        FXL_DCHECK(j == num_loadable_phdrs);
        dso->num_loadable_phdrs = num_loadable_phdrs;
        dso->loadable_phdrs = loadable_phdrs;
      } else {
        FXL_LOG(ERROR) << "OOM reading phdrs";
      }
    }

    rc = elf_reader->ReadBuildId(dso->buildid, sizeof(dso->buildid));
    if (rc != ElfError::OK) {
      // This isn't fatal so don't flag as an error.
      FXL_VLOG(1) << "Unable to read build id: " << ElfErrorName(rc);
    }

    dso->is_main_exec = is_main_exec;
    dso->entry = dso->base + hdr.e_entry;
    dso->phdr = dso->base + hdr.e_phoff;
    dso->phentsize = hdr.e_phentsize;
    dso->phnum = hdr.e_phnum;

    is_main_exec = false;
    lmap_addr = reinterpret_cast<zx_vaddr_t>(lmap.l_next);
  }

  return dsolist;
}

void dso_free_list(dsoinfo_t* list) {
  while (list != nullptr) {
    dsoinfo_t* next = list->next;
    free(list->loadable_phdrs);
    free(list->debug_file);
    free(list);
    list = next;
  }
}

dsoinfo_t* dso_lookup(dsoinfo_t* dso_list, zx_vaddr_t pc) {
  for (auto dso = dso_list; dso != nullptr; dso = dso->next) {
    if (pc >= dso->base)
      return dso;
  }

  return nullptr;
}

dsoinfo_t* dso_get_main_exec(dsoinfo_t* dso_list) {
  for (auto dso = dso_list; dso != nullptr; dso = dso->next) {
    if (dso->is_main_exec)
      return dso;
  }

  return nullptr;
}

void dso_print_list(FILE* out, const dsoinfo_t* dso_list) {
  for (auto dso = dso_list; dso != nullptr; dso = dso->next) {
    fprintf(out, "dso: id=%s base=%p name=%s\n", dso->buildid, (void*)dso->base,
            dso->name);
  }
}

void dso_vlog_list(const dsoinfo_t* dso_list) {
  for (auto dso = dso_list; dso != nullptr; dso = dso->next) {
    FXL_VLOG(2) << fxl::StringPrintf("dso: id=%s base=%p name=%s", dso->buildid,
                                     (void*)dso->base, dso->name);
  }
}

zx_status_t dso_find_debug_file(dsoinfo_t* dso, const char** out_debug_file) {
  // Have we already tried?
  // Yeah, if we OOM it's possible it'll succeed next time, but
  // it's not worth the extra complexity to avoid printing the debugging
  // messages twice.
  if (dso->debug_file_tried) {
    switch (dso->debug_file_status) {
      case ZX_OK:
        FXL_DCHECK(dso->debug_file != nullptr);
        *out_debug_file = dso->debug_file;
      // fall through
      default:
        FXL_VLOG(2) << "returning " << dso->debug_file_status
                    << ", already tried to find debug file for " << dso->name;
        return dso->debug_file_status;
    }
  }

  dso->debug_file_tried = true;

  char* path;
  if (asprintf(&path, "%s/%s%s", kDebugDirectory, dso->buildid, kDebugSuffix) <
      0) {
    FXL_VLOG(1) << "OOM building debug file path for dso " << dso->name;
    dso->debug_file_status = ZX_ERR_NO_MEMORY;
    return dso->debug_file_status;
  }

  FXL_VLOG(1) << "looking for debug file " << path;

  int fd = open(path, O_RDONLY);
  if (fd < 0) {
    FXL_VLOG(1) << "debug file for dso " << dso->name << " not found: " << path;
    free(path);
    dso->debug_file_status = ZX_ERR_NOT_FOUND;
  } else {
    FXL_VLOG(1) << "found debug file for dso " << dso->name << ": " << path;
    close(fd);
    dso->debug_file = path;
    *out_debug_file = path;
    dso->debug_file_status = ZX_OK;
  }

  return dso->debug_file_status;
}

}  // namespace debugger_utils
