Commit a7f8c3c8 authored by hjk's avatar hjk Committed by hjk

debugger: reshuffle sections in module data

Keep track of elf section headers, add a dumper for
Utils::ElfSection etc.

Change-Id: I06d01c0de01ffc6b827a4a79bdc91fdb3e761d75
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent 1b1dbf1b
......@@ -2431,6 +2431,10 @@ def qdump__CPlusPlus__Internal__Value(d, value):
d.putValue(value["l"])
d.putPlainChildren(value)
def qdump__Utils__ElfSection(d, value):
d.putByteArrayValue(value["name"])
d.putPlainChildren(value)
def qdump__CPlusPlus__Token(d, value):
k = value["f"]["kind"];
if long(k) == 6:
......
......@@ -225,6 +225,13 @@ ElfReader::Result ElfReader::parse(const char *dataStart, quint64 fdlen,
section.index = strtab.name;
section.offset = strtab.offset;
section.size = strtab.size;
if (section.name == ".gdb_index")
sections->symbolsType = FastSymbols;
else if (section.name == ".debug_info")
sections->symbolsType = PlainSymbols;
else if (section.name == ".gnu_debuglink")
sections->symbolsType = SeparateSymbols;
sections->sections.append(section);
}
s += e_shentsize;
......
......@@ -48,11 +48,22 @@
#include "utils_global.h"
#include <qendian.h>
#include <qlist.h>
#include <qstring.h>
namespace Utils {
class ElfSectionHeader;
class ElfSections;
enum DebugSymbolsType
{
UnknownSymbols, // Unknown.
NoSymbols, // No usable symbols.
SeparateSymbols, // Symbols mentioned, but not in binary.
PlainSymbols, // Ordinary symbols available.
FastSymbols // Dwarf index available.
};
class QTCREATOR_UTILS_EXPORT ElfSection
{
......@@ -64,8 +75,6 @@ public:
quint64 size;
};
typedef QList<ElfSection> ElfSections;
class QTCREATOR_UTILS_EXPORT ElfReader
{
public:
......@@ -86,6 +95,15 @@ private:
ElfEndian m_endian;
};
class QTCREATOR_UTILS_EXPORT ElfSections
{
public:
ElfSections() : symbolsType(UnknownSymbols) {}
QList<ElfSection> sections;
DebugSymbolsType symbolsType;
};
} // namespace Utils
#endif // UTILS_ELFREADER_H
......@@ -106,6 +106,7 @@
#include <ctype.h>
using namespace ProjectExplorer;
using namespace Utils;
namespace Debugger {
namespace Internal {
......@@ -499,8 +500,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
module.hostPath = _(result.findChild("host-name").data());
module.modulePath = _(result.findChild("target-name").data());
module.moduleName = QFileInfo(module.hostPath).baseName();
examineModule(&module);
modulesHandler()->addModule(module);
modulesHandler()->updateModule(module);
} else if (asyncClass == "library-unloaded") {
// Archer has 'id="/usr/lib/libdrm.so.2",
// target-name="/usr/lib/libdrm.so.2",
......@@ -730,7 +730,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
Task task(Task::Warning,
tr("Missing debug information for %1\nTry: %2")
.arg(m_lastMissingDebugInfo).arg(cmd),
Utils::FileName(), 0, Core::Id("Debuginfo"));
FileName(), 0, Core::Id("Debuginfo"));
taskHub()->addTask(task);
......@@ -3479,7 +3479,6 @@ void GdbEngine::handleModulesList(const GdbResponse &response)
module.moduleName = nameFromPath(module.modulePath);
module.symbolsRead =
(symbolsRead == QLatin1String("Yes") ? Module::ReadOk : Module::ReadFailed);
examineModule(&module);
handler->updateModule(module);
found = true;
} else if (line.trimmed().startsWith(QLatin1String("No"))) {
......@@ -3490,7 +3489,6 @@ void GdbEngine::handleModulesList(const GdbResponse &response)
module.endAddress = 0;
module.modulePath = ts.readLine().trimmed();
module.moduleName = nameFromPath(module.modulePath);
examineModule(&module);
handler->updateModule(module);
found = true;
}
......@@ -3510,44 +3508,18 @@ void GdbEngine::handleModulesList(const GdbResponse &response)
module.startAddress =
item.findChild("loaded_addr").data().toULongLong(0, 0);
module.endAddress = 0; // FIXME: End address not easily available.
examineModule(&module);
handler->updateModule(module);
}
}
}
}
void GdbEngine::examineModule(Module *module)
{
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()
{
ModulesHandler *handler = modulesHandler();
foreach (Module module, handler->modules()) {
if (module.symbolsType == Module::UnknownSymbols) {
examineModule(&module);
modulesHandler()->updateModule(module);
}
if (module.sections.symbolsType == UnknownSymbols)
handler->updateModule(module);
}
}
......@@ -5038,7 +5010,7 @@ void GdbEngine::handleAdapterStarted()
module.endAddress = 0;
module.modulePath = startParameters().executable;
module.moduleName = QLatin1String("<executable>");
modulesHandler()->addModule(module);
modulesHandler()->updateModule(module);
}
void GdbEngine::setupInferior()
......@@ -5380,7 +5352,6 @@ bool GdbEngine::attemptQuickStart() const
void GdbEngine::checkForReleaseBuild()
{
using namespace Utils;
QString binary = startParameters().executable;
ElfReader reader(binary);
ElfSections sections = reader.sections();
......@@ -5404,7 +5375,7 @@ void GdbEngine::checkForReleaseBuild()
}
QSet<QByteArray> seen;
foreach (const ElfSection &section, sections) {
foreach (const ElfSection &section, sections.sections) {
msg.append(section.name);
msg.append(' ');
if (interesting.contains(section.name))
......@@ -5417,12 +5388,12 @@ void GdbEngine::checkForReleaseBuild()
return;
}
if (sections.isEmpty()) {
if (sections.sections.isEmpty()) {
showMessage(_("NO SECTION HEADERS FOUND. IS THIS AN EXECUTABLE?"));
return;
}
foreach (const ElfSection &section, sections) {
foreach (const ElfSection &section, sections.sections) {
if (section.name == ".debug_info")
return;
}
......
......@@ -514,7 +514,6 @@ private: ////////// View & Data Stuff //////////
void requestModuleSymbols(const QString &moduleName);
void reloadModules();
void examineModules();
void examineModule(Module *module);
void reloadModulesInternal();
void handleModulesList(const GdbResponse &response);
void handleShowModuleSymbols(const GdbResponse &response);
......
......@@ -32,11 +32,13 @@
#include "moduleshandler.h"
#include <utils/elfreader.h>
#include <utils/qtcassert.h>
#include <QDebug>
#include <QSortFilterProxyModel>
using namespace Utils;
//////////////////////////////////////////////////////////////////
//
......@@ -65,7 +67,6 @@ public:
QVariant data(const QModelIndex &index, int role) const;
void clearModel();
void addModule(const Module &module);
void removeModule(const QString &modulePath);
void setModules(const Modules &modules);
void updateModule(const Module &module);
......@@ -123,41 +124,41 @@ QVariant ModulesModel::data(const QModelIndex &index, int role) const
break;
case 3:
if (role == Qt::DisplayRole)
switch (module.symbolsType) {
case Module::UnknownSymbols:
switch (module.sections.symbolsType) {
case UnknownSymbols:
return ModulesHandler::tr("unknown");
case Module::NoSymbols:
case NoSymbols:
return ModulesHandler::tr("none");
case Module::PlainSymbols:
case PlainSymbols:
return ModulesHandler::tr("plain");
case Module::FastSymbols:
case FastSymbols:
return ModulesHandler::tr("fast");
case Module::SeparateSymbols:
case SeparateSymbols:
return ModulesHandler::tr("separate");
}
else if (role == Qt::ToolTipRole)
switch (module.symbolsType) {
case Module::UnknownSymbols:
switch (module.sections.symbolsType) {
case UnknownSymbols:
return ModulesHandler::tr(
"It is unknown whether this module contains debug "
"information.\nUse \"Examine Symbols\" from the "
"context menu to initiate a check.");
case Module::NoSymbols:
case NoSymbols:
return ModulesHandler::tr(
"This module neither contains nor references debug "
"information.\nStepping into the module or setting "
"breakpoints by file and line will not work.");
case Module::PlainSymbols:
case PlainSymbols:
return ModulesHandler::tr(
"This module contains debug information.\nStepping "
"into the module or setting breakpoints by file and "
"is expected to work.");
case Module::FastSymbols:
case FastSymbols:
return ModulesHandler::tr(
"This module contains debug information.\nStepping "
"into the module or setting breakpoints by file and "
"is expected to work.");
case Module::SeparateSymbols:
case SeparateSymbols:
return ModulesHandler::tr(
"This module does not contains debug information "
"itself, but contains a reference to external "
......@@ -183,13 +184,6 @@ QVariant ModulesModel::data(const QModelIndex &index, int role) const
return QVariant();
}
void ModulesModel::addModule(const Module &m)
{
beginInsertRows(QModelIndex(), m_modules.size(), m_modules.size());
m_modules.push_back(m);
endInsertRows();
}
void ModulesModel::setModules(const Modules &m)
{
m_modules = m;
......@@ -225,10 +219,17 @@ void ModulesModel::removeModule(const QString &modulePath)
void ModulesModel::updateModule(const Module &module)
{
const int row = indexOfModule(module.modulePath);
ElfReader reader(module.modulePath);
ElfSections sections = reader.sections();
if (row == -1) {
addModule(module);
const int n = m_modules.size();
beginInsertRows(QModelIndex(), n, n);
m_modules.push_back(module);
m_modules.back().sections = sections;
endInsertRows();
} else {
m_modules[row] = module;
m_modules[row].sections = sections;
dataChanged(index(row, 0, QModelIndex()), index(row, 4, QModelIndex()));
}
}
......@@ -256,11 +257,6 @@ void ModulesHandler::removeAll()
m_model->clearModel();
}
void ModulesHandler::addModule(const Module &module)
{
m_model->addModule(module);
}
void ModulesHandler::removeModule(const QString &modulePath)
{
m_model->removeModule(modulePath);
......
......@@ -33,6 +33,8 @@
#ifndef DEBUGGER_MODULESHANDLER_H
#define DEBUGGER_MODULESHANDLER_H
#include <utils/elfreader.h>
#include <QObject>
#include <QVector>
......@@ -73,7 +75,7 @@ typedef QVector<Symbol> Symbols;
class Module
{
public:
Module() : symbolsRead(UnknownReadState), symbolsType(UnknownSymbols) {}
Module() : symbolsRead(UnknownReadState) {}
public:
enum SymbolReadState {
......@@ -81,20 +83,14 @@ public:
ReadFailed, // Tried to read, but failed.
ReadOk // Dwarf index available.
};
enum SymbolType {
UnknownSymbols, // Unknown.
NoSymbols, // No usable symbols.
SeparateSymbols, // Symbols mentioned, but not in binary.
PlainSymbols, // Ordinary symbols available.
FastSymbols // Dwarf index available.
};
QString moduleName;
QString modulePath;
QString hostPath;
SymbolReadState symbolsRead;
SymbolType symbolsType;
quint64 startAddress;
quint64 endAddress;
Utils::ElfSections sections;
};
typedef QVector<Module> Modules;
......@@ -116,7 +112,6 @@ public:
QAbstractItemModel *model() const;
void setModules(const Modules &modules);
void addModule(const Module &module);
void removeModule(const QString &modulePath);
void updateModule(const Module &module);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment