Jakub Jelinek wrote:
On Wed, Feb 18, 2015 at 11:21:56AM -0800, Jeff Prothero wrote:
Starting with gcc 4.9, -O2 implicitly invokes
-fisolate-erroneous-paths-dereference:
which
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
documents as
Detect paths that trigger erroneous or undefined behavior due to
dereferencing a null pointer. Isolate those paths from the main control
flow and turn the statement with erroneous or undefined behavior into a
trap. This flag is enabled by default at -O2 and higher.
This results in a sizable number of previously working embedded programs
mysteriously
crashing when recompiled under gcc 4.9. The problem is that embedded
programs will often have ram starting at address zero (think hardware-defined
interrupt vectors, say) which gets initialized by code which the
-fisolate-erroneous-paths-deference logic can recognize as reading and/or
writing address zero.
If you have some pages mapped at address 0, you really should compile your
code with -fno-delete-null-pointer-checks, otherwise you can run into tons
of other issues.
Hmmmm, Passing the additional option in user code would be one thing,
but what about library code? E.g., using memcpy (either explicitly or
implicitly for a structure copy)?
It looks to me like cr16 and avr are currently the only architectures
that disable flag_delete_null_pointer_checks entirely, but I am sure
that this issue affects other embedded targets besides nios2, too. E.g.
scanning Mentor's ARM board support library, I see a whole pile of
devices that have memory mapped at address zero (TI Stellaris/Tiva,
Energy Micro EFM32Gxxx, Atmel AT91SAMxxx, ....). Plus our simulator
BSPs assume a flat address space starting at address 0.
I can see both sides of the issue here.... On the one hand, you get
better code for 99.99% of situations by enabling
-fdelete-null-pointer-checks, but if it makes GCC unusable in the other
.01% case, that is a problem for the users for whom that case is
critical. :-S So I think Jeff's request here is something that
deserves an answer:
BTW, I'd also be curious to know what is regarded as engineering best
practice for writing a value to address zero when this is architecturally
required by the hardware platform at hand. Obviously one can do various
things to obscure the process sufficiently that the current gcc implementation
won't detect it and complain, but as gcc gets smarter about optimization
those are at risk of failing in a future release. It would be nice to have
a guaranteed-to-work future-proof idiom for doing this. Do we have one, short
of retreating to assembly code?
-Sandra