Index: lib/sanitizer_common/sanitizer_procmaps.h =================================================================== --- lib/sanitizer_common/sanitizer_procmaps.h +++ lib/sanitizer_common/sanitizer_procmaps.h @@ -37,11 +37,20 @@ static const uptr kProtectionExecute = 4; static const uptr kProtectionShared = 8; -struct MemoryMappedSegment { +struct MemoryMappedSection { + uptr start; + uptr end; + uptr offset; +}; + +class MemoryMappedSegment { + public: MemoryMappedSegment(char *buff = nullptr, uptr size = 0) : filename(buff), filename_size(size) {} ~MemoryMappedSegment() {} + bool Next(MemoryMappedSection *section); + bool IsReadable() { return protection & kProtectionRead; } bool IsWritable() { return protection & kProtectionWrite; } bool IsExecutable() { return protection & kProtectionExecute; } @@ -55,6 +64,7 @@ uptr protection; ModuleArch arch; u8 uuid[kModuleUUIDSize]; + bool has_sections; }; class MemoryMappingLayout { Index: lib/sanitizer_common/sanitizer_procmaps_common.cc =================================================================== --- lib/sanitizer_common/sanitizer_procmaps_common.cc +++ lib/sanitizer_common/sanitizer_procmaps_common.cc @@ -64,6 +64,11 @@ return ParseNumber(p, 16); } +// No linux or freebsd segments contain sections +MemoryMappedSegment::Next(MemoryMappedSection *section) { + return false; +} + MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) { ReadProcMaps(&proc_self_maps_); if (cache_enabled) { Index: lib/sanitizer_common/sanitizer_procmaps_freebsd.cc =================================================================== --- lib/sanitizer_common/sanitizer_procmaps_freebsd.cc +++ lib/sanitizer_common/sanitizer_procmaps_freebsd.cc @@ -70,6 +70,7 @@ Min(segment->filename_size, (uptr)PATH_MAX), "%s", VmEntry->kve_path); } + segment->has_sections = false; current_ += VmEntry->kve_structsize; Index: lib/sanitizer_common/sanitizer_procmaps_linux.cc =================================================================== --- lib/sanitizer_common/sanitizer_procmaps_linux.cc +++ lib/sanitizer_common/sanitizer_procmaps_linux.cc @@ -67,6 +67,7 @@ internal_strncpy(segment->filename, current_, len); segment->filename[len] = 0; } + segment->has_sections = false; current_ = next_line + 1; return true; Index: lib/sanitizer_common/sanitizer_procmaps_mac.cc =================================================================== --- lib/sanitizer_common/sanitizer_procmaps_mac.cc +++ lib/sanitizer_common/sanitizer_procmaps_mac.cc @@ -35,6 +35,9 @@ #endif namespace __sanitizer { +bool MemoryMappedSegment::Next(MemoryMappedSection *section) { + return false; +} MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) { Reset(); @@ -143,6 +146,7 @@ current_load_cmd_addr_ += ((const load_command *)lc)->cmdsize; if (((const load_command *)lc)->cmd == kLCSegment) { const SegmentCommand* sc = (const SegmentCommand *)lc; + segment->has_sections = false; if (current_image_ == kDyldImageIdx) { // vmaddr is masked with 0xfffff because on macOS versions < 10.12, @@ -292,7 +296,8 @@ Reset(); InternalScopedString module_name(kMaxPathLength); MemoryMappedSegment segment(module_name.data(), kMaxPathLength); - for (uptr i = 0; Next(&segment); i++) { + MemoryMappedSection section; + while (Next(&segment)) { if (segment.filename[0] == '\0') continue; LoadedModule *cur_module = nullptr; if (!modules->empty() && @@ -304,8 +309,15 @@ cur_module->set(segment.filename, segment.start, segment.arch, segment.uuid, current_instrumented_); } - cur_module->addAddressRange(segment.start, segment.end, - segment.IsExecutable(), segment.IsWritable()); + if (!segment.has_sections) { + cur_module->addAddressRange(segment.start, segment.end, + segment.IsExecutable(), segment.IsWritable()); + continue; + } + while (segment.Next(§ion)) { + cur_module->addAddressRange(section.start, section.end, + segment.IsExecutable(), segment.IsWritable()); + } } }