1
  • 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?
OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87

2 Answers2

4

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).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
2

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.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Just to make sure I understood: re-ordering of binary code is associated with "breaking" the concept of C functions translated independently, and "orthogonally" from other functions – OrenIshShalom Feb 14 '21 at 09:19
  • @OrenIshShalom: I don't understand what you're asking now. – John Zwinck Feb 14 '21 at 09:20
  • 1
    No it's not breaking with any concept because there isn't any. One shall not rely on the order of functions in memory. – rustyx Feb 14 '21 at 09:22
  • sorry, rephrased: If some "hot" code from `foo` is moved to its own section, and `foo` appears **before** `bar` in the source file, then the "hot-foo" part can be **after** `bar` – OrenIshShalom Feb 14 '21 at 09:27
  • @OrenIshShalom: Yes, because there are no guarantees about ordering by default. – John Zwinck Feb 15 '21 at 01:10