Rearranging Order of Aligned Objects For Minimal Space Usage
Asked Answered
G

1

6

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.

Gerdi answered 16/7, 2017 at 12:39 Comment(0)
B
3

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.

Bewley answered 17/7, 2017 at 7:0 Comment(3)
That works neatly, thanks. I just wonder why the symbols still appear to be in .bss when I objdump them, even though I use -fno-common and -fdata-sections. I need them to be in .bss for my purposes actually, it's just I don't understand why those switches don't change the section they belong to.Gerdi
Yes, I was confused about .bss. You can only get zero-initialized symbols out of .bss if you specify an initializer, and if that is still zero, compile -fno-zero-initialized-in-bss (to inhibit the .bss optimization). Glad you need .bss symbols anyway.Bewley
I tried -Wl,--sort-common, but couldn't get the desired effect.Bewley

© 2022 - 2024 — McMap. All rights reserved.