[PATCH] D91689: [LLD] [COFF] Allow wrapping dllimported functions
Martin Storsjö via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 24 00:15:48 PST 2020
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0b2d84fba84b: [LLD] [COFF] Allow wrapping dllimported functions (authored by mstorsjo).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D91689/new/
https://reviews.llvm.org/D91689
Files:
lld/COFF/MinGW.cpp
lld/test/COFF/wrap-dllimport.s
lld/test/COFF/wrap-import.ll
Index: lld/test/COFF/wrap-import.ll
===================================================================
--- lld/test/COFF/wrap-import.ll
+++ lld/test/COFF/wrap-import.ll
@@ -1,7 +1,8 @@
// REQUIRES: x86
// Check that wrapping works when the wrapped symbol is imported from a
-// different DLL.
+// different DLL, redirecting references that used to point at the import
+// thunk, towards the local wrap function instead.
// RUN: split-file %s %t.dir
// RUN: llc %t.dir/main.ll -o %t.main.obj --filetype=obj
Index: lld/test/COFF/wrap-dllimport.s
===================================================================
--- /dev/null
+++ lld/test/COFF/wrap-dllimport.s
@@ -0,0 +1,42 @@
+// REQUIRES: x86
+
+// Check that we can wrap a dllimported symbol, so that references to
+// __imp_<symbol> gets redirected to a defined local import instead.
+
+// RUN: split-file %s %t.dir
+// RUN: llvm-mc -filetype=obj -triple=i686-win32-gnu %t.dir/main.s -o %t.main.obj
+// RUN: llvm-mc -filetype=obj -triple=i686-win32-gnu %t.dir/other.s -o %t.other.obj
+
+// RUN: lld-link -dll -out:%t.dll %t.other.obj -noentry -safeseh:no -export:foo -implib:%t.lib
+// RUN: lld-link -out:%t.exe %t.main.obj %t.lib -entry:entry -subsystem:console -debug:symtab -safeseh:no -wrap:foo -lldmap:%t.map
+// RUN: llvm-objdump -s -d --print-imm-hex %t.exe | FileCheck %s
+
+// CHECK: Contents of section .rdata:
+// CHECK-NEXT: 402000 06104000
+
+// CHECK: Disassembly of section .text:
+// CHECK-EMPTY:
+// CHECK: 00401000 <_entry>:
+// CHECK-NEXT: 401000: ff 25 00 20 40 00 jmpl *0x402000
+// CHECK-EMPTY:
+// CHECK-NEXT: 00401006 <___wrap_foo>:
+// CHECK-NEXT: 401006: c3 retl
+
+// The jmpl instruction in _entry points at an address in 0x402000,
+// which is the first 4 bytes of the .rdata section (above), which is a
+// pointer that points at ___wrap_foo.
+
+#--- main.s
+.global _entry
+_entry:
+ jmpl *__imp__foo
+
+.global ___wrap_foo
+___wrap_foo:
+ ret
+
+#--- other.s
+.global _foo
+
+_foo:
+ ret
Index: lld/COFF/MinGW.cpp
===================================================================
--- lld/COFF/MinGW.cpp
+++ lld/COFF/MinGW.cpp
@@ -238,6 +238,19 @@
for (const WrappedSymbol &w : wrapped) {
map[w.sym] = w.wrap;
map[w.real] = w.sym;
+ if (Defined *d = dyn_cast<Defined>(w.wrap)) {
+ Symbol *imp = symtab->find(("__imp_" + w.sym->getName()).str());
+ // Create a new defined local import for the wrap symbol. If
+ // no imp prefixed symbol existed, there's no need for it.
+ // (We can't easily distinguish whether any object file actually
+ // referenced it or not, though.)
+ if (imp) {
+ DefinedLocalImport *wrapimp = make<DefinedLocalImport>(
+ saver.save("__imp_" + w.wrap->getName()), d);
+ symtab->localImportChunks.push_back(wrapimp->getChunk());
+ map[imp] = wrapimp;
+ }
+ }
}
// Update pointers in input files.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D91689.307256.patch
Type: text/x-patch
Size: 2975 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201124/2ea892d9/attachment.bin>
More information about the llvm-commits
mailing list