ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.6k stars 2.53k forks source link

LLD silently misinterprets the LMA in linkerscripts #4595

Open LemonBoy opened 4 years ago

LemonBoy commented 4 years ago

One more bug for our LLVM friends, this time the problem is inside the linker guts!

ASM file:

.section ".text","ax"
.global _start

.arm
.align 4
_start:
    b _start

Linker script:

OUTPUT_ARCH(arm)
ENTRY(_start)

PHDRS {
    p0  PT_LOAD FLAGS(7);
    p1  PT_LOAD FLAGS(7);
}

MEMORY {
    m0  : ORIGIN = 0x1000, LENGTH = 0x1000
    m1  : ORIGIN = 0x8000, LENGTH = 0x1000
}

SECTIONS
{
    .s0 :
    {
        *(.s0)
    } >m1 AT>m0 :p0

    .s1 :
    {
        KEEP (*(.text))
        KEEP (*(.data))
        KEEP (*(.bss))
    } >m0 :p1
}

Linked using the following command line: ld.lld-10 -T /tmp/script.ld /tmp/foo.o -o /tmp/foo Version: 1:10~++20200228052623+4c6e5899859-1~exp1~20200228163220.107 (from the LLVM's APT repo)

The problem lies in how the physical address of the program headers is calculated, the value computed by lld is wildly wrong:

  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x001000 0x00001000 0xffffa000 0x00004 0x00004 RWE 0x1000

On the other hand gnu ld produces the correct result:

  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000074 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10000
  LOAD           0x001000 0x00001000 0x00001000 0x00004 0x00004 RWE 0x10000
rohlem commented 1 year ago

If I'm reading https://github.com/llvm/llvm-project/issues/163#issuecomment-593586538 correctly, this should have been fixed since LLVM 11, but would be worthwhile (for someone who knows how to) to re-test for verification.