diff options
| author | Pokechu22 <Pokechu022@gmail.com> | 2021-12-08 17:10:39 -0800 |
|---|---|---|
| committer | Pokechu22 <Pokechu022@gmail.com> | 2021-12-08 21:42:15 -0800 |
| commit | 5bcbc8fcef7f0888bacd16c34295666d407a19b6 (patch) | |
| tree | 41a51902ef03e86ac20126a38dab28c1ce00767b /Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp | |
| parent | 85e5070215f1d39331ef7d67dbcb15e067b45173 (diff) | |
CodeViewWidget: Fix undefined behavior when centered around address 0
Diffstat (limited to 'Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp')
| -rw-r--r-- | Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp | 66 |
1 files changed, 50 insertions, 16 deletions
diff --git a/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp b/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp index a2b113f881..77bb8c8bd3 100644 --- a/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp @@ -20,6 +20,7 @@ #include <QTableWidgetItem> #include <QWheelEvent> +#include "Common/Assert.h" #include "Common/GekkoDisassembler.h" #include "Common/StringUtil.h" #include "Core/Core.h" @@ -393,26 +394,27 @@ void CodeViewWidget::CalculateBranchIndentation() // build a 2D lookup table representing the columns and rows the arrow could be drawn in // and try to place all branch arrows in it as far left as possible std::vector<bool> arrow_space_used(columns * rows, false); - const auto index = [&](u32 column, u32 row) { return column * rows + row; }; - const u32 first_visible_addr = AddressForRow(0); - const u32 last_visible_addr = AddressForRow(static_cast<int>(rows - 1)); - for (CodeViewBranch& branch : m_branches) - { + const auto index = [&](u32 column, u32 row) { + ASSERT(row <= rows); + ASSERT(column <= columns); + return column * rows + row; + }; + + const auto add_branch_arrow = [&](CodeViewBranch& branch, u32 first_addr, u32 first_row, + u32 last_addr) { const u32 arrow_src_addr = branch.src_addr; const u32 arrow_dst_addr = branch.is_link ? branch.src_addr : branch.dst_addr; - const u32 arrow_addr_lower = std::min(arrow_src_addr, arrow_dst_addr); - const u32 arrow_addr_higher = std::max(arrow_src_addr, arrow_dst_addr); + const auto [arrow_addr_lower, arrow_addr_higher] = std::minmax(arrow_src_addr, arrow_dst_addr); + const bool is_visible = - last_visible_addr >= arrow_addr_lower || first_visible_addr <= arrow_addr_higher; + std::max(arrow_addr_lower, first_addr) <= std::min(arrow_addr_higher, last_addr); if (!is_visible) - continue; + return; - const u32 arrow_first_visible_addr = - std::clamp(arrow_addr_lower, first_visible_addr, last_visible_addr); - const u32 arrow_last_visible_addr = - std::clamp(arrow_addr_higher, first_visible_addr, last_visible_addr); - const u32 arrow_first_visible_row = (arrow_first_visible_addr - first_visible_addr) / 4; - const u32 arrow_last_visible_row = (arrow_last_visible_addr - first_visible_addr) / 4; + const u32 arrow_first_visible_addr = std::clamp(arrow_addr_lower, first_addr, last_addr); + const u32 arrow_last_visible_addr = std::clamp(arrow_addr_higher, first_addr, last_addr); + const u32 arrow_first_visible_row = (arrow_first_visible_addr - first_addr) / 4 + first_row; + const u32 arrow_last_visible_row = (arrow_last_visible_addr - first_addr) / 4 + first_row; const auto free_column = [&]() -> std::optional<u32> { for (u32 column = 0; column < columns; ++column) @@ -432,11 +434,43 @@ void CodeViewWidget::CalculateBranchIndentation() }(); if (!free_column) - continue; + return; branch.indentation = *free_column; for (u32 row = arrow_first_visible_row; row <= arrow_last_visible_row; ++row) arrow_space_used[index(*free_column, row)] = true; + }; + + const u32 first_visible_addr = AddressForRow(0); + const u32 last_visible_addr = AddressForRow(static_cast<int>(rows - 1)); + + if (first_visible_addr <= last_visible_addr) + { + for (CodeViewBranch& branch : m_branches) + add_branch_arrow(branch, first_visible_addr, 0, last_visible_addr); + } + else + { + // Scrolling defaults to being centered around address 00000000, which means addresses before + // the start are visible (e.g. ffffffa8 - 00000050). We need to do this in two parts, one for + // first_visible_addr to fffffffc, and the second for 00000000 to last_visible_addr. + // That means we need to find the row corresponding to 00000000. + int addr_zero_row = -1; + for (int row = 0; row < rows; row++) + { + if (AddressForRow(row) == 0) + { + addr_zero_row = row; + break; + } + } + ASSERT(addr_zero_row != -1); + + for (CodeViewBranch& branch : m_branches) + { + add_branch_arrow(branch, first_visible_addr, 0, 0xfffffffc); + add_branch_arrow(branch, 0x00000000, addr_zero_row, last_visible_addr); + } } } |
