[llvm] r363016 - llvm-lib: Implement /machine: argument

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 10 18:13:41 PDT 2019


Author: nico
Date: Mon Jun 10 18:13:41 2019
New Revision: 363016

URL: http://llvm.org/viewvc/llvm-project?rev=363016&view=rev
Log:
llvm-lib: Implement /machine: argument

And share some code with lld-link.

While here, also add a FIXME about PR42180 and merge r360150 to llvm-lib.

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

Modified:
    llvm/trunk/include/llvm/ToolDrivers/llvm-lib/LibDriver.h
    llvm/trunk/lib/ToolDrivers/llvm-lib/LibDriver.cpp
    llvm/trunk/lib/ToolDrivers/llvm-lib/Options.td
    llvm/trunk/test/tools/llvm-lib/machine-mismatch.test

Modified: llvm/trunk/include/llvm/ToolDrivers/llvm-lib/LibDriver.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ToolDrivers/llvm-lib/LibDriver.h?rev=363016&r1=363015&r2=363016&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ToolDrivers/llvm-lib/LibDriver.h (original)
+++ llvm/trunk/include/llvm/ToolDrivers/llvm-lib/LibDriver.h Mon Jun 10 18:13:41 2019
@@ -18,6 +18,21 @@ namespace llvm {
 template <typename T> class ArrayRef;
 
 int libDriverMain(ArrayRef<const char *> ARgs);
+
+
+class StringRef;
+namespace COFF {
+enum MachineTypes : unsigned;
+}
+
+// Returns a user-readable string for ARMNT, ARM64, AMD64, I386.
+// Other MachineTypes values must not be pased in.
+StringRef machineToStr(COFF::MachineTypes MT);
+
+// Maps /machine: arguments to a MachineTypes value.
+// Only returns ARMNT, ARM64, AMD64, I386, or IMAGE_FILE_MACHINE_UNKNOWN.
+COFF::MachineTypes getMachineType(StringRef S);
+
 }
 
 #endif

Modified: llvm/trunk/lib/ToolDrivers/llvm-lib/LibDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ToolDrivers/llvm-lib/LibDriver.cpp?rev=363016&r1=363015&r2=363016&view=diff
==============================================================================
--- llvm/trunk/lib/ToolDrivers/llvm-lib/LibDriver.cpp (original)
+++ llvm/trunk/lib/ToolDrivers/llvm-lib/LibDriver.cpp Mon Jun 10 18:13:41 2019
@@ -140,7 +140,17 @@ static void doList(opt::InputArgList& Ar
   fatalOpenError(std::move(Err), B->getBufferIdentifier());
 }
 
-static StringRef machineToStr(COFF::MachineTypes MT) {
+// Returns /machine's value.
+COFF::MachineTypes llvm::getMachineType(StringRef S) {
+  return StringSwitch<COFF::MachineTypes>(S.lower())
+      .Cases("x64", "amd64", COFF::IMAGE_FILE_MACHINE_AMD64)
+      .Cases("x86", "i386", COFF::IMAGE_FILE_MACHINE_I386)
+      .Case("arm", COFF::IMAGE_FILE_MACHINE_ARMNT)
+      .Case("arm64", COFF::IMAGE_FILE_MACHINE_ARM64)
+      .Default(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
+}
+
+StringRef llvm::machineToStr(COFF::MachineTypes MT) {
   switch (MT) {
   case COFF::IMAGE_FILE_MACHINE_ARMNT:
     return "arm";
@@ -196,9 +206,20 @@ int llvm::libDriverMain(ArrayRef<const c
 
   std::vector<StringRef> SearchPaths = getSearchPaths(&Args, Saver);
 
+  COFF::MachineTypes LibMachine = COFF::IMAGE_FILE_MACHINE_UNKNOWN;
+  std::string LibMachineSource;
+  if (auto *Arg = Args.getLastArg(OPT_machine)) {
+    LibMachine = getMachineType(Arg->getValue());
+    if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
+      llvm::errs() << "unknown /machine: arg " << Arg->getValue() << '\n';
+      return 1;
+    }
+    LibMachineSource =
+        std::string(" (from '/machine:") + Arg->getValue() + "' flag)";
+  }
+
   // Create a NewArchiveMember for each input file.
   std::vector<NewArchiveMember> Members;
-  COFF::MachineTypes LibMachine = COFF::IMAGE_FILE_MACHINE_UNKNOWN;
   for (auto *Arg : Args.filtered(OPT_INPUT)) {
     std::string Path = findInputFile(Arg->getValue(), SearchPaths);
     if (Path.empty()) {
@@ -276,14 +297,20 @@ int llvm::libDriverMain(ArrayRef<const c
       }
     }
 
+    // FIXME: Once lld-link rejects multiple resource .obj files:
+    // Call convertResToCOFF() on .res files and add the resulting
+    // COFF file to the .lib output instead of adding the .res file, and remove
+    // this check. See PR42180.
     if (FileMachine != COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
-      if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN)
+      if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
         LibMachine = FileMachine;
-      else if (LibMachine != FileMachine) {
+        LibMachineSource = std::string(" (inferred from earlier file '") +
+                           Arg->getValue() + "')";
+      } else if (LibMachine != FileMachine) {
         llvm::errs() << Arg->getValue() << ": file machine type "
                      << machineToStr(FileMachine)
                      << " conflicts with library machine type "
-                     << machineToStr(LibMachine) << '\n';
+                     << machineToStr(LibMachine) << LibMachineSource << '\n';
         return 1;
       }
     }

Modified: llvm/trunk/lib/ToolDrivers/llvm-lib/Options.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ToolDrivers/llvm-lib/Options.td?rev=363016&r1=363015&r2=363016&view=diff
==============================================================================
--- llvm/trunk/lib/ToolDrivers/llvm-lib/Options.td (original)
+++ llvm/trunk/lib/ToolDrivers/llvm-lib/Options.td Mon Jun 10 18:13:41 2019
@@ -3,11 +3,11 @@ include "llvm/Option/OptParser.td"
 // lib.exe accepts options starting with either a dash or a slash.
 
 // Flag that takes no arguments.
-class F<string name> : Flag<["/", "-", "-?"], name>;
+class F<string name> : Flag<["/", "-", "/?", "-?"], name>;
 
 // Flag that takes one argument after ":".
 class P<string name, string help> :
-      Joined<["/", "-", "-?"], name#":">, HelpText<help>;
+      Joined<["/", "-", "/?", "-?"], name#":">, HelpText<help>;
 
 def libpath: P<"libpath", "Object file search path">;
 
@@ -18,15 +18,18 @@ def out    : P<"out", "Path to file to w
 def llvmlibthin : F<"llvmlibthin">,
     HelpText<"Make .lib point to .obj files instead of copying their contents">;
 
+def machine: P<"machine", "Specify target platform">;
+
 def help : F<"help">;
-def help_q : Flag<["/?", "-?"], "">, Alias<help>;
+
+// /?? and -?? must be before /? and -? to not confuse lib/Options.
+def help_q : Flag<["/??", "-??", "/?", "-?"], "">, Alias<help>;
 
 //==============================================================================
 // The flags below do nothing. They are defined only for lib.exe compatibility.
 //==============================================================================
 
-class QF<string name> : Joined<["/", "-", "-?"], name#":">;
+class QF<string name> : Joined<["/", "-", "/?", "-?"], name#":">;
 
 def ignore : QF<"ignore">;
-def machine: QF<"machine">;
 def nologo : F<"nologo">;

Modified: llvm/trunk/test/tools/llvm-lib/machine-mismatch.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-lib/machine-mismatch.test?rev=363016&r1=363015&r2=363016&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-lib/machine-mismatch.test (original)
+++ llvm/trunk/test/tools/llvm-lib/machine-mismatch.test Mon Jun 10 18:13:41 2019
@@ -24,15 +24,22 @@ Mixing object files with different machi
 
 RUN: not llvm-lib %t/x86_64.obj %t/i386.obj 2>&1 | \
 RUN:     FileCheck --check-prefix=OBJ32 %s
-OBJ32: i386.obj: file machine type x86 conflicts with library machine type x64
+OBJ32: i386.obj: file machine type x86 conflicts with library machine type x64 (inferred from earlier file '{{.*}}x86_64.obj')
 
 
 Neither is mixing object and bitcode files with different machine type:
 
 RUN: not llvm-lib %t/x86_64.obj %t/i386.bc 2>&1 | \
 RUN:     FileCheck --check-prefix=BC32 %s
-BC32: i386.bc: file machine type x86 conflicts with library machine type x64
+BC32: i386.bc: file machine type x86 conflicts with library machine type x64 (inferred from earlier file '{{.*}}x86_64.obj')
 
 RUN: not llvm-lib %t/arm64.bc %t/x86_64.bc 2>&1 | \
 RUN:     FileCheck --check-prefix=BC64 %s
-BC64: x86_64.bc: file machine type x64 conflicts with library machine type arm64
+BC64: x86_64.bc: file machine type x64 conflicts with library machine type arm64 (inferred from earlier file '{{.*}}arm64.bc')
+
+
+If /machine: is passed, its value is authoritative.
+
+RUN: not llvm-lib /machine:X86 %t/x86_64.obj %t/i386.obj 2>&1 | \
+RUN:     FileCheck --check-prefix=OBJ64 %s
+OBJ64: x86_64.obj: file machine type x64 conflicts with library machine type x86 (from '/machine:X86' flag)




More information about the llvm-commits mailing list