From 503bc5f66111f7e4fc79972bb9bfec8bb5606bab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 4 Oct 2023 10:54:50 +0300 Subject: [PATCH] [LLD] [COFF] Fix handling of comdat .drectve sections (#68116) This can happen when manually emitting strings into .drectve sections with `__attribute__((section(".drectve")))`, which is a way to emulate `#pragma comment(linker, "...")` for mingw compilers, without requiring building with -fms-extensions. Normally, this doesn't generate any comdat, but if compiled with -fsanitize=address, this section does get turned into a comdat section. This fixes #67261. This issue can be seen as a regression; a change in the "lli" tool in 17.x triggers this case, if compiled with ASAN enabled, triggering this unsupported corner case in LLD. With this change, LLD can handle it. --- lld/COFF/InputFiles.cpp | 2 ++ lld/test/COFF/comdat-drectve.s | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 lld/test/COFF/comdat-drectve.s diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index 541837a7fcec..a7a08fb2fa6e 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -661,6 +661,8 @@ std::optional ObjFile::createDefined( if (prevailing) { SectionChunk *c = readSection(sectionNumber, def, getName()); sparseChunks[sectionNumber] = c; + if (!c) + return nullptr; c->sym = cast(leader); c->selection = selection; cast(leader)->data = &c->repl; diff --git a/lld/test/COFF/comdat-drectve.s b/lld/test/COFF/comdat-drectve.s new file mode 100644 index 000000000000..6f96a8709fc7 --- /dev/null +++ b/lld/test/COFF/comdat-drectve.s @@ -0,0 +1,31 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj + +# RUN: lld-link %t.obj -out:%t.exe -debug:symtab -subsystem:console +# RUN: llvm-readobj --coff-exports %t.exe | FileCheck %s + +# CHECK: Name: exportedFunc + +## This assembly snippet has been reduced from what Clang generates from +## this C snippet, with -fsanitize=address. Normally, the .drectve +## section would be a regular section - but when compiled with +## -fsanitize=address, it becomes a comdat section. +## +# void exportedFunc(void) {} +# void mainCRTStartup(void) {} +# static __attribute__((section(".drectve"), used)) const char export_chkstk[] = +# "-export:exportedFunc"; + + .text + .globl exportedFunc +exportedFunc: + retq + + .globl mainCRTStartup +mainCRTStartup: + retq + + .section .drectve,"dr",one_only,export_chkstk +export_chkstk: + .asciz "-export:exportedFunc"