blob: 004aac12f59c2bf6cfde154e5f7b9a10792b9b5b [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVELOPER_DEBUG_ZXDB_CONSOLE_FORMAT_CONTEXT_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_CONSOLE_FORMAT_CONTEXT_H_
#include <limits>
#include <map>
#include <string>
#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/console/command.h"
#include "src/developer/debug/zxdb/expr/expr_language.h"
#include "src/lib/fxl/memory/weak_ptr.h"
namespace zxdb {
class ArchInfo;
class FileLine;
class Location;
class MemoryDump;
class ModuleSymbols;
class OutputBuffer;
class Process;
class SourceFileProvider;
// Formats the given location and writes it to the console.
//
// If the location is symbolized and the source affinity is not "assembly", a source-code dump will
// be displayed. Otherwise, a disassembly dump will be displayed.
//
// Disassembly dumps will be done asynchronously since the memory must be requested from the target
// system. Source dumps will be synchronous.
//
// An error will be returned if the location is symbolized but the file can't be found or doesn't
// contain that line. In this case, nothing will be output.
Err OutputSourceContext(Process* process, std::unique_ptr<SourceFileProvider> file_provider,
const Location& location, SourceAffinity source_affinity);
struct FormatSourceOpts {
// Sets the language member based on the extension of the file name, falling back to C for
// anything that doesn't match.
void SetLanguageFromFileName(const std::string& file_name);
// If set, syntax highlights source code according to the given language. If unset, does not
// highlight. See SetLanguageFromFileName() to autodetect.
std::optional<ExprLanguage> language;
// Show the full file path before printing source code. Useful for debugging symbol issues.
//
// This could be enhanced to be an enum to show a short name or the name from the symbol file.
bool show_file_name = false;
// Range of lines to print, inclusive. This can be outside of the range of file lines, the result
// will just be clamped to the end of the file.
int first_line = 0;
int last_line = 0;
// Number of extra spaces before the "gutter" (where the current line caret goes).
int left_indent = 0;
// 1-based line to show as the active one. This line will be shown with an arrow indicator in the
// left column. When 0, no active line will be highlighted.
//
// By convention the active line indicator should be used to show the current execution position
// only. To highlight for another purpose, use highlight_line.
int active_line = 0;
// 1-based line to highlight in bold.
int highlight_line = 0;
// 1-based column number of the highlighted line to start highlighting from. When 0 or 1, the
// entire line will be highlighted.
int highlight_column = 0;
// When true, all non-highlighted lines will be dimmed in source listings. Otherwise they will be
// shown in the normal color.
bool dim_others = false;
// Set to true to issue an error if the active line is not present in the file. This would be set
// if we're showing the current execution location and it would be confusing to show something
// incorrect. In other cases, the active line is secondary information and it doesn't matter if
// it's not visible.
bool require_active_line = false;
// Contains the lines with breakpoints (1-based key) mapped to whether that breakpoint is enabled
// or not.
std::map<int, bool> bp_lines;
// If set, this will be used to compare modification times for source file symbols when loading a
// source file (FormatSourceFileContext()). A warning will be prepended to source listings if the
// source file is newer than the module's symbols. This should be the module corresponding to the
// file being printed.
//
// This is a WeakPtr because sometimes this options struct is saved asynchronously when something
// needs to be fetched.
fxl::WeakPtr<ModuleSymbols> module_for_time_warning;
};
// Formats the contents of the given local file name to the output. See FormatSourceFileContext for
// error handling.
//
// The build_dir indicates the directory where relative file names will be treated as relative to.
Err FormatSourceFileContext(const FileLine& file_line, const SourceFileProvider& file_provider,
const FormatSourceOpts& opts, OutputBuffer* out);
// Formats the given source to the output.
//
// The file_name_for_display is used for display purposes but is not interpreted in any way. This
// will be printed if the show_file_name flag is set in the options.
//
// If the active line is nonzero but is not in the file, an error will be returned and no output
// will be generated. The file_name_for_display will be used to generate this string.
Err FormatSourceContext(const std::string& file_name_for_display, const std::string& file_contents,
const FormatSourceOpts& opts, OutputBuffer* out);
struct FormatAsmOpts {
bool emit_addresses = true;
bool emit_bytes = false;
bool include_source = false;
// When nonzero, a line with this address will be marked as active.
uint64_t active_address = 0;
// When nonzero, disassembly will stop after this many assembly instructions.
size_t max_instructions = std::numeric_limits<size_t>::max();
// Contains the addresses with breakpoints mapped to whether that breakpoint is enabled or not.
std::map<uint64_t, bool> bp_addrs;
};
// Outputs assembly.
//
// The process is used when options.include_source is set to map addresses back to source locations.
// When options.include_source is not set, this can be null.
//
// On error, returns the error and does nothing.
Err FormatAsmContext(const ArchInfo& arch_info, const MemoryDump& dump, const FormatAsmOpts& opts,
Process* process, const SourceFileProvider& file_provider, OutputBuffer* out);
// Creates a source code context of the given location and puts it in the output buffer. This does
// not write disassembly since that would require asynchronously getting the memory which isn't as
// important for breakpoints.
//
// If there are no symbols or the file can't be found, returns the error and doesn't write anything
// to the buffer.
//
// Generally the location passed here should be the location of a resolved BreakpointLocation since
// the breakpoint itself won't have a fully qualified file name, and the breakpoint may move
// slightly when it's actually applied.
//
// Build_dir_prefs is used to find relative files by FormatSourceFileContext().
Err FormatBreakpointContext(const Location& location, const SourceFileProvider& file_provider,
bool enabled, OutputBuffer* out);
// Syntax highlights the given source line according to the language's rules. The is_highlight_line
// flag indicates whether to apply opts.highlight_line and opts.highlight_column to the current
// line.
OutputBuffer FormatSourceLine(const FormatSourceOpts& opts, bool is_highlight_line,
const std::string& line);
} // namespace zxdb
#endif // SRC_DEVELOPER_DEBUG_ZXDB_CONSOLE_FORMAT_CONTEXT_H_