forked from qt-creator/qt-creator
Debugger: Add infrastructure for loading Symbian .sym files.
Add local symbol files for libraries to gdb along with section addresses using the command add-symbol-file <file> <address[es]>. Whenever TRK reports a module load, check for a matching local .sym file in a folder pointed to by the QTC_SYMBIAN_SYMBOLFILE_CACHE environment variable or the folder of the application executable symbol file (which should be udeb/urel of EPOC). Rubber-stamped-by: hjk
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QTextStream>
|
#include <QtCore/QTextStream>
|
||||||
|
#include <QtCore/QFileInfo>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -544,6 +545,83 @@ QVector<QByteArray> gdbStartupSequence()
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Local symbol file handling
|
||||||
|
|
||||||
|
enum { symDebug = 0 };
|
||||||
|
|
||||||
|
// Build complete file name of a local sym file from DLL
|
||||||
|
// 'QtCore.dll' to 'c:\\foo\QtCore.dll.sym'.
|
||||||
|
|
||||||
|
static inline QString symFileName(const QString &folder,
|
||||||
|
const QString &libName)
|
||||||
|
{
|
||||||
|
QString fileName = folder;
|
||||||
|
fileName.append(QLatin1Char('/'));
|
||||||
|
fileName.append(libName);
|
||||||
|
fileName.append(QLatin1String(".sym"));
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look up in local symbol file matching remote library loaded in
|
||||||
|
// cache pointed to by environmentname or in standard location
|
||||||
|
// (next to application.sym file).
|
||||||
|
QString localSymFileForLibrary(const QByteArray &libName,
|
||||||
|
// urel/udeb: exe directory
|
||||||
|
const QString &standardSymDirectory)
|
||||||
|
{
|
||||||
|
// Check
|
||||||
|
const QByteArray envSymFileCacheDirectory = qgetenv("QTC_SYMBIAN_SYMBOLFILE_CACHE");
|
||||||
|
if (envSymFileCacheDirectory.isEmpty() && standardSymDirectory.isEmpty())
|
||||||
|
return QString();
|
||||||
|
// Base name
|
||||||
|
int lastSlashPos = libName.lastIndexOf('/');
|
||||||
|
if (lastSlashPos == -1)
|
||||||
|
lastSlashPos = libName.lastIndexOf('\\');
|
||||||
|
const QString libBaseName = QString::fromLatin1(lastSlashPos != - 1 ? libName.mid(lastSlashPos + 1) : libName);
|
||||||
|
// Check environment variable
|
||||||
|
if (!envSymFileCacheDirectory.isEmpty()) {
|
||||||
|
const QFileInfo envFi(symFileName(QString::fromLatin1(envSymFileCacheDirectory), libBaseName));
|
||||||
|
if (symDebug)
|
||||||
|
qDebug("SYM-ENV: %s exists %d\n", qPrintable(envFi.absoluteFilePath()), envFi.isFile());
|
||||||
|
if (envFi.isFile())
|
||||||
|
return envFi.absoluteFilePath();
|
||||||
|
}
|
||||||
|
// Check standard location
|
||||||
|
if (!standardSymDirectory.isEmpty()) {
|
||||||
|
const QFileInfo standardFi(symFileName(standardSymDirectory, libBaseName));
|
||||||
|
if (symDebug)
|
||||||
|
qDebug("SYM-STANDARD: %s exists %d\n", qPrintable(standardFi.absoluteFilePath()), standardFi.isFile());
|
||||||
|
if (standardFi.isFile())
|
||||||
|
return standardFi.absoluteFilePath();
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a load command for a local symbol file for a library with address.
|
||||||
|
QByteArray symFileLoadCommand(const QString &symFileNameIn,
|
||||||
|
quint64 code, quint64 data)
|
||||||
|
{
|
||||||
|
QByteArray symFileName = symFileNameIn.toLatin1();
|
||||||
|
symFileName.replace('\\', '/'); // gdb wants forward slashes
|
||||||
|
QByteArray command = "add-symbol-file \"";
|
||||||
|
command += symFileName;
|
||||||
|
command += "\" 0x";
|
||||||
|
command += QByteArray::number(code, 16);
|
||||||
|
if (data) {
|
||||||
|
command += " -s .data 0x";
|
||||||
|
command += QByteArray::number(data, 16);
|
||||||
|
}
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString msgLoadLocalSymFile(const QString &symFileName,
|
||||||
|
const QByteArray &libName, quint64 code)
|
||||||
|
{
|
||||||
|
return QString::fromAscii("Loading symbol file '%1' for '%2' at 0x%3").
|
||||||
|
arg(symFileName, QString::fromLatin1(libName)).
|
||||||
|
arg(code, 0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Symbian
|
} // namespace Symbian
|
||||||
|
|
||||||
// Generic gdb server helpers: Read address/length off a memory
|
// Generic gdb server helpers: Read address/length off a memory
|
||||||
|
|||||||
@@ -197,6 +197,16 @@ extern const char *gdbArchitectureXml;
|
|||||||
|
|
||||||
QVector<QByteArray> gdbStartupSequence();
|
QVector<QByteArray> gdbStartupSequence();
|
||||||
|
|
||||||
|
// Look up in symbol file matching library name in local cache
|
||||||
|
QString localSymFileForLibrary(const QByteArray &libName,
|
||||||
|
const QString &standardSymDirectory = QString());
|
||||||
|
// Return a load command for a local symbol file for a library
|
||||||
|
QByteArray symFileLoadCommand(const QString &symFileName, quint64 code,
|
||||||
|
quint64 data = 0);
|
||||||
|
// Utility message
|
||||||
|
QString msgLoadLocalSymFile(const QString &symFileName,
|
||||||
|
const QByteArray &libName, quint64 code);
|
||||||
|
|
||||||
} // namespace Symbian
|
} // namespace Symbian
|
||||||
|
|
||||||
// Generic gdb server helpers: read 'm','X' commands.
|
// Generic gdb server helpers: read 'm','X' commands.
|
||||||
|
|||||||
@@ -211,6 +211,16 @@ void TcfTrkGdbAdapter::handleTcfTrkRunControlModuleLoadContextSuspendedEvent(con
|
|||||||
library.dataseg = minfo.dataAddress;
|
library.dataseg = minfo.dataAddress;
|
||||||
library.pid = RunControlContext::processIdFromTcdfId(se.id());
|
library.pid = RunControlContext::processIdFromTcdfId(se.id());
|
||||||
m_session.libraries.push_back(library);
|
m_session.libraries.push_back(library);
|
||||||
|
// Load local symbol file into gdb provided there is one
|
||||||
|
if (library.codeseg) {
|
||||||
|
const QString localSymFileName = Symbian::localSymFileForLibrary(library.name,
|
||||||
|
m_symbolFileFolder);
|
||||||
|
if (!localSymFileName.isEmpty()) {
|
||||||
|
showMessage(Symbian::msgLoadLocalSymFile(localSymFileName, library.name, library.codeseg), LogMisc);
|
||||||
|
m_engine->postCommand(Symbian::symFileLoadCommand(localSymFileName, library.codeseg, library.dataseg));
|
||||||
|
} // has local sym
|
||||||
|
} // code seg
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const int index = m_session.modules.indexOf(moduleName);
|
const int index = m_session.modules.indexOf(moduleName);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
@@ -974,6 +984,8 @@ void TcfTrkGdbAdapter::startAdapter()
|
|||||||
m_remoteExecutable = parameters.executable;
|
m_remoteExecutable = parameters.executable;
|
||||||
m_remoteArguments = Utils::QtcProcess::splitArgs(parameters.processArgs);
|
m_remoteArguments = Utils::QtcProcess::splitArgs(parameters.processArgs);
|
||||||
m_symbolFile = parameters.symbolFileName;
|
m_symbolFile = parameters.symbolFileName;
|
||||||
|
if (!m_symbolFile.isEmpty())
|
||||||
|
m_symbolFileFolder = QFileInfo(m_symbolFile).absolutePath();
|
||||||
|
|
||||||
QPair<QString, unsigned short> tcfTrkAddress;
|
QPair<QString, unsigned short> tcfTrkAddress;
|
||||||
|
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ private:
|
|||||||
unsigned m_uid;
|
unsigned m_uid;
|
||||||
QStringList m_remoteArguments;
|
QStringList m_remoteArguments;
|
||||||
QString m_symbolFile;
|
QString m_symbolFile;
|
||||||
|
QString m_symbolFileFolder;
|
||||||
int m_verbose;
|
int m_verbose;
|
||||||
bool m_bufferedMemoryRead;
|
bool m_bufferedMemoryRead;
|
||||||
bool m_firstResumableExeLoadedEvent;
|
bool m_firstResumableExeLoadedEvent;
|
||||||
|
|||||||
@@ -1041,6 +1041,15 @@ void TrkGdbAdapter::handleTrkResult(const TrkResult &result)
|
|||||||
if (tid && tid != unsigned(-1) && m_snapshot.indexOfThread(tid) == -1)
|
if (tid && tid != unsigned(-1) && m_snapshot.indexOfThread(tid) == -1)
|
||||||
m_snapshot.addThread(tid);
|
m_snapshot.addThread(tid);
|
||||||
logMessage(logMsg);
|
logMessage(logMsg);
|
||||||
|
// Load local symbol file into gdb provided there is one
|
||||||
|
if (lib.codeseg) {
|
||||||
|
const QString localSymFileName = Symbian::localSymFileForLibrary(lib.name, m_symbolFileFolder);
|
||||||
|
if (!localSymFileName.isEmpty()) {
|
||||||
|
showMessage(Symbian::msgLoadLocalSymFile(localSymFileName, lib.name, lib.codeseg), LogMisc);
|
||||||
|
m_engine->postCommand(Symbian::symFileLoadCommand(localSymFileName, lib.codeseg, lib.dataseg));
|
||||||
|
} // has local sym
|
||||||
|
} // code seg
|
||||||
|
|
||||||
// This lets gdb trigger a register update etc.
|
// This lets gdb trigger a register update etc.
|
||||||
// With CS gdb 6.4 we get a non-standard $qfDllInfo#7f+ request
|
// With CS gdb 6.4 we get a non-standard $qfDllInfo#7f+ request
|
||||||
// afterwards, so don't use it for now.
|
// afterwards, so don't use it for now.
|
||||||
@@ -1550,6 +1559,8 @@ void TrkGdbAdapter::startAdapter()
|
|||||||
m_remoteExecutable = parameters.executable;
|
m_remoteExecutable = parameters.executable;
|
||||||
m_remoteArguments = parameters.processArgs;
|
m_remoteArguments = parameters.processArgs;
|
||||||
m_symbolFile = parameters.symbolFileName;
|
m_symbolFile = parameters.symbolFileName;
|
||||||
|
if (!m_symbolFile.isEmpty())
|
||||||
|
m_symbolFileFolder = QFileInfo(m_symbolFile).absolutePath();
|
||||||
QString remoteChannel = parameters.remoteChannel;
|
QString remoteChannel = parameters.remoteChannel;
|
||||||
// FIXME: testing hack, remove!
|
// FIXME: testing hack, remove!
|
||||||
if (m_remoteArguments.startsWith(__("@sym@ "))) {
|
if (m_remoteArguments.startsWith(__("@sym@ "))) {
|
||||||
|
|||||||
@@ -226,6 +226,7 @@ private:
|
|||||||
QString m_remoteExecutable;
|
QString m_remoteExecutable;
|
||||||
QString m_remoteArguments;
|
QString m_remoteArguments;
|
||||||
QString m_symbolFile;
|
QString m_symbolFile;
|
||||||
|
QString m_symbolFileFolder;
|
||||||
int m_verbose;
|
int m_verbose;
|
||||||
bool m_bufferedMemoryRead;
|
bool m_bufferedMemoryRead;
|
||||||
LocalGdbProcess m_gdbProc;
|
LocalGdbProcess m_gdbProc;
|
||||||
|
|||||||
Reference in New Issue
Block a user