Skip to content

Dangerous allocation linker error when using custom allocators #16

Closed
@pacmancoder

Description

@pacmancoder

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))
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions