Я искал часы и не могу найти ничего, что могло бы мне помочь. Я работаю над проектом, который включает в себя FunctionPass. Я реализовал функцию runOnFunction (функция &е) метод, и это работает нормально. В основном это необходимо для:
1) Определить инструкцию магазина
2) Преобразовать адрес памяти инструкции сохранения в целое число
3) Измените целое число с помощью побитовой операции И (0000FFFF)
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)) {
PtrToIntInst* ptrToInt = new PtrToIntInst(si->getPointerOperand(), IntegerType::get(si->getContext(), 32), "", si);
}
}
}
return true;
}
Я не могу понять, как на самом деле вставить инструкцию или даже найти способ создать инструкцию AND. Если бы кто-нибудь мог указать мне правильное направление, это было бы здорово.
Заранее спасибо.
Я рекомендую взглянуть на Руководство программиста — у этого есть довольно приличное освещение основ.
В частности, есть раздел о создании и вставке новых инструкций. Самый простой способ — просто предоставить существующую инструкцию в качестве последнего аргумента для конструктора новой инструкции, которая затем вставит эту инструкцию непосредственно перед существующей.
В качестве альтернативы, вы можете передать включающий базовый блок, если вы просто хотите добавить в его конец (но помните, что вам нужно позаботиться о терминаторе!). Наконец, вы можете просто позвонить getInstList()
на ограждающем базовом блоке, то insert
или же push_back
вставить новые инструкции там.
Кроме того, вам не нужно перебирать все блоки и затем все инструкции в каждом, вы можете просто перебирать инструкции напрямую; увидеть раздел об итераторе инструкций в руководстве программиста.
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;
}
Вы можете использовать IRBuilder
легко вставлять новые инструкции перед другой инструкцией или в конце основного блока.
В качестве альтернативы, если вам нужно вставить инструкцию после еще один, вам нужно использовать instruction list
в содержащем базовом блоке:
BasicBlock *pb = ...;
Instruction *pi = ...;
Instruction *newInst = new Instruction(...);
pb->getInstList().insertAfter(pi, newInst);
Код и решение взяты из Вот.