diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:03:21 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:03:21 +0000 |
commit | 4e3a0d5a8f750527f2f433019967f8f8214c558a (patch) | |
tree | ab93a9af59dcc83ceaf0deabab831818cc44e49c /lib | |
parent | 5c909fa013fc285f010a95e8d387e0ef3412da9c (diff) | |
download | src-test2-4e3a0d5a8f750527f2f433019967f8f8214c558a.tar.gz src-test2-4e3a0d5a8f750527f2f433019967f8f8214c558a.zip |
Notes
Diffstat (limited to 'lib')
-rw-r--r-- | lib/asan/asan_win_dll_thunk.cc | 1 | ||||
-rw-r--r-- | lib/profile/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/profile/GCDAProfiling.c | 6 | ||||
-rw-r--r-- | lib/profile/InstrProfData.inc | 21 | ||||
-rw-r--r-- | lib/profile/InstrProfilingFile.c | 4 | ||||
-rw-r--r-- | lib/profile/InstrProfilingPort.h | 22 | ||||
-rw-r--r-- | lib/profile/WindowsMMap.c | 128 | ||||
-rw-r--r-- | lib/profile/WindowsMMap.h | 65 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_coverage_libcdep.cc | 19 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_flags.inc | 3 |
10 files changed, 252 insertions, 20 deletions
diff --git a/lib/asan/asan_win_dll_thunk.cc b/lib/asan/asan_win_dll_thunk.cc index 308196d307cc..672cabf43ec1 100644 --- a/lib/asan/asan_win_dll_thunk.cc +++ b/lib/asan/asan_win_dll_thunk.cc @@ -315,6 +315,7 @@ INTERFACE_FUNCTION(__sanitizer_cov_trace_switch) INTERFACE_FUNCTION(__sanitizer_cov_with_check) INTERFACE_FUNCTION(__sanitizer_get_allocated_size) INTERFACE_FUNCTION(__sanitizer_get_coverage_guards) +INTERFACE_FUNCTION(__sanitizer_get_coverage_pc_buffer) INTERFACE_FUNCTION(__sanitizer_get_current_allocated_bytes) INTERFACE_FUNCTION(__sanitizer_get_estimated_allocated_size) INTERFACE_FUNCTION(__sanitizer_get_free_bytes) diff --git a/lib/profile/CMakeLists.txt b/lib/profile/CMakeLists.txt index 1b10ade0eee6..3f84c0e6db35 100644 --- a/lib/profile/CMakeLists.txt +++ b/lib/profile/CMakeLists.txt @@ -35,7 +35,8 @@ set(PROFILE_SOURCES InstrProfilingPlatformLinux.c InstrProfilingPlatformOther.c InstrProfilingRuntime.cc - InstrProfilingUtil.c) + InstrProfilingUtil.c + WindowsMMap.c) if(UNIX) set(EXTRA_FLAGS diff --git a/lib/profile/GCDAProfiling.c b/lib/profile/GCDAProfiling.c index aec232856e74..2338761ae1ab 100644 --- a/lib/profile/GCDAProfiling.c +++ b/lib/profile/GCDAProfiling.c @@ -27,8 +27,13 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> + +#if defined(_WIN32) +#include "WindowsMMap.h" +#else #include <sys/mman.h> #include <sys/file.h> +#endif #define I386_FREEBSD (defined(__FreeBSD__) && defined(__i386__)) @@ -37,6 +42,7 @@ #endif #if defined(_MSC_VER) +typedef unsigned char uint8_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; #elif I386_FREEBSD diff --git a/lib/profile/InstrProfData.inc b/lib/profile/InstrProfData.inc index 48dae506cabb..3a7c0c5f2773 100644 --- a/lib/profile/InstrProfData.inc +++ b/lib/profile/InstrProfData.inc @@ -1,4 +1,4 @@ -/*===-- InstrProfData.inc - instr profiling runtime structures -----------=== *\ +/*===-- InstrProfData.inc - instr profiling runtime structures -*- C++ -*-=== *\ |* |* The LLVM Compiler Infrastructure |* @@ -167,6 +167,25 @@ COVMAP_FUNC_RECORD(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \ #undef COVMAP_FUNC_RECORD /* COVMAP_FUNC_RECORD end. */ +/* COVMAP_HEADER start */ +/* Definition of member fields of coverage map header. + */ +#ifndef COVMAP_HEADER +#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) +#else +#define INSTR_PROF_DATA_DEFINED +#endif +COVMAP_HEADER(uint32_t, Int32Ty, NRecords, \ + llvm::ConstantInt::get(Int32Ty, FunctionRecords.size())) +COVMAP_HEADER(uint32_t, Int32Ty, FilenamesSize, \ + llvm::ConstantInt::get(Int32Ty, FilenamesSize)) +COVMAP_HEADER(uint32_t, Int32Ty, CoverageSize, \ + llvm::ConstantInt::get(Int32Ty, CoverageMappingSize)) +COVMAP_HEADER(uint32_t, Int32Ty, Version, \ + llvm::ConstantInt::get(Int32Ty, CoverageMappingVersion1)) +#undef COVMAP_HEADER +/* COVMAP_HEADER end. */ + #ifdef INSTR_PROF_VALUE_PROF_DATA #define INSTR_PROF_DATA_DEFINED diff --git a/lib/profile/InstrProfilingFile.c b/lib/profile/InstrProfilingFile.c index 4ea7fbf9738a..bf50c02761d3 100644 --- a/lib/profile/InstrProfilingFile.c +++ b/lib/profile/InstrProfilingFile.c @@ -17,6 +17,10 @@ #define UNCONST(ptr) ((void *)(uintptr_t)(ptr)) +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + /* Return 1 if there is an error, otherwise return 0. */ static uint32_t fileWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs, void **WriterCtx) { diff --git a/lib/profile/InstrProfilingPort.h b/lib/profile/InstrProfilingPort.h index da4f18fcbb46..5da814a4a3d7 100644 --- a/lib/profile/InstrProfilingPort.h +++ b/lib/profile/InstrProfilingPort.h @@ -47,26 +47,12 @@ if (GetEnvHook && GetEnvHook("LLVM_PROFILE_VERBOSE_ERRORS")) \ fprintf(stderr, Format, __VA_ARGS__); -#if defined(__FreeBSD__) && defined(__i386__) +#if defined(__FreeBSD__) -/* System headers define 'size_t' incorrectly on x64 FreeBSD (prior to - * FreeBSD 10, r232261) when compiled in 32-bit mode. - */ -#define PRIu64 "llu" -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -typedef uint32_t uintptr_t; -#elif defined(__FreeBSD__) && defined(__x86_64__) -#define PRIu64 "lu" -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -typedef unsigned long int uintptr_t; +#include <inttypes.h> +#include <sys/types.h> -#else /* defined(__FreeBSD__) && defined(__i386__) */ +#else /* defined(__FreeBSD__) */ #include <inttypes.h> #include <stdint.h> diff --git a/lib/profile/WindowsMMap.c b/lib/profile/WindowsMMap.c new file mode 100644 index 000000000000..1f7342050032 --- /dev/null +++ b/lib/profile/WindowsMMap.c @@ -0,0 +1,128 @@ +/* + * This code is derived from uClibc (original license follows). + * https://git.uclibc.org/uClibc/tree/utils/mmap-windows.c + */ + /* mmap() replacement for Windows + * + * Author: Mike Frysinger <vapier@gentoo.org> + * Placed into the public domain + */ + +/* References: + * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx + * CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx + * MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx + * UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx + */ + +#if defined(_WIN32) + +#include "WindowsMMap.h" +#include "InstrProfiling.h" + +#ifdef __USE_FILE_OFFSET64 +# define DWORD_HI(x) (x >> 32) +# define DWORD_LO(x) ((x) & 0xffffffff) +#else +# define DWORD_HI(x) (0) +# define DWORD_LO(x) (x) +#endif + +COMPILER_RT_VISIBILITY +void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) +{ + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) + return MAP_FAILED; + if (fd == -1) { + if (!(flags & MAP_ANON) || offset) + return MAP_FAILED; + } else if (flags & MAP_ANON) + return MAP_FAILED; + + DWORD flProtect; + if (prot & PROT_WRITE) { + if (prot & PROT_EXEC) + flProtect = PAGE_EXECUTE_READWRITE; + else + flProtect = PAGE_READWRITE; + } else if (prot & PROT_EXEC) { + if (prot & PROT_READ) + flProtect = PAGE_EXECUTE_READ; + else if (prot & PROT_EXEC) + flProtect = PAGE_EXECUTE; + } else + flProtect = PAGE_READONLY; + + off_t end = length + offset; + HANDLE mmap_fd, h; + if (fd == -1) + mmap_fd = INVALID_HANDLE_VALUE; + else + mmap_fd = (HANDLE)_get_osfhandle(fd); + h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL); + if (h == NULL) + return MAP_FAILED; + + DWORD dwDesiredAccess; + if (prot & PROT_WRITE) + dwDesiredAccess = FILE_MAP_WRITE; + else + dwDesiredAccess = FILE_MAP_READ; + if (prot & PROT_EXEC) + dwDesiredAccess |= FILE_MAP_EXECUTE; + if (flags & MAP_PRIVATE) + dwDesiredAccess |= FILE_MAP_COPY; + void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length); + if (ret == NULL) { + CloseHandle(h); + ret = MAP_FAILED; + } + return ret; +} + +COMPILER_RT_VISIBILITY +void munmap(void *addr, size_t length) +{ + UnmapViewOfFile(addr); + /* ruh-ro, we leaked handle from CreateFileMapping() ... */ +} + +COMPILER_RT_VISIBILITY +int msync(void *addr, size_t length, int flags) +{ + if (flags & MS_INVALIDATE) + return -1; /* Not supported. */ + + /* Exactly one of MS_ASYNC or MS_SYNC must be specified. */ + switch (flags & (MS_ASYNC | MS_SYNC)) { + case MS_SYNC: + case MS_ASYNC: + break; + default: + return -1; + } + + if (!FlushViewOfFile(addr, length)) + return -1; + + if (flags & MS_SYNC) { + /* FIXME: No longer have access to handle from CreateFileMapping(). */ + /* + * if (!FlushFileBuffers(h)) + * return -1; + */ + } + + return 0; +} + +COMPILER_RT_VISIBILITY +int flock(int fd, int operation) +{ + return -1; /* Not supported. */ +} + +#undef DWORD_HI +#undef DWORD_LO + +#endif /* _WIN32 */ diff --git a/lib/profile/WindowsMMap.h b/lib/profile/WindowsMMap.h new file mode 100644 index 000000000000..7b94eb28230c --- /dev/null +++ b/lib/profile/WindowsMMap.h @@ -0,0 +1,65 @@ +/*===- WindowsMMap.h - Support library for PGO instrumentation ------------===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file is distributed under the University of Illinois Open Source +|* License. See LICENSE.TXT for details. +|* +\*===----------------------------------------------------------------------===*/ + +#ifndef PROFILE_INSTRPROFILING_WINDOWS_MMAP_H +#define PROFILE_INSTRPROFILING_WINDOWS_MMAP_H + +#if defined(_WIN32) + +#include <BaseTsd.h> +#include <io.h> +#include <sys/types.h> + +/* + * mmap() flags + */ +#define PROT_READ 0x1 +#define PROT_WRITE 0x2 +/* This flag is only available in WinXP+ */ +#ifdef FILE_MAP_EXECUTE +#define PROT_EXEC 0x4 +#else +#define PROT_EXEC 0x0 +#define FILE_MAP_EXECUTE 0 +#endif + +#define MAP_FILE 0x00 +#define MAP_SHARED 0x01 +#define MAP_PRIVATE 0x02 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FAILED ((void *) -1) + +/* + * msync() flags + */ +#define MS_ASYNC 0x0001 /* return immediately */ +#define MS_INVALIDATE 0x0002 /* invalidate all cached data */ +#define MS_SYNC 0x0010 /* msync synchronously */ + +/* + * flock() operations + */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* don't block when locking */ +#define LOCK_UN 8 /* unlock */ + +void *mmap(void *start, size_t length, int prot, int flags, int fd, + off_t offset); + +void munmap(void *addr, size_t length); + +int msync(void *addr, size_t length, int flags); + +int flock(int fd, int operation); + +#endif /* _WIN32 */ + +#endif /* PROFILE_INSTRPROFILING_WINDOWS_MMAP_H */ diff --git a/lib/sanitizer_common/sanitizer_coverage_libcdep.cc b/lib/sanitizer_common/sanitizer_coverage_libcdep.cc index b9833c5a1d97..eaa1446afd44 100644 --- a/lib/sanitizer_common/sanitizer_coverage_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_coverage_libcdep.cc @@ -108,6 +108,7 @@ class CoverageData { uptr *data(); uptr size(); + uptr *buffer() const { return pc_buffer; } private: void DirectOpen(); @@ -133,6 +134,8 @@ class CoverageData { // Descriptor of the file mapped pc array. fd_t pc_fd; + uptr *pc_buffer; + // Vector of coverage guard arrays, protected by mu. InternalMmapVectorNoCtor<s32*> guard_array_vec; @@ -209,6 +212,11 @@ void CoverageData::Enable() { atomic_store(&pc_array_size, kPcArrayMaxSize, memory_order_relaxed); } + pc_buffer = nullptr; + if (common_flags()->coverage_pc_buffer) + pc_buffer = reinterpret_cast<uptr *>(MmapNoReserveOrDie( + sizeof(uptr) * kPcArrayMaxSize, "CovInit::pc_buffer")); + cc_array = reinterpret_cast<uptr **>(MmapNoReserveOrDie( sizeof(uptr *) * kCcArrayMaxSize, "CovInit::cc_array")); atomic_store(&cc_array_size, kCcArrayMaxSize, memory_order_relaxed); @@ -246,6 +254,10 @@ void CoverageData::Disable() { UnmapOrDie(cc_array, sizeof(uptr *) * kCcArrayMaxSize); cc_array = nullptr; } + if (pc_buffer) { + UnmapOrDie(pc_buffer, sizeof(uptr) * kPcArrayMaxSize); + pc_buffer = nullptr; + } if (tr_event_array) { UnmapOrDie(tr_event_array, sizeof(tr_event_array[0]) * kTrEventArrayMaxSize + @@ -414,6 +426,7 @@ void CoverageData::Add(uptr pc, u32 *guard) { atomic_load(&pc_array_size, memory_order_acquire)); uptr counter = atomic_fetch_add(&coverage_counter, 1, memory_order_relaxed); pc_array[idx] = BundlePcAndCounter(pc, counter); + if (pc_buffer) pc_buffer[counter] = pc; } // Registers a pair caller=>callee. @@ -944,6 +957,12 @@ uptr __sanitizer_get_coverage_guards(uptr **data) { } SANITIZER_INTERFACE_ATTRIBUTE +uptr __sanitizer_get_coverage_pc_buffer(uptr **data) { + *data = coverage_data.buffer(); + return __sanitizer_get_total_unique_coverage(); +} + +SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_number_of_counters() { return coverage_data.GetNumberOf8bitCounters(); } diff --git a/lib/sanitizer_common/sanitizer_flags.inc b/lib/sanitizer_common/sanitizer_flags.inc index c89273117a5e..c28f7f4a6034 100644 --- a/lib/sanitizer_common/sanitizer_flags.inc +++ b/lib/sanitizer_common/sanitizer_flags.inc @@ -144,6 +144,9 @@ COMMON_FLAG(bool, coverage_direct, SANITIZER_ANDROID, COMMON_FLAG(const char *, coverage_dir, ".", "Target directory for coverage dumps. Defaults to the current " "directory.") +COMMON_FLAG(bool, coverage_pc_buffer, true, + "If set (and if 'coverage' is set too), the pcs would be collected " + "in a buffer.") COMMON_FLAG(bool, full_address_space, false, "Sanitize complete address space; " "by default kernel area on 32-bit platforms will not be sanitized") |