1 //===-- sanitizer_posix.cc ------------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is shared between AddressSanitizer and ThreadSanitizer
9 // run-time libraries and implements POSIX-specific functions from
11 //===----------------------------------------------------------------------===//
12 #if defined(__linux__) || defined(__APPLE__)
14 #include "sanitizer_common.h"
15 #include "sanitizer_libc.h"
16 #include "sanitizer_procmaps.h"
25 #include <sys/resource.h>
27 #include <sys/types.h>
30 namespace __sanitizer
{
32 // ------------- sanitizer_common.h
34 return sysconf(_SC_PAGESIZE
);
37 uptr
GetMmapGranularity() {
45 uptr
GetThreadSelf() {
46 return (uptr
)pthread_self();
49 void *MmapOrDie(uptr size
, const char *mem_type
) {
50 size
= RoundUpTo(size
, GetPageSizeCached());
51 void *res
= internal_mmap(0, size
,
52 PROT_READ
| PROT_WRITE
,
53 MAP_PRIVATE
| MAP_ANON
, -1, 0);
54 if (res
== (void*)-1) {
55 static int recursion_count
;
56 if (recursion_count
) {
57 // The Report() and CHECK calls below may call mmap recursively and fail.
58 // If we went into recursion, just die.
59 RawWrite("AddressSanitizer is unable to mmap\n");
63 Report("ERROR: Failed to allocate 0x%zx (%zd) bytes of %s: %s\n",
64 size
, size
, mem_type
, strerror(errno
));
66 CHECK("unable to mmap" && 0);
71 void UnmapOrDie(void *addr
, uptr size
) {
72 if (!addr
|| !size
) return;
73 int res
= internal_munmap(addr
, size
);
75 Report("ERROR: Failed to deallocate 0x%zx (%zd) bytes at address %p\n",
77 CHECK("unable to unmap" && 0);
81 void *MmapFixedNoReserve(uptr fixed_addr
, uptr size
) {
82 uptr PageSize
= GetPageSizeCached();
83 void *p
= internal_mmap((void*)(fixed_addr
& ~(PageSize
- 1)),
84 RoundUpTo(size
, PageSize
),
85 PROT_READ
| PROT_WRITE
,
86 MAP_PRIVATE
| MAP_ANON
| MAP_FIXED
| MAP_NORESERVE
,
89 Report("ERROR: Failed to allocate 0x%zx (%zd) bytes at address %p (%d)\n",
90 size
, size
, fixed_addr
, errno
);
94 void *Mprotect(uptr fixed_addr
, uptr size
) {
95 return internal_mmap((void*)fixed_addr
, size
,
97 MAP_PRIVATE
| MAP_ANON
| MAP_FIXED
| MAP_NORESERVE
,
101 void *MapFileToMemory(const char *file_name
, uptr
*buff_size
) {
102 fd_t fd
= internal_open(file_name
, false);
103 CHECK_NE(fd
, kInvalidFd
);
104 uptr fsize
= internal_filesize(fd
);
105 CHECK_NE(fsize
, (uptr
)-1);
107 *buff_size
= RoundUpTo(fsize
, GetPageSizeCached());
108 void *map
= internal_mmap(0, *buff_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
109 return (map
== MAP_FAILED
) ? 0 : map
;
113 static inline bool IntervalsAreSeparate(uptr start1
, uptr end1
,
114 uptr start2
, uptr end2
) {
115 CHECK(start1
<= end1
);
116 CHECK(start2
<= end2
);
117 return (end1
< start2
) || (end2
< start1
);
120 // FIXME: this is thread-unsafe, but should not cause problems most of the time.
121 // When the shadow is mapped only a single thread usually exists (plus maybe
122 // several worker threads on Mac, which aren't expected to map big chunks of
124 bool MemoryRangeIsAvailable(uptr range_start
, uptr range_end
) {
125 MemoryMappingLayout procmaps
;
127 while (procmaps
.Next(&start
, &end
,
128 /*offset*/0, /*filename*/0, /*filename_size*/0)) {
129 if (!IntervalsAreSeparate(start
, end
, range_start
, range_end
))
135 void DumpProcessMap() {
136 MemoryMappingLayout proc_maps
;
138 const sptr kBufSize
= 4095;
139 char *filename
= (char*)MmapOrDie(kBufSize
, __FUNCTION__
);
140 Report("Process memory map follows:\n");
141 while (proc_maps
.Next(&start
, &end
, /* file_offset */0,
142 filename
, kBufSize
)) {
143 Printf("\t%p-%p\t%s\n", (void*)start
, (void*)end
, filename
);
145 Report("End of process memory map.\n");
146 UnmapOrDie(filename
, kBufSize
);
149 const char *GetPwd() {
150 return GetEnv("PWD");
153 void DisableCoreDumper() {
154 struct rlimit nocore
;
157 setrlimit(RLIMIT_CORE
, &nocore
);
160 bool StackSizeIsUnlimited() {
162 CHECK_EQ(0, getrlimit(RLIMIT_STACK
, &rlim
));
163 return (rlim
.rlim_cur
== (uptr
)-1);
166 void SetStackSizeLimitInBytes(uptr limit
) {
168 rlim
.rlim_cur
= limit
;
169 rlim
.rlim_max
= limit
;
170 if (setrlimit(RLIMIT_STACK
, &rlim
)) {
171 Report("setrlimit() failed %d\n", errno
);
174 CHECK(!StackSizeIsUnlimited());
177 void SleepForSeconds(int seconds
) {
181 void SleepForMillis(int millis
) {
182 usleep(millis
* 1000);
185 void Exit(int exitcode
) {
193 int Atexit(void (*function
)(void)) {
195 return atexit(function
);
201 int internal_isatty(fd_t fd
) {
205 } // namespace __sanitizer
207 #endif // __linux__ || __APPLE_