+ Add checks for internal linker script

git-svn-id: trunk@17882 -
This commit is contained in:
pierre 2011-06-30 13:16:04 +00:00
parent 0227fbad7d
commit f328836cad

View File

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