Source code of Windows XP (NT5)
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.

539 lines
14 KiB

  1. /***
  2. *rtcpriv.h - declarations and definitions for RTC use
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Contains the declarations and definitions for all RunTime Check
  8. * support.
  9. *
  10. *Revision History:
  11. * ??-??-?? KBF Created implementation header for RTC
  12. * 05-26-99 KBF Removed RTCl & RTCv, added _RTC_ADVMEM stuff
  13. * 10-14-99 PML Replace InitializeCriticalSection with wrapper function
  14. * __crtInitCritSecAndSpinCount
  15. *
  16. ****/
  17. #ifndef _INC_RTCPRIV
  18. #define _INC_RTCPRIV
  19. #ifdef _RTC
  20. #include <windows.h>
  21. #include <winbase.h>
  22. #include <malloc.h>
  23. #include "rtcapi.h"
  24. #pragma warning(disable:4710)
  25. #pragma warning(disable:4711)
  26. #ifndef __cplusplus
  27. #error This header is only for use with the C++ compiler while building the RTC library code.
  28. #endif
  29. #ifdef _MSC_VER
  30. #pragma pack(push, 4)
  31. #endif /* _MSC_VER */
  32. #ifndef _RTC_DEBUG
  33. #pragma optimize("gb1", on)
  34. #endif
  35. // Multithreaded code locking stuff...
  36. #define INIT_LOCK __crtInitCritSecAndSpinCount(&_RTC_memlock, _CRT_SPINCOUNT)
  37. #define LOCK EnterCriticalSection(&_RTC_memlock)
  38. #define UNLOCK LeaveCriticalSection(&_RTC_memlock)
  39. #define DEL_LOCK DeleteCriticalSection(&_RTC_memlock)
  40. #define TRY_LOCK TryEnterCriticalSection(&_RTC_memlock)
  41. extern CRITICAL_SECTION _RTC_memlock;
  42. // Typedefs
  43. struct _RTC_globals;
  44. #ifdef _RTC_ADVMEM
  45. class _RTC_SimpleHeap;
  46. class _RTC_Container;
  47. class _RTC_HeapBlock;
  48. class _RTC_BinaryTree;
  49. template<class T> class HashTable;
  50. typedef unsigned char shadowtag;
  51. typedef unsigned char index_elem;
  52. #endif
  53. // General global functions & symbols
  54. extern int _RTC_ErrorLevels[_RTC_ILLEGAL];
  55. extern _RTC_globals *_RTC_globptr;
  56. bool _RTC_Lock();
  57. void _RTC_Unlock();
  58. void _RTC_Failure(void *retaddr, int errnum);
  59. _RTC_error_fn _RTC_GetErrorFunc(LPCVOID addr);
  60. void _RTC_StackFailure(void *retaddr, const char *varname);
  61. BOOL _RTC_GetSrcLine(DWORD address, char* source, int sourcelen,
  62. int* pline, char** moduleName);
  63. extern "C" {
  64. void __fastcall _RTC_APISet(int on_off);
  65. }
  66. void _RTC_NotifyOthersOfChange(void *addr);
  67. // When this changes, you'd better be sure that everything still works with the old stuff!
  68. #define _RTC_CURRENT_VERSION 1
  69. // The order of the initial stuff here can't change AT ALL!!!
  70. struct _RTC_Funcs {
  71. _RTC_error_fn err;
  72. void (*notify)(void);
  73. void *allocationBase;
  74. _RTC_Funcs *next;
  75. #ifdef _RTC_ADVMEM
  76. int (*shadowoff)(void);
  77. #endif
  78. };
  79. // definitions of library globals
  80. // The order of this stuff MUST STAY THE SAME BETWEEN VERSION!!!
  81. struct _RTC_globals {
  82. int version;
  83. CRITICAL_SECTION memlock;
  84. _RTC_Funcs *callbacks;
  85. #ifdef _RTC_ADVMEM
  86. _RTC_SimpleHeap *heap2;
  87. _RTC_SimpleHeap *heap4;
  88. _RTC_SimpleHeap *heap8;
  89. _RTC_Container *memhier;
  90. shadowtag *shadow;
  91. index_elem *pageidx;
  92. HashTable<_RTC_HeapBlock> *heapblocks;
  93. bool *pi_array;
  94. bool shadowmemory;
  95. #endif
  96. };
  97. #define _RTC_GLOBALS_SIZE 1024
  98. /* Shadow Memory stuff */
  99. #ifdef _RTC_ADVMEM
  100. void _RTC_MS_Init();
  101. void _RTC_MemFailure(void *retaddr, int errnum, const void *assign);
  102. short _RTC_MSAllocShadow(memptr addr, unsigned size, unsigned state);
  103. void _RTC_MSRestoreShadow(memptr addr, unsigned size, short id);
  104. short _RTC_MSRenumberShadow(memptr addr, unsigned size, short notID);
  105. void _RTC_MSFreeShadow(memptr addr, unsigned size);
  106. void __cdecl _RTC_MSAllocateGlobals(void);
  107. void _RTC_MSDecommitRange(memptr addr, unsigned size);
  108. void _RTC_MSCommitRange(memptr addr, unsigned size, unsigned state);
  109. extern "C" {
  110. void __fastcall _RTC_CheckMem_API(memref addr, unsigned size);
  111. }
  112. // Unknown MUST be 0
  113. #define IDX_STATE_UNKNOWN 0
  114. #define IDX_STATE_ILLEGAL 1
  115. #define IDX_STATE_PARTIALLY_KNOWN 2
  116. #define IDX_STATE_FULLY_KNOWN 3
  117. extern _RTC_Container *_RTC_memhier;
  118. extern HashTable<_RTC_HeapBlock> *_RTC_heapblocks;
  119. extern _RTC_SimpleHeap *_RTC_heap2;
  120. extern _RTC_SimpleHeap *_RTC_heap4;
  121. extern _RTC_SimpleHeap *_RTC_heap8;
  122. extern shadowtag *_RTC_shadow;
  123. extern index_elem *_RTC_pageidx;
  124. extern bool *_RTC_pi_array;
  125. extern bool _RTC_shadowmemory;
  126. /**********************************/
  127. #define ALLOC_SIZE 65536
  128. class _RTC_SimpleHeap
  129. {
  130. struct FreeList
  131. {
  132. FreeList *next;
  133. };
  134. struct HeapNode
  135. {
  136. HeapNode *next; // next page in list (not necessarily free)
  137. FreeList *free; // node-local free-list
  138. union info
  139. {
  140. struct topStuff
  141. { // Stuff that pertains only to the top node
  142. HeapNode *nxtFree; // Pointer to node containing free items
  143. short wordSize; // The size of blocks in this heap
  144. bool freePage; // True if there's a 100% free page
  145. } top;
  146. struct nonTopStuff
  147. { // Stuff that pertais only to non-top nodes
  148. unsigned freeCount; // The free count for this node
  149. HeapNode *prev; // previous link
  150. } nontop;
  151. } inf;
  152. } head;
  153. public:
  154. _RTC_SimpleHeap(unsigned blockSize) throw();
  155. ~_RTC_SimpleHeap() throw();
  156. void *operator new(unsigned) throw();
  157. void operator delete(void *addr) throw();
  158. void *alloc() throw();
  159. void free(void *addr) throw();
  160. };
  161. extern _RTC_SimpleHeap *_RTC_heap2;
  162. extern _RTC_SimpleHeap *_RTC_heap4;
  163. extern _RTC_SimpleHeap *_RTC_heap8;
  164. #define DATA(type, name) \
  165. private: \
  166. type _##name; \
  167. public: \
  168. type name() const { return _##name; }\
  169. void name(type a) { _##name = a; }
  170. class _RTC_HeapBlock
  171. {
  172. DATA(void *, addr); // The memory block address
  173. DATA(unsigned, size); // The size of the block
  174. DATA(_RTC_HeapBlock *, next); // The next element
  175. DATA(_RTC_HeapBlock **,list); // The head list pointer
  176. DATA(short, id); // The level ID of the block (for tiers)
  177. DATA(short, tag); // The shadow tag of the block in shadow memory
  178. public:
  179. _RTC_HeapBlock(void *address, short lev)
  180. : _addr(address), _id(lev) , _next(0), _list(0) {}
  181. _RTC_HeapBlock(void *MemAddress, short Identifier, unsigned Size)
  182. : _addr(MemAddress), _id(Identifier), _size(Size), _next(0), _list(0) {}
  183. ~_RTC_HeapBlock() throw()
  184. {
  185. if (_list) del(_list);
  186. }
  187. void *operator new(unsigned) throw()
  188. {
  189. return _RTC_heap8->alloc();
  190. }
  191. void operator delete(void *addr) throw()
  192. {
  193. _RTC_heap8->free(addr);
  194. }
  195. int operator<(const _RTC_HeapBlock &h) const
  196. {
  197. return _addr < h._addr;
  198. }
  199. int operator==(const _RTC_HeapBlock &h) const
  200. {
  201. return h._addr == _addr && h._id == _id;
  202. }
  203. bool contains(const _RTC_HeapBlock &h) const
  204. {
  205. return ((unsigned)_addr <= (unsigned)h._addr) &&
  206. ((unsigned)h._addr < (unsigned)_addr + _size);
  207. }
  208. unsigned hash(unsigned sz) const
  209. {
  210. return (((unsigned)_addr) ^ _id) % sz;
  211. }
  212. void add(_RTC_HeapBlock **lstHead) throw()
  213. {
  214. this->next(*lstHead);
  215. this->list(lstHead);
  216. *lstHead = this;
  217. }
  218. void del(_RTC_HeapBlock **lstHead) throw()
  219. {
  220. _RTC_HeapBlock *head = *lstHead;
  221. _RTC_HeapBlock *prev = 0;
  222. while (head != this)
  223. {
  224. prev = head;
  225. head = head->next();
  226. }
  227. if (prev)
  228. prev->next(this->next());
  229. else
  230. *lstHead = this->next();
  231. next(0);
  232. list(0);
  233. }
  234. };
  235. #undef DATA
  236. class _RTC_BinaryTree
  237. {
  238. public:
  239. class BinaryNode
  240. {
  241. public:
  242. BinaryNode *l, *r;
  243. _RTC_Container *val;
  244. void *operator new(unsigned) throw()
  245. {
  246. return _RTC_heap4->alloc();
  247. }
  248. void operator delete(void *addr) throw()
  249. {
  250. _RTC_heap4->free(addr);
  251. }
  252. BinaryNode(BinaryNode *L, BinaryNode *R, _RTC_Container *V)
  253. : l(L), r(R), val(V) {}
  254. void kill() throw();
  255. };
  256. private:
  257. BinaryNode *tree;
  258. public:
  259. _RTC_BinaryTree(_RTC_Container *i) throw()
  260. : tree(new BinaryNode(0, 0, i)) {}
  261. ~_RTC_BinaryTree() throw()
  262. {
  263. if (tree)
  264. {
  265. tree->kill();
  266. delete tree;
  267. }
  268. }
  269. void *operator new(unsigned) throw()
  270. {
  271. return _RTC_heap2->alloc();
  272. }
  273. void operator delete(void *addr) throw() { _RTC_heap2->free(addr); }
  274. // This will return either the container or null
  275. _RTC_Container *get(_RTC_HeapBlock *) throw();
  276. // This just adds to the current sib list
  277. _RTC_Container* add(_RTC_HeapBlock *) throw();
  278. // This just removes the item from the current sib list
  279. _RTC_Container *del(_RTC_HeapBlock *) throw();
  280. // Here's an iterator
  281. class iter
  282. {
  283. _RTC_Container **allSibs;
  284. int curSib;
  285. int totSibs;
  286. friend class _RTC_BinaryTree;
  287. public:
  288. // This thing should never be allocated...
  289. void *operator new(unsigned)
  290. {
  291. return 0;
  292. }
  293. };
  294. _RTC_Container *FindFirst(iter *) throw();
  295. _RTC_Container *FindNext(iter *) throw();
  296. };
  297. class _RTC_Container
  298. {
  299. // kids - the item that has all the children
  300. _RTC_BinaryTree *kids;
  301. // inf - the item that specifies containment
  302. _RTC_HeapBlock *inf;
  303. // This kills this container, and all contained info
  304. void kill() throw();
  305. public:
  306. _RTC_Container(_RTC_HeapBlock *hb)
  307. : inf(hb), kids(0) {}
  308. ~_RTC_Container() throw()
  309. {
  310. if (inf || kids)
  311. kill();
  312. }
  313. _RTC_HeapBlock *info() const
  314. {
  315. return inf;
  316. }
  317. bool contains(const _RTC_HeapBlock *i) const throw()
  318. {
  319. return inf ? inf->contains(*i) : true;
  320. }
  321. // Returns the parent container
  322. _RTC_Container *DelChild(_RTC_HeapBlock *i) throw();
  323. // Add this item as a child inside this container
  324. // It may or may not be a direct child
  325. // It returns the parent container
  326. _RTC_Container *AddChild(_RTC_HeapBlock *i) throw();
  327. // Find the container that contains the data given
  328. _RTC_Container *FindChild(_RTC_HeapBlock *i) throw();
  329. typedef _RTC_HeapBlock data;
  330. void *operator new(unsigned) throw() { return _RTC_heap2->alloc(); }
  331. void operator delete(void *addr) throw() { _RTC_heap2->free(addr); }
  332. };
  333. template <class T>
  334. class HashTable
  335. {
  336. unsigned size;
  337. T **elems;
  338. public:
  339. HashTable(unsigned s, void *mem)
  340. : elems((T**)mem), size(s)
  341. {
  342. memset(elems, 0, size * sizeof(T*));
  343. }
  344. ~HashTable() {}
  345. void *operator new(unsigned) throw()
  346. {
  347. return _RTC_heap2->alloc();
  348. }
  349. void operator delete(void *addr) throw()
  350. {
  351. _RTC_heap2->free(addr);
  352. }
  353. T *find(T *key) throw()
  354. {
  355. unsigned hkey = key->hash(size);
  356. T *elem = elems[hkey];
  357. while (elem && !(*elem == *key))
  358. elem = elem->next();
  359. return elem;
  360. }
  361. void add(T *itm) throw()
  362. {
  363. unsigned hkey = itm->hash(size);
  364. itm->add(&elems[hkey]);
  365. }
  366. void del(T *key) throw()
  367. {
  368. unsigned hkey = key->hash(size);
  369. T *elem = elems[hkey];
  370. while (elem && !(*elem == *key))
  371. elem = elem->next();
  372. elem->del(&elems[hkey]);
  373. }
  374. };
  375. #endif
  376. // Stuff for the debugger exception mechanism
  377. // Swiped fro vcexcept.h in the LangAPI
  378. #if !defined(_vcexcept_h)
  379. #define _vcexcept_h
  380. // the facility code we have chosen is based on the fact that we already
  381. // use an exception of 'msc' when we throw C++ exceptions
  382. #define FACILITY_VISUALCPP ((LONG)0x6D)
  383. #define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)
  384. /////////////////////////////////////////////////////////////////
  385. // define all exceptions here, so we don't mess with each other
  386. /////////////////////////////////////////////////////////////////
  387. // used by CRTs for C++ exceptions, really defined in ehdata.h
  388. //#define EH_EXCEPTION_NUMBER VcppException( 3<<30, 0x7363 ) // SEV_ERROR, used by CRTs for C++
  389. // used by debugger to do e.g. SetThreadName call
  390. #define EXCEPTION_VISUALCPP_DEBUGGER VcppException(1<<30, 5000) // SEV_INFORMATIONAL
  391. #endif // _vcexcept_h
  392. // Ping the VC debugger
  393. #define HelloVC( exinfo ) \
  394. RaiseException( EXCEPTION_VISUALCPP_DEBUGGER, 0, sizeof(exinfo)/sizeof(DWORD), (DWORD*)&exinfo )
  395. enum EXCEPTION_DEBUGGER_ENUM
  396. {
  397. EXCEPTION_DEBUGGER_NAME_THREAD = 0x1000,
  398. EXCEPTION_DEBUGGER_PROBE = 0x1001,
  399. EXCEPTION_DEBUGGER_RUNTIMECHECK = 0x1002,
  400. EXCEPTION_DEBUGGER_MAX = 0x1002 // largest value this debugger understands
  401. };
  402. // must be convertible to DWORDs for use by RaiseException
  403. typedef struct tagEXCEPTION_VISUALCPP_DEBUG_INFO
  404. {
  405. DWORD dwType; // one of the enums from above
  406. union
  407. {
  408. struct
  409. {
  410. LPCSTR szName; // pointer to name (in user addr space)
  411. DWORD dwThreadID; // thread ID (-1=caller thread)
  412. DWORD dwFlags; // reserved for future use (eg User thread, System thread)
  413. } SetName;
  414. struct
  415. {
  416. DWORD dwLevelRequired; // 0 = do you understand this private exception, else max value of enum
  417. PBYTE pbDebuggerPresent; // debugger puts a non-zero value in this address if there
  418. } DebuggerProbe;
  419. struct
  420. {
  421. DWORD dwRuntimeNumber; // the type of the runtime check
  422. BOOL bRealBug; // TRUE if never a false-positive
  423. PVOID pvReturnAddress; // caller puts a return address in here
  424. PBYTE pbDebuggerPresent; // debugger puts a non-zero value in this address if handled it
  425. LPCWSTR pwRuntimeMessage; // pointer to Unicode message (or NULL)
  426. } RuntimeError;
  427. };
  428. } EXCEPTION_VISUALCPP_DEBUG_INFO;
  429. #ifdef _MSC_VER
  430. #pragma pack(pop)
  431. #endif /* _MSC_VER */
  432. #endif
  433. #endif /* _INC_RTCPRIV */