Go to the documentation of this file.
42 #define DEBUG_TYPE "jmc-instrument"
50 bool runOnModule(
Module &
M)
override;
57 "Instrument function entry with call to __CheckForDebuggerJustMyCode",
63 const char CheckFunctionName[] =
"__CheckForDebuggerJustMyCode";
65 std::string getFlagName(
DISubprogram &SP,
bool UseX86FastCall) {
95 Suffix.push_back(
C ==
'.' ?
'@' :
C);
98 return (UseX86FastCall ?
"_" :
"__") +
99 utohexstr(
djbHash(FilePath),
false,
111 DB.createBasicType(
"unsigned char", 8, dwarf::DW_ATE_unsigned_char,
112 llvm::DINode::FlagArtificial);
114 auto *DGVE =
DB.createGlobalVariableExpression(
116 0, DType,
true,
true);
127 Function *createDefaultCheckFunction(
Module &M,
bool UseX86FastCall) {
129 const char *DefaultCheckFunctionName =
130 UseX86FastCall ?
"_JustMyCode_Default" :
"__JustMyCode_Default";
134 DefaultCheckFunctionName, &M);
142 return DefaultCheckFunc;
146 bool JMCInstrumenter::runOnModule(
Module &M) {
147 bool Changed =
false;
149 Triple ModuleTriple(
M.getTargetTriple());
150 bool IsMSVC = ModuleTriple.isKnownWindowsMSVCEnvironment();
151 bool IsELF = ModuleTriple.isOSBinFormatELF();
152 assert((IsELF || IsMSVC) &&
"Unsupported triple for JMC");
153 bool UseX86FastCall = IsMSVC && ModuleTriple.getArch() ==
Triple::x86;
154 const char *
const FlagSymbolSection = IsELF ?
".data.just.my.code" :
".msvcjmc";
159 if (
F.isDeclaration())
161 auto *SP =
F.getSubprogram();
167 std::string FlagName = getFlagName(*SP, UseX86FastCall);
169 Flag =
M.getOrInsertGlobal(FlagName, FlagTy, [&] {
178 attachDebugInfo(*GV, *SP);
183 if (!CheckFunction) {
185 createDefaultCheckFunction(M, UseX86FastCall);
187 DefaultCheckFunc->
setName(CheckFunctionName);
189 CheckFunction = DefaultCheckFunc;
191 assert(!
M.getFunction(CheckFunctionName) &&
192 "JMC instrument more than once?");
193 auto *CheckFunc = cast<Function>(
194 M.getOrInsertFunction(CheckFunctionName, getCheckFunctionType(Ctx))
197 CheckFunc->addParamAttr(0, Attribute::NoUndef);
198 if (UseX86FastCall) {
200 CheckFunc->addParamAttr(0, Attribute::InReg);
202 CheckFunction = CheckFunc;
206 Comdat *
C =
M.getOrInsertComdat(DefaultCheckFunctionName);
212 std::string AltOption = std::string(
"/alternatename:") +
213 CheckFunctionName +
"=" +
214 DefaultCheckFunctionName.
str();
217 M.getOrInsertNamedMetadata(
"llvm.linker.options")->addOperand(
N);
223 {
Flag},
"", &*
F.begin()->getFirstInsertionPt());
224 CI->addParamAttr(0, Attribute::NoUndef);
225 if (UseX86FastCall) {
227 CI->addParamAttr(0, Attribute::InReg);
StringRef getFilename() const
ModulePass * createJMCInstrumenterPass()
JMC instrument pass.
void setComdat(Comdat *C)
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
void native(const Twine &path, SmallVectorImpl< char > &result, Style style=Style::native)
Convert path to the native form.
void setUnnamedAddr(UnnamedAddr Val)
INITIALIZE_PASS(JMCInstrumenter, DEBUG_TYPE, "Instrument function entry with call to __CheckForDebuggerJustMyCode", false, false) ModulePass *llvm
static IntegerType * getInt8Ty(LLVMContext &C)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
LLVM Basic Block Representation.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void setSection(StringRef S)
Change the section for this global.
(vector float) vec_cmpeq(*A, *B) C
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
@ Any
The linker may choose any COMDAT.
Class to represent integer types.
void initializeJMCInstrumenterPass(PassRegistry &)
Flag
These should be considered private to the implementation of the MCInstrDesc class.
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
void setName(const Twine &Name)
Change the name of the value.
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.
@ InternalLinkage
Rename collisions when linking (static functions).
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an important base class in LLVM.
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
Module * getParent()
Get the module that this global value is contained inside of...
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
This is an important class for using LLVM in a threaded context.
void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
Class to represent pointers.
void setLinkage(LinkageTypes LT)
static MDString * get(LLVMContext &Context, StringRef Str)
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A Module instance is used to store all the information related to an LLVM module.
StringRef - Represent a constant reference to a string, i.e.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
StringRef getDirectory() const
StringRef getName() const
Return a constant reference to the value's name.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
adds the attribute to the list of attributes for the given arg.
bool has_root_name(const Twine &path, Style style=Style::native)
Has root name?
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
@ X86_FastCall
'fast' analog of X86_StdCall.
@ ExternalLinkage
Externally visible function.
static Type * getVoidTy(LLVMContext &C)
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
void remove_filename(SmallVectorImpl< char > &path, Style style=Style::native)
Remove the last component from path unless it is the root dir.
std::string str() const
str - Get the contents as an std::string.
uint32_t djbHash(StringRef Buffer, uint32_t H=5381)
The Bernstein hash function used by the DWARF accelerator tables.
void setAlignment(MaybeAlign Align)
Class to represent function types.