Exemple #1
0
 /// <summary>
 /// Adds one or more OmfReloc instances to the list to represent the provided record.
 /// </summary>
 /// <param name="omfSeg">Segment that contains the record.</param>
 /// <param name="omfRec">Record to add.</param>
 /// <param name="data">File data.</param>
 /// <param name="relocs">List of relocations.  New entries will be appended.</param>
 /// <returns>True on success.</returns>
 public static bool GenerateRelocs(OmfSegment omfSeg, OmfRecord omfRec, byte[] data,
                                   List <OmfReloc> relocs)
 {
     try {
         return(DoGenerateRelocs(omfSeg, omfRec, data, relocs));
     } catch (IndexOutOfRangeException ioore) {
         Debug.WriteLine("Caught IOORE during reloc gen (" + omfRec.Op + "): " +
                         ioore.Message);
         return(false);
     }
 }
Exemple #2
0
 /// <summary>
 /// Creates a new OmfRecord instance from the data at the specified offset.
 /// </summary>
 /// <remarks>
 /// This does not catch segment boundary overruns, unless they happen to overrun
 /// the buffer entirely.  The caller should either pass in a buffer that holds the
 /// exact segment data, or check the return value for excess length.
 /// </remarks>
 /// <param name="data">Data to analyze.</param>
 /// <param name="offset">Offset of start of record.</param>
 /// <param name="version">OMF segment version number.</param>
 /// <param name="labLen">Label length, defined in OMF segment header.</param>
 /// <param name="msgs">Output message holder.</param>
 /// <param name="omfRec">New record instance.</param>
 /// <returns>True on success.</returns>
 public static bool ParseRecord(byte[] data, int offset,
                                OmfSegment.SegmentVersion version, int labLen, Formatter formatter,
                                List <string> msgs, out OmfRecord omfRec)
 {
     omfRec            = new OmfRecord();
     omfRec.FileOffset = offset;
     try {
         return(omfRec.DoParseRecord(data, offset, version, labLen, formatter, msgs));
     } catch (IndexOutOfRangeException ioore) {
         OmfSegment.AddErrorMsg(msgs, offset, "buffer overrun while parsing record");
         Debug.WriteLine("Exception thrown decoding record: " + ioore.Message);
         return(false);
     }
 }
Exemple #3
0
        public bool ParseBody(Formatter formatter, List <string> msgs)
        {
            int offset = FileOffset + DispData;

            while (true)
            {
                bool result = OmfRecord.ParseRecord(mFileData, offset, Version, LabLen,
                                                    formatter, msgs, out OmfRecord omfRec);
                if (!result)
                {
                    // Parsing failure.  Bail out.
                    return(false);
                }
                if (offset + omfRec.Length > FileOffset + RawFileLength)
                {
                    // Overrun.
                    AddErrorMsg(msgs, offset, "record ran off end of file (" + omfRec + ")");
                    return(false);
                }

                if (omfRec.Op == OmfRecord.Opcode.END)
                {
                    // v0/v1 pad to 512-byte block boundaries, so some slop is expected there,
                    // but v2.x should be snug.  Doesn't have to be, but might indicate a
                    // bug in the parser.
                    int remaining = (FileOffset + FileLength) - (offset + omfRec.Length);
                    Debug.Assert(remaining >= 0);
                    Debug.WriteLine("END record found, remaining space=" + remaining);
                    if (remaining >= DISK_BLOCK_SIZE ||
                        (Version >= SegmentVersion.v2_0 && remaining != 0))
                    {
                        AddInfoMsg(msgs, offset, "found " + remaining + " bytes past END record");
                    }
                    return(true);
                }

                Records.Add(omfRec);
                offset += omfRec.Length;
            }
        }
Exemple #4
0
        /// <summary>
        /// Generates a series of relocation items for a SUPER record.
        /// </summary>
        private static bool GenerateRelocForSuper(OmfSegment omfSeg, OmfRecord omfRec, byte[] data,
                                                  List <OmfReloc> relocs)
        {
            int offset    = omfRec.FileOffset;
            int remaining = RawData.GetWord(data, offset + 1, 4, false);
            int type      = data[offset + 5];

            offset += 6;        // we've consumed 6 bytes
            remaining--;        // ...but only 1 counts against the SUPER length

            int  width, shift, fileNum, segNum;
            bool needSegNum = false;

            if (type == 0)
            {
                // SUPER RELOC2
                width   = 2;
                shift   = 0;
                fileNum = segNum = -1;
            }
            else if (type == 1)
            {
                // SUPER RELOC3
                width   = 3;
                shift   = 0;
                fileNum = segNum = -1;
            }
            else if (type >= 2 && type <= 13)
            {
                // SUPER INTERSEG1 - SUPER INTERSEG12
                width      = 3;
                shift      = 0;
                fileNum    = type - 1;
                segNum     = -100;
                needSegNum = true;
            }
            else if (type >= 14 && type <= 25)
            {
                // SUPER INTERSEG13 - SUPER INTERSEG24
                width   = 2;
                shift   = 0;
                fileNum = 1;
                segNum  = type - 13;
            }
            else if (type >= 26 && type <= 37)
            {
                // SUPER INTERSEG25 - SUPER INTERSEG36
                width   = 2;
                shift   = -16;      // right shift
                fileNum = 1;
                segNum  = type - 25;
            }
            else
            {
                return(false);
            }

            int page = 0;

            while (remaining > 0)
            {
                int patchCount = data[offset++];
                remaining--;

                if ((patchCount & 0x80) != 0)
                {
                    // high bit set, this is a skip-count
                    page += (patchCount & 0x7f);
                    continue;
                }
                patchCount++;       // zero means one patch
                while (patchCount-- != 0)
                {
                    int patchOff = data[offset++];
                    remaining--;

                    int relocOff = page * 256 + patchOff;

                    byte[] constData   = omfSeg.GetConstData();
                    int    relocRelOff = RawData.GetWord(constData, relocOff, 2, false);
                    if (needSegNum)
                    {
                        segNum = constData[relocOff + 2];
                    }

                    relocs.Add(new OmfReloc(width, shift, relocOff, relocRelOff,
                                            fileNum, segNum, type));
                }

                page++;
            }

            if (remaining < 0)
            {
                Debug.WriteLine("Ran off end of SUPER record");
                Debug.Assert(false);
                return(false);
            }

            return(true);
        }
Exemple #5
0
        /// <summary>
        /// Adds one or more OmfReloc instances to the list to represent the provided record.
        /// </summary>
        private static bool DoGenerateRelocs(OmfSegment omfSeg, OmfRecord omfRec, byte[] data,
                                             List <OmfReloc> relocs)
        {
            int offset = omfRec.FileOffset;

            Debug.Assert(data[offset] == (int)omfRec.Op);
            switch (omfRec.Op)
            {
            case OmfRecord.Opcode.RELOC: {
                byte  width  = data[offset + 1];
                sbyte shift  = (sbyte)data[offset + 2];
                int   off    = RawData.GetWord(data, offset + 3, 4, false);
                int   relOff = RawData.GetWord(data, offset + 7, 4, false);
                relocs.Add(new OmfReloc(width, shift, off, relOff, -1));
            }
            break;

            case OmfRecord.Opcode.cRELOC: {
                byte  width  = data[offset + 1];
                sbyte shift  = (sbyte)data[offset + 2];
                int   off    = RawData.GetWord(data, offset + 3, 2, false);
                int   relOff = RawData.GetWord(data, offset + 5, 2, false);
                relocs.Add(new OmfReloc(width, shift, off, relOff, -1));
            }
            break;

            case OmfRecord.Opcode.INTERSEG: {
                byte  width   = data[offset + 1];
                sbyte shift   = (sbyte)data[offset + 2];
                int   off     = RawData.GetWord(data, offset + 3, 4, false);
                int   fileNum = RawData.GetWord(data, offset + 7, 2, false);
                int   segNum  = RawData.GetWord(data, offset + 9, 2, false);
                int   relOff  = RawData.GetWord(data, offset + 11, 4, false);
                relocs.Add(new OmfReloc(width, shift, off, relOff, fileNum, segNum, -1));
            }
            break;

            case OmfRecord.Opcode.cINTERSEG: {
                byte  width   = data[offset + 1];
                sbyte shift   = (sbyte)data[offset + 2];
                int   off     = RawData.GetWord(data, offset + 3, 2, false);
                int   fileNum = 1;
                int   segNum  = data[offset + 5];
                int   relOff  = RawData.GetWord(data, offset + 6, 2, false);
                relocs.Add(new OmfReloc(width, shift, off, relOff, fileNum, segNum, -1));
            }
            break;

            case OmfRecord.Opcode.SUPER:
                if (!GenerateRelocForSuper(omfSeg, omfRec, data, relocs))
                {
                    return(false);
                }
                break;

            default:
                Debug.Assert(false);
                return(false);
            }

            return(true);
        }