Sfoglia il codice sorgente

+ implemented reading of MODEND omf records

git-svn-id: trunk@30589 -
nickysn 10 anni fa
parent
commit
b4d044e1b2
1 ha cambiato i file con 96 aggiunte e 2 eliminazioni
  1. 96 2
      compiler/omfbase.pas

+ 96 - 2
compiler/omfbase.pas

@@ -1090,9 +1090,103 @@ implementation
   { TOmfRecord_MODEND }
 
   procedure TOmfRecord_MODEND.DecodeFrom(RawRecord: TOmfRawRecord);
+    var
+      ModTyp: Byte;
+      NextOfs: Integer;
+      EndData: Byte;
     begin
-      {TODO: implement}
-      internalerror(2015040101);
+      if not (RawRecord.RecordType in [RT_MODEND,RT_MODEND32]) then
+        internalerror(2015040301);
+      Is32Bit:=RawRecord.RecordType=RT_MODEND32;
+
+      if RawRecord.RecordLength<2 then
+        internalerror(2015040305);
+      ModTyp:=RawRecord.RawData[0];
+      IsMainModule:=(ModTyp and $80)<>0;
+      HasStartAddress:=(ModTyp and $40)<>0;
+      SegmentBit:=(ModTyp and $20)<>0;
+      LogicalStartAddress:=(ModTyp and $01)<>0;
+      if (ModTyp and $1E)<>0 then
+        internalerror(2015041404);
+      NextOfs:=1;
+
+      { clear all the start address properties first }
+      FrameMethod:=Low(FrameMethod);
+      FrameDatum:=0;
+      TargetMethod:=Low(TargetMethod);
+      TargetDatum:=0;
+      TargetDisplacement:=0;
+      PhysFrameNumber:=0;
+      PhysOffset:=0;
+
+      if HasStartAddress then
+        begin
+          if LogicalStartAddress then
+            begin
+              if EndData>=RawRecord.RecordLength then
+                internalerror(2015040305);
+              EndData:=RawRecord.RawData[NextOfs];
+              Inc(NextOfs);
+              { frame and target method determined by thread is not allowed in MODEND records }
+              if (EndData and $88)<>0 then
+                internalerror(2015041406);
+              FrameMethod:=TOmfFixupFrameMethod((EndData shr 4) and 7);
+              TargetMethod:=TOmfFixupTargetMethod(EndData and 7);
+              { frame method ffmLocation is not allowed in an MODEND record }
+              if FrameMethod=ffmLocation then
+                internalerror(2015041402);
+              { read Frame Datum? }
+              if FrameMethod in [ffmSegmentIndex,ffmGroupIndex,ffmExternalIndex,ffmFrameNumber] then
+                NextOfs:=RawRecord.ReadIndexedRef(NextOfs,FFrameDatum);
+              { read Target Datum? }
+              NextOfs:=RawRecord.ReadIndexedRef(NextOfs,FTargetDatum);
+              { read Target Displacement? }
+              if TargetMethod in [ftmSegmentIndex,ftmGroupIndex,ftmExternalIndex,ftmFrameNumber] then
+                begin
+                  if Is32Bit then
+                    begin
+                      if (NextOfs+3)>=RawRecord.RecordLength then
+                        internalerror(2015040504);
+                      TargetDisplacement := RawRecord.RawData[NextOfs]+
+                                           (RawRecord.RawData[NextOfs+1] shl 8)+
+                                           (RawRecord.RawData[NextOfs+2] shl 16)+
+                                           (RawRecord.RawData[NextOfs+3] shl 24);
+                      Inc(NextOfs,4);
+                    end
+                  else
+                    begin
+                      if (NextOfs+1)>=RawRecord.RecordLength then
+                        internalerror(2015040504);
+                      TargetDisplacement := RawRecord.RawData[NextOfs]+
+                                           (RawRecord.RawData[NextOfs+1] shl 8);
+                      Inc(NextOfs,2);
+                    end;
+                end;
+            end
+          else
+            begin
+              { physical start address }
+              if (NextOfs+1)>=RawRecord.RecordLength then
+                internalerror(2015040305);
+              PhysFrameNumber:=RawRecord.RawData[NextOfs]+(RawRecord.RawData[NextOfs+1] shl 8);
+              Inc(NextOfs,2);
+              if Is32Bit then
+                begin
+                  if (NextOfs+3)>=RawRecord.RecordLength then
+                    internalerror(2015040305);
+                  PhysOffset:=RawRecord.RawData[NextOfs]+(RawRecord.RawData[NextOfs+1] shl 8)+
+                    (RawRecord.RawData[NextOfs+2] shl 16)+(RawRecord.RawData[NextOfs+3] shl 24);
+                  Inc(NextOfs,4);
+                end
+              else
+                begin
+                  if (NextOfs+1)>=RawRecord.RecordLength then
+                    internalerror(2015040305);
+                  PhysOffset:=RawRecord.RawData[NextOfs]+(RawRecord.RawData[NextOfs+1] shl 8);
+                  Inc(NextOfs,2);
+                end;
+            end;
+        end;
     end;
 
   procedure TOmfRecord_MODEND.EncodeTo(RawRecord: TOmfRawRecord);