Skip to content

[llvm][PowerPC] LLVM fails to build working Zig compiler for powerpc64le-linux due to bogus bl target address #171748

@alexrp

Description

@alexrp

I've been trying to bootstrap the Zig compiler for powerpc64le-linux so we can get native CI machines set up for this target. Unfortunately, the bootstrap compiler dies with a SIGSEGV due to a jump to some seemingly random address that happens to contain a zero word. (I'm not sure why the kernel produces SIGSEGV rather than SIGILL here, but that's besides the point.)

I have narrowed it down to a bogus bl instruction:

❯ objdump zig.o -r --disassemble=heap.c_allocator_impl.alloc

zig.o:     file format elf64-powerpcle


Disassembly of section .text:

00000000039ef320 <heap.c_allocator_impl.alloc>:
 39ef320:	00 00 4c 3c 	addis   r2,r12,0
			39ef320: R_PPC64_REL16_HA	.TOC.
 39ef324:	00 00 42 38 	addi    r2,r2,0
			39ef324: R_PPC64_REL16_LO	.TOC.+0x4
 39ef328:	a6 02 08 7c 	mflr    r0
 39ef32c:	f8 ff e1 fb 	std     r31,-8(r1)
 39ef330:	c1 fe 21 f8 	stdu    r1,-320(r1)
 39ef334:	50 01 01 f8 	std     r0,336(r1)
 39ef338:	78 0b 3f 7c 	mr      r31,r1
 39ef33c:	98 00 df f8 	std     r6,152(r31)
 39ef340:	90 00 bf f8 	std     r5,144(r31)
 39ef344:	78 23 86 7c 	mr      r6,r4
 39ef348:	98 00 9f e8 	ld      r4,152(r31)
 39ef34c:	a8 00 7f f8 	std     r3,168(r31)
 39ef350:	a4 00 9f 90 	stw     r4,164(r31)
 39ef354:	f0 8f 0d e9 	ld      r8,-28688(r13)
 39ef358:	30 01 1f f9 	std     r8,304(r31)
 39ef35c:	b8 00 df f8 	std     r6,184(r31)
 39ef360:	c0 00 bf f8 	std     r5,192(r31)
 39ef364:	be 06 84 54 	clrlwi  r4,r4,26
 39ef368:	cf 00 9f 98 	stb     r4,207(r31)
 39ef36c:	d0 00 ff f8 	std     r7,208(r31)
 39ef370:	df 00 9f 98 	stb     r4,223(r31)
 39ef374:	74 00 a4 7c 	cntlzd  r4,r5
 39ef378:	f8 20 84 7c 	not     r4,r4
 39ef37c:	e2 d7 84 78 	rldicl  r4,r4,58,63
 39ef380:	01 00 00 48 	bl      39ef380 <heap.c_allocator_impl.alloc+0x60>
			39ef380: R_PPC64_REL24	debug.assert
 39ef384:	a4 00 bf 80 	lwz     r5,164(r31)
 39ef388:	a8 00 7f e8 	ld      r3,168(r31)
 39ef38c:	78 2b a4 7c 	mr      r4,r5
 39ef390:	20 00 84 78 	clrldi  r4,r4,32
 39ef394:	01 00 00 48 	bl      39ef394 <heap.c_allocator_impl.alloc+0x74>
			39ef394: R_PPC64_REL24	heap.c_allocator_impl.allocStrat
 39ef398:	b4 00 7f 90 	stw     r3,180(r31)
 39ef39c:	be 07 63 54 	clrlwi  r3,r3,30
 39ef3a0:	02 00 03 28 	cmplwi  r3,2
 39ef3a4:	f8 00 82 41 	beq     39ef49c <heap.c_allocator_impl.alloc+0x17c>
 39ef3a8:	04 00 00 48 	b       39ef3ac <heap.c_allocator_impl.alloc+0x8c>
 39ef3ac:	b4 00 7f 80 	lwz     r3,180(r31)
 39ef3b0:	be 07 63 54 	clrlwi  r3,r3,30
 39ef3b4:	00 00 03 28 	cmplwi  r3,0
 39ef3b8:	1c 00 82 41 	beq     39ef3d4 <heap.c_allocator_impl.alloc+0xb4>
 39ef3bc:	04 00 00 48 	b       39ef3c0 <heap.c_allocator_impl.alloc+0xa0>
 39ef3c0:	b4 00 7f 80 	lwz     r3,180(r31)
 39ef3c4:	be 07 63 54 	clrlwi  r3,r3,30
 39ef3c8:	01 00 03 28 	cmplwi  r3,1
 39ef3cc:	34 00 82 41 	beq     39ef400 <heap.c_allocator_impl.alloc+0xe0>
 39ef3d0:	cc 00 00 48 	b       39ef49c <heap.c_allocator_impl.alloc+0x17c>
 39ef3d4:	90 00 7f e8 	ld      r3,144(r31)
 39ef3d8:	08 00 23 28 	cmpldi  r3,8
 39ef3dc:	08 00 80 38 	li      r4,8
 39ef3e0:	5e 20 63 7c 	iselgt  r3,r3,r4
 39ef3e4:	e0 00 7f f8 	std     r3,224(r31)
 39ef3e8:	01 00 00 48 	bl      39ef3e8 <heap.c_allocator_impl.alloc+0xc8>
			39ef3e8: R_PPC64_REL24	malloc
 39ef3ec:	00 00 00 60 	nop
 39ef3f0:	88 00 7f f8 	std     r3,136(r31)
 39ef3f4:	00 00 23 2c 	cmpdi   r3,0
 39ef3f8:	14 01 82 40 	bne     39ef50c <heap.c_allocator_impl.alloc+0x1ec>
 39ef3fc:	1c 01 00 48 	b       39ef518 <heap.c_allocator_impl.alloc+0x1f8>
 39ef400:	a8 00 7f e8 	ld      r3,168(r31)
 39ef404:	df 00 bf 88 	lbz     r5,223(r31)
 39ef408:	78 2b a4 7c 	mr      r4,r5
 39ef40c:	20 00 84 78 	clrldi  r4,r4,32
 39ef410:	d1 ae 72 48 	bl      411a2e0 <hash_map.HashMapUnmanaged([]const u8,codegen.x86_64.CodeGen.airAsm.Label,hash_map.StringContext,80).dbHelper+0x6dd7b0>
 39ef414:	90 00 bf e8     ld      r5,144(r31)
...snip...

That bl at 39ef410 should actually be calling mem.Alignment.toByteUnits, and indeed that is what you see if you look at the assembly output:

    .p2align    4
    .type   heap.c_allocator_impl.alloc,@function
heap.c_allocator_impl.alloc:
.Lfunc_begin69258:
    .loc    13 223 0 is_stmt 1
    .cfi_startproc
.Lfunc_gep69258:
    addis 2, 12, .TOC.-.Lfunc_gep69258@ha
    addi 2, 2, .TOC.-.Lfunc_gep69258@l
.Lfunc_lep69258:
    .localentry heap.c_allocator_impl.alloc, .Lfunc_lep69258-.Lfunc_gep69258
    mflr 0
    std 31, -8(1)
    stdu 1, -336(1)
    std 0, 352(1)
    .cfi_def_cfa_offset 336
    .cfi_offset r31, -8
    .cfi_offset lr, 16
    mr  31, 1
    .cfi_def_cfa_register r31
    std 6, 160(31)
    std 5, 152(31)
    mr  6, 4
    ld 4, 160(31)
    std 3, 176(31)
    stw 4, 172(31)
    ld 8, -28688(13)
    std 8, 256(31)
    ld 8, -28688(13)
    std 8, 320(31)
.Ltmp1953179:
    .loc    13 223 14 prologue_end
    std 6, 192(31)
    std 5, 200(31)
    clrlwi  4, 4, 26
    stb 4, 215(31)
    std 7, 216(31)
    stb 4, 231(31)
    .loc    13 225 15
    cntlzd 4, 5
    not 4, 4
    rldicl 4, 4, 58, 63
    bl debug.assert
    lwz 5, 172(31)
    ld 3, 176(31)
    .loc    13 226 27
    mr  4, 5
    clrldi  4, 4, 32
    bl heap.c_allocator_impl.allocStrat
    stw 3, 188(31)
    clrlwi  3, 3, 30
    .loc    13 226 17 is_stmt 0
    cmplwi  3, 2
    beq 0, .LBB69258_5
    b .LBB69258_1
.LBB69258_1:
    .loc    13 0 17
    lwz 3, 188(31)
    clrlwi  3, 3, 30
    .loc    13 226 17
    cmplwi  3, 0
    beq 0, .LBB69258_3
    b .LBB69258_2
.LBB69258_2:
    .loc    13 0 17
    lwz 3, 188(31)
    clrlwi  3, 3, 30
    .loc    13 226 17
    cmplwi  3, 1
    beq 0, .LBB69258_4
    b .LBB69258_6
.LBB69258_3:
.Ltmp1953180:
    .loc    13 241 17 is_stmt 1
    ld 3, 152(31)
    cmpldi  3, 8
    li 4, 8
    iselgt  3, 3, 4
    std 3, 232(31)
.Ltmp1953181:
    .loc    13 242 37
    bl malloc
    nop
    std 3, 144(31)
    cmpdi   3, 0
    bne 0, .LBB69258_10
    b .LBB69258_11
.Ltmp1953182:
.LBB69258_4:
    .loc    13 249 71
    ld 3, 176(31)
    lbz 5, 231(31)
    mr  4, 5
    clrldi  4, 4, 32
    bl mem.Alignment.toByteUnits
    ld 5, 152(31)
...snip...

Yet it's clearly not calling that function in the object file, and also lacks a relocation.

Interestingly, here's where that function is actually located:

❯ nm zig.o | grep mem.Alignment.toByteUnits
000000000011a2e0 t mem.Alignment.toByteUnits

So out of bl range by a fairly large margin.

Relevant repro files are available here: https://files.alexrp.com/zig.tar.xz

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions