noseglasses / elf_diff

A tool to compare ELF binaries
GNU General Public License v3.0
173 stars 22 forks source link

Newer gcc labels confuse disassembly listing #119

Open jputcu opened 5 months ago

jputcu commented 5 months ago

I'm trying to analyse my AVR firmware going from gcc-7.3 to gcc-13.2 but the produced diffs are incorrect.

python3 -m elf_diff --bin_prefix "avr-" --html_file gcc7_to_13.html build/avr-gcc-7-variant_at128/MinSizeRel/KateSmib.elf build/avr-gcc-variant_at128/MinSizeRel/KateSmib.elf

image

avr-gcc 7.3:

00001acc <etl::basic_string_view<char, etl::char_traits<char> >::basic_string_view(char const*)>:
    1acc:   movw    r30, r24
    1ace:   std Z+1, r23    ; 0x01
    1ad0:   st  Z, r22
    1ad2:   ldi r19, 0x00   ; 0
    1ad4:   ldi r18, 0x00   ; 0
    1ad6:   cp  r22, r1
    1ad8:   cpc r23, r1
    1ada:   breq    .+14        ; 0x1aea <etl::basic_string_view<char, etl::char_traits<char> >::basic_string_view(char const*)+0x1e>
    1adc:   movw    r30, r22
    1ade:   movw    r18, r30
    1ae0:   sub r18, r22
    1ae2:   sbc r19, r23
    1ae4:   ld  r20, Z+
    1ae6:   cpse    r20, r1
    1ae8:   rjmp    .-12        ; 0x1ade <etl::basic_string_view<char, etl::char_traits<char> >::basic_string_view(char const*)+0x12>
    1aea:   add r22, r18
    1aec:   adc r23, r19
    1aee:   movw    r30, r24
    1af0:   std Z+3, r23    ; 0x03
    1af2:   std Z+2, r22    ; 0x02
    1af4:   ret

avr-gcc 13.2:

00001e0e <etl::basic_string_view<char, etl::char_traits<char> >::basic_string_view(char const*)>:
    ETL_CONSTEXPR14  ETL_EXPLICIT_STRING_FROM_CHAR basic_string_view(const T* begin_)
    1e0e:   movw    r26, r24
    1e10:   movw    r24, r22

00001e12 <.Loc.778>:
      : mbegin(begin_)
    1e12:   adiw    r26, 0x01   ; 1
    1e14:   st  X, r23
    1e16:   st  -X, r22

00001e18 <.LBB6103>:
    }

    //*************************************************************************
    static ETL_CONSTEXPR14 size_t length(const char_type* str)
    {
      size_t count = 0UL;
    1e18:   ldi r18, 0x00   ; 0
    1e1a:   ldi r19, 0x00   ; 0

00001e1c <.Loc.781>:

      if (str != 0)
    1e1c:   sbiw    r24, 0x00   ; 0
    1e1e:   breq    .+28        ; 0x1e3c <.L158>
    1e20:   mov r21, r22
    1e22:   mov r20, r25

00001e24 <.LBB6105>:
      size_t count = 0UL;
    1e24:   ldi r18, 0x00   ; 0
    1e26:   ldi r19, 0x00   ; 0
    1e28:   rjmp    .+8         ; 0x1e32 <.L157>

00001e2a <.L159>:
      {
        while (*str++ != 0)
        {
          ++count;
    1e2a:   subi    r18, 0xFF   ; 255
    1e2c:   sbci    r19, 0xFF   ; 255

00001e2e <.Loc.784>:
        while (*str++ != 0)
    1e2e:   mov r21, r30
    1e30:   mov r20, r31

00001e32 <.L157>:
    1e32:   mov r30, r21
    1e34:   mov r31, r20

00001e36 <.Loc.786>:
    1e36:   ld  r20, Z+

00001e38 <.Loc.787>:
    1e38:   cpse    r20, r1
    1e3a:   rjmp    .-18        ; 0x1e2a <.L159>

00001e3c <.L158>:
      , mend(begin_ + TTraits::length(begin_))
    1e3c:   add r24, r18
    1e3e:   adc r25, r19

00001e40 <.Loc.790>:
    1e40:   adiw    r26, 0x03   ; 3
    1e42:   st  X, r25
    1e44:   st  -X, r24
    1e46:   sbiw    r26, 0x02   ; 2

00001e48 <.Loc.791>:
    }
    1e48:   ret
noseglasses commented 4 months ago

I'm sorry, for telling what's the exact difference between the binaries and if there's something wrong with elfdiff, I would need the source code and the exact command line args for the two compiler versions. At first glance it looks like for one of the binaries annotated assembly is created. W.r.t the assembly itself, there's a big difference but that may be due to different optimization levels. In any case elfdiff is not the optimal tool to compare compiler versions. There, compiler explorer may be a better choice. What elf diff is good at is comparing binaries of different versions of a software compiled with the same compiler or the same code but different compiler flags. Then I would expect less problems with assembly annotations and such.