aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Target/RegisterFlags.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-09 13:28:42 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-09 13:28:42 +0000
commitb1c73532ee8997fe5dfbeb7d223027bdf99758a0 (patch)
tree7d6e51c294ab6719475d660217aa0c0ad0526292 /lldb/source/Target/RegisterFlags.cpp
parent7fa27ce4a07f19b07799a767fc29416f3b625afb (diff)
Diffstat (limited to 'lldb/source/Target/RegisterFlags.cpp')
-rw-r--r--lldb/source/Target/RegisterFlags.cpp60
1 files changed, 56 insertions, 4 deletions
diff --git a/lldb/source/Target/RegisterFlags.cpp b/lldb/source/Target/RegisterFlags.cpp
index 06fb45d777ec..b1669b85fd2f 100644
--- a/lldb/source/Target/RegisterFlags.cpp
+++ b/lldb/source/Target/RegisterFlags.cpp
@@ -7,13 +7,21 @@
//===----------------------------------------------------------------------===//
#include "lldb/Target/RegisterFlags.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
+#include "llvm/ADT/StringExtras.h"
+
#include <numeric>
#include <optional>
using namespace lldb_private;
+RegisterFlags::Field::Field(std::string name, unsigned start, unsigned end)
+ : m_name(std::move(name)), m_start(start), m_end(end) {
+ assert(m_start <= m_end && "Start bit must be <= end bit.");
+}
+
void RegisterFlags::Field::log(Log *log) const {
LLDB_LOG(log, " Name: \"{0}\" Start: {1} End: {2}", m_name.c_str(), m_start,
m_end);
@@ -45,9 +53,7 @@ unsigned RegisterFlags::Field::PaddingDistance(const Field &other) const {
return lhs_start - rhs_end - 1;
}
-RegisterFlags::RegisterFlags(std::string id, unsigned size,
- const std::vector<Field> &fields)
- : m_id(std::move(id)), m_size(size) {
+void RegisterFlags::SetFields(const std::vector<Field> &fields) {
// We expect that the XML processor will discard anything describing flags but
// with no fields.
assert(fields.size() && "Some fields must be provided.");
@@ -55,6 +61,8 @@ RegisterFlags::RegisterFlags(std::string id, unsigned size,
// We expect that these are unsorted but do not overlap.
// They could fill the register but may have gaps.
std::vector<Field> provided_fields = fields;
+
+ m_fields.clear();
m_fields.reserve(provided_fields.size());
// ProcessGDBRemote should have sorted these in descending order already.
@@ -63,7 +71,7 @@ RegisterFlags::RegisterFlags(std::string id, unsigned size,
// Build a new list of fields that includes anonymous (empty name) fields
// wherever there is a gap. This will simplify processing later.
std::optional<Field> previous_field;
- unsigned register_msb = (size * 8) - 1;
+ unsigned register_msb = (m_size * 8) - 1;
for (auto field : provided_fields) {
if (previous_field) {
unsigned padding = previous_field->PaddingDistance(field);
@@ -88,6 +96,12 @@ RegisterFlags::RegisterFlags(std::string id, unsigned size,
m_fields.push_back(Field("", 0, previous_field->GetStart() - 1));
}
+RegisterFlags::RegisterFlags(std::string id, unsigned size,
+ const std::vector<Field> &fields)
+ : m_id(std::move(id)), m_size(size) {
+ SetFields(fields);
+}
+
void RegisterFlags::log(Log *log) const {
LLDB_LOG(log, "ID: \"{0}\" Size: {1}", m_id.c_str(), m_size);
for (const Field &field : m_fields)
@@ -175,3 +189,41 @@ std::string RegisterFlags::AsTable(uint32_t max_width) const {
return table;
}
+
+void RegisterFlags::ToXML(StreamString &strm) const {
+ // Example XML:
+ // <flags id="cpsr_flags" size="4">
+ // <field name="incorrect" start="0" end="0"/>
+ // </flags>
+ strm.Indent();
+ strm << "<flags id=\"" << GetID() << "\" ";
+ strm.Printf("size=\"%d\"", GetSize());
+ strm << ">";
+ for (const Field &field : m_fields) {
+ // Skip padding fields.
+ if (field.GetName().empty())
+ continue;
+
+ strm << "\n";
+ strm.IndentMore();
+ field.ToXML(strm);
+ strm.IndentLess();
+ }
+ strm.PutChar('\n');
+ strm.Indent("</flags>\n");
+}
+
+void RegisterFlags::Field::ToXML(StreamString &strm) const {
+ // Example XML:
+ // <field name="correct" start="0" end="0"/>
+ strm.Indent();
+ strm << "<field name=\"";
+
+ std::string escaped_name;
+ llvm::raw_string_ostream escape_strm(escaped_name);
+ llvm::printHTMLEscaped(GetName(), escape_strm);
+ strm << escaped_name << "\" ";
+
+ strm.Printf("start=\"%d\" end=\"%d\"", GetStart(), GetEnd());
+ strm << "/>";
+}