mirror of https://github.com/zeldaret/botw.git
				
				
				
			
		
			
				
	
	
		
			63 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			63 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Python
		
	
	
	
| import csv
 | |
| from pathlib import Path
 | |
| import typing as tp
 | |
| 
 | |
| import util.elf
 | |
| 
 | |
| 
 | |
| class DataSymbol(tp.NamedTuple):
 | |
|     addr: int  # without the 0x7100000000 base
 | |
|     name: str
 | |
|     size: int
 | |
| 
 | |
| 
 | |
| _IDA_BASE = 0x7100000000
 | |
| 
 | |
| 
 | |
| class DataSymbolContainer:
 | |
|     def __init__(self) -> None:
 | |
|         self.symbols: tp.List[DataSymbol] = []
 | |
| 
 | |
|     def load_from_csv(self, path: Path):
 | |
|         symtab = util.elf.build_name_to_symbol_table(util.elf.my_symtab)
 | |
| 
 | |
|         with path.open("r") as f:
 | |
|             for i, line in enumerate(csv.reader(f)):
 | |
|                 if len(line) != 2:
 | |
|                     raise RuntimeError(f"Invalid line format at line {i}")
 | |
| 
 | |
|                 addr = int(line[0], 16) - _IDA_BASE
 | |
|                 name = line[1]
 | |
|                 if name not in symtab:
 | |
|                     continue
 | |
|                 size = symtab[name].size
 | |
| 
 | |
|                 self.symbols.append(DataSymbol(addr, name, size))
 | |
| 
 | |
|         # Sort the list, just in case the entries were not sorted in the CSV.
 | |
|         self.symbols.sort(key=lambda sym: sym.addr)
 | |
| 
 | |
|     def get_symbol(self, addr: int) -> tp.Optional[DataSymbol]:
 | |
|         """If addr is part of a known data symbol, this function returns the corresponding symbol."""
 | |
| 
 | |
|         # Perform a binary search on self.symbols.
 | |
|         a = 0
 | |
|         b = len(self.symbols) - 1
 | |
|         while a <= b:
 | |
|             m = (a + b) // 2
 | |
| 
 | |
|             symbol: DataSymbol = self.symbols[m]
 | |
|             addr_begin = symbol.addr
 | |
|             addr_end = addr_begin + symbol.size
 | |
| 
 | |
|             if addr_begin <= addr < addr_end:
 | |
|                 return symbol
 | |
|             if addr <= addr_begin:
 | |
|                 b = m - 1
 | |
|             elif addr >= addr_end:
 | |
|                 a = m + 1
 | |
|             else:
 | |
|                 return None
 | |
| 
 | |
|         return None
 |