Commit 6841976a authored by hjk's avatar hjk

debugger: give access to the section names in a shared object

Via context menu in the modules view, gdb-only for now.

Change-Id: I1163540cd9894c52243bb1bf0c2afc881e793863
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent 6c6400b7
......@@ -167,7 +167,8 @@ enum DebuggerCapabilities
CatchCapability = 0x200000, //!< fork, vfork, syscall
OperateByInstructionCapability = 0x400000,
RunToLineCapability = 0x800000,
MemoryAddressCapability = 0x1000000
MemoryAddressCapability = 0x1000000,
ShowModuleSectionsCapability = 0x200000
};
enum LogChannel
......
......@@ -64,6 +64,7 @@ namespace Internal {
class BreakHandler;
class SnapshotHandler;
class Symbol;
class Section;
class DebuggerToolTipManager;
class GlobalDebuggerOptions;
......@@ -113,6 +114,8 @@ public:
// DebuggerEngineType et = NoEngineType) const = 0;
virtual void showModuleSymbols(const QString &moduleName,
const QVector<Symbol> &symbols) = 0;
virtual void showModuleSections(const QString &moduleName,
const QVector<Section> &sections) = 0;
virtual void openMemoryEditor() = 0;
virtual void languagesChanged() = 0;
virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages) = 0;
......
......@@ -1451,6 +1451,10 @@ void DebuggerEngine::requestModuleSymbols(const QString &)
{
}
void DebuggerEngine::requestModuleSections(const QString &)
{
}
void DebuggerEngine::reloadRegisters()
{
}
......
......@@ -179,6 +179,7 @@ public:
virtual void loadSymbolsForStack();
virtual void loadAllSymbols();
virtual void requestModuleSymbols(const QString &moduleName);
virtual void requestModuleSections(const QString &moduleName);
virtual void reloadRegisters();
virtual void reloadSourceFiles();
......
......@@ -1220,6 +1220,7 @@ public slots:
QString stringSetting(int code) const;
void showModuleSymbols(const QString &moduleName, const Symbols &symbols);
void showModuleSections(const QString &moduleName, const Sections &sections);
bool parseArgument(QStringList::const_iterator &it,
const QStringList::const_iterator &cend, QString *errorMessage);
......@@ -3327,6 +3328,36 @@ void DebuggerPluginPrivate::showModuleSymbols(const QString &moduleName,
createNewDock(w);
}
void DebuggerPluginPrivate::showModuleSections(const QString &moduleName,
const Sections &sections)
{
QTreeWidget *w = new QTreeWidget;
w->setUniformRowHeights(true);
w->setColumnCount(5);
w->setRootIsDecorated(false);
w->setAlternatingRowColors(true);
w->setSortingEnabled(true);
w->setObjectName(QLatin1String("Sections.") + moduleName);
QStringList header;
header.append(tr("Name"));
header.append(tr("From"));
header.append(tr("To"));
header.append(tr("Address"));
header.append(tr("Flags"));
w->setHeaderLabels(header);
w->setWindowTitle(tr("Sections in \"%1\"").arg(moduleName));
foreach (const Section &s, sections) {
QTreeWidgetItem *it = new QTreeWidgetItem;
it->setData(0, Qt::DisplayRole, s.name);
it->setData(1, Qt::DisplayRole, s.from);
it->setData(2, Qt::DisplayRole, s.to);
it->setData(3, Qt::DisplayRole, s.address);
it->setData(4, Qt::DisplayRole, s.flags);
w->addTopLevelItem(it);
}
createNewDock(w);
}
void DebuggerPluginPrivate::aboutToShutdown()
{
m_plugin->removeObject(this);
......
......@@ -2128,6 +2128,7 @@ bool GdbEngine::hasCapability(unsigned cap) const
| AddWatcherCapability
| WatchWidgetsCapability
| ShowModuleSymbolsCapability
| ShowModuleSectionsCapability
| CatchCapability
| OperateByInstructionCapability
| RunToLineCapability
......@@ -3325,7 +3326,7 @@ void GdbEngine::handleShowModuleSymbols(const GdbResponse &response)
const QString modulePath = cookie.section(QLatin1Char('@'), 0, 0);
const QString fileName = cookie.section(QLatin1Char('@'), 1, 1);
if (response.resultClass == GdbResultDone) {
Symbols rc;
Symbols symbols;
QFile file(fileName);
file.open(QIODevice::ReadOnly);
// Object file /opt/dev/qt/lib/libQtNetworkMyns.so.4:
......@@ -3369,17 +3370,62 @@ void GdbEngine::handleShowModuleSymbols(const GdbResponse &response)
symbol.name = _(line.mid(posName, lenName));
symbol.section = _(line.mid(posSection, lenSection));
symbol.demangled = _(line.mid(posDemangled, lenDemangled));
rc.push_back(symbol);
symbols.push_back(symbol);
}
file.close();
file.remove();
debuggerCore()->showModuleSymbols(modulePath, rc);
debuggerCore()->showModuleSymbols(modulePath, symbols);
} else {
showMessageBox(QMessageBox::Critical, tr("Cannot Read Symbols"),
tr("Cannot read symbols for module \"%1\".").arg(fileName));
}
}
void GdbEngine::requestModuleSections(const QString &moduleName)
{
// There seems to be no way to get the symbols from a single .so.
postCommand("maint info section ALLOBJ",
NeedsStop, CB(handleShowModuleSections), moduleName);
}
void GdbEngine::handleShowModuleSections(const GdbResponse &response)
{
// ~" Object file: /usr/lib/i386-linux-gnu/libffi.so.6\n"
// ~" 0xb44a6114->0xb44a6138 at 0x00000114: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS\n"
if (response.resultClass == GdbResultDone) {
const QString moduleName = response.cookie.toString();
const QStringList lines = QString::fromLocal8Bit(response.consoleStreamOutput).split(QLatin1Char('\n'));
const QString prefix = QLatin1String(" Object file: ");
const QString needle = prefix + moduleName;
Sections sections;
bool active = false;
foreach (const QString &line, lines) {
if (line.startsWith(prefix)) {
if (active)
break;
if (line == needle)
active = true;
} else {
if (active) {
QStringList items = line.split(QLatin1Char(' '), QString::SkipEmptyParts);
QString fromTo = items.value(0, QString());
const int pos = fromTo.indexOf(QLatin1Char('-'));
QTC_ASSERT(pos >= 0, continue);
Section section;
section.from = fromTo.left(pos);
section.to = fromTo.mid(pos + 2);
section.address = items.value(2, QString());
section.name = items.value(3, QString());
section.flags = items.value(4, QString());
sections.append(section);
}
}
}
if (!sections.isEmpty())
debuggerCore()->showModuleSections(moduleName, sections);
}
}
void GdbEngine::reloadModules()
{
if (state() == InferiorRunOk || state() == InferiorStopOk)
......
......@@ -476,11 +476,13 @@ private: ////////// View & Data Stuff //////////
Q_SLOT void loadAllSymbols();
void loadSymbolsForStack();
void requestModuleSymbols(const QString &moduleName);
void requestModuleSections(const QString &moduleName);
void reloadModules();
void examineModules();
void reloadModulesInternal();
void handleModulesList(const GdbResponse &response);
void handleShowModuleSymbols(const GdbResponse &response);
void handleShowModuleSections(const GdbResponse &response);
//
// Snapshot specific stuff
......
......@@ -66,6 +66,24 @@ public:
typedef QVector<Symbol> Symbols;
//////////////////////////////////////////////////////////////////
//
// Section
//
//////////////////////////////////////////////////////////////////
class Section
{
public:
QString from;
QString to;
QString address;
QString name;
QString flags;
};
typedef QVector<Section> Sections;
//////////////////////////////////////////////////////////////////
//
// Module
......
......@@ -112,6 +112,7 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev)
QAction *actLoadSymbolsForModule = 0;
QAction *actEditFile = 0;
QAction *actShowModuleSymbols = 0;
QAction *actShowModuleSections = 0;
QAction *actShowDependencies = 0; // Show dependencies by running 'depends.exe'
if (name.isEmpty()) {
actLoadSymbolsForModule = new QAction(tr("Load Symbols for Module"), &menu);
......@@ -120,6 +121,8 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev)
actEditFile->setEnabled(false);
actShowModuleSymbols = new QAction(tr("Show Symbols"), &menu);
actShowModuleSymbols->setEnabled(false);
actShowModuleSections = new QAction(tr("Show Sections"), &menu);
actShowModuleSections->setEnabled(false);
actShowDependencies = new QAction(tr("Show Dependencies"), &menu);
actShowDependencies->setEnabled(false);
} else {
......@@ -131,6 +134,9 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev)
actShowModuleSymbols
= new QAction(tr("Show Symbols in File \"%1\"").arg(name), &menu);
actShowModuleSymbols->setEnabled(engine->hasCapability(ShowModuleSymbolsCapability));
actShowModuleSections
= new QAction(tr("Show Sections in File \"%1\"").arg(name), &menu);
actShowModuleSections->setEnabled(engine->hasCapability(ShowModuleSymbolsCapability));
actShowDependencies = new QAction(tr("Show Dependencies of \"%1\"").arg(name), &menu);
actShowDependencies->setEnabled(!fileName.isEmpty());
if (!Utils::HostOsInfo::isWindowsHost())
......@@ -146,6 +152,7 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev)
menu.addAction(actLoadSymbolsForModule);
menu.addAction(actEditFile);
menu.addAction(actShowModuleSymbols);
menu.addAction(actShowModuleSections);
addBaseContextActions(&menu);
QAction *act = menu.exec(ev->globalPos());
......@@ -164,6 +171,8 @@ void ModulesTreeView::contextMenuEvent(QContextMenuEvent *ev)
engine->gotoLocation(fileName);
else if (act == actShowModuleSymbols)
engine->requestModuleSymbols(fileName);
else if (act == actShowModuleSections)
engine->requestModuleSections(fileName);
else if (actShowDependencies && act == actShowDependencies)
QProcess::startDetached(QLatin1String("depends"), QStringList(fileName));
else
......
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