blob: 963effa47f0c5b27258bcda8212786f74dd6f854 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/debug/zxdb/console/format_handle.h"
#include <iterator>
#include "src/developer/debug/ipc/records.h"
#include "src/developer/debug/shared/handle_info.h"
#include "src/developer/debug/zxdb/common/string_util.h"
#include "src/developer/debug/zxdb/console/format_table.h"
#include "src/developer/debug/zxdb/console/string_util.h"
namespace zxdb {
namespace {
// Appends a two element string vector to the given output.
void AppendTwoEltRow(const std::string& a, const std::string& b,
std::vector<std::vector<std::string>>& rows) {
auto& row = rows.emplace_back();
row.push_back(a);
row.push_back(b);
}
template <class T>
std::string NumToString(T value, bool hex) {
if (hex)
return to_hex_string(value);
return std::to_string(value);
}
// Handle values can be 0 in the case of VMOs that are mapped but don't have open handles. This
// can be confusing so replace 0 with "<none>".
std::string HandleValueToString(uint64_t handle, bool hex) {
if (handle == 0)
return "<none>";
return NumToString(handle, hex);
}
// Appends the given array of flags, one-per line, using the heading as the key for the first.
void AppendFlags(const std::string& heading, const std::vector<std::string>& flags,
std::vector<std::vector<std::string>>& rows) {
for (size_t i = 0; i < flags.size(); i++) {
if (i == 0)
AppendTwoEltRow(heading, flags[i], rows);
else
AppendTwoEltRow(std::string(), flags[i], rows);
}
}
void AppendVmoInfo(const debug_ipc::InfoHandleVmo& vmo, std::vector<std::vector<std::string>>& rows,
bool hex) {
AppendTwoEltRow("Name", std::string(vmo.name, strnlen(vmo.name, std::size(vmo.name))), rows);
AppendTwoEltRow("VMO size in bytes", NumToString(vmo.size_bytes, hex), rows);
AppendTwoEltRow("Parent koid", NumToString(vmo.parent_koid, hex), rows);
AppendTwoEltRow("# children", NumToString(vmo.num_children, hex), rows);
AppendTwoEltRow("# mappings", NumToString(vmo.num_mappings, hex), rows);
AppendTwoEltRow("Share count", NumToString(vmo.share_count, hex), rows);
AppendFlags("Flags", debug::VmoFlagsToStrings(vmo.flags), rows);
AppendTwoEltRow("Committed bytes", NumToString(vmo.committed_bytes, hex), rows);
AppendTwoEltRow("Cache policy", debug::CachePolicyToString(vmo.cache_policy), rows);
AppendTwoEltRow("Metadata bytes", NumToString(vmo.metadata_bytes, hex), rows);
AppendTwoEltRow("Committed change events", NumToString(vmo.committed_change_events, hex), rows);
}
} // namespace
OutputBuffer FormatHandles(const std::vector<debug_ipc::InfoHandle>& handles, bool hex) {
if (handles.empty())
return OutputBuffer("No handles.");
std::vector<std::vector<std::string>> rows;
for (const auto& handle : handles) {
auto& row = rows.emplace_back();
row.push_back(HandleValueToString(handle.handle_value, hex));
row.push_back(debug::HandleTypeToString(handle.type));
row.push_back(NumToString(handle.koid, hex));
}
OutputBuffer out;
FormatTable({ColSpec(Align::kRight, 0, "Handle", 2), ColSpec(Align::kLeft, 0, "Type", 1),
ColSpec(Align::kRight, 0, "Koid", 1)},
rows, &out);
return out;
}
OutputBuffer FormatHandle(const debug_ipc::InfoHandle& handle, bool hex) {
std::vector<std::vector<std::string>> rows;
AppendTwoEltRow("Handle", HandleValueToString(handle.handle_value, hex), rows);
AppendTwoEltRow("Type", debug::HandleTypeToString(handle.type), rows);
AppendTwoEltRow("Koid", NumToString(handle.koid, hex), rows);
AppendFlags("Rights", debug::HandleRightsToStrings(handle.rights), rows);
if (handle.related_koid)
AppendTwoEltRow("Related koid", NumToString(handle.related_koid, hex), rows);
if (handle.peer_owner_koid)
AppendTwoEltRow("Peer-owner koid", NumToString(handle.peer_owner_koid, hex), rows);
// Type-specific information.
if (handle.type == 3u) { // ZX_OBJ_TYPE_VMO == 3
AppendVmoInfo(handle.ext.vmo, rows, hex);
}
OutputBuffer out;
FormatTable({ColSpec(Align::kRight, 0, std::string(), 2, Syntax::kHeading),
ColSpec(Align::kLeft, 0, std::string(), 1)},
rows, &out);
return out;
}
} // namespace zxdb