Browse Source

+ dwarf support for tls threadvars

git-svn-id: trunk@43134 -
florian 5 years ago
parent
commit
8ecdb2e9ca

+ 4 - 0
compiler/aasmtai.pas

@@ -151,6 +151,8 @@ interface
           aitconst_got,
           { offset of symbol itself from GOT }
           aitconst_gotoff_symbol,
+          { offset in TLS block }
+          aitconst_dtpoff,
           { ARM TLS code }
           aitconst_gottpoff,
           aitconst_tpoff,
@@ -2108,6 +2110,8 @@ implementation
             result:=4;
           aitconst_tlsdesc:
             result:=4;
+          aitconst_dtpoff:
+            result:=4;
           else
             internalerror(200603253);
         end;

+ 15 - 0
compiler/aggas.pas

@@ -1010,6 +1010,21 @@ implementation
                      writer.Asmln;
                    end;
 {$endif cpu64bitaddr}
+                 aitconst_dtpoff:
+                   begin
+{$ifdef arm}
+                     writer.AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(tlsldo)');
+                     writer.Asmln;
+{$endif arm}
+{$ifdef x86_64}
+                     writer.AsmWrite(#9'.long'#9+tai_const(hp).sym.name+'@dtpoff');
+                     writer.Asmln;
+{$endif x86_64}
+{$ifdef i386}
+                     writer.AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'@tdpoff');
+                     writer.Asmln;
+{$endif i386}
+                   end;
                  aitconst_got:
                    begin
                      if tai_const(hp).symofs<>0 then

+ 2 - 0
compiler/arm/cpuelf.pas

@@ -350,6 +350,8 @@ implementation
           result:=R_ARM_TLS_CALL;
         RELOC_ARM_CALL:
           result:=R_ARM_CALL;
+        RELOC_DTPOFF:
+          result:=R_ARM_TLS_LDO32;
       else
         InternalError(2012110602);
       end;

+ 3 - 0
compiler/assemble.pas

@@ -2080,6 +2080,9 @@ Implementation
                        ObjData.writereloc(Tai_const(hp).value,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_TLSDESC);
                      end;
 {$endif arm}
+                   aitconst_dtpoff:
+                     { so far, the size of dtpoff is fixed to 4 bytes }
+                     ObjData.writereloc(Tai_const(hp).symofs,4,Objdata.SymbolRef(tai_const(hp).sym),RELOC_DTPOFF);
                    aitconst_gotoff_symbol:
                      ObjData.writereloc(Tai_const(hp).symofs,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_GOTOFF);
                    aitconst_uleb128bit,

+ 36 - 8
compiler/dbgdwarf.pas

@@ -2653,15 +2653,43 @@ implementation
               case sym.typ of
                 staticvarsym:
                   begin
-                    if (vo_is_thread_var in sym.varoptions) then
+                    if vo_is_thread_var in sym.varoptions then
                       begin
-{ TODO: !!! FIXME: dwarf for thread vars !!!}
-{ This is only a minimal change to at least be able to get a value
-  in only one thread is present PM 2014-11-21, like for stabs format }
-                        templist.concat(tai_const.create_8bit(ord(DW_OP_addr)));
-                        templist.concat(tai_const.Create_type_name(aitconst_ptr_unaligned,sym.mangledname,
-                          offset+sizeof(pint)));
-                        blocksize:=1+sizeof(puint);
+                        if tf_section_threadvars in target_info.flags then
+                          begin
+                            case sizeof(puint) of
+                              2:
+                                templist.concat(tai_const.create_8bit(ord(DW_OP_const2u)));
+                              4:
+                                templist.concat(tai_const.create_8bit(ord(DW_OP_const4u)));
+                              8:
+                                templist.concat(tai_const.create_8bit(ord(DW_OP_const8u)));
+                              else
+                                Internalerror(2019100501);
+                            end;
+{$push}
+{$warn 6018 off}            { Unreachable code due to compile time evaluation }
+                            templist.concat(tai_const.Create_type_name(aitconst_dtpoff,sym.mangledname,0));
+                            { so far, aitconst_dtpoff is solely 32 bit }
+                            if (sizeof(puint)=8) and (target_info.endian=endian_little) then
+                              templist.concat(tai_const.create_32bit(0));
+                            templist.concat(tai_const.create_8bit(ord(DW_OP_GNU_push_tls_address)));
+                            if (sizeof(puint)=8) and (target_info.endian=endian_big) then
+                              templist.concat(tai_const.create_32bit(0));
+{$pop}
+
+                            blocksize:=2+sizeof(puint);
+                          end
+                        else
+                          begin
+                            { TODO: !!! FIXME: dwarf for thread vars !!!}
+                            { This is only a minimal change to at least be able to get a value
+                              in only one thread is present PM 2014-11-21, like for stabs format }
+                            templist.concat(tai_const.create_8bit(ord(DW_OP_addr)));
+                            templist.concat(tai_const.Create_type_name(aitconst_ptr_unaligned,sym.mangledname,
+                              offset+sizeof(pint)));
+                            blocksize:=1+sizeof(puint);
+                          end;
                       end
                     else
                       begin

+ 2 - 0
compiler/i386/cpuelf.pas

@@ -119,6 +119,8 @@ implementation
             InternalError(2019092101);
         RELOC_TLSGD:
           result:=R_386_TLS_GD;
+        RELOC_DTPOFF:
+          result:=R_386_TLS_DTPOFF32;
       else
         result:=0;
         InternalError(2012082301);

+ 3 - 1
compiler/ogbase.pas

@@ -115,7 +115,9 @@ interface
          { Relative to GOT/gp }
          RELOC_GOTOFF,
          { Untranslated target-specific value }
-         RELOC_RAW
+         RELOC_RAW,
+         { offset in TLS block }
+         RELOC_DTPOFF
       );
 
 {$if defined(x86_64)}

+ 10 - 3
compiler/x86_64/cpuelf.pas

@@ -180,9 +180,16 @@ implementation
             InternalError(2019091701);
         RELOC_TLSGD:
           result:=R_X86_64_TLSGD;
-      else
-        result:=0;
-        InternalError(2012082302);
+        RELOC_DTPOFF:
+          if objrel.size=8 then
+            result:=R_X86_64_DTPOFF64
+          else if objrel.size=4 then
+            result:=R_X86_64_DTPOFF32
+          else
+            InternalError(2019091701);
+        else
+          result:=0;
+          InternalError(2012082302);
       end;
     end;