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); }
/// <summary> /// Loads a LIB file from a BinaryReader. /// </summary> /// <param name="reader"></param> /// <returns></returns> public static IEnumerable <Records.RecordContext> LoadLibrary(BinaryReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } LibraryHeaderRecord r = (LibraryHeaderRecord) Record.ReadRecord(reader, null, RecordNumber.LibraryHeader); int pageSize = r.PageSize; while (true) { Records.RecordContext module = LoadObject(reader); if (module == null) // LibraryEndRecord encountered { yield break; } yield return(module); // Since a LIB file consists of multiple object modules // aligned on page boundary, we need to consume the padding // bytes if present. int mod = (int)(reader.BaseStream.Position % pageSize); if (mod != 0) { reader.ReadBytes(pageSize - mod); } } }
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); }
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 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 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) }
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); }
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); }
/// <summary> /// Loads an object module from binary reader. /// </summary> /// <param name="reader"></param> /// <returns> /// The loaded module if successful, or null if LibraryEndRecord is /// encountered before MODEND or MODEND32 record is encountered. /// </returns> public static RecordContext LoadObject(BinaryReader reader) { List<Record> records = new List<Record>(); RecordContext context = new RecordContext(); while (true) { Record record = Record.ReadRecord(reader, context); records.Add(record); if (record.RecordNumber == RecordNumber.MODEND || record.RecordNumber == RecordNumber.MODEND32) { break; } if (record.RecordNumber == RecordNumber.LibraryEnd) { return null; } } context.Records = records.ToArray(); return context; }
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); }
private static object ResolveFixupReferent( RecordContext context, FixupTargetMethod method, UInt16 indexOrFrame) { switch (method) { case FixupTargetMethod.Absolute: return(indexOrFrame); case FixupTargetMethod.SegmentPlusDisplacement: case FixupTargetMethod.SegmentWithoutDisplacement: return(context.Segments[indexOrFrame - 1]); case FixupTargetMethod.GroupPlusDisplacement: case FixupTargetMethod.GroupWithoutDisplacement: return(context.Groups[indexOrFrame - 1]); case FixupTargetMethod.ExternalPlusDisplacement: case FixupTargetMethod.ExternalWithoutDisplacement: return(context.ExternalNames[indexOrFrame - 1]); default: throw new InvalidDataException("Invalid fixup target method: " + method); } }
public THEADRRecord(RecordReader reader, RecordContext context) : base(reader, context) { this.Name = reader.ReadPrefixedString(); context.SourceName = Name; }
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 LibraryEndRecord(RecordReader reader, RecordContext context) : base(reader, context) { // Record data serves as padding to align the dictionary that // follows at 512-byte boundary. }
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); }
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 LIBMODComment(RecordReader reader, RecordContext context) { this.ModuleName = reader.ReadPrefixedString(); context.ObjectName = ModuleName; }
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); }
public COMDATRecord(RecordReader reader, RecordContext context) : base(reader, context) { // TODO: parse contents. }
public UnknownRecord(RecordReader reader, RecordContext context) : base(reader, context) { this.Data = reader.Data; }
internal static Record ReadRecord(BinaryReader binaryReader, RecordContext context) { return(ReadRecord(binaryReader, context, RecordNumber.None)); }
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 LCOMDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { }
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(); }
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); }
internal Record(RecordReader reader, RecordContext context) { this.Position = reader.Position; this.RecordNumber = reader.RecordNumber; }
public LPUBDEFRecord(RecordReader reader, RecordContext context) : base(reader, context) { }
internal static Record ReadRecord(BinaryReader binaryReader, RecordContext context) { return ReadRecord(binaryReader, context, RecordNumber.None); }
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); }
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; }
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 object ResolveFixupReferent( RecordContext context, FixupTargetMethod method, UInt16 indexOrFrame) { switch (method) { case FixupTargetMethod.Absolute: return indexOrFrame; case FixupTargetMethod.SegmentPlusDisplacement: case FixupTargetMethod.SegmentWithoutDisplacement: return context.Segments[indexOrFrame - 1]; case FixupTargetMethod.GroupPlusDisplacement: case FixupTargetMethod.GroupWithoutDisplacement: return context.Groups[indexOrFrame - 1]; case FixupTargetMethod.ExternalPlusDisplacement: case FixupTargetMethod.ExternalWithoutDisplacement: return context.ExternalNames[indexOrFrame - 1]; default: throw new InvalidDataException("Invalid fixup target method: " + method); } }
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); }