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 ************************************************************************/
31 /* POSIX defines that a program is undefined after a SIG_SEGV. The
32 * code stopped working on Linux Kernel 2.6 so I have moved this back to
34 * If at a later time the signals work correctly with the Linux Kernel 2.6
35 * then this change may be reverted although not strictly posix safe. */
36 #define USE_FORK_TO_CHECK 1
44 #include <sys/types.h>
53 #define NO_USE_FORK_TO_CHECK
54 #ifdef USE_FORK_TO_CHECK
61 #define printTypeSize(Type,Name) printf( "sizeof(%s)\t= %d\n", Name, sizeof (Type) )
63 #define isSignedType(Type) (((Type)-1) < 0)
64 #define printTypeSign(Type,Name) printf( "%s\t= %s %s\n", Name, ( isSignedType(Type) ? "signed" : "unsigned" ), Name )
67 /*************************************************************************
71 |* Beschreibung True, wenn CPU BigEndian ist
73 |* Ersterstellung EG 26.06.96
76 *************************************************************************/
83 /*************************************************************************
85 |* IsStackGrowingDown()
87 |* Beschreibung True, wenn der Stack nach unten waechst
89 |* Ersterstellung EG 26.06.96
92 *************************************************************************/
93 int IsStackGrowingDown_2( int * pI
)
96 return ((unsigned long)&i
) < (unsigned long)pI
;
99 int IsStackGrowingDown()
102 return IsStackGrowingDown_2(&i
);
105 /*************************************************************************
107 |* GetStackAlignment()
109 |* Beschreibung Alignment von char Parametern, die (hoffentlich)
110 |* ueber den Stack uebergeben werden
112 |* Ersterstellung EG 26.06.96
115 *************************************************************************/
116 int GetStackAlignment_3( char*p
, long l
, int i
, short s
, char b
, char c
, ... )
118 if ( IsStackGrowingDown() )
124 int GetStackAlignment_2( char*p
, long l
, int i
, short s
, char b
, char c
)
126 if ( IsStackGrowingDown() )
132 int GetStackAlignment()
134 int nStackAlignment
= GetStackAlignment_3(0,1,2,3,4,5);
135 if ( nStackAlignment
!= GetStackAlignment_2(0,1,2,3,4,5) )
136 printf( "Pascal calling convention\n" );
137 return nStackAlignment
;
141 /*************************************************************************
143 |* Typdeclarations for memory access test functions
145 *************************************************************************/
146 typedef enum { t_char
, t_short
, t_int
, t_long
, t_double
} Type
;
147 typedef int (*TestFunc
)( Type
, void* );
150 /*************************************************************************
154 |* Beschreibung Testfunktion fuer variable Parameter
156 |* Ersterstellung EG 26.06.96
159 *************************************************************************/
161 void PrintArgs( int p
, ... )
163 void PrintArgs( p
, va_alist
)
177 printf( "value = %d", p
);
179 while ( ( value
= va_arg(ap
, int) ) != 0 )
180 printf( " %d", value
);
186 #ifndef USE_FORK_TO_CHECK
187 /*************************************************************************
191 |* Beschreibung faengt SIGBUS und SIGSEGV in check() ab
193 |* Ersterstellung EG 26.06.96
196 *************************************************************************/
197 static jmp_buf check_env
;
199 void SignalHdl( int sig
)
203 fprintf( stderr
, "Signal %d caught\n", sig
);
204 signal( SIGSEGV
, SIG_DFL
);
205 signal( SIGBUS
, SIG_DFL
);
206 siglongjmp( check_env
, sig
);
210 /*************************************************************************
214 |* Beschreibung Testet MemoryZugriff (read/write)
216 |* Ersterstellung EG 26.06.96
219 *************************************************************************/
220 int check( TestFunc func
, Type eT
, void* p
)
222 #ifdef USE_FORK_TO_CHECK
223 pid_t nChild
= fork();
228 if ( exitVal
& 0xff )
235 exit( func( eT
, p
) );
242 if ( !sigsetjmp( check_env
, 1 ) )
244 signal( SIGSEGV
, SignalHdl
);
245 signal( SIGBUS
, SignalHdl
);
246 result
= func( eT
, p
);
247 signal( SIGSEGV
, SIG_DFL
);
248 signal( SIGBUS
, SIG_DFL
);
258 /*************************************************************************
262 |* Beschreibung memory read access
264 |* Ersterstellung EG 26.06.96
267 *************************************************************************/
268 int GetAtAddress( Type eT
, void* p
)
272 case t_char
: return *((char*)p
);
273 case t_short
: return *((short*)p
);
274 case t_int
: return *((int*)p
);
275 case t_long
: return *((long*)p
);
276 case t_double
: return *((double*)p
);
281 /*************************************************************************
285 |* Beschreibung memory write access
287 |* Ersterstellung EG 26.06.96
290 *************************************************************************/
291 int SetAtAddress( Type eT
, void* p
)
295 case t_char
: return *((char*)p
) = 0;
296 case t_short
: return *((short*)p
) = 0;
297 case t_int
: return *((int*)p
) = 0;
298 case t_long
: return *((long*)p
) = 0;
299 case t_double
: return *((double*)p
)= 0;
304 char* TypeName( Type eT
)
308 case t_char
: return "char";
309 case t_short
: return "short";
310 case t_int
: return "int";
311 case t_long
: return "long";
312 case t_double
: return "double";
317 /*************************************************************************
319 |* Check(Get|Set)Access()
321 |* Beschreibung Testet MemoryZugriff (read/write)
322 |* Zugriffsverletzungen werden abgefangen
324 |* Ersterstellung EG 26.06.96
327 *************************************************************************/
328 int CheckGetAccess( Type eT
, void* p
)
331 b
= -1 != check( (TestFunc
)GetAtAddress
, eT
, p
);
332 #if OSL_DEBUG_LEVEL > 1
334 "%s read %s at %p\n",
335 (b
? "can" : "can not" ), TypeName(eT
), p
);
339 int CheckSetAccess( Type eT
, void* p
)
343 b
= -1 != check( (TestFunc
)SetAtAddress
, eT
, p
);
344 #if OSL_DEBUG_LEVEL > 1
346 "%s write %s at %p\n",
347 (b
? "can" : "can not" ), TypeName(eT
), p
);
352 /*************************************************************************
356 |* Beschreibung Bestimmt das Alignment verschiedener Typen
358 |* Ersterstellung EG 26.06.96
361 *************************************************************************/
362 int GetAlignment( Type eT
)
365 long p
= (long)(void*)a
;
368 /* clear a[...] to set legal value for double access */
369 for ( i
= 0; i
< 16*8; i
++ )
372 p
= ( p
+ 0xF ) & ~0xF;
373 for ( i
= 1; i
< 16; i
++ )
374 if ( CheckGetAccess( eT
, (void*)(p
+i
) ) )
379 /*************************************************************************
381 |* struct Description
383 |* Beschreibung Beschreibt die Parameter der Architektur
385 |* Ersterstellung EG 26.06.96
388 *************************************************************************/
394 int nAlignment
[3]; /* 2,4,8 */
397 /*************************************************************************
399 |* Description_Ctor()
401 |* Beschreibung Bestimmt die Parameter der Architektur
403 |* Ersterstellung EG 26.06.96
406 *************************************************************************/
407 void Description_Ctor( struct Description
* pThis
)
409 pThis
->bBigEndian
= IsBigEndian();
410 pThis
->bStackGrowsDown
= IsStackGrowingDown();
411 pThis
->nStackAlignment
= GetStackAlignment();
413 if ( sizeof(short) != 2 )
415 pThis
->nAlignment
[0] = GetAlignment( t_short
);
416 if ( sizeof(int) != 4 )
418 pThis
->nAlignment
[1] = GetAlignment( t_int
);
420 if ( sizeof(long) == 8 )
421 pThis
->nAlignment
[2] = GetAlignment( t_long
);
422 else if ( sizeof(double) == 8 )
423 pThis
->nAlignment
[2] = GetAlignment( t_double
);
428 /*************************************************************************
430 |* Description_Print()
432 |* Beschreibung Schreibt die Parameter der Architektur als Header
434 |* Ersterstellung EG 26.06.96
437 *************************************************************************/
438 void Description_Print( struct Description
* pThis
, char* name
)
441 FILE* f
= fopen( name
, "w" );
443 fprintf( stderr
, "Unable to open file %s: %s\n", name
, strerror( errno
) );
446 fprintf( f
, "#define __%s\n",
447 pThis
->bBigEndian
? "BIGENDIAN" : "LITTLEENDIAN" );
448 for ( i
= 0; i
< 3; i
++ )
449 fprintf( f
, "#define __ALIGNMENT%d\t%d\n",
450 1 << (i
+1), pThis
->nAlignment
[i
] );
451 fprintf( f
, "/* Stack alignment is not used... */\n" );
452 fprintf( f
, "#define __STACKALIGNMENT\t%d\n", pThis
->nStackAlignment
);
453 fprintf( f
, "#define __STACKDIRECTION\t%d\n",
454 pThis
->bStackGrowsDown
? -1 : 1 );
455 fprintf( f
, "#define __SIZEOFCHAR\t%d\n", sizeof( char ) );
456 fprintf( f
, "#define __SIZEOFSHORT\t%d\n", sizeof( short ) );
457 fprintf( f
, "#define __SIZEOFINT\t%d\n", sizeof( int ) );
458 fprintf( f
, "#define __SIZEOFLONG\t%d\n", sizeof( long ) );
459 fprintf( f
, "#define __SIZEOFPOINTER\t%d\n", sizeof( void* ) );
460 fprintf( f
, "#define __SIZEOFDOUBLE\t%d\n", sizeof( double ) );
461 fprintf( f
, "#define __IEEEDOUBLE\n" );
465 /*************************************************************************
467 |* InfoMemoryAccess()
469 |* Beschreibung Informeller Bytezugriffstest
471 |* Ersterstellung EG 26.06.96
474 *************************************************************************/
475 void InfoMemoryAccess( char* p
)
477 if ( CheckGetAccess( t_char
, p
) )
478 printf( "can read address %p\n", p
);
480 printf( "can not read address %p\n", p
);
482 if ( CheckSetAccess( t_char
, p
) )
483 printf( "can write address %p\n", p
);
485 printf( "can not write address %p\n", p
);
488 /*************************************************************************
490 |* InfoMemoryTypeAccess()
492 |* Beschreibung Informeller Zugriffstest verschiedener Typen
494 |* Ersterstellung EG 15.08.96
497 *************************************************************************/
498 void InfoMemoryTypeAccess( Type eT
)
503 /* clear a[...] to set legal value for double access */
504 for ( i
= 0; i
< 64; i
++ )
507 for ( i
= 56; i
>= 7; i
>>= 1 )
509 printf( "Zugriff %s auf %i-Aligned Adresse : ", TypeName( eT
), i
/ 7 );
510 printf( ( CheckGetAccess( eT
, (long*)&a
[i
] ) ? "OK\n" : "ERROR\n" ) );
513 /************************************************************************
515 * Use C code to determine the characteristics of the building platform.
517 ************************************************************************/
518 int main( int argc
, char* argv
[] )
520 printTypeSign( char, "char" );
521 printTypeSign( short, "short" );
522 printTypeSign( int, "int" );
523 printTypeSign( long, "long" );
525 printTypeSize( char, "char" );
526 printTypeSize( short, "short" );
527 printTypeSize( int, "int" );
528 printTypeSize( long, "long" );
529 printTypeSize( float, "float" );
530 printTypeSize( double, "double" );
531 printTypeSize( void *, "void *" );
534 printf( "BIGENDIAN (Sparc, MC680x0, RS6000, IP22, IP32, g3)\n" );
536 printf( "LITTLEENDIAN (Intel, VAX, PowerPC)\n" );
538 if( IsStackGrowingDown() )
539 printf( "Stack waechst nach unten\n" );
541 printf( "Stack waechst nach oben\n" );
543 printf( "STACKALIGNMENT : %d\n", GetStackAlignment() );
545 /* PrintArgs( 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ); */
549 struct Description description
;
550 Description_Ctor( &description
);
551 Description_Print( &description
, argv
[1] );
555 InfoMemoryAccess( p
);
557 InfoMemoryAccess( p
);
558 InfoMemoryTypeAccess( t_short
);
559 InfoMemoryTypeAccess( t_int
);
560 InfoMemoryTypeAccess( t_long
);
561 InfoMemoryTypeAccess( t_double
);