Example #1
0
        private void RoutineTable_RoutineAdded(object sender, ZRoutineAddedEventArgs e)
        {
            lines.BeginBulkOperation();
            try
            {
                // Find routine header line that would follow this routine
                int nextRoutineIndex = -1;
                int insertionPoint   = -1;
                for (int i = 0; i < routineAddressAndIndexList.Count; i++)
                {
                    var addressAndIndex = routineAddressAndIndexList[i];
                    if (addressAndIndex.Address > e.Routine.Address)
                    {
                        nextRoutineIndex = i;
                        insertionPoint   = addressAndIndex.Index;
                        break;
                    }
                }

                // If no routine header found, insert at the end of the list.
                if (nextRoutineIndex == -1)
                {
                    insertionPoint = lines.Count;
                }

                var count = 0;

                // Is previous line an address gap? If so, we need to either remove it or update it in place.
                if (insertionPoint > 0)
                {
                    var addressGap = lines[insertionPoint - 1] as DisassemblyAddressGapLineViewModel;
                    if (addressGap != null)
                    {
                        var priorRoutine = addressGap.Start;
                        var nextRoutine  = addressGap.End;

                        if (addressGap.StartAddress == e.Routine.Address)
                        {
                            // If the address gap starts at this routine, we need to remove it.
                            lines.RemoveAt(--insertionPoint);
                            count--;
                        }
                        else if (addressGap.StartAddress < e.Routine.Address)
                        {
                            // If the address gap starts before this routine, we need to update it in place.
                            lines[insertionPoint - 1] = new DisassemblyAddressGapLineViewModel(priorRoutine, e.Routine)
                            {
                                ShowBlankBefore = true
                            };
                        }

                        if (nextRoutine.Address > e.Routine.Address + e.Routine.Length - 1)
                        {
                            // If there is a gap between this routine and the next one, we need to insert an address gap.
                            var newAddressGap = new DisassemblyAddressGapLineViewModel(e.Routine, nextRoutine)
                            {
                                ShowBlankBefore = true
                            };

                            lines.Insert(insertionPoint, newAddressGap);
                            count++;
                        }
                    }
                }

                var instructions = e.Routine.Instructions;
                var lastIndex    = instructions.Length - 1;
                for (int i = lastIndex; i >= 0; i--)
                {
                    var instruction     = instructions[i];
                    var instructionLine = new DisassemblyInstructionLineViewModel(instruction, i == lastIndex);

                    if (breakpointService.Exists(instruction.Address))
                    {
                        instructionLine.HasBreakpoint = true;
                    }

                    lines.Insert(insertionPoint, instructionLine);
                    count++;
                    addressToLineMap.Add(instruction.Address, instructionLine);
                }

                var routineHeaderLine = new DisassemblyRoutineHeaderLineViewModel(e.Routine)
                {
                    ShowBlankBefore = insertionPoint > 0,
                    ShowBlankAfter  = true
                };

                lines.Insert(insertionPoint, routineHeaderLine);
                count++;
                addressToLineMap.Add(e.Routine.Address, routineHeaderLine);

                if (nextRoutineIndex >= 0)
                {
                    // fix up routine indeces...
                    for (int i = nextRoutineIndex; i < routineAddressAndIndexList.Count; i++)
                    {
                        var addressAndIndex = routineAddressAndIndexList[i];
                        routineAddressAndIndexList[i] = new AddressAndIndex(addressAndIndex.Address, addressAndIndex.Index + count);
                    }

                    routineAddressAndIndexList.Insert(nextRoutineIndex, new AddressAndIndex(e.Routine.Address, insertionPoint));
                }
                else
                {
                    routineAddressAndIndexList.Add(new AddressAndIndex(e.Routine.Address, insertionPoint));
                }
            }
            finally
            {
                lines.EndBulkOperation();
            }
        }
Example #2
0
        private void DebuggerService_MachineCreated(object sender, MachineCreatedEventArgs e)
        {
            var reader = new MemoryReader(storyService.Story.Memory, 0);

            DisassemblyLineViewModel ipLine;

            lines.BeginBulkOperation();
            try
            {
                var routineTable = routineService.RoutineTable;

                for (int rIndex = 0; rIndex < routineTable.Count; rIndex++)
                {
                    var routine = routineTable[rIndex];

                    if (rIndex > 0)
                    {
                        var lastRoutine = routineTable[rIndex - 1];
                        if (lastRoutine.Address + lastRoutine.Length < routine.Address)
                        {
                            var addressGapLine = new DisassemblyAddressGapLineViewModel(lastRoutine, routine)
                            {
                                ShowBlankBefore = true
                            };

                            lines.Add(addressGapLine);
                        }
                    }

                    var routineHeaderLine = new DisassemblyRoutineHeaderLineViewModel(routine)
                    {
                        ShowBlankBefore = rIndex > 0,
                        ShowBlankAfter  = true
                    };

                    routineAddressAndIndexList.Add(new AddressAndIndex(routineHeaderLine.Address, lines.Count));
                    lines.Add(routineHeaderLine);
                    addressToLineMap.Add(routine.Address, routineHeaderLine);

                    var instructions = routine.Instructions;
                    var lastIndex    = instructions.Length - 1;
                    for (int i = 0; i <= lastIndex; i++)
                    {
                        var instruction     = instructions[i];
                        var instructionLine = new DisassemblyInstructionLineViewModel(instruction, i == lastIndex);

                        if (breakpointService.Exists(instruction.Address))
                        {
                            instructionLine.HasBreakpoint = true;
                        }

                        lines.Add(instructionLine);
                        addressToLineMap.Add(instruction.Address, instructionLine);
                    }
                }

                ipLine       = GetLineByAddress(debuggerService.Machine.PC);
                ipLine.HasIP = true;
            }
            finally
            {
                lines.EndBulkOperation();
            }

            BringLineIntoView(ipLine);

            routineService.RoutineTable.RoutineAdded += RoutineTable_RoutineAdded;
        }