-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Add support for parsing type unit entries in .debug_names. #72952
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Test that we can use .debug_names to lookup a type that is only referenced | ||
// from within a type unit. In the code below the type named "stype" is only | ||
// referenced within the type unit itself and when we enable .debug_names, we | ||
// expect the have an entry for this and to be able to find this type when | ||
// we do a lookup. | ||
|
||
// REQUIRES: lld | ||
|
||
// RUN: %clang %s -target x86_64-pc-linux -gdwarf-5 -fdebug-types-section \ | ||
// RUN: -gpubnames -fno-limit-debug-info -c -o %t.o | ||
// RUN: ld.lld %t.o -o %t | ||
// RUN: %lldb %t -o "type lookup stype" -b | FileCheck %s --check-prefix=BASE | ||
// RUN: %lldb %t -o "type lookup bar::stype" -b | FileCheck %s --check-prefix=PART | ||
// RUN: %lldb %t -o "type lookup foo::bar::stype" -b | FileCheck %s --check-prefix=FULL | ||
|
||
// BASE: (lldb) type lookup stype | ||
// BASE-NEXT: int | ||
|
||
// PART: (lldb) type lookup bar::stype | ||
// PART-NEXT: int | ||
|
||
// FULL: (lldb) type lookup foo::bar::stype | ||
// FULL-NEXT: int | ||
|
||
namespace foo { | ||
class bar { | ||
public: | ||
typedef unsigned utype; | ||
// This type is only referenced from within the type unit and we need to | ||
// make sure we can find it with the new type unit support in .debug_names. | ||
typedef int stype; | ||
|
||
private: | ||
utype m_unsigned; | ||
|
||
public: | ||
bar(utype u) : m_unsigned(u) {} | ||
|
||
utype get() const { return m_unsigned; } | ||
void set(utype u) { m_unsigned = u; } | ||
stype gets() const { return (stype)m_unsigned; } | ||
}; | ||
} // namespace foo | ||
|
||
int main() { | ||
foo::bar b(12); | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -621,7 +621,10 @@ std::optional<uint64_t> DWARFDebugNames::Entry::getCUIndex() const { | |
if (std::optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_compile_unit)) | ||
return Off->getAsUnsignedConstant(); | ||
// In a per-CU index, the entries without a DW_IDX_compile_unit attribute | ||
// implicitly refer to the single CU. | ||
// implicitly refer to the single CU, but only if we don't have a | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder why do we really need this check? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We only return 0 if this DebugName::Entry doesn't have a |
||
// DW_IDX_type_unit. | ||
if (lookup(dwarf::DW_IDX_type_unit).has_value()) | ||
return std::nullopt; | ||
if (NameIdx->getCUCount() == 1) | ||
return 0; | ||
return std::nullopt; | ||
|
@@ -634,6 +637,19 @@ std::optional<uint64_t> DWARFDebugNames::Entry::getCUOffset() const { | |
return NameIdx->getCUOffset(*Index); | ||
} | ||
|
||
std::optional<uint64_t> DWARFDebugNames::Entry::getLocalTUOffset() const { | ||
std::optional<uint64_t> Index = getLocalTUIndex(); | ||
if (!Index || *Index >= NameIdx->getLocalTUCount()) | ||
return std::nullopt; | ||
return NameIdx->getLocalTUOffset(*Index); | ||
} | ||
|
||
std::optional<uint64_t> DWARFDebugNames::Entry::getLocalTUIndex() const { | ||
if (std::optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_type_unit)) | ||
return Off->getAsUnsignedConstant(); | ||
return std::nullopt; | ||
} | ||
|
||
void DWARFDebugNames::Entry::dump(ScopedPrinter &W) const { | ||
W.startLine() << formatv("Abbrev: {0:x}\n", Abbr->Code); | ||
W.startLine() << formatv("Tag: {0}\n", Abbr->Tag); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will return a NULL
cu
if the*unit_offset
is UINT32_MAX, so it will work with tombstoned units. Though we can make a patch to `DebugNames::Entry::getLocalTUOffset()' to return std::nullopt for tombstoned units as a better fix.