Beispiel #1
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);
     }
 }
Beispiel #2
0
        /// <summary>
        /// Parses OMF record data.
        /// </summary>
        /// <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>
        /// <returns>Parse result code.</returns>
        private bool DoParseRecord(byte[] data, int offset,
                                   OmfSegment.SegmentVersion version, int labLen, Formatter formatter,
                                   List <string> msgs)
        {
            int len = 1;    // 1 byte for the opcode

            Opcode opcode = Op = (Opcode)data[offset++];

            OpName = opcode.ToString();
            Value  = string.Empty;

            if (opcode >= Opcode.CONST_start && opcode <= Opcode.CONST_end)
            {
                // length determined by opcode value
                int count = (int)opcode;
                len   += count;
                OpName = "CONST";
                Value  = count + " bytes of data";
            }
            else
            {
                switch (opcode)
                {
                case Opcode.END:
                    break;

                case Opcode.ALIGN: {
                    int val = GetNum(data, ref offset, ref len);
                    Value = formatter.FormatHexValue(val, 6);
                }
                break;

                case Opcode.ORG: {
                    int val = GetNum(data, ref offset, ref len);
                    Value = "loc " + formatter.FormatAdjustment(val);
                }
                break;

                case Opcode.RELOC: {
                    len += 1 + 1 + 4 + 4;                   // 10
                    int width      = data[offset];
                    int operandOff = RawData.GetWord(data, offset + 2, 4, false);
                    Value = width + " bytes @" + formatter.FormatHexValue(operandOff, 4);
                }
                break;

                case Opcode.INTERSEG: {
                    len += 1 + 1 + 4 + 2 + 2 + 4;           // 14
                    int width      = data[offset];
                    int operandOff = RawData.GetWord(data, offset + 2, 4, false);
                    int segNum     = RawData.GetWord(data, offset + 8, 2, false);
                    Value = width + " bytes @" + formatter.FormatHexValue(operandOff, 4) +
                            " (seg " + segNum + ")";
                }
                break;

                case Opcode.USING:
                case Opcode.STRONG: {
                    string label = GetLabel(data, ref offset, ref len, labLen);
                    Value = "'" + label + "'";
                }
                break;

                case Opcode.GLOBAL:
                case Opcode.LOCAL: {
                    string label = GetLabel(data, ref offset, ref len, labLen);
                    int    bytes;
                    byte   type;
                    byte   priv = 0;
                    if (version == OmfSegment.SegmentVersion.v0_0)
                    {
                        bytes   = data[offset];
                        type    = data[offset + 1];
                        offset += 2;
                        len    += 2;
                    }
                    else if (version == OmfSegment.SegmentVersion.v1_0)
                    {
                        bytes   = data[offset];
                        type    = data[offset + 1];
                        priv    = data[offset + 2];
                        offset += 3;
                        len    += 3;
                    }
                    else
                    {
                        bytes   = RawData.GetWord(data, offset, 2, false);
                        type    = data[offset + 2];
                        priv    = data[offset + 3];
                        offset += 4;
                        len    += 4;
                    }
                    Value = (char)type + " '" + label + "' " +
                            formatter.FormatHexValue(bytes, 4) +
                            ((priv == 0) ? "" : " private");
                }
                break;

                case Opcode.GEQU:
                case Opcode.EQU: {
                    string label = GetLabel(data, ref offset, ref len, labLen);
                    int    bytes;
                    byte   type;
                    byte   priv = 0;
                    if (version == OmfSegment.SegmentVersion.v0_0)
                    {
                        bytes   = data[offset];
                        type    = data[offset + 1];
                        offset += 2;
                        len    += 2;
                    }
                    else if (version == OmfSegment.SegmentVersion.v1_0)
                    {
                        bytes   = data[offset];
                        type    = data[offset + 1];
                        priv    = data[offset + 2];
                        offset += 3;
                        len    += 3;
                    }
                    else
                    {
                        bytes   = RawData.GetWord(data, offset, 2, false);
                        type    = data[offset + 2];
                        priv    = data[offset + 3];
                        offset += 4;
                        len    += 4;
                    }
                    string expr = GetExpression(data, ref offset, ref len, labLen,
                                                formatter, msgs);
                    Value = (char)type + " '" + label + "' " +
                            formatter.FormatHexValue(bytes, 4) +
                            ((priv == 0) ? "" : " private") + " = " + expr;
                }
                break;

                case Opcode.MEM: {
                    int addr1 = GetNum(data, ref offset, ref len);
                    int addr2 = GetNum(data, ref offset, ref len);
                    Value = formatter.FormatHexValue(addr1, 4) + ", " +
                            formatter.FormatHexValue(addr2, 4);
                }
                break;

                case Opcode.EXPR:
                case Opcode.ZEXPR:
                case Opcode.BEXPR:
                case Opcode.LEXPR: {
                    int cap = data[offset++];
                    len++;
                    string expr = GetExpression(data, ref offset, ref len, labLen,
                                                formatter, msgs);
                    Value = "(" + cap + ") " + expr;
                }
                break;

                case Opcode.RELEXPR: {
                    int cap = data[offset++];
                    len++;
                    int    rel  = GetNum(data, ref offset, ref len);
                    string expr = GetExpression(data, ref offset, ref len, labLen,
                                                formatter, msgs);
                    Value = "(" + cap + ") " + formatter.FormatAdjustment(rel) + " " + expr;
                }
                break;

                case Opcode.DS: {
                    int count = GetNum(data, ref offset, ref len);
                    Value = count + " bytes of $00";
                }
                break;

                case Opcode.LCONST: {
                    int count = GetNum(data, ref offset, ref len);
                    len  += count;
                    Value = count + " bytes of data";
                }
                break;

                case Opcode.cRELOC: {
                    len += 1 + 1 + 2 + 2;                   // 6
                    int width      = data[offset];
                    int operandOff = RawData.GetWord(data, offset + 2, 2, false);
                    Value = width + " bytes @" + formatter.FormatHexValue(operandOff, 4);
                }
                break;

                case Opcode.cINTERSEG: {
                    len += 1 + 1 + 2 + 1 + 2;               // 7
                    int width      = data[offset];
                    int operandOff = RawData.GetWord(data, offset + 2, 2, false);
                    int segNum     = data[offset + 4];
                    Value = width + " bytes @" + formatter.FormatHexValue(operandOff, 4) +
                            " (seg " + segNum + ")";
                }
                break;

                case Opcode.SUPER: {
                    int count = GetNum(data, ref offset, ref len);
                    int type  = data[offset];
                    len  += count;          // count includes type byte
                    Value = (count - 1) + " bytes, type=" +
                            formatter.FormatHexValue(type, 2);

                    if (type > 37)
                    {
                        OmfSegment.AddErrorMsg(msgs, offset,
                                               "found SUPER record with bogus type=$" + type.ToString("x2"));
                        // the length field allows us to skip it, so keep going
                    }
                }
                break;

                case Opcode.General:
                case Opcode.Experimental1:
                case Opcode.Experimental2:
                case Opcode.Experimental3:
                case Opcode.Experimental4: {
                    OmfSegment.AddInfoMsg(msgs, offset, "found unusual record type " +
                                          formatter.FormatHexValue((int)opcode, 2));
                    int count = GetNum(data, ref offset, ref len);
                    len += count;
                }
                break;

                case Opcode.unused_e9:
                case Opcode.unused_ea:
                case Opcode.unused_f8:
                case Opcode.unused_f9:
                case Opcode.unused_fa:
                // These are undefined, can't be parsed.
                default:
                    Debug.Assert(false);
                    return(false);
                }
            }
            Length = len;
            //Debug.WriteLine("REC +" + (offset-1).ToString("x6") + " " + this);

            return(true);
        }