Merge tag 'trace-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux...
[linux-2.6-block.git] / tools / perf / util / probe-finder.c
index 7d8c9973492850a3a66efbcf0a4a55f8c58037ba..025fc4491993caff17ae68812a6311e550375d0e 100644 (file)
@@ -280,7 +280,7 @@ static_var:
 
 static int convert_variable_type(Dwarf_Die *vr_die,
                                 struct probe_trace_arg *tvar,
-                                const char *cast)
+                                const char *cast, bool user_access)
 {
        struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
        Dwarf_Die type;
@@ -320,7 +320,8 @@ static int convert_variable_type(Dwarf_Die *vr_die,
        pr_debug("%s type is %s.\n",
                 dwarf_diename(vr_die), dwarf_diename(&type));
 
-       if (cast && strcmp(cast, "string") == 0) {      /* String type */
+       if (cast && (!strcmp(cast, "string") || !strcmp(cast, "ustring"))) {
+               /* String type */
                ret = dwarf_tag(&type);
                if (ret != DW_TAG_pointer_type &&
                    ret != DW_TAG_array_type) {
@@ -343,6 +344,7 @@ static int convert_variable_type(Dwarf_Die *vr_die,
                                pr_warning("Out of memory error\n");
                                return -ENOMEM;
                        }
+                       (*ref_ptr)->user_access = user_access;
                }
                if (!die_compare_name(&type, "char") &&
                    !die_compare_name(&type, "unsigned char")) {
@@ -397,7 +399,7 @@ formatted:
 static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
                                    struct perf_probe_arg_field *field,
                                    struct probe_trace_arg_ref **ref_ptr,
-                                   Dwarf_Die *die_mem)
+                                   Dwarf_Die *die_mem, bool user_access)
 {
        struct probe_trace_arg_ref *ref = *ref_ptr;
        Dwarf_Die type;
@@ -434,6 +436,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
                                *ref_ptr = ref;
                }
                ref->offset += dwarf_bytesize(&type) * field->index;
+               ref->user_access = user_access;
                goto next;
        } else if (tag == DW_TAG_pointer_type) {
                /* Check the pointer and dereference */
@@ -505,17 +508,18 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
                }
        }
        ref->offset += (long)offs;
+       ref->user_access = user_access;
 
        /* If this member is unnamed, we need to reuse this field */
        if (!dwarf_diename(die_mem))
                return convert_variable_fields(die_mem, varname, field,
-                                               &ref, die_mem);
+                                               &ref, die_mem, user_access);
 
 next:
        /* Converting next field */
        if (field->next)
                return convert_variable_fields(die_mem, field->name,
-                                       field->next, &ref, die_mem);
+                               field->next, &ref, die_mem, user_access);
        else
                return 0;
 }
@@ -541,11 +545,12 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
        else if (ret == 0 && pf->pvar->field) {
                ret = convert_variable_fields(vr_die, pf->pvar->var,
                                              pf->pvar->field, &pf->tvar->ref,
-                                             &die_mem);
+                                             &die_mem, pf->pvar->user_access);
                vr_die = &die_mem;
        }
        if (ret == 0)
-               ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type);
+               ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type,
+                                           pf->pvar->user_access);
        /* *expr will be cached in libdw. Don't free it. */
        return ret;
 }