@@ -1966,6 +1966,15 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
1966
1966
convertJmpToTailCall (Inst);
1967
1967
}
1968
1968
1969
+ void createDirectBranch (MCInst &Inst, const MCSymbol *Target,
1970
+ MCContext *Ctx) override {
1971
+ Inst.setOpcode (AArch64::B);
1972
+ Inst.clear ();
1973
+ Inst.addOperand (MCOperand::createExpr (getTargetExprFor (
1974
+ Inst, MCSymbolRefExpr::create (Target, MCSymbolRefExpr::VK_None, *Ctx),
1975
+ *Ctx, 0 )));
1976
+ }
1977
+
1969
1978
bool analyzeBranch (InstructionIterator Begin, InstructionIterator End,
1970
1979
const MCSymbol *&TBB, const MCSymbol *&FBB,
1971
1980
MCInst *&CondBranch,
@@ -2328,21 +2337,26 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
2328
2337
}
2329
2338
2330
2339
InstructionListType createInstrumentedIndCallHandlerExitBB () const override {
2331
- InstructionListType Insts (5 );
2332
2340
// Code sequence for instrumented indirect call handler:
2341
+ // ldr x1, [sp, #16]
2333
2342
// msr nzcv, x1
2334
2343
// ldp x0, x1, [sp], #16
2335
- // ldr x16, [sp], #16
2336
- // ldp x0, x1, [sp], #16
2337
- // br x16
2338
- setSystemFlag (Insts[0 ], AArch64::X1);
2339
- createPopRegisters (Insts[1 ], AArch64::X0, AArch64::X1);
2340
- // Here we load address of the next function which should be called in the
2341
- // original binary to X16 register. Writing to X16 is permitted without
2342
- // needing to restore.
2343
- loadReg (Insts[2 ], AArch64::X16, AArch64::SP);
2344
- createPopRegisters (Insts[3 ], AArch64::X0, AArch64::X1);
2345
- createIndirectBranch (Insts[4 ], AArch64::X16, 0 );
2344
+ // ret
2345
+
2346
+ InstructionListType Insts;
2347
+
2348
+ Insts.emplace_back ();
2349
+ loadReg (Insts.back (), AArch64::X1, AArch64::SP);
2350
+
2351
+ Insts.emplace_back ();
2352
+ setSystemFlag (Insts.back (), AArch64::X1);
2353
+
2354
+ Insts.emplace_back ();
2355
+ createPopRegisters (Insts.back (), AArch64::X0, AArch64::X1);
2356
+
2357
+ Insts.emplace_back ();
2358
+ createReturn (Insts.back ());
2359
+
2346
2360
return Insts;
2347
2361
}
2348
2362
@@ -2418,39 +2432,69 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
2418
2432
MCSymbol *HandlerFuncAddr,
2419
2433
int CallSiteID,
2420
2434
MCContext *Ctx) override {
2421
- InstructionListType Insts;
2422
2435
// Code sequence used to enter indirect call instrumentation helper:
2423
- // stp x0, x1, [sp, #-16]! createPushRegisters
2436
+ // stp x0, x1, [sp, #-16]! createPushRegisters (1)
2424
2437
// mov target x0 convertIndirectCallToLoad -> orr x0 target xzr
2425
2438
// mov x1 CallSiteID createLoadImmediate ->
2426
2439
// movk x1, #0x0, lsl #48
2427
2440
// movk x1, #0x0, lsl #32
2428
2441
// movk x1, #0x0, lsl #16
2429
2442
// movk x1, #0x0
2430
- // stp x0, x1, [sp, #-16]!
2431
- // bl *HandlerFuncAddr createIndirectCall ->
2443
+ // stp x0, x1, [sp, #-16]! (2)
2432
2444
// adr x0 *HandlerFuncAddr -> adrp + add
2433
- // blr x0
2445
+ // str x30, [sp, #-16]! (3)
2446
+ // blr x0 (__bolt_instr_ind_call_handler_func)
2447
+ // ldr x30, sp, #16 (3)
2448
+ // ldp x0, x1, [sp], #16 (2)
2449
+ // mov x0, x0 ; move target address to used register
2450
+ // ldp x0, x1, [sp], #16 (1)
2451
+
2452
+ InstructionListType Insts;
2434
2453
Insts.emplace_back ();
2435
- createPushRegisters (Insts.back (), AArch64::X0, AArch64::X1);
2454
+ createPushRegisters (Insts.back (), getIntArgRegister (0 ),
2455
+ getIntArgRegister (1 ));
2436
2456
Insts.emplace_back (CallInst);
2437
- convertIndirectCallToLoad (Insts.back (), AArch64::X0 );
2457
+ convertIndirectCallToLoad (Insts.back (), getIntArgRegister ( 0 ) );
2438
2458
InstructionListType LoadImm =
2439
2459
createLoadImmediate (getIntArgRegister (1 ), CallSiteID);
2440
2460
Insts.insert (Insts.end (), LoadImm.begin (), LoadImm.end ());
2441
2461
Insts.emplace_back ();
2442
- createPushRegisters (Insts.back (), AArch64::X0, AArch64::X1);
2462
+ createPushRegisters (Insts.back (), getIntArgRegister (0 ),
2463
+ getIntArgRegister (1 ));
2443
2464
Insts.resize (Insts.size () + 2 );
2444
- InstructionListType Addr =
2445
- materializeAddress ( HandlerFuncAddr, Ctx, AArch64::X0 );
2465
+ InstructionListType Addr = materializeAddress (
2466
+ HandlerFuncAddr, Ctx, CallInst. getOperand ( 0 ). getReg () );
2446
2467
assert (Addr.size () == 2 && " Invalid Addr size" );
2447
2468
std::copy (Addr.begin (), Addr.end (), Insts.end () - Addr.size ());
2469
+
2470
+ Insts.emplace_back ();
2471
+ storeReg (Insts.back (), AArch64::LR, getSpRegister (/* Size*/ 8 ));
2472
+
2473
+ Insts.emplace_back ();
2474
+ createIndirectCallInst (Insts.back (), false ,
2475
+ CallInst.getOperand (0 ).getReg ());
2476
+
2448
2477
Insts.emplace_back ();
2449
- createIndirectCallInst (Insts.back (), isTailCall (CallInst), AArch64::X0 );
2478
+ loadReg (Insts.back (), AArch64::LR, getSpRegister ( /* Size */ 8 ) );
2450
2479
2451
- // Carry over metadata including tail call marker if present.
2452
- stripAnnotations (Insts.back ());
2453
- moveAnnotations (std::move (CallInst), Insts.back ());
2480
+ Insts.emplace_back ();
2481
+ createPopRegisters (Insts.back (), getIntArgRegister (0 ),
2482
+ getIntArgRegister (1 ));
2483
+
2484
+ // move x0 to indirect call register
2485
+ Insts.emplace_back ();
2486
+ Insts.back ().setOpcode (AArch64::ORRXrs);
2487
+ Insts.back ().insert (Insts.back ().begin (),
2488
+ MCOperand::createReg (CallInst.getOperand (0 ).getReg ()));
2489
+ Insts.back ().insert (Insts.back ().begin () + 1 ,
2490
+ MCOperand::createReg (AArch64::XZR));
2491
+ Insts.back ().insert (Insts.back ().begin () + 2 ,
2492
+ MCOperand::createReg (getIntArgRegister (0 )));
2493
+ Insts.back ().insert (Insts.back ().begin () + 3 , MCOperand::createImm (0 ));
2494
+
2495
+ Insts.emplace_back ();
2496
+ createPopRegisters (Insts.back (), getIntArgRegister (0 ),
2497
+ getIntArgRegister (1 ));
2454
2498
2455
2499
return Insts;
2456
2500
}
@@ -2472,30 +2516,44 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
2472
2516
// ldr x30, [sp], #16
2473
2517
// b IndCallHandler
2474
2518
InstructionListType Insts;
2519
+
2475
2520
Insts.emplace_back ();
2476
- createPushRegisters (Insts.back (), AArch64::X0, AArch64::X1);
2521
+ createPushRegisters (Insts.back (), getIntArgRegister (0 ),
2522
+ getIntArgRegister (1 ));
2523
+
2477
2524
Insts.emplace_back ();
2478
2525
getSystemFlag (Insts.back (), getIntArgRegister (1 ));
2526
+
2527
+ Insts.emplace_back ();
2528
+ storeReg (Insts.back (), getIntArgRegister (1 ), getSpRegister (/* Size*/ 8 ));
2529
+
2479
2530
Insts.emplace_back ();
2480
2531
Insts.emplace_back ();
2481
2532
InstructionListType Addr =
2482
- materializeAddress (InstrTrampoline, Ctx, AArch64::X0 );
2533
+ materializeAddress (InstrTrampoline, Ctx, getIntArgRegister ( 0 ) );
2483
2534
std::copy (Addr.begin (), Addr.end (), Insts.end () - Addr.size ());
2484
2535
assert (Addr.size () == 2 && " Invalid Addr size" );
2536
+
2485
2537
Insts.emplace_back ();
2486
- loadReg (Insts.back (), AArch64::X0, AArch64::X0);
2538
+ loadReg (Insts.back (), getIntArgRegister (0 ), getIntArgRegister (0 ));
2539
+
2487
2540
InstructionListType cmpJmp =
2488
- createCmpJE (AArch64::X0 , 0 , IndCallHandler, Ctx);
2541
+ createCmpJE (getIntArgRegister ( 0 ) , 0 , IndCallHandler, Ctx);
2489
2542
Insts.insert (Insts.end (), cmpJmp.begin (), cmpJmp.end ());
2543
+
2490
2544
Insts.emplace_back ();
2491
- storeReg (Insts.back (), AArch64::LR, AArch64::SP);
2545
+ storeReg (Insts.back (), AArch64::LR, getSpRegister (/* Size*/ 8 ));
2546
+
2492
2547
Insts.emplace_back ();
2493
2548
Insts.back ().setOpcode (AArch64::BLR);
2494
- Insts.back ().addOperand (MCOperand::createReg (AArch64::X0));
2549
+ Insts.back ().addOperand (MCOperand::createReg (getIntArgRegister (0 )));
2550
+
2495
2551
Insts.emplace_back ();
2496
- loadReg (Insts.back (), AArch64::LR, AArch64::SP);
2552
+ loadReg (Insts.back (), AArch64::LR, getSpRegister (/* Size*/ 8 ));
2553
+
2497
2554
Insts.emplace_back ();
2498
- createDirectCall (Insts.back (), IndCallHandler, Ctx, /* IsTailCall*/ true );
2555
+ createDirectBranch (Insts.back (), IndCallHandler, Ctx);
2556
+
2499
2557
return Insts;
2500
2558
}
2501
2559
0 commit comments