LLVM - How to convert ConstantExpr to ConstantDataArray so I can print value of global variable char*?

Viewed 609

I'm writing LLVM pass which writes value of global variable when opt is called with -var [global_variable_name]. But I'm not able to find out how to write strings defined as char *string = "help"; in .c source code.

I have tried:

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

but this resulted in SEGFAULT.

This is part of function for writing global variable of int type:

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;
    }

Excpected result:

In testsource.c is line as follows:

char *testString = "Hello";

Calling in bash:

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

Output of command above:

Hello
1 Answers

Finally found out solution, it was needed to get operand of constant expression which could be represented as global variable and thus it has initializer of constant data array type so it was just needed to call my function over this type of Constant. See code below:

    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;
    }

For more information look up in repo: https://github.com/Petku/GlobalVariablePass/blob/master/globvars/globvars.cpp

Related