ogomf.pas 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. {
  2. Copyright (c) 2015 by Nikolay Nikolov
  3. Contains the binary Relocatable Object Module Format (OMF) reader and writer
  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 ogomf;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. { common }
  23. cclasses,globtype,
  24. { target }
  25. systems,
  26. { assembler }
  27. cpuinfo,cpubase,aasmbase,assemble,link,
  28. { OMF definitions }
  29. omfbase,
  30. { output }
  31. ogbase,
  32. owbase;
  33. type
  34. TOmfObjData = class(TObjData)
  35. public
  36. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  37. procedure writeReloc(Data:aint;len:aword;p:TObjSymbol;Reloctype:TObjRelocationType);override;
  38. end;
  39. { TOmfObjOutput }
  40. TOmfObjOutput = class(tObjOutput)
  41. private
  42. FLNames: TOmfOrderedNameCollection;
  43. FSegments: TFPHashObjectList;
  44. FGroups: TFPHashObjectList;
  45. procedure AddSegment(const name,segclass: string;
  46. Alignment: TOmfSegmentAlignment; Combination: TOmfSegmentCombination;
  47. Use: TOmfSegmentUse);
  48. procedure AddGroup(const groupname: string; seglist: array of const);
  49. property LNames: TOmfOrderedNameCollection read FLNames;
  50. property Segments: TFPHashObjectList read FSegments;
  51. property Groups: TFPHashObjectList read FGroups;
  52. protected
  53. function writeData(Data:TObjData):boolean;override;
  54. public
  55. constructor create(AWriter:TObjectWriter);override;
  56. destructor Destroy;override;
  57. end;
  58. TOmfAssembler = class(tinternalassembler)
  59. constructor create(smart:boolean);override;
  60. end;
  61. implementation
  62. uses
  63. SysUtils,
  64. cutils,verbose,globals,
  65. fmodule,aasmtai,aasmdata,
  66. ogmap,
  67. version
  68. ;
  69. {****************************************************************************
  70. TOmfObjData
  71. ****************************************************************************}
  72. function TOmfObjData.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  73. begin
  74. result:=aname;
  75. end;
  76. procedure TOmfObjData.writeReloc(Data:aint;len:aword;p:TObjSymbol;Reloctype:TObjRelocationType);
  77. begin
  78. end;
  79. {****************************************************************************
  80. TOmfObjOutput
  81. ****************************************************************************}
  82. procedure TOmfObjOutput.AddSegment(const name, segclass: string;
  83. Alignment: TOmfSegmentAlignment; Combination: TOmfSegmentCombination;
  84. Use: TOmfSegmentUse);
  85. var
  86. s: TOmfRecord_SEGDEF;
  87. begin
  88. s:=TOmfRecord_SEGDEF.Create;
  89. Segments.Add(name,s);
  90. s.SegmentNameIndex:=LNames.Add(name);
  91. s.ClassNameIndex:=LNames.Add(segclass);
  92. s.OverlayNameIndex:=1;
  93. s.Alignment:=Alignment;
  94. s.Combination:=Combination;
  95. s.Use:=Use;
  96. end;
  97. procedure TOmfObjOutput.AddGroup(const groupname: string; seglist: array of const);
  98. var
  99. g: TOmfRecord_GRPDEF;
  100. I: Integer;
  101. SegListStr: TSegmentList;
  102. begin
  103. g:=TOmfRecord_GRPDEF.Create;
  104. Groups.Add(groupname,g);
  105. g.GroupNameIndex:=LNames.Add(groupname);
  106. SetLength(SegListStr,Length(seglist));
  107. for I:=0 to High(seglist) do
  108. begin
  109. case seglist[I].VType of
  110. vtString:
  111. SegListStr[I]:=Segments.FindIndexOf(seglist[I].VString^);
  112. vtAnsiString:
  113. SegListStr[I]:=Segments.FindIndexOf(AnsiString(seglist[I].VAnsiString));
  114. vtWideString:
  115. SegListStr[I]:=Segments.FindIndexOf(WideString(seglist[I].VWideString));
  116. vtUnicodeString:
  117. SegListStr[I]:=Segments.FindIndexOf(UnicodeString(seglist[I].VUnicodeString));
  118. else
  119. internalerror(2015040402);
  120. end;
  121. end;
  122. g.SegmentList:=SegListStr;
  123. end;
  124. function TOmfObjOutput.writeData(Data:TObjData):boolean;
  125. var
  126. RawRecord: TOmfRawRecord;
  127. Header: TOmfRecord_THEADR;
  128. Translator_COMENT: TOmfRecord_COMENT;
  129. LinkPassSeparator_COMENT: TOmfRecord_COMENT;
  130. LNamesRec: TOmfRecord_LNAMES;
  131. I: Integer;
  132. SegDef: TOmfRecord_SEGDEF;
  133. GrpDef: TOmfRecord_GRPDEF;
  134. begin
  135. { write header record }
  136. RawRecord:=TOmfRawRecord.Create;
  137. Header:=TOmfRecord_THEADR.Create;
  138. Header.ModuleName:=Data.Name;
  139. Header.EncodeTo(RawRecord);
  140. RawRecord.WriteTo(FWriter);
  141. Header.Free;
  142. { write translator COMENT header }
  143. Translator_COMENT:=TOmfRecord_COMENT.Create;
  144. Translator_COMENT.CommentClass:=CC_Translator;
  145. Translator_COMENT.CommentString:='FPC '+full_version_string+
  146. ' ['+date_string+'] for '+target_cpu_string+' - '+target_info.shortname;
  147. Translator_COMENT.EncodeTo(RawRecord);
  148. RawRecord.WriteTo(FWriter);
  149. Translator_COMENT.Free;
  150. LNames.Clear;
  151. LNames.Add(''); { insert an empty string, which has index 1 }
  152. if not (cs_huge_code in current_settings.moduleswitches) then
  153. AddSegment({CodeSectionName(current_module.modulename^)}'text','code',saRelocatableByteAligned,scPublic,suUse16);
  154. AddSegment('rodata','data',saRelocatableByteAligned,scPublic,suUse16);
  155. AddSegment('data','data',saRelocatableWordAligned,scPublic,suUse16);
  156. AddSegment('fpc','data',saRelocatableByteAligned,scPublic,suUse16);
  157. AddSegment('bss','bss',saRelocatableByteAligned,scPublic,suUse16);
  158. AddSegment('stack','stack',saRelocatableParaAligned,scStack,suUse16);
  159. AddSegment('heap','heap',saRelocatableParaAligned,scPublic,suUse16);
  160. if current_settings.x86memorymodel=mm_tiny then
  161. AddGroup('dgroup',['text','rodata','data','fpc','bss','heap'])
  162. else if current_settings.x86memorymodel in x86_near_data_models then
  163. AddGroup('dgroup',['rodata','data','fpc','bss','stack','heap'])
  164. else
  165. AddGroup('dgroup',['rodata','data','fpc','bss']);
  166. { write LNAMES record(s) }
  167. LNamesRec:=TOmfRecord_LNAMES.Create;
  168. LNamesRec.Names:=LNames;
  169. while LNamesRec.NextIndex<=LNames.Count do
  170. begin
  171. LNamesRec.EncodeTo(RawRecord);
  172. RawRecord.WriteTo(FWriter);
  173. end;
  174. LNamesRec.Free;
  175. { write SEGDEF record(s) }
  176. for I:=1 to Segments.Count-1 do
  177. begin
  178. SegDef:=TOmfRecord_SEGDEF(Segments[I]);
  179. SegDef.EncodeTo(RawRecord);
  180. RawRecord.WriteTo(FWriter);
  181. end;
  182. { write GRPDEF record(s) }
  183. for I:=1 to Groups.Count-1 do
  184. begin
  185. GrpDef:=TOmfRecord_GRPDEF(Groups[I]);
  186. GrpDef.EncodeTo(RawRecord);
  187. RawRecord.WriteTo(FWriter);
  188. end;
  189. { write link pass separator }
  190. LinkPassSeparator_COMENT:=TOmfRecord_COMENT.Create;
  191. LinkPassSeparator_COMENT.CommentClass:=CC_LinkPassSeparator;
  192. LinkPassSeparator_COMENT.CommentString:=#1;
  193. LinkPassSeparator_COMENT.NoList:=True;
  194. LinkPassSeparator_COMENT.EncodeTo(RawRecord);
  195. RawRecord.WriteTo(FWriter);
  196. LinkPassSeparator_COMENT.Free;
  197. RawRecord.Free;
  198. result:=true;
  199. end;
  200. constructor TOmfObjOutput.create(AWriter:TObjectWriter);
  201. begin
  202. inherited create(AWriter);
  203. cobjdata:=TOmfObjData;
  204. FLNames:=TOmfOrderedNameCollection.Create;
  205. FSegments:=TFPHashObjectList.Create;
  206. FSegments.Add('',nil);
  207. FGroups:=TFPHashObjectList.Create;
  208. FGroups.Add('',nil);
  209. end;
  210. destructor TOmfObjOutput.Destroy;
  211. begin
  212. FGroups.Free;
  213. FSegments.Free;
  214. FLNames.Free;
  215. inherited Destroy;
  216. end;
  217. {****************************************************************************
  218. TOmfAssembler
  219. ****************************************************************************}
  220. constructor TOmfAssembler.Create(smart:boolean);
  221. begin
  222. inherited Create(smart);
  223. CObjOutput:=TOmfObjOutput;
  224. end;
  225. {*****************************************************************************
  226. Initialize
  227. *****************************************************************************}
  228. {$ifdef i8086}
  229. const
  230. as_i8086_omf_info : tasminfo =
  231. (
  232. id : as_i8086_omf;
  233. idtxt : 'OMF';
  234. asmbin : '';
  235. asmcmd : '';
  236. supported_targets : [system_i8086_msdos];
  237. flags : [af_outputbinary,af_needar,af_no_debug];
  238. labelprefix : '..@';
  239. comment : '; ';
  240. dollarsign: '$';
  241. );
  242. {$endif i8086}
  243. initialization
  244. {$ifdef i8086}
  245. RegisterAssembler(as_i8086_omf_info,TOmfAssembler);
  246. {$endif i8086}
  247. end.