2012-08-26 13 views
6

Soy nuevo en LLVM. Intento escribir un pase básico que inspeccionará los argumentos de una llamada printf, cuando se le dé la representación intermedia.
Si la cadena de formato no es una cadena literal, entonces, por supuesto, no puedo inspeccionarla. Pero a menudo, lo es.¿Cómo obtener el valor de una cadena literal en LLVM IR?

El IR muestra que estoy tratando de inspeccionar es:

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

me encontré con el paso de llama preexistente ExternalFunctionsPassedConstants, que parecía relevante:

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; 

     ... 

por lo que añade el código:

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

Hasta ahora, bien - Veo que el tipo ID es 14, lo que significa que es PointerTyID.

Pero ahora, ¿cómo obtengo el contenido del literal de cadena que se pasa como argumento, entonces puedo validar el número de argumentos esperados contra el número realmente dado?

Respuesta

6
CS.getArgument(0) 

representa la GetElementPtrConstantExpr

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

, es un objeto de usuario. La cadena que desea (es decir, @ .str) es este primer operando de GetElementPtrConstantExpr.

Por lo tanto, se puede obtener a través de la cadena literal

CS.getArgument(0).getOperand(0) 

Sin embargo, no he probado este código. Si hay algún error, por favor dígame.

+2

¡Oh impresionante! 'getOperand' me señaló en la dirección correcta! Parece que necesito 'lanzar (emitir (emitir (CS.getArgument (0)) -> getOperand (0)) -> getInitializer()) -> getAsCString()', que me da la cuerda. :) ¡Muchas gracias! – Mehrdad

Cuestiones relacionadas