//===-- sanitizer_symbolizer_linux_libcdep.cc -----------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file is shared between AddressSanitizer and ThreadSanitizer // run-time libraries. // Linux-specific implementation of symbolizer parts. //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" #if SANITIZER_LINUX #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" #include "sanitizer_libc.h" #include "sanitizer_linux.h" #include "sanitizer_placement_new.h" #include "sanitizer_symbolizer.h" // Android NDK r8e elf.h depends on stdint.h without including the latter. #include <stdint.h> #include <elf.h> #include <errno.h> #include <poll.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #if !SANITIZER_ANDROID #include <link.h> #endif namespace __sanitizer { #if SANITIZER_ANDROID uptr GetListOfModules(LoadedModule *modules, uptr max_modules, string_predicate_t filter) { return 0; } #else // SANITIZER_ANDROID typedef ElfW(Phdr) Elf_Phdr; struct DlIteratePhdrData { LoadedModule *modules; uptr current_n; bool first; uptr max_n; string_predicate_t filter; }; static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { DlIteratePhdrData *data = (DlIteratePhdrData*)arg; if (data->current_n == data->max_n) return 0; InternalScopedBuffer<char> module_name(kMaxPathLength); module_name.data()[0] = '\0'; if (data->first) { data->first = false; // First module is the binary itself. ReadBinaryName(module_name.data(), module_name.size()); } else if (info->dlpi_name) { internal_strncpy(module_name.data(), info->dlpi_name, module_name.size()); } if (module_name.data()[0] == '\0') return 0; if (data->filter && !data->filter(module_name.data())) return 0; void *mem = &data->modules[data->current_n]; LoadedModule *cur_module = new(mem) LoadedModule(module_name.data(), info->dlpi_addr); data->current_n++; for (int i = 0; i < info->dlpi_phnum; i++) { const Elf_Phdr *phdr = &info->dlpi_phdr[i]; if (phdr->p_type == PT_LOAD) { uptr cur_beg = info->dlpi_addr + phdr->p_vaddr; uptr cur_end = cur_beg + phdr->p_memsz; cur_module->addAddressRange(cur_beg, cur_end); } } return 0; } uptr GetListOfModules(LoadedModule *modules, uptr max_modules, string_predicate_t filter) { CHECK(modules); DlIteratePhdrData data = {modules, 0, true, max_modules, filter}; dl_iterate_phdr(dl_iterate_phdr_cb, &data); return data.current_n; } #endif // SANITIZER_ANDROID } // namespace __sanitizer #endif // SANITIZER_LINUX