From e8e4ce9728794abfe6f1f15fc1a6e3d5a098ce24 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 2 Dec 2010 14:07:53 +0100 Subject: [PATCH] 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 . 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 --- src/plugins/debugger/gdb/symbian.cpp | 78 +++++++++++++++++++ src/plugins/debugger/gdb/symbian.h | 10 +++ src/plugins/debugger/gdb/tcftrkgdbadapter.cpp | 12 +++ src/plugins/debugger/gdb/tcftrkgdbadapter.h | 1 + src/plugins/debugger/gdb/trkgdbadapter.cpp | 11 +++ src/plugins/debugger/gdb/trkgdbadapter.h | 1 + 6 files changed, 113 insertions(+) diff --git a/src/plugins/debugger/gdb/symbian.cpp b/src/plugins/debugger/gdb/symbian.cpp index 41935a80b5f..3ffb3228863 100644 --- a/src/plugins/debugger/gdb/symbian.cpp +++ b/src/plugins/debugger/gdb/symbian.cpp @@ -36,6 +36,7 @@ #include #include +#include namespace Debugger { namespace Internal { @@ -544,6 +545,83 @@ QVector 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 diff --git a/src/plugins/debugger/gdb/symbian.h b/src/plugins/debugger/gdb/symbian.h index ec34462e47a..a93262b9151 100644 --- a/src/plugins/debugger/gdb/symbian.h +++ b/src/plugins/debugger/gdb/symbian.h @@ -197,6 +197,16 @@ extern const char *gdbArchitectureXml; QVector 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. diff --git a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp index 2bb863ce5c2..a59a6051621 100644 --- a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp @@ -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 tcfTrkAddress; diff --git a/src/plugins/debugger/gdb/tcftrkgdbadapter.h b/src/plugins/debugger/gdb/tcftrkgdbadapter.h index 8cbb44eb2b1..e597cc09820 100644 --- a/src/plugins/debugger/gdb/tcftrkgdbadapter.h +++ b/src/plugins/debugger/gdb/tcftrkgdbadapter.h @@ -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; diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 0a1f792e092..34d44d99186 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -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@ "))) { diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h index 7c7905fbde3..699c5199766 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.h +++ b/src/plugins/debugger/gdb/trkgdbadapter.h @@ -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;