123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- {
- Copyright (c) 2015 by Nikolay Nikolov
- Contains Relocatable Object Module Format (OMF) definitions
- This is the object format used on the i8086-msdos platform.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************
- }
- unit omfbase;
- {$i fpcdefs.inc}
- interface
- uses
- owbase;
- const
- { OMF record types }
- RT_THEADR = $80; { Translator Header Record }
- RT_LHEADR = $82; { Library Module Header Record }
- RT_COMENT = $88; { Comment Record }
- RT_MODEND = $8A; { Module End Record }
- RT_MODEND32 = $8B;
- RT_EXTDEF = $8C; { External Names Definition Record }
- RT_PUBDEF = $90; { Public Names Definition Record }
- RT_PUBDEF32 = $91;
- RT_LINNUM = $94; { Line Numbers Record }
- RT_LINNUM32 = $95;
- RT_LNAMES = $96; { List of Names Record }
- RT_SEGDEF = $98; { Segment Definition Record }
- RT_SEGDEF32 = $99;
- RT_GRPDEF = $9A; { Group Definition Record }
- RT_FIXUPP = $9C; { Fixup Record }
- RT_FIXUPP32 = $9D;
- RT_LEDATA = $A0; { Logical Enumerated Data Record }
- RT_LEDATA32 = $A1;
- RT_LIDATA = $A2; { Logical Iterated Data Record }
- RT_LIDATA32 = $A3;
- RT_COMDEF = $B0; { Communal Names Definition Record }
- RT_BAKPAT = $B2; { Backpatch Record }
- RT_BAKPAT32 = $B3;
- RT_LEXTDEF = $B4; { Local External Names Definition Record }
- RT_LEXTDEF32 = $B5;
- RT_LPUBDEF = $B6; { Local Public Names Definition Record }
- RT_LPUBDEF32 = $B7;
- RT_LCOMDEF = $B8; { Local Communal Names Definition Record }
- RT_CEXTDEF = $BC; { COMDAT External Names Definition Record }
- RT_COMDAT = $C2; { Initialized Communal Data Record }
- RT_COMDAT32 = $C3;
- RT_LINSYM = $C4; { Symbol Line Numbers Record }
- RT_LINSYM32 = $C5;
- RT_ALIAS = $C6; { Alias Definition Record }
- RT_NBKPAT = $C8; { Named Backpatch Record }
- RT_NBKPAT32 = $C9;
- RT_LLNAMES = $CA; { Local Logical Names Definition Record }
- RT_VERNUM = $CC; { OMF Version Number Record }
- RT_VENDEXT = $CE; { Vendor-specific OMF Extension Record }
- type
- { TOmfRawRecord }
- TOmfRawRecord = class
- private
- function GetChecksumByte: Byte;
- function GetRecordLength: Word;
- function GetRecordType: Byte;
- procedure SetChecksumByte(AValue: Byte);
- procedure SetRecordLength(AValue: Word);
- procedure SetRecordType(AValue: Byte);
- public
- RawData: array [-3..65535] of Byte;
- property RecordType: Byte read GetRecordType write SetRecordType;
- property RecordLength: Word read GetRecordLength write SetRecordLength;
- procedure CalculateChecksumByte;
- function VerifyChecksumByte: boolean;
- property ChecksumByte: Byte read GetChecksumByte write SetChecksumByte;
- procedure ReadFrom(aReader: TObjectReader);
- procedure WriteTo(aWriter: TObjectWriter);
- end;
- implementation
- { TOmfRawRecord }
- function TOmfRawRecord.GetRecordType: Byte;
- begin
- Result:=RawData[-3];
- end;
- procedure TOmfRawRecord.SetRecordType(AValue: Byte);
- begin
- RawData[-3]:=AValue;
- end;
- function TOmfRawRecord.GetRecordLength: Word;
- begin
- Result:=RawData[-2] or (RawData[-1] shl 8);
- end;
- procedure TOmfRawRecord.SetRecordLength(AValue: Word);
- begin
- RawData[-2]:=Byte(AValue);
- RawData[-1]:=Byte(AValue shr 8);
- end;
- function TOmfRawRecord.GetChecksumByte: Byte;
- begin
- if RecordLength>0 then
- Result:=RawData[RecordLength-1]
- else
- Result:=0;
- end;
- procedure TOmfRawRecord.SetChecksumByte(AValue: Byte);
- begin
- if RecordLength>0 then
- RawData[RecordLength-1]:=AValue;
- end;
- procedure TOmfRawRecord.CalculateChecksumByte;
- var
- I: Integer;
- b: Byte;
- begin
- b:=0;
- for I:=-3 to RecordLength-2 do
- b:=byte(b+RawData[I]);
- SetChecksumByte($100-b);
- end;
- function TOmfRawRecord.VerifyChecksumByte: boolean;
- var
- I: Integer;
- b: Byte;
- begin
- { according to the OMF spec, some tools always write a 0 rather than
- computing the checksum, so it should also be accepted as correct }
- if ChecksumByte=0 then
- exit(true);
- b:=0;
- for I:=-3 to RecordLength-1 do
- b:=byte(b+RawData[I]);
- Result:=(b=0);
- end;
- procedure TOmfRawRecord.ReadFrom(aReader: TObjectReader);
- begin
- aReader.read(RawData, 3);
- aReader.read(RawData[0], RecordLength);
- end;
- procedure TOmfRawRecord.WriteTo(aWriter: TObjectWriter);
- begin
- aWriter.write(RawData, RecordLength+3);
- end;
- end.
|