DocumentTabReferenceResult Create(AddressReference addrRef, IDocumentTreeView documentTreeView) { var content = hexBoxDocumentTabContentCreator.Value.TryCreate(addrRef.Filename); if (content == null) { return(null); } ulong?fileOffset = GetFileOffset(addrRef, documentTreeView); return(new DocumentTabReferenceResult(content, null, e => { if (e.Success) { Debug.Assert(e.Tab.Content == content); var uiContext = e.Tab.UIContext as HexBoxDocumentTabUIContext; Debug.Assert(uiContext != null); if (uiContext != null && fileOffset != null) { if (!IsVisible(uiContext.DnHexBox, fileOffset.Value, addrRef.Length)) { uiContext.DnHexBox.InitializeStartEndOffsetToDocument(); } if (!e.HasMovedCaret) { uiContext.DnHexBox.SelectAndMoveCaret(fileOffset.Value, addrRef.Length); e.HasMovedCaret = true; } } } })); }
ulong?GetFileOffset(AddressReference addrRef, IDocumentTreeView documentTreeView) { if (!addrRef.IsRVA) { return(addrRef.Address); } if (string.IsNullOrEmpty(addrRef.Filename)) { return(null); } var file = documentTreeView.GetAllCreatedDocumentNodes().FirstOrDefault(a => StringComparer.OrdinalIgnoreCase.Equals(a.Document.Filename, addrRef.Filename)); if (file == null) { return(null); } var pe = file.Document.PEImage; if (pe == null) { return(null); } return((ulong)pe.ToFileOffset((RVA)addrRef.Address)); }
DocumentTabReferenceResult Create(AddressReference addrRef, IDocumentTreeView documentTreeView) { var content = hexViewDocumentTabContentCreator.Value.TryCreate(addrRef.Filename); if (content == null) return null; var fileOffset = GetFileOffset(addrRef, documentTreeView); return new DocumentTabReferenceResult(content, null, e => CreateHandler(e, content, fileOffset, addrRef)); }
void CreateHandler(ShowTabContentEventArgs e, HexViewDocumentTabContent content, HexPosition? fileOffset, AddressReference addrRef) { if (!e.Success) return; Debug.Assert(e.Tab.Content == content); var uiContext = e.Tab.UIContext as HexViewDocumentTabUIContext; Debug.Assert(uiContext != null); if (uiContext == null || fileOffset == null) return; var start = fileOffset.Value; var end = HexPosition.Min(start + addrRef.Length, HexPosition.MaxEndPosition); if (!IsVisible(uiContext.HexView, start, end)) { uiContext.HexView.Options.SetOptionValue(DefaultHexViewOptions.StartPositionId, uiContext.HexView.Buffer.Span.Start); uiContext.HexView.Options.SetOptionValue(DefaultHexViewOptions.EndPositionId, uiContext.HexView.Buffer.Span.End); RedisplayHexLines(uiContext.HexView); if (!IsVisible(uiContext.HexView, start, end)) return; } if (e.HasMovedCaret) return; if (!uiContext.HexView.VisualElement.IsLoaded) { RoutedEventHandler loaded = null; loaded = (s, e2) => { uiContext.HexView.VisualElement.Loaded -= loaded; InitializeHexView(uiContext.HexView, start, end); }; uiContext.HexView.VisualElement.Loaded += loaded; } else InitializeHexView(uiContext.HexView, start, end); e.HasMovedCaret = true; }
private void ParseBreakpoint(WatchValue watchValue, Breakpoint.Types type) { if (AddBreakpoint == null) { return; } var parseExpression = watchValue.Text.Trim(); var addressReference = new AddressReference(parseExpression, GetSymbol); AddBreakpoint(addressReference.BaseAddress, type, Breakpoint.AddressTypes.Cpu, addressReference.BaseAddress < 0 ? parseExpression: null); }
DocumentTabReferenceResult Create(AddressReference addrRef, IDocumentTreeView documentTreeView) { var content = hexViewDocumentTabContentCreator.Value.TryCreate(addrRef.Filename); if (content == null) { return(null); } var fileOffset = GetFileOffset(addrRef, documentTreeView); return(new DocumentTabReferenceResult(content, null, e => CreateHandler(e, content, fileOffset, addrRef))); }
ulong? GetFileOffset(AddressReference addrRef, IFileTreeView fileTreeView) { if (!addrRef.IsRVA) return addrRef.Address; var file = fileTreeView.GetAllCreatedDnSpyFileNodes().FirstOrDefault(a => StringComparer.OrdinalIgnoreCase.Equals(a.DnSpyFile.Filename, addrRef.Filename)); if (file == null) return null; var pe = file.DnSpyFile.PEImage; if (pe == null) return null; return (ulong)pe.ToFileOffset((RVA)addrRef.Address); }
protected string GetParsedAddress(string word) { var memoryState = GetCpuMemory(); if (memoryState == null) { return(word); } var addressReference = new AddressReference(word, s => File.Project.DebugSymbols.ContainsKey(s) ? File.Project.DebugSymbols[s] : null); var val8 = memoryState.ReadAddress(addressReference.BaseAddress, false, addressReference.OffsetRegister, out var address); var val16 = memoryState.ReadAddress(addressReference.BaseAddress, true, addressReference.OffsetRegister); return(string.Format("{0} ({1})\n\nValue: {2} ({3})\nWord value: {4} ({5})", word, WatchValue.FormatHexAddress(address), WatchValue.FormatHex(val8, 2), val8, WatchValue.FormatHex(val16, 4), val16 )); }
ulong?GetFileOffset(AddressReference addrRef, IFileTreeView fileTreeView) { if (!addrRef.IsRVA) { return(addrRef.Address); } var file = fileTreeView.GetAllCreatedDnSpyFileNodes().FirstOrDefault(a => StringComparer.OrdinalIgnoreCase.Equals(a.DnSpyFile.Filename, addrRef.Filename)); if (file == null) { return(null); } var pe = file.DnSpyFile.PEImage; if (pe == null) { return(null); } return((ulong)pe.ToFileOffset((RVA)addrRef.Address)); }
FileTabReferenceResult Create(AddressReference addrRef, IFileTreeView fileTreeView) { var content = hexBoxFileTabContentCreator.Value.TryCreate(addrRef.Filename); if (content == null) return null; ulong? fileOffset = GetFileOffset(addrRef, fileTreeView); return new FileTabReferenceResult(content, null, e => { if (e.Success) { Debug.Assert(e.Tab.Content == content); var uiContext = e.Tab.UIContext as HexBoxFileTabUIContext; Debug.Assert(uiContext != null); if (uiContext != null && fileOffset != null) { if (!IsVisible(uiContext.DnHexBox, fileOffset.Value, addrRef.Length)) uiContext.DnHexBox.InitializeStartEndOffsetToDocument(); if (!e.HasMovedCaret) { uiContext.DnHexBox.SelectAndMoveCaret(fileOffset.Value, addrRef.Length); e.HasMovedCaret = true; } } } }); }
HexPosition? GetFileOffset(AddressReference addrRef, IDocumentTreeView documentTreeView) { if (!addrRef.IsRVA) return addrRef.Address; if (string.IsNullOrEmpty(addrRef.Filename)) return null; var file = documentTreeView.GetAllCreatedDocumentNodes().FirstOrDefault(a => StringComparer.OrdinalIgnoreCase.Equals(a.Document.Filename, addrRef.Filename)); if (file == null) return null; var pe = file.Document.PEImage; if (pe == null) return null; return (ulong)pe.ToFileOffset((RVA)addrRef.Address); }
public CodeEditor(AsmProjectFile file, Events events) { File = file; ModuleEvents = events; Document.FormattingStrategy = new Ca65Formatting(); _fileCompletionDataProvider = new FileCompletion(new[] { file.Project.Directory, file.File.Directory }, () => { _forcedAutoCompleteWindow = true; ShowIntellisense('/', 0); }); ActiveTextAreaControl.TextArea.InsertLeftMargin(1, new CpuAddressMargin(ActiveTextAreaControl.TextArea, GetDebugLine, file.Project.Type == ProjectType.Snes ? 6 : 4)); Menu = new CodeMenu(events); Menu.Enabled = true; Menu.Name = "Menu"; Menu.Size = new Size(108, 70); ActiveTextAreaControl.TextArea.ContextMenuStrip = Menu; Menu.Opening += (sender, e) => { var word = GetAsmWord(ActiveTextAreaControl.Caret.Position); Menu.CurrentWord = word; }; Menu.GoToDefinition = GoToSymbol; Menu.AddToWatch = () => { var word = GetAsmWord(ActiveTextAreaControl.Caret.Position); if (word == null) { return; } switch (word.WordType) { case AsmWord.AsmWordType.NumberWord: case AsmWord.AsmWordType.NumberByte: AddToWatch(word.Word, word.WordType == AsmWord.AsmWordType.NumberWord); break; case AsmWord.AsmWordType.LabelReference: case AsmWord.AsmWordType.LabelAbsolute: case AsmWord.AsmWordType.LabelDefinition: case AsmWord.AsmWordType.AddressReference: AddToWatch(word.Word, false); break; } }; Menu.BreakOnAccess = (type) => { var word = GetAsmWord(ActiveTextAreaControl.Caret.Position); if (word == null) { return; } switch (word.WordType) { case AsmWord.AsmWordType.NumberWord: case AsmWord.AsmWordType.NumberByte: AddAddressBreakpoint(AddressReference.ParseNumber(word.Word), type); break; case AsmWord.AsmWordType.LabelReference: case AsmWord.AsmWordType.LabelAbsolute: case AsmWord.AsmWordType.LabelDefinition: AddSymbolBreakpoint(word.Word, type); break; } }; Menu.ToggleBreakpoint = ToggleBreakpointAtCaret; Document.HighlightingStrategy = new Ca65Highlighting(File.Project.Type); var testMarker = new TextMarker(0, 0, TextMarkerType.SolidBlock, Document.HighlightingStrategy.GetColorFor("Highlighted word").BackgroundColor); Document.MarkerStrategy.AddMarker(testMarker); /*ActiveTextAreaControl.TextArea.MouseMove += (sender, e) => * { * //Document.MarkerStrategy.RemoveMarker(testMarker); * //ActiveTextAreaControl.TextArea.Invalidate(); * * var textPosition = new Point(e.Location.X - ActiveTextAreaControl.TextArea.LeftMargins.Where(m => m.IsVisible).Sum(m => m.Size.Width), e.Location.Y); * if (textPosition.X < 0 || textPosition.Y < 0) return; * * var position = ActiveTextAreaControl.TextArea.TextView.GetLogicalPosition(textPosition); * if (position.Line >= Document.TotalNumberOfLines) return; * * var line = Document.GetLineSegment(position.Line); * if (line == null) return; * var word = line.GetWord(position.Column); * if (word == null || word.IsWhiteSpace) return; * * return; * //word.SyntaxColor = new HighlightColor(word.Color, Color.DarkGray, true, false); * Document.MarkerStrategy.AddMarker(testMarker); * testMarker.Offset = word.Offset + line.Offset; * testMarker.Length = word.Length; * ActiveTextAreaControl.TextArea.Invalidate(); * };*/ var lineAddressToolTip = new ToolTip(); ActiveTextAreaControl.TextArea.ToolTipRequest += (s, e) => { Document.MarkerStrategy.RemoveMarker(testMarker); ActiveTextAreaControl.TextArea.Invalidate(); if (e.ToolTipShown || e.LogicalPosition.Line >= Document.TotalNumberOfLines) { return; } var line = Document.GetLineSegment(e.LogicalPosition.Line); if (line == null) { return; } lineAddressToolTip.Hide(FindForm()); var word = e.InDocument ? GetAsmWord(e.LogicalPosition) : null; if (word == null || word.IsWhiteSpace || word.WordType == AsmWord.AsmWordType.Comment) { var debugLine = GetDebugLine(line.LineNumber); if (debugLine == null || debugLine.CpuAddress == null) { return; } testMarker.Offset = line.Offset; testMarker.Length = line.Length; Document.MarkerStrategy.AddMarker(testMarker); //e.ShowToolTip(WatchValue.FormatHexAddress(debugLine.Address)); lineAddressToolTip.Show( WatchValue.FormatHexAddress(debugLine.CpuAddress.Value), FindForm(), PointToScreen(new Point(-60, e.MousePosition.Y)) , 3000 // TODO: Use a custom form object, not tooltips ); return; } testMarker.Offset = word.Offset + line.Offset; testMarker.Length = word.Length; Document.MarkerStrategy.AddMarker(testMarker); ActiveTextAreaControl.TextArea.Invalidate(); switch (word.WordType) { case AsmWord.AsmWordType.LabelAbsolute: case AsmWord.AsmWordType.LabelReference: case AsmWord.AsmWordType.LabelDefinition: case AsmWord.AsmWordType.Macro: e.ShowToolTip(GetSymbolDescription(word.Word)); break; case AsmWord.AsmWordType.AddressReference: e.ShowToolTip(GetParsedAddress(word.Word)); break; case AsmWord.AsmWordType.Command: var command = Ca65Parser.GetCommandFromWord(word.Word); if (command != null) { e.ShowToolTip(command.ToString()); } break; case AsmWord.AsmWordType.Opcode: var opcode = OpcodeParser.GetOpcodeFromWord(word.Word, File.Project.Type); if (opcode != null) { e.ShowToolTip(opcode.ToString()); } break; default: e.ShowToolTip(word.Word); break; } }; Document.DocumentAboutToBeChanged += (s, arts) => { _changedSinceLastCheck = true; }; //Document.LineCountChanged += (sender, args) => RefreshErrorInfo(); Document.LineLengthChanged += (s, args) => { if (Document.MarkerStrategy.GetMarkers(args.LineSegment.Offset).Any(m => m is ErrorMarker)) { RefreshErrorInfo(); } }; ActiveTextAreaControl.Caret.PositionChanged += (s, a) => { QueueCareInformation(); if (ActiveTextAreaControl.Caret.Line == _caretLine) { return; } _caretLine = ActiveTextAreaControl.Caret.Line; RefreshErrorInfo(); }; ActiveTextAreaControl.TextArea.KeyUp += delegate(object sender, KeyEventArgs e) { /*if (e.KeyCode == Program.Keys[Brewmaster.Settings.Feature.GoToDefinition]) * { * GoToSymbol(); * return; * }*/ //if (e.KeyCode == Keys.Escape) return; if (NavigationKeys.Contains(e.KeyCode)) { return; } ShowIntellisense((char)e.KeyValue, 1); _forcedAutoCompleteWindow = false; HighlightOpcodeOnLine(); }; ActiveTextAreaControl.TextArea.IconBarMargin.MouseDown += (sender, mousepos, buttons) => { if (buttons != MouseButtons.Left) { return; } var line = ActiveTextAreaControl.TextArea.TextView.GetLogicalLine(mousepos.Y); AddBreakpointMarker(line); RefreshBreakpointsInProject(); }; Document.DocumentChanged += (sender, args) => { var changed = false; foreach (var bp in Document.BookmarkManager.Marks.OfType <BreakpointMarker>()) { if (bp.GlobalBreakpoint.CurrentLine != bp.LineNumber + 1) { changed = true; } bp.GlobalBreakpoint.CurrentLine = bp.LineNumber + 1; } if (changed) { RefreshBreakpointsInProject(); } }; }
internal void GoToAddress(AddressReference @ref) { HexTabState tabState; ulong fileOffset; if (@ref.IsRVA) { var asm = assemblyList.FindAssemblyByFileName(@ref.Filename); if (asm == null) return; var pe = asm.PEImage; if (pe == null) return; fileOffset = (ulong)pe.ToFileOffset((RVA)@ref.Address); tabState = GetHexTabStates(@ref.Filename, fileOffset, @ref.Length).FirstOrDefault(); } else { fileOffset = @ref.Address; tabState = GetHexTabStates(@ref.Filename, fileOffset, @ref.Length).FirstOrDefault(); } if (tabState == null) tabState = OpenHexBoxInternal(@ref.Filename); if (tabState == null) return; SetActiveTab(tabState); tabState.SelectAndMoveCaret(fileOffset, @ref.Length); }
void CreateHandler(ShowTabContentEventArgs e, HexViewDocumentTabContent content, HexPosition?fileOffset, AddressReference addrRef) { if (!e.Success) { return; } Debug.Assert(e.Tab.Content == content); var uiContext = e.Tab.UIContext as HexViewDocumentTabUIContext; Debug.Assert(uiContext != null); if (uiContext == null || fileOffset == null) { return; } var start = fileOffset.Value; var end = HexPosition.Min(start + addrRef.Length, HexPosition.MaxEndPosition); if (!IsVisible(uiContext.HexView, start, end)) { uiContext.HexView.Options.SetOptionValue(DefaultHexViewOptions.StartPositionId, uiContext.HexView.Buffer.Span.Start); uiContext.HexView.Options.SetOptionValue(DefaultHexViewOptions.EndPositionId, uiContext.HexView.Buffer.Span.End); RedisplayHexLines(uiContext.HexView); if (!IsVisible(uiContext.HexView, start, end)) { return; } } if (e.HasMovedCaret) { return; } if (!uiContext.HexView.VisualElement.IsLoaded) { RoutedEventHandler loaded = null; loaded = (s, e2) => { uiContext.HexView.VisualElement.Loaded -= loaded; InitializeHexView(uiContext.HexView, start, end); }; uiContext.HexView.VisualElement.Loaded += loaded; } else { InitializeHexView(uiContext.HexView, start, end); } e.HasMovedCaret = true; }
internal void GoToAddress(AddressReference @ref) { HexTabState tabState; ulong fileOffset; if (@ref.IsRVA) { var asm = assemblyList.FindAssemblyByFileName(@ref.Filename); //TODO: Should check whether it's a PE file, not whether it's a .NET file if (asm == null || asm.ModuleDefinition == null) return; var mod = asm.ModuleDefinition as ModuleDefMD; if (mod == null) return; var pe = mod.MetaData.PEImage; fileOffset = (ulong)pe.ToFileOffset((RVA)@ref.Address); tabState = GetHexTabStates(@ref.Filename, fileOffset, @ref.Length).FirstOrDefault(); } else { fileOffset = @ref.Address; tabState = GetHexTabStates(@ref.Filename, fileOffset, @ref.Length).FirstOrDefault(); } if (tabState == null) tabState = OpenHexBoxInternal(@ref.Filename); if (tabState == null) return; SetActiveTab(tabState); tabState.SelectAndMoveCaret(fileOffset, @ref.Length); }