Explorar o código

+ Allow TObjRelocation to be created without a symbol, such relocations are being used to tag specific positions on non-x86 targets.
* Write relocation format dependent dynamic tags based on actual sh_type of dynamic relocation sections, instead of global relocs_use_addend flag.
* Don't write DT_REL[A]COUNT tag if .rel[a].dyn section is not present.

git-svn-id: trunk@23083 -

sergei %!s(int64=12) %!d(string=hai) anos
pai
achega
129d737523
Modificáronse 2 ficheiros con 17 adicións e 11 borrados
  1. 5 3
      compiler/ogbase.pas
  2. 12 8
      compiler/ogelf.pas

+ 5 - 3
compiler/ogbase.pas

@@ -121,6 +121,8 @@ interface
       rf_raw = 1;
       { relocation must be added to dynamic list }
       rf_dynamic = 2;
+      { relocation target is absent/irrelevant (e.g. R_ARM_V4BX) }
+      rf_nosymbol = 4;
 
     type
       TObjSectionOption = (
@@ -708,8 +710,7 @@ implementation
 
     constructor TObjRelocation.CreateRaw(ADataOffset:aword;s:TObjSymbol;ARawType:byte);
       begin
-        if not assigned(s) then
-          internalerror(2012091701);
+        { nil symbol is allowed here }
         DataOffset:=ADataOffset;
         Symbol:=s;
         ObjSection:=nil;
@@ -1465,6 +1466,7 @@ implementation
                 EntryArray[VTableIdx].OrgRelocType:=objreloc.ftype;
                 EntryArray[VTableIdx].OrgRelocFlags:=objreloc.flags;
                 objreloc.typ:=RELOC_ZERO;
+                objreloc.flags:=objreloc.flags or rf_nosymbol;
                 break;
               end;
           end;
@@ -2991,7 +2993,7 @@ implementation
           refobjsec : TObjSection;
         begin
           { Disabled Relocation to 0  }
-          if objreloc.typ=RELOC_ZERO then
+          if (objreloc.flags and rf_nosymbol)<>0 then
             exit;
           if assigned(objreloc.symbol) then
             begin

+ 12 - 8
compiler/ogelf.pas

@@ -1536,10 +1536,11 @@ implementation
             if relsym>=syms then
               InternalError(2012060204);
             p:=TObjSymbol(FSymTbl[relsym]);
-            if assigned(p) then
+            { Some relocations (e.g. R_ARM_V4BX) don't use a symbol at all }
+            if assigned(p) or (relsym=0) then
               begin
                 objrel:=TObjRelocation.CreateRaw(rel.address-secrec.sec.mempos,p,reltyp);
-                if relocs_use_addend then
+                if (secrec.relentsize=3*sizeof(pint)) then
                   objrel.orgsize:=rel.addend;
                 { perform target-specific actions }
                 ElfTarget.loadreloc(objrel);
@@ -3036,6 +3037,8 @@ implementation
       relcnttags: array[boolean] of longword=(DT_RELCOUNT,DT_RELACOUNT);
 
     procedure TElfExeOutput.FinishDynamicTags;
+      var
+        rela: boolean;
       begin
         if assigned(dynsymtable) then
           writeDynTag(DT_STRSZ,dynsymtable.fstrsec.size);
@@ -3046,18 +3049,19 @@ implementation
         if Assigned(pltrelocsec) and (pltrelocsec.size>0) then
           begin
             writeDynTag(DT_PLTRELSZ,pltrelocsec.Size);
-            writeDynTag(DT_PLTREL,pltreltags[relocs_use_addend]);
+            writeDynTag(DT_PLTREL,pltreltags[pltrelocsec.shtype=SHT_RELA]);
             writeDynTag(DT_JMPREL,pltrelocsec);
           end;
 
         if Assigned(dynrelocsec) and (dynrelocsec.size>0) then
           begin
-            writeDynTag(pltreltags[relocs_use_addend],dynrelocsec);
-            writeDynTag(relsztags[relocs_use_addend],dynrelocsec.Size);
-            writeDynTag(relenttags[relocs_use_addend],dynrelocsec.shentsize);
+            rela:=(dynrelocsec.shtype=SHT_RELA);
+            writeDynTag(pltreltags[rela],dynrelocsec);
+            writeDynTag(relsztags[rela],dynrelocsec.Size);
+            writeDynTag(relenttags[rela],dynrelocsec.shentsize);
+            if (relative_reloc_count>0) then
+              writeDynTag(relcnttags[rela],relative_reloc_count);
           end;
-        if (relative_reloc_count>0) then
-          writeDynTag(relcnttags[relocs_use_addend],relative_reloc_count);
         writeDynTag(DT_NULL,0);
       end;