Skip to content

Commit

Permalink
Merge pull request #38 from adrian-prantl/48167864
Browse files Browse the repository at this point in the history
Cherry-pick fixes for rdar://problem/48167864
  • Loading branch information
adrian-prantl authored Nov 4, 2019
2 parents 2485c7f + c5e5e29 commit 0e5ae28
Show file tree
Hide file tree
Showing 7 changed files with 423 additions and 32 deletions.
5 changes: 2 additions & 3 deletions lldb/include/lldb/Core/Section.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ class SectionList {
const_iterator begin() { return m_sections.begin(); }
const_iterator end() { return m_sections.end(); }

SectionList();

~SectionList();
/// Create an empty list.
SectionList() = default;

SectionList &operator=(const SectionList &rhs);

Expand Down
28 changes: 8 additions & 20 deletions lldb/include/lldb/Utility/Scalar.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace lldb_private {
// follows the ANSI C type promotion rules.
class Scalar {
public:
// FIXME: These are host types which seems to be an odd choice.
enum Type {
e_void = 0,
e_sint,
Expand Down Expand Up @@ -98,30 +99,14 @@ class Scalar {
}
Scalar(llvm::APInt v) : m_type(), m_float(static_cast<float>(0)) {
m_integer = llvm::APInt(v);
switch (m_integer.getBitWidth()) {
case 8:
case 16:
case 32:
m_type = e_sint;
return;
case 64:
m_type = e_slonglong;
return;
case 128:
m_type = e_sint128;
return;
case 256:
m_type = e_sint256;
return;
case 512:
m_type = e_sint512;
return;
}
lldbassert(false && "unsupported bitwidth");
m_type = GetBestTypeForBitSize(m_integer.getBitWidth(), true);
}
// Scalar(const RegisterValue& reg_value);
virtual ~Scalar();

/// Return the most efficient Scalar::Type for the requested bit size.
static Type GetBestTypeForBitSize(size_t bit_size, bool sign);

bool SignExtend(uint32_t bit_pos);

bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset);
Expand Down Expand Up @@ -154,6 +139,9 @@ class Scalar {
return (m_type >= e_sint) && (m_type <= e_long_double);
}

/// Convert integer to \p type, limited to \p bits size.
void TruncOrExtendTo(Scalar::Type type, uint16_t bits);

bool Promote(Scalar::Type type);

bool MakeSigned();
Expand Down
4 changes: 0 additions & 4 deletions lldb/source/Core/Section.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,10 +417,6 @@ lldb::offset_t Section::GetSectionData(DataExtractor &section_data) {

#pragma mark SectionList

SectionList::SectionList() : m_sections() {}

SectionList::~SectionList() {}

SectionList &SectionList::operator=(const SectionList &rhs) {
if (this != &rhs)
m_sections = rhs.m_sections;
Expand Down
77 changes: 77 additions & 0 deletions lldb/source/Expression/DWARFExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2559,6 +2559,83 @@ bool DWARFExpression::Evaluate(
stack.back().SetValueType(Value::eValueTypeScalar);
break;

// OPCODE: DW_OP_convert
// OPERANDS: 1
// A ULEB128 that is either a DIE offset of a
// DW_TAG_base_type or 0 for the generic (pointer-sized) type.
//
// DESCRIPTION: Pop the top stack element, convert it to a
// different type, and push the result.
case DW_OP_convert: {
if (stack.size() < 1) {
if (error_ptr)
error_ptr->SetErrorString(
"Expression stack needs at least 1 item for DW_OP_convert.");
return false;
}
const uint64_t die_offset = opcodes.GetULEB128(&offset);
Scalar::Type type = Scalar::e_void;
uint64_t bit_size;
if (die_offset == 0) {
// The generic type has the size of an address on the target
// machine and an unspecified signedness. Scalar has no
// "unspecified signedness", so we use unsigned types.
if (!module_sp) {
if (error_ptr)
error_ptr->SetErrorString("No module");
return false;
}
bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8;
if (!bit_size) {
if (error_ptr)
error_ptr->SetErrorString("unspecified architecture");
return false;
}
type = Scalar::GetBestTypeForBitSize(bit_size, false);
} else {
// Retrieve the type DIE that the value is being converted to.
// FIXME: the constness has annoying ripple effects.
DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(die_offset);
if (!die) {
if (error_ptr)
error_ptr->SetErrorString("Cannot resolve DW_OP_convert type DIE");
return false;
}
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) {
if (error_ptr)
error_ptr->SetErrorString("Unsupported type size in DW_OP_convert");
return false;
}
switch (encoding) {
case DW_ATE_signed:
case DW_ATE_signed_char:
type = Scalar::GetBestTypeForBitSize(bit_size, true);
break;
case DW_ATE_unsigned:
case DW_ATE_unsigned_char:
type = Scalar::GetBestTypeForBitSize(bit_size, false);
break;
default:
if (error_ptr)
error_ptr->SetErrorString("Unsupported encoding in DW_OP_convert");
return false;
}
}
if (type == Scalar::e_void) {
if (error_ptr)
error_ptr->SetErrorString("Unsupported pointer size");
return false;
}
Scalar &top = stack.back().ResolveValue(exe_ctx);
top.TruncOrExtendTo(type, bit_size);
break;
}

// OPCODE: DW_OP_call_frame_cfa
// OPERANDS: None
// DESCRIPTION: Specifies a DWARF expression that pushes the value of
Expand Down
45 changes: 45 additions & 0 deletions lldb/source/Utility/Scalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,51 @@ Scalar &Scalar::operator=(llvm::APInt rhs) {

Scalar::~Scalar() = default;

Scalar::Type Scalar::GetBestTypeForBitSize(size_t bit_size, bool sign) {
// Scalar types are always host types, hence the sizeof().
if (sign) {
if (bit_size <= sizeof(int)*8) return Scalar::e_sint;
if (bit_size <= sizeof(long)*8) return Scalar::e_slong;
if (bit_size <= sizeof(long long)*8) return Scalar::e_slonglong;
if (bit_size <= 128) return Scalar::e_sint128;
if (bit_size <= 256) return Scalar::e_sint256;
if (bit_size <= 512) return Scalar::e_sint512;
} else {
if (bit_size <= sizeof(unsigned int)*8) return Scalar::e_uint;
if (bit_size <= sizeof(unsigned long)*8) return Scalar::e_ulong;
if (bit_size <= sizeof(unsigned long long)*8) return Scalar::e_ulonglong;
if (bit_size <= 128) return Scalar::e_uint128;
if (bit_size <= 256) return Scalar::e_uint256;
if (bit_size <= 512) return Scalar::e_uint512;
}
return Scalar::e_void;
};

void Scalar::TruncOrExtendTo(Scalar::Type type, uint16_t bits) {
switch (type) {
case e_sint:
case e_slong:
case e_slonglong:
case e_sint128:
case e_sint256:
case e_sint512:
m_integer = m_integer.sextOrTrunc(bits);
break;
case e_uint:
case e_ulong:
case e_ulonglong:
case e_uint128:
case e_uint256:
case e_uint512:
m_integer = m_integer.zextOrTrunc(bits);
break;
default:
llvm_unreachable("Promoting a Scalar to a specific number of bits is only "
"supported for integer types.");
}
m_type = type;
}

bool Scalar::Promote(Scalar::Type type) {
bool success = false;
switch (m_type) {
Expand Down
Loading

0 comments on commit 0e5ae28

Please sign in to comment.