static ProbeABI abiFromMachO(const uchar* data, qint64 size) { ProbeABI abi; const quint32 magic = *reinterpret_cast<const quint32*>(data); quint32 offset = 0; qint32 ncmds = 0; qint32 cmdsize = 0; switch (magic) { case MH_MAGIC: abi.setArchitecture(readMachOHeader<mach_header>(data, size, offset, ncmds, cmdsize)); break; case MH_MAGIC_64: abi.setArchitecture(readMachOHeader<mach_header_64>(data, size, offset, ncmds, cmdsize)); break; } if (offset >= size || ncmds <= 0 || cmdsize <= 0 || size <= offset + cmdsize) return ProbeABI(); // read load commands for (int i = 0; i < ncmds; ++i) { const load_command* cmd = reinterpret_cast<const load_command*>(data + offset); if (cmd->cmd == LC_ID_DYLIB) { const dylib_command* dlcmd = reinterpret_cast<const dylib_command*>(data + offset); const int majorVersion = (dlcmd->dylib.current_version & 0x00ff0000) >> 16; const int minorVersion = (dlcmd->dylib.current_version & 0x0000ff00) >> 8; abi.setQtVersion(majorVersion, minorVersion); } offset += cmd->cmdsize; } return abi; }
ProbeABI ProbeABIDetector::detectAbiForQtCore(const QString &path) const { if (path.isEmpty()) return ProbeABI(); // try to find the version ProbeABI abi = qtVersionFromFileName(path); if (!abi.hasQtVersion()) abi = qtVersionFromExec(path); // TODO: architecture detection fallback without elf.h? const QString arch = archFromELF(path); abi.setArchitecture(arch); return abi; }
void testToString() { QFETCH(QString, id); QFETCH(int, majorVersion); QFETCH(int, minorVersion); QFETCH(bool, isDebug); QFETCH(QString, arch); QFETCH(QString, compiler); QFETCH(QString, compilerVersion); ProbeABI abi; abi.setQtVersion(majorVersion, minorVersion); abi.setIsDebug(isDebug); abi.setArchitecture(arch); abi.setCompiler(compiler); abi.setCompilerVersion(compilerVersion); QCOMPARE(abi.id(), id); }
ProbeABI ProbeABI::fromString(const QString &id) { QStringList idParts = id.split('-'); if (idParts.size() < 2) return ProbeABI(); int index = 0; ProbeABI abi; // version static QRegExp versionRegExp("^qt(\\d+)\\_(\\d+)$"); if (versionRegExp.indexIn(idParts.value(index++)) != 0) return ProbeABI(); abi.setQtVersion(versionRegExp.cap(1).toInt(), versionRegExp.cap(2).toInt()); // compiler #ifdef Q_OS_WIN abi.setCompiler(idParts.value(index++)); if (abi.isVersionRelevant()) abi.setCompilerVersion(idParts.value(index++)); #endif if (idParts.size() != index + 1) return ProbeABI(); // architecture / debug/release const QString postfix = QStringLiteral(GAMMARAY_DEBUG_POSTFIX); QString arch = idParts.value(index); if (!postfix.isEmpty()) { if (arch.endsWith(postfix, Qt::CaseInsensitive)) { arch.chop(postfix.length()); if (abi.isDebugRelevant()) abi.setIsDebug(true); } } abi.setArchitecture(arch); return abi; }
ProbeABI ProbeABI::fromString(const QString& id) { QStringList idParts = id.split('-'); if (idParts.size() < 2) return ProbeABI(); int index = 0; ProbeABI abi; // version static QRegExp versionRegExp("^qt(\\d+)\\.(\\d+)$"); if (versionRegExp.indexIn(idParts.value(index++)) != 0) return ProbeABI(); abi.setQtVersion(versionRegExp.cap(1).toInt(), versionRegExp.cap(2).toInt()); // compiler #ifdef Q_OS_WIN abi.setCompiler(idParts.value(index++)); #endif // debug/release if (abi.isDebugRelevant()) { if (idParts.size() <= index) return ProbeABI(); const QString s = idParts.value(index++); if (s != "release" && s != "debug") return ProbeABI(); abi.setIsDebug(s == "debug"); } // architecture if (idParts.size() != index + 1) return ProbeABI(); abi.setArchitecture(idParts.value(index)); return abi; }