GCC no reorder stack variables - c

Hi i'm trying to compile a C code without reordering my variables in stack but can't do it.
I've tryed using:
__attribute__((no_reorder))
But doesn't work, also tryed to compile with the flag:
-fno-toplevel-reorder
But didn't work... so i'm stuck.
Actual code:
uint8_t __attribute__((no_reorder)) first_buf[64];
uint8_t second_buf[32];
This is my compiler version:
gcc (Debian 7.2.0-19) 7.2.0
Thank you for reading!

from the gcc documentation here:
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
no_reorder
Do not reorder functions or variables marked no_reorder against each other or top level assembler statements the executable. The
actual order in the program will depend on the linker command line.
Static variables marked like this are also not removed. This has a
similar effect as the -fno-toplevel-reorder option, but only applies
to the marked symbols.
(emphasis mine)
So it would appear that you would need to apply the attribute to the variables the respective order of which you want preserved. Applying the attribute to only a single variable will only preserve the order of that variable with itsef, which has no effect.

-fno-stack-protector will do it. It will cancel stack canary and reordering of buffer on stack.
add that flag when you compile. i.e.
gcc myprogram.c -fno-stack-protector

Related

Why would gcc change the order of functions in a binary?

Many questions about forcing the order of functions in a binary to match the order of the source file
For example, this post, that post and others
I can't understand why would gcc want to change their order in the first place?
What could be gained from that?
Moreover, why is toplevel-reorder default value is true?
GCC can change the order of functions, because the C standard (e.g. n1570 or newer) allows to do that.
There is no obligation for GCC to compile a C function into a single function in the sense of the ELF format. See elf(5) on Linux
In practice (with optimizations enabled: try compiling foo.c with gcc -Wall -fverbose-asm -O3 foo.c then look into the emitted foo.s assembler file), the GCC compiler is building intermediate representations like GIMPLE. A big lot of optimizations are transforming GIMPLE to better GIMPLE.
Once the GIMPLE representation is "good enough", the compiler is transforming it to RTL
On Linux systems, you could use dladdr(3) to find the nearest ELF function to a given address. You can also use backtrace(3) to inspect your call stack at runtime.
GCC can even remove functions entirely, in particular static functions whose calls would be inline expanded (even without any inline keyword).
I tend to believe that if you compile and link your entire program with gcc -O3 -flto -fwhole-program some non static but unused functions can be removed too....
And you can always write your own GCC plugin to change the order of functions.
If you want to guess how GCC works: download and study its source code (since it is free software) and compile it on your machine, invoke it with GCC developer options, ask questions on GCC mailing lists...
See also the bismon static source code analyzer (some work in progress which could interest you), and the DECODER project. You can contact me by email about both. You could also contribute to RefPerSys and use it to generate GCC plugins (in C++ form).
What could be gained from that?
Optimization. If the compiler thinks some code is like to be used a lot it may put that code in a different region than code which is not expected to execute often (or is an error path, where performance is not as important). And code which is likely to execute after or temporally near some other code should be placed nearby, so it is more likely to be in cache when needed.
__attribute__((hot)) and __attribute__((cold)) exist for some of the same reasons.
why is toplevel-reorder default value is true?
Because 99% of developers are not bothered by this default, and it makes programs faster. The 1% of developers who need to care about ordering use the attributes, profile-guided optimization or other features which are likely to conflict with no-toplevel-reorder anyway.

How to find dead code in C language Project with gcc compiler

I need to find the dead code(functions not used) in my "C" language Project(having multiple C files) with gcc compiler. Please let me know the gcc options to find the dead code. Your help will be greatly appreciated.
For unused static functions, see Ed King's answer.
For global functions you could try this: Build the project twice, once as usual and once with -ffunction-sections -Wl,--gc-sections (the first is a compiler flag, the second a linker flag). Then you can run nm on the generated binaries to obtain a list of symbols for both runs. The linker will have removed unused functions in the second run, so that is your list of dead functions.
This assumes a common target like ELF, the binutils linker, and that the final binaries are not stripped of their symbol table.
You can use the GCC compiler option -Wunused-function to warn you of unused static functions. I'm not sure how you would detect unused 'public' functions though, save for looking at the map file for functions that haven't been linked.

Is memory in same section always allocated contiguously?

char a_1[512];
int some_variable;
char a_2[512];
main()
{
...
}
Here in the above program, I have declared some variables, all in bss section of the code. Considering that I have kept in mind the alignment issues, can I be sure that the memory allocated for those 3 variables will always be contiguous?
Considering that I have kept in mind the alignment issues, can I be sure that the memory allocated for those 3 variables will always be contiguous?
Certainly not. Read the C11 standard n1570, and you won't find any guarantee about that.
Different compilers are likely to order variables differently, in particular when they are optimizing. Some variables might even stay in a register, and not even have any memory location. In practice some compilers are following the order of the source, others are using some different order.
And you practically could customize (perhaps with some pain) your GCC or your Clang compiler to change that order. And this does happen in practice. For example, recent versions of the GCC kernel might be configured with some GCC plugin which could reorder variables. With GCC or Clang you might also add some variable attribute to alter that order.
BTW, if you need some specific order, you could pack the fields in some struct e.g. code:
struct {
char a_1[512];
int some_variable;
char a_2[512];
} my_struct;
#define a_1 my_struct.a_1
#define some_variable my_struct.some_variable
#define a_2 my_struct.a_2
BTW, some old versions of GCC had an optional optimization pass which reordered (in some cases) fields in struct-s (but recent GCC removed that optimization pass).
In a comment (which should go into your question) you mention hunting some bug. Consider using the gdb debugger and its watchpoints (and/or valgrind). Don't forget to enable all warnings and debug info when compiling (so gcc -Wall -Wextra -g with GCC). Maybe you want also instrumentation options like -fsanitize=address etc...
Beware of undefined behavior.

making global variables "hidden" and "aliased"

Is there any way to make a global variable both "hidden" and "aliased"? It would seem the following would be sufficient:
int __voo __attribute__((visibility("hidden")));
extern int voo __attribute__((weak,alias("__voo")));
But this results in:
$ gcc -c alias.c
/tmp/cczCek0H.s: Assembler messages:
/tmp/cczCek0H.s:5: Error: `voo' can't be equated to common symbol '__voo'
Removing "weak" has no effect.
However, adding "static" to the variable declaration allows the link to succeed, but is not the desired effect, as static limits the variable visibility scope to the compilation unit, not the broader scope of the linked object.
Intel System Studio 2019, GCC 4.8.5 and GCC 5.3.1 all show the same behavior.
I had a similar issue. I wasn't even trying to use hidden, and I still got the "can't be equated to common symbol" error. The fix was to initialize the int __voo to some value (even 0). Perhaps it was a BSS vs Data thing, or just a bug.
I got it to work by also supplying -fno-common to the compiler invocation. This might make some not strictly correct C code stop working though, so read what -fno-common does before using it.
It also works if I compile with clang.

Function specific optimization in GCC 4.4.3

In reference to my earlier question here, I found out a possilbe bug in GCC 4.4.3 when it did not support following pragmas in the source code for optimization (although it says 4.4.x onwards it does!)
#pragma GCC optimize ("O3")
__attribute__((optimize("O3")))
Tried both above options but both gave compile time errors in the compiler itself(See the error message snapshot posted in the link mentioned above)
Now are there any further options for me to enable different optimization levels for different functions in my C code?
From the online docs:
Numbers are assumed to be an optimization level. Strings that begin with O are assumed to be an optimization option, while other options are assumed to be used with a -f prefix.
So, if you want the equivalent of the command line -O3 you should probably use the just the number 3 instead of "O3".
I agree that this is a bug and should not generate an ICE, consider reporting it along with a small test case to the GCC guys.
Now are there any further options for me to enable different optimization levels for different functions
in my C code?
Your remaining option is to place the functions in their own .c file and compile that .c file with the optimization flag you want.

Resources