bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/16005] New: [avr] Linker crash on a particular instruction seque


From: konfera at efton dot sk
Subject: [Bug ld/16005] New: [avr] Linker crash on a particular instruction sequence with --relax
Date: Sat, 05 Oct 2013 12:02:26 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=16005

            Bug ID: 16005
           Summary: [avr] Linker crash on a particular instruction
                    sequence with --relax
           Product: binutils
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: ld
          Assignee: unassigned at sourceware dot org
          Reporter: konfera at efton dot sk

As reported in
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=136763 , the
linker for avr target crashes when trying to relax a rjmp/ret sequence.

The test case (crash.s):
main:
   nop
   rjmp main
   ret
   rjmp main 

>avr-as crash.s -o crash.o
>avr-ld --relax --debug-relax crash.o -o crash.elf

Observations:
1. this occurs on various builds ranging back 5 years, hosted both on Win and
Linux, although the visible symptoms vary, on some builds ld ends silently and
generates an empty output file

2. the second rjmp is not needed, a nop or any other instruction would do. In
fact, the observation is, that the error is not occuring if there is no
instruction after the ret

3. the target of rjmp is irrelevant, it can be any symbol

4. adding --debug-relax switch reveals more details: the error occurs as the
consequence of rjmp / ret detection and subsequent ret removal

>avr-ld --relax --debug-relax crash.o -o crash.elf
found rjmp / ret sequence at address 0x2
unreachable ret instruction at address 0x4 deleted.

This locates the error into bfd/elf32-avr.c:elf32_avr_relax_delete_bytes(),
being called just after the debug printout "unreachable ret instruction...
deleted".

5. Replacing the first rjmp by jmp or rcall results in normal linking. This is
interesting, because both the jmp/ret and rcall/ret sequences are in previous
relaxation iteration replaced by rjmp/ret sequence, thus then undergo the same
ret-removal procedure, which in this case is completed correctly:
main:
   nop
   rcall main
   ret
   rjmp main

>avr-as crash.s -o crash.o
>avr-ld --relax --debug-relax crash.o -o crash.elf
converted rcall/ret sequence at address 0x2 into rjmp/ret sequence. Section is
.
text

found rjmp / ret sequence at address 0x2
unreachable ret instruction at address 0x4 deleted.
Relocation at address 0x6 needs to be moved.
Old section offset: 0x6, New section offset: 0x4
Checking if the relocation's addend needs corrections.
Address of anchor symbol: 0x0
Address of relocation target: 0x0
Address of relaxed insn: 0x2
Checking if the relocation's addend needs corrections.
Address of anchor symbol: 0x0
Address of relocation target: 0x0
Address of relaxed insn: 0x2

---

Stepping through elf32_avr_relax_delete_bytes() for the original input file
results in crash in this line:

    memmove (contents + addr, contents + addr + count,
             (size_t) (toaddr - addr - count));

(which is conditionally executed only if there is anything to move, which btw.
matches observation 2). contents was found to be NULL. As previously in this
routine
 contents = elf_section_data (sec)->this_hdr.contents;
it's elf_section_data (sec) which is not properly set up.

Indeed, in the only other case when elf32_avr_relax_delete_bytes() is called
(in the jmp/call shrink branch of the relaxation loop), there are several lines
which might be relevant:

/* Note that we've changed the relocs, section contents,
                   etc.  */
                elf_section_data (sec)->relocs = internal_relocs;
                elf_section_data (sec)->this_hdr.contents = contents;
                symtab_hdr->contents = (unsigned char *) isymbuf;

Copying these three lines just before the other call to
elf32_avr_relax_delete_bytes() and recompiling the linker, appears to have
fixed the problem.

Unfortunately, I am not versed enough to judge, whether this is a proper fix to
the problem.

-- 
You are receiving this mail because:
You are on the CC list for the bug.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]