bug-binutils
[Top][All Lists]
Advanced

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

Possible bugs in gnu assembler for IA64


From: Surbhi C
Subject: Possible bugs in gnu assembler for IA64
Date: Thu, 16 Oct 2008 19:10:07 +1100

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: TEST.tar.gz
Description: application/compressed-tar


reply via email to

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