12fd83355SJason Molenda //===-- AppleGetItemInfoHandler.cpp -------------------------------*- C++ -*-===//
22fd83355SJason Molenda //
32fd83355SJason Molenda //                     The LLVM Compiler Infrastructure
42fd83355SJason Molenda //
52fd83355SJason Molenda // This file is distributed under the University of Illinois Open Source
62fd83355SJason Molenda // License. See LICENSE.TXT for details.
72fd83355SJason Molenda //
82fd83355SJason Molenda //===----------------------------------------------------------------------===//
92fd83355SJason Molenda 
102fd83355SJason Molenda #include "AppleGetItemInfoHandler.h"
112fd83355SJason Molenda 
122fd83355SJason Molenda // C Includes
132fd83355SJason Molenda // C++ Includes
142fd83355SJason Molenda // Other libraries and framework includes
152fd83355SJason Molenda // Project includes
162fd83355SJason Molenda 
172fd83355SJason Molenda #include "clang/AST/ASTContext.h"
182fd83355SJason Molenda #include "clang/AST/DeclCXX.h"
192fd83355SJason Molenda 
202fd83355SJason Molenda #include "lldb/Core/ConstString.h"
212fd83355SJason Molenda #include "lldb/Core/Log.h"
222fd83355SJason Molenda #include "lldb/Core/Module.h"
232fd83355SJason Molenda #include "lldb/Core/StreamString.h"
242fd83355SJason Molenda #include "lldb/Core/Value.h"
252fd83355SJason Molenda #include "lldb/Expression/ClangExpression.h"
262fd83355SJason Molenda #include "lldb/Expression/ClangFunction.h"
272fd83355SJason Molenda #include "lldb/Expression/ClangUtilityFunction.h"
282fd83355SJason Molenda #include "lldb/Symbol/ClangASTContext.h"
292fd83355SJason Molenda #include "lldb/Symbol/Symbol.h"
302fd83355SJason Molenda #include "lldb/Target/ExecutionContext.h"
312fd83355SJason Molenda #include "lldb/Target/Process.h"
322fd83355SJason Molenda #include "lldb/Target/Target.h"
332fd83355SJason Molenda #include "lldb/Target/Thread.h"
342fd83355SJason Molenda 
352fd83355SJason Molenda using namespace lldb;
362fd83355SJason Molenda using namespace lldb_private;
372fd83355SJason Molenda 
382fd83355SJason Molenda const char *AppleGetItemInfoHandler::g_get_item_info_function_name = "__lldb_backtrace_recording_get_item_info";
392fd83355SJason Molenda const char *AppleGetItemInfoHandler::g_get_item_info_function_code = "                                  \n\
402fd83355SJason Molenda extern \"C\"                                                                                                    \n\
412fd83355SJason Molenda {                                                                                                               \n\
422fd83355SJason Molenda     /*                                                                                                          \n\
432fd83355SJason Molenda      * mach defines                                                                                             \n\
442fd83355SJason Molenda      */                                                                                                         \n\
452fd83355SJason Molenda                                                                                                                 \n\
462fd83355SJason Molenda     typedef unsigned int uint32_t;                                                                              \n\
472fd83355SJason Molenda     typedef unsigned long long uint64_t;                                                                        \n\
482fd83355SJason Molenda     typedef uint32_t mach_port_t;                                                                               \n\
492fd83355SJason Molenda     typedef mach_port_t vm_map_t;                                                                               \n\
502fd83355SJason Molenda     typedef int kern_return_t;                                                                                  \n\
512fd83355SJason Molenda     typedef uint64_t mach_vm_address_t;                                                                         \n\
522fd83355SJason Molenda     typedef uint64_t mach_vm_size_t;                                                                            \n\
532fd83355SJason Molenda                                                                                                                 \n\
542fd83355SJason Molenda     mach_port_t mach_task_self ();                                                                              \n\
552fd83355SJason Molenda     kern_return_t mach_vm_deallocate (vm_map_t target, mach_vm_address_t address, mach_vm_size_t size);         \n\
562fd83355SJason Molenda                                                                                                                 \n\
572fd83355SJason Molenda     /*                                                                                                          \n\
582fd83355SJason Molenda      * libBacktraceRecording defines                                                                            \n\
592fd83355SJason Molenda      */                                                                                                         \n\
602fd83355SJason Molenda                                                                                                                 \n\
612fd83355SJason Molenda     typedef uint32_t queue_list_scope_t;                                                                        \n\
622fd83355SJason Molenda     typedef void *dispatch_queue_t;                                                                             \n\
632fd83355SJason Molenda     typedef void *introspection_dispatch_queue_info_t;                                                          \n\
642fd83355SJason Molenda     typedef void *introspection_dispatch_item_info_ref;                                                         \n\
652fd83355SJason Molenda                                                                                                                 \n\
662fd83355SJason Molenda     extern uint64_t __introspection_dispatch_queue_item_get_info (introspection_dispatch_item_info_ref item_info_ref, \n\
672fd83355SJason Molenda                                                  introspection_dispatch_item_info_ref *returned_queues_buffer,  \n\
682fd83355SJason Molenda                                                  uint64_t *returned_queues_buffer_size);                        \n\
692fd83355SJason Molenda     extern int printf(const char *format, ...);                                                                 \n\
702fd83355SJason Molenda                                                                                                                 \n\
712fd83355SJason Molenda     /*                                                                                                          \n\
722fd83355SJason Molenda      * return type define                                                                                       \n\
732fd83355SJason Molenda      */                                                                                                         \n\
742fd83355SJason Molenda                                                                                                                 \n\
752fd83355SJason Molenda     struct get_item_info_return_values                                                                      \n\
762fd83355SJason Molenda     {                                                                                                           \n\
772fd83355SJason Molenda         uint64_t item_info_buffer_ptr;    /* the address of the items buffer from libBacktraceRecording */  \n\
782fd83355SJason Molenda         uint64_t item_info_buffer_size;   /* the size of the items buffer from libBacktraceRecording */     \n\
792fd83355SJason Molenda     };                                                                                                          \n\
802fd83355SJason Molenda                                                                                                                 \n\
812fd83355SJason Molenda     void  __lldb_backtrace_recording_get_item_info                                                          \n\
822fd83355SJason Molenda                                                (struct get_item_info_return_values *return_buffer,          \n\
832fd83355SJason Molenda                                                 int debug,                                                      \n\
842fd83355SJason Molenda                                                 uint64_t /* introspection_dispatch_item_info_ref item_info_ref */ item, \n\
852fd83355SJason Molenda                                                 void *page_to_free,                                             \n\
862fd83355SJason Molenda                                                 uint64_t page_to_free_size)                                     \n\
872fd83355SJason Molenda {                                                                                                               \n\
882fd83355SJason Molenda     if (debug)                                                                                                  \n\
892fd83355SJason Molenda       printf (\"entering get_item_info with args return_buffer == %p, debug == %d, item == 0x%llx, page_to_free == %p, page_to_free_size == 0x%llx\\n\", return_buffer, debug, item, page_to_free, page_to_free_size); \n\
902fd83355SJason Molenda     if (page_to_free != 0)                                                                                      \n\
912fd83355SJason Molenda     {                                                                                                           \n\
922fd83355SJason Molenda         mach_vm_deallocate (mach_task_self(), (mach_vm_address_t) page_to_free, (mach_vm_size_t) page_to_free_size); \n\
932fd83355SJason Molenda     }                                                                                                           \n\
942fd83355SJason Molenda                                                                                                                 \n\
952fd83355SJason Molenda     __introspection_dispatch_queue_item_get_info ((void*) item,                                                 \n\
962fd83355SJason Molenda                                                   (void**)&return_buffer->item_info_buffer_ptr,                 \n\
972fd83355SJason Molenda                                                   &return_buffer->item_info_buffer_size);                       \n\
982fd83355SJason Molenda }                                                                                                               \n\
992fd83355SJason Molenda }                                                                                                               \n\
1002fd83355SJason Molenda ";
1012fd83355SJason Molenda 
1022fd83355SJason Molenda AppleGetItemInfoHandler::AppleGetItemInfoHandler (Process *process) :
1032fd83355SJason Molenda     m_process (process),
1042fd83355SJason Molenda     m_get_item_info_function (),
1052fd83355SJason Molenda     m_get_item_info_impl_code (),
1062fd83355SJason Molenda     m_get_item_info_function_mutex(),
1072fd83355SJason Molenda     m_get_item_info_return_buffer_addr (LLDB_INVALID_ADDRESS),
1082fd83355SJason Molenda     m_get_item_info_retbuffer_mutex()
1092fd83355SJason Molenda {
1102fd83355SJason Molenda }
1112fd83355SJason Molenda 
1122fd83355SJason Molenda AppleGetItemInfoHandler::~AppleGetItemInfoHandler ()
1132fd83355SJason Molenda {
1142fd83355SJason Molenda }
1152fd83355SJason Molenda 
1162fd83355SJason Molenda void
1172fd83355SJason Molenda AppleGetItemInfoHandler::Detach ()
1182fd83355SJason Molenda {
1192fd83355SJason Molenda 
1202fd83355SJason Molenda     if (m_process && m_process->IsAlive() && m_get_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS)
1212fd83355SJason Molenda     {
1222fd83355SJason Molenda         Mutex::Locker locker;
1232fd83355SJason Molenda         locker.TryLock (m_get_item_info_retbuffer_mutex);  // Even if we don't get the lock, deallocate the buffer
1242fd83355SJason Molenda         m_process->DeallocateMemory (m_get_item_info_return_buffer_addr);
1252fd83355SJason Molenda     }
1262fd83355SJason Molenda }
1272fd83355SJason Molenda 
1282fd83355SJason Molenda // Compile our __lldb_backtrace_recording_get_item_info() function (from the
1292fd83355SJason Molenda // source above in g_get_item_info_function_code) if we don't find that function in the inferior
1302fd83355SJason Molenda // already with USE_BUILTIN_FUNCTION defined.  (e.g. this would be the case for testing.)
1312fd83355SJason Molenda //
1322fd83355SJason Molenda // Insert the __lldb_backtrace_recording_get_item_info into the inferior process if needed.
1332fd83355SJason Molenda //
1342fd83355SJason Molenda // Write the get_item_info_arglist into the inferior's memory space to prepare for the call.
1352fd83355SJason Molenda //
1362fd83355SJason Molenda // Returns the address of the arguments written down in the inferior process, which can be used to
1372fd83355SJason Molenda // make the function call.
1382fd83355SJason Molenda 
1392fd83355SJason Molenda lldb::addr_t
1402fd83355SJason Molenda AppleGetItemInfoHandler::SetupGetItemInfoFunction (Thread &thread, ValueList &get_item_info_arglist)
1412fd83355SJason Molenda {
1422fd83355SJason Molenda     ExecutionContext exe_ctx (thread.shared_from_this());
1432fd83355SJason Molenda     Address impl_code_address;
1442fd83355SJason Molenda     StreamString errors;
1452fd83355SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
1462fd83355SJason Molenda     lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
1472fd83355SJason Molenda 
1482fd83355SJason Molenda     // Scope for mutex locker:
1492fd83355SJason Molenda     {
1502fd83355SJason Molenda         Mutex::Locker locker(m_get_item_info_function_mutex);
1512fd83355SJason Molenda 
1522fd83355SJason Molenda         // First stage is to make the ClangUtility to hold our injected function:
1532fd83355SJason Molenda 
1542fd83355SJason Molenda #define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
1552fd83355SJason Molenda                                 // This is useful for debugging additions to the get_impl function 'cause you don't have
1562fd83355SJason Molenda                                 // to bother with string-ifying the code into g_get_item_info_function_code.
1572fd83355SJason Molenda 
1582fd83355SJason Molenda         if (USE_BUILTIN_FUNCTION)
1592fd83355SJason Molenda         {
1602fd83355SJason Molenda             ConstString our_utility_function_name("__lldb_backtrace_recording_get_item_info");
1612fd83355SJason Molenda             SymbolContextList sc_list;
1622fd83355SJason Molenda 
1632fd83355SJason Molenda             exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
1642fd83355SJason Molenda             if (sc_list.GetSize() == 1)
1652fd83355SJason Molenda             {
1662fd83355SJason Molenda                 SymbolContext sc;
1672fd83355SJason Molenda                 sc_list.GetContextAtIndex(0, sc);
1682fd83355SJason Molenda                 if (sc.symbol != NULL)
1692fd83355SJason Molenda                     impl_code_address = sc.symbol->GetAddress();
1702fd83355SJason Molenda 
1712fd83355SJason Molenda                 //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
1722fd83355SJason Molenda                 //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
1732fd83355SJason Molenda             }
1742fd83355SJason Molenda             else
1752fd83355SJason Molenda             {
1762fd83355SJason Molenda                 //printf ("Could not find queues introspection function address.\n");
1772fd83355SJason Molenda                 return args_addr;
1782fd83355SJason Molenda             }
1792fd83355SJason Molenda         }
1802fd83355SJason Molenda         else if (!m_get_item_info_impl_code.get())
1812fd83355SJason Molenda         {
1822fd83355SJason Molenda             if (g_get_item_info_function_code != NULL)
1832fd83355SJason Molenda             {
1842fd83355SJason Molenda                 m_get_item_info_impl_code.reset (new ClangUtilityFunction (g_get_item_info_function_code,
1852fd83355SJason Molenda                                                              g_get_item_info_function_name));
1862fd83355SJason Molenda                 if (!m_get_item_info_impl_code->Install(errors, exe_ctx))
1872fd83355SJason Molenda                 {
1882fd83355SJason Molenda                     if (log)
1892fd83355SJason Molenda                         log->Printf ("Failed to install get-item-info introspection: %s.", errors.GetData());
1902fd83355SJason Molenda                     m_get_item_info_impl_code.reset();
1912fd83355SJason Molenda                     return args_addr;
1922fd83355SJason Molenda                 }
1932fd83355SJason Molenda             }
1942fd83355SJason Molenda             else
1952fd83355SJason Molenda             {
1962fd83355SJason Molenda                 if (log)
1972fd83355SJason Molenda                     log->Printf("No get-item-info introspection code found.");
1982fd83355SJason Molenda                 errors.Printf ("No get-item-info introspection code found.");
1992fd83355SJason Molenda                 return LLDB_INVALID_ADDRESS;
2002fd83355SJason Molenda             }
2012fd83355SJason Molenda 
2022fd83355SJason Molenda             impl_code_address.Clear();
2032fd83355SJason Molenda             impl_code_address.SetOffset(m_get_item_info_impl_code->StartAddress());
2042fd83355SJason Molenda         }
2052fd83355SJason Molenda         else
2062fd83355SJason Molenda         {
2072fd83355SJason Molenda             impl_code_address.Clear();
2082fd83355SJason Molenda             impl_code_address.SetOffset(m_get_item_info_impl_code->StartAddress());
2092fd83355SJason Molenda         }
2102fd83355SJason Molenda 
2112fd83355SJason Molenda         // Next make the runner function for our implementation utility function.
2122fd83355SJason Molenda         if (!m_get_item_info_function.get())
2132fd83355SJason Molenda         {
2142fd83355SJason Molenda             ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
215a1e5dc86SGreg Clayton             CompilerType get_item_info_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
2162fd83355SJason Molenda             m_get_item_info_function.reset(new ClangFunction (thread,
2172fd83355SJason Molenda                                                      get_item_info_return_type,
2182fd83355SJason Molenda                                                      impl_code_address,
21923ef27cdSJim Ingham                                                      get_item_info_arglist,
22023ef27cdSJim Ingham                                                      "queue-bt-item-info"));
2212fd83355SJason Molenda 
2222fd83355SJason Molenda             errors.Clear();
2232fd83355SJason Molenda             unsigned num_errors = m_get_item_info_function->CompileFunction(errors);
2242fd83355SJason Molenda             if (num_errors)
2252fd83355SJason Molenda             {
2262fd83355SJason Molenda                 if (log)
2272fd83355SJason Molenda                     log->Printf ("Error compiling get-item-info function: \"%s\".", errors.GetData());
2282fd83355SJason Molenda                 return args_addr;
2292fd83355SJason Molenda             }
2302fd83355SJason Molenda 
2312fd83355SJason Molenda             errors.Clear();
2322fd83355SJason Molenda             if (!m_get_item_info_function->WriteFunctionWrapper(exe_ctx, errors))
2332fd83355SJason Molenda             {
2342fd83355SJason Molenda                 if (log)
2352fd83355SJason Molenda                     log->Printf ("Error Inserting get-item-info function: \"%s\".", errors.GetData());
2362fd83355SJason Molenda                 return args_addr;
2372fd83355SJason Molenda             }
2382fd83355SJason Molenda         }
2392fd83355SJason Molenda     }
2402fd83355SJason Molenda 
2412fd83355SJason Molenda     errors.Clear();
2422fd83355SJason Molenda 
2432fd83355SJason Molenda     // Now write down the argument values for this particular call.  This looks like it might be a race condition
2442fd83355SJason Molenda     // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
2452fd83355SJason Molenda     // this call by passing args_addr = LLDB_INVALID_ADDRESS...
2462fd83355SJason Molenda 
2472fd83355SJason Molenda     if (!m_get_item_info_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_item_info_arglist, errors))
2482fd83355SJason Molenda     {
2492fd83355SJason Molenda         if (log)
2502fd83355SJason Molenda             log->Printf ("Error writing get-item-info function arguments: \"%s\".", errors.GetData());
2512fd83355SJason Molenda         return args_addr;
2522fd83355SJason Molenda     }
2532fd83355SJason Molenda 
2542fd83355SJason Molenda     return args_addr;
2552fd83355SJason Molenda }
2562fd83355SJason Molenda 
2572fd83355SJason Molenda AppleGetItemInfoHandler::GetItemInfoReturnInfo
2582fd83355SJason Molenda AppleGetItemInfoHandler::GetItemInfo (Thread &thread, uint64_t item, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
2592fd83355SJason Molenda {
2602fd83355SJason Molenda     lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
2612fd83355SJason Molenda     ProcessSP process_sp (thread.CalculateProcess());
2622fd83355SJason Molenda     TargetSP target_sp (thread.CalculateTarget());
2632fd83355SJason Molenda     ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
2642fd83355SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
2652fd83355SJason Molenda 
2662fd83355SJason Molenda     GetItemInfoReturnInfo return_value;
2672fd83355SJason Molenda     return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
2682fd83355SJason Molenda     return_value.item_buffer_size = 0;
2692fd83355SJason Molenda 
2702fd83355SJason Molenda     error.Clear();
2712fd83355SJason Molenda 
272b4892cd2SJason Molenda     if (thread.SafeToCallFunctions() == false)
273b4892cd2SJason Molenda     {
274b4892cd2SJason Molenda         if (log)
275b4892cd2SJason Molenda             log->Printf ("Not safe to call functions on thread 0x%" PRIx64, thread.GetID());
276b4892cd2SJason Molenda         error.SetErrorString ("Not safe to call functions on this thread.");
277b4892cd2SJason Molenda         return return_value;
278b4892cd2SJason Molenda     }
279b4892cd2SJason Molenda 
2802fd83355SJason Molenda     // Set up the arguments for a call to
2812fd83355SJason Molenda 
2822fd83355SJason Molenda     // struct get_item_info_return_values
2832fd83355SJason Molenda     // {
2842fd83355SJason Molenda     //     uint64_t item_info_buffer_ptr;    /* the address of the items buffer from libBacktraceRecording */
2852fd83355SJason Molenda     //     uint64_t item_info_buffer_size;   /* the size of the items buffer from libBacktraceRecording */
2862fd83355SJason Molenda     // };
2872fd83355SJason Molenda     //
2882fd83355SJason Molenda     // void  __lldb_backtrace_recording_get_item_info
2892fd83355SJason Molenda     //                                            (struct get_item_info_return_values *return_buffer,
2902fd83355SJason Molenda     //                                             int debug,
2912fd83355SJason Molenda     //                                             uint64_t item,
2922fd83355SJason Molenda     //                                             void *page_to_free,
2932fd83355SJason Molenda     //                                             uint64_t page_to_free_size)
2942fd83355SJason Molenda 
2952fd83355SJason Molenda     // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
2962fd83355SJason Molenda     // the inferior process.
2972fd83355SJason Molenda 
298a1e5dc86SGreg Clayton     CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
2992fd83355SJason Molenda     Value return_buffer_ptr_value;
3002fd83355SJason Molenda     return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
301*99558cc4SGreg Clayton     return_buffer_ptr_value.SetCompilerType (clang_void_ptr_type);
3022fd83355SJason Molenda 
303a1e5dc86SGreg Clayton     CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
3042fd83355SJason Molenda     Value debug_value;
3052fd83355SJason Molenda     debug_value.SetValueType (Value::eValueTypeScalar);
306*99558cc4SGreg Clayton     debug_value.SetCompilerType (clang_int_type);
3072fd83355SJason Molenda 
308a1e5dc86SGreg Clayton     CompilerType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
3092fd83355SJason Molenda     Value item_value;
3102fd83355SJason Molenda     item_value.SetValueType (Value::eValueTypeScalar);
311*99558cc4SGreg Clayton     item_value.SetCompilerType (clang_uint64_type);
3122fd83355SJason Molenda 
3132fd83355SJason Molenda     Value page_to_free_value;
3142fd83355SJason Molenda     page_to_free_value.SetValueType (Value::eValueTypeScalar);
315*99558cc4SGreg Clayton     page_to_free_value.SetCompilerType (clang_void_ptr_type);
3162fd83355SJason Molenda 
3172fd83355SJason Molenda     Value page_to_free_size_value;
3182fd83355SJason Molenda     page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
319*99558cc4SGreg Clayton     page_to_free_size_value.SetCompilerType (clang_uint64_type);
3202fd83355SJason Molenda 
3212fd83355SJason Molenda 
3222fd83355SJason Molenda     Mutex::Locker locker(m_get_item_info_retbuffer_mutex);
3232fd83355SJason Molenda     if (m_get_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS)
3242fd83355SJason Molenda     {
3252fd83355SJason Molenda         addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
3262fd83355SJason Molenda         if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
3272fd83355SJason Molenda         {
3282fd83355SJason Molenda             if (log)
3292fd83355SJason Molenda                 log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
3302fd83355SJason Molenda             return return_value;
3312fd83355SJason Molenda         }
3322fd83355SJason Molenda         m_get_item_info_return_buffer_addr = bufaddr;
3332fd83355SJason Molenda     }
3342fd83355SJason Molenda 
3352fd83355SJason Molenda     ValueList argument_values;
3362fd83355SJason Molenda 
3372fd83355SJason Molenda     return_buffer_ptr_value.GetScalar() = m_get_item_info_return_buffer_addr;
3382fd83355SJason Molenda     argument_values.PushValue (return_buffer_ptr_value);
3392fd83355SJason Molenda 
3402fd83355SJason Molenda     debug_value.GetScalar() = 0;
3412fd83355SJason Molenda     argument_values.PushValue (debug_value);
3422fd83355SJason Molenda 
3432fd83355SJason Molenda     item_value.GetScalar() = item;
3442fd83355SJason Molenda     argument_values.PushValue (item_value);
3452fd83355SJason Molenda 
3462fd83355SJason Molenda     if (page_to_free != LLDB_INVALID_ADDRESS)
3472fd83355SJason Molenda         page_to_free_value.GetScalar() = page_to_free;
3482fd83355SJason Molenda     else
3492fd83355SJason Molenda         page_to_free_value.GetScalar() = 0;
3502fd83355SJason Molenda     argument_values.PushValue (page_to_free_value);
3512fd83355SJason Molenda 
3522fd83355SJason Molenda     page_to_free_size_value.GetScalar() = page_to_free_size;
3532fd83355SJason Molenda     argument_values.PushValue (page_to_free_size_value);
3542fd83355SJason Molenda 
3552fd83355SJason Molenda     addr_t args_addr = SetupGetItemInfoFunction (thread, argument_values);
3562fd83355SJason Molenda 
3572fd83355SJason Molenda     StreamString errors;
3582fd83355SJason Molenda     ExecutionContext exe_ctx;
3592fd83355SJason Molenda     EvaluateExpressionOptions options;
3602fd83355SJason Molenda     options.SetUnwindOnError (true);
3612fd83355SJason Molenda     options.SetIgnoreBreakpoints (true);
3622fd83355SJason Molenda     options.SetStopOthers (true);
363a0560152SJason Molenda     options.SetTimeoutUsec(500000);
364a0560152SJason Molenda     options.SetTryAllThreads (false);
3652fd83355SJason Molenda     thread.CalculateExecutionContext (exe_ctx);
3662fd83355SJason Molenda 
3672fd83355SJason Molenda     if (m_get_item_info_function == NULL)
3682fd83355SJason Molenda     {
3692fd83355SJason Molenda         error.SetErrorString ("Unable to compile function to call __introspection_dispatch_queue_item_get_info");
3702fd83355SJason Molenda         return return_value;
3712fd83355SJason Molenda     }
3722fd83355SJason Molenda 
3732fd83355SJason Molenda 
3741624a2d3SJim Ingham     ExpressionResults func_call_ret;
3752fd83355SJason Molenda     Value results;
3762fd83355SJason Molenda     func_call_ret =  m_get_item_info_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
3778646d3c1SJim Ingham     if (func_call_ret != eExpressionCompleted || !error.Success())
3782fd83355SJason Molenda     {
3792fd83355SJason Molenda         if (log)
3801624a2d3SJim Ingham             log->Printf ("Unable to call __introspection_dispatch_queue_item_get_info(), got ExpressionResults %d, error contains %s", func_call_ret, error.AsCString(""));
3812fd83355SJason Molenda         error.SetErrorString ("Unable to call __introspection_dispatch_queue_get_item_info() for list of queues");
3822fd83355SJason Molenda         return return_value;
3832fd83355SJason Molenda     }
3842fd83355SJason Molenda 
3852fd83355SJason Molenda     return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
3862fd83355SJason Molenda     if (!error.Success() || return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS)
3872fd83355SJason Molenda     {
3882fd83355SJason Molenda         return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
3892fd83355SJason Molenda         return return_value;
3902fd83355SJason Molenda     }
3912fd83355SJason Molenda 
3922fd83355SJason Molenda     return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_item_info_return_buffer_addr + 8, 8, 0, error);
3932fd83355SJason Molenda 
3942fd83355SJason Molenda     if (!error.Success())
3952fd83355SJason Molenda     {
3962fd83355SJason Molenda         return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
3972fd83355SJason Molenda         return return_value;
3982fd83355SJason Molenda     }
3992a6c252dSJason Molenda     if (log)
4002a6c252dSJason Molenda         log->Printf ("AppleGetItemInfoHandler called __introspection_dispatch_queue_item_get_info (page_to_free == 0x%" PRIx64 ", size = %" PRId64 "), returned page is at 0x%" PRIx64 ", size %" PRId64, page_to_free, page_to_free_size, return_value.item_buffer_ptr, return_value.item_buffer_size);
4012a6c252dSJason Molenda 
4022fd83355SJason Molenda 
4032fd83355SJason Molenda     return return_value;
4042fd83355SJason Molenda }
405