+ write the entry table to the NewExe file

git-svn-id: trunk@42628 -
This commit is contained in:
nickysn 2019-08-09 23:50:59 +00:00
parent 2d77a2c104
commit 9f0f31a1e9

View File

@ -584,10 +584,12 @@ interface
FFlags: TNewExeEntryPointFlags;
FSegment: Byte;
FOffset: Word;
function GetFlagsByte: Byte;
public
property Flags: TNewExeEntryPointFlags read FFlags write FFlags;
property Segment: Byte read FSegment write FSegment;
property Offset: Word read FOffset write FOffset;
property FlagsByte: Byte read GetFlagsByte;
end;
{ TNewExeEntryTable }
@ -600,6 +602,8 @@ interface
function GetItems(i: Integer): TNewExeEntryPoint;
function GetSize: QWord;
procedure SetItems(i: Integer; AValue: TNewExeEntryPoint);
function CanBeInSameBundle(i,j:Integer):Boolean;
function BundleSize(StartingElement:Integer): Byte;
public
destructor Destroy;override;
@ -3982,14 +3986,47 @@ cleanup:
end;
end;
{****************************************************************************
TNewExeEntryPoint
****************************************************************************}
function TNewExeEntryPoint.GetFlagsByte: Byte;
begin
Result:=0;
if neepfExported in Flags then
Result:=Result or 1;
if neepfSingleData in Flags then
Result:=Result or 2;
end;
{****************************************************************************
TNewExeEntryTable
****************************************************************************}
function TNewExeEntryTable.GetSize: QWord;
var
CurBundleStart, i: Integer;
CurBundleSize: Byte;
cp: TNewExeEntryPoint;
begin
{ todo: implement }
Result:=0;
CurBundleStart:=1;
repeat
CurBundleSize:=BundleSize(CurBundleStart);
Inc(Result,2);
if CurBundleSize>0 then
begin
if Items[CurBundleStart]=nil then
{ a bundle of null entries }
else if neepfMovableSegment in Items[CurBundleStart].Flags then
{ a bundle of movable segment records }
Inc(Result,6*CurBundleSize)
else
{ a bundle of fixed segment records }
Inc(Result,3*CurBundleSize);
end;
Inc(CurBundleStart,CurBundleSize);
until CurBundleSize=0;
end;
procedure TNewExeEntryTable.SetItems(i: Integer; AValue: TNewExeEntryPoint);
@ -3999,6 +4036,30 @@ cleanup:
FItems[i-1]:=AValue;
end;
function TNewExeEntryTable.CanBeInSameBundle(i, j: Integer): Boolean;
begin
if (Items[i]=nil) or (Items[j]=nil) then
Result:=(Items[i]=nil) and (Items[j]=nil)
else if not (neepfMovableSegment in Items[i].Flags) and
not (neepfMovableSegment in Items[j].Flags) then
Result:=Items[i].Segment=Items[j].Segment
else
Result:=(neepfMovableSegment in Items[i].Flags)=
(neepfMovableSegment in Items[j].Flags);
end;
function TNewExeEntryTable.BundleSize(StartingElement:Integer): Byte;
begin
if StartingElement>Count then
Result:=0
else
begin
Result:=1;
while (Result<255) and ((StartingElement+Result)<=Count) and CanBeInSameBundle(StartingElement,StartingElement+Result) do
Inc(Result);
end;
end;
function TNewExeEntryTable.GetCount: Word;
begin
Result:=Length(FItems);
@ -4021,8 +4082,63 @@ cleanup:
end;
procedure TNewExeEntryTable.WriteTo(aWriter: TObjectWriter);
var
CurBundleStart, i: Integer;
CurBundleSize: Byte;
buf: array [0..5] of Byte;
cp: TNewExeEntryPoint;
begin
{ todo: implement }
CurBundleStart:=1;
repeat
CurBundleSize:=BundleSize(CurBundleStart);
aWriter.write(CurBundleSize,1);
if CurBundleSize>0 then
begin
if Items[CurBundleStart]=nil then
begin
{ a bundle of null entries }
buf[0]:=0;
aWriter.write(buf[0],1);
end
else if neepfMovableSegment in Items[CurBundleStart].Flags then
begin
{ a bundle of movable segment records }
buf[0]:=$ff;
aWriter.write(buf[0],1);
for i:=CurBundleStart to CurBundleStart+CurBundleSize-1 do
begin
cp:=Items[i];
buf[0]:=cp.FlagsByte;
buf[1]:=$CD; { INT 3Fh instruction }
buf[2]:=$3F;
buf[3]:=Byte(cp.Segment);
buf[4]:=Byte(cp.Offset);
buf[5]:=Byte(cp.Offset shr 8);
aWriter.write(buf[0],6);
end;
end
else
begin
{ a bundle of fixed segment records }
buf[0]:=Items[CurBundleStart].Segment;
aWriter.write(buf[0],1);
for i:=CurBundleStart to CurBundleStart+CurBundleSize-1 do
begin
cp:=Items[i];
buf[0]:=cp.FlagsByte;
buf[1]:=Byte(cp.Offset);
buf[2]:=Byte(cp.Offset shr 8);
aWriter.write(buf[0],3);
end;
end;
end;
Inc(CurBundleStart,CurBundleSize);
until CurBundleSize=0;
{ finish the end marker - a null bundle of 0 entries - must be 2 zero
bytes. The first one was already written by the loop, time to add the
second one. }
buf[0]:=0;
aWriter.write(buf[0],1);
end;
procedure TNewExeEntryTable.GrowTo(aNewCount: Word);