assembly - wrong memory locations when debugging in qemu with gdb -
i'm writing little kernel in assembler. i'm running in qemu , have problems bugs. want debug kernel dbg. assembled so:
$ nasm -g -f elf -o myos.elf myos.asm $ objcopy --only-keep-debug myos.elf myos.sym $ objcopy -o binary myos.elf myos.bin   then run in qemu with:
$ qemu-system-i386 -s -s myos.bin   then connect gdb:
$ gdb (gdb) target remote localhost:1234 remote debugging using localhost:1234 0x0000fff0 in ?? () symbol-file myos.sym reading symbols /home/sven/projekte/myos/myos.sym...done.   i have label named welcome in kernel points string. while testing tried @ string, gave following result:
(gdb) x/32b welcome 0x1e <welcome>: 0x00    0xf0    0xa5    0xfe    0x00    0xf0    0x87    0xe9 0x26:   0x00    0xf0    0x6e    0xc9    0x00    0xf0    0x6e    0xc9 0x2e:   0x00    0xf0    0x6e    0xc9    0x00    0xf0    0x6e    0xc9 0x36:   0x00    0xf0    0x57    0xef    0x00    0xf0    0x6e   the label defined this:
welcome: db "system started. happy hacking!", 10, 0   so can see, gdb pretending welcome starts null byte definition it's not. kernel uses label correctly, doesn't seem poblem code. examining other parts of memory doesn't match loaded kernel @ all.
does know why memory of virtual machine doesn't match loaded kernel, while machine still behaves corectly?
explanation
qemu-system-i386loads first byte of x86 boot sector image file @ address0x7c00@ run time.- your elf files (
myos.elf,myos.sym) mistakenly inform gdb code loaded @ address 0. gdb thinkswelcome@0x1ewhile it's @0x7c1e. - adding 
0x7c00addresses in gdb work clumsy:x/32xb (welcome + 0x7c00) - a better solution create elf file right addresses.
 
solution
boot.asm
; 'boot.asm' ; loaded bios [bits 16] global main main: mov di, welcome print_welcome: mov ah, 0x0e mov al, [di] int 0x10 inc di cmp byte [di], 0 jne print_welcome hlt db "xxxxxxxxxxxxxx" ; padding make welcome appear @ 0x1e welcome: db "system started. happy hacking!", 10, 0 ; x86 boot sector padding , signature ; note: intentionally commented out. added linker script ;times 510 - ($ - $$) db 0x00 ;db 0x55, 0xaa
x86-boot.ld
 entry(main); sections {     . = 0x7c00;     .text : at(0x7c00)     {         _text = .;         *(.text);         _text_end = .;     }     .data :     {         _data = .;         *(.bss);         *(.bss*);         *(.data);         *(.rodata*);         *(common)         _data_end = .;     }     .sig : at(0x7dfe)     {         short(0xaa55);     }     /discard/ :     {         *(.note*);         *(.iplt*);         *(.igot*);         *(.rel*);         *(.comment); /* add unwanted sections spewed out version of gcc , flags here */     } }   build code with:
nasm -g -f elf -f dwarf boot.asm -o boot.o cc -nostdlib -m32 -t x86-boot.ld -wl,--build-id=none boot.o -o boot objcopy -o binary boot boot.good.bin
dump-welcome.gdb
target remote localhost:1234 symbol-file boot monitor system_reset # run until hlt instruction, address obtained through disassembly until *0x7c0f x/32xb welcome monitor quit disconnect quit
sample session:
$ qemu-system-x86_64 -s -s boot.good.bin & $ gdb -q -x dump-welcome.gdb 0x0000fff0 in ?? () main () @ boot.asm:16 16 hlt 0x7c1e : 0x53 0x79 0x73 0x74 0x65 0x6d 0x20 0x73 0x7c26: 0x74 0x61 0x72 0x74 0x65 0x64 0x2e 0x20 0x7c2e: 0x48 0x61 0x70 0x70 0x79 0x20 0x68 0x61 0x7c36: 0x63 0x6b 0x69 0x6e 0x67 0x21 0x0a 0x00
thought process
most of 32 bytes dumped have values ≥ 0x80, i.e. they're not printable ascii characters. raises question: am really dumping right address?
the hex dump of welcome message should be:
$ python -c 's = "system started. happy hacking!"; print [hex(ord(x)) x in s ]' ['0x53', '0x79', '0x73', '0x74', '0x65', '0x6d', '0x20', '0x73', '0x74', '0x61', '0x72', '0x74', '0x65', '0x64', '0x2e', '0x20', '0x48', '0x61', '0x70', '0x70', '0x79', '0x20', '0x68', '0x61', '0x63', '0x6b', '0x69', '0x6e', '0x67', '0x21']
using gdb search welcome message in memory have revealed right address well:
(gdb) find 0, 0xffff, 's', 'y', 's', 't' 0x7c1e
further reading
- gnu ld: basic linker script concepts: see discussion on lma vs. vma
 - real mode in c gcc : writing bootloader: source of linker script above. shows cool gnu toolchain tricks x86 real mode development.
 
Comments
Post a Comment