LLVM: lib/CodeGen/JMCInstrumenter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

40

41using namespace llvm;

42

43#define DEBUG_TYPE "jmc-instrumenter"

44

46namespace {

47struct JMCInstrumenter : public ModulePass {

48 static char ID;

51 }

53};

54char JMCInstrumenter::ID = 0;

55}

56

58 bool Changed = runImpl(M);

60}

61

64 "Instrument function entry with call to __CheckForDebuggerJustMyCode",

65 false, false)

66

68

69namespace {

70const char CheckFunctionName[] = "__CheckForDebuggerJustMyCode";

71

72std::string getFlagName(DISubprogram &SP, bool UseX86FastCall) {

73

74

75

76

77

84

85

86

87

88

93

94

95

96

97

98

99

100 std::string Suffix;

102 Suffix.push_back(C == '.' ? '@' : C);

103

105 return (UseX86FastCall ? "_" : "__") +

106 utohexstr(djbHash(FilePath), false,

107 8) +

108 "_" + Suffix;

109}

110

116

117 auto *DType =

118 DB.createBasicType("unsigned char", 8, dwarf::DW_ATE_unsigned_char,

119 llvm::DINode::FlagArtificial);

120

121 auto *DGVE = DB.createGlobalVariableExpression(

123 0, DType, true, true);

124 GV.addMetadata(LLVMContext::MD_dbg, *DGVE);

125 DB.finalize();

126}

127

132}

133

134Function *createDefaultCheckFunction(Module &M, bool UseX86FastCall) {

136 const char *DefaultCheckFunctionName =

137 UseX86FastCall ? "_JustMyCode_Default" : "__JustMyCode_Default";

138

141 DefaultCheckFunctionName, &M);

143 DefaultCheckFunc->addParamAttr(0, Attribute::NoUndef);

144 if (UseX86FastCall)

145 DefaultCheckFunc->addParamAttr(0, Attribute::InReg);

146

149 return DefaultCheckFunc;

150}

151}

152

154 bool Changed = false;

156 Triple ModuleTriple(M.getTargetTriple());

159 assert((IsELF || IsMSVC) && "Unsupported triple for JMC");

160 bool UseX86FastCall = IsMSVC && ModuleTriple.getArch() == Triple::x86;

161 const char *const FlagSymbolSection = IsELF ? ".data.just.my.code" : ".msvcjmc";

162

165 for (auto &F : M) {

166 if (F.isDeclaration())

167 continue;

168 auto *SP = F.getSubprogram();

169 if (!SP)

170 continue;

171

172 Constant *&Flag = SavedFlags[SP];

173 if (!Flag) {

174 std::string FlagName = getFlagName(*SP, UseX86FastCall);

176 Flag = M.getOrInsertGlobal(FlagName, FlagTy, [&] {

177

178

181 ConstantInt::get(FlagTy, 1), FlagName);

185 attachDebugInfo(*GV, *SP);

186 return GV;

187 });

188 }

189

190 if (!CheckFunction) {

192 createDefaultCheckFunction(M, UseX86FastCall);

193 if (IsELF) {

194 DefaultCheckFunc->setName(CheckFunctionName);

196 CheckFunction = DefaultCheckFunc;

197 } else {

198 assert(!M.getFunction(CheckFunctionName) &&

199 "JMC instrument more than once?");

200 auto *CheckFunc = cast(

201 M.getOrInsertFunction(CheckFunctionName, getCheckFunctionType(Ctx))

202 .getCallee());

204 CheckFunc->addParamAttr(0, Attribute::NoUndef);

205 if (UseX86FastCall) {

207 CheckFunc->addParamAttr(0, Attribute::InReg);

208 }

209 CheckFunction = CheckFunc;

210

211 StringRef DefaultCheckFunctionName = DefaultCheckFunc->getName();

213 Comdat *C = M.getOrInsertComdat(DefaultCheckFunctionName);

216

217

218

219 std::string AltOption = std::string("/alternatename:") +

220 CheckFunctionName + "=" +

221 DefaultCheckFunctionName.str();

224 M.getOrInsertNamedMetadata("llvm.linker.options")->addOperand(N);

225 }

226 }

227

228

229 auto *CI = CallInst::Create(getCheckFunctionType(Ctx), CheckFunction,

230 {Flag}, "", F.begin()->getFirstInsertionPt());

231 CI->addParamAttr(0, Attribute::NoUndef);

232 if (UseX86FastCall) {

234 CI->addParamAttr(0, Attribute::InReg);

235 }

236

237 Changed = true;

238 }

239 return Changed;

240}

static bool runImpl(Function &F, const TargetLowering &TLI)

Module.h This file contains the declarations for the Module class.

static bool runImpl(Module &M)

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallString class.

A container for analyses that lazily runs them and caches their results.

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="", InsertPosition InsertBefore=nullptr)

@ Any

The linker may choose any COMDAT.

This is an important base class in LLVM.

StringRef getFilename() const

StringRef getDirectory() const

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)

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.

PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)

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 PointerType * getUnqual(Type *ElementType)

This constructs a pointer to an object of the specified type in the default address space (address sp...

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses none()

Convenience factory function for the empty preserved set.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition 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.

ArchType getArch() const

Get the parsed architecture type of this triple.

bool isOSBinFormatELF() const

Tests whether the OS uses the ELF binary format.

bool isKnownWindowsMSVCEnvironment() const

Checks if the environment is MSVC.

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.

@ C

The default llvm calling convention, compatible with C.

@ X86_FastCall

'fast' analog of X86_StdCall.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

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 LLVM_LIFETIME_BOUND, 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.