gold-plugin: "Upgrade" debug info and handle its warnings.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 26 Feb 2015 18:24:37 +0000 (18:24 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 26 Feb 2015 18:24:37 +0000 (18:24 +0000)
The gold plugin never calls MaterializeModule, so any old debug info
was not deleted and could cause crashes.

Now that it is being "upgraded", the plugin also has to handle warnings
and create Modules with a nice id (it shows in the warning).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230655 91177308-0d34-0410-b5e6-96231b3b80d8

test/tools/gold/Inputs/drop-debug.bc [new file with mode: 0644]
test/tools/gold/drop-debug.ll [new file with mode: 0644]
tools/gold/gold-plugin.cpp

diff --git a/test/tools/gold/Inputs/drop-debug.bc b/test/tools/gold/Inputs/drop-debug.bc
new file mode 100644 (file)
index 0000000..f9c471f
Binary files /dev/null and b/test/tools/gold/Inputs/drop-debug.bc differ
diff --git a/test/tools/gold/drop-debug.ll b/test/tools/gold/drop-debug.ll
new file mode 100644 (file)
index 0000000..b8c4d8c
--- /dev/null
@@ -0,0 +1,8 @@
+; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so \
+; RUN:    --plugin-opt=emit-llvm -shared %p/Inputs/drop-debug.bc \
+; RUN:    -o t2.bc 2>&1 | FileCheck %s
+
+; drop-debug.bc was created from "void f(void) {}" with clang 3.5 and
+; -gline-tables-only, so it contains old debug info.
+
+; CHECK: warning: LLVM gold plugin: ignoring debug info with an invalid version (1) in {{.*}}/Inputs/drop-debug.bc
index e654a1581f7d50ee13df549f52dd38aaccd7a522..e3a57b55f3342aa39bfbe0ec5c9873ae77f40bce 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/CodeGen/Analysis.h"
 #include "llvm/CodeGen/CommandFlags.h"
+#include "llvm/IR/AutoUpgrade.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
@@ -273,11 +274,11 @@ static bool shouldSkip(uint32_t Symflags) {
 }
 
 static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
-  assert(DI.getSeverity() == DS_Error && "Only expecting errors");
-  const auto &BDI = cast<BitcodeDiagnosticInfo>(DI);
-  std::error_code EC = BDI.getError();
-  if (EC == BitcodeError::InvalidBitcodeSignature)
-    return;
+  if (const auto *BDI = dyn_cast<BitcodeDiagnosticInfo>(&DI)) {
+    std::error_code EC = BDI->getError();
+    if (EC == BitcodeError::InvalidBitcodeSignature)
+      return;
+  }
 
   std::string ErrStorage;
   {
@@ -285,8 +286,21 @@ static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
     DiagnosticPrinterRawOStream DP(OS);
     DI.print(DP);
   }
-  message(LDPL_FATAL, "LLVM gold plugin has failed to create LTO module: %s",
-          ErrStorage.c_str());
+  ld_plugin_level Level;
+  switch (DI.getSeverity()) {
+  case DS_Error:
+    message(LDPL_FATAL, "LLVM gold plugin has failed to create LTO module: %s",
+            ErrStorage.c_str());
+    llvm_unreachable("Fatal doesn't return.");
+  case DS_Warning:
+    Level = LDPL_WARNING;
+    break;
+  case DS_Remark:
+  case DS_Note:
+    Level = LDPL_INFO;
+    break;
+  }
+  message(Level, "LLVM gold plugin: %s",  ErrStorage.c_str());
 }
 
 /// Called by gold to see whether this file is one that our plugin can handle.
@@ -561,7 +575,7 @@ static void freeSymName(ld_plugin_symbol &Sym) {
 
 static std::unique_ptr<Module>
 getModuleForFile(LLVMContext &Context, claimed_file &F,
-                 off_t Filesize, raw_fd_ostream *ApiFile,
+                 ld_plugin_input_file &Info, raw_fd_ostream *ApiFile,
                  StringSet<> &Internalize, StringSet<> &Maybe) {
 
   if (get_symbols(F.handle, F.syms.size(), &F.syms[0]) != LDPS_OK)
@@ -571,7 +585,8 @@ getModuleForFile(LLVMContext &Context, claimed_file &F,
   if (get_view(F.handle, &View) != LDPS_OK)
     message(LDPL_FATAL, "Failed to get a view of file");
 
-  MemoryBufferRef BufferRef(StringRef((const char *)View, Filesize), "");
+  MemoryBufferRef BufferRef(StringRef((const char *)View, Info.filesize),
+                            Info.name);
   ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
       object::IRObjectFile::create(BufferRef, Context);
 
@@ -583,6 +598,8 @@ getModuleForFile(LLVMContext &Context, claimed_file &F,
 
   Module &M = Obj.getModule();
 
+  UpgradeDebugInfo(M);
+
   SmallPtrSet<GlobalValue *, 8> Used;
   collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
 
@@ -792,6 +809,8 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
     return LDPS_OK;
 
   LLVMContext Context;
+  Context.setDiagnosticHandler(diagnosticHandler);
+
   std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context));
   Linker L(Combined.get());
 
@@ -804,8 +823,7 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
     if (get_input_file(F.handle, &File) != LDPS_OK)
       message(LDPL_FATAL, "Failed to get file information");
     std::unique_ptr<Module> M =
-        getModuleForFile(Context, F, File.filesize, ApiFile,
-                         Internalize, Maybe);
+        getModuleForFile(Context, F, File, ApiFile, Internalize, Maybe);
     if (!options::triple.empty())
       M->setTargetTriple(options::triple.c_str());
     else if (M->getTargetTriple().empty()) {