Home | History | Annotate | Download | only in sanitizer_common
      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