numworks / epsilon-sample-app-rust

A sample Rust app for the NumWorks graphing calculator
BSD 3-Clause "New" or "Revised" License
51 stars 10 forks source link

Unable to set up an allocator #16

Open dyc3 opened 1 year ago

dyc3 commented 1 year ago

I'm unable to get an app with an allocator to build. I tried using simple_chunk_allocator to create a small region of memory that I could allocate dynamically.

I set it up like this in the main.rs module.

#![feature(const_mut_refs)]
#![feature(allocator_api)]
#![feature(default_alloc_error_handler)]

static mut HEAP: PageAligned<[u8; 4096]> = heap!(chunks = 256, chunksize = 16);
static mut HEAP_BITMAP: PageAligned<[u8; 2]> = heap_bitmap!(chunks = 16);
#[global_allocator]
static ALLOCATOR: GlobalChunkAllocator =
    unsafe { GlobalChunkAllocator::new(HEAP.deref_mut_const(), HEAP_BITMAP.deref_mut_const()) };

Cargo has no problem building it, but when nwlink runs, I get these errors:

    Finished release [optimized] target(s) in 1.15s
     Running `nwlink install-nwa target/thumbv7em-none-eabihf/release/numworks-app`
Upload [----------------------------------------] 0% | ETA: 0s/home/carson/.nvm/versions/node/v16.9.1/bin/nwlink: app.nwa:(.ARM.exidx.text.__rust_alloc+0x0): undefined reference to `__aeabi_unwind_cpp_pr0'
/home/carson/.nvm/versions/node/v16.9.1/bin/nwlink: app.nwa:(.ARM.exidx.text.__rust_dealloc+0x0): undefined reference to `__aeabi_unwind_cpp_pr0'
/home/carson/.nvm/versions/node/v16.9.1/bin/nwlink: app.nwa:(.ARM.exidx.text.__rust_realloc+0x0): undefined reference to `__aeabi_unwind_cpp_pr0'
/home/carson/.nvm/versions/node/v16.9.1/bin/nwlink: app.nwa:(.ARM.exidx.text.__rust_alloc_error_handler+0x0): undefined reference to `__aeabi_unwind_cpp_pr0'
Ecco commented 1 year ago

Interesting! Technically, nwlink really only links the elf file produced by cargo. And in theory __aeabi_ symbols should be implemented by the compiler. For example, gcc provides them in libgcc. In other words, those symbols should be in the app.nwa file to begin with.

Apparently this allocator reserves some space in the .bss section of the resulting elf file. This works, but is not ideal. When linking nwa files we expose two symbols, _heap_start and _heap_end, as well as an implementation of _sbrk (that newlib uses in C). It would be better to use either of these.

Finally __aeabi_unwind routines are meant to unwind the stack. This is used in exception handling. I'm not sure why this is used in __rust_alloc and __rust_alloc_error_handler at all…

dyc3 commented 1 year ago

I tried a couple of different allocators, and they all result in the same errors. Unfortunately, I'm not familiar enough with embedded rust to debug this further.

It probably wouldn't resolve our problem here, but would it be possible to hook up a custom allocator with liba's malloc, free, etc? The eadk doesn't seem to make those available.