1 //===-- sanitizer_posix.cc ------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is shared between AddressSanitizer and ThreadSanitizer
11 // run-time libraries and implements POSIX-specific functions from
13 //===----------------------------------------------------------------------===//
14 #if defined(__linux__) || defined(__APPLE__)
16 #include "sanitizer_common.h"
17 #include "sanitizer_libc.h"
18 #include "sanitizer_procmaps.h"
27 #include <sys/resource.h>
29 #include <sys/types.h>
32 namespace __sanitizer
{
34 // ------------- sanitizer_common.h
40 uptr
GetThreadSelf() {
41 return (uptr
)pthread_self();
44 void *MmapOrDie(uptr size
, const char *mem_type
) {
45 size
= RoundUpTo(size
, kPageSize
);
46 void *res
= internal_mmap(0, size
,
47 PROT_READ
| PROT_WRITE
,
48 MAP_PRIVATE
| MAP_ANON
, -1, 0);
49 if (res
== (void*)-1) {
50 static int recursion_count
;
51 if (recursion_count
) {
52 // The Report() and CHECK calls below may call mmap recursively and fail.
53 // If we went into recursion, just die.
54 RawWrite("AddressSanitizer is unable to mmap\n");
58 Report("ERROR: Failed to allocate 0x%zx (%zd) bytes of %s: %s\n",
59 size
, size
, mem_type
, strerror(errno
));
61 CHECK("unable to mmap" && 0);
66 void UnmapOrDie(void *addr
, uptr size
) {
67 if (!addr
|| !size
) return;
68 int res
= internal_munmap(addr
, size
);
70 Report("ERROR: Failed to deallocate 0x%zx (%zd) bytes at address %p\n",
72 CHECK("unable to unmap" && 0);
76 void *MmapFixedNoReserve(uptr fixed_addr
, uptr size
) {
77 void *p
= internal_mmap((void*)fixed_addr
, size
,
78 PROT_READ
| PROT_WRITE
,
79 MAP_PRIVATE
| MAP_ANON
| MAP_FIXED
| MAP_NORESERVE
,
81 if (p
!= (void*)fixed_addr
)
82 Report("ERROR: Failed to deallocate 0x%zx (%zd) bytes at address %p (%d)\n",
83 size
, size
, fixed_addr
, errno
);
87 void *Mprotect(uptr fixed_addr
, uptr size
) {
88 return internal_mmap((void*)fixed_addr
, size
,
90 MAP_PRIVATE
| MAP_ANON
| MAP_FIXED
| MAP_NORESERVE
,
94 void *MapFileToMemory(const char *file_name
, uptr
*buff_size
) {
95 fd_t fd
= internal_open(file_name
, false);
96 CHECK_NE(fd
, kInvalidFd
);
97 uptr fsize
= internal_filesize(fd
);
98 CHECK_NE(fsize
, (uptr
)-1);
100 *buff_size
= RoundUpTo(fsize
, kPageSize
);
101 void *map
= internal_mmap(0, *buff_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
102 return (map
== MAP_FAILED
) ? 0 : map
;
106 static inline bool IntervalsAreSeparate(uptr start1
, uptr end1
,
107 uptr start2
, uptr end2
) {
108 CHECK(start1
<= end1
);
109 CHECK(start2
<= end2
);
110 return (end1
< start2
) || (end2
< start1
);
113 // FIXME: this is thread-unsafe, but should not cause problems most of the time.
114 // When the shadow is mapped only a single thread usually exists (plus maybe
115 // several worker threads on Mac, which aren't expected to map big chunks of
117 bool MemoryRangeIsAvailable(uptr range_start
, uptr range_end
) {
118 MemoryMappingLayout procmaps
;
120 while (procmaps
.Next(&start
, &end
,
121 /*offset*/0, /*filename*/0, /*filename_size*/0)) {
122 if (!IntervalsAreSeparate(start
, end
, range_start
, range_end
))
128 void DumpProcessMap() {
129 MemoryMappingLayout proc_maps
;
131 const sptr kBufSize
= 4095;
132 char *filename
= (char*)MmapOrDie(kBufSize
, __FUNCTION__
);
133 Report("Process memory map follows:\n");
134 while (proc_maps
.Next(&start
, &end
, /* file_offset */0,
135 filename
, kBufSize
)) {
136 Printf("\t%p-%p\t%s\n", (void*)start
, (void*)end
, filename
);
138 Report("End of process memory map.\n");
139 UnmapOrDie(filename
, kBufSize
);
142 const char *GetPwd() {
143 return GetEnv("PWD");
146 void DisableCoreDumper() {
147 struct rlimit nocore
;
150 setrlimit(RLIMIT_CORE
, &nocore
);
153 bool StackSizeIsUnlimited() {
155 CHECK_EQ(0, getrlimit(RLIMIT_STACK
, &rlim
));
156 return (rlim
.rlim_cur
== (uptr
)-1);
159 void SetStackSizeLimitInBytes(uptr limit
) {
161 rlim
.rlim_cur
= limit
;
162 rlim
.rlim_max
= limit
;
163 CHECK_EQ(0, setrlimit(RLIMIT_STACK
, &rlim
));
164 CHECK(!StackSizeIsUnlimited());
167 void SleepForSeconds(int seconds
) {
171 void SleepForMillis(int millis
) {
172 usleep(millis
* 1000);
175 void Exit(int exitcode
) {
183 int Atexit(void (*function
)(void)) {
185 return atexit(function
);
191 int internal_isatty(fd_t fd
) {
195 } // namespace __sanitizer
197 #endif // __linux__ || __APPLE_