Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
23 changes: 12 additions & 11 deletions lldb/include/lldb/Expression/DWARFExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace lldb_private {

namespace plugin {
namespace dwarf {
class DWARFUnit;
class DWARFUnitInterface;
} // namespace dwarf
} // namespace plugin

Expand Down Expand Up @@ -65,20 +65,20 @@ class DWARFExpression {
/// \return
/// The address specified by the operation, if the operation exists, or
/// an llvm::Error otherwise.
llvm::Expected<lldb::addr_t>
GetLocation_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu) const;
llvm::Expected<lldb::addr_t> GetLocation_DW_OP_addr(
const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const;

bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu,
bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
lldb::addr_t file_addr);

void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size,
uint8_t addr_byte_size);

bool
ContainsThreadLocalStorage(const plugin::dwarf::DWARFUnit *dwarf_cu) const;
bool ContainsThreadLocalStorage(
const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const;

bool LinkThreadLocalStorage(
const plugin::dwarf::DWARFUnit *dwarf_cu,
const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
std::function<lldb::addr_t(lldb::addr_t file_addr)> const
&link_address_callback);

Expand Down Expand Up @@ -132,13 +132,14 @@ class DWARFExpression {
static llvm::Expected<Value>
Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
const plugin::dwarf::DWARFUnit *dwarf_cu,
const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
const lldb::RegisterKind reg_set, const Value *initial_value_ptr,
const Value *object_address_ptr);

static bool ParseDWARFLocationList(const plugin::dwarf::DWARFUnit *dwarf_cu,
const DataExtractor &data,
DWARFExpressionList *loc_list);
static bool
ParseDWARFLocationList(const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
const DataExtractor &data,
DWARFExpressionList *loc_list);

bool GetExpressionData(DataExtractor &data) const {
data = m_data;
Expand Down
55 changes: 16 additions & 39 deletions lldb/source/Expression/DWARFExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
const lldb::offset_t data_offset,
const LocationAtom op,
const DWARFUnit *dwarf_cu) {
const DWARFUnitInterface *dwarf_cu) {
lldb::offset_t offset = data_offset;
switch (op) {
// Only used in LLVM metadata.
Expand Down Expand Up @@ -362,7 +362,8 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
// + LEB128
{
data.Skip_LEB128(&offset);
return DWARFUnit::GetAddressByteSize(dwarf_cu) + offset - data_offset;
return DWARFUnitInterface::GetAddressByteSize(dwarf_cu) + offset -
data_offset;
}

case DW_OP_GNU_entry_value:
Expand Down Expand Up @@ -393,8 +394,8 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
return LLDB_INVALID_OFFSET;
}

llvm::Expected<lldb::addr_t>
DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const {
llvm::Expected<lldb::addr_t> DWARFExpression::GetLocation_DW_OP_addr(
const DWARFUnitInterface *dwarf_cu) const {
lldb::offset_t offset = 0;
while (m_data.ValidOffset(offset)) {
const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
Expand Down Expand Up @@ -422,7 +423,7 @@ DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const {
return LLDB_INVALID_ADDRESS;
}

bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu,
bool DWARFExpression::Update_DW_OP_addr(const DWARFUnitInterface *dwarf_cu,
lldb::addr_t file_addr) {
lldb::offset_t offset = 0;
while (m_data.ValidOffset(offset)) {
Expand Down Expand Up @@ -481,7 +482,7 @@ bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu,
}

bool DWARFExpression::ContainsThreadLocalStorage(
const DWARFUnit *dwarf_cu) const {
const DWARFUnitInterface *dwarf_cu) const {
lldb::offset_t offset = 0;
while (m_data.ValidOffset(offset)) {
const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
Expand All @@ -497,7 +498,7 @@ bool DWARFExpression::ContainsThreadLocalStorage(
return false;
}
bool DWARFExpression::LinkThreadLocalStorage(
const DWARFUnit *dwarf_cu,
const DWARFUnitInterface *dwarf_cu,
std::function<lldb::addr_t(lldb::addr_t file_addr)> const
&link_address_callback) {
const uint32_t addr_byte_size = m_data.GetAddressByteSize();
Expand Down Expand Up @@ -783,7 +784,8 @@ enum LocationDescriptionKind {
/* Composite*/
};
/// Adjust value's ValueType according to the kind of location description.
void UpdateValueTypeFromLocationDescription(Log *log, const DWARFUnit *dwarf_cu,
void UpdateValueTypeFromLocationDescription(Log *log,
const DWARFUnitInterface *dwarf_cu,
LocationDescriptionKind kind,
Value *value = nullptr) {
// Note that this function is conflating DWARF expressions with
Expand Down Expand Up @@ -875,7 +877,7 @@ static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes,
llvm::Expected<Value> DWARFExpression::Evaluate(
ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_kind,
const DWARFUnitInterface *dwarf_cu, const lldb::RegisterKind reg_kind,
const Value *initial_value_ptr, const Value *object_address_ptr) {

if (opcodes.GetByteSize() == 0)
Expand Down Expand Up @@ -2164,35 +2166,10 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
if (!bit_size)
return llvm::createStringError("unspecified architecture");
} else {
// Retrieve the type DIE that the value is being converted to. This
// offset is compile unit relative so we need to fix it up.
const uint64_t abs_die_offset = die_offset + dwarf_cu->GetOffset();
// FIXME: the constness has annoying ripple effects.
DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(abs_die_offset);
if (!die)
return llvm::createStringError(
"cannot resolve DW_OP_convert type DIE");
uint64_t encoding =
die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
if (!bit_size)
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
if (!bit_size)
return llvm::createStringError(
"unsupported type size in DW_OP_convert");
switch (encoding) {
case DW_ATE_signed:
case DW_ATE_signed_char:
sign = true;
break;
case DW_ATE_unsigned:
case DW_ATE_unsigned_char:
sign = false;
break;
default:
return llvm::createStringError(
"unsupported encoding in DW_OP_convert");
}
if (llvm::Error err =
const_cast<DWARFUnitInterface *>(dwarf_cu)->GetBitSizeAndSign(
die_offset, bit_size, sign))
return err;
}
Scalar &top = stack.back().ResolveValue(exe_ctx);
top.TruncOrExtendTo(bit_size, sign);
Expand Down Expand Up @@ -2353,7 +2330,7 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
}

bool DWARFExpression::ParseDWARFLocationList(
const DWARFUnit *dwarf_cu, const DataExtractor &data,
const DWARFUnitInterface *dwarf_cu, const DataExtractor &data,
DWARFExpressionList *location_list) {
location_list->Clear();
std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
Expand Down
6 changes: 3 additions & 3 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
switch (m_form) {
case DW_FORM_addr:
assert(m_unit);
m_value.uval =
data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_unit));
m_value.uval = data.GetMaxU64(
offset_ptr, DWARFUnitInterface::GetAddressByteSize(m_unit));
break;
case DW_FORM_block1:
m_value.uval = data.GetU8(offset_ptr);
Expand Down Expand Up @@ -242,7 +242,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form,

// Compile unit address sized values
case DW_FORM_addr:
*offset_ptr += DWARFUnit::GetAddressByteSize(unit);
*offset_ptr += DWARFUnitInterface::GetAddressByteSize(unit);
return true;

case DW_FORM_ref_addr:
Expand Down
39 changes: 31 additions & 8 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,37 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) {
return DWARFDIE(); // Not found
}

llvm::Error DWARFUnit::GetBitSizeAndSign(uint64_t die_offset,
uint64_t &bit_size, bool &sign) {
// Retrieve the type DIE that the value is being converted to. This
// offset is compile unit relative so we need to fix it up.
const uint64_t abs_die_offset = die_offset + GetOffset();
// FIXME: the constness has annoying ripple effects.
DWARFDIE die = GetDIE(abs_die_offset);
if (!die)
return llvm::createStringError("cannot resolve DW_OP_convert type DIE");
uint64_t encoding =
die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
if (!bit_size)
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
if (!bit_size)
return llvm::createStringError("unsupported type size in DW_OP_convert");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return llvm::createStringError("unsupported type size in DW_OP_convert");
return llvm::createStringError("unsupported type size");

Let's not mention DW_OP_convert here. (same below)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

switch (encoding) {
case DW_ATE_signed:
case DW_ATE_signed_char:
sign = true;
break;
case DW_ATE_unsigned:
case DW_ATE_unsigned_char:
sign = false;
break;
default:
return llvm::createStringError("unsupported encoding in DW_OP_convert");
}
return llvm::Error::success();
}

llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) {
DWARFDebugInfoEntry die;
if (!die.Extract(GetData(), *this, &die_offset))
Expand Down Expand Up @@ -703,14 +734,6 @@ DWARFUnit &DWARFUnit::GetNonSkeletonUnit() {
return *this;
}

uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) {
if (cu)
return cu->GetAddressByteSize();
return DWARFUnit::GetDefaultAddressSize();
}

uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; }

DWARFCompileUnit *DWARFUnit::GetSkeletonUnit() {
if (m_skeleton_unit.load() == nullptr && IsDWOUnit()) {
SymbolFileDWARFDwo *dwo =
Expand Down
50 changes: 39 additions & 11 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,34 @@ enum DWARFProducer {
eProducerOther
};

class DWARFUnit : public UserID {
class DWARFUnitInterface {
public:
DWARFUnitInterface() = default;
virtual ~DWARFUnitInterface() = default;

virtual SymbolFileDWARF &GetSymbolFileDWARF() const = 0;
virtual dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const = 0;
virtual uint16_t GetVersion() const = 0;
virtual std::unique_ptr<llvm::DWARFLocationTable>
GetLocationTable(const DataExtractor &data) const = 0;
virtual dw_addr_t GetBaseAddress() const = 0;
virtual uint8_t GetAddressByteSize() const = 0;
virtual llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size,
bool &sign) = 0;

static uint8_t GetAddressByteSize(const DWARFUnitInterface *cu) {
if (cu)
return cu->GetAddressByteSize();
return GetDefaultAddressSize();
}

static uint8_t GetDefaultAddressSize() { return 4; }

DWARFUnitInterface(const DWARFUnitInterface &) = delete;
DWARFUnitInterface &operator=(const DWARFUnitInterface &) = delete;
};

class DWARFUnit : public UserID, public DWARFUnitInterface {
using die_iterator_range =
llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>;

Expand Down Expand Up @@ -116,12 +143,14 @@ class DWARFUnit : public UserID {
size_t GetDebugInfoSize() const;
// Size of the CU data incl. header but without initial length.
dw_offset_t GetLength() const { return m_header.getLength(); }
uint16_t GetVersion() const { return m_header.getVersion(); }
uint16_t GetVersion() const override { return m_header.getVersion(); }
const llvm::DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
dw_offset_t GetAbbrevOffset() const;
uint8_t GetAddressByteSize() const { return m_header.getAddressByteSize(); }
uint8_t GetAddressByteSize() const override {
return m_header.getAddressByteSize();
}
dw_addr_t GetAddrBase() const { return m_addr_base.value_or(0); }
dw_addr_t GetBaseAddress() const { return m_base_addr; }
dw_addr_t GetBaseAddress() const override { return m_base_addr; }
dw_offset_t GetLineTableOffset();
dw_addr_t GetRangesBase() const { return m_ranges_base; }
dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; }
Expand All @@ -131,7 +160,7 @@ class DWARFUnit : public UserID {
void SetStrOffsetsBase(dw_offset_t str_offsets_base);
virtual void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) = 0;

dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const;
dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const override;

lldb::ByteOrder GetByteOrder() const;

Expand All @@ -145,17 +174,16 @@ class DWARFUnit : public UserID {

DWARFDIE GetDIE(dw_offset_t die_offset);

llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size,
bool &sign) override;

/// Returns the AT_Name of the DIE at `die_offset`, if it exists, without
/// parsing the entire compile unit. An empty is string is returned upon
/// error or if the attribute is not present.
llvm::StringRef PeekDIEName(dw_offset_t die_offset);

DWARFUnit &GetNonSkeletonUnit();

static uint8_t GetAddressByteSize(const DWARFUnit *cu);

static uint8_t GetDefaultAddressSize();

lldb_private::CompileUnit *GetLLDBCompUnit() const { return m_lldb_cu; }

void SetLLDBCompUnit(lldb_private::CompileUnit *cu) { m_lldb_cu = cu; }
Expand All @@ -174,7 +202,7 @@ class DWARFUnit : public UserID {

bool Supports_unnamed_objc_bitfields();

SymbolFileDWARF &GetSymbolFileDWARF() const { return m_dwarf; }
SymbolFileDWARF &GetSymbolFileDWARF() const override { return m_dwarf; }

DWARFProducer GetProducer();

Expand Down Expand Up @@ -237,7 +265,7 @@ class DWARFUnit : public UserID {
/// Return the location table for parsing the given location list data. The
/// format is chosen according to the unit type. Never returns null.
std::unique_ptr<llvm::DWARFLocationTable>
GetLocationTable(const DataExtractor &data) const;
GetLocationTable(const DataExtractor &data) const override;

DWARFDataExtractor GetLocationData() const;

Expand Down