mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
[sanitizer] [dfsan] Unify aarch64 mapping
This patch changes the DFSan instrumentation for aarch64 to instead of using fixes application mask defined by SANITIZER_AARCH64_VMA to read the application shadow mask value from compiler-rt. The value is initialized based on runtime VAM detection. Along with this patch a compiler-rt one will also be added to export the shadow mask variable. llvm-svn: 254196
This commit is contained in:
parent
916150a366
commit
fd321f0647
@ -72,15 +72,10 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
// VMA size definition for architecture that support multiple sizes.
|
||||
// AArch64 has 3 VMA sizes: 39, 42 and 48.
|
||||
#ifndef SANITIZER_AARCH64_VMA
|
||||
# define SANITIZER_AARCH64_VMA 39
|
||||
#else
|
||||
# if SANITIZER_AARCH64_VMA != 39 && SANITIZER_AARCH64_VMA != 42
|
||||
# error "invalid SANITIZER_AARCH64_VMA size"
|
||||
# endif
|
||||
#endif
|
||||
// External symbol to be used when generating the shadow address for
|
||||
// architectures with multiple VMAs. Instead of using a constant integer
|
||||
// the runtime will set the external mask based on the VMA range.
|
||||
static const char *const kDFSanExternShadowPtrMask = "__dfsan_shadow_ptr_mask";
|
||||
|
||||
// The -dfsan-preserve-alignment flag controls whether this pass assumes that
|
||||
// alignment requirements provided by the input IR are correct. For example,
|
||||
@ -134,6 +129,7 @@ static cl::opt<bool> ClDebugNonzeroLabels(
|
||||
"load or return with a nonzero label"),
|
||||
cl::Hidden);
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
StringRef GetGlobalTypeString(const GlobalValue &G) {
|
||||
@ -241,6 +237,7 @@ class DataFlowSanitizer : public ModulePass {
|
||||
void *(*GetRetvalTLSPtr)();
|
||||
Constant *GetArgTLS;
|
||||
Constant *GetRetvalTLS;
|
||||
Constant *ExternalShadowMask;
|
||||
FunctionType *DFSanUnionFnTy;
|
||||
FunctionType *DFSanUnionLoadFnTy;
|
||||
FunctionType *DFSanUnimplementedFnTy;
|
||||
@ -258,6 +255,7 @@ class DataFlowSanitizer : public ModulePass {
|
||||
DFSanABIList ABIList;
|
||||
DenseMap<Value *, Function *> UnwrappedFnMap;
|
||||
AttributeSet ReadOnlyNoneAttrs;
|
||||
bool DFSanRuntimeShadowMask;
|
||||
|
||||
Value *getShadowAddress(Value *Addr, Instruction *Pos);
|
||||
bool isInstrumented(const Function *F);
|
||||
@ -371,7 +369,8 @@ llvm::createDataFlowSanitizerPass(const std::vector<std::string> &ABIListFiles,
|
||||
DataFlowSanitizer::DataFlowSanitizer(
|
||||
const std::vector<std::string> &ABIListFiles, void *(*getArgTLS)(),
|
||||
void *(*getRetValTLS)())
|
||||
: ModulePass(ID), GetArgTLSPtr(getArgTLS), GetRetvalTLSPtr(getRetValTLS) {
|
||||
: ModulePass(ID), GetArgTLSPtr(getArgTLS), GetRetvalTLSPtr(getRetValTLS),
|
||||
DFSanRuntimeShadowMask(false) {
|
||||
std::vector<std::string> AllABIListFiles(std::move(ABIListFiles));
|
||||
AllABIListFiles.insert(AllABIListFiles.end(), ClABIListFiles.begin(),
|
||||
ClABIListFiles.end());
|
||||
@ -445,12 +444,9 @@ bool DataFlowSanitizer::doInitialization(Module &M) {
|
||||
ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x700000000000LL);
|
||||
else if (IsMIPS64)
|
||||
ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0xF000000000LL);
|
||||
// AArch64 supports multiple VMAs and the shadow mask is set at runtime.
|
||||
else if (IsAArch64)
|
||||
#if SANITIZER_AARCH64_VMA == 39
|
||||
ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x7800000000LL);
|
||||
#else
|
||||
ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x3c000000000LL);
|
||||
#endif
|
||||
DFSanRuntimeShadowMask = true;
|
||||
else
|
||||
report_fatal_error("unsupported triple");
|
||||
|
||||
@ -621,6 +617,9 @@ bool DataFlowSanitizer::runOnModule(Module &M) {
|
||||
G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
|
||||
}
|
||||
|
||||
ExternalShadowMask =
|
||||
Mod->getOrInsertGlobal(kDFSanExternShadowPtrMask, IntptrTy);
|
||||
|
||||
DFSanUnionFn = Mod->getOrInsertFunction("__dfsan_union", DFSanUnionFnTy);
|
||||
if (Function *F = dyn_cast<Function>(DFSanUnionFn)) {
|
||||
F->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
|
||||
@ -938,9 +937,15 @@ void DFSanFunction::setShadow(Instruction *I, Value *Shadow) {
|
||||
Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) {
|
||||
assert(Addr != RetvalTLS && "Reinstrumenting?");
|
||||
IRBuilder<> IRB(Pos);
|
||||
Value *ShadowPtrMaskValue;
|
||||
if (DFSanRuntimeShadowMask)
|
||||
ShadowPtrMaskValue = IRB.CreateLoad(IntptrTy, ExternalShadowMask);
|
||||
else
|
||||
ShadowPtrMaskValue = ShadowPtrMask;
|
||||
return IRB.CreateIntToPtr(
|
||||
IRB.CreateMul(
|
||||
IRB.CreateAnd(IRB.CreatePtrToInt(Addr, IntptrTy), ShadowPtrMask),
|
||||
IRB.CreateAnd(IRB.CreatePtrToInt(Addr, IntptrTy),
|
||||
IRB.CreatePtrToInt(ShadowPtrMaskValue, IntptrTy)),
|
||||
ShadowPtrMul),
|
||||
ShadowPtrTy);
|
||||
}
|
||||
|
14
test/Instrumentation/DataFlowSanitizer/external_mask.ll
Normal file
14
test/Instrumentation/DataFlowSanitizer/external_mask.ll
Normal file
@ -0,0 +1,14 @@
|
||||
; RUN: opt < %s -dfsan -S | FileCheck %s
|
||||
target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
|
||||
target triple = "aarch64-unknown-linux-gnu"
|
||||
|
||||
define i32 @test(i32 %a, i32* nocapture readonly %b) #0 {
|
||||
; CHECK: @"dfs$test"
|
||||
; CHECK: %[[RV:.*]] load{{.*}}__dfsan_shadow_ptr_mask
|
||||
; CHECK: ptrtoint i32* {{.*}} to i64
|
||||
; CHECK: and {{.*}}%[[RV:.*]]
|
||||
; CHECK: mul i64
|
||||
%1 = load i32, i32* %b, align 4
|
||||
%2 = add nsw i32 %1, %a
|
||||
ret i32 %2
|
||||
}
|
Loading…
Reference in New Issue
Block a user