diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-09 13:28:42 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-09 13:28:42 +0000 |
| commit | b1c73532ee8997fe5dfbeb7d223027bdf99758a0 (patch) | |
| tree | 7d6e51c294ab6719475d660217aa0c0ad0526292 /lldb/source/Target/RegisterFlags.cpp | |
| parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) | |
Diffstat (limited to 'lldb/source/Target/RegisterFlags.cpp')
| -rw-r--r-- | lldb/source/Target/RegisterFlags.cpp | 60 |
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 << "/>"; +} |
