//===-- 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/Expression/ClangFunction.h"
#include "lldb/Expression/ClangUtilityFunction.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:
                    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(Mutex::eMutexTypeRecursive),
    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)
{
    Mutex::Locker locker(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)
        {
            ClangASTType uint16 = ast_ctx->GetIntTypeFromBitSize(16, false);
            ClangASTType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct, lldb::eLanguageTypeC);
            dispatch_tsd_indexes_s.StartTagDeclarationDefinition();
            dispatch_tsd_indexes_s.AddFieldToRecordType ("dti_version", uint16, lldb::eAccessPublic, 0);
            dispatch_tsd_indexes_s.AddFieldToRecordType ("dti_queue_index", uint16, lldb::eAccessPublic, 0);
            dispatch_tsd_indexes_s.AddFieldToRecordType ("dti_voucher_index", uint16, lldb::eAccessPublic, 0);
            dispatch_tsd_indexes_s.AddFieldToRecordType ("dti_qos_class_index", uint16, lldb::eAccessPublic, 0);
            dispatch_tsd_indexes_s.CompleteTagDeclarationDefinition();

            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().GetSelectedThread());
            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().GetSelectedThread());
    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().GetSelectedThread());
        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->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()));
                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().GetSelectedThread());
    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().GetSelectedThread());
    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;
}
