Skip to content

defmt::export::acquire appears twice in optimized machine code #586

@japaric

Description

@japaric

Steps to reproduce

Start from app-template, configure it to use the main branch of defmt then modify hello to look like this

fn main() -> ! {
    app::export::acquire();
    app::exit()
}
$ cargo build --bin hello --release

$ arm-none-eabi-objdump -Cd target/thumbv7em-none-eabihf/release/hello
 000001ca <defmt::export::acquire>:
  1ca:   b5f0        push    {r4, r5, r6, r7, lr}
  1cc:   af03        add r7, sp, #12
(..)
 252:   f7ff ffae   bl  1b2 <core::panicking::panic>
 256:   defe        udf #254    ; 0xfe

(..)

00000356 <_defmt_acquire>:
 356:   b5f0        push    {r4, r5, r6, r7, lr}
 358:   af03        add r7, sp, #12
(..)
 3de:   f7ff fee8   bl  1b2 <core::panicking::panic>
 3e2:   defe        udf #254    ; 0xfe

Above _defmt_acquire and defmt::export::acquire are exact duplicates.


defmt::export::acquire is defined like this:

#[inline(never)]
pub fn acquire() {
    extern "Rust" {
        fn _defmt_acquire();
    }
    unsafe { _defmt_acquire() }
}

_defmt_acquire is defined in defmt-rtt. My guess is that _defmt_acquire gets inlined in the export::acquire BUT a full copy of it stays around because it has both #[no_mangle] on it and we have EXTERN(_defmt_acquire) in the defmt.x linker script.

Unsure how to fix. I wouldn't expect EXTERN to act like KEEP (LLD issue?). Removing EXTERN is likely to cause linker errors in some cases.

I think this issue also applies to other _defmt_* symbols but haven't checked

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