Skip to content

Commit

Permalink
Update disassembly output format for call arguments
Browse files Browse the repository at this point in the history
* Display call arguments in the expected order and with the expected count
* Make type display syntax consistent for pairs (which previously used
  " is ") vs singles (which previously used ":")
* Put types before values so it looks more C like
* Make type labels match between arguments, assertions, and
  preconditions (previously arguments showed "CTX" and "FD" for example
  whereas other places showed "ctx" and "map_fd")
* Display "uint64_t" for types that can be anything, instead of an absent
  type, for consistency with how helper function prototypes are shown at
  https://github.com/iovisor/bpf-docs/blob/master/bpf_helpers.rst etc.
  This makes it clear to the viewer that the type is indeed known to not
  be ctx, map_fd, etc.  (We could use "u64" instead but uint64_t is more
  of a standard.)

Sample outputs:

r0 = map_update_elem:2(map_fd r1, map_key r2, map_value r3, uint64_t r4)
r0 = tail_call:12(ctx r1, map_fd r2, uint64_t r3)
r0 = perf_event_output:25(ctx r1, map_fd r2, uint64_t r3, mem r4[r5?], uint64_t r5)
r0 = skb_load_bytes:26(ctx r1, uint64_t r2, out r3[r4], uint64_t r4)
r0 = sock_map_update:53(ctx r1, map_fd r2, map_key r3, uint64_t r4)

Fixes vbpf#221

Signed-off-by: Dave Thaler <[email protected]>
  • Loading branch information
dthaler authored and elazarg committed May 8, 2021
1 parent 62e54c2 commit a6cfb4b
Showing 1 changed file with 34 additions and 25 deletions.
59 changes: 34 additions & 25 deletions src/asm_ostream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,36 @@ using std::vector;

std::ostream& operator<<(std::ostream& os, ArgSingle::Kind kind) {
switch (kind) {
case ArgSingle::Kind::ANYTHING: return os << "";
case ArgSingle::Kind::PTR_TO_CTX: return os << "CTX";
case ArgSingle::Kind::MAP_FD: return os << "FD";
case ArgSingle::Kind::PTR_TO_MAP_KEY: return os << "K";
case ArgSingle::Kind::PTR_TO_MAP_VALUE: return os << "V";
case ArgSingle::Kind::ANYTHING: return os << "uint64_t";
case ArgSingle::Kind::PTR_TO_CTX: return os << "ctx";
case ArgSingle::Kind::MAP_FD: return os << "map_fd";
case ArgSingle::Kind::PTR_TO_MAP_KEY: return os << "map_key";
case ArgSingle::Kind::PTR_TO_MAP_VALUE: return os << "map_value";
}
assert(false);
return os;
}

std::ostream& operator<<(std::ostream& os, ArgPair::Kind kind) {
switch (kind) {
case ArgPair::Kind::PTR_TO_MEM: return os << "MEM";
case ArgPair::Kind::PTR_TO_MEM_OR_NULL: return os << "MEM?";
case ArgPair::Kind::PTR_TO_UNINIT_MEM: return os << "OUT";
case ArgPair::Kind::PTR_TO_MEM: return os << "mem";
case ArgPair::Kind::PTR_TO_MEM_OR_NULL: return os << "mem?";
case ArgPair::Kind::PTR_TO_UNINIT_MEM: return os << "out";
}
assert(false);
return os;
}

std::ostream& operator<<(std::ostream& os, ArgSingle arg) {
os << arg.reg;
if (arg.kind != ArgSingle::Kind::ANYTHING)
os << ":" << arg.kind;
os << arg.kind << " " << arg.reg;
return os;
}

std::ostream& operator<<(std::ostream& os, ArgPair arg) {
os << arg.mem << " is " << arg.kind << "[" << arg.size;
os << arg.kind << " " << arg.mem << "[" << arg.size;
if (arg.can_be_zero)
os << "?";
os << "]";
os << "], uint64_t " << arg.size;
return os;
}

Expand Down Expand Up @@ -185,18 +183,29 @@ struct InstructionPrinterVisitor {

void operator()(Call const& call) {
os_ << "r0 = " << call.name << ":" << call.func << "(";
bool first = true;
for (auto single : call.singles) {
if (!first)
os_ << ", ";
first = false;
os_ << single;
}
for (auto pair : call.pairs) {
if (!first)
os_ << ", ";
first = false;
os_ << pair;
for (uint8_t r = 1; r <= 5; r++) {
// Look for a singleton.
std::vector<ArgSingle>::const_iterator single =
std::find_if(call.singles.begin(), call.singles.end(), [r](ArgSingle arg) { return arg.reg.v == r; });
if (single != call.singles.end()) {
if (r > 1)
os_ << ", ";
os_ << *single;
continue;
}

// Look for the start of a pair.
std::vector<ArgPair>::const_iterator pair =
std::find_if(call.pairs.begin(), call.pairs.end(), [r](ArgPair arg) { return arg.mem.v == r; });
if (pair != call.pairs.end()) {
if (r > 1)
os_ << ", ";
os_ << *pair;
continue;
}

// Not found.
break;
}
os_ << ")";
}
Expand Down

0 comments on commit a6cfb4b

Please sign in to comment.