[lld] r219180 - [PECOFF] Infer machine type from input object file

Rui Ueyama ruiu at google.com
Mon Oct 6 18:38:47 PDT 2014


Author: ruiu
Date: Mon Oct  6 20:38:46 2014
New Revision: 219180

URL: http://llvm.org/viewvc/llvm-project?rev=219180&view=rev
Log:
[PECOFF] Infer machine type from input object file

If /machine option is omitted, the linker needs to infer that from
input object files. This patch implements that.

Modified:
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/test/pecoff/machinetype.test

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=219180&r1=219179&r2=219180&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Mon Oct  6 20:38:46 2014
@@ -23,6 +23,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Object/COFF.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/Option.h"
 #include "llvm/Support/CommandLine.h"
@@ -361,6 +362,25 @@ static bool parseManifestUAC(StringRef o
   }
 }
 
+// Returns the machine type (e.g. x86) of the given input file.
+// If the file is not COFF, returns false.
+static bool getMachineType(StringRef path, llvm::COFF::MachineTypes &result) {
+  llvm::sys::fs::file_magic fileType;
+  if (llvm::sys::fs::identify_magic(path, fileType))
+    return false;
+  if (fileType != llvm::sys::fs::file_magic::coff_object)
+    return false;
+  ErrorOr<std::unique_ptr<MemoryBuffer>> buf = MemoryBuffer::getFile(path);
+  if (!buf)
+    return false;
+  std::error_code ec;
+  llvm::object::COFFObjectFile obj(buf.get()->getMemBufferRef(), ec);
+  if (ec)
+    return false;
+  result = static_cast<llvm::COFF::MachineTypes>(obj.getMachine());
+  return true;
+}
+
 // Parse /export:entryname[=internalname][, at ordinal[,NONAME]][,DATA][,PRIVATE].
 //
 // MSDN doesn't say anything about /export:foo=bar style option or PRIVATE
@@ -854,9 +874,6 @@ bool WinLinkDriver::parse(int argc, cons
   // Handle /machine before parsing all the other options, as the target machine
   // type affects how to handle other options. For example, x86 needs the
   // leading underscore to mangle symbols, while x64 doesn't need it.
-  //
-  // TODO: If /machine option is missing, we probably should take a look at
-  // the magic byte of the first object file to set machine type.
   if (llvm::opt::Arg *inputArg = parsedArgs->getLastArg(OPT_machine)) {
     StringRef arg = inputArg->getValue();
     llvm::COFF::MachineTypes type = stringToMachineType(arg);
@@ -865,6 +882,25 @@ bool WinLinkDriver::parse(int argc, cons
       return false;
     }
     ctx.setMachineType(type);
+  } else {
+    // If /machine option is missing, we need to take a look at
+    // the magic byte of the first object file to infer machine type.
+    std::vector<StringRef> files;
+    for (auto arg : *parsedArgs)
+      if (arg->getOption().getID() == OPT_INPUT)
+        files.push_back(arg->getValue());
+    if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_DASH_DASH))
+      files.insert(files.end(), arg->getValues().begin(),
+                   arg->getValues().end());
+    for (StringRef path : files) {
+      llvm::COFF::MachineTypes type;
+      if (!getMachineType(path, type))
+        continue;
+      if (type == llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN)
+        continue;
+      ctx.setMachineType(type);
+      break;
+    }
   }
 
   // Handle /nodefaultlib:<lib>. The same option without argument is handled in

Modified: lld/trunk/test/pecoff/machinetype.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/machinetype.test?rev=219180&r1=219179&r2=219180&view=diff
==============================================================================
--- lld/trunk/test/pecoff/machinetype.test (original)
+++ lld/trunk/test/pecoff/machinetype.test Mon Oct  6 20:38:46 2014
@@ -1,3 +1,13 @@
-# RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t1.obj
-# RUN: yaml2obj %p/Inputs/machine-type-unknown.obj.yaml > %t2.obj
+# RUN: yaml2obj %p/Inputs/machine-type-unknown.obj.yaml > %t1.obj
+# RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t2.obj
+# RUN: yaml2obj %p/Inputs/hello64.obj.yaml > %t3.obj
+
 # RUN: lld -flavor link /out:%t.exe /subsystem:console /force -- %t1.obj %t2.obj
+# RUN: llvm-readobj %t.exe | FileCheck -check-prefix=X86 %s
+
+X86: Arch: i386
+
+# RUN: lld -flavor link /out:%t.exe /subsystem:console /force -- %t1.obj %t3.obj
+# RUN: llvm-readobj %t.exe | FileCheck -check-prefix=X64 %s
+
+X64: Arch: x86_64





More information about the llvm-commits mailing list