This is PR34512.
We crashed when --emit-relocs was used
and relocated section was collected by GC.
Details
Diff Detail
Event Timeline
I don't think this patch addresses the root cause of the issue. All sections passed to addInputSec should be live. If it should be considered dead by gc, it should be marked as such before reaching here. This patch seems to hide the issue instead of fixing it.
If that should be true, then why first lines of 'addInputSec' returns (and report discarded sections actually) when sections are not live ?
void OutputSectionFactory::addInputSec(InputSectionBase *IS, StringRef OutsecName, OutputSection *&Sec) { if (!IS->Live) { reportDiscarded(IS); return; }
What about D37735 ? It should allow to move reportDiscarded out or at least
calls it earlier, what should help this patch hopefully.
I think instead of "fixing" a concrete bug, you want to think more abstractly and focus on an invariant at each stage of linking. Invariants are abstract concepts but important to make program easier to understand. One invariant in lld is that, if some section is not marked as "live" after GC, it should be actually live, and it should be emitted to the output file.
A situation like "this section is not marked as live, but this is actually dead because a section that the section depends on is marked as dead by gc" is not ok. That is a violation of the invariant and needs fixing.
- Addressed review comment.
Note: D37735 should be landed first for allowing this to work properly. Because at next line:
https://github.com/llvm-mirror/lld/blob/master/ELF/OutputSections.cpp#L230
code would try to access to null pointer Out, when it should just report discarded end return at the begining of addSection method.
ELF/InputSection.cpp | ||
---|---|---|
86–88 | This is too magical that it needs comment. |
- Addressed review comment.
ELF/InputSection.cpp | ||
---|---|---|
86–88 | Oh, I am sorry, looks I put = instead of |= at last minute by mistake. |
ELF/InputSection.cpp | ||
---|---|---|
86–88 | It is better to define a helper function. You can use this. // Return true if a section with given section flags is live (will never be // GCed) by default. If a section can be GCed, this function returns false. static bool isLiveByDefault(uint64_t Flags, uint32_t Type) { // If GC is enabled, all memory-mapped sections are subject of GC. if (!Config->GcSections) return true; if (Flags & SHF_ALLOC) return false; // Besides that, relocation sections can also be GCed because their // relocation target sections may be GCed. This doesn't really matter // in most cases because the linker usually consumes relocation // sections instead of emitting them, but -emit-reloc needs this. return Type != SHT_REL && Type != SHT_RELA; } |
This is too magical that it needs comment.