Importing Object Files

Turbo Pascal can import and link object files created with any other compiler that can create Relocatable Object Module Format file. OMF file is a collection of object records with the following format:
     PObjectFileRecord = ^TObjectFileRecord;
     TObjectFileRecord = Record
                           RecordType: Byte;
                           RecordLength: Word;
                           Case Byte of
                             $88: (Comment: Record
                                              ComType: Byte;
                                              Class: Byte;
                                              Case Byte of
                                                $00: (Translator: String);
                                                $98: (SourceFileNumber: Byte; SourceFileName: String);
                                              end);
                             $8C: (ExternalName: String);
                             $90: (BaseGroupIndex, BaseSegmentIndex: Byte);
                             $96: (Name: String);
                             $98: (SegDef: TSegDef);
                             $A0: (EnumSegmentIndex: Byte; EnumeratedDataOffset: Word; EnumData: Byte);
                             $A2: (ItSegmentIndex: Byte; IteratedDataOffset: Word);
                         end;
Turbo Pascal loads object files and processes records - only few object file record types are supported:
Procedure ImportObjectFiles;
Var UsedFilesBlockRecord: PUsedFilesBlockRecord;
    ObjectFile: File;
    ObjectFileParagraphSize: Word;

  Procedure ReadObjectFile;
  Var ObjectFileSizeRec: LongRec;
  begin
    FindUsedFilePath (UsedFilesBlockRecord, @Identifier);
    OpenFile (ObjectFile, @Identifier);

{$IFDEF DEBUGOMF}
    Writeln ('        OBJECT FILE: ', PChar (@Identifier));
{$ENDIF}

    ObjectFileSizeRec.Long := FileSize (ObjectFile);
    If (ObjectFileSizeRec.WordH <> 0) or (ObjectFileSizeRec.WordL > $FFF0) then FileError (@Identifier, ObjectFileTooLarge);
    ObjectFileSize := ObjectFileSizeRec.WordL;
    ObjectFileParagraphSize := (ObjectFileSizeRec.WordL + $000F) shr 4;
    If HeapEndRec.Seg - ObjectFileParagraphSize < HeapPtrRec.Seg then Error (OutOfMemory);
    Dec (HeapEndRec.Seg, ObjectFileParagraphSize);
    ObjectFileSegment := HeapEndRec.Seg;
    BlockRead (ObjectFile, HeapEnd^, ObjectFileSizeRec.WordL);
    Close (ObjectFile);
  end;

  Procedure ProcessObjectFileRecords;
  Const LinkProc: Array [0..$11] of Procedure = (
    OMF_Dummy,
    OMF_Dummy,
    OMF_Dummy,
    OMF_Dummy,
    OMF_COMENT,
    OMF_MODEND,
    OMF_EXTDEF,
    OMF_Dummy,
    OMF_PUBDEF,
    OMF_Dummy,
    OMF_LINNUM,
    OMF_Dummy,
    OMF_SEGDEF,
    OMF_Dummy,
    OMF_FIXUPP,
    OMF_Dummy,
    OMF_LEDATA,
    OMF_LIDATA);
  Var RecordType: Byte;
  begin
    SegmentCounter := 0;
    CodeSegmentIndex := 0;
    TypedConstantsSegmentIndex := 0;
    VariablesSegmentIndex := 0;
    ReferencesSymbolTable := stMain;
    LastSourceFileNumber := 0;
    SourceFileNumber := 0;
    ExtrnDefinitionsCounter := 0;
    OMF_ReferencedModule := AddReferencedModule (SymbolTable [stMain].Segment);
    ObjectFilePtr := Ptr (ObjectFileSegment, 0);
    Return := False;
    Repeat
      If Ofs (ObjectFilePtr^) >= ObjectFileSize then FileError (@Identifier, InvalidObjectFileRecord);
      RecordType := ObjectFilePtr^.RecordType;
      If Odd (RecordType) or (RecordType < $80) or (RecordType > $A2) then FileError (@Identifier, InvalidObjectFileRecord);
      ObjectRecordChecksumOffset := ObjectFilePtr^.RecordLength + Ofs (ObjectFilePtr^) + 2;
      LinkProc [(RecordType - $80) shr 1];
      If Return then Exit;
      ObjectFilePtr := Ptr (ObjectFileSegment, ObjectRecordChecksumOffset + 1);
    until False;
  end;

begin

{$IFDEF DEBUGOMF}
  Writeln (#13#10'#OMF IMPORT BEGIN');
{$ENDIF}

  UsedFilesBlockRecord := Ptr (SymbolTable [stUsedFiles].Segment, 0);
  While Ofs (UsedFilesBlockRecord^) <> SymbolTable [stUsedFiles].UsedSize do
    begin
      If UsedFilesBlockRecord^.FileType = ufObjectFile then
        begin
          ReadObjectFile;
          ProcessObjectFileRecords;
          Inc (HeapEndRec.Seg, ObjectFileParagraphSize);
          CreateProgramCodeBlockRecord;
          CreateTypedConstantsBlockRecord;
          CreateVariablesBlockRecord;
          UsedFilesBlockRecord := Ptr (SymbolTable [stUsedFiles].Segment, Ofs (UsedFilesBlockRecord^));
        end;
      Inc (PChar (UsedFilesBlockRecord), UsedFilesBlockRecord^.Name.Len + 8);
    end;

{$IFDEF DEBUGOMF}
  Writeln ('#OMF IMPORT END');
{$ENDIF}

end;
 
 
 
© 2017 Turbo Pascal | Privacy Policy