[Modules] Remove potential ODR violations by sinking the DEBUG_TYPE
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DwarfDebug.cpp
index f4182d0b79b20975a55422556c6fc626bda8b89e..22ea1e34503314f8b961c0f667ef8822f6a4ba1e 100644 (file)
@@ -11,7 +11,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "dwarfdebug"
 #include "ByteStreamer.h"
 #include "DwarfDebug.h"
 #include "DIE.h"
@@ -51,6 +50,8 @@
 #include "llvm/Target/TargetRegisterInfo.h"
 using namespace llvm;
 
+#define DEBUG_TYPE "dwarfdebug"
+
 static cl::opt<bool>
 DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
                          cl::desc("Disable debug info printing"));
@@ -168,14 +169,6 @@ DIType DbgVariable::getType() const {
 
 } // end llvm namespace
 
-/// Return Dwarf Version by checking module flags.
-static unsigned getDwarfVersionFromModule(const Module *M) {
-  Value *Val = M->getModuleFlag("Dwarf Version");
-  if (!Val)
-    return dwarf::DWARF_VERSION;
-  return cast<ConstantInt>(Val)->getZExtValue();
-}
-
 DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
     : Asm(A), MMI(Asm->MMI), FirstCU(0), PrevLabel(NULL), GlobalRangeCount(0),
       InfoHolder(A, "info_string", DIEValueAllocator),
@@ -184,7 +177,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
 
   DwarfInfoSectionSym = DwarfAbbrevSectionSym = DwarfStrSectionSym = 0;
   DwarfDebugRangeSectionSym = DwarfDebugLocSectionSym = DwarfLineSectionSym = 0;
-  DwarfAddrSectionSym = DwarfDebugLocDWOSectionSym = 0;
+  DwarfAddrSectionSym = 0;
   DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = 0;
   FunctionBeginSym = FunctionEndSym = 0;
   CurFn = 0;
@@ -211,7 +204,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
 
   DwarfVersion = DwarfVersionNumber
                      ? DwarfVersionNumber
-                     : getDwarfVersionFromModule(MMI->getModule());
+                     : MMI->getModule()->getDwarfVersion();
 
   {
     NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
@@ -571,14 +564,13 @@ DIE *DwarfDebug::createScopeChildrenDIE(DwarfCompileUnit *TheCU,
 
   // Collect arguments for current function.
   if (LScopes.isCurrentFunctionScope(Scope)) {
-    for (DbgVariable *ArgDV : CurrentFnArguments)
-      if (ArgDV)
-        if (DIE *Arg =
-                TheCU->constructVariableDIE(*ArgDV, Scope->isAbstractScope())) {
-          Children.push_back(Arg);
-          if (ArgDV->isObjectPointer())
-            ObjectPointer = Arg;
-        }
+    for (DbgVariable &ArgDV : CurrentFnArguments)
+      if (ArgDV.getVariable()) {
+        DIE *Arg = TheCU->constructVariableDIE(ArgDV, Scope->isAbstractScope());
+        Children.push_back(Arg);
+        if (ArgDV.isObjectPointer())
+          ObjectPointer = Arg;
+      }
 
     // If this is a variadic function, add an unspecified parameter.
     DISubprogram SP(Scope->getScopeNode());
@@ -591,11 +583,11 @@ DIE *DwarfDebug::createScopeChildrenDIE(DwarfCompileUnit *TheCU,
   }
 
   // Collect lexical scope children first.
-  for (DbgVariable *DV : ScopeVariables.lookup(Scope))
-    if (DIE *Variable = TheCU->constructVariableDIE(*DV,
+  for (DbgVariable &DV : ScopeVariables.lookup(Scope))
+    if (DIE *Variable = TheCU->constructVariableDIE(DV,
                                                     Scope->isAbstractScope())) {
       Children.push_back(Variable);
-      if (DV->isObjectPointer())
+      if (DV.isObjectPointer())
         ObjectPointer = Variable;
     }
   for (LexicalScope *LS : Scope->getChildren())
@@ -791,10 +783,9 @@ void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU,
   assert(Module.Verify() &&
          "Use one of the MDNode * overloads to handle invalid metadata");
   assert(Context && "Should always have a context for an imported_module");
-  DIE *IMDie = new DIE(Module.getTag());
-  TheCU->insertDIE(Module, IMDie);
+  DIE *IMDie = TheCU->createAndAddDIE(Module.getTag(), *Context, Module);
   DIE *EntityDie;
-  DIDescriptor Entity = Module.getEntity();
+  DIDescriptor Entity = resolve(Module.getEntity());
   if (Entity.isNameSpace())
     EntityDie = TheCU->getOrCreateNameSpace(DINameSpace(Entity));
   else if (Entity.isSubprogram())
@@ -810,7 +801,6 @@ void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU,
   StringRef Name = Module.getName();
   if (!Name.empty())
     TheCU->addString(IMDie, dwarf::DW_AT_name, Name);
-  Context->addChild(IMDie);
 }
 
 // Emit all Dwarf sections that should come prior to the content. Create
@@ -1076,9 +1066,6 @@ void DwarfDebug::endModule() {
   // Corresponding abbreviations into a abbrev section.
   emitAbbreviations();
 
-  // Emit info into a debug loc section.
-  emitDebugLoc();
-
   // Emit info into a debug aranges section.
   if (GenerateARangeSection)
     emitDebugARanges();
@@ -1093,7 +1080,10 @@ void DwarfDebug::endModule() {
     emitDebugLineDWO();
     // Emit DWO addresses.
     InfoHolder.emitAddresses(Asm->getObjFileLowering().getDwarfAddrSection());
-  }
+    emitDebugLocDWO();
+  } else
+    // Emit info into a debug loc section.
+    emitDebugLoc();
 
   // Emit info into the dwarf accelerator table sections.
   if (useDwarfAccelTables()) {
@@ -1130,32 +1120,33 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV,
   if (!Scope)
     return NULL;
 
-  AbsDbgVariable = new DbgVariable(Var, NULL, this);
-  addScopeVariable(Scope, AbsDbgVariable);
+  AbsDbgVariable = &addScopeVariable(Scope, DbgVariable(Var, NULL, this));
   AbstractVariables[Var] = AbsDbgVariable;
   return AbsDbgVariable;
 }
 
 // If Var is a current function argument then add it to CurrentFnArguments list.
-bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) {
+DbgVariable *DwarfDebug::addCurrentFnArgument(DbgVariable &Var, LexicalScope *Scope) {
   if (!LScopes.isCurrentFunctionScope(Scope))
-    return false;
-  DIVariable DV = Var->getVariable();
+    return nullptr;
+  DIVariable DV = Var.getVariable();
   if (DV.getTag() != dwarf::DW_TAG_arg_variable)
-    return false;
+    return nullptr;
   unsigned ArgNo = DV.getArgNumber();
   if (ArgNo == 0)
-    return false;
+    return nullptr;
 
-  size_t Size = CurrentFnArguments.size();
-  if (Size == 0)
-    CurrentFnArguments.resize(CurFn->getFunction()->arg_size());
-  // llvm::Function argument size is not good indicator of how many
-  // arguments does the function have at source level.
-  if (ArgNo > Size)
-    CurrentFnArguments.resize(ArgNo * 2);
-  CurrentFnArguments[ArgNo - 1] = Var;
-  return true;
+  auto I = CurrentFnArguments.begin();
+  for (; I != CurrentFnArguments.end(); ++I)
+    if (ArgNo < I->getVariable().getArgNumber())
+      break;
+  return &*CurrentFnArguments.insert(I, std::move(Var));
+}
+
+DbgVariable &DwarfDebug::addVariable(DbgVariable Var, LexicalScope *Scope) {
+  if (DbgVariable *Res = addCurrentFnArgument(Var, Scope))
+    return *Res;
+  return addScopeVariable(Scope, std::move(Var));
 }
 
 // Collect variable information from side table maintained by MMI.
@@ -1173,10 +1164,9 @@ void DwarfDebug::collectVariableInfoFromMMITable(
       continue;
 
     DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VI.Loc);
-    DbgVariable *RegVar = new DbgVariable(DV, AbsDbgVariable, this);
-    RegVar->setFrameIndex(VI.Slot);
-    if (!addCurrentFnArgument(RegVar, Scope))
-      addScopeVariable(Scope, RegVar);
+    DbgVariable RegVar(DV, AbsDbgVariable, this);
+    RegVar.setFrameIndex(VI.Slot);
+    addVariable(std::move(RegVar), Scope);
     if (AbsDbgVariable)
       AbsDbgVariable->setFrameIndex(VI.Slot);
   }
@@ -1198,7 +1188,7 @@ static DebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
                                       const MCSymbol *SLabel,
                                       const MachineInstr *MI,
                                       DwarfCompileUnit *Unit) {
-  const MDNode *Var = MI->getOperand(MI->getNumOperands() - 1).getMetadata();
+  const MDNode *Var = MI->getDebugVariable();
 
   assert(MI->getNumOperands() == 3);
   if (MI->getOperand(0).isReg()) {
@@ -1212,11 +1202,13 @@ static DebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
     return DebugLocEntry(FLabel, SLabel, MLoc, Var, Unit);
   }
   if (MI->getOperand(0).isImm())
-    return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getImm(), Unit);
+    return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getImm(), Var, Unit);
   if (MI->getOperand(0).isFPImm())
-    return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getFPImm(), Unit);
+    return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getFPImm(),
+                         Var, Unit);
   if (MI->getOperand(0).isCImm())
-    return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getCImm(), Unit);
+    return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getCImm(),
+                         Var, Unit);
 
   llvm_unreachable("Unexpected 3 operand DBG_VALUE instruction!");
 }
@@ -1255,23 +1247,25 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
     Processed.insert(DV);
     assert(MInsn->isDebugValue() && "History must begin with debug value");
     DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc());
-    DbgVariable *RegVar = new DbgVariable(DV, AbsVar, this);
-    if (!addCurrentFnArgument(RegVar, Scope))
-      addScopeVariable(Scope, RegVar);
+    DbgVariable &RegVar = addVariable(DbgVariable(DV, AbsVar, this), Scope);
     if (AbsVar)
       AbsVar->setMInsn(MInsn);
 
     // Simplify ranges that are fully coalesced.
     if (History.size() <= 1 ||
         (History.size() == 2 && MInsn->isIdenticalTo(History.back()))) {
-      RegVar->setMInsn(MInsn);
+      RegVar.setMInsn(MInsn);
       continue;
     }
 
     // Handle multiple DBG_VALUE instructions describing one variable.
-    RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
+    RegVar.setDotDebugLocOffset(DotDebugLocEntries.size());
 
-    SmallVector<DebugLocEntry, 4> DebugLoc;
+    DotDebugLocEntries.resize(DotDebugLocEntries.size() + 1);
+    DebugLocList &LocList = DotDebugLocEntries.back();
+    LocList.Label =
+        Asm->GetTempSymbol("debug_loc", DotDebugLocEntries.size() - 1);
+    SmallVector<DebugLocEntry, 4> &DebugLoc = LocList.List;
     for (SmallVectorImpl<const MachineInstr *>::const_iterator
              HI = History.begin(),
              HE = History.end();
@@ -1313,7 +1307,6 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
       if (DebugLoc.empty() || !DebugLoc.back().Merge(Loc))
         DebugLoc.push_back(std::move(Loc));
     }
-    DotDebugLocEntries.push_back(std::move(DebugLoc));
   }
 
   // Collect info for variables that were optimized out.
@@ -1324,7 +1317,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
     if (!DV || !DV.isVariable() || !Processed.insert(DV))
       continue;
     if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext()))
-      addScopeVariable(Scope, new DbgVariable(DV, NULL, this));
+      addScopeVariable(Scope, DbgVariable(DV, NULL, this));
   }
 }
 
@@ -1490,8 +1483,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
         assert(MI->getNumOperands() > 1 && "Invalid machine instruction!");
 
         // Keep track of user variables.
-        const MDNode *Var =
-            MI->getOperand(MI->getNumOperands() - 1).getMetadata();
+        const MDNode *Var = MI->getDebugVariable();
 
         // Variable is in a register, we need to check for clobbers.
         if (isDbgValueInDefinedReg(MI))
@@ -1632,9 +1624,9 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
   }
 }
 
-void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
-  SmallVectorImpl<DbgVariable *> &Vars = ScopeVariables[LS];
-  DIVariable DV = Var->getVariable();
+DbgVariable &DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable Var) {
+  auto &Vars = ScopeVariables[LS];
+  DIVariable DV = Var.getVariable();
   // Variables with positive arg numbers are parameters.
   if (unsigned ArgNum = DV.getArgNumber()) {
     // Keep all parameters in order at the start of the variable list to ensure
@@ -1644,9 +1636,9 @@ void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
     // builds have the right order to begin with), searching from the back (this
     // would catch the unoptimized case quickly), or doing a binary search
     // rather than linear search.
-    SmallVectorImpl<DbgVariable *>::iterator I = Vars.begin();
+    auto I = Vars.begin();
     while (I != Vars.end()) {
-      unsigned CurNum = (*I)->getVariable().getArgNumber();
+      unsigned CurNum = I->getVariable().getArgNumber();
       // A local (non-parameter) variable has been found, insert immediately
       // before it.
       if (CurNum == 0)
@@ -1656,11 +1648,11 @@ void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
         break;
       ++I;
     }
-    Vars.insert(I, Var);
-    return;
+    return *Vars.insert(I, std::move(Var));
   }
 
-  Vars.push_back(Var);
+  Vars.push_back(std::move(Var));
+  return Vars.back();
 }
 
 // Gather and emit post-function debug information.
@@ -1716,7 +1708,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
         if (AbstractVariables.lookup(CleanDV))
           continue;
         if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext()))
-          addScopeVariable(Scope, new DbgVariable(DV, NULL, this));
+          addScopeVariable(Scope, DbgVariable(DV, NULL, this));
       }
     }
     if (ProcessedSPNodes.count(AScope->getScopeNode()) == 0)
@@ -1734,10 +1726,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
   PrevCU = TheCU;
 
   // Clear debug info
-  for (auto &I : ScopeVariables)
-    DeleteContainerPointers(I.second);
   ScopeVariables.clear();
-  DeleteContainerPointers(CurrentFnArguments);
+  CurrentFnArguments.clear();
   UserVariables.clear();
   DbgValues.clear();
   AbstractVariables.clear();
@@ -1796,20 +1786,20 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
 
 // Compute the size and offset of a DIE. The offset is relative to start of the
 // CU. It returns the offset after laying out the DIE.
-unsigned DwarfFile::computeSizeAndOffset(DIE *Die, unsigned Offset) {
+unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) {
   // Record the abbreviation.
-  assignAbbrevNumber(Die->getAbbrev());
+  assignAbbrevNumber(Die.getAbbrev());
 
   // Get the abbreviation for this DIE.
-  const DIEAbbrev &Abbrev = Die->getAbbrev();
+  const DIEAbbrev &Abbrev = Die.getAbbrev();
 
   // Set DIE offset
-  Die->setOffset(Offset);
+  Die.setOffset(Offset);
 
   // Start the size with the size of abbreviation code.
-  Offset += getULEB128Size(Die->getAbbrevNumber());
+  Offset += getULEB128Size(Die.getAbbrevNumber());
 
-  const SmallVectorImpl<DIEValue *> &Values = Die->getValues();
+  const SmallVectorImpl<DIEValue *> &Values = Die.getValues();
   const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
 
   // Size the DIE attribute values.
@@ -1818,20 +1808,20 @@ unsigned DwarfFile::computeSizeAndOffset(DIE *Die, unsigned Offset) {
     Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm());
 
   // Get the children.
-  const std::vector<DIE *> &Children = Die->getChildren();
+  const auto &Children = Die.getChildren();
 
   // Size the DIE children if any.
   if (!Children.empty()) {
     assert(Abbrev.hasChildren() && "Children flag not set");
 
-    for (DIE *Child : Children)
-      Offset = computeSizeAndOffset(Child, Offset);
+    for (auto &Child : Children)
+      Offset = computeSizeAndOffset(*Child, Offset);
 
     // End of children marker.
     Offset += sizeof(int8_t);
   }
 
-  Die->setSize(Offset - Die->getOffset());
+  Die.setSize(Offset - Die.getOffset());
   return Offset;
 }
 
@@ -1851,7 +1841,7 @@ void DwarfFile::computeSizeAndOffsets() {
 
     // EndOffset here is CU-relative, after laying out
     // all of the CU DIE.
-    unsigned EndOffset = computeSizeAndOffset(TheU->getUnitDie(), Offset);
+    unsigned EndOffset = computeSizeAndOffset(*TheU->getUnitDie(), Offset);
     SecOffset += EndOffset;
   }
 }
@@ -1893,7 +1883,7 @@ void DwarfDebug::emitSectionLabels() {
         emitSectionSym(Asm, TLOF.getDwarfStrDWOSection(), "skel_string");
     DwarfAddrSectionSym =
         emitSectionSym(Asm, TLOF.getDwarfAddrSection(), "addr_sec");
-    DwarfDebugLocDWOSectionSym =
+    DwarfDebugLocSectionSym =
         emitSectionSym(Asm, TLOF.getDwarfLocDWOSection(), "skel_loc");
   } else
     DwarfDebugLocSectionSym =
@@ -1903,19 +1893,19 @@ void DwarfDebug::emitSectionLabels() {
 }
 
 // Recursively emits a debug information entry.
-void DwarfDebug::emitDIE(DIE *Die) {
+void DwarfDebug::emitDIE(DIE &Die) {
   // Get the abbreviation for this DIE.
-  const DIEAbbrev &Abbrev = Die->getAbbrev();
+  const DIEAbbrev &Abbrev = Die.getAbbrev();
 
   // Emit the code (index) for the abbreviation.
   if (Asm->isVerbose())
     Asm->OutStreamer.AddComment("Abbrev [" + Twine(Abbrev.getNumber()) +
-                                "] 0x" + Twine::utohexstr(Die->getOffset()) +
-                                ":0x" + Twine::utohexstr(Die->getSize()) + " " +
+                                "] 0x" + Twine::utohexstr(Die.getOffset()) +
+                                ":0x" + Twine::utohexstr(Die.getSize()) + " " +
                                 dwarf::TagString(Abbrev.getTag()));
   Asm->EmitULEB128(Abbrev.getNumber());
 
-  const SmallVectorImpl<DIEValue *> &Values = Die->getValues();
+  const SmallVectorImpl<DIEValue *> &Values = Die.getValues();
   const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
 
   // Emit the DIE attribute values.
@@ -1937,10 +1927,8 @@ void DwarfDebug::emitDIE(DIE *Die) {
 
   // Emit the DIE children if any.
   if (Abbrev.hasChildren()) {
-    const std::vector<DIE *> &Children = Die->getChildren();
-
-    for (DIE *Child : Children)
-      emitDIE(Child);
+    for (auto &Child : Die.getChildren())
+      emitDIE(*Child);
 
     Asm->OutStreamer.AddComment("End Of Children Mark");
     Asm->EmitInt8(0);
@@ -1964,7 +1952,7 @@ void DwarfFile::emitUnits(DwarfDebug *DD, const MCSymbol *ASectionSym) {
 
     TheU->emitHeader(ASectionSym);
 
-    DD->emitDIE(Die);
+    DD->emitDIE(*Die);
     Asm->OutStreamer.EmitLabel(TheU->getLabelEnd());
   }
 }
@@ -2386,31 +2374,33 @@ void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
   // FIXME: ^
 }
 
+void DwarfDebug::emitDebugLocEntryLocation(const DebugLocEntry &Entry) {
+  Asm->OutStreamer.AddComment("Loc expr size");
+  MCSymbol *begin = Asm->OutStreamer.getContext().CreateTempSymbol();
+  MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol();
+  Asm->EmitLabelDifference(end, begin, 2);
+  Asm->OutStreamer.EmitLabel(begin);
+  // Emit the entry.
+  APByteStreamer Streamer(*Asm);
+  emitDebugLocEntry(Streamer, Entry);
+  // Close the range.
+  Asm->OutStreamer.EmitLabel(end);
+}
+
 // Emit locations into the debug loc section.
 void DwarfDebug::emitDebugLoc() {
   // Start the dwarf loc section.
   Asm->OutStreamer.SwitchSection(
-      useSplitDwarf() ? Asm->getObjFileLowering().getDwarfLocDWOSection()
-                      : Asm->getObjFileLowering().getDwarfLocSection());
+      Asm->getObjFileLowering().getDwarfLocSection());
   unsigned char Size = Asm->getDataLayout().getPointerSize();
-  unsigned index = 0;
   for (const auto &DebugLoc : DotDebugLocEntries) {
-    Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", index));
-    for (const auto &Entry : DebugLoc) {
+    Asm->OutStreamer.EmitLabel(DebugLoc.Label);
+    for (const auto &Entry : DebugLoc.List) {
       // Set up the range. This range is relative to the entry point of the
       // compile unit. This is a hard coded 0 for low_pc when we're emitting
       // ranges, or the DW_AT_low_pc on the compile unit otherwise.
       const DwarfCompileUnit *CU = Entry.getCU();
-      if (useSplitDwarf()) {
-        // Just always use start_length for now - at least that's one address
-        // rather than two. We could get fancier and try to, say, reuse an
-        // address we know we've emitted elsewhere (the start of the function?
-        // The start of the CU or CU subrange that encloses this range?)
-        Asm->EmitInt8(dwarf::DW_LLE_start_length_entry);
-        unsigned idx = InfoHolder.getAddrPoolIndex(Entry.getBeginSym());
-        Asm->EmitULEB128(idx);
-        Asm->EmitLabelDifference(Entry.getEndSym(), Entry.getBeginSym(), 4);
-      } else if (CU->getRanges().size() == 1) {
+      if (CU->getRanges().size() == 1) {
         // Grab the begin symbol from the first range as our base.
         const MCSymbol *Base = CU->getRanges()[0].getStart();
         Asm->EmitLabelDifference(Entry.getBeginSym(), Base, Size);
@@ -2419,24 +2409,32 @@ void DwarfDebug::emitDebugLoc() {
         Asm->OutStreamer.EmitSymbolValue(Entry.getBeginSym(), Size);
         Asm->OutStreamer.EmitSymbolValue(Entry.getEndSym(), Size);
       }
-      Asm->OutStreamer.AddComment("Loc expr size");
-      MCSymbol *begin = Asm->OutStreamer.getContext().CreateTempSymbol();
-      MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol();
-      Asm->EmitLabelDifference(end, begin, 2);
-      Asm->OutStreamer.EmitLabel(begin);
-      // Emit the entry.
-      APByteStreamer Streamer(*Asm);
-      emitDebugLocEntry(Streamer, Entry);
-      // Close the range.
-      Asm->OutStreamer.EmitLabel(end);
+
+      emitDebugLocEntryLocation(Entry);
     }
-    if (useSplitDwarf())
-      Asm->EmitInt8(dwarf::DW_LLE_end_of_list_entry);
-    else {
-      Asm->OutStreamer.EmitIntValue(0, Size);
-      Asm->OutStreamer.EmitIntValue(0, Size);
+    Asm->OutStreamer.EmitIntValue(0, Size);
+    Asm->OutStreamer.EmitIntValue(0, Size);
+  }
+}
+
+void DwarfDebug::emitDebugLocDWO() {
+  Asm->OutStreamer.SwitchSection(
+      Asm->getObjFileLowering().getDwarfLocDWOSection());
+  for (const auto &DebugLoc : DotDebugLocEntries) {
+    Asm->OutStreamer.EmitLabel(DebugLoc.Label);
+    for (const auto &Entry : DebugLoc.List) {
+      // Just always use start_length for now - at least that's one address
+      // rather than two. We could get fancier and try to, say, reuse an
+      // address we know we've emitted elsewhere (the start of the function?
+      // The start of the CU or CU subrange that encloses this range?)
+      Asm->EmitInt8(dwarf::DW_LLE_start_length_entry);
+      unsigned idx = InfoHolder.getAddrPoolIndex(Entry.getBeginSym());
+      Asm->EmitULEB128(idx);
+      Asm->EmitLabelDifference(Entry.getEndSym(), Entry.getBeginSym(), 4);
+
+      emitDebugLocEntryLocation(Entry);
     }
-    ++index;
+    Asm->EmitInt8(dwarf::DW_LLE_end_of_list_entry);
   }
 }
 
@@ -2468,7 +2466,7 @@ void DwarfDebug::emitDebugARanges() {
 
   // Build a set of address spans, sorted by CU.
   for (const MCSection *Section : Sections) {
-    SmallVector<SymbolCU, 8> &List = SectionMap[Section];
+    auto &List = SectionMap[Section];
     if (List.size() < 2)
       continue;
 
@@ -2696,7 +2694,9 @@ DwarfTypeUnit *DwarfDebug::constructSkeletonTU(DwarfTypeUnit *TU) {
 // compile units that would normally be in debug_info.
 void DwarfDebug::emitDebugInfoDWO() {
   assert(useSplitDwarf() && "No split dwarf debug info?");
-  InfoHolder.emitUnits(this, nullptr);
+  // Don't pass an abbrev symbol, using a constant zero instead so as not to
+  // emit relocations into the dwo file.
+  InfoHolder.emitUnits(this, /* AbbrevSymbol */nullptr);
 }
 
 // Emit the .debug_abbrev.dwo section for separated dwarf. This contains the