//===-- asan_debugging.cc -------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// 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(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;
}
