[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Architectures where unaligned access is (not) OK?



* Simon McVittie <smcv@debian.org> [141121 13:42]:
> A couple of questions for people who know low-level things:
>
> * Of Debian's architectures (official and otherwise), which ones are
>   known/defined/designed to be OK with unaligned accesses from
>   user-space, and which ones (can be configured to) crash or give wrong
>   answers?
[...]
> The ones I know for sure are:
>
> - OK: any-i386, any-amd64

Are you sure about those, especially amd64? AFAIK some newer
instructions (I think something about vector code) have much tighter
requirements than the old 80386 modus operandi of "everything might be unaligned,
it is just slower then").

> The context is that
> https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=757037 describes lzo2
> failing to start up on armel due to unaligned memory accesses. lzo2 has
> a cpp macro, LZO_CFG_NO_UNALIGNED which can be defined to stop it doing
> "clever" things with casting pointers.

'"clever" things with casting pointers' sounds like someone thought C
was an assembler and not a language with quite tight requirements on
what you are allowed to do. If something does 'clever things' I strongly
recommend to compile it with -O0. Optimisation of the compiler is only
supposed to keep the behaviour of conforming code, with 'clever' things
everything is possible.

> If the maintainer doesn't object
> (or fix the bug of course), I intend to NMU lzo2 to use that macro on at
> least armel; I would like to sanity-check whether I should be using a
> blacklist or whitelist approach, and which architectures other than
> armel should be on the blacklist, or which architectures other than x86
> should be on the whitelist.
> 
> Relatedly, if we have
> 
>     typedef struct lzo_memops_TU2_struct {
>       unsigned char a[2];
>     } lzo_memops_TU2;
> 
>     *(lzo_memops_TU2 *) (void *) dest =
>         *(const lzo_memops_TU2 *) (void *) src;
> 
> is gcc within its rights to optimize that into an aligned 16-bit load
> and an aligned 16-bit store, even though alignof(lzo_memops_TU2) == 1;
> or should gcc be emitting pessimistic byte-by-byte code for that?

With the "*(const lzo_memops_TU2 *) (void *) src" you tell the compiler
that src is pointing to a memory address that is a lzo_memops_TU2_struct. 
In a case where it is not gcc is free to assume that this code path is
not  inteded to be ever executed and may replace it in any way it see fit
to cope with other code paths (luckily replacing the code with
'system("rm -rf /");' is unlikely to happen, though that would totally
legit for a compiler in cases src points to anything else.)
For dest things are a bit more complicated. If the alignment is wrong
gcc might replace the code with anything it wants. Otherwise that memory
might afterwards be regarded as lzo_memops_TU2_struct and accessing it
as anything else is fair game for the compiler to assume it is dead
code.

	Bernhard R. Link
-- 
F8AC 04D5 0B9B 064B 3383  C3DA AFFC 96D1 151D FFDC


Reply to: