DataBufferSP ObjectFile::ReadMemory(const ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size) { DataBufferSP data_sp; if (process_sp) { std::unique_ptr<DataBufferHeap> data_ap(new DataBufferHeap(byte_size, 0)); Error error; const size_t bytes_read = process_sp->ReadMemory( addr, data_ap->GetBytes(), data_ap->GetByteSize(), error); if (bytes_read == byte_size) data_sp.reset(data_ap.release()); } return data_sp; }
void CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp) { std::lock_guard<std::mutex> guard(m_mutex); if (m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed) return; // We can't read the index for some reason. if (m_indexes_computed == eLazyBoolNo) { return; } Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); if (log) m_objfile.GetModule()->LogMessage(log, "Reading compact unwind first-level indexes"); if (m_unwindinfo_data_computed == false) { if (m_section_sp->IsEncrypted()) { // Can't get section contents of a protected/encrypted section until we have a live // process and can read them out of memory. if (process_sp.get() == nullptr) return; m_section_contents_if_encrypted.reset (new DataBufferHeap (m_section_sp->GetByteSize(), 0)); Error error; if (process_sp->ReadMemory ( m_section_sp->GetLoadBaseAddress (&process_sp->GetTarget()), m_section_contents_if_encrypted->GetBytes(), m_section_sp->GetByteSize(), error) == m_section_sp->GetByteSize() && error.Success()) { m_unwindinfo_data.SetAddressByteSize (process_sp->GetTarget().GetArchitecture().GetAddressByteSize()); m_unwindinfo_data.SetByteOrder (process_sp->GetTarget().GetArchitecture().GetByteOrder()); m_unwindinfo_data.SetData (m_section_contents_if_encrypted, 0); } } else { m_objfile.ReadSectionData (m_section_sp.get(), m_unwindinfo_data); } if (m_unwindinfo_data.GetByteSize() != m_section_sp->GetByteSize()) return; m_unwindinfo_data_computed = true; } if (m_unwindinfo_data.GetByteSize() > 0) { offset_t offset = 0; // struct unwind_info_section_header // { // uint32_t version; // UNWIND_SECTION_VERSION // uint32_t commonEncodingsArraySectionOffset; // uint32_t commonEncodingsArrayCount; // uint32_t personalityArraySectionOffset; // uint32_t personalityArrayCount; // uint32_t indexSectionOffset; // uint32_t indexCount; m_unwind_header.version = m_unwindinfo_data.GetU32(&offset); m_unwind_header.common_encodings_array_offset = m_unwindinfo_data.GetU32(&offset); m_unwind_header.common_encodings_array_count = m_unwindinfo_data.GetU32(&offset); m_unwind_header.personality_array_offset = m_unwindinfo_data.GetU32(&offset); m_unwind_header.personality_array_count = m_unwindinfo_data.GetU32(&offset); uint32_t indexSectionOffset = m_unwindinfo_data.GetU32(&offset); uint32_t indexCount = m_unwindinfo_data.GetU32(&offset); if (m_unwind_header.common_encodings_array_offset > m_unwindinfo_data.GetByteSize() || m_unwind_header.personality_array_offset > m_unwindinfo_data.GetByteSize() || indexSectionOffset > m_unwindinfo_data.GetByteSize() || offset > m_unwindinfo_data.GetByteSize()) { Host::SystemLog (Host::eSystemLogError, "error: Invalid offset encountered in compact unwind info, skipping\n"); // don't trust anything from this compact_unwind section if it looks // blatantly invalid data in the header. m_indexes_computed = eLazyBoolNo; return; } // Parse the basic information from the indexes // We wait to scan the second level page info until it's needed // struct unwind_info_section_header_index_entry // { // uint32_t functionOffset; // uint32_t secondLevelPagesSectionOffset; // uint32_t lsdaIndexArraySectionOffset; // }; offset = indexSectionOffset; for (uint32_t idx = 0; idx < indexCount; idx++) { uint32_t function_offset = m_unwindinfo_data.GetU32(&offset); // functionOffset uint32_t second_level_offset = m_unwindinfo_data.GetU32(&offset); // secondLevelPagesSectionOffset uint32_t lsda_offset = m_unwindinfo_data.GetU32(&offset); // lsdaIndexArraySectionOffset if (second_level_offset > m_section_sp->GetByteSize() || lsda_offset > m_section_sp->GetByteSize()) { m_indexes_computed = eLazyBoolNo; } UnwindIndex this_index; this_index.function_offset = function_offset; // this_index.second_level = second_level_offset; this_index.lsda_array_start = lsda_offset; if (m_indexes.size() > 0) { m_indexes[m_indexes.size() - 1].lsda_array_end = lsda_offset; } if (second_level_offset == 0) { this_index.sentinal_entry = true; } m_indexes.push_back (this_index); } m_indexes_computed = eLazyBoolYes; } else { m_indexes_computed = eLazyBoolNo; } }