xref: /AOO41X/main/sal/typesconfig/typesconfig.c (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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 #include <errno.h>
31 #include <string.h>
32 
33 #include <unistd.h>
34 #include <sys/types.h>
35 
36 #include <stdarg.h>
37 
38 #include <signal.h>
39 #include <setjmp.h>
40 
41 #define printTypeSize(Type,Name)	printf(	"sizeof(%s)\t\t= %d\n", Name, (int) sizeof (Type) )
42 
43 #define isSignedType(Type)	(((Type)-1) < 0)
44 #define printTypeSign(Type,Name)	printf(	"%s\t\t= %s %s\n", Name, ( isSignedType(Type) ? "signed" : "unsigned" ), Name )
45 
46 
47 /*************************************************************************
48 |*
49 |*	IsBigEndian()
50 |*
51 |*	Beschreibung		True, wenn CPU BigEndian ist
52 |*
53 |*	Ersterstellung		EG 26.06.96
54 |*	Letzte Aenderung
55 |*
56 *************************************************************************/
57 int IsBigEndian()
58 {
59   long l = 1;
60   return ! *(char*)&l;
61 }
62 
63 /*************************************************************************
64 |*
65 |*	Typdeclarations for memory access test functions
66 |*
67 *************************************************************************/
68 typedef enum { t_char, t_short, t_int, t_long, t_double } Type;
69 typedef int (*TestFunc)( Type, void* );
70 
71 
72 /*************************************************************************
73 |*
74 |*	PrintArgs()
75 |*
76 |*	Beschreibung		Testfunktion fuer variable Parameter
77 |*
78 |*	Ersterstellung		EG 26.06.96
79 |*	Letzte Aenderung
80 |*
81 *************************************************************************/
82 void PrintArgs( int p, ... )
83 {
84 	int value;
85 	va_list ap;
86 
87     va_start( ap, p );
88 
89 	printf( "value = %d", p );
90 
91 	while ( ( value = va_arg(ap, int) ) != 0 )
92 	  printf( " %d", value );
93 
94 	printf( "\n" );
95 	va_end(ap);
96 }
97 
98 /*************************************************************************
99 |*
100 |*	SignalHdl()
101 |*
102 |*	Beschreibung		faengt SIGBUS und SIGSEGV in check() ab
103 |*
104 |*	Ersterstellung		EG 26.06.96
105 |*	Letzte Aenderung
106 |*
107 *************************************************************************/
108 
109 static sigjmp_buf jmpbuf;
110 static volatile sig_atomic_t hit;
111 
112 void SignalHdl( int sig )
113 {
114     (void) sig; // ignored
115     hit = 1;
116     siglongjmp(jmpbuf, 0);
117 }
118 
119 /*************************************************************************
120 |*
121 |*	check()
122 |*
123 |*	Beschreibung		Testet MemoryZugriff (read/write)
124 |*
125 |*	Ersterstellung		EG 26.06.96
126 |*	Letzte Aenderung
127 |*
128 *************************************************************************/
129 int check( TestFunc func, Type eT, void* p )
130 {
131     hit = 0;
132     if (sigsetjmp(jmpbuf, 1) == 0) {
133         struct sigaction sa;
134         sa.sa_handler = SignalHdl;
135         sigemptyset(&sa.sa_mask);
136         sa.sa_flags = 0;
137         if (sigaction(SIGBUS, &sa, NULL) != 0 ||
138             sigaction(SIGSEGV, &sa, NULL) != 0)
139         {
140             abort();
141         }
142         func(eT, p);
143         sa.sa_handler = SIG_DFL;
144         if (sigaction(SIGBUS, &sa, NULL) != 0 ||
145             sigaction(SIGSEGV, &sa, NULL) != 0)
146         {
147             abort();
148         }
149     }
150     return hit ? -1 : 0;
151 }
152 
153 /*************************************************************************
154 |*
155 |*	GetAtAddress()
156 |*
157 |*	Beschreibung		memory read access
158 |*
159 |*	Ersterstellung		EG 26.06.96
160 |*	Letzte Aenderung
161 |*
162 *************************************************************************/
163 #if defined(IA64) || defined(ARM32) || defined(HPPA) || defined(AXP)
164 
165 int forceerror()
166 {
167 #if defined(ARM32)
168 // workaround for qemu-user
169     hit = 1;
170 #else
171     raise (SIGBUS);
172 #endif
173     return 1;
174 }
175 
176 int GetAtAddress( Type eT, void* p )
177 {
178   switch ( eT )
179   {
180   case t_char:		return *((char*)p);
181   case t_short:		if ((long)p % sizeof(short)) return forceerror(); else return *((short*)p);
182   case t_int:		if ((long)p % sizeof(int)) return forceerror(); else return *((int*)p);
183   case t_long:		if ((long)p % sizeof(long)) return forceerror(); else return *((long*)p);
184   case t_double:	if ((long)p % sizeof(double)) return forceerror(); else return *((double*)p);
185   }
186   abort();
187 }
188 
189 #else
190 static int dummy(void* unused);
191 
192 int GetAtAddress( Type eT, void* p )
193 {
194   switch ( eT )
195   {
196   case t_char: { char x = *(char*)p; return dummy(&x); }
197   case t_short: { short x = *(short*)p; return dummy(&x); }
198   case t_int: { int x = *(int*)p; return dummy(&x); }
199   case t_long: { long x = *(long*)p; return dummy(&x); }
200   case t_double: { double x = *(double*)p; return dummy(&x); }
201   }
202   abort();
203 }
204 
205 int dummy(void* unused)
206 {
207     (void)unused;
208     return 0;
209 }
210 
211 #endif
212 /*************************************************************************
213 |*
214 |*	SetAtAddress()
215 |*
216 |*	Beschreibung		memory write access
217 |*
218 |*	Ersterstellung		EG 26.06.96
219 |*	Letzte Aenderung
220 |*
221 *************************************************************************/
222 int SetAtAddress( Type eT, void* p )
223 {
224   switch ( eT )
225   {
226   case t_char:		return *((char*)p)	= 0;
227   case t_short:		return *((short*)p)	= 0;
228   case t_int:		return *((int*)p)	= 0;
229   case t_long:		return *((long*)p)	= 0;
230   case t_double:	return *((double*)p)= 0;
231   }
232   abort();
233 }
234 
235 char* TypeName( Type eT )
236 {
237   switch ( eT )
238   {
239   case t_char:		return "char";
240   case t_short:		return "short";
241   case t_int:		return "int";
242   case t_long:		return "long";
243   case t_double:	return "double";
244   }
245   abort();
246 }
247 
248 /*************************************************************************
249 |*
250 |*	Check(Get|Set)Access()
251 |*
252 |*	Beschreibung		Testet MemoryZugriff (read/write)
253 |*						Zugriffsverletzungen werden abgefangen
254 |*
255 |*	Ersterstellung		EG 26.06.96
256 |*	Letzte Aenderung
257 |*
258 *************************************************************************/
259 int CheckGetAccess( Type eT, void* p )
260 {
261   int b;
262   b = -1 != check( (TestFunc)GetAtAddress, eT, p );
263 #if OSL_DEBUG_LEVEL > 1
264   fprintf( stderr,
265 		   "%s read %s at %p\n",
266 		   (b? "can" : "can not" ), TypeName(eT), p );
267 #endif
268   return b;
269 }
270 int CheckSetAccess( Type eT, void* p )
271 {
272   int b;
273 
274   b = -1 != check( (TestFunc)SetAtAddress, eT, p );
275 #if OSL_DEBUG_LEVEL > 1
276   fprintf( stderr,
277 		   "%s write %s at %p\n",
278 		   (b? "can" : "can not" ), TypeName(eT), p );
279 #endif
280   return b;
281 }
282 
283 /*************************************************************************
284 |*
285 |*	GetAlignment()
286 |*
287 |*	Beschreibung		Bestimmt das Alignment verschiedener Typen
288 |*
289 |*	Ersterstellung		EG 26.06.96
290 |*	Letzte Aenderung
291 |*
292 *************************************************************************/
293 int GetAlignment( Type eT )
294 {
295   char	a[ 16*8 ];
296   long	p = (long)(void*)a;
297   int	i;
298 
299   /* clear a[...] to set legal value for double access */
300   for ( i = 0; i < 16*8; i++ )
301 	a[i] = 0;
302 
303   p = ( p + 0xF ) & ~0xF;
304   for ( i = 1; i < 16; i++ )
305 	if ( CheckGetAccess( eT, (void*)(p+i) ) )
306 	  return i;
307   return 0;
308 }
309 
310 /*************************************************************************
311 |*
312 |*	struct Description
313 |*
314 |*	Beschreibung		Beschreibt die Parameter der Architektur
315 |*
316 |*	Ersterstellung		EG 26.06.96
317 |*	Letzte Aenderung
318 |*
319 *************************************************************************/
320 struct Description
321 {
322   int	bBigEndian;
323   int	nAlignment[3];	/* 2,4,8 */
324 };
325 
326 /*************************************************************************
327 |*
328 |*	Description_Ctor()
329 |*
330 |*	Beschreibung		Bestimmt die Parameter der Architektur
331 |*
332 |*	Ersterstellung		EG 26.06.96
333 |*	Letzte Aenderung
334 |*
335 *************************************************************************/
336 void Description_Ctor( struct Description* pThis )
337 {
338   pThis->bBigEndian			= IsBigEndian();
339 
340   if ( sizeof(short) != 2 )
341 	abort();
342   pThis->nAlignment[0] = GetAlignment( t_short );
343   if ( sizeof(int) != 4 )
344 	abort();
345   pThis->nAlignment[1] = GetAlignment( t_int );
346 
347   if	  ( sizeof(long) == 8 )
348 	pThis->nAlignment[2] = GetAlignment( t_long );
349   else if ( sizeof(double) == 8 )
350 	pThis->nAlignment[2] = GetAlignment( t_double );
351   else
352 	abort();
353 }
354 
355 /*************************************************************************
356 |*
357 |*	Description_Print()
358 |*
359 |*	Beschreibung		Schreibt die Parameter der Architektur als Header
360 |*
361 |*	Ersterstellung		EG 26.06.96
362 |*	Letzte Aenderung
363 |*
364 *************************************************************************/
365 void Description_Print( struct Description* pThis, char* name )
366 {
367   int i;
368   FILE* f = fopen( name, "w" );
369   if( ! f ) {
370 	  fprintf( stderr, "Unable to open file %s: %s\n", name, strerror( errno ) );
371 	  exit( 99 );
372   }
373   fprintf( f, "/* This file is autogenerated from the 'typesconfig' program\n * in the sal module\n */\n\n" );
374 
375 /* Disabled for now in preference to big/little endian defines in <osl/endian.h>  fa (2004-03-15) */
376 /*  fprintf( f, "#define SAL_TYPES_%s\n", pThis->bBigEndian ? "BIGENDIAN" : "LITTLEENDIAN" ); */
377 
378   for ( i = 0; i < 3; i++ )
379 	fprintf( f, "#define SAL_TYPES_ALIGNMENT%d\t%d\n",  1 << (i+1), pThis->nAlignment[i] );
380   fprintf( f, "#define SAL_TYPES_SIZEOFSHORT\t%d\n", (int) sizeof( short ) );
381   fprintf( f, "#define SAL_TYPES_SIZEOFINT\t%d\n", (int) sizeof( int ) );
382   fprintf( f, "#define SAL_TYPES_SIZEOFLONG\t%d\n", (int) sizeof( long ) );
383   fprintf( f, "#define SAL_TYPES_SIZEOFLONGLONG\t%d\n", (int) sizeof( long long ) );
384   fprintf( f, "#define SAL_TYPES_SIZEOFPOINTER\t%d\n", (int) sizeof( void* ) );
385 
386 /* Disabled for now, becuase OOo code assumes sizeof(double) == 8 and this is not
387  * likely to change any time soon.  fa (2004-03-15)
388  */
389 /*  fprintf( f, "#define SAL_TYPES_SIZEOFDOUBLE\t%d\n", sizeof( double ) );*/
390 
391   fclose( f );
392 }
393 
394 /*************************************************************************
395 |*
396 |*	InfoMemoryAccess()
397 |*
398 |*	Beschreibung		Informeller Bytezugriffstest
399 |*
400 |*	Ersterstellung		EG 26.06.96
401 |*	Letzte Aenderung
402 |*
403 *************************************************************************/
404 void InfoMemoryAccess( char* p )
405 {
406   if ( CheckGetAccess( t_char, p ) )
407     printf( "can read address %p\n", p );
408   else
409     printf( "cannot read address %p\n", p );
410 
411   if ( CheckSetAccess( t_char, p ) )
412     printf( "can write address %p\n", p );
413   else
414     printf( "cannot write address %p\n", p );
415 }
416 
417 /*************************************************************************
418 |*
419 |*	InfoMemoryTypeAccess()
420 |*
421 |*	Beschreibung		Informeller Zugriffstest verschiedener Typen
422 |*
423 |*	Ersterstellung		EG 15.08.96
424 |*	Letzte Aenderung
425 |*
426 *************************************************************************/
427 void InfoMemoryTypeAccess( Type eT )
428 {
429   char  a[64];
430   int   i;
431 
432   /* clear a[...] to set legal value for double access */
433   for ( i = 0; i < 64; i++ )
434 	a[i] = 0;
435 
436   for ( i = 56; i >= 7; i >>= 1 )
437   {
438 	if ( CheckGetAccess(eT, (long*)&a[i]) )
439 		printf( "Access %s on %i-Aligned Address : OK\n", TypeName(eT), i / 7 );
440 	else
441 		printf( "Access %s on %i-Aligned Address : ERROR\n", TypeName(eT), i / 7 );
442   }
443 }
444 /************************************************************************
445  *
446  * 	Use C code to determine the characteristics of the building platform.
447  *
448  ************************************************************************/
449 int main( int argc, char* argv[] )
450 {
451   printTypeSign( char, "char" );
452   printTypeSign( short, "short" );
453   printTypeSign( int, "int" );
454   printTypeSign( long, "long" );
455   printTypeSign( long long, "long long" );
456 
457   printTypeSize( short, "short" );
458   printTypeSize( int, "int" );
459   printTypeSize( long, "long" );
460   printTypeSize( long long, "long long" );
461   printTypeSize( float, "float" );
462   printTypeSize( double, "double" );
463   printTypeSize( void *, "void *" );
464 
465   if ( IsBigEndian() )
466     printf( "BIGENDIAN (Sparc, RS6000, IP22, IP32, PowerPC(BE))\n" );
467   else
468     printf( "LITTLEENDIAN (Intel, x86-64, PowerPC(LE))\n" );
469 
470   /* PrintArgs( 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ); */
471 
472   if ( argc > 1 )
473   {
474 	struct Description description;
475 	Description_Ctor( &description );
476 	Description_Print( &description, argv[1] );
477   }
478   {
479 	char* p = NULL;
480 	InfoMemoryAccess( p );
481 	p = (char*)&p;
482 	InfoMemoryAccess( p );
483 	InfoMemoryTypeAccess( t_short );
484 	InfoMemoryTypeAccess( t_int );
485 	InfoMemoryTypeAccess( t_long );
486 	InfoMemoryTypeAccess( t_double );
487   }
488 
489   exit( 0 );
490 }
491