[Bug target/103975] DWARF .debug_frame incorrect for ISRs on AVR; pushing SREG creates off-by-one error

kimballa at apache dot org gcc-bugzilla@gcc.gnu.org
Tue Jan 11 09:15:20 GMT 2022


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103975

--- Comment #3 from Aaron Kimball <kimballa at apache dot org> ---
(In reply to Andrew Pinski from comment #2)
> Can you try a newer verison of GCC since 7.x is no longer support like maybe
> 11.2.0 or even 10.3.0?

Hi Andrew,

I tried again and figured out the issue in my `PATH` that was preventing my
cross-compiler from working correctly. I now have gcc 11.2.0, binutils 2.37,
and avr-gcc 2.0.0 built from source, working together.

The issue remains. (Actually, if anything it's worse.)

I had to modify the test case as the original very-simple test now succeeds by
virtue of gcc being smarter about eliminating unnecessary register saves. The
issue can still be reproduced by increasing register pressure in the ISR. I
defined a larger number of `volatile unsigned char` global variables and added
them together with:

```
ISR(TIMER1_COMPA_vect) {
  x++;
  x += a + b + c + d + e + f + g + h + i + j + k + m + n + p;
}
```

This yields the following disassembly:
```
ISR(TIMER1_COMPA_vect) {
  ce:   1f 92           push    r1
  d0:   1f b6           in      r1, 0x3f        ; 63  # read SREG port
  d2:   1f 92           push    r1                    # push SREG
  d4:   11 24           eor     r1, r1
  d6:   1f 93           push    r17
  d8:   2f 93           push    r18
  da:   3f 93           push    r19
  dc:   4f 93           push    r20
# ... prologue continues ... (snip)
  f2:   ff 93           push    r31   # last line of prologue
# remainder of disasm snipped
```

As a bonus w/ this toolchain, binutils 2.37 has fixed the bug in objdump that
prevented it from reading .debug_frame entries correctly. 

Thus, `avr-objdump -Wframe ~/isr.elf` shows the following:
```
00000000 0010 ffffffff CIE
  Version:               1
  Augmentation:          ""
  Code alignment factor: 2
  Data alignment factor: -1
  Return address column: 36

  DW_CFA_def_cfa: r32 ofs 2
  DW_CFA_offset: r36 at cfa-1
  DW_CFA_nop
  DW_CFA_nop

00000014 0054 00000000 FDE cie=00000000 pc=00ce..00ce
  DW_CFA_restore: r14
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
                                 # ... no records for $PC=0xd0, 0xd4, 0xd8 ?
  DW_CFA_advance_loc: 12 to 00da
  DW_CFA_def_cfa_offset: 3
  DW_CFA_offset: r18 at cfa-2    # <-- r18 marked as 1'st reg saved. 
                                 # (cfa-0 & cfa-1 implicitly consumed by r36/PC
                                 # per the CIE)
                                 # ... but what happened to r1, SREG, and r17?
                                 # even if ABI says r1/r17 are disposable (??),
                                 # r18 should be at CFA-5 based on the pushes.
  DW_CFA_advance_loc: 2 to 00dc
  DW_CFA_def_cfa_offset: 4
  DW_CFA_offset: r19 at cfa-3
  DW_CFA_advance_loc: 2 to 00de
  DW_CFA_def_cfa_offset: 5
  DW_CFA_offset: r20 at cfa-4
# ... remainder snipped...
```

At 0xf4 (after prologue is complete) the FDE should have CFA at offset r32 +
19. However, it's missing 3 bytes and has:

```
  DW_CFA_advance_loc: 2 to 00f4
  DW_CFA_def_cfa_offset: 16   # Should be 19: 2 for return pc + 17 push ops
  DW_CFA_offset: r31 at cfa-15
```


Compilation command was:
```
$ avr/bin/avr-gcc  -Os -g  -Wl,--relax,--gc-section -DARCH_AVR \
  -mmcu=atmega32u4 -DF_CPU=16000000 -fno-exceptions ~/isr.c -o ~/isr.elf
```

Compiler build configuration is:
```
aaron@ubuntu:~/share/scratch/gcc11avr$ avr/bin/avr-gcc -v
Using built-in specs.
Reading specs from
/home/aaron/share/scratch/gcc11avr/avr/lib/gcc/avr/11.2.0/device-specs/specs-avr2
COLLECT_GCC=avr/bin/avr-gcc
COLLECT_LTO_WRAPPER=/home/aaron/share/scratch/gcc11avr/avr/libexec/gcc/avr/11.2.0/lto-wrapper
Target: avr
Configured with: ../gcc-11.2.0/configure
--prefix=/home/aaron/share/scratch/gcc11avr
--exec-prefix=/home/aaron/share/scratch/gcc11avr/avr
--with-local-prefix=/home/aaron/share/scratch/gcc11avr/local
--enable-fixed-point --enable-languages=c,c++ --disable-nls --disable-libssp
--disable-libada --disable-shared --disable-threads --with-avrlibc
--with-dwarf2 --disable-doc --target=avr
--with-toolexeclibdir=/home/aaron/share/scratch/gcc11avr/avr/lib
--with-sysroot=/home/aaron/share/scratch/gcc11avr/avr --with-avrlibc
--with-double=32
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 11.2.0 (GCC)
```

Log when building with `-v -save-temps` is:
```
aaron@ubuntu:~/share/scratch/gcc11avr$ avr/bin/avr-gcc -v -save-temps  -Os -g 
-Wl,--relax,--gc-section -DARCH_AVR -mmcu=atmega32u4 -DF_CPU=16000000 
-fno-exceptions ~/isr.c -o ~/isr.elf
Using built-in specs.
Reading specs from
/home/aaron/share/scratch/gcc11avr/avr/lib/gcc/avr/11.2.0/device-specs/specs-atmega32u4
COLLECT_GCC=avr/bin/avr-gcc
COLLECT_LTO_WRAPPER=/home/aaron/share/scratch/gcc11avr/avr/libexec/gcc/avr/11.2.0/lto-wrapper
Target: avr
Configured with: ../gcc-11.2.0/configure
--prefix=/home/aaron/share/scratch/gcc11avr
--exec-prefix=/home/aaron/share/scratch/gcc11avr/avr
--with-local-prefix=/home/aaron/share/scratch/gcc11avr/local
--enable-fixed-point --enable-languages=c,c++ --disable-nls --disable-libssp
--disable-libada --disable-shared --disable-threads --with-avrlibc
--with-dwarf2 --disable-doc --target=avr
--with-toolexeclibdir=/home/aaron/share/scratch/gcc11avr/avr/lib
--with-sysroot=/home/aaron/share/scratch/gcc11avr/avr --with-avrlibc
--with-double=32
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 11.2.0 (GCC)
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Os' '-g' '-D' 'ARCH_AVR'  '-D'
'F_CPU=16000000' '-fno-exceptions' '-o' '/home/aaron/isr.elf' '-mdouble=32'
'-mlong-double=64' '-specs=device-specs/specs-atmega32u4' '-mmcu=avr5'
'-dumpdir' '/home/aaron/isr.elf-'
 /home/aaron/share/scratch/gcc11avr/avr/libexec/gcc/avr/11.2.0/cc1 -E -quiet -v
-imultilib avr5 -D__AVR_ATmega32U4__ -D__AVR_DEVICE_NAME__=atmega32u4 -D
ARCH_AVR -D F_CPU=16000000 /home/aaron/isr.c -mn-flash=1 -mno-skip-bug
-mdouble=32 -mlong-double=64 -mmcu=avr5 -fno-exceptions -g -fworking-directory
-Os -fpch-preprocess -o /home/aaron/isr.elf-isr.i
ignoring nonexistent directory
"/home/aaron/share/scratch/gcc11avr/avr/home/aaron/share/scratch/gcc11avr/local/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/aaron/share/scratch/gcc11avr/avr/lib/gcc/avr/11.2.0/include
 /home/aaron/share/scratch/gcc11avr/avr/lib/gcc/avr/11.2.0/include-fixed

/home/aaron/share/scratch/gcc11avr/avr/lib/gcc/avr/11.2.0/../../../../../avr/include
 /home/aaron/share/scratch/gcc11avr/avr/usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Os' '-g' '-D' 'ARCH_AVR'  '-D'
'F_CPU=16000000' '-fno-exceptions' '-o' '/home/aaron/isr.elf' '-mdouble=32'
'-mlong-double=64' '-specs=device-specs/specs-atmega32u4' '-mmcu=avr5'
'-dumpdir' '/home/aaron/isr.elf-'
 /home/aaron/share/scratch/gcc11avr/avr/libexec/gcc/avr/11.2.0/cc1
-fpreprocessed /home/aaron/isr.elf-isr.i -mn-flash=1 -mno-skip-bug -quiet
-dumpdir /home/aaron/isr.elf- -dumpbase isr.c -dumpbase-ext .c -mdouble=32
-mlong-double=64 -mmcu=avr5 -g -Os -version -fno-exceptions -o
/home/aaron/isr.elf-isr.s
GNU C17 (GCC) version 11.2.0 (avr)
        compiled by GNU C version 9.3.0, GMP version 6.1.0, MPFR version 3.1.6,
MPC version 1.0.3, isl version isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C17 (GCC) version 11.2.0 (avr)
        compiled by GNU C version 9.3.0, GMP version 6.1.0, MPFR version 3.1.6,
MPC version 1.0.3, isl version isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 70441dcee53d290afd2c7af2e72d480e
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Os' '-g' '-D' 'ARCH_AVR'  '-D'
'F_CPU=16000000' '-fno-exceptions' '-o' '/home/aaron/isr.elf' '-mdouble=32'
'-mlong-double=64' '-specs=device-specs/specs-atmega32u4' '-mmcu=avr5'
'-dumpdir' '/home/aaron/isr.elf-'
 as --gdwarf-5 -mmcu=avr5 -mgcc-isr -mno-skip-bug -o /home/aaron/isr.elf-isr.o
/home/aaron/isr.elf-isr.s
COMPILER_PATH=/home/aaron/share/scratch/gcc11avr/avr/libexec/gcc/avr/11.2.0/:/home/aaron/share/scratch/gcc11avr/avr/libexec/gcc/avr/11.2.0/:/home/aaron/share/scratch/gcc11avr/avr/libexec/gcc/avr/:/home/aaron/share/scratch/gcc11avr/avr/lib/gcc/avr/11.2.0/:/home/aaron/share/scratch/gcc11avr/avr/lib/gcc/avr/
LIBRARY_PATH=/home/aaron/share/scratch/gcc11avr/avr/lib/gcc/avr/11.2.0/avr5/:/home/aaron/share/scratch/gcc11avr/avr/lib/avr5/:/home/aaron/share/scratch/gcc11avr/avr/lib/gcc/avr/11.2.0/:/home/aaron/share/scratch/gcc11avr/avr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Os' '-g' '-D' 'ARCH_AVR'  '-D'
'F_CPU=16000000' '-fno-exceptions' '-o' '/home/aaron/isr.elf' '-mdouble=32'
'-mlong-double=64' '-specs=device-specs/specs-atmega32u4' '-mmcu=avr5'
'-dumpdir' '/home/aaron/isr.elf.'
 /home/aaron/share/scratch/gcc11avr/avr/libexec/gcc/avr/11.2.0/collect2 -plugin
/home/aaron/share/scratch/gcc11avr/avr/libexec/gcc/avr/11.2.0/liblto_plugin.so
-plugin-opt=/home/aaron/share/scratch/gcc11avr/avr/libexec/gcc/avr/11.2.0/lto-wrapper
-plugin-opt=-fresolution=/home/aaron/isr.elf.res
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lm
-plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-latmega32u4
--sysroot=/home/aaron/share/scratch/gcc11avr/avr -mavr5 -Tdata 0x800100 -o
/home/aaron/isr.elf
/home/aaron/share/scratch/gcc11avr/avr/lib/avr5/crtatmega32u4.o
-L/home/aaron/share/scratch/gcc11avr/avr/lib/gcc/avr/11.2.0/avr5
-L/home/aaron/share/scratch/gcc11avr/avr/lib/avr5
-L/home/aaron/share/scratch/gcc11avr/avr/lib/gcc/avr/11.2.0
-L/home/aaron/share/scratch/gcc11avr/avr/lib --relax --gc-section
/home/aaron/isr.elf-isr.o --start-group -lgcc -lm -lc -latmega32u4 --end-group
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Os' '-g' '-D' 'ARCH_AVR'  '-D'
'F_CPU=16000000' '-fno-exceptions' '-o' '/home/aaron/isr.elf' '-mdouble=32'
'-mlong-double=64' '-specs=device-specs/specs-atmega32u4' '-mmcu=avr5'
'-dumpdir' '/home/aaron/isr.elf.'
```


More information about the Gcc-bugs mailing list