2

最初はソフトウェア エンジニアにとって「違いを見つける」ゲームのように見えますが、構文のわずかな違いがリンクの動作に大きな違いをもたらすようです。

ldscript1:

OUTPUT_FORMAT(elf64-x86-64)
ENTRY(main)
ABS_FIRST = 0x10000000;
OFF_SECOND = 0x20000000;
SECTIONS
{
    . = ABS_FIRST;
    .first :
    {
        *(.pre)
    }
    . += OFF_SECOND;
    .text :
    {
        *(.text)
        *(.rodata*)
    }
    .data :
    {
        *(.data)
    }
}

ldscript2:

OUTPUT_FORMAT(elf64-x86-64)
ENTRY(main)
ABS_FIRST = 0x10000000;
OFF_SECOND = 0x20000000;
SECTIONS
{
    . = ABS_FIRST;
    .first :
    {
        *(.pre)
    }
    hack = .;
    . = hack + OFF_SECOND;
    .text :
    {
        *(.text)
        *(.rodata*)
    }
    .data :
    {
        *(.data)
    }
}

プレス:

.section .pre
.long 0x0

main.c:

int main()
{
}

コンパイルおよびリンク:

gcc -c -xassembler-with-cpp -o pre.o pre.s
gcc -c -o main.o main.c
ld -T ldscriptX pre.o main.o -o example

古いバージョン:

$ ld -v
GNU ld (GNU Binutils for Ubuntu) 2.22

ldscript1 の場合:

$ objdump -h example | grep -E ".text|VMA"
Idx Name          Size      VMA               LMA               File off  Algn
  2 .text         00000006  0000000020000000  0000000020000000  00200000  2**2

ldscript2 の場合:

$ objdump -h example | grep -E ".text|VMA"
Idx Name          Size      VMA               LMA               File off  Algn
  2 .text         00000006  0000000030000004  0000000030000004  00200004  2**2

VMA は ldscript2 に対して正しいことに注意してください。ldscript1 の「+=」操作の前/中にゼロに戻されました。GNU ld のドキュメントを読みましたが、説明が見つかりません。

4

1 に答える 1