From 444b63cf073299d2bb9610ef0d3541dd8510f5e3 Mon Sep 17 00:00:00 2001 From: nickysn Date: Sun, 5 Apr 2015 19:57:41 +0000 Subject: [PATCH] + added class for reading/writing a FIXUP subrecord in a FIXUPP omf record git-svn-id: trunk@30448 - --- compiler/omfbase.pas | 175 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/compiler/omfbase.pas b/compiler/omfbase.pas index 17e97b42cf..c2db8191b8 100644 --- a/compiler/omfbase.pas +++ b/compiler/omfbase.pas @@ -120,6 +120,8 @@ interface scPublic7 = 7); { same as scPublic } TOmfSegmentUse = (suUse16, suUse32); + TOmfFixupThread = (ftThread0, ftThread1, ftThread2, ftThread3); + TOmfFixupMode = (fmSelfRelative, fmSegmentRelative); TOmfFixupLocationType = ( fltLoByte = 0, { low 8 bits of 16-bit offset } @@ -315,6 +317,49 @@ interface property SegmentList: TSegmentList read FSegmentList write FSegmentList; end; + { TOmfSubRecord_FIXUP } + + TOmfSubRecord_FIXUP = class + private + FIs32Bit: Boolean; + FMode: TOmfFixupMode; + FLocationType: TOmfFixupLocationType; + FLocationOffset: DWord; + FDataRecordStartOffset: DWord; + FTargetDeterminedByThread: Boolean; + FTargetThread: TOmfFixupThread; + FTargetThreadDisplacementPresent: Boolean; + FTargetMethod: TOmfFixupTargetMethod; + FTargetDatum: Integer; + FTargetDisplacement: DWord; + FFrameDeterminedByThread: Boolean; + FFrameThread: TOmfFixupThread; + FFrameMethod: TOmfFixupFrameMethod; + FFrameDatum: Integer; + function GetDataRecordOffset: Integer; + procedure SetDataRecordOffset(AValue: Integer); + public + function ReadAt(RawRecord: TOmfRawRecord; Offset: Integer): Integer; + function WriteAt(RawRecord: TOmfRawRecord; Offset: Integer): Integer; + + property Is32Bit: Boolean read FIs32Bit write FIs32Bit; + property Mode: TOmfFixupMode read FMode write FMode; + property LocationType: TOmfFixupLocationType read FLocationType write FLocationType; + property LocationOffset: DWord read FLocationOffset write FLocationOffset; + property DataRecordStartOffset: DWord read FDataRecordStartOffset write FDataRecordStartOffset; + property DataRecordOffset: Integer read GetDataRecordOffset write SetDataRecordOffset; + property TargetDeterminedByThread: Boolean read FTargetDeterminedByThread write FTargetDeterminedByThread; + property TargetThread: TOmfFixupThread read FTargetThread write FTargetThread; + property TargetThreadDisplacementPresent: Boolean read FTargetThreadDisplacementPresent write FTargetThreadDisplacementPresent; + property TargetMethod: TOmfFixupTargetMethod read FTargetMethod write FTargetMethod; + property TargetDatum: Integer read FTargetDatum write FTargetDatum; + property TargetDisplacement: DWord read FTargetDisplacement write FTargetDisplacement; + property FrameDeterminedByThread: Boolean read FFrameDeterminedByThread write FFrameDeterminedByThread; + property FrameThread: TOmfFixupThread read FFrameThread write FFrameThread; + property FrameMethod: TOmfFixupFrameMethod read FFrameMethod write FFrameMethod; + property FrameDatum: Integer read FFrameDatum write FFrameDatum; + end; + implementation uses @@ -731,5 +776,135 @@ implementation RawRecord.CalculateChecksumByte; end; + { TOmfSubRecord_FIXUP } + + function TOmfSubRecord_FIXUP.GetDataRecordOffset: Integer; + begin + Result:=FLocationOffset-FDataRecordStartOffset; + end; + + procedure TOmfSubRecord_FIXUP.SetDataRecordOffset(AValue: Integer); + begin + FLocationOffset:=AValue+FDataRecordStartOffset; + end; + + function TOmfSubRecord_FIXUP.ReadAt(RawRecord: TOmfRawRecord; Offset: Integer): Integer; + var + Locat: Word; + FixData: Byte; + begin + if (Offset+2)>High(RawRecord.RawData) then + internalerror(2015040504); + { unlike other fields in the OMF format, this one is big endian } + Locat:=(RawRecord.RawData[Offset] shl 8) or RawRecord.RawData[Offset+1]; + FixData:=RawRecord.RawData[Offset+2]; + Inc(Offset,3); + if (Locat and $8000)=0 then + internalerror(2015040503); + DataRecordOffset:=Locat and $3FF; + LocationType:=TOmfFixupLocationType((Locat shr 10) and 15); + Mode:=TOmfFixupMode((Locat shr 14) and 1); + FrameDeterminedByThread:=(FixData and $80)<>0; + TargetDeterminedByThread:=(FixData and $08)<>0; + if FrameDeterminedByThread then + FrameThread:=TOmfFixupThread((FixData shr 4) and 3) + else + FrameMethod:=TOmfFixupFrameMethod((FixData shr 4) and 7); + if TargetDeterminedByThread then + begin + TargetThread:=TOmfFixupThread(FixData and 3); + TargetThreadDisplacementPresent:=(FixData and $40)=0; + end + else + TargetMethod:=TOmfFixupTargetMethod(FixData and 7); + { read Frame Datum? } + if not FrameDeterminedByThread and (FrameMethod in [ffmSegmentIndex,ffmGroupIndex,ffmExternalIndex,ffmFrameNumber]) then + Offset:=RawRecord.ReadIndexedRef(Offset,FFrameDatum) + else + FrameDatum:=0; + { read Target Datum? } + if not TargetDeterminedByThread then + Offset:=RawRecord.ReadIndexedRef(Offset,FTargetDatum) + else + TargetDatum:=0; + { read Target Displacement? } + if (TargetDeterminedByThread and TargetThreadDisplacementPresent) or + (TargetMethod in [ftmSegmentIndex,ftmGroupIndex,ftmExternalIndex,ftmFrameNumber]) then + begin + if Is32Bit then + begin + if (Offset+3)>High(RawRecord.RawData) then + internalerror(2015040504); + TargetDisplacement := RawRecord.RawData[Offset]+ + (RawRecord.RawData[Offset+1] shl 8)+ + (RawRecord.RawData[Offset+2] shl 16)+ + (RawRecord.RawData[Offset+3] shl 24); + Inc(Offset,4); + end + else + begin + if (Offset+1)>High(RawRecord.RawData) then + internalerror(2015040504); + TargetDisplacement := RawRecord.RawData[Offset]+ + (RawRecord.RawData[Offset+1] shl 8); + Inc(Offset,2); + end; + end; + Result:=Offset; + end; + + function TOmfSubRecord_FIXUP.WriteAt(RawRecord: TOmfRawRecord; Offset: Integer): Integer; + var + Locat: Word; + FixData: Byte; + begin + if (DataRecordOffset<0) or (DataRecordOffset>1023) then + internalerror(2015040501); + Locat:=$8000+(Ord(Mode) shl 14)+(Ord(LocationType) shl 10)+DataRecordOffset; + { unlike other fields in the OMF format, this one is big endian } + RawRecord.RawData[Offset]:=Byte(Locat shr 8); + RawRecord.RawData[Offset+1]:=Byte(Locat); + Inc(Offset, 2); + FixData:=(Ord(FrameDeterminedByThread) shl 7)+(Ord(TargetDeterminedByThread) shl 3); + if FrameDeterminedByThread then + FixData:=FixData+(Ord(FrameThread) shl 4) + else + FixData:=FixData+(Ord(FrameMethod) shl 4); + if TargetDeterminedByThread then + FixData:=FixData+Ord(TargetThread)+(Ord(not TargetThreadDisplacementPresent) shl 2) + else + FixData:=FixData+Ord(TargetMethod); + RawRecord.RawData[Offset]:=FixData; + Inc(Offset); + { save Frame Datum? } + if not FrameDeterminedByThread and (FrameMethod in [ffmSegmentIndex,ffmGroupIndex,ffmExternalIndex,ffmFrameNumber]) then + Offset:=RawRecord.WriteIndexedRef(Offset,FrameDatum); + { save Target Datum? } + if not TargetDeterminedByThread then + Offset:=RawRecord.WriteIndexedRef(Offset,TargetDatum); + { save Target Displacement? } + if (TargetDeterminedByThread and TargetThreadDisplacementPresent) or + (TargetMethod in [ftmSegmentIndex,ftmGroupIndex,ftmExternalIndex,ftmFrameNumber]) then + begin + if Is32Bit then + begin + RawRecord.RawData[Offset]:=Byte(TargetDisplacement); + RawRecord.RawData[Offset+1]:=Byte(TargetDisplacement shr 8); + RawRecord.RawData[Offset+2]:=Byte(TargetDisplacement shr 16); + RawRecord.RawData[Offset+3]:=Byte(TargetDisplacement shr 24); + Inc(Offset,4); + end + else + begin + if TargetDisplacement>$ffff then + internalerror(2015040502); + RawRecord.RawData[Offset]:=Byte(TargetDisplacement); + RawRecord.RawData[Offset+1]:=Byte(TargetDisplacement shr 8); + Inc(Offset,2); + end; + end; + Result:=Offset; + end; + end.