2012-08-26 18 views
6

Jestem nowy w LLVM. Próbuję napisać podstawowe hasło, które będzie sprawdzać argumenty wywołania printf, gdy otrzyma reprezentację pośrednią.
Jeśli ciąg formatu nie jest literałem ciągłym, to oczywiście nie mogę go sprawdzić. Ale dość często tak jest.Jak uzyskać wartość literału ciągu w LLVM IR?

IR próbki Próbuję sprawdzić to:

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

znalazłem wcześniej istniejących Przełęcz nazywa ExternalFunctionsPassedConstants, co wydawało się istotne:

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; 

     ... 

Więc dodałem kod:

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

Jak dotąd, tak dobrze - widzę, że identyfikator typu to 14, co oznacza, że ​​jest to PointerTyID.

Ale teraz, jak mogę uzyskać zawartość z literału ciągu, który jest przekazywany jako argument, więc mogę sprawdzić poprawność liczby oczekiwanych argumentów w stosunku do faktycznie podanej liczby?

Odpowiedz

6
CS.getArgument(0) 

reprezentuje GetElementPtrConstantExpr

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

, że jest to obiekt użytkownika. Łańcuch, który chcesz (tj. @str .str) jest pierwszym operandem GetElementPtrConstantExpr.

Tak, można uzyskać ciąg dosłownego przez

CS.getArgument(0).getOperand(0) 

Jednak nie testowałem tego kodu. Jeśli są jakieś błędy, proszę powiedz mi.

+2

Och, super! 'getOperand' wskazał mi właściwy kierunek! Wydaje mi się, że potrzebuję 'cast (cast (cast (CS.getArgument (0)) -> getOperand (0)) -> getInitializer()) -> getAsCString()', co daje mi ciąg znaków. :) Dziękuję bardzo! – Mehrdad

Powiązane problemy