//===-- SystemRuntimeMacOSX.cpp ---------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Target/Queue.h"
#include "lldb/Target/QueueList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/ProcessStructReader.h"

#include "SystemRuntimeMacOSX.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// Create an instance of this class. This function is filled into
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
SystemRuntime *
SystemRuntimeMacOSX::CreateInstance (Process* process)
{
    bool create = false;
    if (!create)
    {
        create = true;
        Module* exe_module = process->GetTarget().GetExecutableModulePointer();
        if (exe_module)
        {
            ObjectFile *object_file = exe_module->GetObjectFile();
            if (object_file)
            {
                create = (object_file->GetStrata() == ObjectFile::eStrataUser);
            }
        }
        
        if (create)
        {
            const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
            switch (triple_ref.getOS())
            {
                case llvm::Triple::Darwin:
                case llvm::Triple::MacOSX:
                case llvm::Triple::IOS:
                case llvm::Triple::TvOS:
                case llvm::Triple::WatchOS:
                    create = triple_ref.getVendor() == llvm::Triple::Apple;
                    break;
                default:
                    create = false;
                    break;
            }
        }
    }
    
    if (create)
        return new SystemRuntimeMacOSX (process);
    return NULL;
}

//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
SystemRuntimeMacOSX::SystemRuntimeMacOSX(Process *process)
    : SystemRuntime(process),
      m_break_id(LLDB_INVALID_BREAK_ID),
      m_mutex(),
      m_get_queues_handler(process),
      m_get_pending_items_handler(process),
      m_get_item_info_handler(process),
      m_get_thread_item_info_handler(process),
      m_page_to_free(LLDB_INVALID_ADDRESS),
      m_page_to_free_size(0),
      m_lib_backtrace_recording_info(),
      m_dispatch_queue_offsets_addr(LLDB_INVALID_ADDRESS),
      m_libdispatch_offsets(),
      m_libpthread_layout_offsets_addr(LLDB_INVALID_ADDRESS),
      m_libpthread_offsets(),
      m_dispatch_tsd_indexes_addr(LLDB_INVALID_ADDRESS),
      m_libdispatch_tsd_indexes(),
      m_dispatch_voucher_offsets_addr(LLDB_INVALID_ADDRESS),
      m_libdispatch_voucher_offsets()
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
SystemRuntimeMacOSX::~SystemRuntimeMacOSX()
{
    Clear (true);
}

void
SystemRuntimeMacOSX::Detach ()
{
        m_get_queues_handler.Detach();
        m_get_pending_items_handler.Detach();
        m_get_item_info_handler.Detach();
        m_get_thread_item_info_handler.Detach();
}

//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
void
SystemRuntimeMacOSX::Clear (bool clear_process)
{
    std::lock_guard<std::recursive_mutex> guard(m_mutex);

    if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
        m_process->ClearBreakpointSiteByID(m_break_id);

    if (clear_process)
        m_process = NULL;
    m_break_id = LLDB_INVALID_BREAK_ID;
}


std::string
SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress (addr_t dispatch_qaddr)
{
    std::string dispatch_queue_name;
    if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
        return "";

    ReadLibdispatchOffsets ();
    if (m_libdispatch_offsets.IsValid ())
    {
        // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a thread -
        // deref it to get the address of the dispatch_queue_t structure for this thread's 
        // queue.
        Error error;
        addr_t dispatch_queue_addr = m_process->ReadPointerFromMemory (dispatch_qaddr, error);
        if (error.Success())
        {
            if (m_libdispatch_offsets.dqo_version >= 4)
            {
                // libdispatch versions 4+, pointer to dispatch name is in the
                // queue structure.
                addr_t pointer_to_label_address = dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
                addr_t label_addr = m_process->ReadPointerFromMemory (pointer_to_label_address, error);
                if (error.Success())
                {
                    m_process->ReadCStringFromMemory (label_addr, dispatch_queue_name, error);
                }
            }
            else
            {
                // libdispatch versions 1-3, dispatch name is a fixed width char array
                // in the queue structure.
                addr_t label_addr = dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
                dispatch_queue_name.resize (m_libdispatch_offsets.dqo_label_size, '\0');
                size_t bytes_read = m_process->ReadMemory (label_addr, &dispatch_queue_name[0], m_libdispatch_offsets.dqo_label_size, error);
                if (bytes_read < m_libdispatch_offsets.dqo_label_size)
                    dispatch_queue_name.erase (bytes_read);
            }
        }
    }
    return dispatch_queue_name;
}

lldb::addr_t
SystemRuntimeMacOSX::GetLibdispatchQueueAddressFromThreadQAddress (addr_t dispatch_qaddr)
{
    addr_t libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
    Error error;
    libdispatch_queue_t_address = m_process->ReadPointerFromMemory (dispatch_qaddr, error);
    if (!error.Success())
    {
        libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
    }
    return libdispatch_queue_t_address;
}

lldb::QueueKind
SystemRuntimeMacOSX::GetQueueKind (addr_t dispatch_queue_addr)
{
    if (dispatch_queue_addr == LLDB_INVALID_ADDRESS || dispatch_queue_addr == 0)
      return eQueueKindUnknown;

    QueueKind kind = eQueueKindUnknown;
    ReadLibdispatchOffsets ();
    if (m_libdispatch_offsets.IsValid () && m_libdispatch_offsets.dqo_version >= 4)
    {
        Error error;
        uint64_t width = m_process->ReadUnsignedIntegerFromMemory (dispatch_queue_addr + m_libdispatch_offsets.dqo_width, m_libdispatch_offsets.dqo_width_size, 0, error);
        if (error.Success())
        {
            if (width == 1)
            {
                kind = eQueueKindSerial;
            }
            if (width > 1)
            {
                kind = eQueueKindConcurrent;
            }
        }
    }
    return kind;
}

void
SystemRuntimeMacOSX::AddThreadExtendedInfoPacketHints (lldb_private::StructuredData::ObjectSP dict_sp)
{
    StructuredData::Dictionary *dict = dict_sp->GetAsDictionary();
    if (dict)
    {
        ReadLibpthreadOffsets();
        if (m_libpthread_offsets.IsValid())
        {
            dict->AddIntegerItem ("plo_pthread_tsd_base_offset", m_libpthread_offsets.plo_pthread_tsd_base_offset);
            dict->AddIntegerItem ("plo_pthread_tsd_base_address_offset", m_libpthread_offsets.plo_pthread_tsd_base_address_offset);
            dict->AddIntegerItem ("plo_pthread_tsd_entry_size", m_libpthread_offsets.plo_pthread_tsd_entry_size);
        }
    
        ReadLibdispatchTSDIndexes ();
        if (m_libdispatch_tsd_indexes.IsValid())
        {
            dict->AddIntegerItem ("dti_queue_index", m_libdispatch_tsd_indexes.dti_queue_index);
            dict->AddIntegerItem ("dti_voucher_index", m_libdispatch_tsd_indexes.dti_voucher_index);
            dict->AddIntegerItem ("dti_qos_class_index", m_libdispatch_tsd_indexes.dti_qos_class_index);
        }
    }
}

bool
SystemRuntimeMacOSX::SafeToCallFunctionsOnThisThread (ThreadSP thread_sp)
{
    if (thread_sp && thread_sp->GetStackFrameCount() > 0 && thread_sp->GetFrameWithConcreteFrameIndex(0))
    {
        const SymbolContext sym_ctx (thread_sp->GetFrameWithConcreteFrameIndex(0)->GetSymbolContext (eSymbolContextSymbol));
        static ConstString g_select_symbol ("__select");
        if (sym_ctx.GetFunctionName() == g_select_symbol)
        {
            return false;
        }
    }
    return true;
}

lldb::queue_id_t
SystemRuntimeMacOSX::GetQueueIDFromThreadQAddress (lldb::addr_t dispatch_qaddr)
{
    queue_id_t queue_id = LLDB_INVALID_QUEUE_ID;

    if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
        return queue_id;

    ReadLibdispatchOffsets ();
    if (m_libdispatch_offsets.IsValid ())
    {
        // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a thread -
        // deref it to get the address of the dispatch_queue_t structure for this thread's 
        // queue.
        Error error;
        uint64_t dispatch_queue_addr = m_process->ReadPointerFromMemory (dispatch_qaddr, error);
        if (error.Success())
        {
            addr_t serialnum_address = dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
            queue_id_t serialnum = m_process->ReadUnsignedIntegerFromMemory (serialnum_address, m_libdispatch_offsets.dqo_serialnum_size, LLDB_INVALID_QUEUE_ID, error);
            if (error.Success())
            {
                queue_id = serialnum;
            }
        }
    }

    return queue_id;
}


void
SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress ()
{
    if (m_dispatch_queue_offsets_addr != LLDB_INVALID_ADDRESS)
        return;

    static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets");
    const Symbol *dispatch_queue_offsets_symbol = NULL;

    // libdispatch symbols were in libSystem.B.dylib up through Mac OS X 10.6 ("Snow Leopard")
    ModuleSpec libSystem_module_spec (FileSpec("libSystem.B.dylib", false));
    ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule (libSystem_module_spec));
    if (module_sp)
        dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
    
    // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion") and later
    if (dispatch_queue_offsets_symbol == NULL)
    {
        ModuleSpec libdispatch_module_spec (FileSpec("libdispatch.dylib", false));
        module_sp = m_process->GetTarget().GetImages().FindFirstModule (libdispatch_module_spec);
        if (module_sp)
            dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
    }
    if (dispatch_queue_offsets_symbol)
        m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
}

void
SystemRuntimeMacOSX::ReadLibdispatchOffsets ()
{
    if (m_libdispatch_offsets.IsValid())
        return;

    ReadLibdispatchOffsetsAddress ();

    uint8_t memory_buffer[sizeof (struct LibdispatchOffsets)];
    DataExtractor data (memory_buffer, 
                        sizeof(memory_buffer), 
                        m_process->GetByteOrder(), 
                        m_process->GetAddressByteSize());

    Error error;
    if (m_process->ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(memory_buffer), error) == sizeof(memory_buffer))
    {
        lldb::offset_t data_offset = 0;

        // The struct LibdispatchOffsets is a series of uint16_t's - extract them all
        // in one big go.
        data.GetU16 (&data_offset, &m_libdispatch_offsets.dqo_version, sizeof (struct LibdispatchOffsets) / sizeof (uint16_t));
    }
}

void
SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress ()
{
    if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
        return;

    static ConstString g_libpthread_layout_offsets_symbol_name ("pthread_layout_offsets");
    const Symbol *libpthread_layout_offsets_symbol = NULL;

    ModuleSpec libpthread_module_spec (FileSpec("libsystem_pthread.dylib", false));
    ModuleSP module_sp (m_process->GetTarget().GetImages().FindFirstModule (libpthread_module_spec));
    if (module_sp)
    {
        libpthread_layout_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType 
                                                           (g_libpthread_layout_offsets_symbol_name, eSymbolTypeData);
        if (libpthread_layout_offsets_symbol)
        {
            m_libpthread_layout_offsets_addr = libpthread_layout_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
        }
    }
}

void
SystemRuntimeMacOSX::ReadLibpthreadOffsets ()
{
    if (m_libpthread_offsets.IsValid())
        return;

    ReadLibpthreadOffsetsAddress ();

    if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
    {
        uint8_t memory_buffer[sizeof (struct LibpthreadOffsets)];
        DataExtractor data (memory_buffer, 
                            sizeof(memory_buffer), 
                            m_process->GetByteOrder(), 
                            m_process->GetAddressByteSize());
        Error error;
        if (m_process->ReadMemory (m_libpthread_layout_offsets_addr, memory_buffer, sizeof(memory_buffer), error) == sizeof(memory_buffer))
        {
            lldb::offset_t data_offset = 0;
    
            // The struct LibpthreadOffsets is a series of uint16_t's - extract them all
            // in one big go.
            data.GetU16 (&data_offset, &m_libpthread_offsets.plo_version, sizeof (struct LibpthreadOffsets) / sizeof (uint16_t));
        }
    }
}

void
SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress ()
{
    if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
        return;

    static ConstString g_libdispatch_tsd_indexes_symbol_name ("dispatch_tsd_indexes");
    const Symbol *libdispatch_tsd_indexes_symbol = NULL;

    ModuleSpec libpthread_module_spec (FileSpec("libdispatch.dylib", false));
    ModuleSP module_sp (m_process->GetTarget().GetImages().FindFirstModule (libpthread_module_spec));
    if (module_sp)
    {
        libdispatch_tsd_indexes_symbol = module_sp->FindFirstSymbolWithNameAndType 
                                                           (g_libdispatch_tsd_indexes_symbol_name, eSymbolTypeData);
        if (libdispatch_tsd_indexes_symbol)
        {
            m_dispatch_tsd_indexes_addr = libdispatch_tsd_indexes_symbol->GetLoadAddress(&m_process->GetTarget());
        }
    }
}

void
SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes ()
{
    if (m_libdispatch_tsd_indexes.IsValid())
        return;

    ReadLibdispatchTSDIndexesAddress ();

    if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
    {

        // We don't need to check the version number right now, it will be at least 2, but
        // keep this code around to fetch just the version # for the future where we need
        // to fetch alternate versions of the struct.
# if 0
        uint16_t dti_version = 2;
        Address dti_struct_addr;
        if (m_process->GetTarget().ResolveLoadAddress (m_dispatch_tsd_indexes_addr, dti_struct_addr))
        {
            Error error;
            uint16_t version = m_process->GetTarget().ReadUnsignedIntegerFromMemory (dti_struct_addr, false, 2, UINT16_MAX, error);
            if (error.Success() && dti_version != UINT16_MAX)
            {
                dti_version = version;
            }
        }
#endif

        ClangASTContext *ast_ctx = m_process->GetTarget().GetScratchClangASTContext();
        if (ast_ctx->getASTContext() && m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
        {
            CompilerType uint16 = ast_ctx->GetBuiltinTypeForEncodingAndBitSize (eEncodingUint, 16);
            CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct, lldb::eLanguageTypeC);

            ClangASTContext::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
            ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_version", uint16, lldb::eAccessPublic, 0);
            ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_queue_index", uint16, lldb::eAccessPublic, 0);
            ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_voucher_index", uint16, lldb::eAccessPublic, 0);
            ClangASTContext::AddFieldToRecordType (dispatch_tsd_indexes_s, "dti_qos_class_index", uint16, lldb::eAccessPublic, 0);
            ClangASTContext::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s);

            ProcessStructReader struct_reader (m_process, m_dispatch_tsd_indexes_addr, dispatch_tsd_indexes_s);

            m_libdispatch_tsd_indexes.dti_version = struct_reader.GetField<uint16_t>(ConstString("dti_version"));
            m_libdispatch_tsd_indexes.dti_queue_index = struct_reader.GetField<uint16_t>(ConstString("dti_queue_index"));
            m_libdispatch_tsd_indexes.dti_voucher_index = struct_reader.GetField<uint16_t>(ConstString("dti_voucher_index"));
            m_libdispatch_tsd_indexes.dti_qos_class_index = struct_reader.GetField<uint16_t>(ConstString("dti_qos_class_index"));
        }
    }
}


ThreadSP
SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP real_thread, ConstString type)
{
    ThreadSP originating_thread_sp;
    if (BacktraceRecordingHeadersInitialized() && type == ConstString ("libdispatch"))
    {
        Error error;

        // real_thread is either an actual, live thread (in which case we need to call into
        // libBacktraceRecording to find its originator) or it is an extended backtrace itself,
        // in which case we get the token from it and call into libBacktraceRecording to find
        // the originator of that token.

        if (real_thread->GetExtendedBacktraceToken() != LLDB_INVALID_ADDRESS)
        {
            originating_thread_sp = GetExtendedBacktraceFromItemRef (real_thread->GetExtendedBacktraceToken());
        }
        else
        {
            ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
            AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo ret = m_get_thread_item_info_handler.GetThreadItemInfo (*cur_thread_sp.get(), real_thread->GetID(), m_page_to_free, m_page_to_free_size, error);
            m_page_to_free = LLDB_INVALID_ADDRESS;
            m_page_to_free_size = 0;
            if (ret.item_buffer_ptr != 0 &&  ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
            {
                DataBufferHeap data (ret.item_buffer_size, 0);
                if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
                {
                    DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
                    ItemInfo item = ExtractItemInfoFromBuffer (extractor);
                    bool stop_id_is_valid = true;
                    if (item.stop_id == 0)
                        stop_id_is_valid = false;
                    originating_thread_sp.reset (new HistoryThread (*m_process,
                                                                    item.enqueuing_thread_id,
                                                                    item.enqueuing_callstack,
                                                                    item.stop_id,
                                                                    stop_id_is_valid));
                    originating_thread_sp->SetExtendedBacktraceToken (item.item_that_enqueued_this);
                    originating_thread_sp->SetQueueName (item.enqueuing_queue_label.c_str());
                    originating_thread_sp->SetQueueID (item.enqueuing_queue_serialnum);
//                    originating_thread_sp->SetThreadName (item.enqueuing_thread_label.c_str());
                }
                m_page_to_free = ret.item_buffer_ptr;
                m_page_to_free_size = ret.item_buffer_size;
            }
        }
    }
    return originating_thread_sp;
}

ThreadSP
SystemRuntimeMacOSX::GetExtendedBacktraceFromItemRef (lldb::addr_t item_ref)
{
    ThreadSP return_thread_sp;

    AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
    ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
    Error error;
    ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), item_ref, m_page_to_free, m_page_to_free_size, error);
    m_page_to_free = LLDB_INVALID_ADDRESS;
    m_page_to_free_size = 0;
    if (ret.item_buffer_ptr != 0 &&  ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
    {
        DataBufferHeap data (ret.item_buffer_size, 0);
        if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
        {
            DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
            ItemInfo item = ExtractItemInfoFromBuffer (extractor);
            bool stop_id_is_valid = true;
            if (item.stop_id == 0)
                stop_id_is_valid = false;
            return_thread_sp.reset (new HistoryThread (*m_process,
                                                            item.enqueuing_thread_id,
                                                            item.enqueuing_callstack,
                                                            item.stop_id,
                                                            stop_id_is_valid));
            return_thread_sp->SetExtendedBacktraceToken (item.item_that_enqueued_this);
            return_thread_sp->SetQueueName (item.enqueuing_queue_label.c_str());
            return_thread_sp->SetQueueID (item.enqueuing_queue_serialnum);
//            return_thread_sp->SetThreadName (item.enqueuing_thread_label.c_str());

            m_page_to_free = ret.item_buffer_ptr;
            m_page_to_free_size = ret.item_buffer_size;
        }
    }
    return return_thread_sp;
}

ThreadSP
SystemRuntimeMacOSX::GetExtendedBacktraceForQueueItem (QueueItemSP queue_item_sp, ConstString type)
{
    ThreadSP extended_thread_sp;
    if (type != ConstString("libdispatch"))
        return extended_thread_sp;

    bool stop_id_is_valid = true;
    if (queue_item_sp->GetStopID() == 0)
        stop_id_is_valid = false;

    extended_thread_sp.reset (new HistoryThread (*m_process, 
                                                 queue_item_sp->GetEnqueueingThreadID(),
                                                 queue_item_sp->GetEnqueueingBacktrace(),
                                                 queue_item_sp->GetStopID(),
                                                 stop_id_is_valid));
    extended_thread_sp->SetExtendedBacktraceToken (queue_item_sp->GetItemThatEnqueuedThis());
    extended_thread_sp->SetQueueName (queue_item_sp->GetQueueLabel().c_str());
    extended_thread_sp->SetQueueID (queue_item_sp->GetEnqueueingQueueID());
//    extended_thread_sp->SetThreadName (queue_item_sp->GetThreadLabel().c_str());

    return extended_thread_sp;
}

/* Returns true if we were able to get the version / offset information
 * out of libBacktraceRecording.  false means we were unable to retrieve
 * this; the queue_info_version field will be 0.
 */

bool
SystemRuntimeMacOSX::BacktraceRecordingHeadersInitialized ()
{
    if (m_lib_backtrace_recording_info.queue_info_version != 0)
        return true;

    addr_t queue_info_version_address = LLDB_INVALID_ADDRESS;
    addr_t queue_info_data_offset_address = LLDB_INVALID_ADDRESS;
    addr_t item_info_version_address = LLDB_INVALID_ADDRESS;
    addr_t item_info_data_offset_address = LLDB_INVALID_ADDRESS;
    Target &target = m_process->GetTarget();


    static ConstString introspection_dispatch_queue_info_version ("__introspection_dispatch_queue_info_version");
    SymbolContextList sc_list;
    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_queue_info_version, eSymbolTypeData, sc_list) > 0)
    {
        SymbolContext sc;
        sc_list.GetContextAtIndex (0, sc);
        AddressRange addr_range;
        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
        queue_info_version_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
    }
    sc_list.Clear();

    static ConstString introspection_dispatch_queue_info_data_offset ("__introspection_dispatch_queue_info_data_offset");
    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_queue_info_data_offset, eSymbolTypeData, sc_list) > 0)
    {
        SymbolContext sc;
        sc_list.GetContextAtIndex (0, sc);
        AddressRange addr_range;
        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
        queue_info_data_offset_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
    }
    sc_list.Clear();

    static ConstString introspection_dispatch_item_info_version ("__introspection_dispatch_item_info_version");
    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_item_info_version, eSymbolTypeData, sc_list) > 0)
    {
        SymbolContext sc;
        sc_list.GetContextAtIndex (0, sc);
        AddressRange addr_range;
        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
        item_info_version_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
    }
    sc_list.Clear();

    static ConstString introspection_dispatch_item_info_data_offset ("__introspection_dispatch_item_info_data_offset");
    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_item_info_data_offset, eSymbolTypeData, sc_list) > 0)
    {
        SymbolContext sc;
        sc_list.GetContextAtIndex (0, sc);
        AddressRange addr_range;
        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
        item_info_data_offset_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
    }

    if (queue_info_version_address != LLDB_INVALID_ADDRESS
        && queue_info_data_offset_address != LLDB_INVALID_ADDRESS
        && item_info_version_address != LLDB_INVALID_ADDRESS
        && item_info_data_offset_address != LLDB_INVALID_ADDRESS)
    {
        Error error;
        m_lib_backtrace_recording_info.queue_info_version = m_process->ReadUnsignedIntegerFromMemory (queue_info_version_address, 2, 0, error);
        if (error.Success())
        {
            m_lib_backtrace_recording_info.queue_info_data_offset = m_process->ReadUnsignedIntegerFromMemory (queue_info_data_offset_address, 2, 0, error);
            if (error.Success())
            {
                m_lib_backtrace_recording_info.item_info_version = m_process->ReadUnsignedIntegerFromMemory (item_info_version_address, 2, 0, error);
                if (error.Success())
                {
                    m_lib_backtrace_recording_info.item_info_data_offset = m_process->ReadUnsignedIntegerFromMemory (item_info_data_offset_address, 2, 0, error);
                    if (!error.Success())
                    {
                        m_lib_backtrace_recording_info.queue_info_version = 0;
                    }
                }
                else
                {
                    m_lib_backtrace_recording_info.queue_info_version = 0;
                }
            }
            else
            {
                m_lib_backtrace_recording_info.queue_info_version = 0;
            }
        }
    }

    return m_lib_backtrace_recording_info.queue_info_version != 0;
}

const std::vector<ConstString> &
SystemRuntimeMacOSX::GetExtendedBacktraceTypes ()
{
    if (m_types.size () == 0)
    {
        m_types.push_back(ConstString("libdispatch"));
        // We could have pthread as another type in the future if we have a way of
        // gathering that information & it's useful to distinguish between them.
    }
    return m_types;
}

void
SystemRuntimeMacOSX::PopulateQueueList (lldb_private::QueueList &queue_list)
{
    if (BacktraceRecordingHeadersInitialized())
    {
        AppleGetQueuesHandler::GetQueuesReturnInfo queue_info_pointer;
        ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
        if (cur_thread_sp)
        { 
            Error error;
            queue_info_pointer = m_get_queues_handler.GetCurrentQueues (*cur_thread_sp.get(), m_page_to_free, m_page_to_free_size, error);
            m_page_to_free = LLDB_INVALID_ADDRESS;
            m_page_to_free_size = 0;
            if (error.Success())
            {

                if (queue_info_pointer.count > 0 
                    && queue_info_pointer.queues_buffer_size > 0
                    && queue_info_pointer.queues_buffer_ptr != 0 
                    && queue_info_pointer.queues_buffer_ptr != LLDB_INVALID_ADDRESS)
                {
                    PopulateQueuesUsingLibBTR (queue_info_pointer.queues_buffer_ptr, queue_info_pointer.queues_buffer_size, queue_info_pointer.count, queue_list);
                }
            }
        }
    }

    // We either didn't have libBacktraceRecording (and need to create the queues list based on threads)
    // or we did get the queues list from libBacktraceRecording but some special queues may not be
    // included in its information.  This is needed because libBacktraceRecording
    // will only list queues with pending or running items by default - but the magic com.apple.main-thread
    // queue on thread 1 is always around.

    for (ThreadSP thread_sp : m_process->Threads())
    {
        if (thread_sp->GetAssociatedWithLibdispatchQueue () != eLazyBoolNo)
        {
            if (thread_sp->GetQueueID() != LLDB_INVALID_QUEUE_ID)
            {
                if (queue_list.FindQueueByID (thread_sp->GetQueueID()).get() == NULL)
                {
                    QueueSP queue_sp (new Queue(m_process->shared_from_this(), thread_sp->GetQueueID(), thread_sp->GetQueueName()));
                    if (thread_sp->ThreadHasQueueInformation ())
                    {
                        queue_sp->SetKind (thread_sp->GetQueueKind ());
                        queue_sp->SetLibdispatchQueueAddress (thread_sp->GetQueueLibdispatchQueueAddress());
                        queue_list.AddQueue (queue_sp);
                    }
                    else
                    {
                        queue_sp->SetKind (GetQueueKind (thread_sp->GetQueueLibdispatchQueueAddress()));
                        queue_sp->SetLibdispatchQueueAddress (thread_sp->GetQueueLibdispatchQueueAddress());
                        queue_list.AddQueue (queue_sp);
                    }
                }
            }
        }
    }
}

// Returns either an array of introspection_dispatch_item_info_ref's for the pending items on
// a queue or an array introspection_dispatch_item_info_ref's and code addresses for the 
// pending items on a queue.  The information about each of these pending items then needs to 
// be fetched individually by passing the ref to libBacktraceRecording.

SystemRuntimeMacOSX::PendingItemsForQueue
SystemRuntimeMacOSX::GetPendingItemRefsForQueue (lldb::addr_t queue)
{
    PendingItemsForQueue pending_item_refs;
    AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer;
    ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
    if (cur_thread_sp)
    { 
        Error error;
        pending_items_pointer = m_get_pending_items_handler.GetPendingItems (*cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size, error);
        m_page_to_free = LLDB_INVALID_ADDRESS;
        m_page_to_free_size = 0;
        if (error.Success())
        {
            if (pending_items_pointer.count > 0
                && pending_items_pointer.items_buffer_size > 0
                && pending_items_pointer.items_buffer_ptr != 0
                && pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS)
            {
                DataBufferHeap data (pending_items_pointer.items_buffer_size, 0);
                if (m_process->ReadMemory (pending_items_pointer.items_buffer_ptr, data.GetBytes(), pending_items_pointer.items_buffer_size, error))
                {
                    DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());

                    // We either have an array of
                    //    void* item_ref
                    // (old style) or we have a structure returned which looks like
                    //
                    // struct introspection_dispatch_pending_item_info_s {
                    //   void *item_ref;
                    //   void *function_or_block;
                    // };
                    //
                    // struct introspection_dispatch_pending_items_array_s {
                    //   uint32_t version;
                    //   uint32_t size_of_item_info;
                    //   introspection_dispatch_pending_item_info_s items[];
                    //   }

                    offset_t offset = 0;
                    int i = 0;
                    uint32_t version = extractor.GetU32(&offset);
                    if (version == 1)
                    {
                        pending_item_refs.new_style = true;
                        uint32_t item_size = extractor.GetU32(&offset);
                        uint32_t start_of_array_offset = offset;
                        while (offset < pending_items_pointer.items_buffer_size &&
                               static_cast<size_t>(i) < pending_items_pointer.count)
                        {
                            offset = start_of_array_offset + (i * item_size);
                            ItemRefAndCodeAddress item;
                            item.item_ref = extractor.GetPointer (&offset);
                            item.code_address = extractor.GetPointer (&offset);
                            pending_item_refs.item_refs_and_code_addresses.push_back (item);
                            i++;
                        }
                    }
                    else
                    {
                        offset = 0;
                        pending_item_refs.new_style = false;
                        while (offset < pending_items_pointer.items_buffer_size &&
                               static_cast<size_t>(i) < pending_items_pointer.count)
                        {
                            ItemRefAndCodeAddress item;
                            item.item_ref = extractor.GetPointer (&offset);
                            item.code_address = LLDB_INVALID_ADDRESS;
                            pending_item_refs.item_refs_and_code_addresses.push_back (item);
                            i++;
                        }
                    }
                }
                m_page_to_free = pending_items_pointer.items_buffer_ptr;
                m_page_to_free_size = pending_items_pointer.items_buffer_size;
            }
        }
    }
    return pending_item_refs;
}



void
SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue)
{
    if (BacktraceRecordingHeadersInitialized())
    {
        PendingItemsForQueue pending_item_refs = GetPendingItemRefsForQueue (queue->GetLibdispatchQueueAddress());
        for (ItemRefAndCodeAddress pending_item : pending_item_refs.item_refs_and_code_addresses)
        {
            Address addr;
            m_process->GetTarget().ResolveLoadAddress (pending_item.code_address, addr);
            QueueItemSP queue_item_sp (new QueueItem (queue->shared_from_this(), m_process->shared_from_this(), pending_item.item_ref, addr));
            queue->PushPendingQueueItem (queue_item_sp);
        }
    }
}

void 
SystemRuntimeMacOSX::CompleteQueueItem (QueueItem *queue_item, addr_t item_ref)
{
    AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;

    ThreadSP cur_thread_sp (m_process->GetThreadList().GetExpressionExecutionThread());
    Error error;
    ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), item_ref, m_page_to_free, m_page_to_free_size, error);
    m_page_to_free = LLDB_INVALID_ADDRESS;
    m_page_to_free_size = 0;
    if (ret.item_buffer_ptr != 0 &&  ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
    {
        DataBufferHeap data (ret.item_buffer_size, 0);
        if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
        {
            DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
            ItemInfo item = ExtractItemInfoFromBuffer (extractor);
            queue_item->SetItemThatEnqueuedThis (item.item_that_enqueued_this);
            queue_item->SetEnqueueingThreadID (item.enqueuing_thread_id);
            queue_item->SetEnqueueingQueueID (item.enqueuing_queue_serialnum);
            queue_item->SetStopID (item.stop_id);
            queue_item->SetEnqueueingBacktrace (item.enqueuing_callstack);
            queue_item->SetThreadLabel (item.enqueuing_thread_label);
            queue_item->SetQueueLabel (item.enqueuing_queue_label);
            queue_item->SetTargetQueueLabel (item.target_queue_label);
        }
        m_page_to_free = ret.item_buffer_ptr;
        m_page_to_free_size = ret.item_buffer_size;
    }
}

void
SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size, 
                                                uint64_t count, lldb_private::QueueList &queue_list)
{
    Error error;
    DataBufferHeap data (queues_buffer_size, 0);
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
    if (m_process->ReadMemory (queues_buffer, data.GetBytes(), queues_buffer_size, error) == queues_buffer_size && error.Success())
    {
        // We've read the information out of inferior memory; free it on the next call we make
        m_page_to_free = queues_buffer;
        m_page_to_free_size = queues_buffer_size;

        DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
        offset_t offset = 0;
        uint64_t queues_read = 0;

        // The information about the queues is stored in this format (v1):
        // typedef struct introspection_dispatch_queue_info_s {
        //     uint32_t offset_to_next;
        //     dispatch_queue_t queue;
        //     uint64_t serialnum;     // queue's serialnum in the process, as provided by libdispatch
        //     uint32_t running_work_items_count;
        //     uint32_t pending_work_items_count;
        // 
        //     char data[];     // Starting here, we have variable-length data:
        //     // char queue_label[];
        // } introspection_dispatch_queue_info_s;

        while (queues_read < count && offset < queues_buffer_size)
        {
            offset_t    start_of_this_item = offset;

            uint32_t    offset_to_next = extractor.GetU32 (&offset);

            offset += 4; // Skip over the 4 bytes of reserved space
            addr_t      queue = extractor.GetPointer (&offset);
            uint64_t    serialnum = extractor.GetU64 (&offset);
            uint32_t    running_work_items_count = extractor.GetU32 (&offset);
            uint32_t    pending_work_items_count = extractor.GetU32 (&offset);

            // Read the first field of the variable length data
            offset = start_of_this_item + m_lib_backtrace_recording_info.queue_info_data_offset;
            const char *queue_label = extractor.GetCStr (&offset);
            if (queue_label == NULL)
                queue_label = "";

            offset_t    start_of_next_item = start_of_this_item + offset_to_next;
            offset = start_of_next_item;

            if (log)
                log->Printf ("SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR added queue with dispatch_queue_t 0x%" PRIx64 ", serial number 0x%" PRIx64 ", running items %d, pending items %d, name '%s'", queue, serialnum, running_work_items_count, pending_work_items_count, queue_label);

            QueueSP queue_sp (new Queue (m_process->shared_from_this(), serialnum, queue_label));
            queue_sp->SetNumRunningWorkItems (running_work_items_count);
            queue_sp->SetNumPendingWorkItems (pending_work_items_count);
            queue_sp->SetLibdispatchQueueAddress (queue);
            queue_sp->SetKind (GetQueueKind (queue));
            queue_list.AddQueue (queue_sp);
            queues_read++;
        }
    }
}

SystemRuntimeMacOSX::ItemInfo
SystemRuntimeMacOSX::ExtractItemInfoFromBuffer (lldb_private::DataExtractor &extractor)
{
    ItemInfo item;

    offset_t offset = 0;
    
    item.item_that_enqueued_this = extractor.GetPointer (&offset);
    item.function_or_block = extractor.GetPointer (&offset);
    item.enqueuing_thread_id = extractor.GetU64 (&offset);
    item.enqueuing_queue_serialnum = extractor.GetU64 (&offset);
    item.target_queue_serialnum = extractor.GetU64 (&offset);
    item.enqueuing_callstack_frame_count = extractor.GetU32 (&offset);
    item.stop_id = extractor.GetU32 (&offset);

    offset = m_lib_backtrace_recording_info.item_info_data_offset;

    for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++)
    {
        item.enqueuing_callstack.push_back (extractor.GetPointer (&offset));
    }
    item.enqueuing_thread_label = extractor.GetCStr (&offset);
    item.enqueuing_queue_label = extractor.GetCStr (&offset);
    item.target_queue_label = extractor.GetCStr (&offset);

    return item;
}

void
SystemRuntimeMacOSX::Initialize()
{
    PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                   GetPluginDescriptionStatic(),
                                   CreateInstance);
}

void
SystemRuntimeMacOSX::Terminate()
{
    PluginManager::UnregisterPlugin (CreateInstance);
}


lldb_private::ConstString
SystemRuntimeMacOSX::GetPluginNameStatic()
{
    static ConstString g_name("systemruntime-macosx");
    return g_name;
}

const char *
SystemRuntimeMacOSX::GetPluginDescriptionStatic()
{
    return "System runtime plugin for Mac OS X native libraries.";
}


//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
lldb_private::ConstString
SystemRuntimeMacOSX::GetPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
SystemRuntimeMacOSX::GetPluginVersion()
{
    return 1;
}
