Skip to content

Commit

Permalink
Dedicated FX
Browse files Browse the repository at this point in the history
  • Loading branch information
sevaa committed Aug 30, 2024
1 parent e1da8d2 commit 760a3de
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 15 deletions.
7 changes: 5 additions & 2 deletions dwex/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from .frames import FramesDlg

# Sync with version in setup.py
version = (4, 0)
version = (4, 10)

# TODO:
# On MacOS, start without a main window, instead show the Open dialog
Expand Down Expand Up @@ -735,6 +735,8 @@ def on_copytable(self):
for r in range(0, m.rowCount(QModelIndex())))
self.on_copy(table_text)

##################################################################

def on_localsat(self):
dlg = LocalsDlg(self, self.dwarfinfo, self.prefix, self.dwarfregnames, self.hex)
if dlg.exec() == QDialog.DialogCode.Accepted and dlg.selected_die:
Expand All @@ -760,7 +762,8 @@ def on_frames(self):
FramesDlg(self, entries, self.dwarfinfo, self.dwarfregnames).exec()
# TODO: navigate to function
else:
QMessageBox(QMessageBox.Icon.Warning, "DWARF Explorer", "This binary does not have neither an eh_frames section nor a debug_frames section.",
# TODO: https://faultlore.com/blah/compact-unwinding/
QMessageBox(QMessageBox.Icon.Warning, "DWARF Explorer", "This binary does not have neither an eh_frames section nor a debug_frames section. Mach-O unwind_info is not supported yet.",
QMessageBox.StandardButton.Ok, self).show()

# If the details pane has data - reload that
Expand Down
12 changes: 11 additions & 1 deletion dwex/frames.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@

from elftools.dwarf.callframe import FDE, RegisterRule, ZERO

from dwex.fx import bold_font
from dwex.locals import LoadedModuleDlgBase

from .exprutil import _REG_NAME_MAP, format_offset

rheaders = ('Start address', 'End address', 'Length')
eheaders = ('Type', 'CIE offset', 'Start address', 'End address', 'Length')

# TODO: more fields in entries mode? Version, augmentation, etc? Or a properties window?
# TODO: dump raw instructions in details?
# TODO: MachO unwind_info

class EntriesModel(QAbstractTableModel):
def __init__(self, cfi, fdes_only):
QAbstractTableModel.__init__(self)
Expand Down Expand Up @@ -45,7 +50,8 @@ def data(self, index, role):
if col == 0:
return ('FDE' if is_fde else 'CIE') if header else 'ZERO'
if col == 1:
return (hex(header.CIE_pointer if is_fde else entry.offset)) if header else ''
return (hex(entry.cie.offset if is_fde else entry.offset)) if header else ''
# CIE_offset in FDE header is relative in EH section, absolute in debug_frames
else:
col -= 2
if is_fde:
Expand All @@ -55,6 +61,9 @@ def data(self, index, role):
return hex(header.initial_location + header.address_range - 1)
elif col == 2:
return hex(header.address_range)
elif role == Qt.ItemDataRole.FontRole:
if not self.fdes_only and is_fde:
return bold_font()

class DecodedEntryModel(QAbstractTableModel):
def __init__(self, entry, regnamelist):
Expand Down Expand Up @@ -192,6 +201,7 @@ def __init__(self, win, cfi, di, regnames):
self.setWindowTitle('Frames')

def set_view(self, fdes_only):
# TODO: change the model in place
self.entries.setModel(EntriesModel(self.cfi, fdes_only))
self.entries.selectionModel().currentChanged.connect(self.on_entry_sel)
self.details.setModel(None)
Expand Down
11 changes: 11 additions & 0 deletions dwex/fx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from PyQt6.QtWidgets import QApplication
from PyQt6.QtGui import QFontInfo, QFont

_bold_font = None

def bold_font():
global _bold_font
if not _bold_font:
fi = QFontInfo(QApplication.font())
_bold_font = QFont(fi.family(), fi.pointSize(), QFont.Weight.Bold)
return _bold_font
9 changes: 2 additions & 7 deletions dwex/locals.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from PyQt6.QtCore import Qt, QAbstractTableModel, QSize
from PyQt6.QtWidgets import *
from PyQt6.QtGui import QFontInfo, QFont
from elftools.dwarf.locationlists import LocationParser, LocationExpr
from elftools.dwarf.callframe import FDE, CFARule

from dwex.exprutil import ExprFormatter, format_offset
from .dwarfutil import *
from .fx import bold_font

#0x25af0
#0xd864 (black)
Expand All @@ -15,7 +15,6 @@
#TODO: Objective C, Pascal, more?

headers = ["Name", "Location"]
_bold_font = None

# TODO: move elsewhere
class WaitCursor():
Expand Down Expand Up @@ -64,11 +63,7 @@ def data(self, index, role):
return val
elif role == Qt.ItemDataRole.FontRole:
if the_row[0]:
global _bold_font
if not _bold_font:
fi = QFontInfo(QApplication.font())
_bold_font = QFont(fi.family(), fi.pointSize(), QFont.Weight.Bold)
return _bold_font
return bold_font()
elif role == Qt.ItemDataRole.ToolTipRole:
if col == 1 and not the_row[0]: # On the location column of a variable
if val is False:
Expand Down
2 changes: 1 addition & 1 deletion dwex/locs.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def desc_CFA_rule(rule):
if rule.expr is not None:
return '; '.join(self.dump_expr(rule.expr))
else:
return self.expr_formatter.format_regofset(rule.reg, rule.offset)
return self.expr_formatter.format_regoffset(rule.reg, rule.offset)

rules = [(r['pc'], r['cfa']) for r in get_frame_rules_for_die(self.die) if 'cfa' in r]
rules = [(pc, r) for (i, (pc, r)) in enumerate(rules) if i == 0 or rules[i-1][1] != r.reg or rules[i-1][1].offset != r.offset or rules[i-1][1].expr != r.expr]
Expand Down
5 changes: 3 additions & 2 deletions dwex/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from PyQt6.QtCore import Qt, QAbstractItemModel, QModelIndex
from PyQt6.QtGui import QFont, QFontInfo, QBrush
from PyQt6.QtWidgets import QApplication, QMessageBox

from .fx import bold_font
from .dwarfutil import has_code_location, safe_DIE_name, top_die_file_name

def cu_sort_key(cu):
Expand Down Expand Up @@ -47,7 +49,6 @@ def __init__(self, di, prefix, sortcus, sortdies):
self.top_dies = [decorate_die(CU.get_top_DIE(), i) for (i, CU) in enumerate(di._CUs)]
self.highlight_condition = None
fi = QFontInfo(QApplication.font())
self.bold_font = QFont(fi.family(), fi.pointSize(), QFont.Weight.Bold)
self.blue_brush = QBrush(Qt.GlobalColor.blue)
self.sortcus = sortcus
self.sortdies = sortdies
Expand Down Expand Up @@ -114,7 +115,7 @@ def data(self, index, role):
elif role == Qt.ItemDataRole.ForegroundRole and self.is_highlighted(die):
return self.blue_brush
elif role == Qt.ItemDataRole.FontRole and self.is_highlighted(die):
return self.bold_font
return bold_font()

# The rest is not Qt callbacks

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def run(self):

setup(
name='dwex',
version='4.0', # Sync with version in __main__
version='4.10', # Sync with version in __main__
packages=['dwex'],
url="https://github.com/sevaa/dwex/",
entry_points={"gui_scripts": ["dwex = dwex.__main__:main"]},
Expand Down
2 changes: 1 addition & 1 deletion test/testall.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from elftools.dwarf.locationlists import LocationParser, LocationExpr
from dwex.formats import read_dwarf
from dwex.die import DIETableModel
from dwex.tree import strip_path
from dwex.dwarfutil import strip_path

def test_dwarfinfo(di):
# Some global cache setup in line with the app proper
Expand Down

0 comments on commit 760a3de

Please sign in to comment.