forked from Lephenixnoir/fxos
add support for flexible location specifiers
This commit is contained in:
parent
5178a489be
commit
54a79ca4b4
|
@ -14,7 +14,7 @@
|
|||
using namespace FxOS;
|
||||
using namespace FxOS::Log;
|
||||
|
||||
void disassembly(Library &library, Target &target, uint32_t ref,
|
||||
int disassembly(Library &library, Target &target, char const *ref,
|
||||
std::vector<std::string> passes)
|
||||
{
|
||||
Disassembly disasm(target);
|
||||
|
@ -24,6 +24,81 @@ void disassembly(Library &library, Target &target, uint32_t ref,
|
|||
if(target.covers(MemoryRegion::ROM))
|
||||
os = std::make_unique<OS>(target);
|
||||
|
||||
uint32_t address;
|
||||
int syscall_id;
|
||||
int len = 0;
|
||||
|
||||
/* Parse different flavors of references. %<hexa>: syscall */
|
||||
if(sscanf(ref, "%%%x", &syscall_id) == 1)
|
||||
{
|
||||
if(!os)
|
||||
{
|
||||
log(ERR "cannot disassemble syscall %s: target does "
|
||||
"not have an OS mapped", ref);
|
||||
return 1;
|
||||
}
|
||||
if(syscall_id >= os->syscall_count())
|
||||
{
|
||||
log(ERR "this OS only has %#x syscalls",
|
||||
os->syscall_count());
|
||||
return 1;
|
||||
}
|
||||
|
||||
address = os->syscall(syscall_id);
|
||||
}
|
||||
/* Pure hexa: address */
|
||||
else if(sscanf(ref, "%x%n", &address, &len) == 1 && !ref[len])
|
||||
{
|
||||
}
|
||||
/* Anything else: look up symbols */
|
||||
else
|
||||
{
|
||||
bool found = false;
|
||||
std::string name = ref;
|
||||
Symbol sym;
|
||||
|
||||
for(auto const &symtable: library.sym_tables())
|
||||
{
|
||||
std::optional<Symbol> s = symtable.lookup(name);
|
||||
if(!s) continue;
|
||||
|
||||
found = true;
|
||||
sym = *s;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
{
|
||||
log(ERR "cannot interpret '%s' (not syscall id, not "
|
||||
"address, and no such symbol in library)",ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch(sym.type)
|
||||
{
|
||||
case Symbol::Syscall:
|
||||
if(!os)
|
||||
{
|
||||
log(ERR "cannot disassemble syscall %s: target"
|
||||
" does not have an OS mapped", ref);
|
||||
return 1;
|
||||
}
|
||||
if(syscall_id >= os->syscall_count())
|
||||
{
|
||||
log(ERR "this OS only has %#x syscalls",
|
||||
os->syscall_count());
|
||||
return 1;
|
||||
}
|
||||
|
||||
address = os->syscall(sym.value);
|
||||
break;
|
||||
|
||||
case Symbol::Address:
|
||||
address = sym.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto pass: passes)
|
||||
{
|
||||
auto start = timer_start();
|
||||
|
@ -32,17 +107,17 @@ void disassembly(Library &library, Target &target, uint32_t ref,
|
|||
if(pass == "cfg")
|
||||
{
|
||||
CfgPass p(disasm);
|
||||
p.run(ref);
|
||||
p.run(address);
|
||||
}
|
||||
else if(pass == "pcrel")
|
||||
{
|
||||
PcrelPass p(disasm);
|
||||
p.run(ref);
|
||||
p.run(address);
|
||||
}
|
||||
else if(pass == "syscall")
|
||||
{
|
||||
SyscallPass p(disasm, os.get());
|
||||
p.run(ref);
|
||||
p.run(address);
|
||||
}
|
||||
else if(pass == "print")
|
||||
{
|
||||
|
@ -59,4 +134,6 @@ void disassembly(Library &library, Target &target, uint32_t ref,
|
|||
}
|
||||
log(LOG "%s", timer_format(timer_end(start)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ void show_library(FxOS::Library &library, bool targets, bool asmtables);
|
|||
void os_info(FxOS::Target &target);
|
||||
|
||||
/* Disassemble */
|
||||
void disassembly(FxOS::Library &library, FxOS::Target &target, uint32_t ref,
|
||||
int disassembly(FxOS::Library &library, FxOS::Target &target, char const *ref,
|
||||
std::vector<std::string> passes);
|
||||
|
||||
#endif /* FXOS_CLI_H */
|
||||
|
|
|
@ -68,8 +68,6 @@ Location specifiers:
|
|||
|
||||
Disassembly options:
|
||||
-p <list> Execute the specified comma-separated list of passes
|
||||
--load <file> Read additional documentation from <file>
|
||||
--load <folder> Read additional documentation recursively from <folder>
|
||||
|
||||
Available passes:
|
||||
cfg Build the control flow graph (always required)
|
||||
|
@ -329,8 +327,7 @@ int main_disassembly(int argc, char **argv)
|
|||
loadconfig(lib);
|
||||
|
||||
Target target;
|
||||
char const *refstr;
|
||||
uint32_t ref;
|
||||
char const *ref;
|
||||
|
||||
if(!file.size())
|
||||
{
|
||||
|
@ -344,8 +341,8 @@ int main_disassembly(int argc, char **argv)
|
|||
|
||||
target = Target(lib.targets().at(tname), lib.paths());
|
||||
|
||||
refstr = argv[optind + 2];
|
||||
log(LOG "Disassembling target %s at %s", tname, refstr);
|
||||
ref = argv[optind + 2];
|
||||
log(LOG "Disassembling target %s at %s", tname, ref);
|
||||
|
||||
}
|
||||
else
|
||||
|
@ -356,14 +353,13 @@ int main_disassembly(int argc, char **argv)
|
|||
target.bind_region(MemoryRegion::ROM, romfile);
|
||||
target.bind_region(MemoryRegion::ROM_P2, romfile);
|
||||
|
||||
refstr = argv[optind + 1];
|
||||
log(LOG "Disassembling file %s at %s", file, refstr);
|
||||
ref = argv[optind + 1];
|
||||
log(LOG "Disassembling file %s at %s", file, ref);
|
||||
}
|
||||
|
||||
sscanf(refstr, "%x", &ref);
|
||||
try
|
||||
{
|
||||
disassembly(lib, target, ref, passes);
|
||||
return disassembly(lib, target, ref, passes);
|
||||
}
|
||||
catch(LangError &e)
|
||||
{
|
||||
|
@ -375,8 +371,6 @@ int main_disassembly(int argc, char **argv)
|
|||
log(ERR "%08x[%d]: %s", e.addr(), e.size(), e.what());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define UN __attribute__((unused))
|
||||
|
@ -399,8 +393,8 @@ int main(int argc, char **argv)
|
|||
return main_info(argc, argv);
|
||||
else if(cmd == "disasm")
|
||||
return main_disassembly(argc, argv);
|
||||
else if(cmd == "analyze")
|
||||
return main_analyze(argc, argv);
|
||||
// else if(cmd == "analyze")
|
||||
// return main_analyze(argc, argv);
|
||||
|
||||
else if(cmd == "-?" || cmd == "-h" || cmd == "--help")
|
||||
usage(0);
|
||||
|
|
|
@ -38,6 +38,8 @@ struct SymbolTable
|
|||
/* Query a value for a certain type of symbol */
|
||||
std::optional<std::string> query(Symbol::Type type, uint32_t value)
|
||||
const;
|
||||
/* Lookup the symbol behind a given name */
|
||||
std::optional<Symbol> lookup(std::string name) const;
|
||||
};
|
||||
|
||||
} /* namespace FxOS */
|
||||
|
|
|
@ -18,4 +18,14 @@ std::optional<std::string> SymbolTable::query(Symbol::Type type,
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<Symbol> SymbolTable::lookup(std::string name) const
|
||||
{
|
||||
for(auto &sym: symbols)
|
||||
{
|
||||
if(sym.name == name) return sym;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
} /* namespace FxOS */
|
||||
|
|
Loading…
Reference in New Issue