adamgreen / CrashCatcher

Catch Hard Faults on Cortex-M devices and save out a crash dump to be used by CrashDebug.
Apache License 2.0
220 stars 49 forks source link

RAM memory region load fail with elf #15

Closed paolok17 closed 2 years ago

paolok17 commented 2 years ago

When running CrashDebug passing an elf file an exception is thrown when loading dump data to .dma section. Passing the corresponding bin file works fine.

Command: arm-none-eabi-gdb filename.elf -ex "set target-charset ASCII" -ex "target remote | CrashDebug --elf filename.elf --dump crash_dump.log" Error: ERROR: The dump file failed to load RAM memory region at 0x20078000 - 0x20080000 [...] Encountered unexpected error: 19

elf file objdump excerpt :

CSNX.elf:     file format elf32-little
CSNX.elf
architecture: UNKNOWN!, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x080b7295

Program Header:
    LOAD off    0x000000c0 vaddr 0x08040000 paddr 0x08040000 align 2**6
         filesz 0x000c86b0 memsz 0x000c86b0 flags rwx
    LOAD off    0x000c8770 vaddr 0x20000000 paddr 0x081086b0 align 2**3
         filesz 0x0000be18 memsz 0x0000be18 flags rw-
    LOAD off    0x000d4588 vaddr 0x2000be18 paddr 0x2000be18 align 2**3
         filesz 0x00000000 memsz 0x0004d898 flags rw-
    LOAD off    0x000d4588 vaddr 0x20078000 paddr 0x20078000 align 2**2
         filesz 0x000040a0 memsz 0x000040a0 flags rw-

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .isr_vector   000001f8  08040000  08040000  000000c0  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .build_info   00000088  080401f8  080401f8  000002b8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .text         000afc58  08040280  08040280  00000340  2**6
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  3 .rodata       00018400  080efed8  080efed8  000aff98  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .ARM.extab    00000148  081082d8  081082d8  000c8398  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .ARM          00000250  08108420  08108420  000c84e0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .preinit_array 00000000  08108670  08108670  000d8628  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  7 .init_array   00000038  08108670  08108670  000c8730  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  8 .fini_array   00000008  081086a8  081086a8  000c8768  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  9 .data         0000be18  20000000  081086b0  000c8770  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 10 .dma          000040a0  20078000  20078000  000d4588  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 11 .bss          00049094  2000be18  2000be18  000d4588  2**3
                  ALLOC
 12 ._user_heap_stack 00004804  20054eac  20054eac  000d4588  2**0
                  ALLOC
 13 .ARM.attributes 0000002e  00000000  00000000  000d8628  2**0
                  CONTENTS, READONLY
 14 .debug_frame  000b77fc  00000000  00000000  000d8658  2**2
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 15 .debug_info   0097020e  00000000  00000000  0018fe54  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 16 .debug_abbrev 00066390  00000000  00000000  00b00062  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 17 .debug_aranges 000264d0  00000000  00000000  00b663f8  2**3
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 18 .debug_ranges 00025f10  00000000  00000000  00b8c8c8  2**3
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 19 .debug_line   00107715  00000000  00000000  00bb27d8  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 20 .debug_str    0070bf94  00000000  00000000  00cb9eed  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 21 .comment      00000079  00000000  00000000  013c5e81  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
08040000 l    d  .isr_vector    00000000 .isr_vector
080401f8 l    d  .build_info    00000000 .build_info
08040280 l    d  .text  00000000 .text
080efed8 l    d  .rodata        00000000 .rodata
081082d8 l    d  .ARM.extab     00000000 .ARM.extab
08108420 l    d  .ARM   00000000 .ARM
08108670 l    d  .preinit_array 00000000 .preinit_array
08108670 l    d  .init_array    00000000 .init_array
[...]

crash_dump.log

adamgreen commented 2 years ago

It looks like what is happening is that the .dma section is defined in your linker script in such a way that makes it look like neither your .data or .bss section. It has initial contents that are non-zero but weren't loaded into FLASH to be copied into RAM from the startup code.

What do you expect the initial contents of the globals/statics in this .dma section to be?

adamgreen commented 2 years ago

To me it looks like the linker script is written in such a way that globals placed in the .dma section should be considered uninitialized when main() starts but one of the globals given an attribute to be placed in this section is also assigned an explicit non-zero value in its definition. Given that this initial data didn't make it into the FLASH of the device, I doubt you have modified startup code which actually initializes it to match those non-zero values either.

You probably need to fix the definitions of the globals placed in this section to not have non-zero initializers. Get rid of the '=' signs from their definitions and if they need initial values then write code that explicitly initializes them as expected.

paolok17 commented 2 years ago

Hi Adam, thank you for the quick feedback.

All the dma buffers are global/statics without initializers, eg: static uint8_t ep0tempbuf[MAXDESCRBUF] __attribute__((section(".dma"), aligned(32))); Usually they would go in .bss section but we assign them to .dma where we don't care about initialization.

From objdump the first 0x40A0 bytes of the section seem to be zero initialized:

objdump -s -j .dma filename.elf
Contents of section .dma:
 20078000 00000000 00000000 00000000 00000000  ................
 20078010 00000000 00000000 00000000 00000000  ................
 20078020 00000000 00000000 00000000 00000000  ................
 20078030 00000000 00000000 00000000 00000000  ................
 20078040 00000000 00000000 00000000 00000000  ................
 20078050 00000000 00000000 00000000 00000000  ................
 20078060 00000000 00000000 00000000 00000000  ................
 20078070 00000000 00000000 00000000 00000000  ................
[...]
 2007c020 00000000 00000000 00000000 00000000  ................
 2007c030 00000000 00000000 00000000 00000000  ................
 2007c040 00000000 00000000 00000000 00000000  ................
 2007c050 00000000 00000000 00000000 00000000  ................
 2007c060 00000000 00000000 00000000 00000000  ................
 2007c070 00000000 00000000 00000000 00000000  ................
 2007c080 00000000 00000000 00000000 00000000  ................
 2007c090 00000000 00000000 00000000 00000000  ................

This is an excerpt of the linker script:

 /* Initialized data sections goes into RAM, load LMA copy after code */
  .data : 
  {
    . = ALIGN(8);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(8);
    _edata = .;        /* define a global symbol at data end */
  } >RAM AT> FLASH

[...]

  /* this rule places the .dma buffers into the DMA area of RAM */
  .dma :
  {
    *(.dma)
  } > DMARAM

  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM
adamgreen commented 2 years ago

Can you try adding the NOLOAD type for the dma section in the script? Like this:

  /* this rule places the .dma buffers into the DMA area of RAM */
  .dma (NOLOAD):
  {
    *(.dma)
  } > DMARAM
paolok17 commented 2 years ago

Hi, adding the NOLOAD attribute to .dma section solves the issue. Thank you!

This is the objdump after adding NOLOAD:

  9 .data         0000be18  20000000  081086b0  000c8770  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 10 .dma          000040a0  20078000  20078000  000d4588  2**2
                  ALLOC
 11 .bss          00049094  2000be18  2000be18  000d4588  2**3
                  ALLOC 
adamgreen commented 2 years ago

Happy to hear that it worked.

Closing this issue.