rename Target into VirtualSpace

This commit is contained in:
Lephenixnoir 2021-03-16 14:43:43 +01:00
parent ca1217af1b
commit 245af5e993
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
19 changed files with 102 additions and 107 deletions

View File

@ -1,7 +1,7 @@
#include "fxos-cli.h"
#include <fxos/disassembly.h>
#include <fxos/memory.h>
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/util.h>
#include <fxos/log.h>
#include <fxos/os.h>
@ -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<std::string> 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> os;
try {
os = std::make_unique<OS>(target);
os = std::make_unique<OS>(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())

View File

@ -5,7 +5,7 @@
#ifndef FXOS_CLI_H
#define FXOS_CLI_H
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/library.h>
#include <string>
#include <vector>
@ -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<std::string> passes);
int disassembly(FxOS::Library &library, FxOS::VirtualSpace &space,
char const *ref, std::vector<std::string> passes);
#endif /* FXOS_CLI_H */

View File

@ -1,5 +1,5 @@
#include "fxos-cli.h"
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/os.h>
#include <fxos/util.h>
#include <cassert>
@ -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),

View File

@ -1,5 +1,5 @@
#include "fxos-cli.h"
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/util.h>
using namespace FxOS;

View File

@ -3,7 +3,7 @@
#include <fxos/disassembly.h>
#include <fxos/library.h>
#include <fxos/errors.h>
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/load.h>
#include <fxos/log.h>
#include <fxos/os.h>
@ -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;
}

View File

@ -6,7 +6,7 @@
#define LIBFXOS_DISASSEMBLY_H
#include <fxos/lang.h>
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/semantics.h>
#include <set>
@ -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<uint32_t, ConcreteInstruction> m_instructions;
};

View File

@ -5,7 +5,7 @@
#ifndef FXOS_LIBRARY_H
#define FXOS_LIBRARY_H
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/symbols.h>
#include <string>

View File

@ -6,7 +6,7 @@
#define LIBFXOS_LOAD_H
#include <fxos/util.h>
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/symbols.h>
#include <string>

View File

@ -5,7 +5,7 @@
#ifndef LIBFXOS_OS_H
#define LIBFXOS_OS_H
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/util.h>
#include <vector>
@ -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

View File

@ -10,7 +10,7 @@
#include <vector>
#include <fxos/os.h>
#include <fxos/target.h>
#include <fxos/vspace.h>
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 */

View File

@ -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 <fxos/memory.h>
#include <fxos/util.h>
@ -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<std::string> 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 */

View File

@ -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])

View File

@ -1,5 +1,5 @@
%{
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/errors.h>
#include <fxos/util.h>

View File

@ -3,7 +3,7 @@
#include <fxos/errors.h>
#include <fxos/util.h>
#include <fxos/load.h>
#include <fxos/target.h>
#include <fxos/vspace.h>
/* The target description to be filled */
FxOS::TargetDescription t;

View File

@ -1,24 +1,24 @@
#include <fxos/os.h>
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/memory.h>
#include <cstring>
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 */

View File

@ -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);

View File

@ -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<OS>(t);
m_os = std::make_unique<OS>(disasm.space());
}
catch(std::exception &) {}
}
@ -109,7 +108,7 @@ std::optional<std::string> 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);

View File

@ -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)

View File

@ -1,4 +1,4 @@
#include <fxos/target.h>
#include <fxos/vspace.h>
#include <fxos/errors.h>
#include <fxos/os.h>
#include <cstring>
@ -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<std::string> 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 &region, Buffer const &buffer)
void VirtualSpace::bind_region(MemoryRegion const &region,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 &region) const noexcept
bool VirtualSpace::covers(MemoryRegion const &region) 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;