Added File.c, added Tex.h,

added KuonMenu.h, Menu.h, Cdvd.h

Added missing struct defines, missing function defines
Implement File
This commit is contained in:
2026-08-03 17:41:47 -05:00
committed by Timothy O'Barr
parent b9a30026a0
commit 183a42e7e0
12 changed files with 705 additions and 11 deletions
+1 -1
View File
@@ -249,7 +249,7 @@ segments:
- [0x032110, asmtu, cs4/Seimei/src/Camera]
- [0x034930, asmtu, cs4/Seimei/src/Debug]
- [0x034D10, asmtu, cs4/Seimei/src/Draw]
- [0x038710, asmtu, cs4/Seimei/src/File]
- [0x038710, c, cs4/Seimei/src/File]
- [0x038D00, asmtu, cs4/Seimei/src/Game]
- [0x039A00, asmtu, cs4/Seimei/src/Load]
- [0x03A380, c, cs4/Seimei/src/Main]
+1 -1
View File
@@ -101,7 +101,7 @@ def make_compiler_cmd(config_dir: Path, src_path: Path, language: str):
game_cc_dir = f"{tools_dir}/cc/{COMPILER}"
compiler_includes = f"-I{src_path.parent / 'src'} -I{src_path.parent / 'include'} -Iinclude/sdk/ee"
compiler_includes = f"-I{src_path.parent / 'src'} -I{src_path.parent / 'include'} -Iinclude/sdk/ee -I../src/cs4/Seimei/fslib"
assembler_includes = f"-I{src_path.parent / 'include'} -I{src_path.parent}"
common_includes = f"{compiler_includes} {assembler_includes}"
game_compile_cmd = f"{WIBO} {game_cc_dir}/mwccps2.exe -c {common_includes} {COMPILER_FLAGS}"
+6
View File
@@ -0,0 +1,6 @@
#ifndef FSFONT_H
#define FSFONT_H
signed int FsFontSetTexBuf(signed int id /* r2 */, void * pTexFileBuf /* r2 */);
#endif // FSFONT_H
+115
View File
@@ -0,0 +1,115 @@
#ifndef CDVD_H
#define CDVD_H
/*
Compile unit: C:\cs4\Seimei\src\Cdvd.c
Producer: MW MIPS C Compiler
Language: C
*/
static // total size: 0x14C
struct /* @anon1 */ {
// Members
// total size: 0x24
struct /* @anon0 */ {
// Members
unsigned int lsn; // offset 0x0, size 0x4
unsigned int size; // offset 0x4, size 0x4
char name[16]; // offset 0x8, size 0x10
unsigned char date[8]; // offset 0x18, size 0x8
unsigned int flag; // offset 0x20, size 0x4
} cdlfile; // offset 0x0, size 0x24
char fname[128]; // offset 0x24, size 0x80
char sname[128]; // offset 0xA4, size 0x80
signed int state; // offset 0x124, size 0x4
signed int fileType; // offset 0x128, size 0x4
signed int index; // offset 0x12C, size 0x4
signed int fhd; // offset 0x130, size 0x4
signed int size; // offset 0x134, size 0x4
signed int sector; // offset 0x138, size 0x4
unsigned int align; // offset 0x13C, size 0x4
unsigned char retry; // offset 0x140, size 0x1
unsigned char unused[3]; // offset 0x141, size 0x3
unsigned char * * lplpAddr; // offset 0x144, size 0x4
unsigned char * lpDmyData; // offset 0x148, size 0x4
} * lpSetCdvd; // size: 0x4, address: 0x257560
static // total size: 0x14C
struct /* @anon1 */ {
// Members
// total size: 0x24
struct /* @anon0 */ {
// Members
unsigned int lsn; // offset 0x0, size 0x4
unsigned int size; // offset 0x4, size 0x4
char name[16]; // offset 0x8, size 0x10
unsigned char date[8]; // offset 0x18, size 0x8
unsigned int flag; // offset 0x20, size 0x4
} cdlfile; // offset 0x0, size 0x24
char fname[128]; // offset 0x24, size 0x80
char sname[128]; // offset 0xA4, size 0x80
signed int state; // offset 0x124, size 0x4
signed int fileType; // offset 0x128, size 0x4
signed int index; // offset 0x12C, size 0x4
signed int fhd; // offset 0x130, size 0x4
signed int size; // offset 0x134, size 0x4
signed int sector; // offset 0x138, size 0x4
unsigned int align; // offset 0x13C, size 0x4
unsigned char retry; // offset 0x140, size 0x1
unsigned char unused[3]; // offset 0x141, size 0x3
unsigned char * * lplpAddr; // offset 0x144, size 0x4
unsigned char * lpDmyData; // offset 0x148, size 0x4
} * lpLastCdvd; // size: 0x4, address: 0x257564
static // total size: 0x14C
struct /* @anon1 */ {
// Members
// total size: 0x24
struct /* @anon0 */ {
// Members
unsigned int lsn; // offset 0x0, size 0x4
unsigned int size; // offset 0x4, size 0x4
char name[16]; // offset 0x8, size 0x10
unsigned char date[8]; // offset 0x18, size 0x8
unsigned int flag; // offset 0x20, size 0x4
} cdlfile; // offset 0x0, size 0x24
char fname[128]; // offset 0x24, size 0x80
char sname[128]; // offset 0xA4, size 0x80
signed int state; // offset 0x124, size 0x4
signed int fileType; // offset 0x128, size 0x4
signed int index; // offset 0x12C, size 0x4
signed int fhd; // offset 0x130, size 0x4
signed int size; // offset 0x134, size 0x4
signed int sector; // offset 0x138, size 0x4
unsigned int align; // offset 0x13C, size 0x4
unsigned char retry; // offset 0x140, size 0x1
unsigned char unused[3]; // offset 0x141, size 0x3
unsigned char * * lplpAddr; // offset 0x144, size 0x4
unsigned char * lpDmyData; // offset 0x148, size 0x4
} * lpCdvdRead; // size: 0x4, address: 0x257568
// total size: 0x14C
struct /* @anon1 */ {
// Members
// total size: 0x24
struct /* @anon0 */ {
// Members
unsigned int lsn; // offset 0x0, size 0x4
unsigned int size; // offset 0x4, size 0x4
char name[16]; // offset 0x8, size 0x10
unsigned char date[8]; // offset 0x18, size 0x8
unsigned int flag; // offset 0x20, size 0x4
} cdlfile; // offset 0x0, size 0x24
char fname[128]; // offset 0x24, size 0x80
char sname[128]; // offset 0xA4, size 0x80
signed int state; // offset 0x124, size 0x4
signed int fileType; // offset 0x128, size 0x4
signed int index; // offset 0x12C, size 0x4
signed int fhd; // offset 0x130, size 0x4
signed int size; // offset 0x134, size 0x4
signed int sector; // offset 0x138, size 0x4
unsigned int align; // offset 0x13C, size 0x4
unsigned char retry; // offset 0x140, size 0x1
unsigned char unused[3]; // offset 0x141, size 0x3
unsigned char * * lplpAddr; // offset 0x144, size 0x4
unsigned char * lpDmyData; // offset 0x148, size 0x4
} CdvdReadSt[256]; // size: 0x14C00, address: 0xA01200
unsigned int GlobalLoadTimer; // size: 0x4, address: 0x257894
#endif // CDVD_H
+217 -9
View File
@@ -1,19 +1,227 @@
#include "File.h"
#include "Cdvd.h"
#include "Game.h"
#include "Model.h"
#include "Tex.h"
#include "Unk.h"
#include "common.h"
#include "lib/FsFont.h"
#include "menu/KuonMenu.h"
#include "menu/Menu.h"
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", AfterFileReadFunc);
unsigned char ScePath[128]; // size: 0x80, address: 0x3254B0
unsigned char RootPath[128]; // size: 0x80, address: 0x325530
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", FileCheckAsyncBusy);
void AfterFileReadFunc(u8 *lpAddr, s32 index, s32 fileType, s32 size) {
switch (fileType) {
case 0x0:
case 0x80:
RemapBinderFile(lpAddr);
SetMdlBndFile(index);
if (GameSt.GameMode != 4) {
if (index == 0) {
MyAppear(0, &MdlMng[0xA0], VW, 0.0f);
}
if ((GameSt.PlayerId != 2) && (index == 0x10E)) {
InitMyWeapon(GameSt.PlayerId);
break;
}
}
break;
case 0x1:
RemapCamData(lpAddr);
break;
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", FileBackReadControl);
case 0x2:
RemapMapFile(lpAddr);
ReadMapMdlFile(lpAddr);
break;
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", FileReadControl);
case 0x3:
break;
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", FileRead);
case 0x4:
break;
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", InitFileRead);
case 0x5:
RemapMdlLink(lpAddr);
SetMdlData(index, lpAddr);
break;
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", GetRootPath);
case 0x6:
RemapMdlLink(lpAddr);
SetTexList(lpAddr, 2);
break;
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", ReadRootPath);
case 0x7:
RemapMdlLink(lpAddr);
SetTexList(lpAddr, 2);
FsFontSetTexBuf(2,
GetTexMngByName(GetGameTexList(), "iconfont.tm2")->lpTm2);
ItemMng_CallBack_FinishLoadFile_ItemList();
break;
INCLUDE_ASM("config/asm/nonmatchings/cs4/Seimei/src/File", InitFileSystem);
case 0x8:
RemapMdlLink(lpAddr);
SetTexList(lpAddr, 1);
SetMapTexListFile(index);
break;
case 0x9:
RemapMdlLink(lpAddr);
SetAniData(index, lpAddr);
break;
case 0xA:
RemapMdlLink(lpAddr);
SetHdlData(index, lpAddr);
break;
case 0xB:
RemapMdlLink(lpAddr);
SetSdlData(index, lpAddr);
break;
case 0xC:
break;
case 0xD:
RemapBinderFile(lpAddr);
Rta_BndReadEndCallBack();
break;
case 0xE:
break;
case 0x11:
RemapMdlLink(lpAddr);
SetTexList(lpAddr, 1);
break;
case 0xF:
break;
case 0x10:
RemapBinderFile(lpAddr);
if ((Menu_GetLastReloadType() & 0xFFFF) == 0x8000) {
Menu_FileReadCallBack(0x8000);
KnMenuMng_ReMakeMenu(KUON_MENU__MAKE_TITLE);
break;
}
if ((Menu_GetLastReloadType(0x8000) & 0xFFFF) == 0x4000) {
Menu_FileReadCallBack(KUON_MENU_RELOAD_FLAG_GAME);
KnMenuMng_ReMakeMenu(KUON_MENU__MAKE_GAME);
SetFixMemoryEndIndex();
break;
}
break;
case 0x12:
SetScript(size, lpAddr);
break;
case 0x13:
break;
case 0x14:
break;
case 0x81:
break;
case 0x15:
RemapDramaData(lpAddr);
if (index != 0) {
SetDramaData();
break;
}
break;
case 0x16:
SND_LoadSecFromFileInMemory(index & 0xFF, lpAddr);
break;
case 0x21:
SND_LoadRandSeFromFileInMemory(lpAddr);
break;
case 0x17:
RemapBinderFile(lpAddr);
break;
case 0x18:
SND_SqPrepare();
break;
case 0x19:
SetSceneBndFile();
break;
case 0x1A:
break;
case 0x1B:
SfxFIO_CallBack_FinishLoadSfxBindFile();
break;
case 0x1C:
break;
case 0x1D:
SetRiddleData();
break;
case 0x1E:
break;
case 0x1F:
RemapMiz(lpAddr);
break;
case 0x20:
break;
case 0x82:
break;
}
return;
}
int FileCheckAsyncBusy(void) { return CdvdCheckAsyncBusy(); }
void FileBackReadControl(void) { CdvdBackReadProc(); }
void FileReadControl(int bDraw) { CdvdAsyncProc(bDraw); }
signed int FileRead(char *filename /* r2 */, signed int size /* r2 */,
unsigned char **lpBuf /* r2 */,
unsigned char bSynch /* r2 */, signed int index /* r2 */,
signed int filetype /* r2 */, unsigned int align /* r2 */) {
return CdvdRead(filename, size, lpBuf, bSynch, index, filetype, align);
}
void InitFileRead(void) { InitCdvdRead(); }
unsigned char *GetRootPath() { return RootPath; }
void ReadRootPath() {
memset(RootPath, 0, 0x80);
memset(ScePath, 0, 0x80);
sprintf((char *)RootPath, "cdrom0:\\");
sprintf((char *)ScePath, "cdrom0:\\");
}
void InitFileSystem() {
/* anonymous block */
// Range: 0x138C20 -> 0x138C78
sceSifInitRpc(0);
sceSifInitIopHeap();
sceSifLoadFileReset();
sceFsReset();
while (!sceCdInit(0)) {
}
sceCdMmode(2);
}
+3
View File
@@ -1,6 +1,9 @@
#ifndef FILE_H
#define FILE_H
extern unsigned char ScePath[128]; // size: 0x80, address: 0x3254B0
extern unsigned char RootPath[128]; // size: 0x80, address: 0x325530
void InitFileRead();
void InitFileSystem();
void ReadRootPath();
+1
View File
@@ -52,4 +52,5 @@ extern GameState GameSt; // size: 0x30, address: 0x3A5E10
int GameLoop();
void InitGameData();
void InitGameDataAfterLoad();
void * GetGameTexList();
#endif // GAME_H
+68
View File
@@ -0,0 +1,68 @@
#ifndef TEX_H
#define TEX_H
/*
Compile unit: C:\cs4\Seimei\src\Tex.c
Producer: MW MIPS C Compiler
Language: C
Code range: 0x0013FA80 -> 0x0013FB18
*/
// Range: 0x13FA80 -> 0x13FB18
// total size: 0x60
struct /* @anon0 */ {
// Members
unsigned char bUse; // offset 0x0, size 0x1
unsigned char unused0; // offset 0x1, size 0x1
unsigned short id; // offset 0x2, size 0x2
// total size: 0x20
struct /* @anon1 */ {
// Members
unsigned int size; // offset 0x0, size 0x4
unsigned int wnum; // offset 0x4, size 0x4
unsigned char dummy[5]; // offset 0x8, size 0x5
unsigned char compare; // offset 0xD, size 0x1
unsigned short tex_id; // offset 0xE, size 0x2
// total size: 0x8
struct /* @anon5 */ {
// Members
unsigned long TBP0 : 14; // offset 0x0, size 0x4
unsigned long TBW : 6; // offset 0x0, size 0x4
unsigned long PSM : 6; // offset 0x0, size 0x4
unsigned long TW : 4; // offset 0x0, size 0x4
unsigned long TH : 4; // offset 0x0, size 0x4
unsigned long TCC : 1; // offset 0x0, size 0x4
unsigned long TFX : 2; // offset 0x0, size 0x4
unsigned long CBP : 14; // offset 0x0, size 0x4
unsigned long CPSM : 4; // offset 0x0, size 0x4
unsigned long CSM : 1; // offset 0x0, size 0x4
unsigned long CSA : 5; // offset 0x0, size 0x4
unsigned long CLD : 3; // offset 0x0, size 0x4
} tex0; // offset 0x10, size 0x8
// total size: 0x8
struct /* @anon7 */ {
// Members
unsigned long LCM : 1; // offset 0x0, size 0x4
unsigned long pad01 : 1; // offset 0x0, size 0x4
unsigned long MXL : 3; // offset 0x0, size 0x4
unsigned long MMAG : 1; // offset 0x0, size 0x4
unsigned long MMIN : 3; // offset 0x0, size 0x4
unsigned long MTBA : 1; // offset 0x0, size 0x4
unsigned long pad10 : 9; // offset 0x0, size 0x4
unsigned long L : 2; // offset 0x0, size 0x4
unsigned long pad21 : 11; // offset 0x0, size 0x4
unsigned long K : 12; // offset 0x0, size 0x4
unsigned long pad44 : 20; // offset 0x0, size 0x4
} tex1; // offset 0x18, size 0x8
} * lpTm2; // offset 0x4, size 0x4
void * lpTexList; // offset 0x8, size 0x4
signed int unused1[1]; // offset 0xC, size 0x4
unsigned char texName[32]; // offset 0x10, size 0x20
unsigned char texNameBase[32]; // offset 0x30, size 0x20
signed int texW; // offset 0x50, size 0x4
signed int texH; // offset 0x54, size 0x4
signed int texTBW; // offset 0x58, size 0x4
signed int texPSM; // offset 0x5C, size 0x4
} * GetTexMngByName(void * lpTexList /* r18 */, char * texname /* r17 */);
#endif // TEX_H
+2
View File
@@ -31,6 +31,8 @@ extern struct /* @anon0 */ {
unsigned short cam_id; // offset 0x6, size 0x2
}* lpSceneLoad; // size: 0x4, address: 0x257530
static float VZ[4]; // size: 0x10, address: 0x228720
static float VW[4]; // size: 0x10, address: 0x228730
#endif // UNK_H
+24
View File
@@ -0,0 +1,24 @@
#ifndef KUONMENU_H
#define KUONMENU_H
enum _KUON_MENU__RELOAD_FLAG_EN {
KUON_MENU_RELOAD_FLAG_NONE = 0,
KUON_MENU_RELOAD_FLAG_TITLE_ = 1,
KUON_MENU_RELOAD_FLAG_START = 2,
KUON_MENU_RELOAD_FLAG_MAIN = 4,
KUON_MENU_RELOAD_FLAG_SAVE = 8,
KUON_MENU_RELOAD_FLAG_LOAD = 16,
KUON_MENU_RELOAD_FLAG_DEAD = 32,
KUON_MENU_RELOAD_FLAG_MM_TOP = 64,
KUON_MENU_RELOAD_FLAG_MM_EQUIP = 128,
KUON_MENU_RELOAD_FLAG_MM_ITEM = 256,
KUON_MENU_RELOAD_FLAG_MM_BOOK = 512,
KUON_MENU_RELOAD_FLAG_MM_MAP = 1024,
KUON_MENU_RELOAD_FLAG_MM_SET = 2048,
KUON_MENU_RELOAD_FLAG_MM_END = 4096,
KUON_MENU_RELOAD_FLAG_DOC = 8192,
KUON_MENU_RELOAD_FLAG_GAME = 16384,
KUON_MENU_RELOAD_FLAG_TITLE = -32768,
};
#endif // KUONMENU_H
+27
View File
@@ -0,0 +1,27 @@
#ifndef MENU_H
#define MENU_H
enum _KUON_MENU__TYPE_EN {
KUON_MENU__TEST_MENU = 0,
KUON_MENU__TITLE_MENU = 1,
KUON_MENU__START_MENU = 2,
KUON_MENU__MAIN_MENU = 3,
KUON_MENU__SAVE_MENU = 4,
KUON_MENU__LOAD_MENU = 5,
KUON_MENU__MAP_MENU = 6,
KUON_MENU__ITEM_MENU = 7,
KUON_MENU__MSG_MENU = 8,
KUON_MENU__SET_MENU = 9,
KUON_MENU__END_SAVE_MENU = 10,
KUON_MENU__DEAD_MENU = 11,
KUON_MENU__MENU_NUM = 12,
KUON_MENU__MAKE_NONE = 100,
KUON_MENU__MAKE_TITLE = 101,
KUON_MENU__MAKE_GAME = 102,
KUON_MENU__DMY_MENU = 999,
};
#endif // MENU_H
+240
View File
@@ -0,0 +1,240 @@
'''
alessatool/annotate
mark up assembly with line numbers.
can also be used to create full-tu scratches in decomp.me.
example:
alessatool annotate \
--asm-path silent-hill-2/config/SLUS_202.28/asm/Effect2/hh_class_water_03.s \
--tu
run `alessatool annotate --help` for more information.
'''
from sys import stdout, stdin
from pathlib import Path
from subprocess import run
from dataclasses import dataclass
from constants import *
from struct import unpack
@dataclass
class AnnotationArgs:
vram_start: int | None
vram_end: int | None
elf_path: Path
asm_path: Path | None
out_path: Path
addr2line_path: Path
line_file_path: Path | None
tu: bool
encoding: str
stdout: bool
verbose: bool
def annotate_asm(args: AnnotationArgs):
if args.asm_path:
with open(args.asm_path, "r") as asm_file:
asm_contents = asm_file.read()
else:
asm_contents = stdin.read()
asm_lines = asm_contents.splitlines()
asm_line_index = 0
vram_start = args.vram_start
vram_end = args.vram_end
if vram_start is None or vram_end is None:
vram_start, vram_end = find_vram_bounds(asm_lines)
line_file_path = get_line_file_path(args)
if line_file_path is None or not line_file_path.exists():
addresses = (f"0x{v:X}" for v in range(vram_start, vram_end, 0x4))
proc = run([args.addr2line_path, "-e", args.elf_path, *addresses], capture_output=True, encoding=args.encoding)
addr2line_output_lines = proc.stdout.splitlines()
else:
# parse the binary line number file.
# the format is a list of u_shorts, one per line number.
# there should be one line number per vram address, and each vram
# address should be exactly 4 bytes apart, mirroring how the addr2line
# output is formatted
with open(line_file_path, "rb") as line_file:
line_data = line_file.read()
line_numbers = unpack(f"<{len(line_data) // 2}H", line_data)
compile_unit = args.asm_path.with_suffix(".c").name
addr2line_output_lines = list(map(lambda n : to_addr2line_format(compile_unit, n), line_numbers))
main_tu_name = None
prev_tu_name = None
prev_line_number = -1
function_count = 0
is_in_function_label = False
is_in_text_section = False
current_vram_addr = vram_start
annotated_asm_lines = []
for addr_index in range(0, len(addr2line_output_lines) - 1):
line = addr2line_output_lines[addr_index]
if line.startswith("?"):
current_vram_addr += 0x4
continue
separator_index = line.rfind(":")
current_line_number = int(line[separator_index+1:])
if current_line_number == prev_line_number:
current_vram_addr += 0x4
continue
vram_addr_str = f"{current_vram_addr:X}"
current_tu_name = line[0:separator_index]
if current_tu_name != main_tu_name and current_tu_name != prev_tu_name:
if main_tu_name:
print(f"[warn] alessatool/annotate: address at {vram_addr_str} belongs to {current_tu_name}")
else:
main_tu_name = current_tu_name
prev_tu_name = current_tu_name
while True:
if asm_line_index >= len(asm_lines):
raise AssertionError(
f"address 0x{current_vram_addr:X} not found in asm"
)
asm_line = asm_lines[asm_line_index]
if asm_line.startswith(SECTION_DIRECTIVE):
is_in_text_section = asm_line.startswith(TEXT_SECTION_DIRECTIVE)
if not is_in_text_section:
annotated_asm_lines.append(asm_line)
asm_line_index += 1
continue
if line_has_vram_addr(asm_line, vram_addr_str):
break
should_append_asm_line = True
if args.tu:
asm_line_trimmed = asm_line.strip()
# track when we go in & out of function symbols
if asm_line_trimmed.startswith(FUNCTION_SYMBOL_LABEL):
function_count += 1
is_in_function_label = True
annotated_asm_lines.append(f"{UNIQUE_TEXT_SECTION_DIRECTIVE}{function_count}")
annotated_asm_lines.append("")
elif asm_line_trimmed.startswith(END_FUNCTION_SYMBOL_LABEL):
is_in_function_label = False
# remove `nop`s
if not is_in_function_label and asm_line_trimmed.endswith("nop"):
should_append_asm_line = False
# remove `macro.inc` include directive
elif asm_line_trimmed == INCLUDE_MACRO_INC_DIRECTIVE:
should_append_asm_line = False
if should_append_asm_line:
annotated_asm_lines.append(asm_line)
asm_line_index += 1
annotated_asm_lines.append(f"\t.loc 1 {current_line_number}")
annotated_asm_lines.append(asm_line)
asm_line_index += 1
prev_line_number = current_line_number
current_vram_addr += 0x4
while asm_line_index < len(asm_lines) - 1:
annotated_asm_lines.append(asm_lines[asm_line_index])
asm_line_index += 1
assert main_tu_name, "no valid compilation unit found"
annotated_asm_lines = [
".section .debug",
".previous",
".text",
f".file 1 \"{main_tu_name}\"",
*annotated_asm_lines
]
append_final_new_line(annotated_asm_lines)
annotated_asm_contents = "\n".join(annotated_asm_lines)
if not args.stdout and args.out_path:
with open(args.out_path, "w") as out_file:
out_file.write(annotated_asm_contents)
if args.verbose:
print(f"alessatool/annotate: wrote asm to {args.out_path}")
else:
stdout.write(annotated_asm_contents)
def get_line_file_path(args: AnnotationArgs):
if args.line_file_path is not None:
return args.line_file_path
if args.elf_path.name == SH2_SERIAL and args.asm_path and "Event/stage" in args.asm_path.as_posix():
return Path(f"{TOOLS}/alessatool/dwarf") / Path(args.asm_path.name).with_suffix(".line")
return None
def to_addr2line_format(compile_unit: str, line_number: int):
return f"{compile_unit}:{line_number}"
def find_vram_bounds(asm_lines: list[str]):
start = None
passed_first_label = False
end = None
for line in asm_lines:
# assumes first address comment is on line after first label
if "label" in line and not passed_first_label:
passed_first_label = True
continue
if passed_first_label and start is None:
start = get_vram_addr_from_line(line)
# assumes .text section comes first
if line.startswith(SECTION_DIRECTIVE) and not line.startswith(TEXT_SECTION_DIRECTIVE):
break
vram_addr = get_vram_addr_from_line(line)
if vram_addr is None:
continue
end = vram_addr
return (start, end)
def get_vram_addr_from_line(line: str):
if "/*" not in line:
return None
_before_comment, after_comment = line.split("/* ", 1)
_file_addr, vram_addr, _rest = after_comment.split(" ", 2)
try:
return int(vram_addr, 0x10)
except:
return None
def line_has_vram_addr(line: str, addr_str: str) -> bool:
if addr_str not in line or "*/" not in line:
return False
return line.index("*/") > line.index(addr_str)
def append_final_new_line(lines: list[str]):
if lines[-1] != "":
lines.append("")