OLD | NEW |
---|---|
(Empty) | |
1 //===- subzero/src/IceASanInstrumentation.cpp - ASan ------------*- C++ -*-===// | |
2 // | |
3 // The Subzero Code Generator | |
4 // | |
5 // This file is distributed under the University of Illinois Open Source | |
6 // License. See LICENSE.TXT for details. | |
7 // | |
8 //===----------------------------------------------------------------------===// | |
9 /// | |
10 /// \file | |
11 /// \brief Implements the AddressSanitizer instrumentation class. | |
12 /// | |
13 //===----------------------------------------------------------------------===// | |
14 | |
15 #include "IceASanInstrumentation.h" | |
16 | |
17 #include "IceBuildDefs.h" | |
18 #include "IceGlobalInits.h" | |
19 | |
20 #include <sstream> | |
21 | |
22 namespace Ice { | |
23 | |
24 const std::string ASanInstrumentation::RzPrefix = "__$rz"; | |
25 | |
26 // Create redzones between all global variables, ensuring that the initializer | |
27 // types of the redzones and their associated globals match so that they are | |
28 // laid out together in memory. | |
29 void ASanInstrumentation::instrumentGlobals(VariableDeclarationList &Globals) { | |
30 if (BuildDefs::minimal() || DidInsertRedZones) | |
31 return; | |
32 | |
33 VariableDeclarationList NewGlobals; | |
34 // Global holding pointers to all redzones | |
35 VariableDeclaration *RzArray; | |
36 // Global holding the size of RzArray | |
37 VariableDeclaration *RzArraySizeVar; | |
38 static SizeT RzArraySize; | |
39 | |
40 RzArray = VariableDeclaration::create(&NewGlobals); | |
Karl
2016/06/10 15:20:27
Why not combine this with line 35 as the initial v
tlively
2016/06/10 17:30:22
Done.
| |
41 RzArraySizeVar = VariableDeclaration::create(&NewGlobals); | |
Karl
2016/06/10 15:20:27
Same here.
tlively
2016/06/10 17:30:22
Done.
| |
42 RzArray->setName(Ctx, nextRzName()); | |
43 RzArraySizeVar->setName(Ctx, nextRzName()); | |
44 NewGlobals.push_back(RzArray); | |
45 NewGlobals.push_back(RzArraySizeVar); | |
46 | |
47 // TODO(tlively): Consider alignment when determining redzone layout. | |
48 for (VariableDeclaration *Global : Globals) { | |
49 VariableDeclaration *RzLeft = | |
50 createRz(&NewGlobals, RzArray, RzArraySize, Global); | |
51 VariableDeclaration *RzRight = | |
52 createRz(&NewGlobals, RzArray, RzArraySize, Global); | |
53 NewGlobals.push_back(RzLeft); | |
54 NewGlobals.push_back(Global); | |
55 NewGlobals.push_back(RzRight); | |
56 } | |
57 | |
58 // update the contents of the RzArraySize global | |
59 llvm::NaClBitcodeRecord::RecordVector SizeContents; | |
60 for (unsigned i = 0; i < sizeof(RzArraySize); i++) { | |
61 SizeContents.emplace_back(RzArraySize % (1 << CHAR_BIT)); | |
62 RzArraySize >>= CHAR_BIT; | |
63 } | |
64 RzArraySizeVar->addInitializer( | |
65 VariableDeclaration::DataInitializer::create(&NewGlobals, SizeContents)); | |
66 | |
67 // Replace old list of globals, without messing up arena allocators | |
68 Globals.clear(); | |
69 Globals.merge(&NewGlobals); | |
70 DidInsertRedZones = true; | |
71 | |
72 // Log the new set of globals | |
73 if (BuildDefs::dump()) { | |
Karl
2016/06/10 15:20:26
The preferred way of locking the Str lock is with
tlively
2016/06/10 17:30:22
Done.
| |
74 Ctx->lockStr(); | |
75 Ctx->getStrDump() << "========= Instrumented Globals =========\n"; | |
76 for (VariableDeclaration *Global : Globals) { | |
77 Global->dump(Ctx->getStrDump()); | |
78 } | |
79 Ctx->unlockStr(); | |
80 } | |
81 } | |
82 | |
83 std::string ASanInstrumentation::nextRzName() { | |
84 std::stringstream Name; | |
85 Name << RzPrefix << RzNum++; | |
86 return Name.str(); | |
87 } | |
88 | |
89 VariableDeclaration * | |
90 ASanInstrumentation::createRz(VariableDeclarationList *List, | |
91 VariableDeclaration *RzArray, SizeT &RzArraySize, | |
92 VariableDeclaration *Global) { | |
93 VariableDeclaration *Rz = VariableDeclaration::create(List); | |
94 Rz->setName(Ctx, nextRzName()); | |
95 if (Global->hasNonzeroInitializer()) { | |
96 llvm::NaClBitcodeRecord::RecordVector Contents(RzSize, 'R'); | |
Karl
2016/06/10 15:20:27
Minor nit. Do you really want the contents (other
Karl
2016/06/10 15:30:49
This record "Contents" is just used to provide the
tlively
2016/06/10 17:30:22
I went a step further and made it a static member
tlively
2016/06/10 17:30:22
This constructor fills the entire vector with 'R'.
| |
97 Rz->addInitializer( | |
98 VariableDeclaration::DataInitializer::create(List, Contents)); | |
99 } else { | |
100 Rz->addInitializer( | |
101 VariableDeclaration::ZeroInitializer::create(List, RzSize)); | |
102 } | |
103 Rz->setIsConstant(Global->getIsConstant()); | |
104 RzArray->addInitializer(VariableDeclaration::RelocInitializer::create( | |
105 List, Rz, RelocOffsetArray(0))); | |
106 ++RzArraySize; | |
107 return Rz; | |
108 } | |
109 | |
110 } // end of namespace Ice | |
OLD | NEW |