Example #1
0
size_t
ObjectFile::GetModuleSpecifications (const FileSpec &file,
                                     lldb::offset_t file_offset,
                                     ModuleSpecList &specs)
{
    DataBufferSP data_sp (file.ReadFileContents(file_offset, 512));
    if (data_sp)
        return ObjectFile::GetModuleSpecifications (file,                    // file spec
                                                    data_sp,                 // data bytes
                                                    0,                       // data offset
                                                    file_offset,             // file offset
                                                    data_sp->GetByteSize(),  // data length
                                                    specs);
    return 0;
}
Example #2
0
size_t ObjectFile::GetModuleSpecifications(const FileSpec &file,
                                           lldb::offset_t file_offset,
                                           lldb::offset_t file_size,
                                           ModuleSpecList &specs) {
  DataBufferSP data_sp(file.ReadFileContents(file_offset, 512));
  if (data_sp) {
    if (file_size == 0) {
      const lldb::offset_t actual_file_size = file.GetByteSize();
      if (actual_file_size > file_offset)
        file_size = actual_file_size - file_offset;
    }
    return ObjectFile::GetModuleSpecifications(file,        // file spec
                                               data_sp,     // data bytes
                                               0,           // data offset
                                               file_offset, // file offset
                                               file_size,   // file length
                                               specs);
  }
  return 0;
}
Example #3
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;
}
Example #4
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;
}
Example #5
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;
}
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;
}