From ad94e5e719f7471000868dfd3ced02a382779594 Mon Sep 17 00:00:00 2001 From: sergei Date: Wed, 27 Jul 2011 23:22:09 +0000 Subject: [PATCH] * Link TLS directory and callbacks only into executables. It is not necessary for DLLs, because callback functionality is contained in DllMain. Moreover, DLLs with TLS directory cannot be dynamically loaded in Windows versions prior to Vista. * In Win32, reference TLS directory from SysInit units, allowing the module which needs TLS to be different from module which contains system unit. * Don't write to TLS directory, as it can be placed into read-only memory. git-svn-id: trunk@18028 - --- rtl/win32/sysinit.inc | 15 +++++++++++++ rtl/win32/sysinitcyg.pp | 3 +++ rtl/win32/sysinitgprof.pp | 3 +++ rtl/win32/sysinitpas.pp | 6 +++++ rtl/win32/system.pp | 9 -------- rtl/win64/system.pp | 47 +++++++++++++++++++++------------------ 6 files changed, 52 insertions(+), 31 deletions(-) diff --git a/rtl/win32/sysinit.inc b/rtl/win32/sysinit.inc index 4c3118b7a5..e852a13395 100644 --- a/rtl/win32/sysinit.inc +++ b/rtl/win32/sysinit.inc @@ -22,6 +22,21 @@ ThreadvarTablesTable : record end; external name 'FPC_THREADVARTABLES'; valgrind_used : boolean;external name '__fpc_valgrind'; +{$if defined(FPC_USE_TLS_DIRECTORY) or defined(FPC_SECTION_THREADVARS)} + var + tlsdir: record end; external name '__tls_used'; + + procedure LinkIn(p1,p2,p3: Pointer); inline; + begin + end; +{$endif} + +{$ifdef FPC_USE_TLS_DIRECTORY} + var + tls_callback_end: pointer; external name '__FPC_end_of_tls_callbacks'; + tls_callback: pointer; external name '__FPC_tls_callbacks'; +{$endif FPC_USE_TLS_DIRECTORY} + procedure EXE_Entry(const info : TEntryInformation); external name '_FPC_EXE_Entry'; function DLL_Entry(const info : TEntryInformation) : longbool; external name '_FPC_DLL_Entry'; procedure PascalMain;stdcall;external name 'PASCALMAIN'; diff --git a/rtl/win32/sysinitcyg.pp b/rtl/win32/sysinitcyg.pp index 1d4b11632d..69e2fcfbbd 100644 --- a/rtl/win32/sysinitcyg.pp +++ b/rtl/win32/sysinitcyg.pp @@ -38,6 +38,9 @@ unit sysinitcyg; end; __main; SetupEntryInformation; +{$ifdef FPC_USE_TLS_DIRECTORY} + LinkIn(@tlsdir,@tls_callback_end,@tls_callback); +{$endif} EXE_Entry(EntryInformation); end; diff --git a/rtl/win32/sysinitgprof.pp b/rtl/win32/sysinitgprof.pp index dca5f806e2..448356b611 100644 --- a/rtl/win32/sysinitgprof.pp +++ b/rtl/win32/sysinitgprof.pp @@ -72,6 +72,9 @@ unit sysinitgprof; EXEgmon_start; __main; SetupEntryInformation; +{$ifdef FPC_USE_TLS_DIRECTORY} + LinkIn(@tlsdir,@tls_callback_end,@tls_callback); +{$endif} EXE_Entry(EntryInformation); end; diff --git a/rtl/win32/sysinitpas.pp b/rtl/win32/sysinitpas.pp index 91f7ba75b3..8d8d707c4f 100644 --- a/rtl/win32/sysinitpas.pp +++ b/rtl/win32/sysinitpas.pp @@ -31,6 +31,9 @@ unit sysinitpas; IsConsole:=true; { do it like it is necessary for the startup code linking against cygwin } GetConsoleMode(GetStdHandle((Std_Input_Handle)),StartupConsoleMode); +{$ifdef FPC_USE_TLS_DIRECTORY} + LinkIn(@tlsdir,@tls_callback_end,@tls_callback); +{$endif} SetupEntryInformation; Exe_entry(EntryInformation); end; @@ -39,6 +42,9 @@ unit sysinitpas; procedure _FPC_WinMainCRTStartup;stdcall;public name '_WinMainCRTStartup'; begin IsConsole:=false; +{$ifdef FPC_USE_TLS_DIRECTORY} + LinkIn(@tlsdir,@tls_callback_end,@tls_callback); +{$endif} SetupEntryInformation; Exe_entry(EntryInformation); end; diff --git a/rtl/win32/system.pp b/rtl/win32/system.pp index 2c3bbcd1a8..5fa6b98576 100644 --- a/rtl/win32/system.pp +++ b/rtl/win32/system.pp @@ -947,14 +947,5 @@ begin {$endif VER2_2} InitWin32Widestrings; DispCallByIDProc:=@DoDispCallByIDError; -{$ifdef FPC_USE_TLS_DIRECTORY} - { This code is only here to force - incorporation of needed labels for - _tls_used record in executable - when smartlinking is on } - _tls_used.Index_pointer:=@FreePascal_TLS_callback; - _tls_used.Index_pointer:=@FreePascal_end_of_TLS_callback; - _tls_used.Index_pointer:=@_tls_index; -{$endif FPC_USE_TLS_DIRECTORY} end. diff --git a/rtl/win64/system.pp b/rtl/win64/system.pp index 4dce362329..5896712ce1 100644 --- a/rtl/win64/system.pp +++ b/rtl/win64/system.pp @@ -440,19 +440,6 @@ function GetConsoleMode(hConsoleHandle: THandle; var lpMode: DWORD): Boolean; st function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntryInformation){$endif FPC_HAS_INDIRECT_MAIN_INFORMATION} : longbool;forward; -procedure _FPC_mainCRTStartup;stdcall;public name '_mainCRTStartup'; -begin - IsConsole:=true; - GetConsoleMode(GetStdHandle((Std_Input_Handle)),StartupConsoleMode); - Exe_entry; -end; - - -procedure _FPC_WinMainCRTStartup;stdcall;public name '_WinMainCRTStartup'; -begin - IsConsole:=false; - Exe_entry; -end; procedure _FPC_DLLMainCRTStartup(_hinstance : qword;_dllreason,_dllparam:longint);stdcall;public name '_DLLMainCRTStartup'; @@ -891,6 +878,31 @@ procedure fpc_cpucodeinit; {$I syswin.inc} {******************************************************************************} +procedure LinkIn(p1,p2,p3: Pointer); inline; +begin +end; + +procedure _FPC_mainCRTStartup;stdcall;public name '_mainCRTStartup'; +begin + IsConsole:=true; + GetConsoleMode(GetStdHandle((Std_Input_Handle)),StartupConsoleMode); +{$ifdef FPC_USE_TLS_DIRECTORY} + LinkIn(@_tls_used,@FreePascal_TLS_callback,@FreePascal_end_of_TLS_callback); +{$endif FPC_USE_TLS_DIRECTORY} + Exe_entry; +end; + + +procedure _FPC_WinMainCRTStartup;stdcall;public name '_WinMainCRTStartup'; +begin + IsConsole:=false; +{$ifdef FPC_USE_TLS_DIRECTORY} + LinkIn(@_tls_used,@FreePascal_TLS_callback,@FreePascal_end_of_TLS_callback); +{$endif FPC_USE_TLS_DIRECTORY} + Exe_entry; +end; + + function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;assembler; asm movq %gs:(8),%rax @@ -935,13 +947,4 @@ begin {$endif VER2_2} InitWin32Widestrings; DispCallByIDProc:=@DoDispCallByIDError; -{$ifdef FPC_USE_TLS_DIRECTORY} - { This code is only here to force - incorporation of needed labels for - _tls_used record in executable - when smartlinking is on } - _tls_used.Index_pointer:=@FreePascal_TLS_callback; - _tls_used.Index_pointer:=@FreePascal_end_of_TLS_callback; - _tls_used.Index_pointer:=@_tls_index; -{$endif FPC_USE_TLS_DIRECTORY} end.