//===-- 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/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->GetAddress().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->GetAddress().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->GetAddress().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;
}
