DBG+BRIDGE+GUI: fix source loading
This commit is contained in:
parent
b63402066b
commit
8c169ae2ed
|
@ -1461,9 +1461,14 @@ BRIDGE_IMPEXP void GuiUpdateSEHChain()
|
|||
_gui_sendmessage(GUI_UPDATE_SEHCHAIN, 0, 0);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiLoadSourceFile(const char* path, int line)
|
||||
extern "C" __declspec(dllexport) void GuiLoadSourceFile(const char* path, int line)
|
||||
{
|
||||
_gui_sendmessage(GUI_LOAD_SOURCE_FILE, (void*)path, (void*)line);
|
||||
return;
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiLoadSourceFileEx(const char* path, duint addr)
|
||||
{
|
||||
_gui_sendmessage(GUI_LOAD_SOURCE_FILE, (void*)path, (void*)addr);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiMenuSetIcon(int hMenu, const ICONDATA* icon)
|
||||
|
|
|
@ -1108,7 +1108,7 @@ typedef enum
|
|||
GUI_SYMBOL_REFRESH_CURRENT, // param1=unused, param2=unused
|
||||
GUI_UPDATE_MEMORY_VIEW, // param1=unused, param2=unused
|
||||
GUI_REF_INITIALIZE, // param1=const char* name, param2=unused
|
||||
GUI_LOAD_SOURCE_FILE, // param1=const char* path, param2=line
|
||||
GUI_LOAD_SOURCE_FILE, // param1=const char* path, param2=duint addr
|
||||
GUI_MENU_SET_ICON, // param1=int hMenu, param2=ICONINFO*
|
||||
GUI_MENU_SET_ENTRY_ICON, // param1=int hEntry, param2=ICONINFO*
|
||||
GUI_SHOW_CPU, // param1=unused, param2=unused
|
||||
|
@ -1285,7 +1285,7 @@ BRIDGE_IMPEXP void GuiRepaintTableView();
|
|||
BRIDGE_IMPEXP void GuiUpdatePatches();
|
||||
BRIDGE_IMPEXP void GuiUpdateCallStack();
|
||||
BRIDGE_IMPEXP void GuiUpdateSEHChain();
|
||||
BRIDGE_IMPEXP void GuiLoadSourceFile(const char* path, int line);
|
||||
BRIDGE_IMPEXP void GuiLoadSourceFileEx(const char* path, duint addr);
|
||||
BRIDGE_IMPEXP void GuiMenuSetIcon(int hMenu, const ICONDATA* icon);
|
||||
BRIDGE_IMPEXP void GuiMenuSetEntryIcon(int hEntry, const ICONDATA* icon);
|
||||
BRIDGE_IMPEXP void GuiMenuSetEntryChecked(int hEntry, bool checked);
|
||||
|
|
|
@ -197,15 +197,17 @@ static void _memupdatemap()
|
|||
|
||||
static duint _getaddrfromline(const char* szSourceFile, int line, duint* disp)
|
||||
{
|
||||
LONG displacement = 0;
|
||||
IMAGEHLP_LINE64 lineData;
|
||||
memset(&lineData, 0, sizeof(lineData));
|
||||
lineData.SizeOfStruct = sizeof(lineData);
|
||||
if(!SymGetLineFromName64(fdProcessInfo->hProcess, NULL, szSourceFile, line, &displacement, &lineData))
|
||||
return 0;
|
||||
if(disp)
|
||||
*disp = displacement;
|
||||
return (duint)lineData.Address;
|
||||
*disp = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static duint _getaddrfromlineex(duint mod, const char* szSourceFile, int line)
|
||||
{
|
||||
duint addr = 0;
|
||||
if(SymGetSourceAddr(mod, szSourceFile, line, &addr))
|
||||
return addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool _getsourcefromaddr(duint addr, char* szSourceFile, int* line)
|
||||
|
@ -481,4 +483,5 @@ void dbgfunctionsinit()
|
|||
_dbgfunctions.DbGetHash = DbGetHash;
|
||||
_dbgfunctions.SymAutoComplete = SymAutoComplete;
|
||||
_dbgfunctions.RefreshModuleList = _refreshmodulelist;
|
||||
_dbgfunctions.GetAddrFromLineEx = _getaddrfromlineex;
|
||||
}
|
||||
|
|
|
@ -198,6 +198,7 @@ typedef bool(*MODRELOCATIONSINRANGE)(duint addr, duint size, ListOf(DBGRELOCATIO
|
|||
typedef duint(*DBGETHASH)();
|
||||
typedef int(*SYMAUTOCOMPLETE)(const char* Search, char** Buffer, int MaxSymbols);
|
||||
typedef void(*REFRESHMODULELIST)();
|
||||
typedef duint(*GETADDRFROMLINEEX)(duint mod, const char* szSourceFile, int line);
|
||||
|
||||
//The list of all the DbgFunctions() return value.
|
||||
//WARNING: This list is append only. Do not insert things in the middle or plugins would break.
|
||||
|
@ -274,6 +275,7 @@ typedef struct DBGFUNCTIONS_
|
|||
DBGETHASH DbGetHash;
|
||||
SYMAUTOCOMPLETE SymAutoComplete;
|
||||
REFRESHMODULELIST RefreshModuleList;
|
||||
GETADDRFROMLINEEX GetAddrFromLineEx;
|
||||
} DBGFUNCTIONS;
|
||||
|
||||
#ifdef BUILD_DBG
|
||||
|
|
|
@ -535,7 +535,7 @@ void ReadDebugDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
|
|||
|
||||
// Debug directory full path
|
||||
const bool bAllowUncPathsInDebugDirectory = false; // TODO: create setting for this
|
||||
if (!dir.empty() && (bAllowUncPathsInDebugDirectory || !PathIsUNCW(StringUtils::Utf8ToUtf16(Info.pdbFile).c_str())))
|
||||
if(!dir.empty() && (bAllowUncPathsInDebugDirectory || !PathIsUNCW(StringUtils::Utf8ToUtf16(Info.pdbFile).c_str())))
|
||||
Info.pdbPaths.push_back(Info.pdbFile);
|
||||
|
||||
// Program directory (debug directory PDB name)
|
||||
|
@ -552,7 +552,7 @@ void ReadDebugDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
|
|||
// Program directory (file name PDB name)
|
||||
strcpy_s(pdbPath, Info.path);
|
||||
lastBack = strrchr(pdbPath, '\\');
|
||||
if (lastBack)
|
||||
if(lastBack)
|
||||
{
|
||||
lastBack[1] = '\0';
|
||||
strncat_s(pdbPath, Info.name, _TRUNCATE);
|
||||
|
@ -560,7 +560,7 @@ void ReadDebugDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
|
|||
Info.pdbPaths.push_back(pdbPath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -367,3 +367,22 @@ bool SymGetSourceLine(duint Cip, char* FileName, int* Line, DWORD* disp)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SymGetSourceAddr(duint Module, const char* FileName, int Line, duint* Address)
|
||||
{
|
||||
SHARED_ACQUIRE(LockModules);
|
||||
auto modInfo = ModInfoFromAddr(Module);
|
||||
if(!modInfo)
|
||||
return false;
|
||||
|
||||
auto sym = modInfo->symbols;
|
||||
if(!sym || sym == &EmptySymbolSource)
|
||||
return false;
|
||||
|
||||
LineInfo lineInfo;
|
||||
if(!sym->findSourceLineInfo(FileName, Line, lineInfo))
|
||||
return false;
|
||||
|
||||
*Address = lineInfo.rva + modInfo->base;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -24,4 +24,6 @@ String SymGetSymbolicName(duint Address);
|
|||
*/
|
||||
bool SymGetSourceLine(duint Cip, char* FileName, int* Line, DWORD* displacement = nullptr);
|
||||
|
||||
bool SymGetSourceAddr(duint Module, const char* FileName, int Line, duint* Address);
|
||||
|
||||
#endif // _SYMBOLINFO_H
|
|
@ -490,7 +490,7 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
|||
break;
|
||||
|
||||
case GUI_LOAD_SOURCE_FILE:
|
||||
emit loadSourceFile(QString((const char*)param1), (int)param2, 0);
|
||||
emit loadSourceFile(QString((const char*)param1), (duint)param2);
|
||||
break;
|
||||
|
||||
case GUI_MENU_SET_ICON:
|
||||
|
|
|
@ -114,7 +114,7 @@ signals:
|
|||
void updateSEHChain();
|
||||
void updateArgumentView();
|
||||
void symbolRefreshCurrent();
|
||||
void loadSourceFile(const QString path, int line, int selection);
|
||||
void loadSourceFile(const QString path, duint addr);
|
||||
void setIconMenuEntry(int hEntry, QIcon icon);
|
||||
void setIconMenu(int hMenu, QIcon icon);
|
||||
void setCheckedMenuEntry(int hEntry, bool checked);
|
||||
|
|
|
@ -1748,9 +1748,10 @@ void CPUDisassembly::openSourceSlot()
|
|||
{
|
||||
char szSourceFile[MAX_STRING_SIZE] = "";
|
||||
int line = 0;
|
||||
if(!DbgFunctions()->GetSourceFromAddr(rvaToVa(getInitialSelection()), szSourceFile, &line))
|
||||
auto sel = rvaToVa(getInitialSelection());
|
||||
if(!DbgFunctions()->GetSourceFromAddr(sel, szSourceFile, &line))
|
||||
return;
|
||||
emit Bridge::getBridge()->loadSourceFile(szSourceFile, 0, line);
|
||||
emit Bridge::getBridge()->loadSourceFile(szSourceFile, sel);
|
||||
emit displaySourceManagerWidget();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
#include <QDesktopServices>
|
||||
#include "Configuration.h"
|
||||
|
||||
SourceView::SourceView(QString path, int line, QWidget* parent)
|
||||
SourceView::SourceView(QString path, duint addr, QWidget* parent)
|
||||
: ReferenceView(true, parent),
|
||||
mIpLine(0)
|
||||
mSourcePath(path),
|
||||
mIpLine(0),
|
||||
mModBase(DbgFunctions()->ModBaseFromAddr(addr))
|
||||
{
|
||||
mSourcePath = path;
|
||||
stdList()->enableColumnSorting(false);
|
||||
stdSearchList()->enableColumnSorting(false);
|
||||
|
||||
|
@ -22,7 +23,7 @@ SourceView::SourceView(QString path, int line, QWidget* parent)
|
|||
connect(this, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(sourceContextMenu(QMenu*)));
|
||||
|
||||
loadFile();
|
||||
setSelection(line);
|
||||
setSelection(addr);
|
||||
|
||||
mMenuBuilder = new MenuBuilder(this);
|
||||
mMenuBuilder->addAction(makeAction(DIcon("source.png"), tr("Open source file"), SLOT(openSourceFileSlot())));
|
||||
|
@ -30,8 +31,11 @@ SourceView::SourceView(QString path, int line, QWidget* parent)
|
|||
mMenuBuilder->loadFromConfig();
|
||||
}
|
||||
|
||||
void SourceView::setSelection(int line)
|
||||
void SourceView::setSelection(duint addr)
|
||||
{
|
||||
int line = 0;
|
||||
if(!DbgFunctions()->GetSourceFromAddr(addr, nullptr, &line))
|
||||
return;
|
||||
mCurList->scrollSelect(line - 1);
|
||||
reloadData(); //repaint
|
||||
}
|
||||
|
@ -54,9 +58,8 @@ void SourceView::loadFile()
|
|||
{
|
||||
QString line = in.readLine().replace('\t', " "); //replace tabs with four spaces
|
||||
setRowCount(lineNum + 1);
|
||||
duint displacement = 0;
|
||||
duint addr = DbgFunctions()->GetAddrFromLine(mSourcePath.toUtf8().constData(), lineNum + 1, &displacement);
|
||||
if(addr && !displacement)
|
||||
duint addr = DbgFunctions()->GetAddrFromLineEx(mModBase, mSourcePath.toUtf8().constData(), lineNum + 1);
|
||||
if(addr)
|
||||
setCellContent(lineNum, 0, ToPtrString(addr));
|
||||
setCellContent(lineNum, 1, QString("%1").arg(lineNum + 1));
|
||||
setCellContent(lineNum, 2, line);
|
||||
|
|
|
@ -11,10 +11,10 @@ class SourceView : public ReferenceView
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SourceView(QString path, int line = 0, QWidget* parent = 0);
|
||||
explicit SourceView(QString path, duint addr, QWidget* parent = 0);
|
||||
QString getSourcePath();
|
||||
void setupContextMenu();
|
||||
void setSelection(int line);
|
||||
void setSelection(duint addr);
|
||||
|
||||
private slots:
|
||||
void sourceContextMenu(QMenu* menu);
|
||||
|
@ -25,6 +25,7 @@ private:
|
|||
QString mSourcePath;
|
||||
int mIpLine;
|
||||
MenuBuilder* mMenuBuilder;
|
||||
duint mModBase;
|
||||
|
||||
void loadFile();
|
||||
};
|
||||
|
|
|
@ -16,21 +16,19 @@ SourceViewerManager::SourceViewerManager(QWidget* parent) : QTabWidget(parent)
|
|||
setCornerWidget(mCloseAllTabs, Qt::TopLeftCorner);
|
||||
|
||||
connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
|
||||
connect(Bridge::getBridge(), SIGNAL(loadSourceFile(QString, int, int)), this, SLOT(loadSourceFile(QString, int, int)));
|
||||
connect(Bridge::getBridge(), SIGNAL(loadSourceFile(QString, duint)), this, SLOT(loadSourceFile(QString, duint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChanged(DBGSTATE)));
|
||||
}
|
||||
|
||||
void SourceViewerManager::loadSourceFile(QString path, int line, int selection)
|
||||
void SourceViewerManager::loadSourceFile(QString path, duint addr)
|
||||
{
|
||||
if(!line)
|
||||
line = selection;
|
||||
for(int i = 0; i < count(); i++)
|
||||
{
|
||||
SourceView* curView = (SourceView*)this->widget(i);
|
||||
if(curView->getSourcePath().compare(path, Qt::CaseInsensitive) == 0) //file already loaded
|
||||
{
|
||||
QWidget* now = QApplication::focusWidget();
|
||||
curView->setSelection(line);
|
||||
curView->setSelection(addr);
|
||||
setCurrentIndex(i); //show that loaded tab
|
||||
if(now)
|
||||
now->setFocus();
|
||||
|
@ -47,7 +45,7 @@ void SourceViewerManager::loadSourceFile(QString path, int line, int selection)
|
|||
int idx = path.lastIndexOf(QDir::separator());
|
||||
if(idx != -1)
|
||||
title = path.mid(idx + 1);
|
||||
SourceView* newView = new SourceView(path, line, this);
|
||||
SourceView* newView = new SourceView(path, addr, this);
|
||||
connect(newView, SIGNAL(showCpu()), this, SIGNAL(showCpu()));
|
||||
addTab(newView, title);
|
||||
setCurrentIndex(count() - 1);
|
||||
|
|
|
@ -13,7 +13,7 @@ public:
|
|||
explicit SourceViewerManager(QWidget* parent = 0);
|
||||
|
||||
public slots:
|
||||
void loadSourceFile(QString path, int line, int selection = 0);
|
||||
void loadSourceFile(QString path, duint addr);
|
||||
void closeTab(int index);
|
||||
void closeAllTabs();
|
||||
void dbgStateChanged(DBGSTATE state);
|
||||
|
|
Loading…
Reference in New Issue