[lld] [LLD][COFF] add __{data,bss}_{start,end}__ symbols for Cygwin support (PR #136180)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 17 11:49:48 PDT 2025
https://github.com/jeremyd2019 created https://github.com/llvm/llvm-project/pull/136180
Cygwin requires these symbols for its fork emulation to know what data to copy into the child. GNU ld defines these symbols for MinGW targets also, so do the same here.
/cc @mstorsjo
>From 7b71533512ed2678eaaa41a00b19e5b01b27b7ea Mon Sep 17 00:00:00 2001
From: Jeremy Drake <github at jdrake.com>
Date: Sun, 13 Apr 2025 22:41:05 -0700
Subject: [PATCH] [LLD][COFF] add __{data,bss}_{start,end}__ symbols for Cygwin
support
Cygwin requires these symbols for its fork emulation to know what data
to copy into the child. GNU ld defines these symbols for MinGW targets
also, so do the same here.
Signed-off-by: Jeremy Drake <github at jdrake.com>
---
lld/COFF/Driver.cpp | 5 +++++
lld/COFF/Writer.cpp | 33 +++++++++++++++++++++++++++++++--
2 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 7aa13bdce488e..72e25634c19d8 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -2039,6 +2039,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
parseMerge(".ctors=.rdata");
parseMerge(".dtors=.rdata");
parseMerge(".CRT=.rdata");
+ parseMerge(".data_cygwin_nocopy=.data");
}
// Handle /section
@@ -2495,6 +2496,10 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (config->mingw) {
symtab.addAbsolute(symtab.mangle("__CTOR_LIST__"), 0);
symtab.addAbsolute(symtab.mangle("__DTOR_LIST__"), 0);
+ symtab.addAbsolute("__data_start__", 0);
+ symtab.addAbsolute("__data_end__", 0);
+ symtab.addAbsolute("__bss_start__", 0);
+ symtab.addAbsolute("__bss_end__", 0);
}
if (config->debug || config->buildIDHash != BuildIDHash::None)
if (symtab.findUnderscore("__buildid"))
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 6ed1f884a9636..32a480e3126e2 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -239,6 +239,7 @@ class Writer {
void createRuntimePseudoRelocs();
void createECChunks();
void insertCtorDtorSymbols();
+ void insertBssDataStartEndSymbols();
void markSymbolsWithRelocations(ObjFile *file, SymbolRVASet &usedSymbols);
void createGuardCFTables();
void markSymbolsForRVATable(ObjFile *file,
@@ -314,6 +315,7 @@ class Writer {
OutputSection *textSec;
OutputSection *hexpthkSec;
+ OutputSection *bssSec;
OutputSection *rdataSec;
OutputSection *buildidSec;
OutputSection *dataSec;
@@ -1077,7 +1079,7 @@ void Writer::createSections() {
textSec = createSection(".text", code | r | x);
if (isArm64EC(ctx.config.machine))
hexpthkSec = createSection(".hexpthk", code | r | x);
- createSection(".bss", bss | r | w);
+ bssSec = createSection(".bss", bss | r | w);
rdataSec = createSection(".rdata", data | r);
buildidSec = createSection(".buildid", data | r);
dataSec = createSection(".data", data | r | w);
@@ -1260,8 +1262,10 @@ void Writer::createMiscChunks() {
if (config->autoImport)
createRuntimePseudoRelocs();
- if (config->mingw)
+ if (config->mingw) {
insertCtorDtorSymbols();
+ insertBssDataStartEndSymbols();
+ }
}
// Create .idata section for the DLL-imported symbol table.
@@ -2369,6 +2373,31 @@ void Writer::insertCtorDtorSymbols() {
}
}
+// MinGW (really, Cygwin) specific.
+// The Cygwin startup code uses __data_start__ __data_end__ __bss_start__
+// and __bss_end__ to know what to copy during fork emulation.
+void Writer::insertBssDataStartEndSymbols() {
+ if (!dataSec->chunks.empty()) {
+ Symbol *dataStartSym = ctx.symtab.find("__data_start__");
+ Symbol *dataEndSym = ctx.symtab.find("__data_end__");
+ Chunk *endChunk = dataSec->chunks.back();
+ replaceSymbol<DefinedSynthetic>(dataStartSym, dataStartSym->getName(),
+ dataSec->chunks.front());
+ replaceSymbol<DefinedSynthetic>(dataEndSym, dataEndSym->getName(), endChunk,
+ endChunk->getSize());
+ }
+
+ if (!bssSec->chunks.empty()) {
+ Symbol *bssStartSym = ctx.symtab.find("__bss_start__");
+ Symbol *bssEndSym = ctx.symtab.find("__bss_end__");
+ Chunk *endChunk = bssSec->chunks.back();
+ replaceSymbol<DefinedSynthetic>(bssStartSym, bssStartSym->getName(),
+ bssSec->chunks.front());
+ replaceSymbol<DefinedSynthetic>(bssEndSym, bssEndSym->getName(), endChunk,
+ endChunk->getSize());
+ }
+}
+
// Handles /section options to allow users to overwrite
// section attributes.
void Writer::setSectionPermissions() {
More information about the llvm-commits
mailing list