[llvm] 55f8c2f - [llvm-link] use file magic when deciding if input should be loaded as archive

Sergey Dmitriev via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 2 16:43:58 PST 2020


Author: Sergey Dmitriev
Date: 2020-12-02T16:29:41-08:00
New Revision: 55f8c2fdfbc5eda1be946e97ecffa2dea44a883e

URL: https://github.com/llvm/llvm-project/commit/55f8c2fdfbc5eda1be946e97ecffa2dea44a883e
DIFF: https://github.com/llvm/llvm-project/commit/55f8c2fdfbc5eda1be946e97ecffa2dea44a883e.diff

LOG: [llvm-link] use file magic when deciding if input should be loaded as archive

llvm-link should not rely on the '.a' file extension when deciding if input file
should be loaded as archive. Archives may have other extensions (f.e. .lib) or no
extensions at all. This patch changes llvm-link to use llvm::file_magic to check
if input file is an archive.

Reviewed By: RaviNarayanaswamy

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

Added: 
    

Modified: 
    llvm/test/tools/llvm-link/archive-bad.ll
    llvm/test/tools/llvm-link/archive.ll
    llvm/tools/llvm-link/llvm-link.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-link/archive-bad.ll b/llvm/test/tools/llvm-link/archive-bad.ll
index 80ce6fc1fe0d..7a4bddb43c0a 100644
--- a/llvm/test/tools/llvm-link/archive-bad.ll
+++ b/llvm/test/tools/llvm-link/archive-bad.ll
@@ -1,7 +1,7 @@
-# RUN: cp %S/Inputs/f.ll %t.fg.a
+# RUN: echo -e '!<arch>\nwith invalid contents' > %t.fg.a
 # RUN: not llvm-link %S/Inputs/h.ll %t.fg.a -o %t.linked.bc 2>&1 | FileCheck %s
 
 # RUN: rm -f %t.fg.a
 # RUN: rm -f %t.linked.bc
 
-# CHECK: file too small to be an archive
+# CHECK: truncated or malformed archive

diff  --git a/llvm/test/tools/llvm-link/archive.ll b/llvm/test/tools/llvm-link/archive.ll
index 10ab83a3d5be..b027db0753d9 100644
--- a/llvm/test/tools/llvm-link/archive.ll
+++ b/llvm/test/tools/llvm-link/archive.ll
@@ -1,8 +1,8 @@
 # RUN: llvm-as %S/Inputs/f.ll -o %t.f.bc
 # RUN: llvm-as %S/Inputs/g.ll -o %t.g.bc
 # RUN: llvm-ar cr %t.fg.a %t.f.bc %t.g.bc
-# RUN: llvm-ar cr %t.empty.a
-# RUN: llvm-link %S/Inputs/h.ll %t.fg.a %t.empty.a -o %t.linked.bc
+# RUN: llvm-ar cr %t.empty.lib
+# RUN: llvm-link %S/Inputs/h.ll %t.fg.a %t.empty.lib -o %t.linked.bc
 
 # RUN: llvm-nm %t.linked.bc | FileCheck %s
 

diff  --git a/llvm/tools/llvm-link/llvm-link.cpp b/llvm/tools/llvm-link/llvm-link.cpp
index 7141bd1ca7a1..0f851a3e7c38 100644
--- a/llvm/tools/llvm-link/llvm-link.cpp
+++ b/llvm/tools/llvm-link/llvm-link.cpp
@@ -11,8 +11,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Object/Archive.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/BinaryFormat/Magic.h"
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/IR/AutoUpgrade.h"
@@ -24,6 +24,7 @@
 #include "llvm/IR/Verifier.h"
 #include "llvm/IRReader/IRReader.h"
 #include "llvm/Linker/Linker.h"
+#include "llvm/Object/Archive.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/InitLLVM.h"
@@ -115,17 +116,18 @@ static ExitOnError ExitOnErr;
 // link path for the specified file to try to find it...
 //
 static std::unique_ptr<Module> loadFile(const char *argv0,
-                                        const std::string &FN,
+                                        std::unique_ptr<MemoryBuffer> Buffer,
                                         LLVMContext &Context,
                                         bool MaterializeMetadata = true) {
   SMDiagnostic Err;
   if (Verbose)
-    errs() << "Loading '" << FN << "'\n";
+    errs() << "Loading '" << Buffer->getBufferIdentifier() << "'\n";
   std::unique_ptr<Module> Result;
   if (DisableLazyLoad)
-    Result = parseIRFile(FN, Err, Context);
+    Result = parseIR(*Buffer, Err, Context);
   else
-    Result = getLazyIRFileModule(FN, Err, Context, !MaterializeMetadata);
+    Result =
+        getLazyIRModule(std::move(Buffer), Err, Context, !MaterializeMetadata);
 
   if (!Result) {
     Err.print(argv0, errs());
@@ -141,19 +143,17 @@ static std::unique_ptr<Module> loadFile(const char *argv0,
 }
 
 static std::unique_ptr<Module> loadArFile(const char *Argv0,
-                                          const std::string &ArchiveName,
+                                          std::unique_ptr<MemoryBuffer> Buffer,
                                           LLVMContext &Context, Linker &L,
                                           unsigned OrigFlags,
                                           unsigned ApplicableFlags) {
   std::unique_ptr<Module> Result(new Module("ArchiveModule", Context));
+  StringRef ArchiveName = Buffer->getBufferIdentifier();
   if (Verbose)
     errs() << "Reading library archive file '" << ArchiveName
            << "' to memory\n";
-  ErrorOr<std::unique_ptr<MemoryBuffer>> Buf =
-    MemoryBuffer::getFile(ArchiveName, -1, false);
-  ExitOnErr(errorCodeToError(Buf.getError()));
   Error Err = Error::success();
-  object::Archive Archive(Buf.get()->getMemBufferRef(), Err);
+  object::Archive Archive(*Buffer, Err);
   ExitOnErr(std::move(Err));
   for (const object::Archive::Child &C : Archive.children(Err)) {
     Expected<StringRef> Ename = C.getName();
@@ -287,7 +287,9 @@ static bool importFunctions(const char *argv0, Module &DestModule) {
 
   auto ModuleLoader = [&DestModule](const char *argv0,
                                     const std::string &Identifier) {
-    return loadFile(argv0, Identifier, DestModule.getContext(), false);
+    std::unique_ptr<MemoryBuffer> Buffer =
+        ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Identifier)));
+    return loadFile(argv0, std::move(Buffer), DestModule.getContext(), false);
   };
 
   ModuleLazyLoaderCache ModuleLoaderCache(ModuleLoader);
@@ -349,10 +351,14 @@ static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
   // Similar to some flags, internalization doesn't apply to the first file.
   bool InternalizeLinkedSymbols = false;
   for (const auto &File : Files) {
+    std::unique_ptr<MemoryBuffer> Buffer =
+        ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(File)));
+
     std::unique_ptr<Module> M =
-      (llvm::sys::path::extension(File) == ".a")
-          ? loadArFile(argv0, File, Context, L, Flags, ApplicableFlags)
-          : loadFile(argv0, File, Context);
+        identify_magic(Buffer->getBuffer()) == file_magic::archive
+            ? loadArFile(argv0, std::move(Buffer), Context, L, Flags,
+                         ApplicableFlags)
+            : loadFile(argv0, std::move(Buffer), Context);
     if (!M.get()) {
       errs() << argv0 << ": ";
       WithColor::error() << " loading file '" << File << "'\n";


        


More information about the llvm-commits mailing list