Как преобразовать ConstantExpr в ConstantDataArray, чтобы я мог напечатать значение глобальной переменной char *? - PullRequest
0 голосов
/ 28 декабря 2018

Я пишу проход 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

1 Ответ

0 голосов
/ 05 января 2019

Наконец, найденное решение, было необходимо получить операнд константного выражения, который мог бы быть представлен как глобальная переменная, и, таким образом, он имел инициализатор типа массива данных констант, так что просто нужно было вызвать мою функцию через этот тип константы.См. Код ниже:

    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

...