From 82f8d0bce10403deab704871e638edc24e7933ee Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 15 Sep 2011 16:59:21 +0200 Subject: Defeat compiler optimization which assumes function addresses are never NULL From email: A warning for people who can be hit by the same or similar issue: gcc 4.1.2 with -march=i486 here with -Os and even with -O2 or -O is "optimizing away" the check if (_stdio_term) in libc/stdlib/_atexit.c which results in a "call 0" and a segfault at exit if you do not happen to link in stdio. Signed-off-by: Denys Vlasenko --- libc/stdlib/abort.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'libc/stdlib/abort.c') diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c index 3cc796370..a5bac461a 100644 --- a/libc/stdlib/abort.c +++ b/libc/stdlib/abort.c @@ -28,6 +28,17 @@ Cambridge, MA 02139, USA. */ +/* Defeat compiler optimization which assumes function addresses are never NULL */ +static __always_inline int not_null_ptr(const void *p) +{ + const void *q; + __asm__ ("" + : "=r" (q) /* output */ + : "0" (p) /* input */ + ); + return q != 0; +} + /* Our last ditch effort to commit suicide */ #ifdef __UCLIBC_ABORT_INSTRUCTION__ # define ABORT_INSTRUCTION __asm__(__UCLIBC_ABORT_INSTRUCTION__) @@ -68,7 +79,7 @@ void abort(void) * this will attempt to commit all buffered writes. It may also * unbuffer all writable files, or close them outright. * Check the stdio routines for details. */ - if (_stdio_term) { + if (not_null_ptr(_stdio_term)) { _stdio_term(); } #endif -- cgit v1.2.3