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