The 68000 architecture requires that (16-bit) word and (32-bit) long memory accesses are aligned with even addresses, but GCC frequently emits code that breaks this when compiling with optimisations (O1 or higher). This causes address error exceptions, which are fatal errors that crash programs. For example, consider struct s { char a, b, c, d, e; }; struct s f(char a) { return (struct s) { .a = a, .d = 'd' }; } that GCC with O1 will compile into 00000000 <f>: 0: 2049 moveal %a1,%a0 2: 202f 0004 movel %sp@(4),%d0 6: 42a9 0001 clrl %a1@(1) /* <<<--- unaligned long clear */ a: 1280 moveb %d0,%a1@ c: 137c 0064 0003 moveb #100,%a1@(3) 12: 4e75 rts where offset 6 has "clrl %a1@(1)", which is an unaligned 32-bit long clear. GCC can emit several similar variants of this, for example unaligned 16-bit word clears, and possibly others.
How did you configure the compiler?
To obtain the object file I can run the command m68k-unknown-linux-gnu-gcc -O1 -march=68000 -c -o address-error.o address-error.c with a cross-compiler made using the Gentoo package sys-devel/crossdev having the target m68k-unknown-linux-gnu.
m68k-linux requires m68020+, you cannot combine that with -march=68000.
Well, GCC accepts -march=68000 as a valid option and so it doesn't seem to make sense that it then proceeds to generate code for something incompatible like the 68020. As far as I understand, other targets such as MIPS don't behave like that: a MIPS III compiler can generate code for MIPS I without problems, for instance. What target(s) would you recommend for the compiler to (completely and without exceptions) honour the given -march=68000 option?
Anything but linux.
Then I would suggest it's a bug that GCC doesn't reject -march=68000 in combination with linux. Unsuspecting projects use this, and in fact it almost works except for random crashes every now and then, which is a grave quality problem to be sure.
The correct target to use in this case is m68k-elf.
Thanks, Mikael. Users evidently take whatever m68k-* GCC they have at hand and so 68000-projects therefore must have a special configure test to verify that -march=68000 isn't broken with the user's choice of GCC. I must say I do think it's quite wrong to blame the user for this problem.