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