* 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 -
This commit is contained in:
sergei 2011-07-27 23:22:09 +00:00
parent 888ea8121c
commit ad94e5e719
6 changed files with 52 additions and 31 deletions

View File

@ -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';

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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.