Skip to content

Commit 995539c

Browse files
mstorsjotstellar
authored andcommitted
[LLD] [COFF] Don't add pseudo relocs for dangling references (#88487)
When doing GC, we normally won't have dangling references, because such a reference would keep the other section alive, keeping it from being eliminated. However, references within DWARF sections are ignored for the purposes of GC (because otherwise, they would essentially keep everything alive, defeating the point of the GC), see c579a5b for more context. Therefore, dangling relocations against discarded symbols are ignored within DWARF sections (see maybeReportRelocationToDiscarded in Chunks.cpp). Consequently, we also shouldn't create any pseudo relocations for these cases, as we run into a null pointer dereference when trying to generate the pseudo relocation info for it. This fixes the downstream bug mstorsjo/llvm-mingw#418, fixing crashes on combinations with -ffunction-sections, -fdata-sections, -Wl,--gc-sections and debug info. (cherry picked from commit 9c970d5)
1 parent db67e6f commit 995539c

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

lld/COFF/Chunks.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,13 @@ void SectionChunk::getRuntimePseudoRelocs(
652652
dyn_cast_or_null<Defined>(file->getSymbol(rel.SymbolTableIndex));
653653
if (!target || !target->isRuntimePseudoReloc)
654654
continue;
655+
// If the target doesn't have a chunk allocated, it may be a
656+
// DefinedImportData symbol which ended up unnecessary after GC.
657+
// Normally we wouldn't eliminate section chunks that are referenced, but
658+
// references within DWARF sections don't count for keeping section chunks
659+
// alive. Thus such dangling references in DWARF sections are expected.
660+
if (!target->getChunk())
661+
continue;
655662
int sizeInBits =
656663
getRuntimePseudoRelocSize(rel.Type, file->ctx.config.machine);
657664
if (sizeInBits == 0) {

lld/test/COFF/autoimport-gc.s

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# REQUIRES: x86
2+
# RUN: split-file %s %t.dir
3+
4+
# RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/lib.s -filetype=obj -o %t.dir/lib.obj
5+
# RUN: lld-link -out:%t.dir/lib.dll -dll -entry:DllMainCRTStartup %t.dir/lib.obj -lldmingw -implib:%t.dir/lib.lib
6+
7+
# RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/main.s -filetype=obj -o %t.dir/main.obj
8+
# RUN: lld-link -lldmingw -out:%t.dir/main.exe -entry:main %t.dir/main.obj %t.dir/lib.lib -opt:ref -debug:dwarf
9+
10+
#--- main.s
11+
.global main
12+
.section .text$main,"xr",one_only,main
13+
main:
14+
ret
15+
16+
.global other
17+
.section .text$other,"xr",one_only,other
18+
other:
19+
movq .refptr.variable(%rip), %rax
20+
movl (%rax), %eax
21+
ret
22+
23+
.section .rdata$.refptr.variable,"dr",discard,.refptr.variable
24+
.global .refptr.variable
25+
.refptr.variable:
26+
.quad variable
27+
28+
.section .debug_info
29+
.long 1
30+
.quad variable
31+
.long 2
32+
33+
#--- lib.s
34+
.global variable
35+
.global DllMainCRTStartup
36+
.text
37+
DllMainCRTStartup:
38+
ret
39+
.data
40+
variable:
41+
.long 42

0 commit comments

Comments
 (0)