2020-02-15 18:42:14 +01:00
|
|
|
%{
|
|
|
|
#include <fxos/symbols.h>
|
|
|
|
#include <fxos/errors.h>
|
|
|
|
#include <fxos/util.h>
|
|
|
|
#include <fxos/load.h>
|
|
|
|
|
|
|
|
#include <cstdarg>
|
|
|
|
|
|
|
|
/* Text value and integer value for parser */
|
|
|
|
static char *yylval;
|
|
|
|
uint32_t yyival;
|
|
|
|
|
|
|
|
/* Tokens */
|
|
|
|
#define SYSCALL 1
|
|
|
|
#define ADDRESS 2
|
|
|
|
#define NAME 3
|
|
|
|
|
|
|
|
/* Current file name */
|
|
|
|
static std::string filename;
|
|
|
|
|
|
|
|
/* Error messages and exceptions */
|
|
|
|
static void err(char const *format, ...)
|
|
|
|
{
|
|
|
|
static char buf[256];
|
|
|
|
|
|
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
|
|
vsnprintf(buf, 256, format, args);
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
throw FxOS::SyntaxError(filename.c_str(), yylineno, buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
%}
|
|
|
|
|
|
|
|
%option prefix="symbols"
|
|
|
|
%option noyywrap
|
|
|
|
%option nounput
|
|
|
|
|
|
|
|
syscall ^%[0-9A-Fa-f]{3,}
|
|
|
|
address ^[0-9A-Fa-f]{8}
|
|
|
|
name [a-zA-Z_][a-zA-Z_0-9.]*
|
|
|
|
space [ \t]+
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
^#[^\n]* ;
|
|
|
|
{space} ;
|
|
|
|
[\n] yylineno++;
|
|
|
|
|
|
|
|
{syscall} { yyival = strtol(yytext+1, NULL, 16); return SYSCALL; }
|
|
|
|
{address} { yyival = strtol(yytext, NULL, 16); return ADDRESS; }
|
|
|
|
{name} { yylval = strdup(yytext); return NAME; }
|
|
|
|
|
|
|
|
. { err("lex error near '%s'", yytext); }
|
|
|
|
<<EOF>> { return -1; }
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
namespace FxOS {
|
|
|
|
|
|
|
|
/* Load a symbol table into the disassembler */
|
2020-06-13 11:23:46 +02:00
|
|
|
void load_symbols(Buffer const &file, size_t start_offset, size_t start_line,
|
|
|
|
SymbolTable &table)
|
2020-02-15 18:42:14 +01:00
|
|
|
{
|
2020-02-16 21:43:58 +01:00
|
|
|
YY_BUFFER_STATE buf = yy_scan_bytes(file.data.get() + start_offset,
|
2020-02-15 18:42:14 +01:00
|
|
|
file.size - start_offset);
|
|
|
|
yylineno = start_line;
|
|
|
|
filename = file.path;
|
|
|
|
|
|
|
|
/* Current symbol and line */
|
|
|
|
Symbol symbol;
|
|
|
|
int line = -1;
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
{
|
|
|
|
int t = yylex();
|
|
|
|
|
|
|
|
if(line >= 0 && (yylineno != line || t != NAME || t == -1))
|
|
|
|
{
|
|
|
|
/* Finalize current symbol */
|
|
|
|
if(symbol.name == "") err("%d: missing name", line);
|
|
|
|
else table.add(symbol);
|
|
|
|
|
|
|
|
symbol = Symbol();
|
|
|
|
}
|
|
|
|
if(t == -1) break;
|
|
|
|
|
|
|
|
if(t == SYSCALL)
|
|
|
|
{
|
|
|
|
symbol.type = Symbol::Syscall;
|
|
|
|
symbol.value = yyival;
|
|
|
|
line = yylineno;
|
|
|
|
}
|
|
|
|
else if(t == ADDRESS)
|
|
|
|
{
|
|
|
|
symbol.type = Symbol::Address;
|
|
|
|
symbol.value = yyival;
|
|
|
|
line = yylineno;
|
|
|
|
}
|
|
|
|
else if(t == NAME)
|
|
|
|
{
|
|
|
|
symbol.name = yylval;
|
|
|
|
free(yylval);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
yy_delete_buffer(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
} /* namespace FxOS */
|