1 //===-- sanitizer_symbolizer_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. 12 // Linux-specific implementation of symbolizer parts. 13 //===----------------------------------------------------------------------===// 14 15 #include "sanitizer_platform.h" 16 #if SANITIZER_LINUX 17 #include "sanitizer_common.h" 18 #include "sanitizer_internal_defs.h" 19 #include "sanitizer_libc.h" 20 #include "sanitizer_linux.h" 21 #include "sanitizer_placement_new.h" 22 #include "sanitizer_symbolizer.h" 23 24 // Android NDK r8e elf.h depends on stdint.h without including the latter. 25 #include <stdint.h> 26 27 #include <elf.h> 28 #include <errno.h> 29 #include <poll.h> 30 #include <sys/socket.h> 31 #include <sys/types.h> 32 #include <sys/wait.h> 33 #include <unistd.h> 34 35 #if !SANITIZER_ANDROID 36 #include <link.h> 37 #endif 38 39 namespace __sanitizer { 40 41 #if SANITIZER_ANDROID 42 uptr GetListOfModules(LoadedModule *modules, uptr max_modules, 43 string_predicate_t filter) { 44 return 0; 45 } 46 #else // SANITIZER_ANDROID 47 typedef ElfW(Phdr) Elf_Phdr; 48 49 struct DlIteratePhdrData { 50 LoadedModule *modules; 51 uptr current_n; 52 bool first; 53 uptr max_n; 54 string_predicate_t filter; 55 }; 56 57 static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { 58 DlIteratePhdrData *data = (DlIteratePhdrData*)arg; 59 if (data->current_n == data->max_n) 60 return 0; 61 InternalScopedBuffer<char> module_name(kMaxPathLength); 62 module_name.data()[0] = '\0'; 63 if (data->first) { 64 data->first = false; 65 // First module is the binary itself. 66 ReadBinaryName(module_name.data(), module_name.size()); 67 } else if (info->dlpi_name) { 68 internal_strncpy(module_name.data(), info->dlpi_name, module_name.size()); 69 } 70 if (module_name.data()[0] == '\0') 71 return 0; 72 if (data->filter && !data->filter(module_name.data())) 73 return 0; 74 void *mem = &data->modules[data->current_n]; 75 LoadedModule *cur_module = new(mem) LoadedModule(module_name.data(), 76 info->dlpi_addr); 77 data->current_n++; 78 for (int i = 0; i < info->dlpi_phnum; i++) { 79 const Elf_Phdr *phdr = &info->dlpi_phdr[i]; 80 if (phdr->p_type == PT_LOAD) { 81 uptr cur_beg = info->dlpi_addr + phdr->p_vaddr; 82 uptr cur_end = cur_beg + phdr->p_memsz; 83 cur_module->addAddressRange(cur_beg, cur_end); 84 } 85 } 86 return 0; 87 } 88 89 uptr GetListOfModules(LoadedModule *modules, uptr max_modules, 90 string_predicate_t filter) { 91 CHECK(modules); 92 DlIteratePhdrData data = {modules, 0, true, max_modules, filter}; 93 dl_iterate_phdr(dl_iterate_phdr_cb, &data); 94 return data.current_n; 95 } 96 #endif // SANITIZER_ANDROID 97 98 } // namespace __sanitizer 99 100 #endif // SANITIZER_LINUX 101