diff options
author | Alexey Samsonov <samsonov@google.com> | 2013-12-25 08:39:38 +0000 |
---|---|---|
committer | Alexey Samsonov <samsonov@google.com> | 2013-12-25 08:39:38 +0000 |
commit | 64ffa598ce21a0df5fc94220844fe11614407fd8 (patch) | |
tree | aad1ff8afc25e1311b645ce5c064fcfc82ddd629 | |
parent | 2f392d237ca586fb510c51bf3511a83ad8fe3306 (diff) | |
download | bcm5719-llvm-64ffa598ce21a0df5fc94220844fe11614407fd8.tar.gz bcm5719-llvm-64ffa598ce21a0df5fc94220844fe11614407fd8.zip |
[Sanitizer] Teach MemoryMappingLayout to dump all loaded modules.
Use this to implement GetListOfModules() on Mac and on Android
(on Linux we use dl_iterate_phdr).
llvm-svn: 198004
6 files changed, 67 insertions, 32 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc index 29d9ce57caf..cd256e913c8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -299,7 +299,8 @@ void AdjustStackSizeLinux(void *attr_) { #if SANITIZER_ANDROID uptr GetListOfModules(LoadedModule *modules, uptr max_modules, string_predicate_t filter) { - return 0; + MemoryMappingLayout memory_mapping(false); + return memory_mapping.DumpListOfModules(modules, max_modules, filter); } #else // SANITIZER_ANDROID typedef ElfW(Phdr) Elf_Phdr; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc index 4f5366b7ddf..3cc3a6b5b9e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc @@ -235,32 +235,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, uptr GetListOfModules(LoadedModule *modules, uptr max_modules, string_predicate_t filter) { MemoryMappingLayout memory_mapping(false); - memory_mapping.Reset(); - uptr cur_beg, cur_end, cur_offset; - InternalScopedBuffer<char> module_name(kMaxPathLength); - uptr n_modules = 0; - for (uptr i = 0; - n_modules < max_modules && - memory_mapping.Next(&cur_beg, &cur_end, &cur_offset, - module_name.data(), module_name.size(), 0); - i++) { - const char *cur_name = module_name.data(); - if (cur_name[0] == '\0') - continue; - if (filter && !filter(cur_name)) - continue; - LoadedModule *cur_module = 0; - if (n_modules > 0 && - 0 == internal_strcmp(cur_name, modules[n_modules - 1].full_name())) { - cur_module = &modules[n_modules - 1]; - } else { - void *mem = &modules[n_modules]; - cur_module = new(mem) LoadedModule(cur_name, cur_beg); - n_modules++; - } - cur_module->addAddressRange(cur_beg, cur_end); - } - return n_modules; + return memory_mapping.DumpListOfModules(modules, max_modules, filter); } } // namespace __sanitizer diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h index 7468d6588d0..73abc5aa937 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h @@ -14,6 +14,7 @@ #ifndef SANITIZER_PROCMAPS_H #define SANITIZER_PROCMAPS_H +#include "sanitizer_common.h" #include "sanitizer_internal_defs.h" #include "sanitizer_mutex.h" @@ -44,6 +45,7 @@ struct ProcSelfMapsBuff { class MemoryMappingLayout { public: explicit MemoryMappingLayout(bool cache_enabled); + ~MemoryMappingLayout(); bool Next(uptr *start, uptr *end, uptr *offset, char filename[], uptr filename_size, uptr *protection); void Reset(); @@ -56,7 +58,10 @@ class MemoryMappingLayout { // to obtain the memory mappings. It should fall back to pre-cached data // instead of aborting. static void CacheMemoryMappings(); - ~MemoryMappingLayout(); + + // Stores the list of mapped objects into an array. + uptr DumpListOfModules(LoadedModule *modules, uptr max_modules, + string_predicate_t filter); // Memory protection masks. static const uptr kProtectionRead = 1; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_posix.cc b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_posix.cc index 941673bf01d..ebdf861cae7 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_posix.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_posix.cc @@ -12,6 +12,8 @@ #include "sanitizer_platform.h" #if SANITIZER_POSIX +#include "sanitizer_common.h" +#include "sanitizer_placement_new.h" #include "sanitizer_procmaps.h" namespace __sanitizer { @@ -46,6 +48,36 @@ bool MemoryMappingLayout::IterateForObjectNameAndOffset(uptr addr, uptr *offset, return false; } +uptr MemoryMappingLayout::DumpListOfModules(LoadedModule *modules, + uptr max_modules, + string_predicate_t filter) { + Reset(); + uptr cur_beg, cur_end, cur_offset; + InternalScopedBuffer<char> module_name(kMaxPathLength); + uptr n_modules = 0; + for (uptr i = 0; n_modules < max_modules && + Next(&cur_beg, &cur_end, &cur_offset, module_name.data(), + module_name.size(), 0); + i++) { + const char *cur_name = module_name.data(); + if (cur_name[0] == '\0') + continue; + if (filter && !filter(cur_name)) + continue; + LoadedModule *cur_module = 0; + if (n_modules > 0 && + 0 == internal_strcmp(cur_name, modules[n_modules - 1].full_name())) { + cur_module = &modules[n_modules - 1]; + } else { + void *mem = &modules[n_modules]; + cur_module = new(mem) LoadedModule(cur_name, cur_beg); + n_modules++; + } + cur_module->addAddressRange(cur_beg, cur_end); + } + return n_modules; +} + } // namespace __sanitizer #endif // SANITIZER_POSIX diff --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt index 5b66917b05b..435ed79de31 100644 --- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt @@ -13,6 +13,7 @@ set(SANITIZER_UNITTESTS sanitizer_nolibc_test.cc sanitizer_posix_test.cc sanitizer_printf_test.cc + sanitizer_procmaps_test.cc sanitizer_scanf_interceptor_test.cc sanitizer_stackdepot_test.cc sanitizer_stacktrace_test.cc diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc index d16e2eebf98..516b77802ff 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc @@ -11,20 +11,41 @@ // //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_procmaps.h" -//#include "sanitizer_common/sanitizer_internal_defs.h" -//#include "sanitizer_common/sanitizer_libc.h" #include "gtest/gtest.h" +#include <stdlib.h> + namespace __sanitizer { #ifdef SANITIZER_LINUX -TEST(ProcMaps, CodeRange) { +TEST(MemoryMappingLayout, CodeRange) { uptr start, end; bool res = GetCodeRangeForFile("[vdso]", &start, &end); EXPECT_EQ(res, true); - EXPECT_GT(start, (uptr)0); + EXPECT_GT(start, 0U); EXPECT_LT(start, end); } #endif +static void noop() {} + +TEST(MemoryMappingLayout, DumpListOfModules) { + MemoryMappingLayout memory_mapping(false); + const uptr kMaxModules = 10; + LoadedModule *modules = + (LoadedModule *)malloc(kMaxModules * sizeof(LoadedModule)); + uptr n_modules = memory_mapping.DumpListOfModules(modules, kMaxModules, 0); + EXPECT_GT(n_modules, 0U); + bool found = false; + for (uptr i = 0; i < n_modules; ++i) { + if (modules[i].containsAddress((uptr)&noop)) { + // Verify that the module name is sane. + if (strstr(modules[i].full_name(), "Sanitizer") != 0) + found = true; + } + } + EXPECT_TRUE(found); + free(modules); +} + } // namespace __sanitizer |