Teach the symbolizer lib symbolize objects directly.

Currently, the symbolizer lib can only symbolize a file on disk.
This patch teaches the symbolizer lib to symbolize objects.
llvm-objdump needs this to support archive disassembly with source info.

https://bugs.llvm.org/show_bug.cgi?id=41871

Reviewed by: jhenderson, grimar, MaskRay

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

llvm-svn: 365376
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
index 6092584..2765bf4 100644
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
@@ -42,7 +42,7 @@
 }
 
 ErrorOr<std::unique_ptr<SymbolizableObjectFile>>
-SymbolizableObjectFile::create(object::ObjectFile *Obj,
+SymbolizableObjectFile::create(const object::ObjectFile *Obj,
                                std::unique_ptr<DIContext> DICtx) {
   assert(DICtx);
   std::unique_ptr<SymbolizableObjectFile> res(
@@ -102,7 +102,7 @@
   return std::move(res);
 }
 
-SymbolizableObjectFile::SymbolizableObjectFile(ObjectFile *Obj,
+SymbolizableObjectFile::SymbolizableObjectFile(const ObjectFile *Obj,
                                                std::unique_ptr<DIContext> DICtx)
     : Module(Obj), DebugInfoContext(std::move(DICtx)) {}
 
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
index 3a511dc..9cab941 100644
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
+++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
@@ -31,7 +31,7 @@
 class SymbolizableObjectFile : public SymbolizableModule {
 public:
   static ErrorOr<std::unique_ptr<SymbolizableObjectFile>>
-  create(object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx);
+  create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx);
 
   DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset,
                            FunctionNameKind FNKind,
@@ -68,7 +68,7 @@
   /// Search for the first occurence of specified Address in ObjectFile.
   uint64_t getModuleSectionIndexForAddress(uint64_t Address) const;
 
-  object::ObjectFile *Module;
+  const object::ObjectFile *Module;
   std::unique_ptr<DIContext> DebugInfoContext;
 
   struct SymbolDesc {
@@ -84,7 +84,7 @@
   std::vector<std::pair<SymbolDesc, StringRef>> Functions;
   std::vector<std::pair<SymbolDesc, StringRef>> Objects;
 
-  SymbolizableObjectFile(object::ObjectFile *Obj,
+  SymbolizableObjectFile(const object::ObjectFile *Obj,
                          std::unique_ptr<DIContext> DICtx);
 };
 
diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index 1cb8a7a..6a619f8 100644
--- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -52,14 +52,8 @@
 namespace symbolize {
 
 Expected<DILineInfo>
-LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
-                              object::SectionedAddress ModuleOffset) {
-  SymbolizableModule *Info;
-  if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
-    Info = InfoOrErr.get();
-  else
-    return InfoOrErr.takeError();
-
+LLVMSymbolizer::symbolizeCodeCommon(SymbolizableModule *Info,
+                                    object::SectionedAddress ModuleOffset) {
   // A null module means an error has already been reported. Return an empty
   // result.
   if (!Info)
@@ -77,6 +71,32 @@
   return LineInfo;
 }
 
+Expected<DILineInfo>
+LLVMSymbolizer::symbolizeCode(const ObjectFile &Obj,
+                              object::SectionedAddress ModuleOffset) {
+  StringRef ModuleName = Obj.getFileName();
+  auto I = Modules.find(ModuleName);
+  if (I != Modules.end())
+    return symbolizeCodeCommon(I->second.get(), ModuleOffset);
+
+  std::unique_ptr<DIContext> Context =
+        DWARFContext::create(Obj, nullptr, DWARFContext::defaultErrorHandler);
+  Expected<SymbolizableModule *> InfoOrErr =
+                     createModuleInfo(&Obj, std::move(Context), ModuleName);
+  if (!InfoOrErr)
+    return InfoOrErr.takeError();
+  return symbolizeCodeCommon(*InfoOrErr, ModuleOffset);
+}
+
+Expected<DILineInfo>
+LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
+                              object::SectionedAddress ModuleOffset) {
+  Expected<SymbolizableModule *> InfoOrErr = getOrCreateModuleInfo(ModuleName);
+  if (!InfoOrErr)
+    return InfoOrErr.takeError();
+  return symbolizeCodeCommon(*InfoOrErr, ModuleOffset);
+}
+
 Expected<DIInliningInfo>
 LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
                                      object::SectionedAddress ModuleOffset) {
@@ -395,6 +415,23 @@
 }
 
 Expected<SymbolizableModule *>
+LLVMSymbolizer::createModuleInfo(const ObjectFile *Obj,
+                                 std::unique_ptr<DIContext> Context,
+                                 StringRef ModuleName) {
+  auto InfoOrErr =
+      SymbolizableObjectFile::create(Obj, std::move(Context));
+  std::unique_ptr<SymbolizableModule> SymMod;
+  if (InfoOrErr)
+    SymMod = std::move(*InfoOrErr);
+  auto InsertResult =
+      Modules.insert(std::make_pair(ModuleName, std::move(SymMod)));
+  assert(InsertResult.second);
+  if (std::error_code EC = InfoOrErr.getError())
+    return errorCodeToError(EC);
+  return InsertResult.first->second.get();
+}
+
+Expected<SymbolizableModule *>
 LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
   auto I = Modules.find(ModuleName);
   if (I != Modules.end())
@@ -442,16 +479,7 @@
     Context =
         DWARFContext::create(*Objects.second, nullptr,
                              DWARFContext::defaultErrorHandler, Opts.DWPName);
-  auto InfoOrErr =
-      SymbolizableObjectFile::create(Objects.first, std::move(Context));
-  std::unique_ptr<SymbolizableModule> SymMod;
-  if (InfoOrErr)
-    SymMod = std::move(InfoOrErr.get());
-  auto InsertResult = Modules.emplace(ModuleName, std::move(SymMod));
-  assert(InsertResult.second);
-  if (auto EC = InfoOrErr.getError())
-    return errorCodeToError(EC);
-  return InsertResult.first->second.get();
+  return createModuleInfo(Objects.first, std::move(Context), ModuleName);
 }
 
 namespace {