OSDev.org https://forum.osdev.org/ |
|
gdb code display not same as source code https://forum.osdev.org/viewtopic.php?f=13&t=37151 |
Page 1 of 1 |
Author: | programmern00b [ Sun Aug 23, 2020 4:00 pm ] |
Post subject: | gdb code display not same as source code |
Hello, I am new to OS development and have been following the book recommended on the wiki called "Operating Systems: From 0 to 1", I have been following along and also implementing the code they use in the book on my computer. Everything was doing well with some slight changes needed from the books code, then section 8.5.3 I stumbled into a problem. The gdb debugger was not displaying the correct assembly code. I followed the books code precisely and do not understand why gdb is displaying the wrong assembly. I know now that the opcodes gdb displays at main are the magic numbers of the main program elf header, but why is this happening and how do I get it to display properly? If not possible is there an alternative solution? bootloader.asm Code: ;************************************************* ; bootloader.asm ; A Simple Bootloader ;************************************************* bits 16 start: jmp boot ;; constants and variable definitions msg db "Welcome to My Operating System!", 0ah, 0dh, 0h boot: cli ; no interrupts cld ; all that we need to init mov ax, 0x0000 ;; set buffer mov es, ax mov bx, 0x0600 mov al, 1 ; read one sector mov ch, 0 ; track 0 mov cl, 2 ; sector to read mov dh, 0 ; head number mov dl, 0 ; drive number mov ah, 0x02 ; read sectors from disk int 0x13 ; call the BIOS routine jmp 0x0000:0x0600 ; jump and execute the sector! hlt ; halt the system ; We have to be 512 bytes. Clear the rest of the bytes with 0 times 510 - ($-$$) db 0 dw 0xAA55 ; Boot Signature readelf -h main Code: ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x600 Start of program headers: 52 (bytes into file) Start of section headers: 12888 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 3 Size of section headers: 40 (bytes) Number of section headers: 12 Section header string table index: 11 readelf -l main Code: Elf file type is EXEC (Executable file) Entry point 0x600 There are 3 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000000 0x00000000 0x00000000 0x00094 0x00094 R 0x4 LOAD 0x000000 0x00000000 0x00000000 0x00094 0x00094 R 0x4 LOAD 0x000100 0x00000600 0x00000600 0x00006 0x00006 R E 0x100 Section to Segment mapping: Segment Sections... 00 01 02 .text main.c Code: void main(){} objdump -z -M intel -S -D build/os/main Code: Disassembly of section .text: 00000600 <main>: void main(){} 600: 55 push ebp 601: 89 e5 mov ebp,esp 603: 90 nop 604: 5d pop ebp 605: c3 ret when jumping to 0x0000:0x0600 in bootloader to main this is what gdb displays; Code: 0x600 <main> jg 0x647 │ │ 0x602 <main+2> dec esp │ │ 0x603 <main+3> inc esi │ │ 0x604 <main+4> add DWORD PTR [ecx],eax │ also here is how I compiled everything and started up qemu Code: nasm -f elf bootloader.asm -F dwarf -g -o ../build/bootloader/bootloader.o ld -m elf_i386 -T bootloader.lds ../build/bootloader/bootloader.o -o ../build/bootloader/bootloader.o.elf objcopy -O binary ../build/bootloader/bootloader.o.elf ../build/bootloader/bootloader.o gcc -ffreestanding -nostdlib -fno-pic -gdwarf-4 -m16 -ggdb3 -c main.c -o ../build/os/main.o ld -m elf_i386 -nmagic -T os.lds ../build/os/main.o -o ../build/os/main dd if=/dev/zero of=disk.img bs=512 count=2880 2880+0 records in 2880+0 records out 1474560 bytes (1.5 MB, 1.4 MiB) copied, 0.0150958 s, 97.7 MB/s dd conv=notrunc if=build/bootloader/bootloader.o of=disk.img bs=512 count=1 seek=0 1+0 records in 1+0 records out 512 bytes copied, 0.000127745 s, 4.0 MB/s dd conv=notrunc if=build/os/main.o of=disk.img bs=512 count=$((8504/512)) seek=1 16+0 records in 16+0 records out 8192 bytes (8.2 kB, 8.0 KiB) copied, 0.000184251 s, 44.5 MB/s qemu-system-i386 -machine q35 -fda disk.img -gdb tcp::26000 -S here is the code I used for gdb Code: set architecture i8086
target remote localhost:26000 b *0x7c00 set disassembly-flavor intel layout asm layout reg symbol-file build/os/main b main |
Author: | foliagecanine [ Sun Aug 23, 2020 8:55 pm ] |
Post subject: | Re: gdb code display not same as source code |
The main problem is that your "main" file is in the ELF format. Computers only read binary format. Here's the way I got your code working: Since you didn't provide os.lds or bootloader.lds, I did it a different way. Code: nasm -fbin bootloader.asm -o bootloader.o gcc -ffreestanding -nostdlib -nostartfiles -fno-pic -fcf-protection=none -gdwar> ld --oformat binary -T os.lds main.o -o os.bin ld -T os.lds main.o -o os.sym dd if=/dev/zero of=disk.img bs=512 count=2880 dd conv=notrunc if=bootloader.o of=disk.img bs=512 count=1 seek=0 dd conv=notrunc if=os.bin of=disk.img bs=512 seek=1 qemu-system-i386 -machine q35 -fda disk.img -gdb tcp::26000 -S using the following linker file (os.lds): Code: OUTPUT_ARCH(i8086) ENTRY (main) SECTIONS { . = 0x600; .text : { *(.text) } .data : { *(.data) } .rodata : { *(.rodata) } } This compiles a bootable floppy. There is os.bin, which is the binary output that the computer should read and os.sym, which is the ELF output that your debugger should read. However, the code you provided (bootloader.asm) does NOT work for two reasons: - You haven't set up a stack of any sort, so right now it is undefined - You used jmp instead of call, so when the main function tries to return, it will look in the undefined stack and find a random number (with QEMU it jumped to 0xf000d002, but it can vary by platform). I believe your intention was for the main function to return and execute the hlt instruction. However, if you are worried whether gdb disassembles it, Code: set architecture i8086 target remote localhost:26000 b *0x7C00 set disassembly-flavor intel layout asm layout reg symbol-file os.sym b main -------- B+>0x600 <main> push %bp │ │ 0x602 <main+2> mov %sp,%bp │ │ 0x605 <main+5> nop │ │ 0x606 <main+6> pop %bp │ │ 0x608 <main+8> retw │ │ 0x60a add %al,(%eax) I don't know how you want your build mechanism to go, but that is up to you. Good luck with your OS! |
Author: | Octocontrabass [ Sun Aug 23, 2020 11:31 pm ] |
Post subject: | Re: gdb code display not same as source code |
I think you should read section 8.5.1 again. |
Author: | foliagecanine [ Mon Aug 24, 2020 9:18 am ] |
Post subject: | Re: gdb code display not same as source code |
Oops. I didn't notice that you were following a book . Octocontrabass is right though; on section 8.5 it tells you how to fix the linker script to load the "text" (code) section at 0x600. However, do note that (as far as I can tell) that book is far from finished and won't get you too far. There's also the two bugs I've mentioned in the previous post (no stack set up and jmp instead of call). Good luck! edit: spelling |
Author: | programmern00b [ Mon Aug 24, 2020 8:48 pm ] |
Post subject: | Re: gdb code display not same as source code |
Sorry for the late reply, fpr this step; gcc -ffreestanding -nostdlib -nostartfiles -fno-pic -fcf-protection=none -gdwar> did you mean this; gcc -ffreestanding -nostdlib -nostartfiles -fno-pic -fcf-protection=none -gdwarf -c main.c, or was it supposed to be like that? also sorry for leaving out the linker scripts I used; os.lds; Code: ENTRY(main); PHDRS { headers PT_PHDR FILEHDR PHDRS; headers2 PT_LOAD FILEHDR PHDRS; code PT_LOAD; } SECTIONS { .text 0x600: ALIGN(0x100) { *(.text) } :code .data : { *(.data) } .bss : { *(.bss) } /DISCARD/ : { *(.eh_frame) } } bootloader.lds Code: OUTPUT(bootloader); PHDRS { headers PT_NULL; text PT_LOAD FILEHDR PHDRS ; data PT_LOAD ; } SECTIONS { . = SIZEOF_HEADERS; .text 0x7c00: { *(.text) } :text .data : { *(.data) } :data } Thanks for the help so far. |
Author: | foliagecanine [ Mon Aug 24, 2020 9:36 pm ] |
Post subject: | Re: gdb code display not same as source code |
programmern00b wrote: fpr this step; gcc -ffreestanding -nostdlib -nostartfiles -fno-pic -fcf-protection=none -gdwar> did you mean this; gcc -ffreestanding -nostdlib -nostartfiles -fno-pic -fcf-protection=none -gdwarf -c main.c, or was it supposed to be like that? Sorry, nano cut out that last bit Code: gcc -ffreestanding -nostdlib -nostartfiles -fno-pic -fcf-protection=none -gdwarf-4 -m16 -ggdb3 -c main.c -o main.o Since you're using a platform specific compiler, this disables GCC start files and disables fcf protections (they're meant for programs running on an OS, otherwise you'd have endbr32's everywhere) ---------------------------------------------------- The way the book says to do it is os.lds: Code: ENTRY(main); PHDRS { headers PT_PHDR FILEHDR PHDRS; code PT_LOAD; } SECTIONS { .text 0x600: ALIGN(0x100) { *(.text) } :code .data : { *(.data) } .bss : { *(.bss) } /DISCARD/ : { *(.eh_frame) } } and in your build process add -nmagic: Code: ld -m elf_i386 -nmagic -T os.lds main.o -o main The way I did it (is probably not the best, but) literally strips out all of the ELF headers and data. It produces two files, one binary and one with the symbols; the PC (or emulator) uses the binary file while gdb uses the symbol file. ---------------------------------------------------- Just a few tips: - If you're running a Linux or BSD distro (in a virtual machine, or on real hardware) with a graphical envorionment, there's a software called DDD (Data Display Debugger). It has a horrible UI, but it's one of the easiest ways (for me at least) to see everything I'm debugging. It uses gdb for everything, but makes it much faster and easier to see and debug things. - If you run QEMU with Code: qemu-system-i386 <flags here> -s it will be the same asCode: qemu-system-i386 <flags here> -gdb tcp::1234 - The book you're using ends very soon. At this point, you'll either want to continue to create a Real Mode OS/bootloader or create a Protected Mode (or even Long Mode) OS. If you choose protected mode (like I did, although I did make a little tiny bootloader once), I'd recommend looking at the Bare Bones page. - You could have probably put this thread in OS Development rather than General Programming, but I don't think it matters too much ---------------------------------------------------- (as a bonus, here's how I'd make bootloader.asm) Code: ;*************************************************
; bootloader.asm ; A Simple Bootloader ;************************************************* bits 16 start: jmp boot ;; constants and variable definitions msg db "Welcome to My Operating System!", 0ah, 0dh, 0h boot: cli ; no interrupts cld ; all that we need to init xor ax,ax ; This is the same thing as doing "mov ax,0" mov ss,ax ; Set stack segment to 0 mov sp,0xFFFF ; Set stack to start at 0xFFFF and grow down ;; set buffer mov es, ax mov bx, 0x0600 mov al, 1 ; read one sector mov ch, 0 ; track 0 mov cl, 2 ; sector to read mov dh, 0 ; head number mov dl, 0 ; drive number mov ah, 0x02 ; read sectors from disk int 0x13 ; call the BIOS routine call 0x0000:0x0600 ; execute the sector, but provide a way for main to return hlt ; halt the system ; We have to be 512 bytes. Clear the rest of the bytes with 0 times 510 - ($-$$) db 0 dw 0xAA55 ; Boot Signature |
Author: | programmern00b [ Mon Aug 24, 2020 9:41 pm ] |
Post subject: | Re: gdb code display not same as source code |
Okay GDB displays the correct code now, all that needed to change was I needed a binary file and symbol file for the kernel code if i'm not mistaken? Thanks for all the help again! |
Author: | programmern00b [ Mon Aug 24, 2020 10:02 pm ] |
Post subject: | Re: gdb code display not same as source code |
Quote: If you're running a Linux or BSD distro (in a virtual machine, or on real hardware) with a graphical envorionment, there's a software called DDD (Data Display Debugger). Yes, I think I have stumbled upon this before to debug assembly code, I'll look more into it. Also thanks for the tips on implementing a stack in my OS, remember to implement one in my future projects. And thanks for giving me some directions on how to move forward, OS development seems like a big topic with lots of paths so thanks for the advice! |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |