xref: /aoo42x/main/tools/workben/solar.c (revision cdf0e10c)
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