From 736820a1a0b1348beb4f0d8c690455de5926cebe Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 6 Sep 2021 18:20:26 +0200 Subject: [PATCH] Debugger: Make ElfReader work remotely This does not use the mmap optimization so it might turn out to be too expensive for large files and slow connections. For now it seems good enough for docker and normal test cases. Change-Id: I0ba09bdbd6aac977209494a33099479f1f8eec0a Reviewed-by: Christian Stenger Reviewed-by: Orgad Shaneh --- src/libs/utils/elfreader.cpp | 31 +++++++++++++++++-------- src/libs/utils/elfreader.h | 19 ++++++++------- src/plugins/debugger/debuggerengine.cpp | 2 +- src/plugins/debugger/moduleshandler.cpp | 2 +- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/libs/utils/elfreader.cpp b/src/libs/utils/elfreader.cpp index 7f685e85522..3ff33880414 100644 --- a/src/libs/utils/elfreader.cpp +++ b/src/libs/utils/elfreader.cpp @@ -28,12 +28,13 @@ #include #include +#include #include // std::bad_alloc namespace Utils { -quint16 getHalfWord(const unsigned char *&s, const ElfData &context) +static quint16 getHalfWord(const unsigned char *&s, const ElfData &context) { quint16 res; if (context.endian == Elf_ELFDATA2MSB) @@ -44,7 +45,7 @@ quint16 getHalfWord(const unsigned char *&s, const ElfData &context) return res; } -quint32 getWord(const unsigned char *&s, const ElfData &context) +static quint32 getWord(const unsigned char *&s, const ElfData &context) { quint32 res; if (context.endian == Elf_ELFDATA2MSB) @@ -55,7 +56,7 @@ quint32 getWord(const unsigned char *&s, const ElfData &context) return res; } -quint64 getAddress(const unsigned char *&s, const ElfData &context) +static quint64 getAddress(const unsigned char *&s, const ElfData &context) { quint64 res; if (context.elfclass == Elf_ELFCLASS32) { @@ -74,7 +75,7 @@ quint64 getAddress(const unsigned char *&s, const ElfData &context) return res; } -quint64 getOffset(const unsigned char *&s, const ElfData &context) +static quint64 getOffset(const unsigned char *&s, const ElfData &context) { return getAddress(s, context); } @@ -99,10 +100,20 @@ static void parseProgramHeader(const uchar *s, ElfProgramHeader *sh, const ElfDa sh->memsz = getWord(s, context); } -ElfMapper::ElfMapper(const ElfReader *reader) : file(reader->m_binary) {} +ElfMapper::ElfMapper(const ElfReader *reader) + : binary(reader->m_binary) +{} bool ElfMapper::map() { + if (binary.needsDevice()) { + raw = binary.fileContents(); + start = raw.constData(); + fdlen = raw.size(); + return fdlen > 0; + } + + file.setFileName(binary.fileName()); if (!file.open(QIODevice::ReadOnly)) return false; @@ -121,7 +132,7 @@ bool ElfMapper::map() return true; } -ElfReader::ElfReader(const QString &binary) +ElfReader::ElfReader(const FilePath &binary) : m_binary(binary) { } @@ -132,10 +143,10 @@ ElfData ElfReader::readHeaders() return m_elfData; } -static inline QString msgInvalidElfObject(const QString &binary, const QString &why) +static QString msgInvalidElfObject(const FilePath &binary, const QString &why) { return ElfReader::tr("\"%1\" is an invalid ELF object (%2)") - .arg(QDir::toNativeSeparators(binary), why); + .arg(binary.toUserOutput(), why); } ElfReader::Result ElfReader::readIt() @@ -152,12 +163,12 @@ ElfReader::Result ElfReader::readIt() const quint64 fdlen = mapper.fdlen; if (fdlen < 64) { - m_errorString = tr("\"%1\" is not an ELF object (file too small)").arg(QDir::toNativeSeparators(m_binary)); + m_errorString = tr("\"%1\" is not an ELF object (file too small)").arg(m_binary.toUserOutput()); return NotElf; } if (strncmp(mapper.start, "\177ELF", 4) != 0) { - m_errorString = tr("\"%1\" is not an ELF object").arg(QDir::toNativeSeparators(m_binary)); + m_errorString = tr("\"%1\" is not an ELF object").arg(m_binary.toUserOutput()); return NotElf; } diff --git a/src/libs/utils/elfreader.h b/src/libs/utils/elfreader.h index cc82e71d018..052703f7c0e 100644 --- a/src/libs/utils/elfreader.h +++ b/src/libs/utils/elfreader.h @@ -27,12 +27,13 @@ #include "utils_global.h" -#include -#include -#include -#include -#include -#include +#include "filepath.h" + +#include +#include +#include +#include +#include namespace Utils { @@ -156,8 +157,9 @@ public: class QTCREATOR_UTILS_EXPORT ElfReader { Q_DECLARE_TR_FUNCTIONS(Utils::ElfReader) + public: - explicit ElfReader(const QString &binary); + explicit ElfReader(const FilePath &binary); enum Result { Ok, NotElf, Corrupt }; ElfData readHeaders(); @@ -169,7 +171,7 @@ private: friend class ElfMapper; Result readIt(); - QString m_binary; + FilePath m_binary; QString m_errorString; ElfData m_elfData; }; @@ -185,6 +187,7 @@ public: QByteArray raw; union { const char *start; const uchar *ustart; }; quint64 fdlen = 0; + FilePath binary; }; } // namespace Utils diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 1a3e31d8270..c55deb55393 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -2778,7 +2778,7 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp) break; } - Utils::ElfReader reader(rp.symbolFile.toString()); + ElfReader reader(rp.symbolFile); const ElfData elfData = reader.readHeaders(); const QString error = reader.errorString(); diff --git a/src/plugins/debugger/moduleshandler.cpp b/src/plugins/debugger/moduleshandler.cpp index 922c8bec2af..e894042c2d8 100644 --- a/src/plugins/debugger/moduleshandler.cpp +++ b/src/plugins/debugger/moduleshandler.cpp @@ -305,7 +305,7 @@ void ModulesHandler::updateModule(const Module &module) } try { // MinGW occasionallly throws std::bad_alloc. - ElfReader reader(path); + ElfReader reader(FilePath::fromString(path)); item->module.elfData = reader.readHeaders(); item->update(); } catch(...) {