Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1940 lines
50 KiB

//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Insert this file into all projects using the memory system
// It will cause that project to use the shader memory allocator
//
// $NoKeywords: $
//=============================================================================//
#ifdef SN_TARGET_PS3
#ifdef PS3MEMOVERRIDEWRAP
/*
========= PS3 LAUNCHER MAIN ELF SECTION ==================
========= Vitaliy ======= May 2010 ===================
The implementation of memory allocation wraps in the scenario
of bootstrapping ELF and PRXs is as follows:
ELF wraps all memory allocation CRT function here (see --wrap below)
ELF lets all statically linked libraries to initialize before
main function runs, it is required in order to be able to load
any PRXs to initialize some CRT globals and sysmodules data.
ELF tries to load tier0.prx containing the custom memory
management allocator as soon as possible in main function.
So this is when allocations can be happening:
1) global CRT contructors calling malloc (IOBUFs,mutexes,etc.)
2) main calling malloc indirectly trying to determine boot
parameters and where to load tier0.prx module
>>--->>-- here we already inject tier0 custom allocator!! <<----
3) global consturctors of tier0.prx before tier0 prx entry
point function runs
4) tier0 prx entry point function returns to bootstrapper's main
5) everything else
****** WHAT HAPPENS BEFORE TIER0 CUSTOM ALLOCATOR IS AVAILABLE?
Since all memory allocation calls are going into our custom
wrapped malloc/free implementation that doesn't yet have real
custom allocator, we create a static .bss section array (256Kb)
and we just hand out 16-byte aligned addresses from this array.
The memory allocated from this .bss section is essentially never
freed. Test runs show that roughly 68Kb is actually allocated
before tier0 custom allocator becomes available.
****** HOW DO WE INJECT TIER0 CUSTOM ALLOCATOR SO EARLY?
For this we utilize two tricks.
RUN SOME CODE IN TIER0 BEFORE EVERYTHING ELSE:
We use attribute "init_priority(101)" on a global struct
in tier0 to run its constructor function before any other
global objects in tier0 construct.
That function calls into ELF to obtain real addresses of
real CRT functions, constructs the custom memory allocator
and signals the ELF the pointer to allocator's interface,
so all other tier0 global objects will already use the
custom allocator's interface even though tier0's entry point
didn't run yet.
EARLY COMMUNICATION ELF-PRX BEFORE PRX ENTRY POINT
We use CRT wrap function "malloc_stats", we call it with
special parameters passing data from PRX into ELF wrapper.
Return value of the function essentially passes data back
from ELF into PRX thus allowing to handshake in the guts
of PRX loading code between ELF calling prx_start_module
and prx entry point.
=============================================================
We must be using --wrap=<symbol> on PS3 SNC compiler to wrap
all calls to malloc-related functions.
--wrap=<symbol>
Use wrapper functions for <symbol>. If the linker is passed
the argument '-wrap=foo', it will resolve references to the
symbol foo to __wrap_foo; in addition, a new symbol __real_foo
will be created which will resolve to the original foo.
For example, by defining a function __wrap_fopen() that
implements any desired wrapping logic and that invokes the
real fopen() call through the __real_foo symbol, we can give
the linker the argument '--wrap=fopen' and easily intercept
calls to fopen().
extern FILE *__real_fopen (const char * restrict filename, const char * restrict mode);
FILE *__wrap_fopen (const char * restrict filename, const char * restrict mode)
{
printf ('open %s\n', filename);
return __real_fopen (filename, mode);
}
*/
#define _PS3 1
#include <stdlib.h>
#include "memalloc.h"
#include "dbg.h"
#include "memoverride_ps3.h"
#include "../steam/steam_platform_ps3/steamps3params.h"
#define WRAP_FN_HOOK( name ) __wrap_##name
#define WRAP_FN_REAL( name ) __real_##name
static IMemAlloc *g_p_tier0_memalloc_interface = NULL;
#ifdef g_pMemAlloc
#undef g_pMemAlloc
#endif
#define g_pMemAlloc g_p_tier0_memalloc_interface
char g_ps3_malloc_startup_buffer[ 256 * 1024 ];
int g_ps3_malloc_startup_index = 0;
inline void * MallocStartupBuffer()
{
return &g_ps3_malloc_startup_buffer[ g_ps3_malloc_startup_index ];
}
inline void MallocStartupUsed( size_t size )
{
size = ( size + 0xF )&~0xF; // round up to a multiple of 16 bytes
g_ps3_malloc_startup_index += size;
if ( g_ps3_malloc_startup_index > sizeof( g_ps3_malloc_startup_buffer ) )
abort();
}
inline bool IsMallocStartupAllocation( void *p )
{
return ( p >= g_ps3_malloc_startup_buffer ) && ( p < &g_ps3_malloc_startup_buffer[ g_ps3_malloc_startup_index ] );
}
inline size_t GetMallocStartupAllocationSize( void *p )
{
char *pCh = ( char * ) p;
pCh -= 16;
size_t *pSize = reinterpret_cast< size_t * >( pCh );
return *pSize;
}
MemOverrideRawCrtFunctions_t * GetRawCrtFunctions();
SteamPS3Memory_t *GetSteamMemoryFunctions();
_C_STD_BEGIN
extern "C" {
void WRAP_FN_REAL(abort)(void);
void WRAP_FN_HOOK(abort)(void)
{
#ifndef _CERT
DebuggerBreak();
#endif
WRAP_FN_REAL(abort)();
}
void * WRAP_FN_REAL(malloc)( size_t size );
void * WRAP_FN_HOOK(malloc)( size_t size )
{
if ( g_pMemAlloc )
{
return g_pMemAlloc->Alloc( size );
}
else
{
size_t *pSize = (size_t*) MallocStartupBuffer();
*pSize = size;
MallocStartupUsed( sizeof( size_t ) );
void *pvResult = MallocStartupBuffer();
MallocStartupUsed( size );
return pvResult;
}
}
void * WRAP_FN_REAL(calloc)( size_t nelem, size_t size );
void * WRAP_FN_HOOK(calloc)( size_t nelem, size_t size )
{
void *p = g_pMemAlloc ? g_pMemAlloc->Alloc( nelem * size ) : malloc( nelem * size );
memset( p, 0, nelem * size );
return p;
}
void * WRAP_FN_REAL(memalign)(size_t boundary, size_t size_arg);
void * WRAP_FN_HOOK(memalign)(size_t boundary, size_t size_arg)
{
if ( g_pMemAlloc )
{
void * p = g_pMemAlloc->AllocAlign( size_arg, boundary );
Assert( 0 == ( reinterpret_cast< size_t >( p ) % boundary ) );
return p;
}
else
{
return malloc( size_arg );
}
}
void * WRAP_FN_REAL(realloc)( void *p, size_t size_arg );
void * WRAP_FN_HOOK(realloc)( void *p, size_t size_arg )
{
if ( !IsMallocStartupAllocation( p ) && g_pMemAlloc )
{
return g_pMemAlloc->Realloc( p, size_arg );
}
else
{
void *pNewData = malloc( size_arg );
size_t nOldSize = GetMallocStartupAllocationSize( p );
memcpy( pNewData, p, nOldSize < size_arg ? nOldSize : size_arg );
free( p );
return pNewData;
}
}
void * WRAP_FN_REAL(reallocalign)(void *p, size_t size_arg, size_t boundary);
void * WRAP_FN_HOOK(reallocalign)(void *p, size_t size_arg, size_t boundary)
{
if ( !IsMallocStartupAllocation( p ) && g_pMemAlloc )
{
p = g_pMemAlloc->ReallocAlign( p, size_arg, boundary );
Assert( 0 == ( reinterpret_cast< size_t >( p ) % boundary ) );
return p;
}
else
{
void *pNewData = memalign( boundary, size_arg );
size_t nOldSize = GetMallocStartupAllocationSize( p );
memcpy( pNewData, p, nOldSize < size_arg ? nOldSize : size_arg );
free( p );
return pNewData;
}
}
size_t WRAP_FN_REAL(malloc_usable_size)( void *p );
size_t WRAP_FN_HOOK(malloc_usable_size)( void *p )
{
if ( !IsMallocStartupAllocation( p ) && g_pMemAlloc )
return g_pMemAlloc->GetSize( p );
return GetMallocStartupAllocationSize( p );
}
int WRAP_FN_REAL(malloc_stats)(struct malloc_managed_size *mms);
int WRAP_FN_HOOK(malloc_stats)(struct malloc_managed_size *mms)
{
if ( mms &&
mms->current_inuse_size == 0x12345678 &&
mms->current_system_size == 0x09ABCDEF )
{
// This is our passthrough function to establish
// real memalloc interface from tier0
g_pMemAlloc = reinterpret_cast< IMemAlloc * >( mms->max_system_size );
return reinterpret_cast<int>( GetRawCrtFunctions() );
}
if ( mms &&
mms->current_inuse_size == STEAMPS3_MALLOC_INUSE &&
mms->current_system_size == STEAMPS3_MALLOC_SYSTEM )
{
// Steam is requesting memory struct
mms->current_inuse_size = STEAMPS3_MALLOC_OK;
return reinterpret_cast<int>( GetSteamMemoryFunctions() );
}
memset( mms, 0, sizeof( *mms ) );
return 0;
}
void WRAP_FN_REAL(free)( void *p );
void WRAP_FN_HOOK(free)( void *p )
{
if ( !IsMallocStartupAllocation( p ) && g_pMemAlloc )
g_pMemAlloc->Free( p );
}
}
_C_STD_END
MemOverrideRawCrtFunctions_t * GetRawCrtFunctions()
{
using namespace std;
static MemOverrideRawCrtFunctions_t g_rawfns =
{
WRAP_FN_REAL( malloc ),
WRAP_FN_REAL( calloc ),
WRAP_FN_REAL( memalign ),
WRAP_FN_REAL( realloc ),
WRAP_FN_REAL( reallocalign ),
WRAP_FN_REAL( malloc_usable_size ),
WRAP_FN_REAL( malloc_stats ),
WRAP_FN_REAL( free )
};
return &g_rawfns;
}
SteamPS3Memory_t *GetSteamMemoryFunctions()
{
using namespace std;
static SteamPS3Memory_t g_steamPS3Memory =
{
#if defined( STEAM_SHARES_GAME_ALLOCATOR )
false, // false=[Steam and game share the tier0 memory allocator]
#else
true, // true=[Steam manages 6Mb chunk, allocated from the game on startup]
#endif
WRAP_FN_HOOK( malloc ),
WRAP_FN_HOOK( realloc ),
WRAP_FN_HOOK( free ),
WRAP_FN_HOOK( malloc_usable_size )
};
return &g_steamPS3Memory;
}
#elif !defined( TIER0_DLL_EXPORT )
/*
========= PS3 SECTION FOR ALL MODULES EXCEPT TIER0 ==================
*/
#include "tier0/dbg.h"
#include "tier0/memalloc.h"
#if (defined(_DEBUG) || defined(USE_MEM_DEBUG))
void *operator new( unsigned int nSize, int nBlockUse_UNUSED, const char *pFileName, int nLine )
{
return MemAlloc_Alloc( nSize, pFileName, nLine );
}
void *operator new[] ( unsigned int nSize, int nBlockUse_UNUSED, const char *pFileName, int nLine )
{
return MemAlloc_Alloc( nSize, pFileName, nLine );
}
#endif
#endif // PS3MEMOVERRIDEWRAP
#else
#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE)
#define AVOID_INCLUDING_ALGORITHM
#undef PROTECTED_THINGS_ENABLE // allow use of _vsnprintf
#include <stdlib.h>
#include "platform.h"
extern "C" void __cdecl WriteMiniDump( void );
inline void __cdecl VPurecallHandler()
{
DebuggerBreakIfDebugging(); // give the debugger a chance to catch first
WriteMiniDump();
Plat_ExitProcess( EXIT_FAILURE );
}
#if defined( _WIN32 ) && !defined( _X360 )
#define WIN_32_LEAN_AND_MEAN
#include <windows.h>
// set Windows pure virtual handler
_purecall_handler OldPurecallHandler = _set_purecall_handler( VPurecallHandler );
#elif defined( POSIX ) && !defined( _PS3 )
// set OSX/Linux pure virtual handler
extern "C" void __cxa_pure_virtual() { VPurecallHandler(); }
#endif
#include "tier0/dbg.h"
#include "tier0/memalloc.h"
#include <string.h>
#include <stdio.h>
#include "memdbgoff.h"
#ifdef _WIN32
// ARG: crtdbg is necessary for certain definitions below,
// but it also redefines malloc as a macro in release.
// To disable this, we gotta define _DEBUG before including it.. BLEAH!
#define _DEBUG 1
#include "crtdbg.h"
#ifdef NDEBUG
#undef _DEBUG
#endif
// Turn this back off in release mode.
#ifdef NDEBUG
#undef _DEBUG
#endif
#elif POSIX
#define __cdecl
#endif
#if defined(USE_MEM_DEBUG)
#pragma optimize( "", off )
#define inline
#endif
const char *g_pszModule = MKSTRING( MEMOVERRIDE_MODULE );
inline void *AllocUnattributed( size_t nSize )
{
#if !defined(USE_LIGHT_MEM_DEBUG) && !defined(USE_MEM_DEBUG)
return MemAlloc_Alloc(nSize);
#else
return MemAlloc_Alloc(nSize, ::g_pszModule, 0);
#endif
}
inline void *ReallocUnattributed( void *pMem, size_t nSize )
{
#if !defined(USE_LIGHT_MEM_DEBUG) && !defined(USE_MEM_DEBUG)
return g_pMemAlloc->Realloc(pMem, nSize);
#else
return g_pMemAlloc->Realloc(pMem, nSize, ::g_pszModule, 0);
#endif
}
#undef inline
//-----------------------------------------------------------------------------
// Standard functions in the CRT that we're going to override to call our allocator
//-----------------------------------------------------------------------------
#if defined(_WIN32) && !defined(_STATIC_LINKED)
// this magic only works under win32
// under linux this malloc() overrides the libc malloc() and so we
// end up in a recursion (as MemAlloc_Alloc() calls malloc)
#if _MSC_VER >= 1400
#if _MSC_VER >= 1900
#define _CRTNOALIAS
#endif
#define ALLOC_CALL _CRTNOALIAS _CRTRESTRICT
#define FREE_CALL _CRTNOALIAS
#else
#define ALLOC_CALL
#define FREE_CALL
#endif
extern "C"
{
ALLOC_CALL void *malloc( size_t nSize )
{
return AllocUnattributed( nSize );
}
FREE_CALL void free( void *pMem )
{
#if !defined(USE_LIGHT_MEM_DEBUG) && !defined(USE_MEM_DEBUG)
g_pMemAlloc->Free(pMem);
#else
g_pMemAlloc->Free(pMem, ::g_pszModule, 0 );
#endif
}
ALLOC_CALL void *realloc( void *pMem, size_t nSize )
{
return ReallocUnattributed( pMem, nSize );
}
ALLOC_CALL void *calloc( size_t nCount, size_t nElementSize )
{
void *pMem = AllocUnattributed( nElementSize * nCount );
memset(pMem, 0, nElementSize * nCount);
return pMem;
}
} // end extern "C"
//-----------------------------------------------------------------------------
// Non-standard MSVC functions that we're going to override to call our allocator
//-----------------------------------------------------------------------------
extern "C"
{
// 64-bit
#ifdef _WIN64
void* __cdecl _malloc_base( size_t nSize )
{
return AllocUnattributed( nSize );
}
#else
void *_malloc_base( size_t nSize )
{
return AllocUnattributed( nSize );
}
#endif
#if ( defined ( _MSC_VER ) && _MSC_VER >= 1900 )
_CRTRESTRICT void *_calloc_base(size_t nCount, size_t nSize)
{
void *pMem = AllocUnattributed(nCount*nSize);
memset(pMem, 0, nCount*nSize);
return pMem;
}
#else
void *_calloc_base( size_t nSize )
{
void *pMem = AllocUnattributed( nSize );
memset(pMem, 0, nSize);
return pMem;
}
#endif
void *_realloc_base( void *pMem, size_t nSize )
{
return ReallocUnattributed( pMem, nSize );
}
void *_recalloc_base( void *pMem, size_t nSize )
{
void *pMemOut = ReallocUnattributed( pMem, nSize );
if (!pMem)
{
memset(pMemOut, 0, nSize);
}
return pMemOut;
}
void _free_base( void *pMem )
{
#if !defined(USE_LIGHT_MEM_DEBUG) && !defined(USE_MEM_DEBUG)
g_pMemAlloc->Free(pMem);
#else
g_pMemAlloc->Free(pMem, ::g_pszModule, 0 );
#endif
}
void *__cdecl _expand_base( void *pMem, size_t nNewSize, int nBlockUse )
{
Assert( 0 );
return NULL;
}
// crt
void * __cdecl _malloc_crt(size_t size)
{
return AllocUnattributed( size );
}
void * __cdecl _calloc_crt(size_t count, size_t size)
{
#if (defined( _MSC_VER ) && _MSC_VER >= 1900)
return _calloc_base(count, size);
#else
return _calloc_base( count * size );
#endif
}
void * __cdecl _realloc_crt(void *ptr, size_t size)
{
return _realloc_base( ptr, size );
}
void * __cdecl _recalloc_crt(void *ptr, size_t count, size_t size)
{
return _recalloc_base( ptr, size * count );
}
ALLOC_CALL void * __cdecl _recalloc ( void * memblock, size_t count, size_t size )
{
void *pMem = ReallocUnattributed( memblock, size * count );
if (!memblock)
{
memset(pMem, 0, size * count);
}
return pMem;
}
size_t _msize_base( void *pMem )
{
return g_pMemAlloc->GetSize(pMem);
}
size_t _msize( void *pMem )
{
return _msize_base(pMem);
}
size_t msize( void *pMem )
{
return g_pMemAlloc->GetSize(pMem);
}
void *__cdecl _heap_alloc( size_t nSize )
{
return AllocUnattributed( nSize );
}
void *__cdecl _nh_malloc( size_t nSize, int )
{
return AllocUnattributed( nSize );
}
void *__cdecl _expand( void *pMem, size_t nSize )
{
Assert( 0 );
return NULL;
}
unsigned int _amblksiz = 16; //BYTES_PER_PARA;
#if _MSC_VER >= 1400
HANDLE _crtheap = (HANDLE)1; // PatM Can't be 0 or CRT pukes
int __active_heap = 1;
#endif // _MSC_VER >= 1400
size_t __cdecl _get_sbh_threshold( void )
{
return 0;
}
int __cdecl _set_sbh_threshold( size_t )
{
return 0;
}
int _heapchk()
{
return g_pMemAlloc->heapchk();
}
int _heapmin()
{
return 1;
}
int __cdecl _heapadd( void *, size_t )
{
return 0;
}
int __cdecl _heapset( unsigned int )
{
return 0;
}
size_t __cdecl _heapused( size_t *, size_t * )
{
return 0;
}
#ifdef _WIN32
#include <malloc.h>
int __cdecl _heapwalk( _HEAPINFO * )
{
return 0;
}
#endif
} // end extern "C"
//-----------------------------------------------------------------------------
// Debugging functions that we're going to override to call our allocator
// NOTE: These have to be here for release + debug builds in case we
// link to a debug static lib!!!
//-----------------------------------------------------------------------------
extern "C"
{
void *malloc_db( size_t nSize, const char *pFileName, int nLine )
{
return MemAlloc_Alloc(nSize, pFileName, nLine);
}
void free_db( void *pMem, const char *pFileName, int nLine )
{
g_pMemAlloc->Free(pMem, pFileName, nLine);
}
void *realloc_db( void *pMem, size_t nSize, const char *pFileName, int nLine )
{
return g_pMemAlloc->Realloc(pMem, nSize, pFileName, nLine);
}
} // end extern "C"
//-----------------------------------------------------------------------------
// These methods are standard MSVC heap initialization + shutdown methods
//-----------------------------------------------------------------------------
extern "C"
{
#if !defined( _X360 )
int __cdecl _heap_init()
{
return g_pMemAlloc != NULL;
}
void __cdecl _heap_term()
{
}
#endif
}
#endif
//-----------------------------------------------------------------------------
// Prevents us from using an inappropriate new or delete method,
// ensures they are here even when linking against debug or release static libs
//-----------------------------------------------------------------------------
#ifndef NO_MEMOVERRIDE_NEW_DELETE
#if !defined( _OSX )
void *__cdecl operator new( size_t nSize )
{
return AllocUnattributed( nSize );
}
void *__cdecl operator new( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
{
return MemAlloc_Alloc(nSize, pFileName, nLine );
}
void *__cdecl operator new[] ( size_t nSize )
{
return AllocUnattributed( nSize );
}
void *__cdecl operator new[] ( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
{
return MemAlloc_Alloc(nSize, pFileName, nLine);
}
#else
void *__cdecl operator new( size_t nSize ) throw (std::bad_alloc)
{
return AllocUnattributed( nSize );
}
void *__cdecl operator new( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
{
return MemAlloc_Alloc(nSize, pFileName, nLine );
}
void *__cdecl operator new[] ( size_t nSize ) throw (std::bad_alloc)
{
return AllocUnattributed( nSize );
}
void *__cdecl operator new[] ( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
{
return MemAlloc_Alloc(nSize, pFileName, nLine);
}
#endif // !_OSX
void __cdecl operator delete( void *pMem ) throw()
{
#if !defined(USE_LIGHT_MEM_DEBUG) && !defined(USE_MEM_DEBUG)
g_pMemAlloc->Free(pMem);
#else
g_pMemAlloc->Free(pMem, ::g_pszModule, 0 );
#endif
}
void __cdecl operator delete[] ( void *pMem ) throw()
{
#if !defined(USE_LIGHT_MEM_DEBUG) && !defined(USE_MEM_DEBUG)
g_pMemAlloc->Free(pMem);
#else
g_pMemAlloc->Free(pMem, ::g_pszModule, 0 );
#endif
}
#endif
//-----------------------------------------------------------------------------
// Override some debugging allocation methods in MSVC
// NOTE: These have to be here for release + debug builds in case we
// link to a debug static lib!!!
//-----------------------------------------------------------------------------
#ifndef _STATIC_LINKED
#ifdef _WIN32
// This here just hides the internal file names, etc of allocations
// made in the c runtime library
#define CRT_INTERNAL_FILE_NAME "C-runtime internal"
class CAttibCRT
{
public:
CAttibCRT(int nBlockUse) : m_nBlockUse(nBlockUse)
{
if (m_nBlockUse == _CRT_BLOCK)
{
g_pMemAlloc->PushAllocDbgInfo(CRT_INTERNAL_FILE_NAME, 0);
}
}
~CAttibCRT()
{
if (m_nBlockUse == _CRT_BLOCK)
{
g_pMemAlloc->PopAllocDbgInfo();
}
}
private:
int m_nBlockUse;
};
#define AttribIfCrt() CAttibCRT _attrib(nBlockUse)
#elif defined(POSIX) || defined( _PS3 )
#define AttribIfCrt()
#endif // _WIN32
extern "C"
{
void *__cdecl _nh_malloc_dbg( size_t nSize, int nFlag, int nBlockUse,
const char *pFileName, int nLine )
{
AttribIfCrt();
return MemAlloc_Alloc(nSize, pFileName, nLine);
}
void *__cdecl _malloc_dbg( size_t nSize, int nBlockUse,
const char *pFileName, int nLine )
{
AttribIfCrt();
return MemAlloc_Alloc(nSize, pFileName, nLine);
}
#if ( defined(_MSC_VER) && ( _MSC_VER >= 1600 ) ) || defined( _X360 )
void *__cdecl _calloc_dbg_impl( size_t nNum, size_t nSize, int nBlockUse,
const char * szFileName, int nLine, int * errno_tmp )
{
return _calloc_dbg( nNum, nSize, nBlockUse, szFileName, nLine );
}
#endif
void *__cdecl _calloc_dbg( size_t nNum, size_t nSize, int nBlockUse,
const char *pFileName, int nLine )
{
AttribIfCrt();
void *pMem = MemAlloc_Alloc(nSize * nNum, pFileName, nLine);
memset(pMem, 0, nSize * nNum);
return pMem;
}
void *__cdecl _realloc_dbg( void *pMem, size_t nNewSize, int nBlockUse,
const char *pFileName, int nLine )
{
AttribIfCrt();
return g_pMemAlloc->Realloc(pMem, nNewSize, pFileName, nLine);
}
void *__cdecl _expand_dbg( void *pMem, size_t nNewSize, int nBlockUse,
const char *pFileName, int nLine )
{
Assert( 0 );
return NULL;
}
void __cdecl _free_dbg( void *pMem, int nBlockUse )
{
AttribIfCrt();
#if !defined(USE_LIGHT_MEM_DEBUG) && !defined(USE_MEM_DEBUG)
g_pMemAlloc->Free(pMem);
#else
g_pMemAlloc->Free(pMem, ::g_pszModule, 0 );
#endif
}
size_t __cdecl _msize_dbg( void *pMem, int nBlockUse )
{
#ifdef _WIN32
return _msize(pMem);
#elif POSIX || _PS3
Assert( "_msize_dbg unsupported" );
return 0;
#endif
}
#ifdef _WIN32
#if defined(_DEBUG) && _MSC_VER >= 1300
// X360TBD: aligned and offset allocations may be important on the 360
// aligned base
ALLOC_CALL void *__cdecl _aligned_malloc_base( size_t size, size_t align )
{
return MemAlloc_AllocAligned( size, align );
}
ALLOC_CALL void *__cdecl _aligned_realloc_base( void *ptr, size_t size, size_t align )
{
return MemAlloc_ReallocAligned( ptr, size, align );
}
ALLOC_CALL void *__cdecl _aligned_recalloc_base( void *ptr, size_t size, size_t align )
{
Error( "Unsupported function\n" );
return NULL;
}
FREE_CALL void __cdecl _aligned_free_base( void *ptr )
{
MemAlloc_FreeAligned( ptr );
}
// aligned
ALLOC_CALL void * __cdecl _aligned_malloc( size_t size, size_t align )
{
return _aligned_malloc_base(size, align);
}
ALLOC_CALL void *__cdecl _aligned_realloc(void *memblock, size_t size, size_t align)
{
return _aligned_realloc_base(memblock, size, align);
}
ALLOC_CALL void * __cdecl _aligned_recalloc( void * memblock, size_t count, size_t size, size_t align )
{
return _aligned_recalloc_base(memblock, count * size, align);
}
FREE_CALL void __cdecl _aligned_free( void *memblock )
{
_aligned_free_base(memblock);
}
// aligned offset base
ALLOC_CALL void * __cdecl _aligned_offset_malloc_base( size_t size, size_t align, size_t offset )
{
Assert( IsPC() || 0 );
return NULL;
}
ALLOC_CALL void * __cdecl _aligned_offset_realloc_base( void * memblock, size_t size, size_t align, size_t offset)
{
Assert( IsPC() || 0 );
return NULL;
}
ALLOC_CALL void * __cdecl _aligned_offset_recalloc_base( void * memblock, size_t size, size_t align, size_t offset)
{
Assert( IsPC() || 0 );
return NULL;
}
// aligned offset
ALLOC_CALL void *__cdecl _aligned_offset_malloc(size_t size, size_t align, size_t offset)
{
return _aligned_offset_malloc_base( size, align, offset );
}
ALLOC_CALL void *__cdecl _aligned_offset_realloc(void *memblock, size_t size, size_t align, size_t offset)
{
return _aligned_offset_realloc_base( memblock, size, align, offset );
}
ALLOC_CALL void * __cdecl _aligned_offset_recalloc( void * memblock, size_t count, size_t size, size_t align, size_t offset )
{
return _aligned_offset_recalloc_base( memblock, count * size, align, offset );
}
#endif // _MSC_VER >= 1400
#endif
} // end extern "C"
//-----------------------------------------------------------------------------
// Override some the _CRT debugging allocation methods in MSVC
//-----------------------------------------------------------------------------
#ifdef _WIN32
extern "C"
{
int _CrtDumpMemoryLeaks(void)
{
return 0;
}
_CRT_DUMP_CLIENT _CrtSetDumpClient( _CRT_DUMP_CLIENT dumpClient )
{
return NULL;
}
int _CrtSetDbgFlag( int nNewFlag )
{
return g_pMemAlloc->CrtSetDbgFlag( nNewFlag );
}
// 64-bit port.
#define AFNAME(var) __p_ ## var
#define AFRET(var) &var
#if ( defined( _MSC_VER ) && _MSC_VER >= 1900)
//Do we need to do anything here for VS2015?
#else
int _crtDbgFlag = _CRTDBG_ALLOC_MEM_DF;
int* AFNAME(_crtDbgFlag)(void)
{
return AFRET(_crtDbgFlag);
}
long _crtBreakAlloc; /* Break on this allocation */
long* AFNAME(_crtBreakAlloc) (void)
{
return AFRET(_crtBreakAlloc);
}
#endif
void __cdecl _CrtSetDbgBlockType( void *pMem, int nBlockUse )
{
DebuggerBreak();
}
_CRT_ALLOC_HOOK __cdecl _CrtSetAllocHook( _CRT_ALLOC_HOOK pfnNewHook )
{
DebuggerBreak();
return NULL;
}
long __cdecl _CrtSetBreakAlloc( long lNewBreakAlloc )
{
return g_pMemAlloc->CrtSetBreakAlloc( lNewBreakAlloc );
}
int __cdecl _CrtIsValidHeapPointer( const void *pMem )
{
return g_pMemAlloc->CrtIsValidHeapPointer( pMem );
}
int __cdecl _CrtIsValidPointer( const void *pMem, unsigned int size, int access )
{
return g_pMemAlloc->CrtIsValidPointer( pMem, size, access );
}
int __cdecl _CrtCheckMemory( void )
{
// FIXME: Remove this when we re-implement the heap
return g_pMemAlloc->CrtCheckMemory( );
}
int __cdecl _CrtIsMemoryBlock( const void *pMem, unsigned int nSize,
long *plRequestNumber, char **ppFileName, int *pnLine )
{
DebuggerBreak();
return 1;
}
int __cdecl _CrtMemDifference( _CrtMemState *pState, const _CrtMemState * oldState, const _CrtMemState * newState )
{
DebuggerBreak();
return FALSE;
}
void __cdecl _CrtMemDumpStatistics( const _CrtMemState *pState )
{
DebuggerBreak();
}
void __cdecl _CrtMemCheckpoint( _CrtMemState *pState )
{
// FIXME: Remove this when we re-implement the heap
g_pMemAlloc->CrtMemCheckpoint( pState );
}
void __cdecl _CrtMemDumpAllObjectsSince( const _CrtMemState *pState )
{
DebuggerBreak();
}
void __cdecl _CrtDoForAllClientObjects( void (*pfn)(void *, void *), void * pContext )
{
DebuggerBreak();
}
//-----------------------------------------------------------------------------
// Methods in dbgrpt.cpp
//-----------------------------------------------------------------------------
long _crtAssertBusy = -1;
int __cdecl _CrtSetReportMode( int nReportType, int nReportMode )
{
return g_pMemAlloc->CrtSetReportMode( nReportType, nReportMode );
}
_HFILE __cdecl _CrtSetReportFile( int nRptType, _HFILE hFile )
{
return (_HFILE)g_pMemAlloc->CrtSetReportFile( nRptType, hFile );
}
_CRT_REPORT_HOOK __cdecl _CrtSetReportHook( _CRT_REPORT_HOOK pfnNewHook )
{
return (_CRT_REPORT_HOOK)g_pMemAlloc->CrtSetReportHook( pfnNewHook );
}
int __cdecl _CrtDbgReport( int nRptType, const char * szFile,
int nLine, const char * szModule, const char * szFormat, ... )
{
static char output[1024];
va_list args;
va_start( args, szFormat );
_vsnprintf( output, sizeof( output )-1, szFormat, args );
va_end( args );
return g_pMemAlloc->CrtDbgReport( nRptType, szFile, nLine, szModule, output );
}
#if _MSC_VER >= 1400
#if defined( _DEBUG ) && _MSC_VER < 1900
// wrapper which passes no debug info; not available in debug
void __cdecl _invalid_parameter_noinfo(void)
{
Assert(0);
}
#endif /* defined( _DEBUG ) */
#if defined( _DEBUG ) || defined( USE_MEM_DEBUG )
int __cdecl __crtMessageWindowW( int nRptType, const wchar_t * szFile, const wchar_t * szLine,
const wchar_t * szModule, const wchar_t * szUserMessage )
{
Assert(0);
return 0;
}
int __cdecl _CrtDbgReportV( int nRptType, const wchar_t *szFile, int nLine,
const wchar_t *szModule, const wchar_t *szFormat, va_list arglist )
{
Assert(0);
return 0;
}
int __cdecl _CrtDbgReportW( int nRptType, const wchar_t *szFile, int nLine,
const wchar_t *szModule, const wchar_t *szFormat, ...)
{
Assert(0);
return 0;
}
#if ( defined(_MSC_VER) && _MSC_VER >= 1900)
int __cdecl _VCrtDbgReportA(int nRptType, void *pReturnAddr, const char* szFile, int nLine,
const char *szModule, const char *szFormat, va_list arglist)
{
Assert(0);
return 0;
}
#else
int __cdecl _VCrtDbgReportA( int nRptType, const wchar_t * szFile, int nLine,
const wchar_t * szModule, const wchar_t * szFormat, va_list arglist )
{
Assert(0);
return 0;
}
#endif
int __cdecl _CrtSetReportHook2( int mode, _CRT_REPORT_HOOK pfnNewHook )
{
_CrtSetReportHook( pfnNewHook );
return 0;
}
#endif /* defined( _DEBUG ) || defined( USE_MEM_DEBUG ) */
extern "C" int __crtDebugCheckCount = FALSE;
extern "C" int __cdecl _CrtSetCheckCount( int fCheckCount )
{
int oldCheckCount = __crtDebugCheckCount;
return oldCheckCount;
}
extern "C" int __cdecl _CrtGetCheckCount( void )
{
return __crtDebugCheckCount;
}
// aligned offset debug
extern "C" void * __cdecl _aligned_offset_recalloc_dbg( void * memblock, size_t count, size_t size, size_t align, size_t offset, const char * f_name, int line_n )
{
Assert( IsPC() || 0 );
void *pMem = ReallocUnattributed( memblock, size * count );
if (!memblock)
{
memset(pMem, 0, size * count);
}
return pMem;
}
extern "C" void * __cdecl _aligned_recalloc_dbg( void *memblock, size_t count, size_t size, size_t align, const char * f_name, int line_n )
{
return _aligned_offset_recalloc_dbg(memblock, count, size, align, 0, f_name, line_n);
}
extern "C" void * __cdecl _recalloc_dbg ( void * memblock, size_t count, size_t size, int nBlockUse, const char * szFileName, int nLine )
{
return _aligned_offset_recalloc_dbg(memblock, count, size, 0, 0, szFileName, nLine);
}
_CRT_REPORT_HOOK __cdecl _CrtGetReportHook( void )
{
return NULL;
}
#endif
int __cdecl _CrtReportBlockType(const void * pUserData)
{
return 0;
}
} // end extern "C"
#endif // _WIN32
// Most files include this file, so when it's used it adds an extra .ValveDbg section,
// to help identify debug binaries.
#ifdef _WIN32
#ifndef NDEBUG // _DEBUG
#pragma data_seg("ValveDBG")
volatile const char* DBG = "*** DEBUG STUB ***";
#endif
#endif
#endif
// Extras added prevent dbgheap.obj from being included - DAL
#ifdef _WIN32
extern "C"
{
size_t __crtDebugFillThreshold = 0;
extern "C" void * __cdecl _heap_alloc_base (size_t size)
{
Assert(0);
return NULL;
}
void * __cdecl _heap_alloc_dbg( size_t nSize, int nBlockUse, const char * szFileName, int nLine)
{
return _heap_alloc(nSize);
}
// 64-bit
#ifdef _WIN64
static void * __cdecl realloc_help( void * pUserData, size_t * pnNewSize, int nBlockUse,const char * szFileName,
int nLine, int fRealloc )
{
Assert(0); // Shouldn't be needed
return NULL;
}
#else
static void * __cdecl realloc_help( void * pUserData, size_t nNewSize, int nBlockUse, const char * szFileName,
int nLine, int fRealloc)
{
Assert(0); // Shouldn't be needed
return NULL;
}
#endif
void __cdecl _free_nolock( void * pUserData)
{
// I don't think the second param is used in memoverride
_free_dbg(pUserData, 0);
}
void __cdecl _free_dbg_nolock( void * pUserData, int nBlockUse)
{
_free_dbg(pUserData, 0);
}
_CRT_ALLOC_HOOK __cdecl _CrtGetAllocHook ( void)
{
Assert(0);
return NULL;
}
static int __cdecl CheckBytes( unsigned char * pb, unsigned char bCheck, size_t nSize)
{
int bOkay = TRUE;
return bOkay;
}
_CRT_DUMP_CLIENT __cdecl _CrtGetDumpClient ( void)
{
Assert(0);
return NULL;
}
#if _MSC_VER >= 1400
static void __cdecl _printMemBlockData( _locale_t plocinfo, _CrtMemBlockHeader * pHead)
{
}
static void __cdecl _CrtMemDumpAllObjectsSince_stat( const _CrtMemState * state, _locale_t plocinfo)
{
}
#endif
void * __cdecl _aligned_malloc_dbg( size_t size, size_t align, const char * f_name, int line_n)
{
return _aligned_malloc(size, align);
}
void * __cdecl _aligned_realloc_dbg( void *memblock, size_t size, size_t align,
const char * f_name, int line_n)
{
return _aligned_realloc(memblock, size, align);
}
void * __cdecl _aligned_offset_malloc_dbg( size_t size, size_t align, size_t offset,
const char * f_name, int line_n)
{
return _aligned_offset_malloc(size, align, offset);
}
void * __cdecl _aligned_offset_realloc_dbg( void * memblock, size_t size, size_t align,
size_t offset, const char * f_name, int line_n)
{
return _aligned_offset_realloc(memblock, size, align, offset);
}
void __cdecl _aligned_free_dbg( void * memblock)
{
_aligned_free(memblock);
}
#if _MSC_VER < 1900
size_t __cdecl _CrtSetDebugFillThreshold( size_t _NewDebugFillThreshold)
{
Assert(0);
return 0;
}
#endif
//===========================================
// NEW!!! 64-bit
#if (_MSC_VER < 1900) || !defined( _DEBUG )
char * __cdecl _strdup ( const char * string )
{
int nSize = strlen(string) + 1;
char *pCopy = (char*)AllocUnattributed( nSize );
if ( pCopy )
memcpy( pCopy, string, nSize );
return pCopy;
}
#endif
#if 0
_TSCHAR * __cdecl _tfullpath_dbg ( _TSCHAR *UserBuf, const _TSCHAR *path, size_t maxlen, int nBlockUse, const char * szFileName, int nLine )
{
Assert(0);
return NULL;
}
_TSCHAR * __cdecl _tfullpath ( _TSCHAR *UserBuf, const _TSCHAR *path, size_t maxlen )
{
Assert(0);
return NULL;
}
_TSCHAR * __cdecl _tgetdcwd_lk_dbg ( int drive, _TSCHAR *pnbuf, int maxlen, int nBlockUse, const char * szFileName, int nLine )
{
Assert(0);
return NULL;
}
_TSCHAR * __cdecl _tgetdcwd_nolock ( int drive, _TSCHAR *pnbuf, int maxlen )
{
Assert(0);
return NULL;
}
errno_t __cdecl _tdupenv_s_helper ( _TSCHAR **pBuffer, size_t *pBufferSizeInTChars, const _TSCHAR *varname, int nBlockUse, const char * szFileName, int nLine )
{
Assert(0);
return 0;
}
errno_t __cdecl _tdupenv_s_helper ( _TSCHAR **pBuffer, size_t *pBufferSizeInTChars, const _TSCHAR *varname )
{
Assert(0);
return 0;
}
_TSCHAR * __cdecl _ttempnam_dbg ( const _TSCHAR *dir, const _TSCHAR *pfx, int nBlockUse, const char * szFileName, int nLine )
{
Assert(0);
return 0;
}
_TSCHAR * __cdecl _ttempnam ( const _TSCHAR *dir, const _TSCHAR *pfx )
{
Assert(0);
return 0;
}
wchar_t * __cdecl _wcsdup_dbg ( const wchar_t * string, int nBlockUse, const char * szFileName, int nLine )
{
Assert(0);
return 0;
}
wchar_t * __cdecl _wcsdup ( const wchar_t * string )
{
Assert(0);
return 0;
}
#endif
} // end extern "C"
#if _MSC_VER >= 1400
//-----------------------------------------------------------------------------
// XBox Memory Allocator Override
//-----------------------------------------------------------------------------
#if defined( _X360 )
#if defined( _DEBUG ) || defined( USE_MEM_DEBUG )
#include "utlmap.h"
MEMALLOC_DEFINE_EXTERNAL_TRACKING( XMem );
CThreadFastMutex g_XMemAllocMutex;
void XMemAlloc_RegisterAllocation( void *p, DWORD dwAllocAttributes )
{
if ( !g_pMemAlloc )
{
// core xallocs cannot be journaled until system is ready
return;
}
AUTO_LOCK_FM( g_XMemAllocMutex );
int size = XMemSize( p, dwAllocAttributes );
MemAlloc_RegisterExternalAllocation( XMem, p, size );
}
void XMemAlloc_RegisterDeallocation( void *p, DWORD dwAllocAttributes )
{
if ( !g_pMemAlloc )
{
// core xallocs cannot be journaled until system is ready
return;
}
AUTO_LOCK_FM( g_XMemAllocMutex );
int size = XMemSize( p, dwAllocAttributes );
MemAlloc_RegisterExternalDeallocation( XMem, p, size );
}
#else
#define XMemAlloc_RegisterAllocation( p, a ) ((void)0)
#define XMemAlloc_RegisterDeallocation( p, a ) ((void)0)
#endif
//-----------------------------------------------------------------------------
// XMemAlloc
//
// XBox Memory Allocator Override
//-----------------------------------------------------------------------------
LPVOID WINAPI XMemAlloc( SIZE_T dwSize, DWORD dwAllocAttributes )
{
LPVOID ptr;
XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes;
bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL );
if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI )
{
MEM_ALLOC_CREDIT();
switch ( pAttribs->dwAlignment )
{
case XALLOC_ALIGNMENT_4:
#if !defined(USE_LIGHT_MEM_DEBUG) && !defined(USE_MEM_DEBUG)
ptr = MemAlloc_Alloc( dwSize );
#else
ptr = MemAlloc_Alloc(dwSize, ::g_pszModule, 0);
#endif
break;
case XALLOC_ALIGNMENT_8:
ptr = MemAlloc_AllocAligned( dwSize, 8 );
break;
case XALLOC_ALIGNMENT_DEFAULT:
case XALLOC_ALIGNMENT_16:
default:
ptr = MemAlloc_AllocAligned( dwSize, 16 );
break;
}
if ( pAttribs->dwZeroInitialize != 0 )
{
memset( ptr, 0, XMemSize( ptr, dwAllocAttributes ) );
}
return ptr;
}
ptr = XMemAllocDefault( dwSize, dwAllocAttributes );
if ( ptr )
{
XMemAlloc_RegisterAllocation( ptr, dwAllocAttributes );
}
return ptr;
}
//-----------------------------------------------------------------------------
// XMemFree
//
// XBox Memory Allocator Override
//-----------------------------------------------------------------------------
VOID WINAPI XMemFree( PVOID pAddress, DWORD dwAllocAttributes )
{
if ( !pAddress )
{
return;
}
XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes;
bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL );
if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI )
{
switch ( pAttribs->dwAlignment )
{
case XALLOC_ALIGNMENT_4:
#if !defined(USE_LIGHT_MEM_DEBUG) && !defined(USE_MEM_DEBUG)
return g_pMemAlloc->Free( pAddress );
#else
return g_pMemAlloc->Free( pAddress, ::g_pszModule, 0 );
#endif
default:
return MemAlloc_FreeAligned( pAddress );
}
return;
}
XMemAlloc_RegisterDeallocation( pAddress, dwAllocAttributes );
XMemFreeDefault( pAddress, dwAllocAttributes );
}
//-----------------------------------------------------------------------------
// XMemSize
//
// XBox Memory Allocator Override
//-----------------------------------------------------------------------------
SIZE_T WINAPI XMemSize( PVOID pAddress, DWORD dwAllocAttributes )
{
XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes;
bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL );
if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI )
{
switch ( pAttribs->dwAlignment )
{
case XALLOC_ALIGNMENT_4:
return g_pMemAlloc->GetSize( pAddress );
default:
return MemAlloc_GetSizeAligned( pAddress );
}
}
return XMemSizeDefault( pAddress, dwAllocAttributes );
}
#endif // _X360
#define MAX_LANG_LEN 64 /* max language name length */
#define MAX_CTRY_LEN 64 /* max country name length */
#define MAX_MODIFIER_LEN 0 /* max modifier name length - n/a */
#define MAX_LC_LEN (MAX_LANG_LEN+MAX_CTRY_LEN+MAX_MODIFIER_LEN+3)
#if _MSC_VER >= 1700 // VS 11 (VS 2012)
// Copied from C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\mtdll.h
#ifndef _SETLOC_STRUCT_DEFINED
struct _is_ctype_compatible {
unsigned long id;
int is_clike;
};
typedef struct setloc_struct {
/* getqloc static variables */
wchar_t *pchLanguage;
wchar_t *pchCountry;
int iLocState;
int iPrimaryLen;
BOOL bAbbrevLanguage;
BOOL bAbbrevCountry;
UINT _cachecp;
wchar_t _cachein[MAX_LC_LEN];
wchar_t _cacheout[MAX_LC_LEN];
/* _setlocale_set_cat (LC_CTYPE) static variable */
struct _is_ctype_compatible _Loc_c[5];
wchar_t _cacheLocaleName[LOCALE_NAME_MAX_LENGTH];
} _setloc_struct, *_psetloc_struct;
#define _SETLOC_STRUCT_DEFINED
#endif /* _SETLOC_STRUCT_DEFINED */
_CRTIMP extern unsigned long __cdecl __threadid(void);
#define _threadid (__threadid())
_CRTIMP extern uintptr_t __cdecl __threadhandle(void);
#define _threadhandle (__threadhandle())
/* Structure for each thread's data */
struct _tiddata {
unsigned long _tid; /* thread ID */
uintptr_t _thandle; /* thread handle */
int _terrno; /* errno value */
unsigned long _tdoserrno; /* _doserrno value */
unsigned int _fpds; /* Floating Point data segment */
unsigned long _holdrand; /* rand() seed value */
char * _token; /* ptr to strtok() token */
wchar_t * _wtoken; /* ptr to wcstok() token */
unsigned char * _mtoken; /* ptr to _mbstok() token */
/* following pointers get malloc'd at runtime */
char * _errmsg; /* ptr to strerror()/_strerror() buff */
wchar_t * _werrmsg; /* ptr to _wcserror()/__wcserror() buff */
char * _namebuf0; /* ptr to tmpnam() buffer */
wchar_t * _wnamebuf0; /* ptr to _wtmpnam() buffer */
char * _namebuf1; /* ptr to tmpfile() buffer */
wchar_t * _wnamebuf1; /* ptr to _wtmpfile() buffer */
char * _asctimebuf; /* ptr to asctime() buffer */
wchar_t * _wasctimebuf; /* ptr to _wasctime() buffer */
void * _gmtimebuf; /* ptr to gmtime() structure */
char * _cvtbuf; /* ptr to ecvt()/fcvt buffer */
unsigned char _con_ch_buf[MB_LEN_MAX];
/* ptr to putch() buffer */
unsigned short _ch_buf_used; /* if the _con_ch_buf is used */
/* following fields are needed by _beginthread code */
void * _initaddr; /* initial user thread address */
void * _initarg; /* initial user thread argument */
/* following three fields are needed to support signal handling and
* runtime errors */
void * _pxcptacttab; /* ptr to exception-action table */
void * _tpxcptinfoptrs; /* ptr to exception info pointers */
int _tfpecode; /* float point exception code */
#if ( defined( _MSC_VER ) && _MSC_VER >= 1900)
void *ptmbcinfo_dummy;
void *ptlocinfo_dummy;
#else
/* pointer to the copy of the multibyte character information used by
* the thread */
pthreadmbcinfo ptmbcinfo;
/* pointer to the copy of the locale informaton used by the thead */
pthreadlocinfo ptlocinfo;
#endif
int _ownlocale; /* if 1, this thread owns its own locale */
/* following field is needed by NLG routines */
unsigned long _NLG_dwCode;
/*
* Per-Thread data needed by C++ Exception Handling
*/
void * _terminate; /* terminate() routine */
void * _unexpected; /* unexpected() routine */
void * _translator; /* S.E. translator */
void * _purecall; /* called when pure virtual happens */
void * _curexception; /* current exception */
void * _curcontext; /* current exception context */
int _ProcessingThrow; /* for uncaught_exception */
void * _curexcspec; /* for handling exceptions thrown from std::unexpected */
#if defined (_M_X64) || defined (_M_ARM)
void * _pExitContext;
void * _pUnwindContext;
void * _pFrameInfoChain;
#if defined (_WIN64)
unsigned __int64 _ImageBase;
unsigned __int64 _ThrowImageBase;
#else /* defined (_WIN64) */
unsigned __int32 _ImageBase;
unsigned __int32 _ThrowImageBase;
#endif /* defined (_WIN64) */
void * _pForeignException;
#elif defined (_M_IX86)
void * _pFrameInfoChain;
#endif /* defined (_M_IX86) */
_setloc_struct _setloc_data;
void * _reserved1; /* nothing */
void * _reserved2; /* nothing */
void * _reserved3; /* nothing */
#ifdef _M_IX86
void * _reserved4; /* nothing */
void * _reserved5; /* nothing */
#endif /* _M_IX86 */
int _cxxReThrow; /* Set to True if it's a rethrown C++ Exception */
unsigned long __initDomain; /* initial domain used by _beginthread[ex] for managed function */
};
#else // _MSC_VER >= 1700 // VS 11 (VS 2012)
struct _is_ctype_compatible {
unsigned long id;
int is_clike;
};
typedef struct setloc_struct {
/* getqloc static variables */
char *pchLanguage;
char *pchCountry;
int iLcidState;
int iPrimaryLen;
BOOL bAbbrevLanguage;
BOOL bAbbrevCountry;
LCID lcidLanguage;
LCID lcidCountry;
/* expand_locale static variables */
LC_ID _cacheid;
UINT _cachecp;
char _cachein[MAX_LC_LEN];
char _cacheout[MAX_LC_LEN];
/* _setlocale_set_cat (LC_CTYPE) static variable */
struct _is_ctype_compatible _Lcid_c[5];
} _setloc_struct, *_psetloc_struct;
struct _tiddata {
unsigned long _tid; /* thread ID */
uintptr_t _thandle; /* thread handle */
int _terrno; /* errno value */
unsigned long _tdoserrno; /* _doserrno value */
unsigned int _fpds; /* Floating Point data segment */
unsigned long _holdrand; /* rand() seed value */
char * _token; /* ptr to strtok() token */
wchar_t * _wtoken; /* ptr to wcstok() token */
unsigned char * _mtoken; /* ptr to _mbstok() token */
/* following pointers get malloc'd at runtime */
char * _errmsg; /* ptr to strerror()/_strerror() buff */
wchar_t * _werrmsg; /* ptr to _wcserror()/__wcserror() buff */
char * _namebuf0; /* ptr to tmpnam() buffer */
wchar_t * _wnamebuf0; /* ptr to _wtmpnam() buffer */
char * _namebuf1; /* ptr to tmpfile() buffer */
wchar_t * _wnamebuf1; /* ptr to _wtmpfile() buffer */
char * _asctimebuf; /* ptr to asctime() buffer */
wchar_t * _wasctimebuf; /* ptr to _wasctime() buffer */
void * _gmtimebuf; /* ptr to gmtime() structure */
char * _cvtbuf; /* ptr to ecvt()/fcvt buffer */
unsigned char _con_ch_buf[MB_LEN_MAX];
/* ptr to putch() buffer */
unsigned short _ch_buf_used; /* if the _con_ch_buf is used */
/* following fields are needed by _beginthread code */
void * _initaddr; /* initial user thread address */
void * _initarg; /* initial user thread argument */
/* following three fields are needed to support signal handling and
* runtime errors */
void * _pxcptacttab; /* ptr to exception-action table */
void * _tpxcptinfoptrs; /* ptr to exception info pointers */
int _tfpecode; /* float point exception code */
/* pointer to the copy of the multibyte character information used by
* the thread */
pthreadmbcinfo ptmbcinfo;
/* pointer to the copy of the locale informaton used by the thead */
pthreadlocinfo ptlocinfo;
int _ownlocale; /* if 1, this thread owns its own locale */
/* following field is needed by NLG routines */
unsigned long _NLG_dwCode;
/*
* Per-Thread data needed by C++ Exception Handling
*/
void * _terminate; /* terminate() routine */
void * _unexpected; /* unexpected() routine */
void * _translator; /* S.E. translator */
void * _purecall; /* called when pure virtual happens */
void * _curexception; /* current exception */
void * _curcontext; /* current exception context */
int _ProcessingThrow; /* for uncaught_exception */
void * _curexcspec; /* for handling exceptions thrown from std::unexpected */
#if defined (_M_IA64) || defined (_M_AMD64)
void * _pExitContext;
void * _pUnwindContext;
void * _pFrameInfoChain;
unsigned __int64 _ImageBase;
#if defined (_M_IA64)
unsigned __int64 _TargetGp;
#endif /* defined (_M_IA64) */
unsigned __int64 _ThrowImageBase;
void * _pForeignException;
#elif defined (_M_IX86)
void * _pFrameInfoChain;
#endif /* defined (_M_IX86) */
_setloc_struct _setloc_data;
void * _encode_ptr; /* EncodePointer() routine */
void * _decode_ptr; /* DecodePointer() routine */
void * _reserved1; /* nothing */
void * _reserved2; /* nothing */
void * _reserved3; /* nothing */
int _cxxReThrow; /* Set to True if it's a rethrown C++ Exception */
unsigned long __initDomain; /* initial domain used by _beginthread[ex] for managed function */
};
#endif // _MSC_VER >= 1700 // VS 11 (VS 2012)
typedef struct _tiddata * _ptiddata;
#if (defined( _MSC_VER ) && _MSC_VER >= 1900)
//Do we need anything in here?
#else
class _LocaleUpdate
{
_locale_tstruct localeinfo;
_ptiddata ptd;
bool updated;
public:
_LocaleUpdate(_locale_t plocinfo)
: updated(false)
{
/*
if (plocinfo == NULL)
{
ptd = _getptd();
localeinfo.locinfo = ptd->ptlocinfo;
localeinfo.mbcinfo = ptd->ptmbcinfo;
__UPDATE_LOCALE(ptd, localeinfo.locinfo);
__UPDATE_MBCP(ptd, localeinfo.mbcinfo);
if (!(ptd->_ownlocale & _PER_THREAD_LOCALE_BIT))
{
ptd->_ownlocale |= _PER_THREAD_LOCALE_BIT;
updated = true;
}
}
else
{
localeinfo=*plocinfo;
}
*/
}
~_LocaleUpdate()
{
// if (updated)
// ptd->_ownlocale = ptd->_ownlocale & ~_PER_THREAD_LOCALE_BIT;
}
_locale_t GetLocaleT()
{
return &localeinfo;
}
};
#endif //_MSC_VER
#pragma warning(push)
#pragma warning(disable: 4483)
#if _MSC_FULL_VER >= 140050415
#define _NATIVE_STARTUP_NAMESPACE __identifier("<CrtImplementationDetails>")
#else /* _MSC_FULL_VER >= 140050415 */
#define _NATIVE_STARTUP_NAMESPACE __CrtImplementationDetails
#endif /* _MSC_FULL_VER >= 140050415 */
namespace _NATIVE_STARTUP_NAMESPACE
{
class NativeDll
{
private:
static const unsigned int ProcessDetach = 0;
static const unsigned int ProcessAttach = 1;
static const unsigned int ThreadAttach = 2;
static const unsigned int ThreadDetach = 3;
static const unsigned int ProcessVerifier = 4;
public:
inline static bool IsInDllMain()
{
return false;
}
inline static bool IsInProcessAttach()
{
return false;
}
inline static bool IsInProcessDetach()
{
return false;
}
inline static bool IsInVcclrit()
{
return false;
}
inline static bool IsSafeForManagedCode()
{
if (!IsInDllMain())
{
return true;
}
if (IsInVcclrit())
{
return true;
}
return !IsInProcessAttach() && !IsInProcessDetach();
}
};
}
#pragma warning(pop)
#endif // _MSC_VER >= 1400
#endif // !STEAM && !NO_MALLOC_OVERRIDE
#endif // _WIN32
#endif // _PS3