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); } }
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); } }
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); }