"interrupt function contains function calls" gcc error - c

In my code I get this
"error: interrupt function contains function calls: foo"
when compiling with the toolchain: riscv32-unknown-elf-gcc (gcc version 5.2.0 (GCC))
but not with this toolchain riscv32-corev-elf-gcc (gcc version 11.0.0 20200813 (experimental)
Having function call in ISR could be bad but that is not the point, I can't get rid of legacy.
How could I disable this error?
in my code I have defined interrupt using:
__attribute__((interrupt))
could this be the cause? not supported attribute?
when I remove the attribute, the error disappears, so I'll need to have prologue/epilogue sequences in assembly I guess
but this is strange because it says it supports it:
https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html#RISC-V-Function-Attributes
could it exist any gcc flag that could disable this error?
note: hard to have a minimal reproducible example as there is no gcc riscv compiler < 8.0 on godbolt.com

using gcc version 5.2.0 (GCC),
you are not allowed to have the attribute keyword with the interrupt declaration, only with the interrupt definition.
BUT, that SHOULD not be used, because epilogue/prologue are not well generated, so interrupt won't work, you'll have to manually write a generic epilogue and prologue for all irqs.

Related

How to disable the warning about using deprecated gets in GCC?

I'm running a CTF and I am currently writing a problem that exploits C's gets function. I understand that the function is deprecated and dangerous and I would never use it in any other circumstance. Unfortunately, gcc compiles my code and when I run the binary when the gets function is hit, I get a friendly error message:
warning: this program uses gets(), which is unsafe.
This would normally be great, because it warns you that gets is unsafe, but unfortunately, in my CTF, I think that this error message makes the problem a bit too easy. Do you know how I would go about disabling this warning? Thanks!
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 11.0.3 (clang-1103.0.32.62)
Target: x86_64-apple-darwin19.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Note: I just realized that your question title seems to be misplaced - The warning you got is from macOS about executing a program which uses gets(). It has nothing to do with the compilation by using GCC.
:-/ Any way, I let my answer alive for reference.
Just as comment: I googled a bit about what you are looking for, but there seems to be no reliable way to disable this warning when executing the program. One suggested rebuilding /usr/lib/libSystem.B.dylib without any result or experience if it indeed works, but I personally think this a bit too extreme and even can be harmful. - I do not recommend this technique.
If you really want to create an exploit program, try to rebuild gets() by a costum-made function and name the function a bit different, like f.e. gets_c(). This should be a workaround to disable this warning from macOS.
Old answer (regarding GCC itself):
First of all, you seem to be using a C99 or C89/C90-compliant compiler or alternatively compile with std=c99 or std=c89/std=c90 option, because only compilers conform to standards preceding C11 warn about gets() being deprecated.
ISO/IEC removed the gets() function in C11. If you would compile with a C11 or newer standard-compliant compiler, you would get an error about the implicit declaration of gets() when using it in the code instead:
"error: implicit declaration of function 'gets'; did you mean 'fgets'? [-Werror=implicit-function-declaration]"
If you want to suppress the warning at compilation, use the -Wno-deprecated-declarations option at compiling to disable the diagnostic for deprecated declarations.
From the GCC online docs:
-Wno-deprecated-declarations
Do not warn about uses of functions, variables, and types marked as deprecated by using the deprecated attribute. (see Function Attributes, see Variable Attributes, see Type Attributes.)
Source: https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Warning-Options.html
If you want to embed the suppression of the warning in your code use the approach used in David´s deleted answer implementing a suppression for -Wno-deprecated-declarations by using #pragma:
char str[256];
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
gets(str);
#pragma GCC diagnostic pop

GCC on windows linux bash

I am using ubuntu through windows linux bash and it happens that I am trying to compile a file and I am getting this error:
"error: ‘for’ loop initial declarations are only allowed in C99 mode".
But actually I would like not to use C99 mode but use C11 instead. How can I set my compiler to use C11 mode by default without having to pass any flags?
My GCC version is 4.8.4 running at ubuntu 14.04.3.
Thanks.
You need to specify -std=c99 or -std=gnu99 or higher to allow initial declarations in for loops. Or, just declare the variable first and use it in the for loop later.
For c11 of course, -std=c11 is the way. I don't know of a way of setting this default and perhaps there is no way. But recent gcc compilers 5.x have c11 default.
Alternative to re-building GCC yourself (complicated and error prone), update GCC (newer GCCs may not be able to compile the kernel, The kernel-developers and the GCC-developers go not always, how shall I put it ... d'accord) and typing -std=c11 every time, you can set an alias. Put the following line at the end of your .bashrc
alias gcc11="gcc -std=c11"
Let the shell re-read it's config file by source ~/.bashrc (If I remember Ubuntu correctly) and try it out.
You can call the alias gcc, too, but that might break 3rd-party makefiles.

gcc canaries : undefined reference to __stack_chk_guard

I'm trying to enable gcc' s canaries' generation but I get an undefined reference to __stack_chk_guard.
From gcc's man about canaries :
-mstack-protector-guard=guard
Generate stack protection code using canary at guard. Supported locations are global for
global canary or tls for per-thread canary in the TLS block (the default). This option
has effect only when -fstack-protector or -fstack-protector-all is specified.
These -m switches are supported in addition to the above on x86-64 processors in 64-bit
environments.
I've done this test program :
#define VALUE 2048
int main()
{
char arr[VALUE];
int i;
for (i = 0; i < VALUE + 15; i++) // "i < VALUE + 15" is to test if canaries works but the code doesn't compile anymore with "i < 10"
arr[i] = '0';
return 0;
}
As said in gcc's man, my compilation line is :
gcc main.c -fstack-protector-all -mstack-protector-guard=global
But I get the following error :
/tmp/ccXxxxVd.o: In function `main':
main.c:(.text+0xe): undefined reference to `__stack_chk_guard'
main.c:(.text+0x51): undefined reference to `__stack_chk_guard'
collect2: error: ld returned 1 exit status
How can I remove this error ?
EDIT:
OS: ubuntu 14.10 utopic
architecture: x86-64
environments: 64-bit
It would appear that the -mstack-protector-guard option is only for backwards compatibility with how the stack protector worked in the past. In the past the canary was in a global variable. Later it was switched to TLS. It would appear that the operating system / libc you use either removed or never had support for the global variable canary, so only TLS works.
Don't touch the -mstack-protector-guard option and everything should work. The default should be fine when you use -fstack-protector-all.
Provide __stack_chk_guard with a random value in c file, avoid using regular values like all zero's or FF's because the stack can easily get these values during any memory operation. Wiki on providing magic number implementation. This __stack_chk_guard will be placed at the top and bottom of the stack, which will be checked during every stack access. Any change in the value implies a corrupted stack and returns with error providing the stack protection.
unsigned long __stack_chk_guard;
void __stack_chk_guard_setup(void)
{
__stack_chk_guard = 0xBAAAAAAD;//provide some magic numbers
}
void __stack_chk_fail(void)
{
/* Error message */
}// will be called when guard variable is corrupted
There are two ways to remove this error: 1. From the compiler option disable(comment out) the "stack guard".
Define __stack_chk_guard in you c file.
When you define __stack_chk_guard make sure you provide random value to it. For providing random value you need to pass as an argument to the random function.
For any further detail you can refer to the compiler manual.
For those that get this error in bare metal software development with a custom linker script, make sure to pass the option -nostdlib option:
gcc -nostdlib
since Ubuntu 16.04 for example enables the stack protection by default on the compiler. man gcc says:
NOTE: In Ubuntu 14.10 and later versions, -fstack-protector-strong is enabled by default for C, C++, ObjC, ObjC++, if none of -fno-stack-protector, -nostdlib, nor -ffreestanding are found.
-fno-stack-protector also solved it for me, but you should likely tell your poor compiler that you are doing baremetal stuff to prevent other such problems.
I'm guessing this is because the feature relies on symbols which are normally defined if a linker script is not given? But TODO I found no mention of those symbols by dumping the default linker script with:
aarch64-linux-gnu-gcc -Wl,-verbose main.c
so I'm not sure.
I grepped GCC 6.4.0 source code and it suggests that the symbol comes from libgcc2.c at gcc/doc/tm.texi:
The default version of this hook creates a variable called
#samp{__stack_chk_guard}, which is normally defined in #file{libgcc2.c}.

Compiling issue: undefined reference to pthread_cleanup_push_defer_np() and pthread_cleanup_pop_restore_np()

I am currently writing a C program with threads and I make use of pthread_cleanup_push_defer_np() and pthread_cleanup_pop_restore_np(). Provided that:
I have included pthread.h;
I am compiling with -pthread option;
I am on Ubuntu 14.04 and using gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1);
when compiling I get back a nasty undefined reference error to the above mentioned functions and I can't figure out why. I have tried to take a look into pthread.h and it seems those two functions are commented out, so I am wondering whether I need to enable them in some way or use some other kind of options. I've read the manual pages and google it up but I can't find a solution, so I would appreciate a little help. Here it is a snippet:
void *start_up(void *arg)
{
char *timestamp;
// ... code ...
timestamp = get_current_timestamp("humread");
pthread_cleanup_push_defer_np(free, timestamp);
// ... some other code
pthread_cleanup_pop_restore_np(1);
// ... more code ...
}
I compile with
gcc -pthread -o server *.c
The manual of pthread_cleanup_push_defer_np and pthread_cleanup_pop_restore_np say these two (non portable) functions are GNU extensions and are enabled
by defining _GNU_SOURCE:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
pthread_cleanup_push_defer_np(), pthread_cleanup_pop_defer_np():
_GNU_SOURCE
This results in linker error (as opposed to compile time error) because your compiler is pre-C99 (or you are compiling in pre-C99 mode) and assumes these functions return int by default.
The rule functions-return-int if no prototype is present has been removed since C99. Enabling more compiler switches can help you with better diagnostics.

How to get into C99 mode in Codeblocks10.05?

I recently realized that I am not even in C99 mode after receiving the compile error
'for' loop initial declarations are only allowed in C99 mode
I found some advice on how to get to C99 via a quick search which has told me to go to Projects -> Properties... But alas, it is greyed out and I am not sure that is even the correct way to fix it (probably not available because my file is not a project, it is a normal source file). I have also seen a lot of similar questions saying to enable C99 mode so I have looked inside the compiler flags menu, but I cannot see anything about C99. I have tried some other flags such as In C Mode, support all ISO C90 programs..., but after I set this flag, I got more errors than I had before which seem to appear whenever the compiler finds comments inside main().
Note: Please don't just say to initialize the counter outside the for loop.
Update: While trying to compile outside of codeblocks with gcc, I tried
gcc -O2 -std=C99 filename.c, but received an error:
unrecognized command line option "-std=C99"
I use 64-bit Windows 7, CodeBlocks10.05, and GNU gcc.
For future reference, type in the flag -std=c99 in settings->compiler->other options which is not case-sensitive, however when compiling in a terminal the flag is case-sensitive. Thanks chris!

Resources