Page 1 of 1

GRUB (not) loading symbol table

Posted: Wed Jul 11, 2007 1:06 am
by JamesM
Hi,
Before you flame I have searched the forums and found one (closely) related topic, but there really wasn't much info there.

I'm trying to get symbol information for my kernel, for a backtrace function. According to the multiboot draft, GRUB is supposed to load this for me in the multiboot info structure, but on inspection neither bit 4 [A.OUT sym info available] or bit 5 [ELF sym info available] are set, and the sym fields themselves are garbage.

My kernel is in ELF32 format, and is loaded fine. objdump says it does contain a symbol table. To try and work around this, I tried adding a

Code: Select all

start_sym = .;
*(.symtab)
end_sym =.;
to my data section in Link.ld but to no avail - start_sym and end_sym refer to the same place in memory - obviously because LD didn't pick up the symtab section properly.

Any ideas?

Cheers,
JamesM

Posted: Thu Feb 28, 2008 7:13 am
by slowfranklin
James,

have you worked out how to let GRUB load yours ELFs symbol table?

I am writing some basic kernel following your tutorial amongst others. I have implemented a debug shell that allows me to dump memory at specified addresses. Now I want to use my kernels symbols but GRUB does not give them to me.

My kernel is multiboot compliant and in ELF format.

Code: Select all

host:~kernel$ eu-readelf -S kernel.kmg | grep .symtab
[ 8] .symtab              SYMTAB       00000000 0054c0 000a70 16        9  45  4

ost:~kernel$ eu-readelf -s mykernel.kmg
Symbol table [ 8] '.symtab' contains 167 entries:
 45 local symbols  String table: [ 9] '.strtab'
...167 symbols....
So apparantly my kernel image has symbols.
GRUB gives me multiboot_info.flags = 0x47 and thus no symbol table.

-Ralph

Posted: Thu Feb 28, 2008 7:57 am
by djenkins75
I took a different approach. I wrote a perl script that strips the symbols from the output of "objdump", and emits them as a large C array. This gets compiled by a helper program into an ELF executable (that runs on the development machine). This executable organizes the symbols and emits a "blob" that was designed to be effecient to read while inside my kernel. I then load this small blob as a kernel module.

I suppose I could have emitted the blob directly from the perl script, but I'm not that great of a perl wizard.

I admit that my idea was kinda kooky.... But it gives me the ability to have or not have the symbol file on the boot floppy, and my blob is very small, and can be easily compressed with bzip2 (once I get bzip2 decompression into my kernel).

Plus I could not figure out how to get LD/grub to play nice and load the ELF symbols directly either.... If anyone gets it to work, please let us know.

If anyone wants my perl script of death I'll post it. In general though, I have not posted any source to my kernel - I'm too embarrassed about its poor quality and lack of recent progress.

Posted: Thu Feb 28, 2008 8:43 am
by slowfranklin
Hello djenkins,

I went that road too. Here is a simple shell script that extracts the symbols and puts them in a C array in a compilable C file. I will link that into my kernel and use that.

Script:

Code: Select all

#!/bin/bash                                                                                                                              

cat <<EOF                                                                                                                                
typedef struct symbol {                                                                                                                  
  unsigned char *name;                                                                                                                   
  unsigned int addr;                                                                                                                     
} symbol_t;                                                                                                                              
                                                                                                                                         
symbol_t symbols[] = {                                                                                                                   
EOF                                                                                                                                      

eu-readelf -s kernel.kmg | awk '/OBJECT/ {printf "\"%s\", 0x%s,\n",$8, $2;}'

cat <<EOF                                                                                                                                
"EOS", 0x0                                                                                                                               
};                                                                                                                                       
EOF
Usage: ./script.sh > symbols.c

-Ralph

Posted: Thu Feb 28, 2008 9:16 am
by JamesM
Hi,

Yes, i worked it out. You have to remove the flag MBOOT_AOUT_KLUDGE from your multiboot header. Having it on makes GRUB take the bad route and ignore all ELF stuff.

I removed that and it all worked.

Cheers,

James

Posted: Thu Feb 28, 2008 10:15 am
by binutils
djenkins75 wrote:I took a different approach. I wrote a perl script that strips the symbols from the output of "objdump", and emits them as a large C array. This gets compiled by a helper program into an ELF executable (that runs on the development machine). This executable organizes the symbols and emits a "blob" that was designed to be effecient to read while inside my kernel. I then load this small blob as a kernel module.

I suppose I could have emitted the blob directly from the perl script, but I'm not that great of a perl wizard.
That approach remind me of early haskell implementation, though i prefer ocaml over haskell.

perl is good enough make it, it even contain lc(lambda calculus).
http://perl.plover.com/lambda/

in other words, perl and asm very nice combo.

Posted: Thu Feb 28, 2008 10:38 am
by slowfranklin
JamesM wrote:...You have to remove the flag MBOOT_AOUT_KLUDGE ...
Hmm... I define MULTIBOOT_HEADER_FLAGS to be 0x03. So I am not using MBOOT_AOUT_KLUDGE.

-Ralph