Chromium Code Reviews| Index: src/IceASanInstrumentation.cpp |
| diff --git a/src/IceASanInstrumentation.cpp b/src/IceASanInstrumentation.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f17b14f210b45dbb4480d1d16cdfc2b879c6ea67 |
| --- /dev/null |
| +++ b/src/IceASanInstrumentation.cpp |
| @@ -0,0 +1,109 @@ |
| +//===- subzero/src/IceASanInstrumentation.cpp - ASan ------------*- C++ -*-===// |
| +// |
| +// The Subzero Code Generator |
| +// |
| +// This file is distributed under the University of Illinois Open Source |
| +// License. See LICENSE.TXT for details. |
| +// |
| +//===----------------------------------------------------------------------===// |
| +/// |
| +/// \file |
| +/// \brief Implements the AddressSanitizer instrumentation class. |
| +/// |
| +//===----------------------------------------------------------------------===// |
| + |
| +#include "IceASanInstrumentation.h" |
| + |
| +#include "IceBuildDefs.h" |
| +#include "IceGlobalInits.h" |
| + |
| +#include <sstream> |
| + |
| +namespace Ice { |
| + |
| +const std::string ASanInstrumentation::RzPrefix = "__$rz"; |
| +const llvm::NaClBitcodeRecord::RecordVector ASanInstrumentation::RzContents = |
| + llvm::NaClBitcodeRecord::RecordVector(RzSize, 'R'); |
|
Karl
2016/06/10 18:04:50
Minor nit. Since these globals are not needed in t
tlively
2016/06/10 19:17:22
Done.
|
| + |
| +// Create redzones between all global variables, ensuring that the initializer |
| +// types of the redzones and their associated globals match so that they are |
| +// laid out together in memory. |
| +void ASanInstrumentation::instrumentGlobals(VariableDeclarationList &Globals) { |
| + if (BuildDefs::minimal() || DidInsertRedZones) |
| + return; |
| + |
| + VariableDeclarationList NewGlobals; |
| + // Global holding pointers to all redzones |
| + VariableDeclaration *RzArray = VariableDeclaration::create(&NewGlobals); |
| + // Global holding the size of RzArray |
| + VariableDeclaration *RzArraySizeVar = |
| + VariableDeclaration::create(&NewGlobals); |
| + static SizeT RzArraySize = 0; |
| + |
| + RzArray->setName(Ctx, nextRzName()); |
| + RzArraySizeVar->setName(Ctx, nextRzName()); |
| + NewGlobals.push_back(RzArray); |
| + NewGlobals.push_back(RzArraySizeVar); |
| + |
| + // TODO(tlively): Consider alignment when determining redzone layout. |
| + for (VariableDeclaration *Global : Globals) { |
| + VariableDeclaration *RzLeft = |
| + createRz(&NewGlobals, RzArray, RzArraySize, Global); |
| + VariableDeclaration *RzRight = |
| + createRz(&NewGlobals, RzArray, RzArraySize, Global); |
| + NewGlobals.push_back(RzLeft); |
| + NewGlobals.push_back(Global); |
| + NewGlobals.push_back(RzRight); |
| + } |
| + |
| + // update the contents of the RzArraySize global |
| + llvm::NaClBitcodeRecord::RecordVector SizeContents; |
| + for (unsigned i = 0; i < sizeof(RzArraySize); i++) { |
| + SizeContents.emplace_back(RzArraySize % (1 << CHAR_BIT)); |
| + RzArraySize >>= CHAR_BIT; |
| + } |
| + RzArraySizeVar->addInitializer( |
| + VariableDeclaration::DataInitializer::create(&NewGlobals, SizeContents)); |
| + |
| + // Replace old list of globals, without messing up arena allocators |
| + Globals.clear(); |
| + Globals.merge(&NewGlobals); |
| + DidInsertRedZones = true; |
| + |
| + // Log the new set of globals |
| + if (BuildDefs::dump()) { |
| + OstreamLocker _(Ctx); |
| + Ctx->getStrDump() << "========= Instrumented Globals =========\n"; |
| + for (VariableDeclaration *Global : Globals) { |
| + Global->dump(Ctx->getStrDump()); |
| + } |
| + } |
| +} |
| + |
| +std::string ASanInstrumentation::nextRzName() { |
| + std::stringstream Name; |
| + Name << RzPrefix << RzNum++; |
| + return Name.str(); |
| +} |
| + |
| +VariableDeclaration * |
| +ASanInstrumentation::createRz(VariableDeclarationList *List, |
| + VariableDeclaration *RzArray, SizeT &RzArraySize, |
| + VariableDeclaration *Global) { |
| + VariableDeclaration *Rz = VariableDeclaration::create(List); |
| + Rz->setName(Ctx, nextRzName()); |
| + if (Global->hasNonzeroInitializer()) { |
| + Rz->addInitializer( |
| + VariableDeclaration::DataInitializer::create(List, RzContents)); |
| + } else { |
| + Rz->addInitializer( |
| + VariableDeclaration::ZeroInitializer::create(List, RzSize)); |
| + } |
| + Rz->setIsConstant(Global->getIsConstant()); |
| + RzArray->addInitializer(VariableDeclaration::RelocInitializer::create( |
| + List, Rz, RelocOffsetArray(0))); |
| + ++RzArraySize; |
| + return Rz; |
| +} |
| + |
| +} // end of namespace Ice |