[lld] r239937 - COFF: Create import library files.
Rui Ueyama
ruiu at google.com
Thu Jul 16 15:21:02 PDT 2015
On Thu, Jul 16, 2015 at 3:15 PM, Sean Silva <chisophugis at gmail.com> wrote:
>
>
> On Thu, Jul 16, 2015 at 2:57 PM, Rui Ueyama <ruiu at google.com> wrote:
>
>> On Thu, Jul 16, 2015 at 2:53 PM, Filipe Cabecinhas <filcab at gmail.com>
>> wrote:
>>
>>> Hi Rui,
>>>
>>> On Wed, Jun 17, 2015 at 1:40 PM, Rui Ueyama <ruiu at google.com> wrote:
>>>
>>>> Author: ruiu
>>>> Date: Wed Jun 17 15:40:43 2015
>>>> New Revision: 239937
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=239937&view=rev
>>>> <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=HotEHX2Iaf4Itp0QWStZq6bAh5NFroMvhCLFt64IWzw&s=rFgSuKRaIFB7IwNuaXxNuJpriqeG1fpXho1oshJZzrA&e=>
>>>> Log:
>>>> COFF: Create import library files.
>>>>
>>>> On Windows, we have to create a .lib file for each .dll.
>>>> When linking against DLLs, the linker doesn't use the DLL files,
>>>> but instead read a list of dllexported symbols from corresponding
>>>> lib files.
>>>>
>>>> A library file containing descriptors of a DLL is called an
>>>> import library file.
>>>>
>>>> lib.exe has a feature to create an import library file from a
>>>> module-definition file. In this patch, we create a module-definition
>>>> file and pass that to lib.exe.
>>>>
>>>> We eventually want to create an import library file by ourselves
>>>> to eliminate dependency to lib.exe. For now, we just use the MSVC
>>>> tool.
>>>>
>>>> Added:
>>>> lld/trunk/test/COFF/Inputs/import.yaml
>>>> lld/trunk/test/COFF/dll.test
>>>> Modified:
>>>> lld/trunk/COFF/Driver.cpp
>>>> lld/trunk/COFF/Driver.h
>>>> lld/trunk/COFF/DriverUtils.cpp
>>>>
>>>> Modified: lld/trunk/COFF/Driver.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=239937&r1=239936&r2=239937&view=diff
>>>> <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=HotEHX2Iaf4Itp0QWStZq6bAh5NFroMvhCLFt64IWzw&s=INZG3GoafMTwC4FFB-qSulbFyNpEPJPEWKqfNdsVKho&e=>
>>>>
>>>> ==============================================================================
>>>> --- lld/trunk/COFF/Driver.cpp (original)
>>>> +++ lld/trunk/COFF/Driver.cpp Wed Jun 17 15:40:43 2015
>>>> @@ -500,6 +500,11 @@ bool LinkerDriver::link(int Argc, const
>>>> }
>>>> }
>>>>
>>>> + // Windows specific -- when we are creating a .dll file, we also
>>>> + // need to create a .lib file.
>>>> + if (!Config->Exports.empty())
>>>> + writeImportLibrary();
>>>> +
>>>> // Windows specific -- fix up dllexported symbols.
>>>> if (!Config->Exports.empty()) {
>>>> for (Export &E : Config->Exports)
>>>>
>>>> Modified: lld/trunk/COFF/Driver.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=239937&r1=239936&r2=239937&view=diff
>>>> <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=HotEHX2Iaf4Itp0QWStZq6bAh5NFroMvhCLFt64IWzw&s=BMZbPr-ruVc6h40qEwZypPZjh7k0eckpTrq1nfC3xlE&e=>
>>>>
>>>> ==============================================================================
>>>> --- lld/trunk/COFF/Driver.h (original)
>>>> +++ lld/trunk/COFF/Driver.h Wed Jun 17 15:40:43 2015
>>>> @@ -98,6 +98,7 @@ private:
>>>> };
>>>>
>>>> std::error_code parseModuleDefs(MemoryBufferRef MB);
>>>> +std::error_code writeImportLibrary();
>>>>
>>>> // Functions below this line are defined in DriverUtils.cpp.
>>>>
>>>>
>>>> Modified: lld/trunk/COFF/DriverUtils.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=239937&r1=239936&r2=239937&view=diff
>>>> <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=HotEHX2Iaf4Itp0QWStZq6bAh5NFroMvhCLFt64IWzw&s=T2ileZ1F9GHIWlr-hzNFoeed4SghyDnruyRi783s4OE&e=>
>>>>
>>>>
>>>> ==============================================================================
>>>> --- lld/trunk/COFF/DriverUtils.cpp (original)
>>>> +++ lld/trunk/COFF/DriverUtils.cpp Wed Jun 17 15:40:43 2015
>>>> @@ -24,6 +24,8 @@
>>>> #include "llvm/Option/ArgList.h"
>>>> #include "llvm/Option/Option.h"
>>>> #include "llvm/Support/CommandLine.h"
>>>> +#include "llvm/Support/FileUtilities.h"
>>>> +#include "llvm/Support/Path.h"
>>>> #include "llvm/Support/Process.h"
>>>> #include "llvm/Support/Program.h"
>>>> #include "llvm/Support/raw_ostream.h"
>>>> @@ -269,6 +271,75 @@ convertResToCOFF(const std::vector<Memor
>>>> return MemoryBuffer::getFile(Path);
>>>> }
>>>>
>>>> +static std::string writeToTempFile(StringRef Contents) {
>>>> + SmallString<128> Path;
>>>> + int FD;
>>>> + if (llvm::sys::fs::createTemporaryFile("tmp", "def", FD, Path)) {
>>>> + llvm::errs() << "failed to create a temporary file\n";
>>>> + return "";
>>>> + }
>>>> + llvm::raw_fd_ostream OS(FD, /*shouldClose*/ true);
>>>> + OS << Contents;
>>>> + return Path.str();
>>>> +}
>>>> +
>>>> +/// Creates a .def file containing the list of exported symbols.
>>>> +static std::string createModuleDefinitionFile() {
>>>> + std::string S;
>>>> + llvm::raw_string_ostream OS(S);
>>>> + OS << "LIBRARY \"" << llvm::sys::path::filename(Config->OutputFile)
>>>> << "\"\n"
>>>> + << "EXPORTS\n";
>>>> + for (Export &E : Config->Exports) {
>>>> + OS << " " << E.ExtName;
>>>> + if (E.Ordinal > 0)
>>>> + OS << " @" << E.Ordinal;
>>>> + if (E.Noname)
>>>> + OS << " NONAME";
>>>> + if (E.Data)
>>>> + OS << " DATA";
>>>> + if (E.Private)
>>>> + OS << " PRIVATE";
>>>> + OS << "\n";
>>>> + }
>>>> + OS.flush();
>>>> + return S;
>>>> +}
>>>> +
>>>> +// Creates a .def file and runs lib.exe on it to create an import
>>>> library.
>>>> +std::error_code writeImportLibrary() {
>>>> + std::string Prog = "lib.exe";
>>>> + ErrorOr<std::string> ExeOrErr = llvm::sys::findProgramByName(Prog);
>>>> + if (auto EC = ExeOrErr.getError()) {
>>>> + llvm::errs() << "unable to find " << Prog << " in PATH: "
>>>> + << EC.message() << "\n";
>>>> + return make_error_code(LLDError::InvalidOption);
>>>> + }
>>>> + llvm::BumpPtrAllocator Alloc;
>>>> + llvm::BumpPtrStringSaver S(Alloc);
>>>> + const char *Exe = S.save(ExeOrErr.get());
>>>> +
>>>> + std::string Contents = createModuleDefinitionFile();
>>>> + StringRef Def = S.save(StringRef(writeToTempFile(Contents)));
>>>> + llvm::FileRemover TempFile(Def);
>>>> +
>>>> + SmallString<128> Out = StringRef(Config->OutputFile);
>>>> + sys::path::replace_extension(Out, ".lib");
>>>> +
>>>> + std::vector<const char *> Args;
>>>> + Args.push_back(Exe);
>>>> + Args.push_back("/nologo");
>>>> + Args.push_back("/machine:x64");
>>>> + Args.push_back(S.save("/def:" + Def));
>>>> + Args.push_back(S.save("/out:" + Out));
>>>> + Args.push_back(nullptr);
>>>> +
>>>> + if (sys::ExecuteAndWait(Exe, Args.data()) != 0) {
>>>> + llvm::errs() << Exe << " failed\n";
>>>> + return make_error_code(LLDError::InvalidOption);
>>>> + }
>>>> + return std::error_code();
>>>> +}
>>>> +
>>>> // Create OptTable
>>>>
>>>> // Create prefix string literals used in Options.td
>>>>
>>>> Added: lld/trunk/test/COFF/Inputs/import.yaml
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/import.yaml?rev=239937&view=auto
>>>> <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=HotEHX2Iaf4Itp0QWStZq6bAh5NFroMvhCLFt64IWzw&s=zGc5n60h8jXHKnatOwxVpNYZWzHfN-sE0aW41MeNeME&e=>
>>>>
>>>>
>>>> ==============================================================================
>>>> --- lld/trunk/test/COFF/Inputs/import.yaml (added)
>>>> +++ lld/trunk/test/COFF/Inputs/import.yaml Wed Jun 17 15:40:43 2015
>>>> @@ -0,0 +1,41 @@
>>>> +---
>>>> +header:
>>>> + Machine: IMAGE_FILE_MACHINE_AMD64
>>>> + Characteristics: []
>>>> +sections:
>>>> + - Name: .text
>>>> + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE,
>>>> IMAGE_SCN_MEM_READ ]
>>>> + Alignment: 4
>>>> + SectionData: 0000000000000000
>>>> +symbols:
>>>> + - Name: .text
>>>> + Value: 0
>>>> + SectionNumber: 1
>>>> + SimpleType: IMAGE_SYM_TYPE_NULL
>>>> + ComplexType: IMAGE_SYM_DTYPE_NULL
>>>> + StorageClass: IMAGE_SYM_CLASS_STATIC
>>>> + SectionDefinition:
>>>> + Length: 8
>>>> + NumberOfRelocations: 0
>>>> + NumberOfLinenumbers: 0
>>>> + CheckSum: 0
>>>> + Number: 0
>>>> + - Name: mainCRTStartup
>>>> + Value: 0
>>>> + SectionNumber: 1
>>>> + SimpleType: IMAGE_SYM_TYPE_NULL
>>>> + ComplexType: IMAGE_SYM_DTYPE_FUNCTION
>>>> + StorageClass: IMAGE_SYM_CLASS_EXTERNAL
>>>> + - Name: exportfn1
>>>> + Value: 0
>>>> + SectionNumber: 0
>>>> + SimpleType: IMAGE_SYM_TYPE_NULL
>>>> + ComplexType: IMAGE_SYM_DTYPE_NULL
>>>> + StorageClass: IMAGE_SYM_CLASS_EXTERNAL
>>>> + - Name: exportfn2
>>>> + Value: 0
>>>> + SectionNumber: 0
>>>> + SimpleType: IMAGE_SYM_TYPE_NULL
>>>> + ComplexType: IMAGE_SYM_DTYPE_NULL
>>>> + StorageClass: IMAGE_SYM_CLASS_EXTERNAL
>>>> +...
>>>>
>>>> Added: lld/trunk/test/COFF/dll.test
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/dll.test?rev=239937&view=auto
>>>> <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=HotEHX2Iaf4Itp0QWStZq6bAh5NFroMvhCLFt64IWzw&s=FVspeG05-fGr8wcJOvocRPUmnlowGc0ax3XEJHiV3yo&e=>
>>>>
>>>> ==============================================================================
>>>> --- lld/trunk/test/COFF/dll.test (added)
>>>> +++ lld/trunk/test/COFF/dll.test Wed Jun 17 15:40:43 2015
>>>> @@ -0,0 +1,19 @@
>>>> +# REQUIRES: winres
>>>>
>>>
>>> Shouldn't it REQUIRE winlib, too?
>>> We have a builder that's failing because it tries to execute lib.exe,
>>> but that can't be found.
>>> 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.
>>>
>>
>> Yes, I think we need to add REQUIRES: winlib too. I'm sorry about that, I
>> should have done that when I submit this patch. In most cases, lib.exe is
>> available as long as res.exe is available, so I didn't notice that.
>>
>
> Thanks for the info. I've added REQUIRES: winlib in r242452.
>
Did it work?
> -- Sean Silva
>
>
>>
>> Are we going to be able to remove the lib.exe dependency in the future?
>>>
>>
>> That's the plan. We already have a lib.exe-compatible command in LLVM, so
>> it might be as easy as calling it instead of MSVC's lib.exe.
>>
>>
>>> Thank you,
>>>
>>> Filipe
>>>
>>>
>>>
>>>> +
>>>> +# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
>>>> +# RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1
>>>> /export:exportfn2
>>>> +# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=EXPORT %s
>>>> +
>>>> +EXPORT: Export Table:
>>>> +EXPORT: DLL name: dll.test.tmp.dll
>>>> +EXPORT: Ordinal RVA Name
>>>> +EXPORT-NEXT: 0 0
>>>> +EXPORT-NEXT: 1 0x1008 exportfn1
>>>> +EXPORT-NEXT: 2 0x1010 exportfn2
>>>> +
>>>> +# RUN: yaml2obj < %p/Inputs/import.yaml > %t2.obj
>>>> +# RUN: lld -flavor link2 /out:%t2.exe %t2.obj %t.lib
>>>> +# RUN: llvm-readobj -coff-imports %t2.exe | FileCheck
>>>> -check-prefix=IMPORT %s
>>>> +
>>>> +IMPORT: Symbol: exportfn1
>>>> +IMPORT: Symbol: exportfn2
>>>>
>>>>
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>>
>>>
>>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150716/b1f019c1/attachment.html>
More information about the llvm-commits
mailing list