[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() { void VersionTableSection::finalizeContents() {
// At the moment of june 2016 GNU docs does not mention that sh_link field if (OutputSection *osec = getPartition(ctx).dynSymTab->getParent())
// should be set, but Sun docs do. Also readelf relies on this field. getParent()->link = osec->sectionIndex;
getParent()->link = getPartition(ctx).dynSymTab->getParent()->sectionIndex;
} }
size_t VersionTableSection::getSize() const { size_t VersionTableSection::getSize() const {

View File

@ -1,24 +1,43 @@
# REQUIRES: aarch64 # REQUIRES: aarch64
## We allow discarding .dynsym, check we don't crash. ## 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: echo 'SECTIONS { /DISCARD/ : { *(.dynsym) } }' > 1.lds
# RUN: ld.lld -shared -T %t.lds %t.o -o %t.so # RUN: ld.lld -shared -T 1.lds a.o c.so -o out1.so
# RUN: llvm-readelf -r %t.so | FileCheck %s # RUN: llvm-readelf -Sr out1.so | FileCheck %s --check-prefixes=CHECK,CHECK1
# RUN: echo 'SECTIONS { /DISCARD/ : { *(.dynsym .dynstr) } }' > %t.lds # RUN: echo 'SECTIONS { /DISCARD/ : { *(.dynsym .dynstr) } }' > 2.lds
# RUN: ld.lld -shared -T %t.lds %t.o -o %t.so # RUN: ld.lld -shared -T 2.lds a.o c.so -o out2.so
# RUN: llvm-readelf -r %t.so | FileCheck %s # 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: contains 2 entries:
# CHECK: R_AARCH64_RELATIVE [[#]] # CHECK: R_AARCH64_RELATIVE [[#]]
# CHECK-NEXT: R_AARCH64_GLOB_DAT 0{{$}} # CHECK-NEXT: R_AARCH64_GLOB_DAT 0{{$}}
#--- a.s
adrp x9, :got:var adrp x9, :got:var
ldr x9, [x9, :got_lo12:var] ldr x9, [x9, :got_lo12:var]
bl __libc_start_main
.data .data
.align 8 .align 8
foo: foo:
.quad foo .quad foo
#--- c.s
.globl __libc_start_main
__libc_start_main:
#--- c.ver
GLIBC_2.34 { __libc_start_main; };