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?
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.
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.
Related
I know that C++11-style attributes support vendor-specific attributes that are prefixed by a namespace. Both GCC and Clang support various attributes with the prefix either gnu:: (gcc and clang) or clang:: (clang only) which correspond to an equivalent __attribute__((...)) syntax.
The documentation for MSVC attributes shows that it supports the standard attributes, as well as a gsl:: attribute -- but it makes no mention of backwards-compatibility for __declspec attributes.
I'd expect something like __declspec(noinline) to have an attribute representation of [[msvc::noinline]] -- but I can't seem to find any documentation on this.
So my question is, does MSVC support __declspec as C++11-style attributes at all?
If it doesn't, would anyone happen to know they don't?
The original rationale for C++'s attributes was to abstract the various compiler-specific __attribute__ and __declspec features, so it would be weird if it's still not supported 9 years after standardization.
There is no [[msvc::noinline]] or other __declspec equivalents as of VC++ 2019.
From the official MSVC documentation for Attributes in C++:
In Visual C++, you can use the [[deprecated]] attribute instead of using declspec(deprecated) and the attribute will be recognized by any conforming compiler. For all other declspec parameters such as dllimport and dllexport, there is as yet no attribute equivalent so you must continue to use declspec syntax.
[ EDIT ] Information on why [[attributes]] are not more widely used in VC++, perhaps replacing __declspec entirely, is surprisingly scarce. The closest to an authoritative source that I found were these comments in the reddit thread C++ attribute specifier sequence, MSVC and me:
spongo2 - MSVC Dev Manager
We just had a rousing team room discussion on this topic. We definitely see the use case here and it's interesting but we're wondering if the fact that the number of places one can put attributes is large and growing would lead to surprising behavior.
STL - MSVC STL Dev
I would use [[msvc::kitty]] instead of __declspec(kitty) in the STL, in order to make our sources more palatable to other front-ends. I already switched to using [[noreturn]] instead of __declspec(noreturn) because that one's Standard.
My reading is that what's holding back a wider adoption is the concern about scopes of attributes vs. __declspec, and backwards compatibility in general.
According to Attributes in C++ the only __declspec() with an attribute replacement is [[deprecated]], for all other __declspec() modifiers you must continue to use __declspec.
I'm developing an online judge system for programming contests. Since C/C++ inline assembly is not allowed in certain programming contests, I would like to add the same restriction to my system.
I would like to let GCC produce an error when compiling a C/C++ program containing inline assembly, so that any program containing inline assembly will be rejected. Is there a way to achieve that?
Note: disabling inline assembly is just for obeying the rules, not for security concerns.
Is there a way to disable inline assembler in GCC?
Yes there are a couple of methods; none useful for security, only guard-rails that could be worked around intentionally, but will stop people from accidentally using asm in places they didn't realize they shouldn't.
Turn off the asm keyword in the compiler (C only)
To do it in compilation phase, use the parameter -fno-asm. However, keep in mind that this will only affect asm for C, not C++. And not __asm__ or __asm for either language.
Documentation:
-fno-asm
Do not recognize "asm", "inline" or "typeof" as a keyword, so that code can use these words as identifiers. You can use the keywords "__asm__", "__inline__" and "__typeof__" instead. -ansi implies -fno-asm.
In C++ , this switch only affects the "typeof" keyword, since "asm" and "inline" are standard keywords. You may want to use the -fno-gnu-keywords flag instead, which has the same effect. In C99 mode (-std=c99 or -std=gnu99), this switch only affects the "asm" and "typeof" keywords, since "inline" is a standard keyword in ISO C99.
Define the keyword as a macro
You can use the parameters -Dasm=error -D__asm__=error -D__asm=error
Note that this construction is generic. What it does is to create macros. It works pretty much like a #define. The documentation says:
-D name=definition
The contents of definition are tokenized and processed as if they appeared during translation phase three in a #define directive. In particular, the definition will be truncated by embedded newline characters.
...
So what it does is simply to change occurrences of asm, __asm, or __asm__ to error. This is done in the preprocessor phase. You don't have to use error. Just pick anything that will not compile.
Use a macro that fires during compilation
A way to solve it in compilation phase by using a macro, as suggested in comments by zwol, you can use -D'asm(...)=_Static_assert(0,"inline assembly not allowed")'. This will also solve the problem if there exist an identifier called error.
Note: This method requires -std=c11 or higher.
Using grep before using gcc
Yet another way that may be the solution to your problem is to just do a grep in the root of the source tree before compiling:
grep -nr "asm"
This will also catch __asm__ but it may give false positives, for instance is you have a string literal, identifier or comment containing the substring "asm". But in your case you could solve this problem by also forbidding any occurrence of that string anywhere in the source code. Just change the rules.
Possible unexpected problems
Note that disabling assembly can cause other problems. For instance, I could not use stdio.h with this option. It is common that system headers contains inline assembly code.
A way to cheat above methods
Aside from the trivial #undef __asm__, it is possible to execute strings as machine code. See this answer for an example: https://stackoverflow.com/a/18477070/6699433
A piece of the code from the link above:
/* our machine code */
char code[] = {0x55,0x48,0x89,0xe5,0x89,0x7d,0xfc,0x48,
0x89,0x75,0xf0,0xb8,0x2a,0x00,0x00,0x00,0xc9,0xc3,0x00};
/* copy code to executable buffer */
void *buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON,-1,0);
memcpy (buf, code, sizeof(code));
/* run code */
int i = ((int (*) (void))buf)();
The code above is only intended to give a quick idea of how to trick the rules OP has stated. It is not intended to be a good example of how to actually perform it in reality. Furthermore, the code is not mine. It is just a short code quote from the link I supplied. If you have ideas about how to improve it, then please comment on 4pie0:s original post instead.
Could C++ standards gurus please enlighten me:
Since which C++ standard version has this statement failed because (v) seems to be equivalent to (*&v)?
I.e. for example the code:
#define DEC(V) ( ((V)>0)? ((V)-=1) : 0 )
...{...
register int v=1;
int r = DEC(v) ;
...}...
This now produces warnings under -std=c++17 like:
cannot take address of register variable
left hand side of operand must be lvalue
Many C macros enclose ALL macro parameters in parentheses, of which the above is meant only to be a representative example.
The actual macros that produce warnings are for instance
the RTA_* macros in /usr/include/linux/rtnetlink.h.
Short of not using/redefining these macros in C++, is there any workaround?
If you look at the revision summary of the latest C++1z draft, you'd see this in [diff.cpp14.dcl.dcl]
[dcl.stc]
Change: Removal of register storage-class-specifier.
Rationale: Enable repurposing of deprecated keyword in future
revisions of this International Standard.
Effect on original feature: A valid C++ 2014 declaration utilizing the register
storage-class-specifier is ill-formed in this International Standard.
The specifier can simply be removed to retain the original meaning.
The warning may be due to that.
register is no longer a storage class specifier, you should remove it. Compilers may not be issuing the right error or warnings but your code should not have register to begin with
The following is a quote from the standard informing people about what they should do with regards to register in their code (relevant part emphasized), you probably have an old version of that file
C.1.6 Clause 10: declarations [diff.dcl]
Change: In C++, register is not a storage class specifier.
Rationale: The storage class specifier had no effect in C++.
Effect on original feature: Deletion of semantically well-defined feature.
Difficulty of converting: Syntactic transformation.
How widely used: Common.
Your worry is unwarranted since the file in question does not actually contain the register keyword:
grep "register" /usr/include/linux/rtnetlink.h
outputs nothing. Either way, you shouldn't be receiving the warning since:
System headers don't emit warnings by default, at least in GCC
It isn't wise to try to compile a file that belongs to a systems project like the linux kernel in C++ mode, as there may be subtle and nasty breaking changes
Just include the file normally or link the C code to your C++ binary. Report a bug if you really are getting a warning that should normally be suppressed to your compiler vendor.
The following example compiles (VS2010 C++ compiler issues a warning C4353 though) and expression (*) evaluates to 0:
#include <iostream>
#include <string>
int main()
{
0(1, "test"); // (*) - any number and type of arguments allowed
int n = 0(1, "test"); // 0
std::string str(0(1, "test")); // Debug assertion fails - 0 pointer passed
}
Is using 0 as a function name allowed/regulated by C++ standard or its resolution is compiler-specific? I was looking in the N3242 draft but could not find anything related to this. Microsoft compiler obviously resolves such construct (or one with __noop) as an integer with value 0.
warning C4353:
warning C4353: nonstandard extension used: constant 0 as function
expression. Use __noop function intrinsic instead
A function name is an identifier and an identifier needs to start with a non-digit (§2.11):
identifier:
identifier-nondigit
identifier identifier-nondigit
identifier digit
I don't know the answer, but I believe we can find it by a little googling...
Looking at the MSDN, I found two links:
C4353 : http://msdn.microsoft.com/en-us/library/2a68558f.aspx
__noop : http://msdn.microsoft.com/en-us/library/s6btaxcs.aspx
The second link explains the __noop
The __noop intrinsic specifies that a function should be ignored and the argument list be parsed but no code be generated for the arguments. It is intended for use in global debug functions that take a variable number of arguments.
Th example shows the __noop can be very interesting indeed for debug code:
#if DEBUG
#define PRINT printf_s
#else
#define PRINT __noop
#endif
int main() { PRINT("\nhello\n"); }
Another comment on the same page gives an historical hint on the 0 function:
The compiler converts the __noop intrinsic to 0 at compile time.
I guess that, once upon a time, this extension was called 0, not __noop, and that later, Microsoft created the __noop keyword because it was easier to search for, more readable, less "strange" than this 0 thing, and clearly marked as an extension (because of the two leading underscores, like MSVC's __declspec or gcc's __attribute__).
Conclusion: What about 0?
This is an extension (as per the warning message)
This is an historical, deprecated extension
Its use is deprecated in favor of __noop
It was deprecated at least at the VC++2003 time (if not before)
With GCC, I can specify __attribute__((format(printf, 1, 2))) , telling the compiler that this function takes vararg parameters that are printf format specifiers.
This is very helpful in the cases where I wrap e.g. the vsprintf function family. I can have
extern void log_error(const char *format, ...) __attribute__((format(printf, 1, 2)));
And whenever I call this function, gcc will check that the types and number of arguments conform to the given format specifiers as it would for printf, and issue a warning if not.
Does the Microsoft C/C++ compiler have anything similar ?
Using SAL Annotations you can use _Printf_format_string_ (as of VS2k8 or VS2k10) or __format_string (for VS2k5):
#undef FORMAT_STRING
#if _MSC_VER >= 1400
# include <sal.h>
# if _MSC_VER > 1400
# define FORMAT_STRING(p) _Printf_format_string_ p
# else
# define FORMAT_STRING(p) __format_string p
# endif /* FORMAT_STRING */
#else
# define FORMAT_STRING(p) p
#endif /* _MSC_VER */
/* use /analyze or _USE_ATTRIBUTES_FOR_SAL for checking */
extern void log_error(FORMAT_STRING(const char* format), ...);
As previously mentioned by #RustyX printf format checking is now supported by default as of VC2015. That is without a /analyze static analysis pass. Regrettably there is not yet a mechanism for marking user-defined wrapper functions.
This suggest the obvious workaround of calling printf. That is defining a macro which invokes both the user-defined function as well as the printf itself. The latter on a dead path to be optimized out.
This has the added benefit of achieving some level of portability to other compilers.
int printf_wrapper_(const char *format, ...);
#define printf_wrapper(...) \
(printf || printf(__VA_ARGS__), printf_wrapper_(__VA_ARGS__))
The drawback is that VC2015 performs some rudimentary dead-code elimination prior to the format check, testing only the remaining live code.
Thus sizeof or constant conditional expressions will fail. As a rule of thumb if a debug build emits run-time code then you will get the warning, though later passes in release builds may still kill the call.
Alas this makes it something of a moving target liable to change in future compiler versions. Albeit a relatively benign one.
While GCC checks format specifiers when -Wformat is enabled, VC++ has no such checking, even for standard functions so there is no equivalent to this __attribute__ because there is no equivalent to -Wformat.
I think Microsoft's emphasis on C++ (evidenced by maintaining ISO compliance for C++ while only supporting C89) may be in part the reason why VC++ does not have format specifier checking; in C++ using <iostream> format specifiers are unnecessary.
There is an interesting article on the subject on Code Project:
"Using C++ Templates for Startup Validation"
by Alexander Gorobets
http://www.codeproject.com/KB/cpp/ValidateprintfFunction.aspx
I've modified it so that I have a macro PRINTF_VALIDATE(format, ...) that logs all format errors at program statup (there's no need to actually execute the code). It produces something like this:
test.cpp(147) : error : 'printf' format character 'f' at position 1 does not match parameter type INT
test.cpp(147) : error : 'printf' too many arguments (3 instead of 2)
One can use it for example like this:
#define LOG(fmt, ...) do { PRINTF_VALIDATE(fmt, __VA_ARGS__); WriteLog(fmt, __VA_ARGS__); } while(0)
This is not as useful as compiler support, but it works on Visual Studio 2005...
Workaround for MSVS, GCC and clang:
"If you’re using a macro to call your printf-like functions, you can use a helper-macro to get compile time format checks like this:
#define CHECK_FORMAT(...) \
do { \
char const dummy = sizeof(printf(__VA_ARGS__)); \
(void)dummy; \
} while (false)
#define MY_FMT(...) \
do { \
CHECK_FORMAT(__VA_ARGS__); \
MyFormatFunc(__FILE__, __LINE__, __VA_ARGS__); \
} while (false)
https://godbolt.org/z/38PaG5fx6
The printf call in the sizeof isn’t evaluated so it doesn’t generate code, but current versions of MSVC, GCC and Clang will still do the format-string check so you get the warning. The local dummy variable is also optimized away with -O2."
Source