uint64_t EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr) { uint64_t uval64 = 0; bool success = false; if (byte_size <= 8) { uint8_t buf[sizeof(uint64_t)]; size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size); if (bytes_read == byte_size) { lldb::offset_t offset = 0; DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize()); uval64 = data.GetMaxU64 (&offset, byte_size); success = true; } } if (success_ptr) *success_ptr = success; if (!success) uval64 = fail_value; return uval64; }
static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr, lldb::offset_t byte_size, llvm::APInt &result) { llvm::SmallVector<uint64_t, 2> uint64_array; lldb::offset_t bytes_left = byte_size; uint64_t u64; const lldb::ByteOrder byte_order = data.GetByteOrder(); if (byte_order == lldb::eByteOrderLittle) { while (bytes_left > 0) { if (bytes_left >= 8) { u64 = data.GetU64(offset_ptr); bytes_left -= 8; } else { u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left); bytes_left = 0; } uint64_array.push_back(u64); } result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); return true; } else if (byte_order == lldb::eByteOrderBig) { lldb::offset_t be_offset = *offset_ptr + byte_size; lldb::offset_t temp_offset; while (bytes_left > 0) { if (bytes_left >= 8) { be_offset -= 8; temp_offset = be_offset; u64 = data.GetU64(&temp_offset); bytes_left -= 8; } else { be_offset -= bytes_left; temp_offset = be_offset; u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left); bytes_left = 0; } uint64_array.push_back(u64); } *offset_ptr += byte_size; result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); return true; } return false; }
void DWARFDebugRanges::Dump(Stream &s, const DataExtractor& debug_ranges_data, uint32_t* offset_ptr, dw_addr_t cu_base_addr) { uint32_t addr_size = s.GetAddressByteSize(); bool verbose = s.GetVerbose(); dw_addr_t base_addr = cu_base_addr; while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) { dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); // Extend 4 byte addresses that consits of 32 bits of 1's to be 64 bits // of ones if (begin == 0xFFFFFFFFull && addr_size == 4) begin = DW_INVALID_ADDRESS; s.Indent(); if (verbose) { s.AddressRange(begin, end, sizeof (dw_addr_t), " offsets = "); } if (begin == 0 && end == 0) { s.PutCString(" End"); break; } else if (begin == DW_INVALID_ADDRESS) { // A base address selection entry base_addr = end; s.Address(base_addr, sizeof (dw_addr_t), " Base address = "); } else { // Convert from offset to an address dw_addr_t begin_addr = begin + base_addr; dw_addr_t end_addr = end + base_addr; s.AddressRange(begin_addr, end_addr, sizeof (dw_addr_t), verbose ? " ==> addrs = " : NULL); } } }
Status ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp) { Status error; if (!new_value_sp) { error.SetErrorString("Empty value object for return value."); return error; } CompilerType compiler_type = new_value_sp->GetCompilerType(); if (!compiler_type) { error.SetErrorString("Null clang type for return value."); return error; } Thread *thread = frame_sp->GetThread().get(); bool is_signed; uint32_t count; bool is_complex; RegisterContext *reg_ctx = thread->GetRegisterContext().get(); bool set_it_simple = false; if (compiler_type.IsIntegerOrEnumerationType(is_signed) || compiler_type.IsPointerType()) { const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0); DataExtractor data; Status data_error; size_t num_bytes = new_value_sp->GetData(data, data_error); if (data_error.Fail()) { error.SetErrorStringWithFormat( "Couldn't convert return value to raw data: %s", data_error.AsCString()); return error; } lldb::offset_t offset = 0; if (num_bytes <= 8) { uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value)) set_it_simple = true; } else { error.SetErrorString("We don't support returning longer than 64 bit " "integer values at present."); } } else if (compiler_type.IsFloatingPointType(count, is_complex)) { if (is_complex) error.SetErrorString( "We don't support returning complex values at present"); else { size_t bit_width = compiler_type.GetBitSize(frame_sp.get()); if (bit_width <= 64) { DataExtractor data; Status data_error; size_t num_bytes = new_value_sp->GetData(data, data_error); if (data_error.Fail()) { error.SetErrorStringWithFormat( "Couldn't convert return value to raw data: %s", data_error.AsCString()); return error; } unsigned char buffer[16]; ByteOrder byte_order = data.GetByteOrder(); data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order); set_it_simple = true; } else { // FIXME - don't know how to do 80 bit long doubles yet. error.SetErrorString( "We don't support returning float values > 64 bits at present"); } } } if (!set_it_simple) { // Okay we've got a structure or something that doesn't fit in a simple // register. // We should figure out where it really goes, but we don't support this yet. error.SetErrorString("We only support setting simple integer and float " "return types at present."); } return error; }
Error RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &src, lldb::offset_t src_offset, bool partial_data_ok) { Error error; if (src.GetByteSize() == 0) { error.SetErrorString ("empty data."); return error; } if (reg_info->byte_size == 0) { error.SetErrorString ("invalid register info."); return error; } uint32_t src_len = src.GetByteSize() - src_offset; if (!partial_data_ok && (src_len < reg_info->byte_size)) { error.SetErrorString ("not enough data."); return error; } // Cap the data length if there is more than enough bytes for this register // value if (src_len > reg_info->byte_size) src_len = reg_info->byte_size; // Zero out the value in case we get partial data... memset (m_data.buffer.bytes, 0, sizeof (m_data.buffer.bytes)); switch (SetType (reg_info)) { case eTypeInvalid: error.SetErrorString(""); break; case eTypeUInt8: SetUInt8 (src.GetMaxU32 (&src_offset, src_len)); break; case eTypeUInt16: SetUInt16 (src.GetMaxU32 (&src_offset, src_len)); break; case eTypeUInt32: SetUInt32 (src.GetMaxU32 (&src_offset, src_len)); break; case eTypeUInt64: SetUInt64 (src.GetMaxU64 (&src_offset, src_len)); break; #if defined (ENABLE_128_BIT_SUPPORT) case eTypeUInt128: { __uint128_t data1 = src.GetU64 (&src_offset); __uint128_t data2 = src.GetU64 (&src_offset); if (src.GetByteSize() == eByteOrderBig) SetUInt128 (data1 << 64 + data2); else SetUInt128 (data2 << 64 + data1); } break; #endif case eTypeFloat: SetFloat (src.GetFloat (&src_offset)); break; case eTypeDouble: SetDouble(src.GetDouble (&src_offset)); break; case eTypeLongDouble: SetFloat (src.GetLongDouble (&src_offset)); break; case eTypeBytes: { m_data.buffer.length = reg_info->byte_size; m_data.buffer.byte_order = src.GetByteOrder(); assert (m_data.buffer.length <= kMaxRegisterByteSize); if (m_data.buffer.length > kMaxRegisterByteSize) m_data.buffer.length = kMaxRegisterByteSize; if (src.CopyByteOrderedData (src_offset, // offset within "src" to start extracting data src_len, // src length m_data.buffer.bytes, // dst buffer m_data.buffer.length, // dst length m_data.buffer.byte_order) == 0)// dst byte order { error.SetErrorString ("data copy failed data."); return error; } } } return error; }
lldb::offset_t lldb_private::DumpDataExtractor( const DataExtractor &DE, Stream *s, offset_t start_offset, lldb::Format item_format, size_t item_byte_size, size_t item_count, size_t num_per_line, uint64_t base_addr, uint32_t item_bit_size, // If zero, this is not a bitfield value, if // non-zero, the value is a bitfield uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the // shift amount to apply to a bitfield ExecutionContextScope *exe_scope) { if (s == nullptr) return start_offset; if (item_format == eFormatPointer) { if (item_byte_size != 4 && item_byte_size != 8) item_byte_size = s->GetAddressByteSize(); } offset_t offset = start_offset; if (item_format == eFormatInstruction) { TargetSP target_sp; if (exe_scope) target_sp = exe_scope->CalculateTarget(); if (target_sp) { DisassemblerSP disassembler_sp(Disassembler::FindPlugin( target_sp->GetArchitecture(), target_sp->GetDisassemblyFlavor(), nullptr)); if (disassembler_sp) { lldb::addr_t addr = base_addr + start_offset; lldb_private::Address so_addr; bool data_from_file = true; if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { data_from_file = false; } else { if (target_sp->GetSectionLoadList().IsEmpty() || !target_sp->GetImages().ResolveFileAddress(addr, so_addr)) so_addr.SetRawAddress(addr); } size_t bytes_consumed = disassembler_sp->DecodeInstructions( so_addr, DE, start_offset, item_count, false, data_from_file); if (bytes_consumed) { offset += bytes_consumed; const bool show_address = base_addr != LLDB_INVALID_ADDRESS; const bool show_bytes = true; ExecutionContext exe_ctx; exe_scope->CalculateExecutionContext(exe_ctx); disassembler_sp->GetInstructionList().Dump(s, show_address, show_bytes, &exe_ctx); } } } else s->Printf("invalid target"); return offset; } if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && item_byte_size > 8) item_format = eFormatHex; lldb::offset_t line_start_offset = start_offset; for (uint32_t count = 0; DE.ValidOffset(offset) && count < item_count; ++count) { if ((count % num_per_line) == 0) { if (count > 0) { if (item_format == eFormatBytesWithASCII && offset > line_start_offset) { s->Printf("%*s", static_cast<int>( (num_per_line - (offset - line_start_offset)) * 3 + 2), ""); DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, 0); } s->EOL(); } if (base_addr != LLDB_INVALID_ADDRESS) s->Printf("0x%8.8" PRIx64 ": ", (uint64_t)(base_addr + (offset - start_offset) / DE.getTargetByteSize())); line_start_offset = offset; } else if (item_format != eFormatChar && item_format != eFormatCharPrintable && item_format != eFormatCharArray && count > 0) { s->PutChar(' '); } switch (item_format) { case eFormatBoolean: if (item_byte_size <= 8) s->Printf("%s", DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset) ? "true" : "false"); else { s->Printf("error: unsupported byte size (%" PRIu64 ") for boolean format", (uint64_t)item_byte_size); return offset; } break; case eFormatBinary: if (item_byte_size <= 8) { uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset); // Avoid std::bitset<64>::to_string() since it is missing in // earlier C++ libraries std::string binary_value(64, '0'); std::bitset<64> bits(uval64); for (uint32_t i = 0; i < 64; ++i) if (bits[i]) binary_value[64 - 1 - i] = '1'; if (item_bit_size > 0) s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size); else if (item_byte_size > 0 && item_byte_size <= 8) s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8); } else { const bool is_signed = false; const unsigned radix = 2; offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); } break; case eFormatBytes: case eFormatBytesWithASCII: for (uint32_t i = 0; i < item_byte_size; ++i) { s->Printf("%2.2x", DE.GetU8(&offset)); } // Put an extra space between the groups of bytes if more than one // is being dumped in a group (item_byte_size is more than 1). if (item_byte_size > 1) s->PutChar(' '); break; case eFormatChar: case eFormatCharPrintable: case eFormatCharArray: { // If we are only printing one character surround it with single // quotes if (item_count == 1 && item_format == eFormatChar) s->PutChar('\''); const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset); if (isprint(ch)) s->Printf("%c", (char)ch); else if (item_format != eFormatCharPrintable) { switch (ch) { case '\033': s->Printf("\\e"); break; case '\a': s->Printf("\\a"); break; case '\b': s->Printf("\\b"); break; case '\f': s->Printf("\\f"); break; case '\n': s->Printf("\\n"); break; case '\r': s->Printf("\\r"); break; case '\t': s->Printf("\\t"); break; case '\v': s->Printf("\\v"); break; case '\0': s->Printf("\\0"); break; default: if (item_byte_size == 1) s->Printf("\\x%2.2x", (uint8_t)ch); else s->Printf("%" PRIu64, ch); break; } } else { s->PutChar(NON_PRINTABLE_CHAR); } // If we are only printing one character surround it with single quotes if (item_count == 1 && item_format == eFormatChar) s->PutChar('\''); } break; case eFormatEnum: // Print enum value as a signed integer when we don't get // the enum type case eFormatDecimal: if (item_byte_size <= 8) s->Printf("%" PRId64, DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset)); else { const bool is_signed = true; const unsigned radix = 10; offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); } break; case eFormatUnsigned: if (item_byte_size <= 8) s->Printf("%" PRIu64, DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset)); else { const bool is_signed = false; const unsigned radix = 10; offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); } break; case eFormatOctal: if (item_byte_size <= 8) s->Printf("0%" PRIo64, DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset)); else { const bool is_signed = false; const unsigned radix = 8; offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); } break; case eFormatOSType: { uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset); s->PutChar('\''); for (uint32_t i = 0; i < item_byte_size; ++i) { uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8)); if (isprint(ch)) s->Printf("%c", ch); else { switch (ch) { case '\033': s->Printf("\\e"); break; case '\a': s->Printf("\\a"); break; case '\b': s->Printf("\\b"); break; case '\f': s->Printf("\\f"); break; case '\n': s->Printf("\\n"); break; case '\r': s->Printf("\\r"); break; case '\t': s->Printf("\\t"); break; case '\v': s->Printf("\\v"); break; case '\0': s->Printf("\\0"); break; default: s->Printf("\\x%2.2x", ch); break; } } } s->PutChar('\''); } break; case eFormatCString: { const char *cstr = DE.GetCStr(&offset); if (!cstr) { s->Printf("NULL"); offset = LLDB_INVALID_OFFSET; } else { s->PutChar('\"'); while (const char c = *cstr) { if (isprint(c)) { s->PutChar(c); } else { switch (c) { case '\033': s->Printf("\\e"); break; case '\a': s->Printf("\\a"); break; case '\b': s->Printf("\\b"); break; case '\f': s->Printf("\\f"); break; case '\n': s->Printf("\\n"); break; case '\r': s->Printf("\\r"); break; case '\t': s->Printf("\\t"); break; case '\v': s->Printf("\\v"); break; default: s->Printf("\\x%2.2x", c); break; } } ++cstr; } s->PutChar('\"'); } } break; case eFormatPointer: s->Address(DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset), sizeof(addr_t)); break; case eFormatComplexInteger: { size_t complex_int_byte_size = item_byte_size / 2; if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) { s->Printf("%" PRIu64, DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); s->Printf(" + %" PRIu64 "i", DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); } else { s->Printf("error: unsupported byte size (%" PRIu64 ") for complex integer format", (uint64_t)item_byte_size); return offset; } } break; case eFormatComplex: if (sizeof(float) * 2 == item_byte_size) { float f32_1 = DE.GetFloat(&offset); float f32_2 = DE.GetFloat(&offset); s->Printf("%g + %gi", f32_1, f32_2); break; } else if (sizeof(double) * 2 == item_byte_size) { double d64_1 = DE.GetDouble(&offset); double d64_2 = DE.GetDouble(&offset); s->Printf("%lg + %lgi", d64_1, d64_2); break; } else if (sizeof(long double) * 2 == item_byte_size) { long double ld64_1 = DE.GetLongDouble(&offset); long double ld64_2 = DE.GetLongDouble(&offset); s->Printf("%Lg + %Lgi", ld64_1, ld64_2); break; } else { s->Printf("error: unsupported byte size (%" PRIu64 ") for complex float format", (uint64_t)item_byte_size); return offset; } break; default: case eFormatDefault: case eFormatHex: case eFormatHexUppercase: { bool wantsuppercase = (item_format == eFormatHexUppercase); switch (item_byte_size) { case 1: case 2: case 4: case 8: s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64, (int)(2 * item_byte_size), (int)(2 * item_byte_size), DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset)); break; default: { assert(item_bit_size == 0 && item_bit_offset == 0); const uint8_t *bytes = (const uint8_t *)DE.GetData(&offset, item_byte_size); if (bytes) { s->PutCString("0x"); uint32_t idx; if (DE.GetByteOrder() == eByteOrderBig) { for (idx = 0; idx < item_byte_size; ++idx) s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]); } else { for (idx = 0; idx < item_byte_size; ++idx) s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[item_byte_size - 1 - idx]); } } } break; } } break; case eFormatFloat: { TargetSP target_sp; bool used_apfloat = false; if (exe_scope) target_sp = exe_scope->CalculateTarget(); if (target_sp) { ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); if (clang_ast) { clang::ASTContext *ast = clang_ast->getASTContext(); if (ast) { llvm::SmallVector<char, 256> sv; // Show full precision when printing float values const unsigned format_precision = 0; const unsigned format_max_padding = 100; size_t item_bit_size = item_byte_size * 8; if (item_bit_size == ast->getTypeSize(ast->FloatTy)) { llvm::APInt apint(item_bit_size, DE.GetMaxU64(&offset, item_byte_size)); llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->FloatTy), apint); apfloat.toString(sv, format_precision, format_max_padding); } else if (item_bit_size == ast->getTypeSize(ast->DoubleTy)) { llvm::APInt apint; if (GetAPInt(DE, &offset, item_byte_size, apint)) { llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->DoubleTy), apint); apfloat.toString(sv, format_precision, format_max_padding); } } else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) { const auto &semantics = ast->getFloatTypeSemantics(ast->LongDoubleTy); const auto byte_size = (llvm::APFloat::getSizeInBits(semantics) + 7) / 8; llvm::APInt apint; if (GetAPInt(DE, &offset, byte_size, apint)) { llvm::APFloat apfloat(semantics, apint); apfloat.toString(sv, format_precision, format_max_padding); } } else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) { llvm::APInt apint(item_bit_size, DE.GetU16(&offset)); llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->HalfTy), apint); apfloat.toString(sv, format_precision, format_max_padding); } if (!sv.empty()) { s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data()); used_apfloat = true; } } } } if (!used_apfloat) { std::ostringstream ss; if (item_byte_size == sizeof(float) || item_byte_size == 2) { float f; if (item_byte_size == 2) { uint16_t half = DE.GetU16(&offset); f = half2float(half); } else { f = DE.GetFloat(&offset); } ss.precision(std::numeric_limits<float>::digits10); ss << f; } else if (item_byte_size == sizeof(double)) { ss.precision(std::numeric_limits<double>::digits10); ss << DE.GetDouble(&offset); } else if (item_byte_size == sizeof(long double) || item_byte_size == 10) { ss.precision(std::numeric_limits<long double>::digits10); ss << DE.GetLongDouble(&offset); } else { s->Printf("error: unsupported byte size (%" PRIu64 ") for float format", (uint64_t)item_byte_size); return offset; } ss.flush(); s->Printf("%s", ss.str().c_str()); } } break; case eFormatUnicode16: s->Printf("U+%4.4x", DE.GetU16(&offset)); break; case eFormatUnicode32: s->Printf("U+0x%8.8x", DE.GetU32(&offset)); break; case eFormatAddressInfo: { addr_t addr = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset); s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size), (int)(2 * item_byte_size), addr); if (exe_scope) { TargetSP target_sp(exe_scope->CalculateTarget()); lldb_private::Address so_addr; if (target_sp) { if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { s->PutChar(' '); so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription, Address::DumpStyleModuleWithFileAddress); } else { so_addr.SetOffset(addr); so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedPointerDescription); } } } } break; case eFormatHexFloat: if (sizeof(float) == item_byte_size) { char float_cstr[256]; llvm::APFloat ap_float(DE.GetFloat(&offset)); ap_float.convertToHexString(float_cstr, 0, false, llvm::APFloat::rmNearestTiesToEven); s->Printf("%s", float_cstr); break; } else if (sizeof(double) == item_byte_size) { char float_cstr[256]; llvm::APFloat ap_float(DE.GetDouble(&offset)); ap_float.convertToHexString(float_cstr, 0, false, llvm::APFloat::rmNearestTiesToEven); s->Printf("%s", float_cstr); break; } else { s->Printf("error: unsupported byte size (%" PRIu64 ") for hex float format", (uint64_t)item_byte_size); return offset; } break; // please keep the single-item formats below in sync with // FormatManager::GetSingleItemFormat // if you fail to do so, users will start getting different outputs // depending on internal // implementation details they should not care about || case eFormatVectorOfChar: // || s->PutChar('{'); // \/ offset = DumpDataExtractor(DE, s, offset, eFormatCharArray, 1, item_byte_size, item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfSInt8: s->PutChar('{'); offset = DumpDataExtractor(DE, s, offset, eFormatDecimal, 1, item_byte_size, item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfUInt8: s->PutChar('{'); offset = DumpDataExtractor(DE, s, offset, eFormatHex, 1, item_byte_size, item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfSInt16: s->PutChar('{'); offset = DumpDataExtractor( DE, s, offset, eFormatDecimal, sizeof(uint16_t), item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfUInt16: s->PutChar('{'); offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint16_t), item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfSInt32: s->PutChar('{'); offset = DumpDataExtractor( DE, s, offset, eFormatDecimal, sizeof(uint32_t), item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfUInt32: s->PutChar('{'); offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint32_t), item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfSInt64: s->PutChar('{'); offset = DumpDataExtractor( DE, s, offset, eFormatDecimal, sizeof(uint64_t), item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfUInt64: s->PutChar('{'); offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint64_t), item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfFloat16: s->PutChar('{'); offset = DumpDataExtractor(DE, s, offset, eFormatFloat, 2, item_byte_size / 2, item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfFloat32: s->PutChar('{'); offset = DumpDataExtractor(DE, s, offset, eFormatFloat, 4, item_byte_size / 4, item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfFloat64: s->PutChar('{'); offset = DumpDataExtractor(DE, s, offset, eFormatFloat, 8, item_byte_size / 8, item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; case eFormatVectorOfUInt128: s->PutChar('{'); offset = DumpDataExtractor(DE, s, offset, eFormatHex, 16, item_byte_size / 16, item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0); s->PutChar('}'); break; } } if (item_format == eFormatBytesWithASCII && offset > line_start_offset) { s->Printf("%*s", static_cast<int>( (num_per_line - (offset - line_start_offset)) * 3 + 2), ""); DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, 0); } return offset; // Return the offset at which we ended up }
Error RegisterValue::SetValueFromData(const RegisterInfo *reg_info, DataExtractor &src, lldb::offset_t src_offset, bool partial_data_ok) { Error error; if (src.GetByteSize() == 0) { error.SetErrorString("empty data."); return error; } if (reg_info->byte_size == 0) { error.SetErrorString("invalid register info."); return error; } uint32_t src_len = src.GetByteSize() - src_offset; if (!partial_data_ok && (src_len < reg_info->byte_size)) { error.SetErrorString("not enough data."); return error; } // Cap the data length if there is more than enough bytes for this register // value if (src_len > reg_info->byte_size) src_len = reg_info->byte_size; // Zero out the value in case we get partial data... memset(buffer.bytes, 0, sizeof(buffer.bytes)); type128 int128; m_type = eTypeInvalid; switch (reg_info->encoding) { case eEncodingInvalid: break; case eEncodingUint: case eEncodingSint: if (reg_info->byte_size == 1) SetUInt8(src.GetMaxU32(&src_offset, src_len)); else if (reg_info->byte_size <= 2) SetUInt16(src.GetMaxU32(&src_offset, src_len)); else if (reg_info->byte_size <= 4) SetUInt32(src.GetMaxU32(&src_offset, src_len)); else if (reg_info->byte_size <= 8) SetUInt64(src.GetMaxU64(&src_offset, src_len)); else if (reg_info->byte_size <= 16) { uint64_t data1 = src.GetU64(&src_offset); uint64_t data2 = src.GetU64(&src_offset); if (src.GetByteSize() == eByteOrderBig) { int128.x[0] = data1; int128.x[1] = data2; } else { int128.x[0] = data2; int128.x[1] = data1; } SetUInt128(llvm::APInt(128, 2, int128.x)); } break; case eEncodingIEEE754: if (reg_info->byte_size == sizeof(float)) SetFloat(src.GetFloat(&src_offset)); else if (reg_info->byte_size == sizeof(double)) SetDouble(src.GetDouble(&src_offset)); else if (reg_info->byte_size == sizeof(long double)) SetLongDouble(src.GetLongDouble(&src_offset)); break; case eEncodingVector: { m_type = eTypeBytes; buffer.length = reg_info->byte_size; buffer.byte_order = src.GetByteOrder(); assert(buffer.length <= kMaxRegisterByteSize); if (buffer.length > kMaxRegisterByteSize) buffer.length = kMaxRegisterByteSize; if (src.CopyByteOrderedData( src_offset, // offset within "src" to start extracting data src_len, // src length buffer.bytes, // dst buffer buffer.length, // dst length buffer.byte_order) == 0) // dst byte order { error.SetErrorStringWithFormat( "failed to copy data for register write of %s", reg_info->name); return error; } } } if (m_type == eTypeInvalid) error.SetErrorStringWithFormat( "invalid register value type for register %s", reg_info->name); return error; }
bool DWARFDebugArangeSet::Extract(const DataExtractor &data, lldb::offset_t *offset_ptr) { if (data.ValidOffset(*offset_ptr)) { m_arange_descriptors.clear(); m_offset = *offset_ptr; // 7.20 Address Range Table // // Each set of entries in the table of address ranges contained in // the .debug_aranges section begins with a header consisting of: a // 4-byte length containing the length of the set of entries for this // compilation unit, not including the length field itself; a 2-byte // version identifier containing the value 2 for DWARF Version 2; a // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer // containing the size in bytes of an address (or the offset portion of // an address for segmented addressing) on the target system; and a // 1-byte unsigned integer containing the size in bytes of a segment // descriptor on the target system. This header is followed by a series // of tuples. Each tuple consists of an address and a length, each in // the size appropriate for an address on the target architecture. m_header.length = data.GetU32(offset_ptr); m_header.version = data.GetU16(offset_ptr); m_header.cu_offset = data.GetU32(offset_ptr); m_header.addr_size = data.GetU8(offset_ptr); m_header.seg_size = data.GetU8(offset_ptr); // The first tuple following the header in each set begins at an offset // that is a multiple of the size of a single tuple (that is, twice the // size of an address). The header is padded, if necessary, to the // appropriate boundary. const uint32_t header_size = *offset_ptr - m_offset; const uint32_t tuple_size = m_header.addr_size << 1; uint32_t first_tuple_offset = 0; while (first_tuple_offset < header_size) first_tuple_offset += tuple_size; *offset_ptr = m_offset + first_tuple_offset; Descriptor arangeDescriptor; assert(sizeof(arangeDescriptor.address) == sizeof(arangeDescriptor.length)); assert(sizeof(arangeDescriptor.address) >= m_header.addr_size); while (data.ValidOffset(*offset_ptr)) { arangeDescriptor.address = data.GetMaxU64(offset_ptr, m_header.addr_size); arangeDescriptor.length = data.GetMaxU64(offset_ptr, m_header.addr_size); // Each set of tuples is terminated by a 0 for the address and 0 // for the length. if (arangeDescriptor.address || arangeDescriptor.length) m_arange_descriptors.push_back(arangeDescriptor); else break; // We are done if we get a zero address and length } return !m_arange_descriptors.empty(); } return false; }
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; }
Error ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp) { Error error; if (!new_value_sp) { error.SetErrorString("Empty value object for return value."); return error; } ClangASTType clang_type = new_value_sp->GetClangType(); if (!clang_type) { error.SetErrorString ("Null clang type for return value."); return error; } Thread *thread = frame_sp->GetThread().get(); RegisterContext *reg_ctx = thread->GetRegisterContext().get(); if (!reg_ctx) error.SetErrorString("no registers are available"); DataExtractor data; Error data_error; size_t num_bytes = new_value_sp->GetData(data, data_error); if (data_error.Fail()) { error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString()); return error; } const uint32_t type_flags = clang_type.GetTypeInfo (NULL); if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer ) { lldb::offset_t offset = 0; if (num_bytes <= 16) { const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0); if (num_bytes <= 8) { uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); if (!reg_ctx->WriteRegisterFromUnsigned (r2_info, raw_value)) error.SetErrorString ("failed to write register r2"); } else { uint64_t raw_value = data.GetMaxU64(&offset, 8); if (reg_ctx->WriteRegisterFromUnsigned (r2_info, raw_value)) { const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0); raw_value = data.GetMaxU64(&offset, num_bytes - offset); if (!reg_ctx->WriteRegisterFromUnsigned (r3_info, raw_value)) error.SetErrorString ("failed to write register r3"); } else error.SetErrorString ("failed to write register r2"); } } else { error.SetErrorString("We don't support returning longer than 128 bit integer values at present."); } } else if (type_flags & eTypeIsFloat) { error.SetErrorString("TODO: Handle Float Types."); } } else if (type_flags & eTypeIsVector) { error.SetErrorString("returning vector values are not supported"); } return error; }