inkwell icon indicating copy to clipboard operation
inkwell copied to clipboard

Question about reading GEP const expr

Open nilslice opened this issue 2 years ago • 3 comments

I'm looking to extract the global ident name "tag" from the following function call:

@tag = internal constant [10 x i8] c"tag_value\00"

declare void @some_func(i8*)

define internal void @main() unnamed_addr {

body:
    tail call void @some_func(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @tag, i32 0, i32 0))
    ret void

}

But when I encounter the some_func function, and am presented with its arguments, I can't seem to do anything useful with the PointerValue (i8*).

The closest I've come is only by knowing in-advance the size of the array, and using it to construct the following:

ptr_value.const_cast(
            context
                .i8_type()
                .array_type(10) // how to get size from ptr_value as array type?
                .ptr_type(inkwell::AddressSpace::Generic),
)

Once I have this, I can use the get_name() method, and resolve the string value in my global. However, without knowing the size in advance, I get no name to lookup.

Thank you for any tips/pointers!

nilslice avatar May 16 '22 17:05 nilslice

Perhaps you're looking for Module::get_global which takes the name by string or Module::get_first_global?

TheDan64 avatar Jun 25 '22 20:06 TheDan64

how to get size from ptr_value as array type?

Array types have a length as they're predefined. Raw pointers don't had a known length ahead of time? You could call PointerType::get_element_type to get the pointed too array and get the length of that

TheDan64 avatar Jun 25 '22 20:06 TheDan64

Perhaps you're looking for Module::get_global which takes the name by string or Module::get_first_global?

The name or index of the global isn't known since you're starting from only the argument i8* getelementptr inbounds ([10 x i8], [10 x i8]* @tag, i32 0, i32 0).

You could call PointerType::get_element_type to get the pointed too array and get the length of that

The element type is i8.

In LLVM, you can look at i8* getelementptr inbounds ([10 x i8], [10 x i8]* @tag, i32 0, i32 0) as a constant getelementptr expression whose first operand is the value @tag = internal constant [10 x i8] c"tag_value\00". From there, you can get its value or name since it's a ConstantDataArray.

So with internal-getters and llvm-sys you can do this:

let expr = unsafe { ptr_value.get_ref() };
let element = unsafe { LLVMGetOperand(expr, 0) };

where element is the LLVM value for @tag = internal constant [10 x i8] c"tag_value\00". It doesn't seem like this is possible in safe Inkwell because get_operand requires an InstructionValue, but ptr_value can't be converted to InstructionValue.

bamarsha avatar Oct 28 '22 20:10 bamarsha