99// ===----------------------------------------------------------------------===//
1010
1111#include " AArch64.h"
12- #include " llvm/BinaryFormat/ELF.h"
13- #include " llvm/IR/Attributes.h"
12+ #include " llvm/ADT/SmallVector.h"
1413#include " llvm/IR/Constants.h"
1514#include " llvm/IR/GlobalValue.h"
1615#include " llvm/IR/GlobalVariable.h"
17- #include " llvm/IR/IRBuilder.h"
1816#include " llvm/IR/Module.h"
1917#include " llvm/Pass.h"
20- #include " llvm/Support/raw_ostream.h"
2118
2219#include < algorithm>
23- #include < set>
2420
2521using namespace llvm ;
2622
2723static const Align kTagGranuleSize = Align(16 );
2824
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) {
3726 // For now, don't instrument constant data, as it'll be in .rodata anyway. It
3827 // may be worth instrumenting these in future to stop them from being used as
3928 // 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 ())
4330 return false ;
44- }
4531
4632 // Globals can be placed implicitly or explicitly in sections. There's two
4733 // different types of globals that meet this criteria that cause problems:
@@ -54,18 +40,15 @@ static bool shouldTagGlobal(GlobalVariable &G) {
5440 // them causes SIGSEGV/MTE[AS]ERR).
5541 // 2. Global variables put into an explicit section, where the section's name
5642 // 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
5844 // globals within this section. Unfortunately, again, these globals would
5945 // be tagged and so iteration causes SIGSEGV/MTE[AS]ERR.
6046 //
6147 // To mitigate both these cases, and because specifying a section is rare
6248 // outside of these two cases, disable MTE protection for globals in any
6349 // section.
64- if (G.hasSection ()) {
65- Meta.Memtag = false ;
66- G.setSanitizerMetadata (Meta);
50+ if (G.hasSection ())
6751 return false ;
68- }
6952
7053 return true ;
7154}
@@ -132,20 +115,26 @@ class AArch64GlobalsTagging : public ModulePass {
132115 bool runOnModule (Module &M) override ;
133116
134117 StringRef getPassName () const override { return " AArch64 Globals Tagging" ; }
135-
136- private:
137- std::set<GlobalVariable *> GlobalsToTag;
138118};
139119} // anonymous namespace
140120
141121char AArch64GlobalsTagging::ID = 0 ;
142122
143123bool AArch64GlobalsTagging::runOnModule (Module &M) {
144124 // No mutating the globals in-place, or iterator invalidation occurs.
145- std::vector <GlobalVariable *> GlobalsToTag;
125+ SmallVector <GlobalVariable *> GlobalsToTag;
146126 for (GlobalVariable &G : M.globals ()) {
147- if (G.isDeclaration () || !shouldTagGlobal (G ))
127+ if (G.isDeclaration () || !G. isTagged ( ))
148128 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+ }
149138 GlobalsToTag.push_back (&G);
150139 }
151140
0 commit comments