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 ClangPersistentVariable *expr_result = 0; 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 if (expr_result) 382 { 383 StreamString ss; 384 385 Error err = expr_result->Print (ss, 386 m_exe_ctx, 387 m_options.format, 388 m_options.show_types, 389 m_options.show_summary, 390 m_options.debug); 391 392 if (err.Success()) 393 output_stream.PutCString(ss.GetString().c_str()); 394 else 395 error_stream.Printf ("Couldn't print result : %s\n", err.AsCString("unknown error")); 396 } 397 else 398 { 399 error_stream.Printf ("Expression produced no result\n"); 400 } 401 402 return true; 403 } 404 405 bool 406 CommandObjectExpression::ExecuteRawCommandString 407 ( 408 CommandInterpreter &interpreter, 409 const char *command, 410 CommandReturnObject &result 411 ) 412 { 413 m_exe_ctx = interpreter.GetDebugger().GetExecutionContext(); 414 415 m_options.ResetOptionValues(); 416 417 const char * expr = NULL; 418 419 if (command[0] == '\0') 420 { 421 m_expr_lines.clear(); 422 m_expr_line_count = 0; 423 424 InputReaderSP reader_sp (new InputReader(interpreter.GetDebugger())); 425 if (reader_sp) 426 { 427 Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback, 428 this, // baton 429 eInputReaderGranularityLine, // token size, to pass to callback function 430 NULL, // end token 431 NULL, // prompt 432 true)); // echo input 433 if (err.Success()) 434 { 435 interpreter.GetDebugger().PushInputReader (reader_sp); 436 result.SetStatus (eReturnStatusSuccessFinishNoResult); 437 } 438 else 439 { 440 result.AppendError (err.AsCString()); 441 result.SetStatus (eReturnStatusFailed); 442 } 443 } 444 else 445 { 446 result.AppendError("out of memory"); 447 result.SetStatus (eReturnStatusFailed); 448 } 449 return result.Succeeded(); 450 } 451 452 if (command[0] == '-') 453 { 454 // We have some options and these options MUST end with --. 455 const char *end_options = NULL; 456 const char *s = command; 457 while (s && s[0]) 458 { 459 end_options = ::strstr (s, "--"); 460 if (end_options) 461 { 462 end_options += 2; // Get past the "--" 463 if (::isspace (end_options[0])) 464 { 465 expr = end_options; 466 while (::isspace (*expr)) 467 ++expr; 468 break; 469 } 470 } 471 s = end_options; 472 } 473 474 if (end_options) 475 { 476 Args args (command, end_options - command); 477 if (!ParseOptions (interpreter, args, result)) 478 return false; 479 } 480 } 481 482 if (expr == NULL) 483 expr = command; 484 485 return EvaluateExpression (expr, false, result.GetOutputStream(), result.GetErrorStream()); 486 } 487 488 lldb::OptionDefinition 489 CommandObjectExpression::CommandOptions::g_option_table[] = 490 { 491 { LLDB_OPT_SET_ALL, false, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."}, 492 { 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."}, 493 { LLDB_OPT_SET_ALL, false, "debug", 'g', no_argument, NULL, 0, NULL, "Enable verbose debug logging of the expression parsing and evaluation."}, 494 { LLDB_OPT_SET_ALL, false, "use-ir", 'i', no_argument, NULL, 0, NULL, "[Temporary] Instructs the expression evaluator to use IR instead of ASTs."}, 495 { 0, false, NULL, 0, 0, NULL, NULL, NULL, NULL } 496 }; 497 498