/*
 * Copyright (C) 2020 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 <libdebuggerd/tombstone.h>

#include <inttypes.h>

#include <functional>
#include <set>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <async_safe/log.h>
#include <bionic/macros.h>

#include "tombstone.pb.h"

using android::base::StringAppendF;
using android::base::StringPrintf;

#define CB(log, ...) callback(StringPrintf(__VA_ARGS__), log)
#define CBL(...) CB(true, __VA_ARGS__)
#define CBS(...) CB(false, __VA_ARGS__)
using CallbackType = std::function<void(const std::string& line, bool should_log)>;

static const char* abi_string(const Tombstone& tombstone) {
  switch (tombstone.arch()) {
    case Architecture::ARM32:
      return "arm";
    case Architecture::ARM64:
      return "arm64";
    case Architecture::RISCV64:
      return "riscv64";
    case Architecture::X86:
      return "x86";
    case Architecture::X86_64:
      return "x86_64";
    default:
      return "<unknown>";
  }
}

static int pointer_width(const Tombstone& tombstone) {
  switch (tombstone.arch()) {
    case Architecture::ARM32:
      return 4;
    case Architecture::ARM64:
      return 8;
    case Architecture::RISCV64:
      return 8;
    case Architecture::X86:
      return 4;
    case Architecture::X86_64:
      return 8;
    default:
      return 8;
  }
}

static void print_thread_header(CallbackType callback, const Tombstone& tombstone,
                                const Thread& thread, bool should_log) {
  const char* process_name = "<unknown>";
  if (!tombstone.command_line().empty()) {
    process_name = tombstone.command_line()[0].c_str();
    CB(should_log, "Cmdline: %s", android::base::Join(tombstone.command_line(), " ").c_str());
  }
  CB(should_log, "pid: %d, tid: %d, name: %s  >>> %s <<<", tombstone.pid(), thread.id(),
     thread.name().c_str(), process_name);
  CB(should_log, "uid: %d", tombstone.uid());
  if (thread.tagged_addr_ctrl() != -1) {
    CB(should_log, "tagged_addr_ctrl: %016" PRIx64 "%s", thread.tagged_addr_ctrl(),
       describe_tagged_addr_ctrl(thread.tagged_addr_ctrl()).c_str());
  }
  if (thread.pac_enabled_keys() != -1) {
    CB(should_log, "pac_enabled_keys: %016" PRIx64 "%s", thread.pac_enabled_keys(),
       describe_pac_enabled_keys(thread.pac_enabled_keys()).c_str());
  }
}

static void print_register_row(CallbackType callback, int word_size,
                               std::vector<std::pair<std::string, uint64_t>> row, bool should_log) {
  std::string output = "  ";
  for (const auto& [name, value] : row) {
    output += android::base::StringPrintf("  %-3s %0*" PRIx64, name.c_str(), 2 * word_size,
                                          static_cast<uint64_t>(value));
  }
  callback(output, should_log);
}

static void print_thread_registers(CallbackType callback, const Tombstone& tombstone,
                                   const Thread& thread, bool should_log) {
  static constexpr size_t column_count = 4;
  std::vector<std::pair<std::string, uint64_t>> current_row;
  std::vector<std::pair<std::string, uint64_t>> special_row;
  std::unordered_set<std::string> special_registers;

  int word_size = pointer_width(tombstone);

  switch (tombstone.arch()) {
    case Architecture::ARM32:
      special_registers = {"ip", "lr", "sp", "pc", "pst"};
      break;

    case Architecture::ARM64:
      special_registers = {"ip", "lr", "sp", "pc", "pst"};
      break;

    case Architecture::RISCV64:
      special_registers = {"ra", "sp", "pc"};
      break;

    case Architecture::X86:
      special_registers = {"ebp", "esp", "eip"};
      break;

    case Architecture::X86_64:
      special_registers = {"rbp", "rsp", "rip"};
      break;

    default:
      async_safe_fatal("unknown architecture");
  }

  for (const auto& reg : thread.registers()) {
    auto row = &current_row;
    if (special_registers.count(reg.name()) == 1) {
      row = &special_row;
    }

    row->emplace_back(reg.name(), reg.u64());
    if (current_row.size() == column_count) {
      print_register_row(callback, word_size, current_row, should_log);
      current_row.clear();
    }
  }

  if (!current_row.empty()) {
    print_register_row(callback, word_size, current_row, should_log);
  }

  print_register_row(callback, word_size, special_row, should_log);
}

static void print_backtrace(CallbackType callback, const Tombstone& tombstone,
                            const google::protobuf::RepeatedPtrField<BacktraceFrame>& backtrace,
                            bool should_log) {
  int index = 0;
  for (const auto& frame : backtrace) {
    std::string function;

    if (!frame.function_name().empty()) {
      function =
          StringPrintf(" (%s+%" PRId64 ")", frame.function_name().c_str(), frame.function_offset());
    }

    std::string build_id;
    if (!frame.build_id().empty()) {
      build_id = StringPrintf(" (BuildId: %s)", frame.build_id().c_str());
    }

    std::string line =
        StringPrintf("      #%02d pc %0*" PRIx64 "  %s", index++, pointer_width(tombstone) * 2,
                     frame.rel_pc(), frame.file_name().c_str());
    if (frame.file_map_offset() != 0) {
      line += StringPrintf(" (offset 0x%" PRIx64 ")", frame.file_map_offset());
    }
    line += function + build_id;
    CB(should_log, "%s", line.c_str());
  }
}

static void print_thread_backtrace(CallbackType callback, const Tombstone& tombstone,
                                   const Thread& thread, bool should_log) {
  CBS("");
  CB(should_log, "%d total frames", thread.current_backtrace().size());
  CB(should_log, "backtrace:");
  if (!thread.backtrace_note().empty()) {
    CB(should_log, "  NOTE: %s",
       android::base::Join(thread.backtrace_note(), "\n  NOTE: ").c_str());
  }
  print_backtrace(callback, tombstone, thread.current_backtrace(), should_log);
}

static void print_thread_memory_dump(CallbackType callback, const Tombstone& tombstone,
                                     const Thread& thread) {
  static constexpr size_t bytes_per_line = 16;
  static_assert(bytes_per_line == kTagGranuleSize);
  int word_size = pointer_width(tombstone);
  for (const auto& mem : thread.memory_dump()) {
    CBS("");
    if (mem.mapping_name().empty()) {
      CBS("memory near %s:", mem.register_name().c_str());
    } else {
      CBS("memory near %s (%s):", mem.register_name().c_str(), mem.mapping_name().c_str());
    }
    uint64_t addr = mem.begin_address();
    for (size_t offset = 0; offset < mem.memory().size(); offset += bytes_per_line) {
      uint64_t tagged_addr = addr;
      if (mem.has_arm_mte_metadata() &&
          mem.arm_mte_metadata().memory_tags().size() > offset / kTagGranuleSize) {
        tagged_addr |=
            static_cast<uint64_t>(mem.arm_mte_metadata().memory_tags()[offset / kTagGranuleSize])
            << 56;
      }
      std::string line = StringPrintf("    %0*" PRIx64, word_size * 2, tagged_addr + offset);

      size_t bytes = std::min(bytes_per_line, mem.memory().size() - offset);
      for (size_t i = 0; i < bytes; i += word_size) {
        uint64_t word = 0;

        // Assumes little-endian, but what doesn't?
        memcpy(&word, mem.memory().data() + offset + i, word_size);

        StringAppendF(&line, " %0*" PRIx64, word_size * 2, word);
      }

      char ascii[bytes_per_line + 1];

      memset(ascii, '.', sizeof(ascii));
      ascii[bytes_per_line] = '\0';

      for (size_t i = 0; i < bytes; ++i) {
        uint8_t byte = mem.memory()[offset + i];
        if (byte >= 0x20 && byte < 0x7f) {
          ascii[i] = byte;
        }
      }

      CBS("%s  %s", line.c_str(), ascii);
    }
  }
}

static void print_thread(CallbackType callback, const Tombstone& tombstone, const Thread& thread) {
  print_thread_header(callback, tombstone, thread, false);
  print_thread_registers(callback, tombstone, thread, false);
  print_thread_backtrace(callback, tombstone, thread, false);
  print_thread_memory_dump(callback, tombstone, thread);
}

static void print_tag_dump(CallbackType callback, const Tombstone& tombstone) {
  if (!tombstone.has_signal_info()) return;

  const Signal& signal = tombstone.signal_info();

  if (!signal.has_fault_address() || !signal.has_fault_adjacent_metadata()) {
    return;
  }

  const MemoryDump& memory_dump = signal.fault_adjacent_metadata();

  if (!memory_dump.has_arm_mte_metadata() || memory_dump.arm_mte_metadata().memory_tags().empty()) {
    return;
  }

  const std::string& tags = memory_dump.arm_mte_metadata().memory_tags();

  CBS("");
  CBS("Memory tags around the fault address (0x%" PRIx64 "), one tag per %zu bytes:",
      signal.fault_address(), kTagGranuleSize);
  constexpr uintptr_t kRowStartMask = ~(kNumTagColumns * kTagGranuleSize - 1);

  size_t tag_index = 0;
  size_t num_tags = tags.length();
  uintptr_t fault_granule = untag_address(signal.fault_address()) & ~(kTagGranuleSize - 1);
  for (size_t row = 0; tag_index < num_tags; ++row) {
    uintptr_t row_addr =
        (memory_dump.begin_address() + row * kNumTagColumns * kTagGranuleSize) & kRowStartMask;
    std::string row_contents;
    bool row_has_fault = false;

    for (size_t column = 0; column < kNumTagColumns; ++column) {
      uintptr_t granule_addr = row_addr + column * kTagGranuleSize;
      if (granule_addr < memory_dump.begin_address() ||
          granule_addr >= memory_dump.begin_address() + num_tags * kTagGranuleSize) {
        row_contents += " . ";
      } else if (granule_addr == fault_granule) {
        row_contents += StringPrintf("[%1hhx]", tags[tag_index++]);
        row_has_fault = true;
      } else {
        row_contents += StringPrintf(" %1hhx ", tags[tag_index++]);
      }
    }

    if (row_contents.back() == ' ') row_contents.pop_back();

    if (row_has_fault) {
      CBS("    =>0x%" PRIxPTR ":%s", row_addr, row_contents.c_str());
    } else {
      CBS("      0x%" PRIxPTR ":%s", row_addr, row_contents.c_str());
    }
  }
}

static void print_memory_maps(CallbackType callback, const Tombstone& tombstone) {
  int word_size = pointer_width(tombstone);
  const auto format_pointer = [word_size](uint64_t ptr) -> std::string {
    if (word_size == 8) {
      uint64_t top = ptr >> 32;
      uint64_t bottom = ptr & 0xFFFFFFFF;
      return StringPrintf("%08" PRIx64 "'%08" PRIx64, top, bottom);
    }

    return StringPrintf("%0*" PRIx64, word_size * 2, ptr);
  };

  std::string memory_map_header =
      StringPrintf("memory map (%d %s):", tombstone.memory_mappings().size(),
                   tombstone.memory_mappings().size() == 1 ? "entry" : "entries");

  const Signal& signal_info = tombstone.signal_info();
  bool has_fault_address = signal_info.has_fault_address();
  uint64_t fault_address = untag_address(signal_info.fault_address());
  bool preamble_printed = false;
  bool printed_fault_address_marker = false;
  for (const auto& map : tombstone.memory_mappings()) {
    if (!preamble_printed) {
      preamble_printed = true;
      if (has_fault_address) {
        if (fault_address < map.begin_address()) {
          memory_map_header +=
              StringPrintf("\n--->Fault address falls at %s before any mapped regions",
                           format_pointer(fault_address).c_str());
          printed_fault_address_marker = true;
        } else {
          memory_map_header += " (fault address prefixed with --->)";
        }
      }
      CBS("%s", memory_map_header.c_str());
    }

    std::string line = "    ";
    if (has_fault_address && !printed_fault_address_marker) {
      if (fault_address < map.begin_address()) {
        printed_fault_address_marker = true;
        CBS("--->Fault address falls at %s between mapped regions",
            format_pointer(fault_address).c_str());
      } else if (fault_address >= map.begin_address() && fault_address < map.end_address()) {
        printed_fault_address_marker = true;
        line = "--->";
      }
    }
    StringAppendF(&line, "%s-%s", format_pointer(map.begin_address()).c_str(),
                  format_pointer(map.end_address() - 1).c_str());
    StringAppendF(&line, " %s%s%s", map.read() ? "r" : "-", map.write() ? "w" : "-",
                  map.execute() ? "x" : "-");
    StringAppendF(&line, "  %8" PRIx64 "  %8" PRIx64, map.offset(),
                  map.end_address() - map.begin_address());

    if (!map.mapping_name().empty()) {
      StringAppendF(&line, "  %s", map.mapping_name().c_str());

      if (!map.build_id().empty()) {
        StringAppendF(&line, " (BuildId: %s)", map.build_id().c_str());
      }

      if (map.load_bias() != 0) {
        StringAppendF(&line, " (load bias 0x%" PRIx64 ")", map.load_bias());
      }
    }

    CBS("%s", line.c_str());
  }

  if (has_fault_address && !printed_fault_address_marker) {
    CBS("--->Fault address falls at %s after any mapped regions",
        format_pointer(fault_address).c_str());
  }
}

static void print_main_thread(CallbackType callback, const Tombstone& tombstone,
                              const Thread& thread) {
  print_thread_header(callback, tombstone, thread, true);

  const Signal& signal_info = tombstone.signal_info();
  std::string sender_desc;

  if (signal_info.has_sender()) {
    sender_desc =
        StringPrintf(" from pid %d, uid %d", signal_info.sender_pid(), signal_info.sender_uid());
  }

  bool is_async_mte_crash = false;
  bool is_mte_crash = false;
  if (!tombstone.has_signal_info()) {
    CBL("signal information missing");
  } else {
    std::string fault_addr_desc;
    if (signal_info.has_fault_address()) {
      fault_addr_desc =
          StringPrintf("0x%0*" PRIx64, 2 * pointer_width(tombstone), signal_info.fault_address());
    } else {
      fault_addr_desc = "--------";
    }

    CBL("signal %d (%s), code %d (%s%s), fault addr %s", signal_info.number(),
        signal_info.name().c_str(), signal_info.code(), signal_info.code_name().c_str(),
        sender_desc.c_str(), fault_addr_desc.c_str());
#ifdef SEGV_MTEAERR
    is_async_mte_crash = signal_info.number() == SIGSEGV && signal_info.code() == SEGV_MTEAERR;
    is_mte_crash = is_async_mte_crash ||
                   (signal_info.number() == SIGSEGV && signal_info.code() == SEGV_MTESERR);
#endif
  }

  if (tombstone.causes_size() == 1) {
    CBL("Cause: %s", tombstone.causes(0).human_readable().c_str());
  }

  if (!tombstone.abort_message().empty()) {
    CBL("Abort message: '%s'", tombstone.abort_message().c_str());
  }

  print_thread_registers(callback, tombstone, thread, true);
  if (is_async_mte_crash) {
    CBL("Note: This crash is a delayed async MTE crash. Memory corruption has occurred");
    CBL("      in this process. The stack trace below is the first system call or context");
    CBL("      switch that was executed after the memory corruption happened.");
  }
  print_thread_backtrace(callback, tombstone, thread, true);

  if (tombstone.causes_size() > 1) {
    CBS("");
    CBL("Note: multiple potential causes for this crash were detected, listing them in decreasing "
        "order of likelihood.");
  }

  for (const Cause& cause : tombstone.causes()) {
    if (tombstone.causes_size() > 1) {
      CBS("");
      CBL("Cause: %s", cause.human_readable().c_str());
    }

    if (cause.has_memory_error() && cause.memory_error().has_heap()) {
      const HeapObject& heap_object = cause.memory_error().heap();

      if (heap_object.deallocation_backtrace_size() != 0) {
        CBS("");
        CBL("deallocated by thread %" PRIu64 ":", heap_object.deallocation_tid());
        print_backtrace(callback, tombstone, heap_object.deallocation_backtrace(), true);
      }

      if (heap_object.allocation_backtrace_size() != 0) {
        CBS("");
        CBL("allocated by thread %" PRIu64 ":", heap_object.allocation_tid());
        print_backtrace(callback, tombstone, heap_object.allocation_backtrace(), true);
      }
    }
  }

  print_tag_dump(callback, tombstone);

  if (is_mte_crash) {
    CBS("");
    CBL("Learn more about MTE reports: "
        "https://source.android.com/docs/security/test/memory-safety/mte-reports");
  }

  print_thread_memory_dump(callback, tombstone, thread);

  CBS("");

  // No memory maps to print.
  if (!tombstone.memory_mappings().empty()) {
    print_memory_maps(callback, tombstone);
  } else {
    CBS("No memory maps found");
  }
}

void print_logs(CallbackType callback, const Tombstone& tombstone, int tail) {
  for (const auto& buffer : tombstone.log_buffers()) {
    if (tail) {
      CBS("--------- tail end of log %s", buffer.name().c_str());
    } else {
      CBS("--------- log %s", buffer.name().c_str());
    }

    int begin = 0;
    if (tail != 0) {
      begin = std::max(0, buffer.logs().size() - tail);
    }

    for (int i = begin; i < buffer.logs().size(); ++i) {
      const LogMessage& msg = buffer.logs(i);

      static const char* kPrioChars = "!.VDIWEFS";
      char priority = (msg.priority() < strlen(kPrioChars) ? kPrioChars[msg.priority()] : '?');
      CBS("%s %5u %5u %c %-8s: %s", msg.timestamp().c_str(), msg.pid(), msg.tid(), priority,
          msg.tag().c_str(), msg.message().c_str());
    }
  }
}

bool tombstone_proto_to_text(const Tombstone& tombstone, CallbackType callback) {
  CBL("*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***");
  CBL("Build fingerprint: '%s'", tombstone.build_fingerprint().c_str());
  CBL("Revision: '%s'", tombstone.revision().c_str());
  CBL("ABI: '%s'", abi_string(tombstone));
  CBL("Timestamp: %s", tombstone.timestamp().c_str());
  CBL("Process uptime: %ds", tombstone.process_uptime());

  // Process header
  const auto& threads = tombstone.threads();
  auto main_thread_it = threads.find(tombstone.tid());
  if (main_thread_it == threads.end()) {
    CBL("failed to find entry for main thread in tombstone");
    return false;
  }

  const auto& main_thread = main_thread_it->second;

  print_main_thread(callback, tombstone, main_thread);

  print_logs(callback, tombstone, 50);

  // protobuf's map is unordered, so sort the keys first.
  std::set<int> thread_ids;
  for (const auto& [tid, _] : threads) {
    if (tid != tombstone.tid()) {
      thread_ids.insert(tid);
    }
  }

  for (const auto& tid : thread_ids) {
    CBS("--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---");
    print_thread(callback, tombstone, threads.find(tid)->second);
  }

  if (tombstone.open_fds().size() > 0) {
    CBS("");
    CBS("open files:");
    for (const auto& fd : tombstone.open_fds()) {
      std::optional<std::string> owner;
      if (!fd.owner().empty()) {
        owner = StringPrintf("owned by %s 0x%" PRIx64, fd.owner().c_str(), fd.tag());
      }

      CBS("    fd %d: %s (%s)", fd.fd(), fd.path().c_str(), owner ? owner->c_str() : "unowned");
    }
  }

  print_logs(callback, tombstone, 0);

  return true;
}
