forked from OSchip/llvm-project
[LLD] [COFF] Allow wrapping dllimported functions
GNU ld doesn't seem to do this though, but it looks like a reasonable use case, is easy to implement, and was requested in https://bugs.llvm.org/show_bug.cgi?id=47384. Differential Revision: https://reviews.llvm.org/D91689
This commit is contained in:
parent
bce2ac9f6d
commit
0b2d84fba8
|
@ -238,6 +238,19 @@ void lld::coff::wrapSymbols(ArrayRef<WrappedSymbol> wrapped) {
|
|||
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.
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue