Index: lld/trunk/ELF/InputFiles.cpp =================================================================== --- lld/trunk/ELF/InputFiles.cpp +++ lld/trunk/ELF/InputFiles.cpp @@ -645,8 +645,16 @@ // This section contains relocation information. // If -r is given, we do not interpret or apply relocation // but just copy relocation sections to output. - if (Config->Relocatable) - return make(*this, Sec, Name); + if (Config->Relocatable) { + InputSection *RelocSec = make(*this, Sec, Name); + // We want to add a dependency to target, similar like we do for + // -emit-relocs below. This is useful for the case when linker script + // contains the "/DISCARD/". It is perhaps uncommon to use a script with + // -r, but we faced it in the Linux kernel and have to handle such case + // and not to crash. + Target->DependentSections.push_back(RelocSec); + return RelocSec; + } if (Target->FirstRelocation) fatal(toString(this) + Index: lld/trunk/ELF/InputSection.cpp =================================================================== --- lld/trunk/ELF/InputSection.cpp +++ lld/trunk/ELF/InputSection.cpp @@ -432,8 +432,8 @@ error("STT_SECTION symbol should be defined"); continue; } - SectionBase *Section = D->Section; - if (Section == &InputSection::Discarded) { + SectionBase *Section = D->Section->Repl; + if (!Section->Live) { P->setSymbolAndType(0, 0, false); continue; } @@ -460,7 +460,7 @@ } if (RelTy::IsRela) - P->r_addend = Sym.getVA(Addend) - Section->Repl->getOutputSection()->Addr; + P->r_addend = Sym.getVA(Addend) - Section->getOutputSection()->Addr; else if (Config->Relocatable) Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Addend, &Sym}); } Index: lld/trunk/test/ELF/linkerscript/relocatable-discard.s =================================================================== --- lld/trunk/test/ELF/linkerscript/relocatable-discard.s +++ lld/trunk/test/ELF/linkerscript/relocatable-discard.s @@ -0,0 +1,21 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { /DISCARD/ : { *(.discard.*) }}" > %t.script +# RUN: ld.lld -o %t --script %t.script -r %t.o +# RUN: llvm-readobj -sections %t | FileCheck %s + +## Test shows that we do not crash after discarding the .discard.foo with -r. +## Previously it happened because of 2 reasons: +## 1) .rela.discard.foo was not handled properly and was not discarded. +## Remaining reference was invalid and caused the crash. +## 2) Third-party section .debug_info referencing discarded section +## did not handle this case properly and tried to apply the +## relocation instead of ignoring it. + +# CHECK-NOT: .discard + +.section .discard.foo,"ax" +callq fn@PLT + +.section .debug_info,"",@progbits +.long .discard.foo