[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 08:03:14 PDT 2023
https://github.com/mstorsjo created https://github.com/llvm/llvm-project/pull/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.
>From 04fa119369fcb756a1b03b3d511a6888c74c7a94 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 | 13 +++++++++----
lld/test/COFF/comdat-drectve.s | 31 +++++++++++++++++++++++++++++++
2 files changed, 40 insertions(+), 4 deletions(-)
create mode 100644 lld/test/COFF/comdat-drectve.s
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 541837a7fceca72..0b0fa4ae3bab868 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -660,10 +660,15 @@ std::optional<Symbol *> ObjFile::createDefined(
if (prevailing) {
SectionChunk *c = readSection(sectionNumber, def, getName());
- sparseChunks[sectionNumber] = c;
- c->sym = cast<DefinedRegular>(leader);
- c->selection = selection;
- cast<DefinedRegular>(leader)->data = &c->repl;
+ if (c) {
+ sparseChunks[sectionNumber] = c;
+ c->sym = cast<DefinedRegular>(leader);
+ c->selection = selection;
+ cast<DefinedRegular>(leader)->data = &c->repl;
+ } else {
+ sparseChunks[sectionNumber] = nullptr;
+ return nullptr;
+ }
} else {
sparseChunks[sectionNumber] = nullptr;
}
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