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 }
public ListingViewModel(BinaryImage image) { this.image = image; // Make a dictionary that maps a location to the error at that location. // TODO: there may be multiple errors at a single location. Dictionary <LinearPointer, Error> errorMap = new Dictionary <LinearPointer, Error>(); foreach (Error error in image.Errors) { errorMap[error.Location.LinearAddress] = error; } // Display analyzed code and data. Pointer address = image.BaseAddress; for (var i = image.StartAddress; i < image.EndAddress;) { ByteProperties b = image[i]; if (IsLeadByteOfCode(b)) { if (b.BasicBlock != null && b.BasicBlock.StartAddress == i) { rows.Add(new LabelListingRow(0, b.BasicBlock)); } Instruction insn = image.DecodeInstruction(b.Address); rows.Add(new CodeListingRow(0, b.Address, insn, image.GetBytes(i, insn.EncodedLength))); address = b.Address + insn.EncodedLength; i += insn.EncodedLength; } else if (IsLeadByteOfData(b)) { var j = i + 1; while (j < image.EndAddress && image[j].Type == ByteType.Data && !image[j].IsLeadByte) { j++; } rows.Add(new DataListingRow(0, b.Address, image.GetBytes(i, j - i))); address = b.Address + (j - i); i = j; } else { if (errorMap.ContainsKey(i)) { // rows.Add(new ErrorListingRow(errorMap[i])); } var j = i + 1; while (j < image.EndAddress && !IsLeadByteOfCode(image[j]) && !IsLeadByteOfData(image[j])) { j++; } rows.Add(new BlankListingRow(0, address, image.GetBytes(i, j - i))); try { address += (j - i); } catch (AddressWrappedException) { address = Pointer.Invalid; } i = j; } } // Create a sorted array containing the address of each row. rowAddresses = new LinearPointer[rows.Count]; for (int i = 0; i < rows.Count; i++) { rowAddresses[i] = rows[i].Location.LinearAddress; } // 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)); } }