diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -42,6 +42,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" +#include "llvm/IR/NoFolder.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" @@ -579,7 +580,8 @@ UseShortGranules = ClUseShortGranules.getNumOccurrences() ? ClUseShortGranules : NewRuntime; OutlinedChecks = - TargetTriple.isAArch64() && TargetTriple.isOSBinFormatELF() && + (TargetTriple.isAArch64() || TargetTriple.isRISCV64()) && + TargetTriple.isOSBinFormatELF() && (ClInlineAllChecks.getNumOccurrences() ? !ClInlineAllChecks : !Recover); if (ClMatchAllTag.getNumOccurrences()) { @@ -602,7 +604,10 @@ bool InstrumentGlobals = ClGlobals.getNumOccurrences() ? ClGlobals : NewRuntime; - if (InstrumentGlobals && !UsePageAliases) + // Currently we do not instrumentation of globals for RISCV + // The reason is that the existing memory models does not allow us + // to use tagged pointers in la/lla expressions + if (InstrumentGlobals && !UsePageAliases && !TargetTriple.isRISCV64()) instrumentGlobals(); bool InstrumentPersonalityFunctions = @@ -791,7 +796,8 @@ } void HWAddressSanitizer::untagPointerOperand(Instruction *I, Value *Addr) { - if (TargetTriple.isAArch64() || TargetTriple.getArch() == Triple::x86_64) + if (TargetTriple.isAArch64() || TargetTriple.getArch() == Triple::x86_64 || + TargetTriple.isRISCV64()) return; IRBuilder<> IRB(I); @@ -828,8 +834,9 @@ IRBuilder<> IRB(InsertBefore); Module *M = IRB.GetInsertBlock()->getParent()->getParent(); Ptr = IRB.CreateBitCast(Ptr, Int8PtrTy); + // In case of RISC-V always use shortgranules IRB.CreateCall(Intrinsic::getDeclaration( - M, UseShortGranules + M, UseShortGranules || TargetTriple.isRISCV64() ? Intrinsic::hwasan_check_memaccess_shortgranules : Intrinsic::hwasan_check_memaccess), {ShadowBase, Ptr, ConstantInt::get(Int32Ty, AccessInfo)}); @@ -909,6 +916,13 @@ "{x0}", /*hasSideEffects=*/true); break; + case Triple::riscv64: + // The signal handler will find the data address in x10. + Asm = InlineAsm::get( + FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false), + "ebreak\naddiw x0, x0, " + itostr(0x40 + AccessInfo), "{x10}", "{x11}", + /*hasSideEffects=*/true); + break; default: report_fatal_error("unsupported architecture"); }