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