Description
I have faced the issues with the "dangerous relocation" linker errors when compiling the rust library and linking it to the main ESP8266 project (IDF-style ESP8266 RTOS SDK v3.3).
I have tried to overcome this issue with solution proposed by @lexxvir in the comment, substituting linker by the stript; Also tried to add -C link-args="-mlongcalls -Wa,--auto-lit-pools"
to the RUSTFLAGS, tried to add adding the same args to the link args for IDF CMake file, but still no luck.
This issue kicks in when I try to perform any dynamic allocation after with alloc crate (e.g. boxing or pushing some data to the String)
Error output:
../../target/xtensa-esp8266-none-elf/release/libfirmware.a(firmware-5b7e9638ff0ed6ee.2qffuh8m3mnmhmu5.rcgu.o): In function `__rust_alloc':
2qffuh8m3mnmhmu5:(.text.__rust_alloc+0xb): dangerous relocation: l32r: literal target out of range (try using text-section-literals): .literal
../../target/xtensa-esp8266-none-elf/release/libfirmware.a(firmware-5b7e9638ff0ed6ee.2qffuh8m3mnmhmu5.rcgu.o): In function `__rust_dealloc':
2qffuh8m3mnmhmu5:(.text.__rust_dealloc+0xd): dangerous relocation: l32r: literal target out of range (try using text-section-literals): (.literal+0x4)
../../target/xtensa-esp8266-none-elf/release/libfirmware.a(firmware-5b7e9638ff0ed6ee.2qffuh8m3mnmhmu5.rcgu.o): In function `__rust_realloc':
2qffuh8m3mnmhmu5:(.text.__rust_realloc+0xf): dangerous relocation: l32r: literal target out of range (try using text-section-literals): (.literal+0x8)
collect2: error: ld returned 1 exit status
Currently, I have found a rather ugly solution, but at least it works:
I have explored the alloc crate sources and found that the allocation mechanism in rust is based on a few non-mangled functions, so I implemented them in my crate as direct calls to the custom allocator:
use idf_alloc::IdfAllocator;
use core::alloc::{GlobalAlloc, Layout};
#[global_allocator]
static GLOBAL_ALLOCATOR: IdfAllocator = IdfAllocator;
#[alloc_error_handler]
fn rust_idf_oom_error_handler(info: Layout) -> ! { panic!("Out of memory error!"); }
// The tricky part starts here
#[no_mangle]
pub unsafe fn __rust_alloc(size: usize, align: usize) -> *mut u8 {
GLOBAL_ALLOCATOR.alloc( Layout::from_size_align_unchecked(size, align))
}
#[no_mangle]
pub unsafe fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize) {
GLOBAL_ALLOCATOR.dealloc(ptr, Layout::from_size_align_unchecked(size, align))
}
#[no_mangle]
pub unsafe fn __rust_realloc(ptr: *mut u8,
old_size: usize,
align: usize,
new_size: usize
) -> *mut u8 {
GLOBAL_ALLOCATOR.realloc(ptr, Layout::from_size_align_unchecked(old_size, align), new_size)
}
#[no_mangle]
pub unsafe fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8 {
GLOBAL_ALLOCATOR.alloc_zeroed(Layout::from_size_align_unchecked(size, align))
}