瀏覽代碼

+ 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 年之前
父節點
當前提交
fde944bf5d
共有 3 個文件被更改,包括 33 次插入32 次删除
  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
            the address of this code label is taken somewhere in the code
            so it must be taken care of it when creating pic
            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
        { 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,
        oso_executable,
        { Never discard section }
        { Never discard section }
        oso_keep,
        oso_keep,
-       { Special common symbols }
-       oso_common,
+       { Procedure Linkage Table specific treatment }
+       oso_plt,
        { Contains debug info and can be stripped }
        { Contains debug info and can be stripped }
        oso_debug,
        oso_debug,
        { Contains only strings }
        { Contains only strings }
@@ -178,7 +178,6 @@ interface
         typ        : TObjRelocationType;
         typ        : TObjRelocationType;
         size       : byte;
         size       : byte;
         constructor CreateSymbol(ADataOffset:aword;s:TObjSymbol;Atyp:TObjRelocationType);
         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);
         constructor CreateSection(ADataOffset:aword;aobjsec:TObjSection;Atyp:TObjRelocationType);
      end;
      end;
 
 
@@ -441,6 +440,7 @@ interface
         FExternalObjSymbols,
         FExternalObjSymbols,
         FCommonObjSymbols   : TFPObjectList;
         FCommonObjSymbols   : TFPObjectList;
         FProvidedObjSymbols : TFPObjectList;
         FProvidedObjSymbols : TFPObjectList;
+        FIndirectObjSymbols : TFPObjectList;
         FEntryName          : string;
         FEntryName          : string;
         FExeVTableList     : TFPObjectList;
         FExeVTableList     : TFPObjectList;
         { Objects }
         { Objects }
@@ -524,6 +524,7 @@ interface
         property UnresolvedExeSymbols:TFPObjectList read FUnresolvedExeSymbols;
         property UnresolvedExeSymbols:TFPObjectList read FUnresolvedExeSymbols;
         property ExternalObjSymbols:TFPObjectList read FExternalObjSymbols;
         property ExternalObjSymbols:TFPObjectList read FExternalObjSymbols;
         property CommonObjSymbols:TFPObjectList read FCommonObjSymbols;
         property CommonObjSymbols:TFPObjectList read FCommonObjSymbols;
+        property IndirectObjSymbols:TFPObjectList read FIndirectObjSymbols;
         property ExeVTableList:TFPObjectList read FExeVTableList;
         property ExeVTableList:TFPObjectList read FExeVTableList;
         property EntryName:string read FEntryName write FEntryName;
         property EntryName:string read FEntryName write FEntryName;
         property ImageBase:aword read FImageBase write FImageBase;
         property ImageBase:aword read FImageBase write FImageBase;
@@ -628,18 +629,6 @@ implementation
       end;
       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);
     constructor TObjRelocation.CreateSection(ADataOffset:aword;aobjsec:TObjSection;Atyp:TObjRelocationType);
       begin
       begin
         if not assigned(aobjsec) then
         if not assigned(aobjsec) then
@@ -1625,6 +1614,7 @@ implementation
         FExternalObjSymbols:=TFPObjectList.Create(false);
         FExternalObjSymbols:=TFPObjectList.Create(false);
         FCommonObjSymbols:=TFPObjectList.Create(false);
         FCommonObjSymbols:=TFPObjectList.Create(false);
         FProvidedObjSymbols:=TFPObjectList.Create(false);
         FProvidedObjSymbols:=TFPObjectList.Create(false);
+        FIndirectObjSymbols:=TFPObjectList.Create(false);
         FExeVTableList:=TFPObjectList.Create(false);
         FExeVTableList:=TFPObjectList.Create(false);
         { sections }
         { sections }
         FExeSectionList:=TFPHashObjectList.Create(true);
         FExeSectionList:=TFPHashObjectList.Create(true);
@@ -1647,6 +1637,7 @@ implementation
         UnresolvedExeSymbols.free;
         UnresolvedExeSymbols.free;
         ExternalObjSymbols.free;
         ExternalObjSymbols.free;
         FProvidedObjSymbols.free;
         FProvidedObjSymbols.free;
+        FIndirectObjSymbols.free;
         CommonObjSymbols.free;
         CommonObjSymbols.free;
         ExeVTableList.free;
         ExeVTableList.free;
         FExeSectionList.free;
         FExeSectionList.free;
@@ -1703,8 +1694,6 @@ implementation
         AddObjData(internalObjData);
         AddObjData(internalObjData);
         { Common Data section }
         { Common Data section }
         commonObjSection:=internalObjData.createsection(sec_bss,'');
         commonObjSection:=internalObjData.createsection(sec_bss,'');
-        { setting SecOptions acts as 'include' }
-        commonObjSection.SecOptions:=[oso_common];
       end;
       end;
 
 
 
 
@@ -2604,15 +2593,22 @@ implementation
           Fixing up symbols is done in the following steps:
           Fixing up symbols is done in the following steps:
            1. Update common references
            1. Update common references
            2. Update external 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
         for i:=0 to CommonObjSymbols.count-1 do
           begin
           begin
             objsym:=TObjSymbol(CommonObjSymbols[i]);
             objsym:=TObjSymbol(CommonObjSymbols[i]);
             if objsym.bind<>AB_COMMON then
             if objsym.bind<>AB_COMMON then
               internalerror(200606241);
               internalerror(200606241);
-            UpdateSymbol(objsym);
+
+            objsym.ObjSection:=objsym.ExeSymbol.ObjSymbol.ObjSection;
+            objsym.offset:=objsym.ExeSymbol.ObjSymbol.offset;
+            objsym.typ:=objsym.ExeSymbol.ObjSymbol.typ;
           end;
           end;
 
 
         { Step 2, Update externals }
         { Step 2, Update externals }
@@ -2622,7 +2618,15 @@ implementation
             if not (objsym.bind in [AB_EXTERNAL,AB_WEAK_EXTERNAL]) then
             if not (objsym.bind in [AB_EXTERNAL,AB_WEAK_EXTERNAL]) then
               internalerror(200606242);
               internalerror(200606242);
             UpdateSymbol(objsym);
             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;
           end;
+        CommonObjSymbols.Clear;
+        ExternalObjSymbols.Pack;
       end;
       end;
 
 
 
 

+ 5 - 12
compiler/ogcoff.pas

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