LLVM-如何将ConstantExpr转换为ConstantDataArray,以便可以打印全局变量char *的值?

时间:2018-12-28 15:06:11

标签: c++ llvm llvm-ir llvm-c++-api

我正在写LLVM传递,该传递在使用-var [global_variable_name]调用opt时写入全局变量的值。但是我不知道如何写定义为char * string =“ help”;的字符串。在.c源代码中。

我尝试过:

if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
        writeConstant(Out, CE->getAggregateElement(CV));
        return;
}

但这导致SEGFAULT。

这是用于编写int类型的全局变量的函数的一部分:

void writeConstant(raw_ostream &Out, const Constant *CV)
{
    if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
        if (CI->getType()->isIntegerTy(1)) {
             Out << (CI->getZExtValue() ? "true" : "false");
            return;
        }
    }
   APInt AI = CI->getValue();
        if( CI->getBitWidth() == 8) { // if sizeof constant == sizeof char
            const uint64_t *letter = AI.getRawData();
            if(char letter2 = (char) (*letter)) {
                Out << letter2;
                return;
            }
        }
        Out << CI->getValue();
        return;
    }

预期结果:

testsource.c中的行如下:

char *testString = "Hello";

调用bash:

opt -load pass.so -var testString < testsource.bc > /dev/null

以上命令的输出:

Hello

1 个答案:

答案 0 :(得分:0)

最后找到了解决方案,需要获取可以表示为全局变量的常量表达式的操作数,因此它具有常量数据数组类型的初始化程序,因此仅需要在此类Constant上调用我的函数。参见下面的代码:

    if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
        Value *firstop = CE->getOperand(0);
        if (GlobalVariable *GV = dyn_cast<GlobalVariable>(firstop)) {
            Constant *v = GV->getInitializer();
            writeConstant(Out, v);
        }
        return;
    }

有关更多信息,请参见回购:https://github.com/Petku/GlobalVariablePass/blob/master/globvars/globvars.cpp