Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable libunwind for NuttX #688

Closed
wants to merge 1 commit into from
Closed

Conversation

no1wudi
Copy link

@no1wudi no1wudi commented Jan 3, 2025

NuttX is a resource-constrained system, libunwind is too large for it in terms of both code size and memory usage. So we disable libunwind for NuttX.

NuttX is a resource-constrained system, libunwind is too large for it
in terms of both code size and memory usage. So we disable libunwind
for NuttX.

Signed-off-by: Huang Qi <[email protected]>
@workingjubilee
Copy link
Member

@no1wudi why are you building with unwinding enabled?

@no1wudi
Copy link
Author

no1wudi commented Jan 4, 2025

@workingjubilee Previously, I have been using the RISC-V platform for development work related to Rust and NuttX. Recently, when I started testing on the ARM platform, I discovered that the ARM platform references _Unwind_GetIP, which is currently not supported in the NuttX environment. Considering that the size of the Rust code could be reduced by approximately 20% after disabling libunwind, we are currently considering turning it off for the time being.

@workingjubilee
Copy link
Member

@no1wudi it's... not supported?

...but this is Arm we're talking about...?

@no1wudi
Copy link
Author

no1wudi commented Jan 4, 2025

@no1wudi it's... not supported?

...but this is Arm we're talking about...?

For ARM platform in NuttX, we are using unwind support from GCC (libgcc.a from arm-none-eabi-gcc), it does not provide an implementation of _Unwind_GetIP.

This branch works, implement _Unwind_GetIP on top of _Unwind_VRS_Get:

use core::ptr::addr_of_mut;
// On android and arm, the function `_Unwind_GetIP` and a bunch of
// others are macros, so we define functions containing the
// expansion of the macros.
//
// TODO: link to the header file that defines these macros, if you
// can find it. (I, fitzgen, cannot find the header file that some
// of these macro expansions were originally borrowed from.)
#[repr(C)]
enum _Unwind_VRS_Result {
_UVRSR_OK = 0,
_UVRSR_NOT_IMPLEMENTED = 1,
_UVRSR_FAILED = 2,
}
#[repr(C)]
enum _Unwind_VRS_RegClass {
_UVRSC_CORE = 0,
_UVRSC_VFP = 1,
_UVRSC_FPA = 2,
_UVRSC_WMMXD = 3,
_UVRSC_WMMXC = 4,
}
#[repr(C)]
enum _Unwind_VRS_DataRepresentation {
_UVRSD_UINT32 = 0,
_UVRSD_VFPX = 1,
_UVRSD_FPAX = 2,
_UVRSD_UINT64 = 3,
_UVRSD_FLOAT = 4,
_UVRSD_DOUBLE = 5,
}
type _Unwind_Word = libc::c_uint;
extern "C" {
fn _Unwind_VRS_Get(
ctx: *mut _Unwind_Context,
klass: _Unwind_VRS_RegClass,
word: _Unwind_Word,
repr: _Unwind_VRS_DataRepresentation,
data: *mut c_void,
) -> _Unwind_VRS_Result;
}
pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
let mut val: _Unwind_Word = 0;
let ptr = addr_of_mut!(val);
let _ = _Unwind_VRS_Get(
ctx,
_Unwind_VRS_RegClass::_UVRSC_CORE,
15,
_Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
ptr.cast::<c_void>(),
);
(val & !1) as libc::uintptr_t
}
// R13 is the stack pointer on arm.
const SP: _Unwind_Word = 13;
pub unsafe fn get_sp(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
let mut val: _Unwind_Word = 0;
let ptr = addr_of_mut!(val);
let _ = _Unwind_VRS_Get(
ctx,
_Unwind_VRS_RegClass::_UVRSC_CORE,
SP,
_Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
ptr.cast::<c_void>(),
);
val as libc::uintptr_t
}
// This function also doesn't exist on Android or ARM/Linux, so make it
// a no-op.
pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void {
pc
}

However, I have observed that compared to disabling libunwind, the code size increases by approximately 20%. Considering that as an embedded system, we typically analyze call stack information and the like on a PC, it is therefore advisable to disable it in order to conserve code space.

@workingjubilee
Copy link
Member

Isn't this what panic_immediate_abort is for?

@no1wudi
Copy link
Author

no1wudi commented Jan 19, 2025

Get it, thank you !

I originally thought that setting -Zbuild-std=std,panic_abort would be sufficient, but I overlooked -Zbuild-std-features=panic_immediate_abort.

@no1wudi no1wudi closed this Jan 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants