Reputation: 138
gdt.h:
void gdt_load(struct segment_descriptor_raw *gdt, uint16_t size);
gdt.c:
struct segment_descriptor_raw gdt_raw[TOTAL_GDT_SEGMENTS];
gdt_load(gdt_raw, sizeof(gdt_raw));
When I open GDB to step through this code, I get the address of the gdb_raw
array by executing print &gdt_raw[0]
and I get an output of 0x380
. I confirmed that this is the actual address of the array, and not the address of the pointer to the array, by examining the memory at 0x380 with the x command in gdb.
gdt.asm:
gdt_load:
mov eax, [esp + 4]
mov [gdt_descriptor + 2], eax
mov ax, [esp + 8]
mov [gdt_descriptor], ax
lgdt [gdt_descriptor]
ret
Now, as I step through the above assembly code in GDB, I expect the value at [esp + 4], the first argument to the function, to be the address of gdt_raw
(0x380
). However, it's not. It's the value 0x106000. Curious as to why this is the case, I stepped into the assembly directly after calling gdt_load: via layout asm
and stepi
and this is what I see:
push 0x18
push 0x106000
call 0x10806e
These are the arguments getting passed to the function. 0x18 makes sense, this is the size of the gdt and what I expect. However, why is the other argument 0x106000 and not 0x380?
Does this have something to do with 0x380 being the address of gdt_raw
in the symbol table, but once the file is mapped to memory, the address we're seeing in the assembly code is the real address of gdt_raw in memory? This is my guess but I'm hoping someone can confirm or deny.
And, if the above is true, then when I use the x command in GDB to view the bytes at a memory location, are those bytes not the real memory, but instead only the offset within the object file?
Update: Makefile and linker script
Upvotes: 4
Views: 175
Reputation: 138
The issue was that I was pulling debug symbols from the symbol table of a relocatable object file.
I was generating a relocatable object file, build/kernelfull.o
. Then, I converted this file into a binary that was loaded into memory at 0x100000
. In GDB, when executing the binary, I pulled in the symbol table from the relocatable file with add-symbol-file build/kernelfull.o 0x100000
.
Thus, GDB only knew an address for gdt_raw
that was relative to 0
. To correct this, I had to create an ELF Executable (as opposed to ELF Relocatable) which I then converted into a binary (objcopy
). By using the debugging symbols of this ELF Executable, GDB could see that gdt_raw
was indeed at the address 0x106000
Thanks to @MichaelPetch for figuring this out.
Upvotes: 2