Skip to content

Commit b39e684

Browse files
authored
debugger: symlist usability + symbol table extensibility (#13694)
Address issue #6655 (symlist command usability), add a bit of plumbing for future extensibility. symlist with no arguments displays all global *and* :maincpu symbols, with clear header text for each list. At the bottom, prints helper text to make user aware of the cpu form To allow for adding new kinds of symbols in the future, this adds an enum field to symbol table for its 'type', for prettier printing from symlist. Symlist now traverses symbol table chain completely.
1 parent efb84a4 commit b39e684

File tree

6 files changed

+78
-44
lines changed

6 files changed

+78
-44
lines changed

src/emu/debug/debugcmd.cpp

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3909,58 +3909,80 @@ void debugger_commands::execute_memdump(const std::vector<std::string_view> &par
39093909

39103910
void debugger_commands::execute_symlist(const std::vector<std::string_view> &params)
39113911
{
3912-
const char *namelist[1000];
3912+
// Default to CPU "0" if none specified
3913+
const char * cpuname = (params.empty()) ? "0" : params[0].cbegin();
3914+
device_t *cpu = nullptr;
39133915
symbol_table *symtable;
3914-
int count = 0;
3915-
3916-
if (!params.empty())
3916+
if (!m_console.validate_cpu_parameter(cpuname, cpu))
39173917
{
3918-
// validate parameters
3919-
device_t *cpu;
3920-
if (!m_console.validate_cpu_parameter(params[0], cpu))
3921-
return;
3922-
symtable = &cpu->debug()->symtable();
3923-
m_console.printf("CPU '%s' symbols:\n", cpu->tag());
3918+
if (!params.empty())
3919+
return; // Explicitly specified cpu is invalid
3920+
3921+
// Somehow cpu "0" is invalid, so just stick with global symbol table
3922+
symtable = &m_machine.debugger().cpu().global_symtable();
39243923
}
39253924
else
39263925
{
3927-
symtable = &m_machine.debugger().cpu().global_symtable();
3928-
m_console.printf("Global symbols:\n");
3926+
symtable = &cpu->debug()->symtable();
39293927
}
39303928

3931-
// gather names for all symbols
3932-
for (auto &entry : symtable->entries())
3929+
// Traverse symbol_table parent chain, printing each table's symbols in its own block
3930+
for (; symtable != nullptr; symtable = symtable->parent())
39333931
{
3934-
// only display "register" type symbols
3935-
if (!entry.second->is_function())
3932+
// Skip globals if user explicitly requested CPU
3933+
if (symtable->type() == symbol_table::BUILTIN_GLOBALS && !params.empty())
3934+
continue;
3935+
3936+
if (symtable->entries().size() == 0)
3937+
continue;
3938+
3939+
std::vector<const char *> namelist;
3940+
3941+
// Print heading for table
3942+
switch (symtable->type())
39363943
{
3937-
namelist[count++] = entry.second->name();
3938-
if (count >= std::size(namelist))
3939-
break;
3944+
case symbol_table::CPU_STATE:
3945+
m_console.printf("\n**** CPU '%s' symbols ****\n", cpu->tag());
3946+
break;
3947+
case symbol_table::BUILTIN_GLOBALS:
3948+
m_console.printf("\n**** Global symbols ****\n");
3949+
break;
3950+
default:
3951+
assert (!"Unrecognized symbol table type");
39403952
}
3941-
}
39423953

3943-
// sort the symbols
3944-
if (count > 1)
3945-
{
3954+
// gather names for all relevant symbols
3955+
for (auto &entry : symtable->entries())
3956+
{
3957+
// ignore built-in function symbols
3958+
if (!entry.second->is_function())
3959+
{
3960+
namelist.push_back(entry.second->name());
3961+
}
3962+
}
3963+
3964+
// sort the symbols
39463965
std::sort(
3947-
&namelist[0],
3948-
&namelist[count],
3966+
namelist.begin(),
3967+
namelist.end(),
39493968
[] (const char *item1, const char *item2) { return strcmp(item1, item2) < 0; });
3950-
}
39513969

3952-
// iterate over symbols and print out relevant ones
3953-
for (int symnum = 0; symnum < count; symnum++)
3970+
// iterate over symbols and print them
3971+
for (const char * symname : namelist)
3972+
{
3973+
symbol_entry const *const entry = symtable->find(symname);
3974+
assert(entry != nullptr);
3975+
m_console.printf("%s = %X", symname, entry->value());
3976+
if (!entry->is_lval())
3977+
m_console.printf(" (read-only)");
3978+
m_console.printf("\n");
3979+
}
3980+
}
3981+
if (params.empty())
39543982
{
3955-
symbol_entry const *const entry = symtable->find(namelist[symnum]);
3956-
assert(entry != nullptr);
3957-
u64 value = entry->value();
3958-
3959-
// only display "register" type symbols
3960-
m_console.printf("%s = %X", namelist[symnum], value);
3961-
if (!entry->is_lval())
3962-
m_console.printf(" (read-only)");
3963-
m_console.printf("\n");
3983+
m_console.printf(
3984+
"\nTo view the symbols for a particular CPU, try symlist <cpu>,\n"
3985+
"where <cpu> is the ID number or tag for a CPU.\n");
39643986
}
39653987
}
39663988

src/emu/debug/debugcpu.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ debugger_cpu::debugger_cpu(running_machine &machine)
5757
m_tempvar = make_unique_clear<u64[]>(NUM_TEMP_VARIABLES);
5858

5959
/* create a global symbol table */
60-
m_symtable = std::make_unique<symbol_table>(machine);
60+
m_symtable = std::make_unique<symbol_table>(machine, symbol_table::BUILTIN_GLOBALS);
6161
m_symtable->set_memory_modified_func([this]() { set_memory_modified(true); });
6262

6363
/* add "wpaddr", "wpdata", "wpsize" to the global symbol table */
@@ -488,7 +488,7 @@ device_debug::device_debug(device_t &device)
488488
, m_state(nullptr)
489489
, m_disasm(nullptr)
490490
, m_flags(0)
491-
, m_symtable(std::make_unique<symbol_table>(device.machine(), &device.machine().debugger().cpu().global_symtable(), &device))
491+
, m_symtable(std::make_unique<symbol_table>(device.machine(), symbol_table::CPU_STATE, &device.machine().debugger().cpu().global_symtable(), &device))
492492
, m_stepaddr(0)
493493
, m_stepsleft(0)
494494
, m_delay_steps(0)

src/emu/debug/express.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,9 @@ symbol_entry::~symbol_entry()
363363
// symbol_table - constructor
364364
//-------------------------------------------------
365365

366-
symbol_table::symbol_table(running_machine &machine, symbol_table *parent, device_t *device)
366+
symbol_table::symbol_table(running_machine &machine, table_type type, symbol_table *parent, device_t *device)
367367
: m_machine(machine)
368+
, m_type(type)
368369
, m_parent(parent)
369370
, m_memintf(dynamic_cast<device_memory_interface *>(device))
370371
, m_memory_modified(nullptr)

src/emu/debug/express.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,21 @@ class symbol_table
171171
READ_WRITE
172172
};
173173

174+
// Identifies the type of symbols stored in this table. These help symlist create
175+
// useful output
176+
enum table_type
177+
{
178+
CPU_STATE, // CPU registers, etc.
179+
BUILTIN_GLOBALS, // Built-in MAME global symbols (e.g., beamx, beamy, frame, etc.)
180+
// (also used for tables outside debugger: lua scripts, cheat engine)
181+
};
182+
174183
// construction/destruction
175-
symbol_table(running_machine &machine, symbol_table *parent = nullptr, device_t *device = nullptr);
184+
symbol_table(running_machine &machine, table_type type, symbol_table *parent = nullptr, device_t *device = nullptr);
176185

177186
// getters
178187
const std::unordered_map<std::string, std::unique_ptr<symbol_entry>> &entries() const { return m_symlist; }
188+
table_type type() const { return m_type; }
179189
symbol_table *parent() const { return m_parent; }
180190
running_machine &machine() { return m_machine; }
181191

@@ -212,6 +222,7 @@ class symbol_table
212222

213223
// internal state
214224
running_machine & m_machine; // reference to the machine
225+
table_type m_type; // kind of symbols stored in this table
215226
symbol_table * m_parent; // pointer to the parent symbol table
216227
std::unordered_map<std::string,std::unique_ptr<symbol_entry>> m_symlist; // list of symbols
217228
device_memory_interface *const m_memintf; // pointer to the local memory interface (if any)

src/frontend/mame/cheat.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ void cheat_script::script_entry::output_argument::save(util::core_file &cheatfil
683683

684684
cheat_entry::cheat_entry(cheat_manager &manager, symbol_table &globaltable, std::string const &filename, util::xml::data_node const &cheatnode)
685685
: m_manager(manager)
686-
, m_symbols(manager.machine(), &globaltable)
686+
, m_symbols(manager.machine(), symbol_table::BUILTIN_GLOBALS, &globaltable)
687687
, m_state(SCRIPT_STATE_OFF)
688688
, m_numtemp(DEFAULT_TEMP_VARIABLES)
689689
, m_argindex(0)
@@ -1065,7 +1065,7 @@ cheat_manager::cheat_manager(running_machine &machine)
10651065
, m_numlines(0)
10661066
, m_lastline(0)
10671067
, m_disabled(true)
1068-
, m_symtable(machine)
1068+
, m_symtable(machine, symbol_table::BUILTIN_GLOBALS)
10691069
{
10701070
// if the cheat engine is disabled, we're done
10711071
if (!machine.options().cheat())

src/frontend/mame/luaengine_debug.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class lua_engine::symbol_table_wrapper
9191

9292
symbol_table_wrapper(lua_engine &host, running_machine &machine, std::shared_ptr<symbol_table_wrapper> const &parent, device_t *device)
9393
: m_host(host)
94-
, m_table(machine, parent ? &parent->table() : nullptr, device)
94+
, m_table(machine, symbol_table::BUILTIN_GLOBALS, parent ? &parent->table() : nullptr, device)
9595
, m_parent(parent)
9696
{
9797
}

0 commit comments

Comments
 (0)