|
@@ -326,6 +326,7 @@ interface
|
|
|
|
|
|
const
|
|
const
|
|
NewExeHeaderSize = $40;
|
|
NewExeHeaderSize = $40;
|
|
|
|
+ NewExeSegmentHeaderSize = 8;
|
|
|
|
|
|
type
|
|
type
|
|
TNewExeHeaderFlag = (
|
|
TNewExeHeaderFlag = (
|
|
@@ -470,6 +471,18 @@ interface
|
|
property ExpectedWindowsVersion: Word read FExpectedWindowsVersion write FExpectedWindowsVersion;
|
|
property ExpectedWindowsVersion: Word read FExpectedWindowsVersion write FExpectedWindowsVersion;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ { TNewExeResourceTable }
|
|
|
|
+
|
|
|
|
+ TNewExeResourceTable = class
|
|
|
|
+ private
|
|
|
|
+ FResourceDataAlignmentShiftCount: Word;
|
|
|
|
+ public
|
|
|
|
+ constructor Create;
|
|
|
|
+ procedure WriteTo(aWriter: TObjectWriter);
|
|
|
|
+
|
|
|
|
+ property ResourceDataAlignmentShiftCount: Word read FResourceDataAlignmentShiftCount write FResourceDataAlignmentShiftCount;
|
|
|
|
+ end;
|
|
|
|
+
|
|
{ These are fake "meta sections" used by the linker script. The actual
|
|
{ These are fake "meta sections" used by the linker script. The actual
|
|
NewExe sections are segments, limited to 64kb, which means there can be
|
|
NewExe sections are segments, limited to 64kb, which means there can be
|
|
multiple code segments, etc. These are created manually as object
|
|
multiple code segments, etc. These are created manually as object
|
|
@@ -524,12 +537,14 @@ interface
|
|
FHeader: TNewExeHeader;
|
|
FHeader: TNewExeHeader;
|
|
FImports: TFPHashObjectList;
|
|
FImports: TFPHashObjectList;
|
|
FCurrExeMetaSec: TNewExeMetaSection;
|
|
FCurrExeMetaSec: TNewExeMetaSection;
|
|
|
|
+ FResourceTable: TNewExeResourceTable;
|
|
procedure AddImportSymbol(const libname,symname,symmangledname:TCmdStr;OrdNr: longint;isvar:boolean);
|
|
procedure AddImportSymbol(const libname,symname,symmangledname:TCmdStr;OrdNr: longint;isvar:boolean);
|
|
procedure AddImportLibrariesExtractedFromObjectModules;
|
|
procedure AddImportLibrariesExtractedFromObjectModules;
|
|
procedure AddNewExeSection;
|
|
procedure AddNewExeSection;
|
|
function WriteNewExe:boolean;
|
|
function WriteNewExe:boolean;
|
|
property Header: TNewExeHeader read FHeader;
|
|
property Header: TNewExeHeader read FHeader;
|
|
property CurrExeMetaSec: TNewExeMetaSection read FCurrExeMetaSec write FCurrExeMetaSec;
|
|
property CurrExeMetaSec: TNewExeMetaSection read FCurrExeMetaSec write FCurrExeMetaSec;
|
|
|
|
+ property ResourceTable: TNewExeResourceTable read FResourceTable;
|
|
protected
|
|
protected
|
|
procedure DoRelocationFixup(objsec:TObjSection);override;
|
|
procedure DoRelocationFixup(objsec:TObjSection);override;
|
|
procedure Order_ObjSectionList(ObjSectionList : TFPObjectList;const aPattern:string);override;
|
|
procedure Order_ObjSectionList(ObjSectionList : TFPObjectList;const aPattern:string);override;
|
|
@@ -3602,6 +3617,46 @@ cleanup:
|
|
aWriter.write(HeaderBytes[0],$40);
|
|
aWriter.write(HeaderBytes[0],$40);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+{****************************************************************************
|
|
|
|
+ TNewExeResourceTable
|
|
|
|
+****************************************************************************}
|
|
|
|
+
|
|
|
|
+ constructor TNewExeResourceTable.Create;
|
|
|
|
+ begin
|
|
|
|
+ ResourceDataAlignmentShiftCount:=8;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ procedure TNewExeResourceTable.WriteTo(aWriter: TObjectWriter);
|
|
|
|
+
|
|
|
|
+ procedure WriteAlignShift;
|
|
|
|
+ var
|
|
|
|
+ AlignShiftBytes: array [0..1] of Byte;
|
|
|
|
+ begin
|
|
|
|
+ AlignShiftBytes[0]:=Byte(ResourceDataAlignmentShiftCount);
|
|
|
|
+ AlignShiftBytes[1]:=Byte(ResourceDataAlignmentShiftCount shr 8);
|
|
|
|
+ aWriter.write(AlignShiftBytes[0],2);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ procedure WriteEndTypes;
|
|
|
|
+ const
|
|
|
|
+ EndTypesBytes: array [0..1] of Byte = (0, 0);
|
|
|
|
+ begin
|
|
|
|
+ aWriter.write(EndTypesBytes[0],2);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ procedure WriteEndNames;
|
|
|
|
+ const
|
|
|
|
+ EndNames: Byte = 0;
|
|
|
|
+ begin
|
|
|
|
+ aWriter.write(EndNames,1);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ begin
|
|
|
|
+ WriteAlignShift;
|
|
|
|
+ WriteEndTypes;
|
|
|
|
+ WriteEndNames;
|
|
|
|
+ end;
|
|
|
|
+
|
|
{****************************************************************************
|
|
{****************************************************************************
|
|
TNewExeSection
|
|
TNewExeSection
|
|
****************************************************************************}
|
|
****************************************************************************}
|
|
@@ -3752,12 +3807,15 @@ cleanup:
|
|
|
|
|
|
Header.SegmentTableStart:=NewExeHeaderSize;
|
|
Header.SegmentTableStart:=NewExeHeaderSize;
|
|
Header.SegmentTableEntriesCount:=ExeSectionList.Count;
|
|
Header.SegmentTableEntriesCount:=ExeSectionList.Count;
|
|
|
|
+ Header.ResourceTableStart:=Header.SegmentTableStart+NewExeSegmentHeaderSize*Header.SegmentTableEntriesCount;
|
|
|
|
|
|
Header.WriteTo(FWriter);
|
|
Header.WriteTo(FWriter);
|
|
|
|
|
|
for i:=0 to ExeSectionList.Count-1 do
|
|
for i:=0 to ExeSectionList.Count-1 do
|
|
TNewExeSection(ExeSectionList[i]).WriteHeaderTo(FWriter);
|
|
TNewExeSection(ExeSectionList[i]).WriteHeaderTo(FWriter);
|
|
|
|
|
|
|
|
+ ResourceTable.WriteTo(FWriter);
|
|
|
|
+
|
|
{ todo: write the rest of the file as well }
|
|
{ todo: write the rest of the file as well }
|
|
|
|
|
|
Result:=True;
|
|
Result:=True;
|
|
@@ -3798,10 +3856,12 @@ cleanup:
|
|
FHeader:=TNewExeHeader.Create;
|
|
FHeader:=TNewExeHeader.Create;
|
|
MaxMemPos:=$FFFFFFFF;
|
|
MaxMemPos:=$FFFFFFFF;
|
|
CurrExeMetaSec:=nemsNone;
|
|
CurrExeMetaSec:=nemsNone;
|
|
|
|
+ FResourceTable:=TNewExeResourceTable.Create;
|
|
end;
|
|
end;
|
|
|
|
|
|
destructor TNewExeOutput.destroy;
|
|
destructor TNewExeOutput.destroy;
|
|
begin
|
|
begin
|
|
|
|
+ FResourceTable.Free;
|
|
FHeader.Free;
|
|
FHeader.Free;
|
|
inherited destroy;
|
|
inherited destroy;
|
|
end;
|
|
end;
|