11
11
// / based on tagged addressing.
12
12
// ===----------------------------------------------------------------------===//
13
13
14
+ #include " llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
14
15
#include " llvm/ADT/SmallVector.h"
15
16
#include " llvm/ADT/StringExtras.h"
16
17
#include " llvm/ADT/StringRef.h"
@@ -164,22 +165,19 @@ namespace {
164
165
165
166
// / An instrumentation pass implementing detection of addressability bugs
166
167
// / using tagged pointers.
167
- class HWAddressSanitizer : public FunctionPass {
168
+ class HWAddressSanitizer {
168
169
public:
169
- // Pass identification, replacement for typeid.
170
- static char ID;
171
-
172
- explicit HWAddressSanitizer (bool CompileKernel = false , bool Recover = false )
173
- : FunctionPass(ID) {
170
+ explicit HWAddressSanitizer (Module &M, bool CompileKernel = false ,
171
+ bool Recover = false ) {
174
172
this ->Recover = ClRecover.getNumOccurrences () > 0 ? ClRecover : Recover;
175
173
this ->CompileKernel = ClEnableKhwasan.getNumOccurrences () > 0 ?
176
174
ClEnableKhwasan : CompileKernel;
177
- }
178
175
179
- StringRef getPassName () const override { return " HWAddressSanitizer" ; }
176
+ initializeModule (M);
177
+ }
180
178
181
- bool runOnFunction (Function &F) override ;
182
- bool doInitialization (Module &M) override ;
179
+ bool sanitizeFunction (Function &F);
180
+ void initializeModule (Module &M);
183
181
184
182
void initializeCallbacks (Module &M);
185
183
@@ -279,29 +277,61 @@ class HWAddressSanitizer : public FunctionPass {
279
277
GlobalValue *ThreadPtrGlobal = nullptr ;
280
278
};
281
279
280
+ class HWAddressSanitizerLegacyPass : public FunctionPass {
281
+ public:
282
+ // Pass identification, replacement for typeid.
283
+ static char ID;
284
+
285
+ explicit HWAddressSanitizerLegacyPass (bool CompileKernel = false ,
286
+ bool Recover = false )
287
+ : FunctionPass(ID), CompileKernel(CompileKernel), Recover(Recover) {}
288
+
289
+ StringRef getPassName () const override { return " HWAddressSanitizer" ; }
290
+
291
+ bool runOnFunction (Function &F) override {
292
+ HWAddressSanitizer HWASan (*F.getParent (), CompileKernel, Recover);
293
+ return HWASan.sanitizeFunction (F);
294
+ }
295
+
296
+ private:
297
+ bool CompileKernel;
298
+ bool Recover;
299
+ };
300
+
282
301
} // end anonymous namespace
283
302
284
- char HWAddressSanitizer ::ID = 0 ;
303
+ char HWAddressSanitizerLegacyPass ::ID = 0 ;
285
304
286
305
INITIALIZE_PASS_BEGIN (
287
- HWAddressSanitizer , " hwasan" ,
306
+ HWAddressSanitizerLegacyPass , " hwasan" ,
288
307
" HWAddressSanitizer: detect memory bugs using tagged addressing." , false ,
289
308
false )
290
309
INITIALIZE_PASS_END(
291
- HWAddressSanitizer , " hwasan" ,
310
+ HWAddressSanitizerLegacyPass , " hwasan" ,
292
311
" HWAddressSanitizer: detect memory bugs using tagged addressing." , false ,
293
312
false )
294
313
295
- FunctionPass *llvm::createHWAddressSanitizerPass (bool CompileKernel,
296
- bool Recover) {
314
+ FunctionPass *llvm::createHWAddressSanitizerLegacyPassPass (bool CompileKernel,
315
+ bool Recover) {
297
316
assert (!CompileKernel || Recover);
298
- return new HWAddressSanitizer (CompileKernel, Recover);
317
+ return new HWAddressSanitizerLegacyPass (CompileKernel, Recover);
318
+ }
319
+
320
+ HWAddressSanitizerPass::HWAddressSanitizerPass (bool CompileKernel, bool Recover)
321
+ : CompileKernel(CompileKernel), Recover(Recover) {}
322
+
323
+ PreservedAnalyses HWAddressSanitizerPass::run (Function &F,
324
+ FunctionAnalysisManager &FAM) {
325
+ HWAddressSanitizer HWASan (*F.getParent (), CompileKernel, Recover);
326
+ if (HWASan.sanitizeFunction (F))
327
+ return PreservedAnalyses::none ();
328
+ return PreservedAnalyses::all ();
299
329
}
300
330
301
331
// / Module-level initialization.
302
332
// /
303
333
// / inserts a call to __hwasan_init to the module's constructor list.
304
- bool HWAddressSanitizer::doInitialization (Module &M) {
334
+ void HWAddressSanitizer::initializeModule (Module &M) {
305
335
LLVM_DEBUG (dbgs () << " Init " << M.getName () << " \n " );
306
336
auto &DL = M.getDataLayout ();
307
337
@@ -320,43 +350,54 @@ bool HWAddressSanitizer::doInitialization(Module &M) {
320
350
HwasanCtorFunction = nullptr ;
321
351
if (!CompileKernel) {
322
352
std::tie (HwasanCtorFunction, std::ignore) =
323
- createSanitizerCtorAndInitFunctions (M, kHwasanModuleCtorName ,
324
- kHwasanInitName ,
325
- /* InitArgTypes=*/ {},
326
- /* InitArgs=*/ {});
327
- Comdat *CtorComdat = M.getOrInsertComdat (kHwasanModuleCtorName );
328
- HwasanCtorFunction->setComdat (CtorComdat);
329
- appendToGlobalCtors (M, HwasanCtorFunction, 0 , HwasanCtorFunction);
353
+ getOrCreateSanitizerCtorAndInitFunctions (
354
+ M, kHwasanModuleCtorName , kHwasanInitName ,
355
+ /* InitArgTypes=*/ {},
356
+ /* InitArgs=*/ {},
357
+ // This callback is invoked when the functions are created the first
358
+ // time. Hook them into the global ctors list in that case:
359
+ [&](Function *Ctor, FunctionCallee) {
360
+ Comdat *CtorComdat = M.getOrInsertComdat (kHwasanModuleCtorName );
361
+ Ctor->setComdat (CtorComdat);
362
+ appendToGlobalCtors (M, Ctor, 0 , Ctor);
363
+
364
+ IRBuilder<> IRBCtor (Ctor->getEntryBlock ().getTerminator ());
365
+ IRBCtor.CreateCall (
366
+ declareSanitizerInitFunction (M, " __hwasan_init_frames" ,
367
+ {Int8PtrTy, Int8PtrTy}),
368
+ {createFrameSectionBound (M, Int8Ty, getFrameSectionBeg ()),
369
+ createFrameSectionBound (M, Int8Ty, getFrameSectionEnd ())});
370
+ });
330
371
331
372
// Create a zero-length global in __hwasan_frame so that the linker will
332
373
// always create start and stop symbols.
333
374
//
334
375
// N.B. If we ever start creating associated metadata in this pass this
335
376
// global will need to be associated with the ctor.
336
377
Type *Int8Arr0Ty = ArrayType::get (Int8Ty, 0 );
337
- auto GV =
338
- new GlobalVariable (M, Int8Arr0Ty, /* isConstantGlobal*/ true ,
339
- GlobalVariable::PrivateLinkage,
340
- Constant::getNullValue (Int8Arr0Ty), " __hwasan" );
341
- GV->setSection (getFrameSection ());
342
- GV->setComdat (CtorComdat);
343
- appendToCompilerUsed (M, GV);
344
-
345
- IRBuilder<> IRBCtor (HwasanCtorFunction->getEntryBlock ().getTerminator ());
346
- IRBCtor.CreateCall (
347
- declareSanitizerInitFunction (M, " __hwasan_init_frames" ,
348
- {Int8PtrTy, Int8PtrTy}),
349
- {createFrameSectionBound (M, Int8Ty, getFrameSectionBeg ()),
350
- createFrameSectionBound (M, Int8Ty, getFrameSectionEnd ())});
378
+ M.getOrInsertGlobal (" __hwasan" , Int8Arr0Ty, [&] {
379
+ auto *GV = new GlobalVariable (
380
+ M, Int8Arr0Ty, /* isConstantGlobal=*/ true , GlobalValue::PrivateLinkage,
381
+ Constant::getNullValue (Int8Arr0Ty), " __hwasan" );
382
+ GV->setSection (getFrameSection ());
383
+ Comdat *CtorComdat = M.getOrInsertComdat (kHwasanModuleCtorName );
384
+ GV->setComdat (CtorComdat);
385
+ appendToCompilerUsed (M, GV);
386
+ return GV;
387
+ });
351
388
}
352
389
353
- if (!TargetTriple.isAndroid ())
354
- appendToCompilerUsed (
355
- M, ThreadPtrGlobal = new GlobalVariable (
356
- M, IntptrTy, false , GlobalVariable::ExternalLinkage, nullptr ,
357
- " __hwasan_tls" , nullptr , GlobalVariable::InitialExecTLSModel));
358
-
359
- return true ;
390
+ if (!TargetTriple.isAndroid ()) {
391
+ Constant *C = M.getOrInsertGlobal (" __hwasan_tls" , IntptrTy, [&] {
392
+ auto *GV = new GlobalVariable (M, IntptrTy, /* isConstantGlobal=*/ false ,
393
+ GlobalValue::ExternalLinkage, nullptr ,
394
+ " __hwasan_tls" , nullptr ,
395
+ GlobalVariable::InitialExecTLSModel);
396
+ appendToCompilerUsed (M, GV);
397
+ return GV;
398
+ });
399
+ ThreadPtrGlobal = cast<GlobalVariable>(C);
400
+ }
360
401
}
361
402
362
403
void HWAddressSanitizer::initializeCallbacks (Module &M) {
@@ -970,7 +1011,7 @@ bool HWAddressSanitizer::isInterestingAlloca(const AllocaInst &AI) {
970
1011
!AI.isSwiftError ());
971
1012
}
972
1013
973
- bool HWAddressSanitizer::runOnFunction (Function &F) {
1014
+ bool HWAddressSanitizer::sanitizeFunction (Function &F) {
974
1015
if (&F == HwasanCtorFunction)
975
1016
return false ;
976
1017
0 commit comments