+ Support assembling expressions ".long L2-L1" where label L1 belongs to the current objsection and L2 comes from any objsection. This is done using relative relocations and is compatible with GNU AS.

* Also fixed ogcoff.pas to handle these relative relocations correctly.

git-svn-id: trunk@21362 -
This commit is contained in:
sergei 2012-05-22 14:59:24 +00:00
parent dbc410de63
commit dc03282cb7
2 changed files with 23 additions and 7 deletions

View File

@ -1140,8 +1140,15 @@ Implementation
if assigned(objsymend.objsection) then
begin
if objsymend.objsection<>objsym.objsection then
internalerror(200404124);
Tai_const(hp).value:=objsymend.address-objsym.address+Tai_const(hp).symofs;
begin
{ leb128 relative constants are not relocatable, but other types are,
given that objsym belongs to the current section. }
if (Tai_const(hp).consttype in [aitconst_uleb128bit,aitconst_sleb128bit]) or
(objsym.objsection<>ObjData.CurrObjSec) then
InternalError(200404124);
end
else
Tai_const(hp).value:=objsymend.address-objsym.address+Tai_const(hp).symofs;
end;
end;
end;
@ -1257,8 +1264,13 @@ Implementation
objsym:=Objdata.SymbolRef(tai_const(hp).sym);
objsymend:=Objdata.SymbolRef(tai_const(hp).endsym);
if objsymend.objsection<>objsym.objsection then
internalerror(200905042);
Tai_const(hp).value:=objsymend.address-objsym.address+Tai_const(hp).symofs;
begin
if (Tai_const(hp).consttype in [aitconst_uleb128bit,aitconst_sleb128bit]) or
(objsym.objsection<>ObjData.CurrObjSec) then
internalerror(200905042);
end
else
Tai_const(hp).value:=objsymend.address-objsym.address+Tai_const(hp).symofs;
end;
ObjData.alloc(tai_const(hp).size);
end;
@ -1324,6 +1336,7 @@ Implementation
objsym,
objsymend : TObjSymbol;
zerobuf : array[0..63] of byte;
relative_reloc: boolean;
begin
fillchar(zerobuf,sizeof(zerobuf),0);
{ main loop }
@ -1388,11 +1401,13 @@ Implementation
begin
{ Recalculate relative symbols, addresses of forward references
can be changed in treepass1 }
relative_reloc:=false;
if assigned(tai_const(hp).sym) and
assigned(tai_const(hp).endsym) then
begin
objsym:=Objdata.SymbolRef(tai_const(hp).sym);
objsymend:=Objdata.SymbolRef(tai_const(hp).endsym);
relative_reloc:=(objsym.objsection<>objsymend.objsection);
Tai_const(hp).value:=objsymend.address-objsym.address+Tai_const(hp).symofs;
end;
case tai_const(hp).consttype of
@ -1404,6 +1419,8 @@ Implementation
if assigned(tai_const(hp).sym) and
not assigned(tai_const(hp).endsym) then
ObjData.writereloc(Tai_const(hp).symofs,tai_const(hp).size,Objdata.SymbolRef(tai_const(hp).sym),RELOC_ABSOLUTE)
else if relative_reloc then
ObjData.writereloc(ObjData.CurrObjSec.size+tai_const(hp).size-objsym.address+tai_const(hp).symofs,tai_const(hp).size,objsymend,RELOC_RELATIVE)
else
ObjData.writebytes(Tai_const(hp).value,tai_const(hp).size);
end;

View File

@ -1136,13 +1136,12 @@ const pemagic : array[0..3] of byte = (
else
begin
if (p.objsection<>nil) and
(p.bind<>AB_COMMON) and
(reloctype<>RELOC_RELATIVE) then
(p.bind<>AB_COMMON) then
CurrObjSec.addsectionreloc(curraddr,p.objsection,reloctype)
else
CurrObjSec.addsymreloc(curraddr,p,reloctype);
if (not win32) or
((reloctype<>RELOC_RELATIVE) and (p.objsection<>nil)) then
(p.objsection<>nil) then
inc(data,symaddr);
if reloctype=RELOC_RELATIVE then
begin