update executable diff action
This commit is contained in:
@@ -661,3 +661,46 @@ vector<DiffEntry> diff_dol_files(const string& a_filename, const string& b_filen
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<DiffEntry> diff_xbe_files(const string& a_filename, const string& b_filename) {
|
||||||
|
ResourceDASM::XBEFile a(a_filename.c_str());
|
||||||
|
ResourceDASM::XBEFile b(b_filename.c_str());
|
||||||
|
auto a_mem = make_shared<ResourceDASM::MemoryContext>();
|
||||||
|
auto b_mem = make_shared<ResourceDASM::MemoryContext>();
|
||||||
|
a.load_into(a_mem);
|
||||||
|
b.load_into(b_mem);
|
||||||
|
|
||||||
|
uint32_t min_addr = 0xFFFFFFFF;
|
||||||
|
uint32_t max_addr = 0x00000000;
|
||||||
|
for (const auto& sec : a.sections) {
|
||||||
|
min_addr = min<uint32_t>(min_addr, sec.addr);
|
||||||
|
max_addr = max<uint32_t>(max_addr, sec.addr + sec.size);
|
||||||
|
}
|
||||||
|
for (const auto& sec : b.sections) {
|
||||||
|
min_addr = min<uint32_t>(min_addr, sec.addr);
|
||||||
|
max_addr = max<uint32_t>(max_addr, sec.addr + sec.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<DiffEntry> ret;
|
||||||
|
for (uint32_t addr = min_addr; addr < max_addr; addr++) {
|
||||||
|
bool a_exists = a_mem->exists(addr, 1);
|
||||||
|
bool b_exists = b_mem->exists(addr, 1);
|
||||||
|
if (a_exists && b_exists) {
|
||||||
|
uint8_t a_value = a_mem->read_u8(addr);
|
||||||
|
uint8_t b_value = b_mem->read_u8(addr);
|
||||||
|
if (a_value != b_value) {
|
||||||
|
if (!ret.empty() && (ret.back().address + ret.back().b_data.size() == addr)) {
|
||||||
|
auto& entry = ret.back();
|
||||||
|
entry.a_data.push_back(a_value);
|
||||||
|
entry.b_data.push_back(b_value);
|
||||||
|
} else {
|
||||||
|
auto& entry = ret.emplace_back();
|
||||||
|
entry.address = addr;
|
||||||
|
entry.a_data.push_back(a_value);
|
||||||
|
entry.b_data.push_back(b_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,3 +14,4 @@ struct DiffEntry {
|
|||||||
|
|
||||||
void run_address_translator(const std::string& directory, const std::string& use_filename, const std::string& command);
|
void run_address_translator(const std::string& directory, const std::string& use_filename, const std::string& command);
|
||||||
std::vector<DiffEntry> diff_dol_files(const std::string& a_filename, const std::string& b_filename);
|
std::vector<DiffEntry> diff_dol_files(const std::string& a_filename, const std::string& b_filename);
|
||||||
|
std::vector<DiffEntry> diff_xbe_files(const std::string& a_filename, const std::string& b_filename);
|
||||||
|
|||||||
+14
-3
@@ -2868,12 +2868,23 @@ Action a_address_translator(
|
|||||||
run_address_translator(dir, args.get<string>(2, false), args.get<string>(3, false));
|
run_address_translator(dir, args.get<string>(2, false), args.get<string>(3, false));
|
||||||
});
|
});
|
||||||
|
|
||||||
Action a_diff_dol_files(
|
Action a_diff_executables(
|
||||||
"diff-dol-files", nullptr, +[](phosg::Arguments& args) {
|
"diff-executables", nullptr, +[](phosg::Arguments& args) {
|
||||||
const string& a_filename = args.get<string>(1);
|
const string& a_filename = args.get<string>(1);
|
||||||
const string& b_filename = args.get<string>(2);
|
const string& b_filename = args.get<string>(2);
|
||||||
bool show_pre = args.get<bool>("show-pre");
|
bool show_pre = args.get<bool>("show-pre");
|
||||||
auto result = diff_dol_files(a_filename, b_filename);
|
bool a_is_dol = phosg::ends_with(a_filename, ".dol");
|
||||||
|
bool b_is_dol = phosg::ends_with(b_filename, ".dol");
|
||||||
|
bool a_is_xbe = phosg::ends_with(a_filename, ".xbe");
|
||||||
|
bool b_is_xbe = phosg::ends_with(b_filename, ".xbe");
|
||||||
|
std::vector<DiffEntry> result;
|
||||||
|
if (a_is_dol && b_is_dol) {
|
||||||
|
result = diff_dol_files(a_filename, b_filename);
|
||||||
|
} else if (a_is_xbe && b_is_xbe) {
|
||||||
|
result = diff_xbe_files(a_filename, b_filename);
|
||||||
|
} else {
|
||||||
|
throw runtime_error("the two files are not the same type of executable, or are neither dol nor xbe");
|
||||||
|
}
|
||||||
for (const auto& it : result) {
|
for (const auto& it : result) {
|
||||||
string b_str = phosg::format_data_string(it.b_data, nullptr, phosg::FormatDataFlags::HEX_ONLY);
|
string b_str = phosg::format_data_string(it.b_data, nullptr, phosg::FormatDataFlags::HEX_ONLY);
|
||||||
if (show_pre) {
|
if (show_pre) {
|
||||||
|
|||||||
Reference in New Issue
Block a user