mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-23 07:32:17 +02:00
* DLL support
git-svn-id: trunk@3623 -
This commit is contained in:
parent
392ef22a7f
commit
a57708e63d
@ -88,6 +88,7 @@ Type
|
||||
procedure ParseScript_Order;
|
||||
procedure ParseScript_CalcPos;
|
||||
procedure PrintLinkerScript;
|
||||
function RunLinkScript(const outputname:string):boolean;
|
||||
protected
|
||||
property CObjInput:TObjInputClass read FCObjInput write FCObjInput;
|
||||
property CExeOutput:TExeOutputClass read FCExeOutput write FCExeOutput;
|
||||
@ -95,9 +96,11 @@ Type
|
||||
procedure DefaultLinkScript;virtual;abstract;
|
||||
linkscript : TStringList;
|
||||
public
|
||||
IsSharedLibrary : boolean;
|
||||
Constructor Create;override;
|
||||
Destructor Destroy;override;
|
||||
Function MakeExecutable:boolean;override;
|
||||
Function MakeSharedLibrary:boolean;override;
|
||||
procedure AddExternalSymbol(const libname,symname:string);override;
|
||||
end;
|
||||
|
||||
@ -819,6 +822,10 @@ end;
|
||||
ExeOutput.Load_Symbol(para)
|
||||
else if keyword='ENTRYNAME' then
|
||||
ExeOutput.Load_EntryName(para)
|
||||
else if keyword='ISSHAREDLIBRARY' then
|
||||
ExeOutput.Load_IsSharedLibrary
|
||||
else if keyword='IMAGEBASE' then
|
||||
ExeOutput.Load_ImageBase(para)
|
||||
else if keyword='READOBJECT' then
|
||||
Load_ReadObject(para)
|
||||
else if keyword='READUNITOBJECTS' then
|
||||
@ -906,15 +913,13 @@ end;
|
||||
end;
|
||||
|
||||
|
||||
function TInternalLinker.MakeExecutable:boolean;
|
||||
function TInternalLinker.RunLinkScript(const outputname:string):boolean;
|
||||
label
|
||||
myexit;
|
||||
var
|
||||
s,s2 : string;
|
||||
begin
|
||||
MakeExecutable:=false;
|
||||
result:=false;
|
||||
|
||||
Message1(exec_i_linking,current_module.exefilename^);
|
||||
Message1(exec_i_linking,outputname);
|
||||
|
||||
{$warning TODO Load custom linker script}
|
||||
DefaultLinkScript;
|
||||
@ -951,7 +956,7 @@ end;
|
||||
if ErrorCount>0 then
|
||||
goto myexit;
|
||||
|
||||
exeoutput.WriteExeFile(current_module.exefilename^);
|
||||
exeoutput.WriteExeFile(outputname);
|
||||
|
||||
{$warning TODO fixed section names}
|
||||
status.codesize:=exeoutput.findexesection('.text').size;
|
||||
@ -969,7 +974,21 @@ end;
|
||||
exeoutput.free;
|
||||
exeoutput:=nil;
|
||||
|
||||
MakeExecutable:=true;
|
||||
result:=true;
|
||||
end;
|
||||
|
||||
|
||||
function TInternalLinker.MakeExecutable:boolean;
|
||||
begin
|
||||
IsSharedLibrary:=false;
|
||||
result:=RunLinkScript(current_module.exefilename^);
|
||||
end;
|
||||
|
||||
|
||||
function TInternalLinker.MakeSharedLibrary:boolean;
|
||||
begin
|
||||
IsSharedLibrary:=true;
|
||||
result:=RunLinkScript(current_module.sharedlibfilename^);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -362,6 +362,7 @@ interface
|
||||
property CExeSection:TExeSectionClass read FCExeSection write FCExeSection;
|
||||
property CObjData:TObjDataClass read FCObjData write FCObjData;
|
||||
public
|
||||
IsSharedLibrary : boolean;
|
||||
constructor create;virtual;
|
||||
destructor destroy;override;
|
||||
function FindExeSection(const aname:string):TExeSection;
|
||||
@ -369,6 +370,8 @@ interface
|
||||
procedure Load_Start;virtual;
|
||||
procedure Load_EntryName(const aname:string);virtual;
|
||||
procedure Load_Symbol(const aname:string);virtual;
|
||||
procedure Load_IsSharedLibrary;
|
||||
procedure Load_ImageBase(const avalue:string);
|
||||
procedure Order_Start;virtual;
|
||||
procedure Order_End;virtual;
|
||||
procedure Order_ExeSection(const aname:string);virtual;
|
||||
@ -1334,6 +1337,20 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure TExeOutput.Load_IsSharedLibrary;
|
||||
begin
|
||||
IsSharedLibrary:=true;
|
||||
end;
|
||||
|
||||
|
||||
procedure TExeOutput.Load_ImageBase(const avalue:string);
|
||||
var
|
||||
code : integer;
|
||||
begin
|
||||
val(avalue,ImageBase,code);
|
||||
end;
|
||||
|
||||
|
||||
procedure TExeOutput.Load_Symbol(const aname:string);
|
||||
begin
|
||||
internalObjData.createsection('*'+aname,0,[]);
|
||||
|
@ -1814,6 +1814,7 @@ const win32stub : array[0..131] of byte=(
|
||||
end;
|
||||
{$warning TODO idata keep can maybe replaced with grouping of text and idata}
|
||||
if (Copy(secname,1,6)='.idata') or
|
||||
(Copy(secname,1,6)='.edata') or
|
||||
(Copy(secname,1,6)='.rsrc') then
|
||||
include(secoptions,oso_keep);
|
||||
objsec:=TCoffObjSection(createsection(secname,secalign,secoptions));
|
||||
@ -2063,11 +2064,22 @@ const win32stub : array[0..131] of byte=(
|
||||
header : coffheader;
|
||||
djoptheader : coffdjoptheader;
|
||||
peoptheader : coffpeoptheader;
|
||||
rsrcexesec,
|
||||
idataexesec,
|
||||
textExeSec,
|
||||
dataExeSec,
|
||||
bssExeSec : TExeSection;
|
||||
|
||||
procedure UpdateDataDir(const secname:string;idx:longint);
|
||||
var
|
||||
exesec : TExeSection;
|
||||
begin
|
||||
exesec:=FindExeSection(secname);
|
||||
if assigned(exesec) then
|
||||
begin
|
||||
peoptheader.DataDirectory[idx].vaddr:=exesec.mempos;
|
||||
peoptheader.DataDirectory[idx].size:=exesec.Size;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
result:=false;
|
||||
FCoffSyms:=TDynamicArray.Create(symbolresize);
|
||||
@ -2096,9 +2108,9 @@ const win32stub : array[0..131] of byte=(
|
||||
header.opthdr:=sizeof(coffdjoptheader);
|
||||
if win32 then
|
||||
begin
|
||||
header.flag:=PE_FILE_EXECUTABLE_IMAGE or PE_FILE_RELOCS_STRIPPED or
|
||||
{PE_FILE_BYTES_REVERSED_LO or }
|
||||
PE_FILE_LINE_NUMS_STRIPPED;
|
||||
header.flag:=PE_FILE_EXECUTABLE_IMAGE or PE_FILE_RELOCS_STRIPPED or PE_FILE_LINE_NUMS_STRIPPED;
|
||||
if IsSharedLibrary then
|
||||
header.flag:=header.flag or PE_FILE_DLL;
|
||||
if FindExeSection('.stab')=nil then
|
||||
header.flag:=header.flag or PE_FILE_DEBUG_STRIPPED;
|
||||
if (cs_link_strip in aktglobalswitches) then
|
||||
@ -2151,18 +2163,9 @@ const win32stub : array[0..131] of byte=(
|
||||
peoptheader.SizeOfHeapCommit:=$1000;
|
||||
peoptheader.LoaderFlags:=0;
|
||||
peoptheader.NumberOfRvaAndSizes:=PE_DATADIR_ENTRIES;
|
||||
idataexesec:=FindExeSection('.idata');
|
||||
if assigned(idataexesec) then
|
||||
begin
|
||||
peoptheader.DataDirectory[PE_DATADIR_IDATA].vaddr:=idataexesec.mempos;
|
||||
peoptheader.DataDirectory[PE_DATADIR_IDATA].size:=idataexesec.Size;
|
||||
end;
|
||||
rsrcexesec:=FindExeSection('.rsrc');
|
||||
if assigned(rsrcexesec) then
|
||||
begin
|
||||
peoptheader.DataDirectory[PE_DATADIR_RSRC].vaddr:=rsrcexesec.mempos;
|
||||
peoptheader.DataDirectory[PE_DATADIR_RSRC].size:=rsrcexesec.Size;
|
||||
end;
|
||||
UpdateDataDir('.idata',PE_DATADIR_IDATA);
|
||||
UpdateDataDir('.edata',PE_DATADIR_EDATA);
|
||||
UpdateDataDir('.rsrc',PE_DATADIR_RSRC);
|
||||
FWriter.write(peoptheader,sizeof(peoptheader));
|
||||
end
|
||||
else
|
||||
@ -2409,10 +2412,22 @@ const win32stub : array[0..131] of byte=(
|
||||
with LinkScript do
|
||||
begin
|
||||
Concat('READUNITOBJECTS');
|
||||
if apptype=app_gui then
|
||||
Concat('ENTRYNAME _WinMainCRTStartup')
|
||||
if IsSharedLibrary then
|
||||
begin
|
||||
Concat('ISSHAREDLIBRARY');
|
||||
Concat('IMAGEBASE $10000000');
|
||||
if apptype=app_gui then
|
||||
Concat('ENTRYNAME _DLLWinMainCRTStartup')
|
||||
else
|
||||
Concat('ENTRYNAME _DLLMainCRTStartup');
|
||||
end
|
||||
else
|
||||
Concat('ENTRYNAME _mainCRTStartup');
|
||||
begin
|
||||
if apptype=app_gui then
|
||||
Concat('ENTRYNAME _WinMainCRTStartup')
|
||||
else
|
||||
Concat('ENTRYNAME _mainCRTStartup');
|
||||
end;
|
||||
Concat('HEADER');
|
||||
Concat('EXESECTION .text');
|
||||
Concat(' OBJSECTION .text*');
|
||||
@ -2438,6 +2453,9 @@ const win32stub : array[0..131] of byte=(
|
||||
Concat(' OBJSECTION .idata$6');
|
||||
Concat(' OBJSECTION .idata$7');
|
||||
Concat('ENDEXESECTION');
|
||||
Concat('EXESECTION .edata');
|
||||
Concat(' OBJSECTION .edata*');
|
||||
Concat('ENDEXESECTION');
|
||||
Concat('EXESECTION .rsrc');
|
||||
Concat(' OBJSECTION .rsrc*');
|
||||
Concat('ENDEXESECTION');
|
||||
|
Loading…
Reference in New Issue
Block a user