From c8b5f2c96d1bf6cefcbe12f67dce0b892fe20512 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 6 Jul 2016 11:56:20 -0300 Subject: tools: Introduce str_error_r() The tools so far have been using the strerror_r() GNU variant, that returns a string, be it the buffer passed or something else. But that, besides being tricky in cases where we expect that the function using strerror_r() returns the error formatted in a provided buffer (we have to check if it returned something else and copy that instead), breaks the build on systems not using glibc, like Alpine Linux, where musl libc is used. So, introduce yet another wrapper, str_error_r(), that has the GNU interface, but uses the portable XSI variant of strerror_r(), so that users rest asured that the provided buffer is used and it is what is returned. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-d4t42fnf48ytlk8rjxs822tf@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/string.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/include/linux') diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index e26223f1f287..b466d0228b57 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -12,4 +12,6 @@ int strtobool(const char *s, bool *res); extern size_t strlcpy(char *dest, const char *src, size_t size); #endif +char *str_error_r(int errnum, char *buf, size_t buflen); + #endif /* _LINUX_STRING_H_ */ -- cgit v1.3-8-gc7d7 From d0761e37fe3fed7810ed8d6e130b79359f0c3e13 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 7 Jul 2016 15:42:33 -0300 Subject: perf tools: Uninline scnprintf() and vscnprint() They were in tools/include/linux/kernel.h, requiring that it in turn included stdio.h, which is way too heavy. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Josh Poimboeuf Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-855h8olnkot9v0dajuee1lo3@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/kernel.h | 28 +++------------------------- tools/lib/vsprintf.c | 24 ++++++++++++++++++++++++ tools/objtool/builtin-check.c | 1 + tools/perf/MANIFEST | 1 + tools/perf/util/Build | 5 +++++ tools/perf/util/color.c | 2 ++ tools/perf/util/dso.h | 1 + tools/perf/util/help-unknown-cmd.c | 1 + tools/perf/util/python-ext-sources | 1 + 9 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 tools/lib/vsprintf.c (limited to 'tools/include/linux') diff --git a/tools/include/linux/kernel.h b/tools/include/linux/kernel.h index 76df53539c2a..28607db02bd3 100644 --- a/tools/include/linux/kernel.h +++ b/tools/include/linux/kernel.h @@ -2,8 +2,7 @@ #define __TOOLS_LINUX_KERNEL_H #include -#include -#include +#include #include #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) @@ -70,29 +69,8 @@ #define cpu_to_le64(x) (x) #define cpu_to_le32(x) (x) -static inline int -vscnprintf(char *buf, size_t size, const char *fmt, va_list args) -{ - int i; - ssize_t ssize = size; - - i = vsnprintf(buf, size, fmt, args); - - return (i >= ssize) ? (ssize - 1) : i; -} - -static inline int scnprintf(char * buf, size_t size, const char * fmt, ...) -{ - va_list args; - ssize_t ssize = size; - int i; - - va_start(args, fmt); - i = vsnprintf(buf, size, fmt, args); - va_end(args); - - return (i >= ssize) ? (ssize - 1) : i; -} +int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); +int scnprintf(char * buf, size_t size, const char * fmt, ...); /* * This looks more complex than it should be. But we need to diff --git a/tools/lib/vsprintf.c b/tools/lib/vsprintf.c new file mode 100644 index 000000000000..45f9a06daa56 --- /dev/null +++ b/tools/lib/vsprintf.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) +{ + int i = vsnprintf(buf, size, fmt, args); + ssize_t ssize = size; + + return (i >= ssize) ? (ssize - 1) : i; +} + +int scnprintf(char * buf, size_t size, const char * fmt, ...) +{ + ssize_t ssize = size; + va_list args; + int i; + + va_start(args, fmt); + i = vsnprintf(buf, size, fmt, args); + va_end(args); + + return (i >= ssize) ? (ssize - 1) : i; +} diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index e8a1e69eb92c..92d84b277032 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -26,6 +26,7 @@ */ #include +#include #include #include "builtin.h" diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index f18e781447bc..2bd8c310606c 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -30,6 +30,7 @@ tools/lib/symbol/kallsyms.h tools/lib/find_bit.c tools/lib/bitmap.c tools/lib/str_error_r.c +tools/lib/vsprintf.c tools/include/asm/atomic.h tools/include/asm/barrier.h tools/include/asm/bug.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index a6a805302312..eda68f582884 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -85,6 +85,7 @@ libperf-y += parse-regs-options.o libperf-y += term.o libperf-y += help-unknown-cmd.o libperf-y += mem-events.o +libperf-y += vsprintf.o libperf-$(CONFIG_LIBBPF) += bpf-loader.o libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o @@ -181,3 +182,7 @@ $(OUTPUT)util/str_error_r.o: ../lib/str_error_r.c FORCE $(OUTPUT)util/hweight.o: ../lib/hweight.c FORCE $(call rule_mkdir) $(call if_changed_dep,cc_o_c) + +$(OUTPUT)util/vsprintf.o: ../lib/vsprintf.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_o_c) diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c index 47a34b561f5d..dbbf89b050a5 100644 --- a/tools/perf/util/color.c +++ b/tools/perf/util/color.c @@ -1,6 +1,8 @@ #include #include "cache.h" #include "config.h" +#include +#include #include "color.h" #include #include diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index a571f24895ca..ecc4bbd3f82e 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/perf/util/help-unknown-cmd.c b/tools/perf/util/help-unknown-cmd.c index 776e28562345..2821f8d77e52 100644 --- a/tools/perf/util/help-unknown-cmd.c +++ b/tools/perf/util/help-unknown-cmd.c @@ -1,5 +1,6 @@ #include "cache.h" #include "config.h" +#include #include #include "../builtin.h" #include "levenshtein.h" diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 49210b7a7925..5065ec98049c 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -14,6 +14,7 @@ util/cpumap.c ../lib/find_bit.c ../lib/hweight.c ../lib/str_error_r.c +../lib/vsprintf.c util/thread_map.c util/util.c util/xyarray.c -- cgit v1.3-8-gc7d7 From 61a6445e463a3152590352d8634131955f531c6e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 8 Jul 2016 15:38:51 -0300 Subject: tools lib: Guard the strlcpy() header with __GLIBC__ Better to whitelist it for libraries that require it (glibc) than blacklist it with the ones that don't (uclibc, musl libc, etc). Cc: Adrian Hunter Cc: Alexey Brodkin Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Vineet Gupta Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-52ih0m63a2n63tanpy6yj682@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/include/linux') diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index b466d0228b57..b96879477311 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -8,7 +8,7 @@ void *memdup(const void *src, size_t len); int strtobool(const char *s, bool *res); -#ifndef __UCLIBC__ +#ifdef __GLIBC__ extern size_t strlcpy(char *dest, const char *src, size_t size); #endif -- cgit v1.3-8-gc7d7 From 7b39cafb7aa68ef8e32a9f51fbe737d96084ca74 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 13 Jul 2016 09:37:43 +0200 Subject: tools: Work around BITS_PER_LONG related build failure in objtool The objtool build fails with the recent changes to the bits-per-long headers: tools/include/linux/bitops.h:12:0: error: "BITS_PER_LONG" redefined [-Werror] Which got introduced by: bb9707077b4e tools: Copy the bitsperlong.h files from the kernel Work it around for the time being. Cc: Arnaldo Carvalho de Melo Cc: Josh Poimboeuf Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar --- tools/include/linux/bitops.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools/include/linux') diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h index 5ad9ee1dd7f6..49c929a104ee 100644 --- a/tools/include/linux/bitops.h +++ b/tools/include/linux/bitops.h @@ -9,7 +9,9 @@ #define __WORDSIZE (__SIZEOF_LONG__ * 8) #endif -#define BITS_PER_LONG __WORDSIZE +#ifndef BITS_PER_LONG +# define BITS_PER_LONG __WORDSIZE +#endif #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) -- cgit v1.3-8-gc7d7 From 8c98abff43616a2a9c208189f86d32cefafbe708 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 14 Jul 2016 12:03:04 -0300 Subject: tools: Make "__always_inline" just "inline" on Android As the gcc there is producing tons of: "warning: always_inline function might not be inlinable" At least on android-ndk-r12/platforms/android-24/arch-arm, so, for the time being, use this big hammer. Cc: Adrian Hunter Cc: Chris Phlipot Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-97l3eg3fnk5shmo4rsyyvj2t@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/compiler.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'tools/include/linux') diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h index fa7208a32d76..e33fc1df3935 100644 --- a/tools/include/linux/compiler.h +++ b/tools/include/linux/compiler.h @@ -9,6 +9,17 @@ # define __always_inline inline __attribute__((always_inline)) #endif +#ifdef __ANDROID__ +/* + * FIXME: Big hammer to get rid of tons of: + * "warning: always_inline function might not be inlinable" + * + * At least on android-ndk-r12/platforms/android-24/arch-arm + */ +#undef __always_inline +#define __always_inline inline +#endif + #define __user #ifndef __attribute_const__ -- cgit v1.3-8-gc7d7 From ae3c14a028ed10552803b68276b6833295ba18cf Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 18 Jul 2016 18:39:36 -0300 Subject: tools: Copy linux/{hash,poison}.h and check for drift We were also using this directly from the kernel sources, the two last cases, fix it. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-7o14xvacqcjc5llc7gvjjyl8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/hash.h | 105 +++++++++++++++++++++++++++++++++++++++++-- tools/include/linux/poison.h | 91 ++++++++++++++++++++++++++++++++++++- tools/perf/MANIFEST | 2 - tools/perf/Makefile.perf | 3 ++ 4 files changed, 195 insertions(+), 6 deletions(-) (limited to 'tools/include/linux') diff --git a/tools/include/linux/hash.h b/tools/include/linux/hash.h index d026c6573018..ad6fa21d977b 100644 --- a/tools/include/linux/hash.h +++ b/tools/include/linux/hash.h @@ -1,5 +1,104 @@ -#include "../../../include/linux/hash.h" +#ifndef _LINUX_HASH_H +#define _LINUX_HASH_H +/* Fast hashing routine for ints, longs and pointers. + (C) 2002 Nadia Yvette Chambers, IBM */ -#ifndef _TOOLS_LINUX_HASH_H -#define _TOOLS_LINUX_HASH_H +#include +#include + +/* + * The "GOLDEN_RATIO_PRIME" is used in ifs/btrfs/brtfs_inode.h and + * fs/inode.c. It's not actually prime any more (the previous primes + * were actively bad for hashing), but the name remains. + */ +#if BITS_PER_LONG == 32 +#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_32 +#define hash_long(val, bits) hash_32(val, bits) +#elif BITS_PER_LONG == 64 +#define hash_long(val, bits) hash_64(val, bits) +#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_64 +#else +#error Wordsize not 32 or 64 +#endif + +/* + * This hash multiplies the input by a large odd number and takes the + * high bits. Since multiplication propagates changes to the most + * significant end only, it is essential that the high bits of the + * product be used for the hash value. + * + * Chuck Lever verified the effectiveness of this technique: + * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf + * + * Although a random odd number will do, it turns out that the golden + * ratio phi = (sqrt(5)-1)/2, or its negative, has particularly nice + * properties. (See Knuth vol 3, section 6.4, exercise 9.) + * + * These are the negative, (1 - phi) = phi**2 = (3 - sqrt(5))/2, + * which is very slightly easier to multiply by and makes no + * difference to the hash distribution. + */ +#define GOLDEN_RATIO_32 0x61C88647 +#define GOLDEN_RATIO_64 0x61C8864680B583EBull + +#ifdef CONFIG_HAVE_ARCH_HASH +/* This header may use the GOLDEN_RATIO_xx constants */ +#include +#endif + +/* + * The _generic versions exist only so lib/test_hash.c can compare + * the arch-optimized versions with the generic. + * + * Note that if you change these, any that aren't updated + * to match need to have their HAVE_ARCH_* define values updated so the + * self-test will not false-positive. + */ +#ifndef HAVE_ARCH__HASH_32 +#define __hash_32 __hash_32_generic +#endif +static inline u32 __hash_32_generic(u32 val) +{ + return val * GOLDEN_RATIO_32; +} + +#ifndef HAVE_ARCH_HASH_32 +#define hash_32 hash_32_generic #endif +static inline u32 hash_32_generic(u32 val, unsigned int bits) +{ + /* High bits are more random, so use them. */ + return __hash_32(val) >> (32 - bits); +} + +#ifndef HAVE_ARCH_HASH_64 +#define hash_64 hash_64_generic +#endif +static __always_inline u32 hash_64_generic(u64 val, unsigned int bits) +{ +#if BITS_PER_LONG == 64 + /* 64x64-bit multiply is efficient on all 64-bit processors */ + return val * GOLDEN_RATIO_64 >> (64 - bits); +#else + /* Hash 64 bits using only 32x32-bit multiply. */ + return hash_32((u32)val ^ __hash_32(val >> 32), bits); +#endif +} + +static inline u32 hash_ptr(const void *ptr, unsigned int bits) +{ + return hash_long((unsigned long)ptr, bits); +} + +/* This really should be called fold32_ptr; it does no hashing to speak of. */ +static inline u32 hash32_ptr(const void *ptr) +{ + unsigned long val = (unsigned long)ptr; + +#if BITS_PER_LONG == 64 + val ^= (val >> 32); +#endif + return (u32)val; +} + +#endif /* _LINUX_HASH_H */ diff --git a/tools/include/linux/poison.h b/tools/include/linux/poison.h index 0c27bdf14233..51334edec506 100644 --- a/tools/include/linux/poison.h +++ b/tools/include/linux/poison.h @@ -1 +1,90 @@ -#include "../../../include/linux/poison.h" +#ifndef _LINUX_POISON_H +#define _LINUX_POISON_H + +/********** include/linux/list.h **********/ + +/* + * Architectures might want to move the poison pointer offset + * into some well-recognized area such as 0xdead000000000000, + * that is also not mappable by user-space exploits: + */ +#ifdef CONFIG_ILLEGAL_POINTER_VALUE +# define POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL) +#else +# define POISON_POINTER_DELTA 0 +#endif + +/* + * These are non-NULL pointers that will result in page faults + * under normal circumstances, used to verify that nobody uses + * non-initialized list entries. + */ +#define LIST_POISON1 ((void *) 0x100 + POISON_POINTER_DELTA) +#define LIST_POISON2 ((void *) 0x200 + POISON_POINTER_DELTA) + +/********** include/linux/timer.h **********/ +/* + * Magic number "tsta" to indicate a static timer initializer + * for the object debugging code. + */ +#define TIMER_ENTRY_STATIC ((void *) 0x300 + POISON_POINTER_DELTA) + +/********** mm/debug-pagealloc.c **********/ +#ifdef CONFIG_PAGE_POISONING_ZERO +#define PAGE_POISON 0x00 +#else +#define PAGE_POISON 0xaa +#endif + +/********** mm/page_alloc.c ************/ + +#define TAIL_MAPPING ((void *) 0x400 + POISON_POINTER_DELTA) + +/********** mm/slab.c **********/ +/* + * Magic nums for obj red zoning. + * Placed in the first word before and the first word after an obj. + */ +#define RED_INACTIVE 0x09F911029D74E35BULL /* when obj is inactive */ +#define RED_ACTIVE 0xD84156C5635688C0ULL /* when obj is active */ + +#define SLUB_RED_INACTIVE 0xbb +#define SLUB_RED_ACTIVE 0xcc + +/* ...and for poisoning */ +#define POISON_INUSE 0x5a /* for use-uninitialised poisoning */ +#define POISON_FREE 0x6b /* for use-after-free poisoning */ +#define POISON_END 0xa5 /* end-byte of poisoning */ + +/********** arch/$ARCH/mm/init.c **********/ +#define POISON_FREE_INITMEM 0xcc + +/********** arch/ia64/hp/common/sba_iommu.c **********/ +/* + * arch/ia64/hp/common/sba_iommu.c uses a 16-byte poison string with a + * value of "SBAIOMMU POISON\0" for spill-over poisoning. + */ + +/********** fs/jbd/journal.c **********/ +#define JBD_POISON_FREE 0x5b +#define JBD2_POISON_FREE 0x5c + +/********** drivers/base/dmapool.c **********/ +#define POOL_POISON_FREED 0xa7 /* !inuse */ +#define POOL_POISON_ALLOCATED 0xa9 /* !initted */ + +/********** drivers/atm/ **********/ +#define ATM_POISON_FREE 0x12 +#define ATM_POISON 0xdeadbeef + +/********** kernel/mutexes **********/ +#define MUTEX_DEBUG_INIT 0x11 +#define MUTEX_DEBUG_FREE 0x22 + +/********** lib/flex_array.c **********/ +#define FLEX_ARRAY_FREE 0x6c /* for use-after-free poisoning */ + +/********** security/ **********/ +#define KEY_DESTROY 0xbd + +#endif diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 3ac7f8dff47f..ad2534df4ba6 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -77,6 +77,4 @@ tools/include/linux/stringify.h tools/include/linux/types.h tools/include/linux/err.h tools/include/linux/bitmap.h -include/linux/hash.h tools/arch/*/include/uapi/asm/perf_regs.h -include/linux/poison.h diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 580f4e208c7a..6641abb97f0a 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -351,6 +351,9 @@ $(PERF_IN): prepare FORCE @(test -f ../../include/uapi/linux/perf_event.h && ( \ (diff -B ../include/uapi/linux/perf_event.h ../../include/uapi/linux/perf_event.h >/dev/null) \ || echo "Warning: tools/include/uapi/linux/perf_event.h differs from kernel" >&2 )) || true + @(test -f ../../include/linux/hash.h && ( \ + (diff -B ../include/linux/hash.h ../../include/linux/hash.h >/dev/null) \ + || echo "Warning: tools/include/linux/hash.h differs from kernel" >&2 )) || true @(test -f ../../include/uapi/linux/hw_breakpoint.h && ( \ (diff -B ../include/uapi/linux/hw_breakpoint.h ../../include/uapi/linux/hw_breakpoint.h >/dev/null) \ || echo "Warning: tools/include/uapi/linux/hw_breakpoint.h differs from kernel" >&2 )) || true -- cgit v1.3-8-gc7d7 From 98c032967a299ee4bf14ef19eded02b65df32e6f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 2 Aug 2016 13:33:02 +0200 Subject: tools lib: Add bitmap_alloc function Adding bitmap_alloc function to dynamically allocate bitmap. Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20160802113302.GA7479@krava Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/bitmap.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tools/include/linux') diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h index 28f5493da491..60c44b615902 100644 --- a/tools/include/linux/bitmap.h +++ b/tools/include/linux/bitmap.h @@ -3,6 +3,7 @@ #include #include +#include #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] @@ -65,4 +66,13 @@ static inline int test_and_set_bit(int nr, unsigned long *addr) return (old & mask) != 0; } +/** + * bitmap_alloc - Allocate bitmap + * @nr: Bit to set + */ +static inline unsigned long *bitmap_alloc(int nbits) +{ + return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long)); +} + #endif /* _PERF_BITOPS_H */ -- cgit v1.3-8-gc7d7 From 820d12b70f91a19eb4a3152b9dd4ea9aee194a36 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 1 Aug 2016 20:02:30 +0200 Subject: tools lib: Add bitmap_scnprintf function Add support to print bitmap list. Code mostly taken from kernel's bitmap_list_string. Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1470074555-24889-3-git-send-email-jolsa@kernel.org [ s/bitmap_snprintf/bitmap_scnprintf/g as it is a scnprintf wrapper, having the same semantics wrt return value ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/bitmap.h | 10 ++++++++++ tools/lib/bitmap.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) (limited to 'tools/include/linux') diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h index 60c44b615902..1cdded0041a8 100644 --- a/tools/include/linux/bitmap.h +++ b/tools/include/linux/bitmap.h @@ -75,4 +75,14 @@ static inline unsigned long *bitmap_alloc(int nbits) return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long)); } +/* + * bitmap_scnprintf - print bitmap list into buffer + * @bitmap: bitmap + * @nbits: size of bitmap + * @buf: buffer to store output + * @size: size of @buf + */ +size_t bitmap_scnprintf(unsigned long *bitmap, int nbits, + char *buf, size_t size); + #endif /* _PERF_BITOPS_H */ diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c index 0a1adc1111fd..5c7e3185507c 100644 --- a/tools/lib/bitmap.c +++ b/tools/lib/bitmap.c @@ -29,3 +29,32 @@ void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, for (k = 0; k < nr; k++) dst[k] = bitmap1[k] | bitmap2[k]; } + +size_t bitmap_scnprintf(unsigned long *bitmap, int nbits, + char *buf, size_t size) +{ + /* current bit is 'cur', most recently seen range is [rbot, rtop] */ + int cur, rbot, rtop; + bool first = true; + size_t ret = 0; + + rbot = cur = find_first_bit(bitmap, nbits); + while (cur < nbits) { + rtop = cur; + cur = find_next_bit(bitmap, nbits, cur + 1); + if (cur < nbits && cur <= rtop + 1) + continue; + + if (!first) + ret += scnprintf(buf + ret, size - ret, ","); + + first = false; + + ret += scnprintf(buf + ret, size - ret, "%d", rbot); + if (rbot < rtop) + ret += scnprintf(buf + ret, size - ret, "-%d", rtop); + + rbot = cur; + } + return ret; +} -- cgit v1.3-8-gc7d7 From 741c74f55e8a66f3bc5bbc29dc162c952759e47b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 1 Aug 2016 20:02:31 +0200 Subject: tools lib: Add bitmap_and function Add support to perform logical and on bitmaps. Code taken from kernel's include/linux/bitmap.h. Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1470074555-24889-4-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/bitmap.h | 17 +++++++++++++++++ tools/lib/bitmap.c | 15 +++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'tools/include/linux') diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h index 1cdded0041a8..43c1c5021e4b 100644 --- a/tools/include/linux/bitmap.h +++ b/tools/include/linux/bitmap.h @@ -11,6 +11,8 @@ int __bitmap_weight(const unsigned long *bitmap, int bits); void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, const unsigned long *bitmap2, int bits); +int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, unsigned int bits); #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) @@ -85,4 +87,19 @@ static inline unsigned long *bitmap_alloc(int nbits) size_t bitmap_scnprintf(unsigned long *bitmap, int nbits, char *buf, size_t size); +/** + * bitmap_and - Do logical and on bitmaps + * @dst: resulting bitmap + * @src1: operand 1 + * @src2: operand 2 + * @nbits: size of bitmap + */ +static inline int bitmap_and(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, unsigned int nbits) +{ + if (small_const_nbits(nbits)) + return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0; + return __bitmap_and(dst, src1, src2, nbits); +} + #endif /* _PERF_BITOPS_H */ diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c index 5c7e3185507c..38748b0e342f 100644 --- a/tools/lib/bitmap.c +++ b/tools/lib/bitmap.c @@ -58,3 +58,18 @@ size_t bitmap_scnprintf(unsigned long *bitmap, int nbits, } return ret; } + +int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, unsigned int bits) +{ + unsigned int k; + unsigned int lim = bits/BITS_PER_LONG; + unsigned long result = 0; + + for (k = 0; k < lim; k++) + result |= (dst[k] = bitmap1[k] & bitmap2[k]); + if (bits % BITS_PER_LONG) + result |= (dst[k] = bitmap1[k] & bitmap2[k] & + BITMAP_LAST_WORD_MASK(bits)); + return result != 0; +} -- cgit v1.3-8-gc7d7 From 0215d59b154ab90c56c4fe49bc1deefe8bca18f1 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Thu, 18 Aug 2016 09:28:23 -0700 Subject: tools lib: Reinstate strlcpy() header guard with __UCLIBC__ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit perf tools build in recent kernels spews splat when cross compiling with uClibc: | CC util/alias.o | In file included from tools/perf/util/../ui/../util/cache.h:8:0, | from tools/perf/util/../ui/helpline.h:7, | from tools/perf/util/debug.h:8, | from arch/../util/cpumap.h:9, | from arch/../util/env.h:5, | from arch/common.h:4, | from arch/common.c:3: | tools/include/linux/string.h:12:15: warning: redundant redeclaration of ‘strlcpy’ [-Wredundant-decls] | extern size_t strlcpy(char *dest, const char *src, size_t size); ^ This is after commit 61a6445e463a31 ("tools lib: Guard the strlcpy() header with __GLIBC__"). The problem is uClibc also defines __GLIBC__ for exported headers for applications. So add that specific check to not trip for uClibc. Signed-off-by: Vineet Gupta Cc: Adrian Hunter Cc: Alexey Brodkin Cc: David Ahern Cc: Jiri Olsa Cc: Josh Poimboeuf Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Petri Gynther Cc: Wang Nan Cc: linux-snps-arc@lists.infradead.org Link: http://lkml.kernel.org/r/1471537703-16439-1-git-send-email-vgupta@synopsys.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/string.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools/include/linux') diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index b96879477311..f436d2420a18 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -8,7 +8,11 @@ void *memdup(const void *src, size_t len); int strtobool(const char *s, bool *res); -#ifdef __GLIBC__ +/* + * glibc based builds needs the extern while uClibc doesn't. + * However uClibc headers also define __GLIBC__ hence the hack below + */ +#if defined(__GLIBC__) && !defined(__UCLIBC__) extern size_t strlcpy(char *dest, const char *src, size_t size); #endif -- cgit v1.3-8-gc7d7