shell: load fxosrc files into flat legacy vspace info

This commit is contained in:
Lephenixnoir 2023-09-23 22:50:00 +02:00
parent e52b8411b3
commit 0c52cfca27
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
9 changed files with 150 additions and 20 deletions

View File

@ -66,6 +66,7 @@ flex_target(Lexer shell/lexer.l
set(fxos_shell_SOURCES
shell/main.cpp
shell/legacy.cpp
shell/parser.cpp
shell/session.cpp
shell/theme.cpp

View File

@ -4,7 +4,7 @@ The loading and management of programs go through several layers that each have
### Loading layer
```c++
```cpp
#include <fxos/vspace.h>
#include <fxos/memory.h>
```
@ -19,7 +19,7 @@ While not explicitly supported yet, the loading layer could be used to load comp
### Binary layer
```c++
```cpp
#include <fxos/binary.h>
#include <fxos/function.h>
#include <fxos/os.h>
@ -36,7 +36,7 @@ Analysis results at the binary layer include:
### Project layer
```c++
```cpp
#include <fxos/project.h>
```

View File

@ -75,7 +75,7 @@ In version 1.x, fxos still loads `fxosrc` if it exists, and lists any legacy vir
(3) % fxos -p <name>
```
When specifying an existing folder as argument (1), fxos assumes the folder is a project folder and attempts to load it. When specifying an existing file (2), a new temporary project is created, with that file mapped in the virtual sapce. When specifying `-p`, fxos loads the most recent project with the provided name.
When specifying an existing folder as argument (1), fxos assumes the folder is a project folder and attempts to load it. When specifying an existing file (2), a new temporary project is created, with that file mapped in the virtual space. When specifying `-p`, fxos loads the most recent project with the provided name.
**`pl`: Project Load**
@ -83,5 +83,5 @@ When specifying an existing folder as argument (1), fxos assumes the folder is a
pl (<name> | "<path>")
```
`pl` loads an existing project. With a symbol argument, loads a recent project by name. With string that identifies a folder, loads a project from the filesystem.
`pl` loads an existing project. With a symbol argument, loads a recent project by name. With a string that identifies a folder, loads a project from the filesystem.

View File

@ -213,6 +213,21 @@ void _ip(Session &session)
for(auto &e: entries)
fmt::print(" {} ({}, last used {:%c})\n", e.name, e.path,
fmt::localtime(e.utime));
if(session.legacySpaces.size() != 0) {
fmt::print("\nLegacy vspaces:\n");
for(auto const &[name, lvs]: session.legacySpaces) {
fmt::print(" {} ({} symbols, {} syscalls)\n", name,
lvs.symbols.size(), lvs.syscalls.size());
for(auto const &b: lvs.bindings) {
fmt::print(" ");
for(auto const &r: b.regions)
fmt::print("0x{:08x} ", r.start);
fmt::print("'{}'\n", b.path);
}
}
}
}
//---

58
shell/legacy.cpp Normal file
View File

@ -0,0 +1,58 @@
#include "legacy.h"
#include "session.h"
#include "parser.h"
#include <fxos/util/log.h>
bool legacy_command(Session &session, std::string const &cmd, Parser &parser)
{
if(cmd == "vc") {
std::string name
= parser.at_end()
? session.legacyGenerateSpaceName("space", true)
: session.legacyGenerateSpaceName(parser.symbol(), false);
parser.end();
/* Construct a new legacy space at name */
session.legacySpaces[name];
session.legacyCurrentSpace = name;
return true;
}
else if(cmd == "vm") {
LegacyBinding b;
b.path = parser.str();
while(!parser.at_end())
b.regions.push_back(parser.region(nullptr));
parser.end();
session.legacySpaces[session.legacyCurrentSpace].bindings.push_back(b);
return true;
}
else if(cmd == "vs") {
std::string name = parser.symbol("vspace_name");
parser.end();
if(session.legacySpaces.count(name))
session.legacyCurrentSpace = name;
return true;
}
else if(cmd == "ms") {
auto &lvs = session.legacySpaces[session.legacyCurrentSpace];
if(parser.lookahead().type == T::SYSCALL) {
int id = parser.expect(T::SYSCALL).value.NUM;
lvs.syscalls[id] = parser.symbol();
}
else {
int addr = parser.expr(nullptr);
lvs.symbols[addr] = parser.symbol();
}
return true;
}
else if(cmd != "." && cmd != ".dt") {
FxOS_log(
WRN, "skipping unrecognized command '%s' in fxosrc", cmd.c_str());
}
return false;
}

39
shell/legacy.h Normal file
View File

@ -0,0 +1,39 @@
//---
// fxos-shell.legacy: Legacy vpsace/pseudo-project format
//---
#ifndef FXOS_LEGACY_H
#define FXOS_LEGACY_H
#include <fxos/util/types.h>
#include <fxos/memory.h>
class Session;
class Parser;
#include <string>
#include <vector>
#include <map>
struct LegacyBinding
{
std::string path;
std::vector<FxOS::MemoryRegion> regions;
};
/* Flat description of a legacy vspace loaded via an fxosrc file. Name might be
empty. */
struct LegacyVspace
{
LegacyVspace() = default;
std::vector<LegacyBinding> bindings;
std::map<u32,std::string> symbols;
std::map<int,std::string> syscalls;
};
/* Try to execute a given command as a legacy command. Returns true if handled,
false if normal behavior should be used. */
bool legacy_command(Session &session, std::string const &cmd, Parser &parser);
#endif /* FXOS_LEGACY_H */

View File

@ -17,6 +17,7 @@ namespace fs = std::filesystem;
#include "shell.h"
#include "theme.h"
#include "parser.h"
#include "legacy.h"
#include "errors.h"
#include "commands.h"
#include <fxos/util/log.h>
@ -153,24 +154,20 @@ char *autocomplete(char const *text, int state)
static bool read_interactive(Session &s, std::string &cmdline)
{
std::string prompt = "no_vspace> ";
if(s.current_space) {
std::string name = "(none)";
std::string prompt;
for(auto &it: s.spaces) {
if(it.second.get() == s.current_space)
name = it.first;
}
Project *p = s.project();
if(p)
prompt += p->name() + (p->isDirty() ? "*" : "");
Project *p = s.project();
if(!p)
prompt
= fmt::format("{} @ 0x{:08x}> ", name, s.current_space->cursor);
else
prompt = fmt::format(
"{}{}|{}> ", p->name(), p->isDirty() ? "*" : "", name);
std::string vspace_name = "(none)";
for(auto &it: s.spaces) {
if(it.second.get() == s.current_space)
vspace_name = it.first;
}
prompt += fmt::format("|{}> ", vspace_name);
/* We need to insert RL_PROMPT_{START,END}_IGNORE into the color
formatting, so we trick a little bit by using a space */
std::string color = fmt::format(theme(9), " ");
@ -426,8 +423,10 @@ int main(int argc, char **argv)
if(fs::exists(path / "fxosrc"))
fxosrc_files.push_back(path / "fxosrc");
}
if(fxosrc_files.size() > 0)
if(fxosrc_files.size() > 0) {
_dot(s, fxosrc_files, true);
FxOS_log(WRN, "Legacy fxosrc files found; use pm to migrate.");
}
}
/* Whether we have reached an idle state after parsing fxosrc files */
@ -477,6 +476,9 @@ int main(int argc, char **argv)
if(cmd == "_p") {
parser.dump_command();
}
else if(!has_idled && legacy_command(s, cmd, parser)) {
continue;
}
else if(commands.count(cmd)) {
if(parser.lookahead().type == '?')
command_help(cmd);

View File

@ -104,6 +104,12 @@ VirtualSpace *Session::get_space(std::string name)
return it == this->spaces.end() ? nullptr : it->second.get();
}
std::string Session::legacyGenerateSpaceName(
std::string prefix, bool force_suffix)
{
return generate_space_name(prefix, force_suffix);
}
std::string Session::generate_space_name(std::string prefix, bool force_suffix)
{
if(!force_suffix && this->spaces.count(prefix) == 0)

View File

@ -5,6 +5,7 @@
#ifndef FXOS_SESSION_H
#define FXOS_SESSION_H
#include "legacy.h"
#include <fxos/vspace.h>
#include <fxos/project.h>
@ -72,6 +73,14 @@ struct Session
return m_recent;
}
//=== Legacy (0.x) virtual space info for migrations ===//
std::map<std::string, LegacyVspace> legacySpaces;
std::string legacyCurrentSpace;
std::string legacyGenerateSpaceName(std::string prefix,
bool force_suffix=false);
//---
// Virtual spaces
// TODO: To be replaced with legacy descriptions