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.
TEST.tar.gz
Description: application/compressed-tar
_______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils