1//===-- Event.cpp ---------------------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "lldb/Utility/Event.h" 10 11#include "lldb/Utility/Broadcaster.h" 12#include "lldb/Utility/DataExtractor.h" 13#include "lldb/Utility/Endian.h" 14#include "lldb/Utility/Listener.h" 15#include "lldb/Utility/Stream.h" 16#include "lldb/Utility/StreamString.h" 17#include "lldb/lldb-enumerations.h" 18 19#include "llvm/ADT/StringExtras.h" 20 21#include <algorithm> 22 23#include <cctype> 24 25using namespace lldb; 26using namespace lldb_private; 27 28#pragma mark - 29#pragma mark Event 30 31// Event functions 32 33Event::Event(Broadcaster *broadcaster, uint32_t event_type, EventData *data) 34 : m_broadcaster_wp(broadcaster->GetBroadcasterImpl()), m_type(event_type), 35 m_data_sp(data) {} 36 37Event::Event(Broadcaster *broadcaster, uint32_t event_type, 38 const EventDataSP &event_data_sp) 39 : m_broadcaster_wp(broadcaster->GetBroadcasterImpl()), m_type(event_type), 40 m_data_sp(event_data_sp) {} 41 42Event::Event(uint32_t event_type, EventData *data) 43 : m_broadcaster_wp(), m_type(event_type), m_data_sp(data) {} 44 45Event::Event(uint32_t event_type, const EventDataSP &event_data_sp) 46 : m_broadcaster_wp(), m_type(event_type), m_data_sp(event_data_sp) {} 47 48Event::~Event() = default; 49 50void Event::Dump(Stream *s) const { 51 Broadcaster *broadcaster; 52 Broadcaster::BroadcasterImplSP broadcaster_impl_sp(m_broadcaster_wp.lock()); 53 if (broadcaster_impl_sp) 54 broadcaster = broadcaster_impl_sp->GetBroadcaster(); 55 else 56 broadcaster = nullptr; 57 58 if (broadcaster) { 59 StreamString event_name; 60 if (broadcaster->GetEventNames(event_name, m_type, false)) 61 s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x (%s), data = ", 62 static_cast<const void *>(this), 63 static_cast<void *>(broadcaster), 64 broadcaster->GetBroadcasterName().c_str(), m_type, 65 event_name.GetData()); 66 else 67 s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x, data = ", 68 static_cast<const void *>(this), 69 static_cast<void *>(broadcaster), 70 broadcaster->GetBroadcasterName().c_str(), m_type); 71 } else 72 s->Printf("%p Event: broadcaster = NULL, type = 0x%8.8x, data = ", 73 static_cast<const void *>(this), m_type); 74 75 if (m_data_sp) { 76 s->PutChar('{'); 77 m_data_sp->Dump(s); 78 s->PutChar('}'); 79 } else 80 s->Printf("<NULL>"); 81} 82 83void Event::DoOnRemoval() { 84 std::lock_guard<std::mutex> guard(m_listeners_mutex); 85 86 if (m_data_sp) 87 m_data_sp->DoOnRemoval(this); 88 // Now that the event has been handled by the primary event Listener, forward 89 // it to the other Listeners. 90 EventSP me_sp = shared_from_this(); 91 for (auto listener_sp : m_pending_listeners) 92 listener_sp->AddEvent(me_sp); 93 m_pending_listeners.clear(); 94} 95 96#pragma mark - 97#pragma mark EventData 98 99// EventData functions 100 101EventData::EventData() = default; 102 103EventData::~EventData() = default; 104 105void EventData::Dump(Stream *s) const { s->PutCString("Generic Event Data"); } 106 107#pragma mark - 108#pragma mark EventDataBytes 109 110// EventDataBytes functions 111 112EventDataBytes::EventDataBytes() : m_bytes() {} 113 114EventDataBytes::EventDataBytes(const char *cstr) : m_bytes() { 115 SetBytesFromCString(cstr); 116} 117 118EventDataBytes::EventDataBytes(llvm::StringRef str) : m_bytes() { 119 SetBytes(str.data(), str.size()); 120} 121 122EventDataBytes::EventDataBytes(const void *src, size_t src_len) : m_bytes() { 123 SetBytes(src, src_len); 124} 125 126EventDataBytes::~EventDataBytes() = default; 127 128llvm::StringRef EventDataBytes::GetFlavorString() { return "EventDataBytes"; } 129 130llvm::StringRef EventDataBytes::GetFlavor() const { 131 return EventDataBytes::GetFlavorString(); 132} 133 134void EventDataBytes::Dump(Stream *s) const { 135 if (llvm::all_of(m_bytes, llvm::isPrint)) 136 s->Format("\"{0}\"", m_bytes); 137 else 138 s->Format("{0:$[ ]@[x-2]}", llvm::make_range( 139 reinterpret_cast<const uint8_t *>(m_bytes.data()), 140 reinterpret_cast<const uint8_t *>(m_bytes.data() + 141 m_bytes.size()))); 142} 143 144const void *EventDataBytes::GetBytes() const { 145 return (m_bytes.empty() ? nullptr : m_bytes.data()); 146} 147 148size_t EventDataBytes::GetByteSize() const { return m_bytes.size(); } 149 150void EventDataBytes::SetBytes(const void *src, size_t src_len) { 151 if (src != nullptr && src_len > 0) 152 m_bytes.assign(static_cast<const char *>(src), src_len); 153 else 154 m_bytes.clear(); 155} 156 157void EventDataBytes::SetBytesFromCString(const char *cstr) { 158 if (cstr != nullptr && cstr[0]) 159 m_bytes.assign(cstr); 160 else 161 m_bytes.clear(); 162} 163 164const void *EventDataBytes::GetBytesFromEvent(const Event *event_ptr) { 165 const EventDataBytes *e = GetEventDataFromEvent(event_ptr); 166 if (e != nullptr) 167 return e->GetBytes(); 168 return nullptr; 169} 170 171size_t EventDataBytes::GetByteSizeFromEvent(const Event *event_ptr) { 172 const EventDataBytes *e = GetEventDataFromEvent(event_ptr); 173 if (e != nullptr) 174 return e->GetByteSize(); 175 return 0; 176} 177 178const EventDataBytes * 179EventDataBytes::GetEventDataFromEvent(const Event *event_ptr) { 180 if (event_ptr != nullptr) { 181 const EventData *event_data = event_ptr->GetData(); 182 if (event_data && 183 event_data->GetFlavor() == EventDataBytes::GetFlavorString()) 184 return static_cast<const EventDataBytes *>(event_data); 185 } 186 return nullptr; 187} 188 189void EventDataBytes::SwapBytes(std::string &new_bytes) { 190 m_bytes.swap(new_bytes); 191} 192 193llvm::StringRef EventDataReceipt::GetFlavorString() { 194 return "Process::ProcessEventData"; 195} 196 197#pragma mark - 198#pragma mark EventStructuredData 199 200// EventDataStructuredData definitions 201 202EventDataStructuredData::EventDataStructuredData() 203 : EventData(), m_process_sp(), m_object_sp(), m_plugin_sp() {} 204 205EventDataStructuredData::EventDataStructuredData( 206 const ProcessSP &process_sp, const StructuredData::ObjectSP &object_sp, 207 const lldb::StructuredDataPluginSP &plugin_sp) 208 : EventData(), m_process_sp(process_sp), m_object_sp(object_sp), 209 m_plugin_sp(plugin_sp) {} 210 211EventDataStructuredData::~EventDataStructuredData() = default; 212 213// EventDataStructuredData member functions 214 215llvm::StringRef EventDataStructuredData::GetFlavor() const { 216 return EventDataStructuredData::GetFlavorString(); 217} 218 219void EventDataStructuredData::Dump(Stream *s) const { 220 if (!s) 221 return; 222 223 if (m_object_sp) 224 m_object_sp->Dump(*s); 225} 226 227const ProcessSP &EventDataStructuredData::GetProcess() const { 228 return m_process_sp; 229} 230 231const StructuredData::ObjectSP &EventDataStructuredData::GetObject() const { 232 return m_object_sp; 233} 234 235const lldb::StructuredDataPluginSP & 236EventDataStructuredData::GetStructuredDataPlugin() const { 237 return m_plugin_sp; 238} 239 240void EventDataStructuredData::SetProcess(const ProcessSP &process_sp) { 241 m_process_sp = process_sp; 242} 243 244void EventDataStructuredData::SetObject( 245 const StructuredData::ObjectSP &object_sp) { 246 m_object_sp = object_sp; 247} 248 249void EventDataStructuredData::SetStructuredDataPlugin( 250 const lldb::StructuredDataPluginSP &plugin_sp) { 251 m_plugin_sp = plugin_sp; 252} 253 254// EventDataStructuredData static functions 255 256const EventDataStructuredData * 257EventDataStructuredData::GetEventDataFromEvent(const Event *event_ptr) { 258 if (event_ptr == nullptr) 259 return nullptr; 260 261 const EventData *event_data = event_ptr->GetData(); 262 if (!event_data || 263 event_data->GetFlavor() != EventDataStructuredData::GetFlavorString()) 264 return nullptr; 265 266 return static_cast<const EventDataStructuredData *>(event_data); 267} 268 269ProcessSP EventDataStructuredData::GetProcessFromEvent(const Event *event_ptr) { 270 auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); 271 if (event_data) 272 return event_data->GetProcess(); 273 else 274 return ProcessSP(); 275} 276 277StructuredData::ObjectSP 278EventDataStructuredData::GetObjectFromEvent(const Event *event_ptr) { 279 auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); 280 if (event_data) 281 return event_data->GetObject(); 282 else 283 return StructuredData::ObjectSP(); 284} 285 286lldb::StructuredDataPluginSP 287EventDataStructuredData::GetPluginFromEvent(const Event *event_ptr) { 288 auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); 289 if (event_data) 290 return event_data->GetStructuredDataPlugin(); 291 else 292 return StructuredDataPluginSP(); 293} 294 295llvm::StringRef EventDataStructuredData::GetFlavorString() { 296 return "EventDataStructuredData"; 297} 298