Skip to content

Commit

Permalink
CR and moving namespaces around
Browse files Browse the repository at this point in the history
Signed-off-by: Elazar Gershuni <[email protected]>
  • Loading branch information
elazarg committed Nov 10, 2024
1 parent 5d695d8 commit 56ba4ea
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 211 deletions.
2 changes: 1 addition & 1 deletion src/asm_marshal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ struct MarshalVisitor {
};

vector<ebpf_inst> marshal(const Instruction& ins, const pc_t pc) {
return std::visit(MarshalVisitor{label_to_offset16(pc), label_to_offset32(pc)}, ins);
return std::visit(MarshalVisitor{crab::label_to_offset16(pc), crab::label_to_offset32(pc)}, ins);
}

static int size(const Instruction& inst) {
Expand Down
214 changes: 111 additions & 103 deletions src/asm_ostream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "crab/interval.hpp"
#include "crab/type_encoding.hpp"
#include "crab/variable.hpp"
#include "crab_utils/num_big.hpp"
#include "helpers.hpp"
#include "platform.hpp"
#include "spec_type_descriptors.hpp"
Expand All @@ -20,6 +21,113 @@ using std::optional;
using std::string;
using std::vector;

namespace crab {

std::string number_t::to_string() const { return _n.str(); }

std::string interval_t::to_string() const {
std::ostringstream s;
s << *this;
return s.str();
}

std::ostream& operator<<(std::ostream& os, const label_t& label) {
if (label == label_t::entry) {
return os << "entry";
}
if (label == label_t::exit) {
return os << "exit";
}
if (!label.stack_frame_prefix.empty()) {
os << label.stack_frame_prefix << STACK_FRAME_DELIMITER;
}
os << label.from;
if (label.to != -1) {
os << ":" << label.to;
}
if (!label.special_label.empty()) {
os << " (" << label.special_label << ")";
}
return os;
}

string to_string(label_t const& label) {
std::stringstream str;
str << label;
return str.str();
}

void print_dot(const cfg_t& cfg, std::ostream& out) {
out << "digraph program {\n";
out << " node [shape = rectangle];\n";
for (const auto& label : cfg.labels()) {
out << " \"" << label << "\"[xlabel=\"" << label << "\",label=\"";

const auto& value = cfg.get_node(label);
const auto& ins = value.instruction();
for (const auto& pre : ins.preconditions) {
out << "assert " << pre << "\\l";
}
out << ins.cmd << "\\l";

out << "\"];\n";
for (const label_t& next : value.next_labels_set()) {
out << " \"" << label << "\" -> \"" << next << "\";\n";
}
out << "\n";
}
out << "}\n";
}

void print_dot(const cfg_t& cfg, const std::string& outfile) {
std::ofstream out{outfile};
if (out.fail()) {
throw std::runtime_error(std::string("Could not open file ") + outfile);
}
print_dot(cfg, out);
}

std::ostream& operator<<(std::ostream& o, const value_t& value) {
o << value.label() << ":\n";
const auto ins = value.instruction();
for (const auto& pre : ins.preconditions) {
o << " "
<< "assert " << pre << ";\n";
}
o << " " << ins.cmd << ";\n";
auto [it, et] = value.next_labels();
if (it != et) {
o << " "
<< "goto ";
while (it != et) {
o << *it;
++it;
if (it == et) {
o << ";";
} else {
o << ",";
}
}
}
o << "\n";
return o;
}

std::ostream& operator<<(std::ostream& o, const cfg_t& cfg) {
for (const label_t& label : cfg.sorted_labels()) {
o << cfg.get_node(label);
o << "edges to:";
for (const label_t& next_label : cfg.next_nodes(label)) {
o << " " << next_label;
}
o << "\n";
}
return o;
}

} // namespace crab

namespace asm_syntax {
std::ostream& operator<<(std::ostream& os, const ArgSingle::Kind kind) {
switch (kind) {
case ArgSingle::Kind::ANYTHING: return os << "uint64_t";
Expand Down Expand Up @@ -354,32 +462,6 @@ struct CommandPrinterVisitor {
};
// ReSharper restore CppMemberFunctionMayBeConst

std::ostream& operator<<(std::ostream& os, const label_t& label) {
if (label == label_t::entry) {
return os << "entry";
}
if (label == label_t::exit) {
return os << "exit";
}
if (!label.stack_frame_prefix.empty()) {
os << label.stack_frame_prefix << STACK_FRAME_DELIMITER;
}
os << label.from;
if (label.to != -1) {
os << ":" << label.to;
}
if (!label.special_label.empty()) {
os << " (" << label.special_label << ")";
}
return os;
}

string to_string(label_t const& label) {
std::stringstream str;
str << label;
return str.str();
}

std::ostream& operator<<(std::ostream& os, Instruction const& ins) {
std::visit(CommandPrinterVisitor{os}, ins);
return os;
Expand Down Expand Up @@ -452,7 +534,7 @@ void print(const InstructionSeq& insts, std::ostream& out, const std::optional<c
}
if (const auto jmp = std::get_if<Jmp>(&ins)) {
if (!pc_of_label.contains(jmp->target)) {
throw std::runtime_error(string("Cannot find label ") + to_string(jmp->target));
throw std::runtime_error(string("Cannot find label ") + crab::to_string(jmp->target));
}
const pc_t target_pc = pc_of_label.at(jmp->target);
visitor(*jmp, target_pc - static_cast<int>(pc) - 1);
Expand All @@ -465,6 +547,8 @@ void print(const InstructionSeq& insts, std::ostream& out, const std::optional<c
}
}

} // namespace asm_syntax

std::ostream& operator<<(std::ostream& o, const EbpfMapDescriptor& desc) {
return o << "("
<< "original_fd = " << desc.original_fd << ", "
Expand All @@ -483,84 +567,8 @@ void print_map_descriptors(const std::vector<EbpfMapDescriptor>& descriptors, st
}
}

void print_dot(const cfg_t& cfg, std::ostream& out) {
out << "digraph program {\n";
out << " node [shape = rectangle];\n";
for (const auto& label : cfg.labels()) {
out << " \"" << label << "\"[xlabel=\"" << label << "\",label=\"";

const auto& value = cfg.get_node(label);
const auto& ins = value.instruction();
for (const auto& pre : ins.preconditions) {
out << "assert " << pre << "\\l";
}
out << ins.cmd << "\\l";

out << "\"];\n";
for (const label_t& next : value.next_labels_set()) {
out << " \"" << label << "\" -> \"" << next << "\";\n";
}
out << "\n";
}
out << "}\n";
}

void print_dot(const cfg_t& cfg, const std::string& outfile) {
std::ofstream out{outfile};
if (out.fail()) {
throw std::runtime_error(std::string("Could not open file ") + outfile);
}
print_dot(cfg, out);
}

std::ostream& operator<<(std::ostream& o, const crab::value_t& value) {
o << value.label() << ":\n";
const auto ins = value.instruction();
for (const auto& pre : ins.preconditions) {
o << " "
<< "assert " << pre << ";\n";
}
o << " " << ins.cmd << ";\n";
auto [it, et] = value.next_labels();
if (it != et) {
o << " "
<< "goto ";
while (it != et) {
o << *it;
++it;
if (it == et) {
o << ";";
} else {
o << ",";
}
}
}
o << "\n";
return o;
}

std::ostream& operator<<(std::ostream& o, const cfg_t& cfg) {
for (const label_t& label : cfg.sorted_labels()) {
o << cfg.get_node(label);
o << "edges to:";
for (const label_t& next_label : cfg.next_nodes(label)) {
o << " " << next_label;
}
o << "\n";
}
return o;
}

std::ostream& operator<<(std::ostream& os, const btf_line_info_t& line_info) {
os << "; " << line_info.file_name << ":" << line_info.line_number << "\n";
os << "; " << line_info.source_line << "\n";
return os;
}

std::string crab::number_t::to_string() const { return _n.str(); }

std::string crab::interval_t::to_string() const {
std::ostringstream s;
s << *this;
return s.str();
}
47 changes: 8 additions & 39 deletions src/asm_syntax.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
// SPDX-License-Identifier: MIT
#pragma once

#include <functional>
#include <limits>
#include <optional>
#include <ostream>
#include <ranges>
#include <string>
#include <tuple>
#include <utility>
Expand Down Expand Up @@ -362,42 +359,6 @@ struct GuardedInstruction {
bool operator==(const GuardedInstruction&) const = default;
};

// cpu=v4 supports 32-bit PC offsets so we need a large enough type.
using pc_t = uint32_t;

} // namespace asm_syntax

using namespace asm_syntax;

// We use a 16-bit offset whenever it fits in 16 bits.
inline std::function<int16_t(label_t)> label_to_offset16(const pc_t pc) {
return [=](const label_t& label) {
const int64_t offset = label.from - gsl::narrow<int64_t>(pc) - 1;
const bool is16 =
std::numeric_limits<int16_t>::min() <= offset && offset <= std::numeric_limits<int16_t>::max();
return gsl::narrow<int16_t>(is16 ? offset : 0);
};
}

// We use the JA32 opcode with the offset in 'imm' when the offset
// of an unconditional jump doesn't fit in an int16_t.
inline std::function<int32_t(label_t)> label_to_offset32(const pc_t pc) {
return [=](const label_t& label) {
const int64_t offset = label.from - gsl::narrow<int64_t>(pc) - 1;
const bool is16 =
std::numeric_limits<int16_t>::min() <= offset && offset <= std::numeric_limits<int16_t>::max();
return is16 ? 0 : gsl::narrow<int32_t>(offset);
};
}

std::ostream& operator<<(std::ostream& os, const btf_line_info_t& line_info);

void print(const InstructionSeq& insts, std::ostream& out, const std::optional<const label_t>& label_to_print,
bool print_line_info = false);

std::ostream& operator<<(std::ostream& os, const label_t& label);
std::string to_string(label_t const& label);

std::ostream& operator<<(std::ostream& os, Instruction const& ins);
std::string to_string(Instruction const& ins);

Expand All @@ -416,6 +377,14 @@ inline std::ostream& operator<<(std::ostream& os, Value const& a) {
std::ostream& operator<<(std::ostream& os, const Assertion& a);
std::string to_string(const Assertion& constraint);

void print(const InstructionSeq& insts, std::ostream& out, const std::optional<const label_t>& label_to_print,
bool print_line_info = false);

} // namespace asm_syntax

using namespace asm_syntax;
using crab::pc_t;

template <class... Ts>
struct overloaded : Ts... {
using Ts::operator()...;
Expand Down
Loading

0 comments on commit 56ba4ea

Please sign in to comment.