1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: solar.c,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
34 typedef enum { t_char
, t_short
, t_int
, t_long
, t_double
} Type
;
35 typedef int (*TestFunc
)( Type
, void* );
39 int IsBigEndian(void);
40 int IsStackGrowingDown_2( int * pI
);
41 int IsStackGrowingDown(void);
42 int GetStackAlignment_3( char*p
, long l
, int i
, short s
, char b
, char c
, ... );
43 int GetStackAlignment_2( char*p
, long l
, int i
, short s
, char b
, char c
);
44 int GetStackAlignment(void);
45 void PrintArgs( int p
, ... );
46 int check( TestFunc func
, Type eT
, void* p
);
48 #if defined (UNX) || defined (WNT) || defined (OS2)
53 #include <sys/types.h>
62 #define NO_USE_FORK_TO_CHECK
63 #ifdef USE_FORK_TO_CHECK
73 #define printTypeSize(Type,Name) printf( "sizeof(%s)\t= %d\n", Name, \
76 #define isSignedType(Type) (((Type)-1) < 0)
77 #define printTypeSign(Type,Name) printf( "%s\t= %s %s\n", Name, \
78 ( isSignedType(Type) ? "unsigned" : "signed" ), Name )
87 int IsStackGrowingDown_2( int * pI
)
90 return ((unsigned long)&i
) < (unsigned long)pI
;
93 int IsStackGrowingDown()
96 return IsStackGrowingDown_2(&i
);
99 int GetStackAlignment_3( char*p
, long l
, int i
, short s
, char b
, char c
, ... )
101 (void) p
; (void) l
; (void) i
; (void) s
; /* unused */
102 if ( IsStackGrowingDown() )
108 int GetStackAlignment_2( char*p
, long l
, int i
, short s
, char b
, char c
)
110 (void) p
; (void) l
; (void) i
; (void) s
; /* unused */
111 if ( IsStackGrowingDown() )
117 int GetStackAlignment()
119 int nStackAlignment
= GetStackAlignment_3(0,1,2,3,4,5);
120 if ( nStackAlignment
!= GetStackAlignment_2(0,1,2,3,4,5) )
121 printf( "Pascal calling convention\n" );
122 return nStackAlignment
;
128 #if defined (UNX) || defined (WNT) || defined (OS2)
131 void PrintArgs( int p
, ... )
133 void PrintArgs( p
, va_alist
)
147 printf( "value = %d", p
);
149 while ( ( value
= va_arg(ap
, int) ) != 0 )
150 printf( " %d", value
);
156 #ifndef USE_FORK_TO_CHECK
157 static jmp_buf check_env
;
159 #if defined (UNX) || defined (OS2)
160 void SignalHandler( int sig
)
162 void __cdecl
SignalHandler( int sig
)
167 fprintf( stderr, "Signal %d caught\n", sig );
168 signal( sig, SignalHandler );
170 longjmp( check_env
, sig
);
174 int check( TestFunc func
, Type eT
, void* p
)
176 #ifdef USE_FORK_TO_CHECK
177 pid_t nChild
= fork();
182 if ( exitVal
& 0xff )
189 exit( func( eT
, p
) );
196 if ( !setjmp( check_env
) )
198 signal( SIGSEGV
, SignalHandler
);
200 signal( SIGBUS
, SignalHandler
);
203 result
= func( eT
, p
);
204 signal( SIGSEGV
, SIG_DFL
);
206 signal( SIGBUS
, SIG_DFL
);
221 int GetAtAddress( Type eT
, void* p
)
225 case t_char
: return *((char*)p
);
226 case t_short
: return *((short*)p
);
227 case t_int
: return *((int*)p
);
228 case t_long
: return *((long*)p
);
229 case t_double
: return *((double*)p
);
234 int SetAtAddress( Type eT
, void* p
)
238 case t_char
: return *((char*)p
) = 0;
239 case t_short
: return *((short*)p
) = 0;
240 case t_int
: return *((int*)p
) = 0;
241 case t_long
: return *((long*)p
) = 0;
242 case t_double
: return *((double*)p
)= 0;
247 char* TypeName( Type eT
)
251 case t_char
: return "char";
252 case t_short
: return "short";
253 case t_int
: return "int";
254 case t_long
: return "long";
255 case t_double
: return "double";
260 int CheckGetAccess( Type eT
, void* p
)
263 b
= -1 != check( (TestFunc
)GetAtAddress
, eT
, p
);
264 #if OSL_DEBUG_LEVEL > 1
266 "%s read %s at %p\n",
267 (b
? "can" : "can not" ), TypeName(eT
), p
);
271 int CheckSetAccess( Type eT
, void* p
)
274 b
= -1 != check( (TestFunc
)SetAtAddress
, eT
, p
);
275 #if OSL_DEBUG_LEVEL > 1
277 "%s write %s at %p\n",
278 (b
? "can" : "can not" ), TypeName(eT
), p
);
283 int GetAlignment( Type eT
)
286 int p
= (int)(void*)&a
;
288 p
= ( p
+ 0xF ) & ~0xF;
289 for ( i
= 1; i
< 16; i
++ )
290 if ( CheckGetAccess( eT
, (void*)(p
+i
) ) )
295 int CheckCharAccess( char* p
)
297 if ( CheckGetAccess( t_char
, p
) )
298 printf( "can read address %p\n", p
);
300 printf( "can not read address %p\n", p
);
302 if ( CheckSetAccess( t_char
, p
) )
303 printf( "can write address %p\n", p
);
305 printf( "can not write address %p\n", p
);
315 int nAlignment
[3]; /* 2,4,8 */
318 void Description_Ctor( struct Description
* pThis
)
320 pThis
->bBigEndian
= IsBigEndian();
321 pThis
->bStackGrowsDown
= IsStackGrowingDown();
322 pThis
->nStackAlignment
= GetStackAlignment();
324 if ( sizeof(short) != 2 )
326 pThis
->nAlignment
[0] = GetAlignment( t_short
);
327 if ( sizeof(int) != 4 )
329 pThis
->nAlignment
[1] = GetAlignment( t_int
);
330 if ( sizeof(double) != 8 )
332 pThis
->nAlignment
[2] = GetAlignment( t_double
);
335 void Description_Print( struct Description
* pThis
, char* name
)
338 FILE* f
= fopen( name
, "w" );
339 fprintf( f
, "#define __%s\n",
340 pThis
->bBigEndian
? "BIGENDIAN" : "LITTLEENDIAN" );
341 for ( i
= 0; i
< 3; i
++ )
342 fprintf( f
, "#define __ALIGNMENT%d\t%d\n",
343 1 << (i
+1), pThis
->nAlignment
[i
] );
344 fprintf( f
, "#define __STACKALIGNMENT wird nicht benutzt\t%d\n", pThis
->nStackAlignment
);
345 fprintf( f
, "#define __STACKDIRECTION\t%d\n",
346 pThis
->bStackGrowsDown
? -1 : 1 );
347 fprintf( f
, "#define __SIZEOFCHAR\t%d\n", sizeof( char ) );
348 fprintf( f
, "#define __SIZEOFSHORT\t%d\n", sizeof( short ) );
349 fprintf( f
, "#define __SIZEOFINT\t%d\n", sizeof( int ) );
350 fprintf( f
, "#define __SIZEOFLONG\t%d\n", sizeof( long ) );
351 fprintf( f
, "#define __SIZEOFPOINTER\t%d\n", sizeof( void* ) );
352 fprintf( f
, "#define __SIZEOFDOUBLE\t%d\n", sizeof( double ) );
353 fprintf( f
, "#define __IEEEDOUBLE\n" );
354 fprintf( f
, "#define _SOLAR_NODESCRIPTION\n" );
363 main( int argc
, char* argv
[] )
365 printTypeSign( char, "char" );
366 printTypeSign( short, "short" );
367 printTypeSign( int, "int" );
368 printTypeSign( long, "long" );
370 printTypeSize( char, "char" );
371 printTypeSize( short, "short" );
372 printTypeSize( int, "int" );
373 printTypeSize( long, "long" );
374 printTypeSize( float, "float" );
375 printTypeSize( double, "double" );
376 printTypeSize( void *, "void *" );
379 printf( "BIGENDIAN (Sparc, MC680x0, RS6000)\n" );
381 printf( "LITTLEENDIAN (Intel, VAX, PowerPC)\n" );
383 if( IsStackGrowingDown() )
384 printf( "Stack waechst nach unten\n" );
386 printf( "Stack waechst nach oben\n" );
388 printf( "STACKALIGNMENT : %d\n", GetStackAlignment() );
390 PrintArgs( 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 );
397 printf( "Zugriff long auf %i-Aligned Adresse : ", i
/ 7 );
398 printf( ( CheckGetAccess( t_long
, (long*)&a
[i
] ) ? "OK\n" : "ERROR\n" ) );
408 printf( "Zugriff double auf %i-Aligned Adresse : ", i
/ 7 );
409 printf( ( CheckGetAccess( t_double
, (double*)&a
[i
] ) ? "OK\n" : "ERROR\n" ) );
416 CheckCharAccess( p
);
418 CheckCharAccess( p
);
423 struct Description description
;
424 Description_Ctor( &description
);
425 Description_Print( &description
, argv
[1] );