Re: Portable inline asm to get address of TLS variable
> I took a quick look at C++20 coroutines since they are available in > compilers but the primitives look hard to use even from C++, let alone > from C. Same story here :-/
Re: Portable inline asm to get address of TLS variable
On Thu, Feb 17, 2022 at 12:40:40PM +0100, Paolo Bonzini wrote: > On 2/17/22 10:28, Stefan Hajnoczi wrote: > >>But going against ABI and toolchain in this way is really no long-term > >>solution. You need to switch to stackless co-routines, or we need to > >>provide proper ABI-level support for this. Today it's the thread > >>pointer, tomorrow it's the shadow stack pointer, and the day after that, > >>it's the SafeStack pointer. And further down the road, it's some thread > >>state for garbage collection support. Or something like that. > > > >Yes, understood :(. This does feel like solving an undefined behavior > >problem by adding more undefined behavior on top! > > Yes, this is the kind of thing that I generally despise when I see > other programs do it... it's easy to dig ourselves in the same > hole. > > >I took a quick look at C++20 coroutines since they are available in > >compilers but the primitives look hard to use even from C++, let alone > >from C. > > They're C++ only in GCC, too. I really think that QEMU should be > compilable in C++, but I'm not sure how easy a sell it is. It's perfectly fine to have one compilation unit written in C++ with a few symbol in `extern "C"`. No need to touch the other part of the project.
Re: [RFC v2 1/4] tls: add macros for coroutine-safe TLS variables
On Thu, Dec 02, 2021 at 02:44:42PM +, Peter Maydell wrote: > On Wed, 1 Dec 2021 at 17:19, Stefan Hajnoczi wrote: > > > > Compiler optimizations can cache TLS values across coroutine yield > > points, resulting in stale values from the previous thread when a > > coroutine is re-entered by a new thread. > > > > Serge Guelton developed an __attribute__((noinline)) wrapper and tested > > it with clang and gcc. I formatted his idea according to QEMU's coding > > style and wrote documentation. > > > +#ifdef QEMU_CO_TLS_ADDR > > +#define QEMU_DEFINE_STATIC_CO_TLS(type, var)\ > > +__thread type co_tls_##var; \ > > +static inline type get_##var(void) \ > > +{ type *p; QEMU_CO_TLS_ADDR(p, co_tls_##var); return *p; } \ > > +static inline void set_##var(type v)\ > > +{ type *p; QEMU_CO_TLS_ADDR(p, co_tls_##var); *p = v; } \ > > +static inline type *get_ptr_##var(void) \ > > +{ type *p; QEMU_CO_TLS_ADDR(p, co_tls_##var); return p; } > > +#else > > +#define QEMU_DEFINE_STATIC_CO_TLS(type, var)\ > > +static __thread type co_tls_##var; \ > > +static __attribute__((noinline, unused)) type get_##var(void) \ > > +{ return co_tls_##var; }\ > > +static __attribute__((noinline, unused)) void set_##var(type v) \ > > +{ co_tls_##var = v; } \ > > +static __attribute__((noinline, unused)) type *get_ptr_##var(void) \ > > +{ return &co_tls_##var; } > > +#endif > > My compiler-developer colleagues present the following case where > 'noinline' is not sufficient for the compiler to definitely > use different values of the address-of-the-TLS-var across an > intervening function call: > > __thread int i; > > __attribute__((noinline)) long get_ptr_i() > { > return (long)&i; > } > > void switcher(); > > int g() > { > long a = get_ptr_i(); > switcher(); > return a == get_ptr_i(); > } You can also force an extra mov through `volatile` as in https://godbolt.org/z/hWvdb7o9G
[PATCH v2] Fix typo in CFI build documentation
Signed-off-by: Serge Guelton Reviewed-by: Philippe Mathieu-Daudé --- docs/devel/control-flow-integrity.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/devel/control-flow-integrity.rst b/docs/devel/control-flow-integrity.rst index d89d707..e6b73a4 100644 --- a/docs/devel/control-flow-integrity.rst +++ b/docs/devel/control-flow-integrity.rst @@ -39,7 +39,7 @@ later). Given the use of LTO, a version of AR that supports LLVM IR is required. The easies way of doing this is by selecting the AR provided by LLVM:: - AR=llvm-ar-9 CC=clang-9 CXX=lang++-9 /path/to/configure --enable-cfi + AR=llvm-ar-9 CC=clang-9 CXX=clang++-9 /path/to/configure --enable-cfi CFI is enabled on every binary produced. @@ -131,7 +131,7 @@ lld with version 11+. In other words, to compile with fuzzing and CFI, clang 11+ is required, and lld needs to be used as a linker:: - AR=llvm-ar-11 CC=clang-11 CXX=lang++-11 /path/to/configure --enable-cfi \ + AR=llvm-ar-11 CC=clang-11 CXX=clang++-11 /path/to/configure --enable-cfi \ -enable-fuzzing --extra-ldflags="-fuse-ld=lld" and then, compile the fuzzers as usual. -- 1.8.3.1
[PATCH] Fix typo in CFI build documentation
From: serge-sans-paille Signed-off-by: Serge Guelton Reviewed-by: Philippe Mathieu-Daudé --- docs/devel/control-flow-integrity.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/devel/control-flow-integrity.rst b/docs/devel/control-flow-integrity.rst index d89d707..e6b73a4 100644 --- a/docs/devel/control-flow-integrity.rst +++ b/docs/devel/control-flow-integrity.rst @@ -39,7 +39,7 @@ later). Given the use of LTO, a version of AR that supports LLVM IR is required. The easies way of doing this is by selecting the AR provided by LLVM:: - AR=llvm-ar-9 CC=clang-9 CXX=lang++-9 /path/to/configure --enable-cfi + AR=llvm-ar-9 CC=clang-9 CXX=clang++-9 /path/to/configure --enable-cfi CFI is enabled on every binary produced. @@ -131,7 +131,7 @@ lld with version 11+. In other words, to compile with fuzzing and CFI, clang 11+ is required, and lld needs to be used as a linker:: - AR=llvm-ar-11 CC=clang-11 CXX=lang++-11 /path/to/configure --enable-cfi \ + AR=llvm-ar-11 CC=clang-11 CXX=clang++-11 /path/to/configure --enable-cfi \ -enable-fuzzing --extra-ldflags="-fuse-ld=lld" and then, compile the fuzzers as usual. -- 1.8.3.1