Access to protected symbols is special as they can not be interposed. Compare https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248 for the history.
This patch introduces a new predicate on Global Value to decide whether a symbol can be interposed. Hidden and local symbols can never be interposed. Protected symbols are safe as well, if they are actually defined. Common linkage counts as definition here. The rest of the patch teaches the X86 target about using PIC access for interposable protected symbols, even when not doing PIC normally. This is required to avoid copy relocations, which would change the address and are rejected by newer binutils versions.
The spec says:
So whether we have a definition or not should not change this.
I understand what you are trying to do: Given a undefined symbol, be conservative and assume it can be in another DSO. Given that we can't have copy relocs for protected, the issue is more noticeable there.
But I think that that should be handled independently. What is needed is a -mno-copy-reloc that instructs llvm to not assume that the linker can use copy relocations to fix up any bad guesses as to where a symbol is.
For example, given
We would get:
With a default visibility undefined symbol playing the role of a safe undefined symbol, a protected one can be required to be in this DSO as the spec says.