This is sources Bugzilla
Bugzilla Version 2.17.5
Bugzilla Bug 2378
  Incorrect opcode in __do_clear_bss if bss has more than 15 bytes Last modified: 2006-09-01 20:44:58
     Query page      Enter new bug
Bug#: 2378   Hardware:   Reporter: Ken Jackson <KenJackson@ieee.org>
Host: Target: Build:
Product:     Add CC:
Component:   Version:   CC:
Remove selected CCs
Status: NEW   Priority:  
Resolution:   Severity:  
Assigned To: unassigned@sources.redhat.com   Target Milestone:  
Summary:
Keywords:

Attachment Description Type Created Actions
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 2378 depends on: Show dependency tree
Show dependency graph
Bug 2378 blocks:

Additional Comments:


Leave as NEW 
Mark bug as waiting for feedback
Mark bug as suspended
Accept bug (change status to ASSIGNED)
Resolve bug, changing resolution to
Resolve bug, mark it as duplicate of bug #
Reassign bug to
Reassign bug to owner of selected component

View Bug Activity   |   Format For Printing


Description:   Last confirmed: 0000-00-00 00:00 Opened: 2006-02-21 21:11
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.

------- Additional Comment #1 From Ken Jackson 2006-02-22 14:52 -------
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.

------- Additional Comment #2 From Nick Clifton 2006-02-28 11:57 -------
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



------- Additional Comment #3 From Ken Jackson 2006-02-28 13:49 -------
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.

------- Additional Comment #4 From Ben Elliston 2006-04-04 01:57 -------
Updating priority.

     Query page      Enter new bug
Actions: New | Query | bug # | Reports | Requests   New Account | Log In