Press enter to see results or esc to cancel.

Importing FIXUPP Object File Record

This procedure processes FIXUPP record ($9C) and creates reference record in the symbol table.

Procedure OMF_FIXUPP; Far;
Type P_FIXUP_Subrecord = ^T_FIXUP_Subrecord;
     T_FIXUP_Subrecord = Record
                           Locat: WordRec;
                           FixData: Byte;
                         end;
Var PSubrecord: P_FIXUP_Subrecord;
    PSubrecordByte: PChar absolute PSubrecord;
    ReferencedModuleAndFlags: Word;
    FixData: Byte;
    TargetDatum: Word;
    TargetDisplacement: Word;
    DataRecordOffset: Word;
    P: Pword;

  Procedure CreateRecord (OMF_ReferencedOffset: Word);
  Var OMF_ReferencedBlockRecordOffset: Word;
  begin
    If FixData and $02 <> 0 then
      begin
        ReferencedModuleAndFlags := ReferencedModuleAndFlags or ExtrnDefinitions [TargetDatum - 1].edReferencedModuleAndFlags;
        Inc (OMF_ReferencedOffset, ExtrnDefinitions [TargetDatum - 1].edOffset);
        OMF_ReferencedBlockRecordOffset := ExtrnDefinitions [TargetDatum - 1].edBlockRecordOffset;
        If ReferencedModuleAndFlags = $FFFF then
          begin
            MemW [DataBlockSegment : DataRecordOffset + LastBlockSize] := OMF_ReferencedOffset;
            Exit;
          end;
      end else
        If FixData and $01 <> 0 then
          begin
            ReferencedModuleAndFlags := ReferencedModuleAndFlags or $8000 or OMF_ReferencedModule;
            OMF_ReferencedBlockRecordOffset := SymbolTable [stVariablesBlocks].UsedSize;
          end else
            If TargetDatum = CodeSegmentIndex then
              begin
                ReferencedModuleAndFlags := ReferencedModuleAndFlags or $4000 or OMF_ReferencedModule;
                OMF_ReferencedBlockRecordOffset := SymbolTable [stCodeBlocks].UsedSize;
              end else
                If TargetDatum = TypedConstantsSegmentIndex then
                  begin
                    ForceCreationOfTypedConstantsBlockRecord := True;
                    ReferencedModuleAndFlags := ReferencedModuleAndFlags or $C000 or OMF_ReferencedModule;
                    OMF_ReferencedBlockRecordOffset := SymbolTable [stTypedConstantsBlocks].UsedSize;
                  end else
                    If TargetDatum = VariablesSegmentIndex then
                      begin
                        ForceCreationOfVariablesBlockRecord := True;
                        ReferencedModuleAndFlags := ReferencedModuleAndFlags or $8000 or OMF_ReferencedModule;
                        OMF_ReferencedBlockRecordOffset := SymbolTable [stVariablesBlocks].UsedSize;
                      end else FileError (@Identifier, InvalidRelocatableReference);
    P := IncreaseSymbolTable (ReferencesSymbolTable, 8);
    P^ := ReferencedModuleAndFlags;
    Inc (P);
    P^ := OMF_ReferencedBlockRecordOffset;
    Inc (P);
    P^ := OMF_ReferencedOffset;
    Inc (P);
    P^ := DataRecordOffset;
  end;

begin

{$IFDEF DEBUGOMF}
  Writeln ('        FIXUPP');
{$ENDIF}

  Inc (PChar (ObjectFilePtr), 3);
  PSubrecord := P_FIXUP_Subrecord (ObjectFilePtr);
  If ReferencesSymbolTable = stMain then FileError (@Identifier, InvalidRelocatableReference);
  Repeat
    Case PSubrecord^.Locat.ByteL and $FC of
      $84: ReferencedModuleAndFlags := $0000;
      $C4: ReferencedModuleAndFlags := $1000;
      $C8: ReferencedModuleAndFlags := $2000;
      $CC: ReferencedModuleAndFlags := $3000;
      else FileError (@Identifier, InvalidRelocatableReference);
    end;
    DataRecordOffset := Swap (PSubrecord^.Locat.Word) and $3FF + EnumeratedDataOffset;
    FixData := PSubrecord^.FixData;
    Inc (PSubrecordByte, 3);
    If FixData and $88 <> 0 then FileError (@Identifier, InvalidRelocatableReference);
    If FixData and $40 = 0 then
      begin                                                                           { Skip Frame Datum }
        If Byte (PSubrecordByte^) and $80 <> 0 then Inc (PSubrecordByte, 2)
          else Inc (PSubrecordByte);
      end;
    TargetDatum := Byte (PSubrecordByte^);
    Inc (PSubrecordByte);
    If TargetDatum and $80 <> 0 then
      begin
        TargetDatum := Swap (TargetDatum and $7F) or Byte (PSubrecordByte^);
        Inc (PSubrecordByte);
      end;
    TargetDisplacement := 0;
    If FixData and $04 = 0 then
      begin
        TargetDisplacement := PWord (PSubrecordByte)^;
        Inc (PSubrecordByte, 2);
      end;
    CreateRecord (TargetDisplacement + MemW [DataBlockSegment : DataRecordOffset + LastBlockSize]);
  until Ofs (PSubrecordByte^) >= ObjectRecordChecksumOffset;
end;