http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55916

--- Comment #11 from Jouko Orava <jouko.orava at iki dot fi> ---
Just in case there are users who encounter this bug report,
here is the single-file workaround. Save the following as
nosegfault.c, and follow the instructions in the comments.

It can be compiled into a shared library used e.g. via LD_PRELOAD,
or into an object file and linked directly to a C or GNU Fortran
program, to fix the issue.

(It is trivial, so I consider it to be either uncopyrightable,
 or if it is copyrightable, in the public domain.
 It should still be smart enough to work on all architectures,
 as long as GCC's __BIGGEST_ALIGNMENT__ is reliable.)
_______________________________________________________________________

#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <errno.h>

/* Compile to a dynamic library:
 *   gcc $FLAGS -fPIC -shared nosegfault.c \
 *       -Wl,-soname,libnosefault.so -o libnosegfault.so
 * Install the dynamic library at e.g. /usr/local/lib/,
 *   sudo install -m 0644 libnosegfault.so /usr/local/lib/
 * and you can use it via e.g.
 *   env LD_PRELOAD=/usr/local/lib/libnosegfault.so COMMAND [ ARGS .. ]
 *
 * Compile this into an object file:
 *   gcc $FLAGS -c nosegfault.c
 * compile your application, adding
 *   nosegfault.o
 * to the build or final linking command; for example,
 *   gfortran $FLAGS .... nosegfault.o -o program
 *
 * $FLAGS may be empty, or contain your preferred optimization flags.
 * If you are compiling 32-bit code, remember to include -m32 in it.
 *
 * If you compile static binaries, use a copy of the libc.a file
 * (mentioned in the error if you try to compile with the object file
 *  statically), with malloc, calloc, __libc_malloc, and __libc_calloc
 *  replaced by the objects in this file, using e.g. 'ar'.
*/

#if   __BIGGEST_ALIGNMENT__ <= 8
# error "You don't need this, or your compiler options are wrong."
#elif __BIGGEST_ALIGNMENT__ <= 16
# define ALIGNMENT 16
#elif __BIGGEST_ALIGNMENT__ <= 32
# define ALIGNMENT 32
#elif __BIGGEST_ALIGNMENT__ <= 64
# define ALIGNMENT 64
#else
# error "Your architecture has insane alignment requirements."
#endif

void *malloc(size_t size)
{
    return memalign(ALIGNMENT, size);
}

void *__libc_malloc(size_t size)
{
    return memalign(ALIGNMENT, size);
}

void *calloc(size_t count, size_t size)
{
    if (!count || !size) {
        return NULL;
    } else {
        const size_t n = size * count;
        if ((size_t)(n / size) == count) {
            void *p = memalign(ALIGNMENT, n);
            if (!p)
                return NULL;
            memset(p, 0, n);
            return p;
        }
        errno = ENOMEM;
        return NULL;
    }
}

void *__libc_calloc(size_t count, size_t size)
{
    if (!count || !size) {
        return NULL;
    } else {
        const size_t n = size * count;
        if ((size_t)(n / size) == count) {
            void *p = memalign(ALIGNMENT, n);
            if (!p)
                return NULL;
            memset(p, 0, n);
            return p;
        }
        errno = ENOMEM;
        return NULL;
    }
}

/* The End. */

Reply via email to