mfld-fr / emu86

Intel IA16 emulator for embedded development
35 stars 6 forks source link

Add text segment symbol display to disassembler #71

Closed ghaerr closed 3 years ago

ghaerr commented 3 years ago

Here's my 20-line hack to add displaying symbols from any ia86-elf-gcc/ld.gold produced executable during disassembly tracing in EMU86. I think it's pretty cool. The following shows ELKS making a system call and saving the CPU registers onto a kernel stack:

map file2

I think once we get used to this, we won't want to live without it.

Currently, only near text segment addresses are converted. Adding far text and data will be very straightforward, except for the problem of knowing the start segment values for each. Current hack doesn't check for proper text segment.

ELKS displays text, far text and data segments at boot.

The following is required to make this work:

Add ELKS patch to produce ia16-elf-nm symbol listing from ELF binary before elf2elks conversion:

diff --git a/elks/arch/i86/Makefile b/elks/arch/i86/Makefile
index 337adc84..cd08b422 100644
--- a/elks/arch/i86/Makefile
+++ b/elks/arch/i86/Makefile
@@ -132,10 +132,11 @@ else
 # Begin PC image build

 boot/system:   $(XINCLUDE) $(AARCHIVES) $(ADRIVERS) boot/crt0.o
-       (cd $(BASEDIR) ; $(LD) $(LDFLAGS) -M $(ARCH_LD) -T $(TOPDIR)/elks/elks-small.ld \
+       (cd $(BASEDIR) ; $(LD) $(CPU_LD) -M $(ARCH_LD) -T $(TOPDIR)/elks/elks-small.ld \
                $(ARCH_DIR)/boot/crt0.o \
                init/main.o '-(' $(ARCHIVES) $(DRIVERS) '-)' $(LIBGCC) \
                -o $(ARCH_DIR)/boot/system > $(ARCH_DIR)/boot/system.map ; \
+               ia16-elf-nm $(ARCH_DIR)/boot/system > $(ARCH_DIR)/boot/system-nm.map; \
                $(POSTLINK) $(ROMPOSTLINKFLAGS) $(ARCH_DIR)/boot/system)
 #              sort -k3,4 $(ARCH_DIR)/boot/system.tmp > $(ARCH_DIR)/boot/system.map ; \
 #              rm -f $(ARCH_DIR)/boot/system.tmp )

Run convmap.sh, which produces a mapfile.c from the ELKS or other namelist file:

Gregs-MBP2:emu86 greg$ cat convmap.sh
cat ../elks-gh/elks/arch/i86/boot/system-nm.map | sed -e '/&/d; /!/d' | sort > file
cc convmap.c -o convmap
./convmap > mapfile.c
rm file

The preprocessing removes any symbols ending in '&' or '!'. The symbols are then sorted and converted to a C file.

A quick change would be keeping the symbol address unchanged in mapfile.c, which allows keeping all symbols in a single array. Linear brute sweep, rather than binary search, is employed to find the symbol.

The pre-processing should probably all be done inside EMU86, and build a dynamic array instead. This would allow map files to be used without conversion or recompilation. We just need to think of a way of finding out the proper segment values for the 0x10000, 0x20000 and 0x30000 symbol ranges in the map file. At last resort, we could compile in a special symbol that would tell us this from ELKS kernel.

Have fun!

ghaerr commented 3 years ago

Build is failing because of non-existent mapfile.c.

Build can be fixed by adding temp NULL copy of mapfile.c:

struct map { int addr; char *name; };
struct map map[] = {
{ -1, 0} };
ghaerr commented 3 years ago

Add temp null mapfile.c to stop build from breaking.

ghaerr commented 3 years ago

@mfld-fr : If you think this can be made a viable method going forward, I will add automatic ia16-elf-nm system-nm.map file generation patch to ELKS.

mfld-fr commented 3 years ago

Whatever the later processing of the symbols, we do need symbols as input data. So yes, adding the NM command in the ELKS build for both system and setup is a must have.

mfld-fr commented 3 years ago

Retargetted that PR to debug as the WIP branch.

ghaerr commented 3 years ago

So yes, adding the NM command in the ELKS build for both system and setup is a must have.

Thanks, I missed this comment about needing setup-nm.map also before I merged the change for system-nm.map. I'll add the setup change after we figure out how to handle the segment-determination problem, in case more is needed.