11f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//===-- sanitizer_posix.cc ------------------------------------------------===//
21f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//
31f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//                     The LLVM Compiler Infrastructure
41f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//
51f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// This file is distributed under the University of Illinois Open Source
61f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// License. See LICENSE.TXT for details.
71f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//
81f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//===----------------------------------------------------------------------===//
91f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//
101f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// This file is shared between AddressSanitizer and ThreadSanitizer
111f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// run-time libraries and implements POSIX-specific functions from
121f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// sanitizer_libc.h.
131f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//===----------------------------------------------------------------------===//
141f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#if defined(__linux__) || defined(__APPLE__)
151f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
16230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include "sanitizer_common.h"
171f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#include "sanitizer_libc.h"
18be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov#include "sanitizer_procmaps.h"
191f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
200aa04b3f432bc55e7c116d5280685ee3f243be8eKostya Serebryany#include <errno.h>
21fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov#include <pthread.h>
221f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#include <stdarg.h>
231f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#include <stdio.h>
24fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov#include <stdlib.h>
250aa04b3f432bc55e7c116d5280685ee3f243be8eKostya Serebryany#include <string.h>
26230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include <sys/mman.h>
27be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov#include <sys/resource.h>
28be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov#include <sys/time.h>
29230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include <sys/types.h>
30230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include <unistd.h>
311f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
321f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonovnamespace __sanitizer {
331f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
34be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov// ------------- sanitizer_common.h
35be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov
36230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovint GetPid() {
37230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  return getpid();
38230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
39230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
40fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovuptr GetThreadSelf() {
41fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov  return (uptr)pthread_self();
42fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov}
43fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov
44a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonovvoid *MmapOrDie(uptr size, const char *mem_type) {
45230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  size = RoundUpTo(size, kPageSize);
46230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  void *res = internal_mmap(0, size,
47230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov                            PROT_READ | PROT_WRITE,
48230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov                            MAP_PRIVATE | MAP_ANON, -1, 0);
49230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  if (res == (void*)-1) {
500aa04b3f432bc55e7c116d5280685ee3f243be8eKostya Serebryany    Report("ERROR: Failed to allocate 0x%zx (%zd) bytes of %s: %s\n",
510aa04b3f432bc55e7c116d5280685ee3f243be8eKostya Serebryany           size, size, mem_type, strerror(errno));
520aa04b3f432bc55e7c116d5280685ee3f243be8eKostya Serebryany    DumpProcessMap();
53a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov    CHECK("unable to mmap" && 0);
54230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  }
55230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  return res;
56230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
57230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
58230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovvoid UnmapOrDie(void *addr, uptr size) {
59230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  if (!addr || !size) return;
60230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  int res = internal_munmap(addr, size);
61230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  if (res != 0) {
62a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov    Report("ERROR: Failed to deallocate 0x%zx (%zd) bytes at address %p\n",
63a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov           size, size, addr);
64a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov    CHECK("unable to unmap" && 0);
65230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  }
66230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
67230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
68f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonovvoid *MmapFixedNoReserve(uptr fixed_addr, uptr size) {
69f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov  return internal_mmap((void*)fixed_addr, size,
70f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov                      PROT_READ | PROT_WRITE,
71f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov                      MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
7284902c716abf9ba0dc6e7b1cd0522759f29b3179Alexey Samsonov                      -1, 0);
73f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov}
74f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov
75f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonovvoid *Mprotect(uptr fixed_addr, uptr size) {
76f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov  return internal_mmap((void*)fixed_addr, size,
77f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov                       PROT_NONE,
78f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov                       MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
7984902c716abf9ba0dc6e7b1cd0522759f29b3179Alexey Samsonov                       -1, 0);
80f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov}
81f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov
82a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonovvoid *MapFileToMemory(const char *file_name, uptr *buff_size) {
83a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  fd_t fd = internal_open(file_name, false);
84a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  CHECK_NE(fd, kInvalidFd);
85a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  uptr fsize = internal_filesize(fd);
86a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  CHECK_NE(fsize, (uptr)-1);
87a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  CHECK_GT(fsize, 0);
88a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  *buff_size = RoundUpTo(fsize, kPageSize);
89a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  void *map = internal_mmap(0, *buff_size, PROT_READ, MAP_PRIVATE, fd, 0);
90a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  return (map == MAP_FAILED) ? 0 : map;
91a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov}
92a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov
93a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov
94dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonovstatic inline bool IntervalsAreSeparate(uptr start1, uptr end1,
95dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov                                        uptr start2, uptr end2) {
96dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  CHECK(start1 <= end1);
97dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  CHECK(start2 <= end2);
98dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  return (end1 < start2) || (end2 < start1);
99dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov}
100dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov
101dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// FIXME: this is thread-unsafe, but should not cause problems most of the time.
102dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// When the shadow is mapped only a single thread usually exists (plus maybe
103dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// several worker threads on Mac, which aren't expected to map big chunks of
104dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// memory).
105dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonovbool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {
106e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonov  MemoryMappingLayout procmaps;
107dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  uptr start, end;
108dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  while (procmaps.Next(&start, &end,
109dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov                       /*offset*/0, /*filename*/0, /*filename_size*/0)) {
110dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov    if (!IntervalsAreSeparate(start, end, range_start, range_end))
111dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov      return false;
112dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  }
113dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  return true;
114dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov}
115dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov
116be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonovvoid DumpProcessMap() {
117e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonov  MemoryMappingLayout proc_maps;
118be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  uptr start, end;
119be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  const sptr kBufSize = 4095;
120b84ee029ada36949c30c57c5f701191783990574Alexey Samsonov  char *filename = (char*)MmapOrDie(kBufSize, __FUNCTION__);
121be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  Report("Process memory map follows:\n");
122be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  while (proc_maps.Next(&start, &end, /* file_offset */0,
123be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov                        filename, kBufSize)) {
124be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov    Printf("\t%p-%p\t%s\n", (void*)start, (void*)end, filename);
125be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  }
126be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  Report("End of process memory map.\n");
127b84ee029ada36949c30c57c5f701191783990574Alexey Samsonov  UnmapOrDie(filename, kBufSize);
128be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov}
129be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov
1300969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonovconst char *GetPwd() {
1310969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov  return GetEnv("PWD");
1320969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov}
1330969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov
134be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonovvoid DisableCoreDumper() {
135be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  struct rlimit nocore;
136be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  nocore.rlim_cur = 0;
137be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  nocore.rlim_max = 0;
138be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  setrlimit(RLIMIT_CORE, &nocore);
139be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov}
140be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov
141fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid SleepForSeconds(int seconds) {
142fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov  sleep(seconds);
143fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov}
144fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov
1450969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonovvoid SleepForMillis(int millis) {
1460969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov  usleep(millis * 1000);
1470969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov}
1480969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov
149fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid Exit(int exitcode) {
150fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov  _exit(exitcode);
151fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov}
152fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov
153fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid Abort() {
154fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov  abort();
155fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov}
156fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov
157fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovint Atexit(void (*function)(void)) {
158b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#ifndef SANITIZER_GO
159fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov  return atexit(function);
160b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#else
161b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov  return 0;
162b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#endif
163fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov}
164fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov
1651f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov}  // namespace __sanitizer
1661f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
1671f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#endif  // __linux__ || __APPLE_
168