This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Simplify the condition to create .interp
ClosedPublic

Authored by MaskRay on May 31 2019, 7:20 PM.

Details

Summary

(1) {gcc,clang} -fuse-ld=bfd -pie -fPIE -nostdlib a.c => .interp created
(2) {gcc,clang} -fuse-ld=lld -pie -fPIE -nostdlib a.c => .interp not created
(3) {gcc,clang} -fuse-ld=lld -pie -fPIE -nostdlib a.c a.so => .interp created

The inconsistency of (2) is due to the condition !Config->SharedFiles.empty().
To make lld behave more like ld.bfd, we could change the condition to:

Config->HasDynSymTab && !Config->DynamicLinker.empty() && Script->needsInterpSection();

However, that would bring another inconsistency as can be observed with:

(4) {gcc,clang} -fuse-ld=bfd -no-pie -nostdlib a.c => .interp not created

So instead, use !Config->DynamicLinker.empty() && Script->needsInterpSection(),
which is both simple and consistent in these cases.

The inconsistency likely originated from ld.bfd and gold's choice to
have a default --dynamic-linker. Their condition to create .interp is
ANDed with (not -shared). Since lld doesn't have a default
--dynamic-linker, and compiler drivers (gcc/clang) don't pass
--dynamic-linker with -shared, we do not need the condition
Config->Shared. For direct ld users, they are not suppoped to specify
--dynamic-linker for a -shared link.

Event Timeline

MaskRay created this revision.May 31 2019, 7:20 PM
MaskRay updated this revision to Diff 202580.Jun 1 2019, 8:05 PM
MaskRay edited the summary of this revision. (Show Details)

Reword

ruiu accepted this revision.Jun 2 2019, 9:34 PM

LGTM

I'm a little curious about the motivation of this change. Did this incompatibility cause a practical issue, or are you just fixing a disparity?

This revision is now accepted and ready to land.Jun 2 2019, 9:34 PM

I'm a little curious about the motivation of this change. Did this incompatibility cause a practical issue, or are you just fixing a disparity?

I noticed this before but didn't think hard about it.

I rediscovered it while playing with -static-pie. ld.bfd has a --no-dynamic-linker (added in 2015) to suppress its default --dynamic-linker. It would not have been useful if ld.bfd didn't have the default --dynamic-linker in the first place... I guess our !SharedFiles.empty() was probably a mistake of copying gold's behavior (it should check !Config->Shared instead)

      if ((!parameters->options().shared()
	   || parameters->options().dynamic_linker() != NULL)
	  && this->interp_segment_ == NULL)

Our current rule precludes a dynamically linked executable with no DT_NEEDED. Such executables may be created by -nostdlib. I would not bother supporting this use case if the change required more code.

This revision was automatically updated to reflect the committed changes.