예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
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;
}
예제 #9
0
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;
}
예제 #11
0
    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();
    }
예제 #12
0
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;
}
예제 #13
0
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);
}
예제 #14
0
    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();
    }
예제 #15
0
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;
}