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