I have a data structure that needs to be 4-KiB aligned. I can enforce this using __attribute__ ((aligned (4096))).
The problem is that this alignment requirement causes memory to be wasted. This is how the linker places the symbols (pg_dir is the aligned data structure):
00011000 <cursor_loc>:
00012000 <pg_dir>:
00013000 <idt>:
cursor_loc is just four bytes in size. This would be better:
00011000 <pg_dir>:
00012000 <cursor_loc>:
00012008 <idt>:
(idt must be 8-byte aligned here.)
You can reproduce it by using multiple files like this:
test1.c:
char aligned[4096] __attribute__ ((aligned (4096)));
int i;
test2.c:
int j;
int main(void) { }
Then build it with
gcc test1.c test2.c
and objdump -D a.out prints this:
0000000000602004 <j>:
...
0000000000603000 <aligned>:
...
0000000000604000 <i>:
How can I move GNU ld to rearrange symbols for minimal space waste? I really wonder why it isn't done automatically.
There are some idioms which require that objects are arranged in the order objects are specified on the command line (which is why your results are a bit odd, maybe it's due to common symbols), and that intra-object definitions are not reordered. To work around that, you need something like this:
gcc -fno-common -fdata-sections -Wl,--sort-section=alignment test1.c test2.c
-fno-common disables common symbols, -fdata-sections allows the linker to reorder symbols from the same file, and -Wl,--sort-section=alignment finally enables sorting by alignment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With