From 8ecdb2e9ca9b32f1334f237612411e7e17e5d1e6 Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 5 Oct 2019 20:48:31 +0000 Subject: [PATCH] + dwarf support for tls threadvars git-svn-id: trunk@43134 - --- compiler/aasmtai.pas | 4 ++++ compiler/aggas.pas | 15 +++++++++++++ compiler/arm/cpuelf.pas | 2 ++ compiler/assemble.pas | 3 +++ compiler/dbgdwarf.pas | 44 +++++++++++++++++++++++++++++++------- compiler/i386/cpuelf.pas | 2 ++ compiler/ogbase.pas | 4 +++- compiler/x86_64/cpuelf.pas | 13 ++++++++--- 8 files changed, 75 insertions(+), 12 deletions(-) diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas index 0304b497d1..92bfcbfbce 100644 --- a/compiler/aasmtai.pas +++ b/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; diff --git a/compiler/aggas.pas b/compiler/aggas.pas index a0a2f578a0..262647dc44 100644 --- a/compiler/aggas.pas +++ b/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 diff --git a/compiler/arm/cpuelf.pas b/compiler/arm/cpuelf.pas index ff38e7ebe8..ad48f706e4 100644 --- a/compiler/arm/cpuelf.pas +++ b/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; diff --git a/compiler/assemble.pas b/compiler/assemble.pas index e5f03756c3..e415e0b772 100644 --- a/compiler/assemble.pas +++ b/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, diff --git a/compiler/dbgdwarf.pas b/compiler/dbgdwarf.pas index beeeec9c0f..85a754bac2 100644 --- a/compiler/dbgdwarf.pas +++ b/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 diff --git a/compiler/i386/cpuelf.pas b/compiler/i386/cpuelf.pas index c55917a660..ab5a60124d 100644 --- a/compiler/i386/cpuelf.pas +++ b/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); diff --git a/compiler/ogbase.pas b/compiler/ogbase.pas index 615610addb..2dc717a837 100644 --- a/compiler/ogbase.pas +++ b/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)} diff --git a/compiler/x86_64/cpuelf.pas b/compiler/x86_64/cpuelf.pas index 41be366b2e..3d426286e5 100644 --- a/compiler/x86_64/cpuelf.pas +++ b/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;