Я пишу проход LLVM, который записывает значение глобальной переменной, когда opt вызывается с -var [global_variable_name]. Но я не могу понять, как писать строки, определенные как 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
Да, но переменная CI - это просто пример того, как я записываю значения других типов данных (в этом примере int или char), но не знаю, как записывать строковые переменные char *, потому что данный постоянный тип данных не терпит неудачу в ConstantExp, и я не знаю, как получить значение этой строки, как в ожидаемом результате выше.





Наконец найдено решение, нужно было получить операнд константного выражения, который можно было бы представить как глобальную переменную, и, таким образом, он имеет инициализатор типа постоянного массива данных, поэтому мне просто нужно было вызвать мою функцию над этим типом константы. См. Код ниже:
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
Если
dyn_castвыйдет из строя, не будет лиCInullptr?