forked from OSchip/llvm-project
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
This commit is contained in:
parent
52dd808bc3
commit
9058c07c95
|
@ -31,8 +31,6 @@
|
||||||
#define MEM_IS_SHADOW(mem) ((uptr)mem >= 0x200000000000ULL && \
|
#define MEM_IS_SHADOW(mem) ((uptr)mem >= 0x200000000000ULL && \
|
||||||
(uptr)mem <= 0x400000000000ULL)
|
(uptr)mem <= 0x400000000000ULL)
|
||||||
|
|
||||||
struct link_map; // Opaque type returned by dlopen().
|
|
||||||
|
|
||||||
const int kMsanParamTlsSizeInWords = 100;
|
const int kMsanParamTlsSizeInWords = 100;
|
||||||
const int kMsanRetvalTlsSizeInWords = 100;
|
const int kMsanRetvalTlsSizeInWords = 100;
|
||||||
|
|
||||||
|
@ -76,7 +74,6 @@ void ReportUMR(StackTrace *stack, u32 origin);
|
||||||
void ReportExpectedUMRNotFound(StackTrace *stack);
|
void ReportExpectedUMRNotFound(StackTrace *stack);
|
||||||
void ReportAtExitStatistics();
|
void ReportAtExitStatistics();
|
||||||
|
|
||||||
void UnpoisonMappedDSO(struct link_map *map);
|
|
||||||
// Unpoison first n function arguments.
|
// Unpoison first n function arguments.
|
||||||
void UnpoisonParam(uptr n);
|
void UnpoisonParam(uptr n);
|
||||||
|
|
||||||
|
|
|
@ -827,7 +827,7 @@ INTERCEPTOR(void *, dlopen, const char *filename, int flag) {
|
||||||
if (!__msan_has_dynamic_component() && map) {
|
if (!__msan_has_dynamic_component() && map) {
|
||||||
// If msandr didn't clear the shadow before the initializers ran, we do it
|
// If msandr didn't clear the shadow before the initializers ran, we do it
|
||||||
// ourselves afterwards.
|
// ourselves afterwards.
|
||||||
UnpoisonMappedDSO(map);
|
ForEachMappedRegion(map, __msan_unpoison);
|
||||||
}
|
}
|
||||||
return (void *)map;
|
return (void *)map;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
#include "msan.h"
|
#include "msan.h"
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
#include <link.h>
|
#include <link.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -92,41 +91,6 @@ void InstallAtExitHandler() {
|
||||||
atexit(MsanAtExit);
|
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
|
} // namespace __msan
|
||||||
|
|
||||||
#endif // __linux__
|
#endif // __linux__
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <link.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
@ -638,6 +639,42 @@ bool LibraryNameIs(const char *full_name, const char *base_name) {
|
||||||
return (name[base_name_length] == '-' || name[base_name_length] == '.');
|
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
|
} // namespace __sanitizer
|
||||||
|
|
||||||
#endif // SANITIZER_LINUX
|
#endif // SANITIZER_LINUX
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "sanitizer_common.h"
|
#include "sanitizer_common.h"
|
||||||
#include "sanitizer_internal_defs.h"
|
#include "sanitizer_internal_defs.h"
|
||||||
|
|
||||||
|
struct link_map; // Opaque type returned by dlopen().
|
||||||
struct sigaltstack;
|
struct sigaltstack;
|
||||||
|
|
||||||
namespace __sanitizer {
|
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.
|
// Read the name of the current binary from /proc/self/exe.
|
||||||
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
|
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
|
} // namespace __sanitizer
|
||||||
|
|
||||||
#endif // SANITIZER_LINUX_H
|
#endif // SANITIZER_LINUX_H
|
||||||
|
|
Loading…
Reference in New Issue