From 318874837fdc7e81b7d3c77c683e1399adf85194 Mon Sep 17 00:00:00 2001 From: nickysn Date: Sun, 7 Jun 2015 14:31:02 +0000 Subject: [PATCH] + implemented 16-bit dos MZ exe header writer git-svn-id: trunk@31002 - --- compiler/ogomf.pas | 138 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/compiler/ogomf.pas b/compiler/ogomf.pas index 6e6a78649c..d7663036bc 100644 --- a/compiler/ogomf.pas +++ b/compiler/ogomf.pas @@ -140,9 +140,55 @@ interface function ReadObjData(AReader:TObjectreader;out objdata:TObjData):boolean;override; end; + { TMZExeRelocation } + + TMZExeRelocation = record + offset: Word; + segment: Word; + end; + TMZExeRelocations = array of TMZExeRelocation; + TMZExeExtraHeaderData = array of Byte; + + { TMZExeHeader } + + TMZExeHeader = class + private + FChecksum: Word; + FExtraHeaderData: TMZExeExtraHeaderData; + FHeaderSizeAlignment: Integer; + FInitialCS: Word; + FInitialIP: Word; + FInitialSP: Word; + FInitialSS: Word; + FLoadableImageSize: DWord; + FMaxExtraParagraphs: Word; + FMinExtraParagraphs: Word; + FOverlayNumber: Word; + FRelocations: TMZExeRelocations; + procedure SetHeaderSizeAlignment(AValue: Integer); + public + constructor Create; + procedure WriteTo(aWriter: TObjectWriter); + property HeaderSizeAlignment: Integer read FHeaderSizeAlignment write SetHeaderSizeAlignment; {default=16, must be multiple of 16} + property Relocations: TMZExeRelocations read FRelocations write FRelocations; + property ExtraHeaderData: TMZExeExtraHeaderData read FExtraHeaderData write FExtraHeaderData; + property LoadableImageSize: DWord read FLoadableImageSize write FLoadableImageSize; + property MinExtraParagraphs: Word read FMinExtraParagraphs write FMinExtraParagraphs; + property MaxExtraParagraphs: Word read FMaxExtraParagraphs write FMaxExtraParagraphs; + property InitialSS: Word read FInitialSS write FInitialSS; + property InitialSP: Word read FInitialSP write FInitialSP; + property Checksum: Word read FChecksum write FChecksum; + property InitialIP: Word read FInitialIP write FInitialIP; + property InitialCS: Word read FInitialCS write FInitialCS; + property OverlayNumber: Word read FOverlayNumber write FOverlayNumber; + end; + { TMZExeOutput } TMZExeOutput = class(TExeOutput) + protected + function writeData:boolean;override; + public constructor create;override; end; @@ -1213,10 +1259,102 @@ implementation until FRawRecord.RecordType in [RT_MODEND,RT_MODEND32]; end; +{**************************************************************************** + TMZExeHeader +****************************************************************************} + + procedure TMZExeHeader.SetHeaderSizeAlignment(AValue: Integer); + begin + if (AValue<16) or ((AValue mod 16) <> 0) then + Internalerror(2015060601); + FHeaderSizeAlignment:=AValue; + end; + + constructor TMZExeHeader.Create; + begin + FHeaderSizeAlignment:=16; + end; + + procedure TMZExeHeader.WriteTo(aWriter: TObjectWriter); + var + NumRelocs: Word; + HeaderSizeInBytes: DWord; + HeaderParagraphs: Word; + RelocTableOffset: Word; + BytesInLastBlock: Word; + BlocksInFile: Word; + HeaderBytes: array [0..$1B] of Byte; + RelocBytes: array [0..3] of Byte; + TotalExeSize: DWord; + i: Integer; + begin + NumRelocs:=Length(Relocations); + RelocTableOffset:=$1C+Length(ExtraHeaderData); + HeaderSizeInBytes:=Align(RelocTableOffset+4*NumRelocs,16); + HeaderParagraphs:=HeaderSizeInBytes div 16; + TotalExeSize:=HeaderSizeInBytes+LoadableImageSize; + BlocksInFile:=(TotalExeSize+511) div 512; + BytesInLastBlock:=TotalExeSize mod 512; + + HeaderBytes[$00]:=$4D; { 'M' } + HeaderBytes[$01]:=$5A; { 'Z' } + HeaderBytes[$02]:=Byte(BytesInLastBlock); + HeaderBytes[$03]:=Byte(BytesInLastBlock shr 8); + HeaderBytes[$04]:=Byte(BlocksInFile); + HeaderBytes[$05]:=Byte(BlocksInFile shr 8); + HeaderBytes[$06]:=Byte(NumRelocs); + HeaderBytes[$07]:=Byte(NumRelocs shr 8); + HeaderBytes[$08]:=Byte(HeaderParagraphs); + HeaderBytes[$09]:=Byte(HeaderParagraphs shr 8); + HeaderBytes[$0A]:=Byte(MinExtraParagraphs); + HeaderBytes[$0B]:=Byte(MinExtraParagraphs shr 8); + HeaderBytes[$0C]:=Byte(MaxExtraParagraphs); + HeaderBytes[$0D]:=Byte(MaxExtraParagraphs shr 8); + HeaderBytes[$0E]:=Byte(InitialSS); + HeaderBytes[$0F]:=Byte(InitialSS shr 8); + HeaderBytes[$10]:=Byte(InitialSP); + HeaderBytes[$11]:=Byte(InitialSP shr 8); + HeaderBytes[$12]:=Byte(Checksum); + HeaderBytes[$13]:=Byte(Checksum shr 8); + HeaderBytes[$14]:=Byte(InitialIP); + HeaderBytes[$15]:=Byte(InitialIP shr 8); + HeaderBytes[$16]:=Byte(InitialCS); + HeaderBytes[$17]:=Byte(InitialCS shr 8); + HeaderBytes[$18]:=Byte(RelocTableOffset); + HeaderBytes[$19]:=Byte(RelocTableOffset shr 8); + HeaderBytes[$1A]:=Byte(OverlayNumber); + HeaderBytes[$1B]:=Byte(OverlayNumber shr 8); + aWriter.write(HeaderBytes[0],$1C); + aWriter.write(ExtraHeaderData[0],Length(ExtraHeaderData)); + for i:=0 to NumRelocs-1 do + with Relocations[i] do + begin + RelocBytes[0]:=Byte(offset); + RelocBytes[1]:=Byte(offset shr 8); + RelocBytes[2]:=Byte(segment); + RelocBytes[3]:=Byte(segment shr 8); + aWriter.write(RelocBytes[0],4); + end; + { pad with zeros until the end of header (paragraph aligned) } + aWriter.WriteZeros(HeaderSizeInBytes-aWriter.Size); + end; + {**************************************************************************** TMZExeOutput ****************************************************************************} + function TMZExeOutput.writeData: boolean; + var + Header: TMZExeHeader; + begin + Result:=False; + Header:=TMZExeHeader.Create; + {todo: fill header data} + Header.WriteTo(FWriter); + Header.Free; + Result:=True; + end; + constructor TMZExeOutput.create; begin inherited create;