Pārlūkot izejas kodu

+ 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 -

sergei 13 gadi atpakaļ
vecāks
revīzija
dc03282cb7
2 mainītis faili ar 23 papildinājumiem un 7 dzēšanām
  1. 21 4
      compiler/assemble.pas
  2. 2 3
      compiler/ogcoff.pas

+ 21 - 4
compiler/assemble.pas

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

+ 2 - 3
compiler/ogcoff.pas

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