On Mon Jan 22 13:35:37 2024 +0000, Gabriel Ivăncescu wrote:
Ok, I figured it out. First, wine build tools don't create LTO static archives properly (or rather, doesn't pass the arguments properly, or use the correct archiver, despite being set in environment variables). I will send a separate MR for this as it's pretty straightforward I think. Now the bigger issue are functions defined with `ASM_GLOBAL_FUNC`. In short, GCC doesn't "see" inline asms, it doesn't parse them, so it doesn't know a function is being defined here. But LTO has to know—since it pulls in dependencies during early optimization stages, not after assembly. For example, it has to know if it can inline an imported function from a static library, etc. So since LTO doesn't "see" the function being defined with `ASM_GLOBAL_FUNC`, it will pull it from the import library (libkernelbase.a). Later, when it's all assembled and a "normal" link is done (not one with LTO), multiple definitions happen since now the ASM_GLOBAL_FUNC is pasted there as-is, while the imported one is also there. A similar story happens with `winecrt0/setjmp.o` build with LTO. This file has some ASM_GLOBAL_FUNCs. When a module uses them, and tries to import it using winecrt0.a, LTO doesn't "see" them, so it never imports setjmp.o, causing undefined references. If you import setjmp.o directly, it works of course. One way to tackle this is by making such functions proper functions with the `naked` attribute. I know that attribute is not available in older GCC versions for i386/x86_64, so here's my suggestion: We define ASM_GLOBAL_FUNC to make use of attribute naked if it's available (GCC version check? or feature check on configure? please let me know which one you prefer). But, that does mean we need to include the function signature (return type and arg types) in the macro, and thus all the uses of it have to include this. I don't think this is a bad idea in itself, since it's like defining a function, can even be a self-documenting in a way. What do you think? Is that acceptable?
Unfortunately naked functions don't have well-defined semantics, I don't think we can use them.