[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 0df91893efc752a76c7bbe6b063d66c8a2fa0d55)
This commit is contained in:
parent
78f97e22e5
commit
40b0764101
@ -873,7 +873,6 @@ Defined *ObjcCategoryMerger::emitAndLinkProtocolList(
|
||||
infoCategoryWriter.catPtrListInfo.align);
|
||||
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
|
||||
listSec->live = true;
|
||||
addInputSection(listSec);
|
||||
|
||||
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
|
||||
|
||||
@ -889,6 +888,7 @@ Defined *ObjcCategoryMerger::emitAndLinkProtocolList(
|
||||
|
||||
ptrListSym->used = true;
|
||||
parentSym->getObjectFile()->symbols.push_back(ptrListSym);
|
||||
addInputSection(listSec);
|
||||
|
||||
createSymbolReference(parentSym, ptrListSym, linkAtOffset,
|
||||
infoCategoryWriter.catBodyInfo.relocTemplate);
|
||||
@ -933,7 +933,6 @@ void ObjcCategoryMerger::emitAndLinkPointerList(
|
||||
infoCategoryWriter.catPtrListInfo.align);
|
||||
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
|
||||
listSec->live = true;
|
||||
addInputSection(listSec);
|
||||
|
||||
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
|
||||
|
||||
@ -949,6 +948,7 @@ void ObjcCategoryMerger::emitAndLinkPointerList(
|
||||
|
||||
ptrListSym->used = true;
|
||||
parentSym->getObjectFile()->symbols.push_back(ptrListSym);
|
||||
addInputSection(listSec);
|
||||
|
||||
createSymbolReference(parentSym, ptrListSym, linkAtOffset,
|
||||
infoCategoryWriter.catBodyInfo.relocTemplate);
|
||||
@ -974,7 +974,6 @@ ObjcCategoryMerger::emitCatListEntrySec(const std::string &forCategoryName,
|
||||
bodyData, infoCategoryWriter.catListInfo.align);
|
||||
newCatList->parent = infoCategoryWriter.catListInfo.outputSection;
|
||||
newCatList->live = true;
|
||||
addInputSection(newCatList);
|
||||
|
||||
newCatList->parent = infoCategoryWriter.catListInfo.outputSection;
|
||||
|
||||
@ -990,6 +989,7 @@ ObjcCategoryMerger::emitCatListEntrySec(const std::string &forCategoryName,
|
||||
|
||||
catListSym->used = true;
|
||||
objFile->symbols.push_back(catListSym);
|
||||
addInputSection(newCatList);
|
||||
return catListSym;
|
||||
}
|
||||
|
||||
@ -1012,7 +1012,6 @@ Defined *ObjcCategoryMerger::emitCategoryBody(const std::string &name,
|
||||
bodyData, infoCategoryWriter.catBodyInfo.align);
|
||||
newBodySec->parent = infoCategoryWriter.catBodyInfo.outputSection;
|
||||
newBodySec->live = true;
|
||||
addInputSection(newBodySec);
|
||||
|
||||
std::string symName =
|
||||
objc::symbol_names::category + baseClassName + "(" + name + ")";
|
||||
@ -1025,6 +1024,7 @@ Defined *ObjcCategoryMerger::emitCategoryBody(const std::string &name,
|
||||
|
||||
catBodySym->used = true;
|
||||
objFile->symbols.push_back(catBodySym);
|
||||
addInputSection(newBodySec);
|
||||
|
||||
createSymbolReference(catBodySym, nameSym, catLayout.nameOffset,
|
||||
infoCategoryWriter.catBodyInfo.relocTemplate);
|
||||
@ -1245,7 +1245,6 @@ void ObjcCategoryMerger::generateCatListForNonErasedCategories(
|
||||
infoCategoryWriter.catListInfo.align);
|
||||
listSec->parent = infoCategoryWriter.catListInfo.outputSection;
|
||||
listSec->live = true;
|
||||
addInputSection(listSec);
|
||||
|
||||
std::string slotSymName = "<__objc_catlist slot for category ";
|
||||
slotSymName += nonErasedCatBody->getName();
|
||||
@ -1260,6 +1259,7 @@ void ObjcCategoryMerger::generateCatListForNonErasedCategories(
|
||||
|
||||
catListSlotSym->used = true;
|
||||
objFile->symbols.push_back(catListSlotSym);
|
||||
addInputSection(listSec);
|
||||
|
||||
// Now link the category body into the newly created slot
|
||||
createSymbolReference(catListSlotSym, nonErasedCatBody, 0,
|
||||
|
@ -9,7 +9,7 @@
|
||||
## Create our main testing dylib - linking against the fake dylib above
|
||||
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_cat_minimal.o merge_cat_minimal.s
|
||||
# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_no_merge.dylib a64_fakedylib.dylib merge_cat_minimal.o
|
||||
# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_merge.dylib -objc_category_merging a64_fakedylib.dylib merge_cat_minimal.o
|
||||
# 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
|
||||
|
||||
## Now verify that the flag caused category merging to happen appropriatelly
|
||||
# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_no_merge.dylib | FileCheck %s --check-prefixes=NO_MERGE_CATS
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
############ Test merging multiple categories into the base class ############
|
||||
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_base_class_minimal.o merge_base_class_minimal.s
|
||||
# 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
|
||||
# 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
|
||||
# RUN: %lld -arch arm64 -dylib -o merge_base_class_minimal_no_merge.dylib merge_base_class_minimal.o merge_cat_minimal.o
|
||||
|
||||
# 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
|
||||
MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass(Category01|Category02)
|
||||
MERGE_CATS-NEXT: name {{.*}} Category01|Category02
|
||||
MERGE_CATS: instanceMethods
|
||||
MERGE_CATS-NEXT: 24
|
||||
MERGE_CATS-NEXT: 2
|
||||
MERGE_CATS-NEXT: entsize 12 (relative)
|
||||
MERGE_CATS-NEXT: count 2
|
||||
MERGE_CATS-NEXT: name {{.*}} cat01_InstanceMethod
|
||||
MERGE_CATS-NEXT: types {{.*}} v16@0:8
|
||||
MERGE_CATS-NEXT: imp -[MyBaseClass(Category01) cat01_InstanceMethod]
|
||||
MERGE_CATS-NEXT: imp {{.*}} -[MyBaseClass(Category01) cat01_InstanceMethod]
|
||||
MERGE_CATS-NEXT: name {{.*}} cat02_InstanceMethod
|
||||
MERGE_CATS-NEXT: types {{.*}} v16@0:8
|
||||
MERGE_CATS-NEXT: imp -[MyBaseClass(Category02) cat02_InstanceMethod]
|
||||
MERGE_CATS-NEXT: imp {{.*}} -[MyBaseClass(Category02) cat02_InstanceMethod]
|
||||
MERGE_CATS-NEXT: classMethods 0x0
|
||||
MERGE_CATS-NEXT: protocols 0x0
|
||||
MERGE_CATS-NEXT: instanceProperties 0x0
|
||||
@ -69,17 +69,17 @@ YES_MERGE_INTO_BASE-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02
|
||||
YES_MERGE_INTO_BASE: _OBJC_CLASS_$_MyBaseClass
|
||||
YES_MERGE_INTO_BASE-NEXT: _OBJC_METACLASS_$_MyBaseClass
|
||||
YES_MERGE_INTO_BASE: baseMethods
|
||||
YES_MERGE_INTO_BASE-NEXT: entsize 24
|
||||
YES_MERGE_INTO_BASE-NEXT: entsize 12 (relative)
|
||||
YES_MERGE_INTO_BASE-NEXT: count 3
|
||||
YES_MERGE_INTO_BASE-NEXT: name {{.*}} cat01_InstanceMethod
|
||||
YES_MERGE_INTO_BASE-NEXT: types {{.*}} v16@0:8
|
||||
YES_MERGE_INTO_BASE-NEXT: imp -[MyBaseClass(Category01) cat01_InstanceMethod]
|
||||
YES_MERGE_INTO_BASE-NEXT: imp {{.*}} -[MyBaseClass(Category01) cat01_InstanceMethod]
|
||||
YES_MERGE_INTO_BASE-NEXT: name {{.*}} cat02_InstanceMethod
|
||||
YES_MERGE_INTO_BASE-NEXT: types {{.*}} v16@0:8
|
||||
YES_MERGE_INTO_BASE-NEXT: imp -[MyBaseClass(Category02) cat02_InstanceMethod]
|
||||
YES_MERGE_INTO_BASE-NEXT: imp {{.*}} -[MyBaseClass(Category02) cat02_InstanceMethod]
|
||||
YES_MERGE_INTO_BASE-NEXT: name {{.*}} baseInstanceMethod
|
||||
YES_MERGE_INTO_BASE-NEXT: types {{.*}} v16@0:8
|
||||
YES_MERGE_INTO_BASE-NEXT: imp -[MyBaseClass baseInstanceMethod]
|
||||
YES_MERGE_INTO_BASE-NEXT: imp {{.*}} -[MyBaseClass baseInstanceMethod]
|
||||
|
||||
|
||||
#### Check merge swift category into base class ###
|
||||
|
Loading…
x
Reference in New Issue
Block a user