//===-- asan_debugging.cc -------------------------------------------------===//
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
// This file contains various functions that are generally useful to call when
// using a debugger (LLDB, GDB).
//===----------------------------------------------------------------------===//

#include "asan_allocator.h"
#include "asan_descriptions.h"
#include "asan_flags.h"
#include "asan_internal.h"
#include "asan_mapping.h"
#include "asan_report.h"
#include "asan_thread.h"

namespace {
using namespace __asan;

static void FindInfoForStackVar(uptr addr, const char *frame_descr, uptr offset,
                                char *name, uptr name_size,
                                uptr &region_address, uptr &region_size) {
  InternalMmapVector<StackVarDescr> vars;
  vars.reserve(16);
  if (!ParseFrameDescription(frame_descr, &vars)) {
    return;
  }

  for (uptr i = 0; i < vars.size(); i++) {
    if (offset <= vars[i].beg + vars[i].size) {
      // We use name_len + 1 because strlcpy will guarantee a \0 at the end, so
      // if we're limiting the copy due to name_len, we add 1 to ensure we copy
      // the whole name and then terminate with '\0'.
      internal_strlcpy(name, vars[i].name_pos,
                       Min(name_size, vars[i].name_len + 1));
      region_address = addr - (offset - vars[i].beg);
      region_size = vars[i].size;
      return;
    }
  }
}

uptr AsanGetStack(uptr addr, uptr *trace, u32 size, u32 *thread_id,
                         bool alloc_stack) {
  AsanChunkView chunk = FindHeapChunkByAddress(addr);
  if (!chunk.IsValid()) return 0;

  StackTrace stack(nullptr, 0);
  if (alloc_stack) {
    if (chunk.AllocTid() == kInvalidTid) return 0;
    stack = chunk.GetAllocStack();
    if (thread_id) *thread_id = chunk.AllocTid();
  } else {
    if (chunk.FreeTid() == kInvalidTid) return 0;
    stack = chunk.GetFreeStack();
    if (thread_id) *thread_id = chunk.FreeTid();
  }

  if (trace && size) {
    size = Min(size, Min(stack.size, kStackTraceMax));
    for (uptr i = 0; i < size; i++)
      trace[i] = StackTrace::GetPreviousInstructionPc(stack.trace[i]);

    return size;
  }

  return 0;
}

}  // namespace

SANITIZER_INTERFACE_ATTRIBUTE
const char *__asan_locate_address(uptr addr, char *name, uptr name_size,
                                  uptr *region_address_ptr,
                                  uptr *region_size_ptr) {
  AddressDescription descr(addr);
  uptr region_address = 0;
  uptr region_size = 0;
  const char *region_kind = nullptr;
  if (name && name_size > 0) name[0] = 0;

  if (auto shadow = descr.AsShadow()) {
    // region_{address,size} are already 0
    switch (shadow->kind) {
      case kShadowKindLow:
        region_kind = "low shadow";
        break;
      case kShadowKindGap:
        region_kind = "shadow gap";
        break;
      case kShadowKindHigh:
        region_kind = "high shadow";
        break;
    }
  } else if (auto heap = descr.AsHeap()) {
    region_kind = "heap";
    region_address = heap->chunk_access.chunk_begin;
    region_size = heap->chunk_access.chunk_size;
  } else if (auto stack = descr.AsStack()) {
    region_kind = "stack";
    if (!stack->frame_descr) {
      // region_{address,size} are already 0
    } else {
      FindInfoForStackVar(addr, stack->frame_descr, stack->offset, name,
                          name_size, region_address, region_size);
    }
  } else if (auto global = descr.AsGlobal()) {
    region_kind = "global";
    auto &g = global->globals[0];
    internal_strlcpy(name, g.name, name_size);
    region_address = g.beg;
    region_size = g.size;
  } else {
    // region_{address,size} are already 0
    region_kind = "heap-invalid";
  }

  CHECK(region_kind);
  if (region_address_ptr) *region_address_ptr = region_address;
  if (region_size_ptr) *region_size_ptr = region_size;
  return region_kind;
}

SANITIZER_INTERFACE_ATTRIBUTE
uptr __asan_get_alloc_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) {
  return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ true);
}

SANITIZER_INTERFACE_ATTRIBUTE
uptr __asan_get_free_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) {
  return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ false);
}

SANITIZER_INTERFACE_ATTRIBUTE
void __asan_get_shadow_mapping(uptr *shadow_scale, uptr *shadow_offset) {
  if (shadow_scale)
    *shadow_scale = SHADOW_SCALE;
  if (shadow_offset)
    *shadow_offset = SHADOW_OFFSET;
}
