Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect callback resolution in pointer analysis #1607

Open
Frankenween opened this issue Dec 12, 2024 · 6 comments
Open

Incorrect callback resolution in pointer analysis #1607

Frankenween opened this issue Dec 12, 2024 · 6 comments

Comments

@Frankenween
Copy link

While using the wonderful SVF tool for building callgraphs I noticed that some pretty obvious callbacks are not resolved.
Problematic pattern looks like this:

struct t1 {
	void(*ptr)();
};

struct t1 o1 = {
	.ptr = f1
};

void test1() {
	o1.ptr();
}

Call test1 -> f1 is not resolved. However, when there are several callbacks in a struct, the rest seem to be resolved nicely. I thought the problem is with load vs gep:

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @test6() #1 {
  %1 = load ptr, ptr @t6, align 8
  call void (...) %1()
  %2 = load ptr, ptr getelementptr inbounds (%struct.s1, ptr @t6, i32 0, i32 1), align 8
  call void (...) %2()
  ret void
}

But changing first load to gep manually didn't help.
In my task the problem appeared with different fields, not with the first only. Looks like the problem is not Andersen-specific as almost every analysis failed. On the provided test Steensgaard succeeded, but it also failed in my original problem.

test.zip - here test file, its IR and the result of wpa -ander -dump-callgraph.

@yuleisui
Copy link
Collaborator

@jumormt could you take a look at this case?

@yuleisui
Copy link
Collaborator

It should be correct if you rename test1 as main since the program has to have a main driver function.

@Frankenween
Copy link
Author

Nope, it didn't help.
test.zip

@jumormt
Copy link
Contributor

jumormt commented Dec 13, 2024

Nope, it didn't help. test.zip

@Frankenween I believe your observation is correct. The opaque pointer version bitcode miss a gep before loading. This can be solved by turning the ff-eq-base option on: wpa -ander -ff-eq-base -dump-callgraph /path/to/your/bitcode

@jumormt
Copy link
Contributor

jumormt commented Dec 13, 2024

This option basically treats the first field equally as the base object.

Nope, it didn't help. test.zip

@Frankenween I believe your observation is correct. The opaque pointer version bitcode miss a gep before loading. This can be solved by turning the ff-eq-base option on: wpa -ander -ff-eq-base -dump-callgraph /path/to/your/bitcode

@Frankenween
Copy link
Author

Life-saving, thanks! I'll try it on my main project later

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants