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.
This commit is contained in:
Lephenixnoir 2020-02-16 21:22:21 +01:00
parent a51dc7db4c
commit 6ca3bc1f03
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
7 changed files with 119 additions and 12 deletions

View File

@ -10,6 +10,9 @@
#include <string>
#include <vector>
/* 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);

49
fxos/library.cpp Normal file
View File

@ -0,0 +1,49 @@
#include "fxos-cli.h"
#include <fxos/target.h>
#include <fxos/util.h>
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 &reg = 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);
}
}
}

View File

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

View File

@ -37,7 +37,7 @@ struct Library
return m_targets;
}
/* Simple list of assembly tables */
const std::vector<std::string> &asm_tables() {
const std::vector<std::pair<std::string, int>> &asm_tables() {
return m_asmtables;
}
/* List of symbol tables */
@ -48,7 +48,7 @@ struct Library
private:
std::vector<std::string> m_paths;
std::map<std::string, TargetDescription> m_targets;
std::vector<std::string> m_asmtables;
std::vector<std::pair<std::string, int>> m_asmtables;
std::vector<SymbolTable> m_symtables;
};

View File

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

View File

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

View File

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