cargo-n64
cargo-n64 copied to clipboard
Add Newlib binary and allocator support
Adds builds of newlib-3.3.0, and implement an allocator in n64lib which uses this.
Newlib was built as follows:
CFLAGS_FOR_TARGET="-DPREFER_SIZE_OVER_SPEED=1 -Os -G0 -mabi=32 -mno-gpopt" \
../configure --target=mips-elf
libc.a and libm.a are bundled in the cargo-n64 executable, and written to the temp directory where the other temporary build artifacts are placed (linker script, for example).
Since our sbrk() starts returning memory at the end of the .bss section, up the alignment of this in the linker script to 16 bytes.
Also enable the 'noabicalls' feature in the target.json. This is the default in GCC with the mips-elf target, but not for LLVM. The linker will emit some warnings without this.
Clippy is pretty unhappy with this one. We have a couple of options:
- Add
#[cfg(target_vendor = "nintendo64")]
in a lot of places. Like this. - Split the N64 code out of this repo (#6)
- #[cfg(target_vendor = "nintendo64")]
I went with this, as it's the easiest option for the time being.
Had to fix the sbrk implementation, turns out it was wrong. Reference implementation from newlib.
Is this ready for review?
Yes, it's ready. I tested it yesterday by modifying the hello world example to use a format!()'d string rather than a constant, and verifying that malloc was being called.
Actually, just hold off on this for now... I'm seeing some strange behavior when I'm trying to allocate frame buffers using malloc. The _gp symbol is present (and points to something), despite newlib being compiled with -mno-gpopt. And what's weirder is I can't find the _gp symbol anywhere in libc.a. Maybe it's from llvm.
@kskjer FWIW the Nintendo64 target compiles with static relocation model to workaround problems I had with the global pointer:
https://github.com/rust-console/cargo-n64/blob/51a0c8183c6059da9ebe71ed0042d573c7b2dd7d/cargo-n64/src/templates/mips-nintendo64-none.fmt#L19
https://github.com/rust-console/cargo-n64/blob/51a0c8183c6059da9ebe71ed0042d573c7b2dd7d/cargo-n64/src/templates/linker.ld#L40-L45
I suspect libc
and libm
need to be compiled with a fairly similar ABI.
@kskjer FWIW the Nintendo64 target compiles with static relocation model to workaround problems I had with the global pointer:
https://github.com/rust-console/cargo-n64/blob/51a0c8183c6059da9ebe71ed0042d573c7b2dd7d/cargo-n64/src/templates/mips-nintendo64-none.fmt#L19
https://github.com/rust-console/cargo-n64/blob/51a0c8183c6059da9ebe71ed0042d573c7b2dd7d/cargo-n64/src/templates/linker.ld#L40-L45
I suspect
libc
andlibm
need to be compiled with a fairly similar ABI.
Yeah, turns out the _gp sym was a red herring, and it's always there (but not used) if an .sdata section is present. The issue was that the CRCs were wrong due to a bug in my padding PR. The ABI configured in the target.json and what newlib was compiled with should be the same.
Hi!
One alternate approach to an allocator is the one i built here: https://github.com/JoNil/loka-n64/tree/master/n64-alloc
It is basically a copy of https://crates.io/crates/wee_alloc for webassembly but with only the static array backend.
Cheers
That's really cool! Thanks for sharing the link. I see you also have some other interesting stuff floating around in there...
I am also interested in experimenting with drone. I don't think it's an exact fit, but there's a lot of interesting things in it already. As much as I love building kernels, I would like someone else to do the heavy lifting. :joy: