[lld] r238564 - COFF: Add /machine option.

Rui Ueyama ruiu at google.com
Fri May 29 09:06:00 PDT 2015


Author: ruiu
Date: Fri May 29 11:06:00 2015
New Revision: 238564

URL: http://llvm.org/viewvc/llvm-project?rev=238564&view=rev
Log:
COFF: Add /machine option.

Added:
    lld/trunk/test/COFF/machine.test
Modified:
    lld/trunk/COFF/Config.h
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/Driver.h
    lld/trunk/COFF/DriverUtils.cpp
    lld/trunk/COFF/Writer.cpp

Modified: lld/trunk/COFF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Config.h?rev=238564&r1=238563&r2=238564&view=diff
==============================================================================
--- lld/trunk/COFF/Config.h (original)
+++ lld/trunk/COFF/Config.h Fri May 29 11:06:00 2015
@@ -11,6 +11,7 @@
 #define LLD_COFF_CONFIG_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Object/COFF.h"
 #include <cstdint>
 #include <set>
 #include <string>
@@ -20,6 +21,7 @@ namespace coff {
 
 class Configuration {
 public:
+  llvm::COFF::MachineTypes MachineType = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
   bool Verbose = false;
   std::string EntryName = "mainCRTStartup";
   uint64_t ImageBase = 0x140000000;

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=238564&r1=238563&r2=238564&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Fri May 29 11:06:00 2015
@@ -103,11 +103,23 @@ bool link(int Argc, const char *Argv[])
     llvm::errs() << "no input files.\n";
     return false;
   }
+
+  // Handle /verbose
   if (Args->hasArg(OPT_verbose))
     Config->Verbose = true;
+
+  // Handle /entry
   if (auto *Arg = Args->getLastArg(OPT_entry))
     Config->EntryName = Arg->getValue();
 
+  // Handle /machine
+  auto MTOrErr = getMachineType(Args.get());
+  if (auto EC = MTOrErr.getError()) {
+    llvm::errs() << EC.message() << "\n";
+    return false;
+  }
+  Config->MachineType = MTOrErr.get();
+
   // Parse all input files and put all symbols to the symbol table.
   // The symbol table will take care of name resolution.
   SymbolTable Symtab;

Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=238564&r1=238563&r2=238564&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Fri May 29 11:06:00 2015
@@ -22,6 +22,7 @@
 namespace lld {
 namespace coff {
 
+using llvm::COFF::MachineTypes;
 class InputFile;
 
 ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>
@@ -37,6 +38,9 @@ std::error_code parseDirectives(StringRe
 std::string findLib(StringRef Filename);
 std::string findFile(StringRef Filename);
 
+// For /machine option.
+ErrorOr<MachineTypes> getMachineType(llvm::opt::InputArgList *Args);
+
 // Create enum with OPT_xxx values for each option in Options.td
 enum {
   OPT_INVALID = 0,

Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=238564&r1=238563&r2=238564&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Fri May 29 11:06:00 2015
@@ -87,6 +87,47 @@ std::string findFile(StringRef Filename)
   return Filename;
 }
 
+// Peeks at the file header to get architecture (e.g. i386 or AMD64).
+// Returns "unknown" if it's not a valid object file.
+static MachineTypes getFileMachineType(StringRef Path) {
+  file_magic Magic;
+  if (identify_magic(Path, Magic))
+    return IMAGE_FILE_MACHINE_UNKNOWN;
+  if (Magic != file_magic::coff_object)
+    return IMAGE_FILE_MACHINE_UNKNOWN;
+  ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = MemoryBuffer::getFile(Path);
+  if (BufOrErr.getError())
+    return IMAGE_FILE_MACHINE_UNKNOWN;
+  std::error_code EC;
+  llvm::object::COFFObjectFile Obj(BufOrErr.get()->getMemBufferRef(), EC);
+  if (EC)
+    return IMAGE_FILE_MACHINE_UNKNOWN;
+  return static_cast<MachineTypes>(Obj.getMachine());
+}
+
+// Returns /machine's value.
+ErrorOr<MachineTypes> getMachineType(llvm::opt::InputArgList *Args) {
+  if (auto *Arg = Args->getLastArg(OPT_machine)) {
+    StringRef S(Arg->getValue());
+    MachineTypes MT = StringSwitch<MachineTypes>(S.lower())
+                          .Case("arm", IMAGE_FILE_MACHINE_ARMNT)
+                          .Case("x64", IMAGE_FILE_MACHINE_AMD64)
+                          .Case("x86", IMAGE_FILE_MACHINE_I386)
+                          .Default(IMAGE_FILE_MACHINE_UNKNOWN);
+    if (MT == IMAGE_FILE_MACHINE_UNKNOWN)
+      return make_dynamic_error_code("unknown /machine argument" + S);
+    return MT;
+  }
+  // If /machine option is missing, we need to take a look at
+  // the magic byte of the first object file to infer machine type.
+  for (auto *Arg : Args->filtered(OPT_INPUT)) {
+    MachineTypes MT = getFileMachineType(Arg->getValue());
+    if (MT != IMAGE_FILE_MACHINE_UNKNOWN)
+      return MT;
+  }
+  return IMAGE_FILE_MACHINE_UNKNOWN;
+}
+
 // Create OptTable
 
 // Create prefix string literals used in Options.td

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=238564&r1=238563&r2=238564&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Fri May 29 11:06:00 2015
@@ -244,7 +244,7 @@ void Writer::writeHeader() {
   // Write COFF header
   auto *COFF = reinterpret_cast<coff_file_header *>(Buf);
   Buf += sizeof(*COFF);
-  COFF->Machine = IMAGE_FILE_MACHINE_AMD64;
+  COFF->Machine = Config->MachineType;
   COFF->NumberOfSections = OutputSections.size();
   COFF->Characteristics =
       (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_RELOCS_STRIPPED |

Added: lld/trunk/test/COFF/machine.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/machine.test?rev=238564&view=auto
==============================================================================
--- lld/trunk/test/COFF/machine.test (added)
+++ lld/trunk/test/COFF/machine.test Fri May 29 11:06:00 2015
@@ -0,0 +1,11 @@
+# RUN: lld -flavor link2 /entry:main /machine:x64 /out:%t.exe \
+# RUN:   %p/Inputs/ret42.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
+
+AMD64: Machine: IMAGE_FILE_MACHINE_AMD64
+
+# RUN: lld -flavor link2 /entry:main /machine:x86 /out:%t.exe \
+# RUN:   %p/Inputs/ret42.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s
+
+I386: Machine: IMAGE_FILE_MACHINE_I386





More information about the llvm-commits mailing list