Debugging with QEMU&GDB, frames problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
m4nny
Posts: 2
Joined: Mon Apr 22, 2013 12:54 pm

Debugging with QEMU&GDB, frames problem

Post by m4nny »

Hi guys,

I've asked this on #osdev yesterday but nobody was able to help me. I am currently trying to debug my OS, which is loaded by a custom bootloader as a flat binary at address 0xC0000000. The code is working fine, the problem is that I cannot attach the QEMU process and load the object file to debug with both symbols and source code, since each time I enter a function that takes arguments, I end up with error messages like:

Code: Select all

setup_frames (mem_size=<error reading variable: can't compute CFA for this frame>) at frames.c:79
I'm linking with the following script, and then apply an objcopy -O binary to the resulting ELF file.

Code: Select all

ENTRY(entry)

ker_off = 0xc0000000;

SECTIONS
{
    . = 0x0;

    .text ker_off : AT(ker_off)
    {
        code = .;
        objs/asm_entry.o(.text);
        *(.text)
        *(.rodata)
        . = ALIGN(0x10);
    }

    .data : AT(ker_off + (data - code))
    {
        data = .;
        *(.data)
        . = ALIGN(0x10);
    }

    .bss : AT(ker_off + (bss - code))
    {
        bss = .;
        *(.bss)
        . = ALIGN(0x10);
    }

    .eh_frame : AT(ker_off + (eh_frame - code))
    {
        eh_frame = .;
        *(.eh_frame);
        *(.rel.eh_frame);
        . = ALIGN(0x10);
    }

    .rel.eh_frame : AT(ker_off + (rel_eh_frame - code))
    {
        rel_eh_frame = .;
        *(.rel.eh_frame);
        . = ALIGN(0x10);
    }

    ker_end = .;
}
All object files compiled via GCC contains both rel.eh_frame and eh_frame sections, the ASM ones none of those. However, the resulting kernel.o object file only contains a tiny (8 bytes) eh_frame section and no rel.eh_frame section. I've tried googling the previous error but there was no help to be found.

Some help would be greatly appreciated, I don't see what I missed!
Thanks again for reading,
m4nny,
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Debugging with QEMU&GDB, frames problem

Post by sortie »

Could you post as well the commands you use to build the kernel objects, link it, and possibly convert it to a flat binary?
m4nny
Posts: 2
Joined: Mon Apr 22, 2013 12:54 pm

Re: Debugging with QEMU&GDB, frames problem

Post by m4nny »

Hey, thanks for your reply.

Here are the various commands I use to generate my kernel as both an ELF file and a flat binary:

The flags are the following:

Code: Select all

LDFLAGS = -melf_i386 --gc-sections
CFLAGS = -g -ggdb3 -m32 -Werror -Wall -Wextra -nostdlib -nostartfiles -nodefaultlibs -nostdinc -ffreestanding -std=c99
For each object file, the compilation is done as follows (first for asm second for C files):

Code: Select all

nasm -f elf -g -o $(OBJDIR)/asm_YYY.o YYY.asm¬
gcc -I../ $(CFLAGS) -c -o $(OBJDIR)/XXX.o XXX.c
Here is the linking:

Code: Select all

ld $(LDFLAGS) -T kernel.ld objs/*.o -o $(BIN)/kernel.o
objcopy -O binary $(BIN)/kernel.o $(BIN)/kernel.bin
I'm sorry I could not juste paste a Makefile but I do my thing via recursive Makefiles so it would have been quite a mess.
Thanks again,
m4nny
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Debugging with QEMU&GDB, frames problem

Post by sortie »

Hi, it's okay. We need to know which commands are run, it doesn't matter how they are run in the makefile.

Your first problem (perhaps unrelated to your original problem) is that you are not using a real cross-compiler. You should truly do that. See our wiki for instructions on how to build one.

Secondly, you are passing a lot of bad options to cover up that you are not using a real cross-compiler, you should:
  • Remove -melf_i386: if you have proper cross-binutils, it remembers the --target variable from the build.
  • -m32: same.
  • -nostartfiles -nodefaultlibs: The -nostdlib option is the same as passing these two, so you just have to pass -nostdlib.
  • -nostdinc: This disables standard headers that you got with the compiler, but you do want those.
  • -Werror: this is going to cause trouble, because not all warnings are errors. If you encounter a warning that you do consider an error, add -Werror=foo to the compile line.
  • You should be linking the kernel with the compiler rather than invoking ld directly, this will fix some problems and allow the compiler to do good stuff.
  • You should link in libgcc (by passing -lgcc at the end of the compiler link command) (remember to build it with your cross-compiler) as the compiler will need stuff from this library for various support routines. You cannot disable it, the compiler will try to use it regardless of whether you supply it or not.
  • You should probably just forget doing a flat binary and just embrace ELF and do a multiboot kernel. It's much nicer than flat formats, really.
Hope this helps. The problem with not using a real cross-compiler is that the toolchain thinks it is still on Linux (or what your host platform is), but that isn't true, and it just creates lots of imaginary problems that you try to 'fix' by passing the above options.
Post Reply