1AC_ARG_ENABLE([gcc-vcheck], 2[AS_HELP_STRING([--disable-gcc-vcheck], [do not check for buggy gcc version])], 3gcc_check=$enableval, gcc_check="yes") 4 5msg_gcc_check="use --disable-gcc-vcheck to disable this check. Before reporting any bugs check with a supported version of gcc" 6VERSION_SUFFIX= 7dnl Check for gcc-4.1.0 8if test "$gcc_check" = "yes"; then 9 if test "x$ac_compiler_gnu" = "xyes"; then 10 AC_MSG_CHECKING([for a supported version of gcc]) 11 gcc_version=`${CC} -dumpversion` 12 case "${gcc_version}" in 13 4.1.0*) 14 AC_MSG_RESULT([no (${gcc_version})]) 15 AC_MSG_ERROR([gcc 4.1.0 is known to incorrectly compile upx.c. Upgrade your compiler to at least 4.1.1/4.1.2)]) 16 ;; 17 *) 18 AC_MSG_RESULT([ok (${gcc_version})]) 19 ;; 20 esac 21 case "${gcc_version}" in 22 [[56789]].* | 4.[[3456789]].*) 23 # bb #1581 - temporarily add -fno-strict-aliasing so gcc 4.4.0 24 # works correctly 25 CFLAGS="$CFLAGS -fno-strict-aliasing" 26 ;; 27 *) 28 ;; 29 esac 30 fi 31else 32 CFLAGS="$CFLAGS -O0" 33 VERSION_SUFFIX="$VERSION_SUFFIX-broken-compiler" 34fi 35 36# add distcheck warning flags 37distcheck_enable_flags=0 38if test "x$ac_compiler_gnu" = "xyes"; then 39 gcc_version=`${CC} -dumpversion` 40 case "${gcc_version}" in 41 4.[[3456789]]*) 42 distcheck_enable_flags=1 43 ;; 44 [[56789]].*) 45 distcheck_enable_flags=1 46 ;; 47 esac 48fi 49 50dnl Checks if compiler produces valid code, regardless of compiler 51dnl we do these checks here to avoid receiving endless bugreports about 52dnl breakages due to compiler bugs. 53 54dnl Check if compiler produces invalid code on gcc PR27603 (affects upx.c) 55dnl testcase from gcc testsuite 56AC_MSG_CHECKING([for gcc bug PR27603]) 57AC_TRY_RUN( 58 [ 59/* (C) Richard Guenther */ 60void exit (int); 61void abort (void); 62int a; 63int main(void) 64{ 65 int j; 66 for (j = 0; j < 6; j++) 67 { 68 if ((unsigned)j - 3 <= 1) 69 exit (0); 70 a = 1000 * (6 - j); 71 } 72 abort (); 73} 74], [AC_MSG_RESULT([ok, bug not present])], 75[AC_MSG_ERROR([your compiler has gcc PR27603 bug, use a different compiler, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27603])], [AC_MSG_RESULT([cross-compiling, assumed ok])]) 76 77dnl Check if compiler produces invalid code on gcc PR26763-2 (affects upx.c) 78dnl testcase from gcc testsuite 79AC_MSG_CHECKING([for gcc bug PR26763-2]) 80AC_TRY_RUN( 81 [ 82/* (C) Richard Guenther */ 83extern void abort(void); 84 85static int try (char *a, int d) 86{ 87 return a + d > a; 88} 89 90int main(void) 91{ 92 char bla[100]; 93 94 if (try (bla + 50, -1)) 95 abort (); 96 97 return 0; 98} 99], [AC_MSG_RESULT([ok, bug not present])], 100[AC_MSG_ERROR([your compiler has gcc PR26763-2 bug, use a different compiler, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26763])],[AC_MSG_RESULT([cross-compiling, assumed ok])]) 101 102dnl Check if compiler produces invalid code on own testcase based on upx.c 103AC_MSG_CHECKING([for valid code generation of CLI_ISCONTAINED]) 104AC_TRY_RUN( 105 [ 106#include <stdio.h> 107static struct v{ 108 char* dst; 109 unsigned int dsize; 110 unsigned int dcur; 111 unsigned int backsize; 112 signed int unp_offset; 113} values[] = { 114 {(char*)0xf78ab008, 0x2e000, 1, 4, -1594}, 115 {(char*)0xb7af1008, 0x2e000, 1, 4, -1594} 116 117}; 118extern void abort(void); 119 120#define CLI_ISCONTAINED(bb, bb_size, sb, sb_size) \ 121 ((bb_size) > 0 && (sb_size) > 0 && (size_t)(sb_size) <= (size_t)(bb_size) \ 122 && (sb) >= (bb) && ((sb) + (sb_size)) <= ((bb) + (bb_size)) && ((sb) + (sb_size)) > (bb) && (sb) < ((bb) + (bb_size))) 123 124int crashtest() 125{ 126 unsigned int backsize, dcur; 127 int dval=0x12000, unp_offset; 128 int* dsize = &dval; 129 char* dst = (char*)0x12000; 130 while(1) { 131 backsize=4; 132 dcur=0; 133 unp_offset=0x800002c7; 134 135 if (!CLI_ISCONTAINED(dst, *dsize, dst+dcur+unp_offset, backsize) || !CLI_ISCONTAINED(dst, *dsize, dst+dcur, backsize) || unp_offset >=0) 136 return -1; 137 abort(); 138 } 139 return 0; 140} 141 142int main(void) 143{ 144 size_t i; 145 for(i=0;i<sizeof(values)/sizeof(values[0]);i++) { 146 struct v* v= &values[i]; 147 char* dst = v->dst; 148 unsigned int* dsize = &v->dsize; 149 unsigned int dcur = v->dcur; 150 unsigned int backsize = v->backsize-1; 151 signed int unp_offset = v->unp_offset; 152 153 if(!CLI_ISCONTAINED(dst, *dsize, dst+dcur+unp_offset, backsize) || 154 !CLI_ISCONTAINED(dst, *dsize,dst+dcur,backsize) || unp_offset >= 0) { 155 continue; 156 } 157 abort(); 158 } 159 crashtest(); 160 return 0; 161} 162], [AC_MSG_RESULT([ok, bug not present])], 163[AC_MSG_ERROR([your compiler has a bug that causes clamav bug no. 670, use a different compiler, see https://bugzilla.clamav.net/show_bug.cgi?id=670])], [AC_MSG_RESULT([cross-compiling, assumed ok])]) 164 165dnl Check if compiler produces invalid code on gcc PR28045 (affects upx.c) 166dnl testcase from gcc testsuite 167AC_MSG_CHECKING([for gcc bug PR28045]) 168AC_TRY_RUN( 169 [ 170/* (C) Andrew Pinski */ 171extern void abort(void); 172struct a 173{ 174 unsigned int bits : 1; 175 signed long val : ((sizeof(long) * 8) - 1); 176}; 177static int Fnegate (struct a b) 178{ 179 if ((-((long)b.val)) <= ((long) ((1UL << ((sizeof(long) * 8) - 2)) -1UL)) 180 && (-((long)b.val)) >= (-(((long) ((1UL << ((sizeof(long) * 8) - 2)) -1UL))) - 1)) 181 return 0 ; 182 abort (); 183} 184int main (void) 185{ 186 struct a b = {1, 1}; 187 Fnegate (b); 188 return 0; 189} 190], [AC_MSG_RESULT([ok, bug not present])], 191[AC_MSG_ERROR([your compiler has gcc PR28045 bug, use a different compiler, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28045])], [AC_MSG_RESULT([cross-compiling, assumed ok])]) 192 193dnl Check if compiler produces invalid code on gcc PR37573 (affects autoit.c) 194dnl this is a bug in gcc 4.4.0, but for some reason it affects gcc 4.1.2 too 195dnl gcc 4.1.3 is OK. This bug occurs only at -O3. 196AC_MSG_CHECKING([for gcc bug PR37573]) 197AC_TRY_RUN( 198 [ 199#include <stdlib.h> 200#include <string.h> 201struct S 202{ 203 unsigned int *a; 204 unsigned int b; 205 unsigned int c[624]; 206}; 207static unsigned char 208foo (struct S *s) 209{ 210 unsigned int r; 211 if (!--s->b) 212 { 213 unsigned int *c = s->c; 214 unsigned int i; 215 s->a = c; 216 for (i = 0; i < 227; i++) 217 c[i] = 218 ((((c[i] ^ c[i + 1]) & 0x7ffffffe) ^ c[i]) >> 1) ^ 219 ((0 - (c[i + 1] & 1)) & 0x9908b0df) ^ c[i + 397]; 220 for (; i < 623; i++) 221 c[i] = 222 ((((c[i] ^ c[i + 1]) & 0x7ffffffe) ^ c[i]) >> 1) ^ 223 ((0 - (c[i + 1] & 1)) & 0x9908b0df) ^ c[i - 227]; 224 c[623] = 225 ((((c[623] ^ c[0]) & 0x7ffffffe) ^ c[623]) >> 1) ^ ((0 - (c[0] & 1)) & 226 0x9908b0df) ^ c[i 227 - 228 227]; 229 } 230 r = *(s->a++); 231 r ^= (r >> 11); 232 r ^= ((r & 0xff3a58ad) << 7); 233 r ^= ((r & 0xffffdf8c) << 15); 234 r ^= (r >> 18); 235 return (unsigned char) (r >> 1); 236} 237 238void 239bar (unsigned char *p, unsigned int q, unsigned int r) 240{ 241 struct S s; 242 unsigned int i; 243 unsigned int *c = s.c; 244 *c = r; 245 for (i = 1; i < 624; i++) 246 c[i] = i + 0x6c078965 * ((c[i - 1] >> 30) ^ c[i - 1]); 247 s.b = 1; 248 while (q--) 249 *p++ ^= foo (&s); 250}; 251 252static unsigned char p[23] = { 253 0xc0, 0x49, 0x17, 0x32, 0x62, 0x1e, 0x2e, 0xd5, 0x4c, 0x19, 0x28, 0x49, 254 0x91, 0xe4, 0x72, 0x83, 0x91, 0x3d, 0x93, 0x83, 0xb3, 0x61, 0x38 255}; 256 257static unsigned char q[23] = { 258 0x3e, 0x41, 0x55, 0x54, 0x4f, 0x49, 0x54, 0x20, 0x55, 0x4e, 0x49, 0x43, 259 0x4f, 0x44, 0x45, 0x20, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x3c 260}; 261 262int 263main (void) 264{ 265 unsigned int s; 266 s = 23; 267 bar (p, s, s + 0xa25e); 268 if (memcmp (p, q, s) != 0) 269 abort (); 270 return 0; 271} 272 273], [AC_MSG_RESULT([ok, bug not present])], 274[AC_MSG_ERROR([your compiler has gcc PR37573 bug, use a lower optimization level (-O1 or -O2), see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37573])], [AC_MSG_RESULT([cross-compiling, assumed ok])]) 275 276# It's not fatal if gperf is missing 277AM_MISSING_PROG(GPERF, gperf) 278AC_SUBST(GPERF) 279 280AC_TYPE_OFF_T 281AC_COMPILE_CHECK_SIZEOF([short]) 282AC_COMPILE_CHECK_SIZEOF([int]) 283AC_COMPILE_CHECK_SIZEOF([long]) 284AC_COMPILE_CHECK_SIZEOF([long long]) 285AC_COMPILE_CHECK_SIZEOF([void *]) 286