[compiler-rt] r308977 - Add address ranges for individual macho sections on darwin

Francis Ricci via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 25 08:27:32 PDT 2017


Author: fjricci
Date: Tue Jul 25 08:27:32 2017
New Revision: 308977

URL: http://llvm.org/viewvc/llvm-project?rev=308977&view=rev
Log:
Add address ranges for individual macho sections on darwin

Summary:
This is a re-upload of the reverted commit r308644. It has changed quite
a bit to reflect post-commit comments by kcc, so I'm re-uploading as
a new review.

Reviewers: kubamracek, alekseyshl, kcc

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D35799

Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_mac.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h?rev=308977&r1=308976&r2=308977&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps.h Tue Jul 25 08:27:32 2017
@@ -37,9 +37,12 @@ static const uptr kProtectionWrite = 2;
 static const uptr kProtectionExecute = 4;
 static const uptr kProtectionShared = 8;
 
-struct MemoryMappedSegment {
+struct MemoryMappedSegmentData;
+
+class MemoryMappedSegment {
+ public:
   MemoryMappedSegment(char *buff = nullptr, uptr size = 0)
-      : filename(buff), filename_size(size) {}
+      : filename(buff), filename_size(size), data_(nullptr) {}
   ~MemoryMappedSegment() {}
 
   bool IsReadable() const { return protection & kProtectionRead; }
@@ -47,6 +50,8 @@ struct MemoryMappedSegment {
   bool IsExecutable() const { return protection & kProtectionExecute; }
   bool IsShared() const { return protection & kProtectionShared; }
 
+  void AddAddressRanges(LoadedModule *module);
+
   uptr start;
   uptr end;
   uptr offset;
@@ -55,6 +60,12 @@ struct MemoryMappedSegment {
   uptr protection;
   ModuleArch arch;
   u8 uuid[kModuleUUIDSize];
+
+ private:
+  friend class MemoryMappingLayout;
+
+  // This field is assigned and owned by MemoryMappingLayout if needed
+  MemoryMappedSegmentData *data_;
 };
 
 class MemoryMappingLayout {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc?rev=308977&r1=308976&r2=308977&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_common.cc Tue Jul 25 08:27:32 2017
@@ -64,6 +64,10 @@ uptr ParseHex(const char **p) {
   return ParseNumber(p, 16);
 }
 
+void MemoryMappedSegment::AddAddressRanges(LoadedModule *module) {
+  module->addAddressRange(start, end, IsExecutable(), IsWritable());
+}
+
 MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) {
   ReadProcMaps(&proc_self_maps_);
   if (cache_enabled) {
@@ -139,8 +143,7 @@ void MemoryMappingLayout::DumpListOfModu
     uptr base_address = (i ? segment.start : 0) - segment.offset;
     LoadedModule cur_module;
     cur_module.set(cur_name, base_address);
-    cur_module.addAddressRange(segment.start, segment.end,
-                               segment.IsExecutable(), segment.IsWritable());
+    segment.AddAddressRanges(&cur_module);
     modules->push_back(cur_module);
   }
 }

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_mac.cc?rev=308977&r1=308976&r2=308977&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_mac.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_procmaps_mac.cc Tue Jul 25 08:27:32 2017
@@ -36,6 +36,48 @@
 
 namespace __sanitizer {
 
+// Contains information used to iterate through sections.
+struct MemoryMappedSegmentData {
+  uptr nsects;
+  char *current_load_cmd_addr;
+  u32 lc_type;
+  uptr base_virt_addr;
+  uptr addr_mask;
+};
+
+template <typename Section>
+static void NextSectionLoad(LoadedModule *module, MemoryMappedSegmentData *data,
+                            bool isWritable) {
+  const Section *sc = (const Section *)data->current_load_cmd_addr;
+  data->current_load_cmd_addr += sizeof(Section);
+
+  uptr sec_start = (sc->addr & data->addr_mask) + data->base_virt_addr;
+  uptr sec_end = sec_start + sc->size;
+  module->addAddressRange(sec_start, sec_end, /*executable=*/false, isWritable);
+}
+
+void MemoryMappedSegment::AddAddressRanges(LoadedModule *module) {
+  // Don't iterate over sections when the caller hasn't set up the
+  // data pointer, when there are no sections, or when the segment
+  // is executable. Avoid iterating over executable sections because
+  // it will confuse libignore, and because the extra granularity
+  // of information is not needed by any sanitizers.
+  if (!data_ || !data_->nsects || IsExecutable()) {
+    module->addAddressRange(start, end, IsExecutable(), IsWritable());
+    return;
+  }
+
+  do {
+    if (data_->lc_type == LC_SEGMENT) {
+      NextSectionLoad<struct section>(module, data_, IsWritable());
+#ifdef MH_MAGIC_64
+    } else if (data_->lc_type == LC_SEGMENT_64) {
+      NextSectionLoad<struct section_64>(module, data_, IsWritable());
+#endif
+    }
+  } while (--data_->nsects);
+}
+
 MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) {
   Reset();
 }
@@ -144,19 +186,32 @@ bool MemoryMappingLayout::NextSegmentLoa
   if (((const load_command *)lc)->cmd == kLCSegment) {
     const SegmentCommand* sc = (const SegmentCommand *)lc;
 
+    uptr base_virt_addr, addr_mask;
     if (current_image_ == kDyldImageIdx) {
+      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();
+      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;
+      base_virt_addr = (uptr)_dyld_get_image_vmaddr_slide(current_image_);
+      addr_mask = ~0;
+    }
+    segment->start = (sc->vmaddr & addr_mask) + base_virt_addr;
+    segment->end = segment->start + sc->vmsize;
+
+    // Most callers don't need section information, so only fill this struct
+    // when required.
+    if (segment->data_) {
+      segment->data_->nsects = sc->nsects;
+      segment->data_->current_load_cmd_addr =
+          (char *)lc + sizeof(SegmentCommand);
+      segment->data_->lc_type = kLCSegment;
+      segment->data_->base_virt_addr = base_virt_addr;
+      segment->data_->addr_mask = addr_mask;
     }
 
     // Return the initial protection.
@@ -292,7 +347,9 @@ void MemoryMappingLayout::DumpListOfModu
   Reset();
   InternalScopedString module_name(kMaxPathLength);
   MemoryMappedSegment segment(module_name.data(), kMaxPathLength);
-  for (uptr i = 0; Next(&segment); i++) {
+  MemoryMappedSegmentData data;
+  segment.data_ = &data;
+  while (Next(&segment)) {
     if (segment.filename[0] == '\0') continue;
     LoadedModule *cur_module = nullptr;
     if (!modules->empty() &&
@@ -304,8 +361,7 @@ void MemoryMappingLayout::DumpListOfModu
       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);
   }
 }
 




More information about the llvm-commits mailing list