Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
    }
}