(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 have somebring another inconsistency: as can be observed with:
(4) {gcc,clang} -fuse-ld=bfd -no-pie -nostdlib a.c => .interp not created
In contrastSo instead, use `!Config->DynamicLinker.empty() && Script->needsInterpSection()`,
which is both simple and consistent in these cases.
In ld.bfd and gold, the condition to create .interp is ANDed with (notThe inconsistency likely originated from ld.bfd and gold's choice to
-shared). That is because they have default --dynamic-linker. Sincehave a default --dynamic-linker. Their condition to create .interp is
lld doesn't have default --dynamic-linker,ANDed with (not -shared). and compiler driversSince lld doesn't have a default
(gcc/clang) don't pass --dynamic-linker with -sharedr, we do not need theand compiler drivers (gcc/clang) don't pass
condition Config->Shared. In addition--dynamic-linker with -shared, Direct ld users should notwe do not need the condition
Config->Shared. For direct ld users, they are not suppoped to specify
--dynamic-linker for a -shared link.