[compiler-rt] r209653 - [asancov] Write coverage directly to a memory-mapped file.
Timur Iskhodzhanov
timurrrr at google.com
Wed May 28 01:04:32 PDT 2014
Looks like this has broken the build on Windows:
clang_rt.asan-i386.lib(sanitizer_coverage_libcdep.cc.obj) : error
LNK2019: unresolved external symbol "unsigned long __cdecl
__sanitizer::internal_ftruncate(int,unsigned long)"
(?internal_ftruncate at __sanitizer@@YAKHK at Z) referenced in function
"public: void __thiscall __sanitizer::CoverageData::Extend(unsigned
long)" (?Extend at CoverageData@__sanitizer@@QAEXK at Z)
clang_rt.asan-i386.lib(sanitizer_coverage_libcdep.cc.obj) : error
LNK2019: unresolved external symbol "void * __cdecl
__sanitizer::MapWritableFileToMemory(void *,unsigned long,unsigned
long,unsigned long)"
(?MapWritableFileToMemory at __sanitizer@@YAPAXPAXKKK at Z) referenced in
function "public: void __thiscall
__sanitizer::CoverageData::Extend(unsigned long)"
(?Extend at CoverageData@__sanitizer@@QAEXK at Z)
clang_rt.asan-i386.lib(sanitizer_coverage_mapping_libcdep.cc.obj) :
error LNK2019: unresolved external symbol "unsigned long __cdecl
__sanitizer::internal_rename(char const *,char const *)"
(?internal_rename at __sanitizer@@YAKPBD0 at Z) referenced in function "void
__cdecl __sanitizer::CovUpdateMapping(void)"
(?CovUpdateMapping at __sanitizer@@YAXXZ)
2014-05-27 16:37 GMT+04:00 Evgeniy Stepanov <eugeni.stepanov at gmail.com>:
> Author: eugenis
> Date: Tue May 27 07:37:52 2014
> New Revision: 209653
>
> URL: http://llvm.org/viewvc/llvm-project?rev=209653&view=rev
> Log:
> [asancov] Write coverage directly to a memory-mapped file.
>
> This way does not require a __sanitizer_cov_dump() call. That's
> important on Android, where apps can be killed at arbitrary time.
>
> We write raw PCs to disk instead of module offsets; we also write
> memory layout to a separate file. This increases dump size by the
> factor of 2 on 64-bit systems.
>
> Added:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
> - copied, changed from r209626, compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc (with props)
> compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct-large.cc (with props)
> compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct.cc (with props)
> Removed:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc
> Modified:
> compiler-rt/trunk/lib/asan/asan_interceptors.cc
> compiler-rt/trunk/lib/msan/msan_interceptors.cc
> compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
> compiler-rt/trunk/lib/sanitizer_common/scripts/sancov.py
> compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
>
> Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Tue May 27 07:37:52 2014
> @@ -146,6 +146,8 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free,
> } while (false)
> #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
> #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
> +#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res) CovUpdateMapping()
> +#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() CovUpdateMapping()
> #include "sanitizer_common/sanitizer_common_interceptors.inc"
>
> #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(p, s)
>
> Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
> +++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Tue May 27 07:37:52 2014
> @@ -886,25 +886,6 @@ INTERCEPTOR(char *, dlerror, int fake) {
> return res;
> }
>
> -// dlopen() ultimately calls mmap() down inside the loader, which generally
> -// doesn't participate in dynamic symbol resolution. Therefore we won't
> -// intercept its calls to mmap, and we have to hook it here. The loader
> -// initializes the module before returning, so without the dynamic component, we
> -// won't be able to clear the shadow before the initializers. Fixing this would
> -// require putting our own initializer first to clear the shadow.
> -INTERCEPTOR(void *, dlopen, const char *filename, int flag) {
> - ENSURE_MSAN_INITED();
> - EnterLoader();
> - link_map *map = (link_map *)REAL(dlopen)(filename, flag);
> - ExitLoader();
> - if (!__msan_has_dynamic_component() && map) {
> - // If msandr didn't clear the shadow before the initializers ran, we do it
> - // ourselves afterwards.
> - ForEachMappedRegion(map, __msan_unpoison);
> - }
> - return (void *)map;
> -}
> -
> typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
> void *data);
> struct dl_iterate_phdr_data {
> @@ -1234,6 +1215,13 @@ int OnExit() {
> } while (false) // FIXME
> #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
> #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
> +#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, map) \
> + if (!__msan_has_dynamic_component() && map) { \
> + /* If msandr didn't clear the shadow before the initializers ran, we do */ \
> + /* it ourselves afterwards. */ \
> + ForEachMappedRegion((link_map *)map, __msan_unpoison); \
> + }
> +
> #include "sanitizer_common/sanitizer_common_interceptors.inc"
>
> #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
> @@ -1559,7 +1547,6 @@ void InitializeInterceptors() {
> INTERCEPT_FUNCTION(recvfrom);
> INTERCEPT_FUNCTION(dladdr);
> INTERCEPT_FUNCTION(dlerror);
> - INTERCEPT_FUNCTION(dlopen);
> INTERCEPT_FUNCTION(dl_iterate_phdr);
> INTERCEPT_FUNCTION(getrusage);
> INTERCEPT_FUNCTION(sigaction);
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/CMakeLists.txt Tue May 27 07:37:52 2014
> @@ -4,7 +4,6 @@
> set(SANITIZER_SOURCES
> sanitizer_allocator.cc
> sanitizer_common.cc
> - sanitizer_coverage.cc
> sanitizer_deadlock_detector1.cc
> sanitizer_deadlock_detector2.cc
> sanitizer_flags.cc
> @@ -31,6 +30,8 @@ set(SANITIZER_SOURCES
>
> set(SANITIZER_LIBCDEP_SOURCES
> sanitizer_common_libcdep.cc
> + sanitizer_coverage_libcdep.cc
> + sanitizer_coverage_mapping_libcdep.cc
> sanitizer_linux_libcdep.cc
> sanitizer_posix_libcdep.cc
> sanitizer_stacktrace_libcdep.cc
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Tue May 27 07:37:52 2014
> @@ -263,11 +263,6 @@ void DecreaseTotalMmap(uptr size) {
> atomic_fetch_sub(&g_total_mmaped, size, memory_order_relaxed);
> }
>
> -static void (*sandboxing_callback)();
> -void SetSandboxingCallback(void (*f)()) {
> - sandboxing_callback = f;
> -}
> -
> } // namespace __sanitizer
>
> using namespace __sanitizer; // NOLINT
> @@ -300,13 +295,6 @@ void __sanitizer_set_report_path(const c
> }
> }
>
> -void NOINLINE
> -__sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args) {
> - PrepareForSandboxing(args);
> - if (sandboxing_callback)
> - sandboxing_callback();
> -}
> -
> void __sanitizer_report_error_summary(const char *error_summary) {
> Printf("%s\n", error_summary);
> }
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Tue May 27 07:37:52 2014
> @@ -161,6 +161,7 @@ uptr ReadFileToBuffer(const char *file_n
> // (or NULL if the mapping failes). Stores the size of mmaped region
> // in '*buff_size'.
> void *MapFileToMemory(const char *file_name, uptr *buff_size);
> +void *MapWritableFileToMemory(void *addr, uptr size, uptr fd, uptr offset);
>
> // Error report formatting.
> const char *StripPathPrefix(const char *filepath,
> @@ -187,6 +188,8 @@ void PrepareForSandboxing(__sanitizer_sa
> void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args);
> void SetSandboxingCallback(void (*f)());
>
> +void CovUpdateMapping();
> +
> void InitTlsSize();
> uptr GetTlsSize();
>
> @@ -479,6 +482,10 @@ class LoadedModule {
> const char *full_name() const { return full_name_; }
> uptr base_address() const { return base_address_; }
>
> + uptr n_ranges() const { return n_ranges_; }
> + uptr address_range_start(int i) const { return ranges_[i].beg; }
> + uptr address_range_end(int i) const { return ranges_[i].end; }
> +
> private:
> struct AddressRange {
> uptr beg;
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Tue May 27 07:37:52 2014
> @@ -75,6 +75,19 @@
> #define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
> #endif
>
> +#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
> +#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, map) {}
> +#endif
> +
> +#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
> +#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
> +#endif
> +
> +#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
> +#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
> + COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
> +#endif
> +
> struct FileMetadata {
> // For open_memstream().
> char **addr;
> @@ -4036,6 +4049,29 @@ INTERCEPTOR(int, fclose, __sanitizer_FIL
> #define INIT_FCLOSE
> #endif
>
> +#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
> +INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
> + void *ctx;
> + COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
> + void *res = REAL(dlopen)(filename, flag);
> + COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
> + return res;
> +}
> +
> +INTERCEPTOR(int, dlclose, void *handle) {
> + void *ctx;
> + COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
> + int res = REAL(dlclose)(handle);
> + COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
> + return res;
> +}
> +#define INIT_DLOPEN_DLCLOSE \
> + COMMON_INTERCEPT_FUNCTION(dlopen); \
> + COMMON_INTERCEPT_FUNCTION(dlclose);
> +#else
> +#define INIT_DLOPEN_DLCLOSE
> +#endif
> +
> static void InitializeCommonInterceptors() {
> static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
> interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
> @@ -4177,4 +4213,5 @@ static void InitializeCommonInterceptors
> INIT_OBSTACK;
> INIT_FFLUSH;
> INIT_FCLOSE;
> + INIT_DLOPEN_DLCLOSE;
> }
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc Tue May 27 07:37:52 2014
> @@ -41,4 +41,17 @@ bool ColorizeReports() {
> return internal_strcmp(flag, "always") == 0 ||
> (internal_strcmp(flag, "auto") == 0 && PrintsToTtyCached());
> }
> +
> +static void (*sandboxing_callback)();
> +void SetSandboxingCallback(void (*f)()) {
> + sandboxing_callback = f;
> +}
> +
> } // namespace __sanitizer
> +
> +void NOINLINE
> +__sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args) {
> + PrepareForSandboxing(args);
> + if (sandboxing_callback)
> + sandboxing_callback();
> +}
>
> Removed: compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc?rev=209652&view=auto
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc (removed)
> @@ -1,238 +0,0 @@
> -//===-- sanitizer_coverage.cc ---------------------------------------------===//
> -//
> -// The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
> -//===----------------------------------------------------------------------===//
> -//
> -// Sanitizer Coverage.
> -// This file implements run-time support for a poor man's coverage tool.
> -//
> -// Compiler instrumentation:
> -// For every interesting basic block the compiler injects the following code:
> -// if (*Guard) {
> -// __sanitizer_cov();
> -// *Guard = 1;
> -// }
> -// It's fine to call __sanitizer_cov more than once for a given block.
> -//
> -// Run-time:
> -// - __sanitizer_cov(): record that we've executed the PC (GET_CALLER_PC).
> -// - __sanitizer_cov_dump: dump the coverage data to disk.
> -// For every module of the current process that has coverage data
> -// this will create a file module_name.PID.sancov. The file format is simple:
> -// it's just a sorted sequence of 4-byte offsets in the module.
> -//
> -// Eventually, this coverage implementation should be obsoleted by a more
> -// powerful general purpose Clang/LLVM coverage instrumentation.
> -// Consider this implementation as prototype.
> -//
> -// FIXME: support (or at least test with) dlclose.
> -//===----------------------------------------------------------------------===//
> -
> -#include "sanitizer_allocator_internal.h"
> -#include "sanitizer_common.h"
> -#include "sanitizer_libc.h"
> -#include "sanitizer_mutex.h"
> -#include "sanitizer_procmaps.h"
> -#include "sanitizer_stacktrace.h"
> -#include "sanitizer_flags.h"
> -
> -atomic_uint32_t dump_once_guard; // Ensure that CovDump runs only once.
> -
> -// pc_array is the array containing the covered PCs.
> -// To make the pc_array thread- and async-signal-safe it has to be large enough.
> -// 128M counters "ought to be enough for anybody" (4M on 32-bit).
> -// pc_array is allocated with MmapNoReserveOrDie and so it uses only as
> -// much RAM as it really needs.
> -static const uptr kPcArraySize = FIRST_32_SECOND_64(1 << 22, 1 << 27);
> -static uptr *pc_array;
> -static atomic_uintptr_t pc_array_index;
> -
> -static bool cov_sandboxed = false;
> -static int cov_fd = kInvalidFd;
> -static unsigned int cov_max_block_size = 0;
> -
> -namespace __sanitizer {
> -
> -// Simply add the pc into the vector under lock. If the function is called more
> -// than once for a given PC it will be inserted multiple times, which is fine.
> -static void CovAdd(uptr pc) {
> - if (!pc_array) return;
> - uptr idx = atomic_fetch_add(&pc_array_index, 1, memory_order_relaxed);
> - CHECK_LT(idx, kPcArraySize);
> - pc_array[idx] = pc;
> -}
> -
> -void CovInit() {
> - pc_array = reinterpret_cast<uptr *>(
> - MmapNoReserveOrDie(sizeof(uptr) * kPcArraySize, "CovInit"));
> -}
> -
> -static inline bool CompareLess(const uptr &a, const uptr &b) {
> - return a < b;
> -}
> -
> -// Block layout for packed file format: header, followed by module name (no
> -// trailing zero), followed by data blob.
> -struct CovHeader {
> - int pid;
> - unsigned int module_name_length;
> - unsigned int data_length;
> -};
> -
> -static void CovWritePacked(int pid, const char *module, const void *blob,
> - unsigned int blob_size) {
> - if (cov_fd < 0) return;
> - unsigned module_name_length = internal_strlen(module);
> - CovHeader header = {pid, module_name_length, blob_size};
> -
> - if (cov_max_block_size == 0) {
> - // Writing to a file. Just go ahead.
> - internal_write(cov_fd, &header, sizeof(header));
> - internal_write(cov_fd, module, module_name_length);
> - internal_write(cov_fd, blob, blob_size);
> - } else {
> - // Writing to a socket. We want to split the data into appropriately sized
> - // blocks.
> - InternalScopedBuffer<char> block(cov_max_block_size);
> - CHECK_EQ((uptr)block.data(), (uptr)(CovHeader *)block.data());
> - uptr header_size_with_module = sizeof(header) + module_name_length;
> - CHECK_LT(header_size_with_module, cov_max_block_size);
> - unsigned int max_payload_size =
> - cov_max_block_size - header_size_with_module;
> - char *block_pos = block.data();
> - internal_memcpy(block_pos, &header, sizeof(header));
> - block_pos += sizeof(header);
> - internal_memcpy(block_pos, module, module_name_length);
> - block_pos += module_name_length;
> - char *block_data_begin = block_pos;
> - char *blob_pos = (char *)blob;
> - while (blob_size > 0) {
> - unsigned int payload_size = Min(blob_size, max_payload_size);
> - blob_size -= payload_size;
> - internal_memcpy(block_data_begin, blob_pos, payload_size);
> - blob_pos += payload_size;
> - ((CovHeader *)block.data())->data_length = payload_size;
> - internal_write(cov_fd, block.data(),
> - header_size_with_module + payload_size);
> - }
> - }
> -}
> -
> -// If packed = false: <name>.<pid>.<sancov> (name = module name).
> -// If packed = true and name == 0: <pid>.<sancov>.<packed>.
> -// If packed = true and name != 0: <name>.<sancov>.<packed> (name is
> -// user-supplied).
> -static int CovOpenFile(bool packed, const char* name) {
> - InternalScopedBuffer<char> path(1024);
> - if (!packed) {
> - CHECK(name);
> - internal_snprintf((char *)path.data(), path.size(), "%s.%zd.sancov",
> - name, internal_getpid());
> - } else {
> - if (!name)
> - internal_snprintf((char *)path.data(), path.size(), "%zd.sancov.packed",
> - internal_getpid());
> - else
> - internal_snprintf((char *)path.data(), path.size(), "%s.sancov.packed",
> - name);
> - }
> - uptr fd = OpenFile(path.data(), true);
> - if (internal_iserror(fd)) {
> - Report(" SanitizerCoverage: failed to open %s for writing\n", path.data());
> - return -1;
> - }
> - return fd;
> -}
> -
> -// Dump the coverage on disk.
> -static void CovDump() {
> - if (!common_flags()->coverage) return;
> -#if !SANITIZER_WINDOWS
> - if (atomic_fetch_add(&dump_once_guard, 1, memory_order_relaxed))
> - return;
> - uptr size = atomic_load(&pc_array_index, memory_order_relaxed);
> - InternalSort(&pc_array, size, CompareLess);
> - InternalMmapVector<u32> offsets(size);
> - const uptr *vb = pc_array;
> - const uptr *ve = vb + size;
> - MemoryMappingLayout proc_maps(/*cache_enabled*/true);
> - uptr mb, me, off, prot;
> - InternalScopedBuffer<char> module(4096);
> - InternalScopedBuffer<char> path(4096 * 2);
> - for (int i = 0;
> - proc_maps.Next(&mb, &me, &off, module.data(), module.size(), &prot);
> - i++) {
> - if ((prot & MemoryMappingLayout::kProtectionExecute) == 0)
> - continue;
> - while (vb < ve && *vb < mb) vb++;
> - if (vb >= ve) break;
> - if (*vb < me) {
> - offsets.clear();
> - const uptr *old_vb = vb;
> - CHECK_LE(off, *vb);
> - for (; vb < ve && *vb < me; vb++) {
> - uptr diff = *vb - (i ? mb : 0) + off;
> - CHECK_LE(diff, 0xffffffffU);
> - offsets.push_back(static_cast<u32>(diff));
> - }
> - char *module_name = StripModuleName(module.data());
> - if (cov_sandboxed) {
> - if (cov_fd >= 0) {
> - CovWritePacked(internal_getpid(), module_name, offsets.data(),
> - offsets.size() * sizeof(u32));
> - VReport(1, " CovDump: %zd PCs written to packed file\n", vb - old_vb);
> - }
> - } else {
> - // One file per module per process.
> - internal_snprintf((char *)path.data(), path.size(), "%s.%zd.sancov",
> - module_name, internal_getpid());
> - int fd = CovOpenFile(false /* packed */, module_name);
> - if (fd > 0) {
> - internal_write(fd, offsets.data(), offsets.size() * sizeof(u32));
> - internal_close(fd);
> - VReport(1, " CovDump: %s: %zd PCs written\n", path.data(),
> - vb - old_vb);
> - }
> - }
> - InternalFree(module_name);
> - }
> - }
> - if (cov_fd >= 0)
> - internal_close(cov_fd);
> -#endif // !SANITIZER_WINDOWS
> -}
> -
> -void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
> - if (!args) return;
> - if (!common_flags()->coverage) return;
> - cov_sandboxed = args->coverage_sandboxed;
> - if (!cov_sandboxed) return;
> - cov_fd = args->coverage_fd;
> - cov_max_block_size = args->coverage_max_block_size;
> - if (cov_fd < 0)
> - // Pre-open the file now. The sandbox won't allow us to do it later.
> - cov_fd = CovOpenFile(true /* packed */, 0);
> -}
> -
> -int MaybeOpenCovFile(const char *name) {
> - CHECK(name);
> - if (!common_flags()->coverage) return -1;
> - return CovOpenFile(true /* packed */, name);
> -}
> -} // namespace __sanitizer
> -
> -extern "C" {
> -SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov() {
> - CovAdd(StackTrace::GetPreviousInstructionPc(GET_CALLER_PC()));
> -}
> -SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump() { CovDump(); }
> -SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init() { CovInit(); }
> -SANITIZER_INTERFACE_ATTRIBUTE
> -sptr __sanitizer_maybe_open_cov_file(const char *name) {
> - return MaybeOpenCovFile(name);
> -}
> -} // extern "C"
>
> Copied: compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc (from r209626, compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc)
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc?p2=compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc&p1=compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc&r1=209626&r2=209653&rev=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc Tue May 27 07:37:52 2014
> @@ -45,11 +45,10 @@ atomic_uint32_t dump_once_guard; // Ens
> // pc_array is the array containing the covered PCs.
> // To make the pc_array thread- and async-signal-safe it has to be large enough.
> // 128M counters "ought to be enough for anybody" (4M on 32-bit).
> -// pc_array is allocated with MmapNoReserveOrDie and so it uses only as
> -// much RAM as it really needs.
> -static const uptr kPcArraySize = FIRST_32_SECOND_64(1 << 22, 1 << 27);
> -static uptr *pc_array;
> -static atomic_uintptr_t pc_array_index;
> +
> +// With coverage_direct=1 in ASAN_OPTIONS, pc_array memory is mapped to a file.
> +// In this mode, __sanitizer_cov_dump does nothing, and CovUpdateMapping()
> +// dump current memory layout to another file.
>
> static bool cov_sandboxed = false;
> static int cov_fd = kInvalidFd;
> @@ -57,22 +56,114 @@ static unsigned int cov_max_block_size =
>
> namespace __sanitizer {
>
> +class CoverageData {
> + public:
> + void Init();
> + void Extend(uptr npcs);
> + void Add(uptr pc);
> +
> + uptr *data();
> + uptr size();
> +
> + private:
> + // Maximal size pc array may ever grow.
> + // We MmapNoReserve this space to ensure that the array is contiguous.
> + static const uptr kPcArrayMaxSize = FIRST_32_SECOND_64(1 << 22, 1 << 27);
> + // The amount file mapping for the pc array is grown by.
> + static const uptr kPcArrayMmapSize = 64 * 1024;
> +
> + // pc_array is allocated with MmapNoReserveOrDie and so it uses only as
> + // much RAM as it really needs.
> + uptr *pc_array;
> + // Index of the first available pc_array slot.
> + atomic_uintptr_t pc_array_index;
> + // Array size.
> + atomic_uintptr_t pc_array_size;
> + // Current file mapped size of the pc array.
> + uptr pc_array_mapped_size;
> + // Descriptor of the file mapped pc array.
> + int pc_fd;
> + StaticSpinMutex mu;
> +
> + void DirectInit();
> +};
> +
> +static CoverageData coverage_data;
> +
> +void CoverageData::DirectInit() {
> + InternalScopedString path(64);
> + internal_snprintf((char *)path.data(), path.size(), "%zd.sancov.raw",
> + internal_getpid());
> + pc_fd = OpenFile(path.data(), true);
> + if (internal_iserror(pc_fd)) {
> + Report(" Coverage: failed to open %s for writing\n", path.data());
> + Die();
> + }
> +
> + atomic_store(&pc_array_size, 0, memory_order_relaxed);
> + pc_array_mapped_size = 0;
> +
> + CovUpdateMapping();
> +}
> +
> +void CoverageData::Init() {
> + pc_array = reinterpret_cast<uptr *>(
> + MmapNoReserveOrDie(sizeof(uptr) * kPcArrayMaxSize, "CovInit"));
> + if (common_flags()->coverage_direct) {
> + DirectInit();
> + } else {
> + pc_fd = 0;
> + atomic_store(&pc_array_size, kPcArrayMaxSize, memory_order_relaxed);
> + }
> +}
> +
> +// Extend coverage PC array to fit additional npcs elements.
> +void CoverageData::Extend(uptr npcs) {
> + // If pc_fd=0, pc array is a huge anonymous mapping that does not need to be
> + // resized.
> + if (!pc_fd) return;
> + SpinMutexLock l(&mu);
> +
> + uptr size = atomic_load(&pc_array_size, memory_order_relaxed);
> + size += npcs * sizeof(uptr);
> +
> + if (size > pc_array_mapped_size) {
> + uptr new_mapped_size = pc_array_mapped_size;
> + while (size > new_mapped_size) new_mapped_size += kPcArrayMmapSize;
> +
> + // Extend the file and map the new space at the end of pc_array.
> + uptr res = internal_ftruncate(pc_fd, new_mapped_size);
> + int err;
> + if (internal_iserror(res, &err)) {
> + Printf("failed to extend raw coverage file: %d\n", err);
> + Die();
> + }
> + void *p = MapWritableFileToMemory(pc_array + pc_array_mapped_size,
> + new_mapped_size - pc_array_mapped_size,
> + pc_fd, pc_array_mapped_size);
> + CHECK_EQ(p, pc_array + pc_array_mapped_size);
> + pc_array_mapped_size = new_mapped_size;
> + }
> +
> + atomic_store(&pc_array_size, size, memory_order_release);
> +}
> +
> // Simply add the pc into the vector under lock. If the function is called more
> // than once for a given PC it will be inserted multiple times, which is fine.
> -static void CovAdd(uptr pc) {
> +void CoverageData::Add(uptr pc) {
> if (!pc_array) return;
> uptr idx = atomic_fetch_add(&pc_array_index, 1, memory_order_relaxed);
> - CHECK_LT(idx, kPcArraySize);
> + CHECK_LT(idx * sizeof(uptr),
> + atomic_load(&pc_array_size, memory_order_acquire));
> pc_array[idx] = pc;
> }
>
> -void CovInit() {
> - pc_array = reinterpret_cast<uptr *>(
> - MmapNoReserveOrDie(sizeof(uptr) * kPcArraySize, "CovInit"));
> +uptr *CoverageData::data() {
> + return pc_array;
> }
>
> -static inline bool CompareLess(const uptr &a, const uptr &b) {
> - return a < b;
> +uptr CoverageData::size() {
> + return atomic_load(&pc_array_index, memory_order_relaxed);
> }
>
> // Block layout for packed file format: header, followed by module name (no
> @@ -150,15 +241,15 @@ static int CovOpenFile(bool packed, cons
>
> // Dump the coverage on disk.
> static void CovDump() {
> - if (!common_flags()->coverage) return;
> + if (!common_flags()->coverage || common_flags()->coverage_direct) return;
> #if !SANITIZER_WINDOWS
> if (atomic_fetch_add(&dump_once_guard, 1, memory_order_relaxed))
> return;
> - uptr size = atomic_load(&pc_array_index, memory_order_relaxed);
> - InternalSort(&pc_array, size, CompareLess);
> + uptr size = coverage_data.size();
> InternalMmapVector<u32> offsets(size);
> - const uptr *vb = pc_array;
> - const uptr *ve = vb + size;
> + uptr *vb = coverage_data.data();
> + uptr *ve = vb + size;
> + SortArray(vb, size);
> MemoryMappingLayout proc_maps(/*cache_enabled*/true);
> uptr mb, me, off, prot;
> InternalScopedBuffer<char> module(4096);
> @@ -227,10 +318,15 @@ int MaybeOpenCovFile(const char *name) {
>
> extern "C" {
> SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov() {
> - CovAdd(StackTrace::GetPreviousInstructionPc(GET_CALLER_PC()));
> + coverage_data.Add(StackTrace::GetPreviousInstructionPc(GET_CALLER_PC()));
> }
> SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump() { CovDump(); }
> -SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init() { CovInit(); }
> +SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init() {
> + coverage_data.Init();
> +}
> +SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_module_init(uptr npcs) {
> + coverage_data.Extend(npcs);
> +}
> SANITIZER_INTERFACE_ATTRIBUTE
> sptr __sanitizer_maybe_open_cov_file(const char *name) {
> return MaybeOpenCovFile(name);
>
> Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc?rev=209653&view=auto
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc (added)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc Tue May 27 07:37:52 2014
> @@ -0,0 +1,97 @@
> +//===-- sanitizer_coverage_mapping.cc -------------------------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// Mmap-based implementation of sanitizer coverage.
> +//
> +// This is part of the implementation of code coverage that does not require
> +// __sanitizer_cov_dump() call. Data is stored in 2 files per process.
> +//
> +// $pid.sancov.map describes process memory layout in the following text-based
> +// format:
> +// <pointer size in bits> // 1 line, 32 or 64
> +// <mapping start> <mapping end> <base address> <dso name> // repeated
> +// ...
> +// Mapping lines are NOT sorted. This file is updated every time memory layout
> +// is changed (i.e. in dlopen() and dlclose() interceptors).
> +//
> +// $pid.sancov.raw is a binary dump of PC values, sizeof(uptr) each. Again, not
> +// sorted. This file is extended by 64Kb at a time and mapped into memory. It
> +// contains one or more 0 words at the end, up to the next 64Kb aligned offset.
> +//
> +// To convert these 2 files to the usual .sancov format, run sancov.py rawunpack
> +// $pid.sancov.raw.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "sanitizer_allocator_internal.h"
> +#include "sanitizer_libc.h"
> +#include "sanitizer_procmaps.h"
> +
> +namespace __sanitizer {
> +
> +static const uptr kMaxNumberOfModules = 1 << 14;
> +
> +void CovUpdateMapping() {
> + if (!common_flags()->coverage || !common_flags()->coverage_direct) return;
> +
> + int err;
> + InternalScopedString tmp_path(64);
> + internal_snprintf((char *)tmp_path.data(), tmp_path.size(),
> + "%zd.sancov.map.tmp", internal_getpid());
> + uptr map_fd = OpenFile(tmp_path.data(), true);
> + if (internal_iserror(map_fd)) {
> + Report(" Coverage: failed to open %s for writing\n", tmp_path.data());
> + Die();
> + }
> +
> + InternalScopedBuffer<char> modules_data(kMaxNumberOfModules *
> + sizeof(LoadedModule));
> + LoadedModule *modules = (LoadedModule *)modules_data.data();
> + CHECK(modules);
> + int n_modules = GetListOfModules(modules, kMaxNumberOfModules,
> + /* filter */ 0);
> +
> + InternalScopedString line(4096);
> + line.append("%d\n", sizeof(uptr) * 8);
> + uptr res = internal_write(map_fd, line.data(), line.length());
> + if (internal_iserror(res, &err)) {
> + Printf("sancov.map write failed: %d\n", err);
> + Die();
> + }
> + line.clear();
> +
> + for (int i = 0; i < n_modules; ++i) {
> + char *module_name = StripModuleName(modules[i].full_name());
> + for (unsigned j = 0; j < modules[i].n_ranges(); ++j) {
> + line.append("%zx %zx %zx %s\n", modules[i].address_range_start(j),
> + modules[i].address_range_end(j), modules[i].base_address(),
> + module_name);
> + res = internal_write(map_fd, line.data(), line.length());
> + if (internal_iserror(res, &err)) {
> + Printf("sancov.map write failed: %d\n", err);
> + Die();
> + }
> + line.clear();
> + }
> + InternalFree(module_name);
> + }
> +
> + internal_close(map_fd);
> +
> + InternalScopedString path(64);
> + internal_snprintf((char *)path.data(), path.size(), "%zd.sancov.map",
> + internal_getpid());
> + res = internal_rename(tmp_path.data(), path.data());
> + if (internal_iserror(res, &err)) {
> + Printf("sancov.map rename failed: %d\n", err);
> + Die();
> + }
> +}
> +
> +} // namespace __sanitizer
>
> Propchange: compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc
> ------------------------------------------------------------------------------
> svn:eol-style = LF
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc Tue May 27 07:37:52 2014
> @@ -55,6 +55,7 @@ void SetCommonFlagsDefaults(CommonFlags
> f->legacy_pthread_cond = false;
> f->intercept_tls_get_addr = false;
> f->coverage = false;
> + f->coverage_direct = false;
> f->full_address_space = false;
> }
>
> @@ -127,6 +128,10 @@ void ParseCommonFlagsFromString(CommonFl
> ParseFlag(str, &f->coverage, "coverage",
> "If set, coverage information will be dumped at program shutdown (if the "
> "coverage instrumentation was enabled at compile time).");
> + ParseFlag(str, &f->coverage_direct, "coverage_direct",
> + "If set, coverage information will be dumped directly to a memory "
> + "mapped file. This way data is not lost even if the process is "
> + "suddenly killed.");
> ParseFlag(str, &f->full_address_space, "full_address_space",
> "Sanitize complete address space; "
> "by default kernel area on 32-bit platforms will not be sanitized");
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h Tue May 27 07:37:52 2014
> @@ -54,6 +54,7 @@ struct CommonFlags {
> bool help;
> uptr mmap_limit_mb;
> bool coverage;
> + bool coverage_direct;
> bool full_address_space;
> };
>
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h Tue May 27 07:37:52 2014
> @@ -74,6 +74,7 @@ uptr internal_open(const char *filename,
>
> uptr internal_read(fd_t fd, void *buf, uptr count);
> uptr internal_write(fd_t fd, const void *buf, uptr count);
> +uptr internal_ftruncate(fd_t fd, uptr size);
>
> // OS
> uptr internal_filesize(fd_t fd); // -1 on error.
> @@ -83,6 +84,7 @@ uptr internal_fstat(fd_t fd, void *buf);
> uptr internal_dup2(int oldfd, int newfd);
> uptr internal_readlink(const char *path, char *buf, uptr bufsize);
> uptr internal_unlink(const char *path);
> +uptr internal_rename(const char *oldpath, const char *newpath);
> void NORETURN internal__exit(int exitcode);
> uptr internal_lseek(fd_t fd, OFF_T offset, int whence);
>
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Tue May 27 07:37:52 2014
> @@ -134,7 +134,7 @@ uptr internal_open(const char *filename,
>
> uptr OpenFile(const char *filename, bool write) {
> return internal_open(filename,
> - write ? O_WRONLY | O_CREAT /*| O_CLOEXEC*/ : O_RDONLY, 0660);
> + write ? O_RDWR | O_CREAT /*| O_CLOEXEC*/ : O_RDONLY, 0660);
> }
>
> uptr internal_read(fd_t fd, void *buf, uptr count) {
> @@ -151,6 +151,12 @@ uptr internal_write(fd_t fd, const void
> return res;
> }
>
> +uptr internal_ftruncate(fd_t fd, uptr size) {
> + sptr res;
> + HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(ftruncate), fd, size));
> + return res;
> +}
> +
> #if !SANITIZER_LINUX_USES_64BIT_SYSCALLS && !SANITIZER_FREEBSD
> static void stat64_to_stat(struct stat64 *in, struct stat *out) {
> internal_memset(out, 0, sizeof(*out));
> @@ -246,6 +252,15 @@ uptr internal_unlink(const char *path) {
> #endif
> }
>
> +uptr internal_rename(const char *oldpath, const char *newpath) {
> +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
> + return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
> + (uptr)newpath);
> +#else
> + return internal_syscall(SYSCALL(rename), (uptr)oldpath, (uptr)newpath);
> +#endif
> +}
> +
> uptr internal_sched_yield() {
> return internal_syscall(SYSCALL(sched_yield));
> }
> @@ -390,20 +405,6 @@ void GetThreadStackAndTls(bool main, upt
> }
> #endif // SANITIZER_GO
>
> -void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
> - // Some kinds of sandboxes may forbid filesystem access, so we won't be able
> - // to read the file mappings from /proc/self/maps. Luckily, neither the
> - // process will be able to load additional libraries, so it's fine to use the
> - // cached mappings.
> - MemoryMappingLayout::CacheMemoryMappings();
> - // Same for /proc/self/exe in the symbolizer.
> -#if !SANITIZER_GO
> - if (Symbolizer *sym = Symbolizer::GetOrNull())
> - sym->PrepareForSandboxing();
> - CovPrepareForSandboxing(args);
> -#endif
> -}
> -
> enum MutexState {
> MtxUnlocked = 0,
> MtxLocked = 1,
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc Tue May 27 07:37:52 2014
> @@ -22,6 +22,7 @@
> #include "sanitizer_procmaps.h"
> #include "sanitizer_stacktrace.h"
> #include "sanitizer_atomic.h"
> +#include "sanitizer_symbolizer.h"
>
> #include <dlfcn.h>
> #include <pthread.h>
> @@ -529,6 +530,20 @@ void SetIndirectCallWrapper(uptr wrapper
> indirect_call_wrapper = wrapper;
> }
>
> +void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
> + // Some kinds of sandboxes may forbid filesystem access, so we won't be able
> + // to read the file mappings from /proc/self/maps. Luckily, neither the
> + // process will be able to load additional libraries, so it's fine to use the
> + // cached mappings.
> + MemoryMappingLayout::CacheMemoryMappings();
> + // Same for /proc/self/exe in the symbolizer.
> +#if !SANITIZER_GO
> + if (Symbolizer *sym = Symbolizer::GetOrNull())
> + sym->PrepareForSandboxing();
> + CovPrepareForSandboxing(args);
> +#endif
> +}
> +
> } // namespace __sanitizer
>
> #endif // SANITIZER_FREEBSD || SANITIZER_LINUX
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc Tue May 27 07:37:52 2014
> @@ -131,6 +131,14 @@ int internal_fork() {
> return fork();
> }
>
> +uptr internal_rename(const char *oldpath, const char *newpath) {
> + return rename(oldpath, newpath);
> +}
> +
> +uptr internal_ftruncate(fd_t fd, uptr size) {
> + return ftruncate(fd, size);
> +}
> +
> // ----------------- sanitizer_common.h
> bool FileExists(const char *filename) {
> struct stat st;
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Tue May 27 07:37:52 2014
> @@ -203,5 +203,6 @@
> #define SANITIZER_INTERCEPT_OBSTACK SI_LINUX_NOT_ANDROID
> #define SANITIZER_INTERCEPT_FFLUSH SI_NOT_WINDOWS
> #define SANITIZER_INTERCEPT_FCLOSE SI_NOT_WINDOWS
> +#define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE SI_NOT_WINDOWS
>
> #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc Tue May 27 07:37:52 2014
> @@ -206,6 +206,17 @@ void *MapFileToMemory(const char *file_n
> return internal_iserror(map) ? 0 : (void *)map;
> }
>
> +void *MapWritableFileToMemory(void *addr, uptr size, uptr fd, uptr offset) {
> + uptr flags = MAP_SHARED;
> + if (addr) flags |= MAP_FIXED;
> + uptr p = internal_mmap(addr, size, PROT_READ | PROT_WRITE, flags, fd, offset);
> + if (internal_iserror(p)) {
> + Printf("could not map writable file (%zd, %zu, %zu): %zd\n", fd, offset,
> + size, p);
> + return 0;
> + }
> + return (void *)p;
> +}
>
> static inline bool IntervalsAreSeparate(uptr start1, uptr end1,
> uptr start2, uptr end2) {
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/scripts/sancov.py
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/scripts/sancov.py?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/scripts/sancov.py (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/scripts/sancov.py Tue May 27 07:37:52 2014
> @@ -6,6 +6,8 @@
> import array
> import struct
> import sys
> +import bisect
> +import os.path
>
> prog_name = "";
>
> @@ -74,6 +76,63 @@ def Unpack(files):
> for f in files:
> UnpackOneFile(f)
>
> +def UnpackOneRawFile(path, map_path):
> + mem_map = []
> + with open(map_path, mode="rt") as f_map:
> + print >> sys.stderr, "%s: reading map %s" % (prog_name, map_path)
> + bits = int(f_map.readline())
> + for line in f_map:
> + parts = line.rstrip().split()
> + assert len(parts) == 4
> + mem_map.append((int(parts[0], 16),
> + int(parts[1], 16),
> + int(parts[2], 16),
> + parts[3]))
> + mem_map.sort(key=lambda m : m[0])
> + mem_map_keys = [m[0] for m in mem_map]
> +
> + print mem_map
> + with open(path, mode="rb") as f:
> + print >> sys.stderr, "%s: unpacking %s" % (prog_name, path)
> +
> + f.seek(0, 2)
> + size = f.tell()
> + f.seek(0, 0)
> + if bits == 64:
> + typecode = 'L'
> + else:
> + typecode = 'I'
> + pcs = array.array(typecode, f.read(size))
> + mem_map_pcs = [[] for i in range(0, len(mem_map))]
> +
> + for pc in pcs:
> + if pc == 0: continue
> + map_idx = bisect.bisect(mem_map_keys, pc) - 1
> + (start, end, base, module_path) = mem_map[map_idx]
> + print pc
> + print start, end, base, module_path
> + assert pc >= start
> + if pc >= end:
> + print >> sys.stderr, "warning: %s: pc %x outside of any known mapping" % (prog_name, pc)
> + continue
> + mem_map_pcs[map_idx].append(pc - base)
> +
> + for ((start, end, base, module_path), pc_list) in zip(mem_map, mem_map_pcs):
> + if len(pc_list) == 0: continue
> + assert path.endswith('.sancov.raw')
> + dst_path = module_path + '.' + os.path.basename(path)[:-4]
> + print "writing %d PCs to %s" % (len(pc_list), dst_path)
> + arr = array.array('I')
> + arr.fromlist(sorted(pc_list))
> + with open(dst_path, 'ab') as f2:
> + arr.tofile(f2)
> +
> +def RawUnpack(files):
> + for f in files:
> + if not f.endswith('.sancov.raw'):
> + raise Exception('Unexpected raw file name %s' % f)
> + f_map = f[:-3] + 'map'
> + UnpackOneRawFile(f, f_map)
>
> if __name__ == '__main__':
> prog_name = sys.argv[0]
> @@ -85,5 +144,7 @@ if __name__ == '__main__':
> MergeAndPrint(sys.argv[2:])
> elif sys.argv[1] == "unpack":
> Unpack(sys.argv[2:])
> + elif sys.argv[1] == "rawunpack":
> + RawUnpack(sys.argv[2:])
> else:
> Usage()
>
> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=209653&r1=209652&r2=209653&view=diff
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Tue May 27 07:37:52 2014
> @@ -207,7 +207,7 @@ ScopedInterceptor::~ScopedInterceptor()
> if (REAL(func) == 0) { \
> Report("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \
> Die(); \
> - } \
> + } \
> if (thr->ignore_interceptors || thr->in_ignored_lib) \
> return REAL(func)(__VA_ARGS__); \
> /**/
> @@ -259,20 +259,6 @@ TSAN_INTERCEPTOR(int, nanosleep, void *r
> return res;
> }
>
> -TSAN_INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
> - SCOPED_INTERCEPTOR_RAW(dlopen, filename, flag);
> - void *res = REAL(dlopen)(filename, flag);
> - libignore()->OnLibraryLoaded(filename);
> - return res;
> -}
> -
> -TSAN_INTERCEPTOR(int, dlclose, void *handle) {
> - SCOPED_INTERCEPTOR_RAW(dlclose, handle);
> - int res = REAL(dlclose)(handle);
> - libignore()->OnLibraryUnloaded();
> - return res;
> -}
> -
> class AtExitContext {
> public:
> AtExitContext()
> @@ -2021,6 +2007,12 @@ static void HandleRecvmsg(ThreadState *t
> ctx = (void *)&_ctx; \
> (void) ctx;
>
> +#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, func, ...) \
> + SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
> + TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
> + ctx = (void *)&_ctx; \
> + (void) ctx;
> +
> #define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) \
> Acquire(thr, pc, File2addr(path)); \
> if (file) { \
> @@ -2034,6 +2026,12 @@ static void HandleRecvmsg(ThreadState *t
> if (fd >= 0) FdClose(thr, pc, fd); \
> }
>
> +#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res) \
> + libignore()->OnLibraryLoaded(filename)
> +
> +#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() \
> + libignore()->OnLibraryUnloaded()
> +
> #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
> FdAcquire(((TsanInterceptorContext *) ctx)->thr, pc, fd)
>
> @@ -2376,8 +2374,6 @@ void InitializeInterceptors() {
>
> TSAN_INTERCEPT(fork);
> TSAN_INTERCEPT(vfork);
> - TSAN_INTERCEPT(dlopen);
> - TSAN_INTERCEPT(dlclose);
> TSAN_INTERCEPT(on_exit);
> TSAN_INTERCEPT(__cxa_atexit);
> TSAN_INTERCEPT(_exit);
>
> Added: compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct-large.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct-large.cc?rev=209653&view=auto
> ==============================================================================
> --- compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct-large.cc (added)
> +++ compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct-large.cc Tue May 27 07:37:52 2014
> @@ -0,0 +1,45 @@
> +// Test for direct coverage writing with lots of data.
> +// Current implementation maps output file in chunks of 64K. This test overflows
> +// 1 chunk.
> +// RUN: %clangxx_asan -mllvm -asan-coverage=1 -O0 %s -o %t
> +
> +// RUN: rm -rf %T/coverage-direct-large
> +
> +// RUN: mkdir -p %T/coverage-direct-large/normal && cd %T/coverage-direct-large/normal
> +// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:verbosity=1 %run %t
> +// RUN: %sancov print *.sancov >out.txt
> +// RUN: cd ../..
> +
> +// RUN: mkdir -p %T/coverage-direct-large/direct && cd %T/coverage-direct-large/direct
> +// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:verbosity=1 %run %t
> +// RUN: %sancov rawunpack *.sancov.raw
> +// RUN: %sancov print *.sancov >out.txt
> +// RUN: cd ../..
> +
> +// RUN: diff -u coverage-direct-large/normal/out.txt coverage-direct-large/direct/out.txt
> +//
> +// XFAIL: android
> +
> +#define F0(Q, x) Q(x)
> +#define F1(Q, x) \
> + F0(Q, x##0) F0(Q, x##1) F0(Q, x##2) F0(Q, x##3) F0(Q, x##4) F0(Q, x##5) \
> + F0(Q, x##6) F0(Q, x##7) F0(Q, x##8) F0(Q, x##9)
> +#define F2(Q, x) \
> + F1(Q, x##0) F1(Q, x##1) F1(Q, x##2) F1(Q, x##3) F1(Q, x##4) F1(Q, x##5) \
> + F1(Q, x##6) F1(Q, x##7) F1(Q, x##8) F1(Q, x##9)
> +#define F3(Q, x) \
> + F2(Q, x##0) F2(Q, x##1) F2(Q, x##2) F2(Q, x##3) F2(Q, x##4) F2(Q, x##5) \
> + F2(Q, x##6) F2(Q, x##7) F2(Q, x##8) F2(Q, x##9)
> +#define F4(Q, x) \
> + F3(Q, x##0) F3(Q, x##1) F3(Q, x##2) F3(Q, x##3) F3(Q, x##4) F3(Q, x##5) \
> + F3(Q, x##6) F3(Q, x##7) F3(Q, x##8) F3(Q, x##9)
> +
> +#define DECL(x) __attribute__((noinline)) void x() {}
> +#define CALL(x) x();
> +
> +F4(DECL, f)
> +
> +int main(void) {
> + F4(CALL, f)
> + return 0;
> +}
>
> Propchange: compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct-large.cc
> ------------------------------------------------------------------------------
> svn:eol-style = LF
>
> Added: compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct.cc?rev=209653&view=auto
> ==============================================================================
> --- compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct.cc (added)
> +++ compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct.cc Tue May 27 07:37:52 2014
> @@ -0,0 +1,44 @@
> +// Test for direct coverage writing with dlopen.
> +// RUN: %clangxx_asan -mllvm -asan-coverage=1 -DSHARED %s -shared -o %T/libcoverage_direct_test_1.so -fPIC
> +// RUN: %clangxx_asan -mllvm -asan-coverage=1 -DSO_DIR=\"%T\" %s -o %t
> +
> +// RUN: rm -rf %T/coverage-direct
> +
> +// RUN: mkdir -p %T/coverage-direct/normal && cd %T/coverage-direct/normal
> +// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:verbosity=1 %run %t
> +// RUN: %sancov print *.sancov >out.txt
> +// RUN: cd ../..
> +
> +// RUN: mkdir -p %T/coverage-direct/direct && cd %T/coverage-direct/direct
> +// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:verbosity=1 %run %t
> +// RUN: %sancov rawunpack *.sancov.raw
> +// RUN: %sancov print *.sancov >out.txt
> +// RUN: cd ../..
> +
> +// RUN: diff -u coverage-direct/normal/out.txt coverage-direct/direct/out.txt
> +//
> +// XFAIL: android
> +
> +#include <assert.h>
> +#include <dlfcn.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +#ifdef SHARED
> +extern "C" {
> +void bar() { printf("bar\n"); }
> +}
> +#else
> +
> +int main(int argc, char **argv) {
> + fprintf(stderr, "PID: %d\n", getpid());
> + void *handle1 =
> + dlopen(SO_DIR "/libcoverage_direct_test_1.so", RTLD_LAZY);
> + assert(handle1);
> + void (*bar1)() = (void (*)())dlsym(handle1, "bar");
> + assert(bar1);
> + bar1();
> +
> + return 0;
> +}
> +#endif
>
> Propchange: compiler-rt/trunk/test/asan/TestCases/Linux/coverage-direct.cc
> ------------------------------------------------------------------------------
> svn:eol-style = LF
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list