summaryrefslogtreecommitdiff
path: root/compiler/ogrel.pas
diff options
context:
space:
mode:
authornickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2020-06-01 21:07:21 +0000
committernickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2020-06-01 21:07:21 +0000
commita5df9e9c322658257ac98ede16d8cea63aefbb2e (patch)
tree586a5bf2de527e0b56dd7b3a2953dc194c501eff /compiler/ogrel.pas
parent020b4c86fed07c83bd7b335f00386fca4ea91eb0 (diff)
downloadfpc-a5df9e9c322658257ac98ede16d8cea63aefbb2e.tar.gz
+ parse the REL symbol records
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@45556 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/ogrel.pas')
-rw-r--r--compiler/ogrel.pas80
1 files changed, 77 insertions, 3 deletions
diff --git a/compiler/ogrel.pas b/compiler/ogrel.pas
index 6fa4eb2031..17ad4414f2 100644
--- a/compiler/ogrel.pas
+++ b/compiler/ogrel.pas
@@ -660,12 +660,14 @@ implementation
const
GenericRelErrMsg='Error reading REL file';
var
- s, AreaName: string;
+ s, AreaName, SymbolName: string;
RecType: Char;
HeaderFound: Boolean=false;
- ExpectedAreas,ExpectedSymbols,AreaSize,AreaFlags,AreaAddr: LongInt;
+ ExpectedAreas,ExpectedSymbols,AreaSize,AreaFlags,AreaAddr,
+ SymbolOfs: LongInt;
tmpint: SizeInt;
CurrSec: TObjSection=nil;
+ objsym: TObjSymbol;
begin
FReader:=AReader;
InputFileName:=AReader.FileName;
@@ -743,7 +745,79 @@ implementation
end;
'S': { symbol }
begin
- { todo: implement }
+ if not HeaderFound then
+ begin
+ InputError('Symbol record encountered before header');
+ exit;
+ end;
+ tmpint:=Pos(' ',s);
+ if tmpint<=1 then
+ begin
+ InputError('Invalid symbol record');
+ exit;
+ end;
+ SymbolName:=copy(s,1,tmpint-1);
+ delete(s,1,tmpint);
+ if Length(s)<4 then
+ begin
+ InputError('Invalid symbol record');
+ exit;
+ end;
+ if not TryStrToInt('$'+Copy(s,4,Length(s)-4),SymbolOfs) then
+ begin
+ InputError('Invalid symbol offset');
+ exit;
+ end;
+ case Copy(s,1,3) of
+ 'Def':
+ begin
+ if CurrSec=nil then
+ begin
+ InputError('Public symbol defined outside any area');
+ exit;
+ end;
+ if (SymbolOfs<0) or (SymbolOfs>=CurrSec.Size) then
+ begin
+ InputError('Public symbol offset outside the range of the current area');
+ exit;
+ end;
+ objsym:=Data.CreateSymbol(SymbolName);
+ objsym.bind:=AB_GLOBAL;
+ objsym.typ:=AT_FUNCTION;
+ objsym.objsection:=CurrSec;
+ objsym.offset:=SymbolOfs;
+ objsym.size:=0;
+ end;
+ 'Ref':
+ begin
+ if CurrSec<>nil then
+ begin
+ InputError('External symbols must be defined before the first area');
+ exit;
+ end;
+ if SymbolOfs<>0 then
+ begin
+ InputError('External symbols must be declared with an offset of 0');
+ exit;
+ end;
+ objsym:=Data.CreateSymbol(SymbolName);
+ objsym.bind:=AB_EXTERNAL;
+ objsym.typ:=AT_FUNCTION;
+ objsym.objsection:=nil;
+ objsym.offset:=0;
+ objsym.size:=0;
+ end;
+ else
+ begin
+ InputError('Invalid or unsupported symbol record');
+ exit;
+ end;
+ end;
+ if Data.ObjSymbolList.Count>ExpectedSymbols then
+ begin
+ InputError('Number of symbols exceeds the number, declared in header');
+ exit;
+ end;
end;
'A': { area }
begin