In pondering the ELF issue, I was looking over the stage0 in Coreboot-v3. It contains some workarounds for gas/binutils issues that have been hit in the past, as well as .globl symbols.
On reading about Gas, I found that gcc output passes through it, implying that Gas can emit rich debugging information. I didn't see any -g flags to cause a symbol table to be emitted, so just for fun I built arch/x86/geodelx/stage0.S using -g.
It turns out you can load stage0.o into gcc, and disassemble 32bit "functions", show source file lines, all that fun stuff, and objdump can manage the 16bit stuff.
Then it occurred to me, couldn't everything be built with debug symbols, and then strip that into a separate symbol file to go with the final ROM image?
With some cleanups, even structures in stage0 could be examined conveniently with gdb, ie (gdb) print gdt, would show the C struct formatted nicely.
$ gdb stage0.o (gdb) disassemble DCacheSetupGood Dump of assembler code for function DCacheSetupGood: 0x0000019a <DCacheSetupGood+0>: mov $0x87ffc,%eax 0x0000019f <DCacheSetupGood+5>: mov %eax,%esp 0x000001a1 <DCacheSetupGood+7>: mov $0x20,%ax 0x000001a5 <DCacheSetupGood+11>: movl %eax,%ds 0x000001a7 <DCacheSetupGood+13>: movl %eax,%es 0x000001a9 <DCacheSetupGood+15>: movl %eax,%ss End of assembler dump.