Exemplo n.º 1
0
        private int[] rowAddresses; // rename to rowOffsets

        public ListingViewModel(Assembly assembly, int segmentId)
        {
            this.image = assembly.GetImage();

            // Make a list of the errors in this segment. Ideally we should
            // put this logic into ErrorCollection. But for convenience we
            // leave it here for the moment.
            List <Error> errors =
                (from error in assembly.GetImage().Errors
                 where error.Location.Segment == segmentId
                 orderby error.Location
                 select error).ToList();
            int iError = 0;

            // Find the segment.
            // Todo: we should provide a way to do this.
            Segment segment = null;

            foreach (Segment seg in image.Segments)
            {
                if (seg.Id == segmentId)
                {
                    segment = seg;
                    break;
                }
            }

            // Display analyzed code and data.
            // TODO: a segment may not start at zero.
            Address address = new Address(segmentId, segment.OffsetBounds.Begin);

            while (image.IsAddressValid(address))
            {
                ByteAttribute b = image[address];

                while (iError < errors.Count && errors[iError].Location.Offset <= address.Offset)
                {
                    rows.Add(new ErrorListingRow(assembly, errors[iError++]));
                }

                if (IsLeadByteOfCode(b))
                {
#if false
                    if (b.BasicBlock != null && b.BasicBlock.Location.Offset == i)
                    {
                        rows.Add(new LabelListingRow(0, b.BasicBlock));
                    }
#endif

                    Instruction insn = image.Instructions.Find(address);
                    System.Diagnostics.Debug.Assert(insn != null);
                    rows.Add(new CodeListingRow(
                                 assembly, address, insn,
                                 image.GetBytes(address, insn.EncodedLength).ToArray()));

                    address += insn.EncodedLength; // TODO: handle wrapping
                }
                else if (IsLeadByteOfData(b))
                {
                    Address j = address + 1;
                    while (image.IsAddressValid(j) &&
                           image[j].Type == ByteType.Data &&
                           !image[j].IsLeadByte)
                    {
                        j += 1;
                    }

                    int count = j.Offset - address.Offset;
                    rows.Add(new DataListingRow(
                                 assembly, address,
                                 image.GetBytes(address, count).ToArray()));
                    address = j; // TODO: handle wrapping
                }
                else
                {
                    //if (errorMap.ContainsKey(i))
                    {
                        //    rows.Add(new ErrorListingRow(errorMap[i]));
                    }
                    Address j = address + 1;
                    while (image.IsAddressValid(j) &&
                           !IsLeadByteOfCode(image[j]) &&
                           !IsLeadByteOfData(image[j]))
                    {
                        j += 1;
                    }

                    int count = j.Offset - address.Offset;
                    rows.Add(new BlankListingRow(
                                 assembly, address,
                                 image.GetBytes(address, count).ToArray()));
                    address = j; // TODO: handle wrapping
#if false
                    try
                    {
                        address = address.Increment(j - i);
                    }
                    catch (AddressWrappedException)
                    {
                        address = Address.Invalid;
                    }
#endif
                }
            }

            while (iError < errors.Count)
            {
                rows.Add(new ErrorListingRow(assembly, errors[iError++]));
            }

            // Create a sorted array containing the address of each row.
            rowAddresses = new int[rows.Count];
            for (int i = 0; i < rows.Count; i++)
            {
                rowAddresses[i] = rows[i].Location.Offset;
            }

#if false
            // Create a ProcedureItem view object for each non-empty
            // procedure.
            // TODO: display an error for empty procedures.
            foreach (Procedure proc in image.Procedures)
            {
                if (proc.IsEmpty)
                {
                    continue;
                }

                ProcedureItem item = new ProcedureItem(proc);
                //var range = proc.Bounds;
                //item.FirstRowIndex = FindRowIndex(range.Begin);
                //item.LastRowIndex = FindRowIndex(range.End - 1);

                // TBD: need to check broken instruction conditions
                // as well as leading/trailing unanalyzed bytes.
                procItems.Add(item);
            }

            // Create segment items.
            foreach (Segment segment in image.Segments)
            {
                segmentItems.Add(new SegmentItem(segment));
            }
#endif
        }