Reputation: 135
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"
);
Upvotes: 8
Views: 1699
Reputation: 27222
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.
Upvotes: 9