Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions libdevice/sanitizer/asan_rtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -935,4 +935,93 @@ __asan_set_private_base(__SYCL_PRIVATE__ void *ptr) {
SubGroupBarrier();
}

// Intercept string functions
#define ASAN_MEMSET(as) \
DEVICE_EXTERN_C_NOINLINE __attribute__((address_space(as))) void * \
__asan_memset_p##as(__attribute__((address_space(as))) char *ptr, int val, \
size_t size, const char __SYCL_CONSTANT__ *file, \
uint32_t line, const char __SYCL_CONSTANT__ *func) { \
if (__AsanLaunchInfo) { \
DebugInfo debug{(uptr)ptr, as, size, true, file, func, line}; \
if (auto poisoned_addr = \
IsRegionPoisoned((uptr)ptr, as, size, &debug)) { \
ReportAccessError(poisoned_addr, as, false, &debug); \
} \
} \
return Memset(ptr, val, size); \
}

ASAN_MEMSET(0)
ASAN_MEMSET(1)
ASAN_MEMSET(3)
ASAN_MEMSET(4)

#define ASAN_MEMCPY_BASE(dst_as, src_as) \
DEVICE_EXTERN_C_NOINLINE __attribute__((address_space(dst_as))) void * \
__asan_memcpy_p##dst_as##_p##src_as( \
__attribute__((address_space(dst_as))) char *dst, \
__attribute__((address_space(src_as))) char *src, size_t size, \
const char __SYCL_CONSTANT__ *file, uint32_t line, \
const char __SYCL_CONSTANT__ *func) { \
if (__AsanLaunchInfo) { \
DebugInfo debug_dst{(uptr)dst, dst_as, size, true, file, func, line}; \
if (auto poisoned_addr = \
IsRegionPoisoned((uptr)dst, dst_as, size, &debug_dst)) { \
ReportAccessError(poisoned_addr, dst_as, false, &debug_dst); \
} \
DebugInfo debug_src{(uptr)src, src_as, size, false, file, func, line}; \
if (auto poisoned_addr = \
IsRegionPoisoned((uptr)src, src_as, size, &debug_src)) { \
ReportAccessError(poisoned_addr, src_as, false, &debug_src); \
} \
} \
return Memcpy(dst, src, size); \
}

#define ASAN_MEMCPY(dst_as) \
ASAN_MEMCPY_BASE(dst_as, 0) \
ASAN_MEMCPY_BASE(dst_as, 1) \
ASAN_MEMCPY_BASE(dst_as, 2) \
ASAN_MEMCPY_BASE(dst_as, 3) \
ASAN_MEMCPY_BASE(dst_as, 4)

ASAN_MEMCPY(0)
ASAN_MEMCPY(1)
ASAN_MEMCPY(3)
ASAN_MEMCPY(4)

#define ASAN_MEMMOVE_BASE(dst_as, src_as) \
DEVICE_EXTERN_C_NOINLINE __attribute__((address_space(dst_as))) void * \
__asan_memmove_p##dst_as##_p##src_as( \
__attribute__((address_space(dst_as))) char *dst, \
__attribute__((address_space(src_as))) char *src, size_t size, \
const char __SYCL_CONSTANT__ *file, uint32_t line, \
const char __SYCL_CONSTANT__ *func) { \
if (__AsanLaunchInfo) { \
DebugInfo debug_dst{(uptr)dst, dst_as, size, true, file, func, line}; \
if (auto poisoned_addr = \
IsRegionPoisoned((uptr)dst, dst_as, size, &debug_dst)) { \
ReportAccessError(poisoned_addr, dst_as, false, &debug_dst); \
} \
DebugInfo debug_src{(uptr)src, src_as, size, false, file, func, line}; \
if (auto poisoned_addr = \
IsRegionPoisoned((uptr)src, src_as, size, &debug_src)) { \
ReportAccessError(poisoned_addr, src_as, false, &debug_src); \
} \
} \
return Memmove(dst, src, size); \
}

#define ASAN_MEMMOVE(dst_as) \
ASAN_MEMMOVE_BASE(dst_as, 0) \
ASAN_MEMMOVE_BASE(dst_as, 1) \
ASAN_MEMMOVE_BASE(dst_as, 2) \
ASAN_MEMMOVE_BASE(dst_as, 3) \
ASAN_MEMMOVE_BASE(dst_as, 4)

ASAN_MEMMOVE(0)
ASAN_MEMMOVE(1)
ASAN_MEMMOVE(3)
ASAN_MEMMOVE(4)

#endif // __SPIR__ || __SPIRV__
113 changes: 92 additions & 21 deletions llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,7 @@ struct AddressSanitizer {
bool instrumentSyclDynamicLocalMemory(Function &F);
void instrumentInitAsanLaunchInfo(Function &F, const TargetLibraryInfo *TLI);

void AppendDebugInfoToArgs(Instruction *InsertBefore, Value *Addr,
void AppendDebugInfoToArgs(Instruction *InsertBefore,
SmallVectorImpl<Value *> &Args);

private:
Expand Down Expand Up @@ -964,6 +964,9 @@ struct AddressSanitizer {
FunctionCallee AsanMemoryAccessCallbackSizedAS[2][2][kNumberOfAddressSpace];

FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
FunctionCallee AsanMemcpyAS[kNumberOfAddressSpace][kNumberOfAddressSpace],
AsanMemmoveAS[kNumberOfAddressSpace][kNumberOfAddressSpace],
AsanMemsetAS[kNumberOfAddressSpace];
Value *LocalDynamicShadow = nullptr;
const StackSafetyGlobalInfo *SSGI;
DenseMap<const AllocaInst *, bool> ProcessedAllocas;
Expand Down Expand Up @@ -1355,7 +1358,7 @@ class AddressSanitizerOnSpirv {
void initializeCallbacks() {
IRBuilder<> IRB(*C);

// __msan_set_private_base(
// __asan_set_private_base(
// as(0) void * ptr
// )
AsanSetPrivateBaseFunc =
Expand Down Expand Up @@ -1803,7 +1806,6 @@ static bool isUnsupportedSPIRAccess(Value *Addr, Instruction *Inst) {
}

void AddressSanitizer::AppendDebugInfoToArgs(Instruction *InsertBefore,
Value *Addr,
SmallVectorImpl<Value *> &Args) {
auto *M = InsertBefore->getModule();
auto &C = InsertBefore->getContext();
Expand Down Expand Up @@ -1933,17 +1935,48 @@ void AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI,
RuntimeCallInserter &RTCI) {
InstrumentationIRBuilder IRB(MI);
if (isa<MemTransferInst>(MI)) {
RTCI.createRuntimeCall(
IRB, isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy,
{IRB.CreateAddrSpaceCast(MI->getOperand(0), PtrTy),
IRB.CreateAddrSpaceCast(MI->getOperand(1), PtrTy),
IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
if (TargetTriple.isSPIROrSPIRV()) {
unsigned int DstAS =
cast<PointerType>(MI->getOperand(0)->getType()->getScalarType())
->getPointerAddressSpace();
unsigned int SrcAS =
cast<PointerType>(MI->getOperand(1)->getType()->getScalarType())
->getPointerAddressSpace();
SmallVector<Value *, 6> Args;
Args.push_back(MI->getOperand(0));
Args.push_back(MI->getOperand(1));
Args.push_back(IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false));
AppendDebugInfoToArgs(MI, Args);
RTCI.createRuntimeCall(IRB,
isa<MemMoveInst>(MI) ? AsanMemmoveAS[DstAS][SrcAS]
: AsanMemcpyAS[DstAS][SrcAS],
Args);
} else {
RTCI.createRuntimeCall(
IRB, isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy,
{IRB.CreateAddrSpaceCast(MI->getOperand(0), PtrTy),
IRB.CreateAddrSpaceCast(MI->getOperand(1), PtrTy),
IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
}
} else if (isa<MemSetInst>(MI)) {
RTCI.createRuntimeCall(
IRB, AsanMemset,
{IRB.CreateAddrSpaceCast(MI->getOperand(0), PtrTy),
IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
if (TargetTriple.isSPIROrSPIRV()) {
unsigned int AS =
cast<PointerType>(MI->getOperand(0)->getType()->getScalarType())
->getPointerAddressSpace();
SmallVector<Value *, 6> Args;
Args.push_back(MI->getOperand(0));
Args.push_back(
IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false));
Args.push_back(IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false));
AppendDebugInfoToArgs(MI, Args);
RTCI.createRuntimeCall(IRB, AsanMemsetAS[AS], Args);
} else {
RTCI.createRuntimeCall(
IRB, AsanMemset,
{IRB.CreateAddrSpaceCast(MI->getOperand(0), PtrTy),
IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
}
}
MI->eraseFromParent();
}
Expand Down Expand Up @@ -2496,7 +2529,7 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
auto AS = cast<PointerType>(Addr->getType()->getScalarType())
->getPointerAddressSpace();
Args.push_back(AddrLong);
AppendDebugInfoToArgs(InsertBefore, Addr, Args);
AppendDebugInfoToArgs(InsertBefore, Args);
RTCI.createRuntimeCall(
IRB, AsanMemoryAccessCallbackAS[IsWrite][0][AccessSizeIndex][AS],
Args);
Expand Down Expand Up @@ -2582,7 +2615,7 @@ void AddressSanitizer::instrumentUnusualSizeOrAlignment(
->getPointerAddressSpace();
Args.push_back(AddrLong);
Args.push_back(Size);
AppendDebugInfoToArgs(InsertBefore, Addr, Args);
AppendDebugInfoToArgs(InsertBefore, Args);
RTCI.createRuntimeCall(
IRB, AsanMemoryAccessCallbackSizedAS[IsWrite][0][AS], Args);
} else {
Expand Down Expand Up @@ -3774,6 +3807,46 @@ void AddressSanitizer::initializeCallbacks(const TargetLibraryInfo *TLI) {
}
}

if (TargetTriple.isSPIROrSPIRV()) {
auto *Int8PtrTy = PointerType::get(*C, kSpirOffloadConstantAS);
for (size_t FirstArgAS = 0; FirstArgAS < kNumberOfAddressSpace;
FirstArgAS++) {
PointerType *FirstArgPtrTy = PointerType::get(*C, FirstArgAS);
// __asan_memset_pX (
// ...
// char* file,
// unsigned int line,
// char* func
// )
AsanMemsetAS[FirstArgAS] = M.getOrInsertFunction(
ClMemoryAccessCallbackPrefix + "memset_p" + itostr(FirstArgAS),
TLI->getAttrList(C, {1}, /*Signed=*/false), FirstArgPtrTy,
FirstArgPtrTy, IRB.getInt32Ty(), IntptrTy, Int8PtrTy,
IRB.getInt32Ty(), Int8PtrTy);

for (size_t SecondArgAS = 0; SecondArgAS < kNumberOfAddressSpace;
SecondArgAS++) {
PointerType *SecondArgPtrTy = PointerType::get(*C, SecondArgAS);
// __asan_mem[cpy|move]_pX_pX (
// ...
// char* file,
// unsigned int line,
// char* func
// )
AsanMemcpyAS[FirstArgAS][SecondArgAS] = M.getOrInsertFunction(
ClMemoryAccessCallbackPrefix + "memcpy_p" + itostr(FirstArgAS) +
"_p" + itostr(SecondArgAS),
FirstArgPtrTy, FirstArgPtrTy, SecondArgPtrTy, IntptrTy, Int8PtrTy,
IRB.getInt32Ty(), Int8PtrTy);
AsanMemmoveAS[FirstArgAS][SecondArgAS] = M.getOrInsertFunction(
ClMemoryAccessCallbackPrefix + "memmove_p" + itostr(FirstArgAS) +
"_p" + itostr(SecondArgAS),
FirstArgPtrTy, FirstArgPtrTy, SecondArgPtrTy, IntptrTy, Int8PtrTy,
IRB.getInt32Ty(), Int8PtrTy);
}
}
}

const std::string MemIntrinCallbackPrefix =
(CompileKernel && !ClKasanMemIntrinCallbackPrefix)
? std::string("")
Expand Down Expand Up @@ -4048,12 +4121,10 @@ bool AddressSanitizer::instrumentFunction(Function &F,
F.getDataLayout(), RTCI);
FunctionModified = true;
}
if (!TargetTriple.isSPIROrSPIRV()) {
for (auto *Inst : IntrinToInstrument) {
if (!suppressInstrumentationSiteForDebug(NumInstrumented))
instrumentMemIntrinsic(Inst, RTCI);
FunctionModified = true;
}
for (auto *Inst : IntrinToInstrument) {
if (!suppressInstrumentationSiteForDebug(NumInstrumented))
instrumentMemIntrinsic(Inst, RTCI);
FunctionModified = true;
}

FunctionStackPoisoner FSP(F, *this, RTCI);
Expand Down
Loading