core: Fix libdwarf and Qt build failure
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / callstackbrowser.cpp
index 77fe154..607c398 100644 (file)
 //
 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
 //
-// Who  When        What
-// ---  ----------  -----------------------------------------------------------
-// JPM  08/31/2018  Created this file
-//
+// Who  When (M/D/Y)  What
+// ---  ------------  -----------------------------------------------------------
+// JPM  08/31/2018    Created this file
+// JPM  09/12/2018    Added a status bar and better status report
+// JPM  10/20/2018    Added the return address information in the call stack
+// JPM  08/09/2019    Prevent crash in case of call stack is out of range
+// JPM  03/16/2020    Modified the layout window and added source filename from the called source line
+// JPM  April/2021    Added a #line information
 
 // STILL TO DO:
-// Better display presentation
-// To display call function
-// To use DWARF frame information
+// To set the information display at the right
+// To use DWARF frame information?
+// To check if call stack pointer is used (DWARF information?)
 //
 
 #include "debugger/callstackbrowser.h"
 #include "memory.h"
 #include "debugger/DBGManager.h"
 #include "m68000/m68kinterface.h"
+#include "settings.h"
 
 
-//
+// 
 CallStackBrowserWindow::CallStackBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),
-       layout(new QVBoxLayout), text(new QTextBrowser)
+#ifdef CS_LAYOUTTEXTS
+text(new QTextBrowser),
+#else
+TableView(new QTableView),
+model(new QStandardItemModel),
+#endif
+statusbar(new QStatusBar),
+layout(new QVBoxLayout)
 {
        setWindowTitle(tr("Call Stack"));
 
+       // Set the font
        QFont fixedFont("Lucida Console", 8, QFont::Normal);
        fixedFont.setStyleHint(QFont::TypeWriter);
-       text->setFont(fixedFont);
-       setLayout(layout);
 
+#ifdef CS_LAYOUTTEXTS
+       // Set original layout
+       text->setFont(fixedFont);
        layout->addWidget(text);
+#else
+       // Set the new layout with proper identation and readibility
+       model->setColumnCount(5);
+       model->setHeaderData(0, Qt::Horizontal, QObject::tr("Function"));
+       model->setHeaderData(1, Qt::Horizontal, QObject::tr("#Line"));
+       model->setHeaderData(2, Qt::Horizontal, QObject::tr("Line"));
+       model->setHeaderData(3, Qt::Horizontal, QObject::tr("Return address"));
+       model->setHeaderData(4, Qt::Horizontal, QObject::tr("Filename"));
+       // Information table
+       TableView->setModel(model);
+       TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
+       TableView->setShowGrid(0);
+       TableView->setFont(fixedFont);
+       TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize());
+       TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight);
+       layout->addWidget(TableView);
+#endif
+
+       // Status bar
+       layout->addWidget(statusbar);
+       setLayout(layout);
 }
 
 
-//
+// 
 CallStackBrowserWindow::~CallStackBrowserWindow(void)
 {
 }
 
 
-//
+// 
 void CallStackBrowserWindow::RefreshContents(void)
 {
+       char msg[1024];
+       size_t Error = CS_NOERROR;
+       DBGstatus FilenameStatus;
        unsigned int a6, Sa6, ret;
-       char *FuncName;
+       char *Name;
+       size_t NumError = 0;
+#ifdef CS_LAYOUTTEXTS
        QString CallStack;
        char string[1024];
+#else
+       int NbRaw = 0;
+       QString FunctionName;
+#endif
 
        if (isVisible())
        {
+#ifndef CS_LAYOUTTEXTS
+               model->setRowCount(0);
+#endif
                if ((a6 = m68k_get_reg(NULL, M68K_REG_A6)) && DBGManager_GetType())
                {
-                       while ((Sa6 = a6))
+                       while ((Sa6 = a6) && !NumError)
                        {
-                               a6 = GET32(jaguarMainRAM, Sa6);
-                               ret = GET32(jaguarMainRAM, Sa6 + 4);
-
-                               sprintf(string, "0x%06X | Ret: 0x%06X | From: %s - 0x%06X", Sa6, ret, (FuncName = DBGManager_GetFunctionName(ret)), (unsigned int)DBGManager_GetAdrFromSymbolName(FuncName));
-                               CallStack += QString(string);
-                               if (a6)
+                               if ((Sa6 >= (m68k_get_reg(NULL, M68K_REG_SP) - 4)) && (Sa6 < vjs.DRAM_size))
                                {
-                                       sprintf(string, "<br>");
+                                       a6 = GET32(jaguarMainRAM, Sa6);
+                                       ret = GET32(jaguarMainRAM, Sa6 + 4);
+#ifdef CS_LAYOUTTEXTS
+                                       sprintf(string, "0x%06X | Ret: 0x%06X | From: %s - 0x%06X | Line: %s", Sa6, ret, (Name = DBGManager_GetFunctionName(ret)), (unsigned int)DBGManager_GetAdrFromSymbolName(Name), DBGManager_GetLineSrcFromAdr(ret, DBG_NO_TAG));
                                        CallStack += QString(string);
+                                       if (a6)
+                                       {
+                                               CallStack += QString("<br>");
+                                       }
+#else
+                                       // insert line
+                                       model->insertRow(NbRaw);
+                                       // display the function name
+                                       model->setItem(NbRaw, 0, new QStandardItem(QString("%1").arg((Name = DBGManager_GetFunctionName(ret)) ? Name : "(N/A)")));
+                                       // display the line number
+                                       sprintf(msg, "%zi", DBGManager_GetNumLineFromAdr(ret, DBG_NO_TAG));
+                                       model->setItem(NbRaw, 1, new QStandardItem(QString("%1").arg((msg[0] != '0') ? msg : "(N/A)")));
+                                       // display the called line
+                                       FunctionName = QString(Name = DBGManager_GetLineSrcFromAdr(ret, DBG_NO_TAG));
+                                       //FunctionName.replace("&nbsp;", " ");
+                                       FunctionName = FunctionName.trimmed();
+                                       model->setItem(NbRaw, 2, new QStandardItem(QString("%1").arg(Name ? FunctionName : "(N/A)")));
+                                       // display the return address
+                                       sprintf(msg, "0x%06X", ret);
+                                       model->setItem(NbRaw, 3, new QStandardItem(QString("%1").arg(msg)));
+                                       // display the source filename from called source line
+                                       model->setItem(NbRaw++, 4, new QStandardItem(QString("%1").arg(((Name = DBGManager_GetFullSourceFilenameFromAdr(ret, &FilenameStatus)) && !FilenameStatus) ? Name : "(N/A)")));
+#endif
+                               }
+                               else
+                               {
+                                       NumError = 0x1;
                                }
                        }
-
+#ifdef CS_LAYOUTTEXTS
                        text->clear();
                        text->setText(CallStack);
+#endif
+                       switch (NumError)
+                       {
+                       case 0:
+                               sprintf(msg, "Ready");
+                               Error = CS_NOERROR;
+                               break;
+
+                       case 0x1:
+                               sprintf(msg, "Call Stack out of range");
+                               Error = CS_ERROR;
+                               break;
+
+                       default:
+                               sprintf(msg, "Call Stack in limbo");
+                               Error = CS_WARNING;
+                               break;
+                       }
                }
                else
                {
+                       sprintf(msg, "Call Stack not available");
+                       Error = CS_NOCALLSTACK;
+#ifdef CS_LAYOUTTEXTS
                        text->clear();
+#endif
+               }
+
+               // Display status bar
+               if (Error)
+               {
+                       if ((Error & CS_WARNING))
+                       {
+                               statusbar->setStyleSheet("background-color: lightyellow; font: bold");
+                       }
+                       else
+                       {
+                               statusbar->setStyleSheet("background-color: tomato; font: bold");
+                       }
+               }
+               else
+               {
+                       statusbar->setStyleSheet("background-color: lightgreen; font: bold");
                }
+               statusbar->showMessage(QString(msg));
        }
 }
 
 
-//
+// 
 void CallStackBrowserWindow::keyPressEvent(QKeyEvent * e)
 {
        if (e->key() == Qt::Key_Escape)