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