[all-commits] [llvm/llvm-project] a9ff1c: [LLD] [COFF] Support linking directly against DLLs...

Martin Storsjö via All-commits all-commits at lists.llvm.org
Thu Jul 1 23:49:45 PDT 2021


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: a9ff1ce1b9a52add7557cf0579d424c9d0678860
      https://github.com/llvm/llvm-project/commit/a9ff1ce1b9a52add7557cf0579d424c9d0678860
  Author: Martin Storsjö <martin at martin.st>
  Date:   2021-07-02 (Fri, 02 Jul 2021)

  Changed paths:
    M lld/COFF/Driver.cpp
    M lld/COFF/InputFiles.cpp
    M lld/COFF/InputFiles.h
    M lld/COFF/SymbolTable.cpp
    M lld/COFF/SymbolTable.h
    M lld/COFF/Symbols.cpp
    M lld/COFF/Symbols.h
    M lld/COFF/Writer.cpp
    A lld/test/COFF/link-dll-i386.s
    A lld/test/COFF/link-dll.s

  Log Message:
  -----------
  [LLD] [COFF] Support linking directly against DLLs in MinGW mode

GNU ld.bfd supports linking directly against DLLs without using an
import library, and some projects have picked up on this habit.
(There's no one single unsurmountable issue with using import
libraries, but this is a regularly surfacing missing feature.)

As long as one is linking by name (instead of by ordinal), the DLL
export table contains most of the information needed. (One can
inspect what section a symbol points at, to see if it's a function
or data symbol. The practical implementation of this loops over all
sections for each symbol, but as long as they're not very many, that
should hopefully be tolerable performance wise.)

One exception where the information in the DLL isn't entirely enough
is on i386 with stdcall functions; depending on how they're done,
the exported function name can be a plain undecorated name, while
the import library would contain the full decorated symbol name. This
issue is addressed separately in a different patch.

This is implemented mimicing the structure of a regular import library,
with one InputFile corresponding to the static archive that just adds
lazy symbols, which then are fetched when they are needed. When such
a symbol is fetched, we synthesize a coff_import_header structure
in memory and create a regular ImportFile out of it.

The implementation could be even smaller by just creating ImportFiles
for every symbol available immediately, but that would have the
drawback of actually ending up importing all symbols unless running
with GC enabled (and mingw mode defaults to having it disabled for
historical reasons).

Differential Revision: https://reviews.llvm.org/D104530


  Commit: c09e5e50b13aa1f5a2eafc81097ffe8a5799e5b3
      https://github.com/llvm/llvm-project/commit/c09e5e50b13aa1f5a2eafc81097ffe8a5799e5b3
  Author: Martin Storsjö <martin at martin.st>
  Date:   2021-07-02 (Fri, 02 Jul 2021)

  Changed paths:
    M lld/MinGW/Driver.cpp
    M lld/test/MinGW/lib.test

  Log Message:
  -----------
  [LLD] [MinGW] Allow linking to DLLs directly

As the COFF linker is capable of linking directly against a DLL now
(after D104530, as long as it is running in mingw mode), don't error
out here but successfully load libraries specified with "-l" from DLLs
if that's what ld.bfd would have matched.

Differential Revision: https://reviews.llvm.org/D104531


  Commit: ce211c505b82e5bbb68b936968d9b54608285416
      https://github.com/llvm/llvm-project/commit/ce211c505b82e5bbb68b936968d9b54608285416
  Author: Martin Storsjö <martin at martin.st>
  Date:   2021-07-02 (Fri, 02 Jul 2021)

  Changed paths:
    M lld/COFF/Config.h
    M lld/COFF/Driver.cpp
    M lld/COFF/InputFiles.cpp
    M lld/COFF/Options.td
    M lld/COFF/SymbolTable.cpp
    M lld/COFF/SymbolTable.h
    M lld/MinGW/Driver.cpp
    M lld/MinGW/Options.td
    A lld/test/COFF/link-dll-stdcall.s
    M lld/test/MinGW/driver.test

  Log Message:
  -----------
  [LLD] [COFF] Fix up missing stdcall decorations in MinGW mode

If linking directly against a DLL without an import library, the
DLL export symbols might not contain stdcall decorations.

If we have an undefined symbol with decoration, and we happen to have
a matching undecorated symbol (which either is lazy and can be loaded,
or already defined), then alias it against that instead.

This matches what's done in reverse, when we have a def file
declaring to export a symbol without decoration, but we only have
a defined decorated symbol. In that case we do a fuzzy match
(SymbolTable::findMangle). This case is more straightforward; if we
have a decorated undefined symbol, just strip the decoration and look
for the corresponding undecorated symbol name.

Add warnings and options for either silencing the warning or disabling
the whole feature, corresponding to how ld.bfd does it.

(This feature works for any symbol decoration mismatch, not only when
linking against a DLL directly; ld.bfd also tolerates it anywhere,
and also fixes up mismatches in the other direction, like
SymbolTable::findMangle, for any symbol, not only exports. But in
practice, at least for lld, it would primarily end up used for linking
against DLLs.)

Differential Revision: https://reviews.llvm.org/D104532


Compare: https://github.com/llvm/llvm-project/compare/86c5afa6e601...ce211c505b82


More information about the All-commits mailing list