Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[LLD][COFF] add __{data,bss}_{start,end}__ symbols for Cygwin support #136180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lld/COFF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2028,6 +2028,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
parseMerge(".ctors=.rdata");
parseMerge(".dtors=.rdata");
parseMerge(".CRT=.rdata");
parseMerge(".data_cygwin_nocopy=.data");
}

// Handle /section
Expand Down Expand Up @@ -2484,6 +2485,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"))
Expand Down
33 changes: 31 additions & 2 deletions lld/COFF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ class Writer {
void createRuntimePseudoRelocs();
void createECChunks();
void insertCtorDtorSymbols();
void insertBssDataStartEndSymbols();
void markSymbolsWithRelocations(ObjFile *file, SymbolRVASet &usedSymbols);
void createGuardCFTables();
void markSymbolsForRVATable(ObjFile *file,
Expand Down Expand Up @@ -315,6 +316,7 @@ class Writer {

OutputSection *textSec;
OutputSection *hexpthkSec;
OutputSection *bssSec;
OutputSection *rdataSec;
OutputSection *buildidSec;
OutputSection *dataSec;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -2381,6 +2385,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() {
Expand Down
99 changes: 99 additions & 0 deletions lld/test/COFF/cygwin-symbols.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# REQUIRES: x86
# RUN: split-file %s %t.dir && cd %t.dir

# RUN: llvm-mc -triple=x86_64-windows-cygnus -filetype=obj -o data-no-bss.obj data-no-bss.s
# RUN: lld-link -lldmingw -entry:main data-no-bss.obj -out:data-no-bss.exe
# RUN: llvm-objdump -s data-no-bss.exe | FileCheck --check-prefix=DATANOBSS %s

# RUN: llvm-mc -triple=x86_64-windows-cygnus -filetype=obj -o bss-no-data.obj bss-no-data.s
# RUN: lld-link -lldmingw -entry:main bss-no-data.obj -out:bss-no-data.exe
# RUN: llvm-objdump -s bss-no-data.exe | FileCheck --check-prefix=BSSNODATA %s

# RUN: llvm-mc -triple=x86_64-windows-cygnus -filetype=obj -o data-and-bss.obj data-and-bss.s
# RUN: lld-link -lldmingw -entry:main data-and-bss.obj -out:data-and-bss.exe
# RUN: llvm-objdump -s data-and-bss.exe | FileCheck --check-prefix=DATAANDBSS %s

#--- data-no-bss.s
.globl main
main:
nop

.data
.quad 1
.byte 2

.section .data_cygwin_nocopy, "w"
.align 4
.quad 3
.byte 4

.section .test, "w"
.quad __data_start__
.quad __data_end__
.quad __bss_start__
.quad __bss_end__

#--- bss-no-data.s
.globl main
main:
nop

.bss
.zero 8192

.section .test, "w"
.quad __data_start__
.quad __data_end__
.quad __bss_start__
.quad __bss_end__

#--- data-and-bss.s
.globl main
main:
nop

.data
.quad 1
.byte 2

.section .data_cygwin_nocopy, "w"
.align 4
.quad 3
.byte 4

.bss
.zero 8192

.section .test, "w"
.quad __data_start__
.quad __data_end__
.quad __bss_start__
.quad __bss_end__

# DATANOBSS: Contents of section .data:
# DATANOBSS-NEXT: 140003000 01000000 00000000 02000000 03000000
# DATANOBSS-NEXT: 140003010 00000000 04
# __data_start__ pointing at 0x140003000 and
# __data_end__ pointing at 0x140003009.
# DATANOBSS-NEXT: Contents of section .test:
# DATANOBSS-NEXT: 140004000 00300040 01000000 09300040 01000000
# DATANOBSS-NEXT: 140004010 18300040 01000000 18300040 01000000

# __bss_start__ pointing at 0x140003000 and
# __bss_end__ pointing at 0x140005000.
# BSSNODATA-NOT: Contents of section .data:
# BSSNODATA: Contents of section .test:
# BSSNODATA-NEXT: 140005000 00300040 01000000 00300040 01000000
# BSSNODATA-NEXT: 140005010 00300040 01000000 00500040 01000000

# DATAANDBSS: Contents of section .data:
# DATAANDBSS-NEXT: 140003000 01000000 00000000 02000000 03000000
# DATAANDBSS-NEXT: 140003010 00000000 04000000 00000000 00000000
# __data_start__ pointing at 0x140003000 and
# __data_end__ pointing at 0x140003009.
# __bss_start__ pointing at 0x140003018 and
# __bss_end__ pointing at 0x140005018.
# DATAANDBSS: 1400031f0 00000000 00000000 00000000 00000000
# DATAANDBSS-NEXT: Contents of section .test:
# DATAANDBSS-NEXT: 140006000 00300040 01000000 09300040 01000000
# DATAANDBSS-NEXT: 140006010 18300040 01000000 18500040 01000000