Hi,
I am writing a pass which is supposed to ignore library functions. Is there a way to
distinguish functions declared and defined by a developer from non-local functions (library functions)?
Thanks.
George
Hi,
I am writing a pass which is supposed to ignore library functions. Is there a way to
distinguish functions declared and defined by a developer from non-local functions (library functions)?
Thanks.
George
Hi,
I am writing a pass which is supposed to ignore library functions. Is there a way to
distinguish functions declared and defined by a developer from non-local functions (library functions)?
Thanks.
There is no reliable way to do this, but there are several heuristics that will probably work well in practice.
When analyzing a program, any function that is defined (i.e., has a function body) most likely came from the program’s source code. The exception will be functions declared in system header files or C/C++ library header files.
Any function that is declared but not defined (i.e., has no function body) is either a function that is defined in another translation unit (i.e., another source file) or defined in a system or language library (e.g., libc). It is, in general, not possible to distinguish between the two situations, although if you’ve linked your entire program into a single bitcode file, the only external functions are coming from library functions.
– John T.
I see that some of the system header-file definitions have the internal keyword.
For example,
define internal void @__cxx_global_var_init() section “__TEXT,__StaticInit,regular,pure_instructions” {
entry:
call void @_ZNSt8ios_base4InitC1Ev(%“class.std::ios_base::Init”* @_ZStL8__ioinit)
%0 = call i32 @__cxa_atexit(void (i8*)* bitcast (void (%“class.std::ios_base::Init”) @_ZNSt8ios_base4InitD1Ev to void (i8*)), i8 getelementptr
inbounds (%“class.std::ios_base::Init”* @_ZStL8__ioinit, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
ret void
}
I see that some of the system header-file definitions have the internal keyword.
For example,define internal void @__cxx_global_var_init() section “__TEXT,__StaticInit,regular,pure_instructions” {
entry:
call void @_ZNSt8ios_base4InitC1Ev(%“class.std::ios_base::Init”* @_ZStL8__ioinit)
%0 = call i32 @__cxa_atexit(void (i8*)* bitcast (void (%“class.std::ios_base::Init”) @_ZNSt8ios_base4InitD1Ev to void (i8*)), i8 getelementptr
inbounds (%“class.std::ios_base::Init”* @_ZStL8__ioinit, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
ret void
}
Indeed. Functions defined with the static keyword in C/C++ get internal LLVM linkage when compiled to LLVM bitcode. This makes the function name invisible to other functions in other compilation units that might be linked with this bitcode file later on.
Internal linkage, however, is not a sign that a function came from a header file. Programmers can write their own static functions within their own code.
– John T.