10b57cec5SDimitry Andric //===-- sanitizer/common_interface_defs.h -----------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Common part of the public sanitizer interface. 100b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #ifndef SANITIZER_COMMON_INTERFACE_DEFS_H 130b57cec5SDimitry Andric #define SANITIZER_COMMON_INTERFACE_DEFS_H 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include <stddef.h> 160b57cec5SDimitry Andric #include <stdint.h> 170b57cec5SDimitry Andric 18*5f757f3fSDimitry Andric // Windows allows a user to set their default calling convention, but we always 19*5f757f3fSDimitry Andric // use __cdecl 20*5f757f3fSDimitry Andric #ifdef _WIN32 21*5f757f3fSDimitry Andric #define SANITIZER_CDECL __cdecl 22*5f757f3fSDimitry Andric #else 23*5f757f3fSDimitry Andric #define SANITIZER_CDECL 240b57cec5SDimitry Andric #endif 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric #ifdef __cplusplus 270b57cec5SDimitry Andric extern "C" { 280b57cec5SDimitry Andric #endif 290b57cec5SDimitry Andric // Arguments for __sanitizer_sandbox_on_notify() below. 300b57cec5SDimitry Andric typedef struct { 310b57cec5SDimitry Andric // Enable sandbox support in sanitizer coverage. 320b57cec5SDimitry Andric int coverage_sandboxed; 330b57cec5SDimitry Andric // File descriptor to write coverage data to. If -1 is passed, a file will 34349cc55cSDimitry Andric // be pre-opened by __sanitizer_sandbox_on_notify(). This field has no 350b57cec5SDimitry Andric // effect if coverage_sandboxed == 0. 360b57cec5SDimitry Andric intptr_t coverage_fd; 370b57cec5SDimitry Andric // If non-zero, split the coverage data into well-formed blocks. This is 380b57cec5SDimitry Andric // useful when coverage_fd is a socket descriptor. Each block will contain 390b57cec5SDimitry Andric // a header, allowing data from multiple processes to be sent over the same 400b57cec5SDimitry Andric // socket. 410b57cec5SDimitry Andric unsigned int coverage_max_block_size; 420b57cec5SDimitry Andric } __sanitizer_sandbox_arguments; 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric // Tell the tools to write their reports to "path.<pid>" instead of stderr. 45*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_set_report_path(const char *path); 460b57cec5SDimitry Andric // Tell the tools to write their reports to the provided file descriptor 470b57cec5SDimitry Andric // (casted to void *). 48*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_set_report_fd(void *fd); 49e8d8bef9SDimitry Andric // Get the current full report file path, if a path was specified by 50e8d8bef9SDimitry Andric // an earlier call to __sanitizer_set_report_path. Returns null otherwise. 51*5f757f3fSDimitry Andric const char *SANITIZER_CDECL __sanitizer_get_report_path(); 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric // Notify the tools that the sandbox is going to be turned on. The reserved 540b57cec5SDimitry Andric // parameter will be used in the future to hold a structure with functions 550b57cec5SDimitry Andric // that the tools may call to bypass the sandbox. 56*5f757f3fSDimitry Andric void SANITIZER_CDECL 57*5f757f3fSDimitry Andric __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args); 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric // This function is called by the tool when it has just finished reporting 600b57cec5SDimitry Andric // an error. 'error_summary' is a one-line string that summarizes 610b57cec5SDimitry Andric // the error message. This function can be overridden by the client. 62*5f757f3fSDimitry Andric void SANITIZER_CDECL 63*5f757f3fSDimitry Andric __sanitizer_report_error_summary(const char *error_summary); 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric // Some of the sanitizers (for example ASan/TSan) could miss bugs that happen 660b57cec5SDimitry Andric // in unaligned loads/stores. To find such bugs reliably, you need to replace 670b57cec5SDimitry Andric // plain unaligned loads/stores with these calls. 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric /// Loads a 16-bit unaligned value. 70*5f757f3fSDimitry Andric // 710b57cec5SDimitry Andric /// \param p Pointer to unaligned memory. 720b57cec5SDimitry Andric /// 730b57cec5SDimitry Andric /// \returns Loaded value. 74*5f757f3fSDimitry Andric uint16_t SANITIZER_CDECL __sanitizer_unaligned_load16(const void *p); 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric /// Loads a 32-bit unaligned value. 770b57cec5SDimitry Andric /// 780b57cec5SDimitry Andric /// \param p Pointer to unaligned memory. 790b57cec5SDimitry Andric /// 800b57cec5SDimitry Andric /// \returns Loaded value. 81*5f757f3fSDimitry Andric uint32_t SANITIZER_CDECL __sanitizer_unaligned_load32(const void *p); 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric /// Loads a 64-bit unaligned value. 840b57cec5SDimitry Andric /// 850b57cec5SDimitry Andric /// \param p Pointer to unaligned memory. 860b57cec5SDimitry Andric /// 870b57cec5SDimitry Andric /// \returns Loaded value. 88*5f757f3fSDimitry Andric uint64_t SANITIZER_CDECL __sanitizer_unaligned_load64(const void *p); 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric /// Stores a 16-bit unaligned value. 910b57cec5SDimitry Andric /// 920b57cec5SDimitry Andric /// \param p Pointer to unaligned memory. 930b57cec5SDimitry Andric /// \param x 16-bit value to store. 94*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_unaligned_store16(void *p, uint16_t x); 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric /// Stores a 32-bit unaligned value. 970b57cec5SDimitry Andric /// 980b57cec5SDimitry Andric /// \param p Pointer to unaligned memory. 990b57cec5SDimitry Andric /// \param x 32-bit value to store. 100*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_unaligned_store32(void *p, uint32_t x); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric /// Stores a 64-bit unaligned value. 1030b57cec5SDimitry Andric /// 1040b57cec5SDimitry Andric /// \param p Pointer to unaligned memory. 1050b57cec5SDimitry Andric /// \param x 64-bit value to store. 106*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_unaligned_store64(void *p, uint64_t x); 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric // Returns 1 on the first call, then returns 0 thereafter. Called by the tool 1090b57cec5SDimitry Andric // to ensure only one report is printed when multiple errors occur 1100b57cec5SDimitry Andric // simultaneously. 111*5f757f3fSDimitry Andric int SANITIZER_CDECL __sanitizer_acquire_crash_state(); 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric /// Annotates the current state of a contiguous container, such as 1140b57cec5SDimitry Andric /// <c>std::vector</c>, <c>std::string</c>, or similar. 1150b57cec5SDimitry Andric /// 1160b57cec5SDimitry Andric /// A contiguous container is a container that keeps all of its elements 1170b57cec5SDimitry Andric /// in a contiguous region of memory. The container owns the region of memory 1180b57cec5SDimitry Andric /// <c>[beg, end)</c>; the memory <c>[beg, mid)</c> is used to store the 1190b57cec5SDimitry Andric /// current elements, and the memory <c>[mid, end)</c> is reserved for future 1200b57cec5SDimitry Andric /// elements (<c>beg <= mid <= end</c>). For example, in 1210b57cec5SDimitry Andric /// <c>std::vector<> v</c>: 1220b57cec5SDimitry Andric /// 1230b57cec5SDimitry Andric /// \code 1240b57cec5SDimitry Andric /// beg = &v[0]; 1250b57cec5SDimitry Andric /// end = beg + v.capacity() * sizeof(v[0]); 1260b57cec5SDimitry Andric /// mid = beg + v.size() * sizeof(v[0]); 1270b57cec5SDimitry Andric /// \endcode 1280b57cec5SDimitry Andric /// 1290b57cec5SDimitry Andric /// This annotation tells the Sanitizer tool about the current state of the 1300b57cec5SDimitry Andric /// container so that the tool can report errors when memory from 1310b57cec5SDimitry Andric /// <c>[mid, end)</c> is accessed. Insert this annotation into methods like 1320b57cec5SDimitry Andric /// <c>push_back()</c> or <c>pop_back()</c>. Supply the old and new values of 1330b57cec5SDimitry Andric /// <c>mid</c>(<c><i>old_mid</i></c> and <c><i>new_mid</i></c>). In the initial 1340b57cec5SDimitry Andric /// state <c>mid == end</c>, so that should be the final state when the 1350b57cec5SDimitry Andric /// container is destroyed or when the container reallocates the storage. 1360b57cec5SDimitry Andric /// 13706c3fb27SDimitry Andric /// For ASan, <c><i>beg</i></c> no longer needs to be 8-aligned, 13806c3fb27SDimitry Andric /// first and last granule may be shared with other objects 13906c3fb27SDimitry Andric /// and therefore the function can be used for any allocator. 14006c3fb27SDimitry Andric /// 14106c3fb27SDimitry Andric /// The following example shows how to use the function: 1420b57cec5SDimitry Andric /// 1430b57cec5SDimitry Andric /// \code 14406c3fb27SDimitry Andric /// int32_t x[3]; // 12 bytes 1450b57cec5SDimitry Andric /// char *beg = (char*)&x[0]; 14606c3fb27SDimitry Andric /// char *end = beg + 12; 14706c3fb27SDimitry Andric /// __sanitizer_annotate_contiguous_container(beg, end, beg, end); 1480b57cec5SDimitry Andric /// \endcode 1490b57cec5SDimitry Andric /// 1500b57cec5SDimitry Andric /// \note Use this function with caution and do not use for anything other 1510b57cec5SDimitry Andric /// than vector-like classes. 15206c3fb27SDimitry Andric /// \note Unaligned <c><i>beg</i></c> or <c><i>end</i></c> may miss bugs in 15306c3fb27SDimitry Andric /// these granules. 1540b57cec5SDimitry Andric /// 1550b57cec5SDimitry Andric /// \param beg Beginning of memory region. 1560b57cec5SDimitry Andric /// \param end End of memory region. 1570b57cec5SDimitry Andric /// \param old_mid Old middle of memory region. 1580b57cec5SDimitry Andric /// \param new_mid New middle of memory region. 159*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_annotate_contiguous_container( 160*5f757f3fSDimitry Andric const void *beg, const void *end, const void *old_mid, const void *new_mid); 1610b57cec5SDimitry Andric 162bdd1243dSDimitry Andric /// Similar to <c>__sanitizer_annotate_contiguous_container</c>. 163bdd1243dSDimitry Andric /// 164bdd1243dSDimitry Andric /// Annotates the current state of a contiguous container memory, 165bdd1243dSDimitry Andric /// such as <c>std::deque</c>'s single chunk, when the boundries are moved. 166bdd1243dSDimitry Andric /// 167bdd1243dSDimitry Andric /// A contiguous chunk is a chunk that keeps all of its elements 168bdd1243dSDimitry Andric /// in a contiguous region of memory. The container owns the region of memory 169bdd1243dSDimitry Andric /// <c>[storage_beg, storage_end)</c>; the memory <c>[container_beg, 170bdd1243dSDimitry Andric /// container_end)</c> is used to store the current elements, and the memory 171bdd1243dSDimitry Andric /// <c>[storage_beg, container_beg), [container_end, storage_end)</c> is 172bdd1243dSDimitry Andric /// reserved for future elements (<c>storage_beg <= container_beg <= 173bdd1243dSDimitry Andric /// container_end <= storage_end</c>). For example, in <c> std::deque </c>: 174bdd1243dSDimitry Andric /// - chunk with a frist deques element will have container_beg equal to address 175bdd1243dSDimitry Andric /// of the first element. 176bdd1243dSDimitry Andric /// - in every next chunk with elements, true is <c> container_beg == 177bdd1243dSDimitry Andric /// storage_beg </c>. 178bdd1243dSDimitry Andric /// 179bdd1243dSDimitry Andric /// Argument requirements: 180bdd1243dSDimitry Andric /// During unpoisoning memory of empty container (before first element is 181bdd1243dSDimitry Andric /// added): 182bdd1243dSDimitry Andric /// - old_container_beg_p == old_container_end_p 183bdd1243dSDimitry Andric /// During poisoning after last element was removed: 184bdd1243dSDimitry Andric /// - new_container_beg_p == new_container_end_p 185bdd1243dSDimitry Andric /// \param storage_beg Beginning of memory region. 186bdd1243dSDimitry Andric /// \param storage_end End of memory region. 187bdd1243dSDimitry Andric /// \param old_container_beg Old beginning of used region. 188bdd1243dSDimitry Andric /// \param old_container_end End of used region. 189bdd1243dSDimitry Andric /// \param new_container_beg New beginning of used region. 190bdd1243dSDimitry Andric /// \param new_container_end New end of used region. 191*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_annotate_double_ended_contiguous_container( 192bdd1243dSDimitry Andric const void *storage_beg, const void *storage_end, 193bdd1243dSDimitry Andric const void *old_container_beg, const void *old_container_end, 194bdd1243dSDimitry Andric const void *new_container_beg, const void *new_container_end); 195bdd1243dSDimitry Andric 1960b57cec5SDimitry Andric /// Returns true if the contiguous container <c>[beg, end)</c> is properly 1970b57cec5SDimitry Andric /// poisoned. 1980b57cec5SDimitry Andric /// 1990b57cec5SDimitry Andric /// Proper poisoning could occur, for example, with 2000b57cec5SDimitry Andric /// <c>__sanitizer_annotate_contiguous_container</c>), that is, if 2010b57cec5SDimitry Andric /// <c>[beg, mid)</c> is addressable and <c>[mid, end)</c> is unaddressable. 2020b57cec5SDimitry Andric /// Full verification requires O (<c>end - beg</c>) time; this function tries 2030b57cec5SDimitry Andric /// to avoid such complexity by touching only parts of the container around 2040b57cec5SDimitry Andric /// <c><i>beg</i></c>, <c><i>mid</i></c>, and <c><i>end</i></c>. 2050b57cec5SDimitry Andric /// 2060b57cec5SDimitry Andric /// \param beg Beginning of memory region. 2070b57cec5SDimitry Andric /// \param mid Middle of memory region. 2080b57cec5SDimitry Andric /// \param end Old end of memory region. 2090b57cec5SDimitry Andric /// 2100b57cec5SDimitry Andric /// \returns True if the contiguous container <c>[beg, end)</c> is properly 2110b57cec5SDimitry Andric /// poisoned. 212*5f757f3fSDimitry Andric int SANITIZER_CDECL __sanitizer_verify_contiguous_container(const void *beg, 213*5f757f3fSDimitry Andric const void *mid, 2140b57cec5SDimitry Andric const void *end); 2150b57cec5SDimitry Andric 216bdd1243dSDimitry Andric /// Returns true if the double ended contiguous 217bdd1243dSDimitry Andric /// container <c>[storage_beg, storage_end)</c> is properly poisoned. 218bdd1243dSDimitry Andric /// 219bdd1243dSDimitry Andric /// Proper poisoning could occur, for example, with 220bdd1243dSDimitry Andric /// <c>__sanitizer_annotate_double_ended_contiguous_container</c>), that is, if 221bdd1243dSDimitry Andric /// <c>[storage_beg, container_beg)</c> is not addressable, <c>[container_beg, 222bdd1243dSDimitry Andric /// container_end)</c> is addressable and <c>[container_end, end)</c> is 223bdd1243dSDimitry Andric /// unaddressable. Full verification requires O (<c>storage_end - 224bdd1243dSDimitry Andric /// storage_beg</c>) time; this function tries to avoid such complexity by 225bdd1243dSDimitry Andric /// touching only parts of the container around <c><i>storage_beg</i></c>, 226bdd1243dSDimitry Andric /// <c><i>container_beg</i></c>, <c><i>container_end</i></c>, and 227bdd1243dSDimitry Andric /// <c><i>storage_end</i></c>. 228bdd1243dSDimitry Andric /// 229bdd1243dSDimitry Andric /// \param storage_beg Beginning of memory region. 230bdd1243dSDimitry Andric /// \param container_beg Beginning of used region. 231bdd1243dSDimitry Andric /// \param container_end End of used region. 232bdd1243dSDimitry Andric /// \param storage_end End of memory region. 233bdd1243dSDimitry Andric /// 234bdd1243dSDimitry Andric /// \returns True if the double-ended contiguous container <c>[storage_beg, 235bdd1243dSDimitry Andric /// container_beg, container_end, end)</c> is properly poisoned - only 236bdd1243dSDimitry Andric /// [container_beg; container_end) is addressable. 237*5f757f3fSDimitry Andric int SANITIZER_CDECL __sanitizer_verify_double_ended_contiguous_container( 238bdd1243dSDimitry Andric const void *storage_beg, const void *container_beg, 239bdd1243dSDimitry Andric const void *container_end, const void *storage_end); 240bdd1243dSDimitry Andric 2410b57cec5SDimitry Andric /// Similar to <c>__sanitizer_verify_contiguous_container()</c> but also 2420b57cec5SDimitry Andric /// returns the address of the first improperly poisoned byte. 2430b57cec5SDimitry Andric /// 2440b57cec5SDimitry Andric /// Returns NULL if the area is poisoned properly. 2450b57cec5SDimitry Andric /// 2460b57cec5SDimitry Andric /// \param beg Beginning of memory region. 2470b57cec5SDimitry Andric /// \param mid Middle of memory region. 2480b57cec5SDimitry Andric /// \param end Old end of memory region. 2490b57cec5SDimitry Andric /// 2500b57cec5SDimitry Andric /// \returns The bad address or NULL. 251*5f757f3fSDimitry Andric const void *SANITIZER_CDECL __sanitizer_contiguous_container_find_bad_address( 252*5f757f3fSDimitry Andric const void *beg, const void *mid, const void *end); 2530b57cec5SDimitry Andric 254bdd1243dSDimitry Andric /// returns the address of the first improperly poisoned byte. 255bdd1243dSDimitry Andric /// 256bdd1243dSDimitry Andric /// Returns NULL if the area is poisoned properly. 257bdd1243dSDimitry Andric /// 258bdd1243dSDimitry Andric /// \param storage_beg Beginning of memory region. 259bdd1243dSDimitry Andric /// \param container_beg Beginning of used region. 260bdd1243dSDimitry Andric /// \param container_end End of used region. 261bdd1243dSDimitry Andric /// \param storage_end End of memory region. 262bdd1243dSDimitry Andric /// 263bdd1243dSDimitry Andric /// \returns The bad address or NULL. 264*5f757f3fSDimitry Andric const void *SANITIZER_CDECL 265*5f757f3fSDimitry Andric __sanitizer_double_ended_contiguous_container_find_bad_address( 266bdd1243dSDimitry Andric const void *storage_beg, const void *container_beg, 267bdd1243dSDimitry Andric const void *container_end, const void *storage_end); 268bdd1243dSDimitry Andric 2690b57cec5SDimitry Andric /// Prints the stack trace leading to this call (useful for calling from the 2700b57cec5SDimitry Andric /// debugger). 271*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_print_stack_trace(void); 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric // Symbolizes the supplied 'pc' using the format string 'fmt'. 2740b57cec5SDimitry Andric // Outputs at most 'out_buf_size' bytes into 'out_buf'. 2750b57cec5SDimitry Andric // If 'out_buf' is not empty then output is zero or more non empty C strings 2760b57cec5SDimitry Andric // followed by single empty C string. Multiple strings can be returned if PC 2770b57cec5SDimitry Andric // corresponds to inlined function. Inlined frames are printed in the order 2780b57cec5SDimitry Andric // from "most-inlined" to the "least-inlined", so the last frame should be the 2790b57cec5SDimitry Andric // not inlined function. 2800b57cec5SDimitry Andric // Inlined frames can be removed with 'symbolize_inline_frames=0'. 2810b57cec5SDimitry Andric // The format syntax is described in 2820b57cec5SDimitry Andric // lib/sanitizer_common/sanitizer_stacktrace_printer.h. 283*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_symbolize_pc(void *pc, const char *fmt, 284*5f757f3fSDimitry Andric char *out_buf, 2850b57cec5SDimitry Andric size_t out_buf_size); 2860b57cec5SDimitry Andric // Same as __sanitizer_symbolize_pc, but for data section (i.e. globals). 287*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_symbolize_global(void *data_ptr, 288*5f757f3fSDimitry Andric const char *fmt, 289*5f757f3fSDimitry Andric char *out_buf, 290*5f757f3fSDimitry Andric size_t out_buf_size); 2911fd87a68SDimitry Andric // Determine the return address. 2921fd87a68SDimitry Andric #if !defined(_MSC_VER) || defined(__clang__) 2931fd87a68SDimitry Andric #define __sanitizer_return_address() \ 2941fd87a68SDimitry Andric __builtin_extract_return_addr(__builtin_return_address(0)) 2951fd87a68SDimitry Andric #else 296*5f757f3fSDimitry Andric void *_ReturnAddress(void); 2971fd87a68SDimitry Andric #pragma intrinsic(_ReturnAddress) 2981fd87a68SDimitry Andric #define __sanitizer_return_address() _ReturnAddress() 2991fd87a68SDimitry Andric #endif 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric /// Sets the callback to be called immediately before death on error. 3020b57cec5SDimitry Andric /// 3030b57cec5SDimitry Andric /// Passing 0 will unset the callback. 3040b57cec5SDimitry Andric /// 3050b57cec5SDimitry Andric /// \param callback User-provided callback. 306*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_set_death_callback(void (*callback)(void)); 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric // Interceptor hooks. 3090b57cec5SDimitry Andric // Whenever a libc function interceptor is called, it checks if the 3100b57cec5SDimitry Andric // corresponding weak hook is defined, and calls it if it is indeed defined. 3110b57cec5SDimitry Andric // The primary use-case is data-flow-guided fuzzing, where the fuzzer needs 3120b57cec5SDimitry Andric // to know what is being passed to libc functions (for example memcmp). 3130b57cec5SDimitry Andric // FIXME: implement more hooks. 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric /// Interceptor hook for <c>memcmp()</c>. 3160b57cec5SDimitry Andric /// 3170b57cec5SDimitry Andric /// \param called_pc PC (program counter) address of the original call. 3180b57cec5SDimitry Andric /// \param s1 Pointer to block of memory. 3190b57cec5SDimitry Andric /// \param s2 Pointer to block of memory. 3200b57cec5SDimitry Andric /// \param n Number of bytes to compare. 3210b57cec5SDimitry Andric /// \param result Value returned by the intercepted function. 322*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_weak_hook_memcmp(void *called_pc, 323*5f757f3fSDimitry Andric const void *s1, 324*5f757f3fSDimitry Andric const void *s2, size_t n, 325*5f757f3fSDimitry Andric int result); 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric /// Interceptor hook for <c>strncmp()</c>. 3280b57cec5SDimitry Andric /// 3290b57cec5SDimitry Andric /// \param called_pc PC (program counter) address of the original call. 3300b57cec5SDimitry Andric /// \param s1 Pointer to block of memory. 3310b57cec5SDimitry Andric /// \param s2 Pointer to block of memory. 3320b57cec5SDimitry Andric /// \param n Number of bytes to compare. 3330b57cec5SDimitry Andric /// \param result Value returned by the intercepted function. 334*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_weak_hook_strncmp(void *called_pc, 335*5f757f3fSDimitry Andric const char *s1, 336*5f757f3fSDimitry Andric const char *s2, size_t n, 337*5f757f3fSDimitry Andric int result); 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric /// Interceptor hook for <c>strncasecmp()</c>. 3400b57cec5SDimitry Andric /// 3410b57cec5SDimitry Andric /// \param called_pc PC (program counter) address of the original call. 3420b57cec5SDimitry Andric /// \param s1 Pointer to block of memory. 3430b57cec5SDimitry Andric /// \param s2 Pointer to block of memory. 3440b57cec5SDimitry Andric /// \param n Number of bytes to compare. 3450b57cec5SDimitry Andric /// \param result Value returned by the intercepted function. 346*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_weak_hook_strncasecmp(void *called_pc, 347*5f757f3fSDimitry Andric const char *s1, 348*5f757f3fSDimitry Andric const char *s2, size_t n, 349*5f757f3fSDimitry Andric int result); 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric /// Interceptor hook for <c>strcmp()</c>. 3520b57cec5SDimitry Andric /// 3530b57cec5SDimitry Andric /// \param called_pc PC (program counter) address of the original call. 3540b57cec5SDimitry Andric /// \param s1 Pointer to block of memory. 3550b57cec5SDimitry Andric /// \param s2 Pointer to block of memory. 3560b57cec5SDimitry Andric /// \param result Value returned by the intercepted function. 357*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_weak_hook_strcmp(void *called_pc, 358*5f757f3fSDimitry Andric const char *s1, 3590b57cec5SDimitry Andric const char *s2, int result); 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric /// Interceptor hook for <c>strcasecmp()</c>. 3620b57cec5SDimitry Andric /// 3630b57cec5SDimitry Andric /// \param called_pc PC (program counter) address of the original call. 3640b57cec5SDimitry Andric /// \param s1 Pointer to block of memory. 3650b57cec5SDimitry Andric /// \param s2 Pointer to block of memory. 3660b57cec5SDimitry Andric /// \param result Value returned by the intercepted function. 367*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_weak_hook_strcasecmp(void *called_pc, 368*5f757f3fSDimitry Andric const char *s1, 369*5f757f3fSDimitry Andric const char *s2, 370*5f757f3fSDimitry Andric int result); 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric /// Interceptor hook for <c>strstr()</c>. 3730b57cec5SDimitry Andric /// 3740b57cec5SDimitry Andric /// \param called_pc PC (program counter) address of the original call. 3750b57cec5SDimitry Andric /// \param s1 Pointer to block of memory. 3760b57cec5SDimitry Andric /// \param s2 Pointer to block of memory. 3770b57cec5SDimitry Andric /// \param result Value returned by the intercepted function. 378*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_weak_hook_strstr(void *called_pc, 379*5f757f3fSDimitry Andric const char *s1, 3800b57cec5SDimitry Andric const char *s2, char *result); 3810b57cec5SDimitry Andric 382*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_weak_hook_strcasestr(void *called_pc, 383*5f757f3fSDimitry Andric const char *s1, 384*5f757f3fSDimitry Andric const char *s2, 385*5f757f3fSDimitry Andric char *result); 3860b57cec5SDimitry Andric 387*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_weak_hook_memmem(void *called_pc, 3880b57cec5SDimitry Andric const void *s1, size_t len1, 389*5f757f3fSDimitry Andric const void *s2, size_t len2, 390*5f757f3fSDimitry Andric void *result); 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric // Prints stack traces for all live heap allocations ordered by total 3930b57cec5SDimitry Andric // allocation size until top_percent of total live heap is shown. top_percent 3940b57cec5SDimitry Andric // should be between 1 and 100. At most max_number_of_contexts contexts 3950b57cec5SDimitry Andric // (stack traces) are printed. 3960b57cec5SDimitry Andric // Experimental feature currently available only with ASan on Linux/x86_64. 397*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_print_memory_profile( 398*5f757f3fSDimitry Andric size_t top_percent, size_t max_number_of_contexts); 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric /// Notify ASan that a fiber switch has started (required only if implementing 4010b57cec5SDimitry Andric /// your own fiber library). 4020b57cec5SDimitry Andric /// 4030b57cec5SDimitry Andric /// Before switching to a different stack, you must call 4040b57cec5SDimitry Andric /// <c>__sanitizer_start_switch_fiber()</c> with a pointer to the bottom of the 4050b57cec5SDimitry Andric /// destination stack and with its size. When code starts running on the new 4060b57cec5SDimitry Andric /// stack, it must call <c>__sanitizer_finish_switch_fiber()</c> to finalize 4070b57cec5SDimitry Andric /// the switch. The <c>__sanitizer_start_switch_fiber()</c> function takes a 4080b57cec5SDimitry Andric /// <c>void**</c> pointer argument to store the current fake stack if there is 4090b57cec5SDimitry Andric /// one (it is necessary when the runtime option 4100b57cec5SDimitry Andric /// <c>detect_stack_use_after_return</c> is enabled). 4110b57cec5SDimitry Andric /// 4120b57cec5SDimitry Andric /// When restoring a stack, this <c>void**</c> pointer must be given to the 4130b57cec5SDimitry Andric /// <c>__sanitizer_finish_switch_fiber()</c> function. In most cases, this 4140b57cec5SDimitry Andric /// pointer can be stored on the stack immediately before switching. When 4150b57cec5SDimitry Andric /// leaving a fiber definitely, NULL must be passed as the first argument to 4160b57cec5SDimitry Andric /// the <c>__sanitizer_start_switch_fiber()</c> function so that the fake stack 4170b57cec5SDimitry Andric /// is destroyed. If your program does not need stack use-after-return 4180b57cec5SDimitry Andric /// detection, you can always pass NULL to these two functions. 4190b57cec5SDimitry Andric /// 4200b57cec5SDimitry Andric /// \note The fake stack mechanism is disabled during fiber switch, so if a 4210b57cec5SDimitry Andric /// signal callback runs during the switch, it will not benefit from stack 4220b57cec5SDimitry Andric /// use-after-return detection. 4230b57cec5SDimitry Andric /// 424e8d8bef9SDimitry Andric /// \param[out] fake_stack_save Fake stack save location. 4250b57cec5SDimitry Andric /// \param bottom Bottom address of stack. 4260b57cec5SDimitry Andric /// \param size Size of stack in bytes. 427*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_start_switch_fiber(void **fake_stack_save, 428*5f757f3fSDimitry Andric const void *bottom, 429*5f757f3fSDimitry Andric size_t size); 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric /// Notify ASan that a fiber switch has completed (required only if 4320b57cec5SDimitry Andric /// implementing your own fiber library). 4330b57cec5SDimitry Andric /// 4340b57cec5SDimitry Andric /// When code starts running on the new stack, it must call 4350b57cec5SDimitry Andric /// <c>__sanitizer_finish_switch_fiber()</c> to finalize 4360b57cec5SDimitry Andric /// the switch. For usage details, see the description of 4370b57cec5SDimitry Andric /// <c>__sanitizer_start_switch_fiber()</c>. 4380b57cec5SDimitry Andric /// 4390b57cec5SDimitry Andric /// \param fake_stack_save Fake stack save location. 440e8d8bef9SDimitry Andric /// \param[out] bottom_old Bottom address of old stack. 441e8d8bef9SDimitry Andric /// \param[out] size_old Size of old stack in bytes. 442*5f757f3fSDimitry Andric void SANITIZER_CDECL __sanitizer_finish_switch_fiber(void *fake_stack_save, 4430b57cec5SDimitry Andric const void **bottom_old, 4440b57cec5SDimitry Andric size_t *size_old); 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric // Get full module name and calculate pc offset within it. 4470b57cec5SDimitry Andric // Returns 1 if pc belongs to some module, 0 if module was not found. 448*5f757f3fSDimitry Andric int SANITIZER_CDECL __sanitizer_get_module_and_offset_for_pc( 449*5f757f3fSDimitry Andric void *pc, char *module_path, size_t module_path_len, void **pc_offset); 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric #ifdef __cplusplus 4520b57cec5SDimitry Andric } // extern "C" 4530b57cec5SDimitry Andric #endif 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric #endif // SANITIZER_COMMON_INTERFACE_DEFS_H 456