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