Bug 21404 - [avr] assertion fail in bfd/elf32-avr.c:2145
Summary: [avr] assertion fail in bfd/elf32-avr.c:2145
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.28
: P2 normal
Target Milestone: ---
Assignee: Senthil Kumar Selvaraj
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-04-20 15:52 UTC by Georg-Johann Lay
Modified: 2017-05-12 04:53 UTC (History)
2 users (show)

See Also:
Host:
Target: avr
Build:
Last reconfirmed:


Attachments
bernd.elf.ltrans0.s (521 bytes, text/plain)
2017-04-20 15:52 UTC, Georg-Johann Lay
Details
bernd.elf.ltrans0.o (665 bytes, application/octet-stream)
2017-04-20 16:10 UTC, Georg-Johann Lay
Details
Minimal testcase (119 bytes, text/plain)
2017-04-21 12:24 UTC, Senthil Kumar Selvaraj
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Georg-Johann Lay 2017-04-20 15:52:38 UTC
Created attachment 9999 [details]
bernd.elf.ltrans0.s

$ avr-gcc bernd.elf.ltrans0.s -mmcu=atmega168 -mrelax 

/srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/../../../../avr/bin/ld: BFD (GNU Binutils) 2.28.51.20170321 assertion fail ../../../source/binutils-master/bfd/elf32-avr.c:2145
collect2: error: ld returned 1 exit status
Comment 1 Georg-Johann Lay 2017-04-20 16:00:57 UTC
Hi Sentil, CC'ing you as you might have some clue about this assertion failure.

A more verbose output with -v:

$ avr-gcc bernd.elf.ltrans0.s -mmcu=atmega168 -mrelax -v
Using built-in specs.
Reading specs from /srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/device-specs/specs-atmega168
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/srv/local/gnu/install/gcc-6/bin/../libexec/gcc/avr/6.3.1/lto-wrapper
Target: avr
Configured with: ../../gcc.gnu.org/gcc-6-branch/configure --target=avr --prefix=/local/gnu/install/gcc-6 --disable-nls --disable-shared --with-dwarf2 --with-gnu-ld --with-gnu-as --enable-languages=c,c++ --enable-checking=release : (reconfigured) ../../gcc.gnu.org/gcc-6-branch/configure --target=avr --prefix=/local/gnu/install/gcc-6 --disable-nls --disable-shared --with-dwarf2 --with-gnu-ld --with-gnu-as --enable-checking=release target_alias=avr --enable-languages=c,c++,lto --no-create --no-recursion
Thread model: single
gcc version 6.3.1 20170418 [gcc-6-branch revision 243886] (GCC) 
COLLECT_GCC_OPTIONS= '-mrelax' '-v' '-specs=device-specs/specs-atmega168' '-mmcu=avr5'
 /srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/../../../../avr/bin/as -v -mmcu=avr5 --mlink-relax -mno-skip-bug -o /tmp/ccXAfFYs.o bernd.elf.ltrans0.s
GNU assembler version 2.28.51 (avr) using BFD version (GNU Binutils) 2.28.51.20170321
COMPILER_PATH=/srv/local/gnu/install/gcc-6/bin/../libexec/gcc/avr/6.3.1/:/srv/local/gnu/install/gcc-6/bin/../libexec/gcc/:/srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/../../../../avr/bin/
LIBRARY_PATH=/srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/avr5/:/srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/../../../../avr/lib/avr5/:/srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/:/srv/local/gnu/install/gcc-6/bin/../lib/gcc/:/srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/../../../../avr/lib/
COLLECT_GCC_OPTIONS= '-mrelax' '-v' '-specs=device-specs/specs-atmega168' '-mmcu=avr5'
 /srv/local/gnu/install/gcc-6/bin/../libexec/gcc/avr/6.3.1/collect2 -plugin /srv/local/gnu/install/gcc-6/bin/../libexec/gcc/avr/6.3.1/liblto_plugin.so -plugin-opt=/srv/local/gnu/install/gcc-6/bin/../libexec/gcc/avr/6.3.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccLCJimU.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lm -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-latmega168 -mavr5 -Tdata 0x800100 --relax /srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/../../../../avr/lib/avr5/crtatmega168.o -L/srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/avr5 -L/srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/../../../../avr/lib/avr5 -L/srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1 -L/srv/local/gnu/install/gcc-6/bin/../lib/gcc -L/srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/../../../../avr/lib /tmp/ccXAfFYs.o --start-group -lgcc -lm -lc -latmega168 --end-group
/srv/local/gnu/install/gcc-6/bin/../lib/gcc/avr/6.3.1/../../../../avr/bin/ld: BFD (GNU Binutils) 2.28.51.20170321 assertion fail ../../../source/binutils-master/bfd/elf32-avr.c:2145
collect2: error: ld returned 1 exit status
Comment 2 Georg-Johann Lay 2017-04-20 16:10:45 UTC
Created attachment 10000 [details]
bernd.elf.ltrans0.o
Comment 3 Georg-Johann Lay 2017-04-20 16:11:53 UTC
...and here is a direct ld call triggering the PR:

$ avr-ld bernd.elf.ltrans0.o -mavr5 --relax --defsym __tablejump2__=0
avr-ld: BFD (GNU Binutils) 2.28.51.20170321 assertion fail ../../../source/binutils-master/bfd/elf32-avr.c:2145
Comment 4 Senthil Kumar Selvaraj 2017-04-21 12:24:38 UTC
Created attachment 10004 [details]
Minimal testcase

This is caused by incorrect size adjustment of a symbol in certain situations when its size straddles an alignment boundary.
Comment 5 Senthil Kumar Selvaraj 2017-05-04 05:19:30 UTC
Fixed in master with this commit https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=b660e9eb7a45cfe99e719c5d16af35913a2fdc96

Not yet backported to 2.28, have requested approval.
Comment 6 Sourceware Commits 2017-05-11 07:18:06 UTC
The binutils-2_28-branch branch has been updated by Senthil Kumar Selvaraj <saaadhu@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e568fc190ac96d6ab427d018613361e03e4bd22b

commit e568fc190ac96d6ab427d018613361e03e4bd22b
Author: Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
Date:   Mon Apr 24 15:17:14 2017 +0530

    Fix PR21404 - assertion fail when calculating symbol size
    
    Fix a host of problems related to adjustment of
    symbol values and sizes when relaxing for avr.
    
    1. Adjust symbol size first before adjusting symbol
    value. Otherwise, a symbol whose value just got adjusted to the
    relaxed address also ends up getting resized. See pr21404-1.s.
    
    2. Reduce symbol sizes only if their span is below an
    alignment boundary. Otherwise, the size gets decremented once when the
    actual instruction is relaxed and padding bytes are added, and again
    when the padding bytes are deleted (if padding ends up being unnecessary).
    pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
    
    3. Adjust all symbol values before an alignment boundary.
    Previous code did not adjust symbol values if they fell in the
    would-be padded area, resulting in incorrect symbol values in some
    cases (see pr21404-3.s).
    
    4. Increase symbol sizes if alignment directives require so.
    As pr21404-4.s shows
    .global nonzero_sym
    L1:
        jmp  L1
    nonzero_sym:
        nop
        nop
        .p2align 2
    .size nonzero_sym, .-nonzero_sym
    
    The two nops satisfy the 4 byte alignment at assembly time and
    therefore the size of nonzero_sym is 4. Relaxation shortens
    the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
    the code places 2 extra padding bytes after the nops, increasing
    nonzero_sym's size by 2. This wasn't handled before.
    
    If the assembly code does not have any align directives, then the
    boundary is the section size, and symbol values and sizes == boundary
    should also get adjusted. To handle that case, add a did_pad variable
    and use that to determine whether it should use < boundary or <= boundary.
    
    Also get rid of reloc_toaddr, which is now redundant.  toaddr is now not
    adjusted to handle the above case - the newly added
    did_pad variable does the job.
    
    pr21404-{5,6,7,8} are the same testcases written for local symbols, as
    the code handles them slightly differently.
    
    bfd/ChangeLog
    2017-05-01  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
    
    	PR ld/21404
    	* elf32-avr.c (avr_should_move_sym): New function.
    	(avr_should_reduce_sym_size): Likewise.
    	(avr_should_increase_sym_size): Likewise.
    	(elf32_avr_relax_delete_bytes): Adjust symbol values
    	and sizes by calling new functions.
    
    ld/ChangeLog
    2017-04-28  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
    
    	PR ld/21404
    	* testsuite/ld-avr/pr21404-1.d: New test.
    	* testsuite/ld-avr/pr21404-1.s: New test.
    	* testsuite/ld-avr/pr21404-2.d: New test.
    	* testsuite/ld-avr/pr21404-2.s: New test.
    	* testsuite/ld-avr/pr21404-3.d: New test.
    	* testsuite/ld-avr/pr21404-3.s: New test.
    	* testsuite/ld-avr/pr21404-4.d: New test.
    	* testsuite/ld-avr/pr21404-4.s: New test.
    	* testsuite/ld-avr/pr21404-5.d: New test.
    	* testsuite/ld-avr/pr21404-5.s: New test.
    	* testsuite/ld-avr/pr21404-6.d: New test.
    	* testsuite/ld-avr/pr21404-6.s: New test.
    	* testsuite/ld-avr/pr21404-7.d: New test.
    	* testsuite/ld-avr/pr21404-7.s: New test.
    	* testsuite/ld-avr/pr21404-8.d: New test.
    	* testsuite/ld-avr/pr21404-8.s: New test.
Comment 7 Senthil Kumar Selvaraj 2017-05-12 04:53:03 UTC
Fixed in master and binutils-2_28-branch.