mirror of https://github.com/zeldaret/mm.git
				
				
				
			
		
			
				
	
	
		
			140 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
| #!/usr/bin/env python3
 | |
| 
 | |
| import argparse
 | |
| import os.path
 | |
| 
 | |
| parser = argparse.ArgumentParser(
 | |
|     description="Display various information about a symbol or address."
 | |
| )
 | |
| parser.add_argument(
 | |
|     "name",
 | |
|     type=str,
 | |
|     default="",
 | |
|     help="symbol name or VROM/VRAM address to lookup"
 | |
| )
 | |
| parser.add_argument(
 | |
|     "-e",
 | |
|     "--expected",
 | |
|     dest="use_expected",
 | |
|     action="store_true",
 | |
|     help="use the map file in expected/build/ instead of build/"
 | |
| )
 | |
| args = parser.parse_args()
 | |
| 
 | |
| mymap = "build/mm.map"
 | |
| if args.use_expected:
 | |
|     mymap = f"expected/{mymap}"
 | |
| 
 | |
| if not os.path.isfile(mymap):
 | |
|     print(f"{mymap} must exist.")
 | |
|     exit(1)
 | |
| 
 | |
| 
 | |
| def search_address(target_addr):
 | |
|     is_ram = target_addr & 0x80000000
 | |
|     ram_offset = None
 | |
|     prev_ram = 0
 | |
|     prev_rom = 0
 | |
|     prev_sym = "<start of rom>"
 | |
|     cur_file = "<no file>"
 | |
|     prev_file = cur_file
 | |
|     prev_line = ""
 | |
|     with open(mymap) as f:
 | |
|         for line in f:
 | |
|             if "load address" in line:
 | |
|                 # Ignore .bss sections if we're looking for a ROM address
 | |
|                 if not is_ram and (".bss" in line or ".bss" in prev_line):
 | |
|                     ram_offset = None
 | |
|                     continue
 | |
|                 ram = int(line[16 : 16 + 18], 0)
 | |
|                 rom = int(line[59 : 59 + 18], 0)
 | |
|                 ram_offset = ram - rom
 | |
|                 continue
 | |
| 
 | |
|             prev_line = line
 | |
| 
 | |
|             if (
 | |
|                 ram_offset is None
 | |
|                 or "=" in line
 | |
|                 or "*fill*" in line
 | |
|                 or " 0x" not in line
 | |
|             ):
 | |
|                 continue
 | |
| 
 | |
|             ram = int(line[16 : 16 + 18], 0)
 | |
|             rom = ram - ram_offset
 | |
|             sym = line.split()[-1]
 | |
| 
 | |
|             if "0x" in sym and "/" not in sym:
 | |
|                 ram_offset = None
 | |
|                 continue
 | |
|             if "/" in sym:
 | |
|                 cur_file = sym
 | |
|                 continue
 | |
| 
 | |
|             if rom == target_addr or (is_ram and ram == target_addr):
 | |
|                 return f"{sym} (VRAM 0x{ram:X}, VROM 0x{rom:X}, {cur_file})"
 | |
|             if rom > target_addr or (is_ram and ram > target_addr):
 | |
|                 offset = target_addr - prev_ram if is_ram else target_addr - prev_rom
 | |
|                 return f"at 0x{offset:X} bytes inside {prev_sym} (VRAM 0x{prev_ram:X}, VROM 0x{prev_rom:X}, {prev_file})"
 | |
| 
 | |
|             prev_ram = ram
 | |
|             prev_rom = rom
 | |
|             prev_sym = sym
 | |
|             prev_file = cur_file
 | |
| 
 | |
|     return "at end of rom?"
 | |
| 
 | |
| 
 | |
| def search_symbol(target_sym):
 | |
|     ram_offset = None
 | |
|     cur_file = "<no file>"
 | |
|     prev_line = ""
 | |
|     with open(mymap) as f:
 | |
|         for line in f:
 | |
|             if "load address" in line:
 | |
|                 ram = int(line[16 : 16 + 18], 0)
 | |
|                 rom = int(line[59 : 59 + 18], 0)
 | |
|                 ram_offset = ram - rom
 | |
|                 continue
 | |
| 
 | |
|             prev_line = line
 | |
| 
 | |
|             if (
 | |
|                 ram_offset is None
 | |
|                 or "=" in line
 | |
|                 or "*fill*" in line
 | |
|                 or " 0x" not in line
 | |
|             ):
 | |
|                 continue
 | |
| 
 | |
|             ram = int(line[16 : 16 + 18], 0)
 | |
|             rom = ram - ram_offset
 | |
|             sym = line.split()[-1]
 | |
| 
 | |
|             if "0x" in sym and "/" not in sym:
 | |
|                 ram_offset = None
 | |
|                 continue
 | |
|             elif "/" in sym:
 | |
|                 cur_file = sym
 | |
|                 continue
 | |
| 
 | |
|             if sym == target_sym:
 | |
|                 return (rom, cur_file, ram)
 | |
| 
 | |
|     return None
 | |
| 
 | |
| 
 | |
| try:
 | |
|     target_addr = int(args.name, 0)
 | |
|     print(args.name, "is", search_address(target_addr))
 | |
| except ValueError:
 | |
|     sym_info = search_symbol(args.name)
 | |
|     if sym_info is not None:
 | |
|         sym_rom = sym_info[0]
 | |
|         sym_file = sym_info[1]
 | |
|         sym_ram = sym_info[2]
 | |
|         print(f"Symbol {args.name} (VRAM: 0x{sym_ram:08X}, VROM: 0x{sym_rom:06X}, {sym_file})")
 | |
|     else:
 | |
|         print(f"Symbol {args.name} not found in map file {mymap}")
 |