Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a static function from global inline assembly

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"
);
like image 215
Paul Avatar asked Nov 30 '19 13:11

Paul


People also ask

Can static function be inline?

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.

Are global functions static?

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.

Is inline assembly useful?

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.

Is Main static in C++?

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.


1 Answers

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.

like image 180
user3840170 Avatar answered Oct 11 '22 05:10

user3840170