@@ -1685,31 +1685,7 @@ void CStringSection::writeTo(uint8_t *buf) const {
16851685 }
16861686}
16871687
1688- void CStringSection::finalizeContents () {
1689- uint64_t offset = 0 ;
1690- // TODO: Call buildCStringPriorities() to support cstring ordering when
1691- // deduplication is off, although this may negatively impact build
1692- // performance.
1693- for (CStringInputSection *isec : inputs) {
1694- for (const auto &[i, piece] : llvm::enumerate (isec->pieces )) {
1695- if (!piece.live )
1696- continue ;
1697- // See comment above DeduplicatedCStringSection for how alignment is
1698- // handled.
1699- uint32_t pieceAlign = 1
1700- << llvm::countr_zero (isec->align | piece.inSecOff );
1701- offset = alignToPowerOf2 (offset, pieceAlign);
1702- piece.outSecOff = offset;
1703- isec->isFinal = true ;
1704- StringRef string = isec->getStringRef (i);
1705- offset += string.size () + 1 ; // account for null terminator
1706- }
1707- }
1708- size = offset;
1709- }
1710-
1711- // Mergeable cstring literals are found under the __TEXT,__cstring section. In
1712- // contrast to ELF, which puts strings that need different alignments into
1688+ // In contrast to ELF, which puts strings that need different alignments into
17131689// different sections, clang's Mach-O backend puts them all in one section.
17141690// Strings that need to be aligned have the .p2align directive emitted before
17151691// them, which simply translates into zero padding in the object file. In other
@@ -1744,8 +1720,33 @@ void CStringSection::finalizeContents() {
17441720// requires its operand addresses to be 16-byte aligned). However, there will
17451721// typically also be other cstrings in the same file that aren't used via SIMD
17461722// and don't need this alignment. They will be emitted at some arbitrary address
1747- // `A`, but ld64 will treat them as being 16-byte aligned with an offset of `16
1748- // % A`.
1723+ // `A`, but ld64 will treat them as being 16-byte aligned with an offset of
1724+ // `16 % A`.
1725+ static uint8_t getStringPieceAlignment (const CStringInputSection *isec,
1726+ const StringPiece &piece) {
1727+ return llvm::countr_zero (isec->align | piece.inSecOff );
1728+ }
1729+
1730+ void CStringSection::finalizeContents () {
1731+ uint64_t offset = 0 ;
1732+ // TODO: Call buildCStringPriorities() to support cstring ordering when
1733+ // deduplication is off, although this may negatively impact build
1734+ // performance.
1735+ for (CStringInputSection *isec : inputs) {
1736+ for (const auto &[i, piece] : llvm::enumerate (isec->pieces )) {
1737+ if (!piece.live )
1738+ continue ;
1739+ uint32_t pieceAlign = 1 << getStringPieceAlignment (isec, piece);
1740+ offset = alignToPowerOf2 (offset, pieceAlign);
1741+ piece.outSecOff = offset;
1742+ isec->isFinal = true ;
1743+ StringRef string = isec->getStringRef (i);
1744+ offset += string.size () + 1 ; // account for null terminator
1745+ }
1746+ }
1747+ size = offset;
1748+ }
1749+
17491750void DeduplicatedCStringSection::finalizeContents () {
17501751 // Find the largest alignment required for each string.
17511752 for (const CStringInputSection *isec : inputs) {
@@ -1754,7 +1755,7 @@ void DeduplicatedCStringSection::finalizeContents() {
17541755 continue ;
17551756 auto s = isec->getCachedHashStringRef (i);
17561757 assert (isec->align != 0 );
1757- uint8_t trailingZeros = llvm::countr_zero (isec-> align | piece. inSecOff );
1758+ uint8_t trailingZeros = getStringPieceAlignment (isec, piece);
17581759 auto it = stringOffsetMap.insert (
17591760 std::make_pair (s, StringOffset (trailingZeros)));
17601761 if (!it.second && it.first ->second .trailingZeros < trailingZeros)
0 commit comments