DebugInfo: Provide option for explicitly specifying the name of the DWP file

If you've archived the DWP file somewhere it's probably useful to be
able to just tell llvm-symbolizer where it is when you're symbolizing
stack traces from the binary.

This only provides a mechanism for specifying a single DWP file, good if
you're symbolizing a program with a single DWP file, but it's likely if
the program is dynamically linked that you might have a DWP for each
dynamic library - in which case this feature won't help (at least as
it's surfaced in llvm-symbolizer for now) - in theory it could be
extended to specify a collection of DWP files that could all be
consulted for split CU hash resolution.

llvm-svn: 309498
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 67f39ec..aeb1dea 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -792,11 +792,13 @@
     return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
   }
 
-  SmallString<128> DWPName;
   Expected<OwningBinary<ObjectFile>> Obj = [&] {
     if (!CheckedForDWP) {
-      (DObj->getFileName() + ".dwp").toVector(DWPName);
-      auto Obj = object::ObjectFile::createObjectFile(DWPName);
+      SmallString<128> DWPName;
+      auto Obj = object::ObjectFile::createObjectFile(
+          this->DWPName.empty()
+              ? (DObj->getFileName() + ".dwp").toStringRef(DWPName)
+              : StringRef(this->DWPName));
       if (Obj) {
         Entry = &DWP;
         return Obj;
@@ -1252,9 +1254,10 @@
 
 std::unique_ptr<DWARFContext>
 DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
-                     function_ref<ErrorPolicy(Error)> HandleError) {
+                     function_ref<ErrorPolicy(Error)> HandleError,
+                     std::string DWPName) {
   auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
-  return llvm::make_unique<DWARFContext>(std::move(DObj));
+  return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
 }
 
 std::unique_ptr<DWARFContext>
@@ -1262,5 +1265,5 @@
                      uint8_t AddrSize, bool isLittleEndian) {
   auto DObj =
       llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
-  return llvm::make_unique<DWARFContext>(std::move(DObj));
+  return llvm::make_unique<DWARFContext>(std::move(DObj), "");
 }
diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index 1d8b432..7aa55e7 100644
--- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -53,10 +53,11 @@
 namespace llvm {
 namespace symbolize {
 
-Expected<DILineInfo> LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
-                                                  uint64_t ModuleOffset) {
+Expected<DILineInfo>
+LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
+                              uint64_t ModuleOffset, StringRef DWPName) {
   SymbolizableModule *Info;
-  if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
+  if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName))
     Info = InfoOrErr.get();
   else
     return InfoOrErr.takeError();
@@ -80,9 +81,9 @@
 
 Expected<DIInliningInfo>
 LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
-                                     uint64_t ModuleOffset) {
+                                     uint64_t ModuleOffset, StringRef DWPName) {
   SymbolizableModule *Info;
-  if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
+  if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName))
     Info = InfoOrErr.get();
   else
     return InfoOrErr.takeError();
@@ -364,7 +365,8 @@
 }
 
 Expected<SymbolizableModule *>
-LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
+LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName,
+                                      StringRef DWPName) {
   const auto &I = Modules.find(ModuleName);
   if (I != Modules.end()) {
     return I->second.get();
@@ -409,7 +411,8 @@
     }
   }
   if (!Context)
-    Context = DWARFContext::create(*Objects.second);
+    Context = DWARFContext::create(*Objects.second, nullptr,
+                                   DWARFContext::defaultErrorHandler, DWPName);
   assert(Context);
   auto InfoOrErr =
       SymbolizableObjectFile::create(Objects.first, std::move(Context));