| Index: src/IceASanInstrumentation.cpp
|
| diff --git a/src/IceASanInstrumentation.cpp b/src/IceASanInstrumentation.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c0b87dc3a17c6269dd56405c9d64ae44e67104e7
|
| --- /dev/null
|
| +++ b/src/IceASanInstrumentation.cpp
|
| @@ -0,0 +1,114 @@
|
| +//===- 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 {
|
| +
|
| +namespace {
|
| +constexpr SizeT RzSize = 32;
|
| +const std::string RzPrefix = "__$rz";
|
| +const llvm::NaClBitcodeRecord::RecordVector RzContents =
|
| + llvm::NaClBitcodeRecord::RecordVector(RzSize, 'R');
|
| +} // end of anonymous namespace
|
| +
|
| +// 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
|
| + auto *RzArray = VariableDeclaration::create(&NewGlobals);
|
| + // Global holding the size of RzArray
|
| + auto *RzArraySizeVar = VariableDeclaration::create(&NewGlobals);
|
| + SizeT RzArraySize = 0;
|
| +
|
| + RzArray->setName(Ctx, nextRzName());
|
| + RzArraySizeVar->setName(Ctx, nextRzName());
|
| + RzArray->setIsConstant(true);
|
| + RzArraySizeVar->setIsConstant(true);
|
| + NewGlobals.push_back(RzArray);
|
| + NewGlobals.push_back(RzArraySizeVar);
|
| +
|
| + 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() && (getFlags().getVerbose() & IceV_GlobalInit)) {
|
| + OstreamLocker _(Ctx);
|
| + Ctx->getStrDump() << "========= Instrumented Globals =========\n";
|
| + for (VariableDeclaration *Global : Globals) {
|
| + Global->dump(Ctx->getStrDump());
|
| + }
|
| + }
|
| +}
|
| +
|
| +std::string ASanInstrumentation::nextRzName() {
|
| + if (BuildDefs::minimal())
|
| + return "";
|
| + std::stringstream Name;
|
| + Name << RzPrefix << RzNum++;
|
| + return Name.str();
|
| +}
|
| +
|
| +VariableDeclaration *
|
| +ASanInstrumentation::createRz(VariableDeclarationList *List,
|
| + VariableDeclaration *RzArray, SizeT &RzArraySize,
|
| + VariableDeclaration *Global) {
|
| + if (BuildDefs::minimal())
|
| + return nullptr;
|
| + auto *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
|
|
|