8#include "absl/strings/str_format.h"
9#include "absl/strings/str_join.h"
12#include "asar-dll-bindings/c/asar.h"
27 return absl::OkStatus();
31 int api_version = asar_apiversion();
32 if (api_version < 300) {
33 return absl::InternalError(absl::StrFormat(
34 "Asar API version %d is too old (required: 300+)", api_version));
38 return absl::OkStatus();
50 return "Not initialized";
53 int version = asar_version();
54 int major = version / 10000;
55 int minor = (version / 100) % 100;
56 int patch = version % 100;
58 return absl::StrFormat(
"%d.%d.%d", major, minor, patch);
65 return asar_apiversion();
69 const std::string& patch_path,
70 std::vector<uint8_t>& rom_data,
71 const std::vector<std::string>& include_paths) {
74 return absl::FailedPreconditionError(
"Asar not initialized");
84 int rom_size =
static_cast<int>(rom_data.size());
85 int buffer_size = std::max(rom_size, 16 * 1024 * 1024);
88 if (rom_data.size() < buffer_size) {
89 rom_data.resize(buffer_size, 0);
93 bool patch_success = asar_patch(
95 reinterpret_cast<char*
>(rom_data.data()),
109 rom_data.resize(rom_size);
116 result.
symbols.push_back(symbol);
123 return absl::InternalError(absl::StrFormat(
124 "Patch failed: %s", absl::StrJoin(
last_errors_,
"; ")));
131 const std::string& patch_content,
132 std::vector<uint8_t>& rom_data,
133 const std::string& base_path) {
136 std::string temp_path =
"/tmp/yaze_temp_patch.asm";
137 if (!base_path.empty()) {
139 std::filesystem::create_directories(base_path);
140 temp_path = base_path +
"/temp_patch.asm";
143 std::ofstream temp_file(temp_path);
145 return absl::InternalError(absl::StrFormat(
146 "Failed to create temporary patch file at: %s", temp_path));
149 temp_file << patch_content;
152 auto result =
ApplyPatch(temp_path, rom_data);
155 std::remove(temp_path.c_str());
161 const std::string& asm_path,
162 const std::vector<std::string>& include_paths) {
165 return absl::FailedPreconditionError(
"Asar not initialized");
169 std::vector<uint8_t> dummy_rom(1024 * 1024, 0);
171 auto result =
ApplyPatch(asm_path, dummy_rom, include_paths);
173 return result.status();
176 return result->symbols;
192 std::vector<AsarSymbol> symbols;
194 if (symbol.address == address) {
195 symbols.push_back(symbol);
211 const std::vector<uint8_t>& original_rom,
212 const std::vector<uint8_t>& modified_rom,
213 const std::string& patch_path) {
221 return absl::UnimplementedError(
222 "Patch creation from ROM differences not yet implemented");
227 std::vector<uint8_t> dummy_rom(1024, 0);
229 auto result =
ApplyPatch(asm_path, dummy_rom);
231 return result.status();
234 if (!result->success) {
235 return absl::InvalidArgumentError(absl::StrFormat(
236 "Assembly validation failed: %s",
237 absl::StrJoin(result->errors,
"; ")));
240 return absl::OkStatus();
247 const errordata* errors = asar_geterrors(&error_count);
249 for (
int i = 0; i < error_count; ++i) {
250 last_errors_.push_back(std::string(errors[i].fullerrdata));
257 int warning_count = 0;
258 const errordata* warnings = asar_getwarnings(&warning_count);
260 for (
int i = 0; i < warning_count; ++i) {
269 int symbol_count = 0;
270 const labeldata* labels = asar_getalllabels(&symbol_count);
272 for (
int i = 0; i < symbol_count; ++i) {
274 symbol.
name = std::string(labels[i].name);
275 symbol.
address = labels[i].location;
absl::StatusOr< AsarPatchResult > ApplyPatchFromString(const std::string &patch_content, std::vector< uint8_t > &rom_data, const std::string &base_path="")
Apply an assembly patch from string content.
AsarSymbol ConvertAsarSymbol(const void *asar_symbol_data) const
Convert Asar symbol data to AsarSymbol struct.
absl::Status CreatePatch(const std::vector< uint8_t > &original_rom, const std::vector< uint8_t > &modified_rom, const std::string &patch_path)
Create a patch that can be applied to transform one ROM to another.
void ProcessWarnings()
Process warnings from Asar and store them.
std::vector< std::string > last_warnings_
absl::Status ValidateAssembly(const std::string &asm_path)
Validate an assembly file for syntax errors.
std::optional< AsarSymbol > FindSymbol(const std::string &name) const
Find a symbol by name.
std::string GetVersion() const
Get Asar version information.
void ExtractSymbolsFromLastOperation()
Extract symbols from the last Asar operation.
void Shutdown()
Clean up and close the Asar library.
std::map< std::string, AsarSymbol > symbol_table_
void Reset()
Reset the Asar state (clear errors, warnings, symbols)
absl::Status Initialize()
Initialize the Asar library.
absl::StatusOr< AsarPatchResult > ApplyPatch(const std::string &patch_path, std::vector< uint8_t > &rom_data, const std::vector< std::string > &include_paths={})
Apply an assembly patch to a ROM.
std::vector< std::string > last_errors_
int GetApiVersion() const
Get Asar API version.
absl::StatusOr< std::vector< AsarSymbol > > ExtractSymbols(const std::string &asm_path, const std::vector< std::string > &include_paths={})
Extract symbols from an assembly file without patching.
void ProcessErrors()
Process errors from Asar and store them.
std::vector< AsarSymbol > GetSymbolsAtAddress(uint32_t address) const
Get symbols at a specific address.
std::map< std::string, AsarSymbol > GetSymbolTable() const
Get all available symbols from the last patch operation.
Main namespace for the application.
Asar patch result information.
std::vector< std::string > errors
std::vector< AsarSymbol > symbols
std::vector< std::string > warnings
Symbol information extracted from Asar assembly.