This is an archive of the discontinued LLVM Phabricator instance.

ELF: Give automatically generated __start_* and __stop_* symbols hidden visibility.
ClosedPublic

Authored by pcc on Apr 12 2016, 11:11 AM.

Details

Summary

These symbols describe a property of a linkage unit, so it seems reasonable
to limit their visibility to the linkage unit. Furthermore the use cases I
am aware of do not require more than hidden visibility.

This is a departure from the behavior of the bfd and gold linkers. However,
it is unclear that the decision to give these symbols default visibility
in those linkers was made deliberately. The start_*/stop_* feature
was added to the bfd linker in 1994 [1], while the visibility feature was
added about five years later [2], so it may have been that the visibility
of these symbols was not considered. The feature was implemented in gold
[3] in the same way; the behavior may have simply been copied from bfd.

The only related discussion I could find on the binutils mailing list [4]
was a user issue which would most likely not have occurred if the symbols
had hidden visibility.

[1] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=5efddb2e7c3229b569a862205f61d42860af678b
[2] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=0fc731e447cd01e7fc35197b487ff0e4fd25afca
[3] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=bfd58944a64b0997a310b95fbe0423338961e71c
[4] https://sourceware.org/ml/binutils/2014-05/msg00011.html

Diff Detail

Repository
rL LLVM

Event Timeline

pcc updated this revision to Diff 53433.Apr 12 2016, 11:11 AM
pcc retitled this revision from to ELF: Give automatically generated __start_* and __stop_* symbols hidden visibility..
pcc updated this object.
pcc added reviewers: rafael, ruiu.
pcc added a subscriber: llvm-commits.
ruiu edited edge metadata.Apr 12 2016, 12:00 PM

Software archaeology is always interesting, and I agree with you that not making these symbols hidden was by accident. I'm not against doing this, but do you have any specific motivation of doing this?

pcc added a comment.Apr 12 2016, 12:33 PM

I tracked down breakage in one of Chromium's test binaries to code that was doing something like this (in both an executable and a DSO):

__attribute__((section("foo"))) void f() { .... }

void g() {
  ... __start_foo ...
}

In this case, the definition of __start_foo in the executable was coming from the DSO because we only check for undefined symbols when creating the synthetic symbol. If the executable is non-PIC, we cannot relocate the reference to __start_foo in g correctly, and we end up emitting a dynamic relocation for the .text section which causes a segfault at startup.

One way we could solve that problem is by replacing shared definitions with our synthetic symbols (that would make the behavior consistent with other synthetic symbols). But separate from that, I had to ask myself why we are making these symbols default visible in the first place, and I could not see a good reason.

ruiu accepted this revision.Apr 12 2016, 1:02 PM
ruiu edited edge metadata.

LGTM.

Thank you for the explanation, and I agree that this is essentially the direction we'd like to see (eliminating a problem from the root cause instead of resolving a problem by adding more and more features). Let's give it a shot.

This revision is now accepted and ready to land.Apr 12 2016, 1:02 PM
This revision was automatically updated to reflect the committed changes.