Skip to content

Commit 5c93dc9

Browse files
committed
[lld-macho] Simplify category merging code & update symbol names to match ld64
1 parent ad7ee90 commit 5c93dc9

File tree

3 files changed

+34
-49
lines changed

3 files changed

+34
-49
lines changed

lld/MachO/ObjC.cpp

Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -351,30 +351,28 @@ class ObjcCategoryMerger {
351351
// alignment as already used in existing (input) categories. To do this we
352352
// have InfoCategoryWriter which contains the various sections that the
353353
// generated categories will be written to.
354-
template <typename T> struct InfoWriteSection {
354+
struct InfoWriteSection {
355355
bool valid = false; // Data has been successfully collected from input
356356
uint32_t align = 0;
357357
Section *inputSection;
358358
Reloc relocTemplate;
359-
T *outputSection;
359+
OutputSection *outputSection;
360360
};
361361

362362
struct InfoCategoryWriter {
363-
InfoWriteSection<ConcatOutputSection> catListInfo;
364-
InfoWriteSection<ConcatOutputSection> catBodyInfo;
365-
InfoWriteSection<CStringSection> catNameInfo;
366-
InfoWriteSection<ConcatOutputSection> catPtrListInfo;
363+
InfoWriteSection catListInfo;
364+
InfoWriteSection catBodyInfo;
365+
InfoWriteSection catNameInfo;
366+
InfoWriteSection catPtrListInfo;
367367
};
368368

369369
// Information about a pointer list in the original categories (method lists,
370370
// protocol lists, etc)
371371
struct PointerListInfo {
372-
PointerListInfo(const char *_categoryPrefix, uint32_t _categoryOffset,
373-
uint32_t _pointersPerStruct)
374-
: categoryPrefix(_categoryPrefix), categoryOffset(_categoryOffset),
372+
PointerListInfo(const char *_categoryPrefix, uint32_t _pointersPerStruct)
373+
: categoryPrefix(_categoryPrefix),
375374
pointersPerStruct(_pointersPerStruct) {}
376375
const char *categoryPrefix;
377-
uint32_t categoryOffset = 0;
378376

379377
uint32_t pointersPerStruct = 0;
380378

@@ -399,25 +397,16 @@ class ObjcCategoryMerger {
399397
// In case we generate new data, mark the new data as belonging to this file
400398
ObjFile *objFileForMergeData = nullptr;
401399

402-
PointerListInfo instanceMethods = {
403-
objc::symbol_names::categoryInstanceMethods,
404-
/*_categoryOffset=*/catLayout.instanceMethodsOffset,
405-
/*pointersPerStruct=*/3};
406-
PointerListInfo classMethods = {
407-
objc::symbol_names::categoryClassMethods,
408-
/*_categoryOffset=*/catLayout.classMethodsOffset,
409-
/*pointersPerStruct=*/3};
400+
PointerListInfo instanceMethods = {objc::symbol_names::instanceMethods,
401+
/*pointersPerStruct=*/3};
402+
PointerListInfo classMethods = {objc::symbol_names::categoryClassMethods,
403+
/*pointersPerStruct=*/3};
410404
PointerListInfo protocols = {objc::symbol_names::categoryProtocols,
411-
/*_categoryOffset=*/catLayout.protocolsOffset,
412405
/*pointersPerStruct=*/0};
413-
PointerListInfo instanceProps = {
414-
objc::symbol_names::listProprieties,
415-
/*_categoryOffset=*/catLayout.instancePropsOffset,
416-
/*pointersPerStruct=*/2};
417-
PointerListInfo classProps = {
418-
objc::symbol_names::klassPropList,
419-
/*_categoryOffset=*/catLayout.classPropsOffset,
420-
/*pointersPerStruct=*/2};
406+
PointerListInfo instanceProps = {objc::symbol_names::listProprieties,
407+
/*pointersPerStruct=*/2};
408+
PointerListInfo classProps = {objc::symbol_names::klassPropList,
409+
/*pointersPerStruct=*/2};
421410
};
422411

423412
public:
@@ -436,9 +425,8 @@ class ObjcCategoryMerger {
436425
void generateCatListForNonErasedCategories(
437426
std::map<ConcatInputSection *, std::set<uint64_t>>
438427
catListToErasedOffsets);
439-
template <typename T>
440428
void collectSectionWriteInfoFromIsec(const InputSection *isec,
441-
InfoWriteSection<T> &catWriteInfo);
429+
InfoWriteSection &catWriteInfo);
442430
void collectCategoryWriterInfoFromCategory(const InfoInputCategory &catInfo);
443431
void parseCatInfoToExtInfo(const InfoInputCategory &catInfo,
444432
ClassExtensionInfo &extInfo);
@@ -511,15 +499,12 @@ ObjcCategoryMerger::ObjcCategoryMerger(
511499
protocolListHeaderLayout(target->wordSize),
512500
allInputSections(_allInputSections) {}
513501

514-
// This is a template so that it can be used both for CStringSection and
515-
// ConcatOutputSection
516-
template <typename T>
517502
void ObjcCategoryMerger::collectSectionWriteInfoFromIsec(
518-
const InputSection *isec, InfoWriteSection<T> &catWriteInfo) {
503+
const InputSection *isec, InfoWriteSection &catWriteInfo) {
519504

520505
catWriteInfo.inputSection = const_cast<Section *>(&isec->section);
521506
catWriteInfo.align = isec->align;
522-
catWriteInfo.outputSection = dyn_cast_or_null<T>(isec->parent);
507+
catWriteInfo.outputSection = isec->parent;
523508

524509
assert(catWriteInfo.outputSection &&
525510
"outputSection may not be null in collectSectionWriteInfoFromIsec.");
@@ -576,19 +561,19 @@ void ObjcCategoryMerger::collectCategoryWriterInfoFromCategory(
576561
const InfoInputCategory &catInfo) {
577562

578563
if (!infoCategoryWriter.catListInfo.valid)
579-
collectSectionWriteInfoFromIsec<ConcatOutputSection>(
580-
catInfo.catListIsec, infoCategoryWriter.catListInfo);
564+
collectSectionWriteInfoFromIsec(catInfo.catListIsec,
565+
infoCategoryWriter.catListInfo);
581566
if (!infoCategoryWriter.catBodyInfo.valid)
582-
collectSectionWriteInfoFromIsec<ConcatOutputSection>(
583-
catInfo.catBodyIsec, infoCategoryWriter.catBodyInfo);
567+
collectSectionWriteInfoFromIsec(catInfo.catBodyIsec,
568+
infoCategoryWriter.catBodyInfo);
584569

585570
if (!infoCategoryWriter.catNameInfo.valid) {
586571
lld::macho::Defined *catNameSym =
587572
tryGetDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset);
588573
assert(catNameSym && "Category does not have a valid name Symbol");
589574

590-
collectSectionWriteInfoFromIsec<CStringSection>(
591-
catNameSym->isec(), infoCategoryWriter.catNameInfo);
575+
collectSectionWriteInfoFromIsec(catNameSym->isec(),
576+
infoCategoryWriter.catNameInfo);
592577
}
593578

594579
// Collect writer info from all the category lists (we're assuming they all
@@ -598,8 +583,8 @@ void ObjcCategoryMerger::collectCategoryWriterInfoFromCategory(
598583
off <= catLayout.classPropsOffset; off += target->wordSize) {
599584
if (Defined *ptrList =
600585
tryGetDefinedAtIsecOffset(catInfo.catBodyIsec, off)) {
601-
collectSectionWriteInfoFromIsec<ConcatOutputSection>(
602-
ptrList->isec(), infoCategoryWriter.catPtrListInfo);
586+
collectSectionWriteInfoFromIsec(ptrList->isec(),
587+
infoCategoryWriter.catPtrListInfo);
603588
// we've successfully collected data, so we can break
604589
break;
605590
}
@@ -795,7 +780,7 @@ void ObjcCategoryMerger::emitAndLinkProtocolList(
795780
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
796781

797782
std::string symName = ptrList.categoryPrefix;
798-
symName += extInfo.baseClassName + "_$_(" + extInfo.mergedContainerName + ")";
783+
symName += extInfo.baseClassName + "(" + extInfo.mergedContainerName + ")";
799784

800785
Defined *ptrListSym = make<Defined>(
801786
newStringData(symName.c_str()), /*file=*/parentSym->getObjectFile(),
@@ -853,7 +838,7 @@ void ObjcCategoryMerger::emitAndLinkPointerList(
853838
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
854839

855840
std::string symName = ptrList.categoryPrefix;
856-
symName += extInfo.baseClassName + "_$_" + extInfo.mergedContainerName;
841+
symName += extInfo.baseClassName + "(" + extInfo.mergedContainerName + ")";
857842

858843
Defined *ptrListSym = make<Defined>(
859844
newStringData(symName.c_str()), /*file=*/parentSym->getObjectFile(),
@@ -930,7 +915,7 @@ Defined *ObjcCategoryMerger::emitCategoryBody(const std::string &name,
930915
addInputSection(newBodySec);
931916

932917
std::string symName =
933-
objc::symbol_names::category + baseClassName + "_$_(" + name + ")";
918+
objc::symbol_names::category + baseClassName + "(" + name + ")";
934919
Defined *catBodySym = make<Defined>(
935920
newStringData(symName.c_str()), /*file=*/objFile, newBodySec,
936921
/*value=*/0, bodyData.size(), /*isWeakDef=*/false, /*isExternal=*/false,

lld/test/MachO/objc-category-merging-complete-test.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# RUN: llvm-objdump --objc-meta-data --macho a64_file2_merge.exe | FileCheck %s --check-prefixes=MERGE_CATS
1414

1515

16-
MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_(Category02|Category03)
16+
MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass(Category02|Category03)
1717
MERGE_CATS-NEXT: name {{.*}} Category02|Category03
1818
MERGE_CATS: instanceMethods
1919
MERGE_CATS-NEXT: entsize 24
@@ -90,7 +90,7 @@ MERGE_CATS-NEXT: name {{.*}} MyProtocol03Prop
9090
MERGE_CATS-NEXT: attributes {{.*}} Ti,R,D
9191

9292

93-
NO_MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_(Category02|Category03)
93+
NO_MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass(Category02|Category03)
9494
NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category02
9595
NO_MERGE_CATS: instanceMethods
9696
NO_MERGE_CATS-NEXT: 24

lld/test/MachO/objc-category-merging-extern-class-minimal.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category01
2020
MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02
2121

2222
# Check that the merged cateogry is there, in the correct format
23-
MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_(Category01|Category02)
23+
MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass(Category01|Category02)
2424
MERGE_CATS-NEXT: name {{.*}} Category01|Category02
2525
MERGE_CATS: instanceMethods
2626
MERGE_CATS-NEXT: 24
@@ -37,7 +37,7 @@ MERGE_CATS-NEXT: instanceProperties 0x0
3737

3838
#### Check merge categories disabled ###
3939
# Check that the merged category is not there
40-
NO_MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_(Category01|Category02)
40+
NO_MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass(Category01|Category02)
4141

4242
# Check that the original categories are there
4343
NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category01

0 commit comments

Comments
 (0)