From 9058c07c955e2fe564eb0d8bfcd15c6eaf9cbf7f Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Mon, 29 Jul 2013 19:09:49 +0000 Subject: [PATCH] Move UnpoisonMappedDSO to sanitizer_common. This is so DFSan will be able to use it. Differential Revision: http://llvm-reviews.chandlerc.com/D1206 llvm-svn: 187372 --- compiler-rt/lib/msan/msan.h | 3 -- compiler-rt/lib/msan/msan_interceptors.cc | 2 +- compiler-rt/lib/msan/msan_linux.cc | 36 ------------------ .../lib/sanitizer_common/sanitizer_linux.cc | 37 +++++++++++++++++++ .../lib/sanitizer_common/sanitizer_linux.h | 4 ++ 5 files changed, 42 insertions(+), 40 deletions(-) diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h index a7bd478c749a..1432d99bd945 100644 --- a/compiler-rt/lib/msan/msan.h +++ b/compiler-rt/lib/msan/msan.h @@ -31,8 +31,6 @@ #define MEM_IS_SHADOW(mem) ((uptr)mem >= 0x200000000000ULL && \ (uptr)mem <= 0x400000000000ULL) -struct link_map; // Opaque type returned by dlopen(). - const int kMsanParamTlsSizeInWords = 100; const int kMsanRetvalTlsSizeInWords = 100; @@ -76,7 +74,6 @@ void ReportUMR(StackTrace *stack, u32 origin); void ReportExpectedUMRNotFound(StackTrace *stack); void ReportAtExitStatistics(); -void UnpoisonMappedDSO(struct link_map *map); // Unpoison first n function arguments. void UnpoisonParam(uptr n); diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index a4c905ca65e5..ef706e69b1f0 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -827,7 +827,7 @@ INTERCEPTOR(void *, dlopen, const char *filename, int flag) { if (!__msan_has_dynamic_component() && map) { // If msandr didn't clear the shadow before the initializers ran, we do it // ourselves afterwards. - UnpoisonMappedDSO(map); + ForEachMappedRegion(map, __msan_unpoison); } return (void *)map; } diff --git a/compiler-rt/lib/msan/msan_linux.cc b/compiler-rt/lib/msan/msan_linux.cc index 367dc904d05d..b82ed8ce8ced 100644 --- a/compiler-rt/lib/msan/msan_linux.cc +++ b/compiler-rt/lib/msan/msan_linux.cc @@ -17,7 +17,6 @@ #include "msan.h" -#include #include #include #include @@ -92,41 +91,6 @@ void InstallAtExitHandler() { atexit(MsanAtExit); } -void UnpoisonMappedDSO(link_map *map) { - typedef ElfW(Phdr) Elf_Phdr; - typedef ElfW(Ehdr) Elf_Ehdr; - char *base = (char *)map->l_addr; - Elf_Ehdr *ehdr = (Elf_Ehdr *)base; - char *phdrs = base + ehdr->e_phoff; - char *phdrs_end = phdrs + ehdr->e_phnum * ehdr->e_phentsize; - - // Find the segment with the minimum base so we can "relocate" the p_vaddr - // fields. Typically ET_DYN objects (DSOs) have base of zero and ET_EXEC - // objects have a non-zero base. - uptr preferred_base = ~0ULL; - for (char *iter = phdrs; iter != phdrs_end; iter += ehdr->e_phentsize) { - Elf_Phdr *phdr = (Elf_Phdr *)iter; - if (phdr->p_type == PT_LOAD) - preferred_base = std::min(preferred_base, (uptr)phdr->p_vaddr); - } - - // Compute the delta from the real base to get a relocation delta. - sptr delta = (uptr)base - preferred_base; - // Now we can figure out what the loader really mapped. - for (char *iter = phdrs; iter != phdrs_end; iter += ehdr->e_phentsize) { - Elf_Phdr *phdr = (Elf_Phdr *)iter; - if (phdr->p_type == PT_LOAD) { - uptr seg_start = phdr->p_vaddr + delta; - uptr seg_end = seg_start + phdr->p_memsz; - // None of these values are aligned. We consider the ragged edges of the - // load command as defined, since they are mapped from the file. - seg_start = RoundDownTo(seg_start, GetPageSizeCached()); - seg_end = RoundUpTo(seg_end, GetPageSizeCached()); - __msan_unpoison((void *)seg_start, seg_end - seg_start); - } - } -} - } // namespace __msan #endif // __linux__ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc index bbc41f471bbb..4b6373661c73 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -638,6 +639,42 @@ bool LibraryNameIs(const char *full_name, const char *base_name) { return (name[base_name_length] == '-' || name[base_name_length] == '.'); } +// Call cb for each region mapped by map. +void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)) { + typedef ElfW(Phdr) Elf_Phdr; + typedef ElfW(Ehdr) Elf_Ehdr; + char *base = (char *)map->l_addr; + Elf_Ehdr *ehdr = (Elf_Ehdr *)base; + char *phdrs = base + ehdr->e_phoff; + char *phdrs_end = phdrs + ehdr->e_phnum * ehdr->e_phentsize; + + // Find the segment with the minimum base so we can "relocate" the p_vaddr + // fields. Typically ET_DYN objects (DSOs) have base of zero and ET_EXEC + // objects have a non-zero base. + uptr preferred_base = ~0ULL; + for (char *iter = phdrs; iter != phdrs_end; iter += ehdr->e_phentsize) { + Elf_Phdr *phdr = (Elf_Phdr *)iter; + if (phdr->p_type == PT_LOAD && preferred_base > (uptr)phdr->p_vaddr) + preferred_base = (uptr)phdr->p_vaddr; + } + + // Compute the delta from the real base to get a relocation delta. + sptr delta = (uptr)base - preferred_base; + // Now we can figure out what the loader really mapped. + for (char *iter = phdrs; iter != phdrs_end; iter += ehdr->e_phentsize) { + Elf_Phdr *phdr = (Elf_Phdr *)iter; + if (phdr->p_type == PT_LOAD) { + uptr seg_start = phdr->p_vaddr + delta; + uptr seg_end = seg_start + phdr->p_memsz; + // None of these values are aligned. We consider the ragged edges of the + // load command as defined, since they are mapped from the file. + seg_start = RoundDownTo(seg_start, GetPageSizeCached()); + seg_end = RoundUpTo(seg_end, GetPageSizeCached()); + cb((void *)seg_start, seg_end - seg_start); + } + } +} + } // namespace __sanitizer #endif // SANITIZER_LINUX diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index 6992575732bc..edb95fecb8c5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -16,6 +16,7 @@ #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" +struct link_map; // Opaque type returned by dlopen(). struct sigaltstack; namespace __sanitizer { @@ -65,6 +66,9 @@ bool LibraryNameIs(const char *full_name, const char *base_name); // Read the name of the current binary from /proc/self/exe. uptr ReadBinaryName(/*out*/char *buf, uptr buf_len); +// Call cb for each region mapped by map. +void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)); + } // namespace __sanitizer #endif // SANITIZER_LINUX_H