Hi, I installed SDK 2.0 beta and would like upgrade my Zig template for Playdate to work on firmware version 2.0. However pdc is now giving me an error: error: compress failed: buffer is empty.
This is the pdc command I am running pdc --skip-unknown zig-out/Source zig-out/example.pdx. The contents of zig-out/Source: is
$ ls zig-out/Source
pdex.dylib pdex.elf pdxinfo playdate_image.png
Any ideas on what is causing this error? I updated the linker.ld file to match the new linking format of the 2.0 ELF files. Apologies for tagging you here, @dave. But I feel you might have the most insight here.
I installed zig 0.10.1 (on the Mac via brew) and the example project built without an issue using the build.0.10.1.zig build file. Any chance the build.zig file has some-sort of error?
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?
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)
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?
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..
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?
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.