blob: 9915d705ce6b115480f3ddfc022be989aec7a324 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectSource.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
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner24943d22010-06-08 16:52:24 +000012#include "CommandObjectSource.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
Jim Ingham84cdc152010-06-15 19:49:27 +000018#include "lldb/Interpreter/Args.h"
Greg Clayton63094e02010-06-23 01:19:29 +000019#include "lldb/Core/Debugger.h"
Greg Clayton52c8b6e2011-04-19 04:19:37 +000020#include "lldb/Core/FileLineResolver.h"
Greg Clayton78124112012-12-07 00:19:47 +000021#include "lldb/Core/Module.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000022#include "lldb/Core/ModuleSpec.h"
Greg Clayton52c8b6e2011-04-19 04:19:37 +000023#include "lldb/Core/SourceManager.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Interpreter/CommandInterpreter.h"
25#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton5f54ac32011-02-08 05:05:52 +000026#include "lldb/Host/FileSpec.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000027#include "lldb/Symbol/CompileUnit.h"
28#include "lldb/Symbol/Function.h"
Chris Lattner24943d22010-06-08 16:52:24 +000029#include "lldb/Target/Process.h"
30#include "lldb/Target/TargetList.h"
Jim Ingham767af882010-07-07 03:36:20 +000031#include "lldb/Interpreter/CommandCompletions.h"
32#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000033
34using namespace lldb;
35using namespace lldb_private;
36
Chris Lattner24943d22010-06-08 16:52:24 +000037//-------------------------------------------------------------------------
Greg Clayton52c8b6e2011-04-19 04:19:37 +000038// CommandObjectSourceInfo
Chris Lattner24943d22010-06-08 16:52:24 +000039//-------------------------------------------------------------------------
40
Jim Inghamda26bd22012-06-08 21:56:10 +000041class CommandObjectSourceInfo : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +000042{
Chris Lattner24943d22010-06-08 16:52:24 +000043
Jim Ingham767af882010-07-07 03:36:20 +000044 class CommandOptions : public Options
Chris Lattner24943d22010-06-08 16:52:24 +000045 {
Jim Ingham767af882010-07-07 03:36:20 +000046 public:
Greg Claytonf15996e2011-04-07 22:46:35 +000047 CommandOptions (CommandInterpreter &interpreter) :
48 Options(interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +000049 {
Jim Ingham767af882010-07-07 03:36:20 +000050 }
Chris Lattner24943d22010-06-08 16:52:24 +000051
Jim Ingham767af882010-07-07 03:36:20 +000052 ~CommandOptions ()
53 {
54 }
Chris Lattner24943d22010-06-08 16:52:24 +000055
Jim Ingham767af882010-07-07 03:36:20 +000056 Error
Greg Clayton143fcc32011-04-13 00:18:08 +000057 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Ingham767af882010-07-07 03:36:20 +000058 {
59 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +000060 const int short_option = g_option_table[option_idx].short_option;
Jim Ingham767af882010-07-07 03:36:20 +000061 switch (short_option)
Chris Lattner24943d22010-06-08 16:52:24 +000062 {
Jim Ingham767af882010-07-07 03:36:20 +000063 case 'l':
64 start_line = Args::StringToUInt32 (option_arg, 0);
65 if (start_line == 0)
Greg Clayton9c236732011-10-26 00:56:27 +000066 error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg);
Jim Ingham767af882010-07-07 03:36:20 +000067 break;
Chris Lattner24943d22010-06-08 16:52:24 +000068
Jim Ingham767af882010-07-07 03:36:20 +000069 case 'f':
70 file_name = option_arg;
71 break;
72
73 default:
Greg Clayton9c236732011-10-26 00:56:27 +000074 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Jim Ingham767af882010-07-07 03:36:20 +000075 break;
Chris Lattner24943d22010-06-08 16:52:24 +000076 }
77
Jim Ingham767af882010-07-07 03:36:20 +000078 return error;
79 }
Chris Lattner24943d22010-06-08 16:52:24 +000080
Jim Ingham767af882010-07-07 03:36:20 +000081 void
Greg Clayton143fcc32011-04-13 00:18:08 +000082 OptionParsingStarting ()
Jim Ingham767af882010-07-07 03:36:20 +000083 {
Jim Ingham767af882010-07-07 03:36:20 +000084 file_spec.Clear();
85 file_name.clear();
86 start_line = 0;
87 }
88
Greg Claytonb3448432011-03-24 21:19:54 +000089 const OptionDefinition*
Jim Ingham767af882010-07-07 03:36:20 +000090 GetDefinitions ()
91 {
92 return g_option_table;
93 }
Greg Claytonb3448432011-03-24 21:19:54 +000094 static OptionDefinition g_option_table[];
Jim Ingham767af882010-07-07 03:36:20 +000095
96 // Instance variables to hold the values for command options.
97 FileSpec file_spec;
98 std::string file_name;
99 uint32_t start_line;
100
101 };
102
103public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000104 CommandObjectSourceInfo(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000105 CommandObjectParsed (interpreter,
106 "source info",
107 "Display information about the source lines from the current executable's debug info.",
108 "source info [<cmd-options>]"),
Greg Claytonf15996e2011-04-07 22:46:35 +0000109 m_options (interpreter)
Jim Ingham767af882010-07-07 03:36:20 +0000110 {
111 }
112
113 ~CommandObjectSourceInfo ()
114 {
115 }
116
117
118 Options *
119 GetOptions ()
120 {
121 return &m_options;
122 }
123
Jim Inghamda26bd22012-06-08 21:56:10 +0000124protected:
Jim Ingham767af882010-07-07 03:36:20 +0000125 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000126 DoExecute (Args& command, CommandReturnObject &result)
Jim Ingham767af882010-07-07 03:36:20 +0000127 {
128 result.AppendError ("Not yet implemented");
129 result.SetStatus (eReturnStatusFailed);
130 return false;
131 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000132
Jim Ingham767af882010-07-07 03:36:20 +0000133 CommandOptions m_options;
134};
135
Greg Claytonb3448432011-03-24 21:19:54 +0000136OptionDefinition
Jim Ingham767af882010-07-07 03:36:20 +0000137CommandObjectSourceInfo::CommandOptions::g_option_table[] =
138{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000139{ LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."},
140{ LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."},
141{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham767af882010-07-07 03:36:20 +0000142};
143
144#pragma mark CommandObjectSourceList
145//-------------------------------------------------------------------------
146// CommandObjectSourceList
147//-------------------------------------------------------------------------
148
Jim Inghamda26bd22012-06-08 21:56:10 +0000149class CommandObjectSourceList : public CommandObjectParsed
Jim Ingham767af882010-07-07 03:36:20 +0000150{
151
152 class CommandOptions : public Options
153 {
154 public:
Greg Claytonf15996e2011-04-07 22:46:35 +0000155 CommandOptions (CommandInterpreter &interpreter) :
156 Options(interpreter)
Jim Ingham767af882010-07-07 03:36:20 +0000157 {
158 }
159
160 ~CommandOptions ()
161 {
162 }
163
164 Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000165 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Ingham767af882010-07-07 03:36:20 +0000166 {
167 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000168 const int short_option = g_option_table[option_idx].short_option;
Jim Ingham767af882010-07-07 03:36:20 +0000169 switch (short_option)
170 {
171 case 'l':
172 start_line = Args::StringToUInt32 (option_arg, 0);
173 if (start_line == 0)
Greg Clayton9c236732011-10-26 00:56:27 +0000174 error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg);
Jim Ingham767af882010-07-07 03:36:20 +0000175 break;
176
Jim Ingham338f7532010-08-20 01:17:07 +0000177 case 'c':
Jim Ingham767af882010-07-07 03:36:20 +0000178 num_lines = Args::StringToUInt32 (option_arg, 0);
179 if (num_lines == 0)
Greg Clayton9c236732011-10-26 00:56:27 +0000180 error.SetErrorStringWithFormat("invalid line count: '%s'", option_arg);
Jim Ingham767af882010-07-07 03:36:20 +0000181 break;
182
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000183 case 'f':
Jim Ingham767af882010-07-07 03:36:20 +0000184 file_name = option_arg;
185 break;
Jim Ingham338f7532010-08-20 01:17:07 +0000186
187 case 'n':
188 symbol_name = option_arg;
189 break;
Jim Ingham767af882010-07-07 03:36:20 +0000190
Greg Clayton78124112012-12-07 00:19:47 +0000191 case 'a':
192 {
193 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
194 address = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
195 }
196 break;
Jim Ingham338f7532010-08-20 01:17:07 +0000197 case 's':
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000198 modules.push_back (std::string (option_arg));
199 break;
200
201 case 'b':
202 show_bp_locs = true;
Jim Ingham338f7532010-08-20 01:17:07 +0000203 break;
Jim Ingham12b5aa02013-01-09 03:27:33 +0000204 case 'r':
205 reverse = true;
206 break;
Jim Ingham767af882010-07-07 03:36:20 +0000207 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000208 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Jim Ingham767af882010-07-07 03:36:20 +0000209 break;
210 }
211
212 return error;
213 }
214
215 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000216 OptionParsingStarting ()
Jim Ingham767af882010-07-07 03:36:20 +0000217 {
Jim Ingham767af882010-07-07 03:36:20 +0000218 file_spec.Clear();
219 file_name.clear();
Jim Ingham338f7532010-08-20 01:17:07 +0000220 symbol_name.clear();
Greg Clayton78124112012-12-07 00:19:47 +0000221 address = LLDB_INVALID_ADDRESS;
Jim Ingham767af882010-07-07 03:36:20 +0000222 start_line = 0;
223 num_lines = 10;
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000224 show_bp_locs = false;
Jim Ingham12b5aa02013-01-09 03:27:33 +0000225 reverse = false;
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000226 modules.clear();
Jim Ingham767af882010-07-07 03:36:20 +0000227 }
228
Greg Claytonb3448432011-03-24 21:19:54 +0000229 const OptionDefinition*
Jim Ingham767af882010-07-07 03:36:20 +0000230 GetDefinitions ()
231 {
232 return g_option_table;
233 }
Greg Claytonb3448432011-03-24 21:19:54 +0000234 static OptionDefinition g_option_table[];
Jim Ingham767af882010-07-07 03:36:20 +0000235
236 // Instance variables to hold the values for command options.
237 FileSpec file_spec;
238 std::string file_name;
Jim Ingham338f7532010-08-20 01:17:07 +0000239 std::string symbol_name;
Greg Clayton78124112012-12-07 00:19:47 +0000240 lldb::addr_t address;
Jim Ingham767af882010-07-07 03:36:20 +0000241 uint32_t start_line;
242 uint32_t num_lines;
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000243 STLStringArray modules;
244 bool show_bp_locs;
Jim Ingham12b5aa02013-01-09 03:27:33 +0000245 bool reverse;
Jim Ingham767af882010-07-07 03:36:20 +0000246 };
247
248public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000249 CommandObjectSourceList(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000250 CommandObjectParsed (interpreter,
251 "source list",
252 "Display source code (as specified) based on the current executable's debug info.",
253 NULL),
Greg Claytonf15996e2011-04-07 22:46:35 +0000254 m_options (interpreter)
Jim Ingham767af882010-07-07 03:36:20 +0000255 {
256 }
257
258 ~CommandObjectSourceList ()
259 {
260 }
261
262
263 Options *
264 GetOptions ()
265 {
266 return &m_options;
267 }
268
Jim Inghamda26bd22012-06-08 21:56:10 +0000269 virtual const char *
270 GetRepeatCommand (Args &current_command_args, uint32_t index)
Jim Ingham767af882010-07-07 03:36:20 +0000271 {
Jim Ingham12b5aa02013-01-09 03:27:33 +0000272 // This is kind of gross, but the command hasn't been parsed yet so we can't look at the option
273 // values for this invocation... I have to scan the arguments directly.
274 size_t num_args = current_command_args.GetArgumentCount();
275 bool is_reverse = false;
276 for (size_t i = 0 ; i < num_args; i++)
277 {
278 const char *arg = current_command_args.GetArgumentAtIndex(i);
279 if (arg && (strcmp(arg, "-r") == 0 || strcmp(arg, "--reverse") == 0))
280 {
281 is_reverse = true;
282 }
283 }
284 if (is_reverse)
285 {
286 if (m_reverse_name.empty())
287 {
288 m_reverse_name = m_cmd_name;
289 m_reverse_name.append (" -r");
290 }
291 return m_reverse_name.c_str();
292 }
293 else
294 return m_cmd_name.c_str();
Jim Inghamda26bd22012-06-08 21:56:10 +0000295 }
296
297protected:
298 bool
299 DoExecute (Args& command, CommandReturnObject &result)
300 {
301 const int argc = command.GetArgumentCount();
Jim Ingham767af882010-07-07 03:36:20 +0000302
303 if (argc != 0)
304 {
305 result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", GetCommandName());
306 result.SetStatus (eReturnStatusFailed);
Jim Ingham26e089b2011-11-29 21:21:26 +0000307 return false;
Jim Ingham767af882010-07-07 03:36:20 +0000308 }
309
Greg Claytonb72d0f02011-04-12 05:54:46 +0000310 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +0000311 Target *target = exe_ctx.GetTargetPtr();
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000312
Greg Clayton567e7f32011-09-22 04:58:26 +0000313 if (target == NULL)
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000314 target = m_interpreter.GetDebugger().GetSelectedTarget().get();
315
316 if (target == NULL)
317 {
318 result.AppendError ("invalid target, create a debug target using the 'target create' command");
319 result.SetStatus (eReturnStatusFailed);
320 return false;
321 }
322
Greg Clayton78124112012-12-07 00:19:47 +0000323 SymbolContextList sc_list;
Jim Ingham338f7532010-08-20 01:17:07 +0000324 if (!m_options.symbol_name.empty())
325 {
326 // Displaying the source for a symbol:
Jim Ingham338f7532010-08-20 01:17:07 +0000327 ConstString name(m_options.symbol_name.c_str());
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000328 bool include_symbols = false;
Sean Callanan302d78c2012-02-10 22:52:19 +0000329 bool include_inlines = true;
Jim Ingham338f7532010-08-20 01:17:07 +0000330 bool append = true;
331 size_t num_matches = 0;
332
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000333 if (m_options.modules.size() > 0)
Jim Ingham338f7532010-08-20 01:17:07 +0000334 {
335 ModuleList matching_modules;
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000336 for (unsigned i = 0, e = m_options.modules.size(); i != e; i++)
Jim Ingham338f7532010-08-20 01:17:07 +0000337 {
Greg Clayton444fe992012-02-26 05:51:37 +0000338 FileSpec module_file_spec(m_options.modules[i].c_str(), false);
339 if (module_file_spec)
Jim Ingham338f7532010-08-20 01:17:07 +0000340 {
Greg Clayton444fe992012-02-26 05:51:37 +0000341 ModuleSpec module_spec (module_file_spec);
Jim Ingham338f7532010-08-20 01:17:07 +0000342 matching_modules.Clear();
Greg Clayton444fe992012-02-26 05:51:37 +0000343 target->GetImages().FindModules (module_spec, matching_modules);
Sean Callanan302d78c2012-02-10 22:52:19 +0000344 num_matches += matching_modules.FindFunctions (name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list);
Jim Ingham338f7532010-08-20 01:17:07 +0000345 }
346 }
347 }
348 else
349 {
Sean Callanan302d78c2012-02-10 22:52:19 +0000350 num_matches = target->GetImages().FindFunctions (name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list);
Jim Ingham338f7532010-08-20 01:17:07 +0000351 }
352
353 SymbolContext sc;
354
355 if (num_matches == 0)
356 {
357 result.AppendErrorWithFormat("Could not find function named: \"%s\".\n", m_options.symbol_name.c_str());
358 result.SetStatus (eReturnStatusFailed);
359 return false;
360 }
361
362 sc_list.GetContextAtIndex (0, sc);
363 FileSpec start_file;
364 uint32_t start_line;
365 uint32_t end_line;
366 FileSpec end_file;
367 if (sc.function != NULL)
368 {
369 sc.function->GetStartLineSourceInfo (start_file, start_line);
370 if (start_line == 0)
371 {
372 result.AppendErrorWithFormat("Could not find line information for start of function: \"%s\".\n", m_options.symbol_name.c_str());
373 result.SetStatus (eReturnStatusFailed);
374 return false;
375 }
376 sc.function->GetEndLineSourceInfo (end_file, end_line);
377 }
378 else
379 {
380 result.AppendErrorWithFormat("Could not find function info for: \"%s\".\n", m_options.symbol_name.c_str());
381 result.SetStatus (eReturnStatusFailed);
382 return false;
383 }
384
385 if (num_matches > 1)
386 {
387 // This could either be because there are multiple functions of this name, in which case
388 // we'll have to specify this further... Or it could be because there are multiple inlined instances
389 // of one function. So run through the matches and if they all have the same file & line then we can just
390 // list one.
391
392 bool found_multiple = false;
393
394 for (size_t i = 1; i < num_matches; i++)
395 {
396 SymbolContext scratch_sc;
397 sc_list.GetContextAtIndex (i, scratch_sc);
398 if (scratch_sc.function != NULL)
399 {
400 FileSpec scratch_file;
401 uint32_t scratch_line;
402 scratch_sc.function->GetStartLineSourceInfo (scratch_file, scratch_line);
403 if (scratch_file != start_file
404 || scratch_line != start_line)
405 {
406 found_multiple = true;
407 break;
408 }
409 }
410 }
411 if (found_multiple)
412 {
413 StreamString s;
414 for (size_t i = 0; i < num_matches; i++)
415 {
416 SymbolContext scratch_sc;
417 sc_list.GetContextAtIndex (i, scratch_sc);
418 if (scratch_sc.function != NULL)
419 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000420 s.Printf("\n%lu: ", i);
Jim Ingham338f7532010-08-20 01:17:07 +0000421 scratch_sc.function->Dump (&s, true);
422 }
423 }
424 result.AppendErrorWithFormat("Multiple functions found matching: %s: \n%s\n",
425 m_options.symbol_name.c_str(),
426 s.GetData());
427 result.SetStatus (eReturnStatusFailed);
428 return false;
429 }
430 }
431
432
433 // This is a little hacky, but the first line table entry for a function points to the "{" that
434 // starts the function block. It would be nice to actually get the function
435 // declaration in there too. So back up a bit, but not further than what you're going to display.
436 size_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2;
437 uint32_t line_no;
438 if (start_line <= lines_to_back_up)
439 line_no = 1;
440 else
441 line_no = start_line - lines_to_back_up;
442
443 // For fun, if the function is shorter than the number of lines we're supposed to display,
444 // only display the function...
445 if (end_line != 0)
446 {
447 if (m_options.num_lines > end_line - line_no)
448 m_options.num_lines = end_line - line_no;
449 }
450
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000451 char path_buf[PATH_MAX];
452 start_file.GetPath(path_buf, sizeof(path_buf));
Greg Clayton1cee1e62011-04-20 18:52:45 +0000453
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000454 if (m_options.show_bp_locs)
Greg Clayton1cee1e62011-04-20 18:52:45 +0000455 {
456 const bool show_inlines = true;
457 m_breakpoint_locations.Reset (start_file, 0, show_inlines);
Greg Clayton567e7f32011-09-22 04:58:26 +0000458 SearchFilter target_search_filter (exe_ctx.GetTargetSP());
Greg Clayton1cee1e62011-04-20 18:52:45 +0000459 target_search_filter.Search (m_breakpoint_locations);
460 }
461 else
462 m_breakpoint_locations.Clear();
463
Jim Ingham338f7532010-08-20 01:17:07 +0000464 result.AppendMessageWithFormat("File: %s.\n", path_buf);
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000465 target->GetSourceManager().DisplaySourceLinesWithLineNumbers (start_file,
466 line_no,
467 0,
468 m_options.num_lines,
469 "",
470 &result.GetOutputStream(),
471 GetBreakpointLocations ());
Jim Ingham338f7532010-08-20 01:17:07 +0000472
473 result.SetStatus (eReturnStatusSuccessFinishResult);
474 return true;
475
476 }
Greg Clayton78124112012-12-07 00:19:47 +0000477 else if (m_options.address != LLDB_INVALID_ADDRESS)
478 {
479 SymbolContext sc;
480 Address so_addr;
481 StreamString error_strm;
482
483 if (target->GetSectionLoadList().IsEmpty())
484 {
485 // The target isn't loaded yet, we need to lookup the file address
486 // in all modules
487 const ModuleList &module_list = target->GetImages();
488 const uint32_t num_modules = module_list.GetSize();
489 for (uint32_t i=0; i<num_modules; ++i)
490 {
491 ModuleSP module_sp (module_list.GetModuleAtIndex(i));
492 if (module_sp && module_sp->ResolveFileAddress(m_options.address, so_addr))
493 {
494 sc.Clear();
495 if (module_sp->ResolveSymbolContextForAddress (so_addr, eSymbolContextEverything, sc) & eSymbolContextLineEntry)
496 sc_list.Append(sc);
497 }
498 }
499
500 if (sc_list.GetSize() == 0)
501 {
502 result.AppendErrorWithFormat("no modules have source information for file address 0x%" PRIx64 ".\n",
503 m_options.address);
504 result.SetStatus (eReturnStatusFailed);
505 return false;
506 }
507 }
508 else
509 {
510 // The target has some things loaded, resolve this address to a
511 // compile unit + file + line and display
512 if (target->GetSectionLoadList().ResolveLoadAddress (m_options.address, so_addr))
513 {
514 ModuleSP module_sp (so_addr.GetModule());
515 if (module_sp)
516 {
517 sc.Clear();
518 if (module_sp->ResolveSymbolContextForAddress (so_addr, eSymbolContextEverything, sc) & eSymbolContextLineEntry)
519 {
520 sc_list.Append(sc);
521 }
522 else
523 {
524 so_addr.Dump(&error_strm, NULL, Address::DumpStyleModuleWithFileAddress);
525 result.AppendErrorWithFormat("address resolves to %s, but there is no line table information available for this address.\n",
526 error_strm.GetData());
527 result.SetStatus (eReturnStatusFailed);
528 return false;
529 }
530 }
531 }
532
533 if (sc_list.GetSize() == 0)
534 {
535 result.AppendErrorWithFormat("no modules contain load address 0x%" PRIx64 ".\n", m_options.address);
536 result.SetStatus (eReturnStatusFailed);
537 return false;
538 }
539 }
540 uint32_t num_matches = sc_list.GetSize();
541 for (uint32_t i=0; i<num_matches; ++i)
542 {
543 sc_list.GetContextAtIndex(i, sc);
544 if (sc.comp_unit)
545 {
546 if (m_options.show_bp_locs)
547 {
548 m_breakpoint_locations.Clear();
549 const bool show_inlines = true;
550 m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines);
551 SearchFilter target_search_filter (target->shared_from_this());
552 target_search_filter.Search (m_breakpoint_locations);
553 }
554
555 bool show_fullpaths = true;
556 bool show_module = true;
557 bool show_inlined_frames = true;
558 sc.DumpStopContext(&result.GetOutputStream(),
559 exe_ctx.GetBestExecutionContextScope(),
560 sc.line_entry.range.GetBaseAddress(),
561 show_fullpaths,
562 show_module,
563 show_inlined_frames);
564 result.GetOutputStream().EOL();
565
566 size_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2;
567
568 target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
569 sc.line_entry.line,
570 lines_to_back_up,
571 m_options.num_lines - lines_to_back_up,
572 "->",
573 &result.GetOutputStream(),
574 GetBreakpointLocations ());
575 result.SetStatus (eReturnStatusSuccessFinishResult);
576 }
577 }
578 }
Jim Ingham338f7532010-08-20 01:17:07 +0000579 else if (m_options.file_name.empty())
Jim Ingham767af882010-07-07 03:36:20 +0000580 {
581 // Last valid source manager context, or the current frame if no
582 // valid last context in source manager.
583 // One little trick here, if you type the exact same list command twice in a row, it is
584 // more likely because you typed it once, then typed it again
585 if (m_options.start_line == 0)
586 {
Jim Inghamc7f18c82011-09-29 20:22:33 +0000587 if (target->GetSourceManager().DisplayMoreWithLineNumbers (&result.GetOutputStream(),
Jim Ingham12b5aa02013-01-09 03:27:33 +0000588 GetBreakpointLocations (),
589 m_options.reverse))
Chris Lattner24943d22010-06-08 16:52:24 +0000590 {
Chris Lattner24943d22010-06-08 16:52:24 +0000591 result.SetStatus (eReturnStatusSuccessFinishResult);
592 }
Jim Ingham767af882010-07-07 03:36:20 +0000593 }
594 else
595 {
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000596 if (m_options.show_bp_locs)
Greg Clayton1cee1e62011-04-20 18:52:45 +0000597 {
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000598 SourceManager::FileSP last_file_sp (target->GetSourceManager().GetLastFile ());
Greg Clayton1cee1e62011-04-20 18:52:45 +0000599 if (last_file_sp)
600 {
601 const bool show_inlines = true;
602 m_breakpoint_locations.Reset (last_file_sp->GetFileSpec(), 0, show_inlines);
Greg Clayton13d24fb2012-01-29 20:56:30 +0000603 SearchFilter target_search_filter (target->shared_from_this());
Greg Clayton1cee1e62011-04-20 18:52:45 +0000604 target_search_filter.Search (m_breakpoint_locations);
605 }
606 }
607 else
608 m_breakpoint_locations.Clear();
609
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000610 if (target->GetSourceManager().DisplaySourceLinesWithLineNumbersUsingLastFile(
Jim Ingham767af882010-07-07 03:36:20 +0000611 m_options.start_line, // Line to display
612 0, // Lines before line to display
613 m_options.num_lines, // Lines after line to display
614 "", // Don't mark "line"
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000615 &result.GetOutputStream(),
616 GetBreakpointLocations ()))
Chris Lattner24943d22010-06-08 16:52:24 +0000617 {
Jim Ingham767af882010-07-07 03:36:20 +0000618 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000619 }
Jim Ingham767af882010-07-07 03:36:20 +0000620
Chris Lattner24943d22010-06-08 16:52:24 +0000621 }
622 }
623 else
624 {
Jim Ingham767af882010-07-07 03:36:20 +0000625 const char *filename = m_options.file_name.c_str();
Jim Ingham767af882010-07-07 03:36:20 +0000626
627 bool check_inlines = false;
628 SymbolContextList sc_list;
Jim Ingham338f7532010-08-20 01:17:07 +0000629 size_t num_matches = 0;
630
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000631 if (m_options.modules.size() > 0)
Jim Ingham767af882010-07-07 03:36:20 +0000632 {
Jim Ingham338f7532010-08-20 01:17:07 +0000633 ModuleList matching_modules;
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000634 for (unsigned i = 0, e = m_options.modules.size(); i != e; i++)
Jim Ingham767af882010-07-07 03:36:20 +0000635 {
Greg Clayton444fe992012-02-26 05:51:37 +0000636 FileSpec module_file_spec(m_options.modules[i].c_str(), false);
637 if (module_file_spec)
Jim Ingham767af882010-07-07 03:36:20 +0000638 {
Greg Clayton444fe992012-02-26 05:51:37 +0000639 ModuleSpec module_spec (module_file_spec);
Jim Ingham338f7532010-08-20 01:17:07 +0000640 matching_modules.Clear();
Greg Clayton444fe992012-02-26 05:51:37 +0000641 target->GetImages().FindModules (module_spec, matching_modules);
Jim Ingham338f7532010-08-20 01:17:07 +0000642 num_matches += matching_modules.ResolveSymbolContextForFilePath (filename,
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000643 0,
644 check_inlines,
645 eSymbolContextModule | eSymbolContextCompUnit,
646 sc_list);
Jim Ingham767af882010-07-07 03:36:20 +0000647 }
648 }
649 }
Jim Ingham338f7532010-08-20 01:17:07 +0000650 else
651 {
652 num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename,
653 0,
654 check_inlines,
655 eSymbolContextModule | eSymbolContextCompUnit,
656 sc_list);
657 }
658
659 if (num_matches == 0)
660 {
661 result.AppendErrorWithFormat("Could not find source file \"%s\".\n",
662 m_options.file_name.c_str());
663 result.SetStatus (eReturnStatusFailed);
664 return false;
665 }
666
667 if (num_matches > 1)
668 {
669 SymbolContext sc;
670 bool got_multiple = false;
671 FileSpec *test_cu_spec = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000672
Chris Lattner0f6fa732010-09-08 22:55:31 +0000673 for (unsigned i = 0; i < num_matches; i++)
Jim Ingham338f7532010-08-20 01:17:07 +0000674 {
675 sc_list.GetContextAtIndex(i, sc);
676 if (sc.comp_unit)
677 {
678 if (test_cu_spec)
679 {
680 if (test_cu_spec != static_cast<FileSpec *> (sc.comp_unit))
681 got_multiple = true;
682 break;
683 }
684 else
685 test_cu_spec = sc.comp_unit;
686 }
687 }
688 if (got_multiple)
689 {
690 result.AppendErrorWithFormat("Multiple source files found matching: \"%s.\"\n",
691 m_options.file_name.c_str());
692 result.SetStatus (eReturnStatusFailed);
693 return false;
694 }
695 }
696
697 SymbolContext sc;
698 if (sc_list.GetContextAtIndex(0, sc))
699 {
700 if (sc.comp_unit)
701 {
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000702 if (m_options.show_bp_locs)
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000703 {
704 const bool show_inlines = true;
705 m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines);
Greg Clayton13d24fb2012-01-29 20:56:30 +0000706 SearchFilter target_search_filter (target->shared_from_this());
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000707 target_search_filter.Search (m_breakpoint_locations);
708 }
709 else
710 m_breakpoint_locations.Clear();
711
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000712 target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
713 m_options.start_line,
714 0,
715 m_options.num_lines,
716 "",
717 &result.GetOutputStream(),
718 GetBreakpointLocations ());
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000719
Jim Ingham338f7532010-08-20 01:17:07 +0000720 result.SetStatus (eReturnStatusSuccessFinishResult);
721 }
722 else
723 {
724 result.AppendErrorWithFormat("No comp unit found for: \"%s.\"\n",
725 m_options.file_name.c_str());
726 result.SetStatus (eReturnStatusFailed);
727 return false;
728 }
729 }
730 }
Jim Ingham767af882010-07-07 03:36:20 +0000731 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +0000732 }
Jim Ingham767af882010-07-07 03:36:20 +0000733
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000734 const SymbolContextList *
735 GetBreakpointLocations ()
736 {
737 if (m_breakpoint_locations.GetFileLineMatches().GetSize() > 0)
738 return &m_breakpoint_locations.GetFileLineMatches();
739 return NULL;
740 }
Jim Ingham767af882010-07-07 03:36:20 +0000741 CommandOptions m_options;
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000742 FileLineResolver m_breakpoint_locations;
Jim Ingham12b5aa02013-01-09 03:27:33 +0000743 std::string m_reverse_name;
Jim Ingham767af882010-07-07 03:36:20 +0000744
745};
746
Greg Claytonb3448432011-03-24 21:19:54 +0000747OptionDefinition
Jim Ingham767af882010-07-07 03:36:20 +0000748CommandObjectSourceList::CommandOptions::g_option_table[] =
749{
Greg Clayton78124112012-12-07 00:19:47 +0000750{ LLDB_OPT_SET_ALL, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "The number of source lines to display."},
751{ LLDB_OPT_SET_1 |
752 LLDB_OPT_SET_2 , false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library."},
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000753{ LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', no_argument, NULL, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints."},
Greg Clayton78124112012-12-07 00:19:47 +0000754{ LLDB_OPT_SET_1 , false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."},
755{ LLDB_OPT_SET_1 , false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."},
756{ LLDB_OPT_SET_2 , false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."},
757{ LLDB_OPT_SET_3 , false, "address",'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup the address and display the source information for the corresponding file and line."},
Jim Ingham12b5aa02013-01-09 03:27:33 +0000758{ LLDB_OPT_SET_4, false, "reverse", 'r', no_argument, NULL, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source."},
Caroline Tice4d6675c2010-10-01 19:59:14 +0000759{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham767af882010-07-07 03:36:20 +0000760};
761
762#pragma mark CommandObjectMultiwordSource
763
764//-------------------------------------------------------------------------
765// CommandObjectMultiwordSource
766//-------------------------------------------------------------------------
767
768CommandObjectMultiwordSource::CommandObjectMultiwordSource (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000769 CommandObjectMultiword (interpreter,
770 "source",
Caroline Ticec1ad82e2010-09-07 22:38:08 +0000771 "A set of commands for accessing source file information",
Jim Ingham767af882010-07-07 03:36:20 +0000772 "source <subcommand> [<subcommand-options>]")
773{
Greg Clayton238c0a12010-09-18 01:14:36 +0000774 LoadSubCommand ("info", CommandObjectSP (new CommandObjectSourceInfo (interpreter)));
775 LoadSubCommand ("list", CommandObjectSP (new CommandObjectSourceList (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +0000776}
Jim Ingham767af882010-07-07 03:36:20 +0000777
778CommandObjectMultiwordSource::~CommandObjectMultiwordSource ()
779{
780}
781