static std::string get_type_by_signature()

in src/backward.h [2562:2621]


    static std::string get_type_by_signature(Dwarf_Debug dwarf, Dwarf_Die die)
    {
        Dwarf_Error error = DW_DLE_NE;

        Dwarf_Sig8 signature;
        Dwarf_Bool has_attr = 0;
        if (dwarf_hasattr(die, DW_AT_signature, &has_attr, &error) == DW_DLV_OK) {
            if (has_attr) {
                Dwarf_Attribute attr_mem;
                if (dwarf_attr(die, DW_AT_signature, &attr_mem, &error) == DW_DLV_OK) {
                    if (dwarf_formsig8(attr_mem, &signature, &error) != DW_DLV_OK) {
                        return std::string("<no type signature>");
                    }
                }
                dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
            }
        }

        Dwarf_Unsigned next_cu_header;
        Dwarf_Sig8 tu_signature;
        std::string result;
        bool found = false;

        while (dwarf_next_cu_header_d(dwarf, 0, 0, 0, 0, 0, 0, 0, &tu_signature, 0, &next_cu_header, 0, &error) ==
               DW_DLV_OK) {

            if (strncmp(signature.signature, tu_signature.signature, 8) == 0) {
                Dwarf_Die type_cu_die = 0;
                if (dwarf_siblingof_b(dwarf, 0, 0, &type_cu_die, &error) == DW_DLV_OK) {
                    Dwarf_Die child_die = 0;
                    if (dwarf_child(type_cu_die, &child_die, &error) == DW_DLV_OK) {
                        get_type(dwarf, child_die, result);
                        found = !result.empty();
                        dwarf_dealloc(dwarf, child_die, DW_DLA_DIE);
                    }
                    dwarf_dealloc(dwarf, type_cu_die, DW_DLA_DIE);
                }
            }
        }

        if (found) {
            while (dwarf_next_cu_header_d(dwarf, 0, 0, 0, 0, 0, 0, 0, 0, 0, &next_cu_header, 0, &error) == DW_DLV_OK) {
                // Reset the cu header state. Unfortunately, libdwarf's
                // next_cu_header API keeps its own iterator per Dwarf_Debug
                // that can't be reset. We need to keep fetching elements until
                // the end.
            }
        }
        else {
            // If we couldn't resolve the type just print out the signature
            std::ostringstream string_stream;
            string_stream << "<0x" << std::hex << std::setfill('0');
            for (int i = 0; i < 8; ++i) {
                string_stream << std::setw(2) << std::hex << (int)(unsigned char)(signature.signature[i]);
            }
            string_stream << ">";
            result = string_stream.str();
        }
        return result;
    }