From 6ca3bc1f03241faba9aae0dac4f7aab8590da66f Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 16 Feb 2020 21:22:21 +0100 Subject: [PATCH] add the library command for a bit of introspection The library commands lists the targets and instruction sets that have been loaded from fxos data files. --- fxos/fxos-cli.h | 3 +++ fxos/library.cpp | 49 +++++++++++++++++++++++++++++++++++++++ fxos/main.cpp | 52 +++++++++++++++++++++++++++++++++++++++--- include/fxos/library.h | 4 ++-- include/fxos/load.h | 2 +- lib/library.cpp | 4 ++-- lib/load-asm.l | 17 ++++++++++---- 7 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 fxos/library.cpp diff --git a/fxos/fxos-cli.h b/fxos/fxos-cli.h index ede5e4f..e478280 100644 --- a/fxos/fxos-cli.h +++ b/fxos/fxos-cli.h @@ -10,6 +10,9 @@ #include #include +/* Show library */ +void show_library(FxOS::Library &library, bool targets, bool asmtables); + /* Print general information on an OS file */ void os_info(FxOS::Target &target); diff --git a/fxos/library.cpp b/fxos/library.cpp new file mode 100644 index 0000000..6704011 --- /dev/null +++ b/fxos/library.cpp @@ -0,0 +1,49 @@ +#include "fxos-cli.h" +#include +#include + +using namespace FxOS; + +/* Print the details of a single target on standard output */ +void show_target(std::string name, TargetDescription const &tgt) +{ + printf(" %s:", name.c_str()); + + for(TargetDescription::Binding const &b: tgt.bindings) + { + MemoryRegion const ® = b.first; + + if(reg.name != "") + printf(" %s", reg.name.c_str()); + else + printf(" %08x(%x)", reg.start, reg.size()); + } + + printf("\n"); +} + +void show_library(FxOS::Library &library, bool targets, bool asmtables) +{ + if(targets) + { + printf("Targets:\n"); + + for(auto &pair: library.targets()) + { + show_target(pair.first, pair.second); + } + } + if(asmtables) + { + printf("Assembly tables:\n"); + + for(auto const &pair: library.asm_tables()) + { + std::string const &name = pair.first; + int instruction_count = pair.second; + + printf(" %s (%d instructions)\n", name.c_str(), + instruction_count); + } + } +} diff --git a/fxos/main.cpp b/fxos/main.cpp index 9105e88..bea92e9 100644 --- a/fxos/main.cpp +++ b/fxos/main.cpp @@ -46,8 +46,8 @@ Prints out the contents of the library. If an option is set, the results are printed in a simple easily-parsable form without header. Selectors: - -t Print all targets - -a Print all assembler instruction sets + -t, --targets Print all targets + -a, --asm Print all assembler instruction sets INFO COMMAND @@ -140,6 +140,50 @@ void loadconfig(Library &lib) // Main routines //--- +int main_library(int argc, char **argv) +{ + int error=0, option=0; + bool show_targets = false; + bool show_asm = false; + + struct option const longs[] = { + { "help", no_argument, NULL, 'h' }, + { "targets", no_argument, NULL, 't' }, + { "asm", no_argument, NULL, 'a' }, + }; + + while(option >= 0 && option != '?') + switch((option = getopt_long(argc, argv, "hta", longs, NULL))) + { + case 'h': + usage(0); + case 't': + show_targets = true; + break; + case 'a': + show_asm = true; + break; + case '?': + error = 1; + } + + if(error) return 1; + + /* If no option is given, display everything */ + if(!show_targets && !show_asm) + { + show_targets = true; + show_asm = true; + } + + /* Load the library */ + Library lib; + loadconfig(lib); + + show_library(lib, show_targets, show_asm); + return 0; +} + int main_info(int argc, char **argv) { int error=0, option=0; @@ -339,7 +383,9 @@ int main(int argc, char **argv) std::string cmd = argv[1]; argv[1] = (char *)""; - if(cmd == "info") + if(cmd == "library") + return main_library(argc, argv); + else if(cmd == "info") return main_info(argc, argv); else if(cmd == "disasm") return main_disassembly(argc, argv); diff --git a/include/fxos/library.h b/include/fxos/library.h index af4a27c..380d32e 100644 --- a/include/fxos/library.h +++ b/include/fxos/library.h @@ -37,7 +37,7 @@ struct Library return m_targets; } /* Simple list of assembly tables */ - const std::vector &asm_tables() { + const std::vector> &asm_tables() { return m_asmtables; } /* List of symbol tables */ @@ -48,7 +48,7 @@ struct Library private: std::vector m_paths; std::map m_targets; - std::vector m_asmtables; + std::vector> m_asmtables; std::vector m_symtables; }; diff --git a/include/fxos/load.h b/include/fxos/load.h index 30e7e92..771bca8 100644 --- a/include/fxos/load.h +++ b/include/fxos/load.h @@ -36,7 +36,7 @@ Header load_header(Buffer const &file, size_t &offset, int &line); @file Data file, presumably analyzed with lex_header() @offset Offset of assembly data in the file (as set by load_header) @line Line where assembly data starts in the file (idem) */ -void load_asm(Buffer const &file, size_t offset, size_t line); +int load_asm(Buffer const &file, size_t offset, size_t line); /* Load a target description into the target database. This function returns the complete target description */ diff --git a/lib/library.cpp b/lib/library.cpp index 2c89ffc..5d4e4ea 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -61,8 +61,8 @@ void Library::load(std::string path) if(type == "assembly") { try { - load_asm(file, offset, line); - m_asmtables.push_back(path); + int total = load_asm(file, offset, line); + m_asmtables.push_back(std::make_pair(h["name"],total)); } catch(FxOS::SyntaxError &e) { log(ERR "%s", e.str()); diff --git a/lib/load-asm.l b/lib/load-asm.l index 3a909e8..b7327fe 100644 --- a/lib/load-asm.l +++ b/lib/load-asm.l @@ -236,10 +236,12 @@ static Argument make_arg(int token, int opsize, int m, int n, int d, int i) @argtoken2 Token corresponding to the second argument (0 if unused) Generates all the instances of the instruction, then sends them to the - disassembler for fast lookup. */ -static void instantiate(struct Pattern p, std::string mnemonic, int argtoken1, + disassembler for fast lookup. Returns number of instantiated opcodes. */ +static int instantiate(struct Pattern p, std::string mnemonic, int argtoken1, int argtoken2) { + int total = 0; + for(int n = 0; n < (1 << p.n_size); n++) for(int m = 0; m < (1 << p.m_size); m++) for(int d = 0; d < (1 << p.d_size); d++) @@ -260,11 +262,14 @@ static void instantiate(struct Pattern p, std::string mnemonic, int argtoken1, make_arg(argtoken2, ins.opsize, m, n, d, i)); register_instruction(ins); + total++; } + + return total; } /* Load an assembly instruction table for the disassembler. */ -void load_asm(Buffer const &file, size_t start_offset, size_t start_line) +int load_asm(Buffer const &file, size_t start_offset, size_t start_line) { /* Lex all instructions and fill in the general assembly table */ @@ -273,6 +278,9 @@ void load_asm(Buffer const &file, size_t start_offset, size_t start_line) yylineno = start_line; filename = file.path; + /* Number of instructions lexed */ + int total = 0; + /* Instruction information */ char *code=nullptr, *mnemonic=nullptr; int argtoken1=0, argtoken2=0; @@ -292,7 +300,7 @@ void load_asm(Buffer const &file, size_t start_offset, size_t start_line) /* TODO: Generate all parameters and fill */ Pattern p = make_pattern(code); - instantiate(p, mnemonic, argtoken1, argtoken2); + total += instantiate(p, mnemonic, argtoken1,argtoken2); if(code) free(code); if(mnemonic) free(mnemonic); @@ -327,6 +335,7 @@ void load_asm(Buffer const &file, size_t start_offset, size_t start_line) } yy_delete_buffer(buf); + return total; } } /* namespace FxOS */