static int convert_variable_type(Dwarf_Die *vr_die, struct kprobe_trace_arg *targ) { Dwarf_Die type; char buf[16]; int ret; if (die_get_real_type(vr_die, &type) == NULL) { pr_warning("Failed to get a type information of %s.\n", dwarf_diename(vr_die)); return -ENOENT; } 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 = 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; } targ->type = strdup(buf); if (targ->type == NULL) return -ENOMEM; } return 0; }
static int convert_variable_type(Dwarf_Die *vr_die, struct probe_trace_arg *tvar, const char *cast) { struct probe_trace_arg_ref **ref_ptr = &tvar->ref; Dwarf_Die type; char buf[16]; int bsize, boffs, total; int ret; if (cast && strcmp(cast, "string") != 0) { tvar->type = strdup(cast); return (tvar->type == NULL) ? -ENOMEM : 0; } bsize = dwarf_bitsize(vr_die); if (bsize > 0) { boffs = dwarf_bitoffset(vr_die); total = dwarf_bytesize(vr_die); if (boffs < 0 || total < 0) return -ENOENT; ret = snprintf(buf, 16, "b%d@%d/%zd", bsize, boffs, BYTES_TO_BITS(total)); 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)); return -ENOENT; } pr_debug("%s type is %s.\n", dwarf_diename(vr_die), dwarf_diename(&type)); if (cast && strcmp(cast, "string") == 0) { ret = dwarf_tag(&type); if (ret != DW_TAG_pointer_type && ret != DW_TAG_array_type) { pr_warning("Failed to cast into string: " "%s(%s) is not a pointer nor array.\n", dwarf_diename(vr_die), dwarf_diename(&type)); return -EINVAL; } if (ret == DW_TAG_pointer_type) { if (die_get_real_type(&type, &type) == NULL) { pr_warning("Failed to get a type" " information.\n"); return -ENOENT; } while (*ref_ptr) ref_ptr = &(*ref_ptr)->next; *ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref)); if (*ref_ptr == NULL) { pr_warning("Out of memory error\n"); return -ENOMEM; } } if (!die_compare_name(&type, "char") && !die_compare_name(&type, "unsigned char")) { pr_warning("Failed to cast into string: " "%s is not (unsigned) char *.\n", dwarf_diename(vr_die)); return -EINVAL; } tvar->type = strdup(cast); return (tvar->type == NULL) ? -ENOMEM : 0; } ret = dwarf_bytesize(&type); if (ret <= 0) return 0; ret = BYTES_TO_BITS(ret); 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; }
static int convert_variable_type(Dwarf_Die *vr_die, struct probe_trace_arg *tvar, const char *cast) { struct probe_trace_arg_ref **ref_ptr = &tvar->ref; Dwarf_Die type; char buf[16]; int ret; /* TODO: check all types */ if (cast && strcmp(cast, "string") != 0) { /* Non string type is OK */ tvar->type = strdup(cast); 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/%zd", 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)); return -ENOENT; } pr_debug("%s type is %s.\n", dwarf_diename(vr_die), dwarf_diename(&type)); if (cast && strcmp(cast, "string") == 0) { /* String type */ ret = dwarf_tag(&type); if (ret != DW_TAG_pointer_type && ret != DW_TAG_array_type) { pr_warning("Failed to cast into string: " "%s(%s) is not a pointer nor array.\n", dwarf_diename(vr_die), dwarf_diename(&type)); return -EINVAL; } if (ret == DW_TAG_pointer_type) { if (die_get_real_type(&type, &type) == NULL) { pr_warning("Failed to get a type" " information.\n"); return -ENOENT; } while (*ref_ptr) ref_ptr = &(*ref_ptr)->next; /* Add new reference with offset +0 */ *ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref)); if (*ref_ptr == NULL) { pr_warning("Out of memory error\n"); return -ENOMEM; } } if (!die_compare_name(&type, "char") && !die_compare_name(&type, "unsigned char")) { pr_warning("Failed to cast into string: " "%s is not (unsigned) char *.\n", dwarf_diename(vr_die)); return -EINVAL; } tvar->type = strdup(cast); return (tvar->type == NULL) ? -ENOMEM : 0; } ret = BYTES_TO_BITS(die_get_byte_size(&type)); if (!ret) /* No size ... try to use default type */ return 0; /* 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; }