public MODENDRecord(RecordReader reader, RecordContext context) : base(reader, context) { byte type = reader.ReadByte(); this.IsMainModule = (type & 0x80) != 0; this.IsStartAddressPresent = (type & 0x40) != 0; this.IsStartAddressRelocatable = (type & 0x01) != 0; // TODO: read the start address field... }
internal ListOfNamesRecord(RecordReader reader, RecordContext context) : base(reader, context) { List <string> names = new List <string>(); while (!reader.IsEOF) { names.Add(reader.ReadPrefixedString()); } this.Names = names.ToArray(); context.Names.AddRange(Names); }
public LIDATARecord(RecordReader reader, RecordContext context) : base(reader, context) { this.SegmentIndex = reader.ReadIndex(); if (SegmentIndex == 0 || SegmentIndex > context.Segments.Count) { throw new InvalidDataException("SegmentIndex is out of range."); } this.DataOffset = reader.ReadUInt16Or32(); this.Data = reader.ReadToEnd(); // TODO: parse LIDATA (recursive; a bit messy) }
internal WKEXTComment(RecordReader reader) { var defs = new List <WeakExternalDefinition>(); while (!reader.IsEOF) { var def = new WeakExternalDefinition(); def.WeakExternalIndex = reader.ReadIndex(); def.DefaultResolutionIndex = reader.ReadIndex(); defs.Add(def); } this.Definitions = defs.ToArray(); // TODO: add this information into the Context }
public FixupRecord(RecordReader reader, RecordContext context) : base(reader, context) { List <FixupThreadDefinition> threads = new List <FixupThreadDefinition>(); List <FixupDefinition> fixups = new List <FixupDefinition>(); while (!reader.IsEOF) { byte b = reader.PeekByte(); if ((b & 0x80) == 0) { FixupThreadDefinition thread = ParseThreadSubrecord(reader); threads.Add(thread); if (thread.Kind == FixupThreadKind.Target) { context.TargetThreads[thread.ThreadNumber] = thread; } else { context.FrameThreads[thread.ThreadNumber] = thread; } } else { FixupDefinition fixup = ParseFixupSubrecord(reader, context); fixups.Add(fixup); if (context.LastRecord is LEDATARecord) { var r = (LEDATARecord)context.LastRecord; fixup.DataOffset += (ushort)r.DataOffset; r.Segment.Fixups.Add(fixup); } else if (context.LastRecord is LIDATARecord) { } else if (context.LastRecord is COMDATRecord) { } else { throw new InvalidDataException("FIXUPP record must follow LEDATA, LIDATA, or COMDAT record."); } } } this.Threads = threads.ToArray(); this.Fixups = fixups.ToArray(); }
public PUBDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { int baseGroupIndex = reader.ReadIndex(); if (baseGroupIndex > context.Groups.Count) { throw new InvalidDataException("GroupIndex is out of range."); } if (baseGroupIndex > 0) { this.BaseGroup = context.Groups[baseGroupIndex - 1]; } int baseSegmentIndex = reader.ReadIndex(); if (baseSegmentIndex > context.Segments.Count) { throw new InvalidDataException("SegmentIndex is out of range."); } if (baseSegmentIndex == 0) { this.BaseFrame = reader.ReadUInt16(); } else { this.BaseSegment = context.Segments[baseSegmentIndex - 1]; } int startIndex = context.PublicNames.Count; while (!reader.IsEOF) { PublicNameDefinition def = new PublicNameDefinition(); def.DefinedBy = reader.RecordNumber; def.BaseGroup = BaseGroup; def.BaseSegment = BaseSegment; def.BaseFrame = BaseFrame; def.Name = reader.ReadPrefixedString(); def.Offset = (int)reader.ReadUInt16Or32(); def.TypeIndex = reader.ReadIndex(); context.PublicNames.Add(def); } int endIndex = context.PublicNames.Count; this.Definitions = context.PublicNames.Slice( startIndex, endIndex - startIndex); }
public ALIASRecord(RecordReader reader, RecordContext context) : base(reader, context) { int startIndex = context.Aliases.Count; while (!reader.IsEOF) { AliasDefinition def = new AliasDefinition(); def.AliasName = reader.ReadPrefixedString(); def.SubstituteName = reader.ReadPrefixedString(); context.Aliases.Add(def); } int endIndex = context.Aliases.Count; this.Definitions = context.Aliases.Slice(startIndex, endIndex - startIndex); }
public EXTDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { int startIndex = context.ExternalNames.Count; while (!reader.IsEOF) { ExternalNameDefinition def = new ExternalNameDefinition(); def.Name = reader.ReadPrefixedString(); def.TypeIndex = reader.ReadIndex(); def.DefinedBy = reader.RecordNumber; context.ExternalNames.Add(def); } int endIndex = context.ExternalNames.Count; this.Definitions = context.ExternalNames.Slice( startIndex, endIndex - startIndex); }
private FixupThreadDefinition ParseThreadSubrecord(RecordReader reader) { FixupThreadDefinition thread = new FixupThreadDefinition(); byte b = reader.ReadByte(); thread.Kind = ((b & 0x40) == 0) ? FixupThreadKind.Target : FixupThreadKind.Frame; thread.Method = (byte)((b >> 2) & 3); thread.ThreadNumber = (byte)(b & 3); if (thread.Method <= 2) // TBD: should be 3 for intel { thread.IndexOrFrame = reader.ReadIndex(); } thread.IsDefined = true; return(thread); }
public FixupRecord(RecordReader reader, RecordContext context) : base(reader, context) { List<FixupThreadDefinition> threads = new List<FixupThreadDefinition>(); List<FixupDefinition> fixups = new List<FixupDefinition>(); while (!reader.IsEOF) { byte b = reader.PeekByte(); if ((b & 0x80) == 0) { FixupThreadDefinition thread = ParseThreadSubrecord(reader); threads.Add(thread); if (thread.Kind == FixupThreadKind.Target) context.TargetThreads[thread.ThreadNumber] = thread; else context.FrameThreads[thread.ThreadNumber] = thread; } else { FixupDefinition fixup = ParseFixupSubrecord(reader, context); fixups.Add(fixup); if (context.LastRecord is LEDATARecord) { var r = (LEDATARecord)context.LastRecord; fixup.DataOffset += (ushort)r.DataOffset; r.Segment.Fixups.Add(fixup); } else if (context.LastRecord is LIDATARecord) { } else if (context.LastRecord is COMDATRecord) { } else { throw new InvalidDataException("FIXUPP record must follow LEDATA, LIDATA, or COMDAT record."); } } } this.Threads = threads.ToArray(); this.Fixups = fixups.ToArray(); }
public SEGDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { SegmentDefinition def = new SegmentDefinition(); // Read the record. byte acbp = reader.ReadByte(); def.Alignment = GetAlignment(acbp); def.Combination = GetCombination(acbp); def.IsUse32 = GetUse32(acbp); if (def.Alignment == SegmentAlignment.Absolute) { def.Frame = reader.ReadUInt16(); def.Offset = reader.ReadByte(); } UInt32 storedLength=reader.ReadUInt16Or32(); def.Length = GetLength(acbp, storedLength, reader.RecordNumber); UInt16 segmentNameIndex = reader.ReadIndex(); if (segmentNameIndex > context.Names.Count) throw new InvalidDataException("SegmentNameIndex is out of range."); if (segmentNameIndex > 0) def.SegmentName = context.Names[segmentNameIndex - 1]; UInt16 classNameIndex = reader.ReadIndex(); if (classNameIndex > context.Names.Count) throw new InvalidDataException("ClassNameIndex is out of range."); if (classNameIndex > 0) def.ClassName = context.Names[classNameIndex - 1]; UInt16 overlayNameIndex = reader.ReadIndex(); if (overlayNameIndex > context.Names.Count) throw new InvalidDataException("OverlayNameIndex is out of range."); if (overlayNameIndex > 0) def.OverlayName = context.Names[overlayNameIndex - 1]; def.Data = new byte[def.Length]; //def.Fixups = new List<FixupDefinition>(); this.Definition = def; context.Segments.Add(def); }
private static UInt32 ReadEncodedInteger(RecordReader reader) { byte b = reader.ReadByte(); if (b == 0x81) { return(reader.ReadUInt16()); } else if (b == 0x84) { return(reader.ReadUInt24()); } else if (b == 0x88) { return(reader.ReadUInt32()); } else { return(b); } }
public LEDATARecord(RecordReader reader, RecordContext context) : base(reader, context) { UInt16 segmentIndex = reader.ReadIndex(); if (segmentIndex == 0 || segmentIndex > context.Segments.Count) { throw new InvalidDataException("SegmentIndex is out of range."); } this.Segment = context.Segments[segmentIndex - 1]; this.DataOffset = reader.ReadUInt16Or32(); this.Data = reader.ReadToEnd(); // TBD: this can be optimized to // reduce extra data copy // Fill the segment's data. if (Data.Length + DataOffset > Segment.Length) { throw new InvalidDataException("The LEDATA overflows the segment."); } Array.Copy(Data, 0, Segment.Data, DataOffset, Data.Length); }
internal MemoryModelComment(RecordReader reader) { while (!reader.IsEOF) { byte b = reader.ReadByte(); switch ((char)b) { case '0': InstructionSet = 8086; break; case '1': InstructionSet = 80186; break; case '2': InstructionSet = 80286; break; case '3': InstructionSet = 80386; break; case 'O': Optimized = true; break; case 's': MemoryModel = Disassembler.MemoryModel.Small; break; case 'm': MemoryModel = Disassembler.MemoryModel.Medium; break; case 'c': MemoryModel = Disassembler.MemoryModel.Compact; break; case 'l': MemoryModel = Disassembler.MemoryModel.Large; break; case 'h': MemoryModel = Disassembler.MemoryModel.Huge; break; case 'A': InstructionSet = 68000; break; case 'B': InstructionSet = 68010; break; case 'C': InstructionSet = 68020; break; case 'D': InstructionSet = 68030; break; } } }
public SEGDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { SegmentDefinition def = new SegmentDefinition(); // Read the record. byte acbp = reader.ReadByte(); def.Alignment = GetAlignment(acbp); def.Combination = GetCombination(acbp); def.IsUse32 = GetUse32(acbp); if (def.Alignment == SegmentAlignment.Absolute) { def.Frame = reader.ReadUInt16(); def.Offset = reader.ReadByte(); } UInt32 storedLength = reader.ReadUInt16Or32(); def.Length = GetLength(acbp, storedLength, reader.RecordNumber); UInt16 segmentNameIndex = reader.ReadIndex(); if (segmentNameIndex > context.Names.Count) { throw new InvalidDataException("SegmentNameIndex is out of range."); } if (segmentNameIndex > 0) { def.SegmentName = context.Names[segmentNameIndex - 1]; } UInt16 classNameIndex = reader.ReadIndex(); if (classNameIndex > context.Names.Count) { throw new InvalidDataException("ClassNameIndex is out of range."); } if (classNameIndex > 0) { def.ClassName = context.Names[classNameIndex - 1]; } UInt16 overlayNameIndex = reader.ReadIndex(); if (overlayNameIndex > context.Names.Count) { throw new InvalidDataException("OverlayNameIndex is out of range."); } if (overlayNameIndex > 0) { def.OverlayName = context.Names[overlayNameIndex - 1]; } def.Data = new byte[def.Length]; //def.Fixups = new List<FixupDefinition>(); this.Definition = def; context.Segments.Add(def); }
internal DOSSEGComment(RecordReader reader) { }
public THEADRRecord(RecordReader reader, RecordContext context) : base(reader, context) { this.Name = reader.ReadPrefixedString(); context.SourceName = Name; }
public LEDATARecord(RecordReader reader, RecordContext context) : base(reader, context) { UInt16 segmentIndex = reader.ReadIndex(); if (segmentIndex == 0 || segmentIndex > context.Segments.Count) { throw new InvalidDataException("SegmentIndex is out of range."); } this.Segment = context.Segments[segmentIndex - 1]; this.DataOffset = reader.ReadUInt16Or32(); this.Data = reader.ReadToEnd(); // TBD: this can be optimized to // reduce extra data copy // Fill the segment's data. if (Data.Length + DataOffset > Segment.Length) throw new InvalidDataException("The LEDATA overflows the segment."); Array.Copy(Data, 0, Segment.Data, DataOffset, Data.Length); }
internal TextComment(RecordReader reader, string key) { this.Key = key; this.Value = reader.ReadToEndAsString(); }
public LIBMODComment(RecordReader reader, RecordContext context) { this.ModuleName = reader.ReadPrefixedString(); context.ObjectName = ModuleName; }
/// <summary> /// The presence of any unrecognized subtype causes the linker to /// generate a fatal error. /// </summary> private static Comment ParseOmfExtensions(RecordReader reader) { byte subtype = reader.ReadByte(); return(null); }
internal UnknownComment(RecordReader reader, byte commentClass) { this.CommentClass = commentClass; this.Data = reader.ReadToEnd(); }
private FixupDefinition ParseFixupSubrecord(RecordReader reader, RecordContext context) { FixupDefinition fixup = new FixupDefinition(); byte b1 = reader.ReadByte(); byte b2 = reader.ReadByte(); UInt16 w = (UInt16)((b1 << 8) | b2); // big endian fixup.Mode = (w & 0x4000) != 0 ? FixupMode.SegmentRelative : FixupMode.SelfRelative; fixup.Location = (FixupLocation)((w >> 10) & 0x0F); fixup.DataOffset = (UInt16)(w & 0x03FF); byte b = reader.ReadByte(); bool useFrameThread = (b & 0x80) != 0; if (useFrameThread) { int frameNumber = (b >> 4) & 0x3; FixupThreadDefinition thread = context.FrameThreads[frameNumber]; if (!thread.IsDefined) { throw new InvalidDataException("Frame thread " + frameNumber + " is not defined."); } FixupFrame spec = new FixupFrame(); spec.Method = (FixupFrameMethod)thread.Method; spec.IndexOrFrame = thread.IndexOrFrame; fixup.Frame = spec; } else { FixupFrame spec = new FixupFrame(); spec.Method = (FixupFrameMethod)((b >> 4) & 7); if ((int)spec.Method <= 3) { spec.IndexOrFrame = reader.ReadIndex(); } fixup.Frame = spec; } bool useTargetThread = (b & 0x08) != 0; if (useTargetThread) { bool hasTargetDisplacement = (b & 0x04) != 0; int targetNumber = b & 3; FixupThreadDefinition thread = context.TargetThreads[targetNumber]; if (!thread.IsDefined) { throw new InvalidDataException("Target thread " + targetNumber + " is not defined."); } FixupTargetMethod method = (FixupTargetMethod)((int)thread.Method & 3); if (hasTargetDisplacement) { method |= (FixupTargetMethod)4; } FixupTarget spec = new FixupTarget(); spec.Referent = ResolveFixupReferent(context, method, thread.IndexOrFrame); if ((int)method <= 3) { spec.Displacement = reader.ReadUInt16Or32(); } fixup.Target = spec; } else { FixupTargetMethod method = (FixupTargetMethod)(b & 7); UInt16 indexOrFrame = reader.ReadIndex(); FixupTarget spec = new FixupTarget(); spec.Referent = ResolveFixupReferent(context, method, indexOrFrame); if ((int)method <= 3) { spec.Displacement = reader.ReadUInt16Or32(); } fixup.Target = spec; } return(fixup); }
public UnknownRecord(RecordReader reader, RecordContext context) : base(reader, context) { this.Data = reader.Data; }
public LibraryEndRecord(RecordReader reader, RecordContext context) : base(reader, context) { // Record data serves as padding to align the dictionary that // follows at 512-byte boundary. }
internal CommentRecord(RecordReader reader, RecordContext context) : base(reader, context) { byte commentType = reader.ReadByte(); this.IsPreserved = (commentType & 0x80) != 0; this.IsHidden = (commentType & 0x40) != 0; byte commentClass = reader.ReadByte(); switch (commentClass) { case 0: Comment = new TextComment(reader, "Translator"); break; case 1: Comment = new TextComment(reader, "Copyright"); break; case 0x81: case 0x9F: Comment = new TextComment(reader, "DefaultLibrarySearchName"); break; case 0x9C: // not supported break; case 0x9D: Comment = new MemoryModelComment(reader); break; case 0x9E: Comment = new DOSSEGComment(reader); break; case 0xA0: // OMF Extensions Comment = ParseOmfExtensions(reader); break; case 0xA1: // debug symbol type, such as CV; ignored break; case 0xA2: Comment = new LinkPassSeparatorComment(reader); break; case 0xA3: Comment = new LIBMODComment(reader, context); break; case 0xA4: // EXESTR break; case 0xA6: // INCERR break; case 0xA7: // NOPAD break; case 0xA8: // WKEXT Comment = new WKEXTComment(reader); break; case 0xA9: // LZEXT break; case 0xDA: Comment = new TextComment(reader, "Comment"); break; case 0xDB: Comment = new TextComment(reader, "Compiler"); break; case 0xDC: Comment = new TextComment(reader, "Date"); break; case 0xDD: Comment = new TextComment(reader, "Timestamp"); break; case 0xDF: Comment = new TextComment(reader, "User"); break; case 0xE9: // borland Comment = new TextComment(reader, "Dependencies"); break; case 0xFF: // MS QuickC Comment = new TextComment(reader, "CommandLine"); break; } if (Comment == null) { Comment = new UnknownComment(reader, commentClass); } }
public LHEADRRecord(RecordReader reader, RecordContext context) : base(reader, context) { this.Name = reader.ReadPrefixedString(); }
public LIDATARecord(RecordReader reader, RecordContext context) : base(reader, context) { this.SegmentIndex = reader.ReadIndex(); if (SegmentIndex == 0 || SegmentIndex > context.Segments.Count) throw new InvalidDataException("SegmentIndex is out of range."); this.DataOffset = reader.ReadUInt16Or32(); this.Data = reader.ReadToEnd(); // TODO: parse LIDATA (recursive; a bit messy) }
public GRPDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { this.Definition = new GroupDefinition(); UInt16 groupNameIndex = reader.ReadIndex(); if (groupNameIndex == 0 || groupNameIndex > context.Names.Count) { throw new InvalidDataException("GroupNameIndex is out of range."); } this.Definition.Name = context.Names[groupNameIndex - 1]; while (!reader.IsEOF) { reader.ReadByte(); // 'type' ignored UInt16 segmentIndex = reader.ReadIndex(); if (segmentIndex == 0 || segmentIndex > context.Segments.Count) { throw new InvalidDataException("SegmentIndex is out of range."); } this.Definition.Segments.Add(context.Segments[segmentIndex - 1]); } context.Groups.Add(Definition); }
public COMDATRecord(RecordReader reader, RecordContext context) : base(reader, context) { // TODO: parse contents. }
public LibraryHeaderRecord(RecordReader reader, RecordContext context) : base(reader, context) { this.PageSize = reader.Data.Length + 4; // Record data consists of 7 bytes of dictionary information // (which we ignore), followed by padding bytes to make the next // record (which should be THEADR) aligned on page boundary. }
public LPUBDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { }
internal LinkPassSeparatorComment(RecordReader reader) { byte subtype = reader.ReadByte(); IsPresent = (subtype == 1); }
public PUBDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { int baseGroupIndex = reader.ReadIndex(); if (baseGroupIndex > context.Groups.Count) throw new InvalidDataException("GroupIndex is out of range."); if (baseGroupIndex > 0) this.BaseGroup = context.Groups[baseGroupIndex - 1]; int baseSegmentIndex = reader.ReadIndex(); if (baseSegmentIndex > context.Segments.Count) throw new InvalidDataException("SegmentIndex is out of range."); if (baseSegmentIndex == 0) this.BaseFrame = reader.ReadUInt16(); else this.BaseSegment = context.Segments[baseSegmentIndex - 1]; int startIndex = context.PublicNames.Count; while (!reader.IsEOF) { PublicNameDefinition def = new PublicNameDefinition(); def.DefinedBy = reader.RecordNumber; def.BaseGroup = BaseGroup; def.BaseSegment = BaseSegment; def.BaseFrame = BaseFrame; def.Name = reader.ReadPrefixedString(); def.Offset = (int)reader.ReadUInt16Or32(); def.TypeIndex = reader.ReadIndex(); context.PublicNames.Add(def); } int endIndex = context.PublicNames.Count; this.Definitions = context.PublicNames.Slice( startIndex, endIndex - startIndex); }
private FixupThreadDefinition ParseThreadSubrecord(RecordReader reader) { FixupThreadDefinition thread = new FixupThreadDefinition(); byte b = reader.ReadByte(); thread.Kind = ((b & 0x40) == 0) ? FixupThreadKind.Target : FixupThreadKind.Frame; thread.Method = (byte)((b >> 2) & 3); thread.ThreadNumber = (byte)(b & 3); if (thread.Method <= 2) // TBD: should be 3 for intel thread.IndexOrFrame = reader.ReadIndex(); thread.IsDefined = true; return thread; }
/// <summary> /// The presence of any unrecognized subtype causes the linker to /// generate a fatal error. /// </summary> private static Comment ParseOmfExtensions(RecordReader reader) { byte subtype = reader.ReadByte(); return null; }
internal static Record ReadRecord( BinaryReader binaryReader, RecordContext context, RecordNumber expectedRecord) { RecordReader reader = new RecordReader(binaryReader); if (expectedRecord != RecordNumber.None && reader.RecordNumber != expectedRecord) { throw new InvalidDataException(string.Format( "Expecting record {0}, but got record {1}.", expectedRecord, reader.RecordNumber)); } Record r; switch (reader.RecordNumber) { case RecordNumber.LibraryHeader: r = new LibraryHeaderRecord(reader, context); break; case RecordNumber.LibraryEnd: r = new LibraryEndRecord(reader, context); break; case RecordNumber.ALIAS: r = new ALIASRecord(reader, context); break; case RecordNumber.CEXTDEF: r = new CEXTDEFRecord(reader, context); break; case RecordNumber.COMDAT: case RecordNumber.COMDAT32: r = new COMDATRecord(reader, context); break; case RecordNumber.COMDEF: r = new COMDEFRecord(reader, context); break; case RecordNumber.COMENT: r = new CommentRecord(reader, context); break; case RecordNumber.EXTDEF: r = new EXTDEFRecord(reader, context); break; case RecordNumber.FIXUPP: case RecordNumber.FIXUPP32: r = new FixupRecord(reader, context); break; case RecordNumber.GRPDEF: r = new GRPDEFRecord(reader, context); break; case RecordNumber.LCOMDEF: r = new LCOMDEFRecord(reader, context); break; case RecordNumber.LEDATA: case RecordNumber.LEDATA32: r = new LEDATARecord(reader, context); break; case RecordNumber.LEXTDEF: case RecordNumber.LEXTDEF32: r = new LEXTDEFRecord(reader, context); break; case RecordNumber.LHEADR: r = new LHEADRRecord(reader, context); break; case RecordNumber.LIDATA: case RecordNumber.LIDATA32: r = new LIDATARecord(reader, context); break; case RecordNumber.LNAMES: r = new ListOfNamesRecord(reader, context); break; case RecordNumber.LPUBDEF: case RecordNumber.LPUBDEF32: r = new LPUBDEFRecord(reader, context); break; case RecordNumber.MODEND: r = new MODENDRecord(reader, context); break; case RecordNumber.PUBDEF: case RecordNumber.PUBDEF32: r = new PUBDEFRecord(reader, context); break; case RecordNumber.SEGDEF: case RecordNumber.SEGDEF32: r = new SEGDEFRecord(reader, context); break; case RecordNumber.THEADR: r = new THEADRRecord(reader, context); break; default: r = new UnknownRecord(reader, context); break; } // TODO: check all bytes are consumed. // ... // Update RecordContext.LastRecord. This is necessary so that // a FIXUPP record knows which record to fix up. if (context != null) { context.LastRecord = r; } return(r); }
internal TextComment(RecordReader reader,string key) { this.Key = key; this.Value = reader.ReadToEndAsString(); }
public COMDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { int startIndex = context.ExternalNames.Count; while (!reader.IsEOF) { CommunalNameDefinition def = new CommunalNameDefinition(); def.DefinedBy = reader.RecordNumber; def.Name = reader.ReadPrefixedString(); def.TypeIndex = reader.ReadIndex(); def.DataType = reader.ReadByte(); def.ElementCount = ReadEncodedInteger(reader); if (def.DataType == 0x61) // FAR data: count, elemsize def.ElementSize = ReadEncodedInteger(reader); else def.ElementSize = 1; context.ExternalNames.Add(def); } int endIndex = context.ExternalNames.Count; this.Definitions = context.ExternalNames.Slice( startIndex, endIndex - startIndex); }
internal WKEXTComment(RecordReader reader) { var defs = new List<WeakExternalDefinition>(); while (!reader.IsEOF) { var def = new WeakExternalDefinition(); def.WeakExternalIndex = reader.ReadIndex(); def.DefaultResolutionIndex = reader.ReadIndex(); defs.Add(def); } this.Definitions = defs.ToArray(); // TODO: add this information into the Context }
private static UInt32 ReadEncodedInteger(RecordReader reader) { byte b = reader.ReadByte(); if (b == 0x81) return reader.ReadUInt16(); else if (b == 0x84) return reader.ReadUInt24(); else if (b == 0x88) return reader.ReadUInt32(); else return b; }
public LCOMDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { }
private FixupDefinition ParseFixupSubrecord(RecordReader reader, RecordContext context) { FixupDefinition fixup = new FixupDefinition(); byte b1 = reader.ReadByte(); byte b2 = reader.ReadByte(); UInt16 w = (UInt16)((b1 << 8) | b2); // big endian fixup.Mode = (w & 0x4000) != 0 ? FixupMode.SegmentRelative : FixupMode.SelfRelative; fixup.Location = (FixupLocation)((w >> 10) & 0x0F); fixup.DataOffset = (UInt16)(w & 0x03FF); byte b = reader.ReadByte(); bool useFrameThread = (b & 0x80) != 0; if (useFrameThread) { int frameNumber = (b >> 4) & 0x3; FixupThreadDefinition thread = context.FrameThreads[frameNumber]; if (!thread.IsDefined) throw new InvalidDataException("Frame thread " + frameNumber + " is not defined."); FixupFrame spec = new FixupFrame(); spec.Method = (FixupFrameMethod)thread.Method; spec.IndexOrFrame = thread.IndexOrFrame; fixup.Frame = spec; } else { FixupFrame spec = new FixupFrame(); spec.Method = (FixupFrameMethod)((b >> 4) & 7); if ((int)spec.Method <= 3) { spec.IndexOrFrame = reader.ReadIndex(); } fixup.Frame = spec; } bool useTargetThread = (b & 0x08) != 0; if (useTargetThread) { bool hasTargetDisplacement = (b & 0x04) != 0; int targetNumber = b & 3; FixupThreadDefinition thread = context.TargetThreads[targetNumber]; if (!thread.IsDefined) throw new InvalidDataException("Target thread " + targetNumber + " is not defined."); FixupTargetMethod method = (FixupTargetMethod)((int)thread.Method & 3); if (hasTargetDisplacement) method |= (FixupTargetMethod)4; FixupTarget spec = new FixupTarget(); spec.Referent = ResolveFixupReferent(context, method, thread.IndexOrFrame); if ((int)method <= 3) { spec.Displacement = reader.ReadUInt16Or32(); } fixup.Target = spec; } else { FixupTargetMethod method = (FixupTargetMethod)(b & 7); UInt16 indexOrFrame = reader.ReadIndex(); FixupTarget spec = new FixupTarget(); spec.Referent = ResolveFixupReferent(context, method, indexOrFrame); if ((int)method <= 3) { spec.Displacement = reader.ReadUInt16Or32(); } fixup.Target = spec; } return fixup; }
public CEXTDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { int startIndex = context.ExternalNames.Count; while (!reader.IsEOF) { UInt16 nameIndex = reader.ReadIndex(); if (nameIndex == 0 || nameIndex > context.Names.Count) { throw new InvalidDataException("LogicalNameIndex is out of range."); } UInt16 typeIndex = reader.ReadIndex(); ExternalNameDefinition def = new ExternalNameDefinition(); def.Name = context.Names[nameIndex - 1]; def.TypeIndex = typeIndex; def.DefinedBy = reader.RecordNumber; context.ExternalNames.Add(def); } int endIndex = context.ExternalNames.Count; this.Definitions = context.ExternalNames.Slice( startIndex, endIndex - startIndex); }
internal Record(RecordReader reader, RecordContext context) { this.Position = reader.Position; this.RecordNumber = reader.RecordNumber; }