Commit c95f3432 authored by Jiri Olsa's avatar Jiri Olsa Committed by Arnaldo Carvalho de Melo

tools include: Fix strict-aliasing rules breakage

Vinson reported build breakage with gcc 4.4 due to strict-aliasing.

   CC       util/annotate.o
 cc1: warnings being treated as errors
 util/annotate.c: In function ‘disasm__purge’:
 linux-next/tools/include/linux/compiler.h:66: error: dereferencing
 pointer ‘res.41’ does break strict-aliasing rules

The reason is READ_ONCE/WRITE_ONCE code we took from kernel sources.  They
intentionaly break aliasing rules. While this is ok for kernel because it's
built with -fno-strict-aliasing, it breaks perf which is build with
-Wstrict-aliasing=3.

Using extra __may_alias__ type to allow aliasing in this case.
Reported-and-tested-by: default avatarVinson Lee <vlee@twopensource.com>
Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Martin Liska <mliska@suse.cz>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Rabin Vincent <rabin@rab.in>
Cc: linux-next@vger.kernel.org
Link: http://lkml.kernel.org/r/20151013085214.GB2705@krava.brq.redhat.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 31eb4360
...@@ -43,13 +43,29 @@ ...@@ -43,13 +43,29 @@
#include <linux/types.h> #include <linux/types.h>
/*
* Following functions are taken from kernel sources and
* break aliasing rules in their original form.
*
* While kernel is compiled with -fno-strict-aliasing,
* perf uses -Wstrict-aliasing=3 which makes build fail
* under gcc 4.4.
*
* Using extra __may_alias__ type to allow aliasing
* in this case.
*/
typedef __u8 __attribute__((__may_alias__)) __u8_alias_t;
typedef __u16 __attribute__((__may_alias__)) __u16_alias_t;
typedef __u32 __attribute__((__may_alias__)) __u32_alias_t;
typedef __u64 __attribute__((__may_alias__)) __u64_alias_t;
static __always_inline void __read_once_size(const volatile void *p, void *res, int size) static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
{ {
switch (size) { switch (size) {
case 1: *(__u8 *)res = *(volatile __u8 *)p; break; case 1: *(__u8_alias_t *) res = *(volatile __u8_alias_t *) p; break;
case 2: *(__u16 *)res = *(volatile __u16 *)p; break; case 2: *(__u16_alias_t *) res = *(volatile __u16_alias_t *) p; break;
case 4: *(__u32 *)res = *(volatile __u32 *)p; break; case 4: *(__u32_alias_t *) res = *(volatile __u32_alias_t *) p; break;
case 8: *(__u64 *)res = *(volatile __u64 *)p; break; case 8: *(__u64_alias_t *) res = *(volatile __u64_alias_t *) p; break;
default: default:
barrier(); barrier();
__builtin_memcpy((void *)res, (const void *)p, size); __builtin_memcpy((void *)res, (const void *)p, size);
...@@ -60,10 +76,10 @@ static __always_inline void __read_once_size(const volatile void *p, void *res, ...@@ -60,10 +76,10 @@ static __always_inline void __read_once_size(const volatile void *p, void *res,
static __always_inline void __write_once_size(volatile void *p, void *res, int size) static __always_inline void __write_once_size(volatile void *p, void *res, int size)
{ {
switch (size) { switch (size) {
case 1: *(volatile __u8 *)p = *(__u8 *)res; break; case 1: *(volatile __u8_alias_t *) p = *(__u8_alias_t *) res; break;
case 2: *(volatile __u16 *)p = *(__u16 *)res; break; case 2: *(volatile __u16_alias_t *) p = *(__u16_alias_t *) res; break;
case 4: *(volatile __u32 *)p = *(__u32 *)res; break; case 4: *(volatile __u32_alias_t *) p = *(__u32_alias_t *) res; break;
case 8: *(volatile __u64 *)p = *(__u64 *)res; break; case 8: *(volatile __u64_alias_t *) p = *(__u64_alias_t *) res; break;
default: default:
barrier(); barrier();
__builtin_memcpy((void *)p, (const void *)res, size); __builtin_memcpy((void *)p, (const void *)res, size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment