Files
Mergen/lifter/core/Lifter.cpp
T
2026-04-02 14:14:24 +03:00

125 lines
3.6 KiB
C++

#define MAGIC_ENUM_RANGE_MIN -1000
#define MAGIC_ENUM_RANGE_MAX 1000
#include "CommandLineHelpers.hpp"
#include "LifterApplication.hpp"
#include "LifterPipeline.hpp"
#include "LifterStages.hpp"
#include "MergenPB.hpp"
#include "Includes.h"
#include "LifterClass.hpp"
#include "LifterClass_Concolic.hpp"
#include "LifterClass_Symbolic.hpp"
#include "TestInstructions.h"
#include "Semantics.ipp"
#include "Utils.h"
#include <coff/line_number.hpp>
#include <cstdint>
#include <iostream>
#include <llvm/ADT/STLExtras.h>
#include <llvm/Analysis/InstSimplifyFolder.h>
#include <llvm/Analysis/LazyCallGraph.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/IRBuilderFolder.h>
#include <llvm/Support/NativeFormatting.h>
#include <magic_enum/magic_enum.hpp>
// #define TEST
bool InitFunction_and_LiftInstructions(const uint64_t runtime_address,
std::vector<uint8_t>&& fileData,
const std::vector<uint64_t>& outlineAddresses) {
std::string stageError;
auto stageContext =
prepareLifterStageContext(runtime_address, fileData, stageError);
if (!stageContext.has_value()) {
std::cerr << stageError << std::endl;
return false;
}
for (const auto addr : outlineAddresses) {
stageContext->lifter->inlinePolicy.addAddress(addr);
}
runLifterPipeline(stageContext->lifter.get(), stageContext->runtimeContext,
fileData.data(), fileData);
return !stageContext->lifter->diagnostics.hasErrors();
}
// #define TEST
int main(int argc, char* argv[]) {
std::vector<std::string> rawArgs(argv, argv + argc);
#ifdef MERGEN_TEST
constexpr bool allowUnknownOptions = true;
#else
constexpr bool allowUnknownOptions = false;
#endif
auto parseResult = argparser::parseArguments(rawArgs, allowUnknownOptions);
if (!parseResult.ok()) {
for (const auto& error : parseResult.errors) {
std::cerr << error << std::endl;
}
argparser::printHelp();
return 1;
}
if (parseResult.showHelp) {
argparser::printHelp();
return 0;
}
if (parseResult.enableDebug) {
debugging::enableDebug("debug.txt");
}
if (parseResult.concretizeUnsafeReads) {
std::cerr << "Option '--concretize-unsafe-reads' is recognized but "
"not implemented yet."
<< std::endl;
return 1;
}
std::vector<std::string> args = std::move(parseResult.positionalArgs);
timer::startTimer();
#ifdef MERGEN_TEST
if (args.size() > 1 &&
(args[1] == "--build-full-seed" || args[1] == "build-full-seed")) {
const std::string outputPath =
args.size() > 2 ? args[2] : "scripts/rewrite/oracle_seed_full_handlers.json";
uint64_t maxAttempts = 2'500'000;
uint64_t randomSeed = 1337;
try {
if (args.size() > 3) {
maxAttempts = std::stoull(args[3], nullptr, 0);
}
if (args.size() > 4) {
randomSeed = std::stoull(args[4], nullptr, 0);
}
} catch (const std::exception& ex) {
std::cerr << "Invalid build-full-seed numeric arguments: " << ex.what()
<< std::endl;
return 1;
}
return buildFullHandlerSeed(outputPath, "lifter/semantics/x86_64_opcodes.x",
maxAttempts, randomSeed);
}
const std::string suiteFilter = args.size() > 1 ? args[1] : "";
return testInit(suiteFilter);
#endif
const auto& outlineAddrs = parseResult.outlineAddresses;
return runLifterApplication(args,
[&outlineAddrs](uint64_t runtime_address, std::vector<uint8_t>&& fileData) {
return InitFunction_and_LiftInstructions(runtime_address,
std::move(fileData), outlineAddrs);
});
}