mirror of
https://github.com/pret/pokeplatinum.git
synced 2026-04-26 00:32:20 -05:00
partial overlay breakpoint support via GDB
This commit is contained in:
parent
7f68c4e93d
commit
133f80ac2b
|
|
@ -36,7 +36,7 @@ For contacts and other pret projects, see [pret.github.io](https://pret.github.i
|
|||
},
|
||||
{
|
||||
"description": "Set architecture",
|
||||
"text": "set architecture auto"
|
||||
"text": "set architecture armv5te"
|
||||
},
|
||||
{
|
||||
"description": "Enable overlays",
|
||||
|
|
@ -52,4 +52,6 @@ For contacts and other pret projects, see [pret.github.io](https://pret.github.i
|
|||
|
||||
3. Launch melonDS with GDB stub enabled and launch the pokeplatinum ROM (you may need to fiddle with the config file to make this work, melonDS GDB stub config is off and may not actually enable properly through the UI)
|
||||
|
||||
4. Run debugger through VS Code, it should connect to melonDS automatically.
|
||||
4. Run debugger through VS Code, it should connect to melonDS automatically.
|
||||
|
||||
5. Pause the debugger and run `-exec overlay section-map build/overlay.map` (this cannot currently be included in setupCommands due to issues with architecture loading).
|
||||
2
build.sh
2
build.sh
|
|
@ -21,7 +21,7 @@ export MESON_RSP_THRESHOLD=16387
|
|||
if [ "$target" = test ]; then
|
||||
"${MESON:-meson}" test -C build "$@"
|
||||
elif [ "$target" = rom ]; then
|
||||
"${MESON:-meson}" compile -C build "pokeplatinum.us.nds" "debug.nef"
|
||||
"${MESON:-meson}" compile -C build "pokeplatinum.us.nds" "debug.nef" "overlay.map"
|
||||
else
|
||||
"${MESON:-meson}" compile -C build "$target" "$@"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -16,14 +16,13 @@ BOOL Overlay_LoadByID(const FSOverlayID param0, int param1);
|
|||
typedef struct {
|
||||
unsigned long vma;
|
||||
unsigned long size;
|
||||
unsigned long lma;
|
||||
FSOverlayID ovly_id;
|
||||
unsigned long mapped;
|
||||
} struct_overlayTable;
|
||||
|
||||
#define MAX_OVERLAYS 128
|
||||
|
||||
extern unsigned long _novlys;
|
||||
extern const char _ovly_name[];
|
||||
extern struct_overlayTable _ovly_table[MAX_OVERLAYS];
|
||||
|
||||
static void _ovly_debug_event(void);
|
||||
|
|
|
|||
15
meson.build
15
meson.build
|
|
@ -229,7 +229,7 @@ pokeplatinum_nds = custom_target('pokeplatinum.us.nds',
|
|||
)
|
||||
|
||||
############################################################
|
||||
### NEF FIXER ###
|
||||
### GDB HELPERS ###
|
||||
############################################################
|
||||
nef_fixer = custom_target('debug.nef',
|
||||
output: [
|
||||
|
|
@ -244,6 +244,19 @@ nef_fixer = custom_target('debug.nef',
|
|||
build_by_default: true
|
||||
)
|
||||
|
||||
ovly_mapper = custom_target('overlay.map',
|
||||
output: [
|
||||
'overlay.map'
|
||||
],
|
||||
input: [
|
||||
main_lsf
|
||||
],
|
||||
command : [
|
||||
overlay_mapper_py, '@INPUT@', '@OUTPUT@'
|
||||
],
|
||||
build_by_default: true
|
||||
)
|
||||
|
||||
|
||||
############################################################
|
||||
### TESTS ###
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ BOOL Overlay_LoadByID(const FSOverlayID param0, int param1);
|
|||
static UnkStruct_021BF370 Unk_021BF370;
|
||||
|
||||
/* Added to support GDB overlay debugging. */
|
||||
const char _ovly_name[] = "overlay%d";
|
||||
unsigned long _novlys = MAX_OVERLAYS;
|
||||
struct_overlayTable _ovly_table[MAX_OVERLAYS] = {};
|
||||
static void _ovly_debug_event(void) {}
|
||||
|
|
@ -48,25 +47,26 @@ void UnloadOverlayGDB(const FSOverlayID overlayID)
|
|||
void LoadOverlayGDB(const FSOverlayID overlayID)
|
||||
{
|
||||
FSOverlayInfo overlayInfo;
|
||||
FSFileID fileInfo;
|
||||
|
||||
// dummies to force symbols to exist
|
||||
// dummy to force symbols to exist
|
||||
GF_ASSERT(overlayID < _novlys);
|
||||
strcmp(_ovly_name, _ovly_name);
|
||||
|
||||
if(_ovly_table[overlayID].mapped != 0) return;
|
||||
|
||||
// 1. fetch overlay info to identify vma/lma
|
||||
// 1. fetch overlay info to identify vma
|
||||
GF_ASSERT(FS_LoadOverlayInfo(&overlayInfo, MI_PROCESSOR_ARM9, overlayID) == TRUE);
|
||||
fileInfo = FS_GetOverlayFileID(&overlayInfo);
|
||||
|
||||
// 2. add entry to _ovly_table
|
||||
// note that this is a little hacky. the VMA is correct but the LMA is not exposed by the OverlayManager
|
||||
// and the size field is not correct compared to what's stored in the NEF.
|
||||
// the standard overlay manager in GDB bases comparisons on VMA and LMA, so it's not viable here.
|
||||
// requires a custom GDB build which uses section name and which can override section size.
|
||||
// requires a custom GDB build which uses overlay mappings and which can override section size.
|
||||
// see https://github.com/joshua-smith-12/binutils-gdb-nds
|
||||
_ovly_table[overlayID].vma = overlayInfo.header.ram_address;
|
||||
_ovly_table[overlayID].lma = 0;
|
||||
_ovly_table[overlayID].size = overlayInfo.header.ram_size;
|
||||
_ovly_table[overlayID].ovly_id = overlayID;
|
||||
_ovly_table[overlayID].size = overlayInfo.header.ram_size;
|
||||
_ovly_table[overlayID].mapped = 1;
|
||||
_ovly_debug_event();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,4 +10,5 @@ make_species_tables_py = find_program('make_species_tables.py', native: true)
|
|||
make_tutorable_moves_py = find_program('make_tutorable_moves.py', native: true)
|
||||
make_pokedex_data_py = find_program('make_pokedex_data.py', native: true)
|
||||
make_pokedex_message_banks_py = find_program('make_pokedex_message_banks.py', native: true)
|
||||
nef_fixer_py = find_program('nef_fixer.py', native: true)
|
||||
nef_fixer_py = find_program('nef_fixer.py', native: true)
|
||||
overlay_mapper_py = find_program('overlay_mapper.py', native: true)
|
||||
58
tools/scripts/overlay_mapper.py
Normal file
58
tools/scripts/overlay_mapper.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
try:
|
||||
os.remove("overlay.map")
|
||||
except:
|
||||
pass
|
||||
|
||||
source = sys.argv[1]
|
||||
dest = sys.argv[2]
|
||||
|
||||
# TERRIBLE but necessary to allow using the LSF file
|
||||
def base_path(path):
|
||||
splitted = path.split("_")
|
||||
maybe_path = ""
|
||||
found_dir = ".." # need to escape builddir because this sucks
|
||||
while len(splitted) > 1:
|
||||
segment = splitted[0]
|
||||
splitted = splitted[1:]
|
||||
maybe_path += segment
|
||||
if os.path.isdir(found_dir + "/" + maybe_path):
|
||||
found_dir = found_dir + "/" + maybe_path
|
||||
maybe_path = ""
|
||||
else:
|
||||
maybe_path += "_"
|
||||
maybe_path += splitted[0]
|
||||
return maybe_path[:-2] # remove '.o'
|
||||
|
||||
# VERY inflexible parsing!
|
||||
overlays = {}
|
||||
sources = {}
|
||||
overlay_index = 0
|
||||
current_overlay = None
|
||||
in_block = False
|
||||
with open(source) as f:
|
||||
for line in f.readlines():
|
||||
if current_overlay == None and not in_block and line.strip().startswith("Overlay"):
|
||||
current_overlay = line.strip().replace("Overlay ", "")
|
||||
overlays[current_overlay] = overlay_index
|
||||
overlay_index += 1
|
||||
elif not in_block and line.strip() == "{":
|
||||
in_block = True
|
||||
elif in_block and line.strip() == "}":
|
||||
in_block = False
|
||||
current_overlay = None
|
||||
elif current_overlay != None and in_block and line.strip().startswith("Object"):
|
||||
obj_name = base_path(line.strip().replace("Object ", "").split("/")[-1])
|
||||
sources[obj_name] = current_overlay
|
||||
|
||||
with open(dest, mode="w") as f:
|
||||
for ovly in overlays:
|
||||
f.write(f"OVERLAY {ovly}:{overlays[ovly]}\n")
|
||||
f.write("\n")
|
||||
for s in sources:
|
||||
f.write(f"SOURCE {s}:{sources[s]}\n")
|
||||
Loading…
Reference in New Issue
Block a user