Пример #1
0
//----------------------------------------------------------------------
// Get the section data the file on disk
//----------------------------------------------------------------------
size_t
ObjectFile::ReadSectionData (const Section *section, DataExtractor& section_data) const
{
    if (IsInMemory())
    {
        ProcessSP process_sp (m_process_wp.lock());
        if (process_sp)
        {
            DataBufferSP data_sp (ReadMemory (process_sp, section->GetLoadBaseAddress (&process_sp->GetTarget()), section->GetByteSize()));
            if (data_sp)
            {
                section_data.SetData (data_sp, 0, data_sp->GetByteSize());
                section_data.SetByteOrder (process_sp->GetByteOrder());
                section_data.SetAddressByteSize (process_sp->GetAddressByteSize());
                return section_data.GetByteSize();
            }
        }
    }
    else
    {
        // The object file now contains a full mmap'ed copy of the object file data, so just use this
        return MemoryMapSectionData (section, section_data);
    }
    section_data.Clear();
    return 0;
}
Пример #2
0
uint32_t Opcode::GetData(DataExtractor &data) const {
  uint32_t byte_size = GetByteSize();
  uint8_t swap_buf[8];
  const void *buf = nullptr;

  if (byte_size > 0) {
    if (!GetEndianSwap()) {
      if (m_type == Opcode::eType16_2) {
        // 32 bit thumb instruction, we need to sizzle this a bit
        swap_buf[0] = m_data.inst.bytes[2];
        swap_buf[1] = m_data.inst.bytes[3];
        swap_buf[2] = m_data.inst.bytes[0];
        swap_buf[3] = m_data.inst.bytes[1];
        buf = swap_buf;
      } else {
        buf = GetOpcodeDataBytes();
      }
    } else {
      switch (m_type) {
      case Opcode::eTypeInvalid:
        break;
      case Opcode::eType8:
        buf = GetOpcodeDataBytes();
        break;
      case Opcode::eType16:
        *(uint16_t *)swap_buf = llvm::ByteSwap_16(m_data.inst16);
        buf = swap_buf;
        break;
      case Opcode::eType16_2:
        swap_buf[0] = m_data.inst.bytes[1];
        swap_buf[1] = m_data.inst.bytes[0];
        swap_buf[2] = m_data.inst.bytes[3];
        swap_buf[3] = m_data.inst.bytes[2];
        buf = swap_buf;
        break;
      case Opcode::eType32:
        *(uint32_t *)swap_buf = llvm::ByteSwap_32(m_data.inst32);
        buf = swap_buf;
        break;
      case Opcode::eType64:
        *(uint32_t *)swap_buf = llvm::ByteSwap_64(m_data.inst64);
        buf = swap_buf;
        break;
      case Opcode::eTypeBytes:
        buf = GetOpcodeDataBytes();
        break;
      }
    }
  }
  if (buf != nullptr) {
    DataBufferSP buffer_sp;

    buffer_sp.reset(new DataBufferHeap(buf, byte_size));
    data.SetByteOrder(GetDataByteOrder());
    data.SetData(buffer_sp);
    return byte_size;
  }
  data.Clear();
  return 0;
}
Пример #3
0
bool
Value::GetData (DataExtractor &data)
{
    switch (m_value_type)
    {
    default:
        break;

    case eValueTypeScalar:
        if (m_value.GetData (data))
            return true;
        break;

    case eValueTypeLoadAddress:
    case eValueTypeFileAddress:
    case eValueTypeHostAddress:
        if (m_data_buffer.GetByteSize())
        {
            data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(), data.GetByteOrder());
            return true;
        }
        break;
    }

    return false;

}
Пример #4
0
size_t
ObjectFile::GetData (off_t offset, size_t length, DataExtractor &data) const
{
    // The entire file has already been mmap'ed into m_data, so just copy from there
    // as the back mmap buffer will be shared with shared pointers.
    return data.SetData (m_data, offset, length);
}
Пример #5
0
//----------------------------------------------------------------------
// Get the section data the file on disk
//----------------------------------------------------------------------
size_t
ObjectFile::ReadSectionData (const Section *section, DataExtractor& section_data) const
{
    // If some other objectfile owns this data, pass this to them.
    if (section->GetObjectFile() != this)
        return section->GetObjectFile()->ReadSectionData (section, section_data);

    if (IsInMemory())
    {
        ProcessSP process_sp (m_process_wp.lock());
        if (process_sp)
        {
            const addr_t base_load_addr = section->GetLoadBaseAddress (&process_sp->GetTarget());
            if (base_load_addr != LLDB_INVALID_ADDRESS)
            {
                DataBufferSP data_sp (ReadMemory (process_sp, base_load_addr, section->GetByteSize()));
                if (data_sp)
                {
                    section_data.SetData (data_sp, 0, data_sp->GetByteSize());
                    section_data.SetByteOrder (process_sp->GetByteOrder());
                    section_data.SetAddressByteSize (process_sp->GetAddressByteSize());
                    return section_data.GetByteSize();
                }
            }
        }
    }
    else
    {
        // The object file now contains a full mmap'ed copy of the object file data, so just use this
        return MemoryMapSectionData (section, section_data);
    }
    section_data.Clear();
    return 0;
}
Пример #6
0
bool Type::ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr,
                          AddressType address_type, DataExtractor &data) {
  if (address_type == eAddressTypeFile) {
    // Can't convert a file address to anything valid without more
    // context (which Module it came from)
    return false;
  }

  const uint64_t byte_size = GetByteSize();
  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) {
      // The address is an address in this process, so just copy it
      if (addr == 0)
        return false;
      memcpy(dst, (uint8_t *)nullptr + addr, byte_size);
      return true;
    } else {
      if (exe_ctx) {
        Process *process = exe_ctx->GetProcessPtr();
        if (process) {
          Error error;
          return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size,
                                                      error) == byte_size;
        }
      }
    }
  }
  return false;
}
Пример #7
0
void EventDataBytes::Dump(Stream *s) const {
    size_t num_printable_chars =
        std::count_if(m_bytes.begin(), m_bytes.end(), isprint);
    if (num_printable_chars == m_bytes.size()) {
        s->Printf("\"%s\"", m_bytes.c_str());
    } else if (!m_bytes.empty()) {
        DataExtractor data;
        data.SetData(m_bytes.data(), m_bytes.size(), endian::InlHostByteOrder());
        data.Dump(s, 0, eFormatBytes, 1, m_bytes.size(), 32, LLDB_INVALID_ADDRESS,
                  0, 0);
    }
}
Пример #8
0
//----------------------------------------------------------------------
// Get the section data from a complete contiguous copy of the
// entire executable image.
//----------------------------------------------------------------------
size_t
Section::GetSectionDataFromImage (const DataExtractor& image_data, DataExtractor& section_data) const
{
    size_t file_size = GetByteSize();
    if (file_size > 0)
    {
        off_t file_offset = GetFileOffset();
        if (section_data.SetData (image_data, file_offset, file_size) == file_size)
            return true;
    }
    return false;
}
Пример #9
0
uint32_t
Opcode::GetData (DataExtractor &data, lldb::AddressClass address_class) const
{
    uint32_t byte_size = GetByteSize ();
    
    DataBufferSP buffer_sp;
    if (byte_size > 0)
    {
        switch (m_type)
        {
            case Opcode::eTypeInvalid:
                break;
                
            case Opcode::eType8:    buffer_sp.reset (new DataBufferHeap (&m_data.inst8,  byte_size)); break;
            case Opcode::eType16:   buffer_sp.reset (new DataBufferHeap (&m_data.inst16, byte_size)); break;
            case Opcode::eType32:
                {
                    // The only thing that uses eAddressClassCodeAlternateISA currently
                    // is Thumb. If this ever changes, we will need to pass in more
                    // information like an additional "const ArchSpec &arch". For now
                    // this will do
                    if (address_class == eAddressClassCodeAlternateISA)
                    {
                        // 32 bit thumb instruction, we need to sizzle this a bit
                        uint8_t buf[4];
                        buf[0] = m_data.inst.bytes[2];
                        buf[1] = m_data.inst.bytes[3];
                        buf[2] = m_data.inst.bytes[0];
                        buf[3] = m_data.inst.bytes[1];
                        buffer_sp.reset (new DataBufferHeap (buf, byte_size));
                        break;
                    }
                    buffer_sp.reset (new DataBufferHeap (&m_data.inst32, byte_size));
                }
                break;

            case Opcode::eType64:   buffer_sp.reset (new DataBufferHeap (&m_data.inst64, byte_size)); break;
            case Opcode::eTypeBytes:buffer_sp.reset (new DataBufferHeap (GetOpcodeBytes(), byte_size)); break;
                break;
        }
    }
    
    if (buffer_sp)
    {
        data.SetByteOrder(GetDataByteOrder());
        data.SetData (buffer_sp);
        return byte_size;
    }
    data.Clear();
    return 0;
}
Пример #10
0
size_t
ObjectFilePECOFF::GetModuleSpecifications (const lldb_private::FileSpec& file,
                                           lldb::DataBufferSP& data_sp,
                                           lldb::offset_t data_offset,
                                           lldb::offset_t file_offset,
                                           lldb::offset_t length,
                                           lldb_private::ModuleSpecList &specs)
{
    const size_t initial_count = specs.GetSize();

    if (ObjectFilePECOFF::MagicBytesMatch(data_sp))
    {
        DataExtractor data;
        data.SetData(data_sp, data_offset, length);
        data.SetByteOrder(eByteOrderLittle);

        dos_header_t dos_header;
        coff_header_t coff_header;

        if (ParseDOSHeader(data, dos_header))
        {
            lldb::offset_t offset = dos_header.e_lfanew;
            uint32_t pe_signature = data.GetU32(&offset);
            if (pe_signature != IMAGE_NT_SIGNATURE)
                return false;
            if (ParseCOFFHeader(data, &offset, coff_header))
            {
                ArchSpec spec;
                if (coff_header.machine == MachineAmd64)
                {
                    spec.SetTriple("x86_64-pc-windows");
                    specs.Append(ModuleSpec(file, spec));
                }
                else if (coff_header.machine == MachineX86)
                {
                    spec.SetTriple("i386-pc-windows");
                    specs.Append(ModuleSpec(file, spec));
                    spec.SetTriple("i686-pc-windows");
                    specs.Append(ModuleSpec(file, spec));
                }
            }
        }
    }

    return specs.GetSize() - initial_count;
}
bool
RegisterContextMacOSXFrameBackchain::ReadRegisterBytes (uint32_t reg, DataExtractor &data)
{
    Scalar reg_value;

    if (ReadRegisterValue (reg, reg_value))
    {
        if (reg_value.GetData(data))
        {
            // "reg_value" is local and now "data" points to the data within
            // "reg_value", so we must make a copy that will live within "data"
            DataBufferSP data_sp (new DataBufferHeap (data.GetDataStart(), data.GetByteSize()));
            data.SetData (data_sp, 0, data.GetByteSize());
            return true;
        }
    }
    return false;
}
ObjectContainer *ObjectContainerUniversalMachO::CreateInstance(
    const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
    lldb::offset_t data_offset, const FileSpec *file,
    lldb::offset_t file_offset, lldb::offset_t length) {
  // We get data when we aren't trying to look for cached container information,
  // so only try and look for an architecture slice if we get data
  if (data_sp) {
    DataExtractor data;
    data.SetData(data_sp, data_offset, length);
    if (ObjectContainerUniversalMachO::MagicBytesMatch(data)) {
      std::unique_ptr<ObjectContainerUniversalMachO> container_ap(
          new ObjectContainerUniversalMachO(module_sp, data_sp, data_offset,
                                            file, file_offset, length));
      if (container_ap->ParseHeader()) {
        return container_ap.release();
      }
    }
  }
  return NULL;
}
Пример #13
0
size_t
Disassembler::ParseInstructions
(
    const ExecutionContext *exe_ctx,
    const AddressRange &range,
    DataExtractor& data
)
{
    Target *target = exe_ctx->target;

    const addr_t byte_size = range.GetByteSize();
    if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
        return 0;

    DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
    DataBufferSP data_sp(heap_buffer);

    Error error;
    const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), heap_buffer->GetBytes(), heap_buffer->GetByteSize(), error);
    
    if (bytes_read > 0)
    {
        if (bytes_read != heap_buffer->GetByteSize())
            heap_buffer->SetByteSize (bytes_read);

        data.SetData(data_sp);
        if (exe_ctx->process)
        {
            data.SetByteOrder(exe_ctx->process->GetByteOrder());
            data.SetAddressByteSize(exe_ctx->process->GetAddressByteSize());
        }
        else
        {
            data.SetByteOrder(target->GetArchitecture().GetDefaultEndian());
            data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
        }
        return DecodeInstructions (data, 0, UINT32_MAX);
    }

    return 0;
}
Пример #14
0
size_t
Section::MemoryMapSectionDataFromObjectFile(const ObjectFile* objfile, DataExtractor& section_data) const
{
    if (objfile == NULL)
        return 0;

    const FileSpec& file = objfile->GetFileSpec();

    if (file)
    {
        size_t section_file_size = GetFileSize();
        if (section_file_size > 0)
        {
            off_t section_file_offset = GetFileOffset() + objfile->GetOffset();
            DataBufferSP section_data_sp(file.MemoryMapFileContents(section_file_offset, section_file_size));
            section_data.SetByteOrder(objfile->GetByteOrder());
            section_data.SetAddressByteSize(objfile->GetAddressByteSize());
            return section_data.SetData (section_data_sp);
        }
    }
    return 0;
}
Пример #15
0
static bool
FileAtPathContainsArchAndUUID
(
    const FileSpec &file_spec,
    const ArchSpec *arch,
    const lldb_private::UUID *uuid
)
{
    DataExtractor data;
    off_t file_offset = 0;
    DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, 0x1000));

    if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)
    {
        data.SetData(data_buffer_sp);

        uint32_t data_offset = 0;
        uint32_t magic = data.GetU32(&data_offset);

        switch (magic)
        {
        // 32 bit mach-o file
        case HeaderMagic32:
        case HeaderMagic32Swapped:
        case HeaderMagic64:
        case HeaderMagic64Swapped:
            return SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic);

        // fat mach-o file
        case UniversalMagic:
        case UniversalMagicSwapped:
            return UniversalMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset, data, data_offset, magic);

        default:
            break;
        }
    }
    return false;
}
Пример #16
0
DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) {
  if (m_file) {
    // A bit of a hack, but we intend to write to this buffer, so we can't 
    // mmap it.
    auto buffer_sp =
        DataBufferLLVM::CreateSliceFromPath(m_file.GetPath(), size, offset, true);
    return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize());
  }
  ProcessSP process_sp(m_process_wp.lock());
  DataExtractor data;
  if (process_sp) {
    auto data_ap = llvm::make_unique<DataBufferHeap>(size, 0);
    Status readmem_error;
    size_t bytes_read =
        process_sp->ReadMemory(m_image_base + offset, data_ap->GetBytes(),
                               data_ap->GetByteSize(), readmem_error);
    if (bytes_read == size) {
      DataBufferSP buffer_sp(data_ap.release());
      data.SetData(buffer_sp, 0, buffer_sp->GetByteSize());
    }
  }
  return data;
}
Пример #17
0
ObjectContainer *
ObjectContainerBSDArchive::CreateInstance
(
    const lldb::ModuleSP &module_sp,
    DataBufferSP& data_sp,
    const FileSpec *file,
    addr_t offset,
    addr_t length)
{
    DataExtractor data;
    data.SetData (data_sp, offset, length);
    if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data))
    {
        Timer scoped_timer (__PRETTY_FUNCTION__,
                            "ObjectContainerBSDArchive::CreateInstance (module = %s/%s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
                            module_sp->GetFileSpec().GetDirectory().AsCString(),
                            module_sp->GetFileSpec().GetFilename().AsCString(),
                            file, (uint64_t) offset, (uint64_t) length);

        Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));

        std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, data_sp, file, offset, length));

        if (container_ap.get())
        {
            if (archive_sp)
            {
                // We already have this archive in our cache, use it
                container_ap->SetArchive (archive_sp);
                return container_ap.release();
            }
            else if (container_ap->ParseHeader())
                return container_ap.release();
        }
    }
    return NULL;
}
size_t ObjectContainerUniversalMachO::GetModuleSpecifications(
    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
    lldb::offset_t data_offset, lldb::offset_t file_offset,
    lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
  const size_t initial_count = specs.GetSize();

  DataExtractor data;
  data.SetData(data_sp, data_offset, data_sp->GetByteSize());

  if (ObjectContainerUniversalMachO::MagicBytesMatch(data)) {
    llvm::MachO::fat_header header;
    std::vector<llvm::MachO::fat_arch> fat_archs;
    if (ParseHeader(data, header, fat_archs)) {
      for (const llvm::MachO::fat_arch &fat_arch : fat_archs) {
        const lldb::offset_t slice_file_offset = fat_arch.offset + file_offset;
        if (fat_arch.offset < file_size && file_size > slice_file_offset) {
          ObjectFile::GetModuleSpecifications(
              file, slice_file_offset, file_size - slice_file_offset, specs);
        }
      }
    }
  }
  return specs.GetSize() - initial_count;
}
Пример #19
0
static bool
SkinnyMachOFileContainsArchAndUUID
(
    const FileSpec &file_spec,
    const ArchSpec *arch,
    const lldb_private::UUID *uuid,   // the UUID we are looking for
    off_t file_offset,
    DataExtractor& data,
    uint32_t data_offset,
    const uint32_t magic
)
{
    assert(magic == HeaderMagic32 || magic == HeaderMagic32Swapped || magic == HeaderMagic64 || magic == HeaderMagic64Swapped);
    if (magic == HeaderMagic32 || magic == HeaderMagic64)
        data.SetByteOrder (lldb::endian::InlHostByteOrder());
    else if (lldb::endian::InlHostByteOrder() == eByteOrderBig)
        data.SetByteOrder (eByteOrderLittle);
    else
        data.SetByteOrder (eByteOrderBig);

    uint32_t i;
    const uint32_t cputype      = data.GetU32(&data_offset);    // cpu specifier
    const uint32_t cpusubtype   = data.GetU32(&data_offset);    // machine specifier
    data_offset+=4; // Skip mach file type
    const uint32_t ncmds        = data.GetU32(&data_offset);    // number of load commands
    const uint32_t sizeofcmds   = data.GetU32(&data_offset);    // the size of all the load commands
    data_offset+=4; // Skip flags

    // Check the architecture if we have a valid arch pointer
    if (arch)
    {
        ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype);

        if (file_arch != *arch)
            return false;
    }

    // The file exists, and if a valid arch pointer was passed in we know
    // if already matches, so we can return if we aren't looking for a specific
    // UUID
    if (uuid == NULL)
        return true;

    if (magic == HeaderMagic64Swapped || magic == HeaderMagic64)
        data_offset += 4;   // Skip reserved field for in mach_header_64

    // Make sure we have enough data for all the load commands
    if (magic == HeaderMagic64Swapped || magic == HeaderMagic64)
    {
        if (data.GetByteSize() < sizeof(struct mach_header_64) + sizeofcmds)
        {
            DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header_64) + sizeofcmds));
            data.SetData (data_buffer_sp);
        }
    }
    else
    {
        if (data.GetByteSize() < sizeof(struct mach_header) + sizeofcmds)
        {
            DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header) + sizeofcmds));
            data.SetData (data_buffer_sp);
        }
    }

    for (i=0; i<ncmds; i++)
    {
        const uint32_t cmd_offset = data_offset;    // Save this data_offset in case parsing of the segment goes awry!
        uint32_t cmd        = data.GetU32(&data_offset);
        uint32_t cmd_size   = data.GetU32(&data_offset);
        if (cmd == LoadCommandUUID)
        {
            lldb_private::UUID file_uuid (data.GetData(&data_offset, 16), 16);
            if (file_uuid == *uuid)
                return true;

            // Emit some warning messages since the UUIDs do not match!
            char path_buf[PATH_MAX];
            path_buf[0] = '\0';
            const char *path = file_spec.GetPath(path_buf, PATH_MAX) ? path_buf
                                                                     : file_spec.GetFilename().AsCString();
            Host::SystemLog (Host::eSystemLogWarning, 
                             "warning: UUID mismatch detected between binary and:\n\t'%s'\n", 
                             path);
            return false;
        }
        data_offset = cmd_offset + cmd_size;
    }
    return false;
}
Пример #20
0
bool
UniversalMachOFileContainsArchAndUUID
(
    const FileSpec &file_spec,
    const ArchSpec *arch,
    const lldb_private::UUID *uuid,
    off_t file_offset,
    DataExtractor& data,
    uint32_t data_offset,
    const uint32_t magic
)
{
    assert(magic == UniversalMagic || magic == UniversalMagicSwapped);

    // Universal mach-o files always have their headers encoded as BIG endian
    data.SetByteOrder(eByteOrderBig);

    uint32_t i;
    const uint32_t nfat_arch = data.GetU32(&data_offset);   // number of structs that follow
    const uint32_t fat_header_and_arch_size = sizeof(struct fat_header) + nfat_arch * sizeof(struct fat_arch);
    if (data.GetByteSize() < fat_header_and_arch_size)
    {
        DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, fat_header_and_arch_size));
        data.SetData (data_buffer_sp);
    }

    for (i=0; i<nfat_arch; i++)
    {
        cpu_type_t      arch_cputype        = data.GetU32(&data_offset);    // cpu specifier (int)
        cpu_subtype_t   arch_cpusubtype     = data.GetU32(&data_offset);    // machine specifier (int)
        uint32_t        arch_offset         = data.GetU32(&data_offset);    // file offset to this object file
    //  uint32_t        arch_size           = data.GetU32(&data_offset);    // size of this object file
    //  uint32_t        arch_align          = data.GetU32(&data_offset);    // alignment as a power of 2
        data_offset += 8;   // Skip size and align as we don't need those
        // Only process this slice if the cpu type/subtype matches
        if (arch)
        {
            ArchSpec fat_arch(eArchTypeMachO, arch_cputype, arch_cpusubtype);
            if (fat_arch != *arch)
                continue;
        }

        // Create a buffer with only the arch slice date in it
        DataExtractor arch_data;
        DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset + arch_offset, 0x1000));
        arch_data.SetData(data_buffer_sp);
        uint32_t arch_data_offset = 0;
        uint32_t arch_magic = arch_data.GetU32(&arch_data_offset);

        switch (arch_magic)
        {
        case HeaderMagic32:
        case HeaderMagic32Swapped:
        case HeaderMagic64:
        case HeaderMagic64Swapped:
            if (SkinnyMachOFileContainsArchAndUUID (file_spec, arch, uuid, file_offset + arch_offset, arch_data, arch_data_offset, arch_magic))
                return true;
            break;
        }
    }
    return false;
}
ObjectContainer *
ObjectContainerBSDArchive::CreateInstance
(
    const lldb::ModuleSP &module_sp,
    DataBufferSP& data_sp,
    lldb::offset_t data_offset,
    const FileSpec *file,
    lldb::offset_t file_offset,
    lldb::offset_t length)
{
    ConstString object_name (module_sp->GetObjectName());
    if (object_name)
    {
        if (data_sp)
        {
            // We have data, which means this is the first 512 bytes of the file
            // Check to see if the magic bytes match and if they do, read the entire
            // table of contents for the archive and cache it
            DataExtractor data;
            data.SetData (data_sp, data_offset, length);
            if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data))
            {
                Timer scoped_timer (__PRETTY_FUNCTION__,
                                    "ObjectContainerBSDArchive::CreateInstance (module = %s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
                                    module_sp->GetFileSpec().GetPath().c_str(),
                                    file, (uint64_t) file_offset, (uint64_t) length);

                // Map the entire .a file to be sure that we don't lose any data if the file
                // gets updated by a new build while this .a file is being used for debugging
                DataBufferSP archive_data_sp (file->MemoryMapFileContents(file_offset, length));
                lldb::offset_t archive_data_offset = 0;

                Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file,
                                                                            module_sp->GetArchitecture(),
                                                                            module_sp->GetModificationTime(),
                                                                            file_offset));
                std::unique_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp,
                                                                                                       archive_data_sp,
                                                                                                       archive_data_offset,
                                                                                                       file,
                                                                                                       file_offset,
                                                                                                       length));

                if (container_ap.get())
                {
                    if (archive_sp)
                    {
                        // We already have this archive in our cache, use it
                        container_ap->SetArchive (archive_sp);
                        return container_ap.release();
                    }
                    else if (container_ap->ParseHeader())
                        return container_ap.release();
                }
            }
        }
        else
        {
            // No data, just check for a cached archive
            Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file,
                                                                        module_sp->GetArchitecture(),
                                                                        module_sp->GetModificationTime(),
                                                                        file_offset));
            if (archive_sp)
            {
                std::unique_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, data_sp, data_offset, file, file_offset, length));
                
                if (container_ap.get())
                {
                    // We already have this archive in our cache, use it
                    container_ap->SetArchive (archive_sp);
                    return container_ap.release();
                }
            }
        }
    }
    return NULL;
}
Пример #22
0
bool
RegisterContextMach_i386::ReadRegisterBytes (uint32_t reg, DataExtractor &data)
{
    int set = RegisterContextMach_i386::GetSetForNativeRegNum (reg);
    if (set == -1)
        return false;

    if (ReadRegisterSet(set, false) != KERN_SUCCESS)
        return false;

    const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg);
    if (reg_info == NULL)
        return false;

    switch (reg)
    {
    case gpr_eax:
    case gpr_ebx:
    case gpr_ecx:
    case gpr_edx:
    case gpr_edi:
    case gpr_esi:
    case gpr_ebp:
    case gpr_esp:
    case gpr_ss:
    case gpr_eflags:
    case gpr_eip:
    case gpr_cs:
    case gpr_ds:
    case gpr_es:
    case gpr_fs:
    case gpr_gs:
        data.SetData(&gpr.eax + reg - gpr_eax, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_fcw:
        data.SetData(&fpu.fcw, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_fsw:
        data.SetData(&fpu.fsw, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_ftw:
        data.SetData(&fpu.ftw, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_fop:
        data.SetData(&fpu.fop, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_ip:
        data.SetData(&fpu.ip, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_cs:
        data.SetData(&fpu.cs, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_dp:
        data.SetData(&fpu.dp, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_ds:
        data.SetData(&fpu.ds, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_mxcsr:
        data.SetData(&fpu.mxcsr, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_mxcsrmask:
        data.SetData(&fpu.mxcsrmask, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_stmm0:
    case fpu_stmm1:
    case fpu_stmm2:
    case fpu_stmm3:
    case fpu_stmm4:
    case fpu_stmm5:
    case fpu_stmm6:
    case fpu_stmm7:
        data.SetData(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case fpu_xmm0:
    case fpu_xmm1:
    case fpu_xmm2:
    case fpu_xmm3:
    case fpu_xmm4:
    case fpu_xmm5:
    case fpu_xmm6:
    case fpu_xmm7:
        data.SetData(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case exc_trapno:
        data.SetData(&exc.trapno, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case exc_err:
        data.SetData(&exc.err, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    case exc_faultvaddr:
        data.SetData(&exc.faultvaddr, reg_info->byte_size, lldb::endian::InlHostByteOrder());
        break;

    default:
        return false;
    }
    return true;
}
Пример #23
0
bool
RegisterValue::GetData (DataExtractor &data) const
{
    return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
}
Пример #24
0
void
AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded()
{
    // TODO: implement HashTableSignature...
    Process *process = GetProcess();
    
    if (process)
    {
        // Update the process stop ID that indicates the last time we updated the
        // map, whether it was successful or not.
        m_isa_to_descriptor_stop_id = process->GetStopID();
        
        Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
        
        ProcessSP process_sp = process->shared_from_this();
        
        ModuleSP objc_module_sp(GetObjCModule());
        
        if (!objc_module_sp)
            return;
        
        uint32_t isa_count = 0;
        
        lldb::addr_t hash_table_ptr = GetISAHashTablePointer ();
        if (hash_table_ptr != LLDB_INVALID_ADDRESS)
        {
            // Read the NXHashTable struct:
            //
            // typedef struct {
            //     const NXHashTablePrototype *prototype;
            //     unsigned   count;
            //     unsigned   nbBuckets;
            //     void       *buckets;
            //     const void *info;
            // } NXHashTable;

            Error error;
            DataBufferHeap buffer(1024, 0);
            if (process->ReadMemory(hash_table_ptr, buffer.GetBytes(), 20, error) == 20)
            {
                const uint32_t addr_size = m_process->GetAddressByteSize();
                const ByteOrder byte_order = m_process->GetByteOrder();
                DataExtractor data (buffer.GetBytes(), buffer.GetByteSize(), byte_order, addr_size);
                lldb::offset_t offset = addr_size; // Skip prototype
                const uint32_t count = data.GetU32(&offset);
                const uint32_t num_buckets = data.GetU32(&offset);
                const addr_t buckets_ptr = data.GetPointer(&offset);
                if (m_hash_signature.NeedsUpdate (count, num_buckets, buckets_ptr))
                {
                    m_hash_signature.UpdateSignature (count, num_buckets, buckets_ptr);

                    const uint32_t data_size = num_buckets * 2 * sizeof(uint32_t);
                    buffer.SetByteSize(data_size);
                    
                    if (process->ReadMemory(buckets_ptr, buffer.GetBytes(), data_size, error) == data_size)
                    {
                        data.SetData(buffer.GetBytes(), buffer.GetByteSize(), byte_order);
                        offset = 0;
                        for (uint32_t bucket_idx = 0; bucket_idx < num_buckets; ++bucket_idx)
                        {
                            const uint32_t bucket_isa_count = data.GetU32 (&offset);
                            const lldb::addr_t bucket_data = data.GetU32 (&offset);
                            

                            if (bucket_isa_count == 0)
                                continue;
                            
                            isa_count += bucket_isa_count;

                            ObjCISA isa;
                            if (bucket_isa_count == 1)
                            {
                                // When we only have one entry in the bucket, the bucket data is the "isa"
                                isa = bucket_data;
                                if (isa)
                                {
                                    if (!ISAIsCached(isa))
                                    {
                                        ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp));
                                        
                                        if (log && log->GetVerbose())
                                            log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa);
                                        
                                        AddClass (isa, descriptor_sp);
                                    }
                                }
                            }
                            else
                            {
                                // When we have more than one entry in the bucket, the bucket data is a pointer
                                // to an array of "isa" values
                                addr_t isa_addr = bucket_data;
                                for (uint32_t isa_idx = 0; isa_idx < bucket_isa_count; ++isa_idx, isa_addr += addr_size)
                                {
                                    isa = m_process->ReadPointerFromMemory(isa_addr, error);

                                    if (isa && isa != LLDB_INVALID_ADDRESS)
                                    {
                                        if (!ISAIsCached(isa))
                                        {
                                            ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp));
                                            
                                            if (log && log->GetVerbose())
                                                log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa);
                                            
                                            AddClass (isa, descriptor_sp);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }        
    }
    else
    {
        m_isa_to_descriptor_stop_id = UINT32_MAX;
    }
}
static bool
SkinnyMachOFileContainsArchAndUUID
(
    const FileSpec &file_spec,
    const ArchSpec *arch,
    const lldb_private::UUID *uuid,   // the UUID we are looking for
    off_t file_offset,
    DataExtractor& data,
    lldb::offset_t data_offset,
    const uint32_t magic
)
{
    assert(magic == HeaderMagic32 || magic == HeaderMagic32Swapped || magic == HeaderMagic64 || magic == HeaderMagic64Swapped);
    if (magic == HeaderMagic32 || magic == HeaderMagic64)
        data.SetByteOrder (lldb::endian::InlHostByteOrder());
    else if (lldb::endian::InlHostByteOrder() == eByteOrderBig)
        data.SetByteOrder (eByteOrderLittle);
    else
        data.SetByteOrder (eByteOrderBig);

    uint32_t i;
    const uint32_t cputype      = data.GetU32(&data_offset);    // cpu specifier
    const uint32_t cpusubtype   = data.GetU32(&data_offset);    // machine specifier
    data_offset+=4; // Skip mach file type
    const uint32_t ncmds        = data.GetU32(&data_offset);    // number of load commands
    const uint32_t sizeofcmds   = data.GetU32(&data_offset);    // the size of all the load commands
    data_offset+=4; // Skip flags

    // Check the architecture if we have a valid arch pointer
    if (arch)
    {
        ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype);

        if (!file_arch.IsCompatibleMatch(*arch))
            return false;
    }

    // The file exists, and if a valid arch pointer was passed in we know
    // if already matches, so we can return if we aren't looking for a specific
    // UUID
    if (uuid == NULL)
        return true;

    if (magic == HeaderMagic64Swapped || magic == HeaderMagic64)
        data_offset += 4;   // Skip reserved field for in mach_header_64

    // Make sure we have enough data for all the load commands
    if (magic == HeaderMagic64Swapped || magic == HeaderMagic64)
    {
        if (data.GetByteSize() < sizeof(struct mach_header_64) + sizeofcmds)
        {
            DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header_64) + sizeofcmds));
            data.SetData (data_buffer_sp);
        }
    }
    else
    {
        if (data.GetByteSize() < sizeof(struct mach_header) + sizeofcmds)
        {
            DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset, sizeof(struct mach_header) + sizeofcmds));
            data.SetData (data_buffer_sp);
        }
    }

    for (i=0; i<ncmds; i++)
    {
        const lldb::offset_t cmd_offset = data_offset;    // Save this data_offset in case parsing of the segment goes awry!
        uint32_t cmd        = data.GetU32(&data_offset);
        uint32_t cmd_size   = data.GetU32(&data_offset);
        if (cmd == LoadCommandUUID)
        {
            lldb_private::UUID file_uuid (data.GetData(&data_offset, 16), 16);
            if (file_uuid == *uuid)
                return true;
            return false;
        }
        data_offset = cmd_offset + cmd_size;
    }
    return false;
}
Пример #26
0
Error
Value::GetValueAsData (ExecutionContext *exe_ctx, 
                       clang::ASTContext *ast_context, 
                       DataExtractor &data, 
                       uint32_t data_offset,
                       Module *module)
{
    data.Clear();

    Error error;
    lldb::addr_t address = LLDB_INVALID_ADDRESS;
    AddressType address_type = eAddressTypeFile;
    Address file_so_addr;
    switch (m_value_type)
    {
    default:
        error.SetErrorStringWithFormat("invalid value type %i", m_value_type);
        break;

    case eValueTypeScalar:
        data.SetByteOrder (lldb::endian::InlHostByteOrder());
        if (m_context_type == eContextTypeClangType && ast_context)
        {
            uint32_t ptr_bit_width = ClangASTType::GetClangTypeBitWidth (ast_context, 
                                                                     ClangASTContext::GetVoidPtrType(ast_context, false));
            uint32_t ptr_byte_size = (ptr_bit_width + 7) / 8;
            data.SetAddressByteSize (ptr_byte_size);
        }
        else
            data.SetAddressByteSize(sizeof(void *));
        if (m_value.GetData (data))
            return error;   // Success;
        error.SetErrorStringWithFormat("extracting data from value failed");
        break;

    case eValueTypeLoadAddress:
        if (exe_ctx == NULL)
        {
            error.SetErrorString ("can't read load address (no execution context)");
        }
        else 
        {
            Process *process = exe_ctx->GetProcessPtr();
            if (process == NULL)
            {
                error.SetErrorString ("can't read load address (invalid process)");
            }
            else
            {
                address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
                address_type = eAddressTypeLoad;
                data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder());
                data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize());
            }
        }
        break;

    case eValueTypeFileAddress:
        if (exe_ctx == NULL)
        {
            error.SetErrorString ("can't read file address (no execution context)");
        }
        else if (exe_ctx->GetTargetPtr() == NULL)
        {
            error.SetErrorString ("can't read file address (invalid target)");
        }
        else
        {
            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
            if (address == LLDB_INVALID_ADDRESS)
            {
                error.SetErrorString ("invalid file address");
            }
            else
            {
                if (module == NULL)
                {
                    // The only thing we can currently lock down to a module so that
                    // we can resolve a file address, is a variable.
                    Variable *variable = GetVariable();
                    if (variable)
                    {
                        SymbolContext var_sc;
                        variable->CalculateSymbolContext(&var_sc);
                        module = var_sc.module_sp.get();
                    }
                }
                
                if (module)
                {
                    bool resolved = false;
                    ObjectFile *objfile = module->GetObjectFile();
                    if (objfile)
                    {
                        Address so_addr(address, objfile->GetSectionList());
                        addr_t load_address = so_addr.GetLoadAddress (exe_ctx->GetTargetPtr());
                        bool process_launched_and_stopped = exe_ctx->GetProcessPtr()
                            ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(), true /* must_exist */)
                            : false;
                        // Don't use the load address if the process has exited.
                        if (load_address != LLDB_INVALID_ADDRESS && process_launched_and_stopped)
                        {
                            resolved = true;
                            address = load_address;
                            address_type = eAddressTypeLoad;
                            data.SetByteOrder(exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
                            data.SetAddressByteSize(exe_ctx->GetTargetRef().GetArchitecture().GetAddressByteSize());
                        }
                        else
                        {
                            if (so_addr.IsSectionOffset())
                            {
                                resolved = true;
                                file_so_addr = so_addr;
                                data.SetByteOrder(objfile->GetByteOrder());
                                data.SetAddressByteSize(objfile->GetAddressByteSize());
                            }
                        }
                    }
                    if (!resolved)
                    {
                        Variable *variable = GetVariable();
                        
                        if (module)
                        {
                            if (variable)
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s' in %s%s%s", 
                                                                address, 
                                                                variable->GetName().AsCString(""),
                                                                module->GetFileSpec().GetDirectory().GetCString(),
                                                                module->GetFileSpec().GetDirectory() ? "/" : "",
                                                                module->GetFileSpec().GetFilename().GetCString());
                            else
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx in %s%s%s", 
                                                                address, 
                                                                module->GetFileSpec().GetDirectory().GetCString(),
                                                                module->GetFileSpec().GetDirectory() ? "/" : "",
                                                                module->GetFileSpec().GetFilename().GetCString());
                        }
                        else
                        {
                            if (variable)
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'", 
                                                                address, 
                                                                variable->GetName().AsCString(""));
                            else
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx", address);
                        }
                    }
                }
                else
                {
                    // Can't convert a file address to anything valid without more
                    // context (which Module it came from)
                    error.SetErrorString ("can't read memory from file address without more context");
                }
            }
        }
        break;

    case eValueTypeHostAddress:
        address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
        address_type = eAddressTypeHost;
        if (exe_ctx)
        {
            Target *target = exe_ctx->GetTargetPtr();
            if (target)
            {
                data.SetByteOrder(target->GetArchitecture().GetByteOrder());
                data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
                break;
            }
        }
        // fallback to host settings
        data.SetByteOrder(lldb::endian::InlHostByteOrder());
        data.SetAddressByteSize(sizeof(void *));
        break;
    }

    // Bail if we encountered any errors
    if (error.Fail())
        return error;

    if (address == LLDB_INVALID_ADDRESS)
    {
        error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load");
        return error;
    }

    // If we got here, we need to read the value from memory
    uint32_t byte_size = GetValueByteSize (ast_context, &error);

    // Bail if we encountered any errors getting the byte size
    if (error.Fail())
        return error;

    // Make sure we have enough room within "data", and if we don't make
    // something large enough that does
    if (!data.ValidOffsetForDataOfSize (data_offset, byte_size))
    {
        DataBufferSP data_sp(new DataBufferHeap (data_offset + byte_size, '\0'));
        data.SetData(data_sp);
    }

    uint8_t* dst = const_cast<uint8_t*>(data.PeekData (data_offset, byte_size));
    if (dst != NULL)
    {
        if (address_type == eAddressTypeHost)
        {
            // The address is an address in this process, so just copy it
            memcpy (dst, (uint8_t*)NULL + address, byte_size);
        }
        else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile))
        {
            if (file_so_addr.IsValid())
            {
                // We have a file address that we were able to translate into a
                // section offset address so we might be able to read this from
                // the object files if we don't have a live process. Lets always
                // try and read from the process if we have one though since we
                // want to read the actual value by setting "prefer_file_cache"
                // to false. 
                const bool prefer_file_cache = false;
                if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size)
                {
                    error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address);
                }
            }
            else
            {
                // The execution context might have a NULL process, but it
                // might have a valid process in the exe_ctx->target, so use
                // the ExecutionContext::GetProcess accessor to ensure we
                // get the process if there is one.
                Process *process = exe_ctx->GetProcessPtr();

                if (process)
                {
                    const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error);
                    if (bytes_read != byte_size)
                        error.SetErrorStringWithFormat("read memory from 0x%llx failed (%u of %u bytes read)", 
                                                       (uint64_t)address, 
                                                       (uint32_t)bytes_read, 
                                                       (uint32_t)byte_size);
                }
                else
                {
                    error.SetErrorStringWithFormat("read memory from 0x%llx failed (invalid process)", (uint64_t)address);                    
                }
            }
        }
        else
        {
            error.SetErrorStringWithFormat ("unsupported AddressType value (%i)", address_type);
        }
    }
    else
    {
        error.SetErrorStringWithFormat ("out of memory");
    }

    return error;
}
Пример #27
0
bool
TypeFormatImpl_Format::FormatObject (ValueObject *valobj,
                                     std::string& dest) const
{
    if (!valobj)
        return false;
    if (valobj->CanProvideValue())
    {
        Value& value(valobj->GetValue());
        const Value::ContextType context_type = value.GetContextType();
        ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
        DataExtractor data;
        
        if (context_type == Value::eContextTypeRegisterInfo)
        {
            const RegisterInfo *reg_info = value.GetRegisterInfo();
            if (reg_info)
            {
                Error error;
                valobj->GetData(data, error);
                if (error.Fail())
                    return false;
                
                StreamString reg_sstr;
                data.Dump (&reg_sstr,
                           0,
                           GetFormat(),
                           reg_info->byte_size,
                           1,
                           UINT32_MAX,
                           LLDB_INVALID_ADDRESS,
                           0,
                           0,
                           exe_ctx.GetBestExecutionContextScope());
                dest.swap(reg_sstr.GetString());
            }
        }
        else
        {
            CompilerType compiler_type = value.GetCompilerType ();
            if (compiler_type)
            {
                // put custom bytes to display in the DataExtractor to override the default value logic
                if (GetFormat() == eFormatCString)
                {
                    lldb_private::Flags type_flags(compiler_type.GetTypeInfo(NULL)); // disambiguate w.r.t. TypeFormatImpl::Flags
                    if (type_flags.Test(eTypeIsPointer) && !type_flags.Test(eTypeIsObjC))
                    {
                        // if we are dumping a pointer as a c-string, get the pointee data as a string
                        TargetSP target_sp(valobj->GetTargetSP());
                        if (target_sp)
                        {
                            size_t max_len = target_sp->GetMaximumSizeOfStringSummary();
                            Error error;
                            DataBufferSP buffer_sp(new DataBufferHeap(max_len+1,0));
                            Address address(valobj->GetPointerValue());
                            if (target_sp->ReadCStringFromMemory(address, (char*)buffer_sp->GetBytes(), max_len, error) && error.Success())
                                data.SetData(buffer_sp);
                        }
                    }
                }
                else
                {
                    Error error;
                    valobj->GetData(data, error);
                    if (error.Fail())
                        return false;
                }
                
                StreamString sstr;
                compiler_type.DumpTypeValue (&sstr,                         // The stream to use for display
                                          GetFormat(),                  // Format to display this type with
                                          data,                         // Data to extract from
                                          0,                             // Byte offset into "m_data"
                                          valobj->GetByteSize(),                 // Byte size of item in "m_data"
                                          valobj->GetBitfieldBitSize(),          // Bitfield bit size
                                          valobj->GetBitfieldBitOffset(),        // Bitfield bit offset
                                          exe_ctx.GetBestExecutionContextScope());
                // Given that we do not want to set the ValueObject's m_error
                // for a formatting error (or else we wouldn't be able to reformat
                // until a next update), an empty string is treated as a "false"
                // return from here, but that's about as severe as we get
                // CompilerType::DumpTypeValue() should always return
                // something, even if that something is an error message
                if (sstr.GetString().empty())
                    dest.clear();
                else
                    dest.swap(sstr.GetString());
            }
        }
        return !dest.empty();
    }
    else
        return false;
}
Пример #28
0
const char *
ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope)
{
    if (UpdateValueIfNeeded (exe_scope))
    {
        if (m_summary_str.empty())
        {
            void *clang_type = GetOpaqueClangQualType();

            // See if this is a pointer to a C string?
            uint32_t fixed_length = 0;
            if (clang_type && ClangASTContext::IsCStringType (clang_type, fixed_length))
            {
                Process *process = exe_scope->CalculateProcess();
                if (process != NULL)
                {
                    StreamString sstr;
                    lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
                    lldb::AddressType cstr_address_type = eAddressTypeInvalid;
                    switch (GetValue().GetValueType())
                    {
                    case Value::eValueTypeScalar:
                        cstr_address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
                        cstr_address_type = eAddressTypeLoad;
                        break;

                    case Value::eValueTypeLoadAddress:
                    case Value::eValueTypeFileAddress:
                    case Value::eValueTypeHostAddress:
                        {
                            uint32_t data_offset = 0;
                            cstr_address = m_data.GetPointer(&data_offset);
                            cstr_address_type = m_value.GetValueAddressType();
                            if (cstr_address_type == eAddressTypeInvalid)
                                cstr_address_type = eAddressTypeLoad;
                        }
                        break;
                    }

                    if (cstr_address != LLDB_INVALID_ADDRESS)
                    {
                        DataExtractor data;
                        size_t bytes_read = 0;
                        std::vector<char> data_buffer;
                        std::vector<char> cstr_buffer;
                        size_t cstr_length;
                        Error error;
                        if (fixed_length > 0)
                        {
                            data_buffer.resize(fixed_length);
                            // Resize the formatted buffer in case every character
                            // uses the "\xXX" format and one extra byte for a NULL
                            cstr_buffer.resize(data_buffer.size() * 4 + 1);
                            data.SetData (data_buffer.data(), data_buffer.size(), eByteOrderHost);
                            bytes_read = process->ReadMemory (cstr_address, data_buffer.data(), fixed_length, error);
                            if (bytes_read > 0)
                            {
                                sstr << '"';
                                cstr_length = data.Dump (&sstr,
                                                         0,                 // Start offset in "data"
                                                         eFormatChar,       // Print as characters
                                                         1,                 // Size of item (1 byte for a char!)
                                                         bytes_read,        // How many bytes to print?
                                                         UINT32_MAX,        // num per line
                                                         LLDB_INVALID_ADDRESS,// base address
                                                         0,                 // bitfield bit size
                                                         0);                // bitfield bit offset
                                sstr << '"';
                            }
                        }
                        else
                        {
                            const size_t k_max_buf_size = 256;
                            data_buffer.resize (k_max_buf_size + 1);
                            // NULL terminate in case we don't get the entire C string
                            data_buffer.back() = '\0';
                            // Make a formatted buffer that can contain take 4
                            // bytes per character in case each byte uses the
                            // "\xXX" format and one extra byte for a NULL
                            cstr_buffer.resize (k_max_buf_size * 4 + 1);

                            data.SetData (data_buffer.data(), data_buffer.size(), eByteOrderHost);
                            size_t total_cstr_len = 0;
                            while ((bytes_read = process->ReadMemory (cstr_address, data_buffer.data(), k_max_buf_size, error)) > 0)
                            {
                                size_t len = strlen(data_buffer.data());
                                if (len == 0)
                                    break;
                                if (len > bytes_read)
                                    len = bytes_read;
                                if (sstr.GetSize() == 0)
                                    sstr << '"';

                                cstr_length = data.Dump (&sstr,
                                                         0,                 // Start offset in "data"
                                                         eFormatChar,       // Print as characters
                                                         1,                 // Size of item (1 byte for a char!)
                                                         len,               // How many bytes to print?
                                                         UINT32_MAX,        // num per line
                                                         LLDB_INVALID_ADDRESS,// base address
                                                         0,                 // bitfield bit size
                                                         0);                // bitfield bit offset

                                if (len < k_max_buf_size)
                                    break;
                                cstr_address += total_cstr_len;
                            }
                            if (sstr.GetSize() > 0)
                                sstr << '"';
                        }

                        if (sstr.GetSize() > 0)
                            m_summary_str.assign (sstr.GetData(), sstr.GetSize());
                    }
                }
            }
        }
    }
    if (m_summary_str.empty())
        return NULL;
    return m_summary_str.c_str();
}
Пример #29
0
Error
Value::GetValueAsData (ExecutionContext *exe_ctx,
                       DataExtractor &data,
                       uint32_t data_offset,
                       Module *module)
{
    data.Clear();

    Error error;
    lldb::addr_t address = LLDB_INVALID_ADDRESS;
    AddressType address_type = eAddressTypeFile;
    Address file_so_addr;
    const CompilerType &ast_type = GetCompilerType();
    switch (m_value_type)
    {
    case eValueTypeVector:
        if (ast_type.IsValid())
            data.SetAddressByteSize (ast_type.GetPointerByteSize());
        else
            data.SetAddressByteSize(sizeof(void *));
        data.SetData(m_vector.bytes, m_vector.length, m_vector.byte_order);
        break;

    case eValueTypeScalar:
        {
            data.SetByteOrder (endian::InlHostByteOrder());
            if (ast_type.IsValid())
                data.SetAddressByteSize (ast_type.GetPointerByteSize());
            else
                data.SetAddressByteSize(sizeof(void *));

            uint32_t limit_byte_size = UINT32_MAX;
            
            if (ast_type.IsValid() && ast_type.IsScalarType())
            {
                uint64_t type_encoding_count = 0;
                lldb::Encoding type_encoding = ast_type.GetEncoding(type_encoding_count);
                
                if (type_encoding == eEncodingUint || type_encoding == eEncodingSint)
                    limit_byte_size = ast_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
            }
            
            if (m_value.GetData (data, limit_byte_size))
                return error;   // Success;
            
            error.SetErrorStringWithFormat("extracting data from value failed");
            break;
        }
    case eValueTypeLoadAddress:
        if (exe_ctx == NULL)
        {
            error.SetErrorString ("can't read load address (no execution context)");
        }
        else 
        {
            Process *process = exe_ctx->GetProcessPtr();
            if (process == NULL || !process->IsAlive())
            {
                Target *target = exe_ctx->GetTargetPtr();
                if (target)
                {
                    // Allow expressions to run and evaluate things when the target
                    // has memory sections loaded. This allows you to use "target modules load"
                    // to load your executable and any shared libraries, then execute
                    // commands where you can look at types in data sections.
                    const SectionLoadList &target_sections = target->GetSectionLoadList();
                    if (!target_sections.IsEmpty())
                    {
                        address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
                        if (target_sections.ResolveLoadAddress(address, file_so_addr))
                        {
                            address_type = eAddressTypeLoad;
                            data.SetByteOrder(target->GetArchitecture().GetByteOrder());
                            data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
                        }
                        else
                            address = LLDB_INVALID_ADDRESS;
                    }
//                    else
//                    {
//                        ModuleSP exe_module_sp (target->GetExecutableModule());
//                        if (exe_module_sp)
//                        {
//                            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
//                            if (address != LLDB_INVALID_ADDRESS)
//                            {
//                                if (exe_module_sp->ResolveFileAddress(address, file_so_addr))
//                                {
//                                    data.SetByteOrder(target->GetArchitecture().GetByteOrder());
//                                    data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
//                                    address_type = eAddressTypeFile;
//                                }
//                                else
//                                {
//                                    address = LLDB_INVALID_ADDRESS;
//                                }
//                            }
//                        }
//                    }
                }
                else
                {
                    error.SetErrorString ("can't read load address (invalid process)");
                }
            }
            else
            {
                address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
                address_type = eAddressTypeLoad;
                data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder());
                data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize());
            }
        }
        break;

    case eValueTypeFileAddress:
        if (exe_ctx == NULL)
        {
            error.SetErrorString ("can't read file address (no execution context)");
        }
        else if (exe_ctx->GetTargetPtr() == NULL)
        {
            error.SetErrorString ("can't read file address (invalid target)");
        }
        else
        {
            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
            if (address == LLDB_INVALID_ADDRESS)
            {
                error.SetErrorString ("invalid file address");
            }
            else
            {
                if (module == NULL)
                {
                    // The only thing we can currently lock down to a module so that
                    // we can resolve a file address, is a variable.
                    Variable *variable = GetVariable();
                    if (variable)
                    {
                        SymbolContext var_sc;
                        variable->CalculateSymbolContext(&var_sc);
                        module = var_sc.module_sp.get();
                    }
                }
                
                if (module)
                {
                    bool resolved = false;
                    ObjectFile *objfile = module->GetObjectFile();
                    if (objfile)
                    {
                        Address so_addr(address, objfile->GetSectionList());
                        addr_t load_address = so_addr.GetLoadAddress (exe_ctx->GetTargetPtr());
                        bool process_launched_and_stopped = exe_ctx->GetProcessPtr()
                            ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(), true /* must_exist */)
                            : false;
                        // Don't use the load address if the process has exited.
                        if (load_address != LLDB_INVALID_ADDRESS && process_launched_and_stopped)
                        {
                            resolved = true;
                            address = load_address;
                            address_type = eAddressTypeLoad;
                            data.SetByteOrder(exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
                            data.SetAddressByteSize(exe_ctx->GetTargetRef().GetArchitecture().GetAddressByteSize());
                        }
                        else
                        {
                            if (so_addr.IsSectionOffset())
                            {
                                resolved = true;
                                file_so_addr = so_addr;
                                data.SetByteOrder(objfile->GetByteOrder());
                                data.SetAddressByteSize(objfile->GetAddressByteSize());
                            }
                        }
                    }
                    if (!resolved)
                    {
                        Variable *variable = GetVariable();
                        
                        if (module)
                        {
                            if (variable)
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s' in %s",
                                                                address, 
                                                                variable->GetName().AsCString(""),
                                                                module->GetFileSpec().GetPath().c_str());
                            else
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " in %s",
                                                                address, 
                                                                module->GetFileSpec().GetPath().c_str());
                        }
                        else
                        {
                            if (variable)
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s'",
                                                                address, 
                                                                variable->GetName().AsCString(""));
                            else
                                error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64, address);
                        }
                    }
                }
                else
                {
                    // Can't convert a file address to anything valid without more
                    // context (which Module it came from)
                    error.SetErrorString ("can't read memory from file address without more context");
                }
            }
        }
        break;

    case eValueTypeHostAddress:
        address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
        address_type = eAddressTypeHost;
        if (exe_ctx)
        {
            Target *target = exe_ctx->GetTargetPtr();
            if (target)
            {
                data.SetByteOrder(target->GetArchitecture().GetByteOrder());
                data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
                break;
            }
        }
        // fallback to host settings
        data.SetByteOrder(endian::InlHostByteOrder());
        data.SetAddressByteSize(sizeof(void *));
        break;
    }

    // Bail if we encountered any errors
    if (error.Fail())
        return error;

    if (address == LLDB_INVALID_ADDRESS)
    {
        error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load");
        return error;
    }

    // If we got here, we need to read the value from memory
    size_t byte_size = GetValueByteSize (&error, exe_ctx);

    // Bail if we encountered any errors getting the byte size
    if (error.Fail())
        return error;

    // Make sure we have enough room within "data", and if we don't make
    // something large enough that does
    if (!data.ValidOffsetForDataOfSize (data_offset, byte_size))
    {
        DataBufferSP data_sp(new DataBufferHeap (data_offset + byte_size, '\0'));
        data.SetData(data_sp);
    }

    uint8_t* dst = const_cast<uint8_t*>(data.PeekData (data_offset, byte_size));
    if (dst != NULL)
    {
        if (address_type == eAddressTypeHost)
        {
            // The address is an address in this process, so just copy it.
            if (address == 0)
            {
                error.SetErrorStringWithFormat("trying to read from host address of 0.");
                return error;
            }
            memcpy (dst, (uint8_t*)NULL + address, byte_size);
        }
        else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile))
        {
            if (file_so_addr.IsValid())
            {
                // We have a file address that we were able to translate into a
                // section offset address so we might be able to read this from
                // the object files if we don't have a live process. Lets always
                // try and read from the process if we have one though since we
                // want to read the actual value by setting "prefer_file_cache"
                // to false. 
                const bool prefer_file_cache = false;
                if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size)
                {
                    error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed", (uint64_t)address);
                }
            }
            else
            {
                // The execution context might have a NULL process, but it
                // might have a valid process in the exe_ctx->target, so use
                // the ExecutionContext::GetProcess accessor to ensure we
                // get the process if there is one.
                Process *process = exe_ctx->GetProcessPtr();

                if (process)
                {
                    const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error);
                    if (bytes_read != byte_size)
                        error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
                                                       (uint64_t)address, 
                                                       (uint32_t)bytes_read, 
                                                       (uint32_t)byte_size);
                }
                else
                {
                    error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (invalid process)", (uint64_t)address);
                }
            }
        }
        else
        {
            error.SetErrorStringWithFormat ("unsupported AddressType value (%i)", address_type);
        }
    }
    else
    {
        error.SetErrorStringWithFormat ("out of memory");
    }

    return error;
}
Пример #30
0
bool CommunicationKDP::CheckForPacket(const uint8_t *src, size_t src_len,
                                      DataExtractor &packet) {
  // Put the packet data into the buffer in a thread safe fashion
  std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);

  Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));

  if (src && src_len > 0) {
    if (log && log->GetVerbose()) {
      PacketStreamType log_strm;
      DumpHexBytes(&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS);
      log->Printf("CommunicationKDP::%s adding %u bytes: %s", __FUNCTION__,
                  (uint32_t)src_len, log_strm.GetData());
    }
    m_bytes.append((const char *)src, src_len);
  }

  // Make sure we at least have enough bytes for a packet header
  const size_t bytes_available = m_bytes.size();
  if (bytes_available >= 8) {
    packet.SetData(&m_bytes[0], bytes_available, m_byte_order);
    lldb::offset_t offset = 0;
    uint8_t reply_command = packet.GetU8(&offset);
    switch (reply_command) {
    case ePacketTypeRequest | KDP_EXCEPTION:
    case ePacketTypeRequest | KDP_TERMINATION:
      // We got an exception request, so be sure to send an ACK
      {
        PacketStreamType request_ack_packet(Stream::eBinary, m_addr_byte_size,
                                            m_byte_order);
        // Set the reply but and make the ACK packet
        request_ack_packet.PutHex8(reply_command | ePacketTypeReply);
        request_ack_packet.PutHex8(packet.GetU8(&offset));
        request_ack_packet.PutHex16(packet.GetU16(&offset));
        request_ack_packet.PutHex32(packet.GetU32(&offset));
        m_is_running.SetValue(false, eBroadcastAlways);
        // Ack to the exception or termination
        SendRequestPacketNoLock(request_ack_packet);
      }
      // Fall through to case below to get packet contents
      LLVM_FALLTHROUGH;
    case ePacketTypeReply | KDP_CONNECT:
    case ePacketTypeReply | KDP_DISCONNECT:
    case ePacketTypeReply | KDP_HOSTINFO:
    case ePacketTypeReply | KDP_VERSION:
    case ePacketTypeReply | KDP_MAXBYTES:
    case ePacketTypeReply | KDP_READMEM:
    case ePacketTypeReply | KDP_WRITEMEM:
    case ePacketTypeReply | KDP_READREGS:
    case ePacketTypeReply | KDP_WRITEREGS:
    case ePacketTypeReply | KDP_LOAD:
    case ePacketTypeReply | KDP_IMAGEPATH:
    case ePacketTypeReply | KDP_SUSPEND:
    case ePacketTypeReply | KDP_RESUMECPUS:
    case ePacketTypeReply | KDP_BREAKPOINT_SET:
    case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
    case ePacketTypeReply | KDP_REGIONS:
    case ePacketTypeReply | KDP_REATTACH:
    case ePacketTypeReply | KDP_HOSTREBOOT:
    case ePacketTypeReply | KDP_READMEM64:
    case ePacketTypeReply | KDP_WRITEMEM64:
    case ePacketTypeReply | KDP_BREAKPOINT_SET64:
    case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
    case ePacketTypeReply | KDP_KERNELVERSION:
    case ePacketTypeReply | KDP_READPHYSMEM64:
    case ePacketTypeReply | KDP_WRITEPHYSMEM64:
    case ePacketTypeReply | KDP_READIOPORT:
    case ePacketTypeReply | KDP_WRITEIOPORT:
    case ePacketTypeReply | KDP_READMSR64:
    case ePacketTypeReply | KDP_WRITEMSR64:
    case ePacketTypeReply | KDP_DUMPINFO: {
      offset = 2;
      const uint16_t length = packet.GetU16(&offset);
      if (length <= bytes_available) {
        // We have an entire packet ready, we need to copy the data bytes into
        // a buffer that will be owned by the packet and erase the bytes from
        // our communcation buffer "m_bytes"
        packet.SetData(DataBufferSP(new DataBufferHeap(&m_bytes[0], length)));
        m_bytes.erase(0, length);

        if (log) {
          PacketStreamType log_strm;
          DumpPacket(log_strm, packet);

          log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
        }
        return true;
      }
    } break;

    default:
      // Unrecognized reply command byte, erase this byte and try to get back
      // on track
      if (log)
        log->Printf("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
                    __FUNCTION__, (uint8_t)m_bytes[0]);
      m_bytes.erase(0, 1);
      break;
    }
  }
  packet.Clear();
  return false;
}