Skip to content

Commit

Permalink
Add MemoryMappedSection struct for two-level memory map iteration
Browse files Browse the repository at this point in the history
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

llvm-svn: 308210
  • Loading branch information
fjricci committed Jul 17, 2017
1 parent d1daa95 commit 455ba3f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 9 deletions.
18 changes: 17 additions & 1 deletion compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h
Expand Up @@ -37,7 +37,8 @@ static const uptr kProtectionWrite = 2;
static const uptr kProtectionExecute = 4;
static const uptr kProtectionShared = 8;

struct MemoryMappedSegment {
class MemoryMappedSegment {
public:
MemoryMappedSegment(char *buff = nullptr, uptr size = 0)
: filename(buff), filename_size(size) {}
~MemoryMappedSegment() {}
Expand All @@ -55,6 +56,21 @@ struct MemoryMappedSegment {
uptr protection;
ModuleArch arch;
u8 uuid[kModuleUUIDSize];

#if SANITIZER_MAC

private:
friend class MemoryMappingLayout;

template <typename Section>
void NextSectionLoad(LoadedModule *module);
void AddAddressRanges(LoadedModule *module);

uptr nsects_;
char *current_load_cmd_addr_;
u32 lc_type_;
uptr base_virt_addr_;
#endif
};

class MemoryMappingLayout {
Expand Down
45 changes: 37 additions & 8 deletions compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cc
Expand Up @@ -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 + 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();
Expand Down Expand Up @@ -143,21 +169,25 @@ 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->start = (sc->vmaddr & 0xfffff) + segment->base_virt_addr_;
} 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->start = sc->vmaddr + segment->base_virt_addr_;
}
segment->end = segment->start + sc->vmsize;

// Return the initial protection.
segment->protection = sc->initprot;
Expand Down Expand Up @@ -292,7 +322,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() &&
Expand All @@ -304,8 +334,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);
}
}

Expand Down

0 comments on commit 455ba3f

Please sign in to comment.