1
0
Fork 0

DBG+BRIDGE+GUI: fix source loading

This commit is contained in:
Duncan Ogilvie 2018-06-29 15:44:13 +02:00
parent b63402066b
commit 8c169ae2ed
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
14 changed files with 70 additions and 36 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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:

View File

@ -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);

View File

@ -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();
}

View File

@ -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);

View File

@ -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();
};

View File

@ -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);

View File

@ -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);