Sorry to disturb you. I read your reply for a whole day; your code works well and helps a lot. But I still have two problems.
- correctly get the metadata;
- get the type of String
- get dynamic value.
My example demo.cpp
described in the topic is simple. And what I wanna express is that the varibale b
can not be read in IR, which can be shown in below code:
#include <iostream>
int main() {
int b;
int a;
std::cin >> a;
b = a; // line 7
return 0;
}
IR of the main
function:
; Function Attrs: mustprogress noinline norecurse optnone uwtable
define dso_local i32 @main() #4 !dbg !857 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
store i32 0, i32* %1, align 4
call void @llvm.dbg.declare(metadata i32* %2, metadata !858, metadata !DIExpression()), !dbg !859
call void @llvm.dbg.declare(metadata i32* %3, metadata !860, metadata !DIExpression()), !dbg !861
%4 = call nonnull align 8 dereferenceable(16) %"class.std::basic_istream"* @_ZNSirsERi(%"class.std::basic_istream"* nonnull align 8 dereferenceable(16) @_ZSt3cin, i32* nonnull align 4 dereferenceable(4) %3), !dbg !862
%5 = load i32, i32* %3, align 4, !dbg !863
store i32 %5, i32* %2, align 4, !dbg !864
ret i32 0, !dbg !865
}
; METADATA
!857 = distinct !DISubprogram(name: "main", scope: !8, file: !8, line: 11, type: !539, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !9)
!858 = !DILocalVariable(name: "b", scope: !857, file: !8, line: 12, type: !20)
!859 = !DILocation(line: 12, column: 9, scope: !857)
!860 = !DILocalVariable(name: "a", scope: !857, file: !8, line: 13, type: !20)
!861 = !DILocation(line: 13, column: 9, scope: !857)
!862 = !DILocation(line: 14, column: 14, scope: !857)
!863 = !DILocation(line: 15, column: 9, scope: !857)
!864 = !DILocation(line: 15, column: 7, scope: !857)
!865 = !DILocation(line: 16, column: 5, scope: !857)
I need to read dynamic value, so I instrument logvar
function:
#include <iostream>
#include <string>
extern "C" void logvar(int i, std::string name) {
std::cout << "Num: " << i << "; Name: " << name << std::endl;
}
And now, my pass.cpp
is as follows:
virtual bool runOnFunction(Function &F) {
// Get the function to call from our runtime library.
LLVMContext &Ctx = F.getContext();
std::vector<Type*> paramTypes = {
Type::getInt32Ty(Ctx),
// Here I need a string type to match logvar function,
// but I don't know how to write it.
};
Type *retType = Type::getVoidTy(Ctx);
FunctionType *logFuncType = FunctionType::get(retType, paramTypes, false);
FunctionCallee logFunc =
F.getParent()->getOrInsertFunction("logvar", logFuncType);
for (auto &B : F) {
for (auto &I : B) {
if (auto *op = dyn_cast<LoadInst>(&I)) { // timo_schalachter
int number;
auto alloca = dyn_cast<AllocaInst>(op->getOperand(0));
for (auto user: alloca->users()) {
if (auto store = dyn_cast<StoreInst>(user)) {
auto constant_int = dyn_cast<ConstantInt>(store->getOperand(0));
number = constant_int->getSExtValue();
errs() << number << "\n";
}
}
}
if (auto *op = dyn_cast<StoreInst>(&I)) {
errs() << *op << ".StoreInst\n";
Value *val = op->getValueOperand();
if (auto constant_int = dyn_cast<ConstantInt>(val)) {
int number = constant_int->getSExtValue();
errs() << number << ".\n\n";
} else if (auto constant_fp = dyn_cast<ConstantFP>(val)) {
float number = constant_fp->???;
// I cannot find the function to get the value of float point here.
} // and how to deal with constant string?
// metadata:
// store i32 %4, i32* %2, align 4, !dbg !863
Value *arg1 = op->getOperand(0); // %4 = xxx
Value *arg2 = op->getOperand(1); // %2 = xxx
unsigned mk = op->getContext().getMDKindID("dbg");
MDNode *mdn = op->getMetadata(mk);
if (mdn) {
Metadata *mds = mdn->getOperand(0);
StringRef str;
if (MDString::classof(mds)) {
str = (cast<MDString>(*mds)).getString();
errs() << str;
}
} else {
errs() << "no dbg!\n";
// when I run this code, it always says: "no dbg!"
// I don't know why...
}
// instrumentation
IRBuilder<> builder(op);
builder.SetInsertPoint(&B, ++builder.GetInsertPoint());
Value* args[] = {arg1, ???};
// I cannot find the name of variable.
// I think it should be str in metadata.
// But you know, I can not get it .
builder.CreateCall(logFunc, args);
}
}
}
return false;
}
Problems are in code. I cannot make myself understood clearly by using English.
If you know answer, PLEASE Help Me
when you are available.
And I am really new to llvm, so sometimes when I read document of LLVM, I cannot catch the key points completely or find the target function. Just like the method op->getMetadata(1)
mentioned in the reply, I spent a lot of time to search and try how to use it. And unfortunately, it seems I still cannot get metadata properly 
And any links or code snippets or even telling me key phrases to google myself are appreciated! Thank you thank you thank you!