dwarf_wrappers.cxx - systemtap
Functions defined
Source code
#include "dwarf_wrappers.h"
#include "staptree.h"
#include "util.h"
#include <cstring>
#include <sstream>
#include <string>
#include <elfutils/libdwfl.h>
#include <dwarf.h>
using namespace std;
void dwfl_assert(const string& desc, int rc,
const string& file, int line)
{
if (rc == 0)
return;
string msg = _F("libdwfl failure (%s): ", desc.c_str());
if (rc < 0)
msg += (dwfl_errmsg (rc) ?: "?");
else
msg += std::strerror (rc);
throw semantic_error (file+":"+lex_cast(line), msg);
}
void dwarf_assert(const string& desc, int rc,
const string& file, int line)
{
if (rc == 0)
return;
string msg = _F("libdw failure (%s): ", desc.c_str());
if (rc < 0)
msg += dwarf_errmsg (rc);
else
msg += std::strerror (rc);
throw semantic_error (file+":"+lex_cast(line), msg);
}
#if !_ELFUTILS_PREREQ(0, 143)
const char *
dwarf_decl_file_integrate (Dwarf_Die *die)
{
Dwarf_Attribute attr_mem;
Dwarf_Sword idx = 0;
if (dwarf_formsdata (dwarf_attr_integrate (die, DW_AT_decl_file, &attr_mem),
&idx) != 0
|| idx == 0)
return NULL;
Dwarf_Die cudie;
Dwarf_Files *files = NULL;
if (dwarf_getsrcfiles (dwarf_diecu (die, &cudie, NULL, NULL),
&files, NULL) != 0)
return NULL;
return dwarf_filesrc(files, idx, NULL, NULL);
}
int
dwarf_decl_line_integrate (Dwarf_Die *die, int *linep)
{
Dwarf_Attribute attr_mem;
Dwarf_Sword line;
int res = dwarf_formsdata (dwarf_attr_integrate
(die, DW_AT_decl_line, &attr_mem),
&line);
if (res == 0)
*linep = line;
return res;
}
#endif
static bool
dwarf_type_name(Dwarf_Die *type_die, ostream& o)
{
bool done = true;
switch (dwarf_tag(type_die))
{
case DW_TAG_enumeration_type:
o << "enum ";
break;
case DW_TAG_structure_type:
o << "struct ";
break;
case DW_TAG_union_type:
o << "union ";
break;
case DW_TAG_class_type:
o << "class ";
break;
case DW_TAG_typedef:
case DW_TAG_base_type:
break;
case DW_TAG_reference_type:
case DW_TAG_rvalue_reference_type:
case DW_TAG_pointer_type:
case DW_TAG_array_type:
case DW_TAG_const_type:
case DW_TAG_volatile_type:
case DW_TAG_restrict_type:
done = false;
break;
default:
return false;
}
if (done)
{
o << (dwarf_diename(type_die) ?: "{...}");
return true;
}
Dwarf_Die subtype_die_mem, *subtype_die;
subtype_die = dwarf_attr_die(type_die, DW_AT_type, &subtype_die_mem);
if (subtype_die != NULL &&
dwarf_tag(type_die) == DW_TAG_pointer_type &&
dwarf_tag(subtype_die) == DW_TAG_structure_type &&
strcmp(dwarf_diename(subtype_die) ?: "", "__va_list_tag") == 0)
{
o << "va_list";
return true;
}
if (subtype_die == NULL ||
!dwarf_type_name(subtype_die, o))
o << "void";
switch (dwarf_tag(type_die))
{
case DW_TAG_reference_type:
o << "&";
break;
case DW_TAG_rvalue_reference_type:
o << "&&";
break;
case DW_TAG_pointer_type:
o << "*";
break;
case DW_TAG_array_type:
o << "[]";
break;
case DW_TAG_const_type:
if (subtype_die == NULL ||
(dwarf_tag(subtype_die) != DW_TAG_reference_type &&
dwarf_tag(subtype_die) != DW_TAG_rvalue_reference_type))
o << " const";
break;
case DW_TAG_volatile_type:
o << " volatile";
break;
case DW_TAG_restrict_type:
o << " restrict";
break;
default:
return false;
}
return true;
}
bool
dwarf_type_name(Dwarf_Die *type_die, string& type_name)
{
ostringstream o;
bool ret = dwarf_type_name(type_die, o);
type_name = o.str();
return ret;
}
string
dwarf_type_name(Dwarf_Die *type_die)
{
ostringstream o;
return dwarf_type_name(type_die, o) ? o.str() : "<unknown>";
}