Skip to content

[llvm-debuginfo-analyzer] Support DW_TAG_module #137228

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,8 @@ The given criteria describes the debug line state machine registers.
=Discriminator: Line that has a discriminator.
=EndSequence: Marks the end in the sequence of lines.
=EpilogueBegin: Marks the start of a function epilogue.
=LineDebug: Lines that correspond to debug lines.
=LineAssembler: Lines that correspond to disassembly text.
=LineDebug: Lines that correspond to debug lines.
=NeverStepInto: marks a never step into.
=NewStatement: Marks a new statement.
=PrologueEnd: Marks the end of a function prologue.
Expand Down Expand Up @@ -519,6 +519,7 @@ The following options allow printing of scopes that match the given <kind>.
=InlinedFunction: An inlined function.
=Label: A label.
=LexicalBlock: A lexical block.
=Module: A module.
=Namespace: A namespace.
=Root: The element representing the main scope.
=Structure: A structure.
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ enum class LVSubclassID : unsigned char {
LV_SCOPE_FUNCTION,
LV_SCOPE_FUNCTION_INLINED,
LV_SCOPE_FUNCTION_TYPE,
LV_SCOPE_MODULE,
LV_SCOPE_NAMESPACE,
LV_SCOPE_ROOT,
LV_SCOPE_TEMPLATE_PACK,
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class LVReader {
LV_OBJECT_ALLOCATOR(ScopeFunction)
LV_OBJECT_ALLOCATOR(ScopeFunctionInlined)
LV_OBJECT_ALLOCATOR(ScopeFunctionType)
LV_OBJECT_ALLOCATOR(ScopeModule)
LV_OBJECT_ALLOCATOR(ScopeNamespace)
LV_OBJECT_ALLOCATOR(ScopeRoot)
LV_OBJECT_ALLOCATOR(ScopeTemplatePack)
Expand Down Expand Up @@ -210,6 +211,7 @@ class LVReader {
LV_CREATE_OBJECT(ScopeFunction)
LV_CREATE_OBJECT(ScopeFunctionInlined)
LV_CREATE_OBJECT(ScopeFunctionType)
LV_CREATE_OBJECT(ScopeModule)
LV_CREATE_OBJECT(ScopeNamespace)
LV_CREATE_OBJECT(ScopeRoot)
LV_CREATE_OBJECT(ScopeTemplatePack)
Expand Down
19 changes: 19 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ enum class LVScopeKind {
IsLabel,
IsLexicalBlock,
IsMember,
IsModule,
IsNamespace,
IsRoot,
IsStructure,
Expand Down Expand Up @@ -181,6 +182,7 @@ class LVScope : public LVElement {
KIND(LVScopeKind, IsTemplatePack);
KIND_1(LVScopeKind, IsTryBlock, IsBlock);
KIND_1(LVScopeKind, IsUnion, IsAggregate);
KIND_2(LVScopeKind, IsModule, CanHaveRanges, CanHaveLines);

PROPERTY(Property, HasDiscriminator);
PROPERTY(Property, CanHaveRanges);
Expand Down Expand Up @@ -748,6 +750,23 @@ class LVScopeFunctionType final : public LVScopeFunction {
void resolveExtra() override;
};

// Class to represent a DWARF Module.
class LVScopeModule final : public LVScope {
public:
LVScopeModule() : LVScope() {
setIsModule();
setIsLexicalBlock();
}
LVScopeModule(const LVScopeModule &) = delete;
LVScopeModule &operator=(const LVScopeModule &) = delete;
~LVScopeModule() = default;

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

// Class to represent a DWARF Namespace.
class LVScopeNamespace final : public LVScope {
LVScope *Reference = nullptr; // Reference to DW_AT_extension attribute.
Expand Down
16 changes: 16 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const char *const KindEnumeration = "Enumeration";
const char *const KindFile = "File";
const char *const KindFunction = "Function";
const char *const KindInlinedFunction = "InlinedFunction";
const char *const KindModule = "Module";
const char *const KindNamespace = "Namespace";
const char *const KindStruct = "Struct";
const char *const KindTemplateAlias = "TemplateAlias";
Expand All @@ -50,6 +51,8 @@ const char *LVScope::kind() const {
const char *Kind = KindUndefined;
if (getIsArray())
Kind = KindArray;
else if (getIsModule())
Kind = KindModule;
else if (getIsBlock())
Kind = KindBlock;
else if (getIsCallSite())
Expand Down Expand Up @@ -94,6 +97,7 @@ LVScopeDispatch LVScope::Dispatch = {
{LVScopeKind::IsInlinedFunction, &LVScope::getIsInlinedFunction},
{LVScopeKind::IsLabel, &LVScope::getIsLabel},
{LVScopeKind::IsLexicalBlock, &LVScope::getIsLexicalBlock},
{LVScopeKind::IsModule, &LVScope::getIsModule},
{LVScopeKind::IsNamespace, &LVScope::getIsNamespace},
{LVScopeKind::IsRoot, &LVScope::getIsRoot},
{LVScopeKind::IsStructure, &LVScope::getIsStructure},
Expand Down Expand Up @@ -1962,6 +1966,18 @@ void LVScopeFunctionType::resolveExtra() {
setName(Name);
}

//===----------------------------------------------------------------------===//
// DWARF module (DW_TAG_module).
//===----------------------------------------------------------------------===//
bool LVScopeModule::equals(const LVScope *Scope) const {
// For lexical blocks, LVScope::equals() compares the parent scope.
return LVScope::equals(Scope) && (Scope->getName() == getName());
}

void LVScopeModule::printExtra(raw_ostream &OS, bool Full) const {
OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
}

//===----------------------------------------------------------------------===//
// DWARF namespace (DW_TAG_namespace).
//===----------------------------------------------------------------------===//
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ LVElement *LVDWARFReader::createElement(dwarf::Tag Tag) {
case dwarf::DW_TAG_GNU_template_parameter_pack:
CurrentScope = createScopeTemplatePack();
return CurrentScope;
case dwarf::DW_TAG_module:
CurrentScope = createScopeModule();
return CurrentScope;
default:
// Collect TAGs not implemented.
if (options().getInternalTag() && Tag)
Expand Down
1 change: 1 addition & 0 deletions llvm/tools/llvm-debuginfo-analyzer/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ cl::list<LVScopeKind> cmdline::SelectScopes(
clEnumValN(LVScopeKind::IsLabel, "Label", "Label."),
clEnumValN(LVScopeKind::IsLexicalBlock, "LexicalBlock",
"Lexical block."),
clEnumValN(LVScopeKind::IsModule, "Module", "Module."),
clEnumValN(LVScopeKind::IsNamespace, "Namespace", "Namespace."),
clEnumValN(LVScopeKind::IsRoot, "Root", "Root."),
clEnumValN(LVScopeKind::IsStructure, "Structure", "Structure."),
Expand Down
20 changes: 20 additions & 0 deletions llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const char *DwarfClang = "test-dwarf-clang.o";
// Two compile units: one declares `extern int foo_printf(const char *, ...);`
// and another one that defines the function.
const char *DwarfClangUnspecParams = "test-dwarf-clang-unspec-params.elf";
const char *DwarfClangModule = "test-dwarf-clang-module.o";
const char *DwarfGcc = "test-dwarf-gcc.o";

// Helper function to get the first compile unit.
Expand Down Expand Up @@ -157,6 +158,22 @@ void checkUnspecifiedParameters(LVReader *Reader) {
true);
}

// Check the basic properties on parsed DW_TAG_module.
void checkScopeModule(LVReader *Reader) {
LVScopeRoot *Root = Reader->getScopesRoot();
LVScopeCompileUnit *CompileUnit = getFirstCompileUnit(Root);

EXPECT_EQ(Root->getFileFormatName(), "Mach-O 64-bit x86-64");
EXPECT_EQ(Root->getName(), DwarfClangModule);

ASSERT_NE(CompileUnit->getChildren(), nullptr);
LVElement *FirstChild = *(CompileUnit->getChildren()->begin());
EXPECT_EQ(FirstChild->getIsScope(), 1);
LVScopeModule *Module = static_cast<LVScopeModule *>(FirstChild);
EXPECT_EQ(Module->getIsModule(), 1);
EXPECT_EQ(Module->getName(), "DebugModule");
}

// Check the logical elements selection.
void checkElementSelection(LVReader *Reader) {
LVScopeRoot *Root = Reader->getScopesRoot();
Expand Down Expand Up @@ -301,6 +318,9 @@ void elementProperties(SmallString<128> &InputsDir) {

Reader = createReader(ReaderHandler, InputsDir, DwarfClangUnspecParams);
checkUnspecifiedParameters(Reader.get());

Reader = createReader(ReaderHandler, InputsDir, DwarfClangModule);
checkScopeModule(Reader.get());
}

// Logical elements selection.
Expand Down
Binary file not shown.