@@ -1107,6 +1107,35 @@ void AsmPrinter::emitFunctionHeader() {
11071107
11081108static bool needFuncLabels (const MachineFunction &MF, const AsmPrinter &Asm);
11091109
1110+ // / Returns true if function begin label should be emitted due to a
1111+ // / BlockAddress used as an initializer for a GlobalVariable.
1112+ static bool needFuncLabelForBlockAddress (const MachineFunction &MF) {
1113+ SmallVector<const Value *, 4 > Users;
1114+
1115+ for (const auto &MBB : MF) {
1116+ if (!MBB.isIRBlockAddressTaken ())
1117+ continue ;
1118+
1119+ const auto *BB = MBB.getAddressTakenIRBlock ();
1120+ for (const auto &U : BB->users ()) {
1121+ if (isa<BlockAddress>(U))
1122+ Users.push_back (U);
1123+ }
1124+ }
1125+
1126+ while (!Users.empty ()) {
1127+ const Value *V = Users.pop_back_val ();
1128+ if (isa<GlobalVariable>(V))
1129+ return true ;
1130+ if (isa<Instruction>(V))
1131+ continue ;
1132+ for (const auto &U : V->users ())
1133+ Users.push_back (U);
1134+ }
1135+
1136+ return false ;
1137+ }
1138+
11101139// / EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
11111140// / function. This can be overridden by targets as required to do custom stuff.
11121141void AsmPrinter::emitFunctionEntryLabel () {
@@ -1116,7 +1145,9 @@ void AsmPrinter::emitFunctionEntryLabel() {
11161145 if (TM.getTargetTriple ().isOSBinFormatELF ()) {
11171146 // For CHERI purecap exception handling, we always have to use a local
11181147 // alias even if the function is not dso_local.
1119- bool ForceLocal = MAI->isCheriPurecapABI () && needFuncLabels (*MF, *this );
1148+ bool ForceLocal =
1149+ MAI->isCheriPurecapABI () &&
1150+ (needFuncLabels (*MF, *this ) || needFuncLabelForBlockAddress (*MF));
11201151 MCSymbol *Sym = getSymbolPreferLocal (MF->getFunction (), ForceLocal);
11211152 if (Sym != CurrentFnSym) {
11221153 CurrentFnBeginLocal = Sym;
@@ -4163,7 +4194,8 @@ static void emitGlobalConstantCHERICap(const DataLayout &DL, const Constant *CV,
41634194 } else if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
41644195 if (auto BA = dyn_cast<BlockAddress>(CV)) {
41654196 // For block addresses we emit `.chericap FN+(.LtmpN - FN)`
4166- auto FnStart = AP.getSymbol (BA->getFunction ());
4197+ // NB: Must use a non-preemptible symbol
4198+ auto FnStart = AP.getSymbolPreferLocal (*BA->getFunction (), true );
41674199 const MCExpr *Start = MCSymbolRefExpr::create (FnStart, Ctx);
41684200 const MCExpr *DiffToStart = MCBinaryExpr::createSub (SRE, Start, Ctx);
41694201 const MCExpr *CapExpr = MCBinaryExpr::createAdd (Start, DiffToStart, Ctx);
0 commit comments