winit: section names should start with .
wposix: raise exception instead of quietly exiting wstartup: add note on what needs to be done on vc7 This was SVN commit r5148.
This commit is contained in:
parent
914e5f7c2f
commit
163e294eb7
@ -15,7 +15,10 @@
|
||||
|
||||
// see http://blogs.msdn.com/larryosterman/archive/2004/09/27/234840.aspx
|
||||
// for discussion of a similar mechanism.
|
||||
|
||||
//
|
||||
// note: this module is kept distinct from the CRT's init/shutdown mechanism
|
||||
// to insulate against changes there. another advantage is that callbacks
|
||||
// can return LibError instead of int.
|
||||
|
||||
typedef LibError (*PfnLibErrorVoid)(void);
|
||||
|
||||
@ -25,10 +28,10 @@ typedef LibError (*PfnLibErrorVoid)(void);
|
||||
// (zero, because CallFunctionPointers has to ignore entries =0 anyway).
|
||||
// - ASCII '$' and 'Z' come before resp. after '0'..'9', so use that to
|
||||
// bound the section names.
|
||||
__declspec(allocate("WINIT$I$")) PfnLibErrorVoid initBegin = 0;
|
||||
__declspec(allocate("WINIT$IZ")) PfnLibErrorVoid initEnd = 0;
|
||||
__declspec(allocate("WINIT$S$")) PfnLibErrorVoid shutdownBegin = 0;
|
||||
__declspec(allocate("WINIT$SZ")) PfnLibErrorVoid shutdownEnd = 0;
|
||||
__declspec(allocate(".WINIT$I$")) PfnLibErrorVoid initBegin = 0;
|
||||
__declspec(allocate(".WINIT$IZ")) PfnLibErrorVoid initEnd = 0;
|
||||
__declspec(allocate(".WINIT$S$")) PfnLibErrorVoid shutdownBegin = 0;
|
||||
__declspec(allocate(".WINIT$SZ")) PfnLibErrorVoid shutdownEnd = 0;
|
||||
// note: #pragma comment(linker, "/include") is not necessary since
|
||||
// these are referenced below.
|
||||
|
||||
|
@ -69,25 +69,25 @@ Several methods of module init are possible: (see Large Scale C++ Design)
|
||||
//-----------------------------------------------------------------------------
|
||||
// section declarations
|
||||
|
||||
// section names are of the format "WINIT${type}{group}".
|
||||
// section names are of the format ".WINIT${type}{group}".
|
||||
// {type} is I for initialization- or S for shutdown functions.
|
||||
// {group} is [0, 9] - see below.
|
||||
// note: __declspec(allocate) requires declaring segments in advance via
|
||||
// #pragma section.
|
||||
#pragma section("WINIT$I$", read)
|
||||
#pragma section("WINIT$I0", read)
|
||||
#pragma section("WINIT$I1", read)
|
||||
#pragma section("WINIT$I2", read)
|
||||
#pragma section("WINIT$I6", read)
|
||||
#pragma section("WINIT$I7", read)
|
||||
#pragma section("WINIT$IZ", read)
|
||||
#pragma section("WINIT$S$", read)
|
||||
#pragma section("WINIT$S0", read)
|
||||
#pragma section("WINIT$S1", read)
|
||||
#pragma section("WINIT$S6", read)
|
||||
#pragma section("WINIT$S7", read)
|
||||
#pragma section("WINIT$S8", read)
|
||||
#pragma section("WINIT$SZ", read)
|
||||
#pragma section(".WINIT$I$", read)
|
||||
#pragma section(".WINIT$I0", read)
|
||||
#pragma section(".WINIT$I1", read)
|
||||
#pragma section(".WINIT$I2", read)
|
||||
#pragma section(".WINIT$I6", read)
|
||||
#pragma section(".WINIT$I7", read)
|
||||
#pragma section(".WINIT$IZ", read)
|
||||
#pragma section(".WINIT$S$", read)
|
||||
#pragma section(".WINIT$S0", read)
|
||||
#pragma section(".WINIT$S1", read)
|
||||
#pragma section(".WINIT$S6", read)
|
||||
#pragma section(".WINIT$S7", read)
|
||||
#pragma section(".WINIT$S8", read)
|
||||
#pragma section(".WINIT$SZ", read)
|
||||
#pragma comment(linker, "/merge:WINIT=.rdata")
|
||||
|
||||
|
||||
@ -117,29 +117,29 @@ Several methods of module init are possible: (see Large Scale C++ Design)
|
||||
|
||||
// very early init; must not fail, since error handling code *crashes*
|
||||
// if called before these have completed.
|
||||
#define WINIT_REGISTER_CRITICAL_INIT(func) static LibError func(void); EXTERN_C __declspec(allocate("WINIT$I0")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_CRITICAL_INIT(func) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$I0")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
|
||||
// meant for modules with dependents but whose init is complicated and may
|
||||
// raise error/warning messages (=> can't go in WINIT_REGISTER_CRITICAL_INIT)
|
||||
#define WINIT_REGISTER_EARLY_INIT(func) static LibError func(void); EXTERN_C __declspec(allocate("WINIT$I1")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_EARLY_INIT(func) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$I1")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
|
||||
// available for dependents of WINIT_REGISTER_EARLY_INIT-modules that
|
||||
// must still come before WINIT_REGISTER_MAIN_INIT.
|
||||
#define WINIT_REGISTER_EARLY_INIT2(func) static LibError func(void); EXTERN_C __declspec(allocate("WINIT$I2")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_EARLY_INIT2(func) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$I2")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
|
||||
// most modules will go here unless they are often used or
|
||||
// have many dependents.
|
||||
#define WINIT_REGISTER_MAIN_INIT(func) static LibError func(void); EXTERN_C __declspec(allocate("WINIT$I6")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_MAIN_INIT(func) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$I6")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
|
||||
// available for any modules that may need to come after
|
||||
// WINIT_REGISTER_MAIN_INIT (unlikely)
|
||||
#define WINIT_REGISTER_LATE_INIT(func) static LibError func(void); EXTERN_C __declspec(allocate("WINIT$I7")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_LATE_INIT(func) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$I7")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
|
||||
#define WINIT_REGISTER_EARLY_SHUTDOWN(func) static LibError func(void); EXTERN_C __declspec(allocate("WINIT$S0")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_EARLY_SHUTDOWN2(func) static LibError func(void); EXTERN_C __declspec(allocate("WINIT$S1")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_MAIN_SHUTDOWN(func) static LibError func(void); EXTERN_C __declspec(allocate("WINIT$S6")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_LATE_SHUTDOWN(func) static LibError func(void); EXTERN_C __declspec(allocate("WINIT$S7")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_LATE_SHUTDOWN2(func) static LibError func(void); EXTERN_C __declspec(allocate("WINIT$S8")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_EARLY_SHUTDOWN(func) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$S0")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_EARLY_SHUTDOWN2(func) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$S1")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_MAIN_SHUTDOWN(func) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$S6")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_LATE_SHUTDOWN(func) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$S7")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
#define WINIT_REGISTER_LATE_SHUTDOWN2(func) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$S8")) LibError (*p##func)(void) = func; __pragma(comment(linker, "/include:_p"#func))
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -43,10 +43,10 @@ long sysconf(int name)
|
||||
{
|
||||
// called before InitSysconf => winit/wstartup are broken. this is
|
||||
// going to cause a hard crash because debug.cpp's error reporting
|
||||
// code requires the page size to be known. we'll exit with a unique
|
||||
// value to hopefully help track down the problem.
|
||||
// code requires the page size to be known. we'll raise an exception
|
||||
// with a unique value so that this issue is immediately noticed.
|
||||
if(!pageSize)
|
||||
exit(239786); // 0x3A8AA
|
||||
RaiseException(0xFA57FA57, 0, 0, 0);
|
||||
|
||||
switch(name)
|
||||
{
|
||||
|
@ -85,13 +85,15 @@ application, not the CRT DLL.)
|
||||
*/
|
||||
|
||||
|
||||
EXTERN_C void InitAndRegisterShutdown()
|
||||
// reference: see http://www.codeguru.com/cpp/misc/misc/threadsprocesses/article.php/c6945__1
|
||||
|
||||
EXTERN_C void wstartup_InitAndRegisterShutdown()
|
||||
{
|
||||
winit_CallInitFunctions();
|
||||
atexit(winit_CallShutdownFunctions);
|
||||
}
|
||||
|
||||
#pragma data_seg(".CRT$XCB")
|
||||
EXTERN_C void(*pInitAndRegisterShutdown)() = InitAndRegisterShutdown;
|
||||
#pragma comment(linker, "/include:_pInitAndRegisterShutdown")
|
||||
#pragma data_seg(".CRT$XIV") // after C init, after XIU ("User") block
|
||||
EXTERN_C void(*wstartup_pInitAndRegisterShutdown)() = wstartup_InitAndRegisterShutdown;
|
||||
#pragma data_seg()
|
||||
#pragma comment(linker, "/include:_wstartup_pInitAndRegisterShutdown")
|
||||
|
@ -8,15 +8,22 @@
|
||||
|
||||
// license: GPL; see lib/license.txt
|
||||
|
||||
// linking with this component automatically causes winit's functions to
|
||||
// be called at the appropriate times.
|
||||
// linking with this component should automatically arrange for winit's
|
||||
// functions to be called at the appropriate times.
|
||||
//
|
||||
// the current implementation manages to trigger winit initialization
|
||||
// in-between calls to CRT init and the static C++ ctors. that means
|
||||
// wpthread etc. APIs are safe to use from ctors, and winit initializers
|
||||
// are allowed to use non-stateless CRT functions such as atexit.
|
||||
|
||||
#ifndef INCLUDED_WSTARTUP
|
||||
#define INCLUDED_WSTARTUP
|
||||
|
||||
#endif // #ifndef INCLUDED_WSTARTUP
|
||||
// the current implementation manages to trigger initialization in-between
|
||||
// calls to CRT init and the static C++ ctors. that means wpthread etc.
|
||||
// APIs are safe to use from ctors, and winit initializers are allowed
|
||||
// to use non-stateless CRT functions such as atexit.
|
||||
//
|
||||
// IMPORTANT NOTE: if compiling this into a static lib and not using VC8's
|
||||
// "use library dependency inputs" linking mode, the object file will be
|
||||
// discarded because it does not contain any symbols that resolve another
|
||||
// module's undefined external(s). for a discussion of this topic, see:
|
||||
// http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=144087
|
||||
// workaround: in the main EXE project, reference a symbol from this module,
|
||||
// thus forcing it to be linked in. example:
|
||||
// #pragma comment(linker, "/include:_wstartup_InitAndRegisterShutdown")
|
||||
// (doing that in this module isn't sufficient, because it would only
|
||||
// affect the librarian and its generation of the static lib that holds
|
||||
// this file. instead, the process of linking the main EXE must be fixed.)
|
||||
|
Loading…
Reference in New Issue
Block a user