diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/CMakeLists.txt | 22 | ||||
-rw-r--r-- | include/sanitizer/allocator_interface.h | 7 | ||||
-rw-r--r-- | include/sanitizer/asan_interface.h | 4 | ||||
-rw-r--r-- | include/sanitizer/coverage_interface.h | 7 | ||||
-rw-r--r-- | include/sanitizer/hwasan_interface.h | 33 | ||||
-rw-r--r-- | include/sanitizer/lsan_interface.h | 6 | ||||
-rw-r--r-- | include/sanitizer/scudo_interface.h | 34 | ||||
-rw-r--r-- | include/sanitizer/tsan_interface.h | 6 | ||||
-rw-r--r-- | include/xray/xray_interface.h | 8 | ||||
-rw-r--r-- | include/xray/xray_log_interface.h | 50 | ||||
-rw-r--r-- | include/xray/xray_records.h | 37 |
11 files changed, 208 insertions, 6 deletions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index ec3bf40b95e6..f7efb102ab63 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -6,9 +6,11 @@ if (COMPILER_RT_BUILD_SANITIZERS) sanitizer/coverage_interface.h sanitizer/dfsan_interface.h sanitizer/esan_interface.h + sanitizer/hwasan_interface.h sanitizer/linux_syscall_hooks.h sanitizer/lsan_interface.h sanitizer/msan_interface.h + sanitizer/scudo_interface.h sanitizer/tsan_interface.h sanitizer/tsan_interface_atomic.h) endif(COMPILER_RT_BUILD_SANITIZERS) @@ -21,7 +23,7 @@ endif(COMPILER_RT_BUILD_XRAY) set(COMPILER_RT_HEADERS ${SANITIZER_HEADERS} - ${XRAY_HEADERS}) + ${XRAY_HEADERS}) set(output_dir ${COMPILER_RT_OUTPUT_DIR}/include) @@ -43,9 +45,27 @@ set_target_properties(compiler-rt-headers PROPERTIES FOLDER "Compiler-RT Misc") # Install sanitizer headers. install(FILES ${SANITIZER_HEADERS} + COMPONENT compiler-rt-headers PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ DESTINATION ${COMPILER_RT_INSTALL_PATH}/include/sanitizer) # Install xray headers. install(FILES ${XRAY_HEADERS} + COMPONENT compiler-rt-headers PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ DESTINATION ${COMPILER_RT_INSTALL_PATH}/include/xray) + +if (NOT CMAKE_CONFIGURATION_TYPES) # don't add this for IDEs. + add_custom_target(install-compiler-rt-headers + DEPENDS compiler-rt-headers + COMMAND "${CMAKE_COMMAND}" + -DCMAKE_INSTALL_COMPONENT="compiler-rt-headers" + -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" + USES_TERMINAL) + add_custom_target(install-compiler-rt-headers-stripped + DEPENDS compiler-rt-headers + COMMAND "${CMAKE_COMMAND}" + -DCMAKE_INSTALL_COMPONENT="compiler-rt-headers" + -DCMAKE_INSTALL_DO_STRIP=1 + -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" + USES_TERMINAL) +endif() diff --git a/include/sanitizer/allocator_interface.h b/include/sanitizer/allocator_interface.h index 5220631619fc..2d35804b3764 100644 --- a/include/sanitizer/allocator_interface.h +++ b/include/sanitizer/allocator_interface.h @@ -76,6 +76,13 @@ extern "C" { void (*malloc_hook)(const volatile void *, size_t), void (*free_hook)(const volatile void *)); + /* Drains allocator quarantines (calling thread's and global ones), returns + freed memory back to OS and releases other non-essential internal allocator + resources in attempt to reduce process RSS. + Currently available with ASan only. + */ + void __sanitizer_purge_allocator(); + #ifdef __cplusplus } // extern "C" #endif diff --git a/include/sanitizer/asan_interface.h b/include/sanitizer/asan_interface.h index 97ba0ceb0b23..e689a730e2c3 100644 --- a/include/sanitizer/asan_interface.h +++ b/include/sanitizer/asan_interface.h @@ -144,6 +144,10 @@ extern "C" { void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg, void **end); + // Performs cleanup before a [[noreturn]] function. Must be called + // before things like _exit and execl to avoid false positives on stack. + void __asan_handle_no_return(void); + #ifdef __cplusplus } // extern "C" #endif diff --git a/include/sanitizer/coverage_interface.h b/include/sanitizer/coverage_interface.h index 637379d47c41..081033cec8e5 100644 --- a/include/sanitizer/coverage_interface.h +++ b/include/sanitizer/coverage_interface.h @@ -22,8 +22,11 @@ extern "C" { // Record and dump coverage info. void __sanitizer_cov_dump(); - // Dump collected coverage info. Sorts pcs by module into individual - // .sancov files. + // Clear collected coverage info. + void __sanitizer_cov_reset(); + + // Dump collected coverage info. Sorts pcs by module into individual .sancov + // files. void __sanitizer_dump_coverage(const uintptr_t *pcs, uintptr_t len); #ifdef __cplusplus diff --git a/include/sanitizer/hwasan_interface.h b/include/sanitizer/hwasan_interface.h new file mode 100644 index 000000000000..f70d87875968 --- /dev/null +++ b/include/sanitizer/hwasan_interface.h @@ -0,0 +1,33 @@ +//===-- sanitizer/asan_interface.h ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of HWAddressSanitizer. +// +// Public interface header. +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_HWASAN_INTERFACE_H +#define SANITIZER_HWASAN_INTERFACE_H + +#include <sanitizer/common_interface_defs.h> + +#ifdef __cplusplus +extern "C" { +#endif + // This function may be optionally provided by user and should return + // a string containing HWASan runtime options. See asan_flags.h for details. + const char* __hwasan_default_options(); + + void __hwasan_enable_allocator_tagging(); + void __hwasan_disable_allocator_tagging(); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // SANITIZER_HWASAN_INTERFACE_H diff --git a/include/sanitizer/lsan_interface.h b/include/sanitizer/lsan_interface.h index 8fb8e756da26..e3e509ff7d9f 100644 --- a/include/sanitizer/lsan_interface.h +++ b/include/sanitizer/lsan_interface.h @@ -64,8 +64,14 @@ extern "C" { // for the program it is linked into (if the return value is non-zero). This // function must be defined as returning a constant value; any behavior beyond // that is unsupported. + // To avoid dead stripping, you may need to define this function with + // __attribute__((used)) int __lsan_is_turned_off(); + // This function may be optionally provided by user and should return + // a string containing LSan runtime options. See lsan_flags.inc for details. + const char *__lsan_default_options(); + // This function may be optionally provided by the user and should return // a string containing LSan suppressions. const char *__lsan_default_suppressions(); diff --git a/include/sanitizer/scudo_interface.h b/include/sanitizer/scudo_interface.h new file mode 100644 index 000000000000..cab7e0f5f344 --- /dev/null +++ b/include/sanitizer/scudo_interface.h @@ -0,0 +1,34 @@ +//===-- sanitizer/scudo_interface.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// Public Scudo interface header. +// +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_SCUDO_INTERFACE_H_ +#define SANITIZER_SCUDO_INTERFACE_H_ + +#include <sanitizer/common_interface_defs.h> + +#ifdef __cplusplus +extern "C" { +#endif + // This function may be optionally provided by a user and should return + // a string containing Scudo runtime options. See scudo_flags.h for details. + const char* __scudo_default_options(); + + // This function allows to set the RSS limit at runtime. This can be either + // the hard limit (HardLimit=1) or the soft limit (HardLimit=0). The limit + // can be removed by setting LimitMb to 0. This function's parameters should + // be fully trusted to avoid security mishaps. + void __scudo_set_rss_limit(unsigned long LimitMb, int HardLimit); +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // SANITIZER_SCUDO_INTERFACE_H_ diff --git a/include/sanitizer/tsan_interface.h b/include/sanitizer/tsan_interface.h index 5ea09ab5c1ff..530885014ac3 100644 --- a/include/sanitizer/tsan_interface.h +++ b/include/sanitizer/tsan_interface.h @@ -44,6 +44,11 @@ const unsigned __tsan_mutex_linker_init = 1 << 0; const unsigned __tsan_mutex_write_reentrant = 1 << 1; // Mutex is read reentrant. const unsigned __tsan_mutex_read_reentrant = 1 << 2; +// Mutex does not have static storage duration, and must not be used after +// its destructor runs. The opposite of __tsan_mutex_linker_init. +// If this flag is passed to __tsan_mutex_destroy, then the destruction +// is ignored unless this flag was previously set on the mutex. +const unsigned __tsan_mutex_not_static = 1 << 8; // Mutex operation flags: @@ -70,6 +75,7 @@ void __tsan_mutex_create(void *addr, unsigned flags); // Annotate destruction of a mutex. // Supported flags: // - __tsan_mutex_linker_init +// - __tsan_mutex_not_static void __tsan_mutex_destroy(void *addr, unsigned flags); // Annotate start of lock operation. diff --git a/include/xray/xray_interface.h b/include/xray/xray_interface.h index 564613417069..d08039a67fa2 100644 --- a/include/xray/xray_interface.h +++ b/include/xray/xray_interface.h @@ -106,6 +106,14 @@ extern uintptr_t __xray_function_address(int32_t FuncId); /// encounter errors (when there are no instrumented functions, etc.). extern size_t __xray_max_function_id(); +/// Initialize the required XRay data structures. This is useful in cases where +/// users want to control precisely when the XRay instrumentation data +/// structures are initialized, for example when the XRay library is built with +/// the XRAY_NO_PREINIT preprocessor definition. +/// +/// Calling __xray_init() more than once is safe across multiple threads. +extern void __xray_init(); + } // end extern "C" #endif // XRAY_XRAY_INTERFACE_H diff --git a/include/xray/xray_log_interface.h b/include/xray/xray_log_interface.h index cdb20094dc26..6c53cdaebfe2 100644 --- a/include/xray/xray_log_interface.h +++ b/include/xray/xray_log_interface.h @@ -128,6 +128,16 @@ enum XRayLogFlushStatus { XRAY_LOG_FLUSHED = 2, }; +/// This enum indicates the installation state of a logging implementation, when +/// associating a mode to a particular logging implementation through +/// `__xray_log_register_impl(...)` or through `__xray_log_select_mode(...`. +enum XRayLogRegisterStatus { + XRAY_REGISTRATION_OK = 0, + XRAY_DUPLICATE_MODE = 1, + XRAY_MODE_NOT_FOUND = 2, + XRAY_INCOMPLETE_IMPL = 3, +}; + /// A valid XRay logging implementation MUST provide all of the function /// pointers in XRayLogImpl when being installed through `__xray_set_log_impl`. /// To be precise, ALL the functions pointers MUST NOT be nullptr. @@ -159,6 +169,9 @@ struct XRayLogImpl { /// always have a handler for function entry and exit events. In case the /// implementation wants to support arg1 (or other future extensions to XRay /// logging) those MUST be installed by the installed 'log_init' handler. + /// + /// Because we didn't want to change the ABI of this struct, the arg1 handler + /// may be silently overwritten during initialization as well. void (*handle_arg0)(int32_t, XRayEntryType); /// The log implementation provided routine for when __xray_log_flushLog() is @@ -186,6 +199,34 @@ struct XRayLogImpl { /// called while in any other states. void __xray_set_log_impl(XRayLogImpl Impl); +/// This function registers a logging implementation against a "mode" +/// identifier. This allows multiple modes to be registered, and chosen at +/// runtime using the same mode identifier through +/// `__xray_log_select_mode(...)`. +/// +/// We treat the Mode identifier as a null-terminated byte string, as the +/// identifier used when retrieving the log impl. +/// +/// Returns: +/// - XRAY_REGISTRATION_OK on success. +/// - XRAY_DUPLICATE_MODE when an implementation is already associated with +/// the provided Mode; does not update the already-registered +/// implementation. +XRayLogRegisterStatus __xray_log_register_mode(const char *Mode, + XRayLogImpl Impl); + +/// This function selects the implementation associated with Mode that has been +/// registered through __xray_log_register_mode(...) and installs that +/// implementation (as if through calling __xray_set_log_impl(...)). The same +/// caveats apply to __xray_log_select_mode(...) as with +/// __xray_log_set_log_impl(...). +/// +/// Returns: +/// - XRAY_REGISTRATION_OK on success. +/// - XRAY_MODE_NOT_FOUND if there is no implementation associated with Mode; +/// does not update the currently installed implementation. +XRayLogRegisterStatus __xray_log_select_mode(const char *Mode); + /// This function removes the currently installed implementation. It will also /// uninstall any handlers that have been previously installed. It does NOT /// unpatch the instrumentation sleds. @@ -220,12 +261,19 @@ XRayLogFlushStatus __xray_log_flushLog(); namespace __xray { -// Options used by the LLVM XRay FDR implementation. +/// Options used by the LLVM XRay FDR logging implementation. struct FDRLoggingOptions { bool ReportErrors = false; int Fd = -1; }; +/// Options used by the LLVM XRay Basic (Naive) logging implementation. +struct BasicLoggingOptions { + int DurationFilterMicros = 0; + size_t MaxStackDepth = 0; + size_t ThreadBufferSize = 0; +}; + } // namespace __xray #endif // XRAY_XRAY_LOG_INTERFACE_H diff --git a/include/xray/xray_records.h b/include/xray/xray_records.h index feb8d228b2fd..d4b7b4c31a9a 100644 --- a/include/xray/xray_records.h +++ b/include/xray/xray_records.h @@ -17,6 +17,8 @@ #ifndef XRAY_XRAY_RECORDS_H #define XRAY_XRAY_RECORDS_H +#include <cstdint> + namespace __xray { enum FileTypes { @@ -65,18 +67,23 @@ static_assert(sizeof(XRayFileHeader) == 32, "XRayFileHeader != 32 bytes"); enum RecordTypes { NORMAL = 0, + ARG_PAYLOAD = 1, }; struct alignas(32) XRayRecord { // This is the type of the record being written. We use 16 bits to allow us to // treat this as a discriminant, and so that the first 4 bytes get packed // properly. See RecordTypes for more supported types. - uint16_t RecordType = 0; + uint16_t RecordType = RecordTypes::NORMAL; // The CPU where the thread is running. We assume number of CPUs <= 256. uint8_t CPU = 0; - // The type of the event. Usually either ENTER = 0 or EXIT = 1. + // The type of the event. One of the following: + // ENTER = 0 + // EXIT = 1 + // TAIL_EXIT = 2 + // ENTER_ARG = 3 uint8_t Type = 0; // The function ID for the record. @@ -94,6 +101,32 @@ struct alignas(32) XRayRecord { static_assert(sizeof(XRayRecord) == 32, "XRayRecord != 32 bytes"); +struct alignas(32) XRayArgPayload { + // We use the same 16 bits as a discriminant for the records in the log here + // too, and so that the first 4 bytes are packed properly. + uint16_t RecordType = RecordTypes::ARG_PAYLOAD; + + // Add a few bytes to pad. + uint8_t Padding[2] = {}; + + // The function ID for the record. + int32_t FuncId = 0; + + // The thread ID for the currently running thread. + uint32_t TId = 0; + + // Add more padding. + uint8_t Padding2[4] = {}; + + // The argument payload. + uint64_t Arg = 0; + + // The rest of this record ought to be left as padding. + uint8_t TailPadding[8] = {}; +} __attribute__((packed)); + +static_assert(sizeof(XRayArgPayload) == 32, "XRayArgPayload != 32 bytes"); + } // namespace __xray #endif // XRAY_XRAY_RECORDS_H |