SVF icon indicating copy to clipboard operation
SVF copied to clipboard

An intuitive way to convert SVFG node to LLVM Value

Open jjang3 opened this issue 1 year ago • 2 comments

Hello,

So this question pertains to this issue a few years back: https://github.com/SVF-tools/SVF/issues/485

I read through the entire discussion quite carefully and tried to reproduce it, but as the SVF changed quite a bit over few years, I came up with something like this (I have commented out the suggested method with #if 0 because it was throwing me errors:

void checkSVFGwithTargetInsts(const SVFG* svfg, SetVector<Instruction*> targetInsts){

    for(auto it = svfg->begin(); it != svfg->end(); it++) {
        auto targetNode = it->second;
        const llvm::Value *llvm_value;

        #if 0 // Commented it out because it doesn't seem to work anymore.
        const PAGNode* pagnode = svfg->getLHSTopLevPtr(targetNode);
        if(pagnode->hasValue())
            llvm_value = LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(pagnode->getValue()); 
        #endif

        const ICFGNode* icfgNode = targetNode->getICFGNode();
        if (!IntraICFGNode::classof(icfgNode)) 
            continue;
        llvm::errs() << "IntraICFGNode\n";
        auto stmnts = icfgNode->getSVFStmts();
        for (auto item : stmnts)
        {
            auto svfInst = item->getInst();
            llvm_value = LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfInst); 
            for (const llvm::Value* inst : targetInsts)
            {
                llvm::errs() << *inst << " " << *llvm_value << "\n";
                if (inst == llvm_value)  // this is the part I'm failing
                    llvm::errs() << "Found\n";
                llvm::errs() << "\n";
            }
            llvm::errs() << "\n";
        }
    }
}

Output is as follows:


Current function: main
IntraICFGNode
  %a1 = alloca [5 x i32], align 16      %8 = getelementptr inbounds [3 x i8], [3 x i8]* @.str, i64 0, i64 0
   0x55708d15d1f0                        0x55708d15be00  

  %a2 = alloca i32, align 4             %8 = getelementptr inbounds [3 x i8], [3 x i8]* @.str, i64 0, i64 0
   0x55708d15d260                        0x55708d15be00 

IntraICFGNode
  %a1 = alloca [5 x i32], align 16      %a2 = alloca i32, align 4
  0x55708d15d1f0                         0x55708d184430

  %a2 = alloca i32, align 4             %a2 = alloca i32, align 4
  0x55708d15d260                         0x55708d184430

The left output is the instructions in targetInsts, and the right output is as I am iterating through SVFG; I am checking each stmnt node to check whether the instruction matches with any in the targetInsts.

From what I can tell, I am close to getting the desired result but failing the check of if (item == llvm_value), because as you can see, I should have been able to pass the if check of %a2 = alloca i32, align 4 %a2 = alloca i32, align 4

Upon further debugging, I noticed that the address of the llvm_value pointer is different than the item, which is why even though they may be pointing at the same "instruction", the if check is failing.

Therefore my question is as follows:

  1. Is there an easier way than the above code to extract llvm::Value* from the SVF node? (Admittedly, the above code took a while for me to figure out, and I don't even know whether it is correct, I just tried to get the functionality working).

  2. My guess is that even though I extract the value from the SVF into LLVM, I cannot just directly compare the LLVM value with the other LLVM value; what would be the proper way to do this? My potential solution I am thinking of right now is just to use inst->toString() from the SVF and figure out how to convert llvm::Instruction* into a string format as well and do a direct comparison of strings. I am hoping to avoid this because I am unsure whether I may get burned later into the project by doing this.

Thank you in advance. I understand that it is against SVF's principle to do what I want to do (as stated in the issue above), but I still wanted to figure this out if possible, if not I'll just do it via string comparison.

Fixed typos

jjang3 avatar Apr 14 '23 18:04 jjang3

IF anyone wants to use toString() method to compare, you can do it this way (to save you some time)

std::string str;
llvm::raw_string_ostream ss(str);

...
          llvm_value = LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfInst); 
          for (const llvm::Value* inst : targetInsts)
          {
              ss.flush();
              ss << *inst;
              llvm::errs() << strlen(trim(ss.str()).c_str()) << " " << strlen(trim(svfInst->toString()).c_str())<< " " << "\n";
              if (strcmp(trim(ss.str()).c_str(),trim(svfInst->toString()).c_str()) == 0)
                  llvm::errs() << "Found\n";
              str.clear();
          }
          llvm::errs() << "\n";
...

It seems that toString() provides a string with arbitrary whitespace, so I used trim function from https://stackoverflow.com/a/17976541/13626080 to ensure no unnecessary whitespace exists.

Works now:

Current function: main
IntraICFGNode
32 67
25 67

IntraICFGNode
32 25
25 25
Found

jjang3 avatar Apr 14 '23 20:04 jjang3

IF anyone wants to use toString() method to compare, you can do it this way (to save you some time)

std::string str;
llvm::raw_string_ostream ss(str);

...
          llvm_value = LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfInst); 
          for (const llvm::Value* inst : targetInsts)
          {
              ss.flush();
              ss << *inst;
              llvm::errs() << strlen(trim(ss.str()).c_str()) << " " << strlen(trim(svfInst->toString()).c_str())<< " " << "\n";
              if (strcmp(trim(ss.str()).c_str(),trim(svfInst->toString()).c_str()) == 0)
                  llvm::errs() << "Found\n";
              str.clear();
          }
          llvm::errs() << "\n";
...

It seems that toString() provides a string with arbitrary whitespace, so I used trim function from https://stackoverflow.com/a/17976541/13626080 to ensure no unnecessary whitespace exists.

Works now:

Current function: main
IntraICFGNode
32 67
25 67

IntraICFGNode
32 25
25 25
Found

Thanks and would you be able to make a pull request? @xudon9 could you take a look at whether this trim will affect SVF Json format?

yuleisui avatar Apr 15 '23 00:04 yuleisui