mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 15:47:51 +02:00
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 -
This commit is contained in:
parent
8775897621
commit
6afda909d4
@ -915,7 +915,7 @@ var
|
|||||||
edata : ptruint; external name '__data_end__';
|
edata : ptruint; external name '__data_end__';
|
||||||
sbss : ptruint; external name '__bss_start__';
|
sbss : ptruint; external name '__bss_start__';
|
||||||
ebss : ptruint; external name '__bss_end__';
|
ebss : ptruint; external name '__bss_end__';
|
||||||
TLSKey : DWord; external name '_FPC_TlsKey';
|
TLSKey : PDWord; external name '_FPC_TlsKey';
|
||||||
TLSSize : DWord; external name '_FPC_TlsSize';
|
TLSSize : DWord; external name '_FPC_TlsSize';
|
||||||
|
|
||||||
function TlsGetValue(dwTlsIndex : DWord) : pointer;
|
function TlsGetValue(dwTlsIndex : DWord) : pointer;
|
||||||
@ -989,9 +989,9 @@ begin
|
|||||||
if (ptruint(p)>=ptruint(@sbss)) and (ptruint(p)<ptruint(@ebss)) then
|
if (ptruint(p)>=ptruint(@sbss)) and (ptruint(p)<ptruint(@ebss)) then
|
||||||
exit;
|
exit;
|
||||||
{ is program multi-threaded and p inside Threadvar range? }
|
{ is program multi-threaded and p inside Threadvar range? }
|
||||||
if TlsKey<>-1 then
|
if TlsKey^<>-1 then
|
||||||
begin
|
begin
|
||||||
datap:=TlsGetValue(tlskey);
|
datap:=TlsGetValue(tlskey^);
|
||||||
if ((ptruint(p)>=ptruint(datap)) and
|
if ((ptruint(p)>=ptruint(datap)) and
|
||||||
(ptruint(p)<ptruint(datap)+TlsSize)) then
|
(ptruint(p)<ptruint(datap)+TlsSize)) then
|
||||||
exit;
|
exit;
|
||||||
|
@ -126,6 +126,9 @@ begin
|
|||||||
EntryInformation := info;
|
EntryInformation := info;
|
||||||
FPCResStrInitTables := info.ResStrInitTables;
|
FPCResStrInitTables := info.ResStrInitTables;
|
||||||
FPCResourceStringTables := info.ResourceStringTables;
|
FPCResourceStringTables := info.ResourceStringTables;
|
||||||
|
{$ifdef FPC_SYSTEM_HAS_OSSETUPENTRYINFORMATION}
|
||||||
|
OSSetupEntryInformation(info);
|
||||||
|
{$endif FPC_SYSTEM_HAS_OSSETUPENTRYINFORMATION}
|
||||||
end;
|
end;
|
||||||
{$endif FPC_HAS_INDIRECT_MAIN_INFORMATION}
|
{$endif FPC_HAS_INDIRECT_MAIN_INFORMATION}
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ type
|
|||||||
{$define HAS_ENTRYINFORMATION_OS}
|
{$define HAS_ENTRYINFORMATION_OS}
|
||||||
TEntryInformationOS = record
|
TEntryInformationOS = record
|
||||||
asm_exit : Procedure;stdcall;
|
asm_exit : Procedure;stdcall;
|
||||||
|
TlsKeyAddr : PDWord;
|
||||||
end;
|
end;
|
||||||
{$endif Win32}
|
{$endif Win32}
|
||||||
|
|
||||||
|
@ -94,7 +94,12 @@ var
|
|||||||
var
|
var
|
||||||
// public names are used by heaptrc unit
|
// public names are used by heaptrc unit
|
||||||
threadvarblocksize : dword; public name '_FPC_TlsSize';
|
threadvarblocksize : dword; public name '_FPC_TlsSize';
|
||||||
TLSKey : DWord = $ffffffff; public name '_FPC_TlsKey';
|
{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}
|
||||||
|
TLSKey : PDword = nil; public name '_FPC_TlsKey';
|
||||||
|
{$else FPC_HAS_INDIRECT_MAIN_INFORMATION}
|
||||||
|
TLSKeyVar : DWord = $ffffffff;
|
||||||
|
TLSKey : PDWord = @TLSKeyVar; public name '_FPC_TlsKey';
|
||||||
|
{$endif FPC_HAS_INDIRECT_MAIN_INFORMATION}
|
||||||
|
|
||||||
var
|
var
|
||||||
MainThreadIdWin32 : DWORD;
|
MainThreadIdWin32 : DWORD;
|
||||||
@ -121,15 +126,15 @@ var
|
|||||||
{ these aren't allocated yet ... }
|
{ these aren't allocated yet ... }
|
||||||
{ allocate room on the heap for the thread vars }
|
{ allocate room on the heap for the thread vars }
|
||||||
errorsave:=GetLastError;
|
errorsave:=GetLastError;
|
||||||
if tlskey=$ffffffff then
|
if tlskey^=$ffffffff then
|
||||||
RunError(226);
|
RunError(226);
|
||||||
dataindex:=TlsGetValue(tlskey);
|
dataindex:=TlsGetValue(tlskey^);
|
||||||
if dataindex=nil then
|
if dataindex=nil then
|
||||||
begin
|
begin
|
||||||
dataindex:=pointer(LocalAlloc(LMEM_FIXED or LMEM_ZEROINIT,threadvarblocksize));
|
dataindex:=pointer(LocalAlloc(LMEM_FIXED or LMEM_ZEROINIT,threadvarblocksize));
|
||||||
if dataindex=nil then
|
if dataindex=nil then
|
||||||
RunError(226);
|
RunError(226);
|
||||||
TlsSetValue(tlskey,dataindex);
|
TlsSetValue(tlskey^,dataindex);
|
||||||
end;
|
end;
|
||||||
SetLastError(errorsave);
|
SetLastError(errorsave);
|
||||||
end;
|
end;
|
||||||
@ -141,10 +146,10 @@ var
|
|||||||
{ do not check IsMultiThread, as program could have altered it, out of Delphi habit }
|
{ do not check IsMultiThread, as program could have altered it, out of Delphi habit }
|
||||||
|
|
||||||
{ the thread attach/detach code uses locks to avoid multiple calls of this }
|
{ the thread attach/detach code uses locks to avoid multiple calls of this }
|
||||||
if TLSKey=$ffffffff then
|
if TLSKey^=$ffffffff then
|
||||||
begin
|
begin
|
||||||
{ We're still running in single thread mode, setup the TLS }
|
{ We're still running in single thread mode, setup the TLS }
|
||||||
TLSKey:=TlsAlloc;
|
TLSKey^:=TlsAlloc;
|
||||||
InitThreadVars(@SysRelocateThreadvar);
|
InitThreadVars(@SysRelocateThreadvar);
|
||||||
|
|
||||||
IsMultiThread:=true;
|
IsMultiThread:=true;
|
||||||
@ -154,9 +159,9 @@ var
|
|||||||
|
|
||||||
procedure SysFiniMultithreading;
|
procedure SysFiniMultithreading;
|
||||||
begin
|
begin
|
||||||
if TLSKey<>$ffffffff then
|
if TLSKey^<>$ffffffff then
|
||||||
TlsFree(TLSKey);
|
TlsFree(TLSKey^);
|
||||||
TLSKey:=$ffffffff;
|
TLSKey^:=$ffffffff;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function SysRelocateThreadvar(offset : dword) : pointer;
|
function SysRelocateThreadvar(offset : dword) : pointer;
|
||||||
@ -165,11 +170,11 @@ var
|
|||||||
errorsave : dword;
|
errorsave : dword;
|
||||||
begin
|
begin
|
||||||
errorsave:=GetLastError;
|
errorsave:=GetLastError;
|
||||||
dataindex:=TlsGetValue(tlskey);
|
dataindex:=TlsGetValue(tlskey^);
|
||||||
if dataindex=nil then
|
if dataindex=nil then
|
||||||
begin
|
begin
|
||||||
SysAllocateThreadVars;
|
SysAllocateThreadVars;
|
||||||
dataindex:=TlsGetValue(tlskey);
|
dataindex:=TlsGetValue(tlskey^);
|
||||||
InitThread($1000000);
|
InitThread($1000000);
|
||||||
end;
|
end;
|
||||||
SetLastError(errorsave);
|
SetLastError(errorsave);
|
||||||
@ -181,12 +186,12 @@ var
|
|||||||
var
|
var
|
||||||
p: pointer;
|
p: pointer;
|
||||||
begin
|
begin
|
||||||
if TLSKey<>$ffffffff then
|
if TLSKey^<>$ffffffff then
|
||||||
begin
|
begin
|
||||||
p:=TlsGetValue(tlskey);
|
p:=TlsGetValue(tlskey^);
|
||||||
if Assigned(p) then
|
if Assigned(p) then
|
||||||
LocalFree(p);
|
LocalFree(p);
|
||||||
TlsSetValue(tlskey, nil);
|
TlsSetValue(tlskey^, nil);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ Const
|
|||||||
DLL_THREAD_DETACH = 3;
|
DLL_THREAD_DETACH = 3;
|
||||||
|
|
||||||
var
|
var
|
||||||
TlsKey : dword; external name '_FPC_TlsKey';
|
TlsKey : PDWord = @TlsKeyVar;
|
||||||
|
|
||||||
type
|
type
|
||||||
TTlsDirectory=packed record
|
TTlsDirectory=packed record
|
||||||
@ -107,7 +107,7 @@ procedure Exec_Tls_callback(Handle : pointer; reason : Dword; Reserved : pointer
|
|||||||
end;
|
end;
|
||||||
DLL_THREAD_DETACH :
|
DLL_THREAD_DETACH :
|
||||||
begin
|
begin
|
||||||
if TlsGetValue(TLSKey)<>nil then
|
if TlsGetValue(TLSKey^)<>nil then
|
||||||
DoneThread; { Assume everything is idempotent there }
|
DoneThread; { Assume everything is idempotent there }
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -400,7 +400,7 @@ function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntry
|
|||||||
if assigned(Dll_Thread_Detach_Hook) then
|
if assigned(Dll_Thread_Detach_Hook) then
|
||||||
Dll_Thread_Detach_Hook(DllParam);
|
Dll_Thread_Detach_Hook(DllParam);
|
||||||
{ Release Threadvars }
|
{ Release Threadvars }
|
||||||
if TlsGetValue(TLSKey)<>nil then
|
if TlsGetValue(TLSKey^)<>nil then
|
||||||
DoneThread; { Assume everything is idempotent there }
|
DoneThread; { Assume everything is idempotent there }
|
||||||
end;
|
end;
|
||||||
DLL_PROCESS_DETACH :
|
DLL_PROCESS_DETACH :
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
var
|
var
|
||||||
SysInstance : Longint;external name '_FPC_SysInstance';
|
SysInstance : Longint;external name '_FPC_SysInstance';
|
||||||
|
TlsKeyVar: DWord = $ffffffff;
|
||||||
|
|
||||||
InitFinalTable : record end; external name 'INITFINAL';
|
InitFinalTable : record end; external name 'INITFINAL';
|
||||||
ThreadvarTablesTable : record end; external name 'FPC_THREADVARTABLES';
|
ThreadvarTablesTable : record end; external name 'FPC_THREADVARTABLES';
|
||||||
@ -65,6 +66,7 @@
|
|||||||
valgrind_used : false;
|
valgrind_used : false;
|
||||||
OS : (
|
OS : (
|
||||||
asm_exit : @asm_exit;
|
asm_exit : @asm_exit;
|
||||||
|
TlsKeyAddr : @TlsKeyVar;
|
||||||
);
|
);
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -78,6 +80,7 @@
|
|||||||
EntryInformation.ResStrInitTables:=@ResStrInitTables;
|
EntryInformation.ResStrInitTables:=@ResStrInitTables;
|
||||||
EntryInformation.WideInitTables:=@WideInitTables;
|
EntryInformation.WideInitTables:=@WideInitTables;
|
||||||
EntryInformation.OS.asm_exit:=@asm_exit;
|
EntryInformation.OS.asm_exit:=@asm_exit;
|
||||||
|
EntryInformation.OS.TlsKeyAddr:=@TlsKeyVar;
|
||||||
EntryInformation.PascalMain:=@PascalMain;}
|
EntryInformation.PascalMain:=@PascalMain;}
|
||||||
SysInitEntryInformation.valgrind_used:=valgrind_used;
|
SysInitEntryInformation.valgrind_used:=valgrind_used;
|
||||||
end;
|
end;
|
||||||
|
@ -113,6 +113,9 @@ implementation
|
|||||||
var
|
var
|
||||||
SysInstance : Longint;public name '_FPC_SysInstance';
|
SysInstance : Longint;public name '_FPC_SysInstance';
|
||||||
|
|
||||||
|
{$define FPC_SYSTEM_HAS_OSSETUPENTRYINFORMATION}
|
||||||
|
procedure OsSetupEntryInformation(const info: TEntryInformation); forward;
|
||||||
|
|
||||||
{$ifdef FPC_USE_WIN32_SEH}
|
{$ifdef FPC_USE_WIN32_SEH}
|
||||||
function main_wrapper(arg: Pointer; proc: Pointer): ptrint; forward;
|
function main_wrapper(arg: Pointer; proc: Pointer): ptrint; forward;
|
||||||
procedure OutermostHandler; external name '__FPC_DEFAULT_HANDLER';
|
procedure OutermostHandler; external name '__FPC_DEFAULT_HANDLER';
|
||||||
@ -130,6 +133,10 @@ end;
|
|||||||
{ include code common with win64 }
|
{ include code common with win64 }
|
||||||
{$I syswin.inc}
|
{$I syswin.inc}
|
||||||
|
|
||||||
|
procedure OsSetupEntryInformation(const info: TEntryInformation);
|
||||||
|
begin
|
||||||
|
TlsKey := info.OS.TlsKeyAddr;
|
||||||
|
end;
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
System Dependent Exit code
|
System Dependent Exit code
|
||||||
|
Loading…
Reference in New Issue
Block a user