Skip to content

Commit 31275d4

Browse files
committed
COFF: Correctly handle relocations against early discarded sections.
Don't crash if we encounter a reference to an early discarded section (such as .drectve). Instead, handle them the same way as sections discarded by comdat merging, i.e. either print an error message or (for debug sections) silently ignore the relocation. Differential Revision: https://reviews.llvm.org/D40235 llvm-svn: 318689
1 parent 2521937 commit 31275d4

File tree

4 files changed

+34
-3
lines changed

4 files changed

+34
-3
lines changed

lld/COFF/Chunks.cpp

+15-2
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,19 @@ void SectionChunk::writeTo(uint8_t *Buf) const {
252252
// Get the output section of the symbol for this relocation. The output
253253
// section is needed to compute SECREL and SECTION relocations used in debug
254254
// info.
255-
Defined *Sym = cast<Defined>(File->getSymbol(Rel.SymbolTableIndex));
255+
auto *Sym =
256+
dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
257+
if (!Sym) {
258+
if (isCodeView() || isDWARF())
259+
continue;
260+
// Symbols in early discarded sections are represented using null pointers,
261+
// so we need to retrieve the name from the object file.
262+
COFFSymbolRef Sym =
263+
check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex));
264+
StringRef Name;
265+
File->getCOFFObj()->getSymbolName(Sym, Name);
266+
fatal("relocation against symbol in discarded section: " + Name);
267+
}
256268
Chunk *C = Sym->getChunk();
257269
OutputSection *OS = C ? C->getOutputSection() : nullptr;
258270

@@ -328,7 +340,8 @@ void SectionChunk::getBaserels(std::vector<Baserel> *Res) {
328340
uint8_t Ty = getBaserelType(Rel);
329341
if (Ty == IMAGE_REL_BASED_ABSOLUTE)
330342
continue;
331-
if (isa<DefinedAbsolute>(File->getSymbol(Rel.SymbolTableIndex)))
343+
Symbol *Target = File->getSymbol(Rel.SymbolTableIndex);
344+
if (!Target || isa<DefinedAbsolute>(Target))
332345
continue;
333346
Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
334347
}

lld/COFF/MarkLive.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ void markLive(const std::vector<Chunk *> &Chunks) {
6363

6464
// Mark all symbols listed in the relocation table for this section.
6565
for (Symbol *B : SC->symbols())
66-
AddSym(B);
66+
if (B)
67+
AddSym(B);
6768

6869
// Mark associative sections if any.
6970
for (SectionChunk *C : SC->children())

lld/test/COFF/reloc-discarded-early.s

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
2+
# RUN: lld-link -entry:__ImageBase -subsystem:console -debug %t.obj
3+
4+
.section .debug_info,"dr"
5+
.quad .Ldrectve
6+
7+
.section .drectve
8+
.Ldrectve:
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
2+
# RUN: not lld-link -entry:__ImageBase -subsystem:console %t.obj 2>&1 | FileCheck %s
3+
4+
.text
5+
# CHECK: error: relocation against symbol in discarded section: .drectve
6+
.quad .Ldrectve
7+
8+
.section .drectve
9+
.Ldrectve:

0 commit comments

Comments
 (0)