Files
revng-revng/tools/trace/inspect/Main.cpp
2025-02-13 13:10:51 +02:00

111 lines
3.5 KiB
C++

//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include <iostream>
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ToolOutputFile.h"
#include "revng/PipelineC/Tracing/Trace.h"
#include "revng/Support/CommandLine.h"
#include "revng/Support/InitRevng.h"
using llvm::StringRef;
using revng::tracing::BufferLocation;
using revng::tracing::Trace;
namespace Options {
using namespace llvm::cl;
using std::string;
static OptionCategory ThisToolCategory("Tool options", "");
static opt<string> Input(Positional,
cat(ThisToolCategory),
desc("<input trace file>"),
value_desc("input trace file"));
static opt<bool> ListBuffers("list-buffers",
desc("List the buffers present on the trace"),
cat(ThisToolCategory),
init(false));
static opt<string> ExtractBuffer("extract-buffer",
cat(ThisToolCategory),
desc("Buffer to extract"),
value_desc("COMMANDNO:ARGNO"));
static alias ExtractBufferA("e",
cat(ThisToolCategory),
desc("Alias for --extract-buffer"),
aliasopt(ExtractBuffer));
static opt<string> Output("output",
cat(ThisToolCategory),
desc("Output file when extracting"),
value_desc("file"));
static alias OutputA("o",
cat(ThisToolCategory),
desc("Alias for --output"),
aliasopt(Output));
} // namespace Options
static llvm::ExitOnError AbortOnError;
int main(int argc, char *argv[]) {
revng::InitRevng X(argc, argv, "", { &Options::ThisToolCategory });
if (Options::ListBuffers xor Options::ExtractBuffer.empty()) {
dbg << "Please specify either --list-buffers or --extract-buffer\n";
return EXIT_FAILURE;
}
if (Options::ListBuffers) {
Trace TheTrace = AbortOnError(Trace::fromFile(Options::Input));
std::vector<BufferLocation> Result = TheTrace.listBuffers();
for (auto &Location : Result) {
std::cout << "Buffer on command " << Location.CommandName << " (Command #"
<< Location.CommandNumber << "), argument #"
<< Location.ArgumentNumber << "\n";
}
return EXIT_SUCCESS;
}
if (!Options::ExtractBuffer.empty()) {
if (Options::Output.empty()) {
dbg << "Please specify an output file\n";
return EXIT_FAILURE;
}
size_t CommandNo = 0;
size_t ArgNo = 0;
auto &&[CommandNoStr,
ArgNoStr] = StringRef(Options::ExtractBuffer).split(":");
if (CommandNoStr.getAsInteger(10, CommandNo)
|| ArgNoStr.getAsInteger(10, ArgNo)) {
dbg << "Error parsing extract value\n";
return EXIT_FAILURE;
}
Trace TheTrace = AbortOnError(Trace::fromFile(Options::Input));
using Buffer = std::vector<char>;
Buffer Result = AbortOnError(TheTrace.getBuffer(CommandNo, ArgNo));
std::error_code EC;
llvm::ToolOutputFile OutputFile(Options::Output,
EC,
llvm::sys::fs::OF_None);
OutputFile.os() << llvm::StringRef(Result.data(), Result.size());
OutputFile.keep();
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}