1 //===-- CommandObjectExpression.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 #include "CommandObjectExpression.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Interpreter/Args.h" 17 #include "lldb/Core/Value.h" 18 #include "lldb/Core/InputReader.h" 19 #include "lldb/Expression/ClangExpression.h" 20 #include "lldb/Expression/ClangExpressionDeclMap.h" 21 #include "lldb/Expression/ClangExpressionVariable.h" 22 #include "lldb/Expression/ClangPersistentVariables.h" 23 #include "lldb/Expression/ClangFunction.h" 24 #include "lldb/Expression/DWARFExpression.h" 25 #include "lldb/Host/Host.h" 26 #include "lldb/Core/Debugger.h" 27 #include "lldb/Interpreter/CommandInterpreter.h" 28 #include "lldb/Interpreter/CommandReturnObject.h" 29 #include "lldb/Symbol/ObjectFile.h" 30 #include "lldb/Symbol/Variable.h" 31 #include "lldb/Target/Process.h" 32 #include "lldb/Target/StackFrame.h" 33 #include "lldb/Target/Target.h" 34 #include "llvm/ADT/StringRef.h" 35 36 using namespace lldb; 37 using namespace lldb_private; 38 39 CommandObjectExpression::CommandOptions::CommandOptions () : 40 Options() 41 { 42 // Keep only one place to reset the values to their defaults 43 ResetOptionValues(); 44 } 45 46 47 CommandObjectExpression::CommandOptions::~CommandOptions () 48 { 49 } 50 51 Error 52 CommandObjectExpression::CommandOptions::SetOptionValue (int option_idx, const char *option_arg) 53 { 54 Error error; 55 56 char short_option = (char) m_getopt_table[option_idx].val; 57 58 switch (short_option) 59 { 60 case 'l': 61 if (language.SetLanguageFromCString (option_arg) == false) 62 { 63 error.SetErrorStringWithFormat("Invalid language option argument '%s'.\n", option_arg); 64 } 65 break; 66 67 case 'g': 68 debug = true; 69 break; 70 71 case 'f': 72 error = Args::StringToFormat(option_arg, format); 73 break; 74 75 default: 76 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); 77 break; 78 } 79 80 return error; 81 } 82 83 void 84 CommandObjectExpression::CommandOptions::ResetOptionValues () 85 { 86 Options::ResetOptionValues(); 87 language.Clear(); 88 debug = false; 89 format = eFormatDefault; 90 show_types = true; 91 show_summary = true; 92 } 93 94 const lldb::OptionDefinition* 95 CommandObjectExpression::CommandOptions::GetDefinitions () 96 { 97 return g_option_table; 98 } 99 100 CommandObjectExpression::CommandObjectExpression () : 101 CommandObject ( 102 "expression", 103 "Evaluate a C expression in the current program context, using variables currently in scope.", 104 "expression [<cmd-options>] <expr>"), 105 m_expr_line_count (0), 106 m_expr_lines () 107 { 108 SetHelpLong( 109 "Examples: \n\ 110 \n\ 111 expr my_struct->a = my_array[3] \n\ 112 expr -f bin -- (index * 8) + 5 \n\ 113 expr char c[] = \"foo\"; c[0]\n"); 114 } 115 116 CommandObjectExpression::~CommandObjectExpression () 117 { 118 } 119 120 Options * 121 CommandObjectExpression::GetOptions () 122 { 123 return &m_options; 124 } 125 126 127 bool 128 CommandObjectExpression::Execute 129 ( 130 CommandInterpreter &interpreter, 131 Args& command, 132 CommandReturnObject &result 133 ) 134 { 135 return false; 136 } 137 138 139 size_t 140 CommandObjectExpression::MultiLineExpressionCallback 141 ( 142 void *baton, 143 InputReader &reader, 144 lldb::InputReaderAction notification, 145 const char *bytes, 146 size_t bytes_len 147 ) 148 { 149 CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton; 150 151 switch (notification) 152 { 153 case eInputReaderActivate: 154 reader.GetDebugger().GetOutputStream().Printf("%s\n", "Enter expressions, then terminate with an empty line to evaluate:"); 155 // Fall through 156 case eInputReaderReactivate: 157 //if (out_fh) 158 // reader.GetDebugger().GetOutputStream().Printf ("%3u: ", cmd_object_expr->m_expr_line_count); 159 break; 160 161 case eInputReaderDeactivate: 162 break; 163 164 case eInputReaderGotToken: 165 ++cmd_object_expr->m_expr_line_count; 166 if (bytes && bytes_len) 167 { 168 cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1); 169 } 170 171 if (bytes_len == 0) 172 reader.SetIsDone(true); 173 //else if (out_fh && !reader->IsDone()) 174 // ::fprintf (out_fh, "%3u: ", cmd_object_expr->m_expr_line_count); 175 break; 176 177 case eInputReaderDone: 178 { 179 bool bare = false; 180 cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(), 181 bare, 182 reader.GetDebugger().GetOutputStream(), 183 reader.GetDebugger().GetErrorStream()); 184 } 185 break; 186 } 187 188 return bytes_len; 189 } 190 191 bool 192 CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream &output_stream, Stream &error_stream) 193 { 194 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 195 196 //////////////////////////////////// 197 // Set up the target and compiler 198 // 199 200 Target *target = m_exe_ctx.target; 201 202 if (!target) 203 { 204 error_stream.PutCString ("error: invalid target\n"); 205 return false; 206 } 207 208 ConstString target_triple; 209 210 target->GetTargetTriple (target_triple); 211 212 if (!target_triple) 213 target_triple = Host::GetTargetTriple (); 214 215 if (!target_triple) 216 { 217 error_stream.PutCString ("error: invalid target triple\n"); 218 return false; 219 } 220 221 ClangExpressionDeclMap expr_decl_map (&m_exe_ctx); 222 ClangExpression clang_expr (target_triple.AsCString (), &expr_decl_map); 223 224 ////////////////////////// 225 // Parse the expression 226 // 227 228 unsigned num_errors; 229 230 if (bare) 231 num_errors = clang_expr.ParseBareExpression (llvm::StringRef (expr), error_stream); 232 else 233 num_errors = clang_expr.ParseExpression (expr, error_stream, true); 234 235 if (num_errors) 236 { 237 error_stream.Printf ("error: %d errors parsing expression\n", num_errors); 238 return false; 239 } 240 241 /////////////////////////////////////////////// 242 // Convert the output of the parser to DWARF 243 // 244 245 StreamString dwarf_opcodes; 246 dwarf_opcodes.SetByteOrder (eByteOrderHost); 247 dwarf_opcodes.GetFlags ().Set (Stream::eBinary); 248 249 ClangExpressionVariableList expr_local_vars; 250 251 bool success; 252 bool canInterpret = false; 253 254 clang::ASTContext *ast_context = clang_expr.GetASTContext (); 255 Value expr_result; 256 Error expr_error; 257 258 canInterpret = clang_expr.ConvertIRToDWARF (expr_local_vars, dwarf_opcodes); 259 260 if (canInterpret) 261 { 262 if (log) 263 log->Printf("Code can be interpreted."); 264 success = true; 265 } 266 else 267 { 268 if (log) 269 log->Printf("Code cannot be interpreted and must be run in the target."); 270 success = clang_expr.PrepareIRForTarget (expr_local_vars); 271 } 272 273 if (!success) 274 { 275 error_stream.PutCString ("error: expression couldn't be converted to IR\n"); 276 return false; 277 } 278 279 if (canInterpret) 280 { 281 // TODO interpret IR 282 return false; 283 } 284 else 285 { 286 if (!clang_expr.JITFunction (m_exe_ctx, "___clang_expr")) 287 { 288 error_stream.PutCString ("error: IR could not be JIT compiled\n"); 289 return false; 290 } 291 292 if (!clang_expr.WriteJITCode (m_exe_ctx)) 293 { 294 error_stream.PutCString ("error: JIT code could not be written to the target\n"); 295 return false; 296 } 297 298 lldb::addr_t function_address(clang_expr.GetFunctionAddress ("___clang_expr")); 299 300 if (function_address == LLDB_INVALID_ADDRESS) 301 { 302 error_stream.PutCString ("JIT compiled code's address couldn't be found\n"); 303 return false; 304 } 305 306 lldb::addr_t struct_address; 307 308 if (!expr_decl_map.Materialize(&m_exe_ctx, struct_address, expr_error)) 309 { 310 error_stream.Printf ("Couldn't materialize struct: %s\n", expr_error.AsCString("unknown error")); 311 return false; 312 } 313 314 if (log) 315 { 316 log->Printf("Function address : 0x%llx", (uint64_t)function_address); 317 log->Printf("Structure address : 0x%llx", (uint64_t)struct_address); 318 319 StreamString insns; 320 321 Error err = clang_expr.DisassembleFunction(insns, m_exe_ctx, "___clang_expr"); 322 323 if (!err.Success()) 324 { 325 log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error")); 326 } 327 else 328 { 329 log->Printf("Function disassembly:\n%s", insns.GetData()); 330 } 331 332 StreamString args; 333 334 if (!expr_decl_map.DumpMaterializedStruct(&m_exe_ctx, args, err)) 335 { 336 log->Printf("Couldn't extract variable values : %s", err.AsCString("unknown error")); 337 } 338 else 339 { 340 log->Printf("Structure contents:\n%s", args.GetData()); 341 } 342 } 343 344 ClangFunction::ExecutionResults execution_result = 345 ClangFunction::ExecuteFunction (m_exe_ctx, function_address, struct_address, true, true, 10000, error_stream); 346 347 if (execution_result != ClangFunction::eExecutionCompleted) 348 { 349 const char *result_name; 350 351 switch (execution_result) 352 { 353 case ClangFunction::eExecutionCompleted: 354 result_name = "eExecutionCompleted"; 355 break; 356 case ClangFunction::eExecutionDiscarded: 357 result_name = "eExecutionDiscarded"; 358 break; 359 case ClangFunction::eExecutionInterrupted: 360 result_name = "eExecutionInterrupted"; 361 break; 362 case ClangFunction::eExecutionSetupError: 363 result_name = "eExecutionSetupError"; 364 break; 365 case ClangFunction::eExecutionTimedOut: 366 result_name = "eExecutionTimedOut"; 367 break; 368 } 369 370 error_stream.Printf ("Couldn't execute function; result was %s\n", result_name); 371 return false; 372 } 373 374 if (!expr_decl_map.Dematerialize(&m_exe_ctx, expr_result, expr_error)) 375 { 376 error_stream.Printf ("Couldn't dematerialize struct: %s\n", expr_error.AsCString("unknown error")); 377 return false; 378 } 379 } 380 381 /////////////////////////////////////// 382 // Interpret the result and print it 383 // 384 385 lldb::Format format = m_options.format; 386 387 // Resolve any values that are possible 388 expr_result.ResolveValue (&m_exe_ctx, ast_context); 389 390 if (expr_result.GetContextType () == Value::eContextTypeInvalid && 391 expr_result.GetValueType () == Value::eValueTypeScalar && 392 format == eFormatDefault) 393 { 394 // The expression result is just a scalar with no special formatting 395 expr_result.GetScalar ().GetValue (&output_stream, m_options.show_types); 396 output_stream.EOL (); 397 return true; 398 } 399 400 // The expression result is more complext and requires special handling 401 DataExtractor data; 402 expr_error = expr_result.GetValueAsData (&m_exe_ctx, ast_context, data, 0); 403 404 if (!expr_error.Success ()) 405 { 406 error_stream.Printf ("error: couldn't resolve result value: %s\n", expr_error.AsCString ()); 407 return false; 408 } 409 410 if (format == eFormatDefault) 411 format = expr_result.GetValueDefaultFormat (); 412 413 void *clang_type = expr_result.GetValueOpaqueClangQualType (); 414 415 if (clang_type) 416 { 417 if (m_options.show_types) 418 output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString()); 419 420 ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to 421 clang_type, // The opaque clang type we want to dump that value of 422 &m_exe_ctx, // The execution context for memory and variable access 423 &output_stream, // Stream to dump to 424 format, // Format to use when dumping 425 data, // A buffer containing the bytes for the clang type 426 0, // Byte offset within "data" where value is 427 data.GetByteSize (), // Size in bytes of the value we are dumping 428 0, // Bitfield bit size 429 0, // Bitfield bit offset 430 m_options.show_types, // Show types? 431 m_options.show_summary, // Show summary? 432 m_options.debug, // Debug logging output? 433 UINT32_MAX); // Depth to dump in case this is an aggregate type 434 } 435 else 436 { 437 data.Dump (&output_stream, // Stream to dump to 438 0, // Byte offset within "data" 439 format, // Format to use when dumping 440 data.GetByteSize (), // Size in bytes of each item we are dumping 441 1, // Number of items to dump 442 UINT32_MAX, // Number of items per line 443 LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context 444 0, // Bitfield bit size 445 0); // Bitfield bit offset 446 } 447 output_stream.EOL(); 448 449 return true; 450 } 451 452 bool 453 CommandObjectExpression::ExecuteRawCommandString 454 ( 455 CommandInterpreter &interpreter, 456 const char *command, 457 CommandReturnObject &result 458 ) 459 { 460 m_exe_ctx = interpreter.GetDebugger().GetExecutionContext(); 461 462 m_options.ResetOptionValues(); 463 464 const char * expr = NULL; 465 466 if (command[0] == '\0') 467 { 468 m_expr_lines.clear(); 469 m_expr_line_count = 0; 470 471 InputReaderSP reader_sp (new InputReader(interpreter.GetDebugger())); 472 if (reader_sp) 473 { 474 Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback, 475 this, // baton 476 eInputReaderGranularityLine, // token size, to pass to callback function 477 NULL, // end token 478 NULL, // prompt 479 true)); // echo input 480 if (err.Success()) 481 { 482 interpreter.GetDebugger().PushInputReader (reader_sp); 483 result.SetStatus (eReturnStatusSuccessFinishNoResult); 484 } 485 else 486 { 487 result.AppendError (err.AsCString()); 488 result.SetStatus (eReturnStatusFailed); 489 } 490 } 491 else 492 { 493 result.AppendError("out of memory"); 494 result.SetStatus (eReturnStatusFailed); 495 } 496 return result.Succeeded(); 497 } 498 499 if (command[0] == '-') 500 { 501 // We have some options and these options MUST end with --. 502 const char *end_options = NULL; 503 const char *s = command; 504 while (s && s[0]) 505 { 506 end_options = ::strstr (s, "--"); 507 if (end_options) 508 { 509 end_options += 2; // Get past the "--" 510 if (::isspace (end_options[0])) 511 { 512 expr = end_options; 513 while (::isspace (*expr)) 514 ++expr; 515 break; 516 } 517 } 518 s = end_options; 519 } 520 521 if (end_options) 522 { 523 Args args (command, end_options - command); 524 if (!ParseOptions (interpreter, args, result)) 525 return false; 526 } 527 } 528 529 if (expr == NULL) 530 expr = command; 531 532 return EvaluateExpression (expr, false, result.GetOutputStream(), result.GetErrorStream()); 533 } 534 535 lldb::OptionDefinition 536 CommandObjectExpression::CommandOptions::g_option_table[] = 537 { 538 { LLDB_OPT_SET_ALL, false, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."}, 539 { LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]", "Specify the format that the expression output should use."}, 540 { LLDB_OPT_SET_ALL, false, "debug", 'g', no_argument, NULL, 0, NULL, "Enable verbose debug logging of the expression parsing and evaluation."}, 541 { LLDB_OPT_SET_ALL, false, "use-ir", 'i', no_argument, NULL, 0, NULL, "[Temporary] Instructs the expression evaluator to use IR instead of ASTs."}, 542 { 0, false, NULL, 0, 0, NULL, NULL, NULL, NULL } 543 }; 544 545