summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2017-07-19 02:01:27 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2017-07-19 02:01:27 +0000
commitace2fa7da4da610d1792ed8bf9d1272366f98736 (patch)
tree217261b7953d17448b650e11a66ff271296133e3
parent08e5f6853bcc39b0695ef140b387851a8624270f (diff)
downloadbcm5719-llvm-ace2fa7da4da610d1792ed8bf9d1272366f98736.tar.gz
bcm5719-llvm-ace2fa7da4da610d1792ed8bf9d1272366f98736.zip
COFF: improve link conformance for import names
Improve the link conformance for the import name embedded into the import library. This requires the associated change to the LLVM portion for the DEF file parser. The import file generation embeds a different name based on whether the driver is invoked as "link" or "lib". Furthermore, the LIBRARY keyword in the DEF file influences the import name. The behaviour can be summarised according to the following table: | LIBRARY w/ ext | LIBRARY w/o ext | no LIBRARY -----+----------------+---------------------+------------------ LINK | {value} | {value}.{.dll/.exe} | {output name} LIB | {value} | {value}.dll | {output name}.dll llvm-svn: 308407
-rw-r--r--lld/COFF/Config.h1
-rw-r--r--lld/COFF/Driver.cpp37
-rw-r--r--lld/test/COFF/Inputs/default.def2
-rw-r--r--lld/test/COFF/Inputs/named.def3
-rw-r--r--lld/test/COFF/Inputs/object.s13
-rw-r--r--lld/test/COFF/implib-name.test71
6 files changed, 121 insertions, 6 deletions
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index 25fdc7abd67..a58e7d5585f 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -82,6 +82,7 @@ struct Configuration {
SymbolBody *Entry = nullptr;
bool NoEntry = false;
std::string OutputFile;
+ std::string ImportName;
bool ColorDiagnostics;
bool DoGC = true;
bool DoICF = true;
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 3620297b8b9..35f4a04866c 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -429,7 +429,32 @@ static std::string getImplibPath() {
return Out.str();
}
-static void createImportLibrary() {
+//
+// The import name is caculated as the following:
+//
+// | LIBRARY w/ ext | LIBRARY w/o ext | no LIBRARY
+// -----+----------------+---------------------+------------------
+// LINK | {value} | {value}.{.dll/.exe} | {output name}
+// LIB | {value} | {value}.dll | {output name}.dll
+//
+static std::string getImportName(bool AsLib) {
+ SmallString<128> Out;
+
+ if (Config->ImportName.empty()) {
+ Out.assign(sys::path::filename(Config->OutputFile));
+ if (AsLib)
+ sys::path::replace_extension(Out, ".dll");
+ } else {
+ Out.assign(Config->ImportName);
+ if (!sys::path::has_extension(Out))
+ sys::path::replace_extension(Out,
+ (Config->DLL || AsLib) ? ".dll" : ".exe");
+ }
+
+ return Out.str();
+}
+
+static void createImportLibrary(bool AsLib) {
std::vector<COFFShortExport> Exports;
for (Export &E1 : Config->Exports) {
COFFShortExport E2;
@@ -444,9 +469,8 @@ static void createImportLibrary() {
Exports.push_back(E2);
}
- std::string DLLName = sys::path::filename(Config->OutputFile);
- std::string Path = getImplibPath();
- writeImportLibrary(DLLName, Path, Exports, Config->Machine);
+ writeImportLibrary(getImportName(AsLib), getImplibPath(), Exports,
+ Config->Machine);
}
static void parseModuleDefs(StringRef Path) {
@@ -457,6 +481,7 @@ static void parseModuleDefs(StringRef Path) {
if (Config->OutputFile.empty())
Config->OutputFile = Saver.save(M.OutputFile);
+ Config->ImportName = Saver.save(M.ImportName);
if (M.ImageBase)
Config->ImageBase = M.ImageBase;
if (M.StackReserve)
@@ -992,7 +1017,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// Handle generation of import library from a def file.
if (!Args.hasArgNoClaim(OPT_INPUT)) {
fixupExports();
- createImportLibrary();
+ createImportLibrary(/*AsLib=*/true);
exit(0);
}
@@ -1117,7 +1142,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// need to create a .lib file.
if (!Config->Exports.empty() || Config->DLL) {
fixupExports();
- createImportLibrary();
+ createImportLibrary(/*AsLib=*/false);
assignExportOrdinals();
}
diff --git a/lld/test/COFF/Inputs/default.def b/lld/test/COFF/Inputs/default.def
new file mode 100644
index 00000000000..1d59beebbb2
--- /dev/null
+++ b/lld/test/COFF/Inputs/default.def
@@ -0,0 +1,2 @@
+EXPORTS
+ f
diff --git a/lld/test/COFF/Inputs/named.def b/lld/test/COFF/Inputs/named.def
new file mode 100644
index 00000000000..07c8622189d
--- /dev/null
+++ b/lld/test/COFF/Inputs/named.def
@@ -0,0 +1,3 @@
+LIBRARY library
+EXPORTS
+ f
diff --git a/lld/test/COFF/Inputs/object.s b/lld/test/COFF/Inputs/object.s
new file mode 100644
index 00000000000..b7059938559
--- /dev/null
+++ b/lld/test/COFF/Inputs/object.s
@@ -0,0 +1,13 @@
+
+ .text
+
+ .def f
+ .scl 2
+ .type 32
+ .endef
+ .global f
+f:
+ retq $0
+
+ .section .drectve,"rd"
+ .ascii " /EXPORT:f"
diff --git a/lld/test/COFF/implib-name.test b/lld/test/COFF/implib-name.test
new file mode 100644
index 00000000000..81b5b258483
--- /dev/null
+++ b/lld/test/COFF/implib-name.test
@@ -0,0 +1,71 @@
+# RUN: mkdir -p %T
+# RUN: llvm-mc -triple x86_64-unknown-windows-msvc -filetype obj -o %T/object.obj %S/Inputs/object.s
+
+# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/named.def /out:%T/library.dll %T/object.obj /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-DLL-EXT
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/named.def /out:%T/library.lib
+# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-DLL-EXT
+
+CHECK-DEFAULT-DLL-EXT: library.dll
+CHECK-DEFAULT-DLL-EXT: library.dll
+CHECK-DEFAULT-DLL-EXT: library.dll
+CHECK-DEFAULT-DLL-EXT: library.dll
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/named.def /out:%T/library.exe %T/object.obj /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-EXE-EXT
+
+CHECK-DEFAULT-EXE-EXT: library.exe
+CHECK-DEFAULT-EXE-EXT: library.exe
+CHECK-DEFAULT-EXE-EXT: library.exe
+CHECK-DEFAULT-EXE-EXT: library.exe
+
+# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.dll /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.exe /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.lib
+# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION
+
+CHECK-EXTENSION: library.ext
+CHECK-EXTENSION: library.ext
+CHECK-EXTENSION: library.ext
+CHECK-EXTENSION: library.ext
+
+# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/default.def /out:%T/default.dll /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-DLL
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/default.def /out:%T/default.lib
+# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-DLL
+
+CHECK-OUTPUT-NAME-DLL: default.dll
+CHECK-OUTPUT-NAME-DLL: default.dll
+CHECK-OUTPUT-NAME-DLL: default.dll
+CHECK-OUTPUT-NAME-DLL: default.dll
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/default.def /out:%T/default.exe %T/object.obj /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-EXE
+
+CHECK-OUTPUT-NAME-EXE: default.exe
+CHECK-OUTPUT-NAME-EXE: default.exe
+CHECK-OUTPUT-NAME-EXE: default.exe
+CHECK-OUTPUT-NAME-EXE: default.exe
+
+# RUN: lld-link /machine:x64 /out:%T/default.exe %T/object.obj /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-NODEF-EXE
+
+CHECK-NODEF-EXE: default.exe
+CHECK-NODEF-EXE: default.exe
+CHECK-NODEF-EXE: default.exe
+CHECK-NODEF-EXE: default.exe
+
+# RUN: lld-link /machine:x64 /dll /out:%T/default.dll %T/object.obj /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-NODEF-DLL
+
+CHECK-NODEF-DLL: default.dll
+CHECK-NODEF-DLL: default.dll
+CHECK-NODEF-DLL: default.dll
+CHECK-NODEF-DLL: default.dll
+
OpenPOWER on IntegriCloud