diff --git a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp --- a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp +++ b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp @@ -11,12 +11,14 @@ //===----------------------------------------------------------------------===// #include "llvm/ToolDrivers/llvm-dlltool/DlltoolDriver.h" +#include "llvm/ADT/Optional.h" #include "llvm/Object/COFF.h" #include "llvm/Object/COFFImportFile.h" #include "llvm/Object/COFFModuleDefinition.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" +#include "llvm/Support/Host.h" #include "llvm/Support/Path.h" #include @@ -51,10 +53,8 @@ DllOptTable() : OptTable(InfoTable, false) {} }; -} // namespace - // Opens a file. Path has to be resolved already. -static std::unique_ptr openFile(const Twine &Path) { +std::unique_ptr openFile(const Twine &Path) { ErrorOr> MB = MemoryBuffer::getFile(Path); if (std::error_code EC = MB.getError()) { @@ -65,7 +65,7 @@ return std::move(*MB); } -static MachineTypes getEmulation(StringRef S) { +MachineTypes getEmulation(StringRef S) { return StringSwitch(S) .Case("i386", IMAGE_FILE_MACHINE_I386) .Case("i386:x86-64", IMAGE_FILE_MACHINE_AMD64) @@ -74,6 +74,47 @@ .Default(IMAGE_FILE_MACHINE_UNKNOWN); } +MachineTypes getMachine(Triple T) { + switch (T.getArch()) { + case Triple::x86: + return COFF::IMAGE_FILE_MACHINE_I386; + case Triple::x86_64: + return COFF::IMAGE_FILE_MACHINE_AMD64; + case Triple::arm: + return COFF::IMAGE_FILE_MACHINE_ARMNT; + case Triple::aarch64: + return COFF::IMAGE_FILE_MACHINE_ARM64; + default: + return COFF::IMAGE_FILE_MACHINE_UNKNOWN; + } +} + +MachineTypes getDefaultMachine() { + return getMachine(Triple(sys::getDefaultTargetTriple())); +} + +static bool consume_back_lower(StringRef &S, const char *Str) { + if (!S.endswith_lower(Str)) + return false; + S = S.drop_back(strlen(Str)); + return true; +} + +Optional getPrefix(StringRef Argv0) { + StringRef ProgName = llvm::sys::path::stem(Argv0); + // x86_64-w64-mingw32-dlltool -> x86_64-w64-mingw32 + // llvm-dlltool -> None + // aarch64-w64-mingw32-llvm-dlltool-10.exe -> aarch64-w64-mingw32 + ProgName = ProgName.rtrim("0123456789.-"); + if (!consume_back_lower(ProgName, "dlltool")) + return None; + consume_back_lower(ProgName, "llvm-"); + consume_back_lower(ProgName, "-"); + return ProgName.str(); +} + +} // namespace + int llvm::dlltoolDriverMain(llvm::ArrayRef ArgsArr) { DllOptTable Table; unsigned MissingIndex; @@ -94,12 +135,6 @@ return 1; } - if (!Args.hasArgNoClaim(OPT_m) && Args.hasArgNoClaim(OPT_d)) { - llvm::errs() << "error: no target machine specified\n" - << "supported targets: i386, i386:x86-64, arm, arm64\n"; - return 1; - } - for (auto *Arg : Args.filtered(OPT_UNKNOWN)) llvm::errs() << "ignoring unknown argument: " << Arg->getAsString(Args) << "\n"; @@ -119,7 +154,12 @@ return 1; } - COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN; + COFF::MachineTypes Machine = getDefaultMachine(); + if (Optional Prefix = getPrefix(ArgsArr[0])) { + Triple T(*Prefix); + if (T.getArch() != Triple::UnknownArch) + Machine = getMachine(T); + } if (auto *Arg = Args.getLastArg(OPT_m)) Machine = getEmulation(Arg->getValue()); diff --git a/llvm/test/tools/llvm-dlltool/triple-prefix.def b/llvm/test/tools/llvm-dlltool/triple-prefix.def new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-dlltool/triple-prefix.def @@ -0,0 +1,27 @@ +;; Don't make symlinks on Windows. +; UNSUPPORTED: system-windows + +; RUN: rm -rf %t +; RUN: mkdir %t +; RUN: ln -s llvm-dlltool %t/i686-w64-mingw32-llvm-dlltool-10.0.exe +; RUN: ln -s llvm-dlltool %t/x86_64-w64-mingw32-llvm-dlltool-10 +; RUN: ln -s llvm-dlltool %t/armv7-w64-mingw32-dlltool +; RUN: ln -s llvm-dlltool %t/aarch64-w64-mingw32-DLLTOOL.exe + +; RUN: %t/i686-w64-mingw32-llvm-dlltool-10.0.exe -d %s -l %t.a +; RUN: llvm-readobj %t.a | FileCheck --check-prefix=I386 %s +; RUN: %t/x86_64-w64-mingw32-llvm-dlltool-10 -d %s -l %t.a +; RUN: llvm-readobj %t.a | FileCheck --check-prefix=X86_64 %s +; RUN: %t/armv7-w64-mingw32-dlltool -d %s -l %t.a +; RUN: llvm-readobj %t.a | FileCheck --check-prefix=ARM %s +; RUN: %t/aarch64-w64-mingw32-DLLTOOL.exe -d %s -l %t.a +; RUN: llvm-readobj %t.a | FileCheck --check-prefix=ARM64 %s + +LIBRARY test.dll +EXPORTS +TestFunction + +; I386: Format: COFF-i386 +; X86_64: Format: COFF-x86-64 +; ARM: Format: COFF-ARM{{$}} +; ARM64: Format: COFF-ARM64