simavr icon indicating copy to clipboard operation
simavr copied to clipboard

simavr not loading .data correctly when avr_mmcu_vcd_trace_t is present.

Open ali1234 opened this issue 7 years ago • 2 comments

Test one:

#include <avr/io.h>

unsigned char myvar = 0xab;

void main(void)
{
    PORTB = myvar;
}

Compile and run it in simavr:

avr-gcc -g -mmcu=atmega168 -DF_CPU=16000000UL   -c -o test.o test.c
avr-gcc -g -mmcu=atmega168 -DF_CPU=16000000UL -o test.elf test.o

Check the contents of the data section:

$ avr-objdump -s -j .data test.elf

test.elf:     file format elf32-avr

Contents of section .data:
 800100 ab00                                 ..     

Run it in simavr:

$ run_avr -g -m atmega168 -f 16000000 test.elf
Loaded 182 .text at address 0x0
Loaded 2 .data
avr_gdb_init listening on port 1234

Debug with gdb:

(gdb) target remote :1234
Remote debugging using :1234
0x00000000 in __vectors ()
(gdb) break main
Note: breakpoints 1 and 2 also set at pc 0x9e.
Breakpoint 3 at 0x9e: file test.c, line 7.
(gdb) continue
Continuing.

Breakpoint 1, main () at test.c:7
7	    PORTB = myvar;
(gdb) disassemble
Dump of assembler code for function main:
   0x00000096 <+0>:	push	r28
   0x00000098 <+2>:	push	r29
   0x0000009a <+4>:	in	r28, 0x3d	; 61
   0x0000009c <+6>:	in	r29, 0x3e	; 62
=> 0x0000009e <+8>:	ldi	r24, 0x25	; 37
   0x000000a0 <+10>:	ldi	r25, 0x00	; 0
   0x000000a2 <+12>:	lds	r18, 0x0100
   0x000000a6 <+16>:	movw	r30, r24
   0x000000a8 <+18>:	st	Z, r18
   0x000000aa <+20>:	nop
   0x000000ac <+22>:	pop	r29
   0x000000ae <+24>:	pop	r28
   0x000000b0 <+26>:	ret
End of assembler dump.
(gdb) x 0x100
0x800100 <myvar>:	0x000000ab

Test two:

Source code:

#include <avr/io.h>
#include "avr_mcu_section.h"

/* trace struct for simavr */

const struct avr_mmcu_vcd_trace_t _mytrace[]  _MMCU_ = {
    { AVR_MCU_VCD_SYMBOL("B0"), .mask = (1 << 0), .what = (void*)&PORTB, },
    { AVR_MCU_VCD_SYMBOL("B1"), .mask = (1 << 1), .what = (void*)&PORTB, },
    { AVR_MCU_VCD_SYMBOL("B2"), .mask = (1 << 2), .what = (void*)&PORTB, },
    { AVR_MCU_VCD_SYMBOL("B3"), .mask = (1 << 3), .what = (void*)&PORTB, },
    { AVR_MCU_VCD_SYMBOL("B4"), .mask = (1 << 4), .what = (void*)&PORTB, },
    { AVR_MCU_VCD_SYMBOL("B5"), .mask = (1 << 5), .what = (void*)&PORTB, },
    { AVR_MCU_VCD_SYMBOL("B6"), .mask = (1 << 6), .what = (void*)&PORTB, },
    { AVR_MCU_VCD_SYMBOL("B7"), .mask = (1 << 7), .what = (void*)&PORTB, },

};

unsigned char myvar = 0xab;

void main(void)
{
    PORTB = myvar;
}

Compile and run as before. Verify the data section again with objdump to confirm it is the same.

Run it in gdb:

(gdb) target remote :1234
Remote debugging using :1234
0x00000000 in __vectors ()
(gdb) break main
Breakpoint 1 at 0x9e: file test.c, line 24.
(gdb) continue
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.

Breakpoint 1, main () at test.c:24
24	    PORTB = myvar;
(gdb) disassemble
Dump of assembler code for function main:
   0x00000096 <+0>:	push	r28
   0x00000098 <+2>:	push	r29
   0x0000009a <+4>:	in	r28, 0x3d	; 61
   0x0000009c <+6>:	in	r29, 0x3e	; 62
=> 0x0000009e <+8>:	ldi	r24, 0x25	; 37
   0x000000a0 <+10>:	ldi	r25, 0x00	; 0
   0x000000a2 <+12>:	lds	r18, 0x0100
   0x000000a6 <+16>:	movw	r30, r24
   0x000000a8 <+18>:	st	Z, r18
   0x000000aa <+20>:	nop
   0x000000ac <+22>:	pop	r29
   0x000000ae <+24>:	pop	r28
   0x000000b0 <+26>:	ret
End of assembler dump.
(gdb) x 0x100
0x800100 <myvar>:	0x0000ffff

Result: myvar is now 0xff instead of 0xab, but the data section has not changed according to objdump.

ali1234 avatar Oct 10 '18 05:10 ali1234

Including the link flags "-Wl,--undefined=_mmcu,--section-start=.mmcu=0x910000" makes this work, but I don't see why it should be necessary given that objdump can find the intact .data section just fine without it.

ali1234 avatar Oct 10 '18 06:10 ali1234

I realize this is quite old news, but this occurs because of section ordering. It's possible that the .mmcu section appears between .text and .data, but simavr loads .text and .data immediately adjacent to each other. This means the offsets in __do_copy_data (a stub inserted by libgcc) don't match the flash memory map simulated by simavr. Moving the section start address ensures it is not mapped between the two other sections.

Matir avatar Dec 06 '20 07:12 Matir