summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2013-03-13 06:51:02 +0000
committerAlexey Samsonov <samsonov@google.com>2013-03-13 06:51:02 +0000
commit45717c9d5e39a434749ae10509111f9df1b2cdf4 (patch)
tree21356f373baa2d0aa2853f3c68f4faedc63d0a6a /lib/sanitizer_common
parentaf9297b9be5e8993326c87ed32e44a8d2a5d7598 (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.cc31
-rw-r--r--lib/sanitizer_common/sanitizer_mac.cc10
-rw-r--r--lib/sanitizer_common/sanitizer_posix.cc5
-rw-r--r--lib/sanitizer_common/sanitizer_procmaps.h17
-rw-r--r--lib/sanitizer_common/sanitizer_stacktrace.cc3
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(&current_);
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(&current_);
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");