2012-11-13 9 views
5

Ho cercato ore e non riesco a trovare nulla che possa aiutarmi. Sto lavorando a un progetto che prevede un FunctionPass. Ho implementato un metodo runOnFunction (Funzione & f) e funziona bene. Fondamentalmente si deve:Come inserire un'istruzione LLVM?

1) Rilevare un istruzione di memorizzazione

2) Convertire l'indirizzo di memoria della istruzione di memorizzazione di un intero

3) Modificare il numero intero utilizzando un'operazione AND (0000FFFF)

4) Convertire il numero intero di nuovo nel puntatore

Finora ho ottenuto il seguente:

virtual bool runOnFunction(Function &F) { 
    for (Function::iterator bb = F.begin(), bbe = F.end(); bb != bbe; ++bb) { 
    BasicBlock& b = *bb; 
    for (BasicBlock::iterator i = b.begin(), ie = b.end(); i != ie; ++i) { 
     if(StoreInst *si = dyn_cast<StoreInst>(&*i)) { 
     PtrToIntInst* ptrToInt = new PtrToIntInst(si->getPointerOperand(), IntegerType::get(si->getContext(), 32), "", si); 
     } 
    } 
    } 
    return true; 
} 

Non riesco, per la vita di me, a capire come inserire effettivamente l'istruzione, o persino a trovare un modo per creare un'istruzione AND. Se qualcuno potesse indicarmi la giusta direzione, sarebbe fantastico.

Grazie in anticipo.

risposta

4

Si consiglia di dare un'occhiata allo Programmer's Manual - ha una copertura abbastanza decente delle nozioni di base.

In particolare, c'è a section about creating and inserting new instructions. Il modo più semplice è solo quello di fornire un'istruzione esistente come ultimo argomento per il costruttore della nuova istruzione, che quindi inserirà quell'istruzione immediatamente prima di quella esistente.

In alternativa, è possibile passare il blocco di base che lo racchiude se si desidera solo aggiungere alla sua fine (ma ricorda che è necessario occuparsi del terminatore!). Infine, è possibile chiamare lo getInstList() sul blocco di base allegato, quindi insert o push_back per inserire nuove istruzioni lì.

Come parte, non è necessario eseguire iterazioni su tutti i blocchi e quindi su tutte le istruzioni di ciascuno, è possibile semplicemente scorrere direttamente le istruzioni; vedi the section about the instruction iterator in the programmer's manual.

+0

Come si prende cura del terminatore in caso di passaggio di un blocco di base in allegato? – PatoBeltran

+1

@PatoBeltran L'aggiunta di istruzioni in questo modo non attiva la verifica del blocco di base, pertanto è possibile avere un blocco di base non valido in tali fasi intermedie. Assicurati di posizionare un terminatore alla fine prima di completare la funzione di passaggio. – Oak

4
virtual bool runOnFunction(Function &F) { 
    for (Function::iterator bb = F.begin(), bbe = F.end(); bb != bbe; ++bb) { 
    BasicBlock &b = *bb; 
    for (BasicBlock::iterator i = b.begin(), ie = b.end(); i != ie; ++i) { 
     if (StoreInst *si = dyn_cast<StoreInst>(&*i)) { 
     IRBuilder Builder(si); 
     Value *StoreAddr = Builder.CreatePtrToInt(si->getPointerOperand(), Builder.getInt32Ty()); 
     Value *Masked = Builder.CreateAnd(StoreAddr, 0xffff); 
     Value *AlignedAddr = Builder.CreateIntToPtr(Masked, si->getPointerOperand()->getType()); 
     // ... 
     } 
    } 
    } 
    return true; 
} 
0

È possibile utilizzare un IRBuilder per inserire facilmente nuove istruzioni prima di un'altra istruzione o alla fine di un blocco di base.

In alternativa, se avete bisogno di inserire un'istruzione dopo un altro, è necessario utilizzare il instruction list nel blocco di base contenente:

BasicBlock *pb = ...; 
Instruction *pi = ...; 
Instruction *newInst = new Instruction(...); 

pb->getInstList().insertAfter(pi, newInst); 

Codice e soluzione prelevata dalla here.