* 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:
sergei 2011-07-06 20:55:57 +00:00
parent cd94bb5edf
commit 2d96c34b06

View File

@ -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;