diff --git a/bolt/lib/Core/Exceptions.cpp b/bolt/lib/Core/Exceptions.cpp --- a/bolt/lib/Core/Exceptions.cpp +++ b/bolt/lib/Core/Exceptions.cpp @@ -180,19 +180,36 @@ BinaryFunction *Fragment = BC.getBinaryFunctionContainingAddress(LPAddress); // Verify if landing pad code is located outside current function - // Support landing pad to builtin_unreachable + // Skip case where landing pad targets builtin_unreachable if (LPAddress < Address || LPAddress > Address + getSize()) { + // Assume landing pad not target another fragment's builtin_unreachable + // If this assumption is violated, must run a global check first assert(Fragment != nullptr && "BOLT-ERROR: cannot find landing pad fragment"); + + // Update IsFragment: + // In stripped mode, always trust LSDA, consider the function that + // contains LP as a fragment + // In non-stripped mode, use pattern matching (adjustFunctionBoundaries) + if (BC.IsStripped) + Fragment->IsFragment = true; + + // Update parent-fragment relation, add Fragment as secondary entry of + // the current function, not an independent function BC.addInterproceduralReference(this, Fragment->getAddress()); BC.processInterproceduralReferences(); - auto isFragmentOf = [](BinaryFunction *Fragment, - BinaryFunction *Parent) -> bool { - return (Fragment->isFragment() && Fragment->isParentFragment(Parent)); - }; - assert((isFragmentOf(this, Fragment) || isFragmentOf(Fragment, this)) && - "BOLT-ERROR: cannot have landing pads in different " - "functions"); + + // In stripped mode, parent-fragment is always established --> skip check + // In non-stripped mode, parent-fragment depends on symbol name --> check + if (!BC.IsStripped) { + auto isFragmentOf = [](BinaryFunction *Fragment, + BinaryFunction *Parent) -> bool { + return (Fragment->isFragment() && Fragment->isParentFragment(Parent)); + }; + assert((isFragmentOf(this, Fragment) || isFragmentOf(Fragment, this)) && + "BOLT-ERROR: cannot have landing pads in different functions"); + } + // Mark that this fragment reaches LP in another fragment of same function setHasIndirectTargetToSplitFragment(true); BC.addFragmentsToSkip(this); } diff --git a/bolt/test/X86/split-landing-pad.s b/bolt/test/X86/split-landing-pad.s --- a/bolt/test/X86/split-landing-pad.s +++ b/bolt/test/X86/split-landing-pad.s @@ -8,6 +8,8 @@ # This test is written to ensure BOLT safely handle these targets, e.g., by # marking them as non-simple. # +# This test is for both stripped and non-stripped binaries +# # Steps to write this test: # - Create a copy of Inputs/src/unreachable.cpp # - Simplify bar(), focus on throw an exception @@ -27,6 +29,10 @@ # RUN: %clang++ %cxxflags %t.o -o %t.exe -Wl,-q # RUN: llvm-bolt -v=3 %t.exe -o %t.out -print-exceptions 2>&1 | FileCheck %s +# RUN: cp %t.exe %t.tmp.exe +# RUN: llvm-strip -s %t.tmp.exe +# RUN: llvm-bolt -v=3 %t.tmp.exe -o %t.out -print-exceptions 2>&1 | FileCheck %s + # CHECK: BOLT-INFO: marking [[FOO_COLD:.+]] as a fragment of [[FOO:.+]] # CHECK: landing pad label: [[TMP2:.+]] # CHECK: landing pad label: [[TMP5:.+]]