【问题标题】:LD: ALIGN vs SUBALIGN in linker scriptsLD:链接描述文件中的 ALIGN 与 SUBALIGN
【发布时间】:2019-03-12 15:41:19
【问题描述】:

它们有何不同?

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

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

【问题讨论】:

    标签: gcc linker ld memory-alignment sections


    【解决方案1】:

    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).mysection 与下一个 8 字节边界 0x10008 对齐, 在 0x10004 之后。

    char 符号 a_one,来自输入部分 one.o(.mysection),位于 .mysection 的开头 在下一个字节后面跟着b_two,同样来自输入部分one.o(.mysection)。在下一个字节, 是a_two,来自输入部分two.o(.mysection),然后是b_two,也来自two.o(.mysection)。全部 4 来自所有输入部分*(.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
    

    这一次,.mysection 的 8 字节对齐地址不变。但是 SUBALIGN(16) 的效果是符号 a_one,来自输入 one.o(.mysection) 部分放在下一个 16 字节 边界,0x10010,在.mysection的开始之后,符号b_one,来自 same 输入部分在下一个字节。但是符号a_two,来自输入部分 two.o(.mysection) 位于下一个 16 字节边界,0x10020;和b_two,来了 同样来自two.o(.mysection),之后是1个字节。

    【讨论】:

    • :的左边和右边的意义是什么?
    猜你喜欢
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-02
    • 2013-05-17
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多