Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ and changes to better use these tools in scripts.

For full details please take a look at the git changesets, repo available at:

http://git.kernel.org/?p=linux/kernel/git/acme/pahole.git
http://git.kernel.org/cgit/devel/pahole/pahole.git

- Arnaldo

Expand Down
5 changes: 3 additions & 2 deletions ctf_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "ctf.h"
#include "hash.h"
#include "elf_symtab.h"
#include <inttypes.h>

static int tag__check_id_drift(const struct tag *tag,
uint16_t core_id, uint16_t ctf_id)
Expand Down Expand Up @@ -290,7 +291,7 @@ int cu__encode_ctf(struct cu *cu, int verbose)
if (function == NULL) {
if (verbose)
fprintf(stderr,
"function %4d: %-20s %#Lx %5u NOT FOUND!\n",
"function %4d: %-20s %#" PRIx64 " %5u NOT FOUND!\n",
id, sym_name, addr,
elf_sym__size(&sym));
err = ctf__add_function(ctf, 0, 0, 0, &position);
Expand Down Expand Up @@ -333,7 +334,7 @@ int cu__encode_ctf(struct cu *cu, int verbose)
if (var == NULL) {
if (verbose)
fprintf(stderr,
"variable %4d: %-20s %#Lx %5u NOT FOUND!\n",
"variable %4d: %-20s %#" PRIx64 " %5u NOT FOUND!\n",
id, sym_name, addr,
elf_sym__size(&sym));
err = ctf__add_object(ctf, 0);
Expand Down
218 changes: 218 additions & 0 deletions dutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
#include <stddef.h>
#include <elf.h>
#include <gelf.h>
#include <asm/bitsperlong.h>
#include "rbtree.h"

#define BITS_PER_LONG __BITS_PER_LONG

#ifndef __unused
#define __unused __attribute__ ((unused))
#endif
Expand All @@ -32,6 +35,221 @@ static inline __attribute__((const)) bool is_power_of_2(unsigned long n)
return (n != 0 && ((n & (n - 1)) == 0));
}

/**
* fls - find last (most-significant) bit set
* @x: the word to search
*
* This is defined the same way as ffs.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
static __always_inline int fls(int x)
{
return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
}

/**
* fls64 - find last set bit in a 64-bit word
* @x: the word to search
*
* This is defined in a similar way as the libc and compiler builtin
* ffsll, but returns the position of the most significant set bit.
*
* fls64(value) returns 0 if value is 0 or the position of the last
* set bit if value is nonzero. The last (most significant) bit is
* at position 64.
*/
#if BITS_PER_LONG == 32
static __always_inline int fls64(uint64_t x)
{
uint32_t h = x >> 32;
if (h)
return fls(h) + 32;
return fls(x);
}
#elif BITS_PER_LONG == 64
/**
* __fls - find last (most-significant) set bit in a long word
* @word: the word to search
*
* Undefined if no set bit exists, so code should check against 0 first.
*/
static __always_inline unsigned long __fls(unsigned long word)
{
int num = BITS_PER_LONG - 1;

#if BITS_PER_LONG == 64
if (!(word & (~0ul << 32))) {
num -= 32;
word <<= 32;
}
#endif
if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
num -= 16;
word <<= 16;
}
if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
num -= 8;
word <<= 8;
}
if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
num -= 4;
word <<= 4;
}
if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
num -= 2;
word <<= 2;
}
if (!(word & (~0ul << (BITS_PER_LONG-1))))
num -= 1;
return num;
}

static __always_inline int fls64(uint64_t x)
{
if (x == 0)
return 0;
return __fls(x) + 1;
}
#else
#error BITS_PER_LONG not 32 or 64
#endif

static inline unsigned fls_long(unsigned long l)
{
if (sizeof(l) == 4)
return fls(l);
return fls64(l);
}

/*
* round up to nearest power of two
*/
static inline __attribute__((const))
unsigned long __roundup_pow_of_two(unsigned long n)
{
return 1UL << fls_long(n - 1);
}

/*
* non-constant log of base 2 calculators
* - the arch may override these in asm/bitops.h if they can be implemented
* more efficiently than using fls() and fls64()
* - the arch is not required to handle n==0 if implementing the fallback
*/
static inline __attribute__((const))
int __ilog2_u32(uint32_t n)
{
return fls(n) - 1;
}

static inline __attribute__((const))
int __ilog2_u64(uint64_t n)
{
return fls64(n) - 1;
}

/**
* ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
* @n - parameter
*
* constant-capable log of base 2 calculation
* - this can be used to initialise global variables from constant data, hence
* the massive ternary operator construction
*
* selects the appropriately-sized optimised version depending on sizeof(n)
*/
#define ilog2(n) \
( \
__builtin_constant_p(n) ? ( \
(n) < 1 ? ____ilog2_NaN() : \
(n) & (1ULL << 63) ? 63 : \
(n) & (1ULL << 62) ? 62 : \
(n) & (1ULL << 61) ? 61 : \
(n) & (1ULL << 60) ? 60 : \
(n) & (1ULL << 59) ? 59 : \
(n) & (1ULL << 58) ? 58 : \
(n) & (1ULL << 57) ? 57 : \
(n) & (1ULL << 56) ? 56 : \
(n) & (1ULL << 55) ? 55 : \
(n) & (1ULL << 54) ? 54 : \
(n) & (1ULL << 53) ? 53 : \
(n) & (1ULL << 52) ? 52 : \
(n) & (1ULL << 51) ? 51 : \
(n) & (1ULL << 50) ? 50 : \
(n) & (1ULL << 49) ? 49 : \
(n) & (1ULL << 48) ? 48 : \
(n) & (1ULL << 47) ? 47 : \
(n) & (1ULL << 46) ? 46 : \
(n) & (1ULL << 45) ? 45 : \
(n) & (1ULL << 44) ? 44 : \
(n) & (1ULL << 43) ? 43 : \
(n) & (1ULL << 42) ? 42 : \
(n) & (1ULL << 41) ? 41 : \
(n) & (1ULL << 40) ? 40 : \
(n) & (1ULL << 39) ? 39 : \
(n) & (1ULL << 38) ? 38 : \
(n) & (1ULL << 37) ? 37 : \
(n) & (1ULL << 36) ? 36 : \
(n) & (1ULL << 35) ? 35 : \
(n) & (1ULL << 34) ? 34 : \
(n) & (1ULL << 33) ? 33 : \
(n) & (1ULL << 32) ? 32 : \
(n) & (1ULL << 31) ? 31 : \
(n) & (1ULL << 30) ? 30 : \
(n) & (1ULL << 29) ? 29 : \
(n) & (1ULL << 28) ? 28 : \
(n) & (1ULL << 27) ? 27 : \
(n) & (1ULL << 26) ? 26 : \
(n) & (1ULL << 25) ? 25 : \
(n) & (1ULL << 24) ? 24 : \
(n) & (1ULL << 23) ? 23 : \
(n) & (1ULL << 22) ? 22 : \
(n) & (1ULL << 21) ? 21 : \
(n) & (1ULL << 20) ? 20 : \
(n) & (1ULL << 19) ? 19 : \
(n) & (1ULL << 18) ? 18 : \
(n) & (1ULL << 17) ? 17 : \
(n) & (1ULL << 16) ? 16 : \
(n) & (1ULL << 15) ? 15 : \
(n) & (1ULL << 14) ? 14 : \
(n) & (1ULL << 13) ? 13 : \
(n) & (1ULL << 12) ? 12 : \
(n) & (1ULL << 11) ? 11 : \
(n) & (1ULL << 10) ? 10 : \
(n) & (1ULL << 9) ? 9 : \
(n) & (1ULL << 8) ? 8 : \
(n) & (1ULL << 7) ? 7 : \
(n) & (1ULL << 6) ? 6 : \
(n) & (1ULL << 5) ? 5 : \
(n) & (1ULL << 4) ? 4 : \
(n) & (1ULL << 3) ? 3 : \
(n) & (1ULL << 2) ? 2 : \
(n) & (1ULL << 1) ? 1 : \
(n) & (1ULL << 0) ? 0 : \
____ilog2_NaN() \
) : \
(sizeof(n) <= 4) ? \
__ilog2_u32(n) : \
__ilog2_u64(n) \
)

/**
* roundup_pow_of_two - round the given value up to nearest power of two
* @n - parameter
*
* round the given value up to the nearest power of two
* - the result is undefined when n == 0
* - this can be used to initialise global variables from constant data
*/
#define roundup_pow_of_two(n) \
( \
__builtin_constant_p(n) ? ( \
(n == 1) ? 1 : \
(1UL << (ilog2((n) - 1) + 1)) \
) : \
__roundup_pow_of_two(n) \
)

/* We need define two variables, argp_program_version_hook and
argp_program_bug_address, in all programs. argp.h declares these
variables as non-const (which is correct in general). But we can
Expand Down
2 changes: 2 additions & 0 deletions dwarf_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ static Dwarf_Off attr_offset(Dwarf_Die *die, const uint32_t name)
switch (dwarf_whatform(&attr)) {
case DW_FORM_data1:
case DW_FORM_data2:
case DW_FORM_data4:
case DW_FORM_data8:
case DW_FORM_sdata:
case DW_FORM_udata: {
Dwarf_Word value;
Expand Down
29 changes: 19 additions & 10 deletions dwarves_fprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>

#include "config.h"
#include "dwarves.h"
Expand Down Expand Up @@ -366,7 +367,8 @@ static const char *__tag__name(const struct tag *tag, const struct cu *cu,
const struct conf_fprintf *conf);

static const char *tag__ptr_name(const struct tag *tag, const struct cu *cu,
char *bf, size_t len, const char *ptr_suffix)
char *bf, size_t len, const char *ptr_suffix,
const struct conf_fprintf *conf)
{
if (tag->type == 0) /* No type == void */
snprintf(bf, len, "void %s", ptr_suffix);
Expand All @@ -381,7 +383,7 @@ static const char *tag__ptr_name(const struct tag *tag, const struct cu *cu,

snprintf(bf, len, "%s %s",
__tag__name(type, cu,
tmpbf, sizeof(tmpbf), NULL),
tmpbf, sizeof(tmpbf), conf),
ptr_suffix);
}
}
Expand Down Expand Up @@ -415,9 +417,9 @@ static const char *__tag__name(const struct tag *tag, const struct cu *cu,
strncpy(bf, function__name(tag__function(tag), cu), len);
break;
case DW_TAG_pointer_type:
return tag__ptr_name(tag, cu, bf, len, "*");
return tag__ptr_name(tag, cu, bf, len, "*", conf);
case DW_TAG_reference_type:
return tag__ptr_name(tag, cu, bf, len, "&");
return tag__ptr_name(tag, cu, bf, len, "&", conf);
case DW_TAG_ptr_to_member_type: {
char suffix[512];
uint16_t id = tag__ptr_to_member_type(tag)->containing_type;
Expand All @@ -433,7 +435,7 @@ static const char *__tag__name(const struct tag *tag, const struct cu *cu,
snprintf(suffix + l, sizeof(suffix) - l, "::*");
}

return tag__ptr_name(tag, cu, bf, len, suffix);
return tag__ptr_name(tag, cu, bf, len, suffix, conf);
}
case DW_TAG_volatile_type:
case DW_TAG_const_type:
Expand Down Expand Up @@ -725,7 +727,7 @@ static size_t struct_member__fprintf(struct class_member *member,

if (member->is_static) {
if (member->const_value != 0)
printed += fprintf(fp, " = %lld;", member->const_value);
printed += fprintf(fp, " = %" PRIu64 ";", member->const_value);
} else if (member->bitfield_size != 0) {
printed += fprintf(fp, ":%u;", member->bitfield_size);
} else {
Expand Down Expand Up @@ -1386,10 +1388,17 @@ size_t class__fprintf(struct class *class, const struct cu *cu,
++printed;

/* XXX for now just skip these */
if (tag_pos->tag == DW_TAG_inheritance &&
pos->virtuality == DW_VIRTUALITY_virtual)
if (tag_pos->tag == DW_TAG_inheritance)
continue;

#if 0
/*
* This one was being skipped but caused problems with:
* http://article.gmane.org/gmane.comp.debugging.dwarves/185
* http://www.spinics.net/lists/dwarves/msg00119.html
*/
if (pos->virtuality == DW_VIRTUALITY_virtual)
continue;
#endif
/*
* Check if we have to adjust size because bitfields were
* combined with previous fields.
Expand Down Expand Up @@ -1459,7 +1468,7 @@ size_t class__fprintf(struct class *class, const struct cu *cu,
if (!cconf.emit_stats)
goto out;

printed += fprintf(fp, "\n%.*s/* size: %zd, cachelines: %zd, members: %u",
printed += fprintf(fp, "\n%.*s/* size: %d, cachelines: %zd, members: %u",
cconf.indent, tabs,
class__size(class),
tag__nr_cachelines(class__tag(class), cu),
Expand Down
Loading