diff options
| author | Kostya Serebryany <kcc@google.com> | 2013-12-23 09:24:36 +0000 |
|---|---|---|
| committer | Kostya Serebryany <kcc@google.com> | 2013-12-23 09:24:36 +0000 |
| commit | ff7bde158253d0af9a9ba525a653dbc074466dee (patch) | |
| tree | a3a0fdec8ae9cf3eb1c7a72cb1ccd7ffaeef565c /llvm/lib/Transforms | |
| parent | b09e5af914a3242c4bf31376e4c51400e5bf9590 (diff) | |
| download | bcm5719-llvm-ff7bde158253d0af9a9ba525a653dbc074466dee.tar.gz bcm5719-llvm-ff7bde158253d0af9a9ba525a653dbc074466dee.zip | |
[asan] produce fewer stores when poisoning stack shadow
llvm-svn: 197904
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index b4c789c5f82..758669f1257 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1351,27 +1351,26 @@ FunctionStackPoisoner::poisonRedZones(const ArrayRef<uint8_t> ShadowBytes, IRBuilder<> &IRB, Value *ShadowBase, bool DoPoison) { size_t n = ShadowBytes.size(); - size_t LargeStoreSize = ASan.LongSize / 8; - size_t i; - for (i = 0; i + LargeStoreSize - 1 < n; i += LargeStoreSize) { - uint64_t Val = 0; - for (size_t j = 0; j < LargeStoreSize; j++) { - if (ASan.TD->isLittleEndian()) - Val |= (uint64_t)ShadowBytes[i + j] << (8 * j); - else - Val = (Val << 8) | ShadowBytes[i + j]; + size_t i = 0; + // We need to (un)poison n bytes of stack shadow. Poison as many as we can + // using 64-bit stores (if we are on 64-bit arch), then poison the rest + // with 32-bit stores, then with 16-byte stores, then with 8-byte stores. + for (size_t LargeStoreSizeInBytes = ASan.LongSize / 8; + LargeStoreSizeInBytes != 0; LargeStoreSizeInBytes /= 2) { + for (; i + LargeStoreSizeInBytes - 1 < n; i += LargeStoreSizeInBytes) { + uint64_t Val = 0; + for (size_t j = 0; j < LargeStoreSizeInBytes; j++) { + if (ASan.TD->isLittleEndian()) + Val |= (uint64_t)ShadowBytes[i + j] << (8 * j); + else + Val = (Val << 8) | ShadowBytes[i + j]; + } + if (!Val) continue; + Value *Ptr = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)); + Type *StoreTy = Type::getIntNTy(*C, LargeStoreSizeInBytes * 8); + Value *Poison = ConstantInt::get(StoreTy, DoPoison ? Val : 0); + IRB.CreateStore(Poison, IRB.CreateIntToPtr(Ptr, StoreTy->getPointerTo())); } - if (!Val) continue; - Value *Ptr = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)); - Value *Poison = ConstantInt::get(IntptrTy, DoPoison ? Val : 0); - IRB.CreateStore(Poison, IRB.CreateIntToPtr(Ptr, IntptrPtrTy)); - } - for (; i < n; i++) { - uint8_t Val = ShadowBytes[i]; - if (!Val) continue; - Value *Ptr = IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)); - Value *Poison = ConstantInt::get(IRB.getInt8Ty(), DoPoison ? Val : 0); - IRB.CreateStore(Poison, IRB.CreateIntToPtr(Ptr, IRB.getInt8PtrTy())); } } |

