diff --git a/fxos/disassembly.cpp b/fxos/disassembly.cpp index 5d356b6..b01214a 100644 --- a/fxos/disassembly.cpp +++ b/fxos/disassembly.cpp @@ -1,7 +1,7 @@ #include "fxos-cli.h" #include #include -#include +#include #include #include #include @@ -14,16 +14,16 @@ using namespace FxOS; using namespace FxOS::Log; -int disassembly(Library &library, Target &target, char const *ref, +int disassembly(Library &library, VirtualSpace &space, char const *ref, std::vector passes) { - Disassembly disasm(target); + Disassembly disasm(space); int len=0; - /* Observe the target only if it has an OS mapped */ + /* Observe the space only if it has an OS mapped */ std::unique_ptr os; try { - os = std::make_unique(target); + os = std::make_unique(space); } catch(std::exception &) {} @@ -78,8 +78,8 @@ int disassembly(Library &library, Target &target, char const *ref, { if(!os) { - log(ERR "cannot disassemble syscall %s: target does " - "not have an OS mapped", ref); + log(ERR "cannot disassemble syscall %s: virtual space does not " + "have an OS mapped", ref); return 1; } if(syscall_id >= os->syscall_count()) diff --git a/fxos/fxos-cli.h b/fxos/fxos-cli.h index 7ef85fc..e89514b 100644 --- a/fxos/fxos-cli.h +++ b/fxos/fxos-cli.h @@ -5,7 +5,7 @@ #ifndef FXOS_CLI_H #define FXOS_CLI_H -#include +#include #include #include #include @@ -14,10 +14,10 @@ void show_library(FxOS::Library &library, bool targets, bool asmtables); /* Print general information on an OS file */ -void os_info(FxOS::Target &target); +void os_info(FxOS::VirtualSpace &space); /* Disassemble */ -int disassembly(FxOS::Library &library, FxOS::Target &target, char const *ref, - std::vector passes); +int disassembly(FxOS::Library &library, FxOS::VirtualSpace &space, + char const *ref, std::vector passes); #endif /* FXOS_CLI_H */ diff --git a/fxos/info.cpp b/fxos/info.cpp index c4c1fe7..e734676 100644 --- a/fxos/info.cpp +++ b/fxos/info.cpp @@ -1,5 +1,5 @@ #include "fxos-cli.h" -#include +#include #include #include #include @@ -32,11 +32,11 @@ static char const *syscall_str = static char const *syscall_nonrom_str = " %%%03x -> %08x (%s memory)\n"; -void os_info(Target &t) +void os_info(VirtualSpace &space) { /* Create an OS analysis over t. If t does not have a ROM mapped, this will fail with an exception */ - OS os(t); + OS os(space); printf(info_str, (os.type == OS::FX ? "FX" : "CG"), &os.bootcode_timestamp, os.bootcode_timestamp.value.c_str(), @@ -56,7 +56,7 @@ void os_info(Target &t) } uint32_t syscall_table = os.syscall_table_address(); - uint32_t first_noncall = t.read_u32(syscall_table + + uint32_t first_noncall = space.read_u32(syscall_table + 4 * os.syscall_count()); printf(syscall_str, (os.type == OS::FX ? 0x8001007c : 0x8002007c), diff --git a/fxos/library.cpp b/fxos/library.cpp index 6704011..93048c4 100644 --- a/fxos/library.cpp +++ b/fxos/library.cpp @@ -1,5 +1,5 @@ #include "fxos-cli.h" -#include +#include #include using namespace FxOS; diff --git a/fxos/main.cpp b/fxos/main.cpp index 7d16c64..b59276d 100644 --- a/fxos/main.cpp +++ b/fxos/main.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include @@ -210,10 +210,10 @@ int main_info(int argc, char **argv) try { /* Load the file in ROM over 8M */ Buffer romfile(path, MemoryRegion::ROM.size()); - Target t; - t.bind_region(MemoryRegion::ROM, romfile); - t.bind_region(MemoryRegion::ROM_P2, romfile); - os_info(t); + VirtualSpace s; + s.bind_region(MemoryRegion::ROM, romfile); + s.bind_region(MemoryRegion::ROM_P2, romfile); + os_info(s); } catch(std::exception &e) { log(ERR "%s", e.what()); @@ -233,8 +233,8 @@ int main_info(int argc, char **argv) } try { - Target t(lib.targets().at(tname), lib.paths()); - os_info(t); + VirtualSpace s(lib.targets().at(tname), lib.paths()); + os_info(s); } catch(std::exception &e) { log(ERR "%s", e.what()); @@ -315,7 +315,7 @@ int main_disassembly(int argc, char **argv) Library lib; loadconfig(lib); - Target target; + VirtualSpace space; char const *ref; if(!file.size()) @@ -328,7 +328,7 @@ int main_disassembly(int argc, char **argv) return 1; } - target = Target(lib.targets().at(tname), lib.paths()); + space = VirtualSpace(lib.targets().at(tname), lib.paths()); ref = argv[optind + 2]; log(LOG "Disassembling target %s at %s", tname, ref); @@ -338,9 +338,9 @@ int main_disassembly(int argc, char **argv) { /* Load the file in ROM over 8M */ Buffer romfile(file, MemoryRegion::ROM.size()); - target = Target(); - target.bind_region(MemoryRegion::ROM, romfile); - target.bind_region(MemoryRegion::ROM_P2, romfile); + space = VirtualSpace(); + space.bind_region(MemoryRegion::ROM, romfile); + space.bind_region(MemoryRegion::ROM_P2, romfile); ref = argv[optind + 1]; log(LOG "Disassembling file %s at %s", file, ref); @@ -348,7 +348,7 @@ int main_disassembly(int argc, char **argv) try { - int rc = disassembly(lib, target, ref, passes); + int rc = disassembly(lib, space, ref, passes); if(log_getminlevel() <= LEVEL_LOG) malloc_stats(); return rc; } diff --git a/include/fxos/disassembly.h b/include/fxos/disassembly.h index f5a37a0..69a4715 100644 --- a/include/fxos/disassembly.h +++ b/include/fxos/disassembly.h @@ -6,7 +6,7 @@ #define LIBFXOS_DISASSEMBLY_H #include -#include +#include #include #include @@ -98,7 +98,7 @@ struct ConcreteInstruction class Disassembly { public: - Disassembly(Target &target); + Disassembly(VirtualSpace &space); /* Check whether an instruction has been visited so far */ bool hasins(uint32_t pc); @@ -116,8 +116,8 @@ public: } /* Access to memory */ - Target &target() noexcept { - return m_target; + VirtualSpace &space() noexcept { + return m_space; } /* List of passes that have run so far */ @@ -125,7 +125,7 @@ public: private: /* Underlying target */ - Target &m_target; + VirtualSpace &m_space; /* Loaded instructions by address */ std::map m_instructions; }; diff --git a/include/fxos/library.h b/include/fxos/library.h index 380d32e..f215564 100644 --- a/include/fxos/library.h +++ b/include/fxos/library.h @@ -5,7 +5,7 @@ #ifndef FXOS_LIBRARY_H #define FXOS_LIBRARY_H -#include +#include #include #include diff --git a/include/fxos/load.h b/include/fxos/load.h index f958b89..d2ea92b 100644 --- a/include/fxos/load.h +++ b/include/fxos/load.h @@ -6,7 +6,7 @@ #define LIBFXOS_LOAD_H #include -#include +#include #include #include diff --git a/include/fxos/os.h b/include/fxos/os.h index 8b38069..ba96fff 100644 --- a/include/fxos/os.h +++ b/include/fxos/os.h @@ -5,7 +5,7 @@ #ifndef LIBFXOS_OS_H #define LIBFXOS_OS_H -#include +#include #include #include @@ -16,9 +16,9 @@ namespace FxOS { class OS { public: - /* Create an OS interface for this target. If the target does not have - data loaded in ROM, this raises an exception. */ - OS(Target &target); + /* Create an OS interface for this virtual space. If there is no data + loaded in ROM, this raises an exception. */ + OS(VirtualSpace &space); /* Type of OS, determined at construction */ enum Type { FX, CG }; @@ -49,8 +49,8 @@ public: int langdata; private: - /* Target being analyzed */ - Target &m_target; + /* Virtual space being analyzed */ + VirtualSpace &m_space; /* Parse the OS header. This should be the first analysis function to be called, because it determines the type of model (ie. fx9860g vs diff --git a/include/fxos/symbols.h b/include/fxos/symbols.h index dd51beb..83e485b 100644 --- a/include/fxos/symbols.h +++ b/include/fxos/symbols.h @@ -10,7 +10,7 @@ #include #include -#include +#include namespace FxOS { @@ -44,7 +44,7 @@ public: /* Validate constraints to see if table is usable */ bool is_usable_on(OS &os) const noexcept; - bool is_usable_on(Target &target) const noexcept; + bool is_usable_on(VirtualSpace &space) const noexcept; /* Add a symbol to the table */ void add(Symbol s); /* Query a value for a certain type of symbol */ diff --git a/include/fxos/target.h b/include/fxos/vspace.h similarity index 92% rename from include/fxos/target.h rename to include/fxos/vspace.h index 1c4d836..53adc48 100644 --- a/include/fxos/target.h +++ b/include/fxos/vspace.h @@ -1,9 +1,9 @@ //--- -// fxos.target: The target which is being studied +// fxos.vspace: A virtual space where code is being studied //--- -#ifndef LIBFXOS_TARGET_H -#define LIBFXOS_TARGET_H +#ifndef LIBFXOS_VSPACE_H +#define LIBFXOS_VSPACE_H #include #include @@ -100,16 +100,15 @@ struct TargetDescription std::string mpu; }; -/* A composite target where regions can be bound dynamically */ -class Target: public AbstractMemory +/* A composite space where regions can be bound dynamically */ +class VirtualSpace: public AbstractMemory { public: - /* Create an empty target with no regions */ - Target(); + /* Create an empty space with no regions */ + VirtualSpace(); - /* Create a target from a target description by loading files from a - library. */ - Target(TargetDescription const &description, + /* Create a new virtual space with a target loaded. */ + VirtualSpace(TargetDescription const &description, std::vector folders); /* MPU used by this target, or an empty string if unspecified */ @@ -147,4 +146,4 @@ private: } /* namespace FxOS */ -#endif /* LIBFXOS_TARGET_H */ +#endif /* LIBFXOS_VSPACE_H */ diff --git a/lib/disassembly.cpp b/lib/disassembly.cpp index 8f5e502..938c90a 100644 --- a/lib/disassembly.cpp +++ b/lib/disassembly.cpp @@ -55,8 +55,8 @@ ConcreteInstruction::ConcreteInstruction(uint16_t opcode): // Disassembler interface //--- -Disassembly::Disassembly(Target &target): - passes {}, m_target {target}, m_instructions {} +Disassembly::Disassembly(VirtualSpace &space): + passes {}, m_space {space}, m_instructions {} { } @@ -99,7 +99,7 @@ ConcreteInstruction &Disassembly::readins(uint32_t pc) } catch(std::out_of_range &e) { - uint16_t opcode = m_target.read_u16(pc); + uint16_t opcode = m_space.read_u16(pc); ConcreteInstruction ci(opcode); if(insmap[opcode]) diff --git a/lib/load-target.l b/lib/load-target.l index b6417b5..8ccecd6 100644 --- a/lib/load-target.l +++ b/lib/load-target.l @@ -1,5 +1,5 @@ %{ -#include +#include #include #include diff --git a/lib/load-target.y b/lib/load-target.y index 5653a65..defe67a 100644 --- a/lib/load-target.y +++ b/lib/load-target.y @@ -3,7 +3,7 @@ #include #include #include -#include +#include /* The target description to be filled */ FxOS::TargetDescription t; diff --git a/lib/os.cpp b/lib/os.cpp index 45c60bd..1a479a3 100644 --- a/lib/os.cpp +++ b/lib/os.cpp @@ -1,24 +1,24 @@ #include -#include +#include #include #include namespace FxOS { -OS::OS(Target &t): m_target {t} +OS::OS(VirtualSpace &space): m_space {space} { - if(!t.covers(0x80000000)) + if(!space.covers(0x80000000)) throw std::runtime_error("OS requires a target with ROM"); /* OS files are all at least 1 MB large */ - if(!t.covers(0x80000000, 1000000)) + if(!space.covers(0x80000000, 1000000)) throw std::runtime_error("OS requires target with >1MB ROM"); /* Detect OS type by heuristic */ - if(t.read_str(0x80010000, 8).value == "CASIOWIN") + if(space.read_str(0x80010000, 8).value == "CASIOWIN") this->type = FX; - else if(t.read_str(0x80020000, 8).value == "CASIOWIN") + else if(space.read_str(0x80020000, 8).value == "CASIOWIN") this->type = CG; else throw std::runtime_error("Cannot determine OS type (FX/CG)"); @@ -30,22 +30,22 @@ OS::OS(Target &t): m_target {t} void OS::parse_header() { - Target &t = m_target; + VirtualSpace &s = m_space; if(this->type == FX) { /* Bootcode timestamp at the very end of the bootcode */ - this->bootcode_timestamp = t.read_str(0x8000ffb0, 14); - this->bootcode_checksum = t.read_u32(0x8000fffc); - this->version = t.read_str(0x80010020, 10); - this->serial_number = t.read_str(0x8000ffd0, 8); + this->bootcode_timestamp = s.read_str(0x8000ffb0, 14); + this->bootcode_checksum = s.read_u32(0x8000fffc); + this->version = s.read_str(0x80010020, 10); + this->serial_number = s.read_str(0x8000ffd0, 8); } else if(this->type == CG) { - this->bootcode_timestamp = t.read_str(0x8001ffb0, 14); - this->bootcode_checksum = t.read_u32(0x8001fffc); - this->version = t.read_str(0x80020020, 10); - this->serial_number = t.read_str(0x8001ffd0, 8); + this->bootcode_timestamp = s.read_str(0x8001ffb0, 14); + this->bootcode_checksum = s.read_u32(0x8001fffc); + this->version = s.read_str(0x80020020, 10); + this->serial_number = s.read_str(0x8001ffd0, 8); } } @@ -76,20 +76,18 @@ int OS::find_syscall(uint32_t entry) const noexcept uint32_t OS::syscall_table_address() const noexcept { uint32_t address = (this->type == FX) ? 0x8001007c : 0x8002007c; - return m_target.read_u32(address); + return m_space.read_u32(address); } void OS::parse_syscall_table() { - Target &t = m_target; - /* Traverse the syscall table */ uint32_t syscall_table = syscall_table_address(); int id = 0; while(1) { - uint32_t entry = t.read_u32(syscall_table + 4 * id); + uint32_t entry = m_space.read_u32(syscall_table + 4 * id); MemoryRegion const *r = MemoryRegion::region_for(entry); if(!r) break; @@ -107,13 +105,13 @@ void OS::parse_syscall_table() void OS::parse_footer() { - Target &t = m_target; + VirtualSpace &s = m_space; /* Find the footer address (occurrence of "CASIOABSLangdata") */ uint32_t start = MemoryRegion::ROM.start; uint32_t end = MemoryRegion::ROM.end; - this->footer = t.search(start, end, "CASIOABSLangdata", 16); + this->footer = s.search(start, end, "CASIOABSLangdata", 16); if(this->footer == end) { this->footer = -1; @@ -125,14 +123,14 @@ void OS::parse_footer() uint32_t addr = this->footer + 8; this->langdata = 0; - while(!memcmp(t.translate(addr, 8), "Langdata", 8)) + while(!memcmp(s.translate(addr, 8), "Langdata", 8)) { this->langdata++; addr += 0x30; } - this->timestamp = t.read_str(addr, 14); - this->checksum = t.read_u32(addr + 0x18); + this->timestamp = s.read_str(addr, 14); + this->checksum = s.read_u32(addr + 0x18); } } /* namespace FxOS */ diff --git a/lib/passes/pcrel.cpp b/lib/passes/pcrel.cpp index 27bab83..bb2465b 100644 --- a/lib/passes/pcrel.cpp +++ b/lib/passes/pcrel.cpp @@ -27,14 +27,13 @@ void PcrelPass::analyze(uint32_t pc, ConcreteInstruction &ci) uint32_t addr = (pc & ~(a.opsize - 1)) + 4 + a.disp; ca.location = RelConstDomain().constant(addr); - /* Also compute the value. This is sign-extended from - 16-bit with mov.w. There is no mov.b for this - instruction. */ - Target &t = m_disasm.target(); + /* Also compute the value. This is sign-extended from 16-bit with + mov.w. There is no mov.b for this instruction. */ + VirtualSpace &space = m_disasm.space(); uint32_t v = -1; - if(i->opsize == 2) v = t.read_i16(addr); - if(i->opsize == 4) v = t.read_i32(addr); + if(i->opsize == 2) v = space.read_i16(addr); + if(i->opsize == 4) v = space.read_i32(addr); ca.value = DataValue(IntegerType::u32); ca.value.write(0, 4, v); @@ -52,8 +51,8 @@ void PcrelPass::analyze(uint32_t pc, ConcreteInstruction &ci) { uint32_t addr = (pc & ~3) + 4 + a.disp; - /* SH3 manual says that the semantics of mova change in - a delay slot. GNU as: "yeah but sorry they don't" */ + /* SH3 manual says that the semantics of mova change in a delay + slot. GNU as says they don't. */ // if(ci.delayslot) addr = (ci.jmptarget&~3) + 4 + a.disp; ca.location = RelConstDomain().constant(addr); diff --git a/lib/passes/print.cpp b/lib/passes/print.cpp index 6f18f1f..7f1f799 100644 --- a/lib/passes/print.cpp +++ b/lib/passes/print.cpp @@ -18,9 +18,8 @@ PrintPass::PrintPass(Disassembly &disasm, /* Default parameters: all 0 */ /* Use an OS observer to describe syscalls in header lines */ - Target &t = disasm.target(); try { - m_os = std::make_unique(t); + m_os = std::make_unique(disasm.space()); } catch(std::exception &) {} } @@ -109,7 +108,7 @@ std::optional PrintPass::symquery(Symbol::Type type, for(int i = m_symtables.size() - 1; i >= 0; i--) { SymbolTable const &st = m_symtables[i]; - if(!st.is_usable_on(m_disasm.target())) continue; + if(!st.is_usable_on(m_disasm.space())) continue; if(m_os && !st.is_usable_on(*m_os)) continue; auto maybe_str = st.query(type, value); diff --git a/lib/symbols.cpp b/lib/symbols.cpp index 31e60ef..55b1a8d 100644 --- a/lib/symbols.cpp +++ b/lib/symbols.cpp @@ -13,10 +13,10 @@ bool SymbolTable::is_usable_on(OS &os) const noexcept return (m_os_constraint == "" || m_os_constraint == constraint); } -bool SymbolTable::is_usable_on(Target &target) const noexcept +bool SymbolTable::is_usable_on(VirtualSpace &space) const noexcept { - return m_mpu_constraint == "" || target.mpu == "" || - m_mpu_constraint == target.mpu; + return m_mpu_constraint == "" || space.mpu == "" || + m_mpu_constraint == space.mpu; } void SymbolTable::add(Symbol s) diff --git a/lib/target.cpp b/lib/vspace.cpp similarity index 88% rename from lib/target.cpp rename to lib/vspace.cpp index 144af28..70364f8 100644 --- a/lib/target.cpp +++ b/lib/vspace.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -109,14 +109,14 @@ uint32_t Binding::search(uint32_t start, uint32_t end, void const *pattern, // Composite memory targets //--- -Target::Target(): +VirtualSpace::VirtualSpace(): m_bindings {}, m_buffers {} { } -Target::Target(TargetDescription const &descr, +VirtualSpace::VirtualSpace(TargetDescription const &descr, std::vector folders): - Target() + VirtualSpace() { for(auto binding: descr.bindings) { @@ -131,13 +131,13 @@ Target::Target(TargetDescription const &descr, this->mpu = descr.mpu; } -void Target::bind_region(MemoryRegion const ®ion, Buffer const &buffer) +void VirtualSpace::bind_region(MemoryRegion const ®ion,Buffer const &buffer) { Binding b(region, buffer); m_bindings.push_back(b); } -bool Target::covers(uint32_t addr, int size) const noexcept +bool VirtualSpace::covers(uint32_t addr, int size) const noexcept { for(auto it = m_bindings.crbegin(); it != m_bindings.crend(); it++) { @@ -147,12 +147,12 @@ bool Target::covers(uint32_t addr, int size) const noexcept return false; } -bool Target::covers(MemoryRegion const ®ion) const noexcept +bool VirtualSpace::covers(MemoryRegion const ®ion) const noexcept { return covers(region.start, region.size()); } -char const *Target::translate(uint32_t addr, int size) const +char const *VirtualSpace::translate(uint32_t addr, int size) const { for(auto it = m_bindings.crbegin(); it != m_bindings.crend(); it++) { @@ -163,7 +163,7 @@ char const *Target::translate(uint32_t addr, int size) const throw AddressError(addr, size); } -uint32_t Target::search(uint32_t start, uint32_t end, void const *pattern, +uint32_t VirtualSpace::search(uint32_t start, uint32_t end,void const *pattern, int size) const { uint32_t occurrence;