diff options
author | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2020-06-01 21:07:21 +0000 |
---|---|---|
committer | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2020-06-01 21:07:21 +0000 |
commit | a5df9e9c322658257ac98ede16d8cea63aefbb2e (patch) | |
tree | 586a5bf2de527e0b56dd7b3a2953dc194c501eff /compiler/ogrel.pas | |
parent | 020b4c86fed07c83bd7b335f00386fca4ea91eb0 (diff) | |
download | fpc-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.pas | 80 |
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 |