In GCC, the .refptr stubs are only generated for x86_64, and only
for code models medium and larger (and medium is the default for
x86_64 since this was introduced). They can be omitted for
projects that are conscious about performance and size, and don't
need automatically importing dll data members, by passing -mcmodel=small.
In Clang/LLVM, such .refptr stubs are generated for any potentially
symbol reference that might end up autoimported. The .refptr stubs
are emitted for three separate reasons:
- Without .refptr stubs, undefined symbols are mostly referenced with 32 bit wide relocations. If the symbol ends up autoimported from a different DLL, a 32 bit relative offset might not be enough to reference data in a different DLL, depending on runtime loader layout.
- Without .refptr stubs, the runtime pseudo relocation mechanism will need to temporarily make sections read-write-executable if there are such relocations in the text section
- On ARM and AArch64, the immediate addressing encoded into instructions isn't in the form of a plain 32 bit relative offset, but is expressed with various bits scattered throughout two instructions - the mingw runtime pseudo relocation mechanism doesn't support updating offsets in that form.
If autoimporting is known not to be needed, the user can now
compile with -fno-auto-import, avoiding the extra overhead of
the .refptr stubs.
However, omitting them is potentially fragile as the code
might still rely on automatically importing some symbol without
the developer knowing. If this happens, linking still usually
will succeed, but users may encounter issues at runtime.
Therefore, if the new option -fno-auto-import is passed to the compiler
when driving linking, it passes the flag --disable-auto-import to
the linker, making sure that no symbols actually are autoimported
when the generated code doesn't expect it.