123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- {
- Copyright (c) 2015 by Nikolay Nikolov
- Contains the binary Relocatable Object Module Format (OMF) reader and writer
- 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 ogomf;
- {$i fpcdefs.inc}
- interface
- uses
- { common }
- cclasses,globtype,
- { target }
- systems,
- { assembler }
- cpuinfo,cpubase,aasmbase,assemble,link,
- { OMF definitions }
- omfbase,
- { output }
- ogbase,
- owbase;
- type
- TOmfObjData = class(TObjData)
- public
- function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
- procedure writeReloc(Data:aint;len:aword;p:TObjSymbol;Reloctype:TObjRelocationType);override;
- end;
- { TOmfObjOutput }
- TOmfObjOutput = class(tObjOutput)
- private
- FLNames: TOmfOrderedNameCollection;
- FSegments: TFPHashObjectList;
- FGroups: TFPHashObjectList;
- procedure AddSegment(const name,segclass: string;
- Alignment: TOmfSegmentAlignment; Combination: TOmfSegmentCombination;
- Use: TOmfSegmentUse);
- procedure AddGroup(const groupname: string; seglist: array of const);
- property LNames: TOmfOrderedNameCollection read FLNames;
- property Segments: TFPHashObjectList read FSegments;
- property Groups: TFPHashObjectList read FGroups;
- protected
- function writeData(Data:TObjData):boolean;override;
- public
- constructor create(AWriter:TObjectWriter);override;
- destructor Destroy;override;
- end;
- TOmfAssembler = class(tinternalassembler)
- constructor create(smart:boolean);override;
- end;
- implementation
- uses
- SysUtils,
- cutils,verbose,globals,
- fmodule,aasmtai,aasmdata,
- ogmap,
- version
- ;
- {****************************************************************************
- TOmfObjData
- ****************************************************************************}
- function TOmfObjData.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
- begin
- result:=aname;
- end;
- procedure TOmfObjData.writeReloc(Data:aint;len:aword;p:TObjSymbol;Reloctype:TObjRelocationType);
- begin
- end;
- {****************************************************************************
- TOmfObjOutput
- ****************************************************************************}
- procedure TOmfObjOutput.AddSegment(const name, segclass: string;
- Alignment: TOmfSegmentAlignment; Combination: TOmfSegmentCombination;
- Use: TOmfSegmentUse);
- var
- s: TOmfRecord_SEGDEF;
- begin
- s:=TOmfRecord_SEGDEF.Create;
- Segments.Add(name,s);
- s.SegmentNameIndex:=LNames.Add(name);
- s.ClassNameIndex:=LNames.Add(segclass);
- s.OverlayNameIndex:=1;
- s.Alignment:=Alignment;
- s.Combination:=Combination;
- s.Use:=Use;
- end;
- procedure TOmfObjOutput.AddGroup(const groupname: string; seglist: array of const);
- var
- g: TOmfRecord_GRPDEF;
- I: Integer;
- SegListStr: TSegmentList;
- begin
- g:=TOmfRecord_GRPDEF.Create;
- Groups.Add(groupname,g);
- g.GroupNameIndex:=LNames.Add(groupname);
- SetLength(SegListStr,Length(seglist));
- for I:=0 to High(seglist) do
- begin
- case seglist[I].VType of
- vtString:
- SegListStr[I]:=Segments.FindIndexOf(seglist[I].VString^);
- vtAnsiString:
- SegListStr[I]:=Segments.FindIndexOf(AnsiString(seglist[I].VAnsiString));
- vtWideString:
- SegListStr[I]:=Segments.FindIndexOf(WideString(seglist[I].VWideString));
- vtUnicodeString:
- SegListStr[I]:=Segments.FindIndexOf(UnicodeString(seglist[I].VUnicodeString));
- else
- internalerror(2015040402);
- end;
- end;
- g.SegmentList:=SegListStr;
- end;
- function TOmfObjOutput.writeData(Data:TObjData):boolean;
- var
- RawRecord: TOmfRawRecord;
- Header: TOmfRecord_THEADR;
- Translator_COMENT: TOmfRecord_COMENT;
- LinkPassSeparator_COMENT: TOmfRecord_COMENT;
- LNamesRec: TOmfRecord_LNAMES;
- I: Integer;
- SegDef: TOmfRecord_SEGDEF;
- GrpDef: TOmfRecord_GRPDEF;
- begin
- { write header record }
- RawRecord:=TOmfRawRecord.Create;
- Header:=TOmfRecord_THEADR.Create;
- Header.ModuleName:=Data.Name;
- Header.EncodeTo(RawRecord);
- RawRecord.WriteTo(FWriter);
- Header.Free;
- { write translator COMENT header }
- Translator_COMENT:=TOmfRecord_COMENT.Create;
- Translator_COMENT.CommentClass:=CC_Translator;
- Translator_COMENT.CommentString:='FPC '+full_version_string+
- ' ['+date_string+'] for '+target_cpu_string+' - '+target_info.shortname;
- Translator_COMENT.EncodeTo(RawRecord);
- RawRecord.WriteTo(FWriter);
- Translator_COMENT.Free;
- LNames.Clear;
- LNames.Add(''); { insert an empty string, which has index 1 }
- if not (cs_huge_code in current_settings.moduleswitches) then
- AddSegment({CodeSectionName(current_module.modulename^)}'text','code',saRelocatableByteAligned,scPublic,suUse16);
- AddSegment('rodata','data',saRelocatableByteAligned,scPublic,suUse16);
- AddSegment('data','data',saRelocatableWordAligned,scPublic,suUse16);
- AddSegment('fpc','data',saRelocatableByteAligned,scPublic,suUse16);
- AddSegment('bss','bss',saRelocatableByteAligned,scPublic,suUse16);
- AddSegment('stack','stack',saRelocatableParaAligned,scStack,suUse16);
- AddSegment('heap','heap',saRelocatableParaAligned,scPublic,suUse16);
- if current_settings.x86memorymodel=mm_tiny then
- AddGroup('dgroup',['text','rodata','data','fpc','bss','heap'])
- else if current_settings.x86memorymodel in x86_near_data_models then
- AddGroup('dgroup',['rodata','data','fpc','bss','stack','heap'])
- else
- AddGroup('dgroup',['rodata','data','fpc','bss']);
- { write LNAMES record(s) }
- LNamesRec:=TOmfRecord_LNAMES.Create;
- LNamesRec.Names:=LNames;
- while LNamesRec.NextIndex<=LNames.Count do
- begin
- LNamesRec.EncodeTo(RawRecord);
- RawRecord.WriteTo(FWriter);
- end;
- LNamesRec.Free;
- { write SEGDEF record(s) }
- for I:=1 to Segments.Count-1 do
- begin
- SegDef:=TOmfRecord_SEGDEF(Segments[I]);
- SegDef.EncodeTo(RawRecord);
- RawRecord.WriteTo(FWriter);
- end;
- { write GRPDEF record(s) }
- for I:=1 to Groups.Count-1 do
- begin
- GrpDef:=TOmfRecord_GRPDEF(Groups[I]);
- GrpDef.EncodeTo(RawRecord);
- RawRecord.WriteTo(FWriter);
- end;
- { write link pass separator }
- LinkPassSeparator_COMENT:=TOmfRecord_COMENT.Create;
- LinkPassSeparator_COMENT.CommentClass:=CC_LinkPassSeparator;
- LinkPassSeparator_COMENT.CommentString:=#1;
- LinkPassSeparator_COMENT.NoList:=True;
- LinkPassSeparator_COMENT.EncodeTo(RawRecord);
- RawRecord.WriteTo(FWriter);
- LinkPassSeparator_COMENT.Free;
- RawRecord.Free;
- result:=true;
- end;
- constructor TOmfObjOutput.create(AWriter:TObjectWriter);
- begin
- inherited create(AWriter);
- cobjdata:=TOmfObjData;
- FLNames:=TOmfOrderedNameCollection.Create;
- FSegments:=TFPHashObjectList.Create;
- FSegments.Add('',nil);
- FGroups:=TFPHashObjectList.Create;
- FGroups.Add('',nil);
- end;
- destructor TOmfObjOutput.Destroy;
- begin
- FGroups.Free;
- FSegments.Free;
- FLNames.Free;
- inherited Destroy;
- end;
- {****************************************************************************
- TOmfAssembler
- ****************************************************************************}
- constructor TOmfAssembler.Create(smart:boolean);
- begin
- inherited Create(smart);
- CObjOutput:=TOmfObjOutput;
- end;
- {*****************************************************************************
- Initialize
- *****************************************************************************}
- {$ifdef i8086}
- const
- as_i8086_omf_info : tasminfo =
- (
- id : as_i8086_omf;
- idtxt : 'OMF';
- asmbin : '';
- asmcmd : '';
- supported_targets : [system_i8086_msdos];
- flags : [af_outputbinary,af_needar,af_no_debug];
- labelprefix : '..@';
- comment : '; ';
- dollarsign: '$';
- );
- {$endif i8086}
- initialization
- {$ifdef i8086}
- RegisterAssembler(as_i8086_omf_info,TOmfAssembler);
- {$endif i8086}
- end.
|