Prev: Sudoku
Next: Linux distro request
From: Frank Kotler on 10 Apr 2008 03:00 Chuck Crayne wrote: > On Thu, 10 Apr 2008 02:43:34 GMT > Frank Kotler <fbkotler(a)verizon.net> wrote: > >> Okay... on their way... > > To my surprise, it fails (Killed) on my system. So much for my kernel > bug has been fixed theory. However, I have a new theory. Perhaps you > remember a discussion on the Nasm-devel list in which hpa informed me > that the Red Hat Nasm RPM contained a patch to the outelf code, and > that I fixed the code so that the Red Hat patch was no longer needed. Only vaguely... you've fixed a *lot* of stuff! > Well, it appears to me that Slackware 12.0 does not have that patch. Correct - comes with 0.98.39, and I haven't upgraded yet. > The symbol table for the object module which you sent me looks like > this: [snip] > Although the linker has deleted the bogus ABS section symbol, it has > moved the file symbol from #1, where it belongs, to a position after > the section symbols -- which is a violation of the ELF standard. Oh, oh! Bad Nasm after all... maybe... > According to the change log, my fix appeared in 0.99.06, so, if you > feel like exploring this any further, I suggest that you test it with > that, or any later, version. I will do that. In view of your discovery, this may be pointless, but I've got a "working one" and a broken one that differ by a nop. The good one: global _start section .bss i resb 1 section .text _start: mov byte [i], 41h mov eax, 4 mov ebx, 1 mov ecx, i mov edx, 1 int 80h mov byte [i], 31h push byte 4 pop eax int 80h mov eax, 1 int 80h And for Herbert... the bytes... 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 80 80 04 08 34 00 00 00 C8 00 00 00 00 00 00 00 34 00 20 00 02 00 28 00 04 00 03 00 01 00 00 00 00 00 00 00 00 80 04 08 00 80 04 08 B0 00 00 00 B0 00 00 00 05 00 00 00 00 10 00 00 01 00 00 00 B0 00 00 00 B0 90 04 08 B0 90 04 08 00 00 00 00 04 00 00 00 06 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6 05 B0 90 04 08 41 B8 04 00 00 00 BB 01 00 00 00 B9 B0 90 04 08 BA 01 00 00 00 CD 80 C6 05 B0 90 04 08 31 6A 04 58 CD 80 B8 01 00 00 00 CD 80 00 2E 73 68 73 74 72 74 61 62 00 2E 74 65 78 74 00 2E 62 73 73 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0B 00 00 00 01 00 00 00 06 00 00 00 80 80 04 08 80 00 00 00 30 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 11 00 00 00 08 00 00 00 03 00 00 00 B0 90 04 08 B0 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 01 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 B0 00 00 00 16 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 And the bad one: global _start ; nasm -f elf killme2.asm ; ld -o killme2 killme2.o section .bss i resb 1 section .text _start: mov byte [i], 41h mov eax, 4 mov ebx, 1 mov ecx, i mov edx, 1 int 80h mov byte [i], 31h push byte 4 pop eax nop ; killer nop :) int 80h mov eax, 1 int 80h And its bytes: 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 80 80 04 08 34 00 00 00 C8 00 00 00 00 00 00 00 34 00 20 00 02 00 28 00 04 00 03 00 01 00 00 00 00 00 00 00 00 80 04 08 00 80 04 08 B1 00 00 00 B1 00 00 00 05 00 00 00 00 10 00 00 01 00 00 00 B1 00 00 00 B4 90 04 08 B4 90 04 08 00 00 00 00 04 00 00 00 06 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6 05 B4 90 04 08 41 B8 04 00 00 00 BB 01 00 00 00 B9 B4 90 04 08 BA 01 00 00 00 CD 80 C6 05 B4 90 04 08 31 6A 04 58 90 CD 80 B8 01 00 00 00 CD 80 00 2E 73 68 73 74 72 74 61 62 00 2E 74 65 78 74 00 2E 62 73 73 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0B 00 00 00 01 00 00 00 06 00 00 00 80 80 04 08 80 00 00 00 31 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 11 00 00 00 08 00 00 00 03 00 00 00 B4 90 04 08 B1 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 01 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 B1 00 00 00 16 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 Those are both assembled with "nasm -f elf myfile.asm", linked with "ld -o myfile myfile.o" and stripped with "strip -R.comment myfile". (Stripping them didn't seem to make any difference... and it makes the post shorter...) FWIW, I tried a couple of files by "Herbert's method", a simple "hello world", one "just like Ivan's" (more or less), and the program that produced the hex dumps, and they all worked fine. Other investigation shows that I apparently trashed the partition table on my "good" drive... "fdisk /dev/hdc" shows the same partitions as "fdisk /dev/hdb"... the one with the new kernel on it - one dos partition, one linux, and one swap. There's no dos partition on /dev/hdc, or there *wasn't*... The backups in the /boot directory... one of 'em's close, but no cigar - the other two are 512 zeros... :( My current thinking is to repartition it as a bigger Linux partition than there probably was, and a smaller swap partition. Probably still won't boot, but maybe I can save some stuff off it... I should write this stuff down... but then I wouldn't be able to find the paper... I tried loadlin under dos, and it works as slick as I remember (and the source is in asm, too!!!), so I'll give lilo a rest for a while. What is it they say about "experience is that thing you get right after you need it"? Best, Frank
From: Herbert Kleebauer on 10 Apr 2008 07:49 Frank Kotler wrote: > Oh, oh! Bad Nasm after all... maybe... > > > According to the change log, my fix appeared in 0.99.06, so, if you > > feel like exploring this any further, I suggest that you test it with > > that, or any later, version. > > I will do that. In view of your discovery, this may be pointless, but > I've got a "working one" and a broken one that differ by a nop. The good > one: Your second program also crashes here. Seems the calculation of the start of the data section is wrong. Don't know if this is a bug NASM or ld. The correct calculation would be: even 4 @=(@+4095)/4096*4096+(@@\4096) data_offset=@@ data_addr: But it does: @=(@+3)/4*4 @@1=(@@+3)/4*4 @=(@+4095)/4096*4096+(@@1\4096) data_offset=@@ data_addr: In the case that the code segment size is a multiple of 4 (as in your first program) this is the same. Add an "align 4" at the end of your code and it should work. Here the source code of your posted binaries: seg32 @=$08048000 code_offset=@@ code_addr: ;--------------------------- ELF header ----------------------------------- dc.l $464c457f,$00010101,0,0,$00030002,1,main,$34,$c8,0,$00200034,$00280002,$00030004 dc.l 1,code_offset,code_addr,code_addr,code_filez,code_memsz,5,4096 dc.l 1,data_offset,data_addr,data_addr,data_filez,data_memsz,6,4096 ;--------------------------- code ------------------------------------------ even 16 main: move.b #$41,i move.l #$00000004,r0 move.l #$00000001,r3 move.l #i,r2 move.l #$00000001,r1 trap #$80 move.b #$31,i moveq.l #$04,-(sp) move.l (sp)+,r0 trap #$80 move.l #$00000001,r0 trap #$80 ;--------------------------- constant data --------------------------------- ;--------------------------------------------------------------------------- code_filez=@@-code_offset code_memsz= @-code_addr even 4 @=(@+4095)/4096*4096+(@@\4096) data_offset=@@ data_addr: ;--------------------------- initialized data ------------------------------ ;--------------------------- uninitialized data ---------------------------- i: blk.l 1 ;--------------------------------------------------------------------------- data_filez=@@-data_offset data_memsz= @-data_addr dc.b 0,".shstrtab",0,".text",0,".bss",0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,$0b dc.l 1,6,$08048080,$80,$30,0,0,$10,0,$11,$08 dc.l $03,$080490b0,$b0,$04,0,0,$04,0,$01,$03 dc.l 0,0,$b0,$16,0,0,1,0 seg32 @=$08048000 code_offset=@@ code_addr: ;--------------------------- ELF header ----------------------------------- dc.l $464c457f,$00010101,0,0,$00030002,1,main,$34,$c8,0,$00200034,$00280002,$00030004 dc.l 1,code_offset,code_addr,code_addr,code_filez,code_memsz,5,4096 dc.l 1,data_offset,data_addr,data_addr,data_filez,data_memsz,6,4096 ;--------------------------- code ------------------------------------------ even 16 main: move.b #$41,i move.l #$00000004,r0 move.l #$00000001,r3 move.l #i,r2 move.l #$00000001,r1 trap #$80 move.b #$31,i moveq.l #$04,-(sp) move.l (sp)+,r0 nop trap #$80 move.l #$00000001,r0 trap #$80 ;--------------------------- constant data --------------------------------- ;--------------------------------------------------------------------------- code_filez=@@-code_offset code_memsz= @-code_addr ; even 4 ; @=(@+4095)/4096*4096+(@@\4096) @=(@+3)/4*4 @@1=(@@+3)/4*4 @=(@+4095)/4096*4096+(@@1\4096) data_offset=@@ data_addr: ;--------------------------- initialized data ------------------------------ ;--------------------------- uninitialized data ---------------------------- i: blk.l 1 ;--------------------------------------------------------------------------- data_filez=@@-data_offset data_memsz= @-data_addr dc.b 0,".shstrtab",0,".text",0,".bss",0,0 dc.l 0,0,0,0,0,0,0,0,0,0,$0b dc.l 1,6,$08048080,$80,$31,0,0,$10,0,$11,$08 dc.l $03,$080490b4,$b1,$04,0,0,$04,0,$01,$03 dc.l 0,0,$b1,$16,0,0,1,0
From: Chuck Crayne on 11 Apr 2008 21:38 On Thu, 10 Apr 2008 07:00:06 GMT Frank Kotler <fbkotler(a)verizon.net> wrote: > I will do that. In view of your discovery, this may be pointless, but > I've got a "working one" and a broken one that differ by a nop. The > good one: Thanks to you cleverly constructed examples, I have discovered the proximate cause of the failure. If you compare the PLT entries in the two cases with your favorite elf tool, you will see that the second entries each case look like this: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x0000b0 0x080490b0 0x080490b0 0x00000 0x00004 RW 0x1000 (good) LOAD 0x0000b1 0x080490b4 0x080490b4 0x00000 0x00004 RW 0x1000 (bad) According to the elf man page, "Loadable process segments must have congruent values for p_vaddr and p_offset, modulo the page size." This condition is met by the good case, but, when you added the nop, the file offset increased by one byte, but the virtual address increased by four bytes, creating an alignment error. Without seeing the corresponding object file, I can't tell whether it was NASM or the linker which was at fault. You can test that this really is the problem, by changing the byte at file offset 58h from 0b1h to 0b4h. [The other places where 0b1h appears are correct, and should not be changed.] -- Chuck http://www.pacificsites.com/~ccrayne/charles.html
From: Frank Kotler on 12 Apr 2008 11:51 Chuck Crayne wrote: > On Thu, 10 Apr 2008 07:00:06 GMT > Frank Kotler <fbkotler(a)verizon.net> wrote: > >> I will do that. In view of your discovery, this may be pointless, but >> I've got a "working one" and a broken one that differ by a nop. The >> good one: > > Thanks to you cleverly constructed examples, I have discovered the > proximate cause of the failure. If you compare the PLT entries in the > two cases with your favorite elf tool, you will see that the second > entries each case look like this: > > Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align > LOAD 0x0000b0 0x080490b0 0x080490b0 0x00000 0x00004 RW 0x1000 (good) > LOAD 0x0000b1 0x080490b4 0x080490b4 0x00000 0x00004 RW 0x1000 (bad) > > According to the elf man page, "Loadable process segments must have > congruent values for p_vaddr and p_offset, modulo the page size." This > condition is met by the good case, but, when you added the nop, the > file offset increased by one byte, but the virtual address increased by > four bytes, creating an alignment error. Without seeing the > corresponding object file, I can't tell whether it was NASM or the > linker which was at fault. > > You can test that this really is the problem, by changing the byte at > file offset 58h from 0b1h to 0b4h. [The other places where 0b1h appears are > correct, and should not be changed.] Yup! Since I don't have any toys installed, I had to write my own. Almas would be proud of me - only took two tries before I got it right! (increment the counter *after* the test... Duh!) As Herbert observes, an "align 4" at the end of the .text section also fixes it. I have a still simpler example: global _start section .text _start: mov eax, 1 mov bl, 42 int 80h align 4 section .bss dummy resb 1 Without the "align 4", it gets killed. Also *this* example: ..globl _start ..text _start: movl $1, %eax movb $42, %bl int $0x80 #.align 4 ..bss .byte 0 So, if it's a "Nasm bug", Gas has the same problem... I hadn't the wit to try an old ld, while I was "there". Why do I always think of what I "shouldda" done right *after* I reboot? Well... I'm gettin' used to it. Since Nasm aligns anything but an "arbitrary" section, it wouldn't "cost" anything (in size) to throw in an "align" at the end of the ".text" section by default, right? (The way Herbert does it. *Told* ya he doesn't miss much! Who says throwing dwords into the file isn't the correct way to make an ELF executable? At least we know the bug, if any, isn't in ld! ... wonder why that didn't work for Ivan?) "BRB" means "boot, reboot, boot" right? BRB, Frank
From: Chuck Crayne on 12 Apr 2008 17:08
On Sat, 12 Apr 2008 18:18:55 GMT Frank Kotler <fbkotler(a)verizon.net> wrote: > "align 4" at the end of the ".text" section, Ivan. Although Ivan's problem is real, the error itself is quite silly. The elf loader is refusing to load zero bytes from the executable file because the non-existent bytes are not properly aligned to the physical address where they are not supposed to be loaded. If I had such a problem in my code, I would be very embarrassed when it came to light. -- Chuck http://www.pacificsites.com/~ccrayne/charles.html |