Skip to content

Commit 4cf1fe2

Browse files
authored
[lldb] Add missing operations to GetOpcodeDataSize (#120163)
The improved error reporting in #120162 revealed that we were missing opcodes in GetOpcodeDataSize. I changed the function to remove the default case and switch over the enum type which will cause the compiler to emit a warning if there are unhandled operations in the future. rdar://139705570
1 parent a6211a6 commit 4cf1fe2

File tree

1 file changed

+63
-13
lines changed

1 file changed

+63
-13
lines changed

lldb/source/Expression/DWARFExpression.cpp

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,35 @@ static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
132132
/// are made on the state of \p data after this call.
133133
static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
134134
const lldb::offset_t data_offset,
135-
const uint8_t op,
135+
const LocationAtom op,
136136
const DWARFUnit *dwarf_cu) {
137137
lldb::offset_t offset = data_offset;
138138
switch (op) {
139+
// Only used in LLVM metadata.
140+
case DW_OP_LLVM_fragment:
141+
case DW_OP_LLVM_convert:
142+
case DW_OP_LLVM_tag_offset:
143+
case DW_OP_LLVM_entry_value:
144+
case DW_OP_LLVM_implicit_pointer:
145+
case DW_OP_LLVM_arg:
146+
case DW_OP_LLVM_extract_bits_sext:
147+
case DW_OP_LLVM_extract_bits_zext:
148+
break;
149+
// Vendor extensions:
150+
case DW_OP_HP_is_value:
151+
case DW_OP_HP_fltconst4:
152+
case DW_OP_HP_fltconst8:
153+
case DW_OP_HP_mod_range:
154+
case DW_OP_HP_unmod_range:
155+
case DW_OP_HP_tls:
156+
case DW_OP_INTEL_bit_piece:
157+
case DW_OP_WASM_location:
158+
case DW_OP_WASM_location_int:
159+
case DW_OP_APPLE_uninit:
160+
case DW_OP_PGI_omp_thread_num:
161+
case DW_OP_hi_user:
162+
break;
163+
139164
case DW_OP_addr:
140165
case DW_OP_call_ref: // 0x9a 1 address sized offset of DIE (DWARF3)
141166
return data.GetAddressByteSize();
@@ -246,6 +271,7 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
246271
case DW_OP_pick: // 0x15 1 1-byte stack index
247272
case DW_OP_deref_size: // 0x94 1 1-byte size of data retrieved
248273
case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved
274+
case DW_OP_deref_type: // 0xa6 1 1-byte constant
249275
return 1;
250276

251277
// Opcodes with a single 2 byte arguments
@@ -268,7 +294,6 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
268294
return 8;
269295

270296
// All opcodes that have a single ULEB (signed or unsigned) argument
271-
case DW_OP_addrx: // 0xa1 1 ULEB128 index
272297
case DW_OP_constu: // 0x10 1 ULEB128 constant
273298
case DW_OP_consts: // 0x11 1 SLEB128 constant
274299
case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend
@@ -307,14 +332,20 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
307332
case DW_OP_regx: // 0x90 1 ULEB128 register
308333
case DW_OP_fbreg: // 0x91 1 SLEB128 offset
309334
case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed
335+
case DW_OP_convert: // 0xa8 1 ULEB128 offset
336+
case DW_OP_reinterpret: // 0xa9 1 ULEB128 offset
337+
case DW_OP_addrx: // 0xa1 1 ULEB128 index
338+
case DW_OP_constx: // 0xa2 1 ULEB128 index
339+
case DW_OP_xderef_type: // 0xa7 1 ULEB128 index
310340
case DW_OP_GNU_addr_index: // 0xfb 1 ULEB128 index
311341
case DW_OP_GNU_const_index: // 0xfc 1 ULEB128 index
312342
data.Skip_LEB128(&offset);
313343
return offset - data_offset;
314344

315345
// All opcodes that have a 2 ULEB (signed or unsigned) arguments
316-
case DW_OP_bregx: // 0x92 2 ULEB128 register followed by SLEB128 offset
317-
case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
346+
case DW_OP_bregx: // 0x92 2 ULEB128 register followed by SLEB128 offset
347+
case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
348+
case DW_OP_regval_type: // 0xa5 ULEB128 + ULEB128
318349
data.Skip_LEB128(&offset);
319350
data.Skip_LEB128(&offset);
320351
return offset - data_offset;
@@ -327,27 +358,46 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
327358
return offset - data_offset;
328359
}
329360

361+
case DW_OP_implicit_pointer: // 0xa0 4-byte (or 8-byte for DWARF 64) constant
362+
// + LEB128
363+
{
364+
data.Skip_LEB128(&offset);
365+
return DWARFUnit::GetAddressByteSize(dwarf_cu) + offset - data_offset;
366+
}
367+
330368
case DW_OP_GNU_entry_value:
331369
case DW_OP_entry_value: // 0xa3 ULEB128 size + variable-length block
332370
{
333371
uint64_t subexpr_len = data.GetULEB128(&offset);
334372
return (offset - data_offset) + subexpr_len;
335373
}
336374

337-
default:
338-
if (!dwarf_cu) {
339-
return LLDB_INVALID_OFFSET;
340-
}
375+
case DW_OP_const_type: // 0xa4 ULEB128 + size + variable-length block
376+
{
377+
data.Skip_LEB128(&offset);
378+
uint8_t length = data.GetU8(&offset);
379+
return (offset - data_offset) + length;
380+
}
381+
382+
case DW_OP_LLVM_user: // 0xe9: ULEB128 + variable length constant
383+
{
384+
uint64_t constants = data.GetULEB128(&offset);
385+
return (offset - data_offset) + constants;
386+
}
387+
}
388+
389+
if (dwarf_cu)
341390
return dwarf_cu->GetSymbolFileDWARF().GetVendorDWARFOpcodeSize(
342391
data, data_offset, op);
343-
}
392+
393+
return LLDB_INVALID_OFFSET;
344394
}
345395

346396
llvm::Expected<lldb::addr_t>
347397
DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const {
348398
lldb::offset_t offset = 0;
349399
while (m_data.ValidOffset(offset)) {
350-
const uint8_t op = m_data.GetU8(&offset);
400+
const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
351401

352402
if (op == DW_OP_addr)
353403
return m_data.GetAddress(&offset);
@@ -376,7 +426,7 @@ bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu,
376426
lldb::addr_t file_addr) {
377427
lldb::offset_t offset = 0;
378428
while (m_data.ValidOffset(offset)) {
379-
const uint8_t op = m_data.GetU8(&offset);
429+
const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
380430

381431
if (op == DW_OP_addr) {
382432
const uint32_t addr_byte_size = m_data.GetAddressByteSize();
@@ -434,7 +484,7 @@ bool DWARFExpression::ContainsThreadLocalStorage(
434484
const DWARFUnit *dwarf_cu) const {
435485
lldb::offset_t offset = 0;
436486
while (m_data.ValidOffset(offset)) {
437-
const uint8_t op = m_data.GetU8(&offset);
487+
const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
438488

439489
if (op == DW_OP_form_tls_address || op == DW_OP_GNU_push_tls_address)
440490
return true;
@@ -465,7 +515,7 @@ bool DWARFExpression::LinkThreadLocalStorage(
465515
lldb::addr_t const_value = 0;
466516
size_t const_byte_size = 0;
467517
while (m_data.ValidOffset(offset)) {
468-
const uint8_t op = m_data.GetU8(&offset);
518+
const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
469519

470520
bool decoded_data = false;
471521
switch (op) {

0 commit comments

Comments
 (0)