<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/57982>57982</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
COFF LTO fails to map locally defined __imp_name symbols
</td>
</tr>
<tr>
<th>Labels</th>
<td>
lld:COFF,
platform:windows,
LTO
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
mstorsjo
</td>
</tr>
</table>
<pre>
In some cases, it's useful to provide a local definition of a function that was originally declared and referred to as dllimported. In these cases, one can provide a pointer named `__imp_<symbolname>` which points towards the function or variable that provides the definition.
This normally works fine, when not using LTO, and also works fine when either the object file referencing it or providing the definition are compiled with LTO. But when both object files are built with LTO, it fails to resolve the dllimported symbol.
An example of the setup:
```
$ cat lto-dllimp1.c
void __declspec(dllimport) importedFunc(void);
void other(void);
void entry(void) {
importedFunc();
other();
}
$ cat lto-dllimp2.c
static void importedFuncReplacement(void) {
}
void (*__imp_importedFunc)(void) = importedFuncReplacement;
void other(void) {
}
```
Building and linking without LTO succeeds:
```
$ clang -target x86_64-windows-msvc -c lto-dllimp1.c
$ clang -target x86_64-windows-msvc -c lto-dllimp2.c
$ llvm-nm lto-dllimp1.o lto-dllimp2.o
lto-dllimp1.o:
00000000 a @feat.00
U __imp_importedFunc
00000000 T entry
U other
lto-dllimp2.o:
00000000 a @feat.00
00000000 D __imp_importedFunc
00000000 t importedFuncReplacement
00000010 T other
$ lld-link lto-dllimp1.o lto-dllimp2.o -out:lto-dllimp.dll -dll -entry:entry
```
Building and linking with LTO fails:
```
$ clang -target x86_64-windows-msvc -c lto-dllimp1.c -flto
$ clang -target x86_64-windows-msvc -c lto-dllimp2.c -flto
$ llvm-nm lto-dllimp1.o lto-dllimp2.o
lto-dllimp1.o:
U __imp_importedFunc
---------------- T entry
U other
lto-dllimp2.o:
---------------- D __imp_importedFunc
---------------- t importedFuncReplacement
---------------- T other
$ lld-link lto-dllimp1.o lto-dllimp2.o -out:lto-dllimp.dll -dll -entry:entry -demangle:no
lld-link: error: undefined symbol: __imp_importedFunc
>>> referenced by lto-dllimp.dll.lto.obj:(entry)
```
I'm not quite familiar with the LTO internals myself to know where to start looking at this; CC @MaskRay who might have some experience in the area?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy9Vl2P4jYU_TXh5SooOAyQhzwwUKSRWq20mj4jJ3HAO46d2g4M_77XNgMJhdltu9oIAfb9Or4-jk-hqlP-IsGohkFJDTMRWQG3EZkb6AyrOwFWQavVgVcMKAhVUgEVq7nklisJqsbZupOlH9k9tXCkBpTmOy6pECd0LgXVrAIqK9CsZtoNMCu6VULwplXasmoMLy6emR4QJd1A9uq3ikvLNEjaYJJolmy3mGAbpStzagol3HyU_oYGOO55uQ8BBssdqa6MK3BFqzQcqOa0ECwgP9cJbtdFjqNkHSXL8P265wak0o1f3FHpNwPoyBze455JtFlsHZc7-P31i5t166bCqJ5z8GQc62hfTBXfWGnRhlB8j5gsXQpuHcqAy42HwAD7CqVqWgyr4IjpXM0xPHc2VCgUTvVyGx9RdFzYi3vYcagpF65PWN4ocWCh1HV_IDR40IslruGdNi2CRh64AMNs10bpsu-Fm3H-hCGZ4qZaEFbFIf9kXEKwHRSvYLt1lDEtKyOyuCCISAYfWDa4g2hz3jgdpc-9aOV6esfYc2HS6tPVBaL52QfwuanRT-HMH-kHqefrR0sjl6UZSy0vwQPo1_jKWkFL1iCoe5AuuX2gL7wMnB8CzfrB6fphiTvtuOnYndq3O-i_n5FFnpOO34LLN_ffkUoh-5BXYLqyZKwyP0AHQTE2tlTvmIX3xWw7m8ZHLit1NHFjDiXE5V2-_IdgMggW4tDEshkkVwNv1cc-cLusKzk_-H6KpknNqB0nyZUy_vkT7uzaMPr1TMzbwLA_YfYWBvkeDLixre_guPWxj9gzcJw4xD1s_aZWsSPEZ12FGGmC0K-TY_yB2H-FPqTLXj_-HQU9__wb7Uq-n0K7uMbx_yPfbYofoCB8n4Nw-zwmXHzzPCDeXQJ-xr9_5L3HtQeuDyn3EPIvYB7OsQb3V6CkWMrzi-CjBE4BShml3Z9O-kv5cku6uUdrd_LEfy4XPYYVJxjiGeNwjDe36y5ZnG-s7JOz8IKarfHi46-OW1Q5tOGCUx3Og7ub3Znw6gl1mYHmZJio3YX_JtXRyQVUBjjCe0rjDaaUP0x4mVkUPHhtwGrlXit_UPP2laLw2Sto-G5vYU9RLHgByd5bprlbENbxJVFt0CjdjFg-mc2mkyxJsmRU5WmVpRkdWW4Fy1dfNpvreXUQGtoGoenVY-hr6KaTd-cWm1GnRb63tvVnnGzws8OldsUYFREO3Lk6_8QooJwGwiE3pnPicvM0zxZktM-r6aycl5SyYpEUVVYvspTSGSlJUc4zMp2MBC2YMHn09BwRgruP1RxkHDjlhD_IVVujIETD-eRfbV5fkehpPeI5SQhJMjKbJOkkwTcBm2U1qxZsSp5mLHvC5iLbOO48Ih4rvRvp3IMvup1Bo-DGmquRGsN3kjEPDPPTDm9enTfGKm2-qZFfaO5X-TcSlrY0">