1 //===-- SystemRuntimeMacOSX.h -----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_SystemRuntimeMacOSX_h_
11 #define liblldb_SystemRuntimeMacOSX_h_
12 
13 // C Includes
14 // C++ Includes
15 #include <map>
16 #include <vector>
17 #include <string>
18 
19 // Other libraries and framework includes
20 
21 #include "lldb/Target/SystemRuntime.h"
22 #include "lldb/Host/FileSpec.h"
23 #include "lldb/Core/ConstString.h"
24 #include "lldb/Core/ModuleList.h"
25 #include "lldb/Core/UUID.h"
26 #include "lldb/Host/Mutex.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/QueueItem.h"
29 
30 #include "AppleGetItemInfoHandler.h"
31 #include "AppleGetQueuesHandler.h"
32 #include "AppleGetPendingItemsHandler.h"
33 #include "AppleGetThreadItemInfoHandler.h"
34 
35 class SystemRuntimeMacOSX : public lldb_private::SystemRuntime
36 {
37 public:
38     //------------------------------------------------------------------
39     // Static Functions
40     //------------------------------------------------------------------
41     static void
42     Initialize();
43 
44     static void
45     Terminate();
46 
47     static lldb_private::ConstString
48     GetPluginNameStatic();
49 
50     static const char *
51     GetPluginDescriptionStatic();
52 
53     static lldb_private::SystemRuntime *
54     CreateInstance (lldb_private::Process *process);
55 
56 
57     //------------------------------------------------------------------
58     // instance methods
59     //------------------------------------------------------------------
60 
61     SystemRuntimeMacOSX (lldb_private::Process *process);
62 
63     virtual
64     ~SystemRuntimeMacOSX ();
65 
66     void
67     Clear (bool clear_process);
68 
69     void
70     Detach ();
71 
72     const std::vector<lldb_private::ConstString> &
73     GetExtendedBacktraceTypes ();
74 
75     lldb::ThreadSP
76     GetExtendedBacktraceThread (lldb::ThreadSP thread, lldb_private::ConstString type);
77 
78     lldb::ThreadSP
79     GetExtendedBacktraceForQueueItem (lldb::QueueItemSP queue_item_sp, lldb_private::ConstString type);
80 
81     lldb::ThreadSP
82     GetExtendedBacktraceFromItemRef (lldb::addr_t item_ref);
83 
84     void
85     PopulateQueueList (lldb_private::QueueList &queue_list);
86 
87     void
88     PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count, lldb_private::QueueList &queue_list);
89 
90     void
91     PopulatePendingQueuesUsingLibBTR (lldb::addr_t items_buffer, uint64_t items_buffer_size, uint64_t count, lldb_private::Queue *queue);
92 
93     std::string
94     GetQueueNameFromThreadQAddress (lldb::addr_t dispatch_qaddr);
95 
96     lldb::queue_id_t
97     GetQueueIDFromThreadQAddress (lldb::addr_t dispatch_qaddr);
98 
99     lldb::addr_t
100     GetLibdispatchQueueAddressFromThreadQAddress (lldb::addr_t dispatch_qaddr);
101 
102     void
103     PopulatePendingItemsForQueue (lldb_private::Queue *queue);
104 
105     void
106     CompleteQueueItem (lldb_private::QueueItem *queue_item, lldb::addr_t item_ref);
107 
108     virtual lldb::QueueKind
109     GetQueueKind (lldb::addr_t dispatch_queue_addr);
110 
111     //------------------------------------------------------------------
112     // PluginInterface protocol
113     //------------------------------------------------------------------
114     virtual lldb_private::ConstString
115     GetPluginName();
116 
117     virtual uint32_t
118     GetPluginVersion();
119 
120 
121 protected:
122     lldb::user_id_t m_break_id;
123     mutable lldb_private::Mutex m_mutex;
124 
125 private:
126 
127     struct libBacktraceRecording_info {
128         uint16_t    queue_info_version;
129         uint16_t    queue_info_data_offset;
130         uint16_t    item_info_version;
131         uint16_t    item_info_data_offset;
132 
133         libBacktraceRecording_info () :
134             queue_info_version(0),
135             queue_info_data_offset(0),
136             item_info_version(0),
137             item_info_data_offset(0) {}
138     };
139 
140 
141     // A structure which reflects the data recorded in the
142     // libBacktraceRecording introspection_dispatch_item_info_s.
143     struct ItemInfo {
144         lldb::addr_t    item_that_enqueued_this;
145         lldb::addr_t    function_or_block;
146         uint64_t        enqueuing_thread_id;
147         uint64_t        enqueuing_queue_serialnum;
148         uint64_t        target_queue_serialnum;
149         uint32_t        enqueuing_callstack_frame_count;
150         uint32_t        stop_id;
151         std::vector<lldb::addr_t>   enqueuing_callstack;
152         std::string                 enqueuing_thread_label;
153         std::string                 enqueuing_queue_label;
154         std::string                 target_queue_label;
155     };
156 
157     // The offsets of different fields of the dispatch_queue_t structure in
158     // a thread/queue process.
159     // Based on libdispatch src/queue_private.h, struct dispatch_queue_offsets_s
160     // With dqo_version 1-3, the dqo_label field is a per-queue value and cannot be cached.
161     // With dqo_version 4 (Mac OS X 10.9 / iOS 7), dqo_label is a constant value that can be cached.
162     struct LibdispatchOffsets
163     {
164         uint16_t dqo_version;
165         uint16_t dqo_label;
166         uint16_t dqo_label_size;
167         uint16_t dqo_flags;
168         uint16_t dqo_flags_size;
169         uint16_t dqo_serialnum;
170         uint16_t dqo_serialnum_size;
171         uint16_t dqo_width;
172         uint16_t dqo_width_size;
173         uint16_t dqo_running;
174         uint16_t dqo_running_size;
175 
176         LibdispatchOffsets ()
177         {
178             dqo_version = UINT16_MAX;
179             dqo_flags  = UINT16_MAX;
180             dqo_serialnum = UINT16_MAX;
181             dqo_label = UINT16_MAX;
182             dqo_width = UINT16_MAX;
183             dqo_running = UINT16_MAX;
184         };
185 
186         bool
187         IsValid ()
188         {
189             return dqo_version != UINT16_MAX;
190         }
191 
192         bool
193         LabelIsValid ()
194         {
195             return dqo_label != UINT16_MAX;
196         }
197     };
198 
199 
200     // The libBacktraceRecording function __introspection_dispatch_queue_get_pending_items has
201     // two forms.  It can either return a simple array of item_refs (void *) size or it can return
202     // a header with uint32_t version, a uint32_t size of item, and then an array of item_refs (void*)
203     // and code addresses (void*) for all the pending blocks.
204 
205     struct ItemRefAndCodeAddress {
206         lldb::addr_t    item_ref;
207         lldb::addr_t    code_address;
208     };
209 
210     struct PendingItemsForQueue {
211         bool new_style;              // new-style means both item_refs and code_addresses avail
212                                      // old-style means only item_refs is filled in
213         std::vector<ItemRefAndCodeAddress> item_refs_and_code_addresses;
214     };
215 
216     bool
217     BacktraceRecordingHeadersInitialized ();
218 
219     void
220     ReadLibdispatchOffsetsAddress();
221 
222     void
223     ReadLibdispatchOffsets ();
224 
225     PendingItemsForQueue
226     GetPendingItemRefsForQueue (lldb::addr_t queue);
227 
228     ItemInfo
229     ExtractItemInfoFromBuffer (lldb_private::DataExtractor &extractor);
230 
231     lldb_private::AppleGetQueuesHandler m_get_queues_handler;
232     lldb_private::AppleGetPendingItemsHandler m_get_pending_items_handler;
233     lldb_private::AppleGetItemInfoHandler m_get_item_info_handler;
234     lldb_private::AppleGetThreadItemInfoHandler m_get_thread_item_info_handler;
235 
236     lldb::addr_t                        m_page_to_free;
237     uint64_t                            m_page_to_free_size;
238     libBacktraceRecording_info          m_lib_backtrace_recording_info;
239     lldb::addr_t                        m_dispatch_queue_offsets_addr;
240     struct LibdispatchOffsets           m_libdispatch_offsets;
241 
242     DISALLOW_COPY_AND_ASSIGN (SystemRuntimeMacOSX);
243 };
244 
245 #endif  // liblldb_SystemRuntimeMacOSX_h_
246