static int print_dwarf_exp_op (Stream &s, const DataExtractor& data, uint32_t* offset_ptr, int address_size, int dwarf_ref_size) { uint8_t opcode = data.GetU8(offset_ptr); DRC_class opcode_class; uint64_t uint; int64_t sint; int size; opcode_class = DW_OP_value_to_class (opcode) & (~DRC_DWARFv3); s.Printf("%s ", DW_OP_value_to_name (opcode)); /* Does this take zero parameters? If so we can shortcut this function. */ if (opcode_class == DRC_ZEROOPERANDS) return 0; if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_bregx) { uint = data.GetULEB128(offset_ptr); sint = data.GetSLEB128(offset_ptr); s.Printf("%llu %lli", uint, sint); return 0; } if (opcode_class != DRC_ONEOPERAND) { s.Printf("UNKNOWN OP %u", opcode); return 1; } switch (opcode) { case DW_OP_addr: size = address_size; break; case DW_OP_const1u: size = 1; break; case DW_OP_const1s: size = -1; break; case DW_OP_const2u: size = 2; break; case DW_OP_const2s: size = -2; break; case DW_OP_const4u: size = 4; break; case DW_OP_const4s: size = -4; break; case DW_OP_const8u: size = 8; break; case DW_OP_const8s: size = -8; break; case DW_OP_constu: size = 128; break; case DW_OP_consts: size = -128; break; case DW_OP_fbreg: size = -128; break; case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: size = -128; break; case DW_OP_pick: size = 1; break; case DW_OP_deref_size: size = 1; break; case DW_OP_xderef_size: size = 1; break; case DW_OP_plus_uconst: size = 128; break; case DW_OP_skip: size = -2; break; case DW_OP_bra: size = -2; break; case DW_OP_call2: size = 2; break; case DW_OP_call4: size = 4; break; case DW_OP_call_ref: size = dwarf_ref_size; break; case DW_OP_piece: size = 128; break; case DW_OP_regx: size = 128; break; default: s.Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode); return 1; } switch (size) { case -1: sint = (int8_t) data.GetU8(offset_ptr); s.Printf("%+lli", sint); break; case -2: sint = (int16_t) data.GetU16(offset_ptr); s.Printf("%+lli", sint); break; case -4: sint = (int32_t) data.GetU32(offset_ptr); s.Printf("%+lli", sint); break; case -8: sint = (int64_t) data.GetU64(offset_ptr); s.Printf("%+lli", sint); break; case -128: sint = data.GetSLEB128(offset_ptr); s.Printf("%+lli", sint); break; case 1: uint = data.GetU8(offset_ptr); s.Printf("0x%2.2llx", uint); break; case 2: uint = data.GetU16(offset_ptr); s.Printf("0x%4.4llx", uint); break; case 4: uint = data.GetU32(offset_ptr); s.Printf("0x%8.8llx", uint); break; case 8: uint = data.GetU64(offset_ptr); s.Printf("0x%16.16llx", uint); break; case 128: uint = data.GetULEB128(offset_ptr); s.Printf("0x%llx", uint); break; } return 0; }
bool DWARFFormValue::ExtractValue(const DataExtractor& data, lldb::offset_t* offset_ptr, const DWARFCompileUnit* cu) { bool indirect = false; bool is_block = false; m_value.data = NULL; // Read the value for the form into value and follow and DW_FORM_indirect instances we run into do { indirect = false; switch (m_form) { case DW_FORM_addr: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); break; case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); is_block = true; break; case DW_FORM_block4: m_value.value.uval = data.GetU32(offset_ptr); is_block = true; break; case DW_FORM_data2: m_value.value.uval = data.GetU16(offset_ptr); break; case DW_FORM_data4: m_value.value.uval = data.GetU32(offset_ptr); break; case DW_FORM_data8: m_value.value.uval = data.GetU64(offset_ptr); break; case DW_FORM_string: m_value.value.cstr = data.GetCStr(offset_ptr); // Set the string value to also be the data for inlined cstr form values only // so we can tell the differnence between DW_FORM_string and DW_FORM_strp form // values; m_value.data = (uint8_t*)m_value.value.cstr; break; case DW_FORM_exprloc: case DW_FORM_block: m_value.value.uval = data.GetULEB128(offset_ptr); is_block = true; break; case DW_FORM_block1: m_value.value.uval = data.GetU8(offset_ptr); is_block = true; break; case DW_FORM_data1: m_value.value.uval = data.GetU8(offset_ptr); break; case DW_FORM_flag: m_value.value.uval = data.GetU8(offset_ptr); break; case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(offset_ptr); break; case DW_FORM_strp: m_value.value.uval = data.GetU32(offset_ptr); break; // case DW_FORM_APPLE_db_str: case DW_FORM_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break; case DW_FORM_ref_addr: if (cu->GetVersion() <= 2) m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); else m_value.value.uval = data.GetU32(offset_ptr); // 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet break; case DW_FORM_ref1: m_value.value.uval = data.GetU8(offset_ptr); break; case DW_FORM_ref2: m_value.value.uval = data.GetU16(offset_ptr); break; case DW_FORM_ref4: m_value.value.uval = data.GetU32(offset_ptr); break; case DW_FORM_ref8: m_value.value.uval = data.GetU64(offset_ptr); break; case DW_FORM_ref_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break; case DW_FORM_indirect: m_form = data.GetULEB128(offset_ptr); indirect = true; break; case DW_FORM_sec_offset: m_value.value.uval = data.GetU32(offset_ptr); break; case DW_FORM_flag_present: m_value.value.uval = 1; break; case DW_FORM_ref_sig8: m_value.value.uval = data.GetU64(offset_ptr); break; default: return false; break; } } while (indirect); if (is_block) { m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); if (m_value.data != NULL) { *offset_ptr += m_value.value.uval; } } return true; }