From f0a687d821c151b23013da75296be369a4c420d3 Mon Sep 17 00:00:00 2001 From: =?utf8?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. (cherry picked from commit 503bc5f66111f7e4fc79972bb9bfec8bb5606bab) --- 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 541837a..a7a08fb 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 0000000..6f96a87 --- /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" -- 2.7.4