2013-05-21 20:08:37 +08:00
|
|
|
//===-- sanitizer_symbolizer_linux_libcdep.cc -----------------------------===//
|
2012-08-14 21:00:32 +08:00
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2013-03-19 22:33:38 +08:00
|
|
|
|
|
|
|
#include "sanitizer_platform.h"
|
|
|
|
#if SANITIZER_LINUX
|
2012-08-14 21:00:32 +08:00
|
|
|
#include "sanitizer_common.h"
|
|
|
|
#include "sanitizer_internal_defs.h"
|
2012-08-23 15:32:06 +08:00
|
|
|
#include "sanitizer_libc.h"
|
2013-05-29 20:11:43 +08:00
|
|
|
#include "sanitizer_linux.h"
|
2012-08-14 21:00:32 +08:00
|
|
|
#include "sanitizer_placement_new.h"
|
|
|
|
#include "sanitizer_symbolizer.h"
|
|
|
|
|
2013-05-17 23:22:32 +08:00
|
|
|
// Android NDK r8e elf.h depends on stdint.h without including the latter.
|
|
|
|
#include <stdint.h>
|
|
|
|
|
2012-08-14 21:00:32 +08:00
|
|
|
#include <elf.h>
|
2012-08-23 15:32:06 +08:00
|
|
|
#include <errno.h>
|
|
|
|
#include <poll.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/types.h>
|
2012-11-09 22:45:30 +08:00
|
|
|
#include <sys/wait.h>
|
2012-08-14 21:00:32 +08:00
|
|
|
#include <unistd.h>
|
|
|
|
|
2013-04-03 15:24:35 +08:00
|
|
|
#if !SANITIZER_ANDROID
|
2012-08-27 19:15:55 +08:00
|
|
|
#include <link.h>
|
|
|
|
#endif
|
|
|
|
|
2012-08-14 21:00:32 +08:00
|
|
|
namespace __sanitizer {
|
|
|
|
|
2013-04-03 15:24:35 +08:00
|
|
|
#if SANITIZER_ANDROID
|
2013-05-14 23:22:39 +08:00
|
|
|
uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
|
|
|
|
string_predicate_t filter) {
|
2013-05-16 21:04:29 +08:00
|
|
|
return 0;
|
2012-08-14 21:00:32 +08:00
|
|
|
}
|
2013-04-03 15:24:35 +08:00
|
|
|
#else // SANITIZER_ANDROID
|
2012-08-23 15:32:06 +08:00
|
|
|
typedef ElfW(Phdr) Elf_Phdr;
|
|
|
|
|
2012-08-14 21:00:32 +08:00
|
|
|
struct DlIteratePhdrData {
|
2012-08-23 15:32:06 +08:00
|
|
|
LoadedModule *modules;
|
2012-08-14 21:00:32 +08:00
|
|
|
uptr current_n;
|
2013-05-14 22:48:58 +08:00
|
|
|
bool first;
|
2012-08-14 21:00:32 +08:00
|
|
|
uptr max_n;
|
2013-05-14 22:04:06 +08:00
|
|
|
string_predicate_t filter;
|
2012-08-14 21:00:32 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
2012-08-31 19:07:52 +08:00
|
|
|
InternalScopedBuffer<char> module_name(kMaxPathLength);
|
2012-08-31 19:43:01 +08:00
|
|
|
module_name.data()[0] = '\0';
|
2013-05-14 22:48:58 +08:00
|
|
|
if (data->first) {
|
|
|
|
data->first = false;
|
2012-08-14 21:00:32 +08:00
|
|
|
// First module is the binary itself.
|
2013-05-23 19:53:36 +08:00
|
|
|
ReadBinaryName(module_name.data(), module_name.size());
|
2012-08-14 21:00:32 +08:00
|
|
|
} else if (info->dlpi_name) {
|
2012-09-05 15:23:44 +08:00
|
|
|
internal_strncpy(module_name.data(), info->dlpi_name, module_name.size());
|
2012-08-14 21:00:32 +08:00
|
|
|
}
|
2012-08-31 19:43:01 +08:00
|
|
|
if (module_name.data()[0] == '\0')
|
2012-08-14 21:00:32 +08:00
|
|
|
return 0;
|
2013-05-14 22:04:06 +08:00
|
|
|
if (data->filter && !data->filter(module_name.data()))
|
|
|
|
return 0;
|
2012-08-14 21:00:32 +08:00
|
|
|
void *mem = &data->modules[data->current_n];
|
2012-09-05 15:23:44 +08:00
|
|
|
LoadedModule *cur_module = new(mem) LoadedModule(module_name.data(),
|
2012-08-23 15:32:06 +08:00
|
|
|
info->dlpi_addr);
|
2012-08-14 21:00:32 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2013-05-14 22:04:06 +08:00
|
|
|
uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
|
|
|
|
string_predicate_t filter) {
|
2012-08-14 21:00:32 +08:00
|
|
|
CHECK(modules);
|
2013-05-14 22:48:58 +08:00
|
|
|
DlIteratePhdrData data = {modules, 0, true, max_modules, filter};
|
2012-08-14 21:00:32 +08:00
|
|
|
dl_iterate_phdr(dl_iterate_phdr_cb, &data);
|
|
|
|
return data.current_n;
|
|
|
|
}
|
2013-04-03 15:24:35 +08:00
|
|
|
#endif // SANITIZER_ANDROID
|
2012-08-14 21:00:32 +08:00
|
|
|
|
|
|
|
} // namespace __sanitizer
|
|
|
|
|
2013-04-03 15:24:35 +08:00
|
|
|
#endif // SANITIZER_LINUX
|