浏览代码

* 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 -

sergei 14 年之前
父节点
当前提交
ad94e5e719
共有 6 个文件被更改,包括 52 次插入31 次删除
  1. 15 0
      rtl/win32/sysinit.inc
  2. 3 0
      rtl/win32/sysinitcyg.pp
  3. 3 0
      rtl/win32/sysinitgprof.pp
  4. 6 0
      rtl/win32/sysinitpas.pp
  5. 0 9
      rtl/win32/system.pp
  6. 25 22
      rtl/win64/system.pp

+ 15 - 0
rtl/win32/sysinit.inc

@@ -22,6 +22,21 @@
       ThreadvarTablesTable : record end; external name 'FPC_THREADVARTABLES';
       ThreadvarTablesTable : record end; external name 'FPC_THREADVARTABLES';
       valgrind_used : boolean;external name '__fpc_valgrind';
       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';
     procedure EXE_Entry(const info : TEntryInformation); external name '_FPC_EXE_Entry';
     function DLL_Entry(const info : TEntryInformation) : longbool; external name '_FPC_DLL_Entry';
     function DLL_Entry(const info : TEntryInformation) : longbool; external name '_FPC_DLL_Entry';
     procedure PascalMain;stdcall;external name 'PASCALMAIN';
     procedure PascalMain;stdcall;external name 'PASCALMAIN';

+ 3 - 0
rtl/win32/sysinitcyg.pp

@@ -38,6 +38,9 @@ unit sysinitcyg;
         end;
         end;
         __main;
         __main;
         SetupEntryInformation;
         SetupEntryInformation;
+{$ifdef FPC_USE_TLS_DIRECTORY}
+        LinkIn(@tlsdir,@tls_callback_end,@tls_callback);
+{$endif}
         EXE_Entry(EntryInformation);
         EXE_Entry(EntryInformation);
       end;
       end;
 
 

+ 3 - 0
rtl/win32/sysinitgprof.pp

@@ -72,6 +72,9 @@ unit sysinitgprof;
         EXEgmon_start;
         EXEgmon_start;
         __main;
         __main;
         SetupEntryInformation;
         SetupEntryInformation;
+{$ifdef FPC_USE_TLS_DIRECTORY}
+        LinkIn(@tlsdir,@tls_callback_end,@tls_callback);
+{$endif}
         EXE_Entry(EntryInformation);
         EXE_Entry(EntryInformation);
       end;
       end;
 
 

+ 6 - 0
rtl/win32/sysinitpas.pp

@@ -31,6 +31,9 @@ unit sysinitpas;
       IsConsole:=true;
       IsConsole:=true;
       { do it like it is necessary for the startup code linking against cygwin }
       { do it like it is necessary for the startup code linking against cygwin }
       GetConsoleMode(GetStdHandle((Std_Input_Handle)),StartupConsoleMode);
       GetConsoleMode(GetStdHandle((Std_Input_Handle)),StartupConsoleMode);
+{$ifdef FPC_USE_TLS_DIRECTORY}
+      LinkIn(@tlsdir,@tls_callback_end,@tls_callback);
+{$endif}
       SetupEntryInformation;
       SetupEntryInformation;
       Exe_entry(EntryInformation);
       Exe_entry(EntryInformation);
     end;
     end;
@@ -39,6 +42,9 @@ unit sysinitpas;
     procedure _FPC_WinMainCRTStartup;stdcall;public name '_WinMainCRTStartup';
     procedure _FPC_WinMainCRTStartup;stdcall;public name '_WinMainCRTStartup';
     begin
     begin
       IsConsole:=false;
       IsConsole:=false;
+{$ifdef FPC_USE_TLS_DIRECTORY}
+      LinkIn(@tlsdir,@tls_callback_end,@tls_callback);
+{$endif}
       SetupEntryInformation;
       SetupEntryInformation;
       Exe_entry(EntryInformation);
       Exe_entry(EntryInformation);
     end;
     end;

+ 0 - 9
rtl/win32/system.pp

@@ -947,14 +947,5 @@ begin
 {$endif VER2_2}
 {$endif VER2_2}
   InitWin32Widestrings;
   InitWin32Widestrings;
   DispCallByIDProc:=@DoDispCallByIDError;
   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.
 end.
 
 

+ 25 - 22
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;
 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';
 procedure _FPC_DLLMainCRTStartup(_hinstance : qword;_dllreason,_dllparam:longint);stdcall;public name '_DLLMainCRTStartup';
@@ -891,6 +878,31 @@ procedure fpc_cpucodeinit;
 {$I syswin.inc}
 {$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;
 function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;assembler;
 asm
 asm
   movq  %gs:(8),%rax
   movq  %gs:(8),%rax
@@ -935,13 +947,4 @@ begin
 {$endif VER2_2}
 {$endif VER2_2}
   InitWin32Widestrings;
   InitWin32Widestrings;
   DispCallByIDProc:=@DoDispCallByIDError;
   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.
 end.