add support for flexible location specifiers

This commit is contained in:
Lephenixnoir 2020-02-17 22:47:09 +01:00
parent 5178a489be
commit 54a79ca4b4
Signed by untrusted user: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
5 changed files with 102 additions and 19 deletions

View File

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

View File

@ -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 */

View File

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

View File

@ -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 */

View File

@ -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 */