diff options
author | Alexey Samsonov <samsonov@google.com> | 2013-03-13 06:51:02 +0000 |
---|---|---|
committer | Alexey Samsonov <samsonov@google.com> | 2013-03-13 06:51:02 +0000 |
commit | 45717c9d5e39a434749ae10509111f9df1b2cdf4 (patch) | |
tree | 21356f373baa2d0aa2853f3c68f4faedc63d0a6a /lib/sanitizer_common | |
parent | af9297b9be5e8993326c87ed32e44a8d2a5d7598 (diff) |
[Sanitizer] Change MemoryMappingLayout methods to also report memory protection flags (for future use in leak checker). Patch by Sergey Matveev.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@176931 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common')
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux.cc | 31 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_mac.cc | 10 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_posix.cc | 5 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_procmaps.h | 17 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stacktrace.cc | 3 |
5 files changed, 48 insertions, 18 deletions
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc index 9b51d2c2e..3f32ecc54 100644 --- a/lib/sanitizer_common/sanitizer_linux.cc +++ b/lib/sanitizer_common/sanitizer_linux.cc @@ -184,7 +184,7 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, MemoryMappingLayout proc_maps; uptr start, end, offset; uptr prev_end = 0; - while (proc_maps.Next(&start, &end, &offset, 0, 0)) { + while (proc_maps.Next(&start, &end, &offset, 0, 0, /* protection */0)) { if ((uptr)&rl < end) break; prev_end = end; @@ -390,7 +390,8 @@ static bool IsDecimal(char c) { } bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset, - char filename[], uptr filename_size) { + char filename[], uptr filename_size, + uptr *protection) { char *last = proc_self_maps_.data + proc_self_maps_.len; if (current_ >= last) return false; uptr dummy; @@ -405,10 +406,22 @@ bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset, CHECK_EQ(*current_++, '-'); *end = ParseHex(¤t_); CHECK_EQ(*current_++, ' '); - CHECK(IsOnOf(*current_++, '-', 'r')); - CHECK(IsOnOf(*current_++, '-', 'w')); - CHECK(IsOnOf(*current_++, '-', 'x')); - CHECK(IsOnOf(*current_++, 's', 'p')); + uptr local_protection = 0; + CHECK(IsOnOf(*current_, '-', 'r')); + if (*current_++ == 'r') + local_protection |= kProtectionRead; + CHECK(IsOnOf(*current_, '-', 'w')); + if (*current_++ == 'w') + local_protection |= kProtectionWrite; + CHECK(IsOnOf(*current_, '-', 'x')); + if (*current_++ == 'x') + local_protection |= kProtectionExecute; + CHECK(IsOnOf(*current_, 's', 'p')); + if (*current_++ == 's') + local_protection |= kProtectionShared; + if (protection) { + *protection = local_protection; + } CHECK_EQ(*current_++, ' '); *offset = ParseHex(¤t_); CHECK_EQ(*current_++, ' '); @@ -438,8 +451,10 @@ bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset, // Gets the object name and the offset by walking MemoryMappingLayout. bool MemoryMappingLayout::GetObjectNameAndOffset(uptr addr, uptr *offset, char filename[], - uptr filename_size) { - return IterateForObjectNameAndOffset(addr, offset, filename, filename_size); + uptr filename_size, + uptr *protection) { + return IterateForObjectNameAndOffset(addr, offset, filename, filename_size, + protection); } bool SanitizerSetThreadName(const char *name) { diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc index 0f112203b..eb2a6b6d8 100644 --- a/lib/sanitizer_common/sanitizer_mac.cc +++ b/lib/sanitizer_common/sanitizer_mac.cc @@ -216,7 +216,9 @@ void MemoryMappingLayout::LoadFromCache() { template<u32 kLCSegment, typename SegmentCommand> bool MemoryMappingLayout::NextSegmentLoad( uptr *start, uptr *end, uptr *offset, - char filename[], uptr filename_size) { + char filename[], uptr filename_size, uptr *protection) { + if (protection) + UNIMPLEMENTED(); const char* lc = current_load_cmd_addr_; current_load_cmd_addr_ += ((const load_command *)lc)->cmdsize; if (((const load_command *)lc)->cmd == kLCSegment) { @@ -294,8 +296,10 @@ bool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset, bool MemoryMappingLayout::GetObjectNameAndOffset(uptr addr, uptr *offset, char filename[], - uptr filename_size) { - return IterateForObjectNameAndOffset(addr, offset, filename, filename_size); + uptr filename_size + uptr *protection) { + return IterateForObjectNameAndOffset(addr, offset, filename, filename_size, + protection); } BlockingMutex::BlockingMutex(LinkerInitialized) { diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cc index 773f376a3..27f0977b5 100644 --- a/lib/sanitizer_common/sanitizer_posix.cc +++ b/lib/sanitizer_common/sanitizer_posix.cc @@ -152,7 +152,8 @@ bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) { MemoryMappingLayout procmaps; uptr start, end; while (procmaps.Next(&start, &end, - /*offset*/0, /*filename*/0, /*filename_size*/0)) { + /*offset*/0, /*filename*/0, /*filename_size*/0, + /*protection*/0)) { if (!IntervalsAreSeparate(start, end, range_start, range_end)) return false; } @@ -166,7 +167,7 @@ void DumpProcessMap() { char *filename = (char*)MmapOrDie(kBufSize, __FUNCTION__); Report("Process memory map follows:\n"); while (proc_maps.Next(&start, &end, /* file_offset */0, - filename, kBufSize)) { + filename, kBufSize, /* protection */0)) { Printf("\t%p-%p\t%s\n", (void*)start, (void*)end, filename); } Report("End of process memory map.\n"); diff --git a/lib/sanitizer_common/sanitizer_procmaps.h b/lib/sanitizer_common/sanitizer_procmaps.h index 1b8ea7aff..1b6151527 100644 --- a/lib/sanitizer_common/sanitizer_procmaps.h +++ b/lib/sanitizer_common/sanitizer_procmaps.h @@ -42,28 +42,37 @@ class MemoryMappingLayout { public: MemoryMappingLayout(); bool Next(uptr *start, uptr *end, uptr *offset, - char filename[], uptr filename_size); + char filename[], uptr filename_size, uptr *protection); void Reset(); // Gets the object file name and the offset in that object for a given // address 'addr'. Returns true on success. bool GetObjectNameAndOffset(uptr addr, uptr *offset, - char filename[], uptr filename_size); + char filename[], uptr filename_size, + uptr *protection); // In some cases, e.g. when running under a sandbox on Linux, ASan is unable // to obtain the memory mappings. It should fall back to pre-cached data // instead of aborting. static void CacheMemoryMappings(); ~MemoryMappingLayout(); + // Memory protection masks. + static const uptr kProtectionRead = 1; + static const uptr kProtectionWrite = 2; + static const uptr kProtectionExecute = 4; + static const uptr kProtectionShared = 8; + private: void LoadFromCache(); // Default implementation of GetObjectNameAndOffset. // Quite slow, because it iterates through the whole process map for each // lookup. bool IterateForObjectNameAndOffset(uptr addr, uptr *offset, - char filename[], uptr filename_size) { + char filename[], uptr filename_size, + uptr *protection) { Reset(); uptr start, end, file_offset; - for (int i = 0; Next(&start, &end, &file_offset, filename, filename_size); + for (int i = 0; Next(&start, &end, &file_offset, filename, filename_size, + protection); i++) { if (addr >= start && addr < end) { // Don't subtract 'start' for the first entry: diff --git a/lib/sanitizer_common/sanitizer_stacktrace.cc b/lib/sanitizer_common/sanitizer_stacktrace.cc index 6309b23cc..1b3a1f5bc 100644 --- a/lib/sanitizer_common/sanitizer_stacktrace.cc +++ b/lib/sanitizer_common/sanitizer_stacktrace.cc @@ -113,7 +113,8 @@ void StackTrace::PrintStack(const uptr *addr, uptr size, PrintStackFramePrefix(frame_num, pc); uptr offset; if (proc_maps.GetObjectNameAndOffset(pc, &offset, - buff.data(), buff.size())) { + buff.data(), buff.size(), + /* protection */0)) { PrintModuleAndOffset(buff.data(), offset, strip_file_prefix); } Printf("\n"); |