LD: ALIGN против SUBALIGN в скриптах компоновщика - PullRequest
1 голос
/ 12 марта 2019

Чем они отличаются?

Я читал, что SUBALIGN () каким-то образом вызывает определенное выравнивание. Есть ли другие отличия?

Когда я должен использовать ALIGN () и когда я должен использовать SUBALIGN ()?

1 Ответ

1 голос
/ 13 марта 2019

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

На этот раз 8-байтовый выровненный адрес .mysection не изменяется. Но Эффект SUBALIGN(16) - это символ a_one, поступающий с входа секция one.o(.mysection) размещается на следующем 16-байтовом граница , 0x10010, после начала .mysection и символ b_one, идущий от такая же секция ввода находится на следующем байте. Но символ a_two, поступающий из секции ввода two.o(.mysection) находится на следующей 16-байтовой границе, 0x10020; и b_two, ближайшие также от two.o(.mysection), после этого 1 байт.

...