'LLVM beginner: instrument, string type and metadata

I am a beginner in LLVM, and I wanna get the true value of a given varibale name and line number by using LLVM pass. I have several problems.

  • correctly get the metadata;
  • get the type of String;
  • get dynamic value.

For example, I wanna get the value of b after line 7:

#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.
// Maybe a pointerType?
      };
      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. 
// Still the problem: how to write STRING's type in LLVM?
            builder.CreateCall(logFunc, args);
          }
        }
      }
      return false;
    }

Problems are in code. I cannot make myself understood clearly by using English.



Solution 1:[1]

I think String maybe i8*. You can read this link https://llvm.org/docs/LangRef.html#function-type to get function type.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 prettypig