فهرست منبع

+ support tls threadvars with the internal assembler

git-svn-id: trunk@43070 -
florian 5 سال پیش
والد
کامیت
56d91b4ca7
5فایلهای تغییر یافته به همراه34 افزوده شده و 13 حذف شده
  1. 7 0
      compiler/i386/cpuelf.pas
  2. 5 0
      compiler/ogbase.pas
  3. 3 3
      compiler/ogelf.pas
  4. 19 3
      compiler/x86/aasmcpu.pas
  5. 0 7
      rtl/linux/i386/si_prc.inc

+ 7 - 0
compiler/i386/cpuelf.pas

@@ -112,6 +112,13 @@ implementation
           result:=R_386_PLT32;
           result:=R_386_PLT32;
         RELOC_GOTOFF:
         RELOC_GOTOFF:
           result:=R_386_GOTOFF;
           result:=R_386_GOTOFF;
+        RELOC_NTPOFF:
+          if objrel.size=4 then
+            result:=R_386_TLS_LE
+          else
+            InternalError(2019092101);
+        RELOC_TLSGD:
+          result:=R_386_TLS_GD;
       else
       else
         result:=0;
         result:=0;
         InternalError(2012082301);
         InternalError(2012082301);

+ 5 - 0
compiler/ogbase.pas

@@ -68,6 +68,8 @@ interface
          RELOC_GOTPC,
          RELOC_GOTPC,
          RELOC_GOT32,
          RELOC_GOT32,
          RELOC_PLT32,
          RELOC_PLT32,
+         RELOC_TLSGD,
+         RELOC_NTPOFF,
 {$endif i386}
 {$endif i386}
 {$ifdef i8086}
 {$ifdef i8086}
          RELOC_ABSOLUTE32,
          RELOC_ABSOLUTE32,
@@ -1410,6 +1412,9 @@ implementation
             { The weak bit could have been removed from asmsym. }
             { The weak bit could have been removed from asmsym. }
             if (asmsym.bind=AB_EXTERNAL) and (result.bind=AB_WEAK_EXTERNAL) then
             if (asmsym.bind=AB_EXTERNAL) and (result.bind=AB_WEAK_EXTERNAL) then
               result.bind:=AB_EXTERNAL;
               result.bind:=AB_EXTERNAL;
+            { the TLS type needs to be inherited }
+            if asmsym.typ=AT_TLS then
+              result.typ:=AT_TLS;
           end
           end
         else
         else
           result:=nil;
           result:=nil;

+ 3 - 3
compiler/ogelf.pas

@@ -666,7 +666,7 @@ implementation
         if assigned(objreloc) then
         if assigned(objreloc) then
           begin
           begin
             objreloc.size:=len;
             objreloc.size:=len;
-            if reltype in [RELOC_RELATIVE{$ifdef x86},RELOC_PLT32{$endif}{$ifdef x86_64},RELOC_GOTPCREL,RELOC_TLSGD{$endif}] then
+            if reltype in [RELOC_RELATIVE{$ifdef x86},RELOC_PLT32{$endif}{$ifdef x86_64},RELOC_TLSGD,RELOC_GOTPCREL{$endif}] then
               dec(data,len);
               dec(data,len);
             if ElfTarget.relocs_use_addend then
             if ElfTarget.relocs_use_addend then
               begin
               begin
@@ -785,8 +785,8 @@ implementation
         else
         else
           InternalError(2012111801);
           InternalError(2012111801);
         end;
         end;
-        { External symbols must be NOTYPE in relocatable files }
-        if (objsym.bind<>AB_EXTERNAL) or (kind<>esk_obj) then
+        { External symbols must be NOTYPE in relocatable files except if they are TLS symbols }
+        if (objsym.bind<>AB_EXTERNAL) or (kind<>esk_obj) or (objsym.typ=AT_TLS) then
           begin
           begin
             case objsym.typ of
             case objsym.typ of
               AT_FUNCTION :
               AT_FUNCTION :

+ 19 - 3
compiler/x86/aasmcpu.pas

@@ -1510,11 +1510,11 @@ implementation
                 end;
                 end;
               top_ref :
               top_ref :
                 begin
                 begin
-                  if (ref^.refaddr in [addr_no{$ifdef x86_64},addr_tpoff{$endif x86_64}])
+                  if (ref^.refaddr in [addr_no{$ifdef x86_64},addr_tpoff{$endif x86_64}{$ifdef i386},addr_ntpoff{$endif i386}])
 {$ifdef i386}
 {$ifdef i386}
                      or (
                      or (
-                         (ref^.refaddr in [addr_pic]) and
-                         (ref^.base<>NR_NO)
+                         (ref^.refaddr in [addr_pic,addr_tlsgd]) and
+                         ((ref^.base<>NR_NO) or (ref^.index<>NR_NO))
                         )
                         )
 {$endif i386}
 {$endif i386}
 {$ifdef x86_64}
 {$ifdef x86_64}
@@ -3577,6 +3577,18 @@ implementation
                       currabsreloc:=RELOC_GOT32;
                       currabsreloc:=RELOC_GOT32;
                       currabsreloc32:=RELOC_GOT32;
                       currabsreloc32:=RELOC_GOT32;
                     end
                     end
+                  else if oper[opidx]^.ref^.refaddr=addr_ntpoff then
+                    begin
+                      currrelreloc:=RELOC_NTPOFF;
+                      currabsreloc:=RELOC_NTPOFF;
+                      currabsreloc32:=RELOC_NTPOFF;
+                    end
+                  else if oper[opidx]^.ref^.refaddr=addr_tlsgd then
+                    begin
+                      currrelreloc:=RELOC_TLSGD;
+                      currabsreloc:=RELOC_TLSGD;
+                      currabsreloc32:=RELOC_TLSGD;
+                    end
                   else
                   else
 {$endif i386}
 {$endif i386}
 {$ifdef x86_64}
 {$ifdef x86_64}
@@ -4565,6 +4577,10 @@ implementation
                          if (oper[opidx]^.ref^.refaddr=addr_pic) and
                          if (oper[opidx]^.ref^.refaddr=addr_pic) and
                             (tf_pic_uses_got in target_info.flags) then
                             (tf_pic_uses_got in target_info.flags) then
                            currabsreloc:=RELOC_GOT32
                            currabsreloc:=RELOC_GOT32
+                         else if oper[opidx]^.ref^.refaddr=addr_tlsgd then
+                           currabsreloc:=RELOC_TLSGD
+                         else if oper[opidx]^.ref^.refaddr=addr_ntpoff then
+                           currabsreloc:=RELOC_NTPOFF
                          else
                          else
 {$endif i386}
 {$endif i386}
 {$ifdef i8086}
 {$ifdef i8086}

+ 0 - 7
rtl/linux/i386/si_prc.inc

@@ -47,13 +47,6 @@ function fpc_geteipasebxlocal : pointer; [external name 'fpc_geteipasebx'];
 
 
 procedure InitTLS; [external name 'FPC_INITTLS'];
 procedure InitTLS; [external name 'FPC_INITTLS'];
 
 
-
-{ so far, I found no case where this is actually called, so it is a dummy so far (FK) }
-function ___tls_get_addr(p : pointer) : pointer; public name '___tls_get_addr';
-  begin
-  end;
-
-
 procedure _FPC_proc_start; assembler; nostackframe; public name '_start';
 procedure _FPC_proc_start; assembler; nostackframe; public name '_start';
 asm
 asm
   { First locate the start of the environment variables }
   { First locate the start of the environment variables }