Implemented parsing of instruction patches in config file
This commit is contained in:
parent
7df3e28c76
commit
9949813018
|
@ -33,6 +33,12 @@ namespace RecompPort {
|
||||||
// Mapping of function name to argument types
|
// Mapping of function name to argument types
|
||||||
using DeclaredFunctionMap = std::unordered_map<std::string, std::vector<FunctionArgType>>;
|
using DeclaredFunctionMap = std::unordered_map<std::string, std::vector<FunctionArgType>>;
|
||||||
|
|
||||||
|
struct InstructionPatch {
|
||||||
|
std::string func_name;
|
||||||
|
int32_t vram;
|
||||||
|
uint32_t value;
|
||||||
|
};
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
int32_t entrypoint;
|
int32_t entrypoint;
|
||||||
std::filesystem::path elf_path;
|
std::filesystem::path elf_path;
|
||||||
|
@ -40,6 +46,7 @@ namespace RecompPort {
|
||||||
std::filesystem::path relocatable_sections_path;
|
std::filesystem::path relocatable_sections_path;
|
||||||
std::vector<std::string> stubbed_funcs;
|
std::vector<std::string> stubbed_funcs;
|
||||||
DeclaredFunctionMap declared_funcs;
|
DeclaredFunctionMap declared_funcs;
|
||||||
|
std::vector<InstructionPatch> instruction_patches;
|
||||||
|
|
||||||
Config(const char* path);
|
Config(const char* path);
|
||||||
bool good() { return !bad; }
|
bool good() { return !bad; }
|
||||||
|
|
|
@ -4,13 +4,15 @@
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "recomp_port.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.
|
// Check if the stubs array exists.
|
||||||
const auto& stubs_data = toml::find_or<toml::value>(patches_data, "stubs", toml::value{});
|
const auto& stubs_data = toml::find_or<toml::value>(patches_data, "stubs", toml::value{});
|
||||||
|
|
||||||
if (stubs_data.type() == toml::value_t::empty) {
|
if (stubs_data.type() == toml::value_t::empty) {
|
||||||
// No stubs, nothing to do here.
|
// No stubs, nothing to do here.
|
||||||
return;
|
return stubbed_funcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the stubs array as an array type.
|
// 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.
|
// Copy the entry into the stubbed function list.
|
||||||
stubbed_funcs[stub_idx] = stubs_array[stub_idx].as_string();
|
stubbed_funcs[stub_idx] = stubs_array[stub_idx].as_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return stubbed_funcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<std::string, RecompPort::FunctionArgType> arg_type_map{
|
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;
|
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.
|
// Check if the func array exists.
|
||||||
const toml::value& funcs_data = toml::find_or<toml::value>(patches_data, "func", toml::value{});
|
const toml::value& funcs_data = toml::find_or<toml::value>(patches_data, "func", toml::value{});
|
||||||
if (funcs_data.type() == toml::value_t::empty) {
|
if (funcs_data.type() == toml::value_t::empty) {
|
||||||
// No func array, nothing to do here
|
// No func array, nothing to do here
|
||||||
return;
|
return declared_funcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the funcs array as an array type.
|
// 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));
|
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) {
|
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{});
|
const toml::value& patches_data = toml::find_or<toml::value>(config_data, "patches", toml::value{});
|
||||||
if (patches_data.type() != toml::value_t::empty) {
|
if (patches_data.type() != toml::value_t::empty) {
|
||||||
// Stubs array (optional)
|
// Stubs array (optional)
|
||||||
get_stubbed_funcs(stubbed_funcs, patches_data);
|
stubbed_funcs = get_stubbed_funcs(patches_data);
|
||||||
|
|
||||||
// Functions (optional)
|
// 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) {
|
catch (const toml::syntax_error& err) {
|
||||||
|
|
Loading…
Reference in a new issue