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. >
.macro emul_ptr_i pr,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
_______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils