首页 > 解决方案 > LD:链接描述文件中的 ALIGN 与 SUBALIGN

问题描述

它们有何不同?

我读到 SUBALIGN() 以某种方式强制进行某种对齐。还有其他区别吗?

什么时候应该使用 ALIGN(),什么时候应该使用 SUBALIGN()?

标签: gcclinkerldmemory-alignmentsections

解决方案


SUBALIGN专门用于调整输出节中输入的对齐方式。为了显示:

$ cat one.c
char a_one __attribute__((section(".mysection"))) = 0;
char b_one __attribute__((section(".mysection"))) = 0;

$ cat two.c
char a_two __attribute__((section(".mysection"))) = 0;
char b_two __attribute__((section(".mysection"))) = 0;

$ gcc -c one.c two.c

情况1

$ cat foo_1.lds
SECTIONS
{
    . = 0x10004;
    .mysection ALIGN(8) : {
        *(.mysection)
    }
}

$ ld -T foo_1.lds one.o two.o -o foo1.out
$ readelf -s foo1.out

Symbol table '.symtab' contains 9 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000010008     0 SECTION LOCAL  DEFAULT    1 
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     3: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS one.c
     4: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS two.c
     5: 000000000001000b     1 OBJECT  GLOBAL DEFAULT    1 b_two
     6: 0000000000010008     1 OBJECT  GLOBAL DEFAULT    1 a_one
     7: 0000000000010009     1 OBJECT  GLOBAL DEFAULT    1 b_one
     8: 000000000001000a     1 OBJECT  GLOBAL DEFAULT    1 a_two

$ readelf -t foo1.out | grep -A3 mysection
  [ 1] .mysection
       PROGBITS               PROGBITS         0000000000010008  0000000000010008  0
       0000000000000004 0000000000000000  0                 1
       [0000000000000003]: WRITE, ALLOC

这里,ALIGN(8).mysection0x10004 之后的下一个 8 字节边界 0x10008 对齐。

来自输入部分的char符号 位于下一个字节 by的开头,也来自输入部分。在下一个字节,是,来自输入部分,然后,也来自。来自所有输入部分的所有 4 个对象只是从输出部分的开头端对端放置。a_oneone.o(.mysection).mysectionb_twoone.o(.mysection)a_twotwo.o(.mysection)b_twotwo.o(.mysection)*(.mysection).mysection

案例2

$ cat foo_2.lds
SECTIONS
{
    . = 0x10004;
    .mysection ALIGN(8) : SUBALIGN(16) {
        *(.mysection)
    }
}

$ ld -T foo_2.lds one.o two.o -o foo2.out
$ readelf -s foo2.out

Symbol table '.symtab' contains 9 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000010008     0 SECTION LOCAL  DEFAULT    1 
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     3: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS one.c
     4: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS two.c
     5: 0000000000010021     1 OBJECT  GLOBAL DEFAULT    1 b_two
     6: 0000000000010010     1 OBJECT  GLOBAL DEFAULT    1 a_one
     7: 0000000000010011     1 OBJECT  GLOBAL DEFAULT    1 b_one
     8: 0000000000010020     1 OBJECT  GLOBAL DEFAULT    1 a_two

$ readelf -t foo2.out | grep -A3 mysection
  [ 1] .mysection
       PROGBITS               PROGBITS         0000000000010008  0000000000010008  0
       000000000000001a 0000000000000000  0                 16
       [0000000000000003]: WRITE, ALLOC

这一次, 的 8 字节对齐地址.mysection不变。但效果是,来自输入部分的SUBALIGN(16)符号被放置在下一个 16 字节边界0x10010 的开始之后,来自 同一输入部分的符号位于下一个字节。但是来自输入部分 的符号位于下一个16 字节边界 0x10020;并且,也来自,之后是 1 个字节。a_oneone.o(.mysection).mysectionb_onea_twotwo.o(.mysection)b_twotwo.o(.mysection)


推荐阅读