This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Don't emit weak undefined symbols in .dynsym for static executables
AbandonedPublic

Authored by MaskRay on Mar 19 2019, 8:42 AM.

Details

Summary

D59275 added the following clause to Symbol::includeInDynsym()

if (isUndefWeak() && Config->Pie && SharedFiles.empty())
  return false;

It seems we don't have to differentiate non-PIE from PIE, thus we can
generalize it to weak undefined symbols in any static executable:

if (!Config->Shared && isUndefWeak() && SharedFiles.empty())
  return false;

Note !Config->Shared && isUndefWeak() is used to decide whether a
relocation which is not a constant at link time should resolve to 0.
This patch adjusts the order of clauses to make the code simpler.

ld.bfd has complex and architecture-varying rules. We try to provide
reasonable semantics to exclude some weak undefined symbols but not be
too smart. Future improvement may include the refinement of
ExportDynamic assignment.

In the updated tests, weak-undef-rw.s is folded into
weak-undef-exported.s as they are checking the same thing except that
the former checks a writable section.

Event Timeline

MaskRay created this revision.Mar 19 2019, 8:42 AM
MaskRay updated this revision to Diff 191316.Mar 19 2019, 8:48 AM

Improve weak-undef-no-shared-libs.s

MaskRay updated this revision to Diff 191319.Mar 19 2019, 8:51 AM
MaskRay retitled this revision from [ELF] Don't emit weak undefined symbols in static executables to [ELF] Don't emit weak undefined symbols in .dynsym for static executables.

Re-title :)

MaskRay added a comment.EditedMar 19 2019, 8:55 AM

I surveyed ld.bfd's architecture-varying rules:

  • x86 uses UNDEFINED_WEAK_RESOLVED_TO_ZERO which basicaly does isLocal() || (!Shared && zero_undefweak). zero_undefweak has two bits:
- Bit 0: Symbol has no GOT nor PLT relocations.
- Bit 1: Symbol has non-GOT/non-PLT relocations in text sections.
  • Other architectures mostly use UNDEFWEAK_NO_DYNAMIC_RELOC which checks Visibility != STV_DEFAULT || dynamic_undefined_weak. The variable has different initial values on different architectures and is controlled by -z {,no-}dynamic-undefined-weak.

The GOT/PLT relocation type differentiation is only implemented on x86.

I definitely missed some rules but just wanted to give you an impression why following it in every corner case is unreasonable :)

I've found a previous attempt that is related: https://reviews.llvm.org/D39392

MaskRay abandoned this revision.Jul 17 2020, 3:20 PM
test/ELF/weak-undef-no-shared-libs.s