Skip to content

[NFC] Separate high-level-dependent portions of DWARFExpression #139175

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions lldb/source/Expression/DWARFExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,
};
llvm::DIDumpOptions DumpOpts;
DumpOpts.GetNameForDWARFReg = GetRegName;
llvm::DWARFExpression(m_data.GetAsLLVM(), m_data.GetAddressByteSize())
.print(s->AsRawOstream(), DumpOpts, nullptr);
llvm::DWARFExpression E(m_data.GetAsLLVM(), m_data.GetAddressByteSize());
llvm::DWARFExpressionPrinter::print(&E, s->AsRawOstream(), DumpOpts, nullptr);
}

RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }
Expand Down
6 changes: 4 additions & 2 deletions lldb/source/Symbol/UnwindPlan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ static void DumpDWARFExpr(Stream &s, llvm::ArrayRef<uint8_t> expr, Thread *threa
if (auto order_and_width = GetByteOrderAndAddrSize(thread)) {
llvm::DataExtractor data(expr, order_and_width->first == eByteOrderLittle,
order_and_width->second);
llvm::DWARFExpression(data, order_and_width->second, llvm::dwarf::DWARF32)
.print(s.AsRawOstream(), llvm::DIDumpOptions(), nullptr);
llvm::DWARFExpression E(data, order_and_width->second,
llvm::dwarf::DWARF32);
llvm::DWARFExpressionPrinter::print(&E, s.AsRawOstream(),
llvm::DIDumpOptions(), nullptr);
} else
s.PutCString("dwarf-expr");
}
Expand Down
4 changes: 2 additions & 2 deletions lldb/unittests/Symbol/PostfixExpressionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ static std::string ParseAndGenerateDWARF(llvm::StringRef expr) {

std::string result;
llvm::raw_string_ostream os(result);
llvm::DWARFExpression(extractor, addr_size, llvm::dwarf::DWARF32)
.print(os, llvm::DIDumpOptions(), nullptr);
llvm::DWARFExpression E(extractor, addr_size, llvm::dwarf::DWARF32);
llvm::DWARFExpressionPrinter::print(&E, os, llvm::DIDumpOptions(), nullptr);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ CheckValidProgramTranslation(llvm::StringRef fpo_program,

std::string result;
llvm::raw_string_ostream os(result);
llvm::DWARFExpression(extractor, /*AddressSize=*/4, llvm::dwarf::DWARF32)
.print(os, llvm::DIDumpOptions(), nullptr);
llvm::DWARFExpression E(extractor, /*AddressSize=*/4, llvm::dwarf::DWARF32);
llvm::DWARFExpressionPrinter::print(&E, os, llvm::DIDumpOptions(), nullptr);

// actual check
ASSERT_EQ(expected_dwarf_expression, result);
Expand Down
88 changes: 65 additions & 23 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ class DWARFExpression {

private:
friend class DWARFExpression::iterator;
friend class DWARFExpressionPrinter;
friend class DWARFVerifier;

uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
Description Desc;
bool Error = false;
Expand All @@ -98,11 +101,6 @@ class DWARFExpression {
}
uint64_t getEndOffset() const { return EndOffset; }
bool isError() const { return Error; }
bool print(raw_ostream &OS, DIDumpOptions DumpOpts,
const DWARFExpression *Expr, DWARFUnit *U) const;

/// Verify \p Op. Does not affect the return of \a isError().
static bool verify(const Operation &Op, DWARFUnit *U);

private:
bool extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset,
Expand Down Expand Up @@ -152,26 +150,12 @@ class DWARFExpression {
iterator begin() const { return iterator(this, 0); }
iterator end() const { return iterator(this, Data.getData().size()); }

void print(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFUnit *U,
bool IsEH = false) const;

/// Print the expression in a format intended to be compact and useful to a
/// user, but not perfectly unambiguous, or capable of representing every
/// valid DWARF expression. Returns true if the expression was sucessfully
/// printed.
bool printCompact(raw_ostream &OS,
std::function<StringRef(uint64_t RegNum, bool IsEH)>
GetNameForDWARFReg = nullptr);

bool verify(DWARFUnit *U);

bool operator==(const DWARFExpression &RHS) const;

StringRef getData() const { return Data.getData(); }

static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
DIDumpOptions DumpOpts, uint8_t Opcode,
const ArrayRef<uint64_t> Operands);
friend class DWARFExpressionPrinter;
friend class DWARFVerifier;

private:
DataExtractor Data;
Expand All @@ -183,5 +167,63 @@ inline bool operator==(const DWARFExpression::iterator &LHS,
const DWARFExpression::iterator &RHS) {
return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
}
}
#endif

// This functionality is separated from the main data structure so that nothing
// in DWARFExpression.cpp needs build-time dependencies on DWARFUnit or other
// higher-level Dwarf structures. This approach creates better layering and
// allows DWARFExpression to be used from code which can't have dependencies on
// those higher-level structures.

class DWARFUnit;
struct DIDumpOptions;
class raw_ostream;

class DWARFExpressionPrinter {
public:
/// Print a Dwarf expression/
/// \param E to be printed
/// \param OS to this stream
/// \param GetNameForDWARFReg callback to return dwarf register name
static void print(const DWARFExpression *E, raw_ostream &OS,
DIDumpOptions DumpOpts, DWARFUnit *U, bool IsEH = false);

/// Print the expression in a format intended to be compact and useful to a
/// user, but not perfectly unambiguous, or capable of representing every
/// valid DWARF expression. Returns true if the expression was sucessfully
/// printed.
///
/// \param E to be printed
/// \param OS to this stream
/// \param GetNameForDWARFReg callback to return dwarf register name
///
/// \returns true if the expression was successfully printed
static bool printCompact(const DWARFExpression *E, raw_ostream &OS,
std::function<StringRef(uint64_t RegNum, bool IsEH)>
GetNameForDWARFReg = nullptr);

/// Pretty print a register opcode and operands.
/// \param U within the context of this Dwarf unit, if any.
/// \param OS to this stream
/// \param DumpOpts with these options
/// \param Opcode to print
/// \param Operands to the opcode
///
/// returns true if the Op was successfully printed
static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
DIDumpOptions DumpOpts, uint8_t Opcode,
ArrayRef<uint64_t> Operands);

private:
static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
DIDumpOptions DumpOpts, const DWARFExpression *Expr,
DWARFUnit *U);

static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
DIDumpOptions DumpOpts,
ArrayRef<uint64_t> Operands,
unsigned Operand);
};

} // end namespace llvm

#endif // LLVM_DEBUGINFO_DWARF_DWARFEXPRESSION_H
18 changes: 18 additions & 0 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
#include <cstdint>
#include <map>
Expand Down Expand Up @@ -319,6 +320,23 @@ class DWARFVerifier {
void verifyDebugNames(const DWARFSection &AccelSection,
const DataExtractor &StrData);

/// Verify that the the expression is valid within the context of unit U.
///
/// \param E expression to verify.
/// \param U containing DWARFUnit, if any.
///
/// returns true if E is a valid expression.
bool verifyExpression(const DWARFExpression &E, DWARFUnit *U);

/// Verify that the the expression operation is valid within the context of
/// unit U.
///
/// \param Op operation to verify
/// \param U containing DWARFUnit, if any
///
/// returns true if Op is a valid Dwarf operation
bool verifyExpressionOp(const DWARFExpression::Operation &Op, DWARFUnit *U);

public:
DWARFVerifier(raw_ostream &S, DWARFContext &D,
DIDumpOptions DumpOpts = DIDumpOptions::getForSingleDIE());
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Errc.h"
Expand Down Expand Up @@ -109,7 +110,8 @@ void UnwindLocation::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
OS << " in addrspace" << *AddrSpace;
break;
case DWARFExpr: {
Expr->print(OS, DumpOpts, nullptr);
if (Expr)
DWARFExpressionPrinter::print(&(*Expr), OS, DumpOpts, nullptr);
break;
}
case Constant:
Expand Down Expand Up @@ -943,7 +945,7 @@ void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
case OT_Expression:
assert(Instr.Expression && "missing DWARFExpression object");
OS << " ";
Instr.Expression->print(OS, DumpOpts, nullptr);
DWARFExpressionPrinter::print(&(*Instr.Expression), OS, DumpOpts, nullptr);
break;
}
}
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
std::optional<dwarf::DwarfFormat> Format;
if (U)
Format = U->getFormat();
DWARFExpression(Extractor, AddressSize, Format).print(OS, DumpOpts, U);
DWARFExpression E(Extractor, AddressSize, Format);
DWARFExpressionPrinter::print(&E, OS, DumpOpts, U);
}

bool DWARFLocationTable::dumpLocationList(
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue,
ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
Ctx.isLittleEndian(), 0);
DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format)
.print(OS, DumpOpts, U);
DWARFExpression DE(Data, U->getAddressByteSize(), U->getFormParams().Format);
DWARFExpressionPrinter::print(&DE, OS, DumpOpts, U);
}

static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
Expand Down
Loading
Loading