mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
b1feb5b989
This commit drops libptc in favor of its new form libtcg. It brings several improvements, among which: * The QEMU version we work on has been upgraded. * CPUStateAccessAnalysis has been reimplemented in a way that makes it easier to debug and solves some limitations (e.g., tracking leaking pointers). * Identification of pieces of the CPU state that are read by each helper and fixing access to the CPU state is now performed at build-time. * We no longer mmap the code we need to translate, dropping all the issues related to code that needed to be mapped where something is already present. * We now have two distinct flavors of helper modules: the full one and the "slim" one. The latter contains the definition only of functions we intend to inline. It is used in most of the pipeline, a good thing since we spend less time optimizing code we don't really care about. The full module is only used on the re-compilation branch of the pipeline. * We no longer split the `cpu_loop` function. * We change MetaAddress to rely on architectures from `model::` as opposed to the LLVM ones. * We no longer attach debug info to LLVM IR containing the original assembly. * We now verify that the lifted code only contains code we expect.
103 lines
3.3 KiB
C++
103 lines
3.3 KiB
C++
/// \file Lift.cpp
|
|
|
|
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
#include "revng/Lift/LibTcg.h"
|
|
#include "revng/Lift/Lift.h"
|
|
#include "revng/Support/CommandLine.h"
|
|
#include "revng/Support/IRHelpers.h"
|
|
#include "revng/Support/ResourceFinder.h"
|
|
|
|
#include "CodeGenerator.h"
|
|
|
|
using namespace llvm::cl;
|
|
|
|
namespace {
|
|
const char *EntryDescStr = "virtual address of the entry point where to start";
|
|
opt<unsigned long long> EntryPointAddress("entry",
|
|
desc(EntryDescStr),
|
|
value_desc("address"),
|
|
cat(MainCategory));
|
|
alias A1("e",
|
|
desc("Alias for -entry"),
|
|
aliasopt(EntryPointAddress),
|
|
cat(MainCategory));
|
|
|
|
} // namespace
|
|
|
|
char LiftPass::ID;
|
|
|
|
using Register = llvm::RegisterPass<LiftPass>;
|
|
static Register X("lift", "Lift Pass", true, true);
|
|
|
|
struct ExternalFilePaths {
|
|
std::string LibHelpers;
|
|
std::string EarlyLinked;
|
|
};
|
|
|
|
static ExternalFilePaths
|
|
findExternalFilePaths(const model::Architecture::Values Architecture) {
|
|
// What symbols from the revng namespace are actually used here?
|
|
using namespace revng;
|
|
|
|
const std::string ArchName = model::Architecture::getQEMUName(Architecture)
|
|
.str();
|
|
|
|
ExternalFilePaths Paths = {};
|
|
|
|
// Note: here we use the slim version of the helpers, i.e., where we only have
|
|
// definitions for revng_inline functions.
|
|
const std::string LibHelpersName = "/share/revng/libtcg-helpers-annotated"
|
|
"-slim-"
|
|
+ ArchName + ".bc";
|
|
auto OptionalHelpers = ResourceFinder.findFile(LibHelpersName);
|
|
revng_assert(OptionalHelpers.has_value(), "Cannot find tinycode helpers");
|
|
Paths.LibHelpers = OptionalHelpers.value();
|
|
|
|
const std::string EarlyLinkedName = "/share/revng/early-linked-" + ArchName
|
|
+ ".ll";
|
|
auto OptionalEarlyLinked = ResourceFinder.findFile(EarlyLinkedName);
|
|
revng_assert(OptionalEarlyLinked.has_value(), "Cannot find early-linked.ll");
|
|
|
|
Paths.EarlyLinked = OptionalEarlyLinked.value();
|
|
|
|
return Paths;
|
|
}
|
|
|
|
bool LiftPass::runOnModule(llvm::Module &M) {
|
|
llvm::Task T(4, "Lift pass");
|
|
const auto &ModelWrapper = getAnalysis<LoadModelWrapperPass>().get();
|
|
const TupleTree<model::Binary> &Model = ModelWrapper.getReadOnlyModel();
|
|
|
|
T.advance("findFiles", false);
|
|
const auto Paths = findExternalFilePaths(Model->Architecture());
|
|
|
|
// Look for the library in the system's paths
|
|
T.advance("Load libtcg", false);
|
|
auto TheLibTcg = LibTcg::get(Model->Architecture());
|
|
|
|
// Get access to raw binary data
|
|
RawBinaryView &RawBinary = getAnalysis<LoadBinaryWrapperPass>().get();
|
|
|
|
T.advance("Construct CodeGenerator", false);
|
|
CodeGenerator Generator(RawBinary,
|
|
&M,
|
|
Model,
|
|
Paths.LibHelpers,
|
|
Paths.EarlyLinked,
|
|
model::Architecture::x86_64);
|
|
|
|
std::optional<uint64_t> EntryPointAddressOptional;
|
|
if (EntryPointAddress.getNumOccurrences() != 0)
|
|
EntryPointAddressOptional = EntryPointAddress;
|
|
T.advance("Translate", true);
|
|
|
|
Generator.translate(TheLibTcg, EntryPointAddressOptional);
|
|
|
|
sortModule(M);
|
|
|
|
return false;
|
|
}
|