LLVM - 如何将 ConstantExpr 转换为 ConstantDataArray 以便打印全局变量 char* 的值?
LLVM - How to convert ConstantExpr to ConstantDataArray so I can print value of global variable char*?
我正在编写 LLVM pass,它在使用 -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
终于找到了解决方案,需要获取可以表示为全局变量的常量表达式的操作数,因此它具有常量数据数组类型的初始化程序,因此只需要通过这种类型的常量调用我的函数.请参阅下面的代码:
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
我正在编写 LLVM pass,它在使用 -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
终于找到了解决方案,需要获取可以表示为全局变量的常量表达式的操作数,因此它具有常量数据数组类型的初始化程序,因此只需要通过这种类型的常量调用我的函数.请参阅下面的代码:
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