bug-binutils
[Top][All Lists]
Advanced

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

Re: Possible bugs in gnu assembler for IA64


From: Surbhi Chitre
Subject: Re: Possible bugs in gnu assembler for IA64
Date: Mon, 20 Oct 2008 12:05:49 +1100

Hi,

Here is  a pointer to the last bug mentioned in the first email..

as -v
GNU assembler version 2.18.0 (ia64-linux-gnu) using BFD version (GNU
Binutils for Debian) 2.18.0.20080103

uname -a
Linux lime 2.6.24-1-mckinley #1 SMP Sat Apr 19 00:19:28 UTC 2008 ia64
GNU/Linux


I have attached a file which explains the bug.

The bug is as follows: The label of a bundle does not work properly,
when the bundle is not in .text section

For eg :
.section "test"
.quad 1f
.quad 2f  
1:{
        nop 0x0
        nop 0x0
        nop 0x0
 }
2:{
        nop 0x0
        nop 0x0
        nop 0x0
}
.previous

Comment:
2: refers to the address of the first bundle rather than the second. 
This happens when the bundles are in a section other than the text
section. This can be confirmed by the objdump -D of the executable 
of this file. One can verify the contents of test section corresponding
to .quad 1f and .quad 2f - both of them seem to be the same,
when actually they should <some addr> and some <addr + 16>


Please refer to the file bug3.S

$  gcc bug3.S
$  objdump -D a.out 
Disassembly of section test1:

4000000000000780 <test1>:
4000000000000780:   a0 07 00 00 00 00   [MII] (p61) break.m 0x0
4000000000000786:   00 40 a0 07 00 00         data8 0x01e810000
400000000000078c:   00 00 00 40                dep r0=r0,r0,63,1
4000000000000790:   b0 07 00 00 00 00   [MIB] (p61) break.m 0x0
4000000000000796:   00 40 c0 07 00 00        data8 0x01f010000
400000000000079c:   00 00 00 40     br.few 4000000000000790 <_fini+0x30>
40000000000007a0:   10 00 00 00 01 00   [MIB]       nop.m 0x0
40000000000007a6:   00 00 00 02 00 00               nop.i 0x0
40000000000007ac:   00 00 40 00                     epc


Please refer to the contents at the locations 4000000000000780:
They are : a0 07 00 00 00 00 00 40 and a0 07 00 00 00 00 00 40
which is the starting address of the bundle containing epc.
Actually the contents should have been 
       a0 07 00 00 00 00 00 40
       b0 07 00 00 00 00 00 40

Hope this helps.

Thanks !

Warm Regards,
Surbhi.






                





On Mon, 2008-10-20 at 11:50 +1100, Surbhi Chitre wrote:
> Hi,
> 
> Here is a easier pointer to  bug2:
> 
> $ as -v
> GNU assembler version 2.18.0 (ia64-linux-gnu) using BFD version (GNU
> Binutils for Debian) 2.18.0.20080103 
> $ uname -a
> Linux lime 2.6.24-1-mckinley #1 SMP Sat Apr 19 00:19:28 UTC 2008 ia64
> GNU/Linux
> 
> 
> I have attached a file which contains the following:
> 
> +++++++++++++++++++++++++++++++++++++++++
> lime:~/TEST$ cat bug.S
> .global main
> .proc main
> main::
> .pushsection "test", "a", "progbits"
> .asciz "00000"
> .quad 0
> .quad 0
> .align(16)
> (p0) itc.i r1
> .popsection
> .align(16)
> .endp main
> 
> lime:~/TEST$ as bug.S
> lime:~/TEST$ objdump -D a.out 
> a.out:     file format elf64-ia64-little
> Disassembly of section test:
> 0000000000000000 <test>:
>    0:   30 30 30 30 30 00       [MIB] (p01) srlz.d
>         ...
>   1e:   00 00 0a 00                         break.i 0x0
>   22:   04 00 2f 04 00 00       [MMI]       itc.i r1;;
>   28:   00 02 00 00 00 00                   nop.m 0x0
>   2e:   04 00 00 00                         nop.i 0x0
> 
> Please note that itc.i r1;; starts at address 0x22, which is
> not 16 bytes aligned.
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 
> 
> Hope this helps!
> 
> Warm Regards,
> Surbhi.
> 
> 
> 
> 
> 
> 
> 
> 
> 
> On Mon, 2008-10-20 at 10:47 +1100, Surbhi Chitre wrote:
> > Hi,
> > 
> > Here is a easier pointer to the bug1:
> > 
> > $ as -v
> > GNU assembler version 2.18.0 (ia64-linux-gnu) using BFD version (GNU
> > Binutils for Debian) 2.18.0.20080103
> > 
> > $ uname -a
> > Linux lime 2.6.24-1-mckinley #1 SMP Sat Apr 19 00:19:28 UTC 2008 ia64
> > GNU/Linux
> > 
> > 
> > About the bug:
> > +++++++++++++++++++++++++++++++++++++++++++
> > I am attaching a small .S file. The objdump -D 
> > of its compiled version shows the error.
> > 
> > .macro emul_ptr_i pr=p0,va,sz
> >  .section "test", "a", "progbits"
> >         (\pr) ptr.i \va,\sz
> >  .previous
> >         (\pr) ptr.i \va,\sz
> >  .endm
> >  
> >  nop.m 0x0
> >  emul_ptr_i p1, r1, r2
> > 
> > Comment : both the ptr.i instructions go into the .text
> > section. The first instruction is supposed to go in 
> > the "test" section. 
> > _______________________________________
> > Disassembly of section .text:
> > 0000000000000000 <.text>:
> >    0:   01 00 00 00 01 00       [MII]       nop.m 0x0
> >    6:   00 00 00 02 00 00                   nop.i 0x0
> >    c:   00 00 04 00                         nop.i 0x0;;
> >   10:   29 00 08 02 0d 44       [MMI] (p01) ptr.i r1,r2
> >   16:   00 10 04 1a 08 00             (p01) ptr.i r1,r2
> >   1c:   00 00 04 00                         nop.i 0x0;;
> > _______________________________________
> > 
> > 
> > Putting a .align(16) before the instruction insertion in the 
> > "test" section and after the .popsection, helps in putting
> > the instructions in their respective sections.
> > 
> > 
> > .macro emul_ptr_i pr=p0,va,sz
> >  .section "test", "a", "progbits"
> >        .align(16)
> >       (\pr) ptr.i \va,\sz
> >  .previous
> >     .align(16)
> >         (\pr) ptr.i \va,\sz
> >  .endm
> >  
> >  nop.m 0x0
> >  emul_ptr_i p1, r1, r2
> > 
> > 
> > Hope this helps.
> > 
> > Warm Regards,
> > Surbhi.
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > On Thu, 2008-10-16 at 19:10 +1100, Surbhi C wrote:
> > > Hi,
> > > 
> > > I have attached a program with this email that can be used for proving
> > > the following cases which are some possible bugs in ia64-gnu-assembler:
> > > Here is what the tar.gz has
> > > 
> > > 1) elf.h
> > > 2) elfOps.c
> > > 3) elfOps.h
> > > 4) fileIO.c
> > > 5) fileIO.h
> > > 6) initDb.ld
> > > 7) initialize.S
> > > 8) Makefile
> > > 9) origLdScript.ld
> > > 10) orig.S
> > > 11) replaceAnnotated.h
> > > 12) replaceOrigCode.c
> > > 13) README
> > > 
> > > Here is some background on what the program does:
> > > make origElf creates a origElf file which has code to be replaced. 
> > > 
> > > 1) origElf has a section "afterburn" in it, which has annotation of 
> > > some instructions. The annotation includes, a string that identifies the
> > > instruction, address of a instruction, length upto which replacement
> > > should be done, how many arguments the instruction has, and if it has 
> > > arguments, then the original instruction. (The instructions which is
> > > annotated are really useles..and the code is arbitarily put in there..
> > > the annotation is not entirely relevant here... however ..the only
> > > important information is the address in the annotation). 
> > > 
> > > 2) replaceOrigCode (created after make replaceOrigCode) similarly has a
> > > annotated section, which has the annotation of the corresponding
> > > replacement code. The annotation is again a string that identifies the
> > > original instruction to be replaced, the corresponding address, the
> > > length, and some information about the arguments.  
> > > 
> > > 3) The replaceOrigCode.c shall read the annotation in the "afterburn"
> > > section from the origElf file. It shall then replace the instructions
> > > which are annotated in the origElf with the corresponding instructions 
> > > kept in its own elf image. However when a instruction has arguments, it
> > > reads the original instruction  kept in the "afterburn" section of the
> > > origFile and puts it at the address mentioned, along with other code
> > > from the replacement code in the  initialize.S. 
> > > 
> > > So basically, the aim is basically to replace some instructions or a
> > > block of code from origElf with some code kept in replaceOrigCode. 
> > > 
> > > While doing so, I encountered the following possible bugs in the
> > > ia64-gnu-assembler. The programs have a lot of printf statements which
> > > can be used to see that the contents of the annotated addresses changes
> > > with the way labelling is done and so on.
> > > 
> > > Here is some more information:
> > > 
> > > 1) Following is the output of "as -v"
> > > GNU assembler version 2.18.0 (ia64-linux-gnu) using BFD version (GNU
> > > Binutils for Debian) 2.18.0.20080103
> > > 
> > > 2) The output of uname -a is as follows:
> > > Linux torrone 2.6.15-1-mckinley-smp #2 SMP Mon Mar 6 17:47:45 UTC 2006
> > > ia64 GNU/Linux
> > > 
> > > 
> > > 
> > > ____________________________________________________________________________
> > > Possible Bug 1: 
> > > 
> > > Here is a scenario :
> > > 
> > > 
> > > Case1) 
> > > Contents of file named "test"
> > > ++++++++++++++++++++++++++++++++++
> > > .macro emul_ptr_i pr=p0,va,sz
> > > .section "afterburn", "a", "progbits"
> > > .asciz "ptr_i"
> > > .quad 3f
> > > .quad 1 // length of the macro
> > > .quad 2 // num of args
> > >      (\pr) ptr.i \va,\sz
> > > .previous
> > > [3:]        (\pr) ptr.i \va,\sz
> > > .endm
> > > 
> > > mov r2=r1
> > > emul_ptr_i p1, r1, r2
> > > ++++++++++++++++++++++++++++++++++++
> > > 
> > > >> as test
> > > >> objdump -D a.out
> > > a.out:     file format elf64-ia64-little
> > > 
> > > Disassembly of section .text:
> > > 
> > > 0000000000000000 <.text>:
> > >    0:   01 10 00 02 00 21       [MII]       mov r2=r1
> > >    6:   00 00 00 02 00 00                   nop.i 0x0
> > >    c:   00 00 04 00                         nop.i 0x0;;
> > >   10:   29 00 08 02 0d 44       [MMI] (p01) ptr.i r1,r2
> > >   16:   00 10 04 1a 08 00             (p01) ptr.i r1,r2
> > >   1c:   00 00 04 00                         nop.i 0x0;;
> > > Disassembly of section afterburn:
> > > 
> > > 0000000000000000 <afterburn>:
> > >    0:   70 74 72 5f 69 00       [MIB]       data8 0x34afb93a3
> > >    6:   00 00 00 00 00 00                   break.i 0x0
> > >    c:   00 00 00 00                         break.b 0x0
> > >   10:   01 00 00 00 00 00       [MII]       break.m 0x0
> > >   16:   00 00 02 00 00 00                   break.i 0x2000
> > >   1c:   00 00 00 00                         break.i 0x0;;
> > > 
> > > 
> > > Comments: Both the ptr.i are going in the .text section, even when we
> > > have a .section directive which says that the first ptr.i should go in
> > > to the afterburn section
> > > 
> > > ____________________________________________________
> > > 
> > > Case 2: 
> > > Contents of file named "test"
> > > ++++++++++++++++++++++++++++++++++
> > > .macro emul_ptr_i pr=p0,va,sz
> > > .section "afterburn", "a", "progbits"
> > > .asciz "ptr_i"
> > > .quad 3f
> > > .quad 1 // length of the macro
> > > .quad 2 // num of args
> > >     (\pr) ptr.i \va,\sz
> > > .previous
> > > .previous
> > > [3:]        (\pr) ptr.i \va,\sz
> > > .endm
> > > 
> > > mov r2=r1
> > > emul_ptr_i p1, r1, r2
> > > ++++++++++++++++++++++++++++++++++++
> > > 
> > > >> as test
> > > >> objdump -D a.out
> > > 
> > > a.out:     file format elf64-ia64-little
> > > 
> > > Disassembly of section .text:
> > > 
> > > 0000000000000000 <.text>:
> > >    0:   01 10 00 02 00 21       [MII]       mov r2=r1
> > >    6:   00 00 00 02 00 00                   nop.i 0x0
> > >    c:   00 00 04 00                         nop.i 0x0;;
> > > Disassembly of section afterburn:
> > > 
> > > 0000000000000000 <afterburn>:
> > >    0:   70 74 72 5f 69 00       [MIB]       data8 0x34afb93a3
> > >    6:   00 00 00 00 00 00                   break.i 0x0
> > >    c:   00 00 00 00                         break.b 0x0
> > >   10:   01 00 00 00 00 00       [MII]       break.m 0x0
> > >   16:   00 00 02 00 00 00                   break.i 0x2000
> > >   1c:   00 00 00 00                         break.i 0x0;;
> > >   20:   21 00 08 02 0d 04       [MII] (p01) ptr.i r1,r2
> > >   26:   00 00 00 02 00 00                   nop.i 0x0
> > >   2c:   00 00 04 00                         nop.i 0x0;;
> > >   30:   21 00 08 02 0d 04       [MII] (p01) ptr.i r1,r2
> > >   36:   00 00 00 02 00 00                   nop.i 0x0
> > >   3c:   00 00 04 00                         nop.i 0x0;
> > > 
> > > Comments : Both the ptr.i are going in the .afterburn section !!
> > > even when we have a .section directive !
> > > 
> > > 
> > > Case 3: 
> > > Contents of file named "test"
> > > ++++++++++++++++++++++++++++++++++
> > > .macro emul_ptr_i pr=p0,va,sz
> > > .section "afterburn", "a", "progbits"
> > > .asciz "ptr_i"
> > > .quad 3f
> > > .quad 1 // length of the macro
> > > .quad 2 // num of args
> > >      (\pr) ptr.i \va,\sz
> > > .previous
> > > .previous
> > > .previous
> > > [3:]        (\pr) ptr.i \va,\sz
> > > .endm
> > > 
> > > mov r2=r1
> > > emul_ptr_i p1, r1, r2
> > > ++++++++++++++++++++++++++++++++++++
> > > 
> > > >> as test
> > > >> objdump -D a.out
> > > a.out:     file format elf64-ia64-little
> > > 
> > > Disassembly of section .text:
> > > 
> > > 0000000000000000 <.text>:
> > >    0:   01 10 00 02 00 21         [MII]       mov r2=r1 
> > >    6:   00 00 00 02 00 00                   nop.i 0x0
> > >    c:   00 00 04 00                         nop.i 0x0;;
> > >   10:   21 00 08 02 0d 04         [MII] (p01) ptr.i r1,r2
> > >   16:   00 00 00 02 00 00                   nop.i 0x0
> > >   1c:   00 00 04 00                         nop.i 0x0;;
> > > Disassembly of section afterburn:
> > > 
> > > 0000000000000000 <afterburn>:
> > >    0:   70 74 72 5f 69 00       [MIB]       data8 0x34afb93a3
> > >    6:   00 00 00 00 00 00                   break.i 0x0
> > >    c:   00 00 00 00                         break.b 0x0
> > >   10:   01 00 00 00 00 00       [MII]       break.m 0x0
> > >   16:   00 00 02 00 00 00                   break.i 0x2000
> > >   1c:   00 00 00 00                         break.i 0x0;;
> > >   20:   21 00 08 02 0d 04       [MII] (p01) ptr.i r1,r2
> > >   26:   00 00 00 02 00 00                   nop.i 0x0
> > >   2c:   00 00 04 00                         nop.i 0x0;;
> > > 
> > > Comments : This works like a charm !! 
> > > My understanding of the ideal case goes like this :
> > > 
> > > 1) .section directive lets you stack upto 10 sections.
> > > 
> > > .text       /* current section is .text */
> > > .section "afterburn" /* current section is .afterburn */
> > > .previous /* should make current section as .text */
> > > .previous /* should make afterburn, the current section */
> > > .previous /* should make .text, the current section */
> > > 
> > > 
> > > If we have the following scenario:
> > > .text
> > > .A
> > > .B
> > > .C
> > > .previous /* current section is C */
> > > .previous /* current section is B */
> > > .previous /* Current section is A 
> > > .previous /* current section is .text */
> > > .previous /* current section is A */
> > > .previous /* current section is B */ 
> > > .previuos /* current section is C */
> > > 
> > > The same argument applies for .pushsection and .popsection directives.
> > > ____________________________________________________________________________
> > > 
> > > Possible Bug 2:
> > > 
> > > .align(16) 
> > > If this is used in before inserting the instruction in some section and
> > > after the .popsection directive then, the data and instructions get
> > > inserted in the correct section. For eg:
> > > 
> > > .macro emul_ptr_i pr=p0,va,sz
> > > .pushsection "afterburn", "a", "progbits"
> > > .asciz "ptr_i"
> > > .quad 3f
> > > .quad 1 // length of the macro
> > > .quad 2 // num of args
> > > .align(16)
> > >     (\pr) ptr.i \va,\sz
> > > .popsection
> > > .align(16)
> > > [3:]        (\pr) ptr.i \va,\sz
> > > 
> > > Then this works fine. Now the problem is, .align(16) adds 16 more bytes,
> > > even when the location counter is divisible by 16. Furthermore, this is
> > > not always the case. Should not .align(16) add *upto 16 bytes only when
> > > the location counter is not divisible by 16 bytes to make it 16byte
> > > aligned ?
> > > 
> > > You can see this in orig.S wherein we have added a bundle containing
> > > nops before adding the instruction, so that the 16bytes are accounted
> > > for, when the assembler does not add the 16 bytes.
> > > For eg:  One can see in the orig.S : 
> > > 
> > > .align(16)
> > > nop.m 0x0
> > > nop.i 0x0
> > > nop.b 0x0
> > > (p1) mov r2 = b2
> > > .popsection
> > > .align(16)
> > > 
> > > ____________________________________________________________________________
> > > 
> > > Possible Bug 3: 
> > >   
> > >  34:   (p0) nop.i 0x0
> > >        (p0) nop.i 0x0
> > >        (p0) nop.m 0x0
> > > 35: {.mii
> > >     (p0) fc r2  //src = r2
> > >     (p0) nop.i 0x0
> > >     (p0) nop.i 0x0
> > > }
> > > 
> > > Here 35b or 35f fetches the address of the previous bundle (the bundle
> > > marked with label 34 !) Hence to avert this , the following needs to be
> > > done: 
> > > 
> > >     (p0) mov r2 = ar2  //dst=r2, kr=2
> > >     (p0) nop.i 0x0
> > >     (p0) nop.i 0x0
> > >     (p0) nop.m 0x0
> > > 34:
> > > 
> > > {.mii
> > >     (p0) fc r2  //src = r2
> > >     (p0) nop.i 0x0
> > >     (p0) nop.i 0x0
> > > 35:
> > > }
> > > 
> > > Please verify this by changing the labeling as the above case in
> > > initialize.S in the program given. Currently the labelling is done
> > > as shown in the second method above (i.e at the end of the bundle)
> > > Surprisingly, the labeling works fine in the other orig.S file
> > > but not in the initialize.S.
> > > 
> > > __________________________________________________________________________________
> > > 
> > > 
> > > After running the programs, by doing a "make run", we can see that the 
> > > replacement is performed. However, for doing so, we have to insert
> > > a bundle at places where .align(16) does not add 16 bytes or 
> > > put .align (in the first place) to get the instruction in the correct
> > > section, change the way the labels work...!! 
> > > 
> > > The program is attached, just to show the possible reasons, why someone
> > > might need to put data and instruction in the same section and also
> > > illustrate the deviation from the expected behaviour of the assembler.
> > > 
> > > If there is any more information that anyone needs, please
> > > email me back.
> > > 
> > > Thanks !
> > > 
> > > Warm Regards,
> > > Surbhi.
> > > 

Attachment: bug3.S
Description: Text document


reply via email to

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