mirror of
				https://github.com/N64Recomp/N64Recomp.git
				synced 2025-10-30 08:02:11 +00:00 
			
		
		
		
	Added toml11 and implemented initial config file parsing, replaces command-line arg inputs
This commit is contained in:
		
							parent
							
								
									f4324ee599
								
							
						
					
					
						commit
						fba0085946
					
				
					 8 changed files with 199 additions and 47 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							|  | @ -7,3 +7,6 @@ | |||
| [submodule "lib/fmt"] | ||||
| 	path = lib/fmt | ||||
| 	url = https://github.com/fmtlib/fmt | ||||
| [submodule "lib/toml11"] | ||||
| 	path = lib/toml11 | ||||
| 	url = https://github.com/ToruNiina/toml11 | ||||
|  |  | |||
|  | @ -77,7 +77,7 @@ | |||
|       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> | ||||
|       <Optimization>Disabled</Optimization> | ||||
|       <LanguageStandard>stdcpp20</LanguageStandard> | ||||
|       <AdditionalIncludeDirectories>$(SolutionDir)lib\rabbitizer\include;$(SolutionDir)lib\rabbitizer\cplusplus\include;$(SolutionDir)lib\ELFIO;$(SolutionDir)lib\fmt\include;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <AdditionalIncludeDirectories>$(SolutionDir)lib\rabbitizer\include;$(SolutionDir)lib\rabbitizer\cplusplus\include;$(SolutionDir)lib\ELFIO;$(SolutionDir)lib\fmt\include;$(SolutionDir)lib\toml11;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <OpenMPSupport>true</OpenMPSupport> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|  | @ -94,7 +94,7 @@ | |||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> | ||||
|       <LanguageStandard>stdcpp20</LanguageStandard> | ||||
|       <AdditionalIncludeDirectories>$(SolutionDir)lib\rabbitizer\include;$(SolutionDir)lib\rabbitizer\cplusplus\include;$(SolutionDir)lib\ELFIO;$(SolutionDir)lib\fmt\include;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <AdditionalIncludeDirectories>$(SolutionDir)lib\rabbitizer\include;$(SolutionDir)lib\rabbitizer\cplusplus\include;$(SolutionDir)lib\ELFIO;$(SolutionDir)lib\fmt\include;$(SolutionDir)lib\toml11;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <OpenMPSupport>true</OpenMPSupport> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|  | @ -109,7 +109,7 @@ | |||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | ||||
|     <ClCompile> | ||||
|       <LanguageStandard>stdcpp20</LanguageStandard> | ||||
|       <AdditionalIncludeDirectories>$(SolutionDir)lib\rabbitizer\include;$(SolutionDir)lib\rabbitizer\cplusplus\include;$(SolutionDir)lib\ELFIO;$(SolutionDir)lib\fmt\include;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <AdditionalIncludeDirectories>$(SolutionDir)lib\rabbitizer\include;$(SolutionDir)lib\rabbitizer\cplusplus\include;$(SolutionDir)lib\ELFIO;$(SolutionDir)lib\fmt\include;$(SolutionDir)lib\toml11;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <OpenMPSupport>true</OpenMPSupport> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|  | @ -120,7 +120,7 @@ | |||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | ||||
|     <ClCompile> | ||||
|       <LanguageStandard>stdcpp20</LanguageStandard> | ||||
|       <AdditionalIncludeDirectories>$(SolutionDir)lib\rabbitizer\include;$(SolutionDir)lib\rabbitizer\cplusplus\include;$(SolutionDir)lib\ELFIO;$(SolutionDir)lib\fmt\include;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <AdditionalIncludeDirectories>$(SolutionDir)lib\rabbitizer\include;$(SolutionDir)lib\rabbitizer\cplusplus\include;$(SolutionDir)lib\ELFIO;$(SolutionDir)lib\fmt\include;$(SolutionDir)lib\toml11;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <OpenMPSupport>true</OpenMPSupport> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|  | @ -138,6 +138,7 @@ | |||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="src\analysis.cpp" /> | ||||
|     <ClCompile Include="src\config.cpp" /> | ||||
|     <ClCompile Include="src\main.cpp" /> | ||||
|     <ClCompile Include="src\recompilation.cpp" /> | ||||
|   </ItemGroup> | ||||
|  |  | |||
|  | @ -24,6 +24,9 @@ | |||
|     <ClCompile Include="src\analysis.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="src\config.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="lib\ELFIO\elfio\elfio.hpp"> | ||||
|  |  | |||
|  | @ -8,6 +8,8 @@ | |||
| #include <unordered_map> | ||||
| #include <span> | ||||
| #include <unordered_set> | ||||
| #include <filesystem> | ||||
| #include "rabbitizer.hpp" | ||||
| #include "elfio/elfio.hpp" | ||||
| 
 | ||||
| #ifdef _MSC_VER | ||||
|  | @ -22,6 +24,29 @@ constexpr uint32_t byteswap(uint32_t val) { | |||
| 
 | ||||
| namespace RecompPort { | ||||
| 
 | ||||
|     // Potential argument types for function declarations
 | ||||
|     enum class FunctionArgType { | ||||
|         u32, | ||||
|         s32, | ||||
|     }; | ||||
| 
 | ||||
|     // Mapping of function name to argument types
 | ||||
|     using DeclaredFunctionMap = std::unordered_map<std::string, std::vector<FunctionArgType>>; | ||||
| 
 | ||||
|     struct Config { | ||||
|         int32_t entrypoint; | ||||
|         std::filesystem::path elf_path; | ||||
|         std::filesystem::path output_func_path; | ||||
|         std::filesystem::path relocatable_sections_path; | ||||
|         std::vector<std::string> stubbed_funcs; | ||||
|         DeclaredFunctionMap declared_funcs; | ||||
| 
 | ||||
|         Config(const char* path); | ||||
|         bool good() { return !bad; } | ||||
|     private: | ||||
|         bool bad; | ||||
|     }; | ||||
| 
 | ||||
|     struct JumpTable { | ||||
|         uint32_t vram; | ||||
|         uint32_t addend_reg; | ||||
|  | @ -68,14 +93,14 @@ namespace RecompPort { | |||
|     }; | ||||
| 
 | ||||
|     struct Section { | ||||
|         ELFIO::Elf_Xword rom_addr; | ||||
|         ELFIO::Elf64_Addr ram_addr; | ||||
|         ELFIO::Elf_Xword size; | ||||
|         ELFIO::Elf_Xword rom_addr = 0; | ||||
|         ELFIO::Elf64_Addr ram_addr = 0; | ||||
|         ELFIO::Elf_Xword size = 0; | ||||
|         std::vector<uint32_t> function_addrs; | ||||
|         std::vector<Reloc> relocs; | ||||
|         std::string name; | ||||
|         bool executable; | ||||
|         bool relocatable; | ||||
|         bool executable = false; | ||||
|         bool relocatable = false; | ||||
|     }; | ||||
| 
 | ||||
|     struct FunctionStats { | ||||
|  | @ -106,7 +131,7 @@ namespace RecompPort { | |||
|     }; | ||||
| 
 | ||||
|     bool analyze_function(const Context& context, const Function& function, const std::vector<rabbitizer::InstructionCpu>& instructions, FunctionStats& stats); | ||||
|     bool recompile_function(const Context& context, const Function& func, std::string_view output_path, std::span<std::vector<uint32_t>> static_funcs); | ||||
|     bool recompile_function(const Context& context, const Function& func, const std::filesystem::path& output_path, std::span<std::vector<uint32_t>> static_funcs); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										1
									
								
								lib/toml11
									
										
									
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								lib/toml11
									
										
									
									
									
										Submodule
									
								
							|  | @ -0,0 +1 @@ | |||
| Subproject commit d47fe788bcb08c9d0d2a73954a0dfaf512964fdc | ||||
							
								
								
									
										126
									
								
								src/config.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								src/config.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,126 @@ | |||
| #include <source_location> | ||||
| 
 | ||||
| #include "toml.hpp" | ||||
| #include "fmt/format.h" | ||||
| #include "recomp_port.h" | ||||
| 
 | ||||
| void get_stubbed_funcs(std::vector<std::string>& stubbed_funcs, const toml::value& patches_data) { | ||||
| 	// 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; | ||||
| 	} | ||||
| 
 | ||||
| 	// Get the stubs array as an array type.
 | ||||
| 	const toml::array& stubs_array = stubs_data.as_array(); | ||||
| 
 | ||||
| 	// Make room for all the stubs in the array.
 | ||||
| 	stubbed_funcs.resize(stubs_array.size()); | ||||
| 
 | ||||
| 	// Gather the stubs and place them into the array.
 | ||||
| 	for (size_t stub_idx = 0; stub_idx < stubs_array.size(); stub_idx++) { | ||||
| 		// Copy the entry into the stubbed function list.
 | ||||
| 		stubbed_funcs[stub_idx] = stubs_array[stub_idx].as_string(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| std::unordered_map<std::string, RecompPort::FunctionArgType> arg_type_map{ | ||||
| 	{"u32", RecompPort::FunctionArgType::u32}, | ||||
| 	{"s32", RecompPort::FunctionArgType::s32}, | ||||
| }; | ||||
| 
 | ||||
| std::vector<RecompPort::FunctionArgType> parse_args(const toml::array& args_in) { | ||||
| 	std::vector<RecompPort::FunctionArgType> ret(args_in.size()); | ||||
| 
 | ||||
| 	for (size_t arg_idx = 0; arg_idx < args_in.size(); arg_idx++) { | ||||
| 		const toml::value& arg_val = args_in[arg_idx]; | ||||
| 		const std::string& arg_str = arg_val.as_string(); | ||||
| 
 | ||||
| 		// Check if the argument type string is valid.
 | ||||
| 		auto type_find = arg_type_map.find(arg_str); | ||||
| 		if (type_find == arg_type_map.end()) { | ||||
| 			// It's not, so throw an error (and make it look like a normal toml one).
 | ||||
| 			throw toml::type_error(toml::detail::format_underline( | ||||
| 				std::string{ std::source_location::current().function_name() } + ": invalid function arg type", { | ||||
| 					{arg_val.location(), ""} | ||||
| 				}), arg_val.location()); | ||||
| 		} | ||||
| 		ret[arg_idx] = type_find->second; | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void get_declared_funcs(RecompPort::DeclaredFunctionMap& declared_funcs, const toml::value& patches_data) { | ||||
| 	// 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; | ||||
| 	} | ||||
| 
 | ||||
| 	// Get the funcs array as an array type.
 | ||||
| 	const toml::array& funcs_array = funcs_data.as_array(); | ||||
| 
 | ||||
| 	// Reserve room for all the funcs in the map.
 | ||||
| 	declared_funcs.reserve(funcs_data.size()); | ||||
| 	for (const toml::value& cur_func_val : funcs_array) { | ||||
| 		const std::string& func_name = toml::find<std::string>(cur_func_val, "name"); | ||||
| 		const toml::array& args_in = toml::find<toml::array>(cur_func_val, "args"); | ||||
| 		 | ||||
| 		declared_funcs.emplace(func_name, parse_args(args_in)); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path concat_if_not_empty(const std::filesystem::path& parent, const std::filesystem::path& child) { | ||||
| 	if (!child.empty()) { | ||||
| 		return parent / child; | ||||
| 	} | ||||
| 	return child; | ||||
| } | ||||
| 
 | ||||
| RecompPort::Config::Config(const char* path) { | ||||
| 	// Start this config out as bad so that it has to finish parsing without errors to be good.
 | ||||
| 	entrypoint = 0; | ||||
| 	bad = true; | ||||
| 
 | ||||
| 	try { | ||||
| 		const toml::value config_data = toml::parse(path); | ||||
| 		std::filesystem::path basedir = std::filesystem::path{ path }.parent_path(); | ||||
| 
 | ||||
| 		// Input section (required)
 | ||||
| 		const toml::value& input_data = toml::find<toml::value>(config_data, "input"); | ||||
| 
 | ||||
| 		entrypoint = toml::find<int32_t>(input_data, "entrypoint"); | ||||
| 		elf_path                  = concat_if_not_empty(basedir, toml::find<std::string>(input_data, "elf_path")); | ||||
| 		output_func_path          = concat_if_not_empty(basedir, toml::find<std::string>(input_data, "output_func_path")); | ||||
| 		relocatable_sections_path = concat_if_not_empty(basedir, toml::find_or<std::string>(input_data, "relocatable_sections_path", "")); | ||||
| 
 | ||||
| 		// Patches section (optional)
 | ||||
| 		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); | ||||
| 
 | ||||
| 			// Functions (optional)
 | ||||
| 			get_declared_funcs(declared_funcs, patches_data); | ||||
| 		} | ||||
| 	} | ||||
| 	catch (const toml::syntax_error& err) { | ||||
| 		fmt::print(stderr, "Syntax error in config file on line {}, full error:\n{}\n", err.location().line(), err.what()); | ||||
| 		return; | ||||
| 	} | ||||
| 	catch (const toml::type_error& err) { | ||||
| 		fmt::print(stderr, "Incorrect type in config file on line {}, full error:\n{}\n", err.location().line(), err.what()); | ||||
| 		return; | ||||
| 	} | ||||
| 	catch (const std::out_of_range& err) { | ||||
| 		fmt::print(stderr, "Missing value in config file, full error:\n{}\n", err.what()); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	// No errors occured, so mark this config file as good.
 | ||||
| 	bad = false; | ||||
| } | ||||
							
								
								
									
										59
									
								
								src/main.cpp
									
										
									
									
									
								
							
							
						
						
									
										59
									
								
								src/main.cpp
									
										
									
									
									
								
							|  | @ -10,7 +10,6 @@ | |||
| #include "fmt/ostream.h" | ||||
| 
 | ||||
| #include "recomp_port.h" | ||||
| #include "main.h" | ||||
| #include <set> | ||||
| 
 | ||||
| std::unordered_set<std::string> reimplemented_funcs{ | ||||
|  | @ -964,7 +963,7 @@ void analyze_sections(RecompPort::Context& context, const ELFIO::elfio& elf_file | |||
|     ); | ||||
| } | ||||
| 
 | ||||
| bool read_list_file(const char* filename, std::unordered_set<std::string>& entries_out) { | ||||
| bool read_list_file(const std::filesystem::path& filename, std::unordered_set<std::string>& entries_out) { | ||||
|     std::ifstream input_file{ filename }; | ||||
|     if (!input_file.good()) { | ||||
|         return false; | ||||
|  | @ -980,47 +979,41 @@ bool read_list_file(const char* filename, std::unordered_set<std::string>& entri | |||
| } | ||||
| 
 | ||||
| int main(int argc, char** argv) { | ||||
|     if (argc < 4 || argc > 5) { | ||||
|         fmt::print("Usage: {} [input elf file] [entrypoint RAM address] [output path] [relocatable sections list file (optional)]\n", argv[0]); | ||||
|     auto exit_failure = [] (const std::string& error_str) { | ||||
|         fmt::print(stderr, error_str); | ||||
|         std::exit(EXIT_FAILURE); | ||||
|     }; | ||||
| 
 | ||||
|     if (argc != 2) { | ||||
|         fmt::print("Usage: {} [config file]\n", argv[0]); | ||||
|         std::exit(EXIT_SUCCESS); | ||||
|     } | ||||
| 
 | ||||
|     const char* config_path = argv[1]; | ||||
| 
 | ||||
|     RecompPort::Config config{ config_path }; | ||||
|     if (!config.good()) { | ||||
|         exit_failure(fmt::format("Failed to load config file: {}\n", config_path)); | ||||
|     } | ||||
| 
 | ||||
|     ELFIO::elfio elf_file; | ||||
|     RabbitizerConfig_Cfg.pseudos.pseudoMove = false; | ||||
|     RabbitizerConfig_Cfg.pseudos.pseudoBeqz = false; | ||||
|     RabbitizerConfig_Cfg.pseudos.pseudoBnez = false; | ||||
|     RabbitizerConfig_Cfg.pseudos.pseudoNot = false; | ||||
| 
 | ||||
|     auto exit_failure = [] (const std::string& error_str) { | ||||
|         fmt::print(stderr, error_str); | ||||
|         std::exit(EXIT_FAILURE); | ||||
|     }; | ||||
| 
 | ||||
|     std::unordered_set<std::string> relocatable_sections{}; | ||||
| 
 | ||||
|     if (argc == 5) { | ||||
|         if (!read_list_file(argv[4], relocatable_sections)) { | ||||
|     if (!config.relocatable_sections_path.empty()) { | ||||
|         if (!read_list_file(config.relocatable_sections_path, relocatable_sections)) { | ||||
|             exit_failure("Failed to load the relocatable section list file: " + std::string(argv[4]) + "\n"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     std::string output_dir{ argv[3] }; | ||||
|     std::string elf_name{ argv[1] }; | ||||
| 
 | ||||
|     if (!output_dir.ends_with('/')) { | ||||
|         output_dir += "/"; | ||||
|     } | ||||
| 
 | ||||
|     if (!elf_file.load(elf_name)) { | ||||
|     if (!elf_file.load(config.elf_path.string())) { | ||||
|         exit_failure("Failed to load provided elf file\n"); | ||||
|     } | ||||
| 
 | ||||
|     char* end; | ||||
|     const uint32_t entrypoint = (uint32_t)strtoul(argv[2], &end, 0); | ||||
|     if (argv[2] == end) { | ||||
|         exit_failure("Invalid entrypoint value: " + std::string(argv[2]) + "\n"); | ||||
|     } | ||||
| 
 | ||||
|     if (elf_file.get_class() != ELFIO::ELFCLASS32) { | ||||
|         exit_failure("Incorrect elf class\n"); | ||||
|     } | ||||
|  | @ -1044,7 +1037,7 @@ int main(int argc, char** argv) { | |||
|     } | ||||
| 
 | ||||
|     // Read all of the symbols in the elf and look for the entrypoint function
 | ||||
|     bool found_entrypoint_func = read_symbols(context, elf_file, symtab_section, entrypoint); | ||||
|     bool found_entrypoint_func = read_symbols(context, elf_file, symtab_section, config.entrypoint); | ||||
| 
 | ||||
|     if (!found_entrypoint_func) { | ||||
|         exit_failure("Could not find entrypoint function\n"); | ||||
|  | @ -1052,8 +1045,8 @@ int main(int argc, char** argv) { | |||
| 
 | ||||
|     fmt::print("Function count: {}\n", context.functions.size()); | ||||
| 
 | ||||
|     std::ofstream lookup_file{ output_dir + "lookup.cpp" }; | ||||
|     std::ofstream func_header_file{ output_dir + "funcs.h" }; | ||||
|     std::ofstream lookup_file{ config.output_func_path / "lookup.cpp" }; | ||||
|     std::ofstream func_header_file{ config.output_func_path / "funcs.h" }; | ||||
| 
 | ||||
|     fmt::print(lookup_file, | ||||
|         //"#include <utility>\n"
 | ||||
|  | @ -1085,7 +1078,7 @@ int main(int argc, char** argv) { | |||
|                 "void {}(uint8_t* rdram, recomp_context* ctx);\n", func.name); | ||||
|             //fmt::print(lookup_file,
 | ||||
|             //    "    {{ 0x{:08X}u, {} }},\n", func.vram, func.name);
 | ||||
|             if (RecompPort::recompile_function(context, func, output_dir + func.name + ".c", static_funcs_by_section) == false) { | ||||
|             if (RecompPort::recompile_function(context, func, config.output_func_path / (func.name + ".c"), static_funcs_by_section) == false) { | ||||
|                 //lookup_file.clear();
 | ||||
|                 fmt::print(stderr, "Error recompiling {}\n", func.name); | ||||
|                 std::exit(EXIT_FAILURE); | ||||
|  | @ -1151,7 +1144,7 @@ int main(int argc, char** argv) { | |||
|                        "void {}(uint8_t* rdram, recomp_context* ctx);\n", func.name); | ||||
|             //fmt::print(lookup_file,
 | ||||
|             //           "    {{ 0x{:08X}u, {} }},\n", func.vram, func.name);
 | ||||
|             if (RecompPort::recompile_function(context, func, output_dir + func.name + ".c", static_funcs_by_section) == false) { | ||||
|             if (RecompPort::recompile_function(context, func, config.output_func_path / (func.name + ".c"), static_funcs_by_section) == false) { | ||||
|                 //lookup_file.clear();
 | ||||
|                 fmt::print(stderr, "Error recompiling {}\n", func.name); | ||||
|                 std::exit(EXIT_FAILURE); | ||||
|  | @ -1167,8 +1160,8 @@ int main(int argc, char** argv) { | |||
|         "\n" | ||||
|         "const char* get_rom_name() {{ return \"{}\"; }}\n" | ||||
|         "\n", | ||||
|         entrypoint, | ||||
|         std::filesystem::path{ elf_name }.filename().replace_extension(".z64").string() | ||||
|         config.entrypoint, | ||||
|         config.elf_path.filename().replace_extension(".z64").string() | ||||
|     ); | ||||
| 
 | ||||
|     fmt::print(func_header_file, | ||||
|  | @ -1179,7 +1172,7 @@ int main(int argc, char** argv) { | |||
|     ); | ||||
| 
 | ||||
|     { | ||||
|         std::ofstream overlay_file(output_dir + "recomp_overlays.inl"); | ||||
|         std::ofstream overlay_file(config.output_func_path / "recomp_overlays.inl"); | ||||
|         std::string section_load_table = "static SectionTableEntry section_table[] = {\n"; | ||||
| 
 | ||||
|         fmt::print(overlay_file,  | ||||
|  |  | |||
|  | @ -976,14 +976,14 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::F | |||
|     return true; | ||||
| } | ||||
| 
 | ||||
| bool RecompPort::recompile_function(const RecompPort::Context& context, const RecompPort::Function& func, std::string_view output_path, std::span<std::vector<uint32_t>> static_funcs_out) { | ||||
| bool RecompPort::recompile_function(const RecompPort::Context& context, const RecompPort::Function& func, const std::filesystem::path& output_path, std::span<std::vector<uint32_t>> static_funcs_out) { | ||||
|     //fmt::print("Recompiling {}\n", func.name);
 | ||||
|     std::vector<rabbitizer::InstructionCpu> instructions; | ||||
| 
 | ||||
|     // Open the output file and write the file header
 | ||||
|     std::ofstream output_file{ output_path.data() }; | ||||
|     std::ofstream output_file{ output_path }; | ||||
|     if (!output_file.good()) { | ||||
|         fmt::print(stderr, "Failed to open file for writing: {}\n", output_path); | ||||
|         fmt::print(stderr, "Failed to open file for writing: {}\n", output_path.string() ); | ||||
|         return false; | ||||
|     } | ||||
|     fmt::print(output_file, | ||||
|  | @ -1065,7 +1065,7 @@ bool RecompPort::recompile_function(const RecompPort::Context& context, const Re | |||
|          | ||||
|         // Process the current instruction and check for errors
 | ||||
|         if (process_instruction(context, func, stats, skipped_insns, instr_index, instructions, output_file, false, needs_link_branch, num_link_branches, reloc_index, needs_link_branch, is_branch_likely, static_funcs_out) == false) { | ||||
|             fmt::print(stderr, "Error in recompilation, clearing {}\n", output_path); | ||||
|             fmt::print(stderr, "Error in recompilation, clearing {}\n", output_path.string() ); | ||||
|             output_file.clear(); | ||||
|             return false; | ||||
|         } | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Mr-Wiseguy
						Mr-Wiseguy