Move some commented out type dwarf tree walking code to the end of the file

This commit is contained in:
Jeremy 2023-09-17 00:52:31 -04:00
parent 5e4e842704
commit e47cb7147d
No known key found for this signature in database
GPG Key ID: 19AA8270105E8EB4

View File

@ -507,246 +507,6 @@ namespace libdwarf {
return continue_traversal;
}
/*die_object get_type_die(Dwarf_Debug dbg, const die_object& die) {
Dwarf_Off type_offset;
Dwarf_Bool is_info;
int ret = dwarf_dietype_offset(die.get(), &type_offset, &is_info, nullptr);
if(ret == DW_DLV_OK) {
Dwarf_Die type_die;
ret = dwarf_offdie_b(
dbg,
type_offset,
is_info,
&type_die,
nullptr
);
if(ret == DW_DLV_OK) {
return die_object(dbg, type_die);
} else {
fprintf(stderr, "Error\n");
exit(1);
}
} else {
fprintf(stderr, "no type offset??\n");
}
return die_object(dbg, nullptr);
}
bool has_type(Dwarf_Debug dbg, const die_object& die) {
Dwarf_Attribute attr;
int ret = dwarf_attr(die.get(), DW_AT_type, &attr, nullptr);
if(ret == DW_DLV_NO_ENTRY) {
return false;
} else if(ret == DW_DLV_OK) {
dwarf_dealloc_attribute(attr);
return true;
} else {
fprintf(stderr, "Error\n");
exit(1);
}
}
struct type_result {
std::string base;
std::string extent;
std::string get_type() {
return base + extent;
}
};
// TODO: ::*, namespace lookup, arrays
// DW_TAG_namespace
const char* tag_to_keyword(Dwarf_Half tag) {
switch(tag) {
case DW_TAG_atomic_type:
return "_Atomic";
case DW_TAG_const_type:
return "const";
case DW_TAG_volatile_type:
return "volatile";
case DW_TAG_restrict_type:
return "restrict";
default:
{
const char* tag_name = nullptr;
dwarf_get_TAG_name(tag, &tag_name);
fprintf(stderr, "tag_to_keyword unknown tag %s\n", tag_name);
exit(1);
}
}
}
const char* tag_to_ptr_ref(Dwarf_Half tag) {
switch(tag) {
case DW_TAG_pointer_type:
return "*";
case DW_TAG_ptr_to_member_type:
return "::*"; // TODO
case DW_TAG_reference_type:
return "&";
case DW_TAG_rvalue_reference_type:
return "&&";
default:
{
const char* tag_name = nullptr;
dwarf_get_TAG_name(tag, &tag_name);
fprintf(stderr, "tag_to_ptr_ref unknown tag %s\n", tag_name);
exit(1);
}
}
}
std::string resolve_type(Dwarf_Debug dbg, const die_object& die, std::string build = "");
std::string get_array_extents(Dwarf_Debug dbg, const die_object& die) {
CPPTRACE_VERIFY(die.get_tag() == DW_TAG_array_type);
std::string extents = "";
walk_die_list(dbg, die.get_child(), [&extents](Dwarf_Debug dbg, const die_object& subrange) {
if(subrange.get_tag() == DW_TAG_subrange_type) {
Dwarf_Attribute attr = 0;
int res = 0;
res = dwarf_attr(subrange.get(), DW_AT_upper_bound, &attr, nullptr);
if(res != DW_DLV_OK) {
fprintf(stderr, "Error\n");
return;
}
Dwarf_Half form;
res = dwarf_whatform(attr, &form, nullptr);
if(res != DW_DLV_OK) {
fprintf(stderr, "Error\n");
return;
}
//fprintf(stderr, "form: %d\n", form);
Dwarf_Unsigned val;
res = dwarf_formudata(attr, &val, nullptr);
if(res != DW_DLV_OK) {
fprintf(stderr, "Error\n");
return;
}
extents += "[" + std::to_string(val + 1) + "]";
dwarf_dealloc_attribute(attr);
} else {
fprintf(stderr, "unknown tag %s\n", subrange.get_tag_name());
}
});
return extents;
}
std::string get_parameters(Dwarf_Debug dbg, const die_object& die) {
CPPTRACE_VERIFY(die.get_tag() == DW_TAG_subroutine_type);
std::vector<std::string> params;
walk_die_list(dbg, die.get_child(), [&params](Dwarf_Debug dbg, const die_object& die) {
if(die.get_tag() == DW_TAG_formal_parameter) {
// TODO: Ignore DW_AT_artificial
params.push_back(resolve_type(dbg, get_type_die(dbg, die)));
}
});
return "(" + join(params, ", ") + ")";
}
std::string resolve_type(Dwarf_Debug dbg, const die_object& die, std::string build) {
switch(auto tag = die.get_tag()) {
case DW_TAG_base_type:
case DW_TAG_class_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_enumeration_type:
return die.get_name() + build;
case DW_TAG_typedef:
return resolve_type(dbg, get_type_die(dbg, die));
//case DW_TAG_subroutine_type:
// {
// // If there's no DW_AT_type then it's a void
// std::vector<std::string> params;
// // TODO: Code duplication with retrieve_symbol_for_subprogram?
// walk_die_list(dbg, die.get_child(), [&params] (Dwarf_Debug dbg, const die_object& die) {
// if(die.get_tag() == DW_TAG_formal_parameter) {
// // TODO: Ignore DW_AT_artificial
// params.push_back(resolve_type(dbg, get_type_die(dbg, die)));
// }
// });
// if(!has_type(dbg, die)) {
// return "void" + (build.empty() ? "" : "(" + build + ")") + "(" + join(params, ", ") + ")";
// } else {
// // resolving return type, building on build
// return resolve_type(
// dbg, get_type_die(dbg, die),
// (build.empty() ? "" : "(" + build + ")")
// + "("
// + join(params, ", ")
// + ")"
// );
// }
// }
//case DW_TAG_array_type:
// return resolve_type(dbg, get_type_die(dbg, die), (build.empty() ? "" : "(" + build + ")") + "[" + "x" + "]");
case DW_TAG_pointer_type:
case DW_TAG_reference_type:
case DW_TAG_rvalue_reference_type:
case DW_TAG_ptr_to_member_type:
{
const auto child = get_type_die(dbg, die); // AST child, rather than dwarf child
const auto child_tag = child.get_tag();
switch(child_tag) {
case DW_TAG_subroutine_type:
if(!has_type(dbg, child)) {
return "void(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_parameters(dbg, child);
} else {
return resolve_type(
dbg,
get_type_die(dbg, child),
"(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_parameters(dbg, child)
);
}
case DW_TAG_array_type:
return resolve_type(
dbg,
get_type_die(dbg, child),
"(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_array_extents(dbg, child)
);
default:
if(build.empty()) {
return resolve_type(dbg, get_type_die(dbg, die), tag_to_ptr_ref(tag));
} else {
return resolve_type(
dbg,
get_type_die(dbg, die),
std::string(tag_to_ptr_ref(tag)) + " " + build
);
}
}
}
case DW_TAG_const_type:
case DW_TAG_atomic_type:
case DW_TAG_volatile_type:
case DW_TAG_restrict_type:
{
const auto child = get_type_die(dbg, die); // AST child, rather than dwarf child
const auto child_tag = child.get_tag();
switch(child_tag) {
case DW_TAG_base_type:
case DW_TAG_class_type:
case DW_TAG_typedef:
return std::string(tag_to_keyword(tag))
+ " "
+ resolve_type(dbg, get_type_die(dbg, die), build);
default:
return resolve_type(
dbg,
get_type_die(dbg, die),
std::string(tag_to_keyword(tag)) + " " + build
);
}
}
default:
{
fprintf(stderr, "unknown tag %s\n", die.get_tag_name());
exit(1);
}
}
return {"<unknown>", "<unknown>"};
}*/
bool is_mangled_name(const std::string& name) {
return name.find("_Z") || name.find("?h@@");
}
@ -1083,6 +843,248 @@ namespace libdwarf {
}
return trace;
}
// Currently commented out. Need to decide if this is worth it. The mangled name is easier and maybe more
// trustworthy. This is a lot of effort for something that would only be relevant for extern "C" methods.
/*die_object get_type_die(Dwarf_Debug dbg, const die_object& die) {
Dwarf_Off type_offset;
Dwarf_Bool is_info;
int ret = dwarf_dietype_offset(die.get(), &type_offset, &is_info, nullptr);
if(ret == DW_DLV_OK) {
Dwarf_Die type_die;
ret = dwarf_offdie_b(
dbg,
type_offset,
is_info,
&type_die,
nullptr
);
if(ret == DW_DLV_OK) {
return die_object(dbg, type_die);
} else {
fprintf(stderr, "Error\n");
exit(1);
}
} else {
fprintf(stderr, "no type offset??\n");
}
return die_object(dbg, nullptr);
}
bool has_type(Dwarf_Debug dbg, const die_object& die) {
Dwarf_Attribute attr;
int ret = dwarf_attr(die.get(), DW_AT_type, &attr, nullptr);
if(ret == DW_DLV_NO_ENTRY) {
return false;
} else if(ret == DW_DLV_OK) {
dwarf_dealloc_attribute(attr);
return true;
} else {
fprintf(stderr, "Error\n");
exit(1);
}
}
struct type_result {
std::string base;
std::string extent;
std::string get_type() {
return base + extent;
}
};
// TODO: ::*, namespace lookup, arrays
// DW_TAG_namespace
const char* tag_to_keyword(Dwarf_Half tag) {
switch(tag) {
case DW_TAG_atomic_type:
return "_Atomic";
case DW_TAG_const_type:
return "const";
case DW_TAG_volatile_type:
return "volatile";
case DW_TAG_restrict_type:
return "restrict";
default:
{
const char* tag_name = nullptr;
dwarf_get_TAG_name(tag, &tag_name);
fprintf(stderr, "tag_to_keyword unknown tag %s\n", tag_name);
exit(1);
}
}
}
const char* tag_to_ptr_ref(Dwarf_Half tag) {
switch(tag) {
case DW_TAG_pointer_type:
return "*";
case DW_TAG_ptr_to_member_type:
return "::*"; // TODO
case DW_TAG_reference_type:
return "&";
case DW_TAG_rvalue_reference_type:
return "&&";
default:
{
const char* tag_name = nullptr;
dwarf_get_TAG_name(tag, &tag_name);
fprintf(stderr, "tag_to_ptr_ref unknown tag %s\n", tag_name);
exit(1);
}
}
}
std::string resolve_type(Dwarf_Debug dbg, const die_object& die, std::string build = "");
std::string get_array_extents(Dwarf_Debug dbg, const die_object& die) {
CPPTRACE_VERIFY(die.get_tag() == DW_TAG_array_type);
std::string extents = "";
walk_die_list(dbg, die.get_child(), [&extents](Dwarf_Debug dbg, const die_object& subrange) {
if(subrange.get_tag() == DW_TAG_subrange_type) {
Dwarf_Attribute attr = 0;
int res = 0;
res = dwarf_attr(subrange.get(), DW_AT_upper_bound, &attr, nullptr);
if(res != DW_DLV_OK) {
fprintf(stderr, "Error\n");
return;
}
Dwarf_Half form;
res = dwarf_whatform(attr, &form, nullptr);
if(res != DW_DLV_OK) {
fprintf(stderr, "Error\n");
return;
}
//fprintf(stderr, "form: %d\n", form);
Dwarf_Unsigned val;
res = dwarf_formudata(attr, &val, nullptr);
if(res != DW_DLV_OK) {
fprintf(stderr, "Error\n");
return;
}
extents += "[" + std::to_string(val + 1) + "]";
dwarf_dealloc_attribute(attr);
} else {
fprintf(stderr, "unknown tag %s\n", subrange.get_tag_name());
}
});
return extents;
}
std::string get_parameters(Dwarf_Debug dbg, const die_object& die) {
CPPTRACE_VERIFY(die.get_tag() == DW_TAG_subroutine_type);
std::vector<std::string> params;
walk_die_list(dbg, die.get_child(), [&params](Dwarf_Debug dbg, const die_object& die) {
if(die.get_tag() == DW_TAG_formal_parameter) {
// TODO: Ignore DW_AT_artificial
params.push_back(resolve_type(dbg, get_type_die(dbg, die)));
}
});
return "(" + join(params, ", ") + ")";
}
std::string resolve_type(Dwarf_Debug dbg, const die_object& die, std::string build) {
switch(auto tag = die.get_tag()) {
case DW_TAG_base_type:
case DW_TAG_class_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_enumeration_type:
return die.get_name() + build;
case DW_TAG_typedef:
return resolve_type(dbg, get_type_die(dbg, die));
//case DW_TAG_subroutine_type:
// {
// // If there's no DW_AT_type then it's a void
// std::vector<std::string> params;
// // TODO: Code duplication with retrieve_symbol_for_subprogram?
// walk_die_list(dbg, die.get_child(), [&params] (Dwarf_Debug dbg, const die_object& die) {
// if(die.get_tag() == DW_TAG_formal_parameter) {
// // TODO: Ignore DW_AT_artificial
// params.push_back(resolve_type(dbg, get_type_die(dbg, die)));
// }
// });
// if(!has_type(dbg, die)) {
// return "void" + (build.empty() ? "" : "(" + build + ")") + "(" + join(params, ", ") + ")";
// } else {
// // resolving return type, building on build
// return resolve_type(
// dbg, get_type_die(dbg, die),
// (build.empty() ? "" : "(" + build + ")")
// + "("
// + join(params, ", ")
// + ")"
// );
// }
// }
//case DW_TAG_array_type:
// return resolve_type(dbg, get_type_die(dbg, die), (build.empty() ? "" : "(" + build + ")") + "[" + "x" + "]");
case DW_TAG_pointer_type:
case DW_TAG_reference_type:
case DW_TAG_rvalue_reference_type:
case DW_TAG_ptr_to_member_type:
{
const auto child = get_type_die(dbg, die); // AST child, rather than dwarf child
const auto child_tag = child.get_tag();
switch(child_tag) {
case DW_TAG_subroutine_type:
if(!has_type(dbg, child)) {
return "void(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_parameters(dbg, child);
} else {
return resolve_type(
dbg,
get_type_die(dbg, child),
"(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_parameters(dbg, child)
);
}
case DW_TAG_array_type:
return resolve_type(
dbg,
get_type_die(dbg, child),
"(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_array_extents(dbg, child)
);
default:
if(build.empty()) {
return resolve_type(dbg, get_type_die(dbg, die), tag_to_ptr_ref(tag));
} else {
return resolve_type(
dbg,
get_type_die(dbg, die),
std::string(tag_to_ptr_ref(tag)) + " " + build
);
}
}
}
case DW_TAG_const_type:
case DW_TAG_atomic_type:
case DW_TAG_volatile_type:
case DW_TAG_restrict_type:
{
const auto child = get_type_die(dbg, die); // AST child, rather than dwarf child
const auto child_tag = child.get_tag();
switch(child_tag) {
case DW_TAG_base_type:
case DW_TAG_class_type:
case DW_TAG_typedef:
return std::string(tag_to_keyword(tag))
+ " "
+ resolve_type(dbg, get_type_die(dbg, die), build);
default:
return resolve_type(
dbg,
get_type_die(dbg, die),
std::string(tag_to_keyword(tag)) + " " + build
);
}
}
default:
{
fprintf(stderr, "unknown tag %s\n", die.get_tag_name());
exit(1);
}
}
return {"<unknown>", "<unknown>"};
}*/
}
}
}