@@ -198,6 +198,111 @@ TEST_P(MCPlusBuilderTester, AArch64_BTI) {
198198 ASSERT_TRUE (BC->MIB ->isImplicitBTIC (*II));
199199}
200200
201+ TEST_P (MCPlusBuilderTester, AArch64_addBTItoBBStart_0) {
202+ if (GetParam () != Triple::aarch64)
203+ GTEST_SKIP ();
204+ BinaryFunction *BF = BC->createInjectedBinaryFunction (" BF" , true );
205+ std::unique_ptr<BinaryBasicBlock> BB = BF->createBasicBlock ();
206+ MCInst Inst = MCInstBuilder (AArch64::RET).addReg (AArch64::LR);
207+ BB->addInstruction (Inst);
208+ // BR x16 needs BTI c or BTI j. We prefer adding a BTI c.
209+ MCInst CallInst = MCInstBuilder (AArch64::BR).addReg (AArch64::X16);
210+ BC->MIB ->addBTItoBBStart (*BB, CallInst);
211+ auto II = BB->begin ();
212+ ASSERT_TRUE (BC->MIB ->isBTILandingPad (*II, true , false ));
213+ }
214+
215+ TEST_P (MCPlusBuilderTester, AArch64_addBTItoBBStart_1) {
216+ if (GetParam () != Triple::aarch64)
217+ GTEST_SKIP ();
218+ BinaryFunction *BF = BC->createInjectedBinaryFunction (" BF" , true );
219+ std::unique_ptr<BinaryBasicBlock> BB = BF->createBasicBlock ();
220+ MCInst BTIc;
221+ BC->MIB ->createBTI (BTIc, true , false );
222+ BB->addInstruction (BTIc);
223+ // BR x16 needs BTI c or BTI j. We have a BTI c, no change is needed.
224+ MCInst CallInst = MCInstBuilder (AArch64::BR).addReg (AArch64::X16);
225+ BC->MIB ->addBTItoBBStart (*BB, CallInst);
226+ auto II = BB->begin ();
227+ ASSERT_TRUE (BC->MIB ->isBTILandingPad (*II, true , false ));
228+ }
229+
230+ TEST_P (MCPlusBuilderTester, AArch64_addBTItoBBStart_2) {
231+ if (GetParam () != Triple::aarch64)
232+ GTEST_SKIP ();
233+ BinaryFunction *BF = BC->createInjectedBinaryFunction (" BF" , true );
234+ std::unique_ptr<BinaryBasicBlock> BB = BF->createBasicBlock ();
235+ MCInst BTIc;
236+ BC->MIB ->createBTI (BTIc, true , false );
237+ BB->addInstruction (BTIc);
238+ // BR x5 needs BTI j
239+ // we have BTI c -> extend it to BTI jc.
240+ MCInst CallInst = MCInstBuilder (AArch64::BR).addReg (AArch64::X5);
241+ BC->MIB ->addBTItoBBStart (*BB, CallInst);
242+ auto II = BB->begin ();
243+ ASSERT_TRUE (BC->MIB ->isBTILandingPad (*II, true , true ));
244+ }
245+
246+ TEST_P (MCPlusBuilderTester, AArch64_addBTItoBBStart_3) {
247+ if (GetParam () != Triple::aarch64)
248+ GTEST_SKIP ();
249+ BinaryFunction *BF = BC->createInjectedBinaryFunction (" BF" , true );
250+ std::unique_ptr<BinaryBasicBlock> BB = BF->createBasicBlock ();
251+ MCInst Inst = MCInstBuilder (AArch64::RET).addReg (AArch64::LR);
252+ BB->addInstruction (Inst);
253+ // BR x5 needs BTI j
254+ MCInst CallInst = MCInstBuilder (AArch64::BR).addReg (AArch64::X5);
255+ BC->MIB ->addBTItoBBStart (*BB, CallInst);
256+ auto II = BB->begin ();
257+ ASSERT_TRUE (BC->MIB ->isBTILandingPad (*II, false , true ));
258+ }
259+
260+ TEST_P (MCPlusBuilderTester, AArch64_addBTItoBBStart_4) {
261+ if (GetParam () != Triple::aarch64)
262+ GTEST_SKIP ();
263+ BinaryFunction *BF = BC->createInjectedBinaryFunction (" BF" , true );
264+ std::unique_ptr<BinaryBasicBlock> BB = BF->createBasicBlock ();
265+ MCInst Inst = MCInstBuilder (AArch64::RET).addReg (AArch64::LR);
266+ BB->addInstruction (Inst);
267+ // BLR needs BTI c, regardless of the register used.
268+ MCInst CallInst = MCInstBuilder (AArch64::BLR).addReg (AArch64::X5);
269+ BC->MIB ->addBTItoBBStart (*BB, CallInst);
270+ auto II = BB->begin ();
271+ ASSERT_TRUE (BC->MIB ->isBTILandingPad (*II, true , false ));
272+ }
273+
274+ TEST_P (MCPlusBuilderTester, AArch64_addBTItoBBStart_5) {
275+ if (GetParam () != Triple::aarch64)
276+ GTEST_SKIP ();
277+ BinaryFunction *BF = BC->createInjectedBinaryFunction (" BF" , true );
278+ std::unique_ptr<BinaryBasicBlock> BB = BF->createBasicBlock ();
279+ MCInst BTIj;
280+ BC->MIB ->createBTI (BTIj, false , true );
281+ BB->addInstruction (BTIj);
282+ // BLR needs BTI c, regardless of the register used.
283+ // We have a BTI j -> extend it to BTI jc.
284+ MCInst CallInst = MCInstBuilder (AArch64::BLR).addReg (AArch64::X5);
285+ BC->MIB ->addBTItoBBStart (*BB, CallInst);
286+ auto II = BB->begin ();
287+ ASSERT_TRUE (BC->MIB ->isBTILandingPad (*II, true , true ));
288+ }
289+
290+ TEST_P (MCPlusBuilderTester, AArch64_addBTItoBBStart_6) {
291+ if (GetParam () != Triple::aarch64)
292+ GTEST_SKIP ();
293+ BinaryFunction *BF = BC->createInjectedBinaryFunction (" BF" , true );
294+ std::unique_ptr<BinaryBasicBlock> BB = BF->createBasicBlock ();
295+ MCInst Paciasp =
296+ MCInstBuilder (AArch64::PACIASP).addReg (AArch64::LR).addReg (AArch64::SP);
297+ BB->addInstruction (Paciasp);
298+ // PACI(AB)SP are implicit BTI c, no change needed.
299+ MCInst CallInst = MCInstBuilder (AArch64::BR).addReg (AArch64::X17);
300+ BC->MIB ->addBTItoBBStart (*BB, CallInst);
301+ auto II = BB->begin ();
302+ ASSERT_TRUE (BC->MIB ->isBTILandingPad (*II, true , false ));
303+ ASSERT_TRUE (BC->MIB ->isPSignOnLR (*II));
304+ }
305+
201306TEST_P (MCPlusBuilderTester, AArch64_CmpJNE) {
202307 if (GetParam () != Triple::aarch64)
203308 GTEST_SKIP ();
0 commit comments