重新排列对齐对象的最小空间使用顺序

问题描述:

我有一个数据结构需要4-KiB对齐。我可以使用__attribute__ ((aligned (4096)))来强制执行此操作。重新排列对齐对象的最小空间使用顺序

问题是,这种对齐要求会导致内存浪费。这是链接器如何放置符号(pg_dir是对齐的数据结构):

00011000 <cursor_loc>: 
00012000 <pg_dir>: 
00013000 <idt>: 

cursor_loc的大小只是四个字节。这将是更好的:

00011000 <pg_dir>: 
00012000 <cursor_loc>: 
00012008 <idt>: 

idt必须是我们在8字节对齐。)


您可以通过使用多个文件这样的重现:

test1.c

char aligned[4096] __attribute__ ((aligned (4096))); 
int i; 

test2.c

0000000000602004 <j>: 
     ... 

0000000000603000 <aligned>: 
     ... 

0000000000604000 <i>: 

我怎样才能移动GNU LD重新排列为最小的空间浪费符号:

int j; 

int main(void) { } 

然后用

gcc test1.c test2.c 

objdump -D a.out打印此建呢?我真的很想知道为什么它不能自动完成。

有一些成语要求对象按照命令行中指定的顺序排列(这就是为什么你的结果有点奇怪,可能是由于常见的符号),并且对象内定义是不重新排序。要解决这一点,你需要的是这样的:

gcc -fno-common -fdata-sections -Wl,--sort-section=alignment test1.c test2.c 

-fno-common禁用常见的符号,-fdata-sections允许链接器从同一文件重新排列的符号,并-Wl,--sort-section=alignment终于能够通过对准排序。

+0

这工作整齐,谢谢。我只是想知道为什么当我objdump时它们仍然出现在'.bss'中,尽管我使用了'-fno-common'和'-fdata-sections'。实际上,我需要它们在'.bss'中,这只是我不明白为什么这些开关不会更改它们所属的部分。 – Downvoter

+0

是的,我对'.bss'感到困惑。如果你指定了一个初始化方法,你只能从'.bss'中得到零初始化的符号,如果它仍然为零,编译'-fno-zero-initialized-in-bss'(来禁止'.bss'优化) 。很高兴你需要'.bss'符号。 –

+0

不会“-Wl, - sort-common”也起作用吗? – Hasturkun