Robert Schilling via llvm-dev
2018-Jan-27 10:14 UTC
[llvm-dev] [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. Thanks! Cheers, Robert