// Copyright 2018 The Chromium 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 "base/trace_event/cfi_backtrace_android.h"

#include <sys/mman.h>
#include <sys/types.h>

#include "base/android/apk_assets.h"
#include "starboard/memory.h"
#include "starboard/types.h"

#if !defined(ARCH_CPU_ARMEL)
#error This file should not be built for this architecture.
#endif

/*
Basics of unwinding:
For each instruction in a function we need to know what is the offset of SP
(Stack Pointer) to reach the previous function's stack frame. To know which
function is being invoked, we need the return address of the next function. The
CFI information for an instruction is made up of 2 offsets, CFA (Call Frame
Address) offset and RA (Return Address) offset. The CFA offset is the change in
SP made by the function till the current instruction. This depends on amount of
memory allocated on stack by the function plus some registers that the function
stores that needs to be restored at the end of function. So, at each instruction
the CFA offset tells the offset from original SP before the function call. The
RA offset tells us the offset from the previous SP into the current function
where the return address is stored.

The unwind table file has 2 tables UNW_INDEX and UNW_DATA, inspired from ARM
EHABI format. The first table contains function addresses and an index into the
UNW_DATA table. The second table contains one or more rows for the function
unwind information.

UNW_INDEX contains two columns of N rows each, where N is the number of
functions.
  1. First column 4 byte rows of all the function start address as offset from
     start of the binary, in sorted order.
  2. For each function addr, the second column contains 2 byte indices in order.
     The indices are offsets (in count of 2 bytes) of the CFI data from start of
     UNW_DATA.
The last entry in the table always contains CANT_UNWIND index to specify the
end address of the last function.

UNW_DATA contains data of all the functions. Each function data contains N rows.
The data found at the address pointed from UNW_INDEX will be:
  2 bytes: N - number of rows that belong to current function.
  N * 4 bytes: N rows of data. 16 bits : Address offset from function start.
                               14 bits : CFA offset / 4.
                                2 bits : RA offset / 4.
If the RA offset of a row is 0, then use the offset of the previous rows in the
same function.
TODO(ssid): Make sure RA offset is always present.

See extract_unwind_tables.py for details about how this data is extracted from
breakpad symbol files.
*/

extern "C" {

// The address of |__executable_start| gives the start address of the
// executable or shared library. This value is used to find the offset address
// of the instruction in binary from PC.
extern char __executable_start;

// The address |_etext| gives the end of the .text section in the binary. This
// value is more accurate than parsing the memory map since the mapped
// regions are usualy larger than the .text section.
extern char _etext;
}

namespace base {
namespace trace_event {

namespace {

// The value of index when the function does not have unwind information.
constexpr uint32_t kCantUnwind = 0xFFFF;

// The mask on the CFI row data that is used to get the high 14 bits and
// multiply it by 4 to get CFA offset. Since the last 2 bits are masked out, a
// shift is not necessary.
constexpr uint16_t kCFAMask = 0xfffc;

// The mask on the CFI row data that is used to get the low 2 bits and multiply
// it by 4 to get the RA offset.
constexpr uint16_t kRAMask = 0x3;
constexpr uint16_t kRAShift = 2;

// The code in this file assumes we are running in 32-bit builds since all the
// addresses in the unwind table are specified in 32 bits.
static_assert(sizeof(uintptr_t) == 4,
              "The unwind table format is only valid for 32 bit builds.");

// The CFI data in UNW_DATA table starts with number of rows (N) and then
// followed by N rows of 4 bytes long. The CFIUnwindDataRow represents a single
// row of CFI data of a function in the table. Since we cast the memory at the
// address after the address of number of rows, into an array of
// CFIUnwindDataRow, the size of the struct should be 4 bytes and the order of
// the members is fixed according to the given format. The first 2 bytes tell
// the address of function and last 2 bytes give the CFI data for the offset.
struct CFIUnwindDataRow {
  // The address of the instruction in terms of offset from the start of the
  // function.
  uint16_t addr_offset;
  // Represents the CFA and RA offsets to get information about next stack
  // frame. This is the CFI data at the point before executing the instruction
  // at |addr_offset| from the start of the function.
  uint16_t cfi_data;

  // Return the RA offset for the current unwind row.
  size_t ra_offset() const { return (cfi_data & kRAMask) << kRAShift; }

  // Returns the CFA offset for the current unwind row.
  size_t cfa_offset() const { return cfi_data & kCFAMask; }
};

static_assert(
    sizeof(CFIUnwindDataRow) == 4,
    "The CFIUnwindDataRow struct must be exactly 4 bytes for searching.");

}  // namespace

// static
CFIBacktraceAndroid* CFIBacktraceAndroid::GetInitializedInstance() {
  static CFIBacktraceAndroid* instance = new CFIBacktraceAndroid();
  return instance;
}

// static
uintptr_t CFIBacktraceAndroid::executable_start_addr() {
  return reinterpret_cast<uintptr_t>(&__executable_start);
}

// static
uintptr_t CFIBacktraceAndroid::executable_end_addr() {
  return reinterpret_cast<uintptr_t>(&_etext);
}

CFIBacktraceAndroid::CFIBacktraceAndroid()
    : thread_local_cfi_cache_(
          [](void* ptr) { delete static_cast<CFICache*>(ptr); }) {
  Initialize();
}

CFIBacktraceAndroid::~CFIBacktraceAndroid() {}

void CFIBacktraceAndroid::Initialize() {
  // This file name is defined by extract_unwind_tables.gni.
  static constexpr char kCfiFileName[] = "assets/unwind_cfi_32";
  MemoryMappedFile::Region cfi_region;
  int fd = base::android::OpenApkAsset(kCfiFileName, &cfi_region);
  if (fd < 0)
    return;
  cfi_mmap_ = std::make_unique<MemoryMappedFile>();
  // The CFI region starts at |cfi_region.offset|.
  if (!cfi_mmap_->Initialize(base::File(fd), cfi_region))
    return;

  ParseCFITables();
  can_unwind_stack_frames_ = true;
}

void CFIBacktraceAndroid::ParseCFITables() {
  // The first 4 bytes in the file is the size of UNW_INDEX table.
  static constexpr size_t kUnwIndexRowSize =
      sizeof(*unw_index_function_col_) + sizeof(*unw_index_indices_col_);
  size_t unw_index_size = 0;
  SbMemoryCopy(&unw_index_size, cfi_mmap_->data(), sizeof(unw_index_size));
  DCHECK_EQ(0u, unw_index_size % kUnwIndexRowSize);
  // UNW_INDEX table starts after 4 bytes.
  unw_index_function_col_ =
      reinterpret_cast<const uintptr_t*>(cfi_mmap_->data()) + 1;
  unw_index_row_count_ = unw_index_size / kUnwIndexRowSize;
  unw_index_indices_col_ = reinterpret_cast<const uint16_t*>(
      unw_index_function_col_ + unw_index_row_count_);

  // The UNW_DATA table data is right after the end of UNW_INDEX table.
  // Interpret the UNW_DATA table as an array of 2 byte numbers since the
  // indexes we have from the UNW_INDEX table are in terms of 2 bytes.
  unw_data_start_addr_ = unw_index_indices_col_ + unw_index_row_count_;
}

size_t CFIBacktraceAndroid::Unwind(const void** out_trace, size_t max_depth) {
  // This function walks the stack using the call frame information to find the
  // return addresses of all the functions that belong to current binary in call
  // stack. For each function the CFI table defines the offset of the previous
  // call frame and offset where the return address is stored.
  if (!can_unwind_stack_frames())
    return 0;

  // Get the current register state. This register state can be taken at any
  // point in the function and the unwind information would be for this point.
  // Define local variables before trying to get the current PC and SP to make
  // sure the register state obtained is consistent with each other.
  uintptr_t pc = 0, sp = 0;
  asm volatile("mov %0, pc" : "=r"(pc));
  asm volatile("mov %0, sp" : "=r"(sp));

  return Unwind(pc, sp, out_trace, max_depth);
}

size_t CFIBacktraceAndroid::Unwind(uintptr_t pc,
                                   uintptr_t sp,
                                   const void** out_trace,
                                   size_t max_depth) {
  if (!can_unwind_stack_frames())
    return 0;

  // We can only unwind as long as the pc is within the chrome.so.
  size_t depth = 0;
  while (is_chrome_address(pc) && depth < max_depth) {
    out_trace[depth++] = reinterpret_cast<void*>(pc);
    // The offset of function from the start of the chrome.so binary:
    uintptr_t func_addr = pc - executable_start_addr();
    CFIRow cfi{};
    if (!FindCFIRowForPC(func_addr, &cfi))
      break;

    // The rules for unwinding using the CFI information are:
    // SP_prev = SP_cur + cfa_offset and
    // PC_prev = * (SP_prev - ra_offset).
    sp = sp + cfi.cfa_offset;
    SbMemoryCopy(&pc, reinterpret_cast<uintptr_t*>(sp - cfi.ra_offset),
                 sizeof(uintptr_t));
  }
  return depth;
}

void CFIBacktraceAndroid::AllocateCacheForCurrentThread() {
  GetThreadLocalCFICache();
}

bool CFIBacktraceAndroid::FindCFIRowForPC(uintptr_t func_addr,
                                          CFIBacktraceAndroid::CFIRow* cfi) {
  if (!can_unwind_stack_frames())
    return false;

  auto* cache = GetThreadLocalCFICache();
  *cfi = {0};
  if (cache->Find(func_addr, cfi))
    return true;

  // Consider each column of UNW_INDEX table as arrays of uintptr_t (function
  // addresses) and uint16_t (indices). Define start and end iterator on the
  // first column array (addresses) and use std::lower_bound() to binary search
  // on this array to find the required function address.
  static const uintptr_t* const unw_index_fn_end =
      unw_index_function_col_ + unw_index_row_count_;
  const uintptr_t* found =
      std::lower_bound(unw_index_function_col_, unw_index_fn_end, func_addr);

  // If found is start, then the given function is not in the table. If the
  // given pc is start of a function then we cannot unwind.
  if (found == unw_index_function_col_ || *found == func_addr)
    return false;

  // std::lower_bound() returns the iter that corresponds to the first address
  // that is greater than the given address. So, the required iter is always one
  // less than the value returned by std::lower_bound().
  --found;
  uintptr_t func_start_addr = *found;
  size_t row_num = found - unw_index_function_col_;
  uint16_t index = unw_index_indices_col_[row_num];
  DCHECK_LE(func_start_addr, func_addr);
  // If the index is CANT_UNWIND then we do not have unwind infomation for the
  // function.
  if (index == kCantUnwind)
    return false;

  // The unwind data for the current function is at an offsset of the index
  // found in UNW_INDEX table.
  const uint16_t* unwind_data = unw_data_start_addr_ + index;
  // The value of first 2 bytes is the CFI data row count for the function.
  uint16_t row_count = 0;
  SbMemoryCopy(&row_count, unwind_data, sizeof(row_count));
  // And the actual CFI rows start after 2 bytes from the |unwind_data|. Cast
  // the data into an array of CFIUnwindDataRow since the struct is designed to
  // represent each row. We should be careful to read only |row_count| number of
  // elements in the array.
  const CFIUnwindDataRow* function_data =
      reinterpret_cast<const CFIUnwindDataRow*>(unwind_data + 1);

  // Iterate through the CFI rows of the function to find the row that gives
  // offset for the given instruction address.
  CFIUnwindDataRow cfi_row = {0, 0};
  uint16_t ra_offset = 0;
  for (uint16_t i = 0; i < row_count; ++i) {
    CFIUnwindDataRow row;
    SbMemoryCopy(&row, function_data + i, sizeof(CFIUnwindDataRow));
    // The return address of the function is the instruction that is not yet
    // been executed. The cfi row specifies the unwind info before executing the
    // given instruction. If the given address is equal to the instruction
    // offset, then use the current row. Or use the row with highest address
    // less than the given address.
    if (row.addr_offset + func_start_addr > func_addr)
      break;

    cfi_row = row;
    // The ra offset of the last specified row should be used, if unspecified.
    // So, keep updating the RA offset till we reach the correct CFI row.
    // TODO(ssid): This should be fixed in the format and we should always
    // output ra offset.
    if (cfi_row.ra_offset())
      ra_offset = cfi_row.ra_offset();
  }
  DCHECK_NE(0u, cfi_row.addr_offset);
  *cfi = {cfi_row.cfa_offset(), ra_offset};
  DCHECK(cfi->cfa_offset);
  DCHECK(cfi->ra_offset);

  // safe to update since the cache is thread local.
  cache->Add(func_addr, *cfi);
  return true;
}

CFIBacktraceAndroid::CFICache* CFIBacktraceAndroid::GetThreadLocalCFICache() {
  auto* cache = static_cast<CFICache*>(thread_local_cfi_cache_.Get());
  if (!cache) {
    cache = new CFICache();
    thread_local_cfi_cache_.Set(cache);
  }
  return cache;
}

void CFIBacktraceAndroid::CFICache::Add(uintptr_t address, CFIRow cfi) {
  cache_[address % kLimit] = {address, cfi};
}

bool CFIBacktraceAndroid::CFICache::Find(uintptr_t address, CFIRow* cfi) {
  if (cache_[address % kLimit].address == address) {
    *cfi = cache_[address % kLimit].cfi;
    return true;
  }
  return false;
}

}  // namespace trace_event
}  // namespace base
