0

all

I want to know how a llvm pass output constant char array defined from the input source. Here's an example that I want to do.

Test input source

char* msg = "hello, world\n";

void msg_out(char * in) {
    printf("msg: %s \n", in);
}

main () {
    ...
    msg_out(msg);
    ...
}

llvm pass snippet

...
const CallInst* ci = dyn_cast<CallInst>(val);
const Function* func = ci->getCalledFunction();

if (func->getName() == "msg_out") {
    errs() << ci->getOperand(0);
}
...

With the source, the above llvm pass would print the following output.

output

i8* getelementptr inbounds ([8 x i8]* @10, i32 0, i32 0)

However, what I want to implement instead is

  1. identify the 1st argument is a constant character array
  2. if so, print out "hello, world\n"

Can anyone let me know how to implement this?

Thanks a lot for your help in advance! /Kangkook

kjee
  • 359
  • 5
  • 19

1 Answers1

1

First of all, the first argument isn't a constant character array; it's a pointer to one, hence the getelementptr (gep). In any case, the proper way to do this is to dereference the gep's pointer, verify it's a global, then get its initializer. In your case (and since the gep is actually a constant expression), it should look like this:

Value* op0 = ci->getOperand(0);
if (GetElementPtrConstantExpr* gep = dyn_cast<GetElementPtrConstantExpr>(op0)) {
  if (GlobalVariable* global = dyn_cast<GlobalVariable>(gep->getOperand(0))) {
    if (ConstantDataArray* array = dyn_cast<ConstantDataArray>(global->getInitializer())) {
      if (array->isCString()) return array->getAsCString();
    }
  }
}
Oak
  • 26,231
  • 8
  • 93
  • 152