mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-11 13:29:18 +02:00
* Improvements to PE executable output:
* Clear bits in section flags, that are only valid for object files * Round section datasize up to filealignment (PECOFF v8 documentation requires this) * Zero datapos and datasize for all sections w/o data, not just for .bss * Produce IMPORT_ADDRESS_TABLE directory in exe header * Entirely smartlink away unused DLLs (these used to have two terminating thunks left) git-svn-id: trunk@17949 -
This commit is contained in:
parent
cd94bb5edf
commit
2d96c34b06
@ -2107,12 +2107,18 @@ const pemagic : array[0..3] of byte = (
|
||||
else
|
||||
sechdr.vsize:=mempos;
|
||||
|
||||
{ sechdr.dataSize is size of initilized data. For .bss section it must be zero }
|
||||
if (Name <> '.bss') then
|
||||
sechdr.dataSize:=Size;
|
||||
if (sechdr.dataSize>0) and
|
||||
(oso_data in SecOptions) then
|
||||
sechdr.datapos:=datapos;
|
||||
{ sechdr.dataSize is size of initilized data. Must be zero for sections that
|
||||
do not contain one. In Windows, must be rounded up to FileAlignment
|
||||
(so it can be greater than VirtualSize) }
|
||||
if (oso_data in SecOptions) then
|
||||
begin
|
||||
if win32 then
|
||||
sechdr.dataSize:=Align(Size,SectionDataAlign)
|
||||
else
|
||||
sechdr.dataSize:=Size;
|
||||
if (Size>0) then
|
||||
sechdr.datapos:=datapos;
|
||||
end;
|
||||
sechdr.nrelocs:=0;
|
||||
sechdr.relocpos:=0;
|
||||
if win32 then
|
||||
@ -2122,6 +2128,10 @@ const pemagic : array[0..3] of byte = (
|
||||
sechdr.flags:=peencodesechdrflags(SecOptions,SecAlign) or PE_SCN_MEM_NOT_PAGED
|
||||
else
|
||||
sechdr.flags:=peencodesechdrflags(SecOptions,SecAlign);
|
||||
{ some flags are invalid in executables, reset them }
|
||||
sechdr.flags:=sechdr.flags and
|
||||
not(PE_SCN_LNK_INFO or PE_SCN_LNK_REMOVE or
|
||||
PE_SCN_LNK_COMDAT or PE_SCN_ALIGN_MASK);
|
||||
end
|
||||
else
|
||||
sechdr.flags:=djencodesechdrflags(SecOptions);
|
||||
@ -2250,6 +2260,49 @@ const pemagic : array[0..3] of byte = (
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure UpdateImports;
|
||||
var
|
||||
exesec: TExeSection;
|
||||
objsec, iat_start, iat_end, ilt_start: TObjSection;
|
||||
i: longint;
|
||||
begin
|
||||
exesec:=FindExeSection('.idata');
|
||||
if exesec=nil then
|
||||
exit;
|
||||
iat_start:=nil;
|
||||
iat_end:=nil;
|
||||
ilt_start:=nil;
|
||||
for i:=0 to exesec.ObjSectionList.Count-1 do
|
||||
begin
|
||||
objsec:=TObjSection(exesec.ObjSectionList[i]);
|
||||
if (ilt_start=nil) and (Pos('.idata$4',objsec.Name)=1) then
|
||||
ilt_start:=objsec;
|
||||
if Pos('.idata$5',objsec.Name)=1 then
|
||||
begin
|
||||
if iat_start=nil then
|
||||
iat_start:=objsec;
|
||||
end
|
||||
else
|
||||
if Assigned(iat_start) then
|
||||
begin
|
||||
iat_end:=objsec;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
|
||||
peoptheader.DataDirectory[PE_DATADIR_IDATA].vaddr:=exesec.mempos;
|
||||
if Assigned(ilt_start) then
|
||||
peoptheader.DataDirectory[PE_DATADIR_IDATA].size:=ilt_start.mempos-exesec.mempos
|
||||
else { should not happen }
|
||||
peoptheader.DataDirectory[PE_DATADIR_IDATA].size:=exesec.Size;
|
||||
|
||||
if Assigned(iat_start) and Assigned(iat_end) then
|
||||
begin
|
||||
peoptheader.DataDirectory[PE_DATADIR_IMPORTADDRESSTABLE].vaddr:=iat_start.mempos;
|
||||
peoptheader.DataDirectory[PE_DATADIR_IMPORTADDRESSTABLE].size:=iat_end.mempos-iat_start.mempos;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure UpdateTlsDataDir;
|
||||
var
|
||||
{callbacksection : TExeSection;}
|
||||
@ -2404,7 +2457,7 @@ const pemagic : array[0..3] of byte = (
|
||||
peoptheader.SizeOfHeapReserve:=$100000;
|
||||
peoptheader.SizeOfHeapCommit:=$1000;
|
||||
peoptheader.NumberOfRvaAndSizes:=PE_DATADIR_ENTRIES;
|
||||
UpdateDataDir('.idata',PE_DATADIR_IDATA);
|
||||
UpdateImports;
|
||||
UpdateTlsDataDir;
|
||||
UpdateDataDir('.edata',PE_DATADIR_EDATA);
|
||||
UpdateDataDir('.rsrc',PE_DATADIR_RSRC);
|
||||
@ -2545,6 +2598,7 @@ const pemagic : array[0..3] of byte = (
|
||||
emptyint : longint;
|
||||
begin
|
||||
emptyint:=0;
|
||||
{ These are referenced from idata2, oso_keep is not necessary. }
|
||||
idata4objsection:=internalobjdata.createsection(sec_idata4, basedllname+'_z_');
|
||||
internalobjdata.SymbolDefine('__imp_names_end_'+basedllname,AB_LOCAL,AT_DATA);
|
||||
idata5objsection:=internalobjdata.createsection(sec_idata5, basedllname+'_z_');
|
||||
@ -2559,9 +2613,6 @@ const pemagic : array[0..3] of byte = (
|
||||
internalobjdata.writebytes(emptyint,sizeof(emptyint));
|
||||
if target_info.system=system_x86_64_win64 then
|
||||
internalobjdata.writebytes(emptyint,sizeof(emptyint));
|
||||
{ be sure that this will not be removed }
|
||||
idata4objsection.SecOptions:=idata4objsection.SecOptions + [oso_keep];
|
||||
idata5objsection.SecOptions:=idata5objsection.SecOptions + [oso_keep];
|
||||
end;
|
||||
|
||||
function AddImport(const afuncname,amangledname:string; AOrdNr:longint;isvar:boolean):TObjSymbol;
|
||||
|
Loading…
Reference in New Issue
Block a user