Page 1 of 1

Does anyone know how to load a symbol table into bochs?

Posted: Thu Mar 25, 2021 1:43 pm
by j4cobgarby
I've decided I'm going to try to load the symbol table of my operating system into bochs, so that hopefully it can show me functions names in the dissassembly, etc.

I found the bochsrc option "debug_symbols", and the equivalent bochs command "ldsym", both of which should be able to be used to load a symbol file for this purpose. Now, I'm not exactly sure what format it wants the symbol table to be in, so I tried the following: `objdump -t octos.img > octos.sym`, and then gave that file to the "debug_symbols" line in my bochsrc. When I do this and launch bochs, I get the following error:

Code: Select all

========================================================================
                       Bochs x86 Emulator 2.6.11
              Built from SVN snapshot on January 5, 2020
                Timestamp: Sun Jan  5 08:36:00 CET 2020
========================================================================
00000000000i[      ] BXSHARE not set. using compile time default '/usr/share/bochs'
00000000000i[      ] reading configuration from bochsrc
00000000000e[      ] bochsrc:3: ataX-master/slave CHS set to 0/0/0 - autodetection enabled
00000000000e[      ] bochsrc:4: ataX-master/slave CHS set to 0/0/0 - autodetection enabled
00000000000i[      ] Stopping on magic break points
octos.sym:1: missing symbol name
00000000000p[      ] >>PANIC<< bochsrc:9: debug_symbols: failed to load symbols from 'octos.sym'
00000000000e[SIM   ] notify called, but no bxevent_callback function is registered
00000000000e[SIM   ] notify called, but no bxevent_callback function is registered
========================================================================
Bochs is exiting with the following message:
[      ] bochsrc:9: debug_symbols: failed to load symbols from 'octos.sym'
========================================================================
00000000000i[SIM   ] quit_sim called with exit code 1
Does anyone know why this is happening? What format does bochs expect for the symbol table?

Thanks

Re: Does anyone know how to load a symbol table into bochs?

Posted: Thu Mar 25, 2021 2:27 pm
by j4cobgarby
Update: I've been able make a symbol file that bochs accepts using the `nm` command, however when I load that file into bochs it doesn't show the symbol names in the dissassembly. Is this just something it can't do, or can I make it do that?

Re: Does anyone know how to load a symbol table into bochs?

Posted: Thu Mar 25, 2021 11:03 pm
by stlw
I suggest you to use latest SVN revision of Bochs as it completely reworked the disassembly and symbols stuff.
See also another post where I asked for help there ...

viewtopic.php?f=2&t=39155

Stanislav

Re: Does anyone know how to load a symbol table into bochs?

Posted: Fri Mar 26, 2021 3:16 am
by j4cobgarby
stlw wrote:I suggest you to use latest SVN revision of Bochs as it completely reworked the disassembly and symbols stuff.
See also another post where I asked for help there ...

viewtopic.php?f=2&t=39155

Stanislav
Thanks, that sounds good. I'm having trouble building the latest SVN version of bochs, unforunately - I get the following error:

Code: Select all

g++ -c  -I.. -I./.. -I../instrument/stubs -I./../instrument/stubs -g -O2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -pthread    -I./../host/linux/pcidev pcidev.cc -o pcidev.o
pcidev.cc:245:43: error: macro "BX_UNREGISTER_DEVICE_DEVMODEL" requires 2 arguments, but only 1 given
  245 |     BX_UNREGISTER_DEVICE_DEVMODEL("pcidev");
      |                                           ^
In file included from iodev.h:29,
                 from pcidev.cc:34:
../plugin.h:81: note: macro "BX_UNREGISTER_DEVICE_DEVMODEL" defined here
   81 | #define BX_UNREGISTER_DEVICE_DEVMODEL(a,b) pluginUnregisterDeviceDevmodel(a,b)
      | 
pcidev.cc: In member function ‘virtual void bx_pcidev_c::init()’:
pcidev.cc:245:5: error: ‘BX_UNREGISTER_DEVICE_DEVMODEL’ was not declared in this scope
  245 |     BX_UNREGISTER_DEVICE_DEVMODEL("pcidev");
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make[1]: *** [Makefile:117: pcidev.o] Error 1
make[1]: Leaving directory '/home/j4cobgarby/Documents/code/bochs/iodev'
make: *** [Makefile:297: iodev/libiodev.a] Error 2
Actually, I've fixed that now by going into bochs's pcidev.cc source file and changing BX_UNREGISTER_DEVICE_DEVMODEL("pcidev") to have a second parameter, which I chose randomly to be 0, as I saw it had to be an integer type. Now, everything seems to work, but I bet if I wanted to do PCI stuff something wouldn't work. Is there any proper fix to that error?

Re: Does anyone know how to load a symbol table into bochs?

Posted: Fri Mar 26, 2021 5:38 am
by bzt
j4cobgarby wrote:Update: I've been able make a symbol file that bochs accepts using the `nm` command, however when I load that file into bochs it doesn't show the symbol names in the dissassembly. Is this just something it can't do, or can I make it do that?
To be precise, bochs does not accept `nm` command's output as-is. Bochs expects two coloumns, the first being the address, the second being the symbol, while nm generates three coloumns, first is the address, the second is a type, and the third is the symbol. You'll have to cut out the middle coloumn from nm's output befoure you could load it into bochs.

@stlw: I didn't have time to check out the latest, but would it be possible to add a test when loading symbol files? Just check if the symbol in the file starts with a letter and a space, and if so, add 2 to the pointer. Something like

Code: Select all

char *sym; // this is the symbol in the buffer read from the file
if(((sym[0] >= 'a' && sym[0] <= 'z') || (sym[0] >= 'A' && sym[0] <= 'Z')) && sym[1] == ' ')
    sym += 2;
// now add sym to the in-memory symbol table
This way bochs could use the symbol files like now, but it would accept `nm` output as-is as well. Just an idea, and sorry to bother you if this is already implemented in the latest version.

Cheers,
bzt

Re: Does anyone know how to load a symbol table into bochs?

Posted: Fri Mar 26, 2021 7:01 am
by stlw
Just yesterday someone opened a bug report about this in bug tracker:

[bochs:bugs] #1430 Compilation error with --enable-pcidev flag

see inside. I believe Volker will merge the fix in just few days.

Re: Does anyone know how to load a symbol table into bochs?

Posted: Fri Mar 26, 2021 7:02 am
by stlw
bzt wrote: @stlw: I didn't have time to check out the latest, but would it be possible to add a test when loading symbol files? Just check if the symbol in the file starts with a letter and a space, and if so, add 2 to the pointer. Something like

Code: Select all

char *sym; // this is the symbol in the buffer read from the file
if(((sym[0] >= 'a' && sym[0] <= 'z') || (sym[0] >= 'A' && sym[0] <= 'Z')) && sym[1] == ' ')
    sym += 2;
// now add sym to the in-memory symbol table
This way bochs could use the symbol files like now, but it would accept `nm` output as-is as well. Just an idea, and sorry to bother you if this is already implemented in the latest version.

Cheers,
bzt
What is the nm command and how the output it produces different from one that Bochs accepts ?
I didn't understand ...

Re: Does anyone know how to load a symbol table into bochs?

Posted: Fri Mar 26, 2021 7:31 am
by bzt
stlw wrote:What is the nm command
The nm command is a standard UNIX tool (part of the IEEE Std 1003.1-2008 (“POSIX.1”) specification) to extract symbols from object files like executables and shared libraries. (Similar to readelf -s, but it accepts not only elf, but other formats as well, and the output is easier to parse by scripts)
stlw wrote:and how the output it produces different from one that Bochs accepts ?
I didn't understand ...
The difference is as I wrote before: nm adds an additional coloumn between the address and the symbol's name, the symbol's type. That's a one letter code, something like "t" for local text symbol, "T" for external text symbol, "d" for local data symbol etc.

For example:

Code: Select all

0000000000000000 b .bss
0000000000000000 n .comment
0000000000000004 C const_global
0000000000000000 R const_global_init
0000000000000000 d .data
0000000000000000 r .eh_frame
000000000000000b T function_with_param
0000000000000004 C global
0000000000000000 D global_init
0000000000000027 T main
0000000000000000 a main.c
0000000000000000 n .note.GNU-stack
0000000000000000 r .rodata
0000000000000000 t static_function
0000000000000000 b static_global
0000000000000004 d static_global_init
0000000000000004 b static_local.1733
0000000000000008 d static_local_init.1732
0000000000000000 t .text
So as you can see, the only difference is that one letter type code, otherwise it's exactly the same format as bochs' symbol file. If bochs were to read nm format, it wouldn't have to care about the type code, it could simply skip it (but if you want to differentiate between data and text symbols, you could).

The example I've provided for you in the other topic, was actually made with nm too:

Code: Select all

nm bootboot.elf | sort | sed 's/\ A\ /\ /g' > bootboot.sym
But that was easy because I wrote the Assembly in a way that only "A" (global address) types were defined in the elf, so I could simply remove that " A " string part from the middle with sed. Another option could be cut perhaps.

Cheers,
bzt