Runtime error in the BareMetal environment for microcontroller

Hi all,

From my previous topic, I made the swift compier compiling for the microcontroller(ARM Cortex-M). Most swift codes can run on my cortex-m7 boards now! I tried a lot of code snippets, most of them work very well(I tried different types, Functions, Classes, Structures, Protocols, etc.) I'm using STM32 NUCLEO-F676ZI and NXP MIMXRT1050-EVK for testing. Both of them work very well. Here are what them look like:

Till now, I still get some crashes in some snippets. The RTOS would give hints about the crash. They are all about wrong memory access. And all of the problems are caused by the swift_conformsToProtocolImpl function in the runtime.

Here is the process how I found it:

I met the first crash when I use print function. After some time debugging, I found that when the program goes into the line if case let streamableObject as TextOutputStreamable = value in _print_unlocked function in OutputStream.swift, it crashed.

And in different situation, I also met the exactly same problem. I'll give a whole example here.

In my RTOS main function, it calls madMain() which is compiled by Swift compiler, here is the whole swift file:

 @_silgen_name("madMain")
func madMain(_ x: Int) -> Int {
    var catCharacters: [Character] = ["C", "a", "t", "!"]
    let catString = String(catCharacters)

    return x
}
  1. When this simple program runs to line let catString = String(catCharacters), it would crash. The RTOS gives the following information to the console:
***** USAGE FAULT *****
  Unaligned memory access
***** Hardware exception *****
Current thread ID = 0x800001e4
Faulting instruction address = 0x600bec5a
Fatal fault in essential thread! Spinning...
  1. I checked the related info in the linker map file:
.text._ZL28swift_conformsToProtocolImplPKN5swift14TargetMetadataINS_9InProcessEEEPKNS_24TargetProtocolDescriptorIS1_EE
                0x00000000600beb9c      0x208 mylib/lib/libswiftCore.a(ProtocolConformance.cpp.o)
  1. And the address in the disassemble file:
600bec50:    e044          b.n    600becdc <_ZL28swift_conformsToProtocolImplPKN5swift14TargetMetadataINS_9InProcessEEEPKNS_24TargetProtocolDescriptorIS1_EE+0x140>
600bec52:    f8d8 0000     ldr.w    r0, [r8]
600bec56:    eb00 0608     add.w    r6, r0, r8
600bec5a:    68f0          ldr    r0, [r6, #12]
600bec5c:    f3c0 01c2     ubfx    r1, r0, #3, #3
600bec60:    2903          cmp    r1, #3
  1. Obviously, the function _ZL28swift_conformsToProtocolImplPKN5swift14TargetMetadataINS_9InProcessEEEPKNS_24TargetProtocolDescriptorIS1_EE casued the crash.

  2. After demangled, I found it's the function swift_conformsToProtocolImpl(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*) in ProtocolConformance.cpp

Now, I don't know how to continue. It's a little complicated for me to understand this whole function. Could anyone give any advice here?

3 Likes

Hmm, I think that the question to ask is what is r8 and why is *r8 + r8 + 0xc not suitably aligned for a load, which should be fine at byte, half-word, or word granularity IIRC? What is the value of r6 at the time of the fault?