aboutsummaryrefslogtreecommitdiff
path: root/zucchini_tools.cc
diff options
context:
space:
mode:
authorSamuel Huang <huangs@chromium.org>2018-04-30 22:47:52 +0000
committerEdward Lesmes <ehmaldonado@google.com>2021-07-23 22:17:29 +0000
commit6951a286379338eaa10a712989541ca77c0c2a9c (patch)
tree2b4b9f8addfe9aa37804bb52929a235a10b23239 /zucchini_tools.cc
parent93ffc913ec7d369818a109b9ca6de7adb278e163 (diff)
downloadzucchini-6951a286379338eaa10a712989541ca77c0c2a9c.tar.gz
[Zucchini] Introduce Imposed Ensemble Matcher.
Previously Zucchini-gen uses built-in heuristics to perform element matching for ensemble patch generation. This CL adds an option (accessible via the -impose parameter) to specify elements in "old" and "new", and how they match. This allows the default heuristics to be overridden, and enables external applications (who perhaps have better ideas of element matching, e.g., have access to archiving programs) to better use Zucchini to patch archives. Zucchini-match is updated to prints the -impose command line to repeat its results. Also, ElementMatch::ToString() is added. Change-Id: I541b64722904c2fcd19ed75246d87e0268fbf86c Reviewed-on: https://chromium-review.googlesource.com/1027191 Reviewed-by: Samuel Huang <huangs@chromium.org> Reviewed-by: Greg Thompson <grt@chromium.org> Commit-Queue: Samuel Huang <huangs@chromium.org> Cr-Commit-Position: refs/heads/master@{#554909} NOKEYCHECK=True GitOrigin-RevId: 73a64ffde3f3b64df576aa1f2b5baebf7ec964ba
Diffstat (limited to 'zucchini_tools.cc')
-rw-r--r--zucchini_tools.cc37
1 files changed, 25 insertions, 12 deletions
diff --git a/zucchini_tools.cc b/zucchini_tools.cc
index 57ff0b2..5fcf066 100644
--- a/zucchini_tools.cc
+++ b/zucchini_tools.cc
@@ -10,7 +10,7 @@
#include <algorithm>
#include <memory>
#include <ostream>
-#include <string>
+#include <utility>
#include "base/bind.h"
#include "base/logging.h"
@@ -19,6 +19,7 @@
#include "components/zucchini/element_detection.h"
#include "components/zucchini/ensemble_matcher.h"
#include "components/zucchini/heuristic_ensemble_matcher.h"
+#include "components/zucchini/imposed_ensemble_matcher.h"
#include "components/zucchini/io_utils.h"
namespace zucchini {
@@ -44,11 +45,10 @@ status::Code ReadReferences(ConstBufferView image,
targets.erase(std::unique(targets.begin(), targets.end()), targets.end());
size_t num_targets = targets.size();
- out << "Type " << int(group.type_tag().value());
- out << ": Pool=" << static_cast<uint32_t>(group.pool_tag().value());
- out << ", width=" << group.width();
- out << ", #locations=" << num_locations;
- out << ", #targets=" << num_targets;
+ out << "Type " << int(group.type_tag().value())
+ << ": Pool=" << static_cast<uint32_t>(group.pool_tag().value())
+ << ", width=" << group.width() << ", #locations=" << num_locations
+ << ", #targets=" << num_targets;
if (num_targets > 0) {
double ratio = static_cast<double>(num_locations) / num_targets;
out << " (ratio=" << base::StringPrintf("%.4f", ratio) << ")";
@@ -59,8 +59,8 @@ status::Code ReadReferences(ConstBufferView image,
refs = group.GetReader(disasm.get());
for (auto ref = refs->GetNext(); ref; ref = refs->GetNext()) {
- out << " " << AsHex<8>(ref->location);
- out << " " << AsHex<8>(ref->target) << std::endl;
+ out << " " << AsHex<8>(ref->location) << " " << AsHex<8>(ref->target)
+ << std::endl;
}
}
}
@@ -112,14 +112,27 @@ status::Code DetectAll(ConstBufferView image,
status::Code MatchAll(ConstBufferView old_image,
ConstBufferView new_image,
+ std::string imposed_matches,
std::ostream& out) {
- HeuristicEnsembleMatcher matcher(&out);
- if (!matcher.RunMatch(old_image, new_image)) {
+ std::unique_ptr<EnsembleMatcher> matcher;
+ if (imposed_matches.empty()) {
+ matcher = std::make_unique<HeuristicEnsembleMatcher>(&out);
+ } else {
+ matcher =
+ std::make_unique<ImposedEnsembleMatcher>(std::move(imposed_matches));
+ }
+ if (!matcher->RunMatch(old_image, new_image)) {
out << "RunMatch() failed.";
return status::kStatusFatal;
}
- out << "Found " << matcher.matches().size() << " nontrivial matches and "
- << matcher.num_identical() << " identical matches." << std::endl;
+ out << "Found " << matcher->matches().size() << " nontrivial matches and "
+ << matcher->num_identical() << " identical matches." << std::endl
+ << "To impose the same matches by command line, use: " << std::endl
+ << " -impose=";
+ PrefixSep sep(",");
+ for (const ElementMatch& match : matcher->matches())
+ out << sep << match.ToString();
+ out << std::endl;
return status::kStatusSuccess;
}