/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "tools/trace_to_text/symbolize_profile.h"

#include <map>
#include <set>
#include <string>
#include <vector>

#include <elf.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "perfetto/protozero/proto_utils.h"

#include "perfetto/base/logging.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/pipe.h"
#include "perfetto/ext/base/string_splitter.h"
#include "perfetto/ext/base/utils.h"

#include "tools/trace_to_text/utils.h"

#include "perfetto/trace/profiling/profile_common.pb.h"
#include "perfetto/trace/profiling/profile_packet.pb.h"
#include "perfetto/trace/trace.pbzero.h"
#include "perfetto/trace/trace_packet.pb.h"

#include "perfetto/trace/interned_data/interned_data.pb.h"

namespace perfetto {
namespace trace_to_text {
namespace {

using ::protozero::proto_utils::kMessageLengthFieldSize;
using ::protozero::proto_utils::MakeTagLengthDelimited;
using ::protozero::proto_utils::WriteVarInt;

using ::perfetto::protos::Frame;
using ::perfetto::protos::InternedData;
using ::perfetto::protos::InternedString;
using ::perfetto::protos::Mapping;
using ::perfetto::protos::ProfilePacket;

class Subprocess {
 public:
  Subprocess(const std::string& file, std::vector<std::string> args)
      : input_pipe_(base::Pipe::Create(base::Pipe::kBothBlock)),
        output_pipe_(base::Pipe::Create(base::Pipe::kBothBlock)) {
    std::vector<char*> c_str_args(args.size() + 1, nullptr);
    for (std::string& arg : args)
      c_str_args.push_back(&(arg[0]));

    if ((pid_ = fork()) == 0) {
      // Child
      PERFETTO_CHECK(dup2(*input_pipe_.rd, STDIN_FILENO) != -1);
      PERFETTO_CHECK(dup2(*output_pipe_.wr, STDOUT_FILENO) != -1);
      input_pipe_.wr.reset();
      output_pipe_.rd.reset();
      PERFETTO_CHECK(execvp(file.c_str(), &(c_str_args[0])) != -1);
    }
    PERFETTO_CHECK(pid_ != -1);
    input_pipe_.rd.reset();
    output_pipe_.wr.reset();
  }

  ~Subprocess() {
    if (pid_ != -1) {
      kill(pid_, SIGKILL);
      int wstatus;
      waitpid(pid_, &wstatus, 0);
    }
  }

  int read_fd() { return output_pipe_.rd.get(); }
  int write_fd() { return input_pipe_.wr.get(); }

 private:
  base::Pipe input_pipe_;
  base::Pipe output_pipe_;

  pid_t pid_ = -1;
};

std::vector<std::string> GetLines(FILE* f) {
  std::vector<std::string> lines;
  size_t n = 0;
  char* line = nullptr;
  ssize_t rd = 0;
  do {
    rd = getline(&line, &n, f);
    // Do not read empty line that terminates the output.
    if (rd > 1) {
      // Remove newline character.
      PERFETTO_DCHECK(line[rd - 1] == '\n');
      line[rd - 1] = '\0';
      lines.emplace_back(line);
    }
    free(line);
    line = nullptr;
    n = 0;
  } while (rd > 1);
  return lines;
};

struct Elf32 {
  using Ehdr = Elf32_Ehdr;
  using Shdr = Elf32_Shdr;
  using Nhdr = Elf32_Nhdr;
};

struct Elf64 {
  using Ehdr = Elf64_Ehdr;
  using Shdr = Elf64_Shdr;
  using Nhdr = Elf64_Nhdr;
};

template <typename E>
typename E::Shdr* GetShdr(void* mem, const typename E::Ehdr* ehdr, size_t i) {
  return reinterpret_cast<typename E::Shdr*>(
      static_cast<char*>(mem) + ehdr->e_shoff + i * sizeof(typename E::Shdr));
}

bool InRange(const void* base,
             size_t total_size,
             const void* ptr,
             size_t size) {
  return ptr >= base && static_cast<const char*>(ptr) + size <=
                            static_cast<const char*>(base) + total_size;
}

template <typename E>
base::Optional<std::string> GetBuildId(void* mem, size_t size) {
  const typename E::Ehdr* ehdr = static_cast<typename E::Ehdr*>(mem);
  if (!InRange(mem, size, ehdr, sizeof(typename E::Ehdr))) {
    PERFETTO_ELOG("Corrupted ELF.");
    return base::nullopt;
  }
  for (size_t i = 0; i < ehdr->e_shnum; ++i) {
    typename E::Shdr* shdr = GetShdr<E>(mem, ehdr, i);
    if (!InRange(mem, size, shdr, sizeof(typename E::Shdr))) {
      PERFETTO_ELOG("Corrupted ELF.");
      return base::nullopt;
    }

    if (shdr->sh_type != SHT_NOTE)
      continue;

    auto offset = shdr->sh_offset;
    while (offset < shdr->sh_offset + shdr->sh_size) {
      typename E::Nhdr* nhdr =
          reinterpret_cast<typename E::Nhdr*>(static_cast<char*>(mem) + offset);

      if (!InRange(mem, size, nhdr, sizeof(typename E::Nhdr))) {
        PERFETTO_ELOG("Corrupted ELF.");
        return base::nullopt;
      }
      if (nhdr->n_type == NT_GNU_BUILD_ID && nhdr->n_namesz == 4) {
        char* name = reinterpret_cast<char*>(nhdr) + sizeof(*nhdr);
        if (!InRange(mem, size, name, 4)) {
          PERFETTO_ELOG("Corrupted ELF.");
          return base::nullopt;
        }
        if (memcmp(name, "GNU", 3) == 0) {
          const char* value = reinterpret_cast<char*>(nhdr) + sizeof(*nhdr) +
                              base::AlignUp<4>(nhdr->n_namesz);

          if (!InRange(mem, size, value, nhdr->n_descsz)) {
            PERFETTO_ELOG("Corrupted ELF.");
            return base::nullopt;
          }
          return std::string(value, nhdr->n_descsz);
        }
      }
      offset += sizeof(*nhdr) + base::AlignUp<4>(nhdr->n_namesz) +
                base::AlignUp<4>(nhdr->n_descsz);
    }
  }
  return base::nullopt;
}

class ScopedMmap {
 public:
  ScopedMmap(void* addr,
             size_t length,
             int prot,
             int flags,
             int fd,
             off_t offset)
      : length_(length), ptr_(mmap(addr, length, prot, flags, fd, offset)) {}
  ~ScopedMmap() {
    if (ptr_ != MAP_FAILED)
      munmap(ptr_, length_);
  }

  void* operator*() { return ptr_; }

 private:
  size_t length_;
  void* ptr_;
};

class LocalBinaryFinder {
 public:
  LocalBinaryFinder(std::vector<std::string> roots)
      : roots_(std::move(roots)) {}

  base::Optional<std::string> FindBinary(const std::string& abspath,
                                         const std::string& build_id) {
    auto p = cache_.emplace(abspath, base::nullopt);
    if (!p.second)
      return p.first->second;

    base::Optional<std::string>& cache_entry = p.first->second;

    for (const std::string& root_str : roots_) {
      cache_entry = FindBinaryInRoot(root_str, abspath, build_id);
      if (cache_entry)
        return cache_entry;
    }
    PERFETTO_ELOG("Could not find %s.", abspath.c_str());
    return cache_entry;
  }

 private:
  bool IsCorrectFile(const std::string& symbol_file,
                     const std::string& build_id) {
    base::ScopedFile fd(base::OpenFile(symbol_file, O_RDONLY));
    if (!fd)
      return false;

    struct stat statbuf;
    if (fstat(*fd, &statbuf) == -1)
      return false;

    size_t size = static_cast<size_t>(statbuf.st_size);

    if (size <= EI_CLASS)
      return false;

    ScopedMmap map(nullptr, size, PROT_READ, MAP_PRIVATE, *fd, 0);
    if (*map == MAP_FAILED) {
      PERFETTO_PLOG("mmap");
      return false;
    }
    char* mem = static_cast<char*>(*map);

    if (mem[EI_MAG0] != ELFMAG0 || mem[EI_MAG1] != ELFMAG1 ||
        mem[EI_MAG2] != ELFMAG2 || mem[EI_MAG3] != ELFMAG3) {
      return false;
    }

    switch (mem[EI_CLASS]) {
      case ELFCLASS32:
        return build_id == GetBuildId<Elf32>(mem, size);
      case ELFCLASS64:
        return build_id == GetBuildId<Elf64>(mem, size);
      default:
        return false;
    }
  }

  base::Optional<std::string> FindBinaryInRoot(const std::string& root_str,
                                               const std::string& abspath,
                                               const std::string& build_id) {
    constexpr char kApkPrefix[] = "base.apk!";

    std::string filename;
    std::string dirname;

    for (base::StringSplitter sp(abspath, '/'); sp.Next();) {
      dirname += "/" + filename;
      filename = sp.cur_token();
    }

    // Return the first match for the following options:
    // * absolute path of library file relative to root.
    // * absolute path of library file relative to root, but with base.apk!
    //   removed from filename.
    // * only filename of library file relative to root.
    // * only filename of library file relative to root, but with base.apk!
    //   removed from filename.
    //
    // For example, "/system/lib/base.apk!foo.so" is looked for at
    // * $ROOT/system/lib/base.apk!foo.so
    // * $ROOT/system/lib/foo.so
    // * $ROOT/base.apk!foo.so
    // * $ROOT/foo.so

    std::string symbol_file = root_str + "/" + dirname + "/" + filename;
    if (access(symbol_file.c_str(), F_OK) == 0 &&
        IsCorrectFile(symbol_file, build_id))
      return {symbol_file};

    if (filename.find(kApkPrefix) == 0) {
      symbol_file =
          root_str + "/" + dirname + "/" + filename.substr(sizeof(kApkPrefix));
      if (access(symbol_file.c_str(), F_OK) == 0 &&
          IsCorrectFile(symbol_file, build_id))
        return {symbol_file};
    }

    symbol_file = root_str + "/" + filename;
    if (access(symbol_file.c_str(), F_OK) == 0 &&
        IsCorrectFile(symbol_file, build_id))
      return {symbol_file};

    if (filename.find(kApkPrefix) == 0) {
      symbol_file = root_str + "/" + filename.substr(sizeof(kApkPrefix));
      if (access(symbol_file.c_str(), F_OK) == 0 &&
          IsCorrectFile(symbol_file, build_id))
        return {symbol_file};
    }

    return base::nullopt;
  }

 private:
  std::vector<std::string> roots_;
  std::map<std::string, base::Optional<std::string>> cache_;
};

struct SymbolizedFrame {
  std::string function_name;
  std::string line_information;
};

class LocalLLVMSymbolizer {
 public:
  LocalLLVMSymbolizer()
      : subprocess_("llvm-symbolizer", {"llvm-symbolizer"}),
        read_file_(fdopen(subprocess_.read_fd(), "r")) {}

  std::vector<SymbolizedFrame> Symbolize(const std::string& binary,
                                         uint64_t address) {
    std::vector<SymbolizedFrame> result;

    if (PERFETTO_EINTR(dprintf(subprocess_.write_fd(), "%s 0x%lx\n",
                               binary.c_str(), address)) < 0) {
      PERFETTO_ELOG("Failed to write to llvm-symbolizer.");
      return result;
    }
    auto lines = GetLines(read_file_);
    // llvm-symbolizer writes out records in the form of
    // Foo(Bar*)
    // foo.cc:123
    // This is why we should always get a multiple of two number of lines.
    PERFETTO_DCHECK(lines.size() % 2 == 0);
    result.resize(lines.size() / 2);
    for (size_t i = 0; i < lines.size(); ++i) {
      if (i % 2 == 0)
        result[i / 2].function_name = lines[i];
      else
        result[i / 2].line_information = lines[i];
    }
    return result;
  }

 private:
  Subprocess subprocess_;
  FILE* read_file_;
};

std::vector<std::string> GetRootsForEnv() {
  std::vector<std::string> roots;
  const char* root = getenv("PERFETTO_BINARY_PATH");
  if (root != nullptr) {
    for (base::StringSplitter sp(std::string(root), ':'); sp.Next();)
      roots.emplace_back(sp.cur_token(), sp.cur_token_size());
  }
  return roots;
}

class Symbolizer {
 public:
  Symbolizer() : finder_(GetRootsForEnv()) {}

  void AddInternedString(const InternedString& string) {
    interned_strings_.emplace(string.iid(), string.str());
  }

  void AddMapping(const Mapping& mapping) {
    mappings_.emplace(mapping.iid(), ResolveMapping(mapping));
  }

  void SymbolizeFrame(Frame* frame) {
    auto it = mappings_.find(frame->mapping_id());
    if (it == mappings_.end()) {
      PERFETTO_ELOG("Invalid mapping.");
      return;
    }
    const ResolvedMapping& mapping = it->second;
    base::Optional<std::string> binary =
        finder_.FindBinary(mapping.mapping_name, mapping.build_id);
    if (!binary)
      return;
    auto result = llvm_symbolizer_.Symbolize(*binary, frame->rel_pc());
    if (!result.empty()) {
      // TODO(fmayer): Better support for inline functions.
      const SymbolizedFrame& symf = result[0];
      if (symf.function_name != "??") {
        uint64_t& id = intern_table_[symf.function_name];
        if (!id)
          id = --intern_id_;
        frame->set_function_name_id(id);
      }
    }
  }

  const std::map<std::string, uint64_t>& intern_table() const {
    return intern_table_;
  }

 private:
  struct ResolvedMapping {
    std::string mapping_name;
    std::string build_id;
  };

  std::string ResolveString(uint64_t iid) {
    auto it = interned_strings_.find(iid);
    if (it == interned_strings_.end())
      return {};
    return it->second;
  }

  ResolvedMapping ResolveMapping(const Mapping& mapping) {
    std::string path;
    for (uint64_t iid : mapping.path_string_ids()) {
      path += "/";
      path += ResolveString(iid);
    }
    return {std::move(path), ResolveString(mapping.build_id())};
  }

  LocalLLVMSymbolizer llvm_symbolizer_;
  LocalBinaryFinder finder_;

  std::map<uint64_t, std::string> interned_strings_;
  std::map<uint64_t, ResolvedMapping> mappings_;

  std::map<std::string, uint64_t> intern_table_;
  // Use high IDs for the newly interned strings to avoid clashing with
  // other interned strings. The other solution is to read the trace twice
  // in order to find out the maximum used interned ID. This means that we
  // cannot operate on stdin anymore.
  uint64_t intern_id_ = std::numeric_limits<uint64_t>::max();
};

void WriteTracePacket(const std::string& str, std::ostream* output) {
  constexpr char kPreamble =
      MakeTagLengthDelimited(protos::pbzero::Trace::kPacketFieldNumber);
  uint8_t length_field[10];
  uint8_t* end = WriteVarInt(str.size(), length_field);
  *output << kPreamble;
  *output << std::string(length_field, end);
  *output << str;
}

}  // namespace

int SymbolizeProfile(std::istream* input, std::ostream* output) {
  Symbolizer symbolizer;

  ForEachPacketInTrace(input, [&output,
                               &symbolizer](protos::TracePacket packet) {
    protos::ProfilePacket* profile_packet = nullptr;
    if (packet.has_profile_packet()) {
      profile_packet = packet.mutable_profile_packet();
    }
    InternedData* data = nullptr;
    if (packet.has_interned_data())
      data = packet.mutable_interned_data();
    if (profile_packet) {
      for (const InternedString& interned_string : profile_packet->strings())
        symbolizer.AddInternedString(interned_string);
    }
    if (data) {
      for (const InternedString& interned_string : data->build_ids())
        symbolizer.AddInternedString(interned_string);
      for (const InternedString& interned_string : data->mapping_paths())
        symbolizer.AddInternedString(interned_string);
      for (const InternedString& interned_string : data->function_names())
        symbolizer.AddInternedString(interned_string);
    }
    if (profile_packet) {
      for (const Mapping& mapping : profile_packet->mappings())
        symbolizer.AddMapping(mapping);
    }
    if (data) {
      for (const Mapping& mapping : data->mappings())
        symbolizer.AddMapping(mapping);
    }
    if (profile_packet) {
      for (Frame& frame : *profile_packet->mutable_frames())
        symbolizer.SymbolizeFrame(&frame);
    }
    if (data) {
      for (Frame& frame : *data->mutable_frames())
        symbolizer.SymbolizeFrame(&frame);
    }

    // As we will write the newly interned strings after, we need to set
    // continued for the last ProfilePacket.
    if (profile_packet)
      profile_packet->set_continued(true);
    WriteTracePacket(packet.SerializeAsString(), output);
  });

  // We have to emit a ProfilePacket with continued = false to terminate the
  // sequence of related ProfilePackets.
  protos::TracePacket packet;
  const auto& intern_table = symbolizer.intern_table();
  if (!intern_table.empty()) {
    InternedData* data = packet.mutable_interned_data();
    for (const auto& p : intern_table) {
      InternedString* str = data->add_function_names();
      str->set_iid(p.second);
      str->set_str(p.first);
    }
  }
  packet.mutable_profile_packet();
  WriteTracePacket(packet.SerializeAsString(), output);
  return 0;
}

}  // namespace trace_to_text
}  // namespace perfetto
