mstorsjo added subscribers: alvinhochun, jeremyd2019, jacek, aaron.ballman.
mstorsjo added a comment.

I'm looking to pick this up again - hopefully @rnk has time to discuss what 
would be a good way forward.

So taking it from the top; both GCC and Clang generate `.refptr` stubs when 
referencing variables that might be autoimported. The exact circumstances 
differ a little bit though.

In GCC this is done by making GCC for Windows/x86_64 default to a medium code 
model, and under this code model, references to variables without a visible 
definition get indirection via a `.refptr` stub. This doesn't happen for i386. 
By building with `-mcmodel=small`, one can opt out of them.

In Clang, we generate such `.refptr` stubs with similar heuristics (variables 
without a visible definition), but we do it for all architectures. There are 
three different reasons for wanting to do this:

- Normally, when code references a variable (in the default code model), it is 
done with a 32 bit relative (or absolute) relocation. If the variable turns out 
to end up imported from a different DLL, in a 64 bit address space it may end 
up loaded too far away for a 32 bit relocation.
- If we don't use a `.refptr` stub, the mingw runtime pseudo relocation 
mechanism needs to patch the address at runtime. If this is referenced in a 
code section, it means that the code section needs to be mapped RWX while 
patching it. Changing the memory protection to RWX is generally undesireable 
(and is disallowed outright, within the UWP app model).
- The runtime pseudo relocation format works on N-bit relative or absolute 
addresses. With the x86 instruction encoding, this turns out to work fine - an 
instruction that refers to a different memory location generally is a couple 
bytes of instruction prefix, followed by a 32 bit relative or absolute address, 
easily patchable. In the case of ARM and AArch64, there are no such 
instructions, and loading e.g. a 32 bit immediate constant is often done by a 
pair of instructions, with the actual payload bits scattered throughout the 
instructions. The runtime pseudo relocation format obviously doesn't support 
patching this.

Therefore, with Clang we generate `.refptr` stubs on all architectures. However 
it would be good to be able to opt out from them. When the variables actually 
end up autoimported, LLD has got a couple neat tricks that makes the actual 
pseudo relocations go away in most cases (when it can alias the 
`.refptr.variable` stub with the `__imp_variable` IAT entry). But for the cases 
when the variable isn't autoimported, the `.refptr` stub has to be kept, and it 
produces larger/slower code and more data than necessary. And for low level 
projects like Wine, it might be desireable to be able to tune exactly what is 
done.

So within the Clang context, it is not entirely about range (where the code 
model might be a reasonable fit), but about whether to be prepared for 
autoimports or not.

Within Clang, it is handled by marking variables we know are in the same DLL as 
`dso_local`, while variables that might be autoimported don't get that flag. 
Within LLVM, references to variables that aren't marked `dso_local` get 
indirection via a `.refptr` stub.

Possible ways of handling it would be to invent a new flag for this purpose; 
e.g. `-fno-autoimport` (with the corresponding `-fautoimport` meaning the 
default mode). That makes the use fairly clear, but its role is also a bit 
unclear; there are linker flags `--disable-auto-import` and 
`--disable-runtime-pseudo-reloc` which disable either autoimports of all sorts, 
or only autoimports that end up with an actual pseudo reloc (allowing the 
zero-cost ones that are aliased to IAT entries).

If we make the flag only affect code generation, having it named 
`-fno-autoimport` when the linker still may do something different (ending up 
with a pseudo relocation in executable code, which possibly still works fine, 
just less elegant) is unclear. If we on the other hand make the same flag imply 
either of `--disable-auto-import` or `--disable-runtime-pseudo-reloc`, then 
that name is rather clear.

If we only make it affect code generation, something like `-fdso-local` or 
`-fno-refptr` might be more precise.

If we make the flag imply linker options, then it becomes much clearer to spot 
the error, if you enabled this but the code base still would need autoimports 
somewhere. (This has happened - see 
https://code.videolan.org/videolan/dav1d/-/merge_requests/1303#note_301859, 
https://code.videolan.org/videolan/dav1d/-/merge_requests/1349 and 
https://code.videolan.org/videolan/dav1d/-/merge_requests/1361.) If we make the 
flag only affect code generation, it becomes a more clear match for projects 
using `-mcmodel=small` with GCC today.

I'm open for opinions on how to name these options, @alvinhochun @mati865 
@jeremyd2019 and @jacek. Also requesting early guidance from @aaron.ballman.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61670/new/

https://reviews.llvm.org/D61670

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to