Calling DLL functions involves the linker generating a stub, unless the function was declared __declspec(dllimport)
in which case the stub can be bypassed in favor of an indirect call straight to the import table which is slightly more efficient, e.g.
__declspec(dllimport) void ExitProcess(int);
ExitProcess(0);
generates
call qword ptr [__imp_ExitProcess]
where __imp_ExitProcess
resolves to a location in the import table in the executable.
I'm trying to figure out exactly how __imp_ExitProcess
is resolved. It occurs as a symbol in kernel32.lib to be sure, but that symbol has storage class IMAGE_SYM_CLASS_EXTERNAL
, section number zero and value zero, which amounts to just saying 'this will be defined somewhere else' without actually ever defining it.
Does the __imp_
prefix have special meaning, i.e. does the linker notice that prefix and take it as an instruction to resolve the symbol to the import table entry for the DLL function whose name has that prefix removed? Or is something else going on?
The linker adds to your program a function like:
void (*__imp_ExitProcess)(int) = ...;
void ExitProcess(int n)
{
return (*__imp_ExitProcess)(n);
}
where __imp_ExitProcess points to the "real" ExitProcess in KERNEL32.DLL.
Declaring this in your code:
__declspec(dllimport) void ExitProcess(int);
is equivalent to:
extern void (*__imp_ExitProcess)(int);
#define ExitProcess (*__imp_ExitProcess)
except that __declspec(dllimport) is handled by the compiler, not by the preprocessor.
Just came up with a test that gives a data point. The following program:
__declspec(dllimport) void ExitProcess(int);
void __imp_ExitProcess(int x) {
}
int main() {
ExitProcess(0);
}
crashes when compiled with the Microsoft compiler and run (but runs okay if the empty function is renamed to anything else); thus, it seems the linker behaves as though the __imp_
name is special, at least in the sense that a linker that behaves that way will generate a correct executable in all cases where the Microsoft linker does so, unless I'm missing something.
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