mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-06 14:50:17 +02:00
+ write the entry table to the NewExe file
git-svn-id: trunk@42628 -
This commit is contained in:
parent
2d77a2c104
commit
9f0f31a1e9
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user