[ELF] --emit-relocs: fix a crash if .rela.dyn is an empty output section

Fix PR48357: If .rela.dyn appears as an output section description, its type may
be SHT_RELA (due to the empty synthetic .rela.plt) while there is no input
section. The empty .rela.dyn may be retained due to a reference in a linker
script. Don't crash.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D93367
This commit is contained in:
Fangrui Song 2020-12-16 08:59:38 -08:00
parent b607837c75
commit 16cb7910f5
2 changed files with 22 additions and 1 deletions

View File

@ -418,7 +418,11 @@ void OutputSection::finalize() {
if (!config->copyRelocs || (type != SHT_RELA && type != SHT_REL))
return;
if (isa<SyntheticSection>(first))
// Skip if 'first' is synthetic, i.e. not a section created by --emit-relocs.
// Normally 'type' was changed by 'first' so 'first' should be non-null.
// However, if the output section is .rela.dyn, 'type' can be set by the empty
// synthetic .rela.plt and first can be null.
if (!first || isa<SyntheticSection>(first))
return;
link = in.symTab->getParent()->sectionIndex;

View File

@ -0,0 +1,17 @@
# REQUIRES: x86
## PR48357: If .rela.dyn appears as an output section description, its type may
## be SHT_RELA (due to the empty synthetic .rela.plt) while there is no input
## section. The empty .rela.dyn may be retained due to a reference. Don't crash.
# RUN: llvm-mc -filetype=obj -triple=x86_64 /dev/null -o %t.o
# RUN: ld.lld -shared --emit-relocs -T %s %t.o -o %t
# RUN: llvm-readelf -S %t | FileCheck %s
## Note, sh_link of such an empty .rela.dyn is 0.
# CHECK: Name Type Address Off Size ES Flg Lk Inf Al
# CHECK: .rela.dyn RELA 0000000000000000 001000 000000 18 A 0 0 8
SECTIONS {
.rela.dyn : { *(.rela*) }
__rela_offset = ABSOLUTE(ADDR(.rela.dyn));
}