I was. Do you happen to know if zig uses makefiles behind the scenes?
it does not. the build system itself is written in Zig
Also, one thing to note, is that if I run pdc manually I get the same error. So I doubt this has anything to do with the build system, and more to do with the contents to the Source folder, or the installation of pdc iteslf. Is it possible you could send the contents of your zig-out/Source folder so I can compare?
What OS are you building on? Let's start there. The error you're getting is new in 2.0, I just need to figure out why you're getting it and I'm not.
One thing to try, remove the skip unknown flag. Does that make any difference?
I am using macOS Ventura 13.3.1. I also tried with removing the --skip-unknown flag and same error unfortunately.
Bump. Still happening with the latest SDK. Unfortunately, I cannot get my game working with 2.0 unless I can get past this, I believe.
When we added --skip-unknown we also added --verbose to print which file it's compiling. Does that help at all?
Thanks for the response! Unfortunately no, it just says the same error with no new info. Maybe I am using the flag wrong? (Behaves the same when adding the --skip-unknown flag as well)
➜ Zig-Playdate-Template git:(main) ✗ /Users/danielbokser/Developer/PlaydateSDK/bin/pdc --verbose zig-out/Source zig-out/example.pdx
error: compress failed: buffer is empty
➜ Zig-Playdate-Template git:(main) ✗
However. I did notice it copied over only pdex.dylib to example.pdx
➜ Zig-Playdate-Template git:(main) ✗ ls -ltr zig-out/Source
total 1616
-rwxr-xr-x 1 danielbokser staff 697824 Jun 12 23:33 pdex.dylib
-rwxr-xr-x 1 danielbokser staff 115452 Jun 12 23:33 pdex.elf
-rw-r--r-- 1 danielbokser staff 248 Jun 12 23:47 playdate_image.png
-rw-r--r-- 1 danielbokser staff 123 Jun 12 23:47 pdxinfo
➜ Zig-Playdate-Template git:(main) ✗ ls -ltr zig-out/example.pdx
total 1368
-rw-r--r-- 1 danielbokser staff 697824 Jun 12 23:47 pdex.dylib
➜ Zig-Playdate-Template git:(main) ✗
And here is the pdxinfo
name=Hello World Zig
author=Daniel Bokser
description=A small demo of the Zig API
bundleID=com.panic.hellozigapi
imagePath=
I can attach the Source folder if that would be helpful.
I just noticed that if I delete pdex.elf, pdc succeeds, so that is probably the culprit. readelf output:
➜ Zig-Playdate-Template git:(main) ✗ readelf -h zig-out/Source/pdex.elf
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x1
Start of program headers: 52 (bytes into file)
Start of section headers: 114732 (bytes into file)
Flags: 0x5000400, Version5 EABI, hard-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 3
Size of section headers: 40 (bytes)
Number of section headers: 18
Section header string table index: 16
yeah, looking at the changes in 2.0 I'm guessing the code that builds the relocation table isn't working right in this case. Would you mind posting or DMing me the pdex.elf file so I can check what's going on?
Ah it might be that. I compiled the Hello World C example and noticed that .rel.*
sections are missing in my pdex.elf:
readelf -S zig-out/Source/pdex.elf
There are 18 section headers, starting at offset 0x1c0b8:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 010000 000657 00 AXMS 0 0 8
[ 2] .data PROGBITS 00000657 010657 000001 00 AX 0 0 1
[ 3] .bss NOBITS 00000658 010658 000030 00 WA 0 0 4
[ 4] .debug_loc PROGBITS 00000000 010658 000481 00 0 0 1
[ 5] .debug_abbrev PROGBITS 00000000 010ad9 0001f3 00 0 0 1
[ 6] .debug_info PROGBITS 00000000 010ccc 0035cc 00 0 0 1
[ 7] .debug_ranges PROGBITS 00000000 014298 000198 00 0 0 1
[ 8] .debug_str PROGBITS 00000000 014430 00449d 01 MS 0 0 1
[ 9] .debug_pubnames PROGBITS 00000000 0188cd 000b26 00 0 0 1
[10] .debug_pubtypes PROGBITS 00000000 0193f3 001358 00 0 0 1
[11] .ARM.attributes ARM_ATTRIBUTES 00000000 01a74b 000049 00 0 0 1
[12] .debug_frame PROGBITS 00000000 01a794 000428 00 0 0 4
[13] .debug_line PROGBITS 00000000 01abbc 000d45 00 0 0 1
[14] .comment PROGBITS 00000000 01b901 000013 01 MS 0 0 1
[15] .symtab SYMTAB 00000000 01b914 000290 10 17 35 4
[16] .shstrtab STRTAB 00000000 01bba4 0000bc 00 0 0 1
[17] .strtab STRTAB 00000000 01bc60 000457 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), y (purecode), p (processor specific)
vs the Hello World pdex.elf:
readelf -S Source/pdex.elf
There are 27 section headers, starting at offset 0x32a10:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 010000 000171 00 AX 0 0 16
[ 2] .rel.text REL 00000000 02b5d4 000070 08 I 24 1 4
[ 3] .data PROGBITS 00000174 010174 000014 00 WA 0 0 4
[ 4] .rel.data REL 00000000 02b644 000008 08 I 24 3 4
[ 5] .bss NOBITS 00000188 010188 000008 00 WA 0 0 4
[ 6] .debug_info PROGBITS 00000000 010188 00c67e 00 0 0 1
[ 7] .rel.debug_info REL 00000000 02b64c 0041f0 08 I 24 6 4
[ 8] .debug_abbrev PROGBITS 00000000 01c806 00065d 00 0 0 1
[ 9] .debug_loc PROGBITS 00000000 01ce63 0003cb 00 0 0 1
[10] .rel.debug_loc REL 00000000 02f83c 0003c0 08 I 24 9 4
[11] .debug_aranges PROGBITS 00000000 01d22e 000060 00 0 0 1
[12] .rel.debug_a[...] REL 00000000 02fbfc 000040 08 I 24 11 4
[13] .debug_ranges PROGBITS 00000000 01d28e 000068 00 0 0 1
[14] .rel.debug_ranges REL 00000000 02fc3c 0000a0 08 I 24 13 4
[15] .debug_macro PROGBITS 00000000 01d2f6 002507 00 0 0 1
[16] .rel.debug_macro REL 00000000 02fcdc 002bc8 08 I 24 15 4
[17] .debug_line PROGBITS 00000000 01f7fd 000a09 00 0 0 1
[18] .rel.debug_line REL 00000000 0328a4 000030 08 I 24 17 4
[19] .debug_str PROGBITS 00000000 020206 00aebc 01 MS 0 0 1
[20] .comment PROGBITS 00000000 02b0c2 000079 01 MS 0 0 1
[21] .ARM.attributes ARM_ATTRIBUTES 00000000 02b13b 000034 00 0 0 1
[22] .debug_frame PROGBITS 00000000 02b170 0000cc 00 0 0 4
[23] .rel.debug_frame REL 00000000 0328d4 000060 08 I 24 22 4
[24] .symtab SYMTAB 00000000 02b23c 000300 10 25 35 4
[25] .strtab STRTAB 00000000 02b53c 000097 00 0 0 1
[26] .shstrtab STRTAB 00000000 032934 0000dc 00 0 0 1
What gcc flags in the Makefile enable the relocation table? Is it -mword-relocations
and -Wl,--emit-relocs
?
I have attached the pdex.elf. Thank you very much for looking at this!
pdex.elf.zip (18.6 KB)
Quick update, I just enabled relocations, but unfortunately, I do have the same error. These are the new sections:
There are 26 section headers, starting at offset 0x1f5e4:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 010000 00064f 00 AXMS 0 0 8
[ 2] .data PROGBITS 0000064f 01064f 000001 00 AX 0 0 1
[ 3] .bss NOBITS 00000650 010650 000030 00 WA 0 0 4
[ 4] .rel.text REL 00000000 010650 000130 08 I 23 1 4
[ 5] .debug_loc PROGBITS 00000000 010780 000481 00 0 0 1
[ 6] .rel.debug_loc REL 00000000 010c04 000098 08 I 23 5 4
[ 7] .debug_abbrev PROGBITS 00000000 010c9c 0001f3 00 0 0 1
[ 8] .debug_info PROGBITS 00000000 010e8f 0035cc 00 0 0 1
[ 9] .rel.debug_info REL 00000000 01445c 002b70 08 I 23 8 4
[10] .debug_ranges PROGBITS 00000000 016fcc 000198 00 0 0 1
[11] .rel.debug_ranges REL 00000000 017164 0002e0 08 I 23 10 4
[12] .debug_str PROGBITS 00000000 017444 00449d 01 MS 0 0 1
[13] .debug_pubnames PROGBITS 00000000 01b8e1 000b26 00 0 0 1
[14] .rel.debug_p[...] REL 00000000 01c408 000008 08 I 23 13 4
[15] .debug_pubtypes PROGBITS 00000000 01c410 001358 00 0 0 1
[16] .rel.debug_p[...] REL 00000000 01d768 000008 08 I 23 15 4
[17] .ARM.attributes ARM_ATTRIBUTES 00000000 01d770 000045 00 0 0 1
[18] .debug_frame PROGBITS 00000000 01d7b8 000424 00 0 0 4
[19] .rel.debug_frame REL 00000000 01dbdc 000270 08 I 23 18 4
[20] .debug_line PROGBITS 00000000 01de4c 000cee 00 0 0 1
[21] .rel.debug_line REL 00000000 01eb3c 000130 08 I 23 20 4
[22] .comment PROGBITS 00000000 01ec6c 000013 01 MS 0 0 1
[23] .symtab SYMTAB 00000000 01ec80 000390 10 25 51 4
[24] .shstrtab STRTAB 00000000 01f010 000140 00 0 0 1
[25] .strtab STRTAB 00000000 01f150 000493 00 0 0 1
Here is the new pdex.elf:
pdex.elf.zip (22.6 KB)
I don't know much about ELF internals, but stepping through the processing code in the debugger I see an obvious bug: the bit that finds the total code size only winds up using the last segment, then the later code always uses the first segment. For whatever reason your pdex.elf has three segments: text and code in the first, bss in the second, and then.. bss also in the third but the type is GNU_STACK? I don't know what that's about, but bss doesn't take up space in the file so the compiler marks the total data size as zero, then it doesn't copy anything to the code buffer and then the compression function complains that it doesn't have anything to compress. It looks like our C API examples wind up with just one segment containing text, data, and bss, so I'd guess that's what Marc was testing against when he wrote that code and he didn't hit that bug.
I changed that first size checking loop to break when it sees a segment with non-zero code size and note which segment that is so it can copy its code later on. I'm assuming here you'd only ever have one segment with code+text? Here's a macOS build with that change. Not sure though what all you'll have to do to convince the OS that yes you really want to run this random binary you downloaded..
pdc.zip (793.4 KB)
Wow thank you very much! Unfortunately, I still get the same error with your new pdc build. BUT, that was a huge insight that it the fact that it was due to the fact my ELF defined more than one segment. So I followed this c - How to put 2 sections in 1 segment (Using ld scripts) - Stack Overflow and pdc (this new version and also the original 2.0 version) now works and I now have a proper .pdx file!
However, while it does work in the simulator, it crashes with an e0 error on hardware. I have even simplified my test program to just call playdate->system->setUpdateCallback(update_and_render, null)
and update_and_render
just returns 1, but it still crashes. The disassembly is below.
I have attached the new pdex.elf and pdx, which includes the pdex.bin file. Would you be able to take a look and see why it is crashing?
Thank you very much for all your help!
zig-out/Source/pdex.elf: file format elf32-littlearm
Disassembly of section .text:
00000000 <eventHandler>:
; switch (event) {
0: 09 b1 cbz r1, 0x6 <eventHandler+0x6> @ imm = #2
; return 0;
2: 00 20 movs r0, #0
4: 70 47 bx lr
6: 80 b5 push {r7, lr}
; playdate.system.setUpdateCallback(update_and_render, null);
8: 00 68 ldr r0, [r0]
a: 00 21 movs r1, #0
c: 02 6a ldr r2, [r0, #32]
e: 40 f2 21 00 movw r0, #33
12: c0 f2 00 00 movt r0, #0
16: 90 47 blx r2
18: bd e8 80 40 pop.w {r7, lr}
; return 0;
1c: 00 20 movs r0, #0
1e: 70 47 bx lr
00000020 <main.update_and_render>:
; return 1;
20: 01 20 movs r0, #1
22: 70 47 bx lr
elf_and_pdx.zip (13.8 KB)
Okay, turns out the problem is the code is using movw
at 0xe and movt
at 0x12 to load the address of the update_and_render function
to pass it to setUpdateCallback()
, and it puts R_ARM_THM_MOVW_AB
/R_ARM_THM_MOVT_AB
entries in the relocation table to match, but our loader doesn't know how to deal with that relocation type so the compiler ignores it. The address doesn't get fixed up at load time, then the system jumps to the wrong address for the update function.
Do you know if the -fPIC
flag was set at link time here?
Quick note: It looks like the -mword-relocations
compiler flag might work around this, forcing it to use word-sized addresses in the literal pool instead of splitting them with movt/movw.
Aha, looks like we did add -mword-relocations
to LDFLAGS in C_API/buildsupport/common.mk in v2.0, so hopefully that's the magic trick here. I don't think -fPIC is needed, or even wanted since we don't handle global offset tables in the compiler.
Ah thank you very much!! It looks like Zig may not support this flag out of the box, so I may have to add support for it. Will let you know how it goes
Looks like -fPIC on the latest version of Zig gets everything to work now!
Thanks so much again @dave !