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; }
void handle (Dwarf *dbg, Dwarf_Die *die, int n) { Dwarf_Die child; unsigned int tag; const char *str; char buf[30]; const char *name; Dwarf_Off off; Dwarf_Off cuoff; size_t cnt; Dwarf_Addr addr; int i; tag = dwarf_tag (die); if (tag != DW_TAG_invalid) { if (tag < ntagnames) str = tagnames[tag]; else { snprintf (buf, sizeof buf, "%#x", tag); str = buf; } } else str = "* NO TAG *"; name = dwarf_diename (die); if (name == 0) name = "* NO NAME *"; off = dwarf_dieoffset (die); cuoff = dwarf_cuoffset (die); printf ("%*s%s\n", n * 5, "", str); printf ("%*s Name : %s\n", n * 5, "", name); printf ("%*s Offset : %lld\n", n * 5, "", (long long int) off); printf ("%*s CU offset : %lld\n", n * 5, "", (long long int) cuoff); printf ("%*s Attrs :", n * 5, ""); for (cnt = 0; cnt < nattrs; ++cnt) if (dwarf_hasattr (die, attrs[cnt].code)) printf (" %s", attrs[cnt].name); puts (""); if (dwarf_hasattr (die, DW_AT_low_pc) && dwarf_lowpc (die, &addr) == 0) { Dwarf_Attribute attr; Dwarf_Addr addr2; printf ("%*s low PC : %#llx\n", n * 5, "", (unsigned long long int) addr); if (dwarf_attr (die, DW_AT_low_pc, &attr) == NULL || dwarf_formaddr (&attr, &addr2) != 0 || addr != addr2) puts ("************* DW_AT_low_pc verify failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_addr)) puts ("************* DW_AT_low_pc form failed ************"); else if (dwarf_whatform (&attr) != DW_FORM_addr) puts ("************* DW_AT_low_pc form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_low_pc) puts ("************* DW_AT_low_pc attr failed ************"); } if (dwarf_hasattr (die, DW_AT_high_pc) && dwarf_highpc (die, &addr) == 0) { Dwarf_Attribute attr; Dwarf_Addr addr2; printf ("%*s high PC : %#llx\n", n * 5, "", (unsigned long long int) addr); if (dwarf_attr (die, DW_AT_high_pc, &attr) == NULL || dwarf_formaddr (&attr, &addr2) != 0 || addr != addr2) puts ("************* DW_AT_high_pc verify failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_addr)) puts ("************* DW_AT_high_pc form failed ************"); else if (dwarf_whatform (&attr) != DW_FORM_addr) puts ("************* DW_AT_high_pc form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_high_pc) puts ("************* DW_AT_high_pc attr failed ************"); } if (dwarf_hasattr (die, DW_AT_byte_size) && (i = dwarf_bytesize (die)) != -1) { Dwarf_Attribute attr; Dwarf_Word u2; unsigned int u; printf ("%*s byte size : %d\n", n * 5, "", i); if (dwarf_attr (die, DW_AT_byte_size, &attr) == NULL || dwarf_formudata (&attr, &u2) != 0 || i != (int) u2) puts ("************* DW_AT_byte_size verify failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_data1) && ! dwarf_hasform (&attr, DW_FORM_data2) && ! dwarf_hasform (&attr, DW_FORM_data4) && ! dwarf_hasform (&attr, DW_FORM_data8) && ! dwarf_hasform (&attr, DW_FORM_sdata) && ! dwarf_hasform (&attr, DW_FORM_udata)) puts ("************* DW_AT_byte_size form failed ************"); else if ((u = dwarf_whatform (&attr)) == 0 || (u != DW_FORM_data1 && u != DW_FORM_data2 && u != DW_FORM_data4 && u != DW_FORM_data8 && u != DW_FORM_sdata && u != DW_FORM_udata)) puts ("************* DW_AT_byte_size form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_byte_size) puts ("************* DW_AT_byte_size attr failed ************"); } if (dwarf_hasattr (die, DW_AT_bit_size) && (i = dwarf_bitsize (die)) != -1) { Dwarf_Attribute attr; Dwarf_Word u2; unsigned int u; printf ("%*s bit size : %d\n", n * 5, "", i); if (dwarf_attr (die, DW_AT_bit_size, &attr) == NULL || dwarf_formudata (&attr, &u2) != 0 || i != (int) u2) puts ("************* DW_AT_bit_size test failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_data1) && ! dwarf_hasform (&attr, DW_FORM_data2) && ! dwarf_hasform (&attr, DW_FORM_data4) && ! dwarf_hasform (&attr, DW_FORM_data8) && ! dwarf_hasform (&attr, DW_FORM_sdata) && ! dwarf_hasform (&attr, DW_FORM_udata)) puts ("************* DW_AT_bit_size form failed ************"); else if ((u = dwarf_whatform (&attr)) == 0 || (u != DW_FORM_data1 && u != DW_FORM_data2 && u != DW_FORM_data4 && u != DW_FORM_data8 && u != DW_FORM_sdata && u != DW_FORM_udata)) puts ("************* DW_AT_bit_size form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_bit_size) puts ("************* DW_AT_bit_size attr failed ************"); } if (dwarf_hasattr (die, DW_AT_bit_offset) && (i = dwarf_bitoffset (die)) != -1) { Dwarf_Attribute attr; Dwarf_Word u2; unsigned int u; printf ("%*s bit offset: %d\n", n * 5, "", i); if (dwarf_attr (die, DW_AT_bit_offset, &attr) == NULL || dwarf_formudata (&attr, &u2) != 0 || i != (int) u2) puts ("************* DW_AT_bit_offset test failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_data1) && ! dwarf_hasform (&attr, DW_FORM_data2) && ! dwarf_hasform (&attr, DW_FORM_data4) && ! dwarf_hasform (&attr, DW_FORM_data8) && ! dwarf_hasform (&attr, DW_FORM_sdata) && ! dwarf_hasform (&attr, DW_FORM_udata)) puts ("************* DW_AT_bit_offset form failed ************"); else if ((u = dwarf_whatform (&attr)) == 0 || (u != DW_FORM_data1 && u != DW_FORM_data2 && u != DW_FORM_data4 && u != DW_FORM_data8 && u != DW_FORM_sdata && u != DW_FORM_udata)) puts ("************* DW_AT_bit_offset form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_bit_offset) puts ("************* DW_AT_bit_offset attr failed ************"); } if (dwarf_hasattr (die, DW_AT_language) && (i = dwarf_srclang (die)) != -1) { Dwarf_Attribute attr; Dwarf_Word u2; unsigned int u; printf ("%*s language : %d\n", n * 5, "", i); if (dwarf_attr (die, DW_AT_language, &attr) == NULL || dwarf_formudata (&attr, &u2) != 0 || i != (int) u2) puts ("************* DW_AT_language test failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_data1) && ! dwarf_hasform (&attr, DW_FORM_data2) && ! dwarf_hasform (&attr, DW_FORM_data4) && ! dwarf_hasform (&attr, DW_FORM_data8) && ! dwarf_hasform (&attr, DW_FORM_sdata) && ! dwarf_hasform (&attr, DW_FORM_udata)) puts ("************* DW_AT_language form failed ************"); else if ((u = dwarf_whatform (&attr)) == 0 || (u != DW_FORM_data1 && u != DW_FORM_data2 && u != DW_FORM_data4 && u != DW_FORM_data8 && u != DW_FORM_sdata && u != DW_FORM_udata)) puts ("************* DW_AT_language form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_language) puts ("************* DW_AT_language attr failed ************"); } if (dwarf_hasattr (die, DW_AT_ordering) && (i = dwarf_arrayorder (die)) != -1) { Dwarf_Attribute attr; Dwarf_Word u2; unsigned int u; printf ("%*s ordering : %d\n", n * 5, "", i); if (dwarf_attr (die, DW_AT_ordering, &attr) == NULL || dwarf_formudata (&attr, &u2) != 0 || i != (int) u2) puts ("************* DW_AT_ordering test failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_data1) && ! dwarf_hasform (&attr, DW_FORM_data2) && ! dwarf_hasform (&attr, DW_FORM_data4) && ! dwarf_hasform (&attr, DW_FORM_data8) && ! dwarf_hasform (&attr, DW_FORM_sdata) && ! dwarf_hasform (&attr, DW_FORM_udata)) puts ("************* DW_AT_ordering failed ************"); else if ((u = dwarf_whatform (&attr)) == 0 || (u != DW_FORM_data1 && u != DW_FORM_data2 && u != DW_FORM_data4 && u != DW_FORM_data8 && u != DW_FORM_sdata && u != DW_FORM_udata)) puts ("************* DW_AT_ordering form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_ordering) puts ("************* DW_AT_ordering attr failed ************"); } if (dwarf_hasattr (die, DW_AT_comp_dir)) { Dwarf_Attribute attr; if (dwarf_attr (die, DW_AT_comp_dir, &attr) == NULL || (name = dwarf_formstring (&attr)) == NULL) puts ("************* DW_AT_comp_dir attr failed ************"); else printf ("%*s directory : %s\n", n * 5, "", name); } if (dwarf_hasattr (die, DW_AT_producer)) { Dwarf_Attribute attr; if (dwarf_attr (die, DW_AT_producer, &attr) == NULL || (name = dwarf_formstring (&attr)) == NULL) puts ("************* DW_AT_comp_dir attr failed ************"); else printf ("%*s producer : %s\n", n * 5, "", name); } if (dwarf_haschildren (die) != 0 && dwarf_child (die, &child) == 0) handle (dbg, &child, n + 1); if (dwarf_siblingof (die, die) == 0) handle (dbg, die, n); }