2012-08-26 6 views
6

Ich bin neu in LLVM. Ich versuche, einen grundlegenden Pass zu schreiben, der die Argumente eines printf-Aufrufs untersucht, wenn ihm die Intermediate-Repräsentation zugewiesen wird.
Wenn die Formatzeichenfolge kein Zeichenfolgenliteral ist, kann ich sie natürlich nicht prüfen. Aber ziemlich oft ist es.Wie erhalten Sie den Wert eines String-Literals in LLVM IR?

Die Probe IR ich zu inspizieren bin versucht:

@.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*, ...) 

fand ich den bereits existierenden Pass ExternalFunctionsPassedConstants genannt, die relevant schien:

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; 

     ... 

So habe ich den Code:

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

So weit, so gut - ich sehe, dass die Typ-ID 14 ist, was bedeutet, dass es eineist.

Nun aber, wie bekomme ich die Inhalt des String-Literals, das als Argument übergeben wird, so kann ich die Anzahl der erwarteten Argumente gegen die tatsächlich angegebene Zahl validieren?

Antwort

6
CS.getArgument(0) 

stellt die GetElementPtrConstantExpr

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

, es ist ein Benutzerobjekt. Die Zeichenfolge, die Sie möchten (z. B. @ .str), ist der erste Operand von GetElementPtrConstantExpr.

So können Sie die Stringliteral durch

CS.getArgument(0).getOperand(0) 

Allerdings zu bekommen, ich habe diesen Code nicht getestet. Wenn es Fehler gibt, bitte sag es mir.

+2

Oh großartig! 'getOperand' zeigte mir in die richtige Richtung! Es scheint, ich brauche 'cast (cast (cast (CS.getArgument (0)) -> getOperand (0)) -> getInitializer()) -> getAsCString()', die mir gibt die Saite. :) Ich danke dir sehr! – Mehrdad