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/QTextStream>
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
@@ -544,6 +545,83 @@ QVector<QByteArray> gdbStartupSequence()
|
||||
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
|
||||
|
||||
// Generic gdb server helpers: Read address/length off a memory
|
||||
|
||||
@@ -197,6 +197,16 @@ extern const char *gdbArchitectureXml;
|
||||
|
||||
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
|
||||
|
||||
// Generic gdb server helpers: read 'm','X' commands.
|
||||
|
||||
@@ -211,6 +211,16 @@ void TcfTrkGdbAdapter::handleTcfTrkRunControlModuleLoadContextSuspendedEvent(con
|
||||
library.dataseg = minfo.dataAddress;
|
||||
library.pid = RunControlContext::processIdFromTcdfId(se.id());
|
||||
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 {
|
||||
const int index = m_session.modules.indexOf(moduleName);
|
||||
if (index != -1) {
|
||||
@@ -974,6 +984,8 @@ void TcfTrkGdbAdapter::startAdapter()
|
||||
m_remoteExecutable = parameters.executable;
|
||||
m_remoteArguments = Utils::QtcProcess::splitArgs(parameters.processArgs);
|
||||
m_symbolFile = parameters.symbolFileName;
|
||||
if (!m_symbolFile.isEmpty())
|
||||
m_symbolFileFolder = QFileInfo(m_symbolFile).absolutePath();
|
||||
|
||||
QPair<QString, unsigned short> tcfTrkAddress;
|
||||
|
||||
|
||||
@@ -178,6 +178,7 @@ private:
|
||||
unsigned m_uid;
|
||||
QStringList m_remoteArguments;
|
||||
QString m_symbolFile;
|
||||
QString m_symbolFileFolder;
|
||||
int m_verbose;
|
||||
bool m_bufferedMemoryRead;
|
||||
bool m_firstResumableExeLoadedEvent;
|
||||
|
||||
@@ -1041,6 +1041,15 @@ void TrkGdbAdapter::handleTrkResult(const TrkResult &result)
|
||||
if (tid && tid != unsigned(-1) && m_snapshot.indexOfThread(tid) == -1)
|
||||
m_snapshot.addThread(tid);
|
||||
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.
|
||||
// With CS gdb 6.4 we get a non-standard $qfDllInfo#7f+ request
|
||||
// afterwards, so don't use it for now.
|
||||
@@ -1550,6 +1559,8 @@ void TrkGdbAdapter::startAdapter()
|
||||
m_remoteExecutable = parameters.executable;
|
||||
m_remoteArguments = parameters.processArgs;
|
||||
m_symbolFile = parameters.symbolFileName;
|
||||
if (!m_symbolFile.isEmpty())
|
||||
m_symbolFileFolder = QFileInfo(m_symbolFile).absolutePath();
|
||||
QString remoteChannel = parameters.remoteChannel;
|
||||
// FIXME: testing hack, remove!
|
||||
if (m_remoteArguments.startsWith(__("@sym@ "))) {
|
||||
|
||||
@@ -226,6 +226,7 @@ private:
|
||||
QString m_remoteExecutable;
|
||||
QString m_remoteArguments;
|
||||
QString m_symbolFile;
|
||||
QString m_symbolFileFolder;
|
||||
int m_verbose;
|
||||
bool m_bufferedMemoryRead;
|
||||
LocalGdbProcess m_gdbProc;
|
||||
|
||||
Reference in New Issue
Block a user