omfbase.pas 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. {
  2. Copyright (c) 2015 by Nikolay Nikolov
  3. Contains Relocatable Object Module Format (OMF) definitions
  4. This is the object format used on the i8086-msdos platform.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit omfbase;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. owbase;
  23. const
  24. { OMF record types }
  25. RT_THEADR = $80; { Translator Header Record }
  26. RT_LHEADR = $82; { Library Module Header Record }
  27. RT_COMENT = $88; { Comment Record }
  28. RT_MODEND = $8A; { Module End Record }
  29. RT_MODEND32 = $8B;
  30. RT_EXTDEF = $8C; { External Names Definition Record }
  31. RT_PUBDEF = $90; { Public Names Definition Record }
  32. RT_PUBDEF32 = $91;
  33. RT_LINNUM = $94; { Line Numbers Record }
  34. RT_LINNUM32 = $95;
  35. RT_LNAMES = $96; { List of Names Record }
  36. RT_SEGDEF = $98; { Segment Definition Record }
  37. RT_SEGDEF32 = $99;
  38. RT_GRPDEF = $9A; { Group Definition Record }
  39. RT_FIXUPP = $9C; { Fixup Record }
  40. RT_FIXUPP32 = $9D;
  41. RT_LEDATA = $A0; { Logical Enumerated Data Record }
  42. RT_LEDATA32 = $A1;
  43. RT_LIDATA = $A2; { Logical Iterated Data Record }
  44. RT_LIDATA32 = $A3;
  45. RT_COMDEF = $B0; { Communal Names Definition Record }
  46. RT_BAKPAT = $B2; { Backpatch Record }
  47. RT_BAKPAT32 = $B3;
  48. RT_LEXTDEF = $B4; { Local External Names Definition Record }
  49. RT_LEXTDEF32 = $B5;
  50. RT_LPUBDEF = $B6; { Local Public Names Definition Record }
  51. RT_LPUBDEF32 = $B7;
  52. RT_LCOMDEF = $B8; { Local Communal Names Definition Record }
  53. RT_CEXTDEF = $BC; { COMDAT External Names Definition Record }
  54. RT_COMDAT = $C2; { Initialized Communal Data Record }
  55. RT_COMDAT32 = $C3;
  56. RT_LINSYM = $C4; { Symbol Line Numbers Record }
  57. RT_LINSYM32 = $C5;
  58. RT_ALIAS = $C6; { Alias Definition Record }
  59. RT_NBKPAT = $C8; { Named Backpatch Record }
  60. RT_NBKPAT32 = $C9;
  61. RT_LLNAMES = $CA; { Local Logical Names Definition Record }
  62. RT_VERNUM = $CC; { OMF Version Number Record }
  63. RT_VENDEXT = $CE; { Vendor-specific OMF Extension Record }
  64. type
  65. { TOmfRawRecord }
  66. TOmfRawRecord = class
  67. private
  68. function GetChecksumByte: Byte;
  69. function GetRecordLength: Word;
  70. function GetRecordType: Byte;
  71. procedure SetChecksumByte(AValue: Byte);
  72. procedure SetRecordLength(AValue: Word);
  73. procedure SetRecordType(AValue: Byte);
  74. public
  75. RawData: array [-3..65535] of Byte;
  76. property RecordType: Byte read GetRecordType write SetRecordType;
  77. property RecordLength: Word read GetRecordLength write SetRecordLength;
  78. procedure CalculateChecksumByte;
  79. function VerifyChecksumByte: boolean;
  80. property ChecksumByte: Byte read GetChecksumByte write SetChecksumByte;
  81. procedure ReadFrom(aReader: TObjectReader);
  82. procedure WriteTo(aWriter: TObjectWriter);
  83. end;
  84. implementation
  85. { TOmfRawRecord }
  86. function TOmfRawRecord.GetRecordType: Byte;
  87. begin
  88. Result:=RawData[-3];
  89. end;
  90. procedure TOmfRawRecord.SetRecordType(AValue: Byte);
  91. begin
  92. RawData[-3]:=AValue;
  93. end;
  94. function TOmfRawRecord.GetRecordLength: Word;
  95. begin
  96. Result:=RawData[-2] or (RawData[-1] shl 8);
  97. end;
  98. procedure TOmfRawRecord.SetRecordLength(AValue: Word);
  99. begin
  100. RawData[-2]:=Byte(AValue);
  101. RawData[-1]:=Byte(AValue shr 8);
  102. end;
  103. function TOmfRawRecord.GetChecksumByte: Byte;
  104. begin
  105. if RecordLength>0 then
  106. Result:=RawData[RecordLength-1]
  107. else
  108. Result:=0;
  109. end;
  110. procedure TOmfRawRecord.SetChecksumByte(AValue: Byte);
  111. begin
  112. if RecordLength>0 then
  113. RawData[RecordLength-1]:=AValue;
  114. end;
  115. procedure TOmfRawRecord.CalculateChecksumByte;
  116. var
  117. I: Integer;
  118. b: Byte;
  119. begin
  120. b:=0;
  121. for I:=-3 to RecordLength-2 do
  122. b:=byte(b+RawData[I]);
  123. SetChecksumByte($100-b);
  124. end;
  125. function TOmfRawRecord.VerifyChecksumByte: boolean;
  126. var
  127. I: Integer;
  128. b: Byte;
  129. begin
  130. { according to the OMF spec, some tools always write a 0 rather than
  131. computing the checksum, so it should also be accepted as correct }
  132. if ChecksumByte=0 then
  133. exit(true);
  134. b:=0;
  135. for I:=-3 to RecordLength-1 do
  136. b:=byte(b+RawData[I]);
  137. Result:=(b=0);
  138. end;
  139. procedure TOmfRawRecord.ReadFrom(aReader: TObjectReader);
  140. begin
  141. aReader.read(RawData, 3);
  142. aReader.read(RawData[0], RecordLength);
  143. end;
  144. procedure TOmfRawRecord.WriteTo(aWriter: TObjectWriter);
  145. begin
  146. aWriter.write(RawData, RecordLength+3);
  147. end;
  148. end.