Bug 20221 - [avr] Wrong code generated with linker relaxation for source with alignment directives
Summary: [avr] Wrong code generated with linker relaxation for source with alignment d...
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.27
: P2 normal
Target Milestone: ---
Assignee: Senthil Kumar Selvaraj
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-06-08 08:46 UTC by Senthil Kumar Selvaraj
Modified: 2016-10-11 10:04 UTC (History)
1 user (show)

See Also:
Host:
Target: avr
Build:
Last reconfirmed: 2016-10-11 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Senthil Kumar Selvaraj 2016-06-08 08:46:11 UTC
$ cat avr-prop-5.s
        .text
        .global _start, dest
_start:
        CALL    dest
        .align  1
dest:
        NOP

when assembled with -mlink-relax and linked with --relax

$ avr-gcc -mrelax -mmcu=atmega1280 -Os avr-prop-5.s -nostartfiles
$ avr-objdump -S a.out


a.out:     file format elf32-avr


Disassembly of section .text:

00000000 <__ctors_end>:
   0:	ff df       	rcall	.-2      	; 0x0 <__ctors_end>

00000002 <dest>:
	...

Note that the rcall offset is wrong - it's calling 0x0 rather than calling dest (0x2). Disabling relaxation results in correct code

$ avr-gcc -mno-relax -mmcu=atmega1280 -Os avr-prop-5.s -nostartfiles
$ avr-objdump -S a.out

a.out:     file format elf32-avr


Disassembly of section .text:

00000000 <__ctors_end>:
   0:	0e 94 02 00 	call	0x4	; 0x4 <dest>

00000004 <dest>:
	...
Comment 1 Sourceware Commits 2016-06-09 16:20:04 UTC
The master branch has been updated by Denis Chertykov <denisc@sourceware.org>:

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

commit 5c41dbc302c2dd87e201e4fd1d9ae3186f6e51a0
Author: Denis Chertykov <chertykov@gmail.com>
Date:   Thu Jun 9 19:17:43 2016 +0300

    Fix PR 20221 - adjust syms and relocs only if relax shrunk section.
    
    This patch fixes an edge case in linker relaxation that causes symbol
    values to be computed incorrectly in the presence of align directives
    in input source code.
    
    bfd/
    	* elf32-avr.c (elf32_avr_relax_delete_bytes): Adjust syms
    	and relocs only if shrinking occurred.
    
    ld/
    	* testsuite/ld-avr/avr-prop-5.d: New.
    	* testsuite/ld-avr/avr-prop-5.s: New.
Comment 2 Senthil Kumar Selvaraj 2016-06-10 17:36:41 UTC
There's another related testcase that fails even with or without the current fix in master. It fails on binutils-2_26 branch too.

.text
.global _start, dest
_start: 
  jmp dest
  .align	1
dest:
  nop
  rjmp dest


With 

$ avr-gcc -mmcu=atmega1280 -Os -mrelax test.s -nostartfiles
$ avr-objdump -S a.out

00000000 <__ctors_end>:
   0:	00 c0       	rjmp	.+0      	; 0x2 <dest>

00000002 <dest>:
   2:	00 00       	nop
   4:	00 c0       	rjmp	.+0      	; 0x6 <_etext>

which is obviously wrong.
Comment 3 Sourceware Commits 2016-06-13 12:39:19 UTC
The binutils-2_26-branch branch has been updated by Senthil Kumar Selvaraj <saaadhu@sourceware.org>:

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

commit b3ec896b257ceb9765c1dd8667673c63ce5330c2
Author: Denis Chertykov <chertykov@gmail.com>
Date:   Thu Jun 9 19:17:43 2016 +0300

    Fix PR 20221 - adjust syms and relocs only if relax shrunk section.
    
    This patch fixes an edge case in linker relaxation that causes symbol
    values to be computed incorrectly in the presence of align directives
    in input source code.
    
    bfd/
    	* elf32-avr.c (elf32_avr_relax_delete_bytes): Adjust syms
    	and relocs only if shrinking occurred.
    
    ld/
    	* testsuite/ld-avr/avr-prop-5.d: New.
    	* testsuite/ld-avr/avr-prop-5.s: New.
Comment 4 Senthil Kumar Selvaraj 2016-10-11 10:04:12 UTC
Fixed in trunk and backported to 2.26 a while back