Skip to content

Commit 4104ab0

Browse files
authored
Merge branch 'main' into main
2 parents 49cbcc5 + eba3c7a commit 4104ab0

File tree

9 files changed

+358
-52
lines changed

9 files changed

+358
-52
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,9 @@ luacov.stats.out
124124
/lua
125125
/lua_modules
126126
/.luarocks
127+
128+
# appimage build files
129+
/appimage-build
130+
/AppDir
131+
/*.AppImage
132+
/*.AppImage.zsync

src/core/r3000a.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "core/sio.h"
3535
#include "core/sio1.h"
3636
#include "core/spu.h"
37+
#include "supportpsx/memory.h"
3738
#include "fmt/format.h"
3839

3940
int PCSX::R3000Acpu::psxInit() {
@@ -502,3 +503,28 @@ void PCSX::R3000Acpu::processB0KernelCall(uint32_t call) {
502503
}
503504
}
504505
}
506+
507+
std::pair<const uint32_t, std::string>* PCSX::R3000Acpu::findContainingSymbol(uint32_t addr) {
508+
auto symBefore = m_symbols.upper_bound(addr);
509+
if (symBefore != m_symbols.begin()) { // verify there is actually a symbol before addr
510+
symBefore--;
511+
if (symBefore->first != addr) {
512+
PCSX::PSXAddress addrInfo(addr);
513+
PCSX::PSXAddress symbolInfo(symBefore->first);
514+
if (addrInfo.segment != symbolInfo.segment) {
515+
// if the symbol is different and not in the same memory region, it'd be wrong
516+
return nullptr;
517+
}
518+
}
519+
return &*symBefore;
520+
}
521+
return nullptr;
522+
}
523+
524+
std::string* PCSX::R3000Acpu::getSymbolAt(uint32_t addr) {
525+
auto symBefore = m_symbols.find(addr);
526+
if (symBefore != m_symbols.end()) {
527+
return &symBefore->second;
528+
}
529+
return nullptr;
530+
}

src/core/r3000a.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,9 @@ class R3000Acpu {
290290

291291
std::map<uint32_t, std::string> m_symbols;
292292

293+
std::pair<const uint32_t, std::string>* findContainingSymbol(uint32_t addr);
294+
std::string* getSymbolAt(uint32_t addr);
295+
293296
static int psxInit();
294297
virtual bool isDynarec() = 0;
295298
void psxReset();

src/gui/widgets/assembly.cc

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,8 @@ void PCSX::Widgets::Assembly::Target(uint32_t value) {
302302
if (m_displayArrowForJumps) m_arrows.push_back({m_currentAddr, value});
303303
std::snprintf(label, sizeof(label), "0x%8.8x##%8.8x", value, m_currentAddr);
304304
std::string longLabel = label;
305-
auto symbols = findSymbol(value);
306-
if (symbols.size() != 0) longLabel = *symbols.begin() + " ;" + label;
305+
std::string* symbol = g_emulator->m_cpu->getSymbolAt(value);
306+
if (symbol) longLabel = *symbol + " ;" + label;
307307
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
308308
if (ImGui::Button(longLabel.c_str())) {
309309
m_jumpToPC = value;
@@ -366,8 +366,8 @@ void PCSX::Widgets::Assembly::OfB(int16_t offset, uint8_t reg, int size) {
366366
uint32_t addr = m_registers->GPR.r[reg] + offset;
367367

368368
std::string longLabel;
369-
auto symbols = findSymbol(addr);
370-
if (symbols.size() != 0) longLabel = *symbols.begin() + " ; ";
369+
std::string* symbol = g_emulator->m_cpu->getSymbolAt(addr);
370+
if (symbol) longLabel = *symbol + " ; ";
371371

372372
const auto& io = ImGui::GetIO();
373373
unsigned targetEditorIndex = io.KeyShift ? 1 : (io.KeyCtrl ? 2 : 0);
@@ -405,17 +405,17 @@ void PCSX::Widgets::Assembly::BranchDest(uint32_t value) {
405405
sameLine();
406406
m_arrows.push_back({m_currentAddr, value});
407407
std::snprintf(label, sizeof(label), "0x%8.8x##%8.8x", value, m_currentAddr);
408-
auto symbols = findSymbol(value);
409-
if (symbols.size() == 0) {
408+
std::string* symbol = g_emulator->m_cpu->getSymbolAt(value);
409+
if (symbol) {
410+
std::string longLabel = *symbol + " ;" + label;
410411
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
411-
if (ImGui::Button(label)) {
412+
if (ImGui::Button(longLabel.c_str())) {
412413
m_jumpToPC = value;
413414
}
414415
ImGui::PopStyleVar();
415416
} else {
416-
std::string longLabel = *symbols.begin() + " ;" + label;
417417
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
418-
if (ImGui::Button(longLabel.c_str())) {
418+
if (ImGui::Button(label)) {
419419
m_jumpToPC = value;
420420
}
421421
ImGui::PopStyleVar();
@@ -427,8 +427,8 @@ void PCSX::Widgets::Assembly::Offset(uint32_t addr, int size) {
427427
char label[32];
428428
std::snprintf(label, sizeof(label), "0x%8.8x##%8.8x", addr, m_currentAddr);
429429
std::string longLabel = label;
430-
auto symbols = findSymbol(addr);
431-
if (symbols.size() != 0) longLabel = *symbols.begin() + " ;" + label;
430+
std::string* symbol = g_emulator->m_cpu->getSymbolAt(addr);
431+
if (symbol) longLabel = *symbol + " ;" + label;
432432

433433
const auto& io = ImGui::GetIO();
434434
unsigned targetEditorIndex = io.KeyShift ? 1 : (io.KeyCtrl ? 2 : 0);
@@ -598,6 +598,10 @@ settings, otherwise debugging features may not work.)");
598598
bool openAssembler = false;
599599
bool openSymbolAdder = false;
600600

601+
float lineHeight = ImGui::GetTextLineHeight();
602+
float previousSymbolY = topleft.y;
603+
std::optional<std::string> previousSymbol;
604+
601605
while (clipper.Step()) {
602606
bool skipNext = false;
603607
bool delaySlotNext = false;
@@ -676,11 +680,23 @@ settings, otherwise debugging features may not work.)");
676680
tcode >>= 8;
677681
b[3] = tcode & 0xff;
678682

679-
auto symbols = findSymbol(dispAddr);
680-
if (symbols.size() != 0) {
681-
ImGui::PushStyleColor(ImGuiCol_Text, s_labelColor);
682-
ImGui::Text("%s:", symbols.begin()->c_str());
683-
ImGui::PopStyleColor();
683+
std::pair<const uint32_t, std::string>* symbol = cpu->findContainingSymbol(dispAddr);
684+
if (symbol) {
685+
if (symbol->first == dispAddr) {
686+
ImGui::PushStyleColor(ImGuiCol_Text, s_labelColor);
687+
ImGui::Text("%s:", symbol->second.c_str());
688+
ImGui::PopStyleColor();
689+
} else {
690+
// if this is the first visible line and it's not a label itself, store the previous symbol
691+
float y = ImGui::GetCursorScreenPos().y;
692+
if (y + lineHeight >= topleft.y && y <= topleft.y + lineHeight) {
693+
previousSymbol = symbol->second;
694+
// if the second visible line is a symbol, push the previous symbol display up
695+
if (cpu->getSymbolAt(dispAddr + 4) && y < previousSymbolY) {
696+
previousSymbolY = y;
697+
}
698+
}
699+
}
684700
}
685701

686702
for (int i = 0; i < m_numColumns * ImGui::GetWindowDpiScale(); i++) {
@@ -750,15 +766,15 @@ settings, otherwise debugging features may not work.)");
750766
}
751767
std::string contextMenuID = fmt::format("assembly address menu {}", dispAddr);
752768
if (ImGui::BeginPopupContextItem(contextMenuID.c_str())) {
753-
if (symbols.size() == 0) {
769+
if (symbol) {
770+
if (ImGui::MenuItem(_("Remove symbol"))) {
771+
cpu->m_symbols.erase(dispAddr);
772+
}
773+
} else {
754774
if (ImGui::MenuItem(_("Create symbol here"))) {
755775
openSymbolAdder = true;
756776
m_symbolAddress = dispAddr;
757777
}
758-
} else {
759-
if (ImGui::MenuItem(_("Remove symbol"))) {
760-
cpu->m_symbols.erase(dispAddr);
761-
}
762778
}
763779
if (ImGui::MenuItem(_("Copy Address"))) {
764780
char fmtAddr[10];
@@ -938,6 +954,13 @@ settings, otherwise debugging features may not work.)");
938954
}
939955
}
940956
drawList->ChannelsMerge();
957+
if (previousSymbol) {
958+
ImVec2 pos(ImGui::GetCursorScreenPos().x, previousSymbolY);
959+
ImVec2 posEnd(pos.x + glyphWidth * 64, pos.y + ImGui::GetTextLineHeight());
960+
drawList->AddRectFilled(pos, posEnd, ImGui::GetColorU32(ImGuiCol_WindowBg));
961+
std::string text = "^ " + previousSymbol.value() + " ^";
962+
drawList->AddText(pos, ImGui::GetColorU32(s_labelColor), text.data(), text.data() + text.size());
963+
}
941964
ImGui::EndChild();
942965
ImGui::PopFont();
943966
if (m_jumpToPC.has_value()) {
@@ -1078,7 +1101,7 @@ if not success then return msg else return nil end
10781101

10791102
if (m_showSymbols) {
10801103
if (ImGui::Begin(_("Symbols"), &m_showSymbols)) {
1081-
if (ImGui::Button(_("Refresh"))) rebuildSymbolsCaches();
1104+
if (ImGui::Button(_("Refresh"))) rebuildSymbolsCache();
10821105
ImGui::SameLine();
10831106
ImGui::InputText(_("Filter"), &m_symbolFilter);
10841107
ImGui::BeginChild("symbolsList");
@@ -1114,24 +1137,11 @@ if not success then return msg else return nil end
11141137
return changed;
11151138
}
11161139

1117-
std::list<std::string> PCSX::Widgets::Assembly::findSymbol(uint32_t addr) {
1118-
auto& cpu = g_emulator->m_cpu;
1119-
std::list<std::string> ret;
1120-
auto symbol = cpu->m_symbols.find(addr);
1121-
if (symbol != cpu->m_symbols.end()) ret.emplace_back(symbol->second);
1122-
1123-
if (!m_symbolsCachesValid) rebuildSymbolsCaches();
1124-
auto elfSymbol = m_elfSymbolsCache.find(addr);
1125-
if (elfSymbol != m_elfSymbolsCache.end()) ret.emplace_back(elfSymbol->second);
1126-
1127-
return ret;
1128-
}
1129-
1130-
void PCSX::Widgets::Assembly::rebuildSymbolsCaches() {
1140+
void PCSX::Widgets::Assembly::rebuildSymbolsCache() {
11311141
auto& cpu = g_emulator->m_cpu;
11321142
m_symbolsCache.clear();
11331143
for (auto& symbol : cpu->m_symbols) {
11341144
m_symbolsCache.insert(std::pair(symbol.second, symbol.first));
11351145
}
1136-
m_symbolsCachesValid = true;
1146+
m_symbolsCacheValid = true;
11371147
}

src/gui/widgets/assembly.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,10 @@ class Assembly : private Disasm {
110110
uint32_t addr;
111111
};
112112

113-
std::list<std::string> findSymbol(uint32_t addr);
114113
std::map<std::string, uint32_t> m_symbolsCache;
115-
std::map<uint32_t, std::string> m_elfSymbolsCache;
116-
bool m_symbolsCachesValid = false;
114+
bool m_symbolsCacheValid = false;
117115

118-
void rebuildSymbolsCaches();
116+
void rebuildSymbolsCache();
119117
void addMemoryEditorContext(uint32_t addr, int size);
120118
void addMemoryEditorSubMenu(uint32_t addr, int size);
121119

src/supportpsx/iec-60908b.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ struct fmt::formatter<PCSX::IEC60908b::MSF> {
159159
}
160160

161161
template <typename FormatContext>
162-
auto format(PCSX::IEC60908b::MSF const &msf, FormatContext &ctx) {
162+
auto format(PCSX::IEC60908b::MSF const &msf, FormatContext &ctx) const {
163163
return fmt::format_to(ctx.out(), "{0:02}:{1:02}:{2:02}", msf.m, msf.s, msf.f);
164164
}
165165
};

tools/ghidra_scripts/OverlayReduxSymbols.java

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Exports symbols to PCSX-Redux's symbols map including Overlays filtering
2+
//@author Nicolas "Pixel" Noble
23
//@author acemon33
3-
//@category PSX
44

55
import ghidra.app.script.GhidraScript;
66
import ghidra.program.model.symbol.*;
@@ -15,12 +15,9 @@
1515
public class OverlayReduxSymbols extends GhidraScript {
1616

1717
public void run() throws Exception {
18-
MemoryBlock[] MemoryBlockList = state.getCurrentProgram().getMemory().getBlocks();
19-
List<String> choices = new ArrayList();
20-
for (int i = 0; i < MemoryBlockList.length; i++) { if (MemoryBlockList[i].isOverlay()) choices.add(MemoryBlockList[i].getName()); }
21-
List<String> filterList = askChoices("Title", "Message", choices);
22-
List<String> choiceList = new ArrayList();
23-
for (String e : choices) { choiceList.add(e + "::"); choiceList.add(e + "__"); }
18+
List<String> options = this.getMemoryBlockOptions();
19+
List<String> filterList = askChoices("Title", "Message", options);
20+
List<String> choiceList = this.getOptionList(options);
2421

2522
List<String> symbols = new ArrayList<String>();
2623
SymbolTable st = state.getCurrentProgram().getSymbolTable();
@@ -31,15 +28,28 @@ public void run() throws Exception {
3128
String name = sym.getName(true);
3229

3330
boolean hasFilter = true;
34-
for (String s : filterList) { if (add.toString().contains(s)) { hasFilter = false; break; } }
31+
for (String s : filterList) {
32+
if (add.toString().contains(s)) {
33+
hasFilter = false;
34+
break;
35+
}
36+
}
3537
if (hasFilter)
3638
{
3739
boolean isNext = false;
38-
for (String s : choiceList) { if (add.toString().contains(s)) { isNext = true; break; } }
39-
if (isNext) continue;
40+
for (String s : choiceList) {
41+
if (add.toString().contains(s)) {
42+
isNext = true;
43+
break;
44+
}
45+
}
46+
if (isNext)
47+
continue;
4048
}
4149

4250
symbols.add(String.format("%08x %s", add.getOffset(), name));
51+
// symbols.add(String.format("%s %s", add, name));
52+
// println(String.format("%s %s", add, name));
4353
}
4454

4555
HttpClient client = HttpClient.newHttpClient();
@@ -50,6 +60,26 @@ public void run() throws Exception {
5060

5161
client.send(request, HttpResponse.BodyHandlers.ofString());
5262

63+
// for (String address : symbols) println(address);
5364
println("size: " + symbols.size());
5465
}
66+
67+
private List<String> getMemoryBlockOptions() {
68+
MemoryBlock[] MemoryBlockList = state.getCurrentProgram().getMemory().getBlocks();
69+
List<String> options = new ArrayList();
70+
for (int i = 0; i < MemoryBlockList.length; i++) {
71+
if (MemoryBlockList[i].isOverlay())
72+
options.add(MemoryBlockList[i].getName());
73+
}
74+
return options;
75+
}
76+
77+
private List<String> getOptionList(List<String> options) {
78+
List<String> resultList = new ArrayList();
79+
for (String e : options) {
80+
resultList.add(e + "::");
81+
resultList.add(e + "__");
82+
}
83+
return resultList;
84+
}
5585
}

0 commit comments

Comments
 (0)