diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.o
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001

literal 0
Hc$@<O00001

diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.x86_64 b/llvm/test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.x86_64
new file mode 100755
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001

literal 0
Hc$@<O00001

diff --git a/llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test b/llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test
new file mode 100644
--- /dev/null
+++ b/llvm/test/tools/dsymutil/X86/debug-loc-base-addr.test
@@ -0,0 +1,29 @@
+RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/baseaddr/loc1.x86_64 -f -o - | llvm-dwarfdump -debug-loc - | FileCheck %s
+
+The test was compiled from a single source:
+$ cat loc1.cpp
+int f1(int i, int j) {
+  int x = 5;
+  int y = 3;
+  int r = i + j;
+  int undef;
+  x = undef;
+  y = 4;
+  return r;
+}
+__attribute__((nodebug)) void f2() {
+}
+int main() {
+  return 0;
+}
+
+CHECK: .debug_loc contents:
+CHECK: [0xffffffffffffffff,  0x0000000100000f90):
+CHECK: [0x0000000000000004,  0x0000000000000007): DW_OP_consts +3, DW_OP_stack_value
+CHECK: [0x0000000000000007,  0x0000000000000009): DW_OP_consts +4, DW_OP_stack_value
+
+CHECK: [0xffffffffffffffff,  0x0000000100000f90):
+CHECK: [0x0000000000000004,  0x0000000000000007): DW_OP_consts +5, DW_OP_stack_value
+
+CHECK: [0xffffffffffffffff,  0x0000000100000f90):
+CHECK: [0x0000000000000007,  0x0000000000000009): DW_OP_reg0 RAX
diff --git a/llvm/tools/dsymutil/DwarfStreamer.cpp b/llvm/tools/dsymutil/DwarfStreamer.cpp
--- a/llvm/tools/dsymutil/DwarfStreamer.cpp
+++ b/llvm/tools/dsymutil/DwarfStreamer.cpp
@@ -399,6 +399,9 @@
   MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
 
   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
+  uint64_t BaseAddressMarker = (AddressSize == 8)
+                                   ? std::numeric_limits<uint64_t>::max()
+                                   : std::numeric_limits<uint32_t>::max();
   const DWARFSection &InputSec = Dwarf.getDWARFObj().getLocSection();
   DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
   DWARFUnit &OrigUnit = Unit.getOrigUnit();
@@ -418,11 +421,20 @@
       uint64_t Low = Data.getUnsigned(&Offset, AddressSize);
       uint64_t High = Data.getUnsigned(&Offset, AddressSize);
       LocSectionSize += 2 * AddressSize;
+      // End of list entry.
       if (Low == 0 && High == 0) {
         Asm->OutStreamer->EmitIntValue(0, AddressSize);
         Asm->OutStreamer->EmitIntValue(0, AddressSize);
         break;
       }
+      // Base address selection entry.
+      if (Low == BaseAddressMarker) {
+        Asm->OutStreamer->EmitIntValue(BaseAddressMarker, AddressSize);
+        Asm->OutStreamer->EmitIntValue(High + Attr.second, AddressSize);
+        LocPcOffset = 0;
+        continue;
+      }
+      // Location list entry.
       Asm->OutStreamer->EmitIntValue(Low + LocPcOffset, AddressSize);
       Asm->OutStreamer->EmitIntValue(High + LocPcOffset, AddressSize);
       uint64_t Length = Data.getU16(&Offset);