Home | History | Annotate | Download | only in Expression
      1 //===-- ClangUserExpression.cpp ---------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // C Includes
     11 #include <stdio.h>
     12 #if HAVE_SYS_TYPES_H
     13 #  include <sys/types.h>
     14 #endif
     15 
     16 // C++ Includes
     17 #include <cstdlib>
     18 #include <string>
     19 #include <map>
     20 
     21 #include "lldb/Core/ConstString.h"
     22 #include "lldb/Core/Log.h"
     23 #include "lldb/Core/StreamFile.h"
     24 #include "lldb/Core/StreamString.h"
     25 #include "lldb/Core/ValueObjectConstResult.h"
     26 #include "lldb/Expression/ASTResultSynthesizer.h"
     27 #include "lldb/Expression/ClangExpressionDeclMap.h"
     28 #include "lldb/Expression/ClangExpressionParser.h"
     29 #include "lldb/Expression/ClangFunction.h"
     30 #include "lldb/Expression/ClangUserExpression.h"
     31 #include "lldb/Expression/ExpressionSourceCode.h"
     32 #include "lldb/Expression/IRExecutionUnit.h"
     33 #include "lldb/Expression/IRInterpreter.h"
     34 #include "lldb/Expression/Materializer.h"
     35 #include "lldb/Host/Host.h"
     36 #include "lldb/Symbol/Block.h"
     37 #include "lldb/Symbol/ClangASTContext.h"
     38 #include "lldb/Symbol/Function.h"
     39 #include "lldb/Symbol/Type.h"
     40 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
     41 #include "lldb/Symbol/VariableList.h"
     42 #include "lldb/Target/ExecutionContext.h"
     43 #include "lldb/Target/Process.h"
     44 #include "lldb/Target/StackFrame.h"
     45 #include "lldb/Target/Target.h"
     46 #include "lldb/Target/ThreadPlan.h"
     47 #include "lldb/Target/ThreadPlanCallUserExpression.h"
     48 
     49 #include "clang/AST/DeclCXX.h"
     50 #include "clang/AST/DeclObjC.h"
     51 
     52 using namespace lldb_private;
     53 
     54 ClangUserExpression::ClangUserExpression (const char *expr,
     55                                           const char *expr_prefix,
     56                                           lldb::LanguageType language,
     57                                           ResultType desired_type) :
     58     ClangExpression (),
     59     m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
     60     m_stack_frame_top (LLDB_INVALID_ADDRESS),
     61     m_expr_text (expr),
     62     m_expr_prefix (expr_prefix ? expr_prefix : ""),
     63     m_language (language),
     64     m_transformed_text (),
     65     m_desired_type (desired_type),
     66     m_enforce_valid_object (true),
     67     m_cplusplus (false),
     68     m_objectivec (false),
     69     m_static_method(false),
     70     m_needs_object_ptr (false),
     71     m_const_object (false),
     72     m_target (NULL),
     73     m_can_interpret (false),
     74     m_materialized_address (LLDB_INVALID_ADDRESS)
     75 {
     76     switch (m_language)
     77     {
     78     case lldb::eLanguageTypeC_plus_plus:
     79         m_allow_cxx = true;
     80         break;
     81     case lldb::eLanguageTypeObjC:
     82         m_allow_objc = true;
     83         break;
     84     case lldb::eLanguageTypeObjC_plus_plus:
     85     default:
     86         m_allow_cxx = true;
     87         m_allow_objc = true;
     88         break;
     89     }
     90 }
     91 
     92 ClangUserExpression::~ClangUserExpression ()
     93 {
     94 }
     95 
     96 clang::ASTConsumer *
     97 ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
     98 {
     99     ClangASTContext *clang_ast_context = m_target->GetScratchClangASTContext();
    100 
    101     if (!clang_ast_context)
    102         return NULL;
    103 
    104     if (!m_result_synthesizer.get())
    105         m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
    106                                                             *m_target));
    107 
    108     return m_result_synthesizer.get();
    109 }
    110 
    111 void
    112 ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
    113 {
    114     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    115 
    116     if (log)
    117         log->Printf("ClangUserExpression::ScanContext()");
    118 
    119     m_target = exe_ctx.GetTargetPtr();
    120 
    121     if (!(m_allow_cxx || m_allow_objc))
    122     {
    123         if (log)
    124             log->Printf("  [CUE::SC] Settings inhibit C++ and Objective-C");
    125         return;
    126     }
    127 
    128     StackFrame *frame = exe_ctx.GetFramePtr();
    129     if (frame == NULL)
    130     {
    131         if (log)
    132             log->Printf("  [CUE::SC] Null stack frame");
    133         return;
    134     }
    135 
    136     SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
    137 
    138     if (!sym_ctx.function)
    139     {
    140         if (log)
    141             log->Printf("  [CUE::SC] Null function");
    142         return;
    143     }
    144 
    145     // Find the block that defines the function represented by "sym_ctx"
    146     Block *function_block = sym_ctx.GetFunctionBlock();
    147 
    148     if (!function_block)
    149     {
    150         if (log)
    151             log->Printf("  [CUE::SC] Null function block");
    152         return;
    153     }
    154 
    155     clang::DeclContext *decl_context = function_block->GetClangDeclContext();
    156 
    157     if (!decl_context)
    158     {
    159         if (log)
    160             log->Printf("  [CUE::SC] Null decl context");
    161         return;
    162     }
    163 
    164     if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
    165     {
    166         if (m_allow_cxx && method_decl->isInstance())
    167         {
    168             if (m_enforce_valid_object)
    169             {
    170                 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
    171 
    172                 const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
    173 
    174                 if (!variable_list_sp)
    175                 {
    176                     err.SetErrorString(thisErrorString);
    177                     return;
    178                 }
    179 
    180                 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
    181 
    182                 if (!this_var_sp ||
    183                     !this_var_sp->IsInScope(frame) ||
    184                     !this_var_sp->LocationIsValidForFrame (frame))
    185                 {
    186                     err.SetErrorString(thisErrorString);
    187                     return;
    188                 }
    189             }
    190 
    191             m_cplusplus = true;
    192             m_needs_object_ptr = true;
    193         }
    194     }
    195     else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
    196     {
    197         if (m_allow_objc)
    198         {
    199             if (m_enforce_valid_object)
    200             {
    201                 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
    202 
    203                 const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
    204 
    205                 if (!variable_list_sp)
    206                 {
    207                     err.SetErrorString(selfErrorString);
    208                     return;
    209                 }
    210 
    211                 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
    212 
    213                 if (!self_variable_sp ||
    214                     !self_variable_sp->IsInScope(frame) ||
    215                     !self_variable_sp->LocationIsValidForFrame (frame))
    216                 {
    217                     err.SetErrorString(selfErrorString);
    218                     return;
    219                 }
    220             }
    221 
    222             m_objectivec = true;
    223             m_needs_object_ptr = true;
    224 
    225             if (!method_decl->isInstanceMethod())
    226                 m_static_method = true;
    227         }
    228     }
    229     else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context))
    230     {
    231         // We might also have a function that said in the debug information that it captured an
    232         // object pointer.  The best way to deal with getting to the ivars at present it by pretending
    233         // that this is a method of a class in whatever runtime the debug info says the object pointer
    234         // belongs to.  Do that here.
    235 
    236         ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl);
    237         if (metadata && metadata->HasObjectPtr())
    238         {
    239             lldb::LanguageType language = metadata->GetObjectPtrLanguage();
    240             if (language == lldb::eLanguageTypeC_plus_plus)
    241             {
    242                 if (m_enforce_valid_object)
    243                 {
    244                     lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
    245 
    246                     const char *thisErrorString = "Stopped in a context claiming to capture a C++ object pointer, but 'this' isn't available; pretending we are in a generic context";
    247 
    248                     if (!variable_list_sp)
    249                     {
    250                         err.SetErrorString(thisErrorString);
    251                         return;
    252                     }
    253 
    254                     lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
    255 
    256                     if (!this_var_sp ||
    257                         !this_var_sp->IsInScope(frame) ||
    258                         !this_var_sp->LocationIsValidForFrame (frame))
    259                     {
    260                         err.SetErrorString(thisErrorString);
    261                         return;
    262                     }
    263                 }
    264 
    265                 m_cplusplus = true;
    266                 m_needs_object_ptr = true;
    267             }
    268             else if (language == lldb::eLanguageTypeObjC)
    269             {
    270                 if (m_enforce_valid_object)
    271                 {
    272                     lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
    273 
    274                     const char *selfErrorString = "Stopped in a context claiming to capture an Objective-C object pointer, but 'self' isn't available; pretending we are in a generic context";
    275 
    276                     if (!variable_list_sp)
    277                     {
    278                         err.SetErrorString(selfErrorString);
    279                         return;
    280                     }
    281 
    282                     lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
    283 
    284                     if (!self_variable_sp ||
    285                         !self_variable_sp->IsInScope(frame) ||
    286                         !self_variable_sp->LocationIsValidForFrame (frame))
    287                     {
    288                         err.SetErrorString(selfErrorString);
    289                         return;
    290                     }
    291 
    292                     Type *self_type = self_variable_sp->GetType();
    293 
    294                     if (!self_type)
    295                     {
    296                         err.SetErrorString(selfErrorString);
    297                         return;
    298                     }
    299 
    300                     ClangASTType self_clang_type = self_type->GetClangForwardType();
    301 
    302                     if (!self_clang_type)
    303                     {
    304                         err.SetErrorString(selfErrorString);
    305                         return;
    306                     }
    307 
    308                     if (self_clang_type.IsObjCClassType())
    309                     {
    310                         return;
    311                     }
    312                     else if (self_clang_type.IsObjCObjectPointerType())
    313                     {
    314                         m_objectivec = true;
    315                         m_needs_object_ptr = true;
    316                     }
    317                     else
    318                     {
    319                         err.SetErrorString(selfErrorString);
    320                         return;
    321                     }
    322                 }
    323                 else
    324                 {
    325                     m_objectivec = true;
    326                     m_needs_object_ptr = true;
    327                 }
    328             }
    329         }
    330     }
    331 }
    332 
    333 void
    334 ClangUserExpression::InstallContext (ExecutionContext &exe_ctx)
    335 {
    336     m_process_wp = exe_ctx.GetProcessSP();
    337 
    338     lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
    339 
    340     if (frame_sp)
    341         m_address = frame_sp->GetFrameCodeAddress();
    342 }
    343 
    344 bool
    345 ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
    346                                           lldb::TargetSP &target_sp,
    347                                           lldb::ProcessSP &process_sp,
    348                                           lldb::StackFrameSP &frame_sp)
    349 {
    350     lldb::ProcessSP expected_process_sp = m_process_wp.lock();
    351     process_sp = exe_ctx.GetProcessSP();
    352 
    353     if (process_sp != expected_process_sp)
    354         return false;
    355 
    356     process_sp = exe_ctx.GetProcessSP();
    357     target_sp = exe_ctx.GetTargetSP();
    358     frame_sp = exe_ctx.GetFrameSP();
    359 
    360     if (m_address.IsValid())
    361     {
    362         if (!frame_sp)
    363             return false;
    364         else
    365             return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
    366     }
    367 
    368     return true;
    369 }
    370 
    371 bool
    372 ClangUserExpression::MatchesContext (ExecutionContext &exe_ctx)
    373 {
    374     lldb::TargetSP target_sp;
    375     lldb::ProcessSP process_sp;
    376     lldb::StackFrameSP frame_sp;
    377 
    378     return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
    379 }
    380 
    381 // This is a really nasty hack, meant to fix Objective-C expressions of the form
    382 // (int)[myArray count].  Right now, because the type information for count is
    383 // not available, [myArray count] returns id, which can't be directly cast to
    384 // int without causing a clang error.
    385 static void
    386 ApplyObjcCastHack(std::string &expr)
    387 {
    388 #define OBJC_CAST_HACK_FROM "(int)["
    389 #define OBJC_CAST_HACK_TO   "(int)(long long)["
    390 
    391     size_t from_offset;
    392 
    393     while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
    394         expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
    395 
    396 #undef OBJC_CAST_HACK_TO
    397 #undef OBJC_CAST_HACK_FROM
    398 }
    399 
    400 // Another hack, meant to allow use of unichar despite it not being available in
    401 // the type information.  Although we could special-case it in type lookup,
    402 // hopefully we'll figure out a way to #include the same environment as is
    403 // present in the original source file rather than try to hack specific type
    404 // definitions in as needed.
    405 static void
    406 ApplyUnicharHack(std::string &expr)
    407 {
    408 #define UNICHAR_HACK_FROM "unichar"
    409 #define UNICHAR_HACK_TO   "unsigned short"
    410 
    411     size_t from_offset;
    412 
    413     while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
    414         expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
    415 
    416 #undef UNICHAR_HACK_TO
    417 #undef UNICHAR_HACK_FROM
    418 }
    419 
    420 bool
    421 ClangUserExpression::Parse (Stream &error_stream,
    422                             ExecutionContext &exe_ctx,
    423                             lldb_private::ExecutionPolicy execution_policy,
    424                             bool keep_result_in_memory)
    425 {
    426     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    427 
    428     Error err;
    429 
    430     InstallContext(exe_ctx);
    431 
    432     ScanContext(exe_ctx, err);
    433 
    434     if (!err.Success())
    435     {
    436         error_stream.Printf("warning: %s\n", err.AsCString());
    437     }
    438 
    439     StreamString m_transformed_stream;
    440 
    441     ////////////////////////////////////
    442     // Generate the expression
    443     //
    444 
    445     ApplyObjcCastHack(m_expr_text);
    446     //ApplyUnicharHack(m_expr_text);
    447 
    448     std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str()));
    449 
    450     lldb::LanguageType lang_type;
    451 
    452     if (m_cplusplus)
    453         lang_type = lldb::eLanguageTypeC_plus_plus;
    454     else if(m_objectivec)
    455         lang_type = lldb::eLanguageTypeObjC;
    456     else
    457         lang_type = lldb::eLanguageTypeC;
    458 
    459     if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method))
    460     {
    461         error_stream.PutCString ("error: couldn't construct expression body");
    462         return false;
    463     }
    464 
    465     if (log)
    466         log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
    467 
    468     ////////////////////////////////////
    469     // Set up the target and compiler
    470     //
    471 
    472     Target *target = exe_ctx.GetTargetPtr();
    473 
    474     if (!target)
    475     {
    476         error_stream.PutCString ("error: invalid target\n");
    477         return false;
    478     }
    479 
    480     //////////////////////////
    481     // Parse the expression
    482     //
    483 
    484     m_materializer_ap.reset(new Materializer());
    485 
    486     m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
    487 
    488     class OnExit
    489     {
    490     public:
    491         typedef std::function <void (void)> Callback;
    492 
    493         OnExit (Callback const &callback) :
    494             m_callback(callback)
    495         {
    496         }
    497 
    498         ~OnExit ()
    499         {
    500             m_callback();
    501         }
    502     private:
    503         Callback m_callback;
    504     };
    505 
    506     OnExit on_exit([this]() { m_expr_decl_map.reset(); });
    507 
    508     if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
    509     {
    510         error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
    511         return false;
    512     }
    513 
    514     Process *process = exe_ctx.GetProcessPtr();
    515     ExecutionContextScope *exe_scope = process;
    516 
    517     if (!exe_scope)
    518         exe_scope = exe_ctx.GetTargetPtr();
    519 
    520     ClangExpressionParser parser(exe_scope, *this);
    521 
    522     unsigned num_errors = parser.Parse (error_stream);
    523 
    524     if (num_errors)
    525     {
    526         error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
    527 
    528         m_expr_decl_map->DidParse();
    529 
    530         return false;
    531     }
    532 
    533     //////////////////////////////////////////////////////////////////////////////////////////
    534     // Prepare the output of the parser for execution, evaluating it statically if possible
    535     //
    536 
    537     Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
    538                                                   m_jit_end_addr,
    539                                                   m_execution_unit_ap,
    540                                                   exe_ctx,
    541                                                   m_can_interpret,
    542                                                   execution_policy);
    543 
    544     if (jit_error.Success())
    545     {
    546         if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
    547             m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
    548         return true;
    549     }
    550     else
    551     {
    552         const char *error_cstr = jit_error.AsCString();
    553         if (error_cstr && error_cstr[0])
    554             error_stream.Printf ("error: %s\n", error_cstr);
    555         else
    556             error_stream.Printf ("error: expression can't be interpreted or run\n");
    557         return false;
    558     }
    559 }
    560 
    561 static lldb::addr_t
    562 GetObjectPointer (lldb::StackFrameSP frame_sp,
    563                   ConstString &object_name,
    564                   Error &err)
    565 {
    566     err.Clear();
    567 
    568     if (!frame_sp)
    569     {
    570         err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
    571         return LLDB_INVALID_ADDRESS;
    572     }
    573 
    574     lldb::VariableSP var_sp;
    575     lldb::ValueObjectSP valobj_sp;
    576 
    577     valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
    578                                                             lldb::eNoDynamicValues,
    579                                                             StackFrame::eExpressionPathOptionCheckPtrVsMember ||
    580                                                             StackFrame::eExpressionPathOptionsAllowDirectIVarAccess ||
    581                                                             StackFrame::eExpressionPathOptionsNoFragileObjcIvar ||
    582                                                             StackFrame::eExpressionPathOptionsNoSyntheticChildren ||
    583                                                             StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
    584                                                             var_sp,
    585                                                             err);
    586 
    587     if (!err.Success())
    588         return LLDB_INVALID_ADDRESS;
    589 
    590     lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
    591 
    592     if (ret == LLDB_INVALID_ADDRESS)
    593     {
    594         err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
    595         return LLDB_INVALID_ADDRESS;
    596     }
    597 
    598     return ret;
    599 }
    600 
    601 bool
    602 ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
    603                                                     ExecutionContext &exe_ctx,
    604                                                     lldb::addr_t &struct_address,
    605                                                     lldb::addr_t &object_ptr,
    606                                                     lldb::addr_t &cmd_ptr)
    607 {
    608     lldb::TargetSP target;
    609     lldb::ProcessSP process;
    610     lldb::StackFrameSP frame;
    611 
    612     if (!LockAndCheckContext(exe_ctx,
    613                              target,
    614                              process,
    615                              frame))
    616     {
    617         error_stream.Printf("The context has changed before we could JIT the expression!\n");
    618         return false;
    619     }
    620 
    621     if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
    622     {
    623         if (m_needs_object_ptr)
    624         {
    625             ConstString object_name;
    626 
    627             if (m_cplusplus)
    628             {
    629                 object_name.SetCString("this");
    630             }
    631             else if (m_objectivec)
    632             {
    633                 object_name.SetCString("self");
    634             }
    635             else
    636             {
    637                 error_stream.Printf("Need object pointer but don't know the language\n");
    638                 return false;
    639             }
    640 
    641             Error object_ptr_error;
    642 
    643             object_ptr = GetObjectPointer(frame, object_name, object_ptr_error);
    644 
    645             if (!object_ptr_error.Success())
    646             {
    647                 error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
    648                 object_ptr = 0;
    649             }
    650 
    651             if (m_objectivec)
    652             {
    653                 ConstString cmd_name("_cmd");
    654 
    655                 cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error);
    656 
    657                 if (!object_ptr_error.Success())
    658                 {
    659                     error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
    660                     cmd_ptr = 0;
    661                 }
    662             }
    663         }
    664 
    665         if (m_materialized_address == LLDB_INVALID_ADDRESS)
    666         {
    667             Error alloc_error;
    668 
    669             IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
    670 
    671             m_materialized_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(),
    672                                                                  m_materializer_ap->GetStructAlignment(),
    673                                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
    674                                                                  policy,
    675                                                                  alloc_error);
    676 
    677             if (!alloc_error.Success())
    678             {
    679                 error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
    680                 return false;
    681             }
    682         }
    683 
    684         struct_address = m_materialized_address;
    685 
    686         if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
    687         {
    688             Error alloc_error;
    689 
    690             const size_t stack_frame_size = 512 * 1024;
    691 
    692             m_stack_frame_bottom = m_execution_unit_ap->Malloc(stack_frame_size,
    693                                                                8,
    694                                                                lldb::ePermissionsReadable | lldb::ePermissionsWritable,
    695                                                                IRMemoryMap::eAllocationPolicyHostOnly,
    696                                                                alloc_error);
    697 
    698             m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
    699 
    700             if (!alloc_error.Success())
    701             {
    702                 error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
    703                 return false;
    704             }
    705         }
    706 
    707         Error materialize_error;
    708 
    709         m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_ap, struct_address, materialize_error);
    710 
    711         if (!materialize_error.Success())
    712         {
    713             error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
    714             return false;
    715         }
    716     }
    717     return true;
    718 }
    719 
    720 ThreadPlan *
    721 ClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream,
    722                                                           ExecutionContext &exe_ctx)
    723 {
    724     lldb::addr_t struct_address;
    725 
    726     lldb::addr_t object_ptr = 0;
    727     lldb::addr_t cmd_ptr = 0;
    728 
    729     PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr);
    730 
    731     // FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the
    732     // ClangUserExpression resources before the thread plan finishes execution in the target.  But because we are
    733     // forcing unwind_on_error to be true here, in practical terms that can't happen.
    734 
    735     const bool stop_others = true;
    736     const bool unwind_on_error = true;
    737     const bool ignore_breakpoints = false;
    738     return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
    739                                                        m_jit_start_addr,
    740                                                        struct_address,
    741                                                        error_stream,
    742                                                        stop_others,
    743                                                        unwind_on_error,
    744                                                        ignore_breakpoints,
    745                                                        (m_needs_object_ptr ? &object_ptr : NULL),
    746                                                        (m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
    747 }
    748 
    749 bool
    750 ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
    751                                            ExecutionContext &exe_ctx,
    752                                            lldb::ClangExpressionVariableSP &result,
    753                                            lldb::addr_t function_stack_bottom,
    754                                            lldb::addr_t function_stack_top)
    755 {
    756     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    757 
    758     if (log)
    759         log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
    760 
    761     if (!m_dematerializer_sp)
    762     {
    763         error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
    764         return false;
    765     }
    766 
    767     Error dematerialize_error;
    768 
    769     m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
    770 
    771     if (!dematerialize_error.Success())
    772     {
    773         error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
    774         return false;
    775     }
    776 
    777     if (result)
    778         result->TransferAddress();
    779 
    780     m_dematerializer_sp.reset();
    781 
    782     return true;
    783 }
    784 
    785 ExecutionResults
    786 ClangUserExpression::Execute (Stream &error_stream,
    787                               ExecutionContext &exe_ctx,
    788                               bool unwind_on_error,
    789                               bool ignore_breakpoints,
    790                               ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
    791                               lldb::ClangExpressionVariableSP &result,
    792                               bool run_others,
    793                               uint32_t timeout_usec)
    794 {
    795     // The expression log is quite verbose, and if you're just tracking the execution of the
    796     // expression, it's quite convenient to have these logs come out with the STEP log as well.
    797     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
    798 
    799     if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
    800     {
    801         lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
    802 
    803         lldb::addr_t object_ptr = 0;
    804         lldb::addr_t cmd_ptr = 0;
    805 
    806         if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
    807         {
    808             error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
    809             return eExecutionSetupError;
    810         }
    811 
    812         lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
    813         lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
    814 
    815         if (m_can_interpret)
    816         {
    817             llvm::Module *module = m_execution_unit_ap->GetModule();
    818             llvm::Function *function = m_execution_unit_ap->GetFunction();
    819 
    820             if (!module || !function)
    821             {
    822                 error_stream.Printf("Supposed to interpret, but nothing is there");
    823                 return eExecutionSetupError;
    824             }
    825 
    826             Error interpreter_error;
    827 
    828             llvm::SmallVector <lldb::addr_t, 3> args;
    829 
    830             if (m_needs_object_ptr)
    831             {
    832                 args.push_back(object_ptr);
    833 
    834                 if (m_objectivec)
    835                     args.push_back(cmd_ptr);
    836             }
    837 
    838             args.push_back(struct_address);
    839 
    840             function_stack_bottom = m_stack_frame_bottom;
    841             function_stack_top = m_stack_frame_top;
    842 
    843             IRInterpreter::Interpret (*module,
    844                                       *function,
    845                                       args,
    846                                       *m_execution_unit_ap.get(),
    847                                       interpreter_error,
    848                                       function_stack_bottom,
    849                                       function_stack_top);
    850 
    851             if (!interpreter_error.Success())
    852             {
    853                 error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
    854                 return eExecutionDiscarded;
    855             }
    856         }
    857         else
    858         {
    859             const bool stop_others = true;
    860             const bool try_all_threads = run_others;
    861 
    862             Address wrapper_address (m_jit_start_addr);
    863             lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
    864                                                                               wrapper_address,
    865                                                                               struct_address,
    866                                                                               stop_others,
    867                                                                               unwind_on_error,
    868                                                                               ignore_breakpoints,
    869                                                                               (m_needs_object_ptr ? &object_ptr : NULL),
    870                                                                               ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
    871                                                                               shared_ptr_to_me));
    872 
    873             if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
    874                 return eExecutionSetupError;
    875 
    876             lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
    877 
    878             function_stack_bottom = function_stack_pointer - Host::GetPageSize();
    879             function_stack_top = function_stack_pointer;
    880 
    881             if (log)
    882                 log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
    883 
    884             if (exe_ctx.GetProcessPtr())
    885                 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
    886 
    887             ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
    888                                                                                        call_plan_sp,
    889                                                                                        stop_others,
    890                                                                                        try_all_threads,
    891                                                                                        unwind_on_error,
    892                                                                                        ignore_breakpoints,
    893                                                                                        timeout_usec,
    894                                                                                        error_stream);
    895 
    896             if (exe_ctx.GetProcessPtr())
    897                 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
    898 
    899             if (log)
    900                 log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
    901 
    902             if (execution_result == eExecutionInterrupted || execution_result == eExecutionHitBreakpoint)
    903             {
    904                 const char *error_desc = NULL;
    905 
    906                 if (call_plan_sp)
    907                 {
    908                     lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
    909                     if (real_stop_info_sp)
    910                         error_desc = real_stop_info_sp->GetDescription();
    911                 }
    912                 if (error_desc)
    913                     error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
    914                 else
    915                     error_stream.Printf ("Execution was interrupted.");
    916 
    917                 if ((execution_result == eExecutionInterrupted && unwind_on_error)
    918                     || (execution_result == eExecutionHitBreakpoint && ignore_breakpoints))
    919                     error_stream.Printf ("\nThe process has been returned to the state before expression evaluation.");
    920                 else
    921                     error_stream.Printf ("\nThe process has been left at the point where it was interrupted, use \"thread return -x\" to return to the state before expression evaluation.");
    922 
    923                 return execution_result;
    924             }
    925             else if (execution_result != eExecutionCompleted)
    926             {
    927                 error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
    928                 return execution_result;
    929             }
    930         }
    931 
    932         if  (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
    933         {
    934             return eExecutionCompleted;
    935         }
    936         else
    937         {
    938             return eExecutionSetupError;
    939         }
    940     }
    941     else
    942     {
    943         error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
    944         return eExecutionSetupError;
    945     }
    946 }
    947 
    948 ExecutionResults
    949 ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
    950                                lldb_private::ExecutionPolicy execution_policy,
    951                                lldb::LanguageType language,
    952                                ResultType desired_type,
    953                                bool unwind_on_error,
    954                                bool ignore_breakpoints,
    955                                const char *expr_cstr,
    956                                const char *expr_prefix,
    957                                lldb::ValueObjectSP &result_valobj_sp,
    958                                bool run_others,
    959                                uint32_t timeout_usec)
    960 {
    961     Error error;
    962     return EvaluateWithError (exe_ctx,
    963                               execution_policy,
    964                               language,
    965                               desired_type,
    966                               unwind_on_error,
    967                               ignore_breakpoints,
    968                               expr_cstr,
    969                               expr_prefix,
    970                               result_valobj_sp,
    971                               error,
    972                               run_others,
    973                               timeout_usec);
    974 }
    975 
    976 ExecutionResults
    977 ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
    978                                         lldb_private::ExecutionPolicy execution_policy,
    979                                         lldb::LanguageType language,
    980                                         ResultType desired_type,
    981                                         bool unwind_on_error,
    982                                         bool ignore_breakpoints,
    983                                         const char *expr_cstr,
    984                                         const char *expr_prefix,
    985                                         lldb::ValueObjectSP &result_valobj_sp,
    986                                         Error &error,
    987                                         bool run_others,
    988                                         uint32_t timeout_usec)
    989 {
    990     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
    991 
    992     ExecutionResults execution_results = eExecutionSetupError;
    993 
    994     Process *process = exe_ctx.GetProcessPtr();
    995 
    996     if (process == NULL || process->GetState() != lldb::eStateStopped)
    997     {
    998         if (execution_policy == eExecutionPolicyAlways)
    999         {
   1000             if (log)
   1001                 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
   1002 
   1003             error.SetErrorString ("expression needed to run but couldn't");
   1004 
   1005             return execution_results;
   1006         }
   1007     }
   1008 
   1009     if (process == NULL || !process->CanJIT())
   1010         execution_policy = eExecutionPolicyNever;
   1011 
   1012     ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type));
   1013 
   1014     StreamString error_stream;
   1015 
   1016     if (log)
   1017         log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
   1018 
   1019     const bool keep_expression_in_memory = true;
   1020 
   1021     if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory))
   1022     {
   1023         if (error_stream.GetString().empty())
   1024             error.SetErrorString ("expression failed to parse, unknown error");
   1025         else
   1026             error.SetErrorString (error_stream.GetString().c_str());
   1027     }
   1028     else
   1029     {
   1030         lldb::ClangExpressionVariableSP expr_result;
   1031 
   1032         if (execution_policy == eExecutionPolicyNever &&
   1033             !user_expression_sp->CanInterpret())
   1034         {
   1035             if (log)
   1036                 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
   1037 
   1038             if (error_stream.GetString().empty())
   1039                 error.SetErrorString ("expression needed to run but couldn't");
   1040         }
   1041         else
   1042         {
   1043             error_stream.GetString().clear();
   1044 
   1045             if (log)
   1046                 log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
   1047 
   1048             execution_results = user_expression_sp->Execute (error_stream,
   1049                                                              exe_ctx,
   1050                                                              unwind_on_error,
   1051                                                              ignore_breakpoints,
   1052                                                              user_expression_sp,
   1053                                                              expr_result,
   1054                                                              run_others,
   1055                                                              timeout_usec);
   1056 
   1057             if (execution_results != eExecutionCompleted)
   1058             {
   1059                 if (log)
   1060                     log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
   1061 
   1062                 if (error_stream.GetString().empty())
   1063                     error.SetErrorString ("expression failed to execute, unknown error");
   1064                 else
   1065                     error.SetErrorString (error_stream.GetString().c_str());
   1066             }
   1067             else
   1068             {
   1069                 if (expr_result)
   1070                 {
   1071                     result_valobj_sp = expr_result->GetValueObject();
   1072 
   1073                     if (log)
   1074                         log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString());
   1075                 }
   1076                 else
   1077                 {
   1078                     if (log)
   1079                         log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
   1080 
   1081                     error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
   1082                 }
   1083             }
   1084         }
   1085     }
   1086 
   1087     if (result_valobj_sp.get() == NULL)
   1088         result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
   1089 
   1090     return execution_results;
   1091 }
   1092