How to get the vaue of a global constant

Hi all,
I’m working on a plugin that should help me to add instructions inside a binary. i reach the point I need to get the value of a global const (str) but I’m not sure how to get it. The ll is the following:

; ModuleID = 'globalString.bc'
source_filename = "llvm-link"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

@.str = private unnamed_addr constant [12 x i8] c"Hello Hello\00", align 1
@string = dso_local global i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), align 8

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
  %1 = alloca i32, align 4
  %2 = alloca i8, align 1
  store i32 0, i32* %1, align 4
  %3 = load i8*, i8** @string, align 8
  %4 = getelementptr inbounds i8, i8* %3, i64 0
  %5 = load i8, i8* %4, align 1
  store i8 %5, i8* %2, align 1
  ret i32 0
}

attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.ident = !{!0}
!llvm.module.flags = !{!1, !2, !3}

!0 = !{!"Debian clang version 13.0.1-++20220115052946+5869ea6c6254-1~exp1~20220115053031.58"}
!1 = !{i32 1, !"wchar_size", i32 4}
!2 = !{i32 7, !"uwtable", i32 1}
!3 = !{i32 7, !"frame-pointer", i32 2}

Inside my plugin I have the function visitLoadInst where I’m able to extract the str global. The code is the following

...
} else if (GEPOperator * GEP = cast<GEPOperator>(G->getOperand(0))) {
            std::cout << "GEP" << "\n";
            if (Constant * CE = cast<Constant>(GEP->getOperand(0))) {
                std::cout << "Constant expression" << "\n";
                CE->dump();
                //I want to print Hello Hello here.... 
            }

            I.dump();
}
...

Once I use my application the option seems to tell me that I’m close:

Bitcode file extracted to: global.bc.
GEP
Constant expression
@.str = private unnamed_addr constant [12 x i8] c"Hello Hello\00", align 1
  %3 = load i8*, i8** @string, align 8
GEP
Constant expression
@.str = private unnamed_addr constant [12 x i8] c"Hello Hello\00", align 1
  %3 = load i8*, i8** @string, align 8
GEP
Constant expression
@.str = private unnamed_addr constant [12 x i8] c"Hello Hello\00", align 1
  %3 = load i8*, i8** @string, align 8
Bitcode file extracted to: globalString.bc.

Now, how can print Hello Hello and the numeric representation of each character?

Thanks

Are you interested in strings in particular? In that case you can use the getConstantStringInfo() helper from ValueTracking (llvm-project/ValueTracking.cpp at 85e9b2687a13d1908aa86d1b89c5ce398a06cd39 · llvm/llvm-project · GitHub).

Hi @nikic,
thanks for your answer. is it possible for you to show me which include I should an example on how to use the function?

In reality I would like also to have the int representation of each character but I can work on it later if llvm does not have an helper for it.

Thanks

Hi @nikic ,
I made some progress doing:

StringRef a;
bool ret = getConstantStringInfo(CE, a, 0, true);
cout << ret << "\n";
cout << a.data() << "\n";

@Alberto If you know the constant is a global variable with an initializer, perhaps you could do something like this:

auto *gv = llvm::dyn_cast<llvm::GlobalVariable>(CE);
if (gv && gv->getInitializer()) {
    // do something with gv->getInitializer()
}

Hi @theakman2 ,
sorry for the late reply. In the end I used the recommendation from @nikic but thanks a lot anyway. I’ll try to keep in my it for the next time.

Alberto