Subject: why kvm_mkdb is screwed up
To: None <current-users@NetBSD.ORG>
From: John F. Woods <jfw@jfwhome.funhouse.com>
List: current-users
Date: 01/09/1997 14:16:11
OK, I've looked at kvm_mkdb, and I think I understand why it's failing.

I was going to launch into a long rant about the inadequacies of a.out
format causing this, but that's not actually true.  (Not, of course,
that a.out isn't inadequate.)

Because the MID_I386 ZMAGIC format puts the first page of the text section
in the first page of the executable file, the text section's first useful
address is offset by 0x20 from its actual start.  What this means for the
kernel image is that the symbol _kernel_start equals 0xf8100020 on the 386.
(Other architectures' mileage may vary, but I'll bet some of them are subject
to this same problem.)

kvm_mkdb attempts to adjust for the bizarreness of address calculation for
a.out files by subtracting "kerntextoff" from kernel virtual addresses (when
looking up the version string).  This worked when kerntextoff was a compiled
value of 0xf8100000; but now that nlist_aout.c attempts to look up a standard
symbol, it runs afoul of the adjustment for the a.out header.  The result is
that nlist_aout.c misses the version string by 32 bytes, typically stumbling
on a zero byte right away.

I would suggest changing nlist_aout.c from
	kerntextoff = get_kerntext(name);
to
	kerntextoff = get_kerntext(name) & ~(N_PAGSIZ(ebuf) - 1);

although I'm not 100% certain this is trouble-free for non386 architectures. 
(Is there any reason why it should cause trouble?  I would assume that
get_kerntext() will return either a page-aligned address or a value which
has been offset by an exec header, depending on whether the kernel has a
_kernel_text symbol (and on whether the combined header/first page trick
is used).  In either case, sanding off the sub-page-aligned bits should be
correct, I think.)

get_kerntext() *ought* to return a page aligned value, but it "needs" the
a.out header object in order to correctly call N_PAGSIZ().  (Of course,
N_PAGSIZ() ignores its argument, but it's the principle of the thing.)
It could be passed a pointer to the a.out header; it's not like it will
ACTUALLY cost any memory cycles to call N_PAGSIZ(*pebuf).