lldb::offset_t DWARFMappedHash::Prologue::Read (const lldb_private::DataExtractor &data, lldb::offset_t offset) { ClearAtoms (); die_base_offset = data.GetU32 (&offset); const uint32_t atom_count = data.GetU32 (&offset); if (atom_count == 0x00060003u) { // Old format, deal with contents of old pre-release format while (data.GetU32(&offset)) /* do nothing */; // Hardcode to the only known value for now. AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4); } else { for (uint32_t i=0; i<atom_count; ++i) { AtomType type = (AtomType)data.GetU16 (&offset); dw_form_t form = (dw_form_t)data.GetU16 (&offset); AppendAtom (type, form); } } return offset; }
bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) { const unsigned byte_size = data.GetAddressByteSize(); // Read sh_name and sh_type. if (data.GetU32(offset, &sh_name, 2) == NULL) return false; // Read sh_flags. if (GetMaxU64(data, offset, &sh_flags, byte_size) == false) return false; // Read sh_addr, sh_off and sh_size. if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false) return false; // Read sh_link and sh_info. if (data.GetU32(offset, &sh_link, 2) == NULL) return false; // Read sh_addralign and sh_entsize. if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false) return false; return true; }
bool CompilerType::ReadFromMemory (lldb_private::ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, lldb_private::DataExtractor &data) { if (!IsValid()) return false; // Can't convert a file address to anything valid without more // context (which Module it came from) if (address_type == eAddressTypeFile) return false; if (!GetCompleteType()) return false; const uint64_t byte_size = GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); if (data.GetByteSize() < byte_size) { lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0')); data.SetData(data_sp); } uint8_t* dst = const_cast<uint8_t*>(data.PeekData(0, byte_size)); if (dst != nullptr) { if (address_type == eAddressTypeHost) { if (addr == 0) return false; // The address is an address in this process, so just copy it memcpy (dst, (uint8_t*)nullptr + addr, byte_size); return true; } else { Process *process = nullptr; if (exe_ctx) process = exe_ctx->GetProcessPtr(); if (process) { Error error; return process->ReadMemory(addr, dst, byte_size, error) == byte_size; } } } return false; }
bool ELFHeader::Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset) { // Read e_ident. This provides byte order and address size info. if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL) return false; const unsigned byte_size = Is32Bit() ? 4 : 8; data.SetByteOrder(GetByteOrder()); data.SetAddressByteSize(byte_size); // Read e_type and e_machine. if (data.GetU16(offset, &e_type, 2) == NULL) return false; // Read e_version. if (data.GetU32(offset, &e_version, 1) == NULL) return false; // Read e_entry, e_phoff and e_shoff. if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false) return false; // Read e_flags. if (data.GetU32(offset, &e_flags, 1) == NULL) return false; // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and // e_shstrndx. if (data.GetU16(offset, &e_ehsize, 6) == NULL) return false; return true; }
static bool GetMaxS64(const lldb_private::DataExtractor &data, lldb::offset_t *offset, int64_t *value, uint32_t byte_size) { const lldb::offset_t saved_offset = *offset; *value = data.GetMaxS64(offset, byte_size); return *offset != saved_offset; }
bool ELFRel::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) { const unsigned byte_size = data.GetAddressByteSize(); // Read r_offset and r_info. if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) return false; return true; }
size_t ObjectFileJIT::ReadSectionData (const lldb_private::Section *section, lldb_private::DataExtractor& section_data) const { if (section->GetFileSize()) { const void *src = (void *)(uintptr_t)section->GetFileOffset(); DataBufferSP data_sp (new lldb_private::DataBufferHeap(src, section->GetFileSize())); if (data_sp) { section_data.SetData (data_sp, 0, data_sp->GetByteSize()); section_data.SetByteOrder (GetByteOrder()); section_data.SetAddressByteSize (GetAddressByteSize()); return section_data.GetByteSize(); } } section_data.Clear(); return 0; }
bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) { const uint32_t byte_size = data.GetAddressByteSize(); const bool parsing_32 = byte_size == 4; // Read p_type; if (data.GetU32(offset, &p_type, 1) == NULL) return false; if (parsing_32) { // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz. if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false) return false; // Read p_flags. if (data.GetU32(offset, &p_flags, 1) == NULL) return false; // Read p_align. if (GetMaxU64(data, offset, &p_align, byte_size) == false) return false; } else { // Read p_flags. if (data.GetU32(offset, &p_flags, 1) == NULL) return false; // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align. if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false) return false; } return true; }
bool ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) { const unsigned byte_size = data.GetAddressByteSize(); const bool parsing_32 = byte_size == 4; // Read st_name. if (data.GetU32(offset, &st_name, 1) == NULL) return false; if (parsing_32) { // Read st_value and st_size. if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false) return false; // Read st_info and st_other. if (data.GetU8(offset, &st_info, 2) == NULL) return false; // Read st_shndx. if (data.GetU16(offset, &st_shndx, 1) == NULL) return false; } else { // Read st_info and st_other. if (data.GetU8(offset, &st_info, 2) == NULL) return false; // Read st_shndx. if (data.GetU16(offset, &st_shndx, 1) == NULL) return false; // Read st_value and st_size. if (data.GetU64(offset, &st_value, 2) == NULL) return false; } return true; }
bool ObjectContainerUniversalMachO::ParseHeader( lldb_private::DataExtractor &data, llvm::MachO::fat_header &header, std::vector<llvm::MachO::fat_arch> &fat_archs) { bool success = false; // Store the file offset for this universal file as we could have a universal // .o file // in a BSD archive, or be contained in another kind of object. // Universal mach-o files always have their headers in big endian. lldb::offset_t offset = 0; data.SetByteOrder(eByteOrderBig); header.magic = data.GetU32(&offset); fat_archs.clear(); if (header.magic == FAT_MAGIC) { data.SetAddressByteSize(4); header.nfat_arch = data.GetU32(&offset); // Now we should have enough data for all of the fat headers, so lets index // them so we know how many architectures that this universal binary // contains. uint32_t arch_idx = 0; for (arch_idx = 0; arch_idx < header.nfat_arch; ++arch_idx) { if (data.ValidOffsetForDataOfSize(offset, sizeof(fat_arch))) { fat_arch arch; if (data.GetU32(&offset, &arch, sizeof(fat_arch) / sizeof(uint32_t))) fat_archs.push_back(arch); } } success = true; } else { memset(&header, 0, sizeof(header)); } return success; }
virtual size_t Decode (const lldb_private::Disassembler &disassembler, const lldb_private::DataExtractor &data, lldb::offset_t data_offset) { // All we have to do is read the opcode which can be easy for some // architectures bool got_op = false; DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC(); const ArchSpec &arch = llvm_disasm.GetArchitecture(); const lldb::ByteOrder byte_order = data.GetByteOrder(); const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize(); const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize(); if (min_op_byte_size == max_op_byte_size) { // Fixed size instructions, just read that amount of data. if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size)) return false; switch (min_op_byte_size) { case 1: m_opcode.SetOpcode8 (data.GetU8 (&data_offset), byte_order); got_op = true; break; case 2: m_opcode.SetOpcode16 (data.GetU16 (&data_offset), byte_order); got_op = true; break; case 4: m_opcode.SetOpcode32 (data.GetU32 (&data_offset), byte_order); got_op = true; break; case 8: m_opcode.SetOpcode64 (data.GetU64 (&data_offset), byte_order); got_op = true; break; default: m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size); got_op = true; break; } } if (!got_op) { bool is_alternate_isa = false; DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa); const llvm::Triple::ArchType machine = arch.GetMachine(); if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) { if (machine == llvm::Triple::thumb || is_alternate_isa) { uint32_t thumb_opcode = data.GetU16(&data_offset); if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) { m_opcode.SetOpcode16 (thumb_opcode, byte_order); m_is_valid = true; } else { thumb_opcode <<= 16; thumb_opcode |= data.GetU16(&data_offset); m_opcode.SetOpcode16_2 (thumb_opcode, byte_order); m_is_valid = true; } } else { m_opcode.SetOpcode32 (data.GetU32(&data_offset), byte_order); m_is_valid = true; } } else { // The opcode isn't evenly sized, so we need to actually use the llvm // disassembler to parse it and get the size. uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1)); const size_t opcode_data_len = data.BytesLeft(data_offset); const addr_t pc = m_address.GetFileAddress(); llvm::MCInst inst; llvm_disasm.Lock(this, NULL); const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst); llvm_disasm.Unlock(); if (inst_size == 0) m_opcode.Clear(); else { m_opcode.SetOpcodeBytes(opcode_data, inst_size); m_is_valid = true; } } } return m_opcode.GetByteSize(); }
SystemRuntimeMacOSX::ItemInfo SystemRuntimeMacOSX::ExtractItemInfoFromBuffer (lldb_private::DataExtractor &extractor) { ItemInfo item; offset_t offset = 0; item.item_that_enqueued_this = extractor.GetPointer (&offset); item.function_or_block = extractor.GetPointer (&offset); item.enqueuing_thread_id = extractor.GetU64 (&offset); item.enqueuing_queue_serialnum = extractor.GetU64 (&offset); item.target_queue_serialnum = extractor.GetU64 (&offset); item.enqueuing_callstack_frame_count = extractor.GetU32 (&offset); item.stop_id = extractor.GetU32 (&offset); offset = m_lib_backtrace_recording_info.item_info_data_offset; for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++) { item.enqueuing_callstack.push_back (extractor.GetPointer (&offset)); } item.enqueuing_thread_label = extractor.GetCStr (&offset); item.enqueuing_queue_label = extractor.GetCStr (&offset); item.target_queue_label = extractor.GetCStr (&offset); return item; }
bool ELFDynamic::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) { const unsigned byte_size = data.GetAddressByteSize(); return GetMaxS64(data, offset, &d_tag, byte_size, 2); }
virtual size_t Decode (const lldb_private::Disassembler &disassembler, const lldb_private::DataExtractor &data, uint32_t data_offset) { // All we have to do is read the opcode which can be easy for some // architetures bool got_op = false; const ArchSpec &arch = m_disasm.GetArchitecture(); const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize(); const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize(); if (min_op_byte_size == max_op_byte_size) { // Fixed size instructions, just read that amount of data. if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size)) return false; switch (min_op_byte_size) { case 1: m_opcode.SetOpcode8 (data.GetU8 (&data_offset)); got_op = true; break; case 2: m_opcode.SetOpcode16 (data.GetU16 (&data_offset)); got_op = true; break; case 4: m_opcode.SetOpcode32 (data.GetU32 (&data_offset)); got_op = true; break; case 8: m_opcode.SetOpcode64 (data.GetU64 (&data_offset)); got_op = true; break; default: m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size); got_op = true; break; } } if (!got_op) { ::LLVMDisasmContextRef disasm_context = m_disasm.m_disasm_context; bool is_altnernate_isa = false; if (m_disasm.m_alternate_disasm_context) { const AddressClass address_class = GetAddressClass (); if (address_class == eAddressClassCodeAlternateISA) { disasm_context = m_disasm.m_alternate_disasm_context; is_altnernate_isa = true; } } const llvm::Triple::ArchType machine = arch.GetMachine(); if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) { if (machine == llvm::Triple::thumb || is_altnernate_isa) { uint32_t thumb_opcode = data.GetU16(&data_offset); if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) { m_opcode.SetOpcode16 (thumb_opcode); } else { thumb_opcode <<= 16; thumb_opcode |= data.GetU16(&data_offset); m_opcode.SetOpcode32 (thumb_opcode); m_is_valid = true; } } else { m_opcode.SetOpcode32 (data.GetU32(&data_offset)); } } else { // The opcode isn't evenly sized, so we need to actually use the llvm // disassembler to parse it and get the size. char out_string[512]; m_disasm.Lock(this, NULL); uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1)); const size_t opcode_data_len = data.GetByteSize() - data_offset; const addr_t pc = m_address.GetFileAddress(); const size_t inst_size = ::LLVMDisasmInstruction (disasm_context, opcode_data, opcode_data_len, pc, // PC value out_string, sizeof(out_string)); // The address lookup function could have caused us to fill in our comment m_comment.clear(); m_disasm.Unlock(); if (inst_size == 0) m_opcode.Clear(); else { m_opcode.SetOpcodeBytes(opcode_data, inst_size); m_is_valid = true; } } } return m_opcode.GetByteSize(); }
bool CompilerType::GetValueAsScalar (const lldb_private::DataExtractor &data, lldb::offset_t data_byte_offset, size_t data_byte_size, Scalar &value) const { if (!IsValid()) return false; if (0 == (GetTypeInfo() & eTypeHasValue)) { return false; // Aggregate types don't have scalar values } else { uint64_t count = 0; lldb::Encoding encoding = GetEncoding (count); if (encoding == lldb::eEncodingInvalid || count != 1) return false; const uint64_t byte_size = GetByteSize(nullptr); lldb::offset_t offset = data_byte_offset; switch (encoding) { case lldb::eEncodingInvalid: break; case lldb::eEncodingVector: break; case lldb::eEncodingUint: if (byte_size <= sizeof(unsigned long long)) { uint64_t uval64 = data.GetMaxU64 (&offset, byte_size); if (byte_size <= sizeof(unsigned int)) { value = (unsigned int)uval64; return true; } else if (byte_size <= sizeof(unsigned long)) { value = (unsigned long)uval64; return true; } else if (byte_size <= sizeof(unsigned long long)) { value = (unsigned long long )uval64; return true; } else value.Clear(); } break; case lldb::eEncodingSint: if (byte_size <= sizeof(long long)) { int64_t sval64 = data.GetMaxS64 (&offset, byte_size); if (byte_size <= sizeof(int)) { value = (int)sval64; return true; } else if (byte_size <= sizeof(long)) { value = (long)sval64; return true; } else if (byte_size <= sizeof(long long)) { value = (long long )sval64; return true; } else value.Clear(); } break; case lldb::eEncodingIEEE754: if (byte_size <= sizeof(long double)) { uint32_t u32; uint64_t u64; if (byte_size == sizeof(float)) { if (sizeof(float) == sizeof(uint32_t)) { u32 = data.GetU32(&offset); value = *((float *)&u32); return true; } else if (sizeof(float) == sizeof(uint64_t)) { u64 = data.GetU64(&offset); value = *((float *)&u64); return true; } } else if (byte_size == sizeof(double)) { if (sizeof(double) == sizeof(uint32_t)) { u32 = data.GetU32(&offset); value = *((double *)&u32); return true; } else if (sizeof(double) == sizeof(uint64_t)) { u64 = data.GetU64(&offset); value = *((double *)&u64); return true; } } else if (byte_size == sizeof(long double)) { if (sizeof(long double) == sizeof(uint32_t)) { u32 = data.GetU32(&offset); value = *((long double *)&u32); return true; } else if (sizeof(long double) == sizeof(uint64_t)) { u64 = data.GetU64(&offset); value = *((long double *)&u64); return true; } } } break; } } return false; }