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