Commit e8e4ce97 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

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
parent add6996d
......@@ -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;
......
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