* refactored omf library writing, so that the whole library is written in

TOmfLibObjectWrite.WriteLib, after determining the page size (currently still
  fixed to 512 bytes). Prerequisite for OMF lib page size optimization.

git-svn-id: trunk@39194 -
This commit is contained in:
nickysn 2018-06-07 22:11:03 +00:00
parent 00c6826896
commit 345713c1fa

View File

@ -69,7 +69,7 @@ type
FPageSize: Integer; FPageSize: Integer;
FLibName: string; FLibName: string;
FLibData: TDynamicArray; FLibData: TDynamicArray;
FObjStartPage: Word; FFooterPos: LongWord;
FDictionary: TFPHashObjectList; FDictionary: TFPHashObjectList;
FObjectModules: TFPObjectList; FObjectModules: TFPObjectList;
FCurrentModule: TOmfLibObjectModule; FCurrentModule: TOmfLibObjectModule;
@ -77,6 +77,7 @@ type
procedure WriteHeader(DictStart: DWord; DictBlocks: Word); procedure WriteHeader(DictStart: DWord; DictBlocks: Word);
procedure WriteFooter; procedure WriteFooter;
function TryPageSize(aPageSize: Integer): Boolean;
procedure WriteLib; procedure WriteLib;
function WriteDictionary: Word; function WriteDictionary: Word;
function TryWriteDictionaryWithSize(nblocks: Word): Boolean; function TryWriteDictionaryWithSize(nblocks: Word): Boolean;
@ -131,7 +132,7 @@ implementation
uses uses
SysUtils, SysUtils,
cstreams, cstreams,cutils,
verbose, verbose,
omfbase; omfbase;
@ -195,8 +196,6 @@ implementation
FDictionary:=TFPHashObjectList.Create; FDictionary:=TFPHashObjectList.Create;
FObjectModules:=TFPObjectList.Create(True); FObjectModules:=TFPObjectList.Create(True);
FCurrentModule:=nil; FCurrentModule:=nil;
{ header is at page 0, so first module starts at page 1 }
FObjStartPage:=1;
end; end;
@ -215,7 +214,6 @@ implementation
begin begin
FCurrentModule:=TOmfLibObjectModule.Create(fn); FCurrentModule:=TOmfLibObjectModule.Create(fn);
FCurrentModuleIndex:=FObjectModules.Add(FCurrentModule); FCurrentModuleIndex:=FObjectModules.Add(FCurrentModule);
FCurrentModule.PageNum:=FObjStartPage;
createfile:=true; createfile:=true;
fobjsize:=0; fobjsize:=0;
end; end;
@ -226,7 +224,6 @@ implementation
RawRec: TOmfRawRecord; RawRec: TOmfRawRecord;
ObjHeader: TOmfRecord_THEADR; ObjHeader: TOmfRecord_THEADR;
begin begin
FLibData.seek(FObjStartPage*FPageSize);
FCurrentModule.ObjData.seek(0); FCurrentModule.ObjData.seek(0);
RawRec:=TOmfRawRecord.Create; RawRec:=TOmfRawRecord.Create;
repeat repeat
@ -239,11 +236,8 @@ implementation
TOmfLibDictionaryEntry.Create(FDictionary,ModName2DictEntry(ObjHeader.ModuleName),FCurrentModuleIndex); TOmfLibDictionaryEntry.Create(FDictionary,ModName2DictEntry(ObjHeader.ModuleName),FCurrentModuleIndex);
ObjHeader.Free; ObjHeader.Free;
end; end;
RawRec.WriteTo(FLibData);
until RawRec.RecordType in [RT_MODEND,RT_MODEND32]; until RawRec.RecordType in [RT_MODEND,RT_MODEND32];
RawRec.Free; RawRec.Free;
{ calculate start page of next module }
FObjStartPage:=(FLibData.Pos+FPageSize-1) div FPageSize;
fobjsize:=0; fobjsize:=0;
end; end;
@ -287,7 +281,7 @@ implementation
Footer: TOmfRecord_LIBEND; Footer: TOmfRecord_LIBEND;
RawRec: TOmfRawRecord; RawRec: TOmfRawRecord;
begin begin
FLibData.seek(FObjStartPage*FPageSize); FLibData.seek(FFooterPos);
Footer:=TOmfRecord_LIBEND.Create; Footer:=TOmfRecord_LIBEND.Create;
Footer.CalculatePaddingBytes(FLibData.Pos); Footer.CalculatePaddingBytes(FLibData.Pos);
RawRec:=TOmfRawRecord.Create; RawRec:=TOmfRawRecord.Create;
@ -297,18 +291,60 @@ implementation
RawRec.Free; RawRec.Free;
end; end;
function TOmfLibObjectWriter.TryPageSize(aPageSize: Integer): Boolean;
var
I: Integer;
CurrentPage: Integer;
CurrentPos: LongWord;
pow: longint;
begin
if not IsPowerOf2(aPageSize,pow) then
internalerror(2018060701);
if (pow<4) or (pow>15) then
internalerror(2018060702);
FPageSize:=aPageSize;
{ header is at page 0, so first module starts at page 1 }
CurrentPage:=1;
for I:=0 to FObjectModules.Count-1 do
with TOmfLibObjectModule(FObjectModules[I]) do
begin
if CurrentPage>high(word) then
exit(False);
PageNum:=CurrentPage;
{ calculate next page }
CurrentPos:=CurrentPage*FPageSize+ObjData.Size;
CurrentPage:=(CurrentPos+FPageSize-1) div FPageSize;
end;
FFooterPos:=CurrentPage*FPageSize;
Result:=True;
end;
procedure TOmfLibObjectWriter.WriteLib; procedure TOmfLibObjectWriter.WriteLib;
var var
libf: TCCustomFileStream; libf: TCCustomFileStream;
DictStart: LongWord; DictStart, bytes: LongWord;
DictBlocks: Word; DictBlocks: Word;
I: Integer;
buf: array [0..1023] of Byte;
begin begin
TryPageSize(512);
libf:=CFileStreamClass.Create(FLibName,fmCreate); libf:=CFileStreamClass.Create(FLibName,fmCreate);
if CStreamError<>0 then if CStreamError<>0 then
begin begin
Message1(exec_e_cant_create_archivefile,FLibName); Message1(exec_e_cant_create_archivefile,FLibName);
exit; exit;
end; end;
for I:=0 to FObjectModules.Count-1 do
with TOmfLibObjectModule(FObjectModules[I]) do
begin
FLibData.seek(PageNum*FPageSize);
ObjData.seek(0);
while ObjData.Pos<ObjData.size do
begin
bytes:=ObjData.read(buf,Min(SizeOf(buf),ObjData.size-ObjData.Pos));
FLibData.write(buf,bytes);
end;
end;
WriteFooter; WriteFooter;
DictStart:=FLibData.Pos; DictStart:=FLibData.Pos;
DictBlocks:=WriteDictionary; DictBlocks:=WriteDictionary;