180814287SRaphael Isemann //===-- SystemRuntimeMacOSX.cpp -------------------------------------------===//
2a7b5afa9SJason Molenda //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a7b5afa9SJason Molenda //
7a7b5afa9SJason Molenda //===----------------------------------------------------------------------===//
8a7b5afa9SJason Molenda 
9b9c1b51eSKate Stone #include "Plugins/Process/Utility/HistoryThread.h"
108be30215SAlex Langford #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
11a7b5afa9SJason Molenda #include "lldb/Breakpoint/StoppointCallbackContext.h"
12a7b5afa9SJason Molenda #include "lldb/Core/Module.h"
13a7b5afa9SJason Molenda #include "lldb/Core/ModuleSpec.h"
14a7b5afa9SJason Molenda #include "lldb/Core/PluginManager.h"
15a7b5afa9SJason Molenda #include "lldb/Core/Section.h"
16a7b5afa9SJason Molenda #include "lldb/Symbol/ObjectFile.h"
17a7b5afa9SJason Molenda #include "lldb/Symbol/SymbolContext.h"
18b9c1b51eSKate Stone #include "lldb/Target/Process.h"
1901c3243fSZachary Turner #include "lldb/Target/ProcessStructReader.h"
205e8dce4dSJason Molenda #include "lldb/Target/Queue.h"
215e8dce4dSJason Molenda #include "lldb/Target/QueueList.h"
22a7b5afa9SJason Molenda #include "lldb/Target/Target.h"
23a7b5afa9SJason Molenda #include "lldb/Target/Thread.h"
24666cc0b2SZachary Turner #include "lldb/Utility/DataBufferHeap.h"
25666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h"
265713a05bSZachary Turner #include "lldb/Utility/FileSpec.h"
27c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
286f9e6901SZachary Turner #include "lldb/Utility/Log.h"
29bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
302fd83355SJason Molenda 
31a7b5afa9SJason Molenda #include "SystemRuntimeMacOSX.h"
32a7b5afa9SJason Molenda 
33796ac80bSJonas Devlieghere #include <memory>
34796ac80bSJonas Devlieghere 
35a7b5afa9SJason Molenda using namespace lldb;
36a7b5afa9SJason Molenda using namespace lldb_private;
37a7b5afa9SJason Molenda 
LLDB_PLUGIN_DEFINE(SystemRuntimeMacOSX)38bba9ba8dSJonas Devlieghere LLDB_PLUGIN_DEFINE(SystemRuntimeMacOSX)
39fbb4d1e4SJonas Devlieghere 
4005097246SAdrian Prantl // Create an instance of this class. This function is filled into the plugin
4105097246SAdrian Prantl // info class that gets handed out by the plugin factory and allows the lldb to
4205097246SAdrian Prantl // instantiate an instance of this class.
43b9c1b51eSKate Stone SystemRuntime *SystemRuntimeMacOSX::CreateInstance(Process *process) {
44a7b5afa9SJason Molenda   bool create = false;
45b9c1b51eSKate Stone   if (!create) {
46a7b5afa9SJason Molenda     create = true;
47a7b5afa9SJason Molenda     Module *exe_module = process->GetTarget().GetExecutableModulePointer();
48b9c1b51eSKate Stone     if (exe_module) {
49a7b5afa9SJason Molenda       ObjectFile *object_file = exe_module->GetObjectFile();
50b9c1b51eSKate Stone       if (object_file) {
51a7b5afa9SJason Molenda         create = (object_file->GetStrata() == ObjectFile::eStrataUser);
52a7b5afa9SJason Molenda       }
53a7b5afa9SJason Molenda     }
54a7b5afa9SJason Molenda 
55b9c1b51eSKate Stone     if (create) {
56b9c1b51eSKate Stone       const llvm::Triple &triple_ref =
57b9c1b51eSKate Stone           process->GetTarget().GetArchitecture().GetTriple();
58b9c1b51eSKate Stone       switch (triple_ref.getOS()) {
59a7b5afa9SJason Molenda       case llvm::Triple::Darwin:
60a7b5afa9SJason Molenda       case llvm::Triple::MacOSX:
61a7b5afa9SJason Molenda       case llvm::Triple::IOS:
62a814f704SJason Molenda       case llvm::Triple::TvOS:
63a814f704SJason Molenda       case llvm::Triple::WatchOS:
6432762fd2SJason Molenda       // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
65a7b5afa9SJason Molenda         create = triple_ref.getVendor() == llvm::Triple::Apple;
66a7b5afa9SJason Molenda         break;
67a7b5afa9SJason Molenda       default:
68a7b5afa9SJason Molenda         create = false;
69a7b5afa9SJason Molenda         break;
70a7b5afa9SJason Molenda       }
71a7b5afa9SJason Molenda     }
72a7b5afa9SJason Molenda   }
73a7b5afa9SJason Molenda 
74a7b5afa9SJason Molenda   if (create)
75a7b5afa9SJason Molenda     return new SystemRuntimeMacOSX(process);
76248a1305SKonrad Kleine   return nullptr;
77a7b5afa9SJason Molenda }
78a7b5afa9SJason Molenda 
79a7b5afa9SJason Molenda // Constructor
SystemRuntimeMacOSX(Process * process)8016ff8604SSaleem Abdulrasool SystemRuntimeMacOSX::SystemRuntimeMacOSX(Process *process)
81b9c1b51eSKate Stone     : SystemRuntime(process), m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
82b9c1b51eSKate Stone       m_get_queues_handler(process), m_get_pending_items_handler(process),
83b9c1b51eSKate Stone       m_get_item_info_handler(process), m_get_thread_item_info_handler(process),
84b9c1b51eSKate Stone       m_page_to_free(LLDB_INVALID_ADDRESS), m_page_to_free_size(0),
852fd83355SJason Molenda       m_lib_backtrace_recording_info(),
862fd83355SJason Molenda       m_dispatch_queue_offsets_addr(LLDB_INVALID_ADDRESS),
87705b1809SJason Molenda       m_libdispatch_offsets(),
88705b1809SJason Molenda       m_libpthread_layout_offsets_addr(LLDB_INVALID_ADDRESS),
89b9c1b51eSKate Stone       m_libpthread_offsets(), m_dispatch_tsd_indexes_addr(LLDB_INVALID_ADDRESS),
90705b1809SJason Molenda       m_libdispatch_tsd_indexes(),
91705b1809SJason Molenda       m_dispatch_voucher_offsets_addr(LLDB_INVALID_ADDRESS),
92b9c1b51eSKate Stone       m_libdispatch_voucher_offsets() {}
93a7b5afa9SJason Molenda 
94a7b5afa9SJason Molenda // Destructor
~SystemRuntimeMacOSX()95b9c1b51eSKate Stone SystemRuntimeMacOSX::~SystemRuntimeMacOSX() { Clear(true); }
96a7b5afa9SJason Molenda 
Detach()97b9c1b51eSKate Stone void SystemRuntimeMacOSX::Detach() {
982fd83355SJason Molenda   m_get_queues_handler.Detach();
992fd83355SJason Molenda   m_get_pending_items_handler.Detach();
1002fd83355SJason Molenda   m_get_item_info_handler.Detach();
1012fd83355SJason Molenda   m_get_thread_item_info_handler.Detach();
1022fd83355SJason Molenda }
1032fd83355SJason Molenda 
104a7b5afa9SJason Molenda // Clear out the state of this class.
Clear(bool clear_process)105b9c1b51eSKate Stone void SystemRuntimeMacOSX::Clear(bool clear_process) {
10616ff8604SSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_mutex);
107a7b5afa9SJason Molenda 
108a7b5afa9SJason Molenda   if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
109a7b5afa9SJason Molenda     m_process->ClearBreakpointSiteByID(m_break_id);
110a7b5afa9SJason Molenda 
111a7b5afa9SJason Molenda   if (clear_process)
112248a1305SKonrad Kleine     m_process = nullptr;
113a7b5afa9SJason Molenda   m_break_id = LLDB_INVALID_BREAK_ID;
1142fd83355SJason Molenda }
1152fd83355SJason Molenda 
1162fd83355SJason Molenda std::string
GetQueueNameFromThreadQAddress(addr_t dispatch_qaddr)117b9c1b51eSKate Stone SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress(addr_t dispatch_qaddr) {
1182fd83355SJason Molenda   std::string dispatch_queue_name;
1192fd83355SJason Molenda   if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
1202fd83355SJason Molenda     return "";
1212fd83355SJason Molenda 
1222fd83355SJason Molenda   ReadLibdispatchOffsets();
123b9c1b51eSKate Stone   if (m_libdispatch_offsets.IsValid()) {
124b9c1b51eSKate Stone     // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
12505097246SAdrian Prantl     // thread - deref it to get the address of the dispatch_queue_t structure
12605097246SAdrian Prantl     // for this thread's queue.
12797206d57SZachary Turner     Status error;
128b9c1b51eSKate Stone     addr_t dispatch_queue_addr =
129b9c1b51eSKate Stone         m_process->ReadPointerFromMemory(dispatch_qaddr, error);
130b9c1b51eSKate Stone     if (error.Success()) {
131b9c1b51eSKate Stone       if (m_libdispatch_offsets.dqo_version >= 4) {
13205097246SAdrian Prantl         // libdispatch versions 4+, pointer to dispatch name is in the queue
13305097246SAdrian Prantl         // structure.
134b9c1b51eSKate Stone         addr_t pointer_to_label_address =
135b9c1b51eSKate Stone             dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
136b9c1b51eSKate Stone         addr_t label_addr =
137b9c1b51eSKate Stone             m_process->ReadPointerFromMemory(pointer_to_label_address, error);
138b9c1b51eSKate Stone         if (error.Success()) {
139b9c1b51eSKate Stone           m_process->ReadCStringFromMemory(label_addr, dispatch_queue_name,
140b9c1b51eSKate Stone                                            error);
1412fd83355SJason Molenda         }
142b9c1b51eSKate Stone       } else {
1432fd83355SJason Molenda         // libdispatch versions 1-3, dispatch name is a fixed width char array
1442fd83355SJason Molenda         // in the queue structure.
145b9c1b51eSKate Stone         addr_t label_addr =
146b9c1b51eSKate Stone             dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
1472fd83355SJason Molenda         dispatch_queue_name.resize(m_libdispatch_offsets.dqo_label_size, '\0');
148b9c1b51eSKate Stone         size_t bytes_read =
149b9c1b51eSKate Stone             m_process->ReadMemory(label_addr, &dispatch_queue_name[0],
150b9c1b51eSKate Stone                                   m_libdispatch_offsets.dqo_label_size, error);
1512fd83355SJason Molenda         if (bytes_read < m_libdispatch_offsets.dqo_label_size)
1522fd83355SJason Molenda           dispatch_queue_name.erase(bytes_read);
1532fd83355SJason Molenda       }
1542fd83355SJason Molenda     }
1552fd83355SJason Molenda   }
1562fd83355SJason Molenda   return dispatch_queue_name;
1572fd83355SJason Molenda }
1582fd83355SJason Molenda 
GetLibdispatchQueueAddressFromThreadQAddress(addr_t dispatch_qaddr)159b9c1b51eSKate Stone lldb::addr_t SystemRuntimeMacOSX::GetLibdispatchQueueAddressFromThreadQAddress(
160b9c1b51eSKate Stone     addr_t dispatch_qaddr) {
161aac16e0fSJason Molenda   addr_t libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
16297206d57SZachary Turner   Status error;
163b9c1b51eSKate Stone   libdispatch_queue_t_address =
164b9c1b51eSKate Stone       m_process->ReadPointerFromMemory(dispatch_qaddr, error);
165b9c1b51eSKate Stone   if (!error.Success()) {
166aac16e0fSJason Molenda     libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
167aac16e0fSJason Molenda   }
168aac16e0fSJason Molenda   return libdispatch_queue_t_address;
169aac16e0fSJason Molenda }
170aac16e0fSJason Molenda 
GetQueueKind(addr_t dispatch_queue_addr)171b9c1b51eSKate Stone lldb::QueueKind SystemRuntimeMacOSX::GetQueueKind(addr_t dispatch_queue_addr) {
172aac16e0fSJason Molenda   if (dispatch_queue_addr == LLDB_INVALID_ADDRESS || dispatch_queue_addr == 0)
173aac16e0fSJason Molenda     return eQueueKindUnknown;
174aac16e0fSJason Molenda 
175aac16e0fSJason Molenda   QueueKind kind = eQueueKindUnknown;
176aac16e0fSJason Molenda   ReadLibdispatchOffsets();
177b9c1b51eSKate Stone   if (m_libdispatch_offsets.IsValid() &&
178b9c1b51eSKate Stone       m_libdispatch_offsets.dqo_version >= 4) {
17997206d57SZachary Turner     Status error;
180b9c1b51eSKate Stone     uint64_t width = m_process->ReadUnsignedIntegerFromMemory(
181b9c1b51eSKate Stone         dispatch_queue_addr + m_libdispatch_offsets.dqo_width,
182b9c1b51eSKate Stone         m_libdispatch_offsets.dqo_width_size, 0, error);
183b9c1b51eSKate Stone     if (error.Success()) {
184b9c1b51eSKate Stone       if (width == 1) {
185aac16e0fSJason Molenda         kind = eQueueKindSerial;
186aac16e0fSJason Molenda       }
187b9c1b51eSKate Stone       if (width > 1) {
188aac16e0fSJason Molenda         kind = eQueueKindConcurrent;
189aac16e0fSJason Molenda       }
190aac16e0fSJason Molenda     }
191aac16e0fSJason Molenda   }
192aac16e0fSJason Molenda   return kind;
193aac16e0fSJason Molenda }
194aac16e0fSJason Molenda 
AddThreadExtendedInfoPacketHints(lldb_private::StructuredData::ObjectSP dict_sp)195b9c1b51eSKate Stone void SystemRuntimeMacOSX::AddThreadExtendedInfoPacketHints(
196b9c1b51eSKate Stone     lldb_private::StructuredData::ObjectSP dict_sp) {
197705b1809SJason Molenda   StructuredData::Dictionary *dict = dict_sp->GetAsDictionary();
198b9c1b51eSKate Stone   if (dict) {
199705b1809SJason Molenda     ReadLibpthreadOffsets();
200b9c1b51eSKate Stone     if (m_libpthread_offsets.IsValid()) {
201b9c1b51eSKate Stone       dict->AddIntegerItem("plo_pthread_tsd_base_offset",
202b9c1b51eSKate Stone                            m_libpthread_offsets.plo_pthread_tsd_base_offset);
203b9c1b51eSKate Stone       dict->AddIntegerItem(
204b9c1b51eSKate Stone           "plo_pthread_tsd_base_address_offset",
205b9c1b51eSKate Stone           m_libpthread_offsets.plo_pthread_tsd_base_address_offset);
206b9c1b51eSKate Stone       dict->AddIntegerItem("plo_pthread_tsd_entry_size",
207b9c1b51eSKate Stone                            m_libpthread_offsets.plo_pthread_tsd_entry_size);
208705b1809SJason Molenda     }
209705b1809SJason Molenda 
210705b1809SJason Molenda     ReadLibdispatchTSDIndexes();
211b9c1b51eSKate Stone     if (m_libdispatch_tsd_indexes.IsValid()) {
212b9c1b51eSKate Stone       dict->AddIntegerItem("dti_queue_index",
213b9c1b51eSKate Stone                            m_libdispatch_tsd_indexes.dti_queue_index);
214b9c1b51eSKate Stone       dict->AddIntegerItem("dti_voucher_index",
215b9c1b51eSKate Stone                            m_libdispatch_tsd_indexes.dti_voucher_index);
216b9c1b51eSKate Stone       dict->AddIntegerItem("dti_qos_class_index",
217b9c1b51eSKate Stone                            m_libdispatch_tsd_indexes.dti_qos_class_index);
218705b1809SJason Molenda     }
219705b1809SJason Molenda   }
220705b1809SJason Molenda }
221705b1809SJason Molenda 
SafeToCallFunctionsOnThisThread(ThreadSP thread_sp)222b9c1b51eSKate Stone bool SystemRuntimeMacOSX::SafeToCallFunctionsOnThisThread(ThreadSP thread_sp) {
223b9c1b51eSKate Stone   if (thread_sp && thread_sp->GetStackFrameCount() > 0 &&
224b9c1b51eSKate Stone       thread_sp->GetFrameWithConcreteFrameIndex(0)) {
225b9c1b51eSKate Stone     const SymbolContext sym_ctx(
226b9c1b51eSKate Stone         thread_sp->GetFrameWithConcreteFrameIndex(0)->GetSymbolContext(
227b9c1b51eSKate Stone             eSymbolContextSymbol));
228b4892cd2SJason Molenda     static ConstString g_select_symbol("__select");
229b9c1b51eSKate Stone     if (sym_ctx.GetFunctionName() == g_select_symbol) {
230b4892cd2SJason Molenda       return false;
231b4892cd2SJason Molenda     }
232b4892cd2SJason Molenda   }
233b4892cd2SJason Molenda   return true;
234b4892cd2SJason Molenda }
235b4892cd2SJason Molenda 
2362fd83355SJason Molenda lldb::queue_id_t
GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr)237b9c1b51eSKate Stone SystemRuntimeMacOSX::GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
2382fd83355SJason Molenda   queue_id_t queue_id = LLDB_INVALID_QUEUE_ID;
2392fd83355SJason Molenda 
2402fd83355SJason Molenda   if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
2412fd83355SJason Molenda     return queue_id;
2422fd83355SJason Molenda 
2432fd83355SJason Molenda   ReadLibdispatchOffsets();
244b9c1b51eSKate Stone   if (m_libdispatch_offsets.IsValid()) {
245b9c1b51eSKate Stone     // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
24605097246SAdrian Prantl     // thread - deref it to get the address of the dispatch_queue_t structure
24705097246SAdrian Prantl     // for this thread's queue.
24897206d57SZachary Turner     Status error;
249b9c1b51eSKate Stone     uint64_t dispatch_queue_addr =
250b9c1b51eSKate Stone         m_process->ReadPointerFromMemory(dispatch_qaddr, error);
251b9c1b51eSKate Stone     if (error.Success()) {
252b9c1b51eSKate Stone       addr_t serialnum_address =
253b9c1b51eSKate Stone           dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
254b9c1b51eSKate Stone       queue_id_t serialnum = m_process->ReadUnsignedIntegerFromMemory(
255b9c1b51eSKate Stone           serialnum_address, m_libdispatch_offsets.dqo_serialnum_size,
256b9c1b51eSKate Stone           LLDB_INVALID_QUEUE_ID, error);
257b9c1b51eSKate Stone       if (error.Success()) {
2582fd83355SJason Molenda         queue_id = serialnum;
2592fd83355SJason Molenda       }
2602fd83355SJason Molenda     }
2612fd83355SJason Molenda   }
2622fd83355SJason Molenda 
2632fd83355SJason Molenda   return queue_id;
264a7b5afa9SJason Molenda }
265a7b5afa9SJason Molenda 
ReadLibdispatchOffsetsAddress()266b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress() {
2672fd83355SJason Molenda   if (m_dispatch_queue_offsets_addr != LLDB_INVALID_ADDRESS)
2682fd83355SJason Molenda     return;
2692fd83355SJason Molenda 
270b9c1b51eSKate Stone   static ConstString g_dispatch_queue_offsets_symbol_name(
271b9c1b51eSKate Stone       "dispatch_queue_offsets");
272248a1305SKonrad Kleine   const Symbol *dispatch_queue_offsets_symbol = nullptr;
2732fd83355SJason Molenda 
274b9c1b51eSKate Stone   // libdispatch symbols were in libSystem.B.dylib up through Mac OS X 10.6
275b9c1b51eSKate Stone   // ("Snow Leopard")
2768f3be7a3SJonas Devlieghere   ModuleSpec libSystem_module_spec(FileSpec("libSystem.B.dylib"));
277b9c1b51eSKate Stone   ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
278b9c1b51eSKate Stone       libSystem_module_spec));
2792fd83355SJason Molenda   if (module_sp)
280b9c1b51eSKate Stone     dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
281b9c1b51eSKate Stone         g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
2822fd83355SJason Molenda 
28305097246SAdrian Prantl   // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion")
28405097246SAdrian Prantl   // and later
285248a1305SKonrad Kleine   if (dispatch_queue_offsets_symbol == nullptr) {
2868f3be7a3SJonas Devlieghere     ModuleSpec libdispatch_module_spec(FileSpec("libdispatch.dylib"));
287b9c1b51eSKate Stone     module_sp = m_process->GetTarget().GetImages().FindFirstModule(
288b9c1b51eSKate Stone         libdispatch_module_spec);
2892fd83355SJason Molenda     if (module_sp)
290b9c1b51eSKate Stone       dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
291b9c1b51eSKate Stone           g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
2922fd83355SJason Molenda   }
2932fd83355SJason Molenda   if (dispatch_queue_offsets_symbol)
294b9c1b51eSKate Stone     m_dispatch_queue_offsets_addr =
295b9c1b51eSKate Stone         dispatch_queue_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
296a7b5afa9SJason Molenda }
297a7b5afa9SJason Molenda 
ReadLibdispatchOffsets()298b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibdispatchOffsets() {
2992fd83355SJason Molenda   if (m_libdispatch_offsets.IsValid())
3002fd83355SJason Molenda     return;
3012fd83355SJason Molenda 
3022fd83355SJason Molenda   ReadLibdispatchOffsetsAddress();
3032fd83355SJason Molenda 
3042fd83355SJason Molenda   uint8_t memory_buffer[sizeof(struct LibdispatchOffsets)];
305b9c1b51eSKate Stone   DataExtractor data(memory_buffer, sizeof(memory_buffer),
3062fd83355SJason Molenda                      m_process->GetByteOrder(),
3072fd83355SJason Molenda                      m_process->GetAddressByteSize());
3082fd83355SJason Molenda 
30997206d57SZachary Turner   Status error;
310b9c1b51eSKate Stone   if (m_process->ReadMemory(m_dispatch_queue_offsets_addr, memory_buffer,
311b9c1b51eSKate Stone                             sizeof(memory_buffer),
312b9c1b51eSKate Stone                             error) == sizeof(memory_buffer)) {
3132fd83355SJason Molenda     lldb::offset_t data_offset = 0;
3142fd83355SJason Molenda 
315b9c1b51eSKate Stone     // The struct LibdispatchOffsets is a series of uint16_t's - extract them
31605097246SAdrian Prantl     // all in one big go.
317b9c1b51eSKate Stone     data.GetU16(&data_offset, &m_libdispatch_offsets.dqo_version,
318b9c1b51eSKate Stone                 sizeof(struct LibdispatchOffsets) / sizeof(uint16_t));
3192fd83355SJason Molenda   }
320a7b5afa9SJason Molenda }
321a7b5afa9SJason Molenda 
ReadLibpthreadOffsetsAddress()322b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress() {
323705b1809SJason Molenda   if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
324705b1809SJason Molenda     return;
325705b1809SJason Molenda 
326b9c1b51eSKate Stone   static ConstString g_libpthread_layout_offsets_symbol_name(
327b9c1b51eSKate Stone       "pthread_layout_offsets");
328248a1305SKonrad Kleine   const Symbol *libpthread_layout_offsets_symbol = nullptr;
329705b1809SJason Molenda 
3308f3be7a3SJonas Devlieghere   ModuleSpec libpthread_module_spec(FileSpec("libsystem_pthread.dylib"));
331b9c1b51eSKate Stone   ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
332b9c1b51eSKate Stone       libpthread_module_spec));
333b9c1b51eSKate Stone   if (module_sp) {
334b9c1b51eSKate Stone     libpthread_layout_offsets_symbol =
335b9c1b51eSKate Stone         module_sp->FindFirstSymbolWithNameAndType(
336b9c1b51eSKate Stone             g_libpthread_layout_offsets_symbol_name, eSymbolTypeData);
337b9c1b51eSKate Stone     if (libpthread_layout_offsets_symbol) {
338b9c1b51eSKate Stone       m_libpthread_layout_offsets_addr =
339b9c1b51eSKate Stone           libpthread_layout_offsets_symbol->GetLoadAddress(
340b9c1b51eSKate Stone               &m_process->GetTarget());
341705b1809SJason Molenda     }
342705b1809SJason Molenda   }
343705b1809SJason Molenda }
344705b1809SJason Molenda 
ReadLibpthreadOffsets()345b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibpthreadOffsets() {
346705b1809SJason Molenda   if (m_libpthread_offsets.IsValid())
347705b1809SJason Molenda     return;
348705b1809SJason Molenda 
349705b1809SJason Molenda   ReadLibpthreadOffsetsAddress();
350705b1809SJason Molenda 
351b9c1b51eSKate Stone   if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS) {
352705b1809SJason Molenda     uint8_t memory_buffer[sizeof(struct LibpthreadOffsets)];
353b9c1b51eSKate Stone     DataExtractor data(memory_buffer, sizeof(memory_buffer),
354705b1809SJason Molenda                        m_process->GetByteOrder(),
355705b1809SJason Molenda                        m_process->GetAddressByteSize());
35697206d57SZachary Turner     Status error;
357b9c1b51eSKate Stone     if (m_process->ReadMemory(m_libpthread_layout_offsets_addr, memory_buffer,
358b9c1b51eSKate Stone                               sizeof(memory_buffer),
359b9c1b51eSKate Stone                               error) == sizeof(memory_buffer)) {
360705b1809SJason Molenda       lldb::offset_t data_offset = 0;
361705b1809SJason Molenda 
362b9c1b51eSKate Stone       // The struct LibpthreadOffsets is a series of uint16_t's - extract them
36305097246SAdrian Prantl       // all in one big go.
364b9c1b51eSKate Stone       data.GetU16(&data_offset, &m_libpthread_offsets.plo_version,
365b9c1b51eSKate Stone                   sizeof(struct LibpthreadOffsets) / sizeof(uint16_t));
366705b1809SJason Molenda     }
367705b1809SJason Molenda   }
368705b1809SJason Molenda }
369705b1809SJason Molenda 
ReadLibdispatchTSDIndexesAddress()370b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress() {
371705b1809SJason Molenda   if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
372705b1809SJason Molenda     return;
373705b1809SJason Molenda 
374b9c1b51eSKate Stone   static ConstString g_libdispatch_tsd_indexes_symbol_name(
375b9c1b51eSKate Stone       "dispatch_tsd_indexes");
376248a1305SKonrad Kleine   const Symbol *libdispatch_tsd_indexes_symbol = nullptr;
377705b1809SJason Molenda 
3788f3be7a3SJonas Devlieghere   ModuleSpec libpthread_module_spec(FileSpec("libdispatch.dylib"));
379b9c1b51eSKate Stone   ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
380b9c1b51eSKate Stone       libpthread_module_spec));
381b9c1b51eSKate Stone   if (module_sp) {
382b9c1b51eSKate Stone     libdispatch_tsd_indexes_symbol = module_sp->FindFirstSymbolWithNameAndType(
383b9c1b51eSKate Stone         g_libdispatch_tsd_indexes_symbol_name, eSymbolTypeData);
384b9c1b51eSKate Stone     if (libdispatch_tsd_indexes_symbol) {
385b9c1b51eSKate Stone       m_dispatch_tsd_indexes_addr =
386b9c1b51eSKate Stone           libdispatch_tsd_indexes_symbol->GetLoadAddress(
387b9c1b51eSKate Stone               &m_process->GetTarget());
388705b1809SJason Molenda     }
389705b1809SJason Molenda   }
390705b1809SJason Molenda }
391705b1809SJason Molenda 
ReadLibdispatchTSDIndexes()392b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes() {
393705b1809SJason Molenda   if (m_libdispatch_tsd_indexes.IsValid())
394705b1809SJason Molenda     return;
395705b1809SJason Molenda 
396705b1809SJason Molenda   ReadLibdispatchTSDIndexesAddress();
397705b1809SJason Molenda 
398b9c1b51eSKate Stone   if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
39959ac67e9SJason Molenda 
400b9c1b51eSKate Stone // We don't need to check the version number right now, it will be at least 2,
40105097246SAdrian Prantl // but keep this code around to fetch just the version # for the future where
40205097246SAdrian Prantl // we need to fetch alternate versions of the struct.
40359ac67e9SJason Molenda #if 0
404705b1809SJason Molenda         uint16_t dti_version = 2;
40559ac67e9SJason Molenda         Address dti_struct_addr;
406705b1809SJason Molenda         if (m_process->GetTarget().ResolveLoadAddress (m_dispatch_tsd_indexes_addr, dti_struct_addr))
407705b1809SJason Molenda         {
40897206d57SZachary Turner             Status error;
409705b1809SJason Molenda             uint16_t version = m_process->GetTarget().ReadUnsignedIntegerFromMemory (dti_struct_addr, false, 2, UINT16_MAX, error);
410705b1809SJason Molenda             if (error.Success() && dti_version != UINT16_MAX)
411705b1809SJason Molenda             {
412705b1809SJason Molenda                 dti_version = version;
413705b1809SJason Molenda             }
414705b1809SJason Molenda         }
41559ac67e9SJason Molenda #endif
416705b1809SJason Molenda 
4176e3b0cc2SRaphael Isemann     TypeSystemClang *ast_ctx =
418594308c7SRaphael Isemann         ScratchTypeSystemClang::GetForTarget(m_process->GetTarget());
419f9f49d35SRaphael Isemann     if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
420b9c1b51eSKate Stone       CompilerType uint16 =
421b9c1b51eSKate Stone           ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
422b9c1b51eSKate Stone       CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(
423143d507cSAdrian Prantl           nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
424143d507cSAdrian Prantl           "__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct,
425143d507cSAdrian Prantl           lldb::eLanguageTypeC);
426d8d4a57bSGreg Clayton 
4276e3b0cc2SRaphael Isemann       TypeSystemClang::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
4286e3b0cc2SRaphael Isemann       TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s,
429b9c1b51eSKate Stone                                             "dti_version", uint16,
430b9c1b51eSKate Stone                                             lldb::eAccessPublic, 0);
4316e3b0cc2SRaphael Isemann       TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s,
432b9c1b51eSKate Stone                                             "dti_queue_index", uint16,
433b9c1b51eSKate Stone                                             lldb::eAccessPublic, 0);
4346e3b0cc2SRaphael Isemann       TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s,
435b9c1b51eSKate Stone                                             "dti_voucher_index", uint16,
436b9c1b51eSKate Stone                                             lldb::eAccessPublic, 0);
4376e3b0cc2SRaphael Isemann       TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s,
438b9c1b51eSKate Stone                                             "dti_qos_class_index", uint16,
439b9c1b51eSKate Stone                                             lldb::eAccessPublic, 0);
4406e3b0cc2SRaphael Isemann       TypeSystemClang::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s);
441705b1809SJason Molenda 
442b9c1b51eSKate Stone       ProcessStructReader struct_reader(m_process, m_dispatch_tsd_indexes_addr,
443b9c1b51eSKate Stone                                         dispatch_tsd_indexes_s);
44459ac67e9SJason Molenda 
445b9c1b51eSKate Stone       m_libdispatch_tsd_indexes.dti_version =
446b9c1b51eSKate Stone           struct_reader.GetField<uint16_t>(ConstString("dti_version"));
447b9c1b51eSKate Stone       m_libdispatch_tsd_indexes.dti_queue_index =
448b9c1b51eSKate Stone           struct_reader.GetField<uint16_t>(ConstString("dti_queue_index"));
449b9c1b51eSKate Stone       m_libdispatch_tsd_indexes.dti_voucher_index =
450b9c1b51eSKate Stone           struct_reader.GetField<uint16_t>(ConstString("dti_voucher_index"));
451b9c1b51eSKate Stone       m_libdispatch_tsd_indexes.dti_qos_class_index =
452b9c1b51eSKate Stone           struct_reader.GetField<uint16_t>(ConstString("dti_qos_class_index"));
453705b1809SJason Molenda     }
454705b1809SJason Molenda   }
455705b1809SJason Molenda }
456705b1809SJason Molenda 
GetExtendedBacktraceThread(ThreadSP real_thread,ConstString type)457b9c1b51eSKate Stone ThreadSP SystemRuntimeMacOSX::GetExtendedBacktraceThread(ThreadSP real_thread,
458b9c1b51eSKate Stone                                                          ConstString type) {
4592fd83355SJason Molenda   ThreadSP originating_thread_sp;
46005cfdb0eSRaphael Isemann   if (BacktraceRecordingHeadersInitialized() && type == "libdispatch") {
46197206d57SZachary Turner     Status error;
4622fd83355SJason Molenda 
463b9c1b51eSKate Stone     // real_thread is either an actual, live thread (in which case we need to
46405097246SAdrian Prantl     // call into libBacktraceRecording to find its originator) or it is an
46505097246SAdrian Prantl     // extended backtrace itself, in which case we get the token from it and
46605097246SAdrian Prantl     // call into libBacktraceRecording to find the originator of that token.
4672fd83355SJason Molenda 
468b9c1b51eSKate Stone     if (real_thread->GetExtendedBacktraceToken() != LLDB_INVALID_ADDRESS) {
469b9c1b51eSKate Stone       originating_thread_sp = GetExtendedBacktraceFromItemRef(
470b9c1b51eSKate Stone           real_thread->GetExtendedBacktraceToken());
471b9c1b51eSKate Stone     } else {
472b9c1b51eSKate Stone       ThreadSP cur_thread_sp(
473b9c1b51eSKate Stone           m_process->GetThreadList().GetExpressionExecutionThread());
474b9c1b51eSKate Stone       AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo ret =
475b9c1b51eSKate Stone           m_get_thread_item_info_handler.GetThreadItemInfo(
476b9c1b51eSKate Stone               *cur_thread_sp.get(), real_thread->GetID(), m_page_to_free,
477b9c1b51eSKate Stone               m_page_to_free_size, error);
4782a6c252dSJason Molenda       m_page_to_free = LLDB_INVALID_ADDRESS;
4792a6c252dSJason Molenda       m_page_to_free_size = 0;
480b9c1b51eSKate Stone       if (ret.item_buffer_ptr != 0 &&
481b9c1b51eSKate Stone           ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
482b9c1b51eSKate Stone           ret.item_buffer_size > 0) {
4832fd83355SJason Molenda         DataBufferHeap data(ret.item_buffer_size, 0);
484b9c1b51eSKate Stone         if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
485b9c1b51eSKate Stone                                   ret.item_buffer_size, error) &&
486b9c1b51eSKate Stone             error.Success()) {
487b9c1b51eSKate Stone           DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
488b9c1b51eSKate Stone                                   m_process->GetByteOrder(),
489b9c1b51eSKate Stone                                   m_process->GetAddressByteSize());
4902fd83355SJason Molenda           ItemInfo item = ExtractItemInfoFromBuffer(extractor);
491796ac80bSJonas Devlieghere           originating_thread_sp = std::make_shared<HistoryThread>(
49286df61ccSAlex Langford               *m_process, item.enqueuing_thread_id, item.enqueuing_callstack);
493b9c1b51eSKate Stone           originating_thread_sp->SetExtendedBacktraceToken(
494b9c1b51eSKate Stone               item.item_that_enqueued_this);
495b9c1b51eSKate Stone           originating_thread_sp->SetQueueName(
496b9c1b51eSKate Stone               item.enqueuing_queue_label.c_str());
4972fd83355SJason Molenda           originating_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
498b9c1b51eSKate Stone           //                    originating_thread_sp->SetThreadName
499b9c1b51eSKate Stone           //                    (item.enqueuing_thread_label.c_str());
5002fd83355SJason Molenda         }
501da276f90SJason Molenda         m_page_to_free = ret.item_buffer_ptr;
502da276f90SJason Molenda         m_page_to_free_size = ret.item_buffer_size;
5032fd83355SJason Molenda       }
5042fd83355SJason Molenda     }
5052fd83355SJason Molenda   }
5062fd83355SJason Molenda   return originating_thread_sp;
5072fd83355SJason Molenda }
5082fd83355SJason Molenda 
5092fd83355SJason Molenda ThreadSP
GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref)510b9c1b51eSKate Stone SystemRuntimeMacOSX::GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref) {
5112fd83355SJason Molenda   ThreadSP return_thread_sp;
5122fd83355SJason Molenda 
5132fd83355SJason Molenda   AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
514b9c1b51eSKate Stone   ThreadSP cur_thread_sp(
515b9c1b51eSKate Stone       m_process->GetThreadList().GetExpressionExecutionThread());
51697206d57SZachary Turner   Status error;
517b9c1b51eSKate Stone   ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
518b9c1b51eSKate Stone                                             m_page_to_free, m_page_to_free_size,
519b9c1b51eSKate Stone                                             error);
5202a6c252dSJason Molenda   m_page_to_free = LLDB_INVALID_ADDRESS;
5212a6c252dSJason Molenda   m_page_to_free_size = 0;
522b9c1b51eSKate Stone   if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
523b9c1b51eSKate Stone       ret.item_buffer_size > 0) {
5242fd83355SJason Molenda     DataBufferHeap data(ret.item_buffer_size, 0);
525b9c1b51eSKate Stone     if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
526b9c1b51eSKate Stone                               ret.item_buffer_size, error) &&
527b9c1b51eSKate Stone         error.Success()) {
528b9c1b51eSKate Stone       DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
529b9c1b51eSKate Stone                               m_process->GetByteOrder(),
530b9c1b51eSKate Stone                               m_process->GetAddressByteSize());
5312fd83355SJason Molenda       ItemInfo item = ExtractItemInfoFromBuffer(extractor);
532796ac80bSJonas Devlieghere       return_thread_sp = std::make_shared<HistoryThread>(
53386df61ccSAlex Langford           *m_process, item.enqueuing_thread_id, item.enqueuing_callstack);
5342fd83355SJason Molenda       return_thread_sp->SetExtendedBacktraceToken(item.item_that_enqueued_this);
5352fd83355SJason Molenda       return_thread_sp->SetQueueName(item.enqueuing_queue_label.c_str());
5362fd83355SJason Molenda       return_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
537b9c1b51eSKate Stone       //            return_thread_sp->SetThreadName
538b9c1b51eSKate Stone       //            (item.enqueuing_thread_label.c_str());
5392fd83355SJason Molenda 
540da276f90SJason Molenda       m_page_to_free = ret.item_buffer_ptr;
541da276f90SJason Molenda       m_page_to_free_size = ret.item_buffer_size;
5422fd83355SJason Molenda     }
5432fd83355SJason Molenda   }
5442fd83355SJason Molenda   return return_thread_sp;
5452fd83355SJason Molenda }
5462fd83355SJason Molenda 
5472fd83355SJason Molenda ThreadSP
GetExtendedBacktraceForQueueItem(QueueItemSP queue_item_sp,ConstString type)548b9c1b51eSKate Stone SystemRuntimeMacOSX::GetExtendedBacktraceForQueueItem(QueueItemSP queue_item_sp,
549b9c1b51eSKate Stone                                                       ConstString type) {
5502fd83355SJason Molenda   ThreadSP extended_thread_sp;
55105cfdb0eSRaphael Isemann   if (type != "libdispatch")
5522fd83355SJason Molenda     return extended_thread_sp;
5532fd83355SJason Molenda 
554796ac80bSJonas Devlieghere   extended_thread_sp = std::make_shared<HistoryThread>(
555796ac80bSJonas Devlieghere       *m_process, queue_item_sp->GetEnqueueingThreadID(),
55686df61ccSAlex Langford       queue_item_sp->GetEnqueueingBacktrace());
557b9c1b51eSKate Stone   extended_thread_sp->SetExtendedBacktraceToken(
558b9c1b51eSKate Stone       queue_item_sp->GetItemThatEnqueuedThis());
5592fd83355SJason Molenda   extended_thread_sp->SetQueueName(queue_item_sp->GetQueueLabel().c_str());
5602fd83355SJason Molenda   extended_thread_sp->SetQueueID(queue_item_sp->GetEnqueueingQueueID());
561b9c1b51eSKate Stone   //    extended_thread_sp->SetThreadName
562b9c1b51eSKate Stone   //    (queue_item_sp->GetThreadLabel().c_str());
5632fd83355SJason Molenda 
5642fd83355SJason Molenda   return extended_thread_sp;
5652fd83355SJason Molenda }
5662fd83355SJason Molenda 
5672fd83355SJason Molenda /* Returns true if we were able to get the version / offset information
5682fd83355SJason Molenda  * out of libBacktraceRecording.  false means we were unable to retrieve
5692fd83355SJason Molenda  * this; the queue_info_version field will be 0.
5702fd83355SJason Molenda  */
571a7b5afa9SJason Molenda 
BacktraceRecordingHeadersInitialized()572b9c1b51eSKate Stone bool SystemRuntimeMacOSX::BacktraceRecordingHeadersInitialized() {
5732fd83355SJason Molenda   if (m_lib_backtrace_recording_info.queue_info_version != 0)
5742fd83355SJason Molenda     return true;
575a7b5afa9SJason Molenda 
5762fd83355SJason Molenda   addr_t queue_info_version_address = LLDB_INVALID_ADDRESS;
5772fd83355SJason Molenda   addr_t queue_info_data_offset_address = LLDB_INVALID_ADDRESS;
5782fd83355SJason Molenda   addr_t item_info_version_address = LLDB_INVALID_ADDRESS;
5792fd83355SJason Molenda   addr_t item_info_data_offset_address = LLDB_INVALID_ADDRESS;
5802fd83355SJason Molenda   Target &target = m_process->GetTarget();
5812fd83355SJason Molenda 
582b9c1b51eSKate Stone   static ConstString introspection_dispatch_queue_info_version(
583b9c1b51eSKate Stone       "__introspection_dispatch_queue_info_version");
584a7b5afa9SJason Molenda   SymbolContextList sc_list;
5851ad655e2SAdrian Prantl   m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
5861ad655e2SAdrian Prantl       introspection_dispatch_queue_info_version, eSymbolTypeData, sc_list);
5871ad655e2SAdrian Prantl   if (!sc_list.IsEmpty()) {
588a7b5afa9SJason Molenda     SymbolContext sc;
589a7b5afa9SJason Molenda     sc_list.GetContextAtIndex(0, sc);
590a7b5afa9SJason Molenda     AddressRange addr_range;
591a7b5afa9SJason Molenda     sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
592b9c1b51eSKate Stone     queue_info_version_address =
593b9c1b51eSKate Stone         addr_range.GetBaseAddress().GetLoadAddress(&target);
5942fd83355SJason Molenda   }
5952fd83355SJason Molenda   sc_list.Clear();
596a7b5afa9SJason Molenda 
597b9c1b51eSKate Stone   static ConstString introspection_dispatch_queue_info_data_offset(
598b9c1b51eSKate Stone       "__introspection_dispatch_queue_info_data_offset");
5991ad655e2SAdrian Prantl   m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
6001ad655e2SAdrian Prantl       introspection_dispatch_queue_info_data_offset, eSymbolTypeData, sc_list);
6011ad655e2SAdrian Prantl   if (!sc_list.IsEmpty()) {
6022fd83355SJason Molenda     SymbolContext sc;
6032fd83355SJason Molenda     sc_list.GetContextAtIndex(0, sc);
6042fd83355SJason Molenda     AddressRange addr_range;
6052fd83355SJason Molenda     sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
606b9c1b51eSKate Stone     queue_info_data_offset_address =
607b9c1b51eSKate Stone         addr_range.GetBaseAddress().GetLoadAddress(&target);
6082fd83355SJason Molenda   }
6092fd83355SJason Molenda   sc_list.Clear();
6102fd83355SJason Molenda 
611b9c1b51eSKate Stone   static ConstString introspection_dispatch_item_info_version(
612b9c1b51eSKate Stone       "__introspection_dispatch_item_info_version");
6131ad655e2SAdrian Prantl   m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
6141ad655e2SAdrian Prantl       introspection_dispatch_item_info_version, eSymbolTypeData, sc_list);
6151ad655e2SAdrian Prantl   if (!sc_list.IsEmpty()) {
6162fd83355SJason Molenda     SymbolContext sc;
6172fd83355SJason Molenda     sc_list.GetContextAtIndex(0, sc);
6182fd83355SJason Molenda     AddressRange addr_range;
6192fd83355SJason Molenda     sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
620b9c1b51eSKate Stone     item_info_version_address =
621b9c1b51eSKate Stone         addr_range.GetBaseAddress().GetLoadAddress(&target);
6222fd83355SJason Molenda   }
6232fd83355SJason Molenda   sc_list.Clear();
6242fd83355SJason Molenda 
625b9c1b51eSKate Stone   static ConstString introspection_dispatch_item_info_data_offset(
626b9c1b51eSKate Stone       "__introspection_dispatch_item_info_data_offset");
6271ad655e2SAdrian Prantl   m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
6281ad655e2SAdrian Prantl       introspection_dispatch_item_info_data_offset, eSymbolTypeData, sc_list);
6291ad655e2SAdrian Prantl   if (!sc_list.IsEmpty()) {
6302fd83355SJason Molenda     SymbolContext sc;
6312fd83355SJason Molenda     sc_list.GetContextAtIndex(0, sc);
6322fd83355SJason Molenda     AddressRange addr_range;
6332fd83355SJason Molenda     sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
634b9c1b51eSKate Stone     item_info_data_offset_address =
635b9c1b51eSKate Stone         addr_range.GetBaseAddress().GetLoadAddress(&target);
6362fd83355SJason Molenda   }
6372fd83355SJason Molenda 
638b9c1b51eSKate Stone   if (queue_info_version_address != LLDB_INVALID_ADDRESS &&
639b9c1b51eSKate Stone       queue_info_data_offset_address != LLDB_INVALID_ADDRESS &&
640b9c1b51eSKate Stone       item_info_version_address != LLDB_INVALID_ADDRESS &&
641b9c1b51eSKate Stone       item_info_data_offset_address != LLDB_INVALID_ADDRESS) {
64297206d57SZachary Turner     Status error;
643b9c1b51eSKate Stone     m_lib_backtrace_recording_info.queue_info_version =
644b9c1b51eSKate Stone         m_process->ReadUnsignedIntegerFromMemory(queue_info_version_address, 2,
645b9c1b51eSKate Stone                                                  0, error);
646b9c1b51eSKate Stone     if (error.Success()) {
647b9c1b51eSKate Stone       m_lib_backtrace_recording_info.queue_info_data_offset =
648b9c1b51eSKate Stone           m_process->ReadUnsignedIntegerFromMemory(
649b9c1b51eSKate Stone               queue_info_data_offset_address, 2, 0, error);
650b9c1b51eSKate Stone       if (error.Success()) {
651b9c1b51eSKate Stone         m_lib_backtrace_recording_info.item_info_version =
652b9c1b51eSKate Stone             m_process->ReadUnsignedIntegerFromMemory(item_info_version_address,
653b9c1b51eSKate Stone                                                      2, 0, error);
654b9c1b51eSKate Stone         if (error.Success()) {
655b9c1b51eSKate Stone           m_lib_backtrace_recording_info.item_info_data_offset =
656b9c1b51eSKate Stone               m_process->ReadUnsignedIntegerFromMemory(
657b9c1b51eSKate Stone                   item_info_data_offset_address, 2, 0, error);
658b9c1b51eSKate Stone           if (!error.Success()) {
6592fd83355SJason Molenda             m_lib_backtrace_recording_info.queue_info_version = 0;
6602fd83355SJason Molenda           }
661b9c1b51eSKate Stone         } else {
6622fd83355SJason Molenda           m_lib_backtrace_recording_info.queue_info_version = 0;
663a6e9130dSJason Molenda         }
664b9c1b51eSKate Stone       } else {
6652fd83355SJason Molenda         m_lib_backtrace_recording_info.queue_info_version = 0;
666a7b5afa9SJason Molenda       }
667a7b5afa9SJason Molenda     }
668a7b5afa9SJason Molenda   }
669a7b5afa9SJason Molenda 
6702fd83355SJason Molenda   return m_lib_backtrace_recording_info.queue_info_version != 0;
671a7b5afa9SJason Molenda }
672a7b5afa9SJason Molenda 
673a7b5afa9SJason Molenda const std::vector<ConstString> &
GetExtendedBacktraceTypes()674b9c1b51eSKate Stone SystemRuntimeMacOSX::GetExtendedBacktraceTypes() {
675b9c1b51eSKate Stone   if (m_types.size() == 0) {
676a7b5afa9SJason Molenda     m_types.push_back(ConstString("libdispatch"));
6772fd83355SJason Molenda     // We could have pthread as another type in the future if we have a way of
6782fd83355SJason Molenda     // gathering that information & it's useful to distinguish between them.
679a7b5afa9SJason Molenda   }
680a7b5afa9SJason Molenda   return m_types;
681a7b5afa9SJason Molenda }
682a7b5afa9SJason Molenda 
PopulateQueueList(lldb_private::QueueList & queue_list)683b9c1b51eSKate Stone void SystemRuntimeMacOSX::PopulateQueueList(
684b9c1b51eSKate Stone     lldb_private::QueueList &queue_list) {
685b9c1b51eSKate Stone   if (BacktraceRecordingHeadersInitialized()) {
6862fd83355SJason Molenda     AppleGetQueuesHandler::GetQueuesReturnInfo queue_info_pointer;
687b9c1b51eSKate Stone     ThreadSP cur_thread_sp(
688b9c1b51eSKate Stone         m_process->GetThreadList().GetExpressionExecutionThread());
689b9c1b51eSKate Stone     if (cur_thread_sp) {
69097206d57SZachary Turner       Status error;
691b9c1b51eSKate Stone       queue_info_pointer = m_get_queues_handler.GetCurrentQueues(
692b9c1b51eSKate Stone           *cur_thread_sp.get(), m_page_to_free, m_page_to_free_size, error);
6932fd83355SJason Molenda       m_page_to_free = LLDB_INVALID_ADDRESS;
6942fd83355SJason Molenda       m_page_to_free_size = 0;
695b9c1b51eSKate Stone       if (error.Success()) {
6965e8dce4dSJason Molenda 
697b9c1b51eSKate Stone         if (queue_info_pointer.count > 0 &&
698b9c1b51eSKate Stone             queue_info_pointer.queues_buffer_size > 0 &&
699b9c1b51eSKate Stone             queue_info_pointer.queues_buffer_ptr != 0 &&
700b9c1b51eSKate Stone             queue_info_pointer.queues_buffer_ptr != LLDB_INVALID_ADDRESS) {
701b9c1b51eSKate Stone           PopulateQueuesUsingLibBTR(queue_info_pointer.queues_buffer_ptr,
702b9c1b51eSKate Stone                                     queue_info_pointer.queues_buffer_size,
703b9c1b51eSKate Stone                                     queue_info_pointer.count, queue_list);
7042fd83355SJason Molenda         }
7052fd83355SJason Molenda       }
7062fd83355SJason Molenda     }
7072fd83355SJason Molenda   }
708b9ffa98cSJason Molenda 
709b9c1b51eSKate Stone   // We either didn't have libBacktraceRecording (and need to create the queues
71005097246SAdrian Prantl   // list based on threads) or we did get the queues list from
71105097246SAdrian Prantl   // libBacktraceRecording but some special queues may not be included in its
71205097246SAdrian Prantl   // information.  This is needed because libBacktraceRecording will only list
71305097246SAdrian Prantl   // queues with pending or running items by default - but the magic com.apple
71405097246SAdrian Prantl   // .main-thread queue on thread 1 is always around.
715b9ffa98cSJason Molenda 
716b9c1b51eSKate Stone   for (ThreadSP thread_sp : m_process->Threads()) {
717b9c1b51eSKate Stone     if (thread_sp->GetAssociatedWithLibdispatchQueue() != eLazyBoolNo) {
718b9c1b51eSKate Stone       if (thread_sp->GetQueueID() != LLDB_INVALID_QUEUE_ID) {
719248a1305SKonrad Kleine         if (queue_list.FindQueueByID(thread_sp->GetQueueID()).get() ==
720248a1305SKonrad Kleine             nullptr) {
721b9c1b51eSKate Stone           QueueSP queue_sp(new Queue(m_process->shared_from_this(),
722b9c1b51eSKate Stone                                      thread_sp->GetQueueID(),
723b9c1b51eSKate Stone                                      thread_sp->GetQueueName()));
724b9c1b51eSKate Stone           if (thread_sp->ThreadHasQueueInformation()) {
72577f89352SJason Molenda             queue_sp->SetKind(thread_sp->GetQueueKind());
726b9c1b51eSKate Stone             queue_sp->SetLibdispatchQueueAddress(
727b9c1b51eSKate Stone                 thread_sp->GetQueueLibdispatchQueueAddress());
72877f89352SJason Molenda             queue_list.AddQueue(queue_sp);
729b9c1b51eSKate Stone           } else {
730b9c1b51eSKate Stone             queue_sp->SetKind(
731b9c1b51eSKate Stone                 GetQueueKind(thread_sp->GetQueueLibdispatchQueueAddress()));
732b9c1b51eSKate Stone             queue_sp->SetLibdispatchQueueAddress(
733b9c1b51eSKate Stone                 thread_sp->GetQueueLibdispatchQueueAddress());
734b9ffa98cSJason Molenda             queue_list.AddQueue(queue_sp);
735b9ffa98cSJason Molenda           }
736b9ffa98cSJason Molenda         }
737b9ffa98cSJason Molenda       }
7382fd83355SJason Molenda     }
73977f89352SJason Molenda   }
74077f89352SJason Molenda }
7412fd83355SJason Molenda 
742b9c1b51eSKate Stone // Returns either an array of introspection_dispatch_item_info_ref's for the
74305097246SAdrian Prantl // pending items on a queue or an array introspection_dispatch_item_info_ref's
74405097246SAdrian Prantl // and code addresses for the pending items on a queue.  The information about
74505097246SAdrian Prantl // each of these pending items then needs to be fetched individually by passing
74605097246SAdrian Prantl // the ref to libBacktraceRecording.
74737e9b5abSJason Molenda 
74837e9b5abSJason Molenda SystemRuntimeMacOSX::PendingItemsForQueue
GetPendingItemRefsForQueue(lldb::addr_t queue)749b9c1b51eSKate Stone SystemRuntimeMacOSX::GetPendingItemRefsForQueue(lldb::addr_t queue) {
750*4871dfc6SSlava Gurevich   PendingItemsForQueue pending_item_refs = {};
75137e9b5abSJason Molenda   AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer;
752b9c1b51eSKate Stone   ThreadSP cur_thread_sp(
753b9c1b51eSKate Stone       m_process->GetThreadList().GetExpressionExecutionThread());
754b9c1b51eSKate Stone   if (cur_thread_sp) {
75597206d57SZachary Turner     Status error;
756b9c1b51eSKate Stone     pending_items_pointer = m_get_pending_items_handler.GetPendingItems(
757b9c1b51eSKate Stone         *cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size,
758b9c1b51eSKate Stone         error);
75937e9b5abSJason Molenda     m_page_to_free = LLDB_INVALID_ADDRESS;
76037e9b5abSJason Molenda     m_page_to_free_size = 0;
761b9c1b51eSKate Stone     if (error.Success()) {
762b9c1b51eSKate Stone       if (pending_items_pointer.count > 0 &&
763b9c1b51eSKate Stone           pending_items_pointer.items_buffer_size > 0 &&
764b9c1b51eSKate Stone           pending_items_pointer.items_buffer_ptr != 0 &&
765b9c1b51eSKate Stone           pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS) {
76637e9b5abSJason Molenda         DataBufferHeap data(pending_items_pointer.items_buffer_size, 0);
767b9c1b51eSKate Stone         if (m_process->ReadMemory(
768b9c1b51eSKate Stone                 pending_items_pointer.items_buffer_ptr, data.GetBytes(),
769b9c1b51eSKate Stone                 pending_items_pointer.items_buffer_size, error)) {
770b9c1b51eSKate Stone           DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
771b9c1b51eSKate Stone                                   m_process->GetByteOrder(),
772b9c1b51eSKate Stone                                   m_process->GetAddressByteSize());
77337e9b5abSJason Molenda 
77437e9b5abSJason Molenda           // We either have an array of
77537e9b5abSJason Molenda           //    void* item_ref
77637e9b5abSJason Molenda           // (old style) or we have a structure returned which looks like
77737e9b5abSJason Molenda           //
77837e9b5abSJason Molenda           // struct introspection_dispatch_pending_item_info_s {
77937e9b5abSJason Molenda           //   void *item_ref;
78037e9b5abSJason Molenda           //   void *function_or_block;
78137e9b5abSJason Molenda           // };
78237e9b5abSJason Molenda           //
78337e9b5abSJason Molenda           // struct introspection_dispatch_pending_items_array_s {
78437e9b5abSJason Molenda           //   uint32_t version;
78537e9b5abSJason Molenda           //   uint32_t size_of_item_info;
78637e9b5abSJason Molenda           //   introspection_dispatch_pending_item_info_s items[];
78737e9b5abSJason Molenda           //   }
78837e9b5abSJason Molenda 
78937e9b5abSJason Molenda           offset_t offset = 0;
79037e9b5abSJason Molenda           int i = 0;
79137e9b5abSJason Molenda           uint32_t version = extractor.GetU32(&offset);
792b9c1b51eSKate Stone           if (version == 1) {
79337e9b5abSJason Molenda             pending_item_refs.new_style = true;
79437e9b5abSJason Molenda             uint32_t item_size = extractor.GetU32(&offset);
79537e9b5abSJason Molenda             uint32_t start_of_array_offset = offset;
7963985c8c6SSaleem Abdulrasool             while (offset < pending_items_pointer.items_buffer_size &&
797b9c1b51eSKate Stone                    static_cast<size_t>(i) < pending_items_pointer.count) {
79837e9b5abSJason Molenda               offset = start_of_array_offset + (i * item_size);
79937e9b5abSJason Molenda               ItemRefAndCodeAddress item;
8000863f675SPavel Labath               item.item_ref = extractor.GetAddress(&offset);
8010863f675SPavel Labath               item.code_address = extractor.GetAddress(&offset);
80237e9b5abSJason Molenda               pending_item_refs.item_refs_and_code_addresses.push_back(item);
80337e9b5abSJason Molenda               i++;
80437e9b5abSJason Molenda             }
805b9c1b51eSKate Stone           } else {
80637e9b5abSJason Molenda             offset = 0;
80737e9b5abSJason Molenda             pending_item_refs.new_style = false;
8083985c8c6SSaleem Abdulrasool             while (offset < pending_items_pointer.items_buffer_size &&
809b9c1b51eSKate Stone                    static_cast<size_t>(i) < pending_items_pointer.count) {
81037e9b5abSJason Molenda               ItemRefAndCodeAddress item;
8110863f675SPavel Labath               item.item_ref = extractor.GetAddress(&offset);
81237e9b5abSJason Molenda               item.code_address = LLDB_INVALID_ADDRESS;
81337e9b5abSJason Molenda               pending_item_refs.item_refs_and_code_addresses.push_back(item);
81437e9b5abSJason Molenda               i++;
81537e9b5abSJason Molenda             }
81637e9b5abSJason Molenda           }
81737e9b5abSJason Molenda         }
81837e9b5abSJason Molenda         m_page_to_free = pending_items_pointer.items_buffer_ptr;
81937e9b5abSJason Molenda         m_page_to_free_size = pending_items_pointer.items_buffer_size;
82037e9b5abSJason Molenda       }
82137e9b5abSJason Molenda     }
82237e9b5abSJason Molenda   }
82337e9b5abSJason Molenda   return pending_item_refs;
82437e9b5abSJason Molenda }
82537e9b5abSJason Molenda 
PopulatePendingItemsForQueue(Queue * queue)826b9c1b51eSKate Stone void SystemRuntimeMacOSX::PopulatePendingItemsForQueue(Queue *queue) {
827b9c1b51eSKate Stone   if (BacktraceRecordingHeadersInitialized()) {
828b9c1b51eSKate Stone     PendingItemsForQueue pending_item_refs =
829b9c1b51eSKate Stone         GetPendingItemRefsForQueue(queue->GetLibdispatchQueueAddress());
830b9c1b51eSKate Stone     for (ItemRefAndCodeAddress pending_item :
831b9c1b51eSKate Stone          pending_item_refs.item_refs_and_code_addresses) {
832e32cd191SJason Molenda       Address addr;
833b9c1b51eSKate Stone       m_process->GetTarget().ResolveLoadAddress(pending_item.code_address,
834b9c1b51eSKate Stone                                                 addr);
835b9c1b51eSKate Stone       QueueItemSP queue_item_sp(new QueueItem(queue->shared_from_this(),
836b9c1b51eSKate Stone                                               m_process->shared_from_this(),
837b9c1b51eSKate Stone                                               pending_item.item_ref, addr));
838e32cd191SJason Molenda       queue->PushPendingQueueItem(queue_item_sp);
839e32cd191SJason Molenda     }
840e32cd191SJason Molenda   }
841e32cd191SJason Molenda }
842e32cd191SJason Molenda 
CompleteQueueItem(QueueItem * queue_item,addr_t item_ref)843b9c1b51eSKate Stone void SystemRuntimeMacOSX::CompleteQueueItem(QueueItem *queue_item,
844b9c1b51eSKate Stone                                             addr_t item_ref) {
8452fd83355SJason Molenda   AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
846e32cd191SJason Molenda 
847b9c1b51eSKate Stone   ThreadSP cur_thread_sp(
848b9c1b51eSKate Stone       m_process->GetThreadList().GetExpressionExecutionThread());
84997206d57SZachary Turner   Status error;
850b9c1b51eSKate Stone   ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
851b9c1b51eSKate Stone                                             m_page_to_free, m_page_to_free_size,
852b9c1b51eSKate Stone                                             error);
8532a6c252dSJason Molenda   m_page_to_free = LLDB_INVALID_ADDRESS;
8542a6c252dSJason Molenda   m_page_to_free_size = 0;
855b9c1b51eSKate Stone   if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
856b9c1b51eSKate Stone       ret.item_buffer_size > 0) {
8572fd83355SJason Molenda     DataBufferHeap data(ret.item_buffer_size, 0);
858b9c1b51eSKate Stone     if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
859b9c1b51eSKate Stone                               ret.item_buffer_size, error) &&
860b9c1b51eSKate Stone         error.Success()) {
861b9c1b51eSKate Stone       DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
862b9c1b51eSKate Stone                               m_process->GetByteOrder(),
863b9c1b51eSKate Stone                               m_process->GetAddressByteSize());
8642fd83355SJason Molenda       ItemInfo item = ExtractItemInfoFromBuffer(extractor);
865e32cd191SJason Molenda       queue_item->SetItemThatEnqueuedThis(item.item_that_enqueued_this);
866e32cd191SJason Molenda       queue_item->SetEnqueueingThreadID(item.enqueuing_thread_id);
867e32cd191SJason Molenda       queue_item->SetEnqueueingQueueID(item.enqueuing_queue_serialnum);
868e32cd191SJason Molenda       queue_item->SetStopID(item.stop_id);
869e32cd191SJason Molenda       queue_item->SetEnqueueingBacktrace(item.enqueuing_callstack);
870e32cd191SJason Molenda       queue_item->SetThreadLabel(item.enqueuing_thread_label);
871e32cd191SJason Molenda       queue_item->SetQueueLabel(item.enqueuing_queue_label);
872e32cd191SJason Molenda       queue_item->SetTargetQueueLabel(item.target_queue_label);
8732fd83355SJason Molenda     }
8740d6a1ff2SJason Molenda     m_page_to_free = ret.item_buffer_ptr;
8750d6a1ff2SJason Molenda     m_page_to_free_size = ret.item_buffer_size;
8762fd83355SJason Molenda   }
8772fd83355SJason Molenda }
8782fd83355SJason Molenda 
PopulateQueuesUsingLibBTR(lldb::addr_t queues_buffer,uint64_t queues_buffer_size,uint64_t count,lldb_private::QueueList & queue_list)879b9c1b51eSKate Stone void SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR(
880b9c1b51eSKate Stone     lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count,
881b9c1b51eSKate Stone     lldb_private::QueueList &queue_list) {
88297206d57SZachary Turner   Status error;
8832fd83355SJason Molenda   DataBufferHeap data(queues_buffer_size, 0);
884a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::SystemRuntime);
885b9c1b51eSKate Stone   if (m_process->ReadMemory(queues_buffer, data.GetBytes(), queues_buffer_size,
886b9c1b51eSKate Stone                             error) == queues_buffer_size &&
887b9c1b51eSKate Stone       error.Success()) {
888b9c1b51eSKate Stone     // We've read the information out of inferior memory; free it on the next
889b9c1b51eSKate Stone     // call we make
8902fd83355SJason Molenda     m_page_to_free = queues_buffer;
8912fd83355SJason Molenda     m_page_to_free_size = queues_buffer_size;
8922fd83355SJason Molenda 
893b9c1b51eSKate Stone     DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
894b9c1b51eSKate Stone                             m_process->GetByteOrder(),
895b9c1b51eSKate Stone                             m_process->GetAddressByteSize());
8962fd83355SJason Molenda     offset_t offset = 0;
8972fd83355SJason Molenda     uint64_t queues_read = 0;
8982fd83355SJason Molenda 
89905097246SAdrian Prantl     // The information about the queues is stored in this format (v1): typedef
90005097246SAdrian Prantl     // struct introspection_dispatch_queue_info_s {
9012fd83355SJason Molenda     //     uint32_t offset_to_next;
9022fd83355SJason Molenda     //     dispatch_queue_t queue;
903b9c1b51eSKate Stone     //     uint64_t serialnum;     // queue's serialnum in the process, as
904b9c1b51eSKate Stone     //     provided by libdispatch
9052fd83355SJason Molenda     //     uint32_t running_work_items_count;
9062fd83355SJason Molenda     //     uint32_t pending_work_items_count;
9072fd83355SJason Molenda     //
9082fd83355SJason Molenda     //     char data[];     // Starting here, we have variable-length data:
9092fd83355SJason Molenda     //     // char queue_label[];
9102fd83355SJason Molenda     // } introspection_dispatch_queue_info_s;
9112fd83355SJason Molenda 
912b9c1b51eSKate Stone     while (queues_read < count && offset < queues_buffer_size) {
9132fd83355SJason Molenda       offset_t start_of_this_item = offset;
9142fd83355SJason Molenda 
9152fd83355SJason Molenda       uint32_t offset_to_next = extractor.GetU32(&offset);
916d84f606dSJason Molenda 
917d84f606dSJason Molenda       offset += 4; // Skip over the 4 bytes of reserved space
9180863f675SPavel Labath       addr_t queue = extractor.GetAddress(&offset);
9192fd83355SJason Molenda       uint64_t serialnum = extractor.GetU64(&offset);
9202fd83355SJason Molenda       uint32_t running_work_items_count = extractor.GetU32(&offset);
9212fd83355SJason Molenda       uint32_t pending_work_items_count = extractor.GetU32(&offset);
9222fd83355SJason Molenda 
9232fd83355SJason Molenda       // Read the first field of the variable length data
924b9c1b51eSKate Stone       offset = start_of_this_item +
925b9c1b51eSKate Stone                m_lib_backtrace_recording_info.queue_info_data_offset;
9262fd83355SJason Molenda       const char *queue_label = extractor.GetCStr(&offset);
927248a1305SKonrad Kleine       if (queue_label == nullptr)
9282fd83355SJason Molenda         queue_label = "";
9292fd83355SJason Molenda 
9302fd83355SJason Molenda       offset_t start_of_next_item = start_of_this_item + offset_to_next;
9312fd83355SJason Molenda       offset = start_of_next_item;
9322fd83355SJason Molenda 
93363e5fb76SJonas Devlieghere       LLDB_LOGF(log,
93463e5fb76SJonas Devlieghere                 "SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR added "
935b9c1b51eSKate Stone                 "queue with dispatch_queue_t 0x%" PRIx64
936b9c1b51eSKate Stone                 ", serial number 0x%" PRIx64
937b9c1b51eSKate Stone                 ", running items %d, pending items %d, name '%s'",
938b9c1b51eSKate Stone                 queue, serialnum, running_work_items_count,
939b9c1b51eSKate Stone                 pending_work_items_count, queue_label);
940d84f606dSJason Molenda 
941b9c1b51eSKate Stone       QueueSP queue_sp(
942b9c1b51eSKate Stone           new Queue(m_process->shared_from_this(), serialnum, queue_label));
9432fd83355SJason Molenda       queue_sp->SetNumRunningWorkItems(running_work_items_count);
9442fd83355SJason Molenda       queue_sp->SetNumPendingWorkItems(pending_work_items_count);
9452fd83355SJason Molenda       queue_sp->SetLibdispatchQueueAddress(queue);
946aac16e0fSJason Molenda       queue_sp->SetKind(GetQueueKind(queue));
9472fd83355SJason Molenda       queue_list.AddQueue(queue_sp);
9482fd83355SJason Molenda       queues_read++;
9492fd83355SJason Molenda     }
9502fd83355SJason Molenda   }
9512fd83355SJason Molenda }
9522fd83355SJason Molenda 
ExtractItemInfoFromBuffer(lldb_private::DataExtractor & extractor)953b9c1b51eSKate Stone SystemRuntimeMacOSX::ItemInfo SystemRuntimeMacOSX::ExtractItemInfoFromBuffer(
954b9c1b51eSKate Stone     lldb_private::DataExtractor &extractor) {
9552fd83355SJason Molenda   ItemInfo item;
9562fd83355SJason Molenda 
9572fd83355SJason Molenda   offset_t offset = 0;
9582fd83355SJason Molenda 
9590863f675SPavel Labath   item.item_that_enqueued_this = extractor.GetAddress(&offset);
9600863f675SPavel Labath   item.function_or_block = extractor.GetAddress(&offset);
9612fd83355SJason Molenda   item.enqueuing_thread_id = extractor.GetU64(&offset);
9622fd83355SJason Molenda   item.enqueuing_queue_serialnum = extractor.GetU64(&offset);
9632fd83355SJason Molenda   item.target_queue_serialnum = extractor.GetU64(&offset);
9642fd83355SJason Molenda   item.enqueuing_callstack_frame_count = extractor.GetU32(&offset);
9652fd83355SJason Molenda   item.stop_id = extractor.GetU32(&offset);
9662fd83355SJason Molenda 
9672fd83355SJason Molenda   offset = m_lib_backtrace_recording_info.item_info_data_offset;
9682fd83355SJason Molenda 
969b9c1b51eSKate Stone   for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++) {
9700863f675SPavel Labath     item.enqueuing_callstack.push_back(extractor.GetAddress(&offset));
9712fd83355SJason Molenda   }
9722fd83355SJason Molenda   item.enqueuing_thread_label = extractor.GetCStr(&offset);
9732fd83355SJason Molenda   item.enqueuing_queue_label = extractor.GetCStr(&offset);
9742fd83355SJason Molenda   item.target_queue_label = extractor.GetCStr(&offset);
9752fd83355SJason Molenda 
9762fd83355SJason Molenda   return item;
9772fd83355SJason Molenda }
978a7b5afa9SJason Molenda 
Initialize()979b9c1b51eSKate Stone void SystemRuntimeMacOSX::Initialize() {
98049481b53SPavel Labath   PluginManager::RegisterPlugin(
98149481b53SPavel Labath       GetPluginNameStatic(),
98249481b53SPavel Labath       "System runtime plugin for Mac OS X native libraries.", CreateInstance);
983a7b5afa9SJason Molenda }
984a7b5afa9SJason Molenda 
Terminate()985b9c1b51eSKate Stone void SystemRuntimeMacOSX::Terminate() {
986a7b5afa9SJason Molenda   PluginManager::UnregisterPlugin(CreateInstance);
987a7b5afa9SJason Molenda }
988