diff --git a/ChangeLog b/ChangeLog index 3edb0d0a3..b3e8436b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2013-11-07 Vladimir Serbinenko + + Allow compiling with clang (not really supported though). + + * conf/Makefile.common (CFLAGS_PLATFORM): Don't add -mrtd -mregparm=3 + unconditionally. + * configure.ac: Add -no-integrated-as when using clangfor asm files. + Add -mrtd -mregparm=3 on i386 when not using clang. + * grub-core/kern/misc.c (grub_memset): Add volatile when on clang. + 2013-11-07 Vladimir Serbinenko * grub-core/kern/ieee1275/cmain.c: Add explicit attribute on asm diff --git a/conf/Makefile.common b/conf/Makefile.common index 0aec25f83..f1d9a558a 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -6,18 +6,6 @@ export LC_COLLATE := C unexport LC_ALL # Platform specific options -if COND_i386_pc - CFLAGS_PLATFORM += -mrtd -mregparm=3 -endif -if COND_i386_qemu - CFLAGS_PLATFORM += -mrtd -mregparm=3 -endif -if COND_i386_coreboot - CFLAGS_PLATFORM += -mrtd -mregparm=3 -endif -if COND_i386_ieee1275 - CFLAGS_PLATFORM += -mrtd -mregparm=3 -endif if COND_mips_loongson CFLAGS_PLATFORM += -mexplicit-relocs CPPFLAGS_PLATFORM = -DUSE_ASCII_FALLBACK diff --git a/configure.ac b/configure.ac index 020c7696e..37d928979 100644 --- a/configure.ac +++ b/configure.ac @@ -480,6 +480,45 @@ if test "x$target_cpu" != xi386 && test "x$target_cpu" != xx86_64; then TARGET_CFLAGS="$TARGET_CFLAGS -Wcast-align" fi +AC_CACHE_CHECK([if compiling with clang], [grub_cv_cc_target_clang] +[AC_COMPILE_IFELSE( +[AC_LANG_PROGRAM([], [[ +#ifdef __clang__ +#error "is clang" +#endif +]])], +[grub_cv_cc_target_clang=no], [grub_cv_cc_target_clang=yes])]) + +if test "x$grub_cv_cc_target_clang" = xyes; then + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -no-integrated-as" +fi + +if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then + TARGET_CFLAGS="$TARGET_CFLAGS -march=i386" +fi + +if test "x$target_m32" = x1; then + # Force 32-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m32" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m32" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" + TARGET_MODULE_FORMAT="elf32" +fi + +if test "x$target_m64" = x1; then + # Force 64-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m64" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m64" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" + TARGET_MODULE_FORMAT="elf64" +fi + +if test "x$grub_cv_cc_target_clang" = xno && test "x$target_cpu" = xi386 && test "x$platform" != xemu && test "x$platform" != xefi; then + TARGET_CFLAGS="$TARGET_CFLAGS -mrtd -mregparm=3" +fi + # Force no alignment to save space on i386. if test "x$target_cpu" = xi386; then AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [ @@ -647,28 +686,6 @@ enable_efiemu=no fi AC_SUBST([enable_efiemu]) -if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then - TARGET_CFLAGS="$TARGET_CFLAGS -march=i386" -fi - -if test "x$target_m32" = x1; then - # Force 32-bit mode. - TARGET_CFLAGS="$TARGET_CFLAGS -m32" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32" - TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m32" - TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" - TARGET_MODULE_FORMAT="elf32" -fi - -if test "x$target_m64" = x1; then - # Force 64-bit mode. - TARGET_CFLAGS="$TARGET_CFLAGS -m64" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64" - TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m64" - TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" - TARGET_MODULE_FORMAT="elf64" -fi - case "$target_os" in cygwin) ;; diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index e940acbd3..c875d8524 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -454,6 +454,15 @@ grub_strndup (const char *s, grub_size_t n) return p; } +/* clang detects that we're implementing here a memset so it decides to + optimise and calls memset resulting in infinite recursion. With volatile + we make it not optimise in this way. */ +#ifdef __clang__ +#define VOLATILE_CLANG volatile +#else +#define VOLATILE_CLANG +#endif + void * grub_memset (void *s, int c, grub_size_t len) { @@ -470,13 +479,13 @@ grub_memset (void *s, int c, grub_size_t len) while (len > 0 && (((grub_addr_t) p) & (sizeof (unsigned long) - 1))) { - *(grub_uint8_t *) p = pattern8; + *(VOLATILE_CLANG grub_uint8_t *) p = pattern8; p = (grub_uint8_t *) p + 1; len--; } while (len >= sizeof (unsigned long)) { - *(unsigned long *) p = patternl; + *(VOLATILE_CLANG unsigned long *) p = patternl; p = (unsigned long *) p + 1; len -= sizeof (unsigned long); } @@ -484,7 +493,7 @@ grub_memset (void *s, int c, grub_size_t len) while (len > 0) { - *(grub_uint8_t *) p = pattern8; + *(VOLATILE_CLANG grub_uint8_t *) p = pattern8; p = (grub_uint8_t *) p + 1; len--; }