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

Function pointers passed to and called in a variadic function are ignored in the call graph #551

Open
lzaoral opened this issue Nov 21, 2021 · 6 comments

Comments

@lzaoral
Copy link
Contributor

lzaoral commented Nov 21, 2021

Consider the following C program:

#include <stdarg.h>

void foo(void) {}

void bar(int a, ...)
{
    va_list vaargs;
    va_start(vaargs, a);

    void (*b)(void) = va_arg(vaargs, void(*)(void));
    b();

    va_end(vaargs);
}

int main(void)
{
    bar(5, foo);
}

The corresponding call graph generated by wpa -ander -dump-callgraph main.ll:

Problem: The call to foo from bar is missing. However, if bar isn't variadic, the constructed call graph is correct.

@yuleisui
Copy link
Collaborator

This is a very good case. SVF can not handle variadic functions statically for now. We will put this on our list to seek help with this.

@timmyyuan
Copy link
Contributor

@yuleisui I find that variadic arguments have been handled in the SVF here. Is it safe to remove this condition directly so we can connect variadic functions in the call graph?

@yuleisui
Copy link
Collaborator

Because pointer analysis can be conservative, it can happen the argument mismatch even if the case is not variadic.

@timmyyuan
Copy link
Contributor

@yuleisui Thanks for the explanation, but the following scene confuses me (I hope %1 can resolve to @bar)

; ModuleID = './test/InitExtFnPtr.bc'
source_filename = "./test/InitExtFnPtr.bc"

@fnptr = global i32 (i32, ...)* @bar, align 8

declare i32 @bar(i32, ...)

define void @foo() {
    %ret = alloca i32, align 4
    %1 = load i32 (i32, ...)*, i32 (i32, ...)** @fnptr, align 8
    %2 = load i32, i32* %ret, align 4
    %call = call i32 (i32, ...) %1(i32 1, i32 256, i32 %2)
    ret void
}

but when I tried:

../svf-latest/Release-build/bin/wpa -ander -print-fp test/InitExtFnPtr.bc

SVF answered:

==================Function Pointer Targets==================

NodeID: 17
CallSite:    %call = call i32 (i32, ...) %1(i32 1, i32 256, i32 %2)     Location:
        !!!has no targets!!!

@yuleisui
Copy link
Collaborator

I think one fix is to let matchargs return true if it calls a variadic function. Could you make a pull request?

@timmyyuan
Copy link
Contributor

Sure, PTAL #1031

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