#include "AArch64TargetObjectFile.h"
#include "InstPrinter/AArch64InstPrinter.h"
#include "MCTargetDesc/AArch64AddressingModes.h"
+#include "MCTargetDesc/AArch64MCExpr.h"
#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "MCTargetDesc/AArch64TargetStreamer.h"
#include "Utils/AArch64BaseInfo.h"
MCSymbol *HwasanTagMismatchSym =
OutContext.getOrCreateSymbol("__hwasan_tag_mismatch");
+ const MCSymbolRefExpr *HwasanTagMismatchRef =
+ MCSymbolRefExpr::create(HwasanTagMismatchSym, OutContext);
+
for (auto &P : HwasanMemaccessSymbols) {
unsigned Reg = P.first.first;
uint32_t AccessInfo = P.first.second;
MCInstBuilder(AArch64::RET).addReg(AArch64::LR), *STI);
OutStreamer->EmitLabel(HandleMismatchSym);
+
+ OutStreamer->EmitInstruction(MCInstBuilder(AArch64::STPXpre)
+ .addReg(AArch64::SP)
+ .addReg(AArch64::X0)
+ .addReg(AArch64::X1)
+ .addReg(AArch64::SP)
+ .addImm(-32),
+ *STI);
+ OutStreamer->EmitInstruction(MCInstBuilder(AArch64::STPXi)
+ .addReg(AArch64::FP)
+ .addReg(AArch64::LR)
+ .addReg(AArch64::SP)
+ .addImm(29),
+ *STI);
+
if (Reg != AArch64::X0)
OutStreamer->EmitInstruction(MCInstBuilder(AArch64::ORRXrs)
.addReg(AArch64::X0)
.addImm(AccessInfo)
.addImm(0),
*STI);
+
+ // Intentionally load the GOT entry and branch to it, rather than possibly
+ // late binding the function, which may clobber the registers before we have
+ // a chance to save them.
OutStreamer->EmitInstruction(
- MCInstBuilder(AArch64::B)
- .addExpr(MCSymbolRefExpr::create(HwasanTagMismatchSym, OutContext)),
+ MCInstBuilder(AArch64::ADRP)
+ .addReg(AArch64::X16)
+ .addExpr(AArch64MCExpr::create(
+ HwasanTagMismatchRef,
+ AArch64MCExpr::VariantKind::VK_GOT_PAGE, OutContext)),
*STI);
+ OutStreamer->EmitInstruction(
+ MCInstBuilder(AArch64::LDRXui)
+ .addReg(AArch64::X16)
+ .addReg(AArch64::X16)
+ .addExpr(AArch64MCExpr::create(
+ HwasanTagMismatchRef,
+ AArch64MCExpr::VariantKind::VK_GOT_LO12, OutContext)),
+ *STI);
+ OutStreamer->EmitInstruction(
+ MCInstBuilder(AArch64::BR).addReg(AArch64::X16), *STI);
}
}
; CHECK-NEXT: b.ne .Ltmp0
; CHECK-NEXT: ret
; CHECK-NEXT: .Ltmp0:
+; CHECK-NEXT: stp x0, x1, [sp, #-256]!
+; CHECK-NEXT: stp x29, x30, [sp, #232]
; CHECK-NEXT: mov x1, #456
-; CHECK-NEXT: b __hwasan_tag_mismatch
+; CHECK-NEXT: adrp x16, :got:__hwasan_tag_mismatch
+; CHECK-NEXT: ldr x16, [x16, :got_lo12:__hwasan_tag_mismatch]
+; CHECK-NEXT: br x16
+
; CHECK: .section .text.hot,"axG",@progbits,__hwasan_check_x1_123,comdat
; CHECK-NEXT: .type __hwasan_check_x1_123,@function
; CHECK-NEXT: b.ne .Ltmp1
; CHECK-NEXT: ret
; CHECK-NEXT: .Ltmp1:
+; CHECK-NEXT: stp x0, x1, [sp, #-256]!
+; CHECK-NEXT: stp x29, x30, [sp, #232]
; CHECK-NEXT: mov x0, x1
; CHECK-NEXT: mov x1, #123
-; CHECK-NEXT: b __hwasan_tag_mismatch
+; CHECK-NEXT: adrp x16, :got:__hwasan_tag_mismatch
+; CHECK-NEXT: ldr x16, [x16, :got_lo12:__hwasan_tag_mismatch]
+; CHECK-NEXT: br x16