diff --git a/Cargo.toml b/Cargo.toml index fd0dc3b1ab3f94b05b7cbb9da0f90b3f034937c2..edf0cba3e1c9b8e9dbf07442e74bfa16940cb2a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ crypto = { path = "libraries/crypto" } byteorder = { version = "1", default-features = false } arrayref = "0.3.6" subtle = { version = "2.2", default-features = false, features = ["nightly"] } +linked_list_allocator = { version = "0.8.1", default-features = false } [features] #debug_allocations = ["libtock/debug_allocations"] diff --git a/src/allocator.rs b/src/allocator.rs new file mode 100644 index 0000000000000000000000000000000000000000..05e96695999c90d21aa7799a3ea774a4b263a173 --- /dev/null +++ b/src/allocator.rs @@ -0,0 +1,40 @@ +use core::alloc::GlobalAlloc; +use core::alloc::Layout; +use core::ptr; +use core::ptr::NonNull; +use linked_list_allocator::Heap; + +pub static mut HEAP: Heap = Heap::empty(); + +struct TockAllocator; + +unsafe impl GlobalAlloc for TockAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + HEAP.allocate_first_fit(layout) + .ok() + .map_or(ptr::null_mut(), NonNull::as_ptr) + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + HEAP.deallocate(NonNull::new_unchecked(ptr), layout) + } +} + +#[global_allocator] +static ALLOCATOR: TockAllocator = TockAllocator; + +#[cfg(not(feature = "custom_alloc_error_handler"))] +#[alloc_error_handler] +unsafe fn alloc_error_handler(_: Layout) -> ! { + use crate::syscalls; + + // Print 0x01 using the LowLevelDebug capsule (if available). + let _ = syscalls::command1_insecure(8, 2, 0x01); + + // Signal a panic using the LowLevelDebug capsule (if available). + let _ = syscalls::command1_insecure(8, 1, 0x01); + + loop { + syscalls::raw::yieldk(); + } +} diff --git a/src/main.rs b/src/main.rs index 661ecf841dd9fcdff8fd383da2175de590c41689..2819f81ee92e0f938111a8257f27945ec27c8ff9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,6 +30,7 @@ extern crate crypto; mod ctap; mod usb_ctap_hid; +mod allocator; use core::cell::Cell; #[cfg(feature = "debug_ctap")] @@ -410,4 +411,4 @@ fn check_user_presence(cid: ChannelID) -> Result<(), Ctap2StatusCode> { } else { Err(Ctap2StatusCode::CTAP2_ERR_USER_ACTION_TIMEOUT) } -} \ No newline at end of file +}