From 2e997dba5502eec845f0371e0aef083281f77fc4 Mon Sep 17 00:00:00 2001 From: Ellis Hoag Date: Mon, 29 Sep 2025 10:20:28 -0700 Subject: [PATCH 1/2] [lld][macho][NFC] Factor count zeros into helper function --- lld/MachO/SyntheticSections.cpp | 57 +++++++++++++++++---------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index 228b84db21c2a..d38b6c9e00157 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -1685,31 +1685,7 @@ void CStringSection::writeTo(uint8_t *buf) const { } } -void CStringSection::finalizeContents() { - uint64_t offset = 0; - // TODO: Call buildCStringPriorities() to support cstring ordering when - // deduplication is off, although this may negatively impact build - // performance. - for (CStringInputSection *isec : inputs) { - for (const auto &[i, piece] : llvm::enumerate(isec->pieces)) { - if (!piece.live) - continue; - // See comment above DeduplicatedCStringSection for how alignment is - // handled. - uint32_t pieceAlign = 1 - << llvm::countr_zero(isec->align | piece.inSecOff); - offset = alignToPowerOf2(offset, pieceAlign); - piece.outSecOff = offset; - isec->isFinal = true; - StringRef string = isec->getStringRef(i); - offset += string.size() + 1; // account for null terminator - } - } - size = offset; -} - -// Mergeable cstring literals are found under the __TEXT,__cstring section. In -// contrast to ELF, which puts strings that need different alignments into +// In contrast to ELF, which puts strings that need different alignments into // different sections, clang's Mach-O backend puts them all in one section. // Strings that need to be aligned have the .p2align directive emitted before // them, which simply translates into zero padding in the object file. In other @@ -1744,8 +1720,33 @@ void CStringSection::finalizeContents() { // requires its operand addresses to be 16-byte aligned). However, there will // typically also be other cstrings in the same file that aren't used via SIMD // and don't need this alignment. They will be emitted at some arbitrary address -// `A`, but ld64 will treat them as being 16-byte aligned with an offset of `16 -// % A`. +// `A`, but ld64 will treat them as being 16-byte aligned with an offset of +// `16 % A`. +static uint8_t getStringPieceAlignment(const CStringInputSection *isec, + const StringPiece &piece) { + return llvm::countr_zero(isec->align | piece.inSecOff); +} + +void CStringSection::finalizeContents() { + uint64_t offset = 0; + // TODO: Call buildCStringPriorities() to support cstring ordering when + // deduplication is off, although this may negatively impact build + // performance. + for (CStringInputSection *isec : inputs) { + for (const auto &[i, piece] : llvm::enumerate(isec->pieces)) { + if (!piece.live) + continue; + uint32_t pieceAlign = 1 << getStringPieceAlignment(isec, piece); + offset = alignToPowerOf2(offset, pieceAlign); + piece.outSecOff = offset; + isec->isFinal = true; + StringRef string = isec->getStringRef(i); + offset += string.size() + 1; // account for null terminator + } + } + size = offset; +} + void DeduplicatedCStringSection::finalizeContents() { // Find the largest alignment required for each string. for (const CStringInputSection *isec : inputs) { @@ -1754,7 +1755,7 @@ void DeduplicatedCStringSection::finalizeContents() { continue; auto s = isec->getCachedHashStringRef(i); assert(isec->align != 0); - uint8_t trailingZeros = llvm::countr_zero(isec->align | piece.inSecOff); + uint8_t trailingZeros = getStringPieceAlignment(isec, piece); auto it = stringOffsetMap.insert( std::make_pair(s, StringOffset(trailingZeros))); if (!it.second && it.first->second.trailingZeros < trailingZeros) From ee87e104056cc89a9d5e151edefca335aa823909 Mon Sep 17 00:00:00 2001 From: Ellis Hoag Date: Mon, 29 Sep 2025 10:47:52 -0700 Subject: [PATCH 2/2] fix format --- lld/MachO/SyntheticSections.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index d38b6c9e00157..5645d8a05a28f 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -1723,7 +1723,7 @@ void CStringSection::writeTo(uint8_t *buf) const { // `A`, but ld64 will treat them as being 16-byte aligned with an offset of // `16 % A`. static uint8_t getStringPieceAlignment(const CStringInputSection *isec, - const StringPiece &piece) { + const StringPiece &piece) { return llvm::countr_zero(isec->align | piece.inSecOff); }