//===-- asan_globals.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.
//
// Handle globals.
//===----------------------------------------------------------------------===//
#include "asan_interceptors.h"
#include "asan_interface.h"
#include "asan_internal.h"
#include "asan_lock.h"
#include "asan_mapping.h"
#include "asan_stack.h"
#include "asan_stats.h"
#include "asan_thread.h"

#include <ctype.h>

namespace __asan {

typedef __asan_global Global;

struct ListOfGlobals {
  const Global *g;
  ListOfGlobals *next;
};

static AsanLock mu_for_globals(LINKER_INITIALIZED);
static ListOfGlobals *list_of_globals;
static LowLevelAllocator allocator_for_globals(LINKER_INITIALIZED);

void PoisonRedZones(const Global &g)  {
  uptr shadow_rz_size = kGlobalAndStackRedzone >> SHADOW_SCALE;
  CHECK(shadow_rz_size == 1 || shadow_rz_size == 2 || shadow_rz_size == 4);
  // full right redzone
  uptr g_aligned_size = kGlobalAndStackRedzone *
      ((g.size + kGlobalAndStackRedzone - 1) / kGlobalAndStackRedzone);
  PoisonShadow(g.beg + g_aligned_size,
               kGlobalAndStackRedzone, kAsanGlobalRedzoneMagic);
  if ((g.size % kGlobalAndStackRedzone) != 0) {
    // partial right redzone
    u64 g_aligned_down_size = kGlobalAndStackRedzone *
        (g.size / kGlobalAndStackRedzone);
    CHECK(g_aligned_down_size == g_aligned_size - kGlobalAndStackRedzone);
    PoisonShadowPartialRightRedzone(g.beg + g_aligned_down_size,
                                    g.size % kGlobalAndStackRedzone,
                                    kGlobalAndStackRedzone,
                                    kAsanGlobalRedzoneMagic);
  }
}

static uptr GetAlignedSize(uptr size) {
  return ((size + kGlobalAndStackRedzone - 1) / kGlobalAndStackRedzone)
      * kGlobalAndStackRedzone;
}

  // Check if the global is a zero-terminated ASCII string. If so, print it.
void PrintIfASCII(const Global &g) {
  for (uptr p = g.beg; p < g.beg + g.size - 1; p++) {
    if (!isascii(*(char*)p)) return;
  }
  if (*(char*)(g.beg + g.size - 1) != 0) return;
  AsanPrintf("  '%s' is ascii string '%s'\n", g.name, (char*)g.beg);
}

bool DescribeAddrIfMyRedZone(const Global &g, uptr addr) {
  if (addr < g.beg - kGlobalAndStackRedzone) return false;
  if (addr >= g.beg + g.size_with_redzone) return false;
  AsanPrintf("%p is located ", (void*)addr);
  if (addr < g.beg) {
    AsanPrintf("%zd bytes to the left", g.beg - addr);
  } else if (addr >= g.beg + g.size) {
    AsanPrintf("%zd bytes to the right", addr - (g.beg + g.size));
  } else {
    AsanPrintf("%zd bytes inside", addr - g.beg);  // Can it happen?
  }
  AsanPrintf(" of global variable '%s' (0x%zx) of size %zu\n",
             g.name, g.beg, g.size);
  PrintIfASCII(g);
  return true;
}


bool DescribeAddrIfGlobal(uptr addr) {
  if (!flags()->report_globals) return false;
  ScopedLock lock(&mu_for_globals);
  bool res = false;
  for (ListOfGlobals *l = list_of_globals; l; l = l->next) {
    const Global &g = *l->g;
    if (flags()->report_globals >= 2)
      AsanPrintf("Search Global: beg=%p size=%zu name=%s\n",
                 (void*)g.beg, g.size, (char*)g.name);
    res |= DescribeAddrIfMyRedZone(g, addr);
  }
  return res;
}

// Register a global variable.
// This function may be called more than once for every global
// so we store the globals in a map.
static void RegisterGlobal(const Global *g) {
  CHECK(asan_inited);
  CHECK(flags()->report_globals);
  CHECK(AddrIsInMem(g->beg));
  CHECK(AddrIsAlignedByGranularity(g->beg));
  CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
  PoisonRedZones(*g);
  ListOfGlobals *l =
      (ListOfGlobals*)allocator_for_globals.Allocate(sizeof(ListOfGlobals));
  l->g = g;
  l->next = list_of_globals;
  list_of_globals = l;
  if (flags()->report_globals >= 2)
    Report("Added Global: beg=%p size=%zu name=%s\n",
           (void*)g->beg, g->size, g->name);
}

static void UnregisterGlobal(const Global *g) {
  CHECK(asan_inited);
  CHECK(flags()->report_globals);
  CHECK(AddrIsInMem(g->beg));
  CHECK(AddrIsAlignedByGranularity(g->beg));
  CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
  PoisonShadow(g->beg, g->size_with_redzone, 0);
  // We unpoison the shadow memory for the global but we do not remove it from
  // the list because that would require O(n^2) time with the current list
  // implementation. It might not be worth doing anyway.
}

}  // namespace __asan

// ---------------------- Interface ---------------- {{{1
using namespace __asan;  // NOLINT

// Register one global with a default redzone.
void __asan_register_global(uptr addr, uptr size,
                            const char *name) {
  if (!flags()->report_globals) return;
  ScopedLock lock(&mu_for_globals);
  Global *g = (Global *)allocator_for_globals.Allocate(sizeof(Global));
  g->beg = addr;
  g->size = size;
  g->size_with_redzone = GetAlignedSize(size) + kGlobalAndStackRedzone;
  g->name = name;
  RegisterGlobal(g);
}

// Register an array of globals.
void __asan_register_globals(__asan_global *globals, uptr n) {
  if (!flags()->report_globals) return;
  ScopedLock lock(&mu_for_globals);
  for (uptr i = 0; i < n; i++) {
    RegisterGlobal(&globals[i]);
  }
}

// Unregister an array of globals.
// We must do it when a shared objects gets dlclosed.
void __asan_unregister_globals(__asan_global *globals, uptr n) {
  if (!flags()->report_globals) return;
  ScopedLock lock(&mu_for_globals);
  for (uptr i = 0; i < n; i++) {
    UnregisterGlobal(&globals[i]);
  }
}
