Home | History | Annotate | Line # | Download | only in sanitizer_common
      1 //===-- sanitizer_win.cc --------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is shared between AddressSanitizer and ThreadSanitizer
     11 // run-time libraries and implements windows-specific functions from
     12 // sanitizer_libc.h.
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "sanitizer_platform.h"
     16 #if SANITIZER_WINDOWS
     17 
     18 #define WIN32_LEAN_AND_MEAN
     19 #define NOGDI
     20 #include <windows.h>
     21 #include <io.h>
     22 #include <psapi.h>
     23 #include <stdlib.h>
     24 
     25 #include "sanitizer_common.h"
     26 #include "sanitizer_file.h"
     27 #include "sanitizer_libc.h"
     28 #include "sanitizer_mutex.h"
     29 #include "sanitizer_placement_new.h"
     30 #include "sanitizer_win_defs.h"
     31 
     32 #if defined(PSAPI_VERSION) && PSAPI_VERSION == 1
     33 #pragma comment(lib, "psapi")
     34 #endif
     35 
     36 // A macro to tell the compiler that this part of the code cannot be reached,
     37 // if the compiler supports this feature. Since we're using this in
     38 // code that is called when terminating the process, the expansion of the
     39 // macro should not terminate the process to avoid infinite recursion.
     40 #if defined(__clang__)
     41 # define BUILTIN_UNREACHABLE() __builtin_unreachable()
     42 #elif defined(__GNUC__) && \
     43     (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
     44 # define BUILTIN_UNREACHABLE() __builtin_unreachable()
     45 #elif defined(_MSC_VER)
     46 # define BUILTIN_UNREACHABLE() __assume(0)
     47 #else
     48 # define BUILTIN_UNREACHABLE()
     49 #endif
     50 
     51 namespace __sanitizer {
     52 
     53 #include "sanitizer_syscall_generic.inc"
     54 
     55 // --------------------- sanitizer_common.h
     56 uptr GetPageSize() {
     57   SYSTEM_INFO si;
     58   GetSystemInfo(&si);
     59   return si.dwPageSize;
     60 }
     61 
     62 uptr GetMmapGranularity() {
     63   SYSTEM_INFO si;
     64   GetSystemInfo(&si);
     65   return si.dwAllocationGranularity;
     66 }
     67 
     68 uptr GetMaxUserVirtualAddress() {
     69   SYSTEM_INFO si;
     70   GetSystemInfo(&si);
     71   return (uptr)si.lpMaximumApplicationAddress;
     72 }
     73 
     74 uptr GetMaxVirtualAddress() {
     75   return GetMaxUserVirtualAddress();
     76 }
     77 
     78 bool FileExists(const char *filename) {
     79   return ::GetFileAttributesA(filename) != INVALID_FILE_ATTRIBUTES;
     80 }
     81 
     82 uptr internal_getpid() {
     83   return GetProcessId(GetCurrentProcess());
     84 }
     85 
     86 // In contrast to POSIX, on Windows GetCurrentThreadId()
     87 // returns a system-unique identifier.
     88 tid_t GetTid() {
     89   return GetCurrentThreadId();
     90 }
     91 
     92 uptr GetThreadSelf() {
     93   return GetTid();
     94 }
     95 
     96 #if !SANITIZER_GO
     97 void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
     98                                 uptr *stack_bottom) {
     99   CHECK(stack_top);
    100   CHECK(stack_bottom);
    101   MEMORY_BASIC_INFORMATION mbi;
    102   CHECK_NE(VirtualQuery(&mbi /* on stack */, &mbi, sizeof(mbi)), 0);
    103   // FIXME: is it possible for the stack to not be a single allocation?
    104   // Are these values what ASan expects to get (reserved, not committed;
    105   // including stack guard page) ?
    106   *stack_top = (uptr)mbi.BaseAddress + mbi.RegionSize;
    107   *stack_bottom = (uptr)mbi.AllocationBase;
    108 }
    109 #endif  // #if !SANITIZER_GO
    110 
    111 void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) {
    112   void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    113   if (rv == 0)
    114     ReportMmapFailureAndDie(size, mem_type, "allocate",
    115                             GetLastError(), raw_report);
    116   return rv;
    117 }
    118 
    119 void UnmapOrDie(void *addr, uptr size) {
    120   if (!size || !addr)
    121     return;
    122 
    123   MEMORY_BASIC_INFORMATION mbi;
    124   CHECK(VirtualQuery(addr, &mbi, sizeof(mbi)));
    125 
    126   // MEM_RELEASE can only be used to unmap whole regions previously mapped with
    127   // VirtualAlloc. So we first try MEM_RELEASE since it is better, and if that
    128   // fails try MEM_DECOMMIT.
    129   if (VirtualFree(addr, 0, MEM_RELEASE) == 0) {
    130     if (VirtualFree(addr, size, MEM_DECOMMIT) == 0) {
    131       Report("ERROR: %s failed to "
    132              "deallocate 0x%zx (%zd) bytes at address %p (error code: %d)\n",
    133              SanitizerToolName, size, size, addr, GetLastError());
    134       CHECK("unable to unmap" && 0);
    135     }
    136   }
    137 }
    138 
    139 static void *ReturnNullptrOnOOMOrDie(uptr size, const char *mem_type,
    140                                      const char *mmap_type) {
    141   error_t last_error = GetLastError();
    142   if (last_error == ERROR_NOT_ENOUGH_MEMORY)
    143     return nullptr;
    144   ReportMmapFailureAndDie(size, mem_type, mmap_type, last_error);
    145 }
    146 
    147 void *MmapOrDieOnFatalError(uptr size, const char *mem_type) {
    148   void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    149   if (rv == 0)
    150     return ReturnNullptrOnOOMOrDie(size, mem_type, "allocate");
    151   return rv;
    152 }
    153 
    154 // We want to map a chunk of address space aligned to 'alignment'.
    155 void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
    156                                    const char *mem_type) {
    157   CHECK(IsPowerOfTwo(size));
    158   CHECK(IsPowerOfTwo(alignment));
    159 
    160   // Windows will align our allocations to at least 64K.
    161   alignment = Max(alignment, GetMmapGranularity());
    162 
    163   uptr mapped_addr =
    164       (uptr)VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    165   if (!mapped_addr)
    166     return ReturnNullptrOnOOMOrDie(size, mem_type, "allocate aligned");
    167 
    168   // If we got it right on the first try, return. Otherwise, unmap it and go to
    169   // the slow path.
    170   if (IsAligned(mapped_addr, alignment))
    171     return (void*)mapped_addr;
    172   if (VirtualFree((void *)mapped_addr, 0, MEM_RELEASE) == 0)
    173     ReportMmapFailureAndDie(size, mem_type, "deallocate", GetLastError());
    174 
    175   // If we didn't get an aligned address, overallocate, find an aligned address,
    176   // unmap, and try to allocate at that aligned address.
    177   int retries = 0;
    178   const int kMaxRetries = 10;
    179   for (; retries < kMaxRetries &&
    180          (mapped_addr == 0 || !IsAligned(mapped_addr, alignment));
    181        retries++) {
    182     // Overallocate size + alignment bytes.
    183     mapped_addr =
    184         (uptr)VirtualAlloc(0, size + alignment, MEM_RESERVE, PAGE_NOACCESS);
    185     if (!mapped_addr)
    186       return ReturnNullptrOnOOMOrDie(size, mem_type, "allocate aligned");
    187 
    188     // Find the aligned address.
    189     uptr aligned_addr = RoundUpTo(mapped_addr, alignment);
    190 
    191     // Free the overallocation.
    192     if (VirtualFree((void *)mapped_addr, 0, MEM_RELEASE) == 0)
    193       ReportMmapFailureAndDie(size, mem_type, "deallocate", GetLastError());
    194 
    195     // Attempt to allocate exactly the number of bytes we need at the aligned
    196     // address. This may fail for a number of reasons, in which case we continue
    197     // the loop.
    198     mapped_addr = (uptr)VirtualAlloc((void *)aligned_addr, size,
    199                                      MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    200   }
    201 
    202   // Fail if we can't make this work quickly.
    203   if (retries == kMaxRetries && mapped_addr == 0)
    204     return ReturnNullptrOnOOMOrDie(size, mem_type, "allocate aligned");
    205 
    206   return (void *)mapped_addr;
    207 }
    208 
    209 bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) {
    210   // FIXME: is this really "NoReserve"? On Win32 this does not matter much,
    211   // but on Win64 it does.
    212   (void)name;  // unsupported
    213 #if !SANITIZER_GO && SANITIZER_WINDOWS64
    214   // On asan/Windows64, use MEM_COMMIT would result in error
    215   // 1455:ERROR_COMMITMENT_LIMIT.
    216   // Asan uses exception handler to commit page on demand.
    217   void *p = VirtualAlloc((LPVOID)fixed_addr, size, MEM_RESERVE, PAGE_READWRITE);
    218 #else
    219   void *p = VirtualAlloc((LPVOID)fixed_addr, size, MEM_RESERVE | MEM_COMMIT,
    220                          PAGE_READWRITE);
    221 #endif
    222   if (p == 0) {
    223     Report("ERROR: %s failed to "
    224            "allocate %p (%zd) bytes at %p (error code: %d)\n",
    225            SanitizerToolName, size, size, fixed_addr, GetLastError());
    226     return false;
    227   }
    228   return true;
    229 }
    230 
    231 // Memory space mapped by 'MmapFixedOrDie' must have been reserved by
    232 // 'MmapFixedNoAccess'.
    233 void *MmapFixedOrDie(uptr fixed_addr, uptr size) {
    234   void *p = VirtualAlloc((LPVOID)fixed_addr, size,
    235       MEM_COMMIT, PAGE_READWRITE);
    236   if (p == 0) {
    237     char mem_type[30];
    238     internal_snprintf(mem_type, sizeof(mem_type), "memory at address 0x%zx",
    239                       fixed_addr);
    240     ReportMmapFailureAndDie(size, mem_type, "allocate", GetLastError());
    241   }
    242   return p;
    243 }
    244 
    245 // Uses fixed_addr for now.
    246 // Will use offset instead once we've implemented this function for real.
    247 uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size) {
    248   return reinterpret_cast<uptr>(MmapFixedOrDieOnFatalError(fixed_addr, size));
    249 }
    250 
    251 uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size) {
    252   return reinterpret_cast<uptr>(MmapFixedOrDie(fixed_addr, size));
    253 }
    254 
    255 void ReservedAddressRange::Unmap(uptr addr, uptr size) {
    256   // Only unmap if it covers the entire range.
    257   CHECK((addr == reinterpret_cast<uptr>(base_)) && (size == size_));
    258   // We unmap the whole range, just null out the base.
    259   base_ = nullptr;
    260   size_ = 0;
    261   UnmapOrDie(reinterpret_cast<void*>(addr), size);
    262 }
    263 
    264 void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size) {
    265   void *p = VirtualAlloc((LPVOID)fixed_addr, size,
    266       MEM_COMMIT, PAGE_READWRITE);
    267   if (p == 0) {
    268     char mem_type[30];
    269     internal_snprintf(mem_type, sizeof(mem_type), "memory at address 0x%zx",
    270                       fixed_addr);
    271     return ReturnNullptrOnOOMOrDie(size, mem_type, "allocate");
    272   }
    273   return p;
    274 }
    275 
    276 void *MmapNoReserveOrDie(uptr size, const char *mem_type) {
    277   // FIXME: make this really NoReserve?
    278   return MmapOrDie(size, mem_type);
    279 }
    280 
    281 uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) {
    282   base_ = fixed_addr ? MmapFixedNoAccess(fixed_addr, size) : MmapNoAccess(size);
    283   size_ = size;
    284   name_ = name;
    285   (void)os_handle_;  // unsupported
    286   return reinterpret_cast<uptr>(base_);
    287 }
    288 
    289 
    290 void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) {
    291   (void)name; // unsupported
    292   void *res = VirtualAlloc((LPVOID)fixed_addr, size,
    293                            MEM_RESERVE, PAGE_NOACCESS);
    294   if (res == 0)
    295     Report("WARNING: %s failed to "
    296            "mprotect %p (%zd) bytes at %p (error code: %d)\n",
    297            SanitizerToolName, size, size, fixed_addr, GetLastError());
    298   return res;
    299 }
    300 
    301 void *MmapNoAccess(uptr size) {
    302   void *res = VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_NOACCESS);
    303   if (res == 0)
    304     Report("WARNING: %s failed to "
    305            "mprotect %p (%zd) bytes (error code: %d)\n",
    306            SanitizerToolName, size, size, GetLastError());
    307   return res;
    308 }
    309 
    310 bool MprotectNoAccess(uptr addr, uptr size) {
    311   DWORD old_protection;
    312   return VirtualProtect((LPVOID)addr, size, PAGE_NOACCESS, &old_protection);
    313 }
    314 
    315 void ReleaseMemoryPagesToOS(uptr beg, uptr end) {
    316   // This is almost useless on 32-bits.
    317   // FIXME: add madvise-analog when we move to 64-bits.
    318 }
    319 
    320 bool NoHugePagesInRegion(uptr addr, uptr size) {
    321   // FIXME: probably similar to ReleaseMemoryToOS.
    322   return true;
    323 }
    324 
    325 bool DontDumpShadowMemory(uptr addr, uptr length) {
    326   // This is almost useless on 32-bits.
    327   // FIXME: add madvise-analog when we move to 64-bits.
    328   return true;
    329 }
    330 
    331 uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
    332                               uptr *largest_gap_found,
    333                               uptr *max_occupied_addr) {
    334   uptr address = 0;
    335   while (true) {
    336     MEMORY_BASIC_INFORMATION info;
    337     if (!::VirtualQuery((void*)address, &info, sizeof(info)))
    338       return 0;
    339 
    340     if (info.State == MEM_FREE) {
    341       uptr shadow_address = RoundUpTo((uptr)info.BaseAddress + left_padding,
    342                                       alignment);
    343       if (shadow_address + size < (uptr)info.BaseAddress + info.RegionSize)
    344         return shadow_address;
    345     }
    346 
    347     // Move to the next region.
    348     address = (uptr)info.BaseAddress + info.RegionSize;
    349   }
    350   return 0;
    351 }
    352 
    353 bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {
    354   MEMORY_BASIC_INFORMATION mbi;
    355   CHECK(VirtualQuery((void *)range_start, &mbi, sizeof(mbi)));
    356   return mbi.Protect == PAGE_NOACCESS &&
    357          (uptr)mbi.BaseAddress + mbi.RegionSize >= range_end;
    358 }
    359 
    360 void *MapFileToMemory(const char *file_name, uptr *buff_size) {
    361   UNIMPLEMENTED();
    362 }
    363 
    364 void *MapWritableFileToMemory(void *addr, uptr size, fd_t fd, OFF_T offset) {
    365   UNIMPLEMENTED();
    366 }
    367 
    368 static const int kMaxEnvNameLength = 128;
    369 static const DWORD kMaxEnvValueLength = 32767;
    370 
    371 namespace {
    372 
    373 struct EnvVariable {
    374   char name[kMaxEnvNameLength];
    375   char value[kMaxEnvValueLength];
    376 };
    377 
    378 }  // namespace
    379 
    380 static const int kEnvVariables = 5;
    381 static EnvVariable env_vars[kEnvVariables];
    382 static int num_env_vars;
    383 
    384 const char *GetEnv(const char *name) {
    385   // Note: this implementation caches the values of the environment variables
    386   // and limits their quantity.
    387   for (int i = 0; i < num_env_vars; i++) {
    388     if (0 == internal_strcmp(name, env_vars[i].name))
    389       return env_vars[i].value;
    390   }
    391   CHECK_LT(num_env_vars, kEnvVariables);
    392   DWORD rv = GetEnvironmentVariableA(name, env_vars[num_env_vars].value,
    393                                      kMaxEnvValueLength);
    394   if (rv > 0 && rv < kMaxEnvValueLength) {
    395     CHECK_LT(internal_strlen(name), kMaxEnvNameLength);
    396     internal_strncpy(env_vars[num_env_vars].name, name, kMaxEnvNameLength);
    397     num_env_vars++;
    398     return env_vars[num_env_vars - 1].value;
    399   }
    400   return 0;
    401 }
    402 
    403 const char *GetPwd() {
    404   UNIMPLEMENTED();
    405 }
    406 
    407 u32 GetUid() {
    408   UNIMPLEMENTED();
    409 }
    410 
    411 namespace {
    412 struct ModuleInfo {
    413   const char *filepath;
    414   uptr base_address;
    415   uptr end_address;
    416 };
    417 
    418 #if !SANITIZER_GO
    419 int CompareModulesBase(const void *pl, const void *pr) {
    420   const ModuleInfo *l = (const ModuleInfo *)pl, *r = (const ModuleInfo *)pr;
    421   if (l->base_address < r->base_address)
    422     return -1;
    423   return l->base_address > r->base_address;
    424 }
    425 #endif
    426 }  // namespace
    427 
    428 #if !SANITIZER_GO
    429 void DumpProcessMap() {
    430   Report("Dumping process modules:\n");
    431   ListOfModules modules;
    432   modules.init();
    433   uptr num_modules = modules.size();
    434 
    435   InternalMmapVector<ModuleInfo> module_infos(num_modules);
    436   for (size_t i = 0; i < num_modules; ++i) {
    437     module_infos[i].filepath = modules[i].full_name();
    438     module_infos[i].base_address = modules[i].ranges().front()->beg;
    439     module_infos[i].end_address = modules[i].ranges().back()->end;
    440   }
    441   qsort(module_infos.data(), num_modules, sizeof(ModuleInfo),
    442         CompareModulesBase);
    443 
    444   for (size_t i = 0; i < num_modules; ++i) {
    445     const ModuleInfo &mi = module_infos[i];
    446     if (mi.end_address != 0) {
    447       Printf("\t%p-%p %s\n", mi.base_address, mi.end_address,
    448              mi.filepath[0] ? mi.filepath : "[no name]");
    449     } else if (mi.filepath[0]) {
    450       Printf("\t??\?-??? %s\n", mi.filepath);
    451     } else {
    452       Printf("\t???\n");
    453     }
    454   }
    455 }
    456 #endif
    457 
    458 void PrintModuleMap() { }
    459 
    460 void DisableCoreDumperIfNecessary() {
    461   // Do nothing.
    462 }
    463 
    464 void ReExec() {
    465   UNIMPLEMENTED();
    466 }
    467 
    468 void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {}
    469 
    470 bool StackSizeIsUnlimited() {
    471   UNIMPLEMENTED();
    472 }
    473 
    474 void SetStackSizeLimitInBytes(uptr limit) {
    475   UNIMPLEMENTED();
    476 }
    477 
    478 bool AddressSpaceIsUnlimited() {
    479   UNIMPLEMENTED();
    480 }
    481 
    482 void SetAddressSpaceUnlimited() {
    483   UNIMPLEMENTED();
    484 }
    485 
    486 bool IsPathSeparator(const char c) {
    487   return c == '\\' || c == '/';
    488 }
    489 
    490 bool IsAbsolutePath(const char *path) {
    491   UNIMPLEMENTED();
    492 }
    493 
    494 void SleepForSeconds(int seconds) {
    495   Sleep(seconds * 1000);
    496 }
    497 
    498 void SleepForMillis(int millis) {
    499   Sleep(millis);
    500 }
    501 
    502 u64 NanoTime() {
    503   static LARGE_INTEGER frequency = {};
    504   LARGE_INTEGER counter;
    505   if (UNLIKELY(frequency.QuadPart == 0)) {
    506     QueryPerformanceFrequency(&frequency);
    507     CHECK_NE(frequency.QuadPart, 0);
    508   }
    509   QueryPerformanceCounter(&counter);
    510   counter.QuadPart *= 1000ULL * 1000000ULL;
    511   counter.QuadPart /= frequency.QuadPart;
    512   return counter.QuadPart;
    513 }
    514 
    515 u64 MonotonicNanoTime() { return NanoTime(); }
    516 
    517 void Abort() {
    518   internal__exit(3);
    519 }
    520 
    521 #if !SANITIZER_GO
    522 // Read the file to extract the ImageBase field from the PE header. If ASLR is
    523 // disabled and this virtual address is available, the loader will typically
    524 // load the image at this address. Therefore, we call it the preferred base. Any
    525 // addresses in the DWARF typically assume that the object has been loaded at
    526 // this address.
    527 static uptr GetPreferredBase(const char *modname) {
    528   fd_t fd = OpenFile(modname, RdOnly, nullptr);
    529   if (fd == kInvalidFd)
    530     return 0;
    531   FileCloser closer(fd);
    532 
    533   // Read just the DOS header.
    534   IMAGE_DOS_HEADER dos_header;
    535   uptr bytes_read;
    536   if (!ReadFromFile(fd, &dos_header, sizeof(dos_header), &bytes_read) ||
    537       bytes_read != sizeof(dos_header))
    538     return 0;
    539 
    540   // The file should start with the right signature.
    541   if (dos_header.e_magic != IMAGE_DOS_SIGNATURE)
    542     return 0;
    543 
    544   // The layout at e_lfanew is:
    545   // "PE\0\0"
    546   // IMAGE_FILE_HEADER
    547   // IMAGE_OPTIONAL_HEADER
    548   // Seek to e_lfanew and read all that data.
    549   char buf[4 + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER)];
    550   if (::SetFilePointer(fd, dos_header.e_lfanew, nullptr, FILE_BEGIN) ==
    551       INVALID_SET_FILE_POINTER)
    552     return 0;
    553   if (!ReadFromFile(fd, &buf[0], sizeof(buf), &bytes_read) ||
    554       bytes_read != sizeof(buf))
    555     return 0;
    556 
    557   // Check for "PE\0\0" before the PE header.
    558   char *pe_sig = &buf[0];
    559   if (internal_memcmp(pe_sig, "PE\0\0", 4) != 0)
    560     return 0;
    561 
    562   // Skip over IMAGE_FILE_HEADER. We could do more validation here if we wanted.
    563   IMAGE_OPTIONAL_HEADER *pe_header =
    564       (IMAGE_OPTIONAL_HEADER *)(pe_sig + 4 + sizeof(IMAGE_FILE_HEADER));
    565 
    566   // Check for more magic in the PE header.
    567   if (pe_header->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
    568     return 0;
    569 
    570   // Finally, return the ImageBase.
    571   return (uptr)pe_header->ImageBase;
    572 }
    573 
    574 void ListOfModules::init() {
    575   clearOrInit();
    576   HANDLE cur_process = GetCurrentProcess();
    577 
    578   // Query the list of modules.  Start by assuming there are no more than 256
    579   // modules and retry if that's not sufficient.
    580   HMODULE *hmodules = 0;
    581   uptr modules_buffer_size = sizeof(HMODULE) * 256;
    582   DWORD bytes_required;
    583   while (!hmodules) {
    584     hmodules = (HMODULE *)MmapOrDie(modules_buffer_size, __FUNCTION__);
    585     CHECK(EnumProcessModules(cur_process, hmodules, modules_buffer_size,
    586                              &bytes_required));
    587     if (bytes_required > modules_buffer_size) {
    588       // Either there turned out to be more than 256 hmodules, or new hmodules
    589       // could have loaded since the last try.  Retry.
    590       UnmapOrDie(hmodules, modules_buffer_size);
    591       hmodules = 0;
    592       modules_buffer_size = bytes_required;
    593     }
    594   }
    595 
    596   // |num_modules| is the number of modules actually present,
    597   size_t num_modules = bytes_required / sizeof(HMODULE);
    598   for (size_t i = 0; i < num_modules; ++i) {
    599     HMODULE handle = hmodules[i];
    600     MODULEINFO mi;
    601     if (!GetModuleInformation(cur_process, handle, &mi, sizeof(mi)))
    602       continue;
    603 
    604     // Get the UTF-16 path and convert to UTF-8.
    605     wchar_t modname_utf16[kMaxPathLength];
    606     int modname_utf16_len =
    607         GetModuleFileNameW(handle, modname_utf16, kMaxPathLength);
    608     if (modname_utf16_len == 0)
    609       modname_utf16[0] = '\0';
    610     char module_name[kMaxPathLength];
    611     int module_name_len =
    612         ::WideCharToMultiByte(CP_UTF8, 0, modname_utf16, modname_utf16_len + 1,
    613                               &module_name[0], kMaxPathLength, NULL, NULL);
    614     module_name[module_name_len] = '\0';
    615 
    616     uptr base_address = (uptr)mi.lpBaseOfDll;
    617     uptr end_address = (uptr)mi.lpBaseOfDll + mi.SizeOfImage;
    618 
    619     // Adjust the base address of the module so that we get a VA instead of an
    620     // RVA when computing the module offset. This helps llvm-symbolizer find the
    621     // right DWARF CU. In the common case that the image is loaded at it's
    622     // preferred address, we will now print normal virtual addresses.
    623     uptr preferred_base = GetPreferredBase(&module_name[0]);
    624     uptr adjusted_base = base_address - preferred_base;
    625 
    626     LoadedModule cur_module;
    627     cur_module.set(module_name, adjusted_base);
    628     // We add the whole module as one single address range.
    629     cur_module.addAddressRange(base_address, end_address, /*executable*/ true,
    630                                /*writable*/ true);
    631     modules_.push_back(cur_module);
    632   }
    633   UnmapOrDie(hmodules, modules_buffer_size);
    634 }
    635 
    636 void ListOfModules::fallbackInit() { clear(); }
    637 
    638 // We can't use atexit() directly at __asan_init time as the CRT is not fully
    639 // initialized at this point.  Place the functions into a vector and use
    640 // atexit() as soon as it is ready for use (i.e. after .CRT$XIC initializers).
    641 InternalMmapVectorNoCtor<void (*)(void)> atexit_functions;
    642 
    643 int Atexit(void (*function)(void)) {
    644   atexit_functions.push_back(function);
    645   return 0;
    646 }
    647 
    648 static int RunAtexit() {
    649   int ret = 0;
    650   for (uptr i = 0; i < atexit_functions.size(); ++i) {
    651     ret |= atexit(atexit_functions[i]);
    652   }
    653   return ret;
    654 }
    655 
    656 #pragma section(".CRT$XID", long, read)  // NOLINT
    657 __declspec(allocate(".CRT$XID")) int (*__run_atexit)() = RunAtexit;
    658 #endif
    659 
    660 // ------------------ sanitizer_libc.h
    661 fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *last_error) {
    662   // FIXME: Use the wide variants to handle Unicode filenames.
    663   fd_t res;
    664   if (mode == RdOnly) {
    665     res = CreateFileA(filename, GENERIC_READ,
    666                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    667                       nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
    668   } else if (mode == WrOnly) {
    669     res = CreateFileA(filename, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,
    670                       FILE_ATTRIBUTE_NORMAL, nullptr);
    671   } else {
    672     UNIMPLEMENTED();
    673   }
    674   CHECK(res != kStdoutFd || kStdoutFd == kInvalidFd);
    675   CHECK(res != kStderrFd || kStderrFd == kInvalidFd);
    676   if (res == kInvalidFd && last_error)
    677     *last_error = GetLastError();
    678   return res;
    679 }
    680 
    681 void CloseFile(fd_t fd) {
    682   CloseHandle(fd);
    683 }
    684 
    685 bool ReadFromFile(fd_t fd, void *buff, uptr buff_size, uptr *bytes_read,
    686                   error_t *error_p) {
    687   CHECK(fd != kInvalidFd);
    688 
    689   // bytes_read can't be passed directly to ReadFile:
    690   // uptr is unsigned long long on 64-bit Windows.
    691   unsigned long num_read_long;
    692 
    693   bool success = ::ReadFile(fd, buff, buff_size, &num_read_long, nullptr);
    694   if (!success && error_p)
    695     *error_p = GetLastError();
    696   if (bytes_read)
    697     *bytes_read = num_read_long;
    698   return success;
    699 }
    700 
    701 bool SupportsColoredOutput(fd_t fd) {
    702   // FIXME: support colored output.
    703   return false;
    704 }
    705 
    706 bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written,
    707                  error_t *error_p) {
    708   CHECK(fd != kInvalidFd);
    709 
    710   // Handle null optional parameters.
    711   error_t dummy_error;
    712   error_p = error_p ? error_p : &dummy_error;
    713   uptr dummy_bytes_written;
    714   bytes_written = bytes_written ? bytes_written : &dummy_bytes_written;
    715 
    716   // Initialize output parameters in case we fail.
    717   *error_p = 0;
    718   *bytes_written = 0;
    719 
    720   // Map the conventional Unix fds 1 and 2 to Windows handles. They might be
    721   // closed, in which case this will fail.
    722   if (fd == kStdoutFd || fd == kStderrFd) {
    723     fd = GetStdHandle(fd == kStdoutFd ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
    724     if (fd == 0) {
    725       *error_p = ERROR_INVALID_HANDLE;
    726       return false;
    727     }
    728   }
    729 
    730   DWORD bytes_written_32;
    731   if (!WriteFile(fd, buff, buff_size, &bytes_written_32, 0)) {
    732     *error_p = GetLastError();
    733     return false;
    734   } else {
    735     *bytes_written = bytes_written_32;
    736     return true;
    737   }
    738 }
    739 
    740 uptr internal_sched_yield() {
    741   Sleep(0);
    742   return 0;
    743 }
    744 
    745 void internal__exit(int exitcode) {
    746   // ExitProcess runs some finalizers, so use TerminateProcess to avoid that.
    747   // The debugger doesn't stop on TerminateProcess like it does on ExitProcess,
    748   // so add our own breakpoint here.
    749   if (::IsDebuggerPresent())
    750     __debugbreak();
    751   TerminateProcess(GetCurrentProcess(), exitcode);
    752   BUILTIN_UNREACHABLE();
    753 }
    754 
    755 uptr internal_ftruncate(fd_t fd, uptr size) {
    756   UNIMPLEMENTED();
    757 }
    758 
    759 uptr GetRSS() {
    760   PROCESS_MEMORY_COUNTERS counters;
    761   if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)))
    762     return 0;
    763   return counters.WorkingSetSize;
    764 }
    765 
    766 void *internal_start_thread(void (*func)(void *arg), void *arg) { return 0; }
    767 void internal_join_thread(void *th) { }
    768 
    769 // ---------------------- BlockingMutex ---------------- {{{1
    770 
    771 BlockingMutex::BlockingMutex() {
    772   CHECK(sizeof(SRWLOCK) <= sizeof(opaque_storage_));
    773   internal_memset(this, 0, sizeof(*this));
    774 }
    775 
    776 void BlockingMutex::Lock() {
    777   AcquireSRWLockExclusive((PSRWLOCK)opaque_storage_);
    778   CHECK_EQ(owner_, 0);
    779   owner_ = GetThreadSelf();
    780 }
    781 
    782 void BlockingMutex::Unlock() {
    783   CheckLocked();
    784   owner_ = 0;
    785   ReleaseSRWLockExclusive((PSRWLOCK)opaque_storage_);
    786 }
    787 
    788 void BlockingMutex::CheckLocked() {
    789   CHECK_EQ(owner_, GetThreadSelf());
    790 }
    791 
    792 uptr GetTlsSize() {
    793   return 0;
    794 }
    795 
    796 void InitTlsSize() {
    797 }
    798 
    799 void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
    800                           uptr *tls_addr, uptr *tls_size) {
    801 #if SANITIZER_GO
    802   *stk_addr = 0;
    803   *stk_size = 0;
    804   *tls_addr = 0;
    805   *tls_size = 0;
    806 #else
    807   uptr stack_top, stack_bottom;
    808   GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
    809   *stk_addr = stack_bottom;
    810   *stk_size = stack_top - stack_bottom;
    811   *tls_addr = 0;
    812   *tls_size = 0;
    813 #endif
    814 }
    815 
    816 void ReportFile::Write(const char *buffer, uptr length) {
    817   SpinMutexLock l(mu);
    818   ReopenIfNecessary();
    819   if (!WriteToFile(fd, buffer, length)) {
    820     // stderr may be closed, but we may be able to print to the debugger
    821     // instead.  This is the case when launching a program from Visual Studio,
    822     // and the following routine should write to its console.
    823     OutputDebugStringA(buffer);
    824   }
    825 }
    826 
    827 void SetAlternateSignalStack() {
    828   // FIXME: Decide what to do on Windows.
    829 }
    830 
    831 void UnsetAlternateSignalStack() {
    832   // FIXME: Decide what to do on Windows.
    833 }
    834 
    835 void InstallDeadlySignalHandlers(SignalHandlerType handler) {
    836   (void)handler;
    837   // FIXME: Decide what to do on Windows.
    838 }
    839 
    840 HandleSignalMode GetHandleSignalMode(int signum) {
    841   // FIXME: Decide what to do on Windows.
    842   return kHandleSignalNo;
    843 }
    844 
    845 // Check based on flags if we should handle this exception.
    846 bool IsHandledDeadlyException(DWORD exceptionCode) {
    847   switch (exceptionCode) {
    848     case EXCEPTION_ACCESS_VIOLATION:
    849     case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
    850     case EXCEPTION_STACK_OVERFLOW:
    851     case EXCEPTION_DATATYPE_MISALIGNMENT:
    852     case EXCEPTION_IN_PAGE_ERROR:
    853       return common_flags()->handle_segv;
    854     case EXCEPTION_ILLEGAL_INSTRUCTION:
    855     case EXCEPTION_PRIV_INSTRUCTION:
    856     case EXCEPTION_BREAKPOINT:
    857       return common_flags()->handle_sigill;
    858     case EXCEPTION_FLT_DENORMAL_OPERAND:
    859     case EXCEPTION_FLT_DIVIDE_BY_ZERO:
    860     case EXCEPTION_FLT_INEXACT_RESULT:
    861     case EXCEPTION_FLT_INVALID_OPERATION:
    862     case EXCEPTION_FLT_OVERFLOW:
    863     case EXCEPTION_FLT_STACK_CHECK:
    864     case EXCEPTION_FLT_UNDERFLOW:
    865     case EXCEPTION_INT_DIVIDE_BY_ZERO:
    866     case EXCEPTION_INT_OVERFLOW:
    867       return common_flags()->handle_sigfpe;
    868   }
    869   return false;
    870 }
    871 
    872 bool IsAccessibleMemoryRange(uptr beg, uptr size) {
    873   SYSTEM_INFO si;
    874   GetNativeSystemInfo(&si);
    875   uptr page_size = si.dwPageSize;
    876   uptr page_mask = ~(page_size - 1);
    877 
    878   for (uptr page = beg & page_mask, end = (beg + size - 1) & page_mask;
    879        page <= end;) {
    880     MEMORY_BASIC_INFORMATION info;
    881     if (VirtualQuery((LPCVOID)page, &info, sizeof(info)) != sizeof(info))
    882       return false;
    883 
    884     if (info.Protect == 0 || info.Protect == PAGE_NOACCESS ||
    885         info.Protect == PAGE_EXECUTE)
    886       return false;
    887 
    888     if (info.RegionSize == 0)
    889       return false;
    890 
    891     page += info.RegionSize;
    892   }
    893 
    894   return true;
    895 }
    896 
    897 bool SignalContext::IsStackOverflow() const {
    898   return (DWORD)GetType() == EXCEPTION_STACK_OVERFLOW;
    899 }
    900 
    901 void SignalContext::InitPcSpBp() {
    902   EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD *)siginfo;
    903   CONTEXT *context_record = (CONTEXT *)context;
    904 
    905   pc = (uptr)exception_record->ExceptionAddress;
    906 #ifdef _WIN64
    907   bp = (uptr)context_record->Rbp;
    908   sp = (uptr)context_record->Rsp;
    909 #else
    910   bp = (uptr)context_record->Ebp;
    911   sp = (uptr)context_record->Esp;
    912 #endif
    913 }
    914 
    915 uptr SignalContext::GetAddress() const {
    916   EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD *)siginfo;
    917   return exception_record->ExceptionInformation[1];
    918 }
    919 
    920 bool SignalContext::IsMemoryAccess() const {
    921   return GetWriteFlag() != SignalContext::UNKNOWN;
    922 }
    923 
    924 SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
    925   EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD *)siginfo;
    926   // The contents of this array are documented at
    927   // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082(v=vs.85).aspx
    928   // The first element indicates read as 0, write as 1, or execute as 8.  The
    929   // second element is the faulting address.
    930   switch (exception_record->ExceptionInformation[0]) {
    931     case 0:
    932       return SignalContext::READ;
    933     case 1:
    934       return SignalContext::WRITE;
    935     case 8:
    936       return SignalContext::UNKNOWN;
    937   }
    938   return SignalContext::UNKNOWN;
    939 }
    940 
    941 void SignalContext::DumpAllRegisters(void *context) {
    942   // FIXME: Implement this.
    943 }
    944 
    945 int SignalContext::GetType() const {
    946   return static_cast<const EXCEPTION_RECORD *>(siginfo)->ExceptionCode;
    947 }
    948 
    949 const char *SignalContext::Describe() const {
    950   unsigned code = GetType();
    951   // Get the string description of the exception if this is a known deadly
    952   // exception.
    953   switch (code) {
    954     case EXCEPTION_ACCESS_VIOLATION:
    955       return "access-violation";
    956     case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
    957       return "array-bounds-exceeded";
    958     case EXCEPTION_STACK_OVERFLOW:
    959       return "stack-overflow";
    960     case EXCEPTION_DATATYPE_MISALIGNMENT:
    961       return "datatype-misalignment";
    962     case EXCEPTION_IN_PAGE_ERROR:
    963       return "in-page-error";
    964     case EXCEPTION_ILLEGAL_INSTRUCTION:
    965       return "illegal-instruction";
    966     case EXCEPTION_PRIV_INSTRUCTION:
    967       return "priv-instruction";
    968     case EXCEPTION_BREAKPOINT:
    969       return "breakpoint";
    970     case EXCEPTION_FLT_DENORMAL_OPERAND:
    971       return "flt-denormal-operand";
    972     case EXCEPTION_FLT_DIVIDE_BY_ZERO:
    973       return "flt-divide-by-zero";
    974     case EXCEPTION_FLT_INEXACT_RESULT:
    975       return "flt-inexact-result";
    976     case EXCEPTION_FLT_INVALID_OPERATION:
    977       return "flt-invalid-operation";
    978     case EXCEPTION_FLT_OVERFLOW:
    979       return "flt-overflow";
    980     case EXCEPTION_FLT_STACK_CHECK:
    981       return "flt-stack-check";
    982     case EXCEPTION_FLT_UNDERFLOW:
    983       return "flt-underflow";
    984     case EXCEPTION_INT_DIVIDE_BY_ZERO:
    985       return "int-divide-by-zero";
    986     case EXCEPTION_INT_OVERFLOW:
    987       return "int-overflow";
    988   }
    989   return "unknown exception";
    990 }
    991 
    992 uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
    993   // FIXME: Actually implement this function.
    994   CHECK_GT(buf_len, 0);
    995   buf[0] = 0;
    996   return 0;
    997 }
    998 
    999 uptr ReadLongProcessName(/*out*/char *buf, uptr buf_len) {
   1000   return ReadBinaryName(buf, buf_len);
   1001 }
   1002 
   1003 void CheckVMASize() {
   1004   // Do nothing.
   1005 }
   1006 
   1007 void InitializePlatformEarly() {
   1008   // Do nothing.
   1009 }
   1010 
   1011 void MaybeReexec() {
   1012   // No need to re-exec on Windows.
   1013 }
   1014 
   1015 void CheckASLR() {
   1016   // Do nothing
   1017 }
   1018 
   1019 void CheckMPROTECT() {
   1020   // Do nothing
   1021 }
   1022 
   1023 char **GetArgv() {
   1024   // FIXME: Actually implement this function.
   1025   return 0;
   1026 }
   1027 
   1028 char **GetEnviron() {
   1029   // FIXME: Actually implement this function.
   1030   return 0;
   1031 }
   1032 
   1033 pid_t StartSubprocess(const char *program, const char *const argv[],
   1034                       fd_t stdin_fd, fd_t stdout_fd, fd_t stderr_fd) {
   1035   // FIXME: implement on this platform
   1036   // Should be implemented based on
   1037   // SymbolizerProcess::StarAtSymbolizerSubprocess
   1038   // from lib/sanitizer_common/sanitizer_symbolizer_win.cc.
   1039   return -1;
   1040 }
   1041 
   1042 bool IsProcessRunning(pid_t pid) {
   1043   // FIXME: implement on this platform.
   1044   return false;
   1045 }
   1046 
   1047 int WaitForProcess(pid_t pid) { return -1; }
   1048 
   1049 // FIXME implement on this platform.
   1050 void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size) { }
   1051 
   1052 void CheckNoDeepBind(const char *filename, int flag) {
   1053   // Do nothing.
   1054 }
   1055 
   1056 // FIXME: implement on this platform.
   1057 bool GetRandom(void *buffer, uptr length, bool blocking) {
   1058   UNIMPLEMENTED();
   1059 }
   1060 
   1061 u32 GetNumberOfCPUs() {
   1062   SYSTEM_INFO sysinfo = {};
   1063   GetNativeSystemInfo(&sysinfo);
   1064   return sysinfo.dwNumberOfProcessors;
   1065 }
   1066 
   1067 }  // namespace __sanitizer
   1068 
   1069 #endif  // _WIN32
   1070