Skip to content

Commit

Permalink
[lld-macho] Fix crash: ObjC category merge + relative method lists (l…
Browse files Browse the repository at this point in the history
…lvm#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`.
  • Loading branch information
alx32 authored Aug 15, 2024
1 parent bd47ba7 commit 0df9189
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 15 deletions.
10 changes: 5 additions & 5 deletions lld/MachO/ObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,6 @@ Defined *ObjcCategoryMerger::emitAndLinkProtocolList(
infoCategoryWriter.catPtrListInfo.align);
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
listSec->live = true;
addInputSection(listSec);

listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;

Expand All @@ -867,6 +866,7 @@ Defined *ObjcCategoryMerger::emitAndLinkProtocolList(

ptrListSym->used = true;
parentSym->getObjectFile()->symbols.push_back(ptrListSym);
addInputSection(listSec);

createSymbolReference(parentSym, ptrListSym, linkAtOffset,
infoCategoryWriter.catBodyInfo.relocTemplate);
Expand Down Expand Up @@ -911,7 +911,6 @@ void ObjcCategoryMerger::emitAndLinkPointerList(
infoCategoryWriter.catPtrListInfo.align);
listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
listSec->live = true;
addInputSection(listSec);

listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;

Expand All @@ -927,6 +926,7 @@ void ObjcCategoryMerger::emitAndLinkPointerList(

ptrListSym->used = true;
parentSym->getObjectFile()->symbols.push_back(ptrListSym);
addInputSection(listSec);

createSymbolReference(parentSym, ptrListSym, linkAtOffset,
infoCategoryWriter.catBodyInfo.relocTemplate);
Expand All @@ -952,7 +952,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;

Expand All @@ -968,6 +967,7 @@ ObjcCategoryMerger::emitCatListEntrySec(const std::string &forCategoryName,

catListSym->used = true;
objFile->symbols.push_back(catListSym);
addInputSection(newCatList);
return catListSym;
}

Expand All @@ -990,7 +990,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 + ")";
Expand All @@ -1003,6 +1002,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);
Expand Down Expand Up @@ -1223,7 +1223,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();
Expand All @@ -1238,6 +1237,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,
Expand Down
20 changes: 10 additions & 10 deletions lld/test/MachO/objc-category-merging-minimal.s
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
## 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
# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_merge.dylib | FileCheck %s --check-prefixes=MERGE_CATS

############ 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
Expand All @@ -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
Expand All @@ -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 ###
Expand Down

0 comments on commit 0df9189

Please sign in to comment.