Skip to content

Commit 40b0764

Browse files
alx32tru
authored andcommitted
[lld-macho] Fix crash: ObjC category merge + relative method lists (#104081)
A crash was happening when both ObjC Category Merging and Relative method lists were enabled. ObjC Category Merging creates new data sections and adds them by calling `addInputSection`. `addInputSection` uses the symbols within the added section to determine which container to actually add the section to. The issue is that ObjC Category merging is calling `addInputSection` before actually adding the relevant symbols the the added section. This causes `addInputSection` to add the `InputSection` to the wrong container, eventually resulting in a crash. To fix this, we ensure that ObjC Category Merging calls `addInputSection` only after the symbols have been added to the `InputSection`. (cherry picked from commit 0df9189)
1 parent 78f97e2 commit 40b0764

File tree

2 files changed

+15
-15
lines changed

2 files changed

+15
-15
lines changed

lld/MachO/ObjC.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,6 @@ Defined *ObjcCategoryMerger::emitAndLinkProtocolList(
873873
infoCategoryWriter.catPtrListInfo.align);
874874
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
875875
listSec->live = true;
876-
addInputSection(listSec);
877876

878877
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
879878

@@ -889,6 +888,7 @@ Defined *ObjcCategoryMerger::emitAndLinkProtocolList(
889888

890889
ptrListSym->used = true;
891890
parentSym->getObjectFile()->symbols.push_back(ptrListSym);
891+
addInputSection(listSec);
892892

893893
createSymbolReference(parentSym, ptrListSym, linkAtOffset,
894894
infoCategoryWriter.catBodyInfo.relocTemplate);
@@ -933,7 +933,6 @@ void ObjcCategoryMerger::emitAndLinkPointerList(
933933
infoCategoryWriter.catPtrListInfo.align);
934934
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
935935
listSec->live = true;
936-
addInputSection(listSec);
937936

938937
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
939938

@@ -949,6 +948,7 @@ void ObjcCategoryMerger::emitAndLinkPointerList(
949948

950949
ptrListSym->used = true;
951950
parentSym->getObjectFile()->symbols.push_back(ptrListSym);
951+
addInputSection(listSec);
952952

953953
createSymbolReference(parentSym, ptrListSym, linkAtOffset,
954954
infoCategoryWriter.catBodyInfo.relocTemplate);
@@ -974,7 +974,6 @@ ObjcCategoryMerger::emitCatListEntrySec(const std::string &forCategoryName,
974974
bodyData, infoCategoryWriter.catListInfo.align);
975975
newCatList->parent = infoCategoryWriter.catListInfo.outputSection;
976976
newCatList->live = true;
977-
addInputSection(newCatList);
978977

979978
newCatList->parent = infoCategoryWriter.catListInfo.outputSection;
980979

@@ -990,6 +989,7 @@ ObjcCategoryMerger::emitCatListEntrySec(const std::string &forCategoryName,
990989

991990
catListSym->used = true;
992991
objFile->symbols.push_back(catListSym);
992+
addInputSection(newCatList);
993993
return catListSym;
994994
}
995995

@@ -1012,7 +1012,6 @@ Defined *ObjcCategoryMerger::emitCategoryBody(const std::string &name,
10121012
bodyData, infoCategoryWriter.catBodyInfo.align);
10131013
newBodySec->parent = infoCategoryWriter.catBodyInfo.outputSection;
10141014
newBodySec->live = true;
1015-
addInputSection(newBodySec);
10161015

10171016
std::string symName =
10181017
objc::symbol_names::category + baseClassName + "(" + name + ")";
@@ -1025,6 +1024,7 @@ Defined *ObjcCategoryMerger::emitCategoryBody(const std::string &name,
10251024

10261025
catBodySym->used = true;
10271026
objFile->symbols.push_back(catBodySym);
1027+
addInputSection(newBodySec);
10281028

10291029
createSymbolReference(catBodySym, nameSym, catLayout.nameOffset,
10301030
infoCategoryWriter.catBodyInfo.relocTemplate);
@@ -1245,7 +1245,6 @@ void ObjcCategoryMerger::generateCatListForNonErasedCategories(
12451245
infoCategoryWriter.catListInfo.align);
12461246
listSec->parent = infoCategoryWriter.catListInfo.outputSection;
12471247
listSec->live = true;
1248-
addInputSection(listSec);
12491248

12501249
std::string slotSymName = "<__objc_catlist slot for category ";
12511250
slotSymName += nonErasedCatBody->getName();
@@ -1260,6 +1259,7 @@ void ObjcCategoryMerger::generateCatListForNonErasedCategories(
12601259

12611260
catListSlotSym->used = true;
12621261
objFile->symbols.push_back(catListSlotSym);
1262+
addInputSection(listSec);
12631263

12641264
// Now link the category body into the newly created slot
12651265
createSymbolReference(catListSlotSym, nonErasedCatBody, 0,

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99
## Create our main testing dylib - linking against the fake dylib above
1010
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_cat_minimal.o merge_cat_minimal.s
1111
# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_no_merge.dylib a64_fakedylib.dylib merge_cat_minimal.o
12-
# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_merge.dylib -objc_category_merging a64_fakedylib.dylib merge_cat_minimal.o
12+
# RUN: %lld -objc_relative_method_lists -arch arm64 -dylib -o merge_cat_minimal_merge.dylib -objc_category_merging a64_fakedylib.dylib merge_cat_minimal.o
1313

1414
## Now verify that the flag caused category merging to happen appropriatelly
1515
# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_no_merge.dylib | FileCheck %s --check-prefixes=NO_MERGE_CATS
1616
# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_merge.dylib | FileCheck %s --check-prefixes=MERGE_CATS
1717

1818
############ Test merging multiple categories into the base class ############
1919
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_base_class_minimal.o merge_base_class_minimal.s
20-
# RUN: %lld -arch arm64 -dylib -o merge_base_class_minimal_yes_merge.dylib -objc_category_merging merge_base_class_minimal.o merge_cat_minimal.o
20+
# RUN: %lld -arch arm64 -dylib -objc_relative_method_lists -o merge_base_class_minimal_yes_merge.dylib -objc_category_merging merge_base_class_minimal.o merge_cat_minimal.o
2121
# RUN: %lld -arch arm64 -dylib -o merge_base_class_minimal_no_merge.dylib merge_base_class_minimal.o merge_cat_minimal.o
2222

2323
# RUN: llvm-objdump --objc-meta-data --macho merge_base_class_minimal_no_merge.dylib | FileCheck %s --check-prefixes=NO_MERGE_INTO_BASE
@@ -37,14 +37,14 @@ MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02
3737
MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass(Category01|Category02)
3838
MERGE_CATS-NEXT: name {{.*}} Category01|Category02
3939
MERGE_CATS: instanceMethods
40-
MERGE_CATS-NEXT: 24
41-
MERGE_CATS-NEXT: 2
40+
MERGE_CATS-NEXT: entsize 12 (relative)
41+
MERGE_CATS-NEXT: count 2
4242
MERGE_CATS-NEXT: name {{.*}} cat01_InstanceMethod
4343
MERGE_CATS-NEXT: types {{.*}} v16@0:8
44-
MERGE_CATS-NEXT: imp -[MyBaseClass(Category01) cat01_InstanceMethod]
44+
MERGE_CATS-NEXT: imp {{.*}} -[MyBaseClass(Category01) cat01_InstanceMethod]
4545
MERGE_CATS-NEXT: name {{.*}} cat02_InstanceMethod
4646
MERGE_CATS-NEXT: types {{.*}} v16@0:8
47-
MERGE_CATS-NEXT: imp -[MyBaseClass(Category02) cat02_InstanceMethod]
47+
MERGE_CATS-NEXT: imp {{.*}} -[MyBaseClass(Category02) cat02_InstanceMethod]
4848
MERGE_CATS-NEXT: classMethods 0x0
4949
MERGE_CATS-NEXT: protocols 0x0
5050
MERGE_CATS-NEXT: instanceProperties 0x0
@@ -69,17 +69,17 @@ YES_MERGE_INTO_BASE-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02
6969
YES_MERGE_INTO_BASE: _OBJC_CLASS_$_MyBaseClass
7070
YES_MERGE_INTO_BASE-NEXT: _OBJC_METACLASS_$_MyBaseClass
7171
YES_MERGE_INTO_BASE: baseMethods
72-
YES_MERGE_INTO_BASE-NEXT: entsize 24
72+
YES_MERGE_INTO_BASE-NEXT: entsize 12 (relative)
7373
YES_MERGE_INTO_BASE-NEXT: count 3
7474
YES_MERGE_INTO_BASE-NEXT: name {{.*}} cat01_InstanceMethod
7575
YES_MERGE_INTO_BASE-NEXT: types {{.*}} v16@0:8
76-
YES_MERGE_INTO_BASE-NEXT: imp -[MyBaseClass(Category01) cat01_InstanceMethod]
76+
YES_MERGE_INTO_BASE-NEXT: imp {{.*}} -[MyBaseClass(Category01) cat01_InstanceMethod]
7777
YES_MERGE_INTO_BASE-NEXT: name {{.*}} cat02_InstanceMethod
7878
YES_MERGE_INTO_BASE-NEXT: types {{.*}} v16@0:8
79-
YES_MERGE_INTO_BASE-NEXT: imp -[MyBaseClass(Category02) cat02_InstanceMethod]
79+
YES_MERGE_INTO_BASE-NEXT: imp {{.*}} -[MyBaseClass(Category02) cat02_InstanceMethod]
8080
YES_MERGE_INTO_BASE-NEXT: name {{.*}} baseInstanceMethod
8181
YES_MERGE_INTO_BASE-NEXT: types {{.*}} v16@0:8
82-
YES_MERGE_INTO_BASE-NEXT: imp -[MyBaseClass baseInstanceMethod]
82+
YES_MERGE_INTO_BASE-NEXT: imp {{.*}} -[MyBaseClass baseInstanceMethod]
8383

8484

8585
#### Check merge swift category into base class ###

0 commit comments

Comments
 (0)