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,1887 @@
1
+ /*
2
+ * TCCPE.C - PE file output for the Tiny C Compiler
3
+ *
4
+ * Copyright (c) 2005-2007 grischka
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
+ #ifndef _WIN32
24
+ #define stricmp strcasecmp
25
+ #define strnicmp strncasecmp
26
+ #endif
27
+
28
+ #ifndef MAX_PATH
29
+ #define MAX_PATH 260
30
+ #endif
31
+
32
+ #define PE_MERGE_DATA
33
+ // #define PE_PRINT_SECTIONS
34
+
35
+ #ifdef TCC_TARGET_X86_64
36
+ # define ADDR3264 ULONGLONG
37
+ #else
38
+ # define ADDR3264 DWORD
39
+ #endif
40
+
41
+ #ifdef _WIN32
42
+ void dbg_printf (const char *fmt, ...)
43
+ {
44
+ char buffer[4000];
45
+ va_list arg;
46
+ int x;
47
+ va_start(arg, fmt);
48
+ x = vsprintf (buffer, fmt, arg);
49
+ strcpy(buffer+x, "\n");
50
+ OutputDebugString(buffer);
51
+ }
52
+ #endif
53
+
54
+ /* ----------------------------------------------------------- */
55
+ #ifndef IMAGE_NT_SIGNATURE
56
+ /* ----------------------------------------------------------- */
57
+ /* definitions below are from winnt.h */
58
+
59
+ typedef unsigned char BYTE;
60
+ typedef unsigned short WORD;
61
+ typedef unsigned int DWORD;
62
+ typedef unsigned long long ULONGLONG;
63
+ #pragma pack(push, 1)
64
+
65
+ typedef struct _IMAGE_DOS_HEADER { /* DOS .EXE header */
66
+ WORD e_magic; /* Magic number */
67
+ WORD e_cblp; /* Bytes on last page of file */
68
+ WORD e_cp; /* Pages in file */
69
+ WORD e_crlc; /* Relocations */
70
+ WORD e_cparhdr; /* Size of header in paragraphs */
71
+ WORD e_minalloc; /* Minimum extra paragraphs needed */
72
+ WORD e_maxalloc; /* Maximum extra paragraphs needed */
73
+ WORD e_ss; /* Initial (relative) SS value */
74
+ WORD e_sp; /* Initial SP value */
75
+ WORD e_csum; /* Checksum */
76
+ WORD e_ip; /* Initial IP value */
77
+ WORD e_cs; /* Initial (relative) CS value */
78
+ WORD e_lfarlc; /* File address of relocation table */
79
+ WORD e_ovno; /* Overlay number */
80
+ WORD e_res[4]; /* Reserved words */
81
+ WORD e_oemid; /* OEM identifier (for e_oeminfo) */
82
+ WORD e_oeminfo; /* OEM information; e_oemid specific */
83
+ WORD e_res2[10]; /* Reserved words */
84
+ DWORD e_lfanew; /* File address of new exe header */
85
+ } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
86
+
87
+ #define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
88
+ #define SIZE_OF_NT_SIGNATURE 4
89
+
90
+ typedef struct _IMAGE_FILE_HEADER {
91
+ WORD Machine;
92
+ WORD NumberOfSections;
93
+ DWORD TimeDateStamp;
94
+ DWORD PointerToSymbolTable;
95
+ DWORD NumberOfSymbols;
96
+ WORD SizeOfOptionalHeader;
97
+ WORD Characteristics;
98
+ } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
99
+
100
+
101
+ #define IMAGE_SIZEOF_FILE_HEADER 20
102
+
103
+ typedef struct _IMAGE_DATA_DIRECTORY {
104
+ DWORD VirtualAddress;
105
+ DWORD Size;
106
+ } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
107
+
108
+
109
+ typedef struct _IMAGE_OPTIONAL_HEADER {
110
+ /* Standard fields. */
111
+ WORD Magic;
112
+ BYTE MajorLinkerVersion;
113
+ BYTE MinorLinkerVersion;
114
+ DWORD SizeOfCode;
115
+ DWORD SizeOfInitializedData;
116
+ DWORD SizeOfUninitializedData;
117
+ DWORD AddressOfEntryPoint;
118
+ DWORD BaseOfCode;
119
+ #ifndef TCC_TARGET_X86_64
120
+ DWORD BaseOfData;
121
+ #endif
122
+ /* NT additional fields. */
123
+ ADDR3264 ImageBase;
124
+ DWORD SectionAlignment;
125
+ DWORD FileAlignment;
126
+ WORD MajorOperatingSystemVersion;
127
+ WORD MinorOperatingSystemVersion;
128
+ WORD MajorImageVersion;
129
+ WORD MinorImageVersion;
130
+ WORD MajorSubsystemVersion;
131
+ WORD MinorSubsystemVersion;
132
+ DWORD Win32VersionValue;
133
+ DWORD SizeOfImage;
134
+ DWORD SizeOfHeaders;
135
+ DWORD CheckSum;
136
+ WORD Subsystem;
137
+ WORD DllCharacteristics;
138
+ ADDR3264 SizeOfStackReserve;
139
+ ADDR3264 SizeOfStackCommit;
140
+ ADDR3264 SizeOfHeapReserve;
141
+ ADDR3264 SizeOfHeapCommit;
142
+ DWORD LoaderFlags;
143
+ DWORD NumberOfRvaAndSizes;
144
+ IMAGE_DATA_DIRECTORY DataDirectory[16];
145
+ } IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, IMAGE_OPTIONAL_HEADER;
146
+
147
+ #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 /* Export Directory */
148
+ #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 /* Import Directory */
149
+ #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 /* Resource Directory */
150
+ #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 /* Exception Directory */
151
+ #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 /* Security Directory */
152
+ #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 /* Base Relocation Table */
153
+ #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 /* Debug Directory */
154
+ /* IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 (X86 usage) */
155
+ #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 /* Architecture Specific Data */
156
+ #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* RVA of GP */
157
+ #define IMAGE_DIRECTORY_ENTRY_TLS 9 /* TLS Directory */
158
+ #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 /* Load Configuration Directory */
159
+ #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 /* Bound Import Directory in headers */
160
+ #define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */
161
+ #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 /* Delay Load Import Descriptors */
162
+ #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 /* COM Runtime descriptor */
163
+
164
+ /* Section header format. */
165
+ #define IMAGE_SIZEOF_SHORT_NAME 8
166
+
167
+ typedef struct _IMAGE_SECTION_HEADER {
168
+ BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
169
+ union {
170
+ DWORD PhysicalAddress;
171
+ DWORD VirtualSize;
172
+ } Misc;
173
+ DWORD VirtualAddress;
174
+ DWORD SizeOfRawData;
175
+ DWORD PointerToRawData;
176
+ DWORD PointerToRelocations;
177
+ DWORD PointerToLinenumbers;
178
+ WORD NumberOfRelocations;
179
+ WORD NumberOfLinenumbers;
180
+ DWORD Characteristics;
181
+ } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
182
+
183
+ #define IMAGE_SIZEOF_SECTION_HEADER 40
184
+
185
+ typedef struct _IMAGE_EXPORT_DIRECTORY {
186
+ DWORD Characteristics;
187
+ DWORD TimeDateStamp;
188
+ WORD MajorVersion;
189
+ WORD MinorVersion;
190
+ DWORD Name;
191
+ DWORD Base;
192
+ DWORD NumberOfFunctions;
193
+ DWORD NumberOfNames;
194
+ DWORD AddressOfFunctions;
195
+ DWORD AddressOfNames;
196
+ DWORD AddressOfNameOrdinals;
197
+ } IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
198
+
199
+ typedef struct _IMAGE_IMPORT_DESCRIPTOR {
200
+ union {
201
+ DWORD Characteristics;
202
+ DWORD OriginalFirstThunk;
203
+ };
204
+ DWORD TimeDateStamp;
205
+ DWORD ForwarderChain;
206
+ DWORD Name;
207
+ DWORD FirstThunk;
208
+ } IMAGE_IMPORT_DESCRIPTOR;
209
+
210
+ typedef struct _IMAGE_BASE_RELOCATION {
211
+ DWORD VirtualAddress;
212
+ DWORD SizeOfBlock;
213
+ // WORD TypeOffset[1];
214
+ } IMAGE_BASE_RELOCATION;
215
+
216
+ #define IMAGE_SIZEOF_BASE_RELOCATION 8
217
+
218
+ #define IMAGE_REL_BASED_ABSOLUTE 0
219
+ #define IMAGE_REL_BASED_HIGH 1
220
+ #define IMAGE_REL_BASED_LOW 2
221
+ #define IMAGE_REL_BASED_HIGHLOW 3
222
+ #define IMAGE_REL_BASED_HIGHADJ 4
223
+ #define IMAGE_REL_BASED_MIPS_JMPADDR 5
224
+ #define IMAGE_REL_BASED_SECTION 6
225
+ #define IMAGE_REL_BASED_REL32 7
226
+
227
+ #pragma pack(pop)
228
+
229
+ /* ----------------------------------------------------------- */
230
+ #endif /* ndef IMAGE_NT_SIGNATURE */
231
+ /* ----------------------------------------------------------- */
232
+ #pragma pack(push, 1)
233
+
234
+ struct pe_header
235
+ {
236
+ IMAGE_DOS_HEADER doshdr;
237
+ BYTE dosstub[0x40];
238
+ DWORD nt_sig;
239
+ IMAGE_FILE_HEADER filehdr;
240
+ #ifdef TCC_TARGET_X86_64
241
+ IMAGE_OPTIONAL_HEADER64 opthdr;
242
+ #else
243
+ #ifdef _WIN64
244
+ IMAGE_OPTIONAL_HEADER32 opthdr;
245
+ #else
246
+ IMAGE_OPTIONAL_HEADER opthdr;
247
+ #endif
248
+ #endif
249
+ };
250
+
251
+ struct pe_reloc_header {
252
+ DWORD offset;
253
+ DWORD size;
254
+ };
255
+
256
+ struct pe_rsrc_header {
257
+ struct _IMAGE_FILE_HEADER filehdr;
258
+ struct _IMAGE_SECTION_HEADER sectionhdr;
259
+ };
260
+
261
+ struct pe_rsrc_reloc {
262
+ DWORD offset;
263
+ DWORD size;
264
+ WORD type;
265
+ };
266
+
267
+ #pragma pack(pop)
268
+
269
+ /* ------------------------------------------------------------- */
270
+ /* internal temporary structures */
271
+
272
+ /*
273
+ #define IMAGE_SCN_CNT_CODE 0x00000020
274
+ #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
275
+ #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
276
+ #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
277
+ #define IMAGE_SCN_MEM_SHARED 0x10000000
278
+ #define IMAGE_SCN_MEM_EXECUTE 0x20000000
279
+ #define IMAGE_SCN_MEM_READ 0x40000000
280
+ #define IMAGE_SCN_MEM_WRITE 0x80000000
281
+ */
282
+
283
+ enum {
284
+ sec_text = 0,
285
+ sec_data ,
286
+ sec_bss ,
287
+ sec_idata ,
288
+ sec_pdata ,
289
+ sec_other ,
290
+ sec_rsrc ,
291
+ sec_stab ,
292
+ sec_reloc ,
293
+ sec_last
294
+ };
295
+
296
+ static const DWORD pe_sec_flags[] = {
297
+ 0x60000020, /* ".text" , */
298
+ 0xC0000040, /* ".data" , */
299
+ 0xC0000080, /* ".bss" , */
300
+ 0x40000040, /* ".idata" , */
301
+ 0x40000040, /* ".pdata" , */
302
+ 0xE0000060, /* < other > , */
303
+ 0x40000040, /* ".rsrc" , */
304
+ 0x42000802, /* ".stab" , */
305
+ 0x42000040, /* ".reloc" , */
306
+ };
307
+
308
+ struct section_info {
309
+ int cls, ord;
310
+ char name[32];
311
+ DWORD sh_addr;
312
+ DWORD sh_size;
313
+ DWORD sh_flags;
314
+ unsigned char *data;
315
+ DWORD data_size;
316
+ IMAGE_SECTION_HEADER ish;
317
+ };
318
+
319
+ struct import_symbol {
320
+ int sym_index;
321
+ int iat_index;
322
+ int thk_offset;
323
+ };
324
+
325
+ struct pe_import_info {
326
+ int dll_index;
327
+ int sym_count;
328
+ struct import_symbol **symbols;
329
+ };
330
+
331
+ struct pe_info {
332
+ TCCState *s1;
333
+ Section *reloc;
334
+ Section *thunk;
335
+ const char *filename;
336
+ int type;
337
+ DWORD sizeofheaders;
338
+ ADDR3264 imagebase;
339
+ DWORD start_addr;
340
+ DWORD imp_offs;
341
+ DWORD imp_size;
342
+ DWORD iat_offs;
343
+ DWORD iat_size;
344
+ DWORD exp_offs;
345
+ DWORD exp_size;
346
+ int subsystem;
347
+ DWORD section_align;
348
+ DWORD file_align;
349
+ struct section_info *sec_info;
350
+ int sec_count;
351
+ struct pe_import_info **imp_info;
352
+ int imp_count;
353
+ };
354
+
355
+ #define PE_NUL 0
356
+ #define PE_DLL 1
357
+ #define PE_GUI 2
358
+ #define PE_EXE 3
359
+ #define PE_RUN 4
360
+
361
+ /* --------------------------------------------*/
362
+
363
+ static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym)
364
+ {
365
+ const char *name = symtab_section->link->data + sym->st_name;
366
+ if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & 2))
367
+ return name + 1;
368
+ return name;
369
+ }
370
+
371
+ static int pe_find_import(TCCState * s1, ElfW(Sym) *sym)
372
+ {
373
+ char buffer[200];
374
+ const char *s, *p;
375
+ int sym_index = 0, n = 0;
376
+
377
+ do {
378
+ s = pe_export_name(s1, sym);
379
+ if (n) {
380
+ /* second try: */
381
+ if (sym->st_other & 2) {
382
+ /* try w/0 stdcall deco (windows API convention) */
383
+ p = strrchr(s, '@');
384
+ if (!p || s[0] != '_')
385
+ break;
386
+ strcpy(buffer, s+1)[p-s-1] = 0;
387
+ } else if (s[0] != '_') { /* try non-ansi function */
388
+ buffer[0] = '_', strcpy(buffer + 1, s);
389
+ } else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
390
+ strcpy(buffer, s + 6);
391
+ } else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
392
+ strcpy(buffer, s + 6);
393
+ } else {
394
+ break;
395
+ }
396
+ s = buffer;
397
+ }
398
+ sym_index = find_elf_sym(s1->dynsymtab_section, s);
399
+ // printf("find (%d) %d %s\n", n, sym_index, s);
400
+ } while (0 == sym_index && ++n < 2);
401
+ return sym_index;
402
+ }
403
+
404
+ /*----------------------------------------------------------------------------*/
405
+
406
+ static int dynarray_assoc(void **pp, int n, int key)
407
+ {
408
+ int i;
409
+ for (i = 0; i < n; ++i, ++pp)
410
+ if (key == **(int **) pp)
411
+ return i;
412
+ return -1;
413
+ }
414
+
415
+ #if 0
416
+ ST_FN DWORD umin(DWORD a, DWORD b)
417
+ {
418
+ return a < b ? a : b;
419
+ }
420
+ #endif
421
+
422
+ static DWORD umax(DWORD a, DWORD b)
423
+ {
424
+ return a < b ? b : a;
425
+ }
426
+
427
+ static DWORD pe_file_align(struct pe_info *pe, DWORD n)
428
+ {
429
+ return (n + (pe->file_align - 1)) & ~(pe->file_align - 1);
430
+ }
431
+
432
+ static DWORD pe_virtual_align(struct pe_info *pe, DWORD n)
433
+ {
434
+ return (n + (pe->section_align - 1)) & ~(pe->section_align - 1);
435
+ }
436
+
437
+ static void pe_align_section(Section *s, int a)
438
+ {
439
+ int i = s->data_offset & (a-1);
440
+ if (i)
441
+ section_ptr_add(s, a - i);
442
+ }
443
+
444
+ static void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size)
445
+ {
446
+ hdr->opthdr.DataDirectory[dir].VirtualAddress = addr;
447
+ hdr->opthdr.DataDirectory[dir].Size = size;
448
+ }
449
+
450
+ static int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)
451
+ {
452
+ if (psum) {
453
+ DWORD sum = *psum;
454
+ WORD *p = data;
455
+ int i;
456
+ for (i = len; i > 0; i -= 2) {
457
+ sum += (i >= 2) ? *p++ : *(BYTE*)p;
458
+ sum = (sum + (sum >> 16)) & 0xFFFF;
459
+ }
460
+ *psum = sum;
461
+ }
462
+ return len == fwrite(data, 1, len, fp) ? 0 : -1;
463
+ }
464
+
465
+ static void pe_fpad(FILE *fp, DWORD new_pos)
466
+ {
467
+ DWORD pos = ftell(fp);
468
+ while (++pos <= new_pos)
469
+ fputc(0, fp);
470
+ }
471
+
472
+ /*----------------------------------------------------------------------------*/
473
+ static int pe_write(struct pe_info *pe)
474
+ {
475
+ static const struct pe_header pe_template = {
476
+ {
477
+ /* IMAGE_DOS_HEADER doshdr */
478
+ 0x5A4D, /*WORD e_magic; Magic number */
479
+ 0x0090, /*WORD e_cblp; Bytes on last page of file */
480
+ 0x0003, /*WORD e_cp; Pages in file */
481
+ 0x0000, /*WORD e_crlc; Relocations */
482
+
483
+ 0x0004, /*WORD e_cparhdr; Size of header in paragraphs */
484
+ 0x0000, /*WORD e_minalloc; Minimum extra paragraphs needed */
485
+ 0xFFFF, /*WORD e_maxalloc; Maximum extra paragraphs needed */
486
+ 0x0000, /*WORD e_ss; Initial (relative) SS value */
487
+
488
+ 0x00B8, /*WORD e_sp; Initial SP value */
489
+ 0x0000, /*WORD e_csum; Checksum */
490
+ 0x0000, /*WORD e_ip; Initial IP value */
491
+ 0x0000, /*WORD e_cs; Initial (relative) CS value */
492
+ 0x0040, /*WORD e_lfarlc; File address of relocation table */
493
+ 0x0000, /*WORD e_ovno; Overlay number */
494
+ {0,0,0,0}, /*WORD e_res[4]; Reserved words */
495
+ 0x0000, /*WORD e_oemid; OEM identifier (for e_oeminfo) */
496
+ 0x0000, /*WORD e_oeminfo; OEM information; e_oemid specific */
497
+ {0,0,0,0,0,0,0,0,0,0}, /*WORD e_res2[10]; Reserved words */
498
+ 0x00000080 /*DWORD e_lfanew; File address of new exe header */
499
+ },{
500
+ /* BYTE dosstub[0x40] */
501
+ /* 14 code bytes + "This program cannot be run in DOS mode.\r\r\n$" + 6 * 0x00 */
502
+ 0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68,
503
+ 0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f,
504
+ 0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20,
505
+ 0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0d,0x0a,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
506
+ },
507
+ 0x00004550, /* DWORD nt_sig = IMAGE_NT_SIGNATURE */
508
+ {
509
+ /* IMAGE_FILE_HEADER filehdr */
510
+ #if defined(TCC_TARGET_I386)
511
+ 0x014C, /*WORD Machine; */
512
+ #elif defined(TCC_TARGET_X86_64)
513
+ 0x8664, /*WORD Machine; */
514
+ #elif defined(TCC_TARGET_ARM)
515
+ 0x01C0, /*WORD Machine; */
516
+ #endif
517
+ 0x0003, /*WORD NumberOfSections; */
518
+ 0x00000000, /*DWORD TimeDateStamp; */
519
+ 0x00000000, /*DWORD PointerToSymbolTable; */
520
+ 0x00000000, /*DWORD NumberOfSymbols; */
521
+ #if defined(TCC_TARGET_X86_64)
522
+ 0x00F0, /*WORD SizeOfOptionalHeader; */
523
+ 0x022F /*WORD Characteristics; */
524
+ #define CHARACTERISTICS_DLL 0x222E
525
+ #elif defined(TCC_TARGET_I386)
526
+ 0x00E0, /*WORD SizeOfOptionalHeader; */
527
+ 0x030F /*WORD Characteristics; */
528
+ #define CHARACTERISTICS_DLL 0x230E
529
+ #elif defined(TCC_TARGET_ARM)
530
+ 0x00E0, /*WORD SizeOfOptionalHeader; */
531
+ 0x010F, /*WORD Characteristics; */
532
+ #define CHARACTERISTICS_DLL 0x230F
533
+ #endif
534
+ },{
535
+ /* IMAGE_OPTIONAL_HEADER opthdr */
536
+ /* Standard fields. */
537
+ #ifdef TCC_TARGET_X86_64
538
+ 0x020B, /*WORD Magic; */
539
+ #else
540
+ 0x010B, /*WORD Magic; */
541
+ #endif
542
+ 0x06, /*BYTE MajorLinkerVersion; */
543
+ 0x00, /*BYTE MinorLinkerVersion; */
544
+ 0x00000000, /*DWORD SizeOfCode; */
545
+ 0x00000000, /*DWORD SizeOfInitializedData; */
546
+ 0x00000000, /*DWORD SizeOfUninitializedData; */
547
+ 0x00000000, /*DWORD AddressOfEntryPoint; */
548
+ 0x00000000, /*DWORD BaseOfCode; */
549
+ #ifndef TCC_TARGET_X86_64
550
+ 0x00000000, /*DWORD BaseOfData; */
551
+ #endif
552
+ /* NT additional fields. */
553
+ #if defined(TCC_TARGET_ARM)
554
+ 0x00100000, /*DWORD ImageBase; */
555
+ #else
556
+ 0x00400000, /*DWORD ImageBase; */
557
+ #endif
558
+ 0x00001000, /*DWORD SectionAlignment; */
559
+ 0x00000200, /*DWORD FileAlignment; */
560
+ 0x0004, /*WORD MajorOperatingSystemVersion; */
561
+ 0x0000, /*WORD MinorOperatingSystemVersion; */
562
+ 0x0000, /*WORD MajorImageVersion; */
563
+ 0x0000, /*WORD MinorImageVersion; */
564
+ 0x0004, /*WORD MajorSubsystemVersion; */
565
+ 0x0000, /*WORD MinorSubsystemVersion; */
566
+ 0x00000000, /*DWORD Win32VersionValue; */
567
+ 0x00000000, /*DWORD SizeOfImage; */
568
+ 0x00000200, /*DWORD SizeOfHeaders; */
569
+ 0x00000000, /*DWORD CheckSum; */
570
+ 0x0002, /*WORD Subsystem; */
571
+ 0x0000, /*WORD DllCharacteristics; */
572
+ 0x00100000, /*DWORD SizeOfStackReserve; */
573
+ 0x00001000, /*DWORD SizeOfStackCommit; */
574
+ 0x00100000, /*DWORD SizeOfHeapReserve; */
575
+ 0x00001000, /*DWORD SizeOfHeapCommit; */
576
+ 0x00000000, /*DWORD LoaderFlags; */
577
+ 0x00000010, /*DWORD NumberOfRvaAndSizes; */
578
+
579
+ /* IMAGE_DATA_DIRECTORY DataDirectory[16]; */
580
+ {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
581
+ {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}}
582
+ }};
583
+
584
+ struct pe_header pe_header = pe_template;
585
+
586
+ int i;
587
+ FILE *op;
588
+ DWORD file_offset, sum;
589
+ struct section_info *si;
590
+ IMAGE_SECTION_HEADER *psh;
591
+
592
+ op = fopen(pe->filename, "wb");
593
+ if (NULL == op) {
594
+ tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
595
+ return -1;
596
+ }
597
+
598
+ pe->sizeofheaders = pe_file_align(pe,
599
+ sizeof (struct pe_header)
600
+ + pe->sec_count * sizeof (IMAGE_SECTION_HEADER)
601
+ );
602
+
603
+ file_offset = pe->sizeofheaders;
604
+
605
+ if (2 == pe->s1->verbose)
606
+ printf("-------------------------------"
607
+ "\n virt file size section" "\n");
608
+ for (i = 0; i < pe->sec_count; ++i) {
609
+ DWORD addr, size;
610
+ const char *sh_name;
611
+
612
+ si = pe->sec_info + i;
613
+ sh_name = si->name;
614
+ addr = si->sh_addr - pe->imagebase;
615
+ size = si->sh_size;
616
+ psh = &si->ish;
617
+
618
+ if (2 == pe->s1->verbose)
619
+ printf("%6x %6x %6x %s\n",
620
+ (unsigned)addr, (unsigned)file_offset, (unsigned)size, sh_name);
621
+
622
+ switch (si->cls) {
623
+ case sec_text:
624
+ pe_header.opthdr.BaseOfCode = addr;
625
+ pe_header.opthdr.AddressOfEntryPoint = addr + pe->start_addr;
626
+ break;
627
+
628
+ case sec_data:
629
+ #ifndef TCC_TARGET_X86_64
630
+ pe_header.opthdr.BaseOfData = addr;
631
+ #endif
632
+ break;
633
+
634
+ case sec_bss:
635
+ break;
636
+
637
+ case sec_reloc:
638
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_BASERELOC, addr, size);
639
+ break;
640
+
641
+ case sec_rsrc:
642
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_RESOURCE, addr, size);
643
+ break;
644
+
645
+ case sec_pdata:
646
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXCEPTION, addr, size);
647
+ break;
648
+
649
+ case sec_stab:
650
+ break;
651
+ }
652
+
653
+ if (pe->thunk == pe->s1->sections[si->ord]) {
654
+ if (pe->imp_size) {
655
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_IMPORT,
656
+ pe->imp_offs + addr, pe->imp_size);
657
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_IAT,
658
+ pe->iat_offs + addr, pe->iat_size);
659
+ }
660
+ if (pe->exp_size) {
661
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXPORT,
662
+ pe->exp_offs + addr, pe->exp_size);
663
+ }
664
+ }
665
+
666
+ pstrcpy((char*)psh->Name, sizeof psh->Name, sh_name);
667
+
668
+ psh->Characteristics = pe_sec_flags[si->cls];
669
+ psh->VirtualAddress = addr;
670
+ psh->Misc.VirtualSize = size;
671
+ pe_header.opthdr.SizeOfImage =
672
+ umax(pe_virtual_align(pe, size + addr), pe_header.opthdr.SizeOfImage);
673
+
674
+ if (si->data_size) {
675
+ psh->PointerToRawData = file_offset;
676
+ file_offset = pe_file_align(pe, file_offset + si->data_size);
677
+ psh->SizeOfRawData = file_offset - psh->PointerToRawData;
678
+ }
679
+ }
680
+
681
+ //pe_header.filehdr.TimeDateStamp = time(NULL);
682
+ pe_header.filehdr.NumberOfSections = pe->sec_count;
683
+ pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
684
+ pe_header.opthdr.ImageBase = pe->imagebase;
685
+ pe_header.opthdr.Subsystem = pe->subsystem;
686
+ if (pe->s1->pe_stack_size)
687
+ pe_header.opthdr.SizeOfStackReserve = pe->s1->pe_stack_size;
688
+ if (PE_DLL == pe->type)
689
+ pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL;
690
+
691
+ sum = 0;
692
+ pe_fwrite(&pe_header, sizeof pe_header, op, &sum);
693
+ for (i = 0; i < pe->sec_count; ++i)
694
+ pe_fwrite(&pe->sec_info[i].ish, sizeof(IMAGE_SECTION_HEADER), op, &sum);
695
+ pe_fpad(op, pe->sizeofheaders);
696
+ for (i = 0; i < pe->sec_count; ++i) {
697
+ si = pe->sec_info + i;
698
+ psh = &si->ish;
699
+ if (si->data_size) {
700
+ pe_fwrite(si->data, si->data_size, op, &sum);
701
+ file_offset = psh->PointerToRawData + psh->SizeOfRawData;
702
+ pe_fpad(op, file_offset);
703
+ }
704
+ }
705
+
706
+ pe_header.opthdr.CheckSum = sum + file_offset;
707
+ fseek(op, offsetof(struct pe_header, opthdr.CheckSum), SEEK_SET);
708
+ pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL);
709
+ fclose (op);
710
+
711
+ if (2 == pe->s1->verbose)
712
+ printf("-------------------------------\n");
713
+ if (pe->s1->verbose)
714
+ printf("<- %s (%u bytes)\n", pe->filename, (unsigned)file_offset);
715
+
716
+ return 0;
717
+ }
718
+
719
+ /*----------------------------------------------------------------------------*/
720
+
721
+ #if defined(TCC_TARGET_X86_64)
722
+ #define REL_TYPE_DIRECT R_X86_64_64
723
+ #define R_XXX_THUNKFIX R_X86_64_PC32
724
+ #define R_XXX_RELATIVE R_X86_64_RELATIVE
725
+
726
+ #elif defined(TCC_TARGET_I386)
727
+ #define REL_TYPE_DIRECT R_386_32
728
+ #define R_XXX_THUNKFIX R_386_32
729
+ #define R_XXX_RELATIVE R_386_RELATIVE
730
+
731
+ #elif defined(TCC_TARGET_ARM)
732
+ #define REL_TYPE_DIRECT R_ARM_ABS32
733
+ #define R_XXX_THUNKFIX R_ARM_ABS32
734
+ #define R_XXX_RELATIVE R_ARM_RELATIVE
735
+
736
+ #endif
737
+ /*----------------------------------------------------------------------------*/
738
+
739
+ static struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index)
740
+ {
741
+ int i;
742
+ int dll_index;
743
+ struct pe_import_info *p;
744
+ struct import_symbol *s;
745
+ ElfW(Sym) *isym;
746
+
747
+ isym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index;
748
+ dll_index = isym->st_size;
749
+
750
+ i = dynarray_assoc ((void**)pe->imp_info, pe->imp_count, dll_index);
751
+ if (-1 != i) {
752
+ p = pe->imp_info[i];
753
+ goto found_dll;
754
+ }
755
+ p = tcc_mallocz(sizeof *p);
756
+ p->dll_index = dll_index;
757
+ dynarray_add((void***)&pe->imp_info, &pe->imp_count, p);
758
+
759
+ found_dll:
760
+ i = dynarray_assoc ((void**)p->symbols, p->sym_count, sym_index);
761
+ if (-1 != i)
762
+ return p->symbols[i];
763
+
764
+ s = tcc_mallocz(sizeof *s);
765
+ dynarray_add((void***)&p->symbols, &p->sym_count, s);
766
+ s->sym_index = sym_index;
767
+ return s;
768
+ }
769
+
770
+ /*----------------------------------------------------------------------------*/
771
+ static void pe_build_imports(struct pe_info *pe)
772
+ {
773
+ int thk_ptr, ent_ptr, dll_ptr, sym_cnt, i;
774
+ DWORD rva_base = pe->thunk->sh_addr - pe->imagebase;
775
+ int ndlls = pe->imp_count;
776
+
777
+ for (sym_cnt = i = 0; i < ndlls; ++i)
778
+ sym_cnt += pe->imp_info[i]->sym_count;
779
+
780
+ if (0 == sym_cnt)
781
+ return;
782
+
783
+ pe_align_section(pe->thunk, 16);
784
+
785
+ pe->imp_offs = dll_ptr = pe->thunk->data_offset;
786
+ pe->imp_size = (ndlls + 1) * sizeof(IMAGE_IMPORT_DESCRIPTOR);
787
+ pe->iat_offs = dll_ptr + pe->imp_size;
788
+ pe->iat_size = (sym_cnt + ndlls) * sizeof(ADDR3264);
789
+ section_ptr_add(pe->thunk, pe->imp_size + 2*pe->iat_size);
790
+
791
+ thk_ptr = pe->iat_offs;
792
+ ent_ptr = pe->iat_offs + pe->iat_size;
793
+
794
+ for (i = 0; i < pe->imp_count; ++i) {
795
+ IMAGE_IMPORT_DESCRIPTOR *hdr;
796
+ int k, n, dllindex;
797
+ ADDR3264 v;
798
+ struct pe_import_info *p = pe->imp_info[i];
799
+ const char *name;
800
+ DLLReference *dllref;
801
+
802
+ dllindex = p->dll_index;
803
+ if (dllindex)
804
+ name = (dllref = pe->s1->loaded_dlls[dllindex-1])->name;
805
+ else
806
+ name = "", dllref = NULL;
807
+
808
+ /* put the dll name into the import header */
809
+ v = put_elf_str(pe->thunk, name);
810
+ hdr = (IMAGE_IMPORT_DESCRIPTOR*)(pe->thunk->data + dll_ptr);
811
+ hdr->FirstThunk = thk_ptr + rva_base;
812
+ hdr->OriginalFirstThunk = ent_ptr + rva_base;
813
+ hdr->Name = v + rva_base;
814
+
815
+ for (k = 0, n = p->sym_count; k <= n; ++k) {
816
+ if (k < n) {
817
+ int iat_index = p->symbols[k]->iat_index;
818
+ int sym_index = p->symbols[k]->sym_index;
819
+ ElfW(Sym) *imp_sym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index;
820
+ ElfW(Sym) *org_sym = (ElfW(Sym) *)symtab_section->data + iat_index;
821
+ const char *name = pe->s1->dynsymtab_section->link->data + imp_sym->st_name;
822
+
823
+ org_sym->st_value = thk_ptr;
824
+ org_sym->st_shndx = pe->thunk->sh_num;
825
+ v = pe->thunk->data_offset + rva_base;
826
+ section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */
827
+ put_elf_str(pe->thunk, name);
828
+ #ifdef TCC_IS_NATIVE
829
+ if (pe->type == PE_RUN) {
830
+ v = imp_sym->st_value;
831
+ if (dllref) {
832
+ if ( !dllref->handle )
833
+ dllref->handle = LoadLibrary(dllref->name);
834
+ v = (ADDR3264)GetProcAddress(dllref->handle, name);
835
+ }
836
+ if (!v)
837
+ tcc_error_noabort("undefined symbol '%s'", name);
838
+ }
839
+ #endif
840
+ } else {
841
+ v = 0; /* last entry is zero */
842
+ }
843
+ *(ADDR3264*)(pe->thunk->data+thk_ptr) =
844
+ *(ADDR3264*)(pe->thunk->data+ent_ptr) = v;
845
+ thk_ptr += sizeof (ADDR3264);
846
+ ent_ptr += sizeof (ADDR3264);
847
+ }
848
+ dll_ptr += sizeof(IMAGE_IMPORT_DESCRIPTOR);
849
+ dynarray_reset(&p->symbols, &p->sym_count);
850
+ }
851
+ dynarray_reset(&pe->imp_info, &pe->imp_count);
852
+ }
853
+
854
+ /* ------------------------------------------------------------- */
855
+
856
+ struct pe_sort_sym
857
+ {
858
+ int index;
859
+ const char *name;
860
+ };
861
+
862
+ static int sym_cmp(const void *va, const void *vb)
863
+ {
864
+ const char *ca = (*(struct pe_sort_sym**)va)->name;
865
+ const char *cb = (*(struct pe_sort_sym**)vb)->name;
866
+ return strcmp(ca, cb);
867
+ }
868
+
869
+ static void pe_build_exports(struct pe_info *pe)
870
+ {
871
+ ElfW(Sym) *sym;
872
+ int sym_index, sym_end;
873
+ DWORD rva_base, func_o, name_o, ord_o, str_o;
874
+ IMAGE_EXPORT_DIRECTORY *hdr;
875
+ int sym_count, ord;
876
+ struct pe_sort_sym **sorted, *p;
877
+
878
+ FILE *op;
879
+ char buf[MAX_PATH];
880
+ const char *dllname;
881
+ const char *name;
882
+
883
+ rva_base = pe->thunk->sh_addr - pe->imagebase;
884
+ sym_count = 0, sorted = NULL, op = NULL;
885
+
886
+ sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
887
+ for (sym_index = 1; sym_index < sym_end; ++sym_index) {
888
+ sym = (ElfW(Sym)*)symtab_section->data + sym_index;
889
+ name = pe_export_name(pe->s1, sym);
890
+ if ((sym->st_other & 1)
891
+ /* export only symbols from actually written sections */
892
+ && pe->s1->sections[sym->st_shndx]->sh_addr) {
893
+ p = tcc_malloc(sizeof *p);
894
+ p->index = sym_index;
895
+ p->name = name;
896
+ dynarray_add((void***)&sorted, &sym_count, p);
897
+ }
898
+ #if 0
899
+ if (sym->st_other & 1)
900
+ printf("export: %s\n", name);
901
+ if (sym->st_other & 2)
902
+ printf("stdcall: %s\n", name);
903
+ #endif
904
+ }
905
+
906
+ if (0 == sym_count)
907
+ return;
908
+
909
+ qsort (sorted, sym_count, sizeof *sorted, sym_cmp);
910
+
911
+ pe_align_section(pe->thunk, 16);
912
+ dllname = tcc_basename(pe->filename);
913
+
914
+ pe->exp_offs = pe->thunk->data_offset;
915
+ func_o = pe->exp_offs + sizeof(IMAGE_EXPORT_DIRECTORY);
916
+ name_o = func_o + sym_count * sizeof (DWORD);
917
+ ord_o = name_o + sym_count * sizeof (DWORD);
918
+ str_o = ord_o + sym_count * sizeof(WORD);
919
+
920
+ hdr = section_ptr_add(pe->thunk, str_o - pe->exp_offs);
921
+ hdr->Characteristics = 0;
922
+ hdr->Base = 1;
923
+ hdr->NumberOfFunctions = sym_count;
924
+ hdr->NumberOfNames = sym_count;
925
+ hdr->AddressOfFunctions = func_o + rva_base;
926
+ hdr->AddressOfNames = name_o + rva_base;
927
+ hdr->AddressOfNameOrdinals = ord_o + rva_base;
928
+ hdr->Name = str_o + rva_base;
929
+ put_elf_str(pe->thunk, dllname);
930
+
931
+ #if 1
932
+ /* automatically write exports to <output-filename>.def */
933
+ pstrcpy(buf, sizeof buf, pe->filename);
934
+ strcpy(tcc_fileextension(buf), ".def");
935
+ op = fopen(buf, "w");
936
+ if (NULL == op) {
937
+ tcc_error_noabort("could not create '%s': %s", buf, strerror(errno));
938
+ } else {
939
+ fprintf(op, "LIBRARY %s\n\nEXPORTS\n", dllname);
940
+ if (pe->s1->verbose)
941
+ printf("<- %s (%d symbols)\n", buf, sym_count);
942
+ }
943
+ #endif
944
+
945
+ for (ord = 0; ord < sym_count; ++ord)
946
+ {
947
+ p = sorted[ord], sym_index = p->index, name = p->name;
948
+ /* insert actual address later in pe_relocate_rva */
949
+ put_elf_reloc(symtab_section, pe->thunk,
950
+ func_o, R_XXX_RELATIVE, sym_index);
951
+ *(DWORD*)(pe->thunk->data + name_o)
952
+ = pe->thunk->data_offset + rva_base;
953
+ *(WORD*)(pe->thunk->data + ord_o)
954
+ = ord;
955
+ put_elf_str(pe->thunk, name);
956
+ func_o += sizeof (DWORD);
957
+ name_o += sizeof (DWORD);
958
+ ord_o += sizeof (WORD);
959
+ if (op)
960
+ fprintf(op, "%s\n", name);
961
+ }
962
+ pe->exp_size = pe->thunk->data_offset - pe->exp_offs;
963
+ dynarray_reset(&sorted, &sym_count);
964
+ if (op)
965
+ fclose(op);
966
+ }
967
+
968
+ /* ------------------------------------------------------------- */
969
+ static void pe_build_reloc (struct pe_info *pe)
970
+ {
971
+ DWORD offset, block_ptr, addr;
972
+ int count, i;
973
+ ElfW_Rel *rel, *rel_end;
974
+ Section *s = NULL, *sr;
975
+
976
+ offset = addr = block_ptr = count = i = 0;
977
+ rel = rel_end = NULL;
978
+
979
+ for(;;) {
980
+ if (rel < rel_end) {
981
+ int type = ELFW(R_TYPE)(rel->r_info);
982
+ addr = rel->r_offset + s->sh_addr;
983
+ ++ rel;
984
+ if (type != REL_TYPE_DIRECT)
985
+ continue;
986
+ if (count == 0) { /* new block */
987
+ block_ptr = pe->reloc->data_offset;
988
+ section_ptr_add(pe->reloc, sizeof(struct pe_reloc_header));
989
+ offset = addr & 0xFFFFFFFF<<12;
990
+ }
991
+ if ((addr -= offset) < (1<<12)) { /* one block spans 4k addresses */
992
+ WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD));
993
+ *wp = addr | IMAGE_REL_BASED_HIGHLOW<<12;
994
+ ++count;
995
+ continue;
996
+ }
997
+ -- rel;
998
+
999
+ } else if (i < pe->sec_count) {
1000
+ sr = (s = pe->s1->sections[pe->sec_info[i++].ord])->reloc;
1001
+ if (sr) {
1002
+ rel = (ElfW_Rel *)sr->data;
1003
+ rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
1004
+ }
1005
+ continue;
1006
+ }
1007
+
1008
+ if (count) {
1009
+ /* store the last block and ready for a new one */
1010
+ struct pe_reloc_header *hdr;
1011
+ if (count & 1) /* align for DWORDS */
1012
+ section_ptr_add(pe->reloc, sizeof(WORD)), ++count;
1013
+ hdr = (struct pe_reloc_header *)(pe->reloc->data + block_ptr);
1014
+ hdr -> offset = offset - pe->imagebase;
1015
+ hdr -> size = count * sizeof(WORD) + sizeof(struct pe_reloc_header);
1016
+ count = 0;
1017
+ }
1018
+
1019
+ if (rel >= rel_end)
1020
+ break;
1021
+ }
1022
+ }
1023
+
1024
+ /* ------------------------------------------------------------- */
1025
+ static int pe_section_class(Section *s)
1026
+ {
1027
+ int type, flags;
1028
+ const char *name;
1029
+
1030
+ type = s->sh_type;
1031
+ flags = s->sh_flags;
1032
+ name = s->name;
1033
+ if (flags & SHF_ALLOC) {
1034
+ if (type == SHT_PROGBITS) {
1035
+ if (flags & SHF_EXECINSTR)
1036
+ return sec_text;
1037
+ if (flags & SHF_WRITE)
1038
+ return sec_data;
1039
+ if (0 == strcmp(name, ".rsrc"))
1040
+ return sec_rsrc;
1041
+ if (0 == strcmp(name, ".iedat"))
1042
+ return sec_idata;
1043
+ if (0 == strcmp(name, ".pdata"))
1044
+ return sec_pdata;
1045
+ return sec_other;
1046
+ } else if (type == SHT_NOBITS) {
1047
+ if (flags & SHF_WRITE)
1048
+ return sec_bss;
1049
+ }
1050
+ } else {
1051
+ if (0 == strcmp(name, ".reloc"))
1052
+ return sec_reloc;
1053
+ if (0 == strncmp(name, ".stab", 5)) /* .stab and .stabstr */
1054
+ return sec_stab;
1055
+ }
1056
+ return -1;
1057
+ }
1058
+
1059
+ static int pe_assign_addresses (struct pe_info *pe)
1060
+ {
1061
+ int i, k, o, c;
1062
+ DWORD addr;
1063
+ int *section_order;
1064
+ struct section_info *si;
1065
+ Section *s;
1066
+
1067
+ // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
1068
+
1069
+ section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int));
1070
+ for (o = k = 0 ; k < sec_last; ++k) {
1071
+ for (i = 1; i < pe->s1->nb_sections; ++i) {
1072
+ s = pe->s1->sections[i];
1073
+ if (k == pe_section_class(s)) {
1074
+ // printf("%s %d\n", s->name, k);
1075
+ s->sh_addr = pe->imagebase;
1076
+ section_order[o++] = i;
1077
+ }
1078
+ }
1079
+ }
1080
+
1081
+ pe->sec_info = tcc_mallocz(o * sizeof (struct section_info));
1082
+ addr = pe->imagebase + 1;
1083
+
1084
+ for (i = 0; i < o; ++i)
1085
+ {
1086
+ k = section_order[i];
1087
+ s = pe->s1->sections[k];
1088
+ c = pe_section_class(s);
1089
+ si = &pe->sec_info[pe->sec_count];
1090
+
1091
+ #ifdef PE_MERGE_DATA
1092
+ if (c == sec_bss && pe->sec_count && si[-1].cls == sec_data) {
1093
+ /* append .bss to .data */
1094
+ s->sh_addr = addr = ((addr-1) | (s->sh_addralign-1)) + 1;
1095
+ addr += s->data_offset;
1096
+ si[-1].sh_size = addr - si[-1].sh_addr;
1097
+ continue;
1098
+ }
1099
+ #endif
1100
+ if (c == sec_stab && 0 == pe->s1->do_debug)
1101
+ continue;
1102
+
1103
+ strcpy(si->name, s->name);
1104
+ si->cls = c;
1105
+ si->ord = k;
1106
+ si->sh_addr = s->sh_addr = addr = pe_virtual_align(pe, addr);
1107
+ si->sh_flags = s->sh_flags;
1108
+
1109
+ if (c == sec_data && NULL == pe->thunk)
1110
+ pe->thunk = s;
1111
+
1112
+ if (s == pe->thunk) {
1113
+ pe_build_imports(pe);
1114
+ pe_build_exports(pe);
1115
+ }
1116
+
1117
+ if (c == sec_reloc)
1118
+ pe_build_reloc (pe);
1119
+
1120
+ if (s->data_offset)
1121
+ {
1122
+ if (s->sh_type != SHT_NOBITS) {
1123
+ si->data = s->data;
1124
+ si->data_size = s->data_offset;
1125
+ }
1126
+
1127
+ addr += s->data_offset;
1128
+ si->sh_size = s->data_offset;
1129
+ ++pe->sec_count;
1130
+ }
1131
+ // printf("%08x %05x %s\n", si->sh_addr, si->sh_size, si->name);
1132
+ }
1133
+
1134
+ #if 0
1135
+ for (i = 1; i < pe->s1->nb_sections; ++i) {
1136
+ Section *s = pe->s1->sections[i];
1137
+ int type = s->sh_type;
1138
+ int flags = s->sh_flags;
1139
+ printf("section %-16s %-10s %5x %s,%s,%s\n",
1140
+ s->name,
1141
+ type == SHT_PROGBITS ? "progbits" :
1142
+ type == SHT_NOBITS ? "nobits" :
1143
+ type == SHT_SYMTAB ? "symtab" :
1144
+ type == SHT_STRTAB ? "strtab" :
1145
+ type == SHT_RELX ? "rel" : "???",
1146
+ s->data_offset,
1147
+ flags & SHF_ALLOC ? "alloc" : "",
1148
+ flags & SHF_WRITE ? "write" : "",
1149
+ flags & SHF_EXECINSTR ? "exec" : ""
1150
+ );
1151
+ }
1152
+ pe->s1->verbose = 2;
1153
+ #endif
1154
+
1155
+ tcc_free(section_order);
1156
+ return 0;
1157
+ }
1158
+
1159
+ /* ------------------------------------------------------------- */
1160
+ static void pe_relocate_rva (struct pe_info *pe, Section *s)
1161
+ {
1162
+ Section *sr = s->reloc;
1163
+ ElfW_Rel *rel, *rel_end;
1164
+ rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
1165
+ for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
1166
+ if (ELFW(R_TYPE)(rel->r_info) == R_XXX_RELATIVE) {
1167
+ int sym_index = ELFW(R_SYM)(rel->r_info);
1168
+ DWORD addr = s->sh_addr;
1169
+ if (sym_index) {
1170
+ ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
1171
+ addr = sym->st_value;
1172
+ }
1173
+ // printf("reloc rva %08x %08x %s\n", (DWORD)rel->r_offset, addr, s->name);
1174
+ *(DWORD*)(s->data + rel->r_offset) += addr - pe->imagebase;
1175
+ }
1176
+ }
1177
+ }
1178
+
1179
+ /*----------------------------------------------------------------------------*/
1180
+
1181
+ static int pe_isafunc(int sym_index)
1182
+ {
1183
+ Section *sr = text_section->reloc;
1184
+ ElfW_Rel *rel, *rel_end;
1185
+ Elf32_Word info = ELF32_R_INFO(sym_index, R_386_PC32);
1186
+ if (!sr)
1187
+ return 0;
1188
+ rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
1189
+ for (rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++)
1190
+ if (rel->r_info == info)
1191
+ return 1;
1192
+ return 0;
1193
+ }
1194
+
1195
+ /*----------------------------------------------------------------------------*/
1196
+ static int pe_check_symbols(struct pe_info *pe)
1197
+ {
1198
+ ElfW(Sym) *sym;
1199
+ int sym_index, sym_end;
1200
+ int ret = 0;
1201
+
1202
+ pe_align_section(text_section, 8);
1203
+
1204
+ sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
1205
+ for (sym_index = 1; sym_index < sym_end; ++sym_index) {
1206
+
1207
+ sym = (ElfW(Sym) *)symtab_section->data + sym_index;
1208
+ if (sym->st_shndx == SHN_UNDEF) {
1209
+
1210
+ const char *name = symtab_section->link->data + sym->st_name;
1211
+ unsigned type = ELFW(ST_TYPE)(sym->st_info);
1212
+ int imp_sym = pe_find_import(pe->s1, sym);
1213
+ struct import_symbol *is;
1214
+
1215
+ if (0 == imp_sym)
1216
+ goto not_found;
1217
+
1218
+ if (type == STT_NOTYPE) {
1219
+ /* symbols from assembler have no type, find out which */
1220
+ if (pe_isafunc(sym_index))
1221
+ type = STT_FUNC;
1222
+ else
1223
+ type = STT_OBJECT;
1224
+ }
1225
+
1226
+ is = pe_add_import(pe, imp_sym);
1227
+
1228
+ if (type == STT_FUNC) {
1229
+ unsigned long offset = is->thk_offset;
1230
+ if (offset) {
1231
+ /* got aliased symbol, like stricmp and _stricmp */
1232
+
1233
+ } else {
1234
+ char buffer[100];
1235
+ WORD *p;
1236
+
1237
+ offset = text_section->data_offset;
1238
+ /* add the 'jmp IAT[x]' instruction */
1239
+ #ifdef TCC_TARGET_ARM
1240
+ p = section_ptr_add(text_section, 8+4); // room for code and address
1241
+ (*(DWORD*)(p)) = 0xE59FC000; // arm code ldr ip, [pc] ; PC+8+0 = 0001xxxx
1242
+ (*(DWORD*)(p+2)) = 0xE59CF000; // arm code ldr pc, [ip]
1243
+ #else
1244
+ p = section_ptr_add(text_section, 8);
1245
+ *p = 0x25FF;
1246
+ #ifdef TCC_TARGET_X86_64
1247
+ *(DWORD*)(p+1) = (DWORD)-4;
1248
+ #endif
1249
+ #endif
1250
+ /* add a helper symbol, will be patched later in
1251
+ pe_build_imports */
1252
+ sprintf(buffer, "IAT.%s", name);
1253
+ is->iat_index = put_elf_sym(
1254
+ symtab_section, 0, sizeof(DWORD),
1255
+ ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1256
+ 0, SHN_UNDEF, buffer);
1257
+ #ifdef TCC_TARGET_ARM
1258
+ put_elf_reloc(symtab_section, text_section,
1259
+ offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
1260
+ #else
1261
+ put_elf_reloc(symtab_section, text_section,
1262
+ offset + 2, R_XXX_THUNKFIX, is->iat_index);
1263
+ #endif
1264
+ is->thk_offset = offset;
1265
+ }
1266
+
1267
+ /* tcc_realloc might have altered sym's address */
1268
+ sym = (ElfW(Sym) *)symtab_section->data + sym_index;
1269
+
1270
+ /* patch the original symbol */
1271
+ sym->st_value = offset;
1272
+ sym->st_shndx = text_section->sh_num;
1273
+ sym->st_other &= ~1; /* do not export */
1274
+ continue;
1275
+ }
1276
+
1277
+ if (type == STT_OBJECT) { /* data, ptr to that should be */
1278
+ if (0 == is->iat_index) {
1279
+ /* original symbol will be patched later in pe_build_imports */
1280
+ is->iat_index = sym_index;
1281
+ continue;
1282
+ }
1283
+ }
1284
+
1285
+ not_found:
1286
+ tcc_error_noabort("undefined symbol '%s'", name);
1287
+ ret = -1;
1288
+
1289
+ } else if (pe->s1->rdynamic
1290
+ && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1291
+ /* if -rdynamic option, then export all non local symbols */
1292
+ sym->st_other |= 1;
1293
+ }
1294
+ }
1295
+ return ret;
1296
+ }
1297
+
1298
+ /*----------------------------------------------------------------------------*/
1299
+ #ifdef PE_PRINT_SECTIONS
1300
+ static void pe_print_section(FILE * f, Section * s)
1301
+ {
1302
+ /* just if you'r curious */
1303
+ BYTE *p, *e, b;
1304
+ int i, n, l, m;
1305
+ p = s->data;
1306
+ e = s->data + s->data_offset;
1307
+ l = e - p;
1308
+
1309
+ fprintf(f, "section \"%s\"", s->name);
1310
+ if (s->link)
1311
+ fprintf(f, "\nlink \"%s\"", s->link->name);
1312
+ if (s->reloc)
1313
+ fprintf(f, "\nreloc \"%s\"", s->reloc->name);
1314
+ fprintf(f, "\nv_addr %08X", (unsigned)s->sh_addr);
1315
+ fprintf(f, "\ncontents %08X", (unsigned)l);
1316
+ fprintf(f, "\n\n");
1317
+
1318
+ if (s->sh_type == SHT_NOBITS)
1319
+ return;
1320
+
1321
+ if (0 == l)
1322
+ return;
1323
+
1324
+ if (s->sh_type == SHT_SYMTAB)
1325
+ m = sizeof(ElfW(Sym));
1326
+ else if (s->sh_type == SHT_RELX)
1327
+ m = sizeof(ElfW_Rel);
1328
+ else
1329
+ m = 16;
1330
+
1331
+ fprintf(f, "%-8s", "offset");
1332
+ for (i = 0; i < m; ++i)
1333
+ fprintf(f, " %02x", i);
1334
+ n = 56;
1335
+
1336
+ if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_RELX) {
1337
+ const char *fields1[] = {
1338
+ "name",
1339
+ "value",
1340
+ "size",
1341
+ "bind",
1342
+ "type",
1343
+ "other",
1344
+ "shndx",
1345
+ NULL
1346
+ };
1347
+
1348
+ const char *fields2[] = {
1349
+ "offs",
1350
+ "type",
1351
+ "symb",
1352
+ NULL
1353
+ };
1354
+
1355
+ const char **p;
1356
+
1357
+ if (s->sh_type == SHT_SYMTAB)
1358
+ p = fields1, n = 106;
1359
+ else
1360
+ p = fields2, n = 58;
1361
+
1362
+ for (i = 0; p[i]; ++i)
1363
+ fprintf(f, "%6s", p[i]);
1364
+ fprintf(f, " symbol");
1365
+ }
1366
+
1367
+ fprintf(f, "\n");
1368
+ for (i = 0; i < n; ++i)
1369
+ fprintf(f, "-");
1370
+ fprintf(f, "\n");
1371
+
1372
+ for (i = 0; i < l;)
1373
+ {
1374
+ fprintf(f, "%08X", i);
1375
+ for (n = 0; n < m; ++n) {
1376
+ if (n + i < l)
1377
+ fprintf(f, " %02X", p[i + n]);
1378
+ else
1379
+ fprintf(f, " ");
1380
+ }
1381
+
1382
+ if (s->sh_type == SHT_SYMTAB) {
1383
+ ElfW(Sym) *sym = (ElfW(Sym) *) (p + i);
1384
+ const char *name = s->link->data + sym->st_name;
1385
+ fprintf(f, " %04X %04X %04X %02X %02X %02X %04X \"%s\"",
1386
+ (unsigned)sym->st_name,
1387
+ (unsigned)sym->st_value,
1388
+ (unsigned)sym->st_size,
1389
+ (unsigned)ELFW(ST_BIND)(sym->st_info),
1390
+ (unsigned)ELFW(ST_TYPE)(sym->st_info),
1391
+ (unsigned)sym->st_other,
1392
+ (unsigned)sym->st_shndx,
1393
+ name);
1394
+
1395
+ } else if (s->sh_type == SHT_RELX) {
1396
+ ElfW_Rel *rel = (ElfW_Rel *) (p + i);
1397
+ ElfW(Sym) *sym =
1398
+ (ElfW(Sym) *) s->link->data + ELFW(R_SYM)(rel->r_info);
1399
+ const char *name = s->link->link->data + sym->st_name;
1400
+ fprintf(f, " %04X %02X %04X \"%s\"",
1401
+ (unsigned)rel->r_offset,
1402
+ (unsigned)ELFW(R_TYPE)(rel->r_info),
1403
+ (unsigned)ELFW(R_SYM)(rel->r_info),
1404
+ name);
1405
+ } else {
1406
+ fprintf(f, " ");
1407
+ for (n = 0; n < m; ++n) {
1408
+ if (n + i < l) {
1409
+ b = p[i + n];
1410
+ if (b < 32 || b >= 127)
1411
+ b = '.';
1412
+ fprintf(f, "%c", b);
1413
+ }
1414
+ }
1415
+ }
1416
+ i += m;
1417
+ fprintf(f, "\n");
1418
+ }
1419
+ fprintf(f, "\n\n");
1420
+ }
1421
+
1422
+ static void pe_print_sections(TCCState *s1, const char *fname)
1423
+ {
1424
+ Section *s;
1425
+ FILE *f;
1426
+ int i;
1427
+ f = fopen(fname, "w");
1428
+ for (i = 1; i < s1->nb_sections; ++i) {
1429
+ s = s1->sections[i];
1430
+ pe_print_section(f, s);
1431
+ }
1432
+ pe_print_section(f, s1->dynsymtab_section);
1433
+ fclose(f);
1434
+ }
1435
+ #endif
1436
+
1437
+ /* ------------------------------------------------------------- */
1438
+ /* helper function for load/store to insert one more indirection */
1439
+
1440
+ ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2)
1441
+ {
1442
+ Sym *sym;
1443
+ ElfW(Sym) *esym;
1444
+ int r2;
1445
+
1446
+ if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST))
1447
+ return sv;
1448
+ sym = sv->sym;
1449
+ if ((sym->type.t & (VT_EXTERN|VT_STATIC)) != VT_EXTERN)
1450
+ return sv;
1451
+ if (!sym->c)
1452
+ put_extern_sym(sym, NULL, 0, 0);
1453
+ esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
1454
+ if (!(esym->st_other & 4))
1455
+ return sv;
1456
+
1457
+ // printf("import %04x %04x %04x %s\n", sv->type.t, sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL));
1458
+
1459
+ memset(v2, 0, sizeof *v2);
1460
+ v2->type.t = VT_PTR;
1461
+ v2->r = VT_CONST | VT_SYM | VT_LVAL;
1462
+ v2->sym = sv->sym;
1463
+
1464
+ r2 = get_reg(RC_INT);
1465
+ load(r2, v2);
1466
+ v2->r = r2;
1467
+
1468
+ if (sv->c.ui) {
1469
+ vpushv(v2);
1470
+ vpushi(sv->c.ui);
1471
+ gen_opi('+');
1472
+ *v2 = *vtop--;
1473
+ }
1474
+
1475
+ v2->type.t = sv->type.t;
1476
+ v2->r |= sv->r & VT_LVAL;
1477
+ return v2;
1478
+ }
1479
+
1480
+ ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value)
1481
+ {
1482
+ return add_elf_sym(
1483
+ s1->dynsymtab_section,
1484
+ value,
1485
+ dllindex, /* st_size */
1486
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE),
1487
+ 0,
1488
+ value ? SHN_ABS : SHN_UNDEF,
1489
+ name
1490
+ );
1491
+ }
1492
+
1493
+ static int add_dllref(TCCState *s1, const char *dllname)
1494
+ {
1495
+ DLLReference *dllref;
1496
+ int i;
1497
+ for (i = 0; i < s1->nb_loaded_dlls; ++i)
1498
+ if (0 == strcmp(s1->loaded_dlls[i]->name, dllname))
1499
+ return i + 1;
1500
+ dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
1501
+ strcpy(dllref->name, dllname);
1502
+ dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
1503
+ return s1->nb_loaded_dlls;
1504
+ }
1505
+
1506
+ /* ------------------------------------------------------------- */
1507
+
1508
+ static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
1509
+ {
1510
+ lseek(fd, offset, SEEK_SET);
1511
+ return len == read(fd, buffer, len);
1512
+ }
1513
+
1514
+ /* -------------------------------------------------------------
1515
+ * This is for compiled windows resources in 'coff' format
1516
+ * as generated by 'windres.exe -O coff ...'.
1517
+ */
1518
+
1519
+ static int pe_load_res(TCCState *s1, int fd)
1520
+ {
1521
+ struct pe_rsrc_header hdr;
1522
+ Section *rsrc_section;
1523
+ int i, ret = -1;
1524
+ BYTE *ptr;
1525
+ unsigned offs;
1526
+
1527
+ if (!read_mem(fd, 0, &hdr, sizeof hdr))
1528
+ goto quit;
1529
+
1530
+ if (hdr.filehdr.Machine != 0x014C
1531
+ || hdr.filehdr.NumberOfSections != 1
1532
+ || strcmp(hdr.sectionhdr.Name, ".rsrc") != 0)
1533
+ goto quit;
1534
+
1535
+ rsrc_section = new_section(s1, ".rsrc", SHT_PROGBITS, SHF_ALLOC);
1536
+ ptr = section_ptr_add(rsrc_section, hdr.sectionhdr.SizeOfRawData);
1537
+ offs = hdr.sectionhdr.PointerToRawData;
1538
+ if (!read_mem(fd, offs, ptr, hdr.sectionhdr.SizeOfRawData))
1539
+ goto quit;
1540
+ offs = hdr.sectionhdr.PointerToRelocations;
1541
+ for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i)
1542
+ {
1543
+ struct pe_rsrc_reloc rel;
1544
+ if (!read_mem(fd, offs, &rel, sizeof rel))
1545
+ goto quit;
1546
+ // printf("rsrc_reloc: %x %x %x\n", rel.offset, rel.size, rel.type);
1547
+ if (rel.type != 7) /* DIR32NB */
1548
+ goto quit;
1549
+ put_elf_reloc(symtab_section, rsrc_section,
1550
+ rel.offset, R_XXX_RELATIVE, 0);
1551
+ offs += sizeof rel;
1552
+ }
1553
+ ret = 0;
1554
+ quit:
1555
+ return ret;
1556
+ }
1557
+
1558
+ /* ------------------------------------------------------------- */
1559
+ static char *trimfront(char *p)
1560
+ {
1561
+ while (*p && (unsigned char)*p <= ' ')
1562
+ ++p;
1563
+ return p;
1564
+ }
1565
+
1566
+ static char *trimback(char *a, char *e)
1567
+ {
1568
+ while (e > a && (unsigned char)e[-1] <= ' ')
1569
+ --e;
1570
+ *e = 0;;
1571
+ return a;
1572
+ }
1573
+
1574
+ static char *get_line(char *line, int size, int fd)
1575
+ {
1576
+ int n;
1577
+ for (n = 0; n < size - 1; )
1578
+ if (read(fd, line + n, 1) < 1 || line[n++] == '\n')
1579
+ break;
1580
+ if (0 == n)
1581
+ return NULL;
1582
+ trimback(line, line + n);
1583
+ return trimfront(line);
1584
+ }
1585
+
1586
+ /* ------------------------------------------------------------- */
1587
+ static int pe_load_def(TCCState *s1, int fd)
1588
+ {
1589
+ int state = 0, ret = -1, dllindex = 0;
1590
+ char line[400], dllname[80], *p;
1591
+
1592
+ for (;;) {
1593
+ p = get_line(line, sizeof line, fd);
1594
+ if (NULL == p)
1595
+ break;
1596
+ if (0 == *p || ';' == *p)
1597
+ continue;
1598
+ switch (state) {
1599
+ case 0:
1600
+ if (0 != strnicmp(p, "LIBRARY", 7))
1601
+ goto quit;
1602
+ pstrcpy(dllname, sizeof dllname, trimfront(p+7));
1603
+ ++state;
1604
+ continue;
1605
+
1606
+ case 1:
1607
+ if (0 != stricmp(p, "EXPORTS"))
1608
+ goto quit;
1609
+ ++state;
1610
+ continue;
1611
+
1612
+ case 2:
1613
+ dllindex = add_dllref(s1, dllname);
1614
+ ++state;
1615
+
1616
+ default:
1617
+ pe_putimport(s1, dllindex, p, 0);
1618
+ continue;
1619
+ }
1620
+ }
1621
+ ret = 0;
1622
+ quit:
1623
+ return ret;
1624
+ }
1625
+
1626
+ /* ------------------------------------------------------------- */
1627
+ #define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
1628
+ #include "win32/tools/tiny_impdef.c"
1629
+
1630
+ static int pe_load_dll(TCCState *s1, const char *dllname, int fd)
1631
+ {
1632
+ char *p, *q;
1633
+ int index;
1634
+ p = get_export_names(fd);
1635
+ if (!p)
1636
+ return -1;
1637
+ index = add_dllref(s1, dllname);
1638
+ for (q = p; *q; q += 1 + strlen(q))
1639
+ pe_putimport(s1, index, q, 0);
1640
+ tcc_free(p);
1641
+ return 0;
1642
+ }
1643
+
1644
+ /* ------------------------------------------------------------- */
1645
+ ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd)
1646
+ {
1647
+ int ret = -1;
1648
+ char buf[10];
1649
+ if (0 == strcmp(tcc_fileextension(filename), ".def"))
1650
+ ret = pe_load_def(s1, fd);
1651
+ else if (pe_load_res(s1, fd) == 0)
1652
+ ret = 0;
1653
+ else if (read_mem(fd, 0, buf, sizeof buf) && 0 == strncmp(buf, "MZ", 2))
1654
+ ret = pe_load_dll(s1, tcc_basename(filename), fd);
1655
+ return ret;
1656
+ }
1657
+
1658
+ /* ------------------------------------------------------------- */
1659
+ #ifdef TCC_TARGET_X86_64
1660
+ static unsigned pe_add_uwwind_info(TCCState *s1)
1661
+ {
1662
+ if (NULL == s1->uw_pdata) {
1663
+ s1->uw_pdata = find_section(tcc_state, ".pdata");
1664
+ s1->uw_pdata->sh_addralign = 4;
1665
+ s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, NULL);
1666
+ }
1667
+
1668
+ if (0 == s1->uw_offs) {
1669
+ /* As our functions all have the same stackframe, we use one entry for all */
1670
+ static const unsigned char uw_info[] = {
1671
+ 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags
1672
+ 0x04, // UBYTE Size of prolog
1673
+ 0x02, // UBYTE Count of unwind codes
1674
+ 0x05, // UBYTE: 4 Frame Register (rbp), UBYTE: 4 Frame Register offset (scaled)
1675
+ // USHORT * n Unwind codes array
1676
+ // 0x0b, 0x01, 0xff, 0xff, // stack size
1677
+ 0x04, 0x03, // set frame ptr (mov rsp -> rbp)
1678
+ 0x01, 0x50 // push reg (rbp)
1679
+ };
1680
+
1681
+ Section *s = text_section;
1682
+ unsigned char *p;
1683
+
1684
+ section_ptr_add(s, -s->data_offset & 3); /* align */
1685
+ s1->uw_offs = s->data_offset;
1686
+ p = section_ptr_add(s, sizeof uw_info);
1687
+ memcpy(p, uw_info, sizeof uw_info);
1688
+ }
1689
+
1690
+ return s1->uw_offs;
1691
+ }
1692
+
1693
+ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack)
1694
+ {
1695
+ TCCState *s1 = tcc_state;
1696
+ Section *pd;
1697
+ unsigned o, n, d;
1698
+ struct /* _RUNTIME_FUNCTION */ {
1699
+ DWORD BeginAddress;
1700
+ DWORD EndAddress;
1701
+ DWORD UnwindData;
1702
+ } *p;
1703
+
1704
+ d = pe_add_uwwind_info(s1);
1705
+ pd = s1->uw_pdata;
1706
+ o = pd->data_offset;
1707
+ p = section_ptr_add(pd, sizeof *p);
1708
+
1709
+ /* record this function */
1710
+ p->BeginAddress = start;
1711
+ p->EndAddress = end;
1712
+ p->UnwindData = d;
1713
+
1714
+ /* put relocations on it */
1715
+ for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress)
1716
+ put_elf_reloc(symtab_section, pd, o, R_X86_64_RELATIVE, s1->uw_sym);
1717
+ }
1718
+ #endif
1719
+ /* ------------------------------------------------------------- */
1720
+ #ifdef TCC_TARGET_X86_64
1721
+ #define PE_STDSYM(n,s) n
1722
+ #else
1723
+ #define PE_STDSYM(n,s) "_" n s
1724
+ #endif
1725
+
1726
+ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
1727
+ {
1728
+ const char *start_symbol;
1729
+ ADDR3264 addr = 0;
1730
+ int pe_type = 0;
1731
+
1732
+ if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16")))
1733
+ pe_type = PE_GUI;
1734
+ else
1735
+ if (TCC_OUTPUT_DLL == s1->output_type) {
1736
+ pe_type = PE_DLL;
1737
+ /* need this for 'tccelf.c:relocate_section()' */
1738
+ s1->output_type = TCC_OUTPUT_EXE;
1739
+ }
1740
+ else
1741
+ pe_type = PE_EXE;
1742
+
1743
+ start_symbol =
1744
+ TCC_OUTPUT_MEMORY == s1->output_type
1745
+ ? PE_GUI == pe_type ? "__runwinmain" : "_main"
1746
+ : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12")
1747
+ : PE_GUI == pe_type ? "__winstart" : "__start"
1748
+ ;
1749
+
1750
+ if (!s1->leading_underscore || strchr(start_symbol, '@')) {
1751
+ ++start_symbol;
1752
+ if (start_symbol[0] != '_')
1753
+ start_symbol = NULL;
1754
+ }
1755
+
1756
+ /* grab the startup code from libtcc1 */
1757
+ if (start_symbol)
1758
+ add_elf_sym(symtab_section,
1759
+ 0, 0,
1760
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1761
+ SHN_UNDEF, start_symbol);
1762
+
1763
+ if (0 == s1->nostdlib) {
1764
+ static const char *libs[] = {
1765
+ "libtcc1.a", "msvcrt", "kernel32", "", "user32", "gdi32", NULL
1766
+ };
1767
+ const char **pp, *p;
1768
+ for (pp = libs; 0 != (p = *pp); ++pp) {
1769
+ if (0 == *p) {
1770
+ if (PE_DLL != pe_type && PE_GUI != pe_type)
1771
+ break;
1772
+ } else if (pp == libs ? tcc_add_dll(s1, p, 0) : tcc_add_library(s1, p)) {
1773
+ tcc_error_noabort("cannot find library: %s", p);
1774
+ break;
1775
+ }
1776
+ }
1777
+ }
1778
+
1779
+ if (TCC_OUTPUT_MEMORY == s1->output_type)
1780
+ pe_type = PE_RUN;
1781
+
1782
+ if (start_symbol) {
1783
+ addr = get_elf_sym_addr(s1, start_symbol, 1);
1784
+ if (PE_RUN == pe_type && addr)
1785
+ /* for -run GUI's, put '_runwinmain' instead of 'main' */
1786
+ add_elf_sym(symtab_section,
1787
+ addr, 0,
1788
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1789
+ text_section->sh_num, "main");
1790
+ }
1791
+
1792
+ pe->type = pe_type;
1793
+ pe->start_addr = addr;
1794
+ }
1795
+
1796
+ ST_FUNC int pe_output_file(TCCState * s1, const char *filename)
1797
+ {
1798
+ int ret;
1799
+ struct pe_info pe;
1800
+ int i;
1801
+
1802
+ memset(&pe, 0, sizeof pe);
1803
+ pe.filename = filename;
1804
+ pe.s1 = s1;
1805
+
1806
+ tcc_add_bcheck(s1);
1807
+ pe_add_runtime(s1, &pe);
1808
+ relocate_common_syms(); /* assign bss adresses */
1809
+ tcc_add_linker_symbols(s1);
1810
+
1811
+ ret = pe_check_symbols(&pe);
1812
+ if (ret)
1813
+ ;
1814
+ else if (filename) {
1815
+ if (PE_DLL == pe.type) {
1816
+ pe.reloc = new_section(pe.s1, ".reloc", SHT_PROGBITS, 0);
1817
+ /* XXX: check if is correct for arm-pe target */
1818
+ pe.imagebase = 0x10000000;
1819
+ } else {
1820
+ #if defined(TCC_TARGET_ARM)
1821
+ pe.imagebase = 0x00010000;
1822
+ #else
1823
+ pe.imagebase = 0x00400000;
1824
+ #endif
1825
+ }
1826
+
1827
+ #if defined(TCC_TARGET_ARM)
1828
+ /* we use "console" subsystem by default */
1829
+ pe.subsystem = 9;
1830
+ #else
1831
+ if (PE_DLL == pe.type || PE_GUI == pe.type)
1832
+ pe.subsystem = 2;
1833
+ else
1834
+ pe.subsystem = 3;
1835
+ #endif
1836
+ /* Allow override via -Wl,-subsystem=... option */
1837
+ if (s1->pe_subsystem != 0)
1838
+ pe.subsystem = s1->pe_subsystem;
1839
+
1840
+ /* set default file/section alignment */
1841
+ if (pe.subsystem == 1) {
1842
+ pe.section_align = 0x20;
1843
+ pe.file_align = 0x20;
1844
+ } else {
1845
+ pe.section_align = 0x1000;
1846
+ pe.file_align = 0x200;
1847
+ }
1848
+
1849
+ if (s1->section_align != 0)
1850
+ pe.section_align = s1->section_align;
1851
+ if (s1->pe_file_align != 0)
1852
+ pe.file_align = s1->pe_file_align;
1853
+
1854
+ if ((pe.subsystem >= 10) && (pe.subsystem <= 12))
1855
+ pe.imagebase = 0;
1856
+
1857
+ if (s1->has_text_addr)
1858
+ pe.imagebase = s1->text_addr;
1859
+
1860
+ pe_assign_addresses(&pe);
1861
+ relocate_syms(s1, 0);
1862
+ for (i = 1; i < s1->nb_sections; ++i) {
1863
+ Section *s = s1->sections[i];
1864
+ if (s->reloc) {
1865
+ relocate_section(s1, s);
1866
+ pe_relocate_rva(&pe, s);
1867
+ }
1868
+ }
1869
+ if (s1->nb_errors)
1870
+ ret = -1;
1871
+ else
1872
+ ret = pe_write(&pe);
1873
+ tcc_free(pe.sec_info);
1874
+ } else {
1875
+ #ifdef TCC_IS_NATIVE
1876
+ pe.thunk = data_section;
1877
+ pe_build_imports(&pe);
1878
+ #endif
1879
+ }
1880
+
1881
+ #ifdef PE_PRINT_SECTIONS
1882
+ pe_print_sections(s1, "tcc.log");
1883
+ #endif
1884
+ return ret;
1885
+ }
1886
+
1887
+ /* ------------------------------------------------------------- */