avr-objdump producing incorrect output with g++ -flto

0

I am using an Arduino Mega 2560 that has an AVR Atmega2560 chip. I am programming it using the stock Arduino IDE 1.8.4 on Windows, which ships with avr-objdump 2.26 and avr-g++ 4.9.2.

My programs are more or less working, but when attempting to examine the produced assembly, it appears that objdump is not producing the correct output.

Executing

avr-objdump -D -S -m avr:6 "arduino_build_948544\sketch\mysketch.ino.cpp.o" > mysketch.asm

appears to succeed, but for a function as simple as

void sleep_example() {
    SMCR = 1;
    __asm__("sleep");
}

the disassembly appears to be essentially random:

Disassembly of section .gnu.lto__Z13sleep_examplev.af7e500a:

00000000 <.gnu.lto__Z13sleep_examplev.af7e500a>:
   0:   78 9c           mul r7, r8
   2:   63 66           ori r22, 0x63   ; 99
   4:   c0 04           cpc r12, r0
   6:   52 40           sbci    r21, 0x02   ; 2
   8:   fc 18           sub r15, r12
   a:   88 3d           cpi r24, 0xD8   ; 216
   c:   81 98           cbi 0x10, 1 ; 16
   e:   91 99           sbic    0x12, 1 ; 18
  10:   81 91           ld  r24, Z+
  12:   69 c2           rjmp    .+1234      ; 0x4e6 <__SREG__+0x4a7>
  14:   39 06           cpc r3, r25
  16:   86 46           sbci    r24, 0x66   ; 102
  18:   0e 26           eor r0, r30
  1a:   46 46           sbci    r20, 0x66   ; 102
  1c:   10 83           st  Z, r17
  1e:   81 91           ld  r24, Z+
  20:   a1 9e           mul r10, r17
  22:   89 b1           in  r24, 0x09   ; 9
  24:   9e f1           brts    .+102       ; 0x8c <__SREG__+0x4d>
  26:   25 d3           rcall   .+1610      ; 0x672 <__SREG__+0x633>
  28:   47 26           eor r4, r23
  2a:   c6 ef           ldi r28, 0xF6   ; 246
  2c:   73 17           cp  r23, r19
  2e:   9c 60           ori r25, 0x0C   ; 12
  30:   52 57           subi    r21, 0x72   ; 114
  32:   9d fe           .word   0xfe9d  ; ????
  34:   ba 99           sbic    0x17, 2 ; 23
  36:   bb a1           ldd r27, Y+35   ; 0x23
  38:   cb e0           ldi r28, 0x0B   ; 11
  3a:   27 13           cpse    r18, r23
  3c:   03 c3           rjmp    .+1542      ; 0x644 <__SREG__+0x605>
  3e:   67 26           eor r6, r23
  40:   88 21           and r24, r8
  42:   8c cb           rjmp    .-2280      ; 0xfffff75c <__SREG__+0xfffff71d>
  44:   19 d5           rcall   .+2610      ; 0xa78 <__SREG__+0xa39>
  46:   19 80           ldd r1, Y+1 ; 0x01
  48:   2a 3a           cpi r18, 0xAA   ; 170
  4a:   77 dc           rcall   .-1810      ; 0xfffff93a <__SREG__+0xfffff8fb>
  4c:   ee e0           ldi r30, 0x0E   ; 14
  4e:   63 63           ori r22, 0x33   ; 51
  50:   61 84           ldd r6, Z+9 ; 0x09
  52:   48 30           cpi r20, 0x08   ; 8
  54:   ae 60           ori r26, 0x0E   ; 14
  56:   64 63           ori r22, 0x34   ; 52
  58:   04 d2           rcall   .+1032      ; 0x462 <__SREG__+0x423>
  5a:   eb 85           ldd r30, Y+11   ; 0x0b
  5c:   0e 34           cpi r16, 0x4E   ; 78
  5e:   fc ff           .word   0xfffc  ; ????
  60:   cf bc           out 0x2f, r12   ; 47
  62:   eb e1           ldi r30, 0x1B   ; 27
  64:   3b 65           ori r19, 0x5B   ; 91
  66:   66 06           cpc r6, r22
  68:   86 27           eor r24, r22
  6a:   40 29           or  r20, r0
  6c:   90 d1           rcall   .+800       ; 0x38e <__SREG__+0x34f>
  6e:   4f 99           sbic    0x09, 7 ; 9
  70:   98 40           sbci    r25, 0x08   ; 8
  72:   34 f3           brlt    .-52        ; 0x40 <__SREG__+0x1>
  74:   2d c6           rjmp    .+3162      ; 0xcd0 <__SREG__+0xc91>
  76:   43 1f           adc r20, r19
  78:   36 7c           andi    r19, 0xC6   ; 198
  7a:   63 94           inc r6
  7c:   05 a9           ldd r16, Z+53   ; 0x35
  7e:   06 1a           sub r0, r22
  80:   31 67           ori r19, 0x71   ; 113
  82:   75 fb           bst r23, 5
  84:   19 de           rcall   .-974       ; 0xfffffcb8 <__SREG__+0xfffffc79>
  86:   17 4c           sbci    r17, 0xC7   ; 199
  88:   3f 99           sbic    0x07, 7 ; 7
  8a:   18 83           st  Y, r17
  8c:   41 26           eor r4, r17
  8e:   ee ea           ldi r30, 0xAE   ; 174
  90:   fb 7f           andi    r31, 0xFB   ; 251
  92:   90 0b           sbc r25, r16
  94:   cc 65           ori r28, 0x5C   ; 92
  96:   00 71           andi    r16, 0x10   ; 16
  98:   37 ed           ldi r19, 0xD7   ; 215
  9a:   5e 74           andi    r21, 0x4E   ; 78
  9c:   9c 79           andi    r25, 0x9C   ; 156
  9e:   2e e3           ldi r18, 0x3E   ; 62
  a0:   ec c6           rjmp    .+3544      ; 0xe7a <__SREG__+0xe3b>
  a2:   16 46           sbci    r17, 0x66   ; 102
  a4:   86 9f           mul r24, r22
  a6:   4c 4c           sbci    r20, 0xCC   ; 204
  a8:   8c 2b           or  r24, r28
  aa:   19 a5           ldd r17, Y+41   ; 0x29
  ac:   18 57           subi    r17, 0x78   ; 120
  ae:   31 02           muls    r19, r17
  b0:   fd c0           rjmp    .+506       ; 0x2ac <__SREG__+0x26d>
  b2:   b8 9a           sbi 0x17, 0 ; 23
  b4:   71 2e           mov r7, r17
  b6:   23 50           subi    r18, 0x03   ; 3
  b8:   c1 a7           std Z+41, r28   ; 0x29
  ba:   27 37           cpi r18, 0x77   ; 119
  bc:   7f b2           in  r7, 0x1f    ; 31
  be:   83 d4           rcall   .+2310      ; 0x9c6 <__SREG__+0x987>
  c0:   33 33           cpi r19, 0x33   ; 51
  c2:   32 30           cpi r19, 0x02   ; 2
  c4:   ae 01           movw    r20, r28
  c6:   ca dc           rcall   .-1644      ; 0xfffffa5c <__SREG__+0xfffffa1d>
  c8:   66 6c           ori r22, 0xC6   ; 198
  ca:   38 7c           andi    r19, 0xC8   ; 200
  cc:   fb 38           cpi r31, 0x8B   ; 139
  ce:   1b 13           cpse    r17, r27
  d0:   c8 78           andi    r28, 0x88   ; 136
  d2:   90 53           subi    r25, 0x30   ; 48
  d4:   9d 19           sub r25, r13
  d6:   ee 31           cpi r30, 0x1E   ; 30
  d8:   36 1e           adc r3, r22
  da:   b8 eb           ldi r27, 0xB8   ; 184
  dc:   0e e3           ldi r16, 0x3E   ; 62
  de:   3f 01           movw    r6, r30
  e0:   9a 0c           add r9, r10
  e2:   74 06           cpc r7, r20
  e4:   d0 51           subi    r29, 0x10   ; 16
  e6:   0e ce           rjmp    .-996       ; 0xfffffd04 <__SREG__+0xfffffcc5>
  e8:   56 31           cpi r21, 0x16   ; 22
  ea:   a1 c5           rjmp    .+2882      ; 0xc2e <__SREG__+0xbef>
  ec:   a9 45           sbci    r26, 0x59   ; 89
  ee:   c5 31           cpi r28, 0x15   ; 21
  f0:   e9 25           eor r30, r9
  f2:   f9 f9           .word   0xf9f9  ; ????
  f4:   b9 31           cpi r27, 0x19   ; 25
  f6:   fe 79           andi    r31, 0x9E   ; 158
  f8:   a9 2e           mov r10, r25
  fa:   45 99           sbic    0x08, 5 ; 8
  fc:   65 a9           ldd r22, Z+53   ; 0x35
  fe:   31 2e           mov r3, r17
 100:   f9 c9           rjmp    .-3086      ; 0xfffff4f4 <__SREG__+0xfffff4b5>
 102:   a5 b9           out 0x05, r26   ; 5
 104:   a9 79           andi    r26, 0x99   ; 153
 106:   25 c5           rjmp    .+2634      ; 0xb52 <__SREG__+0xb13>
 108:   31 8e           std Z+25, r3    ; 0x19
 10a:   45 29           or  r20, r5
 10c:   a5 99           sbic    0x14, 5 ; 20
 10e:   79 f9           .word   0xf979  ; ????
 110:   31 c9           rjmp    .-3486      ; 0xfffff374 <__SREG__+0xfffff335>
 112:   89 05           cpc r24, r9
 114:   b9 a9           ldd r27, Y+49   ; 0x31
 116:   25 a9           ldd r18, Z+53   ; 0x35
 118:   45 70           andi    r20, 0x05   ; 5
 11a:   86 1e           adc r8, r22
 11c:   50 94           com r5
 11e:   81 ad           ldd r24, Z+57   ; 0x39
 120:   38 27           eor r19, r24
 122:   35 b5           in  r19, 0x25   ; 37
 124:   80 01           movw    r16, r0
 126:   00 1d           adc r16, r0
 128:   9f 69           ori r25, 0x9F   ; 159
 12a:   9f f5           Address 0x0000012a is out of bounds.
.word   0xffff  ; ????

I'm not sure why this is. It's likely my invocation of avr-objdump, but I don't know what to change to show the correct disassembly.

c++
assembly
avr
avr-gcc
objdump
asked on Stack Overflow Sep 23, 2017 by Reinderien • edited Sep 23, 2017 by Peter Cordes

1 Answer

4

-flto puts GCC's internal representation into the .o, for cross-file optimization at link time. https://gcc.gnu.org/wiki/LinkTimeOptimization

It's not in a code section, but you used -D to disassemble non-code sections as if they were code. So you got exactly what you asked for.

If you hadn't used LTO, there would be actual AVR machine code in the .o.

There may be an option to include machine-code and gcc internal representation in the .o, but that won't be the final machine code that will go into the binary if you use -flto while linking. But a better way to see that is with gcc -O3 -S (See also How to remove "noise" from GCC/clang assembly output?). (Without -flto, otherwise you'll see the asm that gcc feeds to gas to produce a .o with a .gnu.lto__Z13sleep... section instead of a .text section.)

The only way to see the code in the final binary is to disassemble it. Optimization happens in the same step that creates it, so none of the earlier steps are guaranteed to be the same. However, it can be useful to look at the compiler's asm output since it can keep some symbolic info attached, especially with -fverbose-asm.

answered on Stack Overflow Sep 23, 2017 by Peter Cordes • edited Sep 23, 2017 by Peter Cordes

User contributions licensed under CC BY-SA 3.0