From ca56b33daf6781a248750b6d538cef84fdae0d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 14 Jun 2021 13:21:54 +0300 Subject: [PATCH] [llvm-dlltool] Imply the target arch from a tool triple prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also use the default LLVM target as default for dlltool. This matches how GNU dlltool behaves; it is compiled with one default target, which is used if no option is provided. Extend the anonymous namespace in the implementation file instead of using static functions. Based on a patch by Mateusz MikuĊ‚a. The effect of the default LLVM target, if neither the -m option nor a tool triple prefix is provided, isn't tested, as we can't make assumptions about what it is set to. (We could make the default be forced to one of the four supported architectures if the default triple is another arch, and then just test that llvm-dlltool without an -m option is able to produce an import library, without checking the actual architecture though.) Differential Revision: https://reviews.llvm.org/D104212 --- .../llvm-dlltool/DlltoolDriver.cpp | 62 +++++++++++++++---- .../test/tools/llvm-dlltool/triple-prefix.def | 27 ++++++++ 2 files changed, 78 insertions(+), 11 deletions(-) create mode 100644 llvm/test/tools/llvm-dlltool/triple-prefix.def diff --git a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp index a4fd62e5557f..65ef877a8de8 100644 --- 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 @@ public: 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 @@ static std::unique_ptr openFile(const Twine &Path) { 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 @@ static MachineTypes getEmulation(StringRef S) { .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 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef ArgsArr) { 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 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef ArgsArr) { 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 index 000000000000..94b56bcb08ec --- /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