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 10:47:13 +1100

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: bug1.S
Description: Text document


reply via email to

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