mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-01 03:39:19 +02:00
+ Add checks for internal linker script
git-svn-id: trunk@17882 -
This commit is contained in:
parent
0227fbad7d
commit
f328836cad
@ -84,6 +84,9 @@ interface
|
||||
Function MakeStaticLibrary:boolean;override;
|
||||
end;
|
||||
|
||||
TBooleanArray = array [1..1024] of boolean;
|
||||
PBooleanArray = ^TBooleanArray;
|
||||
|
||||
TInternalLinker = class(TLinker)
|
||||
private
|
||||
FCExeOutput : TExeOutputClass;
|
||||
@ -94,6 +97,7 @@ interface
|
||||
procedure Load_ReadObject(const para:TCmdStr);
|
||||
procedure Load_ReadStaticLibrary(const para:TCmdStr);
|
||||
procedure ParseScript_Handle;
|
||||
procedure ParseScript_PostCheck;
|
||||
procedure ParseScript_Load;
|
||||
procedure ParseScript_Order;
|
||||
procedure ParseScript_MemPos;
|
||||
@ -102,6 +106,8 @@ interface
|
||||
function RunLinkScript(const outputname:TCmdStr):boolean;
|
||||
protected
|
||||
linkscript : TCmdStrList;
|
||||
ScriptCount : longint;
|
||||
IsHandled : PBooleanArray;
|
||||
property CObjInput:TObjInputClass read FCObjInput write FCObjInput;
|
||||
property CExeOutput:TExeOutputClass read FCExeOutput write FCExeOutput;
|
||||
property StaticLibraryList:TFPHashObjectList read FStaticLibraryList;
|
||||
@ -109,6 +115,7 @@ interface
|
||||
procedure DefaultLinkScript;virtual;abstract;
|
||||
public
|
||||
IsSharedLibrary : boolean;
|
||||
UseStabs : boolean;
|
||||
Constructor Create;override;
|
||||
Destructor Destroy;override;
|
||||
Function MakeExecutable:boolean;override;
|
||||
@ -811,7 +818,10 @@ Implementation
|
||||
FImportLibraryList:=TFPHashObjectList.Create(true);
|
||||
exemap:=nil;
|
||||
exeoutput:=nil;
|
||||
UseStabs:=false;
|
||||
CObjInput:=TObjInput;
|
||||
ScriptCount:=0;
|
||||
IsHandled:=nil;
|
||||
end;
|
||||
|
||||
|
||||
@ -820,6 +830,12 @@ Implementation
|
||||
linkscript.free;
|
||||
StaticLibraryList.Free;
|
||||
ImportLibraryList.Free;
|
||||
if assigned(IsHandled) then
|
||||
begin
|
||||
FreeMem(IsHandled,sizeof(boolean)*ScriptCount);
|
||||
IsHandled:=nil;
|
||||
ScriptCount:=0;
|
||||
end;
|
||||
if assigned(exeoutput) then
|
||||
begin
|
||||
exeoutput.free;
|
||||
@ -887,15 +903,15 @@ Implementation
|
||||
|
||||
procedure TInternalLinker.ParseScript_Handle;
|
||||
var
|
||||
s,
|
||||
para,
|
||||
keyword : String;
|
||||
s, para, keyword : String;
|
||||
hp : TCmdStrListItem;
|
||||
i : longint;
|
||||
begin
|
||||
exeoutput.Load_Start;
|
||||
hp:=TCmdStrListItem(linkscript.first);
|
||||
i:=0;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
inc(i);
|
||||
s:=hp.str;
|
||||
if (s='') or (s[1]='#') then
|
||||
continue;
|
||||
@ -904,8 +920,10 @@ Implementation
|
||||
if Trim(s)<>'' then
|
||||
Comment(V_Warning,'Unknown part "'+s+'" in "'+hp.str+'" internal linker script');
|
||||
if (keyword<>'SYMBOL') and
|
||||
(keyword<>'SYMBOLS') and
|
||||
(keyword<>'STABS') and
|
||||
(keyword<>'PROVIDE') and
|
||||
(keyword<>'ZEROES') and
|
||||
(keyword<>'ZEROS') and
|
||||
(keyword<>'BYTE') and
|
||||
(keyword<>'WORD') and
|
||||
(keyword<>'LONG') and
|
||||
@ -924,6 +942,33 @@ Implementation
|
||||
+'" internal linker script');
|
||||
hp:=TCmdStrListItem(hp.next);
|
||||
end;
|
||||
ScriptCount:=i;
|
||||
if ScriptCount>0 then
|
||||
begin
|
||||
GetMem(IsHandled,sizeof(boolean)*ScriptCount);
|
||||
Fillchar(IsHandled^,sizeof(boolean)*ScriptCount,#0);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TInternalLinker.ParseScript_PostCheck;
|
||||
var
|
||||
s : String;
|
||||
hp : TCmdStrListItem;
|
||||
i : longint;
|
||||
begin
|
||||
hp:=TCmdStrListItem(linkscript.first);
|
||||
i:=0;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
inc(i);
|
||||
if not IsHandled^[i] then
|
||||
begin
|
||||
s:=hp.str;
|
||||
Comment(V_Warning,'"'+hp.str+
|
||||
'" internal linker script not handled');
|
||||
end;
|
||||
hp:=TCmdStrListItem(hp.next);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TInternalLinker.ParseScript_Load;
|
||||
@ -932,14 +977,22 @@ Implementation
|
||||
para,
|
||||
keyword : String;
|
||||
hp : TCmdStrListItem;
|
||||
i : longint;
|
||||
handled : boolean;
|
||||
begin
|
||||
exeoutput.Load_Start;
|
||||
hp:=TCmdStrListItem(linkscript.first);
|
||||
i:=0;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
inc(i);
|
||||
s:=hp.str;
|
||||
if (s='') or (s[1]='#') then
|
||||
continue;
|
||||
begin
|
||||
IsHandled^[i]:=true;
|
||||
continue;
|
||||
end;
|
||||
handled:=true;
|
||||
keyword:=Upper(GetToken(s,' '));
|
||||
para:=GetToken(s,' ');
|
||||
if keyword='SYMBOL' then
|
||||
@ -954,8 +1007,14 @@ Implementation
|
||||
ExeOutput.Load_ImageBase(para)
|
||||
else if keyword='READOBJECT' then
|
||||
Load_ReadObject(para)
|
||||
else if keyword='STABS' then
|
||||
UseStabs:=true
|
||||
else if keyword='READSTATICLIBRARY' then
|
||||
Load_ReadStaticLibrary(para);
|
||||
Load_ReadStaticLibrary(para)
|
||||
else
|
||||
handled:=false;
|
||||
if handled then
|
||||
IsHandled^[i]:=true;
|
||||
hp:=TCmdStrListItem(hp.next);
|
||||
end;
|
||||
end;
|
||||
@ -967,14 +1026,19 @@ Implementation
|
||||
para,
|
||||
keyword : String;
|
||||
hp : TCmdStrListItem;
|
||||
i : longint;
|
||||
handled : boolean;
|
||||
begin
|
||||
exeoutput.Order_Start;
|
||||
hp:=TCmdStrListItem(linkscript.first);
|
||||
i:=0;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
inc(i);
|
||||
s:=hp.str;
|
||||
if (s='') or (s[1]='#') then
|
||||
continue;
|
||||
handled:=true;
|
||||
keyword:=Upper(GetToken(s,' '));
|
||||
para:=GetToken(s,' ');
|
||||
if keyword='EXESECTION' then
|
||||
@ -996,7 +1060,11 @@ Implementation
|
||||
else if keyword='SYMBOL' then
|
||||
ExeOutput.Order_Symbol(para)
|
||||
else if keyword='PROVIDE' then
|
||||
ExeOutput.Order_ProvideSymbol(para);
|
||||
ExeOutput.Order_ProvideSymbol(para)
|
||||
else
|
||||
handled:=false;
|
||||
if handled then
|
||||
IsHandled^[i]:=true;
|
||||
hp:=TCmdStrListItem(hp.next);
|
||||
end;
|
||||
exeoutput.Order_End;
|
||||
@ -1009,14 +1077,19 @@ Implementation
|
||||
para,
|
||||
keyword : String;
|
||||
hp : TCmdStrListItem;
|
||||
i : longint;
|
||||
handled : boolean;
|
||||
begin
|
||||
exeoutput.MemPos_Start;
|
||||
hp:=TCmdStrListItem(linkscript.first);
|
||||
i:=0;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
inc(i);
|
||||
s:=hp.str;
|
||||
if (s='') or (s[1]='#') then
|
||||
continue;
|
||||
handled:=true;
|
||||
keyword:=Upper(GetToken(s,' '));
|
||||
para:=GetToken(s,' ');
|
||||
if keyword='EXESECTION' then
|
||||
@ -1024,7 +1097,11 @@ Implementation
|
||||
else if keyword='ENDEXESECTION' then
|
||||
ExeOutput.MemPos_EndExeSection
|
||||
else if keyword='HEADER' then
|
||||
ExeOutput.MemPos_Header;
|
||||
ExeOutput.MemPos_Header
|
||||
else
|
||||
handled:=false;
|
||||
if handled then
|
||||
IsHandled^[i]:=true;
|
||||
hp:=TCmdStrListItem(hp.next);
|
||||
end;
|
||||
end;
|
||||
@ -1036,14 +1113,19 @@ Implementation
|
||||
para,
|
||||
keyword : String;
|
||||
hp : TCmdStrListItem;
|
||||
i : longint;
|
||||
handled : boolean;
|
||||
begin
|
||||
exeoutput.DataPos_Start;
|
||||
hp:=TCmdStrListItem(linkscript.first);
|
||||
i:=0;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
inc(i);
|
||||
s:=hp.str;
|
||||
if (s='') or (s[1]='#') then
|
||||
continue;
|
||||
handled:=true;
|
||||
keyword:=Upper(GetToken(s,' '));
|
||||
para:=GetToken(s,' ');
|
||||
if keyword='EXESECTION' then
|
||||
@ -1053,7 +1135,11 @@ Implementation
|
||||
else if keyword='HEADER' then
|
||||
ExeOutput.DataPos_Header
|
||||
else if keyword='SYMBOLS' then
|
||||
ExeOutput.DataPos_Symbols;
|
||||
ExeOutput.DataPos_Symbols
|
||||
else
|
||||
handled:=false;
|
||||
if handled then
|
||||
IsHandled^[i]:=true;
|
||||
hp:=TCmdStrListItem(hp.next);
|
||||
end;
|
||||
end;
|
||||
@ -1099,6 +1185,8 @@ Implementation
|
||||
|
||||
PrintLinkerScript;
|
||||
|
||||
{ Check that syntax is OK }
|
||||
ParseScript_Handle;
|
||||
{ Load .o files and resolve symbols }
|
||||
ParseScript_Load;
|
||||
exeoutput.ResolveSymbols(StaticLibraryList);
|
||||
@ -1115,7 +1203,9 @@ Implementation
|
||||
{ Create .exe sections and add .o sections }
|
||||
ParseScript_Order;
|
||||
exeoutput.RemoveUnreferencedSections;
|
||||
exeoutput.MergeStabs;
|
||||
{ if UseStabs then, this would remove
|
||||
STABS for empty linker scripts }
|
||||
exeoutput.MergeStabs;
|
||||
exeoutput.RemoveEmptySections;
|
||||
if ErrorCount>0 then
|
||||
goto myexit;
|
||||
@ -1149,6 +1239,9 @@ Implementation
|
||||
exeoutput.WriteExeFile(outputname);
|
||||
end;
|
||||
|
||||
{ Post check that everything was handled }
|
||||
ParseScript_PostCheck;
|
||||
|
||||
{ TODO: fixed section names}
|
||||
status.codesize:=exeoutput.findexesection('.text').size;
|
||||
status.datasize:=exeoutput.findexesection('.data').size;
|
||||
|
Loading…
Reference in New Issue
Block a user