|Summary:||Incorrect opcode in __do_clear_bss if bss has more than 15 bytes|
|Product:||binutils||Reporter:||Ken Jackson <KenJackson>|
Description Ken Jackson 2006-02-21 21:11:56 UTC
Sixteen or more bytes of uninitialized data will cause ld to generate an incorrect opcode in __do_clear_bss in the startup for the avr target as shown in this example. Source file, a.S: .comm x,16,1 .global __do_copy_data .global __do_clear_bss .global main main: cpi r26,lo8(16) rjmp main Compile script: FLAGS="-m avr4 -Tdata 0x800100 -L/usr/local/lib/gcc/avr/4.0.2/avr4" avr-as a.S -o a.o avr-ld $FLAGS -o a.hex /usr/local/avr/lib/avr4/crtm88.o --oformat=ihex \ a.o -lgcc -lc avr-ld $FLAGS -o a.elf /usr/local/avr/lib/avr4/crtm88.o a.o -lgcc -lc avr-objdump -dSCg a.elf > a.lst Output a.lst, lines 68,69,77,78: 00000060 <.do_clear_bss_start>: 60: a0 31 cpi r26, 0x10 ; 16 0000006a <main>: 6a: a0 31 cpi r26, 0x10 ; 16 Output a.hex, lines 8,11: :100056001160A0E1B16001C01D92B031B107E1F7B6 :04006A00A031FECFF4 The listing is correct for both cpi instructions, "a0 31", but the hex file is wrong for the first, "B031", though it's correct for the second, "A031". And, indeed, test programs fail to execute on real hardware with 16 or more bytes of BSS, but _do_ execute with less. The first cpi instruction is in function __do_clear_bss in source file gcc-4.0.2/gcc/config/avr/libgcc.S. But gcc itself doesn't seem be be involved, other than supplying the code, which is assembled by avr-as (or directly by avr-ld?). It's not clear how the hex is generated or where the error occurs. I'm using Mandriva Linux 2006 (2.6.12-12mdk) and compiled from source binutils-2.16.1, gcc-4.0.2, and avr-libc-1.4.3. $ avr-ld -V GNU ld version 2.16.1 Supported emulations: avr2 avr1 avr3 avr4 avr5 Note: I thank everyone that works on binutils.
Comment 1 Ken Jackson 2006-02-22 14:52:31 UTC
I've simplified it by stripping away all gcc influence. This is purely a binutils bug. I suspect it is ld's relocation that is causing the problem. Or maybe it's the BFD library, if that's a separate entity. Source file, a.S: .comm x,16,1 .global main main: cpi r26,lo8(__bss_end) cpi r26,lo8(16) Compile script: avr-as a.S -o a.o avr-ld -m avr4 -Tdata 0x800100 -o a.elf a.o avr-objdump -d a.elf > a.lst avr-ld -m avr4 -Tdata 0x800100 -o a.hex --oformat=ihex a.o Output file a.lst, lines 7,8: 0: a0 31 cpi r26, 0x10 ; 16 2: a0 31 cpi r26, 0x10 ; 16 Output file a.hex: :04000000B031A0314A :00000001FF The list file shows both opcodes correctly, "a0 31". But in the hex file the first one is wrong, "B031", while the second one is correct, "A031". The difference is that avr-ld had to do a relocation for the first one. Running "avr-objdump -r a.o" shows one record with type R_AVR_LO8_LDI relocation, value __bss_end. R_AVR_LO8_LDI is performed in binutils-2.16.1/bfd/elf32-avr.c. It works correctly for the default ELF format, but fails for the IHEX format. This is progress, but I'm still stumped.
Comment 2 Nick Clifton 2006-02-28 11:57:50 UTC
Subject: Re: Incorrect opcode in __do_clear_bss if bss has more than 15 bytes Hi Ken, > avr-as a.S -o a.o > avr-ld -m avr4 -Tdata 0x800100 -o a.elf a.o > avr-objdump -d a.elf > a.lst > avr-ld -m avr4 -Tdata 0x800100 -o a.hex --oformat=ihex a.o > The list file shows both opcodes correctly, "a0 31". But in the hex file > the first one is wrong, "B031", while the second one is correct, "A031". > > The difference is that avr-ld had to do a relocation for the first one. > Running "avr-objdump -r a.o" shows one record with type R_AVR_LO8_LDI > relocation, value __bss_end. > > R_AVR_LO8_LDI is performed in binutils-2.16.1/bfd/elf32-avr.c. It works > correctly for the default ELF format, but fails for the IHEX format. > > This is progress, but I'm still stumped. It is quite common that LD is unable to correctly translate binary file formats and link at the same time. Quite a few targets suffer from this problem. The simplest workaround is to perform the link first and then use objcopy to perform the binary translation. ie: avr-ld -m avr4 -Tdata 0x800100 -o a.elf a.o avr-objcopy --output-target ihex a.elf a.ihex Cheers Nick
Comment 3 Ken Jackson 2006-02-28 13:49:46 UTC
Thank you Nick. Someone at avrfreaks gave me the same information. I meant to update the bug, but didn't get to it. It's still a bug, because the documented capability does not work. This cost me nearly two weeks of frustration, and may do the same to others. But it's clearly a low priority because avr-objcopy works.
Comment 4 Ben Elliston 2006-04-04 01:57:05 UTC
Comment 5 Eric Weddington 2010-09-20 02:54:05 UTC
Resolving bug as WONTFIX. This is an old bug. Standard operating procedure on AVR is to link first, then use objcopy to convert to other formats. Plus the user should call the assembler and linker through avr-gcc.