summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_procmaps_mac.cc
diff options
context:
space:
mode:
authorFrancis Ricci <francisjricci@gmail.com>2017-07-20 18:06:02 +0000
committerFrancis Ricci <francisjricci@gmail.com>2017-07-20 18:06:02 +0000
commit35ad307c385e384f47a7fb348c14b3602d3a33c4 (patch)
treed6766a5c5d142f1de4be79731bfba3675a3631d9 /lib/sanitizer_common/sanitizer_procmaps_mac.cc
parent3139224a27831570b278640087187155adc4fd05 (diff)
Add MemoryMappedSection struct for two-level memory map iteration
Summary: This will allow sanitizer_procmaps on mac to expose section information. Reviewers: kubamracek, alekseyshl, kcc Subscribers: llvm-commits, emaste Differential Revision: https://reviews.llvm.org/D35422 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@308644 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_procmaps_mac.cc')
-rw-r--r--lib/sanitizer_common/sanitizer_procmaps_mac.cc47
1 files changed, 39 insertions, 8 deletions
diff --git a/lib/sanitizer_common/sanitizer_procmaps_mac.cc b/lib/sanitizer_common/sanitizer_procmaps_mac.cc
index 560451a16..65236da1a 100644
--- a/lib/sanitizer_common/sanitizer_procmaps_mac.cc
+++ b/lib/sanitizer_common/sanitizer_procmaps_mac.cc
@@ -35,6 +35,32 @@
#endif
namespace __sanitizer {
+template <typename Section>
+void MemoryMappedSegment::NextSectionLoad(LoadedModule *module) {
+ const Section *sc = (const Section *)current_load_cmd_addr_;
+ current_load_cmd_addr_ += sizeof(Section);
+
+ uptr sec_start = (sc->addr & addr_mask_) + base_virt_addr_;
+ uptr sec_end = sec_start + sc->size;
+ module->addAddressRange(sec_start, sec_end, IsExecutable(), IsWritable());
+}
+
+void MemoryMappedSegment::AddAddressRanges(LoadedModule *module) {
+ if (!nsects_) {
+ module->addAddressRange(start, end, IsExecutable(), IsWritable());
+ return;
+ }
+
+ do {
+ if (lc_type_ == LC_SEGMENT) {
+ NextSectionLoad<struct section>(module);
+#ifdef MH_MAGIC_64
+ } else if (lc_type_ == LC_SEGMENT_64) {
+ NextSectionLoad<struct section_64>(module);
+#endif
+ }
+ } while (--nsects_);
+}
MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) {
Reset();
@@ -143,21 +169,27 @@ bool MemoryMappingLayout::NextSegmentLoad(MemoryMappedSegment *segment) {
current_load_cmd_addr_ += ((const load_command *)lc)->cmdsize;
if (((const load_command *)lc)->cmd == kLCSegment) {
const SegmentCommand* sc = (const SegmentCommand *)lc;
+ segment->current_load_cmd_addr_ = (char *)lc + sizeof(SegmentCommand);
+ segment->lc_type_ = kLCSegment;
+ segment->nsects_ = sc->nsects;
if (current_image_ == kDyldImageIdx) {
+ segment->base_virt_addr_ = (uptr)get_dyld_hdr();
// vmaddr is masked with 0xfffff because on macOS versions < 10.12,
// it contains an absolute address rather than an offset for dyld.
// To make matters even more complicated, this absolute address
// isn't actually the absolute segment address, but the offset portion
// of the address is accurate when combined with the dyld base address,
// and the mask will give just this offset.
- segment->start = (sc->vmaddr & 0xfffff) + (uptr)get_dyld_hdr();
- segment->end = (sc->vmaddr & 0xfffff) + sc->vmsize + (uptr)get_dyld_hdr();
+ segment->addr_mask_ = 0xfffff;
} else {
- const sptr dlloff = _dyld_get_image_vmaddr_slide(current_image_);
- segment->start = sc->vmaddr + dlloff;
- segment->end = sc->vmaddr + sc->vmsize + dlloff;
+ segment->base_virt_addr_ =
+ (uptr)_dyld_get_image_vmaddr_slide(current_image_);
+ segment->addr_mask_ = ~0;
}
+ segment->start =
+ (sc->vmaddr & segment->addr_mask_) + segment->base_virt_addr_;
+ segment->end = segment->start + sc->vmsize;
// Return the initial protection.
segment->protection = sc->initprot;
@@ -292,7 +324,7 @@ void MemoryMappingLayout::DumpListOfModules(
Reset();
InternalScopedString module_name(kMaxPathLength);
MemoryMappedSegment segment(module_name.data(), kMaxPathLength);
- for (uptr i = 0; Next(&segment); i++) {
+ while (Next(&segment)) {
if (segment.filename[0] == '\0') continue;
LoadedModule *cur_module = nullptr;
if (!modules->empty() &&
@@ -304,8 +336,7 @@ void MemoryMappingLayout::DumpListOfModules(
cur_module->set(segment.filename, segment.start, segment.arch,
segment.uuid, current_instrumented_);
}
- cur_module->addAddressRange(segment.start, segment.end,
- segment.IsExecutable(), segment.IsWritable());
+ segment.AddAddressRanges(cur_module);
}
}