2012-08-26 16 views
6

私はLLVMを初めて使う人です。私はprintf呼び出しの引数を検査する基本的なパスを記述しようとしています。中間の表現が与えられているときです。
フォーマット文字列が文字列リテラルでない場合は、もちろん検査できません。しかし、かなりの頻度で、そうです。LLVM IRで文字列リテラルの値を取得する方法は?

私が検査しようとしているサンプルのIRは、次のとおりです。

@.str = private unnamed_addr constant [7 x i8] c"Hi %u\0A\00", align 1 

define i32 @main() nounwind { 
entry: 
    %retval = alloca i32, align 4 
    store i32 0, i32* %retval 
    %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), i32 1) 
    ret i32 0 
} 

declare i32 @printf(i8*, ...) 

私は既存のパスが関連思えた、ExternalFunctionsPassedConstantsと呼ばれるが見つかりました:

struct ExternalFunctionsPassedConstants : public ModulePass { 
    static char ID; // Pass ID, replacement for typeid 
    ExternalFunctionsPassedConstants() : ModulePass(ID) {} 
    virtual bool runOnModule(Module &M) { 
    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 
     if (!I->isDeclaration()) continue; 

     bool PrintedFn = false; 
     for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); 
      UI != E; ++UI) { 
     Instruction *User = dyn_cast<Instruction>(*UI); 
     if (!User) continue; 

     CallSite CS(cast<Value>(User)); 
     if (!CS) continue; 

     ... 

だから私は、コードを追加:

 if (I->getName() == "printf") { 
      errs() << "printf() arg0 type: " 
       << CS.getArgument(0)->getType()->getTypeID() << "\n"; 
     } 

これまでのところ、タイプIDが14であることがわかりました。つまり、それはです。

今のところ、引数として渡される文字列リテラルのの内容を取得するにはどうすればよいでしょうか?実際に与えられた数に対して予想される引数の数を検証できますか?

答えて

6
CS.getArgument(0) 

がGetElementPtrConstantExpr

i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0) 

を表し、それは、ユーザオブジェクトです。必要な文字列(つまり、@ .str)は、GetElementPtrConstantExprの最初のオペランドです。

だから、あなたはしかし

CS.getArgument(0).getOperand(0) 

を通じてリテラル文字列を取得することができ、私はこのコードをテストしていません。間違いがある場合は教えてください。

+2

すごい! 'getOperand'が正しい方向に私を指摘しました!それは私に 'キャスト(キャスト(キャスト(CS.getArgument(0)) - > getOperand(0)) - > getInitializer()) - > getAsCString文字列:) どうもありがとうございます! – Mehrdad

関連する問題