Subject: Re: unaligned access
To: nm <nmanisca@vt.edu>
From: Chris G. Demetriou <cgd@pa.dec.com>
List: port-alpha
Date: 05/19/1998 18:54:07
> will an unaligned access cause a program to fail on netbsd/alpha 1.3?

by default, user unaligned accesses other than unaligned accesses
caused by VAX floating point instructions (in other words, "all
unaligned accesses you are likely to see") are fixed up, but print a
warning.

for instance:

18 [notunix] tmp % cat foo.c

main()
{
        long l[2];

        printf("%lx\n", *(long *)((char *)l + 4));
}
19 [notunix] tmp % cc foo.c
20 [notunix] tmp % ./a.out
pid 20482 (a.out): unaligned access: va=0x1fffff284 pc=0x120000ae0 ra=0x120000750 op=ldq
fffff80000000001

The Alpha Architecture specifies that general purpose OSes "must" do
the fixups for application programs under normal circumstances.  (I
forget what the exact words are, and it's not clear that there's a
real penalty for violating the dictum, but I decided that it'd be nice
to do it by default.  I can quote chapter & verse if necessary, but
not easily right now.  8-) Support for doing this for VAX FP
instructions can be enabled with a kernel option, but it's not in most
kernels because it's _very_, _very_ unlikely that anyone will need
that under NetBSD/alpha unless they know _exactly_ what they're doing,
in which case they can enable it.


Note that unaligned accesses in the kernel are _not_ fixed up, and
will cause the kernel to panic.


In my opinion, no properly written program should _EVER_ cause an
unaligned access fault on the Alpha.  I can imagine reasons why people
might do it intentionally, but I'd say that any code author that does
... needs some adjustment.  However, there are lots of reasons -- most
bugs -- why it would happen unintentionally.

The system-wide default behavior can be controlled with the sysctl
variables:

	machdep.unaligned_print = 1
	machdep.unaligned_fix = 1
	machdep.unaligned_sigbus = 0

(Those are their default values.)

machdep.unaligned_print controls whether or not the warning is
printed.

machdep.unaligned_fix controls whether the access is "fixed up" to do
that the program (likely) intended.

machdep.unaligned_sigbus forces a SIGBUS on all unaligned accesses.

Note that the existing code will _not_ let processes run with
known-bogus data.  That is, if you disable unaligned access fixups,
processes will get SIGBUS regardless of the value of unaligned_sigbus.
(If the access isn't fixed up, no data remotely related to what the
program expected is in the register or memory, depending whether
you're doing a load or store.  In that case, it's "always" best to
kill the program immediately rather than let it die later because of
the bogus data.)

I forget whether the default values are currently settable via a
compile-time option.


In a perfect world, there would be per-process controlls for the
flags, as well, a la Digital UNIX's 'uac' command (but a bit more
configurable).  For each axis of control (same ones as you can specify
with sysctl), i would allow the states:

	* default to system's default behaviour (per the global sysctl)

	* "true"

	* "false"

The settings would be inherited across fork (I dunno what 'exec'
should do -- several reasonable arguments can be made 8-).





cgd