9
9
// ===----------------------------------------------------------------------===//
10
10
11
11
#include " AArch64.h"
12
- #include " llvm/BinaryFormat/ELF.h"
13
- #include " llvm/IR/Attributes.h"
12
+ #include " llvm/ADT/SmallVector.h"
14
13
#include " llvm/IR/Constants.h"
15
14
#include " llvm/IR/GlobalValue.h"
16
15
#include " llvm/IR/GlobalVariable.h"
17
- #include " llvm/IR/IRBuilder.h"
18
16
#include " llvm/IR/Module.h"
19
17
#include " llvm/Pass.h"
20
- #include " llvm/Support/raw_ostream.h"
21
18
22
19
#include < algorithm>
23
- #include < set>
24
20
25
21
using namespace llvm ;
26
22
27
23
static const Align kTagGranuleSize = Align(16 );
28
24
29
- static bool shouldTagGlobal (GlobalVariable &G) {
30
- if (!G.isTagged ())
31
- return false ;
32
-
33
- assert (G.hasSanitizerMetadata () &&
34
- " Missing sanitizer metadata, but symbol is apparently tagged." );
35
- GlobalValue::SanitizerMetadata Meta = G.getSanitizerMetadata ();
36
-
25
+ static bool shouldTagGlobal (const GlobalVariable &G) {
37
26
// For now, don't instrument constant data, as it'll be in .rodata anyway. It
38
27
// may be worth instrumenting these in future to stop them from being used as
39
28
// gadgets.
40
- if (G.getName ().starts_with (" llvm." ) || G.isThreadLocal () || G.isConstant ()) {
41
- Meta.Memtag = false ;
42
- G.setSanitizerMetadata (Meta);
29
+ if (G.getName ().starts_with (" llvm." ) || G.isThreadLocal () || G.isConstant ())
43
30
return false ;
44
- }
45
31
46
32
// Globals can be placed implicitly or explicitly in sections. There's two
47
33
// different types of globals that meet this criteria that cause problems:
@@ -54,18 +40,15 @@ static bool shouldTagGlobal(GlobalVariable &G) {
54
40
// them causes SIGSEGV/MTE[AS]ERR).
55
41
// 2. Global variables put into an explicit section, where the section's name
56
42
// is a valid C-style identifier. The linker emits a `__start_<name>` and
57
- // `__stop_<na,e >` symbol for the section, so that you can iterate over
43
+ // `__stop_<name >` symbol for the section, so that you can iterate over
58
44
// globals within this section. Unfortunately, again, these globals would
59
45
// be tagged and so iteration causes SIGSEGV/MTE[AS]ERR.
60
46
//
61
47
// To mitigate both these cases, and because specifying a section is rare
62
48
// outside of these two cases, disable MTE protection for globals in any
63
49
// section.
64
- if (G.hasSection ()) {
65
- Meta.Memtag = false ;
66
- G.setSanitizerMetadata (Meta);
50
+ if (G.hasSection ())
67
51
return false ;
68
- }
69
52
70
53
return true ;
71
54
}
@@ -132,20 +115,26 @@ class AArch64GlobalsTagging : public ModulePass {
132
115
bool runOnModule (Module &M) override ;
133
116
134
117
StringRef getPassName () const override { return " AArch64 Globals Tagging" ; }
135
-
136
- private:
137
- std::set<GlobalVariable *> GlobalsToTag;
138
118
};
139
119
} // anonymous namespace
140
120
141
121
char AArch64GlobalsTagging::ID = 0 ;
142
122
143
123
bool AArch64GlobalsTagging::runOnModule (Module &M) {
144
124
// No mutating the globals in-place, or iterator invalidation occurs.
145
- std::vector <GlobalVariable *> GlobalsToTag;
125
+ SmallVector <GlobalVariable *> GlobalsToTag;
146
126
for (GlobalVariable &G : M.globals ()) {
147
- if (G.isDeclaration () || !shouldTagGlobal (G ))
127
+ if (G.isDeclaration () || !G. isTagged ( ))
148
128
continue ;
129
+
130
+ assert (G.hasSanitizerMetadata () &&
131
+ " Missing sanitizer metadata, but symbol is apparently tagged." );
132
+ if (!shouldTagGlobal (G)) {
133
+ GlobalValue::SanitizerMetadata Meta = G.getSanitizerMetadata ();
134
+ Meta.Memtag = false ;
135
+ G.setSanitizerMetadata (Meta);
136
+ assert (!G.isTagged ());
137
+ }
149
138
GlobalsToTag.push_back (&G);
150
139
}
151
140
0 commit comments