<div dir="ltr">Hi Rui,<div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 17, 2015 at 1:40 PM, Rui Ueyama <span dir="ltr"><<a href="mailto:ruiu@google.com" target="_blank">ruiu@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: ruiu<br>
Date: Wed Jun 17 15:40:43 2015<br>
New Revision: 239937<br>
<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D239937-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=_CoJz1sHY7BS9ffXLl-9NuuYr5xYIJJWOJl_aKTviww&s=5cim1g0B2iWthFqrJtU7_TbmPJ5Lf-u44JM1O7wSPh4&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=239937&view=rev</a><br>
Log:<br>
COFF: Create import library files.<br>
<br>
On Windows, we have to create a .lib file for each .dll.<br>
When linking against DLLs, the linker doesn't use the DLL files,<br>
but instead read a list of dllexported symbols from corresponding<br>
lib files.<br>
<br>
A library file containing descriptors of a DLL is called an<br>
import library file.<br>
<br>
lib.exe has a feature to create an import library file from a<br>
module-definition file. In this patch, we create a module-definition<br>
file and pass that to lib.exe.<br>
<br>
We eventually want to create an import library file by ourselves<br>
to eliminate dependency to lib.exe. For now, we just use the MSVC<br>
tool.<br>
<br>
Added:<br>
lld/trunk/test/COFF/Inputs/import.yaml<br>
lld/trunk/test/COFF/dll.test<br>
Modified:<br>
lld/trunk/COFF/Driver.cpp<br>
lld/trunk/COFF/Driver.h<br>
lld/trunk/COFF/DriverUtils.cpp<br>
<br>
Modified: lld/trunk/COFF/Driver.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lld_trunk_COFF_Driver.cpp-3Frev-3D239937-26r1-3D239936-26r2-3D239937-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=_CoJz1sHY7BS9ffXLl-9NuuYr5xYIJJWOJl_aKTviww&s=y2WRKWe_zmdEgWZrOD_WaSK2ZHFQhrRrXzdUHtNxMds&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=239937&r1=239936&r2=239937&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/COFF/Driver.cpp (original)<br>
+++ lld/trunk/COFF/Driver.cpp Wed Jun 17 15:40:43 2015<br>
@@ -500,6 +500,11 @@ bool LinkerDriver::link(int Argc, const<br>
}<br>
}<br>
<br>
+ // Windows specific -- when we are creating a .dll file, we also<br>
+ // need to create a .lib file.<br>
+ if (!Config->Exports.empty())<br>
+ writeImportLibrary();<br>
+<br>
// Windows specific -- fix up dllexported symbols.<br>
if (!Config->Exports.empty()) {<br>
for (Export &E : Config->Exports)<br>
<br>
Modified: lld/trunk/COFF/Driver.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lld_trunk_COFF_Driver.h-3Frev-3D239937-26r1-3D239936-26r2-3D239937-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=_CoJz1sHY7BS9ffXLl-9NuuYr5xYIJJWOJl_aKTviww&s=dWAHd3vpuF0nt2EskSd8dZn4wkLkryNpiQ0i0tvV2Nc&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=239937&r1=239936&r2=239937&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/COFF/Driver.h (original)<br>
+++ lld/trunk/COFF/Driver.h Wed Jun 17 15:40:43 2015<br>
@@ -98,6 +98,7 @@ private:<br>
};<br>
<br>
std::error_code parseModuleDefs(MemoryBufferRef MB);<br>
+std::error_code writeImportLibrary();<br>
<br>
// Functions below this line are defined in DriverUtils.cpp.<br>
<br>
<br>
Modified: lld/trunk/COFF/DriverUtils.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lld_trunk_COFF_DriverUtils.cpp-3Frev-3D239937-26r1-3D239936-26r2-3D239937-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=_CoJz1sHY7BS9ffXLl-9NuuYr5xYIJJWOJl_aKTviww&s=i1kaiEk5VYqDB06jyjGnPg-_oujvLqHzE7CabAjixVA&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=239937&r1=239936&r2=239937&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/COFF/DriverUtils.cpp (original)<br>
+++ lld/trunk/COFF/DriverUtils.cpp Wed Jun 17 15:40:43 2015<br>
@@ -24,6 +24,8 @@<br>
#include "llvm/Option/ArgList.h"<br>
#include "llvm/Option/Option.h"<br>
#include "llvm/Support/CommandLine.h"<br>
+#include "llvm/Support/FileUtilities.h"<br>
+#include "llvm/Support/Path.h"<br>
#include "llvm/Support/Process.h"<br>
#include "llvm/Support/Program.h"<br>
#include "llvm/Support/raw_ostream.h"<br>
@@ -269,6 +271,75 @@ convertResToCOFF(const std::vector<Memor<br>
return MemoryBuffer::getFile(Path);<br>
}<br>
<br>
+static std::string writeToTempFile(StringRef Contents) {<br>
+ SmallString<128> Path;<br>
+ int FD;<br>
+ if (llvm::sys::fs::createTemporaryFile("tmp", "def", FD, Path)) {<br>
+ llvm::errs() << "failed to create a temporary file\n";<br>
+ return "";<br>
+ }<br>
+ llvm::raw_fd_ostream OS(FD, /*shouldClose*/ true);<br>
+ OS << Contents;<br>
+ return Path.str();<br>
+}<br>
+<br>
+/// Creates a .def file containing the list of exported symbols.<br>
+static std::string createModuleDefinitionFile() {<br>
+ std::string S;<br>
+ llvm::raw_string_ostream OS(S);<br>
+ OS << "LIBRARY \"" << llvm::sys::path::filename(Config->OutputFile) << "\"\n"<br>
+ << "EXPORTS\n";<br>
+ for (Export &E : Config->Exports) {<br>
+ OS << " " << E.ExtName;<br>
+ if (E.Ordinal > 0)<br>
+ OS << " @" << E.Ordinal;<br>
+ if (E.Noname)<br>
+ OS << " NONAME";<br>
+ if (E.Data)<br>
+ OS << " DATA";<br>
+ if (E.Private)<br>
+ OS << " PRIVATE";<br>
+ OS << "\n";<br>
+ }<br>
+ OS.flush();<br>
+ return S;<br>
+}<br>
+<br>
+// Creates a .def file and runs lib.exe on it to create an import library.<br>
+std::error_code writeImportLibrary() {<br>
+ std::string Prog = "lib.exe";<br>
+ ErrorOr<std::string> ExeOrErr = llvm::sys::findProgramByName(Prog);<br>
+ if (auto EC = ExeOrErr.getError()) {<br>
+ llvm::errs() << "unable to find " << Prog << " in PATH: "<br>
+ << EC.message() << "\n";<br>
+ return make_error_code(LLDError::InvalidOption);<br>
+ }<br>
+ llvm::BumpPtrAllocator Alloc;<br>
+ llvm::BumpPtrStringSaver S(Alloc);<br>
+ const char *Exe = S.save(ExeOrErr.get());<br>
+<br>
+ std::string Contents = createModuleDefinitionFile();<br>
+ StringRef Def = S.save(StringRef(writeToTempFile(Contents)));<br>
+ llvm::FileRemover TempFile(Def);<br>
+<br>
+ SmallString<128> Out = StringRef(Config->OutputFile);<br>
+ sys::path::replace_extension(Out, ".lib");<br>
+<br>
+ std::vector<const char *> Args;<br>
+ Args.push_back(Exe);<br>
+ Args.push_back("/nologo");<br>
+ Args.push_back("/machine:x64");<br>
+ Args.push_back(S.save("/def:" + Def));<br>
+ Args.push_back(S.save("/out:" + Out));<br>
+ Args.push_back(nullptr);<br>
+<br>
+ if (sys::ExecuteAndWait(Exe, Args.data()) != 0) {<br>
+ llvm::errs() << Exe << " failed\n";<br>
+ return make_error_code(LLDError::InvalidOption);<br>
+ }<br>
+ return std::error_code();<br>
+}<br>
+<br>
// Create OptTable<br>
<br>
// Create prefix string literals used in Options.td<br>
<br>
Added: lld/trunk/test/COFF/Inputs/import.yaml<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lld_trunk_test_COFF_Inputs_import.yaml-3Frev-3D239937-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=_CoJz1sHY7BS9ffXLl-9NuuYr5xYIJJWOJl_aKTviww&s=vZ-L2K5VxRr7gkQXyvZiU5QkpIDdEsRrzeXxptF2_Pw&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/import.yaml?rev=239937&view=auto</a><br>
==============================================================================<br>
--- lld/trunk/test/COFF/Inputs/import.yaml (added)<br>
+++ lld/trunk/test/COFF/Inputs/import.yaml Wed Jun 17 15:40:43 2015<br>
@@ -0,0 +1,41 @@<br>
+---<br>
+header:<br>
+ Machine: IMAGE_FILE_MACHINE_AMD64<br>
+ Characteristics: []<br>
+sections:<br>
+ - Name: .text<br>
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]<br>
+ Alignment: 4<br>
+ SectionData: 0000000000000000<br>
+symbols:<br>
+ - Name: .text<br>
+ Value: 0<br>
+ SectionNumber: 1<br>
+ SimpleType: IMAGE_SYM_TYPE_NULL<br>
+ ComplexType: IMAGE_SYM_DTYPE_NULL<br>
+ StorageClass: IMAGE_SYM_CLASS_STATIC<br>
+ SectionDefinition:<br>
+ Length: 8<br>
+ NumberOfRelocations: 0<br>
+ NumberOfLinenumbers: 0<br>
+ CheckSum: 0<br>
+ Number: 0<br>
+ - Name: mainCRTStartup<br>
+ Value: 0<br>
+ SectionNumber: 1<br>
+ SimpleType: IMAGE_SYM_TYPE_NULL<br>
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION<br>
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL<br>
+ - Name: exportfn1<br>
+ Value: 0<br>
+ SectionNumber: 0<br>
+ SimpleType: IMAGE_SYM_TYPE_NULL<br>
+ ComplexType: IMAGE_SYM_DTYPE_NULL<br>
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL<br>
+ - Name: exportfn2<br>
+ Value: 0<br>
+ SectionNumber: 0<br>
+ SimpleType: IMAGE_SYM_TYPE_NULL<br>
+ ComplexType: IMAGE_SYM_DTYPE_NULL<br>
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL<br>
+...<br>
<br>
Added: lld/trunk/test/COFF/dll.test<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lld_trunk_test_COFF_dll.test-3Frev-3D239937-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=_CoJz1sHY7BS9ffXLl-9NuuYr5xYIJJWOJl_aKTviww&s=U36yP6dIaXTrJUozzz2cIugOpBsAQ2YjyfcAyPjkO04&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/dll.test?rev=239937&view=auto</a><br>
==============================================================================<br>
--- lld/trunk/test/COFF/dll.test (added)<br>
+++ lld/trunk/test/COFF/dll.test Wed Jun 17 15:40:43 2015<br>
@@ -0,0 +1,19 @@<br>
+# REQUIRES: winres<br></blockquote><div><br></div><div>Shouldn't it REQUIRE winlib, too?</div><div>We have a builder that's failing because it tries to execute lib.exe, but that can't be found.</div><div>I think what's happening is that CMake finds all the utilities due to having some env var defined pointing at Visual Studio, but then we don't have those in the path.</div><div><br></div><div>Are we going to be able to remove the lib.exe dependency in the future?</div><div><br></div><div>Thank you,</div><div><br></div><div> Filipe</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj<br>
+# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2<br>
+# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=EXPORT %s<br>
+<br>
+EXPORT: Export Table:<br>
+EXPORT: DLL name: dll.test.tmp.dll<br>
+EXPORT: Ordinal RVA Name<br>
+EXPORT-NEXT: 0 0<br>
+EXPORT-NEXT: 1 0x1008 exportfn1<br>
+EXPORT-NEXT: 2 0x1010 exportfn2<br>
+<br>
+# RUN: yaml2obj < %p/Inputs/import.yaml > %t2.obj<br>
+# RUN: lld -flavor link2 /out:%t2.exe %t2.obj %t.lib<br>
+# RUN: llvm-readobj -coff-imports %t2.exe | FileCheck -check-prefix=IMPORT %s<br>
+<br>
+IMPORT: Symbol: exportfn1<br>
+IMPORT: Symbol: exportfn2<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>