rust-embedded / cortex-m-quickstart

Template to develop bare metal applications for Cortex-M microcontrollers
809 stars 167 forks source link

use a single codegen-unit with the dev profile #18

Closed japaric closed 7 years ago

japaric commented 7 years ago

rust-lang/rust#44853 changed the default number of codegen units from 1 to 32 for the dev profile. Unfortunately this broke our dev builds so we are reverting the change in the Cargo.toml.


I haven't been able to figure the exact problem but things break at linking time. The related bits are these:

  1. We create a .vector_table.exceptions linker section in the cortex-m-rt crate.
// cortex-m-rt/src/lib.rs
static EXCEPTIONS: [Option<unsafe extern "C" fn()>; 14] = [
    Some(NMI),
    Some(HARD_FAULT),
    Some(MEM_MANAGE),
    Some(BUS_FAULT),
    Some(USAGE_FAULT),
    None,
    None,
    None,
    None,
    Some(SVCALL),
    None,
    None,
    Some(PENDSV),
    Some(SYS_TICK),
];
  1. We want this linker section to be available in all binaries that link to the cortex-m-rt crate so we have a linker section, in the cortex-m-rt crate, that does that:
// link.x
SECTIONS
{
  .vector_table ORIGIN(FLASH) : ALIGN(4)
  {
    /* Vector table */
    _svector_table = .;
    LONG(_stack_start);

    KEEP(*(.vector_table.reset_vector));

    KEEP(*(.vector_table.exceptions));
    _eexceptions = .;

    KEEP(*(.vector_table.interrupts));
    _einterrupts = .;
  } > FLASH

  /* .. */
}

Now when compiling with either 1 or 32 codegen units the libcortex_m_rt.rlib library does contain the EXCEPTIONS symbol and the symbol is placed in the right linker section. AFAICT, the only different between using 1 or 32 codegen units is that the rlib contains more object files inside when compiling with 32 codegen units.

My wild guess about what's happening is that since there are more object files the linker is not looking at all of them so it never looks at the object file that contains the EXCEPTIONS symbol and that's why it doesn't end up in the final binary.

japaric commented 7 years ago

cc @alexcrichton please check the PR description. TL;DR the recent codegen-units broke the dev builds of embedded programs that use this template.

bootchk commented 7 years ago

Linker option --whole-archive? Its been awhile since I studied how the linker works but this seems familiar. Order of object files (or libraries?) is important? I recall struggling with this trying to override weak symbols (e.g. DEFAULT_HANDLER) defined in startup code, with code defined in a library.

japaric commented 7 years ago

Fixed in cortex-m-rt v0.3.6. Affected users try cargo update.