1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 31 typedef enum { t_char, t_short, t_int, t_long, t_double } Type; 32 typedef int (*TestFunc)( Type, void* ); 33 34 struct Description; 35 36 int IsBigEndian(void); 37 int IsStackGrowingDown_2( int * pI ); 38 int IsStackGrowingDown(void); 39 int GetStackAlignment_3( char*p, long l, int i, short s, char b, char c, ... ); 40 int GetStackAlignment_2( char*p, long l, int i, short s, char b, char c ); 41 int GetStackAlignment(void); 42 void PrintArgs( int p, ... ); 43 int check( TestFunc func, Type eT, void* p ); 44 45 #if defined (UNX) || defined (WNT) || defined (OS2) 46 47 #ifdef UNX 48 #include <unistd.h> 49 #endif 50 #include <sys/types.h> 51 52 #define I_STDARG 53 #ifdef I_STDARG 54 #include <stdarg.h> 55 #else 56 #include <varargs.h> 57 #endif 58 59 #define NO_USE_FORK_TO_CHECK 60 #ifdef USE_FORK_TO_CHECK 61 #include <sys/wait.h> 62 #else 63 #include <signal.h> 64 #include <setjmp.h> 65 #endif 66 67 #else 68 #endif 69 70 #define printTypeSize(Type,Name) printf( "sizeof(%s)\t= %d\n", Name, \ 71 sizeof (Type) ) 72 73 #define isSignedType(Type) (((Type)-1) < 0) 74 #define printTypeSign(Type,Name) printf( "%s\t= %s %s\n", Name, \ 75 ( isSignedType(Type) ? "unsigned" : "signed" ), Name ) 76 77 78 int IsBigEndian() 79 { 80 long l = 1; 81 return ! *(char*)&l; 82 } 83 84 int IsStackGrowingDown_2( int * pI ) 85 { 86 int i = 1; 87 return ((unsigned long)&i) < (unsigned long)pI; 88 } 89 90 int IsStackGrowingDown() 91 { 92 int i = 1; 93 return IsStackGrowingDown_2(&i); 94 } 95 96 int GetStackAlignment_3( char*p, long l, int i, short s, char b, char c, ... ) 97 { 98 (void) p; (void) l; (void) i; (void) s; /* unused */ 99 if ( IsStackGrowingDown() ) 100 return &c - &b; 101 else 102 return &b - &c; 103 } 104 105 int GetStackAlignment_2( char*p, long l, int i, short s, char b, char c ) 106 { 107 (void) p; (void) l; (void) i; (void) s; /* unused */ 108 if ( IsStackGrowingDown() ) 109 return &c - &b; 110 else 111 return &b - &c; 112 } 113 114 int GetStackAlignment() 115 { 116 int nStackAlignment = GetStackAlignment_3(0,1,2,3,4,5); 117 if ( nStackAlignment != GetStackAlignment_2(0,1,2,3,4,5) ) 118 printf( "Pascal calling convention\n" ); 119 return nStackAlignment; 120 } 121 122 123 124 125 #if defined (UNX) || defined (WNT) || defined (OS2) 126 127 #ifdef I_STDARG 128 void PrintArgs( int p, ... ) 129 #else 130 void PrintArgs( p, va_alist ) 131 int p; 132 va_dcl 133 #endif 134 { 135 int value; 136 va_list ap; 137 138 #ifdef I_STDARG 139 va_start( ap, p ); 140 #else 141 va_start( ap ); 142 #endif 143 144 printf( "value = %d", p ); 145 146 while ( ( value = va_arg(ap, int) ) != 0 ) 147 printf( " %d", value ); 148 149 printf( "\n" ); 150 va_end(ap); 151 } 152 153 #ifndef USE_FORK_TO_CHECK 154 static jmp_buf check_env; 155 static int bSignal; 156 #if defined (UNX) || defined (OS2) 157 void SignalHandler( int sig ) 158 #else 159 void __cdecl SignalHandler( int sig ) 160 #endif 161 { 162 bSignal = 1; 163 /* 164 fprintf( stderr, "Signal %d caught\n", sig ); 165 signal( sig, SignalHandler ); 166 */ 167 longjmp( check_env, sig ); 168 } 169 #endif 170 171 int check( TestFunc func, Type eT, void* p ) 172 { 173 #ifdef USE_FORK_TO_CHECK 174 pid_t nChild = fork(); 175 if ( nChild ) 176 { 177 int exitVal; 178 wait( &exitVal ); 179 if ( exitVal & 0xff ) 180 return -1; 181 else 182 return exitVal >> 8; 183 } 184 else 185 { 186 exit( func( eT, p ) ); 187 } 188 #else 189 int result; 190 191 bSignal = 0; 192 193 if ( !setjmp( check_env ) ) 194 { 195 signal( SIGSEGV, SignalHandler ); 196 #ifdef UNX 197 signal( SIGBUS, SignalHandler ); 198 #else 199 #endif 200 result = func( eT, p ); 201 signal( SIGSEGV, SIG_DFL ); 202 #ifdef UNX 203 signal( SIGBUS, SIG_DFL ); 204 #else 205 #endif 206 } 207 208 if ( bSignal ) 209 return -1; 210 else 211 return 0; 212 #endif 213 } 214 215 #endif 216 217 218 int GetAtAddress( Type eT, void* p ) 219 { 220 switch ( eT ) 221 { 222 case t_char: return *((char*)p); 223 case t_short: return *((short*)p); 224 case t_int: return *((int*)p); 225 case t_long: return *((long*)p); 226 case t_double: return *((double*)p); 227 } 228 abort(); 229 } 230 231 int SetAtAddress( Type eT, void* p ) 232 { 233 switch ( eT ) 234 { 235 case t_char: return *((char*)p) = 0; 236 case t_short: return *((short*)p) = 0; 237 case t_int: return *((int*)p) = 0; 238 case t_long: return *((long*)p) = 0; 239 case t_double: return *((double*)p)= 0; 240 } 241 abort(); 242 } 243 244 char* TypeName( Type eT ) 245 { 246 switch ( eT ) 247 { 248 case t_char: return "char"; 249 case t_short: return "short"; 250 case t_int: return "int"; 251 case t_long: return "long"; 252 case t_double: return "double"; 253 } 254 abort(); 255 } 256 257 int CheckGetAccess( Type eT, void* p ) 258 { 259 int b; 260 b = -1 != check( (TestFunc)GetAtAddress, eT, p ); 261 #if OSL_DEBUG_LEVEL > 1 262 fprintf( stderr, 263 "%s read %s at %p\n", 264 (b? "can" : "can not" ), TypeName(eT), p ); 265 #endif 266 return b; 267 } 268 int CheckSetAccess( Type eT, void* p ) 269 { 270 int b; 271 b = -1 != check( (TestFunc)SetAtAddress, eT, p ); 272 #if OSL_DEBUG_LEVEL > 1 273 fprintf( stderr, 274 "%s write %s at %p\n", 275 (b? "can" : "can not" ), TypeName(eT), p ); 276 #endif 277 return b; 278 } 279 280 int GetAlignment( Type eT ) 281 { 282 char a[ 16*8 ]; 283 int p = (int)(void*)&a; 284 int i; 285 p = ( p + 0xF ) & ~0xF; 286 for ( i = 1; i < 16; i++ ) 287 if ( CheckGetAccess( eT, (void*)(p+i) ) ) 288 return i; 289 return 0; 290 } 291 292 int CheckCharAccess( char* p ) 293 { 294 if ( CheckGetAccess( t_char, p ) ) 295 printf( "can read address %p\n", p ); 296 else 297 printf( "can not read address %p\n", p ); 298 299 if ( CheckSetAccess( t_char, p ) ) 300 printf( "can write address %p\n", p ); 301 else 302 printf( "can not write address %p\n", p ); 303 304 return 0; 305 } 306 307 struct Description 308 { 309 int bBigEndian; 310 int bStackGrowsDown; 311 int nStackAlignment; 312 int nAlignment[3]; /* 2,4,8 */ 313 }; 314 315 void Description_Ctor( struct Description* pThis ) 316 { 317 pThis->bBigEndian = IsBigEndian(); 318 pThis->bStackGrowsDown = IsStackGrowingDown(); 319 pThis->nStackAlignment = GetStackAlignment(); 320 321 if ( sizeof(short) != 2 ) 322 abort(); 323 pThis->nAlignment[0] = GetAlignment( t_short ); 324 if ( sizeof(int) != 4 ) 325 abort(); 326 pThis->nAlignment[1] = GetAlignment( t_int ); 327 if ( sizeof(double) != 8 ) 328 abort(); 329 pThis->nAlignment[2] = GetAlignment( t_double ); 330 } 331 332 void Description_Print( struct Description* pThis, char* name ) 333 { 334 int i; 335 FILE* f = fopen( name, "w" ); 336 fprintf( f, "#define __%s\n", 337 pThis->bBigEndian ? "BIGENDIAN" : "LITTLEENDIAN" ); 338 for ( i = 0; i < 3; i++ ) 339 fprintf( f, "#define __ALIGNMENT%d\t%d\n", 340 1 << (i+1), pThis->nAlignment[i] ); 341 fprintf( f, "#define __STACKALIGNMENT wird nicht benutzt\t%d\n", pThis->nStackAlignment ); 342 fprintf( f, "#define __STACKDIRECTION\t%d\n", 343 pThis->bStackGrowsDown ? -1 : 1 ); 344 fprintf( f, "#define __SIZEOFCHAR\t%d\n", sizeof( char ) ); 345 fprintf( f, "#define __SIZEOFSHORT\t%d\n", sizeof( short ) ); 346 fprintf( f, "#define __SIZEOFINT\t%d\n", sizeof( int ) ); 347 fprintf( f, "#define __SIZEOFLONG\t%d\n", sizeof( long ) ); 348 fprintf( f, "#define __SIZEOFPOINTER\t%d\n", sizeof( void* ) ); 349 fprintf( f, "#define __SIZEOFDOUBLE\t%d\n", sizeof( double ) ); 350 fprintf( f, "#define __IEEEDOUBLE\n" ); 351 fprintf( f, "#define _SOLAR_NODESCRIPTION\n" ); 352 353 fclose(f); 354 } 355 356 int 357 #ifdef WNT 358 __cdecl 359 #endif 360 main( int argc, char* argv[] ) 361 { 362 printTypeSign( char, "char" ); 363 printTypeSign( short, "short" ); 364 printTypeSign( int, "int" ); 365 printTypeSign( long, "long" ); 366 367 printTypeSize( char, "char" ); 368 printTypeSize( short, "short" ); 369 printTypeSize( int, "int" ); 370 printTypeSize( long, "long" ); 371 printTypeSize( float, "float" ); 372 printTypeSize( double, "double" ); 373 printTypeSize( void *, "void *" ); 374 375 if ( IsBigEndian() ) 376 printf( "BIGENDIAN (Sparc, MC680x0, RS6000)\n" ); 377 else 378 printf( "LITTLEENDIAN (Intel, VAX, PowerPC)\n" ); 379 380 if( IsStackGrowingDown() ) 381 printf( "Stack waechst nach unten\n" ); 382 else 383 printf( "Stack waechst nach oben\n" ); 384 385 printf( "STACKALIGNMENT : %d\n", GetStackAlignment() ); 386 387 PrintArgs( 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ); 388 389 { 390 char a[64]; 391 int i = 56; 392 do 393 { 394 printf( "Zugriff long auf %i-Aligned Adresse : ", i / 7 ); 395 printf( ( CheckGetAccess( t_long, (long*)&a[i] ) ? "OK\n" : "ERROR\n" ) ); 396 i >>= 1; 397 } while( i >= 7 ); 398 } 399 400 { 401 char a[64]; 402 int i = 56; 403 do 404 { 405 printf( "Zugriff double auf %i-Aligned Adresse : ", i / 7 ); 406 printf( ( CheckGetAccess( t_double, (double*)&a[i] ) ? "OK\n" : "ERROR\n" ) ); 407 i >>= 1; 408 } while( i >= 7 ); 409 } 410 411 { 412 char* p = NULL; 413 CheckCharAccess( p ); 414 p = (char*)&p; 415 CheckCharAccess( p ); 416 } 417 418 if ( argc > 1 ) 419 { 420 struct Description description; 421 Description_Ctor( &description ); 422 Description_Print( &description, argv[1] ); 423 } 424 425 exit( 0 ); 426 return 0; 427 } 428