//===----------------------------------------------------------------------===//
#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 <vector>
DllOptTable() : OptTable(InfoTable, false) {}
};
-} // namespace
-
// Opens a file. Path has to be resolved already.
-static std::unique_ptr<MemoryBuffer> openFile(const Twine &Path) {
+std::unique_ptr<MemoryBuffer> openFile(const Twine &Path) {
ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MB = MemoryBuffer::getFile(Path);
if (std::error_code EC = MB.getError()) {
return std::move(*MB);
}
-static MachineTypes getEmulation(StringRef S) {
+MachineTypes getEmulation(StringRef S) {
return StringSwitch<MachineTypes>(S)
.Case("i386", IMAGE_FILE_MACHINE_I386)
.Case("i386:x86-64", IMAGE_FILE_MACHINE_AMD64)
.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<std::string> 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<const char *> ArgsArr) {
DllOptTable Table;
unsigned MissingIndex;
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";
return 1;
}
- COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN;
+ COFF::MachineTypes Machine = getDefaultMachine();
+ if (Optional<std::string> 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());
--- /dev/null
+;; 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