diff options
author | Francis Ricci <francisjricci@gmail.com> | 2017-07-20 18:06:02 +0000 |
---|---|---|
committer | Francis Ricci <francisjricci@gmail.com> | 2017-07-20 18:06:02 +0000 |
commit | 35ad307c385e384f47a7fb348c14b3602d3a33c4 (patch) | |
tree | d6766a5c5d142f1de4be79731bfba3675a3631d9 /lib/sanitizer_common/sanitizer_procmaps_mac.cc | |
parent | 3139224a27831570b278640087187155adc4fd05 (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.cc | 47 |
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); } } |