42#define DEBUG_TYPE "jmc-instrument"
52char JMCInstrumenter::ID = 0;
57 "Instrument function entry with call to __CheckForDebuggerJustMyCode",
63const char CheckFunctionName[] =
"__CheckForDebuggerJustMyCode";
65std::string getFlagName(
DISubprogram &SP,
bool UseX86FastCall) {
75 ? sys::path::Style::windows_backslash
76 : sys::path::Style::posix;
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);
123 PointerType *VoidPtrTy = PointerType::getUnqual(Ctx);
124 return FunctionType::get(VoidTy, VoidPtrTy,
false);
127Function *createDefaultCheckFunction(
Module &M,
bool UseX86FastCall) {
129 const char *DefaultCheckFunctionName =
130 UseX86FastCall ?
"_JustMyCode_Default" :
"__JustMyCode_Default";
134 DefaultCheckFunctionName, &M);
135 DefaultCheckFunc->
setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
142 return DefaultCheckFunc;
146bool 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))
196 CheckFunc->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
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);
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
LLVM Basic Block Representation.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
@ Any
The linker may choose any COMDAT.
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.
This is an important base class in LLVM.
StringRef getFilename() const
StringRef getDirectory() const
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
adds the attribute to the list of attributes for the given arg.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalObject.
void setComdat(Comdat *C)
void setSection(StringRef S)
Change the section for this global.
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
void setUnnamedAddr(UnnamedAddr Val)
void setLinkage(LinkageTypes LT)
Module * getParent()
Get the module that this global value is contained inside of...
@ InternalLinkage
Rename collisions when linking (static functions).
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static MDString * get(LLVMContext &Context, StringRef Str)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
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.
static Type * getVoidTy(LLVMContext &C)
static IntegerType * getInt8Ty(LLVMContext &C)
void setName(const Twine &Name)
Change the name of the value.
StringRef getName() const
Return a constant reference to the value's name.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ X86_FastCall
'fast' analog of X86_StdCall.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
void remove_filename(SmallVectorImpl< char > &path, Style style=Style::native)
Remove the last component from path unless it is the root dir.
bool has_root_name(const Twine &path, Style style=Style::native)
Has root name?
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
void initializeJMCInstrumenterPass(PassRegistry &)
ModulePass * createJMCInstrumenterPass()
JMC instrument pass.
uint32_t djbHash(StringRef Buffer, uint32_t H=5381)
The Bernstein hash function used by the DWARF accelerator tables.
void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
This struct is a compact representation of a valid (non-zero power of two) alignment.