Skip to content

Commit 947444d

Browse files
committed
[LLD][MachO] Option to emit separate cstring sections
1 parent f94e36d commit 947444d

File tree

9 files changed

+73
-12
lines changed

9 files changed

+73
-12
lines changed

lld/MachO/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ struct Configuration {
222222
bool pgoWarnMismatch;
223223
bool warnThinArchiveMissingMembers;
224224
bool disableVerify;
225+
bool separateCstringLiteralSections;
225226

226227
bool callGraphProfileSort = false;
227228
llvm::StringRef printSymbolOrder;

lld/MachO/Driver.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1520,7 +1520,8 @@ static void foldIdenticalLiterals() {
15201520
// We always create a cStringSection, regardless of whether dedupLiterals is
15211521
// true. If it isn't, we simply create a non-deduplicating CStringSection.
15221522
// Either way, we must unconditionally finalize it here.
1523-
in.cStringSection->finalizeContents();
1523+
for (auto &[name, sec] : in.cStringSectionMap)
1524+
sec->finalizeContents();
15241525
in.objcMethnameSection->finalizeContents();
15251526
in.wordLiteralSection->finalizeContents();
15261527
}
@@ -1981,6 +1982,9 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
19811982
OPT_no_warn_thin_archive_missing_members, true);
19821983
config->generateUuid = !args.hasArg(OPT_no_uuid);
19831984
config->disableVerify = args.hasArg(OPT_disable_verify);
1985+
config->separateCstringLiteralSections =
1986+
args.hasFlag(OPT_separate_cstring_literal_sections,
1987+
OPT_no_separate_cstring_literal_sections, false);
19841988

19851989
auto IncompatWithCGSort = [&](StringRef firstArgStr) {
19861990
// Throw an error only if --call-graph-profile-sort is explicitly specified

lld/MachO/InputSection.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,12 @@ void lld::macho::addInputSection(InputSection *inputSection) {
6868
in.objcMethnameSection->inputOrder = inputSectionsOrder++;
6969
in.objcMethnameSection->addInput(isec);
7070
} else {
71-
if (in.cStringSection->inputOrder == UnspecifiedInputOrder)
72-
in.cStringSection->inputOrder = inputSectionsOrder++;
73-
in.cStringSection->addInput(isec);
71+
auto *osec = in.getOrCreateCStringSection(
72+
config->separateCstringLiteralSections ? isec->getName()
73+
: section_names::cString);
74+
if (osec->inputOrder == UnspecifiedInputOrder)
75+
osec->inputOrder = inputSectionsOrder++;
76+
osec->addInput(isec);
7477
}
7578
} else if (auto *isec = dyn_cast<WordLiteralInputSection>(inputSection)) {
7679
if (in.wordLiteralSection->inputOrder == UnspecifiedInputOrder)

lld/MachO/MapFile.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,9 @@ void macho::writeMapFile() {
239239
printIsecArrSyms(textOsec->inputs, textOsec->getThunks());
240240
} else if (auto *concatOsec = dyn_cast<ConcatOutputSection>(osec)) {
241241
printIsecArrSyms(concatOsec->inputs);
242-
} else if (osec == in.cStringSection || osec == in.objcMethnameSection) {
242+
} else if (any_of(in.cStringSectionMap,
243+
[&](auto &it) { return osec == it.getValue(); }) ||
244+
osec == in.objcMethnameSection) {
243245
const auto &liveCStrings = info.liveCStringsForSection.lookup(osec);
244246
uint64_t lastAddr = 0; // strings will never start at address 0, so this
245247
// is a sentinel value

lld/MachO/ObjC.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ Defined *ObjcCategoryMerger::emitCategoryName(const std::string &name,
10571057
newStringSec->splitIntoPieces();
10581058
newStringSec->pieces[0].live = true;
10591059
newStringSec->parent = infoCategoryWriter.catNameInfo.outputSection;
1060-
in.cStringSection->addInput(newStringSec);
1060+
in.getOrCreateCStringSection(section_names::cString)->addInput(newStringSec);
10611061
assert(newStringSec->pieces.size() == 1);
10621062

10631063
Defined *catNameSym = make<Defined>(

lld/MachO/Options.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,13 @@ def dyld_env : Separate<["-"], "dyld_env">,
10841084
def ignore_auto_link : Flag<["-"], "ignore_auto_link">,
10851085
HelpText<"Ignore LC_LINKER_OPTIONs">,
10861086
Group<grp_rare>;
1087+
defm separate_cstring_literal_sections
1088+
: BB<"separate-cstring-literal-sections",
1089+
"Emit all cstring literals into their respective sections defined by "
1090+
"their section names.",
1091+
"Emit all cstring literals into the __cstring section. As a special "
1092+
"case, the __objc_methname section will still be emitted. (default)">,
1093+
Group<grp_rare>;
10871094

10881095
def grp_deprecated : OptionGroup<"deprecated">, HelpText<"DEPRECATED">;
10891096

lld/MachO/SyntheticSections.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ void writeChainedFixup(uint8_t *buf, const Symbol *sym, int64_t addend);
843843
struct InStruct {
844844
const uint8_t *bufferStart = nullptr;
845845
MachHeaderSection *header = nullptr;
846-
CStringSection *cStringSection = nullptr;
846+
llvm::StringMap<CStringSection *> cStringSectionMap;
847847
DeduplicatedCStringSection *objcMethnameSection = nullptr;
848848
WordLiteralSection *wordLiteralSection = nullptr;
849849
RebaseSection *rebase = nullptr;
@@ -863,6 +863,21 @@ struct InStruct {
863863
InitOffsetsSection *initOffsets = nullptr;
864864
ObjCMethListSection *objcMethList = nullptr;
865865
ChainedFixupsSection *chainedFixups = nullptr;
866+
867+
CStringSection *getOrCreateCStringSection(StringRef name) {
868+
auto it = cStringSectionMap.find(name);
869+
if (it != cStringSectionMap.end())
870+
return it->getValue();
871+
872+
std::string &nameData = *make<std::string>(name);
873+
CStringSection *sec;
874+
if (config->dedupStrings)
875+
sec = make<DeduplicatedCStringSection>(nameData.c_str());
876+
else
877+
sec = make<CStringSection>(nameData.c_str());
878+
cStringSectionMap[name] = sec;
879+
return sec;
880+
}
866881
};
867882

868883
extern InStruct in;

lld/MachO/Writer.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,11 +1377,8 @@ void macho::resetWriter() { LCDylib::resetInstanceCount(); }
13771377

13781378
void macho::createSyntheticSections() {
13791379
in.header = make<MachHeaderSection>();
1380-
if (config->dedupStrings)
1381-
in.cStringSection =
1382-
make<DeduplicatedCStringSection>(section_names::cString);
1383-
else
1384-
in.cStringSection = make<CStringSection>(section_names::cString);
1380+
// Materialize the cstring section
1381+
in.getOrCreateCStringSection(section_names::cString);
13851382
in.objcMethnameSection =
13861383
make<DeduplicatedCStringSection>(section_names::objcMethname);
13871384
in.wordLiteralSection = make<WordLiteralSection>();

lld/test/MachO/cstring.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; REQUIRES: aarch64
2+
; RUN: llvm-as %s -o %t.o
3+
4+
; RUN: %lld -dylib --separate-cstring-literal-sections %t.o -o - | llvm-objdump --macho --section-headers - | FileCheck %s
5+
; RUN: %lld -dylib --no-separate-cstring-literal-sections %t.o -o - | llvm-objdump --macho --section-headers - | FileCheck %s --check-prefix=CSTR
6+
; RUN: %lld -dylib %t.o -o - | llvm-objdump --macho --section-headers - | FileCheck %s --check-prefix=CSTR
7+
8+
; CHECK-DAG: __cstring
9+
; CHECK-DAG: __new_sec
10+
; CHECK-DAG: __objc_classname
11+
; CHECK-DAG: __objc_methname
12+
; CHECK-DAG: __objc_methtype
13+
14+
; CSTR-DAG: __cstring
15+
; CSTR-DAG: __objc_methname
16+
17+
target triple = "x86_64-apple-darwin"
18+
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"
19+
20+
@.str = private unnamed_addr constant [10 x i8] c"my string\00", align 1
21+
@.str1 = private unnamed_addr constant [16 x i8] c"my other string\00", section "__TEXT,__new_sec,cstring_literals", align 1
22+
@OBJC_CLASS_NAME_ = private unnamed_addr constant [4 x i8] c"foo\00", section "__TEXT,__objc_classname,cstring_literals", align 1
23+
@OBJC_METH_VAR_NAME_ = private unnamed_addr constant [4 x i8] c"bar\00", section "__TEXT,__objc_methname,cstring_literals", align 1
24+
@OBJC_METH_VAR_TYPE_ = private unnamed_addr constant [4 x i8] c"goo\00", section "__TEXT,__objc_methtype,cstring_literals", align 1
25+
26+
@llvm.compiler.used = appending global [5 x ptr] [
27+
ptr @.str,
28+
ptr @.str1,
29+
ptr @OBJC_METH_VAR_NAME_,
30+
ptr @OBJC_CLASS_NAME_,
31+
ptr @OBJC_METH_VAR_TYPE_
32+
]

0 commit comments

Comments
 (0)