Browse Source

+ Declare AT_TLS and AT_GNU_IFUNC symbol types, these are needed to handle object files created by gcc in ELF internal linker.
* TExeOutput.FixupSymbols:
+ Collect AT_GNU_IFUNC symbols in IndirectObjSymbols list for further processing by ELF back-end.
* Do not overwrite bind and size while fixing AB_COMMON symbols, this removes need in storing symbol size in every relocation and dedicated handling of oso_common section.
* Remove symbols with objsection<>nil from lists, so calling FixupSymbols several times skips already processed symbols.

git-svn-id: trunk@22393 -

sergei 13 năm trước cách đây
mục cha
commit
fde944bf5d
3 tập tin đã thay đổi với 33 bổ sung32 xóa
  1. 5 1
      compiler/aasmbase.pas
  2. 23 19
      compiler/ogbase.pas
  3. 5 12
      compiler/ogcoff.pas

+ 5 - 1
compiler/aasmbase.pas

@@ -48,7 +48,11 @@ interface
            the address of this code label is taken somewhere in the code
            so it must be taken care of it when creating pic
          }
-         AT_ADDR
+         AT_ADDR,
+         { Thread-local symbol (ELF targets) }
+         AT_TLS,
+         { GNU indirect function (ELF targets) }
+         AT_GNU_IFUNC
          );
 
        { is the label only there for getting an DataOffset (e.g. for i/o

+ 23 - 19
compiler/ogbase.pas

@@ -126,8 +126,8 @@ interface
        oso_executable,
        { Never discard section }
        oso_keep,
-       { Special common symbols }
-       oso_common,
+       { Procedure Linkage Table specific treatment }
+       oso_plt,
        { Contains debug info and can be stripped }
        oso_debug,
        { Contains only strings }
@@ -178,7 +178,6 @@ interface
         typ        : TObjRelocationType;
         size       : byte;
         constructor CreateSymbol(ADataOffset:aword;s:TObjSymbol;Atyp:TObjRelocationType);
-        constructor CreateSymbolSize(ADataOffset:aword;s:TObjSymbol;Aorgsize:aword;Atyp:TObjRelocationType);
         constructor CreateSection(ADataOffset:aword;aobjsec:TObjSection;Atyp:TObjRelocationType);
      end;
 
@@ -441,6 +440,7 @@ interface
         FExternalObjSymbols,
         FCommonObjSymbols   : TFPObjectList;
         FProvidedObjSymbols : TFPObjectList;
+        FIndirectObjSymbols : TFPObjectList;
         FEntryName          : string;
         FExeVTableList     : TFPObjectList;
         { Objects }
@@ -524,6 +524,7 @@ interface
         property UnresolvedExeSymbols:TFPObjectList read FUnresolvedExeSymbols;
         property ExternalObjSymbols:TFPObjectList read FExternalObjSymbols;
         property CommonObjSymbols:TFPObjectList read FCommonObjSymbols;
+        property IndirectObjSymbols:TFPObjectList read FIndirectObjSymbols;
         property ExeVTableList:TFPObjectList read FExeVTableList;
         property EntryName:string read FEntryName write FEntryName;
         property ImageBase:aword read FImageBase write FImageBase;
@@ -628,18 +629,6 @@ implementation
       end;
 
 
-    constructor TObjRelocation.CreateSymbolSize(ADataOffset:aword;s:TObjSymbol;Aorgsize:aword;Atyp:TObjRelocationType);
-      begin
-        if not assigned(s) then
-          internalerror(200603035);
-        DataOffset:=ADataOffset;
-        Symbol:=s;
-        OrgSize:=Aorgsize;
-        ObjSection:=nil;
-        Typ:=Atyp;
-      end;
-
-
     constructor TObjRelocation.CreateSection(ADataOffset:aword;aobjsec:TObjSection;Atyp:TObjRelocationType);
       begin
         if not assigned(aobjsec) then
@@ -1625,6 +1614,7 @@ implementation
         FExternalObjSymbols:=TFPObjectList.Create(false);
         FCommonObjSymbols:=TFPObjectList.Create(false);
         FProvidedObjSymbols:=TFPObjectList.Create(false);
+        FIndirectObjSymbols:=TFPObjectList.Create(false);
         FExeVTableList:=TFPObjectList.Create(false);
         { sections }
         FExeSectionList:=TFPHashObjectList.Create(true);
@@ -1647,6 +1637,7 @@ implementation
         UnresolvedExeSymbols.free;
         ExternalObjSymbols.free;
         FProvidedObjSymbols.free;
+        FIndirectObjSymbols.free;
         CommonObjSymbols.free;
         ExeVTableList.free;
         FExeSectionList.free;
@@ -1703,8 +1694,6 @@ implementation
         AddObjData(internalObjData);
         { Common Data section }
         commonObjSection:=internalObjData.createsection(sec_bss,'');
-        { setting SecOptions acts as 'include' }
-        commonObjSection.SecOptions:=[oso_common];
       end;
 
 
@@ -2604,15 +2593,22 @@ implementation
           Fixing up symbols is done in the following steps:
            1. Update common references
            2. Update external references
+
+           Symbols with objsection<>nil are removed from the lists,
+           remaining ones can be processed later by calling this method again.
         }
 
-        { Step 1, Update commons }
+        { Step 1, Update commons. Preserve the original symbol size and bind,
+          this is needed for correct relocation of DJCOFF files. }
         for i:=0 to CommonObjSymbols.count-1 do
           begin
             objsym:=TObjSymbol(CommonObjSymbols[i]);
             if objsym.bind<>AB_COMMON then
               internalerror(200606241);
-            UpdateSymbol(objsym);
+
+            objsym.ObjSection:=objsym.ExeSymbol.ObjSymbol.ObjSection;
+            objsym.offset:=objsym.ExeSymbol.ObjSymbol.offset;
+            objsym.typ:=objsym.ExeSymbol.ObjSymbol.typ;
           end;
 
         { Step 2, Update externals }
@@ -2622,7 +2618,15 @@ implementation
             if not (objsym.bind in [AB_EXTERNAL,AB_WEAK_EXTERNAL]) then
               internalerror(200606242);
             UpdateSymbol(objsym);
+            { Collect symbols that resolve to indirect functions,
+              they will need additional target-specific processing. }
+            if objsym.typ=AT_GNU_IFUNC then
+              IndirectObjSymbols.Add(objsym)
+            else if assigned(objsym.objsection) then
+              ExternalObjSymbols[i]:=nil;
           end;
+        CommonObjSymbols.Clear;
+        ExternalObjSymbols.Pack;
       end;
 
 

+ 5 - 12
compiler/ogcoff.pas

@@ -108,7 +108,6 @@ interface
          coffrelocpos : aword;
        public
          constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);override;
-         procedure addsymsizereloc(ofs:aword;p:TObjSymbol;symsize:aword;reloctype:TObjRelocationType);
          procedure writereloc_internal(aTarget:TObjSection;offset:aword;len:byte;reltype:TObjRelocationType);override;
        end;
 
@@ -806,12 +805,6 @@ const pemagic : array[0..3] of byte = (
       end;
 
 
-    procedure TCoffObjSection.addsymsizereloc(ofs:aword;p:TObjSymbol;symsize:aword;reloctype:TObjRelocationType);
-      begin
-        ObjRelocations.Add(TObjRelocation.createsymbolsize(ofs,p,symsize,reloctype));
-      end;
-
-
     procedure TCoffObjSection.writereloc_internal(aTarget:TObjSection;offset:aword;len:byte;reltype:TObjRelocationType);
       begin
         AddSectionReloc(size,aTarget,reltype);
@@ -877,7 +870,7 @@ const pemagic : array[0..3] of byte = (
                 RELOC_RELATIVE  :
                   begin
                     address:=address-objsec.mempos+relocval;
-                    if TCoffObjData(objsec.objdata).win32 then
+                    if win32 then
                       dec(address,objreloc.dataoffset+4);
                   end;
                 RELOC_RVA:
@@ -940,10 +933,10 @@ const pemagic : array[0..3] of byte = (
 {$endif x86_64}
                 RELOC_ABSOLUTE :
                   begin
-                    if oso_common in relocsec.secoptions then
+                    if (not win32) and assigned(objreloc.symbol) and
+                      (objreloc.symbol.bind=AB_COMMON) then
                       begin
-                        if (not win32) then
-                          dec(address,objreloc.orgsize);
+                        dec(address,objreloc.symbol.size);
                       end
                     else
                       begin
@@ -1584,7 +1577,7 @@ const pemagic : array[0..3] of byte = (
 
            p:=FSymTbl^[rel.sym];
            if assigned(p) then
-             s.addsymsizereloc(rel.address-s.mempos,p,p.size,rel_type)
+             s.addsymreloc(rel.address-s.mempos,p,rel_type)
            else
             begin
               InputError('Failed reading coff file, can''t resolve symbol of relocation');