diff options
| author | Rui Ueyama <ruiu@google.com> | 2016-01-09 01:22:00 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2016-01-09 01:22:00 +0000 |
| commit | 84425d7289e8f0b667a43bf60035aed66ac8184d (patch) | |
| tree | 254eeea9f91d1c3d9ce83d03402ad131d686f096 /lld/COFF/DLL.cpp | |
| parent | 22861aeab8d4d5525d709806494ece1a42478297 (diff) | |
| download | bcm5719-llvm-84425d7289e8f0b667a43bf60035aed66ac8184d.tar.gz bcm5719-llvm-84425d7289e8f0b667a43bf60035aed66ac8184d.zip | |
COFF: Implement DLL symbol forwarding.
DLL export tables usually contain dllexport'ed symbol RVAs so that
applications which use the DLLs can find symbols from the DLLs.
However, there's a minor feature to "forward" DLL symbols to other
DLLs.
If you set an RVA to a string whose form is "<dllname>.<symbolname>"
(e.g. "KERNEL32.ExitProcess") instead of symbol RVA to the export
table, the loader interprets that as a forwarder symbol, and resolve
that symbol from the specified DLL.
This patch implements that feature.
llvm-svn: 257243
Diffstat (limited to 'lld/COFF/DLL.cpp')
| -rw-r--r-- | lld/COFF/DLL.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp index cc99f9a2f8d..8f3383d75c7 100644 --- a/lld/COFF/DLL.cpp +++ b/lld/COFF/DLL.cpp @@ -320,8 +320,12 @@ public: void writeTo(uint8_t *Buf) const override { for (Export &E : Config->Exports) { - auto *D = cast<Defined>(E.Sym->repl()); - write32le(Buf + OutputSectionOff + E.Ordinal * 4, D->getRVA()); + uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4; + if (E.ForwardChunk) { + write32le(P, E.ForwardChunk->getRVA()); + } else { + write32le(P, cast<Defined>(E.Sym->repl())->getRVA()); + } } } @@ -539,6 +543,15 @@ EdataContents::EdataContents() { for (Export &E : Config->Exports) if (!E.Noname) Names.push_back(new StringChunk(E.ExportName)); + + std::vector<Chunk *> Forwards; + for (Export &E : Config->Exports) { + if (E.ForwardTo.empty()) + continue; + E.ForwardChunk = new StringChunk(E.ForwardTo); + Forwards.push_back(E.ForwardChunk); + } + auto *NameTab = new NamePointersChunk(Names); auto *OrdinalTab = new ExportOrdinalChunk(Names.size()); auto *Dir = new ExportDirectoryChunk(MaxOrdinal, Names.size(), DLLName, @@ -550,6 +563,8 @@ EdataContents::EdataContents() { Chunks.push_back(std::unique_ptr<Chunk>(OrdinalTab)); for (Chunk *C : Names) Chunks.push_back(std::unique_ptr<Chunk>(C)); + for (Chunk *C : Forwards) + Chunks.push_back(std::unique_ptr<Chunk>(C)); } } // namespace coff |

