I am trying to create small riscv:32 binaries using zig for an embedded system and have a problem with objcopy.
My build.zig uses addObjCopy() to create a binary from the ELF build artefact, but it (sometimes) gets zero padded at the start. This seems to come and go depending on the program size.
It definitely seems to be an addObjCopy() issue as using GNU objcopy on the ELF works fine.
Source code and explanation at: GitHub - ringtailsoftware/zig-objcopy-problem
Any ideas?
Sze
December 5, 2025, 11:00pm
2
opened 08:08PM - 21 Oct 25 UTC
bug
### Zig Version
0.15.1
### Steps to Reproduce and Observed Behavior
I used th… e blinky.elf file from the project [stm32-baremetal-zig](https://github.com/haydenridd/stm32-baremetal-zig), but other elf files should also show the same behavior.
I run the command
```bash
zig objcopy -O binary blinky.elf blinky.bin
```
with zig 0.14.1 I get the correct output:
```txt
1 │ 00000000 00 00 05 20 99 20 00 08 49 22 00 08 49 22 00 08 |... . ..I"..I"..|
2 │ 00000010 49 22 00 08 49 22 00 08 49 22 00 08 00 00 00 00 |I"..I"..I"......|
3 │ 00000020 00 00 00 00 00 00 00 00 00 00 00 00 49 22 00 08 |............I"..|
4 │ 00000030 49 22 00 08 00 00 00 00 49 22 00 08 51 22 00 08 |I"......I"..Q"..|
```
with zig 0.15.1 there is some zero padding at the start, which is wrong:
```txt
1 │ 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
2 │ *
3 │ 000001c0 00 00 00 00 00 00 00 00 00 00 05 20 99 20 00 08 |........... . ..|
4 │ 000001d0 49 22 00 08 49 22 00 08 49 22 00 08 49 22 00 08 |I"..I"..I"..I"..|
5 │ 000001e0 49 22 00 08 00 00 00 00 00 00 00 00 00 00 00 00 |I"..............|
6 │ 000001f0 00 00 00 00 49 22 00 08 49 22 00 08 00 00 00 00 |....I"..I"......|
```
### Expected Behavior
produce a correct bin file
opened 11:42PM - 20 Jul 25 UTC
bug
contributor friendly
https://github.com/ziglang/zig/blob/e4abdf5a133ac4822644da1dabd5437ac751d78d/lib… /compiler/objcopy.zig#L823-L829
This isn't up to zig project standards.
https://github.com/ziglang/zig/blob/e4abdf5a133ac4822644da1dabd5437ac751d78d/test/standalone/stack_iterator/build.zig#L107-L108
👎 👎
tigerbeetle uses llvm-objcopy as their workaround:
main ← matklad/vendor-llvm-objcopy
opened 11:37AM - 30 Aug 24 UTC
We now depend on llvm-objcopy to make our multiversion binaries. Long term, we s… hould probably upstream the capabilities we need to `zig objcopy` but for now "vendor" a specific copy of llvm-objcopy we use.
Vendoring is useful primarily because there isn't an easy way to install the tool in a cross-platform way! As we want to make multiversion a normal build, it is important that the build remains seemless and that the user doesn't have to manually install anything.
The solution is to upload specific versions of llvm-objectopy as a release on <https://github.com/tigerbeetle/dependencies> and use that.
Sadly, you have to trust me that the binaries I uploaded there are good, but the mac and windows versions are straight from LLVM upstream release, and the build of statically-linked linux version seems to be reproduciable.
Assuming the specific binaries are fine, any further risks are locked down by veryfying the checksum upon the download.
So I think for now using a non-zig objcopy is the easiest solution, until the Zig version has been improved.
1 Like