On Thu Jan 23 21:01:24 2025 +0000, William Horvath wrote:
We only need to decorate all functions that are **only** called from asm, not **every** function that's ever called from asm at all. All we are doing is ensuring that these problematic functions/objects remain available and don't get optimized out at link-time. I haven't come across a case where this wasn't enough (with `ld.bfd`). For reference, [`dlls/wow64/syscall.c`](https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/wow64/syscall.c?ref_t...) contains a similar pattern. `call_user_exception_dispatcher` has the attribute, because it's only reachable from an asm block, counting `Wow64PassExceptionToGuest` which itself is only reachable from asm. In general, my preferred approach for working towards fully functional Wine+LTO would be to make targeted, small changes in small batches, with whatever techniques are required for each case. Given that there's no chance that LTO will be a default compiler/linker option for Wine, I don't think it's worth struggling to wrangle everything all at once. In this case, I think that these functions should have had these attributes from the start, like the WoW64 example.
As I said, just because it works by luck does not mean that it's the correct way to do it. The compiler is free to change the function signature or behavior if:
- it's not exported - it knows all callers
And then what will the asm block that calls it do? Either give compile-time error with "undefined symbol" because it can't find the original function, or run-time crash because the compiler changed the function's behavior which, while correct for all C callers, is not correct for the asm block. That's because the compiler does not look into asm statements. It doesn't know it's being called from an asm block.
BTW GCC does do function signature changes and cloning when optimizing. A simple case is constant propagation where a constant argument is replaced and removed (if the called function is always called with the same constant), or parameter is removed if unused and so on, but there's many more. A new GCC version or LLVM might make your patch not be enough anymore. What else do you think the "no cloning" attribute does?
So just decorate **all** functions called from asm blocks, to be safe and correct with LTO.