sanitizer_common.cc revision 694d85636b148dfcac37e5c23639baa8fe9abce9
1230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov//===-- sanitizer_common.cc -----------------------------------------------===// 2230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// 3230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// The LLVM Compiler Infrastructure 4230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// 5230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// This file is distributed under the University of Illinois Open Source 6230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// License. See LICENSE.TXT for details. 7230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// 8230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov//===----------------------------------------------------------------------===// 9230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// 10230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// This file is shared between AddressSanitizer and ThreadSanitizer 11230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// run-time libraries. 12230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov//===----------------------------------------------------------------------===// 13230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 14230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include "sanitizer_common.h" 1590b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov#include "sanitizer_flags.h" 16230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include "sanitizer_libc.h" 172fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov#include "sanitizer_stacktrace.h" 182fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov#include "sanitizer_symbolizer.h" 194c49666e611f06241bb8462cea7674d877241492Alexey Samsonov 20230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovnamespace __sanitizer { 21230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 22859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryanyconst char *SanitizerToolName = "SanitizerTool"; 23859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany 24f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryanyuptr GetPageSizeCached() { 25f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany static uptr PageSize; 26f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany if (!PageSize) 27f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany PageSize = GetPageSize(); 28f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany return PageSize; 29f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany} 30f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany 31dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko 32dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// By default, dump to stderr. If |log_to_file| is true and |report_fd_pid| 33dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// isn't equal to the current PID, try to obtain file descriptor by opening 34dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// file "report_path_prefix.<PID>". 350c547de62dc0852a03fae2d868fa571e7f5512b3Peter Collingbournefd_t report_fd = kStderrFd; 36923bac7a85d8bd37219b440a6b4c0800ea4bcd21Reid Kleckner 37923bac7a85d8bd37219b440a6b4c0800ea4bcd21Reid Kleckner// Set via __sanitizer_set_report_path. 38923bac7a85d8bd37219b440a6b4c0800ea4bcd21Reid Klecknerbool log_to_file = false; 39923bac7a85d8bd37219b440a6b4c0800ea4bcd21Reid Klecknerchar report_path_prefix[sizeof(report_path_prefix)]; 40923bac7a85d8bd37219b440a6b4c0800ea4bcd21Reid Kleckner 41dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// PID of process that opened |report_fd|. If a fork() occurs, the PID of the 42dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// child thread will be different from |report_fd_pid|. 43923bac7a85d8bd37219b440a6b4c0800ea4bcd21Reid Kleckneruptr report_fd_pid = 0; 4481dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany 4590629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveevstatic DieCallbackType DieCallback; 4690629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveevvoid SetDieCallback(DieCallbackType callback) { 47591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov DieCallback = callback; 48591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov} 49591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov 5090629fb8072efc95e46a0cbc641293511fbaba2eSergey MatveevDieCallbackType GetDieCallback() { 5190629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev return DieCallback; 5290629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev} 5390629fb8072efc95e46a0cbc641293511fbaba2eSergey Matveev 54591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovvoid NORETURN Die() { 55591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov if (DieCallback) { 56591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov DieCallback(); 57591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov } 58f882247088952deed954a19d745c2dd8871e2035Alexey Samsonov internal__exit(1); 59591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov} 60591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov 61591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovstatic CheckFailedCallbackType CheckFailedCallback; 62591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovvoid SetCheckFailedCallback(CheckFailedCallbackType callback) { 63591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov CheckFailedCallback = callback; 64591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov} 65591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov 66591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovvoid NORETURN CheckFailed(const char *file, int line, const char *cond, 67591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov u64 v1, u64 v2) { 68591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov if (CheckFailedCallback) { 69591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov CheckFailedCallback(file, line, cond, v1, v2); 70591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov } 71e3c35c7e30ce24b76f1e67eb049cf9e84c9b89d8Dmitry Vyukov Report("Sanitizer CHECK failed: %s:%d %s (%lld, %lld)\n", file, line, cond, 72e3c35c7e30ce24b76f1e67eb049cf9e84c9b89d8Dmitry Vyukov v1, v2); 73591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov Die(); 74591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov} 75591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov 76cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonovuptr ReadFileToBuffer(const char *file_name, char **buff, 77cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov uptr *buff_size, uptr max_len) { 78f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany uptr PageSize = GetPageSizeCached(); 79f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany uptr kMinFileLen = PageSize; 80cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov uptr read_len = 0; 81cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov *buff = 0; 82cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov *buff_size = 0; 83cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov // The files we usually open are not seekable, so try different buffer sizes. 84cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov for (uptr size = kMinFileLen; size <= max_len; size *= 2) { 859578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne uptr openrv = OpenFile(file_name, /*write*/ false); 869578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne if (internal_iserror(openrv)) return 0; 879578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne fd_t fd = openrv; 88cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov UnmapOrDie(*buff, *buff_size); 89cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov *buff = (char*)MmapOrDie(size, __FUNCTION__); 90cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov *buff_size = size; 91cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov // Read up to one page at a time. 92cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov read_len = 0; 93cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov bool reached_eof = false; 94f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany while (read_len + PageSize <= size) { 95f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany uptr just_read = internal_read(fd, *buff + read_len, PageSize); 96cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov if (just_read == 0) { 97cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov reached_eof = true; 98cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov break; 99cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov } 100cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov read_len += just_read; 101cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov } 102cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov internal_close(fd); 103cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov if (reached_eof) // We've read the whole file. 104cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov break; 105cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov } 106cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov return read_len; 107cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov} 108cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov 10915bb32b9e1342030a6c4742625f3c3356de42a2aSergey Matveevtypedef bool UptrComparisonFunction(const uptr &a, const uptr &b); 11015bb32b9e1342030a6c4742625f3c3356de42a2aSergey Matveev 11115bb32b9e1342030a6c4742625f3c3356de42a2aSergey Matveevtemplate<class T> 11215bb32b9e1342030a6c4742625f3c3356de42a2aSergey Matveevstatic inline bool CompareLess(const T &a, const T &b) { 11315bb32b9e1342030a6c4742625f3c3356de42a2aSergey Matveev return a < b; 11415bb32b9e1342030a6c4742625f3c3356de42a2aSergey Matveev} 11515bb32b9e1342030a6c4742625f3c3356de42a2aSergey Matveev 1164c49666e611f06241bb8462cea7674d877241492Alexey Samsonovvoid SortArray(uptr *array, uptr size) { 11715bb32b9e1342030a6c4742625f3c3356de42a2aSergey Matveev InternalSort<uptr*, UptrComparisonFunction>(&array, size, CompareLess); 1184c49666e611f06241bb8462cea7674d877241492Alexey Samsonov} 1194c49666e611f06241bb8462cea7674d877241492Alexey Samsonov 120cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany// We want to map a chunk of address space aligned to 'alignment'. 121cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany// We do it by maping a bit more and then unmaping redundant pieces. 122cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany// We probably can do it with fewer syscalls in some OS-dependent way. 123cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryanyvoid *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) { 1242dae63aea3589fded1ef17b5a6c7f0c9352559a2Bill Wendling// uptr PageSize = GetPageSizeCached(); 125cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany CHECK(IsPowerOfTwo(size)); 126cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany CHECK(IsPowerOfTwo(alignment)); 127cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany uptr map_size = size + alignment; 128cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany uptr map_res = (uptr)MmapOrDie(map_size, mem_type); 129cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany uptr map_end = map_res + map_size; 130cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany uptr res = map_res; 131cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany if (res & (alignment - 1)) // Not aligned. 1323617ad70f3ade71b944b35fa3faaadfb97700deaDmitry Vyukov res = (map_res + alignment) & ~(alignment - 1); 133cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany uptr end = res + size; 134cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany if (res != map_res) 135cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany UnmapOrDie((void*)map_res, res - map_res); 136cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany if (end != map_end) 137cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany UnmapOrDie((void*)end, map_end - end); 138cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany return (void*)res; 139cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany} 140cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany 14190b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonovconst char *StripPathPrefix(const char *filepath, 14290b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov const char *strip_path_prefix) { 14390b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov if (filepath == 0) return 0; 14490b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov if (strip_path_prefix == 0) return filepath; 14590b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov const char *pos = internal_strstr(filepath, strip_path_prefix); 14690b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov if (pos == 0) return filepath; 14790b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov pos += internal_strlen(strip_path_prefix); 14890b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov if (pos[0] == '.' && pos[1] == '/') 14990b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov pos += 2; 15090b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov return pos; 15190b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov} 15290b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov 15390b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonovvoid PrintSourceLocation(const char *file, int line, int column) { 15490b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov CHECK(file); 15590b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov Printf("%s", StripPathPrefix(file, common_flags()->strip_path_prefix)); 15690b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov if (line > 0) { 15790b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov Printf(":%d", line); 15890b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov if (column > 0) 15990b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov Printf(":%d", column); 16090b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov } 16190b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov} 16290b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov 16390b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonovvoid PrintModuleAndOffset(const char *module, uptr offset) { 16490b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov Printf("(%s+0x%zx)", 16590b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov StripPathPrefix(module, common_flags()->strip_path_prefix), offset); 16690b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov} 16790b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov 1682fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonovvoid ReportErrorSummary(const char *error_message) { 169694d85636b148dfcac37e5c23639baa8fe9abce9Alexey Samsonov if (!common_flags()->print_summary) 170694d85636b148dfcac37e5c23639baa8fe9abce9Alexey Samsonov return; 1712fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov InternalScopedBuffer<char> buff(kMaxSummaryLength); 1722fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov internal_snprintf(buff.data(), buff.size(), 1732fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov "SUMMARY: %s: %s", SanitizerToolName, error_message); 1742fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov __sanitizer_report_error_summary(buff.data()); 1752fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov} 1762fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov 1772673fd8406197c42f16cede6d287f72169298c2eKostya Serebryanyvoid ReportErrorSummary(const char *error_type, const char *file, 1782673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany int line, const char *function) { 179694d85636b148dfcac37e5c23639baa8fe9abce9Alexey Samsonov if (!common_flags()->print_summary) 180694d85636b148dfcac37e5c23639baa8fe9abce9Alexey Samsonov return; 1812fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov InternalScopedBuffer<char> buff(kMaxSummaryLength); 18290b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov internal_snprintf( 1832fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov buff.data(), buff.size(), "%s %s:%d %s", error_type, 18490b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov file ? StripPathPrefix(file, common_flags()->strip_path_prefix) : "??", 18590b0f1e3ba126bb2e92ab51ef379c98782c23d90Alexey Samsonov line, function ? function : "??"); 1862fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov ReportErrorSummary(buff.data()); 1872fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov} 1882fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov 1892fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonovvoid ReportErrorSummary(const char *error_type, StackTrace *stack) { 190694d85636b148dfcac37e5c23639baa8fe9abce9Alexey Samsonov if (!common_flags()->print_summary) 191694d85636b148dfcac37e5c23639baa8fe9abce9Alexey Samsonov return; 1922fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov AddressInfo ai; 19350cdc5a0d78f400183bd9dc7c23a2ed6e733e48bAlexey Samsonov#if !SANITIZER_GO 1942fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov if (stack->size > 0 && Symbolizer::Get()->IsAvailable()) { 1952fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov // Currently, we include the first stack frame into the report summary. 1962fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc). 1972fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]); 1982fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov Symbolizer::Get()->SymbolizeCode(pc, &ai, 1); 1992fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov } 20050cdc5a0d78f400183bd9dc7c23a2ed6e733e48bAlexey Samsonov#endif 2012fb08720b11b4c339e191b90d85477c6a2dd74dbAlexey Samsonov ReportErrorSummary(error_type, ai.file, ai.line, ai.function); 2022673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany} 2032673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany 2047847d77b246635211c3bf465421d49d7af5226c1Alexey SamsonovLoadedModule::LoadedModule(const char *module_name, uptr base_address) { 2057847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov full_name_ = internal_strdup(module_name); 2067847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov base_address_ = base_address; 2077847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov n_ranges_ = 0; 2087847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov} 2097847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov 2107847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonovvoid LoadedModule::addAddressRange(uptr beg, uptr end) { 2117847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov CHECK_LT(n_ranges_, kMaxNumberOfAddressRanges); 2127847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov ranges_[n_ranges_].beg = beg; 2137847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov ranges_[n_ranges_].end = end; 2147847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov n_ranges_++; 2157847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov} 2167847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov 2177847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonovbool LoadedModule::containsAddress(uptr address) const { 2187847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov for (uptr i = 0; i < n_ranges_; i++) { 2197847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov if (ranges_[i].beg <= address && address < ranges_[i].end) 2207847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov return true; 2217847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov } 2227847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov return false; 2237847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov} 2247847d77b246635211c3bf465421d49d7af5226c1Alexey Samsonov 225230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov} // namespace __sanitizer 22681dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany 227ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonovusing namespace __sanitizer; // NOLINT 228ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonov 229ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonovextern "C" { 23081dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryanyvoid __sanitizer_set_report_path(const char *path) { 231b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov if (!path) 232b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov return; 23381dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany uptr len = internal_strlen(path); 234dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko if (len > sizeof(report_path_prefix) - 100) { 23581dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n", 23681dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany path[0], path[1], path[2], path[3], 23781dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany path[4], path[5], path[6], path[7]); 23881dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany Die(); 23981dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany } 240f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov if (report_fd != kStdoutFd && 241f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov report_fd != kStderrFd && 242f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov report_fd != kInvalidFd) 243f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov internal_close(report_fd); 244b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov report_fd = kInvalidFd; 245b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov log_to_file = false; 246b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov if (internal_strcmp(path, "stdout") == 0) { 247b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov report_fd = kStdoutFd; 248b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov } else if (internal_strcmp(path, "stderr") == 0) { 249b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov report_fd = kStderrFd; 250b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov } else { 251b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov internal_strncpy(report_path_prefix, path, sizeof(report_path_prefix)); 252b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov report_path_prefix[len] = '\0'; 253b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov log_to_file = true; 254b48c2b2072c8cc17dc1579a6b20ce6c2a575821dDmitry Vyukov } 255ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonov} 25625742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko 25725742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenkovoid NOINLINE __sanitizer_sandbox_on_notify(void *reserved) { 25825742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko (void)reserved; 25925742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko PrepareForSandboxing(); 26025742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko} 2612673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany 2622673fd8406197c42f16cede6d287f72169298c2eKostya Serebryanyvoid __sanitizer_report_error_summary(const char *error_summary) { 26347fcd76474fc6b6c963ae4eeeeea15d465bd6a3cNick Lewycky Printf("%s\n", error_summary); 2642673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany} 265ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonov} // extern "C" 266