[lld] [LLD] [COFF] Fix handling of comdat .drectve sections (PR #68116)

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 3 10:23:03 PDT 2023


https://github.com/mstorsjo updated https://github.com/llvm/llvm-project/pull/68116

>From ba36114f0904e5e8112d4f210e5df0c0038a6efe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Tue, 3 Oct 2023 15:04:40 +0300
Subject: [PATCH] [LLD] [COFF] Fix handling of comdat .drectve sections

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 541837a7fceca72..a7a08fb2fa6ea50 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -661,6 +661,8 @@ std::optional<Symbol *> ObjFile::createDefined(
     if (prevailing) {
       SectionChunk *c = readSection(sectionNumber, def, getName());
       sparseChunks[sectionNumber] = c;
+      if (!c)
+        return nullptr;
       c->sym = cast<DefinedRegular>(leader);
       c->selection = selection;
       cast<DefinedRegular>(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 000000000000000..6f96a8709fc7703
--- /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"



More information about the llvm-commits mailing list