Skip to content

Commit 2963d6e

Browse files
jrtc27resistor
authored andcommitted
[CodeGen] Use non-preemptible symbol for BlockAddress global constants
Just as with landing pads, which are basically a special form of BlockAddress, we should not use preemptible symbols here.
1 parent 00c80f9 commit 2963d6e

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,35 @@ void AsmPrinter::emitFunctionHeader() {
11071107

11081108
static 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.
11121141
void 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);

llvm/test/CodeGen/Mips/cheri/cheri-blockaddress.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ indirectgoto: ; preds = %entry
6262
; ASM: .end addrof_label_in_local
6363

6464
; ASM-LABEL: addrof_label_in_static.b:
65-
; ASM-NEXT: .chericap addrof_label_in_static+(.Ltmp0-addrof_label_in_static)
65+
; ASM-NEXT: .chericap .Laddrof_label_in_static$local+(.Ltmp0-.Laddrof_label_in_static$local)
6666
; ASM-NEXT: .size addrof_label_in_static.b, [[#CAP_SIZE]]
6767

6868
; The .o file should contain a relocation against the function with a constant addend (0x1c)
6969
; OBJ: Section (8) .rela.data {
70-
; OBJ-NEXT: 0x0 R_MIPS_CHERI_CAPABILITY/R_MIPS_NONE/R_MIPS_NONE addrof_label_in_static 0x1C
70+
; OBJ-NEXT: 0x0 R_MIPS_CHERI_CAPABILITY/R_MIPS_NONE/R_MIPS_NONE .Laddrof_label_in_static$local 0x1C
7171
; OBJ-NEXT: }
7272

7373

0 commit comments

Comments
 (0)