mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-02 07:09:38 +01:00
+ Added method TObjSection.writeReloc_internal to write relocations to given section+offset without need to have a symbol at target location.
* Optimized COFF importing code using the new method. - Don't create .text sections for imported variables. - Don't create .idata$6 sections for imports by ordinal. git-svn-id: trunk@22086 -
This commit is contained in:
parent
0801287956
commit
ec56677927
@ -209,6 +209,7 @@ interface
|
||||
function write(const d;l:aword):aword;
|
||||
function writestr(const s:string):aword;
|
||||
function WriteZeros(l:longword):aword;
|
||||
procedure writeReloc_internal(aTarget:TObjSection;offset:aword;len:byte;reltype:TObjRelocationType);virtual;
|
||||
function setmempos(mpos:qword):qword;
|
||||
procedure setDatapos(var dpos:aword);
|
||||
procedure alloc(l:aword);
|
||||
@ -712,6 +713,14 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
{ Writes relocation to (section+offset) without need to have a symbol at that location.
|
||||
Not an abstract method because not every backend needs this functionality. }
|
||||
procedure TObjSection.writeReloc_internal(aTarget:TObjSection;offset:aword;len:byte;reltype:TObjRelocationType);
|
||||
begin
|
||||
InternalError(2012081501);
|
||||
end;
|
||||
|
||||
|
||||
procedure TObjSection.setDatapos(var dpos:aword);
|
||||
begin
|
||||
if oso_Data in secoptions then
|
||||
|
||||
@ -109,6 +109,7 @@ interface
|
||||
public
|
||||
constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);override;
|
||||
procedure addsymsizereloc(ofs:aword;p:TObjSymbol;symsize:aword;reloctype:TObjRelocationType);
|
||||
procedure writereloc_internal(aTarget:TObjSection;offset:aword;len:byte;reltype:TObjRelocationType);override;
|
||||
end;
|
||||
|
||||
TCoffObjData = class(TObjData)
|
||||
@ -220,7 +221,6 @@ interface
|
||||
|
||||
TPECoffexeoutput = class(TCoffexeoutput)
|
||||
private
|
||||
idatalabnr : longword;
|
||||
FRelocsGenerated : boolean;
|
||||
procedure GenerateRelocs;
|
||||
public
|
||||
@ -812,6 +812,13 @@ const pemagic : array[0..3] of byte = (
|
||||
end;
|
||||
|
||||
|
||||
procedure TCoffObjSection.writereloc_internal(aTarget:TObjSection;offset:aword;len:byte;reltype:TObjRelocationType);
|
||||
begin
|
||||
AddSectionReloc(size,aTarget,reltype);
|
||||
write(offset,len);
|
||||
end;
|
||||
|
||||
|
||||
procedure TCoffExeOutput.DoRelocationFixup(objsec:TObjSection);
|
||||
var
|
||||
i,zero,address_size : longint;
|
||||
@ -2400,77 +2407,49 @@ const pemagic : array[0..3] of byte = (
|
||||
idata5objsection,
|
||||
idata6objsection,
|
||||
idata7objsection : TObjSection;
|
||||
idata2label : TObjSymbol;
|
||||
basedllname : string;
|
||||
|
||||
procedure StartImport(const dllname:string);
|
||||
var
|
||||
idata4label,
|
||||
idata5label,
|
||||
idata7label : TObjSymbol;
|
||||
emptyint : longint;
|
||||
begin
|
||||
if assigned(exemap) then
|
||||
begin
|
||||
exemap.Add('');
|
||||
exemap.Add('Importing from DLL '+dllname);
|
||||
end;
|
||||
emptyint:=0;
|
||||
basedllname:=ExtractFileName(dllname);
|
||||
idata2objsection:=internalobjdata.createsection(sec_idata2,basedllname);
|
||||
idata2label:=internalobjdata.SymbolDefine('__imp_dir_'+basedllname,AB_LOCAL,AT_DATA);
|
||||
idata4objsection:=internalobjdata.createsection(sec_idata4,basedllname);
|
||||
idata4label:=internalobjdata.SymbolDefine('__imp_names_'+basedllname,AB_LOCAL,AT_DATA);
|
||||
idata5objsection:=internalobjdata.createsection(sec_idata5,basedllname);
|
||||
idata5label:=internalobjdata.SymbolDefine('__imp_fixup_'+basedllname,AB_LOCAL,AT_DATA);
|
||||
idata7objsection:=internalobjdata.createsection(sec_idata7,basedllname);
|
||||
idata7label:=internalobjdata.SymbolDefine('__imp_dll_'+basedllname,AB_LOCAL,AT_DATA);
|
||||
{ idata2 }
|
||||
internalobjdata.SetSection(idata2objsection);
|
||||
{ dummy links to imports finalization }
|
||||
internalobjdata.writereloc(0,0,internalobjdata.SymbolRef('__imp_names_end_'+basedllname),RELOC_NONE);
|
||||
internalobjdata.writereloc(0,0,internalobjdata.SymbolRef('__imp_fixup_end_'+basedllname),RELOC_NONE);
|
||||
{ section data }
|
||||
internalobjdata.writereloc(0,sizeof(longint),idata4label,RELOC_RVA);
|
||||
internalobjdata.writebytes(emptyint,sizeof(emptyint));
|
||||
internalobjdata.writebytes(emptyint,sizeof(emptyint));
|
||||
internalobjdata.writereloc(0,sizeof(longint),idata7label,RELOC_RVA);
|
||||
internalobjdata.writereloc(0,sizeof(longint),idata5label,RELOC_RVA);
|
||||
idata2objsection.writereloc_internal(idata4objsection,0,sizeof(longint),RELOC_RVA);
|
||||
idata2objsection.writezeros(2*sizeof(longint));
|
||||
idata2objsection.writereloc_internal(idata7objsection,0,sizeof(longint),RELOC_RVA);
|
||||
idata2objsection.writereloc_internal(idata5objsection,0,sizeof(longint),RELOC_RVA);
|
||||
{ idata7 }
|
||||
internalobjdata.SetSection(idata7objsection);
|
||||
internalobjdata.writebytes(basedllname[1],length(basedllname));
|
||||
internalobjdata.writebytes(emptyint,1);
|
||||
idata7objsection.writestr(basedllname);
|
||||
idata7objsection.writezeros(1);
|
||||
end;
|
||||
|
||||
procedure EndImport;
|
||||
var
|
||||
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_');
|
||||
internalobjdata.SymbolDefine('__imp_fixup_end_'+basedllname,AB_LOCAL,AT_DATA);
|
||||
idata2objsection.writereloc_internal(idata4objsection,0,0,RELOC_NONE);
|
||||
idata2objsection.writereloc_internal(idata5objsection,0,0,RELOC_NONE);
|
||||
{ idata4 }
|
||||
internalobjdata.SetSection(idata4objsection);
|
||||
internalobjdata.writebytes(emptyint,sizeof(emptyint));
|
||||
idata4objsection.writezeros(sizeof(longint));
|
||||
if target_info.system=system_x86_64_win64 then
|
||||
internalobjdata.writebytes(emptyint,sizeof(emptyint));
|
||||
idata4objsection.writezeros(sizeof(longint));
|
||||
{ idata5 }
|
||||
internalobjdata.SetSection(idata5objsection);
|
||||
internalobjdata.writebytes(emptyint,sizeof(emptyint));
|
||||
idata5objsection.writezeros(sizeof(longint));
|
||||
if target_info.system=system_x86_64_win64 then
|
||||
internalobjdata.writebytes(emptyint,sizeof(emptyint));
|
||||
idata5objsection.writezeros(sizeof(longint));
|
||||
end;
|
||||
|
||||
function AddImport(const afuncname,amangledname:string; AOrdNr:longint;isvar:boolean):TObjSymbol;
|
||||
const
|
||||
{$ifdef x86_64}
|
||||
jmpopcode : array[0..1] of byte = (
|
||||
$ff,$25 // jmp qword [rip + offset32]
|
||||
);
|
||||
{$else x86_64}
|
||||
{$ifdef arm}
|
||||
jmpopcode : array[0..7] of byte = (
|
||||
$00,$c0,$9f,$e5, // ldr ip, [pc, #0]
|
||||
@ -2481,29 +2460,32 @@ const pemagic : array[0..3] of byte = (
|
||||
$ff,$25
|
||||
);
|
||||
{$endif arm}
|
||||
{$endif x86_64}
|
||||
nopopcodes : array[0..1] of byte = (
|
||||
$90,$90
|
||||
);
|
||||
var
|
||||
idata4label,
|
||||
idata5label,
|
||||
idata6label : TObjSymbol;
|
||||
emptyint : longint;
|
||||
secname,
|
||||
num : string;
|
||||
absordnr: word;
|
||||
secname: string;
|
||||
|
||||
procedure WriteTableEntry;
|
||||
procedure WriteTableEntry(objsec:TObjSection);
|
||||
var
|
||||
ordint: dword;
|
||||
begin
|
||||
if AOrdNr <= 0 then
|
||||
begin
|
||||
{ import by name }
|
||||
internalobjdata.writereloc(0,sizeof(longint),idata6label,RELOC_RVA);
|
||||
if idata6objsection=nil then
|
||||
begin
|
||||
idata6objsection:=internalobjdata.createsection(sec_idata6,secname);
|
||||
ordint:=Abs(AOrdNr);
|
||||
{ index hint, function name, null terminator and align }
|
||||
idata6objsection.write(ordint,2);
|
||||
idata6objsection.writestr(afuncname);
|
||||
idata6objsection.writezeros(1);
|
||||
idata6objsection.writezeros(align(idata6objsection.size,2)-idata6objsection.size);
|
||||
end;
|
||||
objsec.writereloc_internal(idata6objsection,0,sizeof(longint),RELOC_RVA);
|
||||
if target_info.system=system_x86_64_win64 then
|
||||
internalobjdata.writebytes(emptyint,sizeof(emptyint));
|
||||
objsec.writezeros(sizeof(longint));
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -2511,21 +2493,22 @@ const pemagic : array[0..3] of byte = (
|
||||
ordint:=AOrdNr;
|
||||
if target_info.system=system_x86_64_win64 then
|
||||
begin
|
||||
internalobjdata.writebytes(ordint,sizeof(ordint));
|
||||
objsec.write(ordint,sizeof(ordint));
|
||||
ordint:=$80000000;
|
||||
internalobjdata.writebytes(ordint,sizeof(ordint));
|
||||
objsec.write(ordint,sizeof(ordint));
|
||||
end
|
||||
else
|
||||
begin
|
||||
ordint:=ordint or $80000000;
|
||||
internalobjdata.writebytes(ordint,sizeof(ordint));
|
||||
objsec.write(ordint,sizeof(ordint));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
result:=nil;
|
||||
emptyint:=0;
|
||||
textobjsection:=nil;
|
||||
idata6objsection:=nil;
|
||||
if assigned(exemap) then
|
||||
begin
|
||||
if AOrdNr <= 0 then
|
||||
@ -2534,56 +2517,35 @@ const pemagic : array[0..3] of byte = (
|
||||
exemap.Add(' Importing Function '+afuncname+' (OrdNr='+tostr(AOrdNr)+')');
|
||||
end;
|
||||
|
||||
with internalobjdata do
|
||||
begin
|
||||
secname:=basedllname+'_i_'+amangledname;
|
||||
textobjsection:=createsection(sectionname(sec_code,secname,secorder_default),current_settings.alignment.procalign,sectiontype2options(sec_code) - [oso_keep]);
|
||||
idata4objsection:=createsection(sec_idata4, secname);
|
||||
idata5objsection:=createsection(sec_idata5, secname);
|
||||
idata6objsection:=createsection(sec_idata6, secname);
|
||||
end;
|
||||
secname:=basedllname+'_i_'+amangledname;
|
||||
idata4objsection:=internalobjdata.createsection(sec_idata4, secname);
|
||||
idata5objsection:=internalobjdata.createsection(sec_idata5, secname);
|
||||
|
||||
{ idata6, import data (ordnr+name) }
|
||||
internalobjdata.SetSection(idata6objsection);
|
||||
inc(idatalabnr);
|
||||
num:=tostr(idatalabnr);
|
||||
idata6label:=internalobjdata.SymbolDefine('__imp_'+num,AB_LOCAL,AT_DATA);
|
||||
absordnr:=Abs(AOrdNr);
|
||||
{ write index hint }
|
||||
internalobjdata.writebytes(absordnr,2);
|
||||
if AOrdNr <= 0 then
|
||||
internalobjdata.writebytes(afuncname[1],length(afuncname));
|
||||
internalobjdata.writebytes(emptyint,1);
|
||||
internalobjdata.writebytes(emptyint,align(internalobjdata.CurrObjSec.size,2)-internalobjdata.CurrObjSec.size);
|
||||
{ idata4, import lookup table }
|
||||
internalobjdata.SetSection(idata4objsection);
|
||||
idata4label:=internalobjdata.SymbolDefine('__imp_lookup_'+num,AB_LOCAL,AT_DATA);
|
||||
WriteTableEntry;
|
||||
WriteTableEntry(idata4objsection);
|
||||
{ idata5, import address table }
|
||||
internalobjdata.SetSection(idata5objsection);
|
||||
{ dummy back links }
|
||||
internalobjdata.writereloc(0,0,idata4label,RELOC_NONE);
|
||||
internalobjdata.writereloc(0,0,idata2label,RELOC_NONE);
|
||||
{ section data }
|
||||
idata5objsection.writereloc_internal(idata4objsection,0,0,RELOC_NONE);
|
||||
idata5objsection.writereloc_internal(idata2objsection,0,0,RELOC_NONE);
|
||||
if isvar then
|
||||
result:=internalobjdata.SymbolDefine(amangledname,AB_GLOBAL,AT_DATA)
|
||||
else
|
||||
idata5label:=internalobjdata.SymbolDefine('__imp_'+amangledname,AB_LOCAL,AT_DATA);
|
||||
WriteTableEntry;
|
||||
{ text, jmp }
|
||||
if not isvar then
|
||||
begin
|
||||
internalobjdata.SetSection(textobjsection);
|
||||
textobjsection:=internalobjdata.createsection(internalobjdata.sectionname(sec_code,secname,secorder_default),current_settings.alignment.procalign,
|
||||
internalobjdata.sectiontype2options(sec_code) - [oso_keep]);
|
||||
result:=internalobjdata.SymbolDefine('_'+amangledname,AB_GLOBAL,AT_FUNCTION);
|
||||
internalobjdata.writebytes(jmpopcode,sizeof(jmpopcode));
|
||||
textobjsection.write(jmpopcode,sizeof(jmpopcode));
|
||||
{$ifdef x86_64}
|
||||
internalobjdata.writereloc(0,4,idata5label,RELOC_RELATIVE);
|
||||
textobjsection.writereloc_internal(idata5objsection,0,4,RELOC_RELATIVE);
|
||||
{$else}
|
||||
internalobjdata.writereloc(0,4,idata5label,RELOC_ABSOLUTE32);
|
||||
textobjsection.writereloc_internal(idata5objsection,0,4,RELOC_ABSOLUTE32);
|
||||
{$endif x86_64}
|
||||
|
||||
internalobjdata.writebytes(nopopcodes,align(internalobjdata.CurrObjSec.size,sizeof(nopopcodes))-internalobjdata.CurrObjSec.size);
|
||||
textobjsection.write(nopopcodes,align(textobjsection.size,sizeof(nopopcodes))-textobjsection.size);
|
||||
end;
|
||||
{ idata5 section data }
|
||||
WriteTableEntry(idata5objsection);
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
Loading…
Reference in New Issue
Block a user