This patch provides a new analysis: ExternalFunctionAnalysis (EFA). EFA is useful for my Control-Flow Integrity pass (I'm waiting to submit the CFI patch until EFA is dealt with), since it can inform CFI about potential false positives due to known external function pointers.
The end result of EFA is an analysis that can answer two questions:
- is this Instruction maybe an indirect call that is calling a function that is not in the current Module?
- does this Function maybe contain indirect calls that target functions that are not in the current Module?
These questions are useful when the "current Module" is the Module used during Link-Time Optimization (LTO), since LTO gathers as much of the code as possible into a single Module.
EFA looks for function pointers returned by functions external to the module it is analyzing, and it traces the dataflow of these incoming external function pointers to find places where they are stored or called in indirect function calls.
EFA also supports an attribute annotation: "efa-maybe-external". This can be applied to variables, pointers, or functions (using llvm.var.annotation, llvm.ptr.annotation, and llvm.global.annotations, respectively). EFA traces the dataflow from variables and pointers annotated with efa-maybe-external and finds store instructions and indirect calls. It tries to match these store locations with the stores found from the incoming external function pointer analysis. And it warns if external function pointers are being stored into non-annotated locations.
EFA could be generalized to an Analysis Group, since there's a trivial EFA that just returns false for both questions mentioned above: it simply assumes that no instructions target external function pointers, and no functions contain indirect calls to external function pointers.