4

I'm trying to print a string through semihosting on STM32F4. I define a variable:

let array: &[u8] = &[
    0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 
    0x6e, 0x65, 0x77, 0x20, 0x77, 0x61, 0x79, 0x00, 0x00, 0x00,
];

This a non-mutable variable so it goes into .rodata section in the ELF file.

Section Headers:
[Nr] Name    Type     Addr     Off    Size   ES Flg Lk Inf Al
[ 4] .rodata PROGBITS 0800077c 00277c 000014 00   A  0   0  4

Here I can see the variable is 20 bytes long and stored at 0x800077c.

If I dump the section I can see the text:

Hex dump of section '.rodata':
0x0800077c 54686973 20697320 61206e65 77207761 This is a new wa
0x0800078c 79000000                            y...

Finally, I load the program to the target and execute it. If I look at the address of the string I see this:

(gdb) x /20bx 0x0800077c
0x800077c <.Lbyte_str.0>:    0x00 0x68 0x01 0x00 0x00 0x00 0x72 0x07
0x8000784 <.Lbyte_str.0+8>:  0x00 0x68 0x01 0x00 0x00 0x00 0xff 0xff
0x800078c <.Lbyte_str.0+16>: 0xff 0xff 0xff 0xff

Here is the relevant section for the linker script:

.rodata : ALIGN(4)
{
  _srodata = .;
  *(.rodata)
  *(.rodata.*)
  _erodata = ALIGN(4);
} > FLASH

Why does the content of memory on the target and in the ELF file differ?

If I place the variable in RAM it works.

I checked with GDB and it loads the .rodata section as follows:

Loading section .rodata, size 0x14 lma 0xf0000ef6
Loading section .text, size 0x77a lma 0x8000000

Why does GDB load the .rodata section to 0xf0000ef6 instead of 0x800077c? I'd expect it will read the ELF file and load the sections correctly.

Removing the .rodata section and placing content of .rodata directly into .text solves the issue.

Content of the linker script that causes the issue:

ENTRY(reset_handler)

MEMORY
{
    FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K
    RAM  (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
}

PROVIDE(_stack_start = ORIGIN(RAM) + LENGTH(RAM));

SECTIONS
{
    .text : {
        __STACK_START = .;
        LONG(_stack_start);

        KEEP(*(.vector_table.reset_vector));
    __reset_vector = ABSOLUTE(.);

        KEEP(*(.vector_table.exceptions));
    __eexceptions = ABSOLUTE(.);

    KEEP(*(.vector_table.interrupts));
    __einterrupts = ABSOLUTE(.);

    *(.text*)
    } > FLASH = 0xFF

    .bss : ALIGN(4)
    {
        _sbss = .;
        *(.bss.*);
       _ebss = ALIGN(4);
    } > RAM

    .data : ALIGN(4)
    {
    _sdata = .;
    *(.data*)
    _edata = ALIGN(4);
     } > RAM AT > FLASH = 0xFF

    .rodata :  ALIGN(4)
     {
     _srodata = .;
     *(.rodata*)
     *(.rodata)
     _erodata = ALIGN(4);
     } > FLASH

     .ARM.exidx :
     {
     *(.ARM.exidx*)
     } > RAM

    _sidata = LOADADDR(.data);
   }

Result in GDB output:

Reading symbols from target/thumbv7em-none-eabi/debug/cortex...done.
0x00000000 in ?? ()
Loading section .rodata, size 0x14 lma 0xf0000ef6
Loading section .text, size 0x77a lma 0x8000000
Loading section .ARM.exidx, size 0x10 lma 0x800077a
Start address 0x80004ae, load size 1950
Transfer rate: 1 KB/sec, 650 bytes/write.

readelf dump:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        08000000 001000 00077a 00  AX  0   0  4
  [ 2] .bss              NOBITS          20000000 002000 000000 00  WA  0   0  4
  [ 3] .data             NOBITS          20000000 002000 000000 00  WA  0   0  4
  [ 4] .rodata           PROGBITS        0800077c 00277c 000014 00   A  0   0  4
Shepmaster
  • 274,917
  • 47
  • 731
  • 969
phodina
  • 991
  • 6
  • 22
  • Does "load the program to the target" include flashing? If not, you are seeing some old content in the flash memory. – starblue Aug 19 '18 at 10:53
  • Yes it does. But for some unknown reason the .rodata section is flashed to `0xf0000ef6` which no assigned to FLASH or RAM. – phodina Aug 19 '18 at 14:23

0 Answers0