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,1941 @@
1
+ /*
2
+ * TCC - Tiny C Compiler
3
+ *
4
+ * Copyright (c) 2001-2004 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
+
21
+ #include "tcc.h"
22
+
23
+ /********************************************************/
24
+ /* global variables */
25
+
26
+ /* use GNU C extensions */
27
+ ST_DATA int gnu_ext = 1;
28
+
29
+ /* use TinyCC extensions */
30
+ ST_DATA int tcc_ext = 1;
31
+
32
+ /* XXX: get rid of this ASAP */
33
+ ST_DATA struct TCCState *tcc_state;
34
+
35
+ /********************************************************/
36
+
37
+ #ifdef ONE_SOURCE
38
+ #include "tccpp.c"
39
+ #include "tccgen.c"
40
+ #include "tccelf.c"
41
+ #include "tccrun.c"
42
+ #ifdef TCC_TARGET_I386
43
+ #include "i386-gen.c"
44
+ #endif
45
+ #ifdef TCC_TARGET_ARM
46
+ #include "arm-gen.c"
47
+ #endif
48
+ #ifdef TCC_TARGET_C67
49
+ #include "c67-gen.c"
50
+ #endif
51
+ #ifdef TCC_TARGET_X86_64
52
+ #include "x86_64-gen.c"
53
+ #endif
54
+ #ifdef CONFIG_TCC_ASM
55
+ #include "tccasm.c"
56
+ #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
57
+ #include "i386-asm.c"
58
+ #endif
59
+ #endif
60
+ #ifdef TCC_TARGET_COFF
61
+ #include "tcccoff.c"
62
+ #endif
63
+ #ifdef TCC_TARGET_PE
64
+ #include "tccpe.c"
65
+ #endif
66
+ #endif /* ONE_SOURCE */
67
+
68
+ /********************************************************/
69
+ #ifndef CONFIG_TCC_ASM
70
+ ST_FUNC void asm_instr(void)
71
+ {
72
+ tcc_error("inline asm() not supported");
73
+ }
74
+ ST_FUNC void asm_global_instr(void)
75
+ {
76
+ tcc_error("inline asm() not supported");
77
+ }
78
+ #endif
79
+
80
+ /********************************************************/
81
+
82
+ #ifdef _WIN32
83
+ static char *normalize_slashes(char *path)
84
+ {
85
+ char *p;
86
+ for (p = path; *p; ++p)
87
+ if (*p == '\\')
88
+ *p = '/';
89
+ return path;
90
+ }
91
+
92
+ static HMODULE tcc_module;
93
+
94
+ /* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */
95
+ static void tcc_set_lib_path_w32(TCCState *s)
96
+ {
97
+ char path[1024], *p;
98
+ GetModuleFileNameA(tcc_module, path, sizeof path);
99
+ p = tcc_basename(normalize_slashes(strlwr(path)));
100
+ if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5))
101
+ p -= 5;
102
+ else if (p > path)
103
+ p--;
104
+ *p = 0;
105
+ tcc_set_lib_path(s, path);
106
+ }
107
+
108
+ #ifdef TCC_TARGET_PE
109
+ static void tcc_add_systemdir(TCCState *s)
110
+ {
111
+ char buf[1000];
112
+ GetSystemDirectory(buf, sizeof buf);
113
+ tcc_add_library_path(s, normalize_slashes(buf));
114
+ }
115
+ #endif
116
+
117
+ #ifndef CONFIG_TCC_STATIC
118
+ void dlclose(void *p)
119
+ {
120
+ FreeLibrary((HMODULE)p);
121
+ }
122
+ #endif
123
+
124
+ #ifdef LIBTCC_AS_DLL
125
+ BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
126
+ {
127
+ if (DLL_PROCESS_ATTACH == dwReason)
128
+ tcc_module = hDll;
129
+ return TRUE;
130
+ }
131
+ #endif
132
+ #endif
133
+
134
+ /********************************************************/
135
+ /* copy a string and truncate it. */
136
+ PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
137
+ {
138
+ char *q, *q_end;
139
+ int c;
140
+
141
+ if (buf_size > 0) {
142
+ q = buf;
143
+ q_end = buf + buf_size - 1;
144
+ while (q < q_end) {
145
+ c = *s++;
146
+ if (c == '\0')
147
+ break;
148
+ *q++ = c;
149
+ }
150
+ *q = '\0';
151
+ }
152
+ return buf;
153
+ }
154
+
155
+ /* strcat and truncate. */
156
+ PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
157
+ {
158
+ int len;
159
+ len = strlen(buf);
160
+ if (len < buf_size)
161
+ pstrcpy(buf + len, buf_size - len, s);
162
+ return buf;
163
+ }
164
+
165
+ PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num)
166
+ {
167
+ memcpy(out, in, num);
168
+ out[num] = '\0';
169
+ return out;
170
+ }
171
+
172
+ /* extract the basename of a file */
173
+ PUB_FUNC char *tcc_basename(const char *name)
174
+ {
175
+ char *p = strchr(name, 0);
176
+ while (p > name && !IS_DIRSEP(p[-1]))
177
+ --p;
178
+ return p;
179
+ }
180
+
181
+ /* extract extension part of a file
182
+ *
183
+ * (if no extension, return pointer to end-of-string)
184
+ */
185
+ PUB_FUNC char *tcc_fileextension (const char *name)
186
+ {
187
+ char *b = tcc_basename(name);
188
+ char *e = strrchr(b, '.');
189
+ return e ? e : strchr(b, 0);
190
+ }
191
+
192
+ /********************************************************/
193
+ /* memory management */
194
+
195
+ #undef free
196
+ #undef malloc
197
+ #undef realloc
198
+
199
+ #ifdef MEM_DEBUG
200
+ ST_DATA int mem_cur_size;
201
+ ST_DATA int mem_max_size;
202
+ unsigned malloc_usable_size(void*);
203
+ #endif
204
+
205
+ PUB_FUNC void tcc_free(void *ptr)
206
+ {
207
+ #ifdef MEM_DEBUG
208
+ mem_cur_size -= malloc_usable_size(ptr);
209
+ #endif
210
+ free(ptr);
211
+ }
212
+
213
+ PUB_FUNC void *tcc_malloc(unsigned long size)
214
+ {
215
+ void *ptr;
216
+ ptr = malloc(size);
217
+ if (!ptr && size)
218
+ tcc_error("memory full");
219
+ #ifdef MEM_DEBUG
220
+ mem_cur_size += malloc_usable_size(ptr);
221
+ if (mem_cur_size > mem_max_size)
222
+ mem_max_size = mem_cur_size;
223
+ #endif
224
+ return ptr;
225
+ }
226
+
227
+ PUB_FUNC void *tcc_mallocz(unsigned long size)
228
+ {
229
+ void *ptr;
230
+ ptr = tcc_malloc(size);
231
+ memset(ptr, 0, size);
232
+ return ptr;
233
+ }
234
+
235
+ PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
236
+ {
237
+ void *ptr1;
238
+ #ifdef MEM_DEBUG
239
+ mem_cur_size -= malloc_usable_size(ptr);
240
+ #endif
241
+ ptr1 = realloc(ptr, size);
242
+ if (!ptr1 && size)
243
+ tcc_error("memory full");
244
+ #ifdef MEM_DEBUG
245
+ /* NOTE: count not correct if alloc error, but not critical */
246
+ mem_cur_size += malloc_usable_size(ptr1);
247
+ if (mem_cur_size > mem_max_size)
248
+ mem_max_size = mem_cur_size;
249
+ #endif
250
+ return ptr1;
251
+ }
252
+
253
+ PUB_FUNC char *tcc_strdup(const char *str)
254
+ {
255
+ char *ptr;
256
+ ptr = tcc_malloc(strlen(str) + 1);
257
+ strcpy(ptr, str);
258
+ return ptr;
259
+ }
260
+
261
+ PUB_FUNC void tcc_memstats(void)
262
+ {
263
+ #ifdef MEM_DEBUG
264
+ printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
265
+ #endif
266
+ }
267
+
268
+ #define free(p) use_tcc_free(p)
269
+ #define malloc(s) use_tcc_malloc(s)
270
+ #define realloc(p, s) use_tcc_realloc(p, s)
271
+
272
+ /********************************************************/
273
+ /* dynarrays */
274
+
275
+ ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data)
276
+ {
277
+ int nb, nb_alloc;
278
+ void **pp;
279
+
280
+ nb = *nb_ptr;
281
+ pp = *ptab;
282
+ /* every power of two we double array size */
283
+ if ((nb & (nb - 1)) == 0) {
284
+ if (!nb)
285
+ nb_alloc = 1;
286
+ else
287
+ nb_alloc = nb * 2;
288
+ pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
289
+ *ptab = pp;
290
+ }
291
+ pp[nb++] = data;
292
+ *nb_ptr = nb;
293
+ }
294
+
295
+ ST_FUNC void dynarray_reset(void *pp, int *n)
296
+ {
297
+ void **p;
298
+ for (p = *(void***)pp; *n; ++p, --*n)
299
+ if (*p)
300
+ tcc_free(*p);
301
+ tcc_free(*(void**)pp);
302
+ *(void**)pp = NULL;
303
+ }
304
+
305
+ static void tcc_split_path(TCCState *s, void ***p_ary, int *p_nb_ary, const char *in)
306
+ {
307
+ const char *p;
308
+ do {
309
+ int c;
310
+ CString str;
311
+
312
+ cstr_new(&str);
313
+ for (p = in; c = *p, c != '\0' && c != PATHSEP; ++p) {
314
+ if (c == '{' && p[1] && p[2] == '}') {
315
+ c = p[1], p += 2;
316
+ if (c == 'B')
317
+ cstr_cat(&str, s->tcc_lib_path);
318
+ } else {
319
+ cstr_ccat(&str, c);
320
+ }
321
+ }
322
+ cstr_ccat(&str, '\0');
323
+ dynarray_add(p_ary, p_nb_ary, str.data);
324
+ in = p+1;
325
+ } while (*p);
326
+ }
327
+
328
+ /********************************************************/
329
+
330
+ ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
331
+ {
332
+ Section *sec;
333
+
334
+ sec = tcc_mallocz(sizeof(Section) + strlen(name));
335
+ strcpy(sec->name, name);
336
+ sec->sh_type = sh_type;
337
+ sec->sh_flags = sh_flags;
338
+ switch(sh_type) {
339
+ case SHT_HASH:
340
+ case SHT_REL:
341
+ case SHT_RELA:
342
+ case SHT_DYNSYM:
343
+ case SHT_SYMTAB:
344
+ case SHT_DYNAMIC:
345
+ sec->sh_addralign = 4;
346
+ break;
347
+ case SHT_STRTAB:
348
+ sec->sh_addralign = 1;
349
+ break;
350
+ default:
351
+ sec->sh_addralign = 32; /* default conservative alignment */
352
+ break;
353
+ }
354
+
355
+ if (sh_flags & SHF_PRIVATE) {
356
+ dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec);
357
+ } else {
358
+ sec->sh_num = s1->nb_sections;
359
+ dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
360
+ }
361
+
362
+ return sec;
363
+ }
364
+
365
+ static void free_section(Section *s)
366
+ {
367
+ tcc_free(s->data);
368
+ }
369
+
370
+ /* realloc section and set its content to zero */
371
+ ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
372
+ {
373
+ unsigned long size;
374
+ unsigned char *data;
375
+
376
+ size = sec->data_allocated;
377
+ if (size == 0)
378
+ size = 1;
379
+ while (size < new_size)
380
+ size = size * 2;
381
+ data = tcc_realloc(sec->data, size);
382
+ memset(data + sec->data_allocated, 0, size - sec->data_allocated);
383
+ sec->data = data;
384
+ sec->data_allocated = size;
385
+ }
386
+
387
+ /* reserve at least 'size' bytes in section 'sec' from
388
+ sec->data_offset. */
389
+ ST_FUNC void *section_ptr_add(Section *sec, unsigned long size)
390
+ {
391
+ unsigned long offset, offset1;
392
+
393
+ offset = sec->data_offset;
394
+ offset1 = offset + size;
395
+ if (offset1 > sec->data_allocated)
396
+ section_realloc(sec, offset1);
397
+ sec->data_offset = offset1;
398
+ return sec->data + offset;
399
+ }
400
+
401
+ /* reserve at least 'size' bytes from section start */
402
+ ST_FUNC void section_reserve(Section *sec, unsigned long size)
403
+ {
404
+ if (size > sec->data_allocated)
405
+ section_realloc(sec, size);
406
+ if (size > sec->data_offset)
407
+ sec->data_offset = size;
408
+ }
409
+
410
+ /* return a reference to a section, and create it if it does not
411
+ exists */
412
+ ST_FUNC Section *find_section(TCCState *s1, const char *name)
413
+ {
414
+ Section *sec;
415
+ int i;
416
+ for(i = 1; i < s1->nb_sections; i++) {
417
+ sec = s1->sections[i];
418
+ if (!strcmp(name, sec->name))
419
+ return sec;
420
+ }
421
+ /* sections are created as PROGBITS */
422
+ return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
423
+ }
424
+
425
+ /* update sym->c so that it points to an external symbol in section
426
+ 'section' with value 'value' */
427
+ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
428
+ addr_t value, unsigned long size,
429
+ int can_add_underscore)
430
+ {
431
+ int sym_type, sym_bind, sh_num, info, other;
432
+ ElfW(Sym) *esym;
433
+ const char *name;
434
+ char buf1[256];
435
+
436
+ if (section == NULL)
437
+ sh_num = SHN_UNDEF;
438
+ else if (section == SECTION_ABS)
439
+ sh_num = SHN_ABS;
440
+ else
441
+ sh_num = section->sh_num;
442
+
443
+ if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
444
+ sym_type = STT_FUNC;
445
+ } else if ((sym->type.t & VT_BTYPE) == VT_VOID) {
446
+ sym_type = STT_NOTYPE;
447
+ } else {
448
+ sym_type = STT_OBJECT;
449
+ }
450
+
451
+ if (sym->type.t & VT_STATIC)
452
+ sym_bind = STB_LOCAL;
453
+ else {
454
+ if (sym->type.t & VT_WEAK)
455
+ sym_bind = STB_WEAK;
456
+ else
457
+ sym_bind = STB_GLOBAL;
458
+ }
459
+
460
+ if (!sym->c) {
461
+ name = get_tok_str(sym->v, NULL);
462
+ #ifdef CONFIG_TCC_BCHECK
463
+ if (tcc_state->do_bounds_check) {
464
+ char buf[32];
465
+
466
+ /* XXX: avoid doing that for statics ? */
467
+ /* if bound checking is activated, we change some function
468
+ names by adding the "__bound" prefix */
469
+ switch(sym->v) {
470
+ #ifdef TCC_TARGET_PE
471
+ /* XXX: we rely only on malloc hooks */
472
+ case TOK_malloc:
473
+ case TOK_free:
474
+ case TOK_realloc:
475
+ case TOK_memalign:
476
+ case TOK_calloc:
477
+ #endif
478
+ case TOK_memcpy:
479
+ case TOK_memmove:
480
+ case TOK_memset:
481
+ case TOK_strlen:
482
+ case TOK_strcpy:
483
+ case TOK_alloca:
484
+ strcpy(buf, "__bound_");
485
+ strcat(buf, name);
486
+ name = buf;
487
+ break;
488
+ }
489
+ }
490
+ #endif
491
+ other = 0;
492
+
493
+ #ifdef TCC_TARGET_PE
494
+ if (sym->type.t & VT_EXPORT)
495
+ other |= 1;
496
+ if (sym_type == STT_FUNC && sym->type.ref) {
497
+ int attr = sym->type.ref->r;
498
+ if (FUNC_EXPORT(attr))
499
+ other |= 1;
500
+ if (FUNC_CALL(attr) == FUNC_STDCALL && can_add_underscore) {
501
+ sprintf(buf1, "_%s@%d", name, FUNC_ARGS(attr) * PTR_SIZE);
502
+ name = buf1;
503
+ other |= 2;
504
+ can_add_underscore = 0;
505
+ }
506
+ } else {
507
+ if (find_elf_sym(tcc_state->dynsymtab_section, name))
508
+ other |= 4;
509
+ if (sym->type.t & VT_IMPORT)
510
+ other |= 4;
511
+ }
512
+ #endif
513
+ if (tcc_state->leading_underscore && can_add_underscore) {
514
+ buf1[0] = '_';
515
+ pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
516
+ name = buf1;
517
+ }
518
+ if (sym->asm_label) {
519
+ name = sym->asm_label;
520
+ }
521
+ info = ELFW(ST_INFO)(sym_bind, sym_type);
522
+ sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);
523
+ } else {
524
+ esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
525
+ esym->st_value = value;
526
+ esym->st_size = size;
527
+ esym->st_shndx = sh_num;
528
+ }
529
+ }
530
+
531
+ ST_FUNC void put_extern_sym(Sym *sym, Section *section,
532
+ addr_t value, unsigned long size)
533
+ {
534
+ put_extern_sym2(sym, section, value, size, 1);
535
+ }
536
+
537
+ /* add a new relocation entry to symbol 'sym' in section 's' */
538
+ ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
539
+ {
540
+ int c = 0;
541
+ if (sym) {
542
+ if (0 == sym->c)
543
+ put_extern_sym(sym, NULL, 0, 0);
544
+ c = sym->c;
545
+ }
546
+ /* now we can add ELF relocation info */
547
+ put_elf_reloc(symtab_section, s, offset, type, c);
548
+ }
549
+
550
+ /********************************************************/
551
+
552
+ static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
553
+ {
554
+ int len;
555
+ len = strlen(buf);
556
+ vsnprintf(buf + len, buf_size - len, fmt, ap);
557
+ }
558
+
559
+ static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
560
+ {
561
+ va_list ap;
562
+ va_start(ap, fmt);
563
+ strcat_vprintf(buf, buf_size, fmt, ap);
564
+ va_end(ap);
565
+ }
566
+
567
+ static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
568
+ {
569
+ char buf[2048];
570
+ BufferedFile **pf, *f;
571
+
572
+ buf[0] = '\0';
573
+ /* use upper file if inline ":asm:" or token ":paste:" */
574
+ for (f = file; f && f->filename[0] == ':'; f = f->prev);
575
+ if (f) {
576
+ for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++)
577
+ strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
578
+ (*pf)->filename, (*pf)->line_num);
579
+ if (f->line_num > 0) {
580
+ strcat_printf(buf, sizeof(buf), "%s:%d: ",
581
+ f->filename, f->line_num);
582
+ } else {
583
+ strcat_printf(buf, sizeof(buf), "%s: ",
584
+ f->filename);
585
+ }
586
+ } else {
587
+ strcat_printf(buf, sizeof(buf), "tcc: ");
588
+ }
589
+ if (is_warning)
590
+ strcat_printf(buf, sizeof(buf), "warning: ");
591
+ else
592
+ strcat_printf(buf, sizeof(buf), "error: ");
593
+ strcat_vprintf(buf, sizeof(buf), fmt, ap);
594
+
595
+ if (!s1->error_func) {
596
+ /* default case: stderr */
597
+ fprintf(stderr, "%s\n", buf);
598
+ } else {
599
+ s1->error_func(s1->error_opaque, buf);
600
+ }
601
+ if (!is_warning || s1->warn_error)
602
+ s1->nb_errors++;
603
+ }
604
+
605
+ LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
606
+ void (*error_func)(void *opaque, const char *msg))
607
+ {
608
+ s->error_opaque = error_opaque;
609
+ s->error_func = error_func;
610
+ }
611
+
612
+ /* error without aborting current compilation */
613
+ PUB_FUNC void tcc_error_noabort(const char *fmt, ...)
614
+ {
615
+ TCCState *s1 = tcc_state;
616
+ va_list ap;
617
+
618
+ va_start(ap, fmt);
619
+ error1(s1, 0, fmt, ap);
620
+ va_end(ap);
621
+ }
622
+
623
+ PUB_FUNC void tcc_error(const char *fmt, ...)
624
+ {
625
+ TCCState *s1 = tcc_state;
626
+ va_list ap;
627
+
628
+ va_start(ap, fmt);
629
+ error1(s1, 0, fmt, ap);
630
+ va_end(ap);
631
+ /* better than nothing: in some cases, we accept to handle errors */
632
+ if (s1->error_set_jmp_enabled) {
633
+ longjmp(s1->error_jmp_buf, 1);
634
+ } else {
635
+ /* XXX: eliminate this someday */
636
+ exit(1);
637
+ }
638
+ }
639
+
640
+ PUB_FUNC void tcc_warning(const char *fmt, ...)
641
+ {
642
+ TCCState *s1 = tcc_state;
643
+ va_list ap;
644
+
645
+ if (s1->warn_none)
646
+ return;
647
+
648
+ va_start(ap, fmt);
649
+ error1(s1, 1, fmt, ap);
650
+ va_end(ap);
651
+ }
652
+
653
+ /********************************************************/
654
+ /* I/O layer */
655
+
656
+ ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
657
+ {
658
+ BufferedFile *bf;
659
+ int buflen = initlen ? initlen : IO_BUF_SIZE;
660
+
661
+ bf = tcc_malloc(sizeof(BufferedFile) + buflen);
662
+ bf->buf_ptr = bf->buffer;
663
+ bf->buf_end = bf->buffer + initlen;
664
+ bf->buf_end[0] = CH_EOB; /* put eob symbol */
665
+ pstrcpy(bf->filename, sizeof(bf->filename), filename);
666
+ #ifdef _WIN32
667
+ normalize_slashes(bf->filename);
668
+ #endif
669
+ bf->line_num = 1;
670
+ bf->ifndef_macro = 0;
671
+ bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
672
+ bf->fd = -1;
673
+ bf->prev = file;
674
+ file = bf;
675
+ }
676
+
677
+ ST_FUNC void tcc_close(void)
678
+ {
679
+ BufferedFile *bf = file;
680
+ if (bf->fd > 0) {
681
+ close(bf->fd);
682
+ total_lines += bf->line_num;
683
+ }
684
+ file = bf->prev;
685
+ tcc_free(bf);
686
+ }
687
+
688
+ ST_FUNC int tcc_open(TCCState *s1, const char *filename)
689
+ {
690
+ int fd;
691
+ if (strcmp(filename, "-") == 0)
692
+ fd = 0, filename = "stdin";
693
+ else
694
+ fd = open(filename, O_RDONLY | O_BINARY);
695
+ if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)
696
+ printf("%s %*s%s\n", fd < 0 ? "nf":"->",
697
+ (int)(s1->include_stack_ptr - s1->include_stack), "", filename);
698
+ if (fd < 0)
699
+ return -1;
700
+
701
+ tcc_open_bf(s1, filename, 0);
702
+ file->fd = fd;
703
+ return fd;
704
+ }
705
+
706
+ /* compile the C file opened in 'file'. Return non zero if errors. */
707
+ static int tcc_compile(TCCState *s1)
708
+ {
709
+ Sym *define_start;
710
+ SValue *pvtop;
711
+ char buf[512];
712
+ volatile int section_sym;
713
+
714
+ #ifdef INC_DEBUG
715
+ printf("%s: **** new file\n", file->filename);
716
+ #endif
717
+ preprocess_init(s1);
718
+
719
+ cur_text_section = NULL;
720
+ funcname = "";
721
+ anon_sym = SYM_FIRST_ANOM;
722
+
723
+ /* file info: full path + filename */
724
+ section_sym = 0; /* avoid warning */
725
+ if (s1->do_debug) {
726
+ section_sym = put_elf_sym(symtab_section, 0, 0,
727
+ ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
728
+ text_section->sh_num, NULL);
729
+ getcwd(buf, sizeof(buf));
730
+ #ifdef _WIN32
731
+ normalize_slashes(buf);
732
+ #endif
733
+ pstrcat(buf, sizeof(buf), "/");
734
+ put_stabs_r(buf, N_SO, 0, 0,
735
+ text_section->data_offset, text_section, section_sym);
736
+ put_stabs_r(file->filename, N_SO, 0, 0,
737
+ text_section->data_offset, text_section, section_sym);
738
+ }
739
+ /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
740
+ symbols can be safely used */
741
+ put_elf_sym(symtab_section, 0, 0,
742
+ ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
743
+ SHN_ABS, file->filename);
744
+
745
+ /* define some often used types */
746
+ int_type.t = VT_INT;
747
+
748
+ char_pointer_type.t = VT_BYTE;
749
+ mk_pointer(&char_pointer_type);
750
+
751
+ #if PTR_SIZE == 4
752
+ size_type.t = VT_INT;
753
+ #else
754
+ size_type.t = VT_LLONG;
755
+ #endif
756
+
757
+ func_old_type.t = VT_FUNC;
758
+ func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
759
+ #ifdef TCC_TARGET_ARM
760
+ arm_init_types();
761
+ #endif
762
+
763
+ #if 0
764
+ /* define 'void *alloca(unsigned int)' builtin function */
765
+ {
766
+ Sym *s1;
767
+
768
+ p = anon_sym++;
769
+ sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
770
+ s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
771
+ s1->next = NULL;
772
+ sym->next = s1;
773
+ sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
774
+ }
775
+ #endif
776
+
777
+ define_start = define_stack;
778
+ nocode_wanted = 1;
779
+
780
+ if (setjmp(s1->error_jmp_buf) == 0) {
781
+ s1->nb_errors = 0;
782
+ s1->error_set_jmp_enabled = 1;
783
+
784
+ ch = file->buf_ptr[0];
785
+ tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
786
+ parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
787
+ pvtop = vtop;
788
+ next();
789
+ decl(VT_CONST);
790
+ if (tok != TOK_EOF)
791
+ expect("declaration");
792
+ if (pvtop != vtop)
793
+ tcc_warning("internal compiler error: vstack leak? (%d)", vtop - pvtop);
794
+
795
+ /* end of translation unit info */
796
+ if (s1->do_debug) {
797
+ put_stabs_r(NULL, N_SO, 0, 0,
798
+ text_section->data_offset, text_section, section_sym);
799
+ }
800
+ }
801
+
802
+ s1->error_set_jmp_enabled = 0;
803
+
804
+ /* reset define stack, but leave -Dsymbols (may be incorrect if
805
+ they are undefined) */
806
+ free_defines(define_start);
807
+
808
+ gen_inline_functions();
809
+
810
+ sym_pop(&global_stack, NULL);
811
+ sym_pop(&local_stack, NULL);
812
+
813
+ return s1->nb_errors != 0 ? -1 : 0;
814
+ }
815
+
816
+ LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
817
+ {
818
+ int len, ret;
819
+ len = strlen(str);
820
+
821
+ tcc_open_bf(s, "<string>", len);
822
+ memcpy(file->buffer, str, len);
823
+ ret = tcc_compile(s);
824
+ tcc_close();
825
+ return ret;
826
+ }
827
+
828
+ /* define a preprocessor symbol. A value can also be provided with the '=' operator */
829
+ LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
830
+ {
831
+ int len1, len2;
832
+ /* default value */
833
+ if (!value)
834
+ value = "1";
835
+ len1 = strlen(sym);
836
+ len2 = strlen(value);
837
+
838
+ /* init file structure */
839
+ tcc_open_bf(s1, "<define>", len1 + len2 + 1);
840
+ memcpy(file->buffer, sym, len1);
841
+ file->buffer[len1] = ' ';
842
+ memcpy(file->buffer + len1 + 1, value, len2);
843
+
844
+ /* parse with define parser */
845
+ ch = file->buf_ptr[0];
846
+ next_nomacro();
847
+ parse_define();
848
+
849
+ tcc_close();
850
+ }
851
+
852
+ /* undefine a preprocessor symbol */
853
+ LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
854
+ {
855
+ TokenSym *ts;
856
+ Sym *s;
857
+ ts = tok_alloc(sym, strlen(sym));
858
+ s = define_find(ts->tok);
859
+ /* undefine symbol by putting an invalid name */
860
+ if (s)
861
+ define_undef(s);
862
+ }
863
+
864
+ /* cleanup all static data used during compilation */
865
+ static void tcc_cleanup(void)
866
+ {
867
+ int i, n;
868
+ if (NULL == tcc_state)
869
+ return;
870
+ tcc_state = NULL;
871
+
872
+ /* free -D defines */
873
+ free_defines(NULL);
874
+
875
+ /* free tokens */
876
+ n = tok_ident - TOK_IDENT;
877
+ for(i = 0; i < n; i++)
878
+ tcc_free(table_ident[i]);
879
+ tcc_free(table_ident);
880
+
881
+ /* free sym_pools */
882
+ dynarray_reset(&sym_pools, &nb_sym_pools);
883
+ /* string buffer */
884
+ cstr_free(&tokcstr);
885
+ /* reset symbol stack */
886
+ sym_free_first = NULL;
887
+ /* cleanup from error/setjmp */
888
+ macro_ptr = NULL;
889
+ }
890
+
891
+ LIBTCCAPI TCCState *tcc_new(void)
892
+ {
893
+ TCCState *s;
894
+ char buffer[100];
895
+ int a,b,c;
896
+
897
+ tcc_cleanup();
898
+
899
+ s = tcc_mallocz(sizeof(TCCState));
900
+ if (!s)
901
+ return NULL;
902
+ tcc_state = s;
903
+ #ifdef _WIN32
904
+ tcc_set_lib_path_w32(s);
905
+ #else
906
+ tcc_set_lib_path(s, CONFIG_TCCDIR);
907
+ #endif
908
+ s->output_type = TCC_OUTPUT_MEMORY;
909
+ preprocess_new();
910
+ s->include_stack_ptr = s->include_stack;
911
+
912
+ /* we add dummy defines for some special macros to speed up tests
913
+ and to have working defined() */
914
+ define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
915
+ define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
916
+ define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
917
+ define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
918
+
919
+ /* define __TINYC__ 92X */
920
+ sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c);
921
+ sprintf(buffer, "%d", a*10000 + b*100 + c);
922
+ tcc_define_symbol(s, "__TINYC__", buffer);
923
+
924
+ /* standard defines */
925
+ tcc_define_symbol(s, "__STDC__", NULL);
926
+ tcc_define_symbol(s, "__STDC_VERSION__", "199901L");
927
+
928
+ /* target defines */
929
+ #if defined(TCC_TARGET_I386)
930
+ tcc_define_symbol(s, "__i386__", NULL);
931
+ tcc_define_symbol(s, "__i386", NULL);
932
+ tcc_define_symbol(s, "i386", NULL);
933
+ #elif defined(TCC_TARGET_X86_64)
934
+ tcc_define_symbol(s, "__x86_64__", NULL);
935
+ #elif defined(TCC_TARGET_ARM)
936
+ tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
937
+ tcc_define_symbol(s, "__arm_elf__", NULL);
938
+ tcc_define_symbol(s, "__arm_elf", NULL);
939
+ tcc_define_symbol(s, "arm_elf", NULL);
940
+ tcc_define_symbol(s, "__arm__", NULL);
941
+ tcc_define_symbol(s, "__arm", NULL);
942
+ tcc_define_symbol(s, "arm", NULL);
943
+ tcc_define_symbol(s, "__APCS_32__", NULL);
944
+ #endif
945
+
946
+ #ifdef TCC_TARGET_PE
947
+ tcc_define_symbol(s, "_WIN32", NULL);
948
+ # ifdef TCC_TARGET_X86_64
949
+ tcc_define_symbol(s, "_WIN64", NULL);
950
+ # endif
951
+ #else
952
+ tcc_define_symbol(s, "__unix__", NULL);
953
+ tcc_define_symbol(s, "__unix", NULL);
954
+ tcc_define_symbol(s, "unix", NULL);
955
+ # if defined(__linux)
956
+ tcc_define_symbol(s, "__linux__", NULL);
957
+ tcc_define_symbol(s, "__linux", NULL);
958
+ # endif
959
+ # if defined(__FreeBSD__)
960
+ # define str(s) #s
961
+ tcc_define_symbol(s, "__FreeBSD__", str( __FreeBSD__));
962
+ # undef str
963
+ # endif
964
+ # if defined(__FreeBSD_kernel__)
965
+ tcc_define_symbol(s, "__FreeBSD_kernel__", NULL);
966
+ # endif
967
+ #endif
968
+
969
+ /* TinyCC & gcc defines */
970
+ #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
971
+ tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long");
972
+ tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long");
973
+ #else
974
+ tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");
975
+ tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");
976
+ #endif
977
+
978
+ #ifdef TCC_TARGET_PE
979
+ tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short");
980
+ #else
981
+ tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
982
+ #endif
983
+
984
+ #ifndef TCC_TARGET_PE
985
+ /* glibc defines */
986
+ tcc_define_symbol(s, "__REDIRECT(name, proto, alias)", "name proto __asm__ (#alias)");
987
+ tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", "name proto __asm__ (#alias) __THROW");
988
+ /* default library paths */
989
+ tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
990
+ /* paths for crt objects */
991
+ tcc_split_path(s, (void ***)&s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
992
+ #endif
993
+
994
+ /* no section zero */
995
+ dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
996
+
997
+ /* create standard sections */
998
+ text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
999
+ data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1000
+ bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
1001
+
1002
+ /* symbols are always generated for linking stage */
1003
+ symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
1004
+ ".strtab",
1005
+ ".hashtab", SHF_PRIVATE);
1006
+ strtab_section = symtab_section->link;
1007
+ s->symtab = symtab_section;
1008
+
1009
+ /* private symbol table for dynamic symbols */
1010
+ s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
1011
+ ".dynstrtab",
1012
+ ".dynhashtab", SHF_PRIVATE);
1013
+ s->alacarte_link = 1;
1014
+ s->nocommon = 1;
1015
+ s->section_align = ELF_PAGE_SIZE;
1016
+
1017
+ #ifdef CHAR_IS_UNSIGNED
1018
+ s->char_is_unsigned = 1;
1019
+ #endif
1020
+ /* enable this if you want symbols with leading underscore on windows: */
1021
+ #if 0 //def TCC_TARGET_PE
1022
+ s->leading_underscore = 1;
1023
+ #endif
1024
+ #ifdef TCC_TARGET_I386
1025
+ s->seg_size = 32;
1026
+ #endif
1027
+ return s;
1028
+ }
1029
+
1030
+ LIBTCCAPI void tcc_delete(TCCState *s1)
1031
+ {
1032
+ int i;
1033
+
1034
+ tcc_cleanup();
1035
+
1036
+ /* free all sections */
1037
+ for(i = 1; i < s1->nb_sections; i++)
1038
+ free_section(s1->sections[i]);
1039
+ dynarray_reset(&s1->sections, &s1->nb_sections);
1040
+
1041
+ for(i = 0; i < s1->nb_priv_sections; i++)
1042
+ free_section(s1->priv_sections[i]);
1043
+ dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
1044
+
1045
+ /* free any loaded DLLs */
1046
+ for ( i = 0; i < s1->nb_loaded_dlls; i++) {
1047
+ DLLReference *ref = s1->loaded_dlls[i];
1048
+ if ( ref->handle )
1049
+ dlclose(ref->handle);
1050
+ }
1051
+
1052
+ /* free loaded dlls array */
1053
+ dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
1054
+
1055
+ /* free library paths */
1056
+ dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
1057
+ dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths);
1058
+
1059
+ /* free include paths */
1060
+ dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
1061
+ dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
1062
+ dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
1063
+
1064
+ tcc_free(s1->tcc_lib_path);
1065
+ tcc_free(s1->soname);
1066
+ tcc_free(s1->rpath);
1067
+ tcc_free(s1->init_symbol);
1068
+ tcc_free(s1->fini_symbol);
1069
+ tcc_free(s1->outfile);
1070
+ tcc_free(s1->deps_outfile);
1071
+ dynarray_reset(&s1->files, &s1->nb_files);
1072
+ dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
1073
+
1074
+ #ifdef TCC_IS_NATIVE
1075
+ # ifdef HAVE_SELINUX
1076
+ munmap (s1->write_mem, s1->mem_size);
1077
+ munmap (s1->runtime_mem, s1->mem_size);
1078
+ # else
1079
+ tcc_free(s1->runtime_mem);
1080
+ # endif
1081
+ #endif
1082
+
1083
+ tcc_free(s1);
1084
+ }
1085
+
1086
+ LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
1087
+ {
1088
+ tcc_split_path(s, (void ***)&s->include_paths, &s->nb_include_paths, pathname);
1089
+ return 0;
1090
+ }
1091
+
1092
+ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
1093
+ {
1094
+ tcc_split_path(s, (void ***)&s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);
1095
+ return 0;
1096
+ }
1097
+
1098
+ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
1099
+ {
1100
+ const char *ext;
1101
+ ElfW(Ehdr) ehdr;
1102
+ int fd, ret, size;
1103
+
1104
+ /* find source file type with extension */
1105
+ ext = tcc_fileextension(filename);
1106
+ if (ext[0])
1107
+ ext++;
1108
+
1109
+ #ifdef CONFIG_TCC_ASM
1110
+ /* if .S file, define __ASSEMBLER__ like gcc does */
1111
+ if (!strcmp(ext, "S"))
1112
+ tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
1113
+ #endif
1114
+
1115
+ /* open the file */
1116
+ ret = tcc_open(s1, filename);
1117
+ if (ret < 0) {
1118
+ if (flags & AFF_PRINT_ERROR)
1119
+ tcc_error_noabort("file '%s' not found", filename);
1120
+ return ret;
1121
+ }
1122
+
1123
+ /* update target deps */
1124
+ dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
1125
+ tcc_strdup(filename));
1126
+
1127
+ if (flags & AFF_PREPROCESS) {
1128
+ ret = tcc_preprocess(s1);
1129
+ goto the_end;
1130
+ }
1131
+
1132
+ if (!ext[0] || !PATHCMP(ext, "c")) {
1133
+ /* C file assumed */
1134
+ ret = tcc_compile(s1);
1135
+ goto the_end;
1136
+ }
1137
+
1138
+ #ifdef CONFIG_TCC_ASM
1139
+ if (!strcmp(ext, "S")) {
1140
+ /* preprocessed assembler */
1141
+ ret = tcc_assemble(s1, 1);
1142
+ goto the_end;
1143
+ }
1144
+
1145
+ if (!strcmp(ext, "s")) {
1146
+ /* non preprocessed assembler */
1147
+ ret = tcc_assemble(s1, 0);
1148
+ goto the_end;
1149
+ }
1150
+ #endif
1151
+
1152
+ fd = file->fd;
1153
+ /* assume executable format: auto guess file type */
1154
+ size = read(fd, &ehdr, sizeof(ehdr));
1155
+ lseek(fd, 0, SEEK_SET);
1156
+ if (size <= 0) {
1157
+ tcc_error_noabort("could not read header");
1158
+ goto the_end;
1159
+ }
1160
+
1161
+ if (size == sizeof(ehdr) &&
1162
+ ehdr.e_ident[0] == ELFMAG0 &&
1163
+ ehdr.e_ident[1] == ELFMAG1 &&
1164
+ ehdr.e_ident[2] == ELFMAG2 &&
1165
+ ehdr.e_ident[3] == ELFMAG3) {
1166
+
1167
+ /* do not display line number if error */
1168
+ file->line_num = 0;
1169
+ if (ehdr.e_type == ET_REL) {
1170
+ ret = tcc_load_object_file(s1, fd, 0);
1171
+ goto the_end;
1172
+
1173
+ }
1174
+ #ifndef TCC_TARGET_PE
1175
+ if (ehdr.e_type == ET_DYN) {
1176
+ if (s1->output_type == TCC_OUTPUT_MEMORY) {
1177
+ #ifdef TCC_IS_NATIVE
1178
+ void *h;
1179
+ h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
1180
+ if (h)
1181
+ #endif
1182
+ ret = 0;
1183
+ } else {
1184
+ ret = tcc_load_dll(s1, fd, filename,
1185
+ (flags & AFF_REFERENCED_DLL) != 0);
1186
+ }
1187
+ goto the_end;
1188
+ }
1189
+ #endif
1190
+ tcc_error_noabort("unrecognized ELF file");
1191
+ goto the_end;
1192
+ }
1193
+
1194
+ if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
1195
+ file->line_num = 0; /* do not display line number if error */
1196
+ ret = tcc_load_archive(s1, fd);
1197
+ goto the_end;
1198
+ }
1199
+
1200
+ #ifdef TCC_TARGET_COFF
1201
+ if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
1202
+ ret = tcc_load_coff(s1, fd);
1203
+ goto the_end;
1204
+ }
1205
+ #endif
1206
+
1207
+ #ifdef TCC_TARGET_PE
1208
+ ret = pe_load_file(s1, filename, fd);
1209
+ #else
1210
+ /* as GNU ld, consider it is an ld script if not recognized */
1211
+ ret = tcc_load_ldscript(s1);
1212
+ #endif
1213
+ if (ret < 0)
1214
+ tcc_error_noabort("unrecognized file type");
1215
+
1216
+ the_end:
1217
+ tcc_close();
1218
+ return ret;
1219
+ }
1220
+
1221
+ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
1222
+ {
1223
+ if (s->output_type == TCC_OUTPUT_PREPROCESS)
1224
+ return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS);
1225
+ else
1226
+ return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
1227
+ }
1228
+
1229
+ LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
1230
+ {
1231
+ tcc_split_path(s, (void ***)&s->library_paths, &s->nb_library_paths, pathname);
1232
+ return 0;
1233
+ }
1234
+
1235
+ static int tcc_add_library_internal(TCCState *s, const char *fmt,
1236
+ const char *filename, int flags, char **paths, int nb_paths)
1237
+ {
1238
+ char buf[1024];
1239
+ int i;
1240
+
1241
+ for(i = 0; i < nb_paths; i++) {
1242
+ snprintf(buf, sizeof(buf), fmt, paths[i], filename);
1243
+ if (tcc_add_file_internal(s, buf, flags) == 0)
1244
+ return 0;
1245
+ }
1246
+ return -1;
1247
+ }
1248
+
1249
+ /* find and load a dll. Return non zero if not found */
1250
+ /* XXX: add '-rpath' option support ? */
1251
+ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
1252
+ {
1253
+ return tcc_add_library_internal(s, "%s/%s", filename, flags,
1254
+ s->library_paths, s->nb_library_paths);
1255
+ }
1256
+
1257
+ ST_FUNC int tcc_add_crt(TCCState *s, const char *filename)
1258
+ {
1259
+ if (-1 == tcc_add_library_internal(s, "%s/%s",
1260
+ filename, 0, s->crt_paths, s->nb_crt_paths))
1261
+ tcc_error_noabort("file '%s' not found", filename);
1262
+ return 0;
1263
+ }
1264
+
1265
+ /* the library name is the same as the argument of the '-l' option */
1266
+ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
1267
+ {
1268
+ #ifdef TCC_TARGET_PE
1269
+ const char *libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };
1270
+ const char **pp = s->static_link ? libs + 4 : libs;
1271
+ #else
1272
+ const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
1273
+ const char **pp = s->static_link ? libs + 1 : libs;
1274
+ #endif
1275
+ while (*pp) {
1276
+ if (0 == tcc_add_library_internal(s, *pp,
1277
+ libraryname, 0, s->library_paths, s->nb_library_paths))
1278
+ return 0;
1279
+ ++pp;
1280
+ }
1281
+ return -1;
1282
+ }
1283
+
1284
+ LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val)
1285
+ {
1286
+ #ifdef TCC_TARGET_PE
1287
+ /* On x86_64 'val' might not be reachable with a 32bit offset.
1288
+ So it is handled here as if it were in a DLL. */
1289
+ pe_putimport(s, 0, name, (uintptr_t)val);
1290
+ #else
1291
+ /* XXX: Same problem on linux but currently "solved" elsewhere
1292
+ via the rather dirty 'runtime_plt_and_got' hack. */
1293
+ add_elf_sym(symtab_section, (uintptr_t)val, 0,
1294
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1295
+ SHN_ABS, name);
1296
+ #endif
1297
+ return 0;
1298
+ }
1299
+
1300
+ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
1301
+ {
1302
+ s->output_type = output_type;
1303
+
1304
+ if (!s->nostdinc) {
1305
+ /* default include paths */
1306
+ /* -isystem paths have already been handled */
1307
+ tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
1308
+ }
1309
+
1310
+ /* if bound checking, then add corresponding sections */
1311
+ #ifdef CONFIG_TCC_BCHECK
1312
+ if (s->do_bounds_check) {
1313
+ /* define symbol */
1314
+ tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
1315
+ /* create bounds sections */
1316
+ bounds_section = new_section(s, ".bounds",
1317
+ SHT_PROGBITS, SHF_ALLOC);
1318
+ lbounds_section = new_section(s, ".lbounds",
1319
+ SHT_PROGBITS, SHF_ALLOC);
1320
+ }
1321
+ #endif
1322
+
1323
+ if (s->char_is_unsigned) {
1324
+ tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
1325
+ }
1326
+
1327
+ /* add debug sections */
1328
+ if (s->do_debug) {
1329
+ /* stab symbols */
1330
+ stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
1331
+ stab_section->sh_entsize = sizeof(Stab_Sym);
1332
+ stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
1333
+ put_elf_str(stabstr_section, "");
1334
+ stab_section->link = stabstr_section;
1335
+ /* put first entry */
1336
+ put_stabs("", 0, 0, 0, 0);
1337
+ }
1338
+
1339
+ #ifdef TCC_TARGET_PE
1340
+ tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
1341
+ # ifdef _WIN32
1342
+ tcc_add_systemdir(s);
1343
+ # endif
1344
+ #else
1345
+ /* add libc crt1/crti objects */
1346
+ if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
1347
+ !s->nostdlib) {
1348
+ if (output_type != TCC_OUTPUT_DLL)
1349
+ tcc_add_crt(s, "crt1.o");
1350
+ tcc_add_crt(s, "crti.o");
1351
+ }
1352
+ #endif
1353
+ return 0;
1354
+ }
1355
+
1356
+ LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
1357
+ {
1358
+ tcc_free(s->tcc_lib_path);
1359
+ s->tcc_lib_path = tcc_strdup(path);
1360
+ }
1361
+
1362
+ #define WD_ALL 0x0001 /* warning is activated when using -Wall */
1363
+ #define FD_INVERT 0x0002 /* invert value before storing */
1364
+
1365
+ typedef struct FlagDef {
1366
+ uint16_t offset;
1367
+ uint16_t flags;
1368
+ const char *name;
1369
+ } FlagDef;
1370
+
1371
+ static const FlagDef warning_defs[] = {
1372
+ { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
1373
+ { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
1374
+ { offsetof(TCCState, warn_error), 0, "error" },
1375
+ { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
1376
+ "implicit-function-declaration" },
1377
+ };
1378
+
1379
+ ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
1380
+ const char *name, int value)
1381
+ {
1382
+ int i;
1383
+ const FlagDef *p;
1384
+ const char *r;
1385
+
1386
+ r = name;
1387
+ if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
1388
+ r += 3;
1389
+ value = !value;
1390
+ }
1391
+ for(i = 0, p = flags; i < nb_flags; i++, p++) {
1392
+ if (!strcmp(r, p->name))
1393
+ goto found;
1394
+ }
1395
+ return -1;
1396
+ found:
1397
+ if (p->flags & FD_INVERT)
1398
+ value = !value;
1399
+ *(int *)((uint8_t *)s + p->offset) = value;
1400
+ return 0;
1401
+ }
1402
+
1403
+ /* set/reset a warning */
1404
+ static int tcc_set_warning(TCCState *s, const char *warning_name, int value)
1405
+ {
1406
+ int i;
1407
+ const FlagDef *p;
1408
+
1409
+ if (!strcmp(warning_name, "all")) {
1410
+ for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
1411
+ if (p->flags & WD_ALL)
1412
+ *(int *)((uint8_t *)s + p->offset) = 1;
1413
+ }
1414
+ return 0;
1415
+ } else {
1416
+ return set_flag(s, warning_defs, countof(warning_defs),
1417
+ warning_name, value);
1418
+ }
1419
+ }
1420
+
1421
+ static const FlagDef flag_defs[] = {
1422
+ { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
1423
+ { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
1424
+ { offsetof(TCCState, nocommon), FD_INVERT, "common" },
1425
+ { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
1426
+ };
1427
+
1428
+ /* set/reset a flag */
1429
+ static int tcc_set_flag(TCCState *s, const char *flag_name, int value)
1430
+ {
1431
+ return set_flag(s, flag_defs, countof(flag_defs),
1432
+ flag_name, value);
1433
+ }
1434
+
1435
+
1436
+ static int strstart(const char *val, const char **str)
1437
+ {
1438
+ const char *p, *q;
1439
+ p = *str;
1440
+ q = val;
1441
+ while (*q) {
1442
+ if (*p != *q)
1443
+ return 0;
1444
+ p++;
1445
+ q++;
1446
+ }
1447
+ *str = p;
1448
+ return 1;
1449
+ }
1450
+
1451
+ /* Like strstart, but automatically takes into account that ld options can
1452
+ *
1453
+ * - start with double or single dash (e.g. '--soname' or '-soname')
1454
+ * - arguments can be given as separate or after '=' (e.g. '-Wl,-soname,x.so'
1455
+ * or '-Wl,-soname=x.so')
1456
+ *
1457
+ * you provide `val` always in 'option[=]' form (no leading -)
1458
+ */
1459
+ static int link_option(const char *str, const char *val, const char **ptr)
1460
+ {
1461
+ const char *p, *q;
1462
+
1463
+ /* there should be 1 or 2 dashes */
1464
+ if (*str++ != '-')
1465
+ return 0;
1466
+ if (*str == '-')
1467
+ str++;
1468
+
1469
+ /* then str & val should match (potentialy up to '=') */
1470
+ p = str;
1471
+ q = val;
1472
+
1473
+ while (*q != '\0' && *q != '=') {
1474
+ if (*p != *q)
1475
+ return 0;
1476
+ p++;
1477
+ q++;
1478
+ }
1479
+
1480
+ /* '=' near eos means ',' or '=' is ok */
1481
+ if (*q == '=') {
1482
+ if (*p != ',' && *p != '=')
1483
+ return 0;
1484
+ p++;
1485
+ q++;
1486
+ }
1487
+
1488
+ if (ptr)
1489
+ *ptr = p;
1490
+ return 1;
1491
+ }
1492
+
1493
+ static const char *skip_linker_arg(const char **str)
1494
+ {
1495
+ const char *s1 = *str;
1496
+ const char *s2 = strchr(s1, ',');
1497
+ *str = s2 ? s2++ : (s2 = s1 + strlen(s1));
1498
+ return s2;
1499
+ }
1500
+
1501
+ static char *copy_linker_arg(const char *p)
1502
+ {
1503
+ const char *q = p;
1504
+ skip_linker_arg(&q);
1505
+ return pstrncpy(tcc_malloc(q - p + 1), p, q - p);
1506
+ }
1507
+
1508
+ /* set linker options */
1509
+ static int tcc_set_linker(TCCState *s, const char *option)
1510
+ {
1511
+ while (option && *option) {
1512
+
1513
+ const char *p = option;
1514
+ char *end = NULL;
1515
+ int ignoring = 0;
1516
+
1517
+ if (link_option(option, "Bsymbolic", &p)) {
1518
+ s->symbolic = 1;
1519
+ } else if (link_option(option, "nostdlib", &p)) {
1520
+ s->nostdlib = 1;
1521
+ } else if (link_option(option, "fini=", &p)) {
1522
+ s->fini_symbol = copy_linker_arg(p);
1523
+ ignoring = 1;
1524
+ } else if (link_option(option, "image-base=", &p)
1525
+ || link_option(option, "Ttext=", &p)) {
1526
+ s->text_addr = strtoull(p, &end, 16);
1527
+ s->has_text_addr = 1;
1528
+ } else if (link_option(option, "init=", &p)) {
1529
+ s->init_symbol = copy_linker_arg(p);
1530
+ ignoring = 1;
1531
+ } else if (link_option(option, "oformat=", &p)) {
1532
+ #if defined(TCC_TARGET_PE)
1533
+ if (strstart("pe-", &p)) {
1534
+ #elif defined(TCC_TARGET_X86_64)
1535
+ if (strstart("elf64-", &p)) {
1536
+ #else
1537
+ if (strstart("elf32-", &p)) {
1538
+ #endif
1539
+ s->output_format = TCC_OUTPUT_FORMAT_ELF;
1540
+ } else if (!strcmp(p, "binary")) {
1541
+ s->output_format = TCC_OUTPUT_FORMAT_BINARY;
1542
+ #ifdef TCC_TARGET_COFF
1543
+ } else if (!strcmp(p, "coff")) {
1544
+ s->output_format = TCC_OUTPUT_FORMAT_COFF;
1545
+ #endif
1546
+ } else
1547
+ goto err;
1548
+
1549
+ } else if (link_option(option, "rpath=", &p)) {
1550
+ s->rpath = copy_linker_arg(p);
1551
+ } else if (link_option(option, "section-alignment=", &p)) {
1552
+ s->section_align = strtoul(p, &end, 16);
1553
+ } else if (link_option(option, "soname=", &p)) {
1554
+ s->soname = copy_linker_arg(p);
1555
+ #ifdef TCC_TARGET_PE
1556
+ } else if (link_option(option, "file-alignment=", &p)) {
1557
+ s->pe_file_align = strtoul(p, &end, 16);
1558
+ } else if (link_option(option, "stack=", &p)) {
1559
+ s->pe_stack_size = strtoul(p, &end, 10);
1560
+ } else if (link_option(option, "subsystem=", &p)) {
1561
+ #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1562
+ if (!strcmp(p, "native")) {
1563
+ s->pe_subsystem = 1;
1564
+ } else if (!strcmp(p, "console")) {
1565
+ s->pe_subsystem = 3;
1566
+ } else if (!strcmp(p, "gui")) {
1567
+ s->pe_subsystem = 2;
1568
+ } else if (!strcmp(p, "posix")) {
1569
+ s->pe_subsystem = 7;
1570
+ } else if (!strcmp(p, "efiapp")) {
1571
+ s->pe_subsystem = 10;
1572
+ } else if (!strcmp(p, "efiboot")) {
1573
+ s->pe_subsystem = 11;
1574
+ } else if (!strcmp(p, "efiruntime")) {
1575
+ s->pe_subsystem = 12;
1576
+ } else if (!strcmp(p, "efirom")) {
1577
+ s->pe_subsystem = 13;
1578
+ #elif defined(TCC_TARGET_ARM)
1579
+ if (!strcmp(p, "wince")) {
1580
+ s->pe_subsystem = 9;
1581
+ #endif
1582
+ } else
1583
+ goto err;
1584
+ #endif
1585
+ } else
1586
+ goto err;
1587
+
1588
+ if (ignoring && s->warn_unsupported) err: {
1589
+ char buf[100], *e;
1590
+ pstrcpy(buf, sizeof buf, e = copy_linker_arg(option)), tcc_free(e);
1591
+ if (ignoring)
1592
+ tcc_warning("unsupported linker option '%s'", buf);
1593
+ else
1594
+ tcc_error("unsupported linker option '%s'", buf);
1595
+ }
1596
+ option = skip_linker_arg(&p);
1597
+ }
1598
+ return 0;
1599
+ }
1600
+
1601
+ typedef struct TCCOption {
1602
+ const char *name;
1603
+ uint16_t index;
1604
+ uint16_t flags;
1605
+ } TCCOption;
1606
+
1607
+ enum {
1608
+ TCC_OPTION_HELP,
1609
+ TCC_OPTION_I,
1610
+ TCC_OPTION_D,
1611
+ TCC_OPTION_U,
1612
+ TCC_OPTION_L,
1613
+ TCC_OPTION_B,
1614
+ TCC_OPTION_l,
1615
+ TCC_OPTION_bench,
1616
+ TCC_OPTION_bt,
1617
+ TCC_OPTION_b,
1618
+ TCC_OPTION_g,
1619
+ TCC_OPTION_c,
1620
+ TCC_OPTION_static,
1621
+ TCC_OPTION_shared,
1622
+ TCC_OPTION_soname,
1623
+ TCC_OPTION_o,
1624
+ TCC_OPTION_r,
1625
+ TCC_OPTION_s,
1626
+ TCC_OPTION_Wl,
1627
+ TCC_OPTION_W,
1628
+ TCC_OPTION_O,
1629
+ TCC_OPTION_m,
1630
+ TCC_OPTION_f,
1631
+ TCC_OPTION_isystem,
1632
+ TCC_OPTION_nostdinc,
1633
+ TCC_OPTION_nostdlib,
1634
+ TCC_OPTION_print_search_dirs,
1635
+ TCC_OPTION_rdynamic,
1636
+ TCC_OPTION_pedantic,
1637
+ TCC_OPTION_pthread,
1638
+ TCC_OPTION_run,
1639
+ TCC_OPTION_v,
1640
+ TCC_OPTION_w,
1641
+ TCC_OPTION_pipe,
1642
+ TCC_OPTION_E,
1643
+ TCC_OPTION_MD,
1644
+ TCC_OPTION_MF,
1645
+ TCC_OPTION_x,
1646
+ TCC_OPTION_dumpversion,
1647
+ };
1648
+
1649
+ #define TCC_OPTION_HAS_ARG 0x0001
1650
+ #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
1651
+
1652
+ static const TCCOption tcc_options[] = {
1653
+ { "h", TCC_OPTION_HELP, 0 },
1654
+ { "-help", TCC_OPTION_HELP, 0 },
1655
+ { "?", TCC_OPTION_HELP, 0 },
1656
+ { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
1657
+ { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
1658
+ { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
1659
+ { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
1660
+ { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
1661
+ { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1662
+ { "bench", TCC_OPTION_bench, 0 },
1663
+ #ifdef CONFIG_TCC_BACKTRACE
1664
+ { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
1665
+ #endif
1666
+ #ifdef CONFIG_TCC_BCHECK
1667
+ { "b", TCC_OPTION_b, 0 },
1668
+ #endif
1669
+ { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1670
+ { "c", TCC_OPTION_c, 0 },
1671
+ { "static", TCC_OPTION_static, 0 },
1672
+ { "shared", TCC_OPTION_shared, 0 },
1673
+ { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG },
1674
+ { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
1675
+ { "pedantic", TCC_OPTION_pedantic, 0},
1676
+ { "pthread", TCC_OPTION_pthread, 0},
1677
+ { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1678
+ { "rdynamic", TCC_OPTION_rdynamic, 0 },
1679
+ { "r", TCC_OPTION_r, 0 },
1680
+ { "s", TCC_OPTION_s, 0 },
1681
+ { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1682
+ { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1683
+ { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1684
+ { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
1685
+ { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1686
+ { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
1687
+ { "nostdinc", TCC_OPTION_nostdinc, 0 },
1688
+ { "nostdlib", TCC_OPTION_nostdlib, 0 },
1689
+ { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
1690
+ { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1691
+ { "w", TCC_OPTION_w, 0 },
1692
+ { "pipe", TCC_OPTION_pipe, 0},
1693
+ { "E", TCC_OPTION_E, 0},
1694
+ { "MD", TCC_OPTION_MD, 0},
1695
+ { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
1696
+ { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
1697
+ { "dumpversion", TCC_OPTION_dumpversion, 0},
1698
+ { NULL, 0, 0 },
1699
+ };
1700
+
1701
+ static void parse_option_D(TCCState *s1, const char *optarg)
1702
+ {
1703
+ char *sym = tcc_strdup(optarg);
1704
+ char *value = strchr(sym, '=');
1705
+ if (value)
1706
+ *value++ = '\0';
1707
+ tcc_define_symbol(s1, sym, value);
1708
+ tcc_free(sym);
1709
+ }
1710
+
1711
+ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
1712
+ {
1713
+ const TCCOption *popt;
1714
+ const char *optarg, *r;
1715
+ int run = 0;
1716
+ int pthread = 0;
1717
+ int optind = 0;
1718
+
1719
+ /* collect -Wl options for input such as "-Wl,-rpath -Wl,<path>" */
1720
+ CString linker_arg;
1721
+ cstr_new(&linker_arg);
1722
+
1723
+ while (optind < argc) {
1724
+
1725
+ r = argv[optind++];
1726
+ if (r[0] != '-' || r[1] == '\0') {
1727
+ /* add a new file */
1728
+ dynarray_add((void ***)&s->files, &s->nb_files, tcc_strdup(r));
1729
+ if (run) {
1730
+ optind--;
1731
+ /* argv[0] will be this file */
1732
+ break;
1733
+ }
1734
+ continue;
1735
+ }
1736
+
1737
+ /* find option in table */
1738
+ for(popt = tcc_options; ; ++popt) {
1739
+ const char *p1 = popt->name;
1740
+ const char *r1 = r + 1;
1741
+ if (p1 == NULL)
1742
+ tcc_error("invalid option -- '%s'", r);
1743
+ if (!strstart(p1, &r1))
1744
+ continue;
1745
+ optarg = r1;
1746
+ if (popt->flags & TCC_OPTION_HAS_ARG) {
1747
+ if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
1748
+ if (optind >= argc)
1749
+ tcc_error("argument to '%s' is missing", r);
1750
+ optarg = argv[optind++];
1751
+ }
1752
+ } else if (*r1 != '\0')
1753
+ continue;
1754
+ break;
1755
+ }
1756
+
1757
+ switch(popt->index) {
1758
+ case TCC_OPTION_HELP:
1759
+ return 0;
1760
+ case TCC_OPTION_I:
1761
+ if (tcc_add_include_path(s, optarg) < 0)
1762
+ tcc_error("too many include paths");
1763
+ break;
1764
+ case TCC_OPTION_D:
1765
+ parse_option_D(s, optarg);
1766
+ break;
1767
+ case TCC_OPTION_U:
1768
+ tcc_undefine_symbol(s, optarg);
1769
+ break;
1770
+ case TCC_OPTION_L:
1771
+ tcc_add_library_path(s, optarg);
1772
+ break;
1773
+ case TCC_OPTION_B:
1774
+ /* set tcc utilities path (mainly for tcc development) */
1775
+ tcc_set_lib_path(s, optarg);
1776
+ break;
1777
+ case TCC_OPTION_l:
1778
+ dynarray_add((void ***)&s->files, &s->nb_files, tcc_strdup(r));
1779
+ s->nb_libraries++;
1780
+ break;
1781
+ case TCC_OPTION_pthread:
1782
+ parse_option_D(s, "_REENTRANT");
1783
+ pthread = 1;
1784
+ break;
1785
+ case TCC_OPTION_bench:
1786
+ s->do_bench = 1;
1787
+ break;
1788
+ #ifdef CONFIG_TCC_BACKTRACE
1789
+ case TCC_OPTION_bt:
1790
+ tcc_set_num_callers(atoi(optarg));
1791
+ break;
1792
+ #endif
1793
+ #ifdef CONFIG_TCC_BCHECK
1794
+ case TCC_OPTION_b:
1795
+ s->do_bounds_check = 1;
1796
+ s->do_debug = 1;
1797
+ break;
1798
+ #endif
1799
+ case TCC_OPTION_g:
1800
+ s->do_debug = 1;
1801
+ break;
1802
+ case TCC_OPTION_c:
1803
+ s->output_type = TCC_OUTPUT_OBJ;
1804
+ break;
1805
+ case TCC_OPTION_static:
1806
+ s->static_link = 1;
1807
+ break;
1808
+ case TCC_OPTION_shared:
1809
+ s->output_type = TCC_OUTPUT_DLL;
1810
+ break;
1811
+ case TCC_OPTION_soname:
1812
+ s->soname = tcc_strdup(optarg);
1813
+ break;
1814
+ case TCC_OPTION_m:
1815
+ s->option_m = tcc_strdup(optarg);
1816
+ break;
1817
+ case TCC_OPTION_o:
1818
+ s->outfile = tcc_strdup(optarg);
1819
+ break;
1820
+ case TCC_OPTION_r:
1821
+ /* generate a .o merging several output files */
1822
+ s->option_r = 1;
1823
+ s->output_type = TCC_OUTPUT_OBJ;
1824
+ break;
1825
+ case TCC_OPTION_isystem:
1826
+ tcc_add_sysinclude_path(s, optarg);
1827
+ break;
1828
+ case TCC_OPTION_nostdinc:
1829
+ s->nostdinc = 1;
1830
+ break;
1831
+ case TCC_OPTION_nostdlib:
1832
+ s->nostdlib = 1;
1833
+ break;
1834
+ case TCC_OPTION_print_search_dirs:
1835
+ s->print_search_dirs = 1;
1836
+ break;
1837
+ case TCC_OPTION_run:
1838
+ s->output_type = TCC_OUTPUT_MEMORY;
1839
+ tcc_set_options(s, optarg);
1840
+ run = 1;
1841
+ break;
1842
+ case TCC_OPTION_v:
1843
+ do ++s->verbose; while (*optarg++ == 'v');
1844
+ break;
1845
+ case TCC_OPTION_f:
1846
+ if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported)
1847
+ goto unsupported_option;
1848
+ break;
1849
+ case TCC_OPTION_W:
1850
+ if (tcc_set_warning(s, optarg, 1) < 0 &&
1851
+ s->warn_unsupported)
1852
+ goto unsupported_option;
1853
+ break;
1854
+ case TCC_OPTION_w:
1855
+ s->warn_none = 1;
1856
+ break;
1857
+ case TCC_OPTION_rdynamic:
1858
+ s->rdynamic = 1;
1859
+ break;
1860
+ case TCC_OPTION_Wl:
1861
+ if (linker_arg.size)
1862
+ --linker_arg.size, cstr_ccat(&linker_arg, ',');
1863
+ cstr_cat(&linker_arg, optarg);
1864
+ cstr_ccat(&linker_arg, '\0');
1865
+ break;
1866
+ case TCC_OPTION_E:
1867
+ s->output_type = TCC_OUTPUT_PREPROCESS;
1868
+ break;
1869
+ case TCC_OPTION_MD:
1870
+ s->gen_deps = 1;
1871
+ break;
1872
+ case TCC_OPTION_MF:
1873
+ s->deps_outfile = tcc_strdup(optarg);
1874
+ break;
1875
+ case TCC_OPTION_dumpversion:
1876
+ printf ("%s\n", TCC_VERSION);
1877
+ exit(0);
1878
+ case TCC_OPTION_O:
1879
+ case TCC_OPTION_pedantic:
1880
+ case TCC_OPTION_pipe:
1881
+ case TCC_OPTION_s:
1882
+ case TCC_OPTION_x:
1883
+ /* ignored */
1884
+ break;
1885
+ default:
1886
+ if (s->warn_unsupported) {
1887
+ unsupported_option:
1888
+ tcc_warning("unsupported option '%s'", r);
1889
+ }
1890
+ break;
1891
+ }
1892
+ }
1893
+
1894
+ if (pthread && s->output_type != TCC_OUTPUT_OBJ)
1895
+ tcc_set_options(s, "-lpthread");
1896
+
1897
+ tcc_set_linker(s, (const char *)linker_arg.data);
1898
+ cstr_free(&linker_arg);
1899
+
1900
+ return optind;
1901
+ }
1902
+
1903
+ LIBTCCAPI int tcc_set_options(TCCState *s, const char *str)
1904
+ {
1905
+ const char *s1;
1906
+ char **argv, *arg;
1907
+ int argc, len;
1908
+ int ret;
1909
+
1910
+ argc = 0, argv = NULL;
1911
+ for(;;) {
1912
+ while (is_space(*str))
1913
+ str++;
1914
+ if (*str == '\0')
1915
+ break;
1916
+ s1 = str;
1917
+ while (*str != '\0' && !is_space(*str))
1918
+ str++;
1919
+ len = str - s1;
1920
+ arg = tcc_malloc(len + 1);
1921
+ pstrncpy(arg, s1, len);
1922
+ dynarray_add((void ***)&argv, &argc, arg);
1923
+ }
1924
+ ret = tcc_parse_args(s, argc, argv);
1925
+ dynarray_reset(&argv, &argc);
1926
+ return ret;
1927
+ }
1928
+
1929
+ PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time)
1930
+ {
1931
+ double tt;
1932
+ tt = (double)total_time / 1000000.0;
1933
+ if (tt < 0.001)
1934
+ tt = 0.001;
1935
+ if (total_bytes < 1)
1936
+ total_bytes = 1;
1937
+ printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
1938
+ tok_ident - TOK_IDENT, total_lines, total_bytes,
1939
+ tt, (int)(total_lines / tt),
1940
+ total_bytes / tt / 1000000.0);
1941
+ }