// Copyright 2017 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 "load_maps.h"

#include <cinttypes>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>

#include <lib/fit/defer.h>

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

#include "util.h"

namespace debugger_utils {

bool LoadMapTable::ReadLogListenerOutput(const std::string& file) {
  FXL_LOG(INFO) << "Loading load maps from " << file;

  FILE* f = fopen(file.c_str(), "r");
  if (!f) {
    FXL_LOG(ERROR) << "error opening file, " << ErrnoString(errno);
    return false;
  }
  auto close_file = fit::defer([&]() { fclose(f); });

  constexpr size_t kMaxLineLen = 1024;
  char* line = nullptr;
  size_t line_capacity = 0;
  int lineno = 1;

  std::map<uint64_t, LoadMap> map_data;
  ssize_t line_len;

  // These buffers are needed to break out elements of the line. Rather than
  // allocate space for them during each iteration we allocate them here.
  // And rather than use up a fair bit of stack, we use the heap.
  char* prefix = reinterpret_cast<char*>(malloc(kMaxLineLen));
  char* build_id = reinterpret_cast<char*>(malloc(kMaxLineLen));
  char* name = reinterpret_cast<char*>(malloc(kMaxLineLen));
  char* so_name = reinterpret_cast<char*>(malloc(kMaxLineLen));

  auto free_mem = fit::defer([&]() {
    free(line);
    free(prefix);
    free(build_id);
    free(name);
    free(so_name);
  });

  if (!prefix || !build_id || !name || !so_name) {
    FXL_LOG(ERROR) << "Out of memory";
    return false;
  }

  for (; (line_len = getline(&line, &line_capacity, f)) > 0; ++lineno) {
    // For paranoia's sake, watch for embedded NULs.
    size_t n = strlen(line);
    if (static_cast<ssize_t>(n) != line_len) {
      FXL_LOG(WARNING) << "Line contains embedded NULs: "
                       << std::string(line, line_len);
      continue;
    }
    if (n > 0 && line[n - 1] == '\n')
      line[n - 1] = '\0';
    FXL_VLOG(2) << fxl::StringPrintf("%d: %s", lineno, line);

    if (n > kMaxLineLen) {
      FXL_VLOG(2) << fxl::StringPrintf("%d: too long, ignoring", lineno);
    }

    if (!strcmp(line, "\n"))
      continue;
    if (line[0] == '#')
      continue;

    // If this is a new boot, start over.
    if (strstr(line, "welcome to Zircon")) {
      FXL_VLOG(1) << "Restarting reading of load maps, machine rebooted";
      map_data.clear();
      Clear();
      continue;
    }

    // The sequence number is used for grouping records, done beforehand, but
    // is no longer needed after that.
    unsigned seqno;
    uint64_t pid, base_addr, load_addr, end_addr;

    // ld.so dumps the data in three separate records to avoid line-wrapping:
    // a: base load end
    // b: build_id
    // c: name so_name
    // TODO(dje): See MG-519. This is a temp hack until ld.so logs this data
    // via something better.

#define GET_ENTRY_ID(pid, seqno) (((pid) << 8) + (seqno))

    if (sscanf(line,
               "%[^@]@trace_load: %" PRIu64 ":%ua"
               " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64,
               prefix, &pid, &seqno, &base_addr, &load_addr, &end_addr) == 6) {
      uint64_t id = GET_ENTRY_ID(pid, seqno);
      if (map_data.find(id) != map_data.end()) {
        FXL_LOG(ERROR) << "Already have map entry for: " << line;
        continue;
      }
      struct LoadMap entry;
      entry.pid = pid;
      entry.base_addr = base_addr;
      entry.load_addr = load_addr;
      entry.end_addr = end_addr;
      map_data[id] = entry;
    } else if (sscanf(line,
                      "%[^@]@trace_load: %" PRIu64 ":%ub"
                      " %s",
                      prefix, &pid, &seqno, build_id) == 4) {
      uint64_t id = GET_ENTRY_ID(pid, seqno);
      auto entry_iter = map_data.find(id);
      if (entry_iter == map_data.end()) {
        FXL_LOG(ERROR) << "Missing entry (A record) for: " << line;
        continue;
      }
      (*entry_iter).second.build_id = build_id;
    } else if (sscanf(line,
                      "%[^@]@trace_load: %" PRIu64 ":%uc"
                      " %s %s",
                      prefix, &pid, &seqno, name, so_name) == 5) {
      uint64_t id = GET_ENTRY_ID(pid, seqno);
      auto entry_iter = map_data.find(id);
      if (entry_iter == map_data.end()) {
        FXL_LOG(ERROR) << "Missing entry (A record) for: " << line;
        continue;
      }
      LoadMap& entry = (*entry_iter).second;
      entry.name = name;
      entry.so_name = so_name;
      // We should now have the full record.
      AddLoadMap(entry);
    } else {
      FXL_VLOG(2) << fxl::StringPrintf("%d: ignoring", lineno);
    }
  }

  if (!feof(f)) {
    FXL_LOG(ERROR) << "Error reading file";
    return false;
  }

  return true;
}

void LoadMapTable::AddLoadMap(const LoadMap& map) {
  FXL_VLOG(2) << fxl::StringPrintf(
      "Adding map entry, pid %" PRIu64 " %s 0x%" PRIx64 "-0x%" PRIx64, map.pid,
      map.name.c_str(), map.load_addr, map.end_addr);
  maps_.push_back(map);
}

void LoadMapTable::Clear() { maps_.clear(); }

const LoadMap* LoadMapTable::LookupLoadMap(zx_koid_t pid, uint64_t addr) {
  for (auto& m : maps_) {
    if (pid == m.pid && addr >= m.load_addr && addr < m.end_addr)
      return &m;
  }

  return nullptr;
}

}  // namespace debugger_utils
