1254721Semaste//===-- DWARFExpression.cpp -------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Expression/DWARFExpression.h" 11254721Semaste 12254721Semaste#include <vector> 13254721Semaste 14254721Semaste#include "lldb/Core/DataEncoder.h" 15254721Semaste#include "lldb/Core/dwarf.h" 16254721Semaste#include "lldb/Core/Log.h" 17254721Semaste#include "lldb/Core/RegisterValue.h" 18254721Semaste#include "lldb/Core/StreamString.h" 19254721Semaste#include "lldb/Core/Scalar.h" 20254721Semaste#include "lldb/Core/Value.h" 21254721Semaste#include "lldb/Core/VMRange.h" 22254721Semaste 23254721Semaste#include "lldb/Expression/ClangExpressionDeclMap.h" 24254721Semaste#include "lldb/Expression/ClangExpressionVariable.h" 25254721Semaste 26254721Semaste#include "lldb/Host/Endian.h" 27254721Semaste#include "lldb/Host/Host.h" 28254721Semaste 29254721Semaste#include "lldb/lldb-private-log.h" 30254721Semaste 31254721Semaste#include "lldb/Symbol/ClangASTType.h" 32254721Semaste#include "lldb/Symbol/ClangASTContext.h" 33254721Semaste#include "lldb/Symbol/Type.h" 34254721Semaste 35254721Semaste#include "lldb/Target/ABI.h" 36254721Semaste#include "lldb/Target/ExecutionContext.h" 37254721Semaste#include "lldb/Target/Process.h" 38254721Semaste#include "lldb/Target/RegisterContext.h" 39254721Semaste#include "lldb/Target/StackFrame.h" 40254721Semaste#include "lldb/Target/StackID.h" 41254721Semaste 42254721Semasteusing namespace lldb; 43254721Semasteusing namespace lldb_private; 44254721Semaste 45254721Semasteconst char * 46254721SemasteDW_OP_value_to_name (uint32_t val) 47254721Semaste{ 48254721Semaste static char invalid[100]; 49254721Semaste switch (val) { 50254721Semaste case 0x03: return "DW_OP_addr"; 51254721Semaste case 0x06: return "DW_OP_deref"; 52254721Semaste case 0x08: return "DW_OP_const1u"; 53254721Semaste case 0x09: return "DW_OP_const1s"; 54254721Semaste case 0x0a: return "DW_OP_const2u"; 55254721Semaste case 0x0b: return "DW_OP_const2s"; 56254721Semaste case 0x0c: return "DW_OP_const4u"; 57254721Semaste case 0x0d: return "DW_OP_const4s"; 58254721Semaste case 0x0e: return "DW_OP_const8u"; 59254721Semaste case 0x0f: return "DW_OP_const8s"; 60254721Semaste case 0x10: return "DW_OP_constu"; 61254721Semaste case 0x11: return "DW_OP_consts"; 62254721Semaste case 0x12: return "DW_OP_dup"; 63254721Semaste case 0x13: return "DW_OP_drop"; 64254721Semaste case 0x14: return "DW_OP_over"; 65254721Semaste case 0x15: return "DW_OP_pick"; 66254721Semaste case 0x16: return "DW_OP_swap"; 67254721Semaste case 0x17: return "DW_OP_rot"; 68254721Semaste case 0x18: return "DW_OP_xderef"; 69254721Semaste case 0x19: return "DW_OP_abs"; 70254721Semaste case 0x1a: return "DW_OP_and"; 71254721Semaste case 0x1b: return "DW_OP_div"; 72254721Semaste case 0x1c: return "DW_OP_minus"; 73254721Semaste case 0x1d: return "DW_OP_mod"; 74254721Semaste case 0x1e: return "DW_OP_mul"; 75254721Semaste case 0x1f: return "DW_OP_neg"; 76254721Semaste case 0x20: return "DW_OP_not"; 77254721Semaste case 0x21: return "DW_OP_or"; 78254721Semaste case 0x22: return "DW_OP_plus"; 79254721Semaste case 0x23: return "DW_OP_plus_uconst"; 80254721Semaste case 0x24: return "DW_OP_shl"; 81254721Semaste case 0x25: return "DW_OP_shr"; 82254721Semaste case 0x26: return "DW_OP_shra"; 83254721Semaste case 0x27: return "DW_OP_xor"; 84254721Semaste case 0x2f: return "DW_OP_skip"; 85254721Semaste case 0x28: return "DW_OP_bra"; 86254721Semaste case 0x29: return "DW_OP_eq"; 87254721Semaste case 0x2a: return "DW_OP_ge"; 88254721Semaste case 0x2b: return "DW_OP_gt"; 89254721Semaste case 0x2c: return "DW_OP_le"; 90254721Semaste case 0x2d: return "DW_OP_lt"; 91254721Semaste case 0x2e: return "DW_OP_ne"; 92254721Semaste case 0x30: return "DW_OP_lit0"; 93254721Semaste case 0x31: return "DW_OP_lit1"; 94254721Semaste case 0x32: return "DW_OP_lit2"; 95254721Semaste case 0x33: return "DW_OP_lit3"; 96254721Semaste case 0x34: return "DW_OP_lit4"; 97254721Semaste case 0x35: return "DW_OP_lit5"; 98254721Semaste case 0x36: return "DW_OP_lit6"; 99254721Semaste case 0x37: return "DW_OP_lit7"; 100254721Semaste case 0x38: return "DW_OP_lit8"; 101254721Semaste case 0x39: return "DW_OP_lit9"; 102254721Semaste case 0x3a: return "DW_OP_lit10"; 103254721Semaste case 0x3b: return "DW_OP_lit11"; 104254721Semaste case 0x3c: return "DW_OP_lit12"; 105254721Semaste case 0x3d: return "DW_OP_lit13"; 106254721Semaste case 0x3e: return "DW_OP_lit14"; 107254721Semaste case 0x3f: return "DW_OP_lit15"; 108254721Semaste case 0x40: return "DW_OP_lit16"; 109254721Semaste case 0x41: return "DW_OP_lit17"; 110254721Semaste case 0x42: return "DW_OP_lit18"; 111254721Semaste case 0x43: return "DW_OP_lit19"; 112254721Semaste case 0x44: return "DW_OP_lit20"; 113254721Semaste case 0x45: return "DW_OP_lit21"; 114254721Semaste case 0x46: return "DW_OP_lit22"; 115254721Semaste case 0x47: return "DW_OP_lit23"; 116254721Semaste case 0x48: return "DW_OP_lit24"; 117254721Semaste case 0x49: return "DW_OP_lit25"; 118254721Semaste case 0x4a: return "DW_OP_lit26"; 119254721Semaste case 0x4b: return "DW_OP_lit27"; 120254721Semaste case 0x4c: return "DW_OP_lit28"; 121254721Semaste case 0x4d: return "DW_OP_lit29"; 122254721Semaste case 0x4e: return "DW_OP_lit30"; 123254721Semaste case 0x4f: return "DW_OP_lit31"; 124254721Semaste case 0x50: return "DW_OP_reg0"; 125254721Semaste case 0x51: return "DW_OP_reg1"; 126254721Semaste case 0x52: return "DW_OP_reg2"; 127254721Semaste case 0x53: return "DW_OP_reg3"; 128254721Semaste case 0x54: return "DW_OP_reg4"; 129254721Semaste case 0x55: return "DW_OP_reg5"; 130254721Semaste case 0x56: return "DW_OP_reg6"; 131254721Semaste case 0x57: return "DW_OP_reg7"; 132254721Semaste case 0x58: return "DW_OP_reg8"; 133254721Semaste case 0x59: return "DW_OP_reg9"; 134254721Semaste case 0x5a: return "DW_OP_reg10"; 135254721Semaste case 0x5b: return "DW_OP_reg11"; 136254721Semaste case 0x5c: return "DW_OP_reg12"; 137254721Semaste case 0x5d: return "DW_OP_reg13"; 138254721Semaste case 0x5e: return "DW_OP_reg14"; 139254721Semaste case 0x5f: return "DW_OP_reg15"; 140254721Semaste case 0x60: return "DW_OP_reg16"; 141254721Semaste case 0x61: return "DW_OP_reg17"; 142254721Semaste case 0x62: return "DW_OP_reg18"; 143254721Semaste case 0x63: return "DW_OP_reg19"; 144254721Semaste case 0x64: return "DW_OP_reg20"; 145254721Semaste case 0x65: return "DW_OP_reg21"; 146254721Semaste case 0x66: return "DW_OP_reg22"; 147254721Semaste case 0x67: return "DW_OP_reg23"; 148254721Semaste case 0x68: return "DW_OP_reg24"; 149254721Semaste case 0x69: return "DW_OP_reg25"; 150254721Semaste case 0x6a: return "DW_OP_reg26"; 151254721Semaste case 0x6b: return "DW_OP_reg27"; 152254721Semaste case 0x6c: return "DW_OP_reg28"; 153254721Semaste case 0x6d: return "DW_OP_reg29"; 154254721Semaste case 0x6e: return "DW_OP_reg30"; 155254721Semaste case 0x6f: return "DW_OP_reg31"; 156254721Semaste case 0x70: return "DW_OP_breg0"; 157254721Semaste case 0x71: return "DW_OP_breg1"; 158254721Semaste case 0x72: return "DW_OP_breg2"; 159254721Semaste case 0x73: return "DW_OP_breg3"; 160254721Semaste case 0x74: return "DW_OP_breg4"; 161254721Semaste case 0x75: return "DW_OP_breg5"; 162254721Semaste case 0x76: return "DW_OP_breg6"; 163254721Semaste case 0x77: return "DW_OP_breg7"; 164254721Semaste case 0x78: return "DW_OP_breg8"; 165254721Semaste case 0x79: return "DW_OP_breg9"; 166254721Semaste case 0x7a: return "DW_OP_breg10"; 167254721Semaste case 0x7b: return "DW_OP_breg11"; 168254721Semaste case 0x7c: return "DW_OP_breg12"; 169254721Semaste case 0x7d: return "DW_OP_breg13"; 170254721Semaste case 0x7e: return "DW_OP_breg14"; 171254721Semaste case 0x7f: return "DW_OP_breg15"; 172254721Semaste case 0x80: return "DW_OP_breg16"; 173254721Semaste case 0x81: return "DW_OP_breg17"; 174254721Semaste case 0x82: return "DW_OP_breg18"; 175254721Semaste case 0x83: return "DW_OP_breg19"; 176254721Semaste case 0x84: return "DW_OP_breg20"; 177254721Semaste case 0x85: return "DW_OP_breg21"; 178254721Semaste case 0x86: return "DW_OP_breg22"; 179254721Semaste case 0x87: return "DW_OP_breg23"; 180254721Semaste case 0x88: return "DW_OP_breg24"; 181254721Semaste case 0x89: return "DW_OP_breg25"; 182254721Semaste case 0x8a: return "DW_OP_breg26"; 183254721Semaste case 0x8b: return "DW_OP_breg27"; 184254721Semaste case 0x8c: return "DW_OP_breg28"; 185254721Semaste case 0x8d: return "DW_OP_breg29"; 186254721Semaste case 0x8e: return "DW_OP_breg30"; 187254721Semaste case 0x8f: return "DW_OP_breg31"; 188254721Semaste case 0x90: return "DW_OP_regx"; 189254721Semaste case 0x91: return "DW_OP_fbreg"; 190254721Semaste case 0x92: return "DW_OP_bregx"; 191254721Semaste case 0x93: return "DW_OP_piece"; 192254721Semaste case 0x94: return "DW_OP_deref_size"; 193254721Semaste case 0x95: return "DW_OP_xderef_size"; 194254721Semaste case 0x96: return "DW_OP_nop"; 195254721Semaste case 0x97: return "DW_OP_push_object_address"; 196254721Semaste case 0x98: return "DW_OP_call2"; 197254721Semaste case 0x99: return "DW_OP_call4"; 198254721Semaste case 0x9a: return "DW_OP_call_ref"; 199254721Semaste// case DW_OP_APPLE_array_ref: return "DW_OP_APPLE_array_ref"; 200254721Semaste// case DW_OP_APPLE_extern: return "DW_OP_APPLE_extern"; 201254721Semaste case DW_OP_APPLE_uninit: return "DW_OP_APPLE_uninit"; 202254721Semaste// case DW_OP_APPLE_assign: return "DW_OP_APPLE_assign"; 203254721Semaste// case DW_OP_APPLE_address_of: return "DW_OP_APPLE_address_of"; 204254721Semaste// case DW_OP_APPLE_value_of: return "DW_OP_APPLE_value_of"; 205254721Semaste// case DW_OP_APPLE_deref_type: return "DW_OP_APPLE_deref_type"; 206254721Semaste// case DW_OP_APPLE_expr_local: return "DW_OP_APPLE_expr_local"; 207254721Semaste// case DW_OP_APPLE_constf: return "DW_OP_APPLE_constf"; 208254721Semaste// case DW_OP_APPLE_scalar_cast: return "DW_OP_APPLE_scalar_cast"; 209254721Semaste// case DW_OP_APPLE_clang_cast: return "DW_OP_APPLE_clang_cast"; 210254721Semaste// case DW_OP_APPLE_clear: return "DW_OP_APPLE_clear"; 211254721Semaste// case DW_OP_APPLE_error: return "DW_OP_APPLE_error"; 212254721Semaste default: 213254721Semaste snprintf (invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val); 214254721Semaste return invalid; 215254721Semaste } 216254721Semaste} 217254721Semaste 218254721Semaste 219254721Semaste//---------------------------------------------------------------------- 220254721Semaste// DWARFExpression constructor 221254721Semaste//---------------------------------------------------------------------- 222254721SemasteDWARFExpression::DWARFExpression() : 223254721Semaste m_data(), 224254721Semaste m_reg_kind (eRegisterKindDWARF), 225254721Semaste m_loclist_slide (LLDB_INVALID_ADDRESS) 226254721Semaste{ 227254721Semaste} 228254721Semaste 229254721SemasteDWARFExpression::DWARFExpression(const DWARFExpression& rhs) : 230254721Semaste m_data(rhs.m_data), 231254721Semaste m_reg_kind (rhs.m_reg_kind), 232254721Semaste m_loclist_slide(rhs.m_loclist_slide) 233254721Semaste{ 234254721Semaste} 235254721Semaste 236254721Semaste 237254721SemasteDWARFExpression::DWARFExpression(const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) : 238254721Semaste m_data(data, data_offset, data_length), 239254721Semaste m_reg_kind (eRegisterKindDWARF), 240254721Semaste m_loclist_slide(LLDB_INVALID_ADDRESS) 241254721Semaste{ 242254721Semaste} 243254721Semaste 244254721Semaste//---------------------------------------------------------------------- 245254721Semaste// Destructor 246254721Semaste//---------------------------------------------------------------------- 247254721SemasteDWARFExpression::~DWARFExpression() 248254721Semaste{ 249254721Semaste} 250254721Semaste 251254721Semaste 252254721Semastebool 253254721SemasteDWARFExpression::IsValid() const 254254721Semaste{ 255254721Semaste return m_data.GetByteSize() > 0; 256254721Semaste} 257254721Semaste 258254721Semastevoid 259254721SemasteDWARFExpression::SetOpcodeData (const DataExtractor& data) 260254721Semaste{ 261254721Semaste m_data = data; 262254721Semaste} 263254721Semaste 264254721Semastevoid 265254721SemasteDWARFExpression::CopyOpcodeData (const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) 266254721Semaste{ 267254721Semaste const uint8_t *bytes = data.PeekData(data_offset, data_length); 268254721Semaste if (bytes) 269254721Semaste { 270254721Semaste m_data.SetData(DataBufferSP(new DataBufferHeap(bytes, data_length))); 271254721Semaste m_data.SetByteOrder(data.GetByteOrder()); 272254721Semaste m_data.SetAddressByteSize(data.GetAddressByteSize()); 273254721Semaste } 274254721Semaste} 275254721Semaste 276254721Semastevoid 277254721SemasteDWARFExpression::SetOpcodeData (const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) 278254721Semaste{ 279254721Semaste m_data.SetData(data, data_offset, data_length); 280254721Semaste} 281254721Semaste 282254721Semastevoid 283254721SemasteDWARFExpression::DumpLocation (Stream *s, lldb::offset_t offset, lldb::offset_t length, lldb::DescriptionLevel level, ABI *abi) const 284254721Semaste{ 285254721Semaste if (!m_data.ValidOffsetForDataOfSize(offset, length)) 286254721Semaste return; 287254721Semaste const lldb::offset_t start_offset = offset; 288254721Semaste const lldb::offset_t end_offset = offset + length; 289254721Semaste while (m_data.ValidOffset(offset) && offset < end_offset) 290254721Semaste { 291254721Semaste const lldb::offset_t op_offset = offset; 292254721Semaste const uint8_t op = m_data.GetU8(&offset); 293254721Semaste 294254721Semaste switch (level) 295254721Semaste { 296254721Semaste default: 297254721Semaste break; 298254721Semaste 299254721Semaste case lldb::eDescriptionLevelBrief: 300254721Semaste if (offset > start_offset) 301254721Semaste s->PutChar(' '); 302254721Semaste break; 303254721Semaste 304254721Semaste case lldb::eDescriptionLevelFull: 305254721Semaste case lldb::eDescriptionLevelVerbose: 306254721Semaste if (offset > start_offset) 307254721Semaste s->EOL(); 308254721Semaste s->Indent(); 309254721Semaste if (level == lldb::eDescriptionLevelFull) 310254721Semaste break; 311254721Semaste // Fall through for verbose and print offset and DW_OP prefix.. 312254721Semaste s->Printf("0x%8.8" PRIx64 ": %s", op_offset, op >= DW_OP_APPLE_uninit ? "DW_OP_APPLE_" : "DW_OP_"); 313254721Semaste break; 314254721Semaste } 315254721Semaste 316254721Semaste switch (op) 317254721Semaste { 318254721Semaste case DW_OP_addr: *s << "DW_OP_addr(" << m_data.GetAddress(&offset) << ") "; break; // 0x03 1 address 319254721Semaste case DW_OP_deref: *s << "DW_OP_deref"; break; // 0x06 320254721Semaste case DW_OP_const1u: s->Printf("DW_OP_const1u(0x%2.2x) ", m_data.GetU8(&offset)); break; // 0x08 1 1-byte constant 321254721Semaste case DW_OP_const1s: s->Printf("DW_OP_const1s(0x%2.2x) ", m_data.GetU8(&offset)); break; // 0x09 1 1-byte constant 322254721Semaste case DW_OP_const2u: s->Printf("DW_OP_const2u(0x%4.4x) ", m_data.GetU16(&offset)); break; // 0x0a 1 2-byte constant 323254721Semaste case DW_OP_const2s: s->Printf("DW_OP_const2s(0x%4.4x) ", m_data.GetU16(&offset)); break; // 0x0b 1 2-byte constant 324254721Semaste case DW_OP_const4u: s->Printf("DW_OP_const4u(0x%8.8x) ", m_data.GetU32(&offset)); break; // 0x0c 1 4-byte constant 325254721Semaste case DW_OP_const4s: s->Printf("DW_OP_const4s(0x%8.8x) ", m_data.GetU32(&offset)); break; // 0x0d 1 4-byte constant 326254721Semaste case DW_OP_const8u: s->Printf("DW_OP_const8u(0x%16.16" PRIx64 ") ", m_data.GetU64(&offset)); break; // 0x0e 1 8-byte constant 327254721Semaste case DW_OP_const8s: s->Printf("DW_OP_const8s(0x%16.16" PRIx64 ") ", m_data.GetU64(&offset)); break; // 0x0f 1 8-byte constant 328254721Semaste case DW_OP_constu: s->Printf("DW_OP_constu(0x%" PRIx64 ") ", m_data.GetULEB128(&offset)); break; // 0x10 1 ULEB128 constant 329254721Semaste case DW_OP_consts: s->Printf("DW_OP_consts(0x%" PRId64 ") ", m_data.GetSLEB128(&offset)); break; // 0x11 1 SLEB128 constant 330254721Semaste case DW_OP_dup: s->PutCString("DW_OP_dup"); break; // 0x12 331254721Semaste case DW_OP_drop: s->PutCString("DW_OP_drop"); break; // 0x13 332254721Semaste case DW_OP_over: s->PutCString("DW_OP_over"); break; // 0x14 333254721Semaste case DW_OP_pick: s->Printf("DW_OP_pick(0x%2.2x) ", m_data.GetU8(&offset)); break; // 0x15 1 1-byte stack index 334254721Semaste case DW_OP_swap: s->PutCString("DW_OP_swap"); break; // 0x16 335254721Semaste case DW_OP_rot: s->PutCString("DW_OP_rot"); break; // 0x17 336254721Semaste case DW_OP_xderef: s->PutCString("DW_OP_xderef"); break; // 0x18 337254721Semaste case DW_OP_abs: s->PutCString("DW_OP_abs"); break; // 0x19 338254721Semaste case DW_OP_and: s->PutCString("DW_OP_and"); break; // 0x1a 339254721Semaste case DW_OP_div: s->PutCString("DW_OP_div"); break; // 0x1b 340254721Semaste case DW_OP_minus: s->PutCString("DW_OP_minus"); break; // 0x1c 341254721Semaste case DW_OP_mod: s->PutCString("DW_OP_mod"); break; // 0x1d 342254721Semaste case DW_OP_mul: s->PutCString("DW_OP_mul"); break; // 0x1e 343254721Semaste case DW_OP_neg: s->PutCString("DW_OP_neg"); break; // 0x1f 344254721Semaste case DW_OP_not: s->PutCString("DW_OP_not"); break; // 0x20 345254721Semaste case DW_OP_or: s->PutCString("DW_OP_or"); break; // 0x21 346254721Semaste case DW_OP_plus: s->PutCString("DW_OP_plus"); break; // 0x22 347254721Semaste case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend 348254721Semaste s->Printf("DW_OP_plus_uconst(0x%" PRIx64 ") ", m_data.GetULEB128(&offset)); 349254721Semaste break; 350254721Semaste 351254721Semaste case DW_OP_shl: s->PutCString("DW_OP_shl"); break; // 0x24 352254721Semaste case DW_OP_shr: s->PutCString("DW_OP_shr"); break; // 0x25 353254721Semaste case DW_OP_shra: s->PutCString("DW_OP_shra"); break; // 0x26 354254721Semaste case DW_OP_xor: s->PutCString("DW_OP_xor"); break; // 0x27 355254721Semaste case DW_OP_skip: s->Printf("DW_OP_skip(0x%4.4x)", m_data.GetU16(&offset)); break; // 0x2f 1 signed 2-byte constant 356254721Semaste case DW_OP_bra: s->Printf("DW_OP_bra(0x%4.4x)", m_data.GetU16(&offset)); break; // 0x28 1 signed 2-byte constant 357254721Semaste case DW_OP_eq: s->PutCString("DW_OP_eq"); break; // 0x29 358254721Semaste case DW_OP_ge: s->PutCString("DW_OP_ge"); break; // 0x2a 359254721Semaste case DW_OP_gt: s->PutCString("DW_OP_gt"); break; // 0x2b 360254721Semaste case DW_OP_le: s->PutCString("DW_OP_le"); break; // 0x2c 361254721Semaste case DW_OP_lt: s->PutCString("DW_OP_lt"); break; // 0x2d 362254721Semaste case DW_OP_ne: s->PutCString("DW_OP_ne"); break; // 0x2e 363254721Semaste 364254721Semaste case DW_OP_lit0: // 0x30 365254721Semaste case DW_OP_lit1: // 0x31 366254721Semaste case DW_OP_lit2: // 0x32 367254721Semaste case DW_OP_lit3: // 0x33 368254721Semaste case DW_OP_lit4: // 0x34 369254721Semaste case DW_OP_lit5: // 0x35 370254721Semaste case DW_OP_lit6: // 0x36 371254721Semaste case DW_OP_lit7: // 0x37 372254721Semaste case DW_OP_lit8: // 0x38 373254721Semaste case DW_OP_lit9: // 0x39 374254721Semaste case DW_OP_lit10: // 0x3A 375254721Semaste case DW_OP_lit11: // 0x3B 376254721Semaste case DW_OP_lit12: // 0x3C 377254721Semaste case DW_OP_lit13: // 0x3D 378254721Semaste case DW_OP_lit14: // 0x3E 379254721Semaste case DW_OP_lit15: // 0x3F 380254721Semaste case DW_OP_lit16: // 0x40 381254721Semaste case DW_OP_lit17: // 0x41 382254721Semaste case DW_OP_lit18: // 0x42 383254721Semaste case DW_OP_lit19: // 0x43 384254721Semaste case DW_OP_lit20: // 0x44 385254721Semaste case DW_OP_lit21: // 0x45 386254721Semaste case DW_OP_lit22: // 0x46 387254721Semaste case DW_OP_lit23: // 0x47 388254721Semaste case DW_OP_lit24: // 0x48 389254721Semaste case DW_OP_lit25: // 0x49 390254721Semaste case DW_OP_lit26: // 0x4A 391254721Semaste case DW_OP_lit27: // 0x4B 392254721Semaste case DW_OP_lit28: // 0x4C 393254721Semaste case DW_OP_lit29: // 0x4D 394254721Semaste case DW_OP_lit30: // 0x4E 395254721Semaste case DW_OP_lit31: s->Printf("DW_OP_lit%i", op - DW_OP_lit0); break; // 0x4f 396254721Semaste 397254721Semaste case DW_OP_reg0: // 0x50 398254721Semaste case DW_OP_reg1: // 0x51 399254721Semaste case DW_OP_reg2: // 0x52 400254721Semaste case DW_OP_reg3: // 0x53 401254721Semaste case DW_OP_reg4: // 0x54 402254721Semaste case DW_OP_reg5: // 0x55 403254721Semaste case DW_OP_reg6: // 0x56 404254721Semaste case DW_OP_reg7: // 0x57 405254721Semaste case DW_OP_reg8: // 0x58 406254721Semaste case DW_OP_reg9: // 0x59 407254721Semaste case DW_OP_reg10: // 0x5A 408254721Semaste case DW_OP_reg11: // 0x5B 409254721Semaste case DW_OP_reg12: // 0x5C 410254721Semaste case DW_OP_reg13: // 0x5D 411254721Semaste case DW_OP_reg14: // 0x5E 412254721Semaste case DW_OP_reg15: // 0x5F 413254721Semaste case DW_OP_reg16: // 0x60 414254721Semaste case DW_OP_reg17: // 0x61 415254721Semaste case DW_OP_reg18: // 0x62 416254721Semaste case DW_OP_reg19: // 0x63 417254721Semaste case DW_OP_reg20: // 0x64 418254721Semaste case DW_OP_reg21: // 0x65 419254721Semaste case DW_OP_reg22: // 0x66 420254721Semaste case DW_OP_reg23: // 0x67 421254721Semaste case DW_OP_reg24: // 0x68 422254721Semaste case DW_OP_reg25: // 0x69 423254721Semaste case DW_OP_reg26: // 0x6A 424254721Semaste case DW_OP_reg27: // 0x6B 425254721Semaste case DW_OP_reg28: // 0x6C 426254721Semaste case DW_OP_reg29: // 0x6D 427254721Semaste case DW_OP_reg30: // 0x6E 428254721Semaste case DW_OP_reg31: // 0x6F 429254721Semaste { 430254721Semaste uint32_t reg_num = op - DW_OP_reg0; 431254721Semaste if (abi) 432254721Semaste { 433254721Semaste RegisterInfo reg_info; 434254721Semaste if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) 435254721Semaste { 436254721Semaste if (reg_info.name) 437254721Semaste { 438254721Semaste s->PutCString (reg_info.name); 439254721Semaste break; 440254721Semaste } 441254721Semaste else if (reg_info.alt_name) 442254721Semaste { 443254721Semaste s->PutCString (reg_info.alt_name); 444254721Semaste break; 445254721Semaste } 446254721Semaste } 447254721Semaste } 448254721Semaste s->Printf("DW_OP_reg%u", reg_num); break; 449254721Semaste } 450254721Semaste break; 451254721Semaste 452254721Semaste case DW_OP_breg0: 453254721Semaste case DW_OP_breg1: 454254721Semaste case DW_OP_breg2: 455254721Semaste case DW_OP_breg3: 456254721Semaste case DW_OP_breg4: 457254721Semaste case DW_OP_breg5: 458254721Semaste case DW_OP_breg6: 459254721Semaste case DW_OP_breg7: 460254721Semaste case DW_OP_breg8: 461254721Semaste case DW_OP_breg9: 462254721Semaste case DW_OP_breg10: 463254721Semaste case DW_OP_breg11: 464254721Semaste case DW_OP_breg12: 465254721Semaste case DW_OP_breg13: 466254721Semaste case DW_OP_breg14: 467254721Semaste case DW_OP_breg15: 468254721Semaste case DW_OP_breg16: 469254721Semaste case DW_OP_breg17: 470254721Semaste case DW_OP_breg18: 471254721Semaste case DW_OP_breg19: 472254721Semaste case DW_OP_breg20: 473254721Semaste case DW_OP_breg21: 474254721Semaste case DW_OP_breg22: 475254721Semaste case DW_OP_breg23: 476254721Semaste case DW_OP_breg24: 477254721Semaste case DW_OP_breg25: 478254721Semaste case DW_OP_breg26: 479254721Semaste case DW_OP_breg27: 480254721Semaste case DW_OP_breg28: 481254721Semaste case DW_OP_breg29: 482254721Semaste case DW_OP_breg30: 483254721Semaste case DW_OP_breg31: 484254721Semaste { 485254721Semaste uint32_t reg_num = op - DW_OP_breg0; 486254721Semaste int64_t reg_offset = m_data.GetSLEB128(&offset); 487254721Semaste if (abi) 488254721Semaste { 489254721Semaste RegisterInfo reg_info; 490254721Semaste if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) 491254721Semaste { 492254721Semaste if (reg_info.name) 493254721Semaste { 494254721Semaste s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset); 495254721Semaste break; 496254721Semaste } 497254721Semaste else if (reg_info.alt_name) 498254721Semaste { 499254721Semaste s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset); 500254721Semaste break; 501254721Semaste } 502254721Semaste } 503254721Semaste } 504254721Semaste s->Printf("DW_OP_breg%i(0x%" PRIx64 ")", reg_num, reg_offset); 505254721Semaste } 506254721Semaste break; 507254721Semaste 508254721Semaste case DW_OP_regx: // 0x90 1 ULEB128 register 509254721Semaste { 510254721Semaste uint32_t reg_num = m_data.GetULEB128(&offset); 511254721Semaste if (abi) 512254721Semaste { 513254721Semaste RegisterInfo reg_info; 514254721Semaste if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) 515254721Semaste { 516254721Semaste if (reg_info.name) 517254721Semaste { 518254721Semaste s->PutCString (reg_info.name); 519254721Semaste break; 520254721Semaste } 521254721Semaste else if (reg_info.alt_name) 522254721Semaste { 523254721Semaste s->PutCString (reg_info.alt_name); 524254721Semaste break; 525254721Semaste } 526254721Semaste } 527254721Semaste } 528254721Semaste s->Printf("DW_OP_regx(%" PRIu32 ")", reg_num); break; 529254721Semaste } 530254721Semaste break; 531254721Semaste case DW_OP_fbreg: // 0x91 1 SLEB128 offset 532254721Semaste s->Printf("DW_OP_fbreg(%" PRIi64 ")",m_data.GetSLEB128(&offset)); 533254721Semaste break; 534254721Semaste case DW_OP_bregx: // 0x92 2 ULEB128 register followed by SLEB128 offset 535254721Semaste { 536254721Semaste uint32_t reg_num = m_data.GetULEB128(&offset); 537254721Semaste int64_t reg_offset = m_data.GetSLEB128(&offset); 538254721Semaste if (abi) 539254721Semaste { 540254721Semaste RegisterInfo reg_info; 541254721Semaste if (abi->GetRegisterInfoByKind(m_reg_kind, reg_num, reg_info)) 542254721Semaste { 543254721Semaste if (reg_info.name) 544254721Semaste { 545254721Semaste s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset); 546254721Semaste break; 547254721Semaste } 548254721Semaste else if (reg_info.alt_name) 549254721Semaste { 550254721Semaste s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset); 551254721Semaste break; 552254721Semaste } 553254721Semaste } 554254721Semaste } 555254721Semaste s->Printf("DW_OP_bregx(reg=%" PRIu32 ",offset=%" PRIi64 ")", reg_num, reg_offset); 556254721Semaste } 557254721Semaste break; 558254721Semaste case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed 559254721Semaste s->Printf("DW_OP_piece(0x%" PRIx64 ")", m_data.GetULEB128(&offset)); 560254721Semaste break; 561254721Semaste case DW_OP_deref_size: // 0x94 1 1-byte size of data retrieved 562254721Semaste s->Printf("DW_OP_deref_size(0x%2.2x)", m_data.GetU8(&offset)); 563254721Semaste break; 564254721Semaste case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved 565254721Semaste s->Printf("DW_OP_xderef_size(0x%2.2x)", m_data.GetU8(&offset)); 566254721Semaste break; 567254721Semaste case DW_OP_nop: s->PutCString("DW_OP_nop"); break; // 0x96 568254721Semaste case DW_OP_push_object_address: s->PutCString("DW_OP_push_object_address"); break; // 0x97 DWARF3 569254721Semaste case DW_OP_call2: // 0x98 DWARF3 1 2-byte offset of DIE 570254721Semaste s->Printf("DW_OP_call2(0x%4.4x)", m_data.GetU16(&offset)); 571254721Semaste break; 572254721Semaste case DW_OP_call4: // 0x99 DWARF3 1 4-byte offset of DIE 573254721Semaste s->Printf("DW_OP_call4(0x%8.8x)", m_data.GetU32(&offset)); 574254721Semaste break; 575254721Semaste case DW_OP_call_ref: // 0x9a DWARF3 1 4- or 8-byte offset of DIE 576254721Semaste s->Printf("DW_OP_call_ref(0x%8.8" PRIx64 ")", m_data.GetAddress(&offset)); 577254721Semaste break; 578254721Semaste// case DW_OP_form_tls_address: s << "form_tls_address"; break; // 0x9b DWARF3 579254721Semaste// case DW_OP_call_frame_cfa: s << "call_frame_cfa"; break; // 0x9c DWARF3 580254721Semaste// case DW_OP_bit_piece: // 0x9d DWARF3 2 581254721Semaste// s->Printf("DW_OP_bit_piece(0x%x, 0x%x)", m_data.GetULEB128(&offset), m_data.GetULEB128(&offset)); 582254721Semaste// break; 583254721Semaste// case DW_OP_lo_user: s->PutCString("DW_OP_lo_user"); break; // 0xe0 584254721Semaste// case DW_OP_hi_user: s->PutCString("DW_OP_hi_user"); break; // 0xff 585254721Semaste// case DW_OP_APPLE_extern: 586254721Semaste// s->Printf("DW_OP_APPLE_extern(%" PRIu64 ")", m_data.GetULEB128(&offset)); 587254721Semaste// break; 588254721Semaste// case DW_OP_APPLE_array_ref: 589254721Semaste// s->PutCString("DW_OP_APPLE_array_ref"); 590254721Semaste// break; 591254721Semaste case DW_OP_APPLE_uninit: 592254721Semaste s->PutCString("DW_OP_APPLE_uninit"); // 0xF0 593254721Semaste break; 594254721Semaste// case DW_OP_APPLE_assign: // 0xF1 - pops value off and assigns it to second item on stack (2nd item must have assignable context) 595254721Semaste// s->PutCString("DW_OP_APPLE_assign"); 596254721Semaste// break; 597254721Semaste// case DW_OP_APPLE_address_of: // 0xF2 - gets the address of the top stack item (top item must be a variable, or have value_type that is an address already) 598254721Semaste// s->PutCString("DW_OP_APPLE_address_of"); 599254721Semaste// break; 600254721Semaste// case DW_OP_APPLE_value_of: // 0xF3 - pops the value off the stack and pushes the value of that object (top item must be a variable, or expression local) 601254721Semaste// s->PutCString("DW_OP_APPLE_value_of"); 602254721Semaste// break; 603254721Semaste// case DW_OP_APPLE_deref_type: // 0xF4 - gets the address of the top stack item (top item must be a variable, or a clang type) 604254721Semaste// s->PutCString("DW_OP_APPLE_deref_type"); 605254721Semaste// break; 606254721Semaste// case DW_OP_APPLE_expr_local: // 0xF5 - ULEB128 expression local index 607254721Semaste// s->Printf("DW_OP_APPLE_expr_local(%" PRIu64 ")", m_data.GetULEB128(&offset)); 608254721Semaste// break; 609254721Semaste// case DW_OP_APPLE_constf: // 0xF6 - 1 byte float size, followed by constant float data 610254721Semaste// { 611254721Semaste// uint8_t float_length = m_data.GetU8(&offset); 612254721Semaste// s->Printf("DW_OP_APPLE_constf(<%u> ", float_length); 613254721Semaste// m_data.Dump(s, offset, eFormatHex, float_length, 1, UINT32_MAX, DW_INVALID_ADDRESS, 0, 0); 614254721Semaste// s->PutChar(')'); 615254721Semaste// // Consume the float data 616254721Semaste// m_data.GetData(&offset, float_length); 617254721Semaste// } 618254721Semaste// break; 619254721Semaste// case DW_OP_APPLE_scalar_cast: 620254721Semaste// s->Printf("DW_OP_APPLE_scalar_cast(%s)", Scalar::GetValueTypeAsCString ((Scalar::Type)m_data.GetU8(&offset))); 621254721Semaste// break; 622254721Semaste// case DW_OP_APPLE_clang_cast: 623254721Semaste// { 624254721Semaste// clang::Type *clang_type = (clang::Type *)m_data.GetMaxU64(&offset, sizeof(void*)); 625254721Semaste// s->Printf("DW_OP_APPLE_clang_cast(%p)", clang_type); 626254721Semaste// } 627254721Semaste// break; 628254721Semaste// case DW_OP_APPLE_clear: 629254721Semaste// s->PutCString("DW_OP_APPLE_clear"); 630254721Semaste// break; 631254721Semaste// case DW_OP_APPLE_error: // 0xFF - Stops expression evaluation and returns an error (no args) 632254721Semaste// s->PutCString("DW_OP_APPLE_error"); 633254721Semaste// break; 634254721Semaste } 635254721Semaste } 636254721Semaste} 637254721Semaste 638254721Semastevoid 639254721SemasteDWARFExpression::SetLocationListSlide (addr_t slide) 640254721Semaste{ 641254721Semaste m_loclist_slide = slide; 642254721Semaste} 643254721Semaste 644254721Semasteint 645254721SemasteDWARFExpression::GetRegisterKind () 646254721Semaste{ 647254721Semaste return m_reg_kind; 648254721Semaste} 649254721Semaste 650254721Semastevoid 651254721SemasteDWARFExpression::SetRegisterKind (RegisterKind reg_kind) 652254721Semaste{ 653254721Semaste m_reg_kind = reg_kind; 654254721Semaste} 655254721Semaste 656254721Semastebool 657254721SemasteDWARFExpression::IsLocationList() const 658254721Semaste{ 659254721Semaste return m_loclist_slide != LLDB_INVALID_ADDRESS; 660254721Semaste} 661254721Semaste 662254721Semastevoid 663254721SemasteDWARFExpression::GetDescription (Stream *s, lldb::DescriptionLevel level, addr_t location_list_base_addr, ABI *abi) const 664254721Semaste{ 665254721Semaste if (IsLocationList()) 666254721Semaste { 667254721Semaste // We have a location list 668254721Semaste lldb::offset_t offset = 0; 669254721Semaste uint32_t count = 0; 670254721Semaste addr_t curr_base_addr = location_list_base_addr; 671254721Semaste while (m_data.ValidOffset(offset)) 672254721Semaste { 673254721Semaste lldb::addr_t begin_addr_offset = m_data.GetAddress(&offset); 674254721Semaste lldb::addr_t end_addr_offset = m_data.GetAddress(&offset); 675254721Semaste if (begin_addr_offset < end_addr_offset) 676254721Semaste { 677254721Semaste if (count > 0) 678254721Semaste s->PutCString(", "); 679254721Semaste VMRange addr_range(curr_base_addr + begin_addr_offset, curr_base_addr + end_addr_offset); 680254721Semaste addr_range.Dump(s, 0, 8); 681254721Semaste s->PutChar('{'); 682254721Semaste lldb::offset_t location_length = m_data.GetU16(&offset); 683254721Semaste DumpLocation (s, offset, location_length, level, abi); 684254721Semaste s->PutChar('}'); 685254721Semaste offset += location_length; 686254721Semaste } 687254721Semaste else if (begin_addr_offset == 0 && end_addr_offset == 0) 688254721Semaste { 689254721Semaste // The end of the location list is marked by both the start and end offset being zero 690254721Semaste break; 691254721Semaste } 692254721Semaste else 693254721Semaste { 694254721Semaste if ((m_data.GetAddressByteSize() == 4 && (begin_addr_offset == UINT32_MAX)) || 695254721Semaste (m_data.GetAddressByteSize() == 8 && (begin_addr_offset == UINT64_MAX))) 696254721Semaste { 697254721Semaste curr_base_addr = end_addr_offset + location_list_base_addr; 698254721Semaste // We have a new base address 699254721Semaste if (count > 0) 700254721Semaste s->PutCString(", "); 701254721Semaste *s << "base_addr = " << end_addr_offset; 702254721Semaste } 703254721Semaste } 704254721Semaste 705254721Semaste count++; 706254721Semaste } 707254721Semaste } 708254721Semaste else 709254721Semaste { 710254721Semaste // We have a normal location that contains DW_OP location opcodes 711254721Semaste DumpLocation (s, 0, m_data.GetByteSize(), level, abi); 712254721Semaste } 713254721Semaste} 714254721Semaste 715254721Semastestatic bool 716254721SemasteReadRegisterValueAsScalar 717254721Semaste( 718254721Semaste RegisterContext *reg_ctx, 719254721Semaste uint32_t reg_kind, 720254721Semaste uint32_t reg_num, 721254721Semaste Error *error_ptr, 722254721Semaste Value &value 723254721Semaste) 724254721Semaste{ 725254721Semaste if (reg_ctx == NULL) 726254721Semaste { 727254721Semaste if (error_ptr) 728254721Semaste error_ptr->SetErrorStringWithFormat("No register context in frame.\n"); 729254721Semaste } 730254721Semaste else 731254721Semaste { 732254721Semaste uint32_t native_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); 733254721Semaste if (native_reg == LLDB_INVALID_REGNUM) 734254721Semaste { 735254721Semaste if (error_ptr) 736254721Semaste error_ptr->SetErrorStringWithFormat("Unable to convert register kind=%u reg_num=%u to a native register number.\n", reg_kind, reg_num); 737254721Semaste } 738254721Semaste else 739254721Semaste { 740254721Semaste const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(native_reg); 741254721Semaste RegisterValue reg_value; 742254721Semaste if (reg_ctx->ReadRegister (reg_info, reg_value)) 743254721Semaste { 744254721Semaste if (reg_value.GetScalarValue(value.GetScalar())) 745254721Semaste { 746254721Semaste value.SetValueType (Value::eValueTypeScalar); 747254721Semaste value.SetContext (Value::eContextTypeRegisterInfo, 748254721Semaste const_cast<RegisterInfo *>(reg_info)); 749254721Semaste if (error_ptr) 750254721Semaste error_ptr->Clear(); 751254721Semaste return true; 752254721Semaste } 753254721Semaste else 754254721Semaste { 755254721Semaste // If we get this error, then we need to implement a value 756254721Semaste // buffer in the dwarf expression evaluation function... 757254721Semaste if (error_ptr) 758254721Semaste error_ptr->SetErrorStringWithFormat ("register %s can't be converted to a scalar value", 759254721Semaste reg_info->name); 760254721Semaste } 761254721Semaste } 762254721Semaste else 763254721Semaste { 764254721Semaste if (error_ptr) 765254721Semaste error_ptr->SetErrorStringWithFormat("register %s is not available", reg_info->name); 766254721Semaste } 767254721Semaste } 768254721Semaste } 769254721Semaste return false; 770254721Semaste} 771254721Semaste 772254721Semaste//bool 773254721Semaste//DWARFExpression::LocationListContainsLoadAddress (Process* process, const Address &addr) const 774254721Semaste//{ 775254721Semaste// return LocationListContainsLoadAddress(process, addr.GetLoadAddress(process)); 776254721Semaste//} 777254721Semaste// 778254721Semaste//bool 779254721Semaste//DWARFExpression::LocationListContainsLoadAddress (Process* process, addr_t load_addr) const 780254721Semaste//{ 781254721Semaste// if (load_addr == LLDB_INVALID_ADDRESS) 782254721Semaste// return false; 783254721Semaste// 784254721Semaste// if (IsLocationList()) 785254721Semaste// { 786254721Semaste// lldb::offset_t offset = 0; 787254721Semaste// 788254721Semaste// addr_t loc_list_base_addr = m_loclist_slide.GetLoadAddress(process); 789254721Semaste// 790254721Semaste// if (loc_list_base_addr == LLDB_INVALID_ADDRESS) 791254721Semaste// return false; 792254721Semaste// 793254721Semaste// while (m_data.ValidOffset(offset)) 794254721Semaste// { 795254721Semaste// // We need to figure out what the value is for the location. 796254721Semaste// addr_t lo_pc = m_data.GetAddress(&offset); 797254721Semaste// addr_t hi_pc = m_data.GetAddress(&offset); 798254721Semaste// if (lo_pc == 0 && hi_pc == 0) 799254721Semaste// break; 800254721Semaste// else 801254721Semaste// { 802254721Semaste// lo_pc += loc_list_base_addr; 803254721Semaste// hi_pc += loc_list_base_addr; 804254721Semaste// 805254721Semaste// if (lo_pc <= load_addr && load_addr < hi_pc) 806254721Semaste// return true; 807254721Semaste// 808254721Semaste// offset += m_data.GetU16(&offset); 809254721Semaste// } 810254721Semaste// } 811254721Semaste// } 812254721Semaste// return false; 813254721Semaste//} 814254721Semaste 815254721Semastestatic offset_t 816254721SemasteGetOpcodeDataSize (const DataExtractor &data, const lldb::offset_t data_offset, const uint8_t op) 817254721Semaste{ 818254721Semaste lldb::offset_t offset = data_offset; 819254721Semaste switch (op) 820254721Semaste { 821254721Semaste case DW_OP_addr: 822254721Semaste case DW_OP_call_ref: // 0x9a 1 address sized offset of DIE (DWARF3) 823254721Semaste return data.GetAddressByteSize(); 824254721Semaste 825254721Semaste // Opcodes with no arguments 826254721Semaste case DW_OP_deref: // 0x06 827254721Semaste case DW_OP_dup: // 0x12 828254721Semaste case DW_OP_drop: // 0x13 829254721Semaste case DW_OP_over: // 0x14 830254721Semaste case DW_OP_swap: // 0x16 831254721Semaste case DW_OP_rot: // 0x17 832254721Semaste case DW_OP_xderef: // 0x18 833254721Semaste case DW_OP_abs: // 0x19 834254721Semaste case DW_OP_and: // 0x1a 835254721Semaste case DW_OP_div: // 0x1b 836254721Semaste case DW_OP_minus: // 0x1c 837254721Semaste case DW_OP_mod: // 0x1d 838254721Semaste case DW_OP_mul: // 0x1e 839254721Semaste case DW_OP_neg: // 0x1f 840254721Semaste case DW_OP_not: // 0x20 841254721Semaste case DW_OP_or: // 0x21 842254721Semaste case DW_OP_plus: // 0x22 843254721Semaste case DW_OP_shl: // 0x24 844254721Semaste case DW_OP_shr: // 0x25 845254721Semaste case DW_OP_shra: // 0x26 846254721Semaste case DW_OP_xor: // 0x27 847254721Semaste case DW_OP_eq: // 0x29 848254721Semaste case DW_OP_ge: // 0x2a 849254721Semaste case DW_OP_gt: // 0x2b 850254721Semaste case DW_OP_le: // 0x2c 851254721Semaste case DW_OP_lt: // 0x2d 852254721Semaste case DW_OP_ne: // 0x2e 853254721Semaste case DW_OP_lit0: // 0x30 854254721Semaste case DW_OP_lit1: // 0x31 855254721Semaste case DW_OP_lit2: // 0x32 856254721Semaste case DW_OP_lit3: // 0x33 857254721Semaste case DW_OP_lit4: // 0x34 858254721Semaste case DW_OP_lit5: // 0x35 859254721Semaste case DW_OP_lit6: // 0x36 860254721Semaste case DW_OP_lit7: // 0x37 861254721Semaste case DW_OP_lit8: // 0x38 862254721Semaste case DW_OP_lit9: // 0x39 863254721Semaste case DW_OP_lit10: // 0x3A 864254721Semaste case DW_OP_lit11: // 0x3B 865254721Semaste case DW_OP_lit12: // 0x3C 866254721Semaste case DW_OP_lit13: // 0x3D 867254721Semaste case DW_OP_lit14: // 0x3E 868254721Semaste case DW_OP_lit15: // 0x3F 869254721Semaste case DW_OP_lit16: // 0x40 870254721Semaste case DW_OP_lit17: // 0x41 871254721Semaste case DW_OP_lit18: // 0x42 872254721Semaste case DW_OP_lit19: // 0x43 873254721Semaste case DW_OP_lit20: // 0x44 874254721Semaste case DW_OP_lit21: // 0x45 875254721Semaste case DW_OP_lit22: // 0x46 876254721Semaste case DW_OP_lit23: // 0x47 877254721Semaste case DW_OP_lit24: // 0x48 878254721Semaste case DW_OP_lit25: // 0x49 879254721Semaste case DW_OP_lit26: // 0x4A 880254721Semaste case DW_OP_lit27: // 0x4B 881254721Semaste case DW_OP_lit28: // 0x4C 882254721Semaste case DW_OP_lit29: // 0x4D 883254721Semaste case DW_OP_lit30: // 0x4E 884254721Semaste case DW_OP_lit31: // 0x4f 885254721Semaste case DW_OP_reg0: // 0x50 886254721Semaste case DW_OP_reg1: // 0x51 887254721Semaste case DW_OP_reg2: // 0x52 888254721Semaste case DW_OP_reg3: // 0x53 889254721Semaste case DW_OP_reg4: // 0x54 890254721Semaste case DW_OP_reg5: // 0x55 891254721Semaste case DW_OP_reg6: // 0x56 892254721Semaste case DW_OP_reg7: // 0x57 893254721Semaste case DW_OP_reg8: // 0x58 894254721Semaste case DW_OP_reg9: // 0x59 895254721Semaste case DW_OP_reg10: // 0x5A 896254721Semaste case DW_OP_reg11: // 0x5B 897254721Semaste case DW_OP_reg12: // 0x5C 898254721Semaste case DW_OP_reg13: // 0x5D 899254721Semaste case DW_OP_reg14: // 0x5E 900254721Semaste case DW_OP_reg15: // 0x5F 901254721Semaste case DW_OP_reg16: // 0x60 902254721Semaste case DW_OP_reg17: // 0x61 903254721Semaste case DW_OP_reg18: // 0x62 904254721Semaste case DW_OP_reg19: // 0x63 905254721Semaste case DW_OP_reg20: // 0x64 906254721Semaste case DW_OP_reg21: // 0x65 907254721Semaste case DW_OP_reg22: // 0x66 908254721Semaste case DW_OP_reg23: // 0x67 909254721Semaste case DW_OP_reg24: // 0x68 910254721Semaste case DW_OP_reg25: // 0x69 911254721Semaste case DW_OP_reg26: // 0x6A 912254721Semaste case DW_OP_reg27: // 0x6B 913254721Semaste case DW_OP_reg28: // 0x6C 914254721Semaste case DW_OP_reg29: // 0x6D 915254721Semaste case DW_OP_reg30: // 0x6E 916254721Semaste case DW_OP_reg31: // 0x6F 917254721Semaste case DW_OP_nop: // 0x96 918254721Semaste case DW_OP_push_object_address: // 0x97 DWARF3 919254721Semaste case DW_OP_form_tls_address: // 0x9b DWARF3 920254721Semaste case DW_OP_call_frame_cfa: // 0x9c DWARF3 921254721Semaste case DW_OP_stack_value: // 0x9f DWARF4 922254721Semaste return 0; 923254721Semaste 924254721Semaste // Opcodes with a single 1 byte arguments 925254721Semaste case DW_OP_const1u: // 0x08 1 1-byte constant 926254721Semaste case DW_OP_const1s: // 0x09 1 1-byte constant 927254721Semaste case DW_OP_pick: // 0x15 1 1-byte stack index 928254721Semaste case DW_OP_deref_size: // 0x94 1 1-byte size of data retrieved 929254721Semaste case DW_OP_xderef_size: // 0x95 1 1-byte size of data retrieved 930254721Semaste return 1; 931254721Semaste 932254721Semaste // Opcodes with a single 2 byte arguments 933254721Semaste case DW_OP_const2u: // 0x0a 1 2-byte constant 934254721Semaste case DW_OP_const2s: // 0x0b 1 2-byte constant 935254721Semaste case DW_OP_skip: // 0x2f 1 signed 2-byte constant 936254721Semaste case DW_OP_bra: // 0x28 1 signed 2-byte constant 937254721Semaste case DW_OP_call2: // 0x98 1 2-byte offset of DIE (DWARF3) 938254721Semaste return 2; 939254721Semaste 940254721Semaste // Opcodes with a single 4 byte arguments 941254721Semaste case DW_OP_const4u: // 0x0c 1 4-byte constant 942254721Semaste case DW_OP_const4s: // 0x0d 1 4-byte constant 943254721Semaste case DW_OP_call4: // 0x99 1 4-byte offset of DIE (DWARF3) 944254721Semaste return 4; 945254721Semaste 946254721Semaste // Opcodes with a single 8 byte arguments 947254721Semaste case DW_OP_const8u: // 0x0e 1 8-byte constant 948254721Semaste case DW_OP_const8s: // 0x0f 1 8-byte constant 949254721Semaste return 8; 950254721Semaste 951254721Semaste // All opcodes that have a single ULEB (signed or unsigned) argument 952254721Semaste case DW_OP_constu: // 0x10 1 ULEB128 constant 953254721Semaste case DW_OP_consts: // 0x11 1 SLEB128 constant 954254721Semaste case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend 955254721Semaste case DW_OP_breg0: // 0x70 1 ULEB128 register 956254721Semaste case DW_OP_breg1: // 0x71 1 ULEB128 register 957254721Semaste case DW_OP_breg2: // 0x72 1 ULEB128 register 958254721Semaste case DW_OP_breg3: // 0x73 1 ULEB128 register 959254721Semaste case DW_OP_breg4: // 0x74 1 ULEB128 register 960254721Semaste case DW_OP_breg5: // 0x75 1 ULEB128 register 961254721Semaste case DW_OP_breg6: // 0x76 1 ULEB128 register 962254721Semaste case DW_OP_breg7: // 0x77 1 ULEB128 register 963254721Semaste case DW_OP_breg8: // 0x78 1 ULEB128 register 964254721Semaste case DW_OP_breg9: // 0x79 1 ULEB128 register 965254721Semaste case DW_OP_breg10: // 0x7a 1 ULEB128 register 966254721Semaste case DW_OP_breg11: // 0x7b 1 ULEB128 register 967254721Semaste case DW_OP_breg12: // 0x7c 1 ULEB128 register 968254721Semaste case DW_OP_breg13: // 0x7d 1 ULEB128 register 969254721Semaste case DW_OP_breg14: // 0x7e 1 ULEB128 register 970254721Semaste case DW_OP_breg15: // 0x7f 1 ULEB128 register 971254721Semaste case DW_OP_breg16: // 0x80 1 ULEB128 register 972254721Semaste case DW_OP_breg17: // 0x81 1 ULEB128 register 973254721Semaste case DW_OP_breg18: // 0x82 1 ULEB128 register 974254721Semaste case DW_OP_breg19: // 0x83 1 ULEB128 register 975254721Semaste case DW_OP_breg20: // 0x84 1 ULEB128 register 976254721Semaste case DW_OP_breg21: // 0x85 1 ULEB128 register 977254721Semaste case DW_OP_breg22: // 0x86 1 ULEB128 register 978254721Semaste case DW_OP_breg23: // 0x87 1 ULEB128 register 979254721Semaste case DW_OP_breg24: // 0x88 1 ULEB128 register 980254721Semaste case DW_OP_breg25: // 0x89 1 ULEB128 register 981254721Semaste case DW_OP_breg26: // 0x8a 1 ULEB128 register 982254721Semaste case DW_OP_breg27: // 0x8b 1 ULEB128 register 983254721Semaste case DW_OP_breg28: // 0x8c 1 ULEB128 register 984254721Semaste case DW_OP_breg29: // 0x8d 1 ULEB128 register 985254721Semaste case DW_OP_breg30: // 0x8e 1 ULEB128 register 986254721Semaste case DW_OP_breg31: // 0x8f 1 ULEB128 register 987254721Semaste case DW_OP_regx: // 0x90 1 ULEB128 register 988254721Semaste case DW_OP_fbreg: // 0x91 1 SLEB128 offset 989254721Semaste case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed 990254721Semaste data.Skip_LEB128(&offset); 991254721Semaste return offset - data_offset; 992254721Semaste 993254721Semaste // All opcodes that have a 2 ULEB (signed or unsigned) arguments 994254721Semaste case DW_OP_bregx: // 0x92 2 ULEB128 register followed by SLEB128 offset 995254721Semaste case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3); 996254721Semaste data.Skip_LEB128(&offset); 997254721Semaste data.Skip_LEB128(&offset); 998254721Semaste return offset - data_offset; 999254721Semaste 1000254721Semaste case DW_OP_implicit_value: // 0x9e ULEB128 size followed by block of that size (DWARF4) 1001254721Semaste { 1002254721Semaste uint64_t block_len = data.Skip_LEB128(&offset); 1003254721Semaste offset += block_len; 1004254721Semaste return offset - data_offset; 1005254721Semaste } 1006254721Semaste 1007254721Semaste default: 1008254721Semaste break; 1009254721Semaste } 1010254721Semaste return LLDB_INVALID_OFFSET; 1011254721Semaste} 1012254721Semaste 1013254721Semastelldb::addr_t 1014254721SemasteDWARFExpression::GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const 1015254721Semaste{ 1016254721Semaste error = false; 1017254721Semaste if (IsLocationList()) 1018254721Semaste return LLDB_INVALID_ADDRESS; 1019254721Semaste lldb::offset_t offset = 0; 1020254721Semaste uint32_t curr_op_addr_idx = 0; 1021254721Semaste while (m_data.ValidOffset(offset)) 1022254721Semaste { 1023254721Semaste const uint8_t op = m_data.GetU8(&offset); 1024254721Semaste 1025254721Semaste if (op == DW_OP_addr) 1026254721Semaste { 1027254721Semaste const lldb::addr_t op_file_addr = m_data.GetAddress(&offset); 1028254721Semaste if (curr_op_addr_idx == op_addr_idx) 1029254721Semaste return op_file_addr; 1030254721Semaste else 1031254721Semaste ++curr_op_addr_idx; 1032254721Semaste } 1033254721Semaste else 1034254721Semaste { 1035254721Semaste const offset_t op_arg_size = GetOpcodeDataSize (m_data, offset, op); 1036254721Semaste if (op_arg_size == LLDB_INVALID_OFFSET) 1037254721Semaste { 1038254721Semaste error = true; 1039254721Semaste break; 1040254721Semaste } 1041254721Semaste offset += op_arg_size; 1042254721Semaste } 1043254721Semaste } 1044254721Semaste return LLDB_INVALID_ADDRESS; 1045254721Semaste} 1046254721Semaste 1047254721Semastebool 1048254721SemasteDWARFExpression::Update_DW_OP_addr (lldb::addr_t file_addr) 1049254721Semaste{ 1050254721Semaste if (IsLocationList()) 1051254721Semaste return false; 1052254721Semaste lldb::offset_t offset = 0; 1053254721Semaste while (m_data.ValidOffset(offset)) 1054254721Semaste { 1055254721Semaste const uint8_t op = m_data.GetU8(&offset); 1056254721Semaste 1057254721Semaste if (op == DW_OP_addr) 1058254721Semaste { 1059254721Semaste const uint32_t addr_byte_size = m_data.GetAddressByteSize(); 1060254721Semaste // We have to make a copy of the data as we don't know if this 1061254721Semaste // data is from a read only memory mapped buffer, so we duplicate 1062254721Semaste // all of the data first, then modify it, and if all goes well, 1063254721Semaste // we then replace the data for this expression 1064254721Semaste 1065254721Semaste // So first we copy the data into a heap buffer 1066254721Semaste std::unique_ptr<DataBufferHeap> head_data_ap (new DataBufferHeap (m_data.GetDataStart(), 1067254721Semaste m_data.GetByteSize())); 1068254721Semaste 1069254721Semaste // Make en encoder so we can write the address into the buffer using 1070254721Semaste // the correct byte order (endianness) 1071254721Semaste DataEncoder encoder (head_data_ap->GetBytes(), 1072254721Semaste head_data_ap->GetByteSize(), 1073254721Semaste m_data.GetByteOrder(), 1074254721Semaste addr_byte_size); 1075254721Semaste 1076254721Semaste // Replace the address in the new buffer 1077254721Semaste if (encoder.PutMaxU64 (offset, addr_byte_size, file_addr) == UINT32_MAX) 1078254721Semaste return false; 1079254721Semaste 1080254721Semaste // All went well, so now we can reset the data using a shared 1081254721Semaste // pointer to the heap data so "m_data" will now correctly 1082254721Semaste // manage the heap data. 1083254721Semaste m_data.SetData (DataBufferSP (head_data_ap.release())); 1084254721Semaste return true; 1085254721Semaste } 1086254721Semaste else 1087254721Semaste { 1088254721Semaste const offset_t op_arg_size = GetOpcodeDataSize (m_data, offset, op); 1089254721Semaste if (op_arg_size == LLDB_INVALID_OFFSET) 1090254721Semaste break; 1091254721Semaste offset += op_arg_size; 1092254721Semaste } 1093254721Semaste } 1094254721Semaste return false; 1095254721Semaste} 1096254721Semaste 1097254721Semastebool 1098254721SemasteDWARFExpression::LocationListContainsAddress (lldb::addr_t loclist_base_addr, lldb::addr_t addr) const 1099254721Semaste{ 1100254721Semaste if (addr == LLDB_INVALID_ADDRESS) 1101254721Semaste return false; 1102254721Semaste 1103254721Semaste if (IsLocationList()) 1104254721Semaste { 1105254721Semaste lldb::offset_t offset = 0; 1106254721Semaste 1107254721Semaste if (loclist_base_addr == LLDB_INVALID_ADDRESS) 1108254721Semaste return false; 1109254721Semaste 1110254721Semaste while (m_data.ValidOffset(offset)) 1111254721Semaste { 1112254721Semaste // We need to figure out what the value is for the location. 1113254721Semaste addr_t lo_pc = m_data.GetAddress(&offset); 1114254721Semaste addr_t hi_pc = m_data.GetAddress(&offset); 1115254721Semaste if (lo_pc == 0 && hi_pc == 0) 1116254721Semaste break; 1117254721Semaste else 1118254721Semaste { 1119254721Semaste lo_pc += loclist_base_addr - m_loclist_slide; 1120254721Semaste hi_pc += loclist_base_addr - m_loclist_slide; 1121254721Semaste 1122254721Semaste if (lo_pc <= addr && addr < hi_pc) 1123254721Semaste return true; 1124254721Semaste 1125254721Semaste offset += m_data.GetU16(&offset); 1126254721Semaste } 1127254721Semaste } 1128254721Semaste } 1129254721Semaste return false; 1130254721Semaste} 1131254721Semaste 1132254721Semastebool 1133254721SemasteDWARFExpression::GetLocation (addr_t base_addr, addr_t pc, lldb::offset_t &offset, lldb::offset_t &length) 1134254721Semaste{ 1135254721Semaste offset = 0; 1136254721Semaste if (!IsLocationList()) 1137254721Semaste { 1138254721Semaste length = m_data.GetByteSize(); 1139254721Semaste return true; 1140254721Semaste } 1141254721Semaste 1142254721Semaste if (base_addr != LLDB_INVALID_ADDRESS && pc != LLDB_INVALID_ADDRESS) 1143254721Semaste { 1144254721Semaste addr_t curr_base_addr = base_addr; 1145254721Semaste 1146254721Semaste while (m_data.ValidOffset(offset)) 1147254721Semaste { 1148254721Semaste // We need to figure out what the value is for the location. 1149254721Semaste addr_t lo_pc = m_data.GetAddress(&offset); 1150254721Semaste addr_t hi_pc = m_data.GetAddress(&offset); 1151254721Semaste if (lo_pc == 0 && hi_pc == 0) 1152254721Semaste { 1153254721Semaste break; 1154254721Semaste } 1155254721Semaste else 1156254721Semaste { 1157254721Semaste lo_pc += curr_base_addr - m_loclist_slide; 1158254721Semaste hi_pc += curr_base_addr - m_loclist_slide; 1159254721Semaste 1160254721Semaste length = m_data.GetU16(&offset); 1161254721Semaste 1162254721Semaste if (length > 0 && lo_pc <= pc && pc < hi_pc) 1163254721Semaste return true; 1164254721Semaste 1165254721Semaste offset += length; 1166254721Semaste } 1167254721Semaste } 1168254721Semaste } 1169254721Semaste offset = LLDB_INVALID_OFFSET; 1170254721Semaste length = 0; 1171254721Semaste return false; 1172254721Semaste} 1173254721Semaste 1174254721Semastebool 1175254721SemasteDWARFExpression::DumpLocationForAddress (Stream *s, 1176254721Semaste lldb::DescriptionLevel level, 1177254721Semaste addr_t base_addr, 1178254721Semaste addr_t address, 1179254721Semaste ABI *abi) 1180254721Semaste{ 1181254721Semaste lldb::offset_t offset = 0; 1182254721Semaste lldb::offset_t length = 0; 1183254721Semaste 1184254721Semaste if (GetLocation (base_addr, address, offset, length)) 1185254721Semaste { 1186254721Semaste if (length > 0) 1187254721Semaste { 1188254721Semaste DumpLocation(s, offset, length, level, abi); 1189254721Semaste return true; 1190254721Semaste } 1191254721Semaste } 1192254721Semaste return false; 1193254721Semaste} 1194254721Semaste 1195254721Semastebool 1196254721SemasteDWARFExpression::Evaluate 1197254721Semaste( 1198254721Semaste ExecutionContextScope *exe_scope, 1199254721Semaste ClangExpressionVariableList *expr_locals, 1200254721Semaste ClangExpressionDeclMap *decl_map, 1201254721Semaste lldb::addr_t loclist_base_load_addr, 1202254721Semaste const Value* initial_value_ptr, 1203254721Semaste Value& result, 1204254721Semaste Error *error_ptr 1205254721Semaste) const 1206254721Semaste{ 1207254721Semaste ExecutionContext exe_ctx (exe_scope); 1208254721Semaste return Evaluate(&exe_ctx, expr_locals, decl_map, NULL, loclist_base_load_addr, initial_value_ptr, result, error_ptr); 1209254721Semaste} 1210254721Semaste 1211254721Semastebool 1212254721SemasteDWARFExpression::Evaluate 1213254721Semaste( 1214254721Semaste ExecutionContext *exe_ctx, 1215254721Semaste ClangExpressionVariableList *expr_locals, 1216254721Semaste ClangExpressionDeclMap *decl_map, 1217254721Semaste RegisterContext *reg_ctx, 1218254721Semaste lldb::addr_t loclist_base_load_addr, 1219254721Semaste const Value* initial_value_ptr, 1220254721Semaste Value& result, 1221254721Semaste Error *error_ptr 1222254721Semaste) const 1223254721Semaste{ 1224254721Semaste if (IsLocationList()) 1225254721Semaste { 1226254721Semaste lldb::offset_t offset = 0; 1227254721Semaste addr_t pc; 1228254721Semaste StackFrame *frame = NULL; 1229254721Semaste if (reg_ctx) 1230254721Semaste pc = reg_ctx->GetPC(); 1231254721Semaste else 1232254721Semaste { 1233254721Semaste frame = exe_ctx->GetFramePtr(); 1234254721Semaste if (!frame) 1235254721Semaste return false; 1236254721Semaste RegisterContextSP reg_ctx_sp = frame->GetRegisterContext(); 1237254721Semaste if (!reg_ctx_sp) 1238254721Semaste return false; 1239254721Semaste pc = reg_ctx_sp->GetPC(); 1240254721Semaste } 1241254721Semaste 1242254721Semaste if (loclist_base_load_addr != LLDB_INVALID_ADDRESS) 1243254721Semaste { 1244254721Semaste if (pc == LLDB_INVALID_ADDRESS) 1245254721Semaste { 1246254721Semaste if (error_ptr) 1247254721Semaste error_ptr->SetErrorString("Invalid PC in frame."); 1248254721Semaste return false; 1249254721Semaste } 1250254721Semaste 1251254721Semaste addr_t curr_loclist_base_load_addr = loclist_base_load_addr; 1252254721Semaste 1253254721Semaste while (m_data.ValidOffset(offset)) 1254254721Semaste { 1255254721Semaste // We need to figure out what the value is for the location. 1256254721Semaste addr_t lo_pc = m_data.GetAddress(&offset); 1257254721Semaste addr_t hi_pc = m_data.GetAddress(&offset); 1258254721Semaste if (lo_pc == 0 && hi_pc == 0) 1259254721Semaste { 1260254721Semaste break; 1261254721Semaste } 1262254721Semaste else 1263254721Semaste { 1264254721Semaste lo_pc += curr_loclist_base_load_addr - m_loclist_slide; 1265254721Semaste hi_pc += curr_loclist_base_load_addr - m_loclist_slide; 1266254721Semaste 1267254721Semaste uint16_t length = m_data.GetU16(&offset); 1268254721Semaste 1269254721Semaste if (length > 0 && lo_pc <= pc && pc < hi_pc) 1270254721Semaste { 1271254721Semaste return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, m_data, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr); 1272254721Semaste } 1273254721Semaste offset += length; 1274254721Semaste } 1275254721Semaste } 1276254721Semaste } 1277254721Semaste if (error_ptr) 1278254721Semaste error_ptr->SetErrorString ("variable not available"); 1279254721Semaste return false; 1280254721Semaste } 1281254721Semaste 1282254721Semaste // Not a location list, just a single expression. 1283254721Semaste return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, m_data, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr); 1284254721Semaste} 1285254721Semaste 1286254721Semaste 1287254721Semaste 1288254721Semastebool 1289254721SemasteDWARFExpression::Evaluate 1290254721Semaste( 1291254721Semaste ExecutionContext *exe_ctx, 1292254721Semaste ClangExpressionVariableList *expr_locals, 1293254721Semaste ClangExpressionDeclMap *decl_map, 1294254721Semaste RegisterContext *reg_ctx, 1295254721Semaste const DataExtractor& opcodes, 1296254721Semaste const lldb::offset_t opcodes_offset, 1297254721Semaste const lldb::offset_t opcodes_length, 1298254721Semaste const uint32_t reg_kind, 1299254721Semaste const Value* initial_value_ptr, 1300254721Semaste Value& result, 1301254721Semaste Error *error_ptr 1302254721Semaste) 1303254721Semaste{ 1304254721Semaste 1305254721Semaste if (opcodes_length == 0) 1306254721Semaste { 1307254721Semaste if (error_ptr) 1308254721Semaste error_ptr->SetErrorString ("no location, value may have been optimized out"); 1309254721Semaste return false; 1310254721Semaste } 1311254721Semaste std::vector<Value> stack; 1312254721Semaste 1313254721Semaste Process *process = NULL; 1314254721Semaste StackFrame *frame = NULL; 1315254721Semaste 1316254721Semaste if (exe_ctx) 1317254721Semaste { 1318254721Semaste process = exe_ctx->GetProcessPtr(); 1319254721Semaste frame = exe_ctx->GetFramePtr(); 1320254721Semaste } 1321254721Semaste if (reg_ctx == NULL && frame) 1322254721Semaste reg_ctx = frame->GetRegisterContext().get(); 1323254721Semaste 1324254721Semaste if (initial_value_ptr) 1325254721Semaste stack.push_back(*initial_value_ptr); 1326254721Semaste 1327254721Semaste lldb::offset_t offset = opcodes_offset; 1328254721Semaste const lldb::offset_t end_offset = opcodes_offset + opcodes_length; 1329254721Semaste Value tmp; 1330254721Semaste uint32_t reg_num; 1331254721Semaste 1332254721Semaste // Make sure all of the data is available in opcodes. 1333254721Semaste if (!opcodes.ValidOffsetForDataOfSize(opcodes_offset, opcodes_length)) 1334254721Semaste { 1335254721Semaste if (error_ptr) 1336254721Semaste error_ptr->SetErrorString ("invalid offset and/or length for opcodes buffer."); 1337254721Semaste return false; 1338254721Semaste } 1339254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1340254721Semaste 1341254721Semaste 1342254721Semaste while (opcodes.ValidOffset(offset) && offset < end_offset) 1343254721Semaste { 1344254721Semaste const lldb::offset_t op_offset = offset; 1345254721Semaste const uint8_t op = opcodes.GetU8(&offset); 1346254721Semaste 1347254721Semaste if (log && log->GetVerbose()) 1348254721Semaste { 1349254721Semaste size_t count = stack.size(); 1350254721Semaste log->Printf("Stack before operation has %lu values:", count); 1351254721Semaste for (size_t i=0; i<count; ++i) 1352254721Semaste { 1353254721Semaste StreamString new_value; 1354254721Semaste new_value.Printf("[%" PRIu64 "]", (uint64_t)i); 1355254721Semaste stack[i].Dump(&new_value); 1356254721Semaste log->Printf(" %s", new_value.GetData()); 1357254721Semaste } 1358254721Semaste log->Printf("0x%8.8" PRIx64 ": %s", op_offset, DW_OP_value_to_name(op)); 1359254721Semaste } 1360254721Semaste switch (op) 1361254721Semaste { 1362254721Semaste //---------------------------------------------------------------------- 1363254721Semaste // The DW_OP_addr operation has a single operand that encodes a machine 1364254721Semaste // address and whose size is the size of an address on the target machine. 1365254721Semaste //---------------------------------------------------------------------- 1366254721Semaste case DW_OP_addr: 1367254721Semaste stack.push_back(Scalar(opcodes.GetAddress(&offset))); 1368254721Semaste stack.back().SetValueType (Value::eValueTypeFileAddress); 1369254721Semaste break; 1370254721Semaste 1371254721Semaste //---------------------------------------------------------------------- 1372254721Semaste // The DW_OP_addr_sect_offset4 is used for any location expressions in 1373254721Semaste // shared libraries that have a location like: 1374254721Semaste // DW_OP_addr(0x1000) 1375254721Semaste // If this address resides in a shared library, then this virtual 1376254721Semaste // address won't make sense when it is evaluated in the context of a 1377254721Semaste // running process where shared libraries have been slid. To account for 1378254721Semaste // this, this new address type where we can store the section pointer 1379254721Semaste // and a 4 byte offset. 1380254721Semaste //---------------------------------------------------------------------- 1381254721Semaste// case DW_OP_addr_sect_offset4: 1382254721Semaste// { 1383254721Semaste// result_type = eResultTypeFileAddress; 1384254721Semaste// lldb::Section *sect = (lldb::Section *)opcodes.GetMaxU64(&offset, sizeof(void *)); 1385254721Semaste// lldb::addr_t sect_offset = opcodes.GetU32(&offset); 1386254721Semaste// 1387254721Semaste// Address so_addr (sect, sect_offset); 1388254721Semaste// lldb::addr_t load_addr = so_addr.GetLoadAddress(); 1389254721Semaste// if (load_addr != LLDB_INVALID_ADDRESS) 1390254721Semaste// { 1391254721Semaste// // We successfully resolve a file address to a load 1392254721Semaste// // address. 1393254721Semaste// stack.push_back(load_addr); 1394254721Semaste// break; 1395254721Semaste// } 1396254721Semaste// else 1397254721Semaste// { 1398254721Semaste// // We were able 1399254721Semaste// if (error_ptr) 1400254721Semaste// error_ptr->SetErrorStringWithFormat ("Section %s in %s is not currently loaded.\n", sect->GetName().AsCString(), sect->GetModule()->GetFileSpec().GetFilename().AsCString()); 1401254721Semaste// return false; 1402254721Semaste// } 1403254721Semaste// } 1404254721Semaste// break; 1405254721Semaste 1406254721Semaste //---------------------------------------------------------------------- 1407254721Semaste // OPCODE: DW_OP_deref 1408254721Semaste // OPERANDS: none 1409254721Semaste // DESCRIPTION: Pops the top stack entry and treats it as an address. 1410254721Semaste // The value retrieved from that address is pushed. The size of the 1411254721Semaste // data retrieved from the dereferenced address is the size of an 1412254721Semaste // address on the target machine. 1413254721Semaste //---------------------------------------------------------------------- 1414254721Semaste case DW_OP_deref: 1415254721Semaste { 1416254721Semaste Value::ValueType value_type = stack.back().GetValueType(); 1417254721Semaste switch (value_type) 1418254721Semaste { 1419254721Semaste case Value::eValueTypeHostAddress: 1420254721Semaste { 1421254721Semaste void *src = (void *)stack.back().GetScalar().ULongLong(); 1422254721Semaste intptr_t ptr; 1423254721Semaste ::memcpy (&ptr, src, sizeof(void *)); 1424254721Semaste stack.back().GetScalar() = ptr; 1425254721Semaste stack.back().ClearContext(); 1426254721Semaste } 1427254721Semaste break; 1428254721Semaste case Value::eValueTypeLoadAddress: 1429254721Semaste if (exe_ctx) 1430254721Semaste { 1431254721Semaste if (process) 1432254721Semaste { 1433254721Semaste lldb::addr_t pointer_addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1434254721Semaste uint8_t addr_bytes[sizeof(lldb::addr_t)]; 1435254721Semaste uint32_t addr_size = process->GetAddressByteSize(); 1436254721Semaste Error error; 1437254721Semaste if (process->ReadMemory(pointer_addr, &addr_bytes, addr_size, error) == addr_size) 1438254721Semaste { 1439254721Semaste DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), process->GetByteOrder(), addr_size); 1440254721Semaste lldb::offset_t addr_data_offset = 0; 1441254721Semaste stack.back().GetScalar() = addr_data.GetPointer(&addr_data_offset); 1442254721Semaste stack.back().ClearContext(); 1443254721Semaste } 1444254721Semaste else 1445254721Semaste { 1446254721Semaste if (error_ptr) 1447254721Semaste error_ptr->SetErrorStringWithFormat ("Failed to dereference pointer from 0x%" PRIx64 " for DW_OP_deref: %s\n", 1448254721Semaste pointer_addr, 1449254721Semaste error.AsCString()); 1450254721Semaste return false; 1451254721Semaste } 1452254721Semaste } 1453254721Semaste else 1454254721Semaste { 1455254721Semaste if (error_ptr) 1456254721Semaste error_ptr->SetErrorStringWithFormat ("NULL process for DW_OP_deref.\n"); 1457254721Semaste return false; 1458254721Semaste } 1459254721Semaste } 1460254721Semaste else 1461254721Semaste { 1462254721Semaste if (error_ptr) 1463254721Semaste error_ptr->SetErrorStringWithFormat ("NULL execution context for DW_OP_deref.\n"); 1464254721Semaste return false; 1465254721Semaste } 1466254721Semaste break; 1467254721Semaste 1468254721Semaste default: 1469254721Semaste break; 1470254721Semaste } 1471254721Semaste 1472254721Semaste } 1473254721Semaste break; 1474254721Semaste 1475254721Semaste //---------------------------------------------------------------------- 1476254721Semaste // OPCODE: DW_OP_deref_size 1477254721Semaste // OPERANDS: 1 1478254721Semaste // 1 - uint8_t that specifies the size of the data to dereference. 1479254721Semaste // DESCRIPTION: Behaves like the DW_OP_deref operation: it pops the top 1480254721Semaste // stack entry and treats it as an address. The value retrieved from that 1481254721Semaste // address is pushed. In the DW_OP_deref_size operation, however, the 1482254721Semaste // size in bytes of the data retrieved from the dereferenced address is 1483254721Semaste // specified by the single operand. This operand is a 1-byte unsigned 1484254721Semaste // integral constant whose value may not be larger than the size of an 1485254721Semaste // address on the target machine. The data retrieved is zero extended 1486254721Semaste // to the size of an address on the target machine before being pushed 1487254721Semaste // on the expression stack. 1488254721Semaste //---------------------------------------------------------------------- 1489254721Semaste case DW_OP_deref_size: 1490254721Semaste { 1491254721Semaste uint8_t size = opcodes.GetU8(&offset); 1492254721Semaste Value::ValueType value_type = stack.back().GetValueType(); 1493254721Semaste switch (value_type) 1494254721Semaste { 1495254721Semaste case Value::eValueTypeHostAddress: 1496254721Semaste { 1497254721Semaste void *src = (void *)stack.back().GetScalar().ULongLong(); 1498254721Semaste intptr_t ptr; 1499254721Semaste ::memcpy (&ptr, src, sizeof(void *)); 1500254721Semaste // I can't decide whether the size operand should apply to the bytes in their 1501254721Semaste // lldb-host endianness or the target endianness.. I doubt this'll ever come up 1502254721Semaste // but I'll opt for assuming big endian regardless. 1503254721Semaste switch (size) 1504254721Semaste { 1505254721Semaste case 1: ptr = ptr & 0xff; break; 1506254721Semaste case 2: ptr = ptr & 0xffff; break; 1507254721Semaste case 3: ptr = ptr & 0xffffff; break; 1508254721Semaste case 4: ptr = ptr & 0xffffffff; break; 1509254721Semaste // the casts are added to work around the case where intptr_t is a 32 bit quantity; 1510254721Semaste // presumably we won't hit the 5..7 cases if (void*) is 32-bits in this program. 1511254721Semaste case 5: ptr = (intptr_t) ptr & 0xffffffffffULL; break; 1512254721Semaste case 6: ptr = (intptr_t) ptr & 0xffffffffffffULL; break; 1513254721Semaste case 7: ptr = (intptr_t) ptr & 0xffffffffffffffULL; break; 1514254721Semaste default: break; 1515254721Semaste } 1516254721Semaste stack.back().GetScalar() = ptr; 1517254721Semaste stack.back().ClearContext(); 1518254721Semaste } 1519254721Semaste break; 1520254721Semaste case Value::eValueTypeLoadAddress: 1521254721Semaste if (exe_ctx) 1522254721Semaste { 1523254721Semaste if (process) 1524254721Semaste { 1525254721Semaste lldb::addr_t pointer_addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1526254721Semaste uint8_t addr_bytes[sizeof(lldb::addr_t)]; 1527254721Semaste Error error; 1528254721Semaste if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) == size) 1529254721Semaste { 1530254721Semaste DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), process->GetByteOrder(), size); 1531254721Semaste lldb::offset_t addr_data_offset = 0; 1532254721Semaste switch (size) 1533254721Semaste { 1534254721Semaste case 1: stack.back().GetScalar() = addr_data.GetU8(&addr_data_offset); break; 1535254721Semaste case 2: stack.back().GetScalar() = addr_data.GetU16(&addr_data_offset); break; 1536254721Semaste case 4: stack.back().GetScalar() = addr_data.GetU32(&addr_data_offset); break; 1537254721Semaste case 8: stack.back().GetScalar() = addr_data.GetU64(&addr_data_offset); break; 1538254721Semaste default: stack.back().GetScalar() = addr_data.GetPointer(&addr_data_offset); 1539254721Semaste } 1540254721Semaste stack.back().ClearContext(); 1541254721Semaste } 1542254721Semaste else 1543254721Semaste { 1544254721Semaste if (error_ptr) 1545254721Semaste error_ptr->SetErrorStringWithFormat ("Failed to dereference pointer from 0x%" PRIx64 " for DW_OP_deref: %s\n", 1546254721Semaste pointer_addr, 1547254721Semaste error.AsCString()); 1548254721Semaste return false; 1549254721Semaste } 1550254721Semaste } 1551254721Semaste else 1552254721Semaste { 1553254721Semaste if (error_ptr) 1554254721Semaste error_ptr->SetErrorStringWithFormat ("NULL process for DW_OP_deref.\n"); 1555254721Semaste return false; 1556254721Semaste } 1557254721Semaste } 1558254721Semaste else 1559254721Semaste { 1560254721Semaste if (error_ptr) 1561254721Semaste error_ptr->SetErrorStringWithFormat ("NULL execution context for DW_OP_deref.\n"); 1562254721Semaste return false; 1563254721Semaste } 1564254721Semaste break; 1565254721Semaste 1566254721Semaste default: 1567254721Semaste break; 1568254721Semaste } 1569254721Semaste 1570254721Semaste } 1571254721Semaste break; 1572254721Semaste 1573254721Semaste //---------------------------------------------------------------------- 1574254721Semaste // OPCODE: DW_OP_xderef_size 1575254721Semaste // OPERANDS: 1 1576254721Semaste // 1 - uint8_t that specifies the size of the data to dereference. 1577254721Semaste // DESCRIPTION: Behaves like the DW_OP_xderef operation: the entry at 1578254721Semaste // the top of the stack is treated as an address. The second stack 1579254721Semaste // entry is treated as an "address space identifier" for those 1580254721Semaste // architectures that support multiple address spaces. The top two 1581254721Semaste // stack elements are popped, a data item is retrieved through an 1582254721Semaste // implementation-defined address calculation and pushed as the new 1583254721Semaste // stack top. In the DW_OP_xderef_size operation, however, the size in 1584254721Semaste // bytes of the data retrieved from the dereferenced address is 1585254721Semaste // specified by the single operand. This operand is a 1-byte unsigned 1586254721Semaste // integral constant whose value may not be larger than the size of an 1587254721Semaste // address on the target machine. The data retrieved is zero extended 1588254721Semaste // to the size of an address on the target machine before being pushed 1589254721Semaste // on the expression stack. 1590254721Semaste //---------------------------------------------------------------------- 1591254721Semaste case DW_OP_xderef_size: 1592254721Semaste if (error_ptr) 1593254721Semaste error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef_size."); 1594254721Semaste return false; 1595254721Semaste //---------------------------------------------------------------------- 1596254721Semaste // OPCODE: DW_OP_xderef 1597254721Semaste // OPERANDS: none 1598254721Semaste // DESCRIPTION: Provides an extended dereference mechanism. The entry at 1599254721Semaste // the top of the stack is treated as an address. The second stack entry 1600254721Semaste // is treated as an "address space identifier" for those architectures 1601254721Semaste // that support multiple address spaces. The top two stack elements are 1602254721Semaste // popped, a data item is retrieved through an implementation-defined 1603254721Semaste // address calculation and pushed as the new stack top. The size of the 1604254721Semaste // data retrieved from the dereferenced address is the size of an address 1605254721Semaste // on the target machine. 1606254721Semaste //---------------------------------------------------------------------- 1607254721Semaste case DW_OP_xderef: 1608254721Semaste if (error_ptr) 1609254721Semaste error_ptr->SetErrorString("Unimplemented opcode: DW_OP_xderef."); 1610254721Semaste return false; 1611254721Semaste 1612254721Semaste //---------------------------------------------------------------------- 1613254721Semaste // All DW_OP_constXXX opcodes have a single operand as noted below: 1614254721Semaste // 1615254721Semaste // Opcode Operand 1 1616254721Semaste // --------------- ---------------------------------------------------- 1617254721Semaste // DW_OP_const1u 1-byte unsigned integer constant 1618254721Semaste // DW_OP_const1s 1-byte signed integer constant 1619254721Semaste // DW_OP_const2u 2-byte unsigned integer constant 1620254721Semaste // DW_OP_const2s 2-byte signed integer constant 1621254721Semaste // DW_OP_const4u 4-byte unsigned integer constant 1622254721Semaste // DW_OP_const4s 4-byte signed integer constant 1623254721Semaste // DW_OP_const8u 8-byte unsigned integer constant 1624254721Semaste // DW_OP_const8s 8-byte signed integer constant 1625254721Semaste // DW_OP_constu unsigned LEB128 integer constant 1626254721Semaste // DW_OP_consts signed LEB128 integer constant 1627254721Semaste //---------------------------------------------------------------------- 1628254721Semaste case DW_OP_const1u : stack.push_back(Scalar(( uint8_t)opcodes.GetU8 (&offset))); break; 1629254721Semaste case DW_OP_const1s : stack.push_back(Scalar(( int8_t)opcodes.GetU8 (&offset))); break; 1630254721Semaste case DW_OP_const2u : stack.push_back(Scalar((uint16_t)opcodes.GetU16 (&offset))); break; 1631254721Semaste case DW_OP_const2s : stack.push_back(Scalar(( int16_t)opcodes.GetU16 (&offset))); break; 1632254721Semaste case DW_OP_const4u : stack.push_back(Scalar((uint32_t)opcodes.GetU32 (&offset))); break; 1633254721Semaste case DW_OP_const4s : stack.push_back(Scalar(( int32_t)opcodes.GetU32 (&offset))); break; 1634254721Semaste case DW_OP_const8u : stack.push_back(Scalar((uint64_t)opcodes.GetU64 (&offset))); break; 1635254721Semaste case DW_OP_const8s : stack.push_back(Scalar(( int64_t)opcodes.GetU64 (&offset))); break; 1636254721Semaste case DW_OP_constu : stack.push_back(Scalar(opcodes.GetULEB128 (&offset))); break; 1637254721Semaste case DW_OP_consts : stack.push_back(Scalar(opcodes.GetSLEB128 (&offset))); break; 1638254721Semaste 1639254721Semaste //---------------------------------------------------------------------- 1640254721Semaste // OPCODE: DW_OP_dup 1641254721Semaste // OPERANDS: none 1642254721Semaste // DESCRIPTION: duplicates the value at the top of the stack 1643254721Semaste //---------------------------------------------------------------------- 1644254721Semaste case DW_OP_dup: 1645254721Semaste if (stack.empty()) 1646254721Semaste { 1647254721Semaste if (error_ptr) 1648254721Semaste error_ptr->SetErrorString("Expression stack empty for DW_OP_dup."); 1649254721Semaste return false; 1650254721Semaste } 1651254721Semaste else 1652254721Semaste stack.push_back(stack.back()); 1653254721Semaste break; 1654254721Semaste 1655254721Semaste //---------------------------------------------------------------------- 1656254721Semaste // OPCODE: DW_OP_drop 1657254721Semaste // OPERANDS: none 1658254721Semaste // DESCRIPTION: pops the value at the top of the stack 1659254721Semaste //---------------------------------------------------------------------- 1660254721Semaste case DW_OP_drop: 1661254721Semaste if (stack.empty()) 1662254721Semaste { 1663254721Semaste if (error_ptr) 1664254721Semaste error_ptr->SetErrorString("Expression stack empty for DW_OP_drop."); 1665254721Semaste return false; 1666254721Semaste } 1667254721Semaste else 1668254721Semaste stack.pop_back(); 1669254721Semaste break; 1670254721Semaste 1671254721Semaste //---------------------------------------------------------------------- 1672254721Semaste // OPCODE: DW_OP_over 1673254721Semaste // OPERANDS: none 1674254721Semaste // DESCRIPTION: Duplicates the entry currently second in the stack at 1675254721Semaste // the top of the stack. 1676254721Semaste //---------------------------------------------------------------------- 1677254721Semaste case DW_OP_over: 1678254721Semaste if (stack.size() < 2) 1679254721Semaste { 1680254721Semaste if (error_ptr) 1681254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_over."); 1682254721Semaste return false; 1683254721Semaste } 1684254721Semaste else 1685254721Semaste stack.push_back(stack[stack.size() - 2]); 1686254721Semaste break; 1687254721Semaste 1688254721Semaste 1689254721Semaste //---------------------------------------------------------------------- 1690254721Semaste // OPCODE: DW_OP_pick 1691254721Semaste // OPERANDS: uint8_t index into the current stack 1692254721Semaste // DESCRIPTION: The stack entry with the specified index (0 through 255, 1693254721Semaste // inclusive) is pushed on the stack 1694254721Semaste //---------------------------------------------------------------------- 1695254721Semaste case DW_OP_pick: 1696254721Semaste { 1697254721Semaste uint8_t pick_idx = opcodes.GetU8(&offset); 1698254721Semaste if (pick_idx < stack.size()) 1699254721Semaste stack.push_back(stack[pick_idx]); 1700254721Semaste else 1701254721Semaste { 1702254721Semaste if (error_ptr) 1703254721Semaste error_ptr->SetErrorStringWithFormat("Index %u out of range for DW_OP_pick.\n", pick_idx); 1704254721Semaste return false; 1705254721Semaste } 1706254721Semaste } 1707254721Semaste break; 1708254721Semaste 1709254721Semaste //---------------------------------------------------------------------- 1710254721Semaste // OPCODE: DW_OP_swap 1711254721Semaste // OPERANDS: none 1712254721Semaste // DESCRIPTION: swaps the top two stack entries. The entry at the top 1713254721Semaste // of the stack becomes the second stack entry, and the second entry 1714254721Semaste // becomes the top of the stack 1715254721Semaste //---------------------------------------------------------------------- 1716254721Semaste case DW_OP_swap: 1717254721Semaste if (stack.size() < 2) 1718254721Semaste { 1719254721Semaste if (error_ptr) 1720254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_swap."); 1721254721Semaste return false; 1722254721Semaste } 1723254721Semaste else 1724254721Semaste { 1725254721Semaste tmp = stack.back(); 1726254721Semaste stack.back() = stack[stack.size() - 2]; 1727254721Semaste stack[stack.size() - 2] = tmp; 1728254721Semaste } 1729254721Semaste break; 1730254721Semaste 1731254721Semaste //---------------------------------------------------------------------- 1732254721Semaste // OPCODE: DW_OP_rot 1733254721Semaste // OPERANDS: none 1734254721Semaste // DESCRIPTION: Rotates the first three stack entries. The entry at 1735254721Semaste // the top of the stack becomes the third stack entry, the second 1736254721Semaste // entry becomes the top of the stack, and the third entry becomes 1737254721Semaste // the second entry. 1738254721Semaste //---------------------------------------------------------------------- 1739254721Semaste case DW_OP_rot: 1740254721Semaste if (stack.size() < 3) 1741254721Semaste { 1742254721Semaste if (error_ptr) 1743254721Semaste error_ptr->SetErrorString("Expression stack needs at least 3 items for DW_OP_rot."); 1744254721Semaste return false; 1745254721Semaste } 1746254721Semaste else 1747254721Semaste { 1748254721Semaste size_t last_idx = stack.size() - 1; 1749254721Semaste Value old_top = stack[last_idx]; 1750254721Semaste stack[last_idx] = stack[last_idx - 1]; 1751254721Semaste stack[last_idx - 1] = stack[last_idx - 2]; 1752254721Semaste stack[last_idx - 2] = old_top; 1753254721Semaste } 1754254721Semaste break; 1755254721Semaste 1756254721Semaste //---------------------------------------------------------------------- 1757254721Semaste // OPCODE: DW_OP_abs 1758254721Semaste // OPERANDS: none 1759254721Semaste // DESCRIPTION: pops the top stack entry, interprets it as a signed 1760254721Semaste // value and pushes its absolute value. If the absolute value can not be 1761254721Semaste // represented, the result is undefined. 1762254721Semaste //---------------------------------------------------------------------- 1763254721Semaste case DW_OP_abs: 1764254721Semaste if (stack.empty()) 1765254721Semaste { 1766254721Semaste if (error_ptr) 1767254721Semaste error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_abs."); 1768254721Semaste return false; 1769254721Semaste } 1770254721Semaste else if (stack.back().ResolveValue(exe_ctx).AbsoluteValue() == false) 1771254721Semaste { 1772254721Semaste if (error_ptr) 1773254721Semaste error_ptr->SetErrorString("Failed to take the absolute value of the first stack item."); 1774254721Semaste return false; 1775254721Semaste } 1776254721Semaste break; 1777254721Semaste 1778254721Semaste //---------------------------------------------------------------------- 1779254721Semaste // OPCODE: DW_OP_and 1780254721Semaste // OPERANDS: none 1781254721Semaste // DESCRIPTION: pops the top two stack values, performs a bitwise and 1782254721Semaste // operation on the two, and pushes the result. 1783254721Semaste //---------------------------------------------------------------------- 1784254721Semaste case DW_OP_and: 1785254721Semaste if (stack.size() < 2) 1786254721Semaste { 1787254721Semaste if (error_ptr) 1788254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_and."); 1789254721Semaste return false; 1790254721Semaste } 1791254721Semaste else 1792254721Semaste { 1793254721Semaste tmp = stack.back(); 1794254721Semaste stack.pop_back(); 1795254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) & tmp.ResolveValue(exe_ctx); 1796254721Semaste } 1797254721Semaste break; 1798254721Semaste 1799254721Semaste //---------------------------------------------------------------------- 1800254721Semaste // OPCODE: DW_OP_div 1801254721Semaste // OPERANDS: none 1802254721Semaste // DESCRIPTION: pops the top two stack values, divides the former second 1803254721Semaste // entry by the former top of the stack using signed division, and 1804254721Semaste // pushes the result. 1805254721Semaste //---------------------------------------------------------------------- 1806254721Semaste case DW_OP_div: 1807254721Semaste if (stack.size() < 2) 1808254721Semaste { 1809254721Semaste if (error_ptr) 1810254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_div."); 1811254721Semaste return false; 1812254721Semaste } 1813254721Semaste else 1814254721Semaste { 1815254721Semaste tmp = stack.back(); 1816254721Semaste if (tmp.ResolveValue(exe_ctx).IsZero()) 1817254721Semaste { 1818254721Semaste if (error_ptr) 1819254721Semaste error_ptr->SetErrorString("Divide by zero."); 1820254721Semaste return false; 1821254721Semaste } 1822254721Semaste else 1823254721Semaste { 1824254721Semaste stack.pop_back(); 1825254721Semaste stack.back() = stack.back().ResolveValue(exe_ctx) / tmp.ResolveValue(exe_ctx); 1826254721Semaste if (!stack.back().ResolveValue(exe_ctx).IsValid()) 1827254721Semaste { 1828254721Semaste if (error_ptr) 1829254721Semaste error_ptr->SetErrorString("Divide failed."); 1830254721Semaste return false; 1831254721Semaste } 1832254721Semaste } 1833254721Semaste } 1834254721Semaste break; 1835254721Semaste 1836254721Semaste //---------------------------------------------------------------------- 1837254721Semaste // OPCODE: DW_OP_minus 1838254721Semaste // OPERANDS: none 1839254721Semaste // DESCRIPTION: pops the top two stack values, subtracts the former top 1840254721Semaste // of the stack from the former second entry, and pushes the result. 1841254721Semaste //---------------------------------------------------------------------- 1842254721Semaste case DW_OP_minus: 1843254721Semaste if (stack.size() < 2) 1844254721Semaste { 1845254721Semaste if (error_ptr) 1846254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_minus."); 1847254721Semaste return false; 1848254721Semaste } 1849254721Semaste else 1850254721Semaste { 1851254721Semaste tmp = stack.back(); 1852254721Semaste stack.pop_back(); 1853254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) - tmp.ResolveValue(exe_ctx); 1854254721Semaste } 1855254721Semaste break; 1856254721Semaste 1857254721Semaste //---------------------------------------------------------------------- 1858254721Semaste // OPCODE: DW_OP_mod 1859254721Semaste // OPERANDS: none 1860254721Semaste // DESCRIPTION: pops the top two stack values and pushes the result of 1861254721Semaste // the calculation: former second stack entry modulo the former top of 1862254721Semaste // the stack. 1863254721Semaste //---------------------------------------------------------------------- 1864254721Semaste case DW_OP_mod: 1865254721Semaste if (stack.size() < 2) 1866254721Semaste { 1867254721Semaste if (error_ptr) 1868254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_mod."); 1869254721Semaste return false; 1870254721Semaste } 1871254721Semaste else 1872254721Semaste { 1873254721Semaste tmp = stack.back(); 1874254721Semaste stack.pop_back(); 1875254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) % tmp.ResolveValue(exe_ctx); 1876254721Semaste } 1877254721Semaste break; 1878254721Semaste 1879254721Semaste 1880254721Semaste //---------------------------------------------------------------------- 1881254721Semaste // OPCODE: DW_OP_mul 1882254721Semaste // OPERANDS: none 1883254721Semaste // DESCRIPTION: pops the top two stack entries, multiplies them 1884254721Semaste // together, and pushes the result. 1885254721Semaste //---------------------------------------------------------------------- 1886254721Semaste case DW_OP_mul: 1887254721Semaste if (stack.size() < 2) 1888254721Semaste { 1889254721Semaste if (error_ptr) 1890254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_mul."); 1891254721Semaste return false; 1892254721Semaste } 1893254721Semaste else 1894254721Semaste { 1895254721Semaste tmp = stack.back(); 1896254721Semaste stack.pop_back(); 1897254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) * tmp.ResolveValue(exe_ctx); 1898254721Semaste } 1899254721Semaste break; 1900254721Semaste 1901254721Semaste //---------------------------------------------------------------------- 1902254721Semaste // OPCODE: DW_OP_neg 1903254721Semaste // OPERANDS: none 1904254721Semaste // DESCRIPTION: pops the top stack entry, and pushes its negation. 1905254721Semaste //---------------------------------------------------------------------- 1906254721Semaste case DW_OP_neg: 1907254721Semaste if (stack.empty()) 1908254721Semaste { 1909254721Semaste if (error_ptr) 1910254721Semaste error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_neg."); 1911254721Semaste return false; 1912254721Semaste } 1913254721Semaste else 1914254721Semaste { 1915254721Semaste if (stack.back().ResolveValue(exe_ctx).UnaryNegate() == false) 1916254721Semaste { 1917254721Semaste if (error_ptr) 1918254721Semaste error_ptr->SetErrorString("Unary negate failed."); 1919254721Semaste return false; 1920254721Semaste } 1921254721Semaste } 1922254721Semaste break; 1923254721Semaste 1924254721Semaste //---------------------------------------------------------------------- 1925254721Semaste // OPCODE: DW_OP_not 1926254721Semaste // OPERANDS: none 1927254721Semaste // DESCRIPTION: pops the top stack entry, and pushes its bitwise 1928254721Semaste // complement 1929254721Semaste //---------------------------------------------------------------------- 1930254721Semaste case DW_OP_not: 1931254721Semaste if (stack.empty()) 1932254721Semaste { 1933254721Semaste if (error_ptr) 1934254721Semaste error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_not."); 1935254721Semaste return false; 1936254721Semaste } 1937254721Semaste else 1938254721Semaste { 1939254721Semaste if (stack.back().ResolveValue(exe_ctx).OnesComplement() == false) 1940254721Semaste { 1941254721Semaste if (error_ptr) 1942254721Semaste error_ptr->SetErrorString("Logical NOT failed."); 1943254721Semaste return false; 1944254721Semaste } 1945254721Semaste } 1946254721Semaste break; 1947254721Semaste 1948254721Semaste //---------------------------------------------------------------------- 1949254721Semaste // OPCODE: DW_OP_or 1950254721Semaste // OPERANDS: none 1951254721Semaste // DESCRIPTION: pops the top two stack entries, performs a bitwise or 1952254721Semaste // operation on the two, and pushes the result. 1953254721Semaste //---------------------------------------------------------------------- 1954254721Semaste case DW_OP_or: 1955254721Semaste if (stack.size() < 2) 1956254721Semaste { 1957254721Semaste if (error_ptr) 1958254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_or."); 1959254721Semaste return false; 1960254721Semaste } 1961254721Semaste else 1962254721Semaste { 1963254721Semaste tmp = stack.back(); 1964254721Semaste stack.pop_back(); 1965254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) | tmp.ResolveValue(exe_ctx); 1966254721Semaste } 1967254721Semaste break; 1968254721Semaste 1969254721Semaste //---------------------------------------------------------------------- 1970254721Semaste // OPCODE: DW_OP_plus 1971254721Semaste // OPERANDS: none 1972254721Semaste // DESCRIPTION: pops the top two stack entries, adds them together, and 1973254721Semaste // pushes the result. 1974254721Semaste //---------------------------------------------------------------------- 1975254721Semaste case DW_OP_plus: 1976254721Semaste if (stack.size() < 2) 1977254721Semaste { 1978254721Semaste if (error_ptr) 1979254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_plus."); 1980254721Semaste return false; 1981254721Semaste } 1982254721Semaste else 1983254721Semaste { 1984254721Semaste tmp = stack.back(); 1985254721Semaste stack.pop_back(); 1986254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) + tmp.ResolveValue(exe_ctx); 1987254721Semaste } 1988254721Semaste break; 1989254721Semaste 1990254721Semaste //---------------------------------------------------------------------- 1991254721Semaste // OPCODE: DW_OP_plus_uconst 1992254721Semaste // OPERANDS: none 1993254721Semaste // DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB128 1994254721Semaste // constant operand and pushes the result. 1995254721Semaste //---------------------------------------------------------------------- 1996254721Semaste case DW_OP_plus_uconst: 1997254721Semaste if (stack.empty()) 1998254721Semaste { 1999254721Semaste if (error_ptr) 2000254721Semaste error_ptr->SetErrorString("Expression stack needs at least 1 item for DW_OP_plus_uconst."); 2001254721Semaste return false; 2002254721Semaste } 2003254721Semaste else 2004254721Semaste { 2005254721Semaste const uint64_t uconst_value = opcodes.GetULEB128(&offset); 2006254721Semaste // Implicit conversion from a UINT to a Scalar... 2007254721Semaste stack.back().ResolveValue(exe_ctx) += uconst_value; 2008254721Semaste if (!stack.back().ResolveValue(exe_ctx).IsValid()) 2009254721Semaste { 2010254721Semaste if (error_ptr) 2011254721Semaste error_ptr->SetErrorString("DW_OP_plus_uconst failed."); 2012254721Semaste return false; 2013254721Semaste } 2014254721Semaste } 2015254721Semaste break; 2016254721Semaste 2017254721Semaste //---------------------------------------------------------------------- 2018254721Semaste // OPCODE: DW_OP_shl 2019254721Semaste // OPERANDS: none 2020254721Semaste // DESCRIPTION: pops the top two stack entries, shifts the former 2021254721Semaste // second entry left by the number of bits specified by the former top 2022254721Semaste // of the stack, and pushes the result. 2023254721Semaste //---------------------------------------------------------------------- 2024254721Semaste case DW_OP_shl: 2025254721Semaste if (stack.size() < 2) 2026254721Semaste { 2027254721Semaste if (error_ptr) 2028254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_shl."); 2029254721Semaste return false; 2030254721Semaste } 2031254721Semaste else 2032254721Semaste { 2033254721Semaste tmp = stack.back(); 2034254721Semaste stack.pop_back(); 2035254721Semaste stack.back().ResolveValue(exe_ctx) <<= tmp.ResolveValue(exe_ctx); 2036254721Semaste } 2037254721Semaste break; 2038254721Semaste 2039254721Semaste //---------------------------------------------------------------------- 2040254721Semaste // OPCODE: DW_OP_shr 2041254721Semaste // OPERANDS: none 2042254721Semaste // DESCRIPTION: pops the top two stack entries, shifts the former second 2043254721Semaste // entry right logically (filling with zero bits) by the number of bits 2044254721Semaste // specified by the former top of the stack, and pushes the result. 2045254721Semaste //---------------------------------------------------------------------- 2046254721Semaste case DW_OP_shr: 2047254721Semaste if (stack.size() < 2) 2048254721Semaste { 2049254721Semaste if (error_ptr) 2050254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_shr."); 2051254721Semaste return false; 2052254721Semaste } 2053254721Semaste else 2054254721Semaste { 2055254721Semaste tmp = stack.back(); 2056254721Semaste stack.pop_back(); 2057254721Semaste if (stack.back().ResolveValue(exe_ctx).ShiftRightLogical(tmp.ResolveValue(exe_ctx)) == false) 2058254721Semaste { 2059254721Semaste if (error_ptr) 2060254721Semaste error_ptr->SetErrorString("DW_OP_shr failed."); 2061254721Semaste return false; 2062254721Semaste } 2063254721Semaste } 2064254721Semaste break; 2065254721Semaste 2066254721Semaste //---------------------------------------------------------------------- 2067254721Semaste // OPCODE: DW_OP_shra 2068254721Semaste // OPERANDS: none 2069254721Semaste // DESCRIPTION: pops the top two stack entries, shifts the former second 2070254721Semaste // entry right arithmetically (divide the magnitude by 2, keep the same 2071254721Semaste // sign for the result) by the number of bits specified by the former 2072254721Semaste // top of the stack, and pushes the result. 2073254721Semaste //---------------------------------------------------------------------- 2074254721Semaste case DW_OP_shra: 2075254721Semaste if (stack.size() < 2) 2076254721Semaste { 2077254721Semaste if (error_ptr) 2078254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_shra."); 2079254721Semaste return false; 2080254721Semaste } 2081254721Semaste else 2082254721Semaste { 2083254721Semaste tmp = stack.back(); 2084254721Semaste stack.pop_back(); 2085254721Semaste stack.back().ResolveValue(exe_ctx) >>= tmp.ResolveValue(exe_ctx); 2086254721Semaste } 2087254721Semaste break; 2088254721Semaste 2089254721Semaste //---------------------------------------------------------------------- 2090254721Semaste // OPCODE: DW_OP_xor 2091254721Semaste // OPERANDS: none 2092254721Semaste // DESCRIPTION: pops the top two stack entries, performs the bitwise 2093254721Semaste // exclusive-or operation on the two, and pushes the result. 2094254721Semaste //---------------------------------------------------------------------- 2095254721Semaste case DW_OP_xor: 2096254721Semaste if (stack.size() < 2) 2097254721Semaste { 2098254721Semaste if (error_ptr) 2099254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_xor."); 2100254721Semaste return false; 2101254721Semaste } 2102254721Semaste else 2103254721Semaste { 2104254721Semaste tmp = stack.back(); 2105254721Semaste stack.pop_back(); 2106254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) ^ tmp.ResolveValue(exe_ctx); 2107254721Semaste } 2108254721Semaste break; 2109254721Semaste 2110254721Semaste 2111254721Semaste //---------------------------------------------------------------------- 2112254721Semaste // OPCODE: DW_OP_skip 2113254721Semaste // OPERANDS: int16_t 2114254721Semaste // DESCRIPTION: An unconditional branch. Its single operand is a 2-byte 2115254721Semaste // signed integer constant. The 2-byte constant is the number of bytes 2116254721Semaste // of the DWARF expression to skip forward or backward from the current 2117254721Semaste // operation, beginning after the 2-byte constant. 2118254721Semaste //---------------------------------------------------------------------- 2119254721Semaste case DW_OP_skip: 2120254721Semaste { 2121254721Semaste int16_t skip_offset = (int16_t)opcodes.GetU16(&offset); 2122254721Semaste lldb::offset_t new_offset = offset + skip_offset; 2123254721Semaste if (new_offset >= opcodes_offset && new_offset < end_offset) 2124254721Semaste offset = new_offset; 2125254721Semaste else 2126254721Semaste { 2127254721Semaste if (error_ptr) 2128254721Semaste error_ptr->SetErrorString("Invalid opcode offset in DW_OP_skip."); 2129254721Semaste return false; 2130254721Semaste } 2131254721Semaste } 2132254721Semaste break; 2133254721Semaste 2134254721Semaste //---------------------------------------------------------------------- 2135254721Semaste // OPCODE: DW_OP_bra 2136254721Semaste // OPERANDS: int16_t 2137254721Semaste // DESCRIPTION: A conditional branch. Its single operand is a 2-byte 2138254721Semaste // signed integer constant. This operation pops the top of stack. If 2139254721Semaste // the value popped is not the constant 0, the 2-byte constant operand 2140254721Semaste // is the number of bytes of the DWARF expression to skip forward or 2141254721Semaste // backward from the current operation, beginning after the 2-byte 2142254721Semaste // constant. 2143254721Semaste //---------------------------------------------------------------------- 2144254721Semaste case DW_OP_bra: 2145254721Semaste { 2146254721Semaste tmp = stack.back(); 2147254721Semaste stack.pop_back(); 2148254721Semaste int16_t bra_offset = (int16_t)opcodes.GetU16(&offset); 2149254721Semaste Scalar zero(0); 2150254721Semaste if (tmp.ResolveValue(exe_ctx) != zero) 2151254721Semaste { 2152254721Semaste lldb::offset_t new_offset = offset + bra_offset; 2153254721Semaste if (new_offset >= opcodes_offset && new_offset < end_offset) 2154254721Semaste offset = new_offset; 2155254721Semaste else 2156254721Semaste { 2157254721Semaste if (error_ptr) 2158254721Semaste error_ptr->SetErrorString("Invalid opcode offset in DW_OP_bra."); 2159254721Semaste return false; 2160254721Semaste } 2161254721Semaste } 2162254721Semaste } 2163254721Semaste break; 2164254721Semaste 2165254721Semaste //---------------------------------------------------------------------- 2166254721Semaste // OPCODE: DW_OP_eq 2167254721Semaste // OPERANDS: none 2168254721Semaste // DESCRIPTION: pops the top two stack values, compares using the 2169254721Semaste // equals (==) operator. 2170254721Semaste // STACK RESULT: push the constant value 1 onto the stack if the result 2171254721Semaste // of the operation is true or the constant value 0 if the result of the 2172254721Semaste // operation is false. 2173254721Semaste //---------------------------------------------------------------------- 2174254721Semaste case DW_OP_eq: 2175254721Semaste if (stack.size() < 2) 2176254721Semaste { 2177254721Semaste if (error_ptr) 2178254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_eq."); 2179254721Semaste return false; 2180254721Semaste } 2181254721Semaste else 2182254721Semaste { 2183254721Semaste tmp = stack.back(); 2184254721Semaste stack.pop_back(); 2185254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) == tmp.ResolveValue(exe_ctx); 2186254721Semaste } 2187254721Semaste break; 2188254721Semaste 2189254721Semaste //---------------------------------------------------------------------- 2190254721Semaste // OPCODE: DW_OP_ge 2191254721Semaste // OPERANDS: none 2192254721Semaste // DESCRIPTION: pops the top two stack values, compares using the 2193254721Semaste // greater than or equal to (>=) operator. 2194254721Semaste // STACK RESULT: push the constant value 1 onto the stack if the result 2195254721Semaste // of the operation is true or the constant value 0 if the result of the 2196254721Semaste // operation is false. 2197254721Semaste //---------------------------------------------------------------------- 2198254721Semaste case DW_OP_ge: 2199254721Semaste if (stack.size() < 2) 2200254721Semaste { 2201254721Semaste if (error_ptr) 2202254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_ge."); 2203254721Semaste return false; 2204254721Semaste } 2205254721Semaste else 2206254721Semaste { 2207254721Semaste tmp = stack.back(); 2208254721Semaste stack.pop_back(); 2209254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) >= tmp.ResolveValue(exe_ctx); 2210254721Semaste } 2211254721Semaste break; 2212254721Semaste 2213254721Semaste //---------------------------------------------------------------------- 2214254721Semaste // OPCODE: DW_OP_gt 2215254721Semaste // OPERANDS: none 2216254721Semaste // DESCRIPTION: pops the top two stack values, compares using the 2217254721Semaste // greater than (>) operator. 2218254721Semaste // STACK RESULT: push the constant value 1 onto the stack if the result 2219254721Semaste // of the operation is true or the constant value 0 if the result of the 2220254721Semaste // operation is false. 2221254721Semaste //---------------------------------------------------------------------- 2222254721Semaste case DW_OP_gt: 2223254721Semaste if (stack.size() < 2) 2224254721Semaste { 2225254721Semaste if (error_ptr) 2226254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_gt."); 2227254721Semaste return false; 2228254721Semaste } 2229254721Semaste else 2230254721Semaste { 2231254721Semaste tmp = stack.back(); 2232254721Semaste stack.pop_back(); 2233254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) > tmp.ResolveValue(exe_ctx); 2234254721Semaste } 2235254721Semaste break; 2236254721Semaste 2237254721Semaste //---------------------------------------------------------------------- 2238254721Semaste // OPCODE: DW_OP_le 2239254721Semaste // OPERANDS: none 2240254721Semaste // DESCRIPTION: pops the top two stack values, compares using the 2241254721Semaste // less than or equal to (<=) operator. 2242254721Semaste // STACK RESULT: push the constant value 1 onto the stack if the result 2243254721Semaste // of the operation is true or the constant value 0 if the result of the 2244254721Semaste // operation is false. 2245254721Semaste //---------------------------------------------------------------------- 2246254721Semaste case DW_OP_le: 2247254721Semaste if (stack.size() < 2) 2248254721Semaste { 2249254721Semaste if (error_ptr) 2250254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_le."); 2251254721Semaste return false; 2252254721Semaste } 2253254721Semaste else 2254254721Semaste { 2255254721Semaste tmp = stack.back(); 2256254721Semaste stack.pop_back(); 2257254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) <= tmp.ResolveValue(exe_ctx); 2258254721Semaste } 2259254721Semaste break; 2260254721Semaste 2261254721Semaste //---------------------------------------------------------------------- 2262254721Semaste // OPCODE: DW_OP_lt 2263254721Semaste // OPERANDS: none 2264254721Semaste // DESCRIPTION: pops the top two stack values, compares using the 2265254721Semaste // less than (<) operator. 2266254721Semaste // STACK RESULT: push the constant value 1 onto the stack if the result 2267254721Semaste // of the operation is true or the constant value 0 if the result of the 2268254721Semaste // operation is false. 2269254721Semaste //---------------------------------------------------------------------- 2270254721Semaste case DW_OP_lt: 2271254721Semaste if (stack.size() < 2) 2272254721Semaste { 2273254721Semaste if (error_ptr) 2274254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_lt."); 2275254721Semaste return false; 2276254721Semaste } 2277254721Semaste else 2278254721Semaste { 2279254721Semaste tmp = stack.back(); 2280254721Semaste stack.pop_back(); 2281254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) < tmp.ResolveValue(exe_ctx); 2282254721Semaste } 2283254721Semaste break; 2284254721Semaste 2285254721Semaste //---------------------------------------------------------------------- 2286254721Semaste // OPCODE: DW_OP_ne 2287254721Semaste // OPERANDS: none 2288254721Semaste // DESCRIPTION: pops the top two stack values, compares using the 2289254721Semaste // not equal (!=) operator. 2290254721Semaste // STACK RESULT: push the constant value 1 onto the stack if the result 2291254721Semaste // of the operation is true or the constant value 0 if the result of the 2292254721Semaste // operation is false. 2293254721Semaste //---------------------------------------------------------------------- 2294254721Semaste case DW_OP_ne: 2295254721Semaste if (stack.size() < 2) 2296254721Semaste { 2297254721Semaste if (error_ptr) 2298254721Semaste error_ptr->SetErrorString("Expression stack needs at least 2 items for DW_OP_ne."); 2299254721Semaste return false; 2300254721Semaste } 2301254721Semaste else 2302254721Semaste { 2303254721Semaste tmp = stack.back(); 2304254721Semaste stack.pop_back(); 2305254721Semaste stack.back().ResolveValue(exe_ctx) = stack.back().ResolveValue(exe_ctx) != tmp.ResolveValue(exe_ctx); 2306254721Semaste } 2307254721Semaste break; 2308254721Semaste 2309254721Semaste //---------------------------------------------------------------------- 2310254721Semaste // OPCODE: DW_OP_litn 2311254721Semaste // OPERANDS: none 2312254721Semaste // DESCRIPTION: encode the unsigned literal values from 0 through 31. 2313254721Semaste // STACK RESULT: push the unsigned literal constant value onto the top 2314254721Semaste // of the stack. 2315254721Semaste //---------------------------------------------------------------------- 2316254721Semaste case DW_OP_lit0: 2317254721Semaste case DW_OP_lit1: 2318254721Semaste case DW_OP_lit2: 2319254721Semaste case DW_OP_lit3: 2320254721Semaste case DW_OP_lit4: 2321254721Semaste case DW_OP_lit5: 2322254721Semaste case DW_OP_lit6: 2323254721Semaste case DW_OP_lit7: 2324254721Semaste case DW_OP_lit8: 2325254721Semaste case DW_OP_lit9: 2326254721Semaste case DW_OP_lit10: 2327254721Semaste case DW_OP_lit11: 2328254721Semaste case DW_OP_lit12: 2329254721Semaste case DW_OP_lit13: 2330254721Semaste case DW_OP_lit14: 2331254721Semaste case DW_OP_lit15: 2332254721Semaste case DW_OP_lit16: 2333254721Semaste case DW_OP_lit17: 2334254721Semaste case DW_OP_lit18: 2335254721Semaste case DW_OP_lit19: 2336254721Semaste case DW_OP_lit20: 2337254721Semaste case DW_OP_lit21: 2338254721Semaste case DW_OP_lit22: 2339254721Semaste case DW_OP_lit23: 2340254721Semaste case DW_OP_lit24: 2341254721Semaste case DW_OP_lit25: 2342254721Semaste case DW_OP_lit26: 2343254721Semaste case DW_OP_lit27: 2344254721Semaste case DW_OP_lit28: 2345254721Semaste case DW_OP_lit29: 2346254721Semaste case DW_OP_lit30: 2347254721Semaste case DW_OP_lit31: 2348254721Semaste stack.push_back(Scalar(op - DW_OP_lit0)); 2349254721Semaste break; 2350254721Semaste 2351254721Semaste //---------------------------------------------------------------------- 2352254721Semaste // OPCODE: DW_OP_regN 2353254721Semaste // OPERANDS: none 2354254721Semaste // DESCRIPTION: Push the value in register n on the top of the stack. 2355254721Semaste //---------------------------------------------------------------------- 2356254721Semaste case DW_OP_reg0: 2357254721Semaste case DW_OP_reg1: 2358254721Semaste case DW_OP_reg2: 2359254721Semaste case DW_OP_reg3: 2360254721Semaste case DW_OP_reg4: 2361254721Semaste case DW_OP_reg5: 2362254721Semaste case DW_OP_reg6: 2363254721Semaste case DW_OP_reg7: 2364254721Semaste case DW_OP_reg8: 2365254721Semaste case DW_OP_reg9: 2366254721Semaste case DW_OP_reg10: 2367254721Semaste case DW_OP_reg11: 2368254721Semaste case DW_OP_reg12: 2369254721Semaste case DW_OP_reg13: 2370254721Semaste case DW_OP_reg14: 2371254721Semaste case DW_OP_reg15: 2372254721Semaste case DW_OP_reg16: 2373254721Semaste case DW_OP_reg17: 2374254721Semaste case DW_OP_reg18: 2375254721Semaste case DW_OP_reg19: 2376254721Semaste case DW_OP_reg20: 2377254721Semaste case DW_OP_reg21: 2378254721Semaste case DW_OP_reg22: 2379254721Semaste case DW_OP_reg23: 2380254721Semaste case DW_OP_reg24: 2381254721Semaste case DW_OP_reg25: 2382254721Semaste case DW_OP_reg26: 2383254721Semaste case DW_OP_reg27: 2384254721Semaste case DW_OP_reg28: 2385254721Semaste case DW_OP_reg29: 2386254721Semaste case DW_OP_reg30: 2387254721Semaste case DW_OP_reg31: 2388254721Semaste { 2389254721Semaste reg_num = op - DW_OP_reg0; 2390254721Semaste 2391254721Semaste if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp)) 2392254721Semaste stack.push_back(tmp); 2393254721Semaste else 2394254721Semaste return false; 2395254721Semaste } 2396254721Semaste break; 2397254721Semaste //---------------------------------------------------------------------- 2398254721Semaste // OPCODE: DW_OP_regx 2399254721Semaste // OPERANDS: 2400254721Semaste // ULEB128 literal operand that encodes the register. 2401254721Semaste // DESCRIPTION: Push the value in register on the top of the stack. 2402254721Semaste //---------------------------------------------------------------------- 2403254721Semaste case DW_OP_regx: 2404254721Semaste { 2405254721Semaste reg_num = opcodes.GetULEB128(&offset); 2406254721Semaste if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp)) 2407254721Semaste stack.push_back(tmp); 2408254721Semaste else 2409254721Semaste return false; 2410254721Semaste } 2411254721Semaste break; 2412254721Semaste 2413254721Semaste //---------------------------------------------------------------------- 2414254721Semaste // OPCODE: DW_OP_bregN 2415254721Semaste // OPERANDS: 2416254721Semaste // SLEB128 offset from register N 2417254721Semaste // DESCRIPTION: Value is in memory at the address specified by register 2418254721Semaste // N plus an offset. 2419254721Semaste //---------------------------------------------------------------------- 2420254721Semaste case DW_OP_breg0: 2421254721Semaste case DW_OP_breg1: 2422254721Semaste case DW_OP_breg2: 2423254721Semaste case DW_OP_breg3: 2424254721Semaste case DW_OP_breg4: 2425254721Semaste case DW_OP_breg5: 2426254721Semaste case DW_OP_breg6: 2427254721Semaste case DW_OP_breg7: 2428254721Semaste case DW_OP_breg8: 2429254721Semaste case DW_OP_breg9: 2430254721Semaste case DW_OP_breg10: 2431254721Semaste case DW_OP_breg11: 2432254721Semaste case DW_OP_breg12: 2433254721Semaste case DW_OP_breg13: 2434254721Semaste case DW_OP_breg14: 2435254721Semaste case DW_OP_breg15: 2436254721Semaste case DW_OP_breg16: 2437254721Semaste case DW_OP_breg17: 2438254721Semaste case DW_OP_breg18: 2439254721Semaste case DW_OP_breg19: 2440254721Semaste case DW_OP_breg20: 2441254721Semaste case DW_OP_breg21: 2442254721Semaste case DW_OP_breg22: 2443254721Semaste case DW_OP_breg23: 2444254721Semaste case DW_OP_breg24: 2445254721Semaste case DW_OP_breg25: 2446254721Semaste case DW_OP_breg26: 2447254721Semaste case DW_OP_breg27: 2448254721Semaste case DW_OP_breg28: 2449254721Semaste case DW_OP_breg29: 2450254721Semaste case DW_OP_breg30: 2451254721Semaste case DW_OP_breg31: 2452254721Semaste { 2453254721Semaste reg_num = op - DW_OP_breg0; 2454254721Semaste 2455254721Semaste if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp)) 2456254721Semaste { 2457254721Semaste int64_t breg_offset = opcodes.GetSLEB128(&offset); 2458254721Semaste tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset; 2459254721Semaste tmp.ClearContext(); 2460254721Semaste stack.push_back(tmp); 2461254721Semaste stack.back().SetValueType (Value::eValueTypeLoadAddress); 2462254721Semaste } 2463254721Semaste else 2464254721Semaste return false; 2465254721Semaste } 2466254721Semaste break; 2467254721Semaste //---------------------------------------------------------------------- 2468254721Semaste // OPCODE: DW_OP_bregx 2469254721Semaste // OPERANDS: 2 2470254721Semaste // ULEB128 literal operand that encodes the register. 2471254721Semaste // SLEB128 offset from register N 2472254721Semaste // DESCRIPTION: Value is in memory at the address specified by register 2473254721Semaste // N plus an offset. 2474254721Semaste //---------------------------------------------------------------------- 2475254721Semaste case DW_OP_bregx: 2476254721Semaste { 2477254721Semaste reg_num = opcodes.GetULEB128(&offset); 2478254721Semaste 2479254721Semaste if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp)) 2480254721Semaste { 2481254721Semaste int64_t breg_offset = opcodes.GetSLEB128(&offset); 2482254721Semaste tmp.ResolveValue(exe_ctx) += (uint64_t)breg_offset; 2483254721Semaste tmp.ClearContext(); 2484254721Semaste stack.push_back(tmp); 2485254721Semaste stack.back().SetValueType (Value::eValueTypeLoadAddress); 2486254721Semaste } 2487254721Semaste else 2488254721Semaste return false; 2489254721Semaste } 2490254721Semaste break; 2491254721Semaste 2492254721Semaste case DW_OP_fbreg: 2493254721Semaste if (exe_ctx) 2494254721Semaste { 2495254721Semaste if (frame) 2496254721Semaste { 2497254721Semaste Scalar value; 2498254721Semaste if (frame->GetFrameBaseValue(value, error_ptr)) 2499254721Semaste { 2500254721Semaste int64_t fbreg_offset = opcodes.GetSLEB128(&offset); 2501254721Semaste value += fbreg_offset; 2502254721Semaste stack.push_back(value); 2503254721Semaste stack.back().SetValueType (Value::eValueTypeLoadAddress); 2504254721Semaste } 2505254721Semaste else 2506254721Semaste return false; 2507254721Semaste } 2508254721Semaste else 2509254721Semaste { 2510254721Semaste if (error_ptr) 2511254721Semaste error_ptr->SetErrorString ("Invalid stack frame in context for DW_OP_fbreg opcode."); 2512254721Semaste return false; 2513254721Semaste } 2514254721Semaste } 2515254721Semaste else 2516254721Semaste { 2517254721Semaste if (error_ptr) 2518254721Semaste error_ptr->SetErrorStringWithFormat ("NULL execution context for DW_OP_fbreg.\n"); 2519254721Semaste return false; 2520254721Semaste } 2521254721Semaste 2522254721Semaste break; 2523254721Semaste 2524254721Semaste //---------------------------------------------------------------------- 2525254721Semaste // OPCODE: DW_OP_nop 2526254721Semaste // OPERANDS: none 2527254721Semaste // DESCRIPTION: A place holder. It has no effect on the location stack 2528254721Semaste // or any of its values. 2529254721Semaste //---------------------------------------------------------------------- 2530254721Semaste case DW_OP_nop: 2531254721Semaste break; 2532254721Semaste 2533254721Semaste //---------------------------------------------------------------------- 2534254721Semaste // OPCODE: DW_OP_piece 2535254721Semaste // OPERANDS: 1 2536254721Semaste // ULEB128: byte size of the piece 2537254721Semaste // DESCRIPTION: The operand describes the size in bytes of the piece of 2538254721Semaste // the object referenced by the DWARF expression whose result is at the 2539254721Semaste // top of the stack. If the piece is located in a register, but does not 2540254721Semaste // occupy the entire register, the placement of the piece within that 2541254721Semaste // register is defined by the ABI. 2542254721Semaste // 2543254721Semaste // Many compilers store a single variable in sets of registers, or store 2544254721Semaste // a variable partially in memory and partially in registers. 2545254721Semaste // DW_OP_piece provides a way of describing how large a part of a 2546254721Semaste // variable a particular DWARF expression refers to. 2547254721Semaste //---------------------------------------------------------------------- 2548254721Semaste case DW_OP_piece: 2549254721Semaste if (error_ptr) 2550254721Semaste error_ptr->SetErrorString ("Unimplemented opcode DW_OP_piece."); 2551254721Semaste return false; 2552254721Semaste 2553254721Semaste //---------------------------------------------------------------------- 2554254721Semaste // OPCODE: DW_OP_push_object_address 2555254721Semaste // OPERANDS: none 2556254721Semaste // DESCRIPTION: Pushes the address of the object currently being 2557254721Semaste // evaluated as part of evaluation of a user presented expression. 2558254721Semaste // This object may correspond to an independent variable described by 2559254721Semaste // its own DIE or it may be a component of an array, structure, or class 2560254721Semaste // whose address has been dynamically determined by an earlier step 2561254721Semaste // during user expression evaluation. 2562254721Semaste //---------------------------------------------------------------------- 2563254721Semaste case DW_OP_push_object_address: 2564254721Semaste if (error_ptr) 2565254721Semaste error_ptr->SetErrorString ("Unimplemented opcode DW_OP_push_object_address."); 2566254721Semaste return false; 2567254721Semaste 2568254721Semaste //---------------------------------------------------------------------- 2569254721Semaste // OPCODE: DW_OP_call2 2570254721Semaste // OPERANDS: 2571254721Semaste // uint16_t compile unit relative offset of a DIE 2572254721Semaste // DESCRIPTION: Performs subroutine calls during evaluation 2573254721Semaste // of a DWARF expression. The operand is the 2-byte unsigned offset 2574254721Semaste // of a debugging information entry in the current compilation unit. 2575254721Semaste // 2576254721Semaste // Operand interpretation is exactly like that for DW_FORM_ref2. 2577254721Semaste // 2578254721Semaste // This operation transfers control of DWARF expression evaluation 2579254721Semaste // to the DW_AT_location attribute of the referenced DIE. If there is 2580254721Semaste // no such attribute, then there is no effect. Execution of the DWARF 2581254721Semaste // expression of a DW_AT_location attribute may add to and/or remove from 2582254721Semaste // values on the stack. Execution returns to the point following the call 2583254721Semaste // when the end of the attribute is reached. Values on the stack at the 2584254721Semaste // time of the call may be used as parameters by the called expression 2585254721Semaste // and values left on the stack by the called expression may be used as 2586254721Semaste // return values by prior agreement between the calling and called 2587254721Semaste // expressions. 2588254721Semaste //---------------------------------------------------------------------- 2589254721Semaste case DW_OP_call2: 2590254721Semaste if (error_ptr) 2591254721Semaste error_ptr->SetErrorString ("Unimplemented opcode DW_OP_call2."); 2592254721Semaste return false; 2593254721Semaste //---------------------------------------------------------------------- 2594254721Semaste // OPCODE: DW_OP_call4 2595254721Semaste // OPERANDS: 1 2596254721Semaste // uint32_t compile unit relative offset of a DIE 2597254721Semaste // DESCRIPTION: Performs a subroutine call during evaluation of a DWARF 2598254721Semaste // expression. For DW_OP_call4, the operand is a 4-byte unsigned offset 2599254721Semaste // of a debugging information entry in the current compilation unit. 2600254721Semaste // 2601254721Semaste // Operand interpretation DW_OP_call4 is exactly like that for 2602254721Semaste // DW_FORM_ref4. 2603254721Semaste // 2604254721Semaste // This operation transfers control of DWARF expression evaluation 2605254721Semaste // to the DW_AT_location attribute of the referenced DIE. If there is 2606254721Semaste // no such attribute, then there is no effect. Execution of the DWARF 2607254721Semaste // expression of a DW_AT_location attribute may add to and/or remove from 2608254721Semaste // values on the stack. Execution returns to the point following the call 2609254721Semaste // when the end of the attribute is reached. Values on the stack at the 2610254721Semaste // time of the call may be used as parameters by the called expression 2611254721Semaste // and values left on the stack by the called expression may be used as 2612254721Semaste // return values by prior agreement between the calling and called 2613254721Semaste // expressions. 2614254721Semaste //---------------------------------------------------------------------- 2615254721Semaste case DW_OP_call4: 2616254721Semaste if (error_ptr) 2617254721Semaste error_ptr->SetErrorString ("Unimplemented opcode DW_OP_call4."); 2618254721Semaste return false; 2619254721Semaste 2620254721Semaste //---------------------------------------------------------------------- 2621254721Semaste // OPCODE: DW_OP_stack_value 2622254721Semaste // OPERANDS: None 2623254721Semaste // DESCRIPTION: Specifies that the object does not exist in memory but 2624254721Semaste // rather is a constant value. The value from the top of the stack is 2625254721Semaste // the value to be used. This is the actual object value and not the 2626254721Semaste // location. 2627254721Semaste //---------------------------------------------------------------------- 2628254721Semaste case DW_OP_stack_value: 2629254721Semaste stack.back().SetValueType(Value::eValueTypeScalar); 2630254721Semaste break; 2631254721Semaste 2632254721Semaste //---------------------------------------------------------------------- 2633254721Semaste // OPCODE: DW_OP_call_frame_cfa 2634254721Semaste // OPERANDS: None 2635254721Semaste // DESCRIPTION: Specifies a DWARF expression that pushes the value of 2636254721Semaste // the canonical frame address consistent with the call frame information 2637254721Semaste // located in .debug_frame (or in the FDEs of the eh_frame section). 2638254721Semaste //---------------------------------------------------------------------- 2639254721Semaste case DW_OP_call_frame_cfa: 2640254721Semaste if (frame) 2641254721Semaste { 2642254721Semaste // Note that we don't have to parse FDEs because this DWARF expression 2643254721Semaste // is commonly evaluated with a valid stack frame. 2644254721Semaste StackID id = frame->GetStackID(); 2645254721Semaste addr_t cfa = id.GetCallFrameAddress(); 2646254721Semaste if (cfa != LLDB_INVALID_ADDRESS) 2647254721Semaste { 2648254721Semaste stack.push_back(Scalar(cfa)); 2649254721Semaste stack.back().SetValueType (Value::eValueTypeHostAddress); 2650254721Semaste } 2651254721Semaste else 2652254721Semaste if (error_ptr) 2653254721Semaste error_ptr->SetErrorString ("Stack frame does not include a canonical frame address for DW_OP_call_frame_cfa opcode."); 2654254721Semaste } 2655254721Semaste else 2656254721Semaste { 2657254721Semaste if (error_ptr) 2658254721Semaste error_ptr->SetErrorString ("Invalid stack frame in context for DW_OP_call_frame_cfa opcode."); 2659254721Semaste return false; 2660254721Semaste } 2661254721Semaste break; 2662254721Semaste default: 2663254721Semaste if (log) 2664254721Semaste log->Printf("Unhandled opcode %s in DWARFExpression.", DW_OP_value_to_name(op)); 2665254721Semaste break; 2666254721Semaste } 2667254721Semaste } 2668254721Semaste 2669254721Semaste if (stack.empty()) 2670254721Semaste { 2671254721Semaste if (error_ptr) 2672254721Semaste error_ptr->SetErrorString ("Stack empty after evaluation."); 2673254721Semaste return false; 2674254721Semaste } 2675254721Semaste else if (log && log->GetVerbose()) 2676254721Semaste { 2677254721Semaste size_t count = stack.size(); 2678254721Semaste log->Printf("Stack after operation has %lu values:", count); 2679254721Semaste for (size_t i=0; i<count; ++i) 2680254721Semaste { 2681254721Semaste StreamString new_value; 2682254721Semaste new_value.Printf("[%" PRIu64 "]", (uint64_t)i); 2683254721Semaste stack[i].Dump(&new_value); 2684254721Semaste log->Printf(" %s", new_value.GetData()); 2685254721Semaste } 2686254721Semaste } 2687254721Semaste 2688254721Semaste result = stack.back(); 2689254721Semaste return true; // Return true on success 2690254721Semaste} 2691254721Semaste 2692