[ELF] Fix .gnu.version crash when .dynsym is discarded

Fix #88650

In addition, delete the unneeded comment.
https://sourceware.org/gnu-gabi/program-loading-and-dynamic-linking.txt
This commit is contained in:
Fangrui Song 2025-01-02 18:46:44 -08:00
parent e8cf41311f
commit 510a5c7fc2
2 changed files with 28 additions and 10 deletions

View File

@ -3798,9 +3798,8 @@ VersionTableSection::VersionTableSection(Ctx &ctx)
}
void VersionTableSection::finalizeContents() {
// At the moment of june 2016 GNU docs does not mention that sh_link field
// should be set, but Sun docs do. Also readelf relies on this field.
getParent()->link = getPartition(ctx).dynSymTab->getParent()->sectionIndex;
if (OutputSection *osec = getPartition(ctx).dynSymTab->getParent())
getParent()->link = osec->sectionIndex;
}
size_t VersionTableSection::getSize() const {

View File

@ -1,24 +1,43 @@
# REQUIRES: aarch64
## We allow discarding .dynsym, check we don't crash.
# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
# RUN: rm -rf %t && split-file %s %t && cd %t
# RUN: llvm-mc -filetype=obj -triple=aarch64 a.s -o a.o
# RUN: llvm-mc -filetype=obj -triple=aarch64 c.s -o c.o
# RUN: ld.lld -shared --version-script=c.ver c.o -o c.so
# RUN: echo 'SECTIONS { /DISCARD/ : { *(.dynsym) } }' > %t.lds
# RUN: ld.lld -shared -T %t.lds %t.o -o %t.so
# RUN: llvm-readelf -r %t.so | FileCheck %s
# RUN: echo 'SECTIONS { /DISCARD/ : { *(.dynsym) } }' > 1.lds
# RUN: ld.lld -shared -T 1.lds a.o c.so -o out1.so
# RUN: llvm-readelf -Sr out1.so | FileCheck %s --check-prefixes=CHECK,CHECK1
# RUN: echo 'SECTIONS { /DISCARD/ : { *(.dynsym .dynstr) } }' > %t.lds
# RUN: ld.lld -shared -T %t.lds %t.o -o %t.so
# RUN: llvm-readelf -r %t.so | FileCheck %s
# RUN: echo 'SECTIONS { /DISCARD/ : { *(.dynsym .dynstr) } }' > 2.lds
# RUN: ld.lld -shared -T 2.lds a.o c.so -o out2.so
# RUN: llvm-readelf -Sr out2.so | FileCheck %s --check-prefixes=CHECK,CHECK2
# CHECK: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
# CHECK-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
# CHECK-NEXT: [ 1] .gnu.version VERSYM 0000000000000000 {{.*}} 000006 02 A 0 0 2
# CHECK1-NEXT: [ 2] .gnu.version_r VERNEED 0000000000000008 {{.*}} 000020 00 A 5 1 4
# CHECK2-NEXT: [ 2] .gnu.version_r VERNEED 0000000000000008 {{.*}} 000020 00 A 0 1 4
# CHECK1: [ 5] .dynstr STRTAB
# CHECK: contains 2 entries:
# CHECK: R_AARCH64_RELATIVE [[#]]
# CHECK-NEXT: R_AARCH64_GLOB_DAT 0{{$}}
#--- a.s
adrp x9, :got:var
ldr x9, [x9, :got_lo12:var]
bl __libc_start_main
.data
.align 8
foo:
.quad foo
#--- c.s
.globl __libc_start_main
__libc_start_main:
#--- c.ver
GLIBC_2.34 { __libc_start_main; };