diff --git a/src/libs/utils/elfreader.cpp b/src/libs/utils/elfreader.cpp index ade7311a44145320c24ff34ba3d638ff3505725e..8499599730594c27c0ae2e901b39381a68c551b3 100644 --- a/src/libs/utils/elfreader.cpp +++ b/src/libs/utils/elfreader.cpp @@ -48,6 +48,21 @@ namespace Utils { + +typedef quint16 qelfhalf_t; +typedef quint32 qelfword_t; +typedef quintptr qelfoff_t; +typedef quintptr qelfaddr_t; + +class ElfSectionHeader +{ +public: + qelfword_t name; + qelfword_t type; + qelfoff_t offset; + qelfoff_t size; +}; + template <typename T> T read(const char *s, ElfReader::ElfEndian endian) { @@ -78,7 +93,7 @@ const char *ElfReader::parseSectionHeader(const char *data, ElfSectionHeader *sh } ElfReader::Result ElfReader::parse(const char *dataStart, quint64 fdlen, - QList<QByteArray> *sectionNames) + ElfSections *sections) { if (fdlen < 64) { m_errorString = QLibrary::tr("'%1' is not an ELF object (%2)") @@ -204,17 +219,22 @@ ElfReader::Result ElfReader::parse(const char *dataStart, quint64 fdlen, return Corrupt; } - if (sectionNames) - sectionNames->append(shnam); + if (sections) { + ElfSection section; + section.name = shnam; + section.index = strtab.name; + section.offset = strtab.offset; + section.size = strtab.size; + } s += e_shentsize; } return Ok; } -QList<QByteArray> ElfReader::sectionNames() +ElfSections ElfReader::sections() { - QList<QByteArray> names; + ElfSections names; QFile file(m_binary); if (!file.open(QIODevice::ReadOnly)) { diff --git a/src/libs/utils/elfreader.h b/src/libs/utils/elfreader.h index 97449508f0e8e5ce2ce4a97ecb24460531117aa4..02bf6884a4cf2f19755320dc2ea9b42293afec8b 100644 --- a/src/libs/utils/elfreader.h +++ b/src/libs/utils/elfreader.h @@ -52,33 +52,34 @@ namespace Utils { -typedef quint16 qelfhalf_t; -typedef quint32 qelfword_t; -typedef quintptr qelfoff_t; -typedef quintptr qelfaddr_t; +class ElfSectionHeader; + +class QTCREATOR_UTILS_EXPORT ElfSection +{ +public: + QByteArray name; + quint32 index; + quint32 type; + quint64 offset; + quint64 size; +}; + +typedef QList<ElfSection> ElfSections; class QTCREATOR_UTILS_EXPORT ElfReader { public: explicit ElfReader(const QString &binary); - struct ElfSectionHeader - { - qelfword_t name; - qelfword_t type; - qelfoff_t offset; - qelfoff_t size; - }; - enum ElfEndian { ElfLittleEndian = 0, ElfBigEndian = 1 }; - QList<QByteArray> sectionNames(); + ElfSections sections(); QString errorString() const { return m_errorString; } private: enum Result { Ok, NotElf, Corrupt }; const char *parseSectionHeader(const char *s, ElfSectionHeader *sh); - Result parse(const char *dataStart, quint64 fdlen, QList<QByteArray> *sectionNames); + Result parse(const char *dataStart, quint64 fdlen, ElfSections *sections); QString m_binary; QString m_errorString; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 8465027530531efe5ea25ac5a9fed9ad37d7f01c..63f201409e435a3a3fd5d6c547e5509fdedec2c4 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3519,16 +3519,25 @@ void GdbEngine::handleModulesList(const GdbResponse &response) void GdbEngine::examineModule(Module *module) { - Utils::ElfReader reader(module->modulePath); - QList<QByteArray> names = reader.sectionNames(); - if (names.contains(".gdb_index")) - module->symbolsType = Module::FastSymbols; - else if (names.contains(".debug_inf")) - module->symbolsType = Module::PlainSymbols; - else if (names.contains(".gnu_debuglink")) - module->symbolsType = Module::SeparateSymbols; - else - module->symbolsType = Module::NoSymbols; + using namespace Utils; + ElfReader reader(module->modulePath); + ElfSections sections = reader.sections(); + module->symbolsType = Module::NoSymbols; + for (int i = 0, n = sections.size(); i != n; ++i) { + const QByteArray &name = sections.at(i).name; + if (name == ".gdb_index") { + module->symbolsType = Module::FastSymbols; + break; + } + if (name == ".debug_info") { + module->symbolsType = Module::PlainSymbols; + break; + } + if (name == ".gnu_debuglink") { + module->symbolsType = Module::SeparateSymbols; + break; + } + } } void GdbEngine::examineModules() @@ -5371,9 +5380,10 @@ bool GdbEngine::attemptQuickStart() const void GdbEngine::checkForReleaseBuild() { + using namespace Utils; QString binary = startParameters().executable; - Utils::ElfReader reader(binary); - QList<QByteArray> names = reader.sectionNames(); + ElfReader reader(binary); + ElfSections sections = reader.sections(); QString error = reader.errorString(); showMessage(_("EXAMINING ") + binary); @@ -5394,11 +5404,11 @@ void GdbEngine::checkForReleaseBuild() } QSet<QByteArray> seen; - foreach (const QByteArray &name, names) { - msg.append(name); + foreach (const ElfSection §ion, sections) { + msg.append(section.name); msg.append(' '); - if (interesting.contains(name)) - seen.insert(name); + if (interesting.contains(section.name)) + seen.insert(section.name); } showMessage(_(msg)); @@ -5406,13 +5416,16 @@ void GdbEngine::checkForReleaseBuild() showMessage(_("ERROR WHILE READING ELF SECTIONS: ") + error); return; } - if (names.isEmpty()) { - showMessage(_("NO SECTION HEADERS FOUND")); + + if (sections.isEmpty()) { + showMessage(_("NO SECTION HEADERS FOUND. IS THIS AN EXECUTABLE?")); return; } - if (names.contains(".debug_info")) - return; + foreach (const ElfSection §ion, sections) { + if (section.name == ".debug_info") + return; + } QString warning; warning = tr("This does not seem to be a \"Debug\" build.\n"