From 16fa8d7cc8c92f5ab879e4cf9c6c0bbb3567860f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 24 May 2018 01:37:55 -0700 Subject: systemc: Import tests from the Accellera systemc distribution. Change-Id: Iad76b398949a55d768a34d027a2d8e3739953da6 Reviewed-on: https://gem5-review.googlesource.com/10845 Reviewed-by: Giacomo Travaglini Maintainer: Gabe Black --- .../bugs/stack_alignment/stack_alignment.cpp | 129 +++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 src/systemc/tests/systemc/bugs/stack_alignment/stack_alignment.cpp (limited to 'src/systemc/tests/systemc/bugs/stack_alignment/stack_alignment.cpp') diff --git a/src/systemc/tests/systemc/bugs/stack_alignment/stack_alignment.cpp b/src/systemc/tests/systemc/bugs/stack_alignment/stack_alignment.cpp new file mode 100644 index 000000000..e20395e2f --- /dev/null +++ b/src/systemc/tests/systemc/bugs/stack_alignment/stack_alignment.cpp @@ -0,0 +1,129 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + stack_alignment.cpp -- This example shows the crash of an fxsave instruction + in the sc_thread stack environment, but not in the + original linux process stack, which is correctly + aligned on first function. + + Please note that this test probably runs OK on a faulty implementation in + 64-bit in general (depending on your libc implementation), but will crash + for sure in 32-bit. + + Original Author: Eric Paire, STMicroelectronics + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +#include "systemc.h" + +/* + * This program exhibits a bug in the management by QT of the stack of each + * SystemC process. At least on i686 & x86_64, GCC makes the assumption that + * the stack is aligned on a 16-byte boundary on each C/C++ function entry. + * This convention allows GCC to respects constraints of automatic (stack) + * variable alignment, using the __attribute)__ ((align(X))) GCC extension. + * + * The X is known to be 16 for i686 & x86_64, as this is the largest alignment + * required by instructions operands, actually used by fxsave instruction. + * + * The attached code shows up the problem by crashing when fxsave is executed + * in a SystemC thread, and executing correctly the *same* code on the initial + * process stack, as initialized by the libc runtime. + * + * This misbehavior does not occur systematically for x86_64 (no crash, + * or crash difficult to reproduce with standard malloc()), but often does + * with i686. Notice that the instruction with the right alignment is shown + * when using the myfpxregs address which is aligned on 16-byte boundary. + */ + +#if defined(__x86_64__) +# define FXSAVE "fxsaveq" +#else +# define FXSAVE "fxsave" +#endif + +#if defined(__GNUC__) +# define ALIGNED_ARRAY( Type, Name, Size, Align ) \ + Type Name[Size] __attribute__((aligned(Align))) +#elif defined(_MSC_VER) +# define ALIGNED_ARRAY( Type, Name, Size, Align ) \ + __declspec(align(Align)) Type Name[Size] +#endif + +#if defined(__GNUC__) && ( defined(__x86_64__) || defined(__i386__) ) +# define ASM( Assembly ) __asm__ __volatile__( Assembly ) +#else +# define ASM( Assembly ) /* not implemented */ +#endif + +// Class +SC_MODULE(C) +{ +public: + SC_CTOR(C) { + SC_THREAD(run); + } + void run(void) + { + ALIGNED_ARRAY( char, fpxregs64, 512+15, 16 ); + + cout << "Inside C::run() " << endl; + + // manually enforce alignment (volatile to avoid optmizations) + char * volatile myfpxregs = fpxregs64; + while ((uintptr_t)myfpxregs & 0xF) + myfpxregs++; + + // the "real" requirement: enforced alignment works + sc_assert( !((uintptr_t)fpxregs64 & 0xF) ); + sc_assert( !((uintptr_t)myfpxregs & 0xF) ); + sc_assert( myfpxregs == fpxregs64 ); + + // test assembly on supported platforms + ASM( FXSAVE " (%0)" :: "r"(myfpxregs) ); + cout << "Between C::run() " << endl; + ASM( FXSAVE " %0" : "=m"(fpxregs64) ); + + cout << "Out of C::run() " << endl; + } +}; + +int sc_main(int , char** ) { + C the_C("C"); + + ALIGNED_ARRAY( char, fpxregs64, 512, 16 ); + + cout << "Inside sc_main() " << endl; + ASM( FXSAVE " %0" : "=m"(fpxregs64) ); + sc_start(1, SC_NS); + cout << "Out of sc_main() " << endl; + return 0; +} -- cgit v1.2.3