1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
35 #include <sys/types.h>
42 #define printTypeSize(Type,Name) printf( "sizeof(%s)\t\t= %d\n", Name, (int) sizeof (Type) )
44 #define isSignedType(Type) (((Type)-1) < 0)
45 #define printTypeSign(Type,Name) printf( "%s\t\t= %s %s\n", Name, ( isSignedType(Type) ? "signed" : "unsigned" ), Name )
48 /*************************************************************************
52 |* Beschreibung True, wenn CPU BigEndian ist
54 *************************************************************************/
61 /*************************************************************************
63 |* Typdeclarations for memory access test functions
65 *************************************************************************/
66 typedef enum { t_char
, t_short
, t_int
, t_long
, t_double
} Type
;
67 typedef int (*TestFunc
)( Type
, void* );
70 /*************************************************************************
74 |* Beschreibung Testfunktion fuer variable Parameter
76 *************************************************************************/
77 void PrintArgs( int p
, ... )
84 printf( "value = %d", p
);
86 while ( ( value
= va_arg(ap
, int) ) != 0 )
87 printf( " %d", value
);
93 /*************************************************************************
97 |* Beschreibung faengt SIGBUS und SIGSEGV in check() ab
99 *************************************************************************/
101 static sigjmp_buf jmpbuf
;
102 static volatile sig_atomic_t hit
;
104 void SignalHdl( int sig
)
106 (void) sig
; // ignored
108 siglongjmp(jmpbuf
, 0);
111 /*************************************************************************
115 |* Beschreibung Testet MemoryZugriff (read/write)
117 *************************************************************************/
118 int check( TestFunc func
, Type eT
, void* p
)
121 if (sigsetjmp(jmpbuf
, 1) == 0) {
123 sa
.sa_handler
= SignalHdl
;
124 sigemptyset(&sa
.sa_mask
);
126 if (sigaction(SIGBUS
, &sa
, NULL
) != 0 ||
127 sigaction(SIGSEGV
, &sa
, NULL
) != 0)
132 sa
.sa_handler
= SIG_DFL
;
133 if (sigaction(SIGBUS
, &sa
, NULL
) != 0 ||
134 sigaction(SIGSEGV
, &sa
, NULL
) != 0)
142 /*************************************************************************
146 |* Beschreibung memory read access
148 *************************************************************************/
149 #if defined(IA64) || defined(ARM32) || defined(HPPA) || defined(AXP)
154 // workaround for qemu-user
162 int GetAtAddress( Type eT
, void* p
)
166 case t_char
: return *((char*)p
);
167 case t_short
: if ((long)p
% sizeof(short)) return forceerror(); else return *((short*)p
);
168 case t_int
: if ((long)p
% sizeof(int)) return forceerror(); else return *((int*)p
);
169 case t_long
: if ((long)p
% sizeof(long)) return forceerror(); else return *((long*)p
);
170 case t_double
: if ((long)p
% sizeof(double)) return forceerror(); else return *((double*)p
);
176 static int dummy(void* unused
);
178 int GetAtAddress( Type eT
, void* p
)
182 case t_char
: { char x
= *(char*)p
; return dummy(&x
); }
183 case t_short
: { short x
= *(short*)p
; return dummy(&x
); }
184 case t_int
: { int x
= *(int*)p
; return dummy(&x
); }
185 case t_long
: { long x
= *(long*)p
; return dummy(&x
); }
186 case t_double
: { double x
= *(double*)p
; return dummy(&x
); }
191 int dummy(void* unused
)
198 /*************************************************************************
202 |* Beschreibung memory write access
204 *************************************************************************/
205 int SetAtAddress( Type eT
, void* p
)
209 case t_char
: return *((char*)p
) = 0;
210 case t_short
: return *((short*)p
) = 0;
211 case t_int
: return *((int*)p
) = 0;
212 case t_long
: return *((long*)p
) = 0;
213 case t_double
: return *((double*)p
)= 0;
218 char* TypeName( Type eT
)
222 case t_char
: return "char";
223 case t_short
: return "short";
224 case t_int
: return "int";
225 case t_long
: return "long";
226 case t_double
: return "double";
231 /*************************************************************************
233 |* Check(Get|Set)Access()
235 |* Beschreibung Testet MemoryZugriff (read/write)
236 |* Zugriffsverletzungen werden abgefangen
238 *************************************************************************/
239 int CheckGetAccess( Type eT
, void* p
)
242 b
= -1 != check( (TestFunc
)GetAtAddress
, eT
, p
);
243 #if OSL_DEBUG_LEVEL > 1
245 "%s read %s at %p\n",
246 (b
? "can" : "can not" ), TypeName(eT
), p
);
250 int CheckSetAccess( Type eT
, void* p
)
254 b
= -1 != check( (TestFunc
)SetAtAddress
, eT
, p
);
255 #if OSL_DEBUG_LEVEL > 1
257 "%s write %s at %p\n",
258 (b
? "can" : "can not" ), TypeName(eT
), p
);
263 /*************************************************************************
267 |* Beschreibung Bestimmt das Alignment verschiedener Typen
269 *************************************************************************/
270 int GetAlignment( Type eT
)
273 long p
= (long)(void*)a
;
276 /* clear a[...] to set legal value for double access */
277 for ( i
= 0; i
< 16*8; i
++ )
280 p
= ( p
+ 0xF ) & ~0xF;
281 for ( i
= 1; i
< 16; i
++ )
282 if ( CheckGetAccess( eT
, (void*)(p
+i
) ) )
287 /*************************************************************************
289 |* struct Description
291 |* Beschreibung Beschreibt die Parameter der Architektur
293 *************************************************************************/
297 int nAlignment
[3]; /* 2,4,8 */
300 /*************************************************************************
302 |* Description_Ctor()
304 |* Beschreibung Bestimmt die Parameter der Architektur
306 *************************************************************************/
307 void Description_Ctor( struct Description
* pThis
)
309 pThis
->bBigEndian
= IsBigEndian();
311 if ( sizeof(short) != 2 )
313 pThis
->nAlignment
[0] = GetAlignment( t_short
);
314 if ( sizeof(int) != 4 )
316 pThis
->nAlignment
[1] = GetAlignment( t_int
);
318 if ( sizeof(long) == 8 )
319 pThis
->nAlignment
[2] = GetAlignment( t_long
);
320 else if ( sizeof(double) == 8 )
321 pThis
->nAlignment
[2] = GetAlignment( t_double
);
326 /*************************************************************************
328 |* Description_Print()
330 |* Beschreibung Schreibt die Parameter der Architektur als Header
332 *************************************************************************/
333 void Description_Print( struct Description
* pThis
, char* name
)
336 FILE* f
= fopen( name
, "w" );
338 fprintf( stderr
, "Unable to open file %s: %s\n", name
, strerror( errno
) );
341 fprintf( f
, "/* This file is autogenerated from the 'typesconfig' program\n * in the sal module\n */\n\n" );
343 /* Disabled for now in preference to big/little endian defines in <osl/endian.h> fa (2004-03-15) */
344 /* fprintf( f, "#define SAL_TYPES_%s\n", pThis->bBigEndian ? "BIGENDIAN" : "LITTLEENDIAN" ); */
346 for ( i
= 0; i
< 3; i
++ )
347 fprintf( f
, "#define SAL_TYPES_ALIGNMENT%d\t%d\n", 1 << (i
+1), pThis
->nAlignment
[i
] );
348 fprintf( f
, "#define SAL_TYPES_SIZEOFSHORT\t%d\n", (int) sizeof( short ) );
349 fprintf( f
, "#define SAL_TYPES_SIZEOFINT\t%d\n", (int) sizeof( int ) );
350 fprintf( f
, "#define SAL_TYPES_SIZEOFLONG\t%d\n", (int) sizeof( long ) );
351 fprintf( f
, "#define SAL_TYPES_SIZEOFLONGLONG\t%d\n", (int) sizeof( long long ) );
352 fprintf( f
, "#define SAL_TYPES_SIZEOFPOINTER\t%d\n", (int) sizeof( void* ) );
354 /* Disabled for now, becuase OOo code assumes sizeof(double) == 8 and this is not
355 * likely to change any time soon. fa (2004-03-15)
357 /* fprintf( f, "#define SAL_TYPES_SIZEOFDOUBLE\t%d\n", sizeof( double ) );*/
362 /*************************************************************************
364 |* InfoMemoryAccess()
366 |* Beschreibung Informeller Bytezugriffstest
368 *************************************************************************/
369 void InfoMemoryAccess( char* p
)
371 if ( CheckGetAccess( t_char
, p
) )
372 printf( "can read address %p\n", p
);
374 printf( "cannot read address %p\n", p
);
376 if ( CheckSetAccess( t_char
, p
) )
377 printf( "can write address %p\n", p
);
379 printf( "cannot write address %p\n", p
);
382 /*************************************************************************
384 |* InfoMemoryTypeAccess()
386 |* Beschreibung Informeller Zugriffstest verschiedener Typen
388 *************************************************************************/
389 void InfoMemoryTypeAccess( Type eT
)
394 /* clear a[...] to set legal value for double access */
395 for ( i
= 0; i
< 64; i
++ )
398 for ( i
= 56; i
>= 7; i
>>= 1 )
400 if ( CheckGetAccess(eT
, (long*)&a
[i
]) )
401 printf( "Access %s on %i-Aligned Address : OK\n", TypeName(eT
), i
/ 7 );
403 printf( "Access %s on %i-Aligned Address : ERROR\n", TypeName(eT
), i
/ 7 );
406 /************************************************************************
408 * Use C code to determine the characteristics of the building platform.
410 ************************************************************************/
411 int main( int argc
, char* argv
[] )
413 printTypeSign( char, "char" );
414 printTypeSign( short, "short" );
415 printTypeSign( int, "int" );
416 printTypeSign( long, "long" );
417 printTypeSign( long long, "long long" );
419 printTypeSize( short, "short" );
420 printTypeSize( int, "int" );
421 printTypeSize( long, "long" );
422 printTypeSize( long long, "long long" );
423 printTypeSize( float, "float" );
424 printTypeSize( double, "double" );
425 printTypeSize( void *, "void *" );
428 printf( "BIGENDIAN (Sparc, RS6000, IP22, IP32, PowerPC(BE))\n" );
430 printf( "LITTLEENDIAN (Intel, x86-64, PowerPC(LE))\n" );
432 /* PrintArgs( 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ); */
436 struct Description description
;
437 Description_Ctor( &description
);
438 Description_Print( &description
, argv
[1] );
442 InfoMemoryAccess( p
);
444 InfoMemoryAccess( p
);
445 InfoMemoryTypeAccess( t_short
);
446 InfoMemoryTypeAccess( t_int
);
447 InfoMemoryTypeAccess( t_long
);
448 InfoMemoryTypeAccess( t_double
);
454 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */