Skip to content

Commit 9c970d5

Browse files
authored
[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.
1 parent bd7b170 commit 9c970d5

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
@@ -648,6 +648,13 @@ void SectionChunk::getRuntimePseudoRelocs(
648648
dyn_cast_or_null<Defined>(file->getSymbol(rel.SymbolTableIndex));
649649
if (!target || !target->isRuntimePseudoReloc)
650650
continue;
651+
// If the target doesn't have a chunk allocated, it may be a
652+
// DefinedImportData symbol which ended up unnecessary after GC.
653+
// Normally we wouldn't eliminate section chunks that are referenced, but
654+
// references within DWARF sections don't count for keeping section chunks
655+
// alive. Thus such dangling references in DWARF sections are expected.
656+
if (!target->getChunk())
657+
continue;
651658
int sizeInBits =
652659
getRuntimePseudoRelocSize(rel.Type, file->ctx.config.machine);
653660
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)