Skip to content

Commit 0e5ae28

Browse files
Merge pull request #38 from adrian-prantl/48167864
Cherry-pick fixes for rdar://problem/48167864
2 parents 2485c7f + c5e5e29 commit 0e5ae28

File tree

7 files changed

+423
-32
lines changed

7 files changed

+423
-32
lines changed

lldb/include/lldb/Core/Section.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ class SectionList {
4343
const_iterator begin() { return m_sections.begin(); }
4444
const_iterator end() { return m_sections.end(); }
4545

46-
SectionList();
47-
48-
~SectionList();
46+
/// Create an empty list.
47+
SectionList() = default;
4948

5049
SectionList &operator=(const SectionList &rhs);
5150

lldb/include/lldb/Utility/Scalar.h

+8-20
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ namespace lldb_private {
3838
// follows the ANSI C type promotion rules.
3939
class Scalar {
4040
public:
41+
// FIXME: These are host types which seems to be an odd choice.
4142
enum Type {
4243
e_void = 0,
4344
e_sint,
@@ -98,30 +99,14 @@ class Scalar {
9899
}
99100
Scalar(llvm::APInt v) : m_type(), m_float(static_cast<float>(0)) {
100101
m_integer = llvm::APInt(v);
101-
switch (m_integer.getBitWidth()) {
102-
case 8:
103-
case 16:
104-
case 32:
105-
m_type = e_sint;
106-
return;
107-
case 64:
108-
m_type = e_slonglong;
109-
return;
110-
case 128:
111-
m_type = e_sint128;
112-
return;
113-
case 256:
114-
m_type = e_sint256;
115-
return;
116-
case 512:
117-
m_type = e_sint512;
118-
return;
119-
}
120-
lldbassert(false && "unsupported bitwidth");
102+
m_type = GetBestTypeForBitSize(m_integer.getBitWidth(), true);
121103
}
122104
// Scalar(const RegisterValue& reg_value);
123105
virtual ~Scalar();
124106

107+
/// Return the most efficient Scalar::Type for the requested bit size.
108+
static Type GetBestTypeForBitSize(size_t bit_size, bool sign);
109+
125110
bool SignExtend(uint32_t bit_pos);
126111

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

142+
/// Convert integer to \p type, limited to \p bits size.
143+
void TruncOrExtendTo(Scalar::Type type, uint16_t bits);
144+
157145
bool Promote(Scalar::Type type);
158146

159147
bool MakeSigned();

lldb/source/Core/Section.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,6 @@ lldb::offset_t Section::GetSectionData(DataExtractor &section_data) {
417417

418418
#pragma mark SectionList
419419

420-
SectionList::SectionList() : m_sections() {}
421-
422-
SectionList::~SectionList() {}
423-
424420
SectionList &SectionList::operator=(const SectionList &rhs) {
425421
if (this != &rhs)
426422
m_sections = rhs.m_sections;

lldb/source/Expression/DWARFExpression.cpp

+77
Original file line numberDiff line numberDiff line change
@@ -2559,6 +2559,83 @@ bool DWARFExpression::Evaluate(
25592559
stack.back().SetValueType(Value::eValueTypeScalar);
25602560
break;
25612561

2562+
// OPCODE: DW_OP_convert
2563+
// OPERANDS: 1
2564+
// A ULEB128 that is either a DIE offset of a
2565+
// DW_TAG_base_type or 0 for the generic (pointer-sized) type.
2566+
//
2567+
// DESCRIPTION: Pop the top stack element, convert it to a
2568+
// different type, and push the result.
2569+
case DW_OP_convert: {
2570+
if (stack.size() < 1) {
2571+
if (error_ptr)
2572+
error_ptr->SetErrorString(
2573+
"Expression stack needs at least 1 item for DW_OP_convert.");
2574+
return false;
2575+
}
2576+
const uint64_t die_offset = opcodes.GetULEB128(&offset);
2577+
Scalar::Type type = Scalar::e_void;
2578+
uint64_t bit_size;
2579+
if (die_offset == 0) {
2580+
// The generic type has the size of an address on the target
2581+
// machine and an unspecified signedness. Scalar has no
2582+
// "unspecified signedness", so we use unsigned types.
2583+
if (!module_sp) {
2584+
if (error_ptr)
2585+
error_ptr->SetErrorString("No module");
2586+
return false;
2587+
}
2588+
bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8;
2589+
if (!bit_size) {
2590+
if (error_ptr)
2591+
error_ptr->SetErrorString("unspecified architecture");
2592+
return false;
2593+
}
2594+
type = Scalar::GetBestTypeForBitSize(bit_size, false);
2595+
} else {
2596+
// Retrieve the type DIE that the value is being converted to.
2597+
// FIXME: the constness has annoying ripple effects.
2598+
DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(die_offset);
2599+
if (!die) {
2600+
if (error_ptr)
2601+
error_ptr->SetErrorString("Cannot resolve DW_OP_convert type DIE");
2602+
return false;
2603+
}
2604+
uint64_t encoding =
2605+
die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
2606+
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
2607+
if (!bit_size)
2608+
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
2609+
if (!bit_size) {
2610+
if (error_ptr)
2611+
error_ptr->SetErrorString("Unsupported type size in DW_OP_convert");
2612+
return false;
2613+
}
2614+
switch (encoding) {
2615+
case DW_ATE_signed:
2616+
case DW_ATE_signed_char:
2617+
type = Scalar::GetBestTypeForBitSize(bit_size, true);
2618+
break;
2619+
case DW_ATE_unsigned:
2620+
case DW_ATE_unsigned_char:
2621+
type = Scalar::GetBestTypeForBitSize(bit_size, false);
2622+
break;
2623+
default:
2624+
if (error_ptr)
2625+
error_ptr->SetErrorString("Unsupported encoding in DW_OP_convert");
2626+
return false;
2627+
}
2628+
}
2629+
if (type == Scalar::e_void) {
2630+
if (error_ptr)
2631+
error_ptr->SetErrorString("Unsupported pointer size");
2632+
return false;
2633+
}
2634+
Scalar &top = stack.back().ResolveValue(exe_ctx);
2635+
top.TruncOrExtendTo(type, bit_size);
2636+
break;
2637+
}
2638+
25622639
// OPCODE: DW_OP_call_frame_cfa
25632640
// OPERANDS: None
25642641
// DESCRIPTION: Specifies a DWARF expression that pushes the value of

lldb/source/Utility/Scalar.cpp

+45
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,51 @@ Scalar &Scalar::operator=(llvm::APInt rhs) {
416416

417417
Scalar::~Scalar() = default;
418418

419+
Scalar::Type Scalar::GetBestTypeForBitSize(size_t bit_size, bool sign) {
420+
// Scalar types are always host types, hence the sizeof().
421+
if (sign) {
422+
if (bit_size <= sizeof(int)*8) return Scalar::e_sint;
423+
if (bit_size <= sizeof(long)*8) return Scalar::e_slong;
424+
if (bit_size <= sizeof(long long)*8) return Scalar::e_slonglong;
425+
if (bit_size <= 128) return Scalar::e_sint128;
426+
if (bit_size <= 256) return Scalar::e_sint256;
427+
if (bit_size <= 512) return Scalar::e_sint512;
428+
} else {
429+
if (bit_size <= sizeof(unsigned int)*8) return Scalar::e_uint;
430+
if (bit_size <= sizeof(unsigned long)*8) return Scalar::e_ulong;
431+
if (bit_size <= sizeof(unsigned long long)*8) return Scalar::e_ulonglong;
432+
if (bit_size <= 128) return Scalar::e_uint128;
433+
if (bit_size <= 256) return Scalar::e_uint256;
434+
if (bit_size <= 512) return Scalar::e_uint512;
435+
}
436+
return Scalar::e_void;
437+
};
438+
439+
void Scalar::TruncOrExtendTo(Scalar::Type type, uint16_t bits) {
440+
switch (type) {
441+
case e_sint:
442+
case e_slong:
443+
case e_slonglong:
444+
case e_sint128:
445+
case e_sint256:
446+
case e_sint512:
447+
m_integer = m_integer.sextOrTrunc(bits);
448+
break;
449+
case e_uint:
450+
case e_ulong:
451+
case e_ulonglong:
452+
case e_uint128:
453+
case e_uint256:
454+
case e_uint512:
455+
m_integer = m_integer.zextOrTrunc(bits);
456+
break;
457+
default:
458+
llvm_unreachable("Promoting a Scalar to a specific number of bits is only "
459+
"supported for integer types.");
460+
}
461+
m_type = type;
462+
}
463+
419464
bool Scalar::Promote(Scalar::Type type) {
420465
bool success = false;
421466
switch (m_type) {

0 commit comments

Comments
 (0)