I read a book on reverse engineering, which claims that with C/C++, functions from the same source typically end up in the compiled binary next to each other, in the order they were written.
Is it really typically the case? (assuming any options to manually control it were disabled, but keeping "defaults")
What is the chance that a compiler/linker, or optimizations, would affect this? I'm not asking about any particular compiler, more like popular ones, let it be GCC and MSVC for example, and Windows / Linux as platforms.
Edit: not a duplicate of Why would gcc change the order of functions in a binary? , my question is a "general rule" kind, not specifically about GCC.
Linkers typically operate at the section level when arranging code and data in the binary. By default:
When you force the compiler to generate separate sections for every function or data, their placement in the binary can be influenced by:
GCC + LD (GNU binutils) can place functions is data in separate sections:
-ffunction-sections
: Places each function in its own .text.<function_name> section.-fdata-sections
: Places each global or static data variable in its own .data.<variable_name> or .bss.<variable_name> section.You can eliminate dead code on function level (as it has its own section) by passing --gc-sections
to the linker
Functions and data can be sorted in the executable by leveraging the -ffunction-sections
and -fdata-sections
options in conjunction with a custom linker script or linker options.
Example:
ld --sort-section=name -o sorted_binary main.o
You can sort section (and functions as they are placed in separate sections) by:
Wildcard Patterns:
*
or ?
to match section names.*(.text.*)
matches all sections starting with .text.Explicit Section Order:
Automatic Sorting:
ld --sort-section
command line optionMSVC is less flexible compared to GCC/Clang when it comes to automatically placing each function or variable in separate sections. However, similar behaviour can be achieved by manually assigning functions and variables to specific sections using #pragma
directives or __declspec(allocate)
. This process can be streamlined using macros, effectively automating the assignment while achieving the same result.
functions from the same source typically end up in the compiled binary next to each other, in the order they were written.
It would be best if you did not assume this.