2

对于软件工程师来说,这看起来像是一场“找出差异”的游戏,但语法上的微小差异显然会对链接行为产生巨大影响。

脚本1:

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)
    }
}

脚本2:

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

主.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版本:

$ 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

请注意,对于 ldscript2,VMA 是正确的,但不知何故“。” 在 ldscript1 中的“+=”操作之前/中被设置回零。我已阅读 GNU ld 文档,但找不到解释。

4

1 回答 1

0

To me, it looks like ldscript1 behaves as expected...

This looks like a relative/absolute address issue. What is the value assigned to hack? I suspect it is 0.

Can you try hack = ABSOLUTE(.) ; ?

于 2013-11-07T08:48:25.310 回答