Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rearranging Order of Aligned Objects For Minimal Space Usage

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.

like image 716
cadaniluk Avatar asked Jul 16 '17 12:07

cadaniluk


1 Answers

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.

like image 193
Florian Weimer Avatar answered Sep 25 '22 20:09

Florian Weimer