Constants
It looks like store ptr %foo, ptr @bar, ... means “store the value in SSA register foo in global variable bar”. I think this is what Victor means by “constant”. I’ve changed my mind, I don’t think it’s what Victor meant.
This can be reproduced with
int* C;
extern int* get_pointer(int*);
void f(int* foo) {
int* bar = get_pointer(foo);
C = bar;
}I’m going to try to get store ptr %foo, ptr null, ....
After consulting with AI, I’ve found this program that can produce the desired output.
void store_at_null(void* foo) {
void* volatile* p = (void* volatile*)0;
*p = foo;
}It produces the main body
define dso_local void @store_at_null(ptr noundef %foo) #0 {
entry:
store volatile ptr %foo, ptr null, align 8, !tbaa !4
ret void
}and running it with &inator produces the following warning:
WARN: Encountered `store` with non-variable LHS
So I assume this is what we’re looking for in terms of constants.
Based on searching, it seems like this isn’t very prevalent in the LLVM code, so I’ll probably focus on function pointers for now.
Function Pointers
Working example:
int add(int *x, int *y) {
return *x + *y;
}
int calc(int (*f)(int*, int*), int x, int y) {
return (*f)(&x, &y);
}
int main() {
int result = calc(&add, 1, 2);
return 0;
}Relevant LLVM output:
; Function Attrs: nounwind uwtable
define dso_local i32 @add(ptr noundef %x, ptr noundef %y) #0 {
entry:
%0 = load i32, ptr %x, align 4, !tbaa !4
%1 = load i32, ptr %y, align 4, !tbaa !4
%add = add nsw i32 %0, %1
ret i32 %add
}
; Function Attrs: nounwind uwtable
define dso_local i32 @calc(ptr noundef %f, i32 noundef %x, i32 noundef %y) #0 {
entry:
%x.addr = alloca i32, align 4
%y.addr = alloca i32, align 4
store i32 %x, ptr %x.addr, align 4, !tbaa !4
store i32 %y, ptr %y.addr, align 4, !tbaa !4
%call = call i32 %f(ptr noundef %x.addr, ptr noundef %y.addr)
ret i32 %call
}
; Function Attrs: nounwind uwtable
define dso_local i32 @main() #0 {
entry:
%call = call i32 @calc(ptr noundef @add, i32 noundef 1, i32 noundef 2)
ret i32 0
}How does &inator currently handle function pointers?
ptr noundef @add gets a pointer to the global function add.
&inator panics in Instruction::extract_callee when it gets llvm_ir::Operand::LocalOperand. I’m not sure how to handle this yet, so I need to get to know the surrounding code better.
I’m going to add a Callee type to Instruction::Call that specifies whether the call is a “global” or “local” function.
This seems to be working out. Now, I just need to propagate the changes outward.
Maybe, instead of having callee inside of Instruction::Call be different, I’ll create two different enums, Instruction::GlobalCall and Instruction::LocalCall.
This didn’t seem to produce a lot of value. I think I’ll just have the callee field be different.