LLVM 17.0.0git
SanitizerStats.cpp
Go to the documentation of this file.
1//===- SanitizerStats.cpp - Sanitizer statistics gathering ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Implements code generation for sanitizer statistics gathering.
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/IR/Constants.h"
17#include "llvm/IR/IRBuilder.h"
18#include "llvm/IR/Module.h"
20
21using namespace llvm;
22
24 StatTy = ArrayType::get(Type::getInt8PtrTy(M->getContext()), 2);
25 EmptyModuleStatsTy = makeModuleStatsTy();
26
27 ModuleStatsGV = new GlobalVariable(*M, EmptyModuleStatsTy, false,
29}
30
31ArrayType *SanitizerStatReport::makeModuleStatsArrayTy() {
32 return ArrayType::get(StatTy, Inits.size());
33}
34
35StructType *SanitizerStatReport::makeModuleStatsTy() {
36 return StructType::get(M->getContext(), {Type::getInt8PtrTy(M->getContext()),
37 Type::getInt32Ty(M->getContext()),
38 makeModuleStatsArrayTy()});
39}
40
42 Function *F = B.GetInsertBlock()->getParent();
43 Module *M = F->getParent();
44 PointerType *Int8PtrTy = B.getInt8PtrTy();
45 IntegerType *IntPtrTy = B.getIntPtrTy(M->getDataLayout());
46 ArrayType *StatTy = ArrayType::get(Int8PtrTy, 2);
47
48 Inits.push_back(ConstantArray::get(
49 StatTy,
50 {Constant::getNullValue(Int8PtrTy),
52 ConstantInt::get(IntPtrTy, uint64_t(SK) << (IntPtrTy->getBitWidth() -
54 Int8PtrTy)}));
55
56 FunctionType *StatReportTy =
57 FunctionType::get(B.getVoidTy(), Int8PtrTy, false);
58 FunctionCallee StatReport =
59 M->getOrInsertFunction("__sanitizer_stat_report", StatReportTy);
60
61 auto InitAddr = ConstantExpr::getGetElementPtr(
62 EmptyModuleStatsTy, ModuleStatsGV,
64 ConstantInt::get(IntPtrTy, 0), ConstantInt::get(B.getInt32Ty(), 2),
65 ConstantInt::get(IntPtrTy, Inits.size() - 1),
66 });
67 B.CreateCall(StatReport, ConstantExpr::getBitCast(InitAddr, Int8PtrTy));
68}
69
71 if (Inits.empty()) {
72 ModuleStatsGV->eraseFromParent();
73 return;
74 }
75
76 PointerType *Int8PtrTy = Type::getInt8PtrTy(M->getContext());
78 Type *VoidTy = Type::getVoidTy(M->getContext());
79
80 // Create a new ModuleStatsGV to replace the old one. We can't just set the
81 // old one's initializer because its type is different.
82 auto NewModuleStatsGV = new GlobalVariable(
83 *M, makeModuleStatsTy(), false, GlobalValue::InternalLinkage,
85 {Constant::getNullValue(Int8PtrTy),
86 ConstantInt::get(Int32Ty, Inits.size()),
87 ConstantArray::get(makeModuleStatsArrayTy(), Inits)}));
88 ModuleStatsGV->replaceAllUsesWith(
89 ConstantExpr::getBitCast(NewModuleStatsGV, ModuleStatsGV->getType()));
90 ModuleStatsGV->eraseFromParent();
91
92 // Create a global constructor to register NewModuleStatsGV.
93 auto F = Function::Create(FunctionType::get(VoidTy, false),
95 auto BB = BasicBlock::Create(M->getContext(), "", F);
96 IRBuilder<> B(BB);
97
98 FunctionType *StatInitTy = FunctionType::get(VoidTy, Int8PtrTy, false);
99 FunctionCallee StatInit =
100 M->getOrInsertFunction("__sanitizer_stat_init", StatInitTy);
101
102 B.CreateCall(StatInit, ConstantExpr::getBitCast(NewModuleStatsGV, Int8PtrTy));
103 B.CreateRetVoid();
104
105 appendToGlobalCtors(*M, F, 0);
106}
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define F(x, y, z)
Definition: MD5.cpp:55
Module.h This file contains the declarations for the Module class.
IntegerType * Int32Ty
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Class to represent array types.
Definition: DerivedTypes.h:357
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Definition: Type.cpp:658
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:105
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1242
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2206
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, std::optional< unsigned > InRangeIndex=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
Definition: Constants.h:1232
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2220
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:888
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
Definition: Constants.h:466
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:356
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
Class to represent function types.
Definition: DerivedTypes.h:103
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:136
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:290
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:55
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition: Globals.cpp:468
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2558
Class to represent integer types.
Definition: DerivedTypes.h:40
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
Definition: DerivedTypes.h:72
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:262
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
Definition: Module.cpp:144
Class to represent pointers.
Definition: DerivedTypes.h:632
Class to represent struct types.
Definition: DerivedTypes.h:213
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition: Type.cpp:426
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static Type * getVoidTy(LLVMContext &C)
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
static IntegerType * getInt32Ty(LLVMContext &C)
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:532
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
SanitizerStatKind
void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
Definition: ModuleUtils.cpp:71
@ kSanitizerStatKindBits
void finish()
Finalize module stats array and add global constructor to register it.
void create(IRBuilder<> &B, SanitizerStatKind SK)
Generates code into B that increments a location-specific counter tagged with the given sanitizer kin...