ogomf.pas 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718
  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. { TOmfRelocation }
  35. TOmfRelocation = class(TObjRelocation)
  36. private
  37. FOmfFixup: TOmfSubRecord_FIXUP;
  38. function GetGroupIndex(const groupname: string): Integer;
  39. public
  40. constructor CreateSection(ADataOffset:aword;aobjsec:TObjSection;Atyp:TObjRelocationType);
  41. destructor Destroy; override;
  42. procedure BuildOmfFixup;
  43. property OmfFixup: TOmfSubRecord_FIXUP read FOmfFixup;
  44. end;
  45. { TOmfObjSection }
  46. TOmfObjSection = class(TObjSection)
  47. private
  48. FClassName: string;
  49. FOverlayName: string;
  50. FCombination: TOmfSegmentCombination;
  51. FUse: TOmfSegmentUse;
  52. FPrimaryGroup: string;
  53. function GetOmfAlignment: TOmfSegmentAlignment;
  54. public
  55. constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);override;
  56. property ClassName: string read FClassName;
  57. property OverlayName: string read FOverlayName;
  58. property OmfAlignment: TOmfSegmentAlignment read GetOmfAlignment;
  59. property Combination: TOmfSegmentCombination read FCombination;
  60. property Use: TOmfSegmentUse read FUse;
  61. property PrimaryGroup: string read FPrimaryGroup;
  62. end;
  63. { TOmfObjData }
  64. TOmfObjData = class(TObjData)
  65. private
  66. class function CodeSectionName(const aname:string): string;
  67. public
  68. constructor create(const n:string);override;
  69. function sectiontype2align(atype:TAsmSectiontype):shortint;override;
  70. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  71. procedure writeReloc(Data:aint;len:aword;p:TObjSymbol;Reloctype:TObjRelocationType);override;
  72. end;
  73. { TOmfObjOutput }
  74. TOmfObjOutput = class(tObjOutput)
  75. private
  76. FLNames: TOmfOrderedNameCollection;
  77. FSegments: TFPHashObjectList;
  78. FGroups: TFPHashObjectList;
  79. procedure AddSegment(const name,segclass,ovlname: string;
  80. Alignment: TOmfSegmentAlignment; Combination: TOmfSegmentCombination;
  81. Use: TOmfSegmentUse; Size: aword);
  82. procedure AddGroup(const groupname: string; seglist: array of const);
  83. procedure AddGroup(const groupname: string; seglist: TSegmentList);
  84. procedure WriteSections(Data:TObjData);
  85. procedure WriteSectionContentAndFixups(sec: TObjSection);
  86. procedure section_count_sections(p:TObject;arg:pointer);
  87. procedure WritePUBDEFs(Data: TObjData);
  88. procedure WriteEXTDEFs(Data: TObjData);
  89. property LNames: TOmfOrderedNameCollection read FLNames;
  90. property Segments: TFPHashObjectList read FSegments;
  91. property Groups: TFPHashObjectList read FGroups;
  92. protected
  93. function writeData(Data:TObjData):boolean;override;
  94. public
  95. constructor create(AWriter:TObjectWriter);override;
  96. destructor Destroy;override;
  97. end;
  98. { TOmfObjInput }
  99. TOmfObjInput = class(TObjInput)
  100. private
  101. FLNames: TOmfOrderedNameCollection;
  102. FExtDefs: TFPHashObjectList;
  103. FPubDefs: TFPHashObjectList;
  104. FRawRecord: TOmfRawRecord;
  105. FCaseSensitive: Boolean;
  106. function PeekNextRecordType: Byte;
  107. function ReadLNames(RawRec: TOmfRawRecord): Boolean;
  108. function ReadSegDef(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
  109. function ReadGrpDef(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
  110. function ReadExtDef(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
  111. function ReadPubDef(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
  112. function ReadModEnd(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
  113. function ReadLEDataAndFixups(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
  114. function ImportOmfFixup(objdata: TObjData; objsec: TOmfObjSection; Fixup: TOmfSubRecord_FIXUP): Boolean;
  115. property LNames: TOmfOrderedNameCollection read FLNames;
  116. property ExtDefs: TFPHashObjectList read FExtDefs;
  117. property PubDefs: TFPHashObjectList read FPubDefs;
  118. { Specifies whether we're case sensitive in regards to segment, class, overlay and group names.
  119. Symbols (in EXTDEF and PUBDEF records) are always case sensitive, regardless of the value of this property. }
  120. property CaseSensitive: Boolean read FCaseSensitive write FCaseSensitive;
  121. public
  122. constructor create;override;
  123. destructor destroy;override;
  124. class function CanReadObjData(AReader:TObjectreader):boolean;override;
  125. function ReadObjData(AReader:TObjectreader;out objdata:TObjData):boolean;override;
  126. end;
  127. { TMZExeRelocation }
  128. TMZExeRelocation = record
  129. offset: Word;
  130. segment: Word;
  131. end;
  132. TMZExeRelocations = array of TMZExeRelocation;
  133. TMZExeExtraHeaderData = array of Byte;
  134. { TMZExeHeader }
  135. TMZExeHeader = class
  136. private
  137. FChecksum: Word;
  138. FExtraHeaderData: TMZExeExtraHeaderData;
  139. FHeaderSizeAlignment: Integer;
  140. FInitialCS: Word;
  141. FInitialIP: Word;
  142. FInitialSP: Word;
  143. FInitialSS: Word;
  144. FLoadableImageSize: DWord;
  145. FMaxExtraParagraphs: Word;
  146. FMinExtraParagraphs: Word;
  147. FOverlayNumber: Word;
  148. FRelocations: TMZExeRelocations;
  149. procedure SetHeaderSizeAlignment(AValue: Integer);
  150. public
  151. constructor Create;
  152. procedure WriteTo(aWriter: TObjectWriter);
  153. property HeaderSizeAlignment: Integer read FHeaderSizeAlignment write SetHeaderSizeAlignment; {default=16, must be multiple of 16}
  154. property Relocations: TMZExeRelocations read FRelocations write FRelocations;
  155. property ExtraHeaderData: TMZExeExtraHeaderData read FExtraHeaderData write FExtraHeaderData;
  156. property LoadableImageSize: DWord read FLoadableImageSize write FLoadableImageSize;
  157. property MinExtraParagraphs: Word read FMinExtraParagraphs write FMinExtraParagraphs;
  158. property MaxExtraParagraphs: Word read FMaxExtraParagraphs write FMaxExtraParagraphs;
  159. property InitialSS: Word read FInitialSS write FInitialSS;
  160. property InitialSP: Word read FInitialSP write FInitialSP;
  161. property Checksum: Word read FChecksum write FChecksum;
  162. property InitialIP: Word read FInitialIP write FInitialIP;
  163. property InitialCS: Word read FInitialCS write FInitialCS;
  164. property OverlayNumber: Word read FOverlayNumber write FOverlayNumber;
  165. end;
  166. { TMZExeSection }
  167. TMZExeSection=class(TExeSection)
  168. public
  169. procedure AddObjSection(objsec:TObjSection;ignoreprops:boolean=false);override;
  170. end;
  171. { TMZExeOutput }
  172. TMZExeOutput = class(TExeOutput)
  173. protected
  174. function writeData:boolean;override;
  175. public
  176. constructor create;override;
  177. end;
  178. TOmfAssembler = class(tinternalassembler)
  179. constructor create(smart:boolean);override;
  180. end;
  181. implementation
  182. uses
  183. SysUtils,
  184. cutils,verbose,globals,
  185. fmodule,aasmtai,aasmdata,
  186. ogmap,owomflib,
  187. version
  188. ;
  189. {****************************************************************************
  190. TOmfRelocation
  191. ****************************************************************************}
  192. function TOmfRelocation.GetGroupIndex(const groupname: string): Integer;
  193. begin
  194. if groupname='dgroup' then
  195. Result:=1
  196. else
  197. internalerror(2014040703);
  198. end;
  199. constructor TOmfRelocation.CreateSection(ADataOffset: aword; aobjsec: TObjSection; Atyp: TObjRelocationType);
  200. begin
  201. if not (Atyp in [RELOC_DGROUP,RELOC_DGROUPREL]) and not assigned(aobjsec) then
  202. internalerror(200603036);
  203. DataOffset:=ADataOffset;
  204. Symbol:=nil;
  205. OrgSize:=0;
  206. ObjSection:=aobjsec;
  207. ftype:=ord(Atyp);
  208. end;
  209. destructor TOmfRelocation.Destroy;
  210. begin
  211. FOmfFixup.Free;
  212. inherited Destroy;
  213. end;
  214. procedure TOmfRelocation.BuildOmfFixup;
  215. begin
  216. FreeAndNil(FOmfFixup);
  217. FOmfFixup:=TOmfSubRecord_FIXUP.Create;
  218. if ObjSection<>nil then
  219. begin
  220. FOmfFixup.LocationOffset:=DataOffset;
  221. if typ in [RELOC_ABSOLUTE,RELOC_RELATIVE] then
  222. FOmfFixup.LocationType:=fltOffset
  223. else if typ in [RELOC_SEG,RELOC_SEGREL] then
  224. FOmfFixup.LocationType:=fltBase
  225. else
  226. internalerror(2015041501);
  227. FOmfFixup.FrameDeterminedByThread:=False;
  228. FOmfFixup.TargetDeterminedByThread:=False;
  229. if typ in [RELOC_ABSOLUTE,RELOC_SEG] then
  230. FOmfFixup.Mode:=fmSegmentRelative
  231. else if typ in [RELOC_RELATIVE,RELOC_SEGREL] then
  232. FOmfFixup.Mode:=fmSelfRelative
  233. else
  234. internalerror(2015041401);
  235. if typ in [RELOC_ABSOLUTE,RELOC_RELATIVE] then
  236. begin
  237. FOmfFixup.TargetMethod:=ftmSegmentIndexNoDisp;
  238. FOmfFixup.TargetDatum:=ObjSection.Index;
  239. if TOmfObjSection(ObjSection).PrimaryGroup<>'' then
  240. begin
  241. FOmfFixup.FrameMethod:=ffmGroupIndex;
  242. FOmfFixup.FrameDatum:=GetGroupIndex(TOmfObjSection(ObjSection).PrimaryGroup);
  243. end
  244. else
  245. FOmfFixup.FrameMethod:=ffmTarget;
  246. end
  247. else
  248. begin
  249. FOmfFixup.FrameMethod:=ffmTarget;
  250. if TOmfObjSection(ObjSection).PrimaryGroup<>'' then
  251. begin
  252. FOmfFixup.TargetMethod:=ftmGroupIndexNoDisp;
  253. FOmfFixup.TargetDatum:=GetGroupIndex(TOmfObjSection(ObjSection).PrimaryGroup);
  254. end
  255. else
  256. begin
  257. FOmfFixup.TargetMethod:=ftmSegmentIndexNoDisp;
  258. FOmfFixup.TargetDatum:=ObjSection.Index;
  259. end;
  260. end;
  261. end
  262. else if symbol<>nil then
  263. begin
  264. FOmfFixup.LocationOffset:=DataOffset;
  265. if typ in [RELOC_ABSOLUTE,RELOC_RELATIVE] then
  266. FOmfFixup.LocationType:=fltOffset
  267. else if typ in [RELOC_SEG,RELOC_SEGREL] then
  268. FOmfFixup.LocationType:=fltBase
  269. else
  270. internalerror(2015041501);
  271. FOmfFixup.FrameDeterminedByThread:=False;
  272. FOmfFixup.TargetDeterminedByThread:=False;
  273. if typ in [RELOC_ABSOLUTE,RELOC_SEG] then
  274. FOmfFixup.Mode:=fmSegmentRelative
  275. else if typ in [RELOC_RELATIVE,RELOC_SEGREL] then
  276. FOmfFixup.Mode:=fmSelfRelative
  277. else
  278. internalerror(2015041401);
  279. FOmfFixup.TargetMethod:=ftmExternalIndexNoDisp;
  280. FOmfFixup.TargetDatum:=symbol.symidx;
  281. FOmfFixup.FrameMethod:=ffmTarget;
  282. end
  283. else if typ in [RELOC_DGROUP,RELOC_DGROUPREL] then
  284. begin
  285. FOmfFixup.LocationOffset:=DataOffset;
  286. FOmfFixup.LocationType:=fltBase;
  287. FOmfFixup.FrameDeterminedByThread:=False;
  288. FOmfFixup.TargetDeterminedByThread:=False;
  289. if typ=RELOC_DGROUP then
  290. FOmfFixup.Mode:=fmSegmentRelative
  291. else if typ=RELOC_DGROUPREL then
  292. FOmfFixup.Mode:=fmSelfRelative
  293. else
  294. internalerror(2015041401);
  295. FOmfFixup.FrameMethod:=ffmTarget;
  296. FOmfFixup.TargetMethod:=ftmGroupIndexNoDisp;
  297. FOmfFixup.TargetDatum:=GetGroupIndex('dgroup');
  298. end
  299. else
  300. internalerror(2015040702);
  301. end;
  302. {****************************************************************************
  303. TOmfObjSection
  304. ****************************************************************************}
  305. function TOmfObjSection.GetOmfAlignment: TOmfSegmentAlignment;
  306. begin
  307. case SecAlign of
  308. 1:
  309. result:=saRelocatableByteAligned;
  310. 2:
  311. result:=saRelocatableWordAligned;
  312. 4:
  313. result:=saRelocatableDWordAligned;
  314. 16:
  315. result:=saRelocatableParaAligned;
  316. else
  317. internalerror(2015041504);
  318. end;
  319. end;
  320. constructor TOmfObjSection.create(AList: TFPHashObjectList;
  321. const Aname: string; Aalign: shortint; Aoptions: TObjSectionOptions);
  322. var
  323. dgroup: Boolean;
  324. begin
  325. inherited create(AList, Aname, Aalign, Aoptions);
  326. FCombination:=scPublic;
  327. FUse:=suUse16;
  328. if oso_executable in Aoptions then
  329. begin
  330. FClassName:='code';
  331. dgroup:=(current_settings.x86memorymodel=mm_tiny);
  332. end
  333. else if Aname='stack' then
  334. begin
  335. FClassName:='stack';
  336. FCombination:=scStack;
  337. dgroup:=current_settings.x86memorymodel in (x86_near_data_models-[mm_tiny]);
  338. end
  339. else if Aname='heap' then
  340. begin
  341. FClassName:='heap';
  342. dgroup:=current_settings.x86memorymodel in x86_near_data_models;
  343. end
  344. else if Aname='bss' then
  345. begin
  346. FClassName:='bss';
  347. dgroup:=true;
  348. end
  349. else if Aname='data' then
  350. begin
  351. FClassName:='data';
  352. dgroup:=true;
  353. end
  354. else if (Aname='debug_frame') or
  355. (Aname='debug_info') or
  356. (Aname='debug_line') or
  357. (Aname='debug_abbrev') then
  358. begin
  359. FClassName:='DWARF';
  360. FUse:=suUse32;
  361. dgroup:=false;
  362. end
  363. else
  364. begin
  365. FClassName:='data';
  366. dgroup:=true;
  367. end;
  368. if dgroup then
  369. FPrimaryGroup:='dgroup'
  370. else
  371. FPrimaryGroup:='';
  372. end;
  373. {****************************************************************************
  374. TOmfObjData
  375. ****************************************************************************}
  376. class function TOmfObjData.CodeSectionName(const aname: string): string;
  377. begin
  378. {$ifdef i8086}
  379. if current_settings.x86memorymodel in x86_far_code_models then
  380. begin
  381. if cs_huge_code in current_settings.moduleswitches then
  382. result:=aname + '_TEXT'
  383. else
  384. result:=current_module.modulename^ + '_TEXT';
  385. end
  386. else
  387. {$endif}
  388. result:='text';
  389. end;
  390. constructor TOmfObjData.create(const n: string);
  391. begin
  392. inherited create(n);
  393. CObjSection:=TOmfObjSection;
  394. end;
  395. function TOmfObjData.sectiontype2align(atype: TAsmSectiontype): shortint;
  396. begin
  397. case atype of
  398. sec_stabstr:
  399. result:=1;
  400. sec_code:
  401. result:=1;
  402. sec_data,
  403. sec_rodata,
  404. sec_rodata_norel,
  405. sec_bss:
  406. result:=2;
  407. { For idata (at least idata2) it must be 4 bytes, because
  408. an entry is always (also in win64) 20 bytes and aligning
  409. on 8 bytes will insert 4 bytes between the entries resulting
  410. in a corrupt idata section.
  411. Same story with .pdata, it has 4-byte elements which should
  412. be packed without gaps. }
  413. sec_idata2,sec_idata4,sec_idata5,sec_idata6,sec_idata7,sec_pdata:
  414. result:=4;
  415. sec_debug_frame,sec_debug_info,sec_debug_line,sec_debug_abbrev:
  416. result:=4;
  417. sec_stack,
  418. sec_heap:
  419. result:=16;
  420. else
  421. result:=1;
  422. end;
  423. end;
  424. function TOmfObjData.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  425. const
  426. secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
  427. 'text',
  428. 'data',
  429. 'data',
  430. 'rodata',
  431. 'bss',
  432. 'tbss',
  433. 'pdata',
  434. 'text','data','data','data','data',
  435. 'stab',
  436. 'stabstr',
  437. 'idata2','idata4','idata5','idata6','idata7','edata',
  438. 'eh_frame',
  439. 'debug_frame','debug_info','debug_line','debug_abbrev',
  440. 'fpc',
  441. '',
  442. 'init',
  443. 'fini',
  444. 'objc_class',
  445. 'objc_meta_class',
  446. 'objc_cat_cls_meth',
  447. 'objc_cat_inst_meth',
  448. 'objc_protocol',
  449. 'objc_string_object',
  450. 'objc_cls_meth',
  451. 'objc_inst_meth',
  452. 'objc_cls_refs',
  453. 'objc_message_refs',
  454. 'objc_symbols',
  455. 'objc_category',
  456. 'objc_class_vars',
  457. 'objc_instance_vars',
  458. 'objc_module_info',
  459. 'objc_class_names',
  460. 'objc_meth_var_types',
  461. 'objc_meth_var_names',
  462. 'objc_selector_strs',
  463. 'objc_protocol_ext',
  464. 'objc_class_ext',
  465. 'objc_property',
  466. 'objc_image_info',
  467. 'objc_cstring_object',
  468. 'objc_sel_fixup',
  469. '__DATA,__objc_data',
  470. '__DATA,__objc_const',
  471. 'objc_superrefs',
  472. '__DATA, __datacoal_nt,coalesced',
  473. 'objc_classlist',
  474. 'objc_nlclasslist',
  475. 'objc_catlist',
  476. 'obcj_nlcatlist',
  477. 'objc_protolist',
  478. 'stack',
  479. 'heap'
  480. );
  481. begin
  482. if (atype=sec_user) then
  483. Result:=aname
  484. else if secnames[atype]='text' then
  485. Result:=CodeSectionName(aname)
  486. else
  487. Result:=secnames[atype];
  488. end;
  489. procedure TOmfObjData.writeReloc(Data:aint;len:aword;p:TObjSymbol;Reloctype:TObjRelocationType);
  490. var
  491. objreloc: TOmfRelocation;
  492. symaddr: AWord;
  493. begin
  494. { RELOC_FARPTR = RELOC_ABSOLUTE+RELOC_SEG }
  495. if Reloctype=RELOC_FARPTR then
  496. begin
  497. if len<>4 then
  498. internalerror(2015041502);
  499. writeReloc(Data,2,p,RELOC_ABSOLUTE);
  500. writeReloc(0,2,p,RELOC_SEG);
  501. exit;
  502. end;
  503. if CurrObjSec=nil then
  504. internalerror(200403072);
  505. objreloc:=nil;
  506. if assigned(p) then
  507. begin
  508. { real address of the symbol }
  509. symaddr:=p.address;
  510. if p.bind=AB_EXTERNAL then
  511. begin
  512. objreloc:=TOmfRelocation.CreateSymbol(CurrObjSec.Size,p,Reloctype);
  513. CurrObjSec.ObjRelocations.Add(objreloc);
  514. end
  515. { relative relocations within the same section can be calculated directly,
  516. without the need to emit a relocation entry }
  517. else if (p.objsection=CurrObjSec) and
  518. (p.bind<>AB_COMMON) and
  519. (Reloctype=RELOC_RELATIVE) then
  520. begin
  521. data:=data+symaddr-len-CurrObjSec.Size;
  522. end
  523. else
  524. begin
  525. objreloc:=TOmfRelocation.CreateSection(CurrObjSec.Size,p.objsection,Reloctype);
  526. CurrObjSec.ObjRelocations.Add(objreloc);
  527. if not (Reloctype in [RELOC_SEG,RELOC_SEGREL]) then
  528. inc(data,symaddr);
  529. end;
  530. end
  531. else if Reloctype in [RELOC_DGROUP,RELOC_DGROUPREL] then
  532. begin
  533. objreloc:=TOmfRelocation.CreateSection(CurrObjSec.Size,nil,Reloctype);
  534. CurrObjSec.ObjRelocations.Add(objreloc);
  535. end;
  536. CurrObjSec.write(data,len);
  537. end;
  538. {****************************************************************************
  539. TOmfObjOutput
  540. ****************************************************************************}
  541. procedure TOmfObjOutput.AddSegment(const name, segclass, ovlname: string;
  542. Alignment: TOmfSegmentAlignment; Combination: TOmfSegmentCombination;
  543. Use: TOmfSegmentUse; Size: aword);
  544. var
  545. s: TOmfRecord_SEGDEF;
  546. begin
  547. s:=TOmfRecord_SEGDEF.Create;
  548. Segments.Add(name,s);
  549. s.SegmentNameIndex:=LNames.Add(name);
  550. s.ClassNameIndex:=LNames.Add(segclass);
  551. s.OverlayNameIndex:=LNames.Add(ovlname);
  552. s.Alignment:=Alignment;
  553. s.Combination:=Combination;
  554. s.Use:=Use;
  555. s.SegmentLength:=Size;
  556. end;
  557. procedure TOmfObjOutput.AddGroup(const groupname: string; seglist: array of const);
  558. var
  559. g: TOmfRecord_GRPDEF;
  560. I: Integer;
  561. SegListStr: TSegmentList;
  562. begin
  563. g:=TOmfRecord_GRPDEF.Create;
  564. Groups.Add(groupname,g);
  565. g.GroupNameIndex:=LNames.Add(groupname);
  566. SetLength(SegListStr,Length(seglist));
  567. for I:=0 to High(seglist) do
  568. begin
  569. case seglist[I].VType of
  570. vtString:
  571. SegListStr[I]:=Segments.FindIndexOf(seglist[I].VString^);
  572. vtAnsiString:
  573. SegListStr[I]:=Segments.FindIndexOf(AnsiString(seglist[I].VAnsiString));
  574. vtWideString:
  575. SegListStr[I]:=Segments.FindIndexOf(AnsiString(WideString(seglist[I].VWideString)));
  576. vtUnicodeString:
  577. SegListStr[I]:=Segments.FindIndexOf(AnsiString(UnicodeString(seglist[I].VUnicodeString)));
  578. else
  579. internalerror(2015040402);
  580. end;
  581. end;
  582. g.SegmentList:=SegListStr;
  583. end;
  584. procedure TOmfObjOutput.AddGroup(const groupname: string; seglist: TSegmentList);
  585. var
  586. g: TOmfRecord_GRPDEF;
  587. begin
  588. g:=TOmfRecord_GRPDEF.Create;
  589. Groups.Add(groupname,g);
  590. g.GroupNameIndex:=LNames.Add(groupname);
  591. g.SegmentList:=Copy(seglist);
  592. end;
  593. procedure TOmfObjOutput.WriteSections(Data: TObjData);
  594. var
  595. i:longint;
  596. sec:TObjSection;
  597. begin
  598. for i:=0 to Data.ObjSectionList.Count-1 do
  599. begin
  600. sec:=TObjSection(Data.ObjSectionList[i]);
  601. WriteSectionContentAndFixups(sec);
  602. end;
  603. end;
  604. procedure TOmfObjOutput.WriteSectionContentAndFixups(sec: TObjSection);
  605. const
  606. MaxChunkSize=$3fa;
  607. var
  608. RawRecord: TOmfRawRecord;
  609. ChunkStart,ChunkLen: DWord;
  610. ChunkFixupStart,ChunkFixupEnd: Integer;
  611. SegIndex: Integer;
  612. NextOfs: Integer;
  613. I: Integer;
  614. begin
  615. if (oso_data in sec.SecOptions) then
  616. begin
  617. if sec.Data=nil then
  618. internalerror(200403073);
  619. for I:=0 to sec.ObjRelocations.Count-1 do
  620. TOmfRelocation(sec.ObjRelocations[I]).BuildOmfFixup;
  621. SegIndex:=Segments.FindIndexOf(sec.Name);
  622. RawRecord:=TOmfRawRecord.Create;
  623. sec.data.seek(0);
  624. ChunkFixupStart:=0;
  625. ChunkFixupEnd:=-1;
  626. ChunkStart:=0;
  627. ChunkLen:=Min(MaxChunkSize, sec.Data.size-ChunkStart);
  628. while ChunkLen>0 do
  629. begin
  630. { find last fixup in the chunk }
  631. while (ChunkFixupEnd<(sec.ObjRelocations.Count-1)) and
  632. (TOmfRelocation(sec.ObjRelocations[ChunkFixupEnd+1]).DataOffset<(ChunkStart+ChunkLen)) do
  633. inc(ChunkFixupEnd);
  634. { check if last chunk is crossing the chunk boundary, and trim ChunkLen if necessary }
  635. if (ChunkFixupEnd>=ChunkFixupStart) and
  636. ((TOmfRelocation(sec.ObjRelocations[ChunkFixupEnd]).DataOffset+
  637. TOmfRelocation(sec.ObjRelocations[ChunkFixupEnd]).OmfFixup.LocationSize)>(ChunkStart+ChunkLen)) then
  638. begin
  639. ChunkLen:=TOmfRelocation(sec.ObjRelocations[ChunkFixupEnd]).DataOffset-ChunkStart;
  640. Dec(ChunkFixupEnd);
  641. end;
  642. { write LEDATA record }
  643. RawRecord.RecordType:=RT_LEDATA;
  644. NextOfs:=RawRecord.WriteIndexedRef(0,SegIndex);
  645. RawRecord.RawData[NextOfs]:=Byte(ChunkStart);
  646. RawRecord.RawData[NextOfs+1]:=Byte(ChunkStart shr 8);
  647. Inc(NextOfs,2);
  648. sec.data.read(RawRecord.RawData[NextOfs], ChunkLen);
  649. Inc(NextOfs, ChunkLen);
  650. RawRecord.RecordLength:=NextOfs+1;
  651. RawRecord.CalculateChecksumByte;
  652. RawRecord.WriteTo(FWriter);
  653. { write FIXUPP record }
  654. if ChunkFixupEnd>=ChunkFixupStart then
  655. begin
  656. RawRecord.RecordType:=RT_FIXUPP;
  657. NextOfs:=0;
  658. for I:=ChunkFixupStart to ChunkFixupEnd do
  659. begin
  660. TOmfRelocation(sec.ObjRelocations[I]).OmfFixup.DataRecordStartOffset:=ChunkStart;
  661. NextOfs:=TOmfRelocation(sec.ObjRelocations[I]).OmfFixup.WriteAt(RawRecord,NextOfs);
  662. end;
  663. RawRecord.RecordLength:=NextOfs+1;
  664. RawRecord.CalculateChecksumByte;
  665. RawRecord.WriteTo(FWriter);
  666. end;
  667. { prepare next chunk }
  668. Inc(ChunkStart, ChunkLen);
  669. ChunkLen:=Min(MaxChunkSize, sec.Data.size-ChunkStart);
  670. ChunkFixupStart:=ChunkFixupEnd+1;
  671. end;
  672. RawRecord.Free;
  673. end;
  674. end;
  675. procedure TOmfObjOutput.section_count_sections(p: TObject; arg: pointer);
  676. begin
  677. TOmfObjSection(p).index:=pinteger(arg)^;
  678. inc(pinteger(arg)^);
  679. end;
  680. procedure TOmfObjOutput.WritePUBDEFs(Data: TObjData);
  681. var
  682. PubNamesForSection: array of TFPHashObjectList;
  683. i: Integer;
  684. objsym: TObjSymbol;
  685. PublicNameElem: TOmfPublicNameElement;
  686. RawRecord: TOmfRawRecord;
  687. PubDefRec: TOmfRecord_PUBDEF;
  688. PrimaryGroupName: string;
  689. begin
  690. RawRecord:=TOmfRawRecord.Create;
  691. SetLength(PubNamesForSection,Data.ObjSectionList.Count);
  692. for i:=0 to Data.ObjSectionList.Count-1 do
  693. PubNamesForSection[i]:=TFPHashObjectList.Create;
  694. for i:=0 to Data.ObjSymbolList.Count-1 do
  695. begin
  696. objsym:=TObjSymbol(Data.ObjSymbolList[i]);
  697. if objsym.bind=AB_GLOBAL then
  698. begin
  699. PublicNameElem:=TOmfPublicNameElement.Create(PubNamesForSection[objsym.objsection.index-1],objsym.Name);
  700. PublicNameElem.PublicOffset:=objsym.offset;
  701. end;
  702. end;
  703. for i:=0 to Data.ObjSectionList.Count-1 do
  704. if PubNamesForSection[i].Count>0 then
  705. begin
  706. PubDefRec:=TOmfRecord_PUBDEF.Create;
  707. PubDefRec.BaseSegmentIndex:=i+1;
  708. PrimaryGroupName:=TOmfObjSection(Data.ObjSectionList[i]).PrimaryGroup;
  709. if PrimaryGroupName<>'' then
  710. PubDefRec.BaseGroupIndex:=Groups.FindIndexOf(PrimaryGroupName)
  711. else
  712. PubDefRec.BaseGroupIndex:=0;
  713. PubDefRec.PublicNames:=PubNamesForSection[i];
  714. while PubDefRec.NextIndex<PubDefRec.PublicNames.Count do
  715. begin
  716. PubDefRec.EncodeTo(RawRecord);
  717. RawRecord.WriteTo(FWriter);
  718. end;
  719. PubDefRec.Free;
  720. end;
  721. for i:=0 to Data.ObjSectionList.Count-1 do
  722. FreeAndNil(PubNamesForSection[i]);
  723. RawRecord.Free;
  724. end;
  725. procedure TOmfObjOutput.WriteEXTDEFs(Data: TObjData);
  726. var
  727. ExtNames: TFPHashObjectList;
  728. RawRecord: TOmfRawRecord;
  729. i,idx: Integer;
  730. objsym: TObjSymbol;
  731. ExternalNameElem: TOmfExternalNameElement;
  732. ExtDefRec: TOmfRecord_EXTDEF;
  733. begin
  734. ExtNames:=TFPHashObjectList.Create;
  735. RawRecord:=TOmfRawRecord.Create;
  736. idx:=1;
  737. for i:=0 to Data.ObjSymbolList.Count-1 do
  738. begin
  739. objsym:=TObjSymbol(Data.ObjSymbolList[i]);
  740. if objsym.bind=AB_EXTERNAL then
  741. begin
  742. ExternalNameElem:=TOmfExternalNameElement.Create(ExtNames,objsym.Name);
  743. objsym.symidx:=idx;
  744. Inc(idx);
  745. end;
  746. end;
  747. if ExtNames.Count>0 then
  748. begin
  749. ExtDefRec:=TOmfRecord_EXTDEF.Create;
  750. ExtDefRec.ExternalNames:=ExtNames;
  751. while ExtDefRec.NextIndex<ExtDefRec.ExternalNames.Count do
  752. begin
  753. ExtDefRec.EncodeTo(RawRecord);
  754. RawRecord.WriteTo(FWriter);
  755. end;
  756. ExtDefRec.Free;
  757. end;
  758. ExtNames.Free;
  759. RawRecord.Free;
  760. end;
  761. function TOmfObjOutput.writeData(Data:TObjData):boolean;
  762. var
  763. RawRecord: TOmfRawRecord;
  764. Header: TOmfRecord_THEADR;
  765. Translator_COMENT: TOmfRecord_COMENT;
  766. LinkPassSeparator_COMENT: TOmfRecord_COMENT;
  767. LNamesRec: TOmfRecord_LNAMES;
  768. ModEnd: TOmfRecord_MODEND;
  769. I: Integer;
  770. SegDef: TOmfRecord_SEGDEF;
  771. GrpDef: TOmfRecord_GRPDEF;
  772. DGroupSegments: TSegmentList;
  773. nsections: Integer;
  774. begin
  775. { calc amount of sections we have and set their index, starting with 1 }
  776. nsections:=1;
  777. data.ObjSectionList.ForEachCall(@section_count_sections,@nsections);
  778. { maximum amount of sections supported in the omf format is $7fff }
  779. if (nsections-1)>$7fff then
  780. internalerror(2015040701);
  781. { write header record }
  782. RawRecord:=TOmfRawRecord.Create;
  783. Header:=TOmfRecord_THEADR.Create;
  784. Header.ModuleName:=Data.Name;
  785. Header.EncodeTo(RawRecord);
  786. RawRecord.WriteTo(FWriter);
  787. Header.Free;
  788. { write translator COMENT header }
  789. Translator_COMENT:=TOmfRecord_COMENT.Create;
  790. Translator_COMENT.CommentClass:=CC_Translator;
  791. Translator_COMENT.CommentString:='FPC '+full_version_string+
  792. ' ['+date_string+'] for '+target_cpu_string+' - '+target_info.shortname;
  793. Translator_COMENT.EncodeTo(RawRecord);
  794. RawRecord.WriteTo(FWriter);
  795. Translator_COMENT.Free;
  796. LNames.Clear;
  797. LNames.Add(''); { insert an empty string, which has index 1 }
  798. FSegments.Clear;
  799. FSegments.Add('',nil);
  800. FGroups.Clear;
  801. FGroups.Add('',nil);
  802. for i:=0 to Data.ObjSectionList.Count-1 do
  803. with TOmfObjSection(Data.ObjSectionList[I]) do
  804. AddSegment(Name,ClassName,OverlayName,OmfAlignment,Combination,Use,Size);
  805. { create group "dgroup" }
  806. SetLength(DGroupSegments,0);
  807. for i:=0 to Data.ObjSectionList.Count-1 do
  808. with TOmfObjSection(Data.ObjSectionList[I]) do
  809. if PrimaryGroup='dgroup' then
  810. begin
  811. SetLength(DGroupSegments,Length(DGroupSegments)+1);
  812. DGroupSegments[High(DGroupSegments)]:=index;
  813. end;
  814. AddGroup('dgroup',DGroupSegments);
  815. { write LNAMES record(s) }
  816. LNamesRec:=TOmfRecord_LNAMES.Create;
  817. LNamesRec.Names:=LNames;
  818. while LNamesRec.NextIndex<=LNames.Count do
  819. begin
  820. LNamesRec.EncodeTo(RawRecord);
  821. RawRecord.WriteTo(FWriter);
  822. end;
  823. LNamesRec.Free;
  824. { write SEGDEF record(s) }
  825. for I:=1 to Segments.Count-1 do
  826. begin
  827. SegDef:=TOmfRecord_SEGDEF(Segments[I]);
  828. SegDef.EncodeTo(RawRecord);
  829. RawRecord.WriteTo(FWriter);
  830. end;
  831. { write GRPDEF record(s) }
  832. for I:=1 to Groups.Count-1 do
  833. begin
  834. GrpDef:=TOmfRecord_GRPDEF(Groups[I]);
  835. GrpDef.EncodeTo(RawRecord);
  836. RawRecord.WriteTo(FWriter);
  837. end;
  838. { write PUBDEF record(s) }
  839. WritePUBDEFs(Data);
  840. { write EXTDEF record(s) }
  841. WriteEXTDEFs(Data);
  842. { write link pass separator }
  843. LinkPassSeparator_COMENT:=TOmfRecord_COMENT.Create;
  844. LinkPassSeparator_COMENT.CommentClass:=CC_LinkPassSeparator;
  845. LinkPassSeparator_COMENT.CommentString:=#1;
  846. LinkPassSeparator_COMENT.NoList:=True;
  847. LinkPassSeparator_COMENT.EncodeTo(RawRecord);
  848. RawRecord.WriteTo(FWriter);
  849. LinkPassSeparator_COMENT.Free;
  850. { write section content, interleaved with fixups }
  851. WriteSections(Data);
  852. { write MODEND record }
  853. ModEnd:=TOmfRecord_MODEND.Create;
  854. ModEnd.EncodeTo(RawRecord);
  855. RawRecord.WriteTo(FWriter);
  856. ModEnd.Free;
  857. RawRecord.Free;
  858. result:=true;
  859. end;
  860. constructor TOmfObjOutput.create(AWriter:TObjectWriter);
  861. begin
  862. inherited create(AWriter);
  863. cobjdata:=TOmfObjData;
  864. FLNames:=TOmfOrderedNameCollection.Create;
  865. FSegments:=TFPHashObjectList.Create;
  866. FSegments.Add('',nil);
  867. FGroups:=TFPHashObjectList.Create;
  868. FGroups.Add('',nil);
  869. end;
  870. destructor TOmfObjOutput.Destroy;
  871. begin
  872. FGroups.Free;
  873. FSegments.Free;
  874. FLNames.Free;
  875. inherited Destroy;
  876. end;
  877. {****************************************************************************
  878. TOmfObjInput
  879. ****************************************************************************}
  880. function TOmfObjInput.PeekNextRecordType: Byte;
  881. var
  882. OldPos: LongInt;
  883. begin
  884. OldPos:=FReader.Pos;
  885. if not FReader.read(Result, 1) then
  886. begin
  887. InputError('Unexpected end of file');
  888. Result:=0;
  889. exit;
  890. end;
  891. FReader.seek(OldPos);
  892. end;
  893. function TOmfObjInput.ReadLNames(RawRec: TOmfRawRecord): Boolean;
  894. var
  895. LNamesRec: TOmfRecord_LNAMES;
  896. begin
  897. Result:=False;
  898. LNamesRec:=TOmfRecord_LNAMES.Create;
  899. LNamesRec.Names:=LNames;
  900. LNamesRec.DecodeFrom(RawRec);
  901. LNamesRec.Free;
  902. Result:=True;
  903. end;
  904. function TOmfObjInput.ReadSegDef(RawRec: TOmfRawRecord; objdata: TObjData): Boolean;
  905. var
  906. SegDefRec: TOmfRecord_SEGDEF;
  907. SegmentName,SegClassName,OverlayName: string;
  908. SecAlign: ShortInt;
  909. secoptions: TObjSectionOptions;
  910. objsec: TOmfObjSection;
  911. begin
  912. Result:=False;
  913. SegDefRec:=TOmfRecord_SEGDEF.Create;
  914. SegDefRec.DecodeFrom(RawRec);
  915. if (SegDefRec.SegmentNameIndex<1) or (SegDefRec.SegmentNameIndex>LNames.Count) then
  916. begin
  917. InputError('Segment name index out of range');
  918. SegDefRec.Free;
  919. exit;
  920. end;
  921. SegmentName:=LNames[SegDefRec.SegmentNameIndex];
  922. if (SegDefRec.ClassNameIndex<1) or (SegDefRec.ClassNameIndex>LNames.Count) then
  923. begin
  924. InputError('Segment class name index out of range');
  925. SegDefRec.Free;
  926. exit;
  927. end;
  928. SegClassName:=LNames[SegDefRec.ClassNameIndex];
  929. if (SegDefRec.OverlayNameIndex<1) or (SegDefRec.OverlayNameIndex>LNames.Count) then
  930. begin
  931. InputError('Segment overlay name index out of range');
  932. SegDefRec.Free;
  933. exit;
  934. end;
  935. OverlayName:=LNames[SegDefRec.OverlayNameIndex];
  936. SecAlign:=1; // otherwise warning prohibits compilation
  937. case SegDefRec.Alignment of
  938. saRelocatableByteAligned:
  939. SecAlign:=1;
  940. saRelocatableWordAligned:
  941. SecAlign:=2;
  942. saRelocatableParaAligned:
  943. SecAlign:=16;
  944. saRelocatableDWordAligned:
  945. SecAlign:=4;
  946. saRelocatablePageAligned:
  947. begin
  948. InputError('Page segment alignment not supported');
  949. SegDefRec.Free;
  950. exit;
  951. end;
  952. saAbsolute:
  953. begin
  954. InputError('Absolute segment alignment not supported');
  955. SegDefRec.Free;
  956. exit;
  957. end;
  958. saNotSupported,
  959. saNotDefined:
  960. begin
  961. InputError('Invalid (unsupported/undefined) OMF segment alignment');
  962. SegDefRec.Free;
  963. exit;
  964. end;
  965. end;
  966. if not CaseSensitive then
  967. begin
  968. SegmentName:=UpCase(SegmentName);
  969. SegClassName:=UpCase(SegClassName);
  970. OverlayName:=UpCase(OverlayName);
  971. end;
  972. secoptions:=[];
  973. objsec:=TOmfObjSection(objdata.createsection(SegmentName+'||'+SegClassName,SecAlign,secoptions,false));
  974. objsec.FClassName:=SegClassName;
  975. objsec.FOverlayName:=OverlayName;
  976. objsec.FCombination:=SegDefRec.Combination;
  977. objsec.FUse:=SegDefRec.Use;
  978. if SegDefRec.SegmentLength>High(objsec.Size) then
  979. begin
  980. InputError('Segment too large');
  981. SegDefRec.Free;
  982. exit;
  983. end;
  984. objsec.Size:=SegDefRec.SegmentLength;
  985. SegDefRec.Free;
  986. Result:=True;
  987. end;
  988. function TOmfObjInput.ReadGrpDef(RawRec: TOmfRawRecord; objdata: TObjData): Boolean;
  989. var
  990. GrpDefRec: TOmfRecord_GRPDEF;
  991. GroupName: string;
  992. SecGroup: TObjSectionGroup;
  993. i,SegIndex: Integer;
  994. begin
  995. Result:=False;
  996. GrpDefRec:=TOmfRecord_GRPDEF.Create;
  997. GrpDefRec.DecodeFrom(RawRec);
  998. if (GrpDefRec.GroupNameIndex<1) or (GrpDefRec.GroupNameIndex>LNames.Count) then
  999. begin
  1000. InputError('Group name index out of range');
  1001. GrpDefRec.Free;
  1002. exit;
  1003. end;
  1004. GroupName:=LNames[GrpDefRec.GroupNameIndex];
  1005. if not CaseSensitive then
  1006. GroupName:=UpCase(GroupName);
  1007. SecGroup:=objdata.createsectiongroup(GroupName);
  1008. SetLength(SecGroup.members,Length(GrpDefRec.SegmentList));
  1009. for i:=0 to Length(GrpDefRec.SegmentList)-1 do
  1010. begin
  1011. SegIndex:=GrpDefRec.SegmentList[i];
  1012. if (SegIndex<1) or (SegIndex>objdata.ObjSectionList.Count) then
  1013. begin
  1014. InputError('Segment name index out of range in group definition');
  1015. GrpDefRec.Free;
  1016. exit;
  1017. end;
  1018. SecGroup.members[i]:=TOmfObjSection(objdata.ObjSectionList[SegIndex-1]);
  1019. end;
  1020. GrpDefRec.Free;
  1021. Result:=True;
  1022. end;
  1023. function TOmfObjInput.ReadExtDef(RawRec: TOmfRawRecord; objdata: TObjData): Boolean;
  1024. var
  1025. ExtDefRec: TOmfRecord_EXTDEF;
  1026. ExtDefElem: TOmfExternalNameElement;
  1027. OldCount,NewCount,i: Integer;
  1028. objsym: TObjSymbol;
  1029. begin
  1030. Result:=False;
  1031. ExtDefRec:=TOmfRecord_EXTDEF.Create;
  1032. ExtDefRec.ExternalNames:=ExtDefs;
  1033. OldCount:=ExtDefs.Count;
  1034. ExtDefRec.DecodeFrom(RawRec);
  1035. NewCount:=ExtDefs.Count;
  1036. for i:=OldCount to NewCount-1 do
  1037. begin
  1038. ExtDefElem:=TOmfExternalNameElement(ExtDefs[i]);
  1039. objsym:=objdata.CreateSymbol(ExtDefElem.Name);
  1040. objsym.bind:=AB_EXTERNAL;
  1041. objsym.typ:=AT_FUNCTION;
  1042. objsym.objsection:=nil;
  1043. objsym.offset:=0;
  1044. objsym.size:=0;
  1045. end;
  1046. ExtDefRec.Free;
  1047. Result:=True;
  1048. end;
  1049. function TOmfObjInput.ReadPubDef(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
  1050. var
  1051. PubDefRec: TOmfRecord_PUBDEF;
  1052. PubDefElem: TOmfPublicNameElement;
  1053. OldCount,NewCount,i: Integer;
  1054. basegroup: TObjSectionGroup;
  1055. objsym: TObjSymbol;
  1056. objsec: TOmfObjSection;
  1057. begin
  1058. Result:=False;
  1059. PubDefRec:=TOmfRecord_PUBDEF.Create;
  1060. PubDefRec.PublicNames:=PubDefs;
  1061. OldCount:=PubDefs.Count;
  1062. PubDefRec.DecodeFrom(RawRec);
  1063. NewCount:=PubDefs.Count;
  1064. if (PubDefRec.BaseGroupIndex<0) or (PubDefRec.BaseGroupIndex>objdata.GroupsList.Count) then
  1065. begin
  1066. InputError('Public symbol''s group name index out of range');
  1067. PubDefRec.Free;
  1068. exit;
  1069. end;
  1070. if PubDefRec.BaseGroupIndex<>0 then
  1071. basegroup:=TObjSectionGroup(objdata.GroupsList[PubDefRec.BaseGroupIndex-1])
  1072. else
  1073. basegroup:=nil;
  1074. if (PubDefRec.BaseSegmentIndex<0) or (PubDefRec.BaseSegmentIndex>objdata.ObjSectionList.Count) then
  1075. begin
  1076. InputError('Public symbol''s segment name index out of range');
  1077. PubDefRec.Free;
  1078. exit;
  1079. end;
  1080. if PubDefRec.BaseSegmentIndex=0 then
  1081. begin
  1082. InputError('Public symbol uses absolute addressing, which is not supported by this linker');
  1083. PubDefRec.Free;
  1084. exit;
  1085. end;
  1086. objsec:=TOmfObjSection(objdata.ObjSectionList[PubDefRec.BaseSegmentIndex-1]);
  1087. for i:=OldCount to NewCount-1 do
  1088. begin
  1089. PubDefElem:=TOmfPublicNameElement(PubDefs[i]);
  1090. objsym:=objdata.CreateSymbol(PubDefElem.Name);
  1091. objsym.bind:=AB_GLOBAL;
  1092. objsym.typ:=AT_FUNCTION;
  1093. objsym.group:=basegroup;
  1094. objsym.objsection:=objsec;
  1095. objsym.offset:=PubDefElem.PublicOffset;
  1096. objsym.size:=0;
  1097. end;
  1098. PubDefRec.Free;
  1099. Result:=True;
  1100. end;
  1101. function TOmfObjInput.ReadModEnd(RawRec: TOmfRawRecord; objdata:TObjData): Boolean;
  1102. var
  1103. ModEndRec: TOmfRecord_MODEND;
  1104. objsym: TObjSymbol;
  1105. objsec: TOmfObjSection;
  1106. begin
  1107. Result:=False;
  1108. ModEndRec:=TOmfRecord_MODEND.Create;
  1109. ModEndRec.DecodeFrom(RawRec);
  1110. if ModEndRec.HasStartAddress then
  1111. begin
  1112. if not ModEndRec.LogicalStartAddress then
  1113. begin
  1114. InputError('Physical start address not supported');
  1115. ModEndRec.Free;
  1116. exit;
  1117. end;
  1118. if not (ModEndRec.TargetMethod in [ftmSegmentIndex,ftmSegmentIndexNoDisp]) then
  1119. begin
  1120. InputError('Target method for start address other than "Segment Index" is not supported');
  1121. ModEndRec.Free;
  1122. exit;
  1123. end;
  1124. if (ModEndRec.TargetDatum<1) or (ModEndRec.TargetDatum>objdata.ObjSectionList.Count) then
  1125. begin
  1126. InputError('Segment name index for start address out of range');
  1127. ModEndRec.Free;
  1128. exit;
  1129. end;
  1130. objsec:=TOmfObjSection(objdata.ObjSectionList[ModEndRec.TargetDatum-1]);
  1131. objsym:=objdata.CreateSymbol('..start');
  1132. objsym.bind:=AB_GLOBAL;
  1133. objsym.typ:=AT_FUNCTION;
  1134. //objsym.group:=basegroup;
  1135. objsym.objsection:=objsec;
  1136. objsym.offset:=ModEndRec.TargetDisplacement;
  1137. objsym.size:=0;
  1138. end;
  1139. ModEndRec.Free;
  1140. Result:=True;
  1141. end;
  1142. function TOmfObjInput.ReadLEDataAndFixups(RawRec: TOmfRawRecord; objdata: TObjData): Boolean;
  1143. var
  1144. Is32Bit: Boolean;
  1145. NextOfs: Integer;
  1146. SegmentIndex: Integer;
  1147. EnumeratedDataOffset: DWord;
  1148. BlockLength: Integer;
  1149. objsec: TOmfObjSection;
  1150. FixupRawRec: TOmfRawRecord;
  1151. Fixup: TOmfSubRecord_FIXUP;
  1152. begin
  1153. Result:=False;
  1154. if not (RawRec.RecordType in [RT_LEDATA,RT_LEDATA32]) then
  1155. internalerror(2015040301);
  1156. Is32Bit:=RawRec.RecordType=RT_LEDATA32;
  1157. NextOfs:=RawRec.ReadIndexedRef(0,SegmentIndex);
  1158. if Is32Bit then
  1159. begin
  1160. if (NextOfs+3)>=RawRec.RecordLength then
  1161. internalerror(2015040504);
  1162. EnumeratedDataOffset := RawRec.RawData[NextOfs]+
  1163. (RawRec.RawData[NextOfs+1] shl 8)+
  1164. (RawRec.RawData[NextOfs+2] shl 16)+
  1165. (RawRec.RawData[NextOfs+3] shl 24);
  1166. Inc(NextOfs,4);
  1167. end
  1168. else
  1169. begin
  1170. if (NextOfs+1)>=RawRec.RecordLength then
  1171. internalerror(2015040504);
  1172. EnumeratedDataOffset := RawRec.RawData[NextOfs]+
  1173. (RawRec.RawData[NextOfs+1] shl 8);
  1174. Inc(NextOfs,2);
  1175. end;
  1176. BlockLength:=RawRec.RecordLength-NextOfs-1;
  1177. if BlockLength<0 then
  1178. internalerror(2015060501);
  1179. if BlockLength>1024 then
  1180. begin
  1181. InputError('LEDATA contains more than 1024 bytes of data');
  1182. exit;
  1183. end;
  1184. if (SegmentIndex<1) or (SegmentIndex>objdata.ObjSectionList.Count) then
  1185. begin
  1186. InputError('Segment index in LEDATA field is out of range');
  1187. exit;
  1188. end;
  1189. objsec:=TOmfObjSection(objdata.ObjSectionList[SegmentIndex-1]);
  1190. objsec.SecOptions:=objsec.SecOptions+[oso_Data];
  1191. if (objsec.Data.Size<>EnumeratedDataOffset) then
  1192. begin
  1193. InputError('LEDATA enumerated data offset field out of sequence');
  1194. exit;
  1195. end;
  1196. if (EnumeratedDataOffset+BlockLength)>objsec.Size then
  1197. begin
  1198. InputError('LEDATA goes beyond the segment size declared in the SEGDEF record');
  1199. exit;
  1200. end;
  1201. objsec.Data.write(RawRec.RawData[NextOfs],BlockLength);
  1202. { also read all the FIXUPP records that may follow }
  1203. while PeekNextRecordType in [RT_FIXUPP,RT_FIXUPP32] do
  1204. begin
  1205. FixupRawRec:=TOmfRawRecord.Create;
  1206. FixupRawRec.ReadFrom(FReader);
  1207. if not FRawRecord.VerifyChecksumByte then
  1208. begin
  1209. InputError('Invalid checksum in OMF record');
  1210. FixupRawRec.Free;
  1211. exit;
  1212. end;
  1213. NextOfs:=0;
  1214. Fixup:=TOmfSubRecord_FIXUP.Create;
  1215. Fixup.Is32Bit:=FixupRawRec.RecordType=RT_FIXUPP32;
  1216. Fixup.DataRecordStartOffset:=EnumeratedDataOffset;
  1217. while NextOfs<(FixupRawRec.RecordLength-1) do
  1218. begin
  1219. NextOfs:=Fixup.ReadAt(FixupRawRec,NextOfs);
  1220. if Fixup.FrameDeterminedByThread or Fixup.TargetDeterminedByThread then
  1221. begin
  1222. InputError('Fixups determined by thread not supported');
  1223. Fixup.Free;
  1224. FixupRawRec.Free;
  1225. exit;
  1226. end;
  1227. ImportOmfFixup(objdata,objsec,Fixup);
  1228. end;
  1229. Fixup.Free;
  1230. FixupRawRec.Free;
  1231. end;
  1232. Result:=True;
  1233. end;
  1234. function TOmfObjInput.ImportOmfFixup(objdata: TObjData; objsec: TOmfObjSection; Fixup: TOmfSubRecord_FIXUP): Boolean;
  1235. var
  1236. reloc: TOmfRelocation;
  1237. sym: TObjSymbol;
  1238. RelocType: TObjRelocationType;
  1239. begin
  1240. Result:=False;
  1241. { range check location }
  1242. if (Fixup.LocationOffset+Fixup.LocationSize)>objsec.Size then
  1243. begin
  1244. InputError('Fixup location exceeds the current segment boundary');
  1245. exit;
  1246. end;
  1247. { range check target datum }
  1248. case Fixup.TargetMethod of
  1249. ftmSegmentIndex:
  1250. if (Fixup.TargetDatum<1) or (Fixup.TargetDatum>objdata.ObjSectionList.Count) then
  1251. begin
  1252. InputError('Segment name index in SI(<segment name>),<displacement> fixup target is out of range');
  1253. exit;
  1254. end;
  1255. ftmSegmentIndexNoDisp:
  1256. if (Fixup.TargetDatum<1) or (Fixup.TargetDatum>objdata.ObjSectionList.Count) then
  1257. begin
  1258. InputError('Segment name index in SI(<segment name>) fixup target is out of range');
  1259. exit;
  1260. end;
  1261. ftmGroupIndex:
  1262. if (Fixup.TargetDatum<1) or (Fixup.TargetDatum>objdata.GroupsList.Count) then
  1263. begin
  1264. InputError('Group name index in GI(<group name>),<displacement> fixup target is out of range');
  1265. exit;
  1266. end;
  1267. ftmGroupIndexNoDisp:
  1268. if (Fixup.TargetDatum<1) or (Fixup.TargetDatum>objdata.GroupsList.Count) then
  1269. begin
  1270. InputError('Group name index in GI(<group name>) fixup target is out of range');
  1271. exit;
  1272. end;
  1273. ftmExternalIndex:
  1274. if (Fixup.TargetDatum<1) or (Fixup.TargetDatum>ExtDefs.Count) then
  1275. begin
  1276. InputError('External symbol name index in EI(<symbol name>),<displacement> fixup target is out of range');
  1277. exit;
  1278. end;
  1279. ftmExternalIndexNoDisp:
  1280. if (Fixup.TargetDatum<1) or (Fixup.TargetDatum>ExtDefs.Count) then
  1281. begin
  1282. InputError('External symbol name index in EI(<symbol name>) fixup target is out of range');
  1283. exit;
  1284. end;
  1285. end;
  1286. { range check frame datum }
  1287. case Fixup.FrameMethod of
  1288. ffmSegmentIndex:
  1289. if (Fixup.FrameDatum<1) or (Fixup.FrameDatum>objdata.ObjSectionList.Count) then
  1290. begin
  1291. InputError('Segment name index in SI(<segment name>) fixup frame is out of range');
  1292. exit;
  1293. end;
  1294. ffmGroupIndex:
  1295. if (Fixup.FrameDatum<1) or (Fixup.FrameDatum>objdata.GroupsList.Count) then
  1296. begin
  1297. InputError('Group name index in GI(<group name>) fixup frame is out of range');
  1298. exit;
  1299. end;
  1300. ffmExternalIndex:
  1301. if (Fixup.TargetDatum<1) or (Fixup.TargetDatum>ExtDefs.Count) then
  1302. begin
  1303. InputError('External symbol name index in EI(<symbol name>) fixup frame is out of range');
  1304. exit;
  1305. end;
  1306. end;
  1307. if Fixup.TargetMethod in [ftmExternalIndex,ftmExternalIndexNoDisp] then
  1308. begin
  1309. sym:=objdata.symbolref(TOmfExternalNameElement(ExtDefs[Fixup.TargetDatum-1]).Name);
  1310. case Fixup.LocationType of
  1311. fltOffset:
  1312. case Fixup.Mode of
  1313. fmSegmentRelative:
  1314. RelocType:=RELOC_ABSOLUTE;
  1315. fmSelfRelative:
  1316. RelocType:=RELOC_RELATIVE;
  1317. end;
  1318. fltBase:
  1319. case Fixup.Mode of
  1320. fmSegmentRelative:
  1321. RelocType:=RELOC_SEG;
  1322. fmSelfRelative:
  1323. RelocType:=RELOC_SEGREL;
  1324. end;
  1325. else
  1326. begin
  1327. InputError('Unsupported fixup location type '+IntToStr(Ord(Fixup.LocationType))+' in external reference to '+sym.Name);
  1328. exit;
  1329. end;
  1330. end;
  1331. case Fixup.FrameMethod of
  1332. ffmTarget:
  1333. {nothing};
  1334. ffmGroupIndex:
  1335. begin
  1336. {todo: handle 'wrt dgroup' here}
  1337. end;
  1338. else
  1339. begin
  1340. InputError('Unsupported frame method '+IntToStr(Ord(Fixup.FrameMethod))+' in external reference to '+sym.Name);
  1341. exit;
  1342. end;
  1343. end;
  1344. if Fixup.TargetDisplacement<>0 then
  1345. begin
  1346. InputError('Unsupported nonzero target displacement '+IntToStr(Fixup.TargetDisplacement)+' in external reference to '+sym.Name);
  1347. exit;
  1348. end;
  1349. reloc:=TOmfRelocation.CreateSymbol(Fixup.LocationOffset,sym,RelocType);
  1350. objsec.ObjRelocations.Add(reloc);
  1351. end;
  1352. {todo: convert other fixup types as well }
  1353. Result:=True;
  1354. end;
  1355. constructor TOmfObjInput.create;
  1356. begin
  1357. inherited create;
  1358. cobjdata:=TOmfObjData;
  1359. FLNames:=TOmfOrderedNameCollection.Create;
  1360. FExtDefs:=TFPHashObjectList.Create;
  1361. FPubDefs:=TFPHashObjectList.Create;
  1362. FRawRecord:=TOmfRawRecord.Create;
  1363. CaseSensitive:=False;
  1364. end;
  1365. destructor TOmfObjInput.destroy;
  1366. begin
  1367. FRawRecord.Free;
  1368. FPubDefs.Free;
  1369. FExtDefs.Free;
  1370. FLNames.Free;
  1371. inherited destroy;
  1372. end;
  1373. class function TOmfObjInput.CanReadObjData(AReader: TObjectreader): boolean;
  1374. var
  1375. b: Byte;
  1376. begin
  1377. result:=false;
  1378. if AReader.Read(b,sizeof(b)) then
  1379. begin
  1380. if b=RT_THEADR then
  1381. { TODO: check additional fields }
  1382. result:=true;
  1383. end;
  1384. AReader.Seek(0);
  1385. end;
  1386. function TOmfObjInput.ReadObjData(AReader: TObjectreader; out objdata: TObjData): boolean;
  1387. begin
  1388. FReader:=AReader;
  1389. InputFileName:=AReader.FileName;
  1390. objdata:=CObjData.Create(InputFileName);
  1391. result:=false;
  1392. LNames.Clear;
  1393. ExtDefs.Clear;
  1394. FRawRecord.ReadFrom(FReader);
  1395. if not FRawRecord.VerifyChecksumByte then
  1396. begin
  1397. InputError('Invalid checksum in OMF record');
  1398. exit;
  1399. end;
  1400. if FRawRecord.RecordType<>RT_THEADR then
  1401. begin
  1402. InputError('Can''t read OMF header');
  1403. exit;
  1404. end;
  1405. repeat
  1406. FRawRecord.ReadFrom(FReader);
  1407. if not FRawRecord.VerifyChecksumByte then
  1408. begin
  1409. InputError('Invalid checksum in OMF record');
  1410. exit;
  1411. end;
  1412. case FRawRecord.RecordType of
  1413. RT_LNAMES:
  1414. if not ReadLNames(FRawRecord) then
  1415. exit;
  1416. RT_SEGDEF,RT_SEGDEF32:
  1417. if not ReadSegDef(FRawRecord,objdata) then
  1418. exit;
  1419. RT_GRPDEF:
  1420. if not ReadGrpDef(FRawRecord,objdata) then
  1421. exit;
  1422. RT_COMENT:
  1423. begin
  1424. {todo}
  1425. end;
  1426. RT_EXTDEF:
  1427. if not ReadExtDef(FRawRecord,objdata) then
  1428. exit;
  1429. RT_PUBDEF,RT_PUBDEF32:
  1430. if not ReadPubDef(FRawRecord,objdata) then
  1431. exit;
  1432. RT_LEDATA,RT_LEDATA32:
  1433. if not ReadLEDataAndFixups(FRawRecord,objdata) then
  1434. exit;
  1435. RT_LIDATA,RT_LIDATA32:
  1436. begin
  1437. InputError('LIDATA records are not supported');
  1438. exit;
  1439. end;
  1440. RT_FIXUPP,RT_FIXUPP32:
  1441. begin
  1442. InputError('FIXUPP record is invalid, because it does not follow a LEDATA or LIDATA record');
  1443. exit;
  1444. end;
  1445. RT_MODEND,RT_MODEND32:
  1446. if not ReadModEnd(FRawRecord,objdata) then
  1447. exit;
  1448. else
  1449. begin
  1450. InputError('Unsupported OMF record type $'+HexStr(FRawRecord.RecordType,2));
  1451. exit;
  1452. end;
  1453. end;
  1454. until FRawRecord.RecordType in [RT_MODEND,RT_MODEND32];
  1455. result:=true;
  1456. end;
  1457. {****************************************************************************
  1458. TMZExeHeader
  1459. ****************************************************************************}
  1460. procedure TMZExeHeader.SetHeaderSizeAlignment(AValue: Integer);
  1461. begin
  1462. if (AValue<16) or ((AValue mod 16) <> 0) then
  1463. Internalerror(2015060601);
  1464. FHeaderSizeAlignment:=AValue;
  1465. end;
  1466. constructor TMZExeHeader.Create;
  1467. begin
  1468. FHeaderSizeAlignment:=16;
  1469. end;
  1470. procedure TMZExeHeader.WriteTo(aWriter: TObjectWriter);
  1471. var
  1472. NumRelocs: Word;
  1473. HeaderSizeInBytes: DWord;
  1474. HeaderParagraphs: Word;
  1475. RelocTableOffset: Word;
  1476. BytesInLastBlock: Word;
  1477. BlocksInFile: Word;
  1478. HeaderBytes: array [0..$1B] of Byte;
  1479. RelocBytes: array [0..3] of Byte;
  1480. TotalExeSize: DWord;
  1481. i: Integer;
  1482. begin
  1483. NumRelocs:=Length(Relocations);
  1484. RelocTableOffset:=$1C+Length(ExtraHeaderData);
  1485. HeaderSizeInBytes:=Align(RelocTableOffset+4*NumRelocs,16);
  1486. HeaderParagraphs:=HeaderSizeInBytes div 16;
  1487. TotalExeSize:=HeaderSizeInBytes+LoadableImageSize;
  1488. BlocksInFile:=(TotalExeSize+511) div 512;
  1489. BytesInLastBlock:=TotalExeSize mod 512;
  1490. HeaderBytes[$00]:=$4D; { 'M' }
  1491. HeaderBytes[$01]:=$5A; { 'Z' }
  1492. HeaderBytes[$02]:=Byte(BytesInLastBlock);
  1493. HeaderBytes[$03]:=Byte(BytesInLastBlock shr 8);
  1494. HeaderBytes[$04]:=Byte(BlocksInFile);
  1495. HeaderBytes[$05]:=Byte(BlocksInFile shr 8);
  1496. HeaderBytes[$06]:=Byte(NumRelocs);
  1497. HeaderBytes[$07]:=Byte(NumRelocs shr 8);
  1498. HeaderBytes[$08]:=Byte(HeaderParagraphs);
  1499. HeaderBytes[$09]:=Byte(HeaderParagraphs shr 8);
  1500. HeaderBytes[$0A]:=Byte(MinExtraParagraphs);
  1501. HeaderBytes[$0B]:=Byte(MinExtraParagraphs shr 8);
  1502. HeaderBytes[$0C]:=Byte(MaxExtraParagraphs);
  1503. HeaderBytes[$0D]:=Byte(MaxExtraParagraphs shr 8);
  1504. HeaderBytes[$0E]:=Byte(InitialSS);
  1505. HeaderBytes[$0F]:=Byte(InitialSS shr 8);
  1506. HeaderBytes[$10]:=Byte(InitialSP);
  1507. HeaderBytes[$11]:=Byte(InitialSP shr 8);
  1508. HeaderBytes[$12]:=Byte(Checksum);
  1509. HeaderBytes[$13]:=Byte(Checksum shr 8);
  1510. HeaderBytes[$14]:=Byte(InitialIP);
  1511. HeaderBytes[$15]:=Byte(InitialIP shr 8);
  1512. HeaderBytes[$16]:=Byte(InitialCS);
  1513. HeaderBytes[$17]:=Byte(InitialCS shr 8);
  1514. HeaderBytes[$18]:=Byte(RelocTableOffset);
  1515. HeaderBytes[$19]:=Byte(RelocTableOffset shr 8);
  1516. HeaderBytes[$1A]:=Byte(OverlayNumber);
  1517. HeaderBytes[$1B]:=Byte(OverlayNumber shr 8);
  1518. aWriter.write(HeaderBytes[0],$1C);
  1519. aWriter.write(ExtraHeaderData[0],Length(ExtraHeaderData));
  1520. for i:=0 to NumRelocs-1 do
  1521. with Relocations[i] do
  1522. begin
  1523. RelocBytes[0]:=Byte(offset);
  1524. RelocBytes[1]:=Byte(offset shr 8);
  1525. RelocBytes[2]:=Byte(segment);
  1526. RelocBytes[3]:=Byte(segment shr 8);
  1527. aWriter.write(RelocBytes[0],4);
  1528. end;
  1529. { pad with zeros until the end of header (paragraph aligned) }
  1530. aWriter.WriteZeros(HeaderSizeInBytes-aWriter.Size);
  1531. end;
  1532. {****************************************************************************
  1533. TMZExeSection
  1534. ****************************************************************************}
  1535. procedure TMZExeSection.AddObjSection(objsec: TObjSection; ignoreprops: boolean);
  1536. begin
  1537. { allow mixing initialized and uninitialized data in the same section
  1538. => set ignoreprops=true }
  1539. inherited AddObjSection(objsec,true);
  1540. end;
  1541. {****************************************************************************
  1542. TMZExeOutput
  1543. ****************************************************************************}
  1544. function TMZExeOutput.writeData: boolean;
  1545. var
  1546. Header: TMZExeHeader;
  1547. begin
  1548. Result:=False;
  1549. Header:=TMZExeHeader.Create;
  1550. {todo: fill header data}
  1551. Header.WriteTo(FWriter);
  1552. Header.Free;
  1553. Result:=True;
  1554. end;
  1555. constructor TMZExeOutput.create;
  1556. begin
  1557. inherited create;
  1558. CExeSection:=TMZExeSection;
  1559. CObjData:=TOmfObjData;
  1560. { "640K ought to be enough for anybody" :) }
  1561. MaxMemPos:=$9FFFF;
  1562. end;
  1563. {****************************************************************************
  1564. TOmfAssembler
  1565. ****************************************************************************}
  1566. constructor TOmfAssembler.Create(smart:boolean);
  1567. begin
  1568. inherited Create(smart);
  1569. CObjOutput:=TOmfObjOutput;
  1570. CInternalAr:=TOmfLibObjectWriter;
  1571. end;
  1572. {*****************************************************************************
  1573. Initialize
  1574. *****************************************************************************}
  1575. {$ifdef i8086}
  1576. const
  1577. as_i8086_omf_info : tasminfo =
  1578. (
  1579. id : as_i8086_omf;
  1580. idtxt : 'OMF';
  1581. asmbin : '';
  1582. asmcmd : '';
  1583. supported_targets : [system_i8086_msdos];
  1584. flags : [af_outputbinary,af_no_debug];
  1585. labelprefix : '..@';
  1586. comment : '; ';
  1587. dollarsign: '$';
  1588. );
  1589. {$endif i8086}
  1590. initialization
  1591. {$ifdef i8086}
  1592. RegisterAssembler(as_i8086_omf_info,TOmfAssembler);
  1593. {$endif i8086}
  1594. end.