summaryrefslogtreecommitdiffstats
path: root/lld/COFF/DLL.cpp
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-01-09 01:22:00 +0000
committerRui Ueyama <ruiu@google.com>2016-01-09 01:22:00 +0000
commit84425d7289e8f0b667a43bf60035aed66ac8184d (patch)
tree254eeea9f91d1c3d9ce83d03402ad131d686f096 /lld/COFF/DLL.cpp
parent22861aeab8d4d5525d709806494ece1a42478297 (diff)
downloadbcm5719-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.cpp19
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
OpenPOWER on IntegriCloud