Index: compiler-rt/trunk/include/sanitizer/asan_interface.h
===================================================================
--- compiler-rt/trunk/include/sanitizer/asan_interface.h
+++ compiler-rt/trunk/include/sanitizer/asan_interface.h
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file is a part of AddressSanitizer.
+// This file is a part of AddressSanitizer (ASan).
//
// Public interface header.
//===----------------------------------------------------------------------===//
@@ -18,28 +18,54 @@
#ifdef __cplusplus
extern "C" {
#endif
- // Marks memory region [addr, addr+size) as unaddressable.
- // This memory must be previously allocated by the user program. Accessing
- // addresses in this region from instrumented code is forbidden until
- // this region is unpoisoned. This function is not guaranteed to poison
- // the whole region - it may poison only subregion of [addr, addr+size) due
- // to ASan alignment restrictions.
- // Method is NOT thread-safe in the sense that no two threads can
- // (un)poison memory in the same memory region simultaneously.
- void __asan_poison_memory_region(void const volatile *addr, size_t size);
- // Marks memory region [addr, addr+size) as addressable.
- // This memory must be previously allocated by the user program. Accessing
- // addresses in this region is allowed until this region is poisoned again.
- // This function may unpoison a superregion of [addr, addr+size) due to
- // ASan alignment restrictions.
- // Method is NOT thread-safe in the sense that no two threads can
- // (un)poison memory in the same memory region simultaneously.
- void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
+/// Marks a memory region ([addr, addr+size)) as unaddressable.
+///
+/// This memory must be previously allocated by your program. Instrumented
+/// code is forbidden from accessing addresses in this region until it is
+/// unpoisoned. This function is not guaranteed to poison the entire region -
+/// it could poison only a subregion of [addr, addr+size) due to ASan
+/// alignment restrictions.
+///
+/// \note This function is not thread-safe because no two threads can poison or
+/// unpoison memory in the same memory region simultaneously.
+///
+/// \param addr Start of memory region.
+/// \param size Size of memory region.
+void __asan_poison_memory_region(void const volatile *addr, size_t size);
+
+/// Marks a memory region ([addr, addr+size)) as addressable.
+///
+/// This memory must be previously allocated by your program. Accessing
+/// addresses in this region is allowed until this region is poisoned again.
+/// This function could unpoison a super-region of [addr, addr+size) due
+/// to ASan alignment restrictions.
+///
+/// \note This function is not thread-safe because no two threads can
+/// poison or unpoison memory in the same memory region simultaneously.
+///
+/// \param addr Start of memory region.
+/// \param size Size of memory region.
+void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
-// User code should use macros instead of functions.
+// Macros provided for convenience.
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+/// Marks a memory region as unaddressable.
+///
+/// \note Macro provided for convenience; defined as a no-op if ASan is not
+/// enabled.
+///
+/// \param addr Start of memory region.
+/// \param size Size of memory region.
#define ASAN_POISON_MEMORY_REGION(addr, size) \
__asan_poison_memory_region((addr), (size))
+
+/// Marks a memory region as addressable.
+///
+/// \note Macro provided for convenience; defined as a no-op if ASan is not
+/// enabled.
+///
+/// \param addr Start of memory region.
+/// \param size Size of memory region.
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
__asan_unpoison_memory_region((addr), (size))
#else
@@ -49,103 +75,245 @@
((void)(addr), (void)(size))
#endif
- // Returns 1 if addr is poisoned (i.e. 1-byte read/write access to this
- // address will result in error report from AddressSanitizer).
- // Otherwise returns 0.
- int __asan_address_is_poisoned(void const volatile *addr);
-
- // If at least one byte in [beg, beg+size) is poisoned, return the address
- // of the first such byte. Otherwise return 0.
- void *__asan_region_is_poisoned(void *beg, size_t size);
-
- // Print the description of addr (useful when debugging in gdb).
- void __asan_describe_address(void *addr);
-
- // Useful for calling from a debugger to get information about an ASan error.
- // Returns 1 if an error has been (or is being) reported, otherwise returns 0.
- int __asan_report_present(void);
-
- // Useful for calling from a debugger to get information about an ASan error.
- // If an error has been (or is being) reported, the following functions return
- // the pc, bp, sp, address, access type (0 = read, 1 = write), access size and
- // bug description (e.g. "heap-use-after-free"). Otherwise they return 0.
- void *__asan_get_report_pc(void);
- void *__asan_get_report_bp(void);
- void *__asan_get_report_sp(void);
- void *__asan_get_report_address(void);
- int __asan_get_report_access_type(void);
- size_t __asan_get_report_access_size(void);
- const char *__asan_get_report_description(void);
-
- // Useful for calling from the debugger to get information about a pointer.
- // Returns the category of the given pointer as a constant string.
- // Possible return values are "global", "stack", "stack-fake", "heap",
- // "heap-invalid", "shadow-low", "shadow-gap", "shadow-high", "unknown".
- // If global or stack, tries to also return the variable name, address and
- // size. If heap, tries to return the chunk address and size. 'name' should
- // point to an allocated buffer of size 'name_size'.
- const char *__asan_locate_address(void *addr, char *name, size_t name_size,
- void **region_address, size_t *region_size);
-
- // Useful for calling from the debugger to get the allocation stack trace
- // and thread ID for a heap address. Stores up to 'size' frames into 'trace',
- // returns the number of stored frames or 0 on error.
- size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size,
- int *thread_id);
-
- // Useful for calling from the debugger to get the free stack trace
- // and thread ID for a heap address. Stores up to 'size' frames into 'trace',
- // returns the number of stored frames or 0 on error.
- size_t __asan_get_free_stack(void *addr, void **trace, size_t size,
- int *thread_id);
-
- // Useful for calling from the debugger to get the current shadow memory
- // mapping.
- void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset);
-
- // This is an internal function that is called to report an error.
- // However it is still a part of the interface because users may want to
- // set a breakpoint on this function in a debugger.
- void __asan_report_error(void *pc, void *bp, void *sp,
- void *addr, int is_write, size_t access_size);
-
- // Deprecated. Call __sanitizer_set_death_callback instead.
- void __asan_set_death_callback(void (*callback)(void));
-
- void __asan_set_error_report_callback(void (*callback)(const char*));
-
- // User may provide function that would be called right when ASan detects
- // an error. This can be used to notice cases when ASan detects an error, but
- // the program crashes before ASan report is printed.
- void __asan_on_error(void);
-
- // Prints accumulated stats to stderr. Used for debugging.
- void __asan_print_accumulated_stats(void);
-
- // This function may be optionally provided by user and should return
- // a string containing ASan runtime options. See asan_flags.h for details.
- const char* __asan_default_options(void);
-
- // The following 2 functions facilitate garbage collection in presence of
- // asan's fake stack.
-
- // Returns an opaque handler to be used later in __asan_addr_is_in_fake_stack.
- // Returns NULL if the current thread does not have a fake stack.
- void *__asan_get_current_fake_stack(void);
-
- // If fake_stack is non-NULL and addr belongs to a fake frame in
- // fake_stack, returns the address on real stack that corresponds to
- // the fake frame and sets beg/end to the boundaries of this fake frame.
- // Otherwise returns NULL and does not touch beg/end.
- // If beg/end are NULL, they are not touched.
- // This function may be called from a thread other than the owner of
- // fake_stack, but the owner thread need to be alive.
- 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);
+/// Checks if an address is poisoned.
+///
+/// Returns 1 if addr is poisoned (that is, 1-byte read/write
+/// access to this address would result in an error report from ASan).
+/// Otherwise returns 0.
+///
+/// \param addr Address to check.
+///
+/// \retval 1 Address is poisoned.
+/// \retval 0 Address is not poisoned.
+int __asan_address_is_poisoned(void const volatile *addr);
+
+/// Checks if a region is poisoned.
+///
+/// If at least one byte in [beg, beg+size) is poisoned, returns the
+/// address of the first such byte. Otherwise returns 0.
+///
+/// \param beg Start of memory region.
+/// \param size Start of memory region.
+/// \returns Address of first poisoned byte.
+void *__asan_region_is_poisoned(void *beg, size_t size);
+
+/// Describes an address (useful for calling from the debugger).
+///
+/// Prints the description of addr.
+///
+/// \param addr Address to describe.
+void __asan_describe_address(void *addr);
+
+/// Checks if an error has been or is being reported (useful for calling from
+/// the debugger to get information about an ASan error).
+///
+/// Returns 1 if an error has been (or is being) reported. Otherwise returns 0.
+///
+/// \returns 1 if an error has been (or is being) reported. Otherwise returns
+/// 0.
+int __asan_report_present(void);
+
+/// Gets the PC (program counter) register value of an ASan error (useful for
+/// calling from the debugger).
+///
+/// Returns PC if an error has been (or is being) reported.
+/// Otherwise returns 0.
+///
+/// \returns PC value.
+void *__asan_get_report_pc(void);
+
+/// Gets the BP (base pointer) register value of an ASan error (useful for
+/// calling from the debugger).
+///
+/// Returns BP if an error has been (or is being) reported.
+/// Otherwise returns 0.
+///
+/// \returns BP value.
+void *__asan_get_report_bp(void);
+
+/// Gets the SP (stack pointer) register value of an ASan error (useful for
+/// calling from the debugger).
+///
+/// If an error has been (or is being) reported, returns SP.
+/// Otherwise returns 0.
+///
+/// \returns SP value.
+void *__asan_get_report_sp(void);
+
+/// Gets the address of the report buffer of an ASan error (useful for calling
+/// from the debugger).
+///
+/// Returns the address of the report buffer if an error has been (or is being)
+/// reported. Otherwise returns 0.
+///
+/// \returns Address of report buffer.
+void *__asan_get_report_address(void);
+
+/// Gets access type of an ASan error (useful for calling from the debugger).
+///
+/// Returns access type (read or write) if an error has been (or is being)
+/// reported. Otherwise returns 0.
+///
+/// \returns Access type (0 = read, 1 = write).
+int __asan_get_report_access_type(void);
+
+/// Gets access size of an ASan error (useful for calling from the debugger).
+///
+/// Returns access size if an error has been (or is being) reported. Otherwise
+/// returns 0.
+///
+/// \returns Access size in bytes.
+size_t __asan_get_report_access_size(void);
+
+/// Gets the bug description of an ASan error (useful for calling from a
+/// debugger).
+///
+/// \returns Returns a bug description if an error has been (or is being)
+/// reported - for example, "heap-use-after-free". Otherwise returns an empty
+/// string.
+const char *__asan_get_report_description(void);
+
+/// Gets information about a pointer (useful for calling from the debugger).
+///
+/// Returns the category of the given pointer as a constant string.
+/// Possible return values are global, stack, stack-fake,
+/// heap, heap-invalid, shadow-low, shadow-gap,
+/// shadow-high, and unknown.
+///
+/// If the return value is global or stack, tries to also return
+/// the variable name, address, and size. If the return value is heap,
+/// tries to return the chunk address and size. name should point
+/// to an allocated buffer of size name_size.
+///
+/// \param addr Address to locate.
+/// \param name Buffer to store the variable's name.
+/// \param name_size Size in bytes of the variable's name buffer.
+/// \param region_address [out] Address of the region.
+/// \param region_size [out] Size of the region in bytes.
+///
+/// \returns Returns the category of the given pointer as a constant string.
+const char *__asan_locate_address(void *addr, char *name, size_t name_size,
+ void **region_address, size_t *region_size);
+
+/// Gets the allocation stack trace and thread ID for a heap address (useful
+/// for calling from the debugger).
+///
+/// Stores up to size frames in trace. Returns
+/// the number of stored frames or 0 on error.
+///
+/// \param addr A heap address.
+/// \param trace A buffer to store the stack trace.
+/// \param size Size in bytes of the trace buffer.
+/// \param thread_id [out] The thread ID of the address.
+///
+/// \returns Returns the number of stored frames or 0 on error.
+size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size,
+ int *thread_id);
+
+/// Gets the free stack trace and thread ID for a heap address (useful for
+/// calling from the debugger).
+///
+/// Stores up to size frames in trace. Returns
+/// the number of stored frames or 0 on error.
+///
+/// \param addr A heap address.
+/// \param trace A buffer to store the stack trace.
+/// \param size Size in bytes of the trace buffer.
+/// \param thread_id [out] The thread ID of the address.
+///
+/// \returns Returns the number of stored frames or 0 on error.
+size_t __asan_get_free_stack(void *addr, void **trace, size_t size,
+ int *thread_id);
+
+/// Gets the current shadow memory mapping (useful for calling from the
+/// debugger).
+///
+/// \param shadow_scale [out] Shadow scale value.
+/// \param shadow_offset [out] Offset value.
+void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset);
+
+/// This is an internal function that is called to report an error. However,
+/// it is still a part of the interface because you might want to set a
+/// breakpoint on this function in the debugger.
+///
+/// \param pc pc value of the ASan error.
+/// \param bp bp value of the ASan error.
+/// \param sp sp value of the ASan error.
+/// \param addr Address of the ASan error.
+/// \param is_write True if the error is a write error; false otherwise.
+/// \param access_size Size of the memory access of the ASan error.
+void __asan_report_error(void *pc, void *bp, void *sp,
+ void *addr, int is_write, size_t access_size);
+
+// Deprecated. Call __sanitizer_set_death_callback instead.
+void __asan_set_death_callback(void (*callback)(void));
+
+/// Sets the callback function to be called during ASan error reporting.
+///
+/// The callback provides a string pointer to the report.
+///
+/// \param callback User-provided function.
+void __asan_set_error_report_callback(void (*callback)(const char *));
+
+/// User-provided callback on ASan errors.
+///
+/// You can provide a function that would be called immediately when ASan
+/// detects an error. This is useful in cases when ASan detects an error but
+/// your program crashes before the ASan report is printed.
+void __asan_on_error(void);
+
+/// Prints accumulated statistics to stderr (useful for calling from the
+/// debugger).
+void __asan_print_accumulated_stats(void);
+
+/// User-provided default option settings.
+///
+/// You can provide your own implementation of this function to return a string
+/// containing ASan runtime options (for example,
+/// verbosity=1:halt_on_error=0).
+///
+/// \returns Default options string.
+const char* __asan_default_options(void);
+
+// The following two functions facilitate garbage collection in presence of
+// ASan's fake stack.
+
+/// Gets an opaque handler to the current thread's fake stack.
+///
+/// Returns an opaque handler to be used by
+/// __asan_addr_is_in_fake_stack(). Returns NULL if the current thread
+/// does not have a fake stack.
+///
+/// \returns An opaque handler to the fake stack or NULL.
+void *__asan_get_current_fake_stack(void);
+
+/// Checks if an address belongs to a given fake stack.
+///
+/// If fake_stack is non-NULL and addr belongs to a
+/// fake frame in fake_stack, returns the address of the real
+/// stack that corresponds to the fake frame and sets beg and
+/// end to the boundaries of this fake frame. Otherwise returns
+/// NULL and does not touch beg and end.
+///
+/// If beg or end are NULL, they are not touched.
+///
+/// \note This function can be called from a thread other than the owner of
+/// fake_stack, but the owner thread needs to be alive.
+///
+/// \param fake_stack An opaque handler to a fake stack.
+/// \param addr Address to test.
+/// \param beg [out] Beginning of fake frame.
+/// \param end [out] End of fake frame.
+/// \returns Stack address or NULL.
+void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
+ void **end);
+
+/// Performs shadow memory cleanup of the current thread's stack before a
+/// function marked with the [[noreturn]] attribute is called.
+///
+/// To avoid false positives on the stack, must be called before no-return
+/// functions like _exit() and execl().
+void __asan_handle_no_return(void);
#ifdef __cplusplus
} // extern "C"
Index: compiler-rt/trunk/include/sanitizer/common_interface_defs.h
===================================================================
--- compiler-rt/trunk/include/sanitizer/common_interface_defs.h
+++ compiler-rt/trunk/include/sanitizer/common_interface_defs.h
@@ -17,189 +17,335 @@
// GCC does not understand __has_feature.
#if !defined(__has_feature)
-# define __has_feature(x) 0
+#define __has_feature(x) 0
#endif
#ifdef __cplusplus
extern "C" {
#endif
- // Arguments for __sanitizer_sandbox_on_notify() below.
- typedef struct {
- // Enable sandbox support in sanitizer coverage.
- int coverage_sandboxed;
- // File descriptor to write coverage data to. If -1 is passed, a file will
- // be pre-opened by __sanitizer_sandobx_on_notify(). This field has no
- // effect if coverage_sandboxed == 0.
- intptr_t coverage_fd;
- // If non-zero, split the coverage data into well-formed blocks. This is
- // useful when coverage_fd is a socket descriptor. Each block will contain
- // a header, allowing data from multiple processes to be sent over the same
- // socket.
- unsigned int coverage_max_block_size;
- } __sanitizer_sandbox_arguments;
-
- // Tell the tools to write their reports to "path." instead of stderr.
- void __sanitizer_set_report_path(const char *path);
- // Tell the tools to write their reports to the provided file descriptor
- // (casted to void *).
- void __sanitizer_set_report_fd(void *fd);
-
- // Notify the tools that the sandbox is going to be turned on. The reserved
- // parameter will be used in the future to hold a structure with functions
- // that the tools may call to bypass the sandbox.
- void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
-
- // This function is called by the tool when it has just finished reporting
- // an error. 'error_summary' is a one-line string that summarizes
- // the error message. This function can be overridden by the client.
- void __sanitizer_report_error_summary(const char *error_summary);
-
- // Some of the sanitizers (e.g. asan/tsan) may miss bugs that happen
- // in unaligned loads/stores. In order to find such bugs reliably one needs
- // to replace plain unaligned loads/stores with these calls.
- uint16_t __sanitizer_unaligned_load16(const void *p);
- uint32_t __sanitizer_unaligned_load32(const void *p);
- uint64_t __sanitizer_unaligned_load64(const void *p);
- void __sanitizer_unaligned_store16(void *p, uint16_t x);
- void __sanitizer_unaligned_store32(void *p, uint32_t x);
- void __sanitizer_unaligned_store64(void *p, uint64_t x);
-
- // Returns 1 on the first call, then returns 0 thereafter. Called by the tool
- // to ensure only one report is printed when multiple errors occur
- // simultaneously.
- int __sanitizer_acquire_crash_state();
-
- // Annotate the current state of a contiguous container, such as
- // std::vector, std::string or similar.
- // A contiguous container is a container that keeps all of its elements
- // in a contiguous region of memory. The container owns the region of memory
- // [beg, end); the memory [beg, mid) is used to store the current elements
- // and the memory [mid, end) is reserved for future elements;
- // beg <= mid <= end. For example, in "std::vector<> v"
- // beg = &v[0];
- // end = beg + v.capacity() * sizeof(v[0]);
- // mid = beg + v.size() * sizeof(v[0]);
- //
- // This annotation tells the Sanitizer tool about the current state of the
- // container so that the tool can report errors when memory from [mid, end)
- // is accessed. Insert this annotation into methods like push_back/pop_back.
- // Supply the old and the new values of mid (old_mid/new_mid).
- // In the initial state mid == end and so should be the final
- // state when the container is destroyed or when it reallocates the storage.
- //
- // Use with caution and don't use for anything other than vector-like classes.
- //
- // For AddressSanitizer, 'beg' should be 8-aligned and 'end' should
- // be either 8-aligned or it should point to the end of a separate heap-,
- // stack-, or global- allocated buffer. I.e. the following will not work:
- // int64_t x[2]; // 16 bytes, 8-aligned.
- // char *beg = (char *)&x[0];
- // char *end = beg + 12; // Not 8 aligned, not the end of the buffer.
- // This however will work fine:
- // int32_t x[3]; // 12 bytes, but 8-aligned under AddressSanitizer.
- // char *beg = (char*)&x[0];
- // char *end = beg + 12; // Not 8-aligned, but is the end of the buffer.
- void __sanitizer_annotate_contiguous_container(const void *beg,
- const void *end,
- const void *old_mid,
- const void *new_mid);
- // Returns true if the contiguous container [beg, end) is properly poisoned
- // (e.g. with __sanitizer_annotate_contiguous_container), i.e. if
- // - [beg, mid) is addressable,
- // - [mid, end) is unaddressable.
- // Full verification requires O(end-beg) time; this function tries to avoid
- // such complexity by touching only parts of the container around beg/mid/end.
- int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
- const void *end);
-
- // Similar to __sanitizer_verify_contiguous_container but returns the address
- // of the first improperly poisoned byte otherwise. Returns null if the area
- // is poisoned properly.
- const void *__sanitizer_contiguous_container_find_bad_address(
- const void *beg, const void *mid, const void *end);
-
- // Print the stack trace leading to this call. Useful for debugging user code.
- void __sanitizer_print_stack_trace(void);
-
- // Symbolizes the supplied 'pc' using the format string 'fmt'.
- // Outputs at most 'out_buf_size' bytes into 'out_buf'.
- // If 'out_buf' is not empty then output is zero or more non empty C strings
- // followed by single empty C string. Multiple strings can be returned if PC
- // corresponds to inlined function. Inlined frames are printed in the order
- // from "most-inlined" to the "least-inlined", so the last frame should be the
- // not inlined function.
- // Inlined frames can be removed with 'symbolize_inline_frames=0'.
- // The format syntax is described in
- // lib/sanitizer_common/sanitizer_stacktrace_printer.h.
- void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf,
- size_t out_buf_size);
- // Same as __sanitizer_symbolize_pc, but for data section (i.e. globals).
- void __sanitizer_symbolize_global(void *data_ptr, const char *fmt,
- char *out_buf, size_t out_buf_size);
-
- // Sets the callback to be called right before death on error.
- // Passing 0 will unset the callback.
- void __sanitizer_set_death_callback(void (*callback)(void));
-
- // Interceptor hooks.
- // Whenever a libc function interceptor is called it checks if the
- // corresponding weak hook is defined, and it so -- calls it.
- // The primary use case is data-flow-guided fuzzing, where the fuzzer needs
- // to know what is being passed to libc functions, e.g. memcmp.
- // FIXME: implement more hooks.
- void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
- const void *s2, size_t n, int result);
- void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
- const char *s2, size_t n, int result);
- void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
- const char *s2, size_t n, int result);
- void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
- const char *s2, int result);
- void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
- const char *s2, int result);
- void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
- const char *s2, char *result);
- void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
- const char *s2, char *result);
- void __sanitizer_weak_hook_memmem(void *called_pc,
- const void *s1, size_t len1,
- const void *s2, size_t len2, void *result);
-
- // Prints stack traces for all live heap allocations ordered by total
- // allocation size until `top_percent` of total live heap is shown.
- // `top_percent` should be between 1 and 100.
- // At most `max_number_of_contexts` contexts (stack traces) is printed.
- // Experimental feature currently available only with asan on Linux/x86_64.
- void __sanitizer_print_memory_profile(size_t top_percent,
- size_t max_number_of_contexts);
-
- // Fiber annotation interface.
- // Before switching to a different stack, one must call
- // __sanitizer_start_switch_fiber with a pointer to the bottom of the
- // destination stack and its size. When code starts running on the new stack,
- // it must call __sanitizer_finish_switch_fiber to finalize the switch.
- // The start_switch function takes a void** to store the current fake stack if
- // there is one (it is needed when detect_stack_use_after_return is enabled).
- // When restoring a stack, this pointer must be given to the finish_switch
- // function. In most cases, this void* can be stored on the stack just before
- // switching. When leaving a fiber definitely, null must be passed as first
- // argument to the start_switch function so that the fake stack is destroyed.
- // If you do not want support for stack use-after-return detection, you can
- // always pass null to these two functions.
- // Note that the fake stack mechanism is disabled during fiber switch, so if a
- // signal callback runs during the switch, it will not benefit from the stack
- // use-after-return detection.
- void __sanitizer_start_switch_fiber(void **fake_stack_save,
- const void *bottom, size_t size);
- void __sanitizer_finish_switch_fiber(void *fake_stack_save,
- const void **bottom_old,
- size_t *size_old);
-
- // Get full module name and calculate pc offset within it.
- // Returns 1 if pc belongs to some module, 0 if module was not found.
- int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path,
- size_t module_path_len,
- void **pc_offset);
+// Arguments for __sanitizer_sandbox_on_notify() below.
+typedef struct {
+ // Enable sandbox support in sanitizer coverage.
+ int coverage_sandboxed;
+ // File descriptor to write coverage data to. If -1 is passed, a file will
+ // be pre-opened by __sanitizer_sandobx_on_notify(). This field has no
+ // effect if coverage_sandboxed == 0.
+ intptr_t coverage_fd;
+ // If non-zero, split the coverage data into well-formed blocks. This is
+ // useful when coverage_fd is a socket descriptor. Each block will contain
+ // a header, allowing data from multiple processes to be sent over the same
+ // socket.
+ unsigned int coverage_max_block_size;
+} __sanitizer_sandbox_arguments;
+
+// Tell the tools to write their reports to "path." instead of stderr.
+void __sanitizer_set_report_path(const char *path);
+// Tell the tools to write their reports to the provided file descriptor
+// (casted to void *).
+void __sanitizer_set_report_fd(void *fd);
+
+// Notify the tools that the sandbox is going to be turned on. The reserved
+// parameter will be used in the future to hold a structure with functions
+// that the tools may call to bypass the sandbox.
+void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
+
+// This function is called by the tool when it has just finished reporting
+// an error. 'error_summary' is a one-line string that summarizes
+// the error message. This function can be overridden by the client.
+void __sanitizer_report_error_summary(const char *error_summary);
+
+// Some of the sanitizers (for example ASan/TSan) could miss bugs that happen
+// in unaligned loads/stores. To find such bugs reliably, you need to replace
+// plain unaligned loads/stores with these calls.
+
+/// Loads a 16-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+///
+/// \returns Loaded value.
+uint16_t __sanitizer_unaligned_load16(const void *p);
+
+/// Loads a 32-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+///
+/// \returns Loaded value.
+uint32_t __sanitizer_unaligned_load32(const void *p);
+
+/// Loads a 64-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+///
+/// \returns Loaded value.
+uint64_t __sanitizer_unaligned_load64(const void *p);
+
+/// Stores a 16-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+/// \param x 16-bit value to store.
+void __sanitizer_unaligned_store16(void *p, uint16_t x);
+
+/// Stores a 32-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+/// \param x 32-bit value to store.
+void __sanitizer_unaligned_store32(void *p, uint32_t x);
+
+/// Stores a 64-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+/// \param x 64-bit value to store.
+void __sanitizer_unaligned_store64(void *p, uint64_t x);
+
+// Returns 1 on the first call, then returns 0 thereafter. Called by the tool
+// to ensure only one report is printed when multiple errors occur
+// simultaneously.
+int __sanitizer_acquire_crash_state();
+
+/// Annotates the current state of a contiguous container, such as
+/// std::vector, std::string, or similar.
+///
+/// A contiguous container is a container that keeps all of its elements
+/// in a contiguous region of memory. The container owns the region of memory
+/// [beg, end); the memory [beg, mid) is used to store the
+/// current elements, and the memory [mid, end) is reserved for future
+/// elements (beg <= mid <= end). For example, in
+/// std::vector<> v:
+///
+/// \code
+/// beg = &v[0];
+/// end = beg + v.capacity() * sizeof(v[0]);
+/// mid = beg + v.size() * sizeof(v[0]);
+/// \endcode
+///
+/// This annotation tells the Sanitizer tool about the current state of the
+/// container so that the tool can report errors when memory from
+/// [mid, end) is accessed. Insert this annotation into methods like
+/// push_back() or pop_back(). Supply the old and new values of
+/// mid(old_mid and new_mid). In the initial
+/// state mid == end, so that should be the final state when the
+/// container is destroyed or when the container reallocates the storage.
+///
+/// For ASan, beg should be 8-aligned and end
+/// should be either 8-aligned or it should point to the end of a separate
+/// heap-, stack-, or global-allocated buffer. So the following example will
+/// not work:
+///
+/// \code
+/// int64_t x[2]; // 16 bytes, 8-aligned
+/// char *beg = (char *)&x[0];
+/// char *end = beg + 12; // Not 8-aligned, not the end of the buffer
+/// \endcode
+///
+/// The following, however, will work:
+/// \code
+/// int32_t x[3]; // 12 bytes, but 8-aligned under ASan.
+/// char *beg = (char*)&x[0];
+/// char *end = beg + 12; // Not 8-aligned, but is the end of the buffer
+/// \endcode
+///
+/// \note Use this function with caution and do not use for anything other
+/// than vector-like classes.
+///
+/// \param beg Beginning of memory region.
+/// \param end End of memory region.
+/// \param old_mid Old middle of memory region.
+/// \param new_mid New middle of memory region.
+void __sanitizer_annotate_contiguous_container(const void *beg,
+ const void *end,
+ const void *old_mid,
+ const void *new_mid);
+
+/// Returns true if the contiguous container [beg, end) is properly
+/// poisoned.
+///
+/// Proper poisoning could occur, for example, with
+/// __sanitizer_annotate_contiguous_container), that is, if
+/// [beg, mid) is addressable and [mid, end) is unaddressable.
+/// Full verification requires O (end - beg) time; this function tries
+/// to avoid such complexity by touching only parts of the container around
+/// beg, mid, and end.
+///
+/// \param beg Beginning of memory region.
+/// \param mid Middle of memory region.
+/// \param end Old end of memory region.
+///
+/// \returns True if the contiguous container [beg, end) is properly
+/// poisoned.
+int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
+ const void *end);
+
+/// Similar to __sanitizer_verify_contiguous_container() but also
+/// returns the address of the first improperly poisoned byte.
+///
+/// Returns NULL if the area is poisoned properly.
+///
+/// \param beg Beginning of memory region.
+/// \param mid Middle of memory region.
+/// \param end Old end of memory region.
+///
+/// \returns The bad address or NULL.
+const void *__sanitizer_contiguous_container_find_bad_address(const void *beg,
+ const void *mid,
+ const void *end);
+
+/// Prints the stack trace leading to this call (useful for calling from the
+/// debugger).
+void __sanitizer_print_stack_trace(void);
+
+// Symbolizes the supplied 'pc' using the format string 'fmt'.
+// Outputs at most 'out_buf_size' bytes into 'out_buf'.
+// If 'out_buf' is not empty then output is zero or more non empty C strings
+// followed by single empty C string. Multiple strings can be returned if PC
+// corresponds to inlined function. Inlined frames are printed in the order
+// from "most-inlined" to the "least-inlined", so the last frame should be the
+// not inlined function.
+// Inlined frames can be removed with 'symbolize_inline_frames=0'.
+// The format syntax is described in
+// lib/sanitizer_common/sanitizer_stacktrace_printer.h.
+void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf,
+ size_t out_buf_size);
+// Same as __sanitizer_symbolize_pc, but for data section (i.e. globals).
+void __sanitizer_symbolize_global(void *data_ptr, const char *fmt,
+ char *out_buf, size_t out_buf_size);
+
+/// Sets the callback to be called immediately before death on error.
+///
+/// Passing 0 will unset the callback.
+///
+/// \param callback User-provided callback.
+void __sanitizer_set_death_callback(void (*callback)(void));
+
+
+// Interceptor hooks.
+// Whenever a libc function interceptor is called, it checks if the
+// corresponding weak hook is defined, and calls it if it is indeed defined.
+// The primary use-case is data-flow-guided fuzzing, where the fuzzer needs
+// to know what is being passed to libc functions (for example memcmp).
+// FIXME: implement more hooks.
+
+/// Interceptor hook for memcmp().
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param n Number of bytes to compare.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
+ const void *s2, size_t n, int result);
+
+/// Interceptor hook for strncmp().
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param n Number of bytes to compare.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
+ const char *s2, size_t n, int result);
+
+/// Interceptor hook for strncasecmp().
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param n Number of bytes to compare.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
+ const char *s2, size_t n, int result);
+
+/// Interceptor hook for strcmp().
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
+ const char *s2, int result);
+
+/// Interceptor hook for strcasecmp().
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
+ const char *s2, int result);
+
+/// Interceptor hook for strstr().
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
+ const char *s2, char *result);
+
+void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
+ const char *s2, char *result);
+
+void __sanitizer_weak_hook_memmem(void *called_pc,
+ const void *s1, size_t len1,
+ const void *s2, size_t len2, void *result);
+
+// Prints stack traces for all live heap allocations ordered by total
+// allocation size until top_percent of total live heap is shown. top_percent
+// should be between 1 and 100. At most max_number_of_contexts contexts
+// (stack traces) are printed.
+// Experimental feature currently available only with ASan on Linux/x86_64.
+void __sanitizer_print_memory_profile(size_t top_percent,
+ size_t max_number_of_contexts);
+
+/// Notify ASan that a fiber switch has started (required only if implementing
+/// your own fiber library).
+///
+/// Before switching to a different stack, you must call
+/// __sanitizer_start_switch_fiber() with a pointer to the bottom of the
+/// destination stack and with its size. When code starts running on the new
+/// stack, it must call __sanitizer_finish_switch_fiber() to finalize
+/// the switch. The __sanitizer_start_switch_fiber() function takes a
+/// void** pointer argument to store the current fake stack if there is
+/// one (it is necessary when the runtime option
+/// detect_stack_use_after_return is enabled).
+///
+/// When restoring a stack, this void** pointer must be given to the
+/// __sanitizer_finish_switch_fiber() function. In most cases, this
+/// pointer can be stored on the stack immediately before switching. When
+/// leaving a fiber definitely, NULL must be passed as the first argument to
+/// the __sanitizer_start_switch_fiber() function so that the fake stack
+/// is destroyed. If your program does not need stack use-after-return
+/// detection, you can always pass NULL to these two functions.
+///
+/// \note The fake stack mechanism is disabled during fiber switch, so if a
+/// signal callback runs during the switch, it will not benefit from stack
+/// use-after-return detection.
+///
+/// \param fake_stack_save [out] Fake stack save location.
+/// \param bottom Bottom address of stack.
+/// \param size Size of stack in bytes.
+void __sanitizer_start_switch_fiber(void **fake_stack_save,
+ const void *bottom, size_t size);
+
+/// Notify ASan that a fiber switch has completed (required only if
+/// implementing your own fiber library).
+///
+/// When code starts running on the new stack, it must call
+/// __sanitizer_finish_switch_fiber() to finalize
+/// the switch. For usage details, see the description of
+/// __sanitizer_start_switch_fiber().
+///
+/// \param fake_stack_save Fake stack save location.
+/// \param bottom_old [out] Bottom address of old stack.
+/// \param size_old [out] Size of old stack in bytes.
+void __sanitizer_finish_switch_fiber(void *fake_stack_save,
+ const void **bottom_old,
+ size_t *size_old);
+
+// Get full module name and calculate pc offset within it.
+// Returns 1 if pc belongs to some module, 0 if module was not found.
+int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path,
+ size_t module_path_len,
+ void **pc_offset);
#ifdef __cplusplus
} // extern "C"