ziglang / zig

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

support for linking powerpc64 ELFv1 ABI objects #5927

Open koachan opened 4 years ago

koachan commented 4 years ago

Hi, I'm trying to add linux-powerpc64 support to the compiler. I've gotten it far enough that the stage1 zig could compile things, but now I'm having problems with linking since apparently, lld doesn't support powerpc64 ELFv1 ABI (which Debian/ppc64 uses). Is there any way to specify an alternate ld binary to get around this issue?


More details:

With Zig code, lld generates wrong target for branches:

// hello.zig, compiled with "zig build-exe hello.zig"
const std = @import("std");

pub fn main() !void {
 const stdout = std.io.getStdOut().writer();
 try stdout.print("Hello, {}!\n", .{"world"});
}

Annotated objdump output of hello, for the relevant parts:

Disassembly of section .opd: # This contains metadata of functions

# Metadata of _start
# The actual code is at 0x0000000010013ab0, but at program startup,
# it tries to jump into this address, causing segfault.
0000000010075658 <_start>:
    10075658:   00 00 00 00     .long 0x0
    1007565c:   10 01 3a b0     maddhd  r0,r1,r7,r10
    10075660:   00 00 00 00     .long 0x0
    10075664:   10 06 d4 e0     vmhaddshs v0,v6,v26,v19
        ...

# Metadata of std.start.posixCallMainAndExit
# Again, the actual code is at 0x0000000010013ae0
0000000010075670 <std.start.posixCallMainAndExit>:
    10075670:   00 00 00 00     .long 0x0
    10075674:   10 01 3a e0     vmhaddshs v0,v1,v7,v11
    10075678:   00 00 00 00     .long 0x0
    1007567c:   10 06 d4 e0     vmhaddshs v0,v6,v26,v19
        ...
Disassembly of section .text:

    # This is the actual code of _start
    10013ab0:   3c 62 00 01     addis   r3,r2,1
    10013ab4:   38 63 c8 e0     addi    r3,r3,-14112
    10013ab8:   7c 24 0b 78     mr      r4,r1
    10013abc:   f8 83 00 00     std     r4,0(r3)

    # This branches into the wrong address.
    # It should branch into 0x0000000010013ae0 instead.
    10013ac0:   48 06 1b b1     bl      10075670 <std.start.posixCallMainAndExit>

    10013ac4:   60 00 00 00     nop
    ...

    # This is the actual code of std.start.posixCallMainAndExit
    10013ae0:   7c 08 02 a6     mflr    r0
    10013ae4:   fb e1 ff f8     std     r31,-8(r1)
    10013ae8:   f8 01 00 10     std     r0,16(r1)
    10013aec:   f8 21 fd 91     stdu    r1,-624(r1)
    10013af0:   7c 3f 0b 78     mr      r31,r1
    10013af4:   3c 62 00 01     addis   r3,r2,1
    10013af8:   38 63 c8 e0     addi    r3,r3,-14112
    10013afc:   e8 83 00 00     ld      r4,0(r3)
    10013b00:   e8 84 00 00     ld      r4,0(r4)
    10013b04:   f8 9f 01 00     std     r4,256(r31)
    ...

Trying to do it with C and clang shows that lld doesn't support ELFv1 ABI:

int main(void) { return 0; }
$ clang -fuse-ld=lld -o test test.c
ld.lld: error: /usr/lib/gcc/powerpc64-linux-gnu/10/../../../powerpc64-linux-gnu/crt1.o: ABI version 1 is not supported
prazzb commented 4 years ago

You can try doing as I did here.

The basic idea is to generate .o files using zig and then use any other linker.

andrewrk commented 4 years ago

In scope of the Zig project:

Out of scope of the Zig project:

If you want this issue to be a proposal, then it would be closed now. However instead I'll leave it open and turn it into the use case of linking for powerpc64 ELFv1 ABI.

koachan commented 4 years ago

Thanks! I guess I'll just try to make everything work on ELFv2 first, for now.

The-King-of-Toasters commented 1 year ago

Necro'ing this issue to add this great blog post by Maskray about PPC linker details.

My hope is one day I can run Zig on my G5 (just for fun).

alexrp commented 1 month ago

FYI: https://github.com/ziglang/zig/pull/21310