createconf.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /*
  2. * KDUMA - Red-Zone memory allocator.
  3. *
  4. * Copyright (C) 2006 Michael Eddington <meddington@gmail.com>
  5. * Copyright (C) 2002-2005 Hayati Ayguen <h_ayguen@web.de>, Procitec GmbH
  6. * Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
  7. *
  8. * License: GNU GPL (GNU General Public License, see COPYING-GPL)
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. *
  24. *
  25. * FILE CONTENTS:
  26. * --------------
  27. * This is a small tool to generate the "duma_config.h" configuration file.
  28. * Its purpose is to allow fixed size memory allocation on stack, which can
  29. * get protected calling page protection functions.
  30. * Also its nice for the user to be able to see the page size.
  31. */
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include <memory.h>
  35. #include <stdarg.h>
  36. #ifdef _MSC_VER
  37. #include <direct.h>
  38. #endif
  39. #ifndef WIN32
  40. #include <unistd.h>
  41. #include <fcntl.h>
  42. #include <sys/mman.h>
  43. #else
  44. #define WIN32_LEAN_AND_MEAN 1
  45. #include <windows.h>
  46. #include <winbase.h>
  47. typedef LPVOID caddr_t;
  48. typedef unsigned u_int;
  49. #endif
  50. /*
  51. * retrieve page size
  52. * size_t Page_Size(void)
  53. */
  54. static size_t
  55. Page_Size(void)
  56. {
  57. #if defined(WIN32)
  58. SYSTEM_INFO SystemInfo;
  59. GetSystemInfo( &SystemInfo );
  60. return (size_t)SystemInfo.dwPageSize;
  61. #elif defined(_SC_PAGESIZE)
  62. return (size_t)sysconf(_SC_PAGESIZE);
  63. #elif defined(_SC_PAGE_SIZE)
  64. return (size_t)sysconf(_SC_PAGE_SIZE);
  65. #else
  66. /* extern int getpagesize(); */
  67. return getpagesize();
  68. #endif
  69. }
  70. int initattr_ok = 0;
  71. void
  72. #ifdef __GNUC__
  73. __attribute ((constructor))
  74. #endif
  75. init_function(void)
  76. {
  77. initattr_ok = 1;
  78. }
  79. typedef struct
  80. {
  81. int id;
  82. int size;
  83. char *type;
  84. }
  85. DataType_T;
  86. DataType_T sIntTypes[] =
  87. {
  88. { 0, sizeof(char) , "char" }
  89. , { 1, sizeof(short int), "short int" }
  90. , { 2, sizeof(int) , "int" }
  91. , { 3, sizeof(long int) , "long int" }
  92. /* hier zusaetzliche compiler-spezifische datentypen hinzufuegen */
  93. #ifdef _MSC_VER
  94. , { 4, sizeof(__int64), "__int64" }
  95. #endif
  96. #ifdef __GNUC__
  97. , { 5, sizeof(long long int), "long long int" }
  98. #endif
  99. };
  100. /* test access to each data type */
  101. void testAlignment(int addrIdx, char * buffer, int alignment, int max_sizeof)
  102. {
  103. int offset;
  104. switch ( sIntTypes[addrIdx].id )
  105. {
  106. case 0:
  107. #define TYPE unsigned char
  108. for(offset=0; offset < max_sizeof; ++offset)
  109. {
  110. TYPE addr = (TYPE)(buffer) + offset;
  111. if ( addr % alignment == 0 )
  112. {
  113. *( (unsigned char *) addr ) = 0;
  114. *( (unsigned short int*) addr ) = 0;
  115. *( (unsigned int *) addr ) = 0;
  116. *( (unsigned long int *) addr ) = 0L;
  117. *( (float *) addr ) = 0.0F;
  118. *( (double *) addr ) = 0.0;
  119. *( (long double *) addr ) = 0.0;
  120. #ifdef _MSC_VER
  121. *( (unsigned __int64 *) addr ) = 0L;
  122. #endif
  123. #ifdef __GNUC__
  124. *( (unsigned long long int *) addr ) = 0L;
  125. #endif
  126. }
  127. }
  128. break;
  129. case 1:
  130. #undef TYPE
  131. #define TYPE unsigned short int
  132. for(offset=0; offset < max_sizeof; ++offset)
  133. {
  134. TYPE addr = (TYPE)(buffer) + offset;
  135. if ( addr % alignment == 0 )
  136. {
  137. *( (unsigned char *) addr ) = 0;
  138. *( (unsigned short int*) addr ) = 0;
  139. *( (unsigned int *) addr ) = 0;
  140. *( (unsigned long int *) addr ) = 0L;
  141. *( (float *) addr ) = 0.0F;
  142. *( (double *) addr ) = 0.0;
  143. *( (long double *) addr ) = 0.0;
  144. #ifdef _MSC_VER
  145. *( (unsigned __int64 *) addr ) = 0L;
  146. #endif
  147. #ifdef __GNUC__
  148. *( (unsigned long long int *) addr ) = 0L;
  149. #endif
  150. }
  151. }
  152. break;
  153. case 2:
  154. #undef TYPE
  155. #define TYPE unsigned int
  156. for(offset=0; offset < max_sizeof; ++offset)
  157. {
  158. TYPE addr = (TYPE)(buffer) + offset;
  159. if ( addr % alignment == 0 )
  160. {
  161. *( (unsigned char *) addr ) = 0;
  162. *( (unsigned short int*) addr ) = 0;
  163. *( (unsigned int *) addr ) = 0;
  164. *( (unsigned long int *) addr ) = 0L;
  165. *( (float *) addr ) = 0.0F;
  166. *( (double *) addr ) = 0.0;
  167. *( (long double *) addr ) = 0.0;
  168. #ifdef _MSC_VER
  169. *( (unsigned __int64 *) addr ) = 0L;
  170. #endif
  171. #ifdef __GNUC__
  172. *( (unsigned long long int *) addr ) = 0L;
  173. #endif
  174. }
  175. }
  176. break;
  177. case 3:
  178. #undef TYPE
  179. #define TYPE unsigned long int
  180. for(offset=0; offset < max_sizeof; ++offset)
  181. {
  182. TYPE addr = (TYPE)(buffer) + offset;
  183. if ( addr % alignment == 0 )
  184. {
  185. *( (unsigned char *) addr ) = 0;
  186. *( (unsigned short int*) addr ) = 0;
  187. *( (unsigned int *) addr ) = 0;
  188. *( (unsigned long int *) addr ) = 0L;
  189. *( (float *) addr ) = 0.0F;
  190. *( (double *) addr ) = 0.0;
  191. *( (long double *) addr ) = 0.0;
  192. #ifdef _MSC_VER
  193. *( (unsigned __int64 *) addr ) = 0L;
  194. #endif
  195. #ifdef __GNUC__
  196. *( (unsigned long long int *) addr ) = 0L;
  197. #endif
  198. }
  199. }
  200. break;
  201. #ifdef _MSC_VER
  202. case 4:
  203. #undef TYPE
  204. #define TYPE unsigned __int64
  205. for(offset=0; offset < max_sizeof; ++offset)
  206. {
  207. TYPE addr = (TYPE)(buffer) + offset;
  208. if ( addr % alignment == 0 )
  209. {
  210. *( (unsigned char *) addr ) = 0;
  211. *( (unsigned short int*) addr ) = 0;
  212. *( (unsigned int *) addr ) = 0;
  213. *( (unsigned long int *) addr ) = 0L;
  214. *( (float *) addr ) = 0.0F;
  215. *( (double *) addr ) = 0.0;
  216. *( (long double *) addr ) = 0.0;
  217. #ifdef _MSC_VER
  218. *( (unsigned __int64 *) addr ) = 0L;
  219. #endif
  220. #ifdef __GNUC__
  221. *( (unsigned long long int *) addr ) = 0L;
  222. #endif
  223. }
  224. }
  225. break;
  226. #endif
  227. #ifdef __GNUC__
  228. case 5:
  229. #undef TYPE
  230. #define TYPE unsigned long long int
  231. for(offset=0; offset < max_sizeof; ++offset)
  232. {
  233. TYPE addr = (TYPE)(buffer) + offset;
  234. if ( addr % alignment == 0 )
  235. {
  236. *( (unsigned char *) addr ) = 0;
  237. *( (unsigned short int*) addr ) = 0;
  238. *( (unsigned int *) addr ) = 0;
  239. *( (unsigned long int *) addr ) = 0L;
  240. *( (float *) addr ) = 0.0F;
  241. *( (double *) addr ) = 0.0;
  242. *( (long double *) addr ) = 0.0;
  243. #ifdef _MSC_VER
  244. *( (unsigned __int64 *) addr ) = 0L;
  245. #endif
  246. #ifdef __GNUC__
  247. *( (unsigned long long int *) addr ) = 0L;
  248. #endif
  249. }
  250. }
  251. break;
  252. #endif
  253. ;
  254. }
  255. }
  256. void writeFile(const char * filename, unsigned long pagesize, int addrIdx, int sizeIdx, int alignment)
  257. {
  258. FILE * f = fopen(filename, "w");
  259. if (!f)
  260. return;
  261. fprintf(f, "/*\n");
  262. fprintf(f, " * WARNING: DO NOT CHANGE THIS FILE!\n");
  263. fprintf(f, " * This file is automatically generated from createconf\n");
  264. #if defined(WIN32)
  265. #if defined(_MSC_VER)
  266. fprintf(f, " * using Microsoft Visual C++ under MS Windows(TM) the %s\n", __DATE__ );
  267. #else
  268. printf(f, " * under MS Windows(TM) the %s\n", __DATE__ );
  269. #endif
  270. #elif ( defined(sgi) )
  271. fprintf(f, " * under sgi the %s\n", __DATE__ );
  272. #elif ( defined(_AIX) )
  273. fprintf(f, " * under AIX the %s\n", __DATE__ );
  274. #elif ( defined(__linux__) )
  275. fprintf(f, " * under Linux the %s\n", __DATE__ );
  276. #else
  277. fprintf(f, " * the %s \n", __DATE__ );
  278. #endif
  279. fprintf(f, " */\n");
  280. fprintf(f, "\n");
  281. fprintf(f, "#ifndef _DUMA_CONFIG_H_\n");
  282. fprintf(f, "#define _DUMA_CONFIG_H_\n");
  283. fprintf(f, "\n");
  284. fprintf(f, "\n");
  285. fprintf(f, "/* Variable: DUMA_PAGE_SIZE\n");
  286. fprintf(f, " *\n");
  287. fprintf(f, " * Number of bytes per virtual-memory page, as returned by Page_Size().\n");
  288. fprintf(f, " */\n");
  289. fprintf(f, "#define DUMA_PAGE_SIZE %lu\n", pagesize);
  290. fprintf(f, "\n");
  291. fprintf(f, "/* Variable: DUMA_MIN_ALIGNMENT\n");
  292. fprintf(f, " *\n");
  293. fprintf(f, " * Minimum required alignment by CPU.\n");
  294. fprintf(f, " */\n");
  295. fprintf(f, "#define DUMA_MIN_ALIGNMENT %d\n", alignment);
  296. fprintf(f, "\n");
  297. fprintf(f, "/* Variable: DUMA_GNU_INIT_ATTR\n");
  298. fprintf(f, " *\n");
  299. fprintf(f, " * Build environment supports the '__attribute ((constructor))'?\n");
  300. fprintf(f, " */\n");
  301. if (initattr_ok)
  302. fprintf(f, "#define DUMA_GNU_INIT_ATTR 1\n");
  303. else
  304. fprintf(f, "/* #define DUMA_GNU_INIT_ATTR 0 */\n");
  305. fprintf(f, "\n");
  306. fprintf(f, "/* Type: DUMA_ADDR\n");
  307. fprintf(f, " *\n");
  308. fprintf(f, " * An integer type with same size as 'void *'\n");
  309. fprintf(f, " */\n");
  310. if (addrIdx >= 0)
  311. fprintf(f, "typedef unsigned %s DUMA_ADDR;\n", sIntTypes[addrIdx].type);
  312. else
  313. fprintf(f, "/* Error: No datatype for DUMA_ADDR found! */\n");
  314. fprintf(f, "\n");
  315. fprintf(f, "/* Type: DUMA_SIZE\n");
  316. fprintf(f, " *\n");
  317. fprintf(f, " * An integer type with same size as 'size_t'\n");
  318. fprintf(f, " */\n");
  319. if (sizeIdx >= 0)
  320. fprintf(f, "typedef unsigned %s DUMA_SIZE;\n", sIntTypes[sizeIdx].type);
  321. else
  322. fprintf(f, "/* No datatype for DUMA_SIZE found! */\n");
  323. fprintf(f, "\n");
  324. fprintf(f, "#endif /* _DUMA_CONFIG_H_ */\n");
  325. fclose(f);
  326. }
  327. int main()
  328. {
  329. int iNumIntTypes, iIt;
  330. int addrIdx, sizeIdx;
  331. int alignment, max_sizeof;
  332. char buffer[1024];
  333. char filename[1024];
  334. unsigned long pagesize = Page_Size();
  335. iNumIntTypes = sizeof( sIntTypes ) / sizeof( sIntTypes[0] );
  336. // detect compatible type for ADDRESS
  337. addrIdx = -1;
  338. for (iIt = 0; iIt < iNumIntTypes; ++iIt)
  339. {
  340. if ( sizeof(void*) == sIntTypes[iIt].size )
  341. {
  342. addrIdx = iIt;
  343. break;
  344. }
  345. }
  346. // detect compatible type for SIZE_T
  347. sizeIdx = -1;
  348. for (iIt = 0; iIt < iNumIntTypes; ++iIt)
  349. {
  350. if ( sizeof(size_t) == sIntTypes[iIt].size )
  351. {
  352. sizeIdx = iIt;
  353. break;
  354. }
  355. }
  356. /* detect maximum data type, which should be maximum alignment */
  357. max_sizeof = 0;
  358. for (iIt = 0; iIt < iNumIntTypes; ++iIt)
  359. {
  360. if ( max_sizeof < sIntTypes[iIt].size )
  361. max_sizeof = sIntTypes[iIt].size;
  362. }
  363. if ( max_sizeof < sizeof(float) )
  364. max_sizeof = sizeof(float);
  365. if ( max_sizeof < sizeof(double) )
  366. max_sizeof = sizeof(double);
  367. if ( max_sizeof < sizeof(long double) )
  368. max_sizeof = sizeof(long double);
  369. #ifdef _MSC_VER
  370. {
  371. /* fix output path when started form Visual C++ IDE */
  372. char directory[1024];
  373. char * start;
  374. _getcwd( directory, 1024 ); /* get current directory */
  375. if ( ( start = strstr( directory, "win32-msvc" ) ) )
  376. {
  377. *start = 0;
  378. strcpy(filename, directory);
  379. strcat(filename, "duma_config.h");
  380. }
  381. else
  382. strcpy( filename, "duma_config.h" );
  383. }
  384. #else
  385. strcpy( filename, "duma_config.h" );
  386. #endif
  387. /* detect minimum alignment */
  388. alignment = max_sizeof;
  389. do
  390. {
  391. /* do the alignment access tests */
  392. testAlignment(addrIdx, buffer, alignment, max_sizeof);
  393. /* write whole config file. next test may crash ! */
  394. writeFile(filename, pagesize, addrIdx, sizeIdx, alignment);
  395. /* try next lower alignment */
  396. alignment >>= 1;
  397. }
  398. while ( alignment > 0 );
  399. return 0;
  400. }