[lld] Garbage collection of linked sections with the SHF_LINK_ORDER flag

Hi folks,

Our LLVM compiler creates a special debug section, which depends on a certain
text section. This debug section is created with the SHF_LINK_ORDER flag, and
sh_link field in the section header points to the correct section.

When linking the program with the linker flag '-gc-sections', lld can garbage-
collect unused sections. In my case, the text section is correctly garbage-
collected. However, the linked debug section remains in the program and
relocations in these debug sections are invalid.

I found the following Google groups thread on the Generic System V ABI mailing
list (https://groups.google.com/d/msg/generic-abi/_CbBM6T6WeM/eGF9A0AnAAAJ),
which also discusses this topic. In particular, it is discussing the following
change to the description of SHF_LINK_ORDER flag:

"When performing unused section elimination, the link editor should
ensure that both the section and the referenced section are retained
or discarded together."

This sentence makes sense to me, and I assumed lld works like this.

When looking through the code of lld, I found that in MarkLive::markLive(), the
liveness of parent sections is not propagated to the child sections. Instead,
it is marked as live resulting that the section is kept even though the parent
section is removed.

To fix this issue, I propose changing the code marking sections live to
the following loop:

for (InputSectionBase *Sec : InputSections) {
if (Sec->Flags & SHF_LINK_ORDER)
Sec->Live = Sec->getLinkOrderDep()->Live;
else {
bool IsAlloc = (Sec->Flags & SHF_ALLOC);
bool IsRel = (Sec->Type == SHT_REL || Sec->Type == SHT_RELA);
if (!IsAlloc && !IsRel)
Sec->Live = true;

If an input section has the SHF_LINK_ORDER flag set, it propagates the liveness
of this section to the parent. This allows the garbage collector to also remove
children sections if dependent parent sections are marked to be removed.

I found a similar code already inside lld. There is a special case for ARM.
When ICF being enabled, this live propagation of linked sections is already
performed for ARM targets in ICF::run(). However, I think this makes sense
also for other targets.

I am new to lld and may not know all implications of the SHF_LINK_ORDER flag
or what implications my proposed change may has. Can someone help me in
understanding what's the expected behavior and if my change makes sense?

If so, I am happy to make an upstream patch.