コード例 #1
0
        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);
            }
        }
コード例 #2
0
 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);
     }
 }
コード例 #3
0
        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);
        }