added name field to executables for easy debugging
This commit is contained in:
parent
64507a4e7e
commit
34a44860e0
@ -59,6 +59,7 @@ class Executable:
|
||||
sections: Dict[str, MemorySection]
|
||||
symbols: Dict[str, Tuple[str, int]]
|
||||
stack_pref: Optional[int]
|
||||
name: str
|
||||
|
||||
def __repr__(self):
|
||||
return "{}(sections = {}, symbols = {}, stack = {}, run_ptr = {})".format(
|
||||
@ -129,6 +130,7 @@ class LoadedMemorySection:
|
||||
size: int
|
||||
content: Union[List[LoadedInstruction], bytearray] = field(repr=False)
|
||||
flags: MemoryFlags
|
||||
owner: str
|
||||
|
||||
def read(self, offset: int, size: int):
|
||||
if offset < 0:
|
||||
@ -220,6 +222,7 @@ class LoadedExecutable:
|
||||
It still holds a symbol table, that is not accessible memory since I don't want to deal with
|
||||
binary strings in memory etc.
|
||||
"""
|
||||
name: str
|
||||
base_addr: int
|
||||
sections_by_name: Dict[str, LoadedMemorySection]
|
||||
sections: List[LoadedMemorySection]
|
||||
@ -228,6 +231,7 @@ class LoadedExecutable:
|
||||
stack_heap: Tuple[int, int] # pointers to stack and heap, are nullptr if no stack/heap is available
|
||||
|
||||
def __init__(self, exe: Executable, base_addr: int):
|
||||
self.name = exe.name
|
||||
self.base_addr = base_addr
|
||||
self.sections = list()
|
||||
self.sections_by_name = dict()
|
||||
@ -240,7 +244,8 @@ class LoadedExecutable:
|
||||
base_addr,
|
||||
exe.stack_pref,
|
||||
bytearray(exe.stack_pref),
|
||||
MemoryFlags(read_only=False, executable=False)
|
||||
MemoryFlags(read_only=False, executable=False),
|
||||
self.name
|
||||
))
|
||||
self.stack_heap = (self.base_addr, self.base_addr + exe.stack_pref)
|
||||
else:
|
||||
@ -253,7 +258,8 @@ class LoadedExecutable:
|
||||
curr,
|
||||
sec.size,
|
||||
sec.continuous_content(self),
|
||||
sec.flags
|
||||
sec.flags,
|
||||
self.name
|
||||
)
|
||||
self.sections.append(loaded_sec)
|
||||
self.sections_by_name[loaded_sec.name] = loaded_sec
|
||||
@ -269,8 +275,12 @@ class LoadedExecutable:
|
||||
run_ptr_sec, run_ptr_off = exe.run_ptr
|
||||
self.run_ptr = self.sections_by_name[run_ptr_sec].base + run_ptr_off
|
||||
|
||||
print("successfully loaded binary\n\tsize: {}\n\tsections: {}\n\trun_ptr: 0x{:08x}".format(
|
||||
def __repr__(self):
|
||||
return '{}[{}](base=0x{:08X}, size={}bytes, sections={}, run_ptr=0x{:08X})'.format(
|
||||
self.__class__.__name__,
|
||||
self.name,
|
||||
self.base_addr,
|
||||
self.size,
|
||||
" ".join(self.sections_by_name.keys()),
|
||||
self.run_ptr
|
||||
))
|
||||
)
|
||||
|
@ -27,7 +27,7 @@ class ExecutableParser:
|
||||
self.handle_symbol(token)
|
||||
elif isinstance(token, RiscVPseudoOpToken):
|
||||
self.handle_pseudo_op(token)
|
||||
return self
|
||||
return self.get_execuable()
|
||||
|
||||
def get_execuable(self):
|
||||
start_ptr = ('text', 0)
|
||||
@ -35,7 +35,7 @@ class ExecutableParser:
|
||||
start_ptr = self.symbols['_start']
|
||||
elif 'main' in self.symbols:
|
||||
start_ptr = self.symbols['main']
|
||||
return Executable(start_ptr, self.sections, self.symbols, self.stack_pref)
|
||||
return Executable(start_ptr, self.sections, self.symbols, self.stack_pref, self.tokenizer.name)
|
||||
|
||||
def parse_instruction(self, ins: 'RiscVInstructionToken'):
|
||||
if self.active_section is None:
|
||||
|
@ -43,6 +43,8 @@ class MMU:
|
||||
for sec in loaded_bin.sections:
|
||||
self.sections.append(sec)
|
||||
|
||||
print("Successfully loaded {}".format(loaded_bin))
|
||||
|
||||
return loaded_bin
|
||||
|
||||
def get_sec_containing(self, addr: int):
|
||||
|
@ -78,10 +78,16 @@ def split_accepting_quotes(string, at=REG_ARG_SPLIT, quotes=('"', "'")):
|
||||
|
||||
|
||||
class RiscVInput:
|
||||
def __init__(self, content: str):
|
||||
def __init__(self, content: str, name: str):
|
||||
self.content = content
|
||||
self.pos = 0
|
||||
self.len = len(content)
|
||||
self.name = name
|
||||
|
||||
@staticmethod
|
||||
def from_file(src: str):
|
||||
with open(src, 'r') as f:
|
||||
return RiscVInput(f.read(), src)
|
||||
|
||||
def peek(self, offset: int = 0, size: int = 1, regex: re.Pattern = None, text: str = None, regex_group: int = 0):
|
||||
at = self.pos + offset
|
||||
@ -89,7 +95,7 @@ class RiscVInput:
|
||||
if regex:
|
||||
if not isinstance(regex, re.Pattern):
|
||||
print("uncompiled regex passed to peek!")
|
||||
reges = re.compile(regex)
|
||||
regex = re.compile(regex)
|
||||
match = regex.match(self.content[at:])
|
||||
if match is None:
|
||||
return None
|
||||
@ -241,6 +247,7 @@ class RiscVTokenizer:
|
||||
def __init__(self, input: RiscVInput):
|
||||
self.input = input
|
||||
self.tokens: List[RiscVToken] = []
|
||||
self.name = input.name
|
||||
|
||||
def tokenize(self):
|
||||
while self.input.has_next():
|
||||
|
@ -20,7 +20,6 @@ if __name__ == '__main__':
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
print(args)
|
||||
|
||||
cfg = RunConfig(
|
||||
color=not args.no_color,
|
||||
@ -34,10 +33,7 @@ if __name__ == '__main__':
|
||||
FMT_NONE = ""
|
||||
FMT_PRINT = ""
|
||||
|
||||
with open(args.file, 'r') as f:
|
||||
asm = f.read()
|
||||
|
||||
tk = RiscVTokenizer(RiscVInput(asm))
|
||||
tk = RiscVTokenizer(RiscVInput.from_file(args.file))
|
||||
tk.tokenize()
|
||||
|
||||
if args.print_tokens:
|
||||
@ -45,9 +41,7 @@ if __name__ == '__main__':
|
||||
for token in tk.tokens:
|
||||
print(token)
|
||||
|
||||
executable = ExecutableParser(tk).parse().get_execuable()
|
||||
|
||||
print(FMT_PRINT + "Executable:" + FMT_NONE, executable)
|
||||
executable = ExecutableParser(tk).parse()
|
||||
|
||||
cpu = CPU(cfg)
|
||||
le = cpu.load(executable)
|
||||
|
Loading…
Reference in New Issue
Block a user