Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
[Linux][GDB-JIT] Add simple C++ mangling of method names in GDBJIT DW…
Browse files Browse the repository at this point in the history
…ARF (#8638)

* Add simple C++ mangling of method names in GDBJIT DWARF

Example:
    Namespace1.Class1.Method -> void Namespace1_Class1::Method()

* Do not convert a name during mangling if target buffer is NULL
  • Loading branch information
ayuckhulk authored and janvorli committed Dec 14, 2016
1 parent b038f90 commit f25bff4
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 3 deletions.
83 changes: 80 additions & 3 deletions src/vm/gdbjit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ const unsigned char AbbrevTable[] = {
DW_AT_type, DW_FORM_ref4, 0, 0,

4, DW_TAG_subprogram, DW_CHILDREN_yes,
DW_AT_name, DW_FORM_strp, DW_AT_decl_file, DW_FORM_data1, DW_AT_decl_line, DW_FORM_data1,
DW_AT_name, DW_FORM_strp, DW_AT_linkage_name, DW_FORM_strp, DW_AT_decl_file, DW_FORM_data1, DW_AT_decl_line, DW_FORM_data1,
DW_AT_type, DW_FORM_ref4, DW_AT_external, DW_FORM_flag_present,
DW_AT_low_pc, DW_FORM_addr, DW_AT_high_pc,
#if defined(_TARGET_AMD64_)
Expand Down Expand Up @@ -719,7 +719,7 @@ const unsigned char AbbrevTable[] = {
DW_AT_upper_bound, DW_FORM_exprloc, 0, 0,

12, DW_TAG_subprogram, DW_CHILDREN_yes,
DW_AT_name, DW_FORM_strp, DW_AT_decl_file, DW_FORM_data1, DW_AT_decl_line, DW_FORM_data1,
DW_AT_name, DW_FORM_strp, DW_AT_linkage_name, DW_FORM_strp, DW_AT_decl_file, DW_FORM_data1, DW_AT_decl_line, DW_FORM_data1,
DW_AT_type, DW_FORM_ref4, DW_AT_external, DW_FORM_flag_present,
DW_AT_low_pc, DW_FORM_addr, DW_AT_high_pc,
#if defined(_TARGET_AMD64_)
Expand Down Expand Up @@ -771,6 +771,7 @@ struct __attribute__((packed)) DebugInfoSub
{
uint8_t m_sub_abbrev;
uint32_t m_sub_name;
uint32_t m_linkage_name;
uint8_t m_file, m_line;
uint32_t m_sub_type;
#if defined(_TARGET_AMD64_)
Expand Down Expand Up @@ -1029,6 +1030,79 @@ void TypeMember::DumpStaticDebugInfo(char* ptr, int& offset)
offset += ptrSize + 2;
}

void FunctionMember::MangleName(char *buf, int &buf_offset, const char *name)
{
int name_length = strlen(name);

char tmp[20];
int tmp_len = sprintf_s(tmp, _countof(tmp), "%i", name_length);
if (tmp_len <= 0)
return;

if (buf)
strncpy(buf + buf_offset, tmp, tmp_len);
buf_offset += tmp_len;

if (buf)
{
for (int i = 0; i < name_length; i++)
{
char c = name[i];
bool valid = (c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9');
*(buf + buf_offset + i) = valid ? c : '_';
}
}
buf_offset += name_length;
}

void FunctionMember::DumpMangledNamespaceAndMethod(char *buf, int &offset, const char *nspace, const char *mname)
{
static const char *begin_mangled = "_ZN";
static const char *end_mangled = "Ev";
static const int begin_mangled_len = strlen(begin_mangled);
static const int end_mangled_len = strlen(end_mangled);

if (buf)
strncpy(buf + offset, begin_mangled, begin_mangled_len);
offset += begin_mangled_len;

MangleName(buf, offset, nspace);
MangleName(buf, offset, mname);

if (buf)
strncpy(buf + offset, end_mangled, end_mangled_len);
offset += end_mangled_len;

if (buf)
buf[offset] = '\0';
++offset;
}

void FunctionMember::DumpLinkageName(char* ptr, int& offset)
{
SString namespaceOrClassName;
SString methodName;

md->GetMethodInfoNoSig(namespaceOrClassName, methodName);
SString utf8namespaceOrClassName;
SString utf8methodName;
namespaceOrClassName.ConvertToUTF8(utf8namespaceOrClassName);
methodName.ConvertToUTF8(utf8methodName);

const char *nspace = utf8namespaceOrClassName.GetUTF8NoConvert();
const char *mname = utf8methodName.GetUTF8NoConvert();

if (!nspace || !mname)
{
m_linkage_name_offset = 0;
return;
}

m_linkage_name_offset = offset;
DumpMangledNamespaceAndMethod(ptr, offset, nspace, mname);
}

void FunctionMember::DumpStrings(char* ptr, int& offset)
{
Expand All @@ -1037,7 +1111,9 @@ void FunctionMember::DumpStrings(char* ptr, int& offset)
for (int i = 0; i < m_num_vars; ++i)
{
vars[i].DumpStrings(ptr, offset);
}
}

DumpLinkageName(ptr, offset);
}

void FunctionMember::DumpDebugInfo(char* ptr, int& offset)
Expand All @@ -1048,6 +1124,7 @@ void FunctionMember::DumpDebugInfo(char* ptr, int& offset)

subEntry.m_sub_abbrev = 4;
subEntry.m_sub_name = m_member_name_offset;
subEntry.m_linkage_name = m_linkage_name_offset;
subEntry.m_file = m_file;
subEntry.m_line = m_line;
subEntry.m_sub_type = m_member_type->m_type_offset;
Expand Down
5 changes: 5 additions & 0 deletions src/vm/gdbjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ class FunctionMember: public TypeMember
m_num_vars(num_args + num_locals),
m_entry_offset(0),
vars(new VarDebugInfo[m_num_vars]),
m_linkage_name_offset(0),
dumped(false)
{
m_sub_loc[0] = 1;
Expand Down Expand Up @@ -459,8 +460,12 @@ class FunctionMember: public TypeMember
uint16_t m_num_vars;
int m_entry_offset;
VarDebugInfo* vars;
int m_linkage_name_offset;
private:
int GetArgsAndLocalsLen();
void MangleName(char *buf, int &buf_offset, const char *name);
void DumpMangledNamespaceAndMethod(char *buf, int &offset, const char *nspace, const char *mname);
void DumpLinkageName(char* ptr, int& offset);
BOOL dumped;
};
#endif // #ifndef __GDBJIT_H__

0 comments on commit f25bff4

Please sign in to comment.