From 6afda909d456542c27ca7f0a1a82a8eec6e3d7ff Mon Sep 17 00:00:00 2001 From: svenbarth Date: Fri, 12 Feb 2016 17:03:52 +0000 Subject: [PATCH] Rework TlsKey handling on Windows so that it works as intended with indirect main information rtl/inc/system.inc: * SetupEntryInformation: call new, optional function OSSetupEntryInformation to handle platform specific entry information initialization rtl/win/sysosh.inc, TEntryInformationOS: + new field TlsKeyAddr which will hold the address to the main binary's TlsKey variable win32/sysinit.inc: + provide the variable holding the TlsKey and pass that on to the entry information record win32/system.pp: + new OS specific entry information initialization (currently only the TlsKey) win/systhrd.inc: * declare TlsKey as a pointer to a DWord value instead of a DWord; on non-indirect entry platforms this is initialized with the address of new variable TlsKeyVar, on indirect entry platforms it will be initialized by the entry information initialization * adjust usages of TlsKey from DWord to PDWord win/systlsdir.inc: * TlsKey is now a PDWord and (in sysinit) points to TlsKeyVar win/syswin.inc: * adjust TlsKey usage inc/heaptrc.pp: * TlsKey is now a PDWord, thus adjust the import and the usage git-svn-id: trunk@33091 - --- rtl/inc/heaptrc.pp | 6 +++--- rtl/inc/system.inc | 3 +++ rtl/win/sysosh.inc | 1 + rtl/win/systhrd.inc | 33 +++++++++++++++++++-------------- rtl/win/systlsdir.inc | 4 ++-- rtl/win/syswin.inc | 2 +- rtl/win32/sysinit.inc | 3 +++ rtl/win32/system.pp | 7 +++++++ 8 files changed, 39 insertions(+), 20 deletions(-) diff --git a/rtl/inc/heaptrc.pp b/rtl/inc/heaptrc.pp index dd1de0d10a..169398441f 100644 --- a/rtl/inc/heaptrc.pp +++ b/rtl/inc/heaptrc.pp @@ -915,7 +915,7 @@ var edata : ptruint; external name '__data_end__'; sbss : ptruint; external name '__bss_start__'; ebss : ptruint; external name '__bss_end__'; - TLSKey : DWord; external name '_FPC_TlsKey'; + TLSKey : PDWord; external name '_FPC_TlsKey'; TLSSize : DWord; external name '_FPC_TlsSize'; function TlsGetValue(dwTlsIndex : DWord) : pointer; @@ -989,9 +989,9 @@ begin if (ptruint(p)>=ptruint(@sbss)) and (ptruint(p)-1 then + if TlsKey^<>-1 then begin - datap:=TlsGetValue(tlskey); + datap:=TlsGetValue(tlskey^); if ((ptruint(p)>=ptruint(datap)) and (ptruint(p)$ffffffff then - TlsFree(TLSKey); - TLSKey:=$ffffffff; + if TLSKey^<>$ffffffff then + TlsFree(TLSKey^); + TLSKey^:=$ffffffff; end; function SysRelocateThreadvar(offset : dword) : pointer; @@ -165,11 +170,11 @@ var errorsave : dword; begin errorsave:=GetLastError; - dataindex:=TlsGetValue(tlskey); + dataindex:=TlsGetValue(tlskey^); if dataindex=nil then begin SysAllocateThreadVars; - dataindex:=TlsGetValue(tlskey); + dataindex:=TlsGetValue(tlskey^); InitThread($1000000); end; SetLastError(errorsave); @@ -181,12 +186,12 @@ var var p: pointer; begin - if TLSKey<>$ffffffff then + if TLSKey^<>$ffffffff then begin - p:=TlsGetValue(tlskey); + p:=TlsGetValue(tlskey^); if Assigned(p) then LocalFree(p); - TlsSetValue(tlskey, nil); + TlsSetValue(tlskey^, nil); end; end; diff --git a/rtl/win/systlsdir.inc b/rtl/win/systlsdir.inc index 5fdcbb67e3..5fe7b2a903 100644 --- a/rtl/win/systlsdir.inc +++ b/rtl/win/systlsdir.inc @@ -33,7 +33,7 @@ Const DLL_THREAD_DETACH = 3; var - TlsKey : dword; external name '_FPC_TlsKey'; + TlsKey : PDWord = @TlsKeyVar; type TTlsDirectory=packed record @@ -107,7 +107,7 @@ procedure Exec_Tls_callback(Handle : pointer; reason : Dword; Reserved : pointer end; DLL_THREAD_DETACH : begin - if TlsGetValue(TLSKey)<>nil then + if TlsGetValue(TLSKey^)<>nil then DoneThread; { Assume everything is idempotent there } end; end; diff --git a/rtl/win/syswin.inc b/rtl/win/syswin.inc index e1ca86edf3..1d2353972c 100644 --- a/rtl/win/syswin.inc +++ b/rtl/win/syswin.inc @@ -400,7 +400,7 @@ function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntry if assigned(Dll_Thread_Detach_Hook) then Dll_Thread_Detach_Hook(DllParam); { Release Threadvars } - if TlsGetValue(TLSKey)<>nil then + if TlsGetValue(TLSKey^)<>nil then DoneThread; { Assume everything is idempotent there } end; DLL_PROCESS_DETACH : diff --git a/rtl/win32/sysinit.inc b/rtl/win32/sysinit.inc index e304bce3a1..e78fbf35f7 100644 --- a/rtl/win32/sysinit.inc +++ b/rtl/win32/sysinit.inc @@ -16,6 +16,7 @@ var SysInstance : Longint;external name '_FPC_SysInstance'; + TlsKeyVar: DWord = $ffffffff; InitFinalTable : record end; external name 'INITFINAL'; ThreadvarTablesTable : record end; external name 'FPC_THREADVARTABLES'; @@ -65,6 +66,7 @@ valgrind_used : false; OS : ( asm_exit : @asm_exit; + TlsKeyAddr : @TlsKeyVar; ); ); @@ -78,6 +80,7 @@ EntryInformation.ResStrInitTables:=@ResStrInitTables; EntryInformation.WideInitTables:=@WideInitTables; EntryInformation.OS.asm_exit:=@asm_exit; + EntryInformation.OS.TlsKeyAddr:=@TlsKeyVar; EntryInformation.PascalMain:=@PascalMain;} SysInitEntryInformation.valgrind_used:=valgrind_used; end; diff --git a/rtl/win32/system.pp b/rtl/win32/system.pp index 3287e0f7c7..60b4c1f82a 100644 --- a/rtl/win32/system.pp +++ b/rtl/win32/system.pp @@ -113,6 +113,9 @@ implementation var SysInstance : Longint;public name '_FPC_SysInstance'; +{$define FPC_SYSTEM_HAS_OSSETUPENTRYINFORMATION} +procedure OsSetupEntryInformation(const info: TEntryInformation); forward; + {$ifdef FPC_USE_WIN32_SEH} function main_wrapper(arg: Pointer; proc: Pointer): ptrint; forward; procedure OutermostHandler; external name '__FPC_DEFAULT_HANDLER'; @@ -130,6 +133,10 @@ end; { include code common with win64 } {$I syswin.inc} +procedure OsSetupEntryInformation(const info: TEntryInformation); +begin + TlsKey := info.OS.TlsKeyAddr; +end; {***************************************************************************** System Dependent Exit code