I'm trying to define a function without any prologues/epilogues, a "landing address" so it can call an inner function which is properly managed by the compiler (useful for a caller-cleanup environment).
I found I can create a global label using inline assembly but I am having trouble calling another function within the same file. When I compile the code as is listed here I'm getting a warning:
WARNING: "handle_vmexit" [/Code/hyper/kernel/hyper.ko] undefined!
When I remove the static modifier, there are no issues.
So my question is, why is the inline assembly unable to link with handle_vmexit when it's static and how can I make it call a static handle_vmexit.
Here's the relevant code:
static void handle_vmexit(void){
...
}
__asm__(".handle_vmexit: \n\t"
"call handle_vmexit"
);
Any function, with the exception of main , can be declared or defined as inline with the inline function specifier. Static local variables are not allowed to be defined within the body of an inline function. C++ functions implemented inside of a class declaration are automatically defined inline.
In C, functions are global by default. The “static” keyword before a function name makes it static. For example, below function fun() is static. Unlike global functions in C, access to static functions is restricted to the file where they are declared.
Inline Assembly is useful for in-place optimizations, and access to CPU features not exposed by any libraries or the operating system. For example, some applications need strict tracking of timing.
static for functions has the exact same impact as denoting a global variable as static ... the static function IS ONLY VISIBLE IN THE CURRENT FILE ... Thus main can NEVER be static, because it would not be able to serve as the primary entry point for the program.
When a C function is declared static
, it is not visible to other translation units, so the C compiler assumes it can see its every use and make optimisation decisions based on that assumption. If the function is unused, the compiler may fail to emit code for it entirely; if it is used only once, it may be inlined into its only caller and not have its symbol emitted separately (GCC option -finline-functions-called-once
), and so on. The compiler may even decide to inline all calls, even if you don't use the inline
keyword yourself (option -finline-functions
).*
However, GCC cannot detect usages within inline assembly; assembly code is completely opaque to GCC. To force the compiler to separately emit code for this function anyway, use __attribute__((used))
; the attribute was added specifically for this purpose. The manual describes the attribute as follows:
used
- This attribute, attached to a function, means that code must be emitted for the function even if it appears that the function is not referenced. This is useful, for example, when the function is referenced only in inline assembly.
When applied to a member function of a C++ class template, the attribute also means that the function is instantiated if the class itself is instantiated.
* Strictly speaking, even if the code for the function is emitted separately, the compiler is free not to declare the usual named symbol in the generated assembly file at all, and instead refer to the function by some opaque, artificially generated identifier, like it does with labels. But I think it improbable that GCC will ever exploit this freedom, especially if the solution given here is applied.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With