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