问题
I can jmp to an address using Visual Studio 2012.. When it comes to gcc/mingw, I cannot tell if my jump is correct.
How can I jump to an address in gcc?
I tried:
__declspec(naked) void DXHook_D3DPERF_BeginEvent()
{
#ifdef _MSC_VER //If using visual studio..
__asm{jmp[Addr]} //Jump to: Address stored in Addr.
#else //else using gcc..
__asm("jmp *%0"
: /*No Outputs*/
: "r" (Addr)
: "%eax");
#endif
}
Is this correct? Also, is there a way to get gcc to stop bothering me about:
warning: 'naked' attribute directive ignored.
Why does it ignore my naked attribute?
回答1:
TL;DR In GCC, this is only available on: ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports
It is NOT available on x86.
Workaround (proposed by Brendon in the comments).
Full answer
(The rest of this answer assumes you are using a supported target)
That is because you are using the Windows attribute syntax, __declspec with GCC.
Quote from the MSDN reference on __declspec:
The extended attribute syntax simplifies and standardizes Microsoft-specific extensions to the C and C++ languages.
You should use the GCC function attribute syntax instead or in parallel.
Please also note the following quote from this GCC article:
Note: The semantics are not the same between Windows and this GCC feature - for example, __declspec(dllexport) void (*foo)(void) and void (__declspec(dllexport) *foo)(void) mean quite different things whereas this generates a warning about not being able to apply attributes to non-types on GCC.
So there could also be an issue with the way you are using the __declspec
syntax in GCC (if it even supports it).
You should also note that the only __declspec
attribute that GCC states it supports is the __declspec(dllexport)
(as stated in the already mentioned GCC attribute syntax link).
So let's look for a generic solution to your problem but first we will need to read about the actual GCC attribute syntax and find the following:
An attribute specifier list may appear immediately before a declarator (other than the first) in a comma-separated list of declarators in a declaration of more than one identifier using a single list of specifiers and qualifiers. Such attribute specifiers apply only to the identifier before whose declarator they appear. For example, in
__attribute__((noreturn)) void d0 (void), __attribute__((format(printf, 1, 2))) d1 (const char *, ...), d2 (void)
the noreturn attribute applies to all the functions declared; the format attribute only applies to d1.
So the solution to your problem would be something like the following:
#ifdef __GNUC__
#define ATTRIBUTE_NAKED __attribute__((naked))
#else
#define ATTRIBUTE_NAKED __declspec(naked)
#endif
ATTRIBUTE_NAKED void DXHook_D3DPERF_BeginEvent()
{
#ifdef _MSC_VER //If using visual studio..
__asm{jmp[Addr]} //Jump to: Address stored in Addr.
#else //else using gcc..
__asm("jmp *%0"
: /*No Outputs*/
: "r" (Addr)
: "%eax");
#endif
}
Edit:
It is important to note that this attribute is platform specific. And I quote:
naked
This attribute is available on the ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports. It allows the compiler to construct the requisite function declaration, while allowing the body of the function to be assembly code. The specified function will not have prologue/epilogue sequences generated by the compiler. Only basic asm statements can safely be included in naked functions (see Basic Asm). While using extended asm or a mixture of basic asm and C code may appear to work, they cannot be depended upon to work reliably and are not supported.
Quoted from the GCC documentation on function attributes.
Side note
Possible further reading on clang attributes could help (mostly compatible with GCC) but these comments seem to suggest a desire to match GCC behavior.
回答2:
To do the equivalent of the Visual C++ code, implement it entirely in assembly either in a separate file or in a top level (not in a function) asm
statement.
来源:https://stackoverflow.com/questions/19577809/gcc-inlined-assembly-jmp-address-naked-functions