Port-vax archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
4.3BSD a.out compatibility issues in NetBSD
I just discovered why my binaries produced by the 4.3BSD-Qj
cc (pcc) under NetBSD 1.5.2 [a] dump core due to illegal
instruction.
After extensive hacking of the a.out compat/exec/emul related
portions of the NetBSD 1.5.2 kernel, most 4.3BSD-Qj programs
run properly.
However, the output produced by 4.3 cc is invariably invalid,
although the a.out MAGIC is correct (little-endian ZMAGIC).
The reason is the erroneous insertion of extra padding by cc,
as illustrated by hexdumps in footnote [b].
The reason why the compiler inserts extra padding is that
the NetBSD kernel returns the wrong page-cluster size, namely
4096 rather than the correct 1024, as can be seen from the
output of ktrace + kdump at footnote [c].
Why does NetBSD 1.5.2 return information that is likely to
confuse legacy programs? Is it perhaps confused by the fact
that I've chroot()ed to the directory "/q" where all my
4.3BSD-Qj binaries are located (in a typical directory
hierarchy). From footnote [c], it is clear that sometimes
the correct path is returned, starting with "/q/", and sometimes
the prefix is missing. (Note that /q is normally /emul or
something similar - I've redefined it.)
As far as I can see, NetBSD should be detecting the fact
that programs - chrooted or otherwise - are executing from
within the emulation directory ("/emul", or "/q" in my case),
and upon identifying them as old binaries in need of
emulation, it should execute them in the "compat_43" mode -
isn't that correct, Ragge?
Furthermore, compat_43 program should always get the expected
pagecluster size, namely 1024 (not 4096). The sane should
hold true for the NetBSD 1k type of binaries, which have a
big-endian ZMAGIC, unlike the older 4.3 binaries. Right?
Question: is it ever correct to apply 4096 padding to
little-endian (old-style) ZMAGIC a.out binaries? If not,
PCC should not use the incorrect 4096 value returned by
the running kernel. At the very least, it should issue a
strong warning (which might be overridden with an option
or env. variable?). Perhaps pcc should not generate
"unusual" (likely to be wrong) padding unless the default
has been overridden at the command line, or at the time
the compiler was built.
Please examine the hex dumps [b] and the output of
kdump [c]. Are the a a.out headers internally consistent,
or do they contain information in different fields
contradicting each other?
I don't recall the exact structure or what information
is included in the a.out header (I will research that
again later), but hypothetically, if the header has a
pagesize value indicating 4096, but another field
specifying an entry point of 1024, is that "legal" or
potentially valid, or does it indicate a corrupt
program with high certainty?
I'm thinking about collecting some data on headers
actually occurring on various systems I hae access to,
but I'm still interested in feedback and observations
from others, as I do not have access to all data
likely to be relevant.
It might be useful to report a specific error for
programs faulting immediately at their entry point
upon execution. The current reported error of "Illegal
instruction" is certainly valid in such cases, but
nevertheless misleading as it is usually interpreted
as a bug in the program itself (e.g. following a corrupt
pointer) rather than in the format imposed on it by the
compiler or linker.
Are there other "bogosities" in the kdump output in [c]
than what I've already discussed?
-aw
[a] kernel only, userland is probably 1.5.1. The kernel has also had
extensive hacks applied by me in order to allow the 4.3BSD binary
compatibility to function at all. For more details on the fixes
I applied in order to restore the capability of executing 4.3BSD-
compatible binaries, refer to the followin sources:
ftp://vax.narpes.com/users/aw/outgoing/nbsd-vax/
http://mail-index.netbsd.org/port-vax/2006/03/oindex.html
http://mail-index.netbsd.org/port-vax/2006/03/11/0000.html
[b] Hexdumps of two programs with little-endian ZMAGIC. The first
program, which is the pcc C compiler, runs properly, whereas
the second program, a "Hello World" program of mine, dumps core
due to illegal instruction, as seen in [d]. My test programs
may be downloaded from:
ftp://vax.narpes.com/users/aw/outgoing/vax-tmp/test2
The 4.3BSD-Quasijarus compiler can be obtained from the usual places.
# hexdump -C </bin/cc|more
00000000 0b 01 00 00 00 2c 00 00 00 08 00 00 ac 01 00 00 |.....,..........|
00000010 50 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |P...............|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000400 00 0f 11 43 d0 5e 5a c1 04 5a 50 d0 50 59 d0 59 |...C.^Z..ZP.PY.Y|
# hexdump -C <hello-world|more
00000000 0b 01 00 00 00 20 00 00 00 10 00 00 00 00 00 00 |..... ..........|
00000010 f8 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
[c] Output of ktrace + kdump, illustrating the fact that NetBSD 1.5.2
returns the wrong page-cluster size to a 4.3BSD program.
# ktrace -d cc -g -o hello-world hello-world.c
# kdump
7557 ktrace EMUL "netbsd"
7557 ktrace RET ktrace 0
7557 ktrace CALL execve(0x7ffff548,0x7ffffa00,0x7ffffa18)
7557 ktrace NAMI "/bin/cc"
7557 cc EMUL "netbsd"
7557 cc CALL compat_43_ogetpagesize
7557 cc RET compat_43_ogetpagesize 4096/0x1000
7557 cc CALL break(0x35ac)
7557 cc RET break 0
7557 cc CALL break(0x3ffc)
7557 cc RET break 0
7557 cc CALL break(0x4ffc)
7557 cc RET break 0
7557 cc CALL break(0x5ffc)
7557 cc RET break 0
7557 cc CALL break(0x6ffc)
7557 cc RET break 0
7557 cc CALL compat_43_osigvec(0x2,0x7ffff998,0x7ffff9a4)
7557 cc RET compat_43_osigvec 0
7557 cc CALL compat_43_osigvec(0x2,0x7ffff998,0x7ffff9a4)
7557 cc RET compat_43_osigvec 0
7557 cc CALL compat_43_osigvec(0x2,0x7ffff998,0)
7557 cc RET compat_43_osigvec 0
7557 cc CALL compat_43_osigvec(0xf,0x7ffff998,0x7ffff9a4)
7557 cc RET compat_43_osigvec 0
7557 cc CALL compat_43_osigvec(0xf,0x7ffff998,0x7ffff9a4)
7557 cc RET compat_43_osigvec 0
7557 cc CALL compat_43_osigvec(0xf,0x7ffff998,0)
7557 cc RET compat_43_osigvec 0
7557 cc CALL compat_43_osigvec(0x1,0x7ffff998,0x7ffff9a4)
7557 cc RET compat_43_osigvec 0
7557 cc CALL compat_43_osigvec(0x1,0x7ffff998,0x7ffff9a4)
7557 cc RET compat_43_osigvec 0
7557 cc CALL compat_43_osigvec(0x1,0x7ffff998,0)
7557 cc RET compat_43_osigvec 0
7557 cc CALL getpid
7557 cc RET getpid 7557/0x1d85
7557 cc CALL vfork
7557 cc RET vfork 7558/0x1d86
7557 cc CALL compat_43_owait
7557 cc RET compat_43_owait 7558/0x1d86
7557 cc CALL vfork
7557 cc RET vfork 7559/0x1d87
7557 cc CALL compat_43_owait
7557 cc RET compat_43_owait 7559/0x1d87
7557 cc CALL unlink(0x600e)
7557 cc NAMI "/q/tmp/ctm075571"
7557 cc NAMI "/tmp/ctm075571"
7557 cc RET unlink -1 errno 2 No such file or directory
7557 cc CALL unlink(0x601d)
7557 cc NAMI "/q/tmp/ctm075572"
7557 cc NAMI "/tmp/ctm075572"
7557 cc RET unlink -1 errno 2 No such file or directory
7557 cc CALL unlink(0x603b)
7557 cc NAMI "/q/tmp/ctm075574"
7557 cc NAMI "/q"
7557 cc NAMI "/q/tmp/ctm075574"
7557 cc RET unlink 0
7557 cc CALL vfork
7557 cc RET vfork 7560/0x1d88
7557 cc CALL compat_43_owait
7557 cc RET compat_43_owait 7560/0x1d88
7557 cc CALL vfork
7557 cc RET vfork 7561/0x1d89
7557 cc CALL compat_43_owait
7557 cc RET compat_43_owait 7561/0x1d89
7557 cc CALL unlink(0x6058)
7557 cc NAMI "hello-world.o"
7557 cc RET unlink 0
7557 cc CALL unlink(0x600e)
7557 cc NAMI "/q/tmp/ctm075571"
7557 cc NAMI "/tmp/ctm075571"
7557 cc RET unlink -1 errno 2 No such file or directory
7557 cc CALL unlink(0x601d)
7557 cc NAMI "/q/tmp/ctm075572"
7557 cc NAMI "/tmp/ctm075572"
7557 cc RET unlink -1 errno 2 No such file or directory
7557 cc CALL unlink(0x602c)
7557 cc NAMI "/q/tmp/ctm075573"
7557 cc NAMI "/q"
7557 cc NAMI "/q/tmp/ctm075573"
7557 cc RET unlink 0
7557 cc CALL unlink(0x603b)
7557 cc NAMI "/q/tmp/ctm075574"
7557 cc NAMI "/tmp/ctm075574"
7557 cc RET unlink -1 errno 2 No such file or directory
7557 cc CALL close(0)
7557 cc RET close 0
7557 cc CALL close(0x1)
7557 cc RET close 0
7557 cc CALL close(0x2)
7557 cc RET close 0
7557 cc CALL exit(0)
[d] invalid executable from cc dumps core:
# ktrace -d ./hello-world
Illegal instruction - core dumped
# kdump
8188 ktrace EMUL "netbsd"
8188 ktrace RET ktrace 0
8188 ktrace CALL execve(0x7ffffa66,0x7ffffa28,0x7ffffa30)
8188 ktrace NAMI "./hello-world"
8188 hello-world EMUL "netbsd"
8188 hello-world PSIG SIGILL SIG_DFL
8188 hello-world NAMI "hello-world.core"
Home |
Main Index |
Thread Index |
Old Index