tcc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +35 -0
  3. data/README.md +196 -0
  4. data/ext/tcc/extconf.rb +25 -0
  5. data/ext/tcc/tcc-0.9.26.patch +30 -0
  6. data/ext/tcc/tcc-0.9.26/COPYING +504 -0
  7. data/ext/tcc/tcc-0.9.26/Changelog +396 -0
  8. data/ext/tcc/tcc-0.9.26/Makefile +349 -0
  9. data/ext/tcc/tcc-0.9.26/README +101 -0
  10. data/ext/tcc/tcc-0.9.26/TODO +93 -0
  11. data/ext/tcc/tcc-0.9.26/VERSION +1 -0
  12. data/ext/tcc/tcc-0.9.26/arm-gen.c +2005 -0
  13. data/ext/tcc/tcc-0.9.26/c67-gen.c +2560 -0
  14. data/ext/tcc/tcc-0.9.26/coff.h +446 -0
  15. data/ext/tcc/tcc-0.9.26/config.h +8 -0
  16. data/ext/tcc/tcc-0.9.26/config.mak +28 -0
  17. data/ext/tcc/tcc-0.9.26/config.texi +1 -0
  18. data/ext/tcc/tcc-0.9.26/configure +540 -0
  19. data/ext/tcc/tcc-0.9.26/conftest.c +71 -0
  20. data/ext/tcc/tcc-0.9.26/elf.h +1731 -0
  21. data/ext/tcc/tcc-0.9.26/examples/ex1.c +8 -0
  22. data/ext/tcc/tcc-0.9.26/examples/ex2.c +98 -0
  23. data/ext/tcc/tcc-0.9.26/examples/ex3.c +24 -0
  24. data/ext/tcc/tcc-0.9.26/examples/ex4.c +26 -0
  25. data/ext/tcc/tcc-0.9.26/examples/ex5.c +8 -0
  26. data/ext/tcc/tcc-0.9.26/i386-asm.c +1498 -0
  27. data/ext/tcc/tcc-0.9.26/i386-asm.h +473 -0
  28. data/ext/tcc/tcc-0.9.26/i386-gen.c +1096 -0
  29. data/ext/tcc/tcc-0.9.26/i386-tok.h +243 -0
  30. data/ext/tcc/tcc-0.9.26/il-gen.c +667 -0
  31. data/ext/tcc/tcc-0.9.26/il-opcodes.h +251 -0
  32. data/ext/tcc/tcc-0.9.26/include/float.h +57 -0
  33. data/ext/tcc/tcc-0.9.26/include/stdarg.h +41 -0
  34. data/ext/tcc/tcc-0.9.26/include/stdbool.h +10 -0
  35. data/ext/tcc/tcc-0.9.26/include/stddef.h +28 -0
  36. data/ext/tcc/tcc-0.9.26/include/tcclib.h +78 -0
  37. data/ext/tcc/tcc-0.9.26/include/varargs.h +12 -0
  38. data/ext/tcc/tcc-0.9.26/lib/Makefile +102 -0
  39. data/ext/tcc/tcc-0.9.26/lib/alloca86-bt.S +47 -0
  40. data/ext/tcc/tcc-0.9.26/lib/alloca86.S +35 -0
  41. data/ext/tcc/tcc-0.9.26/lib/alloca86_64.S +42 -0
  42. data/ext/tcc/tcc-0.9.26/lib/bcheck.c +875 -0
  43. data/ext/tcc/tcc-0.9.26/lib/libtcc1.c +691 -0
  44. data/ext/tcc/tcc-0.9.26/libtcc.c +1941 -0
  45. data/ext/tcc/tcc-0.9.26/libtcc.h +103 -0
  46. data/ext/tcc/tcc-0.9.26/stab.def +234 -0
  47. data/ext/tcc/tcc-0.9.26/stab.h +17 -0
  48. data/ext/tcc/tcc-0.9.26/tcc-doc.html +2332 -0
  49. data/ext/tcc/tcc-0.9.26/tcc-doc.info +1151 -0
  50. data/ext/tcc/tcc-0.9.26/tcc-doc.texi +1268 -0
  51. data/ext/tcc/tcc-0.9.26/tcc.1 +415 -0
  52. data/ext/tcc/tcc-0.9.26/tcc.c +352 -0
  53. data/ext/tcc/tcc-0.9.26/tcc.h +1379 -0
  54. data/ext/tcc/tcc-0.9.26/tccasm.c +1118 -0
  55. data/ext/tcc/tcc-0.9.26/tcccoff.c +948 -0
  56. data/ext/tcc/tcc-0.9.26/tccelf.c +3129 -0
  57. data/ext/tcc/tcc-0.9.26/tccgen.c +5841 -0
  58. data/ext/tcc/tcc-0.9.26/tccpe.c +1887 -0
  59. data/ext/tcc/tcc-0.9.26/tccpp.c +3128 -0
  60. data/ext/tcc/tcc-0.9.26/tccrun.c +737 -0
  61. data/ext/tcc/tcc-0.9.26/tcctok.h +278 -0
  62. data/ext/tcc/tcc-0.9.26/tests/Makefile +199 -0
  63. data/ext/tcc/tcc-0.9.26/tests/asmtest.S +609 -0
  64. data/ext/tcc/tcc-0.9.26/tests/boundtest.c +233 -0
  65. data/ext/tcc/tcc-0.9.26/tests/gcctestsuite.sh +33 -0
  66. data/ext/tcc/tcc-0.9.26/tests/libtcc_test.c +76 -0
  67. data/ext/tcc/tcc-0.9.26/tests/tcctest.c +2713 -0
  68. data/ext/tcc/tcc-0.9.26/tests/tests2/00_assignment.c +18 -0
  69. data/ext/tcc/tcc-0.9.26/tests/tests2/00_assignment.expect +3 -0
  70. data/ext/tcc/tcc-0.9.26/tests/tests2/01_comment.c +14 -0
  71. data/ext/tcc/tcc-0.9.26/tests/tests2/01_comment.expect +5 -0
  72. data/ext/tcc/tcc-0.9.26/tests/tests2/02_printf.c +18 -0
  73. data/ext/tcc/tcc-0.9.26/tests/tests2/02_printf.expect +15 -0
  74. data/ext/tcc/tcc-0.9.26/tests/tests2/03_struct.c +31 -0
  75. data/ext/tcc/tcc-0.9.26/tests/tests2/03_struct.expect +6 -0
  76. data/ext/tcc/tcc-0.9.26/tests/tests2/04_for.c +15 -0
  77. data/ext/tcc/tcc-0.9.26/tests/tests2/04_for.expect +10 -0
  78. data/ext/tcc/tcc-0.9.26/tests/tests2/05_array.c +21 -0
  79. data/ext/tcc/tcc-0.9.26/tests/tests2/05_array.expect +10 -0
  80. data/ext/tcc/tcc-0.9.26/tests/tests2/06_case.c +29 -0
  81. data/ext/tcc/tcc-0.9.26/tests/tests2/06_case.expect +8 -0
  82. data/ext/tcc/tcc-0.9.26/tests/tests2/07_function.c +30 -0
  83. data/ext/tcc/tcc-0.9.26/tests/tests2/07_function.expect +4 -0
  84. data/ext/tcc/tcc-0.9.26/tests/tests2/08_while.c +24 -0
  85. data/ext/tcc/tcc-0.9.26/tests/tests2/08_while.expect +11 -0
  86. data/ext/tcc/tcc-0.9.26/tests/tests2/09_do_while.c +24 -0
  87. data/ext/tcc/tcc-0.9.26/tests/tests2/09_do_while.expect +11 -0
  88. data/ext/tcc/tcc-0.9.26/tests/tests2/10_pointer.c +40 -0
  89. data/ext/tcc/tcc-0.9.26/tests/tests2/10_pointer.expect +8 -0
  90. data/ext/tcc/tcc-0.9.26/tests/tests2/11_precedence.c +40 -0
  91. data/ext/tcc/tcc-0.9.26/tests/tests2/11_precedence.expect +15 -0
  92. data/ext/tcc/tcc-0.9.26/tests/tests2/12_hashdefine.c +14 -0
  93. data/ext/tcc/tcc-0.9.26/tests/tests2/12_hashdefine.expect +2 -0
  94. data/ext/tcc/tcc-0.9.26/tests/tests2/13_integer_literals.c +20 -0
  95. data/ext/tcc/tcc-0.9.26/tests/tests2/13_integer_literals.expect +5 -0
  96. data/ext/tcc/tcc-0.9.26/tests/tests2/14_if.c +21 -0
  97. data/ext/tcc/tcc-0.9.26/tests/tests2/14_if.expect +2 -0
  98. data/ext/tcc/tcc-0.9.26/tests/tests2/15_recursion.c +21 -0
  99. data/ext/tcc/tcc-0.9.26/tests/tests2/15_recursion.expect +10 -0
  100. data/ext/tcc/tcc-0.9.26/tests/tests2/16_nesting.c +21 -0
  101. data/ext/tcc/tcc-0.9.26/tests/tests2/16_nesting.expect +18 -0
  102. data/ext/tcc/tcc-0.9.26/tests/tests2/17_enum.c +29 -0
  103. data/ext/tcc/tcc-0.9.26/tests/tests2/17_enum.expect +3 -0
  104. data/ext/tcc/tcc-0.9.26/tests/tests2/18_include.c +12 -0
  105. data/ext/tcc/tcc-0.9.26/tests/tests2/18_include.expect +3 -0
  106. data/ext/tcc/tcc-0.9.26/tests/tests2/18_include.h +1 -0
  107. data/ext/tcc/tcc-0.9.26/tests/tests2/19_pointer_arithmetic.c +28 -0
  108. data/ext/tcc/tcc-0.9.26/tests/tests2/19_pointer_arithmetic.expect +3 -0
  109. data/ext/tcc/tcc-0.9.26/tests/tests2/20_pointer_comparison.c +24 -0
  110. data/ext/tcc/tcc-0.9.26/tests/tests2/20_pointer_comparison.expect +6 -0
  111. data/ext/tcc/tcc-0.9.26/tests/tests2/21_char_array.c +33 -0
  112. data/ext/tcc/tcc-0.9.26/tests/tests2/21_char_array.expect +7 -0
  113. data/ext/tcc/tcc-0.9.26/tests/tests2/22_floating_point.c +50 -0
  114. data/ext/tcc/tcc-0.9.26/tests/tests2/22_floating_point.expect +16 -0
  115. data/ext/tcc/tcc-0.9.26/tests/tests2/23_type_coercion.c +54 -0
  116. data/ext/tcc/tcc-0.9.26/tests/tests2/23_type_coercion.expect +12 -0
  117. data/ext/tcc/tcc-0.9.26/tests/tests2/24_math_library.c +28 -0
  118. data/ext/tcc/tcc-0.9.26/tests/tests2/24_math_library.expect +18 -0
  119. data/ext/tcc/tcc-0.9.26/tests/tests2/25_quicksort.c +83 -0
  120. data/ext/tcc/tcc-0.9.26/tests/tests2/25_quicksort.expect +2 -0
  121. data/ext/tcc/tcc-0.9.26/tests/tests2/26_character_constants.c +17 -0
  122. data/ext/tcc/tcc-0.9.26/tests/tests2/26_character_constants.expect +8 -0
  123. data/ext/tcc/tcc-0.9.26/tests/tests2/27_sizeof.c +16 -0
  124. data/ext/tcc/tcc-0.9.26/tests/tests2/27_sizeof.expect +3 -0
  125. data/ext/tcc/tcc-0.9.26/tests/tests2/28_strings.c +46 -0
  126. data/ext/tcc/tcc-0.9.26/tests/tests2/28_strings.expect +19 -0
  127. data/ext/tcc/tcc-0.9.26/tests/tests2/29_array_address.c +13 -0
  128. data/ext/tcc/tcc-0.9.26/tests/tests2/29_array_address.expect +1 -0
  129. data/ext/tcc/tcc-0.9.26/tests/tests2/30_hanoi.c +122 -0
  130. data/ext/tcc/tcc-0.9.26/tests/tests2/30_hanoi.expect +71 -0
  131. data/ext/tcc/tcc-0.9.26/tests/tests2/31_args.c +14 -0
  132. data/ext/tcc/tcc-0.9.26/tests/tests2/31_args.expect +7 -0
  133. data/ext/tcc/tcc-0.9.26/tests/tests2/32_led.c +266 -0
  134. data/ext/tcc/tcc-0.9.26/tests/tests2/32_led.expect +4 -0
  135. data/ext/tcc/tcc-0.9.26/tests/tests2/33_ternary_op.c +15 -0
  136. data/ext/tcc/tcc-0.9.26/tests/tests2/33_ternary_op.expect +10 -0
  137. data/ext/tcc/tcc-0.9.26/tests/tests2/34_array_assignment.c +23 -0
  138. data/ext/tcc/tcc-0.9.26/tests/tests2/34_array_assignment.expect +2 -0
  139. data/ext/tcc/tcc-0.9.26/tests/tests2/35_sizeof.c +14 -0
  140. data/ext/tcc/tcc-0.9.26/tests/tests2/35_sizeof.expect +2 -0
  141. data/ext/tcc/tcc-0.9.26/tests/tests2/36_array_initialisers.c +21 -0
  142. data/ext/tcc/tcc-0.9.26/tests/tests2/36_array_initialisers.expect +20 -0
  143. data/ext/tcc/tcc-0.9.26/tests/tests2/37_sprintf.c +17 -0
  144. data/ext/tcc/tcc-0.9.26/tests/tests2/37_sprintf.expect +20 -0
  145. data/ext/tcc/tcc-0.9.26/tests/tests2/38_multiple_array_index.c +32 -0
  146. data/ext/tcc/tcc-0.9.26/tests/tests2/38_multiple_array_index.expect +4 -0
  147. data/ext/tcc/tcc-0.9.26/tests/tests2/39_typedef.c +31 -0
  148. data/ext/tcc/tcc-0.9.26/tests/tests2/39_typedef.expect +3 -0
  149. data/ext/tcc/tcc-0.9.26/tests/tests2/40_stdio.c +52 -0
  150. data/ext/tcc/tcc-0.9.26/tests/tests2/40_stdio.expect +27 -0
  151. data/ext/tcc/tcc-0.9.26/tests/tests2/41_hashif.c +85 -0
  152. data/ext/tcc/tcc-0.9.26/tests/tests2/41_hashif.expect +6 -0
  153. data/ext/tcc/tcc-0.9.26/tests/tests2/42_function_pointer.c +18 -0
  154. data/ext/tcc/tcc-0.9.26/tests/tests2/42_function_pointer.expect +2 -0
  155. data/ext/tcc/tcc-0.9.26/tests/tests2/43_void_param.c +15 -0
  156. data/ext/tcc/tcc-0.9.26/tests/tests2/43_void_param.expect +1 -0
  157. data/ext/tcc/tcc-0.9.26/tests/tests2/44_scoped_declarations.c +17 -0
  158. data/ext/tcc/tcc-0.9.26/tests/tests2/44_scoped_declarations.expect +1 -0
  159. data/ext/tcc/tcc-0.9.26/tests/tests2/45_empty_for.c +18 -0
  160. data/ext/tcc/tcc-0.9.26/tests/tests2/45_empty_for.expect +10 -0
  161. data/ext/tcc/tcc-0.9.26/tests/tests2/46_grep.c +564 -0
  162. data/ext/tcc/tcc-0.9.26/tests/tests2/47_switch_return.c +24 -0
  163. data/ext/tcc/tcc-0.9.26/tests/tests2/47_switch_return.expect +4 -0
  164. data/ext/tcc/tcc-0.9.26/tests/tests2/48_nested_break.c +26 -0
  165. data/ext/tcc/tcc-0.9.26/tests/tests2/48_nested_break.expect +1 -0
  166. data/ext/tcc/tcc-0.9.26/tests/tests2/49_bracket_evaluation.c +23 -0
  167. data/ext/tcc/tcc-0.9.26/tests/tests2/49_bracket_evaluation.expect +1 -0
  168. data/ext/tcc/tcc-0.9.26/tests/tests2/50_logical_second_arg.c +29 -0
  169. data/ext/tcc/tcc-0.9.26/tests/tests2/50_logical_second_arg.expect +20 -0
  170. data/ext/tcc/tcc-0.9.26/tests/tests2/51_static.c +30 -0
  171. data/ext/tcc/tcc-0.9.26/tests/tests2/51_static.expect +8 -0
  172. data/ext/tcc/tcc-0.9.26/tests/tests2/52_unnamed_enum.c +27 -0
  173. data/ext/tcc/tcc-0.9.26/tests/tests2/52_unnamed_enum.expect +9 -0
  174. data/ext/tcc/tcc-0.9.26/tests/tests2/54_goto.c +56 -0
  175. data/ext/tcc/tcc-0.9.26/tests/tests2/54_goto.expect +8 -0
  176. data/ext/tcc/tcc-0.9.26/tests/tests2/55_lshift_type.c +52 -0
  177. data/ext/tcc/tcc-0.9.26/tests/tests2/55_lshift_type.expect +1 -0
  178. data/ext/tcc/tcc-0.9.26/tests/tests2/LICENSE +37 -0
  179. data/ext/tcc/tcc-0.9.26/tests/tests2/Makefile +98 -0
  180. data/ext/tcc/tcc-0.9.26/texi2pod.pl +427 -0
  181. data/ext/tcc/tcc-0.9.26/win32/build-tcc.bat +60 -0
  182. data/ext/tcc/tcc-0.9.26/win32/examples/dll.c +12 -0
  183. data/ext/tcc/tcc-0.9.26/win32/examples/fib.c +23 -0
  184. data/ext/tcc/tcc-0.9.26/win32/examples/hello_dll.c +19 -0
  185. data/ext/tcc/tcc-0.9.26/win32/examples/hello_win.c +163 -0
  186. data/ext/tcc/tcc-0.9.26/win32/include/_mingw.h +139 -0
  187. data/ext/tcc/tcc-0.9.26/win32/include/assert.h +54 -0
  188. data/ext/tcc/tcc-0.9.26/win32/include/conio.h +409 -0
  189. data/ext/tcc/tcc-0.9.26/win32/include/ctype.h +281 -0
  190. data/ext/tcc/tcc-0.9.26/win32/include/dir.h +31 -0
  191. data/ext/tcc/tcc-0.9.26/win32/include/direct.h +68 -0
  192. data/ext/tcc/tcc-0.9.26/win32/include/dirent.h +135 -0
  193. data/ext/tcc/tcc-0.9.26/win32/include/dos.h +55 -0
  194. data/ext/tcc/tcc-0.9.26/win32/include/errno.h +75 -0
  195. data/ext/tcc/tcc-0.9.26/win32/include/excpt.h +123 -0
  196. data/ext/tcc/tcc-0.9.26/win32/include/fcntl.h +52 -0
  197. data/ext/tcc/tcc-0.9.26/win32/include/fenv.h +108 -0
  198. data/ext/tcc/tcc-0.9.26/win32/include/inttypes.h +297 -0
  199. data/ext/tcc/tcc-0.9.26/win32/include/io.h +418 -0
  200. data/ext/tcc/tcc-0.9.26/win32/include/limits.h +111 -0
  201. data/ext/tcc/tcc-0.9.26/win32/include/locale.h +91 -0
  202. data/ext/tcc/tcc-0.9.26/win32/include/malloc.h +175 -0
  203. data/ext/tcc/tcc-0.9.26/win32/include/math.h +777 -0
  204. data/ext/tcc/tcc-0.9.26/win32/include/mem.h +13 -0
  205. data/ext/tcc/tcc-0.9.26/win32/include/memory.h +40 -0
  206. data/ext/tcc/tcc-0.9.26/win32/include/process.h +176 -0
  207. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/conio_s.h +42 -0
  208. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/crtdbg_s.h +19 -0
  209. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/io_s.h +33 -0
  210. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/mbstring_s.h +52 -0
  211. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/search_s.h +25 -0
  212. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/stdio_s.h +145 -0
  213. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/stdlib_s.h +67 -0
  214. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/stralign_s.h +30 -0
  215. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/string_s.h +41 -0
  216. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/sys/timeb_s.h +34 -0
  217. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/tchar_s.h +266 -0
  218. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/time_s.h +61 -0
  219. data/ext/tcc/tcc-0.9.26/win32/include/sec_api/wchar_s.h +128 -0
  220. data/ext/tcc/tcc-0.9.26/win32/include/setjmp.h +160 -0
  221. data/ext/tcc/tcc-0.9.26/win32/include/share.h +28 -0
  222. data/ext/tcc/tcc-0.9.26/win32/include/signal.h +63 -0
  223. data/ext/tcc/tcc-0.9.26/win32/include/stdint.h +209 -0
  224. data/ext/tcc/tcc-0.9.26/win32/include/stdio.h +429 -0
  225. data/ext/tcc/tcc-0.9.26/win32/include/stdlib.h +580 -0
  226. data/ext/tcc/tcc-0.9.26/win32/include/string.h +164 -0
  227. data/ext/tcc/tcc-0.9.26/win32/include/sys/fcntl.h +13 -0
  228. data/ext/tcc/tcc-0.9.26/win32/include/sys/file.h +14 -0
  229. data/ext/tcc/tcc-0.9.26/win32/include/sys/locking.h +30 -0
  230. data/ext/tcc/tcc-0.9.26/win32/include/sys/stat.h +290 -0
  231. data/ext/tcc/tcc-0.9.26/win32/include/sys/time.h +69 -0
  232. data/ext/tcc/tcc-0.9.26/win32/include/sys/timeb.h +133 -0
  233. data/ext/tcc/tcc-0.9.26/win32/include/sys/types.h +118 -0
  234. data/ext/tcc/tcc-0.9.26/win32/include/sys/unistd.h +14 -0
  235. data/ext/tcc/tcc-0.9.26/win32/include/sys/utime.h +146 -0
  236. data/ext/tcc/tcc-0.9.26/win32/include/tchar.h +1102 -0
  237. data/ext/tcc/tcc-0.9.26/win32/include/time.h +287 -0
  238. data/ext/tcc/tcc-0.9.26/win32/include/vadefs.h +11 -0
  239. data/ext/tcc/tcc-0.9.26/win32/include/values.h +4 -0
  240. data/ext/tcc/tcc-0.9.26/win32/include/wchar.h +871 -0
  241. data/ext/tcc/tcc-0.9.26/win32/include/wctype.h +172 -0
  242. data/ext/tcc/tcc-0.9.26/win32/include/winapi/basetsd.h +149 -0
  243. data/ext/tcc/tcc-0.9.26/win32/include/winapi/basetyps.h +85 -0
  244. data/ext/tcc/tcc-0.9.26/win32/include/winapi/guiddef.h +151 -0
  245. data/ext/tcc/tcc-0.9.26/win32/include/winapi/intrin.h +11 -0
  246. data/ext/tcc/tcc-0.9.26/win32/include/winapi/poppack.h +8 -0
  247. data/ext/tcc/tcc-0.9.26/win32/include/winapi/pshpack1.h +8 -0
  248. data/ext/tcc/tcc-0.9.26/win32/include/winapi/pshpack2.h +8 -0
  249. data/ext/tcc/tcc-0.9.26/win32/include/winapi/pshpack4.h +8 -0
  250. data/ext/tcc/tcc-0.9.26/win32/include/winapi/pshpack8.h +8 -0
  251. data/ext/tcc/tcc-0.9.26/win32/include/winapi/reason.h +80 -0
  252. data/ext/tcc/tcc-0.9.26/win32/include/winapi/specstrings.h +7 -0
  253. data/ext/tcc/tcc-0.9.26/win32/include/winapi/stralign.h +154 -0
  254. data/ext/tcc/tcc-0.9.26/win32/include/winapi/tvout.h +79 -0
  255. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winbase.h +2951 -0
  256. data/ext/tcc/tcc-0.9.26/win32/include/winapi/wincon.h +301 -0
  257. data/ext/tcc/tcc-0.9.26/win32/include/winapi/windef.h +293 -0
  258. data/ext/tcc/tcc-0.9.26/win32/include/winapi/windows.h +123 -0
  259. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winerror.h +3166 -0
  260. data/ext/tcc/tcc-0.9.26/win32/include/winapi/wingdi.h +4080 -0
  261. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winnetwk.h +476 -0
  262. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winnls.h +765 -0
  263. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winnt.h +5770 -0
  264. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winreg.h +272 -0
  265. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winuser.h +5651 -0
  266. data/ext/tcc/tcc-0.9.26/win32/include/winapi/winver.h +160 -0
  267. data/ext/tcc/tcc-0.9.26/win32/lib/chkstk.S +191 -0
  268. data/ext/tcc/tcc-0.9.26/win32/lib/crt1.c +34 -0
  269. data/ext/tcc/tcc-0.9.26/win32/lib/dllcrt1.c +13 -0
  270. data/ext/tcc/tcc-0.9.26/win32/lib/dllmain.c +9 -0
  271. data/ext/tcc/tcc-0.9.26/win32/lib/gdi32.def +337 -0
  272. data/ext/tcc/tcc-0.9.26/win32/lib/kernel32.def +765 -0
  273. data/ext/tcc/tcc-0.9.26/win32/lib/msvcrt.def +1399 -0
  274. data/ext/tcc/tcc-0.9.26/win32/lib/user32.def +654 -0
  275. data/ext/tcc/tcc-0.9.26/win32/lib/wincrt1.c +64 -0
  276. data/ext/tcc/tcc-0.9.26/win32/tcc-win32.txt +156 -0
  277. data/ext/tcc/tcc-0.9.26/win32/tools/tiny_impdef.c +243 -0
  278. data/ext/tcc/tcc-0.9.26/win32/tools/tiny_libmaker.c +258 -0
  279. data/ext/tcc/tcc-0.9.26/x86_64-asm.h +448 -0
  280. data/ext/tcc/tcc-0.9.26/x86_64-gen.c +1701 -0
  281. data/lib/tcc.rb +291 -0
  282. data/tcc.gemspec +15 -0
  283. metadata +343 -0
@@ -0,0 +1,12 @@
1
+ /**
2
+ * This file has no copyright assigned and is placed in the Public Domain.
3
+ * This file is part of the w64 mingw-runtime package.
4
+ * No warranty is given; refer to the file DISCLAIMER within this package.
5
+ */
6
+ #ifndef _VARARGS_H
7
+ #define _VARARGS_H
8
+
9
+ #error "TinyCC no longer implements <varargs.h>."
10
+ #error "Revise your code to use <stdarg.h>."
11
+
12
+ #endif
@@ -0,0 +1,102 @@
1
+ #
2
+ # Tiny C Compiler Makefile for libtcc1.a
3
+ #
4
+
5
+ TOP = ..
6
+ include $(TOP)/Makefile
7
+ VPATH = $(top_srcdir)/lib $(top_srcdir)/win32/lib
8
+
9
+ ifndef TARGET
10
+ ifdef CONFIG_WIN64
11
+ TARGET = x86_64-win32
12
+ else
13
+ ifdef CONFIG_WIN32
14
+ TARGET = i386-win32
15
+ else
16
+ ifeq ($(ARCH),i386)
17
+ TARGET = i386
18
+ ifneq ($(TARGETOS),Darwin)
19
+ XCC = $(CC)
20
+ endif
21
+ else
22
+ ifeq ($(ARCH),x86-64)
23
+ TARGET = x86_64
24
+ ifneq ($(TARGETOS),Darwin)
25
+ XCC = $(CC)
26
+ endif
27
+ endif
28
+ endif
29
+ endif
30
+ endif
31
+ BCHECK_O = bcheck.o
32
+ endif
33
+
34
+ DIR = $(TARGET)
35
+
36
+ native : ../libtcc1.a
37
+ cross : $(DIR)/libtcc1.a
38
+
39
+ native : TCC = $(TOP)/tcc$(EXESUF)
40
+ cross : TCC = $(TOP)/$(TARGET)-tcc$(EXESUF)
41
+
42
+ I386_O = libtcc1.o alloca86.o alloca86-bt.o $(BCHECK_O)
43
+ X86_64_O = libtcc1.o alloca86_64.o
44
+ WIN32_O = $(I386_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
45
+ WIN64_O = $(X86_64_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
46
+
47
+ ifeq "$(TARGET)" "i386-win32"
48
+ OBJ = $(addprefix $(DIR)/,$(WIN32_O))
49
+ TGT = -DTCC_TARGET_I386 -DTCC_TARGET_PE
50
+ XCC = $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/include
51
+ XAR = $(DIR)/tiny_libmaker$(EXESUF)
52
+ else
53
+ ifeq "$(TARGET)" "x86_64-win32"
54
+ OBJ = $(addprefix $(DIR)/,$(WIN64_O))
55
+ TGT = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE
56
+ XCC = $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/include
57
+ XAR = $(DIR)/tiny_libmaker$(EXESUF)
58
+ else
59
+ ifeq "$(TARGET)" "i386"
60
+ OBJ = $(addprefix $(DIR)/,$(I386_O))
61
+ TGT = -DTCC_TARGET_I386
62
+ XCC ?= $(TCC) -B$(TOP)
63
+ else
64
+ ifeq "$(TARGET)" "x86_64"
65
+ OBJ = $(addprefix $(DIR)/,$(X86_64_O))
66
+ TGT = -DTCC_TARGET_X86_64
67
+ XCC ?= $(TCC) -B$(TOP)
68
+ else
69
+ $(error libtcc1.a not supported on target '$(TARGET)')
70
+ endif
71
+ endif
72
+ endif
73
+ endif
74
+
75
+ XFLAGS = $(CPPFLAGS) $(CFLAGS) $(TGT)
76
+
77
+ ifeq ($(TARGETOS),Darwin)
78
+ XAR = $(DIR)/tiny_libmaker$(EXESUF)
79
+ XFLAGS += -D_ANSI_SOURCE
80
+ BCHECK_O =
81
+ endif
82
+
83
+ ifdef XAR
84
+ AR = $(XAR)
85
+ endif
86
+
87
+ $(DIR)/libtcc1.a ../libtcc1.a : $(OBJ) $(XAR)
88
+ $(AR) rcs $@ $(OBJ)
89
+ $(DIR)/%.o : %.c
90
+ $(XCC) -c $< -o $@ $(XFLAGS)
91
+ $(DIR)/%.o : %.S
92
+ $(XCC) -c $< -o $@ $(XFLAGS)
93
+ $(DIR)/%$(EXESUF) : $(TOP)/win32/tools/%.c
94
+ $(CC) -o $@ $< $(XFLAGS) $(LDFLAGS)
95
+
96
+ $(OBJ) $(XAR) : $(DIR)/exists
97
+ $(DIR)/exists :
98
+ mkdir -p $(DIR)
99
+ @echo $@ > $@
100
+
101
+ clean :
102
+ rm -rfv i386-win32 x86_64-win32 i386 x86_64
@@ -0,0 +1,47 @@
1
+ /* ---------------------------------------------- */
2
+ /* alloca86-bt.S */
3
+
4
+ .globl __bound_alloca
5
+
6
+ __bound_alloca:
7
+ pop %edx
8
+ pop %eax
9
+ mov %eax, %ecx
10
+ add $3,%eax
11
+ and $-4,%eax
12
+ jz p6
13
+
14
+ #ifdef TCC_TARGET_PE
15
+ p4:
16
+ cmp $4096,%eax
17
+ jle p5
18
+ sub $4096,%esp
19
+ sub $4096,%eax
20
+ test %eax,(%esp)
21
+ jmp p4
22
+
23
+ p5:
24
+ #endif
25
+
26
+ sub %eax,%esp
27
+ mov %esp,%eax
28
+
29
+ push %edx
30
+ push %eax
31
+ push %ecx
32
+ push %eax
33
+ call __bound_new_region
34
+ add $8, %esp
35
+ pop %eax
36
+ pop %edx
37
+
38
+ p6:
39
+ push %edx
40
+ push %edx
41
+ ret
42
+
43
+ /* mark stack as nonexecutable */
44
+ #if defined __ELF__ && defined __linux__
45
+ .section .note.GNU-stack,"",@progbits
46
+ #endif
47
+ /* ---------------------------------------------- */
@@ -0,0 +1,35 @@
1
+ /* ---------------------------------------------- */
2
+ /* alloca86.S */
3
+
4
+ .globl alloca
5
+
6
+ alloca:
7
+ pop %edx
8
+ pop %eax
9
+ add $3,%eax
10
+ and $-4,%eax
11
+ jz p3
12
+
13
+ #ifdef TCC_TARGET_PE
14
+ p1:
15
+ cmp $4096,%eax
16
+ jle p2
17
+ sub $4096,%esp
18
+ sub $4096,%eax
19
+ test %eax,(%esp)
20
+ jmp p1
21
+ p2:
22
+ #endif
23
+
24
+ sub %eax,%esp
25
+ mov %esp,%eax
26
+ p3:
27
+ push %edx
28
+ push %edx
29
+ ret
30
+
31
+ /* mark stack as nonexecutable */
32
+ #if defined __ELF__ && defined __linux__
33
+ .section .note.GNU-stack,"",@progbits
34
+ #endif
35
+ /* ---------------------------------------------- */
@@ -0,0 +1,42 @@
1
+ /* ---------------------------------------------- */
2
+ /* alloca86_64.S */
3
+
4
+ .globl alloca
5
+
6
+ alloca:
7
+ pop %rdx
8
+ #ifdef TCC_TARGET_PE
9
+ mov %rcx,%rax
10
+ #else
11
+ mov %rdi,%rax
12
+ #endif
13
+ add $15,%rax
14
+ and $-16,%rax
15
+ jz p3
16
+
17
+ #ifdef TCC_TARGET_PE
18
+ p1:
19
+ cmp $4096,%rax
20
+ jle p2
21
+ sub $4096,%rsp
22
+ sub $4096,%rax
23
+ test %rax,(%rsp)
24
+ jmp p1
25
+ p2:
26
+ #endif
27
+
28
+ sub %rax,%rsp
29
+ mov %rsp,%rax
30
+ #ifdef TCC_TARGET_PE
31
+ add $32,%rax
32
+ #endif
33
+
34
+ p3:
35
+ push %rdx
36
+ ret
37
+
38
+ /* mark stack as nonexecutable */
39
+ #if defined __ELF__ && defined __linux__
40
+ .section .note.GNU-stack,"",@progbits
41
+ #endif
42
+ /* ---------------------------------------------- */
@@ -0,0 +1,875 @@
1
+ /*
2
+ * Tiny C Memory and bounds checker
3
+ *
4
+ * Copyright (c) 2002 Fabrice Bellard
5
+ *
6
+ * This library is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2 of the License, or (at your option) any later version.
10
+ *
11
+ * This library is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with this library; if not, write to the Free Software
18
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ */
20
+ #include <stdlib.h>
21
+ #include <stdio.h>
22
+ #include <stdarg.h>
23
+ #include <string.h>
24
+ #if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) \
25
+ && !defined(__DragonFly__) && !defined(__OpenBSD__)
26
+ #include <malloc.h>
27
+ #endif
28
+ #if !defined(_WIN32)
29
+ #include <unistd.h>
30
+ #endif
31
+
32
+ //#define BOUND_DEBUG
33
+
34
+ /* define so that bound array is static (faster, but use memory if
35
+ bound checking not used) */
36
+ //#define BOUND_STATIC
37
+
38
+ /* use malloc hooks. Currently the code cannot be reliable if no hooks */
39
+ #define CONFIG_TCC_MALLOC_HOOKS
40
+ #define HAVE_MEMALIGN
41
+
42
+ #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
43
+ || defined(__DragonFly__) || defined(__dietlibc__) \
44
+ || defined(__UCLIBC__) || defined(__OpenBSD__) \
45
+ || defined(_WIN32) || defined(TCC_UCLIBC)
46
+ #warning Bound checking does not support malloc (etc.) in this environment.
47
+ #undef CONFIG_TCC_MALLOC_HOOKS
48
+ #undef HAVE_MEMALIGN
49
+ #endif
50
+
51
+ #define BOUND_T1_BITS 13
52
+ #define BOUND_T2_BITS 11
53
+ #define BOUND_T3_BITS (32 - BOUND_T1_BITS - BOUND_T2_BITS)
54
+
55
+ #define BOUND_T1_SIZE (1 << BOUND_T1_BITS)
56
+ #define BOUND_T2_SIZE (1 << BOUND_T2_BITS)
57
+ #define BOUND_T3_SIZE (1 << BOUND_T3_BITS)
58
+ #define BOUND_E_BITS 4
59
+
60
+ #define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS)
61
+ #define BOUND_T23_SIZE (1 << BOUND_T23_BITS)
62
+
63
+
64
+ /* this pointer is generated when bound check is incorrect */
65
+ #define INVALID_POINTER ((void *)(-2))
66
+ /* size of an empty region */
67
+ #define EMPTY_SIZE 0xffffffff
68
+ /* size of an invalid region */
69
+ #define INVALID_SIZE 0
70
+
71
+ typedef struct BoundEntry {
72
+ unsigned long start;
73
+ unsigned long size;
74
+ struct BoundEntry *next;
75
+ unsigned long is_invalid; /* true if pointers outside region are invalid */
76
+ } BoundEntry;
77
+
78
+ /* external interface */
79
+ void __bound_init(void);
80
+ void __bound_new_region(void *p, unsigned long size);
81
+ int __bound_delete_region(void *p);
82
+
83
+ #define FASTCALL __attribute__((regparm(3)))
84
+
85
+ void *__bound_malloc(size_t size, const void *caller);
86
+ void *__bound_memalign(size_t size, size_t align, const void *caller);
87
+ void __bound_free(void *ptr, const void *caller);
88
+ void *__bound_realloc(void *ptr, size_t size, const void *caller);
89
+ static void *libc_malloc(size_t size);
90
+ static void libc_free(void *ptr);
91
+ static void install_malloc_hooks(void);
92
+ static void restore_malloc_hooks(void);
93
+
94
+ #ifdef CONFIG_TCC_MALLOC_HOOKS
95
+ static void *saved_malloc_hook;
96
+ static void *saved_free_hook;
97
+ static void *saved_realloc_hook;
98
+ static void *saved_memalign_hook;
99
+ #endif
100
+
101
+ /* TCC definitions */
102
+ extern char __bounds_start; /* start of static bounds table */
103
+ /* error message, just for TCC */
104
+ const char *__bound_error_msg;
105
+
106
+ /* runtime error output */
107
+ extern void rt_error(unsigned long pc, const char *fmt, ...);
108
+
109
+ #ifdef BOUND_STATIC
110
+ static BoundEntry *__bound_t1[BOUND_T1_SIZE]; /* page table */
111
+ #else
112
+ static BoundEntry **__bound_t1; /* page table */
113
+ #endif
114
+ static BoundEntry *__bound_empty_t2; /* empty page, for unused pages */
115
+ static BoundEntry *__bound_invalid_t2; /* invalid page, for invalid pointers */
116
+
117
+ static BoundEntry *__bound_find_region(BoundEntry *e1, void *p)
118
+ {
119
+ unsigned long addr, tmp;
120
+ BoundEntry *e;
121
+
122
+ e = e1;
123
+ while (e != NULL) {
124
+ addr = (unsigned long)p;
125
+ addr -= e->start;
126
+ if (addr <= e->size) {
127
+ /* put region at the head */
128
+ tmp = e1->start;
129
+ e1->start = e->start;
130
+ e->start = tmp;
131
+ tmp = e1->size;
132
+ e1->size = e->size;
133
+ e->size = tmp;
134
+ return e1;
135
+ }
136
+ e = e->next;
137
+ }
138
+ /* no entry found: return empty entry or invalid entry */
139
+ if (e1->is_invalid)
140
+ return __bound_invalid_t2;
141
+ else
142
+ return __bound_empty_t2;
143
+ }
144
+
145
+ /* print a bound error message */
146
+ static void bound_error(const char *fmt, ...)
147
+ {
148
+ __bound_error_msg = fmt;
149
+ *(int *)0 = 0; /* force a runtime error */
150
+ }
151
+
152
+ static void bound_alloc_error(void)
153
+ {
154
+ bound_error("not enough memory for bound checking code");
155
+ }
156
+
157
+ /* return '(p + offset)' for pointer arithmetic (a pointer can reach
158
+ the end of a region in this case */
159
+ void * FASTCALL __bound_ptr_add(void *p, int offset)
160
+ {
161
+ unsigned long addr = (unsigned long)p;
162
+ BoundEntry *e;
163
+ #if defined(BOUND_DEBUG)
164
+ printf("add: 0x%x %d\n", (int)p, offset);
165
+ #endif
166
+
167
+ e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
168
+ e = (BoundEntry *)((char *)e +
169
+ ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
170
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
171
+ addr -= e->start;
172
+ if (addr > e->size) {
173
+ e = __bound_find_region(e, p);
174
+ addr = (unsigned long)p - e->start;
175
+ }
176
+ addr += offset;
177
+ if (addr > e->size)
178
+ return INVALID_POINTER; /* return an invalid pointer */
179
+ return p + offset;
180
+ }
181
+
182
+ /* return '(p + offset)' for pointer indirection (the resulting must
183
+ be strictly inside the region */
184
+ #define BOUND_PTR_INDIR(dsize) \
185
+ void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset) \
186
+ { \
187
+ unsigned long addr = (unsigned long)p; \
188
+ BoundEntry *e; \
189
+ \
190
+ e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; \
191
+ e = (BoundEntry *)((char *)e + \
192
+ ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & \
193
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS))); \
194
+ addr -= e->start; \
195
+ if (addr > e->size) { \
196
+ e = __bound_find_region(e, p); \
197
+ addr = (unsigned long)p - e->start; \
198
+ } \
199
+ addr += offset + dsize; \
200
+ if (addr > e->size) \
201
+ return INVALID_POINTER; /* return an invalid pointer */ \
202
+ return p + offset; \
203
+ }
204
+
205
+ BOUND_PTR_INDIR(1)
206
+ BOUND_PTR_INDIR(2)
207
+ BOUND_PTR_INDIR(4)
208
+ BOUND_PTR_INDIR(8)
209
+ BOUND_PTR_INDIR(12)
210
+ BOUND_PTR_INDIR(16)
211
+
212
+ /* return the frame pointer of the caller */
213
+ #define GET_CALLER_FP(fp)\
214
+ {\
215
+ fp = (unsigned long)__builtin_frame_address(1);\
216
+ }
217
+
218
+ /* called when entering a function to add all the local regions */
219
+ void FASTCALL __bound_local_new(void *p1)
220
+ {
221
+ unsigned long addr, size, fp, *p = p1;
222
+ GET_CALLER_FP(fp);
223
+ for(;;) {
224
+ addr = p[0];
225
+ if (addr == 0)
226
+ break;
227
+ addr += fp;
228
+ size = p[1];
229
+ p += 2;
230
+ __bound_new_region((void *)addr, size);
231
+ }
232
+ }
233
+
234
+ /* called when leaving a function to delete all the local regions */
235
+ void FASTCALL __bound_local_delete(void *p1)
236
+ {
237
+ unsigned long addr, fp, *p = p1;
238
+ GET_CALLER_FP(fp);
239
+ for(;;) {
240
+ addr = p[0];
241
+ if (addr == 0)
242
+ break;
243
+ addr += fp;
244
+ p += 2;
245
+ __bound_delete_region((void *)addr);
246
+ }
247
+ }
248
+
249
+ static BoundEntry *__bound_new_page(void)
250
+ {
251
+ BoundEntry *page;
252
+ int i;
253
+
254
+ page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE);
255
+ if (!page)
256
+ bound_alloc_error();
257
+ for(i=0;i<BOUND_T2_SIZE;i++) {
258
+ /* put empty entries */
259
+ page[i].start = 0;
260
+ page[i].size = EMPTY_SIZE;
261
+ page[i].next = NULL;
262
+ page[i].is_invalid = 0;
263
+ }
264
+ return page;
265
+ }
266
+
267
+ /* currently we use malloc(). Should use bound_new_page() */
268
+ static BoundEntry *bound_new_entry(void)
269
+ {
270
+ BoundEntry *e;
271
+ e = libc_malloc(sizeof(BoundEntry));
272
+ return e;
273
+ }
274
+
275
+ static void bound_free_entry(BoundEntry *e)
276
+ {
277
+ libc_free(e);
278
+ }
279
+
280
+ static inline BoundEntry *get_page(int index)
281
+ {
282
+ BoundEntry *page;
283
+ page = __bound_t1[index];
284
+ if (page == __bound_empty_t2 || page == __bound_invalid_t2) {
285
+ /* create a new page if necessary */
286
+ page = __bound_new_page();
287
+ __bound_t1[index] = page;
288
+ }
289
+ return page;
290
+ }
291
+
292
+ /* mark a region as being invalid (can only be used during init) */
293
+ static void mark_invalid(unsigned long addr, unsigned long size)
294
+ {
295
+ unsigned long start, end;
296
+ BoundEntry *page;
297
+ int t1_start, t1_end, i, j, t2_start, t2_end;
298
+
299
+ start = addr;
300
+ end = addr + size;
301
+
302
+ t2_start = (start + BOUND_T3_SIZE - 1) >> BOUND_T3_BITS;
303
+ if (end != 0)
304
+ t2_end = end >> BOUND_T3_BITS;
305
+ else
306
+ t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS);
307
+
308
+ #if 0
309
+ printf("mark_invalid: start = %x %x\n", t2_start, t2_end);
310
+ #endif
311
+
312
+ /* first we handle full pages */
313
+ t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS;
314
+ t1_end = t2_end >> BOUND_T2_BITS;
315
+
316
+ i = t2_start & (BOUND_T2_SIZE - 1);
317
+ j = t2_end & (BOUND_T2_SIZE - 1);
318
+
319
+ if (t1_start == t1_end) {
320
+ page = get_page(t2_start >> BOUND_T2_BITS);
321
+ for(; i < j; i++) {
322
+ page[i].size = INVALID_SIZE;
323
+ page[i].is_invalid = 1;
324
+ }
325
+ } else {
326
+ if (i > 0) {
327
+ page = get_page(t2_start >> BOUND_T2_BITS);
328
+ for(; i < BOUND_T2_SIZE; i++) {
329
+ page[i].size = INVALID_SIZE;
330
+ page[i].is_invalid = 1;
331
+ }
332
+ }
333
+ for(i = t1_start; i < t1_end; i++) {
334
+ __bound_t1[i] = __bound_invalid_t2;
335
+ }
336
+ if (j != 0) {
337
+ page = get_page(t1_end);
338
+ for(i = 0; i < j; i++) {
339
+ page[i].size = INVALID_SIZE;
340
+ page[i].is_invalid = 1;
341
+ }
342
+ }
343
+ }
344
+ }
345
+
346
+ void __bound_init(void)
347
+ {
348
+ int i;
349
+ BoundEntry *page;
350
+ unsigned long start, size;
351
+ int *p;
352
+
353
+ /* save malloc hooks and install bound check hooks */
354
+ install_malloc_hooks();
355
+
356
+ #ifndef BOUND_STATIC
357
+ __bound_t1 = libc_malloc(BOUND_T1_SIZE * sizeof(BoundEntry *));
358
+ if (!__bound_t1)
359
+ bound_alloc_error();
360
+ #endif
361
+ __bound_empty_t2 = __bound_new_page();
362
+ for(i=0;i<BOUND_T1_SIZE;i++) {
363
+ __bound_t1[i] = __bound_empty_t2;
364
+ }
365
+
366
+ page = __bound_new_page();
367
+ for(i=0;i<BOUND_T2_SIZE;i++) {
368
+ /* put invalid entries */
369
+ page[i].start = 0;
370
+ page[i].size = INVALID_SIZE;
371
+ page[i].next = NULL;
372
+ page[i].is_invalid = 1;
373
+ }
374
+ __bound_invalid_t2 = page;
375
+
376
+ /* invalid pointer zone */
377
+ start = (unsigned long)INVALID_POINTER & ~(BOUND_T23_SIZE - 1);
378
+ size = BOUND_T23_SIZE;
379
+ mark_invalid(start, size);
380
+
381
+ #if defined(CONFIG_TCC_MALLOC_HOOKS)
382
+ /* malloc zone is also marked invalid. can only use that with
383
+ * hooks because all libs should use the same malloc. The solution
384
+ * would be to build a new malloc for tcc.
385
+ *
386
+ * usually heap (= malloc zone) comes right after bss, i.e. after _end, but
387
+ * not always - either if we are running from under `tcc -b -run`, or if
388
+ * address space randomization is turned on(a), heap start will be separated
389
+ * from bss end.
390
+ *
391
+ * So sbrk(0) will be a good approximation for start_brk:
392
+ *
393
+ * - if we are a separately compiled program, __bound_init() runs early,
394
+ * and sbrk(0) should be equal or very near to start_brk(b) (in case other
395
+ * constructors malloc something), or
396
+ *
397
+ * - if we are running from under `tcc -b -run`, sbrk(0) will return
398
+ * start of heap portion which is under this program control, and not
399
+ * mark as invalid earlier allocated memory.
400
+ *
401
+ *
402
+ * (a) /proc/sys/kernel/randomize_va_space = 2, on Linux;
403
+ * usually turned on by default.
404
+ *
405
+ * (b) on Linux >= v3.3, the alternative is to read
406
+ * start_brk from /proc/self/stat
407
+ */
408
+ start = (unsigned long)sbrk(0);
409
+ size = 128 * 0x100000;
410
+ mark_invalid(start, size);
411
+ #endif
412
+
413
+ /* add all static bound check values */
414
+ p = (int *)&__bounds_start;
415
+ while (p[0] != 0) {
416
+ __bound_new_region((void *)p[0], p[1]);
417
+ p += 2;
418
+ }
419
+ }
420
+
421
+ void __bound_exit(void)
422
+ {
423
+ restore_malloc_hooks();
424
+ }
425
+
426
+ static inline void add_region(BoundEntry *e,
427
+ unsigned long start, unsigned long size)
428
+ {
429
+ BoundEntry *e1;
430
+ if (e->start == 0) {
431
+ /* no region : add it */
432
+ e->start = start;
433
+ e->size = size;
434
+ } else {
435
+ /* already regions in the list: add it at the head */
436
+ e1 = bound_new_entry();
437
+ e1->start = e->start;
438
+ e1->size = e->size;
439
+ e1->next = e->next;
440
+ e->start = start;
441
+ e->size = size;
442
+ e->next = e1;
443
+ }
444
+ }
445
+
446
+ /* create a new region. It should not already exist in the region list */
447
+ void __bound_new_region(void *p, unsigned long size)
448
+ {
449
+ unsigned long start, end;
450
+ BoundEntry *page, *e, *e2;
451
+ int t1_start, t1_end, i, t2_start, t2_end;
452
+
453
+ start = (unsigned long)p;
454
+ end = start + size;
455
+ t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
456
+ t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
457
+
458
+ /* start */
459
+ page = get_page(t1_start);
460
+ t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
461
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
462
+ t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
463
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
464
+ #ifdef BOUND_DEBUG
465
+ printf("new %lx %lx %x %x %x %x\n",
466
+ start, end, t1_start, t1_end, t2_start, t2_end);
467
+ #endif
468
+
469
+ e = (BoundEntry *)((char *)page + t2_start);
470
+ add_region(e, start, size);
471
+
472
+ if (t1_end == t1_start) {
473
+ /* same ending page */
474
+ e2 = (BoundEntry *)((char *)page + t2_end);
475
+ if (e2 > e) {
476
+ e++;
477
+ for(;e<e2;e++) {
478
+ e->start = start;
479
+ e->size = size;
480
+ }
481
+ add_region(e, start, size);
482
+ }
483
+ } else {
484
+ /* mark until end of page */
485
+ e2 = page + BOUND_T2_SIZE;
486
+ e++;
487
+ for(;e<e2;e++) {
488
+ e->start = start;
489
+ e->size = size;
490
+ }
491
+ /* mark intermediate pages, if any */
492
+ for(i=t1_start+1;i<t1_end;i++) {
493
+ page = get_page(i);
494
+ e2 = page + BOUND_T2_SIZE;
495
+ for(e=page;e<e2;e++) {
496
+ e->start = start;
497
+ e->size = size;
498
+ }
499
+ }
500
+ /* last page */
501
+ page = get_page(t1_end);
502
+ e2 = (BoundEntry *)((char *)page + t2_end);
503
+ for(e=page;e<e2;e++) {
504
+ e->start = start;
505
+ e->size = size;
506
+ }
507
+ add_region(e, start, size);
508
+ }
509
+ }
510
+
511
+ /* delete a region */
512
+ static inline void delete_region(BoundEntry *e,
513
+ void *p, unsigned long empty_size)
514
+ {
515
+ unsigned long addr;
516
+ BoundEntry *e1;
517
+
518
+ addr = (unsigned long)p;
519
+ addr -= e->start;
520
+ if (addr <= e->size) {
521
+ /* region found is first one */
522
+ e1 = e->next;
523
+ if (e1 == NULL) {
524
+ /* no more region: mark it empty */
525
+ e->start = 0;
526
+ e->size = empty_size;
527
+ } else {
528
+ /* copy next region in head */
529
+ e->start = e1->start;
530
+ e->size = e1->size;
531
+ e->next = e1->next;
532
+ bound_free_entry(e1);
533
+ }
534
+ } else {
535
+ /* find the matching region */
536
+ for(;;) {
537
+ e1 = e;
538
+ e = e->next;
539
+ /* region not found: do nothing */
540
+ if (e == NULL)
541
+ break;
542
+ addr = (unsigned long)p - e->start;
543
+ if (addr <= e->size) {
544
+ /* found: remove entry */
545
+ e1->next = e->next;
546
+ bound_free_entry(e);
547
+ break;
548
+ }
549
+ }
550
+ }
551
+ }
552
+
553
+ /* WARNING: 'p' must be the starting point of the region. */
554
+ /* return non zero if error */
555
+ int __bound_delete_region(void *p)
556
+ {
557
+ unsigned long start, end, addr, size, empty_size;
558
+ BoundEntry *page, *e, *e2;
559
+ int t1_start, t1_end, t2_start, t2_end, i;
560
+
561
+ start = (unsigned long)p;
562
+ t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
563
+ t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
564
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
565
+
566
+ /* find region size */
567
+ page = __bound_t1[t1_start];
568
+ e = (BoundEntry *)((char *)page + t2_start);
569
+ addr = start - e->start;
570
+ if (addr > e->size)
571
+ e = __bound_find_region(e, p);
572
+ /* test if invalid region */
573
+ if (e->size == EMPTY_SIZE || (unsigned long)p != e->start)
574
+ return -1;
575
+ /* compute the size we put in invalid regions */
576
+ if (e->is_invalid)
577
+ empty_size = INVALID_SIZE;
578
+ else
579
+ empty_size = EMPTY_SIZE;
580
+ size = e->size;
581
+ end = start + size;
582
+
583
+ /* now we can free each entry */
584
+ t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
585
+ t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
586
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
587
+
588
+ delete_region(e, p, empty_size);
589
+ if (t1_end == t1_start) {
590
+ /* same ending page */
591
+ e2 = (BoundEntry *)((char *)page + t2_end);
592
+ if (e2 > e) {
593
+ e++;
594
+ for(;e<e2;e++) {
595
+ e->start = 0;
596
+ e->size = empty_size;
597
+ }
598
+ delete_region(e, p, empty_size);
599
+ }
600
+ } else {
601
+ /* mark until end of page */
602
+ e2 = page + BOUND_T2_SIZE;
603
+ e++;
604
+ for(;e<e2;e++) {
605
+ e->start = 0;
606
+ e->size = empty_size;
607
+ }
608
+ /* mark intermediate pages, if any */
609
+ /* XXX: should free them */
610
+ for(i=t1_start+1;i<t1_end;i++) {
611
+ page = get_page(i);
612
+ e2 = page + BOUND_T2_SIZE;
613
+ for(e=page;e<e2;e++) {
614
+ e->start = 0;
615
+ e->size = empty_size;
616
+ }
617
+ }
618
+ /* last page */
619
+ page = get_page(t1_end);
620
+ e2 = (BoundEntry *)((char *)page + t2_end);
621
+ for(e=page;e<e2;e++) {
622
+ e->start = 0;
623
+ e->size = empty_size;
624
+ }
625
+ delete_region(e, p, empty_size);
626
+ }
627
+ return 0;
628
+ }
629
+
630
+ /* return the size of the region starting at p, or EMPTY_SIZE if non
631
+ existant region. */
632
+ static unsigned long get_region_size(void *p)
633
+ {
634
+ unsigned long addr = (unsigned long)p;
635
+ BoundEntry *e;
636
+
637
+ e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
638
+ e = (BoundEntry *)((char *)e +
639
+ ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
640
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
641
+ addr -= e->start;
642
+ if (addr > e->size)
643
+ e = __bound_find_region(e, p);
644
+ if (e->start != (unsigned long)p)
645
+ return EMPTY_SIZE;
646
+ return e->size;
647
+ }
648
+
649
+ /* patched memory functions */
650
+
651
+ /* force compiler to perform stores coded up to this point */
652
+ #define barrier() __asm__ __volatile__ ("": : : "memory")
653
+
654
+ static void install_malloc_hooks(void)
655
+ {
656
+ #ifdef CONFIG_TCC_MALLOC_HOOKS
657
+ saved_malloc_hook = __malloc_hook;
658
+ saved_free_hook = __free_hook;
659
+ saved_realloc_hook = __realloc_hook;
660
+ saved_memalign_hook = __memalign_hook;
661
+ __malloc_hook = __bound_malloc;
662
+ __free_hook = __bound_free;
663
+ __realloc_hook = __bound_realloc;
664
+ __memalign_hook = __bound_memalign;
665
+
666
+ barrier();
667
+ #endif
668
+ }
669
+
670
+ static void restore_malloc_hooks(void)
671
+ {
672
+ #ifdef CONFIG_TCC_MALLOC_HOOKS
673
+ __malloc_hook = saved_malloc_hook;
674
+ __free_hook = saved_free_hook;
675
+ __realloc_hook = saved_realloc_hook;
676
+ __memalign_hook = saved_memalign_hook;
677
+
678
+ barrier();
679
+ #endif
680
+ }
681
+
682
+ static void *libc_malloc(size_t size)
683
+ {
684
+ void *ptr;
685
+ restore_malloc_hooks();
686
+ ptr = malloc(size);
687
+ install_malloc_hooks();
688
+ return ptr;
689
+ }
690
+
691
+ static void libc_free(void *ptr)
692
+ {
693
+ restore_malloc_hooks();
694
+ free(ptr);
695
+ install_malloc_hooks();
696
+ }
697
+
698
+ /* XXX: we should use a malloc which ensure that it is unlikely that
699
+ two malloc'ed data have the same address if 'free' are made in
700
+ between. */
701
+ void *__bound_malloc(size_t size, const void *caller)
702
+ {
703
+ void *ptr;
704
+
705
+ /* we allocate one more byte to ensure the regions will be
706
+ separated by at least one byte. With the glibc malloc, it may
707
+ be in fact not necessary */
708
+ ptr = libc_malloc(size + 1);
709
+
710
+ if (!ptr)
711
+ return NULL;
712
+ __bound_new_region(ptr, size);
713
+ return ptr;
714
+ }
715
+
716
+ void *__bound_memalign(size_t size, size_t align, const void *caller)
717
+ {
718
+ void *ptr;
719
+
720
+ restore_malloc_hooks();
721
+
722
+ #ifndef HAVE_MEMALIGN
723
+ if (align > 4) {
724
+ /* XXX: handle it ? */
725
+ ptr = NULL;
726
+ } else {
727
+ /* we suppose that malloc aligns to at least four bytes */
728
+ ptr = malloc(size + 1);
729
+ }
730
+ #else
731
+ /* we allocate one more byte to ensure the regions will be
732
+ separated by at least one byte. With the glibc malloc, it may
733
+ be in fact not necessary */
734
+ ptr = memalign(size + 1, align);
735
+ #endif
736
+
737
+ install_malloc_hooks();
738
+
739
+ if (!ptr)
740
+ return NULL;
741
+ __bound_new_region(ptr, size);
742
+ return ptr;
743
+ }
744
+
745
+ void __bound_free(void *ptr, const void *caller)
746
+ {
747
+ if (ptr == NULL)
748
+ return;
749
+ if (__bound_delete_region(ptr) != 0)
750
+ bound_error("freeing invalid region");
751
+
752
+ libc_free(ptr);
753
+ }
754
+
755
+ void *__bound_realloc(void *ptr, size_t size, const void *caller)
756
+ {
757
+ void *ptr1;
758
+ int old_size;
759
+
760
+ if (size == 0) {
761
+ __bound_free(ptr, caller);
762
+ return NULL;
763
+ } else {
764
+ ptr1 = __bound_malloc(size, caller);
765
+ if (ptr == NULL || ptr1 == NULL)
766
+ return ptr1;
767
+ old_size = get_region_size(ptr);
768
+ if (old_size == EMPTY_SIZE)
769
+ bound_error("realloc'ing invalid pointer");
770
+ memcpy(ptr1, ptr, old_size);
771
+ __bound_free(ptr, caller);
772
+ return ptr1;
773
+ }
774
+ }
775
+
776
+ #ifndef CONFIG_TCC_MALLOC_HOOKS
777
+ void *__bound_calloc(size_t nmemb, size_t size)
778
+ {
779
+ void *ptr;
780
+ size = size * nmemb;
781
+ ptr = __bound_malloc(size, NULL);
782
+ if (!ptr)
783
+ return NULL;
784
+ memset(ptr, 0, size);
785
+ return ptr;
786
+ }
787
+ #endif
788
+
789
+ #if 0
790
+ static void bound_dump(void)
791
+ {
792
+ BoundEntry *page, *e;
793
+ int i, j;
794
+
795
+ printf("region dump:\n");
796
+ for(i=0;i<BOUND_T1_SIZE;i++) {
797
+ page = __bound_t1[i];
798
+ for(j=0;j<BOUND_T2_SIZE;j++) {
799
+ e = page + j;
800
+ /* do not print invalid or empty entries */
801
+ if (e->size != EMPTY_SIZE && e->start != 0) {
802
+ printf("%08x:",
803
+ (i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
804
+ (j << BOUND_T3_BITS));
805
+ do {
806
+ printf(" %08lx:%08lx", e->start, e->start + e->size);
807
+ e = e->next;
808
+ } while (e != NULL);
809
+ printf("\n");
810
+ }
811
+ }
812
+ }
813
+ }
814
+ #endif
815
+
816
+ /* some useful checked functions */
817
+
818
+ /* check that (p ... p + size - 1) lies inside 'p' region, if any */
819
+ static void __bound_check(const void *p, size_t size)
820
+ {
821
+ if (size == 0)
822
+ return;
823
+ p = __bound_ptr_add((void *)p, size);
824
+ if (p == INVALID_POINTER)
825
+ bound_error("invalid pointer");
826
+ }
827
+
828
+ void *__bound_memcpy(void *dst, const void *src, size_t size)
829
+ {
830
+ __bound_check(dst, size);
831
+ __bound_check(src, size);
832
+ /* check also region overlap */
833
+ if (src >= dst && src < dst + size)
834
+ bound_error("overlapping regions in memcpy()");
835
+ return memcpy(dst, src, size);
836
+ }
837
+
838
+ void *__bound_memmove(void *dst, const void *src, size_t size)
839
+ {
840
+ __bound_check(dst, size);
841
+ __bound_check(src, size);
842
+ return memmove(dst, src, size);
843
+ }
844
+
845
+ void *__bound_memset(void *dst, int c, size_t size)
846
+ {
847
+ __bound_check(dst, size);
848
+ return memset(dst, c, size);
849
+ }
850
+
851
+ /* XXX: could be optimized */
852
+ int __bound_strlen(const char *s)
853
+ {
854
+ const char *p;
855
+ int len;
856
+
857
+ len = 0;
858
+ for(;;) {
859
+ p = __bound_ptr_indir1((char *)s, len);
860
+ if (p == INVALID_POINTER)
861
+ bound_error("bad pointer in strlen()");
862
+ if (*p == '\0')
863
+ break;
864
+ len++;
865
+ }
866
+ return len;
867
+ }
868
+
869
+ char *__bound_strcpy(char *dst, const char *src)
870
+ {
871
+ int len;
872
+ len = __bound_strlen(src);
873
+ return __bound_memcpy(dst, src, len + 1);
874
+ }
875
+