This is an archive of the discontinued LLVM Phabricator instance.

Access protected symbols via GOT, even in non-PIC mode
AbandonedPublic

Authored by joerg on Mar 23 2016, 9:54 AM.

Details

Summary

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.

Diff Detail

Event Timeline

joerg updated this revision to Diff 51438.Mar 23 2016, 9:54 AM
joerg retitled this revision from to Access protected symbols via GOT, even in non-PIC mode.
joerg updated this object.
joerg added reviewers: hjl.tools, rafael, nadav.
joerg set the repository for this revision to rL LLVM.
joerg added a subscriber: llvm-commits.
joerg updated this object.Mar 24 2016, 7:44 AM
joerg updated this revision to Diff 51920.Mar 29 2016, 8:21 AM
joerg removed rL LLVM as the repository for this revision.

Explicitly check that the address of a protected function uses the GOT as well. That's the remaining concern the IRC discussion.

rafael added inline comments.Mar 30 2016, 7:52 AM
include/llvm/IR/GlobalValue.h
371

The spec says:

  • all of the non-default visibility attributes, when applied to a symbol reference, imply that a definition to satisfy that reference must be provided within the current executable or shared object.

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

declare void @somewhere()
define void @here() { ret void }
define void @use() {
  call void @here()
  call void @somewhere()
  ret void
}

We would get:

  • -relocation-model=pic:
callq   here@PLT
callq   somewhere@PLT
  • -relocation-model=static:
callq   here
callq   somewhere
  • -relocation-model=static -mno-copy-reloc:
callq   here
callq   somewhere@PLT

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.

emaste added a subscriber: emaste.Mar 30 2016, 8:18 AM
joerg abandoned this revision.Oct 28 2016, 11:36 AM