Implemented parsing of instruction patches in config file

This commit is contained in:
Mr-Wiseguy 2023-03-24 19:22:30 -04:00
parent 7df3e28c76
commit 9949813018
2 changed files with 50 additions and 6 deletions

View file

@ -33,6 +33,12 @@ namespace RecompPort {
// Mapping of function name to argument types
using DeclaredFunctionMap = std::unordered_map<std::string, std::vector<FunctionArgType>>;
struct InstructionPatch {
std::string func_name;
int32_t vram;
uint32_t value;
};
struct Config {
int32_t entrypoint;
std::filesystem::path elf_path;
@ -40,6 +46,7 @@ namespace RecompPort {
std::filesystem::path relocatable_sections_path;
std::vector<std::string> stubbed_funcs;
DeclaredFunctionMap declared_funcs;
std::vector<InstructionPatch> instruction_patches;
Config(const char* path);
bool good() { return !bad; }

View file

@ -4,13 +4,15 @@
#include "fmt/format.h"
#include "recomp_port.h"
void get_stubbed_funcs(std::vector<std::string>& stubbed_funcs, const toml::value& patches_data) {
std::vector<std::string> get_stubbed_funcs(const toml::value& patches_data) {
std::vector<std::string> stubbed_funcs{};
// Check if the stubs array exists.
const auto& stubs_data = toml::find_or<toml::value>(patches_data, "stubs", toml::value{});
if (stubs_data.type() == toml::value_t::empty) {
// No stubs, nothing to do here.
return;
return stubbed_funcs;
}
// Get the stubs array as an array type.
@ -24,6 +26,8 @@ void get_stubbed_funcs(std::vector<std::string>& stubbed_funcs, const toml::valu
// Copy the entry into the stubbed function list.
stubbed_funcs[stub_idx] = stubs_array[stub_idx].as_string();
}
return stubbed_funcs;
}
std::unordered_map<std::string, RecompPort::FunctionArgType> arg_type_map{
@ -53,12 +57,14 @@ std::vector<RecompPort::FunctionArgType> parse_args(const toml::array& args_in)
return ret;
}
void get_declared_funcs(RecompPort::DeclaredFunctionMap& declared_funcs, const toml::value& patches_data) {
RecompPort::DeclaredFunctionMap get_declared_funcs(const toml::value& patches_data) {
RecompPort::DeclaredFunctionMap declared_funcs{};
// Check if the func array exists.
const toml::value& funcs_data = toml::find_or<toml::value>(patches_data, "func", toml::value{});
if (funcs_data.type() == toml::value_t::empty) {
// No func array, nothing to do here
return;
return declared_funcs;
}
// Get the funcs array as an array type.
@ -72,6 +78,34 @@ void get_declared_funcs(RecompPort::DeclaredFunctionMap& declared_funcs, const t
declared_funcs.emplace(func_name, parse_args(args_in));
}
return declared_funcs;
}
std::vector<RecompPort::InstructionPatch> get_instruction_patches(const toml::value& patches_data) {
std::vector<RecompPort::InstructionPatch> ret;
// Check if the instruction patch array exists.
const toml::value& insn_patch_data = toml::find_or<toml::value>(patches_data, "instruction", toml::value{});
if (insn_patch_data.type() == toml::value_t::empty) {
// No instruction patch array, nothing to do here
return ret;
}
// Get the instruction patch array as an array type.
const toml::array& insn_patch_array = insn_patch_data.as_array();
ret.resize(insn_patch_array.size());
// Copy all the patches into the output vector.
for (size_t patch_idx = 0; patch_idx < insn_patch_array.size(); patch_idx++) {
const toml::value& cur_patch = insn_patch_array[patch_idx];
ret[patch_idx].func_name = toml::find<std::string>(cur_patch, "func");
ret[patch_idx].vram = toml::find<int32_t>(cur_patch, "vram");
ret[patch_idx].value = toml::find<uint32_t>(cur_patch, "value");
}
return ret;
}
std::filesystem::path concat_if_not_empty(const std::filesystem::path& parent, const std::filesystem::path& child) {
@ -102,10 +136,13 @@ RecompPort::Config::Config(const char* path) {
const toml::value& patches_data = toml::find_or<toml::value>(config_data, "patches", toml::value{});
if (patches_data.type() != toml::value_t::empty) {
// Stubs array (optional)
get_stubbed_funcs(stubbed_funcs, patches_data);
stubbed_funcs = get_stubbed_funcs(patches_data);
// Functions (optional)
get_declared_funcs(declared_funcs, patches_data);
declared_funcs = get_declared_funcs(patches_data);
// Single-instruction patches (optional)
instruction_patches = get_instruction_patches(patches_data);
}
}
catch (const toml::syntax_error& err) {