summaryrefslogtreecommitdiff
path: root/libc/stdlib/abort.c
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2011-09-15 16:59:21 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2011-09-15 16:59:21 +0200
commit82f8d0bce10403deab704871e638edc24e7933ee (patch)
tree1afb443b538e0dcdaed4908dac4872a73366f3bb /libc/stdlib/abort.c
parent200895dab88678b5b4e7d1dac9172be23e92eb31 (diff)
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 <dvlasenk@redhat.com>
Diffstat (limited to 'libc/stdlib/abort.c')
-rw-r--r--libc/stdlib/abort.c13
1 files changed, 12 insertions, 1 deletions
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