1061da546Spatrick //===-- SystemRuntimeMacOSX.h -----------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_SYSTEMRUNTIMEMACOSX_H 10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_SYSTEMRUNTIMEMACOSX_H 11061da546Spatrick 12061da546Spatrick #include <mutex> 13061da546Spatrick #include <string> 14061da546Spatrick #include <vector> 15061da546Spatrick 16061da546Spatrick // Other libraries and framework include 17061da546Spatrick #include "lldb/Core/ModuleList.h" 18061da546Spatrick #include "lldb/Target/Process.h" 19061da546Spatrick #include "lldb/Target/QueueItem.h" 20061da546Spatrick #include "lldb/Target/SystemRuntime.h" 21061da546Spatrick #include "lldb/Utility/ConstString.h" 22061da546Spatrick #include "lldb/Utility/FileSpec.h" 23061da546Spatrick #include "lldb/Utility/StructuredData.h" 24061da546Spatrick #include "lldb/Utility/UUID.h" 25061da546Spatrick 26061da546Spatrick #include "AppleGetItemInfoHandler.h" 27061da546Spatrick #include "AppleGetPendingItemsHandler.h" 28061da546Spatrick #include "AppleGetQueuesHandler.h" 29061da546Spatrick #include "AppleGetThreadItemInfoHandler.h" 30061da546Spatrick 31061da546Spatrick class SystemRuntimeMacOSX : public lldb_private::SystemRuntime { 32061da546Spatrick public: 33061da546Spatrick SystemRuntimeMacOSX(lldb_private::Process *process); 34061da546Spatrick 35061da546Spatrick ~SystemRuntimeMacOSX() override; 36061da546Spatrick 37061da546Spatrick // Static Functions 38061da546Spatrick static void Initialize(); 39061da546Spatrick 40061da546Spatrick static void Terminate(); 41061da546Spatrick GetPluginNameStatic()42*f6aab3d8Srobert static llvm::StringRef GetPluginNameStatic() { 43*f6aab3d8Srobert return "systemruntime-macosx"; 44*f6aab3d8Srobert } 45061da546Spatrick 46061da546Spatrick static lldb_private::SystemRuntime * 47061da546Spatrick CreateInstance(lldb_private::Process *process); 48061da546Spatrick 49061da546Spatrick // instance methods 50061da546Spatrick 51061da546Spatrick void Clear(bool clear_process); 52061da546Spatrick 53061da546Spatrick void Detach() override; 54061da546Spatrick 55061da546Spatrick const std::vector<lldb_private::ConstString> & 56061da546Spatrick GetExtendedBacktraceTypes() override; 57061da546Spatrick 58061da546Spatrick lldb::ThreadSP 59061da546Spatrick GetExtendedBacktraceThread(lldb::ThreadSP thread, 60061da546Spatrick lldb_private::ConstString type) override; 61061da546Spatrick 62061da546Spatrick lldb::ThreadSP 63061da546Spatrick GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp, 64061da546Spatrick lldb_private::ConstString type) override; 65061da546Spatrick 66061da546Spatrick lldb::ThreadSP GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref); 67061da546Spatrick 68061da546Spatrick void PopulateQueueList(lldb_private::QueueList &queue_list) override; 69061da546Spatrick 70061da546Spatrick void PopulateQueuesUsingLibBTR(lldb::addr_t queues_buffer, 71061da546Spatrick uint64_t queues_buffer_size, uint64_t count, 72061da546Spatrick lldb_private::QueueList &queue_list); 73061da546Spatrick 74061da546Spatrick void PopulatePendingQueuesUsingLibBTR(lldb::addr_t items_buffer, 75061da546Spatrick uint64_t items_buffer_size, 76061da546Spatrick uint64_t count, 77061da546Spatrick lldb_private::Queue *queue); 78061da546Spatrick 79061da546Spatrick std::string 80061da546Spatrick GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr) override; 81061da546Spatrick 82061da546Spatrick lldb::queue_id_t 83061da546Spatrick GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) override; 84061da546Spatrick 85061da546Spatrick lldb::addr_t GetLibdispatchQueueAddressFromThreadQAddress( 86061da546Spatrick lldb::addr_t dispatch_qaddr) override; 87061da546Spatrick 88061da546Spatrick void PopulatePendingItemsForQueue(lldb_private::Queue *queue) override; 89061da546Spatrick 90061da546Spatrick void CompleteQueueItem(lldb_private::QueueItem *queue_item, 91061da546Spatrick lldb::addr_t item_ref) override; 92061da546Spatrick 93061da546Spatrick lldb::QueueKind GetQueueKind(lldb::addr_t dispatch_queue_addr) override; 94061da546Spatrick 95061da546Spatrick void AddThreadExtendedInfoPacketHints( 96061da546Spatrick lldb_private::StructuredData::ObjectSP dict) override; 97061da546Spatrick 98061da546Spatrick bool SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp) override; 99061da546Spatrick 100061da546Spatrick // PluginInterface protocol GetPluginName()101*f6aab3d8Srobert llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 102061da546Spatrick 103061da546Spatrick protected: 104061da546Spatrick lldb::user_id_t m_break_id; 105061da546Spatrick mutable std::recursive_mutex m_mutex; 106061da546Spatrick 107061da546Spatrick private: 108061da546Spatrick struct libBacktraceRecording_info { 109be691f3bSpatrick uint16_t queue_info_version = 0; 110be691f3bSpatrick uint16_t queue_info_data_offset = 0; 111be691f3bSpatrick uint16_t item_info_version = 0; 112be691f3bSpatrick uint16_t item_info_data_offset = 0; 113061da546Spatrick 114be691f3bSpatrick libBacktraceRecording_info() = default; 115061da546Spatrick }; 116061da546Spatrick 117061da546Spatrick // A structure which reflects the data recorded in the 118061da546Spatrick // libBacktraceRecording introspection_dispatch_item_info_s. 119061da546Spatrick struct ItemInfo { 120061da546Spatrick lldb::addr_t item_that_enqueued_this; 121061da546Spatrick lldb::addr_t function_or_block; 122061da546Spatrick uint64_t enqueuing_thread_id; 123061da546Spatrick uint64_t enqueuing_queue_serialnum; 124061da546Spatrick uint64_t target_queue_serialnum; 125061da546Spatrick uint32_t enqueuing_callstack_frame_count; 126061da546Spatrick uint32_t stop_id; 127061da546Spatrick std::vector<lldb::addr_t> enqueuing_callstack; 128061da546Spatrick std::string enqueuing_thread_label; 129061da546Spatrick std::string enqueuing_queue_label; 130061da546Spatrick std::string target_queue_label; 131061da546Spatrick }; 132061da546Spatrick 133061da546Spatrick // The offsets of different fields of the dispatch_queue_t structure in 134061da546Spatrick // a thread/queue process. 135061da546Spatrick // Based on libdispatch src/queue_private.h, struct dispatch_queue_offsets_s 136061da546Spatrick // With dqo_version 1-3, the dqo_label field is a per-queue value and cannot 137061da546Spatrick // be cached. 138061da546Spatrick // With dqo_version 4 (Mac OS X 10.9 / iOS 7), dqo_label is a constant value 139061da546Spatrick // that can be cached. 140061da546Spatrick struct LibdispatchOffsets { 141061da546Spatrick uint16_t dqo_version; 142061da546Spatrick uint16_t dqo_label; 143061da546Spatrick uint16_t dqo_label_size; 144061da546Spatrick uint16_t dqo_flags; 145061da546Spatrick uint16_t dqo_flags_size; 146061da546Spatrick uint16_t dqo_serialnum; 147061da546Spatrick uint16_t dqo_serialnum_size; 148061da546Spatrick uint16_t dqo_width; 149061da546Spatrick uint16_t dqo_width_size; 150061da546Spatrick uint16_t dqo_running; 151061da546Spatrick uint16_t dqo_running_size; 152061da546Spatrick 153061da546Spatrick uint16_t dqo_suspend_cnt; // version 5 and later, starting with Mac OS X 154061da546Spatrick // 10.10/iOS 8 155061da546Spatrick uint16_t dqo_suspend_cnt_size; // version 5 and later, starting with Mac OS 156061da546Spatrick // X 10.10/iOS 8 157061da546Spatrick uint16_t dqo_target_queue; // version 5 and later, starting with Mac OS X 158061da546Spatrick // 10.10/iOS 8 159061da546Spatrick uint16_t dqo_target_queue_size; // version 5 and later, starting with Mac OS 160061da546Spatrick // X 10.10/iOS 8 161061da546Spatrick uint16_t 162061da546Spatrick dqo_priority; // version 5 and later, starting with Mac OS X 10.10/iOS 8 163061da546Spatrick uint16_t dqo_priority_size; // version 5 and later, starting with Mac OS X 164061da546Spatrick // 10.10/iOS 8 165061da546Spatrick LibdispatchOffsetsLibdispatchOffsets166061da546Spatrick LibdispatchOffsets() { 167061da546Spatrick dqo_version = UINT16_MAX; 168061da546Spatrick dqo_flags = UINT16_MAX; 169061da546Spatrick dqo_serialnum = UINT16_MAX; 170061da546Spatrick dqo_label = UINT16_MAX; 171061da546Spatrick dqo_width = UINT16_MAX; 172061da546Spatrick dqo_running = UINT16_MAX; 173061da546Spatrick dqo_suspend_cnt = UINT16_MAX; 174061da546Spatrick dqo_target_queue = UINT16_MAX; 175061da546Spatrick dqo_target_queue = UINT16_MAX; 176061da546Spatrick dqo_priority = UINT16_MAX; 177*f6aab3d8Srobert dqo_label_size = 0; 178*f6aab3d8Srobert dqo_flags_size = 0; 179*f6aab3d8Srobert dqo_serialnum_size = 0; 180*f6aab3d8Srobert dqo_width_size = 0; 181*f6aab3d8Srobert dqo_running_size = 0; 182*f6aab3d8Srobert dqo_suspend_cnt_size = 0; 183*f6aab3d8Srobert dqo_target_queue_size = 0; 184*f6aab3d8Srobert dqo_priority_size = 0; 185061da546Spatrick } 186061da546Spatrick IsValidLibdispatchOffsets187061da546Spatrick bool IsValid() { return dqo_version != UINT16_MAX; } 188061da546Spatrick LabelIsValidLibdispatchOffsets189061da546Spatrick bool LabelIsValid() { return dqo_label != UINT16_MAX; } 190061da546Spatrick }; 191061da546Spatrick 192061da546Spatrick struct LibdispatchVoucherOffsets { 193be691f3bSpatrick uint16_t vo_version = UINT16_MAX; 194be691f3bSpatrick uint16_t vo_activity_ids_count = UINT16_MAX; 195be691f3bSpatrick uint16_t vo_activity_ids_count_size = UINT16_MAX; 196be691f3bSpatrick uint16_t vo_activity_ids_array = UINT16_MAX; 197be691f3bSpatrick uint16_t vo_activity_ids_array_entry_size = UINT16_MAX; 198061da546Spatrick 199be691f3bSpatrick LibdispatchVoucherOffsets() = default; 200061da546Spatrick IsValidLibdispatchVoucherOffsets201061da546Spatrick bool IsValid() { return vo_version != UINT16_MAX; } 202061da546Spatrick }; 203061da546Spatrick 204061da546Spatrick struct LibdispatchTSDIndexes { 205be691f3bSpatrick uint16_t dti_version = UINT16_MAX; 206be691f3bSpatrick uint64_t dti_queue_index = UINT64_MAX; 207be691f3bSpatrick uint64_t dti_voucher_index = UINT64_MAX; 208be691f3bSpatrick uint64_t dti_qos_class_index = UINT64_MAX; 209061da546Spatrick 210be691f3bSpatrick LibdispatchTSDIndexes() = default; 211061da546Spatrick IsValidLibdispatchTSDIndexes212061da546Spatrick bool IsValid() { return dti_version != UINT16_MAX; } 213061da546Spatrick }; 214061da546Spatrick 215061da546Spatrick struct LibpthreadOffsets { 216be691f3bSpatrick uint16_t plo_version = UINT16_MAX; 217be691f3bSpatrick uint16_t plo_pthread_tsd_base_offset = UINT16_MAX; 218be691f3bSpatrick uint16_t plo_pthread_tsd_base_address_offset = UINT16_MAX; 219be691f3bSpatrick uint16_t plo_pthread_tsd_entry_size = UINT16_MAX; 220061da546Spatrick 221be691f3bSpatrick LibpthreadOffsets() = default; 222061da546Spatrick IsValidLibpthreadOffsets223061da546Spatrick bool IsValid() { return plo_version != UINT16_MAX; } 224061da546Spatrick }; 225061da546Spatrick 226061da546Spatrick // The libBacktraceRecording function 227061da546Spatrick // __introspection_dispatch_queue_get_pending_items has 228061da546Spatrick // two forms. It can either return a simple array of item_refs (void *) size 229061da546Spatrick // or it can return 230061da546Spatrick // a header with uint32_t version, a uint32_t size of item, and then an array 231061da546Spatrick // of item_refs (void*) 232061da546Spatrick // and code addresses (void*) for all the pending blocks. 233061da546Spatrick 234061da546Spatrick struct ItemRefAndCodeAddress { 235061da546Spatrick lldb::addr_t item_ref; 236061da546Spatrick lldb::addr_t code_address; 237061da546Spatrick }; 238061da546Spatrick 239061da546Spatrick struct PendingItemsForQueue { 240061da546Spatrick bool new_style; // new-style means both item_refs and code_addresses avail 241061da546Spatrick // old-style means only item_refs is filled in 242061da546Spatrick std::vector<ItemRefAndCodeAddress> item_refs_and_code_addresses; 243061da546Spatrick }; 244061da546Spatrick 245061da546Spatrick bool BacktraceRecordingHeadersInitialized(); 246061da546Spatrick 247061da546Spatrick void ReadLibdispatchOffsetsAddress(); 248061da546Spatrick 249061da546Spatrick void ReadLibdispatchOffsets(); 250061da546Spatrick 251061da546Spatrick void ReadLibpthreadOffsetsAddress(); 252061da546Spatrick 253061da546Spatrick void ReadLibpthreadOffsets(); 254061da546Spatrick 255061da546Spatrick void ReadLibdispatchTSDIndexesAddress(); 256061da546Spatrick 257061da546Spatrick void ReadLibdispatchTSDIndexes(); 258061da546Spatrick 259061da546Spatrick PendingItemsForQueue GetPendingItemRefsForQueue(lldb::addr_t queue); 260061da546Spatrick 261061da546Spatrick ItemInfo ExtractItemInfoFromBuffer(lldb_private::DataExtractor &extractor); 262061da546Spatrick 263061da546Spatrick lldb_private::AppleGetQueuesHandler m_get_queues_handler; 264061da546Spatrick lldb_private::AppleGetPendingItemsHandler m_get_pending_items_handler; 265061da546Spatrick lldb_private::AppleGetItemInfoHandler m_get_item_info_handler; 266061da546Spatrick lldb_private::AppleGetThreadItemInfoHandler m_get_thread_item_info_handler; 267061da546Spatrick 268061da546Spatrick lldb::addr_t m_page_to_free; 269061da546Spatrick uint64_t m_page_to_free_size; 270061da546Spatrick libBacktraceRecording_info m_lib_backtrace_recording_info; 271061da546Spatrick 272061da546Spatrick lldb::addr_t m_dispatch_queue_offsets_addr; 273061da546Spatrick struct LibdispatchOffsets m_libdispatch_offsets; 274061da546Spatrick 275061da546Spatrick lldb::addr_t m_libpthread_layout_offsets_addr; 276061da546Spatrick struct LibpthreadOffsets m_libpthread_offsets; 277061da546Spatrick 278061da546Spatrick lldb::addr_t m_dispatch_tsd_indexes_addr; 279061da546Spatrick struct LibdispatchTSDIndexes m_libdispatch_tsd_indexes; 280061da546Spatrick 281061da546Spatrick lldb::addr_t m_dispatch_voucher_offsets_addr; 282061da546Spatrick struct LibdispatchVoucherOffsets m_libdispatch_voucher_offsets; 283061da546Spatrick 284dda28197Spatrick SystemRuntimeMacOSX(const SystemRuntimeMacOSX &) = delete; 285dda28197Spatrick const SystemRuntimeMacOSX &operator=(const SystemRuntimeMacOSX &) = delete; 286061da546Spatrick }; 287061da546Spatrick 288dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_SYSTEMRUNTIME_MACOSX_SYSTEMRUNTIMEMACOSX_H 289