| Since the fault shown in .0 is on an ldq at a 4-byte-aligned address,
most likely this is a struct-pointer dereference, the first of the
differences noted by Joe in .1.
Since you say that this code was originally written under VAX C (where
alignment was not really an issue), and does lots of pointer casting,
it's reasonably likely that you'd get a number of alignments faults.
You may also be getting the same faults on OpenVMS Alpha and just not
noticing because by default they get fixed up silently on that platform.
Instead of using -assume noaligned_objects, which is a huge hammer that
will produce awful generated code to avoid any alignment faults, you
should consider fixing the source code. The alignment fault locations
identify the faulting instructions, from which you can determine the
source code. With luck, there may be only a handful of distinct struct
types involved in pointer casts in the faulting locations, and by
analyzing those types you'll be able to do one or more of the following:
1. Change the larger-aligned type to be smaller-aligned.
This can be done with #pragma pack.
2. Change the smaller-aligned type to be larger-aligned. This
can be done by making the interior of the smaller-alligned struct
a union against a double or a long (__int64 on VMS). Depending on
how this is done, you may have to change some or all expressions that
refer to members of the original struct. The variant_struct feature
of -vaxc mode, the unnamed member feature of -ms mode, or a set of
macro definitions (if the member names are globally unique) can
be used to avoid changing each referencing expression.
3. If there are only a handful of specific references that are a problem,
the problem dereferences can be changed to cast to a pointer to
an __unaligned struct. E.g. if "((struct foo *)ptr)->member" is
getting an alignment fault, change it to
"((__unaligned struct foo *)ptr)->member)". Note the placement of
__unaligned. Similar-looking things that will *not* work are:
((struct foo * __unaligned)ptr)->member;
typedef struct foo * fooptr;
((__unaligned fooptr)ptr)->member;
If the pointer type is within a typedef, you cannot use __unaligned
effectively in a cast using that typedef name. You either need to
make a new typedef, or change the cast to use the type underlying
the original typedef, e.g.:
typedef __unaligned struct foo * ufooptr;
((ufooptr)ptr)->member;
Correct use of __unaligned will produce the same code as -assume
noaligned_objects, but only on those accesses that are actually
marked instead of forcing all pointer accesses throughout the code
to be made that way.
|