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