Skip to content
This repository was archived by the owner on Jan 24, 2022. It is now read-only.

default_handler! doesn't work #58

Closed
crawford opened this issue Mar 1, 2018 · 2 comments
Closed

default_handler! doesn't work #58

crawford opened this issue Mar 1, 2018 · 2 comments

Comments

@crawford
Copy link
Contributor

crawford commented Mar 1, 2018

The default_handler! doesn't work in this example code. This was tested with rust-1.26.0-nightly-2018-02-27-29f5c699b:

Debug Build:

000004de <_ZN11cortex_m_rt15default_handler17h87e495993753afeeE>:
///
/// That exception frame is a snapshot of the program state right before the
/// exception occurred.
#[allow(unused_variables)]
#[cfg(target_arch = "arm")]
extern "C" fn default_handler(ef: &ExceptionFrame) -> ! {
 4de:   b082            sub     sp, #8
 4e0:   4601            mov     r1, r0
 4e2:   9001            str     r0, [sp, #4]
/// cause an exception
#[inline(always)]
pub fn bkpt() {
    #[cfg(target_arch = "arm")]
    unsafe {
        asm!("bkpt"
 4e4:   be00            bkpt    0x0000
    asm::bkpt();
 4e6:   9100            str     r1, [sp, #0]
 4e8:   e7ff            b.n     4ea <_ZN11cortex_m_rt15default_handler17h87e495993753afeeE+0xc>

    loop {}
 4ea:   e7fe            b.n     4ea <_ZN11cortex_m_rt15default_handler17h87e495993753afeeE+0xc>

000004ec <BUS_FAULT>:
    #[export_name = "DEFAULT_HANDLER"]
    #[linkage = "weak"]
    #[naked]
    extern "C" fn trampoline() -> ! {
        unsafe {
            asm!("mrs r0, MSP
 4ec:   f3ef 8008       mrs     r0, MSP
 4f0:   f7ff bff5       b.w     4de <_ZN11cortex_m_rt15default_handler17h87e495993753afeeE>
                 :
                 : "i"(default_handler as extern "C" fn(&ExceptionFrame) -> !)
                 :
                 : "volatile");

            intrinsics::unreachable()
 4f4:   defe            udf     #254    ; 0xfe

Release Build:

00000598 <_ZN11cortex_m_rt15default_handler17h6304dc68fb71af89E>:
 598:   be00            bkpt    0x0000
 59a:   e7fe            b.n     59a <_ZN11cortex_m_rt15default_handler17h6304dc68fb71af89E+0x2>

0000059c <BUS_FAULT>:
 59c:   f3ef 8008       mrs     r0, MSP
 5a0:   f7ff bffa       b.w     598 <_ZN11cortex_m_rt15default_handler17h6304dc68fb71af89E>
 5a4:   defe            udf     #254    ; 0xfe
@crawford crawford changed the title default_handler! doesn't work default_handler! doesn't work Mar 1, 2018
pftbest pushed a commit to pftbest/cortex-m-rt that referenced this issue Apr 18, 2018
Fixes rust-embedded#58

This is a breaking change for projects that are using custom linker
scripts.
@pftbest
Copy link
Contributor

pftbest commented Apr 18, 2018

I did some investigation into this issue, and I think this is a hard limitation of a GNU linker.
This is similar problem to what we had in https://github.com/japaric/cortex-m-rtfm/issues/39, we are creating a weak alias pointing into a weak symbol, and I think such configuration is not supported.
Here is the code to reproduce the exact same problem in C:

main.c

void _start() {}

void DEFAULT_HANDLER() {
  *((int*)0x10) = 5;
}

cortex_m_rt.c

__attribute__((weak)) void DEFAULT_HANDLER() {
    *((int*)0x10) = 1;
}

__attribute__((weak, alias("DEFAULT_HANDLER"))) void HARD_FAULT();
__attribute__((weak, alias("DEFAULT_HANDLER"))) void BUS_FAULT();

void (*VECTORS[])() = {
    HARD_FAULT,
    BUS_FAULT,
};
arm-none-eabi-gcc -Os -o main.o -c main.c
arm-none-eabi-gcc -Os -o cortex_m_rt.o -c cortex_m_rt.c
arm-none-eabi-ld main.o cortex_m_rt.o
00008014 <BUS_FAULT>:
    8014:	e3a03000 	mov	r3, #0
    8018:	e3a02001 	mov	r2, #1
    801c:	e5832010 	str	r2, [r3, #16]
    8020:	e12fff1e 	bx	lr

Disassembly of section .data:

00018024 <VECTORS>:
   18024:	00008014 	andeq	r8, r0, r4, lsl r0
   18028:	00008014 	andeq	r8, r0, r4, lsl r0

There are two ways to fix it, either by introducing a DH_TRAMPOLINE as we did in svd2rust, but much much better solution would be to use linker script to create such weak symbols. And since we are going to do this for moving on stable compiler anyway, it will also fix this issue.
I've created a pull request #66

@japaric
Copy link
Member

japaric commented Aug 3, 2018

I believe this was fixed after we moved to using PROVIDE in linker scripts.

@japaric japaric closed this as completed Aug 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants