lkml.org 
[lkml]   [2011]   [Feb]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH -perf/perf/core 4/4] perf/probe: Add bitfield member support
    Date
    Add bitfield member accessing support to probe arguments.

    Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
    Suggested-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Paul Mackerras <paulus@samba.org>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: linux-kernel@vger.kernel.org
    ---

    tools/perf/util/probe-finder.c | 95 +++++++++++++++++++++++++++++-----------
    1 files changed, 68 insertions(+), 27 deletions(-)

    diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
    index 69215bf..613e5fb 100644
    --- a/tools/perf/util/probe-finder.c
    +++ b/tools/perf/util/probe-finder.c
    @@ -33,6 +33,7 @@
    #include <ctype.h>
    #include <dwarf-regs.h>

    +#include <linux/bitops.h>
    #include "event.h"
    #include "debug.h"
    #include "util.h"
    @@ -333,13 +334,23 @@ static Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
    return vr_die;
    }

    -static bool die_is_signed_type(Dwarf_Die *tp_die)
    +static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
    + Dwarf_Word *result)
    {
    Dwarf_Attribute attr;
    +
    + if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
    + dwarf_formudata(&attr, result) != 0)
    + return -ENOENT;
    +
    + return 0;
    +}
    +
    +static bool die_is_signed_type(Dwarf_Die *tp_die)
    +{
    Dwarf_Word ret;

    - if (dwarf_attr(tp_die, DW_AT_encoding, &attr) == NULL ||
    - dwarf_formudata(&attr, &ret) != 0)
    + if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret))
    return false;

    return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
    @@ -348,11 +359,29 @@ static bool die_is_signed_type(Dwarf_Die *tp_die)

    static int die_get_byte_size(Dwarf_Die *tp_die)
    {
    - Dwarf_Attribute attr;
    Dwarf_Word ret;

    - if (dwarf_attr(tp_die, DW_AT_byte_size, &attr) == NULL ||
    - dwarf_formudata(&attr, &ret) != 0)
    + if (die_get_attr_udata(tp_die, DW_AT_byte_size, &ret))
    + return 0;
    +
    + return (int)ret;
    +}
    +
    +static int die_get_bit_size(Dwarf_Die *tp_die)
    +{
    + Dwarf_Word ret;
    +
    + if (die_get_attr_udata(tp_die, DW_AT_bit_size, &ret))
    + return 0;
    +
    + return (int)ret;
    +}
    +
    +static int die_get_bit_offset(Dwarf_Die *tp_die)
    +{
    + Dwarf_Word ret;
    +
    + if (die_get_attr_udata(tp_die, DW_AT_bit_offset, &ret))
    return 0;

    return (int)ret;
    @@ -827,6 +856,8 @@ static_var:
    return 0;
    }

    +#define BYTES_TO_BITS(nb) ((nb) * BITS_PER_LONG / sizeof(long))
    +
    static int convert_variable_type(Dwarf_Die *vr_die,
    struct probe_trace_arg *tvar,
    const char *cast)
    @@ -843,6 +874,14 @@ static int convert_variable_type(Dwarf_Die *vr_die,
    return (tvar->type == NULL) ? -ENOMEM : 0;
    }

    + if (die_get_bit_size(vr_die) != 0) {
    + /* This is a bitfield */
    + ret = snprintf(buf, 16, "b%d@%d/%lu", die_get_bit_size(vr_die),
    + die_get_bit_offset(vr_die),
    + BYTES_TO_BITS(die_get_byte_size(vr_die)));
    + goto formatted;
    + }
    +
    if (die_get_real_type(vr_die, &type) == NULL) {
    pr_warning("Failed to get a type information of %s.\n",
    dwarf_diename(vr_die));
    @@ -887,29 +926,31 @@ static int convert_variable_type(Dwarf_Die *vr_die,
    return (tvar->type == NULL) ? -ENOMEM : 0;
    }

    - ret = die_get_byte_size(&type) * 8;
    - if (ret) {
    - /* Check the bitwidth */
    - if (ret > MAX_BASIC_TYPE_BITS) {
    - pr_info("%s exceeds max-bitwidth."
    - " Cut down to %d bits.\n",
    - dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
    - ret = MAX_BASIC_TYPE_BITS;
    - }
    + ret = BYTES_TO_BITS(die_get_byte_size(&type));
    + if (!ret)
    + /* No size ... try to use default type */
    + return 0;

    - ret = snprintf(buf, 16, "%c%d",
    - die_is_signed_type(&type) ? 's' : 'u', ret);
    - if (ret < 0 || ret >= 16) {
    - if (ret >= 16)
    - ret = -E2BIG;
    - pr_warning("Failed to convert variable type: %s\n",
    - strerror(-ret));
    - return ret;
    - }
    - tvar->type = strdup(buf);
    - if (tvar->type == NULL)
    - return -ENOMEM;
    + /* Check the bitwidth */
    + if (ret > MAX_BASIC_TYPE_BITS) {
    + pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n",
    + dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
    + ret = MAX_BASIC_TYPE_BITS;
    + }
    + ret = snprintf(buf, 16, "%c%d",
    + die_is_signed_type(&type) ? 's' : 'u', ret);
    +
    +formatted:
    + if (ret < 0 || ret >= 16) {
    + if (ret >= 16)
    + ret = -E2BIG;
    + pr_warning("Failed to convert variable type: %s\n",
    + strerror(-ret));
    + return ret;
    }
    + tvar->type = strdup(buf);
    + if (tvar->type == NULL)
    + return -ENOMEM;
    return 0;
    }



    \
     
     \ /
      Last update: 2011-02-04 14:01    [W:0.029 / U:0.128 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site