* create NewExe sections, corresponding to 64kb segments

git-svn-id: trunk@42561 -
This commit is contained in:
nickysn 2019-08-02 14:20:02 +00:00
parent 6952ab5baf
commit c32ddf42eb

View File

@ -466,9 +466,43 @@ interface
property ExpectedWindowsVersion: Word read FExpectedWindowsVersion write FExpectedWindowsVersion;
end;
{ These are fake "meta sections" used by the linker script. The actual
NewExe sections are segments, limited to 64kb, which means there can be
multiple code segments, etc. These are created manually as object
sections are added. If they fit the current segment, without exceeding
64kb, they are added to the current segment, otherwise a new segment is
created. The current "meta sections" tells what kind of new segment to
create (e.g. nemsCode means that a new code segment will be created). }
TNewExeMetaSection = (
nemsNone,
nemsCode,
nemsData,
nemsBss,
nemsStack,
nemsLocalHeap);
const
NewExeMetaSection2String: array [TNewExeMetaSection] of string[9] = (
'',
'Code',
'Data',
'Bss',
'Stack',
'LocalHeap');
type
{ TNewExeSection }
TNewExeSection=class(TExeSection)
private
FEarlySize: QWord;
FExeMetaSec: TNewExeMetaSection;
public
procedure AddObjSection(objsec:TObjSection;ignoreprops:boolean=false);override;
function CanAddObjSection(objsec:TObjSection;ExeSectionLimit:QWord):boolean;
property EarlySize: QWord read FEarlySize write FEarlySize;
property ExeMetaSec: TNewExeMetaSection read FExeMetaSec write FExeMetaSec;
end;
{ TNewExeOutput }
@ -477,10 +511,13 @@ interface
private
FHeader: TNewExeHeader;
FImports: TFPHashObjectList;
FCurrExeMetaSec: TNewExeMetaSection;
procedure AddImportSymbol(const libname,symname,symmangledname:TCmdStr;OrdNr: longint;isvar:boolean);
procedure AddImportLibrariesExtractedFromObjectModules;
procedure AddNewExeSection;
function WriteNewExe:boolean;
property Header: TNewExeHeader read FHeader;
property CurrExeMetaSec: TNewExeMetaSection read FCurrExeMetaSec write FCurrExeMetaSec;
protected
procedure DoRelocationFixup(objsec:TObjSection);override;
procedure Order_ObjSectionList(ObjSectionList : TFPObjectList;const aPattern:string);override;
@ -488,6 +525,9 @@ interface
constructor create;override;
destructor destroy;override;
procedure Order_ExeSection(const aname:string);override;
procedure Order_EndExeSection;override;
procedure Order_ObjSection(const aname:string);override;
procedure GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);override;
function writeData:boolean;override;
end;
@ -3538,6 +3578,26 @@ cleanup:
aWriter.write(HeaderBytes[0],$40);
end;
{****************************************************************************
TNewExeSection
****************************************************************************}
procedure TNewExeSection.AddObjSection(objsec: TObjSection; ignoreprops: boolean);
begin
inherited;
EarlySize:=align_qword(EarlySize,SecAlign)+objsec.Size;
end;
function TNewExeSection.CanAddObjSection(objsec: TObjSection; ExeSectionLimit: QWord): boolean;
var
NewSecAlign: LongInt;
NewSize: QWord;
begin
NewSecAlign:=max(objsec.SecAlign,SecAlign);
NewSize:=align_qword(EarlySize,NewSecAlign)+objsec.Size;
Result:=NewSize<=ExeSectionLimit;
end;
{****************************************************************************
TNewExeOutput
****************************************************************************}
@ -3578,6 +3638,15 @@ cleanup:
end;
end;
procedure TNewExeOutput.AddNewExeSection;
var
SecName: string;
begin
WriteStr(SecName,'Segment',ExeSectionList.Count+1,'_',NewExeMetaSection2String[CurrExeMetaSec]);
inherited Order_ExeSection(SecName);
TNewExeSection(CurrExeSec).ExeMetaSec:=CurrExeMetaSec;
end;
function TNewExeOutput.WriteNewExe: boolean;
begin
Header.WriteTo(FWriter);
@ -3619,6 +3688,7 @@ cleanup:
CExeSection:=TNewExeSection;
FHeader:=TNewExeHeader.Create;
MaxMemPos:=$FFFFFFFF;
CurrExeMetaSec:=nemsNone;
end;
destructor TNewExeOutput.destroy;
@ -3627,6 +3697,69 @@ cleanup:
inherited destroy;
end;
procedure TNewExeOutput.Order_ExeSection(const aname: string);
begin
case aname of
'.NE_code':
CurrExeMetaSec:=nemsCode;
'.NE_data':
CurrExeMetaSec:=nemsData;
'.NE_bss':
CurrExeMetaSec:=nemsBss;
'.NE_stack':
CurrExeMetaSec:=nemsStack;
'.NE_localheap':
CurrExeMetaSec:=nemsLocalHeap;
else
internalerror(2019080201);
end;
end;
procedure TNewExeOutput.Order_EndExeSection;
begin
CurrExeMetaSec:=nemsNone;
inherited;
end;
procedure TNewExeOutput.Order_ObjSection(const aname: string);
const
SegmentLimit=$10000;
var
i,j : longint;
ObjData : TObjData;
objsec : TObjSection;
TmpObjSectionList : TFPObjectList;
begin
if CurrExeMetaSec=nemsNone then
internalerror(2019080202);
if not assigned (CurrExeSec) then
AddNewExeSection;
TmpObjSectionList:=TFPObjectList.Create(false);
for i:=0 to ObjDataList.Count-1 do
begin
ObjData:=TObjData(ObjDataList[i]);
for j:=0 to ObjData.ObjSectionList.Count-1 do
begin
objsec:=TObjSection(ObjData.ObjSectionList[j]);
if (not objsec.Used) and
MatchPattern(aname,objsec.name) then
TmpObjSectionList.Add(objsec);
end;
end;
{ Order list if needed }
Order_ObjSectionList(TmpObjSectionList,aname);
{ Add the (ordered) list to the current ExeSection }
for i:=0 to TmpObjSectionList.Count-1 do
begin
objsec:=TObjSection(TmpObjSectionList[i]);
{ If there's no room left in the current section, create a new one }
if not TNewExeSection(CurrExeSec).CanAddObjSection(objsec,SegmentLimit) then
AddNewExeSection;
CurrExeSec.AddObjSection(objsec);
end;
TmpObjSectionList.Free;
end;
procedure TNewExeOutput.GenerateLibraryImports(ImportLibraryList: TFPHashObjectList);
var
i,j: longint;