sanitizer_linux_libcdep.cc revision 7177d2bbb5850fb499d3e8910b2e05f5c6b025b0
1//===-- sanitizer_linux_libcdep.cc ----------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is shared between AddressSanitizer and ThreadSanitizer 11// run-time libraries and implements linux-specific functions from 12// sanitizer_libc.h. 13//===----------------------------------------------------------------------===// 14 15#include "sanitizer_platform.h" 16#if SANITIZER_LINUX 17 18#include "sanitizer_common.h" 19#include "sanitizer_flags.h" 20#include "sanitizer_linux.h" 21#include "sanitizer_placement_new.h" 22#include "sanitizer_procmaps.h" 23#include "sanitizer_stacktrace.h" 24 25#include <dlfcn.h> 26#include <pthread.h> 27#include <sys/prctl.h> 28#include <sys/resource.h> 29#include <unwind.h> 30 31#if !SANITIZER_ANDROID 32#include <elf.h> 33#include <link.h> 34#endif 35 36namespace __sanitizer { 37 38void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, 39 uptr *stack_bottom) { 40 static const uptr kMaxThreadStackSize = 1 << 30; // 1Gb 41 CHECK(stack_top); 42 CHECK(stack_bottom); 43 if (at_initialization) { 44 // This is the main thread. Libpthread may not be initialized yet. 45 struct rlimit rl; 46 CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0); 47 48 // Find the mapping that contains a stack variable. 49 MemoryMappingLayout proc_maps(/*cache_enabled*/true); 50 uptr start, end, offset; 51 uptr prev_end = 0; 52 while (proc_maps.Next(&start, &end, &offset, 0, 0, /* protection */0)) { 53 if ((uptr)&rl < end) 54 break; 55 prev_end = end; 56 } 57 CHECK((uptr)&rl >= start && (uptr)&rl < end); 58 59 // Get stacksize from rlimit, but clip it so that it does not overlap 60 // with other mappings. 61 uptr stacksize = rl.rlim_cur; 62 if (stacksize > end - prev_end) 63 stacksize = end - prev_end; 64 // When running with unlimited stack size, we still want to set some limit. 65 // The unlimited stack size is caused by 'ulimit -s unlimited'. 66 // Also, for some reason, GNU make spawns subprocesses with unlimited stack. 67 if (stacksize > kMaxThreadStackSize) 68 stacksize = kMaxThreadStackSize; 69 *stack_top = end; 70 *stack_bottom = end - stacksize; 71 return; 72 } 73 pthread_attr_t attr; 74 CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0); 75 uptr stacksize = 0; 76 void *stackaddr = 0; 77 pthread_attr_getstack(&attr, &stackaddr, (size_t*)&stacksize); 78 pthread_attr_destroy(&attr); 79 80 CHECK_LE(stacksize, kMaxThreadStackSize); // Sanity check. 81 *stack_top = (uptr)stackaddr + stacksize; 82 *stack_bottom = (uptr)stackaddr; 83} 84 85// Does not compile for Go because dlsym() requires -ldl 86#ifndef SANITIZER_GO 87bool SetEnv(const char *name, const char *value) { 88 void *f = dlsym(RTLD_NEXT, "setenv"); 89 if (f == 0) 90 return false; 91 typedef int(*setenv_ft)(const char *name, const char *value, int overwrite); 92 setenv_ft setenv_f; 93 CHECK_EQ(sizeof(setenv_f), sizeof(f)); 94 internal_memcpy(&setenv_f, &f, sizeof(f)); 95 return setenv_f(name, value, 1) == 0; 96} 97#endif 98 99bool SanitizerSetThreadName(const char *name) { 100#ifdef PR_SET_NAME 101 return 0 == prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0); // NOLINT 102#else 103 return false; 104#endif 105} 106 107bool SanitizerGetThreadName(char *name, int max_len) { 108#ifdef PR_GET_NAME 109 char buff[17]; 110 if (prctl(PR_GET_NAME, (unsigned long)buff, 0, 0, 0)) // NOLINT 111 return false; 112 internal_strncpy(name, buff, max_len); 113 name[max_len] = 0; 114 return true; 115#else 116 return false; 117#endif 118} 119 120#ifndef SANITIZER_GO 121//------------------------- SlowUnwindStack ----------------------------------- 122#ifdef __arm__ 123#define UNWIND_STOP _URC_END_OF_STACK 124#define UNWIND_CONTINUE _URC_NO_REASON 125#else 126#define UNWIND_STOP _URC_NORMAL_STOP 127#define UNWIND_CONTINUE _URC_NO_REASON 128#endif 129 130uptr Unwind_GetIP(struct _Unwind_Context *ctx) { 131#ifdef __arm__ 132 uptr val; 133 _Unwind_VRS_Result res = _Unwind_VRS_Get(ctx, _UVRSC_CORE, 134 15 /* r15 = PC */, _UVRSD_UINT32, &val); 135 CHECK(res == _UVRSR_OK && "_Unwind_VRS_Get failed"); 136 // Clear the Thumb bit. 137 return val & ~(uptr)1; 138#else 139 return _Unwind_GetIP(ctx); 140#endif 141} 142 143struct UnwindTraceArg { 144 StackTrace *stack; 145 uptr max_depth; 146}; 147 148_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) { 149 UnwindTraceArg *arg = (UnwindTraceArg*)param; 150 CHECK_LT(arg->stack->size, arg->max_depth); 151 uptr pc = Unwind_GetIP(ctx); 152 arg->stack->trace[arg->stack->size++] = pc; 153 if (arg->stack->size == arg->max_depth) return UNWIND_STOP; 154 return UNWIND_CONTINUE; 155} 156 157void StackTrace::SlowUnwindStack(uptr pc, uptr max_depth) { 158 size = 0; 159 if (max_depth == 0) 160 return; 161 UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)}; 162 _Unwind_Backtrace(Unwind_Trace, &arg); 163 // We need to pop a few frames so that pc is on top. 164 uptr to_pop = LocatePcInTrace(pc, 64, 6); 165 // trace[0] belongs to the current function so we always pop it. 166 if (to_pop == 0) 167 to_pop = 1; 168 PopStackFrames(to_pop); 169 trace[0] = pc; 170} 171 172#endif // !SANITIZER_GO 173 174static uptr g_tls_size; 175 176#ifdef __i386__ 177# define DL_INTERNAL_FUNCTION __attribute__((regparm(3), stdcall)) 178#else 179# define DL_INTERNAL_FUNCTION 180#endif 181 182void InitTlsSize() { 183#if !defined(SANITIZER_GO) && !SANITIZER_ANDROID 184 typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION; 185 get_tls_func get_tls; 186 void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info"); 187 CHECK_EQ(sizeof(get_tls), sizeof(get_tls_static_info_ptr)); 188 internal_memcpy(&get_tls, &get_tls_static_info_ptr, 189 sizeof(get_tls_static_info_ptr)); 190 CHECK_NE(get_tls, 0); 191 size_t tls_size = 0; 192 size_t tls_align = 0; 193 get_tls(&tls_size, &tls_align); 194 g_tls_size = tls_size; 195#endif 196} 197 198uptr GetTlsSize() { 199 return g_tls_size; 200} 201 202#if defined(__x86_64__) || defined(__i386__) 203// sizeof(struct thread) from glibc. 204// There has been a report of this being different on glibc 2.11 and 2.13. We 205// don't know when this change happened, so 2.14 is a conservative estimate. 206#if __GLIBC_PREREQ(2, 14) 207const uptr kThreadDescriptorSize = FIRST_32_SECOND_64(1216, 2304); 208#else 209const uptr kThreadDescriptorSize = FIRST_32_SECOND_64(1168, 2304); 210#endif 211 212uptr ThreadDescriptorSize() { 213 return kThreadDescriptorSize; 214} 215 216// The offset at which pointer to self is located in the thread descriptor. 217const uptr kThreadSelfOffset = FIRST_32_SECOND_64(8, 16); 218 219uptr ThreadSelfOffset() { 220 return kThreadSelfOffset; 221} 222 223uptr ThreadSelf() { 224 uptr descr_addr; 225#ifdef __i386__ 226 asm("mov %%gs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset)); 227#else 228 asm("mov %%fs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset)); 229#endif 230 return descr_addr; 231} 232#endif // defined(__x86_64__) || defined(__i386__) 233 234void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, 235 uptr *tls_addr, uptr *tls_size) { 236#ifndef SANITIZER_GO 237#if defined(__x86_64__) || defined(__i386__) 238 *tls_addr = ThreadSelf(); 239 *tls_size = GetTlsSize(); 240 *tls_addr -= *tls_size; 241 *tls_addr += kThreadDescriptorSize; 242#else 243 *tls_addr = 0; 244 *tls_size = 0; 245#endif 246 247 uptr stack_top, stack_bottom; 248 GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom); 249 *stk_addr = stack_bottom; 250 *stk_size = stack_top - stack_bottom; 251 252 if (!main) { 253 // If stack and tls intersect, make them non-intersecting. 254 if (*tls_addr > *stk_addr && *tls_addr < *stk_addr + *stk_size) { 255 CHECK_GT(*tls_addr + *tls_size, *stk_addr); 256 CHECK_LE(*tls_addr + *tls_size, *stk_addr + *stk_size); 257 *stk_size -= *tls_size; 258 *tls_addr = *stk_addr + *stk_size; 259 } 260 } 261#else // SANITIZER_GO 262 *stk_addr = 0; 263 *stk_size = 0; 264 *tls_addr = 0; 265 *tls_size = 0; 266#endif // SANITIZER_GO 267} 268 269void AdjustStackSizeLinux(void *attr_) { 270 pthread_attr_t *attr = (pthread_attr_t *)attr_; 271 uptr stackaddr = 0; 272 size_t stacksize = 0; 273 pthread_attr_getstack(attr, (void**)&stackaddr, &stacksize); 274 // GLibC will return (0 - stacksize) as the stack address in the case when 275 // stacksize is set, but stackaddr is not. 276 bool stack_set = (stackaddr != 0) && (stackaddr + stacksize != 0); 277 // We place a lot of tool data into TLS, account for that. 278 const uptr minstacksize = GetTlsSize() + 128*1024; 279 if (stacksize < minstacksize) { 280 if (!stack_set) { 281 if (common_flags()->verbosity && stacksize != 0) 282 Printf("Sanitizer: increasing stacksize %zu->%zu\n", stacksize, 283 minstacksize); 284 pthread_attr_setstacksize(attr, minstacksize); 285 } else { 286 Printf("Sanitizer: pre-allocated stack size is insufficient: " 287 "%zu < %zu\n", stacksize, minstacksize); 288 Printf("Sanitizer: pthread_create is likely to fail.\n"); 289 } 290 } 291} 292 293#if SANITIZER_ANDROID 294uptr GetListOfModules(LoadedModule *modules, uptr max_modules, 295 string_predicate_t filter) { 296 return 0; 297} 298#else // SANITIZER_ANDROID 299typedef ElfW(Phdr) Elf_Phdr; 300 301struct DlIteratePhdrData { 302 LoadedModule *modules; 303 uptr current_n; 304 bool first; 305 uptr max_n; 306 string_predicate_t filter; 307}; 308 309static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { 310 DlIteratePhdrData *data = (DlIteratePhdrData*)arg; 311 if (data->current_n == data->max_n) 312 return 0; 313 InternalScopedBuffer<char> module_name(kMaxPathLength); 314 module_name.data()[0] = '\0'; 315 if (data->first) { 316 data->first = false; 317 // First module is the binary itself. 318 ReadBinaryName(module_name.data(), module_name.size()); 319 } else if (info->dlpi_name) { 320 internal_strncpy(module_name.data(), info->dlpi_name, module_name.size()); 321 } 322 if (module_name.data()[0] == '\0') 323 return 0; 324 if (data->filter && !data->filter(module_name.data())) 325 return 0; 326 void *mem = &data->modules[data->current_n]; 327 LoadedModule *cur_module = new(mem) LoadedModule(module_name.data(), 328 info->dlpi_addr); 329 data->current_n++; 330 for (int i = 0; i < info->dlpi_phnum; i++) { 331 const Elf_Phdr *phdr = &info->dlpi_phdr[i]; 332 if (phdr->p_type == PT_LOAD) { 333 uptr cur_beg = info->dlpi_addr + phdr->p_vaddr; 334 uptr cur_end = cur_beg + phdr->p_memsz; 335 cur_module->addAddressRange(cur_beg, cur_end); 336 } 337 } 338 return 0; 339} 340 341uptr GetListOfModules(LoadedModule *modules, uptr max_modules, 342 string_predicate_t filter) { 343 CHECK(modules); 344 DlIteratePhdrData data = {modules, 0, true, max_modules, filter}; 345 dl_iterate_phdr(dl_iterate_phdr_cb, &data); 346 return data.current_n; 347} 348#endif // SANITIZER_ANDROID 349 350} // namespace __sanitizer 351 352#endif // SANITIZER_LINUX 353