Merge pull request #181 from QuasarApp/ELFFixes

Elf fixes
This commit is contained in:
Andrei Yankovich 2019-09-23 14:51:50 +03:00 committed by GitHub
commit 000f0f3d6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 236 additions and 24 deletions

View File

@ -52,6 +52,7 @@ SOURCES += \
envirement.cpp \
extracter.cpp \
filemanager.cpp \
ignorerule.cpp \
metafilemanager.cpp \
pe.cpp \
igetlibinfo.cpp \
@ -71,6 +72,7 @@ HEADERS += \
envirement.h \
extracter.h \
filemanager.h \
ignorerule.h \
metafilemanager.h \
pe.h \
igetlibinfo.h \

View File

@ -361,11 +361,48 @@ void ConfigParser::initIgnoreList()
{
if (QuasarAppUtils::Params::isEndable("ignore")) {
auto list = QuasarAppUtils::Params::getStrArg("ignore").split(',');
_config.ignoreList.append(list);
for (auto &i : list) {
_config.ignoreList.addRule(IgnoreData(i));
}
}
if (QuasarAppUtils::Params::isEndable("noLibc")) {
_config.ignoreList.append("libc.so");
IgnoreData rule;
Envirement env;
env.addEnv(recursiveInvairement(3 ,"/lib"), "", "");
env.addEnv(recursiveInvairement(3 ,"/usr/lib"), "", "");
rule.prority = SystemLib;
rule.platform = Unix32 | Unix64;
rule.enfirement = env;
auto addRule = [&rule](const QString & lib) {
rule.label = lib;
return rule;
};
_config.ignoreList.addRule(addRule("libc"));
_config.ignoreList.addRule(addRule("ld-"));
_config.ignoreList.addRule(addRule("libpthread"));
_config.ignoreList.addRule(addRule("libm"));
_config.ignoreList.addRule(addRule("libz"));
_config.ignoreList.addRule(addRule("libnsl"));
_config.ignoreList.addRule(addRule("libdl"));
_config.ignoreList.addRule(addRule("libutil"));
_config.ignoreList.addRule(addRule("libresolv"));
_config.ignoreList.addRule(addRule("libBrokenLocale"));
_config.ignoreList.addRule(addRule("libBrokenLocale"));
_config.ignoreList.addRule(addRule("libSegFault"));
_config.ignoreList.addRule(addRule("libanl"));
_config.ignoreList.addRule(addRule("libcrypt"));
_config.ignoreList.addRule(addRule("/gconv/"));
_config.ignoreList.addRule(addRule("libnss"));
}
}
@ -480,6 +517,12 @@ QString ConfigParser::recursiveInvairement(int depch, QDir &dir) {
return res;
}
QString ConfigParser::recursiveInvairement(int depch, const QString &dir) {
QDir _dir(dir);
return recursiveInvairement(depch, _dir);
}
void ConfigParser::initEnvirement() {
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
_config.envirement.addEnv(env.value("LD_LIBRARY_PATH"), _config.appDir, _config.targetDir);

View File

@ -2,6 +2,7 @@
#define CQT_H
#include "distrostruct.h"
#include "envirement.h"
#include "ignorerule.h"
#include <QJsonObject>
#include <QJsonDocument>
@ -21,7 +22,7 @@ struct DEPLOYSHARED_EXPORT DeployConfig {
QString qmlDir = "";
int depchLimit = 0;
bool deployQml = false;
QStringList ignoreList;
IgnoreRule ignoreList;
QStringList extraPlugins;
QString appDir;
QString qtDir;
@ -66,6 +67,7 @@ private:
void setExtraPlugins(const QStringList &value);
QString recursiveInvairement(int depch, QDir &dir);
QString recursiveInvairement(int depch, const QString &dir);
void initEnvirement();

View File

@ -33,10 +33,10 @@ struct DEPLOYSHARED_EXPORT QtModuleEntry {
enum Platform {
UnknownPlatform = 0x0,
Win32,
Win64,
Unix32,
Unix64
Win32 = 0x1,
Win64 = 0x2,
Unix32 = 0x4,
Unix64 = 0x8
};
enum LibPriority : int {

View File

@ -1,5 +1,5 @@
#include "elf.h"
#include <cmath>
#include <QFileInfo>
ELF::ELF()
@ -7,6 +7,41 @@ ELF::ELF()
}
QByteArrayList ELF::getDynamicString(ElfReader& reader) const {
auto headers = reader.readHeaders();
for (auto &sectionHeader : headers.sectionHeaders) {
if (sectionHeader.name == ".dynstr") {
auto arr = reader.readSection(sectionHeader.name).split(0);
return arr;
}
}
return {};
}
int ELF::getVersionOfTag(const QByteArray& tag, QByteArray& source) const {
auto versions = source.replace(tag, "").split('.');
int step = static_cast<int>(pow(100, 4));
int ver = 0;
auto it = versions.begin();
while (it != versions.end()) {
bool ok;
int curVer = it->toInt(&ok);
if (!ok) {
return -1;
}
ver += curVer * step;
step /= 100;
it++;
}
return ver;
}
bool ELF::getLibInfo(const QString &lib, LibInfo &info) const {
ElfReader reader(lib);
@ -21,6 +56,20 @@ bool ELF::getLibInfo(const QString &lib, LibInfo &info) const {
return false;
}
auto dynStr = getDynamicString(reader);
for (auto i = dynStr.rbegin(); i != dynStr.rend(); ++i) {
if (i->contains("end_")) {
break;
}
if (QFileInfo(*i).isDir()) {
info.setQtPath(*i);
}
}
info.setName(QFileInfo(lib).fileName());
info.setPath(QFileInfo(lib).absolutePath());

View File

@ -7,6 +7,11 @@
class ELF : public IGetLibInfo
{
private:
QByteArrayList getDynamicString(ElfReader &reader) const;
int getVersionOfTag(const QByteArray &tag, QByteArray &source) const;
public:
ELF();

View File

@ -43,7 +43,7 @@ void Envirement::addEnv(const QString &dir, const QString &appDir, const QString
}
}
if (path.contains(appDir)) {
if (!appDir.isEmpty() && path.contains(appDir)) {
QuasarAppUtils::Params::verboseLog("is cqtdeployer dir!: " + path + " app dir : " + appDir);
return;
}
@ -58,7 +58,7 @@ void Envirement::addEnv(const QString &dir, const QString &appDir, const QString
return;
}
if (path.contains(targetDir)) {
if (!targetDir.isEmpty() && path.contains(targetDir)) {
QuasarAppUtils::Params::verboseLog ("Skip paths becouse it is target : " + path);
return;
}
@ -66,6 +66,15 @@ void Envirement::addEnv(const QString &dir, const QString &appDir, const QString
_deployEnvironment.insert(QDir::fromNativeSeparators(path));
}
bool Envirement::inThisEnvirement(const QString &file) const {
QFileInfo info (file);
if (info.isFile()) {
return _deployEnvironment.contains(info.absolutePath());
}
return _deployEnvironment.contains(file);
}
int Envirement::size() const {
return _deployEnvironment.size();
}

View File

@ -19,7 +19,9 @@ public:
QStringList ignoreEnvList() const;
void setIgnoreEnvList(const QStringList &ignoreEnvList);
void addEnv(const QString &dir, const QString &appDir, const QString &targetDir);
void addEnv(const QString &dir, const QString &appDir = "", const QString &targetDir = "");
// return true if file exits in this envirement
bool inThisEnvirement(const QString &file) const;
int size() const;
QString concatEnv() const;

View File

@ -268,16 +268,7 @@ void Extracter::extractLib(const QString &file) {
auto data = scaner.scan(file);
for (auto &line : data) {
bool isIgnore = false;
for (auto ignore : DeployCore::_config->ignoreList) {
if (line.fullPath().contains(ignore)) {
QuasarAppUtils::Params::verboseLog(line.fullPath() + " ignored by filter" + ignore);
isIgnore = true;
continue;
}
}
if (isIgnore) {
if (DeployCore::_config->ignoreList.isIgnore(line)) {
continue;
}

49
Deploy/ignorerule.cpp Normal file
View File

@ -0,0 +1,49 @@
#include "ignorerule.h"
#include <quasarapp.h>
bool IgnoreRule::checkOnlytext(const QString &lib) {
for (auto ignore : _data) {
if (lib.contains(ignore.label)) {
return true;
}
}
return false;
}
IgnoreRule::IgnoreRule() {
}
void IgnoreRule::addRule(const IgnoreData &rule) {
_data.push_back(rule);
}
bool IgnoreRule::check(const LibInfo &info, const QString& ignoreLabel) const {
if (info.fullPath().contains(ignoreLabel)) {
QuasarAppUtils::Params::verboseLog(info.fullPath() + " ignored by filter" + ignoreLabel);
return true;
}
return false;
}
bool IgnoreRule::isIgnore(const LibInfo &info) const {
for (auto &ignore : _data) {
bool checkPlatform = ((ignore.platform & info.getPlatform()) == info.getPlatform()) || ignore.platform == UnknownPlatform;
bool checkPriority = ignore.prority >= info.getPriority();
bool checkEnvirement = !ignore.enfirement.size() || ignore.enfirement.inThisEnvirement(info.fullPath());
if (checkPlatform && checkPriority && checkEnvirement) {
return check(info, ignore.label);
}
}
return false;
}
IgnoreData::IgnoreData(const QString &label) {
this->label = label;
}

39
Deploy/ignorerule.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef IGNORERULE_H
#define IGNORERULE_H
#include "envirement.h"
#include "libinfo.h"
#include <QString>
#include <deploycore.h>
/**
* @brief The IgnoreData struct
* ignore file with label and othe rooles
*/
struct IgnoreData{
IgnoreData(const QString& label = "");
QString label;
Platform platform = UnknownPlatform;
LibPriority prority = NotFile;
Envirement enfirement;
};
class IgnoreRule
{
private:
QList<IgnoreData> _data;
bool checkOnlytext(const QString& lib);
bool check(const LibInfo &info, const QString &ignoreLabel) const;
public:
IgnoreRule();
void addRule(const IgnoreData& rule);
bool isIgnore(const LibInfo& info) const;
};
#endif // IGNORERULE_H

View File

@ -72,6 +72,16 @@ void LibInfo::setPriority(const LibPriority &value) {
priority = value;
}
QString LibInfo::getQtPath() const
{
return qtPath;
}
void LibInfo::setQtPath(const QString &value)
{
qtPath = value;
}
QString LibInfo::fullPath() const {
return path + "/" + name;
}
@ -79,6 +89,7 @@ QString LibInfo::fullPath() const {
void LibInfo::clear() {
path = "";
name = "";
qtPath = "";
platform = Platform::UnknownPlatform;
dependncies.clear();
allDep.clear();

View File

@ -11,6 +11,7 @@ private:
QString name;
QString path;
QSet<QString> dependncies;
QString qtPath;
LibPriority priority = NotFile;
public:
@ -42,6 +43,8 @@ public:
LibPriority getPriority() const;
void setPriority(const LibPriority &value);
QString getQtPath() const;
void setQtPath(const QString &value);
};
uint qHash(const LibInfo& info);

View File

@ -8,9 +8,13 @@ TestUtils::TestUtils()
}
QSet<QString> TestUtils::getTree(const QString &path) {
QSet<QString> TestUtils::getTree(const QString &path, int limit, int depch) {
QFileInfo info(path);
if (limit > 0 && depch >= limit) {
return {};
}
if (!info.exists()) {
return {};
}
@ -25,7 +29,7 @@ QSet<QString> TestUtils::getTree(const QString &path) {
QDir dir(info.absoluteFilePath());
auto list = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
for (auto &i: list) {
result.unite(getTree(i.absoluteFilePath()));
result.unite(getTree(i.absoluteFilePath(), limit, depch + 1));
}
return result;

View File

@ -7,7 +7,7 @@ class TestUtils
{
public:
TestUtils();
QSet<QString> getTree( const QString& path);
QSet<QString> getTree(const QString& path, int limit = -1, int depch = 0);
QSet<QString> createTree( const QStringList& tree);
/**

View File

@ -187,6 +187,9 @@ deploytest::deploytest() {
auto tempTree = utils.getTree(TestQtDir);
tempTree += utils.getTree("/lib", 4);
tempTree += utils.getTree("/usr/lib", 4);
for (const QString &i: tempTree) {
qtFilesTree.insert(QFileInfo(i).fileName());
}