This prepares the introduction of a new program model different enough
from the original that I'd rather build it on the side than
progressively update the current one.
We look for constants in call instruction parameters, but this only
works for jsr because the register argument in [jmp @rn] is not known to
be a constant yet (some static analysis required).
* Store CpuRegister on a single byte
* Store operation sizes (0, 1, 2, 4) on a single byte
* Share the (disp) and (imm) fields of instruction arguments
* Store instructions as char[12] instead of std::string (>32B)
* Store instruction args in Argument[2], not std::vector (>24B)
Size changes:
CpuRegister: 4B -> 1B
Argument: 24B -> 8B
Instruction: >64B -> 32B
This reduced the malloc size from 3.3M to 177k after a standard 40-line
disassembly (this excludes OS files mapped to memory), and improved the
loading time for the SH3 instruction table by about 30% (100 ms -> 65
ms).
This finally makes it possible to disassemble any interval without
worrying about potential errors. That's some progress.
By the way, now we can fully disassemble fx@3.10. Takes about 6 seconds
for the analysis passes, and ~9 seconds for printing on my machine.
-> The cfg pass loads the function into memory, annotates leaders and
jumps, and resolves delay slots.
-> The pcrel pass currently computes locations for pc-relative moves and
jumps, but does not yet compute the pc-relative moved data.
-> The print pass displays the results of analysis with various layout
and formatting options.
-> The Library class handles the loading and parsing of data files. This
is because any fxos application will use this since everyone will
have only one library.
-> Add a logging function that automatically format()s everything in
sight with basic logging levels and a verbose mode. Standard logs are
prefixed with __func__ for debugging purposes.
-> Allow format() to take std::string arguments for %s by statically
extracting c_str()s.
-> Add a simple timing utility to understand which file load or
disassembler pass takes up the time.
* Separate OS and Target conceptually; now an OS is created on an
existing target which must have ROM bound.
* Add a configuration file with a data library and description files
which are automatically loaded at startup.
* As a first application, implement target descriptions. It is now
possible (given the proper library) to type [fxos info fx@3.10] to get
information on the fx OS version 3.10.
* Set up the pass infrastructure and the first few easy passes. This
is still a Work In Progress and not yet called from the command-line.
* Improve the copy/move behavior of classes (C++ concerns).
* Add instruction metadata, which will make it easier to write actual
useful analysis passes.