Index: lib/Driver/UniversalDriver.cpp =================================================================== --- lib/Driver/UniversalDriver.cpp +++ lib/Driver/UniversalDriver.cpp @@ -20,6 +20,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Triple.h" #include "llvm/Option/Arg.h" #include "llvm/Option/Option.h" #include "llvm/Support/CommandLine.h" @@ -125,6 +126,17 @@ return ret; } +static std::pair getTargetFromEmulation(StringRef S) { + if (S == "i386pe") + return {llvm::Triple::COFF, llvm::Triple::ArchType::x86}; + if (S == "i386pep") + return {llvm::Triple::COFF, llvm::Triple::ArchType::x86_64}; + if (S == "thumb2pe") + return {llvm::Triple::COFF, llvm::Triple::ArchType::arm}; + + return {llvm::Triple::UnknownObjectFormat, llvm::Triple::ArchType::UnknownArch}; +} + // Removes the argument from argv along with its value, if exists, and updates // argc. static void removeArg(llvm::opt::Arg *arg, @@ -200,6 +212,17 @@ Flavor flavor = getFlavor(args, parsedArgs); + // Override -m for coff targets + if (llvm::opt::Arg *argMachine = parsedArgs.getLastArg(OPT_m)) { + std::pair targetEmulation = + getTargetFromEmulation(argMachine->getValue()); + + if(targetEmulation.first == llvm::Triple::COFF) { + coff::link(args); + return true; + } + } + // Switch to appropriate driver. switch (flavor) { case Flavor::gnu_ld: Index: lib/Driver/UniversalDriverOptions.td =================================================================== --- lib/Driver/UniversalDriverOptions.td +++ lib/Driver/UniversalDriverOptions.td @@ -11,6 +11,10 @@ def target: Separate<["-"], "target">, HelpText<"Select the target">; +// Used to override gnu pe targets +def m : Separate<["-"], "m">, MetaVarName<"">, + HelpText<"Select target emulation">; + def version: Flag<["-"], "version">, HelpText<"Display the version">;