static uint64_t ReadUIntMax64 (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, bool &success) { uint64_t uval64 = 0; if (exe_scope == NULL || byte_size > sizeof(uint64_t)) { success = false; return 0; } uint64_t buf = 0; success = ReadBytes (exe_scope, address, &buf, byte_size) == byte_size; if (success) { ByteOrder byte_order = eByteOrderInvalid; uint32_t addr_size = 0; if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size)) { DataExtractor data (&buf, sizeof(buf), byte_order, addr_size); lldb::offset_t offset = 0; uval64 = data.GetU64(&offset); } else success = false; } 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; }
RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64(Thread &thread, RegisterInfoInterface *register_info, const DataExtractor &gpregset, const DataExtractor &fpregset) : RegisterContextPOSIX_mips64(thread, 0, register_info) { size_t i; lldb::offset_t offset = 0; for (i = 0; i < k_num_gpr_registers_mips64; i++) { m_reg[i] = gpregset.GetU64(&offset); } }
virtual void CalculateMnemonicOperandsAndComment (const lldb_private::ExecutionContext *exe_ctx) { DataExtractor data; const AddressClass address_class = GetAddressClass (); if (m_opcode.GetData(data)) { char out_string[512]; DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC(); DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr; if (address_class == eAddressClassCodeAlternateISA) mc_disasm_ptr = llvm_disasm.m_alternate_disasm_ap.get(); else mc_disasm_ptr = llvm_disasm.m_disasm_ap.get(); lldb::addr_t pc = m_address.GetFileAddress(); m_using_file_addr = true; const bool data_from_file = GetDisassemblerLLVMC().m_data_from_file; bool use_hex_immediates = true; Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC; if (exe_ctx) { Target *target = exe_ctx->GetTargetPtr(); if (target) { use_hex_immediates = target->GetUseHexImmediates(); hex_style = target->GetHexImmediateStyle(); if (!data_from_file) { const lldb::addr_t load_addr = m_address.GetLoadAddress(target); if (load_addr != LLDB_INVALID_ADDRESS) { pc = load_addr; m_using_file_addr = false; } } } } llvm_disasm.Lock(this, exe_ctx); const uint8_t *opcode_data = data.GetDataStart(); const size_t opcode_data_len = data.GetByteSize(); llvm::MCInst inst; size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data, opcode_data_len, pc, inst); if (inst_size > 0) { mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style); mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string)); } llvm_disasm.Unlock(); if (inst_size == 0) { m_comment.assign ("unknown opcode"); inst_size = m_opcode.GetByteSize(); StreamString mnemonic_strm; lldb::offset_t offset = 0; lldb::ByteOrder byte_order = data.GetByteOrder(); switch (inst_size) { case 1: { const uint8_t uval8 = data.GetU8 (&offset); m_opcode.SetOpcode8 (uval8, byte_order); m_opcode_name.assign (".byte"); mnemonic_strm.Printf("0x%2.2x", uval8); } break; case 2: { const uint16_t uval16 = data.GetU16(&offset); m_opcode.SetOpcode16(uval16, byte_order); m_opcode_name.assign (".short"); mnemonic_strm.Printf("0x%4.4x", uval16); } break; case 4: { const uint32_t uval32 = data.GetU32(&offset); m_opcode.SetOpcode32(uval32, byte_order); m_opcode_name.assign (".long"); mnemonic_strm.Printf("0x%8.8x", uval32); } break; case 8: { const uint64_t uval64 = data.GetU64(&offset); m_opcode.SetOpcode64(uval64, byte_order); m_opcode_name.assign (".quad"); mnemonic_strm.Printf("0x%16.16" PRIx64, uval64); } break; default: if (inst_size == 0) return; else { const uint8_t *bytes = data.PeekData(offset, inst_size); if (bytes == NULL) return; m_opcode_name.assign (".byte"); m_opcode.SetOpcodeBytes(bytes, inst_size); mnemonic_strm.Printf("0x%2.2x", bytes[0]); for (uint32_t i=1; i<inst_size; ++i) mnemonic_strm.Printf(" 0x%2.2x", bytes[i]); } break; } m_mnemonics.swap(mnemonic_strm.GetString()); return; } else { if (m_does_branch == eLazyBoolCalculate) { const bool can_branch = mc_disasm_ptr->CanBranch(inst); if (can_branch) m_does_branch = eLazyBoolYes; else m_does_branch = eLazyBoolNo; } } static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED); RegularExpression::Match matches(3); if (s_regex.Execute(out_string, &matches)) { matches.GetMatchAtIndex(out_string, 1, m_opcode_name); matches.GetMatchAtIndex(out_string, 2, m_mnemonics); } } }
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; }
void CommunicationKDP::DumpPacket(Stream &s, const DataExtractor &packet) { const char *error_desc = NULL; if (packet.GetByteSize() < 8) { error_desc = "error: invalid packet (too short): "; } else { lldb::offset_t offset = 0; const uint8_t first_packet_byte = packet.GetU8(&offset); const uint8_t sequence_id = packet.GetU8(&offset); const uint16_t length = packet.GetU16(&offset); const uint32_t key = packet.GetU32(&offset); const CommandType command = ExtractCommand(first_packet_byte); const char *command_name = GetCommandAsCString(command); if (command_name) { const bool is_reply = ExtractIsReply(first_packet_byte); s.Printf("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ", IsRunning(), is_reply ? "<--" : "-->", command_name, first_packet_byte, sequence_id, length, key); if (is_reply) { // Dump request reply packets switch (command) { // Commands that return a single 32 bit error case KDP_CONNECT: case KDP_WRITEMEM: case KDP_WRITEMEM64: case KDP_BREAKPOINT_SET: case KDP_BREAKPOINT_REMOVE: case KDP_BREAKPOINT_SET64: case KDP_BREAKPOINT_REMOVE64: case KDP_WRITEREGS: case KDP_LOAD: case KDP_WRITEIOPORT: case KDP_WRITEMSR64: { const uint32_t error = packet.GetU32(&offset); s.Printf(" (error=0x%8.8x)", error); } break; case KDP_DISCONNECT: case KDP_REATTACH: case KDP_HOSTREBOOT: case KDP_SUSPEND: case KDP_RESUMECPUS: case KDP_EXCEPTION: case KDP_TERMINATION: // No return value for the reply, just the header to ack s.PutCString(" ()"); break; case KDP_HOSTINFO: { const uint32_t cpu_mask = packet.GetU32(&offset); const uint32_t cpu_type = packet.GetU32(&offset); const uint32_t cpu_subtype = packet.GetU32(&offset); s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)", cpu_mask, cpu_type, cpu_subtype); } break; case KDP_VERSION: { const uint32_t version = packet.GetU32(&offset); const uint32_t feature = packet.GetU32(&offset); s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature); } break; case KDP_REGIONS: { const uint32_t region_count = packet.GetU32(&offset); s.Printf(" (count = %u", region_count); for (uint32_t i = 0; i < region_count; ++i) { const addr_t region_addr = packet.GetPointer(&offset); const uint32_t region_size = packet.GetU32(&offset); const uint32_t region_prot = packet.GetU32(&offset); s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }", region_addr, region_addr, region_addr + region_size, region_size, GetPermissionsAsCString(region_prot)); } } break; case KDP_READMEM: case KDP_READMEM64: case KDP_READPHYSMEM64: { const uint32_t error = packet.GetU32(&offset); const uint32_t count = packet.GetByteSize() - offset; s.Printf(" (error = 0x%8.8x:\n", error); if (count > 0) DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatBytesWithASCII, // Format to use 1, // Size of each item // in bytes count, // Number of items 16, // Number per line m_last_read_memory_addr, // Don't show addresses // before each line 0, 0); // No bitfields } break; case KDP_READREGS: { const uint32_t error = packet.GetU32(&offset); const uint32_t count = packet.GetByteSize() - offset; s.Printf(" (error = 0x%8.8x regs:\n", error); if (count > 0) DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use m_addr_byte_size, // Size of each item // in bytes count / m_addr_byte_size, // Number of items 16 / m_addr_byte_size, // Number per line LLDB_INVALID_ADDRESS, // Don't // show addresses before // each line 0, 0); // No bitfields } break; case KDP_KERNELVERSION: { const char *kernel_version = packet.PeekCStr(8); s.Printf(" (version = \"%s\")", kernel_version); } break; case KDP_MAXBYTES: { const uint32_t max_bytes = packet.GetU32(&offset); s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes); } break; case KDP_IMAGEPATH: { const char *path = packet.GetCStr(&offset); s.Printf(" (path = \"%s\")", path); } break; case KDP_READIOPORT: case KDP_READMSR64: { const uint32_t error = packet.GetU32(&offset); const uint32_t count = packet.GetByteSize() - offset; s.Printf(" (error = 0x%8.8x io:\n", error); if (count > 0) DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use 1, // Size of each item in bytes count, // Number of items 16, // Number per line LLDB_INVALID_ADDRESS, // Don't show addresses // before each line 0, 0); // No bitfields } break; case KDP_DUMPINFO: { const uint32_t count = packet.GetByteSize() - offset; s.Printf(" (count = %u, bytes = \n", count); if (count > 0) DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use 1, // Size of each item in // bytes count, // Number of items 16, // Number per line LLDB_INVALID_ADDRESS, // Don't show addresses // before each line 0, 0); // No bitfields } break; default: s.Printf(" (add support for dumping this packet reply!!!"); break; } } else { // Dump request packets switch (command) { case KDP_CONNECT: { const uint16_t reply_port = ntohs(packet.GetU16(&offset)); const uint16_t exc_port = ntohs(packet.GetU16(&offset)); s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")", reply_port, exc_port, packet.GetCStr(&offset)); } break; case KDP_DISCONNECT: case KDP_HOSTREBOOT: case KDP_HOSTINFO: case KDP_VERSION: case KDP_REGIONS: case KDP_KERNELVERSION: case KDP_MAXBYTES: case KDP_IMAGEPATH: case KDP_SUSPEND: // No args, just the header in the request... s.PutCString(" ()"); break; case KDP_RESUMECPUS: { const uint32_t cpu_mask = packet.GetU32(&offset); s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask); } break; case KDP_READMEM: { const uint32_t addr = packet.GetU32(&offset); const uint32_t size = packet.GetU32(&offset); s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size); m_last_read_memory_addr = addr; } break; case KDP_WRITEMEM: { const uint32_t addr = packet.GetU32(&offset); const uint32_t size = packet.GetU32(&offset); s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size); if (size > 0) DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr); } break; case KDP_READMEM64: { const uint64_t addr = packet.GetU64(&offset); const uint32_t size = packet.GetU32(&offset); s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size); m_last_read_memory_addr = addr; } break; case KDP_READPHYSMEM64: { const uint64_t addr = packet.GetU64(&offset); const uint32_t size = packet.GetU32(&offset); const uint32_t lcpu = packet.GetU16(&offset); s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size, lcpu); m_last_read_memory_addr = addr; } break; case KDP_WRITEMEM64: { const uint64_t addr = packet.GetU64(&offset); const uint32_t size = packet.GetU32(&offset); s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr, size); if (size > 0) DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr); } break; case KDP_WRITEPHYSMEM64: { const uint64_t addr = packet.GetU64(&offset); const uint32_t size = packet.GetU32(&offset); const uint32_t lcpu = packet.GetU16(&offset); s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n", addr, size, lcpu); if (size > 0) DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr); } break; case KDP_READREGS: { const uint32_t cpu = packet.GetU32(&offset); const uint32_t flavor = packet.GetU32(&offset); s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor); } break; case KDP_WRITEREGS: { const uint32_t cpu = packet.GetU32(&offset); const uint32_t flavor = packet.GetU32(&offset); const uint32_t nbytes = packet.GetByteSize() - offset; s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor); if (nbytes > 0) DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within // "packet" eFormatHex, // Format to use m_addr_byte_size, // Size of each item in // bytes nbytes / m_addr_byte_size, // Number of items 16 / m_addr_byte_size, // Number per line LLDB_INVALID_ADDRESS, // Don't show addresses // before each line 0, 0); // No bitfields } break; case KDP_BREAKPOINT_SET: case KDP_BREAKPOINT_REMOVE: { const uint32_t addr = packet.GetU32(&offset); s.Printf(" (addr = 0x%8.8x)", addr); } break; case KDP_BREAKPOINT_SET64: case KDP_BREAKPOINT_REMOVE64: { const uint64_t addr = packet.GetU64(&offset); s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr); } break; case KDP_LOAD: { const char *path = packet.GetCStr(&offset); s.Printf(" (path = \"%s\")", path); } break; case KDP_EXCEPTION: { const uint32_t count = packet.GetU32(&offset); for (uint32_t i = 0; i < count; ++i) { const uint32_t cpu = packet.GetU32(&offset); const uint32_t exc = packet.GetU32(&offset); const uint32_t code = packet.GetU32(&offset); const uint32_t subcode = packet.GetU32(&offset); const char *exc_cstr = NULL; switch (exc) { case 1: exc_cstr = "EXC_BAD_ACCESS"; break; case 2: exc_cstr = "EXC_BAD_INSTRUCTION"; break; case 3: exc_cstr = "EXC_ARITHMETIC"; break; case 4: exc_cstr = "EXC_EMULATION"; break; case 5: exc_cstr = "EXC_SOFTWARE"; break; case 6: exc_cstr = "EXC_BREAKPOINT"; break; case 7: exc_cstr = "EXC_SYSCALL"; break; case 8: exc_cstr = "EXC_MACH_SYSCALL"; break; case 9: exc_cstr = "EXC_RPC_ALERT"; break; case 10: exc_cstr = "EXC_CRASH"; break; default: break; } s.Printf("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), " "subcode = %u (0x%8.8x)} ", cpu, exc_cstr, exc, code, code, subcode, subcode); } } break; case KDP_TERMINATION: { const uint32_t term_code = packet.GetU32(&offset); const uint32_t exit_code = packet.GetU32(&offset); s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))", term_code, term_code, exit_code, exit_code); } break; case KDP_REATTACH: { const uint16_t reply_port = ntohs(packet.GetU16(&offset)); s.Printf(" (reply_port = %u)", reply_port); } break; case KDP_READMSR64: { const uint32_t address = packet.GetU32(&offset); const uint16_t lcpu = packet.GetU16(&offset); s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu); } break; case KDP_WRITEMSR64: { const uint32_t address = packet.GetU32(&offset); const uint16_t lcpu = packet.GetU16(&offset); const uint32_t nbytes = packet.GetByteSize() - offset; s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu, address, nbytes); if (nbytes > 0) DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use 1, // Size of each item in // bytes nbytes, // Number of items 16, // Number per line LLDB_INVALID_ADDRESS, // Don't show addresses // before each line 0, 0); // No bitfields } break; case KDP_READIOPORT: { const uint16_t lcpu = packet.GetU16(&offset); const uint16_t address = packet.GetU16(&offset); const uint16_t nbytes = packet.GetU16(&offset); s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address, nbytes); } break; case KDP_WRITEIOPORT: { const uint16_t lcpu = packet.GetU16(&offset); const uint16_t address = packet.GetU16(&offset); const uint16_t nbytes = packet.GetU16(&offset); s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu, address, nbytes); if (nbytes > 0) DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use 1, // Size of each item in // bytes nbytes, // Number of items 16, // Number per line LLDB_INVALID_ADDRESS, // Don't show addresses // before each line 0, 0); // No bitfields } break; case KDP_DUMPINFO: { const uint32_t count = packet.GetByteSize() - offset; s.Printf(" (count = %u, bytes = \n", count); if (count > 0) DumpDataExtractor(packet, &s, // Stream to dump to offset, // Offset within "packet" eFormatHex, // Format to use 1, // Size of each item in bytes count, // Number of items 16, // Number per line LLDB_INVALID_ADDRESS, // Don't show addresses before each line 0, 0); // No bitfields } break; } } } else { error_desc = "error: invalid packet command: "; } } if (error_desc) { s.PutCString(error_desc); DumpDataExtractor(packet, &s, // Stream to dump to 0, // Offset into "packet" eFormatBytes, // Dump as hex bytes 1, // Size of each item is 1 for // single bytes packet.GetByteSize(), // Number of bytes UINT32_MAX, // Num bytes per line LLDB_INVALID_ADDRESS, // Base address 0, 0); // Bitfield info set to not do // anything bitfield related } }
void SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count, lldb_private::QueueList &queue_list) { Error error; DataBufferHeap data (queues_buffer_size, 0); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME)); if (m_process->ReadMemory (queues_buffer, data.GetBytes(), queues_buffer_size, error) == queues_buffer_size && error.Success()) { // We've read the information out of inferior memory; free it on the next call we make m_page_to_free = queues_buffer; m_page_to_free_size = queues_buffer_size; DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize()); offset_t offset = 0; uint64_t queues_read = 0; // The information about the queues is stored in this format (v1): // typedef struct introspection_dispatch_queue_info_s { // uint32_t offset_to_next; // dispatch_queue_t queue; // uint64_t serialnum; // queue's serialnum in the process, as provided by libdispatch // uint32_t running_work_items_count; // uint32_t pending_work_items_count; // // char data[]; // Starting here, we have variable-length data: // // char queue_label[]; // } introspection_dispatch_queue_info_s; while (queues_read < count && offset < queues_buffer_size) { offset_t start_of_this_item = offset; uint32_t offset_to_next = extractor.GetU32 (&offset); offset += 4; // Skip over the 4 bytes of reserved space addr_t queue = extractor.GetPointer (&offset); uint64_t serialnum = extractor.GetU64 (&offset); uint32_t running_work_items_count = extractor.GetU32 (&offset); uint32_t pending_work_items_count = extractor.GetU32 (&offset); // Read the first field of the variable length data offset = start_of_this_item + m_lib_backtrace_recording_info.queue_info_data_offset; const char *queue_label = extractor.GetCStr (&offset); if (queue_label == NULL) queue_label = ""; offset_t start_of_next_item = start_of_this_item + offset_to_next; offset = start_of_next_item; if (log) log->Printf ("SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR added queue with dispatch_queue_t 0x%" PRIx64 ", serial number 0x%" PRIx64 ", running items %d, pending items %d, name '%s'", queue, serialnum, running_work_items_count, pending_work_items_count, queue_label); QueueSP queue_sp (new Queue (m_process->shared_from_this(), serialnum, queue_label)); queue_sp->SetNumRunningWorkItems (running_work_items_count); queue_sp->SetNumPendingWorkItems (pending_work_items_count); queue_sp->SetLibdispatchQueueAddress (queue); queue_sp->SetKind (GetQueueKind (queue)); queue_list.AddQueue (queue_sp); queues_read++; } } }
virtual void CalculateMnemonicOperandsAndComment (const lldb_private::ExecutionContext *exe_ctx) { DataExtractor data; const AddressClass address_class = GetAddressClass (); if (m_opcode.GetData(data, address_class)) { char out_string[512]; ::LLVMDisasmContextRef disasm_context; if (address_class == eAddressClassCodeAlternateISA) disasm_context = m_disasm.m_alternate_disasm_context; else disasm_context = m_disasm.m_disasm_context; lldb::addr_t pc = LLDB_INVALID_ADDRESS; if (exe_ctx) { Target *target = exe_ctx->GetTargetPtr(); if (target) pc = m_address.GetLoadAddress(target); } if (pc == LLDB_INVALID_ADDRESS) pc = m_address.GetFileAddress(); m_disasm.Lock(this, exe_ctx); uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1)); const size_t opcode_data_len = data.GetByteSize(); size_t inst_size = ::LLVMDisasmInstruction (disasm_context, opcode_data, opcode_data_len, pc, out_string, sizeof(out_string)); m_disasm.Unlock(); if (inst_size == 0) { m_comment.assign ("unknown opcode"); inst_size = m_opcode.GetByteSize(); StreamString mnemonic_strm; uint32_t offset = 0; switch (inst_size) { case 1: { const uint8_t uval8 = data.GetU8 (&offset); m_opcode.SetOpcode8 (uval8); m_opcode_name.assign (".byte"); mnemonic_strm.Printf("0x%2.2x", uval8); } break; case 2: { const uint16_t uval16 = data.GetU16(&offset); m_opcode.SetOpcode16(uval16); m_opcode_name.assign (".short"); mnemonic_strm.Printf("0x%4.4x", uval16); } break; case 4: { const uint32_t uval32 = data.GetU32(&offset); m_opcode.SetOpcode32(uval32); m_opcode_name.assign (".long"); mnemonic_strm.Printf("0x%8.8x", uval32); } break; case 8: { const uint64_t uval64 = data.GetU64(&offset); m_opcode.SetOpcode64(uval64); m_opcode_name.assign (".quad"); mnemonic_strm.Printf("0x%16.16llx", uval64); } break; default: if (inst_size == 0) return; else { const uint8_t *bytes = data.PeekData(offset, inst_size); if (bytes == NULL) return; m_opcode_name.assign (".byte"); m_opcode.SetOpcodeBytes(bytes, inst_size); mnemonic_strm.Printf("0x%2.2x", bytes[0]); for (uint32_t i=1; i<inst_size; ++i) mnemonic_strm.Printf(" 0x%2.2x", bytes[i]); } break; } m_mnemocics.swap(mnemonic_strm.GetString()); return; } else { if (m_does_branch == eLazyBoolCalculate) { if (StringRepresentsBranch (out_string, strlen(out_string))) m_does_branch = eLazyBoolYes; else m_does_branch = eLazyBoolNo; } } if (!s_regex_compiled) { ::regcomp(&s_regex, "[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED); s_regex_compiled = true; } ::regmatch_t matches[3]; if (!::regexec(&s_regex, out_string, sizeof(matches) / sizeof(::regmatch_t), matches, 0)) { if (matches[1].rm_so != -1) m_opcode_name.assign(out_string + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so); if (matches[2].rm_so != -1) m_mnemocics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so); } } }
// Parse the load commands for an image uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data, ImageInfo &dylib_info, FileSpec *lc_id_dylinker) { lldb::offset_t offset = 0; uint32_t cmd_idx; Segment segment; dylib_info.Clear(true); for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++) { // Clear out any load command specific data from DYLIB_INFO since we are // about to read it. if (data.ValidOffsetForDataOfSize(offset, sizeof(llvm::MachO::load_command))) { llvm::MachO::load_command load_cmd; lldb::offset_t load_cmd_offset = offset; load_cmd.cmd = data.GetU32(&offset); load_cmd.cmdsize = data.GetU32(&offset); switch (load_cmd.cmd) { case llvm::MachO::LC_SEGMENT: { segment.name.SetTrimmedCStringWithLength( (const char *)data.GetData(&offset, 16), 16); // We are putting 4 uint32_t values 4 uint64_t values so we have to use // multiple 32 bit gets below. segment.vmaddr = data.GetU32(&offset); segment.vmsize = data.GetU32(&offset); segment.fileoff = data.GetU32(&offset); segment.filesize = data.GetU32(&offset); // Extract maxprot, initprot, nsects and flags all at once data.GetU32(&offset, &segment.maxprot, 4); dylib_info.segments.push_back(segment); } break; case llvm::MachO::LC_SEGMENT_64: { segment.name.SetTrimmedCStringWithLength( (const char *)data.GetData(&offset, 16), 16); // Extract vmaddr, vmsize, fileoff, and filesize all at once data.GetU64(&offset, &segment.vmaddr, 4); // Extract maxprot, initprot, nsects and flags all at once data.GetU32(&offset, &segment.maxprot, 4); dylib_info.segments.push_back(segment); } break; case llvm::MachO::LC_ID_DYLINKER: if (lc_id_dylinker) { const lldb::offset_t name_offset = load_cmd_offset + data.GetU32(&offset); const char *path = data.PeekCStr(name_offset); lc_id_dylinker->SetFile(path, FileSpec::Style::native); FileSystem::Instance().Resolve(*lc_id_dylinker); } break; case llvm::MachO::LC_UUID: dylib_info.uuid = UUID::fromOptionalData(data.GetData(&offset, 16), 16); break; default: break; } // Set offset to be the beginning of the next load command. offset = load_cmd_offset + load_cmd.cmdsize; } } // All sections listed in the dyld image info structure will all either be // fixed up already, or they will all be off by a single slide amount that is // determined by finding the first segment that is at file offset zero which // also has bytes (a file size that is greater than zero) in the object file. // Determine the slide amount (if any) const size_t num_sections = dylib_info.segments.size(); for (size_t i = 0; i < num_sections; ++i) { // Iterate through the object file sections to find the first section that // starts of file offset zero and that has bytes in the file... if ((dylib_info.segments[i].fileoff == 0 && dylib_info.segments[i].filesize > 0) || (dylib_info.segments[i].name == "__TEXT")) { dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr; // We have found the slide amount, so we can exit this for loop. break; } } return cmd_idx; }
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; }
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; }
uint32_t DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr, uint32_t image_infos_count, OSKextLoadedKextSummary::collection &image_infos) { const ByteOrder endian = m_kernel.GetByteOrder(); const uint32_t addr_size = m_kernel.GetAddressByteSize(); image_infos.resize(image_infos_count); const size_t count = image_infos.size() * m_kext_summary_header.entry_size; DataBufferHeap data(count, 0); Error error; Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); if (s) s->Printf ("Reading %u kext summaries...\n", image_infos_count); const bool prefer_file_cache = false; const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr, prefer_file_cache, data.GetBytes(), data.GetByteSize(), error); if (bytes_read == count) { DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size); uint32_t i=0; for (uint32_t kext_summary_offset = 0; i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size); ++i, kext_summary_offset += m_kext_summary_header.entry_size) { uint32_t offset = kext_summary_offset; const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME); if (name_data == NULL) break; memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME); image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16)); image_infos[i].address = extractor.GetU64(&offset); if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget())) m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address); image_infos[i].size = extractor.GetU64(&offset); image_infos[i].version = extractor.GetU64(&offset); image_infos[i].load_tag = extractor.GetU32(&offset); image_infos[i].flags = extractor.GetU32(&offset); if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size) { image_infos[i].reference_list = extractor.GetU64(&offset); } else { image_infos[i].reference_list = 0; } // printf ("[%3u] %*.*s: address=0x%16.16llx, size=0x%16.16llx, version=0x%16.16llx, load_tag=0x%8.8x, flags=0x%8.8x\n", // i, // KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data, // image_infos[i].address, // image_infos[i].size, // image_infos[i].version, // image_infos[i].load_tag, // image_infos[i].flags); } if (i < image_infos.size()) image_infos.resize(i); } else { image_infos.clear(); } return image_infos.size(); }
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; }