Chromium Code Reviews| Index: src/IceASanInstrumentation.cpp |
| diff --git a/src/IceASanInstrumentation.cpp b/src/IceASanInstrumentation.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..928ba7690a1434fb5390cdaf15660c46ccc2cdb1 |
| --- /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"; |
|
Karl
2016/06/09 21:20:56
Why not prefix with "$" so that it won't conflict
Jim Stichnoth
2016/06/09 22:27:38
Or, __rz or __$rz because "__" prefix is reserved
tlively
2016/06/09 23:30:10
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. |
| +// TODO(tlively): make everything here thread safe, including dumps |
| +void ASanInstrumentation::instrumentGlobals(VariableDeclarationList &Globals) { |
| + if (didInsertRedZones) |
|
Jim Stichnoth
2016/06/09 22:27:39
I'm not sure how this code ends up getting invoked
tlively
2016/06/09 23:30:10
Done.
|
| + return; |
| + |
| + VariableDeclarationList NewGlobals; |
| + // Global holding pointers to all redzones |
| + VariableDeclaration *RzArray; |
| + // Global holding the size of RzArray |
| + VariableDeclaration *RzArraySizeVar; |
| + static SizeT RzArraySize; |
| + |
| + // used to construct new redzones |
| + uint32_t RzNum = 0; |
| + auto NextRzName = [&] { |
|
Karl
2016/06/09 21:20:56
Why not make this a private method of the class, o
tlively
2016/06/09 23:30:10
Done.
|
| + std::stringstream Name; |
| + Name << RzPrefix << "." << RzNum++; |
| + return Name.str(); |
| + }; |
| + |
| + auto CreateRz = [&](VariableDeclaration *Global) { |
|
Karl
2016/06/09 21:20:56
Why not make this a private method of the class?
tlively
2016/06/09 23:30:10
Done.
|
| + VariableDeclaration *Rz = VariableDeclaration::create(&NewGlobals); |
| + Rz->setName(Ctx, NextRzName()); |
| + if (Global->hasNonzeroInitializer()) { |
| + Rz->addInitializer( |
|
Karl
2016/06/09 21:20:56
Question? If all initializers are zero initialiali
tlively
2016/06/09 23:30:10
Done.
|
| + VariableDeclaration::ZeroInitializer::create(&NewGlobals, RzSize-1)); |
| + Rz->addInitializer( |
| + VariableDeclaration::ZeroInitializer::create(&NewGlobals, 1)); |
| + } else { |
| + Rz->addInitializer( |
| + VariableDeclaration::ZeroInitializer::create( |
| + &NewGlobals, RzSize)); |
| + } |
| + Rz->setIsConstant(Global->getIsConstant()); |
| + RzArray->addInitializer(VariableDeclaration::RelocInitializer::create( |
| + &NewGlobals, Rz, RelocOffsetArray(0))); |
| + ++RzArraySize; |
| + return Rz; |
| + }; |
| + |
| + RzArray = VariableDeclaration::create(&NewGlobals); |
| + RzArraySizeVar = VariableDeclaration::create(&NewGlobals); |
| + RzArray->setName(Ctx, NextRzName()); |
| + RzArraySizeVar->setName(Ctx, NextRzName()); |
| + NewGlobals.push_back(RzArray); |
|
Jim Stichnoth
2016/06/09 22:27:38
I believe emplace_back is the newer improveder way
tlively
2016/06/09 23:30:10
VariableDeclarationList is a wrapper that only exp
|
| + NewGlobals.push_back(RzArraySizeVar); |
| + |
| + // TODO(tlively): Consider alignment when determining redzone layout. |
| + for (VariableDeclaration *Global : Globals) { |
| + VariableDeclaration *RzLeft = CreateRz(Global); |
| + VariableDeclaration *RzRight = CreateRz(Global); |
| + NewGlobals.push_back(RzLeft); |
| + NewGlobals.push_back(Global); |
| + NewGlobals.push_back(RzRight); |
| + } |
| + |
| + // update the contents of the RzArraySize global (as a 4-byte little endian int) |
|
Jim Stichnoth
2016/06/09 22:27:39
80-col here and elsewhere
tlively
2016/06/09 23:30:10
Done.
|
| + llvm::NaClBitcodeRecord::RecordVector SizeContents; |
| + for (int i = 0; i < 4; i++) { |
|
Karl
2016/06/09 21:20:56
Use sizeof(uint32) instead of 4. This will give yo
tlively
2016/06/09 23:30:10
Done.
|
| + SizeContents.push_back(RzArraySize % (1 << 8)); |
|
Karl
2016/06/09 21:20:56
Use CHAR_BIT for the number of bits in a character
tlively
2016/06/09 23:30:09
Done.
|
| + RzArraySize /= (1 << 8); |
|
Karl
2016/06/09 21:20:56
Since RzArraySize is unsigned (or it should be if
tlively
2016/06/09 23:30:10
Done.
|
| + } |
| + assert(RzArraySize == 0 && "There were too many globals for ASan to instrument"); |
|
Karl
2016/06/09 21:20:56
This line is too long.
In general, you should "re
tlively
2016/06/09 23:30:10
Done.
|
| + RzArraySizeVar->addInitializer(VariableDeclaration::DataInitializer::create( |
| + &NewGlobals, SizeContents)); |
| + |
| + // Replace old list of globals |
|
Karl
2016/06/09 21:20:56
An more efficient solution for the next two statem
tlively
2016/06/09 23:30:10
Not possible due to VariableDeclarationList being
|
| + Globals.clear(); |
| + Globals.merge(&NewGlobals); |
| + didInsertRedZones = true; |
| + |
| + // Log the new set of globals |
| + if (BuildDefs::dump()) { |
| + Ctx->getStrDump() << "========= Instrumented Globals =========\n"; |
|
Jim Stichnoth
2016/06/09 22:27:38
You should "lock" the dump stream so that this out
tlively
2016/06/09 23:30:10
Done.
|
| + for (VariableDeclaration *Global : Globals) { |
| + Global->dump(Ctx->getStrDump()); |
| + } |
| + } |
| +} |
| + |
| +} // end of namespace Ice |