[Top][All Lists]
[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 11:50:18 +1100 |
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.
> >
bug2.S
Description: Text document