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;
}