Skip to content

[llvm-debuginfo-analyzer] Add support for DWARF DW_AT_byte_size #139110

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
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
5 changes: 4 additions & 1 deletion llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ toolchain name, binary file format, etc.
transformations, in order to display built-in types (int, bool, etc.);
parameters and arguments used during template instantiation; parent
name hierarchy; array dimensions information; compiler generated
elements and the underlying types associated with the types aliases.
elements; type sizes and the underlying types associated with the types
aliases.

.. code-block:: text

Expand All @@ -171,6 +172,7 @@ toolchain name, binary file format, etc.
=encoded: Template arguments encoded in the template name.
=qualified: The element type include parents in its name.
=reference: Element declaration and definition references.
=size: Sizes for compound and base types.
=subrange: Subrange encoding information for arrays.
=typename: Template parameters.
=underlying: Underlying type for type definitions.
Expand Down Expand Up @@ -258,6 +260,7 @@ toolchain name, binary file format, etc.
=qualified
=qualifier
=register
=size
=subrange
=system
=typename
Expand Down
8 changes: 8 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "llvm/DebugInfo/LogicalView/Core/LVObject.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/MathExtras.h"
#include <map>
#include <set>
#include <vector>
Expand Down Expand Up @@ -65,6 +66,10 @@ using LVElementKindSet = std::set<LVElementKind>;
using LVElementDispatch = std::map<LVElementKind, LVElementGetFunction>;
using LVElementRequest = std::vector<LVElementGetFunction>;

// Assume 8-bit bytes; this is consistent, e.g. with
// lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp.
constexpr unsigned int DWARF_CHAR_BIT = 8u;

class LVElement : public LVObject {
enum class Property {
IsLine, // A logical line.
Expand Down Expand Up @@ -240,6 +245,9 @@ class LVElement : public LVObject {
virtual bool isBase() const { return false; }
virtual bool isTemplateParam() const { return false; }

uint32_t getStorageSizeInBytes() const {
return llvm::divideCeil(getBitSize(), DWARF_CHAR_BIT);
}
virtual uint32_t getBitSize() const { return 0; }
virtual void setBitSize(uint32_t Size) {}

Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ enum class LVAttributeKind {
Range, // --attribute=range
Reference, // --attribute=reference
Register, // --attribute=register
Size, // --attribute=size
Standard, // --attribute=standard
Subrange, // --attribute=subrange
System, // --attribute=system
Expand Down Expand Up @@ -349,6 +350,7 @@ class LVOptions {
ATTRIBUTE_OPTION(Range);
ATTRIBUTE_OPTION(Reference);
ATTRIBUTE_OPTION(Register);
ATTRIBUTE_OPTION(Size);
ATTRIBUTE_OPTION(Standard);
ATTRIBUTE_OPTION(Subrange);
ATTRIBUTE_OPTION(System);
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class LVScope : public LVElement {
LVProperties<Property> Properties;
static LVScopeDispatch Dispatch;

// Size in bits if this scope represents also a compound type.
uint32_t BitSize = 0;

// Coverage factor in units (bytes).
unsigned CoverageFactor = 0;

Expand Down Expand Up @@ -271,6 +274,9 @@ class LVScope : public LVElement {
bool removeElement(LVElement *Element) override;
void updateLevel(LVScope *Parent, bool Moved) override;

uint32_t getBitSize() const override { return BitSize; }
void setBitSize(uint32_t Size) override { BitSize = Size; }

void resolve() override;
void resolveName() override;
void resolveReferences() override;
Expand Down
7 changes: 7 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class LVType : public LVElement {
LVProperties<Property> Properties;
static LVTypeDispatch Dispatch;

// Size in bits of a symbol of this type.
uint32_t BitSize = 0;

// Find the current type in the given 'Targets'.
LVType *findIn(const LVTypes *Targets) const;

Expand Down Expand Up @@ -109,6 +112,10 @@ class LVType : public LVElement {
virtual LVElement *getUnderlyingType() { return nullptr; }
virtual void setUnderlyingType(LVElement *Element) {}

// Return the size in bits of an entity of this type.
uint32_t getBitSize() const override { return BitSize; }
void setBitSize(uint32_t Size) override { BitSize = Size; }

void resolveName() override;
void resolveReferences() override;

Expand Down
9 changes: 6 additions & 3 deletions llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ void LVOptions::resolveDependencies() {
setAttributeQualified();
setAttributeQualifier();
setAttributeRegister();
setAttributeSize();
setAttributeSubrange();
setAttributeSystem();
setAttributeTypename();
Expand Down Expand Up @@ -208,7 +209,7 @@ void LVOptions::resolveDependencies() {
// 1) Sort the CUs, to get a fast compare.
// 2) Encode template instantiations, so the names include template
// parameter information.
// 3) Include qualified types.
// 3) Include qualified types and their sizes.
// 4) Include any inserted abstract references.
// 5) For added/missing elements add the '+' or '-' tags.
if (getCompareExecute()) {
Expand All @@ -221,6 +222,7 @@ void LVOptions::resolveDependencies() {
setAttributeInserted();
setAttributeMissing();
setAttributeQualified();
setAttributeSize();
}

// Enable formatting for printing (indentation, print children).
Expand Down Expand Up @@ -312,9 +314,10 @@ void LVOptions::print(raw_ostream &OS) const {
<< "Range: " << getAttributeRange() << ", "
<< "Reference: " << getAttributeReference() << "\n"
<< "Register: " << getAttributeRegister() << ", "
<< "Size: " << getAttributeSize() << ", "
<< "Standard: " << getAttributeStandard() << ", "
<< "Subrange: " << getAttributeSubrange() << ", "
<< "System: " << getAttributeSystem() << "\n"
<< "Subrange: " << getAttributeSubrange() << "\n"
<< "System: " << getAttributeSystem() << ", "
<< "Typename: " << getAttributeTypename() << ", "
<< "Underlying: " << getAttributeUnderlying() << ", "
<< "Zero: " << getAttributeZero() << "\n";
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1018,9 +1018,13 @@ void LVScope::printExtra(raw_ostream &OS, bool Full) const {
// Do not print any type or name for a lexical block.
if (!getIsBlock()) {
OS << " " << formattedName(getName());
if (!getIsAggregate())
if (!getIsAggregate()) {
OS << " -> " << typeOffsetAsString()
<< formattedNames(getTypeQualifiedName(), typeAsString());
}
if (options().getAttributeSize())
if (uint32_t Size = getStorageSizeInBytes())
OS << " [Size = " << Size << "]";
}
OS << "\n";

Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,11 @@ void LVType::print(raw_ostream &OS, bool Full) const {
}

void LVType::printExtra(raw_ostream &OS, bool Full) const {
OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
OS << formattedKind(kind()) << " " << formattedName(getName());
if (options().getAttributeSize())
if (uint32_t Size = getStorageSizeInBytes())
OS << " [Size = " << Size << "]";
OS << "\n";
}

//===----------------------------------------------------------------------===//
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1987,6 +1987,7 @@ Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ClassRecord &Class,
Scope->setName(Class.getName());
if (Class.hasUniqueName())
Scope->setLinkageName(Class.getUniqueName());
Scope->setBitSize(Class.getSize() * DWARF_CHAR_BIT);

if (Class.isNested()) {
Scope->setIsNested();
Expand Down Expand Up @@ -2455,6 +2456,7 @@ Error LVLogicalVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union,
Scope->setName(Union.getName());
if (Union.hasUniqueName())
Scope->setLinkageName(Union.getUniqueName());
Scope->setBitSize(Union.getSize() * DWARF_CHAR_BIT);

if (Union.isNested()) {
Scope->setIsNested();
Expand Down Expand Up @@ -3208,6 +3210,7 @@ LVType *LVLogicalVisitor::createBaseType(TypeIndex TI, StringRef TypeName) {

if (createElement(TIR, SimpleKind)) {
CurrentType->setName(TypeName);
CurrentType->setBitSize(getSizeInBytesForTypeIndex(TIR) * DWARF_CHAR_BIT);
Reader->getCompileUnit()->addElement(CurrentType);
}
return CurrentType;
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 @@ -310,6 +310,9 @@ void LVDWARFReader::processOneAttribute(const DWARFDie &Die,
case dwarf::DW_AT_bit_size:
CurrentElement->setBitSize(GetAsUnsignedConstant());
break;
case dwarf::DW_AT_byte_size:
CurrentElement->setBitSize(GetAsUnsignedConstant() * DWARF_CHAR_BIT);
break;
case dwarf::DW_AT_call_file:
CurrentElement->setCallFilenameIndex(IncrementFileIndex
? GetAsUnsignedConstant() + 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
; references to the enumerators 'RED' and 'BLUE'. The CodeView generated
; by GCC and MSVC, does include such references.

; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer,size \
; RUN: --output-sort=name \
; RUN: --print=symbols,types \
; RUN: %p/Inputs/pr-46466-codeview-clang.o \
Expand All @@ -38,9 +38,9 @@
; ONE-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
; ONE-NEXT: [002] {Producer} 'clang version 15.0.0 {{.*}}'
; ONE-NEXT: [002] {Variable} extern 'S' -> 'Struct'
; ONE-NEXT: [002] 1 {Struct} 'Struct'
; ONE-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; ONE-NEXT: [003] {Member} public 'U' -> 'Union'
; ONE-NEXT: [003] 2 {Union} 'Union'
; ONE-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; ONE-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'int'
; ONE-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; ONE-NEXT: [005] {Enumerator} 'RED' = '0x0'
Expand All @@ -51,9 +51,9 @@
; ONE-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
; ONE-NEXT: [002] {Producer} 'Microsoft (R) Optimizing Compiler'
; ONE-NEXT: [002] {Variable} extern 'S' -> 'Struct'
; ONE-NEXT: [002] 1 {Struct} 'Struct'
; ONE-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; ONE-NEXT: [003] {Member} public 'U' -> 'Union'
; ONE-NEXT: [003] 2 {Union} 'Union'
; ONE-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; ONE-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'int'
; ONE-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; ONE-NEXT: [005] {Enumerator} 'RED' = '0x0'
Expand All @@ -62,7 +62,7 @@
; showing just the logical types that are 'Enumerator' and its
; parents. The logical view is sorted by the types name.

; RUN: llvm-debuginfo-analyzer --attribute=level,format \
; RUN: llvm-debuginfo-analyzer --attribute=level,format,size \
; RUN: --output-sort=name \
; RUN: --select-types=Enumerator \
; RUN: --report=parents \
Expand All @@ -74,8 +74,8 @@
; TWO-NEXT: [000] {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64
; TWO-EMPTY:
; TWO-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
; TWO-NEXT: [002] 1 {Struct} 'Struct'
; TWO-NEXT: [003] 2 {Union} 'Union'
; TWO-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; TWO-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; TWO-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'int'
; TWO-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; TWO-NEXT: [005] {Enumerator} 'RED' = '0x0'
Expand All @@ -84,8 +84,8 @@
; TWO-NEXT: [000] {File} 'pr-46466-codeview-msvc.o' -> COFF-x86-64
; TWO-EMPTY:
; TWO-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
; TWO-NEXT: [002] 1 {Struct} 'Struct'
; TWO-NEXT: [003] 2 {Union} 'Union'
; TWO-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; TWO-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; TWO-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'int'
; TWO-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; TWO-NEXT: [005] {Enumerator} 'RED' = '0x0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
; ONE-NEXT: {File} 'test.cpp'
; ONE-NEXT: {Public} 'foo' [0x0000000000:0x0000000046]
; ONE-NEXT: [0x0000000000][002] {TypeAlias} 'INTPTR' -> [0x0000001001]'* const int'
; ONE-NEXT: [0x0000000030][002] {BaseType} 'bool'
; ONE-NEXT: [0x0000000030][002] {BaseType} 'bool' [Size = 1]
; ONE-NEXT: [0x0000000000][002] {Function} extern not_inlined 'foo' -> [0x0000000074]'int'
; ONE-NEXT: [0x0000000000][003] {Range} Lines 2:9 [0x0000000000:0x0000000046]
; ONE-NEXT: [0x0000000000][003] {Linkage} 0x1 '?foo@@YAHPEBHI_N@Z'
Expand Down Expand Up @@ -80,8 +80,8 @@
; ONE-NEXT: [0x000000003e][003] {Code} 'movl 0x1c(%rsp), %eax'
; ONE-NEXT: [0x0000000042][003] {Code} 'addq $0x20, %rsp'
; ONE-NEXT: [0x0000000046][003] {Code} 'retq'
; ONE-NEXT: [0x0000000074][002] {BaseType} 'int'
; ONE-NEXT: [0x0000000075][002] {BaseType} 'unsigned'
; ONE-NEXT: [0x0000000074][002] {BaseType} 'int' [Size = 4]
; ONE-NEXT: [0x0000000075][002] {BaseType} 'unsigned' [Size = 4]
; ONE-EMPTY:
; ONE-NEXT: -----------------------------
; ONE-NEXT: Element Total Printed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
; references to the enumerators 'RED' and 'BLUE'. The DWARF generated
; by GCC, does include such references.

; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer,size \
; RUN: --output-sort=name \
; RUN: --print=symbols,types \
; RUN: %p/Inputs/pr-46466-dwarf-clang.o \
Expand All @@ -38,7 +38,7 @@
; ONE-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
; ONE-NEXT: [002] {Producer} 'clang version 15.0.0 {{.*}}'
; ONE-NEXT: [002] 8 {Variable} extern 'S' -> 'Struct'
; ONE-NEXT: [002] 1 {Struct} 'Struct'
; ONE-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; ONE-NEXT: [003] 5 {Member} public 'U' -> 'Union'
; ONE-EMPTY:
; ONE-NEXT: Logical View:
Expand All @@ -47,9 +47,9 @@
; ONE-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
; ONE-NEXT: [002] {Producer} 'GNU C++14 10.3.0 {{.*}}'
; ONE-NEXT: [002] 8 {Variable} extern 'S' -> 'Struct'
; ONE-NEXT: [002] 1 {Struct} 'Struct'
; ONE-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; ONE-NEXT: [003] 5 {Member} public 'U' -> 'Union'
; ONE-NEXT: [003] 2 {Union} 'Union'
; ONE-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; ONE-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int'
; ONE-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; ONE-NEXT: [005] {Enumerator} 'RED' = '0x0'
Expand All @@ -58,7 +58,7 @@
; showing just the logical types that are 'Enumerator' and its
; parents. The logical view is sorted by the types name.

; RUN: llvm-debuginfo-analyzer --attribute=level,format \
; RUN: llvm-debuginfo-analyzer --attribute=level,format,size \
; RUN: --output-sort=name \
; RUN: --select-types=Enumerator \
; RUN: --report=parents \
Expand All @@ -75,8 +75,8 @@
; TWO-NEXT: [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64
; TWO-EMPTY:
; TWO-NEXT: [001] {CompileUnit} 'pr-46466.cpp'
; TWO-NEXT: [002] 1 {Struct} 'Struct'
; TWO-NEXT: [003] 2 {Union} 'Union'
; TWO-NEXT: [002] 1 {Struct} 'Struct' [Size = 1]
; TWO-NEXT: [003] 2 {Union} 'Union' [Size = 1]
; TWO-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int'
; TWO-NEXT: [005] {Enumerator} 'BLUE' = '0x1'
; TWO-NEXT: [005] {Enumerator} 'RED' = '0x0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
; ONE-NEXT: {File} 'test.cpp'
; ONE-NEXT: {Public} 'foo' [0x0000000000:0x000000003a]
; ONE-NEXT: [0x000000000b][002] {Range} Lines 2:9 [0x0000000000:0x000000003a]
; ONE-NEXT: [0x00000000bc][002] {BaseType} 'bool'
; ONE-NEXT: [0x0000000099][002] {BaseType} 'int'
; ONE-NEXT: [0x00000000b5][002] {BaseType} 'unsigned int'
; ONE-NEXT: [0x00000000bc][002] {BaseType} 'bool' [Size = 1]
; ONE-NEXT: [0x0000000099][002] {BaseType} 'int' [Size = 4]
; ONE-NEXT: [0x00000000b5][002] {BaseType} 'unsigned int' [Size = 4]
; ONE-EMPTY:
; ONE-NEXT: [0x00000000a0][002] {Source} '/data/projects/tests/input/general/test.cpp'
; ONE-NEXT: [0x00000000a0][002] 1 {TypeAlias} 'INTPTR' -> [0x00000000ab]'* const int'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
; an assert in the LVDWARFReader:
; $ clang++ -g -c dw-at-specification.cpp -o dw-at-specification.o

; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \
; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer,size \
; RUN: --output-sort=name \
; RUN: --print=symbols \
; RUN: %p/Inputs/dw-at-specification.o 2>&1 | \
Expand All @@ -25,5 +25,5 @@
; CHECK: [001] {CompileUnit} 'a.cpp'
; CHECK: [002] {Producer} 'clang version 11.0.0 ({{.*}})'
; CHECK: [002] {Variable} 'Arr' -> 'const int [3]'
; CHECK: [002] 1 {Struct} 'S'
; CHECK: [002] 1 {Struct} 'S' [Size = 1]
; CHECK: [003] 2 {Member} extern public 'Arr' -> 'const int [1]'
2 changes: 2 additions & 0 deletions llvm/test/tools/llvm-debuginfo-analyzer/cmdline.test
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ HELP-ALL: =qualifier - Line qualifiers (Newstatement, BasicB
HELP-ALL: =range - Debug location ranges.
HELP-ALL: =reference - Element declaration and definition references.
HELP-ALL: =register - Processor register names.
HELP-ALL: =size - Type sizes.
HELP-ALL: =standard - Basic attributes alias.
HELP-ALL: =subrange - Subrange encoding information for arrays.
HELP-ALL: =system - Display PDB's MS system elements.
Expand Down Expand Up @@ -169,6 +170,7 @@ HELP-ALL: =FunctionType - Function type.
HELP-ALL: =InlinedFunction - Inlined function.
HELP-ALL: =Label - Label.
HELP-ALL: =LexicalBlock - Lexical block.
HELP-ALL: =Module - Module.
HELP-ALL: =Namespace - Namespace.
HELP-ALL: =Root - Root.
HELP-ALL: =Structure - Structure.
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 @@ -114,6 +114,7 @@ cl::list<LVAttributeKind> cmdline::AttributeOptions(
"Element declaration and definition references."),
clEnumValN(LVAttributeKind::Register, "register",
"Processor register names."),
clEnumValN(LVAttributeKind::Size, "size", "Type sizes."),
clEnumValN(LVAttributeKind::Standard, "standard",
"Basic attributes alias."),
clEnumValN(LVAttributeKind::Subrange, "subrange",
Expand Down
Loading