diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2017-07-19 02:01:27 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2017-07-19 02:01:27 +0000 |
commit | ace2fa7da4da610d1792ed8bf9d1272366f98736 (patch) | |
tree | 217261b7953d17448b650e11a66ff271296133e3 | |
parent | 08e5f6853bcc39b0695ef140b387851a8624270f (diff) | |
download | bcm5719-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.h | 1 | ||||
-rw-r--r-- | lld/COFF/Driver.cpp | 37 | ||||
-rw-r--r-- | lld/test/COFF/Inputs/default.def | 2 | ||||
-rw-r--r-- | lld/test/COFF/Inputs/named.def | 3 | ||||
-rw-r--r-- | lld/test/COFF/Inputs/object.s | 13 | ||||
-rw-r--r-- | lld/test/COFF/implib-name.test | 71 |
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 + |