插入并填充全局数组LLVM

问题描述 投票:0回答:1

我正在尝试编写LLVM Pass来定位全局数组,将其复制并插入新的修改后的全局数组。但是我什至不能将元素插入到我的新数组中。我尝试了许多不同的操作,例如填充Value *数组,IRBuilder,推入向量,读取从clang发出的终端输出ellvm等。看来,Getelementptr加载和存储应该是执行此操作的最佳方法,但我一直在出错而LLVM文档对此并不能很好地解释。您的帮助将不胜感激。

#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

namespace {

    struct CopyMod : public FunctionPass
    {
        static char ID;
        const ConstantDataArray *data;
        const GlobalVariable *GR;
        ConstantDataArray *Add;
        GlobalVariable *G;
        Module * Mod;

        CopyMod() : FunctionPass(ID) {}

        bool runOnFunction(Function &F) override
        {
          for (inst_iterator idx = inst_begin(F), E = inst_end(F); idx != E; idx++)
          {
             if(auto *GI = dyn_cast<GetElementPtrInst>(&*idx))
             {
                 for(const Value *Op : GI->operands())
                 {
                     if(GR = dyn_cast<GlobalVariable>(Op))
                     {
                         if(data = dyn_cast<ConstantDataArray>(GR->getInitializer()))
                         {
                             errs() << "Number of Elements we got: " << data->getNumElements() << "\n";

                             for(int k = 0, ed = data->getNumElements(); k < ed; ++k)
                                errs() << data->getElementAsInteger(k) << "\n";

                                Mod = F.getParent();
                                auto dude = Mod->getOrInsertGlobal("new_table", ArrayType::get(Type::getInt32Ty(F.getContext()), 
                                                                                                data->getNumElements()));
                                G = Mod->getNamedGlobal("new_table");
                                G->setLinkage(GlobalValue::LinkageTypes::CommonLinkage);

                                auto arrayType = 
                                    llvm::ArrayType::get(llvm::IntegerType::get(idx->getContext(), 32), data->getNumElements());

                                auto arrayPtr = new llvm::AllocaInst(arrayType, "", idx->getContext());

                                for(auto id = 0; id < data->getNumElements(); ++id)
                                {

                                      auto myElt = llvm::ConstantInt::get(idx->getContext(), llvm::APInt(64, 0, true));
                                      auto myIndex = llvm::ConstantInt::get(idx->getContext(), llvm::APInt(32, id, true));

                                      auto ptr = llvm::GetElementPtrInst::Create(arrayPtr->getType(), arrayPtr, { myElt, myIndex }, "", idx->getParent());
                                      auto store = new llvm::StoreInst(myIndex, ptr, false, idx->getParent());
                                }
                                G->setInitializer((Constant *)arrayPtr);
                         }
                     }

                 }
             }
          }
            return false;
        }
    };
} //End of namespace

char CopyMod::ID = 0;
static RegisterPass<CopyMod> X("cpymd", "CopyMod", false, false);
c++ llvm-c++-api
1个回答
0
投票

GetElementPtrInst不执行存储器操作。它仅计算内存地址。您已经构造了新的数组dude,因此要用data的元素填充它,我们将像使用循环那样使用循环,除了每次迭代之外,我们使用[ C0]指令从该地址创建加载操作,并将该加载操作的值存储在GEP数组的相应计算地址中](很酷的名字!也许这就是为什么它总是有麻烦的原因正在获取密码评论:) :))。

我建议您使用一个构建器实例,因为它容易得多。我已经修改了您的代码

dude
© www.soinside.com 2019 - 2024. All rights reserved.