diff --git a/llvm/include/llvm/DebugInfo/Symbolize/MarkupContext.h b/llvm/include/llvm/DebugInfo/Symbolize/MarkupContext.h
--- a/llvm/include/llvm/DebugInfo/Symbolize/MarkupContext.h
+++ b/llvm/include/llvm/DebugInfo/Symbolize/MarkupContext.h
@@ -8,7 +8,7 @@
 ///
 /// \file
 /// This file declares an object that represents a process context that relates
-/// virtual addresses to module addresses.
+/// addresses to module addresses.
 ///
 //===----------------------------------------------------------------------===//
 
@@ -30,7 +30,7 @@
 
 namespace symbolize {
 
-/// A process context that allows converting between virtual addresses and
+/// A process context that allows converting between addresses and
 /// module-relative addresses.
 class MarkupContext {
 public:
@@ -48,7 +48,9 @@
     uint64_t ModuleRelativeAddr;
 
     bool contains(uint64_t Addr) const;
-    uint64_t getModuleRelativeAddr(uint64_t Addr) const;
+    bool containsMRAddr(uint64_t MRAddr) const;
+    uint64_t toModuleRelativeAddr(uint64_t Addr) const;
+    uint64_t fromModuleRelativeAddr(uint64_t MRAddr) const;
   };
 
 private:
@@ -58,6 +60,9 @@
   // Ordered map from starting address to mmap.
   std::map<uint64_t, MMap> MMaps;
 
+  // Ordered map from starting module-relative address to mmap.
+  std::map<uint64_t, MMap *> MMapsByMRAddr;
+
 public:
   bool empty() const;
   void clear();
@@ -74,8 +79,13 @@
   /// Returns the MMap that contains the given address or nullptr if none.
   const MMap *getContainingMMap(uint64_t Addr) const;
 
+  /// Returns the MMap that contains the given module-relative address or
+  /// nullptr if none.
+  const MMap *getContainingMMapForMRAddr(uint64_t MRAddr) const;
+
 private:
   const MMap *getOverlappingMMap(const MMap &Map) const;
+  const MMap *getOverlappingMRAddrMMap(const MMap &Map) const;
 };
 
 } // end namespace symbolize
diff --git a/llvm/lib/DebugInfo/Symbolize/MarkupContext.cpp b/llvm/lib/DebugInfo/Symbolize/MarkupContext.cpp
--- a/llvm/lib/DebugInfo/Symbolize/MarkupContext.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/MarkupContext.cpp
@@ -40,6 +40,7 @@
 void MarkupContext::clear() {
   Modules.clear();
   MMaps.clear();
+  MMapsByMRAddr.clear();
 }
 
 void MarkupContext::dump(json::OStream &JOS) const {
@@ -89,7 +90,12 @@
   (void)Res;
   assert(Res.second &&
          "Overlap check should have ensured unique starting address.");
-  return {&Res.first->second, true};
+  auto ReverseRes =
+      MMapsByMRAddr.try_emplace(MM.ModuleRelativeAddr, &Res.first->second);
+  (void)ReverseRes;
+  assert(ReverseRes.second &&
+         "Overlap check should have ensured unique starting address.");
+  return {&Res.first->second, Res.second};
 }
 
 const MarkupContext::MMap *
@@ -106,6 +112,20 @@
   return I->second.contains(Addr) ? &I->second : nullptr;
 }
 
+const MarkupContext::MMap *
+MarkupContext::getContainingMMapForMRAddr(uint64_t MRAddr) const {
+  // Find the first mmap starting >= MRAddr.
+  auto I = MMapsByMRAddr.lower_bound(MRAddr);
+  if (I != MMapsByMRAddr.end() && I->second->containsMRAddr(MRAddr))
+    return I->second;
+
+  // The previous mmap is the last one starting < MRAddr.
+  if (I == MMapsByMRAddr.begin())
+    return nullptr;
+  --I;
+  return I->second->containsMRAddr(MRAddr) ? I->second : nullptr;
+}
+
 // Checks for an existing mmap that overlaps the given one and returns a pointer
 // to it. Checking for overlaps in insertMMap ensures the overlap is unique.
 const MarkupContext::MMap *
@@ -122,6 +142,24 @@
     if (I->second.contains(Map.Addr))
       return &I->second;
   }
+  return getOverlappingMRAddrMMap(Map);
+}
+
+const MarkupContext::MMap *
+MarkupContext::getOverlappingMRAddrMMap(const MMap &Map) const {
+  // If the given map contains the start of another mmap, they overlap.
+  auto I = MMapsByMRAddr.upper_bound(Map.ModuleRelativeAddr);
+  if (I != MMapsByMRAddr.end() &&
+      Map.containsMRAddr(I->second->ModuleRelativeAddr))
+    return I->second;
+
+  // If no element starts inside the given mmap, the only possible overlap would
+  // be if the preceding mmap contains the start point of the given mmap.
+  if (I != MMapsByMRAddr.begin()) {
+    --I;
+    if (I->second->containsMRAddr(Map.ModuleRelativeAddr))
+      return I->second;
+  }
   return nullptr;
 }
 
@@ -129,7 +167,15 @@
   return this->Addr <= Addr && Addr < this->Addr + Size;
 }
 
-// Returns the module-relative address for a given virtual address.
-uint64_t MarkupContext::MMap::getModuleRelativeAddr(uint64_t Addr) const {
+bool MarkupContext::MMap::containsMRAddr(uint64_t MRAddr) const {
+  return this->ModuleRelativeAddr <= MRAddr &&
+         MRAddr < this->ModuleRelativeAddr + Size;
+}
+
+uint64_t MarkupContext::MMap::toModuleRelativeAddr(uint64_t Addr) const {
   return Addr - this->Addr + ModuleRelativeAddr;
 }
+
+uint64_t MarkupContext::MMap::fromModuleRelativeAddr(uint64_t MRAddr) const {
+  return MRAddr - ModuleRelativeAddr + this->Addr;
+}
diff --git a/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp b/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp
--- a/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/MarkupFilter.cpp
@@ -117,7 +117,7 @@
     WithColor::error(errs())
         << formatv("overlapping mmap: #{0:x} [{1:x}-{2:x}]\n", MMap.Mod->ID,
                    MMap.Addr, MMap.Addr + MMap.Size - 1);
-    reportLocation(Node.Fields[0].begin());
+    reportLocation(Node.Text.begin());
     return true;
   }
 
@@ -290,7 +290,7 @@
   }
 
   Expected<DILineInfo> LI = Symbolizer.symbolizeCode(
-      MMap->Mod->BuildID, {MMap->getModuleRelativeAddr(*Addr)});
+      MMap->Mod->BuildID, {MMap->toModuleRelativeAddr(*Addr)});
   if (!LI) {
     WithColor::defaultErrorHandler(LI.takeError());
     printRawElement(Node);
@@ -345,7 +345,7 @@
     printRawElement(Node);
     return true;
   }
-  uint64_t MRA = MMap->getModuleRelativeAddr(*Addr);
+  uint64_t MRA = MMap->toModuleRelativeAddr(*Addr);
 
   Expected<DIInliningInfo> II =
       Symbolizer.symbolizeInlinedCode(MMap->Mod->BuildID, {MRA});
@@ -411,7 +411,7 @@
   }
 
   Expected<DIGlobal> Symbol = Symbolizer.symbolizeData(
-      MMap->Mod->BuildID, {MMap->getModuleRelativeAddr(*Addr)});
+      MMap->Mod->BuildID, {MMap->toModuleRelativeAddr(*Addr)});
   if (!Symbol) {
     WithColor::defaultErrorHandler(Symbol.takeError());
     printRawElement(Node);
diff --git a/llvm/test/DebugInfo/symbolize-filter-markup-data.test b/llvm/test/DebugInfo/symbolize-filter-markup-data.test
--- a/llvm/test/DebugInfo/symbolize-filter-markup-data.test
+++ b/llvm/test/DebugInfo/symbolize-filter-markup-data.test
@@ -9,9 +9,9 @@
 RUN:   --implicit-check-not {{.}}
 RUN: FileCheck %s --check-prefix=ERR --input-file=%t.err --match-full-lines
 
-CHECK: [[BEGIN:\[{3}]]ELF module #0x0 "a.o"; BuildID=abcdef [0x0-0x4](r),[0x10-0x11](r)[[END:\]{3}]]
-CHECK: long long byte
-CHECK: long byte
+CHECK: [[BEGIN:\[{3}]]ELF module #0x0 "a.o"; BuildID=abcdef [0x0-0x3](r),[0x10-0x10](r)[[END:\]{3}]]
+CHECK: long long
+CHECK: byte
 CHECK: [[BEGIN]]data:0x5[[END]]
 
 ERR: error: expected 1 field(s); found 0
@@ -19,10 +19,10 @@
 
 ;--- input
 {{{module:0:a.o:elf:abcdef}}}
-{{{mmap:0:5:load:0:r:0}}}
-{{{mmap:0x10:2:load:0:r:0x3}}}
-{{{data:0x0}}} {{{data:0x1}}} {{{data:0x4}}}
-{{{data:0x10}}} {{{data:0x11}}}
+{{{mmap:0:4:load:0:r:0}}}
+{{{mmap:0x10:1:load:0:r:0x4}}}
+{{{data:0x0}}} {{{data:0x1}}}
+{{{data:0x10}}}
 
 {{{data}}}
 {{{data:0x5}}}
diff --git a/llvm/test/DebugInfo/symbolize-filter-markup-dump-context.test b/llvm/test/DebugInfo/symbolize-filter-markup-dump-context.test
--- a/llvm/test/DebugInfo/symbolize-filter-markup-dump-context.test
+++ b/llvm/test/DebugInfo/symbolize-filter-markup-dump-context.test
@@ -28,7 +28,7 @@
 CHECK-NEXT:         "type": "load",
 CHECK-NEXT:         "moduleID": 1,
 CHECK-NEXT:         "mode": "r",
-CHECK-NEXT:         "moduleRelativeAddress": 2
+CHECK-NEXT:         "moduleRelativeAddress": 32
 CHECK-NEXT:       },
 CHECK-NEXT:       {
 CHECK-NEXT:         "address": 32,
@@ -36,7 +36,7 @@
 CHECK-NEXT:         "type": "load",
 CHECK-NEXT:         "moduleID": 1,
 CHECK-NEXT:         "mode": "w",
-CHECK-NEXT:         "moduleRelativeAddress": 3
+CHECK-NEXT:         "moduleRelativeAddress": 64
 CHECK-NEXT:       },
 CHECK-NEXT:       {
 CHECK-NEXT:         "address": 80,
@@ -44,7 +44,7 @@
 CHECK-NEXT:         "type": "load",
 CHECK-NEXT:         "moduleID": 0,
 CHECK-NEXT:         "mode": "rx",
-CHECK-NEXT:         "moduleRelativeAddress": 4
+CHECK-NEXT:         "moduleRelativeAddress": 128
 CHECK-NEXT:       }
 CHECK-NEXT:     ]
 CHECK-NEXT:   },
@@ -66,9 +66,9 @@
 ;--- log
 {{{module:1:a.o:elf:cd}}}
 {{{module:0:b.o:elf:ab}}}
-{{{mmap:0x10:0x10:load:1:r:0x2}}}
-{{{mmap:0x20:0x30:load:1:w:0x3}}}
-{{{mmap:0x50:0x60:load:0:rx:0x4}}}
+{{{mmap:0x10:0x10:load:1:r:0x20}}}
+{{{mmap:0x20:0x30:load:1:w:0x40}}}
+{{{mmap:0x50:0x60:load:0:rx:0x80}}}
 {{{pc:0x20}}}
 {{{reset}}}
 {{{module:0:c.o:elf:ef}}}
diff --git a/llvm/test/DebugInfo/symbolize-filter-markup-mmap.test b/llvm/test/DebugInfo/symbolize-filter-markup-mmap.test
--- a/llvm/test/DebugInfo/symbolize-filter-markup-mmap.test
+++ b/llvm/test/DebugInfo/symbolize-filter-markup-mmap.test
@@ -17,15 +17,16 @@
 ERR: error: overlapping mmap: #0x0 [0xa-0xb]
 ERR: error: overlapping mmap: #0x0 [0xa-0xb]
 ERR: error: overlapping mmap: #0x0 [0xa-0xb]
+ERR: error: overlapping mmap: #0x0 [0x1-0x1]
 
 ;--- log
 {{{module:0:a.o:elf:abb50d82b6bdc861}}}
 {{{mmap:0x1:1:load:0:r:0}}}
-{{{mmap:0x2:1:load:0:w:0}}}
-{{{mmap:0x3:1:load:0:x:0}}}
-{{{mmap:0x4:1:load:0:rwx:0}}}
-{{{mmap:0x0:1:load:0:RWX:0}}}
-{{{mmap:0xa:2:load:0:r:0}}}
+{{{mmap:0x2:1:load:0:w:0x4}}}
+{{{mmap:0x3:1:load:0:x:0x6}}}
+{{{mmap:0x4:1:load:0:rwx:0x8}}}
+{{{mmap:0x0:1:load:0:RWX:0xa}}}
+{{{mmap:0xa:2:load:0:r:0xc}}}
 
 {{{mmap}}}
 {{{mmap:0:1:unknown}}}
@@ -35,6 +36,7 @@
 {{{mmap:0:10000000:load:0::0}}}
 {{{mmap:0:10000000:load:0:g:0}}}
 {{{mmap:0:10000000:load:0:wr:0}}}
-{{{mmap:0xa:1:load:0:r:0}}}
-{{{mmap:0x9:2:load:0:r:0}}}
-{{{mmap:0x9:5:load:0:r:0}}}
+{{{mmap:0xa:1:load:0:r:0xe}}}
+{{{mmap:0x9:2:load:0:r:0x11}}}
+{{{mmap:0x9:5:load:0:r:0x13}}}
+{{{mmap:0xc:1:load:0:r:0}}}