summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@debian.org>2018-02-23 23:39:54 +0000
committerThomas Preud'homme <robotux@debian.org>2018-02-23 23:39:54 +0000
commit6ff03085ca236f6748959826728c986600fa66bd (patch)
treefc30b3b3fe20cc005634818512dab3514acf8ef4
Import tcc_0.9.27.orig.tar.bz2
[dgit import orig tcc_0.9.27.orig.tar.bz2]
-rw-r--r--.gitignore57
-rw-r--r--COPYING504
-rw-r--r--Changelog439
-rw-r--r--CodingStyle71
-rw-r--r--Makefile403
-rw-r--r--README95
-rw-r--r--RELICENSING60
-rw-r--r--TODO100
-rw-r--r--VERSION1
-rw-r--r--arm-asm.c94
-rw-r--r--arm-gen.c2151
-rw-r--r--arm-link.c398
-rw-r--r--arm64-gen.c1837
-rw-r--r--arm64-link.c256
-rw-r--r--c67-gen.c2540
-rw-r--r--c67-link.c131
-rw-r--r--coff.h446
-rwxr-xr-xconfigure527
-rw-r--r--conftest.c87
-rw-r--r--elf.h3237
-rwxr-xr-xexamples/ex1.c8
-rw-r--r--examples/ex2.c98
-rw-r--r--examples/ex3.c23
-rwxr-xr-xexamples/ex4.c26
-rw-r--r--examples/ex5.c8
-rw-r--r--i386-asm.c1723
-rw-r--r--i386-asm.h480
-rw-r--r--i386-gen.c1164
-rw-r--r--i386-link.c247
-rw-r--r--i386-tok.h253
-rw-r--r--il-gen.c657
-rw-r--r--il-opcodes.h251
-rw-r--r--include/float.h57
-rw-r--r--include/stdarg.h79
-rw-r--r--include/stdbool.h11
-rw-r--r--include/stddef.h54
-rw-r--r--include/varargs.h12
-rw-r--r--lib/Makefile73
-rw-r--r--lib/alloca-arm.S17
-rw-r--r--lib/alloca86-bt.S47
-rw-r--r--lib/alloca86.S31
-rw-r--r--lib/alloca86_64-bt.S56
-rw-r--r--lib/alloca86_64.S34
-rw-r--r--lib/armeabi.c501
-rw-r--r--lib/armflush.c58
-rw-r--r--lib/bcheck.c979
-rw-r--r--lib/lib-arm64.c664
-rw-r--r--lib/libtcc1.c622
-rw-r--r--lib/va_list.c65
-rw-r--r--libtcc.c1981
-rw-r--r--libtcc.h100
-rw-r--r--stab.def234
-rw-r--r--stab.h17
-rw-r--r--tcc-doc.html2489
-rw-r--r--tcc-doc.texi1326
-rw-r--r--tcc.c371
-rw-r--r--tcc.h1660
-rw-r--r--tccasm.c1277
-rw-r--r--tcccoff.c948
-rw-r--r--tccelf.c3058
-rw-r--r--tccgen.c7386
-rw-r--r--tcclib.h80
-rw-r--r--tccpe.c1996
-rw-r--r--tccpp.c3903
-rw-r--r--tccrun.c844
-rw-r--r--tcctok.h350
-rw-r--r--tcctools.c546
-rw-r--r--tests/42test.h13
-rw-r--r--tests/Makefile289
-rw-r--r--tests/abitest.c691
-rw-r--r--tests/asm-c-connect-1.c57
-rw-r--r--tests/asm-c-connect-2.c36
-rw-r--r--tests/asmtest.S978
-rw-r--r--tests/boundtest.c285
-rwxr-xr-xtests/gcctestsuite.sh33
-rw-r--r--tests/libtcc_test.c96
-rw-r--r--tests/pp/01.c6
-rw-r--r--tests/pp/01.expect1
-rw-r--r--tests/pp/02.c28
-rw-r--r--tests/pp/02.expect5
-rw-r--r--tests/pp/03.c15
-rw-r--r--tests/pp/03.expect5
-rw-r--r--tests/pp/04.c4
-rw-r--r--tests/pp/04.expect1
-rw-r--r--tests/pp/05.c7
-rw-r--r--tests/pp/05.expect3
-rw-r--r--tests/pp/06.c5
-rw-r--r--tests/pp/06.expect1
-rw-r--r--tests/pp/07.c4
-rw-r--r--tests/pp/07.expect2
-rw-r--r--tests/pp/08.c4
-rw-r--r--tests/pp/08.expect1
-rw-r--r--tests/pp/09.c4
-rw-r--r--tests/pp/09.expect1
-rw-r--r--tests/pp/10.c10
-rw-r--r--tests/pp/10.expect5
-rw-r--r--tests/pp/11.c31
-rw-r--r--tests/pp/11.expect15
-rw-r--r--tests/pp/12.S8
-rw-r--r--tests/pp/12.expect2
-rw-r--r--tests/pp/13.S6
-rw-r--r--tests/pp/13.expect2
-rw-r--r--tests/pp/14.c13
-rw-r--r--tests/pp/14.expect3
-rw-r--r--tests/pp/15.c18
-rw-r--r--tests/pp/15.expect5
-rw-r--r--tests/pp/16.c3
-rw-r--r--tests/pp/16.expect2
-rw-r--r--tests/pp/17.c14
-rw-r--r--tests/pp/17.expect6
-rw-r--r--tests/pp/18.c15
-rw-r--r--tests/pp/18.expect3
-rw-r--r--tests/pp/19.c101
-rw-r--r--tests/pp/19.expect14
-rw-r--r--tests/pp/20.c13
-rw-r--r--tests/pp/20.expect6
-rw-r--r--tests/pp/21.c36
-rw-r--r--tests/pp/21.expect8
-rw-r--r--tests/pp/Makefile49
-rw-r--r--tests/pp/pp-counter.c27
-rw-r--r--tests/pp/pp-counter.expect15
-rw-r--r--tests/tcctest.c3871
-rw-r--r--tests/tcctest.h9
-rw-r--r--tests/testfp.c510
-rw-r--r--tests/tests2/00_assignment.c18
-rw-r--r--tests/tests2/00_assignment.expect3
-rw-r--r--tests/tests2/01_comment.c14
-rw-r--r--tests/tests2/01_comment.expect5
-rw-r--r--tests/tests2/02_printf.c18
-rw-r--r--tests/tests2/02_printf.expect15
-rw-r--r--tests/tests2/03_struct.c31
-rw-r--r--tests/tests2/03_struct.expect6
-rw-r--r--tests/tests2/04_for.c15
-rw-r--r--tests/tests2/04_for.expect10
-rw-r--r--tests/tests2/05_array.c21
-rw-r--r--tests/tests2/05_array.expect10
-rw-r--r--tests/tests2/06_case.c29
-rw-r--r--tests/tests2/06_case.expect8
-rw-r--r--tests/tests2/07_function.c30
-rw-r--r--tests/tests2/07_function.expect4
-rw-r--r--tests/tests2/08_while.c24
-rw-r--r--tests/tests2/08_while.expect11
-rw-r--r--tests/tests2/09_do_while.c24
-rw-r--r--tests/tests2/09_do_while.expect11
-rw-r--r--tests/tests2/10_pointer.c40
-rw-r--r--tests/tests2/10_pointer.expect8
-rw-r--r--tests/tests2/11_precedence.c40
-rw-r--r--tests/tests2/11_precedence.expect15
-rw-r--r--tests/tests2/12_hashdefine.c14
-rw-r--r--tests/tests2/12_hashdefine.expect2
-rw-r--r--tests/tests2/13_integer_literals.c20
-rw-r--r--tests/tests2/13_integer_literals.expect5
-rw-r--r--tests/tests2/14_if.c21
-rw-r--r--tests/tests2/14_if.expect2
-rw-r--r--tests/tests2/15_recursion.c21
-rw-r--r--tests/tests2/15_recursion.expect10
-rw-r--r--tests/tests2/16_nesting.c21
-rw-r--r--tests/tests2/16_nesting.expect18
-rw-r--r--tests/tests2/17_enum.c72
-rw-r--r--tests/tests2/17_enum.expect4
-rw-r--r--tests/tests2/18_include.c12
-rw-r--r--tests/tests2/18_include.expect3
-rw-r--r--tests/tests2/18_include.h1
-rw-r--r--tests/tests2/19_pointer_arithmetic.c28
-rw-r--r--tests/tests2/19_pointer_arithmetic.expect3
-rw-r--r--tests/tests2/20_pointer_comparison.c24
-rw-r--r--tests/tests2/20_pointer_comparison.expect6
-rw-r--r--tests/tests2/21_char_array.c33
-rw-r--r--tests/tests2/21_char_array.expect7
-rw-r--r--tests/tests2/22_floating_point.c50
-rw-r--r--tests/tests2/22_floating_point.expect16
-rw-r--r--tests/tests2/23_type_coercion.c54
-rw-r--r--tests/tests2/23_type_coercion.expect12
-rw-r--r--tests/tests2/24_math_library.c30
-rw-r--r--tests/tests2/24_math_library.expect18
-rw-r--r--tests/tests2/25_quicksort.c83
-rw-r--r--tests/tests2/25_quicksort.expect2
-rw-r--r--tests/tests2/26_character_constants.c17
-rw-r--r--tests/tests2/26_character_constants.expect8
-rw-r--r--tests/tests2/27_sizeof.c18
-rw-r--r--tests/tests2/27_sizeof.expect4
-rw-r--r--tests/tests2/28_strings.c45
-rw-r--r--tests/tests2/28_strings.expect19
-rw-r--r--tests/tests2/29_array_address.c13
-rw-r--r--tests/tests2/29_array_address.expect1
-rw-r--r--tests/tests2/30_hanoi.c122
-rw-r--r--tests/tests2/30_hanoi.expect71
-rw-r--r--tests/tests2/31_args.c14
-rw-r--r--tests/tests2/31_args.expect6
-rw-r--r--tests/tests2/32_led.c266
-rw-r--r--tests/tests2/32_led.expect4
-rw-r--r--tests/tests2/33_ternary_op.c15
-rw-r--r--tests/tests2/33_ternary_op.expect10
-rw-r--r--tests/tests2/34_array_assignment.c23
-rw-r--r--tests/tests2/34_array_assignment.expect2
-rw-r--r--tests/tests2/35_sizeof.c14
-rw-r--r--tests/tests2/35_sizeof.expect2
-rw-r--r--tests/tests2/36_array_initialisers.c21
-rw-r--r--tests/tests2/36_array_initialisers.expect20
-rw-r--r--tests/tests2/37_sprintf.c17
-rw-r--r--tests/tests2/37_sprintf.expect20
-rw-r--r--tests/tests2/38_multiple_array_index.c32
-rw-r--r--tests/tests2/38_multiple_array_index.expect4
-rw-r--r--tests/tests2/39_typedef.c65
-rw-r--r--tests/tests2/39_typedef.expect3
-rw-r--r--tests/tests2/40_stdio.c52
-rw-r--r--tests/tests2/40_stdio.expect27
-rw-r--r--tests/tests2/41_hashif.c85
-rw-r--r--tests/tests2/41_hashif.expect6
-rw-r--r--tests/tests2/42_function_pointer.c22
-rw-r--r--tests/tests2/42_function_pointer.expect2
-rw-r--r--tests/tests2/43_void_param.c15
-rw-r--r--tests/tests2/43_void_param.expect1
-rw-r--r--tests/tests2/44_scoped_declarations.c17
-rw-r--r--tests/tests2/44_scoped_declarations.expect1
-rw-r--r--tests/tests2/45_empty_for.c18
-rw-r--r--tests/tests2/45_empty_for.expect10
-rw-r--r--tests/tests2/46_grep.c568
-rw-r--r--tests/tests2/46_grep.expect3
-rw-r--r--tests/tests2/47_switch_return.c24
-rw-r--r--tests/tests2/47_switch_return.expect4
-rw-r--r--tests/tests2/48_nested_break.c26
-rw-r--r--tests/tests2/48_nested_break.expect1
-rw-r--r--tests/tests2/49_bracket_evaluation.c23
-rw-r--r--tests/tests2/49_bracket_evaluation.expect1
-rw-r--r--tests/tests2/50_logical_second_arg.c29
-rw-r--r--tests/tests2/50_logical_second_arg.expect20
-rw-r--r--tests/tests2/51_static.c30
-rw-r--r--tests/tests2/51_static.expect8
-rw-r--r--tests/tests2/52_unnamed_enum.c27
-rw-r--r--tests/tests2/52_unnamed_enum.expect9
-rw-r--r--tests/tests2/54_goto.c56
-rw-r--r--tests/tests2/54_goto.expect8
-rw-r--r--tests/tests2/55_lshift_type.c52
-rw-r--r--tests/tests2/55_lshift_type.expect1
-rw-r--r--tests/tests2/60_errors_and_warnings.c51
-rw-r--r--tests/tests2/60_errors_and_warnings.expect28
-rw-r--r--tests/tests2/64_macro_nesting.c12
-rw-r--r--tests/tests2/64_macro_nesting.expect1
-rw-r--r--tests/tests2/67_macro_concat.c14
-rw-r--r--tests/tests2/67_macro_concat.expect2
-rw-r--r--tests/tests2/70_floating_point_literals.c77
-rw-r--r--tests/tests2/70_floating_point_literals.expect53
-rw-r--r--tests/tests2/71_macro_empty_arg.c9
-rw-r--r--tests/tests2/71_macro_empty_arg.expect1
-rw-r--r--tests/tests2/72_long_long_constant.c19
-rw-r--r--tests/tests2/72_long_long_constant.expect1
-rw-r--r--tests/tests2/73_arm64.c527
-rw-r--r--tests/tests2/73_arm64.expect174
-rw-r--r--tests/tests2/75_array_in_struct_init.c33
-rw-r--r--tests/tests2/75_array_in_struct_init.expect72
-rw-r--r--tests/tests2/76_dollars_in_identifiers.c41
-rw-r--r--tests/tests2/76_dollars_in_identifiers.expect14
-rw-r--r--tests/tests2/77_push_pop_macro.c30
-rw-r--r--tests/tests2/77_push_pop_macro.expect5
-rw-r--r--tests/tests2/78_vla_label.c45
-rw-r--r--tests/tests2/78_vla_label.expect6
-rw-r--r--tests/tests2/79_vla_continue.c116
-rw-r--r--tests/tests2/79_vla_continue.expect5
-rw-r--r--tests/tests2/80_flexarray.c25
-rw-r--r--tests/tests2/80_flexarray.expect0
-rw-r--r--tests/tests2/81_types.c43
-rw-r--r--tests/tests2/81_types.expect0
-rw-r--r--tests/tests2/82_attribs_position.c19
-rw-r--r--tests/tests2/82_attribs_position.expect0
-rw-r--r--tests/tests2/83_utf8_in_identifiers.c9
-rw-r--r--tests/tests2/83_utf8_in_identifiers.expect2
-rw-r--r--tests/tests2/84_hex-float.c12
-rw-r--r--tests/tests2/84_hex-float.expect1
-rw-r--r--tests/tests2/85_asm-outside-function.c9
-rw-r--r--tests/tests2/85_asm-outside-function.expect1
-rw-r--r--tests/tests2/86_memory-model.c38
-rw-r--r--tests/tests2/86_memory-model.expect1
-rw-r--r--tests/tests2/87_dead_code.c122
-rw-r--r--tests/tests2/87_dead_code.expect18
-rw-r--r--tests/tests2/88_codeopt.c68
-rw-r--r--tests/tests2/88_codeopt.expect2
-rw-r--r--tests/tests2/89_nocode_wanted.c112
-rw-r--r--tests/tests2/89_nocode_wanted.expect14
-rw-r--r--tests/tests2/90_struct-init.c282
-rw-r--r--tests/tests2/90_struct-init.expect43
-rw-r--r--tests/tests2/91_ptr_longlong_arith32.c15
-rw-r--r--tests/tests2/91_ptr_longlong_arith32.expect1
-rw-r--r--tests/tests2/92_enum_bitfield.c57
-rw-r--r--tests/tests2/92_enum_bitfield.expect0
-rw-r--r--tests/tests2/93_integer_promotion.c71
-rw-r--r--tests/tests2/93_integer_promotion.expect46
-rw-r--r--tests/tests2/94_generic.c64
-rw-r--r--tests/tests2/94_generic.expect13
-rw-r--r--tests/tests2/95_bitfields.c218
-rw-r--r--tests/tests2/95_bitfields.expect149
-rw-r--r--tests/tests2/95_bitfields_ms.c2
-rw-r--r--tests/tests2/95_bitfields_ms.expect149
-rw-r--r--tests/tests2/96_nodata_wanted.c84
-rw-r--r--tests/tests2/96_nodata_wanted.expect23
-rw-r--r--tests/tests2/97_utf8_string_literal.c12
-rw-r--r--tests/tests2/97_utf8_string_literal.expect1
-rw-r--r--tests/tests2/98_al_ax_extend.c41
-rw-r--r--tests/tests2/98_al_ax_extend.expect9
-rw-r--r--tests/tests2/99_fastcall.c276
-rw-r--r--tests/tests2/99_fastcall.expect1
-rw-r--r--tests/tests2/LICENSE37
-rw-r--r--tests/tests2/Makefile112
-rw-r--r--tests/vla_test.c84
-rwxr-xr-xtexi2pod.pl427
-rwxr-xr-xwin32/build-tcc.bat189
-rw-r--r--win32/examples/dll.c13
-rw-r--r--win32/examples/fib.c24
-rw-r--r--win32/examples/hello_dll.c20
-rw-r--r--win32/examples/hello_win.c163
-rw-r--r--win32/include/_mingw.h170
-rw-r--r--win32/include/assert.h57
-rw-r--r--win32/include/conio.h409
-rw-r--r--win32/include/ctype.h281
-rw-r--r--win32/include/dir.h31
-rw-r--r--win32/include/direct.h68
-rw-r--r--win32/include/dirent.h135
-rw-r--r--win32/include/dos.h55
-rw-r--r--win32/include/errno.h75
-rw-r--r--win32/include/excpt.h123
-rw-r--r--win32/include/fcntl.h52
-rw-r--r--win32/include/fenv.h108
-rw-r--r--win32/include/inttypes.h297
-rw-r--r--win32/include/io.h418
-rw-r--r--win32/include/limits.h111
-rw-r--r--win32/include/locale.h91
-rw-r--r--win32/include/malloc.h181
-rw-r--r--win32/include/math.h737
-rw-r--r--win32/include/mem.h13
-rw-r--r--win32/include/memory.h40
-rw-r--r--win32/include/process.h176
-rw-r--r--win32/include/sec_api/conio_s.h42
-rw-r--r--win32/include/sec_api/crtdbg_s.h19
-rw-r--r--win32/include/sec_api/io_s.h33
-rw-r--r--win32/include/sec_api/mbstring_s.h52
-rw-r--r--win32/include/sec_api/search_s.h25
-rw-r--r--win32/include/sec_api/stdio_s.h145
-rw-r--r--win32/include/sec_api/stdlib_s.h67
-rw-r--r--win32/include/sec_api/stralign_s.h30
-rw-r--r--win32/include/sec_api/string_s.h41
-rw-r--r--win32/include/sec_api/sys/timeb_s.h34
-rw-r--r--win32/include/sec_api/tchar_s.h266
-rw-r--r--win32/include/sec_api/time_s.h61
-rw-r--r--win32/include/sec_api/wchar_s.h128
-rw-r--r--win32/include/setjmp.h160
-rw-r--r--win32/include/share.h28
-rw-r--r--win32/include/signal.h63
-rw-r--r--win32/include/stdint.h212
-rw-r--r--win32/include/stdio.h429
-rw-r--r--win32/include/stdlib.h580
-rw-r--r--win32/include/string.h164
-rw-r--r--win32/include/sys/fcntl.h13
-rw-r--r--win32/include/sys/file.h14
-rw-r--r--win32/include/sys/locking.h30
-rw-r--r--win32/include/sys/stat.h290
-rw-r--r--win32/include/sys/time.h69
-rw-r--r--win32/include/sys/timeb.h133
-rw-r--r--win32/include/sys/types.h118
-rw-r--r--win32/include/sys/unistd.h14
-rw-r--r--win32/include/sys/utime.h146
-rw-r--r--win32/include/tcc/tcc_libm.h201
-rw-r--r--win32/include/tchar.h1102
-rw-r--r--win32/include/time.h287
-rw-r--r--win32/include/vadefs.h11
-rw-r--r--win32/include/values.h4
-rw-r--r--win32/include/wchar.h873
-rw-r--r--win32/include/wctype.h172
-rw-r--r--win32/include/winapi/basetsd.h149
-rw-r--r--win32/include/winapi/basetyps.h85
-rw-r--r--win32/include/winapi/guiddef.h156
-rw-r--r--win32/include/winapi/poppack.h8
-rw-r--r--win32/include/winapi/pshpack1.h8
-rw-r--r--win32/include/winapi/pshpack2.h8
-rw-r--r--win32/include/winapi/pshpack4.h8
-rw-r--r--win32/include/winapi/pshpack8.h8
-rw-r--r--win32/include/winapi/winbase.h2951
-rw-r--r--win32/include/winapi/wincon.h301
-rw-r--r--win32/include/winapi/windef.h293
-rw-r--r--win32/include/winapi/windows.h127
-rw-r--r--win32/include/winapi/winerror.h3166
-rw-r--r--win32/include/winapi/wingdi.h4080
-rw-r--r--win32/include/winapi/winnt.h5835
-rw-r--r--win32/include/winapi/winreg.h272
-rw-r--r--win32/include/winapi/winuser.h5651
-rw-r--r--win32/include/winapi/winver.h160
-rw-r--r--win32/lib/chkstk.S191
-rw-r--r--win32/lib/crt1.c79
-rw-r--r--win32/lib/crt1w.c3
-rw-r--r--win32/lib/dllcrt1.c13
-rw-r--r--win32/lib/dllmain.c9
-rw-r--r--win32/lib/gdi32.def337
-rw-r--r--win32/lib/kernel32.def770
-rw-r--r--win32/lib/msvcrt.def1399
-rw-r--r--win32/lib/user32.def658
-rw-r--r--win32/lib/wincrt1.c75
-rw-r--r--win32/lib/wincrt1w.c3
-rw-r--r--win32/tcc-win32.txt168
-rw-r--r--x86_64-asm.h525
-rw-r--r--x86_64-gen.c2258
-rw-r--r--x86_64-link.c298
400 files changed, 104891 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c989b6b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,57 @@
+*~
+\#*
+.#*
+*.o
+*.a
+*.exe
+*.dll
+*.obj
+*.pdb
+*.lib
+*.exp
+*.log
+*.bz2
+*.zip
+.gdb_history
+a.out
+tcc_g
+tcc
+*-tcc
+libtcc*.def
+
+config*.h
+config*.mak
+config.texi
+conftest*
+tags
+TAGS
+tcc.1
+tcc.pod
+tcc-doc.html
+tcc-doc.info
+
+win32/doc
+win32/libtcc
+win32/lib/32
+win32/lib/64
+win32/include/float.h
+win32/include/stdarg.h
+win32/include/stdbool.h
+win32/include/stddef.h
+win32/include/varargs.h
+win32/include/tcclib.h
+
+tests/tcctest[1234]
+tests/tcctest.gcc
+tests/*.out*
+tests/*.ref
+tests/*.txt
+tests/*.gcc
+tests/*-cc*
+tests/*-tcc*
+tests/libtcc_test
+tests/asm-c-connect
+tests/asm-c-connect-sep
+tests/vla_test
+tests/hello
+tests/tests2/fred.txt
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..223ede7
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/Changelog b/Changelog
new file mode 100644
index 0000000..17f5bde
--- /dev/null
+++ b/Changelog
@@ -0,0 +1,439 @@
+Version 0.9.27:
+
+User interface:
+- -x[c|a|n] filetype option (Sergey Korshunoff)
+- -P[1], -dD, -dM preprocessor options (Sergey Korshunoff)
+- -Wl,-(no-)whole-archive linker option (Reuben Thomas)
+- -mms-bitfields option (David Mertens)
+- -include <file> option (Michael Matz)
+- -mno-sse on x86-64 disables use of SSE instructions
+- @listfile support (Vlad Vissoultchev)
+- tcc -ar/-impdef - formerly tiny_xxx tools integrated (grischka)
+- CPATH, C_INCLUDE_PATH and LIBRARY_PATH environment variables support
+ (Andrew Aladjev, Urs Janssen)
+
+Platforms:
+- new AARCH64 (arm64) target (Edmund Grimley Evans)
+- vastly improved support for ARM hard float calling convention
+ (Thomas Preud'homme, Daniel Glöckner)
+- provide a runtime library for ARM (Thomas Preud'homme)
+- many x86_64 ABI fixes incl. XMM register passing and tests (James Lyon)
+- ABI tests with native compiler using libtcc (James Lyon)
+- UNICODE startup code supports wmain and wWinMain (YX Hao)
+- shared libraries for x86_64 (Michael Matz)
+- Bootstrap native Windows 32/64 compiler using Cygwin+gcc (Christian Jullien)
+
+Features:
+- VLA (variable length array) improved (James Lyon, Pip Cet)
+- import functions by ordinal in .def files on windows (YX Hao)
+- x86/x86_64 assembler much improved (Michael Matz)
+- simple dead code suppression (Edmund Grimley Evans, Michael Matz, grischka)
+- implement round/fmin/fmax etc. math on windows (Avi Halachmi)
+- #pragma once support (Sergey Korshunoff, Vlad Vissoultchev, ...)
+- switch/case code improved (Zdenek Pavlas)
+- ~15% faster by TinyAlloc fast memory allocator (Vlad Vissoultchev)
+- standard conforming (and GCC compatible) struct initialization
+ (Michael Matz)
+- bit-field layout made compatible with GCC (Michael Matz)
+- UTF8 in string literals supported (Zdenek Pavlas)
+_ _Generic(...) supported (Matthias Gatto)
+
+Licensing:
+- TinyCC partly relicensed to MIT license (See RELICENSING file).
+
+version 0.9.26:
+
+User interface:
+- -MD/-MF (automatically generate dependencies for make)
+- -pthread option (same as -D_REENTRANT -lpthread) (Henry Kroll III)
+- -m32/-m64 to re-exec cross compiler (Henry Kroll III)
+- -Wl, Mimic all GNU -option forms supported by ld (Kirill Smelkov)
+- new LIBTCCAPI tcc_set_options() (grischka)
+
+Platforms:
+- Many improvements for x86-64 target (Shinichiro Hamaji, Michael Matz, grischka)
+- x86-64 assembler (Frederic Feret)
+- Many improvements for ARM target (Daniel Glöckner, Thomas Preud'homme)
+- Support WinCE PE ARM (Timo VJ Lahde)
+- Support ARM hardfloat calling convention (Thomas Preud'homme)
+- Support SELinux (Security-Enhanced Linux) (Henry Kroll III)
+- Support Debian GNU/kFreeBSD kernels (Pierre Chifflier)
+- Support GNU/Hurd kernels (Thomas Preud'homme)
+- Support OSX (tcc -run only) (Milutin Jovanovic)
+- Support multiarch configuration (Thomas Preud'homme)
+- Support out-of-tree build (Akim Demaille)
+
+Features:
+- C99 variable length arrays (Thomas Preud'homme & Joe Soroka)
+- Asm labels for variables and functions (Thomas Preud'homme)
+- STT_GNU_IFUNC (Indirect functions as externals) (Thomas Preud'homme)
+- More tests (tests2) (Milutin Jovanovic)
+
+version 0.9.25:
+
+- first support for x86-64 target (Shinichiro Hamaji)
+- support µClibc
+- split tcc.c into tcc.h libtcc.c tccpp.c tccgen.c tcc.c
+- improved preprocess output with linenumbers and spaces preserved
+- tcc_relocate now copies code into user buffer
+- fix bitfields with non-int types and in unions
+- improve ARM cross-compiling (Daniel Glöckner)
+- link stabstr sections from multiple objects
+- better (still limited) support for multiple TCCStates
+
+version 0.9.24:
+
+- added verbosity levels -v, -vv, -vvv
+- Accept standard input as an inputstream (Hanzac Chen)
+- Support c89 compilers other than gcc (Hanzac Chen)
+- -soname linker option (Marc Andre Tanner)
+- Just warn about unknown directives, ignore quotes in #error/#warning
+- Define __STDC_VERSION__=199901L (477)
+- Switch to newer tccpe.c (includes support for resources)
+- Handle backslashes within #include/#error/#warning
+- Import changesets (part 4) 428,457,460,467: defines for openbsd etc.
+- Use _WIN32 for a windows hosted tcc and define it for the PE target,
+ otherwise define __unix / __linux (Detlef Riekenberg)
+- Import changesets (part 3) 409,410: ARM EABI by Daniel Glöckner
+- Some in-between fixes:
+ TCC -E no longer hangs with macro calls involving newlines.
+ (next_nomacro1 now advances the read-pointer with TOK_LINEFEED)
+ Global cast (int g_i = 1LL;) no longer crashes tcc.
+ (nocode_wanted is initially 1, and only 0 for gen_function)
+ On win32 now tcc.exe finds 'include' & 'lib' even if itself is in 'bin'.
+ (new function w32_tcc_lib_path removes 'bin' if detected)
+ Added quick build batch file for mingw (win32/build-tcc.bat)
+ Last added case label optimization (455) produced wrong code. Reverted.
+
+- Import more changesets from Rob Landley's fork (part 2):
+ 487: Handle long long constants in gen_opic() (Rob Landley)
+ 484: Handle parentheses within __attribute__((...)) (Rob Landley)
+ 480: Remove a goto in decl_initializer_alloc (Rob Landley)
+ 475: Fix dereferences in inline assembly output (Joshua Phillips)
+ 474: Cast ptrs to ints of different sizes correctly (Joshua Phillips)
+ 473: Fix size of structs with empty array member (Joshua Phillips)
+ 470: No warning for && and || with mixed pointers/integers (Rob Landley)
+ 469: Fix symbol visibility problems in the linker (Vincent Pit)
+ 468: Allow && and || involving pointer arguments (Rob Landley)
+ 455: Optimize case labels with no code in between (Zdenek Pavlas)
+ 450: Implement alloca for x86 (grischka)
+ 415: Parse unicode escape sequences (Axel Liljencrantz)
+ 407: Add a simple va_copy() in stdarg.h (Hasso Tepper)
+ 400: Allow typedef names as symbols (Dave Dodge)
+
+- Import some changesets from Rob Landley's fork (part 1):
+ 462: Use LGPL with bcheck.c and il-gen.c
+ 458: Fix global compound literals (in unary: case '&':) (Andrew Johnson)
+ 456: Use return code from tcc_output_file in main() (Michael Somos)
+ 442: Fix indirections with function pointers (***fn)() (grischka)
+ 441: Fix LL left shift in libtcc1.c:__shldi3 (grischka)
+ 440: Pass structures and function ptrs through ?: (grischka)
+ 439: Keep rvalue in bit assignment (bit2 = bit1 = x) (grischka)
+ 438: Degrade nonportable pointer assignment to warning (grischka)
+ 437: Call 'saveregs()' before jumping with logical and/or/not (grischka)
+ 435: Put local static variables into global memory (grischka)
+ 432/434: Cast double and ptr to bool (grischka)
+ 420: Zero pad x87 tenbyte long doubles (Felix Nawothnig)
+ 417: Make 'sizeof' unsigned (Rob Landley)
+ 397: Fix save_reg for longlongs (Daniel Glöckner)
+ 396: Fix "invalid relocation entry" problem on ubuntu - (Bernhard Fischer)
+
+- ignore AS_NEEDED ld command
+- mark executable sections as executable when running in memory
+- added support for win32 wchar_t (Filip Navara)
+- segment override prefix support (Filip Navara)
+- normalized slashes in paths (Filip Navara)
+- windows style fastcall (Filip Navara)
+- support for empty input register section in asm (Filip Navara)
+- anonymous union/struct support (Filip Navara)
+- fixed parsing of function parameters
+- workaround for function pointers in conditional expressions (Dave Dodge)
+- initial '-E' option support to use the C preprocessor alone
+- discard type qualifiers when comparing function parameters (Dave Dodge)
+- Bug fix: A long long value used as a test expression ignores the
+ upper 32 bits at runtime (Dave Dodge)
+- fixed multiple concatenation of PPNUM tokens (initial patch by Dave Dodge)
+- fixed multiple typedef specifiers handling
+- fixed sign extension in some type conversions (Dave Dodge)
+
+version 0.9.23:
+
+- initial PE executable format for windows version (grischka)
+- '#pragma pack' support (grischka)
+- '#include_next' support (Bernhard Fischer)
+- ignore '-pipe' option
+- added -f[no-]leading-underscore
+- preprocessor function macro parsing fix (grischka)
+
+version 0.9.22:
+
+- simple memory optimisations: kernel compilation is 30% faster
+- linker symbol definitions fixes
+- gcc 3.4 fixes
+- fixed value stack full error
+- 'packed' attribute support for variables and structure fields
+- ignore 'const' and 'volatile' in function prototypes
+- allow '_Bool' in bit fields
+
+version 0.9.21:
+
+- ARM target support (Daniel Glöckner)
+- added '-funsigned-char, '-fsigned-char' and
+ '-Wimplicit-function-declaration'
+- fixed assignment of const struct in struct
+- line comment fix (reported by Bertram Felgenhauer)
+- initial TMS320C67xx target support (TK)
+- win32 configure
+- regparm() attribute
+- many built-in assembler fixes
+- added '.org', '.fill' and '.previous' assembler directives
+- '-fno-common' option
+- '-Ttext' linker option
+- section alignment fixes
+- bit fields fixes
+- do not generate code for unused inline functions
+- '-oformat' linker option.
+- added 'binary' output format.
+
+version 0.9.20:
+
+- added '-w' option
+- added '.gnu.linkonce' ELF sections support
+- fixed libc linking when running in memory (avoid 'stat' function
+ errors).
+- extended '-run' option to be able to give several arguments to a C
+ script.
+
+version 0.9.19:
+
+- "alacarte" linking (Dave Long)
+- simpler function call
+- more strict type checks
+- added 'const' and 'volatile' support and associated warnings
+- added -Werror, -Wunsupported, -Wwrite-strings, -Wall.
+- added __builtin_types_compatible_p() and __builtin_constant_p()
+- chars support in assembler (Dave Long)
+- .string, .globl, .section, .text, .data and .bss asm directive
+ support (Dave Long)
+- man page generated from tcc-doc.texi
+- fixed macro argument substitution
+- fixed zero argument macro parsing
+- changed license to LGPL
+- added -rdynamic option support
+
+version 0.9.18:
+
+- header fix (time.h)
+- fixed inline asm without operand case
+- fixed 'default:' or 'case x:' with '}' after (incorrect C construct accepted
+ by gcc)
+- added 'A' inline asm constraint.
+
+version 0.9.17:
+
+- PLT generation fix
+- tcc doc fixes (Peter Lund)
+- struct parse fix (signaled by Pedro A. Aranda Gutierrez)
+- better _Bool lvalue support (signaled by Alex Measday)
+- function parameters must be converted to pointers (signaled by Neil Brown)
+- sanitized string and character constant parsing
+- fixed comment parse (signaled by Damian M Gryski)
+- fixed macro function bug (signaled by Philippe Ribet)
+- added configure (initial patch by Mitchell N Charity)
+- added '-run' and '-v' options (initial patch by vlindos)
+- added real date report in __DATE__ and __TIME__ macros
+
+version 0.9.16:
+
+- added assembler language support
+- added GCC inline asm() support
+- fixed multiple variable definitions : uninitialized variables are
+ created as COMMON symbols.
+- optimized macro processing
+- added GCC statement expressions support
+- added GCC local labels support
+- fixed array declaration in old style function parameters
+- support casts in static structure initializations
+- added various __xxx[__] keywords for GCC compatibility
+- ignore __extension__ GCC in an expression or in a type (still not perfect)
+- added '? :' GCC extension support
+
+version 0.9.15:
+
+- compilation fixes for glibc 2.2, gcc 2.95.3 and gcc 3.2.
+- FreeBSD compile fixes. Makefile patches still missing (Carl Drougge).
+- fixed file type guessing if '.' is in the path.
+- fixed tcc_compile_string()
+- add a dummy page in ELF files to fix RX/RW accesses (pageexec at
+ freemail dot hu).
+
+version 0.9.14:
+
+- added #warning. error message if invalid preprocessing directive.
+- added CType structure to ease typing (faster parse).
+- suppressed secondary hash tables (faster parse).
+- rewrote parser by optimizing common cases (faster parse).
+- fixed signed long long comparisons.
+- fixed 'int a(), b();' declaration case.
+- fixed structure init without '{}'.
+- correct alignment support in structures.
+- empty structures support.
+- gcc testsuite now supported.
+- output only warning if implicit integer/pointer conversions.
+- added static bitfield init.
+
+version 0.9.13:
+
+- correct preprocessing token pasting (## operator) in all cases (added
+ preprocessing number token).
+- fixed long long register spill.
+- fixed signed long long '>>'.
+- removed memory leaks.
+- better error handling : processing can continue on link errors. A
+ custom callback can be added to display error messages. Most
+ errors do not call exit() now.
+- ignore -O, -W, -m and -f options
+- added old style function declarations
+- added GCC __alignof__ support.
+- added GCC typeof support.
+- added GCC computed gotos support.
+- added stack backtrace in runtime error message. Improved runtime
+ error position display.
+
+version 0.9.12:
+
+- more fixes for || and && handling.
+- improved '? :' type handling.
+- fixed bound checking generation with structures
+- force '#endif' to be in same file as matching '#if'
+- #include file optimization with '#ifndef #endif' construct detection
+- macro handling optimization
+- added tcc_relocate() and tcc_get_symbol() in libtcc.
+
+version 0.9.11:
+
+- stdarg.h fix for double type (thanks to Philippe Ribet).
+- correct white space characters and added MSDOS newline support.
+- fixed invalid implicit function call type declaration.
+- special macros such as __LINE__ are defined if tested with defined().
+- fixed '!' operator with relocated address.
+- added symbol + offset relocation (fixes some static variable initializers)
+- '-l' option can be specified anywhere. '-c' option yields default
+ output name. added '-r' option for relocatable output.
+- fixed '\nnn' octal parsing.
+- fixed local extern variables declarations.
+
+version 0.9.10:
+
+- fixed lvalue type when saved in local stack.
+- fixed '#include' syntax when using macros.
+- fixed '#line' bug.
+- removed size limit on strings. Unified string constants handling
+ with variable declarations.
+- added correct support for '\xX' in wchar_t strings.
+- added support for bound checking in generated executables
+- fixed -I include order.
+- fixed incorrect function displayed in runtime error.
+
+version 0.9.9:
+
+- fixed preprocessor expression parsing for #if/#elif.
+- relocated debug info (.stab section).
+- relocated bounds info (.bounds section).
+- fixed cast to char of char constants ('\377' is -1 instead of 255)
+- fixed implicit cast for unary plus.
+- strings and '__func__' have now 'char[]' type instead of 'char *'
+ (fixes sizeof() return value).
+- added __start_xxx and __stop_xxx symbols in linker.
+- better DLL creation support (option -shared begins to work).
+- ELF sections and hash tables are resized dynamically.
+- executables and DLLs are stripped by default.
+
+version 0.9.8:
+
+- First version of full ELF linking support (generate objects, static
+ executable, dynamic executable, dynamic libraries). Dynamic library
+ support is not finished (need PIC support in compiler and some
+ patches in symbol exporting).
+- First version of ELF loader for object (.o) and archive (.a) files.
+- Support of simple GNU ld scripts (GROUP and FILE commands)
+- Separated runtime library and bound check code from TCC (smaller
+ compiler core).
+- fixed register reload in float compare.
+- fixed implicit char/short to int casting.
+- allow array type for address of ('&') operator.
+- fixed unused || or && result.
+- added GCC style variadic macro support.
+- optimized bound checking code for array access.
+- tcc includes are now in $(prefix)/lib/tcc/include.
+- more command line options - more consistent handling of multiple
+ input files.
+- added tcc man page (thanks to Cyril Bouthors).
+- uClibc Makefile update
+- converted documentation to texinfo format.
+- added developper's guide in documentation.
+
+version 0.9.7:
+
+- added library API for easy dynamic compilation (see libtcc.h - first
+ draft).
+- fixed long long register spill bug.
+- fixed '? :' register spill bug.
+
+version 0.9.6:
+
+- added floating point constant propagation (fixes negative floating
+ point constants bug).
+
+version 0.9.5:
+
+ - uClibc patches (submitted by Alfonso Martone).
+ - error reporting fix
+ - added CONFIG_TCC_BCHECK to get smaller code if needed.
+
+version 0.9.4:
+
+ - windows port (currently cannot use -g, -b and dll functions).
+ - faster and simpler I/O handling.
+ - '-D' option works in all cases.
+ - preprocessor fixes (#elif and empty macro args)
+ - floating point fixes
+ - first code for CIL generation (does not work yet)
+
+version 0.9.3:
+
+ - better and smaller code generator.
+ - full ISOC99 64 bit 'long long' support.
+ - full 32 bit 'float', 64 bit 'double' and 96 bit 'long double' support.
+ - added '-U' option.
+ - added assembly sections support.
+ - even faster startup time by mmaping sections instead of mallocing them.
+ - added GNUC __attribute__ keyword support (currently supports
+ 'section' and 'aligned' attributes).
+ - added ELF file output (only usable for debugging now)
+ - added debug symbol generation (STAB format).
+ - added integrated runtime error analysis ('-g' option: print clear
+ run time error messages instead of "Segmentation fault").
+ - added first version of tiny memory and bound checker ('-b' option).
+
+version 0.9.2:
+
+ - even faster parsing.
+ - various syntax parsing fixes.
+ - fixed external relocation handling for variables or functions pointers.
+ - better function pointers type handling.
+ - can compile multiple files (-i option).
+ - ANSI C bit fields are supported.
+ - beginning of float/double/long double support.
+ - beginning of long long support.
+
+version 0.9.1:
+
+ - full ISOC99 initializers handling.
+ - compound literals.
+ - structures handle in assignments and as function param or return value.
+ - wide chars and strings.
+ - macro bug fix
+
+version 0.9:
+ - initial version.
diff --git a/CodingStyle b/CodingStyle
new file mode 100644
index 0000000..93d1324
--- /dev/null
+++ b/CodingStyle
@@ -0,0 +1,71 @@
+
+In general, use the same coding style as the surrounding code.
+
+However, do not make any unnecessary changes as that complicates
+the VCS (git) history and makes it harder to merge patches. So
+do not modify code just to make it conform to a coding style.
+
+ Indentation
+
+Turn on a "fill tabs with spaces" option in your editor.
+
+Remove tabs and trailing spaces from any lines that are modified.
+
+Note that some files are indented with 2 spaces (when they
+have large indentation) while most are indented with 4 spaces.
+
+ Language
+
+TCC is mostly implemented in C90. Do not use any non-C90 features
+that are not already in use.
+
+Non-C90 features currently in use, as revealed by
+./configure --extra-cflags="-std=c90 -Wpedantic":
+
+- long long (including "LL" constants)
+- inline
+- very long string constants
+- assignment between function pointer and 'void *'
+- "//" comments
+- empty macro arguments (DEF_ASMTEST in i386-tok.h)
+- unnamed struct and union fields (in struct Sym), a C11 feature
+
+ Testing
+
+A simple "make test" is sufficient for some simple changes. However,
+before committing a change consider performing some of the following
+additional tests:
+
+- Build and run "make test" on several architectures.
+
+- Build with ./configure --enable-cross.
+
+- If the generation of relocations has been changed, try compiling
+ with TCC and linking with GCC/Clang. If the linker has been
+ modified, try compiling with GCC/Clang and linking with TCC.
+
+- Test with ASan/UBSan to detect memory corruption and undefined behaviour:
+
+make clean
+./configure
+make
+make test
+cp libtcc.a libtcc.a.hide
+
+make clean
+./configure --extra-cflags="-fsanitize=address,undefined -g"
+make
+cp libtcc.a.hide libtcc.a
+make test
+
+- Test with Valgrind to detect some uses of uninitialised values:
+
+make clean
+./configure
+make
+# On Intel, because Valgrind does floating-point arithmetic differently:
+( cd tests && gcc -I.. tcctest.c && valgrind -q ./a.out > test.ref )
+make test TCC="valgrind -q --leak-check=full `pwd`/tcc -B`pwd` -I`pwd`"
+
+ (Because of how VLAs are implemented, invalid reads are expected
+ with 79_vla_continue.)
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3ae466f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,403 @@
+# --------------------------------------------------------------------------
+#
+# Tiny C Compiler Makefile
+#
+
+ifndef TOP
+ TOP = .
+ INCLUDED = no
+endif
+
+include $(TOP)/config.mak
+
+ifeq (-$(CC)-$(GCC_MAJOR)-$(findstring $(GCC_MINOR),56789)-,-gcc-4--)
+ CFLAGS += -D_FORTIFY_SOURCE=0
+endif
+
+LIBTCC = libtcc.a
+LIBTCC1 = libtcc1.a
+LINK_LIBTCC =
+LIBS =
+CFLAGS += -I$(TOP)
+CFLAGS += $(CPPFLAGS)
+VPATH = $(TOPSRC)
+
+ifdef CONFIG_WIN32
+ ifneq ($(CONFIG_static),yes)
+ LIBTCC = libtcc$(DLLSUF)
+ LIBTCCDEF = libtcc.def
+ endif
+ CFGWIN = -win
+ NATIVE_TARGET = $(ARCH)-win$(if $(findstring arm,$(ARCH)),ce,32)
+else
+ LIBS=-lm
+ ifneq ($(CONFIG_ldl),no)
+ LIBS+=-ldl
+ endif
+ # make libtcc as static or dynamic library?
+ ifeq ($(CONFIG_static),no)
+ LIBTCC=libtcc$(DLLSUF)
+ export LD_LIBRARY_PATH := $(CURDIR)/$(TOP)
+ ifneq ($(CONFIG_rpath),no)
+ LINK_LIBTCC += -Wl,-rpath,"$(libdir)"
+ endif
+ endif
+ CFGWIN =-unx
+ NATIVE_TARGET = $(ARCH)
+ ifdef CONFIG_OSX
+ NATIVE_TARGET = $(ARCH)-osx
+ LDFLAGS += -flat_namespace -undefined warning
+ export MACOSX_DEPLOYMENT_TARGET := 10.2
+ endif
+endif
+
+# run local version of tcc with local libraries and includes
+TCCFLAGS-unx = -B$(TOP) -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP)
+TCCFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP) -L$(TOP)
+TCCFLAGS = $(TCCFLAGS$(CFGWIN))
+TCC = $(TOP)/tcc$(EXESUF) $(TCCFLAGS)
+ifdef CONFIG_OSX
+ TCCFLAGS += -D_ANSI_SOURCE
+endif
+
+CFLAGS_P = $(CFLAGS) -pg -static -DCONFIG_TCC_STATIC -DTCC_PROFILE
+LIBS_P = $(LIBS)
+LDFLAGS_P = $(LDFLAGS)
+
+CONFIG_$(ARCH) = yes
+NATIVE_DEFINES_$(CONFIG_i386) += -DTCC_TARGET_I386
+NATIVE_DEFINES_$(CONFIG_x86_64) += -DTCC_TARGET_X86_64
+NATIVE_DEFINES_$(CONFIG_WIN32) += -DTCC_TARGET_PE
+NATIVE_DEFINES_$(CONFIG_OSX) += -DTCC_TARGET_MACHO
+NATIVE_DEFINES_$(CONFIG_uClibc) += -DTCC_UCLIBC
+NATIVE_DEFINES_$(CONFIG_musl) += -DTCC_MUSL
+NATIVE_DEFINES_$(CONFIG_libgcc) += -DCONFIG_USE_LIBGCC
+NATIVE_DEFINES_$(CONFIG_selinux) += -DHAVE_SELINUX
+NATIVE_DEFINES_$(CONFIG_arm) += -DTCC_TARGET_ARM
+NATIVE_DEFINES_$(CONFIG_arm_eabihf) += -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
+NATIVE_DEFINES_$(CONFIG_arm_eabi) += -DTCC_ARM_EABI
+NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP
+NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64
+NATIVE_DEFINES += $(NATIVE_DEFINES_yes)
+
+ifeq ($(INCLUDED),no)
+# --------------------------------------------------------------------------
+# running top Makefile
+
+PROGS = tcc$(EXESUF)
+TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCCDEF)
+TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
+
+all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
+
+# cross compiler targets to build
+TCC_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince c67
+# TCC_X += arm-fpa arm-fpa-ld arm-vfp arm-eabi
+
+# cross libtcc1.a targets to build
+LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince
+
+PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF))
+LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a)
+
+# build cross compilers & libs
+cross: $(LIBTCC1_CROSS) $(PROGS_CROSS)
+
+# build specific cross compiler & lib
+cross-%: %-tcc$(EXESUF) %-libtcc1.a ;
+
+install: ; @$(MAKE) --no-print-directory install$(CFGWIN)
+install-strip: ; @$(MAKE) --no-print-directory install$(CFGWIN) CONFIG_strip=yes
+uninstall: ; @$(MAKE) --no-print-directory uninstall$(CFGWIN)
+
+ifdef CONFIG_cross
+all : cross
+endif
+
+# --------------------------------------------
+
+T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
+X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
+
+DEF-i386 = -DTCC_TARGET_I386
+DEF-x86_64 = -DTCC_TARGET_X86_64
+DEF-i386-win32 = -DTCC_TARGET_PE -DTCC_TARGET_I386
+DEF-x86_64-win32= -DTCC_TARGET_PE -DTCC_TARGET_X86_64
+DEF-x86_64-osx = -DTCC_TARGET_MACHO -DTCC_TARGET_X86_64
+DEF-arm-wince = -DTCC_TARGET_PE -DTCC_TARGET_ARM -DTCC_ARM_EABI -DTCC_ARM_VFP -DTCC_ARM_HARDFLOAT
+DEF-arm64 = -DTCC_TARGET_ARM64
+DEF-c67 = -DTCC_TARGET_C67 -w # disable warnigs
+DEF-arm-fpa = -DTCC_TARGET_ARM
+DEF-arm-fpa-ld = -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12
+DEF-arm-vfp = -DTCC_TARGET_ARM -DTCC_ARM_VFP
+DEF-arm-eabi = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI
+DEF-arm-eabihf = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
+DEF-arm = $(DEF-arm-eabihf)
+DEF-$(NATIVE_TARGET) = $(NATIVE_DEFINES)
+
+DEFINES += $(DEF-$T) $(DEF-all)
+DEFINES += $(if $(ROOT-$T),-DCONFIG_SYSROOT="\"$(ROOT-$T)\"")
+DEFINES += $(if $(CRT-$T),-DCONFIG_TCC_CRTPREFIX="\"$(CRT-$T)\"")
+DEFINES += $(if $(LIB-$T),-DCONFIG_TCC_LIBPATHS="\"$(LIB-$T)\"")
+DEFINES += $(if $(INC-$T),-DCONFIG_TCC_SYSINCLUDEPATHS="\"$(INC-$T)\"")
+DEFINES += $(DEF-$(or $(findstring win,$T),unx))
+
+ifneq ($(X),)
+ifeq ($(CONFIG_WIN32),yes)
+DEF-win += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
+DEF-unx += -DTCC_LIBTCC1="\"lib/$(X)libtcc1.a\""
+else
+DEF-all += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
+DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
+endif
+endif
+
+# include custom configuration (see make help)
+-include config-extra.mak
+
+CORE_FILES = tcc.c tcctools.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
+CORE_FILES += tcc.h config.h libtcc.h tcctok.h
+i386_FILES = $(CORE_FILES) i386-gen.c i386-link.c i386-asm.c i386-asm.h i386-tok.h
+i386-win32_FILES = $(i386_FILES) tccpe.c
+x86_64_FILES = $(CORE_FILES) x86_64-gen.c x86_64-link.c i386-asm.c x86_64-asm.h
+x86_64-win32_FILES = $(x86_64_FILES) tccpe.c
+x86_64-osx_FILES = $(x86_64_FILES)
+arm_FILES = $(CORE_FILES) arm-gen.c arm-link.c arm-asm.c
+arm-wince_FILES = $(arm_FILES) tccpe.c
+arm64_FILES = $(CORE_FILES) arm64-gen.c arm64-link.c
+c67_FILES = $(CORE_FILES) c67-gen.c c67-link.c tcccoff.c
+
+# libtcc sources
+LIBTCC_SRC = $(filter-out tcc.c tcctools.c,$(filter %.c,$($T_FILES)))
+
+ifeq ($(ONE_SOURCE),yes)
+LIBTCC_OBJ = $(X)libtcc.o
+LIBTCC_INC = $($T_FILES)
+TCC_FILES = $(X)tcc.o
+tcc.o : DEFINES += -DONE_SOURCE=0
+else
+LIBTCC_OBJ = $(patsubst %.c,$(X)%.o,$(LIBTCC_SRC))
+LIBTCC_INC = $(filter %.h %-gen.c %-link.c,$($T_FILES))
+TCC_FILES = $(X)tcc.o $(LIBTCC_OBJ)
+$(TCC_FILES) : DEFINES += -DONE_SOURCE=0
+endif
+
+# target specific object rule
+$(X)%.o : %.c $(LIBTCC_INC)
+ $(CC) -o $@ -c $< $(DEFINES) $(CFLAGS)
+
+# additional dependencies
+$(X)tcc.o : tcctools.c
+
+# Host Tiny C Compiler
+tcc$(EXESUF): tcc.o $(LIBTCC)
+ $(CC) -o $@ $^ $(LIBS) $(LDFLAGS) $(LINK_LIBTCC)
+
+# Cross Tiny C Compilers
+%-tcc$(EXESUF): FORCE
+ @$(MAKE) --no-print-directory $@ CROSS_TARGET=$* ONE_SOURCE=$(or $(ONE_SOURCE),yes)
+
+$(CROSS_TARGET)-tcc$(EXESUF): $(TCC_FILES)
+ $(CC) -o $@ $^ $(LIBS) $(LDFLAGS)
+
+# profiling version
+tcc_p$(EXESUF): $($T_FILES)
+ $(CC) -o $@ $< $(DEFINES) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
+
+# static libtcc library
+libtcc.a: $(LIBTCC_OBJ)
+ $(AR) rcs $@ $^
+
+# dynamic libtcc library
+libtcc.so: $(LIBTCC_OBJ)
+ $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
+
+libtcc.so: CFLAGS+=-fPIC
+libtcc.so: LDFLAGS+=-fPIC
+
+# windows dynamic libtcc library
+libtcc.dll : $(LIBTCC_OBJ)
+ $(CC) -shared -o $@ $^ $(LDFLAGS)
+libtcc.dll : DEFINES += -DLIBTCC_AS_DLL
+
+# import file for windows libtcc.dll
+libtcc.def : libtcc.dll tcc$(EXESUF)
+ $(XTCC) -impdef $< -o $@
+XTCC ?= ./tcc$(EXESUF)
+
+# TinyCC runtime libraries
+libtcc1.a : tcc$(EXESUF) FORCE
+ @$(MAKE) -C lib DEFINES='$(DEF-$T)'
+
+# Cross libtcc1.a
+%-libtcc1.a : %-tcc$(EXESUF) FORCE
+ @$(MAKE) -C lib DEFINES='$(DEF-$*)' CROSS_TARGET=$*
+
+.PRECIOUS: %-libtcc1.a
+FORCE:
+
+# --------------------------------------------------------------------------
+# documentation and man page
+tcc-doc.html: tcc-doc.texi
+ makeinfo --no-split --html --number-sections -o $@ $< || true
+
+tcc.1: tcc-doc.texi
+ $(TOPSRC)/texi2pod.pl $< tcc.pod \
+ && pod2man --section=1 --center="Tiny C Compiler" --release="$(VERSION)" tcc.pod >tmp.1 \
+ && mv tmp.1 $@ || rm -f tmp.1
+
+tcc-doc.info: tcc-doc.texi
+ makeinfo $< || true
+
+# --------------------------------------------------------------------------
+# install
+
+INSTALL = install -m644
+INSTALLBIN = install -m755 $(STRIP_$(CONFIG_strip))
+STRIP_yes = -s
+
+LIBTCC1_W = $(filter %-win32-libtcc1.a %-wince-libtcc1.a,$(LIBTCC1_CROSS))
+LIBTCC1_U = $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS))
+IB = $(if $1,mkdir -p $2 && $(INSTALLBIN) $1 $2)
+IBw = $(call IB,$(wildcard $1),$2)
+IF = $(if $1,mkdir -p $2 && $(INSTALL) $1 $2)
+IFw = $(call IF,$(wildcard $1),$2)
+IR = mkdir -p $2 && cp -r $1/. $2
+
+# install progs & libs
+install-unx:
+ $(call IBw,$(PROGS) $(PROGS_CROSS),"$(bindir)")
+ $(call IFw,$(LIBTCC1) $(LIBTCC1_U),"$(tccdir)")
+ $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
+ $(call $(if $(findstring .so,$(LIBTCC)),IBw,IFw),$(LIBTCC),"$(libdir)")
+ $(call IF,$(TOPSRC)/libtcc.h,"$(includedir)")
+ $(call IFw,tcc.1,"$(mandir)/man1")
+ $(call IFw,tcc-doc.info,"$(infodir)")
+ $(call IFw,tcc-doc.html,"$(docdir)")
+ifneq "$(wildcard $(LIBTCC1_W))" ""
+ $(call IFw,$(TOPSRC)/win32/lib/*.def $(LIBTCC1_W),"$(tccdir)/win32/lib")
+ $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/win32/include")
+ $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/win32/include")
+endif
+
+# uninstall
+uninstall-unx:
+ @rm -fv $(foreach P,$(PROGS) $(PROGS_CROSS),"$(bindir)/$P")
+ @rm -fv "$(libdir)/libtcc.a" "$(libdir)/libtcc.so" "$(includedir)/libtcc.h"
+ @rm -fv "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
+ @rm -fv "$(docdir)/tcc-doc.html"
+ rm -r "$(tccdir)"
+
+# install progs & libs on windows
+install-win:
+ $(call IBw,$(PROGS) $(PROGS_CROSS) $(subst libtcc.a,,$(LIBTCC)),"$(bindir)")
+ $(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib")
+ $(call IFw,libtcc1.a $(LIBTCC1_W),"$(tccdir)/lib")
+ $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
+ $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include")
+ $(call IR,$(TOPSRC)/win32/examples,"$(tccdir)/examples")
+ $(call IF,$(TOPSRC)/tests/libtcc_test.c,"$(tccdir)/examples")
+ $(call IFw,$(TOPSRC)/libtcc.h $(subst .dll,.def,$(LIBTCC)),"$(libdir)")
+ $(call IFw,$(TOPSRC)/win32/tcc-win32.txt tcc-doc.html,"$(docdir)")
+ifneq "$(wildcard $(LIBTCC1_U))" ""
+ $(call IFw,$(LIBTCC1_U),"$(tccdir)/lib")
+ $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/lib/include")
+endif
+
+# the msys-git shell works to configure && make except it does not have install
+ifeq "$(and $(CONFIG_WIN32),$(shell which install >/dev/null 2>&1 || echo no))" "no"
+install-win : INSTALL = cp
+install-win : INSTALLBIN = cp
+endif
+
+# uninstall on windows
+uninstall-win:
+ @rm -fv $(foreach P,$(PROGS) $(PROGS_CROSS) libtcc.dll,"$(bindir)/$P")
+ @rm -fv $(foreach F,tcc-doc.html tcc-win32.txt,"$(docdir)/$F")
+ @rm -fv $(foreach F,libtcc.h libtcc.def libtcc.a,"$(libdir)/$F")
+ rm -r "$(tccdir)"
+
+# --------------------------------------------------------------------------
+# other stuff
+
+TAGFILES = *.[ch] include/*.h lib/*.[chS]
+tags : ; ctags $(TAGFILES)
+# cannot have both tags and TAGS on windows
+ETAGS : ; etags $(TAGFILES)
+
+# create release tarball from *current* git branch (including tcc-doc.html
+# and converting two files to CRLF)
+TCC-VERSION = tcc-$(VERSION)
+tar: tcc-doc.html
+ mkdir $(TCC-VERSION)
+ ( cd $(TCC-VERSION) && git --git-dir ../.git checkout -f )
+ cp tcc-doc.html $(TCC-VERSION)
+ for f in tcc-win32.txt build-tcc.bat ; do \
+ cat win32/$$f | sed 's,\(.*\),\1\r,g' > $(TCC-VERSION)/win32/$$f ; \
+ done
+ tar cjf $(TCC-VERSION).tar.bz2 $(TCC-VERSION)
+ rm -rf $(TCC-VERSION)
+ git reset
+
+config.mak:
+ $(if $(wildcard $@),,@echo "Please run ./configure." && exit 1)
+
+# run all tests
+test:
+ $(MAKE) -C tests
+# run test(s) from tests2 subdir (see make help)
+tests2.%:
+ $(MAKE) -C tests/tests2 $@
+
+clean:
+ rm -f tcc$(EXESUF) tcc_p$(EXESUF) *-tcc$(EXESUF) tcc.pod
+ rm -f *~ *.o *.a *.so* *.out *.log lib*.def *.exe *.dll a.out tags TAGS
+ @$(MAKE) -C lib $@
+ @$(MAKE) -C tests $@
+
+distclean: clean
+ rm -f config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html
+
+.PHONY: all clean test tar tags ETAGS distclean install uninstall FORCE
+
+help:
+ @echo "make"
+ @echo " build native compiler (from separate objects)"
+ @echo ""
+ @echo "make cross"
+ @echo " build cross compilers (from one source)"
+ @echo ""
+ @echo "make ONE_SOURCE=yes / no"
+ @echo " force building from one source / separate objects"
+ @echo ""
+ @echo "make cross-TARGET"
+ @echo " build one specific cross compiler for 'TARGET', as in"
+ @echo " $(TCC_X)"
+ @echo ""
+ @echo "Custom configuration:"
+ @echo " The makefile includes a file 'config-extra.mak' if it is present."
+ @echo " This file may contain some custom configuration. For example:"
+ @echo ""
+ @echo " NATIVE_DEFINES += -D..."
+ @echo ""
+ @echo " Or for example to configure the search paths for a cross-compiler"
+ @echo " that expects the linux files in <tccdir>/i386-linux:"
+ @echo ""
+ @echo " ROOT-i386 = {B}/i386-linux"
+ @echo " CRT-i386 = {B}/i386-linux/usr/lib"
+ @echo " LIB-i386 = {B}/i386-linux/lib:{B}/i386-linux/usr/lib"
+ @echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include"
+ @echo " DEF-i386 += -D__linux__"
+ @echo ""
+ @echo "make test"
+ @echo " run all tests"
+ @echo ""
+ @echo "make tests2.all / make tests2.37 / make tests2.37+"
+ @echo " run all/single test(s) from tests2, optionally update .expect"
+ @echo ""
+ @echo "Other supported make targets:"
+ @echo " install install-strip tags ETAGS tar clean distclean help"
+ @echo ""
+
+# --------------------------------------------------------------------------
+endif # ($(INCLUDED),no)
diff --git a/README b/README
new file mode 100644
index 0000000..3a3f90b
--- /dev/null
+++ b/README
@@ -0,0 +1,95 @@
+Tiny C Compiler - C Scripting Everywhere - The Smallest ANSI C compiler
+-----------------------------------------------------------------------
+
+Features:
+--------
+
+- SMALL! You can compile and execute C code everywhere, for example on
+ rescue disks.
+
+- FAST! tcc generates optimized x86 code. No byte code
+ overhead. Compile, assemble and link about 7 times faster than 'gcc
+ -O0'.
+
+- UNLIMITED! Any C dynamic library can be used directly. TCC is
+ heading torward full ISOC99 compliance. TCC can of course compile
+ itself.
+
+- SAFE! tcc includes an optional memory and bound checker. Bound
+ checked code can be mixed freely with standard code.
+
+- Compile and execute C source directly. No linking or assembly
+ necessary. Full C preprocessor included.
+
+- C script supported : just add '#!/usr/local/bin/tcc -run' at the first
+ line of your C source, and execute it directly from the command
+ line.
+
+Documentation:
+-------------
+
+1) Installation on a i386/x86_64/arm Linux/OSX/FreeBSD host
+
+ ./configure
+ make
+ make test
+ make install
+
+ Notes: For OSX and FreeBSD, gmake should be used instead of make.
+ For Windows read tcc-win32.txt.
+
+makeinfo must be installed to compile the doc. By default, tcc is
+installed in /usr/local/bin. ./configure --help shows configuration
+options.
+
+
+2) Introduction
+
+We assume here that you know ANSI C. Look at the example ex1.c to know
+what the programs look like.
+
+The include file <tcclib.h> can be used if you want a small basic libc
+include support (especially useful for floppy disks). Of course, you
+can also use standard headers, although they are slower to compile.
+
+You can begin your C script with '#!/usr/local/bin/tcc -run' on the first
+line and set its execute bits (chmod a+x your_script). Then, you can
+launch the C code as a shell or perl script :-) The command line
+arguments are put in 'argc' and 'argv' of the main functions, as in
+ANSI C.
+
+3) Examples
+
+ex1.c: simplest example (hello world). Can also be launched directly
+as a script: './ex1.c'.
+
+ex2.c: more complicated example: find a number with the four
+operations given a list of numbers (benchmark).
+
+ex3.c: compute fibonacci numbers (benchmark).
+
+ex4.c: more complicated: X11 program. Very complicated test in fact
+because standard headers are being used ! As for ex1.c, can also be launched
+directly as a script: './ex4.c'.
+
+ex5.c: 'hello world' with standard glibc headers.
+
+tcc.c: TCC can of course compile itself. Used to check the code
+generator.
+
+tcctest.c: auto test for TCC which tests many subtle possible bugs. Used
+when doing 'make test'.
+
+4) Full Documentation
+
+Please read tcc-doc.html to have all the features of TCC.
+
+Additional information is available for the Windows port in tcc-win32.txt.
+
+License:
+-------
+
+TCC is distributed under the GNU Lesser General Public License (see
+COPYING file).
+
+Fabrice Bellard.
diff --git a/RELICENSING b/RELICENSING
new file mode 100644
index 0000000..20841a7
--- /dev/null
+++ b/RELICENSING
@@ -0,0 +1,60 @@
+
+ Relicensing TinyCC
+ ------------------
+
+ The authors listed below hereby confirm their agreement to relicense TinyCC
+ including their past contributions under the following terms:
+
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+
+
+ Author (name) I agree (YES/NO) Files/Features (optional)
+ ------------------------------------------------------------------------------
+ Adam Sampson YES makefiles
+ Daniel Glöckner NO arm-gen.c
+ Daniel Glöckner YES not arm-gen.c
+ Edmund Grimley Evans YES arm64
+ Fabrice Bellard YES original author
+ Frédéric Féret YES x86 64/16 bit asm
+ grischka YES tccpe.c
+ Henry Kroll YES
+ Joe Soroka YES
+ Kirill Smelkov YES
+ mingodad YES
+ Pip Cet YES
+ Shinichiro Hamaji YES x86_64-gen.c
+ Vincent Lefèvre YES
+ Thomas Preud'homme YES arm-gen.c
+ Timo VJ Lähde (Timppa) ? tiny_libmaker.c
+ TK ? tcccoff.c c67-gen.c
+ Urs Janssen YES
+ waddlesplash YES
+ Christian Jullien YES Windows Cygwin build and tests
+
+
+ ------------------------------------------------------------------------------
+
+ Please add yourself to the list above (rsp. replace the question mark)
+ and (after fetching the latest version) commit to the "mob" branch with
+ commit message:
+
+ Relicensing TinyCC
+
+ Thanks.
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..d810088
--- /dev/null
+++ b/TODO
@@ -0,0 +1,100 @@
+TODO list:
+
+Bugs:
+
+- i386 fastcall is mostly wrong
+- FPU st(0) is left unclean (kwisatz haderach). Incompatible with
+ optimized gcc/msc code
+- see transparent union pb in /urs/include/sys/socket.h
+- precise behaviour of typeof with arrays ? (__put_user macro)
+ but should suffice for most cases)
+- handle '? x, y : z' in unsized variable initialization (',' is
+ considered incorrectly as separator in preparser)
+- transform functions to function pointers in function parameters
+ (net/ipv4/ip_output.c)
+- fix function pointer type display
+- check section alignment in C
+- fix invalid cast in comparison 'if (v == (int8_t)v)'
+- finish varargs.h support (gcc 3.2 testsuite issue)
+- fix static functions declared inside block
+- fix multiple unions init
+- make libtcc fully reentrant (except for the compilation stage itself).
+- struct/union/enum definitions in nested scopes (see also Debian bug #770657)
+- __STDC_IEC_559__: float f(void) { static float x = 0.0 / 0.0; return x; }
+- memory may be leaked after errors (longjmp).
+
+Portability:
+
+- it is assumed that int is 32-bit and sizeof(int) == 4
+- int is used when host or target size_t would make more sense
+- TCC handles target floating-point (fp) values using the host's fp
+ arithmetic, which is simple and fast but may lead to exceptions
+ and inaccuracy and wrong representations when cross-compiling
+
+Linking:
+
+- static linking (-static) does not work
+
+Bound checking:
+
+- fix bound exit on RedHat 7.3
+- setjmp is not supported properly in bound checking.
+- fix bound check code with '&' on local variables (currently done
+ only for local arrays).
+- bound checking and float/long long/struct copy code. bound
+ checking and symbol + offset optimization
+
+Missing features:
+
+- disable-asm and disable-bcheck options
+- __builtin_expect()
+- atexit (Nigel Horne)
+- C99: add complex types (gcc 3.2 testsuite issue)
+- postfix compound literals (see 20010124-1.c)
+- interactive mode / integrated debugger
+
+Optimizations:
+
+- suppress specific anonymous symbol handling
+- more parse optimizations (=even faster compilation)
+- memory alloc optimizations (=even faster compilation)
+- optimize VT_LOCAL + const
+- better local variables handling (needed for other targets)
+
+Not critical:
+
+- C99: fix multiple compound literals inits in blocks (ISOC99
+ normative example - only relevant when using gotos! -> must add
+ boolean variable to tell if compound literal was already
+ initialized).
+- add PowerPC generator and improve codegen for RISC (need
+ to suppress VT_LOCAL and use a base register instead).
+- fix preprocessor symbol redefinition
+- add portable byte code generator and interpreter for other
+ unsupported architectures.
+- C++: variable declaration in for, minimal 'class' support.
+- win32: __intxx. use resolve for bchecked malloc et al.
+ check exception code (exception filter func).
+- handle void (__attribute__() *ptr)()
+- VLAs are implemented in a way that is not compatible with signals:
+ http://lists.gnu.org/archive/html/tinycc-devel/2015-11/msg00018.html
+
+Fixed (probably):
+
+- bug with defines:
+ #define spin_lock(lock) do { } while (0)
+ #define wq_spin_lock spin_lock
+ #define TEST() wq_spin_lock(a)
+- typedefs can be structure fields
+- see bugfixes.diff + improvement.diff from Daniel Glockner
+- long long constant evaluation
+- add alloca()
+- gcc '-E' option.
+- #include_next support for /usr/include/limits ?
+- function pointers/lvalues in ? : (linux kernel net/core/dev.c)
+- win32: add __stdcall, check GetModuleHandle for dlls.
+- macro substitution with nested definitions (ShangHongzhang)
+- with "-run" and libtcc, a PLT is now built.
+- '-E' option was improved
+- packed attribute is now supported
+- ARM and ARM64 code generators have been added.
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..9a54223
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.9.27
diff --git a/arm-asm.c b/arm-asm.c
new file mode 100644
index 0000000..3b5ae66
--- /dev/null
+++ b/arm-asm.c
@@ -0,0 +1,94 @@
+/*************************************************************/
+/*
+ * ARM dummy assembler for TCC
+ *
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+#define CONFIG_TCC_ASM
+#define NB_ASM_REGS 16
+
+ST_FUNC void g(int c);
+ST_FUNC void gen_le16(int c);
+ST_FUNC void gen_le32(int c);
+
+/*************************************************************/
+#else
+/*************************************************************/
+
+#include "tcc.h"
+
+static void asm_error(void)
+{
+ tcc_error("ARM asm not implemented.");
+}
+
+/* XXX: make it faster ? */
+ST_FUNC void g(int c)
+{
+ int ind1;
+ if (nocode_wanted)
+ return;
+ ind1 = ind + 1;
+ if (ind1 > cur_text_section->data_allocated)
+ section_realloc(cur_text_section, ind1);
+ cur_text_section->data[ind] = c;
+ ind = ind1;
+}
+
+ST_FUNC void gen_le16 (int i)
+{
+ g(i);
+ g(i>>8);
+}
+
+ST_FUNC void gen_le32 (int i)
+{
+ gen_le16(i);
+ gen_le16(i>>16);
+}
+
+ST_FUNC void gen_expr32(ExprValue *pe)
+{
+ gen_le32(pe->v);
+}
+
+ST_FUNC void asm_opcode(TCCState *s1, int opcode)
+{
+ asm_error();
+}
+
+ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
+{
+ asm_error();
+}
+
+/* generate prolog and epilog code for asm statement */
+ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
+ int nb_outputs, int is_output,
+ uint8_t *clobber_regs,
+ int out_reg)
+{
+}
+
+ST_FUNC void asm_compute_constraints(ASMOperand *operands,
+ int nb_operands, int nb_outputs,
+ const uint8_t *clobber_regs,
+ int *pout_reg)
+{
+}
+
+ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
+{
+ asm_error();
+}
+
+ST_FUNC int asm_parse_regvar (int t)
+{
+ asm_error();
+ return -1;
+}
+
+/*************************************************************/
+#endif /* ndef TARGET_DEFS_ONLY */
diff --git a/arm-gen.c b/arm-gen.c
new file mode 100644
index 0000000..f535a09
--- /dev/null
+++ b/arm-gen.c
@@ -0,0 +1,2151 @@
+/*
+ * ARMv4 code generator for TCC
+ *
+ * Copyright (c) 2003 Daniel Glöckner
+ * Copyright (c) 2012 Thomas Preud'homme
+ *
+ * Based on i386-gen.c by Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+#if defined(TCC_ARM_EABI) && !defined(TCC_ARM_VFP)
+#error "Currently TinyCC only supports float computation with VFP instructions"
+#endif
+
+/* number of available registers */
+#ifdef TCC_ARM_VFP
+#define NB_REGS 13
+#else
+#define NB_REGS 9
+#endif
+
+#ifndef TCC_CPU_VERSION
+# define TCC_CPU_VERSION 5
+#endif
+
+/* a register can belong to several classes. The classes must be
+ sorted from more general to more precise (see gv2() code which does
+ assumptions on it). */
+#define RC_INT 0x0001 /* generic integer register */
+#define RC_FLOAT 0x0002 /* generic float register */
+#define RC_R0 0x0004
+#define RC_R1 0x0008
+#define RC_R2 0x0010
+#define RC_R3 0x0020
+#define RC_R12 0x0040
+#define RC_F0 0x0080
+#define RC_F1 0x0100
+#define RC_F2 0x0200
+#define RC_F3 0x0400
+#ifdef TCC_ARM_VFP
+#define RC_F4 0x0800
+#define RC_F5 0x1000
+#define RC_F6 0x2000
+#define RC_F7 0x4000
+#endif
+#define RC_IRET RC_R0 /* function return: integer register */
+#define RC_LRET RC_R1 /* function return: second integer register */
+#define RC_FRET RC_F0 /* function return: float register */
+
+/* pretty names for the registers */
+enum {
+ TREG_R0 = 0,
+ TREG_R1,
+ TREG_R2,
+ TREG_R3,
+ TREG_R12,
+ TREG_F0,
+ TREG_F1,
+ TREG_F2,
+ TREG_F3,
+#ifdef TCC_ARM_VFP
+ TREG_F4,
+ TREG_F5,
+ TREG_F6,
+ TREG_F7,
+#endif
+ TREG_SP = 13,
+ TREG_LR,
+};
+
+#ifdef TCC_ARM_VFP
+#define T2CPR(t) (((t) & VT_BTYPE) != VT_FLOAT ? 0x100 : 0)
+#endif
+
+/* return registers for function */
+#define REG_IRET TREG_R0 /* single word int return register */
+#define REG_LRET TREG_R1 /* second word return register (for long long) */
+#define REG_FRET TREG_F0 /* float return register */
+
+#ifdef TCC_ARM_EABI
+#define TOK___divdi3 TOK___aeabi_ldivmod
+#define TOK___moddi3 TOK___aeabi_ldivmod
+#define TOK___udivdi3 TOK___aeabi_uldivmod
+#define TOK___umoddi3 TOK___aeabi_uldivmod
+#endif
+
+/* defined if function parameters must be evaluated in reverse order */
+#define INVERT_FUNC_PARAMS
+
+/* defined if structures are passed as pointers. Otherwise structures
+ are directly pushed on stack. */
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#ifdef TCC_ARM_VFP
+#define LDOUBLE_SIZE 8
+#endif
+
+#ifndef LDOUBLE_SIZE
+#define LDOUBLE_SIZE 8
+#endif
+
+#ifdef TCC_ARM_EABI
+#define LDOUBLE_ALIGN 8
+#else
+#define LDOUBLE_ALIGN 4
+#endif
+
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN 8
+
+#define CHAR_IS_UNSIGNED
+
+/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+
+enum float_abi float_abi;
+
+ST_DATA const int reg_classes[NB_REGS] = {
+ /* r0 */ RC_INT | RC_R0,
+ /* r1 */ RC_INT | RC_R1,
+ /* r2 */ RC_INT | RC_R2,
+ /* r3 */ RC_INT | RC_R3,
+ /* r12 */ RC_INT | RC_R12,
+ /* f0 */ RC_FLOAT | RC_F0,
+ /* f1 */ RC_FLOAT | RC_F1,
+ /* f2 */ RC_FLOAT | RC_F2,
+ /* f3 */ RC_FLOAT | RC_F3,
+#ifdef TCC_ARM_VFP
+ /* d4/s8 */ RC_FLOAT | RC_F4,
+/* d5/s10 */ RC_FLOAT | RC_F5,
+/* d6/s12 */ RC_FLOAT | RC_F6,
+/* d7/s14 */ RC_FLOAT | RC_F7,
+#endif
+};
+
+static int func_sub_sp_offset, last_itod_magic;
+static int leaffunc;
+
+#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
+static CType float_type, double_type, func_float_type, func_double_type;
+ST_FUNC void arm_init(struct TCCState *s)
+{
+ float_type.t = VT_FLOAT;
+ double_type.t = VT_DOUBLE;
+ func_float_type.t = VT_FUNC;
+ func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD);
+ func_double_type.t = VT_FUNC;
+ func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
+
+ float_abi = s->float_abi;
+#ifndef TCC_ARM_HARDFLOAT
+ tcc_warning("soft float ABI currently not supported: default to softfp");
+#endif
+}
+#else
+#define func_float_type func_old_type
+#define func_double_type func_old_type
+#define func_ldouble_type func_old_type
+ST_FUNC void arm_init(struct TCCState *s)
+{
+#if 0
+#if !defined (TCC_ARM_VFP)
+ tcc_warning("Support for FPA is deprecated and will be removed in next"
+ " release");
+#endif
+#if !defined (TCC_ARM_EABI)
+ tcc_warning("Support for OABI is deprecated and will be removed in next"
+ " release");
+#endif
+#endif
+}
+#endif
+
+static int two2mask(int a,int b) {
+ return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
+}
+
+static int regmask(int r) {
+ return reg_classes[r]&~(RC_INT|RC_FLOAT);
+}
+
+/******************************************************/
+
+#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
+const char *default_elfinterp(struct TCCState *s)
+{
+ if (s->float_abi == ARM_HARD_FLOAT)
+ return "/lib/ld-linux-armhf.so.3";
+ else
+ return "/lib/ld-linux.so.3";
+}
+#endif
+
+void o(uint32_t i)
+{
+ /* this is a good place to start adding big-endian support*/
+ int ind1;
+ if (nocode_wanted)
+ return;
+ ind1 = ind + 4;
+ if (!cur_text_section)
+ tcc_error("compiler error! This happens f.ex. if the compiler\n"
+ "can't evaluate constant expressions outside of a function.");
+ if (ind1 > cur_text_section->data_allocated)
+ section_realloc(cur_text_section, ind1);
+ cur_text_section->data[ind++] = i&255;
+ i>>=8;
+ cur_text_section->data[ind++] = i&255;
+ i>>=8;
+ cur_text_section->data[ind++] = i&255;
+ i>>=8;
+ cur_text_section->data[ind++] = i;
+}
+
+static uint32_t stuff_const(uint32_t op, uint32_t c)
+{
+ int try_neg=0;
+ uint32_t nc = 0, negop = 0;
+
+ switch(op&0x1F00000)
+ {
+ case 0x800000: //add
+ case 0x400000: //sub
+ try_neg=1;
+ negop=op^0xC00000;
+ nc=-c;
+ break;
+ case 0x1A00000: //mov
+ case 0x1E00000: //mvn
+ try_neg=1;
+ negop=op^0x400000;
+ nc=~c;
+ break;
+ case 0x200000: //xor
+ if(c==~0)
+ return (op&0xF010F000)|((op>>16)&0xF)|0x1E00000;
+ break;
+ case 0x0: //and
+ if(c==~0)
+ return (op&0xF010F000)|((op>>16)&0xF)|0x1A00000;
+ case 0x1C00000: //bic
+ try_neg=1;
+ negop=op^0x1C00000;
+ nc=~c;
+ break;
+ case 0x1800000: //orr
+ if(c==~0)
+ return (op&0xFFF0FFFF)|0x1E00000;
+ break;
+ }
+ do {
+ uint32_t m;
+ int i;
+ if(c<256) /* catch undefined <<32 */
+ return op|c;
+ for(i=2;i<32;i+=2) {
+ m=(0xff>>i)|(0xff<<(32-i));
+ if(!(c&~m))
+ return op|(i<<7)|(c<<i)|(c>>(32-i));
+ }
+ op=negop;
+ c=nc;
+ } while(try_neg--);
+ return 0;
+}
+
+
+//only add,sub
+void stuff_const_harder(uint32_t op, uint32_t v) {
+ uint32_t x;
+ x=stuff_const(op,v);
+ if(x)
+ o(x);
+ else {
+ uint32_t a[16], nv, no, o2, n2;
+ int i,j,k;
+ a[0]=0xff;
+ o2=(op&0xfff0ffff)|((op&0xf000)<<4);;
+ for(i=1;i<16;i++)
+ a[i]=(a[i-1]>>2)|(a[i-1]<<30);
+ for(i=0;i<12;i++)
+ for(j=i<4?i+12:15;j>=i+4;j--)
+ if((v&(a[i]|a[j]))==v) {
+ o(stuff_const(op,v&a[i]));
+ o(stuff_const(o2,v&a[j]));
+ return;
+ }
+ no=op^0xC00000;
+ n2=o2^0xC00000;
+ nv=-v;
+ for(i=0;i<12;i++)
+ for(j=i<4?i+12:15;j>=i+4;j--)
+ if((nv&(a[i]|a[j]))==nv) {
+ o(stuff_const(no,nv&a[i]));
+ o(stuff_const(n2,nv&a[j]));
+ return;
+ }
+ for(i=0;i<8;i++)
+ for(j=i+4;j<12;j++)
+ for(k=i<4?i+12:15;k>=j+4;k--)
+ if((v&(a[i]|a[j]|a[k]))==v) {
+ o(stuff_const(op,v&a[i]));
+ o(stuff_const(o2,v&a[j]));
+ o(stuff_const(o2,v&a[k]));
+ return;
+ }
+ no=op^0xC00000;
+ nv=-v;
+ for(i=0;i<8;i++)
+ for(j=i+4;j<12;j++)
+ for(k=i<4?i+12:15;k>=j+4;k--)
+ if((nv&(a[i]|a[j]|a[k]))==nv) {
+ o(stuff_const(no,nv&a[i]));
+ o(stuff_const(n2,nv&a[j]));
+ o(stuff_const(n2,nv&a[k]));
+ return;
+ }
+ o(stuff_const(op,v&a[0]));
+ o(stuff_const(o2,v&a[4]));
+ o(stuff_const(o2,v&a[8]));
+ o(stuff_const(o2,v&a[12]));
+ }
+}
+
+uint32_t encbranch(int pos, int addr, int fail)
+{
+ addr-=pos+8;
+ addr/=4;
+ if(addr>=0x1000000 || addr<-0x1000000) {
+ if(fail)
+ tcc_error("FIXME: function bigger than 32MB");
+ return 0;
+ }
+ return 0x0A000000|(addr&0xffffff);
+}
+
+int decbranch(int pos)
+{
+ int x;
+ x=*(uint32_t *)(cur_text_section->data + pos);
+ x&=0x00ffffff;
+ if(x&0x800000)
+ x-=0x1000000;
+ return x*4+pos+8;
+}
+
+/* output a symbol and patch all calls to it */
+void gsym_addr(int t, int a)
+{
+ uint32_t *x;
+ int lt;
+ while(t) {
+ x=(uint32_t *)(cur_text_section->data + t);
+ t=decbranch(lt=t);
+ if(a==lt+4)
+ *x=0xE1A00000; // nop
+ else {
+ *x &= 0xff000000;
+ *x |= encbranch(lt,a,1);
+ }
+ }
+}
+
+void gsym(int t)
+{
+ gsym_addr(t, ind);
+}
+
+#ifdef TCC_ARM_VFP
+static uint32_t vfpr(int r)
+{
+ if(r<TREG_F0 || r>TREG_F7)
+ tcc_error("compiler error! register %i is no vfp register",r);
+ return r - TREG_F0;
+}
+#else
+static uint32_t fpr(int r)
+{
+ if(r<TREG_F0 || r>TREG_F3)
+ tcc_error("compiler error! register %i is no fpa register",r);
+ return r - TREG_F0;
+}
+#endif
+
+static uint32_t intr(int r)
+{
+ if(r == TREG_R12)
+ return 12;
+ if(r >= TREG_R0 && r <= TREG_R3)
+ return r - TREG_R0;
+ if (r >= TREG_SP && r <= TREG_LR)
+ return r + (13 - TREG_SP);
+ tcc_error("compiler error! register %i is no int register",r);
+}
+
+static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift)
+{
+ if(*off>maxoff || *off&((1<<shift)-1)) {
+ uint32_t x, y;
+ x=0xE280E000;
+ if(*sgn)
+ x=0xE240E000;
+ x|=(*base)<<16;
+ *base=14; // lr
+ y=stuff_const(x,*off&~maxoff);
+ if(y) {
+ o(y);
+ *off&=maxoff;
+ return;
+ }
+ y=stuff_const(x,(*off+maxoff)&~maxoff);
+ if(y) {
+ o(y);
+ *sgn=!*sgn;
+ *off=((*off+maxoff)&~maxoff)-*off;
+ return;
+ }
+ stuff_const_harder(x,*off&~maxoff);
+ *off&=maxoff;
+ }
+}
+
+static uint32_t mapcc(int cc)
+{
+ switch(cc)
+ {
+ case TOK_ULT:
+ return 0x30000000; /* CC/LO */
+ case TOK_UGE:
+ return 0x20000000; /* CS/HS */
+ case TOK_EQ:
+ return 0x00000000; /* EQ */
+ case TOK_NE:
+ return 0x10000000; /* NE */
+ case TOK_ULE:
+ return 0x90000000; /* LS */
+ case TOK_UGT:
+ return 0x80000000; /* HI */
+ case TOK_Nset:
+ return 0x40000000; /* MI */
+ case TOK_Nclear:
+ return 0x50000000; /* PL */
+ case TOK_LT:
+ return 0xB0000000; /* LT */
+ case TOK_GE:
+ return 0xA0000000; /* GE */
+ case TOK_LE:
+ return 0xD0000000; /* LE */
+ case TOK_GT:
+ return 0xC0000000; /* GT */
+ }
+ tcc_error("unexpected condition code");
+ return 0xE0000000; /* AL */
+}
+
+static int negcc(int cc)
+{
+ switch(cc)
+ {
+ case TOK_ULT:
+ return TOK_UGE;
+ case TOK_UGE:
+ return TOK_ULT;
+ case TOK_EQ:
+ return TOK_NE;
+ case TOK_NE:
+ return TOK_EQ;
+ case TOK_ULE:
+ return TOK_UGT;
+ case TOK_UGT:
+ return TOK_ULE;
+ case TOK_Nset:
+ return TOK_Nclear;
+ case TOK_Nclear:
+ return TOK_Nset;
+ case TOK_LT:
+ return TOK_GE;
+ case TOK_GE:
+ return TOK_LT;
+ case TOK_LE:
+ return TOK_GT;
+ case TOK_GT:
+ return TOK_LE;
+ }
+ tcc_error("unexpected condition code");
+ return TOK_NE;
+}
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue *sv)
+{
+ int v, ft, fc, fr, sign;
+ uint32_t op;
+ SValue v1;
+
+ fr = sv->r;
+ ft = sv->type.t;
+ fc = sv->c.i;
+
+ if(fc>=0)
+ sign=0;
+ else {
+ sign=1;
+ fc=-fc;
+ }
+
+ v = fr & VT_VALMASK;
+ if (fr & VT_LVAL) {
+ uint32_t base = 0xB; // fp
+ if(v == VT_LLOCAL) {
+ v1.type.t = VT_PTR;
+ v1.r = VT_LOCAL | VT_LVAL;
+ v1.c.i = sv->c.i;
+ load(TREG_LR, &v1);
+ base = 14; /* lr */
+ fc=sign=0;
+ v=VT_LOCAL;
+ } else if(v == VT_CONST) {
+ v1.type.t = VT_PTR;
+ v1.r = fr&~VT_LVAL;
+ v1.c.i = sv->c.i;
+ v1.sym=sv->sym;
+ load(TREG_LR, &v1);
+ base = 14; /* lr */
+ fc=sign=0;
+ v=VT_LOCAL;
+ } else if(v < VT_CONST) {
+ base=intr(v);
+ fc=sign=0;
+ v=VT_LOCAL;
+ }
+ if(v == VT_LOCAL) {
+ if(is_float(ft)) {
+ calcaddr(&base,&fc,&sign,1020,2);
+#ifdef TCC_ARM_VFP
+ op=0xED100A00; /* flds */
+ if(!sign)
+ op|=0x800000;
+ if ((ft & VT_BTYPE) != VT_FLOAT)
+ op|=0x100; /* flds -> fldd */
+ o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
+#else
+ op=0xED100100;
+ if(!sign)
+ op|=0x800000;
+#if LDOUBLE_SIZE == 8
+ if ((ft & VT_BTYPE) != VT_FLOAT)
+ op|=0x8000;
+#else
+ if ((ft & VT_BTYPE) == VT_DOUBLE)
+ op|=0x8000;
+ else if ((ft & VT_BTYPE) == VT_LDOUBLE)
+ op|=0x400000;
+#endif
+ o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
+#endif
+ } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE
+ || (ft & VT_BTYPE) == VT_SHORT) {
+ calcaddr(&base,&fc,&sign,255,0);
+ op=0xE1500090;
+ if ((ft & VT_BTYPE) == VT_SHORT)
+ op|=0x20;
+ if ((ft & VT_UNSIGNED) == 0)
+ op|=0x40;
+ if(!sign)
+ op|=0x800000;
+ o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
+ } else {
+ calcaddr(&base,&fc,&sign,4095,0);
+ op=0xE5100000;
+ if(!sign)
+ op|=0x800000;
+ if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
+ op|=0x400000;
+ o(op|(intr(r)<<12)|fc|(base<<16));
+ }
+ return;
+ }
+ } else {
+ if (v == VT_CONST) {
+ op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.i);
+ if (fr & VT_SYM || !op) {
+ o(0xE59F0000|(intr(r)<<12));
+ o(0xEA000000);
+ if(fr & VT_SYM)
+ greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
+ o(sv->c.i);
+ } else
+ o(op);
+ return;
+ } else if (v == VT_LOCAL) {
+ op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.i);
+ if (fr & VT_SYM || !op) {
+ o(0xE59F0000|(intr(r)<<12));
+ o(0xEA000000);
+ if(fr & VT_SYM) // needed ?
+ greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
+ o(sv->c.i);
+ o(0xE08B0000|(intr(r)<<12)|intr(r));
+ } else
+ o(op);
+ return;
+ } else if(v == VT_CMP) {
+ o(mapcc(sv->c.i)|0x3A00001|(intr(r)<<12));
+ o(mapcc(negcc(sv->c.i))|0x3A00000|(intr(r)<<12));
+ return;
+ } else if (v == VT_JMP || v == VT_JMPI) {
+ int t;
+ t = v & 1;
+ o(0xE3A00000|(intr(r)<<12)|t);
+ o(0xEA000000);
+ gsym(sv->c.i);
+ o(0xE3A00000|(intr(r)<<12)|(t^1));
+ return;
+ } else if (v < VT_CONST) {
+ if(is_float(ft))
+#ifdef TCC_ARM_VFP
+ o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */
+#else
+ o(0xEE008180|(fpr(r)<<12)|fpr(v));
+#endif
+ else
+ o(0xE1A00000|(intr(r)<<12)|intr(v));
+ return;
+ }
+ }
+ tcc_error("load unimplemented!");
+}
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue *sv)
+{
+ SValue v1;
+ int v, ft, fc, fr, sign;
+ uint32_t op;
+
+ fr = sv->r;
+ ft = sv->type.t;
+ fc = sv->c.i;
+
+ if(fc>=0)
+ sign=0;
+ else {
+ sign=1;
+ fc=-fc;
+ }
+
+ v = fr & VT_VALMASK;
+ if (fr & VT_LVAL || fr == VT_LOCAL) {
+ uint32_t base = 0xb; /* fp */
+ if(v < VT_CONST) {
+ base=intr(v);
+ v=VT_LOCAL;
+ fc=sign=0;
+ } else if(v == VT_CONST) {
+ v1.type.t = ft;
+ v1.r = fr&~VT_LVAL;
+ v1.c.i = sv->c.i;
+ v1.sym=sv->sym;
+ load(TREG_LR, &v1);
+ base = 14; /* lr */
+ fc=sign=0;
+ v=VT_LOCAL;
+ }
+ if(v == VT_LOCAL) {
+ if(is_float(ft)) {
+ calcaddr(&base,&fc,&sign,1020,2);
+#ifdef TCC_ARM_VFP
+ op=0xED000A00; /* fsts */
+ if(!sign)
+ op|=0x800000;
+ if ((ft & VT_BTYPE) != VT_FLOAT)
+ op|=0x100; /* fsts -> fstd */
+ o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
+#else
+ op=0xED000100;
+ if(!sign)
+ op|=0x800000;
+#if LDOUBLE_SIZE == 8
+ if ((ft & VT_BTYPE) != VT_FLOAT)
+ op|=0x8000;
+#else
+ if ((ft & VT_BTYPE) == VT_DOUBLE)
+ op|=0x8000;
+ if ((ft & VT_BTYPE) == VT_LDOUBLE)
+ op|=0x400000;
+#endif
+ o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
+#endif
+ return;
+ } else if((ft & VT_BTYPE) == VT_SHORT) {
+ calcaddr(&base,&fc,&sign,255,0);
+ op=0xE14000B0;
+ if(!sign)
+ op|=0x800000;
+ o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
+ } else {
+ calcaddr(&base,&fc,&sign,4095,0);
+ op=0xE5000000;
+ if(!sign)
+ op|=0x800000;
+ if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
+ op|=0x400000;
+ o(op|(intr(r)<<12)|fc|(base<<16));
+ }
+ return;
+ }
+ }
+ tcc_error("store unimplemented");
+}
+
+static void gadd_sp(int val)
+{
+ stuff_const_harder(0xE28DD000,val);
+}
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+ int r;
+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+ uint32_t x;
+ /* constant case */
+ x=encbranch(ind,ind+vtop->c.i,0);
+ if(x) {
+ if (vtop->r & VT_SYM) {
+ /* relocation case */
+ greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);
+ } else
+ put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24, 0);
+ o(x|(is_jmp?0xE0000000:0xE1000000));
+ } else {
+ if(!is_jmp)
+ o(0xE28FE004); // add lr,pc,#4
+ o(0xE51FF004); // ldr pc,[pc,#-4]
+ if (vtop->r & VT_SYM)
+ greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32);
+ o(vtop->c.i);
+ }
+ } else {
+ /* otherwise, indirect call */
+ r = gv(RC_INT);
+ if(!is_jmp)
+ o(0xE1A0E00F); // mov lr,pc
+ o(0xE1A0F000|intr(r)); // mov pc,r
+ }
+}
+
+static int unalias_ldbl(int btype)
+{
+#if LDOUBLE_SIZE == 8
+ if (btype == VT_LDOUBLE)
+ btype = VT_DOUBLE;
+#endif
+ return btype;
+}
+
+/* Return whether a structure is an homogeneous float aggregate or not.
+ The answer is true if all the elements of the structure are of the same
+ primitive float type and there is less than 4 elements.
+
+ type: the type corresponding to the structure to be tested */
+static int is_hgen_float_aggr(CType *type)
+{
+ if ((type->t & VT_BTYPE) == VT_STRUCT) {
+ struct Sym *ref;
+ int btype, nb_fields = 0;
+
+ ref = type->ref->next;
+ btype = unalias_ldbl(ref->type.t & VT_BTYPE);
+ if (btype == VT_FLOAT || btype == VT_DOUBLE) {
+ for(; ref && btype == unalias_ldbl(ref->type.t & VT_BTYPE); ref = ref->next, nb_fields++);
+ return !ref && nb_fields <= 4;
+ }
+ }
+ return 0;
+}
+
+struct avail_regs {
+ signed char avail[3]; /* 3 holes max with only float and double alignments */
+ int first_hole; /* first available hole */
+ int last_hole; /* last available hole (none if equal to first_hole) */
+ int first_free_reg; /* next free register in the sequence, hole excluded */
+};
+
+#define AVAIL_REGS_INITIALIZER (struct avail_regs) { { 0, 0, 0}, 0, 0, 0 }
+
+/* Find suitable registers for a VFP Co-Processor Register Candidate (VFP CPRC
+ param) according to the rules described in the procedure call standard for
+ the ARM architecture (AAPCS). If found, the registers are assigned to this
+ VFP CPRC parameter. Registers are allocated in sequence unless a hole exists
+ and the parameter is a single float.
+
+ avregs: opaque structure to keep track of available VFP co-processor regs
+ align: alignment constraints for the param, as returned by type_size()
+ size: size of the parameter, as returned by type_size() */
+int assign_vfpreg(struct avail_regs *avregs, int align, int size)
+{
+ int first_reg = 0;
+
+ if (avregs->first_free_reg == -1)
+ return -1;
+ if (align >> 3) { /* double alignment */
+ first_reg = avregs->first_free_reg;
+ /* alignment constraint not respected so use next reg and record hole */
+ if (first_reg & 1)
+ avregs->avail[avregs->last_hole++] = first_reg++;
+ } else { /* no special alignment (float or array of float) */
+ /* if single float and a hole is available, assign the param to it */
+ if (size == 4 && avregs->first_hole != avregs->last_hole)
+ return avregs->avail[avregs->first_hole++];
+ else
+ first_reg = avregs->first_free_reg;
+ }
+ if (first_reg + size / 4 <= 16) {
+ avregs->first_free_reg = first_reg + size / 4;
+ return first_reg;
+ }
+ avregs->first_free_reg = -1;
+ return -1;
+}
+
+/* Returns whether all params need to be passed in core registers or not.
+ This is the case for function part of the runtime ABI. */
+int floats_in_core_regs(SValue *sval)
+{
+ if (!sval->sym)
+ return 0;
+
+ switch (sval->sym->v) {
+ case TOK___floatundisf:
+ case TOK___floatundidf:
+ case TOK___fixunssfdi:
+ case TOK___fixunsdfdi:
+#ifndef TCC_ARM_VFP
+ case TOK___fixunsxfdi:
+#endif
+ case TOK___floatdisf:
+ case TOK___floatdidf:
+ case TOK___fixsfdi:
+ case TOK___fixdfdi:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+/* Return the number of registers needed to return the struct, or 0 if
+ returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) {
+#ifdef TCC_ARM_EABI
+ int size, align;
+ size = type_size(vt, &align);
+ if (float_abi == ARM_HARD_FLOAT && !variadic &&
+ (is_float(vt->t) || is_hgen_float_aggr(vt))) {
+ *ret_align = 8;
+ *regsize = 8;
+ ret->ref = NULL;
+ ret->t = VT_DOUBLE;
+ return (size + 7) >> 3;
+ } else if (size <= 4) {
+ *ret_align = 4;
+ *regsize = 4;
+ ret->ref = NULL;
+ ret->t = VT_INT;
+ return 1;
+ } else
+ return 0;
+#else
+ return 0;
+#endif
+}
+
+/* Parameters are classified according to how they are copied to their final
+ destination for the function call. Because the copying is performed class
+ after class according to the order in the union below, it is important that
+ some constraints about the order of the members of this union are respected:
+ - CORE_STRUCT_CLASS must come after STACK_CLASS;
+ - CORE_CLASS must come after STACK_CLASS, CORE_STRUCT_CLASS and
+ VFP_STRUCT_CLASS;
+ - VFP_STRUCT_CLASS must come after VFP_CLASS.
+ See the comment for the main loop in copy_params() for the reason. */
+enum reg_class {
+ STACK_CLASS = 0,
+ CORE_STRUCT_CLASS,
+ VFP_CLASS,
+ VFP_STRUCT_CLASS,
+ CORE_CLASS,
+ NB_CLASSES
+};
+
+struct param_plan {
+ int start; /* first reg or addr used depending on the class */
+ int end; /* last reg used or next free addr depending on the class */
+ SValue *sval; /* pointer to SValue on the value stack */
+ struct param_plan *prev; /* previous element in this class */
+};
+
+struct plan {
+ struct param_plan *pplans; /* array of all the param plans */
+ struct param_plan *clsplans[NB_CLASSES]; /* per class lists of param plans */
+};
+
+#define add_param_plan(plan,pplan,class) \
+ do { \
+ pplan.prev = plan->clsplans[class]; \
+ plan->pplans[plan ## _nb] = pplan; \
+ plan->clsplans[class] = &plan->pplans[plan ## _nb++]; \
+ } while(0)
+
+/* Assign parameters to registers and stack with alignment according to the
+ rules in the procedure call standard for the ARM architecture (AAPCS).
+ The overall assignment is recorded in an array of per parameter structures
+ called parameter plans. The parameter plans are also further organized in a
+ number of linked lists, one per class of parameter (see the comment for the
+ definition of union reg_class).
+
+ nb_args: number of parameters of the function for which a call is generated
+ float_abi: float ABI in use for this function call
+ plan: the structure where the overall assignment is recorded
+ todo: a bitmap that record which core registers hold a parameter
+
+ Returns the amount of stack space needed for parameter passing
+
+ Note: this function allocated an array in plan->pplans with tcc_malloc. It
+ is the responsibility of the caller to free this array once used (ie not
+ before copy_params). */
+static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
+{
+ int i, size, align;
+ int ncrn /* next core register number */, nsaa /* next stacked argument address*/;
+ int plan_nb = 0;
+ struct param_plan pplan;
+ struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
+
+ ncrn = nsaa = 0;
+ *todo = 0;
+ plan->pplans = tcc_malloc(nb_args * sizeof(*plan->pplans));
+ memset(plan->clsplans, 0, sizeof(plan->clsplans));
+ for(i = nb_args; i-- ;) {
+ int j, start_vfpreg = 0;
+ CType type = vtop[-i].type;
+ type.t &= ~VT_ARRAY;
+ size = type_size(&type, &align);
+ size = (size + 3) & ~3;
+ align = (align + 3) & ~3;
+ switch(vtop[-i].type.t & VT_BTYPE) {
+ case VT_STRUCT:
+ case VT_FLOAT:
+ case VT_DOUBLE:
+ case VT_LDOUBLE:
+ if (float_abi == ARM_HARD_FLOAT) {
+ int is_hfa = 0; /* Homogeneous float aggregate */
+
+ if (is_float(vtop[-i].type.t)
+ || (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) {
+ int end_vfpreg;
+
+ start_vfpreg = assign_vfpreg(&avregs, align, size);
+ end_vfpreg = start_vfpreg + ((size - 1) >> 2);
+ if (start_vfpreg >= 0) {
+ pplan = (struct param_plan) {start_vfpreg, end_vfpreg, &vtop[-i]};
+ if (is_hfa)
+ add_param_plan(plan, pplan, VFP_STRUCT_CLASS);
+ else
+ add_param_plan(plan, pplan, VFP_CLASS);
+ continue;
+ } else
+ break;
+ }
+ }
+ ncrn = (ncrn + (align-1)/4) & ~((align/4) - 1);
+ if (ncrn + size/4 <= 4 || (ncrn < 4 && start_vfpreg != -1)) {
+ /* The parameter is allocated both in core register and on stack. As
+ * such, it can be of either class: it would either be the last of
+ * CORE_STRUCT_CLASS or the first of STACK_CLASS. */
+ for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
+ *todo|=(1<<j);
+ pplan = (struct param_plan) {ncrn, j, &vtop[-i]};
+ add_param_plan(plan, pplan, CORE_STRUCT_CLASS);
+ ncrn += size/4;
+ if (ncrn > 4)
+ nsaa = (ncrn - 4) * 4;
+ } else {
+ ncrn = 4;
+ break;
+ }
+ continue;
+ default:
+ if (ncrn < 4) {
+ int is_long = (vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
+
+ if (is_long) {
+ ncrn = (ncrn + 1) & -2;
+ if (ncrn == 4)
+ break;
+ }
+ pplan = (struct param_plan) {ncrn, ncrn, &vtop[-i]};
+ ncrn++;
+ if (is_long)
+ pplan.end = ncrn++;
+ add_param_plan(plan, pplan, CORE_CLASS);
+ continue;
+ }
+ }
+ nsaa = (nsaa + (align - 1)) & ~(align - 1);
+ pplan = (struct param_plan) {nsaa, nsaa + size, &vtop[-i]};
+ add_param_plan(plan, pplan, STACK_CLASS);
+ nsaa += size; /* size already rounded up before */
+ }
+ return nsaa;
+}
+
+#undef add_param_plan
+
+/* Copy parameters to their final destination (core reg, VFP reg or stack) for
+ function call.
+
+ nb_args: number of parameters the function take
+ plan: the overall assignment plan for parameters
+ todo: a bitmap indicating what core reg will hold a parameter
+
+ Returns the number of SValue added by this function on the value stack */
+static int copy_params(int nb_args, struct plan *plan, int todo)
+{
+ int size, align, r, i, nb_extra_sval = 0;
+ struct param_plan *pplan;
+ int pass = 0;
+
+ /* Several constraints require parameters to be copied in a specific order:
+ - structures are copied to the stack before being loaded in a reg;
+ - floats loaded to an odd numbered VFP reg are first copied to the
+ preceding even numbered VFP reg and then moved to the next VFP reg.
+
+ It is thus important that:
+ - structures assigned to core regs must be copied after parameters
+ assigned to the stack but before structures assigned to VFP regs because
+ a structure can lie partly in core registers and partly on the stack;
+ - parameters assigned to the stack and all structures be copied before
+ parameters assigned to a core reg since copying a parameter to the stack
+ require using a core reg;
+ - parameters assigned to VFP regs be copied before structures assigned to
+ VFP regs as the copy might use an even numbered VFP reg that already
+ holds part of a structure. */
+again:
+ for(i = 0; i < NB_CLASSES; i++) {
+ for(pplan = plan->clsplans[i]; pplan; pplan = pplan->prev) {
+
+ if (pass
+ && (i != CORE_CLASS || pplan->sval->r < VT_CONST))
+ continue;
+
+ vpushv(pplan->sval);
+ pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */
+ switch(i) {
+ case STACK_CLASS:
+ case CORE_STRUCT_CLASS:
+ case VFP_STRUCT_CLASS:
+ if ((pplan->sval->type.t & VT_BTYPE) == VT_STRUCT) {
+ int padding = 0;
+ size = type_size(&pplan->sval->type, &align);
+ /* align to stack align size */
+ size = (size + 3) & ~3;
+ if (i == STACK_CLASS && pplan->prev)
+ padding = pplan->start - pplan->prev->end;
+ size += padding; /* Add padding if any */
+ /* allocate the necessary size on stack */
+ gadd_sp(-size);
+ /* generate structure store */
+ r = get_reg(RC_INT);
+ o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */
+ vset(&vtop->type, r | VT_LVAL, 0);
+ vswap();
+ vstore(); /* memcpy to current sp + potential padding */
+
+ /* Homogeneous float aggregate are loaded to VFP registers
+ immediately since there is no way of loading data in multiple
+ non consecutive VFP registers as what is done for other
+ structures (see the use of todo). */
+ if (i == VFP_STRUCT_CLASS) {
+ int first = pplan->start, nb = pplan->end - first + 1;
+ /* vpop.32 {pplan->start, ..., pplan->end} */
+ o(0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb);
+ /* No need to write the register used to a SValue since VFP regs
+ cannot be used for gcall_or_jmp */
+ }
+ } else {
+ if (is_float(pplan->sval->type.t)) {
+#ifdef TCC_ARM_VFP
+ r = vfpr(gv(RC_FLOAT)) << 12;
+ if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
+ size = 4;
+ else {
+ size = 8;
+ r |= 0x101; /* vpush.32 -> vpush.64 */
+ }
+ o(0xED2D0A01 + r); /* vpush */
+#else
+ r = fpr(gv(RC_FLOAT)) << 12;
+ if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
+ size = 4;
+ else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE)
+ size = 8;
+ else
+ size = LDOUBLE_SIZE;
+
+ if (size == 12)
+ r |= 0x400000;
+ else if(size == 8)
+ r|=0x8000;
+
+ o(0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */
+#endif
+ } else {
+ /* simple type (currently always same size) */
+ /* XXX: implicit cast ? */
+ size=4;
+ if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
+ lexpand_nr();
+ size = 8;
+ r = gv(RC_INT);
+ o(0xE52D0004|(intr(r)<<12)); /* push r */
+ vtop--;
+ }
+ r = gv(RC_INT);
+ o(0xE52D0004|(intr(r)<<12)); /* push r */
+ }
+ if (i == STACK_CLASS && pplan->prev)
+ gadd_sp(pplan->prev->end - pplan->start); /* Add padding if any */
+ }
+ break;
+
+ case VFP_CLASS:
+ gv(regmask(TREG_F0 + (pplan->start >> 1)));
+ if (pplan->start & 1) { /* Must be in upper part of double register */
+ o(0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */
+ vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
+ }
+ break;
+
+ case CORE_CLASS:
+ if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
+ lexpand_nr();
+ gv(regmask(pplan->end));
+ pplan->sval->r2 = vtop->r;
+ vtop--;
+ }
+ gv(regmask(pplan->start));
+ /* Mark register as used so that gcall_or_jmp use another one
+ (regs >=4 are free as never used to pass parameters) */
+ pplan->sval->r = vtop->r;
+ break;
+ }
+ vtop--;
+ }
+ }
+
+ /* second pass to restore registers that were saved on stack by accident.
+ Maybe redundant after the "lvalue_save" patch in tccgen.c:gv() */
+ if (++pass < 2)
+ goto again;
+
+ /* Manually free remaining registers since next parameters are loaded
+ * manually, without the help of gv(int). */
+ save_regs(nb_args);
+
+ if(todo) {
+ o(0xE8BD0000|todo); /* pop {todo} */
+ for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {
+ int r;
+ pplan->sval->r = pplan->start;
+ /* An SValue can only pin 2 registers at best (r and r2) but a structure
+ can occupy more than 2 registers. Thus, we need to push on the value
+ stack some fake parameter to have on SValue for each registers used
+ by a structure (r2 is not used). */
+ for (r = pplan->start + 1; r <= pplan->end; r++) {
+ if (todo & (1 << r)) {
+ nb_extra_sval++;
+ vpushi(0);
+ vtop->r = r;
+ }
+ }
+ }
+ }
+ return nb_extra_sval;
+}
+
+/* Generate function call. The function address is pushed first, then
+ all the parameters in call order. This functions pops all the
+ parameters and the function address. */
+void gfunc_call(int nb_args)
+{
+ int r, args_size;
+ int def_float_abi = float_abi;
+ int todo;
+ struct plan plan;
+
+#ifdef TCC_ARM_EABI
+ int variadic;
+
+ if (float_abi == ARM_HARD_FLOAT) {
+ variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
+ if (variadic || floats_in_core_regs(&vtop[-nb_args]))
+ float_abi = ARM_SOFTFP_FLOAT;
+ }
+#endif
+ /* cannot let cpu flags if other instruction are generated. Also avoid leaving
+ VT_JMP anywhere except on the top of the stack because it would complicate
+ the code generator. */
+ r = vtop->r & VT_VALMASK;
+ if (r == VT_CMP || (r & ~1) == VT_JMP)
+ gv(RC_INT);
+
+ args_size = assign_regs(nb_args, float_abi, &plan, &todo);
+
+#ifdef TCC_ARM_EABI
+ if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */
+ args_size = (args_size + 7) & ~7;
+ o(0xE24DD004); /* sub sp, sp, #4 */
+ }
+#endif
+
+ nb_args += copy_params(nb_args, &plan, todo);
+ tcc_free(plan.pplans);
+
+ /* Move fct SValue on top as required by gcall_or_jmp */
+ vrotb(nb_args + 1);
+ gcall_or_jmp(0);
+ if (args_size)
+ gadd_sp(args_size); /* pop all parameters passed on the stack */
+#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
+ if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) {
+ if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
+ o(0xEE000A10); /*vmov s0, r0 */
+ } else {
+ o(0xEE000B10); /* vmov.32 d0[0], r0 */
+ o(0xEE201B10); /* vmov.32 d0[1], r1 */
+ }
+ }
+#endif
+ vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
+ leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
+ float_abi = def_float_abi;
+}
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType *func_type)
+{
+ Sym *sym,*sym2;
+ int n, nf, size, align, rs, struct_ret = 0;
+ int addr, pn, sn; /* pn=core, sn=stack */
+ CType ret_type;
+
+#ifdef TCC_ARM_EABI
+ struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
+#endif
+
+ sym = func_type->ref;
+ func_vt = sym->type;
+ func_var = (func_type->ref->f.func_type == FUNC_ELLIPSIS);
+
+ n = nf = 0;
+ if ((func_vt.t & VT_BTYPE) == VT_STRUCT &&
+ !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs))
+ {
+ n++;
+ struct_ret = 1;
+ func_vc = 12; /* Offset from fp of the place to store the result */
+ }
+ for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {
+ size = type_size(&sym2->type, &align);
+#ifdef TCC_ARM_EABI
+ if (float_abi == ARM_HARD_FLOAT && !func_var &&
+ (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {
+ int tmpnf = assign_vfpreg(&avregs, align, size);
+ tmpnf += (size + 3) / 4;
+ nf = (tmpnf > nf) ? tmpnf : nf;
+ } else
+#endif
+ if (n < 4)
+ n += (size + 3) / 4;
+ }
+ o(0xE1A0C00D); /* mov ip,sp */
+ if (func_var)
+ n=4;
+ if (n) {
+ if(n>4)
+ n=4;
+#ifdef TCC_ARM_EABI
+ n=(n+1)&-2;
+#endif
+ o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */
+ }
+ if (nf) {
+ if (nf>16)
+ nf=16;
+ nf=(nf+1)&-2; /* nf => HARDFLOAT => EABI */
+ o(0xED2D0A00|nf); /* save s0-s15 on stack if needed */
+ }
+ o(0xE92D5800); /* save fp, ip, lr */
+ o(0xE1A0B00D); /* mov fp, sp */
+ func_sub_sp_offset = ind;
+ o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */
+
+#ifdef TCC_ARM_EABI
+ if (float_abi == ARM_HARD_FLOAT) {
+ func_vc += nf * 4;
+ avregs = AVAIL_REGS_INITIALIZER;
+ }
+#endif
+ pn = struct_ret, sn = 0;
+ while ((sym = sym->next)) {
+ CType *type;
+ type = &sym->type;
+ size = type_size(type, &align);
+ size = (size + 3) >> 2;
+ align = (align + 3) & ~3;
+#ifdef TCC_ARM_EABI
+ if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t)
+ || is_hgen_float_aggr(&sym->type))) {
+ int fpn = assign_vfpreg(&avregs, align, size << 2);
+ if (fpn >= 0)
+ addr = fpn * 4;
+ else
+ goto from_stack;
+ } else
+#endif
+ if (pn < 4) {
+#ifdef TCC_ARM_EABI
+ pn = (pn + (align-1)/4) & -(align/4);
+#endif
+ addr = (nf + pn) * 4;
+ pn += size;
+ if (!sn && pn > 4)
+ sn = (pn - 4);
+ } else {
+#ifdef TCC_ARM_EABI
+from_stack:
+ sn = (sn + (align-1)/4) & -(align/4);
+#endif
+ addr = (n + nf + sn) * 4;
+ sn += size;
+ }
+ sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t),
+ addr + 12);
+ }
+ last_itod_magic=0;
+ leaffunc = 1;
+ loc = 0;
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+ uint32_t x;
+ int diff;
+ /* Copy float return value to core register if base standard is used and
+ float computation is made with VFP */
+#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
+ if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) {
+ if((func_vt.t & VT_BTYPE) == VT_FLOAT)
+ o(0xEE100A10); /* fmrs r0, s0 */
+ else {
+ o(0xEE100B10); /* fmrdl r0, d0 */
+ o(0xEE301B10); /* fmrdh r1, d0 */
+ }
+ }
+#endif
+ o(0xE89BA800); /* restore fp, sp, pc */
+ diff = (-loc + 3) & -4;
+#ifdef TCC_ARM_EABI
+ if(!leaffunc)
+ diff = ((diff + 11) & -8) - 4;
+#endif
+ if(diff > 0) {
+ x=stuff_const(0xE24BD000, diff); /* sub sp,fp,# */
+ if(x)
+ *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x;
+ else {
+ int addr;
+ addr=ind;
+ o(0xE59FC004); /* ldr ip,[pc+4] */
+ o(0xE04BD00C); /* sub sp,fp,ip */
+ o(0xE1A0F00E); /* mov pc,lr */
+ o(diff);
+ *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1);
+ }
+ }
+}
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+ int r;
+ if (nocode_wanted)
+ return t;
+ r=ind;
+ o(0xE0000000|encbranch(r,t,1));
+ return r;
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+ gjmp(a);
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+int gtst(int inv, int t)
+{
+ int v, r;
+ uint32_t op;
+
+ v = vtop->r & VT_VALMASK;
+ r=ind;
+
+ if (nocode_wanted) {
+ ;
+ } else if (v == VT_CMP) {
+ op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
+ op|=encbranch(r,t,1);
+ o(op);
+ t=r;
+ } else if (v == VT_JMP || v == VT_JMPI) {
+ if ((v & 1) == inv) {
+ if(!vtop->c.i)
+ vtop->c.i=t;
+ else {
+ uint32_t *x;
+ int p,lp;
+ if(t) {
+ p = vtop->c.i;
+ do {
+ p = decbranch(lp=p);
+ } while(p);
+ x = (uint32_t *)(cur_text_section->data + lp);
+ *x &= 0xff000000;
+ *x |= encbranch(lp,t,1);
+ }
+ t = vtop->c.i;
+ }
+ } else {
+ t = gjmp(t);
+ gsym(vtop->c.i);
+ }
+ }
+ vtop--;
+ return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+ int c, func = 0;
+ uint32_t opc = 0, r, fr;
+ unsigned short retreg = REG_IRET;
+
+ c=0;
+ switch(op) {
+ case '+':
+ opc = 0x8;
+ c=1;
+ break;
+ case TOK_ADDC1: /* add with carry generation */
+ opc = 0x9;
+ c=1;
+ break;
+ case '-':
+ opc = 0x4;
+ c=1;
+ break;
+ case TOK_SUBC1: /* sub with carry generation */
+ opc = 0x5;
+ c=1;
+ break;
+ case TOK_ADDC2: /* add with carry use */
+ opc = 0xA;
+ c=1;
+ break;
+ case TOK_SUBC2: /* sub with carry use */
+ opc = 0xC;
+ c=1;
+ break;
+ case '&':
+ opc = 0x0;
+ c=1;
+ break;
+ case '^':
+ opc = 0x2;
+ c=1;
+ break;
+ case '|':
+ opc = 0x18;
+ c=1;
+ break;
+ case '*':
+ gv2(RC_INT, RC_INT);
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ vtop--;
+ o(0xE0000090|(intr(r)<<16)|(intr(r)<<8)|intr(fr));
+ return;
+ case TOK_SHL:
+ opc = 0;
+ c=2;
+ break;
+ case TOK_SHR:
+ opc = 1;
+ c=2;
+ break;
+ case TOK_SAR:
+ opc = 2;
+ c=2;
+ break;
+ case '/':
+ case TOK_PDIV:
+ func=TOK___divsi3;
+ c=3;
+ break;
+ case TOK_UDIV:
+ func=TOK___udivsi3;
+ c=3;
+ break;
+ case '%':
+#ifdef TCC_ARM_EABI
+ func=TOK___aeabi_idivmod;
+ retreg=REG_LRET;
+#else
+ func=TOK___modsi3;
+#endif
+ c=3;
+ break;
+ case TOK_UMOD:
+#ifdef TCC_ARM_EABI
+ func=TOK___aeabi_uidivmod;
+ retreg=REG_LRET;
+#else
+ func=TOK___umodsi3;
+#endif
+ c=3;
+ break;
+ case TOK_UMULL:
+ gv2(RC_INT, RC_INT);
+ r=intr(vtop[-1].r2=get_reg(RC_INT));
+ c=vtop[-1].r;
+ vtop[-1].r=get_reg_ex(RC_INT,regmask(c));
+ vtop--;
+ o(0xE0800090|(r<<16)|(intr(vtop->r)<<12)|(intr(c)<<8)|intr(vtop[1].r));
+ return;
+ default:
+ opc = 0x15;
+ c=1;
+ break;
+ }
+ switch(c) {
+ case 1:
+ if((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ if(opc == 4 || opc == 5 || opc == 0xc) {
+ vswap();
+ opc|=2; // sub -> rsb
+ }
+ }
+ if ((vtop->r & VT_VALMASK) == VT_CMP ||
+ (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
+ gv(RC_INT);
+ vswap();
+ c=intr(gv(RC_INT));
+ vswap();
+ opc=0xE0000000|(opc<<20)|(c<<16);
+ if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ uint32_t x;
+ x=stuff_const(opc|0x2000000,vtop->c.i);
+ if(x) {
+ r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
+ o(x|(r<<12));
+ goto done;
+ }
+ }
+ fr=intr(gv(RC_INT));
+ r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
+ o(opc|(r<<12)|fr);
+done:
+ vtop--;
+ if (op >= TOK_ULT && op <= TOK_GT) {
+ vtop->r = VT_CMP;
+ vtop->c.i = op;
+ }
+ break;
+ case 2:
+ opc=0xE1A00000|(opc<<5);
+ if ((vtop->r & VT_VALMASK) == VT_CMP ||
+ (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
+ gv(RC_INT);
+ vswap();
+ r=intr(gv(RC_INT));
+ vswap();
+ opc|=r;
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ fr=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
+ c = vtop->c.i & 0x1f;
+ o(opc|(c<<7)|(fr<<12));
+ } else {
+ fr=intr(gv(RC_INT));
+ c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
+ o(opc|(c<<12)|(fr<<8)|0x10);
+ }
+ vtop--;
+ break;
+ case 3:
+ vpush_global_sym(&func_old_type, func);
+ vrott(3);
+ gfunc_call(2);
+ vpushi(0);
+ vtop->r = retreg;
+ break;
+ default:
+ tcc_error("gen_opi %i unimplemented!",op);
+ }
+}
+
+#ifdef TCC_ARM_VFP
+static int is_zero(int i)
+{
+ if((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+ return 0;
+ if (vtop[i].type.t == VT_FLOAT)
+ return (vtop[i].c.f == 0.f);
+ else if (vtop[i].type.t == VT_DOUBLE)
+ return (vtop[i].c.d == 0.0);
+ return (vtop[i].c.ld == 0.l);
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+ * two operands are guaranteed to have the same floating point type */
+void gen_opf(int op)
+{
+ uint32_t x;
+ int fneg=0,r;
+ x=0xEE000A00|T2CPR(vtop->type.t);
+ switch(op) {
+ case '+':
+ if(is_zero(-1))
+ vswap();
+ if(is_zero(0)) {
+ vtop--;
+ return;
+ }
+ x|=0x300000;
+ break;
+ case '-':
+ x|=0x300040;
+ if(is_zero(0)) {
+ vtop--;
+ return;
+ }
+ if(is_zero(-1)) {
+ x|=0x810000; /* fsubX -> fnegX */
+ vswap();
+ vtop--;
+ fneg=1;
+ }
+ break;
+ case '*':
+ x|=0x200000;
+ break;
+ case '/':
+ x|=0x800000;
+ break;
+ default:
+ if(op < TOK_ULT || op > TOK_GT) {
+ tcc_error("unknown fp op %x!",op);
+ return;
+ }
+ if(is_zero(-1)) {
+ vswap();
+ switch(op) {
+ case TOK_LT: op=TOK_GT; break;
+ case TOK_GE: op=TOK_ULE; break;
+ case TOK_LE: op=TOK_GE; break;
+ case TOK_GT: op=TOK_ULT; break;
+ }
+ }
+ x|=0xB40040; /* fcmpX */
+ if(op!=TOK_EQ && op!=TOK_NE)
+ x|=0x80; /* fcmpX -> fcmpeX */
+ if(is_zero(0)) {
+ vtop--;
+ o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
+ } else {
+ x|=vfpr(gv(RC_FLOAT));
+ vswap();
+ o(x|(vfpr(gv(RC_FLOAT))<<12));
+ vtop--;
+ }
+ o(0xEEF1FA10); /* fmstat */
+
+ switch(op) {
+ case TOK_LE: op=TOK_ULE; break;
+ case TOK_LT: op=TOK_ULT; break;
+ case TOK_UGE: op=TOK_GE; break;
+ case TOK_UGT: op=TOK_GT; break;
+ }
+
+ vtop->r = VT_CMP;
+ vtop->c.i = op;
+ return;
+ }
+ r=gv(RC_FLOAT);
+ x|=vfpr(r);
+ r=regmask(r);
+ if(!fneg) {
+ int r2;
+ vswap();
+ r2=gv(RC_FLOAT);
+ x|=vfpr(r2)<<16;
+ r|=regmask(r2);
+ }
+ vtop->r=get_reg_ex(RC_FLOAT,r);
+ if(!fneg)
+ vtop--;
+ o(x|(vfpr(vtop->r)<<12));
+}
+
+#else
+static uint32_t is_fconst()
+{
+ long double f;
+ uint32_t r;
+ if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+ return 0;
+ if (vtop->type.t == VT_FLOAT)
+ f = vtop->c.f;
+ else if (vtop->type.t == VT_DOUBLE)
+ f = vtop->c.d;
+ else
+ f = vtop->c.ld;
+ if(!ieee_finite(f))
+ return 0;
+ r=0x8;
+ if(f<0.0) {
+ r=0x18;
+ f=-f;
+ }
+ if(f==0.0)
+ return r;
+ if(f==1.0)
+ return r|1;
+ if(f==2.0)
+ return r|2;
+ if(f==3.0)
+ return r|3;
+ if(f==4.0)
+ return r|4;
+ if(f==5.0)
+ return r|5;
+ if(f==0.5)
+ return r|6;
+ if(f==10.0)
+ return r|7;
+ return 0;
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+ two operands are guaranteed to have the same floating point type */
+void gen_opf(int op)
+{
+ uint32_t x, r, r2, c1, c2;
+ //fputs("gen_opf\n",stderr);
+ vswap();
+ c1 = is_fconst();
+ vswap();
+ c2 = is_fconst();
+ x=0xEE000100;
+#if LDOUBLE_SIZE == 8
+ if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
+ x|=0x80;
+#else
+ if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+ x|=0x80;
+ else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
+ x|=0x80000;
+#endif
+ switch(op)
+ {
+ case '+':
+ if(!c2) {
+ vswap();
+ c2=c1;
+ }
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
+ if(c2) {
+ if(c2>0xf)
+ x|=0x200000; // suf
+ r2=c2&0xf;
+ } else {
+ r2=fpr(gv(RC_FLOAT));
+ }
+ break;
+ case '-':
+ if(c2) {
+ if(c2<=0xf)
+ x|=0x200000; // suf
+ r2=c2&0xf;
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
+ } else if(c1 && c1<=0xf) {
+ x|=0x300000; // rsf
+ r2=c1;
+ r=fpr(gv(RC_FLOAT));
+ vswap();
+ } else {
+ x|=0x200000; // suf
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
+ r2=fpr(gv(RC_FLOAT));
+ }
+ break;
+ case '*':
+ if(!c2 || c2>0xf) {
+ vswap();
+ c2=c1;
+ }
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
+ if(c2 && c2<=0xf)
+ r2=c2;
+ else
+ r2=fpr(gv(RC_FLOAT));
+ x|=0x100000; // muf
+ break;
+ case '/':
+ if(c2 && c2<=0xf) {
+ x|=0x400000; // dvf
+ r2=c2;
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
+ } else if(c1 && c1<=0xf) {
+ x|=0x500000; // rdf
+ r2=c1;
+ r=fpr(gv(RC_FLOAT));
+ vswap();
+ } else {
+ x|=0x400000; // dvf
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
+ r2=fpr(gv(RC_FLOAT));
+ }
+ break;
+ default:
+ if(op >= TOK_ULT && op <= TOK_GT) {
+ x|=0xd0f110; // cmfe
+/* bug (intention?) in Linux FPU emulator
+ doesn't set carry if equal */
+ switch(op) {
+ case TOK_ULT:
+ case TOK_UGE:
+ case TOK_ULE:
+ case TOK_UGT:
+ tcc_error("unsigned comparison on floats?");
+ break;
+ case TOK_LT:
+ op=TOK_Nset;
+ break;
+ case TOK_LE:
+ op=TOK_ULE; /* correct in unordered case only if AC bit in FPSR set */
+ break;
+ case TOK_EQ:
+ case TOK_NE:
+ x&=~0x400000; // cmfe -> cmf
+ break;
+ }
+ if(c1 && !c2) {
+ c2=c1;
+ vswap();
+ switch(op) {
+ case TOK_Nset:
+ op=TOK_GT;
+ break;
+ case TOK_GE:
+ op=TOK_ULE;
+ break;
+ case TOK_ULE:
+ op=TOK_GE;
+ break;
+ case TOK_GT:
+ op=TOK_Nset;
+ break;
+ }
+ }
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
+ if(c2) {
+ if(c2>0xf)
+ x|=0x200000;
+ r2=c2&0xf;
+ } else {
+ r2=fpr(gv(RC_FLOAT));
+ }
+ vtop[-1].r = VT_CMP;
+ vtop[-1].c.i = op;
+ } else {
+ tcc_error("unknown fp op %x!",op);
+ return;
+ }
+ }
+ if(vtop[-1].r == VT_CMP)
+ c1=15;
+ else {
+ c1=vtop->r;
+ if(r2&0x8)
+ c1=vtop[-1].r;
+ vtop[-1].r=get_reg_ex(RC_FLOAT,two2mask(vtop[-1].r,c1));
+ c1=fpr(vtop[-1].r);
+ }
+ vtop--;
+ o(x|(r<<16)|(c1<<12)|r2);
+}
+#endif
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+ and 'long long' cases. */
+ST_FUNC void gen_cvt_itof1(int t)
+{
+ uint32_t r, r2;
+ int bt;
+ bt=vtop->type.t & VT_BTYPE;
+ if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
+#ifndef TCC_ARM_VFP
+ uint32_t dsize = 0;
+#endif
+ r=intr(gv(RC_INT));
+#ifdef TCC_ARM_VFP
+ r2=vfpr(vtop->r=get_reg(RC_FLOAT));
+ o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
+ r2|=r2<<12;
+ if(!(vtop->type.t & VT_UNSIGNED))
+ r2|=0x80; /* fuitoX -> fsituX */
+ o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
+#else
+ r2=fpr(vtop->r=get_reg(RC_FLOAT));
+ if((t & VT_BTYPE) != VT_FLOAT)
+ dsize=0x80; /* flts -> fltd */
+ o(0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */
+ if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
+ uint32_t off = 0;
+ o(0xE3500000|(r<<12)); /* cmp */
+ r=fpr(get_reg(RC_FLOAT));
+ if(last_itod_magic) {
+ off=ind+8-last_itod_magic;
+ off/=4;
+ if(off>255)
+ off=0;
+ }
+ o(0xBD1F0100|(r<<12)|off); /* ldflts */
+ if(!off) {
+ o(0xEA000000); /* b */
+ last_itod_magic=ind;
+ o(0x4F800000); /* 4294967296.0f */
+ }
+ o(0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */
+ }
+#endif
+ return;
+ } else if(bt == VT_LLONG) {
+ int func;
+ CType *func_type = 0;
+ if((t & VT_BTYPE) == VT_FLOAT) {
+ func_type = &func_float_type;
+ if(vtop->type.t & VT_UNSIGNED)
+ func=TOK___floatundisf;
+ else
+ func=TOK___floatdisf;
+#if LDOUBLE_SIZE != 8
+ } else if((t & VT_BTYPE) == VT_LDOUBLE) {
+ func_type = &func_ldouble_type;
+ if(vtop->type.t & VT_UNSIGNED)
+ func=TOK___floatundixf;
+ else
+ func=TOK___floatdixf;
+ } else if((t & VT_BTYPE) == VT_DOUBLE) {
+#else
+ } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {
+#endif
+ func_type = &func_double_type;
+ if(vtop->type.t & VT_UNSIGNED)
+ func=TOK___floatundidf;
+ else
+ func=TOK___floatdidf;
+ }
+ if(func_type) {
+ vpush_global_sym(func_type, func);
+ vswap();
+ gfunc_call(1);
+ vpushi(0);
+ vtop->r=TREG_F0;
+ return;
+ }
+ }
+ tcc_error("unimplemented gen_cvt_itof %x!",vtop->type.t);
+}
+
+/* convert fp to int 't' type */
+void gen_cvt_ftoi(int t)
+{
+ uint32_t r, r2;
+ int u, func = 0;
+ u=t&VT_UNSIGNED;
+ t&=VT_BTYPE;
+ r2=vtop->type.t & VT_BTYPE;
+ if(t==VT_INT) {
+#ifdef TCC_ARM_VFP
+ r=vfpr(gv(RC_FLOAT));
+ u=u?0:0x10000;
+ o(0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */
+ r2=intr(vtop->r=get_reg(RC_INT));
+ o(0xEE100A10|(r<<16)|(r2<<12));
+ return;
+#else
+ if(u) {
+ if(r2 == VT_FLOAT)
+ func=TOK___fixunssfsi;
+#if LDOUBLE_SIZE != 8
+ else if(r2 == VT_LDOUBLE)
+ func=TOK___fixunsxfsi;
+ else if(r2 == VT_DOUBLE)
+#else
+ else if(r2 == VT_LDOUBLE || r2 == VT_DOUBLE)
+#endif
+ func=TOK___fixunsdfsi;
+ } else {
+ r=fpr(gv(RC_FLOAT));
+ r2=intr(vtop->r=get_reg(RC_INT));
+ o(0xEE100170|(r2<<12)|r);
+ return;
+ }
+#endif
+ } else if(t == VT_LLONG) { // unsigned handled in gen_cvt_ftoi1
+ if(r2 == VT_FLOAT)
+ func=TOK___fixsfdi;
+#if LDOUBLE_SIZE != 8
+ else if(r2 == VT_LDOUBLE)
+ func=TOK___fixxfdi;
+ else if(r2 == VT_DOUBLE)
+#else
+ else if(r2 == VT_LDOUBLE || r2 == VT_DOUBLE)
+#endif
+ func=TOK___fixdfdi;
+ }
+ if(func) {
+ vpush_global_sym(&func_old_type, func);
+ vswap();
+ gfunc_call(1);
+ vpushi(0);
+ if(t == VT_LLONG)
+ vtop->r2 = REG_LRET;
+ vtop->r = REG_IRET;
+ return;
+ }
+ tcc_error("unimplemented gen_cvt_ftoi!");
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+#ifdef TCC_ARM_VFP
+ if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
+ uint32_t r = vfpr(gv(RC_FLOAT));
+ o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t));
+ }
+#else
+ /* all we have to do on i386 and FPA ARM is to put the float in a register */
+ gv(RC_FLOAT);
+#endif
+}
+
+/* computed goto support */
+void ggoto(void)
+{
+ gcall_or_jmp(1);
+ vtop--;
+}
+
+/* Save the stack pointer onto the stack and return the location of its address */
+ST_FUNC void gen_vla_sp_save(int addr) {
+ SValue v;
+ v.type.t = VT_PTR;
+ v.r = VT_LOCAL | VT_LVAL;
+ v.c.i = addr;
+ store(TREG_SP, &v);
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+ SValue v;
+ v.type.t = VT_PTR;
+ v.r = VT_LOCAL | VT_LVAL;
+ v.c.i = addr;
+ load(TREG_SP, &v);
+}
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+ int r = intr(gv(RC_INT));
+ o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */
+#ifdef TCC_ARM_EABI
+ if (align < 8)
+ align = 8;
+#else
+ if (align < 4)
+ align = 4;
+#endif
+ if (align & (align - 1))
+ tcc_error("alignment is not a power of 2: %i", align);
+ o(stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */
+ vpop();
+}
+
+/* end of ARM code generator */
+/*************************************************************/
+#endif
+/*************************************************************/
diff --git a/arm-link.c b/arm-link.c
new file mode 100644
index 0000000..92a24eb
--- /dev/null
+++ b/arm-link.c
@@ -0,0 +1,398 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_ARM
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32 R_ARM_ABS32
+#define R_DATA_PTR R_ARM_ABS32
+#define R_JMP_SLOT R_ARM_JUMP_SLOT
+#define R_GLOB_DAT R_ARM_GLOB_DAT
+#define R_COPY R_ARM_COPY
+#define R_RELATIVE R_ARM_RELATIVE
+
+#define R_NUM R_ARM_NUM
+
+#define ELF_START_ADDR 0x00008000
+#define ELF_PAGE_SIZE 0x1000
+
+#define PCRELATIVE_DLLPLT 1
+#define RELOCATE_DLLPLT 0
+
+enum float_abi {
+ ARM_SOFTFP_FLOAT,
+ ARM_HARD_FLOAT,
+};
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+ relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+ switch (reloc_type) {
+ case R_ARM_MOVT_ABS:
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_ABS32:
+ case R_ARM_REL32:
+ case R_ARM_GOTPC:
+ case R_ARM_GOTOFF:
+ case R_ARM_GOT32:
+ case R_ARM_COPY:
+ case R_ARM_GLOB_DAT:
+ case R_ARM_NONE:
+ return 0;
+
+ case R_ARM_PC24:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ case R_ARM_PLT32:
+ case R_ARM_THM_PC22:
+ case R_ARM_THM_JUMP24:
+ case R_ARM_PREL31:
+ case R_ARM_V4BX:
+ case R_ARM_JUMP_SLOT:
+ return 1;
+ }
+
+ tcc_error ("Unknown relocation type: %d", reloc_type);
+ return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+ GOT and/or PLT entry to be created. See tcc.h for a description of the
+ different values. */
+int gotplt_entry_type (int reloc_type)
+{
+ switch (reloc_type) {
+ case R_ARM_NONE:
+ case R_ARM_COPY:
+ case R_ARM_GLOB_DAT:
+ case R_ARM_JUMP_SLOT:
+ return NO_GOTPLT_ENTRY;
+
+ case R_ARM_PC24:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ case R_ARM_PLT32:
+ case R_ARM_THM_PC22:
+ case R_ARM_THM_JUMP24:
+ case R_ARM_MOVT_ABS:
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_PREL31:
+ case R_ARM_ABS32:
+ case R_ARM_REL32:
+ case R_ARM_V4BX:
+ return AUTO_GOTPLT_ENTRY;
+
+ case R_ARM_GOTPC:
+ case R_ARM_GOTOFF:
+ return BUILD_GOT_ONLY;
+
+ case R_ARM_GOT32:
+ return ALWAYS_GOTPLT_ENTRY;
+ }
+
+ tcc_error ("Unknown relocation type: %d", reloc_type);
+ return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+ Section *plt = s1->plt;
+ uint8_t *p;
+ unsigned plt_offset;
+
+ /* when building a DLL, GOT entry accesses must be done relative to
+ start of GOT (see x86_64 example above) */
+ if (s1->output_type == TCC_OUTPUT_DLL)
+ tcc_error("DLLs unimplemented!");
+
+ /* empty PLT: create PLT0 entry that push address of call site and
+ jump to ld.so resolution routine (GOT + 8) */
+ if (plt->data_offset == 0) {
+ p = section_ptr_add(plt, 20);
+ write32le(p, 0xe52de004); /* push {lr} */
+ write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */
+ write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */
+ write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
+ /* p+16 is set in relocate_plt */
+ }
+ plt_offset = plt->data_offset;
+
+ if (attr->plt_thumb_stub) {
+ p = section_ptr_add(plt, 4);
+ write32le(p, 0x4778); /* bx pc */
+ write32le(p+2, 0x46c0); /* nop */
+ }
+ p = section_ptr_add(plt, 16);
+ /* Jump to GOT entry where ld.so initially put address of PLT0 */
+ write32le(p, 0xe59fc004); /* ldr ip, [pc, #4] */
+ write32le(p+4, 0xe08fc00c); /* add ip, pc, ip */
+ write32le(p+8, 0xe59cf000); /* ldr pc, [ip] */
+ /* p + 12 contains offset to GOT entry once patched by relocate_plt */
+ write32le(p+12, got_offset);
+ return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+ address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+ uint8_t *p, *p_end;
+
+ if (!s1->plt)
+ return;
+
+ p = s1->plt->data;
+ p_end = p + s1->plt->data_offset;
+
+ if (p < p_end) {
+ int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
+ write32le(s1->plt->data + 16, x - 16);
+ p += 20;
+ while (p < p_end) {
+ if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
+ p += 4;
+ add32le(p + 12, x + s1->plt->data - p);
+ p += 16;
+ }
+ }
+}
+
+void relocate_init(Section *sr) {}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+ ElfW(Sym) *sym;
+ int sym_index;
+
+ sym_index = ELFW(R_SYM)(rel->r_info);
+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+
+ switch(type) {
+ case R_ARM_PC24:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ case R_ARM_PLT32:
+ {
+ int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
+ x = (*(int *) ptr) & 0xffffff;
+#ifdef DEBUG_RELOC
+ printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
+#endif
+ (*(int *)ptr) &= 0xff000000;
+ if (x & 0x800000)
+ x -= 0x1000000;
+ x <<= 2;
+ blx_avail = (TCC_CPU_VERSION >= 5);
+ is_thumb = val & 1;
+ is_bl = (*(unsigned *) ptr) >> 24 == 0xeb;
+ is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
+ x += val - addr;
+#ifdef DEBUG_RELOC
+ printf (" newx=0x%x name=%s\n", x,
+ (char *) symtab_section->link->data + sym->st_name);
+#endif
+ h = x & 2;
+ th_ko = (x & 3) && (!blx_avail || !is_call);
+ if (th_ko || x >= 0x2000000 || x < -0x2000000)
+ tcc_error("can't relocate value at %x,%d",addr, type);
+ x >>= 2;
+ x &= 0xffffff;
+ /* Only reached if blx is avail and it is a call */
+ if (is_thumb) {
+ x |= h << 24;
+ (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
+ }
+ (*(int *) ptr) |= x;
+ }
+ return;
+ /* Since these relocations only concern Thumb-2 and blx instruction was
+ introduced before Thumb-2, we can assume blx is available and not
+ guard its use */
+ case R_ARM_THM_PC22:
+ case R_ARM_THM_JUMP24:
+ {
+ int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
+ int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
+ Section *plt;
+
+ /* weak reference */
+ if (sym->st_shndx == SHN_UNDEF &&
+ ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
+ return;
+
+ /* Get initial offset */
+ hi = (*(uint16_t *)ptr);
+ lo = (*(uint16_t *)(ptr+2));
+ s = (hi >> 10) & 1;
+ j1 = (lo >> 13) & 1;
+ j2 = (lo >> 11) & 1;
+ i1 = (j1 ^ s) ^ 1;
+ i2 = (j2 ^ s) ^ 1;
+ imm10 = hi & 0x3ff;
+ imm11 = lo & 0x7ff;
+ x = (s << 24) | (i1 << 23) | (i2 << 22) |
+ (imm10 << 12) | (imm11 << 1);
+ if (x & 0x01000000)
+ x -= 0x02000000;
+
+ /* Relocation infos */
+ to_thumb = val & 1;
+ plt = s1->plt;
+ to_plt = (val >= plt->sh_addr) &&
+ (val < plt->sh_addr + plt->data_offset);
+ is_call = (type == R_ARM_THM_PC22);
+
+ if (!to_thumb && !to_plt && !is_call) {
+ int index;
+ uint8_t *p;
+ char *name, buf[1024];
+ Section *text_section;
+
+ name = (char *) symtab_section->link->data + sym->st_name;
+ text_section = s1->sections[sym->st_shndx];
+ /* Modify reloc to target a thumb stub to switch to ARM */
+ snprintf(buf, sizeof(buf), "%s_from_thumb", name);
+ index = put_elf_sym(symtab_section,
+ text_section->data_offset + 1,
+ sym->st_size, sym->st_info, 0,
+ sym->st_shndx, buf);
+ to_thumb = 1;
+ val = text_section->data_offset + 1;
+ rel->r_info = ELFW(R_INFO)(index, type);
+ /* Create a thumb stub function to switch to ARM mode */
+ put_elf_reloc(symtab_section, text_section,
+ text_section->data_offset + 4, R_ARM_JUMP24,
+ sym_index);
+ p = section_ptr_add(text_section, 8);
+ write32le(p, 0x4778); /* bx pc */
+ write32le(p+2, 0x46c0); /* nop */
+ write32le(p+4, 0xeafffffe); /* b $sym */
+ }
+
+ /* Compute final offset */
+ x += val - addr;
+ if (!to_thumb && is_call) {
+ blx_bit = 0; /* bl -> blx */
+ x = (x + 3) & -4; /* Compute offset from aligned PC */
+ }
+
+ /* Check that relocation is possible
+ * offset must not be out of range
+ * if target is to be entered in arm mode:
+ - bit 1 must not set
+ - instruction must be a call (bl) or a jump to PLT */
+ if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
+ if (to_thumb || (val & 2) || (!is_call && !to_plt))
+ tcc_error("can't relocate value at %x,%d",addr, type);
+
+ /* Compute and store final offset */
+ s = (x >> 24) & 1;
+ i1 = (x >> 23) & 1;
+ i2 = (x >> 22) & 1;
+ j1 = s ^ (i1 ^ 1);
+ j2 = s ^ (i2 ^ 1);
+ imm10 = (x >> 12) & 0x3ff;
+ imm11 = (x >> 1) & 0x7ff;
+ (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) |
+ (s << 10) | imm10);
+ (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) |
+ (j1 << 13) | blx_bit | (j2 << 11) |
+ imm11);
+ }
+ return;
+ case R_ARM_MOVT_ABS:
+ case R_ARM_MOVW_ABS_NC:
+ {
+ int x, imm4, imm12;
+ if (type == R_ARM_MOVT_ABS)
+ val >>= 16;
+ imm12 = val & 0xfff;
+ imm4 = (val >> 12) & 0xf;
+ x = (imm4 << 16) | imm12;
+ if (type == R_ARM_THM_MOVT_ABS)
+ *(int *)ptr |= x;
+ else
+ *(int *)ptr += x;
+ }
+ return;
+ case R_ARM_THM_MOVT_ABS:
+ case R_ARM_THM_MOVW_ABS_NC:
+ {
+ int x, i, imm4, imm3, imm8;
+ if (type == R_ARM_THM_MOVT_ABS)
+ val >>= 16;
+ imm8 = val & 0xff;
+ imm3 = (val >> 8) & 0x7;
+ i = (val >> 11) & 1;
+ imm4 = (val >> 12) & 0xf;
+ x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
+ if (type == R_ARM_THM_MOVT_ABS)
+ *(int *)ptr |= x;
+ else
+ *(int *)ptr += x;
+ }
+ return;
+ case R_ARM_PREL31:
+ {
+ int x;
+ x = (*(int *)ptr) & 0x7fffffff;
+ (*(int *)ptr) &= 0x80000000;
+ x = (x * 2) / 2;
+ x += val - addr;
+ if((x^(x>>1))&0x40000000)
+ tcc_error("can't relocate value at %x,%d",addr, type);
+ (*(int *)ptr) |= x & 0x7fffffff;
+ }
+ case R_ARM_ABS32:
+ *(int *)ptr += val;
+ return;
+ case R_ARM_REL32:
+ *(int *)ptr += val - addr;
+ return;
+ case R_ARM_GOTPC:
+ *(int *)ptr += s1->got->sh_addr - addr;
+ return;
+ case R_ARM_GOTOFF:
+ *(int *)ptr += val - s1->got->sh_addr;
+ return;
+ case R_ARM_GOT32:
+ /* we load the got offset */
+ *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
+ return;
+ case R_ARM_COPY:
+ return;
+ case R_ARM_V4BX:
+ /* trade Thumb support for ARMv4 support */
+ if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
+ *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
+ return;
+ case R_ARM_GLOB_DAT:
+ case R_ARM_JUMP_SLOT:
+ *(addr_t *)ptr = val;
+ return;
+ case R_ARM_NONE:
+ /* Nothing to do. Normally used to indicate a dependency
+ on a certain symbol (like for exception handling under EABI). */
+ return;
+ case R_ARM_RELATIVE:
+#ifdef TCC_TARGET_PE
+ add32le(ptr, val - s1->pe_imagebase);
+#endif
+ /* do nothing */
+ return;
+ default:
+ fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
+ type, (unsigned)addr, ptr, (unsigned)val);
+ return;
+ }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
diff --git a/arm64-gen.c b/arm64-gen.c
new file mode 100644
index 0000000..86b3af7
--- /dev/null
+++ b/arm64-gen.c
@@ -0,0 +1,1837 @@
+/*
+ * A64 code generator for TCC
+ *
+ * Copyright (c) 2014-2015 Edmund Grimley Evans
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved. This file is offered as-is,
+ * without any warranty.
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+// Number of registers available to allocator:
+#define NB_REGS 28 // x0-x18, x30, v0-v7
+
+#define TREG_R(x) (x) // x = 0..18
+#define TREG_R30 19
+#define TREG_F(x) (x + 20) // x = 0..7
+
+// Register classes sorted from more general to more precise:
+#define RC_INT (1 << 0)
+#define RC_FLOAT (1 << 1)
+#define RC_R(x) (1 << (2 + (x))) // x = 0..18
+#define RC_R30 (1 << 21)
+#define RC_F(x) (1 << (22 + (x))) // x = 0..7
+
+#define RC_IRET (RC_R(0)) // int return register class
+#define RC_FRET (RC_F(0)) // float return register class
+
+#define REG_IRET (TREG_R(0)) // int return register number
+#define REG_FRET (TREG_F(0)) // float return register number
+
+#define PTR_SIZE 8
+
+#define LDOUBLE_SIZE 16
+#define LDOUBLE_ALIGN 16
+
+#define MAX_ALIGN 16
+
+#define CHAR_IS_UNSIGNED
+
+/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+#include <assert.h>
+
+ST_DATA const int reg_classes[NB_REGS] = {
+ RC_INT | RC_R(0),
+ RC_INT | RC_R(1),
+ RC_INT | RC_R(2),
+ RC_INT | RC_R(3),
+ RC_INT | RC_R(4),
+ RC_INT | RC_R(5),
+ RC_INT | RC_R(6),
+ RC_INT | RC_R(7),
+ RC_INT | RC_R(8),
+ RC_INT | RC_R(9),
+ RC_INT | RC_R(10),
+ RC_INT | RC_R(11),
+ RC_INT | RC_R(12),
+ RC_INT | RC_R(13),
+ RC_INT | RC_R(14),
+ RC_INT | RC_R(15),
+ RC_INT | RC_R(16),
+ RC_INT | RC_R(17),
+ RC_INT | RC_R(18),
+ RC_R30, // not in RC_INT as we make special use of x30
+ RC_FLOAT | RC_F(0),
+ RC_FLOAT | RC_F(1),
+ RC_FLOAT | RC_F(2),
+ RC_FLOAT | RC_F(3),
+ RC_FLOAT | RC_F(4),
+ RC_FLOAT | RC_F(5),
+ RC_FLOAT | RC_F(6),
+ RC_FLOAT | RC_F(7)
+};
+
+#define IS_FREG(x) ((x) >= TREG_F(0))
+
+static uint32_t intr(int r)
+{
+ assert(TREG_R(0) <= r && r <= TREG_R30);
+ return r < TREG_R30 ? r : 30;
+}
+
+static uint32_t fltr(int r)
+{
+ assert(TREG_F(0) <= r && r <= TREG_F(7));
+ return r - TREG_F(0);
+}
+
+// Add an instruction to text section:
+ST_FUNC void o(unsigned int c)
+{
+ int ind1 = ind + 4;
+ if (nocode_wanted)
+ return;
+ if (ind1 > cur_text_section->data_allocated)
+ section_realloc(cur_text_section, ind1);
+ write32le(cur_text_section->data + ind, c);
+ ind = ind1;
+}
+
+static int arm64_encode_bimm64(uint64_t x)
+{
+ int neg = x & 1;
+ int rep, pos, len;
+
+ if (neg)
+ x = ~x;
+ if (!x)
+ return -1;
+
+ if (x >> 2 == (x & (((uint64_t)1 << (64 - 2)) - 1)))
+ rep = 2, x &= ((uint64_t)1 << 2) - 1;
+ else if (x >> 4 == (x & (((uint64_t)1 << (64 - 4)) - 1)))
+ rep = 4, x &= ((uint64_t)1 << 4) - 1;
+ else if (x >> 8 == (x & (((uint64_t)1 << (64 - 8)) - 1)))
+ rep = 8, x &= ((uint64_t)1 << 8) - 1;
+ else if (x >> 16 == (x & (((uint64_t)1 << (64 - 16)) - 1)))
+ rep = 16, x &= ((uint64_t)1 << 16) - 1;
+ else if (x >> 32 == (x & (((uint64_t)1 << (64 - 32)) - 1)))
+ rep = 32, x &= ((uint64_t)1 << 32) - 1;
+ else
+ rep = 64;
+
+ pos = 0;
+ if (!(x & (((uint64_t)1 << 32) - 1))) x >>= 32, pos += 32;
+ if (!(x & (((uint64_t)1 << 16) - 1))) x >>= 16, pos += 16;
+ if (!(x & (((uint64_t)1 << 8) - 1))) x >>= 8, pos += 8;
+ if (!(x & (((uint64_t)1 << 4) - 1))) x >>= 4, pos += 4;
+ if (!(x & (((uint64_t)1 << 2) - 1))) x >>= 2, pos += 2;
+ if (!(x & (((uint64_t)1 << 1) - 1))) x >>= 1, pos += 1;
+
+ len = 0;
+ if (!(~x & (((uint64_t)1 << 32) - 1))) x >>= 32, len += 32;
+ if (!(~x & (((uint64_t)1 << 16) - 1))) x >>= 16, len += 16;
+ if (!(~x & (((uint64_t)1 << 8) - 1))) x >>= 8, len += 8;
+ if (!(~x & (((uint64_t)1 << 4) - 1))) x >>= 4, len += 4;
+ if (!(~x & (((uint64_t)1 << 2) - 1))) x >>= 2, len += 2;
+ if (!(~x & (((uint64_t)1 << 1) - 1))) x >>= 1, len += 1;
+
+ if (x)
+ return -1;
+ if (neg) {
+ pos = (pos + len) & (rep - 1);
+ len = rep - len;
+ }
+ return ((0x1000 & rep << 6) | (((rep - 1) ^ 31) << 1 & 63) |
+ ((rep - pos) & (rep - 1)) << 6 | (len - 1));
+}
+
+static uint32_t arm64_movi(int r, uint64_t x)
+{
+ uint64_t m = 0xffff;
+ int e;
+ if (!(x & ~m))
+ return 0x52800000 | r | x << 5; // movz w(r),#(x)
+ if (!(x & ~(m << 16)))
+ return 0x52a00000 | r | x >> 11; // movz w(r),#(x >> 16),lsl #16
+ if (!(x & ~(m << 32)))
+ return 0xd2c00000 | r | x >> 27; // movz x(r),#(x >> 32),lsl #32
+ if (!(x & ~(m << 48)))
+ return 0xd2e00000 | r | x >> 43; // movz x(r),#(x >> 48),lsl #48
+ if ((x & ~m) == m << 16)
+ return (0x12800000 | r |
+ (~x << 5 & 0x1fffe0)); // movn w(r),#(~x)
+ if ((x & ~(m << 16)) == m)
+ return (0x12a00000 | r |
+ (~x >> 11 & 0x1fffe0)); // movn w(r),#(~x >> 16),lsl #16
+ if (!~(x | m))
+ return (0x92800000 | r |
+ (~x << 5 & 0x1fffe0)); // movn x(r),#(~x)
+ if (!~(x | m << 16))
+ return (0x92a00000 | r |
+ (~x >> 11 & 0x1fffe0)); // movn x(r),#(~x >> 16),lsl #16
+ if (!~(x | m << 32))
+ return (0x92c00000 | r |
+ (~x >> 27 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32
+ if (!~(x | m << 48))
+ return (0x92e00000 | r |
+ (~x >> 43 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32
+ if (!(x >> 32) && (e = arm64_encode_bimm64(x | x << 32)) >= 0)
+ return 0x320003e0 | r | (uint32_t)e << 10; // movi w(r),#(x)
+ if ((e = arm64_encode_bimm64(x)) >= 0)
+ return 0xb20003e0 | r | (uint32_t)e << 10; // movi x(r),#(x)
+ return 0;
+}
+
+static void arm64_movimm(int r, uint64_t x)
+{
+ uint32_t i;
+ if ((i = arm64_movi(r, x)))
+ o(i); // a single MOV
+ else {
+ // MOVZ/MOVN and 1-3 MOVKs
+ int z = 0, m = 0;
+ uint32_t mov1 = 0xd2800000; // movz
+ uint64_t x1 = x;
+ for (i = 0; i < 64; i += 16) {
+ z += !(x >> i & 0xffff);
+ m += !(~x >> i & 0xffff);
+ }
+ if (m > z) {
+ x1 = ~x;
+ mov1 = 0x92800000; // movn
+ }
+ for (i = 0; i < 64; i += 16)
+ if (x1 >> i & 0xffff) {
+ o(mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17);
+ // movz/movn x(r),#(*),lsl #(i)
+ break;
+ }
+ for (i += 16; i < 64; i += 16)
+ if (x1 >> i & 0xffff)
+ o(0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17);
+ // movk x(r),#(*),lsl #(i)
+ }
+}
+
+// Patch all branches in list pointed to by t to branch to a:
+ST_FUNC void gsym_addr(int t_, int a_)
+{
+ uint32_t t = t_;
+ uint32_t a = a_;
+ while (t) {
+ unsigned char *ptr = cur_text_section->data + t;
+ uint32_t next = read32le(ptr);
+ if (a - t + 0x8000000 >= 0x10000000)
+ tcc_error("branch out of range");
+ write32le(ptr, (a - t == 4 ? 0xd503201f : // nop
+ 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b
+ t = next;
+ }
+}
+
+// Patch all branches in list pointed to by t to branch to current location:
+ST_FUNC void gsym(int t)
+{
+ gsym_addr(t, ind);
+}
+
+static int arm64_type_size(int t)
+{
+ switch (t & VT_BTYPE) {
+ case VT_INT: return 2;
+ case VT_BYTE: return 0;
+ case VT_SHORT: return 1;
+ case VT_PTR: return 3;
+ case VT_FUNC: return 3;
+ case VT_FLOAT: return 2;
+ case VT_DOUBLE: return 3;
+ case VT_LDOUBLE: return 4;
+ case VT_BOOL: return 0;
+ case VT_LLONG: return 3;
+ }
+ assert(0);
+ return 0;
+}
+
+static void arm64_spoff(int reg, uint64_t off)
+{
+ uint32_t sub = off >> 63;
+ if (sub)
+ off = -off;
+ if (off < 4096)
+ o(0x910003e0 | sub << 30 | reg | off << 10);
+ // (add|sub) x(reg),sp,#(off)
+ else {
+ arm64_movimm(30, off); // use x30 for offset
+ o(0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30
+ }
+}
+
+static void arm64_ldrx(int sg, int sz_, int dst, int bas, uint64_t off)
+{
+ uint32_t sz = sz_;
+ if (sz >= 2)
+ sg = 0;
+ if (!(off & ~((uint32_t)0xfff << sz)))
+ o(0x39400000 | dst | bas << 5 | off << (10 - sz) |
+ (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)]
+ else if (off < 256 || -off <= 256)
+ o(0x38400000 | dst | bas << 5 | (off & 511) << 12 |
+ (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)]
+ else {
+ arm64_movimm(30, off); // use x30 for offset
+ o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 |
+ (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30]
+ }
+}
+
+static void arm64_ldrv(int sz_, int dst, int bas, uint64_t off)
+{
+ uint32_t sz = sz_;
+ if (!(off & ~((uint32_t)0xfff << sz)))
+ o(0x3d400000 | dst | bas << 5 | off << (10 - sz) |
+ (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)]
+ else if (off < 256 || -off <= 256)
+ o(0x3c400000 | dst | bas << 5 | (off & 511) << 12 |
+ (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)]
+ else {
+ arm64_movimm(30, off); // use x30 for offset
+ o(0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 |
+ sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30]
+ }
+}
+
+static void arm64_ldrs(int reg_, int size)
+{
+ uint32_t reg = reg_;
+ // Use x30 for intermediate value in some cases.
+ switch (size) {
+ default: assert(0); break;
+ case 1:
+ arm64_ldrx(0, 0, reg, reg, 0);
+ break;
+ case 2:
+ arm64_ldrx(0, 1, reg, reg, 0);
+ break;
+ case 3:
+ arm64_ldrx(0, 1, 30, reg, 0);
+ arm64_ldrx(0, 0, reg, reg, 2);
+ o(0x2a0043c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #16
+ break;
+ case 4:
+ arm64_ldrx(0, 2, reg, reg, 0);
+ break;
+ case 5:
+ arm64_ldrx(0, 2, 30, reg, 0);
+ arm64_ldrx(0, 0, reg, reg, 4);
+ o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
+ break;
+ case 6:
+ arm64_ldrx(0, 2, 30, reg, 0);
+ arm64_ldrx(0, 1, reg, reg, 4);
+ o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
+ break;
+ case 7:
+ arm64_ldrx(0, 2, 30, reg, 0);
+ arm64_ldrx(0, 2, reg, reg, 3);
+ o(0x53087c00 | reg | reg << 5); // lsr w(reg), w(reg), #8
+ o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
+ break;
+ case 8:
+ arm64_ldrx(0, 3, reg, reg, 0);
+ break;
+ case 9:
+ arm64_ldrx(0, 0, reg + 1, reg, 8);
+ arm64_ldrx(0, 3, reg, reg, 0);
+ break;
+ case 10:
+ arm64_ldrx(0, 1, reg + 1, reg, 8);
+ arm64_ldrx(0, 3, reg, reg, 0);
+ break;
+ case 11:
+ arm64_ldrx(0, 2, reg + 1, reg, 7);
+ o(0x53087c00 | (reg+1) | (reg+1) << 5); // lsr w(reg+1), w(reg+1), #8
+ arm64_ldrx(0, 3, reg, reg, 0);
+ break;
+ case 12:
+ arm64_ldrx(0, 2, reg + 1, reg, 8);
+ arm64_ldrx(0, 3, reg, reg, 0);
+ break;
+ case 13:
+ arm64_ldrx(0, 3, reg + 1, reg, 5);
+ o(0xd358fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #24
+ arm64_ldrx(0, 3, reg, reg, 0);
+ break;
+ case 14:
+ arm64_ldrx(0, 3, reg + 1, reg, 6);
+ o(0xd350fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #16
+ arm64_ldrx(0, 3, reg, reg, 0);
+ break;
+ case 15:
+ arm64_ldrx(0, 3, reg + 1, reg, 7);
+ o(0xd348fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #8
+ arm64_ldrx(0, 3, reg, reg, 0);
+ break;
+ case 16:
+ o(0xa9400000 | reg | (reg+1) << 10 | reg << 5);
+ // ldp x(reg),x(reg+1),[x(reg)]
+ break;
+ }
+}
+
+static void arm64_strx(int sz_, int dst, int bas, uint64_t off)
+{
+ uint32_t sz = sz_;
+ if (!(off & ~((uint32_t)0xfff << sz)))
+ o(0x39000000 | dst | bas << 5 | off << (10 - sz) | sz << 30);
+ // str(*) x(dst),[x(bas],#(off)]
+ else if (off < 256 || -off <= 256)
+ o(0x38000000 | dst | bas << 5 | (off & 511) << 12 | sz << 30);
+ // stur(*) x(dst),[x(bas],#(off)]
+ else {
+ arm64_movimm(30, off); // use x30 for offset
+ o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | sz << 30);
+ // str(*) x(dst),[x(bas),x30]
+ }
+}
+
+static void arm64_strv(int sz_, int dst, int bas, uint64_t off)
+{
+ uint32_t sz = sz_;
+ if (!(off & ~((uint32_t)0xfff << sz)))
+ o(0x3d000000 | dst | bas << 5 | off << (10 - sz) |
+ (sz & 4) << 21 | (sz & 3) << 30); // str (s|d|q)(dst),[x(bas),#(off)]
+ else if (off < 256 || -off <= 256)
+ o(0x3c000000 | dst | bas << 5 | (off & 511) << 12 |
+ (sz & 4) << 21 | (sz & 3) << 30); // stur (s|d|q)(dst),[x(bas),#(off)]
+ else {
+ arm64_movimm(30, off); // use x30 for offset
+ o(0x3c206800 | dst | bas << 5 | (uint32_t)30 << 16 |
+ sz << 30 | (sz & 4) << 21); // str (s|d|q)(dst),[x(bas),x30]
+ }
+}
+
+static void arm64_sym(int r, Sym *sym, unsigned long addend)
+{
+ // Currently TCC's linker does not generate COPY relocations for
+ // STT_OBJECTs when tcc is invoked with "-run". This typically
+ // results in "R_AARCH64_ADR_PREL_PG_HI21 relocation failed" when
+ // a program refers to stdin. A workaround is to avoid that
+ // relocation and use only relocations with unlimited range.
+ int avoid_adrp = 1;
+
+ if (avoid_adrp || sym->a.weak) {
+ // (GCC uses a R_AARCH64_ABS64 in this case.)
+ greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G0_NC, addend);
+ o(0xd2800000 | r); // mov x(rt),#0,lsl #0
+ greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G1_NC, addend);
+ o(0xf2a00000 | r); // movk x(rt),#0,lsl #16
+ greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G2_NC, addend);
+ o(0xf2c00000 | r); // movk x(rt),#0,lsl #32
+ greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G3, addend);
+ o(0xf2e00000 | r); // movk x(rt),#0,lsl #48
+ }
+ else {
+ greloca(cur_text_section, sym, ind, R_AARCH64_ADR_PREL_PG_HI21, addend);
+ o(0x90000000 | r);
+ greloca(cur_text_section, sym, ind, R_AARCH64_ADD_ABS_LO12_NC, addend);
+ o(0x91000000 | r | r << 5);
+ }
+}
+
+ST_FUNC void load(int r, SValue *sv)
+{
+ int svtt = sv->type.t;
+ int svr = sv->r & ~VT_LVAL_TYPE;
+ int svrv = svr & VT_VALMASK;
+ uint64_t svcul = (uint32_t)sv->c.i;
+ svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul;
+
+ if (svr == (VT_LOCAL | VT_LVAL)) {
+ if (IS_FREG(r))
+ arm64_ldrv(arm64_type_size(svtt), fltr(r), 29, svcul);
+ else
+ arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+ intr(r), 29, svcul);
+ return;
+ }
+
+ if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {
+ if (IS_FREG(r))
+ arm64_ldrv(arm64_type_size(svtt), fltr(r), intr(svrv), 0);
+ else
+ arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+ intr(r), intr(svrv), 0);
+ return;
+ }
+
+ if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
+ arm64_sym(30, sv->sym, svcul); // use x30 for address
+ if (IS_FREG(r))
+ arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0);
+ else
+ arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+ intr(r), 30, 0);
+ return;
+ }
+
+ if (svr == (VT_CONST | VT_SYM)) {
+ arm64_sym(intr(r), sv->sym, svcul);
+ return;
+ }
+
+ if (svr == VT_CONST) {
+ if ((svtt & VT_BTYPE) != VT_VOID)
+ arm64_movimm(intr(r), arm64_type_size(svtt) == 3 ?
+ sv->c.i : (uint32_t)svcul);
+ return;
+ }
+
+ if (svr < VT_CONST) {
+ if (IS_FREG(r) && IS_FREG(svr))
+ if (svtt == VT_LDOUBLE)
+ o(0x4ea01c00 | fltr(r) | fltr(svr) << 5);
+ // mov v(r).16b,v(svr).16b
+ else
+ o(0x1e604000 | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr)
+ else if (!IS_FREG(r) && !IS_FREG(svr))
+ o(0xaa0003e0 | intr(r) | intr(svr) << 16); // mov x(r),x(svr)
+ else
+ assert(0);
+ return;
+ }
+
+ if (svr == VT_LOCAL) {
+ if (-svcul < 0x1000)
+ o(0xd10003a0 | intr(r) | -svcul << 10); // sub x(r),x29,#...
+ else {
+ arm64_movimm(30, -svcul); // use x30 for offset
+ o(0xcb0003a0 | intr(r) | (uint32_t)30 << 16); // sub x(r),x29,x30
+ }
+ return;
+ }
+
+ if (svr == VT_JMP || svr == VT_JMPI) {
+ int t = (svr == VT_JMPI);
+ arm64_movimm(intr(r), t);
+ o(0x14000002); // b .+8
+ gsym(svcul);
+ arm64_movimm(intr(r), t ^ 1);
+ return;
+ }
+
+ if (svr == (VT_LLOCAL | VT_LVAL)) {
+ arm64_ldrx(0, 3, 30, 29, svcul); // use x30 for offset
+ if (IS_FREG(r))
+ arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0);
+ else
+ arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+ intr(r), 30, 0);
+ return;
+ }
+
+ printf("load(%x, (%x, %x, %llx))\n", r, svtt, sv->r, (long long)svcul);
+ assert(0);
+}
+
+ST_FUNC void store(int r, SValue *sv)
+{
+ int svtt = sv->type.t;
+ int svr = sv->r & ~VT_LVAL_TYPE;
+ int svrv = svr & VT_VALMASK;
+ uint64_t svcul = (uint32_t)sv->c.i;
+ svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul;
+
+ if (svr == (VT_LOCAL | VT_LVAL)) {
+ if (IS_FREG(r))
+ arm64_strv(arm64_type_size(svtt), fltr(r), 29, svcul);
+ else
+ arm64_strx(arm64_type_size(svtt), intr(r), 29, svcul);
+ return;
+ }
+
+ if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {
+ if (IS_FREG(r))
+ arm64_strv(arm64_type_size(svtt), fltr(r), intr(svrv), 0);
+ else
+ arm64_strx(arm64_type_size(svtt), intr(r), intr(svrv), 0);
+ return;
+ }
+
+ if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
+ arm64_sym(30, sv->sym, svcul); // use x30 for address
+ if (IS_FREG(r))
+ arm64_strv(arm64_type_size(svtt), fltr(r), 30, 0);
+ else
+ arm64_strx(arm64_type_size(svtt), intr(r), 30, 0);
+ return;
+ }
+
+ printf("store(%x, (%x, %x, %llx))\n", r, svtt, sv->r, (long long)svcul);
+ assert(0);
+}
+
+static void arm64_gen_bl_or_b(int b)
+{
+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+ assert(!b && (vtop->r & VT_SYM));
+ greloca(cur_text_section, vtop->sym, ind, R_AARCH64_CALL26, 0);
+ o(0x94000000); // bl .
+ }
+ else
+ o(0xd61f0000 | (uint32_t)!b << 21 | intr(gv(RC_R30)) << 5); // br/blr
+}
+
+static int arm64_hfa_aux(CType *type, int *fsize, int num)
+{
+ if (is_float(type->t)) {
+ int a, n = type_size(type, &a);
+ if (num >= 4 || (*fsize && *fsize != n))
+ return -1;
+ *fsize = n;
+ return num + 1;
+ }
+ else if ((type->t & VT_BTYPE) == VT_STRUCT) {
+ int is_struct = 0; // rather than union
+ Sym *field;
+ for (field = type->ref->next; field; field = field->next)
+ if (field->c) {
+ is_struct = 1;
+ break;
+ }
+ if (is_struct) {
+ int num0 = num;
+ for (field = type->ref->next; field; field = field->next) {
+ if (field->c != (num - num0) * *fsize)
+ return -1;
+ num = arm64_hfa_aux(&field->type, fsize, num);
+ if (num == -1)
+ return -1;
+ }
+ if (type->ref->c != (num - num0) * *fsize)
+ return -1;
+ return num;
+ }
+ else { // union
+ int num0 = num;
+ for (field = type->ref->next; field; field = field->next) {
+ int num1 = arm64_hfa_aux(&field->type, fsize, num0);
+ if (num1 == -1)
+ return -1;
+ num = num1 < num ? num : num1;
+ }
+ if (type->ref->c != (num - num0) * *fsize)
+ return -1;
+ return num;
+ }
+ }
+ else if (type->t & VT_ARRAY) {
+ int num1;
+ if (!type->ref->c)
+ return num;
+ num1 = arm64_hfa_aux(&type->ref->type, fsize, num);
+ if (num1 == -1 || (num1 != num && type->ref->c > 4))
+ return -1;
+ num1 = num + type->ref->c * (num1 - num);
+ if (num1 > 4)
+ return -1;
+ return num1;
+ }
+ return -1;
+}
+
+static int arm64_hfa(CType *type, int *fsize)
+{
+ if ((type->t & VT_BTYPE) == VT_STRUCT || (type->t & VT_ARRAY)) {
+ int sz = 0;
+ int n = arm64_hfa_aux(type, &sz, 0);
+ if (0 < n && n <= 4) {
+ if (fsize)
+ *fsize = sz;
+ return n;
+ }
+ }
+ return 0;
+}
+
+static unsigned long arm64_pcs_aux(int n, CType **type, unsigned long *a)
+{
+ int nx = 0; // next integer register
+ int nv = 0; // next vector register
+ unsigned long ns = 32; // next stack offset
+ int i;
+
+ for (i = 0; i < n; i++) {
+ int hfa = arm64_hfa(type[i], 0);
+ int size, align;
+
+ if ((type[i]->t & VT_ARRAY) ||
+ (type[i]->t & VT_BTYPE) == VT_FUNC)
+ size = align = 8;
+ else
+ size = type_size(type[i], &align);
+
+ if (hfa)
+ // B.2
+ ;
+ else if (size > 16) {
+ // B.3: replace with pointer
+ if (nx < 8)
+ a[i] = nx++ << 1 | 1;
+ else {
+ ns = (ns + 7) & ~7;
+ a[i] = ns | 1;
+ ns += 8;
+ }
+ continue;
+ }
+ else if ((type[i]->t & VT_BTYPE) == VT_STRUCT)
+ // B.4
+ size = (size + 7) & ~7;
+
+ // C.1
+ if (is_float(type[i]->t) && nv < 8) {
+ a[i] = 16 + (nv++ << 1);
+ continue;
+ }
+
+ // C.2
+ if (hfa && nv + hfa <= 8) {
+ a[i] = 16 + (nv << 1);
+ nv += hfa;
+ continue;
+ }
+
+ // C.3
+ if (hfa) {
+ nv = 8;
+ size = (size + 7) & ~7;
+ }
+
+ // C.4
+ if (hfa || (type[i]->t & VT_BTYPE) == VT_LDOUBLE) {
+ ns = (ns + 7) & ~7;
+ ns = (ns + align - 1) & -align;
+ }
+
+ // C.5
+ if ((type[i]->t & VT_BTYPE) == VT_FLOAT)
+ size = 8;
+
+ // C.6
+ if (hfa || is_float(type[i]->t)) {
+ a[i] = ns;
+ ns += size;
+ continue;
+ }
+
+ // C.7
+ if ((type[i]->t & VT_BTYPE) != VT_STRUCT && size <= 8 && nx < 8) {
+ a[i] = nx++ << 1;
+ continue;
+ }
+
+ // C.8
+ if (align == 16)
+ nx = (nx + 1) & ~1;
+
+ // C.9
+ if ((type[i]->t & VT_BTYPE) != VT_STRUCT && size == 16 && nx < 7) {
+ a[i] = nx << 1;
+ nx += 2;
+ continue;
+ }
+
+ // C.10
+ if ((type[i]->t & VT_BTYPE) == VT_STRUCT && size <= (8 - nx) * 8) {
+ a[i] = nx << 1;
+ nx += (size + 7) >> 3;
+ continue;
+ }
+
+ // C.11
+ nx = 8;
+
+ // C.12
+ ns = (ns + 7) & ~7;
+ ns = (ns + align - 1) & -align;
+
+ // C.13
+ if ((type[i]->t & VT_BTYPE) == VT_STRUCT) {
+ a[i] = ns;
+ ns += size;
+ continue;
+ }
+
+ // C.14
+ if (size < 8)
+ size = 8;
+
+ // C.15
+ a[i] = ns;
+ ns += size;
+ }
+
+ return ns - 32;
+}
+
+static unsigned long arm64_pcs(int n, CType **type, unsigned long *a)
+{
+ unsigned long stack;
+
+ // Return type:
+ if ((type[0]->t & VT_BTYPE) == VT_VOID)
+ a[0] = -1;
+ else {
+ arm64_pcs_aux(1, type, a);
+ assert(a[0] == 0 || a[0] == 1 || a[0] == 16);
+ }
+
+ // Argument types:
+ stack = arm64_pcs_aux(n, type + 1, a + 1);
+
+ if (0) {
+ int i;
+ for (i = 0; i <= n; i++) {
+ if (!i)
+ printf("arm64_pcs return: ");
+ else
+ printf("arm64_pcs arg %d: ", i);
+ if (a[i] == (unsigned long)-1)
+ printf("void\n");
+ else if (a[i] == 1 && !i)
+ printf("X8 pointer\n");
+ else if (a[i] < 16)
+ printf("X%lu%s\n", a[i] / 2, a[i] & 1 ? " pointer" : "");
+ else if (a[i] < 32)
+ printf("V%lu\n", a[i] / 2 - 8);
+ else
+ printf("stack %lu%s\n",
+ (a[i] - 32) & ~1, a[i] & 1 ? " pointer" : "");
+ }
+ }
+
+ return stack;
+}
+
+ST_FUNC void gfunc_call(int nb_args)
+{
+ CType *return_type;
+ CType **t;
+ unsigned long *a, *a1;
+ unsigned long stack;
+ int i;
+
+ return_type = &vtop[-nb_args].type.ref->type;
+ if ((return_type->t & VT_BTYPE) == VT_STRUCT)
+ --nb_args;
+
+ t = tcc_malloc((nb_args + 1) * sizeof(*t));
+ a = tcc_malloc((nb_args + 1) * sizeof(*a));
+ a1 = tcc_malloc((nb_args + 1) * sizeof(*a1));
+
+ t[0] = return_type;
+ for (i = 0; i < nb_args; i++)
+ t[nb_args - i] = &vtop[-i].type;
+
+ stack = arm64_pcs(nb_args, t, a);
+
+ // Allocate space for structs replaced by pointer:
+ for (i = nb_args; i; i--)
+ if (a[i] & 1) {
+ SValue *arg = &vtop[i - nb_args];
+ int align, size = type_size(&arg->type, &align);
+ assert((arg->type.t & VT_BTYPE) == VT_STRUCT);
+ stack = (stack + align - 1) & -align;
+ a1[i] = stack;
+ stack += size;
+ }
+
+ stack = (stack + 15) >> 4 << 4;
+
+ assert(stack < 0x1000);
+ if (stack)
+ o(0xd10003ff | stack << 10); // sub sp,sp,#(n)
+
+ // First pass: set all values on stack
+ for (i = nb_args; i; i--) {
+ vpushv(vtop - nb_args + i);
+
+ if (a[i] & 1) {
+ // struct replaced by pointer
+ int r = get_reg(RC_INT);
+ arm64_spoff(intr(r), a1[i]);
+ vset(&vtop->type, r | VT_LVAL, 0);
+ vswap();
+ vstore();
+ if (a[i] >= 32) {
+ // pointer on stack
+ r = get_reg(RC_INT);
+ arm64_spoff(intr(r), a1[i]);
+ arm64_strx(3, intr(r), 31, (a[i] - 32) >> 1 << 1);
+ }
+ }
+ else if (a[i] >= 32) {
+ // value on stack
+ if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+ int r = get_reg(RC_INT);
+ arm64_spoff(intr(r), a[i] - 32);
+ vset(&vtop->type, r | VT_LVAL, 0);
+ vswap();
+ vstore();
+ }
+ else if (is_float(vtop->type.t)) {
+ gv(RC_FLOAT);
+ arm64_strv(arm64_type_size(vtop[0].type.t),
+ fltr(vtop[0].r), 31, a[i] - 32);
+ }
+ else {
+ gv(RC_INT);
+ arm64_strx(arm64_type_size(vtop[0].type.t),
+ intr(vtop[0].r), 31, a[i] - 32);
+ }
+ }
+
+ --vtop;
+ }
+
+ // Second pass: assign values to registers
+ for (i = nb_args; i; i--, vtop--) {
+ if (a[i] < 16 && !(a[i] & 1)) {
+ // value in general-purpose registers
+ if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+ int align, size = type_size(&vtop->type, &align);
+ vtop->type.t = VT_PTR;
+ gaddrof();
+ gv(RC_R(a[i] / 2));
+ arm64_ldrs(a[i] / 2, size);
+ }
+ else
+ gv(RC_R(a[i] / 2));
+ }
+ else if (a[i] < 16)
+ // struct replaced by pointer in register
+ arm64_spoff(a[i] / 2, a1[i]);
+ else if (a[i] < 32) {
+ // value in floating-point registers
+ if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+ uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
+ vtop->type.t = VT_PTR;
+ gaddrof();
+ gv(RC_R30);
+ for (j = 0; j < n; j++)
+ o(0x3d4003c0 |
+ (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
+ (a[i] / 2 - 8 + j) |
+ j << 10); // ldr ([sdq])(*),[x30,#(j * sz)]
+ }
+ else
+ gv(RC_F(a[i] / 2 - 8));
+ }
+ }
+
+ if ((return_type->t & VT_BTYPE) == VT_STRUCT) {
+ if (a[0] == 1) {
+ // indirect return: set x8 and discard the stack value
+ gv(RC_R(8));
+ --vtop;
+ }
+ else
+ // return in registers: keep the address for after the call
+ vswap();
+ }
+
+ save_regs(0);
+ arm64_gen_bl_or_b(0);
+ --vtop;
+ if (stack)
+ o(0x910003ff | stack << 10); // add sp,sp,#(n)
+
+ {
+ int rt = return_type->t;
+ int bt = rt & VT_BTYPE;
+ if (bt == VT_BYTE || bt == VT_SHORT)
+ // Promote small integers:
+ o(0x13001c00 | (bt == VT_SHORT) << 13 |
+ (uint32_t)!!(rt & VT_UNSIGNED) << 30); // [su]xt[bh] w0,w0
+ else if (bt == VT_STRUCT && !(a[0] & 1)) {
+ // A struct was returned in registers, so write it out:
+ gv(RC_R(8));
+ --vtop;
+ if (a[0] == 0) {
+ int align, size = type_size(return_type, &align);
+ assert(size <= 16);
+ if (size > 8)
+ o(0xa9000500); // stp x0,x1,[x8]
+ else if (size)
+ arm64_strx(size > 4 ? 3 : size > 2 ? 2 : size > 1, 0, 8, 0);
+
+ }
+ else if (a[0] == 16) {
+ uint32_t j, sz, n = arm64_hfa(return_type, &sz);
+ for (j = 0; j < n; j++)
+ o(0x3d000100 |
+ (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
+ (a[i] / 2 - 8 + j) |
+ j << 10); // str ([sdq])(*),[x8,#(j * sz)]
+ }
+ }
+ }
+
+ tcc_free(a1);
+ tcc_free(a);
+ tcc_free(t);
+}
+
+static unsigned long arm64_func_va_list_stack;
+static int arm64_func_va_list_gr_offs;
+static int arm64_func_va_list_vr_offs;
+static int arm64_func_sub_sp_offset;
+
+ST_FUNC void gfunc_prolog(CType *func_type)
+{
+ int n = 0;
+ int i = 0;
+ Sym *sym;
+ CType **t;
+ unsigned long *a;
+
+ // Why doesn't the caller (gen_function) set func_vt?
+ func_vt = func_type->ref->type;
+ func_vc = 144; // offset of where x8 is stored
+
+ for (sym = func_type->ref; sym; sym = sym->next)
+ ++n;
+ t = tcc_malloc(n * sizeof(*t));
+ a = tcc_malloc(n * sizeof(*a));
+
+ for (sym = func_type->ref; sym; sym = sym->next)
+ t[i++] = &sym->type;
+
+ arm64_func_va_list_stack = arm64_pcs(n - 1, t, a);
+
+ o(0xa9b27bfd); // stp x29,x30,[sp,#-224]!
+ o(0xad0087e0); // stp q0,q1,[sp,#16]
+ o(0xad018fe2); // stp q2,q3,[sp,#48]
+ o(0xad0297e4); // stp q4,q5,[sp,#80]
+ o(0xad039fe6); // stp q6,q7,[sp,#112]
+ o(0xa90923e8); // stp x8,x8,[sp,#144]
+ o(0xa90a07e0); // stp x0,x1,[sp,#160]
+ o(0xa90b0fe2); // stp x2,x3,[sp,#176]
+ o(0xa90c17e4); // stp x4,x5,[sp,#192]
+ o(0xa90d1fe6); // stp x6,x7,[sp,#208]
+
+ arm64_func_va_list_gr_offs = -64;
+ arm64_func_va_list_vr_offs = -128;
+
+ for (i = 1, sym = func_type->ref->next; sym; i++, sym = sym->next) {
+ int off = (a[i] < 16 ? 160 + a[i] / 2 * 8 :
+ a[i] < 32 ? 16 + (a[i] - 16) / 2 * 16 :
+ 224 + ((a[i] - 32) >> 1 << 1));
+ sym_push(sym->v & ~SYM_FIELD, &sym->type,
+ (a[i] & 1 ? VT_LLOCAL : VT_LOCAL) | lvalue_type(sym->type.t),
+ off);
+
+ if (a[i] < 16) {
+ int align, size = type_size(&sym->type, &align);
+ arm64_func_va_list_gr_offs = (a[i] / 2 - 7 +
+ (!(a[i] & 1) && size > 8)) * 8;
+ }
+ else if (a[i] < 32) {
+ uint32_t hfa = arm64_hfa(&sym->type, 0);
+ arm64_func_va_list_vr_offs = (a[i] / 2 - 16 +
+ (hfa ? hfa : 1)) * 16;
+ }
+
+ // HFAs of float and double need to be written differently:
+ if (16 <= a[i] && a[i] < 32 && (sym->type.t & VT_BTYPE) == VT_STRUCT) {
+ uint32_t j, sz, k = arm64_hfa(&sym->type, &sz);
+ if (sz < 16)
+ for (j = 0; j < k; j++) {
+ o(0x3d0003e0 | -(sz & 8) << 27 | (sz & 4) << 29 |
+ ((a[i] - 16) / 2 + j) | (off / sz + j) << 10);
+ // str ([sdq])(*),[sp,#(j * sz)]
+ }
+ }
+ }
+
+ tcc_free(a);
+ tcc_free(t);
+
+ o(0x910003fd); // mov x29,sp
+ arm64_func_sub_sp_offset = ind;
+ // In gfunc_epilog these will be replaced with code to decrement SP:
+ o(0xd503201f); // nop
+ o(0xd503201f); // nop
+ loc = 0;
+}
+
+ST_FUNC void gen_va_start(void)
+{
+ int r;
+ --vtop; // we don't need the "arg"
+ gaddrof();
+ r = intr(gv(RC_INT));
+
+ if (arm64_func_va_list_stack) {
+ //xx could use add (immediate) here
+ arm64_movimm(30, arm64_func_va_list_stack + 224);
+ o(0x8b1e03be); // add x30,x29,x30
+ }
+ else
+ o(0x910383be); // add x30,x29,#224
+ o(0xf900001e | r << 5); // str x30,[x(r)]
+
+ if (arm64_func_va_list_gr_offs) {
+ if (arm64_func_va_list_stack)
+ o(0x910383be); // add x30,x29,#224
+ o(0xf900041e | r << 5); // str x30,[x(r),#8]
+ }
+
+ if (arm64_func_va_list_vr_offs) {
+ o(0x910243be); // add x30,x29,#144
+ o(0xf900081e | r << 5); // str x30,[x(r),#16]
+ }
+
+ arm64_movimm(30, arm64_func_va_list_gr_offs);
+ o(0xb900181e | r << 5); // str w30,[x(r),#24]
+
+ arm64_movimm(30, arm64_func_va_list_vr_offs);
+ o(0xb9001c1e | r << 5); // str w30,[x(r),#28]
+
+ --vtop;
+}
+
+ST_FUNC void gen_va_arg(CType *t)
+{
+ int align, size = type_size(t, &align);
+ int fsize, hfa = arm64_hfa(t, &fsize);
+ uint32_t r0, r1;
+
+ if (is_float(t->t)) {
+ hfa = 1;
+ fsize = size;
+ }
+
+ gaddrof();
+ r0 = intr(gv(RC_INT));
+ r1 = get_reg(RC_INT);
+ vtop[0].r = r1 | lvalue_type(t->t);
+ r1 = intr(r1);
+
+ if (!hfa) {
+ uint32_t n = size > 16 ? 8 : (size + 7) & -8;
+ o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs
+ if (align == 16) {
+ assert(0); // this path untested but needed for __uint128_t
+ o(0x11003fde); // add w30,w30,#15
+ o(0x121c6fde); // and w30,w30,#-16
+ }
+ o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)
+ o(0x540000ad); // b.le .+20
+ o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
+ o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)
+ o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
+ o(0x14000004); // b .+16
+ o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs
+ o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top
+ o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
+ if (size > 16)
+ o(0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)]
+ }
+ else {
+ uint32_t rsz = hfa << 4;
+ uint32_t ssz = (size + 7) & -(uint32_t)8;
+ uint32_t b1, b2;
+ o(0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs
+ o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)
+ b1 = ind; o(0x5400000d); // b.le lab1
+ o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
+ if (fsize == 16) {
+ o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15
+ o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16
+ }
+ o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)
+ o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
+ b2 = ind; o(0x14000000); // b lab2
+ // lab1:
+ write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3);
+ o(0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs
+ o(0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top
+ if (hfa == 1 || fsize == 16)
+ o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
+ else {
+ // We need to change the layout of this HFA.
+ // Get some space on the stack using global variable "loc":
+ loc = (loc - size) & -(uint32_t)align;
+ o(0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw
+ arm64_movimm(r1, loc);
+ o(0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1)
+ o(0x4c402bdc | (uint32_t)fsize << 7 |
+ (uint32_t)(hfa == 2) << 15 |
+ (uint32_t)(hfa == 3) << 14); // ld1 {v28.(4s|2d),...},[x30]
+ o(0x0d00801c | r1 << 5 | (fsize == 8) << 10 |
+ (uint32_t)(hfa != 2) << 13 |
+ (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]
+ }
+ // lab2:
+ write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2);
+ }
+}
+
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret,
+ int *align, int *regsize)
+{
+ return 0;
+}
+
+ST_FUNC void gfunc_return(CType *func_type)
+{
+ CType *t = func_type;
+ unsigned long a;
+
+ arm64_pcs(0, &t, &a);
+ switch (a) {
+ case -1:
+ break;
+ case 0:
+ if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
+ int align, size = type_size(func_type, &align);
+ gaddrof();
+ gv(RC_R(0));
+ arm64_ldrs(0, size);
+ }
+ else
+ gv(RC_IRET);
+ break;
+ case 1: {
+ CType type = *func_type;
+ mk_pointer(&type);
+ vset(&type, VT_LOCAL | VT_LVAL, func_vc);
+ indir();
+ vswap();
+ vstore();
+ break;
+ }
+ case 16:
+ if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
+ uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
+ gaddrof();
+ gv(RC_R(0));
+ for (j = 0; j < n; j++)
+ o(0x3d400000 |
+ (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
+ j | j << 10); // ldr ([sdq])(*),[x0,#(j * sz)]
+ }
+ else
+ gv(RC_FRET);
+ break;
+ default:
+ assert(0);
+ }
+ vtop--;
+}
+
+ST_FUNC void gfunc_epilog(void)
+{
+ if (loc) {
+ // Insert instructions to subtract size of stack frame from SP.
+ unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset;
+ uint64_t diff = (-loc + 15) & ~15;
+ if (!(diff >> 24)) {
+ if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff)
+ write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10);
+ if (diff >> 12) // sub sp,sp,#(diff >> 12),lsl #12
+ write32le(ptr + 4, 0xd14003ff | (diff >> 12) << 10);
+ }
+ else {
+ // In this case we may subtract more than necessary,
+ // but always less than 17/16 of what we were aiming for.
+ int i = 0;
+ int j = 0;
+ while (diff >> 20) {
+ diff = (diff + 0xffff) >> 16;
+ ++i;
+ }
+ while (diff >> 16) {
+ diff = (diff + 1) >> 1;
+ ++j;
+ }
+ write32le(ptr, 0xd2800010 | diff << 5 | i << 21);
+ // mov x16,#(diff),lsl #(16 * i)
+ write32le(ptr + 4, 0xcb3063ff | j << 10);
+ // sub sp,sp,x16,lsl #(j)
+ }
+ }
+ o(0x910003bf); // mov sp,x29
+ o(0xa8ce7bfd); // ldp x29,x30,[sp],#224
+
+ o(0xd65f03c0); // ret
+}
+
+// Generate forward branch to label:
+ST_FUNC int gjmp(int t)
+{
+ int r = ind;
+ if (nocode_wanted)
+ return t;
+ o(t);
+ return r;
+}
+
+// Generate branch to known address:
+ST_FUNC void gjmp_addr(int a)
+{
+ assert(a - ind + 0x8000000 < 0x10000000);
+ o(0x14000000 | ((a - ind) >> 2 & 0x3ffffff));
+}
+
+ST_FUNC int gtst(int inv, int t)
+{
+ int bt = vtop->type.t & VT_BTYPE;
+ if (bt == VT_LDOUBLE) {
+ uint32_t a, b, f = fltr(gv(RC_FLOAT));
+ a = get_reg(RC_INT);
+ vpushi(0);
+ vtop[0].r = a;
+ b = get_reg(RC_INT);
+ a = intr(a);
+ b = intr(b);
+ o(0x4e083c00 | a | f << 5); // mov x(a),v(f).d[0]
+ o(0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1]
+ o(0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1
+ o(0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8
+ --vtop;
+ }
+ else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
+ uint32_t a = fltr(gv(RC_FLOAT));
+ o(0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp
+ o(0x54000040 | !!inv); // b.eq/b.ne .+8
+ }
+ else {
+ uint32_t ll = (bt == VT_PTR || bt == VT_LLONG);
+ uint32_t a = intr(gv(RC_INT));
+ o(0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+8
+ }
+ --vtop;
+ return gjmp(t);
+}
+
+static int arm64_iconst(uint64_t *val, SValue *sv)
+{
+ if ((sv->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+ return 0;
+ if (val) {
+ int t = sv->type.t;
+ int bt = t & VT_BTYPE;
+ *val = ((bt == VT_LLONG || bt == VT_PTR) ? sv->c.i :
+ (uint32_t)sv->c.i |
+ (t & VT_UNSIGNED ? 0 : -(sv->c.i & 0x80000000)));
+ }
+ return 1;
+}
+
+static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val,
+ uint32_t x, uint32_t a)
+{
+ if (op == '-' && !rev) {
+ val = -val;
+ op = '+';
+ }
+ val = l ? val : (uint32_t)val;
+
+ switch (op) {
+
+ case '+': {
+ uint32_t s = l ? val >> 63 : val >> 31;
+ val = s ? -val : val;
+ val = l ? val : (uint32_t)val;
+ if (!(val & ~(uint64_t)0xfff))
+ o(0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10);
+ else if (!(val & ~(uint64_t)0xfff000))
+ o(0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10);
+ else {
+ arm64_movimm(30, val); // use x30
+ o(0x0b1e0000 | l << 31 | s << 30 | x | a << 5);
+ }
+ return 1;
+ }
+
+ case '-':
+ if (!val)
+ o(0x4b0003e0 | l << 31 | x | a << 16); // neg
+ else if (val == (l ? (uint64_t)-1 : (uint32_t)-1))
+ o(0x2a2003e0 | l << 31 | x | a << 16); // mvn
+ else {
+ arm64_movimm(30, val); // use x30
+ o(0x4b0003c0 | l << 31 | x | a << 16); // sub
+ }
+ return 1;
+
+ case '^':
+ if (val == -1 || (val == 0xffffffff && !l)) {
+ o(0x2a2003e0 | l << 31 | x | a << 16); // mvn
+ return 1;
+ }
+ // fall through
+ case '&':
+ case '|': {
+ int e = arm64_encode_bimm64(l ? val : val | val << 32);
+ if (e < 0)
+ return 0;
+ o((op == '&' ? 0x12000000 :
+ op == '|' ? 0x32000000 : 0x52000000) |
+ l << 31 | x | a << 5 | (uint32_t)e << 10);
+ return 1;
+ }
+
+ case TOK_SAR:
+ case TOK_SHL:
+ case TOK_SHR: {
+ uint32_t n = 32 << l;
+ val = val & (n - 1);
+ if (rev)
+ return 0;
+ if (!val)
+ assert(0);
+ else if (op == TOK_SHL)
+ o(0x53000000 | l << 31 | l << 22 | x | a << 5 |
+ (n - val) << 16 | (n - 1 - val) << 10); // lsl
+ else
+ o(0x13000000 | (op == TOK_SHR) << 30 | l << 31 | l << 22 |
+ x | a << 5 | val << 16 | (n - 1) << 10); // lsr/asr
+ return 1;
+ }
+
+ }
+ return 0;
+}
+
+static void arm64_gen_opil(int op, uint32_t l)
+{
+ uint32_t x, a, b;
+
+ // Special treatment for operations with a constant operand:
+ {
+ uint64_t val;
+ int rev = 1;
+
+ if (arm64_iconst(0, &vtop[0])) {
+ vswap();
+ rev = 0;
+ }
+ if (arm64_iconst(&val, &vtop[-1])) {
+ gv(RC_INT);
+ a = intr(vtop[0].r);
+ --vtop;
+ x = get_reg(RC_INT);
+ ++vtop;
+ if (arm64_gen_opic(op, l, rev, val, intr(x), a)) {
+ vtop[0].r = x;
+ vswap();
+ --vtop;
+ return;
+ }
+ }
+ if (!rev)
+ vswap();
+ }
+
+ gv2(RC_INT, RC_INT);
+ assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST);
+ a = intr(vtop[-1].r);
+ b = intr(vtop[0].r);
+ vtop -= 2;
+ x = get_reg(RC_INT);
+ ++vtop;
+ vtop[0].r = x;
+ x = intr(x);
+
+ switch (op) {
+ case '%':
+ // Use x30 for quotient:
+ o(0x1ac00c00 | l << 31 | 30 | a << 5 | b << 16); // sdiv
+ o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
+ b << 16 | a << 10); // msub
+ break;
+ case '&':
+ o(0x0a000000 | l << 31 | x | a << 5 | b << 16); // and
+ break;
+ case '*':
+ o(0x1b007c00 | l << 31 | x | a << 5 | b << 16); // mul
+ break;
+ case '+':
+ o(0x0b000000 | l << 31 | x | a << 5 | b << 16); // add
+ break;
+ case '-':
+ o(0x4b000000 | l << 31 | x | a << 5 | b << 16); // sub
+ break;
+ case '/':
+ o(0x1ac00c00 | l << 31 | x | a << 5 | b << 16); // sdiv
+ break;
+ case '^':
+ o(0x4a000000 | l << 31 | x | a << 5 | b << 16); // eor
+ break;
+ case '|':
+ o(0x2a000000 | l << 31 | x | a << 5 | b << 16); // orr
+ break;
+ case TOK_EQ:
+ o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+ o(0x1a9f17e0 | x); // cset wA,eq
+ break;
+ case TOK_GE:
+ o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+ o(0x1a9fb7e0 | x); // cset wA,ge
+ break;
+ case TOK_GT:
+ o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+ o(0x1a9fd7e0 | x); // cset wA,gt
+ break;
+ case TOK_LE:
+ o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+ o(0x1a9fc7e0 | x); // cset wA,le
+ break;
+ case TOK_LT:
+ o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+ o(0x1a9fa7e0 | x); // cset wA,lt
+ break;
+ case TOK_NE:
+ o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+ o(0x1a9f07e0 | x); // cset wA,ne
+ break;
+ case TOK_SAR:
+ o(0x1ac02800 | l << 31 | x | a << 5 | b << 16); // asr
+ break;
+ case TOK_SHL:
+ o(0x1ac02000 | l << 31 | x | a << 5 | b << 16); // lsl
+ break;
+ case TOK_SHR:
+ o(0x1ac02400 | l << 31 | x | a << 5 | b << 16); // lsr
+ break;
+ case TOK_UDIV:
+ case TOK_PDIV:
+ o(0x1ac00800 | l << 31 | x | a << 5 | b << 16); // udiv
+ break;
+ case TOK_UGE:
+ o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+ o(0x1a9f37e0 | x); // cset wA,cs
+ break;
+ case TOK_UGT:
+ o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+ o(0x1a9f97e0 | x); // cset wA,hi
+ break;
+ case TOK_ULT:
+ o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+ o(0x1a9f27e0 | x); // cset wA,cc
+ break;
+ case TOK_ULE:
+ o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+ o(0x1a9f87e0 | x); // cset wA,ls
+ break;
+ case TOK_UMOD:
+ // Use x30 for quotient:
+ o(0x1ac00800 | l << 31 | 30 | a << 5 | b << 16); // udiv
+ o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
+ b << 16 | a << 10); // msub
+ break;
+ default:
+ assert(0);
+ }
+}
+
+ST_FUNC void gen_opi(int op)
+{
+ arm64_gen_opil(op, 0);
+}
+
+ST_FUNC void gen_opl(int op)
+{
+ arm64_gen_opil(op, 1);
+}
+
+ST_FUNC void gen_opf(int op)
+{
+ uint32_t x, a, b, dbl;
+
+ if (vtop[0].type.t == VT_LDOUBLE) {
+ CType type = vtop[0].type;
+ int func = 0;
+ int cond = -1;
+ switch (op) {
+ case '*': func = TOK___multf3; break;
+ case '+': func = TOK___addtf3; break;
+ case '-': func = TOK___subtf3; break;
+ case '/': func = TOK___divtf3; break;
+ case TOK_EQ: func = TOK___eqtf2; cond = 1; break;
+ case TOK_NE: func = TOK___netf2; cond = 0; break;
+ case TOK_LT: func = TOK___lttf2; cond = 10; break;
+ case TOK_GE: func = TOK___getf2; cond = 11; break;
+ case TOK_LE: func = TOK___letf2; cond = 12; break;
+ case TOK_GT: func = TOK___gttf2; cond = 13; break;
+ default: assert(0); break;
+ }
+ vpush_global_sym(&func_old_type, func);
+ vrott(3);
+ gfunc_call(2);
+ vpushi(0);
+ vtop->r = cond < 0 ? REG_FRET : REG_IRET;
+ if (cond < 0)
+ vtop->type = type;
+ else {
+ o(0x7100001f); // cmp w0,#0
+ o(0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)
+ }
+ return;
+ }
+
+ dbl = vtop[0].type.t != VT_FLOAT;
+ gv2(RC_FLOAT, RC_FLOAT);
+ assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST);
+ a = fltr(vtop[-1].r);
+ b = fltr(vtop[0].r);
+ vtop -= 2;
+ switch (op) {
+ case TOK_EQ: case TOK_NE:
+ case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT:
+ x = get_reg(RC_INT);
+ ++vtop;
+ vtop[0].r = x;
+ x = intr(x);
+ break;
+ default:
+ x = get_reg(RC_FLOAT);
+ ++vtop;
+ vtop[0].r = x;
+ x = fltr(x);
+ break;
+ }
+
+ switch (op) {
+ case '*':
+ o(0x1e200800 | dbl << 22 | x | a << 5 | b << 16); // fmul
+ break;
+ case '+':
+ o(0x1e202800 | dbl << 22 | x | a << 5 | b << 16); // fadd
+ break;
+ case '-':
+ o(0x1e203800 | dbl << 22 | x | a << 5 | b << 16); // fsub
+ break;
+ case '/':
+ o(0x1e201800 | dbl << 22 | x | a << 5 | b << 16); // fdiv
+ break;
+ case TOK_EQ:
+ o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+ o(0x1a9f17e0 | x); // cset w(x),eq
+ break;
+ case TOK_GE:
+ o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+ o(0x1a9fb7e0 | x); // cset w(x),ge
+ break;
+ case TOK_GT:
+ o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+ o(0x1a9fd7e0 | x); // cset w(x),gt
+ break;
+ case TOK_LE:
+ o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+ o(0x1a9f87e0 | x); // cset w(x),ls
+ break;
+ case TOK_LT:
+ o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+ o(0x1a9f57e0 | x); // cset w(x),mi
+ break;
+ case TOK_NE:
+ o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+ o(0x1a9f07e0 | x); // cset w(x),ne
+ break;
+ default:
+ assert(0);
+ }
+}
+
+// Generate sign extension from 32 to 64 bits:
+ST_FUNC void gen_cvt_sxtw(void)
+{
+ uint32_t r = intr(gv(RC_INT));
+ o(0x93407c00 | r | r << 5); // sxtw x(r),w(r)
+}
+
+ST_FUNC void gen_cvt_itof(int t)
+{
+ if (t == VT_LDOUBLE) {
+ int f = vtop->type.t;
+ int func = (f & VT_BTYPE) == VT_LLONG ?
+ (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :
+ (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);
+ vpush_global_sym(&func_old_type, func);
+ vrott(2);
+ gfunc_call(1);
+ vpushi(0);
+ vtop->type.t = t;
+ vtop->r = REG_FRET;
+ return;
+ }
+ else {
+ int d, n = intr(gv(RC_INT));
+ int s = !(vtop->type.t & VT_UNSIGNED);
+ uint32_t l = ((vtop->type.t & VT_BTYPE) == VT_LLONG);
+ --vtop;
+ d = get_reg(RC_FLOAT);
+ ++vtop;
+ vtop[0].r = d;
+ o(0x1e220000 | (uint32_t)!s << 16 |
+ (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) |
+ l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n)
+ }
+}
+
+ST_FUNC void gen_cvt_ftoi(int t)
+{
+ if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+ int func = (t & VT_BTYPE) == VT_LLONG ?
+ (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :
+ (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);
+ vpush_global_sym(&func_old_type, func);
+ vrott(2);
+ gfunc_call(1);
+ vpushi(0);
+ vtop->type.t = t;
+ vtop->r = REG_IRET;
+ return;
+ }
+ else {
+ int d, n = fltr(gv(RC_FLOAT));
+ uint32_t l = ((vtop->type.t & VT_BTYPE) != VT_FLOAT);
+ --vtop;
+ d = get_reg(RC_INT);
+ ++vtop;
+ vtop[0].r = d;
+ o(0x1e380000 |
+ (uint32_t)!!(t & VT_UNSIGNED) << 16 |
+ (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(d) |
+ l << 22 | n << 5); // fcvtz[su] [wx](d),[sd](n)
+ }
+}
+
+ST_FUNC void gen_cvt_ftof(int t)
+{
+ int f = vtop[0].type.t;
+ assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE);
+ assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE);
+ if (t == f)
+ return;
+
+ if (t == VT_LDOUBLE || f == VT_LDOUBLE) {
+ int func = (t == VT_LDOUBLE) ?
+ (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) :
+ (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2);
+ vpush_global_sym(&func_old_type, func);
+ vrott(2);
+ gfunc_call(1);
+ vpushi(0);
+ vtop->type.t = t;
+ vtop->r = REG_FRET;
+ }
+ else {
+ int x, a;
+ gv(RC_FLOAT);
+ assert(vtop[0].r < VT_CONST);
+ a = fltr(vtop[0].r);
+ --vtop;
+ x = get_reg(RC_FLOAT);
+ ++vtop;
+ vtop[0].r = x;
+ x = fltr(x);
+
+ if (f == VT_FLOAT)
+ o(0x1e22c000 | x | a << 5); // fcvt d(x),s(a)
+ else
+ o(0x1e624000 | x | a << 5); // fcvt s(x),d(a)
+ }
+}
+
+ST_FUNC void ggoto(void)
+{
+ arm64_gen_bl_or_b(1);
+ --vtop;
+}
+
+ST_FUNC void gen_clear_cache(void)
+{
+ uint32_t beg, end, dsz, isz, p, lab1, b1;
+ gv2(RC_INT, RC_INT);
+ vpushi(0);
+ vtop->r = get_reg(RC_INT);
+ vpushi(0);
+ vtop->r = get_reg(RC_INT);
+ vpushi(0);
+ vtop->r = get_reg(RC_INT);
+ beg = intr(vtop[-4].r); // x0
+ end = intr(vtop[-3].r); // x1
+ dsz = intr(vtop[-2].r); // x2
+ isz = intr(vtop[-1].r); // x3
+ p = intr(vtop[0].r); // x4
+ vtop -= 5;
+
+ o(0xd53b0020 | isz); // mrs x(isz),ctr_el0
+ o(0x52800080 | p); // mov w(p),#4
+ o(0x53104c00 | dsz | isz << 5); // ubfx w(dsz),w(isz),#16,#4
+ o(0x1ac02000 | dsz | p << 5 | dsz << 16); // lsl w(dsz),w(p),w(dsz)
+ o(0x12000c00 | isz | isz << 5); // and w(isz),w(isz),#15
+ o(0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz)
+ o(0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1
+ o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
+ b1 = ind; o(0x14000000); // b
+ lab1 = ind;
+ o(0xd50b7b20 | p); // dc cvau,x(p)
+ o(0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz)
+ write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);
+ o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
+ o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1
+ o(0xd5033b9f); // dsb ish
+ o(0x51000400 | p | isz << 5); // sub w(p),w(isz),#1
+ o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
+ b1 = ind; o(0x14000000); // b
+ lab1 = ind;
+ o(0xd50b7520 | p); // ic ivau,x(p)
+ o(0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz)
+ write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);
+ o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
+ o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1
+ o(0xd5033b9f); // dsb ish
+ o(0xd5033fdf); // isb
+}
+
+ST_FUNC void gen_vla_sp_save(int addr) {
+ uint32_t r = intr(get_reg(RC_INT));
+ o(0x910003e0 | r); // mov x(r),sp
+ arm64_strx(3, r, 29, addr);
+}
+
+ST_FUNC void gen_vla_sp_restore(int addr) {
+ // Use x30 because this function can be called when there
+ // is a live return value in x0 but there is nothing on
+ // the value stack to prevent get_reg from returning x0.
+ uint32_t r = 30;
+ arm64_ldrx(0, 3, r, 29, addr);
+ o(0x9100001f | r << 5); // mov sp,x(r)
+}
+
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+ uint32_t r = intr(gv(RC_INT));
+ o(0x91003c00 | r | r << 5); // add x(r),x(r),#15
+ o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15
+ o(0xcb2063ff | r << 16); // sub sp,sp,x(r)
+ vpop();
+}
+
+/* end of A64 code generator */
+/*************************************************************/
+#endif
+/*************************************************************/
diff --git a/arm64-link.c b/arm64-link.c
new file mode 100644
index 0000000..59322c5
--- /dev/null
+++ b/arm64-link.c
@@ -0,0 +1,256 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_AARCH64
+
+#define R_DATA_32 R_AARCH64_ABS32
+#define R_DATA_PTR R_AARCH64_ABS64
+#define R_JMP_SLOT R_AARCH64_JUMP_SLOT
+#define R_GLOB_DAT R_AARCH64_GLOB_DAT
+#define R_COPY R_AARCH64_COPY
+#define R_RELATIVE R_AARCH64_RELATIVE
+
+#define R_NUM R_AARCH64_NUM
+
+#define ELF_START_ADDR 0x00400000
+#define ELF_PAGE_SIZE 0x1000
+
+#define PCRELATIVE_DLLPLT 1
+#define RELOCATE_DLLPLT 1
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+ relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+ switch (reloc_type) {
+ case R_AARCH64_ABS32:
+ case R_AARCH64_ABS64:
+ case R_AARCH64_PREL32:
+ case R_AARCH64_MOVW_UABS_G0_NC:
+ case R_AARCH64_MOVW_UABS_G1_NC:
+ case R_AARCH64_MOVW_UABS_G2_NC:
+ case R_AARCH64_MOVW_UABS_G3:
+ case R_AARCH64_ADR_PREL_PG_HI21:
+ case R_AARCH64_ADD_ABS_LO12_NC:
+ case R_AARCH64_ADR_GOT_PAGE:
+ case R_AARCH64_LD64_GOT_LO12_NC:
+ case R_AARCH64_GLOB_DAT:
+ case R_AARCH64_COPY:
+ return 0;
+
+ case R_AARCH64_JUMP26:
+ case R_AARCH64_CALL26:
+ case R_AARCH64_JUMP_SLOT:
+ return 1;
+ }
+
+ tcc_error ("Unknown relocation type: %d", reloc_type);
+ return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+ GOT and/or PLT entry to be created. See tcc.h for a description of the
+ different values. */
+int gotplt_entry_type (int reloc_type)
+{
+ switch (reloc_type) {
+ case R_AARCH64_PREL32:
+ case R_AARCH64_MOVW_UABS_G0_NC:
+ case R_AARCH64_MOVW_UABS_G1_NC:
+ case R_AARCH64_MOVW_UABS_G2_NC:
+ case R_AARCH64_MOVW_UABS_G3:
+ case R_AARCH64_ADR_PREL_PG_HI21:
+ case R_AARCH64_ADD_ABS_LO12_NC:
+ case R_AARCH64_GLOB_DAT:
+ case R_AARCH64_JUMP_SLOT:
+ case R_AARCH64_COPY:
+ return NO_GOTPLT_ENTRY;
+
+ case R_AARCH64_ABS32:
+ case R_AARCH64_ABS64:
+ case R_AARCH64_JUMP26:
+ case R_AARCH64_CALL26:
+ return AUTO_GOTPLT_ENTRY;
+
+ case R_AARCH64_ADR_GOT_PAGE:
+ case R_AARCH64_LD64_GOT_LO12_NC:
+ return ALWAYS_GOTPLT_ENTRY;
+ }
+
+ tcc_error ("Unknown relocation type: %d", reloc_type);
+ return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+ Section *plt = s1->plt;
+ uint8_t *p;
+ unsigned plt_offset;
+
+ if (s1->output_type == TCC_OUTPUT_DLL)
+ tcc_error("DLLs unimplemented!");
+
+ if (plt->data_offset == 0) {
+ section_ptr_add(plt, 32);
+ }
+ plt_offset = plt->data_offset;
+
+ p = section_ptr_add(plt, 16);
+ write32le(p, got_offset);
+ write32le(p + 4, (uint64_t) got_offset >> 32);
+ return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+ address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+ uint8_t *p, *p_end;
+
+ if (!s1->plt)
+ return;
+
+ p = s1->plt->data;
+ p_end = p + s1->plt->data_offset;
+
+ if (p < p_end) {
+ uint64_t plt = s1->plt->sh_addr;
+ uint64_t got = s1->got->sh_addr;
+ uint64_t off = (got >> 12) - (plt >> 12);
+ if ((off + ((uint32_t)1 << 20)) >> 21)
+ tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
+ write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
+ write32le(p + 4, (0x90000010 | // adrp x16,...
+ (off & 0x1ffffc) << 3 | (off & 3) << 29));
+ write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
+ (got & 0xff8) << 7));
+ write32le(p + 12, (0x91000210 | // add x16,x16,#...
+ (got & 0xfff) << 10));
+ write32le(p + 16, 0xd61f0220); // br x17
+ write32le(p + 20, 0xd503201f); // nop
+ write32le(p + 24, 0xd503201f); // nop
+ write32le(p + 28, 0xd503201f); // nop
+ p += 32;
+ while (p < p_end) {
+ uint64_t pc = plt + (p - s1->plt->data);
+ uint64_t addr = got + read64le(p);
+ uint64_t off = (addr >> 12) - (pc >> 12);
+ if ((off + ((uint32_t)1 << 20)) >> 21)
+ tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
+ write32le(p, (0x90000010 | // adrp x16,...
+ (off & 0x1ffffc) << 3 | (off & 3) << 29));
+ write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
+ (addr & 0xff8) << 7));
+ write32le(p + 8, (0x91000210 | // add x16,x16,#...
+ (addr & 0xfff) << 10));
+ write32le(p + 12, 0xd61f0220); // br x17
+ p += 16;
+ }
+ }
+}
+
+void relocate_init(Section *sr) {}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+ int sym_index = ELFW(R_SYM)(rel->r_info);
+#ifdef DEBUG_RELOC
+ ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+#endif
+
+ switch(type) {
+ case R_AARCH64_ABS64:
+ write64le(ptr, val);
+ return;
+ case R_AARCH64_ABS32:
+ write32le(ptr, val);
+ return;
+ case R_AARCH64_PREL32:
+ write32le(ptr, val - addr);
+ return;
+ case R_AARCH64_MOVW_UABS_G0_NC:
+ write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+ (val & 0xffff) << 5));
+ return;
+ case R_AARCH64_MOVW_UABS_G1_NC:
+ write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+ (val >> 16 & 0xffff) << 5));
+ return;
+ case R_AARCH64_MOVW_UABS_G2_NC:
+ write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+ (val >> 32 & 0xffff) << 5));
+ return;
+ case R_AARCH64_MOVW_UABS_G3:
+ write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+ (val >> 48 & 0xffff) << 5));
+ return;
+ case R_AARCH64_ADR_PREL_PG_HI21: {
+ uint64_t off = (val >> 12) - (addr >> 12);
+ if ((off + ((uint64_t)1 << 20)) >> 21)
+ tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
+ write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
+ (off & 0x1ffffc) << 3 | (off & 3) << 29));
+ return;
+ }
+ case R_AARCH64_ADD_ABS_LO12_NC:
+ write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
+ (val & 0xfff) << 10));
+ return;
+ case R_AARCH64_JUMP26:
+ case R_AARCH64_CALL26:
+#ifdef DEBUG_RELOC
+ printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
+ (char *) symtab_section->link->data + sym->st_name);
+#endif
+ if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
+ tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed"
+ " (val=%lx, addr=%lx)", val, addr);
+ write32le(ptr, (0x14000000 |
+ (uint32_t)(type == R_AARCH64_CALL26) << 31 |
+ ((val - addr) >> 2 & 0x3ffffff)));
+ return;
+ case R_AARCH64_ADR_GOT_PAGE: {
+ uint64_t off =
+ (((s1->got->sh_addr +
+ s1->sym_attrs[sym_index].got_offset) >> 12) - (addr >> 12));
+ if ((off + ((uint64_t)1 << 20)) >> 21)
+ tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
+ write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
+ (off & 0x1ffffc) << 3 | (off & 3) << 29));
+ return;
+ }
+ case R_AARCH64_LD64_GOT_LO12_NC:
+ write32le(ptr,
+ ((read32le(ptr) & 0xfff803ff) |
+ ((s1->got->sh_addr +
+ s1->sym_attrs[sym_index].got_offset) & 0xff8) << 7));
+ return;
+ case R_AARCH64_COPY:
+ return;
+ case R_AARCH64_GLOB_DAT:
+ case R_AARCH64_JUMP_SLOT:
+ /* They don't need addend */
+#ifdef DEBUG_RELOC
+ printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
+ val - rel->r_addend,
+ (char *) symtab_section->link->data + sym->st_name);
+#endif
+ write64le(ptr, val - rel->r_addend);
+ return;
+ case R_AARCH64_RELATIVE:
+#ifdef TCC_TARGET_PE
+ add32le(ptr, val - s1->pe_imagebase);
+#endif
+ /* do nothing */
+ return;
+ default:
+ fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
+ type, (unsigned)addr, ptr, (unsigned)val);
+ return;
+ }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
diff --git a/c67-gen.c b/c67-gen.c
new file mode 100644
index 0000000..bcb4b0e
--- /dev/null
+++ b/c67-gen.c
@@ -0,0 +1,2540 @@
+/*
+ * TMS320C67xx code generator for TCC
+ *
+ * Copyright (c) 2001, 2002 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+/* #define ASSEMBLY_LISTING_C67 */
+
+/* number of available registers */
+#define NB_REGS 24
+
+/* a register can belong to several classes. The classes must be
+ sorted from more general to more precise (see gv2() code which does
+ assumptions on it). */
+#define RC_INT 0x0001 /* generic integer register */
+#define RC_FLOAT 0x0002 /* generic float register */
+#define RC_EAX 0x0004
+#define RC_ST0 0x0008
+#define RC_ECX 0x0010
+#define RC_EDX 0x0020
+#define RC_INT_BSIDE 0x00000040 /* generic integer register on b side */
+#define RC_C67_A4 0x00000100
+#define RC_C67_A5 0x00000200
+#define RC_C67_B4 0x00000400
+#define RC_C67_B5 0x00000800
+#define RC_C67_A6 0x00001000
+#define RC_C67_A7 0x00002000
+#define RC_C67_B6 0x00004000
+#define RC_C67_B7 0x00008000
+#define RC_C67_A8 0x00010000
+#define RC_C67_A9 0x00020000
+#define RC_C67_B8 0x00040000
+#define RC_C67_B9 0x00080000
+#define RC_C67_A10 0x00100000
+#define RC_C67_A11 0x00200000
+#define RC_C67_B10 0x00400000
+#define RC_C67_B11 0x00800000
+#define RC_C67_A12 0x01000000
+#define RC_C67_A13 0x02000000
+#define RC_C67_B12 0x04000000
+#define RC_C67_B13 0x08000000
+#define RC_IRET RC_C67_A4 /* function return: integer register */
+#define RC_LRET RC_C67_A5 /* function return: second integer register */
+#define RC_FRET RC_C67_A4 /* function return: float register */
+
+/* pretty names for the registers */
+enum {
+ TREG_EAX = 0, // really A2
+ TREG_ECX, // really A3
+ TREG_EDX, // really B0
+ TREG_ST0, // really B1
+ TREG_C67_A4,
+ TREG_C67_A5,
+ TREG_C67_B4,
+ TREG_C67_B5,
+ TREG_C67_A6,
+ TREG_C67_A7,
+ TREG_C67_B6,
+ TREG_C67_B7,
+ TREG_C67_A8,
+ TREG_C67_A9,
+ TREG_C67_B8,
+ TREG_C67_B9,
+ TREG_C67_A10,
+ TREG_C67_A11,
+ TREG_C67_B10,
+ TREG_C67_B11,
+ TREG_C67_A12,
+ TREG_C67_A13,
+ TREG_C67_B12,
+ TREG_C67_B13,
+};
+
+/* return registers for function */
+#define REG_IRET TREG_C67_A4 /* single word int return register */
+#define REG_LRET TREG_C67_A5 /* second word return register (for long long) */
+#define REG_FRET TREG_C67_A4 /* float return register */
+
+/* defined if function parameters must be evaluated in reverse order */
+/* #define INVERT_FUNC_PARAMS */
+
+/* defined if structures are passed as pointers. Otherwise structures
+ are directly pushed on stack. */
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE 12
+#define LDOUBLE_ALIGN 4
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN 8
+
+/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+
+ST_DATA const int reg_classes[NB_REGS] = {
+ /* eax */ RC_INT | RC_FLOAT | RC_EAX,
+ // only allow even regs for floats (allow for doubles)
+ /* ecx */ RC_INT | RC_ECX,
+ /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
+ // only allow even regs for floats (allow for doubles)
+ /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0,
+ /* A4 */ RC_C67_A4,
+ /* A5 */ RC_C67_A5,
+ /* B4 */ RC_C67_B4,
+ /* B5 */ RC_C67_B5,
+ /* A6 */ RC_C67_A6,
+ /* A7 */ RC_C67_A7,
+ /* B6 */ RC_C67_B6,
+ /* B7 */ RC_C67_B7,
+ /* A8 */ RC_C67_A8,
+ /* A9 */ RC_C67_A9,
+ /* B8 */ RC_C67_B8,
+ /* B9 */ RC_C67_B9,
+ /* A10 */ RC_C67_A10,
+ /* A11 */ RC_C67_A11,
+ /* B10 */ RC_C67_B10,
+ /* B11 */ RC_C67_B11,
+ /* A12 */ RC_C67_A10,
+ /* A13 */ RC_C67_A11,
+ /* B12 */ RC_C67_B10,
+ /* B13 */ RC_C67_B11
+};
+
+// although tcc thinks it is passing parameters on the stack,
+// the C67 really passes up to the first 10 params in special
+// regs or regs pairs (for 64 bit params). So keep track of
+// the stack offsets so we can translate to the appropriate
+// reg (pair)
+
+#define NoCallArgsPassedOnStack 10
+int NoOfCurFuncArgs;
+int TranslateStackToReg[NoCallArgsPassedOnStack];
+int ParamLocOnStack[NoCallArgsPassedOnStack];
+int TotalBytesPushedOnStack;
+
+#ifndef FALSE
+# define FALSE 0
+# define TRUE 1
+#endif
+
+#undef BOOL
+#define BOOL int
+
+#define ALWAYS_ASSERT(x) \
+do {\
+ if (!(x))\
+ tcc_error("internal compiler error file at %s:%d", __FILE__, __LINE__);\
+} while (0)
+
+/******************************************************/
+static unsigned long func_sub_sp_offset;
+static int func_ret_sub;
+
+static BOOL C67_invert_test;
+static int C67_compare_reg;
+
+#ifdef ASSEMBLY_LISTING_C67
+FILE *f = NULL;
+#endif
+
+void C67_g(int c)
+{
+ int ind1;
+ if (nocode_wanted)
+ return;
+#ifdef ASSEMBLY_LISTING_C67
+ fprintf(f, " %08X", c);
+#endif
+ ind1 = ind + 4;
+ if (ind1 > (int) cur_text_section->data_allocated)
+ section_realloc(cur_text_section, ind1);
+ cur_text_section->data[ind] = c & 0xff;
+ cur_text_section->data[ind + 1] = (c >> 8) & 0xff;
+ cur_text_section->data[ind + 2] = (c >> 16) & 0xff;
+ cur_text_section->data[ind + 3] = (c >> 24) & 0xff;
+ ind = ind1;
+}
+
+
+/* output a symbol and patch all calls to it */
+void gsym_addr(int t, int a)
+{
+ int n, *ptr;
+ while (t) {
+ ptr = (int *) (cur_text_section->data + t);
+ {
+ Sym *sym;
+
+ // extract 32 bit address from MVKH/MVKL
+ n = ((*ptr >> 7) & 0xffff);
+ n |= ((*(ptr + 1) >> 7) & 0xffff) << 16;
+
+ // define a label that will be relocated
+
+ sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
+ greloc(cur_text_section, sym, t, R_C60LO16);
+ greloc(cur_text_section, sym, t + 4, R_C60HI16);
+
+ // clear out where the pointer was
+
+ *ptr &= ~(0xffff << 7);
+ *(ptr + 1) &= ~(0xffff << 7);
+ }
+ t = n;
+ }
+}
+
+void gsym(int t)
+{
+ gsym_addr(t, ind);
+}
+
+// these are regs that tcc doesn't really know about,
+// but assign them unique values so the mapping routines
+// can distinguish them
+
+#define C67_A0 105
+#define C67_SP 106
+#define C67_B3 107
+#define C67_FP 108
+#define C67_B2 109
+#define C67_CREG_ZERO -1 /* Special code for no condition reg test */
+
+
+int ConvertRegToRegClass(int r)
+{
+ // only works for A4-B13
+
+ return RC_C67_A4 << (r - TREG_C67_A4);
+}
+
+
+// map TCC reg to C67 reg number
+
+int C67_map_regn(int r)
+{
+ if (r == 0) // normal tcc regs
+ return 0x2; // A2
+ else if (r == 1) // normal tcc regs
+ return 3; // A3
+ else if (r == 2) // normal tcc regs
+ return 0; // B0
+ else if (r == 3) // normal tcc regs
+ return 1; // B1
+ else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs
+ return (((r & 0xfffffffc) >> 1) | (r & 1)) + 2;
+ else if (r == C67_A0)
+ return 0; // set to A0 (offset reg)
+ else if (r == C67_B2)
+ return 2; // set to B2 (offset reg)
+ else if (r == C67_B3)
+ return 3; // set to B3 (return address reg)
+ else if (r == C67_SP)
+ return 15; // set to SP (B15) (offset reg)
+ else if (r == C67_FP)
+ return 15; // set to FP (A15) (offset reg)
+ else if (r == C67_CREG_ZERO)
+ return 0; // Special code for no condition reg test
+ else
+ ALWAYS_ASSERT(FALSE);
+
+ return 0;
+}
+
+// mapping from tcc reg number to
+// C67 register to condition code field
+//
+// valid condition code regs are:
+//
+// tcc reg 2 ->B0 -> 1
+// tcc reg 3 ->B1 -> 2
+// tcc reg 0 -> A2 -> 5
+// tcc reg 1 -> A3 -> X
+// tcc reg B2 -> 3
+
+int C67_map_regc(int r)
+{
+ if (r == 0) // normal tcc regs
+ return 0x5;
+ else if (r == 2) // normal tcc regs
+ return 0x1;
+ else if (r == 3) // normal tcc regs
+ return 0x2;
+ else if (r == C67_B2) // normal tcc regs
+ return 0x3;
+ else if (r == C67_CREG_ZERO)
+ return 0; // Special code for no condition reg test
+ else
+ ALWAYS_ASSERT(FALSE);
+
+ return 0;
+}
+
+
+// map TCC reg to C67 reg side A or B
+
+int C67_map_regs(int r)
+{
+ if (r == 0) // normal tcc regs
+ return 0x0;
+ else if (r == 1) // normal tcc regs
+ return 0x0;
+ else if (r == 2) // normal tcc regs
+ return 0x1;
+ else if (r == 3) // normal tcc regs
+ return 0x1;
+ else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs
+ return (r & 2) >> 1;
+ else if (r == C67_A0)
+ return 0; // set to A side
+ else if (r == C67_B2)
+ return 1; // set to B side
+ else if (r == C67_B3)
+ return 1; // set to B side
+ else if (r == C67_SP)
+ return 0x1; // set to SP (B15) B side
+ else if (r == C67_FP)
+ return 0x0; // set to FP (A15) A side
+ else
+ ALWAYS_ASSERT(FALSE);
+
+ return 0;
+}
+
+int C67_map_S12(char *s)
+{
+ if (strstr(s, ".S1") != NULL)
+ return 0;
+ else if (strcmp(s, ".S2"))
+ return 1;
+ else
+ ALWAYS_ASSERT(FALSE);
+
+ return 0;
+}
+
+int C67_map_D12(char *s)
+{
+ if (strstr(s, ".D1") != NULL)
+ return 0;
+ else if (strcmp(s, ".D2"))
+ return 1;
+ else
+ ALWAYS_ASSERT(FALSE);
+
+ return 0;
+}
+
+
+
+void C67_asm(char *s, int a, int b, int c)
+{
+ BOOL xpath;
+
+#ifdef ASSEMBLY_LISTING_C67
+ if (!f) {
+ f = fopen("TCC67_out.txt", "wt");
+ }
+ fprintf(f, "%04X ", ind);
+#endif
+
+ if (strstr(s, "MVKL") == s) {
+ C67_g((C67_map_regn(b) << 23) |
+ ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(b) << 1));
+ } else if (strstr(s, "MVKH") == s) {
+ C67_g((C67_map_regn(b) << 23) |
+ (((a >> 16) & 0xffff) << 7) |
+ (0x1a << 2) | (C67_map_regs(b) << 1));
+ } else if (strstr(s, "STW.D SP POST DEC") == s) {
+ C67_g((C67_map_regn(a) << 23) | //src
+ (15 << 18) | //SP B15
+ (2 << 13) | //ucst5 (must keep 8 byte boundary !!)
+ (0xa << 9) | //mode a = post dec ucst
+ (0 << 8) | //r (LDDW bit 0)
+ (1 << 7) | //y D1/D2 use B side
+ (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of src
+ (0 << 0)); //parallel
+ } else if (strstr(s, "STB.D *+SP[A0]") == s) {
+ C67_g((C67_map_regn(a) << 23) | //src
+ (15 << 18) | //base reg A15
+ (0 << 13) | //offset reg A0
+ (5 << 9) | //mode 5 = pos offset, base reg + off reg
+ (0 << 8) | //r (LDDW bit 0)
+ (0 << 7) | //y D1/D2 A side
+ (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of src
+ (0 << 0)); //parallel
+ } else if (strstr(s, "STH.D *+SP[A0]") == s) {
+ C67_g((C67_map_regn(a) << 23) | //src
+ (15 << 18) | //base reg A15
+ (0 << 13) | //offset reg A0
+ (5 << 9) | //mode 5 = pos offset, base reg + off reg
+ (0 << 8) | //r (LDDW bit 0)
+ (0 << 7) | //y D1/D2 A side
+ (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of src
+ (0 << 0)); //parallel
+ } else if (strstr(s, "STB.D *+SP[A0]") == s) {
+ C67_g((C67_map_regn(a) << 23) | //src
+ (15 << 18) | //base reg A15
+ (0 << 13) | //offset reg A0
+ (5 << 9) | //mode 5 = pos offset, base reg + off reg
+ (0 << 8) | //r (LDDW bit 0)
+ (0 << 7) | //y D1/D2 A side
+ (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of src
+ (0 << 0)); //parallel
+ } else if (strstr(s, "STH.D *+SP[A0]") == s) {
+ C67_g((C67_map_regn(a) << 23) | //src
+ (15 << 18) | //base reg A15
+ (0 << 13) | //offset reg A0
+ (5 << 9) | //mode 5 = pos offset, base reg + off reg
+ (0 << 8) | //r (LDDW bit 0)
+ (0 << 7) | //y D1/D2 A side
+ (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of src
+ (0 << 0)); //parallel
+ } else if (strstr(s, "STW.D *+SP[A0]") == s) {
+ C67_g((C67_map_regn(a) << 23) | //src
+ (15 << 18) | //base reg A15
+ (0 << 13) | //offset reg A0
+ (5 << 9) | //mode 5 = pos offset, base reg + off reg
+ (0 << 8) | //r (LDDW bit 0)
+ (0 << 7) | //y D1/D2 A side
+ (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of src
+ (0 << 0)); //parallel
+ } else if (strstr(s, "STW.D *") == s) {
+ C67_g((C67_map_regn(a) << 23) | //src
+ (C67_map_regn(b) << 18) | //base reg A0
+ (0 << 13) | //cst5
+ (1 << 9) | //mode 1 = pos cst offset
+ (0 << 8) | //r (LDDW bit 0)
+ (C67_map_regs(b) << 7) | //y D1/D2 base reg side
+ (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of src
+ (0 << 0)); //parallel
+ } else if (strstr(s, "STH.D *") == s) {
+ C67_g((C67_map_regn(a) << 23) | //src
+ (C67_map_regn(b) << 18) | //base reg A0
+ (0 << 13) | //cst5
+ (1 << 9) | //mode 1 = pos cst offset
+ (0 << 8) | //r (LDDW bit 0)
+ (C67_map_regs(b) << 7) | //y D1/D2 base reg side
+ (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of src
+ (0 << 0)); //parallel
+ } else if (strstr(s, "STB.D *") == s) {
+ C67_g((C67_map_regn(a) << 23) | //src
+ (C67_map_regn(b) << 18) | //base reg A0
+ (0 << 13) | //cst5
+ (1 << 9) | //mode 1 = pos cst offset
+ (0 << 8) | //r (LDDW bit 0)
+ (C67_map_regs(b) << 7) | //y D1/D2 base reg side
+ (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of src
+ (0 << 0)); //parallel
+ } else if (strstr(s, "STW.D +*") == s) {
+ ALWAYS_ASSERT(c < 32);
+ C67_g((C67_map_regn(a) << 23) | //src
+ (C67_map_regn(b) << 18) | //base reg A0
+ (c << 13) | //cst5
+ (1 << 9) | //mode 1 = pos cst offset
+ (0 << 8) | //r (LDDW bit 0)
+ (C67_map_regs(b) << 7) | //y D1/D2 base reg side
+ (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of src
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDW.D SP PRE INC") == s) {
+ C67_g((C67_map_regn(a) << 23) | //dst
+ (15 << 18) | //base reg B15
+ (2 << 13) | //ucst5 (must keep 8 byte boundary)
+ (9 << 9) | //mode 9 = pre inc ucst5
+ (0 << 8) | //r (LDDW bit 0)
+ (1 << 7) | //y D1/D2 B side
+ (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDDW.D SP PRE INC") == s) {
+ C67_g((C67_map_regn(a) << 23) | //dst
+ (15 << 18) | //base reg B15
+ (1 << 13) | //ucst5 (must keep 8 byte boundary)
+ (9 << 9) | //mode 9 = pre inc ucst5
+ (1 << 8) | //r (LDDW bit 1)
+ (1 << 7) | //y D1/D2 B side
+ (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDW.D *+SP[A0]") == s) {
+ C67_g((C67_map_regn(a) << 23) | //dst
+ (15 << 18) | //base reg A15
+ (0 << 13) | //offset reg A0
+ (5 << 9) | //mode 5 = pos offset, base reg + off reg
+ (0 << 8) | //r (LDDW bit 0)
+ (0 << 7) | //y D1/D2 A side
+ (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDDW.D *+SP[A0]") == s) {
+ C67_g((C67_map_regn(a) << 23) | //dst
+ (15 << 18) | //base reg A15
+ (0 << 13) | //offset reg A0
+ (5 << 9) | //mode 5 = pos offset, base reg + off reg
+ (1 << 8) | //r (LDDW bit 1)
+ (0 << 7) | //y D1/D2 A side
+ (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDH.D *+SP[A0]") == s) {
+ C67_g((C67_map_regn(a) << 23) | //dst
+ (15 << 18) | //base reg A15
+ (0 << 13) | //offset reg A0
+ (5 << 9) | //mode 5 = pos offset, base reg + off reg
+ (0 << 8) | //r (LDDW bit 0)
+ (0 << 7) | //y D1/D2 A side
+ (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDB.D *+SP[A0]") == s) {
+ C67_g((C67_map_regn(a) << 23) | //dst
+ (15 << 18) | //base reg A15
+ (0 << 13) | //offset reg A0
+ (5 << 9) | //mode 5 = pos offset, base reg + off reg
+ (0 << 8) | //r (LDDW bit 0)
+ (0 << 7) | //y D1/D2 A side
+ (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDHU.D *+SP[A0]") == s) {
+ C67_g((C67_map_regn(a) << 23) | //dst
+ (15 << 18) | //base reg A15
+ (0 << 13) | //offset reg A0
+ (5 << 9) | //mode 5 = pos offset, base reg + off reg
+ (0 << 8) | //r (LDDW bit 0)
+ (0 << 7) | //y D1/D2 A side
+ (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDBU.D *+SP[A0]") == s) {
+ C67_g((C67_map_regn(a) << 23) | //dst
+ (15 << 18) | //base reg A15
+ (0 << 13) | //offset reg A0
+ (5 << 9) | //mode 5 = pos offset, base reg + off reg
+ (0 << 8) | //r (LDDW bit 0)
+ (0 << 7) | //y D1/D2 A side
+ (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(a) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDW.D *") == s) {
+ C67_g((C67_map_regn(b) << 23) | //dst
+ (C67_map_regn(a) << 18) | //base reg A15
+ (0 << 13) | //cst5
+ (1 << 9) | //mode 1 = pos cst offset
+ (0 << 8) | //r (LDDW bit 0)
+ (C67_map_regs(a) << 7) | //y D1/D2 src side
+ (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(b) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDDW.D *") == s) {
+ C67_g((C67_map_regn(b) << 23) | //dst
+ (C67_map_regn(a) << 18) | //base reg A15
+ (0 << 13) | //cst5
+ (1 << 9) | //mode 1 = pos cst offset
+ (1 << 8) | //r (LDDW bit 1)
+ (C67_map_regs(a) << 7) | //y D1/D2 src side
+ (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(b) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDH.D *") == s) {
+ C67_g((C67_map_regn(b) << 23) | //dst
+ (C67_map_regn(a) << 18) | //base reg A15
+ (0 << 13) | //cst5
+ (1 << 9) | //mode 1 = pos cst offset
+ (0 << 8) | //r (LDDW bit 0)
+ (C67_map_regs(a) << 7) | //y D1/D2 src side
+ (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(b) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDB.D *") == s) {
+ C67_g((C67_map_regn(b) << 23) | //dst
+ (C67_map_regn(a) << 18) | //base reg A15
+ (0 << 13) | //cst5
+ (1 << 9) | //mode 1 = pos cst offset
+ (0 << 8) | //r (LDDW bit 0)
+ (C67_map_regs(a) << 7) | //y D1/D2 src side
+ (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(b) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDHU.D *") == s) {
+ C67_g((C67_map_regn(b) << 23) | //dst
+ (C67_map_regn(a) << 18) | //base reg A15
+ (0 << 13) | //cst5
+ (1 << 9) | //mode 1 = pos cst offset
+ (0 << 8) | //r (LDDW bit 0)
+ (C67_map_regs(a) << 7) | //y D1/D2 src side
+ (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(b) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDBU.D *") == s) {
+ C67_g((C67_map_regn(b) << 23) | //dst
+ (C67_map_regn(a) << 18) | //base reg A15
+ (0 << 13) | //cst5
+ (1 << 9) | //mode 1 = pos cst offset
+ (0 << 8) | //r (LDDW bit 0)
+ (C67_map_regs(a) << 7) | //y D1/D2 src side
+ (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(b) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "LDW.D +*") == s) {
+ C67_g((C67_map_regn(b) << 23) | //dst
+ (C67_map_regn(a) << 18) | //base reg A15
+ (1 << 13) | //cst5
+ (1 << 9) | //mode 1 = pos cst offset
+ (0 << 8) | //r (LDDW bit 0)
+ (C67_map_regs(a) << 7) | //y D1/D2 src side
+ (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+ (1 << 2) | //opcode
+ (C67_map_regs(b) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "CMPLTSP") == s) {
+ xpath = C67_map_regs(a) ^ C67_map_regs(b);
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x use cross path for src2
+ (0x3a << 6) | //opcode
+ (0x8 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side for reg c
+ (0 << 0)); //parallel
+ } else if (strstr(s, "CMPGTSP") == s) {
+ xpath = C67_map_regs(a) ^ C67_map_regs(b);
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x use cross path for src2
+ (0x39 << 6) | //opcode
+ (0x8 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side for reg c
+ (0 << 0)); //parallel
+ } else if (strstr(s, "CMPEQSP") == s) {
+ xpath = C67_map_regs(a) ^ C67_map_regs(b);
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x use cross path for src2
+ (0x38 << 6) | //opcode
+ (0x8 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side for reg c
+ (0 << 0)); //parallel
+ }
+
+ else if (strstr(s, "CMPLTDP") == s) {
+ xpath = C67_map_regs(a) ^ C67_map_regs(b);
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x use cross path for src2
+ (0x2a << 6) | //opcode
+ (0x8 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side for reg c
+ (0 << 0)); //parallel
+ } else if (strstr(s, "CMPGTDP") == s) {
+ xpath = C67_map_regs(a) ^ C67_map_regs(b);
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x use cross path for src2
+ (0x29 << 6) | //opcode
+ (0x8 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side for reg c
+ (0 << 0)); //parallel
+ } else if (strstr(s, "CMPEQDP") == s) {
+ xpath = C67_map_regs(a) ^ C67_map_regs(b);
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x use cross path for src2
+ (0x28 << 6) | //opcode
+ (0x8 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side for reg c
+ (0 << 0)); //parallel
+ } else if (strstr(s, "CMPLT") == s) {
+ xpath = C67_map_regs(a) ^ C67_map_regs(b);
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x use cross path for src2
+ (0x57 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side for reg c
+ (0 << 0)); //parallel
+ } else if (strstr(s, "CMPGT") == s) {
+ xpath = C67_map_regs(a) ^ C67_map_regs(b);
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x use cross path for src2
+ (0x47 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side for reg c
+ (0 << 0)); //parallel
+ } else if (strstr(s, "CMPEQ") == s) {
+ xpath = C67_map_regs(a) ^ C67_map_regs(b);
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x use cross path for src2
+ (0x53 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side for reg c
+ (0 << 0)); //parallel
+ } else if (strstr(s, "CMPLTU") == s) {
+ xpath = C67_map_regs(a) ^ C67_map_regs(b);
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x use cross path for src2
+ (0x5f << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side for reg c
+ (0 << 0)); //parallel
+ } else if (strstr(s, "CMPGTU") == s) {
+ xpath = C67_map_regs(a) ^ C67_map_regs(b);
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x use cross path for src2
+ (0x4f << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side for reg c
+ (0 << 0)); //parallel
+ } else if (strstr(s, "B DISP") == s) {
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //z
+ (a << 7) | //cnst
+ (0x4 << 2) | //opcode fixed
+ (0 << 1) | //S0/S1
+ (0 << 0)); //parallel
+ } else if (strstr(s, "B.") == s) {
+ xpath = C67_map_regs(c) ^ 1;
+
+ C67_g((C67_map_regc(b) << 29) | //creg
+ (a << 28) | //inv
+ (0 << 23) | //dst
+ (C67_map_regn(c) << 18) | //src2
+ (0 << 13) | //
+ (xpath << 12) | //x cross path if !B side
+ (0xd << 6) | //opcode
+ (0x8 << 2) | //opcode fixed
+ (1 << 1) | //must be S2
+ (0 << 0)); //parallel
+ } else if (strstr(s, "MV.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (0 << 13) | //src1 (cst5)
+ (xpath << 12) | //x cross path if opposite sides
+ (0x2 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "SPTRUNC.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (0 << 13) | //src1 NA
+ (xpath << 12) | //x cross path if opposite sides
+ (0xb << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "DPTRUNC.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason
+ (0 << 13) | //src1 NA
+ (xpath << 12) | //x cross path if opposite sides
+ (0x1 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "INTSP.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (0 << 13) | //src1 NA
+ (xpath << 12) | //x cross path if opposite sides
+ (0x4a << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "INTSPU.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (0 << 13) | //src1 NA
+ (xpath << 12) | //x cross path if opposite sides
+ (0x49 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "INTDP.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (0 << 13) | //src1 NA
+ (xpath << 12) | //x cross path if opposite sides
+ (0x39 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "INTDPU.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason
+ (0 << 13) | //src1 NA
+ (xpath << 12) | //x cross path if opposite sides
+ (0x3b << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "SPDP.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (0 << 13) | //src1 NA
+ (xpath << 12) | //x cross path if opposite sides
+ (0x2 << 6) | //opcode
+ (0x8 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "DPSP.L") == s) {
+ ALWAYS_ASSERT(C67_map_regs(b) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason
+ (0 << 13) | //src1 NA
+ (0 << 12) | //x cross path if opposite sides
+ (0x9 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "ADD.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2 (possible x path)
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x3 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "SUB.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2 (possible x path)
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x7 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "OR.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2 (possible x path)
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x7f << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "AND.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2 (possible x path)
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x7b << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "XOR.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2 (possible x path)
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x6f << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "ADDSP.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2 (possible x path)
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x10 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "ADDDP.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2 (possible x path)
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x18 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "SUBSP.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2 (possible x path)
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x11 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "SUBDP.L") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2 (possible x path)
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x19 << 5) | //opcode
+ (0x6 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "MPYSP.M") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2 (possible x path)
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x1c << 7) | //opcode
+ (0x0 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "MPYDP.M") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2 (possible x path)
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x0e << 7) | //opcode
+ (0x0 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "MPYI.M") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1 (cst5)
+ (xpath << 12) | //x cross path if opposite sides
+ (0x4 << 7) | //opcode
+ (0x0 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "SHR.S") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x37 << 6) | //opcode
+ (0x8 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "SHRU.S") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x27 << 6) | //opcode
+ (0x8 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "SHL.S") == s) {
+ xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+ ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(c) << 23) | //dst
+ (C67_map_regn(b) << 18) | //src2
+ (C67_map_regn(a) << 13) | //src1
+ (xpath << 12) | //x cross path if opposite sides
+ (0x33 << 6) | //opcode
+ (0x8 << 2) | //opcode fixed
+ (C67_map_regs(c) << 1) | //side of dest
+ (0 << 0)); //parallel
+ } else if (strstr(s, "||ADDK") == s) {
+ xpath = 0; // no xpath required just use the side of the src/dst
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(b) << 23) | //dst
+ (a << 07) | //scst16
+ (0x14 << 2) | //opcode fixed
+ (C67_map_regs(b) << 1) | //side of dst
+ (1 << 0)); //parallel
+ } else if (strstr(s, "ADDK") == s) {
+ xpath = 0; // no xpath required just use the side of the src/dst
+
+ C67_g((0 << 29) | //creg
+ (0 << 28) | //inv
+ (C67_map_regn(b) << 23) | //dst
+ (a << 07) | //scst16
+ (0x14 << 2) | //opcode fixed
+ (C67_map_regs(b) << 1) | //side of dst
+ (0 << 0)); //parallel
+ } else if (strstr(s, "NOP") == s) {
+ C67_g(((a - 1) << 13) | //no of cycles
+ (0 << 0)); //parallel
+ } else
+ ALWAYS_ASSERT(FALSE);
+
+#ifdef ASSEMBLY_LISTING_C67
+ fprintf(f, " %s %d %d %d\n", s, a, b, c);
+#endif
+
+}
+
+//r=reg to load, fr=from reg, symbol for relocation, constant
+
+void C67_MVKL(int r, int fc)
+{
+ C67_asm("MVKL.", fc, r, 0);
+}
+
+void C67_MVKH(int r, int fc)
+{
+ C67_asm("MVKH.", fc, r, 0);
+}
+
+void C67_STB_SP_A0(int r)
+{
+ C67_asm("STB.D *+SP[A0]", r, 0, 0); // STB r,*+SP[A0]
+}
+
+void C67_STH_SP_A0(int r)
+{
+ C67_asm("STH.D *+SP[A0]", r, 0, 0); // STH r,*+SP[A0]
+}
+
+void C67_STW_SP_A0(int r)
+{
+ C67_asm("STW.D *+SP[A0]", r, 0, 0); // STW r,*+SP[A0]
+}
+
+void C67_STB_PTR(int r, int r2)
+{
+ C67_asm("STB.D *", r, r2, 0); // STB r, *r2
+}
+
+void C67_STH_PTR(int r, int r2)
+{
+ C67_asm("STH.D *", r, r2, 0); // STH r, *r2
+}
+
+void C67_STW_PTR(int r, int r2)
+{
+ C67_asm("STW.D *", r, r2, 0); // STW r, *r2
+}
+
+void C67_STW_PTR_PRE_INC(int r, int r2, int n)
+{
+ C67_asm("STW.D +*", r, r2, n); // STW r, *+r2
+}
+
+void C67_PUSH(int r)
+{
+ C67_asm("STW.D SP POST DEC", r, 0, 0); // STW r,*SP--
+}
+
+void C67_LDW_SP_A0(int r)
+{
+ C67_asm("LDW.D *+SP[A0]", r, 0, 0); // LDW *+SP[A0],r
+}
+
+void C67_LDDW_SP_A0(int r)
+{
+ C67_asm("LDDW.D *+SP[A0]", r, 0, 0); // LDDW *+SP[A0],r
+}
+
+void C67_LDH_SP_A0(int r)
+{
+ C67_asm("LDH.D *+SP[A0]", r, 0, 0); // LDH *+SP[A0],r
+}
+
+void C67_LDB_SP_A0(int r)
+{
+ C67_asm("LDB.D *+SP[A0]", r, 0, 0); // LDB *+SP[A0],r
+}
+
+void C67_LDHU_SP_A0(int r)
+{
+ C67_asm("LDHU.D *+SP[A0]", r, 0, 0); // LDHU *+SP[A0],r
+}
+
+void C67_LDBU_SP_A0(int r)
+{
+ C67_asm("LDBU.D *+SP[A0]", r, 0, 0); // LDBU *+SP[A0],r
+}
+
+void C67_LDW_PTR(int r, int r2)
+{
+ C67_asm("LDW.D *", r, r2, 0); // LDW *r,r2
+}
+
+void C67_LDDW_PTR(int r, int r2)
+{
+ C67_asm("LDDW.D *", r, r2, 0); // LDDW *r,r2
+}
+
+void C67_LDH_PTR(int r, int r2)
+{
+ C67_asm("LDH.D *", r, r2, 0); // LDH *r,r2
+}
+
+void C67_LDB_PTR(int r, int r2)
+{
+ C67_asm("LDB.D *", r, r2, 0); // LDB *r,r2
+}
+
+void C67_LDHU_PTR(int r, int r2)
+{
+ C67_asm("LDHU.D *", r, r2, 0); // LDHU *r,r2
+}
+
+void C67_LDBU_PTR(int r, int r2)
+{
+ C67_asm("LDBU.D *", r, r2, 0); // LDBU *r,r2
+}
+
+void C67_LDW_PTR_PRE_INC(int r, int r2)
+{
+ C67_asm("LDW.D +*", r, r2, 0); // LDW *+r,r2
+}
+
+void C67_POP(int r)
+{
+ C67_asm("LDW.D SP PRE INC", r, 0, 0); // LDW *++SP,r
+}
+
+void C67_POP_DW(int r)
+{
+ C67_asm("LDDW.D SP PRE INC", r, 0, 0); // LDDW *++SP,r
+}
+
+void C67_CMPLT(int s1, int s2, int dst)
+{
+ C67_asm("CMPLT.L1", s1, s2, dst);
+}
+
+void C67_CMPGT(int s1, int s2, int dst)
+{
+ C67_asm("CMPGT.L1", s1, s2, dst);
+}
+
+void C67_CMPEQ(int s1, int s2, int dst)
+{
+ C67_asm("CMPEQ.L1", s1, s2, dst);
+}
+
+void C67_CMPLTU(int s1, int s2, int dst)
+{
+ C67_asm("CMPLTU.L1", s1, s2, dst);
+}
+
+void C67_CMPGTU(int s1, int s2, int dst)
+{
+ C67_asm("CMPGTU.L1", s1, s2, dst);
+}
+
+
+void C67_CMPLTSP(int s1, int s2, int dst)
+{
+ C67_asm("CMPLTSP.S1", s1, s2, dst);
+}
+
+void C67_CMPGTSP(int s1, int s2, int dst)
+{
+ C67_asm("CMPGTSP.S1", s1, s2, dst);
+}
+
+void C67_CMPEQSP(int s1, int s2, int dst)
+{
+ C67_asm("CMPEQSP.S1", s1, s2, dst);
+}
+
+void C67_CMPLTDP(int s1, int s2, int dst)
+{
+ C67_asm("CMPLTDP.S1", s1, s2, dst);
+}
+
+void C67_CMPGTDP(int s1, int s2, int dst)
+{
+ C67_asm("CMPGTDP.S1", s1, s2, dst);
+}
+
+void C67_CMPEQDP(int s1, int s2, int dst)
+{
+ C67_asm("CMPEQDP.S1", s1, s2, dst);
+}
+
+
+void C67_IREG_B_REG(int inv, int r1, int r2) // [!R] B r2
+{
+ C67_asm("B.S2", inv, r1, r2);
+}
+
+
+// call with how many 32 bit words to skip
+// (0 would branch to the branch instruction)
+
+void C67_B_DISP(int disp) // B +2 Branch with constant displacement
+{
+ // Branch point is relative to the 8 word fetch packet
+ //
+ // we will assume the text section always starts on an 8 word (32 byte boundary)
+ //
+ // so add in how many words into the fetch packet the branch is
+
+
+ C67_asm("B DISP", disp + ((ind & 31) >> 2), 0, 0);
+}
+
+void C67_NOP(int n)
+{
+ C67_asm("NOP", n, 0, 0);
+}
+
+void C67_ADDK(int n, int r)
+{
+ ALWAYS_ASSERT(abs(n) < 32767);
+
+ C67_asm("ADDK", n, r, 0);
+}
+
+void C67_ADDK_PARALLEL(int n, int r)
+{
+ ALWAYS_ASSERT(abs(n) < 32767);
+
+ C67_asm("||ADDK", n, r, 0);
+}
+
+void C67_Adjust_ADDK(int *inst, int n)
+{
+ ALWAYS_ASSERT(abs(n) < 32767);
+
+ *inst = (*inst & (~(0xffff << 7))) | ((n & 0xffff) << 7);
+}
+
+void C67_MV(int r, int v)
+{
+ C67_asm("MV.L", 0, r, v);
+}
+
+
+void C67_DPTRUNC(int r, int v)
+{
+ C67_asm("DPTRUNC.L", 0, r, v);
+}
+
+void C67_SPTRUNC(int r, int v)
+{
+ C67_asm("SPTRUNC.L", 0, r, v);
+}
+
+void C67_INTSP(int r, int v)
+{
+ C67_asm("INTSP.L", 0, r, v);
+}
+
+void C67_INTDP(int r, int v)
+{
+ C67_asm("INTDP.L", 0, r, v);
+}
+
+void C67_INTSPU(int r, int v)
+{
+ C67_asm("INTSPU.L", 0, r, v);
+}
+
+void C67_INTDPU(int r, int v)
+{
+ C67_asm("INTDPU.L", 0, r, v);
+}
+
+void C67_SPDP(int r, int v)
+{
+ C67_asm("SPDP.L", 0, r, v);
+}
+
+void C67_DPSP(int r, int v) // note regs must be on the same side
+{
+ C67_asm("DPSP.L", 0, r, v);
+}
+
+void C67_ADD(int r, int v)
+{
+ C67_asm("ADD.L", v, r, v);
+}
+
+void C67_SUB(int r, int v)
+{
+ C67_asm("SUB.L", v, r, v);
+}
+
+void C67_AND(int r, int v)
+{
+ C67_asm("AND.L", v, r, v);
+}
+
+void C67_OR(int r, int v)
+{
+ C67_asm("OR.L", v, r, v);
+}
+
+void C67_XOR(int r, int v)
+{
+ C67_asm("XOR.L", v, r, v);
+}
+
+void C67_ADDSP(int r, int v)
+{
+ C67_asm("ADDSP.L", v, r, v);
+}
+
+void C67_SUBSP(int r, int v)
+{
+ C67_asm("SUBSP.L", v, r, v);
+}
+
+void C67_MPYSP(int r, int v)
+{
+ C67_asm("MPYSP.M", v, r, v);
+}
+
+void C67_ADDDP(int r, int v)
+{
+ C67_asm("ADDDP.L", v, r, v);
+}
+
+void C67_SUBDP(int r, int v)
+{
+ C67_asm("SUBDP.L", v, r, v);
+}
+
+void C67_MPYDP(int r, int v)
+{
+ C67_asm("MPYDP.M", v, r, v);
+}
+
+void C67_MPYI(int r, int v)
+{
+ C67_asm("MPYI.M", v, r, v);
+}
+
+void C67_SHL(int r, int v)
+{
+ C67_asm("SHL.S", r, v, v);
+}
+
+void C67_SHRU(int r, int v)
+{
+ C67_asm("SHRU.S", r, v, v);
+}
+
+void C67_SHR(int r, int v)
+{
+ C67_asm("SHR.S", r, v, v);
+}
+
+
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue * sv)
+{
+ int v, t, ft, fc, fr, size = 0, element;
+ BOOL Unsigned = FALSE;
+ SValue v1;
+
+ fr = sv->r;
+ ft = sv->type.t;
+ fc = sv->c.i;
+
+ v = fr & VT_VALMASK;
+ if (fr & VT_LVAL) {
+ if (v == VT_LLOCAL) {
+ v1.type.t = VT_INT;
+ v1.r = VT_LOCAL | VT_LVAL;
+ v1.c.i = fc;
+ load(r, &v1);
+ fr = r;
+ } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+ tcc_error("long double not supported");
+ } else if ((ft & VT_TYPE) == VT_BYTE) {
+ size = 1;
+ } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
+ size = 1;
+ Unsigned = TRUE;
+ } else if ((ft & VT_TYPE) == VT_SHORT) {
+ size = 2;
+ } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
+ size = 2;
+ Unsigned = TRUE;
+ } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+ size = 8;
+ } else {
+ size = 4;
+ }
+
+ // check if fc is a positive reference on the stack,
+ // if it is tcc is referencing what it thinks is a parameter
+ // on the stack, so check if it is really in a register.
+
+
+ if (v == VT_LOCAL && fc > 0) {
+ int stack_pos = 8;
+
+ for (t = 0; t < NoCallArgsPassedOnStack; t++) {
+ if (fc == stack_pos)
+ break;
+
+ stack_pos += TranslateStackToReg[t];
+ }
+
+ // param has been pushed on stack, get it like a local var
+
+ fc = ParamLocOnStack[t] - 8;
+ }
+
+ if ((fr & VT_VALMASK) < VT_CONST) // check for pure indirect
+ {
+ if (size == 1) {
+ if (Unsigned)
+ C67_LDBU_PTR(v, r); // LDBU *v,r
+ else
+ C67_LDB_PTR(v, r); // LDB *v,r
+ } else if (size == 2) {
+ if (Unsigned)
+ C67_LDHU_PTR(v, r); // LDHU *v,r
+ else
+ C67_LDH_PTR(v, r); // LDH *v,r
+ } else if (size == 4) {
+ C67_LDW_PTR(v, r); // LDW *v,r
+ } else if (size == 8) {
+ C67_LDDW_PTR(v, r); // LDDW *v,r
+ }
+
+ C67_NOP(4); // NOP 4
+ return;
+ } else if (fr & VT_SYM) {
+ greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched
+ greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);
+
+
+ C67_MVKL(C67_A0, fc); //r=reg to load, constant
+ C67_MVKH(C67_A0, fc); //r=reg to load, constant
+
+
+ if (size == 1) {
+ if (Unsigned)
+ C67_LDBU_PTR(C67_A0, r); // LDBU *A0,r
+ else
+ C67_LDB_PTR(C67_A0, r); // LDB *A0,r
+ } else if (size == 2) {
+ if (Unsigned)
+ C67_LDHU_PTR(C67_A0, r); // LDHU *A0,r
+ else
+ C67_LDH_PTR(C67_A0, r); // LDH *A0,r
+ } else if (size == 4) {
+ C67_LDW_PTR(C67_A0, r); // LDW *A0,r
+ } else if (size == 8) {
+ C67_LDDW_PTR(C67_A0, r); // LDDW *A0,r
+ }
+
+ C67_NOP(4); // NOP 4
+ return;
+ } else {
+ element = size;
+
+ // divide offset in bytes to create element index
+ C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
+ C67_MVKH(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
+
+ if (size == 1) {
+ if (Unsigned)
+ C67_LDBU_SP_A0(r); // LDBU r, SP[A0]
+ else
+ C67_LDB_SP_A0(r); // LDB r, SP[A0]
+ } else if (size == 2) {
+ if (Unsigned)
+ C67_LDHU_SP_A0(r); // LDHU r, SP[A0]
+ else
+ C67_LDH_SP_A0(r); // LDH r, SP[A0]
+ } else if (size == 4) {
+ C67_LDW_SP_A0(r); // LDW r, SP[A0]
+ } else if (size == 8) {
+ C67_LDDW_SP_A0(r); // LDDW r, SP[A0]
+ }
+
+
+ C67_NOP(4); // NOP 4
+ return;
+ }
+ } else {
+ if (v == VT_CONST) {
+ if (fr & VT_SYM) {
+ greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched
+ greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);
+ }
+ C67_MVKL(r, fc); //r=reg to load, constant
+ C67_MVKH(r, fc); //r=reg to load, constant
+ } else if (v == VT_LOCAL) {
+ C67_MVKL(r, fc + 8); //r=reg to load, constant C67 stack points to next free
+ C67_MVKH(r, fc + 8); //r=reg to load, constant
+ C67_ADD(C67_FP, r); // MV v,r v -> r
+ } else if (v == VT_CMP) {
+ C67_MV(C67_compare_reg, r); // MV v,r v -> r
+ } else if (v == VT_JMP || v == VT_JMPI) {
+ t = v & 1;
+ C67_B_DISP(4); // Branch with constant displacement, skip over this branch, load, nop, load
+ C67_MVKL(r, t); // r=reg to load, 0 or 1 (do this while branching)
+ C67_NOP(4); // NOP 4
+ gsym(fc); // modifies other branches to branch here
+ C67_MVKL(r, t ^ 1); // r=reg to load, 0 or 1
+ } else if (v != r) {
+ C67_MV(v, r); // MV v,r v -> r
+
+ if ((ft & VT_BTYPE) == VT_DOUBLE)
+ C67_MV(v + 1, r + 1); // MV v,r v -> r
+ }
+ }
+}
+
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue * v)
+{
+ int fr, bt, ft, fc, size, t, element;
+
+ ft = v->type.t;
+ fc = v->c.i;
+ fr = v->r & VT_VALMASK;
+ bt = ft & VT_BTYPE;
+ /* XXX: incorrect if float reg to reg */
+
+ if (bt == VT_LDOUBLE) {
+ tcc_error("long double not supported");
+ } else {
+ if (bt == VT_SHORT)
+ size = 2;
+ else if (bt == VT_BYTE)
+ size = 1;
+ else if (bt == VT_DOUBLE)
+ size = 8;
+ else
+ size = 4;
+
+ if ((v->r & VT_VALMASK) == VT_CONST) {
+ /* constant memory reference */
+
+ if (v->r & VT_SYM) {
+ greloc(cur_text_section, v->sym, ind, R_C60LO16); // rem the inst need to be patched
+ greloc(cur_text_section, v->sym, ind + 4, R_C60HI16);
+ }
+ C67_MVKL(C67_A0, fc); //r=reg to load, constant
+ C67_MVKH(C67_A0, fc); //r=reg to load, constant
+
+ if (size == 1)
+ C67_STB_PTR(r, C67_A0); // STB r, *A0
+ else if (size == 2)
+ C67_STH_PTR(r, C67_A0); // STH r, *A0
+ else if (size == 4 || size == 8)
+ C67_STW_PTR(r, C67_A0); // STW r, *A0
+
+ if (size == 8)
+ C67_STW_PTR_PRE_INC(r + 1, C67_A0, 1); // STW r, *+A0[1]
+ } else if ((v->r & VT_VALMASK) == VT_LOCAL) {
+ // check case of storing to passed argument that
+ // tcc thinks is on the stack but for C67 is
+ // passed as a reg. However it may have been
+ // saved to the stack, if that reg was required
+ // for a call to a child function
+
+ if (fc > 0) // argument ??
+ {
+ // walk through sizes and figure which param
+
+ int stack_pos = 8;
+
+ for (t = 0; t < NoCallArgsPassedOnStack; t++) {
+ if (fc == stack_pos)
+ break;
+
+ stack_pos += TranslateStackToReg[t];
+ }
+
+ // param has been pushed on stack, get it like a local var
+ fc = ParamLocOnStack[t] - 8;
+ }
+
+ if (size == 8)
+ element = 4;
+ else
+ element = size;
+
+ // divide offset in bytes to create word index
+ C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
+ C67_MVKH(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
+
+
+
+ if (size == 1)
+ C67_STB_SP_A0(r); // STB r, SP[A0]
+ else if (size == 2)
+ C67_STH_SP_A0(r); // STH r, SP[A0]
+ else if (size == 4 || size == 8)
+ C67_STW_SP_A0(r); // STW r, SP[A0]
+
+ if (size == 8) {
+ C67_ADDK(1, C67_A0); // ADDK 1,A0
+ C67_STW_SP_A0(r + 1); // STW r, SP[A0]
+ }
+ } else {
+ if (size == 1)
+ C67_STB_PTR(r, fr); // STB r, *fr
+ else if (size == 2)
+ C67_STH_PTR(r, fr); // STH r, *fr
+ else if (size == 4 || size == 8)
+ C67_STW_PTR(r, fr); // STW r, *fr
+
+ if (size == 8) {
+ C67_STW_PTR_PRE_INC(r + 1, fr, 1); // STW r, *+fr[1]
+ }
+ }
+ }
+}
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+ int r;
+ Sym *sym;
+
+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+ /* constant case */
+ if (vtop->r & VT_SYM) {
+ /* relocation case */
+
+ // get add into A0, then start the jump B3
+
+ greloc(cur_text_section, vtop->sym, ind, R_C60LO16); // rem the inst need to be patched
+ greloc(cur_text_section, vtop->sym, ind + 4, R_C60HI16);
+
+ C67_MVKL(C67_A0, 0); //r=reg to load, constant
+ C67_MVKH(C67_A0, 0); //r=reg to load, constant
+ C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // B.S2x A0
+
+ if (is_jmp) {
+ C67_NOP(5); // simple jump, just put NOP
+ } else {
+ // Call, must load return address into B3 during delay slots
+
+ sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address
+ greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched
+ greloc(cur_text_section, sym, ind + 4, R_C60HI16);
+ C67_MVKL(C67_B3, 0); //r=reg to load, constant
+ C67_MVKH(C67_B3, 0); //r=reg to load, constant
+ C67_NOP(3); // put remaining NOPs
+ }
+ } else {
+ /* put an empty PC32 relocation */
+ ALWAYS_ASSERT(FALSE);
+ }
+ } else {
+ /* otherwise, indirect call */
+ r = gv(RC_INT);
+ C67_IREG_B_REG(0, C67_CREG_ZERO, r); // B.S2x r
+
+ if (is_jmp) {
+ C67_NOP(5); // simple jump, just put NOP
+ } else {
+ // Call, must load return address into B3 during delay slots
+
+ sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address
+ greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched
+ greloc(cur_text_section, sym, ind + 4, R_C60HI16);
+ C67_MVKL(C67_B3, 0); //r=reg to load, constant
+ C67_MVKH(C67_B3, 0); //r=reg to load, constant
+ C67_NOP(3); // put remaining NOPs
+ }
+ }
+}
+
+/* Return the number of registers needed to return the struct, or 0 if
+ returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) {
+ *ret_align = 1; // Never have to re-align return values for x86-64
+ return 0;
+}
+
+/* generate function call with address in (vtop->t, vtop->c) and free function
+ context. Stack entry is popped */
+void gfunc_call(int nb_args)
+{
+ int i, r, size = 0;
+ int args_sizes[NoCallArgsPassedOnStack];
+
+ if (nb_args > NoCallArgsPassedOnStack) {
+ tcc_error("more than 10 function params not currently supported");
+ // handle more than 10, put some on the stack
+ }
+
+ for (i = 0; i < nb_args; i++) {
+ if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+ ALWAYS_ASSERT(FALSE);
+ } else {
+ /* simple type (currently always same size) */
+ /* XXX: implicit cast ? */
+
+
+ if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+ tcc_error("long long not supported");
+ } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+ tcc_error("long double not supported");
+ } else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
+ size = 8;
+ } else {
+ size = 4;
+ }
+
+ // put the parameter into the corresponding reg (pair)
+
+ r = gv(RC_C67_A4 << (2 * i));
+
+ // must put on stack because with 1 pass compiler , no way to tell
+ // if an up coming nested call might overwrite these regs
+
+ C67_PUSH(r);
+
+ if (size == 8) {
+ C67_STW_PTR_PRE_INC(r + 1, C67_SP, 3); // STW r, *+SP[3] (go back and put the other)
+ }
+ args_sizes[i] = size;
+ }
+ vtop--;
+ }
+ // POP all the params on the stack into registers for the
+ // immediate call (in reverse order)
+
+ for (i = nb_args - 1; i >= 0; i--) {
+
+ if (args_sizes[i] == 8)
+ C67_POP_DW(TREG_C67_A4 + i * 2);
+ else
+ C67_POP(TREG_C67_A4 + i * 2);
+ }
+ gcall_or_jmp(0);
+ vtop--;
+}
+
+
+// to be compatible with Code Composer for the C67
+// the first 10 parameters must be passed in registers
+// (pairs for 64 bits) starting wit; A4:A5, then B4:B5 and
+// ending with B12:B13.
+//
+// When a call is made, if the caller has its parameters
+// in regs A4-B13 these must be saved before/as the call
+// parameters are loaded and restored upon return (or if/when needed).
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType * func_type)
+{
+ int addr, align, size, func_call, i;
+ Sym *sym;
+ CType *type;
+
+ sym = func_type->ref;
+ func_call = sym->f.func_call;
+ addr = 8;
+ /* if the function returns a structure, then add an
+ implicit pointer parameter */
+ func_vt = sym->type;
+ func_var = (sym->f.func_type == FUNC_ELLIPSIS);
+ if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+ func_vc = addr;
+ addr += 4;
+ }
+
+ NoOfCurFuncArgs = 0;
+
+ /* define parameters */
+ while ((sym = sym->next) != NULL) {
+ type = &sym->type;
+ sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr);
+ size = type_size(type, &align);
+ size = (size + 3) & ~3;
+
+ // keep track of size of arguments so
+ // we can translate where tcc thinks they
+ // are on the stack into the appropriate reg
+
+ TranslateStackToReg[NoOfCurFuncArgs] = size;
+ NoOfCurFuncArgs++;
+
+#ifdef FUNC_STRUCT_PARAM_AS_PTR
+ /* structs are passed as pointer */
+ if ((type->t & VT_BTYPE) == VT_STRUCT) {
+ size = 4;
+ }
+#endif
+ addr += size;
+ }
+ func_ret_sub = 0;
+ /* pascal type call ? */
+ if (func_call == FUNC_STDCALL)
+ func_ret_sub = addr - 8;
+
+ C67_MV(C67_FP, C67_A0); // move FP -> A0
+ C67_MV(C67_SP, C67_FP); // move SP -> FP
+
+ // place all the args passed in regs onto the stack
+
+ loc = 0;
+ for (i = 0; i < NoOfCurFuncArgs; i++) {
+
+ ParamLocOnStack[i] = loc; // remember where the param is
+ loc += -8;
+
+ C67_PUSH(TREG_C67_A4 + i * 2);
+
+ if (TranslateStackToReg[i] == 8) {
+ C67_STW_PTR_PRE_INC(TREG_C67_A4 + i * 2 + 1, C67_SP, 3); // STW r, *+SP[1] (go back and put the other)
+ }
+ }
+
+ TotalBytesPushedOnStack = -loc;
+
+ func_sub_sp_offset = ind; // remember where we put the stack instruction
+ C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
+
+ C67_PUSH(C67_A0);
+ C67_PUSH(C67_B3);
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+ {
+ int local = (-loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr
+ C67_POP(C67_B3);
+ C67_NOP(4); // NOP wait for load
+ C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3
+ C67_POP(C67_FP);
+ C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP
+ C67_Adjust_ADDK((int *) (cur_text_section->data +
+ func_sub_sp_offset),
+ -local + TotalBytesPushedOnStack);
+ C67_NOP(3); // NOP
+ }
+}
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+ int ind1 = ind;
+ if (nocode_wanted)
+ return t;
+
+ C67_MVKL(C67_A0, t); //r=reg to load, constant
+ C67_MVKH(C67_A0, t); //r=reg to load, constant
+ C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // [!R] B.S2x A0
+ C67_NOP(5);
+ return ind1;
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+ Sym *sym;
+ // I guess this routine is used for relative short
+ // local jumps, for now just handle it as the general
+ // case
+
+ // define a label that will be relocated
+
+ sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
+ greloc(cur_text_section, sym, ind, R_C60LO16);
+ greloc(cur_text_section, sym, ind + 4, R_C60HI16);
+
+ gjmp(0); // place a zero there later the symbol will be added to it
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+int gtst(int inv, int t)
+{
+ int ind1, n;
+ int v, *p;
+
+ v = vtop->r & VT_VALMASK;
+ if (nocode_wanted) {
+ ;
+ } else if (v == VT_CMP) {
+ /* fast case : can jump directly since flags are set */
+ // C67 uses B2 sort of as flags register
+ ind1 = ind;
+ C67_MVKL(C67_A0, t); //r=reg to load, constant
+ C67_MVKH(C67_A0, t); //r=reg to load, constant
+
+ if (C67_compare_reg != TREG_EAX && // check if not already in a conditional test reg
+ C67_compare_reg != TREG_EDX &&
+ C67_compare_reg != TREG_ST0 && C67_compare_reg != C67_B2) {
+ C67_MV(C67_compare_reg, C67_B2);
+ C67_compare_reg = C67_B2;
+ }
+
+ C67_IREG_B_REG(C67_invert_test ^ inv, C67_compare_reg, C67_A0); // [!R] B.S2x A0
+ C67_NOP(5);
+ t = ind1; //return where we need to patch
+
+ } else if (v == VT_JMP || v == VT_JMPI) {
+ /* && or || optimization */
+ if ((v & 1) == inv) {
+ /* insert vtop->c jump list in t */
+
+ // I guess the idea is to traverse to the
+ // null at the end of the list and store t
+ // there
+
+ n = vtop->c.i;
+ while (n != 0) {
+ p = (int *) (cur_text_section->data + n);
+
+ // extract 32 bit address from MVKH/MVKL
+ n = ((*p >> 7) & 0xffff);
+ n |= ((*(p + 1) >> 7) & 0xffff) << 16;
+ }
+ *p |= (t & 0xffff) << 7;
+ *(p + 1) |= ((t >> 16) & 0xffff) << 7;
+ t = vtop->c.i;
+
+ } else {
+ t = gjmp(t);
+ gsym(vtop->c.i);
+ }
+ }
+ vtop--;
+ return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+ int r, fr, opc, t;
+
+ switch (op) {
+ case '+':
+ case TOK_ADDC1: /* add with carry generation */
+ opc = 0;
+ gen_op8:
+
+
+// C67 can't do const compares, must load into a reg
+// so just go to gv2 directly - tktk
+
+
+
+ if (op >= TOK_ULT && op <= TOK_GT)
+ gv2(RC_INT_BSIDE, RC_INT); // make sure r (src1) is on the B Side of CPU
+ else
+ gv2(RC_INT, RC_INT);
+
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+
+ C67_compare_reg = C67_B2;
+
+
+ if (op == TOK_LT) {
+ C67_CMPLT(r, fr, C67_B2);
+ C67_invert_test = FALSE;
+ } else if (op == TOK_GE) {
+ C67_CMPLT(r, fr, C67_B2);
+ C67_invert_test = TRUE;
+ } else if (op == TOK_GT) {
+ C67_CMPGT(r, fr, C67_B2);
+ C67_invert_test = FALSE;
+ } else if (op == TOK_LE) {
+ C67_CMPGT(r, fr, C67_B2);
+ C67_invert_test = TRUE;
+ } else if (op == TOK_EQ) {
+ C67_CMPEQ(r, fr, C67_B2);
+ C67_invert_test = FALSE;
+ } else if (op == TOK_NE) {
+ C67_CMPEQ(r, fr, C67_B2);
+ C67_invert_test = TRUE;
+ } else if (op == TOK_ULT) {
+ C67_CMPLTU(r, fr, C67_B2);
+ C67_invert_test = FALSE;
+ } else if (op == TOK_UGE) {
+ C67_CMPLTU(r, fr, C67_B2);
+ C67_invert_test = TRUE;
+ } else if (op == TOK_UGT) {
+ C67_CMPGTU(r, fr, C67_B2);
+ C67_invert_test = FALSE;
+ } else if (op == TOK_ULE) {
+ C67_CMPGTU(r, fr, C67_B2);
+ C67_invert_test = TRUE;
+ } else if (op == '+')
+ C67_ADD(fr, r); // ADD r,fr,r
+ else if (op == '-')
+ C67_SUB(fr, r); // SUB r,fr,r
+ else if (op == '&')
+ C67_AND(fr, r); // AND r,fr,r
+ else if (op == '|')
+ C67_OR(fr, r); // OR r,fr,r
+ else if (op == '^')
+ C67_XOR(fr, r); // XOR r,fr,r
+ else
+ ALWAYS_ASSERT(FALSE);
+
+ vtop--;
+ if (op >= TOK_ULT && op <= TOK_GT) {
+ vtop->r = VT_CMP;
+ vtop->c.i = op;
+ }
+ break;
+ case '-':
+ case TOK_SUBC1: /* sub with carry generation */
+ opc = 5;
+ goto gen_op8;
+ case TOK_ADDC2: /* add with carry use */
+ opc = 2;
+ goto gen_op8;
+ case TOK_SUBC2: /* sub with carry use */
+ opc = 3;
+ goto gen_op8;
+ case '&':
+ opc = 4;
+ goto gen_op8;
+ case '^':
+ opc = 6;
+ goto gen_op8;
+ case '|':
+ opc = 1;
+ goto gen_op8;
+ case '*':
+ case TOK_UMULL:
+ gv2(RC_INT, RC_INT);
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ vtop--;
+ C67_MPYI(fr, r); // 32 bit multiply fr,r,fr
+ C67_NOP(8); // NOP 8 for worst case
+ break;
+ case TOK_SHL:
+ gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ vtop--;
+ C67_SHL(fr, r); // arithmetic/logical shift
+ break;
+
+ case TOK_SHR:
+ gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ vtop--;
+ C67_SHRU(fr, r); // logical shift
+ break;
+
+ case TOK_SAR:
+ gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ vtop--;
+ C67_SHR(fr, r); // arithmetic shift
+ break;
+
+ case '/':
+ t = TOK__divi;
+ call_func:
+ vswap();
+ /* call generic idiv function */
+ vpush_global_sym(&func_old_type, t);
+ vrott(3);
+ gfunc_call(2);
+ vpushi(0);
+ vtop->r = REG_IRET;
+ vtop->r2 = VT_CONST;
+ break;
+ case TOK_UDIV:
+ case TOK_PDIV:
+ t = TOK__divu;
+ goto call_func;
+ case '%':
+ t = TOK__remi;
+ goto call_func;
+ case TOK_UMOD:
+ t = TOK__remu;
+ goto call_func;
+
+ default:
+ opc = 7;
+ goto gen_op8;
+ }
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+ two operands are guaranteed to have the same floating point type */
+/* XXX: need to use ST1 too */
+void gen_opf(int op)
+{
+ int ft, fc, fr, r;
+
+ if (op >= TOK_ULT && op <= TOK_GT)
+ gv2(RC_EDX, RC_EAX); // make sure src2 is on b side
+ else
+ gv2(RC_FLOAT, RC_FLOAT); // make sure src2 is on b side
+
+ ft = vtop->type.t;
+ fc = vtop->c.i;
+ r = vtop->r;
+ fr = vtop[-1].r;
+
+
+ if ((ft & VT_BTYPE) == VT_LDOUBLE)
+ tcc_error("long doubles not supported");
+
+ if (op >= TOK_ULT && op <= TOK_GT) {
+
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+
+ C67_compare_reg = C67_B2;
+
+ if (op == TOK_LT) {
+ if ((ft & VT_BTYPE) == VT_DOUBLE)
+ C67_CMPLTDP(r, fr, C67_B2);
+ else
+ C67_CMPLTSP(r, fr, C67_B2);
+
+ C67_invert_test = FALSE;
+ } else if (op == TOK_GE) {
+ if ((ft & VT_BTYPE) == VT_DOUBLE)
+ C67_CMPLTDP(r, fr, C67_B2);
+ else
+ C67_CMPLTSP(r, fr, C67_B2);
+
+ C67_invert_test = TRUE;
+ } else if (op == TOK_GT) {
+ if ((ft & VT_BTYPE) == VT_DOUBLE)
+ C67_CMPGTDP(r, fr, C67_B2);
+ else
+ C67_CMPGTSP(r, fr, C67_B2);
+
+ C67_invert_test = FALSE;
+ } else if (op == TOK_LE) {
+ if ((ft & VT_BTYPE) == VT_DOUBLE)
+ C67_CMPGTDP(r, fr, C67_B2);
+ else
+ C67_CMPGTSP(r, fr, C67_B2);
+
+ C67_invert_test = TRUE;
+ } else if (op == TOK_EQ) {
+ if ((ft & VT_BTYPE) == VT_DOUBLE)
+ C67_CMPEQDP(r, fr, C67_B2);
+ else
+ C67_CMPEQSP(r, fr, C67_B2);
+
+ C67_invert_test = FALSE;
+ } else if (op == TOK_NE) {
+ if ((ft & VT_BTYPE) == VT_DOUBLE)
+ C67_CMPEQDP(r, fr, C67_B2);
+ else
+ C67_CMPEQSP(r, fr, C67_B2);
+
+ C67_invert_test = TRUE;
+ } else {
+ ALWAYS_ASSERT(FALSE);
+ }
+ vtop->r = VT_CMP; // tell TCC that result is in "flags" actually B2
+ } else {
+ if (op == '+') {
+ if ((ft & VT_BTYPE) == VT_DOUBLE) {
+ C67_ADDDP(r, fr); // ADD fr,r,fr
+ C67_NOP(6);
+ } else {
+ C67_ADDSP(r, fr); // ADD fr,r,fr
+ C67_NOP(3);
+ }
+ vtop--;
+ } else if (op == '-') {
+ if ((ft & VT_BTYPE) == VT_DOUBLE) {
+ C67_SUBDP(r, fr); // SUB fr,r,fr
+ C67_NOP(6);
+ } else {
+ C67_SUBSP(r, fr); // SUB fr,r,fr
+ C67_NOP(3);
+ }
+ vtop--;
+ } else if (op == '*') {
+ if ((ft & VT_BTYPE) == VT_DOUBLE) {
+ C67_MPYDP(r, fr); // MPY fr,r,fr
+ C67_NOP(9);
+ } else {
+ C67_MPYSP(r, fr); // MPY fr,r,fr
+ C67_NOP(3);
+ }
+ vtop--;
+ } else if (op == '/') {
+ if ((ft & VT_BTYPE) == VT_DOUBLE) {
+ // must call intrinsic DP floating point divide
+ vswap();
+ /* call generic idiv function */
+ vpush_global_sym(&func_old_type, TOK__divd);
+ vrott(3);
+ gfunc_call(2);
+ vpushi(0);
+ vtop->r = REG_FRET;
+ vtop->r2 = REG_LRET;
+
+ } else {
+ // must call intrinsic SP floating point divide
+ vswap();
+ /* call generic idiv function */
+ vpush_global_sym(&func_old_type, TOK__divf);
+ vrott(3);
+ gfunc_call(2);
+ vpushi(0);
+ vtop->r = REG_FRET;
+ vtop->r2 = VT_CONST;
+ }
+ } else
+ ALWAYS_ASSERT(FALSE);
+
+
+ }
+}
+
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+ and 'long long' cases. */
+void gen_cvt_itof(int t)
+{
+ int r;
+
+ gv(RC_INT);
+ r = vtop->r;
+
+ if ((t & VT_BTYPE) == VT_DOUBLE) {
+ if (t & VT_UNSIGNED)
+ C67_INTDPU(r, r);
+ else
+ C67_INTDP(r, r);
+
+ C67_NOP(4);
+ vtop->type.t = VT_DOUBLE;
+ } else {
+ if (t & VT_UNSIGNED)
+ C67_INTSPU(r, r);
+ else
+ C67_INTSP(r, r);
+ C67_NOP(3);
+ vtop->type.t = VT_FLOAT;
+ }
+
+}
+
+/* convert fp to int 't' type */
+/* XXX: handle long long case */
+void gen_cvt_ftoi(int t)
+{
+ int r;
+
+ gv(RC_FLOAT);
+ r = vtop->r;
+
+ if (t != VT_INT)
+ tcc_error("long long not supported");
+ else {
+ if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
+ C67_DPTRUNC(r, r);
+ C67_NOP(3);
+ } else {
+ C67_SPTRUNC(r, r);
+ C67_NOP(3);
+ }
+
+ vtop->type.t = VT_INT;
+
+ }
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+ int r, r2;
+
+ if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE &&
+ (t & VT_BTYPE) == VT_FLOAT) {
+ // convert double to float
+
+ gv(RC_FLOAT); // get it in a register pair
+
+ r = vtop->r;
+
+ C67_DPSP(r, r); // convert it to SP same register
+ C67_NOP(3);
+
+ vtop->type.t = VT_FLOAT;
+ vtop->r2 = VT_CONST; // set this as unused
+ } else if ((vtop->type.t & VT_BTYPE) == VT_FLOAT &&
+ (t & VT_BTYPE) == VT_DOUBLE) {
+ // convert float to double
+
+ gv(RC_FLOAT); // get it in a register
+
+ r = vtop->r;
+
+ if (r == TREG_EAX) { // make sure the paired reg is avail
+ r2 = get_reg(RC_ECX);
+ } else if (r == TREG_EDX) {
+ r2 = get_reg(RC_ST0);
+ } else {
+ ALWAYS_ASSERT(FALSE);
+ r2 = 0; /* avoid warning */
+ }
+
+ C67_SPDP(r, r); // convert it to DP same register
+ C67_NOP(1);
+
+ vtop->type.t = VT_DOUBLE;
+ vtop->r2 = r2; // set this as unused
+ } else {
+ ALWAYS_ASSERT(FALSE);
+ }
+}
+
+/* computed goto support */
+void ggoto(void)
+{
+ gcall_or_jmp(1);
+ vtop--;
+}
+
+/* Save the stack pointer onto the stack and return the location of its address */
+ST_FUNC void gen_vla_sp_save(int addr) {
+ tcc_error("variable length arrays unsupported for this target");
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+ tcc_error("variable length arrays unsupported for this target");
+}
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+ tcc_error("variable length arrays unsupported for this target");
+}
+
+/* end of C67 code generator */
+/*************************************************************/
+#endif
+/*************************************************************/
diff --git a/c67-link.c b/c67-link.c
new file mode 100644
index 0000000..de72e44
--- /dev/null
+++ b/c67-link.c
@@ -0,0 +1,131 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_C60
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32 R_C60_32
+#define R_DATA_PTR R_C60_32
+#define R_JMP_SLOT R_C60_JMP_SLOT
+#define R_GLOB_DAT R_C60_GLOB_DAT
+#define R_COPY R_C60_COPY
+#define R_RELATIVE R_C60_RELATIVE
+
+#define R_NUM R_C60_NUM
+
+#define ELF_START_ADDR 0x00000400
+#define ELF_PAGE_SIZE 0x1000
+
+#define PCRELATIVE_DLLPLT 0
+#define RELOCATE_DLLPLT 0
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+ relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+ switch (reloc_type) {
+ case R_C60_32:
+ case R_C60LO16:
+ case R_C60HI16:
+ case R_C60_GOT32:
+ case R_C60_GOTOFF:
+ case R_C60_GOTPC:
+ case R_C60_COPY:
+ return 0;
+
+ case R_C60_PLT32:
+ return 1;
+ }
+
+ tcc_error ("Unknown relocation type: %d", reloc_type);
+ return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+ GOT and/or PLT entry to be created. See tcc.h for a description of the
+ different values. */
+int gotplt_entry_type (int reloc_type)
+{
+ switch (reloc_type) {
+ case R_C60_32:
+ case R_C60LO16:
+ case R_C60HI16:
+ case R_C60_COPY:
+ return NO_GOTPLT_ENTRY;
+
+ case R_C60_GOTOFF:
+ case R_C60_GOTPC:
+ return BUILD_GOT_ONLY;
+
+ case R_C60_PLT32:
+ case R_C60_GOT32:
+ return ALWAYS_GOTPLT_ENTRY;
+ }
+
+ tcc_error ("Unknown relocation type: %d", reloc_type);
+ return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+ tcc_error("C67 got not implemented");
+ return 0;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+ address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+ uint8_t *p, *p_end;
+
+ if (!s1->plt)
+ return;
+
+ p = s1->plt->data;
+ p_end = p + s1->plt->data_offset;
+
+ if (p < p_end) {
+ /* XXX: TODO */
+ while (p < p_end) {
+ /* XXX: TODO */
+ }
+ }
+}
+
+void relocate_init(Section *sr) {}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+ switch(type) {
+ case R_C60_32:
+ *(int *)ptr += val;
+ break;
+ case R_C60LO16:
+ {
+ uint32_t orig;
+
+ /* put the low 16 bits of the absolute address add to what is
+ already there */
+ orig = ((*(int *)(ptr )) >> 7) & 0xffff;
+ orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
+
+ /* patch both at once - assumes always in pairs Low - High */
+ *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) |
+ (((val+orig) & 0xffff) << 7);
+ *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) |
+ ((((val+orig)>>16) & 0xffff) << 7);
+ }
+ break;
+ case R_C60HI16:
+ break;
+ default:
+ fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
+ type, (unsigned) addr, ptr, (unsigned) val);
+ break;
+ }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
diff --git a/coff.h b/coff.h
new file mode 100644
index 0000000..e8e6185
--- /dev/null
+++ b/coff.h
@@ -0,0 +1,446 @@
+/**************************************************************************/
+/* COFF.H */
+/* COFF data structures and related definitions used by the linker */
+/**************************************************************************/
+
+/*------------------------------------------------------------------------*/
+/* COFF FILE HEADER */
+/*------------------------------------------------------------------------*/
+struct filehdr {
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* number of sections */
+ long f_timdat; /* time & date stamp */
+ long f_symptr; /* file pointer to symtab */
+ long f_nsyms; /* number of symtab entries */
+ unsigned short f_opthdr; /* sizeof(optional hdr) */
+ unsigned short f_flags; /* flags */
+ unsigned short f_TargetID; /* for C6x = 0x0099 */
+ };
+
+/*------------------------------------------------------------------------*/
+/* File header flags */
+/*------------------------------------------------------------------------*/
+#define F_RELFLG 0x01 /* relocation info stripped from file */
+#define F_EXEC 0x02 /* file is executable (no unresolved refs) */
+#define F_LNNO 0x04 /* line numbers stripped from file */
+#define F_LSYMS 0x08 /* local symbols stripped from file */
+#define F_GSP10 0x10 /* 34010 version */
+#define F_GSP20 0x20 /* 34020 version */
+#define F_SWABD 0x40 /* bytes swabbed (in names) */
+#define F_AR16WR 0x80 /* byte ordering of an AR16WR (PDP-11) */
+#define F_LITTLE 0x100 /* byte ordering of an AR32WR (vax) */
+#define F_BIG 0x200 /* byte ordering of an AR32W (3B, maxi) */
+#define F_PATCH 0x400 /* contains "patch" list in optional header */
+#define F_NODF 0x400
+
+#define F_VERSION (F_GSP10 | F_GSP20)
+#define F_BYTE_ORDER (F_LITTLE | F_BIG)
+#define FILHDR struct filehdr
+
+/* #define FILHSZ sizeof(FILHDR) */
+#define FILHSZ 22 /* above rounds to align on 4 bytes which causes problems */
+
+#define COFF_C67_MAGIC 0x00c2
+
+/*------------------------------------------------------------------------*/
+/* Macros to recognize magic numbers */
+/*------------------------------------------------------------------------*/
+#define ISMAGIC(x) (((unsigned short)(x))==(unsigned short)magic)
+#define ISARCHIVE(x) ((((unsigned short)(x))==(unsigned short)ARTYPE))
+#define BADMAGIC(x) (((unsigned short)(x) & 0x8080) && !ISMAGIC(x))
+
+
+/*------------------------------------------------------------------------*/
+/* OPTIONAL FILE HEADER */
+/*------------------------------------------------------------------------*/
+typedef struct aouthdr {
+ short magic; /* see magic.h */
+ short vstamp; /* version stamp */
+ long tsize; /* text size in bytes, padded to FW bdry*/
+ long dsize; /* initialized data " " */
+ long bsize; /* uninitialized data " " */
+ long entrypt; /* entry pt. */
+ long text_start; /* base of text used for this file */
+ long data_start; /* base of data used for this file */
+} AOUTHDR;
+
+#define AOUTSZ sizeof(AOUTHDR)
+
+/*----------------------------------------------------------------------*/
+/* When a UNIX aout header is to be built in the optional header, */
+/* the following magic numbers can appear in that header: */
+/* */
+/* AOUT1MAGIC : default : readonly sharable text segment */
+/* AOUT2MAGIC: : writable text segment */
+/* PAGEMAGIC : : configured for paging */
+/*----------------------------------------------------------------------*/
+#define AOUT1MAGIC 0410
+#define AOUT2MAGIC 0407
+#define PAGEMAGIC 0413
+
+
+/*------------------------------------------------------------------------*/
+/* COMMON ARCHIVE FILE STRUCTURES */
+/* */
+/* ARCHIVE File Organization: */
+/* _______________________________________________ */
+/* |__________ARCHIVE_MAGIC_STRING_______________| */
+/* |__________ARCHIVE_FILE_MEMBER_1______________| */
+/* | | */
+/* | Archive File Header "ar_hdr" | */
+/* |.............................................| */
+/* | Member Contents | */
+/* | 1. External symbol directory | */
+/* | 2. Text file | */
+/* |_____________________________________________| */
+/* |________ARCHIVE_FILE_MEMBER_2________________| */
+/* | "ar_hdr" | */
+/* |.............................................| */
+/* | Member Contents (.o or text file) | */
+/* |_____________________________________________| */
+/* | . . . | */
+/* | . . . | */
+/* | . . . | */
+/* |_____________________________________________| */
+/* |________ARCHIVE_FILE_MEMBER_n________________| */
+/* | "ar_hdr" | */
+/* |.............................................| */
+/* | Member Contents | */
+/* |_____________________________________________| */
+/* */
+/*------------------------------------------------------------------------*/
+
+#define COFF_ARMAG "!<arch>\n"
+#define SARMAG 8
+#define ARFMAG "`\n"
+
+struct ar_hdr /* archive file member header - printable ascii */
+{
+ char ar_name[16]; /* file member name - `/' terminated */
+ char ar_date[12]; /* file member date - decimal */
+ char ar_uid[6]; /* file member user id - decimal */
+ char ar_gid[6]; /* file member group id - decimal */
+ char ar_mode[8]; /* file member mode - octal */
+ char ar_size[10]; /* file member size - decimal */
+ char ar_fmag[2]; /* ARFMAG - string to end header */
+};
+
+
+/*------------------------------------------------------------------------*/
+/* SECTION HEADER */
+/*------------------------------------------------------------------------*/
+struct scnhdr {
+ char s_name[8]; /* section name */
+ long s_paddr; /* physical address */
+ long s_vaddr; /* virtual address */
+ long s_size; /* section size */
+ long s_scnptr; /* file ptr to raw data for section */
+ long s_relptr; /* file ptr to relocation */
+ long s_lnnoptr; /* file ptr to line numbers */
+ unsigned int s_nreloc; /* number of relocation entries */
+ unsigned int s_nlnno; /* number of line number entries */
+ unsigned int s_flags; /* flags */
+ unsigned short s_reserved; /* reserved byte */
+ unsigned short s_page; /* memory page id */
+ };
+
+#define SCNHDR struct scnhdr
+#define SCNHSZ sizeof(SCNHDR)
+
+/*------------------------------------------------------------------------*/
+/* Define constants for names of "special" sections */
+/*------------------------------------------------------------------------*/
+/* #define _TEXT ".text" */
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _CINIT ".cinit"
+#define _TV ".tv"
+
+/*------------------------------------------------------------------------*/
+/* The low 4 bits of s_flags is used as a section "type" */
+/*------------------------------------------------------------------------*/
+#define STYP_REG 0x00 /* "regular" : allocated, relocated, loaded */
+#define STYP_DSECT 0x01 /* "dummy" : not allocated, relocated, not loaded */
+#define STYP_NOLOAD 0x02 /* "noload" : allocated, relocated, not loaded */
+#define STYP_GROUP 0x04 /* "grouped" : formed of input sections */
+#define STYP_PAD 0x08 /* "padding" : not allocated, not relocated, loaded */
+#define STYP_COPY 0x10 /* "copy" : used for C init tables -
+ not allocated, relocated,
+ loaded; reloc & lineno
+ entries processed normally */
+#define STYP_TEXT 0x20 /* section contains text only */
+#define STYP_DATA 0x40 /* section contains data only */
+#define STYP_BSS 0x80 /* section contains bss only */
+
+#define STYP_ALIGN 0x100 /* align flag passed by old version assemblers */
+#define ALIGN_MASK 0x0F00 /* part of s_flags that is used for align vals */
+#define ALIGNSIZE(x) (1 << ((x & ALIGN_MASK) >> 8))
+
+
+/*------------------------------------------------------------------------*/
+/* RELOCATION ENTRIES */
+/*------------------------------------------------------------------------*/
+struct reloc
+{
+ long r_vaddr; /* (virtual) address of reference */
+ short r_symndx; /* index into symbol table */
+ unsigned short r_disp; /* additional bits for address calculation */
+ unsigned short r_type; /* relocation type */
+};
+
+#define RELOC struct reloc
+#define RELSZ 10 /* sizeof(RELOC) */
+
+/*--------------------------------------------------------------------------*/
+/* define all relocation types */
+/*--------------------------------------------------------------------------*/
+
+#define R_ABS 0 /* absolute address - no relocation */
+#define R_DIR16 01 /* UNUSED */
+#define R_REL16 02 /* UNUSED */
+#define R_DIR24 04 /* UNUSED */
+#define R_REL24 05 /* 24 bits, direct */
+#define R_DIR32 06 /* UNUSED */
+#define R_RELBYTE 017 /* 8 bits, direct */
+#define R_RELWORD 020 /* 16 bits, direct */
+#define R_RELLONG 021 /* 32 bits, direct */
+#define R_PCRBYTE 022 /* 8 bits, PC-relative */
+#define R_PCRWORD 023 /* 16 bits, PC-relative */
+#define R_PCRLONG 024 /* 32 bits, PC-relative */
+#define R_OCRLONG 030 /* GSP: 32 bits, one's complement direct */
+#define R_GSPPCR16 031 /* GSP: 16 bits, PC relative (in words) */
+#define R_GSPOPR32 032 /* GSP: 32 bits, direct big-endian */
+#define R_PARTLS16 040 /* Brahma: 16 bit offset of 24 bit address*/
+#define R_PARTMS8 041 /* Brahma: 8 bit page of 24 bit address */
+#define R_PARTLS7 050 /* DSP: 7 bit offset of 16 bit address */
+#define R_PARTMS9 051 /* DSP: 9 bit page of 16 bit address */
+#define R_REL13 052 /* DSP: 13 bits, direct */
+
+
+/*------------------------------------------------------------------------*/
+/* LINE NUMBER ENTRIES */
+/*------------------------------------------------------------------------*/
+struct lineno
+{
+ union
+ {
+ long l_symndx ; /* sym. table index of function name
+ iff l_lnno == 0 */
+ long l_paddr ; /* (physical) address of line number */
+ } l_addr ;
+ unsigned short l_lnno ; /* line number */
+};
+
+#define LINENO struct lineno
+#define LINESZ 6 /* sizeof(LINENO) */
+
+
+/*------------------------------------------------------------------------*/
+/* STORAGE CLASSES */
+/*------------------------------------------------------------------------*/
+#define C_EFCN -1 /* physical end of function */
+#define C_NULL 0
+#define C_AUTO 1 /* automatic variable */
+#define C_EXT 2 /* external symbol */
+#define C_STAT 3 /* static */
+#define C_REG 4 /* register variable */
+#define C_EXTDEF 5 /* external definition */
+#define C_LABEL 6 /* label */
+#define C_ULABEL 7 /* undefined label */
+#define C_MOS 8 /* member of structure */
+#define C_ARG 9 /* function argument */
+#define C_STRTAG 10 /* structure tag */
+#define C_MOU 11 /* member of union */
+#define C_UNTAG 12 /* union tag */
+#define C_TPDEF 13 /* type definition */
+#define C_USTATIC 14 /* undefined static */
+#define C_ENTAG 15 /* enumeration tag */
+#define C_MOE 16 /* member of enumeration */
+#define C_REGPARM 17 /* register parameter */
+#define C_FIELD 18 /* bit field */
+
+#define C_BLOCK 100 /* ".bb" or ".eb" */
+#define C_FCN 101 /* ".bf" or ".ef" */
+#define C_EOS 102 /* end of structure */
+#define C_FILE 103 /* file name */
+#define C_LINE 104 /* dummy sclass for line number entry */
+#define C_ALIAS 105 /* duplicate tag */
+#define C_HIDDEN 106 /* special storage class for external */
+ /* symbols in dmert public libraries */
+
+/*------------------------------------------------------------------------*/
+/* SYMBOL TABLE ENTRIES */
+/*------------------------------------------------------------------------*/
+
+#define SYMNMLEN 8 /* Number of characters in a symbol name */
+#define FILNMLEN 14 /* Number of characters in a file name */
+#define DIMNUM 4 /* Number of array dimensions in auxiliary entry */
+
+
+struct syment
+{
+ union
+ {
+ char _n_name[SYMNMLEN]; /* old COFF version */
+ struct
+ {
+ long _n_zeroes; /* new == 0 */
+ long _n_offset; /* offset into string table */
+ } _n_n;
+ char *_n_nptr[2]; /* allows for overlaying */
+ } _n;
+ long n_value; /* value of symbol */
+ short n_scnum; /* section number */
+ unsigned short n_type; /* type and derived type */
+ char n_sclass; /* storage class */
+ char n_numaux; /* number of aux. entries */
+};
+
+#define n_name _n._n_name
+#define n_nptr _n._n_nptr[1]
+#define n_zeroes _n._n_n._n_zeroes
+#define n_offset _n._n_n._n_offset
+
+/*------------------------------------------------------------------------*/
+/* Relocatable symbols have a section number of the */
+/* section in which they are defined. Otherwise, section */
+/* numbers have the following meanings: */
+/*------------------------------------------------------------------------*/
+#define N_UNDEF 0 /* undefined symbol */
+#define N_ABS -1 /* value of symbol is absolute */
+#define N_DEBUG -2 /* special debugging symbol */
+#define N_TV (unsigned short)-3 /* needs transfer vector (preload) */
+#define P_TV (unsigned short)-4 /* needs transfer vector (postload) */
+
+
+/*------------------------------------------------------------------------*/
+/* The fundamental type of a symbol packed into the low */
+/* 4 bits of the word. */
+/*------------------------------------------------------------------------*/
+#define _EF ".ef"
+
+#define T_NULL 0 /* no type info */
+#define T_ARG 1 /* function argument (only used by compiler) */
+#define T_CHAR 2 /* character */
+#define T_SHORT 3 /* short integer */
+#define T_INT 4 /* integer */
+#define T_LONG 5 /* long integer */
+#define T_FLOAT 6 /* floating point */
+#define T_DOUBLE 7 /* double word */
+#define T_STRUCT 8 /* structure */
+#define T_UNION 9 /* union */
+#define T_ENUM 10 /* enumeration */
+#define T_MOE 11 /* member of enumeration */
+#define T_UCHAR 12 /* unsigned character */
+#define T_USHORT 13 /* unsigned short */
+#define T_UINT 14 /* unsigned integer */
+#define T_ULONG 15 /* unsigned long */
+
+/*------------------------------------------------------------------------*/
+/* derived types are: */
+/*------------------------------------------------------------------------*/
+#define DT_NON 0 /* no derived type */
+#define DT_PTR 1 /* pointer */
+#define DT_FCN 2 /* function */
+#define DT_ARY 3 /* array */
+
+#define MKTYPE(basic, d1,d2,d3,d4,d5,d6) \
+ ((basic) | ((d1) << 4) | ((d2) << 6) | ((d3) << 8) |\
+ ((d4) << 10) | ((d5) << 12) | ((d6) << 14))
+
+/*------------------------------------------------------------------------*/
+/* type packing constants and macros */
+/*------------------------------------------------------------------------*/
+#define N_BTMASK_COFF 017
+#define N_TMASK_COFF 060
+#define N_TMASK1_COFF 0300
+#define N_TMASK2_COFF 0360
+#define N_BTSHFT_COFF 4
+#define N_TSHIFT_COFF 2
+
+#define BTYPE_COFF(x) ((x) & N_BTMASK_COFF)
+#define ISINT(x) (((x) >= T_CHAR && (x) <= T_LONG) || \
+ ((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM)
+#define ISFLT_COFF(x) ((x) == T_DOUBLE || (x) == T_FLOAT)
+#define ISPTR_COFF(x) (((x) & N_TMASK_COFF) == (DT_PTR << N_BTSHFT_COFF))
+#define ISFCN_COFF(x) (((x) & N_TMASK_COFF) == (DT_FCN << N_BTSHFT_COFF))
+#define ISARY_COFF(x) (((x) & N_TMASK_COFF) == (DT_ARY << N_BTSHFT_COFF))
+#define ISTAG_COFF(x) ((x)==C_STRTAG || (x)==C_UNTAG || (x)==C_ENTAG)
+
+#define INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<<N_TSHIFT_COFF)|(DT_PTR<<N_BTSHFT_COFF)|(x&N_BTMASK_COFF))
+#define DECREF_COFF(x) ((((x)>>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF))
+
+
+/*------------------------------------------------------------------------*/
+/* AUXILIARY SYMBOL ENTRY */
+/*------------------------------------------------------------------------*/
+union auxent
+{
+ struct
+ {
+ long x_tagndx; /* str, un, or enum tag indx */
+ union
+ {
+ struct
+ {
+ unsigned short x_lnno; /* declaration line number */
+ unsigned short x_size; /* str, union, array size */
+ } x_lnsz;
+ long x_fsize; /* size of function */
+ } x_misc;
+ union
+ {
+ struct /* if ISFCN, tag, or .bb */
+ {
+ long x_lnnoptr; /* ptr to fcn line # */
+ long x_endndx; /* entry ndx past block end */
+ } x_fcn;
+ struct /* if ISARY, up to 4 dimen. */
+ {
+ unsigned short x_dimen[DIMNUM];
+ } x_ary;
+ } x_fcnary;
+ unsigned short x_regcount; /* number of registers used by func */
+ } x_sym;
+ struct
+ {
+ char x_fname[FILNMLEN];
+ } x_file;
+ struct
+ {
+ long x_scnlen; /* section length */
+ unsigned short x_nreloc; /* number of relocation entries */
+ unsigned short x_nlinno; /* number of line numbers */
+ } x_scn;
+};
+
+#define SYMENT struct syment
+#define SYMESZ 18 /* sizeof(SYMENT) */
+
+#define AUXENT union auxent
+#define AUXESZ 18 /* sizeof(AUXENT) */
+
+/*------------------------------------------------------------------------*/
+/* NAMES OF "SPECIAL" SYMBOLS */
+/*------------------------------------------------------------------------*/
+#define _STEXT ".text"
+#define _ETEXT "etext"
+#define _SDATA ".data"
+#define _EDATA "edata"
+#define _SBSS ".bss"
+#define _END "end"
+#define _CINITPTR "cinit"
+
+/*--------------------------------------------------------------------------*/
+/* ENTRY POINT SYMBOLS */
+/*--------------------------------------------------------------------------*/
+#define _START "_start"
+#define _MAIN "_main"
+ /* _CSTART "_c_int00" (defined in params.h) */
+
+
+#define _TVORIG "_tvorig"
+#define _TORIGIN "_torigin"
+#define _DORIGIN "_dorigin"
+
+#define _SORIGIN "_sorigin"
diff --git a/configure b/configure
new file mode 100755
index 0000000..1ee3acb
--- /dev/null
+++ b/configure
@@ -0,0 +1,527 @@
+#!/bin/sh
+#
+# tcc configure script (c) 2003 Fabrice Bellard
+
+# set temporary file name
+# if test ! -z "$TMPDIR" ; then
+# TMPDIR1="${TMPDIR}"
+# elif test ! -z "$TEMPDIR" ; then
+# TMPDIR1="${TEMPDIR}"
+# else
+# TMPDIR1="/tmp"
+# fi
+#
+# bashism: TMPN="${TMPDIR1}/tcc-conf-${RANDOM}-$$-${RANDOM}.c"
+
+TMPN="./conftest-$$"
+TMPH=$TMPN.h
+
+# default parameters
+prefix=""
+execprefix=""
+bindir=""
+libdir=""
+tccdir=""
+includedir=""
+mandir=""
+infodir=""
+sysroot=""
+cross_prefix=""
+cc="gcc"
+ar="ar"
+strip="strip"
+bigendian="no"
+mingw32="no"
+LIBSUF=".a"
+EXESUF=""
+DLLSUF=".so"
+tcc_sysincludepaths=""
+tcc_libpaths=""
+tcc_crtprefix=""
+tcc_elfinterp=""
+triplet=
+tcc_lddir=
+confvars=
+suggest="yes"
+cpu=
+cpuver=
+gcc_major=0
+gcc_minor=0
+
+# OS specific
+targetos=`uname`
+case $targetos in
+ Darwin)
+ confvars="$confvars OSX"
+ DLLSUF=".dylib"
+ ;;
+ MINGW*|MSYS*|CYGWIN*)
+ mingw32=yes
+ ;;
+ DragonFly|OpenBSD|FreeBSD|NetBSD)
+ confvars="$confvars ldl=no"
+ ;;
+ *)
+ ;;
+esac
+
+# find source path
+source_path=${0%configure}
+source_path=${source_path%/}
+source_path_used="yes"
+if test -z "$source_path" -o "$source_path" = "." ; then
+ source_path=`pwd`
+ source_path_used="no"
+fi
+
+for opt do
+ eval opt=\"$opt\"
+ case "$opt" in
+ --prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --exec-prefix=*) execprefix=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --tccdir=*) tccdir=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --bindir=*) bindir=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --libdir=*) libdir=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --includedir=*) includedir=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --sharedir=*) sharedir=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --mandir=*) mandir=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --infodir=*) infodir=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --docdir=*) docdir=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --sysroot=*) sysroot=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --source-path=*) source_path=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --cc=*) cc=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --ar=*) ar=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --extra-cflags=*) CFLAGS="${opt#--extra-cflags=}"
+ ;;
+ --extra-ldflags=*) LDFLAGS="${opt#--extra-ldflags=}"
+ ;;
+ --extra-libs=*) extralibs="${opt#--extra-libs=}"
+ ;;
+ --sysincludepaths=*) tcc_sysincludepaths=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --libpaths=*) tcc_libpaths=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --crtprefix=*) tcc_crtprefix=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --elfinterp=*) tcc_elfinterp=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --triplet=*) triplet=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --cpu=*) cpu=`echo $opt | cut -d '=' -f 2`
+ ;;
+ --enable-cross) confvars="$confvars cross"
+ ;;
+ --disable-static) confvars="$confvars static=no"
+ ;;
+ --enable-static) confvars="$confvars static"
+ ;;
+ --disable-rpath) confvars="$confvars rpath=no"
+ ;;
+ --strip-binaries) confvars="$confvars strip"
+ ;;
+ --with-libgcc) confvars="$confvars libgcc"
+ ;;
+ --with-selinux) confvars="$confvars selinux"
+ ;;
+ --config-mingw32*) mingw32=$(echo "$opt=yes" | cut -d '=' -f 2)
+ ;;
+ --config-*) confvars="$confvars ${opt#--config-}"; suggest="no"
+ ;;
+ --help|-h) show_help="yes"
+ ;;
+ *) echo "configure: WARNING: unrecognized option $opt"
+ ;;
+ esac
+done
+
+if test -z "$cpu" ; then
+ if test -n "$ARCH" ; then
+ cpu="$ARCH"
+ else
+ cpu=`uname -m`
+ fi
+fi
+
+case "$cpu" in
+ x86|i386|i486|i586|i686|i86pc|BePC|i686-AT386)
+ cpu="i386"
+ ;;
+ x86_64|amd64|x86-64)
+ cpu="x86_64"
+ ;;
+ arm*)
+ case "$cpu" in
+ arm|armv4l)
+ cpuver=4
+ ;;
+ armv5tel|armv5tejl)
+ cpuver=5
+ ;;
+ armv6j|armv6l)
+ cpuver=6
+ ;;
+ armv7a|armv7l)
+ cpuver=7
+ ;;
+ esac
+ cpu="arm"
+ ;;
+ aarch64)
+ cpu="aarch64"
+ ;;
+ alpha)
+ cpu="alpha"
+ ;;
+ "Power Macintosh"|ppc|ppc64)
+ cpu="ppc"
+ ;;
+ mips)
+ cpu="mips"
+ ;;
+ s390)
+ cpu="s390"
+ ;;
+ *)
+ echo "Unsupported CPU"
+ exit 1
+ ;;
+esac
+
+# Checking for CFLAGS
+if test -z "$CFLAGS"; then
+ CFLAGS="-Wall -g -O2"
+fi
+
+if test "$mingw32" = "yes" ; then
+ if test "$source_path_used" = "no"; then
+ source_path="."
+ fi
+ if test "$cc" = gcc; then
+ test -z "$LDFLAGS" && LDFLAGS="-static"
+ fi
+ test -z "$prefix" && prefix="C:/Program Files/tcc"
+ test -z "$tccdir" && tccdir="${prefix}"
+ test -z "$bindir" && bindir="${tccdir}"
+ test -z "$docdir" && docdir="${tccdir}/doc"
+ test -z "$libdir" && libdir="${tccdir}/libtcc"
+ confvars="$confvars WIN32"
+ LIBSUF=".lib"
+ EXESUF=".exe"
+ DLLSUF=".dll"
+else
+ if test -z "$prefix" ; then
+ prefix="/usr/local"
+ fi
+ if test -z "$sharedir" ; then
+ sharedir="${prefix}/share"
+ fi
+ if test x"$execprefix" = x""; then
+ execprefix="${prefix}"
+ fi
+ if test x"$libdir" = x""; then
+ libdir="${execprefix}/lib"
+ fi
+ if test x"$bindir" = x""; then
+ bindir="${execprefix}/bin"
+ fi
+ if test x"$docdir" = x""; then
+ docdir="${sharedir}/doc"
+ fi
+ if test x"$mandir" = x""; then
+ mandir="${sharedir}/man"
+ fi
+ if test x"$infodir" = x""; then
+ infodir="${sharedir}/info"
+ fi
+ if test x"$tccdir" = x""; then
+ tccdir="${libdir}/tcc"
+ fi
+ if test x"$includedir" = x""; then
+ includedir="${prefix}/include"
+ fi
+fi # mingw32
+
+if test x"$show_help" = "xyes" ; then
+cat << EOF
+Usage: configure [options]
+Options: [defaults in brackets after descriptions]
+
+Standard options:
+ --help print this message
+ --prefix=PREFIX install in PREFIX [$prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --tccdir=DIR installation directory [EPREFIX/lib/tcc]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --sharedir=DIR documentation root DIR [PREFIX/share]
+ --docdir=DIR documentation in DIR [SHAREDIR/doc/tcc]
+ --mandir=DIR man documentation in DIR [SHAREDIR/man]
+ --infodir=DIR info documentation in DIR [SHAREDIR/info]
+
+Advanced options (experts only):
+ --source-path=PATH path of source code [$source_path]
+ --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
+ --sysroot=PREFIX prepend PREFIX to library/include paths []
+ --cc=CC use C compiler CC [$cc]
+ --ar=AR create archives using AR [$ar]
+ --extra-cflags= specify compiler flags [$CFLAGS]
+ --extra-ldflags= specify linker options []
+ --cpu=CPU CPU [$cpu]
+ --strip-binaries strip symbol tables from resulting binaries
+ --disable-static make libtcc.so instead of libtcc.a
+ --enable-static make libtcc.a instead of libtcc.dll (win32)
+ --disable-rpath disable use of -rpath with the above
+ --with-libgcc use libgcc_s.so.1 instead of libtcc1.a
+ --enable-cross build cross compilers
+ --with-selinux use mmap for executable memory (with tcc -run)
+ --sysincludepaths=... specify system include paths, colon separated
+ --libpaths=... specify system library paths, colon separated
+ --crtprefix=... specify locations of crt?.o, colon separated
+ --elfinterp=... specify elf interpreter
+ --triplet=... specify system library/include directory triplet
+ --config-uClibc,-musl,-mingw32... enable system specific configurations
+EOF
+#echo "NOTE: The object files are build at the place where configure is launched"
+exit 1
+fi
+
+cc="${cross_prefix}${cc}"
+ar="${cross_prefix}${ar}"
+strip="${cross_prefix}${strip}"
+
+if test -z "$cross_prefix" ; then
+ CONFTEST=./conftest$EXESUF
+ if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then
+ echo "configure: error: '$cc' failed to compile conftest.c."
+ else
+ gcc_major="$($CONFTEST version)"
+ gcc_minor="$($CONFTEST minor)"
+ fi
+ bigendian="$($CONFTEST bigendian)"
+ if test "$mingw32" = "no" ; then
+
+ if test -z "$triplet"; then
+ tt="$($CONFTEST triplet)"
+ if test -n "$tt" -a -f "/usr/lib/$tt/crti.o" ; then
+ triplet="$tt"
+ fi
+ fi
+
+ if test -z "$triplet"; then
+ if test $cpu = "x86_64" -o $cpu = "aarch64" ; then
+ if test -f "/usr/lib64/crti.o" ; then
+ tcc_lddir="lib64"
+ fi
+ fi
+ fi
+
+ if test "$cpu" = "arm" ; then
+ if test "${triplet%eabihf}" != "$triplet" ; then
+ confvars="$confvars arm_eabihf"
+ elif test "${triplet%eabi}" != "$triplet" ; then
+ confvars="$confvars arm_eabi"
+ fi
+ if grep -s -q "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo ; then
+ confvars="$confvars arm_vfp"
+ fi
+ fi
+
+ if test "$suggest" = "yes"; then
+ if test -f "/lib/ld-uClibc.so.0" ; then
+ echo "Perhaps you want ./configure --config-uClibc"
+ fi
+ if test -f "/lib/ld-musl-$cpu.so.1"; then
+ echo "Perhaps you want ./configure --config-musl"
+ fi
+ fi
+ fi
+else
+ # if cross compiling, cannot launch a program, so make a static guess
+ case $cpu in
+ ppc|mips|s390) bigendian=yes;;
+ esac
+fi
+
+if test "$bigendian" = "yes" ; then
+ confvars="$confvars BIGENDIAN"
+fi
+
+# a final configuration tuning
+if ! echo "$cc" | grep -q "tcc"; then
+ OPT1="-Wdeclaration-after-statement -fno-strict-aliasing"
+ # we want -Wno- but gcc does not always reject unknown -Wno- options
+ OPT2="-Wpointer-sign -Wsign-compare -Wunused-result"
+ if echo "$cc" | grep -q "clang"; then
+ OPT1="$OPT1 -fheinous-gnu-extensions"
+ OPT2="$OPT2 -Wstring-plus-int"
+ fi
+ $cc $OPT1 $OPT2 -o a.out -c -xc - < /dev/null > cc_msg.txt 2>&1
+ for o in $OPT1; do # enable these options
+ if ! grep -q -- $o cc_msg.txt; then CFLAGS="$CFLAGS $o"; fi
+ done
+ for o in $OPT2; do # disable these options
+ if ! grep -q -- $o cc_msg.txt; then CFLAGS="$CFLAGS -Wno-${o#-W*}"; fi
+ done
+ # cat cc_msg.txt
+ # echo $CFLAGS
+ rm -f cc_msg.txt a.out
+fi
+
+fcho() { if test -n "$2"; then echo "$1$2"; fi }
+
+fcho "Binary directory " "$bindir"
+fcho "TinyCC directory " "$tccdir"
+fcho "Library directory " "$libdir"
+fcho "Include directory " "$includedir"
+fcho "Manual directory " "$mandir"
+fcho "Info directory " "$infodir"
+fcho "Doc directory " "$docdir"
+fcho "Target root prefix " "$sysroot"
+echo "Source path $source_path"
+echo "C compiler $cc ($gcc_major.$gcc_minor)"
+echo "Target OS $targetos"
+echo "CPU $cpu"
+fcho "Triplet " "$triplet"
+fcho "Config " "${confvars# }"
+echo "Creating config.mak and config.h"
+
+cat >config.mak <<EOF
+# Automatically generated by configure - do not modify
+prefix=$prefix
+bindir=\$(DESTDIR)$bindir
+tccdir=\$(DESTDIR)$tccdir
+libdir=\$(DESTDIR)$libdir
+includedir=\$(DESTDIR)$includedir
+mandir=\$(DESTDIR)$mandir
+infodir=\$(DESTDIR)$infodir
+docdir=\$(DESTDIR)$docdir
+CC=$cc
+GCC_MAJOR=$gcc_major
+GCC_MINOR=$gcc_minor
+AR=$ar
+STRIP=$strip -s -R .comment -R .note
+CFLAGS=$CFLAGS
+LDFLAGS=$LDFLAGS
+LIBSUF=$LIBSUF
+EXESUF=$EXESUF
+DLLSUF=$DLLSUF
+EOF
+
+print_inc() {
+ if test -n "$2"; then
+ echo "#ifndef $1" >> $TMPH
+ echo "# define $1 \"$2\"" >> $TMPH
+ echo "#endif" >> $TMPH
+ fi
+}
+
+print_mak() {
+ if test -n "$2"; then
+ echo "NATIVE_DEFINES+=-D$1=\"\\\"$2\\\"\"" >> config.mak
+ fi
+}
+
+print_mak_int() {
+ if test -n "$2"; then
+ echo "NATIVE_DEFINES+=-D$1=$2" >> config.mak
+ fi
+}
+
+echo "/* Automatically generated by configure - do not modify */" > $TMPH
+
+print_inc CONFIG_SYSROOT "$sysroot"
+print_inc CONFIG_TCCDIR "$tccdir"
+print_mak CONFIG_TCC_SYSINCLUDEPATHS "$tcc_sysincludepaths"
+print_mak CONFIG_TCC_LIBPATHS "$tcc_libpaths"
+print_mak CONFIG_TCC_CRTPREFIX "$tcc_crtprefix"
+print_mak CONFIG_TCC_ELFINTERP "$tcc_elfinterp"
+print_mak CONFIG_LDDIR "$tcc_lddir"
+print_mak CONFIG_TRIPLET "$triplet"
+print_mak_int TCC_CPU_VERSION "$cpuver"
+
+if test "$cpu" = "aarch64" ; then
+ echo "ARCH=arm64" >> config.mak
+else
+ echo "ARCH=$cpu" >> config.mak
+fi
+echo "TARGETOS=$targetos" >> config.mak
+
+for v in $confvars ; do
+ if test "${v%=*}" = "$v"; then
+ echo "CONFIG_$v=yes" >> config.mak
+ else
+ echo "CONFIG_$v" >> config.mak
+ fi
+done
+
+version=`head $source_path/VERSION`
+echo "VERSION = $version" >> config.mak
+echo "#define TCC_VERSION \"$version\"" >> $TMPH
+echo "@set VERSION $version" > config.texi
+
+if test "$source_path_used" = "yes" ; then
+ case $source_path in
+ /*) echo "TOPSRC=$source_path";;
+ *) echo "TOPSRC=\$(TOP)/$source_path";;
+ esac >>config.mak
+else
+ echo 'TOPSRC=$(TOP)' >>config.mak
+fi
+
+diff $TMPH config.h >/dev/null 2>&1
+if test $? -ne 0 ; then
+ mv -f $TMPH config.h
+else
+ echo "config.h is unchanged"
+fi
+
+rm -f $TMPN* $CONFTEST
+
+# ---------------------------------------------------------------------------
+# build tree in object directory if source path is different from current one
+
+fn_makelink()
+{
+ tgt=$1/$2
+ case $2 in
+ */*) dn=${2%/*}
+ test -d $dn || mkdir -p $dn
+ case $1 in
+ /*) ;;
+ *) while test $dn ; do
+ tgt=../$tgt; dn=${dn#${dn%%/*}}; dn=${dn#/}
+ done
+ ;;
+ esac
+ ;;
+ esac
+
+ ln -sfn $tgt $2 || ( echo "ln failed. Using cp instead."; cp -f $1/$2 $2 )
+}
+
+if test "$source_path_used" = "yes" ; then
+ FILES="Makefile lib/Makefile tests/Makefile tests/tests2/Makefile tests/pp/Makefile"
+ for f in $FILES ; do
+ fn_makelink $source_path $f
+ done
+fi
+
+# ---------------------------------------------------------------------------
diff --git a/conftest.c b/conftest.c
new file mode 100644
index 0000000..2824cc8
--- /dev/null
+++ b/conftest.c
@@ -0,0 +1,87 @@
+#include <stdio.h>
+
+/* Define architecture */
+#if defined(__i386__) || defined _M_IX86
+# define TRIPLET_ARCH "i386"
+#elif defined(__x86_64__) || defined _M_AMD64
+# define TRIPLET_ARCH "x86_64"
+#elif defined(__arm__)
+# define TRIPLET_ARCH "arm"
+#elif defined(__aarch64__)
+# define TRIPLET_ARCH "aarch64"
+#else
+# define TRIPLET_ARCH "unknown"
+#endif
+
+/* Define OS */
+#if defined (__linux__)
+# define TRIPLET_OS "linux"
+#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
+# define TRIPLET_OS "kfreebsd"
+#elif defined _WIN32
+# define TRIPLET_OS "win32"
+#elif !defined (__GNU__)
+# define TRIPLET_OS "unknown"
+#endif
+
+/* Define calling convention and ABI */
+#if defined (__ARM_EABI__)
+# if defined (__ARM_PCS_VFP)
+# define TRIPLET_ABI "gnueabihf"
+# else
+# define TRIPLET_ABI "gnueabi"
+# endif
+#else
+# define TRIPLET_ABI "gnu"
+#endif
+
+#if defined _WIN32
+# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS
+#elif defined __GNU__
+# define TRIPLET TRIPLET_ARCH "-" TRIPLET_ABI
+#else
+# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS "-" TRIPLET_ABI
+#endif
+
+#if defined(_WIN32)
+int _CRT_glob = 0;
+#endif
+
+int main(int argc, char *argv[])
+{
+ switch(argc == 2 ? argv[1][0] : 0) {
+ case 'b':
+ {
+ volatile unsigned foo = 0x01234567;
+ puts(*(unsigned char*)&foo == 0x67 ? "no" : "yes");
+ break;
+ }
+#ifdef __GNUC__
+ case 'm':
+ printf("%d\n", __GNUC_MINOR__);
+ break;
+ case 'v':
+ printf("%d\n", __GNUC__);
+ break;
+#elif defined __TINYC__
+ case 'v':
+ puts("0");
+ break;
+ case 'm':
+ printf("%d\n", __TINYC__);
+ break;
+#else
+ case 'm':
+ case 'v':
+ puts("0");
+ break;
+#endif
+ case 't':
+ puts(TRIPLET);
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
diff --git a/elf.h b/elf.h
new file mode 100644
index 0000000..9fed6eb
--- /dev/null
+++ b/elf.h
@@ -0,0 +1,3237 @@
+/* This file defines standard ELF types, structures, and macros.
+ Copyright (C) 1995-2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _ELF_H
+#define _ELF_H 1
+
+#ifndef _WIN32
+#include <inttypes.h>
+#else
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef signed char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
+typedef long long int int64_t;
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long int uint64_t;
+#endif
+#endif
+
+/* Standard ELF types. */
+
+/* Type for a 16-bit quantity. */
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+/* Types for signed and unsigned 32-bit quantities. */
+typedef uint32_t Elf32_Word;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef int32_t Elf64_Sword;
+
+/* Types for signed and unsigned 64-bit quantities. */
+typedef uint64_t Elf32_Xword;
+typedef int64_t Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+/* Type of addresses. */
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+/* Type of file offsets. */
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+/* Type for section indices, which are 16-bit quantities. */
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+/* Type for version symbol information. */
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+
+/* The ELF file header. This appears at the start of every ELF file. */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
+ Elf32_Half e_type; /* Object file type */
+ Elf32_Half e_machine; /* Architecture */
+ Elf32_Word e_version; /* Object file version */
+ Elf32_Addr e_entry; /* Entry point virtual address */
+ Elf32_Off e_phoff; /* Program header table file offset */
+ Elf32_Off e_shoff; /* Section header table file offset */
+ Elf32_Word e_flags; /* Processor-specific flags */
+ Elf32_Half e_ehsize; /* ELF header size in bytes */
+ Elf32_Half e_phentsize; /* Program header table entry size */
+ Elf32_Half e_phnum; /* Program header table entry count */
+ Elf32_Half e_shentsize; /* Section header table entry size */
+ Elf32_Half e_shnum; /* Section header table entry count */
+ Elf32_Half e_shstrndx; /* Section header string table index */
+} Elf32_Ehdr;
+
+typedef struct
+{
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
+ Elf64_Half e_type; /* Object file type */
+ Elf64_Half e_machine; /* Architecture */
+ Elf64_Word e_version; /* Object file version */
+ Elf64_Addr e_entry; /* Entry point virtual address */
+ Elf64_Off e_phoff; /* Program header table file offset */
+ Elf64_Off e_shoff; /* Section header table file offset */
+ Elf64_Word e_flags; /* Processor-specific flags */
+ Elf64_Half e_ehsize; /* ELF header size in bytes */
+ Elf64_Half e_phentsize; /* Program header table entry size */
+ Elf64_Half e_phnum; /* Program header table entry count */
+ Elf64_Half e_shentsize; /* Section header table entry size */
+ Elf64_Half e_shnum; /* Section header table entry count */
+ Elf64_Half e_shstrndx; /* Section header string table index */
+} Elf64_Ehdr;
+
+/* Fields in the e_ident array. The EI_* macros are indices into the
+ array. The macros under each EI_* macro are the values the byte
+ may have. */
+
+#define EI_MAG0 0 /* File identification byte 0 index */
+#define ELFMAG0 0x7f /* Magic number byte 0 */
+
+#define EI_MAG1 1 /* File identification byte 1 index */
+#define ELFMAG1 'E' /* Magic number byte 1 */
+
+#define EI_MAG2 2 /* File identification byte 2 index */
+#define ELFMAG2 'L' /* Magic number byte 2 */
+
+#define EI_MAG3 3 /* File identification byte 3 index */
+#define ELFMAG3 'F' /* Magic number byte 3 */
+
+/* Conglomeration of the identification bytes, for easy testing as a word. */
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define EI_CLASS 4 /* File class byte index */
+#define ELFCLASSNONE 0 /* Invalid class */
+#define ELFCLASS32 1 /* 32-bit objects */
+#define ELFCLASS64 2 /* 64-bit objects */
+#define ELFCLASSNUM 3
+
+#define EI_DATA 5 /* Data encoding byte index */
+#define ELFDATANONE 0 /* Invalid data encoding */
+#define ELFDATA2LSB 1 /* 2's complement, little endian */
+#define ELFDATA2MSB 2 /* 2's complement, big endian */
+#define ELFDATANUM 3
+
+#define EI_VERSION 6 /* File version byte index */
+ /* Value must be EV_CURRENT */
+
+#define EI_OSABI 7 /* OS ABI identification */
+#define ELFOSABI_NONE 0 /* UNIX System V ABI */
+#define ELFOSABI_SYSV 0 /* Alias. */
+#define ELFOSABI_HPUX 1 /* HP-UX */
+#define ELFOSABI_NETBSD 2 /* NetBSD. */
+#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */
+#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */
+#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
+#define ELFOSABI_AIX 7 /* IBM AIX. */
+#define ELFOSABI_IRIX 8 /* SGI Irix. */
+#define ELFOSABI_FREEBSD 9 /* FreeBSD. */
+#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
+#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
+#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
+#define ELFOSABI_ARM 97 /* ARM */
+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
+
+#define EI_ABIVERSION 8 /* ABI version */
+
+#define EI_PAD 9 /* Byte index of padding bytes */
+
+/* Legal values for e_type (object file type). */
+
+#define ET_NONE 0 /* No file type */
+#define ET_REL 1 /* Relocatable file */
+#define ET_EXEC 2 /* Executable file */
+#define ET_DYN 3 /* Shared object file */
+#define ET_CORE 4 /* Core file */
+#define ET_NUM 5 /* Number of defined types */
+#define ET_LOOS 0xfe00 /* OS-specific range start */
+#define ET_HIOS 0xfeff /* OS-specific range end */
+#define ET_LOPROC 0xff00 /* Processor-specific range start */
+#define ET_HIPROC 0xffff /* Processor-specific range end */
+
+/* Legal values for e_machine (architecture). */
+
+#define EM_NONE 0 /* No machine */
+#define EM_M32 1 /* AT&T WE 32100 */
+#define EM_SPARC 2 /* SUN SPARC */
+#define EM_386 3 /* Intel 80386 */
+#define EM_68K 4 /* Motorola m68k family */
+#define EM_88K 5 /* Motorola m88k family */
+#define EM_860 7 /* Intel 80860 */
+#define EM_MIPS 8 /* MIPS R3000 big-endian */
+#define EM_S370 9 /* IBM System/370 */
+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
+
+#define EM_PARISC 15 /* HPPA */
+#define EM_VPP500 17 /* Fujitsu VPP500 */
+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
+#define EM_960 19 /* Intel 80960 */
+#define EM_PPC 20 /* PowerPC */
+#define EM_PPC64 21 /* PowerPC 64-bit */
+#define EM_S390 22 /* IBM S390 */
+
+#define EM_V800 36 /* NEC V800 series */
+#define EM_FR20 37 /* Fujitsu FR20 */
+#define EM_RH32 38 /* TRW RH-32 */
+#define EM_RCE 39 /* Motorola RCE */
+#define EM_ARM 40 /* ARM */
+#define EM_FAKE_ALPHA 41 /* Digital Alpha */
+#define EM_SH 42 /* Hitachi SH */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit */
+#define EM_TRICORE 44 /* Siemens Tricore */
+#define EM_ARC 45 /* Argonaut RISC Core */
+#define EM_H8_300 46 /* Hitachi H8/300 */
+#define EM_H8_300H 47 /* Hitachi H8/300H */
+#define EM_H8S 48 /* Hitachi H8S */
+#define EM_H8_500 49 /* Hitachi H8/500 */
+#define EM_IA_64 50 /* Intel Merced */
+#define EM_MIPS_X 51 /* Stanford MIPS-X */
+#define EM_COLDFIRE 52 /* Motorola Coldfire */
+#define EM_68HC12 53 /* Motorola M68HC12 */
+#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
+#define EM_PCP 55 /* Siemens PCP */
+#define EM_NCPU 56 /* Sony nCPU embedded RISC */
+#define EM_NDR1 57 /* Denso NDR1 microprocessor */
+#define EM_STARCORE 58 /* Motorola Start*Core processor */
+#define EM_ME16 59 /* Toyota ME16 processor */
+#define EM_ST100 60 /* STMicroelectronic ST100 processor */
+#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
+#define EM_X86_64 62 /* AMD x86-64 architecture */
+#define EM_PDSP 63 /* Sony DSP Processor */
+
+#define EM_FX66 66 /* Siemens FX66 microcontroller */
+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7 68 /* STMicroelectronics ST7 8 bit mc */
+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
+#define EM_SVX 73 /* Silicon Graphics SVx */
+#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX 75 /* Digital VAX */
+#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */
+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY 81 /* Harvard University machine-independent object files */
+#define EM_PRISM 82 /* SiTera Prism */
+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
+#define EM_FR30 84 /* Fujitsu FR30 */
+#define EM_D10V 85 /* Mitsubishi D10V */
+#define EM_D30V 86 /* Mitsubishi D30V */
+#define EM_V850 87 /* NEC v850 */
+#define EM_M32R 88 /* Mitsubishi M32R */
+#define EM_MN10300 89 /* Matsushita MN10300 */
+#define EM_MN10200 90 /* Matsushita MN10200 */
+#define EM_PJ 91 /* picoJava */
+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
+#define EM_AARCH64 183 /* ARM AARCH64 */
+#define EM_TILEPRO 188 /* Tilera TILEPro */
+#define EM_TILEGX 191 /* Tilera TILE-Gx */
+#define EM_NUM 192
+
+/* If it is necessary to assign new unofficial EM_* values, please
+ pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+ chances of collision with official or non-GNU unofficial values. */
+
+#define EM_ALPHA 0x9026
+#define EM_C60 0x9c60
+
+/* Legal values for e_version (version). */
+
+#define EV_NONE 0 /* Invalid ELF version */
+#define EV_CURRENT 1 /* Current version */
+#define EV_NUM 2
+
+/* Section header. */
+
+typedef struct
+{
+ Elf32_Word sh_name; /* Section name (string tbl index) */
+ Elf32_Word sh_type; /* Section type */
+ Elf32_Word sh_flags; /* Section flags */
+ Elf32_Addr sh_addr; /* Section virtual addr at execution */
+ Elf32_Off sh_offset; /* Section file offset */
+ Elf32_Word sh_size; /* Section size in bytes */
+ Elf32_Word sh_link; /* Link to another section */
+ Elf32_Word sh_info; /* Additional section information */
+ Elf32_Word sh_addralign; /* Section alignment */
+ Elf32_Word sh_entsize; /* Entry size if section holds table */
+} Elf32_Shdr;
+
+typedef struct
+{
+ Elf64_Word sh_name; /* Section name (string tbl index) */
+ Elf64_Word sh_type; /* Section type */
+ Elf64_Xword sh_flags; /* Section flags */
+ Elf64_Addr sh_addr; /* Section virtual addr at execution */
+ Elf64_Off sh_offset; /* Section file offset */
+ Elf64_Xword sh_size; /* Section size in bytes */
+ Elf64_Word sh_link; /* Link to another section */
+ Elf64_Word sh_info; /* Additional section information */
+ Elf64_Xword sh_addralign; /* Section alignment */
+ Elf64_Xword sh_entsize; /* Entry size if section holds table */
+} Elf64_Shdr;
+
+/* Special section indices. */
+
+#define SHN_UNDEF 0 /* Undefined section */
+#define SHN_LORESERVE 0xff00 /* Start of reserved indices */
+#define SHN_LOPROC 0xff00 /* Start of processor-specific */
+#define SHN_BEFORE 0xff00 /* Order section before all others
+ (Solaris). */
+#define SHN_AFTER 0xff01 /* Order section after all others
+ (Solaris). */
+#define SHN_HIPROC 0xff1f /* End of processor-specific */
+#define SHN_LOOS 0xff20 /* Start of OS-specific */
+#define SHN_HIOS 0xff3f /* End of OS-specific */
+#define SHN_ABS 0xfff1 /* Associated symbol is absolute */
+#define SHN_COMMON 0xfff2 /* Associated symbol is common */
+#define SHN_XINDEX 0xffff /* Index is in extra table. */
+#define SHN_HIRESERVE 0xffff /* End of reserved indices */
+
+/* Legal values for sh_type (section type). */
+
+#define SHT_NULL 0 /* Section header table entry unused */
+#define SHT_PROGBITS 1 /* Program data */
+#define SHT_SYMTAB 2 /* Symbol table */
+#define SHT_STRTAB 3 /* String table */
+#define SHT_RELA 4 /* Relocation entries with addends */
+#define SHT_HASH 5 /* Symbol hash table */
+#define SHT_DYNAMIC 6 /* Dynamic linking information */
+#define SHT_NOTE 7 /* Notes */
+#define SHT_NOBITS 8 /* Program space with no data (bss) */
+#define SHT_REL 9 /* Relocation entries, no addends */
+#define SHT_SHLIB 10 /* Reserved */
+#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY 14 /* Array of constructors */
+#define SHT_FINI_ARRAY 15 /* Array of destructors */
+#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
+#define SHT_GROUP 17 /* Section group */
+#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */
+#define SHT_NUM 19 /* Number of defined types. */
+#define SHT_LOOS 0x60000000 /* Start OS-specific. */
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
+#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
+#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */
+#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
+#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */
+#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */
+#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */
+#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */
+#define SHT_HIOS 0x6fffffff /* End OS-specific type */
+#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
+#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
+#define SHT_LOUSER 0x80000000 /* Start of application-specific */
+#define SHT_HIUSER 0x8fffffff /* End of application-specific */
+
+/* Legal values for sh_flags (section flags). */
+
+#define SHF_WRITE (1 << 0) /* Writable */
+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
+#define SHF_EXECINSTR (1 << 2) /* Executable */
+#define SHF_MERGE (1 << 4) /* Might be merged */
+#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
+#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */
+#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */
+#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling
+ required */
+#define SHF_GROUP (1 << 9) /* Section is member of a group. */
+#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
+#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */
+#define SHF_MASKOS 0x0ff00000 /* OS-specific. */
+#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
+#define SHF_ORDERED (1 << 30) /* Special ordering requirement
+ (Solaris). */
+#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless
+ referenced or allocated (Solaris).*/
+
+/* Section group handling. */
+#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */
+
+/* Symbol table entry. */
+
+typedef struct
+{
+ Elf32_Word st_name; /* Symbol name (string tbl index) */
+ Elf32_Addr st_value; /* Symbol value */
+ Elf32_Word st_size; /* Symbol size */
+ unsigned char st_info; /* Symbol type and binding */
+ unsigned char st_other; /* Symbol visibility */
+ Elf32_Section st_shndx; /* Section index */
+} Elf32_Sym;
+
+typedef struct
+{
+ Elf64_Word st_name; /* Symbol name (string tbl index) */
+ unsigned char st_info; /* Symbol type and binding */
+ unsigned char st_other; /* Symbol visibility */
+ Elf64_Section st_shndx; /* Section index */
+ Elf64_Addr st_value; /* Symbol value */
+ Elf64_Xword st_size; /* Symbol size */
+} Elf64_Sym;
+
+/* The syminfo section if available contains additional information about
+ every dynamic symbol. */
+
+typedef struct
+{
+ Elf32_Half si_boundto; /* Direct bindings, symbol bound to */
+ Elf32_Half si_flags; /* Per symbol flags */
+} Elf32_Syminfo;
+
+typedef struct
+{
+ Elf64_Half si_boundto; /* Direct bindings, symbol bound to */
+ Elf64_Half si_flags; /* Per symbol flags */
+} Elf64_Syminfo;
+
+/* Possible values for si_boundto. */
+#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */
+#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */
+
+/* Possible bitmasks for si_flags. */
+#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy
+ loaded */
+/* Syminfo version values. */
+#define SYMINFO_NONE 0
+#define SYMINFO_CURRENT 1
+#define SYMINFO_NUM 2
+
+
+/* How to extract and insert information held in the st_info field. */
+
+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val) ((val) & 0xf)
+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */
+#define ELF64_ST_BIND(val) ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type))
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding). */
+
+#define STB_LOCAL 0 /* Local symbol */
+#define STB_GLOBAL 1 /* Global symbol */
+#define STB_WEAK 2 /* Weak symbol */
+#define STB_NUM 3 /* Number of defined types. */
+#define STB_LOOS 10 /* Start of OS-specific */
+#define STB_GNU_UNIQUE 10 /* Unique symbol. */
+#define STB_HIOS 12 /* End of OS-specific */
+#define STB_LOPROC 13 /* Start of processor-specific */
+#define STB_HIPROC 15 /* End of processor-specific */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
+
+#define STT_NOTYPE 0 /* Symbol type is unspecified */
+#define STT_OBJECT 1 /* Symbol is a data object */
+#define STT_FUNC 2 /* Symbol is a code object */
+#define STT_SECTION 3 /* Symbol associated with a section */
+#define STT_FILE 4 /* Symbol's name is file name */
+#define STT_COMMON 5 /* Symbol is a common data object */
+#define STT_TLS 6 /* Symbol is thread-local data object*/
+#define STT_NUM 7 /* Number of defined types. */
+#define STT_LOOS 10 /* Start of OS-specific */
+#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */
+#define STT_HIOS 12 /* End of OS-specific */
+#define STT_LOPROC 13 /* Start of processor-specific */
+#define STT_HIPROC 15 /* End of processor-specific */
+
+
+/* Symbol table indices are found in the hash buckets and chain table
+ of a symbol hash table section. This special index value indicates
+ the end of a chain, meaning no further symbols are found in that bucket. */
+
+#define STN_UNDEF 0 /* End of a chain. */
+
+
+/* How to extract and insert information held in the st_other field. */
+
+#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
+
+/* For ELF64 the definitions are the same. */
+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
+
+/* Symbol visibility specification encoded in the st_other field. */
+#define STV_DEFAULT 0 /* Default symbol visibility rules */
+#define STV_INTERNAL 1 /* Processor specific hidden class */
+#define STV_HIDDEN 2 /* Sym unavailable in other modules */
+#define STV_PROTECTED 3 /* Not preemptible, not exported */
+
+
+/* Relocation table entry without addend (in section of type SHT_REL). */
+
+typedef struct
+{
+ Elf32_Addr r_offset; /* Address */
+ Elf32_Word r_info; /* Relocation type and symbol index */
+} Elf32_Rel;
+
+/* I have seen two different definitions of the Elf64_Rel and
+ Elf64_Rela structures, so we'll leave them out until Novell (or
+ whoever) gets their act together. */
+/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */
+
+typedef struct
+{
+ Elf64_Addr r_offset; /* Address */
+ Elf64_Xword r_info; /* Relocation type and symbol index */
+} Elf64_Rel;
+
+/* Relocation table entry with addend (in section of type SHT_RELA). */
+
+typedef struct
+{
+ Elf32_Addr r_offset; /* Address */
+ Elf32_Word r_info; /* Relocation type and symbol index */
+ Elf32_Sword r_addend; /* Addend */
+} Elf32_Rela;
+
+typedef struct
+{
+ Elf64_Addr r_offset; /* Address */
+ Elf64_Xword r_info; /* Relocation type and symbol index */
+ Elf64_Sxword r_addend; /* Addend */
+} Elf64_Rela;
+
+/* How to extract and insert information held in the r_info field. */
+
+#define ELF32_R_SYM(val) ((val) >> 8)
+#define ELF32_R_TYPE(val) ((val) & 0xff)
+#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i) ((i) >> 32)
+#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type))
+
+/* Program segment header. */
+
+typedef struct
+{
+ Elf32_Word p_type; /* Segment type */
+ Elf32_Off p_offset; /* Segment file offset */
+ Elf32_Addr p_vaddr; /* Segment virtual address */
+ Elf32_Addr p_paddr; /* Segment physical address */
+ Elf32_Word p_filesz; /* Segment size in file */
+ Elf32_Word p_memsz; /* Segment size in memory */
+ Elf32_Word p_flags; /* Segment flags */
+ Elf32_Word p_align; /* Segment alignment */
+} Elf32_Phdr;
+
+typedef struct
+{
+ Elf64_Word p_type; /* Segment type */
+ Elf64_Word p_flags; /* Segment flags */
+ Elf64_Off p_offset; /* Segment file offset */
+ Elf64_Addr p_vaddr; /* Segment virtual address */
+ Elf64_Addr p_paddr; /* Segment physical address */
+ Elf64_Xword p_filesz; /* Segment size in file */
+ Elf64_Xword p_memsz; /* Segment size in memory */
+ Elf64_Xword p_align; /* Segment alignment */
+} Elf64_Phdr;
+
+/* Special value for e_phnum. This indicates that the real number of
+ program headers is too large to fit into e_phnum. Instead the real
+ value is in the field sh_info of section 0. */
+
+#define PN_XNUM 0xffff
+
+/* Legal values for p_type (segment type). */
+
+#define PT_NULL 0 /* Program header table entry unused */
+#define PT_LOAD 1 /* Loadable program segment */
+#define PT_DYNAMIC 2 /* Dynamic linking information */
+#define PT_INTERP 3 /* Program interpreter */
+#define PT_NOTE 4 /* Auxiliary information */
+#define PT_SHLIB 5 /* Reserved */
+#define PT_PHDR 6 /* Entry for header table itself */
+#define PT_TLS 7 /* Thread-local storage segment */
+#define PT_NUM 8 /* Number of defined types */
+#define PT_LOOS 0x60000000 /* Start of OS-specific */
+#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
+#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
+#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
+#define PT_LOSUNW 0x6ffffffa
+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
+#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */
+#define PT_HISUNW 0x6fffffff
+#define PT_HIOS 0x6fffffff /* End of OS-specific */
+#define PT_LOPROC 0x70000000 /* Start of processor-specific */
+#define PT_HIPROC 0x7fffffff /* End of processor-specific */
+
+/* Legal values for p_flags (segment flags). */
+
+#define PF_X (1 << 0) /* Segment is executable */
+#define PF_W (1 << 1) /* Segment is writable */
+#define PF_R (1 << 2) /* Segment is readable */
+#define PF_MASKOS 0x0ff00000 /* OS-specific */
+#define PF_MASKPROC 0xf0000000 /* Processor-specific */
+
+/* Legal values for note segment descriptor types for core files. */
+
+#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
+#define NT_FPREGSET 2 /* Contains copy of fpregset struct */
+#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */
+#define NT_PRXREG 4 /* Contains copy of prxregset struct */
+#define NT_TASKSTRUCT 4 /* Contains copy of task structure */
+#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */
+#define NT_AUXV 6 /* Contains copy of auxv array */
+#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */
+#define NT_ASRS 8 /* Contains copy of asrset struct */
+#define NT_PSTATUS 10 /* Contains copy of pstatus struct */
+#define NT_PSINFO 13 /* Contains copy of psinfo struct */
+#define NT_PRCRED 14 /* Contains copy of prcred struct */
+#define NT_UTSNAME 15 /* Contains copy of utsname struct */
+#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */
+#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */
+#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */
+#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */
+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
+#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
+#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
+#define NT_S390_TIMER 0x301 /* s390 timer register */
+#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
+#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */
+#define NT_S390_CTRS 0x304 /* s390 control registers */
+#define NT_S390_PREFIX 0x305 /* s390 prefix register */
+#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
+#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
+#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
+#define NT_ARM_TLS 0x401 /* ARM TLS register */
+#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
+#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
+
+/* Legal values for the note segment descriptor types for object files. */
+
+#define NT_VERSION 1 /* Contains a version string. */
+
+
+/* Dynamic section entry. */
+
+typedef struct
+{
+ Elf32_Sword d_tag; /* Dynamic entry type */
+ union
+ {
+ Elf32_Word d_val; /* Integer value */
+ Elf32_Addr d_ptr; /* Address value */
+ } d_un;
+} Elf32_Dyn;
+
+typedef struct
+{
+ Elf64_Sxword d_tag; /* Dynamic entry type */
+ union
+ {
+ Elf64_Xword d_val; /* Integer value */
+ Elf64_Addr d_ptr; /* Address value */
+ } d_un;
+} Elf64_Dyn;
+
+/* Legal values for d_tag (dynamic entry type). */
+
+#define DT_NULL 0 /* Marks end of dynamic section */
+#define DT_NEEDED 1 /* Name of needed library */
+#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */
+#define DT_PLTGOT 3 /* Processor defined value */
+#define DT_HASH 4 /* Address of symbol hash table */
+#define DT_STRTAB 5 /* Address of string table */
+#define DT_SYMTAB 6 /* Address of symbol table */
+#define DT_RELA 7 /* Address of Rela relocs */
+#define DT_RELASZ 8 /* Total size of Rela relocs */
+#define DT_RELAENT 9 /* Size of one Rela reloc */
+#define DT_STRSZ 10 /* Size of string table */
+#define DT_SYMENT 11 /* Size of one symbol table entry */
+#define DT_INIT 12 /* Address of init function */
+#define DT_FINI 13 /* Address of termination function */
+#define DT_SONAME 14 /* Name of shared object */
+#define DT_RPATH 15 /* Library search path (deprecated) */
+#define DT_SYMBOLIC 16 /* Start symbol search here */
+#define DT_REL 17 /* Address of Rel relocs */
+#define DT_RELSZ 18 /* Total size of Rel relocs */
+#define DT_RELENT 19 /* Size of one Rel reloc */
+#define DT_PLTREL 20 /* Type of reloc in PLT */
+#define DT_DEBUG 21 /* For debugging; unspecified */
+#define DT_TEXTREL 22 /* Reloc might modify .text */
+#define DT_JMPREL 23 /* Address of PLT relocs */
+#define DT_BIND_NOW 24 /* Process relocations of object */
+#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
+#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
+#define DT_RUNPATH 29 /* Library search path */
+#define DT_FLAGS 30 /* Flags for the object being loaded */
+#define DT_ENCODING 32 /* Start of encoded range */
+#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
+#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
+#define DT_NUM 34 /* Number used */
+#define DT_LOOS 0x6000000d /* Start of OS-specific */
+#define DT_HIOS 0x6ffff000 /* End of OS-specific */
+#define DT_LOPROC 0x70000000 /* Start of processor-specific */
+#define DT_HIPROC 0x7fffffff /* End of processor-specific */
+#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */
+
+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+ Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's
+ approach. */
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */
+#define DT_CHECKSUM 0x6ffffdf8
+#define DT_PLTPADSZ 0x6ffffdf9
+#define DT_MOVEENT 0x6ffffdfa
+#define DT_MOVESZ 0x6ffffdfb
+#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */
+#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting
+ the following DT_* entry. */
+#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */
+#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */
+#define DT_VALRNGHI 0x6ffffdff
+#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */
+#define DT_VALNUM 12
+
+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+ Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+
+ If any adjustment is made to the ELF object after it has been
+ built these entries will need to be adjusted. */
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */
+#define DT_TLSDESC_PLT 0x6ffffef6
+#define DT_TLSDESC_GOT 0x6ffffef7
+#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */
+#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */
+#define DT_CONFIG 0x6ffffefa /* Configuration information. */
+#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */
+#define DT_AUDIT 0x6ffffefc /* Object auditing. */
+#define DT_PLTPAD 0x6ffffefd /* PLT padding. */
+#define DT_MOVETAB 0x6ffffefe /* Move table. */
+#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */
+#define DT_ADDRRNGHI 0x6ffffeff
+#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */
+#define DT_ADDRNUM 11
+
+/* The versioning entry types. The next are defined as part of the
+ GNU extension. */
+#define DT_VERSYM 0x6ffffff0
+
+#define DT_RELACOUNT 0x6ffffff9
+#define DT_RELCOUNT 0x6ffffffa
+
+/* These were chosen by Sun. */
+#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */
+#define DT_VERDEF 0x6ffffffc /* Address of version definition
+ table */
+#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */
+#define DT_VERNEED 0x6ffffffe /* Address of table with needed
+ versions */
+#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */
+#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
+#define DT_VERSIONTAGNUM 16
+
+/* Sun added these machine-independent extensions in the "processor-specific"
+ range. Be compatible. */
+#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */
+#define DT_FILTER 0x7fffffff /* Shared object to get values from */
+#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM 3
+
+/* Values of `d_un.d_val' in the DT_FLAGS entry. */
+#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */
+#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */
+#define DF_TEXTREL 0x00000004 /* Object contains text relocations */
+#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */
+#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */
+
+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
+ entry in the dynamic section. */
+#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */
+#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */
+#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */
+#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/
+#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/
+#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/
+#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */
+#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */
+#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */
+#define DF_1_TRANS 0x00000200
+#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */
+#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */
+#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */
+#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/
+#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */
+#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */
+#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */
+#define DF_1_NODIRECT 0x00020000 /* Object has no-direct binding. */
+#define DF_1_IGNMULDEF 0x00040000
+#define DF_1_NOKSYMS 0x00080000
+#define DF_1_NOHDR 0x00100000
+#define DF_1_EDITED 0x00200000 /* Object is modified after built. */
+#define DF_1_NORELOC 0x00400000
+#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */
+#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */
+#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */
+
+/* Flags for the feature selection in DT_FEATURE_1. */
+#define DTF_1_PARINIT 0x00000001
+#define DTF_1_CONFEXP 0x00000002
+
+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */
+#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */
+#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not
+ generally available. */
+
+/* Version definition sections. */
+
+typedef struct
+{
+ Elf32_Half vd_version; /* Version revision */
+ Elf32_Half vd_flags; /* Version information */
+ Elf32_Half vd_ndx; /* Version Index */
+ Elf32_Half vd_cnt; /* Number of associated aux entries */
+ Elf32_Word vd_hash; /* Version name hash value */
+ Elf32_Word vd_aux; /* Offset in bytes to verdaux array */
+ Elf32_Word vd_next; /* Offset in bytes to next verdef
+ entry */
+} Elf32_Verdef;
+
+typedef struct
+{
+ Elf64_Half vd_version; /* Version revision */
+ Elf64_Half vd_flags; /* Version information */
+ Elf64_Half vd_ndx; /* Version Index */
+ Elf64_Half vd_cnt; /* Number of associated aux entries */
+ Elf64_Word vd_hash; /* Version name hash value */
+ Elf64_Word vd_aux; /* Offset in bytes to verdaux array */
+ Elf64_Word vd_next; /* Offset in bytes to next verdef
+ entry */
+} Elf64_Verdef;
+
+
+/* Legal values for vd_version (version revision). */
+#define VER_DEF_NONE 0 /* No version */
+#define VER_DEF_CURRENT 1 /* Current version */
+#define VER_DEF_NUM 2 /* Given version number */
+
+/* Legal values for vd_flags (version information flags). */
+#define VER_FLG_BASE 0x1 /* Version definition of file itself */
+#define VER_FLG_WEAK 0x2 /* Weak version identifier */
+
+/* Versym symbol index values. */
+#define VER_NDX_LOCAL 0 /* Symbol is local. */
+#define VER_NDX_GLOBAL 1 /* Symbol is global. */
+#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */
+#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */
+
+/* Auxiliary version information. */
+
+typedef struct
+{
+ Elf32_Word vda_name; /* Version or dependency names */
+ Elf32_Word vda_next; /* Offset in bytes to next verdaux
+ entry */
+} Elf32_Verdaux;
+
+typedef struct
+{
+ Elf64_Word vda_name; /* Version or dependency names */
+ Elf64_Word vda_next; /* Offset in bytes to next verdaux
+ entry */
+} Elf64_Verdaux;
+
+
+/* Version dependency section. */
+
+typedef struct
+{
+ Elf32_Half vn_version; /* Version of structure */
+ Elf32_Half vn_cnt; /* Number of associated aux entries */
+ Elf32_Word vn_file; /* Offset of filename for this
+ dependency */
+ Elf32_Word vn_aux; /* Offset in bytes to vernaux array */
+ Elf32_Word vn_next; /* Offset in bytes to next verneed
+ entry */
+} Elf32_Verneed;
+
+typedef struct
+{
+ Elf64_Half vn_version; /* Version of structure */
+ Elf64_Half vn_cnt; /* Number of associated aux entries */
+ Elf64_Word vn_file; /* Offset of filename for this
+ dependency */
+ Elf64_Word vn_aux; /* Offset in bytes to vernaux array */
+ Elf64_Word vn_next; /* Offset in bytes to next verneed
+ entry */
+} Elf64_Verneed;
+
+
+/* Legal values for vn_version (version revision). */
+#define VER_NEED_NONE 0 /* No version */
+#define VER_NEED_CURRENT 1 /* Current version */
+#define VER_NEED_NUM 2 /* Given version number */
+
+/* Auxiliary needed version information. */
+
+typedef struct
+{
+ Elf32_Word vna_hash; /* Hash value of dependency name */
+ Elf32_Half vna_flags; /* Dependency specific information */
+ Elf32_Half vna_other; /* Unused */
+ Elf32_Word vna_name; /* Dependency name string offset */
+ Elf32_Word vna_next; /* Offset in bytes to next vernaux
+ entry */
+} Elf32_Vernaux;
+
+typedef struct
+{
+ Elf64_Word vna_hash; /* Hash value of dependency name */
+ Elf64_Half vna_flags; /* Dependency specific information */
+ Elf64_Half vna_other; /* Unused */
+ Elf64_Word vna_name; /* Dependency name string offset */
+ Elf64_Word vna_next; /* Offset in bytes to next vernaux
+ entry */
+} Elf64_Vernaux;
+
+
+/* Legal values for vna_flags. */
+#define VER_FLG_WEAK 0x2 /* Weak version identifier */
+
+
+/* Auxiliary vector. */
+
+/* This vector is normally only used by the program interpreter. The
+ usual definition in an ABI supplement uses the name auxv_t. The
+ vector is not usually defined in a standard <elf.h> file, but it
+ can't hurt. We rename it to avoid conflicts. The sizes of these
+ types are an arrangement between the exec server and the program
+ interpreter, so we don't fully specify them here. */
+
+typedef struct
+{
+ uint32_t a_type; /* Entry type */
+ union
+ {
+ uint32_t a_val; /* Integer value */
+ /* We use to have pointer elements added here. We cannot do that,
+ though, since it does not work when using 32-bit definitions
+ on 64-bit platforms and vice versa. */
+ } a_un;
+} Elf32_auxv_t;
+
+typedef struct
+{
+ uint64_t a_type; /* Entry type */
+ union
+ {
+ uint64_t a_val; /* Integer value */
+ /* We use to have pointer elements added here. We cannot do that,
+ though, since it does not work when using 32-bit definitions
+ on 64-bit platforms and vice versa. */
+ } a_un;
+} Elf64_auxv_t;
+
+/* Legal values for a_type (entry type). */
+
+#define AT_NULL 0 /* End of vector */
+#define AT_IGNORE 1 /* Entry should be ignored */
+#define AT_EXECFD 2 /* File descriptor of program */
+#define AT_PHDR 3 /* Program headers for program */
+#define AT_PHENT 4 /* Size of program header entry */
+#define AT_PHNUM 5 /* Number of program headers */
+#define AT_PAGESZ 6 /* System page size */
+#define AT_BASE 7 /* Base address of interpreter */
+#define AT_FLAGS 8 /* Flags */
+#define AT_ENTRY 9 /* Entry point of program */
+#define AT_NOTELF 10 /* Program is not ELF */
+#define AT_UID 11 /* Real uid */
+#define AT_EUID 12 /* Effective uid */
+#define AT_GID 13 /* Real gid */
+#define AT_EGID 14 /* Effective gid */
+#define AT_CLKTCK 17 /* Frequency of times() */
+
+/* Some more special a_type values describing the hardware. */
+#define AT_PLATFORM 15 /* String identifying platform. */
+#define AT_HWCAP 16 /* Machine dependent hints about
+ processor capabilities. */
+
+/* This entry gives some information about the FPU initialization
+ performed by the kernel. */
+#define AT_FPUCW 18 /* Used FPU control word. */
+
+/* Cache block sizes. */
+#define AT_DCACHEBSIZE 19 /* Data cache block size. */
+#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */
+#define AT_UCACHEBSIZE 21 /* Unified cache block size. */
+
+/* A special ignored value for PPC, used by the kernel to control the
+ interpretation of the AUXV. Must be > 16. */
+#define AT_IGNOREPPC 22 /* Entry should be ignored. */
+
+#define AT_SECURE 23 /* Boolean, was exec setuid-like? */
+
+#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/
+
+#define AT_RANDOM 25 /* Address of 16 random bytes. */
+
+#define AT_EXECFN 31 /* Filename of executable. */
+
+/* Pointer to the global system page used for system calls and other
+ nice things. */
+#define AT_SYSINFO 32
+#define AT_SYSINFO_EHDR 33
+
+/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains
+ log2 of line size; mask those to get cache size. */
+#define AT_L1I_CACHESHAPE 34
+#define AT_L1D_CACHESHAPE 35
+#define AT_L2_CACHESHAPE 36
+#define AT_L3_CACHESHAPE 37
+
+/* Note section contents. Each entry in the note section begins with
+ a header of a fixed form. */
+
+typedef struct
+{
+ Elf32_Word n_namesz; /* Length of the note's name. */
+ Elf32_Word n_descsz; /* Length of the note's descriptor. */
+ Elf32_Word n_type; /* Type of the note. */
+} Elf32_Nhdr;
+
+typedef struct
+{
+ Elf64_Word n_namesz; /* Length of the note's name. */
+ Elf64_Word n_descsz; /* Length of the note's descriptor. */
+ Elf64_Word n_type; /* Type of the note. */
+} Elf64_Nhdr;
+
+/* Known names of notes. */
+
+/* Solaris entries in the note section have this name. */
+#define ELF_NOTE_SOLARIS "SUNW Solaris"
+
+/* Note entries for GNU systems have this name. */
+#define ELF_NOTE_GNU "GNU"
+
+
+/* Defined types of notes for Solaris. */
+
+/* Value of descriptor (one word) is desired pagesize for the binary. */
+#define ELF_NOTE_PAGESIZE_HINT 1
+
+
+/* Defined note types for GNU systems. */
+
+/* ABI information. The descriptor consists of words:
+ word 0: OS descriptor
+ word 1: major version of the ABI
+ word 2: minor version of the ABI
+ word 3: subminor version of the ABI
+*/
+#define NT_GNU_ABI_TAG 1
+#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */
+
+/* Known OSes. These values can appear in word 0 of an
+ NT_GNU_ABI_TAG note section entry. */
+#define ELF_NOTE_OS_LINUX 0
+#define ELF_NOTE_OS_GNU 1
+#define ELF_NOTE_OS_SOLARIS2 2
+#define ELF_NOTE_OS_FREEBSD 3
+
+/* Synthetic hwcap information. The descriptor begins with two words:
+ word 0: number of entries
+ word 1: bitmask of enabled entries
+ Then follow variable-length entries, one byte followed by a
+ '\0'-terminated hwcap name string. The byte gives the bit
+ number to test if enabled, (1U << bit) & bitmask. */
+#define NT_GNU_HWCAP 2
+
+/* Build ID bits as generated by ld --build-id.
+ The descriptor consists of any nonzero number of bytes. */
+#define NT_GNU_BUILD_ID 3
+
+/* Version note generated by GNU gold containing a version string. */
+#define NT_GNU_GOLD_VERSION 4
+
+
+/* Move records. */
+typedef struct
+{
+ Elf32_Xword m_value; /* Symbol value. */
+ Elf32_Word m_info; /* Size and index. */
+ Elf32_Word m_poffset; /* Symbol offset. */
+ Elf32_Half m_repeat; /* Repeat count. */
+ Elf32_Half m_stride; /* Stride info. */
+} Elf32_Move;
+
+typedef struct
+{
+ Elf64_Xword m_value; /* Symbol value. */
+ Elf64_Xword m_info; /* Size and index. */
+ Elf64_Xword m_poffset; /* Symbol offset. */
+ Elf64_Half m_repeat; /* Repeat count. */
+ Elf64_Half m_stride; /* Stride info. */
+} Elf64_Move;
+
+/* Macro to construct move records. */
+#define ELF32_M_SYM(info) ((info) >> 8)
+#define ELF32_M_SIZE(info) ((unsigned char) (info))
+#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info) ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info) ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size)
+
+
+/* Motorola 68k specific definitions. */
+
+/* Values for Elf32_Ehdr.e_flags. */
+#define EF_CPU32 0x00810000
+
+/* m68k relocs. */
+
+#define R_68K_NONE 0 /* No reloc */
+#define R_68K_32 1 /* Direct 32 bit */
+#define R_68K_16 2 /* Direct 16 bit */
+#define R_68K_8 3 /* Direct 8 bit */
+#define R_68K_PC32 4 /* PC relative 32 bit */
+#define R_68K_PC16 5 /* PC relative 16 bit */
+#define R_68K_PC8 6 /* PC relative 8 bit */
+#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */
+#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */
+#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */
+#define R_68K_GOT32O 10 /* 32 bit GOT offset */
+#define R_68K_GOT16O 11 /* 16 bit GOT offset */
+#define R_68K_GOT8O 12 /* 8 bit GOT offset */
+#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */
+#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */
+#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */
+#define R_68K_PLT32O 16 /* 32 bit PLT offset */
+#define R_68K_PLT16O 17 /* 16 bit PLT offset */
+#define R_68K_PLT8O 18 /* 8 bit PLT offset */
+#define R_68K_COPY 19 /* Copy symbol at runtime */
+#define R_68K_GLOB_DAT 20 /* Create GOT entry */
+#define R_68K_JMP_SLOT 21 /* Create PLT entry */
+#define R_68K_RELATIVE 22 /* Adjust by program base */
+#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */
+#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */
+#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */
+#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */
+#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */
+#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */
+#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */
+#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */
+#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */
+#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */
+#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */
+#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */
+#define R_68K_TLS_LE32 37 /* 32 bit offset relative to
+ static TLS block */
+#define R_68K_TLS_LE16 38 /* 16 bit offset relative to
+ static TLS block */
+#define R_68K_TLS_LE8 39 /* 8 bit offset relative to
+ static TLS block */
+#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */
+#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */
+#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */
+/* Keep this the last entry. */
+#define R_68K_NUM 43
+
+/* Intel 80386 specific definitions. */
+
+/* i386 relocs. */
+
+#define R_386_NONE 0 /* No reloc */
+#define R_386_32 1 /* Direct 32 bit */
+#define R_386_PC32 2 /* PC relative 32 bit */
+#define R_386_GOT32 3 /* 32 bit GOT entry */
+#define R_386_PLT32 4 /* 32 bit PLT address */
+#define R_386_COPY 5 /* Copy symbol at runtime */
+#define R_386_GLOB_DAT 6 /* Create GOT entry */
+#define R_386_JMP_SLOT 7 /* Create PLT entry */
+#define R_386_RELATIVE 8 /* Adjust by program base */
+#define R_386_GOTOFF 9 /* 32 bit offset to GOT */
+#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */
+#define R_386_32PLT 11
+#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */
+#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS
+ block offset */
+#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block
+ offset */
+#define R_386_TLS_LE 17 /* Offset relative to static TLS
+ block */
+#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of
+ general dynamic thread local data */
+#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of
+ local dynamic thread local data
+ in LE code */
+#define R_386_16 20
+#define R_386_PC16 21
+#define R_386_8 22
+#define R_386_PC8 23
+#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic
+ thread local data */
+#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */
+#define R_386_TLS_GD_CALL 26 /* Relocation for call to
+ __tls_get_addr() */
+#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */
+#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic
+ thread local data in LE code */
+#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */
+#define R_386_TLS_LDM_CALL 30 /* Relocation for call to
+ __tls_get_addr() in LDM code */
+#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */
+#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */
+#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS
+ block offset */
+#define R_386_TLS_LE_32 34 /* Negated offset relative to static
+ TLS block */
+#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */
+#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */
+#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */
+/* 38? */
+#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */
+#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS
+ descriptor for
+ relaxation. */
+#define R_386_TLS_DESC 41 /* TLS descriptor containing
+ pointer to code and to
+ argument, returning the TLS
+ offset for the symbol. */
+#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */
+#define R_386_GOT32X 43 /* 32 bit GOT entry, relaxable */
+/* Keep this the last entry. */
+#define R_386_NUM 44
+
+/* SUN SPARC specific definitions. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
+
+#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */
+
+/* Values for Elf64_Ehdr.e_flags. */
+
+#define EF_SPARCV9_MM 3
+#define EF_SPARCV9_TSO 0
+#define EF_SPARCV9_PSO 1
+#define EF_SPARCV9_RMO 2
+#define EF_SPARC_LEDATA 0x800000 /* little endian data */
+#define EF_SPARC_EXT_MASK 0xFFFF00
+#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */
+#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */
+
+/* SPARC relocs. */
+
+#define R_SPARC_NONE 0 /* No reloc */
+#define R_SPARC_8 1 /* Direct 8 bit */
+#define R_SPARC_16 2 /* Direct 16 bit */
+#define R_SPARC_32 3 /* Direct 32 bit */
+#define R_SPARC_DISP8 4 /* PC relative 8 bit */
+#define R_SPARC_DISP16 5 /* PC relative 16 bit */
+#define R_SPARC_DISP32 6 /* PC relative 32 bit */
+#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */
+#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */
+#define R_SPARC_HI22 9 /* High 22 bit */
+#define R_SPARC_22 10 /* Direct 22 bit */
+#define R_SPARC_13 11 /* Direct 13 bit */
+#define R_SPARC_LO10 12 /* Truncated 10 bit */
+#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */
+#define R_SPARC_GOT13 14 /* 13 bit GOT entry */
+#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */
+#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */
+#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */
+#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */
+#define R_SPARC_COPY 19 /* Copy symbol at runtime */
+#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */
+#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */
+#define R_SPARC_RELATIVE 22 /* Adjust by program base */
+#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */
+
+/* Additional Sparc64 relocs. */
+
+#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */
+#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */
+#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */
+#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */
+#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */
+#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */
+#define R_SPARC_10 30 /* Direct 10 bit */
+#define R_SPARC_11 31 /* Direct 11 bit */
+#define R_SPARC_64 32 /* Direct 64 bit */
+#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */
+#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */
+#define R_SPARC_HM10 35 /* High middle 10 bits of ... */
+#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */
+#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */
+#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */
+#define R_SPARC_PC_LM22 39 /* Low middle 22 bits of ... */
+#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */
+#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */
+#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */
+#define R_SPARC_7 43 /* Direct 7 bit */
+#define R_SPARC_5 44 /* Direct 5 bit */
+#define R_SPARC_6 45 /* Direct 6 bit */
+#define R_SPARC_DISP64 46 /* PC relative 64 bit */
+#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */
+#define R_SPARC_HIX22 48 /* High 22 bit complemented */
+#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */
+#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */
+#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */
+#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */
+#define R_SPARC_REGISTER 53 /* Global register usage */
+#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */
+#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */
+#define R_SPARC_TLS_GD_HI22 56
+#define R_SPARC_TLS_GD_LO10 57
+#define R_SPARC_TLS_GD_ADD 58
+#define R_SPARC_TLS_GD_CALL 59
+#define R_SPARC_TLS_LDM_HI22 60
+#define R_SPARC_TLS_LDM_LO10 61
+#define R_SPARC_TLS_LDM_ADD 62
+#define R_SPARC_TLS_LDM_CALL 63
+#define R_SPARC_TLS_LDO_HIX22 64
+#define R_SPARC_TLS_LDO_LOX10 65
+#define R_SPARC_TLS_LDO_ADD 66
+#define R_SPARC_TLS_IE_HI22 67
+#define R_SPARC_TLS_IE_LO10 68
+#define R_SPARC_TLS_IE_LD 69
+#define R_SPARC_TLS_IE_LDX 70
+#define R_SPARC_TLS_IE_ADD 71
+#define R_SPARC_TLS_LE_HIX22 72
+#define R_SPARC_TLS_LE_LOX10 73
+#define R_SPARC_TLS_DTPMOD32 74
+#define R_SPARC_TLS_DTPMOD64 75
+#define R_SPARC_TLS_DTPOFF32 76
+#define R_SPARC_TLS_DTPOFF64 77
+#define R_SPARC_TLS_TPOFF32 78
+#define R_SPARC_TLS_TPOFF64 79
+#define R_SPARC_GOTDATA_HIX22 80
+#define R_SPARC_GOTDATA_LOX10 81
+#define R_SPARC_GOTDATA_OP_HIX22 82
+#define R_SPARC_GOTDATA_OP_LOX10 83
+#define R_SPARC_GOTDATA_OP 84
+#define R_SPARC_H34 85
+#define R_SPARC_SIZE32 86
+#define R_SPARC_SIZE64 87
+#define R_SPARC_WDISP10 88
+#define R_SPARC_JMP_IREL 248
+#define R_SPARC_IRELATIVE 249
+#define R_SPARC_GNU_VTINHERIT 250
+#define R_SPARC_GNU_VTENTRY 251
+#define R_SPARC_REV32 252
+/* Keep this the last entry. */
+#define R_SPARC_NUM 253
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn. */
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM 2
+
+/* MIPS R3000 specific definitions. */
+
+/* Legal values for e_flags field of Elf32_Ehdr. */
+
+#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */
+#define EF_MIPS_PIC 2 /* Contains PIC code */
+#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */
+#define EF_MIPS_XGOT 8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2 32
+#define EF_MIPS_ABI_ON32 64
+#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */
+
+/* Legal values for MIPS architecture level. */
+
+#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
+#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
+#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
+#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
+#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
+#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */
+#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */
+
+/* The following are non-official names and should not be used. */
+
+#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
+#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
+#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
+#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
+#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
+#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */
+#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */
+
+/* Special section indices. */
+
+#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */
+#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */
+#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */
+#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */
+#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */
+
+/* Legal values for sh_type field of Elf32_Shdr. */
+
+#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */
+#define SHT_MIPS_MSYM 0x70000001
+#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */
+#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */
+#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */
+#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/
+#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */
+#define SHT_MIPS_PACKAGE 0x70000007
+#define SHT_MIPS_PACKSYM 0x70000008
+#define SHT_MIPS_RELD 0x70000009
+#define SHT_MIPS_IFACE 0x7000000b
+#define SHT_MIPS_CONTENT 0x7000000c
+#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */
+#define SHT_MIPS_SHDR 0x70000010
+#define SHT_MIPS_FDESC 0x70000011
+#define SHT_MIPS_EXTSYM 0x70000012
+#define SHT_MIPS_DENSE 0x70000013
+#define SHT_MIPS_PDESC 0x70000014
+#define SHT_MIPS_LOCSYM 0x70000015
+#define SHT_MIPS_AUXSYM 0x70000016
+#define SHT_MIPS_OPTSYM 0x70000017
+#define SHT_MIPS_LOCSTR 0x70000018
+#define SHT_MIPS_LINE 0x70000019
+#define SHT_MIPS_RFDESC 0x7000001a
+#define SHT_MIPS_DELTASYM 0x7000001b
+#define SHT_MIPS_DELTAINST 0x7000001c
+#define SHT_MIPS_DELTACLASS 0x7000001d
+#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */
+#define SHT_MIPS_DELTADECL 0x7000001f
+#define SHT_MIPS_SYMBOL_LIB 0x70000020
+#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */
+#define SHT_MIPS_TRANSLATE 0x70000022
+#define SHT_MIPS_PIXIE 0x70000023
+#define SHT_MIPS_XLATE 0x70000024
+#define SHT_MIPS_XLATE_DEBUG 0x70000025
+#define SHT_MIPS_WHIRL 0x70000026
+#define SHT_MIPS_EH_REGION 0x70000027
+#define SHT_MIPS_XLATE_OLD 0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+/* Legal values for sh_flags field of Elf32_Shdr. */
+
+#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */
+#define SHF_MIPS_MERGE 0x20000000
+#define SHF_MIPS_ADDR 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL 0x04000000
+#define SHF_MIPS_NAMES 0x02000000
+#define SHF_MIPS_NODUPE 0x01000000
+
+
+/* Symbol tables. */
+
+/* MIPS specific values for `st_other'. */
+#define STO_MIPS_DEFAULT 0x0
+#define STO_MIPS_INTERNAL 0x1
+#define STO_MIPS_HIDDEN 0x2
+#define STO_MIPS_PROTECTED 0x3
+#define STO_MIPS_PLT 0x8
+#define STO_MIPS_SC_ALIGN_UNUSED 0xff
+
+/* MIPS specific values for `st_info'. */
+#define STB_MIPS_SPLIT_COMMON 13
+
+/* Entries found in sections of type SHT_MIPS_GPTAB. */
+
+typedef union
+{
+ struct
+ {
+ Elf32_Word gt_current_g_value; /* -G value used for compilation */
+ Elf32_Word gt_unused; /* Not used */
+ } gt_header; /* First entry in section */
+ struct
+ {
+ Elf32_Word gt_g_value; /* If this value were used for -G */
+ Elf32_Word gt_bytes; /* This many bytes would be used */
+ } gt_entry; /* Subsequent entries in section */
+} Elf32_gptab;
+
+/* Entry found in sections of type SHT_MIPS_REGINFO. */
+
+typedef struct
+{
+ Elf32_Word ri_gprmask; /* General registers used */
+ Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */
+ Elf32_Sword ri_gp_value; /* $gp register value */
+} Elf32_RegInfo;
+
+/* Entries found in sections of type SHT_MIPS_OPTIONS. */
+
+typedef struct
+{
+ unsigned char kind; /* Determines interpretation of the
+ variable part of descriptor. */
+ unsigned char size; /* Size of descriptor, including header. */
+ Elf32_Section section; /* Section header index of section affected,
+ 0 for global options. */
+ Elf32_Word info; /* Kind-specific information. */
+} Elf_Options;
+
+/* Values for `kind' field in Elf_Options. */
+
+#define ODK_NULL 0 /* Undefined. */
+#define ODK_REGINFO 1 /* Register usage information. */
+#define ODK_EXCEPTIONS 2 /* Exception processing options. */
+#define ODK_PAD 3 /* Section padding options. */
+#define ODK_HWPATCH 4 /* Hardware workarounds performed */
+#define ODK_FILL 5 /* record the fill value used by the linker. */
+#define ODK_TAGS 6 /* reserve space for desktop tools to write. */
+#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */
+#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */
+
+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */
+
+#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */
+#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */
+#define OEX_PAGE0 0x10000 /* page zero must be mapped. */
+#define OEX_SMM 0x20000 /* Force sequential memory mode? */
+#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */
+#define OEX_PRECISEFP OEX_FPDBUG
+#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */
+
+#define OEX_FPU_INVAL 0x10
+#define OEX_FPU_DIV0 0x08
+#define OEX_FPU_OFLO 0x04
+#define OEX_FPU_UFLO 0x02
+#define OEX_FPU_INEX 0x01
+
+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */
+
+#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */
+#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */
+#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */
+#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */
+
+#define OPAD_PREFIX 0x1
+#define OPAD_POSTFIX 0x2
+#define OPAD_SYMBOL 0x4
+
+/* Entry found in `.options' section. */
+
+typedef struct
+{
+ Elf32_Word hwp_flags1; /* Extra flags. */
+ Elf32_Word hwp_flags2; /* Extra flags. */
+} Elf_Options_Hw;
+
+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */
+
+#define OHWA0_R4KEOP_CHECKED 0x00000001
+#define OHWA1_R4KEOP_CLEAN 0x00000002
+
+/* MIPS relocs. */
+
+#define R_MIPS_NONE 0 /* No reloc */
+#define R_MIPS_16 1 /* Direct 16 bit */
+#define R_MIPS_32 2 /* Direct 32 bit */
+#define R_MIPS_REL32 3 /* PC relative 32 bit */
+#define R_MIPS_26 4 /* Direct 26 bit shifted */
+#define R_MIPS_HI16 5 /* High 16 bit */
+#define R_MIPS_LO16 6 /* Low 16 bit */
+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
+#define R_MIPS_PC16 10 /* PC relative 16 bit */
+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
+
+#define R_MIPS_SHIFT5 16
+#define R_MIPS_SHIFT6 17
+#define R_MIPS_64 18
+#define R_MIPS_GOT_DISP 19
+#define R_MIPS_GOT_PAGE 20
+#define R_MIPS_GOT_OFST 21
+#define R_MIPS_GOT_HI16 22
+#define R_MIPS_GOT_LO16 23
+#define R_MIPS_SUB 24
+#define R_MIPS_INSERT_A 25
+#define R_MIPS_INSERT_B 26
+#define R_MIPS_DELETE 27
+#define R_MIPS_HIGHER 28
+#define R_MIPS_HIGHEST 29
+#define R_MIPS_CALL_HI16 30
+#define R_MIPS_CALL_LO16 31
+#define R_MIPS_SCN_DISP 32
+#define R_MIPS_REL16 33
+#define R_MIPS_ADD_IMMEDIATE 34
+#define R_MIPS_PJUMP 35
+#define R_MIPS_RELGOT 36
+#define R_MIPS_JALR 37
+#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */
+#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */
+#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */
+#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */
+#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */
+#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */
+#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */
+#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */
+#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */
+#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */
+#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */
+#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */
+#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */
+#define R_MIPS_GLOB_DAT 51
+#define R_MIPS_COPY 126
+#define R_MIPS_JUMP_SLOT 127
+/* Keep this the last entry. */
+#define R_MIPS_NUM 128
+
+/* Legal values for p_type field of Elf32_Phdr. */
+
+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
+#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Special program header types. */
+
+#define PF_MIPS_LOCAL 0x10000000
+
+/* Legal values for d_tag field of Elf32_Dyn. */
+
+#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */
+#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */
+#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */
+#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */
+#define DT_MIPS_FLAGS 0x70000005 /* Flags */
+#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */
+#define DT_MIPS_MSYM 0x70000007
+#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */
+#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */
+#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */
+#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */
+#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */
+#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */
+#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */
+#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */
+#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */
+#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */
+#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in
+ DT_MIPS_DELTA_CLASS. */
+#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
+ DT_MIPS_DELTA_INSTANCE. */
+#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
+ DT_MIPS_DELTA_RELOC. */
+#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta
+ relocations refer to. */
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
+ DT_MIPS_DELTA_SYM. */
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
+ class declaration. */
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
+ DT_MIPS_DELTA_CLASSSYM. */
+#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */
+#define DT_MIPS_PIXIE_INIT 0x70000023
+#define DT_MIPS_SYMBOL_LIB 0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */
+#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
+ function stored in GOT. */
+#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added
+ by rld on dlopen() calls. */
+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
+#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */
+#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */
+/* The address of .got.plt in an executable using the new non-PIC ABI. */
+#define DT_MIPS_PLTGOT 0x70000032
+/* The base of the PLT in an executable using the new non-PIC ABI if that
+ PLT is writable. For a non-writable PLT, this is omitted or has a zero
+ value. */
+#define DT_MIPS_RWPLT 0x70000034
+#define DT_MIPS_NUM 0x35
+
+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */
+
+#define RHF_NONE 0 /* No flags */
+#define RHF_QUICKSTART (1 << 0) /* Use quickstart */
+#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */
+#define RHF_NO_MOVE (1 << 3)
+#define RHF_SGI_ONLY (1 << 4)
+#define RHF_GUARANTEE_INIT (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS (1 << 6)
+#define RHF_GUARANTEE_START_INIT (1 << 7)
+#define RHF_PIXIE (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD (1 << 9)
+#define RHF_REQUICKSTART (1 << 10)
+#define RHF_REQUICKSTARTED (1 << 11)
+#define RHF_CORD (1 << 12)
+#define RHF_NO_UNRES_UNDEF (1 << 13)
+#define RHF_RLD_ORDER_SAFE (1 << 14)
+
+/* Entries found in sections of type SHT_MIPS_LIBLIST. */
+
+typedef struct
+{
+ Elf32_Word l_name; /* Name (string table index) */
+ Elf32_Word l_time_stamp; /* Timestamp */
+ Elf32_Word l_checksum; /* Checksum */
+ Elf32_Word l_version; /* Interface version */
+ Elf32_Word l_flags; /* Flags */
+} Elf32_Lib;
+
+typedef struct
+{
+ Elf64_Word l_name; /* Name (string table index) */
+ Elf64_Word l_time_stamp; /* Timestamp */
+ Elf64_Word l_checksum; /* Checksum */
+ Elf64_Word l_version; /* Interface version */
+ Elf64_Word l_flags; /* Flags */
+} Elf64_Lib;
+
+
+/* Legal values for l_flags. */
+
+#define LL_NONE 0
+#define LL_EXACT_MATCH (1 << 0) /* Require exact match */
+#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */
+#define LL_REQUIRE_MINOR (1 << 2)
+#define LL_EXPORTS (1 << 3)
+#define LL_DELAY_LOAD (1 << 4)
+#define LL_DELTA (1 << 5)
+
+/* Entries found in sections of type SHT_MIPS_CONFLICT. */
+
+typedef Elf32_Addr Elf32_Conflict;
+
+
+/* HPPA specific definitions. */
+
+/* Legal values for e_flags field of Elf32_Ehdr. */
+
+#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */
+#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */
+#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */
+#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */
+#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch
+ prediction. */
+#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */
+#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */
+
+/* Defined values for `e_flags & EF_PARISC_ARCH' are: */
+
+#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */
+#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */
+#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */
+
+/* Additional section indices. */
+
+#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tentatively declared
+ symbols in ANSI C. */
+#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */
+
+/* Legal values for sh_type field of Elf32_Shdr. */
+
+#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */
+#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */
+#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */
+
+/* Legal values for sh_flags field of Elf32_Shdr. */
+
+#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */
+#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */
+#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
+
+#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */
+
+#define STT_HP_OPAQUE (STT_LOOS + 0x1)
+#define STT_HP_STUB (STT_LOOS + 0x2)
+
+/* HPPA relocs. */
+
+#define R_PARISC_NONE 0 /* No reloc. */
+#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */
+#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */
+#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */
+#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */
+#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */
+#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */
+#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */
+#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */
+#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */
+#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */
+#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */
+#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */
+#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */
+#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */
+#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */
+#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */
+#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */
+#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */
+#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */
+#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */
+#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */
+#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */
+#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */
+#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */
+#define R_PARISC_FPTR64 64 /* 64 bits function address. */
+#define R_PARISC_PLABEL32 65 /* 32 bits function address. */
+#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */
+#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */
+#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */
+#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */
+#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */
+#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */
+#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */
+#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */
+#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */
+#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */
+#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */
+#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */
+#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */
+#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */
+#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */
+#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */
+#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */
+#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */
+#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */
+#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */
+#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */
+#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */
+#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */
+#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */
+#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */
+#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */
+#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */
+#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */
+#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */
+#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */
+#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */
+#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */
+#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */
+#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */
+#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */
+#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */
+#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */
+#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */
+#define R_PARISC_LORESERVE 128
+#define R_PARISC_COPY 128 /* Copy relocation. */
+#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */
+#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */
+#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */
+#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */
+#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */
+#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */
+#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */
+#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */
+#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */
+#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */
+#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */
+#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */
+#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */
+#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */
+#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */
+#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */
+#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */
+#define R_PARISC_GNU_VTENTRY 232
+#define R_PARISC_GNU_VTINHERIT 233
+#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */
+#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */
+#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */
+#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */
+#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */
+#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */
+#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */
+#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */
+#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */
+#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */
+#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */
+#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */
+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64
+#define R_PARISC_HIRESERVE 255
+
+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
+
+#define PT_HP_TLS (PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE (PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION (PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM (PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC (PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK (PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM (PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF (PT_LOOS + 0x9)
+#define PT_HP_PARALLEL (PT_LOOS + 0x10)
+#define PT_HP_FASTBIND (PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13)
+#define PT_HP_STACK (PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT 0x70000000
+#define PT_PARISC_UNWIND 0x70000001
+
+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */
+
+#define PF_PARISC_SBP 0x08000000
+
+#define PF_HP_PAGE_SIZE 0x00100000
+#define PF_HP_FAR_SHARED 0x00200000
+#define PF_HP_NEAR_SHARED 0x00400000
+#define PF_HP_CODE 0x01000000
+#define PF_HP_MODIFY 0x02000000
+#define PF_HP_LAZYSWAP 0x04000000
+#define PF_HP_SBP 0x08000000
+
+
+/* Alpha specific definitions. */
+
+/* Legal values for e_flags field of Elf64_Ehdr. */
+
+#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */
+#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */
+
+/* Legal values for sh_type field of Elf64_Shdr. */
+
+/* These two are primarily concerned with ECOFF debugging info. */
+#define SHT_ALPHA_DEBUG 0x70000001
+#define SHT_ALPHA_REGINFO 0x70000002
+
+/* Legal values for sh_flags field of Elf64_Shdr. */
+
+#define SHF_ALPHA_GPREL 0x10000000
+
+/* Legal values for st_other field of Elf64_Sym. */
+#define STO_ALPHA_NOPV 0x80 /* No PV required. */
+#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */
+
+/* Alpha relocs. */
+
+#define R_ALPHA_NONE 0 /* No reloc */
+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
+#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */
+#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */
+#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */
+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
+#define R_ALPHA_TLS_GD_HI 28
+#define R_ALPHA_TLSGD 29
+#define R_ALPHA_TLS_LDM 30
+#define R_ALPHA_DTPMOD64 31
+#define R_ALPHA_GOTDTPREL 32
+#define R_ALPHA_DTPREL64 33
+#define R_ALPHA_DTPRELHI 34
+#define R_ALPHA_DTPRELLO 35
+#define R_ALPHA_DTPREL16 36
+#define R_ALPHA_GOTTPREL 37
+#define R_ALPHA_TPREL64 38
+#define R_ALPHA_TPRELHI 39
+#define R_ALPHA_TPRELLO 40
+#define R_ALPHA_TPREL16 41
+/* Keep this the last entry. */
+#define R_ALPHA_NUM 46
+
+/* Magic values of the LITUSE relocation addend. */
+#define LITUSE_ALPHA_ADDR 0
+#define LITUSE_ALPHA_BASE 1
+#define LITUSE_ALPHA_BYTOFF 2
+#define LITUSE_ALPHA_JSR 3
+#define LITUSE_ALPHA_TLS_GD 4
+#define LITUSE_ALPHA_TLS_LDM 5
+
+/* Legal values for d_tag of Elf64_Dyn. */
+#define DT_ALPHA_PLTRO (DT_LOPROC + 0)
+#define DT_ALPHA_NUM 1
+
+/* PowerPC specific declarations */
+
+/* Values for Elf32/64_Ehdr.e_flags. */
+#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
+
+/* Cygnus local bits below */
+#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
+#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
+ flag */
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE 0
+#define R_PPC_ADDR32 1 /* 32bit absolute address */
+#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
+#define R_PPC_ADDR16 3 /* 16bit absolute address */
+#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
+#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10 /* PC relative 26 bit */
+#define R_PPC_REL14 11 /* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+
+/* PowerPC relocations defined for the TLS access ABI. */
+#define R_PPC_TLS 67 /* none (sym+add)@tls */
+#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */
+#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */
+#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
+#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
+#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
+#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */
+#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */
+#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
+#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
+#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
+#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */
+#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
+#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
+#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
+#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
+#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
+#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
+#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
+#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
+#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */
+#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */
+#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
+#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
+#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */
+#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */
+#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
+#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+ in the SVR4 ELF ABI. */
+#define R_PPC_EMB_NADDR32 101
+#define R_PPC_EMB_NADDR16 102
+#define R_PPC_EMB_NADDR16_LO 103
+#define R_PPC_EMB_NADDR16_HI 104
+#define R_PPC_EMB_NADDR16_HA 105
+#define R_PPC_EMB_SDAI16 106
+#define R_PPC_EMB_SDA2I16 107
+#define R_PPC_EMB_SDA2REL 108
+#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
+#define R_PPC_EMB_MRKREF 110
+#define R_PPC_EMB_RELSEC16 111
+#define R_PPC_EMB_RELST_LO 112
+#define R_PPC_EMB_RELST_HI 113
+#define R_PPC_EMB_RELST_HA 114
+#define R_PPC_EMB_BIT_FLD 115
+#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
+
+/* Diab tool relocations. */
+#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
+#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
+#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
+#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
+#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
+#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
+
+/* GNU extension to support local ifunc. */
+#define R_PPC_IRELATIVE 248
+
+/* GNU relocs used in PIC code sequences. */
+#define R_PPC_REL16 249 /* half16 (sym+add-.) */
+#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */
+#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */
+#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+ that may still be in object files. */
+#define R_PPC_TOC16 255
+
+/* PowerPC specific values for the Dyn d_tag field. */
+#define DT_PPC_GOT (DT_LOPROC + 0)
+#define DT_PPC_NUM 1
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE R_PPC_NONE
+#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */
+#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */
+#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */
+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */
+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */
+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */
+#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */
+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
+#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */
+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16 R_PPC_GOT16
+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA
+
+#define R_PPC64_COPY R_PPC_COPY
+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32 R_PPC_UADDR32
+#define R_PPC64_UADDR16 R_PPC_UADDR16
+#define R_PPC64_REL32 R_PPC_REL32
+#define R_PPC64_PLT32 R_PPC_PLT32
+#define R_PPC64_PLTREL32 R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */
+#define R_PPC64_ADDR64 38 /* doubleword64 S + A */
+#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */
+#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */
+#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */
+#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */
+#define R_PPC64_UADDR64 43 /* doubleword64 S + A */
+#define R_PPC64_REL64 44 /* doubleword64 S + A - P */
+#define R_PPC64_PLT64 45 /* doubleword64 L + A */
+#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */
+#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */
+#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */
+#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */
+#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */
+#define R_PPC64_TOC 51 /* doubleword64 .TOC */
+#define R_PPC64_PLTGOT16 52 /* half16* M + A */
+#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */
+#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */
+#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */
+
+#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */
+#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */
+#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */
+#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */
+#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */
+#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */
+#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */
+#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */
+#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */
+#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */
+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */
+
+/* PowerPC64 relocations defined for the TLS access ABI. */
+#define R_PPC64_TLS 67 /* none (sym+add)@tls */
+#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */
+#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */
+#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
+#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
+#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */
+#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
+#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
+#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */
+#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
+#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
+#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
+#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
+#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
+#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
+#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
+#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
+#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */
+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
+#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
+#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
+#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */
+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
+#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */
+#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */
+#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */
+#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */
+#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */
+#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */
+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */
+#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */
+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */
+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */
+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */
+
+/* GNU extension to support local ifunc. */
+#define R_PPC64_JMP_IREL 247
+#define R_PPC64_IRELATIVE 248
+#define R_PPC64_REL16 249 /* half16 (sym+add-.) */
+#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */
+#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */
+#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */
+
+/* PowerPC64 specific values for the Dyn d_tag field. */
+#define DT_PPC64_GLINK (DT_LOPROC + 0)
+#define DT_PPC64_OPD (DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
+#define DT_PPC64_NUM 3
+
+
+/* ARM specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field. */
+#define EF_ARM_RELEXEC 0x01
+#define EF_ARM_HASENTRY 0x02
+#define EF_ARM_INTERWORK 0x04
+#define EF_ARM_APCS_26 0x08
+#define EF_ARM_APCS_FLOAT 0x10
+#define EF_ARM_PIC 0x20
+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI 0x80
+#define EF_ARM_OLD_ABI 0x100
+#define EF_ARM_SOFT_FLOAT 0x200
+#define EF_ARM_VFP_FLOAT 0x400
+#define EF_ARM_MAVERICK_FLOAT 0x800
+
+#define EF_ARM_ABI_FLOAT_SOFT 0x200 /* NB conflicts with EF_ARM_SOFT_FLOAT */
+#define EF_ARM_ABI_FLOAT_HARD 0x400 /* NB conflicts with EF_ARM_VFP_FLOAT */
+
+
+/* Other constants defined in the ARM ELF spec. version B-01. */
+/* NB. These conflict with values defined above. */
+#define EF_ARM_SYMSARESORTED 0x04
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
+#define EF_ARM_MAPSYMSFIRST 0x10
+#define EF_ARM_EABIMASK 0XFF000000
+
+/* Constants defined in AAELF. */
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_LE8 0x00400000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
+
+/* Additional symbol types for Thumb. */
+#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */
+#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */
+
+/* ARM-specific values for sh_flags */
+#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
+#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
+ in the input to a link step. */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB 0x10000000 /* Segment contains the location
+ addressed by the static base. */
+#define PF_ARM_PI 0x20000000 /* Position-independent segment. */
+#define PF_ARM_ABS 0x40000000 /* Absolute segment. */
+
+/* Processor specific values for the Phdr p_type field. */
+#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */
+
+/* Processor specific values for the Shdr sh_type field. */
+#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */
+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */
+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */
+
+
+/* AArch64 relocs. */
+
+#define R_AARCH64_NONE 0 /* No relocation. */
+#define R_AARCH64_ABS64 257 /* Direct 64 bit. */
+#define R_AARCH64_ABS32 258 /* Direct 32 bit. */
+#define R_AARCH64_ABS16 259 /* Direct 16-bit. */
+#define R_AARCH64_PREL64 260 /* PC-relative 64-bit. */
+#define R_AARCH64_PREL32 261 /* PC-relative 32-bit. */
+#define R_AARCH64_PREL16 262 /* PC-relative 16-bit. */
+#define R_AARCH64_MOVW_UABS_G0 263 /* Dir. MOVZ imm. from bits 15:0. */
+#define R_AARCH64_MOVW_UABS_G0_NC 264 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_UABS_G1 265 /* Dir. MOVZ imm. from bits 31:16. */
+#define R_AARCH64_MOVW_UABS_G1_NC 266 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_UABS_G2 267 /* Dir. MOVZ imm. from bits 47:32. */
+#define R_AARCH64_MOVW_UABS_G2_NC 268 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_UABS_G3 269 /* Dir. MOV{K,Z} imm. from 63:48. */
+#define R_AARCH64_MOVW_SABS_G0 270 /* Dir. MOV{N,Z} imm. from 15:0. */
+#define R_AARCH64_MOVW_SABS_G1 271 /* Dir. MOV{N,Z} imm. from 31:16. */
+#define R_AARCH64_MOVW_SABS_G2 272 /* Dir. MOV{N,Z} imm. from 47:32. */
+#define R_AARCH64_LD_PREL_LO19 273 /* PC-rel. LD imm. from bits 20:2. */
+#define R_AARCH64_ADR_PREL_LO21 274 /* PC-rel. ADR imm. from bits 20:0. */
+#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page-rel. ADRP imm. from 32:12. */
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check. */
+#define R_AARCH64_ADD_ABS_LO12_NC 277 /* Dir. ADD imm. from bits 11:0. */
+#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* Likewise for LD/ST; no check. */
+#define R_AARCH64_TSTBR14 279 /* PC-rel. TBZ/TBNZ imm. from 15:2. */
+#define R_AARCH64_CONDBR19 280 /* PC-rel. cond. br. imm. from 20:2. */
+#define R_AARCH64_JUMP26 282 /* PC-rel. B imm. from bits 27:2. */
+#define R_AARCH64_CALL26 283 /* Likewise for CALL. */
+#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1. */
+#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2. */
+#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3. */
+#define R_AARCH64_MOVW_PREL_G0 287 /* PC-rel. MOV{N,Z} imm. from 15:0. */
+#define R_AARCH64_MOVW_PREL_G0_NC 288 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_PREL_G1 289 /* PC-rel. MOV{N,Z} imm. from 31:16. */
+#define R_AARCH64_MOVW_PREL_G1_NC 290 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_PREL_G2 291 /* PC-rel. MOV{N,Z} imm. from 47:32. */
+#define R_AARCH64_MOVW_PREL_G2_NC 292 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_PREL_G3 293 /* PC-rel. MOV{N,Z} imm. from 63:48. */
+#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4. */
+#define R_AARCH64_MOVW_GOTOFF_G0 300 /* GOT-rel. off. MOV{N,Z} imm. 15:0. */
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_GOTOFF_G1 302 /* GOT-rel. o. MOV{N,Z} imm. 31:16. */
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_GOTOFF_G2 304 /* GOT-rel. o. MOV{N,Z} imm. 47:32. */
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_GOTOFF_G3 306 /* GOT-rel. o. MOV{N,Z} imm. 63:48. */
+#define R_AARCH64_GOTREL64 307 /* GOT-relative 64-bit. */
+#define R_AARCH64_GOTREL32 308 /* GOT-relative 32-bit. */
+#define R_AARCH64_GOT_LD_PREL19 309 /* PC-rel. GOT off. load imm. 20:2. */
+#define R_AARCH64_LD64_GOTOFF_LO15 310 /* GOT-rel. off. LD/ST imm. 14:3. */
+#define R_AARCH64_ADR_GOT_PAGE 311 /* P-page-rel. GOT off. ADRP 32:12. */
+#define R_AARCH64_LD64_GOT_LO12_NC 312 /* Dir. GOT off. LD/ST imm. 11:3. */
+#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* GOT-page-rel. GOT off. LD/ST 14:3 */
+#define R_AARCH64_TLSGD_ADR_PREL21 512 /* PC-relative ADR imm. 20:0. */
+#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* page-rel. ADRP imm. 32:12. */
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* direct ADD imm. from 11:0. */
+#define R_AARCH64_TLSGD_MOVW_G1 515 /* GOT-rel. MOV{N,Z} 31:16. */
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* GOT-rel. MOVK imm. 15:0. */
+#define R_AARCH64_TLSLD_ADR_PREL21 517 /* Like 512; local dynamic model. */
+#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Like 513; local dynamic model. */
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* Like 514; local dynamic model. */
+#define R_AARCH64_TLSLD_MOVW_G1 520 /* Like 515; local dynamic model. */
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* Like 516; local dynamic model. */
+#define R_AARCH64_TLSLD_LD_PREL19 522 /* TLS PC-rel. load imm. 20:2. */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32. */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16. */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check. */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0. */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check. */
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0. */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check. */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0. */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check. */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1. */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check. */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2. */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check. */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3. */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check. */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16. */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0. */
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12. */
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3. */
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2. */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32. */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16. */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check. */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0. */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check. */
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12. */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0. */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check. */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0. */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1. */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check. */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2. */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check. */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3. */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check. */
+#define R_AARCH64_TLSDESC_LD_PREL19 560 /* PC-rel. load immediate 20:2. */
+#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0. */
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12. */
+#define R_AARCH64_TLSDESC_LD64_LO12 563 /* Direct LD off. from 11:3. */
+#define R_AARCH64_TLSDESC_ADD_LO12 564 /* Direct ADD imm. from 11:0. */
+#define R_AARCH64_TLSDESC_OFF_G1 565 /* GOT-rel. MOV{N,Z} imm. 31:16. */
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566 /* GOT-rel. MOVK imm. 15:0; no ck. */
+#define R_AARCH64_TLSDESC_LDR 567 /* Relax LDR. */
+#define R_AARCH64_TLSDESC_ADD 568 /* Relax ADD. */
+#define R_AARCH64_TLSDESC_CALL 569 /* Relax BLR. */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4. */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check. */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check. */
+#define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */
+#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */
+#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */
+#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */
+#define R_AARCH64_TLS_DTPMOD64 1028 /* Module number, 64 bit. */
+#define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */
+#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */
+#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */
+#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */
+/* Keep this the last entry. */
+#define R_AARCH64_NUM 1033
+
+/* ARM relocs. */
+
+#define R_ARM_NONE 0 /* No reloc */
+#define R_ARM_PC24 1 /* PC relative 26 bit branch */
+#define R_ARM_ABS32 2 /* Direct 32 bit */
+#define R_ARM_REL32 3 /* PC relative 32 bit */
+#define R_ARM_PC13 4
+#define R_ARM_ABS16 5 /* Direct 16 bit */
+#define R_ARM_ABS12 6 /* Direct 12 bit */
+#define R_ARM_THM_ABS5 7
+#define R_ARM_ABS8 8 /* Direct 8 bit */
+#define R_ARM_SBREL32 9
+#define R_ARM_THM_PC22 10
+#define R_ARM_THM_PC8 11
+#define R_ARM_AMP_VCALL9 12
+#define R_ARM_SWI24 13 /* Obsolete static relocation. */
+#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */
+#define R_ARM_THM_SWI8 14
+#define R_ARM_XPC25 15
+#define R_ARM_THM_XPC22 16
+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
+#define R_ARM_COPY 20 /* Copy symbol at runtime */
+#define R_ARM_GLOB_DAT 21 /* Create GOT entry */
+#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */
+#define R_ARM_RELATIVE 23 /* Adjust by program base */
+#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */
+#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */
+#define R_ARM_GOT32 26 /* 32 bit GOT entry */
+#define R_ARM_PLT32 27 /* 32 bit PLT address */
+#define R_ARM_CALL 28
+#define R_ARM_JUMP24 29
+#define R_ARM_THM_JUMP24 30
+#define R_ARM_ALU_PCREL_7_0 32
+#define R_ARM_ALU_PCREL_15_8 33
+#define R_ARM_ALU_PCREL_23_15 34
+#define R_ARM_LDR_SBREL_11_0 35
+#define R_ARM_ALU_SBREL_19_12 36
+#define R_ARM_ALU_SBREL_27_20 37
+#define R_ARM_V4BX 40
+#define R_ARM_PREL31 42
+#define R_ARM_MOVW_ABS_NC 43
+#define R_ARM_MOVT_ABS 44
+#define R_ARM_THM_MOVW_ABS_NC 47
+#define R_ARM_THM_MOVT_ABS 48
+#define R_ARM_TLS_GOTDESC 90
+#define R_ARM_TLS_CALL 91
+#define R_ARM_TLS_DESCSEQ 92
+#define R_ARM_THM_TLS_CALL 93
+#define R_ARM_GNU_VTENTRY 100
+#define R_ARM_GNU_VTINHERIT 101
+#define R_ARM_THM_PC11 102 /* thumb unconditional branch */
+#define R_ARM_THM_PC9 103 /* thumb conditional branch */
+#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic
+ thread local data */
+#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic
+ thread local data */
+#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS
+ block */
+#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of
+ static TLS block offset */
+#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static
+ TLS block */
+#define R_ARM_THM_TLS_DESCSEQ 129
+#define R_ARM_IRELATIVE 160
+#define R_ARM_RXPC25 249
+#define R_ARM_RSBREL32 250
+#define R_ARM_THM_RPC22 251
+#define R_ARM_RREL32 252
+#define R_ARM_RABS22 253
+#define R_ARM_RPC24 254
+#define R_ARM_RBASE 255
+/* Keep this the last entry. */
+#define R_ARM_NUM 256
+
+/* TMS320C67xx specific declarations */
+
+/* XXX: no ELF standard yet*/
+
+/* TMS320C67xx relocs. */
+#define R_C60_32 1
+#define R_C60_GOT32 3 /* 32 bit GOT entry */
+#define R_C60_PLT32 4 /* 32 bit PLT address */
+#define R_C60_COPY 5 /* Copy symbol at runtime */
+#define R_C60_GLOB_DAT 6 /* Create GOT entry */
+#define R_C60_JMP_SLOT 7 /* Create PLT entry */
+#define R_C60_RELATIVE 8 /* Adjust by program base */
+#define R_C60_GOTOFF 9 /* 32 bit offset to GOT */
+#define R_C60_GOTPC 10 /* 32 bit PC relative offset to GOT */
+
+#define R_C60LO16 0x54 /* low 16 bit MVKL embedded */
+#define R_C60HI16 0x55 /* high 16 bit MVKH embedded */
+/* Keep this the last entry. */
+#define R_C60_NUM 0x56
+
+/* IA-64 specific declarations. */
+
+/* Processor specific flags for the Ehdr e_flags field. */
+#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */
+#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */
+#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */
+
+/* Processor specific values for the Phdr p_type field. */
+#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */
+#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */
+#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK (PT_LOOS + 0x14)
+
+/* Processor specific flags for the Phdr p_flags field. */
+#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */
+
+/* Processor specific values for the Shdr sh_type field. */
+#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */
+#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */
+
+/* Processor specific flags for the Shdr sh_flags field. */
+#define SHF_IA_64_SHORT 0x10000000 /* section near gp */
+#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */
+
+/* Processor specific values for the Dyn d_tag field. */
+#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0)
+#define DT_IA_64_NUM 1
+
+/* IA-64 relocations. */
+#define R_IA64_NONE 0x00 /* none */
+#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */
+#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */
+#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */
+#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */
+#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */
+#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */
+#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */
+#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */
+#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */
+#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */
+#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */
+#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */
+#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */
+#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */
+#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */
+#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */
+#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */
+#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */
+#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */
+#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */
+#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */
+#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */
+#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */
+#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */
+#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */
+#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */
+#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */
+#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */
+#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */
+#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */
+#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */
+#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */
+#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */
+#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */
+#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */
+#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */
+#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */
+#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */
+#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */
+#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */
+#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */
+#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */
+#define R_IA64_REL32MSB 0x6c /* data 4 + REL */
+#define R_IA64_REL32LSB 0x6d /* data 4 + REL */
+#define R_IA64_REL64MSB 0x6e /* data 8 + REL */
+#define R_IA64_REL64LSB 0x6f /* data 8 + REL */
+#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */
+#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */
+#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */
+#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */
+#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */
+#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */
+#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */
+#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */
+#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */
+#define R_IA64_COPY 0x84 /* copy relocation */
+#define R_IA64_SUB 0x85 /* Addend and symbol difference */
+#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */
+#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */
+#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */
+#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */
+#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */
+#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */
+#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */
+#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */
+#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */
+#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */
+#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */
+#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */
+#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */
+#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */
+#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */
+#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */
+
+/* SH specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field. */
+#define EF_SH_MACH_MASK 0x1f
+#define EF_SH_UNKNOWN 0x0
+#define EF_SH1 0x1
+#define EF_SH2 0x2
+#define EF_SH3 0x3
+#define EF_SH_DSP 0x4
+#define EF_SH3_DSP 0x5
+#define EF_SH4AL_DSP 0x6
+#define EF_SH3E 0x8
+#define EF_SH4 0x9
+#define EF_SH2E 0xb
+#define EF_SH4A 0xc
+#define EF_SH2A 0xd
+#define EF_SH4_NOFPU 0x10
+#define EF_SH4A_NOFPU 0x11
+#define EF_SH4_NOMMU_NOFPU 0x12
+#define EF_SH2A_NOFPU 0x13
+#define EF_SH3_NOMMU 0x14
+#define EF_SH2A_SH4_NOFPU 0x15
+#define EF_SH2A_SH3_NOFPU 0x16
+#define EF_SH2A_SH4 0x17
+#define EF_SH2A_SH3E 0x18
+
+/* SH relocs. */
+#define R_SH_NONE 0
+#define R_SH_DIR32 1
+#define R_SH_REL32 2
+#define R_SH_DIR8WPN 3
+#define R_SH_IND12W 4
+#define R_SH_DIR8WPL 5
+#define R_SH_DIR8WPZ 6
+#define R_SH_DIR8BP 7
+#define R_SH_DIR8W 8
+#define R_SH_DIR8L 9
+#define R_SH_SWITCH16 25
+#define R_SH_SWITCH32 26
+#define R_SH_USES 27
+#define R_SH_COUNT 28
+#define R_SH_ALIGN 29
+#define R_SH_CODE 30
+#define R_SH_DATA 31
+#define R_SH_LABEL 32
+#define R_SH_SWITCH8 33
+#define R_SH_GNU_VTINHERIT 34
+#define R_SH_GNU_VTENTRY 35
+#define R_SH_TLS_GD_32 144
+#define R_SH_TLS_LD_32 145
+#define R_SH_TLS_LDO_32 146
+#define R_SH_TLS_IE_32 147
+#define R_SH_TLS_LE_32 148
+#define R_SH_TLS_DTPMOD32 149
+#define R_SH_TLS_DTPOFF32 150
+#define R_SH_TLS_TPOFF32 151
+#define R_SH_GOT32 160
+#define R_SH_PLT32 161
+#define R_SH_COPY 162
+#define R_SH_GLOB_DAT 163
+#define R_SH_JMP_SLOT 164
+#define R_SH_RELATIVE 165
+#define R_SH_GOTOFF 166
+#define R_SH_GOTPC 167
+/* Keep this the last entry. */
+#define R_SH_NUM 256
+
+/* S/390 specific definitions. */
+
+/* Valid values for the e_flags field. */
+
+#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */
+
+/* Additional s390 relocs */
+
+#define R_390_NONE 0 /* No reloc. */
+#define R_390_8 1 /* Direct 8 bit. */
+#define R_390_12 2 /* Direct 12 bit. */
+#define R_390_16 3 /* Direct 16 bit. */
+#define R_390_32 4 /* Direct 32 bit. */
+#define R_390_PC32 5 /* PC relative 32 bit. */
+#define R_390_GOT12 6 /* 12 bit GOT offset. */
+#define R_390_GOT32 7 /* 32 bit GOT offset. */
+#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */
+#define R_390_COPY 9 /* Copy symbol at runtime. */
+#define R_390_GLOB_DAT 10 /* Create GOT entry. */
+#define R_390_JMP_SLOT 11 /* Create PLT entry. */
+#define R_390_RELATIVE 12 /* Adjust by program base. */
+#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */
+#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */
+#define R_390_GOT16 15 /* 16 bit GOT offset. */
+#define R_390_PC16 16 /* PC relative 16 bit. */
+#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */
+#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */
+#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */
+#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */
+#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */
+#define R_390_64 22 /* Direct 64 bit. */
+#define R_390_PC64 23 /* PC relative 64 bit. */
+#define R_390_GOT64 24 /* 64 bit GOT offset. */
+#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */
+#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */
+#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */
+#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */
+#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */
+#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */
+#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */
+#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */
+#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */
+#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */
+#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */
+#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */
+#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */
+#define R_390_TLS_GDCALL 38 /* Tag for function call in general
+ dynamic TLS code. */
+#define R_390_TLS_LDCALL 39 /* Tag for function call in local
+ dynamic TLS code. */
+#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic
+ thread local data. */
+#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic
+ thread local data. */
+#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS
+ block offset. */
+#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS
+ block offset. */
+#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS
+ block offset. */
+#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic
+ thread local data in LE code. */
+#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic
+ thread local data in LE code. */
+#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for
+ negated static TLS block offset. */
+#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for
+ negated static TLS block offset. */
+#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for
+ negated static TLS block offset. */
+#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to
+ static TLS block. */
+#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to
+ static TLS block. */
+#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS
+ block. */
+#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS
+ block. */
+#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */
+#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
+#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS
+ block. */
+#define R_390_20 57 /* Direct 20 bit. */
+#define R_390_GOT20 58 /* 20 bit GOT offset. */
+#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */
+#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS
+ block offset. */
+#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */
+/* Keep this the last entry. */
+#define R_390_NUM 62
+
+
+/* CRIS relocations. */
+#define R_CRIS_NONE 0
+#define R_CRIS_8 1
+#define R_CRIS_16 2
+#define R_CRIS_32 3
+#define R_CRIS_8_PCREL 4
+#define R_CRIS_16_PCREL 5
+#define R_CRIS_32_PCREL 6
+#define R_CRIS_GNU_VTINHERIT 7
+#define R_CRIS_GNU_VTENTRY 8
+#define R_CRIS_COPY 9
+#define R_CRIS_GLOB_DAT 10
+#define R_CRIS_JUMP_SLOT 11
+#define R_CRIS_RELATIVE 12
+#define R_CRIS_16_GOT 13
+#define R_CRIS_32_GOT 14
+#define R_CRIS_16_GOTPLT 15
+#define R_CRIS_32_GOTPLT 16
+#define R_CRIS_32_GOTREL 17
+#define R_CRIS_32_PLT_GOTREL 18
+#define R_CRIS_32_PLT_PCREL 19
+
+#define R_CRIS_NUM 20
+
+
+/* AMD x86-64 relocations. */
+#define R_X86_64_NONE 0 /* No reloc */
+#define R_X86_64_64 1 /* Direct 64 bit */
+#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
+#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
+#define R_X86_64_PLT32 4 /* 32 bit PLT address */
+#define R_X86_64_COPY 5 /* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
+#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
+#define R_X86_64_RELATIVE 8 /* Adjust by program base */
+#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative
+ offset to GOT */
+#define R_X86_64_32 10 /* Direct 32 bit zero extended */
+#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
+#define R_X86_64_16 12 /* Direct 16 bit zero extended */
+#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
+#define R_X86_64_8 14 /* Direct 8 bit sign extended */
+#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
+#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */
+#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */
+#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset
+ to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset
+ to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
+#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset
+ to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */
+#define R_X86_64_PC64 24 /* PC relative 64 bit */
+#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */
+#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative
+ offset to GOT */
+#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */
+#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset
+ to GOT entry */
+#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */
+#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */
+#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset
+ to PLT entry */
+#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */
+#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */
+#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */
+#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS
+ descriptor. */
+#define R_X86_64_TLSDESC 36 /* TLS descriptor. */
+#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */
+#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */
+#define R_X86_64_GOTPCRELX 41 /* like GOTPCREL, but optionally with
+ linker optimizations */
+#define R_X86_64_REX_GOTPCRELX 42 /* like GOTPCRELX, but a REX prefix
+ is present */
+
+#define R_X86_64_NUM 43
+
+
+/* AM33 relocations. */
+#define R_MN10300_NONE 0 /* No reloc. */
+#define R_MN10300_32 1 /* Direct 32 bit. */
+#define R_MN10300_16 2 /* Direct 16 bit. */
+#define R_MN10300_8 3 /* Direct 8 bit. */
+#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */
+#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */
+#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */
+#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */
+#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */
+#define R_MN10300_24 9 /* Direct 24 bit. */
+#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */
+#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */
+#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */
+#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */
+#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */
+#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */
+#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */
+#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */
+#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */
+#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */
+#define R_MN10300_COPY 20 /* Copy symbol at runtime. */
+#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */
+#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */
+#define R_MN10300_RELATIVE 23 /* Adjust by program base. */
+#define R_MN10300_TLS_GD 24 /* 32-bit offset for global dynamic. */
+#define R_MN10300_TLS_LD 25 /* 32-bit offset for local dynamic. */
+#define R_MN10300_TLS_LDO 26 /* Module-relative offset. */
+#define R_MN10300_TLS_GOTIE 27 /* GOT offset for static TLS block
+ offset. */
+#define R_MN10300_TLS_IE 28 /* GOT address for static TLS block
+ offset. */
+#define R_MN10300_TLS_LE 29 /* Offset relative to static TLS
+ block. */
+#define R_MN10300_TLS_DTPMOD 30 /* ID of module containing symbol. */
+#define R_MN10300_TLS_DTPOFF 31 /* Offset in module TLS block. */
+#define R_MN10300_TLS_TPOFF 32 /* Offset in static TLS block. */
+#define R_MN10300_SYM_DIFF 33 /* Adjustment for next reloc as needed
+ by linker relaxation. */
+#define R_MN10300_ALIGN 34 /* Alignment requirement for linker
+ relaxation. */
+#define R_MN10300_NUM 35
+
+
+/* M32R relocs. */
+#define R_M32R_NONE 0 /* No reloc. */
+#define R_M32R_16 1 /* Direct 16 bit. */
+#define R_M32R_32 2 /* Direct 32 bit. */
+#define R_M32R_24 3 /* Direct 24 bit. */
+#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */
+#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */
+#define R_M32R_LO16 9 /* Low 16 bit. */
+#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */
+#define R_M32R_GNU_VTINHERIT 11
+#define R_M32R_GNU_VTENTRY 12
+/* M32R relocs use SHT_RELA. */
+#define R_M32R_16_RELA 33 /* Direct 16 bit. */
+#define R_M32R_32_RELA 34 /* Direct 32 bit. */
+#define R_M32R_24_RELA 35 /* Direct 24 bit. */
+#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */
+#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */
+#define R_M32R_LO16_RELA 41 /* Low 16 bit */
+#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */
+#define R_M32R_RELA_GNU_VTINHERIT 43
+#define R_M32R_RELA_GNU_VTENTRY 44
+#define R_M32R_REL32 45 /* PC relative 32 bit. */
+
+#define R_M32R_GOT24 48 /* 24 bit GOT entry */
+#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */
+#define R_M32R_COPY 50 /* Copy symbol at runtime */
+#define R_M32R_GLOB_DAT 51 /* Create GOT entry */
+#define R_M32R_JMP_SLOT 52 /* Create PLT entry */
+#define R_M32R_RELATIVE 53 /* Adjust by program base */
+#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */
+#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */
+#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned
+ low */
+#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed
+ low */
+#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */
+#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to
+ GOT with unsigned low */
+#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to
+ GOT with signed low */
+#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to
+ GOT */
+#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT
+ with unsigned low */
+#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT
+ with signed low */
+#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */
+#define R_M32R_NUM 256 /* Keep this the last entry. */
+
+
+/* TILEPro relocations. */
+#define R_TILEPRO_NONE 0 /* No reloc */
+#define R_TILEPRO_32 1 /* Direct 32 bit */
+#define R_TILEPRO_16 2 /* Direct 16 bit */
+#define R_TILEPRO_8 3 /* Direct 8 bit */
+#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */
+#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */
+#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */
+#define R_TILEPRO_LO16 7 /* Low 16 bit */
+#define R_TILEPRO_HI16 8 /* High 16 bit */
+#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */
+#define R_TILEPRO_COPY 10 /* Copy relocation */
+#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */
+#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */
+#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */
+#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */
+#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */
+#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */
+#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */
+#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */
+#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */
+#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */
+#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */
+#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */
+#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */
+#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */
+#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */
+#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */
+#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */
+#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */
+#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */
+/* Relocs 56-59 are currently not defined. */
+#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */
+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */
+#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */
+#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */
+#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */
+#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */
+#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */
+
+#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
+#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
+
+#define R_TILEPRO_NUM 130
+
+
+/* TILE-Gx relocations. */
+#define R_TILEGX_NONE 0 /* No reloc */
+#define R_TILEGX_64 1 /* Direct 64 bit */
+#define R_TILEGX_32 2 /* Direct 32 bit */
+#define R_TILEGX_16 3 /* Direct 16 bit */
+#define R_TILEGX_8 4 /* Direct 8 bit */
+#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */
+#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */
+#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */
+#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */
+#define R_TILEGX_HW0 9 /* hword 0 16-bit */
+#define R_TILEGX_HW1 10 /* hword 1 16-bit */
+#define R_TILEGX_HW2 11 /* hword 2 16-bit */
+#define R_TILEGX_HW3 12 /* hword 3 16-bit */
+#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */
+#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */
+#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */
+#define R_TILEGX_COPY 16 /* Copy relocation */
+#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */
+#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */
+#define R_TILEGX_RELATIVE 19 /* Adjust by program base */
+#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */
+#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */
+#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */
+#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */
+#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */
+#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */
+#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */
+#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */
+#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */
+#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */
+#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */
+#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */
+#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */
+#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */
+#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */
+#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */
+#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */
+#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */
+#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */
+#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */
+#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */
+#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */
+#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */
+#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
+/* Relocs 90-91 are currently not defined. */
+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
+/* Relocs 104-105 are currently not defined. */
+#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */
+#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */
+#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */
+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */
+#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */
+#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */
+
+#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
+#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
+
+#define R_TILEGX_NUM 130
+
+
+#endif /* elf.h */
diff --git a/examples/ex1.c b/examples/ex1.c
new file mode 100755
index 0000000..3d2a3e1
--- /dev/null
+++ b/examples/ex1.c
@@ -0,0 +1,8 @@
+#!/usr/local/bin/tcc -run
+#include <tcclib.h>
+
+int main()
+{
+ printf("Hello World\n");
+ return 0;
+}
diff --git a/examples/ex2.c b/examples/ex2.c
new file mode 100644
index 0000000..d415e39
--- /dev/null
+++ b/examples/ex2.c
@@ -0,0 +1,98 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#define N 20
+
+int nb_num;
+int tab[N];
+int stack_ptr;
+int stack_op[N];
+int stack_res[60];
+int result;
+
+int find(int n, int i1, int a, int b, int op)
+{
+ int i, j;
+ int c;
+
+ if (stack_ptr >= 0) {
+ stack_res[3*stack_ptr] = a;
+ stack_op[stack_ptr] = op;
+ stack_res[3*stack_ptr+1] = b;
+ stack_res[3*stack_ptr+2] = n;
+ if (n == result)
+ return 1;
+ tab[i1] = n;
+ }
+
+ for(i=0;i<nb_num;i++) {
+ for(j=i+1;j<nb_num;j++) {
+ a = tab[i];
+ b = tab[j];
+ if (a != 0 && b != 0) {
+
+ tab[j] = 0;
+ stack_ptr++;
+
+ if (find(a + b, i, a, b, '+'))
+ return 1;
+ if (find(a - b, i, a, b, '-'))
+ return 1;
+ if (find(b - a, i, b, a, '-'))
+ return 1;
+ if (find(a * b, i, a, b, '*'))
+ return 1;
+ if (b != 0) {
+ c = a / b;
+ if (find(c, i, a, b, '/'))
+ return 1;
+ }
+
+ if (a != 0) {
+ c = b / a;
+ if (find(c, i, b, a, '/'))
+ return 1;
+ }
+
+ stack_ptr--;
+ tab[i] = a;
+ tab[j] = b;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int i, res, p;
+
+ if (argc < 3) {
+ printf("usage: %s: result numbers...\n"
+ "Try to find result from numbers with the 4 basic operations.\n", argv[0]);
+ exit(1);
+ }
+
+ p = 1;
+ result = atoi(argv[p]);
+ printf("result=%d\n", result);
+ nb_num = 0;
+ for(i=p+1;i<argc;i++) {
+ tab[nb_num++] = atoi(argv[i]);
+ }
+
+ stack_ptr = -1;
+ res = find(0, 0, 0, 0, ' ');
+ if (res) {
+ for(i=0;i<=stack_ptr;i++) {
+ printf("%d %c %d = %d\n",
+ stack_res[3*i], stack_op[i],
+ stack_res[3*i+1], stack_res[3*i+2]);
+ }
+ return 0;
+ } else {
+ printf("Impossible\n");
+ return 1;
+ }
+}
diff --git a/examples/ex3.c b/examples/ex3.c
new file mode 100644
index 0000000..5556a4b
--- /dev/null
+++ b/examples/ex3.c
@@ -0,0 +1,23 @@
+#include <tcclib.h>
+
+int fib(n)
+{
+ if (n <= 2)
+ return 1;
+ else
+ return fib(n-1) + fib(n-2);
+}
+
+int main(int argc, char **argv)
+{
+ int n;
+ if (argc < 2) {
+ printf("usage: fib n\n"
+ "Compute nth Fibonacci number\n");
+ return 1;
+ }
+
+ n = atoi(argv[1]);
+ printf("fib(%d) = %d\n", n, fib(n, 2));
+ return 0;
+}
diff --git a/examples/ex4.c b/examples/ex4.c
new file mode 100755
index 0000000..f92c0da
--- /dev/null
+++ b/examples/ex4.c
@@ -0,0 +1,26 @@
+#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
+#include <stdlib.h>
+#include <stdio.h>
+#include <X11/Xlib.h>
+
+/* Yes, TCC can use X11 too ! */
+
+int main(int argc, char **argv)
+{
+ Display *display;
+ Screen *screen;
+
+ display = XOpenDisplay("");
+ if (!display) {
+ fprintf(stderr, "Could not open X11 display\n");
+ exit(1);
+ }
+ printf("X11 display opened.\n");
+ screen = XScreenOfDisplay(display, 0);
+ printf("width = %d\nheight = %d\ndepth = %d\n",
+ screen->width,
+ screen->height,
+ screen->root_depth);
+ XCloseDisplay(display);
+ return 0;
+}
diff --git a/examples/ex5.c b/examples/ex5.c
new file mode 100644
index 0000000..156425e
--- /dev/null
+++ b/examples/ex5.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int main()
+{
+ printf("Hello World\n");
+ return 0;
+}
diff --git a/i386-asm.c b/i386-asm.c
new file mode 100644
index 0000000..55c95af
--- /dev/null
+++ b/i386-asm.c
@@ -0,0 +1,1723 @@
+/*
+ * i386 specific functions for TCC assembler
+ *
+ * Copyright (c) 2001, 2002 Fabrice Bellard
+ * Copyright (c) 2009 Frédéric Feret (x86_64 support)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tcc.h"
+
+#define MAX_OPERANDS 3
+
+#define TOK_ASM_first TOK_ASM_clc
+#define TOK_ASM_last TOK_ASM_emms
+#define TOK_ASM_alllast TOK_ASM_subps
+
+#define OPC_B 0x01 /* only used with OPC_WL */
+#define OPC_WL 0x02 /* accepts w, l or no suffix */
+#define OPC_BWL (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */
+#define OPC_REG 0x04 /* register is added to opcode */
+#define OPC_MODRM 0x08 /* modrm encoding */
+
+#define OPCT_MASK 0x70
+#define OPC_FWAIT 0x10 /* add fwait opcode */
+#define OPC_SHIFT 0x20 /* shift opcodes */
+#define OPC_ARITH 0x30 /* arithmetic opcodes */
+#define OPC_FARITH 0x40 /* FPU arithmetic opcodes */
+#define OPC_TEST 0x50 /* test opcodes */
+#define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i))
+
+#define OPC_0F 0x100 /* Is secondary map (0x0f prefix) */
+#define OPC_48 0x200 /* Always has REX prefix */
+#ifdef TCC_TARGET_X86_64
+# define OPC_WLQ 0x1000 /* accepts w, l, q or no suffix */
+# define OPC_BWLQ (OPC_B | OPC_WLQ) /* accepts b, w, l, q or no suffix */
+# define OPC_WLX OPC_WLQ
+# define OPC_BWLX OPC_BWLQ
+#else
+# define OPC_WLX OPC_WL
+# define OPC_BWLX OPC_BWL
+#endif
+
+#define OPC_GROUP_SHIFT 13
+
+/* in order to compress the operand type, we use specific operands and
+ we or only with EA */
+enum {
+ OPT_REG8=0, /* warning: value is hardcoded from TOK_ASM_xxx */
+ OPT_REG16, /* warning: value is hardcoded from TOK_ASM_xxx */
+ OPT_REG32, /* warning: value is hardcoded from TOK_ASM_xxx */
+#ifdef TCC_TARGET_X86_64
+ OPT_REG64, /* warning: value is hardcoded from TOK_ASM_xxx */
+#endif
+ OPT_MMX, /* warning: value is hardcoded from TOK_ASM_xxx */
+ OPT_SSE, /* warning: value is hardcoded from TOK_ASM_xxx */
+ OPT_CR, /* warning: value is hardcoded from TOK_ASM_xxx */
+ OPT_TR, /* warning: value is hardcoded from TOK_ASM_xxx */
+ OPT_DB, /* warning: value is hardcoded from TOK_ASM_xxx */
+ OPT_SEG,
+ OPT_ST,
+#ifdef TCC_TARGET_X86_64
+ OPT_REG8_LOW, /* %spl,%bpl,%sil,%dil, encoded like ah,ch,dh,bh, but
+ with REX prefix, not used in insn templates */
+#endif
+ OPT_IM8,
+ OPT_IM8S,
+ OPT_IM16,
+ OPT_IM32,
+#ifdef TCC_TARGET_X86_64
+ OPT_IM64,
+#endif
+ OPT_EAX, /* %al, %ax, %eax or %rax register */
+ OPT_ST0, /* %st(0) register */
+ OPT_CL, /* %cl register */
+ OPT_DX, /* %dx register */
+ OPT_ADDR, /* OP_EA with only offset */
+ OPT_INDIR, /* *(expr) */
+ /* composite types */
+ OPT_COMPOSITE_FIRST,
+ OPT_IM, /* IM8 | IM16 | IM32 */
+ OPT_REG, /* REG8 | REG16 | REG32 | REG64 */
+ OPT_REGW, /* REG16 | REG32 | REG64 */
+ OPT_IMW, /* IM16 | IM32 */
+ OPT_MMXSSE, /* MMX | SSE */
+ OPT_DISP, /* Like OPT_ADDR, but emitted as displacement (for jumps) */
+ OPT_DISP8, /* Like OPT_ADDR, but only 8bit (short jumps) */
+ /* can be ored with any OPT_xxx */
+ OPT_EA = 0x80
+};
+
+#define OP_REG8 (1 << OPT_REG8)
+#define OP_REG16 (1 << OPT_REG16)
+#define OP_REG32 (1 << OPT_REG32)
+#define OP_MMX (1 << OPT_MMX)
+#define OP_SSE (1 << OPT_SSE)
+#define OP_CR (1 << OPT_CR)
+#define OP_TR (1 << OPT_TR)
+#define OP_DB (1 << OPT_DB)
+#define OP_SEG (1 << OPT_SEG)
+#define OP_ST (1 << OPT_ST)
+#define OP_IM8 (1 << OPT_IM8)
+#define OP_IM8S (1 << OPT_IM8S)
+#define OP_IM16 (1 << OPT_IM16)
+#define OP_IM32 (1 << OPT_IM32)
+#define OP_EAX (1 << OPT_EAX)
+#define OP_ST0 (1 << OPT_ST0)
+#define OP_CL (1 << OPT_CL)
+#define OP_DX (1 << OPT_DX)
+#define OP_ADDR (1 << OPT_ADDR)
+#define OP_INDIR (1 << OPT_INDIR)
+#ifdef TCC_TARGET_X86_64
+# define OP_REG64 (1 << OPT_REG64)
+# define OP_REG8_LOW (1 << OPT_REG8_LOW)
+# define OP_IM64 (1 << OPT_IM64)
+# define OP_EA32 (OP_EA << 1)
+#else
+# define OP_REG64 0
+# define OP_REG8_LOW 0
+# define OP_IM64 0
+# define OP_EA32 0
+#endif
+
+#define OP_EA 0x40000000
+#define OP_REG (OP_REG8 | OP_REG16 | OP_REG32 | OP_REG64)
+
+#ifdef TCC_TARGET_X86_64
+# define TREG_XAX TREG_RAX
+# define TREG_XCX TREG_RCX
+# define TREG_XDX TREG_RDX
+#else
+# define TREG_XAX TREG_EAX
+# define TREG_XCX TREG_ECX
+# define TREG_XDX TREG_EDX
+#endif
+
+typedef struct ASMInstr {
+ uint16_t sym;
+ uint16_t opcode;
+ uint16_t instr_type;
+ uint8_t nb_ops;
+ uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */
+} ASMInstr;
+
+typedef struct Operand {
+ uint32_t type;
+ int8_t reg; /* register, -1 if none */
+ int8_t reg2; /* second register, -1 if none */
+ uint8_t shift;
+ ExprValue e;
+} Operand;
+
+static const uint8_t reg_to_size[9] = {
+/*
+ [OP_REG8] = 0,
+ [OP_REG16] = 1,
+ [OP_REG32] = 2,
+#ifdef TCC_TARGET_X86_64
+ [OP_REG64] = 3,
+#endif
+*/
+ 0, 0, 1, 0, 2, 0, 0, 0, 3
+};
+
+#define NB_TEST_OPCODES 30
+
+static const uint8_t test_bits[NB_TEST_OPCODES] = {
+ 0x00, /* o */
+ 0x01, /* no */
+ 0x02, /* b */
+ 0x02, /* c */
+ 0x02, /* nae */
+ 0x03, /* nb */
+ 0x03, /* nc */
+ 0x03, /* ae */
+ 0x04, /* e */
+ 0x04, /* z */
+ 0x05, /* ne */
+ 0x05, /* nz */
+ 0x06, /* be */
+ 0x06, /* na */
+ 0x07, /* nbe */
+ 0x07, /* a */
+ 0x08, /* s */
+ 0x09, /* ns */
+ 0x0a, /* p */
+ 0x0a, /* pe */
+ 0x0b, /* np */
+ 0x0b, /* po */
+ 0x0c, /* l */
+ 0x0c, /* nge */
+ 0x0d, /* nl */
+ 0x0d, /* ge */
+ 0x0e, /* le */
+ 0x0e, /* ng */
+ 0x0f, /* nle */
+ 0x0f, /* g */
+};
+
+static const uint8_t segment_prefixes[] = {
+ 0x26, /* es */
+ 0x2e, /* cs */
+ 0x36, /* ss */
+ 0x3e, /* ds */
+ 0x64, /* fs */
+ 0x65 /* gs */
+};
+
+static const ASMInstr asm_instrs[] = {
+#define ALT(x) x
+/* This removes a 0x0f in the second byte */
+#define O(o) ((uint64_t) ((((o) & 0xff00) == 0x0f00) ? ((((o) >> 8) & ~0xff) | ((o) & 0xff)) : (o)))
+/* This constructs instr_type from opcode, type and group. */
+#define T(o,i,g) ((i) | ((g) << OPC_GROUP_SHIFT) | ((((o) & 0xff00) == 0x0f00) ? OPC_0F : 0))
+#define DEF_ASM_OP0(name, opcode)
+#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 0, { 0 } },
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 1, { op0 }},
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 2, { op0, op1 }},
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 3, { op0, op1, op2 }},
+#ifdef TCC_TARGET_X86_64
+# include "x86_64-asm.h"
+#else
+# include "i386-asm.h"
+#endif
+ /* last operation */
+ { 0, },
+};
+
+static const uint16_t op0_codes[] = {
+#define ALT(x)
+#define DEF_ASM_OP0(x, opcode) opcode,
+#define DEF_ASM_OP0L(name, opcode, group, instr_type)
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
+#ifdef TCC_TARGET_X86_64
+# include "x86_64-asm.h"
+#else
+# include "i386-asm.h"
+#endif
+};
+
+static inline int get_reg_shift(TCCState *s1)
+{
+ int shift, v;
+ v = asm_int_expr(s1);
+ switch(v) {
+ case 1:
+ shift = 0;
+ break;
+ case 2:
+ shift = 1;
+ break;
+ case 4:
+ shift = 2;
+ break;
+ case 8:
+ shift = 3;
+ break;
+ default:
+ expect("1, 2, 4 or 8 constant");
+ shift = 0;
+ break;
+ }
+ return shift;
+}
+
+#ifdef TCC_TARGET_X86_64
+static int asm_parse_numeric_reg(int t, unsigned int *type)
+{
+ int reg = -1;
+ if (t >= TOK_IDENT && t < tok_ident) {
+ const char *s = table_ident[t - TOK_IDENT]->str;
+ char c;
+ *type = OP_REG64;
+ if (*s == 'c') {
+ s++;
+ *type = OP_CR;
+ }
+ if (*s++ != 'r')
+ return -1;
+ /* Don't allow leading '0'. */
+ if ((c = *s++) >= '1' && c <= '9')
+ reg = c - '0';
+ else
+ return -1;
+ if ((c = *s) >= '0' && c <= '5')
+ s++, reg = reg * 10 + c - '0';
+ if (reg > 15)
+ return -1;
+ if ((c = *s) == 0)
+ ;
+ else if (*type != OP_REG64)
+ return -1;
+ else if (c == 'b' && !s[1])
+ *type = OP_REG8;
+ else if (c == 'w' && !s[1])
+ *type = OP_REG16;
+ else if (c == 'd' && !s[1])
+ *type = OP_REG32;
+ else
+ return -1;
+ }
+ return reg;
+}
+#endif
+
+static int asm_parse_reg(unsigned int *type)
+{
+ int reg = 0;
+ *type = 0;
+ if (tok != '%')
+ goto error_32;
+ next();
+ if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
+ reg = tok - TOK_ASM_eax;
+ *type = OP_REG32;
+#ifdef TCC_TARGET_X86_64
+ } else if (tok >= TOK_ASM_rax && tok <= TOK_ASM_rdi) {
+ reg = tok - TOK_ASM_rax;
+ *type = OP_REG64;
+ } else if (tok == TOK_ASM_rip) {
+ reg = -2; /* Probably should use different escape code. */
+ *type = OP_REG64;
+ } else if ((reg = asm_parse_numeric_reg(tok, type)) >= 0
+ && (*type == OP_REG32 || *type == OP_REG64)) {
+ ;
+#endif
+ } else {
+ error_32:
+ expect("register");
+ }
+ next();
+ return reg;
+}
+
+static void parse_operand(TCCState *s1, Operand *op)
+{
+ ExprValue e;
+ int reg, indir;
+ const char *p;
+
+ indir = 0;
+ if (tok == '*') {
+ next();
+ indir = OP_INDIR;
+ }
+
+ if (tok == '%') {
+ next();
+ if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
+ reg = tok - TOK_ASM_al;
+ op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
+ op->reg = reg & 7;
+ if ((op->type & OP_REG) && op->reg == TREG_XAX)
+ op->type |= OP_EAX;
+ else if (op->type == OP_REG8 && op->reg == TREG_XCX)
+ op->type |= OP_CL;
+ else if (op->type == OP_REG16 && op->reg == TREG_XDX)
+ op->type |= OP_DX;
+ } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
+ op->type = OP_DB;
+ op->reg = tok - TOK_ASM_dr0;
+ } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
+ op->type = OP_SEG;
+ op->reg = tok - TOK_ASM_es;
+ } else if (tok == TOK_ASM_st) {
+ op->type = OP_ST;
+ op->reg = 0;
+ next();
+ if (tok == '(') {
+ next();
+ if (tok != TOK_PPNUM)
+ goto reg_error;
+ p = tokc.str.data;
+ reg = p[0] - '0';
+ if ((unsigned)reg >= 8 || p[1] != '\0')
+ goto reg_error;
+ op->reg = reg;
+ next();
+ skip(')');
+ }
+ if (op->reg == 0)
+ op->type |= OP_ST0;
+ goto no_skip;
+#ifdef TCC_TARGET_X86_64
+ } else if (tok >= TOK_ASM_spl && tok <= TOK_ASM_dil) {
+ op->type = OP_REG8 | OP_REG8_LOW;
+ op->reg = 4 + tok - TOK_ASM_spl;
+ } else if ((op->reg = asm_parse_numeric_reg(tok, &op->type)) >= 0) {
+ ;
+#endif
+ } else {
+ reg_error:
+ tcc_error("unknown register %%%s", get_tok_str(tok, &tokc));
+ }
+ next();
+ no_skip: ;
+ } else if (tok == '$') {
+ /* constant value */
+ next();
+ asm_expr(s1, &e);
+ op->type = OP_IM32;
+ op->e = e;
+ if (!op->e.sym) {
+ if (op->e.v == (uint8_t)op->e.v)
+ op->type |= OP_IM8;
+ if (op->e.v == (int8_t)op->e.v)
+ op->type |= OP_IM8S;
+ if (op->e.v == (uint16_t)op->e.v)
+ op->type |= OP_IM16;
+#ifdef TCC_TARGET_X86_64
+ if (op->e.v != (int32_t)op->e.v && op->e.v != (uint32_t)op->e.v)
+ op->type = OP_IM64;
+#endif
+ }
+ } else {
+ /* address(reg,reg2,shift) with all variants */
+ op->type = OP_EA;
+ op->reg = -1;
+ op->reg2 = -1;
+ op->shift = 0;
+ if (tok != '(') {
+ asm_expr(s1, &e);
+ op->e = e;
+ } else {
+ next();
+ if (tok == '%') {
+ unget_tok('(');
+ op->e.v = 0;
+ op->e.sym = NULL;
+ } else {
+ /* bracketed offset expression */
+ asm_expr(s1, &e);
+ if (tok != ')')
+ expect(")");
+ next();
+ op->e.v = e.v;
+ op->e.sym = e.sym;
+ }
+ op->e.pcrel = 0;
+ }
+ if (tok == '(') {
+ unsigned int type = 0;
+ next();
+ if (tok != ',') {
+ op->reg = asm_parse_reg(&type);
+ }
+ if (tok == ',') {
+ next();
+ if (tok != ',') {
+ op->reg2 = asm_parse_reg(&type);
+ }
+ if (tok == ',') {
+ next();
+ op->shift = get_reg_shift(s1);
+ }
+ }
+ if (type & OP_REG32)
+ op->type |= OP_EA32;
+ skip(')');
+ }
+ if (op->reg == -1 && op->reg2 == -1)
+ op->type |= OP_ADDR;
+ }
+ op->type |= indir;
+}
+
+/* XXX: unify with C code output ? */
+ST_FUNC void gen_expr32(ExprValue *pe)
+{
+ if (pe->pcrel)
+ /* If PC-relative, always set VT_SYM, even without symbol,
+ so as to force a relocation to be emitted. */
+ gen_addrpc32(VT_SYM, pe->sym, pe->v);
+ else
+ gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
+}
+
+#ifdef TCC_TARGET_X86_64
+ST_FUNC void gen_expr64(ExprValue *pe)
+{
+ gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
+}
+#endif
+
+/* XXX: unify with C code output ? */
+static void gen_disp32(ExprValue *pe)
+{
+ Sym *sym = pe->sym;
+ ElfSym *esym = elfsym(sym);
+ if (esym && esym->st_shndx == cur_text_section->sh_num) {
+ /* same section: we can output an absolute value. Note
+ that the TCC compiler behaves differently here because
+ it always outputs a relocation to ease (future) code
+ elimination in the linker */
+ gen_le32(pe->v + esym->st_value - ind - 4);
+ } else {
+ if (sym && sym->type.t == VT_VOID) {
+ sym->type.t = VT_FUNC;
+ sym->type.ref = NULL;
+ }
+ gen_addrpc32(VT_SYM, sym, pe->v);
+ }
+}
+
+/* generate the modrm operand */
+static inline int asm_modrm(int reg, Operand *op)
+{
+ int mod, reg1, reg2, sib_reg1;
+
+ if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
+ g(0xc0 + (reg << 3) + op->reg);
+ } else if (op->reg == -1 && op->reg2 == -1) {
+ /* displacement only */
+#ifdef TCC_TARGET_X86_64
+ g(0x04 + (reg << 3));
+ g(0x25);
+#else
+ g(0x05 + (reg << 3));
+#endif
+ gen_expr32(&op->e);
+#ifdef TCC_TARGET_X86_64
+ } else if (op->reg == -2) {
+ ExprValue *pe = &op->e;
+ g(0x05 + (reg << 3));
+ gen_addrpc32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
+ return ind;
+#endif
+ } else {
+ sib_reg1 = op->reg;
+ /* fist compute displacement encoding */
+ if (sib_reg1 == -1) {
+ sib_reg1 = 5;
+ mod = 0x00;
+ } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) {
+ mod = 0x00;
+ } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) {
+ mod = 0x40;
+ } else {
+ mod = 0x80;
+ }
+ /* compute if sib byte needed */
+ reg1 = op->reg;
+ if (op->reg2 != -1)
+ reg1 = 4;
+ g(mod + (reg << 3) + reg1);
+ if (reg1 == 4) {
+ /* add sib byte */
+ reg2 = op->reg2;
+ if (reg2 == -1)
+ reg2 = 4; /* indicate no index */
+ g((op->shift << 6) + (reg2 << 3) + sib_reg1);
+ }
+ /* add offset */
+ if (mod == 0x40) {
+ g(op->e.v);
+ } else if (mod == 0x80 || op->reg == -1) {
+ gen_expr32(&op->e);
+ }
+ }
+ return 0;
+}
+
+#ifdef TCC_TARGET_X86_64
+#define REX_W 0x48
+#define REX_R 0x44
+#define REX_X 0x42
+#define REX_B 0x41
+
+static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type,
+ int regi, int rmi)
+{
+ unsigned char rex = width64 ? 0x48 : 0;
+ int saw_high_8bit = 0;
+ int i;
+ if (rmi == -1) {
+ /* No mod/rm byte, but we might have a register op nevertheless
+ (we will add it to the opcode later). */
+ for(i = 0; i < nb_ops; i++) {
+ if (op_type[i] & (OP_REG | OP_ST)) {
+ if (ops[i].reg >= 8) {
+ rex |= REX_B;
+ ops[i].reg -= 8;
+ } else if (ops[i].type & OP_REG8_LOW)
+ rex |= 0x40;
+ else if (ops[i].type & OP_REG8 && ops[i].reg >= 4)
+ /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
+ saw_high_8bit = ops[i].reg;
+ break;
+ }
+ }
+ } else {
+ if (regi != -1) {
+ if (ops[regi].reg >= 8) {
+ rex |= REX_R;
+ ops[regi].reg -= 8;
+ } else if (ops[regi].type & OP_REG8_LOW)
+ rex |= 0x40;
+ else if (ops[regi].type & OP_REG8 && ops[regi].reg >= 4)
+ /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
+ saw_high_8bit = ops[regi].reg;
+ }
+ if (ops[rmi].type & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_EA)) {
+ if (ops[rmi].reg >= 8) {
+ rex |= REX_B;
+ ops[rmi].reg -= 8;
+ } else if (ops[rmi].type & OP_REG8_LOW)
+ rex |= 0x40;
+ else if (ops[rmi].type & OP_REG8 && ops[rmi].reg >= 4)
+ /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
+ saw_high_8bit = ops[rmi].reg;
+ }
+ if (ops[rmi].type & OP_EA && ops[rmi].reg2 >= 8) {
+ rex |= REX_X;
+ ops[rmi].reg2 -= 8;
+ }
+ }
+ if (rex) {
+ if (saw_high_8bit)
+ tcc_error("can't encode register %%%ch when REX prefix is required",
+ "acdb"[saw_high_8bit-4]);
+ g(rex);
+ }
+}
+#endif
+
+static void maybe_print_stats (void)
+{
+ static int already = 1;
+ if (!already)
+ /* print stats about opcodes */
+ {
+ const struct ASMInstr *pa;
+ int freq[4];
+ int op_vals[500];
+ int nb_op_vals, i, j;
+
+ already = 1;
+ nb_op_vals = 0;
+ memset(freq, 0, sizeof(freq));
+ for(pa = asm_instrs; pa->sym != 0; pa++) {
+ freq[pa->nb_ops]++;
+ //for(i=0;i<pa->nb_ops;i++) {
+ for(j=0;j<nb_op_vals;j++) {
+ //if (pa->op_type[i] == op_vals[j])
+ if (pa->instr_type == op_vals[j])
+ goto found;
+ }
+ //op_vals[nb_op_vals++] = pa->op_type[i];
+ op_vals[nb_op_vals++] = pa->instr_type;
+ found: ;
+ //}
+ }
+ for(i=0;i<nb_op_vals;i++) {
+ int v = op_vals[i];
+ //if ((v & (v - 1)) != 0)
+ printf("%3d: %08x\n", i, v);
+ }
+ printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
+ (int)sizeof(asm_instrs),
+ (int)sizeof(asm_instrs) / (int)sizeof(ASMInstr),
+ freq[0], freq[1], freq[2], freq[3]);
+ }
+}
+
+ST_FUNC void asm_opcode(TCCState *s1, int opcode)
+{
+ const ASMInstr *pa;
+ int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc;
+ int nb_ops, s;
+ Operand ops[MAX_OPERANDS], *pop;
+ int op_type[3]; /* decoded op type */
+ int alltypes; /* OR of all operand types */
+ int autosize;
+ int p66;
+#ifdef TCC_TARGET_X86_64
+ int rex64;
+#endif
+
+ maybe_print_stats();
+ /* force synthetic ';' after prefix instruction, so we can handle */
+ /* one-line things like "rep stosb" instead of only "rep\nstosb" */
+ if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz)
+ unget_tok(';');
+
+ /* get operands */
+ pop = ops;
+ nb_ops = 0;
+ seg_prefix = 0;
+ alltypes = 0;
+ for(;;) {
+ if (tok == ';' || tok == TOK_LINEFEED)
+ break;
+ if (nb_ops >= MAX_OPERANDS) {
+ tcc_error("incorrect number of operands");
+ }
+ parse_operand(s1, pop);
+ if (tok == ':') {
+ if (pop->type != OP_SEG || seg_prefix)
+ tcc_error("incorrect prefix");
+ seg_prefix = segment_prefixes[pop->reg];
+ next();
+ parse_operand(s1, pop);
+ if (!(pop->type & OP_EA)) {
+ tcc_error("segment prefix must be followed by memory reference");
+ }
+ }
+ pop++;
+ nb_ops++;
+ if (tok != ',')
+ break;
+ next();
+ }
+
+ s = 0; /* avoid warning */
+
+again:
+ /* optimize matching by using a lookup table (no hashing is needed
+ !) */
+ for(pa = asm_instrs; pa->sym != 0; pa++) {
+ int it = pa->instr_type & OPCT_MASK;
+ s = 0;
+ if (it == OPC_FARITH) {
+ v = opcode - pa->sym;
+ if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
+ continue;
+ } else if (it == OPC_ARITH) {
+ if (!(opcode >= pa->sym && opcode < pa->sym + 8*NBWLX))
+ continue;
+ s = (opcode - pa->sym) % NBWLX;
+ if ((pa->instr_type & OPC_BWLX) == OPC_WLX)
+ {
+ /* We need to reject the xxxb opcodes that we accepted above.
+ Note that pa->sym for WLX opcodes is the 'w' token,
+ to get the 'b' token subtract one. */
+ if (((opcode - pa->sym + 1) % NBWLX) == 0)
+ continue;
+ s++;
+ }
+ } else if (it == OPC_SHIFT) {
+ if (!(opcode >= pa->sym && opcode < pa->sym + 7*NBWLX))
+ continue;
+ s = (opcode - pa->sym) % NBWLX;
+ } else if (it == OPC_TEST) {
+ if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
+ continue;
+ /* cmovxx is a test opcode but accepts multiple sizes.
+ The suffixes aren't encoded in the table, instead we
+ simply force size autodetection always and deal with suffixed
+ variants below when we don't find e.g. "cmovzl". */
+ if (pa->instr_type & OPC_WLX)
+ s = NBWLX - 1;
+ } else if (pa->instr_type & OPC_B) {
+#ifdef TCC_TARGET_X86_64
+ /* Some instructions don't have the full size but only
+ bwl form. insb e.g. */
+ if ((pa->instr_type & OPC_WLQ) != OPC_WLQ
+ && !(opcode >= pa->sym && opcode < pa->sym + NBWLX-1))
+ continue;
+#endif
+ if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX))
+ continue;
+ s = opcode - pa->sym;
+ } else if (pa->instr_type & OPC_WLX) {
+ if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX-1))
+ continue;
+ s = opcode - pa->sym + 1;
+ } else {
+ if (pa->sym != opcode)
+ continue;
+ }
+ if (pa->nb_ops != nb_ops)
+ continue;
+#ifdef TCC_TARGET_X86_64
+ /* Special case for moves. Selecting the IM64->REG64 form
+ should only be done if we really have an >32bit imm64, and that
+ is hardcoded. Ignore it here. */
+ if (pa->opcode == 0xb0 && ops[0].type != OP_IM64
+ && (ops[1].type & OP_REG) == OP_REG64
+ && !(pa->instr_type & OPC_0F))
+ continue;
+#endif
+ /* now decode and check each operand */
+ alltypes = 0;
+ for(i = 0; i < nb_ops; i++) {
+ int op1, op2;
+ op1 = pa->op_type[i];
+ op2 = op1 & 0x1f;
+ switch(op2) {
+ case OPT_IM:
+ v = OP_IM8 | OP_IM16 | OP_IM32;
+ break;
+ case OPT_REG:
+ v = OP_REG8 | OP_REG16 | OP_REG32 | OP_REG64;
+ break;
+ case OPT_REGW:
+ v = OP_REG16 | OP_REG32 | OP_REG64;
+ break;
+ case OPT_IMW:
+ v = OP_IM16 | OP_IM32;
+ break;
+ case OPT_MMXSSE:
+ v = OP_MMX | OP_SSE;
+ break;
+ case OPT_DISP:
+ case OPT_DISP8:
+ v = OP_ADDR;
+ break;
+ default:
+ v = 1 << op2;
+ break;
+ }
+ if (op1 & OPT_EA)
+ v |= OP_EA;
+ op_type[i] = v;
+ if ((ops[i].type & v) == 0)
+ goto next;
+ alltypes |= ops[i].type;
+ }
+ /* all is matching ! */
+ break;
+ next: ;
+ }
+ if (pa->sym == 0) {
+ if (opcode >= TOK_ASM_first && opcode <= TOK_ASM_last) {
+ int b;
+ b = op0_codes[opcode - TOK_ASM_first];
+ if (b & 0xff00)
+ g(b >> 8);
+ g(b);
+ return;
+ } else if (opcode <= TOK_ASM_alllast) {
+ tcc_error("bad operand with opcode '%s'",
+ get_tok_str(opcode, NULL));
+ } else {
+ /* Special case for cmovcc, we accept size suffixes but ignore
+ them, but we don't want them to blow up our tables. */
+ TokenSym *ts = table_ident[opcode - TOK_IDENT];
+ if (ts->len >= 6
+ && strchr("wlq", ts->str[ts->len-1])
+ && !memcmp(ts->str, "cmov", 4)) {
+ opcode = tok_alloc(ts->str, ts->len-1)->tok;
+ goto again;
+ }
+ tcc_error("unknown opcode '%s'", ts->str);
+ }
+ }
+ /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
+ autosize = NBWLX-1;
+#ifdef TCC_TARGET_X86_64
+ /* XXX the autosize should rather be zero, to not have to adjust this
+ all the time. */
+ if ((pa->instr_type & OPC_BWLQ) == OPC_B)
+ autosize = NBWLX-2;
+#endif
+ if (s == autosize) {
+ /* Check for register operands providing hints about the size.
+ Start from the end, i.e. destination operands. This matters
+ only for opcodes accepting different sized registers, lar and lsl
+ are such opcodes. */
+ for(i = nb_ops - 1; s == autosize && i >= 0; i--) {
+ if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
+ s = reg_to_size[ops[i].type & OP_REG];
+ }
+ if (s == autosize) {
+ if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
+ (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
+ s = 2;
+ else if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
+ (ops[0].type & OP_EA))
+ s = NBWLX - 2;
+ else
+ tcc_error("cannot infer opcode suffix");
+ }
+ }
+
+#ifdef TCC_TARGET_X86_64
+ /* Generate addr32 prefix if needed */
+ for(i = 0; i < nb_ops; i++) {
+ if (ops[i].type & OP_EA32) {
+ g(0x67);
+ break;
+ }
+ }
+#endif
+ /* generate data16 prefix if needed */
+ p66 = 0;
+ if (s == 1)
+ p66 = 1;
+ else {
+ /* accepting mmx+sse in all operands --> needs 0x66 to
+ switch to sse mode. Accepting only sse in an operand --> is
+ already SSE insn and needs 0x66/f2/f3 handling. */
+ for (i = 0; i < nb_ops; i++)
+ if ((op_type[i] & (OP_MMX | OP_SSE)) == (OP_MMX | OP_SSE)
+ && ops[i].type & OP_SSE)
+ p66 = 1;
+ }
+ if (p66)
+ g(0x66);
+#ifdef TCC_TARGET_X86_64
+ rex64 = 0;
+ if (pa->instr_type & OPC_48)
+ rex64 = 1;
+ else if (s == 3 || (alltypes & OP_REG64)) {
+ /* generate REX prefix */
+ int default64 = 0;
+ for(i = 0; i < nb_ops; i++) {
+ if (op_type[i] == OP_REG64 && pa->opcode != 0xb8) {
+ /* If only 64bit regs are accepted in one operand
+ this is a default64 instruction without need for
+ REX prefixes, except for movabs(0xb8). */
+ default64 = 1;
+ break;
+ }
+ }
+ /* XXX find better encoding for the default64 instructions. */
+ if (((opcode != TOK_ASM_push && opcode != TOK_ASM_pop
+ && opcode != TOK_ASM_pushw && opcode != TOK_ASM_pushl
+ && opcode != TOK_ASM_pushq && opcode != TOK_ASM_popw
+ && opcode != TOK_ASM_popl && opcode != TOK_ASM_popq
+ && opcode != TOK_ASM_call && opcode != TOK_ASM_jmp))
+ && !default64)
+ rex64 = 1;
+ }
+#endif
+
+ /* now generates the operation */
+ if (OPCT_IS(pa->instr_type, OPC_FWAIT))
+ g(0x9b);
+ if (seg_prefix)
+ g(seg_prefix);
+
+ v = pa->opcode;
+ if (pa->instr_type & OPC_0F)
+ v = ((v & ~0xff) << 8) | 0x0f00 | (v & 0xff);
+ if ((v == 0x69 || v == 0x6b) && nb_ops == 2) {
+ /* kludge for imul $im, %reg */
+ nb_ops = 3;
+ ops[2] = ops[1];
+ op_type[2] = op_type[1];
+ } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) {
+ v--; /* int $3 case */
+ nb_ops = 0;
+ } else if ((v == 0x06 || v == 0x07)) {
+ if (ops[0].reg >= 4) {
+ /* push/pop %fs or %gs */
+ v = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3);
+ } else {
+ v += ops[0].reg << 3;
+ }
+ nb_ops = 0;
+ } else if (v <= 0x05) {
+ /* arith case */
+ v += ((opcode - TOK_ASM_addb) / NBWLX) << 3;
+ } else if ((pa->instr_type & (OPCT_MASK | OPC_MODRM)) == OPC_FARITH) {
+ /* fpu arith case */
+ v += ((opcode - pa->sym) / 6) << 3;
+ }
+
+ /* search which operand will be used for modrm */
+ modrm_index = -1;
+ modreg_index = -1;
+ if (pa->instr_type & OPC_MODRM) {
+ if (!nb_ops) {
+ /* A modrm opcode without operands is a special case (e.g. mfence).
+ It has a group and acts as if there's an register operand 0
+ (ax). */
+ i = 0;
+ ops[i].type = OP_REG;
+ ops[i].reg = 0;
+ goto modrm_found;
+ }
+ /* first look for an ea operand */
+ for(i = 0;i < nb_ops; i++) {
+ if (op_type[i] & OP_EA)
+ goto modrm_found;
+ }
+ /* then if not found, a register or indirection (shift instructions) */
+ for(i = 0;i < nb_ops; i++) {
+ if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
+ goto modrm_found;
+ }
+#ifdef ASM_DEBUG
+ tcc_error("bad op table");
+#endif
+ modrm_found:
+ modrm_index = i;
+ /* if a register is used in another operand then it is
+ used instead of group */
+ for(i = 0;i < nb_ops; i++) {
+ int t = op_type[i];
+ if (i != modrm_index &&
+ (t & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
+ modreg_index = i;
+ break;
+ }
+ }
+ }
+#ifdef TCC_TARGET_X86_64
+ asm_rex (rex64, ops, nb_ops, op_type, modreg_index, modrm_index);
+#endif
+
+ if (pa->instr_type & OPC_REG) {
+ /* mov $im, %reg case */
+ if (v == 0xb0 && s >= 1)
+ v += 7;
+ for(i = 0; i < nb_ops; i++) {
+ if (op_type[i] & (OP_REG | OP_ST)) {
+ v += ops[i].reg;
+ break;
+ }
+ }
+ }
+ if (pa->instr_type & OPC_B)
+ v += s >= 1;
+ if (nb_ops == 1 && pa->op_type[0] == OPT_DISP8) {
+ ElfSym *esym;
+ int jmp_disp;
+
+ /* see if we can really generate the jump with a byte offset */
+ esym = elfsym(ops[0].e.sym);
+ if (!esym || esym->st_shndx != cur_text_section->sh_num)
+ goto no_short_jump;
+ jmp_disp = ops[0].e.v + esym->st_value - ind - 2 - (v >= 0xff);
+ if (jmp_disp == (int8_t)jmp_disp) {
+ /* OK to generate jump */
+ ops[0].e.sym = 0;
+ ops[0].e.v = jmp_disp;
+ op_type[0] = OP_IM8S;
+ } else {
+ no_short_jump:
+ /* long jump will be allowed. need to modify the
+ opcode slightly */
+ if (v == 0xeb) /* jmp */
+ v = 0xe9;
+ else if (v == 0x70) /* jcc */
+ v += 0x0f10;
+ else
+ tcc_error("invalid displacement");
+ }
+ }
+ if (OPCT_IS(pa->instr_type, OPC_TEST))
+ v += test_bits[opcode - pa->sym];
+ op1 = v >> 16;
+ if (op1)
+ g(op1);
+ op1 = (v >> 8) & 0xff;
+ if (op1)
+ g(op1);
+ g(v);
+
+ if (OPCT_IS(pa->instr_type, OPC_SHIFT)) {
+ reg = (opcode - pa->sym) / NBWLX;
+ if (reg == 6)
+ reg = 7;
+ } else if (OPCT_IS(pa->instr_type, OPC_ARITH)) {
+ reg = (opcode - pa->sym) / NBWLX;
+ } else if (OPCT_IS(pa->instr_type, OPC_FARITH)) {
+ reg = (opcode - pa->sym) / 6;
+ } else {
+ reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
+ }
+
+ pc = 0;
+ if (pa->instr_type & OPC_MODRM) {
+ /* if a register is used in another operand then it is
+ used instead of group */
+ if (modreg_index >= 0)
+ reg = ops[modreg_index].reg;
+ pc = asm_modrm(reg, &ops[modrm_index]);
+ }
+
+ /* emit constants */
+#ifndef TCC_TARGET_X86_64
+ if (!(pa->instr_type & OPC_0F)
+ && (pa->opcode == 0x9a || pa->opcode == 0xea)) {
+ /* ljmp or lcall kludge */
+ gen_expr32(&ops[1].e);
+ if (ops[0].e.sym)
+ tcc_error("cannot relocate");
+ gen_le16(ops[0].e.v);
+ return;
+ }
+#endif
+ for(i = 0;i < nb_ops; i++) {
+ v = op_type[i];
+ if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64 | OP_IM8S | OP_ADDR)) {
+ /* if multiple sizes are given it means we must look
+ at the op size */
+ if ((v | OP_IM8 | OP_IM64) == (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64)) {
+ if (s == 0)
+ v = OP_IM8;
+ else if (s == 1)
+ v = OP_IM16;
+ else if (s == 2 || (v & OP_IM64) == 0)
+ v = OP_IM32;
+ else
+ v = OP_IM64;
+ }
+
+ if ((v & (OP_IM8 | OP_IM8S | OP_IM16)) && ops[i].e.sym)
+ tcc_error("cannot relocate");
+
+ if (v & (OP_IM8 | OP_IM8S)) {
+ g(ops[i].e.v);
+ } else if (v & OP_IM16) {
+ gen_le16(ops[i].e.v);
+#ifdef TCC_TARGET_X86_64
+ } else if (v & OP_IM64) {
+ gen_expr64(&ops[i].e);
+#endif
+ } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) {
+ gen_disp32(&ops[i].e);
+ } else {
+ gen_expr32(&ops[i].e);
+ }
+ }
+ }
+
+ /* after immediate operands, adjust pc-relative address */
+ if (pc)
+ add32le(cur_text_section->data + pc - 4, pc - ind);
+}
+
+/* return the constraint priority (we allocate first the lowest
+ numbered constraints) */
+static inline int constraint_priority(const char *str)
+{
+ int priority, c, pr;
+
+ /* we take the lowest priority */
+ priority = 0;
+ for(;;) {
+ c = *str;
+ if (c == '\0')
+ break;
+ str++;
+ switch(c) {
+ case 'A':
+ pr = 0;
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'S':
+ case 'D':
+ pr = 1;
+ break;
+ case 'q':
+ pr = 2;
+ break;
+ case 'r':
+ case 'R':
+ case 'p':
+ pr = 3;
+ break;
+ case 'N':
+ case 'M':
+ case 'I':
+ case 'e':
+ case 'i':
+ case 'm':
+ case 'g':
+ pr = 4;
+ break;
+ default:
+ tcc_error("unknown constraint '%c'", c);
+ pr = 0;
+ }
+ if (pr > priority)
+ priority = pr;
+ }
+ return priority;
+}
+
+static const char *skip_constraint_modifiers(const char *p)
+{
+ while (*p == '=' || *p == '&' || *p == '+' || *p == '%')
+ p++;
+ return p;
+}
+
+/* If T (a token) is of the form "%reg" returns the register
+ number and type, otherwise return -1. */
+ST_FUNC int asm_parse_regvar (int t)
+{
+ const char *s;
+ Operand op;
+ if (t < TOK_IDENT)
+ return -1;
+ s = table_ident[t - TOK_IDENT]->str;
+ if (s[0] != '%')
+ return -1;
+ t = tok_alloc(s+1, strlen(s)-1)->tok;
+ unget_tok(t);
+ unget_tok('%');
+ parse_operand(tcc_state, &op);
+ /* Accept only integer regs for now. */
+ if (op.type & OP_REG)
+ return op.reg;
+ else
+ return -1;
+}
+
+#define REG_OUT_MASK 0x01
+#define REG_IN_MASK 0x02
+
+#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
+
+ST_FUNC void asm_compute_constraints(ASMOperand *operands,
+ int nb_operands, int nb_outputs,
+ const uint8_t *clobber_regs,
+ int *pout_reg)
+{
+ ASMOperand *op;
+ int sorted_op[MAX_ASM_OPERANDS];
+ int i, j, k, p1, p2, tmp, reg, c, reg_mask;
+ const char *str;
+ uint8_t regs_allocated[NB_ASM_REGS];
+
+ /* init fields */
+ for(i=0;i<nb_operands;i++) {
+ op = &operands[i];
+ op->input_index = -1;
+ op->ref_index = -1;
+ op->reg = -1;
+ op->is_memory = 0;
+ op->is_rw = 0;
+ }
+ /* compute constraint priority and evaluate references to output
+ constraints if input constraints */
+ for(i=0;i<nb_operands;i++) {
+ op = &operands[i];
+ str = op->constraint;
+ str = skip_constraint_modifiers(str);
+ if (isnum(*str) || *str == '[') {
+ /* this is a reference to another constraint */
+ k = find_constraint(operands, nb_operands, str, NULL);
+ if ((unsigned)k >= i || i < nb_outputs)
+ tcc_error("invalid reference in constraint %d ('%s')",
+ i, str);
+ op->ref_index = k;
+ if (operands[k].input_index >= 0)
+ tcc_error("cannot reference twice the same operand");
+ operands[k].input_index = i;
+ op->priority = 5;
+ } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL
+ && op->vt->sym
+ && (reg = op->vt->sym->r & VT_VALMASK) < VT_CONST) {
+ op->priority = 1;
+ op->reg = reg;
+ } else {
+ op->priority = constraint_priority(str);
+ }
+ }
+
+ /* sort operands according to their priority */
+ for(i=0;i<nb_operands;i++)
+ sorted_op[i] = i;
+ for(i=0;i<nb_operands - 1;i++) {
+ for(j=i+1;j<nb_operands;j++) {
+ p1 = operands[sorted_op[i]].priority;
+ p2 = operands[sorted_op[j]].priority;
+ if (p2 < p1) {
+ tmp = sorted_op[i];
+ sorted_op[i] = sorted_op[j];
+ sorted_op[j] = tmp;
+ }
+ }
+ }
+
+ for(i = 0;i < NB_ASM_REGS; i++) {
+ if (clobber_regs[i])
+ regs_allocated[i] = REG_IN_MASK | REG_OUT_MASK;
+ else
+ regs_allocated[i] = 0;
+ }
+ /* esp cannot be used */
+ regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK;
+ /* ebp cannot be used yet */
+ regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK;
+
+ /* allocate registers and generate corresponding asm moves */
+ for(i=0;i<nb_operands;i++) {
+ j = sorted_op[i];
+ op = &operands[j];
+ str = op->constraint;
+ /* no need to allocate references */
+ if (op->ref_index >= 0)
+ continue;
+ /* select if register is used for output, input or both */
+ if (op->input_index >= 0) {
+ reg_mask = REG_IN_MASK | REG_OUT_MASK;
+ } else if (j < nb_outputs) {
+ reg_mask = REG_OUT_MASK;
+ } else {
+ reg_mask = REG_IN_MASK;
+ }
+ if (op->reg >= 0) {
+ if (is_reg_allocated(op->reg))
+ tcc_error("asm regvar requests register that's taken already");
+ reg = op->reg;
+ goto reg_found;
+ }
+ try_next:
+ c = *str++;
+ switch(c) {
+ case '=':
+ goto try_next;
+ case '+':
+ op->is_rw = 1;
+ /* FALL THRU */
+ case '&':
+ if (j >= nb_outputs)
+ tcc_error("'%c' modifier can only be applied to outputs", c);
+ reg_mask = REG_IN_MASK | REG_OUT_MASK;
+ goto try_next;
+ case 'A':
+ /* allocate both eax and edx */
+ if (is_reg_allocated(TREG_XAX) ||
+ is_reg_allocated(TREG_XDX))
+ goto try_next;
+ op->is_llong = 1;
+ op->reg = TREG_XAX;
+ regs_allocated[TREG_XAX] |= reg_mask;
+ regs_allocated[TREG_XDX] |= reg_mask;
+ break;
+ case 'a':
+ reg = TREG_XAX;
+ goto alloc_reg;
+ case 'b':
+ reg = 3;
+ goto alloc_reg;
+ case 'c':
+ reg = TREG_XCX;
+ goto alloc_reg;
+ case 'd':
+ reg = TREG_XDX;
+ goto alloc_reg;
+ case 'S':
+ reg = 6;
+ goto alloc_reg;
+ case 'D':
+ reg = 7;
+ alloc_reg:
+ if (is_reg_allocated(reg))
+ goto try_next;
+ goto reg_found;
+ case 'q':
+ /* eax, ebx, ecx or edx */
+ for(reg = 0; reg < 4; reg++) {
+ if (!is_reg_allocated(reg))
+ goto reg_found;
+ }
+ goto try_next;
+ case 'r':
+ case 'R':
+ case 'p': /* A general address, for x86(64) any register is acceptable*/
+ /* any general register */
+ for(reg = 0; reg < 8; reg++) {
+ if (!is_reg_allocated(reg))
+ goto reg_found;
+ }
+ goto try_next;
+ reg_found:
+ /* now we can reload in the register */
+ op->is_llong = 0;
+ op->reg = reg;
+ regs_allocated[reg] |= reg_mask;
+ break;
+ case 'e':
+ case 'i':
+ if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
+ goto try_next;
+ break;
+ case 'I':
+ case 'N':
+ case 'M':
+ if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST))
+ goto try_next;
+ break;
+ case 'm':
+ case 'g':
+ /* nothing special to do because the operand is already in
+ memory, except if the pointer itself is stored in a
+ memory variable (VT_LLOCAL case) */
+ /* XXX: fix constant case */
+ /* if it is a reference to a memory zone, it must lie
+ in a register, so we reserve the register in the
+ input registers and a load will be generated
+ later */
+ if (j < nb_outputs || c == 'm') {
+ if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
+ /* any general register */
+ for(reg = 0; reg < 8; reg++) {
+ if (!(regs_allocated[reg] & REG_IN_MASK))
+ goto reg_found1;
+ }
+ goto try_next;
+ reg_found1:
+ /* now we can reload in the register */
+ regs_allocated[reg] |= REG_IN_MASK;
+ op->reg = reg;
+ op->is_memory = 1;
+ }
+ }
+ break;
+ default:
+ tcc_error("asm constraint %d ('%s') could not be satisfied",
+ j, op->constraint);
+ break;
+ }
+ /* if a reference is present for that operand, we assign it too */
+ if (op->input_index >= 0) {
+ operands[op->input_index].reg = op->reg;
+ operands[op->input_index].is_llong = op->is_llong;
+ }
+ }
+
+ /* compute out_reg. It is used to store outputs registers to memory
+ locations references by pointers (VT_LLOCAL case) */
+ *pout_reg = -1;
+ for(i=0;i<nb_operands;i++) {
+ op = &operands[i];
+ if (op->reg >= 0 &&
+ (op->vt->r & VT_VALMASK) == VT_LLOCAL &&
+ !op->is_memory) {
+ for(reg = 0; reg < 8; reg++) {
+ if (!(regs_allocated[reg] & REG_OUT_MASK))
+ goto reg_found2;
+ }
+ tcc_error("could not find free output register for reloading");
+ reg_found2:
+ *pout_reg = reg;
+ break;
+ }
+ }
+
+ /* print sorted constraints */
+#ifdef ASM_DEBUG
+ for(i=0;i<nb_operands;i++) {
+ j = sorted_op[i];
+ op = &operands[j];
+ printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",
+ j,
+ op->id ? get_tok_str(op->id, NULL) : "",
+ op->constraint,
+ op->vt->r,
+ op->reg);
+ }
+ if (*pout_reg >= 0)
+ printf("out_reg=%d\n", *pout_reg);
+#endif
+}
+
+ST_FUNC void subst_asm_operand(CString *add_str,
+ SValue *sv, int modifier)
+{
+ int r, reg, size, val;
+ char buf[64];
+
+ r = sv->r;
+ if ((r & VT_VALMASK) == VT_CONST) {
+ if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' &&
+ modifier != 'P')
+ cstr_ccat(add_str, '$');
+ if (r & VT_SYM) {
+ const char *name = get_tok_str(sv->sym->v, NULL);
+ if (sv->sym->v >= SYM_FIRST_ANOM) {
+ /* In case of anonymous symbols ("L.42", used
+ for static data labels) we can't find them
+ in the C symbol table when later looking up
+ this name. So enter them now into the asm label
+ list when we still know the symbol. */
+ get_asm_sym(tok_alloc(name, strlen(name))->tok, sv->sym);
+ }
+ cstr_cat(add_str, name, -1);
+ if ((uint32_t)sv->c.i == 0)
+ goto no_offset;
+ cstr_ccat(add_str, '+');
+ }
+ val = sv->c.i;
+ if (modifier == 'n')
+ val = -val;
+ snprintf(buf, sizeof(buf), "%d", (int)sv->c.i);
+ cstr_cat(add_str, buf, -1);
+ no_offset:;
+#ifdef TCC_TARGET_X86_64
+ if (r & VT_LVAL)
+ cstr_cat(add_str, "(%rip)", -1);
+#endif
+ } else if ((r & VT_VALMASK) == VT_LOCAL) {
+#ifdef TCC_TARGET_X86_64
+ snprintf(buf, sizeof(buf), "%d(%%rbp)", (int)sv->c.i);
+#else
+ snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i);
+#endif
+ cstr_cat(add_str, buf, -1);
+ } else if (r & VT_LVAL) {
+ reg = r & VT_VALMASK;
+ if (reg >= VT_CONST)
+ tcc_error("internal compiler error");
+ snprintf(buf, sizeof(buf), "(%%%s)",
+#ifdef TCC_TARGET_X86_64
+ get_tok_str(TOK_ASM_rax + reg, NULL)
+#else
+ get_tok_str(TOK_ASM_eax + reg, NULL)
+#endif
+ );
+ cstr_cat(add_str, buf, -1);
+ } else {
+ /* register case */
+ reg = r & VT_VALMASK;
+ if (reg >= VT_CONST)
+ tcc_error("internal compiler error");
+
+ /* choose register operand size */
+ if ((sv->type.t & VT_BTYPE) == VT_BYTE ||
+ (sv->type.t & VT_BTYPE) == VT_BOOL)
+ size = 1;
+ else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
+ size = 2;
+#ifdef TCC_TARGET_X86_64
+ else if ((sv->type.t & VT_BTYPE) == VT_LLONG ||
+ (sv->type.t & VT_BTYPE) == VT_PTR)
+ size = 8;
+#endif
+ else
+ size = 4;
+ if (size == 1 && reg >= 4)
+ size = 4;
+
+ if (modifier == 'b') {
+ if (reg >= 4)
+ tcc_error("cannot use byte register");
+ size = 1;
+ } else if (modifier == 'h') {
+ if (reg >= 4)
+ tcc_error("cannot use byte register");
+ size = -1;
+ } else if (modifier == 'w') {
+ size = 2;
+ } else if (modifier == 'k') {
+ size = 4;
+#ifdef TCC_TARGET_X86_64
+ } else if (modifier == 'q') {
+ size = 8;
+#endif
+ }
+
+ switch(size) {
+ case -1:
+ reg = TOK_ASM_ah + reg;
+ break;
+ case 1:
+ reg = TOK_ASM_al + reg;
+ break;
+ case 2:
+ reg = TOK_ASM_ax + reg;
+ break;
+ default:
+ reg = TOK_ASM_eax + reg;
+ break;
+#ifdef TCC_TARGET_X86_64
+ case 8:
+ reg = TOK_ASM_rax + reg;
+ break;
+#endif
+ }
+ snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
+ cstr_cat(add_str, buf, -1);
+ }
+}
+
+/* generate prolog and epilog code for asm statement */
+ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
+ int nb_outputs, int is_output,
+ uint8_t *clobber_regs,
+ int out_reg)
+{
+ uint8_t regs_allocated[NB_ASM_REGS];
+ ASMOperand *op;
+ int i, reg;
+
+ /* Strictly speaking %Xbp and %Xsp should be included in the
+ call-preserved registers, but currently it doesn't matter. */
+#ifdef TCC_TARGET_X86_64
+#ifdef TCC_TARGET_PE
+ static uint8_t reg_saved[] = { 3, 6, 7, 12, 13, 14, 15 };
+#else
+ static uint8_t reg_saved[] = { 3, 12, 13, 14, 15 };
+#endif
+#else
+ static uint8_t reg_saved[] = { 3, 6, 7 };
+#endif
+
+ /* mark all used registers */
+ memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated));
+ for(i = 0; i < nb_operands;i++) {
+ op = &operands[i];
+ if (op->reg >= 0)
+ regs_allocated[op->reg] = 1;
+ }
+ if (!is_output) {
+ /* generate reg save code */
+ for(i = 0; i < sizeof(reg_saved)/sizeof(reg_saved[0]); i++) {
+ reg = reg_saved[i];
+ if (regs_allocated[reg]) {
+ if (reg >= 8)
+ g(0x41), reg-=8;
+ g(0x50 + reg);
+ }
+ }
+
+ /* generate load code */
+ for(i = 0; i < nb_operands; i++) {
+ op = &operands[i];
+ if (op->reg >= 0) {
+ if ((op->vt->r & VT_VALMASK) == VT_LLOCAL &&
+ op->is_memory) {
+ /* memory reference case (for both input and
+ output cases) */
+ SValue sv;
+ sv = *op->vt;
+ sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
+ sv.type.t = VT_PTR;
+ load(op->reg, &sv);
+ } else if (i >= nb_outputs || op->is_rw) {
+ /* load value in register */
+ load(op->reg, op->vt);
+ if (op->is_llong) {
+ SValue sv;
+ sv = *op->vt;
+ sv.c.i += 4;
+ load(TREG_XDX, &sv);
+ }
+ }
+ }
+ }
+ } else {
+ /* generate save code */
+ for(i = 0 ; i < nb_outputs; i++) {
+ op = &operands[i];
+ if (op->reg >= 0) {
+ if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
+ if (!op->is_memory) {
+ SValue sv;
+ sv = *op->vt;
+ sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
+ sv.type.t = VT_PTR;
+ load(out_reg, &sv);
+
+ sv = *op->vt;
+ sv.r = (sv.r & ~VT_VALMASK) | out_reg;
+ store(op->reg, &sv);
+ }
+ } else {
+ store(op->reg, op->vt);
+ if (op->is_llong) {
+ SValue sv;
+ sv = *op->vt;
+ sv.c.i += 4;
+ store(TREG_XDX, &sv);
+ }
+ }
+ }
+ }
+ /* generate reg restore code */
+ for(i = sizeof(reg_saved)/sizeof(reg_saved[0]) - 1; i >= 0; i--) {
+ reg = reg_saved[i];
+ if (regs_allocated[reg]) {
+ if (reg >= 8)
+ g(0x41), reg-=8;
+ g(0x58 + reg);
+ }
+ }
+ }
+}
+
+ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
+{
+ int reg;
+ TokenSym *ts;
+#ifdef TCC_TARGET_X86_64
+ unsigned int type;
+#endif
+
+ if (!strcmp(str, "memory") ||
+ !strcmp(str, "cc") ||
+ !strcmp(str, "flags"))
+ return;
+ ts = tok_alloc(str, strlen(str));
+ reg = ts->tok;
+ if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {
+ reg -= TOK_ASM_eax;
+ } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {
+ reg -= TOK_ASM_ax;
+#ifdef TCC_TARGET_X86_64
+ } else if (reg >= TOK_ASM_rax && reg <= TOK_ASM_rdi) {
+ reg -= TOK_ASM_rax;
+ } else if ((reg = asm_parse_numeric_reg(reg, &type)) >= 0) {
+ ;
+#endif
+ } else {
+ tcc_error("invalid clobber register '%s'", str);
+ }
+ clobber_regs[reg] = 1;
+}
diff --git a/i386-asm.h b/i386-asm.h
new file mode 100644
index 0000000..65d5179
--- /dev/null
+++ b/i386-asm.h
@@ -0,0 +1,480 @@
+ DEF_ASM_OP0(clc, 0xf8) /* must be first OP0 */
+ DEF_ASM_OP0(cld, 0xfc)
+ DEF_ASM_OP0(cli, 0xfa)
+ DEF_ASM_OP0(clts, 0x0f06)
+ DEF_ASM_OP0(cmc, 0xf5)
+ DEF_ASM_OP0(lahf, 0x9f)
+ DEF_ASM_OP0(sahf, 0x9e)
+ DEF_ASM_OP0(pusha, 0x60)
+ DEF_ASM_OP0(popa, 0x61)
+ DEF_ASM_OP0(pushfl, 0x9c)
+ DEF_ASM_OP0(popfl, 0x9d)
+ DEF_ASM_OP0(pushf, 0x9c)
+ DEF_ASM_OP0(popf, 0x9d)
+ DEF_ASM_OP0(stc, 0xf9)
+ DEF_ASM_OP0(std, 0xfd)
+ DEF_ASM_OP0(sti, 0xfb)
+ DEF_ASM_OP0(aaa, 0x37)
+ DEF_ASM_OP0(aas, 0x3f)
+ DEF_ASM_OP0(daa, 0x27)
+ DEF_ASM_OP0(das, 0x2f)
+ DEF_ASM_OP0(aad, 0xd50a)
+ DEF_ASM_OP0(aam, 0xd40a)
+ DEF_ASM_OP0(cbw, 0x6698)
+ DEF_ASM_OP0(cwd, 0x6699)
+ DEF_ASM_OP0(cwde, 0x98)
+ DEF_ASM_OP0(cdq, 0x99)
+ DEF_ASM_OP0(cbtw, 0x6698)
+ DEF_ASM_OP0(cwtl, 0x98)
+ DEF_ASM_OP0(cwtd, 0x6699)
+ DEF_ASM_OP0(cltd, 0x99)
+ DEF_ASM_OP0(int3, 0xcc)
+ DEF_ASM_OP0(into, 0xce)
+ DEF_ASM_OP0(iret, 0xcf)
+ DEF_ASM_OP0(rsm, 0x0faa)
+ DEF_ASM_OP0(hlt, 0xf4)
+ DEF_ASM_OP0(nop, 0x90)
+ DEF_ASM_OP0(pause, 0xf390)
+ DEF_ASM_OP0(xlat, 0xd7)
+
+ /* strings */
+ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
+
+ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLX))
+
+ /* bits */
+
+ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+
+ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ /* prefixes */
+ DEF_ASM_OP0(wait, 0x9b)
+ DEF_ASM_OP0(fwait, 0x9b)
+ DEF_ASM_OP0(aword, 0x67)
+ DEF_ASM_OP0(addr16, 0x67)
+ ALT(DEF_ASM_OP0(word, 0x66))
+ DEF_ASM_OP0(data16, 0x66)
+ DEF_ASM_OP0(lock, 0xf0)
+ DEF_ASM_OP0(rep, 0xf3)
+ DEF_ASM_OP0(repe, 0xf3)
+ DEF_ASM_OP0(repz, 0xf3)
+ DEF_ASM_OP0(repne, 0xf2)
+ DEF_ASM_OP0(repnz, 0xf2)
+
+ DEF_ASM_OP0(invd, 0x0f08)
+ DEF_ASM_OP0(wbinvd, 0x0f09)
+ DEF_ASM_OP0(cpuid, 0x0fa2)
+ DEF_ASM_OP0(wrmsr, 0x0f30)
+ DEF_ASM_OP0(rdtsc, 0x0f31)
+ DEF_ASM_OP0(rdmsr, 0x0f32)
+ DEF_ASM_OP0(rdpmc, 0x0f33)
+ DEF_ASM_OP0(ud2, 0x0f0b)
+
+ /* NOTE: we took the same order as gas opcode definition order */
+ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLX, OPT_ADDR, OPT_EAX))
+ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLX, OPT_EAX, OPT_ADDR))
+ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLX, OPT_IM, OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLX, OPT_SEG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_SEG))
+
+ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLX, OPT_CR, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLX, OPT_DB, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WLX, OPT_TR, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_CR))
+ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_DB))
+ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_TR))
+
+ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movsbw, 0x660fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG16))
+ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WLX, OPT_REG8 | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
+
+ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WLX, OPT_IM8S))
+ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLX, OPT_IM32))
+ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_REGW, OPT_EAX))
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_EAX, OPT_REGW))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+
+ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
+ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
+ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
+ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
+
+ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
+ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
+ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
+ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
+
+ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLX, OPT_EA, OPT_REG))
+
+ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+
+ /* arith */
+ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
+ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW))
+ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW))
+
+ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
+ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
+
+ /* shifts */
+ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
+
+ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
+ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP))
+ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
+ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8))
+
+ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
+ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
+ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA))
+
+ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
+ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
+ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
+ DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
+ DEF_ASM_OP0(leave, 0xc9)
+ DEF_ASM_OP0(ret, 0xc3)
+ DEF_ASM_OP0(retl,0xc3)
+ALT(DEF_ASM_OP1(retl,0xc2, 0, 0, OPT_IM16))
+ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
+ DEF_ASM_OP0(lret, 0xcb)
+ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
+
+ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8))
+ DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8)
+ DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8)
+ DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8)
+ DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8)
+ DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8)
+ DEF_ASM_OP1(jecxz, 0xe3, 0, 0, OPT_DISP8)
+
+ /* float */
+ /* specific fcomp handling */
+ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
+
+ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
+ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
+ALT(DEF_ASM_OP2(fadd, 0xdcc0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP2(fmul, 0xdcc8, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
+ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
+ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
+ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
+ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+
+ DEF_ASM_OP0(fucompp, 0xdae9)
+ DEF_ASM_OP0(ftst, 0xd9e4)
+ DEF_ASM_OP0(fxam, 0xd9e5)
+ DEF_ASM_OP0(fld1, 0xd9e8)
+ DEF_ASM_OP0(fldl2t, 0xd9e9)
+ DEF_ASM_OP0(fldl2e, 0xd9ea)
+ DEF_ASM_OP0(fldpi, 0xd9eb)
+ DEF_ASM_OP0(fldlg2, 0xd9ec)
+ DEF_ASM_OP0(fldln2, 0xd9ed)
+ DEF_ASM_OP0(fldz, 0xd9ee)
+
+ DEF_ASM_OP0(f2xm1, 0xd9f0)
+ DEF_ASM_OP0(fyl2x, 0xd9f1)
+ DEF_ASM_OP0(fptan, 0xd9f2)
+ DEF_ASM_OP0(fpatan, 0xd9f3)
+ DEF_ASM_OP0(fxtract, 0xd9f4)
+ DEF_ASM_OP0(fprem1, 0xd9f5)
+ DEF_ASM_OP0(fdecstp, 0xd9f6)
+ DEF_ASM_OP0(fincstp, 0xd9f7)
+ DEF_ASM_OP0(fprem, 0xd9f8)
+ DEF_ASM_OP0(fyl2xp1, 0xd9f9)
+ DEF_ASM_OP0(fsqrt, 0xd9fa)
+ DEF_ASM_OP0(fsincos, 0xd9fb)
+ DEF_ASM_OP0(frndint, 0xd9fc)
+ DEF_ASM_OP0(fscale, 0xd9fd)
+ DEF_ASM_OP0(fsin, 0xd9fe)
+ DEF_ASM_OP0(fcos, 0xd9ff)
+ DEF_ASM_OP0(fchs, 0xd9e0)
+ DEF_ASM_OP0(fabs, 0xd9e1)
+ DEF_ASM_OP0(fninit, 0xdbe3)
+ DEF_ASM_OP0(fnclex, 0xdbe2)
+ DEF_ASM_OP0(fnop, 0xd9d0)
+
+ /* fp load */
+ DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
+ DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
+ DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
+ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
+ DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
+ DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
+
+ /* fp store */
+ DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
+ DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
+ DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
+ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
+ DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
+
+ DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
+ DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
+
+ /* exchange */
+ DEF_ASM_OP0(fxch, 0xd9c9)
+ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
+
+ /* misc FPU */
+ DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
+ DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
+
+ DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
+ DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
+ DEF_ASM_OP0(fnstsw, 0xdfe0)
+ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
+ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
+ DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
+ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
+ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
+ DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
+ DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
+ DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
+ DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
+ DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
+ DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
+
+ /* segments */
+ DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
+ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
+ DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
+ DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
+ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_REG))
+ DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
+ DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
+ DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
+ DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
+ DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
+ DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
+
+ /* 486 */
+ DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
+ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
+ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
+ DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
+
+ DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
+ DEF_ASM_OP2(boundw, 0x6662, 0, OPC_MODRM, OPT_REG16, OPT_EA)
+
+ /* pentium */
+ DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
+
+ /* pentium pro */
+ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+ DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+
+ DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+
+ /* mmx */
+ DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
+ DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMXSSE )
+ DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG32 ))
+ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
+ALT(DEF_ASM_OP2(movq, 0x660fd6, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_SSE ))
+ALT(DEF_ASM_OP2(movq, 0xf30f7e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ))
+
+ DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+
+ /* sse */
+ DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+ DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+ DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+ DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE )
+ DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+ DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+ DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+
+#undef ALT
+#undef DEF_ASM_OP0
+#undef DEF_ASM_OP0L
+#undef DEF_ASM_OP1
+#undef DEF_ASM_OP2
+#undef DEF_ASM_OP3
diff --git a/i386-gen.c b/i386-gen.c
new file mode 100644
index 0000000..b9c3599
--- /dev/null
+++ b/i386-gen.c
@@ -0,0 +1,1164 @@
+/*
+ * X86 code generator for TCC
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+/* number of available registers */
+#define NB_REGS 5
+#define NB_ASM_REGS 8
+#define CONFIG_TCC_ASM
+
+/* a register can belong to several classes. The classes must be
+ sorted from more general to more precise (see gv2() code which does
+ assumptions on it). */
+#define RC_INT 0x0001 /* generic integer register */
+#define RC_FLOAT 0x0002 /* generic float register */
+#define RC_EAX 0x0004
+#define RC_ST0 0x0008
+#define RC_ECX 0x0010
+#define RC_EDX 0x0020
+#define RC_EBX 0x0040
+
+#define RC_IRET RC_EAX /* function return: integer register */
+#define RC_LRET RC_EDX /* function return: second integer register */
+#define RC_FRET RC_ST0 /* function return: float register */
+
+/* pretty names for the registers */
+enum {
+ TREG_EAX = 0,
+ TREG_ECX,
+ TREG_EDX,
+ TREG_EBX,
+ TREG_ST0,
+ TREG_ESP = 4
+};
+
+/* return registers for function */
+#define REG_IRET TREG_EAX /* single word int return register */
+#define REG_LRET TREG_EDX /* second word return register (for long long) */
+#define REG_FRET TREG_ST0 /* float return register */
+
+/* defined if function parameters must be evaluated in reverse order */
+#define INVERT_FUNC_PARAMS
+
+/* defined if structures are passed as pointers. Otherwise structures
+ are directly pushed on stack. */
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE 12
+#define LDOUBLE_ALIGN 4
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN 8
+
+/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+
+/* define to 1/0 to [not] have EBX as 4th register */
+#define USE_EBX 0
+
+ST_DATA const int reg_classes[NB_REGS] = {
+ /* eax */ RC_INT | RC_EAX,
+ /* ecx */ RC_INT | RC_ECX,
+ /* edx */ RC_INT | RC_EDX,
+ /* ebx */ (RC_INT | RC_EBX) * USE_EBX,
+ /* st0 */ RC_FLOAT | RC_ST0,
+};
+
+static unsigned long func_sub_sp_offset;
+static int func_ret_sub;
+#ifdef CONFIG_TCC_BCHECK
+static addr_t func_bound_offset;
+static unsigned long func_bound_ind;
+#endif
+
+/* XXX: make it faster ? */
+ST_FUNC void g(int c)
+{
+ int ind1;
+ if (nocode_wanted)
+ return;
+ ind1 = ind + 1;
+ if (ind1 > cur_text_section->data_allocated)
+ section_realloc(cur_text_section, ind1);
+ cur_text_section->data[ind] = c;
+ ind = ind1;
+}
+
+ST_FUNC void o(unsigned int c)
+{
+ while (c) {
+ g(c);
+ c = c >> 8;
+ }
+}
+
+ST_FUNC void gen_le16(int v)
+{
+ g(v);
+ g(v >> 8);
+}
+
+ST_FUNC void gen_le32(int c)
+{
+ g(c);
+ g(c >> 8);
+ g(c >> 16);
+ g(c >> 24);
+}
+
+/* output a symbol and patch all calls to it */
+ST_FUNC void gsym_addr(int t, int a)
+{
+ while (t) {
+ unsigned char *ptr = cur_text_section->data + t;
+ uint32_t n = read32le(ptr); /* next value */
+ write32le(ptr, a - t - 4);
+ t = n;
+ }
+}
+
+ST_FUNC void gsym(int t)
+{
+ gsym_addr(t, ind);
+}
+
+/* instruction + 4 bytes data. Return the address of the data */
+static int oad(int c, int s)
+{
+ int t;
+ if (nocode_wanted)
+ return s;
+ o(c);
+ t = ind;
+ gen_le32(s);
+ return t;
+}
+
+/* generate jmp to a label */
+#define gjmp2(instr,lbl) oad(instr,lbl)
+
+/* output constant with relocation if 'r & VT_SYM' is true */
+ST_FUNC void gen_addr32(int r, Sym *sym, int c)
+{
+ if (r & VT_SYM)
+ greloc(cur_text_section, sym, ind, R_386_32);
+ gen_le32(c);
+}
+
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
+{
+ if (r & VT_SYM)
+ greloc(cur_text_section, sym, ind, R_386_PC32);
+ gen_le32(c - 4);
+}
+
+/* generate a modrm reference. 'op_reg' contains the additional 3
+ opcode bits */
+static void gen_modrm(int op_reg, int r, Sym *sym, int c)
+{
+ op_reg = op_reg << 3;
+ if ((r & VT_VALMASK) == VT_CONST) {
+ /* constant memory reference */
+ o(0x05 | op_reg);
+ gen_addr32(r, sym, c);
+ } else if ((r & VT_VALMASK) == VT_LOCAL) {
+ /* currently, we use only ebp as base */
+ if (c == (char)c) {
+ /* short reference */
+ o(0x45 | op_reg);
+ g(c);
+ } else {
+ oad(0x85 | op_reg, c);
+ }
+ } else {
+ g(0x00 | op_reg | (r & VT_VALMASK));
+ }
+}
+
+/* load 'r' from value 'sv' */
+ST_FUNC void load(int r, SValue *sv)
+{
+ int v, t, ft, fc, fr;
+ SValue v1;
+
+#ifdef TCC_TARGET_PE
+ SValue v2;
+ sv = pe_getimport(sv, &v2);
+#endif
+
+ fr = sv->r;
+ ft = sv->type.t & ~VT_DEFSIGN;
+ fc = sv->c.i;
+
+ ft &= ~(VT_VOLATILE | VT_CONSTANT);
+
+ v = fr & VT_VALMASK;
+ if (fr & VT_LVAL) {
+ if (v == VT_LLOCAL) {
+ v1.type.t = VT_INT;
+ v1.r = VT_LOCAL | VT_LVAL;
+ v1.c.i = fc;
+ fr = r;
+ if (!(reg_classes[fr] & RC_INT))
+ fr = get_reg(RC_INT);
+ load(fr, &v1);
+ }
+ if ((ft & VT_BTYPE) == VT_FLOAT) {
+ o(0xd9); /* flds */
+ r = 0;
+ } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+ o(0xdd); /* fldl */
+ r = 0;
+ } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+ o(0xdb); /* fldt */
+ r = 5;
+ } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
+ o(0xbe0f); /* movsbl */
+ } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
+ o(0xb60f); /* movzbl */
+ } else if ((ft & VT_TYPE) == VT_SHORT) {
+ o(0xbf0f); /* movswl */
+ } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
+ o(0xb70f); /* movzwl */
+ } else {
+ o(0x8b); /* movl */
+ }
+ gen_modrm(r, fr, sv->sym, fc);
+ } else {
+ if (v == VT_CONST) {
+ o(0xb8 + r); /* mov $xx, r */
+ gen_addr32(fr, sv->sym, fc);
+ } else if (v == VT_LOCAL) {
+ if (fc) {
+ o(0x8d); /* lea xxx(%ebp), r */
+ gen_modrm(r, VT_LOCAL, sv->sym, fc);
+ } else {
+ o(0x89);
+ o(0xe8 + r); /* mov %ebp, r */
+ }
+ } else if (v == VT_CMP) {
+ oad(0xb8 + r, 0); /* mov $0, r */
+ o(0x0f); /* setxx %br */
+ o(fc);
+ o(0xc0 + r);
+ } else if (v == VT_JMP || v == VT_JMPI) {
+ t = v & 1;
+ oad(0xb8 + r, t); /* mov $1, r */
+ o(0x05eb); /* jmp after */
+ gsym(fc);
+ oad(0xb8 + r, t ^ 1); /* mov $0, r */
+ } else if (v != r) {
+ o(0x89);
+ o(0xc0 + r + v * 8); /* mov v, r */
+ }
+ }
+}
+
+/* store register 'r' in lvalue 'v' */
+ST_FUNC void store(int r, SValue *v)
+{
+ int fr, bt, ft, fc;
+
+#ifdef TCC_TARGET_PE
+ SValue v2;
+ v = pe_getimport(v, &v2);
+#endif
+
+ ft = v->type.t;
+ fc = v->c.i;
+ fr = v->r & VT_VALMASK;
+ ft &= ~(VT_VOLATILE | VT_CONSTANT);
+ bt = ft & VT_BTYPE;
+ /* XXX: incorrect if float reg to reg */
+ if (bt == VT_FLOAT) {
+ o(0xd9); /* fsts */
+ r = 2;
+ } else if (bt == VT_DOUBLE) {
+ o(0xdd); /* fstpl */
+ r = 2;
+ } else if (bt == VT_LDOUBLE) {
+ o(0xc0d9); /* fld %st(0) */
+ o(0xdb); /* fstpt */
+ r = 7;
+ } else {
+ if (bt == VT_SHORT)
+ o(0x66);
+ if (bt == VT_BYTE || bt == VT_BOOL)
+ o(0x88);
+ else
+ o(0x89);
+ }
+ if (fr == VT_CONST ||
+ fr == VT_LOCAL ||
+ (v->r & VT_LVAL)) {
+ gen_modrm(r, v->r, v->sym, fc);
+ } else if (fr != r) {
+ o(0xc0 + fr + r * 8); /* mov r, fr */
+ }
+}
+
+static void gadd_sp(int val)
+{
+ if (val == (char)val) {
+ o(0xc483);
+ g(val);
+ } else {
+ oad(0xc481, val); /* add $xxx, %esp */
+ }
+}
+
+#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE
+static void gen_static_call(int v)
+{
+ Sym *sym;
+
+ sym = external_global_sym(v, &func_old_type, 0);
+ oad(0xe8, -4);
+ greloc(cur_text_section, sym, ind-4, R_386_PC32);
+}
+#endif
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+ int r;
+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
+ /* constant and relocation case */
+ greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32);
+ oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
+ } else {
+ /* otherwise, indirect call */
+ r = gv(RC_INT);
+ o(0xff); /* call/jmp *r */
+ o(0xd0 + r + (is_jmp << 4));
+ }
+ if (!is_jmp) {
+ int rt;
+ /* extend the return value to the whole register if necessary
+ visual studio and gcc do not always set the whole eax register
+ when assigning the return value of a function */
+ rt = vtop->type.ref->type.t;
+ switch (rt & VT_BTYPE) {
+ case VT_BYTE:
+ if (rt & VT_UNSIGNED) {
+ o(0xc0b60f); /* movzx %al, %eax */
+ }
+ else {
+ o(0xc0be0f); /* movsx %al, %eax */
+ }
+ break;
+ case VT_SHORT:
+ if (rt & VT_UNSIGNED) {
+ o(0xc0b70f); /* movzx %ax, %eax */
+ }
+ else {
+ o(0xc0bf0f); /* movsx %ax, %eax */
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
+static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX };
+
+/* Return the number of registers needed to return the struct, or 0 if
+ returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
+{
+#ifdef TCC_TARGET_PE
+ int size, align;
+ *ret_align = 1; // Never have to re-align return values for x86
+ *regsize = 4;
+ size = type_size(vt, &align);
+ if (size > 8 || (size & (size - 1)))
+ return 0;
+ if (size == 8)
+ ret->t = VT_LLONG;
+ else if (size == 4)
+ ret->t = VT_INT;
+ else if (size == 2)
+ ret->t = VT_SHORT;
+ else
+ ret->t = VT_BYTE;
+ ret->ref = NULL;
+ return 1;
+#else
+ *ret_align = 1; // Never have to re-align return values for x86
+ return 0;
+#endif
+}
+
+/* Generate function call. The function address is pushed first, then
+ all the parameters in call order. This functions pops all the
+ parameters and the function address. */
+ST_FUNC void gfunc_call(int nb_args)
+{
+ int size, align, r, args_size, i, func_call;
+ Sym *func_sym;
+
+ args_size = 0;
+ for(i = 0;i < nb_args; i++) {
+ if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+ size = type_size(&vtop->type, &align);
+ /* align to stack align size */
+ size = (size + 3) & ~3;
+ /* allocate the necessary size on stack */
+ oad(0xec81, size); /* sub $xxx, %esp */
+ /* generate structure store */
+ r = get_reg(RC_INT);
+ o(0x89); /* mov %esp, r */
+ o(0xe0 + r);
+ vset(&vtop->type, r | VT_LVAL, 0);
+ vswap();
+ vstore();
+ args_size += size;
+ } else if (is_float(vtop->type.t)) {
+ gv(RC_FLOAT); /* only one float register */
+ if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
+ size = 4;
+ else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+ size = 8;
+ else
+ size = 12;
+ oad(0xec81, size); /* sub $xxx, %esp */
+ if (size == 12)
+ o(0x7cdb);
+ else
+ o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */
+ g(0x24);
+ g(0x00);
+ args_size += size;
+ } else {
+ /* simple type (currently always same size) */
+ /* XXX: implicit cast ? */
+ r = gv(RC_INT);
+ if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+ size = 8;
+ o(0x50 + vtop->r2); /* push r */
+ } else {
+ size = 4;
+ }
+ o(0x50 + r); /* push r */
+ args_size += size;
+ }
+ vtop--;
+ }
+ save_regs(0); /* save used temporary registers */
+ func_sym = vtop->type.ref;
+ func_call = func_sym->f.func_call;
+ /* fast call case */
+ if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
+ func_call == FUNC_FASTCALLW) {
+ int fastcall_nb_regs;
+ uint8_t *fastcall_regs_ptr;
+ if (func_call == FUNC_FASTCALLW) {
+ fastcall_regs_ptr = fastcallw_regs;
+ fastcall_nb_regs = 2;
+ } else {
+ fastcall_regs_ptr = fastcall_regs;
+ fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
+ }
+ for(i = 0;i < fastcall_nb_regs; i++) {
+ if (args_size <= 0)
+ break;
+ o(0x58 + fastcall_regs_ptr[i]); /* pop r */
+ /* XXX: incorrect for struct/floats */
+ args_size -= 4;
+ }
+ }
+#ifndef TCC_TARGET_PE
+ else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
+ args_size -= 4;
+#endif
+ gcall_or_jmp(0);
+
+ if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)
+ gadd_sp(args_size);
+ vtop--;
+}
+
+#ifdef TCC_TARGET_PE
+#define FUNC_PROLOG_SIZE (10 + USE_EBX)
+#else
+#define FUNC_PROLOG_SIZE (9 + USE_EBX)
+#endif
+
+/* generate function prolog of type 't' */
+ST_FUNC void gfunc_prolog(CType *func_type)
+{
+ int addr, align, size, func_call, fastcall_nb_regs;
+ int param_index, param_addr;
+ uint8_t *fastcall_regs_ptr;
+ Sym *sym;
+ CType *type;
+
+ sym = func_type->ref;
+ func_call = sym->f.func_call;
+ addr = 8;
+ loc = 0;
+ func_vc = 0;
+
+ if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
+ fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
+ fastcall_regs_ptr = fastcall_regs;
+ } else if (func_call == FUNC_FASTCALLW) {
+ fastcall_nb_regs = 2;
+ fastcall_regs_ptr = fastcallw_regs;
+ } else {
+ fastcall_nb_regs = 0;
+ fastcall_regs_ptr = NULL;
+ }
+ param_index = 0;
+
+ ind += FUNC_PROLOG_SIZE;
+ func_sub_sp_offset = ind;
+ /* if the function returns a structure, then add an
+ implicit pointer parameter */
+ func_vt = sym->type;
+ func_var = (sym->f.func_type == FUNC_ELLIPSIS);
+#ifdef TCC_TARGET_PE
+ size = type_size(&func_vt,&align);
+ if (((func_vt.t & VT_BTYPE) == VT_STRUCT)
+ && (size > 8 || (size & (size - 1)))) {
+#else
+ if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+#endif
+ /* XXX: fastcall case ? */
+ func_vc = addr;
+ addr += 4;
+ param_index++;
+ }
+ /* define parameters */
+ while ((sym = sym->next) != NULL) {
+ type = &sym->type;
+ size = type_size(type, &align);
+ size = (size + 3) & ~3;
+#ifdef FUNC_STRUCT_PARAM_AS_PTR
+ /* structs are passed as pointer */
+ if ((type->t & VT_BTYPE) == VT_STRUCT) {
+ size = 4;
+ }
+#endif
+ if (param_index < fastcall_nb_regs) {
+ /* save FASTCALL register */
+ loc -= 4;
+ o(0x89); /* movl */
+ gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);
+ param_addr = loc;
+ } else {
+ param_addr = addr;
+ addr += size;
+ }
+ sym_push(sym->v & ~SYM_FIELD, type,
+ VT_LOCAL | lvalue_type(type->t), param_addr);
+ param_index++;
+ }
+ func_ret_sub = 0;
+ /* pascal type call or fastcall ? */
+ if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW)
+ func_ret_sub = addr - 8;
+#ifndef TCC_TARGET_PE
+ else if (func_vc)
+ func_ret_sub = 4;
+#endif
+
+#ifdef CONFIG_TCC_BCHECK
+ /* leave some room for bound checking code */
+ if (tcc_state->do_bounds_check) {
+ func_bound_offset = lbounds_section->data_offset;
+ func_bound_ind = ind;
+ oad(0xb8, 0); /* lbound section pointer */
+ oad(0xb8, 0); /* call to function */
+ }
+#endif
+}
+
+/* generate function epilog */
+ST_FUNC void gfunc_epilog(void)
+{
+ addr_t v, saved_ind;
+
+#ifdef CONFIG_TCC_BCHECK
+ if (tcc_state->do_bounds_check
+ && func_bound_offset != lbounds_section->data_offset) {
+ addr_t saved_ind;
+ addr_t *bounds_ptr;
+ Sym *sym_data;
+
+ /* add end of table info */
+ bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
+ *bounds_ptr = 0;
+
+ /* generate bound local allocation */
+ saved_ind = ind;
+ ind = func_bound_ind;
+ sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
+ func_bound_offset, lbounds_section->data_offset);
+ greloc(cur_text_section, sym_data,
+ ind + 1, R_386_32);
+ oad(0xb8, 0); /* mov %eax, xxx */
+ gen_static_call(TOK___bound_local_new);
+ ind = saved_ind;
+
+ /* generate bound check local freeing */
+ o(0x5250); /* save returned value, if any */
+ greloc(cur_text_section, sym_data, ind + 1, R_386_32);
+ oad(0xb8, 0); /* mov %eax, xxx */
+ gen_static_call(TOK___bound_local_delete);
+ o(0x585a); /* restore returned value, if any */
+ }
+#endif
+
+ /* align local size to word & save local variables */
+ v = (-loc + 3) & -4;
+
+#if USE_EBX
+ o(0x8b);
+ gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4));
+#endif
+
+ o(0xc9); /* leave */
+ if (func_ret_sub == 0) {
+ o(0xc3); /* ret */
+ } else {
+ o(0xc2); /* ret n */
+ g(func_ret_sub);
+ g(func_ret_sub >> 8);
+ }
+ saved_ind = ind;
+ ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
+#ifdef TCC_TARGET_PE
+ if (v >= 4096) {
+ oad(0xb8, v); /* mov stacksize, %eax */
+ gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */
+ } else
+#endif
+ {
+ o(0xe58955); /* push %ebp, mov %esp, %ebp */
+ o(0xec81); /* sub esp, stacksize */
+ gen_le32(v);
+#ifdef TCC_TARGET_PE
+ o(0x90); /* adjust to FUNC_PROLOG_SIZE */
+#endif
+ }
+ o(0x53 * USE_EBX); /* push ebx */
+ ind = saved_ind;
+}
+
+/* generate a jump to a label */
+ST_FUNC int gjmp(int t)
+{
+ return gjmp2(0xe9, t);
+}
+
+/* generate a jump to a fixed address */
+ST_FUNC void gjmp_addr(int a)
+{
+ int r;
+ r = a - ind - 2;
+ if (r == (char)r) {
+ g(0xeb);
+ g(r);
+ } else {
+ oad(0xe9, a - ind - 5);
+ }
+}
+
+ST_FUNC void gtst_addr(int inv, int a)
+{
+ int v = vtop->r & VT_VALMASK;
+ if (v == VT_CMP) {
+ inv ^= (vtop--)->c.i;
+ a -= ind + 2;
+ if (a == (char)a) {
+ g(inv - 32);
+ g(a);
+ } else {
+ g(0x0f);
+ oad(inv - 16, a - 4);
+ }
+ } else if ((v & ~1) == VT_JMP) {
+ if ((v & 1) != inv) {
+ gjmp_addr(a);
+ gsym(vtop->c.i);
+ } else {
+ gsym(vtop->c.i);
+ o(0x05eb);
+ gjmp_addr(a);
+ }
+ vtop--;
+ }
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+ST_FUNC int gtst(int inv, int t)
+{
+ int v = vtop->r & VT_VALMASK;
+ if (nocode_wanted) {
+ ;
+ } else if (v == VT_CMP) {
+ /* fast case : can jump directly since flags are set */
+ g(0x0f);
+ t = gjmp2((vtop->c.i - 16) ^ inv, t);
+ } else if (v == VT_JMP || v == VT_JMPI) {
+ /* && or || optimization */
+ if ((v & 1) == inv) {
+ /* insert vtop->c jump list in t */
+ uint32_t n1, n = vtop->c.i;
+ if (n) {
+ while ((n1 = read32le(cur_text_section->data + n)))
+ n = n1;
+ write32le(cur_text_section->data + n, t);
+ t = vtop->c.i;
+ }
+ } else {
+ t = gjmp(t);
+ gsym(vtop->c.i);
+ }
+ }
+ vtop--;
+ return t;
+}
+
+/* generate an integer binary operation */
+ST_FUNC void gen_opi(int op)
+{
+ int r, fr, opc, c;
+
+ switch(op) {
+ case '+':
+ case TOK_ADDC1: /* add with carry generation */
+ opc = 0;
+ gen_op8:
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ /* constant case */
+ vswap();
+ r = gv(RC_INT);
+ vswap();
+ c = vtop->c.i;
+ if (c == (char)c) {
+ /* generate inc and dec for smaller code */
+ if (c==1 && opc==0 && op != TOK_ADDC1) {
+ o (0x40 | r); // inc
+ } else if (c==1 && opc==5 && op != TOK_SUBC1) {
+ o (0x48 | r); // dec
+ } else {
+ o(0x83);
+ o(0xc0 | (opc << 3) | r);
+ g(c);
+ }
+ } else {
+ o(0x81);
+ oad(0xc0 | (opc << 3) | r, c);
+ }
+ } else {
+ gv2(RC_INT, RC_INT);
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ o((opc << 3) | 0x01);
+ o(0xc0 + r + fr * 8);
+ }
+ vtop--;
+ if (op >= TOK_ULT && op <= TOK_GT) {
+ vtop->r = VT_CMP;
+ vtop->c.i = op;
+ }
+ break;
+ case '-':
+ case TOK_SUBC1: /* sub with carry generation */
+ opc = 5;
+ goto gen_op8;
+ case TOK_ADDC2: /* add with carry use */
+ opc = 2;
+ goto gen_op8;
+ case TOK_SUBC2: /* sub with carry use */
+ opc = 3;
+ goto gen_op8;
+ case '&':
+ opc = 4;
+ goto gen_op8;
+ case '^':
+ opc = 6;
+ goto gen_op8;
+ case '|':
+ opc = 1;
+ goto gen_op8;
+ case '*':
+ gv2(RC_INT, RC_INT);
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ vtop--;
+ o(0xaf0f); /* imul fr, r */
+ o(0xc0 + fr + r * 8);
+ break;
+ case TOK_SHL:
+ opc = 4;
+ goto gen_shift;
+ case TOK_SHR:
+ opc = 5;
+ goto gen_shift;
+ case TOK_SAR:
+ opc = 7;
+ gen_shift:
+ opc = 0xc0 | (opc << 3);
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ /* constant case */
+ vswap();
+ r = gv(RC_INT);
+ vswap();
+ c = vtop->c.i & 0x1f;
+ o(0xc1); /* shl/shr/sar $xxx, r */
+ o(opc | r);
+ g(c);
+ } else {
+ /* we generate the shift in ecx */
+ gv2(RC_INT, RC_ECX);
+ r = vtop[-1].r;
+ o(0xd3); /* shl/shr/sar %cl, r */
+ o(opc | r);
+ }
+ vtop--;
+ break;
+ case '/':
+ case TOK_UDIV:
+ case TOK_PDIV:
+ case '%':
+ case TOK_UMOD:
+ case TOK_UMULL:
+ /* first operand must be in eax */
+ /* XXX: need better constraint for second operand */
+ gv2(RC_EAX, RC_ECX);
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ vtop--;
+ save_reg(TREG_EDX);
+ /* save EAX too if used otherwise */
+ save_reg_upstack(TREG_EAX, 1);
+ if (op == TOK_UMULL) {
+ o(0xf7); /* mul fr */
+ o(0xe0 + fr);
+ vtop->r2 = TREG_EDX;
+ r = TREG_EAX;
+ } else {
+ if (op == TOK_UDIV || op == TOK_UMOD) {
+ o(0xf7d231); /* xor %edx, %edx, div fr, %eax */
+ o(0xf0 + fr);
+ } else {
+ o(0xf799); /* cltd, idiv fr, %eax */
+ o(0xf8 + fr);
+ }
+ if (op == '%' || op == TOK_UMOD)
+ r = TREG_EDX;
+ else
+ r = TREG_EAX;
+ }
+ vtop->r = r;
+ break;
+ default:
+ opc = 7;
+ goto gen_op8;
+ }
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+ two operands are guaranteed to have the same floating point type */
+/* XXX: need to use ST1 too */
+ST_FUNC void gen_opf(int op)
+{
+ int a, ft, fc, swapped, r;
+
+ /* convert constants to memory references */
+ if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+ vswap();
+ gv(RC_FLOAT);
+ vswap();
+ }
+ if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
+ gv(RC_FLOAT);
+
+ /* must put at least one value in the floating point register */
+ if ((vtop[-1].r & VT_LVAL) &&
+ (vtop[0].r & VT_LVAL)) {
+ vswap();
+ gv(RC_FLOAT);
+ vswap();
+ }
+ swapped = 0;
+ /* swap the stack if needed so that t1 is the register and t2 is
+ the memory reference */
+ if (vtop[-1].r & VT_LVAL) {
+ vswap();
+ swapped = 1;
+ }
+ if (op >= TOK_ULT && op <= TOK_GT) {
+ /* load on stack second operand */
+ load(TREG_ST0, vtop);
+ save_reg(TREG_EAX); /* eax is used by FP comparison code */
+ if (op == TOK_GE || op == TOK_GT)
+ swapped = !swapped;
+ else if (op == TOK_EQ || op == TOK_NE)
+ swapped = 0;
+ if (swapped)
+ o(0xc9d9); /* fxch %st(1) */
+ if (op == TOK_EQ || op == TOK_NE)
+ o(0xe9da); /* fucompp */
+ else
+ o(0xd9de); /* fcompp */
+ o(0xe0df); /* fnstsw %ax */
+ if (op == TOK_EQ) {
+ o(0x45e480); /* and $0x45, %ah */
+ o(0x40fC80); /* cmp $0x40, %ah */
+ } else if (op == TOK_NE) {
+ o(0x45e480); /* and $0x45, %ah */
+ o(0x40f480); /* xor $0x40, %ah */
+ op = TOK_NE;
+ } else if (op == TOK_GE || op == TOK_LE) {
+ o(0x05c4f6); /* test $0x05, %ah */
+ op = TOK_EQ;
+ } else {
+ o(0x45c4f6); /* test $0x45, %ah */
+ op = TOK_EQ;
+ }
+ vtop--;
+ vtop->r = VT_CMP;
+ vtop->c.i = op;
+ } else {
+ /* no memory reference possible for long double operations */
+ if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+ load(TREG_ST0, vtop);
+ swapped = !swapped;
+ }
+
+ switch(op) {
+ default:
+ case '+':
+ a = 0;
+ break;
+ case '-':
+ a = 4;
+ if (swapped)
+ a++;
+ break;
+ case '*':
+ a = 1;
+ break;
+ case '/':
+ a = 6;
+ if (swapped)
+ a++;
+ break;
+ }
+ ft = vtop->type.t;
+ fc = vtop->c.i;
+ if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+ o(0xde); /* fxxxp %st, %st(1) */
+ o(0xc1 + (a << 3));
+ } else {
+ /* if saved lvalue, then we must reload it */
+ r = vtop->r;
+ if ((r & VT_VALMASK) == VT_LLOCAL) {
+ SValue v1;
+ r = get_reg(RC_INT);
+ v1.type.t = VT_INT;
+ v1.r = VT_LOCAL | VT_LVAL;
+ v1.c.i = fc;
+ load(r, &v1);
+ fc = 0;
+ }
+
+ if ((ft & VT_BTYPE) == VT_DOUBLE)
+ o(0xdc);
+ else
+ o(0xd8);
+ gen_modrm(a, r, vtop->sym, fc);
+ }
+ vtop--;
+ }
+}
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+ and 'long long' cases. */
+ST_FUNC void gen_cvt_itof(int t)
+{
+ save_reg(TREG_ST0);
+ gv(RC_INT);
+ if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+ /* signed long long to float/double/long double (unsigned case
+ is handled generically) */
+ o(0x50 + vtop->r2); /* push r2 */
+ o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+ o(0x242cdf); /* fildll (%esp) */
+ o(0x08c483); /* add $8, %esp */
+ } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
+ (VT_INT | VT_UNSIGNED)) {
+ /* unsigned int to float/double/long double */
+ o(0x6a); /* push $0 */
+ g(0x00);
+ o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+ o(0x242cdf); /* fildll (%esp) */
+ o(0x08c483); /* add $8, %esp */
+ } else {
+ /* int to float/double/long double */
+ o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+ o(0x2404db); /* fildl (%esp) */
+ o(0x04c483); /* add $4, %esp */
+ }
+ vtop->r = TREG_ST0;
+}
+
+/* convert fp to int 't' type */
+ST_FUNC void gen_cvt_ftoi(int t)
+{
+ int bt = vtop->type.t & VT_BTYPE;
+ if (bt == VT_FLOAT)
+ vpush_global_sym(&func_old_type, TOK___fixsfdi);
+ else if (bt == VT_LDOUBLE)
+ vpush_global_sym(&func_old_type, TOK___fixxfdi);
+ else
+ vpush_global_sym(&func_old_type, TOK___fixdfdi);
+ vswap();
+ gfunc_call(1);
+ vpushi(0);
+ vtop->r = REG_IRET;
+ vtop->r2 = REG_LRET;
+}
+
+/* convert from one floating point type to another */
+ST_FUNC void gen_cvt_ftof(int t)
+{
+ /* all we have to do on i386 is to put the float in a register */
+ gv(RC_FLOAT);
+}
+
+/* computed goto support */
+ST_FUNC void ggoto(void)
+{
+ gcall_or_jmp(1);
+ vtop--;
+}
+
+/* bound check support functions */
+#ifdef CONFIG_TCC_BCHECK
+
+/* generate a bounded pointer addition */
+ST_FUNC void gen_bounded_ptr_add(void)
+{
+ /* prepare fast i386 function call (args in eax and edx) */
+ gv2(RC_EAX, RC_EDX);
+ /* save all temporary registers */
+ vtop -= 2;
+ save_regs(0);
+ /* do a fast function call */
+ gen_static_call(TOK___bound_ptr_add);
+ /* returned pointer is in eax */
+ vtop++;
+ vtop->r = TREG_EAX | VT_BOUNDED;
+ /* address of bounding function call point */
+ vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
+}
+
+/* patch pointer addition in vtop so that pointer dereferencing is
+ also tested */
+ST_FUNC void gen_bounded_ptr_deref(void)
+{
+ addr_t func;
+ int size, align;
+ Elf32_Rel *rel;
+ Sym *sym;
+
+ size = 0;
+ /* XXX: put that code in generic part of tcc */
+ if (!is_float(vtop->type.t)) {
+ if (vtop->r & VT_LVAL_BYTE)
+ size = 1;
+ else if (vtop->r & VT_LVAL_SHORT)
+ size = 2;
+ }
+ if (!size)
+ size = type_size(&vtop->type, &align);
+ switch(size) {
+ case 1: func = TOK___bound_ptr_indir1; break;
+ case 2: func = TOK___bound_ptr_indir2; break;
+ case 4: func = TOK___bound_ptr_indir4; break;
+ case 8: func = TOK___bound_ptr_indir8; break;
+ case 12: func = TOK___bound_ptr_indir12; break;
+ case 16: func = TOK___bound_ptr_indir16; break;
+ default:
+ tcc_error("unhandled size when dereferencing bounded pointer");
+ func = 0;
+ break;
+ }
+
+ /* patch relocation */
+ /* XXX: find a better solution ? */
+ rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i);
+ sym = external_global_sym(func, &func_old_type, 0);
+ if (!sym->c)
+ put_extern_sym(sym, NULL, 0, 0);
+ rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
+}
+#endif
+
+/* Save the stack pointer onto the stack */
+ST_FUNC void gen_vla_sp_save(int addr) {
+ /* mov %esp,addr(%ebp)*/
+ o(0x89);
+ gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+ o(0x8b);
+ gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
+}
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+#ifdef TCC_TARGET_PE
+ /* alloca does more than just adjust %rsp on Windows */
+ vpush_global_sym(&func_old_type, TOK_alloca);
+ vswap(); /* Move alloca ref past allocation size */
+ gfunc_call(1);
+#else
+ int r;
+ r = gv(RC_INT); /* allocation size */
+ /* sub r,%rsp */
+ o(0x2b);
+ o(0xe0 | r);
+ /* We align to 16 bytes rather than align */
+ /* and ~15, %esp */
+ o(0xf0e483);
+ vpop();
+#endif
+}
+
+/* end of X86 code generator */
+/*************************************************************/
+#endif
+/*************************************************************/
diff --git a/i386-link.c b/i386-link.c
new file mode 100644
index 0000000..aea3c21
--- /dev/null
+++ b/i386-link.c
@@ -0,0 +1,247 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_386
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32 R_386_32
+#define R_DATA_PTR R_386_32
+#define R_JMP_SLOT R_386_JMP_SLOT
+#define R_GLOB_DAT R_386_GLOB_DAT
+#define R_COPY R_386_COPY
+#define R_RELATIVE R_386_RELATIVE
+
+#define R_NUM R_386_NUM
+
+#define ELF_START_ADDR 0x08048000
+#define ELF_PAGE_SIZE 0x1000
+
+#define PCRELATIVE_DLLPLT 0
+#define RELOCATE_DLLPLT 0
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+ relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+ switch (reloc_type) {
+ case R_386_RELATIVE:
+ case R_386_16:
+ case R_386_32:
+ case R_386_GOTPC:
+ case R_386_GOTOFF:
+ case R_386_GOT32:
+ case R_386_GOT32X:
+ case R_386_GLOB_DAT:
+ case R_386_COPY:
+ return 0;
+
+ case R_386_PC16:
+ case R_386_PC32:
+ case R_386_PLT32:
+ case R_386_JMP_SLOT:
+ return 1;
+ }
+
+ tcc_error ("Unknown relocation type: %d", reloc_type);
+ return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+ GOT and/or PLT entry to be created. See tcc.h for a description of the
+ different values. */
+int gotplt_entry_type (int reloc_type)
+{
+ switch (reloc_type) {
+ case R_386_RELATIVE:
+ case R_386_16:
+ case R_386_GLOB_DAT:
+ case R_386_JMP_SLOT:
+ case R_386_COPY:
+ return NO_GOTPLT_ENTRY;
+
+ case R_386_32:
+ /* This relocations shouldn't normally need GOT or PLT
+ slots if it weren't for simplicity in the code generator.
+ See our caller for comments. */
+ return AUTO_GOTPLT_ENTRY;
+
+ case R_386_PC16:
+ case R_386_PC32:
+ return AUTO_GOTPLT_ENTRY;
+
+ case R_386_GOTPC:
+ case R_386_GOTOFF:
+ return BUILD_GOT_ONLY;
+
+ case R_386_GOT32:
+ case R_386_GOT32X:
+ case R_386_PLT32:
+ return ALWAYS_GOTPLT_ENTRY;
+ }
+
+ tcc_error ("Unknown relocation type: %d", reloc_type);
+ return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+ Section *plt = s1->plt;
+ uint8_t *p;
+ int modrm;
+ unsigned plt_offset, relofs;
+
+ /* on i386 if we build a DLL, we add a %ebx offset */
+ if (s1->output_type == TCC_OUTPUT_DLL)
+ modrm = 0xa3;
+ else
+ modrm = 0x25;
+
+ /* empty PLT: create PLT0 entry that pushes the library identifier
+ (GOT + PTR_SIZE) and jumps to ld.so resolution routine
+ (GOT + 2 * PTR_SIZE) */
+ if (plt->data_offset == 0) {
+ p = section_ptr_add(plt, 16);
+ p[0] = 0xff; /* pushl got + PTR_SIZE */
+ p[1] = modrm + 0x10;
+ write32le(p + 2, PTR_SIZE);
+ p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
+ p[7] = modrm;
+ write32le(p + 8, PTR_SIZE * 2);
+ }
+ plt_offset = plt->data_offset;
+
+ /* The PLT slot refers to the relocation entry it needs via offset.
+ The reloc entry is created below, so its offset is the current
+ data_offset */
+ relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
+
+ /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
+ p = section_ptr_add(plt, 16);
+ p[0] = 0xff; /* jmp *(got + x) */
+ p[1] = modrm;
+ write32le(p + 2, got_offset);
+ p[6] = 0x68; /* push $xxx */
+ write32le(p + 7, relofs);
+ p[11] = 0xe9; /* jmp plt_start */
+ write32le(p + 12, -(plt->data_offset));
+ return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+ address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+ uint8_t *p, *p_end;
+
+ if (!s1->plt)
+ return;
+
+ p = s1->plt->data;
+ p_end = p + s1->plt->data_offset;
+
+ if (p < p_end) {
+ add32le(p + 2, s1->got->sh_addr);
+ add32le(p + 8, s1->got->sh_addr);
+ p += 16;
+ while (p < p_end) {
+ add32le(p + 2, s1->got->sh_addr);
+ p += 16;
+ }
+ }
+}
+
+static ElfW_Rel *qrel; /* ptr to next reloc entry reused */
+
+void relocate_init(Section *sr)
+{
+ qrel = (ElfW_Rel *) sr->data;
+}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+ int sym_index, esym_index;
+
+ sym_index = ELFW(R_SYM)(rel->r_info);
+
+ switch (type) {
+ case R_386_32:
+ if (s1->output_type == TCC_OUTPUT_DLL) {
+ esym_index = s1->sym_attrs[sym_index].dyn_index;
+ qrel->r_offset = rel->r_offset;
+ if (esym_index) {
+ qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
+ qrel++;
+ return;
+ } else {
+ qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
+ qrel++;
+ }
+ }
+ add32le(ptr, val);
+ return;
+ case R_386_PC32:
+ if (s1->output_type == TCC_OUTPUT_DLL) {
+ /* DLL relocation */
+ esym_index = s1->sym_attrs[sym_index].dyn_index;
+ if (esym_index) {
+ qrel->r_offset = rel->r_offset;
+ qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
+ qrel++;
+ return;
+ }
+ }
+ add32le(ptr, val - addr);
+ return;
+ case R_386_PLT32:
+ add32le(ptr, val - addr);
+ return;
+ case R_386_GLOB_DAT:
+ case R_386_JMP_SLOT:
+ write32le(ptr, val);
+ return;
+ case R_386_GOTPC:
+ add32le(ptr, s1->got->sh_addr - addr);
+ return;
+ case R_386_GOTOFF:
+ add32le(ptr, val - s1->got->sh_addr);
+ return;
+ case R_386_GOT32:
+ case R_386_GOT32X:
+ /* we load the got offset */
+ add32le(ptr, s1->sym_attrs[sym_index].got_offset);
+ return;
+ case R_386_16:
+ if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
+ output_file:
+ tcc_error("can only produce 16-bit binary files");
+ }
+ write16le(ptr, read16le(ptr) + val);
+ return;
+ case R_386_PC16:
+ if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
+ goto output_file;
+ write16le(ptr, read16le(ptr) + val - addr);
+ return;
+ case R_386_RELATIVE:
+#ifdef TCC_TARGET_PE
+ add32le(ptr, val - s1->pe_imagebase);
+#endif
+ /* do nothing */
+ return;
+ case R_386_COPY:
+ /* This relocation must copy initialized data from the library
+ to the program .bss segment. Currently made like for ARM
+ (to remove noise of default case). Is this true?
+ */
+ return;
+ default:
+ fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n",
+ type, (unsigned)addr, ptr, (unsigned)val);
+ return;
+ }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
diff --git a/i386-tok.h b/i386-tok.h
new file mode 100644
index 0000000..8c25af0
--- /dev/null
+++ b/i386-tok.h
@@ -0,0 +1,253 @@
+/* ------------------------------------------------------------------ */
+/* WARNING: relative order of tokens is important. */
+
+/* register */
+ DEF_ASM(al)
+ DEF_ASM(cl)
+ DEF_ASM(dl)
+ DEF_ASM(bl)
+ DEF_ASM(ah)
+ DEF_ASM(ch)
+ DEF_ASM(dh)
+ DEF_ASM(bh)
+ DEF_ASM(ax)
+ DEF_ASM(cx)
+ DEF_ASM(dx)
+ DEF_ASM(bx)
+ DEF_ASM(sp)
+ DEF_ASM(bp)
+ DEF_ASM(si)
+ DEF_ASM(di)
+ DEF_ASM(eax)
+ DEF_ASM(ecx)
+ DEF_ASM(edx)
+ DEF_ASM(ebx)
+ DEF_ASM(esp)
+ DEF_ASM(ebp)
+ DEF_ASM(esi)
+ DEF_ASM(edi)
+#ifdef TCC_TARGET_X86_64
+ DEF_ASM(rax)
+ DEF_ASM(rcx)
+ DEF_ASM(rdx)
+ DEF_ASM(rbx)
+ DEF_ASM(rsp)
+ DEF_ASM(rbp)
+ DEF_ASM(rsi)
+ DEF_ASM(rdi)
+#endif
+ DEF_ASM(mm0)
+ DEF_ASM(mm1)
+ DEF_ASM(mm2)
+ DEF_ASM(mm3)
+ DEF_ASM(mm4)
+ DEF_ASM(mm5)
+ DEF_ASM(mm6)
+ DEF_ASM(mm7)
+ DEF_ASM(xmm0)
+ DEF_ASM(xmm1)
+ DEF_ASM(xmm2)
+ DEF_ASM(xmm3)
+ DEF_ASM(xmm4)
+ DEF_ASM(xmm5)
+ DEF_ASM(xmm6)
+ DEF_ASM(xmm7)
+ DEF_ASM(cr0)
+ DEF_ASM(cr1)
+ DEF_ASM(cr2)
+ DEF_ASM(cr3)
+ DEF_ASM(cr4)
+ DEF_ASM(cr5)
+ DEF_ASM(cr6)
+ DEF_ASM(cr7)
+ DEF_ASM(tr0)
+ DEF_ASM(tr1)
+ DEF_ASM(tr2)
+ DEF_ASM(tr3)
+ DEF_ASM(tr4)
+ DEF_ASM(tr5)
+ DEF_ASM(tr6)
+ DEF_ASM(tr7)
+ DEF_ASM(db0)
+ DEF_ASM(db1)
+ DEF_ASM(db2)
+ DEF_ASM(db3)
+ DEF_ASM(db4)
+ DEF_ASM(db5)
+ DEF_ASM(db6)
+ DEF_ASM(db7)
+ DEF_ASM(dr0)
+ DEF_ASM(dr1)
+ DEF_ASM(dr2)
+ DEF_ASM(dr3)
+ DEF_ASM(dr4)
+ DEF_ASM(dr5)
+ DEF_ASM(dr6)
+ DEF_ASM(dr7)
+ DEF_ASM(es)
+ DEF_ASM(cs)
+ DEF_ASM(ss)
+ DEF_ASM(ds)
+ DEF_ASM(fs)
+ DEF_ASM(gs)
+ DEF_ASM(st)
+ DEF_ASM(rip)
+
+#ifdef TCC_TARGET_X86_64
+ /* The four low parts of sp/bp/si/di that exist only on
+ x86-64 (encoding aliased to ah,ch,dh,dh when not using REX). */
+ DEF_ASM(spl)
+ DEF_ASM(bpl)
+ DEF_ASM(sil)
+ DEF_ASM(dil)
+#endif
+ /* generic two operands */
+ DEF_BWLX(mov)
+
+ DEF_BWLX(add)
+ DEF_BWLX(or)
+ DEF_BWLX(adc)
+ DEF_BWLX(sbb)
+ DEF_BWLX(and)
+ DEF_BWLX(sub)
+ DEF_BWLX(xor)
+ DEF_BWLX(cmp)
+
+ /* unary ops */
+ DEF_BWLX(inc)
+ DEF_BWLX(dec)
+ DEF_BWLX(not)
+ DEF_BWLX(neg)
+ DEF_BWLX(mul)
+ DEF_BWLX(imul)
+ DEF_BWLX(div)
+ DEF_BWLX(idiv)
+
+ DEF_BWLX(xchg)
+ DEF_BWLX(test)
+
+ /* shifts */
+ DEF_BWLX(rol)
+ DEF_BWLX(ror)
+ DEF_BWLX(rcl)
+ DEF_BWLX(rcr)
+ DEF_BWLX(shl)
+ DEF_BWLX(shr)
+ DEF_BWLX(sar)
+
+ DEF_WLX(shld)
+ DEF_WLX(shrd)
+
+ DEF_ASM(pushw)
+ DEF_ASM(pushl)
+#ifdef TCC_TARGET_X86_64
+ DEF_ASM(pushq)
+#endif
+ DEF_ASM(push)
+
+ DEF_ASM(popw)
+ DEF_ASM(popl)
+#ifdef TCC_TARGET_X86_64
+ DEF_ASM(popq)
+#endif
+ DEF_ASM(pop)
+
+ DEF_BWL(in)
+ DEF_BWL(out)
+
+ DEF_WLX(movzb)
+ DEF_ASM(movzwl)
+ DEF_ASM(movsbw)
+ DEF_ASM(movsbl)
+ DEF_ASM(movswl)
+#ifdef TCC_TARGET_X86_64
+ DEF_ASM(movsbq)
+ DEF_ASM(movswq)
+ DEF_ASM(movzwq)
+ DEF_ASM(movslq)
+#endif
+
+ DEF_WLX(lea)
+
+ DEF_ASM(les)
+ DEF_ASM(lds)
+ DEF_ASM(lss)
+ DEF_ASM(lfs)
+ DEF_ASM(lgs)
+
+ DEF_ASM(call)
+ DEF_ASM(jmp)
+ DEF_ASM(lcall)
+ DEF_ASM(ljmp)
+
+ DEF_ASMTEST(j,)
+
+ DEF_ASMTEST(set,)
+ DEF_ASMTEST(set,b)
+ DEF_ASMTEST(cmov,)
+
+ DEF_WLX(bsf)
+ DEF_WLX(bsr)
+ DEF_WLX(bt)
+ DEF_WLX(bts)
+ DEF_WLX(btr)
+ DEF_WLX(btc)
+
+ DEF_WLX(lar)
+ DEF_WLX(lsl)
+
+ /* generic FP ops */
+ DEF_FP(add)
+ DEF_FP(mul)
+
+ DEF_ASM(fcom)
+ DEF_ASM(fcom_1) /* non existent op, just to have a regular table */
+ DEF_FP1(com)
+
+ DEF_FP(comp)
+ DEF_FP(sub)
+ DEF_FP(subr)
+ DEF_FP(div)
+ DEF_FP(divr)
+
+ DEF_BWLX(xadd)
+ DEF_BWLX(cmpxchg)
+
+ /* string ops */
+ DEF_BWLX(cmps)
+ DEF_BWLX(scmp)
+ DEF_BWL(ins)
+ DEF_BWL(outs)
+ DEF_BWLX(lods)
+ DEF_BWLX(slod)
+ DEF_BWLX(movs)
+ DEF_BWLX(smov)
+ DEF_BWLX(scas)
+ DEF_BWLX(ssca)
+ DEF_BWLX(stos)
+ DEF_BWLX(ssto)
+
+ /* generic asm ops */
+#define ALT(x)
+#define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
+#define DEF_ASM_OP0L(name, opcode, group, instr_type)
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
+#ifdef TCC_TARGET_X86_64
+# include "x86_64-asm.h"
+#else
+# include "i386-asm.h"
+#endif
+
+#define ALT(x)
+#define DEF_ASM_OP0(name, opcode)
+#define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
+#ifdef TCC_TARGET_X86_64
+# include "x86_64-asm.h"
+#else
+# include "i386-asm.h"
+#endif
diff --git a/il-gen.c b/il-gen.c
new file mode 100644
index 0000000..bb670cc
--- /dev/null
+++ b/il-gen.c
@@ -0,0 +1,657 @@
+/*
+ * CIL code generator for TCC
+ *
+ * Copyright (c) 2002 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#error this code has bit-rotted since 2003
+
+/* number of available registers */
+#define NB_REGS 3
+
+/* a register can belong to several classes. The classes must be
+ sorted from more general to more precise (see gv2() code which does
+ assumptions on it). */
+#define RC_ST 0x0001 /* any stack entry */
+#define RC_ST0 0x0002 /* top of stack */
+#define RC_ST1 0x0004 /* top - 1 */
+
+#define RC_INT RC_ST
+#define RC_FLOAT RC_ST
+#define RC_IRET RC_ST0 /* function return: integer register */
+#define RC_LRET RC_ST0 /* function return: second integer register */
+#define RC_FRET RC_ST0 /* function return: float register */
+
+/* pretty names for the registers */
+enum {
+ REG_ST0 = 0,
+ REG_ST1,
+ REG_ST2,
+};
+
+const int reg_classes[NB_REGS] = {
+ /* ST0 */ RC_ST | RC_ST0,
+ /* ST1 */ RC_ST | RC_ST1,
+ /* ST2 */ RC_ST,
+};
+
+/* return registers for function */
+#define REG_IRET REG_ST0 /* single word int return register */
+#define REG_LRET REG_ST0 /* second word return register (for long long) */
+#define REG_FRET REG_ST0 /* float return register */
+
+/* defined if function parameters must be evaluated in reverse order */
+/* #define INVERT_FUNC_PARAMS */
+
+/* defined if structures are passed as pointers. Otherwise structures
+ are directly pushed on stack. */
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE 8
+#define LDOUBLE_ALIGN 8
+
+/* function call context */
+typedef struct GFuncContext {
+ int func_call; /* func call type (FUNC_STDCALL or FUNC_CDECL) */
+} GFuncContext;
+
+/******************************************************/
+/* opcode definitions */
+
+#define IL_OP_PREFIX 0xFE
+
+enum ILOPCodes {
+#define OP(name, str, n) IL_OP_ ## name = n,
+#include "il-opcodes.h"
+#undef OP
+};
+
+char *il_opcodes_str[] = {
+#define OP(name, str, n) [n] = str,
+#include "il-opcodes.h"
+#undef OP
+};
+
+/******************************************************/
+
+/* arguments variable numbers start from there */
+#define ARG_BASE 0x70000000
+
+static FILE *il_outfile;
+
+static void out_byte(int c)
+{
+ *(char *)ind++ = c;
+}
+
+static void out_le32(int c)
+{
+ out_byte(c);
+ out_byte(c >> 8);
+ out_byte(c >> 16);
+ out_byte(c >> 24);
+}
+
+static void init_outfile(void)
+{
+ if (!il_outfile) {
+ il_outfile = stdout;
+ fprintf(il_outfile,
+ ".assembly extern mscorlib\n"
+ "{\n"
+ ".ver 1:0:2411:0\n"
+ "}\n\n");
+ }
+}
+
+static void out_op1(int op)
+{
+ if (op & 0x100)
+ out_byte(IL_OP_PREFIX);
+ out_byte(op & 0xff);
+}
+
+/* output an opcode with prefix */
+static void out_op(int op)
+{
+ out_op1(op);
+ fprintf(il_outfile, " %s\n", il_opcodes_str[op]);
+}
+
+static void out_opb(int op, int c)
+{
+ out_op1(op);
+ out_byte(c);
+ fprintf(il_outfile, " %s %d\n", il_opcodes_str[op], c);
+}
+
+static void out_opi(int op, int c)
+{
+ out_op1(op);
+ out_le32(c);
+ fprintf(il_outfile, " %s 0x%x\n", il_opcodes_str[op], c);
+}
+
+/* XXX: not complete */
+static void il_type_to_str(char *buf, int buf_size,
+ int t, const char *varstr)
+{
+ int bt;
+ Sym *s, *sa;
+ char buf1[256];
+ const char *tstr;
+
+ t = t & VT_TYPE;
+ bt = t & VT_BTYPE;
+ buf[0] = '\0';
+ if (t & VT_UNSIGNED)
+ pstrcat(buf, buf_size, "unsigned ");
+ switch(bt) {
+ case VT_VOID:
+ tstr = "void";
+ goto add_tstr;
+ case VT_BOOL:
+ tstr = "bool";
+ goto add_tstr;
+ case VT_BYTE:
+ tstr = "int8";
+ goto add_tstr;
+ case VT_SHORT:
+ tstr = "int16";
+ goto add_tstr;
+ case VT_ENUM:
+ case VT_INT:
+ case VT_LONG:
+ tstr = "int32";
+ goto add_tstr;
+ case VT_LLONG:
+ tstr = "int64";
+ goto add_tstr;
+ case VT_FLOAT:
+ tstr = "float32";
+ goto add_tstr;
+ case VT_DOUBLE:
+ case VT_LDOUBLE:
+ tstr = "float64";
+ add_tstr:
+ pstrcat(buf, buf_size, tstr);
+ break;
+ case VT_STRUCT:
+ tcc_error("structures not handled yet");
+ break;
+ case VT_FUNC:
+ s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
+ il_type_to_str(buf, buf_size, s->t, varstr);
+ pstrcat(buf, buf_size, "(");
+ sa = s->next;
+ while (sa != NULL) {
+ il_type_to_str(buf1, sizeof(buf1), sa->t, NULL);
+ pstrcat(buf, buf_size, buf1);
+ sa = sa->next;
+ if (sa)
+ pstrcat(buf, buf_size, ", ");
+ }
+ pstrcat(buf, buf_size, ")");
+ goto no_var;
+ case VT_PTR:
+ s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
+ pstrcpy(buf1, sizeof(buf1), "*");
+ if (varstr)
+ pstrcat(buf1, sizeof(buf1), varstr);
+ il_type_to_str(buf, buf_size, s->t, buf1);
+ goto no_var;
+ }
+ if (varstr) {
+ pstrcat(buf, buf_size, " ");
+ pstrcat(buf, buf_size, varstr);
+ }
+ no_var: ;
+}
+
+
+/* patch relocation entry with value 'val' */
+void greloc_patch1(Reloc *p, int val)
+{
+}
+
+/* output a symbol and patch all calls to it */
+void gsym_addr(t, a)
+{
+}
+
+/* output jump and return symbol */
+static int out_opj(int op, int c)
+{
+ out_op1(op);
+ out_le32(0);
+ if (c == 0) {
+ c = ind - (int)cur_text_section->data;
+ }
+ fprintf(il_outfile, " %s L%d\n", il_opcodes_str[op], c);
+ return c;
+}
+
+void gsym(int t)
+{
+ fprintf(il_outfile, "L%d:\n", t);
+}
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue *sv)
+{
+ int v, fc, ft;
+
+ v = sv->r & VT_VALMASK;
+ fc = sv->c.i;
+ ft = sv->t;
+
+ if (sv->r & VT_LVAL) {
+ if (v == VT_LOCAL) {
+ if (fc >= ARG_BASE) {
+ fc -= ARG_BASE;
+ if (fc >= 0 && fc <= 4) {
+ out_op(IL_OP_LDARG_0 + fc);
+ } else if (fc <= 0xff) {
+ out_opb(IL_OP_LDARG_S, fc);
+ } else {
+ out_opi(IL_OP_LDARG, fc);
+ }
+ } else {
+ if (fc >= 0 && fc <= 4) {
+ out_op(IL_OP_LDLOC_0 + fc);
+ } else if (fc <= 0xff) {
+ out_opb(IL_OP_LDLOC_S, fc);
+ } else {
+ out_opi(IL_OP_LDLOC, fc);
+ }
+ }
+ } else if (v == VT_CONST) {
+ /* XXX: handle globals */
+ out_opi(IL_OP_LDSFLD, 0);
+ } else {
+ if ((ft & VT_BTYPE) == VT_FLOAT) {
+ out_op(IL_OP_LDIND_R4);
+ } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+ out_op(IL_OP_LDIND_R8);
+ } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+ out_op(IL_OP_LDIND_R8);
+ } else if ((ft & VT_TYPE) == VT_BYTE)
+ out_op(IL_OP_LDIND_I1);
+ else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED))
+ out_op(IL_OP_LDIND_U1);
+ else if ((ft & VT_TYPE) == VT_SHORT)
+ out_op(IL_OP_LDIND_I2);
+ else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED))
+ out_op(IL_OP_LDIND_U2);
+ else
+ out_op(IL_OP_LDIND_I4);
+ }
+ } else {
+ if (v == VT_CONST) {
+ /* XXX: handle globals */
+ if (fc >= -1 && fc <= 8) {
+ out_op(IL_OP_LDC_I4_M1 + fc + 1);
+ } else {
+ out_opi(IL_OP_LDC_I4, fc);
+ }
+ } else if (v == VT_LOCAL) {
+ if (fc >= ARG_BASE) {
+ fc -= ARG_BASE;
+ if (fc <= 0xff) {
+ out_opb(IL_OP_LDARGA_S, fc);
+ } else {
+ out_opi(IL_OP_LDARGA, fc);
+ }
+ } else {
+ if (fc <= 0xff) {
+ out_opb(IL_OP_LDLOCA_S, fc);
+ } else {
+ out_opi(IL_OP_LDLOCA, fc);
+ }
+ }
+ } else {
+ /* XXX: do it */
+ }
+ }
+}
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue *sv)
+{
+ int v, fc, ft;
+
+ v = sv->r & VT_VALMASK;
+ fc = sv->c.i;
+ ft = sv->t;
+ if (v == VT_LOCAL) {
+ if (fc >= ARG_BASE) {
+ fc -= ARG_BASE;
+ /* XXX: check IL arg store semantics */
+ if (fc <= 0xff) {
+ out_opb(IL_OP_STARG_S, fc);
+ } else {
+ out_opi(IL_OP_STARG, fc);
+ }
+ } else {
+ if (fc >= 0 && fc <= 4) {
+ out_op(IL_OP_STLOC_0 + fc);
+ } else if (fc <= 0xff) {
+ out_opb(IL_OP_STLOC_S, fc);
+ } else {
+ out_opi(IL_OP_STLOC, fc);
+ }
+ }
+ } else if (v == VT_CONST) {
+ /* XXX: handle globals */
+ out_opi(IL_OP_STSFLD, 0);
+ } else {
+ if ((ft & VT_BTYPE) == VT_FLOAT)
+ out_op(IL_OP_STIND_R4);
+ else if ((ft & VT_BTYPE) == VT_DOUBLE)
+ out_op(IL_OP_STIND_R8);
+ else if ((ft & VT_BTYPE) == VT_LDOUBLE)
+ out_op(IL_OP_STIND_R8);
+ else if ((ft & VT_BTYPE) == VT_BYTE)
+ out_op(IL_OP_STIND_I1);
+ else if ((ft & VT_BTYPE) == VT_SHORT)
+ out_op(IL_OP_STIND_I2);
+ else
+ out_op(IL_OP_STIND_I4);
+ }
+}
+
+/* start function call and return function call context */
+void gfunc_start(GFuncContext *c, int func_call)
+{
+ c->func_call = func_call;
+}
+
+/* push function parameter which is in (vtop->t, vtop->c). Stack entry
+ is then popped. */
+void gfunc_param(GFuncContext *c)
+{
+ if ((vtop->t & VT_BTYPE) == VT_STRUCT) {
+ tcc_error("structures passed as value not handled yet");
+ } else {
+ /* simply push on stack */
+ gv(RC_ST0);
+ }
+ vtop--;
+}
+
+/* generate function call with address in (vtop->t, vtop->c) and free function
+ context. Stack entry is popped */
+void gfunc_call(GFuncContext *c)
+{
+ char buf[1024];
+
+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+ /* XXX: more info needed from tcc */
+ il_type_to_str(buf, sizeof(buf), vtop->t, "xxx");
+ fprintf(il_outfile, " call %s\n", buf);
+ } else {
+ /* indirect call */
+ gv(RC_INT);
+ il_type_to_str(buf, sizeof(buf), vtop->t, NULL);
+ fprintf(il_outfile, " calli %s\n", buf);
+ }
+ vtop--;
+}
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(int t)
+{
+ int addr, u, func_call;
+ Sym *sym;
+ char buf[1024];
+
+ init_outfile();
+
+ /* XXX: pass function name to gfunc_prolog */
+ il_type_to_str(buf, sizeof(buf), t, funcname);
+ fprintf(il_outfile, ".method static %s il managed\n", buf);
+ fprintf(il_outfile, "{\n");
+ /* XXX: cannot do better now */
+ fprintf(il_outfile, " .maxstack %d\n", NB_REGS);
+ fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n");
+
+ if (!strcmp(funcname, "main"))
+ fprintf(il_outfile, " .entrypoint\n");
+
+ sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
+ func_call = sym->r;
+
+ addr = ARG_BASE;
+ /* if the function returns a structure, then add an
+ implicit pointer parameter */
+ func_vt = sym->t;
+ func_var = (sym->c == FUNC_ELLIPSIS);
+ if ((func_vt & VT_BTYPE) == VT_STRUCT) {
+ func_vc = addr;
+ addr++;
+ }
+ /* define parameters */
+ while ((sym = sym->next) != NULL) {
+ u = sym->t;
+ sym_push(sym->v & ~SYM_FIELD, u,
+ VT_LOCAL | lvalue_type(sym->type.t), addr);
+ addr++;
+ }
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+ out_op(IL_OP_RET);
+ fprintf(il_outfile, "}\n\n");
+}
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+ return out_opj(IL_OP_BR, t);
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+ /* XXX: handle syms */
+ out_opi(IL_OP_BR, a);
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+int gtst(int inv, int t)
+{
+ int v, *p, c;
+
+ v = vtop->r & VT_VALMASK;
+ if (v == VT_CMP) {
+ c = vtop->c.i ^ inv;
+ switch(c) {
+ case TOK_EQ:
+ c = IL_OP_BEQ;
+ break;
+ case TOK_NE:
+ c = IL_OP_BNE_UN;
+ break;
+ case TOK_LT:
+ c = IL_OP_BLT;
+ break;
+ case TOK_LE:
+ c = IL_OP_BLE;
+ break;
+ case TOK_GT:
+ c = IL_OP_BGT;
+ break;
+ case TOK_GE:
+ c = IL_OP_BGE;
+ break;
+ case TOK_ULT:
+ c = IL_OP_BLT_UN;
+ break;
+ case TOK_ULE:
+ c = IL_OP_BLE_UN;
+ break;
+ case TOK_UGT:
+ c = IL_OP_BGT_UN;
+ break;
+ case TOK_UGE:
+ c = IL_OP_BGE_UN;
+ break;
+ }
+ t = out_opj(c, t);
+ } else if (v == VT_JMP || v == VT_JMPI) {
+ /* && or || optimization */
+ if ((v & 1) == inv) {
+ /* insert vtop->c jump list in t */
+ p = &vtop->c.i;
+ while (*p != 0)
+ p = (int *)*p;
+ *p = t;
+ t = vtop->c.i;
+ } else {
+ t = gjmp(t);
+ gsym(vtop->c.i);
+ }
+ }
+ vtop--;
+ return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+ gv2(RC_ST1, RC_ST0);
+ switch(op) {
+ case '+':
+ out_op(IL_OP_ADD);
+ goto std_op;
+ case '-':
+ out_op(IL_OP_SUB);
+ goto std_op;
+ case '&':
+ out_op(IL_OP_AND);
+ goto std_op;
+ case '^':
+ out_op(IL_OP_XOR);
+ goto std_op;
+ case '|':
+ out_op(IL_OP_OR);
+ goto std_op;
+ case '*':
+ out_op(IL_OP_MUL);
+ goto std_op;
+ case TOK_SHL:
+ out_op(IL_OP_SHL);
+ goto std_op;
+ case TOK_SHR:
+ out_op(IL_OP_SHR_UN);
+ goto std_op;
+ case TOK_SAR:
+ out_op(IL_OP_SHR);
+ goto std_op;
+ case '/':
+ case TOK_PDIV:
+ out_op(IL_OP_DIV);
+ goto std_op;
+ case TOK_UDIV:
+ out_op(IL_OP_DIV_UN);
+ goto std_op;
+ case '%':
+ out_op(IL_OP_REM);
+ goto std_op;
+ case TOK_UMOD:
+ out_op(IL_OP_REM_UN);
+ std_op:
+ vtop--;
+ vtop[0].r = REG_ST0;
+ break;
+ case TOK_EQ:
+ case TOK_NE:
+ case TOK_LT:
+ case TOK_LE:
+ case TOK_GT:
+ case TOK_GE:
+ case TOK_ULT:
+ case TOK_ULE:
+ case TOK_UGT:
+ case TOK_UGE:
+ vtop--;
+ vtop[0].r = VT_CMP;
+ vtop[0].c.i = op;
+ break;
+ }
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+ two operands are guaranteed to have the same floating point type */
+void gen_opf(int op)
+{
+ /* same as integer */
+ gen_opi(op);
+}
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+ and 'long long' cases. */
+void gen_cvt_itof(int t)
+{
+ gv(RC_ST0);
+ if (t == VT_FLOAT)
+ out_op(IL_OP_CONV_R4);
+ else
+ out_op(IL_OP_CONV_R8);
+}
+
+/* convert fp to int 't' type */
+/* XXX: handle long long case */
+void gen_cvt_ftoi(int t)
+{
+ gv(RC_ST0);
+ switch(t) {
+ case VT_INT | VT_UNSIGNED:
+ out_op(IL_OP_CONV_U4);
+ break;
+ case VT_LLONG:
+ out_op(IL_OP_CONV_I8);
+ break;
+ case VT_LLONG | VT_UNSIGNED:
+ out_op(IL_OP_CONV_U8);
+ break;
+ default:
+ out_op(IL_OP_CONV_I4);
+ break;
+ }
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+ gv(RC_ST0);
+ if (t == VT_FLOAT) {
+ out_op(IL_OP_CONV_R4);
+ } else {
+ out_op(IL_OP_CONV_R8);
+ }
+}
+
+/* end of CIL code generator */
+/*************************************************************/
+
diff --git a/il-opcodes.h b/il-opcodes.h
new file mode 100644
index 0000000..d53ffb2
--- /dev/null
+++ b/il-opcodes.h
@@ -0,0 +1,251 @@
+/*
+ * CIL opcode definition
+ *
+ * Copyright (c) 2002 Fabrice Bellard
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+OP(NOP, "nop", 0x00)
+OP(BREAK, "break", 0x01)
+OP(LDARG_0, "ldarg.0", 0x02)
+OP(LDARG_1, "ldarg.1", 0x03)
+OP(LDARG_2, "ldarg.2", 0x04)
+OP(LDARG_3, "ldarg.3", 0x05)
+OP(LDLOC_0, "ldloc.0", 0x06)
+OP(LDLOC_1, "ldloc.1", 0x07)
+OP(LDLOC_2, "ldloc.2", 0x08)
+OP(LDLOC_3, "ldloc.3", 0x09)
+OP(STLOC_0, "stloc.0", 0x0a)
+OP(STLOC_1, "stloc.1", 0x0b)
+OP(STLOC_2, "stloc.2", 0x0c)
+OP(STLOC_3, "stloc.3", 0x0d)
+OP(LDARG_S, "ldarg.s", 0x0e)
+OP(LDARGA_S, "ldarga.s", 0x0f)
+OP(STARG_S, "starg.s", 0x10)
+OP(LDLOC_S, "ldloc.s", 0x11)
+OP(LDLOCA_S, "ldloca.s", 0x12)
+OP(STLOC_S, "stloc.s", 0x13)
+OP(LDNULL, "ldnull", 0x14)
+OP(LDC_I4_M1, "ldc.i4.m1", 0x15)
+OP(LDC_I4_0, "ldc.i4.0", 0x16)
+OP(LDC_I4_1, "ldc.i4.1", 0x17)
+OP(LDC_I4_2, "ldc.i4.2", 0x18)
+OP(LDC_I4_3, "ldc.i4.3", 0x19)
+OP(LDC_I4_4, "ldc.i4.4", 0x1a)
+OP(LDC_I4_5, "ldc.i4.5", 0x1b)
+OP(LDC_I4_6, "ldc.i4.6", 0x1c)
+OP(LDC_I4_7, "ldc.i4.7", 0x1d)
+OP(LDC_I4_8, "ldc.i4.8", 0x1e)
+OP(LDC_I4_S, "ldc.i4.s", 0x1f)
+OP(LDC_I4, "ldc.i4", 0x20)
+OP(LDC_I8, "ldc.i8", 0x21)
+OP(LDC_R4, "ldc.r4", 0x22)
+OP(LDC_R8, "ldc.r8", 0x23)
+OP(LDPTR, "ldptr", 0x24)
+OP(DUP, "dup", 0x25)
+OP(POP, "pop", 0x26)
+OP(JMP, "jmp", 0x27)
+OP(CALL, "call", 0x28)
+OP(CALLI, "calli", 0x29)
+OP(RET, "ret", 0x2a)
+OP(BR_S, "br.s", 0x2b)
+OP(BRFALSE_S, "brfalse.s", 0x2c)
+OP(BRTRUE_S, "brtrue.s", 0x2d)
+OP(BEQ_S, "beq.s", 0x2e)
+OP(BGE_S, "bge.s", 0x2f)
+OP(BGT_S, "bgt.s", 0x30)
+OP(BLE_S, "ble.s", 0x31)
+OP(BLT_S, "blt.s", 0x32)
+OP(BNE_UN_S, "bne.un.s", 0x33)
+OP(BGE_UN_S, "bge.un.s", 0x34)
+OP(BGT_UN_S, "bgt.un.s", 0x35)
+OP(BLE_UN_S, "ble.un.s", 0x36)
+OP(BLT_UN_S, "blt.un.s", 0x37)
+OP(BR, "br", 0x38)
+OP(BRFALSE, "brfalse", 0x39)
+OP(BRTRUE, "brtrue", 0x3a)
+OP(BEQ, "beq", 0x3b)
+OP(BGE, "bge", 0x3c)
+OP(BGT, "bgt", 0x3d)
+OP(BLE, "ble", 0x3e)
+OP(BLT, "blt", 0x3f)
+OP(BNE_UN, "bne.un", 0x40)
+OP(BGE_UN, "bge.un", 0x41)
+OP(BGT_UN, "bgt.un", 0x42)
+OP(BLE_UN, "ble.un", 0x43)
+OP(BLT_UN, "blt.un", 0x44)
+OP(SWITCH, "switch", 0x45)
+OP(LDIND_I1, "ldind.i1", 0x46)
+OP(LDIND_U1, "ldind.u1", 0x47)
+OP(LDIND_I2, "ldind.i2", 0x48)
+OP(LDIND_U2, "ldind.u2", 0x49)
+OP(LDIND_I4, "ldind.i4", 0x4a)
+OP(LDIND_U4, "ldind.u4", 0x4b)
+OP(LDIND_I8, "ldind.i8", 0x4c)
+OP(LDIND_I, "ldind.i", 0x4d)
+OP(LDIND_R4, "ldind.r4", 0x4e)
+OP(LDIND_R8, "ldind.r8", 0x4f)
+OP(LDIND_REF, "ldind.ref", 0x50)
+OP(STIND_REF, "stind.ref", 0x51)
+OP(STIND_I1, "stind.i1", 0x52)
+OP(STIND_I2, "stind.i2", 0x53)
+OP(STIND_I4, "stind.i4", 0x54)
+OP(STIND_I8, "stind.i8", 0x55)
+OP(STIND_R4, "stind.r4", 0x56)
+OP(STIND_R8, "stind.r8", 0x57)
+OP(ADD, "add", 0x58)
+OP(SUB, "sub", 0x59)
+OP(MUL, "mul", 0x5a)
+OP(DIV, "div", 0x5b)
+OP(DIV_UN, "div.un", 0x5c)
+OP(REM, "rem", 0x5d)
+OP(REM_UN, "rem.un", 0x5e)
+OP(AND, "and", 0x5f)
+OP(OR, "or", 0x60)
+OP(XOR, "xor", 0x61)
+OP(SHL, "shl", 0x62)
+OP(SHR, "shr", 0x63)
+OP(SHR_UN, "shr.un", 0x64)
+OP(NEG, "neg", 0x65)
+OP(NOT, "not", 0x66)
+OP(CONV_I1, "conv.i1", 0x67)
+OP(CONV_I2, "conv.i2", 0x68)
+OP(CONV_I4, "conv.i4", 0x69)
+OP(CONV_I8, "conv.i8", 0x6a)
+OP(CONV_R4, "conv.r4", 0x6b)
+OP(CONV_R8, "conv.r8", 0x6c)
+OP(CONV_U4, "conv.u4", 0x6d)
+OP(CONV_U8, "conv.u8", 0x6e)
+OP(CALLVIRT, "callvirt", 0x6f)
+OP(CPOBJ, "cpobj", 0x70)
+OP(LDOBJ, "ldobj", 0x71)
+OP(LDSTR, "ldstr", 0x72)
+OP(NEWOBJ, "newobj", 0x73)
+OP(CASTCLASS, "castclass", 0x74)
+OP(ISINST, "isinst", 0x75)
+OP(CONV_R_UN, "conv.r.un", 0x76)
+OP(ANN_DATA_S, "ann.data.s", 0x77)
+OP(UNBOX, "unbox", 0x79)
+OP(THROW, "throw", 0x7a)
+OP(LDFLD, "ldfld", 0x7b)
+OP(LDFLDA, "ldflda", 0x7c)
+OP(STFLD, "stfld", 0x7d)
+OP(LDSFLD, "ldsfld", 0x7e)
+OP(LDSFLDA, "ldsflda", 0x7f)
+OP(STSFLD, "stsfld", 0x80)
+OP(STOBJ, "stobj", 0x81)
+OP(CONV_OVF_I1_UN, "conv.ovf.i1.un", 0x82)
+OP(CONV_OVF_I2_UN, "conv.ovf.i2.un", 0x83)
+OP(CONV_OVF_I4_UN, "conv.ovf.i4.un", 0x84)
+OP(CONV_OVF_I8_UN, "conv.ovf.i8.un", 0x85)
+OP(CONV_OVF_U1_UN, "conv.ovf.u1.un", 0x86)
+OP(CONV_OVF_U2_UN, "conv.ovf.u2.un", 0x87)
+OP(CONV_OVF_U4_UN, "conv.ovf.u4.un", 0x88)
+OP(CONV_OVF_U8_UN, "conv.ovf.u8.un", 0x89)
+OP(CONV_OVF_I_UN, "conv.ovf.i.un", 0x8a)
+OP(CONV_OVF_U_UN, "conv.ovf.u.un", 0x8b)
+OP(BOX, "box", 0x8c)
+OP(NEWARR, "newarr", 0x8d)
+OP(LDLEN, "ldlen", 0x8e)
+OP(LDELEMA, "ldelema", 0x8f)
+OP(LDELEM_I1, "ldelem.i1", 0x90)
+OP(LDELEM_U1, "ldelem.u1", 0x91)
+OP(LDELEM_I2, "ldelem.i2", 0x92)
+OP(LDELEM_U2, "ldelem.u2", 0x93)
+OP(LDELEM_I4, "ldelem.i4", 0x94)
+OP(LDELEM_U4, "ldelem.u4", 0x95)
+OP(LDELEM_I8, "ldelem.i8", 0x96)
+OP(LDELEM_I, "ldelem.i", 0x97)
+OP(LDELEM_R4, "ldelem.r4", 0x98)
+OP(LDELEM_R8, "ldelem.r8", 0x99)
+OP(LDELEM_REF, "ldelem.ref", 0x9a)
+OP(STELEM_I, "stelem.i", 0x9b)
+OP(STELEM_I1, "stelem.i1", 0x9c)
+OP(STELEM_I2, "stelem.i2", 0x9d)
+OP(STELEM_I4, "stelem.i4", 0x9e)
+OP(STELEM_I8, "stelem.i8", 0x9f)
+OP(STELEM_R4, "stelem.r4", 0xa0)
+OP(STELEM_R8, "stelem.r8", 0xa1)
+OP(STELEM_REF, "stelem.ref", 0xa2)
+OP(CONV_OVF_I1, "conv.ovf.i1", 0xb3)
+OP(CONV_OVF_U1, "conv.ovf.u1", 0xb4)
+OP(CONV_OVF_I2, "conv.ovf.i2", 0xb5)
+OP(CONV_OVF_U2, "conv.ovf.u2", 0xb6)
+OP(CONV_OVF_I4, "conv.ovf.i4", 0xb7)
+OP(CONV_OVF_U4, "conv.ovf.u4", 0xb8)
+OP(CONV_OVF_I8, "conv.ovf.i8", 0xb9)
+OP(CONV_OVF_U8, "conv.ovf.u8", 0xba)
+OP(REFANYVAL, "refanyval", 0xc2)
+OP(CKFINITE, "ckfinite", 0xc3)
+OP(MKREFANY, "mkrefany", 0xc6)
+OP(ANN_CALL, "ann.call", 0xc7)
+OP(ANN_CATCH, "ann.catch", 0xc8)
+OP(ANN_DEAD, "ann.dead", 0xc9)
+OP(ANN_HOISTED, "ann.hoisted", 0xca)
+OP(ANN_HOISTED_CALL, "ann.hoisted.call", 0xcb)
+OP(ANN_LAB, "ann.lab", 0xcc)
+OP(ANN_DEF, "ann.def", 0xcd)
+OP(ANN_REF_S, "ann.ref.s", 0xce)
+OP(ANN_PHI, "ann.phi", 0xcf)
+OP(LDTOKEN, "ldtoken", 0xd0)
+OP(CONV_U2, "conv.u2", 0xd1)
+OP(CONV_U1, "conv.u1", 0xd2)
+OP(CONV_I, "conv.i", 0xd3)
+OP(CONV_OVF_I, "conv.ovf.i", 0xd4)
+OP(CONV_OVF_U, "conv.ovf.u", 0xd5)
+OP(ADD_OVF, "add.ovf", 0xd6)
+OP(ADD_OVF_UN, "add.ovf.un", 0xd7)
+OP(MUL_OVF, "mul.ovf", 0xd8)
+OP(MUL_OVF_UN, "mul.ovf.un", 0xd9)
+OP(SUB_OVF, "sub.ovf", 0xda)
+OP(SUB_OVF_UN, "sub.ovf.un", 0xdb)
+OP(ENDFINALLY, "endfinally", 0xdc)
+OP(LEAVE, "leave", 0xdd)
+OP(LEAVE_S, "leave.s", 0xde)
+OP(STIND_I, "stind.i", 0xdf)
+OP(CONV_U, "conv.u", 0xe0)
+
+/* prefix instructions. we use an opcode >= 256 to ease coding */
+
+OP(ARGLIST, "arglist", 0x100)
+OP(CEQ, "ceq", 0x101)
+OP(CGT, "cgt", 0x102)
+OP(CGT_UN, "cgt.un", 0x103)
+OP(CLT, "clt", 0x104)
+OP(CLT_UN, "clt.un", 0x105)
+OP(LDFTN, "ldftn", 0x106)
+OP(LDVIRTFTN, "ldvirtftn", 0x107)
+OP(JMPI, "jmpi", 0x108)
+OP(LDARG, "ldarg", 0x109)
+OP(LDARGA, "ldarga", 0x10a)
+OP(STARG, "starg", 0x10b)
+OP(LDLOC, "ldloc", 0x10c)
+OP(LDLOCA, "ldloca", 0x10d)
+OP(STLOC, "stloc", 0x10e)
+OP(LOCALLOC, "localloc", 0x10f)
+OP(ENDFILTER, "endfilter", 0x111)
+OP(UNALIGNED, "unaligned", 0x112)
+OP(VOLATILE, "volatile", 0x113)
+OP(TAIL, "tail", 0x114)
+OP(INITOBJ, "initobj", 0x115)
+OP(ANN_LIVE, "ann.live", 0x116)
+OP(CPBLK, "cpblk", 0x117)
+OP(INITBLK, "initblk", 0x118)
+OP(ANN_REF, "ann.ref", 0x119)
+OP(RETHROW, "rethrow", 0x11a)
+OP(SIZEOF, "sizeof", 0x11c)
+OP(REFANYTYPE, "refanytype", 0x11d)
+OP(ANN_DATA, "ann.data", 0x122)
+OP(ANN_ARG, "ann.arg", 0x123)
diff --git a/include/float.h b/include/float.h
new file mode 100644
index 0000000..f16f1f0
--- /dev/null
+++ b/include/float.h
@@ -0,0 +1,57 @@
+#ifndef _FLOAT_H_
+#define _FLOAT_H_
+
+#define FLT_RADIX 2
+
+/* IEEE float */
+#define FLT_MANT_DIG 24
+#define FLT_DIG 6
+#define FLT_ROUNDS 1
+#define FLT_EPSILON 1.19209290e-07F
+#define FLT_MIN_EXP (-125)
+#define FLT_MIN 1.17549435e-38F
+#define FLT_MIN_10_EXP (-37)
+#define FLT_MAX_EXP 128
+#define FLT_MAX 3.40282347e+38F
+#define FLT_MAX_10_EXP 38
+
+/* IEEE double */
+#define DBL_MANT_DIG 53
+#define DBL_DIG 15
+#define DBL_EPSILON 2.2204460492503131e-16
+#define DBL_MIN_EXP (-1021)
+#define DBL_MIN 2.2250738585072014e-308
+#define DBL_MIN_10_EXP (-307)
+#define DBL_MAX_EXP 1024
+#define DBL_MAX 1.7976931348623157e+308
+#define DBL_MAX_10_EXP 308
+
+/* horrible intel long double */
+#if defined __i386__ || defined __x86_64__
+
+#define LDBL_MANT_DIG 64
+#define LDBL_DIG 18
+#define LDBL_EPSILON 1.08420217248550443401e-19L
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MIN 3.36210314311209350626e-4932L
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_EXP 16384
+#define LDBL_MAX 1.18973149535723176502e+4932L
+#define LDBL_MAX_10_EXP 4932
+
+#else
+
+/* same as IEEE double */
+#define LDBL_MANT_DIG 53
+#define LDBL_DIG 15
+#define LDBL_EPSILON 2.2204460492503131e-16
+#define LDBL_MIN_EXP (-1021)
+#define LDBL_MIN 2.2250738585072014e-308
+#define LDBL_MIN_10_EXP (-307)
+#define LDBL_MAX_EXP 1024
+#define LDBL_MAX 1.7976931348623157e+308
+#define LDBL_MAX_10_EXP 308
+
+#endif
+
+#endif /* _FLOAT_H_ */
diff --git a/include/stdarg.h b/include/stdarg.h
new file mode 100644
index 0000000..10ce733
--- /dev/null
+++ b/include/stdarg.h
@@ -0,0 +1,79 @@
+#ifndef _STDARG_H
+#define _STDARG_H
+
+#ifdef __x86_64__
+#ifndef _WIN64
+
+//This should be in sync with the declaration on our lib/libtcc1.c
+/* GCC compatible definition of va_list. */
+typedef struct {
+ unsigned int gp_offset;
+ unsigned int fp_offset;
+ union {
+ unsigned int overflow_offset;
+ char *overflow_arg_area;
+ };
+ char *reg_save_area;
+} __va_list_struct;
+
+typedef __va_list_struct va_list[1];
+
+void __va_start(__va_list_struct *ap, void *fp);
+void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align);
+
+#define va_start(ap, last) __va_start(ap, __builtin_frame_address(0))
+#define va_arg(ap, type) \
+ (*(type *)(__va_arg(ap, __builtin_va_arg_types(type), sizeof(type), __alignof__(type))))
+#define va_copy(dest, src) (*(dest) = *(src))
+#define va_end(ap)
+
+/* avoid conflicting definition for va_list on Macs. */
+#define _VA_LIST_T
+
+#else /* _WIN64 */
+typedef char *va_list;
+#define va_start(ap,last) __builtin_va_start(ap,last)
+#define va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \
+ ? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8))
+#define va_copy(dest, src) ((dest) = (src))
+#define va_end(ap)
+#endif
+
+#elif __arm__
+typedef char *va_list;
+#define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x)
+#define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \
+ & ~(_tcc_alignof(type) - 1))
+#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)
+#define va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \
+ &~3), *(type *)(ap - ((sizeof(type)+3)&~3)))
+#define va_copy(dest, src) (dest) = (src)
+#define va_end(ap)
+
+#elif defined(__aarch64__)
+typedef struct {
+ void *__stack;
+ void *__gr_top;
+ void *__vr_top;
+ int __gr_offs;
+ int __vr_offs;
+} va_list;
+#define va_start(ap, last) __va_start(ap, last)
+#define va_arg(ap, type) __va_arg(ap, type)
+#define va_end(ap)
+#define va_copy(dest, src) ((dest) = (src))
+
+#else /* __i386__ */
+typedef char *va_list;
+/* only correct for i386 */
+#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)
+#define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3)))
+#define va_copy(dest, src) (dest) = (src)
+#define va_end(ap)
+#endif
+
+/* fix a buggy dependency on GCC in libio.h */
+typedef va_list __gnuc_va_list;
+#define _VA_LIST_DEFINED
+
+#endif /* _STDARG_H */
diff --git a/include/stdbool.h b/include/stdbool.h
new file mode 100644
index 0000000..d2ee446
--- /dev/null
+++ b/include/stdbool.h
@@ -0,0 +1,11 @@
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+/* ISOC99 boolean */
+
+#define bool _Bool
+#define true 1
+#define false 0
+#define __bool_true_false_are_defined 1
+
+#endif /* _STDBOOL_H */
diff --git a/include/stddef.h b/include/stddef.h
new file mode 100644
index 0000000..694d503
--- /dev/null
+++ b/include/stddef.h
@@ -0,0 +1,54 @@
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+typedef __SIZE_TYPE__ size_t;
+typedef __PTRDIFF_TYPE__ ssize_t;
+typedef __WCHAR_TYPE__ wchar_t;
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __PTRDIFF_TYPE__ intptr_t;
+typedef __SIZE_TYPE__ uintptr_t;
+
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef signed char int8_t;
+typedef signed short int int16_t;
+typedef signed int int32_t;
+#ifdef __LP64__
+typedef signed long int int64_t;
+#else
+typedef signed long long int int64_t;
+#endif
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned int uint32_t;
+#ifdef __LP64__
+typedef unsigned long int uint64_t;
+#else
+typedef unsigned long long int uint64_t;
+#endif
+#endif
+
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
+
+#define offsetof(type, field) ((size_t)&((type *)0)->field)
+
+void *alloca(size_t size);
+
+#endif
+
+/* Older glibc require a wint_t from <stddef.h> (when requested
+ by __need_wint_t, as otherwise stddef.h isn't allowed to
+ define this type). Note that this must be outside the normal
+ _STDDEF_H guard, so that it works even when we've included the file
+ already (without requiring wint_t). Some other libs define _WINT_T
+ if they've already provided that type, so we can use that as guard.
+ TCC defines __WINT_TYPE__ for us. */
+#if defined (__need_wint_t)
+#ifndef _WINT_T
+#define _WINT_T
+typedef __WINT_TYPE__ wint_t;
+#endif
+#undef __need_wint_t
+#endif
diff --git a/include/varargs.h b/include/varargs.h
new file mode 100644
index 0000000..d614366
--- /dev/null
+++ b/include/varargs.h
@@ -0,0 +1,12 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _VARARGS_H
+#define _VARARGS_H
+
+#error "TinyCC no longer implements <varargs.h>."
+#error "Revise your code to use <stdarg.h>."
+
+#endif
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 0000000..0c1ec54
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,73 @@
+#
+# Tiny C Compiler Makefile for libtcc1.a
+#
+
+TOP = ..
+include $(TOP)/Makefile
+VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
+T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
+X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
+BIN = $(TOP)/$(X)libtcc1.a
+
+XTCC ?= $(TOP)/$(X)tcc$(EXESUF)
+XCC = $(XTCC)
+XAR = $(XTCC) -ar
+XFLAGS-unx = -B$(TOPSRC)
+XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include
+XFLAGS = $(XFLAGS$(XCFG))
+XCFG = $(or $(findstring -win,$T),-unx)
+
+# in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes
+arm-libtcc1-usegcc ?= no
+
+ifeq "$($(T)-libtcc1-usegcc)" "yes"
+ XCC = $(CC)
+ XAR = $(AR)
+ XFLAGS = $(CFLAGS) -fPIC
+endif
+
+# only for native compiler
+$(X)BCHECK_O = bcheck.o
+
+ifeq ($(CONFIG_musl)$(CONFIG_uClibc),yes)
+ BCHECK_O =
+endif
+
+ifdef CONFIG_OSX
+ XFLAGS += -D_ANSI_SOURCE
+endif
+
+I386_O = libtcc1.o alloca86.o alloca86-bt.o
+X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o
+ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o
+ARM64_O = lib-arm64.o
+WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
+
+OBJ-i386 = $(I386_O) $(BCHECK_O)
+OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O)
+OBJ-x86_64-osx = $(X86_64_O) va_list.o
+OBJ-i386-win32 = $(I386_O) chkstk.o bcheck.o $(WIN_O)
+OBJ-x86_64-win32 = $(X86_64_O) chkstk.o bcheck.o $(WIN_O)
+OBJ-arm64 = $(ARM64_O)
+OBJ-arm = $(ARM_O)
+OBJ-arm-fpa = $(ARM_O)
+OBJ-arm-fpa-ld = $(ARM_O)
+OBJ-arm-vfp = $(ARM_O)
+OBJ-arm-eabi = $(ARM_O)
+OBJ-arm-eabihf = $(ARM_O)
+OBJ-arm-wince = $(ARM_O) $(WIN_O)
+
+$(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T))
+ $(XAR) rcs $@ $^
+
+$(X)%.o : %.c
+ $(XCC) -c $< -o $@ $(XFLAGS)
+
+$(X)%.o : %.S
+ $(XCC) -c $< -o $@ $(XFLAGS)
+
+$(X)crt1w.o : crt1.c
+$(X)wincrt1w.o : wincrt1.c
+
+clean :
+ rm -f *.a *.o $(BIN)
diff --git a/lib/alloca-arm.S b/lib/alloca-arm.S
new file mode 100644
index 0000000..68556e3
--- /dev/null
+++ b/lib/alloca-arm.S
@@ -0,0 +1,17 @@
+ .text
+ .align 2
+ .global alloca
+ .type alloca, %function
+alloca:
+#ifdef __TINYC__
+ .int 0xe060d00d
+ .int 0xe3cdd007
+ .int 0xe1a0000d
+ .int 0xe1a0f00e
+#else
+ rsb sp, r0, sp
+ bic sp, sp, #7
+ mov r0, sp
+ mov pc, lr
+#endif
+ .size alloca, .-alloca
diff --git a/lib/alloca86-bt.S b/lib/alloca86-bt.S
new file mode 100644
index 0000000..4f95cf1
--- /dev/null
+++ b/lib/alloca86-bt.S
@@ -0,0 +1,47 @@
+/* ---------------------------------------------- */
+/* alloca86-bt.S */
+
+.globl __bound_alloca
+
+__bound_alloca:
+ pop %edx
+ pop %eax
+ mov %eax, %ecx
+ add $3,%eax
+ and $-4,%eax
+ jz p6
+
+#ifdef _WIN32
+p4:
+ cmp $4096,%eax
+ jbe p5
+ test %eax,-4096(%esp)
+ sub $4096,%esp
+ sub $4096,%eax
+ jmp p4
+
+p5:
+#endif
+
+ sub %eax,%esp
+ mov %esp,%eax
+
+ push %edx
+ push %eax
+ push %ecx
+ push %eax
+ call __bound_new_region
+ add $8, %esp
+ pop %eax
+ pop %edx
+
+p6:
+ push %edx
+ push %edx
+ ret
+
+/* mark stack as nonexecutable */
+#if defined __ELF__ && defined __linux__
+ .section .note.GNU-stack,"",@progbits
+#endif
+/* ---------------------------------------------- */
diff --git a/lib/alloca86.S b/lib/alloca86.S
new file mode 100644
index 0000000..bb7a2c2
--- /dev/null
+++ b/lib/alloca86.S
@@ -0,0 +1,31 @@
+/* ---------------------------------------------- */
+/* alloca86.S */
+
+.globl alloca
+
+alloca:
+ pop %edx
+ pop %eax
+ add $3,%eax
+ and $-4,%eax
+ jz p3
+
+#ifdef _WIN32
+p1:
+ cmp $4096,%eax
+ jbe p2
+ test %eax,-4096(%esp)
+ sub $4096,%esp
+ sub $4096,%eax
+ jmp p1
+p2:
+#endif
+
+ sub %eax,%esp
+ mov %esp,%eax
+p3:
+ push %edx
+ push %edx
+ ret
+
+/* ---------------------------------------------- */
diff --git a/lib/alloca86_64-bt.S b/lib/alloca86_64-bt.S
new file mode 100644
index 0000000..4cbad90
--- /dev/null
+++ b/lib/alloca86_64-bt.S
@@ -0,0 +1,56 @@
+/* ---------------------------------------------- */
+/* alloca86_64.S */
+
+.globl __bound_alloca
+__bound_alloca:
+
+#ifdef _WIN32
+ # bound checking is not implemented
+ pop %rdx
+ mov %rcx,%rax
+ add $15,%rax
+ and $-16,%rax
+ jz p3
+
+p1:
+ cmp $4096,%rax
+ jbe p2
+ test %rax,-4096(%rsp)
+ sub $4096,%rsp
+ sub $4096,%rax
+ jmp p1
+p2:
+
+ sub %rax,%rsp
+ mov %rsp,%rax
+ add $32,%rax
+
+p3:
+ push %rdx
+ ret
+#else
+ pop %rdx
+ mov %rdi,%rax
+ mov %rax,%rsi # size, a second parm to the __bound_new_region
+
+ add $15,%rax
+ and $-16,%rax
+ jz p3
+
+
+ sub %rax,%rsp
+ mov %rsp,%rdi # pointer, a first parm to the __bound_new_region
+ mov %rsp,%rax
+
+ push %rdx
+ push %rax
+ call __bound_new_region
+ pop %rax
+ pop %rdx
+
+p3:
+ push %rdx
+ ret
+#endif
+
+/* ---------------------------------------------- */
diff --git a/lib/alloca86_64.S b/lib/alloca86_64.S
new file mode 100644
index 0000000..ae3c97d
--- /dev/null
+++ b/lib/alloca86_64.S
@@ -0,0 +1,34 @@
+/* ---------------------------------------------- */
+/* alloca86_64.S */
+
+.globl alloca
+
+alloca:
+ pop %rdx
+#ifdef _WIN32
+ mov %rcx,%rax
+#else
+ mov %rdi,%rax
+#endif
+ add $15,%rax
+ and $-16,%rax
+ jz p3
+
+#ifdef _WIN32
+p1:
+ cmp $4096,%rax
+ jbe p2
+ test %rax,-4096(%rsp)
+ sub $4096,%rsp
+ sub $4096,%rax
+ jmp p1
+p2:
+#endif
+
+ sub %rax,%rsp
+ mov %rsp,%rax
+p3:
+ push %rdx
+ ret
+
+/* ---------------------------------------------- */
diff --git a/lib/armeabi.c b/lib/armeabi.c
new file mode 100644
index 0000000..a59640d
--- /dev/null
+++ b/lib/armeabi.c
@@ -0,0 +1,501 @@
+/* TCC ARM runtime EABI
+ Copyright (C) 2013 Thomas Preud'homme
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.*/
+
+#ifdef __TINYC__
+#define INT_MIN (-2147483647 - 1)
+#define INT_MAX 2147483647
+#define UINT_MAX 0xffffffff
+#define LONG_MIN (-2147483647L - 1)
+#define LONG_MAX 2147483647L
+#define ULONG_MAX 0xffffffffUL
+#define LLONG_MAX 9223372036854775807LL
+#define LLONG_MIN (-9223372036854775807LL - 1)
+#define ULLONG_MAX 0xffffffffffffffffULL
+#else
+#include <limits.h>
+#endif
+
+/* We rely on the little endianness and EABI calling convention for this to
+ work */
+
+typedef struct double_unsigned_struct {
+ unsigned low;
+ unsigned high;
+} double_unsigned_struct;
+
+typedef struct unsigned_int_struct {
+ unsigned low;
+ int high;
+} unsigned_int_struct;
+
+#define REGS_RETURN(name, type) \
+ void name ## _return(type ret) {}
+
+
+/* Float helper functions */
+
+#define FLOAT_EXP_BITS 8
+#define FLOAT_FRAC_BITS 23
+
+#define DOUBLE_EXP_BITS 11
+#define DOUBLE_FRAC_BITS 52
+
+#define ONE_EXP(type) ((1 << (type ## _EXP_BITS - 1)) - 1)
+
+REGS_RETURN(unsigned_int_struct, unsigned_int_struct)
+REGS_RETURN(double_unsigned_struct, double_unsigned_struct)
+
+/* float -> integer: (sign) 1.fraction x 2^(exponent - exp_for_one) */
+
+
+/* float to [unsigned] long long conversion */
+#define DEFINE__AEABI_F2XLZ(name, with_sign) \
+void __aeabi_ ## name(unsigned val) \
+{ \
+ int exp, high_shift, sign; \
+ double_unsigned_struct ret; \
+ \
+ /* compute sign */ \
+ sign = val >> 31; \
+ \
+ /* compute real exponent */ \
+ exp = val >> FLOAT_FRAC_BITS; \
+ exp &= (1 << FLOAT_EXP_BITS) - 1; \
+ exp -= ONE_EXP(FLOAT); \
+ \
+ /* undefined behavior if truncated value cannot be represented */ \
+ if (with_sign) { \
+ if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
+ return; \
+ } else { \
+ if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \
+ return; \
+ } \
+ \
+ val &= (1 << FLOAT_FRAC_BITS) - 1; \
+ if (exp >= 32) { \
+ ret.high = 1 << (exp - 32); \
+ if (exp - 32 >= FLOAT_FRAC_BITS) { \
+ ret.high |= val << (exp - 32 - FLOAT_FRAC_BITS); \
+ ret.low = 0; \
+ } else { \
+ high_shift = FLOAT_FRAC_BITS - (exp - 32); \
+ ret.high |= val >> high_shift; \
+ ret.low = val << (32 - high_shift); \
+ } \
+ } else { \
+ ret.high = 0; \
+ ret.low = 1 << exp; \
+ if (exp > FLOAT_FRAC_BITS) \
+ ret.low |= val << (exp - FLOAT_FRAC_BITS); \
+ else \
+ ret.low |= val >> (FLOAT_FRAC_BITS - exp); \
+ } \
+ \
+ /* encode negative integer using 2's complement */ \
+ if (with_sign && sign) { \
+ ret.low = ~ret.low; \
+ ret.high = ~ret.high; \
+ if (ret.low == UINT_MAX) { \
+ ret.low = 0; \
+ ret.high++; \
+ } else \
+ ret.low++; \
+ } \
+ \
+ double_unsigned_struct_return(ret); \
+}
+
+/* float to unsigned long long conversion */
+DEFINE__AEABI_F2XLZ(f2ulz, 0)
+
+/* float to long long conversion */
+DEFINE__AEABI_F2XLZ(f2lz, 1)
+
+/* double to [unsigned] long long conversion */
+#define DEFINE__AEABI_D2XLZ(name, with_sign) \
+void __aeabi_ ## name(double_unsigned_struct val) \
+{ \
+ int exp, high_shift, sign; \
+ double_unsigned_struct ret; \
+ \
+ /* compute sign */ \
+ sign = val.high >> 31; \
+ \
+ /* compute real exponent */ \
+ exp = (val.high >> (DOUBLE_FRAC_BITS - 32)); \
+ exp &= (1 << DOUBLE_EXP_BITS) - 1; \
+ exp -= ONE_EXP(DOUBLE); \
+ \
+ /* undefined behavior if truncated value cannot be represented */ \
+ if (with_sign) { \
+ if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
+ return; \
+ } else { \
+ if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \
+ return; \
+ } \
+ \
+ val.high &= (1 << (DOUBLE_FRAC_BITS - 32)) - 1; \
+ if (exp >= 32) { \
+ ret.high = 1 << (exp - 32); \
+ if (exp >= DOUBLE_FRAC_BITS) { \
+ high_shift = exp - DOUBLE_FRAC_BITS; \
+ ret.high |= val.high << high_shift; \
+ ret.high |= val.low >> (32 - high_shift); \
+ ret.low = val.low << high_shift; \
+ } else { \
+ high_shift = DOUBLE_FRAC_BITS - exp; \
+ ret.high |= val.high >> high_shift; \
+ ret.low = val.high << (32 - high_shift); \
+ ret.low |= val.low >> high_shift; \
+ } \
+ } else { \
+ ret.high = 0; \
+ ret.low = 1 << exp; \
+ if (exp > DOUBLE_FRAC_BITS - 32) { \
+ high_shift = exp - DOUBLE_FRAC_BITS - 32; \
+ ret.low |= val.high << high_shift; \
+ ret.low |= val.low >> (32 - high_shift); \
+ } else \
+ ret.low |= val.high >> (DOUBLE_FRAC_BITS - 32 - exp); \
+ } \
+ \
+ /* encode negative integer using 2's complement */ \
+ if (with_sign && sign) { \
+ ret.low = ~ret.low; \
+ ret.high = ~ret.high; \
+ if (ret.low == UINT_MAX) { \
+ ret.low = 0; \
+ ret.high++; \
+ } else \
+ ret.low++; \
+ } \
+ \
+ double_unsigned_struct_return(ret); \
+}
+
+/* double to unsigned long long conversion */
+DEFINE__AEABI_D2XLZ(d2ulz, 0)
+
+/* double to long long conversion */
+DEFINE__AEABI_D2XLZ(d2lz, 1)
+
+/* long long to float conversion */
+#define DEFINE__AEABI_XL2F(name, with_sign) \
+unsigned __aeabi_ ## name(unsigned long long v) \
+{ \
+ int s /* shift */, flb /* first lost bit */, sign = 0; \
+ unsigned p = 0 /* power */, ret; \
+ double_unsigned_struct val; \
+ \
+ /* fraction in negative float is encoded in 1's complement */ \
+ if (with_sign && (v & (1ULL << 63))) { \
+ sign = 1; \
+ v = ~v + 1; \
+ } \
+ val.low = v; \
+ val.high = v >> 32; \
+ /* fill fraction bits */ \
+ for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \
+ if (p) { \
+ ret = val.high & (p - 1); \
+ if (s < FLOAT_FRAC_BITS) { \
+ ret <<= FLOAT_FRAC_BITS - s; \
+ ret |= val.low >> (32 - (FLOAT_FRAC_BITS - s)); \
+ flb = (val.low >> (32 - (FLOAT_FRAC_BITS - s - 1))) & 1; \
+ } else { \
+ flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \
+ ret >>= s - FLOAT_FRAC_BITS; \
+ } \
+ s += 32; \
+ } else { \
+ for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \
+ if (p) { \
+ ret = val.low & (p - 1); \
+ if (s <= FLOAT_FRAC_BITS) { \
+ ret <<= FLOAT_FRAC_BITS - s; \
+ flb = 0; \
+ } else { \
+ flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \
+ ret >>= s - FLOAT_FRAC_BITS; \
+ } \
+ } else \
+ return 0; \
+ } \
+ if (flb) \
+ ret++; \
+ \
+ /* fill exponent bits */ \
+ ret |= (s + ONE_EXP(FLOAT)) << FLOAT_FRAC_BITS; \
+ \
+ /* fill sign bit */ \
+ ret |= sign << 31; \
+ \
+ return ret; \
+}
+
+/* unsigned long long to float conversion */
+DEFINE__AEABI_XL2F(ul2f, 0)
+
+/* long long to float conversion */
+DEFINE__AEABI_XL2F(l2f, 1)
+
+/* long long to double conversion */
+#define __AEABI_XL2D(name, with_sign) \
+void __aeabi_ ## name(unsigned long long v) \
+{ \
+ int s /* shift */, high_shift, sign = 0; \
+ unsigned tmp, p = 0; \
+ double_unsigned_struct val, ret; \
+ \
+ /* fraction in negative float is encoded in 1's complement */ \
+ if (with_sign && (v & (1ULL << 63))) { \
+ sign = 1; \
+ v = ~v + 1; \
+ } \
+ val.low = v; \
+ val.high = v >> 32; \
+ \
+ /* fill fraction bits */ \
+ for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \
+ if (p) { \
+ tmp = val.high & (p - 1); \
+ if (s < DOUBLE_FRAC_BITS - 32) { \
+ high_shift = DOUBLE_FRAC_BITS - 32 - s; \
+ ret.high = tmp << high_shift; \
+ ret.high |= val.low >> (32 - high_shift); \
+ ret.low = val.low << high_shift; \
+ } else { \
+ high_shift = s - (DOUBLE_FRAC_BITS - 32); \
+ ret.high = tmp >> high_shift; \
+ ret.low = tmp << (32 - high_shift); \
+ ret.low |= val.low >> high_shift; \
+ if ((val.low >> (high_shift - 1)) & 1) { \
+ if (ret.low == UINT_MAX) { \
+ ret.high++; \
+ ret.low = 0; \
+ } else \
+ ret.low++; \
+ } \
+ } \
+ s += 32; \
+ } else { \
+ for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \
+ if (p) { \
+ tmp = val.low & (p - 1); \
+ if (s <= DOUBLE_FRAC_BITS - 32) { \
+ high_shift = DOUBLE_FRAC_BITS - 32 - s; \
+ ret.high = tmp << high_shift; \
+ ret.low = 0; \
+ } else { \
+ high_shift = s - (DOUBLE_FRAC_BITS - 32); \
+ ret.high = tmp >> high_shift; \
+ ret.low = tmp << (32 - high_shift); \
+ } \
+ } else { \
+ ret.high = ret.low = 0; \
+ double_unsigned_struct_return(ret); \
+ } \
+ } \
+ \
+ /* fill exponent bits */ \
+ ret.high |= (s + ONE_EXP(DOUBLE)) << (DOUBLE_FRAC_BITS - 32); \
+ \
+ /* fill sign bit */ \
+ ret.high |= sign << 31; \
+ \
+ double_unsigned_struct_return(ret); \
+}
+
+/* unsigned long long to double conversion */
+__AEABI_XL2D(ul2d, 0)
+
+/* long long to double conversion */
+__AEABI_XL2D(l2d, 1)
+
+
+/* Long long helper functions */
+
+/* TODO: add error in case of den == 0 (see §4.3.1 and §4.3.2) */
+
+#define define_aeabi_xdivmod_signed_type(basetype, type) \
+typedef struct type { \
+ basetype quot; \
+ unsigned basetype rem; \
+} type
+
+#define define_aeabi_xdivmod_unsigned_type(basetype, type) \
+typedef struct type { \
+ basetype quot; \
+ basetype rem; \
+} type
+
+#define AEABI_UXDIVMOD(name,type, rettype, typemacro) \
+static inline rettype aeabi_ ## name (type num, type den) \
+{ \
+ rettype ret; \
+ type quot = 0; \
+ \
+ /* Increase quotient while it is less than numerator */ \
+ while (num >= den) { \
+ type q = 1; \
+ \
+ /* Find closest power of two */ \
+ while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \
+ q <<= 1; \
+ \
+ /* Compute difference between current quotient and numerator */ \
+ num -= q * den; \
+ quot += q; \
+ } \
+ ret.quot = quot; \
+ ret.rem = num; \
+ return ret; \
+}
+
+#define __AEABI_XDIVMOD(name, type, uiname, rettype, urettype, typemacro) \
+void __aeabi_ ## name(type numerator, type denominator) \
+{ \
+ unsigned type num, den; \
+ urettype uxdiv_ret; \
+ rettype ret; \
+ \
+ if (numerator >= 0) \
+ num = numerator; \
+ else \
+ num = 0 - numerator; \
+ if (denominator >= 0) \
+ den = denominator; \
+ else \
+ den = 0 - denominator; \
+ uxdiv_ret = aeabi_ ## uiname(num, den); \
+ /* signs differ */ \
+ if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \
+ ret.quot = 0 - uxdiv_ret.quot; \
+ else \
+ ret.quot = uxdiv_ret.quot; \
+ if (numerator < 0) \
+ ret.rem = 0 - uxdiv_ret.rem; \
+ else \
+ ret.rem = uxdiv_ret.rem; \
+ \
+ rettype ## _return(ret); \
+}
+
+define_aeabi_xdivmod_signed_type(long long, lldiv_t);
+define_aeabi_xdivmod_unsigned_type(unsigned long long, ulldiv_t);
+define_aeabi_xdivmod_signed_type(int, idiv_t);
+define_aeabi_xdivmod_unsigned_type(unsigned, uidiv_t);
+
+REGS_RETURN(lldiv_t, lldiv_t)
+REGS_RETURN(ulldiv_t, ulldiv_t)
+REGS_RETURN(idiv_t, idiv_t)
+REGS_RETURN(uidiv_t, uidiv_t)
+
+AEABI_UXDIVMOD(uldivmod, unsigned long long, ulldiv_t, ULLONG)
+
+__AEABI_XDIVMOD(ldivmod, long long, uldivmod, lldiv_t, ulldiv_t, LLONG)
+
+void __aeabi_uldivmod(unsigned long long num, unsigned long long den)
+{
+ ulldiv_t_return(aeabi_uldivmod(num, den));
+}
+
+void __aeabi_llsl(double_unsigned_struct val, int shift)
+{
+ double_unsigned_struct ret;
+
+ if (shift >= 32) {
+ val.high = val.low;
+ val.low = 0;
+ shift -= 32;
+ }
+ if (shift > 0) {
+ ret.low = val.low << shift;
+ ret.high = (val.high << shift) | (val.low >> (32 - shift));
+ double_unsigned_struct_return(ret);
+ return;
+ }
+ double_unsigned_struct_return(val);
+}
+
+#define aeabi_lsr(val, shift, fill, type) \
+ type ## _struct ret; \
+ \
+ if (shift >= 32) { \
+ val.low = val.high; \
+ val.high = fill; \
+ shift -= 32; \
+ } \
+ if (shift > 0) { \
+ ret.high = val.high >> shift; \
+ ret.low = (val.high << (32 - shift)) | (val.low >> shift); \
+ type ## _struct_return(ret); \
+ return; \
+ } \
+ type ## _struct_return(val);
+
+void __aeabi_llsr(double_unsigned_struct val, int shift)
+{
+ aeabi_lsr(val, shift, 0, double_unsigned);
+}
+
+void __aeabi_lasr(unsigned_int_struct val, int shift)
+{
+ aeabi_lsr(val, shift, val.high >> 31, unsigned_int);
+}
+
+
+/* Integer division functions */
+
+AEABI_UXDIVMOD(uidivmod, unsigned, uidiv_t, UINT)
+
+int __aeabi_idiv(int numerator, int denominator)
+{
+ unsigned num, den;
+ uidiv_t ret;
+
+ if (numerator >= 0)
+ num = numerator;
+ else
+ num = 0 - numerator;
+ if (denominator >= 0)
+ den = denominator;
+ else
+ den = 0 - denominator;
+ ret = aeabi_uidivmod(num, den);
+ if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */
+ ret.quot *= -1;
+ return ret.quot;
+}
+
+unsigned __aeabi_uidiv(unsigned num, unsigned den)
+{
+ return aeabi_uidivmod(num, den).quot;
+}
+
+__AEABI_XDIVMOD(idivmod, int, uidivmod, idiv_t, uidiv_t, INT)
+
+void __aeabi_uidivmod(unsigned num, unsigned den)
+{
+ uidiv_t_return(aeabi_uidivmod(num, den));
+}
diff --git a/lib/armflush.c b/lib/armflush.c
new file mode 100644
index 0000000..eae3260
--- /dev/null
+++ b/lib/armflush.c
@@ -0,0 +1,58 @@
+/* armflush.c - flush the instruction cache
+
+ __clear_cache is used in tccrun.c, It is a built-in
+ intrinsic with gcc. However tcc in order to compile
+ itself needs this function */
+
+#ifdef __TINYC__
+
+/* syscall wrapper */
+unsigned syscall(unsigned syscall_nr, ...);
+
+/* arm-tcc supports only fake asm currently */
+__asm__(
+ ".global syscall\n"
+ "syscall:\n"
+ ".int 0xe92d4080\n" // push {r7, lr}
+ ".int 0xe1a07000\n" // mov r7, r0
+ ".int 0xe1a00001\n" // mov r0, r1
+ ".int 0xe1a01002\n" // mov r1, r2
+ ".int 0xe1a02003\n" // mov r2, r3
+ ".int 0xef000000\n" // svc 0x00000000
+ ".int 0xe8bd8080\n" // pop {r7, pc}
+ );
+
+/* from unistd.h: */
+#if defined(__thumb__) || defined(__ARM_EABI__)
+# define __NR_SYSCALL_BASE 0x0
+#else
+# define __NR_SYSCALL_BASE 0x900000
+#endif
+#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
+#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
+
+#else
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <stdio.h>
+
+#endif
+
+/* Flushing for tccrun */
+void __clear_cache(void *beginning, void *end)
+{
+/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
+ * However, there is no ARM asm parser in tcc so we use it for now */
+#if 1
+ syscall(__ARM_NR_cacheflush, beginning, end, 0);
+#else
+ __asm__ ("push {r7}\n\t"
+ "mov r7, #0xf0002\n\t"
+ "mov r2, #0\n\t"
+ "swi 0\n\t"
+ "pop {r7}\n\t"
+ "ret");
+#endif
+}
diff --git a/lib/bcheck.c b/lib/bcheck.c
new file mode 100644
index 0000000..90f0ad2
--- /dev/null
+++ b/lib/bcheck.c
@@ -0,0 +1,979 @@
+/*
+ * Tiny C Memory and bounds checker
+ *
+ * Copyright (c) 2002 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#if !defined(__FreeBSD__) \
+ && !defined(__FreeBSD_kernel__) \
+ && !defined(__DragonFly__) \
+ && !defined(__OpenBSD__) \
+ && !defined(__NetBSD__)
+#include <malloc.h>
+#endif
+
+#if !defined(_WIN32)
+#include <unistd.h>
+#endif
+
+/* #define BOUND_DEBUG */
+
+#ifdef BOUND_DEBUG
+ #define dprintf(a...) fprintf(a)
+#else
+ #define dprintf(a...)
+#endif
+
+/* define so that bound array is static (faster, but use memory if
+ bound checking not used) */
+/* #define BOUND_STATIC */
+
+/* use malloc hooks. Currently the code cannot be reliable if no hooks */
+#define CONFIG_TCC_MALLOC_HOOKS
+#define HAVE_MEMALIGN
+
+#if defined(__FreeBSD__) \
+ || defined(__FreeBSD_kernel__) \
+ || defined(__DragonFly__) \
+ || defined(__OpenBSD__) \
+ || defined(__NetBSD__) \
+ || defined(__dietlibc__) \
+ || defined(_WIN32)
+//#warning Bound checking does not support malloc (etc.) in this environment.
+#undef CONFIG_TCC_MALLOC_HOOKS
+#undef HAVE_MEMALIGN
+#endif
+
+#define BOUND_T1_BITS 13
+#define BOUND_T2_BITS 11
+#define BOUND_T3_BITS (sizeof(size_t)*8 - BOUND_T1_BITS - BOUND_T2_BITS)
+#define BOUND_E_BITS (sizeof(size_t))
+
+#define BOUND_T1_SIZE ((size_t)1 << BOUND_T1_BITS)
+#define BOUND_T2_SIZE ((size_t)1 << BOUND_T2_BITS)
+#define BOUND_T3_SIZE ((size_t)1 << BOUND_T3_BITS)
+
+#define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS)
+#define BOUND_T23_SIZE ((size_t)1 << BOUND_T23_BITS)
+
+
+/* this pointer is generated when bound check is incorrect */
+#define INVALID_POINTER ((void *)(-2))
+/* size of an empty region */
+#define EMPTY_SIZE ((size_t)(-1))
+/* size of an invalid region */
+#define INVALID_SIZE 0
+
+typedef struct BoundEntry {
+ size_t start;
+ size_t size;
+ struct BoundEntry *next;
+ size_t is_invalid; /* true if pointers outside region are invalid */
+} BoundEntry;
+
+/* external interface */
+void __bound_init(void);
+void __bound_new_region(void *p, size_t size);
+int __bound_delete_region(void *p);
+
+#ifdef __attribute__
+ /* an __attribute__ macro is defined in the system headers */
+ #undef __attribute__
+#endif
+#define FASTCALL __attribute__((regparm(3)))
+
+void *__bound_malloc(size_t size, const void *caller);
+void *__bound_memalign(size_t size, size_t align, const void *caller);
+void __bound_free(void *ptr, const void *caller);
+void *__bound_realloc(void *ptr, size_t size, const void *caller);
+static void *libc_malloc(size_t size);
+static void libc_free(void *ptr);
+static void install_malloc_hooks(void);
+static void restore_malloc_hooks(void);
+
+#ifdef CONFIG_TCC_MALLOC_HOOKS
+static void *saved_malloc_hook;
+static void *saved_free_hook;
+static void *saved_realloc_hook;
+static void *saved_memalign_hook;
+#endif
+
+/* TCC definitions */
+extern char __bounds_start; /* start of static bounds table */
+/* error message, just for TCC */
+const char *__bound_error_msg;
+
+/* runtime error output */
+extern void rt_error(size_t pc, const char *fmt, ...);
+
+#ifdef BOUND_STATIC
+static BoundEntry *__bound_t1[BOUND_T1_SIZE]; /* page table */
+#else
+static BoundEntry **__bound_t1; /* page table */
+#endif
+static BoundEntry *__bound_empty_t2; /* empty page, for unused pages */
+static BoundEntry *__bound_invalid_t2; /* invalid page, for invalid pointers */
+
+static BoundEntry *__bound_find_region(BoundEntry *e1, void *p)
+{
+ size_t addr, tmp;
+ BoundEntry *e;
+
+ e = e1;
+ while (e != NULL) {
+ addr = (size_t)p;
+ addr -= e->start;
+ if (addr <= e->size) {
+ /* put region at the head */
+ tmp = e1->start;
+ e1->start = e->start;
+ e->start = tmp;
+ tmp = e1->size;
+ e1->size = e->size;
+ e->size = tmp;
+ return e1;
+ }
+ e = e->next;
+ }
+ /* no entry found: return empty entry or invalid entry */
+ if (e1->is_invalid)
+ return __bound_invalid_t2;
+ else
+ return __bound_empty_t2;
+}
+
+/* print a bound error message */
+static void bound_error(const char *fmt, ...)
+{
+ __bound_error_msg = fmt;
+ fprintf(stderr,"%s %s: %s\n", __FILE__, __FUNCTION__, fmt);
+ *(void **)0 = 0; /* force a runtime error */
+}
+
+static void bound_alloc_error(void)
+{
+ bound_error("not enough memory for bound checking code");
+}
+
+/* return '(p + offset)' for pointer arithmetic (a pointer can reach
+ the end of a region in this case */
+void * FASTCALL __bound_ptr_add(void *p, size_t offset)
+{
+ size_t addr = (size_t)p;
+ BoundEntry *e;
+
+ dprintf(stderr, "%s %s: %p %x\n",
+ __FILE__, __FUNCTION__, p, (unsigned)offset);
+
+ __bound_init();
+
+ e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
+ e = (BoundEntry *)((char *)e +
+ ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
+ addr -= e->start;
+ if (addr > e->size) {
+ e = __bound_find_region(e, p);
+ addr = (size_t)p - e->start;
+ }
+ addr += offset;
+ if (addr >= e->size) {
+ fprintf(stderr,"%s %s: %p is outside of the region\n",
+ __FILE__, __FUNCTION__, p + offset);
+ return INVALID_POINTER; /* return an invalid pointer */
+ }
+ return p + offset;
+}
+
+/* return '(p + offset)' for pointer indirection (the resulting must
+ be strictly inside the region */
+#define BOUND_PTR_INDIR(dsize) \
+void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \
+{ \
+ size_t addr = (size_t)p; \
+ BoundEntry *e; \
+ \
+ dprintf(stderr, "%s %s: %p %x start\n", \
+ __FILE__, __FUNCTION__, p, (unsigned)offset); \
+ \
+ __bound_init(); \
+ e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; \
+ e = (BoundEntry *)((char *)e + \
+ ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & \
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS))); \
+ addr -= e->start; \
+ if (addr > e->size) { \
+ e = __bound_find_region(e, p); \
+ addr = (size_t)p - e->start; \
+ } \
+ addr += offset + dsize; \
+ if (addr > e->size) { \
+ fprintf(stderr,"%s %s: %p is outside of the region\n", \
+ __FILE__, __FUNCTION__, p + offset); \
+ return INVALID_POINTER; /* return an invalid pointer */ \
+ } \
+ dprintf(stderr, "%s %s: return p+offset = %p\n", \
+ __FILE__, __FUNCTION__, p + offset); \
+ return p + offset; \
+}
+
+BOUND_PTR_INDIR(1)
+BOUND_PTR_INDIR(2)
+BOUND_PTR_INDIR(4)
+BOUND_PTR_INDIR(8)
+BOUND_PTR_INDIR(12)
+BOUND_PTR_INDIR(16)
+
+#if defined(__GNUC__) && (__GNUC__ >= 6)
+/*
+ * At least gcc 6.2 complains when __builtin_frame_address is used with
+ * nonzero argument.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-address"
+#endif
+
+/* return the frame pointer of the caller */
+#define GET_CALLER_FP(fp)\
+{\
+ fp = (size_t)__builtin_frame_address(1);\
+}
+
+/* called when entering a function to add all the local regions */
+void FASTCALL __bound_local_new(void *p1)
+{
+ size_t addr, size, fp, *p = p1;
+
+ dprintf(stderr, "%s, %s start p1=%p\n", __FILE__, __FUNCTION__, p);
+ GET_CALLER_FP(fp);
+ for(;;) {
+ addr = p[0];
+ if (addr == 0)
+ break;
+ addr += fp;
+ size = p[1];
+ p += 2;
+ __bound_new_region((void *)addr, size);
+ }
+ dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
+}
+
+/* called when leaving a function to delete all the local regions */
+void FASTCALL __bound_local_delete(void *p1)
+{
+ size_t addr, fp, *p = p1;
+ GET_CALLER_FP(fp);
+ for(;;) {
+ addr = p[0];
+ if (addr == 0)
+ break;
+ addr += fp;
+ p += 2;
+ __bound_delete_region((void *)addr);
+ }
+}
+
+#if defined(__GNUC__) && (__GNUC__ >= 6)
+#pragma GCC diagnostic pop
+#endif
+
+static BoundEntry *__bound_new_page(void)
+{
+ BoundEntry *page;
+ size_t i;
+
+ page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE);
+ if (!page)
+ bound_alloc_error();
+ for(i=0;i<BOUND_T2_SIZE;i++) {
+ /* put empty entries */
+ page[i].start = 0;
+ page[i].size = EMPTY_SIZE;
+ page[i].next = NULL;
+ page[i].is_invalid = 0;
+ }
+ return page;
+}
+
+/* currently we use malloc(). Should use bound_new_page() */
+static BoundEntry *bound_new_entry(void)
+{
+ BoundEntry *e;
+ e = libc_malloc(sizeof(BoundEntry));
+ return e;
+}
+
+static void bound_free_entry(BoundEntry *e)
+{
+ libc_free(e);
+}
+
+static BoundEntry *get_page(size_t index)
+{
+ BoundEntry *page;
+ page = __bound_t1[index];
+ if (!page || page == __bound_empty_t2 || page == __bound_invalid_t2) {
+ /* create a new page if necessary */
+ page = __bound_new_page();
+ __bound_t1[index] = page;
+ }
+ return page;
+}
+
+/* mark a region as being invalid (can only be used during init) */
+static void mark_invalid(size_t addr, size_t size)
+{
+ size_t start, end;
+ BoundEntry *page;
+ size_t t1_start, t1_end, i, j, t2_start, t2_end;
+
+ start = addr;
+ end = addr + size;
+
+ t2_start = (start + BOUND_T3_SIZE - 1) >> BOUND_T3_BITS;
+ if (end != 0)
+ t2_end = end >> BOUND_T3_BITS;
+ else
+ t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS);
+
+#if 0
+ dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end);
+#endif
+
+ /* first we handle full pages */
+ t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS;
+ t1_end = t2_end >> BOUND_T2_BITS;
+
+ i = t2_start & (BOUND_T2_SIZE - 1);
+ j = t2_end & (BOUND_T2_SIZE - 1);
+
+ if (t1_start == t1_end) {
+ page = get_page(t2_start >> BOUND_T2_BITS);
+ for(; i < j; i++) {
+ page[i].size = INVALID_SIZE;
+ page[i].is_invalid = 1;
+ }
+ } else {
+ if (i > 0) {
+ page = get_page(t2_start >> BOUND_T2_BITS);
+ for(; i < BOUND_T2_SIZE; i++) {
+ page[i].size = INVALID_SIZE;
+ page[i].is_invalid = 1;
+ }
+ }
+ for(i = t1_start; i < t1_end; i++) {
+ __bound_t1[i] = __bound_invalid_t2;
+ }
+ if (j != 0) {
+ page = get_page(t1_end);
+ for(i = 0; i < j; i++) {
+ page[i].size = INVALID_SIZE;
+ page[i].is_invalid = 1;
+ }
+ }
+ }
+}
+
+void __bound_init(void)
+{
+ size_t i;
+ BoundEntry *page;
+ size_t start, size;
+ size_t *p;
+
+ static int inited;
+ if (inited)
+ return;
+
+ inited = 1;
+
+ dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__);
+
+ /* save malloc hooks and install bound check hooks */
+ install_malloc_hooks();
+
+#ifndef BOUND_STATIC
+ __bound_t1 = libc_malloc(BOUND_T1_SIZE * sizeof(BoundEntry *));
+ if (!__bound_t1)
+ bound_alloc_error();
+#endif
+ __bound_empty_t2 = __bound_new_page();
+ for(i=0;i<BOUND_T1_SIZE;i++) {
+ __bound_t1[i] = __bound_empty_t2;
+ }
+
+ page = __bound_new_page();
+ for(i=0;i<BOUND_T2_SIZE;i++) {
+ /* put invalid entries */
+ page[i].start = 0;
+ page[i].size = INVALID_SIZE;
+ page[i].next = NULL;
+ page[i].is_invalid = 1;
+ }
+ __bound_invalid_t2 = page;
+
+ /* invalid pointer zone */
+ start = (size_t)INVALID_POINTER & ~(BOUND_T23_SIZE - 1);
+ size = BOUND_T23_SIZE;
+ mark_invalid(start, size);
+
+#if defined(CONFIG_TCC_MALLOC_HOOKS)
+ /* malloc zone is also marked invalid. can only use that with
+ * hooks because all libs should use the same malloc. The solution
+ * would be to build a new malloc for tcc.
+ *
+ * usually heap (= malloc zone) comes right after bss, i.e. after _end, but
+ * not always - either if we are running from under `tcc -b -run`, or if
+ * address space randomization is turned on(a), heap start will be separated
+ * from bss end.
+ *
+ * So sbrk(0) will be a good approximation for start_brk:
+ *
+ * - if we are a separately compiled program, __bound_init() runs early,
+ * and sbrk(0) should be equal or very near to start_brk(b) (in case other
+ * constructors malloc something), or
+ *
+ * - if we are running from under `tcc -b -run`, sbrk(0) will return
+ * start of heap portion which is under this program control, and not
+ * mark as invalid earlier allocated memory.
+ *
+ *
+ * (a) /proc/sys/kernel/randomize_va_space = 2, on Linux;
+ * usually turned on by default.
+ *
+ * (b) on Linux >= v3.3, the alternative is to read
+ * start_brk from /proc/self/stat
+ */
+ start = (size_t)sbrk(0);
+ size = 128 * 0x100000;
+ mark_invalid(start, size);
+#endif
+
+ /* add all static bound check values */
+ p = (size_t *)&__bounds_start;
+ while (p[0] != 0) {
+ __bound_new_region((void *)p[0], p[1]);
+ p += 2;
+ }
+
+ dprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__);
+}
+
+void __bound_main_arg(void **p)
+{
+ void *start = p;
+ while (*p++);
+
+ dprintf(stderr, "%s, %s calling __bound_new_region(%p %x)\n",
+ __FILE__, __FUNCTION__, start, (unsigned)((void *)p - start));
+
+ __bound_new_region(start, (void *) p - start);
+}
+
+void __bound_exit(void)
+{
+ dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__);
+ restore_malloc_hooks();
+}
+
+static inline void add_region(BoundEntry *e,
+ size_t start, size_t size)
+{
+ BoundEntry *e1;
+ if (e->start == 0) {
+ /* no region : add it */
+ e->start = start;
+ e->size = size;
+ } else {
+ /* already regions in the list: add it at the head */
+ e1 = bound_new_entry();
+ e1->start = e->start;
+ e1->size = e->size;
+ e1->next = e->next;
+ e->start = start;
+ e->size = size;
+ e->next = e1;
+ }
+}
+
+/* create a new region. It should not already exist in the region list */
+void __bound_new_region(void *p, size_t size)
+{
+ size_t start, end;
+ BoundEntry *page, *e, *e2;
+ size_t t1_start, t1_end, i, t2_start, t2_end;
+
+ dprintf(stderr, "%s, %s(%p, %x) start\n",
+ __FILE__, __FUNCTION__, p, (unsigned)size);
+
+ __bound_init();
+
+ start = (size_t)p;
+ end = start + size;
+ t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
+ t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
+
+ /* start */
+ page = get_page(t1_start);
+ t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+ t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+
+
+ e = (BoundEntry *)((char *)page + t2_start);
+ add_region(e, start, size);
+
+ if (t1_end == t1_start) {
+ /* same ending page */
+ e2 = (BoundEntry *)((char *)page + t2_end);
+ if (e2 > e) {
+ e++;
+ for(;e<e2;e++) {
+ e->start = start;
+ e->size = size;
+ }
+ add_region(e, start, size);
+ }
+ } else {
+ /* mark until end of page */
+ e2 = page + BOUND_T2_SIZE;
+ e++;
+ for(;e<e2;e++) {
+ e->start = start;
+ e->size = size;
+ }
+ /* mark intermediate pages, if any */
+ for(i=t1_start+1;i<t1_end;i++) {
+ page = get_page(i);
+ e2 = page + BOUND_T2_SIZE;
+ for(e=page;e<e2;e++) {
+ e->start = start;
+ e->size = size;
+ }
+ }
+ /* last page */
+ page = get_page(t1_end);
+ e2 = (BoundEntry *)((char *)page + t2_end);
+ for(e=page;e<e2;e++) {
+ e->start = start;
+ e->size = size;
+ }
+ add_region(e, start, size);
+ }
+
+ dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
+}
+
+/* delete a region */
+static inline void delete_region(BoundEntry *e, void *p, size_t empty_size)
+{
+ size_t addr;
+ BoundEntry *e1;
+
+ addr = (size_t)p;
+ addr -= e->start;
+ if (addr <= e->size) {
+ /* region found is first one */
+ e1 = e->next;
+ if (e1 == NULL) {
+ /* no more region: mark it empty */
+ e->start = 0;
+ e->size = empty_size;
+ } else {
+ /* copy next region in head */
+ e->start = e1->start;
+ e->size = e1->size;
+ e->next = e1->next;
+ bound_free_entry(e1);
+ }
+ } else {
+ /* find the matching region */
+ for(;;) {
+ e1 = e;
+ e = e->next;
+ /* region not found: do nothing */
+ if (e == NULL)
+ break;
+ addr = (size_t)p - e->start;
+ if (addr <= e->size) {
+ /* found: remove entry */
+ e1->next = e->next;
+ bound_free_entry(e);
+ break;
+ }
+ }
+ }
+}
+
+/* WARNING: 'p' must be the starting point of the region. */
+/* return non zero if error */
+int __bound_delete_region(void *p)
+{
+ size_t start, end, addr, size, empty_size;
+ BoundEntry *page, *e, *e2;
+ size_t t1_start, t1_end, t2_start, t2_end, i;
+
+ dprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__);
+
+ __bound_init();
+
+ start = (size_t)p;
+ t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
+ t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+
+ /* find region size */
+ page = __bound_t1[t1_start];
+ e = (BoundEntry *)((char *)page + t2_start);
+ addr = start - e->start;
+ if (addr > e->size)
+ e = __bound_find_region(e, p);
+ /* test if invalid region */
+ if (e->size == EMPTY_SIZE || (size_t)p != e->start)
+ return -1;
+ /* compute the size we put in invalid regions */
+ if (e->is_invalid)
+ empty_size = INVALID_SIZE;
+ else
+ empty_size = EMPTY_SIZE;
+ size = e->size;
+ end = start + size;
+
+ /* now we can free each entry */
+ t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
+ t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+
+ delete_region(e, p, empty_size);
+ if (t1_end == t1_start) {
+ /* same ending page */
+ e2 = (BoundEntry *)((char *)page + t2_end);
+ if (e2 > e) {
+ e++;
+ for(;e<e2;e++) {
+ e->start = 0;
+ e->size = empty_size;
+ }
+ delete_region(e, p, empty_size);
+ }
+ } else {
+ /* mark until end of page */
+ e2 = page + BOUND_T2_SIZE;
+ e++;
+ for(;e<e2;e++) {
+ e->start = 0;
+ e->size = empty_size;
+ }
+ /* mark intermediate pages, if any */
+ /* XXX: should free them */
+ for(i=t1_start+1;i<t1_end;i++) {
+ page = get_page(i);
+ e2 = page + BOUND_T2_SIZE;
+ for(e=page;e<e2;e++) {
+ e->start = 0;
+ e->size = empty_size;
+ }
+ }
+ /* last page */
+ page = get_page(t1_end);
+ e2 = (BoundEntry *)((char *)page + t2_end);
+ for(e=page;e<e2;e++) {
+ e->start = 0;
+ e->size = empty_size;
+ }
+ delete_region(e, p, empty_size);
+ }
+
+ dprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__);
+
+ return 0;
+}
+
+/* return the size of the region starting at p, or EMPTY_SIZE if non
+ existent region. */
+static size_t get_region_size(void *p)
+{
+ size_t addr = (size_t)p;
+ BoundEntry *e;
+
+ e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
+ e = (BoundEntry *)((char *)e +
+ ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
+ ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
+ addr -= e->start;
+ if (addr > e->size)
+ e = __bound_find_region(e, p);
+ if (e->start != (size_t)p)
+ return EMPTY_SIZE;
+ return e->size;
+}
+
+/* patched memory functions */
+
+/* force compiler to perform stores coded up to this point */
+#define barrier() __asm__ __volatile__ ("": : : "memory")
+
+static void install_malloc_hooks(void)
+{
+#ifdef CONFIG_TCC_MALLOC_HOOKS
+ saved_malloc_hook = __malloc_hook;
+ saved_free_hook = __free_hook;
+ saved_realloc_hook = __realloc_hook;
+ saved_memalign_hook = __memalign_hook;
+ __malloc_hook = __bound_malloc;
+ __free_hook = __bound_free;
+ __realloc_hook = __bound_realloc;
+ __memalign_hook = __bound_memalign;
+
+ barrier();
+#endif
+}
+
+static void restore_malloc_hooks(void)
+{
+#ifdef CONFIG_TCC_MALLOC_HOOKS
+ __malloc_hook = saved_malloc_hook;
+ __free_hook = saved_free_hook;
+ __realloc_hook = saved_realloc_hook;
+ __memalign_hook = saved_memalign_hook;
+
+ barrier();
+#endif
+}
+
+static void *libc_malloc(size_t size)
+{
+ void *ptr;
+ restore_malloc_hooks();
+ ptr = malloc(size);
+ install_malloc_hooks();
+ return ptr;
+}
+
+static void libc_free(void *ptr)
+{
+ restore_malloc_hooks();
+ free(ptr);
+ install_malloc_hooks();
+}
+
+/* XXX: we should use a malloc which ensure that it is unlikely that
+ two malloc'ed data have the same address if 'free' are made in
+ between. */
+void *__bound_malloc(size_t size, const void *caller)
+{
+ void *ptr;
+
+ /* we allocate one more byte to ensure the regions will be
+ separated by at least one byte. With the glibc malloc, it may
+ be in fact not necessary */
+ ptr = libc_malloc(size + 1);
+
+ if (!ptr)
+ return NULL;
+
+ dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n",
+ __FILE__, __FUNCTION__, ptr, (unsigned)size);
+
+ __bound_new_region(ptr, size);
+ return ptr;
+}
+
+void *__bound_memalign(size_t size, size_t align, const void *caller)
+{
+ void *ptr;
+
+ restore_malloc_hooks();
+
+#ifndef HAVE_MEMALIGN
+ if (align > 4) {
+ /* XXX: handle it ? */
+ ptr = NULL;
+ } else {
+ /* we suppose that malloc aligns to at least four bytes */
+ ptr = malloc(size + 1);
+ }
+#else
+ /* we allocate one more byte to ensure the regions will be
+ separated by at least one byte. With the glibc malloc, it may
+ be in fact not necessary */
+ ptr = memalign(size + 1, align);
+#endif
+
+ install_malloc_hooks();
+
+ if (!ptr)
+ return NULL;
+
+ dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n",
+ __FILE__, __FUNCTION__, ptr, (unsigned)size);
+
+ __bound_new_region(ptr, size);
+ return ptr;
+}
+
+void __bound_free(void *ptr, const void *caller)
+{
+ if (ptr == NULL)
+ return;
+ if (__bound_delete_region(ptr) != 0)
+ bound_error("freeing invalid region");
+
+ libc_free(ptr);
+}
+
+void *__bound_realloc(void *ptr, size_t size, const void *caller)
+{
+ void *ptr1;
+ size_t old_size;
+
+ if (size == 0) {
+ __bound_free(ptr, caller);
+ return NULL;
+ } else {
+ ptr1 = __bound_malloc(size, caller);
+ if (ptr == NULL || ptr1 == NULL)
+ return ptr1;
+ old_size = get_region_size(ptr);
+ if (old_size == EMPTY_SIZE)
+ bound_error("realloc'ing invalid pointer");
+ memcpy(ptr1, ptr, old_size);
+ __bound_free(ptr, caller);
+ return ptr1;
+ }
+}
+
+#ifndef CONFIG_TCC_MALLOC_HOOKS
+void *__bound_calloc(size_t nmemb, size_t size)
+{
+ void *ptr;
+ size = size * nmemb;
+ ptr = __bound_malloc(size, NULL);
+ if (!ptr)
+ return NULL;
+ memset(ptr, 0, size);
+ return ptr;
+}
+#endif
+
+#if 0
+static void bound_dump(void)
+{
+ BoundEntry *page, *e;
+ size_t i, j;
+
+ fprintf(stderr, "region dump:\n");
+ for(i=0;i<BOUND_T1_SIZE;i++) {
+ page = __bound_t1[i];
+ for(j=0;j<BOUND_T2_SIZE;j++) {
+ e = page + j;
+ /* do not print invalid or empty entries */
+ if (e->size != EMPTY_SIZE && e->start != 0) {
+ fprintf(stderr, "%08x:",
+ (i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
+ (j << BOUND_T3_BITS));
+ do {
+ fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size);
+ e = e->next;
+ } while (e != NULL);
+ fprintf(stderr, "\n");
+ }
+ }
+ }
+}
+#endif
+
+/* some useful checked functions */
+
+/* check that (p ... p + size - 1) lies inside 'p' region, if any */
+static void __bound_check(const void *p, size_t size)
+{
+ if (size == 0)
+ return;
+ p = __bound_ptr_add((void *)p, size - 1);
+ if (p == INVALID_POINTER)
+ bound_error("invalid pointer");
+}
+
+void *__bound_memcpy(void *dst, const void *src, size_t size)
+{
+ void* p;
+
+ dprintf(stderr, "%s %s: start, dst=%p src=%p size=%x\n",
+ __FILE__, __FUNCTION__, dst, src, (unsigned)size);
+
+ __bound_check(dst, size);
+ __bound_check(src, size);
+ /* check also region overlap */
+ if (src >= dst && src < dst + size)
+ bound_error("overlapping regions in memcpy()");
+
+ p = memcpy(dst, src, size);
+
+ dprintf(stderr, "%s %s: end, p=%p\n", __FILE__, __FUNCTION__, p);
+ return p;
+}
+
+void *__bound_memmove(void *dst, const void *src, size_t size)
+{
+ __bound_check(dst, size);
+ __bound_check(src, size);
+ return memmove(dst, src, size);
+}
+
+void *__bound_memset(void *dst, int c, size_t size)
+{
+ __bound_check(dst, size);
+ return memset(dst, c, size);
+}
+
+/* XXX: could be optimized */
+int __bound_strlen(const char *s)
+{
+ const char *p;
+ size_t len;
+
+ len = 0;
+ for(;;) {
+ p = __bound_ptr_indir1((char *)s, len);
+ if (p == INVALID_POINTER)
+ bound_error("bad pointer in strlen()");
+ if (*p == '\0')
+ break;
+ len++;
+ }
+ return len;
+}
+
+char *__bound_strcpy(char *dst, const char *src)
+{
+ size_t len;
+ void *p;
+
+ dprintf(stderr, "%s %s: strcpy start, dst=%p src=%p\n",
+ __FILE__, __FUNCTION__, dst, src);
+ len = __bound_strlen(src);
+ p = __bound_memcpy(dst, src, len + 1);
+ dprintf(stderr, "%s %s: strcpy end, p = %p\n",
+ __FILE__, __FUNCTION__, p);
+ return p;
+}
diff --git a/lib/lib-arm64.c b/lib/lib-arm64.c
new file mode 100644
index 0000000..b8fd9e8
--- /dev/null
+++ b/lib/lib-arm64.c
@@ -0,0 +1,664 @@
+/*
+ * TCC runtime library for arm64.
+ *
+ * Copyright (c) 2015 Edmund Grimley Evans
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved. This file is offered as-is,
+ * without any warranty.
+ */
+
+#ifdef __TINYC__
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned uint32_t;
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+void *memcpy(void*,void*,__SIZE_TYPE__);
+#else
+#include <stdint.h>
+#include <string.h>
+#endif
+
+void __clear_cache(void *beg, void *end)
+{
+ __arm64_clear_cache(beg, end);
+}
+
+typedef struct {
+ uint64_t x0, x1;
+} u128_t;
+
+static long double f3_zero(int sgn)
+{
+ long double f;
+ u128_t x = { 0, (uint64_t)sgn << 63 };
+ memcpy(&f, &x, 16);
+ return f;
+}
+
+static long double f3_infinity(int sgn)
+{
+ long double f;
+ u128_t x = { 0, (uint64_t)sgn << 63 | 0x7fff000000000000 };
+ memcpy(&f, &x, 16);
+ return f;
+}
+
+static long double f3_NaN(void)
+{
+ long double f;
+#if 0
+ // ARM's default NaN usually has just the top fraction bit set:
+ u128_t x = { 0, 0x7fff800000000000 };
+#else
+ // GCC's library sets all fraction bits:
+ u128_t x = { -1, 0x7fffffffffffffff };
+#endif
+ memcpy(&f, &x, 16);
+ return f;
+}
+
+static int fp3_convert_NaN(long double *f, int sgn, u128_t mnt)
+{
+ u128_t x = { mnt.x0,
+ mnt.x1 | 0x7fff800000000000 | (uint64_t)sgn << 63 };
+ memcpy(f, &x, 16);
+ return 1;
+}
+
+static int fp3_detect_NaNs(long double *f,
+ int a_sgn, int a_exp, u128_t a,
+ int b_sgn, int b_exp, u128_t b)
+{
+ // Detect signalling NaNs:
+ if (a_exp == 32767 && (a.x0 | a.x1 << 16) && !(a.x1 >> 47 & 1))
+ return fp3_convert_NaN(f, a_sgn, a);
+ if (b_exp == 32767 && (b.x0 | b.x1 << 16) && !(b.x1 >> 47 & 1))
+ return fp3_convert_NaN(f, b_sgn, b);
+
+ // Detect quiet NaNs:
+ if (a_exp == 32767 && (a.x0 | a.x1 << 16))
+ return fp3_convert_NaN(f, a_sgn, a);
+ if (b_exp == 32767 && (b.x0 | b.x1 << 16))
+ return fp3_convert_NaN(f, b_sgn, b);
+
+ return 0;
+}
+
+static void f3_unpack(int *sgn, int32_t *exp, u128_t *mnt, long double f)
+{
+ u128_t x;
+ memcpy(&x, &f, 16);
+ *sgn = x.x1 >> 63;
+ *exp = x.x1 >> 48 & 32767;
+ x.x1 = x.x1 << 16 >> 16;
+ if (*exp)
+ x.x1 |= (uint64_t)1 << 48;
+ else
+ *exp = 1;
+ *mnt = x;
+}
+
+static u128_t f3_normalise(int32_t *exp, u128_t mnt)
+{
+ int sh;
+ if (!(mnt.x0 | mnt.x1))
+ return mnt;
+ if (!mnt.x1) {
+ mnt.x1 = mnt.x0;
+ mnt.x0 = 0;
+ *exp -= 64;
+ }
+ for (sh = 32; sh; sh >>= 1) {
+ if (!(mnt.x1 >> (64 - sh))) {
+ mnt.x1 = mnt.x1 << sh | mnt.x0 >> (64 - sh);
+ mnt.x0 = mnt.x0 << sh;
+ *exp -= sh;
+ }
+ }
+ return mnt;
+}
+
+static u128_t f3_sticky_shift(int32_t sh, u128_t x)
+{
+ if (sh >= 128) {
+ x.x0 = !!(x.x0 | x.x1);
+ x.x1 = 0;
+ return x;
+ }
+ if (sh >= 64) {
+ x.x0 = x.x1 | !!x.x0;
+ x.x1 = 0;
+ sh -= 64;
+ }
+ if (sh > 0) {
+ x.x0 = x.x0 >> sh | x.x1 << (64 - sh) | !!(x.x0 << (64 - sh));
+ x.x1 = x.x1 >> sh;
+ }
+ return x;
+}
+
+static long double f3_round(int sgn, int32_t exp, u128_t x)
+{
+ long double f;
+ int error;
+
+ if (exp > 0) {
+ x = f3_sticky_shift(13, x);
+ }
+ else {
+ x = f3_sticky_shift(14 - exp, x);
+ exp = 0;
+ }
+
+ error = x.x0 & 3;
+ x.x0 = x.x0 >> 2 | x.x1 << 62;
+ x.x1 = x.x1 >> 2;
+
+ if (error == 3 || ((error == 2) & (x.x0 & 1))) {
+ if (!++x.x0) {
+ ++x.x1;
+ if (x.x1 == (uint64_t)1 << 48)
+ exp = 1;
+ else if (x.x1 == (uint64_t)1 << 49) {
+ ++exp;
+ x.x0 = x.x0 >> 1 | x.x1 << 63;
+ x.x1 = x.x1 >> 1;
+ }
+ }
+ }
+
+ if (exp >= 32767)
+ return f3_infinity(sgn);
+
+ x.x1 = x.x1 << 16 >> 16 | (uint64_t)exp << 48 | (uint64_t)sgn << 63;
+ memcpy(&f, &x, 16);
+ return f;
+}
+
+static long double f3_add(long double fa, long double fb, int neg)
+{
+ u128_t a, b, x;
+ int32_t a_exp, b_exp, x_exp;
+ int a_sgn, b_sgn, x_sgn;
+ long double fx;
+
+ f3_unpack(&a_sgn, &a_exp, &a, fa);
+ f3_unpack(&b_sgn, &b_exp, &b, fb);
+
+ if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
+ return fx;
+
+ b_sgn ^= neg;
+
+ // Handle infinities and zeroes:
+ if (a_exp == 32767 && b_exp == 32767 && a_sgn != b_sgn)
+ return f3_NaN();
+ if (a_exp == 32767)
+ return f3_infinity(a_sgn);
+ if (b_exp == 32767)
+ return f3_infinity(b_sgn);
+ if (!(a.x0 | a.x1 | b.x0 | b.x1))
+ return f3_zero(a_sgn & b_sgn);
+
+ a.x1 = a.x1 << 3 | a.x0 >> 61;
+ a.x0 = a.x0 << 3;
+ b.x1 = b.x1 << 3 | b.x0 >> 61;
+ b.x0 = b.x0 << 3;
+
+ if (a_exp <= b_exp) {
+ a = f3_sticky_shift(b_exp - a_exp, a);
+ a_exp = b_exp;
+ }
+ else {
+ b = f3_sticky_shift(a_exp - b_exp, b);
+ b_exp = a_exp;
+ }
+
+ x_sgn = a_sgn;
+ x_exp = a_exp;
+ if (a_sgn == b_sgn) {
+ x.x0 = a.x0 + b.x0;
+ x.x1 = a.x1 + b.x1 + (x.x0 < a.x0);
+ }
+ else {
+ x.x0 = a.x0 - b.x0;
+ x.x1 = a.x1 - b.x1 - (x.x0 > a.x0);
+ if (x.x1 >> 63) {
+ x_sgn ^= 1;
+ x.x0 = -x.x0;
+ x.x1 = -x.x1 - !!x.x0;
+ }
+ }
+
+ if (!(x.x0 | x.x1))
+ return f3_zero(0);
+
+ x = f3_normalise(&x_exp, x);
+
+ return f3_round(x_sgn, x_exp + 12, x);
+}
+
+long double __addtf3(long double a, long double b)
+{
+ return f3_add(a, b, 0);
+}
+
+long double __subtf3(long double a, long double b)
+{
+ return f3_add(a, b, 1);
+}
+
+long double __multf3(long double fa, long double fb)
+{
+ u128_t a, b, x;
+ int32_t a_exp, b_exp, x_exp;
+ int a_sgn, b_sgn, x_sgn;
+ long double fx;
+
+ f3_unpack(&a_sgn, &a_exp, &a, fa);
+ f3_unpack(&b_sgn, &b_exp, &b, fb);
+
+ if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
+ return fx;
+
+ // Handle infinities and zeroes:
+ if ((a_exp == 32767 && !(b.x0 | b.x1)) ||
+ (b_exp == 32767 && !(a.x0 | a.x1)))
+ return f3_NaN();
+ if (a_exp == 32767 || b_exp == 32767)
+ return f3_infinity(a_sgn ^ b_sgn);
+ if (!(a.x0 | a.x1) || !(b.x0 | b.x1))
+ return f3_zero(a_sgn ^ b_sgn);
+
+ a = f3_normalise(&a_exp, a);
+ b = f3_normalise(&b_exp, b);
+
+ x_sgn = a_sgn ^ b_sgn;
+ x_exp = a_exp + b_exp - 16352;
+
+ {
+ // Convert to base (1 << 30), discarding bottom 6 bits, which are zero,
+ // so there are (32, 30, 30, 30) bits in (a3, a2, a1, a0):
+ uint64_t a0 = a.x0 << 28 >> 34;
+ uint64_t b0 = b.x0 << 28 >> 34;
+ uint64_t a1 = a.x0 >> 36 | a.x1 << 62 >> 34;
+ uint64_t b1 = b.x0 >> 36 | b.x1 << 62 >> 34;
+ uint64_t a2 = a.x1 << 32 >> 34;
+ uint64_t b2 = b.x1 << 32 >> 34;
+ uint64_t a3 = a.x1 >> 32;
+ uint64_t b3 = b.x1 >> 32;
+ // Use 16 small multiplications and additions that do not overflow:
+ uint64_t x0 = a0 * b0;
+ uint64_t x1 = (x0 >> 30) + a0 * b1 + a1 * b0;
+ uint64_t x2 = (x1 >> 30) + a0 * b2 + a1 * b1 + a2 * b0;
+ uint64_t x3 = (x2 >> 30) + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
+ uint64_t x4 = (x3 >> 30) + a1 * b3 + a2 * b2 + a3 * b1;
+ uint64_t x5 = (x4 >> 30) + a2 * b3 + a3 * b2;
+ uint64_t x6 = (x5 >> 30) + a3 * b3;
+ // We now have (64, 30, 30, ...) bits in (x6, x5, x4, ...).
+ // Take the top 128 bits, setting bottom bit if any lower bits were set:
+ uint64_t y0 = (x5 << 34 | x4 << 34 >> 30 | x3 << 34 >> 60 |
+ !!(x3 << 38 | (x2 | x1 | x0) << 34));
+ uint64_t y1 = x6;
+ // Top bit may be zero. Renormalise:
+ if (!(y1 >> 63)) {
+ y1 = y1 << 1 | y0 >> 63;
+ y0 = y0 << 1;
+ --x_exp;
+ }
+ x.x0 = y0;
+ x.x1 = y1;
+ }
+
+ return f3_round(x_sgn, x_exp, x);
+}
+
+long double __divtf3(long double fa, long double fb)
+{
+ u128_t a, b, x;
+ int32_t a_exp, b_exp, x_exp;
+ int a_sgn, b_sgn, x_sgn, i;
+ long double fx;
+
+ f3_unpack(&a_sgn, &a_exp, &a, fa);
+ f3_unpack(&b_sgn, &b_exp, &b, fb);
+
+ if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
+ return fx;
+
+ // Handle infinities and zeroes:
+ if ((a_exp == 32767 && b_exp == 32767) ||
+ (!(a.x0 | a.x1) && !(b.x0 | b.x1)))
+ return f3_NaN();
+ if (a_exp == 32767 || !(b.x0 | b.x1))
+ return f3_infinity(a_sgn ^ b_sgn);
+ if (!(a.x0 | a.x1) || b_exp == 32767)
+ return f3_zero(a_sgn ^ b_sgn);
+
+ a = f3_normalise(&a_exp, a);
+ b = f3_normalise(&b_exp, b);
+
+ x_sgn = a_sgn ^ b_sgn;
+ x_exp = a_exp - b_exp + 16395;
+
+ a.x0 = a.x0 >> 1 | a.x1 << 63;
+ a.x1 = a.x1 >> 1;
+ b.x0 = b.x0 >> 1 | b.x1 << 63;
+ b.x1 = b.x1 >> 1;
+ x.x0 = 0;
+ x.x1 = 0;
+ for (i = 0; i < 116; i++) {
+ x.x1 = x.x1 << 1 | x.x0 >> 63;
+ x.x0 = x.x0 << 1;
+ if (a.x1 > b.x1 || (a.x1 == b.x1 && a.x0 >= b.x0)) {
+ a.x1 = a.x1 - b.x1 - (a.x0 < b.x0);
+ a.x0 = a.x0 - b.x0;
+ x.x0 |= 1;
+ }
+ a.x1 = a.x1 << 1 | a.x0 >> 63;
+ a.x0 = a.x0 << 1;
+ }
+ x.x0 |= !!(a.x0 | a.x1);
+
+ x = f3_normalise(&x_exp, x);
+
+ return f3_round(x_sgn, x_exp, x);
+}
+
+long double __extendsftf2(float f)
+{
+ long double fx;
+ u128_t x;
+ uint32_t a;
+ uint64_t aa;
+ memcpy(&a, &f, 4);
+ aa = a;
+ x.x0 = 0;
+ if (!(a << 1))
+ x.x1 = aa << 32;
+ else if (a << 1 >> 24 == 255)
+ x.x1 = (0x7fff000000000000 | aa >> 31 << 63 | aa << 41 >> 16 |
+ (uint64_t)!!(a << 9) << 47);
+ else
+ x.x1 = (aa >> 31 << 63 | ((aa >> 23 & 255) + 16256) << 48 |
+ aa << 41 >> 16);
+ memcpy(&fx, &x, 16);
+ return fx;
+}
+
+long double __extenddftf2(double f)
+{
+ long double fx;
+ u128_t x;
+ uint64_t a;
+ memcpy(&a, &f, 8);
+ x.x0 = a << 60;
+ if (!(a << 1))
+ x.x1 = a;
+ else if (a << 1 >> 53 == 2047)
+ x.x1 = (0x7fff000000000000 | a >> 63 << 63 | a << 12 >> 16 |
+ (uint64_t)!!(a << 12) << 47);
+ else
+ x.x1 = a >> 63 << 63 | ((a >> 52 & 2047) + 15360) << 48 | a << 12 >> 16;
+ memcpy(&fx, &x, 16);
+ return fx;
+}
+
+float __trunctfsf2(long double f)
+{
+ u128_t mnt;
+ int32_t exp;
+ int sgn;
+ uint32_t x;
+ float fx;
+
+ f3_unpack(&sgn, &exp, &mnt, f);
+
+ if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
+ x = 0x7fc00000 | (uint32_t)sgn << 31 | (mnt.x1 >> 25 & 0x007fffff);
+ else if (exp > 16510)
+ x = 0x7f800000 | (uint32_t)sgn << 31;
+ else if (exp < 16233)
+ x = (uint32_t)sgn << 31;
+ else {
+ exp -= 16257;
+ x = mnt.x1 >> 23 | !!(mnt.x0 | mnt.x1 << 41);
+ if (exp < 0) {
+ x = x >> -exp | !!(x << (32 + exp));
+ exp = 0;
+ }
+ if ((x & 3) == 3 || (x & 7) == 6)
+ x += 4;
+ x = ((x >> 2) + (exp << 23)) | (uint32_t)sgn << 31;
+ }
+ memcpy(&fx, &x, 4);
+ return fx;
+}
+
+double __trunctfdf2(long double f)
+{
+ u128_t mnt;
+ int32_t exp;
+ int sgn;
+ uint64_t x;
+ double fx;
+
+ f3_unpack(&sgn, &exp, &mnt, f);
+
+ if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
+ x = (0x7ff8000000000000 | (uint64_t)sgn << 63 |
+ mnt.x1 << 16 >> 12 | mnt.x0 >> 60);
+ else if (exp > 17406)
+ x = 0x7ff0000000000000 | (uint64_t)sgn << 63;
+ else if (exp < 15308)
+ x = (uint64_t)sgn << 63;
+ else {
+ exp -= 15361;
+ x = mnt.x1 << 6 | mnt.x0 >> 58 | !!(mnt.x0 << 6);
+ if (exp < 0) {
+ x = x >> -exp | !!(x << (64 + exp));
+ exp = 0;
+ }
+ if ((x & 3) == 3 || (x & 7) == 6)
+ x += 4;
+ x = ((x >> 2) + ((uint64_t)exp << 52)) | (uint64_t)sgn << 63;
+ }
+ memcpy(&fx, &x, 8);
+ return fx;
+}
+
+int32_t __fixtfsi(long double fa)
+{
+ u128_t a;
+ int32_t a_exp;
+ int a_sgn;
+ int32_t x;
+ f3_unpack(&a_sgn, &a_exp, &a, fa);
+ if (a_exp < 16369)
+ return 0;
+ if (a_exp > 16413)
+ return a_sgn ? -0x80000000 : 0x7fffffff;
+ x = a.x1 >> (16431 - a_exp);
+ return a_sgn ? -x : x;
+}
+
+int64_t __fixtfdi(long double fa)
+{
+ u128_t a;
+ int32_t a_exp;
+ int a_sgn;
+ int64_t x;
+ f3_unpack(&a_sgn, &a_exp, &a, fa);
+ if (a_exp < 16383)
+ return 0;
+ if (a_exp > 16445)
+ return a_sgn ? -0x8000000000000000 : 0x7fffffffffffffff;
+ x = (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
+ return a_sgn ? -x : x;
+}
+
+uint32_t __fixunstfsi(long double fa)
+{
+ u128_t a;
+ int32_t a_exp;
+ int a_sgn;
+ f3_unpack(&a_sgn, &a_exp, &a, fa);
+ if (a_sgn || a_exp < 16369)
+ return 0;
+ if (a_exp > 16414)
+ return -1;
+ return a.x1 >> (16431 - a_exp);
+}
+
+uint64_t __fixunstfdi(long double fa)
+{
+ u128_t a;
+ int32_t a_exp;
+ int a_sgn;
+ f3_unpack(&a_sgn, &a_exp, &a, fa);
+ if (a_sgn || a_exp < 16383)
+ return 0;
+ if (a_exp > 16446)
+ return -1;
+ return (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
+}
+
+long double __floatsitf(int32_t a)
+{
+ int sgn = 0;
+ int exp = 16414;
+ uint32_t mnt = a;
+ u128_t x = { 0, 0 };
+ long double f;
+ int i;
+ if (a) {
+ if (a < 0) {
+ sgn = 1;
+ mnt = -mnt;
+ }
+ for (i = 16; i; i >>= 1)
+ if (!(mnt >> (32 - i))) {
+ mnt <<= i;
+ exp -= i;
+ }
+ x.x1 = ((uint64_t)sgn << 63 | (uint64_t)exp << 48 |
+ (uint64_t)(mnt << 1) << 16);
+ }
+ memcpy(&f, &x, 16);
+ return f;
+}
+
+long double __floatditf(int64_t a)
+{
+ int sgn = 0;
+ int exp = 16446;
+ uint64_t mnt = a;
+ u128_t x = { 0, 0 };
+ long double f;
+ int i;
+ if (a) {
+ if (a < 0) {
+ sgn = 1;
+ mnt = -mnt;
+ }
+ for (i = 32; i; i >>= 1)
+ if (!(mnt >> (64 - i))) {
+ mnt <<= i;
+ exp -= i;
+ }
+ x.x0 = mnt << 49;
+ x.x1 = (uint64_t)sgn << 63 | (uint64_t)exp << 48 | mnt << 1 >> 16;
+ }
+ memcpy(&f, &x, 16);
+ return f;
+}
+
+long double __floatunsitf(uint32_t a)
+{
+ int exp = 16414;
+ uint32_t mnt = a;
+ u128_t x = { 0, 0 };
+ long double f;
+ int i;
+ if (a) {
+ for (i = 16; i; i >>= 1)
+ if (!(mnt >> (32 - i))) {
+ mnt <<= i;
+ exp -= i;
+ }
+ x.x1 = (uint64_t)exp << 48 | (uint64_t)(mnt << 1) << 16;
+ }
+ memcpy(&f, &x, 16);
+ return f;
+}
+
+long double __floatunditf(uint64_t a)
+{
+ int exp = 16446;
+ uint64_t mnt = a;
+ u128_t x = { 0, 0 };
+ long double f;
+ int i;
+ if (a) {
+ for (i = 32; i; i >>= 1)
+ if (!(mnt >> (64 - i))) {
+ mnt <<= i;
+ exp -= i;
+ }
+ x.x0 = mnt << 49;
+ x.x1 = (uint64_t)exp << 48 | mnt << 1 >> 16;
+ }
+ memcpy(&f, &x, 16);
+ return f;
+}
+
+static int f3_cmp(long double fa, long double fb)
+{
+ u128_t a, b;
+ memcpy(&a, &fa, 16);
+ memcpy(&b, &fb, 16);
+ return (!(a.x0 | a.x1 << 1 | b.x0 | b.x1 << 1) ? 0 :
+ ((a.x1 << 1 >> 49 == 0x7fff && (a.x0 | a.x1 << 16)) ||
+ (b.x1 << 1 >> 49 == 0x7fff && (b.x0 | b.x1 << 16))) ? 2 :
+ a.x1 >> 63 != b.x1 >> 63 ? (int)(b.x1 >> 63) - (int)(a.x1 >> 63) :
+ a.x1 < b.x1 ? (int)(a.x1 >> 63 << 1) - 1 :
+ a.x1 > b.x1 ? 1 - (int)(a.x1 >> 63 << 1) :
+ a.x0 < b.x0 ? (int)(a.x1 >> 63 << 1) - 1 :
+ b.x0 < a.x0 ? 1 - (int)(a.x1 >> 63 << 1) : 0);
+}
+
+int __eqtf2(long double a, long double b)
+{
+ return !!f3_cmp(a, b);
+}
+
+int __netf2(long double a, long double b)
+{
+ return !!f3_cmp(a, b);
+}
+
+int __lttf2(long double a, long double b)
+{
+ return f3_cmp(a, b);
+}
+
+int __letf2(long double a, long double b)
+{
+ return f3_cmp(a, b);
+}
+
+int __gttf2(long double a, long double b)
+{
+ return -f3_cmp(b, a);
+}
+
+int __getf2(long double a, long double b)
+{
+ return -f3_cmp(b, a);
+}
diff --git a/lib/libtcc1.c b/lib/libtcc1.c
new file mode 100644
index 0000000..0e46618
--- /dev/null
+++ b/lib/libtcc1.c
@@ -0,0 +1,622 @@
+/* TCC runtime library.
+ Parts of this code are (c) 2002 Fabrice Bellard
+
+ Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+#define W_TYPE_SIZE 32
+#define BITS_PER_UNIT 8
+
+typedef int Wtype;
+typedef unsigned int UWtype;
+typedef unsigned int USItype;
+typedef long long DWtype;
+typedef unsigned long long UDWtype;
+
+struct DWstruct {
+ Wtype low, high;
+};
+
+typedef union
+{
+ struct DWstruct s;
+ DWtype ll;
+} DWunion;
+
+typedef long double XFtype;
+#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
+#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
+
+/* the following deal with IEEE single-precision numbers */
+#define EXCESS 126
+#define SIGNBIT 0x80000000
+#define HIDDEN (1 << 23)
+#define SIGN(fp) ((fp) & SIGNBIT)
+#define EXP(fp) (((fp) >> 23) & 0xFF)
+#define MANT(fp) (((fp) & 0x7FFFFF) | HIDDEN)
+#define PACK(s,e,m) ((s) | ((e) << 23) | (m))
+
+/* the following deal with IEEE double-precision numbers */
+#define EXCESSD 1022
+#define HIDDEND (1 << 20)
+#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
+#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
+#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
+ (fp.l.lower >> 22))
+#define HIDDEND_LL ((long long)1 << 52)
+#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
+#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m))
+
+/* the following deal with x86 long double-precision numbers */
+#define EXCESSLD 16382
+#define EXPLD(fp) (fp.l.upper & 0x7fff)
+#define SIGNLD(fp) ((fp.l.upper) & 0x8000)
+
+/* only for x86 */
+union ldouble_long {
+ long double ld;
+ struct {
+ unsigned long long lower;
+ unsigned short upper;
+ } l;
+};
+
+union double_long {
+ double d;
+#if 1
+ struct {
+ unsigned int lower;
+ int upper;
+ } l;
+#else
+ struct {
+ int upper;
+ unsigned int lower;
+ } l;
+#endif
+ long long ll;
+};
+
+union float_long {
+ float f;
+ unsigned int l;
+};
+
+/* XXX: we don't support several builtin supports for now */
+#if !defined __x86_64__ && !defined __arm__
+
+/* XXX: use gcc/tcc intrinsic ? */
+#if defined __i386__
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl %5,%1\n\tsbbl %3,%0" \
+ : "=r" ((USItype) (sh)), \
+ "=&r" ((USItype) (sl)) \
+ : "0" ((USItype) (ah)), \
+ "g" ((USItype) (bh)), \
+ "1" ((USItype) (al)), \
+ "g" ((USItype) (bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mull %3" \
+ : "=a" ((USItype) (w0)), \
+ "=d" ((USItype) (w1)) \
+ : "%0" ((USItype) (u)), \
+ "rm" ((USItype) (v)))
+#define udiv_qrnnd(q, r, n1, n0, dv) \
+ __asm__ ("divl %4" \
+ : "=a" ((USItype) (q)), \
+ "=d" ((USItype) (r)) \
+ : "0" ((USItype) (n0)), \
+ "1" ((USItype) (n1)), \
+ "rm" ((USItype) (dv)))
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("bsrl %1,%0" \
+ : "=r" (__cbtmp) : "rm" ((USItype) (x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#else
+#error unsupported CPU type
+#endif
+
+/* most of this code is taken from libgcc2.c from gcc */
+
+static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
+{
+ DWunion ww;
+ DWunion nn, dd;
+ DWunion rr;
+ UWtype d0, d1, n0, n1, n2;
+ UWtype q0, q1;
+ UWtype b, bm;
+
+ nn.ll = n;
+ dd.ll = d;
+
+ d0 = dd.s.low;
+ d1 = dd.s.high;
+ n0 = nn.s.low;
+ n1 = nn.s.high;
+
+#if !defined(UDIV_NEEDS_NORMALIZATION)
+ if (d1 == 0)
+ {
+ if (d0 > n1)
+ {
+ /* 0q = nn / 0D */
+
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+ q1 = 0;
+
+ /* Remainder in n0. */
+ }
+ else
+ {
+ /* qq = NN / 0d */
+
+ if (d0 == 0)
+ d0 = 1 / d0; /* Divide intentionally by zero. */
+
+ udiv_qrnnd (q1, n1, 0, n1, d0);
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+
+ /* Remainder in n0. */
+ }
+
+ if (rp != 0)
+ {
+ rr.s.low = n0;
+ rr.s.high = 0;
+ *rp = rr.ll;
+ }
+ }
+
+#else /* UDIV_NEEDS_NORMALIZATION */
+
+ if (d1 == 0)
+ {
+ if (d0 > n1)
+ {
+ /* 0q = nn / 0D */
+
+ count_leading_zeros (bm, d0);
+
+ if (bm != 0)
+ {
+ /* Normalize, i.e. make the most significant bit of the
+ denominator set. */
+
+ d0 = d0 << bm;
+ n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
+ n0 = n0 << bm;
+ }
+
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+ q1 = 0;
+
+ /* Remainder in n0 >> bm. */
+ }
+ else
+ {
+ /* qq = NN / 0d */
+
+ if (d0 == 0)
+ d0 = 1 / d0; /* Divide intentionally by zero. */
+
+ count_leading_zeros (bm, d0);
+
+ if (bm == 0)
+ {
+ /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ leading quotient digit q1 = 1).
+
+ This special case is necessary, not an optimization.
+ (Shifts counts of W_TYPE_SIZE are undefined.) */
+
+ n1 -= d0;
+ q1 = 1;
+ }
+ else
+ {
+ /* Normalize. */
+
+ b = W_TYPE_SIZE - bm;
+
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd (q1, n1, n2, n1, d0);
+ }
+
+ /* n1 != d0... */
+
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+
+ /* Remainder in n0 >> bm. */
+ }
+
+ if (rp != 0)
+ {
+ rr.s.low = n0 >> bm;
+ rr.s.high = 0;
+ *rp = rr.ll;
+ }
+ }
+#endif /* UDIV_NEEDS_NORMALIZATION */
+
+ else
+ {
+ if (d1 > n1)
+ {
+ /* 00 = nn / DD */
+
+ q0 = 0;
+ q1 = 0;
+
+ /* Remainder in n1n0. */
+ if (rp != 0)
+ {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ }
+ else
+ {
+ /* 0q = NN / dd */
+
+ count_leading_zeros (bm, d1);
+ if (bm == 0)
+ {
+ /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ quotient digit q0 = 0 or 1).
+
+ This special case is necessary, not an optimization. */
+
+ /* The condition on the next line takes advantage of that
+ n1 >= d1 (true due to program flow). */
+ if (n1 > d1 || n0 >= d0)
+ {
+ q0 = 1;
+ sub_ddmmss (n1, n0, n1, n0, d1, d0);
+ }
+ else
+ q0 = 0;
+
+ q1 = 0;
+
+ if (rp != 0)
+ {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ }
+ else
+ {
+ UWtype m1, m0;
+ /* Normalize. */
+
+ b = W_TYPE_SIZE - bm;
+
+ d1 = (d1 << bm) | (d0 >> b);
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd (q0, n1, n2, n1, d1);
+ umul_ppmm (m1, m0, q0, d0);
+
+ if (m1 > n1 || (m1 == n1 && m0 > n0))
+ {
+ q0--;
+ sub_ddmmss (m1, m0, m1, m0, d1, d0);
+ }
+
+ q1 = 0;
+
+ /* Remainder in (n1n0 - m1m0) >> bm. */
+ if (rp != 0)
+ {
+ sub_ddmmss (n1, n0, n1, n0, m1, m0);
+ rr.s.low = (n1 << b) | (n0 >> bm);
+ rr.s.high = n1 >> bm;
+ *rp = rr.ll;
+ }
+ }
+ }
+ }
+
+ ww.s.low = q0;
+ ww.s.high = q1;
+ return ww.ll;
+}
+
+#define __negdi2(a) (-(a))
+
+long long __divdi3(long long u, long long v)
+{
+ int c = 0;
+ DWunion uu, vv;
+ DWtype w;
+
+ uu.ll = u;
+ vv.ll = v;
+
+ if (uu.s.high < 0) {
+ c = ~c;
+ uu.ll = __negdi2 (uu.ll);
+ }
+ if (vv.s.high < 0) {
+ c = ~c;
+ vv.ll = __negdi2 (vv.ll);
+ }
+ w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
+ if (c)
+ w = __negdi2 (w);
+ return w;
+}
+
+long long __moddi3(long long u, long long v)
+{
+ int c = 0;
+ DWunion uu, vv;
+ DWtype w;
+
+ uu.ll = u;
+ vv.ll = v;
+
+ if (uu.s.high < 0) {
+ c = ~c;
+ uu.ll = __negdi2 (uu.ll);
+ }
+ if (vv.s.high < 0)
+ vv.ll = __negdi2 (vv.ll);
+
+ __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
+ if (c)
+ w = __negdi2 (w);
+ return w;
+}
+
+unsigned long long __udivdi3(unsigned long long u, unsigned long long v)
+{
+ return __udivmoddi4 (u, v, (UDWtype *) 0);
+}
+
+unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
+{
+ UDWtype w;
+
+ __udivmoddi4 (u, v, &w);
+ return w;
+}
+
+/* XXX: fix tcc's code generator to do this instead */
+long long __ashrdi3(long long a, int b)
+{
+#ifdef __TINYC__
+ DWunion u;
+ u.ll = a;
+ if (b >= 32) {
+ u.s.low = u.s.high >> (b - 32);
+ u.s.high = u.s.high >> 31;
+ } else if (b != 0) {
+ u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
+ u.s.high = u.s.high >> b;
+ }
+ return u.ll;
+#else
+ return a >> b;
+#endif
+}
+
+/* XXX: fix tcc's code generator to do this instead */
+unsigned long long __lshrdi3(unsigned long long a, int b)
+{
+#ifdef __TINYC__
+ DWunion u;
+ u.ll = a;
+ if (b >= 32) {
+ u.s.low = (unsigned)u.s.high >> (b - 32);
+ u.s.high = 0;
+ } else if (b != 0) {
+ u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
+ u.s.high = (unsigned)u.s.high >> b;
+ }
+ return u.ll;
+#else
+ return a >> b;
+#endif
+}
+
+/* XXX: fix tcc's code generator to do this instead */
+long long __ashldi3(long long a, int b)
+{
+#ifdef __TINYC__
+ DWunion u;
+ u.ll = a;
+ if (b >= 32) {
+ u.s.high = (unsigned)u.s.low << (b - 32);
+ u.s.low = 0;
+ } else if (b != 0) {
+ u.s.high = ((unsigned)u.s.high << b) | ((unsigned)u.s.low >> (32 - b));
+ u.s.low = (unsigned)u.s.low << b;
+ }
+ return u.ll;
+#else
+ return a << b;
+#endif
+}
+
+#endif /* !__x86_64__ */
+
+/* XXX: fix tcc's code generator to do this instead */
+float __floatundisf(unsigned long long a)
+{
+ DWunion uu;
+ XFtype r;
+
+ uu.ll = a;
+ if (uu.s.high >= 0) {
+ return (float)uu.ll;
+ } else {
+ r = (XFtype)uu.ll;
+ r += 18446744073709551616.0;
+ return (float)r;
+ }
+}
+
+double __floatundidf(unsigned long long a)
+{
+ DWunion uu;
+ XFtype r;
+
+ uu.ll = a;
+ if (uu.s.high >= 0) {
+ return (double)uu.ll;
+ } else {
+ r = (XFtype)uu.ll;
+ r += 18446744073709551616.0;
+ return (double)r;
+ }
+}
+
+long double __floatundixf(unsigned long long a)
+{
+ DWunion uu;
+ XFtype r;
+
+ uu.ll = a;
+ if (uu.s.high >= 0) {
+ return (long double)uu.ll;
+ } else {
+ r = (XFtype)uu.ll;
+ r += 18446744073709551616.0;
+ return (long double)r;
+ }
+}
+
+unsigned long long __fixunssfdi (float a1)
+{
+ register union float_long fl1;
+ register int exp;
+ register unsigned long l;
+
+ fl1.f = a1;
+
+ if (fl1.l == 0)
+ return (0);
+
+ exp = EXP (fl1.l) - EXCESS - 24;
+
+ l = MANT(fl1.l);
+ if (exp >= 41)
+ return (unsigned long long)-1;
+ else if (exp >= 0)
+ return (unsigned long long)l << exp;
+ else if (exp >= -23)
+ return l >> -exp;
+ else
+ return 0;
+}
+
+long long __fixsfdi (float a1)
+{
+ long long ret; int s;
+ ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
+ return s ? ret : -ret;
+}
+
+unsigned long long __fixunsdfdi (double a1)
+{
+ register union double_long dl1;
+ register int exp;
+ register unsigned long long l;
+
+ dl1.d = a1;
+
+ if (dl1.ll == 0)
+ return (0);
+
+ exp = EXPD (dl1) - EXCESSD - 53;
+
+ l = MANTD_LL(dl1);
+
+ if (exp >= 12)
+ return (unsigned long long)-1;
+ else if (exp >= 0)
+ return l << exp;
+ else if (exp >= -52)
+ return l >> -exp;
+ else
+ return 0;
+}
+
+long long __fixdfdi (double a1)
+{
+ long long ret; int s;
+ ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
+ return s ? ret : -ret;
+}
+
+#ifndef __arm__
+unsigned long long __fixunsxfdi (long double a1)
+{
+ register union ldouble_long dl1;
+ register int exp;
+ register unsigned long long l;
+
+ dl1.ld = a1;
+
+ if (dl1.l.lower == 0 && dl1.l.upper == 0)
+ return (0);
+
+ exp = EXPLD (dl1) - EXCESSLD - 64;
+
+ l = dl1.l.lower;
+
+ if (exp > 0)
+ return (unsigned long long)-1;
+ else if (exp >= -63)
+ return l >> -exp;
+ else
+ return 0;
+}
+
+long long __fixxfdi (long double a1)
+{
+ long long ret; int s;
+ ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
+ return s ? ret : -ret;
+}
+#endif /* !ARM */
diff --git a/lib/va_list.c b/lib/va_list.c
new file mode 100644
index 0000000..8749f46
--- /dev/null
+++ b/lib/va_list.c
@@ -0,0 +1,65 @@
+/* va_list.c - tinycc support for va_list on X86_64 */
+
+#if defined __x86_64__
+
+/* Avoid include files, they may not be available when cross compiling */
+extern void *memset(void *s, int c, __SIZE_TYPE__ n);
+extern void abort(void);
+
+/* This should be in sync with our include/stdarg.h */
+enum __va_arg_type {
+ __va_gen_reg, __va_float_reg, __va_stack
+};
+
+/* GCC compatible definition of va_list. */
+typedef struct {
+ unsigned int gp_offset;
+ unsigned int fp_offset;
+ union {
+ unsigned int overflow_offset;
+ char *overflow_arg_area;
+ };
+ char *reg_save_area;
+} __va_list_struct;
+
+void __va_start(__va_list_struct *ap, void *fp)
+{
+ memset(ap, 0, sizeof(__va_list_struct));
+ *ap = *(__va_list_struct *)((char *)fp - 16);
+ ap->overflow_arg_area = (char *)fp + ap->overflow_offset;
+ ap->reg_save_area = (char *)fp - 176 - 16;
+}
+
+void *__va_arg(__va_list_struct *ap,
+ enum __va_arg_type arg_type,
+ int size, int align)
+{
+ size = (size + 7) & ~7;
+ align = (align + 7) & ~7;
+ switch (arg_type) {
+ case __va_gen_reg:
+ if (ap->gp_offset + size <= 48) {
+ ap->gp_offset += size;
+ return ap->reg_save_area + ap->gp_offset - size;
+ }
+ goto use_overflow_area;
+
+ case __va_float_reg:
+ if (ap->fp_offset < 128 + 48) {
+ ap->fp_offset += 16;
+ return ap->reg_save_area + ap->fp_offset - 16;
+ }
+ size = 8;
+ goto use_overflow_area;
+
+ case __va_stack:
+ use_overflow_area:
+ ap->overflow_arg_area += size;
+ ap->overflow_arg_area = (char*)((long long)(ap->overflow_arg_area + align - 1) & -align);
+ return ap->overflow_arg_area - size;
+
+ default: /* should never happen */
+ abort();
+ }
+}
+#endif
diff --git a/libtcc.c b/libtcc.c
new file mode 100644
index 0000000..1e9dd97
--- /dev/null
+++ b/libtcc.c
@@ -0,0 +1,1981 @@
+/*
+ * TCC - Tiny C Compiler
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tcc.h"
+
+/********************************************************/
+/* global variables */
+
+/* use GNU C extensions */
+ST_DATA int gnu_ext = 1;
+
+/* use TinyCC extensions */
+ST_DATA int tcc_ext = 1;
+
+/* XXX: get rid of this ASAP */
+ST_DATA struct TCCState *tcc_state;
+
+static int nb_states;
+
+/********************************************************/
+
+#if ONE_SOURCE
+#include "tccpp.c"
+#include "tccgen.c"
+#include "tccelf.c"
+#include "tccrun.c"
+#ifdef TCC_TARGET_I386
+#include "i386-gen.c"
+#include "i386-link.c"
+#include "i386-asm.c"
+#endif
+#ifdef TCC_TARGET_ARM
+#include "arm-gen.c"
+#include "arm-link.c"
+#include "arm-asm.c"
+#endif
+#ifdef TCC_TARGET_ARM64
+#include "arm64-gen.c"
+#include "arm64-link.c"
+#endif
+#ifdef TCC_TARGET_C67
+#include "c67-gen.c"
+#include "c67-link.c"
+#include "tcccoff.c"
+#endif
+#ifdef TCC_TARGET_X86_64
+#include "x86_64-gen.c"
+#include "x86_64-link.c"
+#include "i386-asm.c"
+#endif
+#ifdef CONFIG_TCC_ASM
+#include "tccasm.c"
+#endif
+#ifdef TCC_TARGET_PE
+#include "tccpe.c"
+#endif
+#endif /* ONE_SOURCE */
+
+/********************************************************/
+#ifndef CONFIG_TCC_ASM
+ST_FUNC void asm_instr(void)
+{
+ tcc_error("inline asm() not supported");
+}
+ST_FUNC void asm_global_instr(void)
+{
+ tcc_error("inline asm() not supported");
+}
+#endif
+
+/********************************************************/
+#ifdef _WIN32
+ST_FUNC char *normalize_slashes(char *path)
+{
+ char *p;
+ for (p = path; *p; ++p)
+ if (*p == '\\')
+ *p = '/';
+ return path;
+}
+
+static HMODULE tcc_module;
+
+/* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */
+static void tcc_set_lib_path_w32(TCCState *s)
+{
+ char path[1024], *p;
+ GetModuleFileNameA(tcc_module, path, sizeof path);
+ p = tcc_basename(normalize_slashes(strlwr(path)));
+ if (p > path)
+ --p;
+ *p = 0;
+ tcc_set_lib_path(s, path);
+}
+
+#ifdef TCC_TARGET_PE
+static void tcc_add_systemdir(TCCState *s)
+{
+ char buf[1000];
+ GetSystemDirectory(buf, sizeof buf);
+ tcc_add_library_path(s, normalize_slashes(buf));
+}
+#endif
+
+#ifdef LIBTCC_AS_DLL
+BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
+{
+ if (DLL_PROCESS_ATTACH == dwReason)
+ tcc_module = hDll;
+ return TRUE;
+}
+#endif
+#endif
+
+/********************************************************/
+/* copy a string and truncate it. */
+ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
+{
+ char *q, *q_end;
+ int c;
+
+ if (buf_size > 0) {
+ q = buf;
+ q_end = buf + buf_size - 1;
+ while (q < q_end) {
+ c = *s++;
+ if (c == '\0')
+ break;
+ *q++ = c;
+ }
+ *q = '\0';
+ }
+ return buf;
+}
+
+/* strcat and truncate. */
+ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
+{
+ int len;
+ len = strlen(buf);
+ if (len < buf_size)
+ pstrcpy(buf + len, buf_size - len, s);
+ return buf;
+}
+
+ST_FUNC char *pstrncpy(char *out, const char *in, size_t num)
+{
+ memcpy(out, in, num);
+ out[num] = '\0';
+ return out;
+}
+
+/* extract the basename of a file */
+PUB_FUNC char *tcc_basename(const char *name)
+{
+ char *p = strchr(name, 0);
+ while (p > name && !IS_DIRSEP(p[-1]))
+ --p;
+ return p;
+}
+
+/* extract extension part of a file
+ *
+ * (if no extension, return pointer to end-of-string)
+ */
+PUB_FUNC char *tcc_fileextension (const char *name)
+{
+ char *b = tcc_basename(name);
+ char *e = strrchr(b, '.');
+ return e ? e : strchr(b, 0);
+}
+
+/********************************************************/
+/* memory management */
+
+#undef free
+#undef malloc
+#undef realloc
+
+#ifndef MEM_DEBUG
+
+PUB_FUNC void tcc_free(void *ptr)
+{
+ free(ptr);
+}
+
+PUB_FUNC void *tcc_malloc(unsigned long size)
+{
+ void *ptr;
+ ptr = malloc(size);
+ if (!ptr && size)
+ tcc_error("memory full (malloc)");
+ return ptr;
+}
+
+PUB_FUNC void *tcc_mallocz(unsigned long size)
+{
+ void *ptr;
+ ptr = tcc_malloc(size);
+ memset(ptr, 0, size);
+ return ptr;
+}
+
+PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
+{
+ void *ptr1;
+ ptr1 = realloc(ptr, size);
+ if (!ptr1 && size)
+ tcc_error("memory full (realloc)");
+ return ptr1;
+}
+
+PUB_FUNC char *tcc_strdup(const char *str)
+{
+ char *ptr;
+ ptr = tcc_malloc(strlen(str) + 1);
+ strcpy(ptr, str);
+ return ptr;
+}
+
+PUB_FUNC void tcc_memcheck(void)
+{
+}
+
+#else
+
+#define MEM_DEBUG_MAGIC1 0xFEEDDEB1
+#define MEM_DEBUG_MAGIC2 0xFEEDDEB2
+#define MEM_DEBUG_MAGIC3 0xFEEDDEB3
+#define MEM_DEBUG_FILE_LEN 40
+#define MEM_DEBUG_CHECK3(header) \
+ ((mem_debug_header_t*)((char*)header + header->size))->magic3
+#define MEM_USER_PTR(header) \
+ ((char *)header + offsetof(mem_debug_header_t, magic3))
+#define MEM_HEADER_PTR(ptr) \
+ (mem_debug_header_t *)((char*)ptr - offsetof(mem_debug_header_t, magic3))
+
+struct mem_debug_header {
+ unsigned magic1;
+ unsigned size;
+ struct mem_debug_header *prev;
+ struct mem_debug_header *next;
+ int line_num;
+ char file_name[MEM_DEBUG_FILE_LEN + 1];
+ unsigned magic2;
+ ALIGNED(16) unsigned magic3;
+};
+
+typedef struct mem_debug_header mem_debug_header_t;
+
+static mem_debug_header_t *mem_debug_chain;
+static unsigned mem_cur_size;
+static unsigned mem_max_size;
+
+static mem_debug_header_t *malloc_check(void *ptr, const char *msg)
+{
+ mem_debug_header_t * header = MEM_HEADER_PTR(ptr);
+ if (header->magic1 != MEM_DEBUG_MAGIC1 ||
+ header->magic2 != MEM_DEBUG_MAGIC2 ||
+ MEM_DEBUG_CHECK3(header) != MEM_DEBUG_MAGIC3 ||
+ header->size == (unsigned)-1) {
+ fprintf(stderr, "%s check failed\n", msg);
+ if (header->magic1 == MEM_DEBUG_MAGIC1)
+ fprintf(stderr, "%s:%u: block allocated here.\n",
+ header->file_name, header->line_num);
+ exit(1);
+ }
+ return header;
+}
+
+PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
+{
+ int ofs;
+ mem_debug_header_t *header;
+
+ header = malloc(sizeof(mem_debug_header_t) + size);
+ if (!header)
+ tcc_error("memory full (malloc)");
+
+ header->magic1 = MEM_DEBUG_MAGIC1;
+ header->magic2 = MEM_DEBUG_MAGIC2;
+ header->size = size;
+ MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3;
+ header->line_num = line;
+ ofs = strlen(file) - MEM_DEBUG_FILE_LEN;
+ strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN);
+ header->file_name[MEM_DEBUG_FILE_LEN] = 0;
+
+ header->next = mem_debug_chain;
+ header->prev = NULL;
+ if (header->next)
+ header->next->prev = header;
+ mem_debug_chain = header;
+
+ mem_cur_size += size;
+ if (mem_cur_size > mem_max_size)
+ mem_max_size = mem_cur_size;
+
+ return MEM_USER_PTR(header);
+}
+
+PUB_FUNC void tcc_free_debug(void *ptr)
+{
+ mem_debug_header_t *header;
+ if (!ptr)
+ return;
+ header = malloc_check(ptr, "tcc_free");
+ mem_cur_size -= header->size;
+ header->size = (unsigned)-1;
+ if (header->next)
+ header->next->prev = header->prev;
+ if (header->prev)
+ header->prev->next = header->next;
+ if (header == mem_debug_chain)
+ mem_debug_chain = header->next;
+ free(header);
+}
+
+PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line)
+{
+ void *ptr;
+ ptr = tcc_malloc_debug(size,file,line);
+ memset(ptr, 0, size);
+ return ptr;
+}
+
+PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line)
+{
+ mem_debug_header_t *header;
+ int mem_debug_chain_update = 0;
+ if (!ptr)
+ return tcc_malloc_debug(size, file, line);
+ header = malloc_check(ptr, "tcc_realloc");
+ mem_cur_size -= header->size;
+ mem_debug_chain_update = (header == mem_debug_chain);
+ header = realloc(header, sizeof(mem_debug_header_t) + size);
+ if (!header)
+ tcc_error("memory full (realloc)");
+ header->size = size;
+ MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3;
+ if (header->next)
+ header->next->prev = header;
+ if (header->prev)
+ header->prev->next = header;
+ if (mem_debug_chain_update)
+ mem_debug_chain = header;
+ mem_cur_size += size;
+ if (mem_cur_size > mem_max_size)
+ mem_max_size = mem_cur_size;
+ return MEM_USER_PTR(header);
+}
+
+PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line)
+{
+ char *ptr;
+ ptr = tcc_malloc_debug(strlen(str) + 1, file, line);
+ strcpy(ptr, str);
+ return ptr;
+}
+
+PUB_FUNC void tcc_memcheck(void)
+{
+ if (mem_cur_size) {
+ mem_debug_header_t *header = mem_debug_chain;
+ fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n",
+ mem_cur_size, mem_max_size);
+ while (header) {
+ fprintf(stderr, "%s:%u: error: %u bytes leaked\n",
+ header->file_name, header->line_num, header->size);
+ header = header->next;
+ }
+#if MEM_DEBUG-0 == 2
+ exit(2);
+#endif
+ }
+}
+#endif /* MEM_DEBUG */
+
+#define free(p) use_tcc_free(p)
+#define malloc(s) use_tcc_malloc(s)
+#define realloc(p, s) use_tcc_realloc(p, s)
+
+/********************************************************/
+/* dynarrays */
+
+ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data)
+{
+ int nb, nb_alloc;
+ void **pp;
+
+ nb = *nb_ptr;
+ pp = *(void ***)ptab;
+ /* every power of two we double array size */
+ if ((nb & (nb - 1)) == 0) {
+ if (!nb)
+ nb_alloc = 1;
+ else
+ nb_alloc = nb * 2;
+ pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
+ *(void***)ptab = pp;
+ }
+ pp[nb++] = data;
+ *nb_ptr = nb;
+}
+
+ST_FUNC void dynarray_reset(void *pp, int *n)
+{
+ void **p;
+ for (p = *(void***)pp; *n; ++p, --*n)
+ if (*p)
+ tcc_free(*p);
+ tcc_free(*(void**)pp);
+ *(void**)pp = NULL;
+}
+
+static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)
+{
+ const char *p;
+ do {
+ int c;
+ CString str;
+
+ cstr_new(&str);
+ for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) {
+ if (c == '{' && p[1] && p[2] == '}') {
+ c = p[1], p += 2;
+ if (c == 'B')
+ cstr_cat(&str, s->tcc_lib_path, -1);
+ } else {
+ cstr_ccat(&str, c);
+ }
+ }
+ if (str.size) {
+ cstr_ccat(&str, '\0');
+ dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data));
+ }
+ cstr_free(&str);
+ in = p+1;
+ } while (*p);
+}
+
+/********************************************************/
+
+static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
+{
+ int len;
+ len = strlen(buf);
+ vsnprintf(buf + len, buf_size - len, fmt, ap);
+}
+
+static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ strcat_vprintf(buf, buf_size, fmt, ap);
+ va_end(ap);
+}
+
+static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
+{
+ char buf[2048];
+ BufferedFile **pf, *f;
+
+ buf[0] = '\0';
+ /* use upper file if inline ":asm:" or token ":paste:" */
+ for (f = file; f && f->filename[0] == ':'; f = f->prev)
+ ;
+ if (f) {
+ for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++)
+ strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
+ (*pf)->filename, (*pf)->line_num);
+ if (s1->error_set_jmp_enabled) {
+ strcat_printf(buf, sizeof(buf), "%s:%d: ",
+ f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL));
+ } else {
+ strcat_printf(buf, sizeof(buf), "%s: ",
+ f->filename);
+ }
+ } else {
+ strcat_printf(buf, sizeof(buf), "tcc: ");
+ }
+ if (is_warning)
+ strcat_printf(buf, sizeof(buf), "warning: ");
+ else
+ strcat_printf(buf, sizeof(buf), "error: ");
+ strcat_vprintf(buf, sizeof(buf), fmt, ap);
+
+ if (!s1->error_func) {
+ /* default case: stderr */
+ if (s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout)
+ /* print a newline during tcc -E */
+ printf("\n"), fflush(stdout);
+ fflush(stdout); /* flush -v output */
+ fprintf(stderr, "%s\n", buf);
+ fflush(stderr); /* print error/warning now (win32) */
+ } else {
+ s1->error_func(s1->error_opaque, buf);
+ }
+ if (!is_warning || s1->warn_error)
+ s1->nb_errors++;
+}
+
+LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
+ void (*error_func)(void *opaque, const char *msg))
+{
+ s->error_opaque = error_opaque;
+ s->error_func = error_func;
+}
+
+/* error without aborting current compilation */
+PUB_FUNC void tcc_error_noabort(const char *fmt, ...)
+{
+ TCCState *s1 = tcc_state;
+ va_list ap;
+
+ va_start(ap, fmt);
+ error1(s1, 0, fmt, ap);
+ va_end(ap);
+}
+
+PUB_FUNC void tcc_error(const char *fmt, ...)
+{
+ TCCState *s1 = tcc_state;
+ va_list ap;
+
+ va_start(ap, fmt);
+ error1(s1, 0, fmt, ap);
+ va_end(ap);
+ /* better than nothing: in some cases, we accept to handle errors */
+ if (s1->error_set_jmp_enabled) {
+ longjmp(s1->error_jmp_buf, 1);
+ } else {
+ /* XXX: eliminate this someday */
+ exit(1);
+ }
+}
+
+PUB_FUNC void tcc_warning(const char *fmt, ...)
+{
+ TCCState *s1 = tcc_state;
+ va_list ap;
+
+ if (s1->warn_none)
+ return;
+
+ va_start(ap, fmt);
+ error1(s1, 1, fmt, ap);
+ va_end(ap);
+}
+
+/********************************************************/
+/* I/O layer */
+
+ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
+{
+ BufferedFile *bf;
+ int buflen = initlen ? initlen : IO_BUF_SIZE;
+
+ bf = tcc_mallocz(sizeof(BufferedFile) + buflen);
+ bf->buf_ptr = bf->buffer;
+ bf->buf_end = bf->buffer + initlen;
+ bf->buf_end[0] = CH_EOB; /* put eob symbol */
+ pstrcpy(bf->filename, sizeof(bf->filename), filename);
+ bf->true_filename = bf->filename;
+ bf->line_num = 1;
+ bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
+ bf->fd = -1;
+ bf->prev = file;
+ file = bf;
+ tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
+}
+
+ST_FUNC void tcc_close(void)
+{
+ BufferedFile *bf = file;
+ if (bf->fd > 0) {
+ close(bf->fd);
+ total_lines += bf->line_num;
+ }
+ if (bf->true_filename != bf->filename)
+ tcc_free(bf->true_filename);
+ file = bf->prev;
+ tcc_free(bf);
+}
+
+ST_FUNC int tcc_open(TCCState *s1, const char *filename)
+{
+ int fd;
+ if (strcmp(filename, "-") == 0)
+ fd = 0, filename = "<stdin>";
+ else
+ fd = open(filename, O_RDONLY | O_BINARY);
+ if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)
+ printf("%s %*s%s\n", fd < 0 ? "nf":"->",
+ (int)(s1->include_stack_ptr - s1->include_stack), "", filename);
+ if (fd < 0)
+ return -1;
+ tcc_open_bf(s1, filename, 0);
+#ifdef _WIN32
+ normalize_slashes(file->filename);
+#endif
+ file->fd = fd;
+ return fd;
+}
+
+/* compile the file opened in 'file'. Return non zero if errors. */
+static int tcc_compile(TCCState *s1)
+{
+ Sym *define_start;
+ int filetype, is_asm;
+
+ define_start = define_stack;
+ filetype = s1->filetype;
+ is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP;
+ tccelf_begin_file(s1);
+
+ if (setjmp(s1->error_jmp_buf) == 0) {
+ s1->nb_errors = 0;
+ s1->error_set_jmp_enabled = 1;
+
+ preprocess_start(s1, is_asm);
+ if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
+ tcc_preprocess(s1);
+ } else if (is_asm) {
+#ifdef CONFIG_TCC_ASM
+ tcc_assemble(s1, filetype == AFF_TYPE_ASMPP);
+#else
+ tcc_error_noabort("asm not supported");
+#endif
+ } else {
+ tccgen_compile(s1);
+ }
+ }
+ s1->error_set_jmp_enabled = 0;
+
+ preprocess_end(s1);
+ free_inline_functions(s1);
+ /* reset define stack, but keep -D and built-ins */
+ free_defines(define_start);
+ sym_pop(&global_stack, NULL, 0);
+ sym_pop(&local_stack, NULL, 0);
+ tccelf_end_file(s1);
+ return s1->nb_errors != 0 ? -1 : 0;
+}
+
+LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
+{
+ int len, ret;
+
+ len = strlen(str);
+ tcc_open_bf(s, "<string>", len);
+ memcpy(file->buffer, str, len);
+ ret = tcc_compile(s);
+ tcc_close();
+ return ret;
+}
+
+/* define a preprocessor symbol. A value can also be provided with the '=' operator */
+LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
+{
+ int len1, len2;
+ /* default value */
+ if (!value)
+ value = "1";
+ len1 = strlen(sym);
+ len2 = strlen(value);
+
+ /* init file structure */
+ tcc_open_bf(s1, "<define>", len1 + len2 + 1);
+ memcpy(file->buffer, sym, len1);
+ file->buffer[len1] = ' ';
+ memcpy(file->buffer + len1 + 1, value, len2);
+
+ /* parse with define parser */
+ next_nomacro();
+ parse_define();
+ tcc_close();
+}
+
+/* undefine a preprocessor symbol */
+LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
+{
+ TokenSym *ts;
+ Sym *s;
+ ts = tok_alloc(sym, strlen(sym));
+ s = define_find(ts->tok);
+ /* undefine symbol by putting an invalid name */
+ if (s)
+ define_undef(s);
+}
+
+/* cleanup all static data used during compilation */
+static void tcc_cleanup(void)
+{
+ if (NULL == tcc_state)
+ return;
+ while (file)
+ tcc_close();
+ tccpp_delete(tcc_state);
+ tcc_state = NULL;
+ /* free sym_pools */
+ dynarray_reset(&sym_pools, &nb_sym_pools);
+ /* reset symbol stack */
+ sym_free_first = NULL;
+}
+
+LIBTCCAPI TCCState *tcc_new(void)
+{
+ TCCState *s;
+
+ tcc_cleanup();
+
+ s = tcc_mallocz(sizeof(TCCState));
+ if (!s)
+ return NULL;
+ tcc_state = s;
+ ++nb_states;
+
+ s->alacarte_link = 1;
+ s->nocommon = 1;
+ s->warn_implicit_function_declaration = 1;
+ s->ms_extensions = 1;
+
+#ifdef CHAR_IS_UNSIGNED
+ s->char_is_unsigned = 1;
+#endif
+#ifdef TCC_TARGET_I386
+ s->seg_size = 32;
+#endif
+ /* enable this if you want symbols with leading underscore on windows: */
+#if 0 /* def TCC_TARGET_PE */
+ s->leading_underscore = 1;
+#endif
+#ifdef _WIN32
+ tcc_set_lib_path_w32(s);
+#else
+ tcc_set_lib_path(s, CONFIG_TCCDIR);
+#endif
+ tccelf_new(s);
+ tccpp_new(s);
+
+ /* we add dummy defines for some special macros to speed up tests
+ and to have working defined() */
+ define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
+ define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
+ define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
+ define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
+ define_push(TOK___COUNTER__, MACRO_OBJ, NULL, NULL);
+ {
+ /* define __TINYC__ 92X */
+ char buffer[32]; int a,b,c;
+ sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c);
+ sprintf(buffer, "%d", a*10000 + b*100 + c);
+ tcc_define_symbol(s, "__TINYC__", buffer);
+ }
+
+ /* standard defines */
+ tcc_define_symbol(s, "__STDC__", NULL);
+ tcc_define_symbol(s, "__STDC_VERSION__", "199901L");
+ tcc_define_symbol(s, "__STDC_HOSTED__", NULL);
+
+ /* target defines */
+#if defined(TCC_TARGET_I386)
+ tcc_define_symbol(s, "__i386__", NULL);
+ tcc_define_symbol(s, "__i386", NULL);
+ tcc_define_symbol(s, "i386", NULL);
+#elif defined(TCC_TARGET_X86_64)
+ tcc_define_symbol(s, "__x86_64__", NULL);
+#elif defined(TCC_TARGET_ARM)
+ tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
+ tcc_define_symbol(s, "__arm_elf__", NULL);
+ tcc_define_symbol(s, "__arm_elf", NULL);
+ tcc_define_symbol(s, "arm_elf", NULL);
+ tcc_define_symbol(s, "__arm__", NULL);
+ tcc_define_symbol(s, "__arm", NULL);
+ tcc_define_symbol(s, "arm", NULL);
+ tcc_define_symbol(s, "__APCS_32__", NULL);
+ tcc_define_symbol(s, "__ARMEL__", NULL);
+#if defined(TCC_ARM_EABI)
+ tcc_define_symbol(s, "__ARM_EABI__", NULL);
+#endif
+#if defined(TCC_ARM_HARDFLOAT)
+ s->float_abi = ARM_HARD_FLOAT;
+ tcc_define_symbol(s, "__ARM_PCS_VFP", NULL);
+#else
+ s->float_abi = ARM_SOFTFP_FLOAT;
+#endif
+#elif defined(TCC_TARGET_ARM64)
+ tcc_define_symbol(s, "__aarch64__", NULL);
+#elif defined TCC_TARGET_C67
+ tcc_define_symbol(s, "__C67__", NULL);
+#endif
+
+#ifdef TCC_TARGET_PE
+ tcc_define_symbol(s, "_WIN32", NULL);
+# ifdef TCC_TARGET_X86_64
+ tcc_define_symbol(s, "_WIN64", NULL);
+# endif
+#else
+ tcc_define_symbol(s, "__unix__", NULL);
+ tcc_define_symbol(s, "__unix", NULL);
+ tcc_define_symbol(s, "unix", NULL);
+# if defined(__linux__)
+ tcc_define_symbol(s, "__linux__", NULL);
+ tcc_define_symbol(s, "__linux", NULL);
+# endif
+# if defined(__FreeBSD__)
+ tcc_define_symbol(s, "__FreeBSD__", "__FreeBSD__");
+ /* No 'Thread Storage Local' on FreeBSD with tcc */
+ tcc_define_symbol(s, "__NO_TLS", NULL);
+# endif
+# if defined(__FreeBSD_kernel__)
+ tcc_define_symbol(s, "__FreeBSD_kernel__", NULL);
+# endif
+# if defined(__NetBSD__)
+ tcc_define_symbol(s, "__NetBSD__", "__NetBSD__");
+# endif
+# if defined(__OpenBSD__)
+ tcc_define_symbol(s, "__OpenBSD__", "__OpenBSD__");
+# endif
+#endif
+
+ /* TinyCC & gcc defines */
+#if PTR_SIZE == 4
+ /* 32bit systems. */
+ tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
+ tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
+ tcc_define_symbol(s, "__ILP32__", NULL);
+#elif LONG_SIZE == 4
+ /* 64bit Windows. */
+ tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long");
+ tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long");
+ tcc_define_symbol(s, "__LLP64__", NULL);
+#else
+ /* Other 64bit systems. */
+ tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");
+ tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");
+ tcc_define_symbol(s, "__LP64__", NULL);
+#endif
+
+#ifdef TCC_TARGET_PE
+ tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short");
+ tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short");
+#else
+ tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
+ /* wint_t is unsigned int by default, but (signed) int on BSDs
+ and unsigned short on windows. Other OSes might have still
+ other conventions, sigh. */
+# if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) \
+ || defined(__NetBSD__) || defined(__OpenBSD__)
+ tcc_define_symbol(s, "__WINT_TYPE__", "int");
+# ifdef __FreeBSD__
+ /* define __GNUC__ to have some useful stuff from sys/cdefs.h
+ that are unconditionally used in FreeBSDs other system headers :/ */
+ tcc_define_symbol(s, "__GNUC__", "2");
+ tcc_define_symbol(s, "__GNUC_MINOR__", "7");
+ tcc_define_symbol(s, "__builtin_alloca", "alloca");
+# endif
+# else
+ tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int");
+ /* glibc defines */
+ tcc_define_symbol(s, "__REDIRECT(name, proto, alias)",
+ "name proto __asm__ (#alias)");
+ tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)",
+ "name proto __asm__ (#alias) __THROW");
+# endif
+# if defined(TCC_MUSL)
+ tcc_define_symbol(s, "__DEFINED_va_list", "");
+ tcc_define_symbol(s, "__DEFINED___isoc_va_list", "");
+ tcc_define_symbol(s, "__isoc_va_list", "void *");
+# endif /* TCC_MUSL */
+ /* Some GCC builtins that are simple to express as macros. */
+ tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x");
+#endif /* ndef TCC_TARGET_PE */
+ return s;
+}
+
+LIBTCCAPI void tcc_delete(TCCState *s1)
+{
+ tcc_cleanup();
+
+ /* free sections */
+ tccelf_delete(s1);
+
+ /* free library paths */
+ dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
+ dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths);
+
+ /* free include paths */
+ dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
+ dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
+ dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
+ dynarray_reset(&s1->cmd_include_files, &s1->nb_cmd_include_files);
+
+ tcc_free(s1->tcc_lib_path);
+ tcc_free(s1->soname);
+ tcc_free(s1->rpath);
+ tcc_free(s1->init_symbol);
+ tcc_free(s1->fini_symbol);
+ tcc_free(s1->outfile);
+ tcc_free(s1->deps_outfile);
+ dynarray_reset(&s1->files, &s1->nb_files);
+ dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
+ dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);
+ dynarray_reset(&s1->argv, &s1->argc);
+
+#ifdef TCC_IS_NATIVE
+ /* free runtime memory */
+ tcc_run_free(s1);
+#endif
+
+ tcc_free(s1);
+ if (0 == --nb_states)
+ tcc_memcheck();
+}
+
+LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
+{
+ s->output_type = output_type;
+
+ /* always elf for objects */
+ if (output_type == TCC_OUTPUT_OBJ)
+ s->output_format = TCC_OUTPUT_FORMAT_ELF;
+
+ if (s->char_is_unsigned)
+ tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
+
+ if (!s->nostdinc) {
+ /* default include paths */
+ /* -isystem paths have already been handled */
+ tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
+ }
+
+#ifdef CONFIG_TCC_BCHECK
+ if (s->do_bounds_check) {
+ /* if bound checking, then add corresponding sections */
+ tccelf_bounds_new(s);
+ /* define symbol */
+ tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
+ }
+#endif
+ if (s->do_debug) {
+ /* add debug sections */
+ tccelf_stab_new(s);
+ }
+
+ tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
+
+#ifdef TCC_TARGET_PE
+# ifdef _WIN32
+ if (!s->nostdlib && output_type != TCC_OUTPUT_OBJ)
+ tcc_add_systemdir(s);
+# endif
+#else
+ /* paths for crt objects */
+ tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
+ /* add libc crt1/crti objects */
+ if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
+ !s->nostdlib) {
+ if (output_type != TCC_OUTPUT_DLL)
+ tcc_add_crt(s, "crt1.o");
+ tcc_add_crt(s, "crti.o");
+ }
+#endif
+ return 0;
+}
+
+LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
+{
+ tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname);
+ return 0;
+}
+
+LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
+{
+ tcc_split_path(s, &s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);
+ return 0;
+}
+
+ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
+{
+ int ret;
+
+ /* open the file */
+ ret = tcc_open(s1, filename);
+ if (ret < 0) {
+ if (flags & AFF_PRINT_ERROR)
+ tcc_error_noabort("file '%s' not found", filename);
+ return ret;
+ }
+
+ /* update target deps */
+ dynarray_add(&s1->target_deps, &s1->nb_target_deps,
+ tcc_strdup(filename));
+
+ if (flags & AFF_TYPE_BIN) {
+ ElfW(Ehdr) ehdr;
+ int fd, obj_type;
+
+ fd = file->fd;
+ obj_type = tcc_object_type(fd, &ehdr);
+ lseek(fd, 0, SEEK_SET);
+
+#ifdef TCC_TARGET_MACHO
+ if (0 == obj_type && 0 == strcmp(tcc_fileextension(filename), ".dylib"))
+ obj_type = AFF_BINTYPE_DYN;
+#endif
+
+ switch (obj_type) {
+ case AFF_BINTYPE_REL:
+ ret = tcc_load_object_file(s1, fd, 0);
+ break;
+#ifndef TCC_TARGET_PE
+ case AFF_BINTYPE_DYN:
+ if (s1->output_type == TCC_OUTPUT_MEMORY) {
+ ret = 0;
+#ifdef TCC_IS_NATIVE
+ if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY))
+ ret = -1;
+#endif
+ } else {
+ ret = tcc_load_dll(s1, fd, filename,
+ (flags & AFF_REFERENCED_DLL) != 0);
+ }
+ break;
+#endif
+ case AFF_BINTYPE_AR:
+ ret = tcc_load_archive(s1, fd);
+ break;
+#ifdef TCC_TARGET_COFF
+ case AFF_BINTYPE_C67:
+ ret = tcc_load_coff(s1, fd);
+ break;
+#endif
+ default:
+#ifdef TCC_TARGET_PE
+ ret = pe_load_file(s1, filename, fd);
+#else
+ /* as GNU ld, consider it is an ld script if not recognized */
+ ret = tcc_load_ldscript(s1);
+#endif
+ if (ret < 0)
+ tcc_error_noabort("unrecognized file type");
+ break;
+ }
+ } else {
+ ret = tcc_compile(s1);
+ }
+ tcc_close();
+ return ret;
+}
+
+LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
+{
+ int filetype = s->filetype;
+ int flags = AFF_PRINT_ERROR;
+ if (filetype == 0) {
+ /* use a file extension to detect a filetype */
+ const char *ext = tcc_fileextension(filename);
+ if (ext[0]) {
+ ext++;
+ if (!strcmp(ext, "S"))
+ filetype = AFF_TYPE_ASMPP;
+ else if (!strcmp(ext, "s"))
+ filetype = AFF_TYPE_ASM;
+ else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i"))
+ filetype = AFF_TYPE_C;
+ else
+ flags |= AFF_TYPE_BIN;
+ } else {
+ filetype = AFF_TYPE_C;
+ }
+ s->filetype = filetype;
+ }
+ return tcc_add_file_internal(s, filename, flags);
+}
+
+LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
+{
+ tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
+ return 0;
+}
+
+static int tcc_add_library_internal(TCCState *s, const char *fmt,
+ const char *filename, int flags, char **paths, int nb_paths)
+{
+ char buf[1024];
+ int i;
+
+ for(i = 0; i < nb_paths; i++) {
+ snprintf(buf, sizeof(buf), fmt, paths[i], filename);
+ if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0)
+ return 0;
+ }
+ return -1;
+}
+
+/* find and load a dll. Return non zero if not found */
+/* XXX: add '-rpath' option support ? */
+ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
+{
+ return tcc_add_library_internal(s, "%s/%s", filename, flags,
+ s->library_paths, s->nb_library_paths);
+}
+
+ST_FUNC int tcc_add_crt(TCCState *s, const char *filename)
+{
+ if (-1 == tcc_add_library_internal(s, "%s/%s",
+ filename, 0, s->crt_paths, s->nb_crt_paths))
+ tcc_error_noabort("file '%s' not found", filename);
+ return 0;
+}
+
+/* the library name is the same as the argument of the '-l' option */
+LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
+{
+#if defined TCC_TARGET_PE
+ const char *libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };
+ const char **pp = s->static_link ? libs + 4 : libs;
+#elif defined TCC_TARGET_MACHO
+ const char *libs[] = { "%s/lib%s.dylib", "%s/lib%s.a", NULL };
+ const char **pp = s->static_link ? libs + 1 : libs;
+#else
+ const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
+ const char **pp = s->static_link ? libs + 1 : libs;
+#endif
+ while (*pp) {
+ if (0 == tcc_add_library_internal(s, *pp,
+ libraryname, 0, s->library_paths, s->nb_library_paths))
+ return 0;
+ ++pp;
+ }
+ return -1;
+}
+
+PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname)
+{
+ int ret = tcc_add_library(s, libname);
+ if (ret < 0)
+ tcc_error_noabort("library '%s' not found", libname);
+ return ret;
+}
+
+/* handle #pragma comment(lib,) */
+ST_FUNC void tcc_add_pragma_libs(TCCState *s1)
+{
+ int i;
+ for (i = 0; i < s1->nb_pragma_libs; i++)
+ tcc_add_library_err(s1, s1->pragma_libs[i]);
+}
+
+LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val)
+{
+#ifdef TCC_TARGET_PE
+ /* On x86_64 'val' might not be reachable with a 32bit offset.
+ So it is handled here as if it were in a DLL. */
+ pe_putimport(s, 0, name, (uintptr_t)val);
+#else
+ set_elf_sym(symtab_section, (uintptr_t)val, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ SHN_ABS, name);
+#endif
+ return 0;
+}
+
+LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
+{
+ tcc_free(s->tcc_lib_path);
+ s->tcc_lib_path = tcc_strdup(path);
+}
+
+#define WD_ALL 0x0001 /* warning is activated when using -Wall */
+#define FD_INVERT 0x0002 /* invert value before storing */
+
+typedef struct FlagDef {
+ uint16_t offset;
+ uint16_t flags;
+ const char *name;
+} FlagDef;
+
+static int no_flag(const char **pp)
+{
+ const char *p = *pp;
+ if (*p != 'n' || *++p != 'o' || *++p != '-')
+ return 0;
+ *pp = p + 1;
+ return 1;
+}
+
+ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name)
+{
+ int value, ret;
+ const FlagDef *p;
+ const char *r;
+
+ value = 1;
+ r = name;
+ if (no_flag(&r))
+ value = 0;
+
+ for (ret = -1, p = flags; p->name; ++p) {
+ if (ret) {
+ if (strcmp(r, p->name))
+ continue;
+ } else {
+ if (0 == (p->flags & WD_ALL))
+ continue;
+ }
+ if (p->offset) {
+ *(int*)((char *)s + p->offset) =
+ p->flags & FD_INVERT ? !value : value;
+ if (ret)
+ return 0;
+ } else {
+ ret = 0;
+ }
+ }
+ return ret;
+}
+
+static int strstart(const char *val, const char **str)
+{
+ const char *p, *q;
+ p = *str;
+ q = val;
+ while (*q) {
+ if (*p != *q)
+ return 0;
+ p++;
+ q++;
+ }
+ *str = p;
+ return 1;
+}
+
+/* Like strstart, but automatically takes into account that ld options can
+ *
+ * - start with double or single dash (e.g. '--soname' or '-soname')
+ * - arguments can be given as separate or after '=' (e.g. '-Wl,-soname,x.so'
+ * or '-Wl,-soname=x.so')
+ *
+ * you provide `val` always in 'option[=]' form (no leading -)
+ */
+static int link_option(const char *str, const char *val, const char **ptr)
+{
+ const char *p, *q;
+ int ret;
+
+ /* there should be 1 or 2 dashes */
+ if (*str++ != '-')
+ return 0;
+ if (*str == '-')
+ str++;
+
+ /* then str & val should match (potentially up to '=') */
+ p = str;
+ q = val;
+
+ ret = 1;
+ if (q[0] == '?') {
+ ++q;
+ if (no_flag(&p))
+ ret = -1;
+ }
+
+ while (*q != '\0' && *q != '=') {
+ if (*p != *q)
+ return 0;
+ p++;
+ q++;
+ }
+
+ /* '=' near eos means ',' or '=' is ok */
+ if (*q == '=') {
+ if (*p == 0)
+ *ptr = p;
+ if (*p != ',' && *p != '=')
+ return 0;
+ p++;
+ } else if (*p) {
+ return 0;
+ }
+ *ptr = p;
+ return ret;
+}
+
+static const char *skip_linker_arg(const char **str)
+{
+ const char *s1 = *str;
+ const char *s2 = strchr(s1, ',');
+ *str = s2 ? s2++ : (s2 = s1 + strlen(s1));
+ return s2;
+}
+
+static void copy_linker_arg(char **pp, const char *s, int sep)
+{
+ const char *q = s;
+ char *p = *pp;
+ int l = 0;
+ if (p && sep)
+ p[l = strlen(p)] = sep, ++l;
+ skip_linker_arg(&q);
+ pstrncpy(l + (*pp = tcc_realloc(p, q - s + l + 1)), s, q - s);
+}
+
+/* set linker options */
+static int tcc_set_linker(TCCState *s, const char *option)
+{
+ while (*option) {
+
+ const char *p = NULL;
+ char *end = NULL;
+ int ignoring = 0;
+ int ret;
+
+ if (link_option(option, "Bsymbolic", &p)) {
+ s->symbolic = 1;
+ } else if (link_option(option, "nostdlib", &p)) {
+ s->nostdlib = 1;
+ } else if (link_option(option, "fini=", &p)) {
+ copy_linker_arg(&s->fini_symbol, p, 0);
+ ignoring = 1;
+ } else if (link_option(option, "image-base=", &p)
+ || link_option(option, "Ttext=", &p)) {
+ s->text_addr = strtoull(p, &end, 16);
+ s->has_text_addr = 1;
+ } else if (link_option(option, "init=", &p)) {
+ copy_linker_arg(&s->init_symbol, p, 0);
+ ignoring = 1;
+ } else if (link_option(option, "oformat=", &p)) {
+#if defined(TCC_TARGET_PE)
+ if (strstart("pe-", &p)) {
+#elif PTR_SIZE == 8
+ if (strstart("elf64-", &p)) {
+#else
+ if (strstart("elf32-", &p)) {
+#endif
+ s->output_format = TCC_OUTPUT_FORMAT_ELF;
+ } else if (!strcmp(p, "binary")) {
+ s->output_format = TCC_OUTPUT_FORMAT_BINARY;
+#ifdef TCC_TARGET_COFF
+ } else if (!strcmp(p, "coff")) {
+ s->output_format = TCC_OUTPUT_FORMAT_COFF;
+#endif
+ } else
+ goto err;
+
+ } else if (link_option(option, "as-needed", &p)) {
+ ignoring = 1;
+ } else if (link_option(option, "O", &p)) {
+ ignoring = 1;
+ } else if (link_option(option, "export-all-symbols", &p)) {
+ s->rdynamic = 1;
+ } else if (link_option(option, "rpath=", &p)) {
+ copy_linker_arg(&s->rpath, p, ':');
+ } else if (link_option(option, "enable-new-dtags", &p)) {
+ s->enable_new_dtags = 1;
+ } else if (link_option(option, "section-alignment=", &p)) {
+ s->section_align = strtoul(p, &end, 16);
+ } else if (link_option(option, "soname=", &p)) {
+ copy_linker_arg(&s->soname, p, 0);
+#ifdef TCC_TARGET_PE
+ } else if (link_option(option, "large-address-aware", &p)) {
+ s->pe_characteristics |= 0x20;
+ } else if (link_option(option, "file-alignment=", &p)) {
+ s->pe_file_align = strtoul(p, &end, 16);
+ } else if (link_option(option, "stack=", &p)) {
+ s->pe_stack_size = strtoul(p, &end, 10);
+ } else if (link_option(option, "subsystem=", &p)) {
+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
+ if (!strcmp(p, "native")) {
+ s->pe_subsystem = 1;
+ } else if (!strcmp(p, "console")) {
+ s->pe_subsystem = 3;
+ } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) {
+ s->pe_subsystem = 2;
+ } else if (!strcmp(p, "posix")) {
+ s->pe_subsystem = 7;
+ } else if (!strcmp(p, "efiapp")) {
+ s->pe_subsystem = 10;
+ } else if (!strcmp(p, "efiboot")) {
+ s->pe_subsystem = 11;
+ } else if (!strcmp(p, "efiruntime")) {
+ s->pe_subsystem = 12;
+ } else if (!strcmp(p, "efirom")) {
+ s->pe_subsystem = 13;
+#elif defined(TCC_TARGET_ARM)
+ if (!strcmp(p, "wince")) {
+ s->pe_subsystem = 9;
+#endif
+ } else
+ goto err;
+#endif
+ } else if (ret = link_option(option, "?whole-archive", &p), ret) {
+ s->alacarte_link = ret < 0;
+ } else if (p) {
+ return 0;
+ } else {
+ err:
+ tcc_error("unsupported linker option '%s'", option);
+ }
+
+ if (ignoring && s->warn_unsupported)
+ tcc_warning("unsupported linker option '%s'", option);
+
+ option = skip_linker_arg(&p);
+ }
+ return 1;
+}
+
+typedef struct TCCOption {
+ const char *name;
+ uint16_t index;
+ uint16_t flags;
+} TCCOption;
+
+enum {
+ TCC_OPTION_HELP,
+ TCC_OPTION_HELP2,
+ TCC_OPTION_v,
+ TCC_OPTION_I,
+ TCC_OPTION_D,
+ TCC_OPTION_U,
+ TCC_OPTION_P,
+ TCC_OPTION_L,
+ TCC_OPTION_B,
+ TCC_OPTION_l,
+ TCC_OPTION_bench,
+ TCC_OPTION_bt,
+ TCC_OPTION_b,
+ TCC_OPTION_g,
+ TCC_OPTION_c,
+ TCC_OPTION_dumpversion,
+ TCC_OPTION_d,
+ TCC_OPTION_static,
+ TCC_OPTION_std,
+ TCC_OPTION_shared,
+ TCC_OPTION_soname,
+ TCC_OPTION_o,
+ TCC_OPTION_r,
+ TCC_OPTION_s,
+ TCC_OPTION_traditional,
+ TCC_OPTION_Wl,
+ TCC_OPTION_Wp,
+ TCC_OPTION_W,
+ TCC_OPTION_O,
+ TCC_OPTION_mfloat_abi,
+ TCC_OPTION_m,
+ TCC_OPTION_f,
+ TCC_OPTION_isystem,
+ TCC_OPTION_iwithprefix,
+ TCC_OPTION_include,
+ TCC_OPTION_nostdinc,
+ TCC_OPTION_nostdlib,
+ TCC_OPTION_print_search_dirs,
+ TCC_OPTION_rdynamic,
+ TCC_OPTION_param,
+ TCC_OPTION_pedantic,
+ TCC_OPTION_pthread,
+ TCC_OPTION_run,
+ TCC_OPTION_w,
+ TCC_OPTION_pipe,
+ TCC_OPTION_E,
+ TCC_OPTION_MD,
+ TCC_OPTION_MF,
+ TCC_OPTION_x,
+ TCC_OPTION_ar,
+ TCC_OPTION_impdef
+};
+
+#define TCC_OPTION_HAS_ARG 0x0001
+#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
+
+static const TCCOption tcc_options[] = {
+ { "h", TCC_OPTION_HELP, 0 },
+ { "-help", TCC_OPTION_HELP, 0 },
+ { "?", TCC_OPTION_HELP, 0 },
+ { "hh", TCC_OPTION_HELP2, 0 },
+ { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
+ { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
+ { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
+ { "P", TCC_OPTION_P, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
+ { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
+ { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "bench", TCC_OPTION_bench, 0 },
+#ifdef CONFIG_TCC_BACKTRACE
+ { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
+#endif
+#ifdef CONFIG_TCC_BCHECK
+ { "b", TCC_OPTION_b, 0 },
+#endif
+ { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "c", TCC_OPTION_c, 0 },
+ { "dumpversion", TCC_OPTION_dumpversion, 0},
+ { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "static", TCC_OPTION_static, 0 },
+ { "std", TCC_OPTION_std, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "shared", TCC_OPTION_shared, 0 },
+ { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG },
+ { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
+ { "-param", TCC_OPTION_param, TCC_OPTION_HAS_ARG },
+ { "pedantic", TCC_OPTION_pedantic, 0},
+ { "pthread", TCC_OPTION_pthread, 0},
+ { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "rdynamic", TCC_OPTION_rdynamic, 0 },
+ { "r", TCC_OPTION_r, 0 },
+ { "s", TCC_OPTION_s, 0 },
+ { "traditional", TCC_OPTION_traditional, 0 },
+ { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "Wp,", TCC_OPTION_Wp, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+#ifdef TCC_TARGET_ARM
+ { "mfloat-abi", TCC_OPTION_mfloat_abi, TCC_OPTION_HAS_ARG },
+#endif
+ { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+ { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
+ { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG },
+ { "nostdinc", TCC_OPTION_nostdinc, 0 },
+ { "nostdlib", TCC_OPTION_nostdlib, 0 },
+ { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
+ { "w", TCC_OPTION_w, 0 },
+ { "pipe", TCC_OPTION_pipe, 0},
+ { "E", TCC_OPTION_E, 0},
+ { "MD", TCC_OPTION_MD, 0},
+ { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
+ { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
+ { "ar", TCC_OPTION_ar, 0},
+#ifdef TCC_TARGET_PE
+ { "impdef", TCC_OPTION_impdef, 0},
+#endif
+ { NULL, 0, 0 },
+};
+
+static const FlagDef options_W[] = {
+ { 0, 0, "all" },
+ { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
+ { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
+ { offsetof(TCCState, warn_error), 0, "error" },
+ { offsetof(TCCState, warn_gcc_compat), 0, "gcc-compat" },
+ { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
+ "implicit-function-declaration" },
+ { 0, 0, NULL }
+};
+
+static const FlagDef options_f[] = {
+ { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
+ { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
+ { offsetof(TCCState, nocommon), FD_INVERT, "common" },
+ { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
+ { offsetof(TCCState, ms_extensions), 0, "ms-extensions" },
+ { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" },
+ { 0, 0, NULL }
+};
+
+static const FlagDef options_m[] = {
+ { offsetof(TCCState, ms_bitfields), 0, "ms-bitfields" },
+#ifdef TCC_TARGET_X86_64
+ { offsetof(TCCState, nosse), FD_INVERT, "sse" },
+#endif
+ { 0, 0, NULL }
+};
+
+static void parse_option_D(TCCState *s1, const char *optarg)
+{
+ char *sym = tcc_strdup(optarg);
+ char *value = strchr(sym, '=');
+ if (value)
+ *value++ = '\0';
+ tcc_define_symbol(s1, sym, value);
+ tcc_free(sym);
+}
+
+static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
+{
+ struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
+ f->type = filetype;
+ f->alacarte = s->alacarte_link;
+ strcpy(f->name, filename);
+ dynarray_add(&s->files, &s->nb_files, f);
+}
+
+static int args_parser_make_argv(const char *r, int *argc, char ***argv)
+{
+ int ret = 0, q, c;
+ CString str;
+ for(;;) {
+ while (c = (unsigned char)*r, c && c <= ' ')
+ ++r;
+ if (c == 0)
+ break;
+ q = 0;
+ cstr_new(&str);
+ while (c = (unsigned char)*r, c) {
+ ++r;
+ if (c == '\\' && (*r == '"' || *r == '\\')) {
+ c = *r++;
+ } else if (c == '"') {
+ q = !q;
+ continue;
+ } else if (q == 0 && c <= ' ') {
+ break;
+ }
+ cstr_ccat(&str, c);
+ }
+ cstr_ccat(&str, 0);
+ //printf("<%s>\n", str.data), fflush(stdout);
+ dynarray_add(argv, argc, tcc_strdup(str.data));
+ cstr_free(&str);
+ ++ret;
+ }
+ return ret;
+}
+
+/* read list file */
+static void args_parser_listfile(TCCState *s,
+ const char *filename, int optind, int *pargc, char ***pargv)
+{
+ int fd, i;
+ size_t len;
+ char *p;
+ int argc = 0;
+ char **argv = NULL;
+
+ fd = open(filename, O_RDONLY | O_BINARY);
+ if (fd < 0)
+ tcc_error("listfile '%s' not found", filename);
+
+ len = lseek(fd, 0, SEEK_END);
+ p = tcc_malloc(len + 1), p[len] = 0;
+ lseek(fd, 0, SEEK_SET), read(fd, p, len), close(fd);
+
+ for (i = 0; i < *pargc; ++i)
+ if (i == optind)
+ args_parser_make_argv(p, &argc, &argv);
+ else
+ dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i]));
+
+ tcc_free(p);
+ dynarray_reset(&s->argv, &s->argc);
+ *pargc = s->argc = argc, *pargv = s->argv = argv;
+}
+
+PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
+{
+ const TCCOption *popt;
+ const char *optarg, *r;
+ const char *run = NULL;
+ int last_o = -1;
+ int x;
+ CString linker_arg; /* collect -Wl options */
+ int tool = 0, arg_start = 0, noaction = optind;
+ char **argv = *pargv;
+ int argc = *pargc;
+
+ cstr_new(&linker_arg);
+
+ while (optind < argc) {
+ r = argv[optind];
+ if (r[0] == '@' && r[1] != '\0') {
+ args_parser_listfile(s, r + 1, optind, &argc, &argv);
+ continue;
+ }
+ optind++;
+ if (tool) {
+ if (r[0] == '-' && r[1] == 'v' && r[2] == 0)
+ ++s->verbose;
+ continue;
+ }
+reparse:
+ if (r[0] != '-' || r[1] == '\0') {
+ if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */
+ args_parser_add_file(s, r, s->filetype);
+ if (run) {
+ tcc_set_options(s, run);
+ arg_start = optind - 1;
+ break;
+ }
+ continue;
+ }
+
+ /* find option in table */
+ for(popt = tcc_options; ; ++popt) {
+ const char *p1 = popt->name;
+ const char *r1 = r + 1;
+ if (p1 == NULL)
+ tcc_error("invalid option -- '%s'", r);
+ if (!strstart(p1, &r1))
+ continue;
+ optarg = r1;
+ if (popt->flags & TCC_OPTION_HAS_ARG) {
+ if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
+ if (optind >= argc)
+ arg_err:
+ tcc_error("argument to '%s' is missing", r);
+ optarg = argv[optind++];
+ }
+ } else if (*r1 != '\0')
+ continue;
+ break;
+ }
+
+ switch(popt->index) {
+ case TCC_OPTION_HELP:
+ return OPT_HELP;
+ case TCC_OPTION_HELP2:
+ return OPT_HELP2;
+ case TCC_OPTION_I:
+ tcc_add_include_path(s, optarg);
+ break;
+ case TCC_OPTION_D:
+ parse_option_D(s, optarg);
+ break;
+ case TCC_OPTION_U:
+ tcc_undefine_symbol(s, optarg);
+ break;
+ case TCC_OPTION_L:
+ tcc_add_library_path(s, optarg);
+ break;
+ case TCC_OPTION_B:
+ /* set tcc utilities path (mainly for tcc development) */
+ tcc_set_lib_path(s, optarg);
+ break;
+ case TCC_OPTION_l:
+ args_parser_add_file(s, optarg, AFF_TYPE_LIB);
+ s->nb_libraries++;
+ break;
+ case TCC_OPTION_pthread:
+ parse_option_D(s, "_REENTRANT");
+ s->option_pthread = 1;
+ break;
+ case TCC_OPTION_bench:
+ s->do_bench = 1;
+ break;
+#ifdef CONFIG_TCC_BACKTRACE
+ case TCC_OPTION_bt:
+ tcc_set_num_callers(atoi(optarg));
+ break;
+#endif
+#ifdef CONFIG_TCC_BCHECK
+ case TCC_OPTION_b:
+ s->do_bounds_check = 1;
+ s->do_debug = 1;
+ break;
+#endif
+ case TCC_OPTION_g:
+ s->do_debug = 1;
+ break;
+ case TCC_OPTION_c:
+ x = TCC_OUTPUT_OBJ;
+ set_output_type:
+ if (s->output_type)
+ tcc_warning("-%s: overriding compiler action already specified", popt->name);
+ s->output_type = x;
+ break;
+ case TCC_OPTION_d:
+ if (*optarg == 'D')
+ s->dflag = 3;
+ else if (*optarg == 'M')
+ s->dflag = 7;
+ else if (*optarg == 't')
+ s->dflag = 16;
+ else if (isnum(*optarg))
+ g_debug = atoi(optarg);
+ else
+ goto unsupported_option;
+ break;
+ case TCC_OPTION_static:
+ s->static_link = 1;
+ break;
+ case TCC_OPTION_std:
+ /* silently ignore, a current purpose:
+ allow to use a tcc as a reference compiler for "make test" */
+ break;
+ case TCC_OPTION_shared:
+ x = TCC_OUTPUT_DLL;
+ goto set_output_type;
+ case TCC_OPTION_soname:
+ s->soname = tcc_strdup(optarg);
+ break;
+ case TCC_OPTION_o:
+ if (s->outfile) {
+ tcc_warning("multiple -o option");
+ tcc_free(s->outfile);
+ }
+ s->outfile = tcc_strdup(optarg);
+ break;
+ case TCC_OPTION_r:
+ /* generate a .o merging several output files */
+ s->option_r = 1;
+ x = TCC_OUTPUT_OBJ;
+ goto set_output_type;
+ case TCC_OPTION_isystem:
+ tcc_add_sysinclude_path(s, optarg);
+ break;
+ case TCC_OPTION_include:
+ dynarray_add(&s->cmd_include_files,
+ &s->nb_cmd_include_files, tcc_strdup(optarg));
+ break;
+ case TCC_OPTION_nostdinc:
+ s->nostdinc = 1;
+ break;
+ case TCC_OPTION_nostdlib:
+ s->nostdlib = 1;
+ break;
+ case TCC_OPTION_run:
+#ifndef TCC_IS_NATIVE
+ tcc_error("-run is not available in a cross compiler");
+#endif
+ run = optarg;
+ x = TCC_OUTPUT_MEMORY;
+ goto set_output_type;
+ case TCC_OPTION_v:
+ do ++s->verbose; while (*optarg++ == 'v');
+ ++noaction;
+ break;
+ case TCC_OPTION_f:
+ if (set_flag(s, options_f, optarg) < 0)
+ goto unsupported_option;
+ break;
+#ifdef TCC_TARGET_ARM
+ case TCC_OPTION_mfloat_abi:
+ /* tcc doesn't support soft float yet */
+ if (!strcmp(optarg, "softfp")) {
+ s->float_abi = ARM_SOFTFP_FLOAT;
+ tcc_undefine_symbol(s, "__ARM_PCS_VFP");
+ } else if (!strcmp(optarg, "hard"))
+ s->float_abi = ARM_HARD_FLOAT;
+ else
+ tcc_error("unsupported float abi '%s'", optarg);
+ break;
+#endif
+ case TCC_OPTION_m:
+ if (set_flag(s, options_m, optarg) < 0) {
+ if (x = atoi(optarg), x != 32 && x != 64)
+ goto unsupported_option;
+ if (PTR_SIZE != x/8)
+ return x;
+ ++noaction;
+ }
+ break;
+ case TCC_OPTION_W:
+ if (set_flag(s, options_W, optarg) < 0)
+ goto unsupported_option;
+ break;
+ case TCC_OPTION_w:
+ s->warn_none = 1;
+ break;
+ case TCC_OPTION_rdynamic:
+ s->rdynamic = 1;
+ break;
+ case TCC_OPTION_Wl:
+ if (linker_arg.size)
+ --linker_arg.size, cstr_ccat(&linker_arg, ',');
+ cstr_cat(&linker_arg, optarg, 0);
+ if (tcc_set_linker(s, linker_arg.data))
+ cstr_free(&linker_arg);
+ break;
+ case TCC_OPTION_Wp:
+ r = optarg;
+ goto reparse;
+ case TCC_OPTION_E:
+ x = TCC_OUTPUT_PREPROCESS;
+ goto set_output_type;
+ case TCC_OPTION_P:
+ s->Pflag = atoi(optarg) + 1;
+ break;
+ case TCC_OPTION_MD:
+ s->gen_deps = 1;
+ break;
+ case TCC_OPTION_MF:
+ s->deps_outfile = tcc_strdup(optarg);
+ break;
+ case TCC_OPTION_dumpversion:
+ printf ("%s\n", TCC_VERSION);
+ exit(0);
+ break;
+ case TCC_OPTION_x:
+ if (*optarg == 'c')
+ s->filetype = AFF_TYPE_C;
+ else if (*optarg == 'a')
+ s->filetype = AFF_TYPE_ASMPP;
+ else if (*optarg == 'n')
+ s->filetype = AFF_TYPE_NONE;
+ else
+ tcc_warning("unsupported language '%s'", optarg);
+ break;
+ case TCC_OPTION_O:
+ last_o = atoi(optarg);
+ break;
+ case TCC_OPTION_print_search_dirs:
+ x = OPT_PRINT_DIRS;
+ goto extra_action;
+ case TCC_OPTION_impdef:
+ x = OPT_IMPDEF;
+ goto extra_action;
+ case TCC_OPTION_ar:
+ x = OPT_AR;
+ extra_action:
+ arg_start = optind - 1;
+ if (arg_start != noaction)
+ tcc_error("cannot parse %s here", r);
+ tool = x;
+ break;
+ case TCC_OPTION_traditional:
+ case TCC_OPTION_pedantic:
+ case TCC_OPTION_pipe:
+ case TCC_OPTION_s:
+ /* ignored */
+ break;
+ default:
+unsupported_option:
+ if (s->warn_unsupported)
+ tcc_warning("unsupported option '%s'", r);
+ break;
+ }
+ }
+ if (last_o > 0)
+ tcc_define_symbol(s, "__OPTIMIZE__", NULL);
+ if (linker_arg.size) {
+ r = linker_arg.data;
+ goto arg_err;
+ }
+ *pargc = argc - arg_start;
+ *pargv = argv + arg_start;
+ if (tool)
+ return tool;
+ if (optind != noaction)
+ return 0;
+ if (s->verbose == 2)
+ return OPT_PRINT_DIRS;
+ if (s->verbose)
+ return OPT_V;
+ return OPT_HELP;
+}
+
+LIBTCCAPI void tcc_set_options(TCCState *s, const char *r)
+{
+ char **argv = NULL;
+ int argc = 0;
+ args_parser_make_argv(r, &argc, &argv);
+ tcc_parse_args(s, &argc, &argv, 0);
+ dynarray_reset(&argv, &argc);
+}
+
+PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time)
+{
+ if (total_time < 1)
+ total_time = 1;
+ if (total_bytes < 1)
+ total_bytes = 1;
+ fprintf(stderr, "* %d idents, %d lines, %d bytes\n"
+ "* %0.3f s, %u lines/s, %0.1f MB/s\n",
+ tok_ident - TOK_IDENT, total_lines, total_bytes,
+ (double)total_time/1000,
+ (unsigned)total_lines*1000/total_time,
+ (double)total_bytes/1000/total_time);
+#ifdef MEM_DEBUG
+ fprintf(stderr, "* %d bytes memory used\n", mem_max_size);
+#endif
+}
diff --git a/libtcc.h b/libtcc.h
new file mode 100644
index 0000000..a1b31e3
--- /dev/null
+++ b/libtcc.h
@@ -0,0 +1,100 @@
+#ifndef LIBTCC_H
+#define LIBTCC_H
+
+#ifndef LIBTCCAPI
+# define LIBTCCAPI
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct TCCState;
+
+typedef struct TCCState TCCState;
+
+/* create a new TCC compilation context */
+LIBTCCAPI TCCState *tcc_new(void);
+
+/* free a TCC compilation context */
+LIBTCCAPI void tcc_delete(TCCState *s);
+
+/* set CONFIG_TCCDIR at runtime */
+LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);
+
+/* set error/warning display callback */
+LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
+ void (*error_func)(void *opaque, const char *msg));
+
+/* set options as from command line (multiple supported) */
+LIBTCCAPI void tcc_set_options(TCCState *s, const char *str);
+
+/*****************************/
+/* preprocessor */
+
+/* add include path */
+LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);
+
+/* add in system include path */
+LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
+
+/* define preprocessor symbol 'sym'. Can put optional value */
+LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
+
+/* undefine preprocess symbol 'sym' */
+LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);
+
+/*****************************/
+/* compiling */
+
+/* add a file (C file, dll, object, library, ld script). Return -1 if error. */
+LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);
+
+/* compile a string containing a C source. Return -1 if error. */
+LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
+
+/*****************************/
+/* linking commands */
+
+/* set output type. MUST BE CALLED before any compilation */
+LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
+#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory (default) */
+#define TCC_OUTPUT_EXE 2 /* executable file */
+#define TCC_OUTPUT_DLL 3 /* dynamic library */
+#define TCC_OUTPUT_OBJ 4 /* object file */
+#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */
+
+/* equivalent to -Lpath option */
+LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);
+
+/* the library name is the same as the argument of the '-l' option */
+LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);
+
+/* add a symbol to the compiled program */
+LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val);
+
+/* output an executable, library or object file. DO NOT call
+ tcc_relocate() before. */
+LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename);
+
+/* link and run main() function and return its value. DO NOT call
+ tcc_relocate() before. */
+LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv);
+
+/* do all relocations (needed before using tcc_get_symbol()) */
+LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr);
+/* possible values for 'ptr':
+ - TCC_RELOCATE_AUTO : Allocate and manage memory internally
+ - NULL : return required memory size for the step below
+ - memory address : copy code to memory passed by the caller
+ returns -1 if error. */
+#define TCC_RELOCATE_AUTO (void*)1
+
+/* return symbol value or NULL if not found */
+LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/stab.def b/stab.def
new file mode 100644
index 0000000..48ea231
--- /dev/null
+++ b/stab.def
@@ -0,0 +1,234 @@
+/* Table of DBX symbol codes for the GNU system.
+ Copyright (C) 1988, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* This contains contribution from Cygnus Support. */
+
+/* Global variable. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_GSYM, 0x20, "GSYM")
+
+/* Function name for BSD Fortran. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_FNAME, 0x22, "FNAME")
+
+/* Function name or text-segment variable for C. Value is its address.
+ Desc is supposedly starting line number, but GCC doesn't set it
+ and DBX seems not to miss it. */
+__define_stab (N_FUN, 0x24, "FUN")
+
+/* Data-segment variable with internal linkage. Value is its address.
+ "Static Sym". */
+__define_stab (N_STSYM, 0x26, "STSYM")
+
+/* BSS-segment variable with internal linkage. Value is its address. */
+__define_stab (N_LCSYM, 0x28, "LCSYM")
+
+/* Name of main routine. Only the name is significant.
+ This is not used in C. */
+__define_stab (N_MAIN, 0x2a, "MAIN")
+
+/* Global symbol in Pascal.
+ Supposedly the value is its line number; I'm skeptical. */
+__define_stab (N_PC, 0x30, "PC")
+
+/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */
+__define_stab (N_NSYMS, 0x32, "NSYMS")
+
+/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */
+__define_stab (N_NOMAP, 0x34, "NOMAP")
+
+/* New stab from Solaris. I don't know what it means, but it
+ don't seem to contain useful information. */
+__define_stab (N_OBJ, 0x38, "OBJ")
+
+/* New stab from Solaris. I don't know what it means, but it
+ don't seem to contain useful information. Possibly related to the
+ optimization flags used in this module. */
+__define_stab (N_OPT, 0x3c, "OPT")
+
+/* Register variable. Value is number of register. */
+__define_stab (N_RSYM, 0x40, "RSYM")
+
+/* Modula-2 compilation unit. Can someone say what info it contains? */
+__define_stab (N_M2C, 0x42, "M2C")
+
+/* Line number in text segment. Desc is the line number;
+ value is corresponding address. */
+__define_stab (N_SLINE, 0x44, "SLINE")
+
+/* Similar, for data segment. */
+__define_stab (N_DSLINE, 0x46, "DSLINE")
+
+/* Similar, for bss segment. */
+__define_stab (N_BSLINE, 0x48, "BSLINE")
+
+/* Sun's source-code browser stabs. ?? Don't know what the fields are.
+ Supposedly the field is "path to associated .cb file". THIS VALUE
+ OVERLAPS WITH N_BSLINE! */
+__define_stab (N_BROWS, 0x48, "BROWS")
+
+/* GNU Modula-2 definition module dependency. Value is the modification time
+ of the definition file. Other is non-zero if it is imported with the
+ GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there
+ are enough empty fields? */
+__define_stab(N_DEFD, 0x4a, "DEFD")
+
+/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2
+ and one is for C++. Still,... */
+/* GNU C++ exception variable. Name is variable name. */
+__define_stab (N_EHDECL, 0x50, "EHDECL")
+/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */
+__define_stab (N_MOD2, 0x50, "MOD2")
+
+/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if
+ this entry is immediately followed by a CAUGHT stab saying what exception
+ was caught. Multiple CAUGHT stabs means that multiple exceptions
+ can be caught here. If Desc is 0, it means all exceptions are caught
+ here. */
+__define_stab (N_CATCH, 0x54, "CATCH")
+
+/* Structure or union element. Value is offset in the structure. */
+__define_stab (N_SSYM, 0x60, "SSYM")
+
+/* Name of main source file.
+ Value is starting text address of the compilation. */
+__define_stab (N_SO, 0x64, "SO")
+
+/* Automatic variable in the stack. Value is offset from frame pointer.
+ Also used for type descriptions. */
+__define_stab (N_LSYM, 0x80, "LSYM")
+
+/* Beginning of an include file. Only Sun uses this.
+ In an object file, only the name is significant.
+ The Sun linker puts data into some of the other fields. */
+__define_stab (N_BINCL, 0x82, "BINCL")
+
+/* Name of sub-source file (#include file).
+ Value is starting text address of the compilation. */
+__define_stab (N_SOL, 0x84, "SOL")
+
+/* Parameter variable. Value is offset from argument pointer.
+ (On most machines the argument pointer is the same as the frame pointer. */
+__define_stab (N_PSYM, 0xa0, "PSYM")
+
+/* End of an include file. No name.
+ This and N_BINCL act as brackets around the file's output.
+ In an object file, there is no significant data in this entry.
+ The Sun linker puts data into some of the fields. */
+__define_stab (N_EINCL, 0xa2, "EINCL")
+
+/* Alternate entry point. Value is its address. */
+__define_stab (N_ENTRY, 0xa4, "ENTRY")
+
+/* Beginning of lexical block.
+ The desc is the nesting level in lexical blocks.
+ The value is the address of the start of the text for the block.
+ The variables declared inside the block *precede* the N_LBRAC symbol. */
+__define_stab (N_LBRAC, 0xc0, "LBRAC")
+
+/* Place holder for deleted include file. Replaces a N_BINCL and everything
+ up to the corresponding N_EINCL. The Sun linker generates these when
+ it finds multiple identical copies of the symbols from an include file.
+ This appears only in output from the Sun linker. */
+__define_stab (N_EXCL, 0xc2, "EXCL")
+
+/* Modula-2 scope information. Can someone say what info it contains? */
+__define_stab (N_SCOPE, 0xc4, "SCOPE")
+
+/* End of a lexical block. Desc matches the N_LBRAC's desc.
+ The value is the address of the end of the text for the block. */
+__define_stab (N_RBRAC, 0xe0, "RBRAC")
+
+/* Begin named common block. Only the name is significant. */
+__define_stab (N_BCOMM, 0xe2, "BCOMM")
+
+/* End named common block. Only the name is significant
+ (and it should match the N_BCOMM). */
+__define_stab (N_ECOMM, 0xe4, "ECOMM")
+
+/* End common (local name): value is address.
+ I'm not sure how this is used. */
+__define_stab (N_ECOML, 0xe8, "ECOML")
+
+/* These STAB's are used on Gould systems for Non-Base register symbols
+ or something like that. FIXME. I have assigned the values at random
+ since I don't have a Gould here. Fixups from Gould folk welcome... */
+__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
+__define_stab (N_NBDATA, 0xF2, "NBDATA")
+__define_stab (N_NBBSS, 0xF4, "NBBSS")
+__define_stab (N_NBSTS, 0xF6, "NBSTS")
+__define_stab (N_NBLCS, 0xF8, "NBLCS")
+
+/* Second symbol entry containing a length-value for the preceding entry.
+ The value is the length. */
+__define_stab (N_LENG, 0xfe, "LENG")
+
+/* The above information, in matrix format.
+
+ STAB MATRIX
+ _________________________________________________
+ | 00 - 1F are not dbx stab symbols |
+ | In most cases, the low bit is the EXTernal bit|
+
+ | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA |
+ | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT |
+
+ | 08 BSS | 0A INDR | 0C FN_SEQ | 0E |
+ | 09 |EXT | 0B | 0D | 0F |
+
+ | 10 | 12 COMM | 14 SETA | 16 SETT |
+ | 11 | 13 | 15 | 17 |
+
+ | 18 SETD | 1A SETB | 1C SETV | 1E WARNING|
+ | 19 | 1B | 1D | 1F FN |
+
+ |_______________________________________________|
+ | Debug entries with bit 01 set are unused. |
+ | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM |
+ | 28 LCSYM | 2A MAIN | 2C | 2E |
+ | 30 PC | 32 NSYMS | 34 NOMAP | 36 |
+ | 38 OBJ | 3A | 3C OPT | 3E |
+ | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE |
+ | 48 BSLINE*| 4A DEFD | 4C | 4E |
+ | 50 EHDECL*| 52 | 54 CATCH | 56 |
+ | 58 | 5A | 5C | 5E |
+ | 60 SSYM | 62 | 64 SO | 66 |
+ | 68 | 6A | 6C | 6E |
+ | 70 | 72 | 74 | 76 |
+ | 78 | 7A | 7C | 7E |
+ | 80 LSYM | 82 BINCL | 84 SOL | 86 |
+ | 88 | 8A | 8C | 8E |
+ | 90 | 92 | 94 | 96 |
+ | 98 | 9A | 9C | 9E |
+ | A0 PSYM | A2 EINCL | A4 ENTRY | A6 |
+ | A8 | AA | AC | AE |
+ | B0 | B2 | B4 | B6 |
+ | B8 | BA | BC | BE |
+ | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 |
+ | C8 | CA | CC | CE |
+ | D0 | D2 | D4 | D6 |
+ | D8 | DA | DC | DE |
+ | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 |
+ | E8 ECOML | EA | EC | EE |
+ | F0 | F2 | F4 | F6 |
+ | F8 | FA | FC | FE LENG |
+ +-----------------------------------------------+
+ * 50 EHDECL is also MOD2.
+ * 48 BSLINE is also BROWS.
+ */
diff --git a/stab.h b/stab.h
new file mode 100644
index 0000000..80bd594
--- /dev/null
+++ b/stab.h
@@ -0,0 +1,17 @@
+#ifndef __GNU_STAB__
+
+/* Indicate the GNU stab.h is in use. */
+
+#define __GNU_STAB__
+
+#define __define_stab(NAME, CODE, STRING) NAME=CODE,
+
+enum __stab_debug_code
+{
+#include "stab.def"
+LAST_UNUSED_STAB_CODE
+};
+
+#undef __define_stab
+
+#endif /* __GNU_STAB_ */
diff --git a/tcc-doc.html b/tcc-doc.html
new file mode 100644
index 0000000..c88d27a
--- /dev/null
+++ b/tcc-doc.html
@@ -0,0 +1,2489 @@
+<HTML>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- Created on December, 17 2017 by texi2html 1.64 -->
+<!--
+Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
+ Karl Berry <karl@freefriends.org>
+ Olaf Bachmann <obachman@mathematik.uni-kl.de>
+ and many others.
+Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>
+Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
+
+-->
+<HEAD>
+<TITLE>Tiny C Compiler Reference Documentation: </TITLE>
+
+<META NAME="description" CONTENT="Tiny C Compiler Reference Documentation: ">
+<META NAME="keywords" CONTENT="Tiny C Compiler Reference Documentation: ">
+<META NAME="resource-type" CONTENT="document">
+<META NAME="distribution" CONTENT="global">
+<META NAME="Generator" CONTENT="texi2html 1.64">
+
+</HEAD>
+
+<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
+
+<A NAME="SEC_Top"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>Tiny C Compiler Reference Documentation</H1></P><P>
+
+This manual documents version 0.9.27 of the Tiny C Compiler.
+</P><P>
+
+<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC1">1. Introduction</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Introduction to tcc.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC2">2. Command line invocation</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Invocation of tcc (command line, options).</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC5">3. C language support</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">ANSI C and extensions.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Assembler syntax.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Output file generation and supported targets.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Automatic bounds-checking of C code.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">The libtcc library.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC23">8. Developer's guide</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Guide for Developers.</TD></TR>
+</TABLE></BLOCKQUOTE>
+<P>
+
+<HR SIZE=1>
+<A NAME="SEC1"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<A NAME="Introduction"></A>
+<H1> 1. Introduction </H1>
+<!--docid::SEC1::-->
+<P>
+
+TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C
+compilers, it is meant to be self-relying: you do not need an
+external assembler or linker because TCC does that for you.
+</P><P>
+
+TCC compiles so <EM>fast</EM> that even for big projects <CODE>Makefile</CODE>s may
+not be necessary.
+</P><P>
+
+TCC not only supports ANSI C, but also most of the new ISO C99
+standard and many GNUC extensions including inline assembly.
+</P><P>
+
+TCC can also be used to make <EM>C scripts</EM>, i.e. pieces of C source
+that you run as a Perl or Python script. Compilation is so fast that
+your script will be as fast as if it was an executable.
+</P><P>
+
+TCC can also automatically generate memory and bound checks
+(see section <A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>) while allowing all C pointers operations. TCC can do
+these checks even if non patched libraries are used.
+</P><P>
+
+With <CODE>libtcc</CODE>, you can use TCC as a backend for dynamic code
+generation (see section <A HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>).
+</P><P>
+
+TCC mainly supports the i386 target on Linux and Windows. There are alpha
+ports for the ARM (<CODE>arm-tcc</CODE>) and the TMS320C67xx targets
+(<CODE>c67-tcc</CODE>). More information about the ARM port is available at
+<A HREF="http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html">http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html</A>.
+</P><P>
+
+For usage on Windows, see also <A HREF="tcc-win32.txt">tcc-win32.txt</A>.
+</P><P>
+
+<A NAME="Invoke"></A>
+<HR SIZE="6">
+<A NAME="SEC2"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC1"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC3"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 2. Command line invocation </H1>
+<!--docid::SEC2::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC3"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC4"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.1 Quick start </H2>
+<!--docid::SEC3::-->
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>usage: tcc [options] [<VAR>infile1</VAR> <VAR>infile2</VAR><small>...</small>] [<SAMP>`-run'</SAMP> <VAR>infile</VAR> <VAR>args</VAR><small>...</small>]
+</pre></td></tr></table></P><P>
+
+TCC options are a very much like gcc options. The main difference is that TCC
+can also execute directly the resulting program and give it runtime
+arguments.
+</P><P>
+
+Here are some examples to understand the logic:
+</P><P>
+
+<DL COMPACT>
+<DT><CODE><SAMP>`tcc -run a.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and execute it directly
+<P>
+
+<DT><CODE><SAMP>`tcc -run a.c arg1'</SAMP></CODE>
+<DD>Compile a.c and execute it directly. arg1 is given as first argument to
+the <CODE>main()</CODE> of a.c.
+<P>
+
+<DT><CODE><SAMP>`tcc a.c -run b.c arg1'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them together and execute them. arg1 is given
+as first argument to the <CODE>main()</CODE> of the resulting program.
+<P>
+
+<DT><CODE><SAMP>`tcc -o myprog a.c b.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them and generate the executable <TT>`myprog'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -o myprog a.o b.o'</SAMP></CODE>
+<DD>link <TT>`a.o'</TT> and <TT>`b.o'</TT> together and generate the executable <TT>`myprog'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -c a.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and generate object file <TT>`a.o'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -c asmfile.S'</SAMP></CODE>
+<DD>Preprocess with C preprocess and assemble <TT>`asmfile.S'</TT> and generate
+object file <TT>`asmfile.o'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -c asmfile.s'</SAMP></CODE>
+<DD>Assemble (but not preprocess) <TT>`asmfile.s'</TT> and generate object file
+<TT>`asmfile.o'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -r -o ab.o a.c b.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them together and generate the object file <TT>`ab.o'</TT>.
+<P>
+
+</DL>
+<P>
+
+Scripting:
+</P><P>
+
+TCC can be invoked from <EM>scripts</EM>, just as shell scripts. You just
+need to add <CODE>#!/usr/local/bin/tcc -run</CODE> at the start of your C source:
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#!/usr/local/bin/tcc -run
+#include &#60;stdio.h&#62;
+
+int main()
+{
+ printf("Hello World\n");
+ return 0;
+}
+</pre></td></tr></table></P><P>
+
+TCC can read C source code from <EM>standard input</EM> when <SAMP>`-'</SAMP> is used in
+place of <SAMP>`infile'</SAMP>. Example:
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>echo 'main(){puts("hello");}' | tcc -run -
+</pre></td></tr></table></P><P>
+
+<HR SIZE="6">
+<A NAME="SEC4"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC3"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.2 Option summary </H2>
+<!--docid::SEC4::-->
+<P>
+
+General Options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-c'</SAMP>
+<DD>Generate an object file.
+<P>
+
+<DT><SAMP>`-o outfile'</SAMP>
+<DD>Put object file, executable, or dll into output file <TT>`outfile'</TT>.
+<P>
+
+<DT><SAMP>`-run source [args...]'</SAMP>
+<DD>Compile file <VAR>source</VAR> and run it with the command line arguments
+<VAR>args</VAR>. In order to be able to give more than one argument to a
+script, several TCC options can be given <EM>after</EM> the
+<SAMP>`-run'</SAMP> option, separated by spaces:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
+</pre></td></tr></table>In a script, it gives the following header:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
+</pre></td></tr></table><P>
+
+<DT><SAMP>`-v'</SAMP>
+<DD>Display TCC version.
+<P>
+
+<DT><SAMP>`-vv'</SAMP>
+<DD>Show included files. As sole argument, print search dirs. -vvv shows tries too.
+<P>
+
+<DT><SAMP>`-bench'</SAMP>
+<DD>Display compilation statistics.
+<P>
+
+</DL>
+<P>
+
+Preprocessor options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-Idir'</SAMP>
+<DD>Specify an additional include path. Include paths are searched in the
+order they are specified.
+<P>
+
+System include paths are always searched after. The default system
+include paths are: <TT>`/usr/local/include'</TT>, <TT>`/usr/include'</TT>
+and <TT>`PREFIX/lib/tcc/include'</TT>. (<TT>`PREFIX'</TT> is usually
+<TT>`/usr'</TT> or <TT>`/usr/local'</TT>).
+</P><P>
+
+<DT><SAMP>`-Dsym[=val]'</SAMP>
+<DD>Define preprocessor symbol <SAMP>`sym'</SAMP> to
+val. If val is not present, its value is <SAMP>`1'</SAMP>. Function-like macros can
+also be defined: <SAMP>`-DF(a)=a+1'</SAMP>
+<P>
+
+<DT><SAMP>`-Usym'</SAMP>
+<DD>Undefine preprocessor symbol <SAMP>`sym'</SAMP>.
+<P>
+
+<DT><SAMP>`-E'</SAMP>
+<DD>Preprocess only, to stdout or file (with -o).
+<P>
+
+</DL>
+<P>
+
+Compilation flags:
+</P><P>
+
+Note: each of the following options has a negative form beginning with
+<SAMP>`-fno-'</SAMP>.
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-funsigned-char'</SAMP>
+<DD>Let the <CODE>char</CODE> type be unsigned.
+<P>
+
+<DT><SAMP>`-fsigned-char'</SAMP>
+<DD>Let the <CODE>char</CODE> type be signed.
+<P>
+
+<DT><SAMP>`-fno-common'</SAMP>
+<DD>Do not generate common symbols for uninitialized data.
+<P>
+
+<DT><SAMP>`-fleading-underscore'</SAMP>
+<DD>Add a leading underscore at the beginning of each C symbol.
+<P>
+
+<DT><SAMP>`-fms-extensions'</SAMP>
+<DD>Allow a MS C compiler extensions to the language. Currently this
+assumes a nested named structure declaration without an identifier
+behaves like an unnamed one.
+<P>
+
+<DT><SAMP>`-fdollars-in-identifiers'</SAMP>
+<DD>Allow dollar signs in identifiers
+<P>
+
+</DL>
+<P>
+
+Warning options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-w'</SAMP>
+<DD>Disable all warnings.
+<P>
+
+</DL>
+<P>
+
+Note: each of the following warning options has a negative form beginning with
+<SAMP>`-Wno-'</SAMP>.
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-Wimplicit-function-declaration'</SAMP>
+<DD>Warn about implicit function declaration.
+<P>
+
+<DT><SAMP>`-Wunsupported'</SAMP>
+<DD>Warn about unsupported GCC features that are ignored by TCC.
+<P>
+
+<DT><SAMP>`-Wwrite-strings'</SAMP>
+<DD>Make string constants be of type <CODE>const char *</CODE> instead of <CODE>char
+*</CODE>.
+<P>
+
+<DT><SAMP>`-Werror'</SAMP>
+<DD>Abort compilation if warnings are issued.
+<P>
+
+<DT><SAMP>`-Wall'</SAMP>
+<DD>Activate all warnings, except <SAMP>`-Werror'</SAMP>, <SAMP>`-Wunusupported'</SAMP> and
+<SAMP>`-Wwrite-strings'</SAMP>.
+<P>
+
+</DL>
+<P>
+
+Linker options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-Ldir'</SAMP>
+<DD>Specify an additional static library path for the <SAMP>`-l'</SAMP> option. The
+default library paths are <TT>`/usr/local/lib'</TT>, <TT>`/usr/lib'</TT> and <TT>`/lib'</TT>.
+<P>
+
+<DT><SAMP>`-lxxx'</SAMP>
+<DD>Link your program with dynamic library libxxx.so or static library
+libxxx.a. The library is searched in the paths specified by the
+<SAMP>`-L'</SAMP> option and <CODE>LIBRARY_PATH</CODE> variable.
+<P>
+
+<DT><SAMP>`-Bdir'</SAMP>
+<DD>Set the path where the tcc internal libraries (and include files) can be
+found (default is <TT>`PREFIX/lib/tcc'</TT>).
+<P>
+
+<DT><SAMP>`-shared'</SAMP>
+<DD>Generate a shared library instead of an executable.
+<P>
+
+<DT><SAMP>`-soname name'</SAMP>
+<DD>set name for shared library to be used at runtime
+<P>
+
+<DT><SAMP>`-static'</SAMP>
+<DD>Generate a statically linked executable (default is a shared linked
+executable).
+<P>
+
+<DT><SAMP>`-rdynamic'</SAMP>
+<DD>Export global symbols to the dynamic linker. It is useful when a library
+opened with <CODE>dlopen()</CODE> needs to access executable symbols.
+<P>
+
+<DT><SAMP>`-r'</SAMP>
+<DD>Generate an object file combining all input files.
+<P>
+
+<DT><SAMP>`-Wl,-rpath=path'</SAMP>
+<DD>Put custom search path for dynamic libraries into executable.
+<P>
+
+<DT><SAMP>`-Wl,--enable-new-dtags'</SAMP>
+<DD>When putting a custom search path for dynamic libraries into the executable,
+create the new ELF dynamic tag DT_RUNPATH instead of the old legacy DT_RPATH.
+<P>
+
+<DT><SAMP>`-Wl,--oformat=fmt'</SAMP>
+<DD>Use <VAR>fmt</VAR> as output format. The supported output formats are:
+<DL COMPACT>
+<DT><CODE>elf32-i386</CODE>
+<DD>ELF output format (default)
+<DT><CODE>binary</CODE>
+<DD>Binary image (only for executable output)
+<DT><CODE>coff</CODE>
+<DD>COFF output format (only for executable output for TMS320C67xx target)
+</DL>
+<P>
+
+<DT><SAMP>`-Wl,-subsystem=console/gui/wince/...'</SAMP>
+<DD>Set type for PE (Windows) executables.
+<P>
+
+<DT><SAMP>`-Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]'</SAMP>
+<DD>Modify executable layout.
+<P>
+
+<DT><SAMP>`-Wl,-Bsymbolic'</SAMP>
+<DD>Set DT_SYMBOLIC tag.
+<P>
+
+<DT><SAMP>`-Wl,-(no-)whole-archive'</SAMP>
+<DD>Turn on/off linking of all objects in archives.
+<P>
+
+</DL>
+<P>
+
+Debugger options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-g'</SAMP>
+<DD>Generate run time debug information so that you get clear run time
+error messages: <CODE> test.c:68: in function 'test5()': dereferencing
+invalid pointer</CODE> instead of the laconic <CODE>Segmentation
+fault</CODE>.
+<P>
+
+<DT><SAMP>`-b'</SAMP>
+<DD>Generate additional support code to check
+memory allocations and array/pointer bounds. <SAMP>`-g'</SAMP> is implied. Note
+that the generated code is slower and bigger in this case.
+<P>
+
+Note: <SAMP>`-b'</SAMP> is only available on i386 when using libtcc for the moment.
+</P><P>
+
+<DT><SAMP>`-bt N'</SAMP>
+<DD>Display N callers in stack traces. This is useful with <SAMP>`-g'</SAMP> or
+<SAMP>`-b'</SAMP>.
+<P>
+
+</DL>
+<P>
+
+Misc options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-MD'</SAMP>
+<DD>Generate makefile fragment with dependencies.
+<P>
+
+<DT><SAMP>`-MF depfile'</SAMP>
+<DD>Use <TT>`depfile'</TT> as output for -MD.
+<P>
+
+<DT><SAMP>`-print-search-dirs'</SAMP>
+<DD>Print the configured installation directory and a list of library
+and include directories tcc will search.
+<P>
+
+<DT><SAMP>`-dumpversion'</SAMP>
+<DD>Print version.
+<P>
+
+</DL>
+<P>
+
+Target specific options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-mms-bitfields'</SAMP>
+<DD>Use an algorithm for bitfield alignment consistent with MSVC. Default is
+gcc's algorithm.
+<P>
+
+<DT><SAMP>`-mfloat-abi (ARM only)'</SAMP>
+<DD>Select the float ABI. Possible values: <CODE>softfp</CODE> and <CODE>hard</CODE>
+<P>
+
+<DT><SAMP>`-mno-sse'</SAMP>
+<DD>Do not use sse registers on x86_64
+<P>
+
+<DT><SAMP>`-m32, -m64'</SAMP>
+<DD>Pass command line to the i386/x86_64 cross compiler.
+<P>
+
+</DL>
+<P>
+
+Note: GCC options <SAMP>`-Ox'</SAMP>, <SAMP>`-fx'</SAMP> and <SAMP>`-mx'</SAMP> are
+ignored.
+</P><P>
+
+Environment variables that affect how tcc operates.
+</P><P>
+
+<DL COMPACT>
+
+<DT><SAMP>`CPATH'</SAMP>
+<DD><DT><SAMP>`C_INCLUDE_PATH'</SAMP>
+<DD>A colon-separated list of directories searched for include files,
+directories given with <SAMP>`-I'</SAMP> are searched first.
+<P>
+
+<DT><SAMP>`LIBRARY_PATH'</SAMP>
+<DD>A colon-separated list of directories searched for libraries for the
+<SAMP>`-l'</SAMP> option, directories given with <SAMP>`-L'</SAMP> are searched first.
+<P>
+
+</DL>
+<P>
+
+<A NAME="Clang"></A>
+<HR SIZE="6">
+<A NAME="SEC5"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC4"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC6"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 3. C language support </H1>
+<!--docid::SEC5::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC6"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC7"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.1 ANSI C </H2>
+<!--docid::SEC6::-->
+<P>
+
+TCC implements all the ANSI C standard, including structure bit fields
+and floating point numbers (<CODE>long double</CODE>, <CODE>double</CODE>, and
+<CODE>float</CODE> fully supported).
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC7"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC6"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.2 ISOC99 extensions </H2>
+<!--docid::SEC7::-->
+<P>
+
+TCC implements many features of the new C standard: ISO C99. Currently
+missing items are: complex and imaginary numbers.
+</P><P>
+
+Currently implemented ISOC99 features:
+</P><P>
+
+<UL>
+
+<LI>variable length arrays.
+<P>
+
+<LI>64 bit <CODE>long long</CODE> types are fully supported.
+<P>
+
+<LI>The boolean type <CODE>_Bool</CODE> is supported.
+<P>
+
+<LI><CODE>__func__</CODE> is a string variable containing the current
+function name.
+<P>
+
+<LI>Variadic macros: <CODE>__VA_ARGS__</CODE> can be used for
+ function-like macros:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__)
+</pre></td></tr></table><P>
+
+<CODE>dprintf</CODE> can then be used with a variable number of parameters.
+</P><P>
+
+<LI>Declarations can appear anywhere in a block (as in C++).
+<P>
+
+<LI>Array and struct/union elements can be initialized in any order by
+ using designators:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> struct { int x, y; } st[10] = { [0].x = 1, [0].y = 2 };
+
+ int tab[10] = { 1, 2, [5] = 5, [9] = 9};
+</pre></td></tr></table>
+<LI>Compound initializers are supported:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> int *p = (int []){ 1, 2, 3 };
+</pre></td></tr></table>to initialize a pointer pointing to an initialized array. The same
+works for structures and strings.
+<P>
+
+<LI>Hexadecimal floating point constants are supported:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> double d = 0x1234p10;
+</pre></td></tr></table><P>
+
+is the same as writing
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> double d = 4771840.0;
+</pre></td></tr></table></P><P>
+
+<LI><CODE>inline</CODE> keyword is ignored.
+<P>
+
+<LI><CODE>restrict</CODE> keyword is ignored.
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC8"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC7"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.3 GNU C extensions </H2>
+<!--docid::SEC8::-->
+<P>
+
+TCC implements some GNU C extensions:
+</P><P>
+
+<UL>
+
+<LI>array designators can be used without '=':
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> int a[10] = { [0] 1, [5] 2, 3, 4 };
+</pre></td></tr></table><P>
+
+<LI>Structure field designators can be a label:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> struct { int x, y; } st = { x: 1, y: 1};
+</pre></td></tr></table>instead of
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> struct { int x, y; } st = { .x = 1, .y = 1};
+</pre></td></tr></table><P>
+
+<LI><CODE>\e</CODE> is ASCII character 27.
+<P>
+
+<LI>case ranges : ranges can be used in <CODE>case</CODE>s:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> switch(a) {
+ case 1 <small>...</small> 9:
+ printf("range 1 to 9\n");
+ break;
+ default:
+ printf("unexpected\n");
+ break;
+ }
+</pre></td></tr></table><P>
+
+<A NAME="IDX1"></A>
+<A NAME="IDX2"></A>
+<A NAME="IDX3"></A>
+<A NAME="IDX4"></A>
+<A NAME="IDX5"></A>
+<A NAME="IDX6"></A>
+<A NAME="IDX7"></A>
+<A NAME="IDX8"></A>
+</P><P>
+
+<LI>The keyword <CODE>__attribute__</CODE> is handled to specify variable or
+function attributes. The following attributes are supported:
+<UL>
+
+<LI><CODE>aligned(n)</CODE>: align a variable or a structure field to n bytes
+(must be a power of two).
+<P>
+
+<LI><CODE>packed</CODE>: force alignment of a variable or a structure field to
+ 1.
+<P>
+
+<LI><CODE>section(name)</CODE>: generate function or data in assembly section
+name (name is a string containing the section name) instead of the default
+section.
+<P>
+
+<LI><CODE>unused</CODE>: specify that the variable or the function is unused.
+<P>
+
+<LI><CODE>cdecl</CODE>: use standard C calling convention (default).
+<P>
+
+<LI><CODE>stdcall</CODE>: use Pascal-like calling convention.
+<P>
+
+<LI><CODE>regparm(n)</CODE>: use fast i386 calling convention. <VAR>n</VAR> must be
+between 1 and 3. The first <VAR>n</VAR> function parameters are respectively put in
+registers <CODE>%eax</CODE>, <CODE>%edx</CODE> and <CODE>%ecx</CODE>.
+<P>
+
+<LI><CODE>dllexport</CODE>: export function from dll/executable (win32 only)
+<P>
+
+</UL>
+<P>
+
+Here are some examples:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> int a __attribute__ ((aligned(8), section(".mysection")));
+</pre></td></tr></table></P><P>
+
+align variable <CODE>a</CODE> to 8 bytes and put it in section <CODE>.mysection</CODE>.
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> int my_add(int a, int b) __attribute__ ((section(".mycodesection")))
+ {
+ return a + b;
+ }
+</pre></td></tr></table></P><P>
+
+generate function <CODE>my_add</CODE> in section <CODE>.mycodesection</CODE>.
+</P><P>
+
+<LI>GNU style variadic macros:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> #define dprintf(fmt, args<small>...</small>) printf(fmt, ## args)
+
+ dprintf("no arg\n");
+ dprintf("one arg %d\n", 1);
+</pre></td></tr></table><P>
+
+<LI><CODE>__FUNCTION__</CODE> is interpreted as C99 <CODE>__func__</CODE>
+(so it has not exactly the same semantics as string literal GNUC
+where it is a string literal).
+<P>
+
+<LI>The <CODE>__alignof__</CODE> keyword can be used as <CODE>sizeof</CODE>
+to get the alignment of a type or an expression.
+<P>
+
+<LI>The <CODE>typeof(x)</CODE> returns the type of <CODE>x</CODE>.
+<CODE>x</CODE> is an expression or a type.
+<P>
+
+<LI>Computed gotos: <CODE>&#38;&#38;label</CODE> returns a pointer of type
+<CODE>void *</CODE> on the goto label <CODE>label</CODE>. <CODE>goto *expr</CODE> can be
+used to jump on the pointer resulting from <CODE>expr</CODE>.
+<P>
+
+<LI>Inline assembly with asm instruction:
+<A NAME="IDX9"></A>
+<A NAME="IDX10"></A>
+<A NAME="IDX11"></A>
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>static inline void * my_memcpy(void * to, const void * from, size_t n)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+ "rep ; movsl\n\t"
+ "testb $2,%b4\n\t"
+ "je 1f\n\t"
+ "movsw\n"
+ "1:\ttestb $1,%b4\n\t"
+ "je 2f\n\t"
+ "movsb\n"
+ "2:"
+ : "=&c" (d0), "=&#38;D" (d1), "=&#38;S" (d2)
+ :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+ : "memory");
+return (to);
+}
+</pre></td></tr></table><P>
+
+<A NAME="IDX12"></A>
+TCC includes its own x86 inline assembler with a <CODE>gas</CODE>-like (GNU
+assembler) syntax. No intermediate files are generated. GCC 3.x named
+operands are supported.
+</P><P>
+
+<LI><CODE>__builtin_types_compatible_p()</CODE> and <CODE>__builtin_constant_p()</CODE>
+are supported.
+<P>
+
+<LI><CODE>#pragma pack</CODE> is supported for win32 compatibility.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC9"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.4 TinyCC extensions </H2>
+<!--docid::SEC9::-->
+<P>
+
+<UL>
+
+<LI><CODE>__TINYC__</CODE> is a predefined macro to indicate that you use TCC.
+<P>
+
+<LI><CODE>#!</CODE> at the start of a line is ignored to allow scripting.
+<P>
+
+<LI>Binary digits can be entered (<CODE>0b101</CODE> instead of
+<CODE>5</CODE>).
+<P>
+
+<LI><CODE>__BOUNDS_CHECKING_ON</CODE> is defined if bound checking is activated.
+<P>
+
+</UL>
+<P>
+
+<A NAME="asm"></A>
+<HR SIZE="6">
+<A NAME="SEC10"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC11"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 4. TinyCC Assembler </H1>
+<!--docid::SEC10::-->
+<P>
+
+Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
+assembler supports a gas-like syntax (GNU assembler). You can
+deactivate assembler support if you want a smaller TinyCC executable
+(the C compiler does not rely on the assembler).
+</P><P>
+
+TinyCC Assembler is used to handle files with <TT>`.S'</TT> (C
+preprocessed assembler) and <TT>`.s'</TT> extensions. It is also used to
+handle the GNU inline assembler with the <CODE>asm</CODE> keyword.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC11"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC12"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.1 Syntax </H2>
+<!--docid::SEC11::-->
+<P>
+
+TinyCC Assembler supports most of the gas syntax. The tokens are the
+same as C.
+</P><P>
+
+<UL>
+
+<LI>C and C++ comments are supported.
+<P>
+
+<LI>Identifiers are the same as C, so you cannot use '.' or '$'.
+<P>
+
+<LI>Only 32 bit integer numbers are supported.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC12"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC11"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.2 Expressions </H2>
+<!--docid::SEC12::-->
+<P>
+
+<UL>
+
+<LI>Integers in decimal, octal and hexa are supported.
+<P>
+
+<LI>Unary operators: +, -, ~.
+<P>
+
+<LI>Binary operators in decreasing priority order:
+<P>
+
+<OL>
+<LI>*, /, %
+<LI>&#38;, |, ^
+<LI>+, -
+</OL>
+<P>
+
+<LI>A value is either an absolute number or a label plus an offset.
+All operators accept absolute values except '+' and '-'. '+' or '-' can be
+used to add an offset to a label. '-' supports two labels only if they
+are the same or if they are both defined and in the same section.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC13"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC12"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.3 Labels </H2>
+<!--docid::SEC13::-->
+<P>
+
+<UL>
+
+<LI>All labels are considered as local, except undefined ones.
+<P>
+
+<LI>Numeric labels can be used as local <CODE>gas</CODE>-like labels.
+They can be defined several times in the same source. Use 'b'
+(backward) or 'f' (forward) as suffix to reference them:
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> 1:
+ jmp 1b /* jump to '1' label before */
+ jmp 1f /* jump to '1' label after */
+ 1:
+</pre></td></tr></table></P><P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC14"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.4 Directives </H2>
+<!--docid::SEC14::-->
+<P>
+
+All directives are preceded by a '.'. The following directives are
+supported:
+</P><P>
+
+<UL>
+<LI>.align n[,value]
+<LI>.skip n[,value]
+<LI>.space n[,value]
+<LI>.byte value1[,...]
+<LI>.word value1[,...]
+<LI>.short value1[,...]
+<LI>.int value1[,...]
+<LI>.long value1[,...]
+<LI>.quad immediate_value1[,...]
+<LI>.globl symbol
+<LI>.global symbol
+<LI>.section section
+<LI>.text
+<LI>.data
+<LI>.bss
+<LI>.fill repeat[,size[,value]]
+<LI>.org n
+<LI>.previous
+<LI>.string string[,...]
+<LI>.asciz string[,...]
+<LI>.ascii string[,...]
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC15"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.5 X86 Assembler </H2>
+<!--docid::SEC15::-->
+<P>
+
+All X86 opcodes are supported. Only ATT syntax is supported (source
+then destination operand order). If no size suffix is given, TinyCC
+tries to guess it from the operand sizes.
+</P><P>
+
+Currently, MMX opcodes are supported but not SSE ones.
+</P><P>
+
+<A NAME="linker"></A>
+<HR SIZE="6">
+<A NAME="SEC16"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC17"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 5. TinyCC Linker </H1>
+<!--docid::SEC16::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC17"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC18"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.1 ELF file generation </H2>
+<!--docid::SEC17::-->
+<P>
+
+TCC can directly output relocatable ELF files (object files),
+executable ELF files and dynamic ELF libraries without relying on an
+external linker.
+</P><P>
+
+Dynamic ELF libraries can be output but the C compiler does not generate
+position independent code (PIC). It means that the dynamic library
+code generated by TCC cannot be factorized among processes yet.
+</P><P>
+
+TCC linker eliminates unreferenced object code in libraries. A single pass is
+done on the object and library list, so the order in which object files and
+libraries are specified is important (same constraint as GNU ld). No grouping
+options (<SAMP>`--start-group'</SAMP> and <SAMP>`--end-group'</SAMP>) are supported.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC18"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC17"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.2 ELF file loader </H2>
+<!--docid::SEC18::-->
+<P>
+
+TCC can load ELF object files, archives (.a files) and dynamic
+libraries (.so).
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC19"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC18"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.3 PE-i386 file generation </H2>
+<!--docid::SEC19::-->
+<P>
+
+TCC for Windows supports the native Win32 executable file format (PE-i386). It
+generates EXE files (console and gui) and DLL files.
+</P><P>
+
+For usage on Windows, see also tcc-win32.txt.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC20"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.4 GNU Linker Scripts </H2>
+<!--docid::SEC20::-->
+<P>
+
+Because on many Linux systems some dynamic libraries (such as
+<TT>`/usr/lib/libc.so'</TT>) are in fact GNU ld link scripts (horrible!),
+the TCC linker also supports a subset of GNU ld scripts.
+</P><P>
+
+The <CODE>GROUP</CODE> and <CODE>FILE</CODE> commands are supported. <CODE>OUTPUT_FORMAT</CODE>
+and <CODE>TARGET</CODE> are ignored.
+</P><P>
+
+Example from <TT>`/usr/lib/libc.so'</TT>:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>/* GNU ld script
+ Use the shared library, but some functions are only in
+ the static library, so try that secondarily. */
+GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )
+</pre></td></tr></table></P><P>
+
+<A NAME="Bounds"></A>
+<HR SIZE="6">
+<A NAME="SEC21"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 6. TinyCC Memory and Bound checks </H1>
+<!--docid::SEC21::-->
+<P>
+
+This feature is activated with the <SAMP>`-b'</SAMP> (see section <A HREF="tcc-doc.html#SEC2">2. Command line invocation</A>).
+</P><P>
+
+Note that pointer size is <EM>unchanged</EM> and that code generated
+with bound checks is <EM>fully compatible</EM> with unchecked
+code. When a pointer comes from unchecked code, it is assumed to be
+valid. Even very obscure C code with casts should work correctly.
+</P><P>
+
+For more information about the ideas behind this method, see
+<A HREF="http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html">http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html</A>.
+</P><P>
+
+Here are some examples of caught errors:
+</P><P>
+
+<DL COMPACT>
+
+<DT>Invalid range with standard string function:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
+ char tab[10];
+ memset(tab, 0, 11);
+}
+</pre></td></tr></table><P>
+
+<DT>Out of bounds-error in global or local arrays:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
+ int tab[10];
+ for(i=0;i&#60;11;i++) {
+ sum += tab[i];
+ }
+}
+</pre></td></tr></table><P>
+
+<DT>Out of bounds-error in malloc'ed data:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
+ int *tab;
+ tab = malloc(20 * sizeof(int));
+ for(i=0;i&#60;21;i++) {
+ sum += tab4[i];
+ }
+ free(tab);
+}
+</pre></td></tr></table><P>
+
+<DT>Access of freed memory:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
+ int *tab;
+ tab = malloc(20 * sizeof(int));
+ free(tab);
+ for(i=0;i&#60;20;i++) {
+ sum += tab4[i];
+ }
+}
+</pre></td></tr></table><P>
+
+<DT>Double free:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
+ int *tab;
+ tab = malloc(20 * sizeof(int));
+ free(tab);
+ free(tab);
+}
+</pre></td></tr></table><P>
+
+</DL>
+<P>
+
+<A NAME="Libtcc"></A>
+<HR SIZE="6">
+<A NAME="SEC22"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 7. The <CODE>libtcc</CODE> library </H1>
+<!--docid::SEC22::-->
+<P>
+
+The <CODE>libtcc</CODE> library enables you to use TCC as a backend for
+dynamic code generation.
+</P><P>
+
+Read the <TT>`libtcc.h'</TT> to have an overview of the API. Read
+<TT>`libtcc_test.c'</TT> to have a very simple example.
+</P><P>
+
+The idea consists in giving a C string containing the program you want
+to compile directly to <CODE>libtcc</CODE>. Then you can access to any global
+symbol (function or variable) defined.
+</P><P>
+
+<A NAME="devel"></A>
+<HR SIZE="6">
+<A NAME="SEC23"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC24"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 8. Developer's guide </H1>
+<!--docid::SEC23::-->
+<P>
+
+This chapter gives some hints to understand how TCC works. You can skip
+it if you do not intend to modify the TCC code.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC24"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC25"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.1 File reading </H2>
+<!--docid::SEC24::-->
+<P>
+
+The <CODE>BufferedFile</CODE> structure contains the context needed to read a
+file, including the current line number. <CODE>tcc_open()</CODE> opens a new
+file and <CODE>tcc_close()</CODE> closes it. <CODE>inp()</CODE> returns the next
+character.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC25"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC24"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.2 Lexer </H2>
+<!--docid::SEC25::-->
+<P>
+
+<CODE>next()</CODE> reads the next token in the current
+file. <CODE>next_nomacro()</CODE> reads the next token without macro
+expansion.
+</P><P>
+
+<CODE>tok</CODE> contains the current token (see <CODE>TOK_xxx</CODE>)
+constants. Identifiers and keywords are also keywords. <CODE>tokc</CODE>
+contains additional infos about the token (for example a constant value
+if number or string token).
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC26"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC25"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.3 Parser </H2>
+<!--docid::SEC26::-->
+<P>
+
+The parser is hardcoded (yacc is not necessary). It does only one pass,
+except:
+</P><P>
+
+<UL>
+
+<LI>For initialized arrays with unknown size, a first pass
+is done to count the number of elements.
+<P>
+
+<LI>For architectures where arguments are evaluated in
+reverse order, a first pass is done to reverse the argument order.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC27"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.4 Types </H2>
+<!--docid::SEC27::-->
+<P>
+
+The types are stored in a single 'int' variable. It was chosen in the
+first stages of development when tcc was much simpler. Now, it may not
+be the best solution.
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_INT 0 /* integer type */
+#define VT_BYTE 1 /* signed byte type */
+#define VT_SHORT 2 /* short type */
+#define VT_VOID 3 /* void type */
+#define VT_PTR 4 /* pointer */
+#define VT_ENUM 5 /* enum definition */
+#define VT_FUNC 6 /* function type */
+#define VT_STRUCT 7 /* struct/union definition */
+#define VT_FLOAT 8 /* IEEE float */
+#define VT_DOUBLE 9 /* IEEE double */
+#define VT_LDOUBLE 10 /* IEEE long double */
+#define VT_BOOL 11 /* ISOC99 boolean type */
+#define VT_LLONG 12 /* 64 bit integer */
+#define VT_LONG 13 /* long integer (NEVER USED as type, only
+ during parsing) */
+#define VT_BTYPE 0x000f /* mask for basic type */
+#define VT_UNSIGNED 0x0010 /* unsigned type */
+#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
+#define VT_VLA 0x20000 /* VLA type (also has VT_PTR and VT_ARRAY) */
+#define VT_BITFIELD 0x0040 /* bitfield modifier */
+#define VT_CONSTANT 0x0800 /* const modifier */
+#define VT_VOLATILE 0x1000 /* volatile modifier */
+#define VT_DEFSIGN 0x2000 /* signed type */
+
+#define VT_STRUCT_SHIFT 18 /* structure/enum name shift (14 bits left) */
+</pre></td></tr></table></P><P>
+
+When a reference to another type is needed (for pointers, functions and
+structures), the <CODE>32 - VT_STRUCT_SHIFT</CODE> high order bits are used to
+store an identifier reference.
+</P><P>
+
+The <CODE>VT_UNSIGNED</CODE> flag can be set for chars, shorts, ints and long
+longs.
+</P><P>
+
+Arrays are considered as pointers <CODE>VT_PTR</CODE> with the flag
+<CODE>VT_ARRAY</CODE> set. Variable length arrays are considered as special
+arrays and have flag <CODE>VT_VLA</CODE> set instead of <CODE>VT_ARRAY</CODE>.
+</P><P>
+
+The <CODE>VT_BITFIELD</CODE> flag can be set for chars, shorts, ints and long
+longs. If it is set, then the bitfield position is stored from bits
+VT_STRUCT_SHIFT to VT_STRUCT_SHIFT + 5 and the bit field size is stored
+from bits VT_STRUCT_SHIFT + 6 to VT_STRUCT_SHIFT + 11.
+</P><P>
+
+<CODE>VT_LONG</CODE> is never used except during parsing.
+</P><P>
+
+During parsing, the storage of an object is also stored in the type
+integer:
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_EXTERN 0x00000080 /* extern definition */
+#define VT_STATIC 0x00000100 /* static variable */
+#define VT_TYPEDEF 0x00000200 /* typedef definition */
+#define VT_INLINE 0x00000400 /* inline definition */
+#define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */
+#define VT_EXPORT 0x00008000 /* win32: data exported from dll */
+#define VT_WEAK 0x00010000 /* win32: data exported from dll */
+</pre></td></tr></table></P><P>
+
+<HR SIZE="6">
+<A NAME="SEC28"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.5 Symbols </H2>
+<!--docid::SEC28::-->
+<P>
+
+All symbols are stored in hashed symbol stacks. Each symbol stack
+contains <CODE>Sym</CODE> structures.
+</P><P>
+
+<CODE>Sym.v</CODE> contains the symbol name (remember
+an identifier is also a token, so a string is never necessary to store
+it). <CODE>Sym.t</CODE> gives the type of the symbol. <CODE>Sym.r</CODE> is usually
+the register in which the corresponding variable is stored. <CODE>Sym.c</CODE> is
+usually a constant associated to the symbol like its address for normal
+symbols, and the number of entries for symbols representing arrays.
+Variable length array types use <CODE>Sym.c</CODE> as a location on the stack
+which holds the runtime sizeof for the type.
+</P><P>
+
+Four main symbol stacks are defined:
+</P><P>
+
+<DL COMPACT>
+
+<DT><CODE>define_stack</CODE>
+<DD>for the macros (<CODE>#define</CODE>s).
+<P>
+
+<DT><CODE>global_stack</CODE>
+<DD>for the global variables, functions and types.
+<P>
+
+<DT><CODE>local_stack</CODE>
+<DD>for the local variables, functions and types.
+<P>
+
+<DT><CODE>global_label_stack</CODE>
+<DD>for the local labels (for <CODE>goto</CODE>).
+<P>
+
+<DT><CODE>label_stack</CODE>
+<DD>for GCC block local labels (see the <CODE>__label__</CODE> keyword).
+<P>
+
+</DL>
+<P>
+
+<CODE>sym_push()</CODE> is used to add a new symbol in the local symbol
+stack. If no local symbol stack is active, it is added in the global
+symbol stack.
+</P><P>
+
+<CODE>sym_pop(st,b)</CODE> pops symbols from the symbol stack <VAR>st</VAR> until
+the symbol <VAR>b</VAR> is on the top of stack. If <VAR>b</VAR> is NULL, the stack
+is emptied.
+</P><P>
+
+<CODE>sym_find(v)</CODE> return the symbol associated to the identifier
+<VAR>v</VAR>. The local stack is searched first from top to bottom, then the
+global stack.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC29"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.6 Sections </H2>
+<!--docid::SEC29::-->
+<P>
+
+The generated code and data are written in sections. The structure
+<CODE>Section</CODE> contains all the necessary information for a given
+section. <CODE>new_section()</CODE> creates a new section. ELF file semantics
+is assumed for each section.
+</P><P>
+
+The following sections are predefined:
+</P><P>
+
+<DL COMPACT>
+
+<DT><CODE>text_section</CODE>
+<DD>is the section containing the generated code. <VAR>ind</VAR> contains the
+current position in the code section.
+<P>
+
+<DT><CODE>data_section</CODE>
+<DD>contains initialized data
+<P>
+
+<DT><CODE>bss_section</CODE>
+<DD>contains uninitialized data
+<P>
+
+<DT><CODE>bounds_section</CODE>
+<DD><DT><CODE>lbounds_section</CODE>
+<DD>are used when bound checking is activated
+<P>
+
+<DT><CODE>stab_section</CODE>
+<DD><DT><CODE>stabstr_section</CODE>
+<DD>are used when debugging is active to store debug information
+<P>
+
+<DT><CODE>symtab_section</CODE>
+<DD><DT><CODE>strtab_section</CODE>
+<DD>contain the exported symbols (currently only used for debugging).
+<P>
+
+</DL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC30"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC31"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.7 Code generation </H2>
+<!--docid::SEC30::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC31"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC32"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.1 Introduction </H3>
+<!--docid::SEC31::-->
+<P>
+
+The TCC code generator directly generates linked binary code in one
+pass. It is rather unusual these days (see gcc for example which
+generates text assembly), but it can be very fast and surprisingly
+little complicated.
+</P><P>
+
+The TCC code generator is register based. Optimization is only done at
+the expression level. No intermediate representation of expression is
+kept except the current values stored in the <EM>value stack</EM>.
+</P><P>
+
+On x86, three temporary registers are used. When more registers are
+needed, one register is spilled into a new temporary variable on the stack.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC32"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC31"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.2 The value stack </H3>
+<!--docid::SEC32::-->
+<P>
+
+When an expression is parsed, its value is pushed on the value stack
+(<VAR>vstack</VAR>). The top of the value stack is <VAR>vtop</VAR>. Each value
+stack entry is the structure <CODE>SValue</CODE>.
+</P><P>
+
+<CODE>SValue.t</CODE> is the type. <CODE>SValue.r</CODE> indicates how the value is
+currently stored in the generated code. It is usually a CPU register
+index (<CODE>REG_xxx</CODE> constants), but additional values and flags are
+defined:
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_CONST 0x00f0
+#define VT_LLOCAL 0x00f1
+#define VT_LOCAL 0x00f2
+#define VT_CMP 0x00f3
+#define VT_JMP 0x00f4
+#define VT_JMPI 0x00f5
+#define VT_LVAL 0x0100
+#define VT_SYM 0x0200
+#define VT_MUSTCAST 0x0400
+#define VT_MUSTBOUND 0x0800
+#define VT_BOUNDED 0x8000
+#define VT_LVAL_BYTE 0x1000
+#define VT_LVAL_SHORT 0x2000
+#define VT_LVAL_UNSIGNED 0x4000
+#define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
+</pre></td></tr></table></P><P>
+
+<DL COMPACT>
+
+<DT><CODE>VT_CONST</CODE>
+<DD>indicates that the value is a constant. It is stored in the union
+<CODE>SValue.c</CODE>, depending on its type.
+<P>
+
+<DT><CODE>VT_LOCAL</CODE>
+<DD>indicates a local variable pointer at offset <CODE>SValue.c.i</CODE> in the
+stack.
+<P>
+
+<DT><CODE>VT_CMP</CODE>
+<DD>indicates that the value is actually stored in the CPU flags (i.e. the
+value is the consequence of a test). The value is either 0 or 1. The
+actual CPU flags used is indicated in <CODE>SValue.c.i</CODE>.
+<P>
+
+If any code is generated which destroys the CPU flags, this value MUST be
+put in a normal register.
+</P><P>
+
+<DT><CODE>VT_JMP</CODE>
+<DD><DT><CODE>VT_JMPI</CODE>
+<DD>indicates that the value is the consequence of a conditional jump. For VT_JMP,
+it is 1 if the jump is taken, 0 otherwise. For VT_JMPI it is inverted.
+<P>
+
+These values are used to compile the <CODE>||</CODE> and <CODE>&#38;&#38;</CODE> logical
+operators.
+</P><P>
+
+If any code is generated, this value MUST be put in a normal
+register. Otherwise, the generated code won't be executed if the jump is
+taken.
+</P><P>
+
+<DT><CODE>VT_LVAL</CODE>
+<DD>is a flag indicating that the value is actually an lvalue (left value of
+an assignment). It means that the value stored is actually a pointer to
+the wanted value.
+<P>
+
+Understanding the use <CODE>VT_LVAL</CODE> is very important if you want to
+understand how TCC works.
+</P><P>
+
+<DT><CODE>VT_LVAL_BYTE</CODE>
+<DD><DT><CODE>VT_LVAL_SHORT</CODE>
+<DD><DT><CODE>VT_LVAL_UNSIGNED</CODE>
+<DD>if the lvalue has an integer type, then these flags give its real
+type. The type alone is not enough in case of cast optimisations.
+<P>
+
+<DT><CODE>VT_LLOCAL</CODE>
+<DD>is a saved lvalue on the stack. <CODE>VT_LVAL</CODE> must also be set with
+<CODE>VT_LLOCAL</CODE>. <CODE>VT_LLOCAL</CODE> can arise when a <CODE>VT_LVAL</CODE> in
+a register has to be saved to the stack, or it can come from an
+architecture-specific calling convention.
+<P>
+
+<DT><CODE>VT_MUSTCAST</CODE>
+<DD>indicates that a cast to the value type must be performed if the value
+is used (lazy casting).
+<P>
+
+<DT><CODE>VT_SYM</CODE>
+<DD>indicates that the symbol <CODE>SValue.sym</CODE> must be added to the constant.
+<P>
+
+<DT><CODE>VT_MUSTBOUND</CODE>
+<DD><DT><CODE>VT_BOUNDED</CODE>
+<DD>are only used for optional bound checking.
+<P>
+
+</DL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC33"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC32"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.3 Manipulating the value stack </H3>
+<!--docid::SEC33::-->
+<P>
+
+<CODE>vsetc()</CODE> and <CODE>vset()</CODE> pushes a new value on the value
+stack. If the previous <VAR>vtop</VAR> was stored in a very unsafe place(for
+example in the CPU flags), then some code is generated to put the
+previous <VAR>vtop</VAR> in a safe storage.
+</P><P>
+
+<CODE>vpop()</CODE> pops <VAR>vtop</VAR>. In some cases, it also generates cleanup
+code (for example if stacked floating point registers are used as on
+x86).
+</P><P>
+
+The <CODE>gv(rc)</CODE> function generates code to evaluate <VAR>vtop</VAR> (the
+top value of the stack) into registers. <VAR>rc</VAR> selects in which
+register class the value should be put. <CODE>gv()</CODE> is the <EM>most
+important function</EM> of the code generator.
+</P><P>
+
+<CODE>gv2()</CODE> is the same as <CODE>gv()</CODE> but for the top two stack
+entries.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC34"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.4 CPU dependent code generation </H3>
+<!--docid::SEC34::-->
+See the <TT>`i386-gen.c'</TT> file to have an example.
+<P>
+
+<DL COMPACT>
+
+<DT><CODE>load()</CODE>
+<DD>must generate the code needed to load a stack value into a register.
+<P>
+
+<DT><CODE>store()</CODE>
+<DD>must generate the code needed to store a register into a stack value
+lvalue.
+<P>
+
+<DT><CODE>gfunc_start()</CODE>
+<DD><DT><CODE>gfunc_param()</CODE>
+<DD><DT><CODE>gfunc_call()</CODE>
+<DD>should generate a function call
+<P>
+
+<DT><CODE>gfunc_prolog()</CODE>
+<DD><DT><CODE>gfunc_epilog()</CODE>
+<DD>should generate a function prolog/epilog.
+<P>
+
+<DT><CODE>gen_opi(op)</CODE>
+<DD>must generate the binary integer operation <VAR>op</VAR> on the two top
+entries of the stack which are guaranteed to contain integer types.
+<P>
+
+The result value should be put on the stack.
+</P><P>
+
+<DT><CODE>gen_opf(op)</CODE>
+<DD>same as <CODE>gen_opi()</CODE> for floating point operations. The two top
+entries of the stack are guaranteed to contain floating point values of
+same types.
+<P>
+
+<DT><CODE>gen_cvt_itof()</CODE>
+<DD>integer to floating point conversion.
+<P>
+
+<DT><CODE>gen_cvt_ftoi()</CODE>
+<DD>floating point to integer conversion.
+<P>
+
+<DT><CODE>gen_cvt_ftof()</CODE>
+<DD>floating point to floating point of different size conversion.
+<P>
+
+<DT><CODE>gen_bounded_ptr_add()</CODE>
+<DD><DT><CODE>gen_bounded_ptr_deref()</CODE>
+<DD>are only used for bounds checking.
+<P>
+
+</DL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC35"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.8 Optimizations done </H2>
+<!--docid::SEC35::-->
+Constant propagation is done for all operations. Multiplications and
+divisions are optimized to shifts when appropriate. Comparison
+operators are optimized by maintaining a special cache for the
+processor flags. &#38;&#38;, || and ! are optimized by maintaining a special
+'jump target' value. No other jump optimization is currently performed
+because it would require to store the code in a more abstract fashion.
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC36"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> Concept Index </H1>
+<!--docid::SEC36::-->
+<table><tr><th valign=top>Jump to: &nbsp; </th><td><A HREF="tcc-doc.html#cp__" style="text-decoration:none"><b>_</b></A>
+ &nbsp;
+<BR>
+<A HREF="tcc-doc.html#cp_A" style="text-decoration:none"><b>A</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_B" style="text-decoration:none"><b>B</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_C" style="text-decoration:none"><b>C</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_D" style="text-decoration:none"><b>D</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_E" style="text-decoration:none"><b>E</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_F" style="text-decoration:none"><b>F</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_G" style="text-decoration:none"><b>G</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_I" style="text-decoration:none"><b>I</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_J" style="text-decoration:none"><b>J</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_L" style="text-decoration:none"><b>L</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_M" style="text-decoration:none"><b>M</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_O" style="text-decoration:none"><b>O</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_P" style="text-decoration:none"><b>P</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_Q" style="text-decoration:none"><b>Q</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_R" style="text-decoration:none"><b>R</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_S" style="text-decoration:none"><b>S</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_T" style="text-decoration:none"><b>T</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_U" style="text-decoration:none"><b>U</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_V" style="text-decoration:none"><b>V</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_W" style="text-decoration:none"><b>W</b></A>
+ &nbsp;
+</td></tr></table><br><P></P>
+<TABLE border=0>
+<TR><TD></TD><TH ALIGN=LEFT>Index Entry</TH><TH ALIGN=LEFT> Section</TH></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp__"></A>_</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX11">__asm__</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_A"></A>A</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">align directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX1">aligned attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">ascii directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">asciz directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC15">assembler</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC15">4.5 X86 Assembler</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">assembler directives</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX10">assembly, inline</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_B"></A>B</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">bound checks</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">bss directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">byte directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_C"></A>C</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">caching processor flags</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX5">cdecl attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC30">code generation</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC30">8.7 Code generation</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">comparison operators</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">constant propagation</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC34">CPU dependent</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC34">8.7.4 CPU dependent code generation</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_D"></A>D</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">data directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">directives, assembler</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX8">dllexport attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_E"></A>E</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC17">ELF</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC17">5.1 ELF file generation</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_F"></A>F</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">FILE, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">fill directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">flags, caching</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_G"></A>G</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX12">gas</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">global directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">globl directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">GROUP, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_I"></A>I</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX9">inline assembly</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">int directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_J"></A>J</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">jump optimization</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_L"></A>L</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC16">linker</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">linker scripts</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">long directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_M"></A>M</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">memory checks</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_O"></A>O</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">optimizations</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">org directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">OUTPUT_FORMAT, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_P"></A>P</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX2">packed attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC19">PE-i386</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC19">5.3 PE-i386 file generation</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">previous directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_Q"></A>Q</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">quad directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_R"></A>R</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX7">regparm attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_S"></A>S</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">scripts, linker</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX3">section attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">section directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">short directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">skip directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">space directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX6">stdcall attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">strength reduction</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">string directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_T"></A>T</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">TARGET, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">text directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_U"></A>U</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX4">unused attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_V"></A>V</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC33">value stack</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC33">8.7.3 Manipulating the value stack</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC32">value stack, introduction</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC32">8.7.2 The value stack</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_W"></A>W</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">word directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+</TABLE><P></P><table><tr><th valign=top>Jump to: &nbsp; </th><td><A HREF="tcc-doc.html#cp__" style="text-decoration:none"><b>_</b></A>
+ &nbsp;
+<BR>
+<A HREF="tcc-doc.html#cp_A" style="text-decoration:none"><b>A</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_B" style="text-decoration:none"><b>B</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_C" style="text-decoration:none"><b>C</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_D" style="text-decoration:none"><b>D</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_E" style="text-decoration:none"><b>E</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_F" style="text-decoration:none"><b>F</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_G" style="text-decoration:none"><b>G</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_I" style="text-decoration:none"><b>I</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_J" style="text-decoration:none"><b>J</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_L" style="text-decoration:none"><b>L</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_M" style="text-decoration:none"><b>M</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_O" style="text-decoration:none"><b>O</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_P" style="text-decoration:none"><b>P</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_Q" style="text-decoration:none"><b>Q</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_R" style="text-decoration:none"><b>R</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_S" style="text-decoration:none"><b>S</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_T" style="text-decoration:none"><b>T</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_U" style="text-decoration:none"><b>U</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_V" style="text-decoration:none"><b>V</b></A>
+ &nbsp;
+<A HREF="tcc-doc.html#cp_W" style="text-decoration:none"><b>W</b></A>
+ &nbsp;
+</td></tr></table><br><P>
+
+<HR SIZE="6">
+<A NAME="SEC_Contents"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>Table of Contents</H1>
+<UL>
+<A NAME="TOC1" HREF="tcc-doc.html#SEC1">1. Introduction</A>
+<BR>
+<A NAME="TOC2" HREF="tcc-doc.html#SEC2">2. Command line invocation</A>
+<BR>
+<UL>
+<A NAME="TOC3" HREF="tcc-doc.html#SEC3">2.1 Quick start</A>
+<BR>
+<A NAME="TOC4" HREF="tcc-doc.html#SEC4">2.2 Option summary</A>
+<BR>
+</UL>
+<A NAME="TOC5" HREF="tcc-doc.html#SEC5">3. C language support</A>
+<BR>
+<UL>
+<A NAME="TOC6" HREF="tcc-doc.html#SEC6">3.1 ANSI C</A>
+<BR>
+<A NAME="TOC7" HREF="tcc-doc.html#SEC7">3.2 ISOC99 extensions</A>
+<BR>
+<A NAME="TOC8" HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A>
+<BR>
+<A NAME="TOC9" HREF="tcc-doc.html#SEC9">3.4 TinyCC extensions</A>
+<BR>
+</UL>
+<A NAME="TOC10" HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A>
+<BR>
+<UL>
+<A NAME="TOC11" HREF="tcc-doc.html#SEC11">4.1 Syntax</A>
+<BR>
+<A NAME="TOC12" HREF="tcc-doc.html#SEC12">4.2 Expressions</A>
+<BR>
+<A NAME="TOC13" HREF="tcc-doc.html#SEC13">4.3 Labels</A>
+<BR>
+<A NAME="TOC14" HREF="tcc-doc.html#SEC14">4.4 Directives</A>
+<BR>
+<A NAME="TOC15" HREF="tcc-doc.html#SEC15">4.5 X86 Assembler</A>
+<BR>
+</UL>
+<A NAME="TOC16" HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A>
+<BR>
+<UL>
+<A NAME="TOC17" HREF="tcc-doc.html#SEC17">5.1 ELF file generation</A>
+<BR>
+<A NAME="TOC18" HREF="tcc-doc.html#SEC18">5.2 ELF file loader</A>
+<BR>
+<A NAME="TOC19" HREF="tcc-doc.html#SEC19">5.3 PE-i386 file generation</A>
+<BR>
+<A NAME="TOC20" HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A>
+<BR>
+</UL>
+<A NAME="TOC21" HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>
+<BR>
+<A NAME="TOC22" HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>
+<BR>
+<A NAME="TOC23" HREF="tcc-doc.html#SEC23">8. Developer's guide</A>
+<BR>
+<UL>
+<A NAME="TOC24" HREF="tcc-doc.html#SEC24">8.1 File reading</A>
+<BR>
+<A NAME="TOC25" HREF="tcc-doc.html#SEC25">8.2 Lexer</A>
+<BR>
+<A NAME="TOC26" HREF="tcc-doc.html#SEC26">8.3 Parser</A>
+<BR>
+<A NAME="TOC27" HREF="tcc-doc.html#SEC27">8.4 Types</A>
+<BR>
+<A NAME="TOC28" HREF="tcc-doc.html#SEC28">8.5 Symbols</A>
+<BR>
+<A NAME="TOC29" HREF="tcc-doc.html#SEC29">8.6 Sections</A>
+<BR>
+<A NAME="TOC30" HREF="tcc-doc.html#SEC30">8.7 Code generation</A>
+<BR>
+<UL>
+<A NAME="TOC31" HREF="tcc-doc.html#SEC31">8.7.1 Introduction</A>
+<BR>
+<A NAME="TOC32" HREF="tcc-doc.html#SEC32">8.7.2 The value stack</A>
+<BR>
+<A NAME="TOC33" HREF="tcc-doc.html#SEC33">8.7.3 Manipulating the value stack</A>
+<BR>
+<A NAME="TOC34" HREF="tcc-doc.html#SEC34">8.7.4 CPU dependent code generation</A>
+<BR>
+</UL>
+<A NAME="TOC35" HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A>
+<BR>
+</UL>
+<A NAME="TOC36" HREF="tcc-doc.html#SEC36">Concept Index</A>
+<BR>
+</UL>
+<HR SIZE=1>
+<A NAME="SEC_OVERVIEW"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>Short Table of Contents</H1>
+<BLOCKQUOTE>
+<A NAME="TOC1" HREF="tcc-doc.html#SEC1">1. Introduction</A>
+<BR>
+<A NAME="TOC2" HREF="tcc-doc.html#SEC2">2. Command line invocation</A>
+<BR>
+<A NAME="TOC5" HREF="tcc-doc.html#SEC5">3. C language support</A>
+<BR>
+<A NAME="TOC10" HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A>
+<BR>
+<A NAME="TOC16" HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A>
+<BR>
+<A NAME="TOC21" HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>
+<BR>
+<A NAME="TOC22" HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>
+<BR>
+<A NAME="TOC23" HREF="tcc-doc.html#SEC23">8. Developer's guide</A>
+<BR>
+<A NAME="TOC36" HREF="tcc-doc.html#SEC36">Concept Index</A>
+<BR>
+
+</BLOCKQUOTE>
+<HR SIZE=1>
+<A NAME="SEC_About"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>About this document</H1>
+This document was generated on <I>December, 17 2017</I>
+using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
+"><I>texi2html</I></A>
+<P></P>
+The buttons in the navigation panels have the following meaning:
+<P></P>
+<table border = "1">
+<TR>
+<TH> Button </TH>
+<TH> Name </TH>
+<TH> Go to </TH>
+<TH> From 1.2.3 go to</TH>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &lt; ] </TD>
+<TD ALIGN="CENTER">
+Back
+</TD>
+<TD>
+previous section in reading order
+</TD>
+<TD>
+1.2.2
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &gt; ] </TD>
+<TD ALIGN="CENTER">
+Forward
+</TD>
+<TD>
+next section in reading order
+</TD>
+<TD>
+1.2.4
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &lt;&lt; ] </TD>
+<TD ALIGN="CENTER">
+FastBack
+</TD>
+<TD>
+previous or up-and-previous section
+</TD>
+<TD>
+1.1
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ Up ] </TD>
+<TD ALIGN="CENTER">
+Up
+</TD>
+<TD>
+up section
+</TD>
+<TD>
+1.2
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &gt;&gt; ] </TD>
+<TD ALIGN="CENTER">
+FastForward
+</TD>
+<TD>
+next or up-and-next section
+</TD>
+<TD>
+1.3
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Top] </TD>
+<TD ALIGN="CENTER">
+Top
+</TD>
+<TD>
+cover (top) of document
+</TD>
+<TD>
+ &nbsp;
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Contents] </TD>
+<TD ALIGN="CENTER">
+Contents
+</TD>
+<TD>
+table of contents
+</TD>
+<TD>
+ &nbsp;
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Index] </TD>
+<TD ALIGN="CENTER">
+Index
+</TD>
+<TD>
+concept index
+</TD>
+<TD>
+ &nbsp;
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ ? ] </TD>
+<TD ALIGN="CENTER">
+About
+</TD>
+<TD>
+this page
+</TD>
+<TD>
+ &nbsp;
+</TD>
+</TR>
+</TABLE>
+<P></P>
+where the <STRONG> Example </STRONG> assumes that the current position
+is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of
+the following structure:
+<UL>
+<LI> 1. Section One </LI>
+<UL>
+<LI>1.1 Subsection One-One</LI>
+<UL>
+<LI> ... </LI>
+</UL>
+<LI>1.2 Subsection One-Two</LI>
+<UL>
+<LI>1.2.1 Subsubsection One-Two-One
+</LI><LI>1.2.2 Subsubsection One-Two-Two
+</LI><LI>1.2.3 Subsubsection One-Two-Three &nbsp; &nbsp; <STRONG>
+&lt;== Current Position </STRONG>
+</LI><LI>1.2.4 Subsubsection One-Two-Four
+</LI></UL>
+<LI>1.3 Subsection One-Three</LI>
+<UL>
+<LI> ... </LI>
+</UL>
+<LI>1.4 Subsection One-Four</LI>
+</UL>
+</UL>
+
+<HR SIZE=1>
+<BR>
+<FONT SIZE="-1">
+This document was generated
+on <I>December, 17 2017</I>
+using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
+"><I>texi2html</I></A>
+
+</BODY>
+</HTML>
diff --git a/tcc-doc.texi b/tcc-doc.texi
new file mode 100644
index 0000000..5e718a2
--- /dev/null
+++ b/tcc-doc.texi
@@ -0,0 +1,1326 @@
+\input texinfo @c -*- texinfo -*-
+@c %**start of header
+@setfilename tcc-doc.info
+@settitle Tiny C Compiler Reference Documentation
+@dircategory Software development
+@direntry
+* TCC: (tcc-doc). The Tiny C Compiler.
+@end direntry
+@c %**end of header
+
+@include config.texi
+
+@iftex
+@titlepage
+@afourpaper
+@sp 7
+@center @titlefont{Tiny C Compiler Reference Documentation}
+@sp 3
+@end titlepage
+@headings double
+@end iftex
+
+@contents
+
+@node Top, Introduction, (dir), (dir)
+@top Tiny C Compiler Reference Documentation
+
+This manual documents version @value{VERSION} of the Tiny C Compiler.
+
+@menu
+* Introduction:: Introduction to tcc.
+* Invoke:: Invocation of tcc (command line, options).
+* Clang:: ANSI C and extensions.
+* asm:: Assembler syntax.
+* linker:: Output file generation and supported targets.
+* Bounds:: Automatic bounds-checking of C code.
+* Libtcc:: The libtcc library.
+* devel:: Guide for Developers.
+@end menu
+
+
+@node Introduction
+@chapter Introduction
+
+TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C
+compilers, it is meant to be self-relying: you do not need an
+external assembler or linker because TCC does that for you.
+
+TCC compiles so @emph{fast} that even for big projects @code{Makefile}s may
+not be necessary.
+
+TCC not only supports ANSI C, but also most of the new ISO C99
+standard and many GNUC extensions including inline assembly.
+
+TCC can also be used to make @emph{C scripts}, i.e. pieces of C source
+that you run as a Perl or Python script. Compilation is so fast that
+your script will be as fast as if it was an executable.
+
+TCC can also automatically generate memory and bound checks
+(@pxref{Bounds}) while allowing all C pointers operations. TCC can do
+these checks even if non patched libraries are used.
+
+With @code{libtcc}, you can use TCC as a backend for dynamic code
+generation (@pxref{Libtcc}).
+
+TCC mainly supports the i386 target on Linux and Windows. There are alpha
+ports for the ARM (@code{arm-tcc}) and the TMS320C67xx targets
+(@code{c67-tcc}). More information about the ARM port is available at
+@url{http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html}.
+
+For usage on Windows, see also @url{tcc-win32.txt}.
+
+@node Invoke
+@chapter Command line invocation
+
+@section Quick start
+
+@example
+@c man begin SYNOPSIS
+usage: tcc [options] [@var{infile1} @var{infile2}@dots{}] [@option{-run} @var{infile} @var{args}@dots{}]
+@c man end
+@end example
+
+@noindent
+@c man begin DESCRIPTION
+TCC options are a very much like gcc options. The main difference is that TCC
+can also execute directly the resulting program and give it runtime
+arguments.
+
+Here are some examples to understand the logic:
+
+@table @code
+@item @samp{tcc -run a.c}
+Compile @file{a.c} and execute it directly
+
+@item @samp{tcc -run a.c arg1}
+Compile a.c and execute it directly. arg1 is given as first argument to
+the @code{main()} of a.c.
+
+@item @samp{tcc a.c -run b.c arg1}
+Compile @file{a.c} and @file{b.c}, link them together and execute them. arg1 is given
+as first argument to the @code{main()} of the resulting program.
+@ignore
+Because multiple C files are specified, @option{--} are necessary to clearly
+separate the program arguments from the TCC options.
+@end ignore
+
+@item @samp{tcc -o myprog a.c b.c}
+Compile @file{a.c} and @file{b.c}, link them and generate the executable @file{myprog}.
+
+@item @samp{tcc -o myprog a.o b.o}
+link @file{a.o} and @file{b.o} together and generate the executable @file{myprog}.
+
+@item @samp{tcc -c a.c}
+Compile @file{a.c} and generate object file @file{a.o}.
+
+@item @samp{tcc -c asmfile.S}
+Preprocess with C preprocess and assemble @file{asmfile.S} and generate
+object file @file{asmfile.o}.
+
+@item @samp{tcc -c asmfile.s}
+Assemble (but not preprocess) @file{asmfile.s} and generate object file
+@file{asmfile.o}.
+
+@item @samp{tcc -r -o ab.o a.c b.c}
+Compile @file{a.c} and @file{b.c}, link them together and generate the object file @file{ab.o}.
+
+@end table
+
+Scripting:
+
+TCC can be invoked from @emph{scripts}, just as shell scripts. You just
+need to add @code{#!/usr/local/bin/tcc -run} at the start of your C source:
+
+@example
+#!/usr/local/bin/tcc -run
+#include <stdio.h>
+
+int main()
+@{
+ printf("Hello World\n");
+ return 0;
+@}
+@end example
+
+TCC can read C source code from @emph{standard input} when @option{-} is used in
+place of @option{infile}. Example:
+
+@example
+echo 'main()@{puts("hello");@}' | tcc -run -
+@end example
+@c man end
+
+@section Option summary
+
+General Options:
+
+@c man begin OPTIONS
+@table @option
+@item -c
+Generate an object file.
+
+@item -o outfile
+Put object file, executable, or dll into output file @file{outfile}.
+
+@item -run source [args...]
+Compile file @var{source} and run it with the command line arguments
+@var{args}. In order to be able to give more than one argument to a
+script, several TCC options can be given @emph{after} the
+@option{-run} option, separated by spaces:
+@example
+tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
+@end example
+In a script, it gives the following header:
+@example
+#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
+@end example
+
+@item -v
+Display TCC version.
+
+@item -vv
+Show included files. As sole argument, print search dirs. -vvv shows tries too.
+
+@item -bench
+Display compilation statistics.
+
+@end table
+
+Preprocessor options:
+
+@table @option
+@item -Idir
+Specify an additional include path. Include paths are searched in the
+order they are specified.
+
+System include paths are always searched after. The default system
+include paths are: @file{/usr/local/include}, @file{/usr/include}
+and @file{PREFIX/lib/tcc/include}. (@file{PREFIX} is usually
+@file{/usr} or @file{/usr/local}).
+
+@item -Dsym[=val]
+Define preprocessor symbol @samp{sym} to
+val. If val is not present, its value is @samp{1}. Function-like macros can
+also be defined: @option{-DF(a)=a+1}
+
+@item -Usym
+Undefine preprocessor symbol @samp{sym}.
+
+@item -E
+Preprocess only, to stdout or file (with -o).
+
+@end table
+
+Compilation flags:
+
+Note: each of the following options has a negative form beginning with
+@option{-fno-}.
+
+@table @option
+@item -funsigned-char
+Let the @code{char} type be unsigned.
+
+@item -fsigned-char
+Let the @code{char} type be signed.
+
+@item -fno-common
+Do not generate common symbols for uninitialized data.
+
+@item -fleading-underscore
+Add a leading underscore at the beginning of each C symbol.
+
+@item -fms-extensions
+Allow a MS C compiler extensions to the language. Currently this
+assumes a nested named structure declaration without an identifier
+behaves like an unnamed one.
+
+@item -fdollars-in-identifiers
+Allow dollar signs in identifiers
+
+@end table
+
+Warning options:
+
+@table @option
+@item -w
+Disable all warnings.
+
+@end table
+
+Note: each of the following warning options has a negative form beginning with
+@option{-Wno-}.
+
+@table @option
+@item -Wimplicit-function-declaration
+Warn about implicit function declaration.
+
+@item -Wunsupported
+Warn about unsupported GCC features that are ignored by TCC.
+
+@item -Wwrite-strings
+Make string constants be of type @code{const char *} instead of @code{char
+*}.
+
+@item -Werror
+Abort compilation if warnings are issued.
+
+@item -Wall
+Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
+@option{-Wwrite-strings}.
+
+@end table
+
+Linker options:
+
+@table @option
+@item -Ldir
+Specify an additional static library path for the @option{-l} option. The
+default library paths are @file{/usr/local/lib}, @file{/usr/lib} and @file{/lib}.
+
+@item -lxxx
+Link your program with dynamic library libxxx.so or static library
+libxxx.a. The library is searched in the paths specified by the
+@option{-L} option and @env{LIBRARY_PATH} variable.
+
+@item -Bdir
+Set the path where the tcc internal libraries (and include files) can be
+found (default is @file{PREFIX/lib/tcc}).
+
+@item -shared
+Generate a shared library instead of an executable.
+
+@item -soname name
+set name for shared library to be used at runtime
+
+@item -static
+Generate a statically linked executable (default is a shared linked
+executable).
+
+@item -rdynamic
+Export global symbols to the dynamic linker. It is useful when a library
+opened with @code{dlopen()} needs to access executable symbols.
+
+@item -r
+Generate an object file combining all input files.
+
+@item -Wl,-rpath=path
+Put custom search path for dynamic libraries into executable.
+
+@item -Wl,--enable-new-dtags
+When putting a custom search path for dynamic libraries into the executable,
+create the new ELF dynamic tag DT_RUNPATH instead of the old legacy DT_RPATH.
+
+@item -Wl,--oformat=fmt
+Use @var{fmt} as output format. The supported output formats are:
+@table @code
+@item elf32-i386
+ELF output format (default)
+@item binary
+Binary image (only for executable output)
+@item coff
+COFF output format (only for executable output for TMS320C67xx target)
+@end table
+
+@item -Wl,-subsystem=console/gui/wince/...
+Set type for PE (Windows) executables.
+
+@item -Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]
+Modify executable layout.
+
+@item -Wl,-Bsymbolic
+Set DT_SYMBOLIC tag.
+
+@item -Wl,-(no-)whole-archive
+Turn on/off linking of all objects in archives.
+
+@end table
+
+Debugger options:
+
+@table @option
+@item -g
+Generate run time debug information so that you get clear run time
+error messages: @code{ test.c:68: in function 'test5()': dereferencing
+invalid pointer} instead of the laconic @code{Segmentation
+fault}.
+
+@item -b
+Generate additional support code to check
+memory allocations and array/pointer bounds. @option{-g} is implied. Note
+that the generated code is slower and bigger in this case.
+
+Note: @option{-b} is only available on i386 when using libtcc for the moment.
+
+@item -bt N
+Display N callers in stack traces. This is useful with @option{-g} or
+@option{-b}.
+
+@end table
+
+Misc options:
+
+@table @option
+@item -MD
+Generate makefile fragment with dependencies.
+
+@item -MF depfile
+Use @file{depfile} as output for -MD.
+
+@item -print-search-dirs
+Print the configured installation directory and a list of library
+and include directories tcc will search.
+
+@item -dumpversion
+Print version.
+
+@end table
+
+Target specific options:
+
+@table @option
+@item -mms-bitfields
+Use an algorithm for bitfield alignment consistent with MSVC. Default is
+gcc's algorithm.
+
+@item -mfloat-abi (ARM only)
+Select the float ABI. Possible values: @code{softfp} and @code{hard}
+
+@item -mno-sse
+Do not use sse registers on x86_64
+
+@item -m32, -m64
+Pass command line to the i386/x86_64 cross compiler.
+
+@end table
+
+Note: GCC options @option{-Ox}, @option{-fx} and @option{-mx} are
+ignored.
+@c man end
+
+@c man begin ENVIRONMENT
+Environment variables that affect how tcc operates.
+
+@table @option
+
+@item CPATH
+@item C_INCLUDE_PATH
+A colon-separated list of directories searched for include files,
+directories given with @option{-I} are searched first.
+
+@item LIBRARY_PATH
+A colon-separated list of directories searched for libraries for the
+@option{-l} option, directories given with @option{-L} are searched first.
+
+@end table
+
+@c man end
+
+@ignore
+
+@setfilename tcc
+@settitle Tiny C Compiler
+
+@c man begin SEEALSO
+cpp(1),
+gcc(1)
+@c man end
+
+@c man begin AUTHOR
+Fabrice Bellard
+@c man end
+
+@end ignore
+
+@node Clang
+@chapter C language support
+
+@section ANSI C
+
+TCC implements all the ANSI C standard, including structure bit fields
+and floating point numbers (@code{long double}, @code{double}, and
+@code{float} fully supported).
+
+@section ISOC99 extensions
+
+TCC implements many features of the new C standard: ISO C99. Currently
+missing items are: complex and imaginary numbers.
+
+Currently implemented ISOC99 features:
+
+@itemize
+
+@item variable length arrays.
+
+@item 64 bit @code{long long} types are fully supported.
+
+@item The boolean type @code{_Bool} is supported.
+
+@item @code{__func__} is a string variable containing the current
+function name.
+
+@item Variadic macros: @code{__VA_ARGS__} can be used for
+ function-like macros:
+@example
+ #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__)
+@end example
+
+@noindent
+@code{dprintf} can then be used with a variable number of parameters.
+
+@item Declarations can appear anywhere in a block (as in C++).
+
+@item Array and struct/union elements can be initialized in any order by
+ using designators:
+@example
+ struct @{ int x, y; @} st[10] = @{ [0].x = 1, [0].y = 2 @};
+
+ int tab[10] = @{ 1, 2, [5] = 5, [9] = 9@};
+@end example
+
+@item Compound initializers are supported:
+@example
+ int *p = (int [])@{ 1, 2, 3 @};
+@end example
+to initialize a pointer pointing to an initialized array. The same
+works for structures and strings.
+
+@item Hexadecimal floating point constants are supported:
+@example
+ double d = 0x1234p10;
+@end example
+
+@noindent
+is the same as writing
+@example
+ double d = 4771840.0;
+@end example
+
+@item @code{inline} keyword is ignored.
+
+@item @code{restrict} keyword is ignored.
+@end itemize
+
+@section GNU C extensions
+
+TCC implements some GNU C extensions:
+
+@itemize
+
+@item array designators can be used without '=':
+@example
+ int a[10] = @{ [0] 1, [5] 2, 3, 4 @};
+@end example
+
+@item Structure field designators can be a label:
+@example
+ struct @{ int x, y; @} st = @{ x: 1, y: 1@};
+@end example
+instead of
+@example
+ struct @{ int x, y; @} st = @{ .x = 1, .y = 1@};
+@end example
+
+@item @code{\e} is ASCII character 27.
+
+@item case ranges : ranges can be used in @code{case}s:
+@example
+ switch(a) @{
+ case 1 @dots{} 9:
+ printf("range 1 to 9\n");
+ break;
+ default:
+ printf("unexpected\n");
+ break;
+ @}
+@end example
+
+@cindex aligned attribute
+@cindex packed attribute
+@cindex section attribute
+@cindex unused attribute
+@cindex cdecl attribute
+@cindex stdcall attribute
+@cindex regparm attribute
+@cindex dllexport attribute
+
+@item The keyword @code{__attribute__} is handled to specify variable or
+function attributes. The following attributes are supported:
+ @itemize
+
+ @item @code{aligned(n)}: align a variable or a structure field to n bytes
+(must be a power of two).
+
+ @item @code{packed}: force alignment of a variable or a structure field to
+ 1.
+
+ @item @code{section(name)}: generate function or data in assembly section
+name (name is a string containing the section name) instead of the default
+section.
+
+ @item @code{unused}: specify that the variable or the function is unused.
+
+ @item @code{cdecl}: use standard C calling convention (default).
+
+ @item @code{stdcall}: use Pascal-like calling convention.
+
+ @item @code{regparm(n)}: use fast i386 calling convention. @var{n} must be
+between 1 and 3. The first @var{n} function parameters are respectively put in
+registers @code{%eax}, @code{%edx} and @code{%ecx}.
+
+ @item @code{dllexport}: export function from dll/executable (win32 only)
+
+ @end itemize
+
+Here are some examples:
+@example
+ int a __attribute__ ((aligned(8), section(".mysection")));
+@end example
+
+@noindent
+align variable @code{a} to 8 bytes and put it in section @code{.mysection}.
+
+@example
+ int my_add(int a, int b) __attribute__ ((section(".mycodesection")))
+ @{
+ return a + b;
+ @}
+@end example
+
+@noindent
+generate function @code{my_add} in section @code{.mycodesection}.
+
+@item GNU style variadic macros:
+@example
+ #define dprintf(fmt, args@dots{}) printf(fmt, ## args)
+
+ dprintf("no arg\n");
+ dprintf("one arg %d\n", 1);
+@end example
+
+@item @code{__FUNCTION__} is interpreted as C99 @code{__func__}
+(so it has not exactly the same semantics as string literal GNUC
+where it is a string literal).
+
+@item The @code{__alignof__} keyword can be used as @code{sizeof}
+to get the alignment of a type or an expression.
+
+@item The @code{typeof(x)} returns the type of @code{x}.
+@code{x} is an expression or a type.
+
+@item Computed gotos: @code{&&label} returns a pointer of type
+@code{void *} on the goto label @code{label}. @code{goto *expr} can be
+used to jump on the pointer resulting from @code{expr}.
+
+@item Inline assembly with asm instruction:
+@cindex inline assembly
+@cindex assembly, inline
+@cindex __asm__
+@example
+static inline void * my_memcpy(void * to, const void * from, size_t n)
+@{
+int d0, d1, d2;
+__asm__ __volatile__(
+ "rep ; movsl\n\t"
+ "testb $2,%b4\n\t"
+ "je 1f\n\t"
+ "movsw\n"
+ "1:\ttestb $1,%b4\n\t"
+ "je 2f\n\t"
+ "movsb\n"
+ "2:"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+ : "memory");
+return (to);
+@}
+@end example
+
+@noindent
+@cindex gas
+TCC includes its own x86 inline assembler with a @code{gas}-like (GNU
+assembler) syntax. No intermediate files are generated. GCC 3.x named
+operands are supported.
+
+@item @code{__builtin_types_compatible_p()} and @code{__builtin_constant_p()}
+are supported.
+
+@item @code{#pragma pack} is supported for win32 compatibility.
+
+@end itemize
+
+@section TinyCC extensions
+
+@itemize
+
+@item @code{__TINYC__} is a predefined macro to indicate that you use TCC.
+
+@item @code{#!} at the start of a line is ignored to allow scripting.
+
+@item Binary digits can be entered (@code{0b101} instead of
+@code{5}).
+
+@item @code{__BOUNDS_CHECKING_ON} is defined if bound checking is activated.
+
+@end itemize
+
+@node asm
+@chapter TinyCC Assembler
+
+Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
+assembler supports a gas-like syntax (GNU assembler). You can
+deactivate assembler support if you want a smaller TinyCC executable
+(the C compiler does not rely on the assembler).
+
+TinyCC Assembler is used to handle files with @file{.S} (C
+preprocessed assembler) and @file{.s} extensions. It is also used to
+handle the GNU inline assembler with the @code{asm} keyword.
+
+@section Syntax
+
+TinyCC Assembler supports most of the gas syntax. The tokens are the
+same as C.
+
+@itemize
+
+@item C and C++ comments are supported.
+
+@item Identifiers are the same as C, so you cannot use '.' or '$'.
+
+@item Only 32 bit integer numbers are supported.
+
+@end itemize
+
+@section Expressions
+
+@itemize
+
+@item Integers in decimal, octal and hexa are supported.
+
+@item Unary operators: +, -, ~.
+
+@item Binary operators in decreasing priority order:
+
+@enumerate
+@item *, /, %
+@item &, |, ^
+@item +, -
+@end enumerate
+
+@item A value is either an absolute number or a label plus an offset.
+All operators accept absolute values except '+' and '-'. '+' or '-' can be
+used to add an offset to a label. '-' supports two labels only if they
+are the same or if they are both defined and in the same section.
+
+@end itemize
+
+@section Labels
+
+@itemize
+
+@item All labels are considered as local, except undefined ones.
+
+@item Numeric labels can be used as local @code{gas}-like labels.
+They can be defined several times in the same source. Use 'b'
+(backward) or 'f' (forward) as suffix to reference them:
+
+@example
+ 1:
+ jmp 1b /* jump to '1' label before */
+ jmp 1f /* jump to '1' label after */
+ 1:
+@end example
+
+@end itemize
+
+@section Directives
+@cindex assembler directives
+@cindex directives, assembler
+@cindex align directive
+@cindex skip directive
+@cindex space directive
+@cindex byte directive
+@cindex word directive
+@cindex short directive
+@cindex int directive
+@cindex long directive
+@cindex quad directive
+@cindex globl directive
+@cindex global directive
+@cindex section directive
+@cindex text directive
+@cindex data directive
+@cindex bss directive
+@cindex fill directive
+@cindex org directive
+@cindex previous directive
+@cindex string directive
+@cindex asciz directive
+@cindex ascii directive
+
+All directives are preceded by a '.'. The following directives are
+supported:
+
+@itemize
+@item .align n[,value]
+@item .skip n[,value]
+@item .space n[,value]
+@item .byte value1[,...]
+@item .word value1[,...]
+@item .short value1[,...]
+@item .int value1[,...]
+@item .long value1[,...]
+@item .quad immediate_value1[,...]
+@item .globl symbol
+@item .global symbol
+@item .section section
+@item .text
+@item .data
+@item .bss
+@item .fill repeat[,size[,value]]
+@item .org n
+@item .previous
+@item .string string[,...]
+@item .asciz string[,...]
+@item .ascii string[,...]
+@end itemize
+
+@section X86 Assembler
+@cindex assembler
+
+All X86 opcodes are supported. Only ATT syntax is supported (source
+then destination operand order). If no size suffix is given, TinyCC
+tries to guess it from the operand sizes.
+
+Currently, MMX opcodes are supported but not SSE ones.
+
+@node linker
+@chapter TinyCC Linker
+@cindex linker
+
+@section ELF file generation
+@cindex ELF
+
+TCC can directly output relocatable ELF files (object files),
+executable ELF files and dynamic ELF libraries without relying on an
+external linker.
+
+Dynamic ELF libraries can be output but the C compiler does not generate
+position independent code (PIC). It means that the dynamic library
+code generated by TCC cannot be factorized among processes yet.
+
+TCC linker eliminates unreferenced object code in libraries. A single pass is
+done on the object and library list, so the order in which object files and
+libraries are specified is important (same constraint as GNU ld). No grouping
+options (@option{--start-group} and @option{--end-group}) are supported.
+
+@section ELF file loader
+
+TCC can load ELF object files, archives (.a files) and dynamic
+libraries (.so).
+
+@section PE-i386 file generation
+@cindex PE-i386
+
+TCC for Windows supports the native Win32 executable file format (PE-i386). It
+generates EXE files (console and gui) and DLL files.
+
+For usage on Windows, see also tcc-win32.txt.
+
+@section GNU Linker Scripts
+@cindex scripts, linker
+@cindex linker scripts
+@cindex GROUP, linker command
+@cindex FILE, linker command
+@cindex OUTPUT_FORMAT, linker command
+@cindex TARGET, linker command
+
+Because on many Linux systems some dynamic libraries (such as
+@file{/usr/lib/libc.so}) are in fact GNU ld link scripts (horrible!),
+the TCC linker also supports a subset of GNU ld scripts.
+
+The @code{GROUP} and @code{FILE} commands are supported. @code{OUTPUT_FORMAT}
+and @code{TARGET} are ignored.
+
+Example from @file{/usr/lib/libc.so}:
+@example
+/* GNU ld script
+ Use the shared library, but some functions are only in
+ the static library, so try that secondarily. */
+GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )
+@end example
+
+@node Bounds
+@chapter TinyCC Memory and Bound checks
+@cindex bound checks
+@cindex memory checks
+
+This feature is activated with the @option{-b} (@pxref{Invoke}).
+
+Note that pointer size is @emph{unchanged} and that code generated
+with bound checks is @emph{fully compatible} with unchecked
+code. When a pointer comes from unchecked code, it is assumed to be
+valid. Even very obscure C code with casts should work correctly.
+
+For more information about the ideas behind this method, see
+@url{http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html}.
+
+Here are some examples of caught errors:
+
+@table @asis
+
+@item Invalid range with standard string function:
+@example
+@{
+ char tab[10];
+ memset(tab, 0, 11);
+@}
+@end example
+
+@item Out of bounds-error in global or local arrays:
+@example
+@{
+ int tab[10];
+ for(i=0;i<11;i++) @{
+ sum += tab[i];
+ @}
+@}
+@end example
+
+@item Out of bounds-error in malloc'ed data:
+@example
+@{
+ int *tab;
+ tab = malloc(20 * sizeof(int));
+ for(i=0;i<21;i++) @{
+ sum += tab4[i];
+ @}
+ free(tab);
+@}
+@end example
+
+@item Access of freed memory:
+@example
+@{
+ int *tab;
+ tab = malloc(20 * sizeof(int));
+ free(tab);
+ for(i=0;i<20;i++) @{
+ sum += tab4[i];
+ @}
+@}
+@end example
+
+@item Double free:
+@example
+@{
+ int *tab;
+ tab = malloc(20 * sizeof(int));
+ free(tab);
+ free(tab);
+@}
+@end example
+
+@end table
+
+@node Libtcc
+@chapter The @code{libtcc} library
+
+The @code{libtcc} library enables you to use TCC as a backend for
+dynamic code generation.
+
+Read the @file{libtcc.h} to have an overview of the API. Read
+@file{libtcc_test.c} to have a very simple example.
+
+The idea consists in giving a C string containing the program you want
+to compile directly to @code{libtcc}. Then you can access to any global
+symbol (function or variable) defined.
+
+@node devel
+@chapter Developer's guide
+
+This chapter gives some hints to understand how TCC works. You can skip
+it if you do not intend to modify the TCC code.
+
+@section File reading
+
+The @code{BufferedFile} structure contains the context needed to read a
+file, including the current line number. @code{tcc_open()} opens a new
+file and @code{tcc_close()} closes it. @code{inp()} returns the next
+character.
+
+@section Lexer
+
+@code{next()} reads the next token in the current
+file. @code{next_nomacro()} reads the next token without macro
+expansion.
+
+@code{tok} contains the current token (see @code{TOK_xxx})
+constants. Identifiers and keywords are also keywords. @code{tokc}
+contains additional infos about the token (for example a constant value
+if number or string token).
+
+@section Parser
+
+The parser is hardcoded (yacc is not necessary). It does only one pass,
+except:
+
+@itemize
+
+@item For initialized arrays with unknown size, a first pass
+is done to count the number of elements.
+
+@item For architectures where arguments are evaluated in
+reverse order, a first pass is done to reverse the argument order.
+
+@end itemize
+
+@section Types
+
+The types are stored in a single 'int' variable. It was chosen in the
+first stages of development when tcc was much simpler. Now, it may not
+be the best solution.
+
+@example
+#define VT_INT 0 /* integer type */
+#define VT_BYTE 1 /* signed byte type */
+#define VT_SHORT 2 /* short type */
+#define VT_VOID 3 /* void type */
+#define VT_PTR 4 /* pointer */
+#define VT_ENUM 5 /* enum definition */
+#define VT_FUNC 6 /* function type */
+#define VT_STRUCT 7 /* struct/union definition */
+#define VT_FLOAT 8 /* IEEE float */
+#define VT_DOUBLE 9 /* IEEE double */
+#define VT_LDOUBLE 10 /* IEEE long double */
+#define VT_BOOL 11 /* ISOC99 boolean type */
+#define VT_LLONG 12 /* 64 bit integer */
+#define VT_LONG 13 /* long integer (NEVER USED as type, only
+ during parsing) */
+#define VT_BTYPE 0x000f /* mask for basic type */
+#define VT_UNSIGNED 0x0010 /* unsigned type */
+#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
+#define VT_VLA 0x20000 /* VLA type (also has VT_PTR and VT_ARRAY) */
+#define VT_BITFIELD 0x0040 /* bitfield modifier */
+#define VT_CONSTANT 0x0800 /* const modifier */
+#define VT_VOLATILE 0x1000 /* volatile modifier */
+#define VT_DEFSIGN 0x2000 /* signed type */
+
+#define VT_STRUCT_SHIFT 18 /* structure/enum name shift (14 bits left) */
+@end example
+
+When a reference to another type is needed (for pointers, functions and
+structures), the @code{32 - VT_STRUCT_SHIFT} high order bits are used to
+store an identifier reference.
+
+The @code{VT_UNSIGNED} flag can be set for chars, shorts, ints and long
+longs.
+
+Arrays are considered as pointers @code{VT_PTR} with the flag
+@code{VT_ARRAY} set. Variable length arrays are considered as special
+arrays and have flag @code{VT_VLA} set instead of @code{VT_ARRAY}.
+
+The @code{VT_BITFIELD} flag can be set for chars, shorts, ints and long
+longs. If it is set, then the bitfield position is stored from bits
+VT_STRUCT_SHIFT to VT_STRUCT_SHIFT + 5 and the bit field size is stored
+from bits VT_STRUCT_SHIFT + 6 to VT_STRUCT_SHIFT + 11.
+
+@code{VT_LONG} is never used except during parsing.
+
+During parsing, the storage of an object is also stored in the type
+integer:
+
+@example
+#define VT_EXTERN 0x00000080 /* extern definition */
+#define VT_STATIC 0x00000100 /* static variable */
+#define VT_TYPEDEF 0x00000200 /* typedef definition */
+#define VT_INLINE 0x00000400 /* inline definition */
+#define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */
+#define VT_EXPORT 0x00008000 /* win32: data exported from dll */
+#define VT_WEAK 0x00010000 /* win32: data exported from dll */
+@end example
+
+@section Symbols
+
+All symbols are stored in hashed symbol stacks. Each symbol stack
+contains @code{Sym} structures.
+
+@code{Sym.v} contains the symbol name (remember
+an identifier is also a token, so a string is never necessary to store
+it). @code{Sym.t} gives the type of the symbol. @code{Sym.r} is usually
+the register in which the corresponding variable is stored. @code{Sym.c} is
+usually a constant associated to the symbol like its address for normal
+symbols, and the number of entries for symbols representing arrays.
+Variable length array types use @code{Sym.c} as a location on the stack
+which holds the runtime sizeof for the type.
+
+Four main symbol stacks are defined:
+
+@table @code
+
+@item define_stack
+for the macros (@code{#define}s).
+
+@item global_stack
+for the global variables, functions and types.
+
+@item local_stack
+for the local variables, functions and types.
+
+@item global_label_stack
+for the local labels (for @code{goto}).
+
+@item label_stack
+for GCC block local labels (see the @code{__label__} keyword).
+
+@end table
+
+@code{sym_push()} is used to add a new symbol in the local symbol
+stack. If no local symbol stack is active, it is added in the global
+symbol stack.
+
+@code{sym_pop(st,b)} pops symbols from the symbol stack @var{st} until
+the symbol @var{b} is on the top of stack. If @var{b} is NULL, the stack
+is emptied.
+
+@code{sym_find(v)} return the symbol associated to the identifier
+@var{v}. The local stack is searched first from top to bottom, then the
+global stack.
+
+@section Sections
+
+The generated code and data are written in sections. The structure
+@code{Section} contains all the necessary information for a given
+section. @code{new_section()} creates a new section. ELF file semantics
+is assumed for each section.
+
+The following sections are predefined:
+
+@table @code
+
+@item text_section
+is the section containing the generated code. @var{ind} contains the
+current position in the code section.
+
+@item data_section
+contains initialized data
+
+@item bss_section
+contains uninitialized data
+
+@item bounds_section
+@itemx lbounds_section
+are used when bound checking is activated
+
+@item stab_section
+@itemx stabstr_section
+are used when debugging is active to store debug information
+
+@item symtab_section
+@itemx strtab_section
+contain the exported symbols (currently only used for debugging).
+
+@end table
+
+@section Code generation
+@cindex code generation
+
+@subsection Introduction
+
+The TCC code generator directly generates linked binary code in one
+pass. It is rather unusual these days (see gcc for example which
+generates text assembly), but it can be very fast and surprisingly
+little complicated.
+
+The TCC code generator is register based. Optimization is only done at
+the expression level. No intermediate representation of expression is
+kept except the current values stored in the @emph{value stack}.
+
+On x86, three temporary registers are used. When more registers are
+needed, one register is spilled into a new temporary variable on the stack.
+
+@subsection The value stack
+@cindex value stack, introduction
+
+When an expression is parsed, its value is pushed on the value stack
+(@var{vstack}). The top of the value stack is @var{vtop}. Each value
+stack entry is the structure @code{SValue}.
+
+@code{SValue.t} is the type. @code{SValue.r} indicates how the value is
+currently stored in the generated code. It is usually a CPU register
+index (@code{REG_xxx} constants), but additional values and flags are
+defined:
+
+@example
+#define VT_CONST 0x00f0
+#define VT_LLOCAL 0x00f1
+#define VT_LOCAL 0x00f2
+#define VT_CMP 0x00f3
+#define VT_JMP 0x00f4
+#define VT_JMPI 0x00f5
+#define VT_LVAL 0x0100
+#define VT_SYM 0x0200
+#define VT_MUSTCAST 0x0400
+#define VT_MUSTBOUND 0x0800
+#define VT_BOUNDED 0x8000
+#define VT_LVAL_BYTE 0x1000
+#define VT_LVAL_SHORT 0x2000
+#define VT_LVAL_UNSIGNED 0x4000
+#define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
+@end example
+
+@table @code
+
+@item VT_CONST
+indicates that the value is a constant. It is stored in the union
+@code{SValue.c}, depending on its type.
+
+@item VT_LOCAL
+indicates a local variable pointer at offset @code{SValue.c.i} in the
+stack.
+
+@item VT_CMP
+indicates that the value is actually stored in the CPU flags (i.e. the
+value is the consequence of a test). The value is either 0 or 1. The
+actual CPU flags used is indicated in @code{SValue.c.i}.
+
+If any code is generated which destroys the CPU flags, this value MUST be
+put in a normal register.
+
+@item VT_JMP
+@itemx VT_JMPI
+indicates that the value is the consequence of a conditional jump. For VT_JMP,
+it is 1 if the jump is taken, 0 otherwise. For VT_JMPI it is inverted.
+
+These values are used to compile the @code{||} and @code{&&} logical
+operators.
+
+If any code is generated, this value MUST be put in a normal
+register. Otherwise, the generated code won't be executed if the jump is
+taken.
+
+@item VT_LVAL
+is a flag indicating that the value is actually an lvalue (left value of
+an assignment). It means that the value stored is actually a pointer to
+the wanted value.
+
+Understanding the use @code{VT_LVAL} is very important if you want to
+understand how TCC works.
+
+@item VT_LVAL_BYTE
+@itemx VT_LVAL_SHORT
+@itemx VT_LVAL_UNSIGNED
+if the lvalue has an integer type, then these flags give its real
+type. The type alone is not enough in case of cast optimisations.
+
+@item VT_LLOCAL
+is a saved lvalue on the stack. @code{VT_LVAL} must also be set with
+@code{VT_LLOCAL}. @code{VT_LLOCAL} can arise when a @code{VT_LVAL} in
+a register has to be saved to the stack, or it can come from an
+architecture-specific calling convention.
+
+@item VT_MUSTCAST
+indicates that a cast to the value type must be performed if the value
+is used (lazy casting).
+
+@item VT_SYM
+indicates that the symbol @code{SValue.sym} must be added to the constant.
+
+@item VT_MUSTBOUND
+@itemx VT_BOUNDED
+are only used for optional bound checking.
+
+@end table
+
+@subsection Manipulating the value stack
+@cindex value stack
+
+@code{vsetc()} and @code{vset()} pushes a new value on the value
+stack. If the previous @var{vtop} was stored in a very unsafe place(for
+example in the CPU flags), then some code is generated to put the
+previous @var{vtop} in a safe storage.
+
+@code{vpop()} pops @var{vtop}. In some cases, it also generates cleanup
+code (for example if stacked floating point registers are used as on
+x86).
+
+The @code{gv(rc)} function generates code to evaluate @var{vtop} (the
+top value of the stack) into registers. @var{rc} selects in which
+register class the value should be put. @code{gv()} is the @emph{most
+important function} of the code generator.
+
+@code{gv2()} is the same as @code{gv()} but for the top two stack
+entries.
+
+@subsection CPU dependent code generation
+@cindex CPU dependent
+See the @file{i386-gen.c} file to have an example.
+
+@table @code
+
+@item load()
+must generate the code needed to load a stack value into a register.
+
+@item store()
+must generate the code needed to store a register into a stack value
+lvalue.
+
+@item gfunc_start()
+@itemx gfunc_param()
+@itemx gfunc_call()
+should generate a function call
+
+@item gfunc_prolog()
+@itemx gfunc_epilog()
+should generate a function prolog/epilog.
+
+@item gen_opi(op)
+must generate the binary integer operation @var{op} on the two top
+entries of the stack which are guaranteed to contain integer types.
+
+The result value should be put on the stack.
+
+@item gen_opf(op)
+same as @code{gen_opi()} for floating point operations. The two top
+entries of the stack are guaranteed to contain floating point values of
+same types.
+
+@item gen_cvt_itof()
+integer to floating point conversion.
+
+@item gen_cvt_ftoi()
+floating point to integer conversion.
+
+@item gen_cvt_ftof()
+floating point to floating point of different size conversion.
+
+@item gen_bounded_ptr_add()
+@item gen_bounded_ptr_deref()
+are only used for bounds checking.
+
+@end table
+
+@section Optimizations done
+@cindex optimizations
+@cindex constant propagation
+@cindex strength reduction
+@cindex comparison operators
+@cindex caching processor flags
+@cindex flags, caching
+@cindex jump optimization
+Constant propagation is done for all operations. Multiplications and
+divisions are optimized to shifts when appropriate. Comparison
+operators are optimized by maintaining a special cache for the
+processor flags. &&, || and ! are optimized by maintaining a special
+'jump target' value. No other jump optimization is currently performed
+because it would require to store the code in a more abstract fashion.
+
+@unnumbered Concept Index
+@printindex cp
+
+@bye
+
+@c Local variables:
+@c fill-column: 78
+@c texinfo-column-for-description: 32
+@c End:
diff --git a/tcc.c b/tcc.c
new file mode 100644
index 0000000..cd887d1
--- /dev/null
+++ b/tcc.c
@@ -0,0 +1,371 @@
+/*
+ * TCC - Tiny C Compiler
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tcc.h"
+#if ONE_SOURCE
+# include "libtcc.c"
+#endif
+#include "tcctools.c"
+
+static const char help[] =
+ "Tiny C Compiler "TCC_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n"
+ "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
+ " tcc [options...] -run infile [arguments...]\n"
+ "General options:\n"
+ " -c compile only - generate an object file\n"
+ " -o outfile set output filename\n"
+ " -run run compiled source\n"
+ " -fflag set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"
+ " -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
+ " -w disable all warnings\n"
+ " -v -vv show version, show search paths or loaded files\n"
+ " -h -hh show this, show more help\n"
+ " -bench show compilation statistics\n"
+ " - use stdin pipe as infile\n"
+ " @listfile read arguments from listfile\n"
+ "Preprocessor options:\n"
+ " -Idir add include path 'dir'\n"
+ " -Dsym[=val] define 'sym' with value 'val'\n"
+ " -Usym undefine 'sym'\n"
+ " -E preprocess only\n"
+ "Linker options:\n"
+ " -Ldir add library path 'dir'\n"
+ " -llib link with dynamic or static library 'lib'\n"
+ " -r generate (relocatable) object file\n"
+ " -shared generate a shared library/dll\n"
+ " -rdynamic export all global symbols to dynamic linker\n"
+ " -soname set name for shared library to be used at runtime\n"
+ " -Wl,-opt[=val] set linker option (see tcc -hh)\n"
+ "Debugger options:\n"
+ " -g generate runtime debug info\n"
+#ifdef CONFIG_TCC_BCHECK
+ " -b compile with built-in memory and bounds checker (implies -g)\n"
+#endif
+#ifdef CONFIG_TCC_BACKTRACE
+ " -bt N show N callers in stack traces\n"
+#endif
+ "Misc. options:\n"
+ " -x[c|a|n] specify type of the next infile\n"
+ " -nostdinc do not use standard system include paths\n"
+ " -nostdlib do not link with standard crt and libraries\n"
+ " -Bdir set tcc's private include/library dir\n"
+ " -MD generate dependency file for make\n"
+ " -MF file specify dependency file name\n"
+ " -m32/64 defer to i386/x86_64 cross compiler\n"
+ "Tools:\n"
+ " create library : tcc -ar [rcsv] lib.a files\n"
+#ifdef TCC_TARGET_PE
+ " create def file : tcc -impdef lib.dll [-v] [-o lib.def]\n"
+#endif
+ ;
+
+static const char help2[] =
+ "Tiny C Compiler "TCC_VERSION" - More Options\n"
+ "Special options:\n"
+ " -P -P1 with -E: no/alternative #line output\n"
+ " -dD -dM with -E: output #define directives\n"
+ " -pthread same as -D_REENTRANT and -lpthread\n"
+ " -On same as -D__OPTIMIZE__ for n > 0\n"
+ " -Wp,-opt same as -opt\n"
+ " -include file include 'file' above each input file\n"
+ " -isystem dir add 'dir' to system include path\n"
+ " -static link to static libraries (not recommended)\n"
+ " -dumpversion print version\n"
+ " -print-search-dirs print search paths\n"
+ " -dt with -run/-E: auto-define 'test_...' macros\n"
+ "Ignored options:\n"
+ " --param -pedantic -pipe -s -std -traditional\n"
+ "-W... warnings:\n"
+ " all turn on some (*) warnings\n"
+ " error stop after first warning\n"
+ " unsupported warn about ignored options, pragmas, etc.\n"
+ " write-strings strings are const\n"
+ " implicit-function-declaration warn for missing prototype (*)\n"
+ "-f[no-]... flags:\n"
+ " unsigned-char default char is unsigned\n"
+ " signed-char default char is signed\n"
+ " common use common section instead of bss\n"
+ " leading-underscore decorate extern symbols\n"
+ " ms-extensions allow anonymous struct in struct\n"
+ " dollars-in-identifiers allow '$' in C symbols\n"
+ "-m... target specific options:\n"
+ " ms-bitfields use MSVC bitfield layout\n"
+#ifdef TCC_TARGET_ARM
+ " float-abi hard/softfp on arm\n"
+#endif
+#ifdef TCC_TARGET_X86_64
+ " no-sse disable floats on x86_64\n"
+#endif
+ "-Wl,... linker options:\n"
+ " -nostdlib do not link with standard crt/libs\n"
+ " -[no-]whole-archive load lib(s) fully/only as needed\n"
+ " -export-all-symbols same as -rdynamic\n"
+ " -image-base= -Ttext= set base address of executable\n"
+ " -section-alignment= set section alignment in executable\n"
+#ifdef TCC_TARGET_PE
+ " -file-alignment= set PE file alignment\n"
+ " -stack= set PE stack reserve\n"
+ " -large-address-aware set related PE option\n"
+ " -subsystem=[console/windows] set PE subsystem\n"
+ " -oformat=[pe-* binary] set executable output format\n"
+ "Predefined macros:\n"
+ " tcc -E -dM - < nul\n"
+#else
+ " -rpath= set dynamic library search path\n"
+ " -enable-new-dtags set DT_RUNPATH instead of DT_RPATH\n"
+ " -soname= set DT_SONAME elf tag\n"
+ " -Bsymbolic set DT_SYMBOLIC elf tag\n"
+ " -oformat=[elf32/64-* binary] set executable output format\n"
+ " -init= -fini= -as-needed -O (ignored)\n"
+ "Predefined macros:\n"
+ " tcc -E -dM - < /dev/null\n"
+#endif
+ "See also the manual for more details.\n"
+ ;
+
+static const char version[] =
+ "tcc version "TCC_VERSION" ("
+#ifdef TCC_TARGET_I386
+ "i386"
+#elif defined TCC_TARGET_X86_64
+ "x86_64"
+#elif defined TCC_TARGET_C67
+ "C67"
+#elif defined TCC_TARGET_ARM
+ "ARM"
+#elif defined TCC_TARGET_ARM64
+ "AArch64"
+#endif
+#ifdef TCC_ARM_HARDFLOAT
+ " Hard Float"
+#endif
+#ifdef TCC_TARGET_PE
+ " Windows"
+#elif defined(TCC_TARGET_MACHO)
+ " Darwin"
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ " FreeBSD"
+#else
+ " Linux"
+#endif
+ ")\n"
+ ;
+
+static void print_dirs(const char *msg, char **paths, int nb_paths)
+{
+ int i;
+ printf("%s:\n%s", msg, nb_paths ? "" : " -\n");
+ for(i = 0; i < nb_paths; i++)
+ printf(" %s\n", paths[i]);
+}
+
+static void print_search_dirs(TCCState *s)
+{
+ printf("install: %s\n", s->tcc_lib_path);
+ /* print_dirs("programs", NULL, 0); */
+ print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
+ print_dirs("libraries", s->library_paths, s->nb_library_paths);
+ printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);
+#ifndef TCC_TARGET_PE
+ print_dirs("crt", s->crt_paths, s->nb_crt_paths);
+ printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
+#endif
+}
+
+static void set_environment(TCCState *s)
+{
+ char * path;
+
+ path = getenv("C_INCLUDE_PATH");
+ if(path != NULL) {
+ tcc_add_sysinclude_path(s, path);
+ }
+ path = getenv("CPATH");
+ if(path != NULL) {
+ tcc_add_include_path(s, path);
+ }
+ path = getenv("LIBRARY_PATH");
+ if(path != NULL) {
+ tcc_add_library_path(s, path);
+ }
+}
+
+static char *default_outputfile(TCCState *s, const char *first_file)
+{
+ char buf[1024];
+ char *ext;
+ const char *name = "a";
+
+ if (first_file && strcmp(first_file, "-"))
+ name = tcc_basename(first_file);
+ snprintf(buf, sizeof(buf), "%s", name);
+ ext = tcc_fileextension(buf);
+#ifdef TCC_TARGET_PE
+ if (s->output_type == TCC_OUTPUT_DLL)
+ strcpy(ext, ".dll");
+ else
+ if (s->output_type == TCC_OUTPUT_EXE)
+ strcpy(ext, ".exe");
+ else
+#endif
+ if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r && *ext)
+ strcpy(ext, ".o");
+ else
+ strcpy(buf, "a.out");
+ return tcc_strdup(buf);
+}
+
+static unsigned getclock_ms(void)
+{
+#ifdef _WIN32
+ return GetTickCount();
+#else
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec*1000 + (tv.tv_usec+500)/1000;
+#endif
+}
+
+int main(int argc0, char **argv0)
+{
+ TCCState *s;
+ int ret, opt, n = 0, t = 0;
+ unsigned start_time = 0;
+ const char *first_file;
+ int argc; char **argv;
+ FILE *ppfp = stdout;
+
+redo:
+ argc = argc0, argv = argv0;
+ s = tcc_new();
+ opt = tcc_parse_args(s, &argc, &argv, 1);
+
+ if ((n | t) == 0) {
+ if (opt == OPT_HELP)
+ return printf(help), 1;
+ if (opt == OPT_HELP2)
+ return printf(help2), 1;
+ if (opt == OPT_M32 || opt == OPT_M64)
+ tcc_tool_cross(s, argv, opt); /* never returns */
+ if (s->verbose)
+ printf(version);
+ if (opt == OPT_AR)
+ return tcc_tool_ar(s, argc, argv);
+#ifdef TCC_TARGET_PE
+ if (opt == OPT_IMPDEF)
+ return tcc_tool_impdef(s, argc, argv);
+#endif
+ if (opt == OPT_V)
+ return 0;
+ if (opt == OPT_PRINT_DIRS) {
+ /* initialize search dirs */
+ set_environment(s);
+ tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
+ print_search_dirs(s);
+ return 0;
+ }
+
+ n = s->nb_files;
+ if (n == 0)
+ tcc_error("no input files\n");
+
+ if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+ if (s->outfile) {
+ ppfp = fopen(s->outfile, "w");
+ if (!ppfp)
+ tcc_error("could not write '%s'", s->outfile);
+ }
+ } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
+ if (s->nb_libraries)
+ tcc_error("cannot specify libraries with -c");
+ if (n > 1 && s->outfile)
+ tcc_error("cannot specify output file with -c many files");
+ } else {
+ if (s->option_pthread)
+ tcc_set_options(s, "-lpthread");
+ }
+
+ if (s->do_bench)
+ start_time = getclock_ms();
+ }
+
+ set_environment(s);
+ if (s->output_type == 0)
+ s->output_type = TCC_OUTPUT_EXE;
+ tcc_set_output_type(s, s->output_type);
+ s->ppfp = ppfp;
+
+ if ((s->output_type == TCC_OUTPUT_MEMORY
+ || s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16))
+ s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files;
+
+ /* compile or add each files or library */
+ for (first_file = NULL, ret = 0;;) {
+ struct filespec *f = s->files[s->nb_files - n];
+ s->filetype = f->type;
+ s->alacarte_link = f->alacarte;
+ if (f->type == AFF_TYPE_LIB) {
+ if (tcc_add_library_err(s, f->name) < 0)
+ ret = 1;
+ } else {
+ if (1 == s->verbose)
+ printf("-> %s\n", f->name);
+ if (!first_file)
+ first_file = f->name;
+ if (tcc_add_file(s, f->name) < 0)
+ ret = 1;
+ }
+ s->filetype = 0;
+ s->alacarte_link = 1;
+ if (--n == 0 || ret
+ || (s->output_type == TCC_OUTPUT_OBJ && !s->option_r))
+ break;
+ }
+
+ if (s->run_test) {
+ t = 0;
+ } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+ ;
+ } else if (0 == ret) {
+ if (s->output_type == TCC_OUTPUT_MEMORY) {
+#ifdef TCC_IS_NATIVE
+ ret = tcc_run(s, argc, argv);
+#endif
+ } else {
+ if (!s->outfile)
+ s->outfile = default_outputfile(s, first_file);
+ if (tcc_output_file(s, s->outfile))
+ ret = 1;
+ else if (s->gen_deps)
+ gen_makedeps(s, s->outfile, s->deps_outfile);
+ }
+ }
+
+ if (s->do_bench && (n | t | ret) == 0)
+ tcc_print_stats(s, getclock_ms() - start_time);
+ tcc_delete(s);
+ if (ret == 0 && n)
+ goto redo; /* compile more files with -c */
+ if (t)
+ goto redo; /* run more tests with -dt -run */
+ if (ppfp && ppfp != stdout)
+ fclose(ppfp);
+ return ret;
+}
diff --git a/tcc.h b/tcc.h
new file mode 100644
index 0000000..cd67973
--- /dev/null
+++ b/tcc.h
@@ -0,0 +1,1660 @@
+/*
+ * TCC - Tiny C Compiler
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _TCC_H
+#define _TCC_H
+
+#define _GNU_SOURCE
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <time.h>
+
+#ifndef _WIN32
+# include <unistd.h>
+# include <sys/time.h>
+# ifndef CONFIG_TCC_STATIC
+# include <dlfcn.h>
+# endif
+/* XXX: need to define this to use them in non ISOC99 context */
+extern float strtof (const char *__nptr, char **__endptr);
+extern long double strtold (const char *__nptr, char **__endptr);
+#endif
+
+#ifdef _WIN32
+# include <windows.h>
+# include <io.h> /* open, close etc. */
+# include <direct.h> /* getcwd */
+# ifdef __GNUC__
+# include <stdint.h>
+# endif
+# define inline __inline
+# define snprintf _snprintf
+# define vsnprintf _vsnprintf
+# ifndef __GNUC__
+# define strtold (long double)strtod
+# define strtof (float)strtod
+# define strtoll _strtoi64
+# define strtoull _strtoui64
+# endif
+# ifdef LIBTCC_AS_DLL
+# define LIBTCCAPI __declspec(dllexport)
+# define PUB_FUNC LIBTCCAPI
+# endif
+# define inp next_inp /* inp is an intrinsic on msvc/mingw */
+# ifdef _MSC_VER
+# pragma warning (disable : 4244) // conversion from 'uint64_t' to 'int', possible loss of data
+# pragma warning (disable : 4267) // conversion from 'size_t' to 'int', possible loss of data
+# pragma warning (disable : 4996) // The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
+# pragma warning (disable : 4018) // signed/unsigned mismatch
+# pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
+# define ssize_t intptr_t
+# endif
+# undef CONFIG_TCC_STATIC
+#endif
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+#ifndef offsetof
+#define offsetof(type, field) ((size_t) &((type *)0)->field)
+#endif
+
+#ifndef countof
+#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
+#endif
+
+#ifdef _MSC_VER
+# define NORETURN __declspec(noreturn)
+# define ALIGNED(x) __declspec(align(x))
+#else
+# define NORETURN __attribute__((noreturn))
+# define ALIGNED(x) __attribute__((aligned(x)))
+#endif
+
+#ifdef _WIN32
+# define IS_DIRSEP(c) (c == '/' || c == '\\')
+# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
+# define PATHCMP stricmp
+# define PATHSEP ";"
+#else
+# define IS_DIRSEP(c) (c == '/')
+# define IS_ABSPATH(p) IS_DIRSEP(p[0])
+# define PATHCMP strcmp
+# define PATHSEP ":"
+#endif
+
+/* -------------------------------------------- */
+
+/* parser debug */
+/* #define PARSE_DEBUG */
+/* preprocessor debug */
+/* #define PP_DEBUG */
+/* include file debug */
+/* #define INC_DEBUG */
+/* memory leak debug */
+/* #define MEM_DEBUG */
+/* assembler debug */
+/* #define ASM_DEBUG */
+
+/* target selection */
+/* #define TCC_TARGET_I386 *//* i386 code generator */
+/* #define TCC_TARGET_X86_64 *//* x86-64 code generator */
+/* #define TCC_TARGET_ARM *//* ARMv4 code generator */
+/* #define TCC_TARGET_ARM64 *//* ARMv8 code generator */
+/* #define TCC_TARGET_C67 *//* TMS320C67xx code generator */
+
+/* default target is I386 */
+#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
+ !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \
+ !defined(TCC_TARGET_X86_64)
+# if defined __x86_64__ || defined _AMD64_
+# define TCC_TARGET_X86_64
+# elif defined __arm__
+# define TCC_TARGET_ARM
+# define TCC_ARM_EABI
+# define TCC_ARM_HARDFLOAT
+# elif defined __aarch64__
+# define TCC_TARGET_ARM64
+# else
+# define TCC_TARGET_I386
+# endif
+# ifdef _WIN32
+# define TCC_TARGET_PE 1
+# endif
+#endif
+
+/* only native compiler supports -run */
+#if defined _WIN32 == defined TCC_TARGET_PE
+# if (defined __i386__ || defined _X86_) && defined TCC_TARGET_I386
+# define TCC_IS_NATIVE
+# elif (defined __x86_64__ || defined _AMD64_) && defined TCC_TARGET_X86_64
+# define TCC_IS_NATIVE
+# elif defined __arm__ && defined TCC_TARGET_ARM
+# define TCC_IS_NATIVE
+# elif defined __aarch64__ && defined TCC_TARGET_ARM64
+# define TCC_IS_NATIVE
+# endif
+#endif
+
+#if defined TCC_IS_NATIVE && !defined CONFIG_TCCBOOT
+# define CONFIG_TCC_BACKTRACE
+# if (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64) \
+ && !defined TCC_UCLIBC && !defined TCC_MUSL
+# define CONFIG_TCC_BCHECK /* enable bound checking code */
+# endif
+#endif
+
+/* ------------ path configuration ------------ */
+
+#ifndef CONFIG_SYSROOT
+# define CONFIG_SYSROOT ""
+#endif
+#ifndef CONFIG_TCCDIR
+# define CONFIG_TCCDIR "/usr/local/lib/tcc"
+#endif
+#ifndef CONFIG_LDDIR
+# define CONFIG_LDDIR "lib"
+#endif
+#ifdef CONFIG_TRIPLET
+# define USE_TRIPLET(s) s "/" CONFIG_TRIPLET
+# define ALSO_TRIPLET(s) USE_TRIPLET(s) ":" s
+#else
+# define USE_TRIPLET(s) s
+# define ALSO_TRIPLET(s) s
+#endif
+
+/* path to find crt1.o, crti.o and crtn.o */
+#ifndef CONFIG_TCC_CRTPREFIX
+# define CONFIG_TCC_CRTPREFIX USE_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR)
+#endif
+
+/* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */
+
+/* system include paths */
+#ifndef CONFIG_TCC_SYSINCLUDEPATHS
+# ifdef TCC_TARGET_PE
+# define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include"PATHSEP"{B}/include/winapi"
+# else
+# define CONFIG_TCC_SYSINCLUDEPATHS \
+ "{B}/include" \
+ ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \
+ ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include")
+# endif
+#endif
+
+/* library search paths */
+#ifndef CONFIG_TCC_LIBPATHS
+# ifdef TCC_TARGET_PE
+# define CONFIG_TCC_LIBPATHS "{B}/lib"
+# else
+# define CONFIG_TCC_LIBPATHS \
+ ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \
+ ":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \
+ ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR)
+# endif
+#endif
+
+/* name of ELF interpreter */
+#ifndef CONFIG_TCC_ELFINTERP
+# if defined __FreeBSD__
+# define CONFIG_TCC_ELFINTERP "/libexec/ld-elf.so.1"
+# elif defined __FreeBSD_kernel__
+# if defined(TCC_TARGET_X86_64)
+# define CONFIG_TCC_ELFINTERP "/lib/ld-kfreebsd-x86-64.so.1"
+# else
+# define CONFIG_TCC_ELFINTERP "/lib/ld.so.1"
+# endif
+# elif defined __DragonFly__
+# define CONFIG_TCC_ELFINTERP "/usr/libexec/ld-elf.so.2"
+# elif defined __NetBSD__
+# define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so"
+# elif defined __GNU__
+# define CONFIG_TCC_ELFINTERP "/lib/ld.so"
+# elif defined(TCC_TARGET_PE)
+# define CONFIG_TCC_ELFINTERP "-"
+# elif defined(TCC_UCLIBC)
+# define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0" /* is there a uClibc for x86_64 ? */
+# elif defined TCC_TARGET_ARM64
+# if defined(TCC_MUSL)
+# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-aarch64.so.1"
+# else
+# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-aarch64.so.1"
+# endif
+# elif defined(TCC_TARGET_X86_64)
+# if defined(TCC_MUSL)
+# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"
+# else
+# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
+# endif
+# elif !defined(TCC_ARM_EABI)
+# if defined(TCC_MUSL)
+# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-arm.so.1"
+# else
+# define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
+# endif
+# endif
+#endif
+
+/* var elf_interp dans *-gen.c */
+#ifdef CONFIG_TCC_ELFINTERP
+# define DEFAULT_ELFINTERP(s) CONFIG_TCC_ELFINTERP
+#else
+# define DEFAULT_ELFINTERP(s) default_elfinterp(s)
+#endif
+
+/* (target specific) libtcc1.a */
+#ifndef TCC_LIBTCC1
+# define TCC_LIBTCC1 "libtcc1.a"
+#endif
+
+/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
+#if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC
+#define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
+#endif
+
+/* -------------------------------------------- */
+
+#include "libtcc.h"
+#include "elf.h"
+#include "stab.h"
+
+/* -------------------------------------------- */
+
+#ifndef PUB_FUNC /* functions used by tcc.c but not in libtcc.h */
+# define PUB_FUNC
+#endif
+
+#ifndef ONE_SOURCE
+# define ONE_SOURCE 1
+#endif
+
+#if ONE_SOURCE
+#define ST_INLN static inline
+#define ST_FUNC static
+#define ST_DATA static
+#else
+#define ST_INLN
+#define ST_FUNC
+#define ST_DATA extern
+#endif
+
+#ifdef TCC_PROFILE /* profile all functions */
+# define static
+#endif
+
+/* -------------------------------------------- */
+/* include the target specific definitions */
+
+#define TARGET_DEFS_ONLY
+#ifdef TCC_TARGET_I386
+# include "i386-gen.c"
+# include "i386-link.c"
+#endif
+#ifdef TCC_TARGET_X86_64
+# include "x86_64-gen.c"
+# include "x86_64-link.c"
+#endif
+#ifdef TCC_TARGET_ARM
+# include "arm-gen.c"
+# include "arm-link.c"
+# include "arm-asm.c"
+#endif
+#ifdef TCC_TARGET_ARM64
+# include "arm64-gen.c"
+# include "arm64-link.c"
+#endif
+#ifdef TCC_TARGET_C67
+# define TCC_TARGET_COFF
+# include "coff.h"
+# include "c67-gen.c"
+# include "c67-link.c"
+#endif
+#undef TARGET_DEFS_ONLY
+
+/* -------------------------------------------- */
+
+#if PTR_SIZE == 8
+# define ELFCLASSW ELFCLASS64
+# define ElfW(type) Elf##64##_##type
+# define ELFW(type) ELF##64##_##type
+# define ElfW_Rel ElfW(Rela)
+# define SHT_RELX SHT_RELA
+# define REL_SECTION_FMT ".rela%s"
+#else
+# define ELFCLASSW ELFCLASS32
+# define ElfW(type) Elf##32##_##type
+# define ELFW(type) ELF##32##_##type
+# define ElfW_Rel ElfW(Rel)
+# define SHT_RELX SHT_REL
+# define REL_SECTION_FMT ".rel%s"
+#endif
+/* target address type */
+#define addr_t ElfW(Addr)
+#define ElfSym ElfW(Sym)
+
+#if PTR_SIZE == 8 && !defined TCC_TARGET_PE
+# define LONG_SIZE 8
+#else
+# define LONG_SIZE 4
+#endif
+
+/* -------------------------------------------- */
+
+#define INCLUDE_STACK_SIZE 32
+#define IFDEF_STACK_SIZE 64
+#define VSTACK_SIZE 256
+#define STRING_MAX_SIZE 1024
+#define TOKSTR_MAX_SIZE 256
+#define PACK_STACK_SIZE 8
+
+#define TOK_HASH_SIZE 16384 /* must be a power of two */
+#define TOK_ALLOC_INCR 512 /* must be a power of two */
+#define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
+
+/* token symbol management */
+typedef struct TokenSym {
+ struct TokenSym *hash_next;
+ struct Sym *sym_define; /* direct pointer to define */
+ struct Sym *sym_label; /* direct pointer to label */
+ struct Sym *sym_struct; /* direct pointer to structure */
+ struct Sym *sym_identifier; /* direct pointer to identifier */
+ int tok; /* token number */
+ int len;
+ char str[1];
+} TokenSym;
+
+#ifdef TCC_TARGET_PE
+typedef unsigned short nwchar_t;
+#else
+typedef int nwchar_t;
+#endif
+
+typedef struct CString {
+ int size; /* size in bytes */
+ void *data; /* either 'char *' or 'nwchar_t *' */
+ int size_allocated;
+} CString;
+
+/* type definition */
+typedef struct CType {
+ int t;
+ struct Sym *ref;
+} CType;
+
+/* constant value */
+typedef union CValue {
+ long double ld;
+ double d;
+ float f;
+ uint64_t i;
+ struct {
+ int size;
+ const void *data;
+ } str;
+ int tab[LDOUBLE_SIZE/4];
+} CValue;
+
+/* value on stack */
+typedef struct SValue {
+ CType type; /* type */
+ unsigned short r; /* register + flags */
+ unsigned short r2; /* second register, used for 'long long'
+ type. If not used, set to VT_CONST */
+ CValue c; /* constant, if VT_CONST */
+ struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST), or if
+ result of unary() for an identifier. */
+} SValue;
+
+/* symbol attributes */
+struct SymAttr {
+ unsigned short
+ aligned : 5, /* alignment as log2+1 (0 == unspecified) */
+ packed : 1,
+ weak : 1,
+ visibility : 2,
+ dllexport : 1,
+ dllimport : 1,
+ unused : 5;
+};
+
+/* function attributes or temporary attributes for parsing */
+struct FuncAttr {
+ unsigned
+ func_call : 3, /* calling convention (0..5), see below */
+ func_type : 2, /* FUNC_OLD/NEW/ELLIPSIS */
+ func_args : 8; /* PE __stdcall args */
+};
+
+/* GNUC attribute definition */
+typedef struct AttributeDef {
+ struct SymAttr a;
+ struct FuncAttr f;
+ struct Section *section;
+ int alias_target; /* token */
+ int asm_label; /* associated asm label */
+ char attr_mode; /* __attribute__((__mode__(...))) */
+} AttributeDef;
+
+/* symbol management */
+typedef struct Sym {
+ int v; /* symbol token */
+ unsigned short r; /* associated register or VT_CONST/VT_LOCAL and LVAL type */
+ struct SymAttr a; /* symbol attributes */
+ union {
+ struct {
+ int c; /* associated number or Elf symbol index */
+ union {
+ int sym_scope; /* scope level for locals */
+ int jnext; /* next jump label */
+ struct FuncAttr f; /* function attributes */
+ int auxtype; /* bitfield access type */
+ };
+ };
+ long long enum_val; /* enum constant if IS_ENUM_VAL */
+ int *d; /* define token stream */
+ };
+ CType type; /* associated type */
+ union {
+ struct Sym *next; /* next related symbol (for fields and anoms) */
+ int asm_label; /* associated asm label */
+ };
+ struct Sym *prev; /* prev symbol in stack */
+ struct Sym *prev_tok; /* previous symbol for this token */
+} Sym;
+
+/* section definition */
+typedef struct Section {
+ unsigned long data_offset; /* current data offset */
+ unsigned char *data; /* section data */
+ unsigned long data_allocated; /* used for realloc() handling */
+ int sh_name; /* elf section name (only used during output) */
+ int sh_num; /* elf section number */
+ int sh_type; /* elf section type */
+ int sh_flags; /* elf section flags */
+ int sh_info; /* elf section info */
+ int sh_addralign; /* elf section alignment */
+ int sh_entsize; /* elf entry size */
+ unsigned long sh_size; /* section size (only used during output) */
+ addr_t sh_addr; /* address at which the section is relocated */
+ unsigned long sh_offset; /* file offset */
+ int nb_hashed_syms; /* used to resize the hash table */
+ struct Section *link; /* link to another section */
+ struct Section *reloc; /* corresponding section for relocation, if any */
+ struct Section *hash; /* hash table for symbols */
+ struct Section *prev; /* previous section on section stack */
+ char name[1]; /* section name */
+} Section;
+
+typedef struct DLLReference {
+ int level;
+ void *handle;
+ char name[1];
+} DLLReference;
+
+/* -------------------------------------------------- */
+
+#define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
+#define SYM_FIELD 0x20000000 /* struct/union field symbol space */
+#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
+
+/* stored in 'Sym->f.func_type' field */
+#define FUNC_NEW 1 /* ansi function prototype */
+#define FUNC_OLD 2 /* old function prototype */
+#define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
+
+/* stored in 'Sym->f.func_call' field */
+#define FUNC_CDECL 0 /* standard c call */
+#define FUNC_STDCALL 1 /* pascal c call */
+#define FUNC_FASTCALL1 2 /* first param in %eax */
+#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
+#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
+#define FUNC_FASTCALLW 5 /* first parameter in %ecx, %edx */
+
+/* field 'Sym.t' for macros */
+#define MACRO_OBJ 0 /* object like macro */
+#define MACRO_FUNC 1 /* function like macro */
+
+/* field 'Sym.r' for C labels */
+#define LABEL_DEFINED 0 /* label is defined */
+#define LABEL_FORWARD 1 /* label is forward defined */
+#define LABEL_DECLARED 2 /* label is declared but never used */
+
+/* type_decl() types */
+#define TYPE_ABSTRACT 1 /* type without variable */
+#define TYPE_DIRECT 2 /* type with variable */
+
+#define IO_BUF_SIZE 8192
+
+typedef struct BufferedFile {
+ uint8_t *buf_ptr;
+ uint8_t *buf_end;
+ int fd;
+ struct BufferedFile *prev;
+ int line_num; /* current line number - here to simplify code */
+ int line_ref; /* tcc -E: last printed line */
+ int ifndef_macro; /* #ifndef macro / #endif search */
+ int ifndef_macro_saved; /* saved ifndef_macro */
+ int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
+ int include_next_index; /* next search path */
+ char filename[1024]; /* filename */
+ char *true_filename; /* filename not modified by # line directive */
+ unsigned char unget[4];
+ unsigned char buffer[1]; /* extra size for CH_EOB char */
+} BufferedFile;
+
+#define CH_EOB '\\' /* end of buffer or '\0' char in file */
+#define CH_EOF (-1) /* end of file */
+
+/* used to record tokens */
+typedef struct TokenString {
+ int *str;
+ int len;
+ int lastlen;
+ int allocated_len;
+ int last_line_num;
+ int save_line_num;
+ /* used to chain token-strings with begin/end_macro() */
+ struct TokenString *prev;
+ const int *prev_ptr;
+ char alloc;
+} TokenString;
+
+/* inline functions */
+typedef struct InlineFunc {
+ TokenString *func_str;
+ Sym *sym;
+ char filename[1];
+} InlineFunc;
+
+/* include file cache, used to find files faster and also to eliminate
+ inclusion if the include file is protected by #ifndef ... #endif */
+typedef struct CachedInclude {
+ int ifndef_macro;
+ int once;
+ int hash_next; /* -1 if none */
+ char filename[1]; /* path specified in #include */
+} CachedInclude;
+
+#define CACHED_INCLUDES_HASH_SIZE 32
+
+#ifdef CONFIG_TCC_ASM
+typedef struct ExprValue {
+ uint64_t v;
+ Sym *sym;
+ int pcrel;
+} ExprValue;
+
+#define MAX_ASM_OPERANDS 30
+typedef struct ASMOperand {
+ int id; /* GCC 3 optional identifier (0 if number only supported */
+ char *constraint;
+ char asm_str[16]; /* computed asm string for operand */
+ SValue *vt; /* C value of the expression */
+ int ref_index; /* if >= 0, gives reference to a output constraint */
+ int input_index; /* if >= 0, gives reference to an input constraint */
+ int priority; /* priority, used to assign registers */
+ int reg; /* if >= 0, register number used for this operand */
+ int is_llong; /* true if double register value */
+ int is_memory; /* true if memory operand */
+ int is_rw; /* for '+' modifier */
+} ASMOperand;
+#endif
+
+/* extra symbol attributes (not in symbol table) */
+struct sym_attr {
+ unsigned got_offset;
+ unsigned plt_offset;
+ int plt_sym;
+ int dyn_index;
+#ifdef TCC_TARGET_ARM
+ unsigned char plt_thumb_stub:1;
+#endif
+};
+
+struct TCCState {
+
+ int verbose; /* if true, display some information during compilation */
+ int nostdinc; /* if true, no standard headers are added */
+ int nostdlib; /* if true, no standard libraries are added */
+ int nocommon; /* if true, do not use common symbols for .bss data */
+ int static_link; /* if true, static linking is performed */
+ int rdynamic; /* if true, all symbols are exported */
+ int symbolic; /* if true, resolve symbols in the current module first */
+ int alacarte_link; /* if true, only link in referenced objects from archive */
+
+ char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */
+ char *soname; /* as specified on the command line (-soname) */
+ char *rpath; /* as specified on the command line (-Wl,-rpath=) */
+ int enable_new_dtags; /* ditto, (-Wl,--enable-new-dtags) */
+
+ /* output type, see TCC_OUTPUT_XXX */
+ int output_type;
+ /* output format, see TCC_OUTPUT_FORMAT_xxx */
+ int output_format;
+
+ /* C language options */
+ int char_is_unsigned;
+ int leading_underscore;
+ int ms_extensions; /* allow nested named struct w/o identifier behave like unnamed */
+ int dollars_in_identifiers; /* allows '$' char in identifiers */
+ int ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
+
+ /* warning switches */
+ int warn_write_strings;
+ int warn_unsupported;
+ int warn_error;
+ int warn_none;
+ int warn_implicit_function_declaration;
+ int warn_gcc_compat;
+
+ /* compile with debug symbol (and use them if error during execution) */
+ int do_debug;
+#ifdef CONFIG_TCC_BCHECK
+ /* compile with built-in memory and bounds checker */
+ int do_bounds_check;
+#endif
+#ifdef TCC_TARGET_ARM
+ enum float_abi float_abi; /* float ABI of the generated code*/
+#endif
+ int run_test; /* nth test to run with -dt -run */
+
+ addr_t text_addr; /* address of text section */
+ int has_text_addr;
+
+ unsigned section_align; /* section alignment */
+
+ char *init_symbol; /* symbols to call at load-time (not used currently) */
+ char *fini_symbol; /* symbols to call at unload-time (not used currently) */
+
+#ifdef TCC_TARGET_I386
+ int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
+#endif
+#ifdef TCC_TARGET_X86_64
+ int nosse; /* For -mno-sse support. */
+#endif
+
+ /* array of all loaded dlls (including those referenced by loaded dlls) */
+ DLLReference **loaded_dlls;
+ int nb_loaded_dlls;
+
+ /* include paths */
+ char **include_paths;
+ int nb_include_paths;
+
+ char **sysinclude_paths;
+ int nb_sysinclude_paths;
+
+ /* library paths */
+ char **library_paths;
+ int nb_library_paths;
+
+ /* crt?.o object path */
+ char **crt_paths;
+ int nb_crt_paths;
+
+ /* -include files */
+ char **cmd_include_files;
+ int nb_cmd_include_files;
+
+ /* error handling */
+ void *error_opaque;
+ void (*error_func)(void *opaque, const char *msg);
+ int error_set_jmp_enabled;
+ jmp_buf error_jmp_buf;
+ int nb_errors;
+
+ /* output file for preprocessing (-E) */
+ FILE *ppfp;
+ enum {
+ LINE_MACRO_OUTPUT_FORMAT_GCC,
+ LINE_MACRO_OUTPUT_FORMAT_NONE,
+ LINE_MACRO_OUTPUT_FORMAT_STD,
+ LINE_MACRO_OUTPUT_FORMAT_P10 = 11
+ } Pflag; /* -P switch */
+ char dflag; /* -dX value */
+
+ /* for -MD/-MF: collected dependencies for this compilation */
+ char **target_deps;
+ int nb_target_deps;
+
+ /* compilation */
+ BufferedFile *include_stack[INCLUDE_STACK_SIZE];
+ BufferedFile **include_stack_ptr;
+
+ int ifdef_stack[IFDEF_STACK_SIZE];
+ int *ifdef_stack_ptr;
+
+ /* included files enclosed with #ifndef MACRO */
+ int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE];
+ CachedInclude **cached_includes;
+ int nb_cached_includes;
+
+ /* #pragma pack stack */
+ int pack_stack[PACK_STACK_SIZE];
+ int *pack_stack_ptr;
+ char **pragma_libs;
+ int nb_pragma_libs;
+
+ /* inline functions are stored as token lists and compiled last
+ only if referenced */
+ struct InlineFunc **inline_fns;
+ int nb_inline_fns;
+
+ /* sections */
+ Section **sections;
+ int nb_sections; /* number of sections, including first dummy section */
+
+ Section **priv_sections;
+ int nb_priv_sections; /* number of private sections */
+
+ /* got & plt handling */
+ Section *got;
+ Section *plt;
+
+ /* temporary dynamic symbol sections (for dll loading) */
+ Section *dynsymtab_section;
+ /* exported dynamic symbol section */
+ Section *dynsym;
+ /* copy of the global symtab_section variable */
+ Section *symtab;
+ /* extra attributes (eg. GOT/PLT value) for symtab symbols */
+ struct sym_attr *sym_attrs;
+ int nb_sym_attrs;
+
+#ifdef TCC_TARGET_PE
+ /* PE info */
+ int pe_subsystem;
+ unsigned pe_characteristics;
+ unsigned pe_file_align;
+ unsigned pe_stack_size;
+ addr_t pe_imagebase;
+# ifdef TCC_TARGET_X86_64
+ Section *uw_pdata;
+ int uw_sym;
+ unsigned uw_offs;
+# endif
+#endif
+
+#ifdef TCC_IS_NATIVE
+ const char *runtime_main;
+ void **runtime_mem;
+ int nb_runtime_mem;
+#endif
+
+ /* used by main and tcc_parse_args only */
+ struct filespec **files; /* files seen on command line */
+ int nb_files; /* number thereof */
+ int nb_libraries; /* number of libs thereof */
+ int filetype;
+ char *outfile; /* output filename */
+ int option_r; /* option -r */
+ int do_bench; /* option -bench */
+ int gen_deps; /* option -MD */
+ char *deps_outfile; /* option -MF */
+ int option_pthread; /* -pthread option */
+ int argc;
+ char **argv;
+};
+
+struct filespec {
+ char type;
+ char alacarte;
+ char name[1];
+};
+
+/* The current value can be: */
+#define VT_VALMASK 0x003f /* mask for value location, register or: */
+#define VT_CONST 0x0030 /* constant in vc (must be first non register value) */
+#define VT_LLOCAL 0x0031 /* lvalue, offset on stack */
+#define VT_LOCAL 0x0032 /* offset on stack */
+#define VT_CMP 0x0033 /* the value is stored in processor flags (in vc) */
+#define VT_JMP 0x0034 /* value is the consequence of jmp true (even) */
+#define VT_JMPI 0x0035 /* value is the consequence of jmp false (odd) */
+#define VT_LVAL 0x0100 /* var is an lvalue */
+#define VT_SYM 0x0200 /* a symbol value is added */
+#define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
+ char/short stored in integer registers) */
+#define VT_MUSTBOUND 0x0800 /* bound checking must be done before
+ dereferencing value */
+#define VT_BOUNDED 0x8000 /* value is bounded. The address of the
+ bounding function call point is in vc */
+#define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
+#define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
+#define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
+#define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
+
+/* types */
+#define VT_BTYPE 0x000f /* mask for basic type */
+#define VT_VOID 0 /* void type */
+#define VT_BYTE 1 /* signed byte type */
+#define VT_SHORT 2 /* short type */
+#define VT_INT 3 /* integer type */
+#define VT_LLONG 4 /* 64 bit integer */
+#define VT_PTR 5 /* pointer */
+#define VT_FUNC 6 /* function type */
+#define VT_STRUCT 7 /* struct/union definition */
+#define VT_FLOAT 8 /* IEEE float */
+#define VT_DOUBLE 9 /* IEEE double */
+#define VT_LDOUBLE 10 /* IEEE long double */
+#define VT_BOOL 11 /* ISOC99 boolean type */
+#define VT_QLONG 13 /* 128-bit integer. Only used for x86-64 ABI */
+#define VT_QFLOAT 14 /* 128-bit float. Only used for x86-64 ABI */
+
+#define VT_UNSIGNED 0x0010 /* unsigned type */
+#define VT_DEFSIGN 0x0020 /* explicitly signed or unsigned */
+#define VT_ARRAY 0x0040 /* array type (also has VT_PTR) */
+#define VT_BITFIELD 0x0080 /* bitfield modifier */
+#define VT_CONSTANT 0x0100 /* const modifier */
+#define VT_VOLATILE 0x0200 /* volatile modifier */
+#define VT_VLA 0x0400 /* VLA type (also has VT_PTR and VT_ARRAY) */
+#define VT_LONG 0x0800 /* long type (also has VT_INT rsp. VT_LLONG) */
+
+/* storage */
+#define VT_EXTERN 0x00001000 /* extern definition */
+#define VT_STATIC 0x00002000 /* static variable */
+#define VT_TYPEDEF 0x00004000 /* typedef definition */
+#define VT_INLINE 0x00008000 /* inline definition */
+/* currently unused: 0x000[1248]0000 */
+
+#define VT_STRUCT_SHIFT 20 /* shift for bitfield shift values (32 - 2*6) */
+#define VT_STRUCT_MASK (((1 << (6+6)) - 1) << VT_STRUCT_SHIFT | VT_BITFIELD)
+#define BIT_POS(t) (((t) >> VT_STRUCT_SHIFT) & 0x3f)
+#define BIT_SIZE(t) (((t) >> (VT_STRUCT_SHIFT + 6)) & 0x3f)
+
+#define VT_UNION (1 << VT_STRUCT_SHIFT | VT_STRUCT)
+#define VT_ENUM (2 << VT_STRUCT_SHIFT) /* integral type is an enum really */
+#define VT_ENUM_VAL (3 << VT_STRUCT_SHIFT) /* integral type is an enum constant really */
+
+#define IS_ENUM(t) ((t & VT_STRUCT_MASK) == VT_ENUM)
+#define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL)
+#define IS_UNION(t) ((t & (VT_STRUCT_MASK|VT_BTYPE)) == VT_UNION)
+
+/* type mask (except storage) */
+#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
+#define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))
+
+/* symbol was created by tccasm.c first */
+#define VT_ASM (VT_VOID | VT_UNSIGNED)
+#define IS_ASM_SYM(sym) (((sym)->type.t & (VT_BTYPE | VT_ASM)) == VT_ASM)
+
+/* token values */
+
+/* warning: the following compare tokens depend on i386 asm code */
+#define TOK_ULT 0x92
+#define TOK_UGE 0x93
+#define TOK_EQ 0x94
+#define TOK_NE 0x95
+#define TOK_ULE 0x96
+#define TOK_UGT 0x97
+#define TOK_Nset 0x98
+#define TOK_Nclear 0x99
+#define TOK_LT 0x9c
+#define TOK_GE 0x9d
+#define TOK_LE 0x9e
+#define TOK_GT 0x9f
+
+#define TOK_LAND 0xa0
+#define TOK_LOR 0xa1
+#define TOK_DEC 0xa2
+#define TOK_MID 0xa3 /* inc/dec, to void constant */
+#define TOK_INC 0xa4
+#define TOK_UDIV 0xb0 /* unsigned division */
+#define TOK_UMOD 0xb1 /* unsigned modulo */
+#define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
+
+/* tokens that carry values (in additional token string space / tokc) --> */
+#define TOK_CCHAR 0xb3 /* char constant in tokc */
+#define TOK_LCHAR 0xb4
+#define TOK_CINT 0xb5 /* number in tokc */
+#define TOK_CUINT 0xb6 /* unsigned int constant */
+#define TOK_CLLONG 0xb7 /* long long constant */
+#define TOK_CULLONG 0xb8 /* unsigned long long constant */
+#define TOK_STR 0xb9 /* pointer to string in tokc */
+#define TOK_LSTR 0xba
+#define TOK_CFLOAT 0xbb /* float constant */
+#define TOK_CDOUBLE 0xbc /* double constant */
+#define TOK_CLDOUBLE 0xbd /* long double constant */
+#define TOK_PPNUM 0xbe /* preprocessor number */
+#define TOK_PPSTR 0xbf /* preprocessor string */
+#define TOK_LINENUM 0xc0 /* line number info */
+#define TOK_TWODOTS 0xa8 /* C++ token ? */
+/* <-- */
+
+#define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
+#define TOK_ADDC1 0xc3 /* add with carry generation */
+#define TOK_ADDC2 0xc4 /* add with carry use */
+#define TOK_SUBC1 0xc5 /* add with carry generation */
+#define TOK_SUBC2 0xc6 /* add with carry use */
+#define TOK_ARROW 0xc7
+#define TOK_DOTS 0xc8 /* three dots */
+#define TOK_SHR 0xc9 /* unsigned shift right */
+#define TOK_TWOSHARPS 0xca /* ## preprocessing token */
+#define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */
+#define TOK_NOSUBST 0xcc /* means following token has already been pp'd */
+#define TOK_PPJOIN 0xcd /* A '##' in the right position to mean pasting */
+#define TOK_CLONG 0xce /* long constant */
+#define TOK_CULONG 0xcf /* unsigned long constant */
+
+#define TOK_SHL 0x01 /* shift left */
+#define TOK_SAR 0x02 /* signed shift right */
+
+/* assignment operators : normal operator or 0x80 */
+#define TOK_A_MOD 0xa5
+#define TOK_A_AND 0xa6
+#define TOK_A_MUL 0xaa
+#define TOK_A_ADD 0xab
+#define TOK_A_SUB 0xad
+#define TOK_A_DIV 0xaf
+#define TOK_A_XOR 0xde
+#define TOK_A_OR 0xfc
+#define TOK_A_SHL 0x81
+#define TOK_A_SAR 0x82
+
+#define TOK_EOF (-1) /* end of file */
+#define TOK_LINEFEED 10 /* line feed */
+
+/* all identifiers and strings have token above that */
+#define TOK_IDENT 256
+
+#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
+#define TOK_ASM_int TOK_INT
+#define DEF_ASMDIR(x) DEF(TOK_ASMDIR_ ## x, "." #x)
+#define TOK_ASMDIR_FIRST TOK_ASMDIR_byte
+#define TOK_ASMDIR_LAST TOK_ASMDIR_section
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+/* only used for i386 asm opcodes definitions */
+#define DEF_BWL(x) \
+ DEF(TOK_ASM_ ## x ## b, #x "b") \
+ DEF(TOK_ASM_ ## x ## w, #x "w") \
+ DEF(TOK_ASM_ ## x ## l, #x "l") \
+ DEF(TOK_ASM_ ## x, #x)
+#define DEF_WL(x) \
+ DEF(TOK_ASM_ ## x ## w, #x "w") \
+ DEF(TOK_ASM_ ## x ## l, #x "l") \
+ DEF(TOK_ASM_ ## x, #x)
+#ifdef TCC_TARGET_X86_64
+# define DEF_BWLQ(x) \
+ DEF(TOK_ASM_ ## x ## b, #x "b") \
+ DEF(TOK_ASM_ ## x ## w, #x "w") \
+ DEF(TOK_ASM_ ## x ## l, #x "l") \
+ DEF(TOK_ASM_ ## x ## q, #x "q") \
+ DEF(TOK_ASM_ ## x, #x)
+# define DEF_WLQ(x) \
+ DEF(TOK_ASM_ ## x ## w, #x "w") \
+ DEF(TOK_ASM_ ## x ## l, #x "l") \
+ DEF(TOK_ASM_ ## x ## q, #x "q") \
+ DEF(TOK_ASM_ ## x, #x)
+# define DEF_BWLX DEF_BWLQ
+# define DEF_WLX DEF_WLQ
+/* number of sizes + 1 */
+# define NBWLX 5
+#else
+# define DEF_BWLX DEF_BWL
+# define DEF_WLX DEF_WL
+/* number of sizes + 1 */
+# define NBWLX 4
+#endif
+
+#define DEF_FP1(x) \
+ DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
+ DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
+ DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
+ DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
+
+#define DEF_FP(x) \
+ DEF(TOK_ASM_ ## f ## x, "f" #x ) \
+ DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
+ DEF_FP1(x)
+
+#define DEF_ASMTEST(x,suffix) \
+ DEF_ASM(x ## o ## suffix) \
+ DEF_ASM(x ## no ## suffix) \
+ DEF_ASM(x ## b ## suffix) \
+ DEF_ASM(x ## c ## suffix) \
+ DEF_ASM(x ## nae ## suffix) \
+ DEF_ASM(x ## nb ## suffix) \
+ DEF_ASM(x ## nc ## suffix) \
+ DEF_ASM(x ## ae ## suffix) \
+ DEF_ASM(x ## e ## suffix) \
+ DEF_ASM(x ## z ## suffix) \
+ DEF_ASM(x ## ne ## suffix) \
+ DEF_ASM(x ## nz ## suffix) \
+ DEF_ASM(x ## be ## suffix) \
+ DEF_ASM(x ## na ## suffix) \
+ DEF_ASM(x ## nbe ## suffix) \
+ DEF_ASM(x ## a ## suffix) \
+ DEF_ASM(x ## s ## suffix) \
+ DEF_ASM(x ## ns ## suffix) \
+ DEF_ASM(x ## p ## suffix) \
+ DEF_ASM(x ## pe ## suffix) \
+ DEF_ASM(x ## np ## suffix) \
+ DEF_ASM(x ## po ## suffix) \
+ DEF_ASM(x ## l ## suffix) \
+ DEF_ASM(x ## nge ## suffix) \
+ DEF_ASM(x ## nl ## suffix) \
+ DEF_ASM(x ## ge ## suffix) \
+ DEF_ASM(x ## le ## suffix) \
+ DEF_ASM(x ## ng ## suffix) \
+ DEF_ASM(x ## nle ## suffix) \
+ DEF_ASM(x ## g ## suffix)
+
+#endif /* defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 */
+
+enum tcc_token {
+ TOK_LAST = TOK_IDENT - 1
+#define DEF(id, str) ,id
+#include "tcctok.h"
+#undef DEF
+};
+
+/* keywords: tok >= TOK_IDENT && tok < TOK_UIDENT */
+#define TOK_UIDENT TOK_DEFINE
+
+/* ------------ libtcc.c ------------ */
+
+/* use GNU C extensions */
+ST_DATA int gnu_ext;
+/* use Tiny C extensions */
+ST_DATA int tcc_ext;
+/* XXX: get rid of this ASAP */
+ST_DATA struct TCCState *tcc_state;
+
+/* public functions currently used by the tcc main function */
+ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s);
+ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s);
+ST_FUNC char *pstrncpy(char *out, const char *in, size_t num);
+PUB_FUNC char *tcc_basename(const char *name);
+PUB_FUNC char *tcc_fileextension (const char *name);
+
+#ifndef MEM_DEBUG
+PUB_FUNC void tcc_free(void *ptr);
+PUB_FUNC void *tcc_malloc(unsigned long size);
+PUB_FUNC void *tcc_mallocz(unsigned long size);
+PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
+PUB_FUNC char *tcc_strdup(const char *str);
+#else
+#define tcc_free(ptr) tcc_free_debug(ptr)
+#define tcc_malloc(size) tcc_malloc_debug(size, __FILE__, __LINE__)
+#define tcc_mallocz(size) tcc_mallocz_debug(size, __FILE__, __LINE__)
+#define tcc_realloc(ptr,size) tcc_realloc_debug(ptr, size, __FILE__, __LINE__)
+#define tcc_strdup(str) tcc_strdup_debug(str, __FILE__, __LINE__)
+PUB_FUNC void tcc_free_debug(void *ptr);
+PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line);
+PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line);
+PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line);
+PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
+#endif
+
+#define free(p) use_tcc_free(p)
+#define malloc(s) use_tcc_malloc(s)
+#define realloc(p, s) use_tcc_realloc(p, s)
+#undef strdup
+#define strdup(s) use_tcc_strdup(s)
+PUB_FUNC void tcc_memcheck(void);
+PUB_FUNC void tcc_error_noabort(const char *fmt, ...);
+PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
+PUB_FUNC void tcc_warning(const char *fmt, ...);
+
+/* other utilities */
+ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data);
+ST_FUNC void dynarray_reset(void *pp, int *n);
+ST_INLN void cstr_ccat(CString *cstr, int ch);
+ST_FUNC void cstr_cat(CString *cstr, const char *str, int len);
+ST_FUNC void cstr_wccat(CString *cstr, int ch);
+ST_FUNC void cstr_new(CString *cstr);
+ST_FUNC void cstr_free(CString *cstr);
+ST_FUNC void cstr_reset(CString *cstr);
+
+ST_INLN void sym_free(Sym *sym);
+ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c);
+ST_FUNC Sym *sym_find2(Sym *s, int v);
+ST_FUNC Sym *sym_push(int v, CType *type, int r, int c);
+ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep);
+ST_INLN Sym *struct_find(int v);
+ST_INLN Sym *sym_find(int v);
+ST_FUNC Sym *global_identifier_push(int v, int t, int c);
+
+ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen);
+ST_FUNC int tcc_open(TCCState *s1, const char *filename);
+ST_FUNC void tcc_close(void);
+
+ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags);
+/* flags: */
+#define AFF_PRINT_ERROR 0x10 /* print error if file not found */
+#define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */
+#define AFF_TYPE_BIN 0x40 /* file to add is binary */
+/* s->filetype: */
+#define AFF_TYPE_NONE 0
+#define AFF_TYPE_C 1
+#define AFF_TYPE_ASM 2
+#define AFF_TYPE_ASMPP 3
+#define AFF_TYPE_LIB 4
+/* values from tcc_object_type(...) */
+#define AFF_BINTYPE_REL 1
+#define AFF_BINTYPE_DYN 2
+#define AFF_BINTYPE_AR 3
+#define AFF_BINTYPE_C67 4
+
+
+ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
+ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
+ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
+PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);
+PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time);
+PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind);
+#ifdef _WIN32
+ST_FUNC char *normalize_slashes(char *path);
+#endif
+
+/* tcc_parse_args return codes: */
+#define OPT_HELP 1
+#define OPT_HELP2 2
+#define OPT_V 3
+#define OPT_PRINT_DIRS 4
+#define OPT_AR 5
+#define OPT_IMPDEF 6
+#define OPT_M32 32
+#define OPT_M64 64
+
+/* ------------ tccpp.c ------------ */
+
+ST_DATA struct BufferedFile *file;
+ST_DATA int ch, tok;
+ST_DATA CValue tokc;
+ST_DATA const int *macro_ptr;
+ST_DATA int parse_flags;
+ST_DATA int tok_flags;
+ST_DATA CString tokcstr; /* current parsed string, if any */
+
+/* display benchmark infos */
+ST_DATA int total_lines;
+ST_DATA int total_bytes;
+ST_DATA int tok_ident;
+ST_DATA TokenSym **table_ident;
+
+#define TOK_FLAG_BOL 0x0001 /* beginning of line before */
+#define TOK_FLAG_BOF 0x0002 /* beginning of file before */
+#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
+#define TOK_FLAG_EOF 0x0008 /* end of file */
+
+#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
+#define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
+#define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
+ token. line feed is also
+ returned at eof */
+#define PARSE_FLAG_ASM_FILE 0x0008 /* we processing an asm file: '#' can be used for line comment, etc. */
+#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
+#define PARSE_FLAG_ACCEPT_STRAYS 0x0020 /* next() returns '\\' token */
+#define PARSE_FLAG_TOK_STR 0x0040 /* return parsed strings instead of TOK_PPSTR */
+
+/* isidnum_table flags: */
+#define IS_SPC 1
+#define IS_ID 2
+#define IS_NUM 4
+
+ST_FUNC TokenSym *tok_alloc(const char *str, int len);
+ST_FUNC const char *get_tok_str(int v, CValue *cv);
+ST_FUNC void begin_macro(TokenString *str, int alloc);
+ST_FUNC void end_macro(void);
+ST_FUNC int set_idnum(int c, int val);
+ST_INLN void tok_str_new(TokenString *s);
+ST_FUNC TokenString *tok_str_alloc(void);
+ST_FUNC void tok_str_free(TokenString *s);
+ST_FUNC void tok_str_free_str(int *str);
+ST_FUNC void tok_str_add(TokenString *s, int t);
+ST_FUNC void tok_str_add_tok(TokenString *s);
+ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg);
+ST_FUNC void define_undef(Sym *s);
+ST_INLN Sym *define_find(int v);
+ST_FUNC void free_defines(Sym *b);
+ST_FUNC Sym *label_find(int v);
+ST_FUNC Sym *label_push(Sym **ptop, int v, int flags);
+ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep);
+ST_FUNC void parse_define(void);
+ST_FUNC void preprocess(int is_bof);
+ST_FUNC void next_nomacro(void);
+ST_FUNC void next(void);
+ST_INLN void unget_tok(int last_tok);
+ST_FUNC void preprocess_start(TCCState *s1, int is_asm);
+ST_FUNC void preprocess_end(TCCState *s1);
+ST_FUNC void tccpp_new(TCCState *s);
+ST_FUNC void tccpp_delete(TCCState *s);
+ST_FUNC int tcc_preprocess(TCCState *s1);
+ST_FUNC void skip(int c);
+ST_FUNC NORETURN void expect(const char *msg);
+
+/* space excluding newline */
+static inline int is_space(int ch) {
+ return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
+}
+static inline int isid(int c) {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
+}
+static inline int isnum(int c) {
+ return c >= '0' && c <= '9';
+}
+static inline int isoct(int c) {
+ return c >= '0' && c <= '7';
+}
+static inline int toup(int c) {
+ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
+}
+
+/* ------------ tccgen.c ------------ */
+
+#define SYM_POOL_NB (8192 / sizeof(Sym))
+ST_DATA Sym *sym_free_first;
+ST_DATA void **sym_pools;
+ST_DATA int nb_sym_pools;
+
+ST_DATA Sym *global_stack;
+ST_DATA Sym *local_stack;
+ST_DATA Sym *local_label_stack;
+ST_DATA Sym *global_label_stack;
+ST_DATA Sym *define_stack;
+ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
+ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop, *pvtop;
+#define vstack (__vstack + 1)
+ST_DATA int rsym, anon_sym, ind, loc;
+
+ST_DATA int const_wanted; /* true if constant wanted */
+ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
+ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
+ST_DATA CType func_vt; /* current function return type (used by return instruction) */
+ST_DATA int func_var; /* true if current function is variadic */
+ST_DATA int func_vc;
+ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
+ST_DATA const char *funcname;
+ST_DATA int g_debug;
+
+ST_FUNC void tcc_debug_start(TCCState *s1);
+ST_FUNC void tcc_debug_end(TCCState *s1);
+ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym);
+ST_FUNC void tcc_debug_funcend(TCCState *s1, int size);
+ST_FUNC void tcc_debug_line(TCCState *s1);
+
+ST_FUNC int tccgen_compile(TCCState *s1);
+ST_FUNC void free_inline_functions(TCCState *s);
+ST_FUNC void check_vstack(void);
+
+ST_INLN int is_float(int t);
+ST_FUNC int ieee_finite(double d);
+ST_FUNC void test_lvalue(void);
+ST_FUNC void vpushi(int v);
+ST_FUNC ElfSym *elfsym(Sym *);
+ST_FUNC void update_storage(Sym *sym);
+ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
+ST_FUNC void vset(CType *type, int r, int v);
+ST_FUNC void vswap(void);
+ST_FUNC void vpush_global_sym(CType *type, int v);
+ST_FUNC void vrote(SValue *e, int n);
+ST_FUNC void vrott(int n);
+ST_FUNC void vrotb(int n);
+#ifdef TCC_TARGET_ARM
+ST_FUNC int get_reg_ex(int rc, int rc2);
+ST_FUNC void lexpand_nr(void);
+#endif
+ST_FUNC void vpushv(SValue *v);
+ST_FUNC void save_reg(int r);
+ST_FUNC void save_reg_upstack(int r, int n);
+ST_FUNC int get_reg(int rc);
+ST_FUNC void save_regs(int n);
+ST_FUNC void gaddrof(void);
+ST_FUNC int gv(int rc);
+ST_FUNC void gv2(int rc1, int rc2);
+ST_FUNC void vpop(void);
+ST_FUNC void gen_op(int op);
+ST_FUNC int type_size(CType *type, int *a);
+ST_FUNC void mk_pointer(CType *type);
+ST_FUNC void vstore(void);
+ST_FUNC void inc(int post, int c);
+ST_FUNC void parse_mult_str (CString *astr, const char *msg);
+ST_FUNC void parse_asm_str(CString *astr);
+ST_FUNC int lvalue_type(int t);
+ST_FUNC void indir(void);
+ST_FUNC void unary(void);
+ST_FUNC void expr_prod(void);
+ST_FUNC void expr_sum(void);
+ST_FUNC void gexpr(void);
+ST_FUNC int expr_const(void);
+#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
+ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
+#endif
+#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
+ST_FUNC int classify_x86_64_va_arg(CType *ty);
+#endif
+
+/* ------------ tccelf.c ------------ */
+
+#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */
+#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
+#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */
+
+#define ARMAG "!<arch>\012" /* For COFF and a.out archives */
+
+typedef struct {
+ unsigned int n_strx; /* index into string table of name */
+ unsigned char n_type; /* type of symbol */
+ unsigned char n_other; /* misc info (usually empty) */
+ unsigned short n_desc; /* description field */
+ unsigned int n_value; /* value of symbol */
+} Stab_Sym;
+
+ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
+ST_DATA Section *common_section;
+ST_DATA Section *cur_text_section; /* current section where function code is generated */
+#ifdef CONFIG_TCC_ASM
+ST_DATA Section *last_text_section; /* to handle .previous asm directive */
+#endif
+#ifdef CONFIG_TCC_BCHECK
+/* bound check related sections */
+ST_DATA Section *bounds_section; /* contains global data bound description */
+ST_DATA Section *lbounds_section; /* contains local data bound description */
+ST_FUNC void tccelf_bounds_new(TCCState *s);
+#endif
+/* symbol sections */
+ST_DATA Section *symtab_section;
+/* debug sections */
+ST_DATA Section *stab_section, *stabstr_section;
+
+ST_FUNC void tccelf_new(TCCState *s);
+ST_FUNC void tccelf_delete(TCCState *s);
+ST_FUNC void tccelf_stab_new(TCCState *s);
+ST_FUNC void tccelf_begin_file(TCCState *s1);
+ST_FUNC void tccelf_end_file(TCCState *s1);
+
+ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
+ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
+ST_FUNC size_t section_add(Section *sec, addr_t size, int align);
+ST_FUNC void *section_ptr_add(Section *sec, addr_t size);
+ST_FUNC void section_reserve(Section *sec, unsigned long size);
+ST_FUNC Section *find_section(TCCState *s1, const char *name);
+ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);
+
+ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore);
+ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
+#if PTR_SIZE == 4
+ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
+#endif
+ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend);
+
+ST_FUNC int put_elf_str(Section *s, const char *sym);
+ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
+ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
+ST_FUNC int find_elf_sym(Section *s, const char *name);
+ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
+ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend);
+
+ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value);
+ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index);
+ST_FUNC void put_stabn(int type, int other, int desc, int value);
+ST_FUNC void put_stabd(int type, int other, int desc);
+
+ST_FUNC void resolve_common_syms(TCCState *s1);
+ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve);
+ST_FUNC void relocate_section(TCCState *s1, Section *s);
+
+ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);
+ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
+ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
+ST_FUNC void tcc_add_bcheck(TCCState *s1);
+ST_FUNC void tcc_add_runtime(TCCState *s1);
+
+ST_FUNC void build_got_entries(TCCState *s1);
+ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc);
+ST_FUNC void squeeze_multi_relocs(Section *sec, size_t oldrelocoffset);
+
+ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err);
+#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
+ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
+#endif
+
+#ifndef TCC_TARGET_PE
+ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);
+ST_FUNC int tcc_load_ldscript(TCCState *s1);
+ST_FUNC uint8_t *parse_comment(uint8_t *p);
+ST_FUNC void minp(void);
+ST_INLN void inp(void);
+ST_FUNC int handle_eob(void);
+#endif
+
+/* ------------ xxx-link.c ------------ */
+
+/* Whether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so
+ that unknown relocation don't create a GOT or PLT entry */
+enum gotplt_entry {
+ NO_GOTPLT_ENTRY, /* never generate (eg. GLOB_DAT & JMP_SLOT relocs) */
+ BUILD_GOT_ONLY, /* only build GOT (eg. TPOFF relocs) */
+ AUTO_GOTPLT_ENTRY, /* generate if sym is UNDEF */
+ ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */
+};
+
+ST_FUNC int code_reloc (int reloc_type);
+ST_FUNC int gotplt_entry_type (int reloc_type);
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);
+ST_FUNC void relocate_init(Section *sr);
+ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
+ST_FUNC void relocate_plt(TCCState *s1);
+
+/* ------------ xxx-gen.c ------------ */
+
+ST_DATA const int reg_classes[NB_REGS];
+
+ST_FUNC void gsym_addr(int t, int a);
+ST_FUNC void gsym(int t);
+ST_FUNC void load(int r, SValue *sv);
+ST_FUNC void store(int r, SValue *v);
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize);
+ST_FUNC void gfunc_call(int nb_args);
+ST_FUNC void gfunc_prolog(CType *func_type);
+ST_FUNC void gfunc_epilog(void);
+ST_FUNC int gjmp(int t);
+ST_FUNC void gjmp_addr(int a);
+ST_FUNC int gtst(int inv, int t);
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ST_FUNC void gtst_addr(int inv, int a);
+#else
+#define gtst_addr(inv, a) gsym_addr(gtst(inv, 0), a)
+#endif
+ST_FUNC void gen_opi(int op);
+ST_FUNC void gen_opf(int op);
+ST_FUNC void gen_cvt_ftoi(int t);
+ST_FUNC void gen_cvt_ftof(int t);
+ST_FUNC void ggoto(void);
+#ifndef TCC_TARGET_C67
+ST_FUNC void o(unsigned int c);
+#endif
+#ifndef TCC_TARGET_ARM
+ST_FUNC void gen_cvt_itof(int t);
+#endif
+ST_FUNC void gen_vla_sp_save(int addr);
+ST_FUNC void gen_vla_sp_restore(int addr);
+ST_FUNC void gen_vla_alloc(CType *type, int align);
+
+static inline uint16_t read16le(unsigned char *p) {
+ return p[0] | (uint16_t)p[1] << 8;
+}
+static inline void write16le(unsigned char *p, uint16_t x) {
+ p[0] = x & 255; p[1] = x >> 8 & 255;
+}
+static inline uint32_t read32le(unsigned char *p) {
+ return read16le(p) | (uint32_t)read16le(p + 2) << 16;
+}
+static inline void write32le(unsigned char *p, uint32_t x) {
+ write16le(p, x); write16le(p + 2, x >> 16);
+}
+static inline void add32le(unsigned char *p, int32_t x) {
+ write32le(p, read32le(p) + x);
+}
+static inline uint64_t read64le(unsigned char *p) {
+ return read32le(p) | (uint64_t)read32le(p + 4) << 32;
+}
+static inline void write64le(unsigned char *p, uint64_t x) {
+ write32le(p, x); write32le(p + 4, x >> 32);
+}
+static inline void add64le(unsigned char *p, int64_t x) {
+ write64le(p, read64le(p) + x);
+}
+
+/* ------------ i386-gen.c ------------ */
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ST_FUNC void g(int c);
+ST_FUNC void gen_le16(int c);
+ST_FUNC void gen_le32(int c);
+ST_FUNC void gen_addr32(int r, Sym *sym, int c);
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c);
+#endif
+
+#ifdef CONFIG_TCC_BCHECK
+ST_FUNC void gen_bounded_ptr_add(void);
+ST_FUNC void gen_bounded_ptr_deref(void);
+#endif
+
+/* ------------ x86_64-gen.c ------------ */
+#ifdef TCC_TARGET_X86_64
+ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
+ST_FUNC void gen_opl(int op);
+#ifdef TCC_TARGET_PE
+ST_FUNC void gen_vla_result(int addr);
+#endif
+#endif
+
+/* ------------ arm-gen.c ------------ */
+#ifdef TCC_TARGET_ARM
+#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
+PUB_FUNC const char *default_elfinterp(struct TCCState *s);
+#endif
+ST_FUNC void arm_init(struct TCCState *s);
+ST_FUNC void gen_cvt_itof1(int t);
+#endif
+
+/* ------------ arm64-gen.c ------------ */
+#ifdef TCC_TARGET_ARM64
+ST_FUNC void gen_cvt_sxtw(void);
+ST_FUNC void gen_opl(int op);
+ST_FUNC void gfunc_return(CType *func_type);
+ST_FUNC void gen_va_start(void);
+ST_FUNC void gen_va_arg(CType *t);
+ST_FUNC void gen_clear_cache(void);
+#endif
+
+/* ------------ c67-gen.c ------------ */
+#ifdef TCC_TARGET_C67
+#endif
+
+/* ------------ tcccoff.c ------------ */
+
+#ifdef TCC_TARGET_COFF
+ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f);
+ST_FUNC int tcc_load_coff(TCCState * s1, int fd);
+#endif
+
+/* ------------ tccasm.c ------------ */
+ST_FUNC void asm_instr(void);
+ST_FUNC void asm_global_instr(void);
+#ifdef CONFIG_TCC_ASM
+ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);
+ST_FUNC Sym* get_asm_sym(int name, Sym *csym);
+ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
+ST_FUNC int asm_int_expr(TCCState *s1);
+ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);
+/* ------------ i386-asm.c ------------ */
+ST_FUNC void gen_expr32(ExprValue *pe);
+#ifdef TCC_TARGET_X86_64
+ST_FUNC void gen_expr64(ExprValue *pe);
+#endif
+ST_FUNC void asm_opcode(TCCState *s1, int opcode);
+ST_FUNC int asm_parse_regvar(int t);
+ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
+ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier);
+ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg);
+ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
+#endif
+
+/* ------------ tccpe.c -------------- */
+#ifdef TCC_TARGET_PE
+ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd);
+ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
+ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value);
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2);
+#endif
+#ifdef TCC_TARGET_X86_64
+ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack);
+#endif
+PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp);
+/* symbol properties stored in Elf32_Sym->st_other */
+# define ST_PE_EXPORT 0x10
+# define ST_PE_IMPORT 0x20
+# define ST_PE_STDCALL 0x40
+#endif
+#define ST_ASM_SET 0x04
+
+/* ------------ tccrun.c ----------------- */
+#ifdef TCC_IS_NATIVE
+#ifdef CONFIG_TCC_STATIC
+#define RTLD_LAZY 0x001
+#define RTLD_NOW 0x002
+#define RTLD_GLOBAL 0x100
+#define RTLD_DEFAULT NULL
+/* dummy function for profiling */
+ST_FUNC void *dlopen(const char *filename, int flag);
+ST_FUNC void dlclose(void *p);
+ST_FUNC const char *dlerror(void);
+ST_FUNC void *dlsym(void *handle, const char *symbol);
+#endif
+#ifdef CONFIG_TCC_BACKTRACE
+ST_DATA int rt_num_callers;
+ST_DATA const char **rt_bound_error_msg;
+ST_DATA void *rt_prog_main;
+ST_FUNC void tcc_set_num_callers(int n);
+#endif
+ST_FUNC void tcc_run_free(TCCState *s1);
+#endif
+
+/* ------------ tcctools.c ----------------- */
+#if 0 /* included in tcc.c */
+ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv);
+#ifdef TCC_TARGET_PE
+ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv);
+#endif
+ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option);
+ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename);
+#endif
+
+/********************************************************/
+#undef ST_DATA
+#if ONE_SOURCE
+#define ST_DATA static
+#else
+#define ST_DATA
+#endif
+/********************************************************/
+#endif /* _TCC_H */
diff --git a/tccasm.c b/tccasm.c
new file mode 100644
index 0000000..c035c8b
--- /dev/null
+++ b/tccasm.c
@@ -0,0 +1,1277 @@
+/*
+ * GAS like assembler for TCC
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tcc.h"
+#ifdef CONFIG_TCC_ASM
+
+ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
+{
+ char buf[64];
+ TokenSym *ts;
+
+ snprintf(buf, sizeof(buf), "L..%u", n);
+ ts = tok_alloc(buf, strlen(buf));
+ return ts->tok;
+}
+
+static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global);
+static Sym* asm_new_label(TCCState *s1, int label, int is_local);
+static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value);
+
+static Sym *asm_label_find(int v)
+{
+ Sym *sym = sym_find(v);
+ while (sym && sym->sym_scope)
+ sym = sym->prev_tok;
+ return sym;
+}
+
+static Sym *asm_label_push(int v)
+{
+ /* We always add VT_EXTERN, for sym definition that's tentative
+ (for .set, removed for real defs), for mere references it's correct
+ as is. */
+ Sym *sym = global_identifier_push(v, VT_ASM | VT_EXTERN | VT_STATIC, 0);
+ sym->r = VT_CONST | VT_SYM;
+ return sym;
+}
+
+/* Return a symbol we can use inside the assembler, having name NAME.
+ Symbols from asm and C source share a namespace. If we generate
+ an asm symbol it's also a (file-global) C symbol, but it's
+ either not accessible by name (like "L.123"), or its type information
+ is such that it's not usable without a proper C declaration.
+
+ Sometimes we need symbols accessible by name from asm, which
+ are anonymous in C, in this case CSYM can be used to transfer
+ all information from that symbol to the (possibly newly created)
+ asm symbol. */
+ST_FUNC Sym* get_asm_sym(int name, Sym *csym)
+{
+ Sym *sym = asm_label_find(name);
+ if (!sym) {
+ sym = asm_label_push(name);
+ if (csym)
+ sym->c = csym->c;
+ }
+ return sym;
+}
+
+static Sym* asm_section_sym(TCCState *s1, Section *sec)
+{
+ char buf[100];
+ int label = tok_alloc(buf,
+ snprintf(buf, sizeof buf, "L.%s", sec->name)
+ )->tok;
+ Sym *sym = asm_label_find(label);
+ return sym ? sym : asm_new_label1(s1, label, 1, sec->sh_num, 0);
+}
+
+/* We do not use the C expression parser to handle symbols. Maybe the
+ C expression parser could be tweaked to do so. */
+
+static void asm_expr_unary(TCCState *s1, ExprValue *pe)
+{
+ Sym *sym;
+ int op, label;
+ uint64_t n;
+ const char *p;
+
+ switch(tok) {
+ case TOK_PPNUM:
+ p = tokc.str.data;
+ n = strtoull(p, (char **)&p, 0);
+ if (*p == 'b' || *p == 'f') {
+ /* backward or forward label */
+ label = asm_get_local_label_name(s1, n);
+ sym = asm_label_find(label);
+ if (*p == 'b') {
+ /* backward : find the last corresponding defined label */
+ if (sym && (!sym->c || elfsym(sym)->st_shndx == SHN_UNDEF))
+ sym = sym->prev_tok;
+ if (!sym)
+ tcc_error("local label '%d' not found backward", n);
+ } else {
+ /* forward */
+ if (!sym || (sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)) {
+ /* if the last label is defined, then define a new one */
+ sym = asm_label_push(label);
+ }
+ }
+ pe->v = 0;
+ pe->sym = sym;
+ pe->pcrel = 0;
+ } else if (*p == '\0') {
+ pe->v = n;
+ pe->sym = NULL;
+ pe->pcrel = 0;
+ } else {
+ tcc_error("invalid number syntax");
+ }
+ next();
+ break;
+ case '+':
+ next();
+ asm_expr_unary(s1, pe);
+ break;
+ case '-':
+ case '~':
+ op = tok;
+ next();
+ asm_expr_unary(s1, pe);
+ if (pe->sym)
+ tcc_error("invalid operation with label");
+ if (op == '-')
+ pe->v = -pe->v;
+ else
+ pe->v = ~pe->v;
+ break;
+ case TOK_CCHAR:
+ case TOK_LCHAR:
+ pe->v = tokc.i;
+ pe->sym = NULL;
+ pe->pcrel = 0;
+ next();
+ break;
+ case '(':
+ next();
+ asm_expr(s1, pe);
+ skip(')');
+ break;
+ case '.':
+ pe->v = ind;
+ pe->sym = asm_section_sym(s1, cur_text_section);
+ pe->pcrel = 0;
+ next();
+ break;
+ default:
+ if (tok >= TOK_IDENT) {
+ ElfSym *esym;
+ /* label case : if the label was not found, add one */
+ sym = get_asm_sym(tok, NULL);
+ esym = elfsym(sym);
+ if (esym && esym->st_shndx == SHN_ABS) {
+ /* if absolute symbol, no need to put a symbol value */
+ pe->v = esym->st_value;
+ pe->sym = NULL;
+ pe->pcrel = 0;
+ } else {
+ pe->v = 0;
+ pe->sym = sym;
+ pe->pcrel = 0;
+ }
+ next();
+ } else {
+ tcc_error("bad expression syntax [%s]", get_tok_str(tok, &tokc));
+ }
+ break;
+ }
+}
+
+static void asm_expr_prod(TCCState *s1, ExprValue *pe)
+{
+ int op;
+ ExprValue e2;
+
+ asm_expr_unary(s1, pe);
+ for(;;) {
+ op = tok;
+ if (op != '*' && op != '/' && op != '%' &&
+ op != TOK_SHL && op != TOK_SAR)
+ break;
+ next();
+ asm_expr_unary(s1, &e2);
+ if (pe->sym || e2.sym)
+ tcc_error("invalid operation with label");
+ switch(op) {
+ case '*':
+ pe->v *= e2.v;
+ break;
+ case '/':
+ if (e2.v == 0) {
+ div_error:
+ tcc_error("division by zero");
+ }
+ pe->v /= e2.v;
+ break;
+ case '%':
+ if (e2.v == 0)
+ goto div_error;
+ pe->v %= e2.v;
+ break;
+ case TOK_SHL:
+ pe->v <<= e2.v;
+ break;
+ default:
+ case TOK_SAR:
+ pe->v >>= e2.v;
+ break;
+ }
+ }
+}
+
+static void asm_expr_logic(TCCState *s1, ExprValue *pe)
+{
+ int op;
+ ExprValue e2;
+
+ asm_expr_prod(s1, pe);
+ for(;;) {
+ op = tok;
+ if (op != '&' && op != '|' && op != '^')
+ break;
+ next();
+ asm_expr_prod(s1, &e2);
+ if (pe->sym || e2.sym)
+ tcc_error("invalid operation with label");
+ switch(op) {
+ case '&':
+ pe->v &= e2.v;
+ break;
+ case '|':
+ pe->v |= e2.v;
+ break;
+ default:
+ case '^':
+ pe->v ^= e2.v;
+ break;
+ }
+ }
+}
+
+static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
+{
+ int op;
+ ExprValue e2;
+
+ asm_expr_logic(s1, pe);
+ for(;;) {
+ op = tok;
+ if (op != '+' && op != '-')
+ break;
+ next();
+ asm_expr_logic(s1, &e2);
+ if (op == '+') {
+ if (pe->sym != NULL && e2.sym != NULL)
+ goto cannot_relocate;
+ pe->v += e2.v;
+ if (pe->sym == NULL && e2.sym != NULL)
+ pe->sym = e2.sym;
+ } else {
+ pe->v -= e2.v;
+ /* NOTE: we are less powerful than gas in that case
+ because we store only one symbol in the expression */
+ if (!e2.sym) {
+ /* OK */
+ } else if (pe->sym == e2.sym) {
+ /* OK */
+ pe->sym = NULL; /* same symbols can be subtracted to NULL */
+ } else {
+ ElfSym *esym1, *esym2;
+ esym1 = elfsym(pe->sym);
+ esym2 = elfsym(e2.sym);
+ if (esym1 && esym1->st_shndx == esym2->st_shndx
+ && esym1->st_shndx != SHN_UNDEF) {
+ /* we also accept defined symbols in the same section */
+ pe->v += esym1->st_value - esym2->st_value;
+ pe->sym = NULL;
+ } else if (esym2->st_shndx == cur_text_section->sh_num) {
+ /* When subtracting a defined symbol in current section
+ this actually makes the value PC-relative. */
+ pe->v -= esym2->st_value - ind - 4;
+ pe->pcrel = 1;
+ e2.sym = NULL;
+ } else {
+cannot_relocate:
+ tcc_error("invalid operation with label");
+ }
+ }
+ }
+ }
+}
+
+static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)
+{
+ int op;
+ ExprValue e2;
+
+ asm_expr_sum(s1, pe);
+ for(;;) {
+ op = tok;
+ if (op != TOK_EQ && op != TOK_NE
+ && (op > TOK_GT || op < TOK_ULE))
+ break;
+ next();
+ asm_expr_sum(s1, &e2);
+ if (pe->sym || e2.sym)
+ tcc_error("invalid operation with label");
+ switch(op) {
+ case TOK_EQ:
+ pe->v = pe->v == e2.v;
+ break;
+ case TOK_NE:
+ pe->v = pe->v != e2.v;
+ break;
+ case TOK_LT:
+ pe->v = (int64_t)pe->v < (int64_t)e2.v;
+ break;
+ case TOK_GE:
+ pe->v = (int64_t)pe->v >= (int64_t)e2.v;
+ break;
+ case TOK_LE:
+ pe->v = (int64_t)pe->v <= (int64_t)e2.v;
+ break;
+ case TOK_GT:
+ pe->v = (int64_t)pe->v > (int64_t)e2.v;
+ break;
+ default:
+ break;
+ }
+ /* GAS compare results are -1/0 not 1/0. */
+ pe->v = -(int64_t)pe->v;
+ }
+}
+
+ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)
+{
+ asm_expr_cmp(s1, pe);
+}
+
+ST_FUNC int asm_int_expr(TCCState *s1)
+{
+ ExprValue e;
+ asm_expr(s1, &e);
+ if (e.sym)
+ expect("constant");
+ return e.v;
+}
+
+static Sym* asm_new_label1(TCCState *s1, int label, int is_local,
+ int sh_num, int value)
+{
+ Sym *sym;
+ ElfSym *esym;
+
+ sym = asm_label_find(label);
+ if (sym) {
+ esym = elfsym(sym);
+ /* A VT_EXTERN symbol, even if it has a section is considered
+ overridable. This is how we "define" .set targets. Real
+ definitions won't have VT_EXTERN set. */
+ if (esym && esym->st_shndx != SHN_UNDEF) {
+ /* the label is already defined */
+ if (IS_ASM_SYM(sym)
+ && (is_local == 1 || (sym->type.t & VT_EXTERN)))
+ goto new_label;
+ if (!(sym->type.t & VT_EXTERN))
+ tcc_error("assembler label '%s' already defined",
+ get_tok_str(label, NULL));
+ }
+ } else {
+ new_label:
+ sym = asm_label_push(label);
+ }
+ if (!sym->c)
+ put_extern_sym2(sym, SHN_UNDEF, 0, 0, 0);
+ esym = elfsym(sym);
+ esym->st_shndx = sh_num;
+ esym->st_value = value;
+ if (is_local != 2)
+ sym->type.t &= ~VT_EXTERN;
+ return sym;
+}
+
+static Sym* asm_new_label(TCCState *s1, int label, int is_local)
+{
+ return asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
+}
+
+/* Set the value of LABEL to that of some expression (possibly
+ involving other symbols). LABEL can be overwritten later still. */
+static Sym* set_symbol(TCCState *s1, int label)
+{
+ long n;
+ ExprValue e;
+ Sym *sym;
+ ElfSym *esym;
+ next();
+ asm_expr(s1, &e);
+ n = e.v;
+ esym = elfsym(e.sym);
+ if (esym)
+ n += esym->st_value;
+ sym = asm_new_label1(s1, label, 2, esym ? esym->st_shndx : SHN_ABS, n);
+ elfsym(sym)->st_other |= ST_ASM_SET;
+ return sym;
+}
+
+static void use_section1(TCCState *s1, Section *sec)
+{
+ cur_text_section->data_offset = ind;
+ cur_text_section = sec;
+ ind = cur_text_section->data_offset;
+}
+
+static void use_section(TCCState *s1, const char *name)
+{
+ Section *sec;
+ sec = find_section(s1, name);
+ use_section1(s1, sec);
+}
+
+static void push_section(TCCState *s1, const char *name)
+{
+ Section *sec = find_section(s1, name);
+ sec->prev = cur_text_section;
+ use_section1(s1, sec);
+}
+
+static void pop_section(TCCState *s1)
+{
+ Section *prev = cur_text_section->prev;
+ if (!prev)
+ tcc_error(".popsection without .pushsection");
+ cur_text_section->prev = NULL;
+ use_section1(s1, prev);
+}
+
+static void asm_parse_directive(TCCState *s1, int global)
+{
+ int n, offset, v, size, tok1;
+ Section *sec;
+ uint8_t *ptr;
+
+ /* assembler directive */
+ sec = cur_text_section;
+ switch(tok) {
+ case TOK_ASMDIR_align:
+ case TOK_ASMDIR_balign:
+ case TOK_ASMDIR_p2align:
+ case TOK_ASMDIR_skip:
+ case TOK_ASMDIR_space:
+ tok1 = tok;
+ next();
+ n = asm_int_expr(s1);
+ if (tok1 == TOK_ASMDIR_p2align)
+ {
+ if (n < 0 || n > 30)
+ tcc_error("invalid p2align, must be between 0 and 30");
+ n = 1 << n;
+ tok1 = TOK_ASMDIR_align;
+ }
+ if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {
+ if (n < 0 || (n & (n-1)) != 0)
+ tcc_error("alignment must be a positive power of two");
+ offset = (ind + n - 1) & -n;
+ size = offset - ind;
+ /* the section must have a compatible alignment */
+ if (sec->sh_addralign < n)
+ sec->sh_addralign = n;
+ } else {
+ if (n < 0)
+ n = 0;
+ size = n;
+ }
+ v = 0;
+ if (tok == ',') {
+ next();
+ v = asm_int_expr(s1);
+ }
+ zero_pad:
+ if (sec->sh_type != SHT_NOBITS) {
+ sec->data_offset = ind;
+ ptr = section_ptr_add(sec, size);
+ memset(ptr, v, size);
+ }
+ ind += size;
+ break;
+ case TOK_ASMDIR_quad:
+#ifdef TCC_TARGET_X86_64
+ size = 8;
+ goto asm_data;
+#else
+ next();
+ for(;;) {
+ uint64_t vl;
+ const char *p;
+
+ p = tokc.str.data;
+ if (tok != TOK_PPNUM) {
+ error_constant:
+ tcc_error("64 bit constant");
+ }
+ vl = strtoll(p, (char **)&p, 0);
+ if (*p != '\0')
+ goto error_constant;
+ next();
+ if (sec->sh_type != SHT_NOBITS) {
+ /* XXX: endianness */
+ gen_le32(vl);
+ gen_le32(vl >> 32);
+ } else {
+ ind += 8;
+ }
+ if (tok != ',')
+ break;
+ next();
+ }
+ break;
+#endif
+ case TOK_ASMDIR_byte:
+ size = 1;
+ goto asm_data;
+ case TOK_ASMDIR_word:
+ case TOK_ASMDIR_short:
+ size = 2;
+ goto asm_data;
+ case TOK_ASMDIR_long:
+ case TOK_ASMDIR_int:
+ size = 4;
+ asm_data:
+ next();
+ for(;;) {
+ ExprValue e;
+ asm_expr(s1, &e);
+ if (sec->sh_type != SHT_NOBITS) {
+ if (size == 4) {
+ gen_expr32(&e);
+#ifdef TCC_TARGET_X86_64
+ } else if (size == 8) {
+ gen_expr64(&e);
+#endif
+ } else {
+ if (e.sym)
+ expect("constant");
+ if (size == 1)
+ g(e.v);
+ else
+ gen_le16(e.v);
+ }
+ } else {
+ ind += size;
+ }
+ if (tok != ',')
+ break;
+ next();
+ }
+ break;
+ case TOK_ASMDIR_fill:
+ {
+ int repeat, size, val, i, j;
+ uint8_t repeat_buf[8];
+ next();
+ repeat = asm_int_expr(s1);
+ if (repeat < 0) {
+ tcc_error("repeat < 0; .fill ignored");
+ break;
+ }
+ size = 1;
+ val = 0;
+ if (tok == ',') {
+ next();
+ size = asm_int_expr(s1);
+ if (size < 0) {
+ tcc_error("size < 0; .fill ignored");
+ break;
+ }
+ if (size > 8)
+ size = 8;
+ if (tok == ',') {
+ next();
+ val = asm_int_expr(s1);
+ }
+ }
+ /* XXX: endianness */
+ repeat_buf[0] = val;
+ repeat_buf[1] = val >> 8;
+ repeat_buf[2] = val >> 16;
+ repeat_buf[3] = val >> 24;
+ repeat_buf[4] = 0;
+ repeat_buf[5] = 0;
+ repeat_buf[6] = 0;
+ repeat_buf[7] = 0;
+ for(i = 0; i < repeat; i++) {
+ for(j = 0; j < size; j++) {
+ g(repeat_buf[j]);
+ }
+ }
+ }
+ break;
+ case TOK_ASMDIR_rept:
+ {
+ int repeat;
+ TokenString *init_str;
+ next();
+ repeat = asm_int_expr(s1);
+ init_str = tok_str_alloc();
+ while (next(), tok != TOK_ASMDIR_endr) {
+ if (tok == CH_EOF)
+ tcc_error("we at end of file, .endr not found");
+ tok_str_add_tok(init_str);
+ }
+ tok_str_add(init_str, -1);
+ tok_str_add(init_str, 0);
+ begin_macro(init_str, 1);
+ while (repeat-- > 0) {
+ tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS),
+ global);
+ macro_ptr = init_str->str;
+ }
+ end_macro();
+ next();
+ break;
+ }
+ case TOK_ASMDIR_org:
+ {
+ unsigned long n;
+ ExprValue e;
+ ElfSym *esym;
+ next();
+ asm_expr(s1, &e);
+ n = e.v;
+ esym = elfsym(e.sym);
+ if (esym) {
+ if (esym->st_shndx != cur_text_section->sh_num)
+ expect("constant or same-section symbol");
+ n += esym->st_value;
+ }
+ if (n < ind)
+ tcc_error("attempt to .org backwards");
+ v = 0;
+ size = n - ind;
+ goto zero_pad;
+ }
+ break;
+ case TOK_ASMDIR_set:
+ next();
+ tok1 = tok;
+ next();
+ /* Also accept '.set stuff', but don't do anything with this.
+ It's used in GAS to set various features like '.set mips16'. */
+ if (tok == ',')
+ set_symbol(s1, tok1);
+ break;
+ case TOK_ASMDIR_globl:
+ case TOK_ASMDIR_global:
+ case TOK_ASMDIR_weak:
+ case TOK_ASMDIR_hidden:
+ tok1 = tok;
+ do {
+ Sym *sym;
+ next();
+ sym = get_asm_sym(tok, NULL);
+ if (tok1 != TOK_ASMDIR_hidden)
+ sym->type.t &= ~VT_STATIC;
+ if (tok1 == TOK_ASMDIR_weak)
+ sym->a.weak = 1;
+ else if (tok1 == TOK_ASMDIR_hidden)
+ sym->a.visibility = STV_HIDDEN;
+ update_storage(sym);
+ next();
+ } while (tok == ',');
+ break;
+ case TOK_ASMDIR_string:
+ case TOK_ASMDIR_ascii:
+ case TOK_ASMDIR_asciz:
+ {
+ const uint8_t *p;
+ int i, size, t;
+
+ t = tok;
+ next();
+ for(;;) {
+ if (tok != TOK_STR)
+ expect("string constant");
+ p = tokc.str.data;
+ size = tokc.str.size;
+ if (t == TOK_ASMDIR_ascii && size > 0)
+ size--;
+ for(i = 0; i < size; i++)
+ g(p[i]);
+ next();
+ if (tok == ',') {
+ next();
+ } else if (tok != TOK_STR) {
+ break;
+ }
+ }
+ }
+ break;
+ case TOK_ASMDIR_text:
+ case TOK_ASMDIR_data:
+ case TOK_ASMDIR_bss:
+ {
+ char sname[64];
+ tok1 = tok;
+ n = 0;
+ next();
+ if (tok != ';' && tok != TOK_LINEFEED) {
+ n = asm_int_expr(s1);
+ next();
+ }
+ if (n)
+ sprintf(sname, "%s%d", get_tok_str(tok1, NULL), n);
+ else
+ sprintf(sname, "%s", get_tok_str(tok1, NULL));
+ use_section(s1, sname);
+ }
+ break;
+ case TOK_ASMDIR_file:
+ {
+ char filename[512];
+
+ filename[0] = '\0';
+ next();
+
+ if (tok == TOK_STR)
+ pstrcat(filename, sizeof(filename), tokc.str.data);
+ else
+ pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
+
+ if (s1->warn_unsupported)
+ tcc_warning("ignoring .file %s", filename);
+
+ next();
+ }
+ break;
+ case TOK_ASMDIR_ident:
+ {
+ char ident[256];
+
+ ident[0] = '\0';
+ next();
+
+ if (tok == TOK_STR)
+ pstrcat(ident, sizeof(ident), tokc.str.data);
+ else
+ pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
+
+ if (s1->warn_unsupported)
+ tcc_warning("ignoring .ident %s", ident);
+
+ next();
+ }
+ break;
+ case TOK_ASMDIR_size:
+ {
+ Sym *sym;
+
+ next();
+ sym = asm_label_find(tok);
+ if (!sym) {
+ tcc_error("label not found: %s", get_tok_str(tok, NULL));
+ }
+
+ /* XXX .size name,label2-label1 */
+ if (s1->warn_unsupported)
+ tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL));
+
+ next();
+ skip(',');
+ while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {
+ next();
+ }
+ }
+ break;
+ case TOK_ASMDIR_type:
+ {
+ Sym *sym;
+ const char *newtype;
+
+ next();
+ sym = get_asm_sym(tok, NULL);
+ next();
+ skip(',');
+ if (tok == TOK_STR) {
+ newtype = tokc.str.data;
+ } else {
+ if (tok == '@' || tok == '%')
+ next();
+ newtype = get_tok_str(tok, NULL);
+ }
+
+ if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
+ sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
+ }
+ else if (s1->warn_unsupported)
+ tcc_warning("change type of '%s' from 0x%x to '%s' ignored",
+ get_tok_str(sym->v, NULL), sym->type.t, newtype);
+
+ next();
+ }
+ break;
+ case TOK_ASMDIR_pushsection:
+ case TOK_ASMDIR_section:
+ {
+ char sname[256];
+ int old_nb_section = s1->nb_sections;
+
+ tok1 = tok;
+ /* XXX: support more options */
+ next();
+ sname[0] = '\0';
+ while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
+ if (tok == TOK_STR)
+ pstrcat(sname, sizeof(sname), tokc.str.data);
+ else
+ pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
+ next();
+ }
+ if (tok == ',') {
+ /* skip section options */
+ next();
+ if (tok != TOK_STR)
+ expect("string constant");
+ next();
+ if (tok == ',') {
+ next();
+ if (tok == '@' || tok == '%')
+ next();
+ next();
+ }
+ }
+ last_text_section = cur_text_section;
+ if (tok1 == TOK_ASMDIR_section)
+ use_section(s1, sname);
+ else
+ push_section(s1, sname);
+ /* If we just allocated a new section reset its alignment to
+ 1. new_section normally acts for GCC compatibility and
+ sets alignment to PTR_SIZE. The assembler behaves different. */
+ if (old_nb_section != s1->nb_sections)
+ cur_text_section->sh_addralign = 1;
+ }
+ break;
+ case TOK_ASMDIR_previous:
+ {
+ Section *sec;
+ next();
+ if (!last_text_section)
+ tcc_error("no previous section referenced");
+ sec = cur_text_section;
+ use_section1(s1, last_text_section);
+ last_text_section = sec;
+ }
+ break;
+ case TOK_ASMDIR_popsection:
+ next();
+ pop_section(s1);
+ break;
+#ifdef TCC_TARGET_I386
+ case TOK_ASMDIR_code16:
+ {
+ next();
+ s1->seg_size = 16;
+ }
+ break;
+ case TOK_ASMDIR_code32:
+ {
+ next();
+ s1->seg_size = 32;
+ }
+ break;
+#endif
+#ifdef TCC_TARGET_X86_64
+ /* added for compatibility with GAS */
+ case TOK_ASMDIR_code64:
+ next();
+ break;
+#endif
+ default:
+ tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
+ break;
+ }
+}
+
+
+/* assemble a file */
+static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
+{
+ int opcode;
+ int saved_parse_flags = parse_flags;
+
+ parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;
+ if (do_preprocess)
+ parse_flags |= PARSE_FLAG_PREPROCESS;
+ for(;;) {
+ next();
+ if (tok == TOK_EOF)
+ break;
+ /* generate line number info */
+ if (global && s1->do_debug)
+ tcc_debug_line(s1);
+ parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
+ redo:
+ if (tok == '#') {
+ /* horrible gas comment */
+ while (tok != TOK_LINEFEED)
+ next();
+ } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) {
+ asm_parse_directive(s1, global);
+ } else if (tok == TOK_PPNUM) {
+ const char *p;
+ int n;
+ p = tokc.str.data;
+ n = strtoul(p, (char **)&p, 10);
+ if (*p != '\0')
+ expect("':'");
+ /* new local label */
+ asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
+ next();
+ skip(':');
+ goto redo;
+ } else if (tok >= TOK_IDENT) {
+ /* instruction or label */
+ opcode = tok;
+ next();
+ if (tok == ':') {
+ /* new label */
+ asm_new_label(s1, opcode, 0);
+ next();
+ goto redo;
+ } else if (tok == '=') {
+ set_symbol(s1, opcode);
+ goto redo;
+ } else {
+ asm_opcode(s1, opcode);
+ }
+ }
+ /* end of line */
+ if (tok != ';' && tok != TOK_LINEFEED)
+ expect("end of line");
+ parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
+ }
+
+ parse_flags = saved_parse_flags;
+ return 0;
+}
+
+/* Assemble the current file */
+ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
+{
+ int ret;
+ tcc_debug_start(s1);
+ /* default section is text */
+ cur_text_section = text_section;
+ ind = cur_text_section->data_offset;
+ nocode_wanted = 0;
+ ret = tcc_assemble_internal(s1, do_preprocess, 1);
+ cur_text_section->data_offset = ind;
+ tcc_debug_end(s1);
+ return ret;
+}
+
+/********************************************************************/
+/* GCC inline asm support */
+
+/* assemble the string 'str' in the current C compilation unit without
+ C preprocessing. NOTE: str is modified by modifying the '\0' at the
+ end */
+static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)
+{
+ const int *saved_macro_ptr = macro_ptr;
+ int dotid = set_idnum('.', IS_ID);
+
+ tcc_open_bf(s1, ":asm:", len);
+ memcpy(file->buffer, str, len);
+ macro_ptr = NULL;
+ tcc_assemble_internal(s1, 0, global);
+ tcc_close();
+
+ set_idnum('.', dotid);
+ macro_ptr = saved_macro_ptr;
+}
+
+/* find a constraint by its number or id (gcc 3 extended
+ syntax). return -1 if not found. Return in *pp in char after the
+ constraint */
+ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
+ const char *name, const char **pp)
+{
+ int index;
+ TokenSym *ts;
+ const char *p;
+
+ if (isnum(*name)) {
+ index = 0;
+ while (isnum(*name)) {
+ index = (index * 10) + (*name) - '0';
+ name++;
+ }
+ if ((unsigned)index >= nb_operands)
+ index = -1;
+ } else if (*name == '[') {
+ name++;
+ p = strchr(name, ']');
+ if (p) {
+ ts = tok_alloc(name, p - name);
+ for(index = 0; index < nb_operands; index++) {
+ if (operands[index].id == ts->tok)
+ goto found;
+ }
+ index = -1;
+ found:
+ name = p + 1;
+ } else {
+ index = -1;
+ }
+ } else {
+ index = -1;
+ }
+ if (pp)
+ *pp = name;
+ return index;
+}
+
+static void subst_asm_operands(ASMOperand *operands, int nb_operands,
+ CString *out_str, CString *in_str)
+{
+ int c, index, modifier;
+ const char *str;
+ ASMOperand *op;
+ SValue sv;
+
+ cstr_new(out_str);
+ str = in_str->data;
+ for(;;) {
+ c = *str++;
+ if (c == '%') {
+ if (*str == '%') {
+ str++;
+ goto add_char;
+ }
+ modifier = 0;
+ if (*str == 'c' || *str == 'n' ||
+ *str == 'b' || *str == 'w' || *str == 'h' || *str == 'k' ||
+ *str == 'q' ||
+ /* P in GCC would add "@PLT" to symbol refs in PIC mode,
+ and make literal operands not be decorated with '$'. */
+ *str == 'P')
+ modifier = *str++;
+ index = find_constraint(operands, nb_operands, str, &str);
+ if (index < 0)
+ tcc_error("invalid operand reference after %%");
+ op = &operands[index];
+ sv = *op->vt;
+ if (op->reg >= 0) {
+ sv.r = op->reg;
+ if ((op->vt->r & VT_VALMASK) == VT_LLOCAL && op->is_memory)
+ sv.r |= VT_LVAL;
+ }
+ subst_asm_operand(out_str, &sv, modifier);
+ } else {
+ add_char:
+ cstr_ccat(out_str, c);
+ if (c == '\0')
+ break;
+ }
+ }
+}
+
+
+static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
+ int is_output)
+{
+ ASMOperand *op;
+ int nb_operands;
+
+ if (tok != ':') {
+ nb_operands = *nb_operands_ptr;
+ for(;;) {
+ CString astr;
+ if (nb_operands >= MAX_ASM_OPERANDS)
+ tcc_error("too many asm operands");
+ op = &operands[nb_operands++];
+ op->id = 0;
+ if (tok == '[') {
+ next();
+ if (tok < TOK_IDENT)
+ expect("identifier");
+ op->id = tok;
+ next();
+ skip(']');
+ }
+ parse_mult_str(&astr, "string constant");
+ op->constraint = tcc_malloc(astr.size);
+ strcpy(op->constraint, astr.data);
+ cstr_free(&astr);
+ skip('(');
+ gexpr();
+ if (is_output) {
+ if (!(vtop->type.t & VT_ARRAY))
+ test_lvalue();
+ } else {
+ /* we want to avoid LLOCAL case, except when the 'm'
+ constraint is used. Note that it may come from
+ register storage, so we need to convert (reg)
+ case */
+ if ((vtop->r & VT_LVAL) &&
+ ((vtop->r & VT_VALMASK) == VT_LLOCAL ||
+ (vtop->r & VT_VALMASK) < VT_CONST) &&
+ !strchr(op->constraint, 'm')) {
+ gv(RC_INT);
+ }
+ }
+ op->vt = vtop;
+ skip(')');
+ if (tok == ',') {
+ next();
+ } else {
+ break;
+ }
+ }
+ *nb_operands_ptr = nb_operands;
+ }
+}
+
+/* parse the GCC asm() instruction */
+ST_FUNC void asm_instr(void)
+{
+ CString astr, astr1;
+ ASMOperand operands[MAX_ASM_OPERANDS];
+ int nb_outputs, nb_operands, i, must_subst, out_reg;
+ uint8_t clobber_regs[NB_ASM_REGS];
+
+ next();
+ /* since we always generate the asm() instruction, we can ignore
+ volatile */
+ if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
+ next();
+ }
+ parse_asm_str(&astr);
+ nb_operands = 0;
+ nb_outputs = 0;
+ must_subst = 0;
+ memset(clobber_regs, 0, sizeof(clobber_regs));
+ if (tok == ':') {
+ next();
+ must_subst = 1;
+ /* output args */
+ parse_asm_operands(operands, &nb_operands, 1);
+ nb_outputs = nb_operands;
+ if (tok == ':') {
+ next();
+ if (tok != ')') {
+ /* input args */
+ parse_asm_operands(operands, &nb_operands, 0);
+ if (tok == ':') {
+ /* clobber list */
+ /* XXX: handle registers */
+ next();
+ for(;;) {
+ if (tok != TOK_STR)
+ expect("string constant");
+ asm_clobber(clobber_regs, tokc.str.data);
+ next();
+ if (tok == ',') {
+ next();
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ skip(')');
+ /* NOTE: we do not eat the ';' so that we can restore the current
+ token after the assembler parsing */
+ if (tok != ';')
+ expect("';'");
+
+ /* save all values in the memory */
+ save_regs(0);
+
+ /* compute constraints */
+ asm_compute_constraints(operands, nb_operands, nb_outputs,
+ clobber_regs, &out_reg);
+
+ /* substitute the operands in the asm string. No substitution is
+ done if no operands (GCC behaviour) */
+#ifdef ASM_DEBUG
+ printf("asm: \"%s\"\n", (char *)astr.data);
+#endif
+ if (must_subst) {
+ subst_asm_operands(operands, nb_operands, &astr1, &astr);
+ cstr_free(&astr);
+ } else {
+ astr1 = astr;
+ }
+#ifdef ASM_DEBUG
+ printf("subst_asm: \"%s\"\n", (char *)astr1.data);
+#endif
+
+ /* generate loads */
+ asm_gen_code(operands, nb_operands, nb_outputs, 0,
+ clobber_regs, out_reg);
+
+ /* assemble the string with tcc internal assembler */
+ tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1, 0);
+
+ /* restore the current C token */
+ next();
+
+ /* store the output values if needed */
+ asm_gen_code(operands, nb_operands, nb_outputs, 1,
+ clobber_regs, out_reg);
+
+ /* free everything */
+ for(i=0;i<nb_operands;i++) {
+ ASMOperand *op;
+ op = &operands[i];
+ tcc_free(op->constraint);
+ vpop();
+ }
+ cstr_free(&astr1);
+}
+
+ST_FUNC void asm_global_instr(void)
+{
+ CString astr;
+ int saved_nocode_wanted = nocode_wanted;
+
+ /* Global asm blocks are always emitted. */
+ nocode_wanted = 0;
+ next();
+ parse_asm_str(&astr);
+ skip(')');
+ /* NOTE: we do not eat the ';' so that we can restore the current
+ token after the assembler parsing */
+ if (tok != ';')
+ expect("';'");
+
+#ifdef ASM_DEBUG
+ printf("asm_global: \"%s\"\n", (char *)astr.data);
+#endif
+ cur_text_section = text_section;
+ ind = cur_text_section->data_offset;
+
+ /* assemble the string with tcc internal assembler */
+ tcc_assemble_inline(tcc_state, astr.data, astr.size - 1, 1);
+
+ cur_text_section->data_offset = ind;
+
+ /* restore the current C token */
+ next();
+
+ cstr_free(&astr);
+ nocode_wanted = saved_nocode_wanted;
+}
+#endif /* CONFIG_TCC_ASM */
diff --git a/tcccoff.c b/tcccoff.c
new file mode 100644
index 0000000..1421ca2
--- /dev/null
+++ b/tcccoff.c
@@ -0,0 +1,948 @@
+/*
+ * COFF file handling for TCC
+ *
+ * Copyright (c) 2003, 2004 TK
+ * Copyright (c) 2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tcc.h"
+
+#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
+#define MAX_STR_TABLE 1000000
+AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
+
+SCNHDR section_header[MAXNSCNS];
+
+#define MAX_FUNCS 1000
+#define MAX_FUNC_NAME_LENGTH 128
+
+int nFuncs;
+char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
+char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
+int LineNoFilePtr[MAX_FUNCS];
+int EndAddress[MAX_FUNCS];
+int LastLineNo[MAX_FUNCS];
+int FuncEntries[MAX_FUNCS];
+
+int OutputTheSection(Section * sect);
+short int GetCoffFlags(const char *s);
+void SortSymbolTable(void);
+Section *FindSection(TCCState * s1, const char *sname);
+
+int C67_main_entry_point;
+
+int FindCoffSymbolIndex(const char *func_name);
+int nb_syms;
+
+typedef struct {
+ long tag;
+ long size;
+ long fileptr;
+ long nextsym;
+ short int dummy;
+} AUXFUNC;
+
+typedef struct {
+ long regmask;
+ unsigned short lineno;
+ unsigned short nentries;
+ int localframe;
+ int nextentry;
+ short int dummy;
+} AUXBF;
+
+typedef struct {
+ long dummy;
+ unsigned short lineno;
+ unsigned short dummy1;
+ int dummy2;
+ int dummy3;
+ unsigned short dummy4;
+} AUXEF;
+
+ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
+{
+ Section *tcc_sect;
+ SCNHDR *coff_sec;
+ int file_pointer;
+ char *Coff_str_table, *pCoff_str_table;
+ int CoffTextSectionNo, coff_nb_syms;
+ FILHDR file_hdr; /* FILE HEADER STRUCTURE */
+ Section *stext, *sdata, *sbss;
+ int i, NSectionsToOutput = 0;
+
+ Coff_str_table = pCoff_str_table = NULL;
+
+ stext = FindSection(s1, ".text");
+ sdata = FindSection(s1, ".data");
+ sbss = FindSection(s1, ".bss");
+
+ nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
+ coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
+
+ file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
+ file_hdr.f_timdat = 0; /* time & date stamp */
+ file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */
+ file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */
+ file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
+
+ o_filehdr.magic = 0x0108; /* see magic.h */
+ o_filehdr.vstamp = 0x0190; /* version stamp */
+ o_filehdr.tsize = stext->data_offset; /* text size in bytes, padded to FW bdry */
+ o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
+ o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
+ o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
+ o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
+ o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
+
+
+ // create all the section headers
+
+ file_pointer = FILHSZ + sizeof(AOUTHDR);
+
+ CoffTextSectionNo = -1;
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = &section_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ NSectionsToOutput++;
+
+ if (CoffTextSectionNo == -1 && tcc_sect == stext)
+ CoffTextSectionNo = NSectionsToOutput; // rem which coff sect number the .text sect is
+
+ strcpy(coff_sec->s_name, tcc_sect->name); /* section name */
+
+ coff_sec->s_paddr = tcc_sect->sh_addr; /* physical address */
+ coff_sec->s_vaddr = tcc_sect->sh_addr; /* virtual address */
+ coff_sec->s_size = tcc_sect->data_offset; /* section size */
+ coff_sec->s_scnptr = 0; /* file ptr to raw data for section */
+ coff_sec->s_relptr = 0; /* file ptr to relocation */
+ coff_sec->s_lnnoptr = 0; /* file ptr to line numbers */
+ coff_sec->s_nreloc = 0; /* number of relocation entries */
+ coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */
+ coff_sec->s_reserved = 0; /* reserved byte */
+ coff_sec->s_page = 0; /* memory page id */
+
+ file_pointer += sizeof(SCNHDR);
+ }
+ }
+
+ file_hdr.f_nscns = NSectionsToOutput; /* number of sections */
+
+ // now loop through and determine file pointer locations
+ // for the raw data
+
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = &section_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ // put raw data
+ coff_sec->s_scnptr = file_pointer; /* file ptr to raw data for section */
+ file_pointer += coff_sec->s_size;
+ }
+ }
+
+ // now loop through and determine file pointer locations
+ // for the relocation data
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = &section_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ // put relocations data
+ if (coff_sec->s_nreloc > 0) {
+ coff_sec->s_relptr = file_pointer; /* file ptr to relocation */
+ file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
+ }
+ }
+ }
+
+ // now loop through and determine file pointer locations
+ // for the line number data
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = &section_header[i];
+ tcc_sect = s1->sections[i];
+
+ coff_sec->s_nlnno = 0;
+ coff_sec->s_lnnoptr = 0;
+
+ if (s1->do_debug && tcc_sect == stext) {
+ // count how many line nos data
+
+ // also find association between source file name and function
+ // so we can sort the symbol table
+
+
+ Stab_Sym *sym, *sym_end;
+ char func_name[MAX_FUNC_NAME_LENGTH],
+ last_func_name[MAX_FUNC_NAME_LENGTH];
+ unsigned long func_addr, last_pc, pc;
+ const char *incl_files[INCLUDE_STACK_SIZE];
+ int incl_index, len, last_line_num;
+ const char *str, *p;
+
+ coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
+
+
+ func_name[0] = '\0';
+ func_addr = 0;
+ incl_index = 0;
+ last_func_name[0] = '\0';
+ last_pc = 0xffffffff;
+ last_line_num = 1;
+ sym = (Stab_Sym *) stab_section->data + 1;
+ sym_end =
+ (Stab_Sym *) (stab_section->data +
+ stab_section->data_offset);
+
+ nFuncs = 0;
+ while (sym < sym_end) {
+ switch (sym->n_type) {
+ /* function start or end */
+ case N_FUN:
+ if (sym->n_strx == 0) {
+ // end of function
+
+ coff_sec->s_nlnno++;
+ file_pointer += LINESZ;
+
+ pc = sym->n_value + func_addr;
+ func_name[0] = '\0';
+ func_addr = 0;
+ EndAddress[nFuncs] = pc;
+ FuncEntries[nFuncs] =
+ (file_pointer -
+ LineNoFilePtr[nFuncs]) / LINESZ - 1;
+ LastLineNo[nFuncs++] = last_line_num + 1;
+ } else {
+ // beginning of function
+
+ LineNoFilePtr[nFuncs] = file_pointer;
+ coff_sec->s_nlnno++;
+ file_pointer += LINESZ;
+
+ str =
+ (const char *) stabstr_section->data +
+ sym->n_strx;
+
+ p = strchr(str, ':');
+ if (!p) {
+ pstrcpy(func_name, sizeof(func_name), str);
+ pstrcpy(Func[nFuncs], sizeof(func_name), str);
+ } else {
+ len = p - str;
+ if (len > sizeof(func_name) - 1)
+ len = sizeof(func_name) - 1;
+ memcpy(func_name, str, len);
+ memcpy(Func[nFuncs], str, len);
+ func_name[len] = '\0';
+ }
+
+ // save the file that it came in so we can sort later
+ pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
+ incl_files[incl_index - 1]);
+
+ func_addr = sym->n_value;
+ }
+ break;
+
+ /* line number info */
+ case N_SLINE:
+ pc = sym->n_value + func_addr;
+
+ last_pc = pc;
+ last_line_num = sym->n_desc;
+
+ /* XXX: slow! */
+ strcpy(last_func_name, func_name);
+
+ coff_sec->s_nlnno++;
+ file_pointer += LINESZ;
+ break;
+ /* include files */
+ case N_BINCL:
+ str =
+ (const char *) stabstr_section->data + sym->n_strx;
+ add_incl:
+ if (incl_index < INCLUDE_STACK_SIZE) {
+ incl_files[incl_index++] = str;
+ }
+ break;
+ case N_EINCL:
+ if (incl_index > 1)
+ incl_index--;
+ break;
+ case N_SO:
+ if (sym->n_strx == 0) {
+ incl_index = 0; /* end of translation unit */
+ } else {
+ str =
+ (const char *) stabstr_section->data +
+ sym->n_strx;
+ /* do not add path */
+ len = strlen(str);
+ if (len > 0 && str[len - 1] != '/')
+ goto add_incl;
+ }
+ break;
+ }
+ sym++;
+ }
+ }
+
+ }
+
+ file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
+
+ if (s1->do_debug)
+ file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */
+ else
+ file_hdr.f_nsyms = 0;
+
+ file_pointer += file_hdr.f_nsyms * SYMNMLEN;
+
+ // OK now we are all set to write the file
+
+
+ fwrite(&file_hdr, FILHSZ, 1, f);
+ fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
+
+ // write section headers
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = &section_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ fwrite(coff_sec, sizeof(SCNHDR), 1, f);
+ }
+ }
+
+ // write raw data
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = &section_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
+ }
+ }
+
+ // write relocation data
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = &section_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (OutputTheSection(tcc_sect)) {
+ // put relocations data
+ if (coff_sec->s_nreloc > 0) {
+ fwrite(tcc_sect->reloc,
+ coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
+ }
+ }
+ }
+
+
+ // group the symbols in order of filename, func1, func2, etc
+ // finally global symbols
+
+ if (s1->do_debug)
+ SortSymbolTable();
+
+ // write line no data
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ coff_sec = &section_header[i];
+ tcc_sect = s1->sections[i];
+
+ if (s1->do_debug && tcc_sect == stext) {
+ // count how many line nos data
+
+
+ Stab_Sym *sym, *sym_end;
+ char func_name[128], last_func_name[128];
+ unsigned long func_addr, last_pc, pc;
+ const char *incl_files[INCLUDE_STACK_SIZE];
+ int incl_index, len, last_line_num;
+ const char *str, *p;
+
+ LINENO CoffLineNo;
+
+ func_name[0] = '\0';
+ func_addr = 0;
+ incl_index = 0;
+ last_func_name[0] = '\0';
+ last_pc = 0;
+ last_line_num = 1;
+ sym = (Stab_Sym *) stab_section->data + 1;
+ sym_end =
+ (Stab_Sym *) (stab_section->data +
+ stab_section->data_offset);
+
+ while (sym < sym_end) {
+ switch (sym->n_type) {
+ /* function start or end */
+ case N_FUN:
+ if (sym->n_strx == 0) {
+ // end of function
+
+ CoffLineNo.l_addr.l_paddr = last_pc;
+ CoffLineNo.l_lnno = last_line_num + 1;
+ fwrite(&CoffLineNo, 6, 1, f);
+
+ pc = sym->n_value + func_addr;
+ func_name[0] = '\0';
+ func_addr = 0;
+ } else {
+ // beginning of function
+
+ str =
+ (const char *) stabstr_section->data +
+ sym->n_strx;
+
+
+ p = strchr(str, ':');
+ if (!p) {
+ pstrcpy(func_name, sizeof(func_name), str);
+ } else {
+ len = p - str;
+ if (len > sizeof(func_name) - 1)
+ len = sizeof(func_name) - 1;
+ memcpy(func_name, str, len);
+ func_name[len] = '\0';
+ }
+ func_addr = sym->n_value;
+ last_pc = func_addr;
+ last_line_num = -1;
+
+ // output a function begin
+
+ CoffLineNo.l_addr.l_symndx =
+ FindCoffSymbolIndex(func_name);
+ CoffLineNo.l_lnno = 0;
+
+ fwrite(&CoffLineNo, 6, 1, f);
+ }
+ break;
+
+ /* line number info */
+ case N_SLINE:
+ pc = sym->n_value + func_addr;
+
+
+ /* XXX: slow! */
+ strcpy(last_func_name, func_name);
+
+ // output a line reference
+
+ CoffLineNo.l_addr.l_paddr = last_pc;
+
+ if (last_line_num == -1) {
+ CoffLineNo.l_lnno = sym->n_desc;
+ } else {
+ CoffLineNo.l_lnno = last_line_num + 1;
+ }
+
+ fwrite(&CoffLineNo, 6, 1, f);
+
+ last_pc = pc;
+ last_line_num = sym->n_desc;
+
+ break;
+
+ /* include files */
+ case N_BINCL:
+ str =
+ (const char *) stabstr_section->data + sym->n_strx;
+ add_incl2:
+ if (incl_index < INCLUDE_STACK_SIZE) {
+ incl_files[incl_index++] = str;
+ }
+ break;
+ case N_EINCL:
+ if (incl_index > 1)
+ incl_index--;
+ break;
+ case N_SO:
+ if (sym->n_strx == 0) {
+ incl_index = 0; /* end of translation unit */
+ } else {
+ str =
+ (const char *) stabstr_section->data +
+ sym->n_strx;
+ /* do not add path */
+ len = strlen(str);
+ if (len > 0 && str[len - 1] != '/')
+ goto add_incl2;
+ }
+ break;
+ }
+ sym++;
+ }
+ }
+ }
+
+ // write symbol table
+ if (s1->do_debug) {
+ int k;
+ struct syment csym;
+ AUXFUNC auxfunc;
+ AUXBF auxbf;
+ AUXEF auxef;
+ int i;
+ Elf32_Sym *p;
+ const char *name;
+ int nstr;
+ int n = 0;
+
+ Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE);
+ pCoff_str_table = Coff_str_table;
+ nstr = 0;
+
+ p = (Elf32_Sym *) symtab_section->data;
+
+
+ for (i = 0; i < nb_syms; i++) {
+
+ name = symtab_section->link->data + p->st_name;
+
+ for (k = 0; k < 8; k++)
+ csym._n._n_name[k] = 0;
+
+ if (strlen(name) <= 8) {
+ strcpy(csym._n._n_name, name);
+ } else {
+ if (pCoff_str_table - Coff_str_table + strlen(name) >
+ MAX_STR_TABLE - 1)
+ tcc_error("String table too large");
+
+ csym._n._n_n._n_zeroes = 0;
+ csym._n._n_n._n_offset =
+ pCoff_str_table - Coff_str_table + 4;
+
+ strcpy(pCoff_str_table, name);
+ pCoff_str_table += strlen(name) + 1; // skip over null
+ nstr++;
+ }
+
+ if (p->st_info == 4) {
+ // put a filename symbol
+ csym.n_value = 33; // ?????
+ csym.n_scnum = N_DEBUG;
+ csym.n_type = 0;
+ csym.n_sclass = C_FILE;
+ csym.n_numaux = 0;
+ fwrite(&csym, 18, 1, f);
+ n++;
+
+ } else if (p->st_info == 0x12) {
+ // find the function data
+
+ for (k = 0; k < nFuncs; k++) {
+ if (strcmp(name, Func[k]) == 0)
+ break;
+ }
+
+ if (k >= nFuncs) {
+ tcc_error("debug info can't find function: %s", name);
+ }
+ // put a Function Name
+
+ csym.n_value = p->st_value; // physical address
+ csym.n_scnum = CoffTextSectionNo;
+ csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
+ csym.n_sclass = C_EXT;
+ csym.n_numaux = 1;
+ fwrite(&csym, 18, 1, f);
+
+ // now put aux info
+
+ auxfunc.tag = 0;
+ auxfunc.size = EndAddress[k] - p->st_value;
+ auxfunc.fileptr = LineNoFilePtr[k];
+ auxfunc.nextsym = n + 6; // tktk
+ auxfunc.dummy = 0;
+ fwrite(&auxfunc, 18, 1, f);
+
+ // put a .bf
+
+ strcpy(csym._n._n_name, ".bf");
+ csym.n_value = p->st_value; // physical address
+ csym.n_scnum = CoffTextSectionNo;
+ csym.n_type = 0;
+ csym.n_sclass = C_FCN;
+ csym.n_numaux = 1;
+ fwrite(&csym, 18, 1, f);
+
+ // now put aux info
+
+ auxbf.regmask = 0;
+ auxbf.lineno = 0;
+ auxbf.nentries = FuncEntries[k];
+ auxbf.localframe = 0;
+ auxbf.nextentry = n + 6;
+ auxbf.dummy = 0;
+ fwrite(&auxbf, 18, 1, f);
+
+ // put a .ef
+
+ strcpy(csym._n._n_name, ".ef");
+ csym.n_value = EndAddress[k]; // physical address
+ csym.n_scnum = CoffTextSectionNo;
+ csym.n_type = 0;
+ csym.n_sclass = C_FCN;
+ csym.n_numaux = 1;
+ fwrite(&csym, 18, 1, f);
+
+ // now put aux info
+
+ auxef.dummy = 0;
+ auxef.lineno = LastLineNo[k];
+ auxef.dummy1 = 0;
+ auxef.dummy2 = 0;
+ auxef.dummy3 = 0;
+ auxef.dummy4 = 0;
+ fwrite(&auxef, 18, 1, f);
+
+ n += 6;
+
+ } else {
+ // try an put some type info
+
+ if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
+ csym.n_type = T_DOUBLE; // int
+ csym.n_sclass = C_EXT;
+ } else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
+ csym.n_type = T_FLOAT;
+ csym.n_sclass = C_EXT;
+ } else if ((p->st_other & VT_BTYPE) == VT_INT) {
+ csym.n_type = T_INT; // int
+ csym.n_sclass = C_EXT;
+ } else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
+ csym.n_type = T_SHORT;
+ csym.n_sclass = C_EXT;
+ } else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
+ csym.n_type = T_CHAR;
+ csym.n_sclass = C_EXT;
+ } else {
+ csym.n_type = T_INT; // just mark as a label
+ csym.n_sclass = C_LABEL;
+ }
+
+
+ csym.n_value = p->st_value;
+ csym.n_scnum = 2;
+ csym.n_numaux = 1;
+ fwrite(&csym, 18, 1, f);
+
+ auxfunc.tag = 0;
+ auxfunc.size = 0x20;
+ auxfunc.fileptr = 0;
+ auxfunc.nextsym = 0;
+ auxfunc.dummy = 0;
+ fwrite(&auxfunc, 18, 1, f);
+ n++;
+ n++;
+
+ }
+
+ p++;
+ }
+ }
+
+ if (s1->do_debug) {
+ // write string table
+
+ // first write the size
+ i = pCoff_str_table - Coff_str_table;
+ fwrite(&i, 4, 1, f);
+
+ // then write the strings
+ fwrite(Coff_str_table, i, 1, f);
+
+ tcc_free(Coff_str_table);
+ }
+
+ return 0;
+}
+
+
+
+// group the symbols in order of filename, func1, func2, etc
+// finally global symbols
+
+void SortSymbolTable(void)
+{
+ int i, j, k, n = 0;
+ Elf32_Sym *p, *p2, *NewTable;
+ char *name, *name2;
+
+ NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
+
+ p = (Elf32_Sym *) symtab_section->data;
+
+
+ // find a file symbol, copy it over
+ // then scan the whole symbol list and copy any function
+ // symbols that match the file association
+
+ for (i = 0; i < nb_syms; i++) {
+ if (p->st_info == 4) {
+ name = (char *) symtab_section->link->data + p->st_name;
+
+ // this is a file symbol, copy it over
+
+ NewTable[n++] = *p;
+
+ p2 = (Elf32_Sym *) symtab_section->data;
+
+ for (j = 0; j < nb_syms; j++) {
+ if (p2->st_info == 0x12) {
+ // this is a func symbol
+
+ name2 =
+ (char *) symtab_section->link->data + p2->st_name;
+
+ // find the function data index
+
+ for (k = 0; k < nFuncs; k++) {
+ if (strcmp(name2, Func[k]) == 0)
+ break;
+ }
+
+ if (k >= nFuncs) {
+ tcc_error("debug (sort) info can't find function: %s", name2);
+ }
+
+ if (strcmp(AssociatedFile[k], name) == 0) {
+ // yes they match copy it over
+
+ NewTable[n++] = *p2;
+ }
+ }
+ p2++;
+ }
+ }
+ p++;
+ }
+
+ // now all the filename and func symbols should have been copied over
+ // copy all the rest over (all except file and funcs)
+
+ p = (Elf32_Sym *) symtab_section->data;
+ for (i = 0; i < nb_syms; i++) {
+ if (p->st_info != 4 && p->st_info != 0x12) {
+ NewTable[n++] = *p;
+ }
+ p++;
+ }
+
+ if (n != nb_syms)
+ tcc_error("Internal Compiler error, debug info");
+
+ // copy it all back
+
+ p = (Elf32_Sym *) symtab_section->data;
+ for (i = 0; i < nb_syms; i++) {
+ *p++ = NewTable[i];
+ }
+
+ tcc_free(NewTable);
+}
+
+
+int FindCoffSymbolIndex(const char *func_name)
+{
+ int i, n = 0;
+ Elf32_Sym *p;
+ char *name;
+
+ p = (Elf32_Sym *) symtab_section->data;
+
+ for (i = 0; i < nb_syms; i++) {
+
+ name = (char *) symtab_section->link->data + p->st_name;
+
+ if (p->st_info == 4) {
+ // put a filename symbol
+ n++;
+ } else if (p->st_info == 0x12) {
+
+ if (strcmp(func_name, name) == 0)
+ return n;
+
+ n += 6;
+
+ // put a Function Name
+
+ // now put aux info
+
+ // put a .bf
+
+ // now put aux info
+
+ // put a .ef
+
+ // now put aux info
+
+ } else {
+ n += 2;
+ }
+
+ p++;
+ }
+
+ return n; // total number of symbols
+}
+
+int OutputTheSection(Section * sect)
+{
+ const char *s = sect->name;
+
+ if (!strcmp(s, ".text"))
+ return 1;
+ else if (!strcmp(s, ".data"))
+ return 1;
+ else
+ return 0;
+}
+
+short int GetCoffFlags(const char *s)
+{
+ if (!strcmp(s, ".text"))
+ return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
+ else if (!strcmp(s, ".data"))
+ return STYP_DATA;
+ else if (!strcmp(s, ".bss"))
+ return STYP_BSS;
+ else if (!strcmp(s, ".stack"))
+ return STYP_BSS | STYP_ALIGN | 0x200;
+ else if (!strcmp(s, ".cinit"))
+ return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
+ else
+ return 0;
+}
+
+Section *FindSection(TCCState * s1, const char *sname)
+{
+ Section *s;
+ int i;
+
+ for (i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+
+ if (!strcmp(sname, s->name))
+ return s;
+ }
+
+ tcc_error("could not find section %s", sname);
+ return 0;
+}
+
+ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
+{
+// tktk TokenSym *ts;
+
+ FILE *f;
+ unsigned int str_size;
+ char *Coff_str_table, *name;
+ int i, k;
+ struct syment csym;
+ char name2[9];
+ FILHDR file_hdr; /* FILE HEADER STRUCTURE */
+
+ f = fdopen(fd, "rb");
+ if (!f) {
+ tcc_error("Unable to open .out file for input");
+ }
+
+ if (fread(&file_hdr, FILHSZ, 1, f) != 1)
+ tcc_error("error reading .out file for input");
+
+ if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
+ tcc_error("error reading .out file for input");
+
+ // first read the string table
+
+ if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
+ tcc_error("error reading .out file for input");
+
+ if (fread(&str_size, sizeof(int), 1, f) != 1)
+ tcc_error("error reading .out file for input");
+
+
+ Coff_str_table = (char *) tcc_malloc(str_size);
+
+ if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
+ tcc_error("error reading .out file for input");
+
+ // read/process all the symbols
+
+ // seek back to symbols
+
+ if (fseek(f, file_hdr.f_symptr, SEEK_SET))
+ tcc_error("error reading .out file for input");
+
+ for (i = 0; i < file_hdr.f_nsyms; i++) {
+ if (fread(&csym, SYMESZ, 1, f) != 1)
+ tcc_error("error reading .out file for input");
+
+ if (csym._n._n_n._n_zeroes == 0) {
+ name = Coff_str_table + csym._n._n_n._n_offset - 4;
+ } else {
+ name = csym._n._n_name;
+
+ if (name[7] != 0) {
+ for (k = 0; k < 8; k++)
+ name2[k] = name[k];
+
+ name2[8] = 0;
+
+ name = name2;
+ }
+ }
+// if (strcmp("_DAC_Buffer",name)==0) // tktk
+// name[0]=0;
+
+ if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures
+ (csym.n_type == 0x18 && csym.n_sclass == 0x2) || // pointer to structure
+ (csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles
+ (csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats
+ {
+ // strip off any leading underscore (except for other main routine)
+
+ if (name[0] == '_' && strcmp(name, "_main") != 0)
+ name++;
+
+ tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
+ }
+ // skip any aux records
+
+ if (csym.n_numaux == 1) {
+ if (fread(&csym, SYMESZ, 1, f) != 1)
+ tcc_error("error reading .out file for input");
+ i++;
+ }
+ }
+
+ return 0;
+}
diff --git a/tccelf.c b/tccelf.c
new file mode 100644
index 0000000..70d47e1
--- /dev/null
+++ b/tccelf.c
@@ -0,0 +1,3058 @@
+/*
+ * ELF file handling for TCC
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tcc.h"
+
+/* Define this to get some debug output during relocation processing. */
+#undef DEBUG_RELOC
+
+/********************************************************/
+/* global variables */
+
+ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
+ST_DATA Section *common_section;
+ST_DATA Section *cur_text_section; /* current section where function code is generated */
+#ifdef CONFIG_TCC_ASM
+ST_DATA Section *last_text_section; /* to handle .previous asm directive */
+#endif
+#ifdef CONFIG_TCC_BCHECK
+/* bound check related sections */
+ST_DATA Section *bounds_section; /* contains global data bound description */
+ST_DATA Section *lbounds_section; /* contains local data bound description */
+#endif
+/* symbol sections */
+ST_DATA Section *symtab_section;
+/* debug sections */
+ST_DATA Section *stab_section, *stabstr_section;
+
+/* XXX: avoid static variable */
+static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
+
+/* special flag to indicate that the section should not be linked to the other ones */
+#define SHF_PRIVATE 0x80000000
+/* section is dynsymtab_section */
+#define SHF_DYNSYM 0x40000000
+
+/* ------------------------------------------------------------------------- */
+
+ST_FUNC void tccelf_new(TCCState *s)
+{
+ /* no section zero */
+ dynarray_add(&s->sections, &s->nb_sections, NULL);
+
+ /* create standard sections */
+ text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
+ data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+ bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
+ common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
+ common_section->sh_num = SHN_COMMON;
+
+ /* symbols are always generated for linking stage */
+ symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
+ ".strtab",
+ ".hashtab", SHF_PRIVATE);
+ s->symtab = symtab_section;
+
+ /* private symbol table for dynamic symbols */
+ s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
+ ".dynstrtab",
+ ".dynhashtab", SHF_PRIVATE);
+ get_sym_attr(s, 0, 1);
+}
+
+#ifdef CONFIG_TCC_BCHECK
+ST_FUNC void tccelf_bounds_new(TCCState *s)
+{
+ /* create bounds sections */
+ bounds_section = new_section(s, ".bounds",
+ SHT_PROGBITS, SHF_ALLOC);
+ lbounds_section = new_section(s, ".lbounds",
+ SHT_PROGBITS, SHF_ALLOC);
+}
+#endif
+
+ST_FUNC void tccelf_stab_new(TCCState *s)
+{
+ stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
+ stab_section->sh_entsize = sizeof(Stab_Sym);
+ stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
+ put_elf_str(stabstr_section, "");
+ stab_section->link = stabstr_section;
+ /* put first entry */
+ put_stabs("", 0, 0, 0, 0);
+}
+
+static void free_section(Section *s)
+{
+ tcc_free(s->data);
+}
+
+ST_FUNC void tccelf_delete(TCCState *s1)
+{
+ int i;
+
+ /* free all sections */
+ for(i = 1; i < s1->nb_sections; i++)
+ free_section(s1->sections[i]);
+ dynarray_reset(&s1->sections, &s1->nb_sections);
+
+ for(i = 0; i < s1->nb_priv_sections; i++)
+ free_section(s1->priv_sections[i]);
+ dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
+
+ /* free any loaded DLLs */
+#ifdef TCC_IS_NATIVE
+ for ( i = 0; i < s1->nb_loaded_dlls; i++) {
+ DLLReference *ref = s1->loaded_dlls[i];
+ if ( ref->handle )
+# ifdef _WIN32
+ FreeLibrary((HMODULE)ref->handle);
+# else
+ dlclose(ref->handle);
+# endif
+ }
+#endif
+ /* free loaded dlls array */
+ dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
+ tcc_free(s1->sym_attrs);
+
+ symtab_section = NULL; /* for tccrun.c:rt_printline() */
+}
+
+/* save section data state */
+ST_FUNC void tccelf_begin_file(TCCState *s1)
+{
+ Section *s; int i;
+ for (i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+ s->sh_offset = s->data_offset;
+ }
+ /* disable symbol hashing during compilation */
+ s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
+#if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
+ s1->uw_sym = 0;
+#endif
+}
+
+/* At the end of compilation, convert any UNDEF syms to global, and merge
+ with previously existing symbols */
+ST_FUNC void tccelf_end_file(TCCState *s1)
+{
+ Section *s = s1->symtab;
+ int first_sym, nb_syms, *tr, i;
+
+ first_sym = s->sh_offset / sizeof (ElfSym);
+ nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
+ s->data_offset = s->sh_offset;
+ s->link->data_offset = s->link->sh_offset;
+ s->hash = s->reloc, s->reloc = NULL;
+ tr = tcc_mallocz(nb_syms * sizeof *tr);
+
+ for (i = 0; i < nb_syms; ++i) {
+ ElfSym *sym = (ElfSym*)s->data + first_sym + i;
+ if (sym->st_shndx == SHN_UNDEF
+ && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
+ sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
+ tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
+ sym->st_other, sym->st_shndx, s->link->data + sym->st_name);
+ }
+ /* now update relocations */
+ for (i = 1; i < s1->nb_sections; i++) {
+ Section *sr = s1->sections[i];
+ if (sr->sh_type == SHT_RELX && sr->link == s) {
+ ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
+ ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
+ for (; rel < rel_end; ++rel) {
+ int n = ELFW(R_SYM)(rel->r_info) - first_sym;
+ //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
+ rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
+ }
+ }
+ }
+ tcc_free(tr);
+}
+
+ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
+{
+ Section *sec;
+
+ sec = tcc_mallocz(sizeof(Section) + strlen(name));
+ strcpy(sec->name, name);
+ sec->sh_type = sh_type;
+ sec->sh_flags = sh_flags;
+ switch(sh_type) {
+ case SHT_HASH:
+ case SHT_REL:
+ case SHT_RELA:
+ case SHT_DYNSYM:
+ case SHT_SYMTAB:
+ case SHT_DYNAMIC:
+ sec->sh_addralign = 4;
+ break;
+ case SHT_STRTAB:
+ sec->sh_addralign = 1;
+ break;
+ default:
+ sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
+ break;
+ }
+
+ if (sh_flags & SHF_PRIVATE) {
+ dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
+ } else {
+ sec->sh_num = s1->nb_sections;
+ dynarray_add(&s1->sections, &s1->nb_sections, sec);
+ }
+
+ return sec;
+}
+
+ST_FUNC Section *new_symtab(TCCState *s1,
+ const char *symtab_name, int sh_type, int sh_flags,
+ const char *strtab_name,
+ const char *hash_name, int hash_sh_flags)
+{
+ Section *symtab, *strtab, *hash;
+ int *ptr, nb_buckets;
+
+ symtab = new_section(s1, symtab_name, sh_type, sh_flags);
+ symtab->sh_entsize = sizeof(ElfW(Sym));
+ strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
+ put_elf_str(strtab, "");
+ symtab->link = strtab;
+ put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
+
+ nb_buckets = 1;
+
+ hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
+ hash->sh_entsize = sizeof(int);
+ symtab->hash = hash;
+ hash->link = symtab;
+
+ ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
+ ptr[0] = nb_buckets;
+ ptr[1] = 1;
+ memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
+ return symtab;
+}
+
+/* realloc section and set its content to zero */
+ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
+{
+ unsigned long size;
+ unsigned char *data;
+
+ size = sec->data_allocated;
+ if (size == 0)
+ size = 1;
+ while (size < new_size)
+ size = size * 2;
+ data = tcc_realloc(sec->data, size);
+ memset(data + sec->data_allocated, 0, size - sec->data_allocated);
+ sec->data = data;
+ sec->data_allocated = size;
+}
+
+/* reserve at least 'size' bytes aligned per 'align' in section
+ 'sec' from current offset, and return the aligned offset */
+ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
+{
+ size_t offset, offset1;
+
+ offset = (sec->data_offset + align - 1) & -align;
+ offset1 = offset + size;
+ if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
+ section_realloc(sec, offset1);
+ sec->data_offset = offset1;
+ if (align > sec->sh_addralign)
+ sec->sh_addralign = align;
+ return offset;
+}
+
+/* reserve at least 'size' bytes in section 'sec' from
+ sec->data_offset. */
+ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
+{
+ size_t offset = section_add(sec, size, 1);
+ return sec->data + offset;
+}
+
+/* reserve at least 'size' bytes from section start */
+ST_FUNC void section_reserve(Section *sec, unsigned long size)
+{
+ if (size > sec->data_allocated)
+ section_realloc(sec, size);
+ if (size > sec->data_offset)
+ sec->data_offset = size;
+}
+
+/* return a reference to a section, and create it if it does not
+ exists */
+ST_FUNC Section *find_section(TCCState *s1, const char *name)
+{
+ Section *sec;
+ int i;
+ for(i = 1; i < s1->nb_sections; i++) {
+ sec = s1->sections[i];
+ if (!strcmp(name, sec->name))
+ return sec;
+ }
+ /* sections are created as PROGBITS */
+ return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
+}
+
+/* ------------------------------------------------------------------------- */
+
+ST_FUNC int put_elf_str(Section *s, const char *sym)
+{
+ int offset, len;
+ char *ptr;
+
+ len = strlen(sym) + 1;
+ offset = s->data_offset;
+ ptr = section_ptr_add(s, len);
+ memmove(ptr, sym, len);
+ return offset;
+}
+
+/* elf symbol hashing function */
+static unsigned long elf_hash(const unsigned char *name)
+{
+ unsigned long h = 0, g;
+
+ while (*name) {
+ h = (h << 4) + *name++;
+ g = h & 0xf0000000;
+ if (g)
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ return h;
+}
+
+/* rebuild hash table of section s */
+/* NOTE: we do factorize the hash table code to go faster */
+static void rebuild_hash(Section *s, unsigned int nb_buckets)
+{
+ ElfW(Sym) *sym;
+ int *ptr, *hash, nb_syms, sym_index, h;
+ unsigned char *strtab;
+
+ strtab = s->link->data;
+ nb_syms = s->data_offset / sizeof(ElfW(Sym));
+
+ if (!nb_buckets)
+ nb_buckets = ((int*)s->hash->data)[0];
+
+ s->hash->data_offset = 0;
+ ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
+ ptr[0] = nb_buckets;
+ ptr[1] = nb_syms;
+ ptr += 2;
+ hash = ptr;
+ memset(hash, 0, (nb_buckets + 1) * sizeof(int));
+ ptr += nb_buckets + 1;
+
+ sym = (ElfW(Sym) *)s->data + 1;
+ for(sym_index = 1; sym_index < nb_syms; sym_index++) {
+ if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+ h = elf_hash(strtab + sym->st_name) % nb_buckets;
+ *ptr = hash[h];
+ hash[h] = sym_index;
+ } else {
+ *ptr = 0;
+ }
+ ptr++;
+ sym++;
+ }
+}
+
+/* return the symbol number */
+ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
+ int info, int other, int shndx, const char *name)
+{
+ int name_offset, sym_index;
+ int nbuckets, h;
+ ElfW(Sym) *sym;
+ Section *hs;
+
+ sym = section_ptr_add(s, sizeof(ElfW(Sym)));
+ if (name && name[0])
+ name_offset = put_elf_str(s->link, name);
+ else
+ name_offset = 0;
+ /* XXX: endianness */
+ sym->st_name = name_offset;
+ sym->st_value = value;
+ sym->st_size = size;
+ sym->st_info = info;
+ sym->st_other = other;
+ sym->st_shndx = shndx;
+ sym_index = sym - (ElfW(Sym) *)s->data;
+ hs = s->hash;
+ if (hs) {
+ int *ptr, *base;
+ ptr = section_ptr_add(hs, sizeof(int));
+ base = (int *)hs->data;
+ /* only add global or weak symbols. */
+ if (ELFW(ST_BIND)(info) != STB_LOCAL) {
+ /* add another hashing entry */
+ nbuckets = base[0];
+ h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
+ *ptr = base[2 + h];
+ base[2 + h] = sym_index;
+ base[1]++;
+ /* we resize the hash table */
+ hs->nb_hashed_syms++;
+ if (hs->nb_hashed_syms > 2 * nbuckets) {
+ rebuild_hash(s, 2 * nbuckets);
+ }
+ } else {
+ *ptr = 0;
+ base[1]++;
+ }
+ }
+ return sym_index;
+}
+
+ST_FUNC int find_elf_sym(Section *s, const char *name)
+{
+ ElfW(Sym) *sym;
+ Section *hs;
+ int nbuckets, sym_index, h;
+ const char *name1;
+
+ hs = s->hash;
+ if (!hs)
+ return 0;
+ nbuckets = ((int *)hs->data)[0];
+ h = elf_hash((unsigned char *) name) % nbuckets;
+ sym_index = ((int *)hs->data)[2 + h];
+ while (sym_index != 0) {
+ sym = &((ElfW(Sym) *)s->data)[sym_index];
+ name1 = (char *) s->link->data + sym->st_name;
+ if (!strcmp(name, name1))
+ return sym_index;
+ sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
+ }
+ return 0;
+}
+
+/* return elf symbol value, signal error if 'err' is nonzero */
+ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
+{
+ int sym_index;
+ ElfW(Sym) *sym;
+
+ sym_index = find_elf_sym(s->symtab, name);
+ sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
+ if (!sym_index || sym->st_shndx == SHN_UNDEF) {
+ if (err)
+ tcc_error("%s not defined", name);
+ return 0;
+ }
+ return sym->st_value;
+}
+
+/* return elf symbol value */
+LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
+{
+ return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
+}
+
+#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
+/* return elf symbol value or error */
+ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
+{
+ return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
+}
+#endif
+
+/* add an elf symbol : check if it is already defined and patch
+ it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
+ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
+ int info, int other, int shndx, const char *name)
+{
+ ElfW(Sym) *esym;
+ int sym_bind, sym_index, sym_type, esym_bind;
+ unsigned char sym_vis, esym_vis, new_vis;
+
+ sym_bind = ELFW(ST_BIND)(info);
+ sym_type = ELFW(ST_TYPE)(info);
+ sym_vis = ELFW(ST_VISIBILITY)(other);
+
+ if (sym_bind != STB_LOCAL) {
+ /* we search global or weak symbols */
+ sym_index = find_elf_sym(s, name);
+ if (!sym_index)
+ goto do_def;
+ esym = &((ElfW(Sym) *)s->data)[sym_index];
+ if (esym->st_value == value && esym->st_size == size && esym->st_info == info
+ && esym->st_other == other && esym->st_shndx == shndx)
+ return sym_index;
+ if (esym->st_shndx != SHN_UNDEF) {
+ esym_bind = ELFW(ST_BIND)(esym->st_info);
+ /* propagate the most constraining visibility */
+ /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
+ esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
+ if (esym_vis == STV_DEFAULT) {
+ new_vis = sym_vis;
+ } else if (sym_vis == STV_DEFAULT) {
+ new_vis = esym_vis;
+ } else {
+ new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
+ }
+ esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
+ | new_vis;
+ other = esym->st_other; /* in case we have to patch esym */
+ if (shndx == SHN_UNDEF) {
+ /* ignore adding of undefined symbol if the
+ corresponding symbol is already defined */
+ } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
+ /* global overrides weak, so patch */
+ goto do_patch;
+ } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
+ /* weak is ignored if already global */
+ } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
+ /* keep first-found weak definition, ignore subsequents */
+ } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
+ /* ignore hidden symbols after */
+ } else if ((esym->st_shndx == SHN_COMMON
+ || esym->st_shndx == bss_section->sh_num)
+ && (shndx < SHN_LORESERVE
+ && shndx != bss_section->sh_num)) {
+ /* data symbol gets precedence over common/bss */
+ goto do_patch;
+ } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
+ /* data symbol keeps precedence over common/bss */
+ } else if (s->sh_flags & SHF_DYNSYM) {
+ /* we accept that two DLL define the same symbol */
+ } else if (esym->st_other & ST_ASM_SET) {
+ /* If the existing symbol came from an asm .set
+ we can override. */
+ goto do_patch;
+ } else {
+#if 0
+ printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
+ sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
+#endif
+ tcc_error_noabort("'%s' defined twice", name);
+ }
+ } else {
+ do_patch:
+ esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
+ esym->st_shndx = shndx;
+ new_undef_sym = 1;
+ esym->st_value = value;
+ esym->st_size = size;
+ esym->st_other = other;
+ }
+ } else {
+ do_def:
+ sym_index = put_elf_sym(s, value, size,
+ ELFW(ST_INFO)(sym_bind, sym_type), other,
+ shndx, name);
+ }
+ return sym_index;
+}
+
+/* put relocation */
+ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
+ int type, int symbol, addr_t addend)
+{
+ char buf[256];
+ Section *sr;
+ ElfW_Rel *rel;
+
+ sr = s->reloc;
+ if (!sr) {
+ /* if no relocation section, create it */
+ snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
+ /* if the symtab is allocated, then we consider the relocation
+ are also */
+ sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
+ sr->sh_entsize = sizeof(ElfW_Rel);
+ sr->link = symtab;
+ sr->sh_info = s->sh_num;
+ s->reloc = sr;
+ }
+ rel = section_ptr_add(sr, sizeof(ElfW_Rel));
+ rel->r_offset = offset;
+ rel->r_info = ELFW(R_INFO)(symbol, type);
+#if SHT_RELX == SHT_RELA
+ rel->r_addend = addend;
+#else
+ if (addend)
+ tcc_error("non-zero addend on REL architecture");
+#endif
+}
+
+ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
+ int type, int symbol)
+{
+ put_elf_reloca(symtab, s, offset, type, symbol, 0);
+}
+
+/* Remove relocations for section S->reloc starting at oldrelocoffset
+ that are to the same place, retaining the last of them. As side effect
+ the relocations are sorted. Possibly reduces the number of relocs. */
+ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
+{
+ Section *sr = s->reloc;
+ ElfW_Rel *r, *dest;
+ ssize_t a;
+ ElfW(Addr) addr;
+
+ if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
+ return;
+ /* The relocs we're dealing with are the result of initializer parsing.
+ So they will be mostly in order and there aren't many of them.
+ Secondly we need a stable sort (which qsort isn't). We use
+ a simple insertion sort. */
+ for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
+ ssize_t i = a - sizeof(*r);
+ addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
+ for (; i >= (ssize_t)oldrelocoffset &&
+ ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
+ ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
+ *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
+ *(ElfW_Rel*)(sr->data + i) = tmp;
+ }
+ }
+
+ r = (ElfW_Rel*)(sr->data + oldrelocoffset);
+ dest = r;
+ for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
+ if (dest->r_offset != r->r_offset)
+ dest++;
+ *dest = *r;
+ }
+ sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
+}
+
+/* put stab debug information */
+
+ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
+ unsigned long value)
+{
+ Stab_Sym *sym;
+
+ sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
+ if (str) {
+ sym->n_strx = put_elf_str(stabstr_section, str);
+ } else {
+ sym->n_strx = 0;
+ }
+ sym->n_type = type;
+ sym->n_other = other;
+ sym->n_desc = desc;
+ sym->n_value = value;
+}
+
+ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
+ unsigned long value, Section *sec, int sym_index)
+{
+ put_stabs(str, type, other, desc, value);
+ put_elf_reloc(symtab_section, stab_section,
+ stab_section->data_offset - sizeof(unsigned int),
+ R_DATA_32, sym_index);
+}
+
+ST_FUNC void put_stabn(int type, int other, int desc, int value)
+{
+ put_stabs(NULL, type, other, desc, value);
+}
+
+ST_FUNC void put_stabd(int type, int other, int desc)
+{
+ put_stabs(NULL, type, other, desc, 0);
+}
+
+ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
+{
+ int n;
+ struct sym_attr *tab;
+
+ if (index >= s1->nb_sym_attrs) {
+ if (!alloc)
+ return s1->sym_attrs;
+ /* find immediately bigger power of 2 and reallocate array */
+ n = 1;
+ while (index >= n)
+ n *= 2;
+ tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
+ s1->sym_attrs = tab;
+ memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
+ (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
+ s1->nb_sym_attrs = n;
+ }
+ return &s1->sym_attrs[index];
+}
+
+/* Browse each elem of type <type> in section <sec> starting at elem <startoff>
+ using variable <elem> */
+#define for_each_elem(sec, startoff, elem, type) \
+ for (elem = (type *) sec->data + startoff; \
+ elem < (type *) (sec->data + sec->data_offset); elem++)
+
+/* In an ELF file symbol table, the local symbols must appear below
+ the global and weak ones. Since TCC cannot sort it while generating
+ the code, we must do it after. All the relocation tables are also
+ modified to take into account the symbol table sorting */
+static void sort_syms(TCCState *s1, Section *s)
+{
+ int *old_to_new_syms;
+ ElfW(Sym) *new_syms;
+ int nb_syms, i;
+ ElfW(Sym) *p, *q;
+ ElfW_Rel *rel;
+ Section *sr;
+ int type, sym_index;
+
+ nb_syms = s->data_offset / sizeof(ElfW(Sym));
+ new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
+ old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
+
+ /* first pass for local symbols */
+ p = (ElfW(Sym) *)s->data;
+ q = new_syms;
+ for(i = 0; i < nb_syms; i++) {
+ if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
+ old_to_new_syms[i] = q - new_syms;
+ *q++ = *p;
+ }
+ p++;
+ }
+ /* save the number of local symbols in section header */
+ if( s->sh_size ) /* this 'if' makes IDA happy */
+ s->sh_info = q - new_syms;
+
+ /* then second pass for non local symbols */
+ p = (ElfW(Sym) *)s->data;
+ for(i = 0; i < nb_syms; i++) {
+ if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
+ old_to_new_syms[i] = q - new_syms;
+ *q++ = *p;
+ }
+ p++;
+ }
+
+ /* we copy the new symbols to the old */
+ memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
+ tcc_free(new_syms);
+
+ /* now we modify all the relocations */
+ for(i = 1; i < s1->nb_sections; i++) {
+ sr = s1->sections[i];
+ if (sr->sh_type == SHT_RELX && sr->link == s) {
+ for_each_elem(sr, 0, rel, ElfW_Rel) {
+ sym_index = ELFW(R_SYM)(rel->r_info);
+ type = ELFW(R_TYPE)(rel->r_info);
+ sym_index = old_to_new_syms[sym_index];
+ rel->r_info = ELFW(R_INFO)(sym_index, type);
+ }
+ }
+ }
+
+ tcc_free(old_to_new_syms);
+}
+
+/* relocate symbol table, resolve undefined symbols if do_resolve is
+ true and output error if undefined symbol. */
+ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
+{
+ ElfW(Sym) *sym;
+ int sym_bind, sh_num;
+ const char *name;
+
+ for_each_elem(symtab, 1, sym, ElfW(Sym)) {
+ sh_num = sym->st_shndx;
+ if (sh_num == SHN_UNDEF) {
+ name = (char *) s1->symtab->link->data + sym->st_name;
+ /* Use ld.so to resolve symbol for us (for tcc -run) */
+ if (do_resolve) {
+#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
+ void *addr = dlsym(RTLD_DEFAULT, name);
+ if (addr) {
+ sym->st_value = (addr_t) addr;
+#ifdef DEBUG_RELOC
+ printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
+#endif
+ goto found;
+ }
+#endif
+ /* if dynamic symbol exist, it will be used in relocate_section */
+ } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
+ goto found;
+ /* XXX: _fp_hw seems to be part of the ABI, so we ignore
+ it */
+ if (!strcmp(name, "_fp_hw"))
+ goto found;
+ /* only weak symbols are accepted to be undefined. Their
+ value is zero */
+ sym_bind = ELFW(ST_BIND)(sym->st_info);
+ if (sym_bind == STB_WEAK)
+ sym->st_value = 0;
+ else
+ tcc_error_noabort("undefined symbol '%s'", name);
+ } else if (sh_num < SHN_LORESERVE) {
+ /* add section base */
+ sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
+ }
+ found: ;
+ }
+}
+
+/* relocate a given section (CPU dependent) by applying the relocations
+ in the associated relocation section */
+ST_FUNC void relocate_section(TCCState *s1, Section *s)
+{
+ Section *sr = s->reloc;
+ ElfW_Rel *rel;
+ ElfW(Sym) *sym;
+ int type, sym_index;
+ unsigned char *ptr;
+ addr_t tgt, addr;
+
+ relocate_init(sr);
+
+ for_each_elem(sr, 0, rel, ElfW_Rel) {
+ ptr = s->data + rel->r_offset;
+ sym_index = ELFW(R_SYM)(rel->r_info);
+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+ type = ELFW(R_TYPE)(rel->r_info);
+ tgt = sym->st_value;
+#if SHT_RELX == SHT_RELA
+ tgt += rel->r_addend;
+#endif
+ addr = s->sh_addr + rel->r_offset;
+ relocate(s1, rel, type, ptr, addr, tgt);
+ }
+ /* if the relocation is allocated, we change its symbol table */
+ if (sr->sh_flags & SHF_ALLOC)
+ sr->link = s1->dynsym;
+}
+
+/* relocate relocation table in 'sr' */
+static void relocate_rel(TCCState *s1, Section *sr)
+{
+ Section *s;
+ ElfW_Rel *rel;
+
+ s = s1->sections[sr->sh_info];
+ for_each_elem(sr, 0, rel, ElfW_Rel)
+ rel->r_offset += s->sh_addr;
+}
+
+/* count the number of dynamic relocations so that we can reserve
+ their space */
+static int prepare_dynamic_rel(TCCState *s1, Section *sr)
+{
+ ElfW_Rel *rel;
+ int sym_index, type, count;
+
+ count = 0;
+ for_each_elem(sr, 0, rel, ElfW_Rel) {
+ sym_index = ELFW(R_SYM)(rel->r_info);
+ type = ELFW(R_TYPE)(rel->r_info);
+ switch(type) {
+#if defined(TCC_TARGET_I386)
+ case R_386_32:
+ if (!get_sym_attr(s1, sym_index, 0)->dyn_index
+ && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
+ /* don't fixup unresolved (weak) symbols */
+ rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
+ break;
+ }
+#elif defined(TCC_TARGET_X86_64)
+ case R_X86_64_32:
+ case R_X86_64_32S:
+ case R_X86_64_64:
+#endif
+ count++;
+ break;
+#if defined(TCC_TARGET_I386)
+ case R_386_PC32:
+#elif defined(TCC_TARGET_X86_64)
+ case R_X86_64_PC32:
+#endif
+ if (get_sym_attr(s1, sym_index, 0)->dyn_index)
+ count++;
+ break;
+ default:
+ break;
+ }
+ }
+ if (count) {
+ /* allocate the section */
+ sr->sh_flags |= SHF_ALLOC;
+ sr->sh_size = count * sizeof(ElfW_Rel);
+ }
+ return count;
+}
+
+static void build_got(TCCState *s1)
+{
+ /* if no got, then create it */
+ s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+ s1->got->sh_entsize = 4;
+ set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
+ 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
+ /* keep space for _DYNAMIC pointer and two dummy got entries */
+ section_ptr_add(s1->got, 3 * PTR_SIZE);
+}
+
+/* Create a GOT and (for function call) a PLT entry corresponding to a symbol
+ in s1->symtab. When creating the dynamic symbol table entry for the GOT
+ relocation, use 'size' and 'info' for the corresponding symbol metadata.
+ Returns the offset of the GOT or (if any) PLT entry. */
+static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
+ unsigned long size,
+ int info, int sym_index)
+{
+ int need_plt_entry;
+ const char *name;
+ ElfW(Sym) *sym;
+ struct sym_attr *attr;
+ unsigned got_offset;
+ char plt_name[100];
+ int len;
+
+ need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
+ attr = get_sym_attr(s1, sym_index, 1);
+
+ /* In case a function is both called and its address taken 2 GOT entries
+ are created, one for taking the address (GOT) and the other for the PLT
+ entry (PLTGOT). */
+ if (need_plt_entry ? attr->plt_offset : attr->got_offset)
+ return attr;
+
+ /* create the GOT entry */
+ got_offset = s1->got->data_offset;
+ section_ptr_add(s1->got, PTR_SIZE);
+
+ /* Create the GOT relocation that will insert the address of the object or
+ function of interest in the GOT entry. This is a static relocation for
+ memory output (dlsym will give us the address of symbols) and dynamic
+ relocation otherwise (executable and DLLs). The relocation should be
+ done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
+ associated to a PLT entry) but is currently done at load time for an
+ unknown reason. */
+
+ sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
+ name = (char *) symtab_section->link->data + sym->st_name;
+
+ if (s1->dynsym) {
+ if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
+ /* Hack alarm. We don't want to emit dynamic symbols
+ and symbol based relocs for STB_LOCAL symbols, but rather
+ want to resolve them directly. At this point the symbol
+ values aren't final yet, so we must defer this. We will later
+ have to create a RELATIVE reloc anyway, so we misuse the
+ relocation slot to smuggle the symbol reference until
+ fill_local_got_entries. Not that the sym_index is
+ relative to symtab_section, not s1->dynsym! Nevertheless
+ we use s1->dyn_sym so that if this is the first call
+ that got->reloc is correctly created. Also note that
+ RELATIVE relocs are not normally created for the .got,
+ so the types serves as a marker for later (and is retained
+ also for the final output, which is okay because then the
+ got is just normal data). */
+ put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
+ sym_index);
+ } else {
+ if (0 == attr->dyn_index)
+ attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value, size,
+ info, 0, sym->st_shndx, name);
+ put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
+ attr->dyn_index);
+ }
+ } else {
+ put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
+ sym_index);
+ }
+
+ if (need_plt_entry) {
+ if (!s1->plt) {
+ s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
+ SHF_ALLOC | SHF_EXECINSTR);
+ s1->plt->sh_entsize = 4;
+ }
+
+ attr->plt_offset = create_plt_entry(s1, got_offset, attr);
+
+ /* create a symbol 'sym@plt' for the PLT jump vector */
+ len = strlen(name);
+ if (len > sizeof plt_name - 5)
+ len = sizeof plt_name - 5;
+ memcpy(plt_name, name, len);
+ strcpy(plt_name + len, "@plt");
+ attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
+
+ } else {
+ attr->got_offset = got_offset;
+ }
+
+ return attr;
+}
+
+/* build GOT and PLT entries */
+ST_FUNC void build_got_entries(TCCState *s1)
+{
+ Section *s;
+ ElfW_Rel *rel;
+ ElfW(Sym) *sym;
+ int i, type, gotplt_entry, reloc_type, sym_index;
+ struct sym_attr *attr;
+
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+ if (s->sh_type != SHT_RELX)
+ continue;
+ /* no need to handle got relocations */
+ if (s->link != symtab_section)
+ continue;
+ for_each_elem(s, 0, rel, ElfW_Rel) {
+ type = ELFW(R_TYPE)(rel->r_info);
+ gotplt_entry = gotplt_entry_type(type);
+ sym_index = ELFW(R_SYM)(rel->r_info);
+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+
+ if (gotplt_entry == NO_GOTPLT_ENTRY) {
+ continue;
+ }
+
+ /* Automatically create PLT/GOT [entry] if it is an undefined
+ reference (resolved at runtime), or the symbol is absolute,
+ probably created by tcc_add_symbol, and thus on 64-bit
+ targets might be too far from application code. */
+ if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
+ if (sym->st_shndx == SHN_UNDEF) {
+ ElfW(Sym) *esym;
+ int dynindex;
+ if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
+ continue;
+ /* Relocations for UNDEF symbols would normally need
+ to be transferred into the executable or shared object.
+ If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
+ But TCC doesn't do that (at least for exes), so we
+ need to resolve all such relocs locally. And that
+ means PLT slots for functions in DLLs and COPY relocs for
+ data symbols. COPY relocs were generated in
+ bind_exe_dynsyms (and the symbol adjusted to be defined),
+ and for functions we were generated a dynamic symbol
+ of function type. */
+ if (s1->dynsym) {
+ /* dynsym isn't set for -run :-/ */
+ dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
+ esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
+ if (dynindex
+ && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
+ || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
+ && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
+ goto jmp_slot;
+ }
+ } else if (!(sym->st_shndx == SHN_ABS
+#ifndef TCC_TARGET_ARM
+ && PTR_SIZE == 8
+#endif
+ ))
+ continue;
+ }
+
+#ifdef TCC_TARGET_X86_64
+ if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
+ (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
+ ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)) {
+ rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
+ continue;
+ }
+#endif
+ if (code_reloc(type)) {
+ jmp_slot:
+ reloc_type = R_JMP_SLOT;
+ } else
+ reloc_type = R_GLOB_DAT;
+
+ if (!s1->got)
+ build_got(s1);
+
+ if (gotplt_entry == BUILD_GOT_ONLY)
+ continue;
+
+ attr = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
+ sym_index);
+
+ if (reloc_type == R_JMP_SLOT)
+ rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
+ }
+ }
+}
+
+/* put dynamic tag */
+static void put_dt(Section *dynamic, int dt, addr_t val)
+{
+ ElfW(Dyn) *dyn;
+ dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
+ dyn->d_tag = dt;
+ dyn->d_un.d_val = val;
+}
+
+#ifndef TCC_TARGET_PE
+static void add_init_array_defines(TCCState *s1, const char *section_name)
+{
+ Section *s;
+ long end_offset;
+ char sym_start[1024];
+ char sym_end[1024];
+
+ snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
+ snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
+
+ s = find_section(s1, section_name);
+ if (!s) {
+ end_offset = 0;
+ s = data_section;
+ } else {
+ end_offset = s->data_offset;
+ }
+
+ set_elf_sym(symtab_section,
+ 0, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ s->sh_num, sym_start);
+ set_elf_sym(symtab_section,
+ end_offset, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ s->sh_num, sym_end);
+}
+#endif
+
+static int tcc_add_support(TCCState *s1, const char *filename)
+{
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
+ return tcc_add_file(s1, buf);
+}
+
+ST_FUNC void tcc_add_bcheck(TCCState *s1)
+{
+#ifdef CONFIG_TCC_BCHECK
+ addr_t *ptr;
+ int sym_index;
+
+ if (0 == s1->do_bounds_check)
+ return;
+ /* XXX: add an object file to do that */
+ ptr = section_ptr_add(bounds_section, sizeof(*ptr));
+ *ptr = 0;
+ set_elf_sym(symtab_section, 0, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ bounds_section->sh_num, "__bounds_start");
+ /* pull bcheck.o from libtcc1.a */
+ sym_index = set_elf_sym(symtab_section, 0, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ SHN_UNDEF, "__bound_init");
+ if (s1->output_type != TCC_OUTPUT_MEMORY) {
+ /* add 'call __bound_init()' in .init section */
+ Section *init_section = find_section(s1, ".init");
+ unsigned char *pinit = section_ptr_add(init_section, 5);
+ pinit[0] = 0xe8;
+ write32le(pinit + 1, -4);
+ put_elf_reloc(symtab_section, init_section,
+ init_section->data_offset - 4, R_386_PC32, sym_index);
+ /* R_386_PC32 = R_X86_64_PC32 = 2 */
+ }
+#endif
+}
+
+/* add tcc runtime libraries */
+ST_FUNC void tcc_add_runtime(TCCState *s1)
+{
+ tcc_add_bcheck(s1);
+ tcc_add_pragma_libs(s1);
+ /* add libc */
+ if (!s1->nostdlib) {
+ tcc_add_library_err(s1, "c");
+#ifdef TCC_LIBGCC
+ if (!s1->static_link) {
+ if (TCC_LIBGCC[0] == '/')
+ tcc_add_file(s1, TCC_LIBGCC);
+ else
+ tcc_add_dll(s1, TCC_LIBGCC, 0);
+ }
+#endif
+ tcc_add_support(s1, TCC_LIBTCC1);
+ /* add crt end if not memory output */
+ if (s1->output_type != TCC_OUTPUT_MEMORY)
+ tcc_add_crt(s1, "crtn.o");
+ }
+}
+
+/* add various standard linker symbols (must be done after the
+ sections are filled (for example after allocating common
+ symbols)) */
+static void tcc_add_linker_symbols(TCCState *s1)
+{
+ char buf[1024];
+ int i;
+ Section *s;
+
+ set_elf_sym(symtab_section,
+ text_section->data_offset, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ text_section->sh_num, "_etext");
+ set_elf_sym(symtab_section,
+ data_section->data_offset, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ data_section->sh_num, "_edata");
+ set_elf_sym(symtab_section,
+ bss_section->data_offset, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ bss_section->sh_num, "_end");
+#ifndef TCC_TARGET_PE
+ /* horrible new standard ldscript defines */
+ add_init_array_defines(s1, ".preinit_array");
+ add_init_array_defines(s1, ".init_array");
+ add_init_array_defines(s1, ".fini_array");
+#endif
+
+ /* add start and stop symbols for sections whose name can be
+ expressed in C */
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+ if (s->sh_type == SHT_PROGBITS &&
+ (s->sh_flags & SHF_ALLOC)) {
+ const char *p;
+ int ch;
+
+ /* check if section name can be expressed in C */
+ p = s->name;
+ for(;;) {
+ ch = *p;
+ if (!ch)
+ break;
+ if (!isid(ch) && !isnum(ch))
+ goto next_sec;
+ p++;
+ }
+ snprintf(buf, sizeof(buf), "__start_%s", s->name);
+ set_elf_sym(symtab_section,
+ 0, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ s->sh_num, buf);
+ snprintf(buf, sizeof(buf), "__stop_%s", s->name);
+ set_elf_sym(symtab_section,
+ s->data_offset, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ s->sh_num, buf);
+ }
+ next_sec: ;
+ }
+}
+
+ST_FUNC void resolve_common_syms(TCCState *s1)
+{
+ ElfW(Sym) *sym;
+
+ /* Allocate common symbols in BSS. */
+ for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
+ if (sym->st_shndx == SHN_COMMON) {
+ /* symbol alignment is in st_value for SHN_COMMONs */
+ sym->st_value = section_add(bss_section, sym->st_size,
+ sym->st_value);
+ sym->st_shndx = bss_section->sh_num;
+ }
+ }
+
+ /* Now assign linker provided symbols their value. */
+ tcc_add_linker_symbols(s1);
+}
+
+static void tcc_output_binary(TCCState *s1, FILE *f,
+ const int *sec_order)
+{
+ Section *s;
+ int i, offset, size;
+
+ offset = 0;
+ for(i=1;i<s1->nb_sections;i++) {
+ s = s1->sections[sec_order[i]];
+ if (s->sh_type != SHT_NOBITS &&
+ (s->sh_flags & SHF_ALLOC)) {
+ while (offset < s->sh_offset) {
+ fputc(0, f);
+ offset++;
+ }
+ size = s->sh_size;
+ fwrite(s->data, 1, size, f);
+ offset += size;
+ }
+ }
+}
+
+ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
+{
+ int sym_index = ELFW(R_SYM) (rel->r_info);
+ ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
+ struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
+ unsigned offset = attr->got_offset;
+
+ if (0 == offset)
+ return;
+ section_reserve(s1->got, offset + PTR_SIZE);
+#ifdef TCC_TARGET_X86_64
+ write64le(s1->got->data + offset, sym->st_value);
+#else
+ write32le(s1->got->data + offset, sym->st_value);
+#endif
+}
+
+/* Perform relocation to GOT or PLT entries */
+ST_FUNC void fill_got(TCCState *s1)
+{
+ Section *s;
+ ElfW_Rel *rel;
+ int i;
+
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+ if (s->sh_type != SHT_RELX)
+ continue;
+ /* no need to handle got relocations */
+ if (s->link != symtab_section)
+ continue;
+ for_each_elem(s, 0, rel, ElfW_Rel) {
+ switch (ELFW(R_TYPE) (rel->r_info)) {
+ case R_X86_64_GOT32:
+ case R_X86_64_GOTPCREL:
+ case R_X86_64_GOTPCRELX:
+ case R_X86_64_REX_GOTPCRELX:
+ case R_X86_64_PLT32:
+ fill_got_entry(s1, rel);
+ break;
+ }
+ }
+ }
+}
+
+/* See put_got_entry for a description. This is the second stage
+ where GOT references to local defined symbols are rewritten. */
+static void fill_local_got_entries(TCCState *s1)
+{
+ ElfW_Rel *rel;
+ for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
+ if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
+ int sym_index = ELFW(R_SYM) (rel->r_info);
+ ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
+ struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
+ unsigned offset = attr->got_offset;
+ if (offset != rel->r_offset - s1->got->sh_addr)
+ tcc_error_noabort("huh");
+ rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
+#if SHT_RELX == SHT_RELA
+ rel->r_addend = sym->st_value;
+#else
+ /* All our REL architectures also happen to be 32bit LE. */
+ write32le(s1->got->data + offset, sym->st_value);
+#endif
+ }
+ }
+}
+
+/* Bind symbols of executable: resolve undefined symbols from exported symbols
+ in shared libraries and export non local defined symbols to shared libraries
+ if -rdynamic switch was given on command line */
+static void bind_exe_dynsyms(TCCState *s1)
+{
+ const char *name;
+ int sym_index, index;
+ ElfW(Sym) *sym, *esym;
+ int type;
+
+ /* Resolve undefined symbols from dynamic symbols. When there is a match:
+ - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
+ - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
+ for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
+ if (sym->st_shndx == SHN_UNDEF) {
+ name = (char *) symtab_section->link->data + sym->st_name;
+ sym_index = find_elf_sym(s1->dynsymtab_section, name);
+ if (sym_index) {
+ esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
+ type = ELFW(ST_TYPE)(esym->st_info);
+ if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
+ /* Indirect functions shall have STT_FUNC type in executable
+ * dynsym section. Indeed, a dlsym call following a lazy
+ * resolution would pick the symbol value from the
+ * executable dynsym entry which would contain the address
+ * of the function wanted by the caller of dlsym instead of
+ * the address of the function that would return that
+ * address */
+ int dynindex
+ = put_elf_sym(s1->dynsym, 0, esym->st_size,
+ ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
+ name);
+ int index = sym - (ElfW(Sym) *) symtab_section->data;
+ get_sym_attr(s1, index, 1)->dyn_index = dynindex;
+ } else if (type == STT_OBJECT) {
+ unsigned long offset;
+ ElfW(Sym) *dynsym;
+ offset = bss_section->data_offset;
+ /* XXX: which alignment ? */
+ offset = (offset + 16 - 1) & -16;
+ set_elf_sym (s1->symtab, offset, esym->st_size,
+ esym->st_info, 0, bss_section->sh_num, name);
+ index = put_elf_sym(s1->dynsym, offset, esym->st_size,
+ esym->st_info, 0, bss_section->sh_num,
+ name);
+
+ /* Ensure R_COPY works for weak symbol aliases */
+ if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
+ for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
+ if ((dynsym->st_value == esym->st_value)
+ && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
+ char *dynname = (char *) s1->dynsymtab_section->link->data
+ + dynsym->st_name;
+ put_elf_sym(s1->dynsym, offset, dynsym->st_size,
+ dynsym->st_info, 0,
+ bss_section->sh_num, dynname);
+ break;
+ }
+ }
+ }
+
+ put_elf_reloc(s1->dynsym, bss_section,
+ offset, R_COPY, index);
+ offset += esym->st_size;
+ bss_section->data_offset = offset;
+ }
+ } else {
+ /* STB_WEAK undefined symbols are accepted */
+ /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
+ if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
+ !strcmp(name, "_fp_hw")) {
+ } else {
+ tcc_error_noabort("undefined symbol '%s'", name);
+ }
+ }
+ } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+ /* if -rdynamic option, then export all non local symbols */
+ name = (char *) symtab_section->link->data + sym->st_name;
+ set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
+ 0, sym->st_shndx, name);
+ }
+ }
+}
+
+/* Bind symbols of libraries: export all non local symbols of executable that
+ are referenced by shared libraries. The reason is that the dynamic loader
+ search symbol first in executable and then in libraries. Therefore a
+ reference to a symbol already defined by a library can still be resolved by
+ a symbol in the executable. */
+static void bind_libs_dynsyms(TCCState *s1)
+{
+ const char *name;
+ int sym_index;
+ ElfW(Sym) *sym, *esym;
+
+ for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
+ name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
+ sym_index = find_elf_sym(symtab_section, name);
+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+ if (sym_index && sym->st_shndx != SHN_UNDEF
+ && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+ set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
+ sym->st_info, 0, sym->st_shndx, name);
+ } else if (esym->st_shndx == SHN_UNDEF) {
+ /* weak symbols can stay undefined */
+ if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
+ tcc_warning("undefined dynamic symbol '%s'", name);
+ }
+ }
+}
+
+/* Export all non local symbols. This is used by shared libraries so that the
+ non local symbols they define can resolve a reference in another shared
+ library or in the executable. Correspondingly, it allows undefined local
+ symbols to be resolved by other shared libraries or by the executable. */
+static void export_global_syms(TCCState *s1)
+{
+ int dynindex, index;
+ const char *name;
+ ElfW(Sym) *sym;
+
+ for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
+ if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+ name = (char *) symtab_section->link->data + sym->st_name;
+ dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
+ sym->st_info, 0, sym->st_shndx, name);
+ index = sym - (ElfW(Sym) *) symtab_section->data;
+ get_sym_attr(s1, index, 1)->dyn_index = dynindex;
+ }
+ }
+}
+
+/* Allocate strings for section names and decide if an unallocated section
+ should be output.
+ NOTE: the strsec section comes last, so its size is also correct ! */
+static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
+{
+ int i;
+ Section *s;
+ int textrel = 0;
+
+ /* Allocate strings for section names */
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+ /* when generating a DLL, we include relocations but we may
+ patch them */
+ if (file_type == TCC_OUTPUT_DLL &&
+ s->sh_type == SHT_RELX &&
+ !(s->sh_flags & SHF_ALLOC) &&
+ (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
+ prepare_dynamic_rel(s1, s)) {
+ if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
+ textrel = 1;
+ } else if (s1->do_debug ||
+ file_type == TCC_OUTPUT_OBJ ||
+ (s->sh_flags & SHF_ALLOC) ||
+ i == (s1->nb_sections - 1)) {
+ /* we output all sections if debug or object file */
+ s->sh_size = s->data_offset;
+ }
+ if (s->sh_size || (s->sh_flags & SHF_ALLOC))
+ s->sh_name = put_elf_str(strsec, s->name);
+ }
+ strsec->sh_size = strsec->data_offset;
+ return textrel;
+}
+
+/* Info to be copied in dynamic section */
+struct dyn_inf {
+ Section *dynamic;
+ Section *dynstr;
+ unsigned long data_offset;
+ addr_t rel_addr;
+ addr_t rel_size;
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ addr_t bss_addr;
+ addr_t bss_size;
+#endif
+};
+
+/* Assign sections to segments and decide how are sections laid out when loaded
+ in memory. This function also fills corresponding program headers. */
+static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
+ Section *interp, Section* strsec,
+ struct dyn_inf *dyninf, int *sec_order)
+{
+ int i, j, k, file_type, sh_order_index, file_offset;
+ unsigned long s_align;
+ long long tmp;
+ addr_t addr;
+ ElfW(Phdr) *ph;
+ Section *s;
+
+ file_type = s1->output_type;
+ sh_order_index = 1;
+ file_offset = 0;
+ if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
+ file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
+ s_align = ELF_PAGE_SIZE;
+ if (s1->section_align)
+ s_align = s1->section_align;
+
+ if (phnum > 0) {
+ if (s1->has_text_addr) {
+ int a_offset, p_offset;
+ addr = s1->text_addr;
+ /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
+ ELF_PAGE_SIZE */
+ a_offset = (int) (addr & (s_align - 1));
+ p_offset = file_offset & (s_align - 1);
+ if (a_offset < p_offset)
+ a_offset += s_align;
+ file_offset += (a_offset - p_offset);
+ } else {
+ if (file_type == TCC_OUTPUT_DLL)
+ addr = 0;
+ else
+ addr = ELF_START_ADDR;
+ /* compute address after headers */
+ addr += (file_offset & (s_align - 1));
+ }
+
+ ph = &phdr[0];
+ /* Leave one program headers for the program interpreter and one for
+ the program header table itself if needed. These are done later as
+ they require section layout to be done first. */
+ if (interp)
+ ph += 2;
+
+ /* dynamic relocation table information, for .dynamic section */
+ dyninf->rel_addr = dyninf->rel_size = 0;
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ dyninf->bss_addr = dyninf->bss_size = 0;
+#endif
+
+ for(j = 0; j < 2; j++) {
+ ph->p_type = PT_LOAD;
+ if (j == 0)
+ ph->p_flags = PF_R | PF_X;
+ else
+ ph->p_flags = PF_R | PF_W;
+ ph->p_align = s_align;
+
+ /* Decide the layout of sections loaded in memory. This must
+ be done before program headers are filled since they contain
+ info about the layout. We do the following ordering: interp,
+ symbol tables, relocations, progbits, nobits */
+ /* XXX: do faster and simpler sorting */
+ for(k = 0; k < 5; k++) {
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+ /* compute if section should be included */
+ if (j == 0) {
+ if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
+ SHF_ALLOC)
+ continue;
+ } else {
+ if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
+ (SHF_ALLOC | SHF_WRITE))
+ continue;
+ }
+ if (s == interp) {
+ if (k != 0)
+ continue;
+ } else if (s->sh_type == SHT_DYNSYM ||
+ s->sh_type == SHT_STRTAB ||
+ s->sh_type == SHT_HASH) {
+ if (k != 1)
+ continue;
+ } else if (s->sh_type == SHT_RELX) {
+ if (k != 2)
+ continue;
+ } else if (s->sh_type == SHT_NOBITS) {
+ if (k != 4)
+ continue;
+ } else {
+ if (k != 3)
+ continue;
+ }
+ sec_order[sh_order_index++] = i;
+
+ /* section matches: we align it and add its size */
+ tmp = addr;
+ addr = (addr + s->sh_addralign - 1) &
+ ~(s->sh_addralign - 1);
+ file_offset += (int) ( addr - tmp );
+ s->sh_offset = file_offset;
+ s->sh_addr = addr;
+
+ /* update program header infos */
+ if (ph->p_offset == 0) {
+ ph->p_offset = file_offset;
+ ph->p_vaddr = addr;
+ ph->p_paddr = ph->p_vaddr;
+ }
+ /* update dynamic relocation infos */
+ if (s->sh_type == SHT_RELX) {
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
+ dyninf->rel_addr = addr;
+ dyninf->rel_size += s->sh_size; /* XXX only first rel. */
+ }
+ if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
+ dyninf->bss_addr = addr;
+ dyninf->bss_size = s->sh_size; /* XXX only first rel. */
+ }
+#else
+ if (dyninf->rel_size == 0)
+ dyninf->rel_addr = addr;
+ dyninf->rel_size += s->sh_size;
+#endif
+ }
+ addr += s->sh_size;
+ if (s->sh_type != SHT_NOBITS)
+ file_offset += s->sh_size;
+ }
+ }
+ if (j == 0) {
+ /* Make the first PT_LOAD segment include the program
+ headers itself (and the ELF header as well), it'll
+ come out with same memory use but will make various
+ tools like binutils strip work better. */
+ ph->p_offset &= ~(ph->p_align - 1);
+ ph->p_vaddr &= ~(ph->p_align - 1);
+ ph->p_paddr &= ~(ph->p_align - 1);
+ }
+ ph->p_filesz = file_offset - ph->p_offset;
+ ph->p_memsz = addr - ph->p_vaddr;
+ ph++;
+ if (j == 0) {
+ if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
+ /* if in the middle of a page, we duplicate the page in
+ memory so that one copy is RX and the other is RW */
+ if ((addr & (s_align - 1)) != 0)
+ addr += s_align;
+ } else {
+ addr = (addr + s_align - 1) & ~(s_align - 1);
+ file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
+ }
+ }
+ }
+ }
+
+ /* all other sections come after */
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+ if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
+ continue;
+ sec_order[sh_order_index++] = i;
+
+ file_offset = (file_offset + s->sh_addralign - 1) &
+ ~(s->sh_addralign - 1);
+ s->sh_offset = file_offset;
+ if (s->sh_type != SHT_NOBITS)
+ file_offset += s->sh_size;
+ }
+
+ return file_offset;
+}
+
+static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
+ Section *dynamic)
+{
+ ElfW(Phdr) *ph;
+
+ /* if interpreter, then add corresponding program header */
+ if (interp) {
+ ph = &phdr[0];
+
+ ph->p_type = PT_PHDR;
+ ph->p_offset = sizeof(ElfW(Ehdr));
+ ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
+ ph->p_vaddr = interp->sh_addr - ph->p_filesz;
+ ph->p_paddr = ph->p_vaddr;
+ ph->p_flags = PF_R | PF_X;
+ ph->p_align = 4; /* interp->sh_addralign; */
+ ph++;
+
+ ph->p_type = PT_INTERP;
+ ph->p_offset = interp->sh_offset;
+ ph->p_vaddr = interp->sh_addr;
+ ph->p_paddr = ph->p_vaddr;
+ ph->p_filesz = interp->sh_size;
+ ph->p_memsz = interp->sh_size;
+ ph->p_flags = PF_R;
+ ph->p_align = interp->sh_addralign;
+ }
+
+ /* if dynamic section, then add corresponding program header */
+ if (dynamic) {
+ ph = &phdr[phnum - 1];
+
+ ph->p_type = PT_DYNAMIC;
+ ph->p_offset = dynamic->sh_offset;
+ ph->p_vaddr = dynamic->sh_addr;
+ ph->p_paddr = ph->p_vaddr;
+ ph->p_filesz = dynamic->sh_size;
+ ph->p_memsz = dynamic->sh_size;
+ ph->p_flags = PF_R | PF_W;
+ ph->p_align = dynamic->sh_addralign;
+ }
+}
+
+/* Fill the dynamic section with tags describing the address and size of
+ sections */
+static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
+{
+ Section *dynamic = dyninf->dynamic;
+
+ /* put dynamic section entries */
+ put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
+ put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
+ put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
+ put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
+ put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
+#if PTR_SIZE == 8
+ put_dt(dynamic, DT_RELA, dyninf->rel_addr);
+ put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
+ put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
+#else
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
+ put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
+ put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
+ put_dt(dynamic, DT_PLTREL, DT_REL);
+ put_dt(dynamic, DT_REL, dyninf->bss_addr);
+ put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
+#else
+ put_dt(dynamic, DT_REL, dyninf->rel_addr);
+ put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
+ put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
+#endif
+#endif
+ if (s1->do_debug)
+ put_dt(dynamic, DT_DEBUG, 0);
+ put_dt(dynamic, DT_NULL, 0);
+}
+
+/* Relocate remaining sections and symbols (that is those not related to
+ dynamic linking) */
+static int final_sections_reloc(TCCState *s1)
+{
+ int i;
+ Section *s;
+
+ relocate_syms(s1, s1->symtab, 0);
+
+ if (s1->nb_errors != 0)
+ return -1;
+
+ /* relocate sections */
+ /* XXX: ignore sections with allocated relocations ? */
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+#if defined(TCC_TARGET_I386) || defined(TCC_MUSL)
+ if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
+ /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
+ checking is removed */
+#else
+ if (s->reloc && s != s1->got)
+ /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
+#endif
+ relocate_section(s1, s);
+ }
+
+ /* relocate relocation entries if the relocation tables are
+ allocated in the executable */
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+ if ((s->sh_flags & SHF_ALLOC) &&
+ s->sh_type == SHT_RELX) {
+ relocate_rel(s1, s);
+ }
+ }
+ return 0;
+}
+
+/* Create an ELF file on disk.
+ This function handle ELF specific layout requirements */
+static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
+ int file_offset, int *sec_order)
+{
+ int i, shnum, offset, size, file_type;
+ Section *s;
+ ElfW(Ehdr) ehdr;
+ ElfW(Shdr) shdr, *sh;
+
+ file_type = s1->output_type;
+ shnum = s1->nb_sections;
+
+ memset(&ehdr, 0, sizeof(ehdr));
+
+ if (phnum > 0) {
+ ehdr.e_phentsize = sizeof(ElfW(Phdr));
+ ehdr.e_phnum = phnum;
+ ehdr.e_phoff = sizeof(ElfW(Ehdr));
+ }
+
+ /* align to 4 */
+ file_offset = (file_offset + 3) & -4;
+
+ /* fill header */
+ ehdr.e_ident[0] = ELFMAG0;
+ ehdr.e_ident[1] = ELFMAG1;
+ ehdr.e_ident[2] = ELFMAG2;
+ ehdr.e_ident[3] = ELFMAG3;
+ ehdr.e_ident[4] = ELFCLASSW;
+ ehdr.e_ident[5] = ELFDATA2LSB;
+ ehdr.e_ident[6] = EV_CURRENT;
+#if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
+ /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
+ ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
+#endif
+#ifdef TCC_TARGET_ARM
+#ifdef TCC_ARM_EABI
+ ehdr.e_ident[EI_OSABI] = 0;
+ ehdr.e_flags = EF_ARM_EABI_VER4;
+ if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
+ ehdr.e_flags |= EF_ARM_HASENTRY;
+ if (s1->float_abi == ARM_HARD_FLOAT)
+ ehdr.e_flags |= EF_ARM_VFP_FLOAT;
+ else
+ ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
+#else
+ ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
+#endif
+#endif
+ switch(file_type) {
+ default:
+ case TCC_OUTPUT_EXE:
+ ehdr.e_type = ET_EXEC;
+ ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
+ break;
+ case TCC_OUTPUT_DLL:
+ ehdr.e_type = ET_DYN;
+ ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
+ break;
+ case TCC_OUTPUT_OBJ:
+ ehdr.e_type = ET_REL;
+ break;
+ }
+ ehdr.e_machine = EM_TCC_TARGET;
+ ehdr.e_version = EV_CURRENT;
+ ehdr.e_shoff = file_offset;
+ ehdr.e_ehsize = sizeof(ElfW(Ehdr));
+ ehdr.e_shentsize = sizeof(ElfW(Shdr));
+ ehdr.e_shnum = shnum;
+ ehdr.e_shstrndx = shnum - 1;
+
+ fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
+ fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
+ offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
+
+ sort_syms(s1, symtab_section);
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[sec_order[i]];
+ if (s->sh_type != SHT_NOBITS) {
+ while (offset < s->sh_offset) {
+ fputc(0, f);
+ offset++;
+ }
+ size = s->sh_size;
+ if (size)
+ fwrite(s->data, 1, size, f);
+ offset += size;
+ }
+ }
+
+ /* output section headers */
+ while (offset < ehdr.e_shoff) {
+ fputc(0, f);
+ offset++;
+ }
+
+ for(i = 0; i < s1->nb_sections; i++) {
+ sh = &shdr;
+ memset(sh, 0, sizeof(ElfW(Shdr)));
+ s = s1->sections[i];
+ if (s) {
+ sh->sh_name = s->sh_name;
+ sh->sh_type = s->sh_type;
+ sh->sh_flags = s->sh_flags;
+ sh->sh_entsize = s->sh_entsize;
+ sh->sh_info = s->sh_info;
+ if (s->link)
+ sh->sh_link = s->link->sh_num;
+ sh->sh_addralign = s->sh_addralign;
+ sh->sh_addr = s->sh_addr;
+ sh->sh_offset = s->sh_offset;
+ sh->sh_size = s->sh_size;
+ }
+ fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
+ }
+}
+
+/* Write an elf, coff or "binary" file */
+static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
+ ElfW(Phdr) *phdr, int file_offset, int *sec_order)
+{
+ int fd, mode, file_type;
+ FILE *f;
+
+ file_type = s1->output_type;
+ if (file_type == TCC_OUTPUT_OBJ)
+ mode = 0666;
+ else
+ mode = 0777;
+ unlink(filename);
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
+ if (fd < 0) {
+ tcc_error_noabort("could not write '%s'", filename);
+ return -1;
+ }
+ f = fdopen(fd, "wb");
+ if (s1->verbose)
+ printf("<- %s\n", filename);
+
+#ifdef TCC_TARGET_COFF
+ if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
+ tcc_output_coff(s1, f);
+ else
+#endif
+ if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
+ tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
+ else
+ tcc_output_binary(s1, f, sec_order);
+ fclose(f);
+
+ return 0;
+}
+
+/* Sort section headers by assigned sh_addr, remove sections
+ that we aren't going to output. */
+static void tidy_section_headers(TCCState *s1, int *sec_order)
+{
+ int i, nnew, l, *backmap;
+ Section **snew, *s;
+ ElfW(Sym) *sym;
+
+ snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
+ backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
+ for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
+ s = s1->sections[sec_order[i]];
+ if (!i || s->sh_name) {
+ backmap[sec_order[i]] = nnew;
+ snew[nnew] = s;
+ ++nnew;
+ } else {
+ backmap[sec_order[i]] = 0;
+ snew[--l] = s;
+ }
+ }
+ for (i = 0; i < nnew; i++) {
+ s = snew[i];
+ if (s) {
+ s->sh_num = i;
+ if (s->sh_type == SHT_RELX)
+ s->sh_info = backmap[s->sh_info];
+ }
+ }
+
+ for_each_elem(symtab_section, 1, sym, ElfW(Sym))
+ if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
+ sym->st_shndx = backmap[sym->st_shndx];
+ if( !s1->static_link ) {
+ for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
+ if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
+ sym->st_shndx = backmap[sym->st_shndx];
+ }
+ for (i = 0; i < s1->nb_sections; i++)
+ sec_order[i] = i;
+ tcc_free(s1->sections);
+ s1->sections = snew;
+ s1->nb_sections = nnew;
+ tcc_free(backmap);
+}
+
+/* Output an elf, coff or binary file */
+/* XXX: suppress unneeded sections */
+static int elf_output_file(TCCState *s1, const char *filename)
+{
+ int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
+ struct dyn_inf dyninf = {0};
+ ElfW(Phdr) *phdr;
+ ElfW(Sym) *sym;
+ Section *strsec, *interp, *dynamic, *dynstr;
+ int textrel;
+
+ file_type = s1->output_type;
+ s1->nb_errors = 0;
+ ret = -1;
+ phdr = NULL;
+ sec_order = NULL;
+ interp = dynamic = dynstr = NULL; /* avoid warning */
+ textrel = 0;
+
+ if (file_type != TCC_OUTPUT_OBJ) {
+ /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
+ tcc_add_runtime(s1);
+ resolve_common_syms(s1);
+
+ if (!s1->static_link) {
+ if (file_type == TCC_OUTPUT_EXE) {
+ char *ptr;
+ /* allow override the dynamic loader */
+ const char *elfint = getenv("LD_SO");
+ if (elfint == NULL)
+ elfint = DEFAULT_ELFINTERP(s1);
+ /* add interpreter section only if executable */
+ interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
+ interp->sh_addralign = 1;
+ ptr = section_ptr_add(interp, 1 + strlen(elfint));
+ strcpy(ptr, elfint);
+ }
+
+ /* add dynamic symbol table */
+ s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
+ ".dynstr",
+ ".hash", SHF_ALLOC);
+ dynstr = s1->dynsym->link;
+
+ /* add dynamic section */
+ dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
+ SHF_ALLOC | SHF_WRITE);
+ dynamic->link = dynstr;
+ dynamic->sh_entsize = sizeof(ElfW(Dyn));
+
+ build_got(s1);
+
+ if (file_type == TCC_OUTPUT_EXE) {
+ bind_exe_dynsyms(s1);
+ if (s1->nb_errors)
+ goto the_end;
+ bind_libs_dynsyms(s1);
+ } else {
+ /* shared library case: simply export all global symbols */
+ export_global_syms(s1);
+ }
+ }
+ build_got_entries(s1);
+ }
+
+ /* we add a section for symbols */
+ strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
+ put_elf_str(strsec, "");
+
+ /* Allocate strings for section names */
+ textrel = alloc_sec_names(s1, file_type, strsec);
+
+ if (dynamic) {
+ /* add a list of needed dlls */
+ for(i = 0; i < s1->nb_loaded_dlls; i++) {
+ DLLReference *dllref = s1->loaded_dlls[i];
+ if (dllref->level == 0)
+ put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
+ }
+
+ if (s1->rpath)
+ put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
+ put_elf_str(dynstr, s1->rpath));
+
+ if (file_type == TCC_OUTPUT_DLL) {
+ if (s1->soname)
+ put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
+ /* XXX: currently, since we do not handle PIC code, we
+ must relocate the readonly segments */
+ if (textrel)
+ put_dt(dynamic, DT_TEXTREL, 0);
+ }
+
+ if (s1->symbolic)
+ put_dt(dynamic, DT_SYMBOLIC, 0);
+
+ dyninf.dynamic = dynamic;
+ dyninf.dynstr = dynstr;
+ /* remember offset and reserve space for 2nd call below */
+ dyninf.data_offset = dynamic->data_offset;
+ fill_dynamic(s1, &dyninf);
+ dynamic->sh_size = dynamic->data_offset;
+ dynstr->sh_size = dynstr->data_offset;
+ }
+
+ /* compute number of program headers */
+ if (file_type == TCC_OUTPUT_OBJ)
+ phnum = 0;
+ else if (file_type == TCC_OUTPUT_DLL)
+ phnum = 3;
+ else if (s1->static_link)
+ phnum = 2;
+ else
+ phnum = 5;
+
+ /* allocate program segment headers */
+ phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
+
+ /* compute number of sections */
+ shnum = s1->nb_sections;
+
+ /* this array is used to reorder sections in the output file */
+ sec_order = tcc_malloc(sizeof(int) * shnum);
+ sec_order[0] = 0;
+
+ /* compute section to program header mapping */
+ file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
+ sec_order);
+
+ /* Fill remaining program header and finalize relocation related to dynamic
+ linking. */
+ if (file_type != TCC_OUTPUT_OBJ) {
+ fill_unloadable_phdr(phdr, phnum, interp, dynamic);
+ if (dynamic) {
+ dynamic->data_offset = dyninf.data_offset;
+ fill_dynamic(s1, &dyninf);
+
+ /* put in GOT the dynamic section address and relocate PLT */
+ write32le(s1->got->data, dynamic->sh_addr);
+ if (file_type == TCC_OUTPUT_EXE
+ || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
+ relocate_plt(s1);
+
+ /* relocate symbols in .dynsym now that final addresses are known */
+ for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
+ if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
+ /* do symbol relocation */
+ sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
+ }
+ }
+ }
+
+ /* if building executable or DLL, then relocate each section
+ except the GOT which is already relocated */
+ ret = final_sections_reloc(s1);
+ if (ret)
+ goto the_end;
+ tidy_section_headers(s1, sec_order);
+
+ /* Perform relocation to GOT or PLT entries */
+ if (file_type == TCC_OUTPUT_EXE && s1->static_link)
+ fill_got(s1);
+ else if (s1->got)
+ fill_local_got_entries(s1);
+ }
+
+ /* Create the ELF file with name 'filename' */
+ ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
+ s1->nb_sections = shnum;
+ the_end:
+ tcc_free(sec_order);
+ tcc_free(phdr);
+ return ret;
+}
+
+LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
+{
+ int ret;
+#ifdef TCC_TARGET_PE
+ if (s->output_type != TCC_OUTPUT_OBJ) {
+ ret = pe_output_file(s, filename);
+ } else
+#endif
+ ret = elf_output_file(s, filename);
+ return ret;
+}
+
+static void *load_data(int fd, unsigned long file_offset, unsigned long size)
+{
+ void *data;
+
+ data = tcc_malloc(size);
+ lseek(fd, file_offset, SEEK_SET);
+ read(fd, data, size);
+ return data;
+}
+
+typedef struct SectionMergeInfo {
+ Section *s; /* corresponding existing section */
+ unsigned long offset; /* offset of the new section in the existing section */
+ uint8_t new_section; /* true if section 's' was added */
+ uint8_t link_once; /* true if link once section */
+} SectionMergeInfo;
+
+ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
+{
+ int size = read(fd, h, sizeof *h);
+ if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
+ if (h->e_type == ET_REL)
+ return AFF_BINTYPE_REL;
+ if (h->e_type == ET_DYN)
+ return AFF_BINTYPE_DYN;
+ } else if (size >= 8) {
+ if (0 == memcmp(h, ARMAG, 8))
+ return AFF_BINTYPE_AR;
+#ifdef TCC_TARGET_COFF
+ if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
+ return AFF_BINTYPE_C67;
+#endif
+ }
+ return 0;
+}
+
+/* load an object file and merge it with current files */
+/* XXX: handle correctly stab (debug) info */
+ST_FUNC int tcc_load_object_file(TCCState *s1,
+ int fd, unsigned long file_offset)
+{
+ ElfW(Ehdr) ehdr;
+ ElfW(Shdr) *shdr, *sh;
+ int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
+ unsigned char *strsec, *strtab;
+ int *old_to_new_syms;
+ char *sh_name, *name;
+ SectionMergeInfo *sm_table, *sm;
+ ElfW(Sym) *sym, *symtab;
+ ElfW_Rel *rel;
+ Section *s;
+
+ int stab_index;
+ int stabstr_index;
+
+ stab_index = stabstr_index = 0;
+
+ lseek(fd, file_offset, SEEK_SET);
+ if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
+ goto fail1;
+ /* test CPU specific stuff */
+ if (ehdr.e_ident[5] != ELFDATA2LSB ||
+ ehdr.e_machine != EM_TCC_TARGET) {
+ fail1:
+ tcc_error_noabort("invalid object file");
+ return -1;
+ }
+ /* read sections */
+ shdr = load_data(fd, file_offset + ehdr.e_shoff,
+ sizeof(ElfW(Shdr)) * ehdr.e_shnum);
+ sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
+
+ /* load section names */
+ sh = &shdr[ehdr.e_shstrndx];
+ strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
+
+ /* load symtab and strtab */
+ old_to_new_syms = NULL;
+ symtab = NULL;
+ strtab = NULL;
+ nb_syms = 0;
+ seencompressed = 0;
+ for(i = 1; i < ehdr.e_shnum; i++) {
+ sh = &shdr[i];
+ if (sh->sh_type == SHT_SYMTAB) {
+ if (symtab) {
+ tcc_error_noabort("object must contain only one symtab");
+ fail:
+ ret = -1;
+ goto the_end;
+ }
+ nb_syms = sh->sh_size / sizeof(ElfW(Sym));
+ symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
+ sm_table[i].s = symtab_section;
+
+ /* now load strtab */
+ sh = &shdr[sh->sh_link];
+ strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
+ }
+ if (sh->sh_flags & SHF_COMPRESSED)
+ seencompressed = 1;
+ }
+
+ /* now examine each section and try to merge its content with the
+ ones in memory */
+ for(i = 1; i < ehdr.e_shnum; i++) {
+ /* no need to examine section name strtab */
+ if (i == ehdr.e_shstrndx)
+ continue;
+ sh = &shdr[i];
+ sh_name = (char *) strsec + sh->sh_name;
+ /* ignore sections types we do not handle */
+ if (sh->sh_type != SHT_PROGBITS &&
+ sh->sh_type != SHT_RELX &&
+#ifdef TCC_ARM_EABI
+ sh->sh_type != SHT_ARM_EXIDX &&
+#endif
+ sh->sh_type != SHT_NOBITS &&
+ sh->sh_type != SHT_PREINIT_ARRAY &&
+ sh->sh_type != SHT_INIT_ARRAY &&
+ sh->sh_type != SHT_FINI_ARRAY &&
+ strcmp(sh_name, ".stabstr")
+ )
+ continue;
+ if (seencompressed
+ && (!strncmp(sh_name, ".debug_", sizeof(".debug_")-1)
+ || (sh->sh_type == SHT_RELX
+ && !strncmp((char*)strsec + shdr[sh->sh_info].sh_name,
+ ".debug_", sizeof(".debug_")-1))))
+ continue;
+ if (sh->sh_addralign < 1)
+ sh->sh_addralign = 1;
+ /* find corresponding section, if any */
+ for(j = 1; j < s1->nb_sections;j++) {
+ s = s1->sections[j];
+ if (!strcmp(s->name, sh_name)) {
+ if (!strncmp(sh_name, ".gnu.linkonce",
+ sizeof(".gnu.linkonce") - 1)) {
+ /* if a 'linkonce' section is already present, we
+ do not add it again. It is a little tricky as
+ symbols can still be defined in
+ it. */
+ sm_table[i].link_once = 1;
+ goto next;
+ } else {
+ goto found;
+ }
+ }
+ }
+ /* not found: create new section */
+ s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
+ /* take as much info as possible from the section. sh_link and
+ sh_info will be updated later */
+ s->sh_addralign = sh->sh_addralign;
+ s->sh_entsize = sh->sh_entsize;
+ sm_table[i].new_section = 1;
+ found:
+ if (sh->sh_type != s->sh_type) {
+ tcc_error_noabort("invalid section type");
+ goto fail;
+ }
+
+ /* align start of section */
+ offset = s->data_offset;
+
+ if (0 == strcmp(sh_name, ".stab")) {
+ stab_index = i;
+ goto no_align;
+ }
+ if (0 == strcmp(sh_name, ".stabstr")) {
+ stabstr_index = i;
+ goto no_align;
+ }
+
+ size = sh->sh_addralign - 1;
+ offset = (offset + size) & ~size;
+ if (sh->sh_addralign > s->sh_addralign)
+ s->sh_addralign = sh->sh_addralign;
+ s->data_offset = offset;
+ no_align:
+ sm_table[i].offset = offset;
+ sm_table[i].s = s;
+ /* concatenate sections */
+ size = sh->sh_size;
+ if (sh->sh_type != SHT_NOBITS) {
+ unsigned char *ptr;
+ lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
+ ptr = section_ptr_add(s, size);
+ read(fd, ptr, size);
+ } else {
+ s->data_offset += size;
+ }
+ next: ;
+ }
+
+ /* gr relocate stab strings */
+ if (stab_index && stabstr_index) {
+ Stab_Sym *a, *b;
+ unsigned o;
+ s = sm_table[stab_index].s;
+ a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
+ b = (Stab_Sym *)(s->data + s->data_offset);
+ o = sm_table[stabstr_index].offset;
+ while (a < b)
+ a->n_strx += o, a++;
+ }
+
+ /* second short pass to update sh_link and sh_info fields of new
+ sections */
+ for(i = 1; i < ehdr.e_shnum; i++) {
+ s = sm_table[i].s;
+ if (!s || !sm_table[i].new_section)
+ continue;
+ sh = &shdr[i];
+ if (sh->sh_link > 0)
+ s->link = sm_table[sh->sh_link].s;
+ if (sh->sh_type == SHT_RELX) {
+ s->sh_info = sm_table[sh->sh_info].s->sh_num;
+ /* update backward link */
+ s1->sections[s->sh_info]->reloc = s;
+ }
+ }
+ sm = sm_table;
+
+ /* resolve symbols */
+ old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
+
+ sym = symtab + 1;
+ for(i = 1; i < nb_syms; i++, sym++) {
+ if (sym->st_shndx != SHN_UNDEF &&
+ sym->st_shndx < SHN_LORESERVE) {
+ sm = &sm_table[sym->st_shndx];
+ if (sm->link_once) {
+ /* if a symbol is in a link once section, we use the
+ already defined symbol. It is very important to get
+ correct relocations */
+ if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+ name = (char *) strtab + sym->st_name;
+ sym_index = find_elf_sym(symtab_section, name);
+ if (sym_index)
+ old_to_new_syms[i] = sym_index;
+ }
+ continue;
+ }
+ /* if no corresponding section added, no need to add symbol */
+ if (!sm->s)
+ continue;
+ /* convert section number */
+ sym->st_shndx = sm->s->sh_num;
+ /* offset value */
+ sym->st_value += sm->offset;
+ }
+ /* add symbol */
+ name = (char *) strtab + sym->st_name;
+ sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
+ sym->st_info, sym->st_other,
+ sym->st_shndx, name);
+ old_to_new_syms[i] = sym_index;
+ }
+
+ /* third pass to patch relocation entries */
+ for(i = 1; i < ehdr.e_shnum; i++) {
+ s = sm_table[i].s;
+ if (!s)
+ continue;
+ sh = &shdr[i];
+ offset = sm_table[i].offset;
+ switch(s->sh_type) {
+ case SHT_RELX:
+ /* take relocation offset information */
+ offseti = sm_table[sh->sh_info].offset;
+ for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
+ int type;
+ unsigned sym_index;
+ /* convert symbol index */
+ type = ELFW(R_TYPE)(rel->r_info);
+ sym_index = ELFW(R_SYM)(rel->r_info);
+ /* NOTE: only one symtab assumed */
+ if (sym_index >= nb_syms)
+ goto invalid_reloc;
+ sym_index = old_to_new_syms[sym_index];
+ /* ignore link_once in rel section. */
+ if (!sym_index && !sm->link_once
+#ifdef TCC_TARGET_ARM
+ && type != R_ARM_V4BX
+#endif
+ ) {
+ invalid_reloc:
+ tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
+ i, strsec + sh->sh_name, rel->r_offset);
+ goto fail;
+ }
+ rel->r_info = ELFW(R_INFO)(sym_index, type);
+ /* offset the relocation offset */
+ rel->r_offset += offseti;
+#ifdef TCC_TARGET_ARM
+ /* Jumps and branches from a Thumb code to a PLT entry need
+ special handling since PLT entries are ARM code.
+ Unconditional bl instructions referencing PLT entries are
+ handled by converting these instructions into blx
+ instructions. Other case of instructions referencing a PLT
+ entry require to add a Thumb stub before the PLT entry to
+ switch to ARM mode. We set bit plt_thumb_stub of the
+ attribute of a symbol to indicate such a case. */
+ if (type == R_ARM_THM_JUMP24)
+ get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ ret = 0;
+ the_end:
+ tcc_free(symtab);
+ tcc_free(strtab);
+ tcc_free(old_to_new_syms);
+ tcc_free(sm_table);
+ tcc_free(strsec);
+ tcc_free(shdr);
+ return ret;
+}
+
+typedef struct ArchiveHeader {
+ char ar_name[16]; /* name of this member */
+ char ar_date[12]; /* file mtime */
+ char ar_uid[6]; /* owner uid; printed as decimal */
+ char ar_gid[6]; /* owner gid; printed as decimal */
+ char ar_mode[8]; /* file mode, printed as octal */
+ char ar_size[10]; /* file size, printed as decimal */
+ char ar_fmag[2]; /* should contain ARFMAG */
+} ArchiveHeader;
+
+static int get_be32(const uint8_t *b)
+{
+ return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
+}
+
+static long get_be64(const uint8_t *b)
+{
+ long long ret = get_be32(b);
+ ret = (ret << 32) | (unsigned)get_be32(b+4);
+ return (long)ret;
+}
+
+/* load only the objects which resolve undefined symbols */
+static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
+{
+ long i, bound, nsyms, sym_index, off, ret;
+ uint8_t *data;
+ const char *ar_names, *p;
+ const uint8_t *ar_index;
+ ElfW(Sym) *sym;
+
+ data = tcc_malloc(size);
+ if (read(fd, data, size) != size)
+ goto fail;
+ nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
+ ar_index = data + entrysize;
+ ar_names = (char *) ar_index + nsyms * entrysize;
+
+ do {
+ bound = 0;
+ for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
+ sym_index = find_elf_sym(symtab_section, p);
+ if(sym_index) {
+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+ if(sym->st_shndx == SHN_UNDEF) {
+ off = (entrysize == 4
+ ? get_be32(ar_index + i * 4)
+ : get_be64(ar_index + i * 8))
+ + sizeof(ArchiveHeader);
+ ++bound;
+ if(tcc_load_object_file(s1, fd, off) < 0) {
+ fail:
+ ret = -1;
+ goto the_end;
+ }
+ }
+ }
+ }
+ } while(bound);
+ ret = 0;
+ the_end:
+ tcc_free(data);
+ return ret;
+}
+
+/* load a '.a' file */
+ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
+{
+ ArchiveHeader hdr;
+ char ar_size[11];
+ char ar_name[17];
+ char magic[8];
+ int size, len, i;
+ unsigned long file_offset;
+
+ /* skip magic which was already checked */
+ read(fd, magic, sizeof(magic));
+
+ for(;;) {
+ len = read(fd, &hdr, sizeof(hdr));
+ if (len == 0)
+ break;
+ if (len != sizeof(hdr)) {
+ tcc_error_noabort("invalid archive");
+ return -1;
+ }
+ memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
+ ar_size[sizeof(hdr.ar_size)] = '\0';
+ size = strtol(ar_size, NULL, 0);
+ memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
+ for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
+ if (ar_name[i] != ' ')
+ break;
+ }
+ ar_name[i + 1] = '\0';
+ file_offset = lseek(fd, 0, SEEK_CUR);
+ /* align to even */
+ size = (size + 1) & ~1;
+ if (!strcmp(ar_name, "/")) {
+ /* coff symbol table : we handle it */
+ if(s1->alacarte_link)
+ return tcc_load_alacarte(s1, fd, size, 4);
+ } else if (!strcmp(ar_name, "/SYM64/")) {
+ if(s1->alacarte_link)
+ return tcc_load_alacarte(s1, fd, size, 8);
+ } else {
+ ElfW(Ehdr) ehdr;
+ if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
+ if (tcc_load_object_file(s1, fd, file_offset) < 0)
+ return -1;
+ }
+ }
+ lseek(fd, file_offset + size, SEEK_SET);
+ }
+ return 0;
+}
+
+#ifndef TCC_TARGET_PE
+/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
+ is referenced by the user (so it should be added as DT_NEEDED in
+ the generated ELF file) */
+ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
+{
+ ElfW(Ehdr) ehdr;
+ ElfW(Shdr) *shdr, *sh, *sh1;
+ int i, j, nb_syms, nb_dts, sym_bind, ret;
+ ElfW(Sym) *sym, *dynsym;
+ ElfW(Dyn) *dt, *dynamic;
+ unsigned char *dynstr;
+ const char *name, *soname;
+ DLLReference *dllref;
+
+ read(fd, &ehdr, sizeof(ehdr));
+
+ /* test CPU specific stuff */
+ if (ehdr.e_ident[5] != ELFDATA2LSB ||
+ ehdr.e_machine != EM_TCC_TARGET) {
+ tcc_error_noabort("bad architecture");
+ return -1;
+ }
+
+ /* read sections */
+ shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
+
+ /* load dynamic section and dynamic symbols */
+ nb_syms = 0;
+ nb_dts = 0;
+ dynamic = NULL;
+ dynsym = NULL; /* avoid warning */
+ dynstr = NULL; /* avoid warning */
+ for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
+ switch(sh->sh_type) {
+ case SHT_DYNAMIC:
+ nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
+ dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
+ break;
+ case SHT_DYNSYM:
+ nb_syms = sh->sh_size / sizeof(ElfW(Sym));
+ dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
+ sh1 = &shdr[sh->sh_link];
+ dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* compute the real library name */
+ soname = tcc_basename(filename);
+
+ for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
+ if (dt->d_tag == DT_SONAME) {
+ soname = (char *) dynstr + dt->d_un.d_val;
+ }
+ }
+
+ /* if the dll is already loaded, do not load it */
+ for(i = 0; i < s1->nb_loaded_dlls; i++) {
+ dllref = s1->loaded_dlls[i];
+ if (!strcmp(soname, dllref->name)) {
+ /* but update level if needed */
+ if (level < dllref->level)
+ dllref->level = level;
+ ret = 0;
+ goto the_end;
+ }
+ }
+
+ /* add the dll and its level */
+ dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
+ dllref->level = level;
+ strcpy(dllref->name, soname);
+ dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
+
+ /* add dynamic symbols in dynsym_section */
+ for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
+ sym_bind = ELFW(ST_BIND)(sym->st_info);
+ if (sym_bind == STB_LOCAL)
+ continue;
+ name = (char *) dynstr + sym->st_name;
+ set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
+ sym->st_info, sym->st_other, sym->st_shndx, name);
+ }
+
+ /* load all referenced DLLs */
+ for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
+ switch(dt->d_tag) {
+ case DT_NEEDED:
+ name = (char *) dynstr + dt->d_un.d_val;
+ for(j = 0; j < s1->nb_loaded_dlls; j++) {
+ dllref = s1->loaded_dlls[j];
+ if (!strcmp(name, dllref->name))
+ goto already_loaded;
+ }
+ if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
+ tcc_error_noabort("referenced dll '%s' not found", name);
+ ret = -1;
+ goto the_end;
+ }
+ already_loaded:
+ break;
+ }
+ }
+ ret = 0;
+ the_end:
+ tcc_free(dynstr);
+ tcc_free(dynsym);
+ tcc_free(dynamic);
+ tcc_free(shdr);
+ return ret;
+}
+
+#define LD_TOK_NAME 256
+#define LD_TOK_EOF (-1)
+
+/* return next ld script token */
+static int ld_next(TCCState *s1, char *name, int name_size)
+{
+ int c;
+ char *q;
+
+ redo:
+ switch(ch) {
+ case ' ':
+ case '\t':
+ case '\f':
+ case '\v':
+ case '\r':
+ case '\n':
+ inp();
+ goto redo;
+ case '/':
+ minp();
+ if (ch == '*') {
+ file->buf_ptr = parse_comment(file->buf_ptr);
+ ch = file->buf_ptr[0];
+ goto redo;
+ } else {
+ q = name;
+ *q++ = '/';
+ goto parse_name;
+ }
+ break;
+ case '\\':
+ ch = handle_eob();
+ if (ch != '\\')
+ goto redo;
+ /* fall through */
+ /* case 'a' ... 'z': */
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'h':
+ case 'i':
+ case 'j':
+ case 'k':
+ case 'l':
+ case 'm':
+ case 'n':
+ case 'o':
+ case 'p':
+ case 'q':
+ case 'r':
+ case 's':
+ case 't':
+ case 'u':
+ case 'v':
+ case 'w':
+ case 'x':
+ case 'y':
+ case 'z':
+ /* case 'A' ... 'z': */
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ case 'G':
+ case 'H':
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'N':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'S':
+ case 'T':
+ case 'U':
+ case 'V':
+ case 'W':
+ case 'X':
+ case 'Y':
+ case 'Z':
+ case '_':
+ case '.':
+ case '$':
+ case '~':
+ q = name;
+ parse_name:
+ for(;;) {
+ if (!((ch >= 'a' && ch <= 'z') ||
+ (ch >= 'A' && ch <= 'Z') ||
+ (ch >= '0' && ch <= '9') ||
+ strchr("/.-_+=$:\\,~", ch)))
+ break;
+ if ((q - name) < name_size - 1) {
+ *q++ = ch;
+ }
+ minp();
+ }
+ *q = '\0';
+ c = LD_TOK_NAME;
+ break;
+ case CH_EOF:
+ c = LD_TOK_EOF;
+ break;
+ default:
+ c = ch;
+ inp();
+ break;
+ }
+ return c;
+}
+
+static int ld_add_file(TCCState *s1, const char filename[])
+{
+ if (filename[0] == '/') {
+ if (CONFIG_SYSROOT[0] == '\0'
+ && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
+ return 0;
+ filename = tcc_basename(filename);
+ }
+ return tcc_add_dll(s1, filename, 0);
+}
+
+static inline int new_undef_syms(void)
+{
+ int ret = 0;
+ ret = new_undef_sym;
+ new_undef_sym = 0;
+ return ret;
+}
+
+static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
+{
+ char filename[1024], libname[1024];
+ int t, group, nblibs = 0, ret = 0;
+ char **libs = NULL;
+
+ group = !strcmp(cmd, "GROUP");
+ if (!as_needed)
+ new_undef_syms();
+ t = ld_next(s1, filename, sizeof(filename));
+ if (t != '(')
+ expect("(");
+ t = ld_next(s1, filename, sizeof(filename));
+ for(;;) {
+ libname[0] = '\0';
+ if (t == LD_TOK_EOF) {
+ tcc_error_noabort("unexpected end of file");
+ ret = -1;
+ goto lib_parse_error;
+ } else if (t == ')') {
+ break;
+ } else if (t == '-') {
+ t = ld_next(s1, filename, sizeof(filename));
+ if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
+ tcc_error_noabort("library name expected");
+ ret = -1;
+ goto lib_parse_error;
+ }
+ pstrcpy(libname, sizeof libname, &filename[1]);
+ if (s1->static_link) {
+ snprintf(filename, sizeof filename, "lib%s.a", libname);
+ } else {
+ snprintf(filename, sizeof filename, "lib%s.so", libname);
+ }
+ } else if (t != LD_TOK_NAME) {
+ tcc_error_noabort("filename expected");
+ ret = -1;
+ goto lib_parse_error;
+ }
+ if (!strcmp(filename, "AS_NEEDED")) {
+ ret = ld_add_file_list(s1, cmd, 1);
+ if (ret)
+ goto lib_parse_error;
+ } else {
+ /* TODO: Implement AS_NEEDED support. Ignore it for now */
+ if (!as_needed) {
+ ret = ld_add_file(s1, filename);
+ if (ret)
+ goto lib_parse_error;
+ if (group) {
+ /* Add the filename *and* the libname to avoid future conversions */
+ dynarray_add(&libs, &nblibs, tcc_strdup(filename));
+ if (libname[0] != '\0')
+ dynarray_add(&libs, &nblibs, tcc_strdup(libname));
+ }
+ }
+ }
+ t = ld_next(s1, filename, sizeof(filename));
+ if (t == ',') {
+ t = ld_next(s1, filename, sizeof(filename));
+ }
+ }
+ if (group && !as_needed) {
+ while (new_undef_syms()) {
+ int i;
+
+ for (i = 0; i < nblibs; i ++)
+ ld_add_file(s1, libs[i]);
+ }
+ }
+lib_parse_error:
+ dynarray_reset(&libs, &nblibs);
+ return ret;
+}
+
+/* interpret a subset of GNU ldscripts to handle the dummy libc.so
+ files */
+ST_FUNC int tcc_load_ldscript(TCCState *s1)
+{
+ char cmd[64];
+ char filename[1024];
+ int t, ret;
+
+ ch = handle_eob();
+ for(;;) {
+ t = ld_next(s1, cmd, sizeof(cmd));
+ if (t == LD_TOK_EOF)
+ return 0;
+ else if (t != LD_TOK_NAME)
+ return -1;
+ if (!strcmp(cmd, "INPUT") ||
+ !strcmp(cmd, "GROUP")) {
+ ret = ld_add_file_list(s1, cmd, 0);
+ if (ret)
+ return ret;
+ } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
+ !strcmp(cmd, "TARGET")) {
+ /* ignore some commands */
+ t = ld_next(s1, cmd, sizeof(cmd));
+ if (t != '(')
+ expect("(");
+ for(;;) {
+ t = ld_next(s1, filename, sizeof(filename));
+ if (t == LD_TOK_EOF) {
+ tcc_error_noabort("unexpected end of file");
+ return -1;
+ } else if (t == ')') {
+ break;
+ }
+ }
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+}
+#endif /* !TCC_TARGET_PE */
diff --git a/tccgen.c b/tccgen.c
new file mode 100644
index 0000000..e0b744e
--- /dev/null
+++ b/tccgen.c
@@ -0,0 +1,7386 @@
+/*
+ * TCC - Tiny C Compiler
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tcc.h"
+
+/********************************************************/
+/* global variables */
+
+/* loc : local variable index
+ ind : output code index
+ rsym: return symbol
+ anon_sym: anonymous symbol index
+*/
+ST_DATA int rsym, anon_sym, ind, loc;
+
+ST_DATA Sym *sym_free_first;
+ST_DATA void **sym_pools;
+ST_DATA int nb_sym_pools;
+
+ST_DATA Sym *global_stack;
+ST_DATA Sym *local_stack;
+ST_DATA Sym *define_stack;
+ST_DATA Sym *global_label_stack;
+ST_DATA Sym *local_label_stack;
+static int local_scope;
+static int in_sizeof;
+static int section_sym;
+
+ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
+ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
+ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
+
+ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop;
+
+ST_DATA int const_wanted; /* true if constant wanted */
+ST_DATA int nocode_wanted; /* no code generation wanted */
+#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
+#define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
+ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
+ST_DATA CType func_vt; /* current function return type (used by return instruction) */
+ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
+ST_DATA int func_vc;
+ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
+ST_DATA const char *funcname;
+ST_DATA int g_debug;
+
+ST_DATA CType char_pointer_type, func_old_type, int_type, size_type, ptrdiff_type;
+
+ST_DATA struct switch_t {
+ struct case_t {
+ int64_t v1, v2;
+ int sym;
+ } **p; int n; /* list of case ranges */
+ int def_sym; /* default symbol */
+} *cur_switch; /* current switch */
+
+/* ------------------------------------------------------------------------- */
+
+static void gen_cast(CType *type);
+static void gen_cast_s(int t);
+static inline CType *pointed_type(CType *type);
+static int is_compatible_types(CType *type1, CType *type2);
+static int parse_btype(CType *type, AttributeDef *ad);
+static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
+static void parse_expr_type(CType *type);
+static void init_putv(CType *type, Section *sec, unsigned long c);
+static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
+static void block(int *bsym, int *csym, int is_expr);
+static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
+static void decl(int l);
+static int decl0(int l, int is_for_loop_init, Sym *);
+static void expr_eq(void);
+static void vla_runtime_type_size(CType *type, int *a);
+static void vla_sp_restore(void);
+static void vla_sp_restore_root(void);
+static int is_compatible_unqualified_types(CType *type1, CType *type2);
+static inline int64_t expr_const64(void);
+static void vpush64(int ty, unsigned long long v);
+static void vpush(CType *type);
+static int gvtst(int inv, int t);
+static void gen_inline_functions(TCCState *s);
+static void skip_or_save_block(TokenString **str);
+static void gv_dup(void);
+
+ST_INLN int is_float(int t)
+{
+ int bt;
+ bt = t & VT_BTYPE;
+ return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
+}
+
+/* we use our own 'finite' function to avoid potential problems with
+ non standard math libs */
+/* XXX: endianness dependent */
+ST_FUNC int ieee_finite(double d)
+{
+ int p[4];
+ memcpy(p, &d, sizeof(double));
+ return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
+}
+
+/* compiling intel long double natively */
+#if (defined __i386__ || defined __x86_64__) \
+ && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
+# define TCC_IS_NATIVE_387
+#endif
+
+ST_FUNC void test_lvalue(void)
+{
+ if (!(vtop->r & VT_LVAL))
+ expect("lvalue");
+}
+
+ST_FUNC void check_vstack(void)
+{
+ if (pvtop != vtop)
+ tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
+}
+
+/* ------------------------------------------------------------------------- */
+/* vstack debugging aid */
+
+#if 0
+void pv (const char *lbl, int a, int b)
+{
+ int i;
+ for (i = a; i < a + b; ++i) {
+ SValue *p = &vtop[-i];
+ printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n",
+ lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
+ }
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* start of translation unit info */
+ST_FUNC void tcc_debug_start(TCCState *s1)
+{
+ if (s1->do_debug) {
+ char buf[512];
+
+ /* file info: full path + filename */
+ section_sym = put_elf_sym(symtab_section, 0, 0,
+ ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
+ text_section->sh_num, NULL);
+ getcwd(buf, sizeof(buf));
+#ifdef _WIN32
+ normalize_slashes(buf);
+#endif
+ pstrcat(buf, sizeof(buf), "/");
+ put_stabs_r(buf, N_SO, 0, 0,
+ text_section->data_offset, text_section, section_sym);
+ put_stabs_r(file->filename, N_SO, 0, 0,
+ text_section->data_offset, text_section, section_sym);
+ last_ind = 0;
+ last_line_num = 0;
+ }
+
+ /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
+ symbols can be safely used */
+ put_elf_sym(symtab_section, 0, 0,
+ ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
+ SHN_ABS, file->filename);
+}
+
+/* put end of translation unit info */
+ST_FUNC void tcc_debug_end(TCCState *s1)
+{
+ if (!s1->do_debug)
+ return;
+ put_stabs_r(NULL, N_SO, 0, 0,
+ text_section->data_offset, text_section, section_sym);
+
+}
+
+/* generate line number info */
+ST_FUNC void tcc_debug_line(TCCState *s1)
+{
+ if (!s1->do_debug)
+ return;
+ if ((last_line_num != file->line_num || last_ind != ind)) {
+ put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
+ last_ind = ind;
+ last_line_num = file->line_num;
+ }
+}
+
+/* put function symbol */
+ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
+{
+ char buf[512];
+
+ if (!s1->do_debug)
+ return;
+
+ /* stabs info */
+ /* XXX: we put here a dummy type */
+ snprintf(buf, sizeof(buf), "%s:%c1",
+ funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
+ put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
+ cur_text_section, sym->c);
+ /* //gr gdb wants a line at the function */
+ put_stabn(N_SLINE, 0, file->line_num, 0);
+
+ last_ind = 0;
+ last_line_num = 0;
+}
+
+/* put function size */
+ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
+{
+ if (!s1->do_debug)
+ return;
+ put_stabn(N_FUN, 0, 0, size);
+}
+
+/* ------------------------------------------------------------------------- */
+ST_FUNC int tccgen_compile(TCCState *s1)
+{
+ cur_text_section = NULL;
+ funcname = "";
+ anon_sym = SYM_FIRST_ANOM;
+ section_sym = 0;
+ const_wanted = 0;
+ nocode_wanted = 0x80000000;
+
+ /* define some often used types */
+ int_type.t = VT_INT;
+ char_pointer_type.t = VT_BYTE;
+ mk_pointer(&char_pointer_type);
+#if PTR_SIZE == 4
+ size_type.t = VT_INT | VT_UNSIGNED;
+ ptrdiff_type.t = VT_INT;
+#elif LONG_SIZE == 4
+ size_type.t = VT_LLONG | VT_UNSIGNED;
+ ptrdiff_type.t = VT_LLONG;
+#else
+ size_type.t = VT_LONG | VT_LLONG | VT_UNSIGNED;
+ ptrdiff_type.t = VT_LONG | VT_LLONG;
+#endif
+ func_old_type.t = VT_FUNC;
+ func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
+ func_old_type.ref->f.func_call = FUNC_CDECL;
+ func_old_type.ref->f.func_type = FUNC_OLD;
+
+ tcc_debug_start(s1);
+
+#ifdef TCC_TARGET_ARM
+ arm_init(s1);
+#endif
+
+#ifdef INC_DEBUG
+ printf("%s: **** new file\n", file->filename);
+#endif
+
+ parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
+ next();
+ decl(VT_CONST);
+ gen_inline_functions(s1);
+ check_vstack();
+ /* end of translation unit info */
+ tcc_debug_end(s1);
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+ST_FUNC ElfSym *elfsym(Sym *s)
+{
+ if (!s || !s->c)
+ return NULL;
+ return &((ElfSym *)symtab_section->data)[s->c];
+}
+
+/* apply storage attributes to Elf symbol */
+ST_FUNC void update_storage(Sym *sym)
+{
+ ElfSym *esym;
+ int sym_bind, old_sym_bind;
+
+ esym = elfsym(sym);
+ if (!esym)
+ return;
+
+ if (sym->a.visibility)
+ esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
+ | sym->a.visibility;
+
+ if (sym->type.t & VT_STATIC)
+ sym_bind = STB_LOCAL;
+ else if (sym->a.weak)
+ sym_bind = STB_WEAK;
+ else
+ sym_bind = STB_GLOBAL;
+ old_sym_bind = ELFW(ST_BIND)(esym->st_info);
+ if (sym_bind != old_sym_bind) {
+ esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
+ }
+
+#ifdef TCC_TARGET_PE
+ if (sym->a.dllimport)
+ esym->st_other |= ST_PE_IMPORT;
+ if (sym->a.dllexport)
+ esym->st_other |= ST_PE_EXPORT;
+#endif
+
+#if 0
+ printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
+ get_tok_str(sym->v, NULL),
+ sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g',
+ sym->a.visibility,
+ sym->a.dllexport,
+ sym->a.dllimport
+ );
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
+/* update sym->c so that it points to an external symbol in section
+ 'section' with value 'value' */
+
+ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
+ addr_t value, unsigned long size,
+ int can_add_underscore)
+{
+ int sym_type, sym_bind, info, other, t;
+ ElfSym *esym;
+ const char *name;
+ char buf1[256];
+#ifdef CONFIG_TCC_BCHECK
+ char buf[32];
+#endif
+
+ if (!sym->c) {
+ name = get_tok_str(sym->v, NULL);
+#ifdef CONFIG_TCC_BCHECK
+ if (tcc_state->do_bounds_check) {
+ /* XXX: avoid doing that for statics ? */
+ /* if bound checking is activated, we change some function
+ names by adding the "__bound" prefix */
+ switch(sym->v) {
+#ifdef TCC_TARGET_PE
+ /* XXX: we rely only on malloc hooks */
+ case TOK_malloc:
+ case TOK_free:
+ case TOK_realloc:
+ case TOK_memalign:
+ case TOK_calloc:
+#endif
+ case TOK_memcpy:
+ case TOK_memmove:
+ case TOK_memset:
+ case TOK_strlen:
+ case TOK_strcpy:
+ case TOK_alloca:
+ strcpy(buf, "__bound_");
+ strcat(buf, name);
+ name = buf;
+ break;
+ }
+ }
+#endif
+ t = sym->type.t;
+ if ((t & VT_BTYPE) == VT_FUNC) {
+ sym_type = STT_FUNC;
+ } else if ((t & VT_BTYPE) == VT_VOID) {
+ sym_type = STT_NOTYPE;
+ } else {
+ sym_type = STT_OBJECT;
+ }
+ if (t & VT_STATIC)
+ sym_bind = STB_LOCAL;
+ else
+ sym_bind = STB_GLOBAL;
+ other = 0;
+#ifdef TCC_TARGET_PE
+ if (sym_type == STT_FUNC && sym->type.ref) {
+ Sym *ref = sym->type.ref;
+ if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) {
+ sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE);
+ name = buf1;
+ other |= ST_PE_STDCALL;
+ can_add_underscore = 0;
+ }
+ }
+#endif
+ if (tcc_state->leading_underscore && can_add_underscore) {
+ buf1[0] = '_';
+ pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
+ name = buf1;
+ }
+ if (sym->asm_label)
+ name = get_tok_str(sym->asm_label, NULL);
+ info = ELFW(ST_INFO)(sym_bind, sym_type);
+ sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
+ } else {
+ esym = elfsym(sym);
+ esym->st_value = value;
+ esym->st_size = size;
+ esym->st_shndx = sh_num;
+ }
+ update_storage(sym);
+}
+
+ST_FUNC void put_extern_sym(Sym *sym, Section *section,
+ addr_t value, unsigned long size)
+{
+ int sh_num = section ? section->sh_num : SHN_UNDEF;
+ put_extern_sym2(sym, sh_num, value, size, 1);
+}
+
+/* add a new relocation entry to symbol 'sym' in section 's' */
+ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
+ addr_t addend)
+{
+ int c = 0;
+
+ if (nocode_wanted && s == cur_text_section)
+ return;
+
+ if (sym) {
+ if (0 == sym->c)
+ put_extern_sym(sym, NULL, 0, 0);
+ c = sym->c;
+ }
+
+ /* now we can add ELF relocation info */
+ put_elf_reloca(symtab_section, s, offset, type, c, addend);
+}
+
+#if PTR_SIZE == 4
+ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
+{
+ greloca(s, sym, offset, type, 0);
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* symbol allocator */
+static Sym *__sym_malloc(void)
+{
+ Sym *sym_pool, *sym, *last_sym;
+ int i;
+
+ sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
+ dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
+
+ last_sym = sym_free_first;
+ sym = sym_pool;
+ for(i = 0; i < SYM_POOL_NB; i++) {
+ sym->next = last_sym;
+ last_sym = sym;
+ sym++;
+ }
+ sym_free_first = last_sym;
+ return last_sym;
+}
+
+static inline Sym *sym_malloc(void)
+{
+ Sym *sym;
+#ifndef SYM_DEBUG
+ sym = sym_free_first;
+ if (!sym)
+ sym = __sym_malloc();
+ sym_free_first = sym->next;
+ return sym;
+#else
+ sym = tcc_malloc(sizeof(Sym));
+ return sym;
+#endif
+}
+
+ST_INLN void sym_free(Sym *sym)
+{
+#ifndef SYM_DEBUG
+ sym->next = sym_free_first;
+ sym_free_first = sym;
+#else
+ tcc_free(sym);
+#endif
+}
+
+/* push, without hashing */
+ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c)
+{
+ Sym *s;
+
+ s = sym_malloc();
+ memset(s, 0, sizeof *s);
+ s->v = v;
+ s->type.t = t;
+ s->c = c;
+ /* add in stack */
+ s->prev = *ps;
+ *ps = s;
+ return s;
+}
+
+/* find a symbol and return its associated structure. 's' is the top
+ of the symbol stack */
+ST_FUNC Sym *sym_find2(Sym *s, int v)
+{
+ while (s) {
+ if (s->v == v)
+ return s;
+ else if (s->v == -1)
+ return NULL;
+ s = s->prev;
+ }
+ return NULL;
+}
+
+/* structure lookup */
+ST_INLN Sym *struct_find(int v)
+{
+ v -= TOK_IDENT;
+ if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+ return NULL;
+ return table_ident[v]->sym_struct;
+}
+
+/* find an identifier */
+ST_INLN Sym *sym_find(int v)
+{
+ v -= TOK_IDENT;
+ if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+ return NULL;
+ return table_ident[v]->sym_identifier;
+}
+
+/* push a given symbol on the symbol stack */
+ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
+{
+ Sym *s, **ps;
+ TokenSym *ts;
+
+ if (local_stack)
+ ps = &local_stack;
+ else
+ ps = &global_stack;
+ s = sym_push2(ps, v, type->t, c);
+ s->type.ref = type->ref;
+ s->r = r;
+ /* don't record fields or anonymous symbols */
+ /* XXX: simplify */
+ if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+ /* record symbol in token array */
+ ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
+ if (v & SYM_STRUCT)
+ ps = &ts->sym_struct;
+ else
+ ps = &ts->sym_identifier;
+ s->prev_tok = *ps;
+ *ps = s;
+ s->sym_scope = local_scope;
+ if (s->prev_tok && s->prev_tok->sym_scope == s->sym_scope)
+ tcc_error("redeclaration of '%s'",
+ get_tok_str(v & ~SYM_STRUCT, NULL));
+ }
+ return s;
+}
+
+/* push a global identifier */
+ST_FUNC Sym *global_identifier_push(int v, int t, int c)
+{
+ Sym *s, **ps;
+ s = sym_push2(&global_stack, v, t, c);
+ /* don't record anonymous symbol */
+ if (v < SYM_FIRST_ANOM) {
+ ps = &table_ident[v - TOK_IDENT]->sym_identifier;
+ /* modify the top most local identifier, so that
+ sym_identifier will point to 's' when popped */
+ while (*ps != NULL && (*ps)->sym_scope)
+ ps = &(*ps)->prev_tok;
+ s->prev_tok = *ps;
+ *ps = s;
+ }
+ return s;
+}
+
+/* pop symbols until top reaches 'b'. If KEEP is non-zero don't really
+ pop them yet from the list, but do remove them from the token array. */
+ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
+{
+ Sym *s, *ss, **ps;
+ TokenSym *ts;
+ int v;
+
+ s = *ptop;
+ while(s != b) {
+ ss = s->prev;
+ v = s->v;
+ /* remove symbol in token array */
+ /* XXX: simplify */
+ if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+ ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
+ if (v & SYM_STRUCT)
+ ps = &ts->sym_struct;
+ else
+ ps = &ts->sym_identifier;
+ *ps = s->prev_tok;
+ }
+ if (!keep)
+ sym_free(s);
+ s = ss;
+ }
+ if (!keep)
+ *ptop = b;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void vsetc(CType *type, int r, CValue *vc)
+{
+ int v;
+
+ if (vtop >= vstack + (VSTACK_SIZE - 1))
+ tcc_error("memory full (vstack)");
+ /* cannot let cpu flags if other instruction are generated. Also
+ avoid leaving VT_JMP anywhere except on the top of the stack
+ because it would complicate the code generator.
+
+ Don't do this when nocode_wanted. vtop might come from
+ !nocode_wanted regions (see 88_codeopt.c) and transforming
+ it to a register without actually generating code is wrong
+ as their value might still be used for real. All values
+ we push under nocode_wanted will eventually be popped
+ again, so that the VT_CMP/VT_JMP value will be in vtop
+ when code is unsuppressed again.
+
+ Same logic below in vswap(); */
+ if (vtop >= vstack && !nocode_wanted) {
+ v = vtop->r & VT_VALMASK;
+ if (v == VT_CMP || (v & ~1) == VT_JMP)
+ gv(RC_INT);
+ }
+
+ vtop++;
+ vtop->type = *type;
+ vtop->r = r;
+ vtop->r2 = VT_CONST;
+ vtop->c = *vc;
+ vtop->sym = NULL;
+}
+
+ST_FUNC void vswap(void)
+{
+ SValue tmp;
+ /* cannot vswap cpu flags. See comment at vsetc() above */
+ if (vtop >= vstack && !nocode_wanted) {
+ int v = vtop->r & VT_VALMASK;
+ if (v == VT_CMP || (v & ~1) == VT_JMP)
+ gv(RC_INT);
+ }
+ tmp = vtop[0];
+ vtop[0] = vtop[-1];
+ vtop[-1] = tmp;
+}
+
+/* pop stack value */
+ST_FUNC void vpop(void)
+{
+ int v;
+ v = vtop->r & VT_VALMASK;
+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
+ /* for x86, we need to pop the FP stack */
+ if (v == TREG_ST0) {
+ o(0xd8dd); /* fstp %st(0) */
+ } else
+#endif
+ if (v == VT_JMP || v == VT_JMPI) {
+ /* need to put correct jump if && or || without test */
+ gsym(vtop->c.i);
+ }
+ vtop--;
+}
+
+/* push constant of type "type" with useless value */
+ST_FUNC void vpush(CType *type)
+{
+ vset(type, VT_CONST, 0);
+}
+
+/* push integer constant */
+ST_FUNC void vpushi(int v)
+{
+ CValue cval;
+ cval.i = v;
+ vsetc(&int_type, VT_CONST, &cval);
+}
+
+/* push a pointer sized constant */
+static void vpushs(addr_t v)
+{
+ CValue cval;
+ cval.i = v;
+ vsetc(&size_type, VT_CONST, &cval);
+}
+
+/* push arbitrary 64bit constant */
+ST_FUNC void vpush64(int ty, unsigned long long v)
+{
+ CValue cval;
+ CType ctype;
+ ctype.t = ty;
+ ctype.ref = NULL;
+ cval.i = v;
+ vsetc(&ctype, VT_CONST, &cval);
+}
+
+/* push long long constant */
+static inline void vpushll(long long v)
+{
+ vpush64(VT_LLONG, v);
+}
+
+ST_FUNC void vset(CType *type, int r, int v)
+{
+ CValue cval;
+
+ cval.i = v;
+ vsetc(type, r, &cval);
+}
+
+static void vseti(int r, int v)
+{
+ CType type;
+ type.t = VT_INT;
+ type.ref = NULL;
+ vset(&type, r, v);
+}
+
+ST_FUNC void vpushv(SValue *v)
+{
+ if (vtop >= vstack + (VSTACK_SIZE - 1))
+ tcc_error("memory full (vstack)");
+ vtop++;
+ *vtop = *v;
+}
+
+static void vdup(void)
+{
+ vpushv(vtop);
+}
+
+/* rotate n first stack elements to the bottom
+ I1 ... In -> I2 ... In I1 [top is right]
+*/
+ST_FUNC void vrotb(int n)
+{
+ int i;
+ SValue tmp;
+
+ tmp = vtop[-n + 1];
+ for(i=-n+1;i!=0;i++)
+ vtop[i] = vtop[i+1];
+ vtop[0] = tmp;
+}
+
+/* rotate the n elements before entry e towards the top
+ I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
+ */
+ST_FUNC void vrote(SValue *e, int n)
+{
+ int i;
+ SValue tmp;
+
+ tmp = *e;
+ for(i = 0;i < n - 1; i++)
+ e[-i] = e[-i - 1];
+ e[-n + 1] = tmp;
+}
+
+/* rotate n first stack elements to the top
+ I1 ... In -> In I1 ... I(n-1) [top is right]
+ */
+ST_FUNC void vrott(int n)
+{
+ vrote(vtop, n);
+}
+
+/* push a symbol value of TYPE */
+static inline void vpushsym(CType *type, Sym *sym)
+{
+ CValue cval;
+ cval.i = 0;
+ vsetc(type, VT_CONST | VT_SYM, &cval);
+ vtop->sym = sym;
+}
+
+/* Return a static symbol pointing to a section */
+ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
+{
+ int v;
+ Sym *sym;
+
+ v = anon_sym++;
+ sym = global_identifier_push(v, type->t | VT_STATIC, 0);
+ sym->type.ref = type->ref;
+ sym->r = VT_CONST | VT_SYM;
+ put_extern_sym(sym, sec, offset, size);
+ return sym;
+}
+
+/* push a reference to a section offset by adding a dummy symbol */
+static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
+{
+ vpushsym(type, get_sym_ref(type, sec, offset, size));
+}
+
+/* define a new external reference to a symbol 'v' of type 'u' */
+ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
+{
+ Sym *s;
+
+ s = sym_find(v);
+ if (!s) {
+ /* push forward reference */
+ s = global_identifier_push(v, type->t | VT_EXTERN, 0);
+ s->type.ref = type->ref;
+ s->r = r | VT_CONST | VT_SYM;
+ } else if (IS_ASM_SYM(s)) {
+ s->type.t = type->t | (s->type.t & VT_EXTERN);
+ s->type.ref = type->ref;
+ update_storage(s);
+ }
+ return s;
+}
+
+/* Merge some type attributes. */
+static void patch_type(Sym *sym, CType *type)
+{
+ if (!(type->t & VT_EXTERN)) {
+ if (!(sym->type.t & VT_EXTERN))
+ tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
+ sym->type.t &= ~VT_EXTERN;
+ }
+
+ if (IS_ASM_SYM(sym)) {
+ /* stay static if both are static */
+ sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
+ sym->type.ref = type->ref;
+ }
+
+ if (!is_compatible_types(&sym->type, type)) {
+ tcc_error("incompatible types for redefinition of '%s'",
+ get_tok_str(sym->v, NULL));
+
+ } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
+ int static_proto = sym->type.t & VT_STATIC;
+ /* warn if static follows non-static function declaration */
+ if ((type->t & VT_STATIC) && !static_proto && !(type->t & VT_INLINE))
+ tcc_warning("static storage ignored for redefinition of '%s'",
+ get_tok_str(sym->v, NULL));
+
+ if (0 == (type->t & VT_EXTERN)) {
+ /* put complete type, use static from prototype */
+ sym->type.t = (type->t & ~VT_STATIC) | static_proto;
+ if (type->t & VT_INLINE)
+ sym->type.t = type->t;
+ sym->type.ref = type->ref;
+ }
+
+ } else {
+ if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) {
+ /* set array size if it was omitted in extern declaration */
+ if (sym->type.ref->c < 0)
+ sym->type.ref->c = type->ref->c;
+ else if (sym->type.ref->c != type->ref->c)
+ tcc_error("conflicting type for '%s'", get_tok_str(sym->v, NULL));
+ }
+ if ((type->t ^ sym->type.t) & VT_STATIC)
+ tcc_warning("storage mismatch for redefinition of '%s'",
+ get_tok_str(sym->v, NULL));
+ }
+}
+
+
+/* Merge some storage attributes. */
+static void patch_storage(Sym *sym, AttributeDef *ad, CType *type)
+{
+ if (type)
+ patch_type(sym, type);
+
+#ifdef TCC_TARGET_PE
+ if (sym->a.dllimport != ad->a.dllimport)
+ tcc_error("incompatible dll linkage for redefinition of '%s'",
+ get_tok_str(sym->v, NULL));
+ sym->a.dllexport |= ad->a.dllexport;
+#endif
+ sym->a.weak |= ad->a.weak;
+ if (ad->a.visibility) {
+ int vis = sym->a.visibility;
+ int vis2 = ad->a.visibility;
+ if (vis == STV_DEFAULT)
+ vis = vis2;
+ else if (vis2 != STV_DEFAULT)
+ vis = (vis < vis2) ? vis : vis2;
+ sym->a.visibility = vis;
+ }
+ if (ad->a.aligned)
+ sym->a.aligned = ad->a.aligned;
+ if (ad->asm_label)
+ sym->asm_label = ad->asm_label;
+ update_storage(sym);
+}
+
+/* define a new external reference to a symbol 'v' */
+static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
+{
+ Sym *s;
+ s = sym_find(v);
+ if (!s) {
+ /* push forward reference */
+ s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
+ s->type.t |= VT_EXTERN;
+ s->a = ad->a;
+ s->sym_scope = 0;
+ } else {
+ if (s->type.ref == func_old_type.ref) {
+ s->type.ref = type->ref;
+ s->r = r | VT_CONST | VT_SYM;
+ s->type.t |= VT_EXTERN;
+ }
+ patch_storage(s, ad, type);
+ }
+ return s;
+}
+
+/* push a reference to global symbol v */
+ST_FUNC void vpush_global_sym(CType *type, int v)
+{
+ vpushsym(type, external_global_sym(v, type, 0));
+}
+
+/* save registers up to (vtop - n) stack entry */
+ST_FUNC void save_regs(int n)
+{
+ SValue *p, *p1;
+ for(p = vstack, p1 = vtop - n; p <= p1; p++)
+ save_reg(p->r);
+}
+
+/* save r to the memory stack, and mark it as being free */
+ST_FUNC void save_reg(int r)
+{
+ save_reg_upstack(r, 0);
+}
+
+/* save r to the memory stack, and mark it as being free,
+ if seen up to (vtop - n) stack entry */
+ST_FUNC void save_reg_upstack(int r, int n)
+{
+ int l, saved, size, align;
+ SValue *p, *p1, sv;
+ CType *type;
+
+ if ((r &= VT_VALMASK) >= VT_CONST)
+ return;
+ if (nocode_wanted)
+ return;
+
+ /* modify all stack values */
+ saved = 0;
+ l = 0;
+ for(p = vstack, p1 = vtop - n; p <= p1; p++) {
+ if ((p->r & VT_VALMASK) == r ||
+ ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
+ /* must save value on stack if not already done */
+ if (!saved) {
+ /* NOTE: must reload 'r' because r might be equal to r2 */
+ r = p->r & VT_VALMASK;
+ /* store register in the stack */
+ type = &p->type;
+ if ((p->r & VT_LVAL) ||
+ (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
+#if PTR_SIZE == 8
+ type = &char_pointer_type;
+#else
+ type = &int_type;
+#endif
+ size = type_size(type, &align);
+ loc = (loc - size) & -align;
+ sv.type.t = type->t;
+ sv.r = VT_LOCAL | VT_LVAL;
+ sv.c.i = loc;
+ store(r, &sv);
+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
+ /* x86 specific: need to pop fp register ST0 if saved */
+ if (r == TREG_ST0) {
+ o(0xd8dd); /* fstp %st(0) */
+ }
+#endif
+#if PTR_SIZE == 4
+ /* special long long case */
+ if ((type->t & VT_BTYPE) == VT_LLONG) {
+ sv.c.i += 4;
+ store(p->r2, &sv);
+ }
+#endif
+ l = loc;
+ saved = 1;
+ }
+ /* mark that stack entry as being saved on the stack */
+ if (p->r & VT_LVAL) {
+ /* also clear the bounded flag because the
+ relocation address of the function was stored in
+ p->c.i */
+ p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
+ } else {
+ p->r = lvalue_type(p->type.t) | VT_LOCAL;
+ }
+ p->r2 = VT_CONST;
+ p->c.i = l;
+ }
+ }
+}
+
+#ifdef TCC_TARGET_ARM
+/* find a register of class 'rc2' with at most one reference on stack.
+ * If none, call get_reg(rc) */
+ST_FUNC int get_reg_ex(int rc, int rc2)
+{
+ int r;
+ SValue *p;
+
+ for(r=0;r<NB_REGS;r++) {
+ if (reg_classes[r] & rc2) {
+ int n;
+ n=0;
+ for(p = vstack; p <= vtop; p++) {
+ if ((p->r & VT_VALMASK) == r ||
+ (p->r2 & VT_VALMASK) == r)
+ n++;
+ }
+ if (n <= 1)
+ return r;
+ }
+ }
+ return get_reg(rc);
+}
+#endif
+
+/* find a free register of class 'rc'. If none, save one register */
+ST_FUNC int get_reg(int rc)
+{
+ int r;
+ SValue *p;
+
+ /* find a free register */
+ for(r=0;r<NB_REGS;r++) {
+ if (reg_classes[r] & rc) {
+ if (nocode_wanted)
+ return r;
+ for(p=vstack;p<=vtop;p++) {
+ if ((p->r & VT_VALMASK) == r ||
+ (p->r2 & VT_VALMASK) == r)
+ goto notfound;
+ }
+ return r;
+ }
+ notfound: ;
+ }
+
+ /* no register left : free the first one on the stack (VERY
+ IMPORTANT to start from the bottom to ensure that we don't
+ spill registers used in gen_opi()) */
+ for(p=vstack;p<=vtop;p++) {
+ /* look at second register (if long long) */
+ r = p->r2 & VT_VALMASK;
+ if (r < VT_CONST && (reg_classes[r] & rc))
+ goto save_found;
+ r = p->r & VT_VALMASK;
+ if (r < VT_CONST && (reg_classes[r] & rc)) {
+ save_found:
+ save_reg(r);
+ return r;
+ }
+ }
+ /* Should never comes here */
+ return -1;
+}
+
+/* move register 's' (of type 't') to 'r', and flush previous value of r to memory
+ if needed */
+static void move_reg(int r, int s, int t)
+{
+ SValue sv;
+
+ if (r != s) {
+ save_reg(r);
+ sv.type.t = t;
+ sv.type.ref = NULL;
+ sv.r = s;
+ sv.c.i = 0;
+ load(r, &sv);
+ }
+}
+
+/* get address of vtop (vtop MUST BE an lvalue) */
+ST_FUNC void gaddrof(void)
+{
+ vtop->r &= ~VT_LVAL;
+ /* tricky: if saved lvalue, then we can go back to lvalue */
+ if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
+ vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
+
+
+}
+
+#ifdef CONFIG_TCC_BCHECK
+/* generate lvalue bound code */
+static void gbound(void)
+{
+ int lval_type;
+ CType type1;
+
+ vtop->r &= ~VT_MUSTBOUND;
+ /* if lvalue, then use checking code before dereferencing */
+ if (vtop->r & VT_LVAL) {
+ /* if not VT_BOUNDED value, then make one */
+ if (!(vtop->r & VT_BOUNDED)) {
+ lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
+ /* must save type because we must set it to int to get pointer */
+ type1 = vtop->type;
+ vtop->type.t = VT_PTR;
+ gaddrof();
+ vpushi(0);
+ gen_bounded_ptr_add();
+ vtop->r |= lval_type;
+ vtop->type = type1;
+ }
+ /* then check for dereferencing */
+ gen_bounded_ptr_deref();
+ }
+}
+#endif
+
+static void incr_bf_adr(int o)
+{
+ vtop->type = char_pointer_type;
+ gaddrof();
+ vpushi(o);
+ gen_op('+');
+ vtop->type.t = (vtop->type.t & ~(VT_BTYPE|VT_DEFSIGN))
+ | (VT_BYTE|VT_UNSIGNED);
+ vtop->r = (vtop->r & ~VT_LVAL_TYPE)
+ | (VT_LVAL_BYTE|VT_LVAL_UNSIGNED|VT_LVAL);
+}
+
+/* single-byte load mode for packed or otherwise unaligned bitfields */
+static void load_packed_bf(CType *type, int bit_pos, int bit_size)
+{
+ int n, o, bits;
+ save_reg_upstack(vtop->r, 1);
+ vpush64(type->t & VT_BTYPE, 0); // B X
+ bits = 0, o = bit_pos >> 3, bit_pos &= 7;
+ do {
+ vswap(); // X B
+ incr_bf_adr(o);
+ vdup(); // X B B
+ n = 8 - bit_pos;
+ if (n > bit_size)
+ n = bit_size;
+ if (bit_pos)
+ vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y
+ if (n < 8)
+ vpushi((1 << n) - 1), gen_op('&');
+ gen_cast(type);
+ if (bits)
+ vpushi(bits), gen_op(TOK_SHL);
+ vrotb(3); // B Y X
+ gen_op('|'); // B X
+ bits += n, bit_size -= n, o = 1;
+ } while (bit_size);
+ vswap(), vpop();
+ if (!(type->t & VT_UNSIGNED)) {
+ n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits;
+ vpushi(n), gen_op(TOK_SHL);
+ vpushi(n), gen_op(TOK_SAR);
+ }
+}
+
+/* single-byte store mode for packed or otherwise unaligned bitfields */
+static void store_packed_bf(int bit_pos, int bit_size)
+{
+ int bits, n, o, m, c;
+
+ c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+ vswap(); // X B
+ save_reg_upstack(vtop->r, 1);
+ bits = 0, o = bit_pos >> 3, bit_pos &= 7;
+ do {
+ incr_bf_adr(o); // X B
+ vswap(); //B X
+ c ? vdup() : gv_dup(); // B V X
+ vrott(3); // X B V
+ if (bits)
+ vpushi(bits), gen_op(TOK_SHR);
+ if (bit_pos)
+ vpushi(bit_pos), gen_op(TOK_SHL);
+ n = 8 - bit_pos;
+ if (n > bit_size)
+ n = bit_size;
+ if (n < 8) {
+ m = ((1 << n) - 1) << bit_pos;
+ vpushi(m), gen_op('&'); // X B V1
+ vpushv(vtop-1); // X B V1 B
+ vpushi(m & 0x80 ? ~m & 0x7f : ~m);
+ gen_op('&'); // X B V1 B1
+ gen_op('|'); // X B V2
+ }
+ vdup(), vtop[-1] = vtop[-2]; // X B B V2
+ vstore(), vpop(); // X B
+ bits += n, bit_size -= n, bit_pos = 0, o = 1;
+ } while (bit_size);
+ vpop(), vpop();
+}
+
+static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
+{
+ int t;
+ if (0 == sv->type.ref)
+ return 0;
+ t = sv->type.ref->auxtype;
+ if (t != -1 && t != VT_STRUCT) {
+ sv->type.t = (sv->type.t & ~VT_BTYPE) | t;
+ sv->r = (sv->r & ~VT_LVAL_TYPE) | lvalue_type(sv->type.t);
+ }
+ return t;
+}
+
+/* store vtop a register belonging to class 'rc'. lvalues are
+ converted to values. Cannot be used if cannot be converted to
+ register value (such as structures). */
+ST_FUNC int gv(int rc)
+{
+ int r, bit_pos, bit_size, size, align, rc2;
+
+ /* NOTE: get_reg can modify vstack[] */
+ if (vtop->type.t & VT_BITFIELD) {
+ CType type;
+
+ bit_pos = BIT_POS(vtop->type.t);
+ bit_size = BIT_SIZE(vtop->type.t);
+ /* remove bit field info to avoid loops */
+ vtop->type.t &= ~VT_STRUCT_MASK;
+
+ type.ref = NULL;
+ type.t = vtop->type.t & VT_UNSIGNED;
+ if ((vtop->type.t & VT_BTYPE) == VT_BOOL)
+ type.t |= VT_UNSIGNED;
+
+ r = adjust_bf(vtop, bit_pos, bit_size);
+
+ if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
+ type.t |= VT_LLONG;
+ else
+ type.t |= VT_INT;
+
+ if (r == VT_STRUCT) {
+ load_packed_bf(&type, bit_pos, bit_size);
+ } else {
+ int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32;
+ /* cast to int to propagate signedness in following ops */
+ gen_cast(&type);
+ /* generate shifts */
+ vpushi(bits - (bit_pos + bit_size));
+ gen_op(TOK_SHL);
+ vpushi(bits - bit_size);
+ /* NOTE: transformed to SHR if unsigned */
+ gen_op(TOK_SAR);
+ }
+ r = gv(rc);
+ } else {
+ if (is_float(vtop->type.t) &&
+ (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+ unsigned long offset;
+ /* CPUs usually cannot use float constants, so we store them
+ generically in data segment */
+ size = type_size(&vtop->type, &align);
+ if (NODATA_WANTED)
+ size = 0, align = 1;
+ offset = section_add(data_section, size, align);
+ vpush_ref(&vtop->type, data_section, offset, size);
+ vswap();
+ init_putv(&vtop->type, data_section, offset);
+ vtop->r |= VT_LVAL;
+ }
+#ifdef CONFIG_TCC_BCHECK
+ if (vtop->r & VT_MUSTBOUND)
+ gbound();
+#endif
+
+ r = vtop->r & VT_VALMASK;
+ rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
+#ifndef TCC_TARGET_ARM64
+ if (rc == RC_IRET)
+ rc2 = RC_LRET;
+#ifdef TCC_TARGET_X86_64
+ else if (rc == RC_FRET)
+ rc2 = RC_QRET;
+#endif
+#endif
+ /* need to reload if:
+ - constant
+ - lvalue (need to dereference pointer)
+ - already a register, but not in the right class */
+ if (r >= VT_CONST
+ || (vtop->r & VT_LVAL)
+ || !(reg_classes[r] & rc)
+#if PTR_SIZE == 8
+ || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
+ || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
+#else
+ || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
+#endif
+ )
+ {
+ r = get_reg(rc);
+#if PTR_SIZE == 8
+ if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
+ int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
+#else
+ if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+ int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
+ unsigned long long ll;
+#endif
+ int r2, original_type;
+ original_type = vtop->type.t;
+ /* two register type load : expand to two words
+ temporarily */
+#if PTR_SIZE == 4
+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+ /* load constant */
+ ll = vtop->c.i;
+ vtop->c.i = ll; /* first word */
+ load(r, vtop);
+ vtop->r = r; /* save register value */
+ vpushi(ll >> 32); /* second word */
+ } else
+#endif
+ if (vtop->r & VT_LVAL) {
+ /* We do not want to modifier the long long
+ pointer here, so the safest (and less
+ efficient) is to save all the other registers
+ in the stack. XXX: totally inefficient. */
+ #if 0
+ save_regs(1);
+ #else
+ /* lvalue_save: save only if used further down the stack */
+ save_reg_upstack(vtop->r, 1);
+ #endif
+ /* load from memory */
+ vtop->type.t = load_type;
+ load(r, vtop);
+ vdup();
+ vtop[-1].r = r; /* save register value */
+ /* increment pointer to get second word */
+ vtop->type.t = addr_type;
+ gaddrof();
+ vpushi(load_size);
+ gen_op('+');
+ vtop->r |= VT_LVAL;
+ vtop->type.t = load_type;
+ } else {
+ /* move registers */
+ load(r, vtop);
+ vdup();
+ vtop[-1].r = r; /* save register value */
+ vtop->r = vtop[-1].r2;
+ }
+ /* Allocate second register. Here we rely on the fact that
+ get_reg() tries first to free r2 of an SValue. */
+ r2 = get_reg(rc2);
+ load(r2, vtop);
+ vpop();
+ /* write second register */
+ vtop->r2 = r2;
+ vtop->type.t = original_type;
+ } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
+ int t1, t;
+ /* lvalue of scalar type : need to use lvalue type
+ because of possible cast */
+ t = vtop->type.t;
+ t1 = t;
+ /* compute memory access type */
+ if (vtop->r & VT_LVAL_BYTE)
+ t = VT_BYTE;
+ else if (vtop->r & VT_LVAL_SHORT)
+ t = VT_SHORT;
+ if (vtop->r & VT_LVAL_UNSIGNED)
+ t |= VT_UNSIGNED;
+ vtop->type.t = t;
+ load(r, vtop);
+ /* restore wanted type */
+ vtop->type.t = t1;
+ } else {
+ /* one register type load */
+ load(r, vtop);
+ }
+ }
+ vtop->r = r;
+#ifdef TCC_TARGET_C67
+ /* uses register pairs for doubles */
+ if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+ vtop->r2 = r+1;
+#endif
+ }
+ return r;
+}
+
+/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
+ST_FUNC void gv2(int rc1, int rc2)
+{
+ int v;
+
+ /* generate more generic register first. But VT_JMP or VT_CMP
+ values must be generated first in all cases to avoid possible
+ reload errors */
+ v = vtop[0].r & VT_VALMASK;
+ if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
+ vswap();
+ gv(rc1);
+ vswap();
+ gv(rc2);
+ /* test if reload is needed for first register */
+ if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
+ vswap();
+ gv(rc1);
+ vswap();
+ }
+ } else {
+ gv(rc2);
+ vswap();
+ gv(rc1);
+ vswap();
+ /* test if reload is needed for first register */
+ if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
+ gv(rc2);
+ }
+ }
+}
+
+#ifndef TCC_TARGET_ARM64
+/* wrapper around RC_FRET to return a register by type */
+static int rc_fret(int t)
+{
+#ifdef TCC_TARGET_X86_64
+ if (t == VT_LDOUBLE) {
+ return RC_ST0;
+ }
+#endif
+ return RC_FRET;
+}
+#endif
+
+/* wrapper around REG_FRET to return a register by type */
+static int reg_fret(int t)
+{
+#ifdef TCC_TARGET_X86_64
+ if (t == VT_LDOUBLE) {
+ return TREG_ST0;
+ }
+#endif
+ return REG_FRET;
+}
+
+#if PTR_SIZE == 4
+/* expand 64bit on stack in two ints */
+static void lexpand(void)
+{
+ int u, v;
+ u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
+ v = vtop->r & (VT_VALMASK | VT_LVAL);
+ if (v == VT_CONST) {
+ vdup();
+ vtop[0].c.i >>= 32;
+ } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
+ vdup();
+ vtop[0].c.i += 4;
+ } else {
+ gv(RC_INT);
+ vdup();
+ vtop[0].r = vtop[-1].r2;
+ vtop[0].r2 = vtop[-1].r2 = VT_CONST;
+ }
+ vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
+}
+#endif
+
+#ifdef TCC_TARGET_ARM
+/* expand long long on stack */
+ST_FUNC void lexpand_nr(void)
+{
+ int u,v;
+
+ u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
+ vdup();
+ vtop->r2 = VT_CONST;
+ vtop->type.t = VT_INT | u;
+ v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
+ if (v == VT_CONST) {
+ vtop[-1].c.i = vtop->c.i;
+ vtop->c.i = vtop->c.i >> 32;
+ vtop->r = VT_CONST;
+ } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
+ vtop->c.i += 4;
+ vtop->r = vtop[-1].r;
+ } else if (v > VT_CONST) {
+ vtop--;
+ lexpand();
+ } else
+ vtop->r = vtop[-1].r2;
+ vtop[-1].r2 = VT_CONST;
+ vtop[-1].type.t = VT_INT | u;
+}
+#endif
+
+#if PTR_SIZE == 4
+/* build a long long from two ints */
+static void lbuild(int t)
+{
+ gv2(RC_INT, RC_INT);
+ vtop[-1].r2 = vtop[0].r;
+ vtop[-1].type.t = t;
+ vpop();
+}
+#endif
+
+/* convert stack entry to register and duplicate its value in another
+ register */
+static void gv_dup(void)
+{
+ int rc, t, r, r1;
+ SValue sv;
+
+ t = vtop->type.t;
+#if PTR_SIZE == 4
+ if ((t & VT_BTYPE) == VT_LLONG) {
+ if (t & VT_BITFIELD) {
+ gv(RC_INT);
+ t = vtop->type.t;
+ }
+ lexpand();
+ gv_dup();
+ vswap();
+ vrotb(3);
+ gv_dup();
+ vrotb(4);
+ /* stack: H L L1 H1 */
+ lbuild(t);
+ vrotb(3);
+ vrotb(3);
+ vswap();
+ lbuild(t);
+ vswap();
+ } else
+#endif
+ {
+ /* duplicate value */
+ rc = RC_INT;
+ sv.type.t = VT_INT;
+ if (is_float(t)) {
+ rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+ if ((t & VT_BTYPE) == VT_LDOUBLE) {
+ rc = RC_ST0;
+ }
+#endif
+ sv.type.t = t;
+ }
+ r = gv(rc);
+ r1 = get_reg(rc);
+ sv.r = r;
+ sv.c.i = 0;
+ load(r1, &sv); /* move r to r1 */
+ vdup();
+ /* duplicates value */
+ if (r != r1)
+ vtop->r = r1;
+ }
+}
+
+/* Generate value test
+ *
+ * Generate a test for any value (jump, comparison and integers) */
+ST_FUNC int gvtst(int inv, int t)
+{
+ int v = vtop->r & VT_VALMASK;
+ if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
+ vpushi(0);
+ gen_op(TOK_NE);
+ }
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ /* constant jmp optimization */
+ if ((vtop->c.i != 0) != inv)
+ t = gjmp(t);
+ vtop--;
+ return t;
+ }
+ return gtst(inv, t);
+}
+
+#if PTR_SIZE == 4
+/* generate CPU independent (unsigned) long long operations */
+static void gen_opl(int op)
+{
+ int t, a, b, op1, c, i;
+ int func;
+ unsigned short reg_iret = REG_IRET;
+ unsigned short reg_lret = REG_LRET;
+ SValue tmp;
+
+ switch(op) {
+ case '/':
+ case TOK_PDIV:
+ func = TOK___divdi3;
+ goto gen_func;
+ case TOK_UDIV:
+ func = TOK___udivdi3;
+ goto gen_func;
+ case '%':
+ func = TOK___moddi3;
+ goto gen_mod_func;
+ case TOK_UMOD:
+ func = TOK___umoddi3;
+ gen_mod_func:
+#ifdef TCC_ARM_EABI
+ reg_iret = TREG_R2;
+ reg_lret = TREG_R3;
+#endif
+ gen_func:
+ /* call generic long long function */
+ vpush_global_sym(&func_old_type, func);
+ vrott(3);
+ gfunc_call(2);
+ vpushi(0);
+ vtop->r = reg_iret;
+ vtop->r2 = reg_lret;
+ break;
+ case '^':
+ case '&':
+ case '|':
+ case '*':
+ case '+':
+ case '-':
+ //pv("gen_opl A",0,2);
+ t = vtop->type.t;
+ vswap();
+ lexpand();
+ vrotb(3);
+ lexpand();
+ /* stack: L1 H1 L2 H2 */
+ tmp = vtop[0];
+ vtop[0] = vtop[-3];
+ vtop[-3] = tmp;
+ tmp = vtop[-2];
+ vtop[-2] = vtop[-3];
+ vtop[-3] = tmp;
+ vswap();
+ /* stack: H1 H2 L1 L2 */
+ //pv("gen_opl B",0,4);
+ if (op == '*') {
+ vpushv(vtop - 1);
+ vpushv(vtop - 1);
+ gen_op(TOK_UMULL);
+ lexpand();
+ /* stack: H1 H2 L1 L2 ML MH */
+ for(i=0;i<4;i++)
+ vrotb(6);
+ /* stack: ML MH H1 H2 L1 L2 */
+ tmp = vtop[0];
+ vtop[0] = vtop[-2];
+ vtop[-2] = tmp;
+ /* stack: ML MH H1 L2 H2 L1 */
+ gen_op('*');
+ vrotb(3);
+ vrotb(3);
+ gen_op('*');
+ /* stack: ML MH M1 M2 */
+ gen_op('+');
+ gen_op('+');
+ } else if (op == '+' || op == '-') {
+ /* XXX: add non carry method too (for MIPS or alpha) */
+ if (op == '+')
+ op1 = TOK_ADDC1;
+ else
+ op1 = TOK_SUBC1;
+ gen_op(op1);
+ /* stack: H1 H2 (L1 op L2) */
+ vrotb(3);
+ vrotb(3);
+ gen_op(op1 + 1); /* TOK_xxxC2 */
+ } else {
+ gen_op(op);
+ /* stack: H1 H2 (L1 op L2) */
+ vrotb(3);
+ vrotb(3);
+ /* stack: (L1 op L2) H1 H2 */
+ gen_op(op);
+ /* stack: (L1 op L2) (H1 op H2) */
+ }
+ /* stack: L H */
+ lbuild(t);
+ break;
+ case TOK_SAR:
+ case TOK_SHR:
+ case TOK_SHL:
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ t = vtop[-1].type.t;
+ vswap();
+ lexpand();
+ vrotb(3);
+ /* stack: L H shift */
+ c = (int)vtop->c.i;
+ /* constant: simpler */
+ /* NOTE: all comments are for SHL. the other cases are
+ done by swapping words */
+ vpop();
+ if (op != TOK_SHL)
+ vswap();
+ if (c >= 32) {
+ /* stack: L H */
+ vpop();
+ if (c > 32) {
+ vpushi(c - 32);
+ gen_op(op);
+ }
+ if (op != TOK_SAR) {
+ vpushi(0);
+ } else {
+ gv_dup();
+ vpushi(31);
+ gen_op(TOK_SAR);
+ }
+ vswap();
+ } else {
+ vswap();
+ gv_dup();
+ /* stack: H L L */
+ vpushi(c);
+ gen_op(op);
+ vswap();
+ vpushi(32 - c);
+ if (op == TOK_SHL)
+ gen_op(TOK_SHR);
+ else
+ gen_op(TOK_SHL);
+ vrotb(3);
+ /* stack: L L H */
+ vpushi(c);
+ if (op == TOK_SHL)
+ gen_op(TOK_SHL);
+ else
+ gen_op(TOK_SHR);
+ gen_op('|');
+ }
+ if (op != TOK_SHL)
+ vswap();
+ lbuild(t);
+ } else {
+ /* XXX: should provide a faster fallback on x86 ? */
+ switch(op) {
+ case TOK_SAR:
+ func = TOK___ashrdi3;
+ goto gen_func;
+ case TOK_SHR:
+ func = TOK___lshrdi3;
+ goto gen_func;
+ case TOK_SHL:
+ func = TOK___ashldi3;
+ goto gen_func;
+ }
+ }
+ break;
+ default:
+ /* compare operations */
+ t = vtop->type.t;
+ vswap();
+ lexpand();
+ vrotb(3);
+ lexpand();
+ /* stack: L1 H1 L2 H2 */
+ tmp = vtop[-1];
+ vtop[-1] = vtop[-2];
+ vtop[-2] = tmp;
+ /* stack: L1 L2 H1 H2 */
+ /* compare high */
+ op1 = op;
+ /* when values are equal, we need to compare low words. since
+ the jump is inverted, we invert the test too. */
+ if (op1 == TOK_LT)
+ op1 = TOK_LE;
+ else if (op1 == TOK_GT)
+ op1 = TOK_GE;
+ else if (op1 == TOK_ULT)
+ op1 = TOK_ULE;
+ else if (op1 == TOK_UGT)
+ op1 = TOK_UGE;
+ a = 0;
+ b = 0;
+ gen_op(op1);
+ if (op == TOK_NE) {
+ b = gvtst(0, 0);
+ } else {
+ a = gvtst(1, 0);
+ if (op != TOK_EQ) {
+ /* generate non equal test */
+ vpushi(TOK_NE);
+ vtop->r = VT_CMP;
+ b = gvtst(0, 0);
+ }
+ }
+ /* compare low. Always unsigned */
+ op1 = op;
+ if (op1 == TOK_LT)
+ op1 = TOK_ULT;
+ else if (op1 == TOK_LE)
+ op1 = TOK_ULE;
+ else if (op1 == TOK_GT)
+ op1 = TOK_UGT;
+ else if (op1 == TOK_GE)
+ op1 = TOK_UGE;
+ gen_op(op1);
+ a = gvtst(1, a);
+ gsym(b);
+ vseti(VT_JMPI, a);
+ break;
+ }
+}
+#endif
+
+static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
+{
+ uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
+ return (a ^ b) >> 63 ? -x : x;
+}
+
+static int gen_opic_lt(uint64_t a, uint64_t b)
+{
+ return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
+}
+
+/* handle integer constant optimizations and various machine
+ independent opt */
+static void gen_opic(int op)
+{
+ SValue *v1 = vtop - 1;
+ SValue *v2 = vtop;
+ int t1 = v1->type.t & VT_BTYPE;
+ int t2 = v2->type.t & VT_BTYPE;
+ int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+ int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+ uint64_t l1 = c1 ? v1->c.i : 0;
+ uint64_t l2 = c2 ? v2->c.i : 0;
+ int shm = (t1 == VT_LLONG) ? 63 : 31;
+
+ if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
+ l1 = ((uint32_t)l1 |
+ (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
+ if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR))
+ l2 = ((uint32_t)l2 |
+ (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
+
+ if (c1 && c2) {
+ switch(op) {
+ case '+': l1 += l2; break;
+ case '-': l1 -= l2; break;
+ case '&': l1 &= l2; break;
+ case '^': l1 ^= l2; break;
+ case '|': l1 |= l2; break;
+ case '*': l1 *= l2; break;
+
+ case TOK_PDIV:
+ case '/':
+ case '%':
+ case TOK_UDIV:
+ case TOK_UMOD:
+ /* if division by zero, generate explicit division */
+ if (l2 == 0) {
+ if (const_wanted)
+ tcc_error("division by zero in constant");
+ goto general_case;
+ }
+ switch(op) {
+ default: l1 = gen_opic_sdiv(l1, l2); break;
+ case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
+ case TOK_UDIV: l1 = l1 / l2; break;
+ case TOK_UMOD: l1 = l1 % l2; break;
+ }
+ break;
+ case TOK_SHL: l1 <<= (l2 & shm); break;
+ case TOK_SHR: l1 >>= (l2 & shm); break;
+ case TOK_SAR:
+ l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
+ break;
+ /* tests */
+ case TOK_ULT: l1 = l1 < l2; break;
+ case TOK_UGE: l1 = l1 >= l2; break;
+ case TOK_EQ: l1 = l1 == l2; break;
+ case TOK_NE: l1 = l1 != l2; break;
+ case TOK_ULE: l1 = l1 <= l2; break;
+ case TOK_UGT: l1 = l1 > l2; break;
+ case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
+ case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
+ case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
+ case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
+ /* logical */
+ case TOK_LAND: l1 = l1 && l2; break;
+ case TOK_LOR: l1 = l1 || l2; break;
+ default:
+ goto general_case;
+ }
+ if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
+ l1 = ((uint32_t)l1 |
+ (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
+ v1->c.i = l1;
+ vtop--;
+ } else {
+ /* if commutative ops, put c2 as constant */
+ if (c1 && (op == '+' || op == '&' || op == '^' ||
+ op == '|' || op == '*')) {
+ vswap();
+ c2 = c1; //c = c1, c1 = c2, c2 = c;
+ l2 = l1; //l = l1, l1 = l2, l2 = l;
+ }
+ if (!const_wanted &&
+ c1 && ((l1 == 0 &&
+ (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
+ (l1 == -1 && op == TOK_SAR))) {
+ /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
+ vtop--;
+ } else if (!const_wanted &&
+ c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
+ (op == '|' &&
+ (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
+ (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
+ /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
+ if (l2 == 1)
+ vtop->c.i = 0;
+ vswap();
+ vtop--;
+ } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
+ op == TOK_PDIV) &&
+ l2 == 1) ||
+ ((op == '+' || op == '-' || op == '|' || op == '^' ||
+ op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
+ l2 == 0) ||
+ (op == '&' &&
+ (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
+ /* filter out NOP operations like x*1, x-0, x&-1... */
+ vtop--;
+ } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
+ /* try to use shifts instead of muls or divs */
+ if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
+ int n = -1;
+ while (l2) {
+ l2 >>= 1;
+ n++;
+ }
+ vtop->c.i = n;
+ if (op == '*')
+ op = TOK_SHL;
+ else if (op == TOK_PDIV)
+ op = TOK_SAR;
+ else
+ op = TOK_SHR;
+ }
+ goto general_case;
+ } else if (c2 && (op == '+' || op == '-') &&
+ (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
+ || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
+ /* symbol + constant case */
+ if (op == '-')
+ l2 = -l2;
+ l2 += vtop[-1].c.i;
+ /* The backends can't always deal with addends to symbols
+ larger than +-1<<31. Don't construct such. */
+ if ((int)l2 != l2)
+ goto general_case;
+ vtop--;
+ vtop->c.i = l2;
+ } else {
+ general_case:
+ /* call low level op generator */
+ if (t1 == VT_LLONG || t2 == VT_LLONG ||
+ (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
+ gen_opl(op);
+ else
+ gen_opi(op);
+ }
+ }
+}
+
+/* generate a floating point operation with constant propagation */
+static void gen_opif(int op)
+{
+ int c1, c2;
+ SValue *v1, *v2;
+#if defined _MSC_VER && defined _AMD64_
+ /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
+ volatile
+#endif
+ long double f1, f2;
+
+ v1 = vtop - 1;
+ v2 = vtop;
+ /* currently, we cannot do computations with forward symbols */
+ c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+ c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+ if (c1 && c2) {
+ if (v1->type.t == VT_FLOAT) {
+ f1 = v1->c.f;
+ f2 = v2->c.f;
+ } else if (v1->type.t == VT_DOUBLE) {
+ f1 = v1->c.d;
+ f2 = v2->c.d;
+ } else {
+ f1 = v1->c.ld;
+ f2 = v2->c.ld;
+ }
+
+ /* NOTE: we only do constant propagation if finite number (not
+ NaN or infinity) (ANSI spec) */
+ if (!ieee_finite(f1) || !ieee_finite(f2))
+ goto general_case;
+
+ switch(op) {
+ case '+': f1 += f2; break;
+ case '-': f1 -= f2; break;
+ case '*': f1 *= f2; break;
+ case '/':
+ if (f2 == 0.0) {
+ if (const_wanted)
+ tcc_error("division by zero in constant");
+ goto general_case;
+ }
+ f1 /= f2;
+ break;
+ /* XXX: also handles tests ? */
+ default:
+ goto general_case;
+ }
+ /* XXX: overflow test ? */
+ if (v1->type.t == VT_FLOAT) {
+ v1->c.f = f1;
+ } else if (v1->type.t == VT_DOUBLE) {
+ v1->c.d = f1;
+ } else {
+ v1->c.ld = f1;
+ }
+ vtop--;
+ } else {
+ general_case:
+ gen_opf(op);
+ }
+}
+
+static int pointed_size(CType *type)
+{
+ int align;
+ return type_size(pointed_type(type), &align);
+}
+
+static void vla_runtime_pointed_size(CType *type)
+{
+ int align;
+ vla_runtime_type_size(pointed_type(type), &align);
+}
+
+static inline int is_null_pointer(SValue *p)
+{
+ if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+ return 0;
+ return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
+ ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
+ ((p->type.t & VT_BTYPE) == VT_PTR &&
+ (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0));
+}
+
+static inline int is_integer_btype(int bt)
+{
+ return (bt == VT_BYTE || bt == VT_SHORT ||
+ bt == VT_INT || bt == VT_LLONG);
+}
+
+/* check types for comparison or subtraction of pointers */
+static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
+{
+ CType *type1, *type2, tmp_type1, tmp_type2;
+ int bt1, bt2;
+
+ /* null pointers are accepted for all comparisons as gcc */
+ if (is_null_pointer(p1) || is_null_pointer(p2))
+ return;
+ type1 = &p1->type;
+ type2 = &p2->type;
+ bt1 = type1->t & VT_BTYPE;
+ bt2 = type2->t & VT_BTYPE;
+ /* accept comparison between pointer and integer with a warning */
+ if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
+ if (op != TOK_LOR && op != TOK_LAND )
+ tcc_warning("comparison between pointer and integer");
+ return;
+ }
+
+ /* both must be pointers or implicit function pointers */
+ if (bt1 == VT_PTR) {
+ type1 = pointed_type(type1);
+ } else if (bt1 != VT_FUNC)
+ goto invalid_operands;
+
+ if (bt2 == VT_PTR) {
+ type2 = pointed_type(type2);
+ } else if (bt2 != VT_FUNC) {
+ invalid_operands:
+ tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
+ }
+ if ((type1->t & VT_BTYPE) == VT_VOID ||
+ (type2->t & VT_BTYPE) == VT_VOID)
+ return;
+ tmp_type1 = *type1;
+ tmp_type2 = *type2;
+ tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
+ tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
+ if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
+ /* gcc-like error if '-' is used */
+ if (op == '-')
+ goto invalid_operands;
+ else
+ tcc_warning("comparison of distinct pointer types lacks a cast");
+ }
+}
+
+/* generic gen_op: handles types problems */
+ST_FUNC void gen_op(int op)
+{
+ int u, t1, t2, bt1, bt2, t;
+ CType type1;
+
+redo:
+ t1 = vtop[-1].type.t;
+ t2 = vtop[0].type.t;
+ bt1 = t1 & VT_BTYPE;
+ bt2 = t2 & VT_BTYPE;
+
+ if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
+ tcc_error("operation on a struct");
+ } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
+ if (bt2 == VT_FUNC) {
+ mk_pointer(&vtop->type);
+ gaddrof();
+ }
+ if (bt1 == VT_FUNC) {
+ vswap();
+ mk_pointer(&vtop->type);
+ gaddrof();
+ vswap();
+ }
+ goto redo;
+ } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
+ /* at least one operand is a pointer */
+ /* relational op: must be both pointers */
+ if (op >= TOK_ULT && op <= TOK_LOR) {
+ check_comparison_pointer_types(vtop - 1, vtop, op);
+ /* pointers are handled are unsigned */
+#if PTR_SIZE == 8
+ t = VT_LLONG | VT_UNSIGNED;
+#else
+ t = VT_INT | VT_UNSIGNED;
+#endif
+ goto std_op;
+ }
+ /* if both pointers, then it must be the '-' op */
+ if (bt1 == VT_PTR && bt2 == VT_PTR) {
+ if (op != '-')
+ tcc_error("cannot use pointers here");
+ check_comparison_pointer_types(vtop - 1, vtop, op);
+ /* XXX: check that types are compatible */
+ if (vtop[-1].type.t & VT_VLA) {
+ vla_runtime_pointed_size(&vtop[-1].type);
+ } else {
+ vpushi(pointed_size(&vtop[-1].type));
+ }
+ vrott(3);
+ gen_opic(op);
+ vtop->type.t = ptrdiff_type.t;
+ vswap();
+ gen_op(TOK_PDIV);
+ } else {
+ /* exactly one pointer : must be '+' or '-'. */
+ if (op != '-' && op != '+')
+ tcc_error("cannot use pointers here");
+ /* Put pointer as first operand */
+ if (bt2 == VT_PTR) {
+ vswap();
+ t = t1, t1 = t2, t2 = t;
+ }
+#if PTR_SIZE == 4
+ if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
+ /* XXX: truncate here because gen_opl can't handle ptr + long long */
+ gen_cast_s(VT_INT);
+#endif
+ type1 = vtop[-1].type;
+ type1.t &= ~VT_ARRAY;
+ if (vtop[-1].type.t & VT_VLA)
+ vla_runtime_pointed_size(&vtop[-1].type);
+ else {
+ u = pointed_size(&vtop[-1].type);
+ if (u < 0)
+ tcc_error("unknown array element size");
+#if PTR_SIZE == 8
+ vpushll(u);
+#else
+ /* XXX: cast to int ? (long long case) */
+ vpushi(u);
+#endif
+ }
+ gen_op('*');
+#if 0
+/* #ifdef CONFIG_TCC_BCHECK
+ The main reason to removing this code:
+ #include <stdio.h>
+ int main ()
+ {
+ int v[10];
+ int i = 10;
+ int j = 9;
+ fprintf(stderr, "v+i-j = %p\n", v+i-j);
+ fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
+ }
+ When this code is on. then the output looks like
+ v+i-j = 0xfffffffe
+ v+(i-j) = 0xbff84000
+ */
+ /* if evaluating constant expression, no code should be
+ generated, so no bound check */
+ if (tcc_state->do_bounds_check && !const_wanted) {
+ /* if bounded pointers, we generate a special code to
+ test bounds */
+ if (op == '-') {
+ vpushi(0);
+ vswap();
+ gen_op('-');
+ }
+ gen_bounded_ptr_add();
+ } else
+#endif
+ {
+ gen_opic(op);
+ }
+ /* put again type if gen_opic() swaped operands */
+ vtop->type = type1;
+ }
+ } else if (is_float(bt1) || is_float(bt2)) {
+ /* compute bigger type and do implicit casts */
+ if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
+ t = VT_LDOUBLE;
+ } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
+ t = VT_DOUBLE;
+ } else {
+ t = VT_FLOAT;
+ }
+ /* floats can only be used for a few operations */
+ if (op != '+' && op != '-' && op != '*' && op != '/' &&
+ (op < TOK_ULT || op > TOK_GT))
+ tcc_error("invalid operands for binary operation");
+ goto std_op;
+ } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
+ t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
+ if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
+ t |= VT_UNSIGNED;
+ t |= (VT_LONG & t1);
+ goto std_op;
+ } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
+ /* cast to biggest op */
+ t = VT_LLONG | VT_LONG;
+ if (bt1 == VT_LLONG)
+ t &= t1;
+ if (bt2 == VT_LLONG)
+ t &= t2;
+ /* convert to unsigned if it does not fit in a long long */
+ if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
+ (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
+ t |= VT_UNSIGNED;
+ goto std_op;
+ } else {
+ /* integer operations */
+ t = VT_INT | (VT_LONG & (t1 | t2));
+ /* convert to unsigned if it does not fit in an integer */
+ if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
+ (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
+ t |= VT_UNSIGNED;
+ std_op:
+ /* XXX: currently, some unsigned operations are explicit, so
+ we modify them here */
+ if (t & VT_UNSIGNED) {
+ if (op == TOK_SAR)
+ op = TOK_SHR;
+ else if (op == '/')
+ op = TOK_UDIV;
+ else if (op == '%')
+ op = TOK_UMOD;
+ else if (op == TOK_LT)
+ op = TOK_ULT;
+ else if (op == TOK_GT)
+ op = TOK_UGT;
+ else if (op == TOK_LE)
+ op = TOK_ULE;
+ else if (op == TOK_GE)
+ op = TOK_UGE;
+ }
+ vswap();
+ type1.t = t;
+ type1.ref = NULL;
+ gen_cast(&type1);
+ vswap();
+ /* special case for shifts and long long: we keep the shift as
+ an integer */
+ if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
+ type1.t = VT_INT;
+ gen_cast(&type1);
+ if (is_float(t))
+ gen_opif(op);
+ else
+ gen_opic(op);
+ if (op >= TOK_ULT && op <= TOK_GT) {
+ /* relational op: the result is an int */
+ vtop->type.t = VT_INT;
+ } else {
+ vtop->type.t = t;
+ }
+ }
+ // Make sure that we have converted to an rvalue:
+ if (vtop->r & VT_LVAL)
+ gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
+}
+
+#ifndef TCC_TARGET_ARM
+/* generic itof for unsigned long long case */
+static void gen_cvt_itof1(int t)
+{
+#ifdef TCC_TARGET_ARM64
+ gen_cvt_itof(t);
+#else
+ if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
+ (VT_LLONG | VT_UNSIGNED)) {
+
+ if (t == VT_FLOAT)
+ vpush_global_sym(&func_old_type, TOK___floatundisf);
+#if LDOUBLE_SIZE != 8
+ else if (t == VT_LDOUBLE)
+ vpush_global_sym(&func_old_type, TOK___floatundixf);
+#endif
+ else
+ vpush_global_sym(&func_old_type, TOK___floatundidf);
+ vrott(2);
+ gfunc_call(1);
+ vpushi(0);
+ vtop->r = reg_fret(t);
+ } else {
+ gen_cvt_itof(t);
+ }
+#endif
+}
+#endif
+
+/* generic ftoi for unsigned long long case */
+static void gen_cvt_ftoi1(int t)
+{
+#ifdef TCC_TARGET_ARM64
+ gen_cvt_ftoi(t);
+#else
+ int st;
+
+ if (t == (VT_LLONG | VT_UNSIGNED)) {
+ /* not handled natively */
+ st = vtop->type.t & VT_BTYPE;
+ if (st == VT_FLOAT)
+ vpush_global_sym(&func_old_type, TOK___fixunssfdi);
+#if LDOUBLE_SIZE != 8
+ else if (st == VT_LDOUBLE)
+ vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
+#endif
+ else
+ vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
+ vrott(2);
+ gfunc_call(1);
+ vpushi(0);
+ vtop->r = REG_IRET;
+ vtop->r2 = REG_LRET;
+ } else {
+ gen_cvt_ftoi(t);
+ }
+#endif
+}
+
+/* force char or short cast */
+static void force_charshort_cast(int t)
+{
+ int bits, dbt;
+
+ /* cannot cast static initializers */
+ if (STATIC_DATA_WANTED)
+ return;
+
+ dbt = t & VT_BTYPE;
+ /* XXX: add optimization if lvalue : just change type and offset */
+ if (dbt == VT_BYTE)
+ bits = 8;
+ else
+ bits = 16;
+ if (t & VT_UNSIGNED) {
+ vpushi((1 << bits) - 1);
+ gen_op('&');
+ } else {
+ if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
+ bits = 64 - bits;
+ else
+ bits = 32 - bits;
+ vpushi(bits);
+ gen_op(TOK_SHL);
+ /* result must be signed or the SAR is converted to an SHL
+ This was not the case when "t" was a signed short
+ and the last value on the stack was an unsigned int */
+ vtop->type.t &= ~VT_UNSIGNED;
+ vpushi(bits);
+ gen_op(TOK_SAR);
+ }
+}
+
+/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
+static void gen_cast_s(int t)
+{
+ CType type;
+ type.t = t;
+ type.ref = NULL;
+ gen_cast(&type);
+}
+
+static void gen_cast(CType *type)
+{
+ int sbt, dbt, sf, df, c, p;
+
+ /* special delayed cast for char/short */
+ /* XXX: in some cases (multiple cascaded casts), it may still
+ be incorrect */
+ if (vtop->r & VT_MUSTCAST) {
+ vtop->r &= ~VT_MUSTCAST;
+ force_charshort_cast(vtop->type.t);
+ }
+
+ /* bitfields first get cast to ints */
+ if (vtop->type.t & VT_BITFIELD) {
+ gv(RC_INT);
+ }
+
+ dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
+ sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
+
+ if (sbt != dbt) {
+ sf = is_float(sbt);
+ df = is_float(dbt);
+ c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+ p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
+#if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
+ c &= dbt != VT_LDOUBLE;
+#endif
+ if (c) {
+ /* constant case: we can do it now */
+ /* XXX: in ISOC, cannot do it if error in convert */
+ if (sbt == VT_FLOAT)
+ vtop->c.ld = vtop->c.f;
+ else if (sbt == VT_DOUBLE)
+ vtop->c.ld = vtop->c.d;
+
+ if (df) {
+ if ((sbt & VT_BTYPE) == VT_LLONG) {
+ if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
+ vtop->c.ld = vtop->c.i;
+ else
+ vtop->c.ld = -(long double)-vtop->c.i;
+ } else if(!sf) {
+ if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
+ vtop->c.ld = (uint32_t)vtop->c.i;
+ else
+ vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
+ }
+
+ if (dbt == VT_FLOAT)
+ vtop->c.f = (float)vtop->c.ld;
+ else if (dbt == VT_DOUBLE)
+ vtop->c.d = (double)vtop->c.ld;
+ } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
+ vtop->c.i = vtop->c.ld;
+ } else if (sf && dbt == VT_BOOL) {
+ vtop->c.i = (vtop->c.ld != 0);
+ } else {
+ if(sf)
+ vtop->c.i = vtop->c.ld;
+ else if (sbt == (VT_LLONG|VT_UNSIGNED))
+ ;
+ else if (sbt & VT_UNSIGNED)
+ vtop->c.i = (uint32_t)vtop->c.i;
+#if PTR_SIZE == 8
+ else if (sbt == VT_PTR)
+ ;
+#endif
+ else if (sbt != VT_LLONG)
+ vtop->c.i = ((uint32_t)vtop->c.i |
+ -(vtop->c.i & 0x80000000));
+
+ if (dbt == (VT_LLONG|VT_UNSIGNED))
+ ;
+ else if (dbt == VT_BOOL)
+ vtop->c.i = (vtop->c.i != 0);
+#if PTR_SIZE == 8
+ else if (dbt == VT_PTR)
+ ;
+#endif
+ else if (dbt != VT_LLONG) {
+ uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
+ (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
+ 0xffffffff);
+ vtop->c.i &= m;
+ if (!(dbt & VT_UNSIGNED))
+ vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
+ }
+ }
+ } else if (p && dbt == VT_BOOL) {
+ vtop->r = VT_CONST;
+ vtop->c.i = 1;
+ } else {
+ /* non constant case: generate code */
+ if (sf && df) {
+ /* convert from fp to fp */
+ gen_cvt_ftof(dbt);
+ } else if (df) {
+ /* convert int to fp */
+ gen_cvt_itof1(dbt);
+ } else if (sf) {
+ /* convert fp to int */
+ if (dbt == VT_BOOL) {
+ vpushi(0);
+ gen_op(TOK_NE);
+ } else {
+ /* we handle char/short/etc... with generic code */
+ if (dbt != (VT_INT | VT_UNSIGNED) &&
+ dbt != (VT_LLONG | VT_UNSIGNED) &&
+ dbt != VT_LLONG)
+ dbt = VT_INT;
+ gen_cvt_ftoi1(dbt);
+ if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
+ /* additional cast for char/short... */
+ vtop->type.t = dbt;
+ gen_cast(type);
+ }
+ }
+#if PTR_SIZE == 4
+ } else if ((dbt & VT_BTYPE) == VT_LLONG) {
+ if ((sbt & VT_BTYPE) != VT_LLONG) {
+ /* scalar to long long */
+ /* machine independent conversion */
+ gv(RC_INT);
+ /* generate high word */
+ if (sbt == (VT_INT | VT_UNSIGNED)) {
+ vpushi(0);
+ gv(RC_INT);
+ } else {
+ if (sbt == VT_PTR) {
+ /* cast from pointer to int before we apply
+ shift operation, which pointers don't support*/
+ gen_cast_s(VT_INT);
+ }
+ gv_dup();
+ vpushi(31);
+ gen_op(TOK_SAR);
+ }
+ /* patch second register */
+ vtop[-1].r2 = vtop->r;
+ vpop();
+ }
+#else
+ } else if ((dbt & VT_BTYPE) == VT_LLONG ||
+ (dbt & VT_BTYPE) == VT_PTR ||
+ (dbt & VT_BTYPE) == VT_FUNC) {
+ if ((sbt & VT_BTYPE) != VT_LLONG &&
+ (sbt & VT_BTYPE) != VT_PTR &&
+ (sbt & VT_BTYPE) != VT_FUNC) {
+ /* need to convert from 32bit to 64bit */
+ gv(RC_INT);
+ if (sbt != (VT_INT | VT_UNSIGNED)) {
+#if defined(TCC_TARGET_ARM64)
+ gen_cvt_sxtw();
+#elif defined(TCC_TARGET_X86_64)
+ int r = gv(RC_INT);
+ /* x86_64 specific: movslq */
+ o(0x6348);
+ o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
+#else
+#error
+#endif
+ }
+ }
+#endif
+ } else if (dbt == VT_BOOL) {
+ /* scalar to bool */
+ vpushi(0);
+ gen_op(TOK_NE);
+ } else if ((dbt & VT_BTYPE) == VT_BYTE ||
+ (dbt & VT_BTYPE) == VT_SHORT) {
+ if (sbt == VT_PTR) {
+ vtop->type.t = VT_INT;
+ tcc_warning("nonportable conversion from pointer to char/short");
+ }
+ force_charshort_cast(dbt);
+#if PTR_SIZE == 4
+ } else if ((dbt & VT_BTYPE) == VT_INT) {
+ /* scalar to int */
+ if ((sbt & VT_BTYPE) == VT_LLONG) {
+ /* from long long: just take low order word */
+ lexpand();
+ vpop();
+ }
+ /* if lvalue and single word type, nothing to do because
+ the lvalue already contains the real type size (see
+ VT_LVAL_xxx constants) */
+#endif
+ }
+ }
+ } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
+ /* if we are casting between pointer types,
+ we must update the VT_LVAL_xxx size */
+ vtop->r = (vtop->r & ~VT_LVAL_TYPE)
+ | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
+ }
+ vtop->type = *type;
+}
+
+/* return type size as known at compile time. Put alignment at 'a' */
+ST_FUNC int type_size(CType *type, int *a)
+{
+ Sym *s;
+ int bt;
+
+ bt = type->t & VT_BTYPE;
+ if (bt == VT_STRUCT) {
+ /* struct/union */
+ s = type->ref;
+ *a = s->r;
+ return s->c;
+ } else if (bt == VT_PTR) {
+ if (type->t & VT_ARRAY) {
+ int ts;
+
+ s = type->ref;
+ ts = type_size(&s->type, a);
+
+ if (ts < 0 && s->c < 0)
+ ts = -ts;
+
+ return ts * s->c;
+ } else {
+ *a = PTR_SIZE;
+ return PTR_SIZE;
+ }
+ } else if (IS_ENUM(type->t) && type->ref->c == -1) {
+ return -1; /* incomplete enum */
+ } else if (bt == VT_LDOUBLE) {
+ *a = LDOUBLE_ALIGN;
+ return LDOUBLE_SIZE;
+ } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
+#ifdef TCC_TARGET_I386
+#ifdef TCC_TARGET_PE
+ *a = 8;
+#else
+ *a = 4;
+#endif
+#elif defined(TCC_TARGET_ARM)
+#ifdef TCC_ARM_EABI
+ *a = 8;
+#else
+ *a = 4;
+#endif
+#else
+ *a = 8;
+#endif
+ return 8;
+ } else if (bt == VT_INT || bt == VT_FLOAT) {
+ *a = 4;
+ return 4;
+ } else if (bt == VT_SHORT) {
+ *a = 2;
+ return 2;
+ } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
+ *a = 8;
+ return 16;
+ } else {
+ /* char, void, function, _Bool */
+ *a = 1;
+ return 1;
+ }
+}
+
+/* push type size as known at runtime time on top of value stack. Put
+ alignment at 'a' */
+ST_FUNC void vla_runtime_type_size(CType *type, int *a)
+{
+ if (type->t & VT_VLA) {
+ type_size(&type->ref->type, a);
+ vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
+ } else {
+ vpushi(type_size(type, a));
+ }
+}
+
+static void vla_sp_restore(void) {
+ if (vlas_in_scope) {
+ gen_vla_sp_restore(vla_sp_loc);
+ }
+}
+
+static void vla_sp_restore_root(void) {
+ if (vlas_in_scope) {
+ gen_vla_sp_restore(vla_sp_root_loc);
+ }
+}
+
+/* return the pointed type of t */
+static inline CType *pointed_type(CType *type)
+{
+ return &type->ref->type;
+}
+
+/* modify type so that its it is a pointer to type. */
+ST_FUNC void mk_pointer(CType *type)
+{
+ Sym *s;
+ s = sym_push(SYM_FIELD, type, 0, -1);
+ type->t = VT_PTR | (type->t & VT_STORAGE);
+ type->ref = s;
+}
+
+/* compare function types. OLD functions match any new functions */
+static int is_compatible_func(CType *type1, CType *type2)
+{
+ Sym *s1, *s2;
+
+ s1 = type1->ref;
+ s2 = type2->ref;
+ if (!is_compatible_types(&s1->type, &s2->type))
+ return 0;
+ /* check func_call */
+ if (s1->f.func_call != s2->f.func_call)
+ return 0;
+ /* XXX: not complete */
+ if (s1->f.func_type == FUNC_OLD || s2->f.func_type == FUNC_OLD)
+ return 1;
+ if (s1->f.func_type != s2->f.func_type)
+ return 0;
+ while (s1 != NULL) {
+ if (s2 == NULL)
+ return 0;
+ if (!is_compatible_unqualified_types(&s1->type, &s2->type))
+ return 0;
+ s1 = s1->next;
+ s2 = s2->next;
+ }
+ if (s2)
+ return 0;
+ return 1;
+}
+
+/* return true if type1 and type2 are the same. If unqualified is
+ true, qualifiers on the types are ignored.
+
+ - enums are not checked as gcc __builtin_types_compatible_p ()
+ */
+static int compare_types(CType *type1, CType *type2, int unqualified)
+{
+ int bt1, t1, t2;
+
+ t1 = type1->t & VT_TYPE;
+ t2 = type2->t & VT_TYPE;
+ if (unqualified) {
+ /* strip qualifiers before comparing */
+ t1 &= ~(VT_CONSTANT | VT_VOLATILE);
+ t2 &= ~(VT_CONSTANT | VT_VOLATILE);
+ }
+
+ /* Default Vs explicit signedness only matters for char */
+ if ((t1 & VT_BTYPE) != VT_BYTE) {
+ t1 &= ~VT_DEFSIGN;
+ t2 &= ~VT_DEFSIGN;
+ }
+ /* XXX: bitfields ? */
+ if (t1 != t2)
+ return 0;
+ /* test more complicated cases */
+ bt1 = t1 & VT_BTYPE;
+ if (bt1 == VT_PTR) {
+ type1 = pointed_type(type1);
+ type2 = pointed_type(type2);
+ return is_compatible_types(type1, type2);
+ } else if (bt1 == VT_STRUCT) {
+ return (type1->ref == type2->ref);
+ } else if (bt1 == VT_FUNC) {
+ return is_compatible_func(type1, type2);
+ } else {
+ return 1;
+ }
+}
+
+/* return true if type1 and type2 are exactly the same (including
+ qualifiers).
+*/
+static int is_compatible_types(CType *type1, CType *type2)
+{
+ return compare_types(type1,type2,0);
+}
+
+/* return true if type1 and type2 are the same (ignoring qualifiers).
+*/
+static int is_compatible_unqualified_types(CType *type1, CType *type2)
+{
+ return compare_types(type1,type2,1);
+}
+
+/* print a type. If 'varstr' is not NULL, then the variable is also
+ printed in the type */
+/* XXX: union */
+/* XXX: add array and function pointers */
+static void type_to_str(char *buf, int buf_size,
+ CType *type, const char *varstr)
+{
+ int bt, v, t;
+ Sym *s, *sa;
+ char buf1[256];
+ const char *tstr;
+
+ t = type->t;
+ bt = t & VT_BTYPE;
+ buf[0] = '\0';
+
+ if (t & VT_EXTERN)
+ pstrcat(buf, buf_size, "extern ");
+ if (t & VT_STATIC)
+ pstrcat(buf, buf_size, "static ");
+ if (t & VT_TYPEDEF)
+ pstrcat(buf, buf_size, "typedef ");
+ if (t & VT_INLINE)
+ pstrcat(buf, buf_size, "inline ");
+ if (t & VT_VOLATILE)
+ pstrcat(buf, buf_size, "volatile ");
+ if (t & VT_CONSTANT)
+ pstrcat(buf, buf_size, "const ");
+
+ if (((t & VT_DEFSIGN) && bt == VT_BYTE)
+ || ((t & VT_UNSIGNED)
+ && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
+ && !IS_ENUM(t)
+ ))
+ pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
+
+ buf_size -= strlen(buf);
+ buf += strlen(buf);
+
+ switch(bt) {
+ case VT_VOID:
+ tstr = "void";
+ goto add_tstr;
+ case VT_BOOL:
+ tstr = "_Bool";
+ goto add_tstr;
+ case VT_BYTE:
+ tstr = "char";
+ goto add_tstr;
+ case VT_SHORT:
+ tstr = "short";
+ goto add_tstr;
+ case VT_INT:
+ tstr = "int";
+ goto maybe_long;
+ case VT_LLONG:
+ tstr = "long long";
+ maybe_long:
+ if (t & VT_LONG)
+ tstr = "long";
+ if (!IS_ENUM(t))
+ goto add_tstr;
+ tstr = "enum ";
+ goto tstruct;
+ case VT_FLOAT:
+ tstr = "float";
+ goto add_tstr;
+ case VT_DOUBLE:
+ tstr = "double";
+ goto add_tstr;
+ case VT_LDOUBLE:
+ tstr = "long double";
+ add_tstr:
+ pstrcat(buf, buf_size, tstr);
+ break;
+ case VT_STRUCT:
+ tstr = "struct ";
+ if (IS_UNION(t))
+ tstr = "union ";
+ tstruct:
+ pstrcat(buf, buf_size, tstr);
+ v = type->ref->v & ~SYM_STRUCT;
+ if (v >= SYM_FIRST_ANOM)
+ pstrcat(buf, buf_size, "<anonymous>");
+ else
+ pstrcat(buf, buf_size, get_tok_str(v, NULL));
+ break;
+ case VT_FUNC:
+ s = type->ref;
+ type_to_str(buf, buf_size, &s->type, varstr);
+ pstrcat(buf, buf_size, "(");
+ sa = s->next;
+ while (sa != NULL) {
+ type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
+ pstrcat(buf, buf_size, buf1);
+ sa = sa->next;
+ if (sa)
+ pstrcat(buf, buf_size, ", ");
+ }
+ pstrcat(buf, buf_size, ")");
+ goto no_var;
+ case VT_PTR:
+ s = type->ref;
+ if (t & VT_ARRAY) {
+ snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
+ type_to_str(buf, buf_size, &s->type, buf1);
+ goto no_var;
+ }
+ pstrcpy(buf1, sizeof(buf1), "*");
+ if (t & VT_CONSTANT)
+ pstrcat(buf1, buf_size, "const ");
+ if (t & VT_VOLATILE)
+ pstrcat(buf1, buf_size, "volatile ");
+ if (varstr)
+ pstrcat(buf1, sizeof(buf1), varstr);
+ type_to_str(buf, buf_size, &s->type, buf1);
+ goto no_var;
+ }
+ if (varstr) {
+ pstrcat(buf, buf_size, " ");
+ pstrcat(buf, buf_size, varstr);
+ }
+ no_var: ;
+}
+
+/* verify type compatibility to store vtop in 'dt' type, and generate
+ casts if needed. */
+static void gen_assign_cast(CType *dt)
+{
+ CType *st, *type1, *type2;
+ char buf1[256], buf2[256];
+ int dbt, sbt;
+
+ st = &vtop->type; /* source type */
+ dbt = dt->t & VT_BTYPE;
+ sbt = st->t & VT_BTYPE;
+ if (sbt == VT_VOID || dbt == VT_VOID) {
+ if (sbt == VT_VOID && dbt == VT_VOID)
+ ; /*
+ It is Ok if both are void
+ A test program:
+ void func1() {}
+ void func2() {
+ return func1();
+ }
+ gcc accepts this program
+ */
+ else
+ tcc_error("cannot cast from/to void");
+ }
+ if (dt->t & VT_CONSTANT)
+ tcc_warning("assignment of read-only location");
+ switch(dbt) {
+ case VT_PTR:
+ /* special cases for pointers */
+ /* '0' can also be a pointer */
+ if (is_null_pointer(vtop))
+ goto type_ok;
+ /* accept implicit pointer to integer cast with warning */
+ if (is_integer_btype(sbt)) {
+ tcc_warning("assignment makes pointer from integer without a cast");
+ goto type_ok;
+ }
+ type1 = pointed_type(dt);
+ /* a function is implicitly a function pointer */
+ if (sbt == VT_FUNC) {
+ if ((type1->t & VT_BTYPE) != VT_VOID &&
+ !is_compatible_types(pointed_type(dt), st))
+ tcc_warning("assignment from incompatible pointer type");
+ goto type_ok;
+ }
+ if (sbt != VT_PTR)
+ goto error;
+ type2 = pointed_type(st);
+ if ((type1->t & VT_BTYPE) == VT_VOID ||
+ (type2->t & VT_BTYPE) == VT_VOID) {
+ /* void * can match anything */
+ } else {
+ //printf("types %08x %08x\n", type1->t, type2->t);
+ /* exact type match, except for qualifiers */
+ if (!is_compatible_unqualified_types(type1, type2)) {
+ /* Like GCC don't warn by default for merely changes
+ in pointer target signedness. Do warn for different
+ base types, though, in particular for unsigned enums
+ and signed int targets. */
+ if ((type1->t & (VT_BTYPE|VT_LONG)) != (type2->t & (VT_BTYPE|VT_LONG))
+ || IS_ENUM(type1->t) || IS_ENUM(type2->t)
+ )
+ tcc_warning("assignment from incompatible pointer type");
+ }
+ }
+ /* check const and volatile */
+ if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
+ (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
+ tcc_warning("assignment discards qualifiers from pointer target type");
+ break;
+ case VT_BYTE:
+ case VT_SHORT:
+ case VT_INT:
+ case VT_LLONG:
+ if (sbt == VT_PTR || sbt == VT_FUNC) {
+ tcc_warning("assignment makes integer from pointer without a cast");
+ } else if (sbt == VT_STRUCT) {
+ goto case_VT_STRUCT;
+ }
+ /* XXX: more tests */
+ break;
+ case VT_STRUCT:
+ case_VT_STRUCT:
+ if (!is_compatible_unqualified_types(dt, st)) {
+ error:
+ type_to_str(buf1, sizeof(buf1), st, NULL);
+ type_to_str(buf2, sizeof(buf2), dt, NULL);
+ tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
+ }
+ break;
+ }
+ type_ok:
+ gen_cast(dt);
+}
+
+/* store vtop in lvalue pushed on stack */
+ST_FUNC void vstore(void)
+{
+ int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
+
+ ft = vtop[-1].type.t;
+ sbt = vtop->type.t & VT_BTYPE;
+ dbt = ft & VT_BTYPE;
+ if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
+ (sbt == VT_INT && dbt == VT_SHORT))
+ && !(vtop->type.t & VT_BITFIELD)) {
+ /* optimize char/short casts */
+ delayed_cast = VT_MUSTCAST;
+ vtop->type.t = ft & VT_TYPE;
+ /* XXX: factorize */
+ if (ft & VT_CONSTANT)
+ tcc_warning("assignment of read-only location");
+ } else {
+ delayed_cast = 0;
+ if (!(ft & VT_BITFIELD))
+ gen_assign_cast(&vtop[-1].type);
+ }
+
+ if (sbt == VT_STRUCT) {
+ /* if structure, only generate pointer */
+ /* structure assignment : generate memcpy */
+ /* XXX: optimize if small size */
+ size = type_size(&vtop->type, &align);
+
+ /* destination */
+ vswap();
+ vtop->type.t = VT_PTR;
+ gaddrof();
+
+ /* address of memcpy() */
+#ifdef TCC_ARM_EABI
+ if(!(align & 7))
+ vpush_global_sym(&func_old_type, TOK_memcpy8);
+ else if(!(align & 3))
+ vpush_global_sym(&func_old_type, TOK_memcpy4);
+ else
+#endif
+ /* Use memmove, rather than memcpy, as dest and src may be same: */
+ vpush_global_sym(&func_old_type, TOK_memmove);
+
+ vswap();
+ /* source */
+ vpushv(vtop - 2);
+ vtop->type.t = VT_PTR;
+ gaddrof();
+ /* type size */
+ vpushi(size);
+ gfunc_call(3);
+
+ /* leave source on stack */
+ } else if (ft & VT_BITFIELD) {
+ /* bitfield store handling */
+
+ /* save lvalue as expression result (example: s.b = s.a = n;) */
+ vdup(), vtop[-1] = vtop[-2];
+
+ bit_pos = BIT_POS(ft);
+ bit_size = BIT_SIZE(ft);
+ /* remove bit field info to avoid loops */
+ vtop[-1].type.t = ft & ~VT_STRUCT_MASK;
+
+ if ((ft & VT_BTYPE) == VT_BOOL) {
+ gen_cast(&vtop[-1].type);
+ vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
+ }
+
+ r = adjust_bf(vtop - 1, bit_pos, bit_size);
+ if (r == VT_STRUCT) {
+ gen_cast_s((ft & VT_BTYPE) == VT_LLONG ? VT_LLONG : VT_INT);
+ store_packed_bf(bit_pos, bit_size);
+ } else {
+ unsigned long long mask = (1ULL << bit_size) - 1;
+ if ((ft & VT_BTYPE) != VT_BOOL) {
+ /* mask source */
+ if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG)
+ vpushll(mask);
+ else
+ vpushi((unsigned)mask);
+ gen_op('&');
+ }
+ /* shift source */
+ vpushi(bit_pos);
+ gen_op(TOK_SHL);
+ vswap();
+ /* duplicate destination */
+ vdup();
+ vrott(3);
+ /* load destination, mask and or with source */
+ if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
+ vpushll(~(mask << bit_pos));
+ else
+ vpushi(~((unsigned)mask << bit_pos));
+ gen_op('&');
+ gen_op('|');
+ /* store result */
+ vstore();
+ /* ... and discard */
+ vpop();
+ }
+ } else if (dbt == VT_VOID) {
+ --vtop;
+ } else {
+#ifdef CONFIG_TCC_BCHECK
+ /* bound check case */
+ if (vtop[-1].r & VT_MUSTBOUND) {
+ vswap();
+ gbound();
+ vswap();
+ }
+#endif
+ rc = RC_INT;
+ if (is_float(ft)) {
+ rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+ if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+ rc = RC_ST0;
+ } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
+ rc = RC_FRET;
+ }
+#endif
+ }
+ r = gv(rc); /* generate value */
+ /* if lvalue was saved on stack, must read it */
+ if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
+ SValue sv;
+ t = get_reg(RC_INT);
+#if PTR_SIZE == 8
+ sv.type.t = VT_PTR;
+#else
+ sv.type.t = VT_INT;
+#endif
+ sv.r = VT_LOCAL | VT_LVAL;
+ sv.c.i = vtop[-1].c.i;
+ load(t, &sv);
+ vtop[-1].r = t | VT_LVAL;
+ }
+ /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
+#if PTR_SIZE == 8
+ if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
+ int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
+#else
+ if ((ft & VT_BTYPE) == VT_LLONG) {
+ int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
+#endif
+ vtop[-1].type.t = load_type;
+ store(r, vtop - 1);
+ vswap();
+ /* convert to int to increment easily */
+ vtop->type.t = addr_type;
+ gaddrof();
+ vpushi(load_size);
+ gen_op('+');
+ vtop->r |= VT_LVAL;
+ vswap();
+ vtop[-1].type.t = load_type;
+ /* XXX: it works because r2 is spilled last ! */
+ store(vtop->r2, vtop - 1);
+ } else {
+ store(r, vtop - 1);
+ }
+
+ vswap();
+ vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
+ vtop->r |= delayed_cast;
+ }
+}
+
+/* post defines POST/PRE add. c is the token ++ or -- */
+ST_FUNC void inc(int post, int c)
+{
+ test_lvalue();
+ vdup(); /* save lvalue */
+ if (post) {
+ gv_dup(); /* duplicate value */
+ vrotb(3);
+ vrotb(3);
+ }
+ /* add constant */
+ vpushi(c - TOK_MID);
+ gen_op('+');
+ vstore(); /* store value */
+ if (post)
+ vpop(); /* if post op, return saved value */
+}
+
+ST_FUNC void parse_mult_str (CString *astr, const char *msg)
+{
+ /* read the string */
+ if (tok != TOK_STR)
+ expect(msg);
+ cstr_new(astr);
+ while (tok == TOK_STR) {
+ /* XXX: add \0 handling too ? */
+ cstr_cat(astr, tokc.str.data, -1);
+ next();
+ }
+ cstr_ccat(astr, '\0');
+}
+
+/* If I is >= 1 and a power of two, returns log2(i)+1.
+ If I is 0 returns 0. */
+static int exact_log2p1(int i)
+{
+ int ret;
+ if (!i)
+ return 0;
+ for (ret = 1; i >= 1 << 8; ret += 8)
+ i >>= 8;
+ if (i >= 1 << 4)
+ ret += 4, i >>= 4;
+ if (i >= 1 << 2)
+ ret += 2, i >>= 2;
+ if (i >= 1 << 1)
+ ret++;
+ return ret;
+}
+
+/* Parse __attribute__((...)) GNUC extension. */
+static void parse_attribute(AttributeDef *ad)
+{
+ int t, n;
+ CString astr;
+
+redo:
+ if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2)
+ return;
+ next();
+ skip('(');
+ skip('(');
+ while (tok != ')') {
+ if (tok < TOK_IDENT)
+ expect("attribute name");
+ t = tok;
+ next();
+ switch(t) {
+ case TOK_SECTION1:
+ case TOK_SECTION2:
+ skip('(');
+ parse_mult_str(&astr, "section name");
+ ad->section = find_section(tcc_state, (char *)astr.data);
+ skip(')');
+ cstr_free(&astr);
+ break;
+ case TOK_ALIAS1:
+ case TOK_ALIAS2:
+ skip('(');
+ parse_mult_str(&astr, "alias(\"target\")");
+ ad->alias_target = /* save string as token, for later */
+ tok_alloc((char*)astr.data, astr.size-1)->tok;
+ skip(')');
+ cstr_free(&astr);
+ break;
+ case TOK_VISIBILITY1:
+ case TOK_VISIBILITY2:
+ skip('(');
+ parse_mult_str(&astr,
+ "visibility(\"default|hidden|internal|protected\")");
+ if (!strcmp (astr.data, "default"))
+ ad->a.visibility = STV_DEFAULT;
+ else if (!strcmp (astr.data, "hidden"))
+ ad->a.visibility = STV_HIDDEN;
+ else if (!strcmp (astr.data, "internal"))
+ ad->a.visibility = STV_INTERNAL;
+ else if (!strcmp (astr.data, "protected"))
+ ad->a.visibility = STV_PROTECTED;
+ else
+ expect("visibility(\"default|hidden|internal|protected\")");
+ skip(')');
+ cstr_free(&astr);
+ break;
+ case TOK_ALIGNED1:
+ case TOK_ALIGNED2:
+ if (tok == '(') {
+ next();
+ n = expr_const();
+ if (n <= 0 || (n & (n - 1)) != 0)
+ tcc_error("alignment must be a positive power of two");
+ skip(')');
+ } else {
+ n = MAX_ALIGN;
+ }
+ ad->a.aligned = exact_log2p1(n);
+ if (n != 1 << (ad->a.aligned - 1))
+ tcc_error("alignment of %d is larger than implemented", n);
+ break;
+ case TOK_PACKED1:
+ case TOK_PACKED2:
+ ad->a.packed = 1;
+ break;
+ case TOK_WEAK1:
+ case TOK_WEAK2:
+ ad->a.weak = 1;
+ break;
+ case TOK_UNUSED1:
+ case TOK_UNUSED2:
+ /* currently, no need to handle it because tcc does not
+ track unused objects */
+ break;
+ case TOK_NORETURN1:
+ case TOK_NORETURN2:
+ /* currently, no need to handle it because tcc does not
+ track unused objects */
+ break;
+ case TOK_CDECL1:
+ case TOK_CDECL2:
+ case TOK_CDECL3:
+ ad->f.func_call = FUNC_CDECL;
+ break;
+ case TOK_STDCALL1:
+ case TOK_STDCALL2:
+ case TOK_STDCALL3:
+ ad->f.func_call = FUNC_STDCALL;
+ break;
+#ifdef TCC_TARGET_I386
+ case TOK_REGPARM1:
+ case TOK_REGPARM2:
+ skip('(');
+ n = expr_const();
+ if (n > 3)
+ n = 3;
+ else if (n < 0)
+ n = 0;
+ if (n > 0)
+ ad->f.func_call = FUNC_FASTCALL1 + n - 1;
+ skip(')');
+ break;
+ case TOK_FASTCALL1:
+ case TOK_FASTCALL2:
+ case TOK_FASTCALL3:
+ ad->f.func_call = FUNC_FASTCALLW;
+ break;
+#endif
+ case TOK_MODE:
+ skip('(');
+ switch(tok) {
+ case TOK_MODE_DI:
+ ad->attr_mode = VT_LLONG + 1;
+ break;
+ case TOK_MODE_QI:
+ ad->attr_mode = VT_BYTE + 1;
+ break;
+ case TOK_MODE_HI:
+ ad->attr_mode = VT_SHORT + 1;
+ break;
+ case TOK_MODE_SI:
+ case TOK_MODE_word:
+ ad->attr_mode = VT_INT + 1;
+ break;
+ default:
+ tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
+ break;
+ }
+ next();
+ skip(')');
+ break;
+ case TOK_DLLEXPORT:
+ ad->a.dllexport = 1;
+ break;
+ case TOK_DLLIMPORT:
+ ad->a.dllimport = 1;
+ break;
+ default:
+ if (tcc_state->warn_unsupported)
+ tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
+ /* skip parameters */
+ if (tok == '(') {
+ int parenthesis = 0;
+ do {
+ if (tok == '(')
+ parenthesis++;
+ else if (tok == ')')
+ parenthesis--;
+ next();
+ } while (parenthesis && tok != -1);
+ }
+ break;
+ }
+ if (tok != ',')
+ break;
+ next();
+ }
+ skip(')');
+ skip(')');
+ goto redo;
+}
+
+static Sym * find_field (CType *type, int v)
+{
+ Sym *s = type->ref;
+ v |= SYM_FIELD;
+ while ((s = s->next) != NULL) {
+ if ((s->v & SYM_FIELD) &&
+ (s->type.t & VT_BTYPE) == VT_STRUCT &&
+ (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
+ Sym *ret = find_field (&s->type, v);
+ if (ret)
+ return ret;
+ }
+ if (s->v == v)
+ break;
+ }
+ return s;
+}
+
+static void struct_add_offset (Sym *s, int offset)
+{
+ while ((s = s->next) != NULL) {
+ if ((s->v & SYM_FIELD) &&
+ (s->type.t & VT_BTYPE) == VT_STRUCT &&
+ (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
+ struct_add_offset(s->type.ref, offset);
+ } else
+ s->c += offset;
+ }
+}
+
+static void struct_layout(CType *type, AttributeDef *ad)
+{
+ int size, align, maxalign, offset, c, bit_pos, bit_size;
+ int packed, a, bt, prevbt, prev_bit_size;
+ int pcc = !tcc_state->ms_bitfields;
+ int pragma_pack = *tcc_state->pack_stack_ptr;
+ Sym *f;
+
+ maxalign = 1;
+ offset = 0;
+ c = 0;
+ bit_pos = 0;
+ prevbt = VT_STRUCT; /* make it never match */
+ prev_bit_size = 0;
+
+//#define BF_DEBUG
+
+ for (f = type->ref->next; f; f = f->next) {
+ if (f->type.t & VT_BITFIELD)
+ bit_size = BIT_SIZE(f->type.t);
+ else
+ bit_size = -1;
+ size = type_size(&f->type, &align);
+ a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
+ packed = 0;
+
+ if (pcc && bit_size == 0) {
+ /* in pcc mode, packing does not affect zero-width bitfields */
+
+ } else {
+ /* in pcc mode, attribute packed overrides if set. */
+ if (pcc && (f->a.packed || ad->a.packed))
+ align = packed = 1;
+
+ /* pragma pack overrides align if lesser and packs bitfields always */
+ if (pragma_pack) {
+ packed = 1;
+ if (pragma_pack < align)
+ align = pragma_pack;
+ /* in pcc mode pragma pack also overrides individual align */
+ if (pcc && pragma_pack < a)
+ a = 0;
+ }
+ }
+ /* some individual align was specified */
+ if (a)
+ align = a;
+
+ if (type->ref->type.t == VT_UNION) {
+ if (pcc && bit_size >= 0)
+ size = (bit_size + 7) >> 3;
+ offset = 0;
+ if (size > c)
+ c = size;
+
+ } else if (bit_size < 0) {
+ if (pcc)
+ c += (bit_pos + 7) >> 3;
+ c = (c + align - 1) & -align;
+ offset = c;
+ if (size > 0)
+ c += size;
+ bit_pos = 0;
+ prevbt = VT_STRUCT;
+ prev_bit_size = 0;
+
+ } else {
+ /* A bit-field. Layout is more complicated. There are two
+ options: PCC (GCC) compatible and MS compatible */
+ if (pcc) {
+ /* In PCC layout a bit-field is placed adjacent to the
+ preceding bit-fields, except if:
+ - it has zero-width
+ - an individual alignment was given
+ - it would overflow its base type container and
+ there is no packing */
+ if (bit_size == 0) {
+ new_field:
+ c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align;
+ bit_pos = 0;
+ } else if (f->a.aligned) {
+ goto new_field;
+ } else if (!packed) {
+ int a8 = align * 8;
+ int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8;
+ if (ofs > size / align)
+ goto new_field;
+ }
+
+ /* in pcc mode, long long bitfields have type int if they fit */
+ if (size == 8 && bit_size <= 32)
+ f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4;
+
+ while (bit_pos >= align * 8)
+ c += align, bit_pos -= align * 8;
+ offset = c;
+
+ /* In PCC layout named bit-fields influence the alignment
+ of the containing struct using the base types alignment,
+ except for packed fields (which here have correct align). */
+ if (f->v & SYM_FIRST_ANOM
+ // && bit_size // ??? gcc on ARM/rpi does that
+ )
+ align = 1;
+
+ } else {
+ bt = f->type.t & VT_BTYPE;
+ if ((bit_pos + bit_size > size * 8)
+ || (bit_size > 0) == (bt != prevbt)
+ ) {
+ c = (c + align - 1) & -align;
+ offset = c;
+ bit_pos = 0;
+ /* In MS bitfield mode a bit-field run always uses
+ at least as many bits as the underlying type.
+ To start a new run it's also required that this
+ or the last bit-field had non-zero width. */
+ if (bit_size || prev_bit_size)
+ c += size;
+ }
+ /* In MS layout the records alignment is normally
+ influenced by the field, except for a zero-width
+ field at the start of a run (but by further zero-width
+ fields it is again). */
+ if (bit_size == 0 && prevbt != bt)
+ align = 1;
+ prevbt = bt;
+ prev_bit_size = bit_size;
+ }
+
+ f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
+ | (bit_pos << VT_STRUCT_SHIFT);
+ bit_pos += bit_size;
+ }
+ if (align > maxalign)
+ maxalign = align;
+
+#ifdef BF_DEBUG
+ printf("set field %s offset %-2d size %-2d align %-2d",
+ get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align);
+ if (f->type.t & VT_BITFIELD) {
+ printf(" pos %-2d bits %-2d",
+ BIT_POS(f->type.t),
+ BIT_SIZE(f->type.t)
+ );
+ }
+ printf("\n");
+#endif
+
+ if (f->v & SYM_FIRST_ANOM && (f->type.t & VT_BTYPE) == VT_STRUCT) {
+ Sym *ass;
+ /* An anonymous struct/union. Adjust member offsets
+ to reflect the real offset of our containing struct.
+ Also set the offset of this anon member inside
+ the outer struct to be zero. Via this it
+ works when accessing the field offset directly
+ (from base object), as well as when recursing
+ members in initializer handling. */
+ int v2 = f->type.ref->v;
+ if (!(v2 & SYM_FIELD) &&
+ (v2 & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+ Sym **pps;
+ /* This happens only with MS extensions. The
+ anon member has a named struct type, so it
+ potentially is shared with other references.
+ We need to unshare members so we can modify
+ them. */
+ ass = f->type.ref;
+ f->type.ref = sym_push(anon_sym++ | SYM_FIELD,
+ &f->type.ref->type, 0,
+ f->type.ref->c);
+ pps = &f->type.ref->next;
+ while ((ass = ass->next) != NULL) {
+ *pps = sym_push(ass->v, &ass->type, 0, ass->c);
+ pps = &((*pps)->next);
+ }
+ *pps = NULL;
+ }
+ struct_add_offset(f->type.ref, offset);
+ f->c = 0;
+ } else {
+ f->c = offset;
+ }
+
+ f->r = 0;
+ }
+
+ if (pcc)
+ c += (bit_pos + 7) >> 3;
+
+ /* store size and alignment */
+ a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
+ if (a < maxalign)
+ a = maxalign;
+ type->ref->r = a;
+ if (pragma_pack && pragma_pack < maxalign && 0 == pcc) {
+ /* can happen if individual align for some member was given. In
+ this case MSVC ignores maxalign when aligning the size */
+ a = pragma_pack;
+ if (a < bt)
+ a = bt;
+ }
+ c = (c + a - 1) & -a;
+ type->ref->c = c;
+
+#ifdef BF_DEBUG
+ printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
+#endif
+
+ /* check whether we can access bitfields by their type */
+ for (f = type->ref->next; f; f = f->next) {
+ int s, px, cx, c0;
+ CType t;
+
+ if (0 == (f->type.t & VT_BITFIELD))
+ continue;
+ f->type.ref = f;
+ f->auxtype = -1;
+ bit_size = BIT_SIZE(f->type.t);
+ if (bit_size == 0)
+ continue;
+ bit_pos = BIT_POS(f->type.t);
+ size = type_size(&f->type, &align);
+ if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
+ continue;
+
+ /* try to access the field using a different type */
+ c0 = -1, s = align = 1;
+ for (;;) {
+ px = f->c * 8 + bit_pos;
+ cx = (px >> 3) & -align;
+ px = px - (cx << 3);
+ if (c0 == cx)
+ break;
+ s = (px + bit_size + 7) >> 3;
+ if (s > 4) {
+ t.t = VT_LLONG;
+ } else if (s > 2) {
+ t.t = VT_INT;
+ } else if (s > 1) {
+ t.t = VT_SHORT;
+ } else {
+ t.t = VT_BYTE;
+ }
+ s = type_size(&t, &align);
+ c0 = cx;
+ }
+
+ if (px + bit_size <= s * 8 && cx + s <= c) {
+ /* update offset and bit position */
+ f->c = cx;
+ bit_pos = px;
+ f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
+ | (bit_pos << VT_STRUCT_SHIFT);
+ if (s != size)
+ f->auxtype = t.t;
+#ifdef BF_DEBUG
+ printf("FIX field %s offset %-2d size %-2d align %-2d "
+ "pos %-2d bits %-2d\n",
+ get_tok_str(f->v & ~SYM_FIELD, NULL),
+ cx, s, align, px, bit_size);
+#endif
+ } else {
+ /* fall back to load/store single-byte wise */
+ f->auxtype = VT_STRUCT;
+#ifdef BF_DEBUG
+ printf("FIX field %s : load byte-wise\n",
+ get_tok_str(f->v & ~SYM_FIELD, NULL));
+#endif
+ }
+ }
+}
+
+/* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
+static void struct_decl(CType *type, int u)
+{
+ int v, c, size, align, flexible;
+ int bit_size, bsize, bt;
+ Sym *s, *ss, **ps;
+ AttributeDef ad, ad1;
+ CType type1, btype;
+
+ memset(&ad, 0, sizeof ad);
+ next();
+ parse_attribute(&ad);
+ if (tok != '{') {
+ v = tok;
+ next();
+ /* struct already defined ? return it */
+ if (v < TOK_IDENT)
+ expect("struct/union/enum name");
+ s = struct_find(v);
+ if (s && (s->sym_scope == local_scope || tok != '{')) {
+ if (u == s->type.t)
+ goto do_decl;
+ if (u == VT_ENUM && IS_ENUM(s->type.t))
+ goto do_decl;
+ tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
+ }
+ } else {
+ v = anon_sym++;
+ }
+ /* Record the original enum/struct/union token. */
+ type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;
+ type1.ref = NULL;
+ /* we put an undefined size for struct/union */
+ s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
+ s->r = 0; /* default alignment is zero as gcc */
+do_decl:
+ type->t = s->type.t;
+ type->ref = s;
+
+ if (tok == '{') {
+ next();
+ if (s->c != -1)
+ tcc_error("struct/union/enum already defined");
+ /* cannot be empty */
+ /* non empty enums are not allowed */
+ ps = &s->next;
+ if (u == VT_ENUM) {
+ long long ll = 0, pl = 0, nl = 0;
+ CType t;
+ t.ref = s;
+ /* enum symbols have static storage */
+ t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
+ for(;;) {
+ v = tok;
+ if (v < TOK_UIDENT)
+ expect("identifier");
+ ss = sym_find(v);
+ if (ss && !local_stack)
+ tcc_error("redefinition of enumerator '%s'",
+ get_tok_str(v, NULL));
+ next();
+ if (tok == '=') {
+ next();
+ ll = expr_const64();
+ }
+ ss = sym_push(v, &t, VT_CONST, 0);
+ ss->enum_val = ll;
+ *ps = ss, ps = &ss->next;
+ if (ll < nl)
+ nl = ll;
+ if (ll > pl)
+ pl = ll;
+ if (tok != ',')
+ break;
+ next();
+ ll++;
+ /* NOTE: we accept a trailing comma */
+ if (tok == '}')
+ break;
+ }
+ skip('}');
+ /* set integral type of the enum */
+ t.t = VT_INT;
+ if (nl >= 0) {
+ if (pl != (unsigned)pl)
+ t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
+ t.t |= VT_UNSIGNED;
+ } else if (pl != (int)pl || nl != (int)nl)
+ t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
+ s->type.t = type->t = t.t | VT_ENUM;
+ s->c = 0;
+ /* set type for enum members */
+ for (ss = s->next; ss; ss = ss->next) {
+ ll = ss->enum_val;
+ if (ll == (int)ll) /* default is int if it fits */
+ continue;
+ if (t.t & VT_UNSIGNED) {
+ ss->type.t |= VT_UNSIGNED;
+ if (ll == (unsigned)ll)
+ continue;
+ }
+ ss->type.t = (ss->type.t & ~VT_BTYPE)
+ | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
+ }
+ } else {
+ c = 0;
+ flexible = 0;
+ while (tok != '}') {
+ if (!parse_btype(&btype, &ad1)) {
+ skip(';');
+ continue;
+ }
+ while (1) {
+ if (flexible)
+ tcc_error("flexible array member '%s' not at the end of struct",
+ get_tok_str(v, NULL));
+ bit_size = -1;
+ v = 0;
+ type1 = btype;
+ if (tok != ':') {
+ if (tok != ';')
+ type_decl(&type1, &ad1, &v, TYPE_DIRECT);
+ if (v == 0) {
+ if ((type1.t & VT_BTYPE) != VT_STRUCT)
+ expect("identifier");
+ else {
+ int v = btype.ref->v;
+ if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+ if (tcc_state->ms_extensions == 0)
+ expect("identifier");
+ }
+ }
+ }
+ if (type_size(&type1, &align) < 0) {
+ if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c)
+ flexible = 1;
+ else
+ tcc_error("field '%s' has incomplete type",
+ get_tok_str(v, NULL));
+ }
+ if ((type1.t & VT_BTYPE) == VT_FUNC ||
+ (type1.t & VT_STORAGE))
+ tcc_error("invalid type for '%s'",
+ get_tok_str(v, NULL));
+ }
+ if (tok == ':') {
+ next();
+ bit_size = expr_const();
+ /* XXX: handle v = 0 case for messages */
+ if (bit_size < 0)
+ tcc_error("negative width in bit-field '%s'",
+ get_tok_str(v, NULL));
+ if (v && bit_size == 0)
+ tcc_error("zero width for bit-field '%s'",
+ get_tok_str(v, NULL));
+ parse_attribute(&ad1);
+ }
+ size = type_size(&type1, &align);
+ if (bit_size >= 0) {
+ bt = type1.t & VT_BTYPE;
+ if (bt != VT_INT &&
+ bt != VT_BYTE &&
+ bt != VT_SHORT &&
+ bt != VT_BOOL &&
+ bt != VT_LLONG)
+ tcc_error("bitfields must have scalar type");
+ bsize = size * 8;
+ if (bit_size > bsize) {
+ tcc_error("width of '%s' exceeds its type",
+ get_tok_str(v, NULL));
+ } else if (bit_size == bsize
+ && !ad.a.packed && !ad1.a.packed) {
+ /* no need for bit fields */
+ ;
+ } else if (bit_size == 64) {
+ tcc_error("field width 64 not implemented");
+ } else {
+ type1.t = (type1.t & ~VT_STRUCT_MASK)
+ | VT_BITFIELD
+ | (bit_size << (VT_STRUCT_SHIFT + 6));
+ }
+ }
+ if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
+ /* Remember we've seen a real field to check
+ for placement of flexible array member. */
+ c = 1;
+ }
+ /* If member is a struct or bit-field, enforce
+ placing into the struct (as anonymous). */
+ if (v == 0 &&
+ ((type1.t & VT_BTYPE) == VT_STRUCT ||
+ bit_size >= 0)) {
+ v = anon_sym++;
+ }
+ if (v) {
+ ss = sym_push(v | SYM_FIELD, &type1, 0, 0);
+ ss->a = ad1.a;
+ *ps = ss;
+ ps = &ss->next;
+ }
+ if (tok == ';' || tok == TOK_EOF)
+ break;
+ skip(',');
+ }
+ skip(';');
+ }
+ skip('}');
+ parse_attribute(&ad);
+ struct_layout(type, &ad);
+ }
+ }
+}
+
+static void sym_to_attr(AttributeDef *ad, Sym *s)
+{
+ if (s->a.aligned && 0 == ad->a.aligned)
+ ad->a.aligned = s->a.aligned;
+ if (s->f.func_call && 0 == ad->f.func_call)
+ ad->f.func_call = s->f.func_call;
+ if (s->f.func_type && 0 == ad->f.func_type)
+ ad->f.func_type = s->f.func_type;
+ if (s->a.packed)
+ ad->a.packed = 1;
+}
+
+/* Add type qualifiers to a type. If the type is an array then the qualifiers
+ are added to the element type, copied because it could be a typedef. */
+static void parse_btype_qualify(CType *type, int qualifiers)
+{
+ while (type->t & VT_ARRAY) {
+ type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
+ type = &type->ref->type;
+ }
+ type->t |= qualifiers;
+}
+
+/* return 0 if no type declaration. otherwise, return the basic type
+ and skip it.
+ */
+static int parse_btype(CType *type, AttributeDef *ad)
+{
+ int t, u, bt, st, type_found, typespec_found, g;
+ Sym *s;
+ CType type1;
+
+ memset(ad, 0, sizeof(AttributeDef));
+ type_found = 0;
+ typespec_found = 0;
+ t = VT_INT;
+ bt = st = -1;
+ type->ref = NULL;
+
+ while(1) {
+ switch(tok) {
+ case TOK_EXTENSION:
+ /* currently, we really ignore extension */
+ next();
+ continue;
+
+ /* basic types */
+ case TOK_CHAR:
+ u = VT_BYTE;
+ basic_type:
+ next();
+ basic_type1:
+ if (u == VT_SHORT || u == VT_LONG) {
+ if (st != -1 || (bt != -1 && bt != VT_INT))
+ tmbt: tcc_error("too many basic types");
+ st = u;
+ } else {
+ if (bt != -1 || (st != -1 && u != VT_INT))
+ goto tmbt;
+ bt = u;
+ }
+ if (u != VT_INT)
+ t = (t & ~(VT_BTYPE|VT_LONG)) | u;
+ typespec_found = 1;
+ break;
+ case TOK_VOID:
+ u = VT_VOID;
+ goto basic_type;
+ case TOK_SHORT:
+ u = VT_SHORT;
+ goto basic_type;
+ case TOK_INT:
+ u = VT_INT;
+ goto basic_type;
+ case TOK_LONG:
+ if ((t & VT_BTYPE) == VT_DOUBLE) {
+ t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
+ } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
+ t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
+ } else {
+ u = VT_LONG;
+ goto basic_type;
+ }
+ next();
+ break;
+#ifdef TCC_TARGET_ARM64
+ case TOK_UINT128:
+ /* GCC's __uint128_t appears in some Linux header files. Make it a
+ synonym for long double to get the size and alignment right. */
+ u = VT_LDOUBLE;
+ goto basic_type;
+#endif
+ case TOK_BOOL:
+ u = VT_BOOL;
+ goto basic_type;
+ case TOK_FLOAT:
+ u = VT_FLOAT;
+ goto basic_type;
+ case TOK_DOUBLE:
+ if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
+ t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
+ } else {
+ u = VT_DOUBLE;
+ goto basic_type;
+ }
+ next();
+ break;
+ case TOK_ENUM:
+ struct_decl(&type1, VT_ENUM);
+ basic_type2:
+ u = type1.t;
+ type->ref = type1.ref;
+ goto basic_type1;
+ case TOK_STRUCT:
+ struct_decl(&type1, VT_STRUCT);
+ goto basic_type2;
+ case TOK_UNION:
+ struct_decl(&type1, VT_UNION);
+ goto basic_type2;
+
+ /* type modifiers */
+ case TOK_CONST1:
+ case TOK_CONST2:
+ case TOK_CONST3:
+ type->t = t;
+ parse_btype_qualify(type, VT_CONSTANT);
+ t = type->t;
+ next();
+ break;
+ case TOK_VOLATILE1:
+ case TOK_VOLATILE2:
+ case TOK_VOLATILE3:
+ type->t = t;
+ parse_btype_qualify(type, VT_VOLATILE);
+ t = type->t;
+ next();
+ break;
+ case TOK_SIGNED1:
+ case TOK_SIGNED2:
+ case TOK_SIGNED3:
+ if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
+ tcc_error("signed and unsigned modifier");
+ t |= VT_DEFSIGN;
+ next();
+ typespec_found = 1;
+ break;
+ case TOK_REGISTER:
+ case TOK_AUTO:
+ case TOK_RESTRICT1:
+ case TOK_RESTRICT2:
+ case TOK_RESTRICT3:
+ next();
+ break;
+ case TOK_UNSIGNED:
+ if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
+ tcc_error("signed and unsigned modifier");
+ t |= VT_DEFSIGN | VT_UNSIGNED;
+ next();
+ typespec_found = 1;
+ break;
+
+ /* storage */
+ case TOK_EXTERN:
+ g = VT_EXTERN;
+ goto storage;
+ case TOK_STATIC:
+ g = VT_STATIC;
+ goto storage;
+ case TOK_TYPEDEF:
+ g = VT_TYPEDEF;
+ goto storage;
+ storage:
+ if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g)
+ tcc_error("multiple storage classes");
+ t |= g;
+ next();
+ break;
+ case TOK_INLINE1:
+ case TOK_INLINE2:
+ case TOK_INLINE3:
+ t |= VT_INLINE;
+ next();
+ break;
+
+ /* GNUC attribute */
+ case TOK_ATTRIBUTE1:
+ case TOK_ATTRIBUTE2:
+ parse_attribute(ad);
+ if (ad->attr_mode) {
+ u = ad->attr_mode -1;
+ t = (t & ~(VT_BTYPE|VT_LONG)) | u;
+ }
+ break;
+ /* GNUC typeof */
+ case TOK_TYPEOF1:
+ case TOK_TYPEOF2:
+ case TOK_TYPEOF3:
+ next();
+ parse_expr_type(&type1);
+ /* remove all storage modifiers except typedef */
+ type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
+ if (type1.ref)
+ sym_to_attr(ad, type1.ref);
+ goto basic_type2;
+ default:
+ if (typespec_found)
+ goto the_end;
+ s = sym_find(tok);
+ if (!s || !(s->type.t & VT_TYPEDEF))
+ goto the_end;
+ t &= ~(VT_BTYPE|VT_LONG);
+ u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
+ type->t = (s->type.t & ~VT_TYPEDEF) | u;
+ type->ref = s->type.ref;
+ if (t)
+ parse_btype_qualify(type, t);
+ t = type->t;
+ /* get attributes from typedef */
+ sym_to_attr(ad, s);
+ next();
+ typespec_found = 1;
+ st = bt = -2;
+ break;
+ }
+ type_found = 1;
+ }
+the_end:
+ if (tcc_state->char_is_unsigned) {
+ if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
+ t |= VT_UNSIGNED;
+ }
+ /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
+ bt = t & (VT_BTYPE|VT_LONG);
+ if (bt == VT_LONG)
+ t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
+#ifdef TCC_TARGET_PE
+ if (bt == VT_LDOUBLE)
+ t = (t & ~(VT_BTYPE|VT_LONG)) | VT_DOUBLE;
+#endif
+ type->t = t;
+ return type_found;
+}
+
+/* convert a function parameter type (array to pointer and function to
+ function pointer) */
+static inline void convert_parameter_type(CType *pt)
+{
+ /* remove const and volatile qualifiers (XXX: const could be used
+ to indicate a const function parameter */
+ pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
+ /* array must be transformed to pointer according to ANSI C */
+ pt->t &= ~VT_ARRAY;
+ if ((pt->t & VT_BTYPE) == VT_FUNC) {
+ mk_pointer(pt);
+ }
+}
+
+ST_FUNC void parse_asm_str(CString *astr)
+{
+ skip('(');
+ parse_mult_str(astr, "string constant");
+}
+
+/* Parse an asm label and return the token */
+static int asm_label_instr(void)
+{
+ int v;
+ CString astr;
+
+ next();
+ parse_asm_str(&astr);
+ skip(')');
+#ifdef ASM_DEBUG
+ printf("asm_alias: \"%s\"\n", (char *)astr.data);
+#endif
+ v = tok_alloc(astr.data, astr.size - 1)->tok;
+ cstr_free(&astr);
+ return v;
+}
+
+static int post_type(CType *type, AttributeDef *ad, int storage, int td)
+{
+ int n, l, t1, arg_size, align;
+ Sym **plast, *s, *first;
+ AttributeDef ad1;
+ CType pt;
+
+ if (tok == '(') {
+ /* function type, or recursive declarator (return if so) */
+ next();
+ if (td && !(td & TYPE_ABSTRACT))
+ return 0;
+ if (tok == ')')
+ l = 0;
+ else if (parse_btype(&pt, &ad1))
+ l = FUNC_NEW;
+ else if (td)
+ return 0;
+ else
+ l = FUNC_OLD;
+ first = NULL;
+ plast = &first;
+ arg_size = 0;
+ if (l) {
+ for(;;) {
+ /* read param name and compute offset */
+ if (l != FUNC_OLD) {
+ if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
+ break;
+ type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
+ if ((pt.t & VT_BTYPE) == VT_VOID)
+ tcc_error("parameter declared as void");
+ arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
+ } else {
+ n = tok;
+ if (n < TOK_UIDENT)
+ expect("identifier");
+ pt.t = VT_VOID; /* invalid type */
+ next();
+ }
+ convert_parameter_type(&pt);
+ s = sym_push(n | SYM_FIELD, &pt, 0, 0);
+ *plast = s;
+ plast = &s->next;
+ if (tok == ')')
+ break;
+ skip(',');
+ if (l == FUNC_NEW && tok == TOK_DOTS) {
+ l = FUNC_ELLIPSIS;
+ next();
+ break;
+ }
+ if (l == FUNC_NEW && !parse_btype(&pt, &ad1))
+ tcc_error("invalid type");
+ }
+ } else
+ /* if no parameters, then old type prototype */
+ l = FUNC_OLD;
+ skip(')');
+ /* NOTE: const is ignored in returned type as it has a special
+ meaning in gcc / C++ */
+ type->t &= ~VT_CONSTANT;
+ /* some ancient pre-K&R C allows a function to return an array
+ and the array brackets to be put after the arguments, such
+ that "int c()[]" means something like "int[] c()" */
+ if (tok == '[') {
+ next();
+ skip(']'); /* only handle simple "[]" */
+ mk_pointer(type);
+ }
+ /* we push a anonymous symbol which will contain the function prototype */
+ ad->f.func_args = arg_size;
+ ad->f.func_type = l;
+ s = sym_push(SYM_FIELD, type, 0, 0);
+ s->a = ad->a;
+ s->f = ad->f;
+ s->next = first;
+ type->t = VT_FUNC;
+ type->ref = s;
+ } else if (tok == '[') {
+ int saved_nocode_wanted = nocode_wanted;
+ /* array definition */
+ next();
+ if (tok == TOK_RESTRICT1)
+ next();
+ n = -1;
+ t1 = 0;
+ if (tok != ']') {
+ if (!local_stack || (storage & VT_STATIC))
+ vpushi(expr_const());
+ else {
+ /* VLAs (which can only happen with local_stack && !VT_STATIC)
+ length must always be evaluated, even under nocode_wanted,
+ so that its size slot is initialized (e.g. under sizeof
+ or typeof). */
+ nocode_wanted = 0;
+ gexpr();
+ }
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ n = vtop->c.i;
+ if (n < 0)
+ tcc_error("invalid array size");
+ } else {
+ if (!is_integer_btype(vtop->type.t & VT_BTYPE))
+ tcc_error("size of variable length array should be an integer");
+ t1 = VT_VLA;
+ }
+ }
+ skip(']');
+ /* parse next post type */
+ post_type(type, ad, storage, 0);
+ if (type->t == VT_FUNC)
+ tcc_error("declaration of an array of functions");
+ t1 |= type->t & VT_VLA;
+
+ if (t1 & VT_VLA) {
+ loc -= type_size(&int_type, &align);
+ loc &= -align;
+ n = loc;
+
+ vla_runtime_type_size(type, &align);
+ gen_op('*');
+ vset(&int_type, VT_LOCAL|VT_LVAL, n);
+ vswap();
+ vstore();
+ }
+ if (n != -1)
+ vpop();
+ nocode_wanted = saved_nocode_wanted;
+
+ /* we push an anonymous symbol which will contain the array
+ element type */
+ s = sym_push(SYM_FIELD, type, 0, n);
+ type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
+ type->ref = s;
+ }
+ return 1;
+}
+
+/* Parse a type declarator (except basic type), and return the type
+ in 'type'. 'td' is a bitmask indicating which kind of type decl is
+ expected. 'type' should contain the basic type. 'ad' is the
+ attribute definition of the basic type. It can be modified by
+ type_decl(). If this (possibly abstract) declarator is a pointer chain
+ it returns the innermost pointed to type (equals *type, but is a different
+ pointer), otherwise returns type itself, that's used for recursive calls. */
+static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
+{
+ CType *post, *ret;
+ int qualifiers, storage;
+
+ /* recursive type, remove storage bits first, apply them later again */
+ storage = type->t & VT_STORAGE;
+ type->t &= ~VT_STORAGE;
+ post = ret = type;
+
+ while (tok == '*') {
+ qualifiers = 0;
+ redo:
+ next();
+ switch(tok) {
+ case TOK_CONST1:
+ case TOK_CONST2:
+ case TOK_CONST3:
+ qualifiers |= VT_CONSTANT;
+ goto redo;
+ case TOK_VOLATILE1:
+ case TOK_VOLATILE2:
+ case TOK_VOLATILE3:
+ qualifiers |= VT_VOLATILE;
+ goto redo;
+ case TOK_RESTRICT1:
+ case TOK_RESTRICT2:
+ case TOK_RESTRICT3:
+ goto redo;
+ /* XXX: clarify attribute handling */
+ case TOK_ATTRIBUTE1:
+ case TOK_ATTRIBUTE2:
+ parse_attribute(ad);
+ break;
+ }
+ mk_pointer(type);
+ type->t |= qualifiers;
+ if (ret == type)
+ /* innermost pointed to type is the one for the first derivation */
+ ret = pointed_type(type);
+ }
+
+ if (tok == '(') {
+ /* This is possibly a parameter type list for abstract declarators
+ ('int ()'), use post_type for testing this. */
+ if (!post_type(type, ad, 0, td)) {
+ /* It's not, so it's a nested declarator, and the post operations
+ apply to the innermost pointed to type (if any). */
+ /* XXX: this is not correct to modify 'ad' at this point, but
+ the syntax is not clear */
+ parse_attribute(ad);
+ post = type_decl(type, ad, v, td);
+ skip(')');
+ }
+ } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
+ /* type identifier */
+ *v = tok;
+ next();
+ } else {
+ if (!(td & TYPE_ABSTRACT))
+ expect("identifier");
+ *v = 0;
+ }
+ post_type(post, ad, storage, 0);
+ parse_attribute(ad);
+ type->t |= storage;
+ return ret;
+}
+
+/* compute the lvalue VT_LVAL_xxx needed to match type t. */
+ST_FUNC int lvalue_type(int t)
+{
+ int bt, r;
+ r = VT_LVAL;
+ bt = t & VT_BTYPE;
+ if (bt == VT_BYTE || bt == VT_BOOL)
+ r |= VT_LVAL_BYTE;
+ else if (bt == VT_SHORT)
+ r |= VT_LVAL_SHORT;
+ else
+ return r;
+ if (t & VT_UNSIGNED)
+ r |= VT_LVAL_UNSIGNED;
+ return r;
+}
+
+/* indirection with full error checking and bound check */
+ST_FUNC void indir(void)
+{
+ if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
+ if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
+ return;
+ expect("pointer");
+ }
+ if (vtop->r & VT_LVAL)
+ gv(RC_INT);
+ vtop->type = *pointed_type(&vtop->type);
+ /* Arrays and functions are never lvalues */
+ if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
+ && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
+ vtop->r |= lvalue_type(vtop->type.t);
+ /* if bound checking, the referenced pointer must be checked */
+#ifdef CONFIG_TCC_BCHECK
+ if (tcc_state->do_bounds_check)
+ vtop->r |= VT_MUSTBOUND;
+#endif
+ }
+}
+
+/* pass a parameter to a function and do type checking and casting */
+static void gfunc_param_typed(Sym *func, Sym *arg)
+{
+ int func_type;
+ CType type;
+
+ func_type = func->f.func_type;
+ if (func_type == FUNC_OLD ||
+ (func_type == FUNC_ELLIPSIS && arg == NULL)) {
+ /* default casting : only need to convert float to double */
+ if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
+ gen_cast_s(VT_DOUBLE);
+ } else if (vtop->type.t & VT_BITFIELD) {
+ type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
+ type.ref = vtop->type.ref;
+ gen_cast(&type);
+ }
+ } else if (arg == NULL) {
+ tcc_error("too many arguments to function");
+ } else {
+ type = arg->type;
+ type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
+ gen_assign_cast(&type);
+ }
+}
+
+/* parse an expression and return its type without any side effect. */
+static void expr_type(CType *type, void (*expr_fn)(void))
+{
+ nocode_wanted++;
+ expr_fn();
+ *type = vtop->type;
+ vpop();
+ nocode_wanted--;
+}
+
+/* parse an expression of the form '(type)' or '(expr)' and return its
+ type */
+static void parse_expr_type(CType *type)
+{
+ int n;
+ AttributeDef ad;
+
+ skip('(');
+ if (parse_btype(type, &ad)) {
+ type_decl(type, &ad, &n, TYPE_ABSTRACT);
+ } else {
+ expr_type(type, gexpr);
+ }
+ skip(')');
+}
+
+static void parse_type(CType *type)
+{
+ AttributeDef ad;
+ int n;
+
+ if (!parse_btype(type, &ad)) {
+ expect("type");
+ }
+ type_decl(type, &ad, &n, TYPE_ABSTRACT);
+}
+
+static void parse_builtin_params(int nc, const char *args)
+{
+ char c, sep = '(';
+ CType t;
+ if (nc)
+ nocode_wanted++;
+ next();
+ while ((c = *args++)) {
+ skip(sep);
+ sep = ',';
+ switch (c) {
+ case 'e': expr_eq(); continue;
+ case 't': parse_type(&t); vpush(&t); continue;
+ default: tcc_error("internal error"); break;
+ }
+ }
+ skip(')');
+ if (nc)
+ nocode_wanted--;
+}
+
+ST_FUNC void unary(void)
+{
+ int n, t, align, size, r, sizeof_caller;
+ CType type;
+ Sym *s;
+ AttributeDef ad;
+
+ sizeof_caller = in_sizeof;
+ in_sizeof = 0;
+ type.ref = NULL;
+ /* XXX: GCC 2.95.3 does not generate a table although it should be
+ better here */
+ tok_next:
+ switch(tok) {
+ case TOK_EXTENSION:
+ next();
+ goto tok_next;
+ case TOK_LCHAR:
+#ifdef TCC_TARGET_PE
+ t = VT_SHORT|VT_UNSIGNED;
+ goto push_tokc;
+#endif
+ case TOK_CINT:
+ case TOK_CCHAR:
+ t = VT_INT;
+ push_tokc:
+ type.t = t;
+ vsetc(&type, VT_CONST, &tokc);
+ next();
+ break;
+ case TOK_CUINT:
+ t = VT_INT | VT_UNSIGNED;
+ goto push_tokc;
+ case TOK_CLLONG:
+ t = VT_LLONG;
+ goto push_tokc;
+ case TOK_CULLONG:
+ t = VT_LLONG | VT_UNSIGNED;
+ goto push_tokc;
+ case TOK_CFLOAT:
+ t = VT_FLOAT;
+ goto push_tokc;
+ case TOK_CDOUBLE:
+ t = VT_DOUBLE;
+ goto push_tokc;
+ case TOK_CLDOUBLE:
+ t = VT_LDOUBLE;
+ goto push_tokc;
+ case TOK_CLONG:
+ t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
+ goto push_tokc;
+ case TOK_CULONG:
+ t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
+ goto push_tokc;
+ case TOK___FUNCTION__:
+ if (!gnu_ext)
+ goto tok_identifier;
+ /* fall thru */
+ case TOK___FUNC__:
+ {
+ void *ptr;
+ int len;
+ /* special function name identifier */
+ len = strlen(funcname) + 1;
+ /* generate char[len] type */
+ type.t = VT_BYTE;
+ mk_pointer(&type);
+ type.t |= VT_ARRAY;
+ type.ref->c = len;
+ vpush_ref(&type, data_section, data_section->data_offset, len);
+ if (!NODATA_WANTED) {
+ ptr = section_ptr_add(data_section, len);
+ memcpy(ptr, funcname, len);
+ }
+ next();
+ }
+ break;
+ case TOK_LSTR:
+#ifdef TCC_TARGET_PE
+ t = VT_SHORT | VT_UNSIGNED;
+#else
+ t = VT_INT;
+#endif
+ goto str_init;
+ case TOK_STR:
+ /* string parsing */
+ t = VT_BYTE;
+ if (tcc_state->char_is_unsigned)
+ t = VT_BYTE | VT_UNSIGNED;
+ str_init:
+ if (tcc_state->warn_write_strings)
+ t |= VT_CONSTANT;
+ type.t = t;
+ mk_pointer(&type);
+ type.t |= VT_ARRAY;
+ memset(&ad, 0, sizeof(AttributeDef));
+ decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
+ break;
+ case '(':
+ next();
+ /* cast ? */
+ if (parse_btype(&type, &ad)) {
+ type_decl(&type, &ad, &n, TYPE_ABSTRACT);
+ skip(')');
+ /* check ISOC99 compound literal */
+ if (tok == '{') {
+ /* data is allocated locally by default */
+ if (global_expr)
+ r = VT_CONST;
+ else
+ r = VT_LOCAL;
+ /* all except arrays are lvalues */
+ if (!(type.t & VT_ARRAY))
+ r |= lvalue_type(type.t);
+ memset(&ad, 0, sizeof(AttributeDef));
+ decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
+ } else {
+ if (sizeof_caller) {
+ vpush(&type);
+ return;
+ }
+ unary();
+ gen_cast(&type);
+ }
+ } else if (tok == '{') {
+ int saved_nocode_wanted = nocode_wanted;
+ if (const_wanted)
+ tcc_error("expected constant");
+ /* save all registers */
+ save_regs(0);
+ /* statement expression : we do not accept break/continue
+ inside as GCC does. We do retain the nocode_wanted state,
+ as statement expressions can't ever be entered from the
+ outside, so any reactivation of code emission (from labels
+ or loop heads) can be disabled again after the end of it. */
+ block(NULL, NULL, 1);
+ nocode_wanted = saved_nocode_wanted;
+ skip(')');
+ } else {
+ gexpr();
+ skip(')');
+ }
+ break;
+ case '*':
+ next();
+ unary();
+ indir();
+ break;
+ case '&':
+ next();
+ unary();
+ /* functions names must be treated as function pointers,
+ except for unary '&' and sizeof. Since we consider that
+ functions are not lvalues, we only have to handle it
+ there and in function calls. */
+ /* arrays can also be used although they are not lvalues */
+ if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
+ !(vtop->type.t & VT_ARRAY))
+ test_lvalue();
+ mk_pointer(&vtop->type);
+ gaddrof();
+ break;
+ case '!':
+ next();
+ unary();
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ gen_cast_s(VT_BOOL);
+ vtop->c.i = !vtop->c.i;
+ } else if ((vtop->r & VT_VALMASK) == VT_CMP)
+ vtop->c.i ^= 1;
+ else {
+ save_regs(1);
+ vseti(VT_JMP, gvtst(1, 0));
+ }
+ break;
+ case '~':
+ next();
+ unary();
+ vpushi(-1);
+ gen_op('^');
+ break;
+ case '+':
+ next();
+ unary();
+ if ((vtop->type.t & VT_BTYPE) == VT_PTR)
+ tcc_error("pointer not accepted for unary plus");
+ /* In order to force cast, we add zero, except for floating point
+ where we really need an noop (otherwise -0.0 will be transformed
+ into +0.0). */
+ if (!is_float(vtop->type.t)) {
+ vpushi(0);
+ gen_op('+');
+ }
+ break;
+ case TOK_SIZEOF:
+ case TOK_ALIGNOF1:
+ case TOK_ALIGNOF2:
+ t = tok;
+ next();
+ in_sizeof++;
+ expr_type(&type, unary); /* Perform a in_sizeof = 0; */
+ s = vtop[1].sym; /* hack: accessing previous vtop */
+ size = type_size(&type, &align);
+ if (s && s->a.aligned)
+ align = 1 << (s->a.aligned - 1);
+ if (t == TOK_SIZEOF) {
+ if (!(type.t & VT_VLA)) {
+ if (size < 0)
+ tcc_error("sizeof applied to an incomplete type");
+ vpushs(size);
+ } else {
+ vla_runtime_type_size(&type, &align);
+ }
+ } else {
+ vpushs(align);
+ }
+ vtop->type.t |= VT_UNSIGNED;
+ break;
+
+ case TOK_builtin_expect:
+ /* __builtin_expect is a no-op for now */
+ parse_builtin_params(0, "ee");
+ vpop();
+ break;
+ case TOK_builtin_types_compatible_p:
+ parse_builtin_params(0, "tt");
+ vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
+ vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
+ n = is_compatible_types(&vtop[-1].type, &vtop[0].type);
+ vtop -= 2;
+ vpushi(n);
+ break;
+ case TOK_builtin_choose_expr:
+ {
+ int64_t c;
+ next();
+ skip('(');
+ c = expr_const64();
+ skip(',');
+ if (!c) {
+ nocode_wanted++;
+ }
+ expr_eq();
+ if (!c) {
+ vpop();
+ nocode_wanted--;
+ }
+ skip(',');
+ if (c) {
+ nocode_wanted++;
+ }
+ expr_eq();
+ if (c) {
+ vpop();
+ nocode_wanted--;
+ }
+ skip(')');
+ }
+ break;
+ case TOK_builtin_constant_p:
+ parse_builtin_params(1, "e");
+ n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+ vtop--;
+ vpushi(n);
+ break;
+ case TOK_builtin_frame_address:
+ case TOK_builtin_return_address:
+ {
+ int tok1 = tok;
+ int level;
+ next();
+ skip('(');
+ if (tok != TOK_CINT) {
+ tcc_error("%s only takes positive integers",
+ tok1 == TOK_builtin_return_address ?
+ "__builtin_return_address" :
+ "__builtin_frame_address");
+ }
+ level = (uint32_t)tokc.i;
+ next();
+ skip(')');
+ type.t = VT_VOID;
+ mk_pointer(&type);
+ vset(&type, VT_LOCAL, 0); /* local frame */
+ while (level--) {
+ mk_pointer(&vtop->type);
+ indir(); /* -> parent frame */
+ }
+ if (tok1 == TOK_builtin_return_address) {
+ // assume return address is just above frame pointer on stack
+ vpushi(PTR_SIZE);
+ gen_op('+');
+ mk_pointer(&vtop->type);
+ indir();
+ }
+ }
+ break;
+#ifdef TCC_TARGET_X86_64
+#ifdef TCC_TARGET_PE
+ case TOK_builtin_va_start:
+ parse_builtin_params(0, "ee");
+ r = vtop->r & VT_VALMASK;
+ if (r == VT_LLOCAL)
+ r = VT_LOCAL;
+ if (r != VT_LOCAL)
+ tcc_error("__builtin_va_start expects a local variable");
+ vtop->r = r;
+ vtop->type = char_pointer_type;
+ vtop->c.i += 8;
+ vstore();
+ break;
+#else
+ case TOK_builtin_va_arg_types:
+ parse_builtin_params(0, "t");
+ vpushi(classify_x86_64_va_arg(&vtop->type));
+ vswap();
+ vpop();
+ break;
+#endif
+#endif
+
+#ifdef TCC_TARGET_ARM64
+ case TOK___va_start: {
+ parse_builtin_params(0, "ee");
+ //xx check types
+ gen_va_start();
+ vpushi(0);
+ vtop->type.t = VT_VOID;
+ break;
+ }
+ case TOK___va_arg: {
+ parse_builtin_params(0, "et");
+ type = vtop->type;
+ vpop();
+ //xx check types
+ gen_va_arg(&type);
+ vtop->type = type;
+ break;
+ }
+ case TOK___arm64_clear_cache: {
+ parse_builtin_params(0, "ee");
+ gen_clear_cache();
+ vpushi(0);
+ vtop->type.t = VT_VOID;
+ break;
+ }
+#endif
+ /* pre operations */
+ case TOK_INC:
+ case TOK_DEC:
+ t = tok;
+ next();
+ unary();
+ inc(0, t);
+ break;
+ case '-':
+ next();
+ unary();
+ t = vtop->type.t & VT_BTYPE;
+ if (is_float(t)) {
+ /* In IEEE negate(x) isn't subtract(0,x), but rather
+ subtract(-0, x). */
+ vpush(&vtop->type);
+ if (t == VT_FLOAT)
+ vtop->c.f = -1.0 * 0.0;
+ else if (t == VT_DOUBLE)
+ vtop->c.d = -1.0 * 0.0;
+ else
+ vtop->c.ld = -1.0 * 0.0;
+ } else
+ vpushi(0);
+ vswap();
+ gen_op('-');
+ break;
+ case TOK_LAND:
+ if (!gnu_ext)
+ goto tok_identifier;
+ next();
+ /* allow to take the address of a label */
+ if (tok < TOK_UIDENT)
+ expect("label identifier");
+ s = label_find(tok);
+ if (!s) {
+ s = label_push(&global_label_stack, tok, LABEL_FORWARD);
+ } else {
+ if (s->r == LABEL_DECLARED)
+ s->r = LABEL_FORWARD;
+ }
+ if (!s->type.t) {
+ s->type.t = VT_VOID;
+ mk_pointer(&s->type);
+ s->type.t |= VT_STATIC;
+ }
+ vpushsym(&s->type, s);
+ next();
+ break;
+
+ case TOK_GENERIC:
+ {
+ CType controlling_type;
+ int has_default = 0;
+ int has_match = 0;
+ int learn = 0;
+ TokenString *str = NULL;
+
+ next();
+ skip('(');
+ expr_type(&controlling_type, expr_eq);
+ controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
+ for (;;) {
+ learn = 0;
+ skip(',');
+ if (tok == TOK_DEFAULT) {
+ if (has_default)
+ tcc_error("too many 'default'");
+ has_default = 1;
+ if (!has_match)
+ learn = 1;
+ next();
+ } else {
+ AttributeDef ad_tmp;
+ int itmp;
+ CType cur_type;
+ parse_btype(&cur_type, &ad_tmp);
+ type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
+ if (compare_types(&controlling_type, &cur_type, 0)) {
+ if (has_match) {
+ tcc_error("type match twice");
+ }
+ has_match = 1;
+ learn = 1;
+ }
+ }
+ skip(':');
+ if (learn) {
+ if (str)
+ tok_str_free(str);
+ skip_or_save_block(&str);
+ } else {
+ skip_or_save_block(NULL);
+ }
+ if (tok == ')')
+ break;
+ }
+ if (!str) {
+ char buf[60];
+ type_to_str(buf, sizeof buf, &controlling_type, NULL);
+ tcc_error("type '%s' does not match any association", buf);
+ }
+ begin_macro(str, 1);
+ next();
+ expr_eq();
+ if (tok != TOK_EOF)
+ expect(",");
+ end_macro();
+ next();
+ break;
+ }
+ // special qnan , snan and infinity values
+ case TOK___NAN__:
+ vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
+ next();
+ break;
+ case TOK___SNAN__:
+ vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
+ next();
+ break;
+ case TOK___INF__:
+ vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
+ next();
+ break;
+
+ default:
+ tok_identifier:
+ t = tok;
+ next();
+ if (t < TOK_UIDENT)
+ expect("identifier");
+ s = sym_find(t);
+ if (!s || IS_ASM_SYM(s)) {
+ const char *name = get_tok_str(t, NULL);
+ if (tok != '(')
+ tcc_error("'%s' undeclared", name);
+ /* for simple function calls, we tolerate undeclared
+ external reference to int() function */
+ if (tcc_state->warn_implicit_function_declaration
+#ifdef TCC_TARGET_PE
+ /* people must be warned about using undeclared WINAPI functions
+ (which usually start with uppercase letter) */
+ || (name[0] >= 'A' && name[0] <= 'Z')
+#endif
+ )
+ tcc_warning("implicit declaration of function '%s'", name);
+ s = external_global_sym(t, &func_old_type, 0);
+ }
+
+ r = s->r;
+ /* A symbol that has a register is a local register variable,
+ which starts out as VT_LOCAL value. */
+ if ((r & VT_VALMASK) < VT_CONST)
+ r = (r & ~VT_VALMASK) | VT_LOCAL;
+
+ vset(&s->type, r, s->c);
+ /* Point to s as backpointer (even without r&VT_SYM).
+ Will be used by at least the x86 inline asm parser for
+ regvars. */
+ vtop->sym = s;
+
+ if (r & VT_SYM) {
+ vtop->c.i = 0;
+ } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) {
+ vtop->c.i = s->enum_val;
+ }
+ break;
+ }
+
+ /* post operations */
+ while (1) {
+ if (tok == TOK_INC || tok == TOK_DEC) {
+ inc(1, tok);
+ next();
+ } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
+ int qualifiers;
+ /* field */
+ if (tok == TOK_ARROW)
+ indir();
+ qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
+ test_lvalue();
+ gaddrof();
+ /* expect pointer on structure */
+ if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
+ expect("struct or union");
+ if (tok == TOK_CDOUBLE)
+ expect("field name");
+ next();
+ if (tok == TOK_CINT || tok == TOK_CUINT)
+ expect("field name");
+ s = find_field(&vtop->type, tok);
+ if (!s)
+ tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
+ /* add field offset to pointer */
+ vtop->type = char_pointer_type; /* change type to 'char *' */
+ vpushi(s->c);
+ gen_op('+');
+ /* change type to field type, and set to lvalue */
+ vtop->type = s->type;
+ vtop->type.t |= qualifiers;
+ /* an array is never an lvalue */
+ if (!(vtop->type.t & VT_ARRAY)) {
+ vtop->r |= lvalue_type(vtop->type.t);
+#ifdef CONFIG_TCC_BCHECK
+ /* if bound checking, the referenced pointer must be checked */
+ if (tcc_state->do_bounds_check && (vtop->r & VT_VALMASK) != VT_LOCAL)
+ vtop->r |= VT_MUSTBOUND;
+#endif
+ }
+ next();
+ } else if (tok == '[') {
+ next();
+ gexpr();
+ gen_op('+');
+ indir();
+ skip(']');
+ } else if (tok == '(') {
+ SValue ret;
+ Sym *sa;
+ int nb_args, ret_nregs, ret_align, regsize, variadic;
+
+ /* function call */
+ if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
+ /* pointer test (no array accepted) */
+ if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
+ vtop->type = *pointed_type(&vtop->type);
+ if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
+ goto error_func;
+ } else {
+ error_func:
+ expect("function pointer");
+ }
+ } else {
+ vtop->r &= ~VT_LVAL; /* no lvalue */
+ }
+ /* get return type */
+ s = vtop->type.ref;
+ next();
+ sa = s->next; /* first parameter */
+ nb_args = regsize = 0;
+ ret.r2 = VT_CONST;
+ /* compute first implicit argument if a structure is returned */
+ if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
+ variadic = (s->f.func_type == FUNC_ELLIPSIS);
+ ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
+ &ret_align, &regsize);
+ if (!ret_nregs) {
+ /* get some space for the returned structure */
+ size = type_size(&s->type, &align);
+#ifdef TCC_TARGET_ARM64
+ /* On arm64, a small struct is return in registers.
+ It is much easier to write it to memory if we know
+ that we are allowed to write some extra bytes, so
+ round the allocated space up to a power of 2: */
+ if (size < 16)
+ while (size & (size - 1))
+ size = (size | (size - 1)) + 1;
+#endif
+ loc = (loc - size) & -align;
+ ret.type = s->type;
+ ret.r = VT_LOCAL | VT_LVAL;
+ /* pass it as 'int' to avoid structure arg passing
+ problems */
+ vseti(VT_LOCAL, loc);
+ ret.c = vtop->c;
+ nb_args++;
+ }
+ } else {
+ ret_nregs = 1;
+ ret.type = s->type;
+ }
+
+ if (ret_nregs) {
+ /* return in register */
+ if (is_float(ret.type.t)) {
+ ret.r = reg_fret(ret.type.t);
+#ifdef TCC_TARGET_X86_64
+ if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
+ ret.r2 = REG_QRET;
+#endif
+ } else {
+#ifndef TCC_TARGET_ARM64
+#ifdef TCC_TARGET_X86_64
+ if ((ret.type.t & VT_BTYPE) == VT_QLONG)
+#else
+ if ((ret.type.t & VT_BTYPE) == VT_LLONG)
+#endif
+ ret.r2 = REG_LRET;
+#endif
+ ret.r = REG_IRET;
+ }
+ ret.c.i = 0;
+ }
+ if (tok != ')') {
+ for(;;) {
+ expr_eq();
+ gfunc_param_typed(s, sa);
+ nb_args++;
+ if (sa)
+ sa = sa->next;
+ if (tok == ')')
+ break;
+ skip(',');
+ }
+ }
+ if (sa)
+ tcc_error("too few arguments to function");
+ skip(')');
+ gfunc_call(nb_args);
+
+ /* return value */
+ for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
+ vsetc(&ret.type, r, &ret.c);
+ vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
+ }
+
+ /* handle packed struct return */
+ if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
+ int addr, offset;
+
+ size = type_size(&s->type, &align);
+ /* We're writing whole regs often, make sure there's enough
+ space. Assume register size is power of 2. */
+ if (regsize > align)
+ align = regsize;
+ loc = (loc - size) & -align;
+ addr = loc;
+ offset = 0;
+ for (;;) {
+ vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
+ vswap();
+ vstore();
+ vtop--;
+ if (--ret_nregs == 0)
+ break;
+ offset += regsize;
+ }
+ vset(&s->type, VT_LOCAL | VT_LVAL, addr);
+ }
+ } else {
+ break;
+ }
+ }
+}
+
+ST_FUNC void expr_prod(void)
+{
+ int t;
+
+ unary();
+ while (tok == '*' || tok == '/' || tok == '%') {
+ t = tok;
+ next();
+ unary();
+ gen_op(t);
+ }
+}
+
+ST_FUNC void expr_sum(void)
+{
+ int t;
+
+ expr_prod();
+ while (tok == '+' || tok == '-') {
+ t = tok;
+ next();
+ expr_prod();
+ gen_op(t);
+ }
+}
+
+static void expr_shift(void)
+{
+ int t;
+
+ expr_sum();
+ while (tok == TOK_SHL || tok == TOK_SAR) {
+ t = tok;
+ next();
+ expr_sum();
+ gen_op(t);
+ }
+}
+
+static void expr_cmp(void)
+{
+ int t;
+
+ expr_shift();
+ while ((tok >= TOK_ULE && tok <= TOK_GT) ||
+ tok == TOK_ULT || tok == TOK_UGE) {
+ t = tok;
+ next();
+ expr_shift();
+ gen_op(t);
+ }
+}
+
+static void expr_cmpeq(void)
+{
+ int t;
+
+ expr_cmp();
+ while (tok == TOK_EQ || tok == TOK_NE) {
+ t = tok;
+ next();
+ expr_cmp();
+ gen_op(t);
+ }
+}
+
+static void expr_and(void)
+{
+ expr_cmpeq();
+ while (tok == '&') {
+ next();
+ expr_cmpeq();
+ gen_op('&');
+ }
+}
+
+static void expr_xor(void)
+{
+ expr_and();
+ while (tok == '^') {
+ next();
+ expr_and();
+ gen_op('^');
+ }
+}
+
+static void expr_or(void)
+{
+ expr_xor();
+ while (tok == '|') {
+ next();
+ expr_xor();
+ gen_op('|');
+ }
+}
+
+static void expr_land(void)
+{
+ expr_or();
+ if (tok == TOK_LAND) {
+ int t = 0;
+ for(;;) {
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ gen_cast_s(VT_BOOL);
+ if (vtop->c.i) {
+ vpop();
+ } else {
+ nocode_wanted++;
+ while (tok == TOK_LAND) {
+ next();
+ expr_or();
+ vpop();
+ }
+ nocode_wanted--;
+ if (t)
+ gsym(t);
+ gen_cast_s(VT_INT);
+ break;
+ }
+ } else {
+ if (!t)
+ save_regs(1);
+ t = gvtst(1, t);
+ }
+ if (tok != TOK_LAND) {
+ if (t)
+ vseti(VT_JMPI, t);
+ else
+ vpushi(1);
+ break;
+ }
+ next();
+ expr_or();
+ }
+ }
+}
+
+static void expr_lor(void)
+{
+ expr_land();
+ if (tok == TOK_LOR) {
+ int t = 0;
+ for(;;) {
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ gen_cast_s(VT_BOOL);
+ if (!vtop->c.i) {
+ vpop();
+ } else {
+ nocode_wanted++;
+ while (tok == TOK_LOR) {
+ next();
+ expr_land();
+ vpop();
+ }
+ nocode_wanted--;
+ if (t)
+ gsym(t);
+ gen_cast_s(VT_INT);
+ break;
+ }
+ } else {
+ if (!t)
+ save_regs(1);
+ t = gvtst(0, t);
+ }
+ if (tok != TOK_LOR) {
+ if (t)
+ vseti(VT_JMP, t);
+ else
+ vpushi(0);
+ break;
+ }
+ next();
+ expr_land();
+ }
+ }
+}
+
+/* Assuming vtop is a value used in a conditional context
+ (i.e. compared with zero) return 0 if it's false, 1 if
+ true and -1 if it can't be statically determined. */
+static int condition_3way(void)
+{
+ int c = -1;
+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
+ (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
+ vdup();
+ gen_cast_s(VT_BOOL);
+ c = vtop->c.i;
+ vpop();
+ }
+ return c;
+}
+
+static void expr_cond(void)
+{
+ int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g;
+ SValue sv;
+ CType type, type1, type2;
+
+ expr_lor();
+ if (tok == '?') {
+ next();
+ c = condition_3way();
+ g = (tok == ':' && gnu_ext);
+ if (c < 0) {
+ /* needed to avoid having different registers saved in
+ each branch */
+ if (is_float(vtop->type.t)) {
+ rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+ if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+ rc = RC_ST0;
+ }
+#endif
+ } else
+ rc = RC_INT;
+ gv(rc);
+ save_regs(1);
+ if (g)
+ gv_dup();
+ tt = gvtst(1, 0);
+
+ } else {
+ if (!g)
+ vpop();
+ tt = 0;
+ }
+
+ if (1) {
+ if (c == 0)
+ nocode_wanted++;
+ if (!g)
+ gexpr();
+
+ type1 = vtop->type;
+ sv = *vtop; /* save value to handle it later */
+ vtop--; /* no vpop so that FP stack is not flushed */
+ skip(':');
+
+ u = 0;
+ if (c < 0)
+ u = gjmp(0);
+ gsym(tt);
+
+ if (c == 0)
+ nocode_wanted--;
+ if (c == 1)
+ nocode_wanted++;
+ expr_cond();
+ if (c == 1)
+ nocode_wanted--;
+
+ type2 = vtop->type;
+ t1 = type1.t;
+ bt1 = t1 & VT_BTYPE;
+ t2 = type2.t;
+ bt2 = t2 & VT_BTYPE;
+ type.ref = NULL;
+
+ /* cast operands to correct type according to ISOC rules */
+ if (is_float(bt1) || is_float(bt2)) {
+ if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
+ type.t = VT_LDOUBLE;
+
+ } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
+ type.t = VT_DOUBLE;
+ } else {
+ type.t = VT_FLOAT;
+ }
+ } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
+ /* cast to biggest op */
+ type.t = VT_LLONG | VT_LONG;
+ if (bt1 == VT_LLONG)
+ type.t &= t1;
+ if (bt2 == VT_LLONG)
+ type.t &= t2;
+ /* convert to unsigned if it does not fit in a long long */
+ if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
+ (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
+ type.t |= VT_UNSIGNED;
+ } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
+ /* If one is a null ptr constant the result type
+ is the other. */
+ if (is_null_pointer (vtop))
+ type = type1;
+ else if (is_null_pointer (&sv))
+ type = type2;
+ /* XXX: test pointer compatibility, C99 has more elaborate
+ rules here. */
+ else
+ type = type1;
+ } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
+ /* XXX: test function pointer compatibility */
+ type = bt1 == VT_FUNC ? type1 : type2;
+ } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
+ /* XXX: test structure compatibility */
+ type = bt1 == VT_STRUCT ? type1 : type2;
+ } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
+ /* NOTE: as an extension, we accept void on only one side */
+ type.t = VT_VOID;
+ } else {
+ /* integer operations */
+ type.t = VT_INT | (VT_LONG & (t1 | t2));
+ /* convert to unsigned if it does not fit in an integer */
+ if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
+ (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
+ type.t |= VT_UNSIGNED;
+ }
+ /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
+ that `(expr ? a : b).mem` does not error with "lvalue expected" */
+ islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
+ islv &= c < 0;
+
+ /* now we convert second operand */
+ if (c != 1) {
+ gen_cast(&type);
+ if (islv) {
+ mk_pointer(&vtop->type);
+ gaddrof();
+ } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
+ gaddrof();
+ }
+
+ rc = RC_INT;
+ if (is_float(type.t)) {
+ rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+ if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
+ rc = RC_ST0;
+ }
+#endif
+ } else if ((type.t & VT_BTYPE) == VT_LLONG) {
+ /* for long longs, we use fixed registers to avoid having
+ to handle a complicated move */
+ rc = RC_IRET;
+ }
+
+ tt = r2 = 0;
+ if (c < 0) {
+ r2 = gv(rc);
+ tt = gjmp(0);
+ }
+ gsym(u);
+
+ /* this is horrible, but we must also convert first
+ operand */
+ if (c != 0) {
+ *vtop = sv;
+ gen_cast(&type);
+ if (islv) {
+ mk_pointer(&vtop->type);
+ gaddrof();
+ } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
+ gaddrof();
+ }
+
+ if (c < 0) {
+ r1 = gv(rc);
+ move_reg(r2, r1, type.t);
+ vtop->r = r2;
+ gsym(tt);
+ if (islv)
+ indir();
+ }
+ }
+ }
+}
+
+static void expr_eq(void)
+{
+ int t;
+
+ expr_cond();
+ if (tok == '=' ||
+ (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
+ tok == TOK_A_XOR || tok == TOK_A_OR ||
+ tok == TOK_A_SHL || tok == TOK_A_SAR) {
+ test_lvalue();
+ t = tok;
+ next();
+ if (t == '=') {
+ expr_eq();
+ } else {
+ vdup();
+ expr_eq();
+ gen_op(t & 0x7f);
+ }
+ vstore();
+ }
+}
+
+ST_FUNC void gexpr(void)
+{
+ while (1) {
+ expr_eq();
+ if (tok != ',')
+ break;
+ vpop();
+ next();
+ }
+}
+
+/* parse a constant expression and return value in vtop. */
+static void expr_const1(void)
+{
+ const_wanted++;
+ nocode_wanted++;
+ expr_cond();
+ nocode_wanted--;
+ const_wanted--;
+}
+
+/* parse an integer constant and return its value. */
+static inline int64_t expr_const64(void)
+{
+ int64_t c;
+ expr_const1();
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+ expect("constant expression");
+ c = vtop->c.i;
+ vpop();
+ return c;
+}
+
+/* parse an integer constant and return its value.
+ Complain if it doesn't fit 32bit (signed or unsigned). */
+ST_FUNC int expr_const(void)
+{
+ int c;
+ int64_t wc = expr_const64();
+ c = wc;
+ if (c != wc && (unsigned)c != wc)
+ tcc_error("constant exceeds 32 bit");
+ return c;
+}
+
+/* return the label token if current token is a label, otherwise
+ return zero */
+static int is_label(void)
+{
+ int last_tok;
+
+ /* fast test first */
+ if (tok < TOK_UIDENT)
+ return 0;
+ /* no need to save tokc because tok is an identifier */
+ last_tok = tok;
+ next();
+ if (tok == ':') {
+ return last_tok;
+ } else {
+ unget_tok(last_tok);
+ return 0;
+ }
+}
+
+#ifndef TCC_TARGET_ARM64
+static void gfunc_return(CType *func_type)
+{
+ if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
+ CType type, ret_type;
+ int ret_align, ret_nregs, regsize;
+ ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
+ &ret_align, &regsize);
+ if (0 == ret_nregs) {
+ /* if returning structure, must copy it to implicit
+ first pointer arg location */
+ type = *func_type;
+ mk_pointer(&type);
+ vset(&type, VT_LOCAL | VT_LVAL, func_vc);
+ indir();
+ vswap();
+ /* copy structure value to pointer */
+ vstore();
+ } else {
+ /* returning structure packed into registers */
+ int r, size, addr, align;
+ size = type_size(func_type,&align);
+ if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
+ (vtop->c.i & (ret_align-1)))
+ && (align & (ret_align-1))) {
+ loc = (loc - size) & -ret_align;
+ addr = loc;
+ type = *func_type;
+ vset(&type, VT_LOCAL | VT_LVAL, addr);
+ vswap();
+ vstore();
+ vpop();
+ vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
+ }
+ vtop->type = ret_type;
+ if (is_float(ret_type.t))
+ r = rc_fret(ret_type.t);
+ else
+ r = RC_IRET;
+
+ if (ret_nregs == 1)
+ gv(r);
+ else {
+ for (;;) {
+ vdup();
+ gv(r);
+ vpop();
+ if (--ret_nregs == 0)
+ break;
+ /* We assume that when a structure is returned in multiple
+ registers, their classes are consecutive values of the
+ suite s(n) = 2^n */
+ r <<= 1;
+ vtop->c.i += regsize;
+ }
+ }
+ }
+ } else if (is_float(func_type->t)) {
+ gv(rc_fret(func_type->t));
+ } else {
+ gv(RC_IRET);
+ }
+ vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
+}
+#endif
+
+static int case_cmp(const void *pa, const void *pb)
+{
+ int64_t a = (*(struct case_t**) pa)->v1;
+ int64_t b = (*(struct case_t**) pb)->v1;
+ return a < b ? -1 : a > b;
+}
+
+static void gcase(struct case_t **base, int len, int *bsym)
+{
+ struct case_t *p;
+ int e;
+ int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
+ gv(RC_INT);
+ while (len > 4) {
+ /* binary search */
+ p = base[len/2];
+ vdup();
+ if (ll)
+ vpushll(p->v2);
+ else
+ vpushi(p->v2);
+ gen_op(TOK_LE);
+ e = gtst(1, 0);
+ vdup();
+ if (ll)
+ vpushll(p->v1);
+ else
+ vpushi(p->v1);
+ gen_op(TOK_GE);
+ gtst_addr(0, p->sym); /* v1 <= x <= v2 */
+ /* x < v1 */
+ gcase(base, len/2, bsym);
+ if (cur_switch->def_sym)
+ gjmp_addr(cur_switch->def_sym);
+ else
+ *bsym = gjmp(*bsym);
+ /* x > v2 */
+ gsym(e);
+ e = len/2 + 1;
+ base += e; len -= e;
+ }
+ /* linear scan */
+ while (len--) {
+ p = *base++;
+ vdup();
+ if (ll)
+ vpushll(p->v2);
+ else
+ vpushi(p->v2);
+ if (p->v1 == p->v2) {
+ gen_op(TOK_EQ);
+ gtst_addr(0, p->sym);
+ } else {
+ gen_op(TOK_LE);
+ e = gtst(1, 0);
+ vdup();
+ if (ll)
+ vpushll(p->v1);
+ else
+ vpushi(p->v1);
+ gen_op(TOK_GE);
+ gtst_addr(0, p->sym);
+ gsym(e);
+ }
+ }
+}
+
+static void block(int *bsym, int *csym, int is_expr)
+{
+ int a, b, c, d, cond;
+ Sym *s;
+
+ /* generate line number info */
+ if (tcc_state->do_debug)
+ tcc_debug_line(tcc_state);
+
+ if (is_expr) {
+ /* default return value is (void) */
+ vpushi(0);
+ vtop->type.t = VT_VOID;
+ }
+
+ if (tok == TOK_IF) {
+ /* if test */
+ int saved_nocode_wanted = nocode_wanted;
+ next();
+ skip('(');
+ gexpr();
+ skip(')');
+ cond = condition_3way();
+ if (cond == 1)
+ a = 0, vpop();
+ else
+ a = gvtst(1, 0);
+ if (cond == 0)
+ nocode_wanted |= 0x20000000;
+ block(bsym, csym, 0);
+ if (cond != 1)
+ nocode_wanted = saved_nocode_wanted;
+ c = tok;
+ if (c == TOK_ELSE) {
+ next();
+ d = gjmp(0);
+ gsym(a);
+ if (cond == 1)
+ nocode_wanted |= 0x20000000;
+ block(bsym, csym, 0);
+ gsym(d); /* patch else jmp */
+ if (cond != 0)
+ nocode_wanted = saved_nocode_wanted;
+ } else
+ gsym(a);
+ } else if (tok == TOK_WHILE) {
+ int saved_nocode_wanted;
+ nocode_wanted &= ~0x20000000;
+ next();
+ d = ind;
+ vla_sp_restore();
+ skip('(');
+ gexpr();
+ skip(')');
+ a = gvtst(1, 0);
+ b = 0;
+ ++local_scope;
+ saved_nocode_wanted = nocode_wanted;
+ block(&a, &b, 0);
+ nocode_wanted = saved_nocode_wanted;
+ --local_scope;
+ gjmp_addr(d);
+ gsym(a);
+ gsym_addr(b, d);
+ } else if (tok == '{') {
+ Sym *llabel;
+ int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
+
+ next();
+ /* record local declaration stack position */
+ s = local_stack;
+ llabel = local_label_stack;
+ ++local_scope;
+
+ /* handle local labels declarations */
+ if (tok == TOK_LABEL) {
+ next();
+ for(;;) {
+ if (tok < TOK_UIDENT)
+ expect("label identifier");
+ label_push(&local_label_stack, tok, LABEL_DECLARED);
+ next();
+ if (tok == ',') {
+ next();
+ } else {
+ skip(';');
+ break;
+ }
+ }
+ }
+ while (tok != '}') {
+ if ((a = is_label()))
+ unget_tok(a);
+ else
+ decl(VT_LOCAL);
+ if (tok != '}') {
+ if (is_expr)
+ vpop();
+ block(bsym, csym, is_expr);
+ }
+ }
+ /* pop locally defined labels */
+ label_pop(&local_label_stack, llabel, is_expr);
+ /* pop locally defined symbols */
+ --local_scope;
+ /* In the is_expr case (a statement expression is finished here),
+ vtop might refer to symbols on the local_stack. Either via the
+ type or via vtop->sym. We can't pop those nor any that in turn
+ might be referred to. To make it easier we don't roll back
+ any symbols in that case; some upper level call to block() will
+ do that. We do have to remove such symbols from the lookup
+ tables, though. sym_pop will do that. */
+ sym_pop(&local_stack, s, is_expr);
+
+ /* Pop VLA frames and restore stack pointer if required */
+ if (vlas_in_scope > saved_vlas_in_scope) {
+ vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
+ vla_sp_restore();
+ }
+ vlas_in_scope = saved_vlas_in_scope;
+
+ next();
+ } else if (tok == TOK_RETURN) {
+ next();
+ if (tok != ';') {
+ gexpr();
+ gen_assign_cast(&func_vt);
+ if ((func_vt.t & VT_BTYPE) == VT_VOID)
+ vtop--;
+ else
+ gfunc_return(&func_vt);
+ }
+ skip(';');
+ /* jump unless last stmt in top-level block */
+ if (tok != '}' || local_scope != 1)
+ rsym = gjmp(rsym);
+ nocode_wanted |= 0x20000000;
+ } else if (tok == TOK_BREAK) {
+ /* compute jump */
+ if (!bsym)
+ tcc_error("cannot break");
+ *bsym = gjmp(*bsym);
+ next();
+ skip(';');
+ nocode_wanted |= 0x20000000;
+ } else if (tok == TOK_CONTINUE) {
+ /* compute jump */
+ if (!csym)
+ tcc_error("cannot continue");
+ vla_sp_restore_root();
+ *csym = gjmp(*csym);
+ next();
+ skip(';');
+ } else if (tok == TOK_FOR) {
+ int e;
+ int saved_nocode_wanted;
+ nocode_wanted &= ~0x20000000;
+ next();
+ skip('(');
+ s = local_stack;
+ ++local_scope;
+ if (tok != ';') {
+ /* c99 for-loop init decl? */
+ if (!decl0(VT_LOCAL, 1, NULL)) {
+ /* no, regular for-loop init expr */
+ gexpr();
+ vpop();
+ }
+ }
+ skip(';');
+ d = ind;
+ c = ind;
+ vla_sp_restore();
+ a = 0;
+ b = 0;
+ if (tok != ';') {
+ gexpr();
+ a = gvtst(1, 0);
+ }
+ skip(';');
+ if (tok != ')') {
+ e = gjmp(0);
+ c = ind;
+ vla_sp_restore();
+ gexpr();
+ vpop();
+ gjmp_addr(d);
+ gsym(e);
+ }
+ skip(')');
+ saved_nocode_wanted = nocode_wanted;
+ block(&a, &b, 0);
+ nocode_wanted = saved_nocode_wanted;
+ gjmp_addr(c);
+ gsym(a);
+ gsym_addr(b, c);
+ --local_scope;
+ sym_pop(&local_stack, s, 0);
+
+ } else
+ if (tok == TOK_DO) {
+ int saved_nocode_wanted;
+ nocode_wanted &= ~0x20000000;
+ next();
+ a = 0;
+ b = 0;
+ d = ind;
+ vla_sp_restore();
+ saved_nocode_wanted = nocode_wanted;
+ block(&a, &b, 0);
+ skip(TOK_WHILE);
+ skip('(');
+ gsym(b);
+ gexpr();
+ c = gvtst(0, 0);
+ gsym_addr(c, d);
+ nocode_wanted = saved_nocode_wanted;
+ skip(')');
+ gsym(a);
+ skip(';');
+ } else
+ if (tok == TOK_SWITCH) {
+ struct switch_t *saved, sw;
+ int saved_nocode_wanted = nocode_wanted;
+ SValue switchval;
+ next();
+ skip('(');
+ gexpr();
+ skip(')');
+ switchval = *vtop--;
+ a = 0;
+ b = gjmp(0); /* jump to first case */
+ sw.p = NULL; sw.n = 0; sw.def_sym = 0;
+ saved = cur_switch;
+ cur_switch = &sw;
+ block(&a, csym, 0);
+ nocode_wanted = saved_nocode_wanted;
+ a = gjmp(a); /* add implicit break */
+ /* case lookup */
+ gsym(b);
+ qsort(sw.p, sw.n, sizeof(void*), case_cmp);
+ for (b = 1; b < sw.n; b++)
+ if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
+ tcc_error("duplicate case value");
+ /* Our switch table sorting is signed, so the compared
+ value needs to be as well when it's 64bit. */
+ if ((switchval.type.t & VT_BTYPE) == VT_LLONG)
+ switchval.type.t &= ~VT_UNSIGNED;
+ vpushv(&switchval);
+ gcase(sw.p, sw.n, &a);
+ vpop();
+ if (sw.def_sym)
+ gjmp_addr(sw.def_sym);
+ dynarray_reset(&sw.p, &sw.n);
+ cur_switch = saved;
+ /* break label */
+ gsym(a);
+ } else
+ if (tok == TOK_CASE) {
+ struct case_t *cr = tcc_malloc(sizeof(struct case_t));
+ if (!cur_switch)
+ expect("switch");
+ nocode_wanted &= ~0x20000000;
+ next();
+ cr->v1 = cr->v2 = expr_const64();
+ if (gnu_ext && tok == TOK_DOTS) {
+ next();
+ cr->v2 = expr_const64();
+ if (cr->v2 < cr->v1)
+ tcc_warning("empty case range");
+ }
+ cr->sym = ind;
+ dynarray_add(&cur_switch->p, &cur_switch->n, cr);
+ skip(':');
+ is_expr = 0;
+ goto block_after_label;
+ } else
+ if (tok == TOK_DEFAULT) {
+ next();
+ skip(':');
+ if (!cur_switch)
+ expect("switch");
+ if (cur_switch->def_sym)
+ tcc_error("too many 'default'");
+ cur_switch->def_sym = ind;
+ is_expr = 0;
+ goto block_after_label;
+ } else
+ if (tok == TOK_GOTO) {
+ next();
+ if (tok == '*' && gnu_ext) {
+ /* computed goto */
+ next();
+ gexpr();
+ if ((vtop->type.t & VT_BTYPE) != VT_PTR)
+ expect("pointer");
+ ggoto();
+ } else if (tok >= TOK_UIDENT) {
+ s = label_find(tok);
+ /* put forward definition if needed */
+ if (!s) {
+ s = label_push(&global_label_stack, tok, LABEL_FORWARD);
+ } else {
+ if (s->r == LABEL_DECLARED)
+ s->r = LABEL_FORWARD;
+ }
+ vla_sp_restore_root();
+ if (s->r & LABEL_FORWARD)
+ s->jnext = gjmp(s->jnext);
+ else
+ gjmp_addr(s->jnext);
+ next();
+ } else {
+ expect("label identifier");
+ }
+ skip(';');
+ } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
+ asm_instr();
+ } else {
+ b = is_label();
+ if (b) {
+ /* label case */
+ next();
+ s = label_find(b);
+ if (s) {
+ if (s->r == LABEL_DEFINED)
+ tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
+ gsym(s->jnext);
+ s->r = LABEL_DEFINED;
+ } else {
+ s = label_push(&global_label_stack, b, LABEL_DEFINED);
+ }
+ s->jnext = ind;
+ vla_sp_restore();
+ /* we accept this, but it is a mistake */
+ block_after_label:
+ nocode_wanted &= ~0x20000000;
+ if (tok == '}') {
+ tcc_warning("deprecated use of label at end of compound statement");
+ } else {
+ if (is_expr)
+ vpop();
+ block(bsym, csym, is_expr);
+ }
+ } else {
+ /* expression case */
+ if (tok != ';') {
+ if (is_expr) {
+ vpop();
+ gexpr();
+ } else {
+ gexpr();
+ vpop();
+ }
+ }
+ skip(';');
+ }
+ }
+}
+
+/* This skips over a stream of tokens containing balanced {} and ()
+ pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
+ with a '{'). If STR then allocates and stores the skipped tokens
+ in *STR. This doesn't check if () and {} are nested correctly,
+ i.e. "({)}" is accepted. */
+static void skip_or_save_block(TokenString **str)
+{
+ int braces = tok == '{';
+ int level = 0;
+ if (str)
+ *str = tok_str_alloc();
+
+ while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) {
+ int t;
+ if (tok == TOK_EOF) {
+ if (str || level > 0)
+ tcc_error("unexpected end of file");
+ else
+ break;
+ }
+ if (str)
+ tok_str_add_tok(*str);
+ t = tok;
+ next();
+ if (t == '{' || t == '(') {
+ level++;
+ } else if (t == '}' || t == ')') {
+ level--;
+ if (level == 0 && braces && t == '}')
+ break;
+ }
+ }
+ if (str) {
+ tok_str_add(*str, -1);
+ tok_str_add(*str, 0);
+ }
+}
+
+#define EXPR_CONST 1
+#define EXPR_ANY 2
+
+static void parse_init_elem(int expr_type)
+{
+ int saved_global_expr;
+ switch(expr_type) {
+ case EXPR_CONST:
+ /* compound literals must be allocated globally in this case */
+ saved_global_expr = global_expr;
+ global_expr = 1;
+ expr_const1();
+ global_expr = saved_global_expr;
+ /* NOTE: symbols are accepted, as well as lvalue for anon symbols
+ (compound literals). */
+ if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST
+ && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL)
+ || vtop->sym->v < SYM_FIRST_ANOM))
+#ifdef TCC_TARGET_PE
+ || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport)
+#endif
+ )
+ tcc_error("initializer element is not constant");
+ break;
+ case EXPR_ANY:
+ expr_eq();
+ break;
+ }
+}
+
+/* put zeros for variable based init */
+static void init_putz(Section *sec, unsigned long c, int size)
+{
+ if (sec) {
+ /* nothing to do because globals are already set to zero */
+ } else {
+ vpush_global_sym(&func_old_type, TOK_memset);
+ vseti(VT_LOCAL, c);
+#ifdef TCC_TARGET_ARM
+ vpushs(size);
+ vpushi(0);
+#else
+ vpushi(0);
+ vpushs(size);
+#endif
+ gfunc_call(3);
+ }
+}
+
+/* t is the array or struct type. c is the array or struct
+ address. cur_field is the pointer to the current
+ field, for arrays the 'c' member contains the current start
+ index. 'size_only' is true if only size info is needed (only used
+ in arrays). al contains the already initialized length of the
+ current container (starting at c). This returns the new length of that. */
+static int decl_designator(CType *type, Section *sec, unsigned long c,
+ Sym **cur_field, int size_only, int al)
+{
+ Sym *s, *f;
+ int index, index_last, align, l, nb_elems, elem_size;
+ unsigned long corig = c;
+
+ elem_size = 0;
+ nb_elems = 1;
+ if (gnu_ext && (l = is_label()) != 0)
+ goto struct_field;
+ /* NOTE: we only support ranges for last designator */
+ while (nb_elems == 1 && (tok == '[' || tok == '.')) {
+ if (tok == '[') {
+ if (!(type->t & VT_ARRAY))
+ expect("array type");
+ next();
+ index = index_last = expr_const();
+ if (tok == TOK_DOTS && gnu_ext) {
+ next();
+ index_last = expr_const();
+ }
+ skip(']');
+ s = type->ref;
+ if (index < 0 || (s->c >= 0 && index_last >= s->c) ||
+ index_last < index)
+ tcc_error("invalid index");
+ if (cur_field)
+ (*cur_field)->c = index_last;
+ type = pointed_type(type);
+ elem_size = type_size(type, &align);
+ c += index * elem_size;
+ nb_elems = index_last - index + 1;
+ } else {
+ next();
+ l = tok;
+ struct_field:
+ next();
+ if ((type->t & VT_BTYPE) != VT_STRUCT)
+ expect("struct/union type");
+ f = find_field(type, l);
+ if (!f)
+ expect("field");
+ if (cur_field)
+ *cur_field = f;
+ type = &f->type;
+ c += f->c;
+ }
+ cur_field = NULL;
+ }
+ if (!cur_field) {
+ if (tok == '=') {
+ next();
+ } else if (!gnu_ext) {
+ expect("=");
+ }
+ } else {
+ if (type->t & VT_ARRAY) {
+ index = (*cur_field)->c;
+ if (type->ref->c >= 0 && index >= type->ref->c)
+ tcc_error("index too large");
+ type = pointed_type(type);
+ c += index * type_size(type, &align);
+ } else {
+ f = *cur_field;
+ while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD))
+ *cur_field = f = f->next;
+ if (!f)
+ tcc_error("too many field init");
+ type = &f->type;
+ c += f->c;
+ }
+ }
+ /* must put zero in holes (note that doing it that way
+ ensures that it even works with designators) */
+ if (!size_only && c - corig > al)
+ init_putz(sec, corig + al, c - corig - al);
+ decl_initializer(type, sec, c, 0, size_only);
+
+ /* XXX: make it more general */
+ if (!size_only && nb_elems > 1) {
+ unsigned long c_end;
+ uint8_t *src, *dst;
+ int i;
+
+ if (!sec) {
+ vset(type, VT_LOCAL|VT_LVAL, c);
+ for (i = 1; i < nb_elems; i++) {
+ vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
+ vswap();
+ vstore();
+ }
+ vpop();
+ } else if (!NODATA_WANTED) {
+ c_end = c + nb_elems * elem_size;
+ if (c_end > sec->data_allocated)
+ section_realloc(sec, c_end);
+ src = sec->data + c;
+ dst = src;
+ for(i = 1; i < nb_elems; i++) {
+ dst += elem_size;
+ memcpy(dst, src, elem_size);
+ }
+ }
+ }
+ c += nb_elems * type_size(type, &align);
+ if (c - corig > al)
+ al = c - corig;
+ return al;
+}
+
+/* store a value or an expression directly in global data or in local array */
+static void init_putv(CType *type, Section *sec, unsigned long c)
+{
+ int bt;
+ void *ptr;
+ CType dtype;
+
+ dtype = *type;
+ dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
+
+ if (sec) {
+ int size, align;
+ /* XXX: not portable */
+ /* XXX: generate error if incorrect relocation */
+ gen_assign_cast(&dtype);
+ bt = type->t & VT_BTYPE;
+
+ if ((vtop->r & VT_SYM)
+ && bt != VT_PTR
+ && bt != VT_FUNC
+ && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
+ || (type->t & VT_BITFIELD))
+ && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
+ )
+ tcc_error("initializer element is not computable at load time");
+
+ if (NODATA_WANTED) {
+ vtop--;
+ return;
+ }
+
+ size = type_size(type, &align);
+ section_reserve(sec, c + size);
+ ptr = sec->data + c;
+
+ /* XXX: make code faster ? */
+ if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
+ vtop->sym->v >= SYM_FIRST_ANOM &&
+ /* XXX This rejects compound literals like
+ '(void *){ptr}'. The problem is that '&sym' is
+ represented the same way, which would be ruled out
+ by the SYM_FIRST_ANOM check above, but also '"string"'
+ in 'char *p = "string"' is represented the same
+ with the type being VT_PTR and the symbol being an
+ anonymous one. That is, there's no difference in vtop
+ between '(void *){x}' and '&(void *){x}'. Ignore
+ pointer typed entities here. Hopefully no real code
+ will every use compound literals with scalar type. */
+ (vtop->type.t & VT_BTYPE) != VT_PTR) {
+ /* These come from compound literals, memcpy stuff over. */
+ Section *ssec;
+ ElfSym *esym;
+ ElfW_Rel *rel;
+ esym = elfsym(vtop->sym);
+ ssec = tcc_state->sections[esym->st_shndx];
+ memmove (ptr, ssec->data + esym->st_value, size);
+ if (ssec->reloc) {
+ /* We need to copy over all memory contents, and that
+ includes relocations. Use the fact that relocs are
+ created it order, so look from the end of relocs
+ until we hit one before the copied region. */
+ int num_relocs = ssec->reloc->data_offset / sizeof(*rel);
+ rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset);
+ while (num_relocs--) {
+ rel--;
+ if (rel->r_offset >= esym->st_value + size)
+ continue;
+ if (rel->r_offset < esym->st_value)
+ break;
+ /* Note: if the same fields are initialized multiple
+ times (possible with designators) then we possibly
+ add multiple relocations for the same offset here.
+ That would lead to wrong code, the last reloc needs
+ to win. We clean this up later after the whole
+ initializer is parsed. */
+ put_elf_reloca(symtab_section, sec,
+ c + rel->r_offset - esym->st_value,
+ ELFW(R_TYPE)(rel->r_info),
+ ELFW(R_SYM)(rel->r_info),
+#if PTR_SIZE == 8
+ rel->r_addend
+#else
+ 0
+#endif
+ );
+ }
+ }
+ } else {
+ if (type->t & VT_BITFIELD) {
+ int bit_pos, bit_size, bits, n;
+ unsigned char *p, v, m;
+ bit_pos = BIT_POS(vtop->type.t);
+ bit_size = BIT_SIZE(vtop->type.t);
+ p = (unsigned char*)ptr + (bit_pos >> 3);
+ bit_pos &= 7, bits = 0;
+ while (bit_size) {
+ n = 8 - bit_pos;
+ if (n > bit_size)
+ n = bit_size;
+ v = vtop->c.i >> bits << bit_pos;
+ m = ((1 << n) - 1) << bit_pos;
+ *p = (*p & ~m) | (v & m);
+ bits += n, bit_size -= n, bit_pos = 0, ++p;
+ }
+ } else
+ switch(bt) {
+ /* XXX: when cross-compiling we assume that each type has the
+ same representation on host and target, which is likely to
+ be wrong in the case of long double */
+ case VT_BOOL:
+ vtop->c.i = vtop->c.i != 0;
+ case VT_BYTE:
+ *(char *)ptr |= vtop->c.i;
+ break;
+ case VT_SHORT:
+ *(short *)ptr |= vtop->c.i;
+ break;
+ case VT_FLOAT:
+ *(float*)ptr = vtop->c.f;
+ break;
+ case VT_DOUBLE:
+ *(double *)ptr = vtop->c.d;
+ break;
+ case VT_LDOUBLE:
+#if defined TCC_IS_NATIVE_387
+ if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
+ memcpy(ptr, &vtop->c.ld, 10);
+#ifdef __TINYC__
+ else if (sizeof (long double) == sizeof (double))
+ __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
+#endif
+ else if (vtop->c.ld == 0.0)
+ ;
+ else
+#endif
+ if (sizeof(long double) == LDOUBLE_SIZE)
+ *(long double*)ptr = vtop->c.ld;
+ else if (sizeof(double) == LDOUBLE_SIZE)
+ *(double *)ptr = (double)vtop->c.ld;
+ else
+ tcc_error("can't cross compile long double constants");
+ break;
+#if PTR_SIZE != 8
+ case VT_LLONG:
+ *(long long *)ptr |= vtop->c.i;
+ break;
+#else
+ case VT_LLONG:
+#endif
+ case VT_PTR:
+ {
+ addr_t val = vtop->c.i;
+#if PTR_SIZE == 8
+ if (vtop->r & VT_SYM)
+ greloca(sec, vtop->sym, c, R_DATA_PTR, val);
+ else
+ *(addr_t *)ptr |= val;
+#else
+ if (vtop->r & VT_SYM)
+ greloc(sec, vtop->sym, c, R_DATA_PTR);
+ *(addr_t *)ptr |= val;
+#endif
+ break;
+ }
+ default:
+ {
+ int val = vtop->c.i;
+#if PTR_SIZE == 8
+ if (vtop->r & VT_SYM)
+ greloca(sec, vtop->sym, c, R_DATA_PTR, val);
+ else
+ *(int *)ptr |= val;
+#else
+ if (vtop->r & VT_SYM)
+ greloc(sec, vtop->sym, c, R_DATA_PTR);
+ *(int *)ptr |= val;
+#endif
+ break;
+ }
+ }
+ }
+ vtop--;
+ } else {
+ vset(&dtype, VT_LOCAL|VT_LVAL, c);
+ vswap();
+ vstore();
+ vpop();
+ }
+}
+
+/* 't' contains the type and storage info. 'c' is the offset of the
+ object in section 'sec'. If 'sec' is NULL, it means stack based
+ allocation. 'first' is true if array '{' must be read (multi
+ dimension implicit array init handling). 'size_only' is true if
+ size only evaluation is wanted (only for arrays). */
+static void decl_initializer(CType *type, Section *sec, unsigned long c,
+ int first, int size_only)
+{
+ int len, n, no_oblock, nb, i;
+ int size1, align1;
+ int have_elem;
+ Sym *s, *f;
+ Sym indexsym;
+ CType *t1;
+
+ /* If we currently are at an '}' or ',' we have read an initializer
+ element in one of our callers, and not yet consumed it. */
+ have_elem = tok == '}' || tok == ',';
+ if (!have_elem && tok != '{' &&
+ /* In case of strings we have special handling for arrays, so
+ don't consume them as initializer value (which would commit them
+ to some anonymous symbol). */
+ tok != TOK_LSTR && tok != TOK_STR &&
+ !size_only) {
+ parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
+ have_elem = 1;
+ }
+
+ if (have_elem &&
+ !(type->t & VT_ARRAY) &&
+ /* Use i_c_parameter_t, to strip toplevel qualifiers.
+ The source type might have VT_CONSTANT set, which is
+ of course assignable to non-const elements. */
+ is_compatible_unqualified_types(type, &vtop->type)) {
+ init_putv(type, sec, c);
+ } else if (type->t & VT_ARRAY) {
+ s = type->ref;
+ n = s->c;
+ t1 = pointed_type(type);
+ size1 = type_size(t1, &align1);
+
+ no_oblock = 1;
+ if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
+ tok == '{') {
+ if (tok != '{')
+ tcc_error("character array initializer must be a literal,"
+ " optionally enclosed in braces");
+ skip('{');
+ no_oblock = 0;
+ }
+
+ /* only parse strings here if correct type (otherwise: handle
+ them as ((w)char *) expressions */
+ if ((tok == TOK_LSTR &&
+#ifdef TCC_TARGET_PE
+ (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
+#else
+ (t1->t & VT_BTYPE) == VT_INT
+#endif
+ ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
+ len = 0;
+ while (tok == TOK_STR || tok == TOK_LSTR) {
+ int cstr_len, ch;
+
+ /* compute maximum number of chars wanted */
+ if (tok == TOK_STR)
+ cstr_len = tokc.str.size;
+ else
+ cstr_len = tokc.str.size / sizeof(nwchar_t);
+ cstr_len--;
+ nb = cstr_len;
+ if (n >= 0 && nb > (n - len))
+ nb = n - len;
+ if (!size_only) {
+ if (cstr_len > nb)
+ tcc_warning("initializer-string for array is too long");
+ /* in order to go faster for common case (char
+ string in global variable, we handle it
+ specifically */
+ if (sec && tok == TOK_STR && size1 == 1) {
+ if (!NODATA_WANTED)
+ memcpy(sec->data + c + len, tokc.str.data, nb);
+ } else {
+ for(i=0;i<nb;i++) {
+ if (tok == TOK_STR)
+ ch = ((unsigned char *)tokc.str.data)[i];
+ else
+ ch = ((nwchar_t *)tokc.str.data)[i];
+ vpushi(ch);
+ init_putv(t1, sec, c + (len + i) * size1);
+ }
+ }
+ }
+ len += nb;
+ next();
+ }
+ /* only add trailing zero if enough storage (no
+ warning in this case since it is standard) */
+ if (n < 0 || len < n) {
+ if (!size_only) {
+ vpushi(0);
+ init_putv(t1, sec, c + (len * size1));
+ }
+ len++;
+ }
+ len *= size1;
+ } else {
+ indexsym.c = 0;
+ f = &indexsym;
+
+ do_init_list:
+ len = 0;
+ while (tok != '}' || have_elem) {
+ len = decl_designator(type, sec, c, &f, size_only, len);
+ have_elem = 0;
+ if (type->t & VT_ARRAY) {
+ ++indexsym.c;
+ /* special test for multi dimensional arrays (may not
+ be strictly correct if designators are used at the
+ same time) */
+ if (no_oblock && len >= n*size1)
+ break;
+ } else {
+ if (s->type.t == VT_UNION)
+ f = NULL;
+ else
+ f = f->next;
+ if (no_oblock && f == NULL)
+ break;
+ }
+
+ if (tok == '}')
+ break;
+ skip(',');
+ }
+ }
+ /* put zeros at the end */
+ if (!size_only && len < n*size1)
+ init_putz(sec, c + len, n*size1 - len);
+ if (!no_oblock)
+ skip('}');
+ /* patch type size if needed, which happens only for array types */
+ if (n < 0)
+ s->c = size1 == 1 ? len : ((len + size1 - 1)/size1);
+ } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
+ size1 = 1;
+ no_oblock = 1;
+ if (first || tok == '{') {
+ skip('{');
+ no_oblock = 0;
+ }
+ s = type->ref;
+ f = s->next;
+ n = s->c;
+ goto do_init_list;
+ } else if (tok == '{') {
+ next();
+ decl_initializer(type, sec, c, first, size_only);
+ skip('}');
+ } else if (size_only) {
+ /* If we supported only ISO C we wouldn't have to accept calling
+ this on anything than an array size_only==1 (and even then
+ only on the outermost level, so no recursion would be needed),
+ because initializing a flex array member isn't supported.
+ But GNU C supports it, so we need to recurse even into
+ subfields of structs and arrays when size_only is set. */
+ /* just skip expression */
+ skip_or_save_block(NULL);
+ } else {
+ if (!have_elem) {
+ /* This should happen only when we haven't parsed
+ the init element above for fear of committing a
+ string constant to memory too early. */
+ if (tok != TOK_STR && tok != TOK_LSTR)
+ expect("string constant");
+ parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
+ }
+ init_putv(type, sec, c);
+ }
+}
+
+/* parse an initializer for type 't' if 'has_init' is non zero, and
+ allocate space in local or global data space ('r' is either
+ VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
+ variable 'v' of scope 'scope' is declared before initializers
+ are parsed. If 'v' is zero, then a reference to the new object
+ is put in the value stack. If 'has_init' is 2, a special parsing
+ is done to handle string constants. */
+static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
+ int has_init, int v, int scope)
+{
+ int size, align, addr;
+ TokenString *init_str = NULL;
+
+ Section *sec;
+ Sym *flexible_array;
+ Sym *sym = NULL;
+ int saved_nocode_wanted = nocode_wanted;
+#ifdef CONFIG_TCC_BCHECK
+ int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
+#endif
+
+ if (type->t & VT_STATIC)
+ nocode_wanted |= NODATA_WANTED ? 0x40000000 : 0x80000000;
+
+ flexible_array = NULL;
+ if ((type->t & VT_BTYPE) == VT_STRUCT) {
+ Sym *field = type->ref->next;
+ if (field) {
+ while (field->next)
+ field = field->next;
+ if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
+ flexible_array = field;
+ }
+ }
+
+ size = type_size(type, &align);
+ /* If unknown size, we must evaluate it before
+ evaluating initializers because
+ initializers can generate global data too
+ (e.g. string pointers or ISOC99 compound
+ literals). It also simplifies local
+ initializers handling */
+ if (size < 0 || (flexible_array && has_init)) {
+ if (!has_init)
+ tcc_error("unknown type size");
+ /* get all init string */
+ if (has_init == 2) {
+ init_str = tok_str_alloc();
+ /* only get strings */
+ while (tok == TOK_STR || tok == TOK_LSTR) {
+ tok_str_add_tok(init_str);
+ next();
+ }
+ tok_str_add(init_str, -1);
+ tok_str_add(init_str, 0);
+ } else {
+ skip_or_save_block(&init_str);
+ }
+ unget_tok(0);
+
+ /* compute size */
+ begin_macro(init_str, 1);
+ next();
+ decl_initializer(type, NULL, 0, 1, 1);
+ /* prepare second initializer parsing */
+ macro_ptr = init_str->str;
+ next();
+
+ /* if still unknown size, error */
+ size = type_size(type, &align);
+ if (size < 0)
+ tcc_error("unknown type size");
+ }
+ /* If there's a flex member and it was used in the initializer
+ adjust size. */
+ if (flexible_array &&
+ flexible_array->type.ref->c > 0)
+ size += flexible_array->type.ref->c
+ * pointed_size(&flexible_array->type);
+ /* take into account specified alignment if bigger */
+ if (ad->a.aligned) {
+ int speca = 1 << (ad->a.aligned - 1);
+ if (speca > align)
+ align = speca;
+ } else if (ad->a.packed) {
+ align = 1;
+ }
+
+ if (NODATA_WANTED)
+ size = 0, align = 1;
+
+ if ((r & VT_VALMASK) == VT_LOCAL) {
+ sec = NULL;
+#ifdef CONFIG_TCC_BCHECK
+ if (bcheck && (type->t & VT_ARRAY)) {
+ loc--;
+ }
+#endif
+ loc = (loc - size) & -align;
+ addr = loc;
+#ifdef CONFIG_TCC_BCHECK
+ /* handles bounds */
+ /* XXX: currently, since we do only one pass, we cannot track
+ '&' operators, so we add only arrays */
+ if (bcheck && (type->t & VT_ARRAY)) {
+ addr_t *bounds_ptr;
+ /* add padding between regions */
+ loc--;
+ /* then add local bound info */
+ bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
+ bounds_ptr[0] = addr;
+ bounds_ptr[1] = size;
+ }
+#endif
+ if (v) {
+ /* local variable */
+#ifdef CONFIG_TCC_ASM
+ if (ad->asm_label) {
+ int reg = asm_parse_regvar(ad->asm_label);
+ if (reg >= 0)
+ r = (r & ~VT_VALMASK) | reg;
+ }
+#endif
+ sym = sym_push(v, type, r, addr);
+ sym->a = ad->a;
+ } else {
+ /* push local reference */
+ vset(type, r, addr);
+ }
+ } else {
+ if (v && scope == VT_CONST) {
+ /* see if the symbol was already defined */
+ sym = sym_find(v);
+ if (sym) {
+ patch_storage(sym, ad, type);
+ /* we accept several definitions of the same global variable. */
+ if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)
+ goto no_alloc;
+ }
+ }
+
+ /* allocate symbol in corresponding section */
+ sec = ad->section;
+ if (!sec) {
+ if (has_init)
+ sec = data_section;
+ else if (tcc_state->nocommon)
+ sec = bss_section;
+ }
+
+ if (sec) {
+ addr = section_add(sec, size, align);
+#ifdef CONFIG_TCC_BCHECK
+ /* add padding if bound check */
+ if (bcheck)
+ section_add(sec, 1, 1);
+#endif
+ } else {
+ addr = align; /* SHN_COMMON is special, symbol value is align */
+ sec = common_section;
+ }
+
+ if (v) {
+ if (!sym) {
+ sym = sym_push(v, type, r | VT_SYM, 0);
+ patch_storage(sym, ad, NULL);
+ }
+ /* Local statics have a scope until now (for
+ warnings), remove it here. */
+ sym->sym_scope = 0;
+ /* update symbol definition */
+ put_extern_sym(sym, sec, addr, size);
+ } else {
+ /* push global reference */
+ sym = get_sym_ref(type, sec, addr, size);
+ vpushsym(type, sym);
+ vtop->r |= r;
+ }
+
+#ifdef CONFIG_TCC_BCHECK
+ /* handles bounds now because the symbol must be defined
+ before for the relocation */
+ if (bcheck) {
+ addr_t *bounds_ptr;
+
+ greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
+ /* then add global bound info */
+ bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
+ bounds_ptr[0] = 0; /* relocated */
+ bounds_ptr[1] = size;
+ }
+#endif
+ }
+
+ if (type->t & VT_VLA) {
+ int a;
+
+ if (NODATA_WANTED)
+ goto no_alloc;
+
+ /* save current stack pointer */
+ if (vlas_in_scope == 0) {
+ if (vla_sp_root_loc == -1)
+ vla_sp_root_loc = (loc -= PTR_SIZE);
+ gen_vla_sp_save(vla_sp_root_loc);
+ }
+
+ vla_runtime_type_size(type, &a);
+ gen_vla_alloc(type, a);
+#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
+ /* on _WIN64, because of the function args scratch area, the
+ result of alloca differs from RSP and is returned in RAX. */
+ gen_vla_result(addr), addr = (loc -= PTR_SIZE);
+#endif
+ gen_vla_sp_save(addr);
+ vla_sp_loc = addr;
+ vlas_in_scope++;
+
+ } else if (has_init) {
+ size_t oldreloc_offset = 0;
+ if (sec && sec->reloc)
+ oldreloc_offset = sec->reloc->data_offset;
+ decl_initializer(type, sec, addr, 1, 0);
+ if (sec && sec->reloc)
+ squeeze_multi_relocs(sec, oldreloc_offset);
+ /* patch flexible array member size back to -1, */
+ /* for possible subsequent similar declarations */
+ if (flexible_array)
+ flexible_array->type.ref->c = -1;
+ }
+
+ no_alloc:
+ /* restore parse state if needed */
+ if (init_str) {
+ end_macro();
+ next();
+ }
+
+ nocode_wanted = saved_nocode_wanted;
+}
+
+/* parse a function defined by symbol 'sym' and generate its code in
+ 'cur_text_section' */
+static void gen_function(Sym *sym)
+{
+ nocode_wanted = 0;
+ ind = cur_text_section->data_offset;
+ /* NOTE: we patch the symbol size later */
+ put_extern_sym(sym, cur_text_section, ind, 0);
+ funcname = get_tok_str(sym->v, NULL);
+ func_ind = ind;
+ /* Initialize VLA state */
+ vla_sp_loc = -1;
+ vla_sp_root_loc = -1;
+ /* put debug symbol */
+ tcc_debug_funcstart(tcc_state, sym);
+ /* push a dummy symbol to enable local sym storage */
+ sym_push2(&local_stack, SYM_FIELD, 0, 0);
+ local_scope = 1; /* for function parameters */
+ gfunc_prolog(&sym->type);
+ local_scope = 0;
+ rsym = 0;
+ block(NULL, NULL, 0);
+ nocode_wanted = 0;
+ gsym(rsym);
+ gfunc_epilog();
+ cur_text_section->data_offset = ind;
+ label_pop(&global_label_stack, NULL, 0);
+ /* reset local stack */
+ local_scope = 0;
+ sym_pop(&local_stack, NULL, 0);
+ /* end of function */
+ /* patch symbol size */
+ elfsym(sym)->st_size = ind - func_ind;
+ tcc_debug_funcend(tcc_state, ind - func_ind);
+ /* It's better to crash than to generate wrong code */
+ cur_text_section = NULL;
+ funcname = ""; /* for safety */
+ func_vt.t = VT_VOID; /* for safety */
+ func_var = 0; /* for safety */
+ ind = 0; /* for safety */
+ nocode_wanted = 0x80000000;
+ check_vstack();
+}
+
+static void gen_inline_functions(TCCState *s)
+{
+ Sym *sym;
+ int inline_generated, i, ln;
+ struct InlineFunc *fn;
+
+ ln = file->line_num;
+ /* iterate while inline function are referenced */
+ do {
+ inline_generated = 0;
+ for (i = 0; i < s->nb_inline_fns; ++i) {
+ fn = s->inline_fns[i];
+ sym = fn->sym;
+ if (sym && sym->c) {
+ /* the function was used: generate its code and
+ convert it to a normal function */
+ fn->sym = NULL;
+ if (file)
+ pstrcpy(file->filename, sizeof file->filename, fn->filename);
+ sym->type.t &= ~VT_INLINE;
+
+ begin_macro(fn->func_str, 1);
+ next();
+ cur_text_section = text_section;
+ gen_function(sym);
+ end_macro();
+
+ inline_generated = 1;
+ }
+ }
+ } while (inline_generated);
+ file->line_num = ln;
+}
+
+ST_FUNC void free_inline_functions(TCCState *s)
+{
+ int i;
+ /* free tokens of unused inline functions */
+ for (i = 0; i < s->nb_inline_fns; ++i) {
+ struct InlineFunc *fn = s->inline_fns[i];
+ if (fn->sym)
+ tok_str_free(fn->func_str);
+ }
+ dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
+}
+
+/* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
+ if parsing old style parameter decl list (and FUNC_SYM is set then) */
+static int decl0(int l, int is_for_loop_init, Sym *func_sym)
+{
+ int v, has_init, r;
+ CType type, btype;
+ Sym *sym;
+ AttributeDef ad;
+
+ while (1) {
+ if (!parse_btype(&btype, &ad)) {
+ if (is_for_loop_init)
+ return 0;
+ /* skip redundant ';' if not in old parameter decl scope */
+ if (tok == ';' && l != VT_CMP) {
+ next();
+ continue;
+ }
+ if (l != VT_CONST)
+ break;
+ if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
+ /* global asm block */
+ asm_global_instr();
+ continue;
+ }
+ if (tok >= TOK_UIDENT) {
+ /* special test for old K&R protos without explicit int
+ type. Only accepted when defining global data */
+ btype.t = VT_INT;
+ } else {
+ if (tok != TOK_EOF)
+ expect("declaration");
+ break;
+ }
+ }
+ if (tok == ';') {
+ if ((btype.t & VT_BTYPE) == VT_STRUCT) {
+ int v = btype.ref->v;
+ if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
+ tcc_warning("unnamed struct/union that defines no instances");
+ next();
+ continue;
+ }
+ if (IS_ENUM(btype.t)) {
+ next();
+ continue;
+ }
+ }
+ while (1) { /* iterate thru each declaration */
+ type = btype;
+ /* If the base type itself was an array type of unspecified
+ size (like in 'typedef int arr[]; arr x = {1};') then
+ we will overwrite the unknown size by the real one for
+ this decl. We need to unshare the ref symbol holding
+ that size. */
+ if ((type.t & VT_ARRAY) && type.ref->c < 0) {
+ type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c);
+ }
+ type_decl(&type, &ad, &v, TYPE_DIRECT);
+#if 0
+ {
+ char buf[500];
+ type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
+ printf("type = '%s'\n", buf);
+ }
+#endif
+ if ((type.t & VT_BTYPE) == VT_FUNC) {
+ if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
+ tcc_error("function without file scope cannot be static");
+ }
+ /* if old style function prototype, we accept a
+ declaration list */
+ sym = type.ref;
+ if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
+ decl0(VT_CMP, 0, sym);
+ }
+
+ if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
+ ad.asm_label = asm_label_instr();
+ /* parse one last attribute list, after asm label */
+ parse_attribute(&ad);
+ if (tok == '{')
+ expect(";");
+ }
+
+#ifdef TCC_TARGET_PE
+ if (ad.a.dllimport || ad.a.dllexport) {
+ if (type.t & (VT_STATIC|VT_TYPEDEF))
+ tcc_error("cannot have dll linkage with static or typedef");
+ if (ad.a.dllimport) {
+ if ((type.t & VT_BTYPE) == VT_FUNC)
+ ad.a.dllimport = 0;
+ else
+ type.t |= VT_EXTERN;
+ }
+ }
+#endif
+ if (tok == '{') {
+ if (l != VT_CONST)
+ tcc_error("cannot use local functions");
+ if ((type.t & VT_BTYPE) != VT_FUNC)
+ expect("function definition");
+
+ /* reject abstract declarators in function definition
+ make old style params without decl have int type */
+ sym = type.ref;
+ while ((sym = sym->next) != NULL) {
+ if (!(sym->v & ~SYM_FIELD))
+ expect("identifier");
+ if (sym->type.t == VT_VOID)
+ sym->type = int_type;
+ }
+
+ /* XXX: cannot do better now: convert extern line to static inline */
+ if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
+ type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
+
+ /* put function symbol */
+ sym = external_global_sym(v, &type, 0);
+ type.t &= ~VT_EXTERN;
+ patch_storage(sym, &ad, &type);
+
+ /* static inline functions are just recorded as a kind
+ of macro. Their code will be emitted at the end of
+ the compilation unit only if they are used */
+ if ((type.t & (VT_INLINE | VT_STATIC)) ==
+ (VT_INLINE | VT_STATIC)) {
+ struct InlineFunc *fn;
+ const char *filename;
+
+ filename = file ? file->filename : "";
+ fn = tcc_malloc(sizeof *fn + strlen(filename));
+ strcpy(fn->filename, filename);
+ fn->sym = sym;
+ skip_or_save_block(&fn->func_str);
+ dynarray_add(&tcc_state->inline_fns,
+ &tcc_state->nb_inline_fns, fn);
+ } else {
+ /* compute text section */
+ cur_text_section = ad.section;
+ if (!cur_text_section)
+ cur_text_section = text_section;
+ gen_function(sym);
+ }
+ break;
+ } else {
+ if (l == VT_CMP) {
+ /* find parameter in function parameter list */
+ for (sym = func_sym->next; sym; sym = sym->next)
+ if ((sym->v & ~SYM_FIELD) == v)
+ goto found;
+ tcc_error("declaration for parameter '%s' but no such parameter",
+ get_tok_str(v, NULL));
+found:
+ if (type.t & VT_STORAGE) /* 'register' is okay */
+ tcc_error("storage class specified for '%s'",
+ get_tok_str(v, NULL));
+ if (sym->type.t != VT_VOID)
+ tcc_error("redefinition of parameter '%s'",
+ get_tok_str(v, NULL));
+ convert_parameter_type(&type);
+ sym->type = type;
+ } else if (type.t & VT_TYPEDEF) {
+ /* save typedefed type */
+ /* XXX: test storage specifiers ? */
+ sym = sym_find(v);
+ if (sym && sym->sym_scope == local_scope) {
+ if (!is_compatible_types(&sym->type, &type)
+ || !(sym->type.t & VT_TYPEDEF))
+ tcc_error("incompatible redefinition of '%s'",
+ get_tok_str(v, NULL));
+ sym->type = type;
+ } else {
+ sym = sym_push(v, &type, 0, 0);
+ }
+ sym->a = ad.a;
+ sym->f = ad.f;
+ } else {
+ r = 0;
+ if ((type.t & VT_BTYPE) == VT_FUNC) {
+ /* external function definition */
+ /* specific case for func_call attribute */
+ type.ref->f = ad.f;
+ } else if (!(type.t & VT_ARRAY)) {
+ /* not lvalue if array */
+ r |= lvalue_type(type.t);
+ }
+ has_init = (tok == '=');
+ if (has_init && (type.t & VT_VLA))
+ tcc_error("variable length array cannot be initialized");
+ if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST)) ||
+ ((type.t & VT_BTYPE) == VT_FUNC) ||
+ ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
+ !has_init && l == VT_CONST && type.ref->c < 0)) {
+ /* external variable or function */
+ /* NOTE: as GCC, uninitialized global static
+ arrays of null size are considered as
+ extern */
+ type.t |= VT_EXTERN;
+ sym = external_sym(v, &type, r, &ad);
+ if (ad.alias_target) {
+ ElfSym *esym;
+ Sym *alias_target;
+ alias_target = sym_find(ad.alias_target);
+ esym = elfsym(alias_target);
+ if (!esym)
+ tcc_error("unsupported forward __alias__ attribute");
+ /* Local statics have a scope until now (for
+ warnings), remove it here. */
+ sym->sym_scope = 0;
+ put_extern_sym2(sym, esym->st_shndx, esym->st_value, esym->st_size, 0);
+ }
+ } else {
+ if (type.t & VT_STATIC)
+ r |= VT_CONST;
+ else
+ r |= l;
+ if (has_init)
+ next();
+ else if (l == VT_CONST)
+ /* uninitialized global variables may be overridden */
+ type.t |= VT_EXTERN;
+ decl_initializer_alloc(&type, &ad, r, has_init, v, l);
+ }
+ }
+ if (tok != ',') {
+ if (is_for_loop_init)
+ return 1;
+ skip(';');
+ break;
+ }
+ next();
+ }
+ ad.a.aligned = 0;
+ }
+ }
+ return 0;
+}
+
+static void decl(int l)
+{
+ decl0(l, 0, NULL);
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/tcclib.h b/tcclib.h
new file mode 100644
index 0000000..8d59e4c
--- /dev/null
+++ b/tcclib.h
@@ -0,0 +1,80 @@
+/* Simple libc header for TCC
+ *
+ * Add any function you want from the libc there. This file is here
+ * only for your convenience so that you do not need to put the whole
+ * glibc include files on your floppy disk
+ */
+#ifndef _TCCLIB_H
+#define _TCCLIB_H
+
+#include <stddef.h>
+#include <stdarg.h>
+
+/* stdlib.h */
+void *calloc(size_t nmemb, size_t size);
+void *malloc(size_t size);
+void free(void *ptr);
+void *realloc(void *ptr, size_t size);
+int atoi(const char *nptr);
+long int strtol(const char *nptr, char **endptr, int base);
+unsigned long int strtoul(const char *nptr, char **endptr, int base);
+void exit(int);
+
+/* stdio.h */
+typedef struct __FILE FILE;
+#define EOF (-1)
+extern FILE *stdin;
+extern FILE *stdout;
+extern FILE *stderr;
+FILE *fopen(const char *path, const char *mode);
+FILE *fdopen(int fildes, const char *mode);
+FILE *freopen(const char *path, const char *mode, FILE *stream);
+int fclose(FILE *stream);
+size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
+int fgetc(FILE *stream);
+char *fgets(char *s, int size, FILE *stream);
+int getc(FILE *stream);
+int getchar(void);
+char *gets(char *s);
+int ungetc(int c, FILE *stream);
+int fflush(FILE *stream);
+int putchar (int c);
+
+int printf(const char *format, ...);
+int fprintf(FILE *stream, const char *format, ...);
+int sprintf(char *str, const char *format, ...);
+int snprintf(char *str, size_t size, const char *format, ...);
+int asprintf(char **strp, const char *format, ...);
+int dprintf(int fd, const char *format, ...);
+int vprintf(const char *format, va_list ap);
+int vfprintf(FILE *stream, const char *format, va_list ap);
+int vsprintf(char *str, const char *format, va_list ap);
+int vsnprintf(char *str, size_t size, const char *format, va_list ap);
+int vasprintf(char **strp, const char *format, va_list ap);
+int vdprintf(int fd, const char *format, va_list ap);
+
+void perror(const char *s);
+
+/* string.h */
+char *strcat(char *dest, const char *src);
+char *strchr(const char *s, int c);
+char *strrchr(const char *s, int c);
+char *strcpy(char *dest, const char *src);
+void *memcpy(void *dest, const void *src, size_t n);
+void *memmove(void *dest, const void *src, size_t n);
+void *memset(void *s, int c, size_t n);
+char *strdup(const char *s);
+size_t strlen(const char *s);
+
+/* dlfcn.h */
+#define RTLD_LAZY 0x001
+#define RTLD_NOW 0x002
+#define RTLD_GLOBAL 0x100
+
+void *dlopen(const char *filename, int flag);
+const char *dlerror(void);
+void *dlsym(void *handle, char *symbol);
+int dlclose(void *handle);
+
+#endif /* _TCCLIB_H */
diff --git a/tccpe.c b/tccpe.c
new file mode 100644
index 0000000..a7266c9
--- /dev/null
+++ b/tccpe.c
@@ -0,0 +1,1996 @@
+/*
+ * TCCPE.C - PE file output for the Tiny C Compiler
+ *
+ * Copyright (c) 2005-2007 grischka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tcc.h"
+
+#define PE_MERGE_DATA
+/* #define PE_PRINT_SECTIONS */
+
+#ifndef _WIN32
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#include <sys/stat.h> /* chmod() */
+#endif
+
+#ifdef TCC_TARGET_X86_64
+# define ADDR3264 ULONGLONG
+# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
+# define REL_TYPE_DIRECT R_X86_64_64
+# define R_XXX_THUNKFIX R_X86_64_PC32
+# define R_XXX_RELATIVE R_X86_64_RELATIVE
+# define IMAGE_FILE_MACHINE 0x8664
+# define RSRC_RELTYPE 3
+
+#elif defined TCC_TARGET_ARM
+# define ADDR3264 DWORD
+# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
+# define REL_TYPE_DIRECT R_ARM_ABS32
+# define R_XXX_THUNKFIX R_ARM_ABS32
+# define R_XXX_RELATIVE R_ARM_RELATIVE
+# define IMAGE_FILE_MACHINE 0x01C0
+# define RSRC_RELTYPE 7 /* ??? (not tested) */
+
+#elif defined TCC_TARGET_I386
+# define ADDR3264 DWORD
+# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
+# define REL_TYPE_DIRECT R_386_32
+# define R_XXX_THUNKFIX R_386_32
+# define R_XXX_RELATIVE R_386_RELATIVE
+# define IMAGE_FILE_MACHINE 0x014C
+# define RSRC_RELTYPE 7 /* DIR32NB */
+
+#endif
+
+#ifndef IMAGE_NT_SIGNATURE
+/* ----------------------------------------------------------- */
+/* definitions below are from winnt.h */
+
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef unsigned int DWORD;
+typedef unsigned long long ULONGLONG;
+#pragma pack(push, 1)
+
+typedef struct _IMAGE_DOS_HEADER { /* DOS .EXE header */
+ WORD e_magic; /* Magic number */
+ WORD e_cblp; /* Bytes on last page of file */
+ WORD e_cp; /* Pages in file */
+ WORD e_crlc; /* Relocations */
+ WORD e_cparhdr; /* Size of header in paragraphs */
+ WORD e_minalloc; /* Minimum extra paragraphs needed */
+ WORD e_maxalloc; /* Maximum extra paragraphs needed */
+ WORD e_ss; /* Initial (relative) SS value */
+ WORD e_sp; /* Initial SP value */
+ WORD e_csum; /* Checksum */
+ WORD e_ip; /* Initial IP value */
+ WORD e_cs; /* Initial (relative) CS value */
+ WORD e_lfarlc; /* File address of relocation table */
+ WORD e_ovno; /* Overlay number */
+ WORD e_res[4]; /* Reserved words */
+ WORD e_oemid; /* OEM identifier (for e_oeminfo) */
+ WORD e_oeminfo; /* OEM information; e_oemid specific */
+ WORD e_res2[10]; /* Reserved words */
+ DWORD e_lfanew; /* File address of new exe header */
+} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
+#define SIZE_OF_NT_SIGNATURE 4
+
+typedef struct _IMAGE_FILE_HEADER {
+ WORD Machine;
+ WORD NumberOfSections;
+ DWORD TimeDateStamp;
+ DWORD PointerToSymbolTable;
+ DWORD NumberOfSymbols;
+ WORD SizeOfOptionalHeader;
+ WORD Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+
+#define IMAGE_SIZEOF_FILE_HEADER 20
+
+typedef struct _IMAGE_DATA_DIRECTORY {
+ DWORD VirtualAddress;
+ DWORD Size;
+} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
+
+
+typedef struct _IMAGE_OPTIONAL_HEADER {
+ /* Standard fields. */
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+#ifndef TCC_TARGET_X86_64
+ DWORD BaseOfData;
+#endif
+ /* NT additional fields. */
+ ADDR3264 ImageBase;
+ DWORD SectionAlignment;
+ DWORD FileAlignment;
+ WORD MajorOperatingSystemVersion;
+ WORD MinorOperatingSystemVersion;
+ WORD MajorImageVersion;
+ WORD MinorImageVersion;
+ WORD MajorSubsystemVersion;
+ WORD MinorSubsystemVersion;
+ DWORD Win32VersionValue;
+ DWORD SizeOfImage;
+ DWORD SizeOfHeaders;
+ DWORD CheckSum;
+ WORD Subsystem;
+ WORD DllCharacteristics;
+ ADDR3264 SizeOfStackReserve;
+ ADDR3264 SizeOfStackCommit;
+ ADDR3264 SizeOfHeapReserve;
+ ADDR3264 SizeOfHeapCommit;
+ DWORD LoaderFlags;
+ DWORD NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[16];
+} IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, IMAGE_OPTIONAL_HEADER;
+
+#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 /* Export Directory */
+#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 /* Import Directory */
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 /* Resource Directory */
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 /* Exception Directory */
+#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 /* Security Directory */
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 /* Base Relocation Table */
+#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 /* Debug Directory */
+/* IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 (X86 usage) */
+#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 /* Architecture Specific Data */
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* RVA of GP */
+#define IMAGE_DIRECTORY_ENTRY_TLS 9 /* TLS Directory */
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 /* Load Configuration Directory */
+#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 /* Bound Import Directory in headers */
+#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */
+#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 /* Delay Load Import Descriptors */
+#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 /* COM Runtime descriptor */
+
+/* Section header format. */
+#define IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct _IMAGE_SECTION_HEADER {
+ BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ DWORD PhysicalAddress;
+ DWORD VirtualSize;
+ } Misc;
+ DWORD VirtualAddress;
+ DWORD SizeOfRawData;
+ DWORD PointerToRawData;
+ DWORD PointerToRelocations;
+ DWORD PointerToLinenumbers;
+ WORD NumberOfRelocations;
+ WORD NumberOfLinenumbers;
+ DWORD Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+#define IMAGE_SIZEOF_SECTION_HEADER 40
+
+typedef struct _IMAGE_EXPORT_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD Name;
+ DWORD Base;
+ DWORD NumberOfFunctions;
+ DWORD NumberOfNames;
+ DWORD AddressOfFunctions;
+ DWORD AddressOfNames;
+ DWORD AddressOfNameOrdinals;
+} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
+
+typedef struct _IMAGE_IMPORT_DESCRIPTOR {
+ union {
+ DWORD Characteristics;
+ DWORD OriginalFirstThunk;
+ };
+ DWORD TimeDateStamp;
+ DWORD ForwarderChain;
+ DWORD Name;
+ DWORD FirstThunk;
+} IMAGE_IMPORT_DESCRIPTOR;
+
+typedef struct _IMAGE_BASE_RELOCATION {
+ DWORD VirtualAddress;
+ DWORD SizeOfBlock;
+// WORD TypeOffset[1];
+} IMAGE_BASE_RELOCATION;
+
+#define IMAGE_SIZEOF_BASE_RELOCATION 8
+
+#define IMAGE_REL_BASED_ABSOLUTE 0
+#define IMAGE_REL_BASED_HIGH 1
+#define IMAGE_REL_BASED_LOW 2
+#define IMAGE_REL_BASED_HIGHLOW 3
+#define IMAGE_REL_BASED_HIGHADJ 4
+#define IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define IMAGE_REL_BASED_SECTION 6
+#define IMAGE_REL_BASED_REL32 7
+#define IMAGE_REL_BASED_DIR64 10
+
+#pragma pack(pop)
+
+/* ----------------------------------------------------------- */
+#endif /* ndef IMAGE_NT_SIGNATURE */
+/* ----------------------------------------------------------- */
+
+#ifndef IMAGE_REL_BASED_DIR64
+# define IMAGE_REL_BASED_DIR64 10
+#endif
+
+#pragma pack(push, 1)
+struct pe_header
+{
+ IMAGE_DOS_HEADER doshdr;
+ BYTE dosstub[0x40];
+ DWORD nt_sig;
+ IMAGE_FILE_HEADER filehdr;
+#ifdef TCC_TARGET_X86_64
+ IMAGE_OPTIONAL_HEADER64 opthdr;
+#else
+#ifdef _WIN64
+ IMAGE_OPTIONAL_HEADER32 opthdr;
+#else
+ IMAGE_OPTIONAL_HEADER opthdr;
+#endif
+#endif
+};
+
+struct pe_reloc_header {
+ DWORD offset;
+ DWORD size;
+};
+
+struct pe_rsrc_header {
+ struct _IMAGE_FILE_HEADER filehdr;
+ struct _IMAGE_SECTION_HEADER sectionhdr;
+};
+
+struct pe_rsrc_reloc {
+ DWORD offset;
+ DWORD size;
+ WORD type;
+};
+#pragma pack(pop)
+
+/* ------------------------------------------------------------- */
+/* internal temporary structures */
+
+/*
+#define IMAGE_SCN_CNT_CODE 0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_SHARED 0x10000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_WRITE 0x80000000
+*/
+
+enum {
+ sec_text = 0,
+ sec_data ,
+ sec_bss ,
+ sec_idata ,
+ sec_pdata ,
+ sec_other ,
+ sec_rsrc ,
+ sec_stab ,
+ sec_reloc ,
+ sec_last
+};
+
+static const DWORD pe_sec_flags[] = {
+ 0x60000020, /* ".text" , */
+ 0xC0000040, /* ".data" , */
+ 0xC0000080, /* ".bss" , */
+ 0x40000040, /* ".idata" , */
+ 0x40000040, /* ".pdata" , */
+ 0xE0000060, /* < other > , */
+ 0x40000040, /* ".rsrc" , */
+ 0x42000802, /* ".stab" , */
+ 0x42000040, /* ".reloc" , */
+};
+
+struct section_info {
+ int cls, ord;
+ char name[32];
+ DWORD sh_addr;
+ DWORD sh_size;
+ DWORD sh_flags;
+ unsigned char *data;
+ DWORD data_size;
+ IMAGE_SECTION_HEADER ish;
+};
+
+struct import_symbol {
+ int sym_index;
+ int iat_index;
+ int thk_offset;
+};
+
+struct pe_import_info {
+ int dll_index;
+ int sym_count;
+ struct import_symbol **symbols;
+};
+
+struct pe_info {
+ TCCState *s1;
+ Section *reloc;
+ Section *thunk;
+ const char *filename;
+ int type;
+ DWORD sizeofheaders;
+ ADDR3264 imagebase;
+ const char *start_symbol;
+ DWORD start_addr;
+ DWORD imp_offs;
+ DWORD imp_size;
+ DWORD iat_offs;
+ DWORD iat_size;
+ DWORD exp_offs;
+ DWORD exp_size;
+ int subsystem;
+ DWORD section_align;
+ DWORD file_align;
+ struct section_info *sec_info;
+ int sec_count;
+ struct pe_import_info **imp_info;
+ int imp_count;
+};
+
+#define PE_NUL 0
+#define PE_DLL 1
+#define PE_GUI 2
+#define PE_EXE 3
+#define PE_RUN 4
+
+/* --------------------------------------------*/
+
+static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym)
+{
+ const char *name = (char*)symtab_section->link->data + sym->st_name;
+ if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & ST_PE_STDCALL))
+ return name + 1;
+ return name;
+}
+
+static int pe_find_import(TCCState * s1, ElfW(Sym) *sym)
+{
+ char buffer[200];
+ const char *s, *p;
+ int sym_index = 0, n = 0;
+ int a, err = 0;
+
+ do {
+ s = pe_export_name(s1, sym);
+ a = 0;
+ if (n) {
+ /* second try: */
+ if (sym->st_other & ST_PE_STDCALL) {
+ /* try w/0 stdcall deco (windows API convention) */
+ p = strrchr(s, '@');
+ if (!p || s[0] != '_')
+ break;
+ strcpy(buffer, s+1)[p-s-1] = 0;
+ } else if (s[0] != '_') { /* try non-ansi function */
+ buffer[0] = '_', strcpy(buffer + 1, s);
+ } else if (0 == memcmp(s, "__imp_", 6)) { /* mingw 2.0 */
+ strcpy(buffer, s + 6), a = 1;
+ } else if (0 == memcmp(s, "_imp__", 6)) { /* mingw 3.7 */
+ strcpy(buffer, s + 6), a = 1;
+ } else {
+ continue;
+ }
+ s = buffer;
+ }
+ sym_index = find_elf_sym(s1->dynsymtab_section, s);
+ // printf("find (%d) %d %s\n", n, sym_index, s);
+ if (sym_index
+ && ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT
+ && 0 == (sym->st_other & ST_PE_IMPORT)
+ && 0 == a
+ ) err = -1, sym_index = 0;
+ } while (0 == sym_index && ++n < 2);
+ return n == 2 ? err : sym_index;
+}
+
+/*----------------------------------------------------------------------------*/
+
+static int dynarray_assoc(void **pp, int n, int key)
+{
+ int i;
+ for (i = 0; i < n; ++i, ++pp)
+ if (key == **(int **) pp)
+ return i;
+ return -1;
+}
+
+#if 0
+ST_FN DWORD umin(DWORD a, DWORD b)
+{
+ return a < b ? a : b;
+}
+#endif
+
+static DWORD umax(DWORD a, DWORD b)
+{
+ return a < b ? b : a;
+}
+
+static DWORD pe_file_align(struct pe_info *pe, DWORD n)
+{
+ return (n + (pe->file_align - 1)) & ~(pe->file_align - 1);
+}
+
+static DWORD pe_virtual_align(struct pe_info *pe, DWORD n)
+{
+ return (n + (pe->section_align - 1)) & ~(pe->section_align - 1);
+}
+
+static void pe_align_section(Section *s, int a)
+{
+ int i = s->data_offset & (a-1);
+ if (i)
+ section_ptr_add(s, a - i);
+}
+
+static void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size)
+{
+ hdr->opthdr.DataDirectory[dir].VirtualAddress = addr;
+ hdr->opthdr.DataDirectory[dir].Size = size;
+}
+
+static int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)
+{
+ if (psum) {
+ DWORD sum = *psum;
+ WORD *p = data;
+ int i;
+ for (i = len; i > 0; i -= 2) {
+ sum += (i >= 2) ? *p++ : *(BYTE*)p;
+ sum = (sum + (sum >> 16)) & 0xFFFF;
+ }
+ *psum = sum;
+ }
+ return len == fwrite(data, 1, len, fp) ? 0 : -1;
+}
+
+static void pe_fpad(FILE *fp, DWORD new_pos)
+{
+ DWORD pos = ftell(fp);
+ while (++pos <= new_pos)
+ fputc(0, fp);
+}
+
+/*----------------------------------------------------------------------------*/
+static int pe_write(struct pe_info *pe)
+{
+ static const struct pe_header pe_template = {
+ {
+ /* IMAGE_DOS_HEADER doshdr */
+ 0x5A4D, /*WORD e_magic; Magic number */
+ 0x0090, /*WORD e_cblp; Bytes on last page of file */
+ 0x0003, /*WORD e_cp; Pages in file */
+ 0x0000, /*WORD e_crlc; Relocations */
+
+ 0x0004, /*WORD e_cparhdr; Size of header in paragraphs */
+ 0x0000, /*WORD e_minalloc; Minimum extra paragraphs needed */
+ 0xFFFF, /*WORD e_maxalloc; Maximum extra paragraphs needed */
+ 0x0000, /*WORD e_ss; Initial (relative) SS value */
+
+ 0x00B8, /*WORD e_sp; Initial SP value */
+ 0x0000, /*WORD e_csum; Checksum */
+ 0x0000, /*WORD e_ip; Initial IP value */
+ 0x0000, /*WORD e_cs; Initial (relative) CS value */
+ 0x0040, /*WORD e_lfarlc; File address of relocation table */
+ 0x0000, /*WORD e_ovno; Overlay number */
+ {0,0,0,0}, /*WORD e_res[4]; Reserved words */
+ 0x0000, /*WORD e_oemid; OEM identifier (for e_oeminfo) */
+ 0x0000, /*WORD e_oeminfo; OEM information; e_oemid specific */
+ {0,0,0,0,0,0,0,0,0,0}, /*WORD e_res2[10]; Reserved words */
+ 0x00000080 /*DWORD e_lfanew; File address of new exe header */
+ },{
+ /* BYTE dosstub[0x40] */
+ /* 14 code bytes + "This program cannot be run in DOS mode.\r\r\n$" + 6 * 0x00 */
+ 0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68,
+ 0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f,
+ 0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20,
+ 0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0d,0x0a,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ },
+ 0x00004550, /* DWORD nt_sig = IMAGE_NT_SIGNATURE */
+ {
+ /* IMAGE_FILE_HEADER filehdr */
+ IMAGE_FILE_MACHINE, /*WORD Machine; */
+ 0x0003, /*WORD NumberOfSections; */
+ 0x00000000, /*DWORD TimeDateStamp; */
+ 0x00000000, /*DWORD PointerToSymbolTable; */
+ 0x00000000, /*DWORD NumberOfSymbols; */
+#if defined(TCC_TARGET_X86_64)
+ 0x00F0, /*WORD SizeOfOptionalHeader; */
+ 0x022F /*WORD Characteristics; */
+#define CHARACTERISTICS_DLL 0x222E
+#elif defined(TCC_TARGET_I386)
+ 0x00E0, /*WORD SizeOfOptionalHeader; */
+ 0x030F /*WORD Characteristics; */
+#define CHARACTERISTICS_DLL 0x230E
+#elif defined(TCC_TARGET_ARM)
+ 0x00E0, /*WORD SizeOfOptionalHeader; */
+ 0x010F, /*WORD Characteristics; */
+#define CHARACTERISTICS_DLL 0x230F
+#endif
+},{
+ /* IMAGE_OPTIONAL_HEADER opthdr */
+ /* Standard fields. */
+#ifdef TCC_TARGET_X86_64
+ 0x020B, /*WORD Magic; */
+#else
+ 0x010B, /*WORD Magic; */
+#endif
+ 0x06, /*BYTE MajorLinkerVersion; */
+ 0x00, /*BYTE MinorLinkerVersion; */
+ 0x00000000, /*DWORD SizeOfCode; */
+ 0x00000000, /*DWORD SizeOfInitializedData; */
+ 0x00000000, /*DWORD SizeOfUninitializedData; */
+ 0x00000000, /*DWORD AddressOfEntryPoint; */
+ 0x00000000, /*DWORD BaseOfCode; */
+#ifndef TCC_TARGET_X86_64
+ 0x00000000, /*DWORD BaseOfData; */
+#endif
+ /* NT additional fields. */
+#if defined(TCC_TARGET_ARM)
+ 0x00100000, /*DWORD ImageBase; */
+#else
+ 0x00400000, /*DWORD ImageBase; */
+#endif
+ 0x00001000, /*DWORD SectionAlignment; */
+ 0x00000200, /*DWORD FileAlignment; */
+ 0x0004, /*WORD MajorOperatingSystemVersion; */
+ 0x0000, /*WORD MinorOperatingSystemVersion; */
+ 0x0000, /*WORD MajorImageVersion; */
+ 0x0000, /*WORD MinorImageVersion; */
+ 0x0004, /*WORD MajorSubsystemVersion; */
+ 0x0000, /*WORD MinorSubsystemVersion; */
+ 0x00000000, /*DWORD Win32VersionValue; */
+ 0x00000000, /*DWORD SizeOfImage; */
+ 0x00000200, /*DWORD SizeOfHeaders; */
+ 0x00000000, /*DWORD CheckSum; */
+ 0x0002, /*WORD Subsystem; */
+ 0x0000, /*WORD DllCharacteristics; */
+ 0x00100000, /*DWORD SizeOfStackReserve; */
+ 0x00001000, /*DWORD SizeOfStackCommit; */
+ 0x00100000, /*DWORD SizeOfHeapReserve; */
+ 0x00001000, /*DWORD SizeOfHeapCommit; */
+ 0x00000000, /*DWORD LoaderFlags; */
+ 0x00000010, /*DWORD NumberOfRvaAndSizes; */
+
+ /* IMAGE_DATA_DIRECTORY DataDirectory[16]; */
+ {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+ {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}}
+ }};
+
+ struct pe_header pe_header = pe_template;
+
+ int i;
+ FILE *op;
+ DWORD file_offset, sum;
+ struct section_info *si;
+ IMAGE_SECTION_HEADER *psh;
+
+ op = fopen(pe->filename, "wb");
+ if (NULL == op) {
+ tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
+ return -1;
+ }
+
+ pe->sizeofheaders = pe_file_align(pe,
+ sizeof (struct pe_header)
+ + pe->sec_count * sizeof (IMAGE_SECTION_HEADER)
+ );
+
+ file_offset = pe->sizeofheaders;
+
+ if (2 == pe->s1->verbose)
+ printf("-------------------------------"
+ "\n virt file size section" "\n");
+ for (i = 0; i < pe->sec_count; ++i) {
+ DWORD addr, size;
+ const char *sh_name;
+
+ si = pe->sec_info + i;
+ sh_name = si->name;
+ addr = si->sh_addr - pe->imagebase;
+ size = si->sh_size;
+ psh = &si->ish;
+
+ if (2 == pe->s1->verbose)
+ printf("%6x %6x %6x %s\n",
+ (unsigned)addr, (unsigned)file_offset, (unsigned)size, sh_name);
+
+ switch (si->cls) {
+ case sec_text:
+ pe_header.opthdr.BaseOfCode = addr;
+ break;
+
+ case sec_data:
+#ifndef TCC_TARGET_X86_64
+ pe_header.opthdr.BaseOfData = addr;
+#endif
+ break;
+
+ case sec_bss:
+ break;
+
+ case sec_reloc:
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_BASERELOC, addr, size);
+ break;
+
+ case sec_rsrc:
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_RESOURCE, addr, size);
+ break;
+
+ case sec_pdata:
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXCEPTION, addr, size);
+ break;
+
+ case sec_stab:
+ break;
+ }
+
+ if (pe->thunk == pe->s1->sections[si->ord]) {
+ if (pe->imp_size) {
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_IMPORT,
+ pe->imp_offs + addr, pe->imp_size);
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_IAT,
+ pe->iat_offs + addr, pe->iat_size);
+ }
+ if (pe->exp_size) {
+ pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXPORT,
+ pe->exp_offs + addr, pe->exp_size);
+ }
+ }
+
+ strncpy((char*)psh->Name, sh_name, sizeof psh->Name);
+
+ psh->Characteristics = pe_sec_flags[si->cls];
+ psh->VirtualAddress = addr;
+ psh->Misc.VirtualSize = size;
+ pe_header.opthdr.SizeOfImage =
+ umax(pe_virtual_align(pe, size + addr), pe_header.opthdr.SizeOfImage);
+
+ if (si->data_size) {
+ psh->PointerToRawData = file_offset;
+ file_offset = pe_file_align(pe, file_offset + si->data_size);
+ psh->SizeOfRawData = file_offset - psh->PointerToRawData;
+ if (si->cls == sec_text)
+ pe_header.opthdr.SizeOfCode += psh->SizeOfRawData;
+ else
+ pe_header.opthdr.SizeOfInitializedData += psh->SizeOfRawData;
+ }
+ }
+
+ //pe_header.filehdr.TimeDateStamp = time(NULL);
+ pe_header.filehdr.NumberOfSections = pe->sec_count;
+ pe_header.opthdr.AddressOfEntryPoint = pe->start_addr;
+ pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
+ pe_header.opthdr.ImageBase = pe->imagebase;
+ pe_header.opthdr.Subsystem = pe->subsystem;
+ if (pe->s1->pe_stack_size)
+ pe_header.opthdr.SizeOfStackReserve = pe->s1->pe_stack_size;
+ if (PE_DLL == pe->type)
+ pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL;
+ pe_header.filehdr.Characteristics |= pe->s1->pe_characteristics;
+
+ sum = 0;
+ pe_fwrite(&pe_header, sizeof pe_header, op, &sum);
+ for (i = 0; i < pe->sec_count; ++i)
+ pe_fwrite(&pe->sec_info[i].ish, sizeof(IMAGE_SECTION_HEADER), op, &sum);
+ pe_fpad(op, pe->sizeofheaders);
+ for (i = 0; i < pe->sec_count; ++i) {
+ si = pe->sec_info + i;
+ psh = &si->ish;
+ if (si->data_size) {
+ pe_fwrite(si->data, si->data_size, op, &sum);
+ file_offset = psh->PointerToRawData + psh->SizeOfRawData;
+ pe_fpad(op, file_offset);
+ }
+ }
+
+ pe_header.opthdr.CheckSum = sum + file_offset;
+ fseek(op, offsetof(struct pe_header, opthdr.CheckSum), SEEK_SET);
+ pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL);
+ fclose (op);
+#ifndef _WIN32
+ chmod(pe->filename, 0777);
+#endif
+
+ if (2 == pe->s1->verbose)
+ printf("-------------------------------\n");
+ if (pe->s1->verbose)
+ printf("<- %s (%u bytes)\n", pe->filename, (unsigned)file_offset);
+
+ return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+
+static struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index)
+{
+ int i;
+ int dll_index;
+ struct pe_import_info *p;
+ struct import_symbol *s;
+ ElfW(Sym) *isym;
+
+ isym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index;
+ dll_index = isym->st_size;
+
+ i = dynarray_assoc ((void**)pe->imp_info, pe->imp_count, dll_index);
+ if (-1 != i) {
+ p = pe->imp_info[i];
+ goto found_dll;
+ }
+ p = tcc_mallocz(sizeof *p);
+ p->dll_index = dll_index;
+ dynarray_add(&pe->imp_info, &pe->imp_count, p);
+
+found_dll:
+ i = dynarray_assoc ((void**)p->symbols, p->sym_count, sym_index);
+ if (-1 != i)
+ return p->symbols[i];
+
+ s = tcc_mallocz(sizeof *s);
+ dynarray_add(&p->symbols, &p->sym_count, s);
+ s->sym_index = sym_index;
+ return s;
+}
+
+void pe_free_imports(struct pe_info *pe)
+{
+ int i;
+ for (i = 0; i < pe->imp_count; ++i) {
+ struct pe_import_info *p = pe->imp_info[i];
+ dynarray_reset(&p->symbols, &p->sym_count);
+ }
+ dynarray_reset(&pe->imp_info, &pe->imp_count);
+}
+
+/*----------------------------------------------------------------------------*/
+static void pe_build_imports(struct pe_info *pe)
+{
+ int thk_ptr, ent_ptr, dll_ptr, sym_cnt, i;
+ DWORD rva_base = pe->thunk->sh_addr - pe->imagebase;
+ int ndlls = pe->imp_count;
+
+ for (sym_cnt = i = 0; i < ndlls; ++i)
+ sym_cnt += pe->imp_info[i]->sym_count;
+
+ if (0 == sym_cnt)
+ return;
+
+ pe_align_section(pe->thunk, 16);
+
+ pe->imp_offs = dll_ptr = pe->thunk->data_offset;
+ pe->imp_size = (ndlls + 1) * sizeof(IMAGE_IMPORT_DESCRIPTOR);
+ pe->iat_offs = dll_ptr + pe->imp_size;
+ pe->iat_size = (sym_cnt + ndlls) * sizeof(ADDR3264);
+ section_ptr_add(pe->thunk, pe->imp_size + 2*pe->iat_size);
+
+ thk_ptr = pe->iat_offs;
+ ent_ptr = pe->iat_offs + pe->iat_size;
+
+ for (i = 0; i < pe->imp_count; ++i) {
+ IMAGE_IMPORT_DESCRIPTOR *hdr;
+ int k, n, dllindex;
+ ADDR3264 v;
+ struct pe_import_info *p = pe->imp_info[i];
+ const char *name;
+ DLLReference *dllref;
+
+ dllindex = p->dll_index;
+ if (dllindex)
+ name = (dllref = pe->s1->loaded_dlls[dllindex-1])->name;
+ else
+ name = "", dllref = NULL;
+
+ /* put the dll name into the import header */
+ v = put_elf_str(pe->thunk, name);
+ hdr = (IMAGE_IMPORT_DESCRIPTOR*)(pe->thunk->data + dll_ptr);
+ hdr->FirstThunk = thk_ptr + rva_base;
+ hdr->OriginalFirstThunk = ent_ptr + rva_base;
+ hdr->Name = v + rva_base;
+
+ for (k = 0, n = p->sym_count; k <= n; ++k) {
+ if (k < n) {
+ int iat_index = p->symbols[k]->iat_index;
+ int sym_index = p->symbols[k]->sym_index;
+ ElfW(Sym) *imp_sym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index;
+ ElfW(Sym) *org_sym = (ElfW(Sym) *)symtab_section->data + iat_index;
+ const char *name = (char*)pe->s1->dynsymtab_section->link->data + imp_sym->st_name;
+ int ordinal;
+
+ org_sym->st_value = thk_ptr;
+ org_sym->st_shndx = pe->thunk->sh_num;
+
+ if (dllref)
+ v = 0, ordinal = imp_sym->st_value; /* ordinal from pe_load_def */
+ else
+ ordinal = 0, v = imp_sym->st_value; /* address from tcc_add_symbol() */
+
+#ifdef TCC_IS_NATIVE
+ if (pe->type == PE_RUN) {
+ if (dllref) {
+ if ( !dllref->handle )
+ dllref->handle = LoadLibrary(dllref->name);
+ v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(char*)0+ordinal:name);
+ }
+ if (!v)
+ tcc_error_noabort("can't build symbol '%s'", name);
+ } else
+#endif
+ if (ordinal) {
+ v = ordinal | (ADDR3264)1 << (sizeof(ADDR3264)*8 - 1);
+ } else {
+ v = pe->thunk->data_offset + rva_base;
+ section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */
+ put_elf_str(pe->thunk, name);
+ }
+
+ } else {
+ v = 0; /* last entry is zero */
+ }
+
+ *(ADDR3264*)(pe->thunk->data+thk_ptr) =
+ *(ADDR3264*)(pe->thunk->data+ent_ptr) = v;
+ thk_ptr += sizeof (ADDR3264);
+ ent_ptr += sizeof (ADDR3264);
+ }
+ dll_ptr += sizeof(IMAGE_IMPORT_DESCRIPTOR);
+ }
+}
+
+/* ------------------------------------------------------------- */
+
+struct pe_sort_sym
+{
+ int index;
+ const char *name;
+};
+
+static int sym_cmp(const void *va, const void *vb)
+{
+ const char *ca = (*(struct pe_sort_sym**)va)->name;
+ const char *cb = (*(struct pe_sort_sym**)vb)->name;
+ return strcmp(ca, cb);
+}
+
+static void pe_build_exports(struct pe_info *pe)
+{
+ ElfW(Sym) *sym;
+ int sym_index, sym_end;
+ DWORD rva_base, func_o, name_o, ord_o, str_o;
+ IMAGE_EXPORT_DIRECTORY *hdr;
+ int sym_count, ord;
+ struct pe_sort_sym **sorted, *p;
+
+ FILE *op;
+ char buf[260];
+ const char *dllname;
+ const char *name;
+
+ rva_base = pe->thunk->sh_addr - pe->imagebase;
+ sym_count = 0, sorted = NULL, op = NULL;
+
+ sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
+ for (sym_index = 1; sym_index < sym_end; ++sym_index) {
+ sym = (ElfW(Sym)*)symtab_section->data + sym_index;
+ name = pe_export_name(pe->s1, sym);
+ if ((sym->st_other & ST_PE_EXPORT)
+ /* export only symbols from actually written sections */
+ && pe->s1->sections[sym->st_shndx]->sh_addr) {
+ p = tcc_malloc(sizeof *p);
+ p->index = sym_index;
+ p->name = name;
+ dynarray_add(&sorted, &sym_count, p);
+ }
+#if 0
+ if (sym->st_other & ST_PE_EXPORT)
+ printf("export: %s\n", name);
+ if (sym->st_other & ST_PE_STDCALL)
+ printf("stdcall: %s\n", name);
+#endif
+ }
+
+ if (0 == sym_count)
+ return;
+
+ qsort (sorted, sym_count, sizeof *sorted, sym_cmp);
+
+ pe_align_section(pe->thunk, 16);
+ dllname = tcc_basename(pe->filename);
+
+ pe->exp_offs = pe->thunk->data_offset;
+ func_o = pe->exp_offs + sizeof(IMAGE_EXPORT_DIRECTORY);
+ name_o = func_o + sym_count * sizeof (DWORD);
+ ord_o = name_o + sym_count * sizeof (DWORD);
+ str_o = ord_o + sym_count * sizeof(WORD);
+
+ hdr = section_ptr_add(pe->thunk, str_o - pe->exp_offs);
+ hdr->Characteristics = 0;
+ hdr->Base = 1;
+ hdr->NumberOfFunctions = sym_count;
+ hdr->NumberOfNames = sym_count;
+ hdr->AddressOfFunctions = func_o + rva_base;
+ hdr->AddressOfNames = name_o + rva_base;
+ hdr->AddressOfNameOrdinals = ord_o + rva_base;
+ hdr->Name = str_o + rva_base;
+ put_elf_str(pe->thunk, dllname);
+
+#if 1
+ /* automatically write exports to <output-filename>.def */
+ pstrcpy(buf, sizeof buf, pe->filename);
+ strcpy(tcc_fileextension(buf), ".def");
+ op = fopen(buf, "wb");
+ if (NULL == op) {
+ tcc_error_noabort("could not create '%s': %s", buf, strerror(errno));
+ } else {
+ fprintf(op, "LIBRARY %s\n\nEXPORTS\n", dllname);
+ if (pe->s1->verbose)
+ printf("<- %s (%d symbol%s)\n", buf, sym_count, &"s"[sym_count < 2]);
+ }
+#endif
+
+ for (ord = 0; ord < sym_count; ++ord)
+ {
+ p = sorted[ord], sym_index = p->index, name = p->name;
+ /* insert actual address later in relocate_section() */
+ put_elf_reloc(symtab_section, pe->thunk,
+ func_o, R_XXX_RELATIVE, sym_index);
+ *(DWORD*)(pe->thunk->data + name_o)
+ = pe->thunk->data_offset + rva_base;
+ *(WORD*)(pe->thunk->data + ord_o)
+ = ord;
+ put_elf_str(pe->thunk, name);
+ func_o += sizeof (DWORD);
+ name_o += sizeof (DWORD);
+ ord_o += sizeof (WORD);
+ if (op)
+ fprintf(op, "%s\n", name);
+ }
+ pe->exp_size = pe->thunk->data_offset - pe->exp_offs;
+ dynarray_reset(&sorted, &sym_count);
+ if (op)
+ fclose(op);
+}
+
+/* ------------------------------------------------------------- */
+static void pe_build_reloc (struct pe_info *pe)
+{
+ DWORD offset, block_ptr, addr;
+ int count, i;
+ ElfW_Rel *rel, *rel_end;
+ Section *s = NULL, *sr;
+
+ offset = addr = block_ptr = count = i = 0;
+ rel = rel_end = NULL;
+
+ for(;;) {
+ if (rel < rel_end) {
+ int type = ELFW(R_TYPE)(rel->r_info);
+ addr = rel->r_offset + s->sh_addr;
+ ++ rel;
+ if (type != REL_TYPE_DIRECT)
+ continue;
+ if (count == 0) { /* new block */
+ block_ptr = pe->reloc->data_offset;
+ section_ptr_add(pe->reloc, sizeof(struct pe_reloc_header));
+ offset = addr & 0xFFFFFFFF<<12;
+ }
+ if ((addr -= offset) < (1<<12)) { /* one block spans 4k addresses */
+ WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD));
+ *wp = addr | PE_IMAGE_REL<<12;
+ ++count;
+ continue;
+ }
+ -- rel;
+
+ } else if (i < pe->sec_count) {
+ sr = (s = pe->s1->sections[pe->sec_info[i++].ord])->reloc;
+ if (sr) {
+ rel = (ElfW_Rel *)sr->data;
+ rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
+ }
+ continue;
+ }
+
+ if (count) {
+ /* store the last block and ready for a new one */
+ struct pe_reloc_header *hdr;
+ if (count & 1) /* align for DWORDS */
+ section_ptr_add(pe->reloc, sizeof(WORD)), ++count;
+ hdr = (struct pe_reloc_header *)(pe->reloc->data + block_ptr);
+ hdr -> offset = offset - pe->imagebase;
+ hdr -> size = count * sizeof(WORD) + sizeof(struct pe_reloc_header);
+ count = 0;
+ }
+
+ if (rel >= rel_end)
+ break;
+ }
+}
+
+/* ------------------------------------------------------------- */
+static int pe_section_class(Section *s)
+{
+ int type, flags;
+ const char *name;
+
+ type = s->sh_type;
+ flags = s->sh_flags;
+ name = s->name;
+ if (flags & SHF_ALLOC) {
+ if (type == SHT_PROGBITS) {
+ if (flags & SHF_EXECINSTR)
+ return sec_text;
+ if (flags & SHF_WRITE)
+ return sec_data;
+ if (0 == strcmp(name, ".rsrc"))
+ return sec_rsrc;
+ if (0 == strcmp(name, ".iedat"))
+ return sec_idata;
+ if (0 == strcmp(name, ".pdata"))
+ return sec_pdata;
+ return sec_other;
+ } else if (type == SHT_NOBITS) {
+ if (flags & SHF_WRITE)
+ return sec_bss;
+ }
+ } else {
+ if (0 == strcmp(name, ".reloc"))
+ return sec_reloc;
+ if (0 == strncmp(name, ".stab", 5)) /* .stab and .stabstr */
+ return sec_stab;
+ }
+ return -1;
+}
+
+static int pe_assign_addresses (struct pe_info *pe)
+{
+ int i, k, o, c;
+ DWORD addr;
+ int *section_order;
+ struct section_info *si;
+ Section *s;
+
+ if (PE_DLL == pe->type)
+ pe->reloc = new_section(pe->s1, ".reloc", SHT_PROGBITS, 0);
+
+ // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
+
+ section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int));
+ for (o = k = 0 ; k < sec_last; ++k) {
+ for (i = 1; i < pe->s1->nb_sections; ++i) {
+ s = pe->s1->sections[i];
+ if (k == pe_section_class(s)) {
+ // printf("%s %d\n", s->name, k);
+ s->sh_addr = pe->imagebase;
+ section_order[o++] = i;
+ }
+ }
+ }
+
+ pe->sec_info = tcc_mallocz(o * sizeof (struct section_info));
+ addr = pe->imagebase + 1;
+
+ for (i = 0; i < o; ++i)
+ {
+ k = section_order[i];
+ s = pe->s1->sections[k];
+ c = pe_section_class(s);
+ si = &pe->sec_info[pe->sec_count];
+
+#ifdef PE_MERGE_DATA
+ if (c == sec_bss && pe->sec_count && si[-1].cls == sec_data) {
+ /* append .bss to .data */
+ s->sh_addr = addr = ((addr-1) | (s->sh_addralign-1)) + 1;
+ addr += s->data_offset;
+ si[-1].sh_size = addr - si[-1].sh_addr;
+ continue;
+ }
+#endif
+ if (c == sec_stab && 0 == pe->s1->do_debug)
+ continue;
+
+ strcpy(si->name, s->name);
+ si->cls = c;
+ si->ord = k;
+ si->sh_addr = s->sh_addr = addr = pe_virtual_align(pe, addr);
+ si->sh_flags = s->sh_flags;
+
+ if (c == sec_data && NULL == pe->thunk)
+ pe->thunk = s;
+
+ if (s == pe->thunk) {
+ pe_build_imports(pe);
+ pe_build_exports(pe);
+ }
+
+ if (c == sec_reloc)
+ pe_build_reloc (pe);
+
+ if (s->data_offset)
+ {
+ if (s->sh_type != SHT_NOBITS) {
+ si->data = s->data;
+ si->data_size = s->data_offset;
+ }
+
+ addr += s->data_offset;
+ si->sh_size = s->data_offset;
+ ++pe->sec_count;
+ }
+ // printf("%08x %05x %s\n", si->sh_addr, si->sh_size, si->name);
+ }
+
+#if 0
+ for (i = 1; i < pe->s1->nb_sections; ++i) {
+ Section *s = pe->s1->sections[i];
+ int type = s->sh_type;
+ int flags = s->sh_flags;
+ printf("section %-16s %-10s %5x %s,%s,%s\n",
+ s->name,
+ type == SHT_PROGBITS ? "progbits" :
+ type == SHT_NOBITS ? "nobits" :
+ type == SHT_SYMTAB ? "symtab" :
+ type == SHT_STRTAB ? "strtab" :
+ type == SHT_RELX ? "rel" : "???",
+ s->data_offset,
+ flags & SHF_ALLOC ? "alloc" : "",
+ flags & SHF_WRITE ? "write" : "",
+ flags & SHF_EXECINSTR ? "exec" : ""
+ );
+ }
+ pe->s1->verbose = 2;
+#endif
+
+ tcc_free(section_order);
+ return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+
+static int pe_isafunc(int sym_index)
+{
+ Section *sr = text_section->reloc;
+ ElfW_Rel *rel, *rel_end;
+ Elf32_Word info = ELF32_R_INFO(sym_index, R_386_PC32);
+ if (!sr)
+ return 0;
+ rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
+ for (rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++)
+ if (rel->r_info == info)
+ return 1;
+ return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+static int pe_check_symbols(struct pe_info *pe)
+{
+ ElfW(Sym) *sym;
+ int sym_index, sym_end;
+ int ret = 0;
+
+ pe_align_section(text_section, 8);
+
+ sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
+ for (sym_index = 1; sym_index < sym_end; ++sym_index) {
+
+ sym = (ElfW(Sym) *)symtab_section->data + sym_index;
+ if (sym->st_shndx == SHN_UNDEF) {
+
+ const char *name = (char*)symtab_section->link->data + sym->st_name;
+ unsigned type = ELFW(ST_TYPE)(sym->st_info);
+ int imp_sym = pe_find_import(pe->s1, sym);
+ struct import_symbol *is;
+
+ if (imp_sym <= 0)
+ goto not_found;
+
+ if (type == STT_NOTYPE) {
+ /* symbols from assembler have no type, find out which */
+ if (pe_isafunc(sym_index))
+ type = STT_FUNC;
+ else
+ type = STT_OBJECT;
+ }
+
+ is = pe_add_import(pe, imp_sym);
+
+ if (type == STT_FUNC) {
+ unsigned long offset = is->thk_offset;
+ if (offset) {
+ /* got aliased symbol, like stricmp and _stricmp */
+
+ } else {
+ char buffer[100];
+ WORD *p;
+
+ offset = text_section->data_offset;
+ /* add the 'jmp IAT[x]' instruction */
+#ifdef TCC_TARGET_ARM
+ p = section_ptr_add(text_section, 8+4); // room for code and address
+ (*(DWORD*)(p)) = 0xE59FC000; // arm code ldr ip, [pc] ; PC+8+0 = 0001xxxx
+ (*(DWORD*)(p+2)) = 0xE59CF000; // arm code ldr pc, [ip]
+#else
+ p = section_ptr_add(text_section, 8);
+ *p = 0x25FF;
+#ifdef TCC_TARGET_X86_64
+ *(DWORD*)(p+1) = (DWORD)-4;
+#endif
+#endif
+ /* add a helper symbol, will be patched later in
+ pe_build_imports */
+ sprintf(buffer, "IAT.%s", name);
+ is->iat_index = put_elf_sym(
+ symtab_section, 0, sizeof(DWORD),
+ ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
+ 0, SHN_UNDEF, buffer);
+#ifdef TCC_TARGET_ARM
+ put_elf_reloc(symtab_section, text_section,
+ offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
+#else
+ put_elf_reloc(symtab_section, text_section,
+ offset + 2, R_XXX_THUNKFIX, is->iat_index);
+#endif
+ is->thk_offset = offset;
+ }
+
+ /* tcc_realloc might have altered sym's address */
+ sym = (ElfW(Sym) *)symtab_section->data + sym_index;
+
+ /* patch the original symbol */
+ sym->st_value = offset;
+ sym->st_shndx = text_section->sh_num;
+ sym->st_other &= ~ST_PE_EXPORT; /* do not export */
+ continue;
+ }
+
+ if (type == STT_OBJECT) { /* data, ptr to that should be */
+ if (0 == is->iat_index) {
+ /* original symbol will be patched later in pe_build_imports */
+ is->iat_index = sym_index;
+ continue;
+ }
+ }
+
+ not_found:
+ if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
+ /* STB_WEAK undefined symbols are accepted */
+ continue;
+ tcc_error_noabort("undefined symbol '%s'%s", name,
+ imp_sym < 0 ? ", missing __declspec(dllimport)?":"");
+ ret = -1;
+
+ } else if (pe->s1->rdynamic
+ && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+ /* if -rdynamic option, then export all non local symbols */
+ sym->st_other |= ST_PE_EXPORT;
+ }
+ }
+ return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+#ifdef PE_PRINT_SECTIONS
+static void pe_print_section(FILE * f, Section * s)
+{
+ /* just if you're curious */
+ BYTE *p, *e, b;
+ int i, n, l, m;
+ p = s->data;
+ e = s->data + s->data_offset;
+ l = e - p;
+
+ fprintf(f, "section \"%s\"", s->name);
+ if (s->link)
+ fprintf(f, "\nlink \"%s\"", s->link->name);
+ if (s->reloc)
+ fprintf(f, "\nreloc \"%s\"", s->reloc->name);
+ fprintf(f, "\nv_addr %08X", (unsigned)s->sh_addr);
+ fprintf(f, "\ncontents %08X", (unsigned)l);
+ fprintf(f, "\n\n");
+
+ if (s->sh_type == SHT_NOBITS)
+ return;
+
+ if (0 == l)
+ return;
+
+ if (s->sh_type == SHT_SYMTAB)
+ m = sizeof(ElfW(Sym));
+ else if (s->sh_type == SHT_RELX)
+ m = sizeof(ElfW_Rel);
+ else
+ m = 16;
+
+ fprintf(f, "%-8s", "offset");
+ for (i = 0; i < m; ++i)
+ fprintf(f, " %02x", i);
+ n = 56;
+
+ if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_RELX) {
+ const char *fields1[] = {
+ "name",
+ "value",
+ "size",
+ "bind",
+ "type",
+ "other",
+ "shndx",
+ NULL
+ };
+
+ const char *fields2[] = {
+ "offs",
+ "type",
+ "symb",
+ NULL
+ };
+
+ const char **p;
+
+ if (s->sh_type == SHT_SYMTAB)
+ p = fields1, n = 106;
+ else
+ p = fields2, n = 58;
+
+ for (i = 0; p[i]; ++i)
+ fprintf(f, "%6s", p[i]);
+ fprintf(f, " symbol");
+ }
+
+ fprintf(f, "\n");
+ for (i = 0; i < n; ++i)
+ fprintf(f, "-");
+ fprintf(f, "\n");
+
+ for (i = 0; i < l;)
+ {
+ fprintf(f, "%08X", i);
+ for (n = 0; n < m; ++n) {
+ if (n + i < l)
+ fprintf(f, " %02X", p[i + n]);
+ else
+ fprintf(f, " ");
+ }
+
+ if (s->sh_type == SHT_SYMTAB) {
+ ElfW(Sym) *sym = (ElfW(Sym) *) (p + i);
+ const char *name = s->link->data + sym->st_name;
+ fprintf(f, " %04X %04X %04X %02X %02X %02X %04X \"%s\"",
+ (unsigned)sym->st_name,
+ (unsigned)sym->st_value,
+ (unsigned)sym->st_size,
+ (unsigned)ELFW(ST_BIND)(sym->st_info),
+ (unsigned)ELFW(ST_TYPE)(sym->st_info),
+ (unsigned)sym->st_other,
+ (unsigned)sym->st_shndx,
+ name);
+
+ } else if (s->sh_type == SHT_RELX) {
+ ElfW_Rel *rel = (ElfW_Rel *) (p + i);
+ ElfW(Sym) *sym =
+ (ElfW(Sym) *) s->link->data + ELFW(R_SYM)(rel->r_info);
+ const char *name = s->link->link->data + sym->st_name;
+ fprintf(f, " %04X %02X %04X \"%s\"",
+ (unsigned)rel->r_offset,
+ (unsigned)ELFW(R_TYPE)(rel->r_info),
+ (unsigned)ELFW(R_SYM)(rel->r_info),
+ name);
+ } else {
+ fprintf(f, " ");
+ for (n = 0; n < m; ++n) {
+ if (n + i < l) {
+ b = p[i + n];
+ if (b < 32 || b >= 127)
+ b = '.';
+ fprintf(f, "%c", b);
+ }
+ }
+ }
+ i += m;
+ fprintf(f, "\n");
+ }
+ fprintf(f, "\n\n");
+}
+
+static void pe_print_sections(TCCState *s1, const char *fname)
+{
+ Section *s;
+ FILE *f;
+ int i;
+ f = fopen(fname, "w");
+ for (i = 1; i < s1->nb_sections; ++i) {
+ s = s1->sections[i];
+ pe_print_section(f, s);
+ }
+ pe_print_section(f, s1->dynsymtab_section);
+ fclose(f);
+}
+#endif
+
+/* ------------------------------------------------------------- */
+/* helper function for load/store to insert one more indirection */
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2)
+{
+ int r2;
+ if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST))
+ return sv;
+ if (!sv->sym->a.dllimport)
+ return sv;
+ // printf("import %04x %04x %04x %s\n", sv->type.t, sv->sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL));
+ memset(v2, 0, sizeof *v2);
+ v2->type.t = VT_PTR;
+ v2->r = VT_CONST | VT_SYM | VT_LVAL;
+ v2->sym = sv->sym;
+
+ r2 = get_reg(RC_INT);
+ load(r2, v2);
+ v2->r = r2;
+ if ((uint32_t)sv->c.i) {
+ vpushv(v2);
+ vpushi(sv->c.i);
+ gen_opi('+');
+ *v2 = *vtop--;
+ }
+ v2->type.t = sv->type.t;
+ v2->r |= sv->r & VT_LVAL;
+ return v2;
+}
+#endif
+
+ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value)
+{
+ return set_elf_sym(
+ s1->dynsymtab_section,
+ value,
+ dllindex, /* st_size */
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE),
+ 0,
+ value ? SHN_ABS : SHN_UNDEF,
+ name
+ );
+}
+
+static int add_dllref(TCCState *s1, const char *dllname)
+{
+ DLLReference *dllref;
+ int i;
+ for (i = 0; i < s1->nb_loaded_dlls; ++i)
+ if (0 == strcmp(s1->loaded_dlls[i]->name, dllname))
+ return i + 1;
+ dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
+ strcpy(dllref->name, dllname);
+ dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
+ return s1->nb_loaded_dlls;
+}
+
+/* ------------------------------------------------------------- */
+
+static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
+{
+ lseek(fd, offset, SEEK_SET);
+ return len == read(fd, buffer, len);
+}
+
+/* ------------------------------------------------------------- */
+
+PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
+{
+ int l, i, n, n0, ret;
+ char *p;
+ int fd;
+
+ IMAGE_SECTION_HEADER ish;
+ IMAGE_EXPORT_DIRECTORY ied;
+ IMAGE_DOS_HEADER dh;
+ IMAGE_FILE_HEADER ih;
+ DWORD sig, ref, addr, ptr, namep;
+
+ int pef_hdroffset, opt_hdroffset, sec_hdroffset;
+
+ n = n0 = 0;
+ p = NULL;
+ ret = -1;
+
+ fd = open(filename, O_RDONLY | O_BINARY);
+ if (fd < 0)
+ goto the_end_1;
+ ret = 1;
+ if (!read_mem(fd, 0, &dh, sizeof dh))
+ goto the_end;
+ if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig))
+ goto the_end;
+ if (sig != 0x00004550)
+ goto the_end;
+ pef_hdroffset = dh.e_lfanew + sizeof sig;
+ if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
+ goto the_end;
+ opt_hdroffset = pef_hdroffset + sizeof ih;
+ if (ih.Machine == 0x014C) {
+ IMAGE_OPTIONAL_HEADER32 oh;
+ sec_hdroffset = opt_hdroffset + sizeof oh;
+ if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
+ goto the_end;
+ if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
+ goto the_end_0;
+ addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ } else if (ih.Machine == 0x8664) {
+ IMAGE_OPTIONAL_HEADER64 oh;
+ sec_hdroffset = opt_hdroffset + sizeof oh;
+ if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
+ goto the_end;
+ if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
+ goto the_end_0;
+ addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ } else
+ goto the_end;
+
+ //printf("addr: %08x\n", addr);
+ for (i = 0; i < ih.NumberOfSections; ++i) {
+ if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
+ goto the_end;
+ //printf("vaddr: %08x\n", ish.VirtualAddress);
+ if (addr >= ish.VirtualAddress && addr < ish.VirtualAddress + ish.SizeOfRawData)
+ goto found;
+ }
+ goto the_end_0;
+
+found:
+ ref = ish.VirtualAddress - ish.PointerToRawData;
+ if (!read_mem(fd, addr - ref, &ied, sizeof ied))
+ goto the_end;
+
+ namep = ied.AddressOfNames - ref;
+ for (i = 0; i < ied.NumberOfNames; ++i) {
+ if (!read_mem(fd, namep, &ptr, sizeof ptr))
+ goto the_end;
+ namep += sizeof ptr;
+ for (l = 0;;) {
+ if (n+1 >= n0)
+ p = tcc_realloc(p, n0 = n0 ? n0 * 2 : 256);
+ if (!read_mem(fd, ptr - ref + l++, p + n, 1)) {
+ tcc_free(p), p = NULL;
+ goto the_end;
+ }
+ if (p[n++] == 0)
+ break;
+ }
+ }
+ if (p)
+ p[n] = 0;
+the_end_0:
+ ret = 0;
+the_end:
+ close(fd);
+the_end_1:
+ *pp = p;
+ return ret;
+}
+
+/* -------------------------------------------------------------
+ * This is for compiled windows resources in 'coff' format
+ * as generated by 'windres.exe -O coff ...'.
+ */
+
+static int pe_load_res(TCCState *s1, int fd)
+{
+ struct pe_rsrc_header hdr;
+ Section *rsrc_section;
+ int i, ret = -1, sym_index;
+ BYTE *ptr;
+ unsigned offs;
+
+ if (!read_mem(fd, 0, &hdr, sizeof hdr))
+ goto quit;
+
+ if (hdr.filehdr.Machine != IMAGE_FILE_MACHINE
+ || hdr.filehdr.NumberOfSections != 1
+ || strcmp((char*)hdr.sectionhdr.Name, ".rsrc") != 0)
+ goto quit;
+
+ rsrc_section = new_section(s1, ".rsrc", SHT_PROGBITS, SHF_ALLOC);
+ ptr = section_ptr_add(rsrc_section, hdr.sectionhdr.SizeOfRawData);
+ offs = hdr.sectionhdr.PointerToRawData;
+ if (!read_mem(fd, offs, ptr, hdr.sectionhdr.SizeOfRawData))
+ goto quit;
+ offs = hdr.sectionhdr.PointerToRelocations;
+ sym_index = put_elf_sym(symtab_section, 0, 0, 0, 0, rsrc_section->sh_num, ".rsrc");
+ for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i) {
+ struct pe_rsrc_reloc rel;
+ if (!read_mem(fd, offs, &rel, sizeof rel))
+ goto quit;
+ // printf("rsrc_reloc: %x %x %x\n", rel.offset, rel.size, rel.type);
+ if (rel.type != RSRC_RELTYPE)
+ goto quit;
+ put_elf_reloc(symtab_section, rsrc_section,
+ rel.offset, R_XXX_RELATIVE, sym_index);
+ offs += sizeof rel;
+ }
+ ret = 0;
+quit:
+ return ret;
+}
+
+/* ------------------------------------------------------------- */
+
+static char *trimfront(char *p)
+{
+ while (*p && (unsigned char)*p <= ' ')
+ ++p;
+ return p;
+}
+
+static char *trimback(char *a, char *e)
+{
+ while (e > a && (unsigned char)e[-1] <= ' ')
+ --e;
+ *e = 0;;
+ return a;
+}
+
+/* ------------------------------------------------------------- */
+static int pe_load_def(TCCState *s1, int fd)
+{
+ int state = 0, ret = -1, dllindex = 0, ord;
+ char line[400], dllname[80], *p, *x;
+ FILE *fp;
+
+ fp = fdopen(dup(fd), "rb");
+ while (fgets(line, sizeof line, fp))
+ {
+ p = trimfront(trimback(line, strchr(line, 0)));
+ if (0 == *p || ';' == *p)
+ continue;
+
+ switch (state) {
+ case 0:
+ if (0 != strnicmp(p, "LIBRARY", 7))
+ goto quit;
+ pstrcpy(dllname, sizeof dllname, trimfront(p+7));
+ ++state;
+ continue;
+
+ case 1:
+ if (0 != stricmp(p, "EXPORTS"))
+ goto quit;
+ ++state;
+ continue;
+
+ case 2:
+ dllindex = add_dllref(s1, dllname);
+ ++state;
+ /* fall through */
+ default:
+ /* get ordinal and will store in sym->st_value */
+ ord = 0;
+ x = strchr(p, ' ');
+ if (x) {
+ *x = 0, x = strrchr(x + 1, '@');
+ if (x) {
+ char *d;
+ ord = (int)strtol(x + 1, &d, 10);
+ if (*d)
+ ord = 0;
+ }
+ }
+ pe_putimport(s1, dllindex, p, ord);
+ continue;
+ }
+ }
+ ret = 0;
+quit:
+ fclose(fp);
+ return ret;
+}
+
+/* ------------------------------------------------------------- */
+static int pe_load_dll(TCCState *s1, const char *filename)
+{
+ char *p, *q;
+ int index, ret;
+
+ ret = tcc_get_dllexports(filename, &p);
+ if (ret) {
+ return -1;
+ } else if (p) {
+ index = add_dllref(s1, tcc_basename(filename));
+ for (q = p; *q; q += 1 + strlen(q))
+ pe_putimport(s1, index, q, 0);
+ tcc_free(p);
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------- */
+ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd)
+{
+ int ret = -1;
+ char buf[10];
+ if (0 == strcmp(tcc_fileextension(filename), ".def"))
+ ret = pe_load_def(s1, fd);
+ else if (pe_load_res(s1, fd) == 0)
+ ret = 0;
+ else if (read_mem(fd, 0, buf, 4) && 0 == memcmp(buf, "MZ\220", 4))
+ ret = pe_load_dll(s1, filename);
+ return ret;
+}
+
+/* ------------------------------------------------------------- */
+#ifdef TCC_TARGET_X86_64
+static unsigned pe_add_uwwind_info(TCCState *s1)
+{
+ if (NULL == s1->uw_pdata) {
+ s1->uw_pdata = find_section(tcc_state, ".pdata");
+ s1->uw_pdata->sh_addralign = 4;
+ }
+ if (0 == s1->uw_sym)
+ s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, ".uw_base");
+ if (0 == s1->uw_offs) {
+ /* As our functions all have the same stackframe, we use one entry for all */
+ static const unsigned char uw_info[] = {
+ 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags
+ 0x04, // UBYTE Size of prolog
+ 0x02, // UBYTE Count of unwind codes
+ 0x05, // UBYTE: 4 Frame Register (rbp), UBYTE: 4 Frame Register offset (scaled)
+ // USHORT * n Unwind codes array
+ // 0x0b, 0x01, 0xff, 0xff, // stack size
+ 0x04, 0x03, // set frame ptr (mov rsp -> rbp)
+ 0x01, 0x50 // push reg (rbp)
+ };
+
+ Section *s = text_section;
+ unsigned char *p;
+
+ section_ptr_add(s, -s->data_offset & 3); /* align */
+ s1->uw_offs = s->data_offset;
+ p = section_ptr_add(s, sizeof uw_info);
+ memcpy(p, uw_info, sizeof uw_info);
+ }
+
+ return s1->uw_offs;
+}
+
+ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack)
+{
+ TCCState *s1 = tcc_state;
+ Section *pd;
+ unsigned o, n, d;
+ struct /* _RUNTIME_FUNCTION */ {
+ DWORD BeginAddress;
+ DWORD EndAddress;
+ DWORD UnwindData;
+ } *p;
+
+ d = pe_add_uwwind_info(s1);
+ pd = s1->uw_pdata;
+ o = pd->data_offset;
+ p = section_ptr_add(pd, sizeof *p);
+
+ /* record this function */
+ p->BeginAddress = start;
+ p->EndAddress = end;
+ p->UnwindData = d;
+
+ /* put relocations on it */
+ for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress)
+ put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);
+}
+#endif
+/* ------------------------------------------------------------- */
+#ifdef TCC_TARGET_X86_64
+#define PE_STDSYM(n,s) n
+#else
+#define PE_STDSYM(n,s) "_" n s
+#endif
+
+static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
+{
+ const char *start_symbol;
+ int pe_type = 0;
+ int unicode_entry = 0;
+
+ if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16")))
+ pe_type = PE_GUI;
+ else
+ if (find_elf_sym(symtab_section, PE_STDSYM("wWinMain","@16"))) {
+ pe_type = PE_GUI;
+ unicode_entry = PE_GUI;
+ }
+ else
+ if (TCC_OUTPUT_DLL == s1->output_type) {
+ pe_type = PE_DLL;
+ /* need this for 'tccelf.c:relocate_section()' */
+ s1->output_type = TCC_OUTPUT_EXE;
+ }
+ else {
+ pe_type = PE_EXE;
+ if (find_elf_sym(symtab_section, "wmain"))
+ unicode_entry = PE_EXE;
+ }
+
+ start_symbol =
+ TCC_OUTPUT_MEMORY == s1->output_type
+ ? PE_GUI == pe_type ? (unicode_entry ? "__runwwinmain" : "__runwinmain")
+ : (unicode_entry ? "__runwmain" : "__runmain")
+ : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12")
+ : PE_GUI == pe_type ? (unicode_entry ? "__wwinstart": "__winstart")
+ : (unicode_entry ? "__wstart" : "__start")
+ ;
+
+ if (!s1->leading_underscore || strchr(start_symbol, '@'))
+ ++start_symbol;
+
+ /* grab the startup code from libtcc1 */
+#ifdef TCC_IS_NATIVE
+ if (TCC_OUTPUT_MEMORY != s1->output_type || s1->runtime_main)
+#endif
+ set_elf_sym(symtab_section,
+ 0, 0,
+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+ SHN_UNDEF, start_symbol);
+
+ tcc_add_pragma_libs(s1);
+
+ if (0 == s1->nostdlib) {
+ static const char *libs[] = {
+ TCC_LIBTCC1, "msvcrt", "kernel32", "", "user32", "gdi32", NULL
+ };
+ const char **pp, *p;
+ for (pp = libs; 0 != (p = *pp); ++pp) {
+ if (0 == *p) {
+ if (PE_DLL != pe_type && PE_GUI != pe_type)
+ break;
+ } else if (pp == libs && tcc_add_dll(s1, p, 0) >= 0) {
+ continue;
+ } else {
+ tcc_add_library_err(s1, p);
+ }
+ }
+ }
+
+ if (TCC_OUTPUT_MEMORY == s1->output_type)
+ pe_type = PE_RUN;
+ pe->type = pe_type;
+ pe->start_symbol = start_symbol;
+}
+
+static void pe_set_options(TCCState * s1, struct pe_info *pe)
+{
+ if (PE_DLL == pe->type) {
+ /* XXX: check if is correct for arm-pe target */
+ pe->imagebase = 0x10000000;
+ } else {
+#if defined(TCC_TARGET_ARM)
+ pe->imagebase = 0x00010000;
+#else
+ pe->imagebase = 0x00400000;
+#endif
+ }
+
+#if defined(TCC_TARGET_ARM)
+ /* we use "console" subsystem by default */
+ pe->subsystem = 9;
+#else
+ if (PE_DLL == pe->type || PE_GUI == pe->type)
+ pe->subsystem = 2;
+ else
+ pe->subsystem = 3;
+#endif
+ /* Allow override via -Wl,-subsystem=... option */
+ if (s1->pe_subsystem != 0)
+ pe->subsystem = s1->pe_subsystem;
+
+ /* set default file/section alignment */
+ if (pe->subsystem == 1) {
+ pe->section_align = 0x20;
+ pe->file_align = 0x20;
+ } else {
+ pe->section_align = 0x1000;
+ pe->file_align = 0x200;
+ }
+
+ if (s1->section_align != 0)
+ pe->section_align = s1->section_align;
+ if (s1->pe_file_align != 0)
+ pe->file_align = s1->pe_file_align;
+
+ if ((pe->subsystem >= 10) && (pe->subsystem <= 12))
+ pe->imagebase = 0;
+
+ if (s1->has_text_addr)
+ pe->imagebase = s1->text_addr;
+}
+
+ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
+{
+ int ret;
+ struct pe_info pe;
+ int i;
+
+ memset(&pe, 0, sizeof pe);
+ pe.filename = filename;
+ pe.s1 = s1;
+
+ tcc_add_bcheck(s1);
+ pe_add_runtime(s1, &pe);
+ resolve_common_syms(s1);
+ pe_set_options(s1, &pe);
+
+ ret = pe_check_symbols(&pe);
+ if (ret)
+ ;
+ else if (filename) {
+ pe_assign_addresses(&pe);
+ relocate_syms(s1, s1->symtab, 0);
+ s1->pe_imagebase = pe.imagebase;
+ for (i = 1; i < s1->nb_sections; ++i) {
+ Section *s = s1->sections[i];
+ if (s->reloc) {
+ relocate_section(s1, s);
+ }
+ }
+ pe.start_addr = (DWORD)
+ ((uintptr_t)tcc_get_symbol_err(s1, pe.start_symbol)
+ - pe.imagebase);
+ if (s1->nb_errors)
+ ret = -1;
+ else
+ ret = pe_write(&pe);
+ tcc_free(pe.sec_info);
+ } else {
+#ifdef TCC_IS_NATIVE
+ pe.thunk = data_section;
+ pe_build_imports(&pe);
+ s1->runtime_main = pe.start_symbol;
+#ifdef TCC_TARGET_X86_64
+ s1->uw_pdata = find_section(s1, ".pdata");
+#endif
+#endif
+ }
+
+ pe_free_imports(&pe);
+
+#ifdef PE_PRINT_SECTIONS
+ pe_print_sections(s1, "tcc.log");
+#endif
+ return ret;
+}
+
+/* ------------------------------------------------------------- */
diff --git a/tccpp.c b/tccpp.c
new file mode 100644
index 0000000..76f9e42
--- /dev/null
+++ b/tccpp.c
@@ -0,0 +1,3903 @@
+/*
+ * TCC - Tiny C Compiler
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tcc.h"
+
+/********************************************************/
+/* global variables */
+
+ST_DATA int tok_flags;
+ST_DATA int parse_flags;
+
+ST_DATA struct BufferedFile *file;
+ST_DATA int ch, tok;
+ST_DATA CValue tokc;
+ST_DATA const int *macro_ptr;
+ST_DATA CString tokcstr; /* current parsed string, if any */
+
+/* display benchmark infos */
+ST_DATA int total_lines;
+ST_DATA int total_bytes;
+ST_DATA int tok_ident;
+ST_DATA TokenSym **table_ident;
+
+/* ------------------------------------------------------------------------- */
+
+static TokenSym *hash_ident[TOK_HASH_SIZE];
+static char token_buf[STRING_MAX_SIZE + 1];
+static CString cstr_buf;
+static CString macro_equal_buf;
+static TokenString tokstr_buf;
+static unsigned char isidnum_table[256 - CH_EOF];
+static int pp_debug_tok, pp_debug_symv;
+static int pp_once;
+static int pp_expr;
+static int pp_counter;
+static void tok_print(const char *msg, const int *str);
+
+static struct TinyAlloc *toksym_alloc;
+static struct TinyAlloc *tokstr_alloc;
+static struct TinyAlloc *cstr_alloc;
+
+static TokenString *macro_stack;
+
+static const char tcc_keywords[] =
+#define DEF(id, str) str "\0"
+#include "tcctok.h"
+#undef DEF
+;
+
+/* WARNING: the content of this string encodes token numbers */
+static const unsigned char tok_two_chars[] =
+/* outdated -- gr
+ "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253"
+ "-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
+*/{
+ '<','=', TOK_LE,
+ '>','=', TOK_GE,
+ '!','=', TOK_NE,
+ '&','&', TOK_LAND,
+ '|','|', TOK_LOR,
+ '+','+', TOK_INC,
+ '-','-', TOK_DEC,
+ '=','=', TOK_EQ,
+ '<','<', TOK_SHL,
+ '>','>', TOK_SAR,
+ '+','=', TOK_A_ADD,
+ '-','=', TOK_A_SUB,
+ '*','=', TOK_A_MUL,
+ '/','=', TOK_A_DIV,
+ '%','=', TOK_A_MOD,
+ '&','=', TOK_A_AND,
+ '^','=', TOK_A_XOR,
+ '|','=', TOK_A_OR,
+ '-','>', TOK_ARROW,
+ '.','.', TOK_TWODOTS,
+ '#','#', TOK_TWOSHARPS,
+ 0
+};
+
+static void next_nomacro_spc(void);
+
+ST_FUNC void skip(int c)
+{
+ if (tok != c)
+ tcc_error("'%c' expected (got \"%s\")", c, get_tok_str(tok, &tokc));
+ next();
+}
+
+ST_FUNC void expect(const char *msg)
+{
+ tcc_error("%s expected", msg);
+}
+
+/* ------------------------------------------------------------------------- */
+/* Custom allocator for tiny objects */
+
+#define USE_TAL
+
+#ifndef USE_TAL
+#define tal_free(al, p) tcc_free(p)
+#define tal_realloc(al, p, size) tcc_realloc(p, size)
+#define tal_new(a,b,c)
+#define tal_delete(a)
+#else
+#if !defined(MEM_DEBUG)
+#define tal_free(al, p) tal_free_impl(al, p)
+#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size)
+#define TAL_DEBUG_PARAMS
+#else
+#define TAL_DEBUG 1
+//#define TAL_INFO 1 /* collect and dump allocators stats */
+#define tal_free(al, p) tal_free_impl(al, p, __FILE__, __LINE__)
+#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size, __FILE__, __LINE__)
+#define TAL_DEBUG_PARAMS , const char *file, int line
+#define TAL_DEBUG_FILE_LEN 40
+#endif
+
+#define TOKSYM_TAL_SIZE (768 * 1024) /* allocator for tiny TokenSym in table_ident */
+#define TOKSTR_TAL_SIZE (768 * 1024) /* allocator for tiny TokenString instances */
+#define CSTR_TAL_SIZE (256 * 1024) /* allocator for tiny CString instances */
+#define TOKSYM_TAL_LIMIT 256 /* prefer unique limits to distinguish allocators debug msgs */
+#define TOKSTR_TAL_LIMIT 128 /* 32 * sizeof(int) */
+#define CSTR_TAL_LIMIT 1024
+
+typedef struct TinyAlloc {
+ unsigned limit;
+ unsigned size;
+ uint8_t *buffer;
+ uint8_t *p;
+ unsigned nb_allocs;
+ struct TinyAlloc *next, *top;
+#ifdef TAL_INFO
+ unsigned nb_peak;
+ unsigned nb_total;
+ unsigned nb_missed;
+ uint8_t *peak_p;
+#endif
+} TinyAlloc;
+
+typedef struct tal_header_t {
+ unsigned size;
+#ifdef TAL_DEBUG
+ int line_num; /* negative line_num used for double free check */
+ char file_name[TAL_DEBUG_FILE_LEN + 1];
+#endif
+} tal_header_t;
+
+/* ------------------------------------------------------------------------- */
+
+static TinyAlloc *tal_new(TinyAlloc **pal, unsigned limit, unsigned size)
+{
+ TinyAlloc *al = tcc_mallocz(sizeof(TinyAlloc));
+ al->p = al->buffer = tcc_malloc(size);
+ al->limit = limit;
+ al->size = size;
+ if (pal) *pal = al;
+ return al;
+}
+
+static void tal_delete(TinyAlloc *al)
+{
+ TinyAlloc *next;
+
+tail_call:
+ if (!al)
+ return;
+#ifdef TAL_INFO
+ fprintf(stderr, "limit=%5d, size=%5g MB, nb_peak=%6d, nb_total=%8d, nb_missed=%6d, usage=%5.1f%%\n",
+ al->limit, al->size / 1024.0 / 1024.0, al->nb_peak, al->nb_total, al->nb_missed,
+ (al->peak_p - al->buffer) * 100.0 / al->size);
+#endif
+#ifdef TAL_DEBUG
+ if (al->nb_allocs > 0) {
+ uint8_t *p;
+ fprintf(stderr, "TAL_DEBUG: memory leak %d chunk(s) (limit= %d)\n",
+ al->nb_allocs, al->limit);
+ p = al->buffer;
+ while (p < al->p) {
+ tal_header_t *header = (tal_header_t *)p;
+ if (header->line_num > 0) {
+ fprintf(stderr, "%s:%d: chunk of %d bytes leaked\n",
+ header->file_name, header->line_num, header->size);
+ }
+ p += header->size + sizeof(tal_header_t);
+ }
+#if MEM_DEBUG-0 == 2
+ exit(2);
+#endif
+ }
+#endif
+ next = al->next;
+ tcc_free(al->buffer);
+ tcc_free(al);
+ al = next;
+ goto tail_call;
+}
+
+static void tal_free_impl(TinyAlloc *al, void *p TAL_DEBUG_PARAMS)
+{
+ if (!p)
+ return;
+tail_call:
+ if (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size) {
+#ifdef TAL_DEBUG
+ tal_header_t *header = (((tal_header_t *)p) - 1);
+ if (header->line_num < 0) {
+ fprintf(stderr, "%s:%d: TAL_DEBUG: double frees chunk from\n",
+ file, line);
+ fprintf(stderr, "%s:%d: %d bytes\n",
+ header->file_name, (int)-header->line_num, (int)header->size);
+ } else
+ header->line_num = -header->line_num;
+#endif
+ al->nb_allocs--;
+ if (!al->nb_allocs)
+ al->p = al->buffer;
+ } else if (al->next) {
+ al = al->next;
+ goto tail_call;
+ }
+ else
+ tcc_free(p);
+}
+
+static void *tal_realloc_impl(TinyAlloc **pal, void *p, unsigned size TAL_DEBUG_PARAMS)
+{
+ tal_header_t *header;
+ void *ret;
+ int is_own;
+ unsigned adj_size = (size + 3) & -4;
+ TinyAlloc *al = *pal;
+
+tail_call:
+ is_own = (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size);
+ if ((!p || is_own) && size <= al->limit) {
+ if (al->p + adj_size + sizeof(tal_header_t) < al->buffer + al->size) {
+ header = (tal_header_t *)al->p;
+ header->size = adj_size;
+#ifdef TAL_DEBUG
+ { int ofs = strlen(file) - TAL_DEBUG_FILE_LEN;
+ strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), TAL_DEBUG_FILE_LEN);
+ header->file_name[TAL_DEBUG_FILE_LEN] = 0;
+ header->line_num = line; }
+#endif
+ ret = al->p + sizeof(tal_header_t);
+ al->p += adj_size + sizeof(tal_header_t);
+ if (is_own) {
+ header = (((tal_header_t *)p) - 1);
+ memcpy(ret, p, header->size);
+#ifdef TAL_DEBUG
+ header->line_num = -header->line_num;
+#endif
+ } else {
+ al->nb_allocs++;
+ }
+#ifdef TAL_INFO
+ if (al->nb_peak < al->nb_allocs)
+ al->nb_peak = al->nb_allocs;
+ if (al->peak_p < al->p)
+ al->peak_p = al->p;
+ al->nb_total++;
+#endif
+ return ret;
+ } else if (is_own) {
+ al->nb_allocs--;
+ ret = tal_realloc(*pal, 0, size);
+ header = (((tal_header_t *)p) - 1);
+ memcpy(ret, p, header->size);
+#ifdef TAL_DEBUG
+ header->line_num = -header->line_num;
+#endif
+ return ret;
+ }
+ if (al->next) {
+ al = al->next;
+ } else {
+ TinyAlloc *bottom = al, *next = al->top ? al->top : al;
+
+ al = tal_new(pal, next->limit, next->size * 2);
+ al->next = next;
+ bottom->top = al;
+ }
+ goto tail_call;
+ }
+ if (is_own) {
+ al->nb_allocs--;
+ ret = tcc_malloc(size);
+ header = (((tal_header_t *)p) - 1);
+ memcpy(ret, p, header->size);
+#ifdef TAL_DEBUG
+ header->line_num = -header->line_num;
+#endif
+ } else if (al->next) {
+ al = al->next;
+ goto tail_call;
+ } else
+ ret = tcc_realloc(p, size);
+#ifdef TAL_INFO
+ al->nb_missed++;
+#endif
+ return ret;
+}
+
+#endif /* USE_TAL */
+
+/* ------------------------------------------------------------------------- */
+/* CString handling */
+static void cstr_realloc(CString *cstr, int new_size)
+{
+ int size;
+
+ size = cstr->size_allocated;
+ if (size < 8)
+ size = 8; /* no need to allocate a too small first string */
+ while (size < new_size)
+ size = size * 2;
+ cstr->data = tal_realloc(cstr_alloc, cstr->data, size);
+ cstr->size_allocated = size;
+}
+
+/* add a byte */
+ST_INLN void cstr_ccat(CString *cstr, int ch)
+{
+ int size;
+ size = cstr->size + 1;
+ if (size > cstr->size_allocated)
+ cstr_realloc(cstr, size);
+ ((unsigned char *)cstr->data)[size - 1] = ch;
+ cstr->size = size;
+}
+
+ST_FUNC void cstr_cat(CString *cstr, const char *str, int len)
+{
+ int size;
+ if (len <= 0)
+ len = strlen(str) + 1 + len;
+ size = cstr->size + len;
+ if (size > cstr->size_allocated)
+ cstr_realloc(cstr, size);
+ memmove(((unsigned char *)cstr->data) + cstr->size, str, len);
+ cstr->size = size;
+}
+
+/* add a wide char */
+ST_FUNC void cstr_wccat(CString *cstr, int ch)
+{
+ int size;
+ size = cstr->size + sizeof(nwchar_t);
+ if (size > cstr->size_allocated)
+ cstr_realloc(cstr, size);
+ *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch;
+ cstr->size = size;
+}
+
+ST_FUNC void cstr_new(CString *cstr)
+{
+ memset(cstr, 0, sizeof(CString));
+}
+
+/* free string and reset it to NULL */
+ST_FUNC void cstr_free(CString *cstr)
+{
+ tal_free(cstr_alloc, cstr->data);
+ cstr_new(cstr);
+}
+
+/* reset string to empty */
+ST_FUNC void cstr_reset(CString *cstr)
+{
+ cstr->size = 0;
+}
+
+/* XXX: unicode ? */
+static void add_char(CString *cstr, int c)
+{
+ if (c == '\'' || c == '\"' || c == '\\') {
+ /* XXX: could be more precise if char or string */
+ cstr_ccat(cstr, '\\');
+ }
+ if (c >= 32 && c <= 126) {
+ cstr_ccat(cstr, c);
+ } else {
+ cstr_ccat(cstr, '\\');
+ if (c == '\n') {
+ cstr_ccat(cstr, 'n');
+ } else {
+ cstr_ccat(cstr, '0' + ((c >> 6) & 7));
+ cstr_ccat(cstr, '0' + ((c >> 3) & 7));
+ cstr_ccat(cstr, '0' + (c & 7));
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* allocate a new token */
+static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
+{
+ TokenSym *ts, **ptable;
+ int i;
+
+ if (tok_ident >= SYM_FIRST_ANOM)
+ tcc_error("memory full (symbols)");
+
+ /* expand token table if needed */
+ i = tok_ident - TOK_IDENT;
+ if ((i % TOK_ALLOC_INCR) == 0) {
+ ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
+ table_ident = ptable;
+ }
+
+ ts = tal_realloc(toksym_alloc, 0, sizeof(TokenSym) + len);
+ table_ident[i] = ts;
+ ts->tok = tok_ident++;
+ ts->sym_define = NULL;
+ ts->sym_label = NULL;
+ ts->sym_struct = NULL;
+ ts->sym_identifier = NULL;
+ ts->len = len;
+ ts->hash_next = NULL;
+ memcpy(ts->str, str, len);
+ ts->str[len] = '\0';
+ *pts = ts;
+ return ts;
+}
+
+#define TOK_HASH_INIT 1
+#define TOK_HASH_FUNC(h, c) ((h) + ((h) << 5) + ((h) >> 27) + (c))
+
+
+/* find a token and add it if not found */
+ST_FUNC TokenSym *tok_alloc(const char *str, int len)
+{
+ TokenSym *ts, **pts;
+ int i;
+ unsigned int h;
+
+ h = TOK_HASH_INIT;
+ for(i=0;i<len;i++)
+ h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
+ h &= (TOK_HASH_SIZE - 1);
+
+ pts = &hash_ident[h];
+ for(;;) {
+ ts = *pts;
+ if (!ts)
+ break;
+ if (ts->len == len && !memcmp(ts->str, str, len))
+ return ts;
+ pts = &(ts->hash_next);
+ }
+ return tok_alloc_new(pts, str, len);
+}
+
+/* XXX: buffer overflow */
+/* XXX: float tokens */
+ST_FUNC const char *get_tok_str(int v, CValue *cv)
+{
+ char *p;
+ int i, len;
+
+ cstr_reset(&cstr_buf);
+ p = cstr_buf.data;
+
+ switch(v) {
+ case TOK_CINT:
+ case TOK_CUINT:
+ case TOK_CLONG:
+ case TOK_CULONG:
+ case TOK_CLLONG:
+ case TOK_CULLONG:
+ /* XXX: not quite exact, but only useful for testing */
+#ifdef _WIN32
+ sprintf(p, "%u", (unsigned)cv->i);
+#else
+ sprintf(p, "%llu", (unsigned long long)cv->i);
+#endif
+ break;
+ case TOK_LCHAR:
+ cstr_ccat(&cstr_buf, 'L');
+ case TOK_CCHAR:
+ cstr_ccat(&cstr_buf, '\'');
+ add_char(&cstr_buf, cv->i);
+ cstr_ccat(&cstr_buf, '\'');
+ cstr_ccat(&cstr_buf, '\0');
+ break;
+ case TOK_PPNUM:
+ case TOK_PPSTR:
+ return (char*)cv->str.data;
+ case TOK_LSTR:
+ cstr_ccat(&cstr_buf, 'L');
+ case TOK_STR:
+ cstr_ccat(&cstr_buf, '\"');
+ if (v == TOK_STR) {
+ len = cv->str.size - 1;
+ for(i=0;i<len;i++)
+ add_char(&cstr_buf, ((unsigned char *)cv->str.data)[i]);
+ } else {
+ len = (cv->str.size / sizeof(nwchar_t)) - 1;
+ for(i=0;i<len;i++)
+ add_char(&cstr_buf, ((nwchar_t *)cv->str.data)[i]);
+ }
+ cstr_ccat(&cstr_buf, '\"');
+ cstr_ccat(&cstr_buf, '\0');
+ break;
+
+ case TOK_CFLOAT:
+ cstr_cat(&cstr_buf, "<float>", 0);
+ break;
+ case TOK_CDOUBLE:
+ cstr_cat(&cstr_buf, "<double>", 0);
+ break;
+ case TOK_CLDOUBLE:
+ cstr_cat(&cstr_buf, "<long double>", 0);
+ break;
+ case TOK_LINENUM:
+ cstr_cat(&cstr_buf, "<linenumber>", 0);
+ break;
+
+ /* above tokens have value, the ones below don't */
+ case TOK_LT:
+ v = '<';
+ goto addv;
+ case TOK_GT:
+ v = '>';
+ goto addv;
+ case TOK_DOTS:
+ return strcpy(p, "...");
+ case TOK_A_SHL:
+ return strcpy(p, "<<=");
+ case TOK_A_SAR:
+ return strcpy(p, ">>=");
+ case TOK_EOF:
+ return strcpy(p, "<eof>");
+ default:
+ if (v < TOK_IDENT) {
+ /* search in two bytes table */
+ const unsigned char *q = tok_two_chars;
+ while (*q) {
+ if (q[2] == v) {
+ *p++ = q[0];
+ *p++ = q[1];
+ *p = '\0';
+ return cstr_buf.data;
+ }
+ q += 3;
+ }
+ if (v >= 127) {
+ sprintf(cstr_buf.data, "<%02x>", v);
+ return cstr_buf.data;
+ }
+ addv:
+ *p++ = v;
+ *p = '\0';
+ } else if (v < tok_ident) {
+ return table_ident[v - TOK_IDENT]->str;
+ } else if (v >= SYM_FIRST_ANOM) {
+ /* special name for anonymous symbol */
+ sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
+ } else {
+ /* should never happen */
+ return NULL;
+ }
+ break;
+ }
+ return cstr_buf.data;
+}
+
+/* return the current character, handling end of block if necessary
+ (but not stray) */
+ST_FUNC int handle_eob(void)
+{
+ BufferedFile *bf = file;
+ int len;
+
+ /* only tries to read if really end of buffer */
+ if (bf->buf_ptr >= bf->buf_end) {
+ if (bf->fd >= 0) {
+#if defined(PARSE_DEBUG)
+ len = 1;
+#else
+ len = IO_BUF_SIZE;
+#endif
+ len = read(bf->fd, bf->buffer, len);
+ if (len < 0)
+ len = 0;
+ } else {
+ len = 0;
+ }
+ total_bytes += len;
+ bf->buf_ptr = bf->buffer;
+ bf->buf_end = bf->buffer + len;
+ *bf->buf_end = CH_EOB;
+ }
+ if (bf->buf_ptr < bf->buf_end) {
+ return bf->buf_ptr[0];
+ } else {
+ bf->buf_ptr = bf->buf_end;
+ return CH_EOF;
+ }
+}
+
+/* read next char from current input file and handle end of input buffer */
+ST_INLN void inp(void)
+{
+ ch = *(++(file->buf_ptr));
+ /* end of buffer/file handling */
+ if (ch == CH_EOB)
+ ch = handle_eob();
+}
+
+/* handle '\[\r]\n' */
+static int handle_stray_noerror(void)
+{
+ while (ch == '\\') {
+ inp();
+ if (ch == '\n') {
+ file->line_num++;
+ inp();
+ } else if (ch == '\r') {
+ inp();
+ if (ch != '\n')
+ goto fail;
+ file->line_num++;
+ inp();
+ } else {
+ fail:
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void handle_stray(void)
+{
+ if (handle_stray_noerror())
+ tcc_error("stray '\\' in program");
+}
+
+/* skip the stray and handle the \\n case. Output an error if
+ incorrect char after the stray */
+static int handle_stray1(uint8_t *p)
+{
+ int c;
+
+ file->buf_ptr = p;
+ if (p >= file->buf_end) {
+ c = handle_eob();
+ if (c != '\\')
+ return c;
+ p = file->buf_ptr;
+ }
+ ch = *p;
+ if (handle_stray_noerror()) {
+ if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
+ tcc_error("stray '\\' in program");
+ *--file->buf_ptr = '\\';
+ }
+ p = file->buf_ptr;
+ c = *p;
+ return c;
+}
+
+/* handle just the EOB case, but not stray */
+#define PEEKC_EOB(c, p)\
+{\
+ p++;\
+ c = *p;\
+ if (c == '\\') {\
+ file->buf_ptr = p;\
+ c = handle_eob();\
+ p = file->buf_ptr;\
+ }\
+}
+
+/* handle the complicated stray case */
+#define PEEKC(c, p)\
+{\
+ p++;\
+ c = *p;\
+ if (c == '\\') {\
+ c = handle_stray1(p);\
+ p = file->buf_ptr;\
+ }\
+}
+
+/* input with '\[\r]\n' handling. Note that this function cannot
+ handle other characters after '\', so you cannot call it inside
+ strings or comments */
+ST_FUNC void minp(void)
+{
+ inp();
+ if (ch == '\\')
+ handle_stray();
+}
+
+/* single line C++ comments */
+static uint8_t *parse_line_comment(uint8_t *p)
+{
+ int c;
+
+ p++;
+ for(;;) {
+ c = *p;
+ redo:
+ if (c == '\n' || c == CH_EOF) {
+ break;
+ } else if (c == '\\') {
+ file->buf_ptr = p;
+ c = handle_eob();
+ p = file->buf_ptr;
+ if (c == '\\') {
+ PEEKC_EOB(c, p);
+ if (c == '\n') {
+ file->line_num++;
+ PEEKC_EOB(c, p);
+ } else if (c == '\r') {
+ PEEKC_EOB(c, p);
+ if (c == '\n') {
+ file->line_num++;
+ PEEKC_EOB(c, p);
+ }
+ }
+ } else {
+ goto redo;
+ }
+ } else {
+ p++;
+ }
+ }
+ return p;
+}
+
+/* C comments */
+ST_FUNC uint8_t *parse_comment(uint8_t *p)
+{
+ int c;
+
+ p++;
+ for(;;) {
+ /* fast skip loop */
+ for(;;) {
+ c = *p;
+ if (c == '\n' || c == '*' || c == '\\')
+ break;
+ p++;
+ c = *p;
+ if (c == '\n' || c == '*' || c == '\\')
+ break;
+ p++;
+ }
+ /* now we can handle all the cases */
+ if (c == '\n') {
+ file->line_num++;
+ p++;
+ } else if (c == '*') {
+ p++;
+ for(;;) {
+ c = *p;
+ if (c == '*') {
+ p++;
+ } else if (c == '/') {
+ goto end_of_comment;
+ } else if (c == '\\') {
+ file->buf_ptr = p;
+ c = handle_eob();
+ p = file->buf_ptr;
+ if (c == CH_EOF)
+ tcc_error("unexpected end of file in comment");
+ if (c == '\\') {
+ /* skip '\[\r]\n', otherwise just skip the stray */
+ while (c == '\\') {
+ PEEKC_EOB(c, p);
+ if (c == '\n') {
+ file->line_num++;
+ PEEKC_EOB(c, p);
+ } else if (c == '\r') {
+ PEEKC_EOB(c, p);
+ if (c == '\n') {
+ file->line_num++;
+ PEEKC_EOB(c, p);
+ }
+ } else {
+ goto after_star;
+ }
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ after_star: ;
+ } else {
+ /* stray, eob or eof */
+ file->buf_ptr = p;
+ c = handle_eob();
+ p = file->buf_ptr;
+ if (c == CH_EOF) {
+ tcc_error("unexpected end of file in comment");
+ } else if (c == '\\') {
+ p++;
+ }
+ }
+ }
+ end_of_comment:
+ p++;
+ return p;
+}
+
+ST_FUNC int set_idnum(int c, int val)
+{
+ int prev = isidnum_table[c - CH_EOF];
+ isidnum_table[c - CH_EOF] = val;
+ return prev;
+}
+
+#define cinp minp
+
+static inline void skip_spaces(void)
+{
+ while (isidnum_table[ch - CH_EOF] & IS_SPC)
+ cinp();
+}
+
+static inline int check_space(int t, int *spc)
+{
+ if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
+ if (*spc)
+ return 1;
+ *spc = 1;
+ } else
+ *spc = 0;
+ return 0;
+}
+
+/* parse a string without interpreting escapes */
+static uint8_t *parse_pp_string(uint8_t *p,
+ int sep, CString *str)
+{
+ int c;
+ p++;
+ for(;;) {
+ c = *p;
+ if (c == sep) {
+ break;
+ } else if (c == '\\') {
+ file->buf_ptr = p;
+ c = handle_eob();
+ p = file->buf_ptr;
+ if (c == CH_EOF) {
+ unterminated_string:
+ /* XXX: indicate line number of start of string */
+ tcc_error("missing terminating %c character", sep);
+ } else if (c == '\\') {
+ /* escape : just skip \[\r]\n */
+ PEEKC_EOB(c, p);
+ if (c == '\n') {
+ file->line_num++;
+ p++;
+ } else if (c == '\r') {
+ PEEKC_EOB(c, p);
+ if (c != '\n')
+ expect("'\n' after '\r'");
+ file->line_num++;
+ p++;
+ } else if (c == CH_EOF) {
+ goto unterminated_string;
+ } else {
+ if (str) {
+ cstr_ccat(str, '\\');
+ cstr_ccat(str, c);
+ }
+ p++;
+ }
+ }
+ } else if (c == '\n') {
+ file->line_num++;
+ goto add_char;
+ } else if (c == '\r') {
+ PEEKC_EOB(c, p);
+ if (c != '\n') {
+ if (str)
+ cstr_ccat(str, '\r');
+ } else {
+ file->line_num++;
+ goto add_char;
+ }
+ } else {
+ add_char:
+ if (str)
+ cstr_ccat(str, c);
+ p++;
+ }
+ }
+ p++;
+ return p;
+}
+
+/* skip block of text until #else, #elif or #endif. skip also pairs of
+ #if/#endif */
+static void preprocess_skip(void)
+{
+ int a, start_of_line, c, in_warn_or_error;
+ uint8_t *p;
+
+ p = file->buf_ptr;
+ a = 0;
+redo_start:
+ start_of_line = 1;
+ in_warn_or_error = 0;
+ for(;;) {
+ redo_no_start:
+ c = *p;
+ switch(c) {
+ case ' ':
+ case '\t':
+ case '\f':
+ case '\v':
+ case '\r':
+ p++;
+ goto redo_no_start;
+ case '\n':
+ file->line_num++;
+ p++;
+ goto redo_start;
+ case '\\':
+ file->buf_ptr = p;
+ c = handle_eob();
+ if (c == CH_EOF) {
+ expect("#endif");
+ } else if (c == '\\') {
+ ch = file->buf_ptr[0];
+ handle_stray_noerror();
+ }
+ p = file->buf_ptr;
+ goto redo_no_start;
+ /* skip strings */
+ case '\"':
+ case '\'':
+ if (in_warn_or_error)
+ goto _default;
+ p = parse_pp_string(p, c, NULL);
+ break;
+ /* skip comments */
+ case '/':
+ if (in_warn_or_error)
+ goto _default;
+ file->buf_ptr = p;
+ ch = *p;
+ minp();
+ p = file->buf_ptr;
+ if (ch == '*') {
+ p = parse_comment(p);
+ } else if (ch == '/') {
+ p = parse_line_comment(p);
+ }
+ break;
+ case '#':
+ p++;
+ if (start_of_line) {
+ file->buf_ptr = p;
+ next_nomacro();
+ p = file->buf_ptr;
+ if (a == 0 &&
+ (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
+ goto the_end;
+ if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
+ a++;
+ else if (tok == TOK_ENDIF)
+ a--;
+ else if( tok == TOK_ERROR || tok == TOK_WARNING)
+ in_warn_or_error = 1;
+ else if (tok == TOK_LINEFEED)
+ goto redo_start;
+ else if (parse_flags & PARSE_FLAG_ASM_FILE)
+ p = parse_line_comment(p - 1);
+ } else if (parse_flags & PARSE_FLAG_ASM_FILE)
+ p = parse_line_comment(p - 1);
+ break;
+_default:
+ default:
+ p++;
+ break;
+ }
+ start_of_line = 0;
+ }
+ the_end: ;
+ file->buf_ptr = p;
+}
+
+#if 0
+/* return the number of additional 'ints' necessary to store the
+ token */
+static inline int tok_size(const int *p)
+{
+ switch(*p) {
+ /* 4 bytes */
+ case TOK_CINT:
+ case TOK_CUINT:
+ case TOK_CCHAR:
+ case TOK_LCHAR:
+ case TOK_CFLOAT:
+ case TOK_LINENUM:
+ return 1 + 1;
+ case TOK_STR:
+ case TOK_LSTR:
+ case TOK_PPNUM:
+ case TOK_PPSTR:
+ return 1 + ((sizeof(CString) + ((CString *)(p+1))->size + 3) >> 2);
+ case TOK_CLONG:
+ case TOK_CULONG:
+ return 1 + LONG_SIZE / 4;
+ case TOK_CDOUBLE:
+ case TOK_CLLONG:
+ case TOK_CULLONG:
+ return 1 + 2;
+ case TOK_CLDOUBLE:
+ return 1 + LDOUBLE_SIZE / 4;
+ default:
+ return 1 + 0;
+ }
+}
+#endif
+
+/* token string handling */
+ST_INLN void tok_str_new(TokenString *s)
+{
+ s->str = NULL;
+ s->len = s->lastlen = 0;
+ s->allocated_len = 0;
+ s->last_line_num = -1;
+}
+
+ST_FUNC TokenString *tok_str_alloc(void)
+{
+ TokenString *str = tal_realloc(tokstr_alloc, 0, sizeof *str);
+ tok_str_new(str);
+ return str;
+}
+
+ST_FUNC int *tok_str_dup(TokenString *s)
+{
+ int *str;
+
+ str = tal_realloc(tokstr_alloc, 0, s->len * sizeof(int));
+ memcpy(str, s->str, s->len * sizeof(int));
+ return str;
+}
+
+ST_FUNC void tok_str_free_str(int *str)
+{
+ tal_free(tokstr_alloc, str);
+}
+
+ST_FUNC void tok_str_free(TokenString *str)
+{
+ tok_str_free_str(str->str);
+ tal_free(tokstr_alloc, str);
+}
+
+ST_FUNC int *tok_str_realloc(TokenString *s, int new_size)
+{
+ int *str, size;
+
+ size = s->allocated_len;
+ if (size < 16)
+ size = 16;
+ while (size < new_size)
+ size = size * 2;
+ if (size > s->allocated_len) {
+ str = tal_realloc(tokstr_alloc, s->str, size * sizeof(int));
+ s->allocated_len = size;
+ s->str = str;
+ }
+ return s->str;
+}
+
+ST_FUNC void tok_str_add(TokenString *s, int t)
+{
+ int len, *str;
+
+ len = s->len;
+ str = s->str;
+ if (len >= s->allocated_len)
+ str = tok_str_realloc(s, len + 1);
+ str[len++] = t;
+ s->len = len;
+}
+
+ST_FUNC void begin_macro(TokenString *str, int alloc)
+{
+ str->alloc = alloc;
+ str->prev = macro_stack;
+ str->prev_ptr = macro_ptr;
+ str->save_line_num = file->line_num;
+ macro_ptr = str->str;
+ macro_stack = str;
+}
+
+ST_FUNC void end_macro(void)
+{
+ TokenString *str = macro_stack;
+ macro_stack = str->prev;
+ macro_ptr = str->prev_ptr;
+ file->line_num = str->save_line_num;
+ if (str->alloc == 2) {
+ str->alloc = 3; /* just mark as finished */
+ } else {
+ tok_str_free(str);
+ }
+}
+
+static void tok_str_add2(TokenString *s, int t, CValue *cv)
+{
+ int len, *str;
+
+ len = s->lastlen = s->len;
+ str = s->str;
+
+ /* allocate space for worst case */
+ if (len + TOK_MAX_SIZE >= s->allocated_len)
+ str = tok_str_realloc(s, len + TOK_MAX_SIZE + 1);
+ str[len++] = t;
+ switch(t) {
+ case TOK_CINT:
+ case TOK_CUINT:
+ case TOK_CCHAR:
+ case TOK_LCHAR:
+ case TOK_CFLOAT:
+ case TOK_LINENUM:
+#if LONG_SIZE == 4
+ case TOK_CLONG:
+ case TOK_CULONG:
+#endif
+ str[len++] = cv->tab[0];
+ break;
+ case TOK_PPNUM:
+ case TOK_PPSTR:
+ case TOK_STR:
+ case TOK_LSTR:
+ {
+ /* Insert the string into the int array. */
+ size_t nb_words =
+ 1 + (cv->str.size + sizeof(int) - 1) / sizeof(int);
+ if (len + nb_words >= s->allocated_len)
+ str = tok_str_realloc(s, len + nb_words + 1);
+ str[len] = cv->str.size;
+ memcpy(&str[len + 1], cv->str.data, cv->str.size);
+ len += nb_words;
+ }
+ break;
+ case TOK_CDOUBLE:
+ case TOK_CLLONG:
+ case TOK_CULLONG:
+#if LONG_SIZE == 8
+ case TOK_CLONG:
+ case TOK_CULONG:
+#endif
+#if LDOUBLE_SIZE == 8
+ case TOK_CLDOUBLE:
+#endif
+ str[len++] = cv->tab[0];
+ str[len++] = cv->tab[1];
+ break;
+#if LDOUBLE_SIZE == 12
+ case TOK_CLDOUBLE:
+ str[len++] = cv->tab[0];
+ str[len++] = cv->tab[1];
+ str[len++] = cv->tab[2];
+#elif LDOUBLE_SIZE == 16
+ case TOK_CLDOUBLE:
+ str[len++] = cv->tab[0];
+ str[len++] = cv->tab[1];
+ str[len++] = cv->tab[2];
+ str[len++] = cv->tab[3];
+#elif LDOUBLE_SIZE != 8
+#error add long double size support
+#endif
+ break;
+ default:
+ break;
+ }
+ s->len = len;
+}
+
+/* add the current parse token in token string 's' */
+ST_FUNC void tok_str_add_tok(TokenString *s)
+{
+ CValue cval;
+
+ /* save line number info */
+ if (file->line_num != s->last_line_num) {
+ s->last_line_num = file->line_num;
+ cval.i = s->last_line_num;
+ tok_str_add2(s, TOK_LINENUM, &cval);
+ }
+ tok_str_add2(s, tok, &tokc);
+}
+
+/* get a token from an integer array and increment pointer
+ accordingly. we code it as a macro to avoid pointer aliasing. */
+static inline void TOK_GET(int *t, const int **pp, CValue *cv)
+{
+ const int *p = *pp;
+ int n, *tab;
+
+ tab = cv->tab;
+ switch(*t = *p++) {
+#if LONG_SIZE == 4
+ case TOK_CLONG:
+#endif
+ case TOK_CINT:
+ case TOK_CCHAR:
+ case TOK_LCHAR:
+ case TOK_LINENUM:
+ cv->i = *p++;
+ break;
+#if LONG_SIZE == 4
+ case TOK_CULONG:
+#endif
+ case TOK_CUINT:
+ cv->i = (unsigned)*p++;
+ break;
+ case TOK_CFLOAT:
+ tab[0] = *p++;
+ break;
+ case TOK_STR:
+ case TOK_LSTR:
+ case TOK_PPNUM:
+ case TOK_PPSTR:
+ cv->str.size = *p++;
+ cv->str.data = p;
+ p += (cv->str.size + sizeof(int) - 1) / sizeof(int);
+ break;
+ case TOK_CDOUBLE:
+ case TOK_CLLONG:
+ case TOK_CULLONG:
+#if LONG_SIZE == 8
+ case TOK_CLONG:
+ case TOK_CULONG:
+#endif
+ n = 2;
+ goto copy;
+ case TOK_CLDOUBLE:
+#if LDOUBLE_SIZE == 16
+ n = 4;
+#elif LDOUBLE_SIZE == 12
+ n = 3;
+#elif LDOUBLE_SIZE == 8
+ n = 2;
+#else
+# error add long double size support
+#endif
+ copy:
+ do
+ *tab++ = *p++;
+ while (--n);
+ break;
+ default:
+ break;
+ }
+ *pp = p;
+}
+
+static int macro_is_equal(const int *a, const int *b)
+{
+ CValue cv;
+ int t;
+
+ if (!a || !b)
+ return 1;
+
+ while (*a && *b) {
+ /* first time preallocate macro_equal_buf, next time only reset position to start */
+ cstr_reset(&macro_equal_buf);
+ TOK_GET(&t, &a, &cv);
+ cstr_cat(&macro_equal_buf, get_tok_str(t, &cv), 0);
+ TOK_GET(&t, &b, &cv);
+ if (strcmp(macro_equal_buf.data, get_tok_str(t, &cv)))
+ return 0;
+ }
+ return !(*a || *b);
+}
+
+/* defines handling */
+ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
+{
+ Sym *s, *o;
+
+ o = define_find(v);
+ s = sym_push2(&define_stack, v, macro_type, 0);
+ s->d = str;
+ s->next = first_arg;
+ table_ident[v - TOK_IDENT]->sym_define = s;
+
+ if (o && !macro_is_equal(o->d, s->d))
+ tcc_warning("%s redefined", get_tok_str(v, NULL));
+}
+
+/* undefined a define symbol. Its name is just set to zero */
+ST_FUNC void define_undef(Sym *s)
+{
+ int v = s->v;
+ if (v >= TOK_IDENT && v < tok_ident)
+ table_ident[v - TOK_IDENT]->sym_define = NULL;
+}
+
+ST_INLN Sym *define_find(int v)
+{
+ v -= TOK_IDENT;
+ if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+ return NULL;
+ return table_ident[v]->sym_define;
+}
+
+/* free define stack until top reaches 'b' */
+ST_FUNC void free_defines(Sym *b)
+{
+ while (define_stack != b) {
+ Sym *top = define_stack;
+ define_stack = top->prev;
+ tok_str_free_str(top->d);
+ define_undef(top);
+ sym_free(top);
+ }
+
+ /* restore remaining (-D or predefined) symbols if they were
+ #undef'd in the file */
+ while (b) {
+ int v = b->v;
+ if (v >= TOK_IDENT && v < tok_ident) {
+ Sym **d = &table_ident[v - TOK_IDENT]->sym_define;
+ if (!*d)
+ *d = b;
+ }
+ b = b->prev;
+ }
+}
+
+/* label lookup */
+ST_FUNC Sym *label_find(int v)
+{
+ v -= TOK_IDENT;
+ if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+ return NULL;
+ return table_ident[v]->sym_label;
+}
+
+ST_FUNC Sym *label_push(Sym **ptop, int v, int flags)
+{
+ Sym *s, **ps;
+ s = sym_push2(ptop, v, 0, 0);
+ s->r = flags;
+ ps = &table_ident[v - TOK_IDENT]->sym_label;
+ if (ptop == &global_label_stack) {
+ /* modify the top most local identifier, so that
+ sym_identifier will point to 's' when popped */
+ while (*ps != NULL)
+ ps = &(*ps)->prev_tok;
+ }
+ s->prev_tok = *ps;
+ *ps = s;
+ return s;
+}
+
+/* pop labels until element last is reached. Look if any labels are
+ undefined. Define symbols if '&&label' was used. */
+ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep)
+{
+ Sym *s, *s1;
+ for(s = *ptop; s != slast; s = s1) {
+ s1 = s->prev;
+ if (s->r == LABEL_DECLARED) {
+ tcc_warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
+ } else if (s->r == LABEL_FORWARD) {
+ tcc_error("label '%s' used but not defined",
+ get_tok_str(s->v, NULL));
+ } else {
+ if (s->c) {
+ /* define corresponding symbol. A size of
+ 1 is put. */
+ put_extern_sym(s, cur_text_section, s->jnext, 1);
+ }
+ }
+ /* remove label */
+ table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
+ if (!keep)
+ sym_free(s);
+ }
+ if (!keep)
+ *ptop = slast;
+}
+
+/* fake the nth "#if defined test_..." for tcc -dt -run */
+static void maybe_run_test(TCCState *s)
+{
+ const char *p;
+ if (s->include_stack_ptr != s->include_stack)
+ return;
+ p = get_tok_str(tok, NULL);
+ if (0 != memcmp(p, "test_", 5))
+ return;
+ if (0 != --s->run_test)
+ return;
+ fprintf(s->ppfp, "\n[%s]\n" + !(s->dflag & 32), p), fflush(s->ppfp);
+ define_push(tok, MACRO_OBJ, NULL, NULL);
+}
+
+/* eval an expression for #if/#elif */
+static int expr_preprocess(void)
+{
+ int c, t;
+ TokenString *str;
+
+ str = tok_str_alloc();
+ pp_expr = 1;
+ while (tok != TOK_LINEFEED && tok != TOK_EOF) {
+ next(); /* do macro subst */
+ if (tok == TOK_DEFINED) {
+ next_nomacro();
+ t = tok;
+ if (t == '(')
+ next_nomacro();
+ if (tok < TOK_IDENT)
+ expect("identifier");
+ if (tcc_state->run_test)
+ maybe_run_test(tcc_state);
+ c = define_find(tok) != 0;
+ if (t == '(') {
+ next_nomacro();
+ if (tok != ')')
+ expect("')'");
+ }
+ tok = TOK_CINT;
+ tokc.i = c;
+ } else if (tok >= TOK_IDENT) {
+ /* if undefined macro */
+ tok = TOK_CINT;
+ tokc.i = 0;
+ }
+ tok_str_add_tok(str);
+ }
+ pp_expr = 0;
+ tok_str_add(str, -1); /* simulate end of file */
+ tok_str_add(str, 0);
+ /* now evaluate C constant expression */
+ begin_macro(str, 1);
+ next();
+ c = expr_const();
+ end_macro();
+ return c != 0;
+}
+
+
+/* parse after #define */
+ST_FUNC void parse_define(void)
+{
+ Sym *s, *first, **ps;
+ int v, t, varg, is_vaargs, spc;
+ int saved_parse_flags = parse_flags;
+
+ v = tok;
+ if (v < TOK_IDENT || v == TOK_DEFINED)
+ tcc_error("invalid macro name '%s'", get_tok_str(tok, &tokc));
+ /* XXX: should check if same macro (ANSI) */
+ first = NULL;
+ t = MACRO_OBJ;
+ /* We have to parse the whole define as if not in asm mode, in particular
+ no line comment with '#' must be ignored. Also for function
+ macros the argument list must be parsed without '.' being an ID
+ character. */
+ parse_flags = ((parse_flags & ~PARSE_FLAG_ASM_FILE) | PARSE_FLAG_SPACES);
+ /* '(' must be just after macro definition for MACRO_FUNC */
+ next_nomacro_spc();
+ if (tok == '(') {
+ int dotid = set_idnum('.', 0);
+ next_nomacro();
+ ps = &first;
+ if (tok != ')') for (;;) {
+ varg = tok;
+ next_nomacro();
+ is_vaargs = 0;
+ if (varg == TOK_DOTS) {
+ varg = TOK___VA_ARGS__;
+ is_vaargs = 1;
+ } else if (tok == TOK_DOTS && gnu_ext) {
+ is_vaargs = 1;
+ next_nomacro();
+ }
+ if (varg < TOK_IDENT)
+ bad_list:
+ tcc_error("bad macro parameter list");
+ s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
+ *ps = s;
+ ps = &s->next;
+ if (tok == ')')
+ break;
+ if (tok != ',' || is_vaargs)
+ goto bad_list;
+ next_nomacro();
+ }
+ next_nomacro_spc();
+ t = MACRO_FUNC;
+ set_idnum('.', dotid);
+ }
+
+ tokstr_buf.len = 0;
+ spc = 2;
+ parse_flags |= PARSE_FLAG_ACCEPT_STRAYS | PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED;
+ /* The body of a macro definition should be parsed such that identifiers
+ are parsed like the file mode determines (i.e. with '.' being an
+ ID character in asm mode). But '#' should be retained instead of
+ regarded as line comment leader, so still don't set ASM_FILE
+ in parse_flags. */
+ while (tok != TOK_LINEFEED && tok != TOK_EOF) {
+ /* remove spaces around ## and after '#' */
+ if (TOK_TWOSHARPS == tok) {
+ if (2 == spc)
+ goto bad_twosharp;
+ if (1 == spc)
+ --tokstr_buf.len;
+ spc = 3;
+ tok = TOK_PPJOIN;
+ } else if ('#' == tok) {
+ spc = 4;
+ } else if (check_space(tok, &spc)) {
+ goto skip;
+ }
+ tok_str_add2(&tokstr_buf, tok, &tokc);
+ skip:
+ next_nomacro_spc();
+ }
+
+ parse_flags = saved_parse_flags;
+ if (spc == 1)
+ --tokstr_buf.len; /* remove trailing space */
+ tok_str_add(&tokstr_buf, 0);
+ if (3 == spc)
+bad_twosharp:
+ tcc_error("'##' cannot appear at either end of macro");
+ define_push(v, t, tok_str_dup(&tokstr_buf), first);
+}
+
+static CachedInclude *search_cached_include(TCCState *s1, const char *filename, int add)
+{
+ const unsigned char *s;
+ unsigned int h;
+ CachedInclude *e;
+ int i;
+
+ h = TOK_HASH_INIT;
+ s = (unsigned char *) filename;
+ while (*s) {
+#ifdef _WIN32
+ h = TOK_HASH_FUNC(h, toup(*s));
+#else
+ h = TOK_HASH_FUNC(h, *s);
+#endif
+ s++;
+ }
+ h &= (CACHED_INCLUDES_HASH_SIZE - 1);
+
+ i = s1->cached_includes_hash[h];
+ for(;;) {
+ if (i == 0)
+ break;
+ e = s1->cached_includes[i - 1];
+ if (0 == PATHCMP(e->filename, filename))
+ return e;
+ i = e->hash_next;
+ }
+ if (!add)
+ return NULL;
+
+ e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
+ strcpy(e->filename, filename);
+ e->ifndef_macro = e->once = 0;
+ dynarray_add(&s1->cached_includes, &s1->nb_cached_includes, e);
+ /* add in hash table */
+ e->hash_next = s1->cached_includes_hash[h];
+ s1->cached_includes_hash[h] = s1->nb_cached_includes;
+#ifdef INC_DEBUG
+ printf("adding cached '%s'\n", filename);
+#endif
+ return e;
+}
+
+static void pragma_parse(TCCState *s1)
+{
+ next_nomacro();
+ if (tok == TOK_push_macro || tok == TOK_pop_macro) {
+ int t = tok, v;
+ Sym *s;
+
+ if (next(), tok != '(')
+ goto pragma_err;
+ if (next(), tok != TOK_STR)
+ goto pragma_err;
+ v = tok_alloc(tokc.str.data, tokc.str.size - 1)->tok;
+ if (next(), tok != ')')
+ goto pragma_err;
+ if (t == TOK_push_macro) {
+ while (NULL == (s = define_find(v)))
+ define_push(v, 0, NULL, NULL);
+ s->type.ref = s; /* set push boundary */
+ } else {
+ for (s = define_stack; s; s = s->prev)
+ if (s->v == v && s->type.ref == s) {
+ s->type.ref = NULL;
+ break;
+ }
+ }
+ if (s)
+ table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL;
+ else
+ tcc_warning("unbalanced #pragma pop_macro");
+ pp_debug_tok = t, pp_debug_symv = v;
+
+ } else if (tok == TOK_once) {
+ search_cached_include(s1, file->filename, 1)->once = pp_once;
+
+ } else if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
+ /* tcc -E: keep pragmas below unchanged */
+ unget_tok(' ');
+ unget_tok(TOK_PRAGMA);
+ unget_tok('#');
+ unget_tok(TOK_LINEFEED);
+
+ } else if (tok == TOK_pack) {
+ /* This may be:
+ #pragma pack(1) // set
+ #pragma pack() // reset to default
+ #pragma pack(push,1) // push & set
+ #pragma pack(pop) // restore previous */
+ next();
+ skip('(');
+ if (tok == TOK_ASM_pop) {
+ next();
+ if (s1->pack_stack_ptr <= s1->pack_stack) {
+ stk_error:
+ tcc_error("out of pack stack");
+ }
+ s1->pack_stack_ptr--;
+ } else {
+ int val = 0;
+ if (tok != ')') {
+ if (tok == TOK_ASM_push) {
+ next();
+ if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
+ goto stk_error;
+ s1->pack_stack_ptr++;
+ skip(',');
+ }
+ if (tok != TOK_CINT)
+ goto pragma_err;
+ val = tokc.i;
+ if (val < 1 || val > 16 || (val & (val - 1)) != 0)
+ goto pragma_err;
+ next();
+ }
+ *s1->pack_stack_ptr = val;
+ }
+ if (tok != ')')
+ goto pragma_err;
+
+ } else if (tok == TOK_comment) {
+ char *p; int t;
+ next();
+ skip('(');
+ t = tok;
+ next();
+ skip(',');
+ if (tok != TOK_STR)
+ goto pragma_err;
+ p = tcc_strdup((char *)tokc.str.data);
+ next();
+ if (tok != ')')
+ goto pragma_err;
+ if (t == TOK_lib) {
+ dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, p);
+ } else {
+ if (t == TOK_option)
+ tcc_set_options(s1, p);
+ tcc_free(p);
+ }
+
+ } else if (s1->warn_unsupported) {
+ tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
+ }
+ return;
+
+pragma_err:
+ tcc_error("malformed #pragma directive");
+ return;
+}
+
+/* is_bof is true if first non space token at beginning of file */
+ST_FUNC void preprocess(int is_bof)
+{
+ TCCState *s1 = tcc_state;
+ int i, c, n, saved_parse_flags;
+ char buf[1024], *q;
+ Sym *s;
+
+ saved_parse_flags = parse_flags;
+ parse_flags = PARSE_FLAG_PREPROCESS
+ | PARSE_FLAG_TOK_NUM
+ | PARSE_FLAG_TOK_STR
+ | PARSE_FLAG_LINEFEED
+ | (parse_flags & PARSE_FLAG_ASM_FILE)
+ ;
+
+ next_nomacro();
+ redo:
+ switch(tok) {
+ case TOK_DEFINE:
+ pp_debug_tok = tok;
+ next_nomacro();
+ pp_debug_symv = tok;
+ parse_define();
+ break;
+ case TOK_UNDEF:
+ pp_debug_tok = tok;
+ next_nomacro();
+ pp_debug_symv = tok;
+ s = define_find(tok);
+ /* undefine symbol by putting an invalid name */
+ if (s)
+ define_undef(s);
+ break;
+ case TOK_INCLUDE:
+ case TOK_INCLUDE_NEXT:
+ ch = file->buf_ptr[0];
+ /* XXX: incorrect if comments : use next_nomacro with a special mode */
+ skip_spaces();
+ if (ch == '<') {
+ c = '>';
+ goto read_name;
+ } else if (ch == '\"') {
+ c = ch;
+ read_name:
+ inp();
+ q = buf;
+ while (ch != c && ch != '\n' && ch != CH_EOF) {
+ if ((q - buf) < sizeof(buf) - 1)
+ *q++ = ch;
+ if (ch == '\\') {
+ if (handle_stray_noerror() == 0)
+ --q;
+ } else
+ inp();
+ }
+ *q = '\0';
+ minp();
+#if 0
+ /* eat all spaces and comments after include */
+ /* XXX: slightly incorrect */
+ while (ch1 != '\n' && ch1 != CH_EOF)
+ inp();
+#endif
+ } else {
+ int len;
+ /* computed #include : concatenate everything up to linefeed,
+ the result must be one of the two accepted forms.
+ Don't convert pp-tokens to tokens here. */
+ parse_flags = (PARSE_FLAG_PREPROCESS
+ | PARSE_FLAG_LINEFEED
+ | (parse_flags & PARSE_FLAG_ASM_FILE));
+ next();
+ buf[0] = '\0';
+ while (tok != TOK_LINEFEED) {
+ pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
+ next();
+ }
+ len = strlen(buf);
+ /* check syntax and remove '<>|""' */
+ if ((len < 2 || ((buf[0] != '"' || buf[len-1] != '"') &&
+ (buf[0] != '<' || buf[len-1] != '>'))))
+ tcc_error("'#include' expects \"FILENAME\" or <FILENAME>");
+ c = buf[len-1];
+ memmove(buf, buf + 1, len - 2);
+ buf[len - 2] = '\0';
+ }
+
+ if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
+ tcc_error("#include recursion too deep");
+ /* store current file in stack, but increment stack later below */
+ *s1->include_stack_ptr = file;
+ i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0;
+ n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths;
+ for (; i < n; ++i) {
+ char buf1[sizeof file->filename];
+ CachedInclude *e;
+ const char *path;
+
+ if (i == 0) {
+ /* check absolute include path */
+ if (!IS_ABSPATH(buf))
+ continue;
+ buf1[0] = 0;
+
+ } else if (i == 1) {
+ /* search in file's dir if "header.h" */
+ if (c != '\"')
+ continue;
+ /* https://savannah.nongnu.org/bugs/index.php?50847 */
+ path = file->true_filename;
+ pstrncpy(buf1, path, tcc_basename(path) - path);
+
+ } else {
+ /* search in all the include paths */
+ int j = i - 2, k = j - s1->nb_include_paths;
+ path = k < 0 ? s1->include_paths[j] : s1->sysinclude_paths[k];
+ pstrcpy(buf1, sizeof(buf1), path);
+ pstrcat(buf1, sizeof(buf1), "/");
+ }
+
+ pstrcat(buf1, sizeof(buf1), buf);
+ e = search_cached_include(s1, buf1, 0);
+ if (e && (define_find(e->ifndef_macro) || e->once == pp_once)) {
+ /* no need to parse the include because the 'ifndef macro'
+ is defined (or had #pragma once) */
+#ifdef INC_DEBUG
+ printf("%s: skipping cached %s\n", file->filename, buf1);
+#endif
+ goto include_done;
+ }
+
+ if (tcc_open(s1, buf1) < 0)
+ continue;
+
+ file->include_next_index = i + 1;
+#ifdef INC_DEBUG
+ printf("%s: including %s\n", file->prev->filename, file->filename);
+#endif
+ /* update target deps */
+ dynarray_add(&s1->target_deps, &s1->nb_target_deps,
+ tcc_strdup(buf1));
+ /* push current file in stack */
+ ++s1->include_stack_ptr;
+ /* add include file debug info */
+ if (s1->do_debug)
+ put_stabs(file->filename, N_BINCL, 0, 0, 0);
+ tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
+ ch = file->buf_ptr[0];
+ goto the_end;
+ }
+ tcc_error("include file '%s' not found", buf);
+include_done:
+ break;
+ case TOK_IFNDEF:
+ c = 1;
+ goto do_ifdef;
+ case TOK_IF:
+ c = expr_preprocess();
+ goto do_if;
+ case TOK_IFDEF:
+ c = 0;
+ do_ifdef:
+ next_nomacro();
+ if (tok < TOK_IDENT)
+ tcc_error("invalid argument for '#if%sdef'", c ? "n" : "");
+ if (is_bof) {
+ if (c) {
+#ifdef INC_DEBUG
+ printf("#ifndef %s\n", get_tok_str(tok, NULL));
+#endif
+ file->ifndef_macro = tok;
+ }
+ }
+ c = (define_find(tok) != 0) ^ c;
+ do_if:
+ if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
+ tcc_error("memory full (ifdef)");
+ *s1->ifdef_stack_ptr++ = c;
+ goto test_skip;
+ case TOK_ELSE:
+ if (s1->ifdef_stack_ptr == s1->ifdef_stack)
+ tcc_error("#else without matching #if");
+ if (s1->ifdef_stack_ptr[-1] & 2)
+ tcc_error("#else after #else");
+ c = (s1->ifdef_stack_ptr[-1] ^= 3);
+ goto test_else;
+ case TOK_ELIF:
+ if (s1->ifdef_stack_ptr == s1->ifdef_stack)
+ tcc_error("#elif without matching #if");
+ c = s1->ifdef_stack_ptr[-1];
+ if (c > 1)
+ tcc_error("#elif after #else");
+ /* last #if/#elif expression was true: we skip */
+ if (c == 1) {
+ c = 0;
+ } else {
+ c = expr_preprocess();
+ s1->ifdef_stack_ptr[-1] = c;
+ }
+ test_else:
+ if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1)
+ file->ifndef_macro = 0;
+ test_skip:
+ if (!(c & 1)) {
+ preprocess_skip();
+ is_bof = 0;
+ goto redo;
+ }
+ break;
+ case TOK_ENDIF:
+ if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
+ tcc_error("#endif without matching #if");
+ s1->ifdef_stack_ptr--;
+ /* '#ifndef macro' was at the start of file. Now we check if
+ an '#endif' is exactly at the end of file */
+ if (file->ifndef_macro &&
+ s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
+ file->ifndef_macro_saved = file->ifndef_macro;
+ /* need to set to zero to avoid false matches if another
+ #ifndef at middle of file */
+ file->ifndef_macro = 0;
+ while (tok != TOK_LINEFEED)
+ next_nomacro();
+ tok_flags |= TOK_FLAG_ENDIF;
+ goto the_end;
+ }
+ break;
+ case TOK_PPNUM:
+ n = strtoul((char*)tokc.str.data, &q, 10);
+ goto _line_num;
+ case TOK_LINE:
+ next();
+ if (tok != TOK_CINT)
+ _line_err:
+ tcc_error("wrong #line format");
+ n = tokc.i;
+ _line_num:
+ next();
+ if (tok != TOK_LINEFEED) {
+ if (tok == TOK_STR) {
+ if (file->true_filename == file->filename)
+ file->true_filename = tcc_strdup(file->filename);
+ pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.str.data);
+ } else if (parse_flags & PARSE_FLAG_ASM_FILE)
+ break;
+ else
+ goto _line_err;
+ --n;
+ }
+ if (file->fd > 0)
+ total_lines += file->line_num - n;
+ file->line_num = n;
+ if (s1->do_debug)
+ put_stabs(file->filename, N_BINCL, 0, 0, 0);
+ break;
+ case TOK_ERROR:
+ case TOK_WARNING:
+ c = tok;
+ ch = file->buf_ptr[0];
+ skip_spaces();
+ q = buf;
+ while (ch != '\n' && ch != CH_EOF) {
+ if ((q - buf) < sizeof(buf) - 1)
+ *q++ = ch;
+ if (ch == '\\') {
+ if (handle_stray_noerror() == 0)
+ --q;
+ } else
+ inp();
+ }
+ *q = '\0';
+ if (c == TOK_ERROR)
+ tcc_error("#error %s", buf);
+ else
+ tcc_warning("#warning %s", buf);
+ break;
+ case TOK_PRAGMA:
+ pragma_parse(s1);
+ break;
+ case TOK_LINEFEED:
+ goto the_end;
+ default:
+ /* ignore gas line comment in an 'S' file. */
+ if (saved_parse_flags & PARSE_FLAG_ASM_FILE)
+ goto ignore;
+ if (tok == '!' && is_bof)
+ /* '!' is ignored at beginning to allow C scripts. */
+ goto ignore;
+ tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
+ ignore:
+ file->buf_ptr = parse_line_comment(file->buf_ptr - 1);
+ goto the_end;
+ }
+ /* ignore other preprocess commands or #! for C scripts */
+ while (tok != TOK_LINEFEED)
+ next_nomacro();
+ the_end:
+ parse_flags = saved_parse_flags;
+}
+
+/* evaluate escape codes in a string. */
+static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
+{
+ int c, n;
+ const uint8_t *p;
+
+ p = buf;
+ for(;;) {
+ c = *p;
+ if (c == '\0')
+ break;
+ if (c == '\\') {
+ p++;
+ /* escape */
+ c = *p;
+ switch(c) {
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ /* at most three octal digits */
+ n = c - '0';
+ p++;
+ c = *p;
+ if (isoct(c)) {
+ n = n * 8 + c - '0';
+ p++;
+ c = *p;
+ if (isoct(c)) {
+ n = n * 8 + c - '0';
+ p++;
+ }
+ }
+ c = n;
+ goto add_char_nonext;
+ case 'x':
+ case 'u':
+ case 'U':
+ p++;
+ n = 0;
+ for(;;) {
+ c = *p;
+ if (c >= 'a' && c <= 'f')
+ c = c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ c = c - 'A' + 10;
+ else if (isnum(c))
+ c = c - '0';
+ else
+ break;
+ n = n * 16 + c;
+ p++;
+ }
+ c = n;
+ goto add_char_nonext;
+ case 'a':
+ c = '\a';
+ break;
+ case 'b':
+ c = '\b';
+ break;
+ case 'f':
+ c = '\f';
+ break;
+ case 'n':
+ c = '\n';
+ break;
+ case 'r':
+ c = '\r';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ case 'v':
+ c = '\v';
+ break;
+ case 'e':
+ if (!gnu_ext)
+ goto invalid_escape;
+ c = 27;
+ break;
+ case '\'':
+ case '\"':
+ case '\\':
+ case '?':
+ break;
+ default:
+ invalid_escape:
+ if (c >= '!' && c <= '~')
+ tcc_warning("unknown escape sequence: \'\\%c\'", c);
+ else
+ tcc_warning("unknown escape sequence: \'\\x%x\'", c);
+ break;
+ }
+ } else if (is_long && c >= 0x80) {
+ /* assume we are processing UTF-8 sequence */
+ /* reference: The Unicode Standard, Version 10.0, ch3.9 */
+
+ int cont; /* count of continuation bytes */
+ int skip; /* how many bytes should skip when error occurred */
+ int i;
+
+ /* decode leading byte */
+ if (c < 0xC2) {
+ skip = 1; goto invalid_utf8_sequence;
+ } else if (c <= 0xDF) {
+ cont = 1; n = c & 0x1f;
+ } else if (c <= 0xEF) {
+ cont = 2; n = c & 0xf;
+ } else if (c <= 0xF4) {
+ cont = 3; n = c & 0x7;
+ } else {
+ skip = 1; goto invalid_utf8_sequence;
+ }
+
+ /* decode continuation bytes */
+ for (i = 1; i <= cont; i++) {
+ int l = 0x80, h = 0xBF;
+
+ /* adjust limit for second byte */
+ if (i == 1) {
+ switch (c) {
+ case 0xE0: l = 0xA0; break;
+ case 0xED: h = 0x9F; break;
+ case 0xF0: l = 0x90; break;
+ case 0xF4: h = 0x8F; break;
+ }
+ }
+
+ if (p[i] < l || p[i] > h) {
+ skip = i; goto invalid_utf8_sequence;
+ }
+
+ n = (n << 6) | (p[i] & 0x3f);
+ }
+
+ /* advance pointer */
+ p += 1 + cont;
+ c = n;
+ goto add_char_nonext;
+
+ /* error handling */
+ invalid_utf8_sequence:
+ tcc_warning("ill-formed UTF-8 subsequence starting with: \'\\x%x\'", c);
+ c = 0xFFFD;
+ p += skip;
+ goto add_char_nonext;
+
+ }
+ p++;
+ add_char_nonext:
+ if (!is_long)
+ cstr_ccat(outstr, c);
+ else {
+#ifdef TCC_TARGET_PE
+ /* store as UTF-16 */
+ if (c < 0x10000) {
+ cstr_wccat(outstr, c);
+ } else {
+ c -= 0x10000;
+ cstr_wccat(outstr, (c >> 10) + 0xD800);
+ cstr_wccat(outstr, (c & 0x3FF) + 0xDC00);
+ }
+#else
+ cstr_wccat(outstr, c);
+#endif
+ }
+ }
+ /* add a trailing '\0' */
+ if (!is_long)
+ cstr_ccat(outstr, '\0');
+ else
+ cstr_wccat(outstr, '\0');
+}
+
+static void parse_string(const char *s, int len)
+{
+ uint8_t buf[1000], *p = buf;
+ int is_long, sep;
+
+ if ((is_long = *s == 'L'))
+ ++s, --len;
+ sep = *s++;
+ len -= 2;
+ if (len >= sizeof buf)
+ p = tcc_malloc(len + 1);
+ memcpy(p, s, len);
+ p[len] = 0;
+
+ cstr_reset(&tokcstr);
+ parse_escape_string(&tokcstr, p, is_long);
+ if (p != buf)
+ tcc_free(p);
+
+ if (sep == '\'') {
+ int char_size, i, n, c;
+ /* XXX: make it portable */
+ if (!is_long)
+ tok = TOK_CCHAR, char_size = 1;
+ else
+ tok = TOK_LCHAR, char_size = sizeof(nwchar_t);
+ n = tokcstr.size / char_size - 1;
+ if (n < 1)
+ tcc_error("empty character constant");
+ if (n > 1)
+ tcc_warning("multi-character character constant");
+ for (c = i = 0; i < n; ++i) {
+ if (is_long)
+ c = ((nwchar_t *)tokcstr.data)[i];
+ else
+ c = (c << 8) | ((char *)tokcstr.data)[i];
+ }
+ tokc.i = c;
+ } else {
+ tokc.str.size = tokcstr.size;
+ tokc.str.data = tokcstr.data;
+ if (!is_long)
+ tok = TOK_STR;
+ else
+ tok = TOK_LSTR;
+ }
+}
+
+/* we use 64 bit numbers */
+#define BN_SIZE 2
+
+/* bn = (bn << shift) | or_val */
+static void bn_lshift(unsigned int *bn, int shift, int or_val)
+{
+ int i;
+ unsigned int v;
+ for(i=0;i<BN_SIZE;i++) {
+ v = bn[i];
+ bn[i] = (v << shift) | or_val;
+ or_val = v >> (32 - shift);
+ }
+}
+
+static void bn_zero(unsigned int *bn)
+{
+ int i;
+ for(i=0;i<BN_SIZE;i++) {
+ bn[i] = 0;
+ }
+}
+
+/* parse number in null terminated string 'p' and return it in the
+ current token */
+static void parse_number(const char *p)
+{
+ int b, t, shift, frac_bits, s, exp_val, ch;
+ char *q;
+ unsigned int bn[BN_SIZE];
+ double d;
+
+ /* number */
+ q = token_buf;
+ ch = *p++;
+ t = ch;
+ ch = *p++;
+ *q++ = t;
+ b = 10;
+ if (t == '.') {
+ goto float_frac_parse;
+ } else if (t == '0') {
+ if (ch == 'x' || ch == 'X') {
+ q--;
+ ch = *p++;
+ b = 16;
+ } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
+ q--;
+ ch = *p++;
+ b = 2;
+ }
+ }
+ /* parse all digits. cannot check octal numbers at this stage
+ because of floating point constants */
+ while (1) {
+ if (ch >= 'a' && ch <= 'f')
+ t = ch - 'a' + 10;
+ else if (ch >= 'A' && ch <= 'F')
+ t = ch - 'A' + 10;
+ else if (isnum(ch))
+ t = ch - '0';
+ else
+ break;
+ if (t >= b)
+ break;
+ if (q >= token_buf + STRING_MAX_SIZE) {
+ num_too_long:
+ tcc_error("number too long");
+ }
+ *q++ = ch;
+ ch = *p++;
+ }
+ if (ch == '.' ||
+ ((ch == 'e' || ch == 'E') && b == 10) ||
+ ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
+ if (b != 10) {
+ /* NOTE: strtox should support that for hexa numbers, but
+ non ISOC99 libcs do not support it, so we prefer to do
+ it by hand */
+ /* hexadecimal or binary floats */
+ /* XXX: handle overflows */
+ *q = '\0';
+ if (b == 16)
+ shift = 4;
+ else
+ shift = 1;
+ bn_zero(bn);
+ q = token_buf;
+ while (1) {
+ t = *q++;
+ if (t == '\0') {
+ break;
+ } else if (t >= 'a') {
+ t = t - 'a' + 10;
+ } else if (t >= 'A') {
+ t = t - 'A' + 10;
+ } else {
+ t = t - '0';
+ }
+ bn_lshift(bn, shift, t);
+ }
+ frac_bits = 0;
+ if (ch == '.') {
+ ch = *p++;
+ while (1) {
+ t = ch;
+ if (t >= 'a' && t <= 'f') {
+ t = t - 'a' + 10;
+ } else if (t >= 'A' && t <= 'F') {
+ t = t - 'A' + 10;
+ } else if (t >= '0' && t <= '9') {
+ t = t - '0';
+ } else {
+ break;
+ }
+ if (t >= b)
+ tcc_error("invalid digit");
+ bn_lshift(bn, shift, t);
+ frac_bits += shift;
+ ch = *p++;
+ }
+ }
+ if (ch != 'p' && ch != 'P')
+ expect("exponent");
+ ch = *p++;
+ s = 1;
+ exp_val = 0;
+ if (ch == '+') {
+ ch = *p++;
+ } else if (ch == '-') {
+ s = -1;
+ ch = *p++;
+ }
+ if (ch < '0' || ch > '9')
+ expect("exponent digits");
+ while (ch >= '0' && ch <= '9') {
+ exp_val = exp_val * 10 + ch - '0';
+ ch = *p++;
+ }
+ exp_val = exp_val * s;
+
+ /* now we can generate the number */
+ /* XXX: should patch directly float number */
+ d = (double)bn[1] * 4294967296.0 + (double)bn[0];
+ d = ldexp(d, exp_val - frac_bits);
+ t = toup(ch);
+ if (t == 'F') {
+ ch = *p++;
+ tok = TOK_CFLOAT;
+ /* float : should handle overflow */
+ tokc.f = (float)d;
+ } else if (t == 'L') {
+ ch = *p++;
+#ifdef TCC_TARGET_PE
+ tok = TOK_CDOUBLE;
+ tokc.d = d;
+#else
+ tok = TOK_CLDOUBLE;
+ /* XXX: not large enough */
+ tokc.ld = (long double)d;
+#endif
+ } else {
+ tok = TOK_CDOUBLE;
+ tokc.d = d;
+ }
+ } else {
+ /* decimal floats */
+ if (ch == '.') {
+ if (q >= token_buf + STRING_MAX_SIZE)
+ goto num_too_long;
+ *q++ = ch;
+ ch = *p++;
+ float_frac_parse:
+ while (ch >= '0' && ch <= '9') {
+ if (q >= token_buf + STRING_MAX_SIZE)
+ goto num_too_long;
+ *q++ = ch;
+ ch = *p++;
+ }
+ }
+ if (ch == 'e' || ch == 'E') {
+ if (q >= token_buf + STRING_MAX_SIZE)
+ goto num_too_long;
+ *q++ = ch;
+ ch = *p++;
+ if (ch == '-' || ch == '+') {
+ if (q >= token_buf + STRING_MAX_SIZE)
+ goto num_too_long;
+ *q++ = ch;
+ ch = *p++;
+ }
+ if (ch < '0' || ch > '9')
+ expect("exponent digits");
+ while (ch >= '0' && ch <= '9') {
+ if (q >= token_buf + STRING_MAX_SIZE)
+ goto num_too_long;
+ *q++ = ch;
+ ch = *p++;
+ }
+ }
+ *q = '\0';
+ t = toup(ch);
+ errno = 0;
+ if (t == 'F') {
+ ch = *p++;
+ tok = TOK_CFLOAT;
+ tokc.f = strtof(token_buf, NULL);
+ } else if (t == 'L') {
+ ch = *p++;
+#ifdef TCC_TARGET_PE
+ tok = TOK_CDOUBLE;
+ tokc.d = strtod(token_buf, NULL);
+#else
+ tok = TOK_CLDOUBLE;
+ tokc.ld = strtold(token_buf, NULL);
+#endif
+ } else {
+ tok = TOK_CDOUBLE;
+ tokc.d = strtod(token_buf, NULL);
+ }
+ }
+ } else {
+ unsigned long long n, n1;
+ int lcount, ucount, ov = 0;
+ const char *p1;
+
+ /* integer number */
+ *q = '\0';
+ q = token_buf;
+ if (b == 10 && *q == '0') {
+ b = 8;
+ q++;
+ }
+ n = 0;
+ while(1) {
+ t = *q++;
+ /* no need for checks except for base 10 / 8 errors */
+ if (t == '\0')
+ break;
+ else if (t >= 'a')
+ t = t - 'a' + 10;
+ else if (t >= 'A')
+ t = t - 'A' + 10;
+ else
+ t = t - '0';
+ if (t >= b)
+ tcc_error("invalid digit");
+ n1 = n;
+ n = n * b + t;
+ /* detect overflow */
+ if (n1 >= 0x1000000000000000ULL && n / b != n1)
+ ov = 1;
+ }
+
+ /* Determine the characteristics (unsigned and/or 64bit) the type of
+ the constant must have according to the constant suffix(es) */
+ lcount = ucount = 0;
+ p1 = p;
+ for(;;) {
+ t = toup(ch);
+ if (t == 'L') {
+ if (lcount >= 2)
+ tcc_error("three 'l's in integer constant");
+ if (lcount && *(p - 1) != ch)
+ tcc_error("incorrect integer suffix: %s", p1);
+ lcount++;
+ ch = *p++;
+ } else if (t == 'U') {
+ if (ucount >= 1)
+ tcc_error("two 'u's in integer constant");
+ ucount++;
+ ch = *p++;
+ } else {
+ break;
+ }
+ }
+
+ /* Determine if it needs 64 bits and/or unsigned in order to fit */
+ if (ucount == 0 && b == 10) {
+ if (lcount <= (LONG_SIZE == 4)) {
+ if (n >= 0x80000000U)
+ lcount = (LONG_SIZE == 4) + 1;
+ }
+ if (n >= 0x8000000000000000ULL)
+ ov = 1, ucount = 1;
+ } else {
+ if (lcount <= (LONG_SIZE == 4)) {
+ if (n >= 0x100000000ULL)
+ lcount = (LONG_SIZE == 4) + 1;
+ else if (n >= 0x80000000U)
+ ucount = 1;
+ }
+ if (n >= 0x8000000000000000ULL)
+ ucount = 1;
+ }
+
+ if (ov)
+ tcc_warning("integer constant overflow");
+
+ tok = TOK_CINT;
+ if (lcount) {
+ tok = TOK_CLONG;
+ if (lcount == 2)
+ tok = TOK_CLLONG;
+ }
+ if (ucount)
+ ++tok; /* TOK_CU... */
+ tokc.i = n;
+ }
+ if (ch)
+ tcc_error("invalid number\n");
+}
+
+
+#define PARSE2(c1, tok1, c2, tok2) \
+ case c1: \
+ PEEKC(c, p); \
+ if (c == c2) { \
+ p++; \
+ tok = tok2; \
+ } else { \
+ tok = tok1; \
+ } \
+ break;
+
+/* return next token without macro substitution */
+static inline void next_nomacro1(void)
+{
+ int t, c, is_long, len;
+ TokenSym *ts;
+ uint8_t *p, *p1;
+ unsigned int h;
+
+ p = file->buf_ptr;
+ redo_no_start:
+ c = *p;
+ switch(c) {
+ case ' ':
+ case '\t':
+ tok = c;
+ p++;
+ if (parse_flags & PARSE_FLAG_SPACES)
+ goto keep_tok_flags;
+ while (isidnum_table[*p - CH_EOF] & IS_SPC)
+ ++p;
+ goto redo_no_start;
+ case '\f':
+ case '\v':
+ case '\r':
+ p++;
+ goto redo_no_start;
+ case '\\':
+ /* first look if it is in fact an end of buffer */
+ c = handle_stray1(p);
+ p = file->buf_ptr;
+ if (c == '\\')
+ goto parse_simple;
+ if (c != CH_EOF)
+ goto redo_no_start;
+ {
+ TCCState *s1 = tcc_state;
+ if ((parse_flags & PARSE_FLAG_LINEFEED)
+ && !(tok_flags & TOK_FLAG_EOF)) {
+ tok_flags |= TOK_FLAG_EOF;
+ tok = TOK_LINEFEED;
+ goto keep_tok_flags;
+ } else if (!(parse_flags & PARSE_FLAG_PREPROCESS)) {
+ tok = TOK_EOF;
+ } else if (s1->ifdef_stack_ptr != file->ifdef_stack_ptr) {
+ tcc_error("missing #endif");
+ } else if (s1->include_stack_ptr == s1->include_stack) {
+ /* no include left : end of file. */
+ tok = TOK_EOF;
+ } else {
+ tok_flags &= ~TOK_FLAG_EOF;
+ /* pop include file */
+
+ /* test if previous '#endif' was after a #ifdef at
+ start of file */
+ if (tok_flags & TOK_FLAG_ENDIF) {
+#ifdef INC_DEBUG
+ printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
+#endif
+ search_cached_include(s1, file->filename, 1)
+ ->ifndef_macro = file->ifndef_macro_saved;
+ tok_flags &= ~TOK_FLAG_ENDIF;
+ }
+
+ /* add end of include file debug info */
+ if (tcc_state->do_debug) {
+ put_stabd(N_EINCL, 0, 0);
+ }
+ /* pop include stack */
+ tcc_close();
+ s1->include_stack_ptr--;
+ p = file->buf_ptr;
+ if (p == file->buffer)
+ tok_flags = TOK_FLAG_BOF|TOK_FLAG_BOL;
+ goto redo_no_start;
+ }
+ }
+ break;
+
+ case '\n':
+ file->line_num++;
+ tok_flags |= TOK_FLAG_BOL;
+ p++;
+maybe_newline:
+ if (0 == (parse_flags & PARSE_FLAG_LINEFEED))
+ goto redo_no_start;
+ tok = TOK_LINEFEED;
+ goto keep_tok_flags;
+
+ case '#':
+ /* XXX: simplify */
+ PEEKC(c, p);
+ if ((tok_flags & TOK_FLAG_BOL) &&
+ (parse_flags & PARSE_FLAG_PREPROCESS)) {
+ file->buf_ptr = p;
+ preprocess(tok_flags & TOK_FLAG_BOF);
+ p = file->buf_ptr;
+ goto maybe_newline;
+ } else {
+ if (c == '#') {
+ p++;
+ tok = TOK_TWOSHARPS;
+ } else {
+ if (parse_flags & PARSE_FLAG_ASM_FILE) {
+ p = parse_line_comment(p - 1);
+ goto redo_no_start;
+ } else {
+ tok = '#';
+ }
+ }
+ }
+ break;
+
+ /* dollar is allowed to start identifiers when not parsing asm */
+ case '$':
+ if (!(isidnum_table[c - CH_EOF] & IS_ID)
+ || (parse_flags & PARSE_FLAG_ASM_FILE))
+ goto parse_simple;
+
+ case 'a': case 'b': case 'c': case 'd':
+ case 'e': case 'f': case 'g': case 'h':
+ case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': case 'p':
+ case 'q': case 'r': case 's': case 't':
+ case 'u': case 'v': case 'w': case 'x':
+ case 'y': case 'z':
+ case 'A': case 'B': case 'C': case 'D':
+ case 'E': case 'F': case 'G': case 'H':
+ case 'I': case 'J': case 'K':
+ case 'M': case 'N': case 'O': case 'P':
+ case 'Q': case 'R': case 'S': case 'T':
+ case 'U': case 'V': case 'W': case 'X':
+ case 'Y': case 'Z':
+ case '_':
+ parse_ident_fast:
+ p1 = p;
+ h = TOK_HASH_INIT;
+ h = TOK_HASH_FUNC(h, c);
+ while (c = *++p, isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
+ h = TOK_HASH_FUNC(h, c);
+ len = p - p1;
+ if (c != '\\') {
+ TokenSym **pts;
+
+ /* fast case : no stray found, so we have the full token
+ and we have already hashed it */
+ h &= (TOK_HASH_SIZE - 1);
+ pts = &hash_ident[h];
+ for(;;) {
+ ts = *pts;
+ if (!ts)
+ break;
+ if (ts->len == len && !memcmp(ts->str, p1, len))
+ goto token_found;
+ pts = &(ts->hash_next);
+ }
+ ts = tok_alloc_new(pts, (char *) p1, len);
+ token_found: ;
+ } else {
+ /* slower case */
+ cstr_reset(&tokcstr);
+ cstr_cat(&tokcstr, (char *) p1, len);
+ p--;
+ PEEKC(c, p);
+ parse_ident_slow:
+ while (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
+ {
+ cstr_ccat(&tokcstr, c);
+ PEEKC(c, p);
+ }
+ ts = tok_alloc(tokcstr.data, tokcstr.size);
+ }
+ tok = ts->tok;
+ break;
+ case 'L':
+ t = p[1];
+ if (t != '\\' && t != '\'' && t != '\"') {
+ /* fast case */
+ goto parse_ident_fast;
+ } else {
+ PEEKC(c, p);
+ if (c == '\'' || c == '\"') {
+ is_long = 1;
+ goto str_const;
+ } else {
+ cstr_reset(&tokcstr);
+ cstr_ccat(&tokcstr, 'L');
+ goto parse_ident_slow;
+ }
+ }
+ break;
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9':
+ t = c;
+ PEEKC(c, p);
+ /* after the first digit, accept digits, alpha, '.' or sign if
+ prefixed by 'eEpP' */
+ parse_num:
+ cstr_reset(&tokcstr);
+ for(;;) {
+ cstr_ccat(&tokcstr, t);
+ if (!((isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
+ || c == '.'
+ || ((c == '+' || c == '-')
+ && (((t == 'e' || t == 'E')
+ && !(parse_flags & PARSE_FLAG_ASM_FILE
+ /* 0xe+1 is 3 tokens in asm */
+ && ((char*)tokcstr.data)[0] == '0'
+ && toup(((char*)tokcstr.data)[1]) == 'X'))
+ || t == 'p' || t == 'P'))))
+ break;
+ t = c;
+ PEEKC(c, p);
+ }
+ /* We add a trailing '\0' to ease parsing */
+ cstr_ccat(&tokcstr, '\0');
+ tokc.str.size = tokcstr.size;
+ tokc.str.data = tokcstr.data;
+ tok = TOK_PPNUM;
+ break;
+
+ case '.':
+ /* special dot handling because it can also start a number */
+ PEEKC(c, p);
+ if (isnum(c)) {
+ t = '.';
+ goto parse_num;
+ } else if ((isidnum_table['.' - CH_EOF] & IS_ID)
+ && (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))) {
+ *--p = c = '.';
+ goto parse_ident_fast;
+ } else if (c == '.') {
+ PEEKC(c, p);
+ if (c == '.') {
+ p++;
+ tok = TOK_DOTS;
+ } else {
+ *--p = '.'; /* may underflow into file->unget[] */
+ tok = '.';
+ }
+ } else {
+ tok = '.';
+ }
+ break;
+ case '\'':
+ case '\"':
+ is_long = 0;
+ str_const:
+ cstr_reset(&tokcstr);
+ if (is_long)
+ cstr_ccat(&tokcstr, 'L');
+ cstr_ccat(&tokcstr, c);
+ p = parse_pp_string(p, c, &tokcstr);
+ cstr_ccat(&tokcstr, c);
+ cstr_ccat(&tokcstr, '\0');
+ tokc.str.size = tokcstr.size;
+ tokc.str.data = tokcstr.data;
+ tok = TOK_PPSTR;
+ break;
+
+ case '<':
+ PEEKC(c, p);
+ if (c == '=') {
+ p++;
+ tok = TOK_LE;
+ } else if (c == '<') {
+ PEEKC(c, p);
+ if (c == '=') {
+ p++;
+ tok = TOK_A_SHL;
+ } else {
+ tok = TOK_SHL;
+ }
+ } else {
+ tok = TOK_LT;
+ }
+ break;
+ case '>':
+ PEEKC(c, p);
+ if (c == '=') {
+ p++;
+ tok = TOK_GE;
+ } else if (c == '>') {
+ PEEKC(c, p);
+ if (c == '=') {
+ p++;
+ tok = TOK_A_SAR;
+ } else {
+ tok = TOK_SAR;
+ }
+ } else {
+ tok = TOK_GT;
+ }
+ break;
+
+ case '&':
+ PEEKC(c, p);
+ if (c == '&') {
+ p++;
+ tok = TOK_LAND;
+ } else if (c == '=') {
+ p++;
+ tok = TOK_A_AND;
+ } else {
+ tok = '&';
+ }
+ break;
+
+ case '|':
+ PEEKC(c, p);
+ if (c == '|') {
+ p++;
+ tok = TOK_LOR;
+ } else if (c == '=') {
+ p++;
+ tok = TOK_A_OR;
+ } else {
+ tok = '|';
+ }
+ break;
+
+ case '+':
+ PEEKC(c, p);
+ if (c == '+') {
+ p++;
+ tok = TOK_INC;
+ } else if (c == '=') {
+ p++;
+ tok = TOK_A_ADD;
+ } else {
+ tok = '+';
+ }
+ break;
+
+ case '-':
+ PEEKC(c, p);
+ if (c == '-') {
+ p++;
+ tok = TOK_DEC;
+ } else if (c == '=') {
+ p++;
+ tok = TOK_A_SUB;
+ } else if (c == '>') {
+ p++;
+ tok = TOK_ARROW;
+ } else {
+ tok = '-';
+ }
+ break;
+
+ PARSE2('!', '!', '=', TOK_NE)
+ PARSE2('=', '=', '=', TOK_EQ)
+ PARSE2('*', '*', '=', TOK_A_MUL)
+ PARSE2('%', '%', '=', TOK_A_MOD)
+ PARSE2('^', '^', '=', TOK_A_XOR)
+
+ /* comments or operator */
+ case '/':
+ PEEKC(c, p);
+ if (c == '*') {
+ p = parse_comment(p);
+ /* comments replaced by a blank */
+ tok = ' ';
+ goto keep_tok_flags;
+ } else if (c == '/') {
+ p = parse_line_comment(p);
+ tok = ' ';
+ goto keep_tok_flags;
+ } else if (c == '=') {
+ p++;
+ tok = TOK_A_DIV;
+ } else {
+ tok = '/';
+ }
+ break;
+
+ /* simple tokens */
+ case '(':
+ case ')':
+ case '[':
+ case ']':
+ case '{':
+ case '}':
+ case ',':
+ case ';':
+ case ':':
+ case '?':
+ case '~':
+ case '@': /* only used in assembler */
+ parse_simple:
+ tok = c;
+ p++;
+ break;
+ default:
+ if (c >= 0x80 && c <= 0xFF) /* utf8 identifiers */
+ goto parse_ident_fast;
+ if (parse_flags & PARSE_FLAG_ASM_FILE)
+ goto parse_simple;
+ tcc_error("unrecognized character \\x%02x", c);
+ break;
+ }
+ tok_flags = 0;
+keep_tok_flags:
+ file->buf_ptr = p;
+#if defined(PARSE_DEBUG)
+ printf("token = %d %s\n", tok, get_tok_str(tok, &tokc));
+#endif
+}
+
+/* return next token without macro substitution. Can read input from
+ macro_ptr buffer */
+static void next_nomacro_spc(void)
+{
+ if (macro_ptr) {
+ redo:
+ tok = *macro_ptr;
+ if (tok) {
+ TOK_GET(&tok, &macro_ptr, &tokc);
+ if (tok == TOK_LINENUM) {
+ file->line_num = tokc.i;
+ goto redo;
+ }
+ }
+ } else {
+ next_nomacro1();
+ }
+ //printf("token = %s\n", get_tok_str(tok, &tokc));
+}
+
+ST_FUNC void next_nomacro(void)
+{
+ do {
+ next_nomacro_spc();
+ } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC));
+}
+
+
+static void macro_subst(
+ TokenString *tok_str,
+ Sym **nested_list,
+ const int *macro_str
+ );
+
+/* substitute arguments in replacement lists in macro_str by the values in
+ args (field d) and return allocated string */
+static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
+{
+ int t, t0, t1, spc;
+ const int *st;
+ Sym *s;
+ CValue cval;
+ TokenString str;
+ CString cstr;
+
+ tok_str_new(&str);
+ t0 = t1 = 0;
+ while(1) {
+ TOK_GET(&t, &macro_str, &cval);
+ if (!t)
+ break;
+ if (t == '#') {
+ /* stringize */
+ TOK_GET(&t, &macro_str, &cval);
+ if (!t)
+ goto bad_stringy;
+ s = sym_find2(args, t);
+ if (s) {
+ cstr_new(&cstr);
+ cstr_ccat(&cstr, '\"');
+ st = s->d;
+ spc = 0;
+ while (*st >= 0) {
+ TOK_GET(&t, &st, &cval);
+ if (t != TOK_PLCHLDR
+ && t != TOK_NOSUBST
+ && 0 == check_space(t, &spc)) {
+ const char *s = get_tok_str(t, &cval);
+ while (*s) {
+ if (t == TOK_PPSTR && *s != '\'')
+ add_char(&cstr, *s);
+ else
+ cstr_ccat(&cstr, *s);
+ ++s;
+ }
+ }
+ }
+ cstr.size -= spc;
+ cstr_ccat(&cstr, '\"');
+ cstr_ccat(&cstr, '\0');
+#ifdef PP_DEBUG
+ printf("\nstringize: <%s>\n", (char *)cstr.data);
+#endif
+ /* add string */
+ cval.str.size = cstr.size;
+ cval.str.data = cstr.data;
+ tok_str_add2(&str, TOK_PPSTR, &cval);
+ cstr_free(&cstr);
+ } else {
+ bad_stringy:
+ expect("macro parameter after '#'");
+ }
+ } else if (t >= TOK_IDENT) {
+ s = sym_find2(args, t);
+ if (s) {
+ int l0 = str.len;
+ st = s->d;
+ /* if '##' is present before or after, no arg substitution */
+ if (*macro_str == TOK_PPJOIN || t1 == TOK_PPJOIN) {
+ /* special case for var arg macros : ## eats the ','
+ if empty VA_ARGS variable. */
+ if (t1 == TOK_PPJOIN && t0 == ',' && gnu_ext && s->type.t) {
+ if (*st <= 0) {
+ /* suppress ',' '##' */
+ str.len -= 2;
+ } else {
+ /* suppress '##' and add variable */
+ str.len--;
+ goto add_var;
+ }
+ }
+ } else {
+ add_var:
+ if (!s->next) {
+ /* Expand arguments tokens and store them. In most
+ cases we could also re-expand each argument if
+ used multiple times, but not if the argument
+ contains the __COUNTER__ macro. */
+ TokenString str2;
+ sym_push2(&s->next, s->v, s->type.t, 0);
+ tok_str_new(&str2);
+ macro_subst(&str2, nested_list, st);
+ tok_str_add(&str2, 0);
+ s->next->d = str2.str;
+ }
+ st = s->next->d;
+ }
+ for(;;) {
+ int t2;
+ TOK_GET(&t2, &st, &cval);
+ if (t2 <= 0)
+ break;
+ tok_str_add2(&str, t2, &cval);
+ }
+ if (str.len == l0) /* expanded to empty string */
+ tok_str_add(&str, TOK_PLCHLDR);
+ } else {
+ tok_str_add(&str, t);
+ }
+ } else {
+ tok_str_add2(&str, t, &cval);
+ }
+ t0 = t1, t1 = t;
+ }
+ tok_str_add(&str, 0);
+ return str.str;
+}
+
+static char const ab_month_name[12][4] =
+{
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2)
+{
+ CString cstr;
+ int n, ret = 1;
+
+ cstr_new(&cstr);
+ if (t1 != TOK_PLCHLDR)
+ cstr_cat(&cstr, get_tok_str(t1, v1), -1);
+ n = cstr.size;
+ if (t2 != TOK_PLCHLDR)
+ cstr_cat(&cstr, get_tok_str(t2, v2), -1);
+ cstr_ccat(&cstr, '\0');
+
+ tcc_open_bf(tcc_state, ":paste:", cstr.size);
+ memcpy(file->buffer, cstr.data, cstr.size);
+ tok_flags = 0;
+ for (;;) {
+ next_nomacro1();
+ if (0 == *file->buf_ptr)
+ break;
+ if (is_space(tok))
+ continue;
+ tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid"
+ " preprocessing token", n, cstr.data, (char*)cstr.data + n);
+ ret = 0;
+ break;
+ }
+ tcc_close();
+ //printf("paste <%s>\n", (char*)cstr.data);
+ cstr_free(&cstr);
+ return ret;
+}
+
+/* handle the '##' operator. Return NULL if no '##' seen. Otherwise
+ return the resulting string (which must be freed). */
+static inline int *macro_twosharps(const int *ptr0)
+{
+ int t;
+ CValue cval;
+ TokenString macro_str1;
+ int start_of_nosubsts = -1;
+ const int *ptr;
+
+ /* we search the first '##' */
+ for (ptr = ptr0;;) {
+ TOK_GET(&t, &ptr, &cval);
+ if (t == TOK_PPJOIN)
+ break;
+ if (t == 0)
+ return NULL;
+ }
+
+ tok_str_new(&macro_str1);
+
+ //tok_print(" $$$", ptr0);
+ for (ptr = ptr0;;) {
+ TOK_GET(&t, &ptr, &cval);
+ if (t == 0)
+ break;
+ if (t == TOK_PPJOIN)
+ continue;
+ while (*ptr == TOK_PPJOIN) {
+ int t1; CValue cv1;
+ /* given 'a##b', remove nosubsts preceding 'a' */
+ if (start_of_nosubsts >= 0)
+ macro_str1.len = start_of_nosubsts;
+ /* given 'a##b', remove nosubsts preceding 'b' */
+ while ((t1 = *++ptr) == TOK_NOSUBST)
+ ;
+ if (t1 && t1 != TOK_PPJOIN) {
+ TOK_GET(&t1, &ptr, &cv1);
+ if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) {
+ if (paste_tokens(t, &cval, t1, &cv1)) {
+ t = tok, cval = tokc;
+ } else {
+ tok_str_add2(&macro_str1, t, &cval);
+ t = t1, cval = cv1;
+ }
+ }
+ }
+ }
+ if (t == TOK_NOSUBST) {
+ if (start_of_nosubsts < 0)
+ start_of_nosubsts = macro_str1.len;
+ } else {
+ start_of_nosubsts = -1;
+ }
+ tok_str_add2(&macro_str1, t, &cval);
+ }
+ tok_str_add(&macro_str1, 0);
+ //tok_print(" ###", macro_str1.str);
+ return macro_str1.str;
+}
+
+/* peek or read [ws_str == NULL] next token from function macro call,
+ walking up macro levels up to the file if necessary */
+static int next_argstream(Sym **nested_list, TokenString *ws_str)
+{
+ int t;
+ const int *p;
+ Sym *sa;
+
+ for (;;) {
+ if (macro_ptr) {
+ p = macro_ptr, t = *p;
+ if (ws_str) {
+ while (is_space(t) || TOK_LINEFEED == t || TOK_PLCHLDR == t)
+ tok_str_add(ws_str, t), t = *++p;
+ }
+ if (t == 0) {
+ end_macro();
+ /* also, end of scope for nested defined symbol */
+ sa = *nested_list;
+ while (sa && sa->v == 0)
+ sa = sa->prev;
+ if (sa)
+ sa->v = 0;
+ continue;
+ }
+ } else {
+ ch = handle_eob();
+ if (ws_str) {
+ while (is_space(ch) || ch == '\n' || ch == '/') {
+ if (ch == '/') {
+ int c;
+ uint8_t *p = file->buf_ptr;
+ PEEKC(c, p);
+ if (c == '*') {
+ p = parse_comment(p);
+ file->buf_ptr = p - 1;
+ } else if (c == '/') {
+ p = parse_line_comment(p);
+ file->buf_ptr = p - 1;
+ } else
+ break;
+ ch = ' ';
+ }
+ if (ch == '\n')
+ file->line_num++;
+ if (!(ch == '\f' || ch == '\v' || ch == '\r'))
+ tok_str_add(ws_str, ch);
+ cinp();
+ }
+ }
+ t = ch;
+ }
+
+ if (ws_str)
+ return t;
+ next_nomacro_spc();
+ return tok;
+ }
+}
+
+/* do macro substitution of current token with macro 's' and add
+ result to (tok_str,tok_len). 'nested_list' is the list of all
+ macros we got inside to avoid recursing. Return non zero if no
+ substitution needs to be done */
+static int macro_subst_tok(
+ TokenString *tok_str,
+ Sym **nested_list,
+ Sym *s)
+{
+ Sym *args, *sa, *sa1;
+ int parlevel, t, t1, spc;
+ TokenString str;
+ char *cstrval;
+ CValue cval;
+ CString cstr;
+ char buf[32];
+
+ /* if symbol is a macro, prepare substitution */
+ /* special macros */
+ if (tok == TOK___LINE__ || tok == TOK___COUNTER__) {
+ t = tok == TOK___LINE__ ? file->line_num : pp_counter++;
+ snprintf(buf, sizeof(buf), "%d", t);
+ cstrval = buf;
+ t1 = TOK_PPNUM;
+ goto add_cstr1;
+ } else if (tok == TOK___FILE__) {
+ cstrval = file->filename;
+ goto add_cstr;
+ } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
+ time_t ti;
+ struct tm *tm;
+
+ time(&ti);
+ tm = localtime(&ti);
+ if (tok == TOK___DATE__) {
+ snprintf(buf, sizeof(buf), "%s %2d %d",
+ ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
+ } else {
+ snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ }
+ cstrval = buf;
+ add_cstr:
+ t1 = TOK_STR;
+ add_cstr1:
+ cstr_new(&cstr);
+ cstr_cat(&cstr, cstrval, 0);
+ cval.str.size = cstr.size;
+ cval.str.data = cstr.data;
+ tok_str_add2(tok_str, t1, &cval);
+ cstr_free(&cstr);
+ } else if (s->d) {
+ int saved_parse_flags = parse_flags;
+ int *joined_str = NULL;
+ int *mstr = s->d;
+
+ if (s->type.t == MACRO_FUNC) {
+ /* whitespace between macro name and argument list */
+ TokenString ws_str;
+ tok_str_new(&ws_str);
+
+ spc = 0;
+ parse_flags |= PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED
+ | PARSE_FLAG_ACCEPT_STRAYS;
+
+ /* get next token from argument stream */
+ t = next_argstream(nested_list, &ws_str);
+ if (t != '(') {
+ /* not a macro substitution after all, restore the
+ * macro token plus all whitespace we've read.
+ * whitespace is intentionally not merged to preserve
+ * newlines. */
+ parse_flags = saved_parse_flags;
+ tok_str_add(tok_str, tok);
+ if (parse_flags & PARSE_FLAG_SPACES) {
+ int i;
+ for (i = 0; i < ws_str.len; i++)
+ tok_str_add(tok_str, ws_str.str[i]);
+ }
+ tok_str_free_str(ws_str.str);
+ return 0;
+ } else {
+ tok_str_free_str(ws_str.str);
+ }
+ do {
+ next_nomacro(); /* eat '(' */
+ } while (tok == TOK_PLCHLDR);
+
+ /* argument macro */
+ args = NULL;
+ sa = s->next;
+ /* NOTE: empty args are allowed, except if no args */
+ for(;;) {
+ do {
+ next_argstream(nested_list, NULL);
+ } while (is_space(tok) || TOK_LINEFEED == tok);
+ empty_arg:
+ /* handle '()' case */
+ if (!args && !sa && tok == ')')
+ break;
+ if (!sa)
+ tcc_error("macro '%s' used with too many args",
+ get_tok_str(s->v, 0));
+ tok_str_new(&str);
+ parlevel = spc = 0;
+ /* NOTE: non zero sa->t indicates VA_ARGS */
+ while ((parlevel > 0 ||
+ (tok != ')' &&
+ (tok != ',' || sa->type.t)))) {
+ if (tok == TOK_EOF || tok == 0)
+ break;
+ if (tok == '(')
+ parlevel++;
+ else if (tok == ')')
+ parlevel--;
+ if (tok == TOK_LINEFEED)
+ tok = ' ';
+ if (!check_space(tok, &spc))
+ tok_str_add2(&str, tok, &tokc);
+ next_argstream(nested_list, NULL);
+ }
+ if (parlevel)
+ expect(")");
+ str.len -= spc;
+ tok_str_add(&str, -1);
+ tok_str_add(&str, 0);
+ sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);
+ sa1->d = str.str;
+ sa = sa->next;
+ if (tok == ')') {
+ /* special case for gcc var args: add an empty
+ var arg argument if it is omitted */
+ if (sa && sa->type.t && gnu_ext)
+ goto empty_arg;
+ break;
+ }
+ if (tok != ',')
+ expect(",");
+ }
+ if (sa) {
+ tcc_error("macro '%s' used with too few args",
+ get_tok_str(s->v, 0));
+ }
+
+ parse_flags = saved_parse_flags;
+
+ /* now subst each arg */
+ mstr = macro_arg_subst(nested_list, mstr, args);
+ /* free memory */
+ sa = args;
+ while (sa) {
+ sa1 = sa->prev;
+ tok_str_free_str(sa->d);
+ if (sa->next) {
+ tok_str_free_str(sa->next->d);
+ sym_free(sa->next);
+ }
+ sym_free(sa);
+ sa = sa1;
+ }
+ }
+
+ sym_push2(nested_list, s->v, 0, 0);
+ parse_flags = saved_parse_flags;
+ joined_str = macro_twosharps(mstr);
+ macro_subst(tok_str, nested_list, joined_str ? joined_str : mstr);
+
+ /* pop nested defined symbol */
+ sa1 = *nested_list;
+ *nested_list = sa1->prev;
+ sym_free(sa1);
+ if (joined_str)
+ tok_str_free_str(joined_str);
+ if (mstr != s->d)
+ tok_str_free_str(mstr);
+ }
+ return 0;
+}
+
+/* do macro substitution of macro_str and add result to
+ (tok_str,tok_len). 'nested_list' is the list of all macros we got
+ inside to avoid recursing. */
+static void macro_subst(
+ TokenString *tok_str,
+ Sym **nested_list,
+ const int *macro_str
+ )
+{
+ Sym *s;
+ int t, spc, nosubst;
+ CValue cval;
+
+ spc = nosubst = 0;
+
+ while (1) {
+ TOK_GET(&t, &macro_str, &cval);
+ if (t <= 0)
+ break;
+
+ if (t >= TOK_IDENT && 0 == nosubst) {
+ s = define_find(t);
+ if (s == NULL)
+ goto no_subst;
+
+ /* if nested substitution, do nothing */
+ if (sym_find2(*nested_list, t)) {
+ /* and mark it as TOK_NOSUBST, so it doesn't get subst'd again */
+ tok_str_add2(tok_str, TOK_NOSUBST, NULL);
+ goto no_subst;
+ }
+
+ {
+ TokenString str;
+ str.str = (int*)macro_str;
+ begin_macro(&str, 2);
+
+ tok = t;
+ macro_subst_tok(tok_str, nested_list, s);
+
+ if (str.alloc == 3) {
+ /* already finished by reading function macro arguments */
+ break;
+ }
+
+ macro_str = macro_ptr;
+ end_macro ();
+ }
+ if (tok_str->len)
+ spc = is_space(t = tok_str->str[tok_str->lastlen]);
+ } else {
+ if (t == '\\' && !(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
+ tcc_error("stray '\\' in program");
+no_subst:
+ if (!check_space(t, &spc))
+ tok_str_add2(tok_str, t, &cval);
+
+ if (nosubst) {
+ if (nosubst > 1 && (spc || (++nosubst == 3 && t == '(')))
+ continue;
+ nosubst = 0;
+ }
+ if (t == TOK_NOSUBST)
+ nosubst = 1;
+ }
+ /* GCC supports 'defined' as result of a macro substitution */
+ if (t == TOK_DEFINED && pp_expr)
+ nosubst = 2;
+ }
+}
+
+/* return next token with macro substitution */
+ST_FUNC void next(void)
+{
+ redo:
+ if (parse_flags & PARSE_FLAG_SPACES)
+ next_nomacro_spc();
+ else
+ next_nomacro();
+
+ if (macro_ptr) {
+ if (tok == TOK_NOSUBST || tok == TOK_PLCHLDR) {
+ /* discard preprocessor markers */
+ goto redo;
+ } else if (tok == 0) {
+ /* end of macro or unget token string */
+ end_macro();
+ goto redo;
+ }
+ } else if (tok >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) {
+ Sym *s;
+ /* if reading from file, try to substitute macros */
+ s = define_find(tok);
+ if (s) {
+ Sym *nested_list = NULL;
+ tokstr_buf.len = 0;
+ macro_subst_tok(&tokstr_buf, &nested_list, s);
+ tok_str_add(&tokstr_buf, 0);
+ begin_macro(&tokstr_buf, 2);
+ goto redo;
+ }
+ }
+ /* convert preprocessor tokens into C tokens */
+ if (tok == TOK_PPNUM) {
+ if (parse_flags & PARSE_FLAG_TOK_NUM)
+ parse_number((char *)tokc.str.data);
+ } else if (tok == TOK_PPSTR) {
+ if (parse_flags & PARSE_FLAG_TOK_STR)
+ parse_string((char *)tokc.str.data, tokc.str.size - 1);
+ }
+}
+
+/* push back current token and set current token to 'last_tok'. Only
+ identifier case handled for labels. */
+ST_INLN void unget_tok(int last_tok)
+{
+
+ TokenString *str = tok_str_alloc();
+ tok_str_add2(str, tok, &tokc);
+ tok_str_add(str, 0);
+ begin_macro(str, 1);
+ tok = last_tok;
+}
+
+ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
+{
+ CString cstr;
+ int i;
+
+ s1->include_stack_ptr = s1->include_stack;
+ s1->ifdef_stack_ptr = s1->ifdef_stack;
+ file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
+ pp_expr = 0;
+ pp_counter = 0;
+ pp_debug_tok = pp_debug_symv = 0;
+ pp_once++;
+ pvtop = vtop = vstack - 1;
+ s1->pack_stack[0] = 0;
+ s1->pack_stack_ptr = s1->pack_stack;
+
+ set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
+ set_idnum('.', is_asm ? IS_ID : 0);
+
+ cstr_new(&cstr);
+ cstr_cat(&cstr, "\"", -1);
+ cstr_cat(&cstr, file->filename, -1);
+ cstr_cat(&cstr, "\"", 0);
+ tcc_define_symbol(s1, "__BASE_FILE__", cstr.data);
+
+ cstr_reset(&cstr);
+ for (i = 0; i < s1->nb_cmd_include_files; i++) {
+ cstr_cat(&cstr, "#include \"", -1);
+ cstr_cat(&cstr, s1->cmd_include_files[i], -1);
+ cstr_cat(&cstr, "\"\n", -1);
+ }
+ if (cstr.size) {
+ *s1->include_stack_ptr++ = file;
+ tcc_open_bf(s1, "<command line>", cstr.size);
+ memcpy(file->buffer, cstr.data, cstr.size);
+ }
+ cstr_free(&cstr);
+
+ if (is_asm)
+ tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
+
+ parse_flags = is_asm ? PARSE_FLAG_ASM_FILE : 0;
+ tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
+}
+
+/* cleanup from error/setjmp */
+ST_FUNC void preprocess_end(TCCState *s1)
+{
+ while (macro_stack)
+ end_macro();
+ macro_ptr = NULL;
+}
+
+ST_FUNC void tccpp_new(TCCState *s)
+{
+ int i, c;
+ const char *p, *r;
+
+ /* might be used in error() before preprocess_start() */
+ s->include_stack_ptr = s->include_stack;
+ s->ppfp = stdout;
+
+ /* init isid table */
+ for(i = CH_EOF; i<128; i++)
+ set_idnum(i,
+ is_space(i) ? IS_SPC
+ : isid(i) ? IS_ID
+ : isnum(i) ? IS_NUM
+ : 0);
+
+ for(i = 128; i<256; i++)
+ set_idnum(i, IS_ID);
+
+ /* init allocators */
+ tal_new(&toksym_alloc, TOKSYM_TAL_LIMIT, TOKSYM_TAL_SIZE);
+ tal_new(&tokstr_alloc, TOKSTR_TAL_LIMIT, TOKSTR_TAL_SIZE);
+ tal_new(&cstr_alloc, CSTR_TAL_LIMIT, CSTR_TAL_SIZE);
+
+ memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
+ cstr_new(&cstr_buf);
+ cstr_realloc(&cstr_buf, STRING_MAX_SIZE);
+ tok_str_new(&tokstr_buf);
+ tok_str_realloc(&tokstr_buf, TOKSTR_MAX_SIZE);
+
+ tok_ident = TOK_IDENT;
+ p = tcc_keywords;
+ while (*p) {
+ r = p;
+ for(;;) {
+ c = *r++;
+ if (c == '\0')
+ break;
+ }
+ tok_alloc(p, r - p - 1);
+ p = r;
+ }
+}
+
+ST_FUNC void tccpp_delete(TCCState *s)
+{
+ int i, n;
+
+ /* free -D and compiler defines */
+ free_defines(NULL);
+
+ /* free tokens */
+ n = tok_ident - TOK_IDENT;
+ for(i = 0; i < n; i++)
+ tal_free(toksym_alloc, table_ident[i]);
+ tcc_free(table_ident);
+ table_ident = NULL;
+
+ /* free static buffers */
+ cstr_free(&tokcstr);
+ cstr_free(&cstr_buf);
+ cstr_free(&macro_equal_buf);
+ tok_str_free_str(tokstr_buf.str);
+
+ /* free allocators */
+ tal_delete(toksym_alloc);
+ toksym_alloc = NULL;
+ tal_delete(tokstr_alloc);
+ tokstr_alloc = NULL;
+ tal_delete(cstr_alloc);
+ cstr_alloc = NULL;
+}
+
+/* ------------------------------------------------------------------------- */
+/* tcc -E [-P[1]] [-dD} support */
+
+static void tok_print(const char *msg, const int *str)
+{
+ FILE *fp;
+ int t, s = 0;
+ CValue cval;
+
+ fp = tcc_state->ppfp;
+ fprintf(fp, "%s", msg);
+ while (str) {
+ TOK_GET(&t, &str, &cval);
+ if (!t)
+ break;
+ fprintf(fp, " %s" + s, get_tok_str(t, &cval)), s = 1;
+ }
+ fprintf(fp, "\n");
+}
+
+static void pp_line(TCCState *s1, BufferedFile *f, int level)
+{
+ int d = f->line_num - f->line_ref;
+
+ if (s1->dflag & 4)
+ return;
+
+ if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE) {
+ ;
+ } else if (level == 0 && f->line_ref && d < 8) {
+ while (d > 0)
+ fputs("\n", s1->ppfp), --d;
+ } else if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) {
+ fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename);
+ } else {
+ fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename,
+ level > 0 ? " 1" : level < 0 ? " 2" : "");
+ }
+ f->line_ref = f->line_num;
+}
+
+static void define_print(TCCState *s1, int v)
+{
+ FILE *fp;
+ Sym *s;
+
+ s = define_find(v);
+ if (NULL == s || NULL == s->d)
+ return;
+
+ fp = s1->ppfp;
+ fprintf(fp, "#define %s", get_tok_str(v, NULL));
+ if (s->type.t == MACRO_FUNC) {
+ Sym *a = s->next;
+ fprintf(fp,"(");
+ if (a)
+ for (;;) {
+ fprintf(fp,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL));
+ if (!(a = a->next))
+ break;
+ fprintf(fp,",");
+ }
+ fprintf(fp,")");
+ }
+ tok_print("", s->d);
+}
+
+static void pp_debug_defines(TCCState *s1)
+{
+ int v, t;
+ const char *vs;
+ FILE *fp;
+
+ t = pp_debug_tok;
+ if (t == 0)
+ return;
+
+ file->line_num--;
+ pp_line(s1, file, 0);
+ file->line_ref = ++file->line_num;
+
+ fp = s1->ppfp;
+ v = pp_debug_symv;
+ vs = get_tok_str(v, NULL);
+ if (t == TOK_DEFINE) {
+ define_print(s1, v);
+ } else if (t == TOK_UNDEF) {
+ fprintf(fp, "#undef %s\n", vs);
+ } else if (t == TOK_push_macro) {
+ fprintf(fp, "#pragma push_macro(\"%s\")\n", vs);
+ } else if (t == TOK_pop_macro) {
+ fprintf(fp, "#pragma pop_macro(\"%s\")\n", vs);
+ }
+ pp_debug_tok = 0;
+}
+
+static void pp_debug_builtins(TCCState *s1)
+{
+ int v;
+ for (v = TOK_IDENT; v < tok_ident; ++v)
+ define_print(s1, v);
+}
+
+/* Add a space between tokens a and b to avoid unwanted textual pasting */
+static int pp_need_space(int a, int b)
+{
+ return 'E' == a ? '+' == b || '-' == b
+ : '+' == a ? TOK_INC == b || '+' == b
+ : '-' == a ? TOK_DEC == b || '-' == b
+ : a >= TOK_IDENT ? b >= TOK_IDENT
+ : a == TOK_PPNUM ? b >= TOK_IDENT
+ : 0;
+}
+
+/* maybe hex like 0x1e */
+static int pp_check_he0xE(int t, const char *p)
+{
+ if (t == TOK_PPNUM && toup(strchr(p, 0)[-1]) == 'E')
+ return 'E';
+ return t;
+}
+
+/* Preprocess the current file */
+ST_FUNC int tcc_preprocess(TCCState *s1)
+{
+ BufferedFile **iptr;
+ int token_seen, spcs, level;
+ const char *p;
+ char white[400];
+
+ parse_flags = PARSE_FLAG_PREPROCESS
+ | (parse_flags & PARSE_FLAG_ASM_FILE)
+ | PARSE_FLAG_LINEFEED
+ | PARSE_FLAG_SPACES
+ | PARSE_FLAG_ACCEPT_STRAYS
+ ;
+ /* Credits to Fabrice Bellard's initial revision to demonstrate its
+ capability to compile and run itself, provided all numbers are
+ given as decimals. tcc -E -P10 will do. */
+ if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_P10)
+ parse_flags |= PARSE_FLAG_TOK_NUM, s1->Pflag = 1;
+
+#ifdef PP_BENCH
+ /* for PP benchmarks */
+ do next(); while (tok != TOK_EOF);
+ return 0;
+#endif
+
+ if (s1->dflag & 1) {
+ pp_debug_builtins(s1);
+ s1->dflag &= ~1;
+ }
+
+ token_seen = TOK_LINEFEED, spcs = 0;
+ pp_line(s1, file, 0);
+ for (;;) {
+ iptr = s1->include_stack_ptr;
+ next();
+ if (tok == TOK_EOF)
+ break;
+
+ level = s1->include_stack_ptr - iptr;
+ if (level) {
+ if (level > 0)
+ pp_line(s1, *iptr, 0);
+ pp_line(s1, file, level);
+ }
+ if (s1->dflag & 7) {
+ pp_debug_defines(s1);
+ if (s1->dflag & 4)
+ continue;
+ }
+
+ if (is_space(tok)) {
+ if (spcs < sizeof white - 1)
+ white[spcs++] = tok;
+ continue;
+ } else if (tok == TOK_LINEFEED) {
+ spcs = 0;
+ if (token_seen == TOK_LINEFEED)
+ continue;
+ ++file->line_ref;
+ } else if (token_seen == TOK_LINEFEED) {
+ pp_line(s1, file, 0);
+ } else if (spcs == 0 && pp_need_space(token_seen, tok)) {
+ white[spcs++] = ' ';
+ }
+
+ white[spcs] = 0, fputs(white, s1->ppfp), spcs = 0;
+ fputs(p = get_tok_str(tok, &tokc), s1->ppfp);
+ token_seen = pp_check_he0xE(tok, p);
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/tccrun.c b/tccrun.c
new file mode 100644
index 0000000..9360164
--- /dev/null
+++ b/tccrun.c
@@ -0,0 +1,844 @@
+/*
+ * TCC - Tiny C Compiler - Support for -run switch
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tcc.h"
+
+/* only native compiler supports -run */
+#ifdef TCC_IS_NATIVE
+
+#ifndef _WIN32
+# include <sys/mman.h>
+#endif
+
+#ifdef CONFIG_TCC_BACKTRACE
+# ifndef _WIN32
+# include <signal.h>
+# ifndef __OpenBSD__
+# include <sys/ucontext.h>
+# endif
+# else
+# define ucontext_t CONTEXT
+# endif
+ST_DATA int rt_num_callers = 6;
+ST_DATA const char **rt_bound_error_msg;
+ST_DATA void *rt_prog_main;
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level);
+static void rt_error(ucontext_t *uc, const char *fmt, ...);
+static void set_exception_handler(void);
+#endif
+
+static void set_pages_executable(void *ptr, unsigned long length);
+static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff);
+
+#ifdef _WIN64
+static void *win64_add_function_table(TCCState *s1);
+static void win64_del_function_table(void *);
+#endif
+
+/* ------------------------------------------------------------- */
+/* Do all relocations (needed before using tcc_get_symbol())
+ Returns -1 on error. */
+
+LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr)
+{
+ int size;
+ addr_t ptr_diff = 0;
+
+ if (TCC_RELOCATE_AUTO != ptr)
+ return tcc_relocate_ex(s1, ptr, 0);
+
+ size = tcc_relocate_ex(s1, NULL, 0);
+ if (size < 0)
+ return -1;
+
+#ifdef HAVE_SELINUX
+{
+ /* Using mmap instead of malloc */
+ void *prx;
+ char tmpfname[] = "/tmp/.tccrunXXXXXX";
+ int fd = mkstemp(tmpfname);
+ unlink(tmpfname);
+ ftruncate(fd, size);
+
+ ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED || prx == MAP_FAILED)
+ tcc_error("tccrun: could not map memory");
+ dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
+ dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, prx);
+ ptr_diff = (char*)prx - (char*)ptr;
+}
+#else
+ ptr = tcc_malloc(size);
+#endif
+ tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */
+ dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
+ return 0;
+}
+
+ST_FUNC void tcc_run_free(TCCState *s1)
+{
+ int i;
+
+ for (i = 0; i < s1->nb_runtime_mem; ++i) {
+#ifdef HAVE_SELINUX
+ unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++];
+ munmap(s1->runtime_mem[i++], size);
+ munmap(s1->runtime_mem[i], size);
+#else
+#ifdef _WIN64
+ win64_del_function_table(*(void**)s1->runtime_mem[i]);
+#endif
+ tcc_free(s1->runtime_mem[i]);
+#endif
+ }
+ tcc_free(s1->runtime_mem);
+}
+
+/* launch the compiled program with the given arguments */
+LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
+{
+ int (*prog_main)(int, char **);
+
+ s1->runtime_main = "main";
+ if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main))
+ return 0;
+ if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
+ return -1;
+ prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
+
+#ifdef CONFIG_TCC_BACKTRACE
+ if (s1->do_debug) {
+ set_exception_handler();
+ rt_prog_main = prog_main;
+ }
+#endif
+
+ errno = 0; /* clean errno value */
+
+#ifdef CONFIG_TCC_BCHECK
+ if (s1->do_bounds_check) {
+ void (*bound_init)(void);
+ void (*bound_exit)(void);
+ void (*bound_new_region)(void *p, addr_t size);
+ int (*bound_delete_region)(void *p);
+ int i, ret;
+
+ /* set error function */
+ rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg");
+ /* XXX: use .init section so that it also work in binary ? */
+ bound_init = tcc_get_symbol_err(s1, "__bound_init");
+ bound_exit = tcc_get_symbol_err(s1, "__bound_exit");
+ bound_new_region = tcc_get_symbol_err(s1, "__bound_new_region");
+ bound_delete_region = tcc_get_symbol_err(s1, "__bound_delete_region");
+
+ bound_init();
+ /* mark argv area as valid */
+ bound_new_region(argv, argc*sizeof(argv[0]));
+ for (i=0; i<argc; ++i)
+ bound_new_region(argv[i], strlen(argv[i]) + 1);
+
+ ret = (*prog_main)(argc, argv);
+
+ /* unmark argv area */
+ for (i=0; i<argc; ++i)
+ bound_delete_region(argv[i]);
+ bound_delete_region(argv);
+ bound_exit();
+ return ret;
+ }
+#endif
+ return (*prog_main)(argc, argv);
+}
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ #define RUN_SECTION_ALIGNMENT 63
+#else
+ #define RUN_SECTION_ALIGNMENT 15
+#endif
+
+/* relocate code. Return -1 on error, required size if ptr is NULL,
+ otherwise copy code into buffer passed by the caller */
+static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
+{
+ Section *s;
+ unsigned offset, length, fill, i, k;
+ addr_t mem;
+
+ if (NULL == ptr) {
+ s1->nb_errors = 0;
+#ifdef TCC_TARGET_PE
+ pe_output_file(s1, NULL);
+#else
+ tcc_add_runtime(s1);
+ resolve_common_syms(s1);
+ build_got_entries(s1);
+#endif
+ if (s1->nb_errors)
+ return -1;
+ }
+
+ offset = 0, mem = (addr_t)ptr;
+ fill = -mem & RUN_SECTION_ALIGNMENT;
+#ifdef _WIN64
+ offset += sizeof (void*);
+#endif
+ for (k = 0; k < 2; ++k) {
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+ if (0 == (s->sh_flags & SHF_ALLOC))
+ continue;
+ if (k != !(s->sh_flags & SHF_EXECINSTR))
+ continue;
+ offset += fill;
+ if (!mem)
+ s->sh_addr = 0;
+ else if (s->sh_flags & SHF_EXECINSTR)
+ s->sh_addr = mem + offset + ptr_diff;
+ else
+ s->sh_addr = mem + offset;
+#if 0
+ if (mem)
+ printf("%-16s +%02lx %p %04x\n",
+ s->name, fill, (void*)s->sh_addr, (unsigned)s->data_offset);
+#endif
+ offset += s->data_offset;
+ fill = -(mem + offset) & 15;
+ }
+#if RUN_SECTION_ALIGNMENT > 15
+ /* To avoid that x86 processors would reload cached instructions each time
+ when data is written in the near, we need to make sure that code and data
+ do not share the same 64 byte unit */
+ fill = -(mem + offset) & RUN_SECTION_ALIGNMENT;
+#endif
+ }
+
+ /* relocate symbols */
+ relocate_syms(s1, s1->symtab, 1);
+ if (s1->nb_errors)
+ return -1;
+
+ if (0 == mem)
+ return offset + RUN_SECTION_ALIGNMENT;
+
+#ifdef TCC_TARGET_PE
+ s1->pe_imagebase = mem;
+#endif
+
+ /* relocate each section */
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+ if (s->reloc)
+ relocate_section(s1, s);
+ }
+ relocate_plt(s1);
+
+ for(i = 1; i < s1->nb_sections; i++) {
+ s = s1->sections[i];
+ if (0 == (s->sh_flags & SHF_ALLOC))
+ continue;
+ length = s->data_offset;
+ ptr = (void*)s->sh_addr;
+ if (s->sh_flags & SHF_EXECINSTR)
+ ptr = (char*)ptr - ptr_diff;
+ if (NULL == s->data || s->sh_type == SHT_NOBITS)
+ memset(ptr, 0, length);
+ else
+ memcpy(ptr, s->data, length);
+ /* mark executable sections as executable in memory */
+ if (s->sh_flags & SHF_EXECINSTR)
+ set_pages_executable((char*)ptr + ptr_diff, length);
+ }
+
+#ifdef _WIN64
+ *(void**)mem = win64_add_function_table(s1);
+#endif
+
+ return 0;
+}
+
+/* ------------------------------------------------------------- */
+/* allow to run code in memory */
+
+static void set_pages_executable(void *ptr, unsigned long length)
+{
+#ifdef _WIN32
+ unsigned long old_protect;
+ VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
+#else
+ void __clear_cache(void *beginning, void *end);
+# ifndef HAVE_SELINUX
+ addr_t start, end;
+# ifndef PAGESIZE
+# define PAGESIZE 4096
+# endif
+ start = (addr_t)ptr & ~(PAGESIZE - 1);
+ end = (addr_t)ptr + length;
+ end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
+ if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC))
+ tcc_error("mprotect failed: did you mean to configure --with-selinux?");
+# endif
+# if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
+ __clear_cache(ptr, (char *)ptr + length);
+# endif
+#endif
+}
+
+#ifdef _WIN64
+static void *win64_add_function_table(TCCState *s1)
+{
+ void *p = NULL;
+ if (s1->uw_pdata) {
+ p = (void*)s1->uw_pdata->sh_addr;
+ RtlAddFunctionTable(
+ (RUNTIME_FUNCTION*)p,
+ s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
+ s1->pe_imagebase
+ );
+ s1->uw_pdata = NULL;
+ }
+ return p;
+}
+
+static void win64_del_function_table(void *p)
+{
+ if (p) {
+ RtlDeleteFunctionTable((RUNTIME_FUNCTION*)p);
+ }
+}
+#endif
+
+/* ------------------------------------------------------------- */
+#ifdef CONFIG_TCC_BACKTRACE
+
+ST_FUNC void tcc_set_num_callers(int n)
+{
+ rt_num_callers = n;
+}
+
+/* print the position in the source file of PC value 'pc' by reading
+ the stabs debug information */
+static addr_t rt_printline(addr_t wanted_pc, const char *msg)
+{
+ char func_name[128], last_func_name[128];
+ addr_t func_addr, last_pc, pc;
+ const char *incl_files[INCLUDE_STACK_SIZE];
+ int incl_index, len, last_line_num, i;
+ const char *str, *p;
+
+ Stab_Sym *stab_sym = NULL, *stab_sym_end, *sym;
+ int stab_len = 0;
+ char *stab_str = NULL;
+
+ if (stab_section) {
+ stab_len = stab_section->data_offset;
+ stab_sym = (Stab_Sym *)stab_section->data;
+ stab_str = (char *) stabstr_section->data;
+ }
+
+ func_name[0] = '\0';
+ func_addr = 0;
+ incl_index = 0;
+ last_func_name[0] = '\0';
+ last_pc = (addr_t)-1;
+ last_line_num = 1;
+
+ if (!stab_sym)
+ goto no_stabs;
+
+ stab_sym_end = (Stab_Sym*)((char*)stab_sym + stab_len);
+ for (sym = stab_sym + 1; sym < stab_sym_end; ++sym) {
+ switch(sym->n_type) {
+ /* function start or end */
+ case N_FUN:
+ if (sym->n_strx == 0) {
+ /* we test if between last line and end of function */
+ pc = sym->n_value + func_addr;
+ if (wanted_pc >= last_pc && wanted_pc < pc)
+ goto found;
+ func_name[0] = '\0';
+ func_addr = 0;
+ } else {
+ str = stab_str + sym->n_strx;
+ p = strchr(str, ':');
+ if (!p) {
+ pstrcpy(func_name, sizeof(func_name), str);
+ } else {
+ len = p - str;
+ if (len > sizeof(func_name) - 1)
+ len = sizeof(func_name) - 1;
+ memcpy(func_name, str, len);
+ func_name[len] = '\0';
+ }
+ func_addr = sym->n_value;
+ }
+ break;
+ /* line number info */
+ case N_SLINE:
+ pc = sym->n_value + func_addr;
+ if (wanted_pc >= last_pc && wanted_pc < pc)
+ goto found;
+ last_pc = pc;
+ last_line_num = sym->n_desc;
+ /* XXX: slow! */
+ strcpy(last_func_name, func_name);
+ break;
+ /* include files */
+ case N_BINCL:
+ str = stab_str + sym->n_strx;
+ add_incl:
+ if (incl_index < INCLUDE_STACK_SIZE) {
+ incl_files[incl_index++] = str;
+ }
+ break;
+ case N_EINCL:
+ if (incl_index > 1)
+ incl_index--;
+ break;
+ case N_SO:
+ if (sym->n_strx == 0) {
+ incl_index = 0; /* end of translation unit */
+ } else {
+ str = stab_str + sym->n_strx;
+ /* do not add path */
+ len = strlen(str);
+ if (len > 0 && str[len - 1] != '/')
+ goto add_incl;
+ }
+ break;
+ }
+ }
+
+no_stabs:
+ /* second pass: we try symtab symbols (no line number info) */
+ incl_index = 0;
+ if (symtab_section)
+ {
+ ElfW(Sym) *sym, *sym_end;
+ int type;
+
+ sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
+ for(sym = (ElfW(Sym) *)symtab_section->data + 1;
+ sym < sym_end;
+ sym++) {
+ type = ELFW(ST_TYPE)(sym->st_info);
+ if (type == STT_FUNC || type == STT_GNU_IFUNC) {
+ if (wanted_pc >= sym->st_value &&
+ wanted_pc < sym->st_value + sym->st_size) {
+ pstrcpy(last_func_name, sizeof(last_func_name),
+ (char *) symtab_section->link->data + sym->st_name);
+ func_addr = sym->st_value;
+ goto found;
+ }
+ }
+ }
+ }
+ /* did not find any info: */
+ fprintf(stderr, "%s %p ???\n", msg, (void*)wanted_pc);
+ fflush(stderr);
+ return 0;
+ found:
+ i = incl_index;
+ if (i > 0)
+ fprintf(stderr, "%s:%d: ", incl_files[--i], last_line_num);
+ fprintf(stderr, "%s %p", msg, (void*)wanted_pc);
+ if (last_func_name[0] != '\0')
+ fprintf(stderr, " %s()", last_func_name);
+ if (--i >= 0) {
+ fprintf(stderr, " (included from ");
+ for (;;) {
+ fprintf(stderr, "%s", incl_files[i]);
+ if (--i < 0)
+ break;
+ fprintf(stderr, ", ");
+ }
+ fprintf(stderr, ")");
+ }
+ fprintf(stderr, "\n");
+ fflush(stderr);
+ return func_addr;
+}
+
+/* emit a run time error at position 'pc' */
+static void rt_error(ucontext_t *uc, const char *fmt, ...)
+{
+ va_list ap;
+ addr_t pc;
+ int i;
+
+ fprintf(stderr, "Runtime error: ");
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+
+ for(i=0;i<rt_num_callers;i++) {
+ if (rt_get_caller_pc(&pc, uc, i) < 0)
+ break;
+ pc = rt_printline(pc, i ? "by" : "at");
+ if (pc == (addr_t)rt_prog_main && pc)
+ break;
+ }
+}
+
+/* ------------------------------------------------------------- */
+#ifndef _WIN32
+
+/* signal handler for fatal errors */
+static void sig_error(int signum, siginfo_t *siginf, void *puc)
+{
+ ucontext_t *uc = puc;
+
+ switch(signum) {
+ case SIGFPE:
+ switch(siginf->si_code) {
+ case FPE_INTDIV:
+ case FPE_FLTDIV:
+ rt_error(uc, "division by zero");
+ break;
+ default:
+ rt_error(uc, "floating point exception");
+ break;
+ }
+ break;
+ case SIGBUS:
+ case SIGSEGV:
+ if (rt_bound_error_msg && *rt_bound_error_msg)
+ rt_error(uc, *rt_bound_error_msg);
+ else
+ rt_error(uc, "dereferencing invalid pointer");
+ break;
+ case SIGILL:
+ rt_error(uc, "illegal instruction");
+ break;
+ case SIGABRT:
+ rt_error(uc, "abort() called");
+ break;
+ default:
+ rt_error(uc, "caught signal %d", signum);
+ break;
+ }
+ exit(255);
+}
+
+#ifndef SA_SIGINFO
+# define SA_SIGINFO 0x00000004u
+#endif
+
+/* Generate a stack backtrace when a CPU exception occurs. */
+static void set_exception_handler(void)
+{
+ struct sigaction sigact;
+ /* install TCC signal handlers to print debug info on fatal
+ runtime errors */
+ sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
+ sigact.sa_sigaction = sig_error;
+ sigemptyset(&sigact.sa_mask);
+ sigaction(SIGFPE, &sigact, NULL);
+ sigaction(SIGILL, &sigact, NULL);
+ sigaction(SIGSEGV, &sigact, NULL);
+ sigaction(SIGBUS, &sigact, NULL);
+ sigaction(SIGABRT, &sigact, NULL);
+}
+
+/* ------------------------------------------------------------- */
+#ifdef __i386__
+
+/* fix for glibc 2.1 */
+#ifndef REG_EIP
+#define REG_EIP EIP
+#define REG_EBP EBP
+#endif
+
+/* return the PC at frame level 'level'. Return negative if not found */
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
+{
+ addr_t fp;
+ int i;
+
+ if (level == 0) {
+#if defined(__APPLE__)
+ *paddr = uc->uc_mcontext->__ss.__eip;
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+ *paddr = uc->uc_mcontext.mc_eip;
+#elif defined(__dietlibc__)
+ *paddr = uc->uc_mcontext.eip;
+#elif defined(__NetBSD__)
+ *paddr = uc->uc_mcontext.__gregs[_REG_EIP];
+#elif defined(__OpenBSD__)
+ *paddr = uc->sc_eip;
+#else
+ *paddr = uc->uc_mcontext.gregs[REG_EIP];
+#endif
+ return 0;
+ } else {
+#if defined(__APPLE__)
+ fp = uc->uc_mcontext->__ss.__ebp;
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+ fp = uc->uc_mcontext.mc_ebp;
+#elif defined(__dietlibc__)
+ fp = uc->uc_mcontext.ebp;
+#elif defined(__NetBSD__)
+ fp = uc->uc_mcontext.__gregs[_REG_EBP];
+#elif defined(__OpenBSD__)
+ *paddr = uc->sc_ebp;
+#else
+ fp = uc->uc_mcontext.gregs[REG_EBP];
+#endif
+ for(i=1;i<level;i++) {
+ /* XXX: check address validity with program info */
+ if (fp <= 0x1000 || fp >= 0xc0000000)
+ return -1;
+ fp = ((addr_t *)fp)[0];
+ }
+ *paddr = ((addr_t *)fp)[1];
+ return 0;
+ }
+}
+
+/* ------------------------------------------------------------- */
+#elif defined(__x86_64__)
+
+/* return the PC at frame level 'level'. Return negative if not found */
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
+{
+ addr_t fp;
+ int i;
+
+ if (level == 0) {
+ /* XXX: only support linux */
+#if defined(__APPLE__)
+ *paddr = uc->uc_mcontext->__ss.__rip;
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+ *paddr = uc->uc_mcontext.mc_rip;
+#elif defined(__NetBSD__)
+ *paddr = uc->uc_mcontext.__gregs[_REG_RIP];
+#else
+ *paddr = uc->uc_mcontext.gregs[REG_RIP];
+#endif
+ return 0;
+ } else {
+#if defined(__APPLE__)
+ fp = uc->uc_mcontext->__ss.__rbp;
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+ fp = uc->uc_mcontext.mc_rbp;
+#elif defined(__NetBSD__)
+ fp = uc->uc_mcontext.__gregs[_REG_RBP];
+#else
+ fp = uc->uc_mcontext.gregs[REG_RBP];
+#endif
+ for(i=1;i<level;i++) {
+ /* XXX: check address validity with program info */
+ if (fp <= 0x1000)
+ return -1;
+ fp = ((addr_t *)fp)[0];
+ }
+ *paddr = ((addr_t *)fp)[1];
+ return 0;
+ }
+}
+
+/* ------------------------------------------------------------- */
+#elif defined(__arm__)
+
+/* return the PC at frame level 'level'. Return negative if not found */
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
+{
+ addr_t fp, sp;
+ int i;
+
+ if (level == 0) {
+ /* XXX: only supports linux */
+#if defined(__linux__)
+ *paddr = uc->uc_mcontext.arm_pc;
+#else
+ return -1;
+#endif
+ return 0;
+ } else {
+#if defined(__linux__)
+ fp = uc->uc_mcontext.arm_fp;
+ sp = uc->uc_mcontext.arm_sp;
+ if (sp < 0x1000)
+ sp = 0x1000;
+#else
+ return -1;
+#endif
+ /* XXX: specific to tinycc stack frames */
+ if (fp < sp + 12 || fp & 3)
+ return -1;
+ for(i = 1; i < level; i++) {
+ sp = ((addr_t *)fp)[-2];
+ if (sp < fp || sp - fp > 16 || sp & 3)
+ return -1;
+ fp = ((addr_t *)fp)[-3];
+ if (fp <= sp || fp - sp < 12 || fp & 3)
+ return -1;
+ }
+ /* XXX: check address validity with program info */
+ *paddr = ((addr_t *)fp)[-1];
+ return 0;
+ }
+}
+
+/* ------------------------------------------------------------- */
+#elif defined(__aarch64__)
+
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
+{
+ if (level < 0)
+ return -1;
+ else if (level == 0) {
+ *paddr = uc->uc_mcontext.pc;
+ return 0;
+ }
+ else {
+ addr_t *fp = (addr_t *)uc->uc_mcontext.regs[29];
+ int i;
+ for (i = 1; i < level; i++)
+ fp = (addr_t *)fp[0];
+ *paddr = fp[1];
+ return 0;
+ }
+}
+
+/* ------------------------------------------------------------- */
+#else
+
+#warning add arch specific rt_get_caller_pc()
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
+{
+ return -1;
+}
+
+#endif /* !__i386__ */
+
+/* ------------------------------------------------------------- */
+#else /* WIN32 */
+
+static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info)
+{
+ EXCEPTION_RECORD *er = ex_info->ExceptionRecord;
+ CONTEXT *uc = ex_info->ContextRecord;
+ switch (er->ExceptionCode) {
+ case EXCEPTION_ACCESS_VIOLATION:
+ if (rt_bound_error_msg && *rt_bound_error_msg)
+ rt_error(uc, *rt_bound_error_msg);
+ else
+ rt_error(uc, "access violation");
+ break;
+ case EXCEPTION_STACK_OVERFLOW:
+ rt_error(uc, "stack overflow");
+ break;
+ case EXCEPTION_INT_DIVIDE_BY_ZERO:
+ rt_error(uc, "division by zero");
+ break;
+ default:
+ rt_error(uc, "exception caught");
+ break;
+ }
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+/* Generate a stack backtrace when a CPU exception occurs. */
+static void set_exception_handler(void)
+{
+ SetUnhandledExceptionFilter(cpu_exception_handler);
+}
+
+/* return the PC at frame level 'level'. Return non zero if not found */
+static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level)
+{
+ addr_t fp, pc;
+ int i;
+#ifdef _WIN64
+ pc = uc->Rip;
+ fp = uc->Rbp;
+#else
+ pc = uc->Eip;
+ fp = uc->Ebp;
+#endif
+ if (level > 0) {
+ for(i=1;i<level;i++) {
+ /* XXX: check address validity with program info */
+ if (fp <= 0x1000 || fp >= 0xc0000000)
+ return -1;
+ fp = ((addr_t*)fp)[0];
+ }
+ pc = ((addr_t*)fp)[1];
+ }
+ *paddr = pc;
+ return 0;
+}
+
+#endif /* _WIN32 */
+#endif /* CONFIG_TCC_BACKTRACE */
+/* ------------------------------------------------------------- */
+#ifdef CONFIG_TCC_STATIC
+
+/* dummy function for profiling */
+ST_FUNC void *dlopen(const char *filename, int flag)
+{
+ return NULL;
+}
+
+ST_FUNC void dlclose(void *p)
+{
+}
+
+ST_FUNC const char *dlerror(void)
+{
+ return "error";
+}
+
+typedef struct TCCSyms {
+ char *str;
+ void *ptr;
+} TCCSyms;
+
+
+/* add the symbol you want here if no dynamic linking is done */
+static TCCSyms tcc_syms[] = {
+#if !defined(CONFIG_TCCBOOT)
+#define TCCSYM(a) { #a, &a, },
+ TCCSYM(printf)
+ TCCSYM(fprintf)
+ TCCSYM(fopen)
+ TCCSYM(fclose)
+#undef TCCSYM
+#endif
+ { NULL, NULL },
+};
+
+ST_FUNC void *dlsym(void *handle, const char *symbol)
+{
+ TCCSyms *p;
+ p = tcc_syms;
+ while (p->str != NULL) {
+ if (!strcmp(p->str, symbol))
+ return p->ptr;
+ p++;
+ }
+ return NULL;
+}
+
+#endif /* CONFIG_TCC_STATIC */
+#endif /* TCC_IS_NATIVE */
+/* ------------------------------------------------------------- */
diff --git a/tcctok.h b/tcctok.h
new file mode 100644
index 0000000..317f64c
--- /dev/null
+++ b/tcctok.h
@@ -0,0 +1,350 @@
+/* keywords */
+ DEF(TOK_INT, "int")
+ DEF(TOK_VOID, "void")
+ DEF(TOK_CHAR, "char")
+ DEF(TOK_IF, "if")
+ DEF(TOK_ELSE, "else")
+ DEF(TOK_WHILE, "while")
+ DEF(TOK_BREAK, "break")
+ DEF(TOK_RETURN, "return")
+ DEF(TOK_FOR, "for")
+ DEF(TOK_EXTERN, "extern")
+ DEF(TOK_STATIC, "static")
+ DEF(TOK_UNSIGNED, "unsigned")
+ DEF(TOK_GOTO, "goto")
+ DEF(TOK_DO, "do")
+ DEF(TOK_CONTINUE, "continue")
+ DEF(TOK_SWITCH, "switch")
+ DEF(TOK_CASE, "case")
+
+ DEF(TOK_CONST1, "const")
+ DEF(TOK_CONST2, "__const") /* gcc keyword */
+ DEF(TOK_CONST3, "__const__") /* gcc keyword */
+ DEF(TOK_VOLATILE1, "volatile")
+ DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
+ DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
+ DEF(TOK_LONG, "long")
+ DEF(TOK_REGISTER, "register")
+ DEF(TOK_SIGNED1, "signed")
+ DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
+ DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */
+ DEF(TOK_AUTO, "auto")
+ DEF(TOK_INLINE1, "inline")
+ DEF(TOK_INLINE2, "__inline") /* gcc keyword */
+ DEF(TOK_INLINE3, "__inline__") /* gcc keyword */
+ DEF(TOK_RESTRICT1, "restrict")
+ DEF(TOK_RESTRICT2, "__restrict")
+ DEF(TOK_RESTRICT3, "__restrict__")
+ DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
+
+ DEF(TOK_GENERIC, "_Generic")
+
+ DEF(TOK_FLOAT, "float")
+ DEF(TOK_DOUBLE, "double")
+ DEF(TOK_BOOL, "_Bool")
+ DEF(TOK_SHORT, "short")
+ DEF(TOK_STRUCT, "struct")
+ DEF(TOK_UNION, "union")
+ DEF(TOK_TYPEDEF, "typedef")
+ DEF(TOK_DEFAULT, "default")
+ DEF(TOK_ENUM, "enum")
+ DEF(TOK_SIZEOF, "sizeof")
+ DEF(TOK_ATTRIBUTE1, "__attribute")
+ DEF(TOK_ATTRIBUTE2, "__attribute__")
+ DEF(TOK_ALIGNOF1, "__alignof")
+ DEF(TOK_ALIGNOF2, "__alignof__")
+ DEF(TOK_TYPEOF1, "typeof")
+ DEF(TOK_TYPEOF2, "__typeof")
+ DEF(TOK_TYPEOF3, "__typeof__")
+ DEF(TOK_LABEL, "__label__")
+ DEF(TOK_ASM1, "asm")
+ DEF(TOK_ASM2, "__asm")
+ DEF(TOK_ASM3, "__asm__")
+
+#ifdef TCC_TARGET_ARM64
+ DEF(TOK_UINT128, "__uint128_t")
+#endif
+
+/*********************************************************************/
+/* the following are not keywords. They are included to ease parsing */
+/* preprocessor only */
+ DEF(TOK_DEFINE, "define")
+ DEF(TOK_INCLUDE, "include")
+ DEF(TOK_INCLUDE_NEXT, "include_next")
+ DEF(TOK_IFDEF, "ifdef")
+ DEF(TOK_IFNDEF, "ifndef")
+ DEF(TOK_ELIF, "elif")
+ DEF(TOK_ENDIF, "endif")
+ DEF(TOK_DEFINED, "defined")
+ DEF(TOK_UNDEF, "undef")
+ DEF(TOK_ERROR, "error")
+ DEF(TOK_WARNING, "warning")
+ DEF(TOK_LINE, "line")
+ DEF(TOK_PRAGMA, "pragma")
+ DEF(TOK___LINE__, "__LINE__")
+ DEF(TOK___FILE__, "__FILE__")
+ DEF(TOK___DATE__, "__DATE__")
+ DEF(TOK___TIME__, "__TIME__")
+ DEF(TOK___FUNCTION__, "__FUNCTION__")
+ DEF(TOK___VA_ARGS__, "__VA_ARGS__")
+ DEF(TOK___COUNTER__, "__COUNTER__")
+
+/* special identifiers */
+ DEF(TOK___FUNC__, "__func__")
+
+/* special floating point values */
+ DEF(TOK___NAN__, "__nan__")
+ DEF(TOK___SNAN__, "__snan__")
+ DEF(TOK___INF__, "__inf__")
+
+/* attribute identifiers */
+/* XXX: handle all tokens generically since speed is not critical */
+ DEF(TOK_SECTION1, "section")
+ DEF(TOK_SECTION2, "__section__")
+ DEF(TOK_ALIGNED1, "aligned")
+ DEF(TOK_ALIGNED2, "__aligned__")
+ DEF(TOK_PACKED1, "packed")
+ DEF(TOK_PACKED2, "__packed__")
+ DEF(TOK_WEAK1, "weak")
+ DEF(TOK_WEAK2, "__weak__")
+ DEF(TOK_ALIAS1, "alias")
+ DEF(TOK_ALIAS2, "__alias__")
+ DEF(TOK_UNUSED1, "unused")
+ DEF(TOK_UNUSED2, "__unused__")
+ DEF(TOK_CDECL1, "cdecl")
+ DEF(TOK_CDECL2, "__cdecl")
+ DEF(TOK_CDECL3, "__cdecl__")
+ DEF(TOK_STDCALL1, "stdcall")
+ DEF(TOK_STDCALL2, "__stdcall")
+ DEF(TOK_STDCALL3, "__stdcall__")
+ DEF(TOK_FASTCALL1, "fastcall")
+ DEF(TOK_FASTCALL2, "__fastcall")
+ DEF(TOK_FASTCALL3, "__fastcall__")
+ DEF(TOK_REGPARM1, "regparm")
+ DEF(TOK_REGPARM2, "__regparm__")
+
+ DEF(TOK_MODE, "__mode__")
+ DEF(TOK_MODE_QI, "__QI__")
+ DEF(TOK_MODE_DI, "__DI__")
+ DEF(TOK_MODE_HI, "__HI__")
+ DEF(TOK_MODE_SI, "__SI__")
+ DEF(TOK_MODE_word, "__word__")
+
+ DEF(TOK_DLLEXPORT, "dllexport")
+ DEF(TOK_DLLIMPORT, "dllimport")
+ DEF(TOK_NORETURN1, "noreturn")
+ DEF(TOK_NORETURN2, "__noreturn__")
+ DEF(TOK_VISIBILITY1, "visibility")
+ DEF(TOK_VISIBILITY2, "__visibility__")
+
+ DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
+ DEF(TOK_builtin_choose_expr, "__builtin_choose_expr")
+ DEF(TOK_builtin_constant_p, "__builtin_constant_p")
+ DEF(TOK_builtin_frame_address, "__builtin_frame_address")
+ DEF(TOK_builtin_return_address, "__builtin_return_address")
+ DEF(TOK_builtin_expect, "__builtin_expect")
+ /*DEF(TOK_builtin_va_list, "__builtin_va_list")*/
+#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
+ DEF(TOK_builtin_va_start, "__builtin_va_start")
+#elif defined TCC_TARGET_X86_64
+ DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
+#elif defined TCC_TARGET_ARM64
+ DEF(TOK___va_start, "__va_start")
+ DEF(TOK___va_arg, "__va_arg")
+#endif
+
+/* pragma */
+ DEF(TOK_pack, "pack")
+#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64)
+ /* already defined for assembler */
+ DEF(TOK_ASM_push, "push")
+ DEF(TOK_ASM_pop, "pop")
+#endif
+ DEF(TOK_comment, "comment")
+ DEF(TOK_lib, "lib")
+ DEF(TOK_push_macro, "push_macro")
+ DEF(TOK_pop_macro, "pop_macro")
+ DEF(TOK_once, "once")
+ DEF(TOK_option, "option")
+
+/* builtin functions or variables */
+#ifndef TCC_ARM_EABI
+ DEF(TOK_memcpy, "memcpy")
+ DEF(TOK_memmove, "memmove")
+ DEF(TOK_memset, "memset")
+ DEF(TOK___divdi3, "__divdi3")
+ DEF(TOK___moddi3, "__moddi3")
+ DEF(TOK___udivdi3, "__udivdi3")
+ DEF(TOK___umoddi3, "__umoddi3")
+ DEF(TOK___ashrdi3, "__ashrdi3")
+ DEF(TOK___lshrdi3, "__lshrdi3")
+ DEF(TOK___ashldi3, "__ashldi3")
+ DEF(TOK___floatundisf, "__floatundisf")
+ DEF(TOK___floatundidf, "__floatundidf")
+# ifndef TCC_ARM_VFP
+ DEF(TOK___floatundixf, "__floatundixf")
+ DEF(TOK___fixunsxfdi, "__fixunsxfdi")
+# endif
+ DEF(TOK___fixunssfdi, "__fixunssfdi")
+ DEF(TOK___fixunsdfdi, "__fixunsdfdi")
+#endif
+
+#if defined TCC_TARGET_ARM
+# ifdef TCC_ARM_EABI
+ DEF(TOK_memcpy, "__aeabi_memcpy")
+ DEF(TOK_memcpy4, "__aeabi_memcpy4")
+ DEF(TOK_memcpy8, "__aeabi_memcpy8")
+ DEF(TOK_memmove, "__aeabi_memmove")
+ DEF(TOK_memset, "__aeabi_memset")
+ DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod")
+ DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod")
+ DEF(TOK___aeabi_idivmod, "__aeabi_idivmod")
+ DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod")
+ DEF(TOK___divsi3, "__aeabi_idiv")
+ DEF(TOK___udivsi3, "__aeabi_uidiv")
+ DEF(TOK___floatdisf, "__aeabi_l2f")
+ DEF(TOK___floatdidf, "__aeabi_l2d")
+ DEF(TOK___fixsfdi, "__aeabi_f2lz")
+ DEF(TOK___fixdfdi, "__aeabi_d2lz")
+ DEF(TOK___ashrdi3, "__aeabi_lasr")
+ DEF(TOK___lshrdi3, "__aeabi_llsr")
+ DEF(TOK___ashldi3, "__aeabi_llsl")
+ DEF(TOK___floatundisf, "__aeabi_ul2f")
+ DEF(TOK___floatundidf, "__aeabi_ul2d")
+ DEF(TOK___fixunssfdi, "__aeabi_f2ulz")
+ DEF(TOK___fixunsdfdi, "__aeabi_d2ulz")
+# else
+ DEF(TOK___modsi3, "__modsi3")
+ DEF(TOK___umodsi3, "__umodsi3")
+ DEF(TOK___divsi3, "__divsi3")
+ DEF(TOK___udivsi3, "__udivsi3")
+ DEF(TOK___floatdisf, "__floatdisf")
+ DEF(TOK___floatdidf, "__floatdidf")
+# ifndef TCC_ARM_VFP
+ DEF(TOK___floatdixf, "__floatdixf")
+ DEF(TOK___fixunssfsi, "__fixunssfsi")
+ DEF(TOK___fixunsdfsi, "__fixunsdfsi")
+ DEF(TOK___fixunsxfsi, "__fixunsxfsi")
+ DEF(TOK___fixxfdi, "__fixxfdi")
+# endif
+ DEF(TOK___fixsfdi, "__fixsfdi")
+ DEF(TOK___fixdfdi, "__fixdfdi")
+# endif
+#endif
+
+#if defined TCC_TARGET_C67
+ DEF(TOK__divi, "_divi")
+ DEF(TOK__divu, "_divu")
+ DEF(TOK__divf, "_divf")
+ DEF(TOK__divd, "_divd")
+ DEF(TOK__remi, "_remi")
+ DEF(TOK__remu, "_remu")
+#endif
+
+#if defined TCC_TARGET_I386
+ DEF(TOK___fixsfdi, "__fixsfdi")
+ DEF(TOK___fixdfdi, "__fixdfdi")
+ DEF(TOK___fixxfdi, "__fixxfdi")
+#endif
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ DEF(TOK_alloca, "alloca")
+#endif
+
+#if defined TCC_TARGET_PE
+ DEF(TOK___chkstk, "__chkstk")
+#endif
+#ifdef TCC_TARGET_ARM64
+ DEF(TOK___arm64_clear_cache, "__arm64_clear_cache")
+ DEF(TOK___addtf3, "__addtf3")
+ DEF(TOK___subtf3, "__subtf3")
+ DEF(TOK___multf3, "__multf3")
+ DEF(TOK___divtf3, "__divtf3")
+ DEF(TOK___extendsftf2, "__extendsftf2")
+ DEF(TOK___extenddftf2, "__extenddftf2")
+ DEF(TOK___trunctfsf2, "__trunctfsf2")
+ DEF(TOK___trunctfdf2, "__trunctfdf2")
+ DEF(TOK___fixtfsi, "__fixtfsi")
+ DEF(TOK___fixtfdi, "__fixtfdi")
+ DEF(TOK___fixunstfsi, "__fixunstfsi")
+ DEF(TOK___fixunstfdi, "__fixunstfdi")
+ DEF(TOK___floatsitf, "__floatsitf")
+ DEF(TOK___floatditf, "__floatditf")
+ DEF(TOK___floatunsitf, "__floatunsitf")
+ DEF(TOK___floatunditf, "__floatunditf")
+ DEF(TOK___eqtf2, "__eqtf2")
+ DEF(TOK___netf2, "__netf2")
+ DEF(TOK___lttf2, "__lttf2")
+ DEF(TOK___letf2, "__letf2")
+ DEF(TOK___gttf2, "__gttf2")
+ DEF(TOK___getf2, "__getf2")
+#endif
+
+/* bound checking symbols */
+#ifdef CONFIG_TCC_BCHECK
+ DEF(TOK___bound_ptr_add, "__bound_ptr_add")
+ DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
+ DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
+ DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
+ DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
+ DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
+ DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
+ DEF(TOK___bound_main_arg, "__bound_main_arg")
+ DEF(TOK___bound_local_new, "__bound_local_new")
+ DEF(TOK___bound_local_delete, "__bound_local_delete")
+# ifdef TCC_TARGET_PE
+ DEF(TOK_malloc, "malloc")
+ DEF(TOK_free, "free")
+ DEF(TOK_realloc, "realloc")
+ DEF(TOK_memalign, "memalign")
+ DEF(TOK_calloc, "calloc")
+# endif
+ DEF(TOK_strlen, "strlen")
+ DEF(TOK_strcpy, "strcpy")
+#endif
+
+/* Tiny Assembler */
+ DEF_ASMDIR(byte) /* must be first directive */
+ DEF_ASMDIR(word)
+ DEF_ASMDIR(align)
+ DEF_ASMDIR(balign)
+ DEF_ASMDIR(p2align)
+ DEF_ASMDIR(set)
+ DEF_ASMDIR(skip)
+ DEF_ASMDIR(space)
+ DEF_ASMDIR(string)
+ DEF_ASMDIR(asciz)
+ DEF_ASMDIR(ascii)
+ DEF_ASMDIR(file)
+ DEF_ASMDIR(globl)
+ DEF_ASMDIR(global)
+ DEF_ASMDIR(weak)
+ DEF_ASMDIR(hidden)
+ DEF_ASMDIR(ident)
+ DEF_ASMDIR(size)
+ DEF_ASMDIR(type)
+ DEF_ASMDIR(text)
+ DEF_ASMDIR(data)
+ DEF_ASMDIR(bss)
+ DEF_ASMDIR(previous)
+ DEF_ASMDIR(pushsection)
+ DEF_ASMDIR(popsection)
+ DEF_ASMDIR(fill)
+ DEF_ASMDIR(rept)
+ DEF_ASMDIR(endr)
+ DEF_ASMDIR(org)
+ DEF_ASMDIR(quad)
+#if defined(TCC_TARGET_I386)
+ DEF_ASMDIR(code16)
+ DEF_ASMDIR(code32)
+#elif defined(TCC_TARGET_X86_64)
+ DEF_ASMDIR(code64)
+#endif
+ DEF_ASMDIR(short)
+ DEF_ASMDIR(long)
+ DEF_ASMDIR(int)
+ DEF_ASMDIR(section) /* must be last directive */
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+#include "i386-tok.h"
+#endif
diff --git a/tcctools.c b/tcctools.c
new file mode 100644
index 0000000..1d4424e
--- /dev/null
+++ b/tcctools.c
@@ -0,0 +1,546 @@
+/* -------------------------------------------------------------- */
+/*
+ * TCC - Tiny C Compiler
+ *
+ * tcctools.c - extra tools and and -m32/64 support
+ *
+ */
+
+/* -------------------------------------------------------------- */
+/*
+ * This program is for making libtcc1.a without ar
+ * tiny_libmaker - tiny elf lib maker
+ * usage: tiny_libmaker [lib] files...
+ * Copyright (c) 2007 Timppa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "tcc.h"
+
+//#define ARMAG "!<arch>\n"
+#define ARFMAG "`\n"
+
+typedef struct {
+ char ar_name[16];
+ char ar_date[12];
+ char ar_uid[6];
+ char ar_gid[6];
+ char ar_mode[8];
+ char ar_size[10];
+ char ar_fmag[2];
+} ArHdr;
+
+static unsigned long le2belong(unsigned long ul) {
+ return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) +
+ ((ul & 0xFF)<<24)+((ul & 0xFF00)<<8);
+}
+
+/* Returns 1 if s contains any of the chars of list, else 0 */
+static int contains_any(const char *s, const char *list) {
+ const char *l;
+ for (; *s; s++) {
+ for (l = list; *l; l++) {
+ if (*s == *l)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int ar_usage(int ret) {
+ fprintf(stderr, "usage: tcc -ar [rcsv] lib file...\n");
+ fprintf(stderr, "create library ([abdioptxN] not supported).\n");
+ return ret;
+}
+
+ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
+{
+ static ArHdr arhdr = {
+ "/ ",
+ " ",
+ "0 ",
+ "0 ",
+ "0 ",
+ " ",
+ ARFMAG
+ };
+
+ static ArHdr arhdro = {
+ " ",
+ " ",
+ "0 ",
+ "0 ",
+ "0 ",
+ " ",
+ ARFMAG
+ };
+
+ FILE *fi, *fh = NULL, *fo = NULL;
+ ElfW(Ehdr) *ehdr;
+ ElfW(Shdr) *shdr;
+ ElfW(Sym) *sym;
+ int i, fsize, i_lib, i_obj;
+ char *buf, *shstr, *symtab = NULL, *strtab = NULL;
+ int symtabsize = 0;//, strtabsize = 0;
+ char *anames = NULL;
+ int *afpos = NULL;
+ int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs;
+ char tfile[260], stmp[20];
+ char *file, *name;
+ int ret = 2;
+ const char *ops_conflict = "habdioptxN"; // unsupported but destructive if ignored.
+ int verbose = 0;
+
+ i_lib = 0; i_obj = 0; // will hold the index of the lib and first obj
+ for (i = 1; i < argc; i++) {
+ const char *a = argv[i];
+ if (*a == '-' && strstr(a, "."))
+ ret = 1; // -x.y is always invalid (same as gnu ar)
+ if ((*a == '-') || (i == 1 && !strstr(a, "."))) { // options argument
+ if (contains_any(a, ops_conflict))
+ ret = 1;
+ if (strstr(a, "v"))
+ verbose = 1;
+ } else { // lib or obj files: don't abort - keep validating all args.
+ if (!i_lib) // first file is the lib
+ i_lib = i;
+ else if (!i_obj) // second file is the first obj
+ i_obj = i;
+ }
+ }
+
+ if (!i_obj) // i_obj implies also i_lib. we require both.
+ ret = 1;
+
+ if (ret == 1)
+ return ar_usage(ret);
+
+ if ((fh = fopen(argv[i_lib], "wb")) == NULL)
+ {
+ fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_lib]);
+ goto the_end;
+ }
+
+ sprintf(tfile, "%s.tmp", argv[i_lib]);
+ if ((fo = fopen(tfile, "wb+")) == NULL)
+ {
+ fprintf(stderr, "tcc: ar: can't create temporary file %s\n", tfile);
+ goto the_end;
+ }
+
+ funcmax = 250;
+ afpos = tcc_realloc(NULL, funcmax * sizeof *afpos); // 250 func
+ memcpy(&arhdro.ar_mode, "100666", 6);
+
+ // i_obj = first input object file
+ while (i_obj < argc)
+ {
+ if (*argv[i_obj] == '-') { // by now, all options start with '-'
+ i_obj++;
+ continue;
+ }
+ if ((fi = fopen(argv[i_obj], "rb")) == NULL) {
+ fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_obj]);
+ goto the_end;
+ }
+ if (verbose)
+ printf("a - %s\n", argv[i_obj]);
+
+ fseek(fi, 0, SEEK_END);
+ fsize = ftell(fi);
+ fseek(fi, 0, SEEK_SET);
+ buf = tcc_malloc(fsize + 1);
+ fread(buf, fsize, 1, fi);
+ fclose(fi);
+
+ // elf header
+ ehdr = (ElfW(Ehdr) *)buf;
+ if (ehdr->e_ident[4] != ELFCLASSW)
+ {
+ fprintf(stderr, "tcc: ar: Unsupported Elf Class: %s\n", argv[i_obj]);
+ goto the_end;
+ }
+
+ shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
+ shstr = (char *)(buf + shdr->sh_offset);
+ for (i = 0; i < ehdr->e_shnum; i++)
+ {
+ shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize);
+ if (!shdr->sh_offset)
+ continue;
+ if (shdr->sh_type == SHT_SYMTAB)
+ {
+ symtab = (char *)(buf + shdr->sh_offset);
+ symtabsize = shdr->sh_size;
+ }
+ if (shdr->sh_type == SHT_STRTAB)
+ {
+ if (!strcmp(shstr + shdr->sh_name, ".strtab"))
+ {
+ strtab = (char *)(buf + shdr->sh_offset);
+ //strtabsize = shdr->sh_size;
+ }
+ }
+ }
+
+ if (symtab && symtabsize)
+ {
+ int nsym = symtabsize / sizeof(ElfW(Sym));
+ //printf("symtab: info size shndx name\n");
+ for (i = 1; i < nsym; i++)
+ {
+ sym = (ElfW(Sym) *) (symtab + i * sizeof(ElfW(Sym)));
+ if (sym->st_shndx &&
+ (sym->st_info == 0x10
+ || sym->st_info == 0x11
+ || sym->st_info == 0x12
+ )) {
+ //printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name);
+ istrlen = strlen(strtab + sym->st_name)+1;
+ anames = tcc_realloc(anames, strpos+istrlen);
+ strcpy(anames + strpos, strtab + sym->st_name);
+ strpos += istrlen;
+ if (++funccnt >= funcmax) {
+ funcmax += 250;
+ afpos = tcc_realloc(afpos, funcmax * sizeof *afpos); // 250 func more
+ }
+ afpos[funccnt] = fpos;
+ }
+ }
+ }
+
+ file = argv[i_obj];
+ for (name = strchr(file, 0);
+ name > file && name[-1] != '/' && name[-1] != '\\';
+ --name);
+ istrlen = strlen(name);
+ if (istrlen >= sizeof(arhdro.ar_name))
+ istrlen = sizeof(arhdro.ar_name) - 1;
+ memset(arhdro.ar_name, ' ', sizeof(arhdro.ar_name));
+ memcpy(arhdro.ar_name, name, istrlen);
+ arhdro.ar_name[istrlen] = '/';
+ sprintf(stmp, "%-10d", fsize);
+ memcpy(&arhdro.ar_size, stmp, 10);
+ fwrite(&arhdro, sizeof(arhdro), 1, fo);
+ fwrite(buf, fsize, 1, fo);
+ tcc_free(buf);
+ i_obj++;
+ fpos += (fsize + sizeof(arhdro));
+ }
+ hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int);
+ fpos = 0;
+ if ((hofs & 1)) // align
+ hofs++, fpos = 1;
+ // write header
+ fwrite("!<arch>\n", 8, 1, fh);
+ sprintf(stmp, "%-10d", (int)(strpos + (funccnt+1) * sizeof(int)));
+ memcpy(&arhdr.ar_size, stmp, 10);
+ fwrite(&arhdr, sizeof(arhdr), 1, fh);
+ afpos[0] = le2belong(funccnt);
+ for (i=1; i<=funccnt; i++)
+ afpos[i] = le2belong(afpos[i] + hofs);
+ fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh);
+ fwrite(anames, strpos, 1, fh);
+ if (fpos)
+ fwrite("", 1, 1, fh);
+ // write objects
+ fseek(fo, 0, SEEK_END);
+ fsize = ftell(fo);
+ fseek(fo, 0, SEEK_SET);
+ buf = tcc_malloc(fsize + 1);
+ fread(buf, fsize, 1, fo);
+ fwrite(buf, fsize, 1, fh);
+ tcc_free(buf);
+ ret = 0;
+the_end:
+ if (anames)
+ tcc_free(anames);
+ if (afpos)
+ tcc_free(afpos);
+ if (fh)
+ fclose(fh);
+ if (fo)
+ fclose(fo), remove(tfile);
+ return ret;
+}
+
+/* -------------------------------------------------------------- */
+/*
+ * tiny_impdef creates an export definition file (.def) from a dll
+ * on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]"
+ *
+ * Copyright (c) 2005,2007 grischka
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef TCC_TARGET_PE
+
+ST_FUNC int tcc_tool_impdef(TCCState *s1, int argc, char **argv)
+{
+ int ret, v, i;
+ char infile[260];
+ char outfile[260];
+
+ const char *file;
+ char *p, *q;
+ FILE *fp, *op;
+
+#ifdef _WIN32
+ char path[260];
+#endif
+
+ infile[0] = outfile[0] = 0;
+ fp = op = NULL;
+ ret = 1;
+ p = NULL;
+ v = 0;
+
+ for (i = 1; i < argc; ++i) {
+ const char *a = argv[i];
+ if ('-' == a[0]) {
+ if (0 == strcmp(a, "-v")) {
+ v = 1;
+ } else if (0 == strcmp(a, "-o")) {
+ if (++i == argc)
+ goto usage;
+ strcpy(outfile, argv[i]);
+ } else
+ goto usage;
+ } else if (0 == infile[0])
+ strcpy(infile, a);
+ else
+ goto usage;
+ }
+
+ if (0 == infile[0]) {
+usage:
+ fprintf(stderr,
+ "usage: tcc -impdef library.dll [-v] [-o outputfile]\n"
+ "create export definition file (.def) from dll\n"
+ );
+ goto the_end;
+ }
+
+ if (0 == outfile[0]) {
+ strcpy(outfile, tcc_basename(infile));
+ q = strrchr(outfile, '.');
+ if (NULL == q)
+ q = strchr(outfile, 0);
+ strcpy(q, ".def");
+ }
+
+ file = infile;
+#ifdef _WIN32
+ if (SearchPath(NULL, file, ".dll", sizeof path, path, NULL))
+ file = path;
+#endif
+ ret = tcc_get_dllexports(file, &p);
+ if (ret || !p) {
+ fprintf(stderr, "tcc: impdef: %s '%s'\n",
+ ret == -1 ? "can't find file" :
+ ret == 1 ? "can't read symbols" :
+ ret == 0 ? "no symbols found in" :
+ "unknown file type", file);
+ ret = 1;
+ goto the_end;
+ }
+
+ if (v)
+ printf("-> %s\n", file);
+
+ op = fopen(outfile, "wb");
+ if (NULL == op) {
+ fprintf(stderr, "tcc: impdef: could not create output file: %s\n", outfile);
+ goto the_end;
+ }
+
+ fprintf(op, "LIBRARY %s\n\nEXPORTS\n", tcc_basename(file));
+ for (q = p, i = 0; *q; ++i) {
+ fprintf(op, "%s\n", q);
+ q += strlen(q) + 1;
+ }
+
+ if (v)
+ printf("<- %s (%d symbol%s)\n", outfile, i, &"s"[i<2]);
+
+ ret = 0;
+
+the_end:
+ /* cannot free memory received from tcc_get_dllexports
+ if it came from a dll */
+ /* if (p)
+ tcc_free(p); */
+ if (fp)
+ fclose(fp);
+ if (op)
+ fclose(op);
+ return ret;
+}
+
+#endif /* TCC_TARGET_PE */
+
+/* -------------------------------------------------------------- */
+/*
+ * TCC - Tiny C Compiler
+ *
+ * Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* re-execute the i386/x86_64 cross-compilers with tcc -m32/-m64: */
+
+#if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64
+
+ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option)
+{
+ tcc_error("-m%d not implemented.", option);
+}
+
+#else
+#ifdef _WIN32
+#include <process.h>
+
+static char *str_replace(const char *str, const char *p, const char *r)
+{
+ const char *s, *s0;
+ char *d, *d0;
+ int sl, pl, rl;
+
+ sl = strlen(str);
+ pl = strlen(p);
+ rl = strlen(r);
+ for (d0 = NULL;; d0 = tcc_malloc(sl + 1)) {
+ for (d = d0, s = str; s0 = s, s = strstr(s, p), s; s += pl) {
+ if (d) {
+ memcpy(d, s0, sl = s - s0), d += sl;
+ memcpy(d, r, rl), d += rl;
+ } else
+ sl += rl - pl;
+ }
+ if (d) {
+ strcpy(d, s0);
+ return d0;
+ }
+ }
+}
+
+static int execvp_win32(const char *prog, char **argv)
+{
+ int ret; char **p;
+ /* replace all " by \" */
+ for (p = argv; *p; ++p)
+ if (strchr(*p, '"'))
+ *p = str_replace(*p, "\"", "\\\"");
+ ret = _spawnvp(P_NOWAIT, prog, (const char *const*)argv);
+ if (-1 == ret)
+ return ret;
+ _cwait(&ret, ret, WAIT_CHILD);
+ exit(ret);
+}
+#define execvp execvp_win32
+#endif /* _WIN32 */
+
+ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int target)
+{
+ char program[4096];
+ char *a0 = argv[0];
+ int prefix = tcc_basename(a0) - a0;
+
+ snprintf(program, sizeof program,
+ "%.*s%s"
+#ifdef TCC_TARGET_PE
+ "-win32"
+#endif
+ "-tcc"
+#ifdef _WIN32
+ ".exe"
+#endif
+ , prefix, a0, target == 64 ? "x86_64" : "i386");
+
+ if (strcmp(a0, program))
+ execvp(argv[0] = program, argv);
+ tcc_error("could not run '%s'", program);
+}
+
+#endif /* TCC_TARGET_I386 && TCC_TARGET_X86_64 */
+/* -------------------------------------------------------------- */
+/* enable commandline wildcard expansion (tcc -o x.exe *.c) */
+
+#ifdef _WIN32
+int _CRT_glob = 1;
+#ifndef _CRT_glob
+int _dowildcard = 1;
+#endif
+#endif
+
+/* -------------------------------------------------------------- */
+/* generate xxx.d file */
+
+ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename)
+{
+ FILE *depout;
+ char buf[1024];
+ int i;
+
+ if (!filename) {
+ /* compute filename automatically: dir/file.o -> dir/file.d */
+ snprintf(buf, sizeof buf, "%.*s.d",
+ (int)(tcc_fileextension(target) - target), target);
+ filename = buf;
+ }
+
+ if (s->verbose)
+ printf("<- %s\n", filename);
+
+ /* XXX return err codes instead of error() ? */
+ depout = fopen(filename, "w");
+ if (!depout)
+ tcc_error("could not open '%s'", filename);
+
+ fprintf(depout, "%s: \\\n", target);
+ for (i=0; i<s->nb_target_deps; ++i)
+ fprintf(depout, " %s \\\n", s->target_deps[i]);
+ fprintf(depout, "\n");
+ fclose(depout);
+}
+
+/* -------------------------------------------------------------- */
diff --git a/tests/42test.h b/tests/42test.h
new file mode 100644
index 0000000..5db7d1c
--- /dev/null
+++ b/tests/42test.h
@@ -0,0 +1,13 @@
+/* This file is to test compute #include directives. It's named so
+ that it starts with a pre-processing number which isn't a valid
+ number (42test.h). Including this must work. */
+#ifndef INC42_FIRST
+int have_included_42test_h;
+#define INC42_FIRST
+#elif !defined INC42_SECOND
+#define INC42_SECOND
+int have_included_42test_h_second;
+#else
+#define INC42_THIRD
+int have_included_42test_h_third;
+#endif
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..5f6777d
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,289 @@
+#
+# Tiny C Compiler Makefile - tests
+#
+
+TOP = ..
+include $(TOP)/Makefile
+VPATH = $(TOPSRC)/tests $(TOPSRC) $(TOP)
+CFLAGS := $(filter-out -W% -g% -O%,$(CFLAGS)) -I$(TOPSRC) $(LDFLAGS)
+
+# what tests to run
+TESTS = \
+ hello-exe \
+ hello-run \
+ libtest \
+ test3 \
+ memtest \
+ dlltest \
+ abitest \
+ asm-c-connect-test \
+ vla_test-run \
+ cross-test \
+ tests2-dir \
+ pp-dir
+
+BTESTS = test1b test3b btest
+
+# test4 -- problem with -static
+# asmtest / asmtest2 -- minor differences with gcc
+# btest -- works on i386 (including win32)
+
+# bounds-checking is supported only on i386
+ifneq ($(ARCH),i386)
+ TESTS := $(filter-out $(BTESTS),$(TESTS))
+endif
+ifdef CONFIG_WIN32
+ TESTS := $(filter-out $(BTESTS),$(TESTS))
+endif
+ifdef CONFIG_OSX # -run only
+ TESTS := hello-run libtest tests2-dir pp-dir
+endif
+ifeq (,$(filter arm64 i386 x86_64,$(ARCH)))
+ TESTS := $(filter-out vla_test-run,$(TESTS))
+endif
+ifeq ($(CONFIG_arm_eabi),yes)
+ TESTS := $(filter-out test3,$(TESTS))
+endif
+ifeq (,$(filter i386 x86_64,$(ARCH)))
+ TESTS := $(filter-out dlltest asm-c-connect-test,$(TESTS))
+endif
+ifndef CONFIG_cross
+ TESTS := $(filter-out cross-%,$(TESTS))
+endif
+
+ifeq ($(OS),Windows_NT) # for libtcc_test to find libtcc.dll
+ PATH := $(CURDIR)/$(TOP)$(if $(findstring :\,$(PATH)),;,:)$(PATH)
+endif
+
+RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS)
+DISAS = objdump -d
+DUMPTCC = (set -x; $(TOP)/tcc -vv; ldd $(TOP)/tcc; exit 1)
+
+all test : clean-s $(TESTS)
+
+hello-exe: ../examples/ex1.c
+ @echo ------------ $@ ------------
+ $(TCC) $< -o hello$(EXESUF) && ./hello$(EXESUF) || $(DUMPTCC)
+
+hello-run: ../examples/ex1.c
+ @echo ------------ $@ ------------
+ $(TCC) -run $< || $(DUMPTCC)
+
+libtest: libtcc_test$(EXESUF)
+ @echo ------------ $@ ------------
+ ./libtcc_test$(EXESUF) $(TCCFLAGS)
+
+libtcc_test$(EXESUF): libtcc_test.c $(LIBTCC)
+ $(CC) -o $@ $^ $(CFLAGS) $(LIBS)
+
+%-dir:
+ @echo ------------ $@ ------------
+ $(MAKE) -k -C $*
+
+# test.ref - generate using cc
+test.ref: tcctest.c
+ $(CC) -o tcctest.gcc $< $(NATIVE_DEFINES) $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
+ ./tcctest.gcc > $@
+
+# auto test
+test1 test1b: tcctest.c test.ref
+ @echo ------------ $@ ------------
+ $(TCC) -run $< > test.out1
+ @diff -u test.ref test.out1 && echo "Auto Test OK"
+
+# iterated test2 (compile tcc then compile tcctest.c !)
+test2 test2b: tcctest.c test.ref
+ @echo ------------ $@ ------------
+ $(TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out2
+ @diff -u test.ref test.out2 && echo "Auto Test2 OK"
+
+# iterated test3 (compile tcc then compile tcc then compile tcctest.c !)
+test3 test3b: tcctest.c test.ref
+ @echo ------------ $@ ------------
+ $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3
+ @diff -u test.ref test.out3 && echo "Auto Test3 OK"
+
+test%b : TCCFLAGS += -b
+
+# binary output test
+test4: tcctest.c test.ref
+ @echo ------------ $@ ------------
+# object + link output
+ $(TCC) -c -o tcctest3.o $<
+ $(TCC) -o tcctest3 tcctest3.o
+ ./tcctest3 > test3.out
+ @if diff -u test.ref test3.out ; then echo "Object Auto Test OK"; fi
+# dynamic output
+ $(TCC) -o tcctest1 $<
+ ./tcctest1 > test1.out
+ @if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi
+# dynamic output + bound check
+ $(TCC) -b -o tcctest4 $<
+ ./tcctest4 > test4.out
+ @if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi
+# static output
+ $(TCC) -static -o tcctest2 $<
+ ./tcctest2 > test2.out
+ @if diff -u test.ref test2.out ; then echo "Static Auto Test OK"; fi
+
+# use tcc to create libtcc.so/.dll and the tcc(.exe) frontend and run them
+dlltest:
+ @echo ------------ $@ ------------
+ $(TCC) $(NATIVE_DEFINES) -DLIBTCC_AS_DLL $(TOPSRC)/libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF)
+ $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
+ ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
+ifndef CONFIG_WIN32
+ @echo ------------ $@ with PIC ------------
+ $(CC) $(CFLAGS) -fPIC $(NATIVE_DEFINES) -DLIBTCC_AS_DLL -c $(TOPSRC)/libtcc.c
+ $(TCC) libtcc.o $(LIBS) -shared -o libtcc2$(DLLSUF)
+ $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
+ ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
+endif
+ @rm tcc2$(EXESUF) libtcc2$(DLLSUF)
+
+memtest:
+ @echo ------------ $@ ------------
+ $(CC) $(CFLAGS) $(NATIVE_DEFINES) -DMEM_DEBUG=2 $(TOPSRC)/tcc.c $(LIBS) -o memtest-tcc$(EXESUF)
+ ./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) $(TOPSRC)/tcc.c $(LIBS)
+ ./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS) $(TOPSRC)/tests/tcctest.c
+
+
+# memory and bound check auto test
+BOUNDS_OK = 1 4 8 10 14
+BOUNDS_FAIL= 2 5 7 9 11 12 13 15
+
+btest: boundtest.c
+ @echo ------------ $@ ------------
+ @for i in $(BOUNDS_OK); do \
+ echo ; echo --- boundtest $$i ---; \
+ if $(TCC) -b -run $< $$i ; then \
+ echo succeeded as expected; \
+ else\
+ echo Failed positive test $$i ; exit 1 ; \
+ fi ;\
+ done ;\
+ for i in $(BOUNDS_FAIL); do \
+ echo ; echo --- boundtest $$i ---; \
+ if $(TCC) -b -run $< $$i ; then \
+ echo Failed negative test $$i ; exit 1 ;\
+ else\
+ echo failed as expected; \
+ fi ;\
+ done ;\
+ echo; echo Bound test OK
+
+# speed test
+speedtest: ex2 ex3
+ @echo ------------ $@ ------------
+ time ./ex2 1238 2 3 4 10 13 4
+ time $(TCC) -run $(TOPSRC)/examples/ex2.c 1238 2 3 4 10 13 4
+ time ./ex3 35
+ time $(TCC) -run $(TOPSRC)/examples/ex3.c 35
+
+weaktest: tcctest.c test.ref
+ $(TCC) -c $< -o weaktest.tcc.o
+ $(CC) -c $< -o weaktest.gcc.o $(NATIVE_DEFINES) $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
+ objdump -t weaktest.tcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.tcc.o.txt
+ objdump -t weaktest.gcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.gcc.o.txt
+ diff weaktest.gcc.o.txt weaktest.tcc.o.txt && echo "Weak Auto Test OK"
+
+ex%: $(TOPSRC)/examples/ex%.c
+ $(CC) -o $@ $< $(CFLAGS)
+
+# tiny assembler testing
+asmtest.ref: asmtest.S
+ $(CC) -Wa,-W -o asmtest.ref.o -c asmtest.S
+ objdump -D asmtest.ref.o > asmtest.ref
+
+asmtest asmtest2: asmtest.ref
+ @echo ------------ $@ ------------
+ $(TCC) $(MAYBE_RUN_TCC) -c asmtest.S
+ objdump -D asmtest.o > asmtest.out
+ @if diff -u --ignore-matching-lines="file format" asmtest.ref asmtest.out ; then echo "ASM Auto Test OK"; fi
+
+# test assembler with tcc compiled by itself
+asmtest2: MAYBE_RUN_TCC = $(RUN_TCC)
+
+# Check that code generated by libtcc is binary compatible with
+# that generated by CC
+abitest-cc$(EXESUF): abitest.c $(LIBTCC)
+ $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -w
+
+abitest-tcc$(EXESUF): abitest.c libtcc.c
+ $(TCC) -o $@ $^ $(NATIVE_DEFINES) $(LIBS)
+
+ABITESTS := abitest-cc$(EXESUF)
+ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
+ ABITESTS += abitest-tcc$(EXESUF)
+endif
+
+abitest: $(ABITESTS)
+ @echo ------------ $@ ------------
+ ./abitest-cc$(EXESUF) $(TCCFLAGS)
+ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
+ ./abitest-tcc$(EXESUF) $(TCCFLAGS)
+endif
+
+vla_test$(EXESUF): vla_test.c
+ $(TCC) -o $@ $^
+
+vla_test-run: vla_test$(EXESUF)
+ @echo ------------ $@ ------------
+ ./vla_test$(EXESUF)
+
+asm-c-connect$(EXESUF): asm-c-connect-1.c asm-c-connect-2.c
+ $(TCC) -o $@ $^
+
+asm-c-connect-%.o: asm-c-connect-%.c
+ $(TCC) -c -o $@ $<
+
+asm-c-connect-sep$(EXESUF): asm-c-connect-1.o asm-c-connect-2.o
+ $(TCC) -o $@ $^
+
+asm-c-connect-test: asm-c-connect$(EXESUF) asm-c-connect-sep$(EXESUF)
+ @echo ------------ $@ ------------
+ ./asm-c-connect$(EXESUF) > asm-c-connect.out1 && cat asm-c-connect.out1
+ ./asm-c-connect-sep$(EXESUF) > asm-c-connect.out2 && cat asm-c-connect.out2
+ @diff -u asm-c-connect.out1 asm-c-connect.out2 && echo "ok"
+
+cross-test :
+ @echo ------------ $@ ------------
+ $(TOP)/i386-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/x86_64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/arm-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/arm64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/c67-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+ $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
+ $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
+ $(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
+
+# targets for development
+%.bin: %.c tcc
+ $(TCC) -g -o $@ $<
+ $(DISAS) $@
+
+instr: instr.o
+ objdump -d instr.o
+
+instr.o: instr.S
+ $(CC) -o $@ -c $< -O2 -Wall -g
+
+cache: tcc_g
+ cachegrind ./tcc_g -o /tmp/linpack -lm bench/linpack.c
+ vg_annotate tcc.c > /tmp/linpack.cache.log
+
+# clean
+clean:
+ rm -f *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc *.gcc
+ rm -f *-cc *-gcc *-tcc *.exe hello libtcc_test vla_test tcctest[1234]
+ rm -f asm-c-connect$(EXESUF)
+ rm -f ex? tcc_g weaktest.*.txt *.def
+ @$(MAKE) -C tests2 $@
+ @$(MAKE) -C pp $@
+
+# silent clean, used before running tests
+clean-s:
+ @$(MAKE) -s --no-print-directory clean
diff --git a/tests/abitest.c b/tests/abitest.c
new file mode 100644
index 0000000..4a192bd
--- /dev/null
+++ b/tests/abitest.c
@@ -0,0 +1,691 @@
+#include <libtcc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
+#if defined(_WIN32) && defined(__GNUC__)
+#define LONG_DOUBLE double
+#define LONG_DOUBLE_LITERAL(x) x
+#else
+#define LONG_DOUBLE long double
+#define LONG_DOUBLE_LITERAL(x) x ## L
+#endif
+
+static int g_argc;
+static char **g_argv;
+
+static void set_options(TCCState *s, int argc, char **argv)
+{
+ int i;
+ for (i = 1; i < argc; ++i) {
+ char *a = argv[i];
+ if (a[0] == '-') {
+ if (a[1] == 'B')
+ tcc_set_lib_path(s, a+2);
+ else if (a[1] == 'I')
+ tcc_add_include_path(s, a+2);
+ else if (a[1] == 'L')
+ tcc_add_library_path(s, a+2);
+ }
+ }
+}
+
+typedef int (*callback_type) (void*);
+
+/*
+ * Compile source code and call a callback with a pointer to the symbol "f".
+ */
+static int run_callback(const char *src, callback_type callback) {
+ TCCState *s;
+ int result;
+ void *ptr;
+
+ s = tcc_new();
+ if (!s)
+ return -1;
+
+ set_options(s, g_argc, g_argv);
+
+ if (tcc_set_output_type(s, TCC_OUTPUT_MEMORY) == -1)
+ return -1;
+ if (tcc_compile_string(s, src) == -1)
+ return -1;
+ if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1)
+ return -1;
+
+ ptr = tcc_get_symbol(s, "f");
+ if (!ptr)
+ return -1;
+ result = callback(ptr);
+
+ tcc_delete(s);
+
+ return result;
+}
+
+#define STR2(x) #x
+#define STR(x) STR2(x)
+
+#define RET_PRIMITIVE_TEST(name, type, val) \
+ static int ret_ ## name ## _test_callback(void *ptr) { \
+ type (*callback) (type) = (type(*)(type))ptr; \
+ type x = val; \
+ type y = callback(x); \
+ return (y == x+x) ? 0 : -1; \
+ } \
+ \
+ static int ret_ ## name ## _test(void) { \
+ const char *src = STR(type) " f(" STR(type) " x) {return x+x;}"; \
+ return run_callback(src, ret_ ## name ## _test_callback); \
+ }
+
+RET_PRIMITIVE_TEST(int, int, 70000)
+RET_PRIMITIVE_TEST(longlong, long long, 4333369356528LL)
+RET_PRIMITIVE_TEST(float, float, 63.0)
+RET_PRIMITIVE_TEST(double, double, 14789798.0)
+RET_PRIMITIVE_TEST(longdouble, LONG_DOUBLE, LONG_DOUBLE_LITERAL(378943892.0))
+
+/*
+ * ret_2float_test:
+ *
+ * On x86-64, a struct with 2 floats should be packed into a single
+ * SSE register (VT_DOUBLE is used for this purpose).
+ */
+typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;
+typedef ret_2float_test_type (*ret_2float_test_function_type) (ret_2float_test_type);
+
+static int ret_2float_test_callback(void *ptr) {
+ ret_2float_test_function_type f = (ret_2float_test_function_type)ptr;
+ ret_2float_test_type a = {10, 35};
+ ret_2float_test_type r;
+ r = f(a);
+ return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_2float_test(void) {
+ const char *src =
+ "typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;"
+ "ret_2float_test_type f(ret_2float_test_type a) {\n"
+ " ret_2float_test_type r = {a.x*5, a.y*3};\n"
+ " return r;\n"
+ "}\n";
+
+ return run_callback(src, ret_2float_test_callback);
+}
+
+/*
+ * ret_2double_test:
+ *
+ * On x86-64, a struct with 2 doubles should be passed in two SSE
+ * registers.
+ */
+typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;
+typedef ret_2double_test_type (*ret_2double_test_function_type) (ret_2double_test_type);
+
+static int ret_2double_test_callback(void *ptr) {
+ ret_2double_test_function_type f = (ret_2double_test_function_type)ptr;
+ ret_2double_test_type a = {10, 35};
+ ret_2double_test_type r;
+ r = f(a);
+ return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_2double_test(void) {
+ const char *src =
+ "typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;"
+ "ret_2double_test_type f(ret_2double_test_type a) {\n"
+ " ret_2double_test_type r = {a.x*5, a.y*3};\n"
+ " return r;\n"
+ "}\n";
+
+ return run_callback(src, ret_2double_test_callback);
+}
+
+/*
+ * ret_8plus2double_test:
+ *
+ * This catches a corner case in the x86_64 ABI code: the first 7
+ * arguments fit into registers, the 8th doesn't, but the 9th argument
+ * fits into the 8th XMM register.
+ *
+ * Note that the purpose of the 10th argument is to avoid a situation
+ * in which gcc would accidentally put the double at the right
+ * address, thus causing a success message even though TCC actually
+ * generated incorrect code.
+ */
+typedef ret_2double_test_type (*ret_8plus2double_test_function_type) (double, double, double, double, double, double, double, ret_2double_test_type, double, double);
+
+static int ret_8plus2double_test_callback(void *ptr) {
+ ret_8plus2double_test_function_type f = (ret_8plus2double_test_function_type)ptr;
+ ret_2double_test_type a = {10, 35};
+ ret_2double_test_type r;
+ r = f(0, 0, 0, 0, 0, 0, 0, a, 37, 38);
+ return ((r.x == 37) && (r.y == 37)) ? 0 : -1;
+}
+
+static int ret_8plus2double_test(void) {
+ const char *src =
+ "typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;"
+ "ret_2double_test_type f(double x1, double x2, double x3, double x4, double x5, double x6, double x7, ret_2double_test_type a, double x8, double x9) {\n"
+ " ret_2double_test_type r = { x8, x8 };\n"
+ " return r;\n"
+ "}\n";
+
+ return run_callback(src, ret_8plus2double_test_callback);
+}
+
+/*
+ * ret_mixed_test:
+ *
+ * On x86-64, a struct with a double and a 64-bit integer should be
+ * passed in one SSE register and one integer register.
+ */
+typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;
+typedef ret_mixed_test_type (*ret_mixed_test_function_type) (ret_mixed_test_type);
+
+static int ret_mixed_test_callback(void *ptr) {
+ ret_mixed_test_function_type f = (ret_mixed_test_function_type)ptr;
+ ret_mixed_test_type a = {10, 35};
+ ret_mixed_test_type r;
+ r = f(a);
+ return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_mixed_test(void) {
+ const char *src =
+ "typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;"
+ "ret_mixed_test_type f(ret_mixed_test_type a) {\n"
+ " ret_mixed_test_type r = {a.x*5, a.y*3};\n"
+ " return r;\n"
+ "}\n";
+
+ return run_callback(src, ret_mixed_test_callback);
+}
+
+/*
+ * ret_mixed2_test:
+ *
+ * On x86-64, a struct with two floats and two 32-bit integers should
+ * be passed in one SSE register and one integer register.
+ */
+typedef struct ret_mixed2_test_type_s {float x,x2; int y,y2;} ret_mixed2_test_type;
+typedef ret_mixed2_test_type (*ret_mixed2_test_function_type) (ret_mixed2_test_type);
+
+static int ret_mixed2_test_callback(void *ptr) {
+ ret_mixed2_test_function_type f = (ret_mixed2_test_function_type)ptr;
+ ret_mixed2_test_type a = {10, 5, 35, 7 };
+ ret_mixed2_test_type r;
+ r = f(a);
+ return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_mixed2_test(void) {
+ const char *src =
+ "typedef struct ret_mixed2_test_type_s {float x, x2; int y,y2;} ret_mixed2_test_type;"
+ "ret_mixed2_test_type f(ret_mixed2_test_type a) {\n"
+ " ret_mixed2_test_type r = {a.x*5, 0, a.y*3, 0};\n"
+ " return r;\n"
+ "}\n";
+
+ return run_callback(src, ret_mixed2_test_callback);
+}
+
+/*
+ * ret_mixed3_test:
+ *
+ * On x86-64, this struct should be passed in two integer registers.
+ */
+typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type;
+typedef ret_mixed3_test_type (*ret_mixed3_test_function_type) (ret_mixed3_test_type);
+
+static int ret_mixed3_test_callback(void *ptr) {
+ ret_mixed3_test_function_type f = (ret_mixed3_test_function_type)ptr;
+ ret_mixed3_test_type a = {10, 5, 35, 7 };
+ ret_mixed3_test_type r;
+ r = f(a);
+ return ((r.x == a.x*5) && (r.y2 == a.y*3)) ? 0 : -1;
+}
+
+static int ret_mixed3_test(void) {
+ const char *src =
+ "typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type;"
+ "ret_mixed3_test_type f(ret_mixed3_test_type a) {\n"
+ " ret_mixed3_test_type r = {a.x*5, 0, 0, a.y*3};\n"
+ " return r;\n"
+ "}\n";
+
+ return run_callback(src, ret_mixed3_test_callback);
+}
+
+/*
+ * reg_pack_test: return a small struct which should be packed into
+ * registers (Win32) during return.
+ */
+typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;
+typedef reg_pack_test_type (*reg_pack_test_function_type) (reg_pack_test_type);
+
+static int reg_pack_test_callback(void *ptr) {
+ reg_pack_test_function_type f = (reg_pack_test_function_type)ptr;
+ reg_pack_test_type a = {10, 35};
+ reg_pack_test_type r;
+ r = f(a);
+ return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int reg_pack_test(void) {
+ const char *src =
+ "typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;"
+ "reg_pack_test_type f(reg_pack_test_type a) {\n"
+ " reg_pack_test_type r = {a.x*5, a.y*3};\n"
+ " return r;\n"
+ "}\n";
+
+ return run_callback(src, reg_pack_test_callback);
+}
+
+/*
+ * reg_pack_longlong_test: return a small struct which should be packed into
+ * registers (x86-64) during return.
+ */
+typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;
+typedef reg_pack_longlong_test_type (*reg_pack_longlong_test_function_type) (reg_pack_longlong_test_type);
+
+static int reg_pack_longlong_test_callback(void *ptr) {
+ reg_pack_longlong_test_function_type f = (reg_pack_longlong_test_function_type)ptr;
+ reg_pack_longlong_test_type a = {10, 35};
+ reg_pack_longlong_test_type r;
+ r = f(a);
+ return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int reg_pack_longlong_test(void) {
+ const char *src =
+ "typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;"
+ "reg_pack_longlong_test_type f(reg_pack_longlong_test_type a) {\n"
+ " reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n"
+ " return r;\n"
+ "}\n";
+
+ return run_callback(src, reg_pack_longlong_test_callback);
+}
+
+/*
+ * ret_6plus2longlong_test:
+ *
+ * This catches a corner case in the x86_64 ABI code: the first 5
+ * arguments fit into registers, the 6th doesn't, but the 7th argument
+ * fits into the 6th argument integer register, %r9.
+ *
+ * Note that the purpose of the 10th argument is to avoid a situation
+ * in which gcc would accidentally put the longlong at the right
+ * address, thus causing a success message even though TCC actually
+ * generated incorrect code.
+ */
+typedef reg_pack_longlong_test_type (*ret_6plus2longlong_test_function_type) (long long, long long, long long, long long, long long, reg_pack_longlong_test_type, long long, long long);
+
+static int ret_6plus2longlong_test_callback(void *ptr) {
+ ret_6plus2longlong_test_function_type f = (ret_6plus2longlong_test_function_type)ptr;
+ reg_pack_longlong_test_type a = {10, 35};
+ reg_pack_longlong_test_type r;
+ r = f(0, 0, 0, 0, 0, a, 37, 38);
+ return ((r.x == 37) && (r.y == 37)) ? 0 : -1;
+}
+
+static int ret_6plus2longlong_test(void) {
+ const char *src =
+ "typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;"
+ "reg_pack_longlong_test_type f(long long x1, long long x2, long long x3, long long x4, long long x5, reg_pack_longlong_test_type a, long long x8, long long x9) {\n"
+ " reg_pack_longlong_test_type r = { x8, x8 };\n"
+ " return r;\n"
+ "}\n";
+
+ return run_callback(src, ret_6plus2longlong_test_callback);
+}
+
+/*
+ * sret_test: Create a struct large enough to be returned via sret
+ * (hidden pointer as first function argument)
+ */
+typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;
+typedef sret_test_type (*sret_test_function_type) (sret_test_type);
+
+static int sret_test_callback(void *ptr) {
+ sret_test_function_type f = (sret_test_function_type)(ptr);
+ sret_test_type x = {5436LL, 658277698LL, 43878957LL};
+ sret_test_type r = f(x);
+ return ((r.a==x.a*35)&&(r.b==x.b*19)&&(r.c==x.c*21)) ? 0 : -1;
+}
+
+static int sret_test(void) {
+ const char *src =
+ "typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;\n"
+ "sret_test_type f(sret_test_type x) {\n"
+ " sret_test_type r = {x.a*35, x.b*19, x.c*21};\n"
+ " return r;\n"
+ "}\n";
+
+ return run_callback(src, sret_test_callback);
+}
+
+/*
+ * one_member_union_test:
+ *
+ * In the x86-64 ABI a union should always be passed on the stack. However
+ * it appears that a single member union is treated by GCC as its member.
+ */
+typedef union one_member_union_test_type_u {int x;} one_member_union_test_type;
+typedef one_member_union_test_type (*one_member_union_test_function_type) (one_member_union_test_type);
+
+static int one_member_union_test_callback(void *ptr) {
+ one_member_union_test_function_type f = (one_member_union_test_function_type)ptr;
+ one_member_union_test_type a, b;
+ a.x = 34;
+ b = f(a);
+ return (b.x == a.x*2) ? 0 : -1;
+}
+
+static int one_member_union_test(void) {
+ const char *src =
+ "typedef union one_member_union_test_type_u {int x;} one_member_union_test_type;\n"
+ "one_member_union_test_type f(one_member_union_test_type a) {\n"
+ " one_member_union_test_type b;\n"
+ " b.x = a.x * 2;\n"
+ " return b;\n"
+ "}\n";
+ return run_callback(src, one_member_union_test_callback);
+}
+
+/*
+ * two_member_union_test:
+ *
+ * In the x86-64 ABI a union should always be passed on the stack.
+ */
+typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;
+typedef two_member_union_test_type (*two_member_union_test_function_type) (two_member_union_test_type);
+
+static int two_member_union_test_callback(void *ptr) {
+ two_member_union_test_function_type f = (two_member_union_test_function_type)ptr;
+ two_member_union_test_type a, b;
+ a.x = 34;
+ b = f(a);
+ return (b.x == a.x*2) ? 0 : -1;
+}
+
+static int two_member_union_test(void) {
+ const char *src =
+ "typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;\n"
+ "two_member_union_test_type f(two_member_union_test_type a) {\n"
+ " two_member_union_test_type b;\n"
+ " b.x = a.x * 2;\n"
+ " return b;\n"
+ "}\n";
+ return run_callback(src, two_member_union_test_callback);
+}
+
+/*
+ * Win64 calling convention test.
+ */
+
+typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;
+typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type);
+
+static int many_struct_test_callback(void *ptr) {
+ many_struct_test_function_type f = (many_struct_test_function_type)ptr;
+ many_struct_test_type v = {1, 2, 3};
+ many_struct_test_type r = f(v,v,v,v,v,v);
+ return ((r.a == 6) && (r.b == 12) && (r.c == 18))?0:-1;
+}
+
+static int many_struct_test(void) {
+ const char *src =
+ "typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;\n"
+ "many_struct_test_type f(many_struct_test_type x1, many_struct_test_type x2, many_struct_test_type x3, many_struct_test_type x4, many_struct_test_type x5, many_struct_test_type x6) {\n"
+ " many_struct_test_type y;\n"
+ " y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
+ " y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
+ " y.c = x1.c + x2.c + x3.c + x4.c + x5.c + x6.c;\n"
+ " return y;\n"
+ "}\n";
+ return run_callback(src, many_struct_test_callback);
+}
+
+/*
+ * Win64 calling convention test.
+ */
+
+typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;
+typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type);
+
+static int many_struct_test_2_callback(void *ptr) {
+ many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr;
+ many_struct_test_2_type v = {1,2};
+ many_struct_test_2_type r = f(v,v,v,v,v,v);
+ return ((r.a == 6) && (r.b == 12))?0:-1;
+}
+
+static int many_struct_test_2(void) {
+ const char *src =
+ "typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;\n"
+ "many_struct_test_2_type f(many_struct_test_2_type x1, many_struct_test_2_type x2, many_struct_test_2_type x3, many_struct_test_2_type x4, many_struct_test_2_type x5, many_struct_test_2_type x6) {\n"
+ " many_struct_test_2_type y;\n"
+ " y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
+ " y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
+ " return y;\n"
+ "}\n";
+ return run_callback(src, many_struct_test_2_callback);
+}
+
+/*
+ * Win64 calling convention test.
+ */
+
+typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type;
+typedef many_struct_test_3_type (*many_struct_test_3_function_type) (many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type, ...);
+typedef struct many_struct_test_3_struct_type { many_struct_test_3_function_type f; many_struct_test_3_function_type *f2; } many_struct_test_3_struct_type;
+
+static void many_struct_test_3_dummy(double d, ...)
+{
+ volatile double x = d;
+}
+
+static int many_struct_test_3_callback(void *ptr) {
+ many_struct_test_3_struct_type s = { ptr, };
+ many_struct_test_3_struct_type *s2 = &s;
+ s2->f2 = &s2->f;
+ many_struct_test_3_dummy(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, &s2);
+ many_struct_test_3_function_type f = *(s2->f2);
+ many_struct_test_3_type v = {1,2};
+ many_struct_test_3_type r = (*((s2->f2=&f)+0))(v,v,v,v,v,v,1.0);
+ return ((r.a == 6) && (r.b == 12))?0:-1;
+}
+
+static int many_struct_test_3(void) {
+ const char *src =
+ "typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type;\n"
+ "many_struct_test_3_type f(many_struct_test_3_type x1, many_struct_test_3_type x2, many_struct_test_3_type x3, many_struct_test_3_type x4, many_struct_test_3_type x5, many_struct_test_3_type x6, ...) {\n"
+ " many_struct_test_3_type y;\n"
+ " y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
+ " y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
+ " return y;\n"
+ "}\n";
+ return run_callback(src, many_struct_test_3_callback);
+}
+
+/*
+ * stdarg_test: Test variable argument list ABI
+ */
+
+typedef struct {long long a, b, c;} stdarg_test_struct_type;
+typedef void (*stdarg_test_function_type) (int,int,int,...);
+
+static int stdarg_test_callback(void *ptr) {
+ stdarg_test_function_type f = (stdarg_test_function_type)ptr;
+ int x;
+ double y;
+ stdarg_test_struct_type z = {1, 2, 3}, w;
+ f(10, 10, 5,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &x,
+ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, &y,
+ z, z, z, z, z, &w);
+ return ((x == 55) && (y == 55) && (w.a == 5) && (w.b == 10) && (w.c == 15)) ? 0 : -1;
+}
+
+static int stdarg_test(void) {
+ const char *src =
+ "#include <stdarg.h>\n"
+ "typedef struct {long long a, b, c;} stdarg_test_struct_type;\n"
+ "void f(int n_int, int n_float, int n_struct, ...) {\n"
+ " int i, ti = 0;\n"
+ " double td = 0.0;\n"
+ " stdarg_test_struct_type ts = {0,0,0}, tmp;\n"
+ " va_list ap;\n"
+ " va_start(ap, n_struct);\n"
+ " for (i = 0, ti = 0; i < n_int; ++i)\n"
+ " ti += va_arg(ap, int);\n"
+ " *va_arg(ap, int*) = ti;\n"
+ " for (i = 0, td = 0; i < n_float; ++i)\n"
+ " td += va_arg(ap, double);\n"
+ " *va_arg(ap, double*) = td;\n"
+ " for (i = 0; i < n_struct; ++i) {\n"
+ " tmp = va_arg(ap, stdarg_test_struct_type);\n"
+ " ts.a += tmp.a; ts.b += tmp.b; ts.c += tmp.c;"
+ " }\n"
+ " *va_arg(ap, stdarg_test_struct_type*) = ts;\n"
+ " va_end(ap);"
+ "}\n";
+ return run_callback(src, stdarg_test_callback);
+}
+
+typedef struct {long long a, b;} stdarg_many_test_struct_type;
+typedef void (*stdarg_many_test_function_type) (int, int, int, int, int,
+ stdarg_many_test_struct_type,
+ int, int, ...);
+
+static int stdarg_many_test_callback(void *ptr)
+{
+ stdarg_many_test_function_type f = (stdarg_many_test_function_type)ptr;
+ int x;
+ stdarg_many_test_struct_type l = {10, 11};
+ f(1, 2, 3, 4, 5, l, 6, 7, &x, 44);
+ return x == 44 ? 0 : -1;
+}
+
+static int stdarg_many_test(void)
+{
+ const char *src =
+ "#include <stdarg.h>\n"
+ "typedef struct {long long a, b;} stdarg_many_test_struct_type;\n"
+ "void f (int a, int b, int c, int d, int e, stdarg_many_test_struct_type l, int f, int g, ...){\n"
+ " va_list ap;\n"
+ " int *p;\n"
+ " va_start (ap, g);\n"
+ " p = va_arg(ap, int*);\n"
+ " *p = va_arg(ap, int);\n"
+ " va_end (ap);\n"
+ "}\n";
+ return run_callback(src, stdarg_many_test_callback);
+}
+
+/*
+ * Test Win32 stdarg handling, since the calling convention will pass a pointer
+ * to the struct and the stdarg pointer must point to that pointer initially.
+ */
+
+typedef struct {long long a, b, c;} stdarg_struct_test_struct_type;
+typedef int (*stdarg_struct_test_function_type) (stdarg_struct_test_struct_type a, ...);
+
+static int stdarg_struct_test_callback(void *ptr) {
+ stdarg_struct_test_function_type f = (stdarg_struct_test_function_type)ptr;
+ stdarg_struct_test_struct_type v = {10, 35, 99};
+ int x = f(v, 234);
+ return (x == 378) ? 0 : -1;
+}
+
+static int stdarg_struct_test(void) {
+ const char *src =
+ "#include <stdarg.h>\n"
+ "typedef struct {long long a, b, c;} stdarg_struct_test_struct_type;\n"
+ "int f(stdarg_struct_test_struct_type a, ...) {\n"
+ " va_list ap;\n"
+ " va_start(ap, a);\n"
+ " int z = va_arg(ap, int);\n"
+ " va_end(ap);\n"
+ " return z + a.a + a.b + a.c;\n"
+ "}\n";
+ return run_callback(src, stdarg_struct_test_callback);
+}
+
+/* Test that x86-64 arranges the stack correctly for arguments with alignment >8 bytes */
+
+typedef LONG_DOUBLE (*arg_align_test_callback_type) (LONG_DOUBLE,int,LONG_DOUBLE,int,LONG_DOUBLE);
+
+static int arg_align_test_callback(void *ptr) {
+ arg_align_test_callback_type f = (arg_align_test_callback_type)ptr;
+ long double x = f(12, 0, 25, 0, 37);
+ return (x == 74) ? 0 : -1;
+}
+
+static int arg_align_test(void) {
+ const char *src =
+ "long double f(long double a, int b, long double c, int d, long double e) {\n"
+ " return a + c + e;\n"
+ "}\n";
+ return run_callback(src, arg_align_test_callback);
+}
+
+#define RUN_TEST(t) \
+ if (!testname || (strcmp(#t, testname) == 0)) { \
+ fputs(#t "... ", stdout); \
+ fflush(stdout); \
+ if (t() == 0) { \
+ fputs("success\n", stdout); \
+ } else { \
+ fputs("failure\n", stdout); \
+ retval = EXIT_FAILURE; \
+ } \
+ }
+
+int main(int argc, char **argv) {
+ int i;
+ const char *testname = NULL;
+ int retval = EXIT_SUCCESS;
+
+ /* if tcclib.h and libtcc1.a are not installed, where can we find them */
+ for (i = 1; i < argc; ++i) {
+ if (!memcmp(argv[i], "run_test=", 9))
+ testname = argv[i] + 9;
+ }
+
+ g_argv = argv, g_argc = argc;
+
+ RUN_TEST(ret_int_test);
+ RUN_TEST(ret_longlong_test);
+ RUN_TEST(ret_float_test);
+ RUN_TEST(ret_double_test);
+ RUN_TEST(ret_longdouble_test);
+ RUN_TEST(ret_2float_test);
+ RUN_TEST(ret_2double_test);
+ RUN_TEST(ret_8plus2double_test);
+ RUN_TEST(ret_6plus2longlong_test);
+#if !defined __x86_64__ || defined _WIN32
+ /* currently broken on x86_64 linux */
+ RUN_TEST(ret_mixed_test);
+ RUN_TEST(ret_mixed2_test);
+#endif
+ RUN_TEST(ret_mixed3_test);
+ RUN_TEST(reg_pack_test);
+ RUN_TEST(reg_pack_longlong_test);
+ RUN_TEST(sret_test);
+ RUN_TEST(one_member_union_test);
+ RUN_TEST(two_member_union_test);
+ RUN_TEST(many_struct_test);
+ RUN_TEST(many_struct_test_2);
+ RUN_TEST(many_struct_test_3);
+ RUN_TEST(stdarg_test);
+ RUN_TEST(stdarg_many_test);
+ RUN_TEST(stdarg_struct_test);
+ RUN_TEST(arg_align_test);
+ return retval;
+}
diff --git a/tests/asm-c-connect-1.c b/tests/asm-c-connect-1.c
new file mode 100644
index 0000000..8a28d78
--- /dev/null
+++ b/tests/asm-c-connect-1.c
@@ -0,0 +1,57 @@
+#include <stdio.h>
+
+#if defined _WIN32 && !defined __TINYC__
+# define _ "_"
+#else
+# define _
+#endif
+
+static int x1_c(void)
+{
+ printf(" x1");
+ return 1;
+}
+
+asm(".text;"_"x1: call "_"x1_c; ret");
+
+void callx4(void);
+void callx5_again(void);
+
+void x6()
+{
+ printf(" x6-1");
+}
+
+int main(int argc, char *argv[])
+{
+ printf("*");
+ asm("call "_"x1");
+ asm("call "_"x2");
+ asm("call "_"x3");
+ callx4();
+ asm("call "_"x5");
+ callx5_again();
+ x6();
+ printf(" *\n");
+ return 0;
+}
+
+static
+int x2(void)
+{
+ printf(" x2");
+ return 2;
+}
+
+extern int x3(void);
+
+void x4(void)
+{
+ printf(" x4");
+}
+
+void x5(void);
+void x5(void)
+{
+ printf(" x5");
+}
diff --git a/tests/asm-c-connect-2.c b/tests/asm-c-connect-2.c
new file mode 100644
index 0000000..3440b40
--- /dev/null
+++ b/tests/asm-c-connect-2.c
@@ -0,0 +1,36 @@
+#include <stdio.h>
+
+#if defined _WIN32 && !defined __TINYC__
+# define _ "_"
+#else
+# define _
+#endif
+
+int x3(void)
+{
+ printf(" x3");
+ return 3;
+}
+
+/* That callx4 is defined globally (as if ".globl callx4")
+ is a TCC extension. GCC doesn't behave like this. */
+void callx4(void);
+__asm__(_"callx4: call "_"x4; ret;"
+#ifndef __TINYC__
+ " .global "_"callx4"
+#endif
+);
+
+extern void x5(void);
+
+void callx5_again(void);
+void callx5_again(void)
+{
+ x5();
+ asm("call "_"x6");
+}
+
+static void x6()
+{
+ printf(" x6-2");
+}
diff --git a/tests/asmtest.S b/tests/asmtest.S
new file mode 100644
index 0000000..e9c0e32
--- /dev/null
+++ b/tests/asmtest.S
@@ -0,0 +1,978 @@
+# gas comment with ``gnu'' style quotes
+
+/* some directive tests */
+
+ .byte 0xff
+ .byte 1, 2, 3
+ .short 1, 2, 3
+ .word 1, 2, 3
+ .long 1, 2, 3
+ .int 1, 2, 3
+ .align 8
+ .byte 1
+/* .align 16, 0x90 gas is too clever for us with 0x90 fill */
+ .balign 4, 0x92
+ .align 16, 0x91 /* 0x91 tests the non-clever behaviour */
+ .skip 3
+ .skip 15, 0x90
+ .string "hello\0world"
+/* Macro expansion should work like with C, the #n shouldn't be parsed
+ as asm line comment */
+#define __stringify(n) #n
+#define stringify(n) __stringify(n)
+ .skip 8,0x90
+ .asciz stringify(BLA)
+ .skip 8,0x90
+
+# 28 "asmtest.S" # a line directive (and a line comment)
+ movl %eax, %ebx # some more asm comment
+/* some label tests */
+L1:
+ movl %eax, %ebx
+ mov 0x10000, %eax
+L2:
+ movl $L2 - L1, %ecx
+var1:
+ nop ; nop ; nop ; nop
+
+ mov var1, %eax
+
+/* instruction tests */
+movl %eax, %ebx
+mov 0x10000, %eax
+mov 0x10000, %ax
+mov 0x10000, %al
+mov %al, 0x10000
+
+mov $1, %edx
+mov $1, %dx
+mov $1, %cl
+movb $2, 0x100(%ebx,%edx,2)
+movw $2, 0x100(%ebx,%edx,2)
+movl $2, 0x100(%ebx,%edx,2)
+movl %eax, 0x100(%ebx,%edx,2)
+movl 0x100(%ebx,%edx,2), %edx
+movw %ax, 0x100(%ebx,%edx,2)
+
+movw $0x1122,%si
+movl $0x112233,%edx
+movl $0x80000000, %esi
+movl $-0x7fffffff, %edi
+#ifdef __x86_64__
+mov $0x11223344,%rbx
+movq $0x11223344,%rbx
+mov $0x1122334455,%rbx
+movq $0x1122334455,%rbx
+movl $0x11334455,(%rbx)
+#endif
+
+mov %eax, 0x12(,%edx,2)
+
+#ifdef __i386__
+mov %cr3, %edx
+mov %ecx, %cr3
+movl %cr3, %eax
+movl %tr3, %eax
+movl %db3, %ebx
+movl %dr6, %eax
+#else
+mov %cr3, %rdx
+mov %rcx, %cr3
+movq %cr3, %rax
+movq %db3, %rbx
+movq %dr6, %rax
+mov %cr8, %rsi
+mov %rdi, %cr8
+#endif
+movl %fs, %ecx
+movl %ebx, %fs
+
+#ifdef __x86_64__
+movq %r8, %r9
+movq %r10, %r11
+movq %r12, %r13
+movq %r14, %r15
+movq %rax, %r9
+movq %r15, %rsi
+inc %r9b
+dec %r10w
+not %r11d
+negq %r12
+decb %r13b
+incw %r14w
+notl %r15d
+#endif
+
+ movsbl 0x1000, %eax
+ movsbw 0x1000, %ax
+ movswl 0x1000, %eax
+
+ movzbl 0x1000, %eax
+ movzbw 0x1000, %ax
+ movzwl 0x1000, %eax
+
+ movzb 0x1000, %eax
+ movzb 0x1000, %ax
+
+ mov $0x12345678,%eax
+
+#ifdef __x86_64__
+ movzb 0x1000, %rax
+ movzbq 0x1000, %rbx
+ movsbq 0x1000, %rdx
+ movzwq 0x1000, %rdi
+ movswq 0x1000, %rdx
+ movslq %eax, %rcx
+ mov $0x12345678,%rax
+ mov $0x12345678,%rdx
+ mov $0x12345678,%r10
+ mov $0x123456789abcdef0,%rax
+ mov $0x123456789abcdef0,%rcx
+ mov $0x123456789abcdef0,%r11
+#endif
+
+#ifdef __i386__
+ pushl %eax
+ push %eax
+ push %cs
+#else
+ pushq %rax
+ push %rax
+#endif
+ pushw %ax
+ push %gs
+ push $1
+ push $100
+ push 0x42(%eax)
+ pop 0x43(%esi)
+
+#ifdef __i386__
+ popl %eax
+ pop %eax
+ pop %ds
+#else
+ popq %rax
+ pop %rax
+#endif
+ popw %ax
+ pop %fs
+
+ xchg %eax, %ecx
+ xchg %edx, %eax
+ xchg %bx, 0x10000
+ xchg 0x10000, %ebx
+ xchg 0x10000, %dl
+
+ in $100, %al
+ in $100, %ax
+ in $100, %eax
+ in %dx, %al
+ in %dx, %ax
+ in %dx, %eax
+ inb %dx
+ inw %dx
+ inl %dx
+
+ out %al, $100
+ out %ax, $100
+ out %eax, $100
+
+ /* NOTE: gas is bugged here, so size must be added */
+ outb %al, %dx
+ outw %ax, %dx
+ outl %eax, %dx
+
+ leal 0x1000(%ebx), %ecx
+ lea 0x1000(%ebx), %ecx
+
+#ifdef __i386__
+ les 0x2000, %eax
+ lds 0x2000, %ebx
+ lss 0x2000, %edx
+#endif
+ lfs 0x2000, %ecx
+ lgs 0x2000, %edx
+
+addl $0x123, %eax
+add $0x123, %ebx
+add $-16, %ecx
+add $-0x123, %esi
+add $1, %bx
+add $1, %ebx
+add $-1, %bx
+add $-1, %ebx
+add $127, %bx
+addl $127, %ebx
+addl $-128, %ebx
+addl $-128, %ebx
+addl $-129, %ebx
+addl $128, %ebx
+addl $255, %ebx
+addl $256, %ebx
+andb $0xf, %ah
+andb $-15, %cl
+xorb $127, %dh
+cmpb $42, (%eax)
+addl $0x123, 0x100
+addl $0x123, 0x100(%ebx)
+addl $0x123, 0x100(%ebx,%edx,2)
+addl $0x123, 0x100(%esp)
+addl $0x123, (3*8)(%esp)
+addl $0x123, (%ebp)
+addl $0x123, (%esp)
+cmpl $0x123, (%esp)
+
+#ifdef __x86_64__
+xor %bl,%ah
+xor %bl,%r8b
+xor %r9b,%bl
+xor %sil,%cl
+add %eax,(%r8d)
+add %ebx,(%r9)
+add %edx,(%r10d,%r11d)
+add %ecx,(%r12,%r13)
+add %esi,(%r14,%r15,4)
+add %edi,0x1000(%rbx,%r12,8)
+add %r11,0x1000(%ebp,%r9d,8)
+movb $12, %ah
+movb $13, %bpl
+movb $14, %dil
+movb $15, %r12b
+#endif
+
+add %eax, (%ebx)
+add (%ebx), %eax
+
+or %dx, (%ebx)
+or (%ebx), %si
+
+add %cl, (%ebx)
+add (%ebx), %dl
+
+ inc %edx
+ incl 0x10000
+ incb 0x10000
+ dec %dx
+
+ test $1, %al
+ test $1, %cl
+
+ testl $1, 0x1000
+ testb $1, 0x1000
+ testw $1, 0x1000
+ test %eax, %ebx
+ test %eax, 0x1000
+ test 0x1000, %edx
+
+ not %edx
+ notw 0x10000
+ notl 0x10000
+ notb 0x10000
+
+ neg %edx
+ negw 0x10000
+ negl 0x10000
+ negb 0x10000
+
+ imul %ecx
+ mul %edx
+ mulb %cl
+
+ imul %eax, %ecx
+ imul 0x1000, %cx
+ imul $10, %eax, %ecx
+ imul $10, %ax, %cx
+ imul $10, %eax
+ imul $0x1100000, %eax
+ imul $1, %eax
+
+ idivw 0x1000
+ div %ecx
+ div %bl
+ div %ecx, %eax
+
+and $15,%bx
+and $-20,%edx
+
+shl %edx
+shl $10, %edx
+shl %cl, %edx
+
+shld $1, %eax, %edx
+shld %cl, %eax, %edx
+shld %eax, %edx
+
+shrd $1, %eax, %edx
+shrd %cl, %eax, %edx
+shrd %eax, %edx
+
+L4:
+call 0x1000
+call L4
+#ifdef __i386__
+call *%eax
+#else
+call *%rax
+#endif
+call *0x1000
+call func1
+
+.global L5,L6
+
+L5:
+L6:
+
+#ifdef __i386__
+lcall $0x100, $0x1000
+#else
+lcall *0x100
+lcall *(%rax)
+#endif
+
+jmp 0x1000
+jmp *(%edi)
+#ifdef __i386__
+jmp *%eax
+#else
+jmp *%rax
+#endif
+jmp *0x1000
+
+#ifdef __i386__
+ljmp $0x100, $0x1000
+#else
+ljmp *0x100
+ljmp *(%rdi)
+ljmpl *(%esi)
+ljmpw *(%esi)
+#endif
+
+ret
+ret $10
+#ifdef __i386__
+retl
+retl $10
+#else
+retq
+retq $10
+#endif
+
+lret
+
+lret $10
+
+enter $1234, $10
+
+L3:
+ jo 0x1000
+ jnp 0x1001
+ jne 0x1002
+ jg 0x1003
+
+ jo L3
+ jnp L3
+ jne L3
+ jg L3
+
+ loopne L3
+ loopnz L3
+ loope L3
+ loopz L3
+ loop L3
+ jecxz L3
+
+
+ seto %al
+ setc %al
+ setcb %al
+ setnp 0x1000
+ setl 0xaaaa
+ setg %dl
+
+ fadd
+ fadd %st(1), %st
+ fadd %st(0), %st(1)
+ fadd %st(3)
+
+ fmul %st(0),%st(0)
+ fmul %st(0),%st(1)
+
+ faddp %st(5)
+ faddp
+ faddp %st(1), %st
+
+ fadds 0x1000
+ fiadds 0x1002
+ faddl 0x1004
+ fiaddl 0x1006
+
+ fmul
+ fmul %st(1), %st
+ fmul %st(3)
+
+ fmulp %st(5)
+ fmulp
+ fmulp %st(1), %st
+
+ fmuls 0x1000
+ fimuls 0x1002
+ fmull 0x1004
+ fimull 0x1006
+
+ fsub
+ fsub %st(1), %st
+ fsub %st(3)
+
+ fsubp %st(5)
+ fsubp
+ fsubp %st(1), %st
+
+ fsubs 0x1000
+ fisubs 0x1002
+ fsubl 0x1004
+ fisubl 0x1006
+
+ fsubr
+ fsubr %st(1), %st
+ fsubr %st(3)
+
+ fsubrp %st(5)
+ fsubrp
+ fsubrp %st(1), %st
+
+ fsubrs 0x1000
+ fisubrs 0x1002
+ fsubrl 0x1004
+ fisubrl 0x1006
+
+ fdiv
+ fdiv %st(1), %st
+ fdiv %st(3)
+
+ fdivp %st(5)
+ fdivp
+ fdivp %st(1), %st
+
+ fdivs 0x1000
+ fidivs 0x1002
+ fdivl 0x1004
+ fidivl 0x1006
+
+ fcom %st(3)
+
+ fcoms 0x1000
+ ficoms 0x1002
+ fcoml 0x1004
+ ficoml 0x1006
+
+ fcomp %st(5)
+ fcomp
+ fcompp
+
+ fcomps 0x1000
+ ficomps 0x1002
+ fcompl 0x1004
+ ficompl 0x1006
+
+ fld %st(5)
+ fldl 0x1000
+ flds 0x1002
+ fildl 0x1004
+ fst %st(4)
+ fstp %st(6)
+ fstpt 0x1006
+ fbstp 0x1008
+
+ fxch
+ fxch %st(4)
+
+ fucom %st(6)
+ fucomp %st(3)
+ fucompp
+
+ finit
+ fninit
+ fldcw 0x1000
+ fnstcw 0x1002
+ fstcw 0x1002
+ fnstsw 0x1004
+ fnstsw (%eax)
+ fstsw 0x1004
+ fstsw (%eax)
+ fnclex
+ fclex
+ fnstenv 0x1000
+ fstenv 0x1000
+ fldenv 0x1000
+ fnsave 0x1002
+ fsave 0x1000
+ frstor 0x1000
+ ffree %st(7)
+ ffreep %st(6)
+
+ ftst
+ fxam
+ fld1
+ fldl2t
+ fldl2e
+ fldpi
+ fldlg2
+ fldln2
+ fldz
+
+ f2xm1
+ fyl2x
+ fptan
+ fpatan
+ fxtract
+ fprem1
+ fdecstp
+ fincstp
+ fprem
+ fyl2xp1
+ fsqrt
+ fsincos
+ frndint
+ fscale
+ fsin
+ fcos
+ fchs
+ fabs
+ fnop
+ fwait
+
+bswap %edx
+bswapl %ecx
+xadd %ecx, %edx
+xaddb %dl, 0x1000
+xaddw %ax, 0x1000
+xaddl %eax, 0x1000
+cmpxchg %ecx, %edx
+cmpxchgb %dl, 0x1000
+cmpxchgw %ax, 0x1000
+cmpxchgl %eax, 0x1000
+invlpg 0x1000
+cmpxchg8b 0x1002
+#ifdef __x86_64__
+cmpxchg16b (%rax)
+cmpxchg16b (%r10,%r11)
+#endif
+
+fcmovb %st(5), %st
+fcmove %st(5), %st
+fcmovbe %st(5), %st
+fcmovu %st(5), %st
+fcmovnb %st(5), %st
+fcmovne %st(5), %st
+fcmovnbe %st(5), %st
+fcmovnu %st(5), %st
+fcomi %st(5), %st
+fucomi %st(5), %st
+fcomip %st(5), %st
+fucomip %st(5), %st
+
+
+
+ cmovo 0x1000, %eax
+ cmovs 0x1000, %eax
+ cmovns %edx, %edi
+ cmovne %ax, %si
+ cmovbw %ax, %di
+ cmovnbel %edx, %ecx
+#ifdef __x86_64__
+ bswapq %rsi
+ bswapq %r10
+ cmovz %rdi,%rbx
+ cmovpeq %rsi, %rdx
+#endif
+
+int $3
+int $0x10
+
+#ifdef __i386__
+ pusha
+ popa
+#endif
+ clc # another comment
+ cld # a comment with embedded ' tick
+ cli
+ clts
+ cmc
+ lahf
+ sahf
+#ifdef __i386__
+ pushfl
+ popfl
+#else
+ pushfq
+ popfq
+#endif
+ pushf
+ popf
+ stc
+ std
+ sti
+#ifdef __i386__
+ aaa
+ aas
+ daa
+ das
+ aad
+ aam
+ into
+#endif
+ cbw
+ cwd
+ cwde
+ cdq
+ cbtw
+ cwtd
+ cwtl
+ cltd
+ leave
+ int3
+ iret
+ rsm
+ hlt
+ wait
+ nop
+
+ /* XXX: handle prefixes */
+#if 0
+ aword
+ addr16
+#endif
+ lock
+ rep
+ repe
+ repz
+ repne
+ repnz
+ nop
+
+ lock ;negl (%eax)
+ wait ;pushf
+ rep ;stosb
+ repe ;lodsb
+ repz ;cmpsb
+ repne;movsb
+ repnz;outsb
+
+ /* handle one-line prefix + ops */
+ lock negl (%eax)
+ wait pushf
+ rep stosb
+ repe lodsb
+ repz cmpsb
+ repne movsb
+ repnz outsb
+
+ invd
+ wbinvd
+ cpuid
+ wrmsr
+ rdtsc
+ rdmsr
+ rdpmc
+ ud2
+#ifdef __x86_64__
+ syscall
+ sysret
+ sysretq
+ lfence
+ mfence
+ sfence
+ prefetchnta 0x18(%rdx)
+ prefetcht0 (%rcx)
+ prefetcht1 (%rsi)
+ prefetcht2 (%rdi)
+ prefetchw (%rdi)
+ clflush 0x1000(%rax,%rcx)
+ fxsaveq (%rdx)
+ fxsaveq (%r11)
+ fxrstorq (%rcx)
+ fxrstorq (%r10)
+
+#endif
+
+ lar %ax,%dx
+ lar %eax,%dx
+ lar %ax,%edx
+ lar %eax,%edx
+#ifdef __x86_64__
+ lar %ax,%rdx
+ lar %eax,%rdx
+#endif
+ emms
+ movd %edx, %mm3
+ movd 0x1000, %mm2
+ movd %mm4, %ecx
+ movd %mm5, 0x1000
+
+ movq 0x1000, %mm2
+ movq %mm4, 0x1000
+
+ pand 0x1000, %mm3
+ pand %mm4, %mm5
+
+ psllw $1, %mm6
+ psllw 0x1000, %mm7
+ psllw %mm2, %mm7
+
+ xlat
+ cmpsb
+ scmpw
+ insl
+ outsw
+ lodsb
+ slodl
+ movsb
+ movsl
+ smovb
+ scasb
+ sscaw
+ stosw
+ sstol
+
+ bsf 0x1000, %ebx
+ bsr 0x1000, %ebx
+ bt %edx, 0x1000
+ btl $2, 0x1000
+ btc %edx, 0x1000
+ btcl $2, 0x1000
+ btr %edx, 0x1000
+ btrl $2, 0x1000
+ bts %edx, 0x1000
+ btsl $2, 0x1000
+
+
+
+#ifdef __i386__
+ boundl %edx, 0x10000
+ boundw %bx, 0x1000
+
+ arpl %bx, 0x1000
+#endif
+ lar 0x1000, %eax
+ lgdt 0x1000
+ lidt 0x1000
+ lldt 0x1000
+ sgdt 0x1000
+ sidt 0x1000
+ sldt 0x1000
+#ifdef __x86_64__
+ lgdtq 0x1000
+ lidtq 0x1000
+ sgdtq 0x1000
+ sidtq 0x1000
+
+ swapgs
+
+ str %rdx
+ str %r9
+#endif
+
+ lmsw 0x1000
+ lsl 0x1000, %ecx
+ ltr 0x1000
+ ltr %si
+ smsw 0x1000
+ str 0x1000
+ str %ecx
+ str %dx
+
+ verr 0x1000
+ verw 0x1000
+
+#ifdef __i386__
+ push %ds
+ pushw %ds
+ pushl %ds
+ pop %ds
+ popw %ds
+ popl %ds
+#endif
+ fxsave 1(%ebx)
+ fxrstor 1(%ecx)
+#ifdef __i386__
+ pushl $1
+#else
+ pushq $1
+#endif
+ pushw $1
+ push $1
+
+#ifdef __ASSEMBLER__ // should be defined, for S files
+ inc %eax
+#endif
+
+#ifndef _WIN32
+ft1: ft2: ft3: ft4: ft5: ft6: ft7: ft8: ft9:
+ xor %eax, %eax
+ ret
+
+.type ft1,STT_FUNC
+.type ft2,@STT_FUNC
+.type ft3,%STT_FUNC
+.type ft4,"STT_FUNC"
+.type ft5,function
+.type ft6,@function
+.type ft7,%function
+.type ft8,"function"
+#endif
+
+ pause
+.rept 6
+ nop
+.endr
+.fill 4,1,0x90
+
+.section .text.one,"ax"
+nop
+.previous
+.pushsection .text.one,"ax"
+nop
+.pushsection .text.two,"ax"
+nop
+.popsection
+.popsection
+
+1: ud2
+.pushsection __bug_table,"a"
+.align 8
+2: .long 1b - 2b
+ .long 0x600000 - 2b
+ .long 1b + 42
+ .long 43 + 1b
+ .long 2b + 144
+ .long 145 + 2b
+ .word 164, 0
+ .org 2b+32
+#ifdef __x86_64__
+ .quad 1b
+#else
+ .long 1b
+#endif
+.popsection
+3: mov %eax,%ecx
+4:
+.pushsection .text.three, "ax"
+nop
+.skip (-((4b-3b) > 0) * 2) , 0x90
+.popsection
+
+.globl overrideme
+.weak overrideme
+ nop
+.globl notimplemented
+notimplemented:
+ ret
+.set overrideme, notimplemented
+overrideme = notimplemented
+overrideme:
+ ret
+
+ movd %esi, %mm1
+ movd %edi, %xmm2
+ movd (%ebx), %mm3
+ movd (%ebx), %xmm3
+ movd %mm1, %esi
+ movd %xmm2, %edi
+ movd %mm3, (%edx)
+ movd %xmm3, (%edx)
+#ifdef __x86_64__
+ movd %rsi, %mm1
+ movd %rdi, %xmm2
+ movd (%rbx), %mm3
+ movd (%rbx), %xmm3
+ movd %mm1, %r12
+ movd %xmm2, %rdi
+ movd %mm3, (%r8)
+ movd %xmm3, (%r13)
+#endif
+
+ movq (%ebp), %mm1
+ movq %mm2, (%edi)
+ movq (%edi), %xmm3
+ movq %mm4, %mm5
+#ifdef __x86_64__
+ movq %rcx, %mm1
+ movq %rdx, %xmm2
+ movq %r13, %xmm3
+ /* movq mem64->xmm is encoded as f30f7e by GAS, but as
+ 660f6e by tcc (which really is a movd and would need
+ a REX.W prefix to be movq). */
+ movq (%rsi), %xmm3
+ movq %mm1, %rdx
+ movq %xmm3, %rcx
+ movq %xmm4, (%rsi)
+#endif
+
+#define TEST_MMX_SSE(insn) \
+ insn %mm1, %mm2; \
+ insn %xmm2, %xmm3; \
+ insn (%ebx), %xmm3;
+#define TEST_MMX_SSE_I8(insn) \
+ TEST_MMX_SSE(insn) \
+ insn $0x42, %mm4; \
+ insn $0x42, %xmm4;
+
+ TEST_MMX_SSE(packssdw)
+ TEST_MMX_SSE(packsswb)
+ TEST_MMX_SSE(packuswb)
+ TEST_MMX_SSE(paddb)
+ TEST_MMX_SSE(paddw)
+ TEST_MMX_SSE(paddd)
+ TEST_MMX_SSE(paddsb)
+ TEST_MMX_SSE(paddsw)
+ TEST_MMX_SSE(paddusb)
+ TEST_MMX_SSE(paddusw)
+ TEST_MMX_SSE(pand)
+ TEST_MMX_SSE(pandn)
+ TEST_MMX_SSE(pcmpeqb)
+ TEST_MMX_SSE(pcmpeqw)
+ TEST_MMX_SSE(pcmpeqd)
+ TEST_MMX_SSE(pcmpgtb)
+ TEST_MMX_SSE(pcmpgtw)
+ TEST_MMX_SSE(pcmpgtd)
+ TEST_MMX_SSE(pmaddwd)
+ TEST_MMX_SSE(pmulhw)
+ TEST_MMX_SSE(pmullw)
+ TEST_MMX_SSE(por)
+ TEST_MMX_SSE(psllw)
+TEST_MMX_SSE_I8(psllw)
+ TEST_MMX_SSE(pslld)
+TEST_MMX_SSE_I8(pslld)
+ TEST_MMX_SSE(psllq)
+TEST_MMX_SSE_I8(psllq)
+ TEST_MMX_SSE(psraw)
+TEST_MMX_SSE_I8(psraw)
+ TEST_MMX_SSE(psrad)
+TEST_MMX_SSE_I8(psrad)
+ TEST_MMX_SSE(psrlw)
+TEST_MMX_SSE_I8(psrlw)
+ TEST_MMX_SSE(psrld)
+TEST_MMX_SSE_I8(psrld)
+ TEST_MMX_SSE(psrlq)
+TEST_MMX_SSE_I8(psrlq)
+ TEST_MMX_SSE(psubb)
+ TEST_MMX_SSE(psubw)
+ TEST_MMX_SSE(psubd)
+ TEST_MMX_SSE(psubsb)
+ TEST_MMX_SSE(psubsw)
+ TEST_MMX_SSE(psubusb)
+ TEST_MMX_SSE(psubusw)
+ TEST_MMX_SSE(punpckhbw)
+ TEST_MMX_SSE(punpckhwd)
+ TEST_MMX_SSE(punpckhdq)
+ TEST_MMX_SSE(punpcklbw)
+ TEST_MMX_SSE(punpcklwd)
+ TEST_MMX_SSE(punpckldq)
+ TEST_MMX_SSE(pxor)
+
+ cvtpi2ps %mm1, %xmm2
+ cvtpi2ps (%ebx), %xmm2
+ TEST_MMX_SSE(pmaxsw)
+ TEST_MMX_SSE(pmaxub)
+ TEST_MMX_SSE(pminsw)
+ TEST_MMX_SSE(pminub)
diff --git a/tests/boundtest.c b/tests/boundtest.c
new file mode 100644
index 0000000..15bffb4
--- /dev/null
+++ b/tests/boundtest.c
@@ -0,0 +1,285 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define NB_ITS 1000000
+//#define NB_ITS 1
+#define TAB_SIZE 100
+
+int tab[TAB_SIZE];
+int ret_sum;
+char tab3[256];
+
+int test1(void)
+{
+ int i, sum = 0;
+ for(i=0;i<TAB_SIZE;i++) {
+ sum += tab[i];
+ }
+ return sum;
+}
+
+/* error */
+int test2(void)
+{
+ int i, sum = 0;
+ for(i=0;i<TAB_SIZE + 1;i++) {
+ sum += tab[i];
+ }
+ return sum;
+}
+
+/* actually, profiling test */
+int test3(void)
+{
+ int sum;
+ int i, it;
+
+ sum = 0;
+ for(it=0;it<NB_ITS;it++) {
+ for(i=0;i<TAB_SIZE;i++) {
+ sum += tab[i];
+ }
+ }
+ return sum;
+}
+
+/* ok */
+int test4(void)
+{
+ int i, sum = 0;
+ int *tab4;
+
+ fprintf(stderr, "%s start\n", __FUNCTION__);
+
+ tab4 = malloc(20 * sizeof(int));
+ for(i=0;i<20;i++) {
+ sum += tab4[i];
+ }
+ free(tab4);
+
+ fprintf(stderr, "%s end\n", __FUNCTION__);
+ return sum;
+}
+
+/* error */
+int test5(void)
+{
+ int i, sum = 0;
+ int *tab4;
+
+ fprintf(stderr, "%s start\n", __FUNCTION__);
+
+ tab4 = malloc(20 * sizeof(int));
+ for(i=0;i<21;i++) {
+ sum += tab4[i];
+ }
+ free(tab4);
+
+ fprintf(stderr, "%s end\n", __FUNCTION__);
+ return sum;
+}
+
+/* error */
+/* XXX: currently: bug */
+int test6(void)
+{
+ int i, sum = 0;
+ int *tab4;
+
+ tab4 = malloc(20 * sizeof(int));
+ free(tab4);
+ for(i=0;i<21;i++) {
+ sum += tab4[i];
+ }
+
+ return sum;
+}
+
+/* error */
+int test7(void)
+{
+ int i, sum = 0;
+ int *p;
+
+ for(i=0;i<TAB_SIZE + 1;i++) {
+ p = &tab[i];
+ if (i == TAB_SIZE)
+ printf("i=%d %x\n", i, p);
+ sum += *p;
+ }
+ return sum;
+}
+
+/* ok */
+int test8(void)
+{
+ int i, sum = 0;
+ int tab[10];
+
+ for(i=0;i<10;i++) {
+ sum += tab[i];
+ }
+ return sum;
+}
+
+/* error */
+int test9(void)
+{
+ int i, sum = 0;
+ char tab[10];
+
+ for(i=0;i<11;i++) {
+ sum += tab[i];
+ }
+ return sum;
+}
+
+/* ok */
+int test10(void)
+{
+ char tab[10];
+ char tab1[10];
+
+ memset(tab, 0, 10);
+ memcpy(tab, tab1, 10);
+ memmove(tab, tab1, 10);
+ return 0;
+}
+
+/* error */
+int test11(void)
+{
+ char tab[10];
+
+ memset(tab, 0, 11);
+ return 0;
+}
+
+/* error */
+int test12(void)
+{
+ void *ptr;
+ ptr = malloc(10);
+ free(ptr);
+ free(ptr);
+ return 0;
+}
+
+/* error */
+int test13(void)
+{
+ char pad1 = 0;
+ char tab[10];
+ char pad2 = 0;
+ memset(tab, 'a', sizeof(tab));
+ return strlen(tab);
+}
+
+int test14(void)
+{
+ char *p = alloca(TAB_SIZE);
+ memset(p, 'a', TAB_SIZE);
+ p[TAB_SIZE-1] = 0;
+ return strlen(p);
+}
+
+/* error */
+int test15(void)
+{
+ char *p = alloca(TAB_SIZE-1);
+ memset(p, 'a', TAB_SIZE);
+ p[TAB_SIZE-1] = 0;
+ return strlen(p);
+}
+
+/* ok */
+int test16()
+{
+ char *demo = "This is only a test.";
+ char *p;
+
+ fprintf(stderr, "%s start\n", __FUNCTION__);
+
+ p = alloca(16);
+ strcpy(p,"12345678901234");
+ printf("alloca: p is %s\n", p);
+
+ /* Test alloca embedded in a larger expression */
+ printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
+
+ fprintf(stderr, "%s end\n", __FUNCTION__);
+}
+
+/* error */
+int test17()
+{
+ char *demo = "This is only a test.";
+ char *p;
+
+ fprintf(stderr, "%s start\n", __FUNCTION__);
+
+ p = alloca(16);
+ strcpy(p,"12345678901234");
+ printf("alloca: p is %s\n", p);
+
+ /* Test alloca embedded in a larger expression */
+ printf("alloca: %s\n", strcpy(alloca(strlen(demo)),demo) );
+
+ fprintf(stderr, "%s end\n", __FUNCTION__);
+}
+
+int (*table_test[])(void) = {
+ test1,
+ test2,
+ test3,
+ test4,
+ test5,
+ test6,
+ test7,
+ test8,
+ test9,
+ test10,
+ test11,
+ test12,
+ test13,
+ test14,
+ test15,
+ test16,
+ test17,
+};
+
+int main(int argc, char **argv)
+{
+ int index;
+ int (*ftest)(void);
+ int index_max = sizeof(table_test)/sizeof(table_test[0]);
+
+ if (argc < 2) {
+ printf(
+ "test TCC bound checking system\n"
+ "usage: boundtest N\n"
+ " 1 <= N <= %d\n", index_max);
+ exit(1);
+ }
+
+ index = 0;
+ if (argc >= 2)
+ index = atoi(argv[1]) - 1;
+
+ if ((index < 0) || (index >= index_max)) {
+ printf("N is outside of the valid range (%d)\n", index);
+ exit(2);
+ }
+
+ /* well, we also use bounds on this ! */
+ ftest = table_test[index];
+ ftest();
+
+ return 0;
+}
+
+/*
+ * without bound 0.77 s
+ * with bounds 4.73
+ */
diff --git a/tests/gcctestsuite.sh b/tests/gcctestsuite.sh
new file mode 100755
index 0000000..f3cc538
--- /dev/null
+++ b/tests/gcctestsuite.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+TESTSUITE_PATH=$HOME/gcc/gcc-3.2/gcc/testsuite/gcc.c-torture
+TCC="./tcc -B. -I. -DNO_TRAMPOLINES"
+rm -f tcc.sum tcc.log
+nb_failed="0"
+
+for src in $TESTSUITE_PATH/compile/*.c ; do
+ echo $TCC -o /tmp/test.o -c $src
+ $TCC -o /tmp/test.o -c $src >> tcc.log 2>&1
+ if [ "$?" = "0" ] ; then
+ result="PASS"
+ else
+ result="FAIL"
+ nb_failed=$(( $nb_failed + 1 ))
+ fi
+ echo "$result: $src" >> tcc.sum
+done
+
+for src in $TESTSUITE_PATH/execute/*.c ; do
+ echo $TCC $src
+ $TCC $src >> tcc.log 2>&1
+ if [ "$?" = "0" ] ; then
+ result="PASS"
+ else
+ result="FAIL"
+ nb_failed=$(( $nb_failed + 1 ))
+ fi
+ echo "$result: $src" >> tcc.sum
+done
+
+echo "$nb_failed test(s) failed." >> tcc.sum
+echo "$nb_failed test(s) failed."
diff --git a/tests/libtcc_test.c b/tests/libtcc_test.c
new file mode 100644
index 0000000..480d314
--- /dev/null
+++ b/tests/libtcc_test.c
@@ -0,0 +1,96 @@
+/*
+ * Simple Test program for libtcc
+ *
+ * libtcc can be useful to use tcc as a "backend" for a code generator.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libtcc.h"
+
+/* this function is called by the generated code */
+int add(int a, int b)
+{
+ return a + b;
+}
+
+/* this strinc is referenced by the generated code */
+const char hello[] = "Hello World!";
+
+char my_program[] =
+"#include <tcclib.h>\n" /* include the "Simple libc header for TCC" */
+"extern int add(int a, int b);\n"
+"#ifdef _WIN32\n" /* dynamically linked data needs 'dllimport' */
+" __attribute__((dllimport))\n"
+"#endif\n"
+"extern const char hello[];\n"
+"int fib(int n)\n"
+"{\n"
+" if (n <= 2)\n"
+" return 1;\n"
+" else\n"
+" return fib(n-1) + fib(n-2);\n"
+"}\n"
+"\n"
+"int foo(int n)\n"
+"{\n"
+" printf(\"%s\\n\", hello);\n"
+" printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
+" printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
+" return 0;\n"
+"}\n";
+
+int main(int argc, char **argv)
+{
+ TCCState *s;
+ int i;
+ int (*func)(int);
+
+ s = tcc_new();
+ if (!s) {
+ fprintf(stderr, "Could not create tcc state\n");
+ exit(1);
+ }
+
+ /* if tcclib.h and libtcc1.a are not installed, where can we find them */
+ for (i = 1; i < argc; ++i) {
+ char *a = argv[i];
+ if (a[0] == '-') {
+ if (a[1] == 'B')
+ tcc_set_lib_path(s, a+2);
+ else if (a[1] == 'I')
+ tcc_add_include_path(s, a+2);
+ else if (a[1] == 'L')
+ tcc_add_library_path(s, a+2);
+ }
+ }
+
+ /* MUST BE CALLED before any compilation */
+ tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
+
+ if (tcc_compile_string(s, my_program) == -1)
+ return 1;
+
+ /* as a test, we add symbols that the compiled program can use.
+ You may also open a dll with tcc_add_dll() and use symbols from that */
+ tcc_add_symbol(s, "add", add);
+ tcc_add_symbol(s, "hello", hello);
+
+ /* relocate the code */
+ if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)
+ return 1;
+
+ /* get entry symbol */
+ func = tcc_get_symbol(s, "foo");
+ if (!func)
+ return 1;
+
+ /* run the code */
+ func(32);
+
+ /* delete the state */
+ tcc_delete(s);
+
+ return 0;
+}
diff --git a/tests/pp/01.c b/tests/pp/01.c
new file mode 100644
index 0000000..2fc3d79
--- /dev/null
+++ b/tests/pp/01.c
@@ -0,0 +1,6 @@
+#define hash_hash # ## #
+#define mkstr(a) # a
+#define in_between(a) mkstr(a)
+#define join(c, d) in_between(c hash_hash d)
+char p[] = join(x, y);
+// char p[] = "x ## y";
diff --git a/tests/pp/01.expect b/tests/pp/01.expect
new file mode 100644
index 0000000..cf5b153
--- /dev/null
+++ b/tests/pp/01.expect
@@ -0,0 +1 @@
+char p[] = "x ## y";
diff --git a/tests/pp/02.c b/tests/pp/02.c
new file mode 100644
index 0000000..feb1254
--- /dev/null
+++ b/tests/pp/02.c
@@ -0,0 +1,28 @@
+#define x 3
+#define f(a) f(x * (a))
+#undef x
+#define x 2
+#define g f
+#define z z[0]
+#define h g(~
+#define m(a) a(w)
+#define w 0,1
+#define t(a) a
+#define p() int
+#define q(x) x
+#define r(x,y) x ## y
+#define str(x) # x
+f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
+g(x+(3,4)-w) | h 5) & m
+(f)^m(m);
+char c[2][6] = { str(hello), str() };
+/*
+ * f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+ * f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
+ * char c[2][6] = { "hello", "" };
+ */
+#define L21 f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
+#define L22 g(x+(3,4)-w) | h 5) & m\
+(f)^m(m);
+L21
+L22
diff --git a/tests/pp/02.expect b/tests/pp/02.expect
new file mode 100644
index 0000000..8ae2eb9
--- /dev/null
+++ b/tests/pp/02.expect
@@ -0,0 +1,5 @@
+f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
+char c[2][6] = { "hello", "" };
+f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
diff --git a/tests/pp/03.c b/tests/pp/03.c
new file mode 100644
index 0000000..a659245
--- /dev/null
+++ b/tests/pp/03.c
@@ -0,0 +1,15 @@
+#define str(s) # s
+#define xstr(s) str(s)
+#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \
+ x ## s, x ## t)
+#define INCFILE(n) vers ## n
+#define glue(a, b) a ## b
+#define xglue(a, b) glue(a, b)
+#define HIGHLOW "hello"
+#define LOW LOW ", world"
+debug(1, 2);
+fputs(str(strncmp("abc\0d", "abc", '\4') // this goes away
+ == 0) str(: @\n), s);
+\#include xstr(INCFILE(2).h)
+glue(HIGH, LOW);
+xglue(HIGH, LOW)
diff --git a/tests/pp/03.expect b/tests/pp/03.expect
new file mode 100644
index 0000000..44aad0a
--- /dev/null
+++ b/tests/pp/03.expect
@@ -0,0 +1,5 @@
+printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
+fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s);
+\#include "vers2.h"
+"hello";
+"hello" ", world"
diff --git a/tests/pp/04.c b/tests/pp/04.c
new file mode 100644
index 0000000..0068f37
--- /dev/null
+++ b/tests/pp/04.c
@@ -0,0 +1,4 @@
+#define foobar 1
+#define C(x,y) x##y
+#define D(x) (C(x,bar))
+D(foo)
diff --git a/tests/pp/04.expect b/tests/pp/04.expect
new file mode 100644
index 0000000..7c67b01
--- /dev/null
+++ b/tests/pp/04.expect
@@ -0,0 +1 @@
+(1)
diff --git a/tests/pp/05.c b/tests/pp/05.c
new file mode 100644
index 0000000..7274941
--- /dev/null
+++ b/tests/pp/05.c
@@ -0,0 +1,7 @@
+#define t(x,y,z) x ## y ## z
+#define xxx(s) int s[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), \
+ t(10,,), t(,11,), t(,,12), t(,,) };
+
+int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
+ t(10,,), t(,11,), t(,,12), t(,,) };
+xxx(j)
diff --git a/tests/pp/05.expect b/tests/pp/05.expect
new file mode 100644
index 0000000..9f9be37
--- /dev/null
+++ b/tests/pp/05.expect
@@ -0,0 +1,3 @@
+int j[] = { 123, 45, 67, 89,
+ 10, 11, 12, };
+int j[] = { 123, 45, 67, 89, 10, 11, 12, };
diff --git a/tests/pp/06.c b/tests/pp/06.c
new file mode 100644
index 0000000..28cfdde
--- /dev/null
+++ b/tests/pp/06.c
@@ -0,0 +1,5 @@
+#define X(a,b, \
+ c,d) \
+ foo
+
+X(1,2,3,4)
diff --git a/tests/pp/06.expect b/tests/pp/06.expect
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/tests/pp/06.expect
@@ -0,0 +1 @@
+foo
diff --git a/tests/pp/07.c b/tests/pp/07.c
new file mode 100644
index 0000000..b22b22b
--- /dev/null
+++ b/tests/pp/07.c
@@ -0,0 +1,4 @@
+#define a() YES
+#define b() a
+b()
+b()()
diff --git a/tests/pp/07.expect b/tests/pp/07.expect
new file mode 100644
index 0000000..ad0e20a
--- /dev/null
+++ b/tests/pp/07.expect
@@ -0,0 +1,2 @@
+a
+YES
diff --git a/tests/pp/08.c b/tests/pp/08.c
new file mode 100644
index 0000000..93018e1
--- /dev/null
+++ b/tests/pp/08.c
@@ -0,0 +1,4 @@
+// test macro expansion in arguments
+#define s_pos s_s.s_pos
+#define foo(x) (x)
+foo(hej.s_pos)
diff --git a/tests/pp/08.expect b/tests/pp/08.expect
new file mode 100644
index 0000000..2b2e3ee
--- /dev/null
+++ b/tests/pp/08.expect
@@ -0,0 +1 @@
+(hej.s_s.s_pos)
diff --git a/tests/pp/09.c b/tests/pp/09.c
new file mode 100644
index 0000000..315b297
--- /dev/null
+++ b/tests/pp/09.c
@@ -0,0 +1,4 @@
+#define C(a,b,c) a##b##c
+#define N(x,y) C(x,_,y)
+#define A_O aaaaoooo
+N(A,O)
diff --git a/tests/pp/09.expect b/tests/pp/09.expect
new file mode 100644
index 0000000..adce0f9
--- /dev/null
+++ b/tests/pp/09.expect
@@ -0,0 +1 @@
+aaaaoooo
diff --git a/tests/pp/10.c b/tests/pp/10.c
new file mode 100644
index 0000000..f180eff
--- /dev/null
+++ b/tests/pp/10.c
@@ -0,0 +1,10 @@
+#define f(x) x
+#define g(x) f(x) f(x
+#define i(x) g(x)) g(x
+#define h(x) i(x))) i(x
+#define k(x) i(x))) i(x))))
+f(x)
+g(x))
+i(x)))
+h(x))))
+k(x))))
diff --git a/tests/pp/10.expect b/tests/pp/10.expect
new file mode 100644
index 0000000..bd18e18
--- /dev/null
+++ b/tests/pp/10.expect
@@ -0,0 +1,5 @@
+x
+x x
+x x x x
+x x x x x x x x
+x x x x x x x x))))
diff --git a/tests/pp/11.c b/tests/pp/11.c
new file mode 100644
index 0000000..c0edf62
--- /dev/null
+++ b/tests/pp/11.c
@@ -0,0 +1,31 @@
+#define D1(s, ...) s
+#define D2(s, ...) s D1(__VA_ARGS__)
+#define D3(s, ...) s D2(__VA_ARGS__)
+#define D4(s, ...) s D3(__VA_ARGS__)
+
+D1(a)
+D2(a, b)
+D3(a, b, c)
+D4(a, b, c, d)
+
+x D4(a, b, c, d) y
+x D4(a, b, c) y
+x D4(a, b) y
+x D4(a) y
+x D4() y
+
+#define GNU_COMMA(X,Y...) X,## Y
+
+x GNU_COMMA(A,B,C) y
+x GNU_COMMA(A,B) y
+x GNU_COMMA(A) y
+x GNU_COMMA() y
+
+#define __sun_attr___noreturn__ __attribute__((__noreturn__))
+#define ___sun_attr_inner(__a) __sun_attr_##__a
+#define __sun_attr__(__a) ___sun_attr_inner __a
+#define __NORETURN __sun_attr__((__noreturn__))
+__NORETURN
+#define X(...)
+#define Y(...) 1 __VA_ARGS__ 2
+Y(X X() ())
diff --git a/tests/pp/11.expect b/tests/pp/11.expect
new file mode 100644
index 0000000..6b9806c
--- /dev/null
+++ b/tests/pp/11.expect
@@ -0,0 +1,15 @@
+a
+a b
+a b c
+a b c d
+x a b c d y
+x a b c y
+x a b y
+x a y
+x y
+x A,B,C y
+x A,B y
+x A y
+x y
+__attribute__((__noreturn__))
+1 2
diff --git a/tests/pp/12.S b/tests/pp/12.S
new file mode 100644
index 0000000..597ccb4
--- /dev/null
+++ b/tests/pp/12.S
@@ -0,0 +1,8 @@
+#define SRC(y...) \
+ 9999: y; \
+ .section __ex_table, "a"; \
+ .long 9999b, 6001f ; \
+ // .previous
+
+ SRC(1: movw (%esi), %bx)
+6001:
diff --git a/tests/pp/12.expect b/tests/pp/12.expect
new file mode 100644
index 0000000..17a861c
--- /dev/null
+++ b/tests/pp/12.expect
@@ -0,0 +1,2 @@
+ 9999: 1: movw (%esi), %bx; .section __ex_table, "a"; .long 9999b, 6001f ;
+6001:
diff --git a/tests/pp/13.S b/tests/pp/13.S
new file mode 100644
index 0000000..bf0b525
--- /dev/null
+++ b/tests/pp/13.S
@@ -0,0 +1,6 @@
+# `modelist' label. Each video mode record looks like:
+#ifdef AAA
+# modelist' label. Each video mode record looks like:
+#endif
+.text
+endtext:
diff --git a/tests/pp/13.expect b/tests/pp/13.expect
new file mode 100644
index 0000000..c7a3230
--- /dev/null
+++ b/tests/pp/13.expect
@@ -0,0 +1,2 @@
+.text
+endtext:
diff --git a/tests/pp/14.c b/tests/pp/14.c
new file mode 100644
index 0000000..e15468c
--- /dev/null
+++ b/tests/pp/14.c
@@ -0,0 +1,13 @@
+#define W Z
+#define Z(X) W(X,2)
+#define Y(X) Z(X)
+#define X Y
+return X(X(1));
+
+#define P Q
+#define Q(n) P(n,2)
+return P(1);
+
+#define A (B * B)
+#define B (A + A)
+return A + B;
diff --git a/tests/pp/14.expect b/tests/pp/14.expect
new file mode 100644
index 0000000..3786044
--- /dev/null
+++ b/tests/pp/14.expect
@@ -0,0 +1,3 @@
+return Z(Z(1,2),2);
+return Q(1,2);
+return ((A + A) * (A + A)) + ((B * B) + (B * B));
diff --git a/tests/pp/15.c b/tests/pp/15.c
new file mode 100644
index 0000000..cf13f9a
--- /dev/null
+++ b/tests/pp/15.c
@@ -0,0 +1,18 @@
+// insert a space between two tokens if otherwise they
+// would form a single token when read back
+
+#define n(x) x
+
+return (n(long)n(double))d;
+return n(A)n(++)n(+)n(B);
+return n(A)n(+)n(++)n(B);
+return n(A)n(++)n(+)n(+)n(B);
+
+// not a hex float
+return n(0x1E)n(-1);
+
+// unlike gcc but correct
+// XXX: return n(x)+n(x)-n(1)+n(1)-2;
+
+// unlike gcc, but cannot appear in valid C
+// XXX: return n(x)n(x)n(1)n(2)n(x);
diff --git a/tests/pp/15.expect b/tests/pp/15.expect
new file mode 100644
index 0000000..b4f885e
--- /dev/null
+++ b/tests/pp/15.expect
@@ -0,0 +1,5 @@
+return (long double)d;
+return A+++B;
+return A+ ++B;
+return A+++ +B;
+return 0x1E -1;
diff --git a/tests/pp/16.c b/tests/pp/16.c
new file mode 100644
index 0000000..8b5b642
--- /dev/null
+++ b/tests/pp/16.c
@@ -0,0 +1,3 @@
+/* The following should warn */
+#define A ...
+#define A <<=
diff --git a/tests/pp/16.expect b/tests/pp/16.expect
new file mode 100644
index 0000000..695d6d4
--- /dev/null
+++ b/tests/pp/16.expect
@@ -0,0 +1,2 @@
+
+16.c:3: warning: A redefined
diff --git a/tests/pp/17.c b/tests/pp/17.c
new file mode 100644
index 0000000..f12196f
--- /dev/null
+++ b/tests/pp/17.c
@@ -0,0 +1,14 @@
+#define STR1(u) # u
+#define pass(a) a
+#define __ASM_REG(reg) STR1(one##reg)
+#define _ASM_DX __ASM_REG(tok)
+X162 pass(__ASM_REG(tok))
+X161 pass(_ASM_DX)
+X163 pass(STR1(one##tok))
+
+X170 pass(x ## y)
+X171 pass(x pass(##) y)
+
+#define Y(x) Z(x)
+#define X Y
+X180 return X(X(1));
diff --git a/tests/pp/17.expect b/tests/pp/17.expect
new file mode 100644
index 0000000..e95aafe
--- /dev/null
+++ b/tests/pp/17.expect
@@ -0,0 +1,6 @@
+X162 "onetok"
+X161 "onetok"
+X163 "one##tok"
+X170 x ## y
+X171 x ## y
+X180 return Z(Z(1));
diff --git a/tests/pp/18.c b/tests/pp/18.c
new file mode 100644
index 0000000..0961426
--- /dev/null
+++ b/tests/pp/18.c
@@ -0,0 +1,15 @@
+#define M_RETI_ARG27(x,y,z,aa, ...) aa
+#define M_RET_ARG27(...) M_RETI_ARG27(__VA_ARGS__)
+#define M_COMMA_P(...) M_RET_ARG27(__VA_ARGS__, 1, 1, 0, useless)
+#define M_EMPTYI_DETECT(...) 0, 1,
+#define M_EMPTYI_P_C1(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ () )
+#define EX
+#define empty(x)
+#define fnlike(x) yeah x
+/* If the following macro is called with empty arg (X183), the use
+ of 'x' between fnlike and '(' doesn't hinder the recognition of this
+ being a further fnlike macro invocation. */
+#define usefnlike(x) fnlike x (x)
+X181 M_EMPTYI_P_C1()
+X182 M_EMPTYI_P_C1(x)
+X183 usefnlike()
diff --git a/tests/pp/18.expect b/tests/pp/18.expect
new file mode 100644
index 0000000..447a9b2
--- /dev/null
+++ b/tests/pp/18.expect
@@ -0,0 +1,3 @@
+X181 1
+X182 0
+X183 yeah
diff --git a/tests/pp/19.c b/tests/pp/19.c
new file mode 100644
index 0000000..aa91abe
--- /dev/null
+++ b/tests/pp/19.c
@@ -0,0 +1,101 @@
+#define M_C2I(a, ...) a ## __VA_ARGS__
+#define M_C(a, ...) M_C2I(a, __VA_ARGS__)
+#define M_C3I(a, b, ...) a ## b ## __VA_ARGS__
+#define M_C3(a, b, ...) M_C3I(a ,b, __VA_ARGS__)
+
+#define M_RETI_ARG2(a, b, ...) b
+#define M_RET_ARG2(...) M_RETI_ARG2(__VA_ARGS__)
+#define M_RETI_ARG27(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa, ...) aa
+#define M_RET_ARG27(...) M_RETI_ARG27(__VA_ARGS__)
+
+#define M_TOBOOLI_0 1, 0,
+#define M_BOOL(x) M_RET_ARG2(M_C(M_TOBOOLI_, x), 1, useless)
+
+#define M_IFI_0(true_macro, ...) __VA_ARGS__
+#define M_IFI_1(true_macro, ...) true_macro
+#define M_IF(c) M_C(M_IFI_, M_BOOL(c))
+
+#define M_FLAT(...) __VA_ARGS__
+#define M_INVI_0 1
+#define M_INVI_1 0
+#define M_INV(x) M_C(M_INVI_, x)
+
+#define M_ANDI_00 0
+#define M_ANDI_01 0
+#define M_ANDI_10 0
+#define M_ANDI_11 1
+#define M_AND(x,y) M_C3(M_ANDI_, x, y)
+
+#define M_ORI_00 0
+#define M_ORI_01 1
+#define M_ORI_10 1
+#define M_ORI_11 1
+#define M_OR(x,y) M_C3(M_ORI_, x, y)
+
+#define M_COMMA_P(...) M_RET_ARG27(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, useless)
+
+#define M_EMPTYI_DETECT(...) 0, 1,
+#define M_EMPTYI_P_C1(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ ())
+#define M_EMPTYI_P_C2(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__)
+#define M_EMPTYI_P_C3(...) M_COMMA_P(__VA_ARGS__ () )
+#define M_EMPTY_P(...) M_AND(M_EMPTYI_P_C1(__VA_ARGS__), M_INV(M_OR(M_OR(M_EMPTYI_P_C2(__VA_ARGS__), M_COMMA_P(__VA_ARGS__)),M_EMPTYI_P_C3(__VA_ARGS__))))
+#define M_APPLY_FUNC2B(func, arg1, arg2) \
+ M_IF(M_EMPTY_P(arg2))(,func(arg1, arg2))
+#define M_MAP2B_0(func, data, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,...) \
+ M_APPLY_FUNC2B(func, data, a) M_APPLY_FUNC2B(func, data, b) M_APPLY_FUNC2B(func, data, c) \
+ M_APPLY_FUNC2B(func, data, d) M_APPLY_FUNC2B(func, data, e) M_APPLY_FUNC2B(func, data, f) \
+ M_APPLY_FUNC2B(func, data, g) M_APPLY_FUNC2B(func, data, h) M_APPLY_FUNC2B(func, data, i) \
+ M_APPLY_FUNC2B(func, data, j) M_APPLY_FUNC2B(func, data, k) M_APPLY_FUNC2B(func, data, l) \
+ M_APPLY_FUNC2B(func, data, m) M_APPLY_FUNC2B(func, data, n) M_APPLY_FUNC2B(func, data, o) \
+ M_APPLY_FUNC2B(func, data, p) M_APPLY_FUNC2B(func, data, q) M_APPLY_FUNC2B(func, data, r) \
+ M_APPLY_FUNC2B(func, data, s) M_APPLY_FUNC2B(func, data, t) M_APPLY_FUNC2B(func, data, u) \
+ M_APPLY_FUNC2B(func, data, v) M_APPLY_FUNC2B(func, data, w) M_APPLY_FUNC2B(func, data, x) \
+ M_APPLY_FUNC2B(func, data, y) M_APPLY_FUNC2B(func, data, z)
+#define M_MAP2B(f, ...) M_MAP2B_0(f, __VA_ARGS__, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , )
+#define M_INIT_INIT(a) ,a,
+
+#define M_GET_METHOD(method, method_default, ...) \
+ M_RET_ARG2 (M_MAP2B(M_C, M_C3(M_, method, _), __VA_ARGS__), method_default,)
+
+#define M_TEST_METHOD_P(method, oplist) \
+ M_BOOL(M_GET_METHOD (method, 0, M_FLAT oplist))
+
+#define TRUE 1
+#define TEST1(n) \
+ M_IF(n)(ok,nok)
+#define TEST2(op) \
+ M_TEST_METHOD_P(INIT, op)
+#define TEST3(op) \
+ M_IF(M_TEST_METHOD_P(INIT, op))(ok, nok)
+#define TEST4(op) \
+ TEST1(TEST2(op))
+#define KO(a) ((void)1)
+
+/* This checks that the various expansions that ultimately lead to
+ something like 'KO(arg,arg)', where 'KO' comes from a macro
+ expansion reducing from a large macro chain do not are regarded
+ as funclike macro invocation of KO. E.g. X93 and X94 expand to 'KO',
+ but X95 must not consume the (a,b) arguments outside the M_IF()
+ invocation to reduce the 'KO' macro to an invocation. Instead
+ X95 should reduce via M_IF(KO)(a,b) to 'a'.
+
+ The other lines here are variations on this scheme, with X1 to
+ X6 coming from the bug report at
+ http://lists.nongnu.org/archive/html/tinycc-devel/2017-07/msg00017.html */
+X92 M_IF(KO)
+X93 M_GET_METHOD(INIT, 0, INIT(KO))
+X94 M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO)))
+X95 M_IF(M_GET_METHOD(INIT, 0, INIT(KO)))(a,b)
+X96 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))))
+X97 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))))(ok,nok)
+X98 (M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok)
+X99 M_IF(M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok)
+// test begins
+X1 TEST1(TRUE) // ==> expect ok, get ok
+// First test with a token which is not a macro
+X2 TEST2((INIT(ok))) // ==> expect 1, get 1
+X3 TEST3((INIT(ok))) // ==> expect ok, get ok
+// Then test with a token which is a macro, but should not be expanded.
+X4 TEST2((INIT(KO))) // ==> expect 1, get 1
+X5 TEST4(INIT(KO))
+X6 TEST3((INIT(KO))) // ==> expect ok, get "error: macro 'KO' used with too many args"
diff --git a/tests/pp/19.expect b/tests/pp/19.expect
new file mode 100644
index 0000000..08c0858
--- /dev/null
+++ b/tests/pp/19.expect
@@ -0,0 +1,14 @@
+X92 M_IFI_1
+X93 KO
+X94 KO
+X95 a
+X96 M_IFI_1
+X97 ok
+X98 (1)(ok, nok)
+X99 ok
+X1 ok
+X2 1
+X3 ok
+X4 1
+X5 nok
+X6 ok
diff --git a/tests/pp/20.c b/tests/pp/20.c
new file mode 100644
index 0000000..7944d62
--- /dev/null
+++ b/tests/pp/20.c
@@ -0,0 +1,13 @@
+/* Various things I encountered while hacking the pre processor */
+#define wrap(x) x
+#define pr_warning(fmt, ...) printk(KERN_WARNING fmt, ##__VA_ARGS__)
+#define pr_warn(x,y) pr_warning(x,y)
+#define net_ratelimited_function(function, ...) function(__VA_ARGS__)
+X1 net_ratelimited_function(pr_warn, "pipapo", bla);
+X2 net_ratelimited_function(wrap(pr_warn), "bla", foo);
+#define two m n
+#define chain4(a,b,c,d) a ## b ## c ## d
+X2 chain4(two,o,p,q)
+X3 chain4(o,two,p,q)
+X4 chain4(o,p,two,q)
+X5 chain4(o,p,q,two)
diff --git a/tests/pp/20.expect b/tests/pp/20.expect
new file mode 100644
index 0000000..d19405d
--- /dev/null
+++ b/tests/pp/20.expect
@@ -0,0 +1,6 @@
+X1 printk(KERN_WARNING "pipapo",bla);
+X2 printk(KERN_WARNING "bla",foo);
+X2 twoopq
+X3 otwopq
+X4 optwoq
+X5 opqtwo
diff --git a/tests/pp/21.c b/tests/pp/21.c
new file mode 100644
index 0000000..1316226
--- /dev/null
+++ b/tests/pp/21.c
@@ -0,0 +1,36 @@
+/* accept 'defined' as result of substitution */
+
+----- 1 ------
+#define AAA 2
+#define BBB
+#define CCC (defined ( AAA ) && AAA > 1 && !defined BBB)
+#if !CCC
+OK
+#else
+NOT OK
+#endif
+
+----- 2 ------
+#undef BBB
+#if CCC
+OK
+#else
+NOT OK
+#endif
+
+----- 3 ------
+#define DEFINED defined
+#define DDD (DEFINED ( AAA ) && AAA > 1 && !DEFINED BBB)
+#if (DDD)
+OK
+#else
+NOT OK
+#endif
+
+----- 4 ------
+#undef AAA
+#if !(DDD)
+OK
+#else
+NOT OK
+#endif
diff --git a/tests/pp/21.expect b/tests/pp/21.expect
new file mode 100644
index 0000000..5a1376b
--- /dev/null
+++ b/tests/pp/21.expect
@@ -0,0 +1,8 @@
+----- 1 ------
+OK
+----- 2 ------
+OK
+----- 3 ------
+OK
+----- 4 ------
+OK
diff --git a/tests/pp/Makefile b/tests/pp/Makefile
new file mode 100644
index 0000000..687aa52
--- /dev/null
+++ b/tests/pp/Makefile
@@ -0,0 +1,49 @@
+#
+# credits: 01..13.c from the pcc cpp-tests suite
+#
+
+TOP = ../..
+include $(TOP)/Makefile
+SRC = $(TOPSRC)/tests/pp
+VPATH = $(SRC)
+
+files = $(patsubst %.$1,%.test,$(notdir $(wildcard $(SRC)/*.$1)))
+TESTS = $(call files,c) $(call files,S)
+
+all test : $(sort $(TESTS))
+
+DIFF_OPTS = -Nu -b -B
+
+# Filter source directory in warnings/errors (out-of-tree builds)
+FILTER = 2>&1 | sed 's,$(SRC)/,,g'
+
+%.test: %.c %.expect
+ @echo PPTest $* ...
+ -@$(TCC) -E -P $< $(FILTER) >$*.output 2>&1 ; \
+ diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \
+ && rm -f $*.output
+
+%.test: %.S %.expect
+ @echo PPTest $* ...
+ -@$(TCC) -E -P $< $(FILTER) >$*.output 2>&1 ; \
+ diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \
+ && rm -f $*.output
+
+# automatically generate .expect files with gcc:
+%.expect: # %.c
+ gcc -E -P $*.[cS] >$*.expect 2>&1
+
+# tell make not to delete
+.PRECIOUS: %.expect
+
+clean:
+ rm -f *.output
+
+02.test : DIFF_OPTS += -w
+# 15.test : DIFF_OPTS += -I"^XXX:"
+
+# diff options:
+# -b ighore space changes
+# -w ighore all whitespace
+# -B ignore blank lines
+# -I <RE> ignore lines matching RE
diff --git a/tests/pp/pp-counter.c b/tests/pp/pp-counter.c
new file mode 100644
index 0000000..3978e1a
--- /dev/null
+++ b/tests/pp/pp-counter.c
@@ -0,0 +1,27 @@
+X1 __COUNTER__
+X2 __COUNTER__
+#if __COUNTER__
+X3 __COUNTER__
+#endif
+#define pass(x) x
+#define a x __COUNTER__ y
+#define a2 pass(__COUNTER__)
+#define f(c) c __COUNTER__
+#define apply(d) d d __COUNTER__ x2 f(d) y2 __COUNTER__
+#define _paste(a,b) a ## b
+#define paste(a,b) _paste(a,b)
+#define _paste3(a,b,c) a ## b ## c
+#define doublepaste(a,b) _paste3(a,b,b)
+#define str(x) #x
+X4 a
+X5 f(a)
+X6 f(b)
+X7 f(__COUNTER__)
+X8 apply(a)
+X9 apply(f(a))
+X10 apply(__COUNTER__)
+X11 apply(a2)
+X12 str(__COUNTER__)
+X13 paste(x,__COUNTER__)
+X14 _paste(x,__COUNTER__)
+X15 doublepaste(x,__COUNTER__)
diff --git a/tests/pp/pp-counter.expect b/tests/pp/pp-counter.expect
new file mode 100644
index 0000000..02fc535
--- /dev/null
+++ b/tests/pp/pp-counter.expect
@@ -0,0 +1,15 @@
+X1 0
+X2 1
+X3 3
+X4 x 4 y
+X5 x 5 y 6
+X6 b 7
+X7 8 9
+X8 x 10 y x 10 y 11 x2 x 10 y 12 y2 13
+X9 x 14 y 15 x 14 y 15 16 x2 x 14 y 15 17 y2 18
+X10 19 19 20 x2 19 21 y2 22
+X11 23 23 24 x2 23 25 y2 26
+X12 "__COUNTER__"
+X13 x27
+X14 x__COUNTER__
+X15 x2828
diff --git a/tests/tcctest.c b/tests/tcctest.c
new file mode 100644
index 0000000..57670be
--- /dev/null
+++ b/tests/tcctest.c
@@ -0,0 +1,3871 @@
+/*
+ * TCC auto test program
+ */
+#include "config.h"
+
+#if GCC_MAJOR >= 3
+
+/* Unfortunately, gcc version < 3 does not handle that! */
+#define ALL_ISOC99
+
+/* only gcc 3 handles _Bool correctly */
+#define BOOL_ISOC99
+
+/* gcc 2.95.3 does not handle correctly CR in strings or after strays */
+#define CORRECT_CR_HANDLING
+
+#endif
+
+#if defined(_WIN32)
+#define LONG_LONG_FORMAT "%lld"
+#define ULONG_LONG_FORMAT "%llu"
+#else
+#define LONG_LONG_FORMAT "%Ld"
+#define ULONG_LONG_FORMAT "%Lu"
+#endif
+
+// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
+#if defined(_WIN32) && defined(__GNUC__)
+#define LONG_DOUBLE double
+#define LONG_DOUBLE_LITERAL(x) x
+#else
+#define LONG_DOUBLE long double
+#define LONG_DOUBLE_LITERAL(x) x ## L
+#endif
+
+/* deprecated and no longer supported in gcc 3.3 */
+//#define ACCEPT_CR_IN_STRINGS
+
+/* __VA_ARGS__ and __func__ support */
+#define C99_MACROS
+
+/* test various include syntaxes */
+
+#define TCCLIB_INC <tcclib.h>
+#define TCCLIB_INC1 <tcclib
+#define TCCLIB_INC2 h>
+#define TCCLIB_INC3 "tcclib.h"
+
+#include TCCLIB_INC
+
+#include TCCLIB_INC1.TCCLIB_INC2
+
+#include TCCLIB_INC1.h>
+
+#include TCCLIB_INC3
+
+#include <tcclib.h>
+
+#include "tcclib.h"
+
+#include "tcctest.h"
+
+/* Test two more ways to include a file named like a pp-number */
+#define INC(name) <tests/name.h>
+#define funnyname 42test.h
+#define incdir tests/
+#define incname < incdir funnyname >
+#define __stringify(x) #x
+#define stringify(x) __stringify(x)
+#include INC(42test)
+#include incname
+#include stringify(funnyname)
+
+void intdiv_test();
+void string_test();
+void expr_test();
+void macro_test();
+void recursive_macro_test();
+void scope_test();
+void forward_test();
+void funcptr_test();
+void loop_test();
+void switch_test();
+void goto_test();
+void enum_test();
+void typedef_test();
+void struct_test();
+void array_test();
+void expr_ptr_test();
+void bool_test();
+void optimize_out();
+void expr2_test();
+void constant_expr_test();
+void expr_cmp_test();
+void char_short_test();
+void init_test(void);
+void compound_literal_test(void);
+int kr_test();
+void struct_assign_test(void);
+void cast_test(void);
+void bitfield_test(void);
+void c99_bool_test(void);
+void float_test(void);
+void longlong_test(void);
+void manyarg_test(void);
+void stdarg_test(void);
+void whitespace_test(void);
+void relocation_test(void);
+void old_style_function(void);
+void alloca_test(void);
+void c99_vla_test(int size1, int size2);
+void sizeof_test(void);
+void typeof_test(void);
+void local_label_test(void);
+void statement_expr_test(void);
+void asm_test(void);
+void builtin_test(void);
+void weak_test(void);
+void global_data_test(void);
+void cmp_comparison_test(void);
+void math_cmp_test(void);
+void callsave_test(void);
+void builtin_frame_address_test(void);
+void attrib_test(void);
+
+int fib(int n);
+void num(int n);
+void forward_ref(void);
+int isid(int c);
+
+/* Line joining happens before tokenization, so the following
+ must be parsed as ellipsis. */
+void funny_line_continuation (int, ..\
+. );
+
+char via_volatile (char);
+
+#define A 2
+#define N 1234 + A
+#define pf printf
+#define M1(a, b) (a) + (b)
+
+#define str\
+(s) # s
+#define glue(a, b) a ## b
+#define xglue(a, b) glue(a, b)
+#define HIGHLOW "hello"
+#define LOW LOW ", world"
+
+static int onetwothree = 123;
+#define onetwothree4 onetwothree
+#define onetwothree xglue(onetwothree,4)
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+#ifdef C99_MACROS
+#define dprintf(level,...) printf(__VA_ARGS__)
+#endif
+
+/* gcc vararg macros */
+#define dprintf1(level, fmt, args...) printf(fmt, ## args)
+
+#define MACRO_NOARGS()
+
+#define AAA 3
+#undef AAA
+#define AAA 4
+
+#if 1
+#define B3 1
+#elif 1
+#define B3 2
+#elif 0
+#define B3 3
+#else
+#define B3 4
+#endif
+
+#ifdef __TINYC__
+/* We try to handle this syntax. Make at least sure it doesn't segfault. */
+char invalid_function_def()[] {}
+#endif
+
+#define __INT64_C(c) c ## LL
+#define INT64_MIN (-__INT64_C(9223372036854775807)-1)
+
+int qq(int x)
+{
+ return x + 40;
+}
+#define qq(x) x
+
+#define spin_lock(lock) do { } while (0)
+#define wq_spin_lock spin_lock
+#define TEST2() wq_spin_lock(a)
+
+#define UINT_MAX ((unsigned) -1)
+
+void intdiv_test(void)
+{
+ printf("18/21=%u\n", 18/21);
+ printf("18%%21=%u\n", 18%21);
+ printf("41/21=%u\n", 41/21);
+ printf("41%%21=%u\n", 41%21);
+ printf("42/21=%u\n", 42/21);
+ printf("42%%21=%u\n", 42%21);
+ printf("43/21=%u\n", 43/21);
+ printf("43%%21=%u\n", 43%21);
+ printf("126/21=%u\n", 126/21);
+ printf("126%%21=%u\n", 126%21);
+ printf("131/21=%u\n", 131/21);
+ printf("131%%21=%u\n", 131%21);
+ printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2);
+ printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2);
+
+ printf("18/-21=%u\n", 18/-21);
+ printf("18%%-21=%u\n", 18%-21);
+ printf("41/-21=%u\n", 41/-21);
+ printf("41%%-21=%u\n", 41%-21);
+ printf("42/-21=%u\n", 42/-21);
+ printf("42%%-21=%u\n", 42%-21);
+ printf("43/-21=%u\n", 43/-21);
+ printf("43%%-21=%u\n", 43%-21);
+ printf("126/-21=%u\n", 126/-21);
+ printf("126%%-21=%u\n", 126%-21);
+ printf("131/-21=%u\n", 131/-21);
+ printf("131%%-21=%u\n", 131%-21);
+ printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2);
+ printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2);
+
+ printf("-18/21=%u\n", -18/21);
+ printf("-18%%21=%u\n", -18%21);
+ printf("-41/21=%u\n", -41/21);
+ printf("-41%%21=%u\n", -41%21);
+ printf("-42/21=%u\n", -42/21);
+ printf("-42%%21=%u\n", -42%21);
+ printf("-43/21=%u\n", -43/21);
+ printf("-43%%21=%u\n", -43%21);
+ printf("-126/21=%u\n", -126/21);
+ printf("-126%%21=%u\n", -126%21);
+ printf("-131/21=%u\n", -131/21);
+ printf("-131%%21=%u\n", -131%21);
+ printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2);
+ printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2);
+
+ printf("-18/-21=%u\n", -18/-21);
+ printf("-18%%-21=%u\n", -18%-21);
+ printf("-41/-21=%u\n", -41/-21);
+ printf("-41%%-21=%u\n", -41%-21);
+ printf("-42/-21=%u\n", -42/-21);
+ printf("-42%%-21=%u\n", -42%-21);
+ printf("-43/-21=%u\n", -43/-21);
+ printf("-43%%-21=%u\n", -43%-21);
+ printf("-126/-21=%u\n", -126/-21);
+ printf("-126%%-21=%u\n", -126%-21);
+ printf("-131/-21=%u\n", -131/-21);
+ printf("-131%%-21=%u\n", -131%-21);
+ printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2);
+ printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2);
+}
+
+void macro_test(void)
+{
+ printf("macro:\n");
+ pf("N=%d\n", N);
+ printf("aaa=%d\n", AAA);
+
+ printf("min=%d\n", min(1, min(2, -1)));
+
+ printf("s1=%s\n", glue(HIGH, LOW));
+ printf("s2=%s\n", xglue(HIGH, LOW));
+ printf("s3=%s\n", str("c"));
+ printf("s4=%s\n", str(a1));
+ printf("B3=%d\n", B3);
+
+ printf("onetwothree=%d\n", onetwothree);
+
+#ifdef A
+ printf("A defined\n");
+#endif
+#ifdef B
+ printf("B defined\n");
+#endif
+#ifdef A
+ printf("A defined\n");
+#else
+ printf("A not defined\n");
+#endif
+#ifdef B
+ printf("B defined\n");
+#else
+ printf("B not defined\n");
+#endif
+
+#ifdef A
+ printf("A defined\n");
+#ifdef B
+ printf("B1 defined\n");
+#else
+ printf("B1 not defined\n");
+#endif
+#else
+ printf("A not defined\n");
+#ifdef B
+ printf("B2 defined\n");
+#else
+ printf("B2 not defined\n");
+#endif
+#endif
+
+#if 1+1
+ printf("test true1\n");
+#endif
+#if 0
+ printf("test true2\n");
+#endif
+#if 1-1
+ printf("test true3\n");
+#endif
+#if defined(A)
+ printf("test trueA\n");
+#endif
+#if defined(B)
+ printf("test trueB\n");
+#endif
+
+#if 0
+ printf("test 0\n");
+#elif 0
+ printf("test 1\n");
+#elif 2
+ printf("test 2\n");
+#else
+ printf("test 3\n");
+#endif
+
+ MACRO_NOARGS();
+
+#ifdef __LINE__
+ printf("__LINE__ defined\n");
+#endif
+
+ printf("__LINE__=%d __FILE__=%s\n",
+ __LINE__, __FILE__);
+#if 0
+#line 200
+ printf("__LINE__=%d __FILE__=%s\n",
+ __LINE__, __FILE__);
+#line 203 "test"
+ printf("__LINE__=%d __FILE__=%s\n",
+ __LINE__, __FILE__);
+#line 227 "tcctest.c"
+#endif
+
+ /* not strictly preprocessor, but we test it there */
+#ifdef C99_MACROS
+ printf("__func__ = %s\n", __func__);
+ dprintf(1, "vaarg=%d\n", 1);
+#endif
+ dprintf1(1, "vaarg1\n");
+ dprintf1(1, "vaarg1=%d\n", 2);
+ dprintf1(1, "vaarg1=%d %d\n", 1, 2);
+
+ /* gcc extension */
+ printf("func='%s'\n", __FUNCTION__);
+
+ /* complicated macros in glibc */
+ printf("INT64_MIN=" LONG_LONG_FORMAT "\n", INT64_MIN);
+ {
+ int a;
+ a = 1;
+ glue(a+, +);
+ printf("a=%d\n", a);
+ glue(a <, <= 2);
+ printf("a=%d\n", a);
+ }
+
+ /* macro function with argument outside the macro string */
+#define MF_s MF_hello
+#define MF_hello(msg) printf("%s\n",msg)
+
+#define MF_t printf("tralala\n"); MF_hello
+
+ MF_s("hi");
+ MF_t("hi");
+
+ /* test macro substitution inside args (should not eat stream) */
+ printf("qq=%d\n", qq(qq)(2));
+
+ /* test zero argument case. NOTE: gcc 2.95.x does not accept a
+ null argument without a space. gcc 3.2 fixes that. */
+
+#define qq1(x) 1
+ printf("qq1=%d\n", qq1( ));
+
+ /* comment with stray handling *\
+/
+ /* this is a valid *\/ comment */
+ /* this is a valid comment *\*/
+ // this is a valid\
+comment
+
+ /* test function macro substitution when the function name is
+ substituted */
+ TEST2();
+
+ /* And again when the name and parentheses are separated by a
+ comment. */
+ TEST2 /* the comment */ ();
+
+ printf("%s\n", get_basefile_from_header());
+ printf("%s\n", __BASE_FILE__);
+ printf("%s\n", get_file_from_header());
+ printf("%s\n", __FILE__);
+
+ /* Check that funnily named include was in fact included */
+ have_included_42test_h = 1;
+ have_included_42test_h_second = 1;
+ have_included_42test_h_third = 1;
+}
+
+
+static void print_num(char *fn, int line, int num) {
+ printf("fn %s, line %d, num %d\n", fn, line, num);
+}
+
+void recursive_macro_test(void)
+{
+
+#define ELF32_ST_TYPE(val) ((val) & 0xf)
+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
+#define STB_WEAK 2 /* Weak symbol */
+#define ELFW(type) ELF##32##_##type
+ printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123)));
+
+#define WRAP(x) x
+
+#define print_num(x) print_num(__FILE__,__LINE__,x)
+ print_num(123);
+ WRAP(print_num(123));
+ WRAP(WRAP(print_num(123)));
+
+static struct recursive_macro { int rm_field; } G;
+#define rm_field (G.rm_field)
+ printf("rm_field = %d\n", rm_field);
+ printf("rm_field = %d\n", WRAP(rm_field));
+ WRAP((printf("rm_field = %d %d\n", rm_field, WRAP(rm_field))));
+}
+
+int op(a,b)
+{
+ return a / b;
+}
+
+int ret(a)
+{
+ if (a == 2)
+ return 1;
+ if (a == 3)
+ return 2;
+ return 0;
+}
+
+void ps(const char *s)
+{
+ int c;
+ while (1) {
+ c = *s;
+ if (c == 0)
+ break;
+ printf("%c", c);
+ s++;
+ }
+}
+
+const char foo1_string[] = "\
+bar\n\
+test\14\
+1";
+
+void string_test()
+{
+ unsigned int b;
+ printf("string:\n");
+ printf("\141\1423\143\n");/* dezdez test */
+ printf("\x41\x42\x43\x3a\n");
+ printf("c=%c\n", 'r');
+ printf("wc=%C 0x%lx %C\n", L'a', L'\x1234', L'c');
+ printf("foo1_string='%s'\n", foo1_string);
+#if 0
+ printf("wstring=%S\n", L"abc");
+ printf("wstring=%S\n", L"abc" L"def" "ghi");
+ printf("'\\377'=%d '\\xff'=%d\n", '\377', '\xff');
+ printf("L'\\377'=%d L'\\xff'=%d\n", L'\377', L'\xff');
+#endif
+ ps("test\n");
+ b = 32;
+ while ((b = b + 1) < 96) {
+ printf("%c", b);
+ }
+ printf("\n");
+ printf("fib=%d\n", fib(33));
+ b = 262144;
+ while (b != 0x80000000) {
+ num(b);
+ b = b * 2;
+ }
+}
+
+void loop_test()
+{
+ int i;
+ i = 0;
+ while (i < 10)
+ printf("%d", i++);
+ printf("\n");
+ for(i = 0; i < 10;i++)
+ printf("%d", i);
+ printf("\n");
+ i = 0;
+ do {
+ printf("%d", i++);
+ } while (i < 10);
+ printf("\n");
+
+ char count = 123;
+ /* c99 for loop init test */
+ for (size_t count = 1; count < 3; count++)
+ printf("count=%d\n", count);
+ printf("count = %d\n", count);
+
+ /* break/continue tests */
+ i = 0;
+ while (1) {
+ if (i == 6)
+ break;
+ i++;
+ if (i == 3)
+ continue;
+ printf("%d", i);
+ }
+ printf("\n");
+
+ /* break/continue tests */
+ i = 0;
+ do {
+ if (i == 6)
+ break;
+ i++;
+ if (i == 3)
+ continue;
+ printf("%d", i);
+ } while(1);
+ printf("\n");
+
+ for(i = 0;i < 10;i++) {
+ if (i == 3)
+ continue;
+ printf("%d", i);
+ }
+ printf("\n");
+}
+
+typedef int typedef_and_label;
+
+void goto_test()
+{
+ int i;
+ static void *label_table[3] = { &&label1, &&label2, &&label3 };
+
+ printf("goto:\n");
+ i = 0;
+ /* This needs to parse as label, not as start of decl. */
+ typedef_and_label:
+ s_loop:
+ if (i >= 10)
+ goto s_end;
+ printf("%d", i);
+ i++;
+ goto s_loop;
+ s_end:
+ printf("\n");
+
+ /* we also test computed gotos (GCC extension) */
+ for(i=0;i<3;i++) {
+ goto *label_table[i];
+ label1:
+ printf("label1\n");
+ goto next;
+ label2:
+ printf("label2\n");
+ goto next;
+ label3:
+ printf("label3\n");
+ next: ;
+ }
+}
+
+enum {
+ E0,
+ E1 = 2,
+ E2 = 4,
+ E3,
+ E4,
+};
+
+enum test {
+ E5 = 1000,
+};
+
+struct S_enum {
+ enum {E6 = 42, E7, E8} e:8;
+};
+
+enum ELong {
+ /* This is either 0 on L32 machines, or a large number
+ on L64 machines. We should be able to store this. */
+ EL_large = ((unsigned long)0xf000 << 31) << 1,
+};
+
+enum { BIASU = -1U<<31 };
+enum { BIASS = -1 << 31 };
+
+static int getint(int i)
+{
+ if (i)
+ return 0;
+ else
+ return (int)(-1U << 31);
+}
+
+void enum_test()
+{
+ enum test b1;
+ /* The following should give no warning */
+ unsigned *p = &b1;
+ struct S_enum s = {E7};
+ printf("enum: %d\n", s.e);
+ printf("enum:\n%d %d %d %d %d %d\n",
+ E0, E1, E2, E3, E4, E5);
+ b1 = 1;
+ printf("b1=%d\n", b1);
+ printf("enum large: %ld\n", EL_large);
+
+ if (getint(0) == BIASU)
+ printf("enum unsigned: ok\n");
+ else
+ printf("enum unsigned: wrong\n");
+ if (getint(0) == BIASS)
+ printf("enum unsigned: ok\n");
+ else
+ printf("enum unsigned: wrong\n");
+}
+
+typedef int *my_ptr;
+
+typedef int mytype1;
+typedef int mytype2;
+
+void typedef_test()
+{
+ my_ptr a;
+ mytype1 mytype2;
+ int b;
+
+ a = &b;
+ *a = 1234;
+ printf("typedef:\n");
+ printf("a=%d\n", *a);
+ mytype2 = 2;
+ printf("mytype2=%d\n", mytype2);
+}
+
+void forward_test()
+{
+ printf("forward:\n");
+ forward_ref();
+ forward_ref();
+}
+
+
+void forward_ref(void)
+{
+ printf("forward ok\n");
+}
+
+typedef struct struct1 {
+ int f1;
+ int f2, f3;
+ union union1 {
+ int v1;
+ int v2;
+ } u;
+ char str[3];
+} struct1;
+
+struct struct2 {
+ int a;
+ char b;
+};
+
+union union2 {
+ int w1;
+ int w2;
+};
+
+struct struct1 st1, st2;
+
+struct empty_mem {
+ /* nothing */ ;
+ int x;
+};
+
+int main(int argc, char **argv)
+{
+ string_test();
+ expr_test();
+ macro_test();
+ recursive_macro_test();
+ scope_test();
+ forward_test();
+ funcptr_test();
+ loop_test();
+ switch_test();
+ goto_test();
+ enum_test();
+ typedef_test();
+ struct_test();
+ array_test();
+ expr_ptr_test();
+ bool_test();
+ optimize_out();
+ expr2_test();
+ constant_expr_test();
+ expr_cmp_test();
+ char_short_test();
+ init_test();
+ compound_literal_test();
+ kr_test();
+ struct_assign_test();
+ cast_test();
+ bitfield_test();
+ c99_bool_test();
+ float_test();
+ longlong_test();
+ manyarg_test();
+ stdarg_test();
+ whitespace_test();
+ relocation_test();
+ old_style_function();
+ alloca_test();
+ c99_vla_test(5, 2);
+ sizeof_test();
+ typeof_test();
+ statement_expr_test();
+ local_label_test();
+ asm_test();
+ builtin_test();
+#ifndef _WIN32
+ weak_test();
+#endif
+ global_data_test();
+ cmp_comparison_test();
+ math_cmp_test();
+ callsave_test();
+ builtin_frame_address_test();
+ intdiv_test();
+ if (via_volatile (42) != 42)
+ printf ("via_volatile broken\n");
+ attrib_test();
+ return 0;
+}
+
+int tab[3];
+int tab2[3][2];
+
+int g;
+
+void f1(g)
+{
+ printf("g1=%d\n", g);
+}
+
+void scope_test()
+{
+ printf("scope:\n");
+ g = 2;
+ f1(1);
+ printf("g2=%d\n", g);
+ {
+ int g;
+ g = 3;
+ printf("g3=%d\n", g);
+ {
+ int g;
+ g = 4;
+ printf("g4=%d\n", g);
+ }
+ }
+ printf("g5=%d\n", g);
+}
+
+void array_test()
+{
+ int i, j, a[4];
+
+ printf("array:\n");
+ printf("sizeof(a) = %d\n", sizeof(a));
+ printf("sizeof(\"a\") = %d\n", sizeof("a"));
+#ifdef C99_MACROS
+ printf("sizeof(__func__) = %d\n", sizeof(__func__));
+#endif
+ printf("sizeof tab %d\n", sizeof(tab));
+ printf("sizeof tab2 %d\n", sizeof tab2);
+ tab[0] = 1;
+ tab[1] = 2;
+ tab[2] = 3;
+ printf("%d %d %d\n", tab[0], tab[1], tab[2]);
+ for(i=0;i<3;i++)
+ for(j=0;j<2;j++)
+ tab2[i][j] = 10 * i + j;
+ for(i=0;i<3*2;i++) {
+ printf(" %3d", ((int *)tab2)[i]);
+ }
+ printf("\n");
+ printf("sizeof(size_t)=%d\n", sizeof(size_t));
+ printf("sizeof(ptrdiff_t)=%d\n", sizeof(ptrdiff_t));
+}
+
+void expr_test()
+{
+ int a, b;
+ a = 0;
+ printf("%d\n", a += 1);
+ printf("%d\n", a -= 2);
+ printf("%d\n", a *= 31232132);
+ printf("%d\n", a /= 4);
+ printf("%d\n", a %= 20);
+ printf("%d\n", a &= 6);
+ printf("%d\n", a ^= 7);
+ printf("%d\n", a |= 8);
+ printf("%d\n", a >>= 3);
+ printf("%d\n", a <<= 4);
+
+ a = 22321;
+ b = -22321;
+ printf("%d\n", a + 1);
+ printf("%d\n", a - 2);
+ printf("%d\n", a * 312);
+ printf("%d\n", a / 4);
+ printf("%d\n", b / 4);
+ printf("%d\n", (unsigned)b / 4);
+ printf("%d\n", a % 20);
+ printf("%d\n", b % 20);
+ printf("%d\n", (unsigned)b % 20);
+ printf("%d\n", a & 6);
+ printf("%d\n", a ^ 7);
+ printf("%d\n", a | 8);
+ printf("%d\n", a >> 3);
+ printf("%d\n", b >> 3);
+ printf("%d\n", (unsigned)b >> 3);
+ printf("%d\n", a << 4);
+ printf("%d\n", ~a);
+ printf("%d\n", -a);
+ printf("%d\n", +a);
+
+ printf("%d\n", 12 + 1);
+ printf("%d\n", 12 - 2);
+ printf("%d\n", 12 * 312);
+ printf("%d\n", 12 / 4);
+ printf("%d\n", 12 % 20);
+ printf("%d\n", 12 & 6);
+ printf("%d\n", 12 ^ 7);
+ printf("%d\n", 12 | 8);
+ printf("%d\n", 12 >> 2);
+ printf("%d\n", 12 << 4);
+ printf("%d\n", ~12);
+ printf("%d\n", -12);
+ printf("%d\n", +12);
+ printf("%d %d %d %d\n",
+ isid('a'),
+ isid('g'),
+ isid('T'),
+ isid('('));
+}
+
+int isid(int c)
+{
+ return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z') | c == '_';
+}
+
+/**********************/
+
+int vstack[10], *vstack_ptr;
+
+void vpush(int vt, int vc)
+{
+ *vstack_ptr++ = vt;
+ *vstack_ptr++ = vc;
+}
+
+void vpop(int *ft, int *fc)
+{
+ *fc = *--vstack_ptr;
+ *ft = *--vstack_ptr;
+}
+
+void expr2_test()
+{
+ int a, b;
+
+ printf("expr2:\n");
+ vstack_ptr = vstack;
+ vpush(1432432, 2);
+ vstack_ptr[-2] &= ~0xffffff80;
+ vpop(&a, &b);
+ printf("res= %d %d\n", a, b);
+}
+
+void constant_expr_test()
+{
+ int a;
+ printf("constant_expr:\n");
+ a = 3;
+ printf("%d\n", a * 16);
+ printf("%d\n", a * 1);
+ printf("%d\n", a + 0);
+}
+
+int tab4[10];
+
+void expr_ptr_test()
+{
+ int *p, *q;
+ int i = -1;
+
+ printf("expr_ptr:\n");
+ p = tab4;
+ q = tab4 + 10;
+ printf("diff=%d\n", q - p);
+ p++;
+ printf("inc=%d\n", p - tab4);
+ p--;
+ printf("dec=%d\n", p - tab4);
+ ++p;
+ printf("inc=%d\n", p - tab4);
+ --p;
+ printf("dec=%d\n", p - tab4);
+ printf("add=%d\n", p + 3 - tab4);
+ printf("add=%d\n", 3 + p - tab4);
+
+ /* check if 64bit support is ok */
+ q = p = 0;
+ q += i;
+ printf("%p %p %ld\n", q, p, p-q);
+ printf("%d %d %d %d %d %d\n",
+ p == q, p != q, p < q, p <= q, p >= q, p > q);
+ i = 0xf0000000;
+ p += i;
+ printf("%p %p %ld\n", q, p, p-q);
+ printf("%d %d %d %d %d %d\n",
+ p == q, p != q, p < q, p <= q, p >= q, p > q);
+ p = (int *)((char *)p + 0xf0000000);
+ printf("%p %p %ld\n", q, p, p-q);
+ printf("%d %d %d %d %d %d\n",
+ p == q, p != q, p < q, p <= q, p >= q, p > q);
+ p += 0xf0000000;
+ printf("%p %p %ld\n", q, p, p-q);
+ printf("%d %d %d %d %d %d\n",
+ p == q, p != q, p < q, p <= q, p >= q, p > q);
+ {
+ struct size12 {
+ int i, j, k;
+ };
+ struct size12 s[2], *sp = s;
+ int i, j;
+ sp->i = 42;
+ sp++;
+ j = -1;
+ printf("%d\n", sp[j].i);
+ }
+#ifdef __LP64__
+ i = 1;
+ p = (int*)0x100000000UL + i;
+ i = ((long)p) >> 32;
+ printf("largeptr: %p %d\n", p, i);
+#endif
+}
+
+void expr_cmp_test()
+{
+ int a, b;
+ printf("constant_expr:\n");
+ a = -1;
+ b = 1;
+ printf("%d\n", a == a);
+ printf("%d\n", a != a);
+
+ printf("%d\n", a < b);
+ printf("%d\n", a <= b);
+ printf("%d\n", a <= a);
+ printf("%d\n", b >= a);
+ printf("%d\n", a >= a);
+ printf("%d\n", b > a);
+
+ printf("%d\n", (unsigned)a < b);
+ printf("%d\n", (unsigned)a <= b);
+ printf("%d\n", (unsigned)a <= a);
+ printf("%d\n", (unsigned)b >= a);
+ printf("%d\n", (unsigned)a >= a);
+ printf("%d\n", (unsigned)b > a);
+}
+
+struct empty {
+};
+
+struct aligntest1 {
+ char a[10];
+};
+
+struct aligntest2 {
+ int a;
+ char b[10];
+};
+
+struct aligntest3 {
+ double a, b;
+};
+
+struct aligntest4 {
+ double a[0];
+};
+
+struct __attribute__((aligned(16))) aligntest5
+{
+ int i;
+};
+struct aligntest6
+{
+ int i;
+} __attribute__((aligned(16)));
+struct aligntest7
+{
+ int i;
+};
+struct aligntest5 altest5[2];
+struct aligntest6 altest6[2];
+int pad1;
+/* altest7 is correctly aligned to 16 bytes also with TCC,
+ but __alignof__ returns the wrong result (4) because we
+ can't store the alignment yet when specified on symbols
+ directly (it's stored in the type so we'd need to make
+ a copy of it). -- FIXED */
+struct aligntest7 altest7[2] __attribute__((aligned(16)));
+
+struct aligntest8
+{
+ int i;
+} __attribute__((aligned(4096)));
+
+struct Large {
+ unsigned long flags;
+ union {
+ void *u1;
+ int *u2;
+ };
+
+ struct {
+ union {
+ unsigned long index;
+ void *freelist;
+ };
+ union {
+ unsigned long counters;
+ struct {
+ int bla;
+ };
+ };
+ };
+
+ union {
+ struct {
+ long u3;
+ long u4;
+ };
+ void *u5;
+ struct {
+ unsigned long compound_head;
+ unsigned int compound_dtor;
+ unsigned int compound_order;
+ };
+ };
+} __attribute__((aligned(2 * sizeof(long))));
+
+typedef unsigned long long __attribute__((aligned(4))) unaligned_u64;
+
+struct aligntest9 {
+ unsigned int buf_nr;
+ unaligned_u64 start_lba;
+};
+
+struct aligntest10 {
+ unsigned int buf_nr;
+ unsigned long long start_lba;
+};
+
+void struct_test()
+{
+ struct1 *s;
+ union union2 u;
+ struct Large ls;
+
+ printf("struct:\n");
+ printf("sizes: %d %d %d %d\n",
+ sizeof(struct struct1),
+ sizeof(struct struct2),
+ sizeof(union union1),
+ sizeof(union union2));
+ printf("offsets: %d\n", (int)((char*)&st1.u.v1 - (char*)&st1));
+ st1.f1 = 1;
+ st1.f2 = 2;
+ st1.f3 = 3;
+ printf("st1: %d %d %d\n",
+ st1.f1, st1.f2, st1.f3);
+ st1.u.v1 = 1;
+ st1.u.v2 = 2;
+ printf("union1: %d\n", st1.u.v1);
+ u.w1 = 1;
+ u.w2 = 2;
+ printf("union2: %d\n", u.w1);
+ s = &st2;
+ s->f1 = 3;
+ s->f2 = 2;
+ s->f3 = 1;
+ printf("st2: %d %d %d\n",
+ s->f1, s->f2, s->f3);
+ printf("str_addr=%x\n", (int)st1.str - (int)&st1.f1);
+
+ /* align / size tests */
+ printf("aligntest1 sizeof=%d alignof=%d\n",
+ sizeof(struct aligntest1), __alignof__(struct aligntest1));
+ printf("aligntest2 sizeof=%d alignof=%d\n",
+ sizeof(struct aligntest2), __alignof__(struct aligntest2));
+ printf("aligntest3 sizeof=%d alignof=%d\n",
+ sizeof(struct aligntest3), __alignof__(struct aligntest3));
+ printf("aligntest4 sizeof=%d alignof=%d\n",
+ sizeof(struct aligntest4), __alignof__(struct aligntest4));
+ printf("aligntest5 sizeof=%d alignof=%d\n",
+ sizeof(struct aligntest5), __alignof__(struct aligntest5));
+ printf("aligntest6 sizeof=%d alignof=%d\n",
+ sizeof(struct aligntest6), __alignof__(struct aligntest6));
+ printf("aligntest7 sizeof=%d alignof=%d\n",
+ sizeof(struct aligntest7), __alignof__(struct aligntest7));
+ printf("aligntest8 sizeof=%d alignof=%d\n",
+ sizeof(struct aligntest8), __alignof__(struct aligntest8));
+ printf("aligntest9 sizeof=%d alignof=%d\n",
+ sizeof(struct aligntest9), __alignof__(struct aligntest9));
+ printf("aligntest10 sizeof=%d alignof=%d\n",
+ sizeof(struct aligntest10), __alignof__(struct aligntest10));
+ printf("altest5 sizeof=%d alignof=%d\n",
+ sizeof(altest5), __alignof__(altest5));
+ printf("altest6 sizeof=%d alignof=%d\n",
+ sizeof(altest6), __alignof__(altest6));
+ printf("altest7 sizeof=%d alignof=%d\n",
+ sizeof(altest7), __alignof__(altest7));
+
+ /* empty structures (GCC extension) */
+ printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
+ printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
+
+ printf("Large: sizeof=%d\n", sizeof(ls));
+ memset(&ls, 0, sizeof(ls));
+ ls.compound_head = 42;
+ printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls.compound_head - (char*)&ls));
+}
+
+/* XXX: depend on endianness */
+void char_short_test()
+{
+ int var1, var2;
+
+ printf("char_short:\n");
+
+ var1 = 0x01020304;
+ var2 = 0xfffefdfc;
+ printf("s8=%d %d\n",
+ *(char *)&var1, *(char *)&var2);
+ printf("u8=%d %d\n",
+ *(unsigned char *)&var1, *(unsigned char *)&var2);
+ printf("s16=%d %d\n",
+ *(short *)&var1, *(short *)&var2);
+ printf("u16=%d %d\n",
+ *(unsigned short *)&var1, *(unsigned short *)&var2);
+ printf("s32=%d %d\n",
+ *(int *)&var1, *(int *)&var2);
+ printf("u32=%d %d\n",
+ *(unsigned int *)&var1, *(unsigned int *)&var2);
+ *(char *)&var1 = 0x08;
+ printf("var1=%x\n", var1);
+ *(short *)&var1 = 0x0809;
+ printf("var1=%x\n", var1);
+ *(int *)&var1 = 0x08090a0b;
+ printf("var1=%x\n", var1);
+}
+
+/******************/
+
+typedef struct Sym {
+ int v;
+ int t;
+ int c;
+ struct Sym *next;
+ struct Sym *prev;
+} Sym;
+
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+
+static int toupper1(int a)
+{
+ return TOUPPER(a);
+}
+
+static unsigned int calc_vm_flags(unsigned int prot)
+{
+ unsigned int prot_bits;
+ /* This used to segfault in some revisions: */
+ prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0);
+ return prot_bits;
+}
+
+void bool_test()
+{
+ int *s, a, b, t, f, i;
+
+ a = 0;
+ s = (void*)0;
+ printf("!s=%d\n", !s);
+
+ if (!s || !s[0])
+ a = 1;
+ printf("a=%d\n", a);
+
+ printf("a=%d %d %d\n", 0 || 0, 0 || 1, 1 || 1);
+ printf("a=%d %d %d\n", 0 && 0, 0 && 1, 1 && 1);
+ printf("a=%d %d\n", 1 ? 1 : 0, 0 ? 1 : 0);
+#if 1 && 1
+ printf("a1\n");
+#endif
+#if 1 || 0
+ printf("a2\n");
+#endif
+#if 1 ? 0 : 1
+ printf("a3\n");
+#endif
+#if 0 ? 0 : 1
+ printf("a4\n");
+#endif
+
+ a = 4;
+ printf("b=%d\n", a + (0 ? 1 : a / 2));
+
+ /* test register spilling */
+ a = 10;
+ b = 10;
+ a = (a + b) * ((a < b) ?
+ ((b - a) * (a - b)): a + b);
+ printf("a=%d\n", a);
+
+ /* test complex || or && expressions */
+ t = 1;
+ f = 0;
+ a = 32;
+ printf("exp=%d\n", f == (32 <= a && a <= 3));
+ printf("r=%d\n", (t || f) + (t && f));
+
+ /* test ? : cast */
+ {
+ int aspect_on;
+ int aspect_native = 65536;
+ double bfu_aspect = 1.0;
+ int aspect;
+ for(aspect_on = 0; aspect_on < 2; aspect_on++) {
+ aspect=aspect_on?(aspect_native*bfu_aspect+0.5):65535UL;
+ printf("aspect=%d\n", aspect);
+ }
+ }
+
+ /* test ? : GCC extension */
+ {
+ static int v1 = 34 ? : -1; /* constant case */
+ static int v2 = 0 ? : -1; /* constant case */
+ int a = 30;
+
+ printf("%d %d\n", v1, v2);
+ printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2);
+ }
+
+ /* again complex expression */
+ for(i=0;i<256;i++) {
+ if (toupper1 (i) != TOUPPER (i))
+ printf("error %d\n", i);
+ }
+ printf ("bits = 0x%x\n", calc_vm_flags (0x1));
+}
+
+extern int undefined_function(void);
+extern int defined_function(void);
+
+static inline void refer_to_undefined(void)
+{
+ undefined_function();
+}
+
+void optimize_out(void)
+{
+ int i = 0 ? undefined_function() : defined_function();
+ printf ("oo:%d\n", i);
+ int j = 1 ? defined_function() : undefined_function();
+ printf ("oo:%d\n", j);
+ if (0)
+ printf("oo:%d\n", undefined_function());
+ else
+ printf("oo:%d\n", defined_function());
+ if (1)
+ printf("oo:%d\n", defined_function());
+ else
+ printf("oo:%d\n", undefined_function());
+ while (1) {
+ printf("oow:%d\n", defined_function());
+ break;
+ printf("oow:%d\n", undefined_function());
+ }
+ j = 1;
+ /* Following is a switch without {} block intentionally. */
+ switch (j)
+ case 1: break;
+ printf ("oos:%d\n", defined_function());
+ /* The following break shouldn't lead to disabled code after
+ the while. */
+ while (1)
+ break;
+ printf ("ool1:%d\n", defined_function());
+ /* Same for the other types of loops. */
+ do
+ break;
+ while (1);
+ printf ("ool2:%d\n", defined_function());
+ for (;;)
+ break;
+ printf ("ool3:%d\n", defined_function());
+ /* Normal {} blocks without controlling statements
+ shouldn't reactivate code emission */
+ while (1) {
+ {
+ break;
+ }
+ printf ("ool4:%d\n", undefined_function());
+ }
+ j = 1;
+ while (j) {
+ if (j == 0)
+ break; /* this break shouldn't disable code outside the if. */
+ printf("ool5:%d\n", defined_function());
+ j--;
+ }
+
+ j = 1;
+ while (j) {
+ if (1)
+ j--;
+ else
+ breakhere: break;
+ printf("ool6:%d\n", defined_function());
+ goto breakhere;
+ }
+
+ /* Test that constants in logical && are optimized: */
+ i = 0 && undefined_function();
+ i = defined_function() && 0 && undefined_function();
+ if (0 && undefined_function())
+ undefined_function();
+ if (defined_function() && 0)
+ undefined_function();
+ if (0 && 0)
+ undefined_function();
+ if (defined_function() && 0 && undefined_function())
+ undefined_function();
+ /* The same for || : */
+ i = 1 || undefined_function();
+ i = defined_function() || 1 || undefined_function();
+ if (1 || undefined_function())
+ ;
+ else
+ undefined_function();
+ if (defined_function() || 1)
+ ;
+ else
+ undefined_function();
+ if (1 || 1)
+ ;
+ else
+ undefined_function();
+ if (defined_function() || 1 || undefined_function())
+ ;
+ else
+ undefined_function();
+
+ if (defined_function() && 0)
+ refer_to_undefined();
+
+ if (0) {
+ (void)sizeof( ({
+ do { } while (0);
+ 0;
+ }) );
+ undefined_function();
+ }
+
+ /* Leave the "if(1)return; printf()" in this order and last in the function */
+ if (1)
+ return;
+ printf ("oor:%d\n", undefined_function());
+}
+
+int defined_function(void)
+{
+ static int i = 40;
+ return i++;
+}
+
+/* GCC accepts that */
+static int tab_reinit[];
+static int tab_reinit[10];
+
+//int cinit1; /* a global variable can be defined several times without error ! */
+int cinit1;
+int cinit1;
+int cinit1 = 0;
+int *cinit2 = (int []){3, 2, 1};
+
+void compound_literal_test(void)
+{
+ int *p, i;
+ char *q, *q3;
+
+ printf("compound_test:\n");
+
+ p = (int []){1, 2, 3};
+ for(i=0;i<3;i++)
+ printf(" %d", p[i]);
+ printf("\n");
+
+ for(i=0;i<3;i++)
+ printf("%d", cinit2[i]);
+ printf("\n");
+
+ q = "tralala1";
+ printf("q1=%s\n", q);
+
+ q = (char *){ "tralala2" };
+ printf("q2=%s\n", q);
+
+ q3 = (char *){ q };
+ printf("q3=%s\n", q3);
+
+ q = (char []){ "tralala3" };
+ printf("q4=%s\n", q);
+
+#ifdef ALL_ISOC99
+ p = (int []){1, 2, cinit1 + 3};
+ for(i=0;i<3;i++)
+ printf(" %d", p[i]);
+ printf("\n");
+
+ for(i=0;i<3;i++) {
+ p = (int []){1, 2, 4 + i};
+ printf("%d %d %d\n",
+ p[0],
+ p[1],
+ p[2]);
+ }
+#endif
+}
+
+/* K & R protos */
+
+kr_func1(a, b)
+{
+ return a + b;
+}
+
+int kr_func2(a, b)
+{
+ return a + b;
+}
+
+kr_test()
+{
+ printf("kr_test:\n");
+ printf("func1=%d\n", kr_func1(3, 4));
+ printf("func2=%d\n", kr_func2(3, 4));
+ return 0;
+}
+
+void num(int n)
+{
+ char *tab, *p;
+ tab = (char*)malloc(20);
+ p = tab;
+ while (1) {
+ *p = 48 + (n % 10);
+ p++;
+ n = n / 10;
+ if (n == 0)
+ break;
+ }
+ while (p != tab) {
+ p--;
+ printf("%c", *p);
+ }
+ printf("\n");
+ free(tab);
+}
+
+/* structure assignment tests */
+struct structa1 {
+ int f1;
+ char f2;
+};
+
+struct structa1 ssta1;
+
+void struct_assign_test1(struct structa1 s1, int t, float f)
+{
+ printf("%d %d %d %f\n", s1.f1, s1.f2, t, f);
+}
+
+struct structa1 struct_assign_test2(struct structa1 s1, int t)
+{
+ s1.f1 += t;
+ s1.f2 -= t;
+ return s1;
+}
+
+void struct_assign_test(void)
+{
+ struct S {
+ struct structa1 lsta1, lsta2;
+ int i;
+ } s, *ps;
+
+ ps = &s;
+ ps->i = 4;
+#if 0
+ printf("struct_assign_test:\n");
+
+ s.lsta1.f1 = 1;
+ s.lsta1.f2 = 2;
+ printf("%d %d\n", s.lsta1.f1, s.lsta1.f2);
+ s.lsta2 = s.lsta1;
+ printf("%d %d\n", s.lsta2.f1, s.lsta2.f2);
+#else
+ s.lsta2.f1 = 1;
+ s.lsta2.f2 = 2;
+#endif
+ struct_assign_test1(ps->lsta2, 3, 4.5);
+
+ printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
+ ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
+ printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
+
+ static struct {
+ void (*elem)();
+ } t[] = {
+ /* XXX: we should allow this even without braces */
+ { struct_assign_test }
+ };
+ printf("%d\n", struct_assign_test == t[0].elem);
+}
+
+/* casts to short/char */
+
+void cast1(char a, short b, unsigned char c, unsigned short d)
+{
+ printf("%d %d %d %d\n", a, b, c, d);
+}
+
+char bcast;
+short scast;
+
+void cast_test()
+{
+ int a;
+ char c;
+ char tab[10];
+ unsigned b,d;
+ short s;
+ char *p = NULL;
+ p -= 0x700000000042;
+
+ printf("cast_test:\n");
+ a = 0xfffff;
+ cast1(a, a, a, a);
+ a = 0xffffe;
+ printf("%d %d %d %d\n",
+ (char)(a + 1),
+ (short)(a + 1),
+ (unsigned char)(a + 1),
+ (unsigned short)(a + 1));
+ printf("%d %d %d %d\n",
+ (char)0xfffff,
+ (short)0xfffff,
+ (unsigned char)0xfffff,
+ (unsigned short)0xfffff);
+
+ a = (bcast = 128) + 1;
+ printf("%d\n", a);
+ a = (scast = 65536) + 1;
+ printf("%d\n", a);
+
+ printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
+
+ /* test cast from unsigned to signed short to int */
+ b = 0xf000;
+ d = (short)b;
+ printf("((unsigned)(short)0x%08x) = 0x%08x\n", b, d);
+ b = 0xf0f0;
+ d = (char)b;
+ printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
+
+ /* test implicit int casting for array accesses */
+ c = 0;
+ tab[1] = 2;
+ tab[c] = 1;
+ printf("%d %d\n", tab[0], tab[1]);
+
+ /* test implicit casting on some operators */
+ printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a'));
+ printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a'));
+ printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a'));
+
+ /* from pointer to integer types */
+ printf("%d %d %ld %ld %lld %lld\n",
+ (int)p, (unsigned int)p,
+ (long)p, (unsigned long)p,
+ (long long)p, (unsigned long long)p);
+
+ /* from integers to pointers */
+ printf("%p %p %p %p\n",
+ (void *)a, (void *)b, (void *)c, (void *)d);
+}
+
+/* initializers tests */
+struct structinit1 {
+ int f1;
+ char f2;
+ short f3;
+ int farray[3];
+};
+
+int sinit1 = 2;
+int sinit2 = { 3 };
+int sinit3[3] = { 1, 2, {{3}}, };
+int sinit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
+int sinit5[3][2] = { 1, 2, 3, 4, 5, 6 };
+int sinit6[] = { 1, 2, 3 };
+int sinit7[] = { [2] = 3, [0] = 1, 2 };
+char sinit8[] = "hello" "trala";
+
+struct structinit1 sinit9 = { 1, 2, 3 };
+struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 };
+struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1,
+#ifdef ALL_ISOC99
+ .farray[0] = 10,
+ .farray[1] = 11,
+ .farray[2] = 12,
+#endif
+};
+
+char *sinit12 = "hello world";
+char *sinit13[] = {
+ "test1",
+ "test2",
+ "test3",
+};
+char sinit14[10] = { "abc" };
+int sinit15[3] = { sizeof(sinit15), 1, 2 };
+
+struct { int a[3], b; } sinit16[] = { { 1 }, 2 };
+
+struct bar {
+ char *s;
+ int len;
+} sinit17[] = {
+ "a1", 4,
+ "a2", 1
+};
+
+int sinit18[10] = {
+ [2 ... 5] = 20,
+ 2,
+ [8] = 10,
+};
+
+struct complexinit0 {
+ int a;
+ int b;
+};
+
+struct complexinit {
+ int a;
+ const struct complexinit0 *b;
+};
+
+const static struct complexinit cix[] = {
+ [0] = {
+ .a = 2000,
+ .b = (const struct complexinit0[]) {
+ { 2001, 2002 },
+ { 2003, 2003 },
+ {}
+ }
+ }
+};
+
+struct complexinit2 {
+ int a;
+ int b[];
+};
+
+struct complexinit2 cix20;
+
+struct complexinit2 cix21 = {
+ .a = 3000,
+ .b = { 3001, 3002, 3003 }
+};
+
+struct complexinit2 cix22 = {
+ .a = 4000,
+ .b = { 4001, 4002, 4003, 4004, 4005, 4006 }
+};
+
+typedef int arrtype1[];
+arrtype1 sinit19 = {1};
+arrtype1 sinit20 = {2,3};
+typedef int arrtype2[3];
+arrtype2 sinit21 = {4};
+arrtype2 sinit22 = {5,6,7};
+
+/* Address comparisons of non-weak symbols with zero can be const-folded */
+int sinit23[2] = { "astring" ? sizeof("astring") : -1,
+ &sinit23 ? 42 : -1 };
+
+extern int external_inited = 42;
+
+void init_test(void)
+{
+ int linit1 = 2;
+ int linit2 = { 3 };
+ int linit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
+ int linit6[] = { 1, 2, 3 };
+ int i, j;
+ char linit8[] = "hello" "trala";
+ int linit12[10] = { 1, 2 };
+ int linit13[10] = { 1, 2, [7] = 3, [3] = 4, };
+ char linit14[10] = "abc";
+ int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
+ struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
+ int linit17 = sizeof(linit17);
+ int zero = 0;
+ /* Addresses on non-weak symbols are non-zero, but not the access itself */
+ int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 };
+
+ printf("init_test:\n");
+
+ printf("sinit1=%d\n", sinit1);
+ printf("sinit2=%d\n", sinit2);
+ printf("sinit3=%d %d %d %d\n",
+ sizeof(sinit3),
+ sinit3[0],
+ sinit3[1],
+ sinit3[2]
+ );
+ printf("sinit6=%d\n", sizeof(sinit6));
+ printf("sinit7=%d %d %d %d\n",
+ sizeof(sinit7),
+ sinit7[0],
+ sinit7[1],
+ sinit7[2]
+ );
+ printf("sinit8=%s\n", sinit8);
+ printf("sinit9=%d %d %d\n",
+ sinit9.f1,
+ sinit9.f2,
+ sinit9.f3
+ );
+ printf("sinit10=%d %d %d\n",
+ sinit10.f1,
+ sinit10.f2,
+ sinit10.f3
+ );
+ printf("sinit11=%d %d %d %d %d %d\n",
+ sinit11.f1,
+ sinit11.f2,
+ sinit11.f3,
+ sinit11.farray[0],
+ sinit11.farray[1],
+ sinit11.farray[2]
+ );
+
+ for(i=0;i<3;i++)
+ for(j=0;j<2;j++)
+ printf("[%d][%d] = %d %d %d\n",
+ i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]);
+ printf("linit1=%d\n", linit1);
+ printf("linit2=%d\n", linit2);
+ printf("linit6=%d\n", sizeof(linit6));
+ printf("linit8=%d %s\n", sizeof(linit8), linit8);
+
+ printf("sinit12=%s\n", sinit12);
+ printf("sinit13=%d %s %s %s\n",
+ sizeof(sinit13),
+ sinit13[0],
+ sinit13[1],
+ sinit13[2]);
+ printf("sinit14=%s\n", sinit14);
+
+ for(i=0;i<10;i++) printf(" %d", linit12[i]);
+ printf("\n");
+ for(i=0;i<10;i++) printf(" %d", linit13[i]);
+ printf("\n");
+ for(i=0;i<10;i++) printf(" %d", linit14[i]);
+ printf("\n");
+ for(i=0;i<10;i++) printf(" %d", linit15[i]);
+ printf("\n");
+ printf("%d %d %d %d\n",
+ linit16.a1,
+ linit16.a2,
+ linit16.a3,
+ linit16.a4);
+ /* test that initialisation is done after variable declare */
+ printf("linit17=%d\n", linit17);
+ printf("sinit15=%d\n", sinit15[0]);
+ printf("sinit16=%d %d\n", sinit16[0].a[0], sinit16[1].a[0]);
+ printf("sinit17=%s %d %s %d\n",
+ sinit17[0].s, sinit17[0].len,
+ sinit17[1].s, sinit17[1].len);
+ for(i=0;i<10;i++)
+ printf("%x ", sinit18[i]);
+ printf("\n");
+ /* complex init check */
+ printf("cix: %d %d %d %d %d %d %d\n",
+ cix[0].a,
+ cix[0].b[0].a, cix[0].b[0].b,
+ cix[0].b[1].a, cix[0].b[1].b,
+ cix[0].b[2].a, cix[0].b[2].b);
+ printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]);
+ printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22);
+
+ printf("arrtype1: %d %d %d\n", sinit19[0], sinit20[0], sinit20[1]);
+ printf("arrtype2: %d %d\n", sizeof(sinit19), sizeof(sinit20));
+ printf("arrtype3: %d %d %d\n", sinit21[0], sinit21[1], sinit21[2]);
+ printf("arrtype4: %d %d %d\n", sinit22[0], sinit22[1], sinit22[2]);
+ printf("arrtype5: %d %d\n", sizeof(sinit21), sizeof(sinit22));
+ printf("arrtype6: %d\n", sizeof(arrtype2));
+
+ printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
+ printf("linit18= %d %d\n", linit18[0], linit18[1]);
+}
+
+void switch_uc(unsigned char uc)
+{
+ switch (uc) {
+ case 0xfb ... 0xfe:
+ printf("ucsw:1\n");
+ break;
+ case 0xff:
+ printf("ucsw:2\n");
+ break;
+ case 0 ... 5:
+ printf("ucsw:3\n");
+ break;
+ default:
+ printf("ucsw: broken!\n");
+ }
+}
+
+void switch_sc(signed char sc)
+{
+ switch (sc) {
+ case -5 ... -2:
+ printf("scsw:1\n");
+ break;
+ case -1:
+ printf("scsw:2\n");
+ break;
+ case 0 ... 5:
+ printf("scsw:3\n");
+ break;
+ default:
+ printf("scsw: broken!\n");
+ }
+}
+
+void switch_test()
+{
+ int i;
+ unsigned long long ull;
+ long long ll;
+
+ for(i=0;i<15;i++) {
+ switch(i) {
+ case 0:
+ case 1:
+ printf("a");
+ break;
+ default:
+ printf("%d", i);
+ break;
+ case 8 ... 12:
+ printf("c");
+ break;
+ case 3:
+ printf("b");
+ break;
+ case 0xc33c6b9fU:
+ case 0x7c9eeeb9U:
+ break;
+ }
+ }
+ printf("\n");
+
+ for (i = 1; i <= 5; i++) {
+ ull = (unsigned long long)i << 61;
+ switch (ull) {
+ case 1ULL << 61:
+ printf("ullsw:1\n");
+ break;
+ case 2ULL << 61:
+ printf("ullsw:2\n");
+ break;
+ case 3ULL << 61:
+ printf("ullsw:3\n");
+ break;
+ case 4ULL << 61:
+ printf("ullsw:4\n");
+ break;
+ case 5ULL << 61:
+ printf("ullsw:5\n");
+ break;
+ default:
+ printf("ullsw: broken!\n");
+ }
+ }
+
+ for (i = 1; i <= 5; i++) {
+ ll = (long long)i << 61;
+ switch (ll) {
+ case 1LL << 61:
+ printf("llsw:1\n");
+ break;
+ case 2LL << 61:
+ printf("llsw:2\n");
+ break;
+ case 3LL << 61:
+ printf("llsw:3\n");
+ break;
+ case 4LL << 61:
+ printf("llsw:4\n");
+ break;
+ case 5LL << 61:
+ printf("llsw:5\n");
+ break;
+ default:
+ printf("llsw: broken!\n");
+ }
+ }
+
+ for (i = -5; i <= 5; i++) {
+ switch_uc((unsigned char)i);
+ }
+
+ for (i = -5; i <= 5; i++) {
+ switch_sc ((signed char)i);
+ }
+}
+
+/* ISOC99 _Bool type */
+void c99_bool_test(void)
+{
+#ifdef BOOL_ISOC99
+ int a;
+ _Bool b;
+
+ printf("bool_test:\n");
+ printf("sizeof(_Bool) = %d\n", sizeof(_Bool));
+ a = 3;
+ printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a);
+ b = 3;
+ printf("b = %d\n", b);
+ b++;
+ printf("b = %d\n", b);
+#endif
+}
+
+void bitfield_test(void)
+{
+ int a;
+ short sa;
+ unsigned char ca;
+ struct sbf1 {
+ int f1 : 3;
+ int : 2;
+ int f2 : 1;
+ int : 0;
+ int f3 : 5;
+ int f4 : 7;
+ unsigned int f5 : 7;
+ } st1;
+ printf("bitfield_test:");
+ printf("sizeof(st1) = %d\n", sizeof(st1));
+
+ st1.f1 = 3;
+ st1.f2 = 1;
+ st1.f3 = 15;
+ a = 120;
+ st1.f4 = a;
+ st1.f5 = a;
+ st1.f5++;
+ printf("%d %d %d %d %d\n",
+ st1.f1, st1.f2, st1.f3, st1.f4, st1.f5);
+ sa = st1.f5;
+ ca = st1.f5;
+ printf("%d %d\n", sa, ca);
+
+ st1.f1 = 7;
+ if (st1.f1 == -1)
+ printf("st1.f1 == -1\n");
+ else
+ printf("st1.f1 != -1\n");
+ if (st1.f2 == -1)
+ printf("st1.f2 == -1\n");
+ else
+ printf("st1.f2 != -1\n");
+
+ struct sbf2 {
+ long long f1 : 45;
+ long long : 2;
+ long long f2 : 35;
+ unsigned long long f3 : 38;
+ } st2;
+ st2.f1 = 0x123456789ULL;
+ a = 120;
+ st2.f2 = (long long)a << 25;
+ st2.f3 = a;
+ st2.f2++;
+ printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
+
+#if 0
+ Disabled for now until further clarification re GCC compatibility
+ struct sbf3 {
+ int f1 : 7;
+ int f2 : 1;
+ char f3;
+ int f4 : 8;
+ int f5 : 1;
+ int f6 : 16;
+ } st3;
+ printf("sizeof(st3) = %d\n", sizeof(st3));
+#endif
+
+ struct sbf4 {
+ int x : 31;
+ char y : 2;
+ } st4;
+ st4.y = 1;
+ printf("st4.y == %d\n", st4.y);
+ struct sbf5 {
+ int a;
+ char b;
+ int x : 12, y : 4, : 0, : 4, z : 3;
+ char c;
+ } st5 = { 1, 2, 3, 4, -3, 6 };
+ printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c);
+ struct sbf6 {
+ short x : 12;
+ unsigned char y : 2;
+ } st6;
+ st6.y = 1;
+ printf("st6.y == %d\n", st6.y);
+}
+
+#ifdef __x86_64__
+#define FLOAT_FMT "%f\n"
+#else
+/* x86's float isn't compatible with GCC */
+#define FLOAT_FMT "%.5f\n"
+#endif
+
+/* declare strto* functions as they are C99 */
+double strtod(const char *nptr, char **endptr);
+
+#if defined(_WIN32)
+float strtof(const char *nptr, char **endptr) {return (float)strtod(nptr, endptr);}
+LONG_DOUBLE strtold(const char *nptr, char **endptr) {return (LONG_DOUBLE)strtod(nptr, endptr);}
+#else
+float strtof(const char *nptr, char **endptr);
+LONG_DOUBLE strtold(const char *nptr, char **endptr);
+#endif
+
+#define FTEST(prefix, typename, type, fmt)\
+void prefix ## cmp(type a, type b)\
+{\
+ printf("%d %d %d %d %d %d\n",\
+ a == b,\
+ a != b,\
+ a < b,\
+ a > b,\
+ a >= b,\
+ a <= b);\
+ printf(fmt " " fmt " " fmt " " fmt " " fmt " " fmt " " fmt "\n",\
+ a,\
+ b,\
+ a + b,\
+ a - b,\
+ a * b,\
+ a / b,\
+ -a);\
+ printf(fmt "\n", ++a);\
+ printf(fmt "\n", a++);\
+ printf(fmt "\n", a);\
+ b = 0;\
+ printf("%d %d\n", !a, !b);\
+}\
+void prefix ## fcast(type a)\
+{\
+ float fa;\
+ double da;\
+ LONG_DOUBLE la;\
+ int ia;\
+ long long llia;\
+ unsigned int ua;\
+ unsigned long long llua;\
+ type b;\
+ fa = a;\
+ da = a;\
+ la = a;\
+ printf("ftof: %f %f %Lf\n", fa, da, la);\
+ ia = (int)a;\
+ llia = (long long)a;\
+ a = (a >= 0) ? a : -a;\
+ ua = (unsigned int)a;\
+ llua = (unsigned long long)a;\
+ printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
+ ia = -1234;\
+ ua = 0x81234500;\
+ llia = -0x123456789012345LL;\
+ llua = 0xf123456789012345LLU;\
+ b = ia;\
+ printf("itof: " fmt "\n", b);\
+ b = ua;\
+ printf("utof: " fmt "\n", b);\
+ b = llia;\
+ printf("lltof: " fmt "\n", b);\
+ b = llua;\
+ printf("ulltof: " fmt "\n", b);\
+}\
+\
+float prefix ## retf(type a) { return a; }\
+double prefix ## retd(type a) { return a; }\
+LONG_DOUBLE prefix ## retld(type a) { return a; }\
+\
+void prefix ## call(void)\
+{\
+ printf("float: " FLOAT_FMT, prefix ## retf(42.123456789));\
+ printf("double: %f\n", prefix ## retd(42.123456789));\
+ printf("long double: %Lf\n", prefix ## retld(42.123456789));\
+ printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
+}\
+\
+void prefix ## signed_zeros(void) \
+{\
+ type x = 0.0, y = -0.0, n, p;\
+ if (x == y)\
+ printf ("Test 1.0 / x != 1.0 / y returns %d (should be 1).\n",\
+ 1.0 / x != 1.0 / y);\
+ else\
+ printf ("x != y; this is wrong!\n");\
+\
+ n = -x;\
+ if (x == n)\
+ printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\
+ 1.0 / x != 1.0 / n);\
+ else\
+ printf ("x != -x; this is wrong!\n");\
+\
+ p = +y;\
+ if (x == p)\
+ printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\
+ 1.0 / x != 1.0 / p);\
+ else\
+ printf ("x != +y; this is wrong!\n");\
+ p = -y;\
+ if (x == p)\
+ printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
+ 1.0 / x != 1.0 / p);\
+ else\
+ printf ("x != -y; this is wrong!\n");\
+}\
+void prefix ## test(void)\
+{\
+ printf("testing '%s'\n", #typename);\
+ prefix ## cmp(1, 2.5);\
+ prefix ## cmp(2, 1.5);\
+ prefix ## cmp(1, 1);\
+ prefix ## fcast(234.6);\
+ prefix ## fcast(-2334.6);\
+ prefix ## call();\
+ prefix ## signed_zeros();\
+}
+
+FTEST(f, float, float, "%f")
+FTEST(d, double, double, "%f")
+FTEST(ld, long double, LONG_DOUBLE, "%Lf")
+
+double ftab1[3] = { 1.2, 3.4, -5.6 };
+
+
+void float_test(void)
+{
+#if !defined(__arm__) || defined(__ARM_PCS_VFP)
+ float fa, fb;
+ double da, db;
+ int a;
+ unsigned int b;
+
+ printf("float_test:\n");
+ printf("sizeof(float) = %d\n", sizeof(float));
+ printf("sizeof(double) = %d\n", sizeof(double));
+ printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE));
+ ftest();
+ dtest();
+ ldtest();
+ printf("%f %f %f\n", ftab1[0], ftab1[1], ftab1[2]);
+ printf("%f %f %f\n", 2.12, .5, 2.3e10);
+ // printf("%f %f %f\n", 0x1234p12, 0x1e23.23p10, 0x12dp-10);
+ da = 123;
+ printf("da=%f\n", da);
+ fa = 123;
+ printf("fa=%f\n", fa);
+ a = 4000000000;
+ da = a;
+ printf("da = %f\n", da);
+ b = 4000000000;
+ db = b;
+ printf("db = %f\n", db);
+#endif
+}
+
+int fib(int n)
+{
+ if (n <= 2)
+ return 1;
+ else
+ return fib(n-1) + fib(n-2);
+}
+
+void funcptr_test()
+{
+ void (*func)(int);
+ int a;
+ struct {
+ int dummy;
+ void (*func)(int);
+ } st1;
+ long diff;
+
+ printf("funcptr:\n");
+ func = &num;
+ (*func)(12345);
+ func = num;
+ a = 1;
+ a = 1;
+ func(12345);
+ /* more complicated pointer computation */
+ st1.func = num;
+ st1.func(12346);
+ printf("sizeof1 = %d\n", sizeof(funcptr_test));
+ printf("sizeof2 = %d\n", sizeof funcptr_test);
+ printf("sizeof3 = %d\n", sizeof(&funcptr_test));
+ printf("sizeof4 = %d\n", sizeof &funcptr_test);
+ a = 0;
+ func = num + a;
+ diff = func - num;
+ func(42);
+ (func + diff)(42);
+ (num + a)(43);
+}
+
+void lloptest(long long a, long long b)
+{
+ unsigned long long ua, ub;
+
+ ua = a;
+ ub = b;
+ /* arith */
+ printf("arith: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+ a + b,
+ a - b,
+ a * b);
+
+ if (b != 0) {
+ printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+ a / b,
+ a % b);
+ }
+
+ /* binary */
+ printf("bin: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+ a & b,
+ a | b,
+ a ^ b);
+
+ /* tests */
+ printf("test: %d %d %d %d %d %d\n",
+ a == b,
+ a != b,
+ a < b,
+ a > b,
+ a >= b,
+ a <= b);
+
+ printf("utest: %d %d %d %d %d %d\n",
+ ua == ub,
+ ua != ub,
+ ua < ub,
+ ua > ub,
+ ua >= ub,
+ ua <= ub);
+
+ /* arith2 */
+ a++;
+ b++;
+ printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
+ printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a++, b++);
+ printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", --a, --b);
+ printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
+ b = ub = 0;
+ printf("not: %d %d %d %d\n", !a, !ua, !b, !ub);
+}
+
+void llshift(long long a, int b)
+{
+ printf("shift: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+ (unsigned long long)a >> b,
+ a >> b,
+ a << b);
+ printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+ (unsigned long long)a >> 3,
+ a >> 3,
+ a << 3);
+ printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+ (unsigned long long)a >> 35,
+ a >> 35,
+ a << 35);
+}
+
+void llfloat(void)
+{
+ float fa;
+ double da;
+ LONG_DOUBLE lda;
+ long long la, lb, lc;
+ unsigned long long ula, ulb, ulc;
+ la = 0x12345678;
+ ula = 0x72345678;
+ la = (la << 20) | 0x12345;
+ ula = ula << 33;
+ printf("la=" LONG_LONG_FORMAT " ula=" ULONG_LONG_FORMAT "\n", la, ula);
+
+ fa = la;
+ da = la;
+ lda = la;
+ printf("lltof: %f %f %Lf\n", fa, da, lda);
+
+ la = fa;
+ lb = da;
+ lc = lda;
+ printf("ftoll: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", la, lb, lc);
+
+ fa = ula;
+ da = ula;
+ lda = ula;
+ printf("ulltof: %f %f %Lf\n", fa, da, lda);
+
+ ula = fa;
+ ulb = da;
+ ulc = lda;
+ printf("ftoull: " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT "\n", ula, ulb, ulc);
+}
+
+long long llfunc1(int a)
+{
+ return a * 2;
+}
+
+struct S {
+ int id;
+ char item;
+};
+
+long long int value(struct S *v)
+{
+ return ((long long int)v->item);
+}
+
+long long llfunc2(long long x, long long y, int z)
+{
+ return x * y * z;
+}
+
+void longlong_test(void)
+{
+ long long a, b, c;
+ int ia;
+ unsigned int ua;
+ printf("longlong_test:\n");
+ printf("sizeof(long long) = %d\n", sizeof(long long));
+ ia = -1;
+ ua = -2;
+ a = ia;
+ b = ua;
+ printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
+ printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
+ (long long)1,
+ (long long)-2,
+ 1LL,
+ 0x1234567812345679);
+ a = llfunc1(-3);
+ printf(LONG_LONG_FORMAT "\n", a);
+
+ lloptest(1000, 23);
+ lloptest(0xff, 0x1234);
+ b = 0x72345678 << 10;
+ lloptest(-3, b);
+ llshift(0x123, 5);
+ llshift(-23, 5);
+ b = 0x72345678LL << 10;
+ llshift(b, 47);
+
+ llfloat();
+#if 1
+ b = 0x12345678;
+ a = -1;
+ c = a + b;
+ printf("%Lx\n", c);
+#endif
+
+ /* long long reg spill test */
+ {
+ struct S a;
+
+ a.item = 3;
+ printf("%lld\n", value(&a));
+ }
+ lloptest(0x80000000, 0);
+
+ {
+ long long *p, v, **pp;
+ v = 1;
+ p = &v;
+ p[0]++;
+ printf("another long long spill test : %lld\n", *p);
+ pp = &p;
+
+ v = llfunc2(**pp, **pp, ia);
+ printf("a long long function (arm-)reg-args test : %lld\n", v);
+ }
+ a = 68719476720LL;
+ b = 4294967295LL;
+ printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b);
+
+ printf(LONG_LONG_FORMAT "\n", 0x123456789LLU);
+
+ /* long long pointer deref in argument passing test */
+ a = 0x123;
+ long long *p = &a;
+ llshift(*p, 5);
+}
+
+void manyarg_test(void)
+{
+ LONG_DOUBLE ld = 1234567891234LL;
+ printf("manyarg_test:\n");
+ printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
+ printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+ LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+ 1234567891234LL, 987654321986LL,
+ 42.0, 43.0);
+ printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+ LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
+ ld, 1, 2, 3, 4, 5, 6, 7, 8,
+ 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+ 1234567891234LL, 987654321986LL,
+ 42.0, 43.0);
+ printf("%d %d %d %d %d %d %d %d %Lf\n",
+ 1, 2, 3, 4, 5, 6, 7, 8, ld);
+ printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+ LONG_LONG_FORMAT " " LONG_LONG_FORMAT "%f %f %Lf\n",
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+ 1234567891234LL, 987654321986LL,
+ 42.0, 43.0, ld);
+ printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+ "%Lf " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f %Lf\n",
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+ ld, 1234567891234LL, 987654321986LL,
+ 42.0, 43.0, ld);
+}
+
+void vprintf1(const char *fmt, ...)
+{
+ va_list ap, aq;
+ const char *p;
+ int c, i;
+ double d;
+ long long ll;
+ LONG_DOUBLE ld;
+
+ va_start(aq, fmt);
+ va_copy(ap, aq);
+
+ p = fmt;
+ for(;;) {
+ c = *p;
+ if (c == '\0')
+ break;
+ p++;
+ if (c == '%') {
+ c = *p;
+ switch(c) {
+ case '\0':
+ goto the_end;
+ case 'd':
+ i = va_arg(ap, int);
+ printf("%d", i);
+ break;
+ case 'f':
+ d = va_arg(ap, double);
+ printf("%f", d);
+ break;
+ case 'l':
+ ll = va_arg(ap, long long);
+ printf(LONG_LONG_FORMAT, ll);
+ break;
+ case 'F':
+ ld = va_arg(ap, LONG_DOUBLE);
+ printf("%Lf", ld);
+ break;
+ }
+ p++;
+ } else {
+ putchar(c);
+ }
+ }
+ the_end:
+ va_end(aq);
+ va_end(ap);
+}
+
+struct myspace {
+ short int profile;
+};
+
+void stdarg_for_struct(struct myspace bob, ...)
+{
+ struct myspace george, bill;
+ va_list ap;
+ short int validate;
+
+ va_start(ap, bob);
+ bill = va_arg(ap, struct myspace);
+ george = va_arg(ap, struct myspace);
+ validate = va_arg(ap, int);
+ printf("stdarg_for_struct: %d %d %d %d\n",
+ bob.profile, bill.profile, george.profile, validate);
+ va_end(ap);
+}
+
+void stdarg_for_libc(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+}
+
+void stdarg_test(void)
+{
+ LONG_DOUBLE ld = 1234567891234LL;
+ struct myspace bob;
+
+ vprintf1("%d %d %d\n", 1, 2, 3);
+ vprintf1("%f %d %f\n", 1.0, 2, 3.0);
+ vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0);
+ vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4));
+ vprintf1("%d %f %l %F %d %f %l %F\n",
+ 1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1));
+ vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n",
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8);
+ vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
+ vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+ "%l %l %f %f\n",
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+ 1234567891234LL, 987654321986LL,
+ 42.0, 43.0);
+ vprintf1("%F %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+ "%l %l %f %f\n",
+ ld, 1, 2, 3, 4, 5, 6, 7, 8,
+ 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+ 1234567891234LL, 987654321986LL,
+ 42.0, 43.0);
+ vprintf1("%d %d %d %d %d %d %d %d %F\n",
+ 1, 2, 3, 4, 5, 6, 7, 8, ld);
+ vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+ "%l %l %f %f %F\n",
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+ 1234567891234LL, 987654321986LL,
+ 42.0, 43.0, ld);
+ vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+ "%F %l %l %f %f %F\n",
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+ ld, 1234567891234LL, 987654321986LL,
+ 42.0, 43.0, ld);
+
+ bob.profile = 42;
+ stdarg_for_struct(bob, bob, bob, bob.profile);
+ stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
+}
+
+void whitespace_test(void)
+{
+ char *str;
+
+ #if 1
+ pri\
+ntf("whitspace:\n");
+#endif
+ pf("N=%d\n", 2);
+
+#ifdef CORRECT_CR_HANDLING
+ pri\
+ntf("aaa=%d\n", 3);
+#endif
+
+ pri\
+\
+ntf("min=%d\n", 4);
+
+#ifdef ACCEPT_CR_IN_STRINGS
+ printf("len1=%d\n", strlen("
+"));
+#ifdef CORRECT_CR_HANDLING
+ str = "
+";
+ printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
+#endif
+ printf("len1=%d\n", strlen(" a
+"));
+#endif /* ACCEPT_CR_IN_STRINGS */
+}
+
+int reltab[3] = { 1, 2, 3 };
+
+int *rel1 = &reltab[1];
+int *rel2 = &reltab[2];
+
+#ifdef _WIN64
+void relocation_test(void) {}
+#else
+void getmyaddress(void)
+{
+ printf("in getmyaddress\n");
+}
+
+#ifdef __LP64__
+long __pa_symbol(void)
+{
+ /* This 64bit constant was handled incorrectly, it was used as addend
+ (which can hold 64bit just fine) in connection with a symbol,
+ and TCC generates wrong code for that (displacements are 32bit only).
+ This effectively is "+ 0x80000000", and if addresses of globals
+ are below 2GB the result should be a number without high 32 bits set. */
+ return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL));
+}
+#endif
+
+unsigned long theaddress = (unsigned long)getmyaddress;
+void relocation_test(void)
+{
+ void (*fptr)(void) = (void (*)(void))theaddress;
+ printf("*rel1=%d\n", *rel1);
+ printf("*rel2=%d\n", *rel2);
+ fptr();
+#ifdef __LP64__
+ printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
+#endif
+}
+#endif
+
+void old_style_f(a,b,c)
+ int a, b;
+ double c;
+{
+ printf("a=%d b=%d b=%f\n", a, b, c);
+}
+
+void decl_func1(int cmpfn())
+{
+ printf("cmpfn=%lx\n", (long)cmpfn);
+}
+
+void decl_func2(cmpfn)
+int cmpfn();
+{
+ printf("cmpfn=%lx\n", (long)cmpfn);
+}
+
+void old_style_function(void)
+{
+ old_style_f((void *)1, 2, 3.0);
+ decl_func1(NULL);
+ decl_func2(NULL);
+}
+
+void alloca_test()
+{
+#if defined __i386__ || defined __x86_64__ || defined __arm__
+ char *p = alloca(16);
+ strcpy(p,"123456789012345");
+ printf("alloca: p is %s\n", p);
+ char *demo = "This is only a test.\n";
+ /* Test alloca embedded in a larger expression */
+ printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
+#endif
+}
+
+void *bounds_checking_is_enabled()
+{
+ char ca[10], *cp = ca-1;
+ return (ca != cp + 1) ? cp : NULL;
+}
+
+typedef int constant_negative_array_size_as_compile_time_assertion_idiom[(1 ? 2 : 0) - 1];
+
+void c99_vla_test(int size1, int size2)
+{
+#if defined __i386__ || defined __x86_64__
+ int size = size1 * size2;
+ int tab1[size][2], tab2[10][2];
+ void *tab1_ptr, *tab2_ptr, *bad_ptr;
+
+ /* "size" should have been 'captured' at tab1 declaration,
+ so modifying it should have no effect on VLA behaviour. */
+ size = size-1;
+
+ printf("Test C99 VLA 1 (sizeof): ");
+ printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
+ tab1_ptr = tab1;
+ tab2_ptr = tab2;
+ printf("Test C99 VLA 2 (ptrs subtract): ");
+ printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED");
+ printf("Test C99 VLA 3 (ptr add): ");
+ printf("%s\n", &tab1[5][1] == (tab1_ptr + (5 * 2 + 1) * sizeof(int)) ? "PASSED" : "FAILED");
+ printf("Test C99 VLA 4 (ptr access): ");
+ tab1[size1][1] = 42;
+ printf("%s\n", (*((int *) (tab1_ptr + (size1 * 2 + 1) * sizeof(int))) == 42) ? "PASSED" : "FAILED");
+
+ printf("Test C99 VLA 5 (bounds checking (might be disabled)): ");
+ if (bad_ptr = bounds_checking_is_enabled()) {
+ int *t1 = &tab1[size1 * size2 - 1][3];
+ int *t2 = &tab2[9][3];
+ printf("%s ", bad_ptr == t1 ? "PASSED" : "FAILED");
+ printf("%s ", bad_ptr == t2 ? "PASSED" : "FAILED");
+
+ char*c1 = 1 + sizeof(tab1) + (char*)tab1;
+ char*c2 = 1 + sizeof(tab2) + (char*)tab2;
+ printf("%s ", bad_ptr == c1 ? "PASSED" : "FAILED");
+ printf("%s ", bad_ptr == c2 ? "PASSED" : "FAILED");
+
+ int *i1 = tab1[-1];
+ int *i2 = tab2[-1];
+ printf("%s ", bad_ptr == i1 ? "PASSED" : "FAILED");
+ printf("%s ", bad_ptr == i2 ? "PASSED" : "FAILED");
+
+ int *x1 = tab1[size1 * size2 + 1];
+ int *x2 = tab2[10 + 1];
+ printf("%s ", bad_ptr == x1 ? "PASSED" : "FAILED");
+ printf("%s ", bad_ptr == x2 ? "PASSED" : "FAILED");
+ } else {
+ printf("PASSED PASSED PASSED PASSED PASSED PASSED PASSED PASSED ");
+ }
+ printf("\n");
+#endif
+}
+
+#ifndef __TINYC__
+typedef __SIZE_TYPE__ uintptr_t;
+#endif
+
+void sizeof_test(void)
+{
+ int a;
+ int **ptr;
+
+ printf("sizeof(int) = %d\n", sizeof(int));
+ printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int));
+ printf("sizeof(long) = %d\n", sizeof(long));
+ printf("sizeof(unsigned long) = %d\n", sizeof(unsigned long));
+ printf("sizeof(short) = %d\n", sizeof(short));
+ printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short));
+ printf("sizeof(char) = %d\n", sizeof(char));
+ printf("sizeof(unsigned char) = %d\n", sizeof(unsigned char));
+ printf("sizeof(func) = %d\n", sizeof sizeof_test());
+ a = 1;
+ printf("sizeof(a++) = %d\n", sizeof a++);
+ printf("a=%d\n", a);
+ ptr = NULL;
+ printf("sizeof(**ptr) = %d\n", sizeof (**ptr));
+
+ /* The type of sizeof should be as large as a pointer, actually
+ it should be size_t. */
+ printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int)));
+ uintptr_t t = 1;
+ uintptr_t t2;
+ /* Effectively <<32, but defined also on 32bit machines. */
+ t <<= 16;
+ t <<= 16;
+ t++;
+ /* This checks that sizeof really can be used to manipulate
+ uintptr_t objects, without truncation. */
+ t2 = t & -sizeof(uintptr_t);
+ printf ("%lu %lu\n", t, t2);
+
+ /* some alignof tests */
+ printf("__alignof__(int) = %d\n", __alignof__(int));
+ printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int));
+ printf("__alignof__(short) = %d\n", __alignof__(short));
+ printf("__alignof__(unsigned short) = %d\n", __alignof__(unsigned short));
+ printf("__alignof__(char) = %d\n", __alignof__(char));
+ printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char));
+ printf("__alignof__(func) = %d\n", __alignof__ sizeof_test());
+
+ /* sizes of VLAs need to be evaluated even inside sizeof: */
+ a = 2;
+ printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a]));
+ /* And checking if sizeof compound literal works. Parenthesized: */
+ printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n",
+ sizeof( (struct {int i; int j;}){4,5} ));
+ /* And as direct sizeof argument (as unary expression): */
+ printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
+ sizeof (struct {short i; short j;}){4,5} );
+
+ /* sizeof(x && y) should be sizeof(int), even if constant
+ evaluating is possible. */
+ printf("sizeof(t && 0) = %d\n", sizeof(t && 0));
+ printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
+ printf("sizeof(t || 1) = %d\n", sizeof(t || 1));
+ printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
+}
+
+void typeof_test(void)
+{
+ double a;
+ typeof(a) b;
+ typeof(float) c;
+
+ a = 1.5;
+ b = 2.5;
+ c = 3.5;
+ printf("a=%f b=%f c=%f\n", a, b, c);
+}
+
+
+struct hlist_node;
+struct hlist_head {
+ struct hlist_node *first, *last;
+};
+
+void consume_ulong (unsigned long i)
+{
+ i = 0;
+}
+
+void statement_expr_test(void)
+{
+ int a, i;
+
+ /* Basic stmt expr test */
+ a = 0;
+ for(i=0;i<10;i++) {
+ a += 1 +
+ ( { int b, j;
+ b = 0;
+ for(j=0;j<5;j++)
+ b += j; b;
+ } );
+ }
+ printf("a=%d\n", a);
+
+ /* Test that symbols aren't freed prematurely.
+ With SYM_DEBUG valgrind will show a read from a freed
+ symbol, and tcc will show an (invalid) warning on the initialization
+ of 'ptr' below, if symbols are popped after the stmt expr. */
+ void *v = (void*)39;
+ typeof(({
+ (struct hlist_node *)v;
+ })) x;
+ typeof (x)
+ ptr = (struct hlist_node *)v;
+
+ /* This part used to segfault when symbols were popped prematurely.
+ The symbols for the static local would be overwritten with
+ helper symbols from the pre-processor expansions in between. */
+#define some_attr __attribute__((aligned(1)))
+#define tps(str) ({ \
+ static const char *t some_attr = str; \
+ t; \
+ })
+ printf ("stmtexpr: %s %s\n",
+ tps("somerandomlongstring"),
+ tps("anotherlongstring"));
+
+ /* Test that the three decls of 't' don't interact. */
+ int t = 40;
+ int b = ({ int t = 41; t; });
+ int c = ({ int t = 42; t; });
+
+ /* Test that aggregate return values work. */
+ struct hlist_head h
+ = ({
+ typedef struct hlist_head T;
+ long pre = 48;
+ T t = { (void*)43, (void*)44 };
+ long post = 49;
+ t;
+ });
+ printf ("stmtexpr: %d %d %d\n", t, b, c);
+ printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last);
+
+ /* Test that we can give out addresses of local labels. */
+ consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; }));
+}
+
+void local_label_test(void)
+{
+ int a;
+ goto l1;
+ l2:
+ a = 1 + ({
+ __label__ l1, l2, l3, l4;
+ goto l1;
+ l4:
+ printf("aa1\n");
+ goto l3;
+ l2:
+ printf("aa3\n");
+ goto l4;
+ l1:
+ printf("aa2\n");
+ goto l2;
+ l3:;
+ 1;
+ });
+ printf("a=%d\n", a);
+ return;
+ l4:
+ printf("bb1\n");
+ goto l2;
+ l1:
+ printf("bb2\n");
+ goto l4;
+}
+
+/* inline assembler test */
+#if defined(__i386__) || defined(__x86_64__)
+
+/* from linux kernel */
+static char * strncat1(char * dest,const char * src,size_t count)
+{
+long d0, d1, d2, d3;
+__asm__ __volatile__(
+ "repne\n\t"
+ "scasb\n\t"
+ "dec %1\n\t"
+ "mov %8,%3\n"
+ "1:\tdec %3\n\t"
+ "js 2f\n\t"
+ "lodsb\n\t"
+ "stosb\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n"
+ "2:\txor %2,%2\n\t"
+ "stosb"
+ : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+ : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
+ : "memory");
+return dest;
+}
+
+static char * strncat2(char * dest,const char * src,size_t count)
+{
+long d0, d1, d2, d3;
+__asm__ __volatile__(
+ "repne scasb\n\t" /* one-line repne prefix + string op */
+ "dec %1\n\t"
+ "mov %8,%3\n"
+ "1:\tdec %3\n\t"
+ "js 2f\n\t"
+ "lodsb\n\t"
+ "stosb\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n"
+ "2:\txor %2,%2\n\t"
+ "stosb"
+ : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+ : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
+ : "memory");
+return dest;
+}
+
+static inline void * memcpy1(void * to, const void * from, size_t n)
+{
+long d0, d1, d2;
+__asm__ __volatile__(
+ "rep ; movsl\n\t"
+ "testb $2,%b4\n\t"
+ "je 1f\n\t"
+ "movsw\n"
+ "1:\ttestb $1,%b4\n\t"
+ "je 2f\n\t"
+ "movsb\n"
+ "2:"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+ : "memory");
+return (to);
+}
+
+static inline void * memcpy2(void * to, const void * from, size_t n)
+{
+long d0, d1, d2;
+__asm__ __volatile__(
+ "rep movsl\n\t" /* one-line rep prefix + string op */
+ "testb $2,%b4\n\t"
+ "je 1f\n\t"
+ "movsw\n"
+ "1:\ttestb $1,%b4\n\t"
+ "je 2f\n\t"
+ "movsb\n"
+ "2:"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+ : "memory");
+return (to);
+}
+
+static __inline__ void sigaddset1(unsigned int *set, int _sig)
+{
+ __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
+}
+
+static __inline__ void sigdelset1(unsigned int *set, int _sig)
+{
+ asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags");
+}
+
+static __inline__ __const__ unsigned int swab32(unsigned int x)
+{
+ __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
+ "rorl $16,%0\n\t" /* swap words */
+ "xchgb %b0,%h0" /* swap higher bytes */
+ :"=" "q" (x)
+ : "0" (x));
+ return x;
+}
+
+static __inline__ unsigned long long mul64(unsigned int a, unsigned int b)
+{
+ unsigned long long res;
+#ifdef __x86_64__
+ /* Using the A constraint is wrong (it means rdx:rax, which is too large)
+ but still test the 32bit->64bit mull. */
+ unsigned int resh, resl;
+ __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b));
+ res = ((unsigned long long)resh << 32) | resl;
+#else
+ __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b));
+#endif
+ return res;
+}
+
+static __inline__ unsigned long long inc64(unsigned long long a)
+{
+ unsigned long long res;
+#ifdef __x86_64__
+ /* Using the A constraint is wrong, and increments are tested
+ elsewhere. */
+ res = a + 1;
+#else
+ __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a));
+#endif
+ return res;
+}
+
+struct struct123 {
+ int a;
+ int b;
+};
+struct struct1231 {
+ unsigned long addr;
+};
+
+unsigned long mconstraint_test(struct struct1231 *r)
+{
+ unsigned long ret;
+ unsigned int a[2];
+ a[0] = 0;
+ __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
+ : "=&r" (ret), "=m" (a)
+ : "m" (*(struct struct123 *)r->addr));
+ return ret + a[0];
+}
+
+#ifdef __x86_64__
+int fls64(unsigned long long x)
+{
+ int bitpos = -1;
+ asm("bsrq %1,%q0"
+ : "+r" (bitpos)
+ : "rm" (x));
+ return bitpos + 1;
+}
+#endif
+
+void other_constraints_test(void)
+{
+ unsigned long ret;
+ int var;
+#ifndef _WIN64
+ __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var));
+ printf ("oc1: %d\n", ret == (unsigned long)&var);
+#endif
+}
+
+#ifndef _WIN32
+/* Test global asm blocks playing with aliases. */
+void base_func(void)
+{
+ printf ("asmc: base\n");
+}
+
+extern void override_func1 (void);
+extern void override_func2 (void);
+
+asm(".weak override_func1\n.set override_func1, base_func");
+asm(".set override_func1, base_func");
+asm(".set override_func2, base_func");
+
+void override_func2 (void)
+{
+ printf ("asmc: override2\n");
+}
+
+/* This checks a construct used by the linux kernel to encode
+ references to strings by PC relative references. */
+extern int bug_table[] __attribute__((section("__bug_table")));
+char * get_asm_string (void)
+{
+ extern int some_symbol;
+ asm volatile (".globl some_symbol\n"
+ "jmp .+6\n"
+ "1:\n"
+ "some_symbol: .long 0\n"
+ ".pushsection __bug_table, \"a\"\n"
+ ".globl bug_table\n"
+ "bug_table:\n"
+ /* The first entry (1b-2b) is unused in this test,
+ but we include it to check if cross-section
+ PC-relative references work. */
+ "2:\t.long 1b - 2b, %c0 - 2b\n"
+ ".popsection\n" : : "i" ("A string"));
+ char * str = ((char*)bug_table) + bug_table[1];
+ return str;
+}
+
+/* This checks another constructs with local labels. */
+extern unsigned char alld_stuff[];
+asm(".data\n"
+ ".byte 41\n"
+ "alld_stuff:\n"
+ "661:\n"
+ ".byte 42\n"
+ "662:\n"
+ ".pushsection .data.ignore\n"
+ ".long 661b - .\n" /* This reference to 661 generates an external sym
+ which shouldn't somehow overwrite the offset that's
+ already determined for it. */
+ ".popsection\n"
+ ".byte 662b - 661b\n" /* So that this value is undeniably 1. */);
+
+void asm_local_label_diff (void)
+{
+ printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);
+}
+
+/* This checks that static local variables are available from assembler. */
+void asm_local_statics (void)
+{
+ static int localint = 41;
+ asm("incl %0" : "+m" (localint));
+ printf ("asm_local_statics: %d\n", localint);
+}
+#endif
+
+static
+unsigned int set;
+
+void fancy_copy (unsigned *in, unsigned *out)
+{
+ asm volatile ("" : "=r" (*out) : "0" (*in));
+}
+
+void fancy_copy2 (unsigned *in, unsigned *out)
+{
+ asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
+}
+
+#if defined __x86_64__ && !defined _WIN64
+void clobber_r12(void)
+{
+ asm volatile("mov $1, %%r12" ::: "r12");
+}
+#endif
+
+void test_high_clobbers(void)
+{
+#if defined __x86_64__ && !defined _WIN64
+ register long val asm("r12");
+ long val2;
+ /* This tests if asm clobbers correctly save/restore callee saved
+ registers if they are clobbered and if it's the high 8 x86-64
+ registers. This is fragile for GCC as the constraints do not
+ correctly capture the data flow, but good enough for us. */
+ asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory");
+ clobber_r12();
+ asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory");
+ printf("asmhc: 0x%x\n", val2);
+#endif
+}
+
+static long cpu_number;
+void trace_console(long len, long len2)
+{
+#ifdef __x86_64__
+ /* This generated invalid code when the emission of the switch
+ table isn't disabled. The asms are necessary to show the bug,
+ normal statements don't work (they need to generate some code
+ even under nocode_wanted, which normal statements don't do,
+ but asms do). Also at least these number of cases is necessary
+ to generate enough "random" bytes. They ultimately are enough
+ to create invalid instruction patterns to which the first
+ skip-to-decision-table jump jumps. If decision table emission
+ is disabled all of this is no problem.
+
+ It also is necessary that the switches are in a statement expression
+ (which has the property of not being enterable from outside. no
+ matter what). */
+ if (0
+ &&
+ ({
+ long pscr_ret__;
+ switch(len) {
+ case 4:
+ {
+ long pfo_ret__;
+ switch (len2) {
+ case 8: printf("bla"); pfo_ret__ = 42; break;
+ }
+ pscr_ret__ = pfo_ret__;
+ }
+ break;
+ case 8:
+ {
+ long pfo_ret__;
+ switch (len2) {
+ case 1:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
+ case 2:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
+ case 4:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
+ case 8:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
+ default: printf("impossible\n");
+ }
+ pscr_ret__ = pfo_ret__;
+ };
+ break;
+ }
+ pscr_ret__;
+ }))
+ {
+ printf("huh?\n");
+ }
+#endif
+}
+
+void test_asm_dead_code(void)
+{
+ long rdi;
+ /* Try to make sure that xdi contains a zero, and hence will
+ lead to a segfault if the next asm is evaluated without
+ arguments being set up. */
+ asm volatile ("" : "=D" (rdi) : "0" (0));
+ (void)sizeof (({
+ int var;
+ /* This shouldn't trigger a segfault, either the argument
+ registers need to be set up and the asm emitted despite
+ this being in an unevaluated context, or both the argument
+ setup _and_ the asm emission need to be suppressed. The latter
+ is better. Disabling asm code gen when suppression is on
+ also fixes the above trace_console bug, but that came earlier
+ than asm suppression. */
+ asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory");
+ var;
+ }));
+}
+
+void test_asm_call(void)
+{
+#if defined __x86_64__ && !defined _WIN64
+ static char str[] = "PATH";
+ char *s;
+ /* This tests if a reference to an undefined symbol from an asm
+ block, which isn't otherwise referenced in this file, is correctly
+ regarded as global symbol, so that it's resolved by other object files
+ or libraries. We chose getenv here, which isn't used anywhere else
+ in this file. (If we used e.g. printf, which is used we already
+ would have a global symbol entry, not triggering the bug which is
+ tested here). */
+ /* two pushes so stack remains aligned */
+ asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;"
+#if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__))
+ "call getenv@plt;"
+#else
+ "call getenv;"
+#endif
+ "pop %%rdi; pop %%rdi"
+ : "=a" (s) : "r" (str));
+ printf("asmd: %s\n", s);
+#endif
+}
+
+#if defined __x86_64__
+# define RX "(%rip)"
+#else
+# define RX
+#endif
+
+void asm_dot_test(void)
+{
+ int x;
+ for (x = 1;; ++x) {
+ int r = x;
+ switch (x) {
+ case 1:
+ asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0");
+ case 2:
+ asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0");
+ case 3:
+ asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4");
+ asm(".text; mov X"RX",%eax; jmp p0");
+ case 4:
+ asm(".data; X=.; .int 789; Y=.; .int 999");
+ asm(".text; mov X"RX",%eax; X=Y; jmp p0");
+ case 0:
+ asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break;
+ }
+ if (r == x)
+ break;
+ printf("asm_dot_test %d: %d\n", x, r);
+ }
+}
+
+void asm_test(void)
+{
+ char buf[128];
+ unsigned int val, val2;
+ struct struct123 s1;
+ struct struct1231 s2 = { (unsigned long)&s1 };
+ /* Hide the outer base_func, but check later that the inline
+ asm block gets the outer one. */
+ int base_func = 42;
+ void override_func3 (void);
+ unsigned long asmret;
+#ifdef BOOL_ISOC99
+ _Bool somebool;
+#endif
+ register int regvar asm("%esi");
+
+ printf("inline asm:\n");
+
+ // parse 0x1E-1 as 3 tokens in asm mode
+ asm volatile ("mov $0x1E-1,%eax");
+
+ /* test the no operand case */
+ asm volatile ("xorl %eax, %eax");
+
+ memcpy1(buf, "hello", 6);
+ strncat1(buf, " worldXXXXX", 3);
+ printf("%s\n", buf);
+
+ memcpy2(buf, "hello", 6);
+ strncat2(buf, " worldXXXXX", 3);
+ printf("%s\n", buf);
+
+ /* 'A' constraint test */
+ printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234));
+ printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
+
+ s1.a = 42;
+ s1.b = 43;
+ printf("mconstraint: %d", mconstraint_test(&s2));
+ printf(" %d %d\n", s1.a, s1.b);
+ other_constraints_test();
+ set = 0xff;
+ sigdelset1(&set, 2);
+ sigaddset1(&set, 16);
+ /* NOTE: we test here if C labels are correctly restored after the
+ asm statement */
+ goto label1;
+ label2:
+ __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
+ printf("set=0x%x\n", set);
+ val = 0x01020304;
+ printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val));
+#ifndef _WIN32
+ override_func1();
+ override_func2();
+ /* The base_func ref from the following inline asm should find
+ the global one, not the local decl from this function. */
+ asm volatile(".weak override_func3\n.set override_func3, base_func");
+ override_func3();
+ printf("asmstr: %s\n", get_asm_string());
+ asm_local_label_diff();
+ asm_local_statics();
+#endif
+ /* Check that we can also load structs of appropriate layout
+ into registers. */
+ asm volatile("" : "=r" (asmret) : "0"(s2));
+ if (asmret != s2.addr)
+ printf("asmstr: failed\n");
+#ifdef BOOL_ISOC99
+ /* Check that the typesize correctly sets the register size to
+ 8 bit. */
+ asm volatile("cmp %1,%2; sete %0" : "=a"(somebool) : "r"(1), "r"(2));
+ if (!somebool)
+ printf("asmbool: failed\n");
+#endif
+ val = 43;
+ fancy_copy (&val, &val2);
+ printf ("fancycpy(%d)=%d\n", val, val2);
+ val = 44;
+ fancy_copy2 (&val, &val2);
+ printf ("fancycpy2(%d)=%d\n", val, val2);
+ asm volatile ("mov $0x4243, %%esi" : "=r" (regvar));
+ printf ("regvar=%x\n", regvar);
+ test_high_clobbers();
+ trace_console(8, 8);
+ test_asm_dead_code();
+ test_asm_call();
+ asm_dot_test();
+ return;
+ label1:
+ goto label2;
+}
+
+#else
+
+void asm_test(void)
+{
+}
+
+#endif
+
+#define COMPAT_TYPE(type1, type2) \
+{\
+ printf("__builtin_types_compatible_p(%s, %s) = %d\n", #type1, #type2, \
+ __builtin_types_compatible_p (type1, type2));\
+}
+
+int constant_p_var;
+
+void builtin_test(void)
+{
+ short s;
+ int i;
+ long long ll;
+#if GCC_MAJOR >= 3
+ COMPAT_TYPE(int, int);
+ COMPAT_TYPE(int, unsigned int);
+ COMPAT_TYPE(int, char);
+ COMPAT_TYPE(int, const int);
+ COMPAT_TYPE(int, volatile int);
+ COMPAT_TYPE(int *, int *);
+ COMPAT_TYPE(int *, void *);
+ COMPAT_TYPE(int *, const int *);
+ COMPAT_TYPE(char *, unsigned char *);
+ COMPAT_TYPE(char *, signed char *);
+ COMPAT_TYPE(char *, char *);
+/* space is needed because tcc preprocessor introduces a space between each token */
+ COMPAT_TYPE(char * *, void *);
+#endif
+ printf("res = %d\n", __builtin_constant_p(1));
+ printf("res = %d\n", __builtin_constant_p(1 + 2));
+ printf("res = %d\n", __builtin_constant_p(&constant_p_var));
+ printf("res = %d\n", __builtin_constant_p(constant_p_var));
+ printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var));
+ s = 1;
+ ll = 2;
+ i = __builtin_choose_expr (1 != 0, ll, s);
+ printf("bce: %d\n", i);
+ i = __builtin_choose_expr (1 != 1, ll, s);
+ printf("bce: %d\n", i);
+ i = sizeof (__builtin_choose_expr (1, ll, s));
+ printf("bce: %d\n", i);
+ i = sizeof (__builtin_choose_expr (0, ll, s));
+ printf("bce: %d\n", i);
+
+ //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
+}
+
+#ifndef _WIN32
+extern int __attribute__((weak)) weak_f1(void);
+extern int __attribute__((weak)) weak_f2(void);
+extern int weak_f3(void);
+extern int __attribute__((weak)) weak_v1;
+extern int __attribute__((weak)) weak_v2;
+extern int weak_v3;
+
+extern int (*weak_fpa)() __attribute__((weak));
+extern int __attribute__((weak)) (*weak_fpb)();
+extern __attribute__((weak)) int (*weak_fpc)();
+
+extern int weak_asm_f1(void) asm("weak_asm_f1x") __attribute((weak));
+extern int __attribute((weak)) weak_asm_f2(void) asm("weak_asm_f2x") ;
+extern int __attribute((weak)) weak_asm_f3(void) asm("weak_asm_f3x") __attribute((weak));
+extern int weak_asm_v1 asm("weak_asm_v1x") __attribute((weak));
+extern int __attribute((weak)) weak_asm_v2 asm("weak_asm_v2x") ;
+extern int __attribute((weak)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak));
+
+static const size_t dummy = 0;
+extern __typeof(dummy) weak_dummy1 __attribute__((weak, alias("dummy")));
+extern __typeof(dummy) __attribute__((weak, alias("dummy"))) weak_dummy2;
+extern __attribute__((weak, alias("dummy"))) __typeof(dummy) weak_dummy3;
+
+int some_lib_func(void);
+int dummy_impl_of_slf(void) { return 444; }
+int some_lib_func(void) __attribute__((weak, alias("dummy_impl_of_slf")));
+
+int weak_toolate() __attribute__((weak));
+int weak_toolate() { return 0; }
+
+void __attribute__((weak)) weak_test(void)
+{
+ printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123);
+ printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123);
+ printf("weak_f3=%d\n", weak_f3 ? weak_f3() : 123);
+ printf("weak_v1=%d\n",&weak_v1 ? weak_v1 : 123);
+ printf("weak_v2=%d\n",&weak_v2 ? weak_v2 : 123);
+ printf("weak_v3=%d\n",&weak_v3 ? weak_v3 : 123);
+
+ printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
+ printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
+ printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
+
+ printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
+ printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
+ printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);
+ printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL);
+ printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL);
+ printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL);
+ printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0);
+}
+
+int __attribute__((weak)) weak_f2() { return 222; }
+int __attribute__((weak)) weak_f3() { return 333; }
+int __attribute__((weak)) weak_v2 = 222;
+int __attribute__((weak)) weak_v3 = 333;
+#endif
+
+void const_func(const int a)
+{
+}
+
+void const_warn_test(void)
+{
+ const_func(1);
+}
+
+struct condstruct {
+ int i;
+};
+
+int getme (struct condstruct *s, int i)
+{
+ int i1 = (i == 0 ? 0 : s)->i;
+ int i2 = (i == 0 ? s : 0)->i;
+ int i3 = (i == 0 ? (void*)0 : s)->i;
+ int i4 = (i == 0 ? s : (void*)0)->i;
+ return i1 + i2 + i3 + i4;
+}
+
+struct global_data
+{
+ int a[40];
+ int *b[40];
+};
+
+struct global_data global_data;
+
+int global_data_getstuff (int *, int);
+
+void global_data_callit (int i)
+{
+ *global_data.b[i] = global_data_getstuff (global_data.b[i], 1);
+}
+
+int global_data_getstuff (int *p, int i)
+{
+ return *p + i;
+}
+
+void global_data_test (void)
+{
+ global_data.a[0] = 42;
+ global_data.b[0] = &global_data.a[0];
+ global_data_callit (0);
+ printf ("%d\n", global_data.a[0]);
+}
+
+struct cmpcmpS
+{
+ unsigned char fill : 3;
+ unsigned char b1 : 1;
+ unsigned char b2 : 1;
+ unsigned char fill2 : 3;
+};
+
+int glob1, glob2, glob3;
+
+void compare_comparisons (struct cmpcmpS *s)
+{
+ if (s->b1 != (glob1 == glob2)
+ || (s->b2 != (glob1 == glob3)))
+ printf ("comparing comparisons broken\n");
+}
+
+void cmp_comparison_test(void)
+{
+ struct cmpcmpS s;
+ s.b1 = 1;
+ glob1 = 42; glob2 = 42;
+ s.b2 = 0;
+ glob3 = 43;
+ compare_comparisons (&s);
+}
+
+int fcompare (double a, double b, int code)
+{
+ switch (code) {
+ case 0: return a == b;
+ case 1: return a != b;
+ case 2: return a < b;
+ case 3: return a >= b;
+ case 4: return a > b;
+ case 5: return a <= b;
+ }
+}
+
+void math_cmp_test(void)
+{
+ double nan = 0.0/0.0;
+ double one = 1.0;
+ double two = 2.0;
+ int comp = 0;
+#define bug(a,b,op,iop,part) printf("Test broken: %s %s %s %s %d\n", #a, #b, #op, #iop, part)
+
+ /* This asserts that "a op b" is _not_ true, but "a iop b" is true.
+ And it does this in various ways so that all code generation paths
+ are checked (generating inverted tests, or non-inverted tests, or
+ producing a 0/1 value without jumps (that's done in the fcompare
+ function). */
+#define FCMP(a,b,op,iop,code) \
+ if (fcompare (a,b,code)) \
+ bug (a,b,op,iop,1); \
+ if (a op b) \
+ bug (a,b,op,iop,2); \
+ if (a iop b) \
+ ; \
+ else \
+ bug (a,b,op,iop,3); \
+ if ((a op b) || comp) \
+ bug (a,b,op,iop,4); \
+ if ((a iop b) || comp) \
+ ; \
+ else \
+ bug (a,b,op,iop,5);
+
+ /* Equality tests. */
+ FCMP(nan, nan, ==, !=, 0);
+ FCMP(one, two, ==, !=, 0);
+ FCMP(one, one, !=, ==, 1);
+ /* Non-equality is a bit special. */
+ if (!fcompare (nan, nan, 1))
+ bug (nan, nan, !=, ==, 6);
+
+ /* Relational tests on numbers. */
+ FCMP(two, one, <, >=, 2);
+ FCMP(one, two, >=, <, 3);
+ FCMP(one, two, >, <=, 4);
+ FCMP(two, one, <=, >, 5);
+
+ /* Relational tests on NaNs. Note that the inverse op here is
+ always !=, there's no operator in C that is equivalent to !(a < b),
+ when NaNs are involved, same for the other relational ops. */
+ FCMP(nan, nan, <, !=, 2);
+ FCMP(nan, nan, >=, !=, 3);
+ FCMP(nan, nan, >, !=, 4);
+ FCMP(nan, nan, <=, !=, 5);
+}
+
+double get100 () { return 100.0; }
+
+void callsave_test(void)
+{
+#if defined __i386__ || defined __x86_64__ || defined __arm__
+ int i, s; double *d; double t;
+ s = sizeof (double);
+ printf ("callsavetest: %d\n", s);
+ d = alloca (sizeof(double));
+ d[0] = 10.0;
+ /* x86-64 had a bug were the next call to get100 would evict
+ the lvalue &d[0] as VT_LLOCAL, and the reload would be done
+ in int type, not pointer type. When alloca returns a pointer
+ with the high 32 bit set (which is likely on x86-64) the access
+ generates a segfault. */
+ i = d[0] > get100 ();
+ printf ("%d\n", i);
+#endif
+}
+
+
+void bfa3(ptrdiff_t str_offset)
+{
+ printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset);
+}
+void bfa2(ptrdiff_t str_offset)
+{
+ printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset);
+ bfa3(str_offset);
+}
+void bfa1(ptrdiff_t str_offset)
+{
+ printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
+ bfa2(str_offset);
+}
+
+void builtin_frame_address_test(void)
+{
+/* builtin_frame_address fails on ARM with gcc which make test3 fail */
+#ifndef __arm__
+ char str[] = "__builtin_frame_address";
+ char *fp0 = __builtin_frame_address(0);
+
+ printf("str: %s\n", str);
+ bfa1(str-fp0);
+#endif
+}
+
+char via_volatile (char i)
+{
+ char volatile vi;
+ vi = i;
+ return vi;
+}
+
+struct __attribute__((__packed__)) Spacked {
+ char a;
+ short b;
+ int c;
+};
+struct Spacked spacked;
+typedef struct __attribute__((__packed__)) {
+ char a;
+ short b;
+ int c;
+} Spacked2;
+Spacked2 spacked2;
+typedef struct Spacked3_s {
+ char a;
+ short b;
+ int c;
+} __attribute__((__packed__)) Spacked3;
+Spacked3 spacked3;
+struct gate_struct64 {
+ unsigned short offset_low;
+ unsigned short segment;
+ unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
+ unsigned short offset_middle;
+ unsigned offset_high;
+ unsigned zero1;
+} __attribute__((packed));
+typedef struct gate_struct64 gate_desc;
+gate_desc a_gate_desc;
+void attrib_test(void)
+{
+#ifndef _WIN32
+ printf("attr: %d %d %d %d\n", sizeof(struct Spacked),
+ sizeof(spacked), sizeof(Spacked2), sizeof(spacked2));
+ printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3));
+ printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc));
+#endif
+}
+extern __attribute__((__unused__)) char * __attribute__((__unused__)) *
+strange_attrib_placement (void);
+
+void * __attribute__((__unused__)) get_void_ptr (void *a)
+{
+ return a;
+}
+
+/* This part checks for a bug in TOK_GET (used for inline expansion),
+ where the large long long constant left the the high bits set for
+ the integer constant token. */
+static inline
+int __get_order(unsigned long long size)
+{
+ int order;
+ size -= 0xffff880000000000ULL; // this const left high bits set in the token
+ {
+ struct S { int i : 1; } s; // constructed for this '1'
+ }
+ order = size;
+ return order;
+}
+
+/* This just forces the above inline function to be actually emitted. */
+int force_get_order(unsigned long s)
+{
+ return __get_order(s);
+}
diff --git a/tests/tcctest.h b/tests/tcctest.h
new file mode 100644
index 0000000..b301c7c
--- /dev/null
+++ b/tests/tcctest.h
@@ -0,0 +1,9 @@
+static inline const char *get_basefile_from_header(void)
+{
+ return __BASE_FILE__;
+}
+
+static inline const char *get_file_from_header(void)
+{
+ return __FILE__;
+}
diff --git a/tests/testfp.c b/tests/testfp.c
new file mode 100644
index 0000000..63342b4
--- /dev/null
+++ b/tests/testfp.c
@@ -0,0 +1,510 @@
+/*
+ * Test 128-bit floating-point arithmetic on arm64:
+ * build with two different compilers and compare the output.
+ *
+ * Copyright (c) 2015 Edmund Grimley Evans
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved. This file is offered as-is,
+ * without any warranty.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define check(x) ((x) ? (void)0 : check_fail(#x, __FILE__, __LINE__))
+
+void check_fail(const char *assertion, const char *file, unsigned int line)
+{
+ printf("%s:%d: Check (%s) failed.", file, line, assertion);
+ exit(1);
+}
+
+typedef struct {
+ unsigned long long x0, x1;
+} u128_t;
+
+float copy_fi(uint32_t x)
+{
+ float f;
+ memcpy(&f, &x, 4);
+ return f;
+}
+
+double copy_di(uint64_t x)
+{
+ double f;
+ memcpy(&f, &x, 8);
+ return f;
+}
+
+long double copy_ldi(u128_t x)
+{
+ long double f;
+ memcpy(&f, &x, 16);
+ return f;
+}
+
+uint32_t copy_if(float f)
+{
+ uint32_t x;
+ memcpy(&x, &f, 4);
+ return x;
+}
+
+uint64_t copy_id(double f)
+{
+ uint64_t x;
+ memcpy(&x, &f, 8);
+ return x;
+}
+
+u128_t copy_ild(long double f)
+{
+ u128_t x;
+ memcpy(&x, &f, 16);
+ return x;
+}
+
+long double make(int sgn, int exp, uint64_t high, uint64_t low)
+{
+ u128_t x = { low,
+ (0x0000ffffffffffff & high) |
+ (0x7fff000000000000 & (uint64_t)exp << 48) |
+ (0x8000000000000000 & (uint64_t)sgn << 63) };
+ return copy_ldi(x);
+}
+
+void cmp(long double a, long double b)
+{
+ u128_t ax = copy_ild(a);
+ u128_t bx = copy_ild(b);
+ int eq = (a == b);
+ int ne = (a != b);
+ int lt = (a < b);
+ int le = (a <= b);
+ int gt = (a > b);
+ int ge = (a >= b);
+
+ check(eq == 0 || eq == 1);
+ check(lt == 0 || lt == 1);
+ check(gt == 0 || gt == 1);
+ check(ne == !eq && le == (lt | eq) && ge == (gt | eq));
+ check(eq + lt + gt < 2);
+
+ printf("cmp %016llx%016llx %016llx%016llx %d %d %d\n",
+ ax.x1, ax.x0, bx.x1, bx.x0, lt, eq, gt);
+}
+
+void cmps(void)
+{
+ int i, j;
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 2; j++)
+ cmp(make(i, 0, 0, 0), make(j, 0, 0, 0));
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 64; j++) {
+ long double f1 = make(i, 32767, (uint64_t)1 << j, 0);
+ long double f2 = make(i, 32767, 0, (uint64_t)1 << j);
+ cmp(f1, 0);
+ cmp(f2, 0);
+ cmp(0, f1);
+ cmp(0, f2);
+ }
+ }
+
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 6; j++)
+ cmp(make(i & 1, i >> 1, 0, 0),
+ make(j & 1, j >> 1, 0, 0));
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ int a, b;
+ for (a = 0; a < 2; a++) {
+ for (b = 0; b < 2; b++) {
+ cmp(make(i, j, a, b), make(i, j, 0, 0));
+ cmp(make(i, j, 0, 0), make(i, j, a, b));
+ }
+ }
+ }
+ }
+}
+
+void xop(const char *name, long double a, long double b, long double c)
+{
+ u128_t ax = copy_ild(a);
+ u128_t bx = copy_ild(b);
+ u128_t cx = copy_ild(c);
+ printf("%s %016llx%016llx %016llx%016llx %016llx%016llx\n",
+ name, ax.x1, ax.x0, bx.x1, bx.x0, cx.x1, cx.x0);
+}
+
+void fadd(long double a, long double b)
+{
+ xop("add", a, b, a + b);
+}
+
+void fsub(long double a, long double b)
+{
+ xop("sub", a, b, a - b);
+}
+
+void fmul(long double a, long double b)
+{
+ xop("mul", a, b, a * b);
+}
+
+void fdiv(long double a, long double b)
+{
+ xop("div", a, b, a / b);
+}
+
+void nanz(void)
+{
+ // Check NaNs:
+ {
+ long double x[7];
+ int i, j, n = 0;
+ x[n++] = make(0, 32000, 0x95132b76effc, 0xd79035214b4f8d53);
+ x[n++] = make(1, 32001, 0xbe71d7a51587, 0x30601c6815d6c3ac);
+ x[n++] = make(0, 32767, 0, 1);
+ x[n++] = make(0, 32767, (uint64_t)1 << 46, 0);
+ x[n++] = make(1, 32767, (uint64_t)1 << 47, 0);
+ x[n++] = make(1, 32767, 0x7596c7099ad5, 0xe25fed2c58f73fc9);
+ x[n++] = make(0, 32767, 0x835d143360f9, 0x5e315efb35630666);
+ check(n == sizeof(x) / sizeof(*x));
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < n; j++) {
+ fadd(x[i], x[j]);
+ fsub(x[i], x[j]);
+ fmul(x[i], x[j]);
+ fdiv(x[i], x[j]);
+ }
+ }
+ }
+
+ // Check infinities and zeroes:
+ {
+ long double x[6];
+ int i, j, n = 0;
+ x[n++] = make(1, 32000, 0x62acda85f700, 0x47b6c9f35edc4044);
+ x[n++] = make(0, 32001, 0x94b7abf55af7, 0x9f425fe354428e19);
+ x[n++] = make(0, 32767, 0, 0);
+ x[n++] = make(1, 32767, 0, 0);
+ x[n++] = make(0, 0, 0, 0);
+ x[n++] = make(1, 0, 0, 0);
+ check(n == sizeof(x) / sizeof(*x));
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < n; j++) {
+ fadd(x[i], x[j]);
+ fsub(x[i], x[j]);
+ fmul(x[i], x[j]);
+ fdiv(x[i], x[j]);
+ }
+ }
+ }
+}
+
+void adds(void)
+{
+ // Check shifting and add/sub:
+ {
+ int i;
+ for (i = -130; i <= 130; i++) {
+ int s1 = (uint32_t)i % 3 < 1;
+ int s2 = (uint32_t)i % 5 < 2;
+ fadd(make(s1, 16384 , 0x502c065e4f71a65d, 0xd2f9bdb031f4f031),
+ make(s2, 16384 + i, 0xae267395a9bc1033, 0xb56b5800da1ba448));
+ }
+ }
+
+ // Check normalisation:
+ {
+ uint64_t a0 = 0xc6bab0a6afbef5ed;
+ uint64_t a1 = 0x4f84136c4a2e9b52;
+ int ee[] = { 0, 1, 10000 };
+ int e, i;
+ for (e = 0; e < sizeof(ee) / sizeof(*ee); e++) {
+ int exp = ee[e];
+ fsub(make(0, exp, a1, a0), make(0, 0, 0, 0));
+ for (i = 63; i >= 0; i--)
+ fsub(make(0, exp, a1 | (uint64_t)1 << i >> 1, a0),
+ make(0, exp, a1 >> i << i, 0));
+ for (i = 63; i >=0; i--)
+ fsub(make(0, exp, a1, a0 | (uint64_t)1 << i >> 1),
+ make(0, exp, a1, a0 >> i << i));
+ }
+ }
+
+ // Carry/overflow from rounding:
+ {
+ fadd(make(0, 114, -1, -1), make(0, 1, 0, 0));
+ fadd(make(0, 32766, -1, -1), make(0, 32653, 0, 0));
+ fsub(make(1, 32766, -1, -1), make(0, 32653, 0, 0));
+ }
+}
+
+void muls(void)
+{
+ int i, j;
+
+ {
+ long double max = make(0, 32766, -1, -1);
+ long double min = make(0, 0, 0, 1);
+ fmul(max, max);
+ fmul(max, min);
+ fmul(min, min);
+ }
+
+ for (i = 117; i > 0; i--)
+ fmul(make(0, 16268, 0x643dcea76edc, 0xe0877a598403627a),
+ make(i & 1, i, 0, 0));
+
+ fmul(make(0, 16383, -1, -3), make(0, 16383, 0, 1));
+ // Round to next exponent:
+ fmul(make(0, 16383, -1, -2), make(0, 16383, 0, 1));
+ // Round from subnormal to normal:
+ fmul(make(0, 1, -1, -1), make(0, 16382, 0, 0));
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 112; j++)
+ fmul(make(0, 16383, (uint64_t)1 << i, 0),
+ make(0, 16383,
+ j < 64 ? 0 : (uint64_t)1 << (j - 64),
+ j < 64 ? (uint64_t)1 << j : 0));
+}
+
+void divs(void)
+{
+ int i;
+
+ {
+ long double max = make(0, 32766, -1, -1);
+ long double min = make(0, 0, 0, 1);
+ fdiv(max, max);
+ fdiv(max, min);
+ fdiv(min, max);
+ fdiv(min, min);
+ }
+
+ for (i = 0; i < 64; i++)
+ fdiv(make(0, 16383, -1, -1), make(0, 16383, -1, -(uint64_t)1 << i));
+ for (i = 0; i < 48; i++)
+ fdiv(make(0, 16383, -1, -1), make(0, 16383, -(uint64_t)1 << i, 0));
+}
+
+void cvtlsw(int32_t a)
+{
+ long double f = a;
+ u128_t x = copy_ild(f);
+ printf("cvtlsw %08lx %016llx%016llx\n", (long)(uint32_t)a, x.x1, x.x0);
+}
+
+void cvtlsx(int64_t a)
+{
+ long double f = a;
+ u128_t x = copy_ild(f);
+ printf("cvtlsx %016llx %016llx%016llx\n",
+ (long long)(uint64_t)a, x.x1, x.x0);
+}
+
+void cvtluw(uint32_t a)
+{
+ long double f = a;
+ u128_t x = copy_ild(f);
+ printf("cvtluw %08lx %016llx%016llx\n", (long)a, x.x1, x.x0);
+}
+
+void cvtlux(uint64_t a)
+{
+ long double f = a;
+ u128_t x = copy_ild(f);
+ printf("cvtlux %016llx %016llx%016llx\n", (long long)a, x.x1, x.x0);
+}
+
+void cvtil(long double a)
+{
+ u128_t x = copy_ild(a);
+ int32_t b1 = a;
+ int64_t b2 = a;
+ uint32_t b3 = a;
+ uint64_t b4 = a;
+ printf("cvtswl %016llx%016llx %08lx\n",
+ x.x1, x.x0, (long)(uint32_t)b1);
+ printf("cvtsxl %016llx%016llx %016llx\n",
+ x.x1, x.x0, (long long)(uint64_t)b2);
+ printf("cvtuwl %016llx%016llx %08lx\n",
+ x.x1, x.x0, (long)b3);
+ printf("cvtuxl %016llx%016llx %016llx\n",
+ x.x1, x.x0, (long long)b4);
+}
+
+void cvtlf(float a)
+{
+ uint32_t ax = copy_if(a);
+ long double b = a;
+ u128_t bx = copy_ild(b);
+ printf("cvtlf %08lx %016llx%016llx\n", (long)ax, bx.x1, bx.x0);
+}
+
+void cvtld(double a)
+{
+ uint64_t ax = copy_id(a);
+ long double b = a;
+ u128_t bx = copy_ild(b);
+ printf("cvtld %016llx %016llx%016llx\n", (long long)ax, bx.x1, bx.x0);
+}
+
+void cvtfl(long double a)
+{
+ u128_t ax = copy_ild(a);
+ float b = a;
+ uint32_t bx = copy_if(b);
+ printf("cvtfl %016llx%016llx %08lx\n", ax.x1, ax.x0, (long)bx);
+}
+
+void cvtdl(long double a)
+{
+ u128_t ax = copy_ild(a);
+ double b = a;
+ uint64_t bx = copy_id(b);
+ printf("cvtdl %016llx%016llx %016llx\n", ax.x1, ax.x0, (long long)bx);
+}
+
+void cvts(void)
+{
+ int i, j;
+
+ {
+ uint32_t x = 0xad040c5b;
+ cvtlsw(0);
+ for (i = 0; i < 31; i++)
+ cvtlsw(x >> (31 - i));
+ for (i = 0; i < 31; i++)
+ cvtlsw(-(x >> (31 - i)));
+ cvtlsw(0x80000000);
+ }
+ {
+ uint64_t x = 0xb630a248cad9afd2;
+ cvtlsx(0);
+ for (i = 0; i < 63; i++)
+ cvtlsx(x >> (63 - i));
+ for (i = 0; i < 63; i++)
+ cvtlsx(-(x >> (63 - i)));
+ cvtlsx(0x8000000000000000);
+ }
+ {
+ uint32_t x = 0xad040c5b;
+ cvtluw(0);
+ for (i = 0; i < 32; i++)
+ cvtluw(x >> (31 - i));
+ }
+ {
+ uint64_t x = 0xb630a248cad9afd2;
+ cvtlux(0);
+ for (i = 0; i < 64; i++)
+ cvtlux(x >> (63 - i));
+ }
+
+ for (i = 0; i < 2; i++) {
+ cvtil(make(i, 32767, 0, 1));
+ cvtil(make(i, 32767, (uint64_t)1 << 47, 0));
+ cvtil(make(i, 32767, 123, 456));
+ cvtil(make(i, 32767, 0, 0));
+ cvtil(make(i, 16382, -1, -1));
+ cvtil(make(i, 16383, -1, -1));
+ cvtil(make(i, 16384, 0x7fffffffffff, -1));
+ cvtil(make(i, 16384, 0x800000000000, 0));
+ for (j = 0; j < 68; j++)
+ cvtil(make(i, 16381 + j, 0xd4822c0a10ec, 0x1fe2f8b2669f5c9d));
+ }
+
+ cvtlf(copy_fi(0x00000000));
+ cvtlf(copy_fi(0x456789ab));
+ cvtlf(copy_fi(0x7f800000));
+ cvtlf(copy_fi(0x7f923456));
+ cvtlf(copy_fi(0x7fdbcdef));
+ cvtlf(copy_fi(0x80000000));
+ cvtlf(copy_fi(0xabcdef12));
+ cvtlf(copy_fi(0xff800000));
+ cvtlf(copy_fi(0xff923456));
+ cvtlf(copy_fi(0xffdbcdef));
+
+ cvtld(copy_di(0x0000000000000000));
+ cvtld(copy_di(0x456789abcdef0123));
+ cvtld(copy_di(0x7ff0000000000000));
+ cvtld(copy_di(0x7ff123456789abcd));
+ cvtld(copy_di(0x7ffabcdef1234567));
+ cvtld(copy_di(0x8000000000000000));
+ cvtld(copy_di(0xcdef123456789abc));
+ cvtld(copy_di(0xfff0000000000000));
+ cvtld(copy_di(0xfff123456789abcd));
+ cvtld(copy_di(0xfffabcdef1234567));
+
+ for (i = 0; i < 2; i++) { \
+ cvtfl(make(i, 0, 0, 0));
+ cvtfl(make(i, 16232, -1, -1));
+ cvtfl(make(i, 16233, 0, 0));
+ cvtfl(make(i, 16233, 0, 1));
+ cvtfl(make(i, 16383, 0xab0ffd000000, 0));
+ cvtfl(make(i, 16383, 0xab0ffd000001, 0));
+ cvtfl(make(i, 16383, 0xab0ffeffffff, 0));
+ cvtfl(make(i, 16383, 0xab0fff000000, 0));
+ cvtfl(make(i, 16383, 0xab0fff000001, 0));
+ cvtfl(make(i, 16510, 0xfffffeffffff, -1));
+ cvtfl(make(i, 16510, 0xffffff000000, 0));
+ cvtfl(make(i, 16511, 0, 0));
+ cvtfl(make(i, 32767, 0, 0));
+ cvtfl(make(i, 32767, 0, 1));
+ cvtfl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5));
+ cvtfl(make(i, 32767, 0x800000000000, 1));
+ cvtfl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099));
+ }
+
+ for (i = 0; i < 2; i++) {
+ cvtdl(make(i, 0, 0, 0));
+ cvtdl(make(i, 15307, -1, -1));
+ cvtdl(make(i, 15308, 0, 0));
+ cvtdl(make(i, 15308, 0, 1));
+ cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000000));
+ cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000001));
+ cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf7ffffffffffffff));
+ cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000000));
+ cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000001));
+ cvtdl(make(i, 17406, 0xffffffffffff, 0xf7ffffffffffffff));
+ cvtdl(make(i, 17406, 0xffffffffffff, 0xf800000000000000));
+ cvtdl(make(i, 17407, 0, 0));
+ cvtdl(make(i, 32767, 0, 0));
+ cvtdl(make(i, 32767, 0, 1));
+ cvtdl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5));
+ cvtdl(make(i, 32767, 0x800000000000, 1));
+ cvtdl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099));
+ }
+}
+
+void tests(void)
+{
+ cmps();
+ nanz();
+ adds();
+ muls();
+ divs();
+ cvts();
+}
+
+int main()
+{
+#ifdef __aarch64__
+ tests();
+#else
+ printf("This test program is intended for a little-endian architecture\n"
+ "with an IEEE-standard 128-bit long double.\n");
+#endif
+ return 0;
+}
diff --git a/tests/tests2/00_assignment.c b/tests/tests2/00_assignment.c
new file mode 100644
index 0000000..c96109f
--- /dev/null
+++ b/tests/tests2/00_assignment.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main()
+{
+ int a;
+ a = 42;
+ printf("%d\n", a);
+
+ int b = 64;
+ printf("%d\n", b);
+
+ int c = 12, d = 34;
+ printf("%d, %d\n", c, d);
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/00_assignment.expect b/tests/tests2/00_assignment.expect
new file mode 100644
index 0000000..d4407f3
--- /dev/null
+++ b/tests/tests2/00_assignment.expect
@@ -0,0 +1,3 @@
+42
+64
+12, 34
diff --git a/tests/tests2/01_comment.c b/tests/tests2/01_comment.c
new file mode 100644
index 0000000..a2e6bc6
--- /dev/null
+++ b/tests/tests2/01_comment.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("Hello\n");
+ printf("Hello\n"); /* this is a comment */ printf("Hello\n");
+ printf("Hello\n");
+ // this is also a comment sayhello();
+ printf("Hello\n");
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/01_comment.expect b/tests/tests2/01_comment.expect
new file mode 100644
index 0000000..b1387ad
--- /dev/null
+++ b/tests/tests2/01_comment.expect
@@ -0,0 +1,5 @@
+Hello
+Hello
+Hello
+Hello
+Hello
diff --git a/tests/tests2/02_printf.c b/tests/tests2/02_printf.c
new file mode 100644
index 0000000..4c34dd8
--- /dev/null
+++ b/tests/tests2/02_printf.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("Hello world\n");
+
+ int Count;
+ for (Count = -5; Count <= 5; Count++)
+ printf("Count = %d\n", Count);
+
+ printf("String 'hello', 'there' is '%s', '%s'\n", "hello", "there");
+ printf("Character 'A' is '%c'\n", 65);
+ printf("Character 'a' is '%c'\n", 'a');
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/02_printf.expect b/tests/tests2/02_printf.expect
new file mode 100644
index 0000000..f67a0f6
--- /dev/null
+++ b/tests/tests2/02_printf.expect
@@ -0,0 +1,15 @@
+Hello world
+Count = -5
+Count = -4
+Count = -3
+Count = -2
+Count = -1
+Count = 0
+Count = 1
+Count = 2
+Count = 3
+Count = 4
+Count = 5
+String 'hello', 'there' is 'hello', 'there'
+Character 'A' is 'A'
+Character 'a' is 'a'
diff --git a/tests/tests2/03_struct.c b/tests/tests2/03_struct.c
new file mode 100644
index 0000000..c5d48c5
--- /dev/null
+++ b/tests/tests2/03_struct.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+struct fred
+{
+ int boris;
+ int natasha;
+};
+
+int main()
+{
+ struct fred bloggs;
+
+ bloggs.boris = 12;
+ bloggs.natasha = 34;
+
+ printf("%d\n", bloggs.boris);
+ printf("%d\n", bloggs.natasha);
+
+ struct fred jones[2];
+ jones[0].boris = 12;
+ jones[0].natasha = 34;
+ jones[1].boris = 56;
+ jones[1].natasha = 78;
+
+ printf("%d\n", jones[0].boris);
+ printf("%d\n", jones[0].natasha);
+ printf("%d\n", jones[1].boris);
+ printf("%d\n", jones[1].natasha);
+
+ return 0;
+}
diff --git a/tests/tests2/03_struct.expect b/tests/tests2/03_struct.expect
new file mode 100644
index 0000000..ecbf589
--- /dev/null
+++ b/tests/tests2/03_struct.expect
@@ -0,0 +1,6 @@
+12
+34
+12
+34
+56
+78
diff --git a/tests/tests2/04_for.c b/tests/tests2/04_for.c
new file mode 100644
index 0000000..312fed8
--- /dev/null
+++ b/tests/tests2/04_for.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main()
+{
+ int Count;
+
+ for (Count = 1; Count <= 10; Count++)
+ {
+ printf("%d\n", Count);
+ }
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/04_for.expect b/tests/tests2/04_for.expect
new file mode 100644
index 0000000..f00c965
--- /dev/null
+++ b/tests/tests2/04_for.expect
@@ -0,0 +1,10 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
diff --git a/tests/tests2/05_array.c b/tests/tests2/05_array.c
new file mode 100644
index 0000000..c218f31
--- /dev/null
+++ b/tests/tests2/05_array.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main()
+{
+ int Count;
+ int Array[10];
+
+ for (Count = 1; Count <= 10; Count++)
+ {
+ Array[Count-1] = Count * Count;
+ }
+
+ for (Count = 0; Count < 10; Count++)
+ {
+ printf("%d\n", Array[Count]);
+ }
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/05_array.expect b/tests/tests2/05_array.expect
new file mode 100644
index 0000000..bc7257c
--- /dev/null
+++ b/tests/tests2/05_array.expect
@@ -0,0 +1,10 @@
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
diff --git a/tests/tests2/06_case.c b/tests/tests2/06_case.c
new file mode 100644
index 0000000..c0191e2
--- /dev/null
+++ b/tests/tests2/06_case.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+int main()
+{
+ int Count;
+
+ for (Count = 0; Count < 4; Count++)
+ {
+ printf("%d\n", Count);
+ switch (Count)
+ {
+ case 1:
+ printf("%d\n", 1);
+ break;
+
+ case 2:
+ printf("%d\n", 2);
+ break;
+
+ default:
+ printf("%d\n", 0);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/06_case.expect b/tests/tests2/06_case.expect
new file mode 100644
index 0000000..fab2c20
--- /dev/null
+++ b/tests/tests2/06_case.expect
@@ -0,0 +1,8 @@
+0
+0
+1
+1
+2
+2
+3
+0
diff --git a/tests/tests2/07_function.c b/tests/tests2/07_function.c
new file mode 100644
index 0000000..0477ce1
--- /dev/null
+++ b/tests/tests2/07_function.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+int myfunc(int x)
+{
+ return x * x;
+}
+
+void vfunc(int a)
+{
+ printf("a=%d\n", a);
+}
+
+void qfunc()
+{
+ printf("qfunc()\n");
+}
+
+int main()
+{
+ printf("%d\n", myfunc(3));
+ printf("%d\n", myfunc(4));
+
+ vfunc(1234);
+
+ qfunc();
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/07_function.expect b/tests/tests2/07_function.expect
new file mode 100644
index 0000000..8ffb0a7
--- /dev/null
+++ b/tests/tests2/07_function.expect
@@ -0,0 +1,4 @@
+9
+16
+a=1234
+qfunc()
diff --git a/tests/tests2/08_while.c b/tests/tests2/08_while.c
new file mode 100644
index 0000000..602ffc7
--- /dev/null
+++ b/tests/tests2/08_while.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int main()
+{
+ int a;
+ int p;
+ int t;
+
+ a = 1;
+ p = 0;
+ t = 0;
+
+ while (a < 100)
+ {
+ printf("%d\n", a);
+ t = a;
+ a = t + p;
+ p = t;
+ }
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/08_while.expect b/tests/tests2/08_while.expect
new file mode 100644
index 0000000..702d4c0
--- /dev/null
+++ b/tests/tests2/08_while.expect
@@ -0,0 +1,11 @@
+1
+1
+2
+3
+5
+8
+13
+21
+34
+55
+89
diff --git a/tests/tests2/09_do_while.c b/tests/tests2/09_do_while.c
new file mode 100644
index 0000000..1d3315d
--- /dev/null
+++ b/tests/tests2/09_do_while.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int main()
+{
+ int a;
+ int p;
+ int t;
+
+ a = 1;
+ p = 0;
+ t = 0;
+
+ do
+ {
+ printf("%d\n", a);
+ t = a;
+ a = t + p;
+ p = t;
+ } while (a < 100);
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/09_do_while.expect b/tests/tests2/09_do_while.expect
new file mode 100644
index 0000000..702d4c0
--- /dev/null
+++ b/tests/tests2/09_do_while.expect
@@ -0,0 +1,11 @@
+1
+1
+2
+3
+5
+8
+13
+21
+34
+55
+89
diff --git a/tests/tests2/10_pointer.c b/tests/tests2/10_pointer.c
new file mode 100644
index 0000000..0177f4d
--- /dev/null
+++ b/tests/tests2/10_pointer.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+
+struct ziggy
+{
+ int a;
+ int b;
+ int c;
+} bolshevic;
+
+int main()
+{
+ int a;
+ int *b;
+ int c;
+
+ a = 42;
+ b = &a;
+ printf("a = %d\n", *b);
+
+ bolshevic.a = 12;
+ bolshevic.b = 34;
+ bolshevic.c = 56;
+
+ printf("bolshevic.a = %d\n", bolshevic.a);
+ printf("bolshevic.b = %d\n", bolshevic.b);
+ printf("bolshevic.c = %d\n", bolshevic.c);
+
+ struct ziggy *tsar = &bolshevic;
+
+ printf("tsar->a = %d\n", tsar->a);
+ printf("tsar->b = %d\n", tsar->b);
+ printf("tsar->c = %d\n", tsar->c);
+
+ b = &(bolshevic.b);
+ printf("bolshevic.b = %d\n", *b);
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/10_pointer.expect b/tests/tests2/10_pointer.expect
new file mode 100644
index 0000000..1e3c473
--- /dev/null
+++ b/tests/tests2/10_pointer.expect
@@ -0,0 +1,8 @@
+a = 42
+bolshevic.a = 12
+bolshevic.b = 34
+bolshevic.c = 56
+tsar->a = 12
+tsar->b = 34
+tsar->c = 56
+bolshevic.b = 34
diff --git a/tests/tests2/11_precedence.c b/tests/tests2/11_precedence.c
new file mode 100644
index 0000000..db2049d
--- /dev/null
+++ b/tests/tests2/11_precedence.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+
+int main()
+{
+ int a;
+ int b;
+ int c;
+ int d;
+ int e;
+ int f;
+ int x;
+ int y;
+
+ a = 12;
+ b = 34;
+ c = 56;
+ d = 78;
+ e = 0;
+ f = 1;
+
+ printf("%d\n", c + d);
+ printf("%d\n", (y = c + d));
+ printf("%d\n", e || e && f);
+ printf("%d\n", e || f && f);
+ printf("%d\n", e && e || f);
+ printf("%d\n", e && f || f);
+ printf("%d\n", a && f | f);
+ printf("%d\n", a | b ^ c & d);
+ printf("%d, %d\n", a == a, a == b);
+ printf("%d, %d\n", a != a, a != b);
+ printf("%d\n", a != b && c != d);
+ printf("%d\n", a + b * c / f);
+ printf("%d\n", a + b * c / f);
+ printf("%d\n", (4 << 4));
+ printf("%d\n", (64 >> 4));
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/11_precedence.expect b/tests/tests2/11_precedence.expect
new file mode 100644
index 0000000..b692396
--- /dev/null
+++ b/tests/tests2/11_precedence.expect
@@ -0,0 +1,15 @@
+134
+134
+0
+1
+1
+1
+1
+46
+1, 0
+0, 1
+1
+1916
+1916
+64
+4
diff --git a/tests/tests2/12_hashdefine.c b/tests/tests2/12_hashdefine.c
new file mode 100644
index 0000000..5c521e0
--- /dev/null
+++ b/tests/tests2/12_hashdefine.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+#define FRED 12
+#define BLOGGS(x) (12*(x))
+
+int main()
+{
+ printf("%d\n", FRED);
+ printf("%d, %d, %d\n", BLOGGS(1), BLOGGS(2), BLOGGS(3));
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/12_hashdefine.expect b/tests/tests2/12_hashdefine.expect
new file mode 100644
index 0000000..99f2ed5
--- /dev/null
+++ b/tests/tests2/12_hashdefine.expect
@@ -0,0 +1,2 @@
+12
+12, 24, 36
diff --git a/tests/tests2/13_integer_literals.c b/tests/tests2/13_integer_literals.c
new file mode 100644
index 0000000..7cee98b
--- /dev/null
+++ b/tests/tests2/13_integer_literals.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+
+int main()
+{
+ int a = 24680;
+ int b = 01234567;
+ int c = 0x2468ac;
+ int d = 0x2468AC;
+ int e = 0b010101010101;
+
+ printf("%d\n", a);
+ printf("%d\n", b);
+ printf("%d\n", c);
+ printf("%d\n", d);
+ printf("%d\n", e);
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/13_integer_literals.expect b/tests/tests2/13_integer_literals.expect
new file mode 100644
index 0000000..f5aca06
--- /dev/null
+++ b/tests/tests2/13_integer_literals.expect
@@ -0,0 +1,5 @@
+24680
+342391
+2386092
+2386092
+1365
diff --git a/tests/tests2/14_if.c b/tests/tests2/14_if.c
new file mode 100644
index 0000000..2bd2550
--- /dev/null
+++ b/tests/tests2/14_if.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main()
+{
+ int a = 1;
+
+ if (a)
+ printf("a is true\n");
+ else
+ printf("a is false\n");
+
+ int b = 0;
+ if (b)
+ printf("b is true\n");
+ else
+ printf("b is false\n");
+
+ return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
diff --git a/tests/tests2/14_if.expect b/tests/tests2/14_if.expect
new file mode 100644
index 0000000..c32c415
--- /dev/null
+++ b/tests/tests2/14_if.expect
@@ -0,0 +1,2 @@
+a is true
+b is false
diff --git a/tests/tests2/15_recursion.c b/tests/tests2/15_recursion.c
new file mode 100644
index 0000000..f79a00d
--- /dev/null
+++ b/tests/tests2/15_recursion.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int factorial(int i)
+{
+ if (i < 2)
+ return i;
+ else
+ return i * factorial(i - 1);
+}
+
+int main()
+{
+ int Count;
+
+ for (Count = 1; Count <= 10; Count++)
+ printf("%d\n", factorial(Count));
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/15_recursion.expect b/tests/tests2/15_recursion.expect
new file mode 100644
index 0000000..db47b28
--- /dev/null
+++ b/tests/tests2/15_recursion.expect
@@ -0,0 +1,10 @@
+1
+2
+6
+24
+120
+720
+5040
+40320
+362880
+3628800
diff --git a/tests/tests2/16_nesting.c b/tests/tests2/16_nesting.c
new file mode 100644
index 0000000..2b72cc0
--- /dev/null
+++ b/tests/tests2/16_nesting.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main()
+{
+ int x, y, z;
+
+ for (x = 0; x < 2; x++)
+ {
+ for (y = 0; y < 3; y++)
+ {
+ for (z = 0; z < 3; z++)
+ {
+ printf("%d %d %d\n", x, y, z);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/16_nesting.expect b/tests/tests2/16_nesting.expect
new file mode 100644
index 0000000..5a3431e
--- /dev/null
+++ b/tests/tests2/16_nesting.expect
@@ -0,0 +1,18 @@
+0 0 0
+0 0 1
+0 0 2
+0 1 0
+0 1 1
+0 1 2
+0 2 0
+0 2 1
+0 2 2
+1 0 0
+1 0 1
+1 0 2
+1 1 0
+1 1 1
+1 1 2
+1 2 0
+1 2 1
+1 2 2
diff --git a/tests/tests2/17_enum.c b/tests/tests2/17_enum.c
new file mode 100644
index 0000000..e2bc736
--- /dev/null
+++ b/tests/tests2/17_enum.c
@@ -0,0 +1,72 @@
+#include <stdio.h>
+
+enum fred
+{
+ a,
+ b,
+ c,
+ d,
+ e = 54,
+ f = 73,
+ g,
+ h
+};
+
+/* All following uses of enum efoo should compile
+ without warning. While forward enums aren't ISO C,
+ it's accepted by GCC also in strict mode, and only warned
+ about with -pedantic. This happens in the real world. */
+/* Strict ISO C doesn't allow this kind of forward declaration of
+ enums, but GCC accepts it (and gives only pedantic warning), and
+ it occurs in the wild. */
+enum efoo;
+struct Sforward_use {
+ int (*fmember) (enum efoo x);
+};
+
+extern enum efoo it_real_fn(void);
+enum efoo {
+ ONE,
+ TWO,
+};
+struct S2 {
+ enum efoo (*f2) (void);
+};
+void should_compile(struct S2 *s)
+{
+ s->f2 = it_real_fn;
+}
+
+enum efoo it_real_fn(void)
+{
+ return TWO;
+}
+
+static unsigned int deref_uintptr(unsigned int *p)
+{
+ return *p;
+}
+
+enum Epositive {
+ epos_one, epos_two
+};
+
+int main()
+{
+ enum fred frod;
+ enum Epositive epos = epos_two;
+
+ printf("%d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h);
+ /* printf("%d\n", frod); */
+ frod = 12;
+ printf("%d\n", frod);
+ frod = e;
+ printf("%d\n", frod);
+
+ /* Following should compile without warning. */
+ printf ("enum to int: %u\n", deref_uintptr(&epos));
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/17_enum.expect b/tests/tests2/17_enum.expect
new file mode 100644
index 0000000..d453a61
--- /dev/null
+++ b/tests/tests2/17_enum.expect
@@ -0,0 +1,4 @@
+0 1 2 3 54 73 74 75
+12
+54
+enum to int: 1
diff --git a/tests/tests2/18_include.c b/tests/tests2/18_include.c
new file mode 100644
index 0000000..dbae3aa
--- /dev/null
+++ b/tests/tests2/18_include.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("including\n");
+#include "18_include.h"
+ printf("done\n");
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/18_include.expect b/tests/tests2/18_include.expect
new file mode 100644
index 0000000..58c6d29
--- /dev/null
+++ b/tests/tests2/18_include.expect
@@ -0,0 +1,3 @@
+including
+included
+done
diff --git a/tests/tests2/18_include.h b/tests/tests2/18_include.h
new file mode 100644
index 0000000..dc86080
--- /dev/null
+++ b/tests/tests2/18_include.h
@@ -0,0 +1 @@
+printf("included\n");
diff --git a/tests/tests2/19_pointer_arithmetic.c b/tests/tests2/19_pointer_arithmetic.c
new file mode 100644
index 0000000..aff65e5
--- /dev/null
+++ b/tests/tests2/19_pointer_arithmetic.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+
+int main()
+{
+ int a;
+ int *b;
+ int *c;
+
+ a = 42;
+ b = &a;
+ c = NULL;
+
+ printf("%d\n", *b);
+
+ if (b == NULL)
+ printf("b is NULL\n");
+ else
+ printf("b is not NULL\n");
+
+ if (c == NULL)
+ printf("c is NULL\n");
+ else
+ printf("c is not NULL\n");
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/19_pointer_arithmetic.expect b/tests/tests2/19_pointer_arithmetic.expect
new file mode 100644
index 0000000..0cf781b
--- /dev/null
+++ b/tests/tests2/19_pointer_arithmetic.expect
@@ -0,0 +1,3 @@
+42
+b is not NULL
+c is NULL
diff --git a/tests/tests2/20_pointer_comparison.c b/tests/tests2/20_pointer_comparison.c
new file mode 100644
index 0000000..825f778
--- /dev/null
+++ b/tests/tests2/20_pointer_comparison.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int main()
+{
+ int a;
+ int b;
+ int *d;
+ int *e;
+ d = &a;
+ e = &b;
+ a = 12;
+ b = 34;
+ printf("%d\n", *d);
+ printf("%d\n", *e);
+ printf("%d\n", d == e);
+ printf("%d\n", d != e);
+ d = e;
+ printf("%d\n", d == e);
+ printf("%d\n", d != e);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/20_pointer_comparison.expect b/tests/tests2/20_pointer_comparison.expect
new file mode 100644
index 0000000..5d1e5f5
--- /dev/null
+++ b/tests/tests2/20_pointer_comparison.expect
@@ -0,0 +1,6 @@
+12
+34
+0
+1
+1
+0
diff --git a/tests/tests2/21_char_array.c b/tests/tests2/21_char_array.c
new file mode 100644
index 0000000..f22f527
--- /dev/null
+++ b/tests/tests2/21_char_array.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+int main()
+{
+ int x = 'a';
+ char y = x;
+
+ char *a = "hello";
+
+ printf("%s\n", a);
+
+ int c;
+ c = *a;
+
+ char *b;
+ for (b = a; *b != 0; b++)
+ printf("%c: %d\n", *b, *b);
+
+ char destarray[10];
+ char *dest = &destarray[0];
+ char *src = a;
+
+ while (*src != 0)
+ *dest++ = *src++;
+
+ *dest = 0;
+
+ printf("copied string is %s\n", destarray);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/21_char_array.expect b/tests/tests2/21_char_array.expect
new file mode 100644
index 0000000..dbc6068
--- /dev/null
+++ b/tests/tests2/21_char_array.expect
@@ -0,0 +1,7 @@
+hello
+h: 104
+e: 101
+l: 108
+l: 108
+o: 111
+copied string is hello
diff --git a/tests/tests2/22_floating_point.c b/tests/tests2/22_floating_point.c
new file mode 100644
index 0000000..e3491f5
--- /dev/null
+++ b/tests/tests2/22_floating_point.c
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <math.h>
+
+int main()
+{
+ // variables
+ float a = 12.34 + 56.78;
+ printf("%f\n", a);
+
+ // infix operators
+ printf("%f\n", 12.34 + 56.78);
+ printf("%f\n", 12.34 - 56.78);
+ printf("%f\n", 12.34 * 56.78);
+ printf("%f\n", 12.34 / 56.78);
+
+ // comparison operators
+ printf("%d %d %d %d %d %d\n", 12.34 < 56.78, 12.34 <= 56.78, 12.34 == 56.78, 12.34 >= 56.78, 12.34 > 56.78, 12.34 != 56.78);
+ printf("%d %d %d %d %d %d\n", 12.34 < 12.34, 12.34 <= 12.34, 12.34 == 12.34, 12.34 >= 12.34, 12.34 > 12.34, 12.34 != 12.34);
+ printf("%d %d %d %d %d %d\n", 56.78 < 12.34, 56.78 <= 12.34, 56.78 == 12.34, 56.78 >= 12.34, 56.78 > 12.34, 56.78 != 12.34);
+
+ // assignment operators
+ a = 12.34;
+ a += 56.78;
+ printf("%f\n", a);
+
+ a = 12.34;
+ a -= 56.78;
+ printf("%f\n", a);
+
+ a = 12.34;
+ a *= 56.78;
+ printf("%f\n", a);
+
+ a = 12.34;
+ a /= 56.78;
+ printf("%f\n", a);
+
+ // prefix operators
+ printf("%f\n", +12.34);
+ printf("%f\n", -12.34);
+
+ // type coercion
+ a = 2;
+ printf("%f\n", a);
+ printf("%f\n", sin(2));
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/22_floating_point.expect b/tests/tests2/22_floating_point.expect
new file mode 100644
index 0000000..75ea3a7
--- /dev/null
+++ b/tests/tests2/22_floating_point.expect
@@ -0,0 +1,16 @@
+69.120003
+69.120000
+-44.440000
+700.665200
+0.217330
+1 1 0 0 0 1
+0 1 1 1 0 0
+0 0 0 1 1 1
+69.120003
+-44.439999
+700.665222
+0.217330
+12.340000
+-12.340000
+2.000000
+0.909297
diff --git a/tests/tests2/23_type_coercion.c b/tests/tests2/23_type_coercion.c
new file mode 100644
index 0000000..1fcc335
--- /dev/null
+++ b/tests/tests2/23_type_coercion.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+
+void charfunc(char a)
+{
+ printf("char: %c\n", a);
+}
+
+void intfunc(int a)
+{
+ printf("int: %d\n", a);
+}
+
+void floatfunc(float a)
+{
+ printf("float: %f\n", a);
+}
+
+int main()
+{
+ charfunc('a');
+ charfunc(98);
+ charfunc(99.0);
+
+ intfunc('a');
+ intfunc(98);
+ intfunc(99.0);
+
+ floatfunc('a');
+ floatfunc(98);
+ floatfunc(99.0);
+
+ /* printf("%c %d %f\n", 'a', 'b', 'c'); */
+ /* printf("%c %d %f\n", 97, 98, 99); */
+ /* printf("%c %d %f\n", 97.0, 98.0, 99.0); */
+
+ char b = 97;
+ char c = 97.0;
+
+ printf("%d %d\n", b, c);
+
+ int d = 'a';
+ int e = 97.0;
+
+ printf("%d %d\n", d, e);
+
+ float f = 'a';
+ float g = 97;
+
+ printf("%f %f\n", f, g);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/23_type_coercion.expect b/tests/tests2/23_type_coercion.expect
new file mode 100644
index 0000000..d9076f0
--- /dev/null
+++ b/tests/tests2/23_type_coercion.expect
@@ -0,0 +1,12 @@
+char: a
+char: b
+char: c
+int: 97
+int: 98
+int: 99
+float: 97.000000
+float: 98.000000
+float: 99.000000
+97 97
+97 97
+97.000000 97.000000
diff --git a/tests/tests2/24_math_library.c b/tests/tests2/24_math_library.c
new file mode 100644
index 0000000..514a25f
--- /dev/null
+++ b/tests/tests2/24_math_library.c
@@ -0,0 +1,30 @@
+#define _ISOC99_SOURCE 1
+
+#include <stdio.h>
+#include <math.h>
+
+int main()
+{
+ printf("%f\n", sin(0.12));
+ printf("%f\n", cos(0.12));
+ printf("%f\n", tan(0.12));
+ printf("%f\n", asin(0.12));
+ printf("%f\n", acos(0.12));
+ printf("%f\n", atan(0.12));
+ printf("%f\n", sinh(0.12));
+ printf("%f\n", cosh(0.12));
+ printf("%f\n", tanh(0.12));
+ printf("%f\n", exp(0.12));
+ printf("%f\n", fabs(-0.12));
+ printf("%f\n", log(0.12));
+ printf("%f\n", log10(0.12));
+ printf("%f\n", pow(0.12, 0.12));
+ printf("%f\n", sqrt(0.12));
+ printf("%f\n", round(12.34));
+ printf("%f\n", ceil(12.34));
+ printf("%f\n", floor(12.34));
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/24_math_library.expect b/tests/tests2/24_math_library.expect
new file mode 100644
index 0000000..99f7299
--- /dev/null
+++ b/tests/tests2/24_math_library.expect
@@ -0,0 +1,18 @@
+0.119712
+0.992809
+0.120579
+0.120290
+1.450506
+0.119429
+0.120288
+1.007209
+0.119427
+1.127497
+0.120000
+-2.120264
+-0.920819
+0.775357
+0.346410
+12.000000
+13.000000
+12.000000
diff --git a/tests/tests2/25_quicksort.c b/tests/tests2/25_quicksort.c
new file mode 100644
index 0000000..5cc08bd
--- /dev/null
+++ b/tests/tests2/25_quicksort.c
@@ -0,0 +1,83 @@
+#include <stdio.h>
+
+int array[16];
+
+//Swap integer values by array indexes
+void swap(int a, int b)
+{
+ int tmp = array[a];
+ array[a] = array[b];
+ array[b] = tmp;
+}
+
+//Partition the array into two halves and return the
+//index about which the array is partitioned
+int partition(int left, int right)
+{
+ int pivotIndex = left;
+ int pivotValue = array[pivotIndex];
+ int index = left;
+ int i;
+
+ swap(pivotIndex, right);
+ for(i = left; i < right; i++)
+ {
+ if(array[i] < pivotValue)
+ {
+ swap(i, index);
+ index += 1;
+ }
+ }
+ swap(right, index);
+
+ return index;
+}
+
+//Quicksort the array
+void quicksort(int left, int right)
+{
+ if(left >= right)
+ return;
+
+ int index = partition(left, right);
+ quicksort(left, index - 1);
+ quicksort(index + 1, right);
+}
+
+int main()
+{
+ int i;
+
+ array[0] = 62;
+ array[1] = 83;
+ array[2] = 4;
+ array[3] = 89;
+ array[4] = 36;
+ array[5] = 21;
+ array[6] = 74;
+ array[7] = 37;
+ array[8] = 65;
+ array[9] = 33;
+ array[10] = 96;
+ array[11] = 38;
+ array[12] = 53;
+ array[13] = 16;
+ array[14] = 74;
+ array[15] = 55;
+
+ for (i = 0; i < 16; i++)
+ printf("%d ", array[i]);
+
+ printf("\n");
+
+ quicksort(0, 15);
+
+ for (i = 0; i < 16; i++)
+ printf("%d ", array[i]);
+
+ printf("\n");
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/25_quicksort.expect b/tests/tests2/25_quicksort.expect
new file mode 100644
index 0000000..2d39cd3
--- /dev/null
+++ b/tests/tests2/25_quicksort.expect
@@ -0,0 +1,2 @@
+62 83 4 89 36 21 74 37 65 33 96 38 53 16 74 55
+4 16 21 33 36 37 38 53 55 62 65 74 74 83 89 96
diff --git a/tests/tests2/26_character_constants.c b/tests/tests2/26_character_constants.c
new file mode 100644
index 0000000..95c4423
--- /dev/null
+++ b/tests/tests2/26_character_constants.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("%d\n", '\1');
+ printf("%d\n", '\10');
+ printf("%d\n", '\100');
+ printf("%d\n", '\x01');
+ printf("%d\n", '\x0e');
+ printf("%d\n", '\x10');
+ printf("%d\n", '\x40');
+ printf("test \x40\n");
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/26_character_constants.expect b/tests/tests2/26_character_constants.expect
new file mode 100644
index 0000000..8f8bfa4
--- /dev/null
+++ b/tests/tests2/26_character_constants.expect
@@ -0,0 +1,8 @@
+1
+8
+64
+1
+14
+16
+64
+test @
diff --git a/tests/tests2/27_sizeof.c b/tests/tests2/27_sizeof.c
new file mode 100644
index 0000000..5ae0ede
--- /dev/null
+++ b/tests/tests2/27_sizeof.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main()
+{
+ char a;
+ int b;
+ double c;
+
+ printf("%d\n", sizeof(a));
+ printf("%d\n", sizeof(b));
+ printf("%d\n", sizeof(c));
+
+ printf("%d\n", sizeof(!a));
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/27_sizeof.expect b/tests/tests2/27_sizeof.expect
new file mode 100644
index 0000000..a47ea3a
--- /dev/null
+++ b/tests/tests2/27_sizeof.expect
@@ -0,0 +1,4 @@
+1
+4
+8
+4
diff --git a/tests/tests2/28_strings.c b/tests/tests2/28_strings.c
new file mode 100644
index 0000000..2db2298
--- /dev/null
+++ b/tests/tests2/28_strings.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+ char a[10];
+
+ strcpy(a, "hello");
+ printf("%s\n", a);
+
+ strncpy(a, "gosh", 2);
+ printf("%s\n", a);
+
+ printf("%d\n", strcmp(a, "apple") > 0);
+ printf("%d\n", strcmp(a, "goere") > 0);
+ printf("%d\n", strcmp(a, "zebra") < 0);
+
+ printf("%d\n", strlen(a));
+
+ strcat(a, "!");
+ printf("%s\n", a);
+
+ printf("%d\n", strncmp(a, "apple", 2) > 0);
+ printf("%d\n", strncmp(a, "goere", 2) == 0);
+ printf("%d\n", strncmp(a, "goerg", 2) == 0);
+ printf("%d\n", strncmp(a, "zebra", 2) < 0);
+
+ printf("%s\n", strchr(a, 'o'));
+ printf("%s\n", strrchr(a, 'l'));
+ printf("%d\n", strrchr(a, 'x') == NULL);
+
+ memset(&a[1], 'r', 4);
+ printf("%s\n", a);
+
+ memcpy(&a[2], a, 2);
+ printf("%s\n", a);
+
+ printf("%d\n", memcmp(a, "apple", 4) > 0);
+ printf("%d\n", memcmp(a, "grgr", 4) == 0);
+ printf("%d\n", memcmp(a, "zebra", 4) < 0);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/28_strings.expect b/tests/tests2/28_strings.expect
new file mode 100644
index 0000000..fd9217a
--- /dev/null
+++ b/tests/tests2/28_strings.expect
@@ -0,0 +1,19 @@
+hello
+gollo
+1
+1
+1
+5
+gollo!
+1
+1
+1
+1
+ollo!
+lo!
+1
+grrrr!
+grgrr!
+1
+1
+1
diff --git a/tests/tests2/29_array_address.c b/tests/tests2/29_array_address.c
new file mode 100644
index 0000000..bda5ddd
--- /dev/null
+++ b/tests/tests2/29_array_address.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+ char a[10];
+ strcpy(a, "abcdef");
+ printf("%s\n", &a[1]);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/29_array_address.expect b/tests/tests2/29_array_address.expect
new file mode 100644
index 0000000..9bc8683
--- /dev/null
+++ b/tests/tests2/29_array_address.expect
@@ -0,0 +1 @@
+bcdef
diff --git a/tests/tests2/30_hanoi.c b/tests/tests2/30_hanoi.c
new file mode 100644
index 0000000..7c0893b
--- /dev/null
+++ b/tests/tests2/30_hanoi.c
@@ -0,0 +1,122 @@
+/* example from http://barnyard.syr.edu/quickies/hanoi.c */
+
+/* hanoi.c: solves the tower of hanoi problem. (Programming exercise.) */
+/* By Terry R. McConnell (12/2/97) */
+/* Compile: cc -o hanoi hanoi.c */
+
+/* This program does no error checking. But then, if it's right,
+ it's right ... right ? */
+
+
+/* The original towers of hanoi problem seems to have been originally posed
+ by one M. Claus in 1883. There is a popular legend that goes along with
+ it that has been often repeated and paraphrased. It goes something like this:
+ In the great temple at Benares there are 3 golden spikes. On one of them,
+ God placed 64 disks increasing in size from bottom to top, at the beginning
+ of time. Since then, and to this day, the priest on duty constantly transfers
+ disks, one at a time, in such a way that no larger disk is ever put on top
+ of a smaller one. When the disks have been transferred entirely to another
+ spike the Universe will come to an end in a large thunderclap.
+
+ This paraphrases the original legend due to DeParville, La Nature, Paris 1884,
+ Part I, 285-286. For this and further information see: Mathematical
+ Recreations & Essays, W.W. Rouse Ball, MacMillan, NewYork, 11th Ed. 1967,
+ 303-305.
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define TRUE 1
+#define FALSE 0
+
+/* This is the number of "disks" on tower A initially. Taken to be 64 in the
+ * legend. The number of moves required, in general, is 2^N - 1. For N = 64,
+ * this is 18,446,744,073,709,551,615 */
+#define N 4
+
+/* These are the three towers. For example if the state of A is 0,1,3,4, that
+ * means that there are three discs on A of sizes 1, 3, and 4. (Think of right
+ * as being the "down" direction.) */
+int A[N], B[N], C[N];
+
+void Hanoi(int,int*,int*,int*);
+
+/* Print the current configuration of A, B, and C to the screen */
+void PrintAll()
+{
+ int i;
+
+ printf("A: ");
+ for(i=0;i<N;i++)printf(" %d ",A[i]);
+ printf("\n");
+
+ printf("B: ");
+ for(i=0;i<N;i++)printf(" %d ",B[i]);
+ printf("\n");
+
+ printf("C: ");
+ for(i=0;i<N;i++)printf(" %d ",C[i]);
+ printf("\n");
+ printf("------------------------------------------\n");
+ return;
+}
+
+/* Move the leftmost nonzero element of source to dest, leave behind 0. */
+/* Returns the value moved (not used.) */
+int Move(int *source, int *dest)
+{
+ int i = 0, j = 0;
+
+ while (i<N && (source[i])==0) i++;
+ while (j<N && (dest[j])==0) j++;
+
+ dest[j-1] = source[i];
+ source[i] = 0;
+ PrintAll(); /* Print configuration after each move. */
+ return dest[j-1];
+}
+
+
+/* Moves first n nonzero numbers from source to dest using the rules of Hanoi.
+ Calls itself recursively.
+ */
+void Hanoi(int n,int *source, int *dest, int *spare)
+{
+ int i;
+ if(n==1){
+ Move(source,dest);
+ return;
+ }
+
+ Hanoi(n-1,source,spare,dest);
+ Move(source,dest);
+ Hanoi(n-1,spare,dest,source);
+ return;
+}
+
+int main()
+{
+ int i;
+
+ /* initialize the towers */
+ for(i=0;i<N;i++)A[i]=i+1;
+ for(i=0;i<N;i++)B[i]=0;
+ for(i=0;i<N;i++)C[i]=0;
+
+ printf("Solution of Tower of Hanoi Problem with %d Disks\n\n",N);
+
+ /* Print the starting state */
+ printf("Starting state:\n");
+ PrintAll();
+ printf("\n\nSubsequent states:\n\n");
+
+ /* Do it! Use A = Source, B = Destination, C = Spare */
+ Hanoi(N,A,B,C);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/30_hanoi.expect b/tests/tests2/30_hanoi.expect
new file mode 100644
index 0000000..7798ee0
--- /dev/null
+++ b/tests/tests2/30_hanoi.expect
@@ -0,0 +1,71 @@
+Solution of Tower of Hanoi Problem with 4 Disks
+
+Starting state:
+A: 1 2 3 4
+B: 0 0 0 0
+C: 0 0 0 0
+------------------------------------------
+
+
+Subsequent states:
+
+A: 0 2 3 4
+B: 0 0 0 0
+C: 0 0 0 1
+------------------------------------------
+A: 0 0 3 4
+B: 0 0 0 2
+C: 0 0 0 1
+------------------------------------------
+A: 0 0 3 4
+B: 0 0 1 2
+C: 0 0 0 0
+------------------------------------------
+A: 0 0 0 4
+B: 0 0 1 2
+C: 0 0 0 3
+------------------------------------------
+A: 0 0 1 4
+B: 0 0 0 2
+C: 0 0 0 3
+------------------------------------------
+A: 0 0 1 4
+B: 0 0 0 0
+C: 0 0 2 3
+------------------------------------------
+A: 0 0 0 4
+B: 0 0 0 0
+C: 0 1 2 3
+------------------------------------------
+A: 0 0 0 0
+B: 0 0 0 4
+C: 0 1 2 3
+------------------------------------------
+A: 0 0 0 0
+B: 0 0 1 4
+C: 0 0 2 3
+------------------------------------------
+A: 0 0 0 2
+B: 0 0 1 4
+C: 0 0 0 3
+------------------------------------------
+A: 0 0 1 2
+B: 0 0 0 4
+C: 0 0 0 3
+------------------------------------------
+A: 0 0 1 2
+B: 0 0 3 4
+C: 0 0 0 0
+------------------------------------------
+A: 0 0 0 2
+B: 0 0 3 4
+C: 0 0 0 1
+------------------------------------------
+A: 0 0 0 0
+B: 0 2 3 4
+C: 0 0 0 1
+------------------------------------------
+A: 0 0 0 0
+B: 1 2 3 4
+C: 0 0 0 0
+------------------------------------------
diff --git a/tests/tests2/31_args.c b/tests/tests2/31_args.c
new file mode 100644
index 0000000..dcafed5
--- /dev/null
+++ b/tests/tests2/31_args.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ int Count;
+
+ printf("hello world %d\n", argc);
+ for (Count = 1; Count < argc; Count++)
+ printf("arg %d: %s\n", Count, argv[Count]);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/31_args.expect b/tests/tests2/31_args.expect
new file mode 100644
index 0000000..8c60bfc
--- /dev/null
+++ b/tests/tests2/31_args.expect
@@ -0,0 +1,6 @@
+hello world 6
+arg 1: arg1
+arg 2: arg2
+arg 3: arg3
+arg 4: arg4
+arg 5: arg5
diff --git a/tests/tests2/32_led.c b/tests/tests2/32_led.c
new file mode 100644
index 0000000..5596cbf
--- /dev/null
+++ b/tests/tests2/32_led.c
@@ -0,0 +1,266 @@
+/* example from http://barnyard.syr.edu/quickies/led.c */
+
+/* led.c: print out number as if on 7 line led display. I.e., write integer
+ given on command line like this:
+ _ _ _
+ | _| _| |_| |_
+ | |_ _| | _| etc.
+
+ We assume the terminal behaves like a classical teletype. So the top
+ lines of all digits have to be printed first, then the middle lines of
+ all digits, etc.
+
+ By Terry R. McConnell
+
+compile: cc -o led led.c
+
+If you just want to link in the subroutine print_led that does all the
+work, compile with -DNO_MAIN, and declare the following in any source file
+that uses the call:
+
+extern void print_led(unsigned long x, char *buf);
+
+Bug: you cannot call repeatedly to print more than one number to a line.
+That would require curses or some other terminal API that allows moving the
+cursor to a previous line.
+
+*/
+
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define MAX_DIGITS 32
+#define NO_MAIN
+
+
+/* Print the top line of the digit d into buffer.
+ Does not null terminate buffer. */
+
+void topline(int d, char *p){
+
+ *p++ = ' ';
+ switch(d){
+
+ /* all these have _ on top line */
+
+ case 0:
+ case 2:
+ case 3:
+ case 5:
+ case 7:
+ case 8:
+ case 9:
+ *p++ = '_';
+ break;
+ default:
+ *p++=' ';
+
+ }
+ *p++=' ';
+}
+
+/* Print the middle line of the digit d into the buffer.
+ Does not null terminate. */
+
+void midline(int d, char *p){
+
+ switch(d){
+
+ /* those that have leading | on middle line */
+
+ case 0:
+ case 4:
+ case 5:
+ case 6:
+ case 8:
+ case 9:
+ *p++='|';
+ break;
+ default:
+ *p++=' ';
+ }
+ switch(d){
+
+ /* those that have _ on middle line */
+
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 8:
+ case 9:
+ *p++='_';
+ break;
+ default:
+ *p++=' ';
+
+ }
+ switch(d){
+
+ /* those that have closing | on middle line */
+
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 7:
+ case 8:
+ case 9:
+ *p++='|';
+ break;
+ default:
+ *p++=' ';
+
+ }
+}
+
+/* Print the bottom line of the digit d. Does not null terminate. */
+
+void botline(int d, char *p){
+
+
+ switch(d){
+
+ /* those that have leading | on bottom line */
+
+ case 0:
+ case 2:
+ case 6:
+ case 8:
+ *p++='|';
+ break;
+ default:
+ *p++=' ';
+ }
+ switch(d){
+
+ /* those that have _ on bottom line */
+
+ case 0:
+ case 2:
+ case 3:
+ case 5:
+ case 6:
+ case 8:
+ *p++='_';
+ break;
+ default:
+ *p++=' ';
+
+ }
+ switch(d){
+
+ /* those that have closing | on bottom line */
+
+ case 0:
+ case 1:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ *p++='|';
+ break;
+ default:
+ *p++=' ';
+
+ }
+}
+
+/* Write the led representation of integer to string buffer. */
+
+void print_led(unsigned long x, char *buf)
+{
+
+ int i=0,n;
+ static int d[MAX_DIGITS];
+
+
+ /* extract digits from x */
+
+ n = ( x == 0L ? 1 : 0 ); /* 0 is a digit, hence a special case */
+
+ while(x){
+ d[n++] = (int)(x%10L);
+ if(n >= MAX_DIGITS)break;
+ x = x/10L;
+ }
+
+ /* print top lines of all digits */
+
+ for(i=n-1;i>=0;i--){
+ topline(d[i],buf);
+ buf += 3;
+ *buf++=' ';
+ }
+ *buf++='\n'; /* move teletype to next line */
+
+ /* print middle lines of all digits */
+
+ for(i=n-1;i>=0;i--){
+ midline(d[i],buf);
+ buf += 3;
+ *buf++=' ';
+ }
+ *buf++='\n';
+
+ /* print bottom lines of all digits */
+
+ for(i=n-1;i>=0;i--){
+ botline(d[i],buf);
+ buf += 3;
+ *buf++=' ';
+ }
+ *buf++='\n';
+ *buf='\0';
+}
+
+int main()
+{
+ char buf[5*MAX_DIGITS];
+ print_led(1234567, buf);
+ printf("%s\n",buf);
+
+ return 0;
+}
+
+#ifndef NO_MAIN
+int main(int argc, char **argv)
+{
+
+ int i=0,n;
+ long x;
+ static int d[MAX_DIGITS];
+ char buf[5*MAX_DIGITS];
+
+ if(argc != 2){
+ fprintf(stderr,"led: usage: led integer\n");
+ return 1;
+ }
+
+ /* fetch argument from command line */
+
+ x = atol(argv[1]);
+
+ /* sanity check */
+
+ if(x<0){
+ fprintf(stderr,"led: %d must be non-negative\n",x);
+ return 1;
+ }
+
+ print_led(x,buf);
+ printf("%s\n",buf);
+
+ return 0;
+
+}
+#endif
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/32_led.expect b/tests/tests2/32_led.expect
new file mode 100644
index 0000000..c53b58a
--- /dev/null
+++ b/tests/tests2/32_led.expect
@@ -0,0 +1,4 @@
+ _ _ _ _
+ | _| _| |_| |_ |_ |
+ | |_ _| | _| |_| |
+
diff --git a/tests/tests2/33_ternary_op.c b/tests/tests2/33_ternary_op.c
new file mode 100644
index 0000000..8579b50
--- /dev/null
+++ b/tests/tests2/33_ternary_op.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main()
+{
+ int Count;
+
+ for (Count = 0; Count < 10; Count++)
+ {
+ printf("%d\n", (Count < 5) ? (Count*Count) : (Count * 3));
+ }
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/33_ternary_op.expect b/tests/tests2/33_ternary_op.expect
new file mode 100644
index 0000000..45ea507
--- /dev/null
+++ b/tests/tests2/33_ternary_op.expect
@@ -0,0 +1,10 @@
+0
+1
+4
+9
+16
+15
+18
+21
+24
+27
diff --git a/tests/tests2/34_array_assignment.c b/tests/tests2/34_array_assignment.c
new file mode 100644
index 0000000..5885c97
--- /dev/null
+++ b/tests/tests2/34_array_assignment.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+int main()
+{
+ int a[4];
+
+ a[0] = 12;
+ a[1] = 23;
+ a[2] = 34;
+ a[3] = 45;
+
+ printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]);
+
+ int b[4];
+
+ b = a;
+
+ printf("%d %d %d %d\n", b[0], b[1], b[2], b[3]);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/34_array_assignment.expect b/tests/tests2/34_array_assignment.expect
new file mode 100644
index 0000000..9736bf5
--- /dev/null
+++ b/tests/tests2/34_array_assignment.expect
@@ -0,0 +1,2 @@
+12 23 34 45
+12 23 34 45
diff --git a/tests/tests2/35_sizeof.c b/tests/tests2/35_sizeof.c
new file mode 100644
index 0000000..672e87e
--- /dev/null
+++ b/tests/tests2/35_sizeof.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int main()
+{
+ char a;
+ short b;
+
+ printf("%d %d\n", sizeof(char), sizeof(a));
+ printf("%d %d\n", sizeof(short), sizeof(b));
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/35_sizeof.expect b/tests/tests2/35_sizeof.expect
new file mode 100644
index 0000000..534fb83
--- /dev/null
+++ b/tests/tests2/35_sizeof.expect
@@ -0,0 +1,2 @@
+1 1
+2 2
diff --git a/tests/tests2/36_array_initialisers.c b/tests/tests2/36_array_initialisers.c
new file mode 100644
index 0000000..1bc8ee0
--- /dev/null
+++ b/tests/tests2/36_array_initialisers.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main()
+{
+ int Count;
+
+ int Array[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753 };
+
+ for (Count = 0; Count < 10; Count++)
+ printf("%d: %d\n", Count, Array[Count]);
+
+ int Array2[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753, };
+
+ for (Count = 0; Count < 10; Count++)
+ printf("%d: %d\n", Count, Array2[Count]);
+
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/36_array_initialisers.expect b/tests/tests2/36_array_initialisers.expect
new file mode 100644
index 0000000..3ac6c77
--- /dev/null
+++ b/tests/tests2/36_array_initialisers.expect
@@ -0,0 +1,20 @@
+0: 12
+1: 34
+2: 56
+3: 78
+4: 90
+5: 123
+6: 456
+7: 789
+8: 8642
+9: 9753
+0: 12
+1: 34
+2: 56
+3: 78
+4: 90
+5: 123
+6: 456
+7: 789
+8: 8642
+9: 9753
diff --git a/tests/tests2/37_sprintf.c b/tests/tests2/37_sprintf.c
new file mode 100644
index 0000000..1dd1dce
--- /dev/null
+++ b/tests/tests2/37_sprintf.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main()
+{
+ char Buf[100];
+ int Count;
+
+ for (Count = 1; Count <= 20; Count++)
+ {
+ sprintf(Buf, "->%02d<-\n", Count);
+ printf("%s", Buf);
+ }
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/37_sprintf.expect b/tests/tests2/37_sprintf.expect
new file mode 100644
index 0000000..a643da8
--- /dev/null
+++ b/tests/tests2/37_sprintf.expect
@@ -0,0 +1,20 @@
+->01<-
+->02<-
+->03<-
+->04<-
+->05<-
+->06<-
+->07<-
+->08<-
+->09<-
+->10<-
+->11<-
+->12<-
+->13<-
+->14<-
+->15<-
+->16<-
+->17<-
+->18<-
+->19<-
+->20<-
diff --git a/tests/tests2/38_multiple_array_index.c b/tests/tests2/38_multiple_array_index.c
new file mode 100644
index 0000000..4e1868e
--- /dev/null
+++ b/tests/tests2/38_multiple_array_index.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+
+int main()
+{
+ int a[4][4];
+ int b = 0;
+ int x;
+ int y;
+
+ for (x = 0; x < 4; x++)
+ {
+ for (y = 0; y < 4; y++)
+ {
+ b++;
+ a[x][y] = b;
+ }
+ }
+
+ for (x = 0; x < 4; x++)
+ {
+ printf("x=%d: ", x);
+ for (y = 0; y < 4; y++)
+ {
+ printf("%d ", a[x][y]);
+ }
+ printf("\n");
+ }
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/38_multiple_array_index.expect b/tests/tests2/38_multiple_array_index.expect
new file mode 100644
index 0000000..747ad75
--- /dev/null
+++ b/tests/tests2/38_multiple_array_index.expect
@@ -0,0 +1,4 @@
+x=0: 1 2 3 4
+x=1: 5 6 7 8
+x=2: 9 10 11 12
+x=3: 13 14 15 16
diff --git a/tests/tests2/39_typedef.c b/tests/tests2/39_typedef.c
new file mode 100644
index 0000000..da73f71
--- /dev/null
+++ b/tests/tests2/39_typedef.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+typedef int MyInt;
+
+struct FunStruct
+{
+ int i;
+ int j;
+};
+
+typedef struct FunStruct MyFunStruct;
+
+typedef MyFunStruct *MoreFunThanEver;
+
+int main()
+{
+ MyInt a = 1;
+ printf("%d\n", a);
+
+ MyFunStruct b;
+ b.i = 12;
+ b.j = 34;
+ printf("%d,%d\n", b.i, b.j);
+
+ MoreFunThanEver c = &b;
+ printf("%d,%d\n", c->i, c->j);
+
+ return 0;
+}
+
+/* "If the specification of an array type includes any type qualifiers,
+ the element type is so-qualified, not the array type." */
+
+typedef int A[3];
+extern A const ca;
+extern const A ca;
+extern const int ca[3];
+
+typedef A B[1][2];
+extern B const cb;
+extern const B cb;
+extern const int cb[1][2][3];
+
+extern B b;
+extern int b[1][2][3];
+
+/* Funny but valid function declaration. */
+typedef int functype (int);
+extern functype func;
+int func(int i)
+{
+ return i + 1;
+}
+
+/* Even funnier function decl and definition using typeof. */
+int set_anon_super(void);
+int set_anon_super(void)
+{
+ return 42;
+}
+typedef int sas_type (void);
+extern typeof(set_anon_super) set_anon_super;
+extern sas_type set_anon_super;
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/39_typedef.expect b/tests/tests2/39_typedef.expect
new file mode 100644
index 0000000..b9050a9
--- /dev/null
+++ b/tests/tests2/39_typedef.expect
@@ -0,0 +1,3 @@
+1
+12,34
+12,34
diff --git a/tests/tests2/40_stdio.c b/tests/tests2/40_stdio.c
new file mode 100644
index 0000000..b986093
--- /dev/null
+++ b/tests/tests2/40_stdio.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+
+int main()
+{
+ FILE *f = fopen("fred.txt", "w");
+ fwrite("hello\nhello\n", 1, 12, f);
+ fclose(f);
+
+ char freddy[7];
+ f = fopen("fred.txt", "r");
+ if (fread(freddy, 1, 6, f) != 6)
+ printf("couldn't read fred.txt\n");
+
+ freddy[6] = '\0';
+ fclose(f);
+
+ printf("%s", freddy);
+
+ int InChar;
+ char ShowChar;
+ f = fopen("fred.txt", "r");
+ while ( (InChar = fgetc(f)) != EOF)
+ {
+ ShowChar = InChar;
+ if (ShowChar < ' ')
+ ShowChar = '.';
+
+ printf("ch: %d '%c'\n", InChar, ShowChar);
+ }
+ fclose(f);
+
+ f = fopen("fred.txt", "r");
+ while ( (InChar = getc(f)) != EOF)
+ {
+ ShowChar = InChar;
+ if (ShowChar < ' ')
+ ShowChar = '.';
+
+ printf("ch: %d '%c'\n", InChar, ShowChar);
+ }
+ fclose(f);
+
+ f = fopen("fred.txt", "r");
+ while (fgets(freddy, sizeof(freddy), f) != NULL)
+ printf("x: %s", freddy);
+
+ fclose(f);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/40_stdio.expect b/tests/tests2/40_stdio.expect
new file mode 100644
index 0000000..e08167a
--- /dev/null
+++ b/tests/tests2/40_stdio.expect
@@ -0,0 +1,27 @@
+hello
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+x: hello
+x: hello
diff --git a/tests/tests2/41_hashif.c b/tests/tests2/41_hashif.c
new file mode 100644
index 0000000..cb37b9e
--- /dev/null
+++ b/tests/tests2/41_hashif.c
@@ -0,0 +1,85 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("#include test\n");
+
+#if 1
+#if 0
+ printf("a\n");
+#else
+ printf("b\n");
+#endif
+#else
+#if 0
+ printf("c\n");
+#else
+ printf("d\n");
+#endif
+#endif
+
+#if 0
+#if 1
+ printf("e\n");
+#else
+ printf("f\n");
+#endif
+#else
+#if 1
+ printf("g\n");
+#else
+ printf("h\n");
+#endif
+#endif
+
+#define DEF
+
+#ifdef DEF
+#ifdef DEF
+ printf("i\n");
+#else
+ printf("j\n");
+#endif
+#else
+#ifdef DEF
+ printf("k\n");
+#else
+ printf("l\n");
+#endif
+#endif
+
+#ifndef DEF
+#ifndef DEF
+ printf("m\n");
+#else
+ printf("n\n");
+#endif
+#else
+#ifndef DEF
+ printf("o\n");
+#else
+ printf("p\n");
+#endif
+#endif
+
+#define ONE 1
+#define ZERO 0
+
+#if ONE
+#if ZERO
+ printf("q\n");
+#else
+ printf("r\n");
+#endif
+#else
+#if ZERO
+ printf("s\n");
+#else
+ printf("t\n");
+#endif
+#endif
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/41_hashif.expect b/tests/tests2/41_hashif.expect
new file mode 100644
index 0000000..5fd414b
--- /dev/null
+++ b/tests/tests2/41_hashif.expect
@@ -0,0 +1,6 @@
+#include test
+b
+g
+i
+p
+r
diff --git a/tests/tests2/42_function_pointer.c b/tests/tests2/42_function_pointer.c
new file mode 100644
index 0000000..697bd79
--- /dev/null
+++ b/tests/tests2/42_function_pointer.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+int fred(int p)
+{
+ printf("yo %d\n", p);
+ return 42;
+}
+
+int (*f)(int) = &fred;
+
+/* To test what this is supposed to test the destination function
+ (fprint here) must not be called directly anywhere in the test. */
+int (*fprintfptr)(FILE *, const char *, ...) = &fprintf;
+
+int main()
+{
+ fprintfptr(stdout, "%d\n", (*f)(24));
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/42_function_pointer.expect b/tests/tests2/42_function_pointer.expect
new file mode 100644
index 0000000..6c8b6ce
--- /dev/null
+++ b/tests/tests2/42_function_pointer.expect
@@ -0,0 +1,2 @@
+yo 24
+42
diff --git a/tests/tests2/43_void_param.c b/tests/tests2/43_void_param.c
new file mode 100644
index 0000000..de17098
--- /dev/null
+++ b/tests/tests2/43_void_param.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+void fred(void)
+{
+ printf("yo\n");
+}
+
+int main()
+{
+ fred();
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/43_void_param.expect b/tests/tests2/43_void_param.expect
new file mode 100644
index 0000000..092bfb9
--- /dev/null
+++ b/tests/tests2/43_void_param.expect
@@ -0,0 +1 @@
+yo
diff --git a/tests/tests2/44_scoped_declarations.c b/tests/tests2/44_scoped_declarations.c
new file mode 100644
index 0000000..f38664f
--- /dev/null
+++ b/tests/tests2/44_scoped_declarations.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main()
+{
+ int a;
+
+ for (a = 0; a < 2; a++)
+ {
+ int b = a;
+ }
+
+ printf("it's all good\n");
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/44_scoped_declarations.expect b/tests/tests2/44_scoped_declarations.expect
new file mode 100644
index 0000000..231ccc0
--- /dev/null
+++ b/tests/tests2/44_scoped_declarations.expect
@@ -0,0 +1 @@
+it's all good
diff --git a/tests/tests2/45_empty_for.c b/tests/tests2/45_empty_for.c
new file mode 100644
index 0000000..7cef513
--- /dev/null
+++ b/tests/tests2/45_empty_for.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main()
+{
+ int Count = 0;
+
+ for (;;)
+ {
+ Count++;
+ printf("%d\n", Count);
+ if (Count >= 10)
+ break;
+ }
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/45_empty_for.expect b/tests/tests2/45_empty_for.expect
new file mode 100644
index 0000000..f00c965
--- /dev/null
+++ b/tests/tests2/45_empty_for.expect
@@ -0,0 +1,10 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
diff --git a/tests/tests2/46_grep.c b/tests/tests2/46_grep.c
new file mode 100644
index 0000000..049dfb1
--- /dev/null
+++ b/tests/tests2/46_grep.c
@@ -0,0 +1,568 @@
+/*
+ * The information in this document is subject to change
+ * without notice and should not be construed as a commitment
+ * by Digital Equipment Corporation or by DECUS.
+ *
+ * Neither Digital Equipment Corporation, DECUS, nor the authors
+ * assume any responsibility for the use or reliability of this
+ * document or the described software.
+ *
+ * Copyright (C) 1980, DECUS
+ *
+ * General permission to copy or modify, but not for profit, is
+ * hereby granted, provided that the above copyright notice is
+ * included and reference made to the fact that reproduction
+ * privileges were granted by DECUS.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h> // tolower()
+
+/*
+ * grep
+ *
+ * Runs on the Decus compiler or on vms, On vms, define as:
+ * grep :== "$disk:[account]grep" (native)
+ * grep :== "$disk:[account]grep grep" (Decus)
+ * See below for more information.
+ */
+
+char *documentation[] = {
+ "grep searches a file for a given pattern. Execute by",
+ " grep [flags] regular_expression file_list\n",
+ "Flags are single characters preceded by '-':",
+ " -c Only a count of matching lines is printed",
+ " -f Print file name for matching lines switch, see below",
+ " -n Each line is preceded by its line number",
+ " -v Only print non-matching lines\n",
+ "The file_list is a list of files (wildcards are acceptable on RSX modes).",
+ "\nThe file name is normally printed if there is a file given.",
+ "The -f flag reverses this action (print name no file, not if more).\n",
+ 0 };
+
+char *patdoc[] = {
+ "The regular_expression defines the pattern to search for. Upper- and",
+ "lower-case are always ignored. Blank lines never match. The expression",
+ "should be quoted to prevent file-name translation.",
+ "x An ordinary character (not mentioned below) matches that character.",
+ "'\\' The backslash quotes any character. \"\\$\" matches a dollar-sign.",
+ "'^' A circumflex at the beginning of an expression matches the",
+ " beginning of a line.",
+ "'$' A dollar-sign at the end of an expression matches the end of a line.",
+ "'.' A period matches any character except \"new-line\".",
+ "':a' A colon matches a class of characters described by the following",
+ "':d' character. \":a\" matches any alphabetic, \":d\" matches digits,",
+ "':n' \":n\" matches alphanumerics, \": \" matches spaces, tabs, and",
+ "': ' other control characters, such as new-line.",
+ "'*' An expression followed by an asterisk matches zero or more",
+ " occurrences of that expression: \"fo*\" matches \"f\", \"fo\"",
+ " \"foo\", etc.",
+ "'+' An expression followed by a plus sign matches one or more",
+ " occurrences of that expression: \"fo+\" matches \"fo\", etc.",
+ "'-' An expression followed by a minus sign optionally matches",
+ " the expression.",
+ "'[]' A string enclosed in square brackets matches any character in",
+ " that string, but no others. If the first character in the",
+ " string is a circumflex, the expression matches any character",
+ " except \"new-line\" and the characters in the string. For",
+ " example, \"[xyz]\" matches \"xx\" and \"zyx\", while \"[^xyz]\"",
+ " matches \"abc\" but not \"axb\". A range of characters may be",
+ " specified by two characters separated by \"-\". Note that,",
+ " [a-z] matches alphabetics, while [z-a] never matches.",
+ "The concatenation of regular expressions is a regular expression.",
+ 0};
+
+#define LMAX 512
+#define PMAX 256
+
+#define CHAR 1
+#define BOL 2
+#define EOL 3
+#define ANY 4
+#define CLASS 5
+#define NCLASS 6
+#define STAR 7
+#define PLUS 8
+#define MINUS 9
+#define ALPHA 10
+#define DIGIT 11
+#define NALPHA 12
+#define PUNCT 13
+#define RANGE 14
+#define ENDPAT 15
+
+int cflag=0, fflag=0, nflag=0, vflag=0, nfile=0, debug=0;
+
+char *pp, lbuf[LMAX], pbuf[PMAX];
+
+char *cclass();
+char *pmatch();
+void store(int);
+void error(char *);
+void badpat(char *, char *, char *);
+int match(void);
+
+
+/*** Display a file name *******************************/
+void file(char *s)
+{
+ printf("File %s:\n", s);
+}
+
+/*** Report unopenable file ****************************/
+void cant(char *s)
+{
+ fprintf(stderr, "%s: cannot open\n", s);
+}
+
+/*** Give good help ************************************/
+void help(char **hp)
+{
+ char **dp;
+
+ for (dp = hp; *dp; ++dp)
+ printf("%s\n", *dp);
+}
+
+/*** Display usage summary *****************************/
+void usage(char *s)
+{
+ fprintf(stderr, "?GREP-E-%s\n", s);
+ fprintf(stderr,
+ "Usage: grep [-cfnv] pattern [file ...]. grep ? for help\n");
+ exit(1);
+}
+
+/*** Compile the pattern into global pbuf[] ************/
+void compile(char *source)
+{
+ char *s; /* Source string pointer */
+ char *lp; /* Last pattern pointer */
+ int c; /* Current character */
+ int o; /* Temp */
+ char *spp; /* Save beginning of pattern */
+
+ s = source;
+ if (debug)
+ printf("Pattern = \"%s\"\n", s);
+ pp = pbuf;
+ while (c = *s++) {
+ /*
+ * STAR, PLUS and MINUS are special.
+ */
+ if (c == '*' || c == '+' || c == '-') {
+ if (pp == pbuf ||
+ (o=pp[-1]) == BOL ||
+ o == EOL ||
+ o == STAR ||
+ o == PLUS ||
+ o == MINUS)
+ badpat("Illegal occurrence op.", source, s);
+ store(ENDPAT);
+ store(ENDPAT);
+ spp = pp; /* Save pattern end */
+ while (--pp > lp) /* Move pattern down */
+ *pp = pp[-1]; /* one byte */
+ *pp = (c == '*') ? STAR :
+ (c == '-') ? MINUS : PLUS;
+ pp = spp; /* Restore pattern end */
+ continue;
+ }
+ /*
+ * All the rest.
+ */
+ lp = pp; /* Remember start */
+ switch(c) {
+
+ case '^':
+ store(BOL);
+ break;
+
+ case '$':
+ store(EOL);
+ break;
+
+ case '.':
+ store(ANY);
+ break;
+
+ case '[':
+ s = cclass(source, s);
+ break;
+
+ case ':':
+ if (*s) {
+ switch(tolower(c = *s++)) {
+
+ case 'a':
+ case 'A':
+ store(ALPHA);
+ break;
+
+ case 'd':
+ case 'D':
+ store(DIGIT);
+ break;
+
+ case 'n':
+ case 'N':
+ store(NALPHA);
+ break;
+
+ case ' ':
+ store(PUNCT);
+ break;
+
+ default:
+ badpat("Unknown : type", source, s);
+
+ }
+ break;
+ }
+ else badpat("No : type", source, s);
+
+ case '\\':
+ if (*s)
+ c = *s++;
+
+ default:
+ store(CHAR);
+ store(tolower(c));
+ }
+ }
+ store(ENDPAT);
+ store(0); /* Terminate string */
+ if (debug) {
+ for (lp = pbuf; lp < pp;) {
+ if ((c = (*lp++ & 0377)) < ' ')
+ printf("\\%o ", c);
+ else printf("%c ", c);
+ }
+ printf("\n");
+ }
+}
+
+/*** Compile a class (within []) ***********************/
+char *cclass(char *source, char *src)
+ /* char *source; // Pattern start -- for error msg. */
+ /* char *src; // Class start */
+{
+ char *s; /* Source pointer */
+ char *cp; /* Pattern start */
+ int c; /* Current character */
+ int o; /* Temp */
+
+ s = src;
+ o = CLASS;
+ if (*s == '^') {
+ ++s;
+ o = NCLASS;
+ }
+ store(o);
+ cp = pp;
+ store(0); /* Byte count */
+ while ((c = *s++) && c!=']') {
+ if (c == '\\') { /* Store quoted char */
+ if ((c = *s++) == '\0') /* Gotta get something */
+ badpat("Class terminates badly", source, s);
+ else store(tolower(c));
+ }
+ else if (c == '-' &&
+ (pp - cp) > 1 && *s != ']' && *s != '\0') {
+ c = pp[-1]; /* Range start */
+ pp[-1] = RANGE; /* Range signal */
+ store(c); /* Re-store start */
+ c = *s++; /* Get end char and*/
+ store(tolower(c)); /* Store it */
+ }
+ else {
+ store(tolower(c)); /* Store normal char */
+ }
+ }
+ if (c != ']')
+ badpat("Unterminated class", source, s);
+ if ((c = (pp - cp)) >= 256)
+ badpat("Class too large", source, s);
+ if (c == 0)
+ badpat("Empty class", source, s);
+ *cp = c;
+ return(s);
+}
+
+/*** Store an entry in the pattern buffer **************/
+void store(int op)
+{
+ if (pp >= &pbuf[PMAX])
+ error("Pattern too complex\n");
+ *pp++ = op;
+}
+
+/*** Report a bad pattern specification ****************/
+void badpat(char *message, char *source, char *stop)
+ /* char *message; // Error message */
+ /* char *source; // Pattern start */
+ /* char *stop; // Pattern end */
+{
+ fprintf(stderr, "-GREP-E-%s, pattern is\"%s\"\n", message, source);
+ fprintf(stderr, "-GREP-E-Stopped at byte %ld, '%c'\n",
+ stop-source, stop[-1]);
+ error("?GREP-E-Bad pattern\n");
+}
+
+/*** Scan the file for the pattern in pbuf[] ***********/
+void grep(FILE *fp, char *fn)
+ /* FILE *fp; // File to process */
+ /* char *fn; // File name (for -f option) */
+{
+ int lno, count, m;
+
+ lno = 0;
+ count = 0;
+ while (fgets(lbuf, LMAX, fp)) {
+ ++lno;
+ m = match();
+ if ((m && !vflag) || (!m && vflag)) {
+ ++count;
+ if (!cflag) {
+ if (fflag && fn) {
+ file(fn);
+ fn = 0;
+ }
+ if (nflag)
+ printf("%d\t", lno);
+ printf("%s\n", lbuf);
+ }
+ }
+ }
+ if (cflag) {
+ if (fflag && fn)
+ file(fn);
+ printf("%d\n", count);
+ }
+}
+
+/*** Match line (lbuf) with pattern (pbuf) return 1 if match ***/
+int match()
+{
+ char *l; /* Line pointer */
+
+ for (l = lbuf; *l; ++l) {
+ if (pmatch(l, pbuf))
+ return(1);
+ }
+ return(0);
+}
+
+/*** Match partial line with pattern *******************/
+char *pmatch(char *line, char *pattern)
+ /* char *line; // (partial) line to match */
+ /* char *pattern; // (partial) pattern to match */
+{
+ char *l; /* Current line pointer */
+ char *p; /* Current pattern pointer */
+ char c; /* Current character */
+ char *e; /* End for STAR and PLUS match */
+ int op; /* Pattern operation */
+ int n; /* Class counter */
+ char *are; /* Start of STAR match */
+
+ l = line;
+ if (debug > 1)
+ printf("pmatch(\"%s\")\n", line);
+ p = pattern;
+ while ((op = *p++) != ENDPAT) {
+ if (debug > 1)
+ printf("byte[%ld] = 0%o, '%c', op = 0%o\n",
+ l-line, *l, *l, op);
+ switch(op) {
+
+ case CHAR:
+ if (tolower(*l++) != *p++)
+ return(0);
+ break;
+
+ case BOL:
+ if (l != lbuf)
+ return(0);
+ break;
+
+ case EOL:
+ if (*l != '\0')
+ return(0);
+ break;
+
+ case ANY:
+ if (*l++ == '\0')
+ return(0);
+ break;
+
+ case DIGIT:
+ if ((c = *l++) < '0' || (c > '9'))
+ return(0);
+ break;
+
+ case ALPHA:
+ c = tolower(*l++);
+ if (c < 'a' || c > 'z')
+ return(0);
+ break;
+
+ case NALPHA:
+ c = tolower(*l++);
+ if (c >= 'a' && c <= 'z')
+ break;
+ else if (c < '0' || c > '9')
+ return(0);
+ break;
+
+ case PUNCT:
+ c = *l++;
+ if (c == 0 || c > ' ')
+ return(0);
+ break;
+
+ case CLASS:
+ case NCLASS:
+ c = tolower(*l++);
+ n = *p++ & 0377;
+ do {
+ if (*p == RANGE) {
+ p += 3;
+ n -= 2;
+ if (c >= p[-2] && c <= p[-1])
+ break;
+ }
+ else if (c == *p++)
+ break;
+ } while (--n > 1);
+ if ((op == CLASS) == (n <= 1))
+ return(0);
+ if (op == CLASS)
+ p += n - 2;
+ break;
+
+ case MINUS:
+ e = pmatch(l, p); /* Look for a match */
+ while (*p++ != ENDPAT); /* Skip over pattern */
+ if (e) /* Got a match? */
+ l = e; /* Yes, update string */
+ break; /* Always succeeds */
+
+ case PLUS: /* One or more ... */
+ if ((l = pmatch(l, p)) == 0)
+ return(0); /* Gotta have a match */
+ case STAR: /* Zero or more ... */
+ are = l; /* Remember line start */
+ while (*l && (e = pmatch(l, p)))
+ l = e; /* Get longest match */
+ while (*p++ != ENDPAT); /* Skip over pattern */
+ while (l >= are) { /* Try to match rest */
+ if (e = pmatch(l, p))
+ return(e);
+ --l; /* Nope, try earlier */
+ }
+ return(0); /* Nothing else worked */
+
+ default:
+ printf("Bad op code %d\n", op);
+ error("Cannot happen -- match\n");
+ }
+ }
+ return(l);
+}
+
+/*** Report an error ***********************************/
+void error(char *s)
+{
+ fprintf(stderr, "%s", s);
+ exit(1);
+}
+
+/*** Main program - parse arguments & grep *************/
+int main(int argc, char **argv)
+{
+ char *p;
+ int c, i;
+ int gotpattern;
+
+ FILE *f;
+
+ if (argc <= 1)
+ usage("No arguments");
+ if (argc == 2 && argv[1][0] == '?' && argv[1][1] == 0) {
+ help(documentation);
+ help(patdoc);
+ return 0;
+ }
+ nfile = argc-1;
+ gotpattern = 0;
+ for (i=1; i < argc; ++i) {
+ p = argv[i];
+ if (*p == '-') {
+ ++p;
+ while (c = *p++) {
+ switch(tolower(c)) {
+
+ case '?':
+ help(documentation);
+ break;
+
+ case 'C':
+ case 'c':
+ ++cflag;
+ break;
+
+ case 'D':
+ case 'd':
+ ++debug;
+ break;
+
+ case 'F':
+ case 'f':
+ ++fflag;
+ break;
+
+ case 'n':
+ case 'N':
+ ++nflag;
+ break;
+
+ case 'v':
+ case 'V':
+ ++vflag;
+ break;
+
+ default:
+ usage("Unknown flag");
+ }
+ }
+ argv[i] = 0;
+ --nfile;
+ } else if (!gotpattern) {
+ compile(p);
+ argv[i] = 0;
+ ++gotpattern;
+ --nfile;
+ }
+ }
+ if (!gotpattern)
+ usage("No pattern");
+ if (nfile == 0)
+ grep(stdin, 0);
+ else {
+ fflag = fflag ^ (nfile > 0);
+ for (i=1; i < argc; ++i) {
+ if (p = argv[i]) {
+ if ((f=fopen(p, "r")) == NULL)
+ cant(p);
+ else {
+ grep(f, p);
+ fclose(f);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/46_grep.expect b/tests/tests2/46_grep.expect
new file mode 100644
index 0000000..e8a6791
--- /dev/null
+++ b/tests/tests2/46_grep.expect
@@ -0,0 +1,3 @@
+File 46_grep.c:
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
+
diff --git a/tests/tests2/47_switch_return.c b/tests/tests2/47_switch_return.c
new file mode 100644
index 0000000..1ec7924
--- /dev/null
+++ b/tests/tests2/47_switch_return.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+void fred(int x)
+{
+ switch (x)
+ {
+ case 1: printf("1\n"); return;
+ case 2: printf("2\n"); break;
+ case 3: printf("3\n"); return;
+ }
+
+ printf("out\n");
+}
+
+int main()
+{
+ fred(1);
+ fred(2);
+ fred(3);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/47_switch_return.expect b/tests/tests2/47_switch_return.expect
new file mode 100644
index 0000000..b6deb7e
--- /dev/null
+++ b/tests/tests2/47_switch_return.expect
@@ -0,0 +1,4 @@
+1
+2
+out
+3
diff --git a/tests/tests2/48_nested_break.c b/tests/tests2/48_nested_break.c
new file mode 100644
index 0000000..5bc5ba4
--- /dev/null
+++ b/tests/tests2/48_nested_break.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+int main()
+{
+ int a;
+ char b;
+
+ a = 0;
+ while (a < 2)
+ {
+ printf("%d", a++);
+ break;
+
+ b = 'A';
+ while (b < 'C')
+ {
+ printf("%c", b++);
+ }
+ printf("e");
+ }
+ printf("\n");
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/48_nested_break.expect b/tests/tests2/48_nested_break.expect
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/tests/tests2/48_nested_break.expect
@@ -0,0 +1 @@
+0
diff --git a/tests/tests2/49_bracket_evaluation.c b/tests/tests2/49_bracket_evaluation.c
new file mode 100644
index 0000000..0cbe57d
--- /dev/null
+++ b/tests/tests2/49_bracket_evaluation.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+struct point
+{
+ double x;
+ double y;
+};
+
+struct point point_array[100];
+
+int main()
+{
+ int my_point = 10;
+
+ point_array[my_point].x = 12.34;
+ point_array[my_point].y = 56.78;
+
+ printf("%f, %f\n", point_array[my_point].x, point_array[my_point].y);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/49_bracket_evaluation.expect b/tests/tests2/49_bracket_evaluation.expect
new file mode 100644
index 0000000..1da66db
--- /dev/null
+++ b/tests/tests2/49_bracket_evaluation.expect
@@ -0,0 +1 @@
+12.340000, 56.780000
diff --git a/tests/tests2/50_logical_second_arg.c b/tests/tests2/50_logical_second_arg.c
new file mode 100644
index 0000000..ddec08c
--- /dev/null
+++ b/tests/tests2/50_logical_second_arg.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+int fred()
+{
+ printf("fred\n");
+ return 0;
+}
+
+int joe()
+{
+ printf("joe\n");
+ return 1;
+}
+
+int main()
+{
+ printf("%d\n", fred() && joe());
+ printf("%d\n", fred() || joe());
+ printf("%d\n", joe() && fred());
+ printf("%d\n", joe() || fred());
+ printf("%d\n", fred() && (1 + joe()));
+ printf("%d\n", fred() || (0 + joe()));
+ printf("%d\n", joe() && (0 + fred()));
+ printf("%d\n", joe() || (1 + fred()));
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/50_logical_second_arg.expect b/tests/tests2/50_logical_second_arg.expect
new file mode 100644
index 0000000..d6174ae
--- /dev/null
+++ b/tests/tests2/50_logical_second_arg.expect
@@ -0,0 +1,20 @@
+fred
+0
+fred
+joe
+1
+joe
+fred
+0
+joe
+1
+fred
+0
+fred
+joe
+1
+joe
+fred
+0
+joe
+1
diff --git a/tests/tests2/51_static.c b/tests/tests2/51_static.c
new file mode 100644
index 0000000..d6c0917
--- /dev/null
+++ b/tests/tests2/51_static.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+static int fred = 1234;
+static int joe;
+
+void henry()
+{
+ static int fred = 4567;
+
+ printf("%d\n", fred);
+ fred++;
+}
+
+int main()
+{
+ printf("%d\n", fred);
+ henry();
+ henry();
+ henry();
+ henry();
+ printf("%d\n", fred);
+ fred = 8901;
+ joe = 2345;
+ printf("%d\n", fred);
+ printf("%d\n", joe);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/51_static.expect b/tests/tests2/51_static.expect
new file mode 100644
index 0000000..18224fa
--- /dev/null
+++ b/tests/tests2/51_static.expect
@@ -0,0 +1,8 @@
+1234
+4567
+4568
+4569
+4570
+1234
+8901
+2345
diff --git a/tests/tests2/52_unnamed_enum.c b/tests/tests2/52_unnamed_enum.c
new file mode 100644
index 0000000..d0395b2
--- /dev/null
+++ b/tests/tests2/52_unnamed_enum.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+
+enum fred { a, b, c };
+
+int main()
+{
+ printf("a=%d\n", a);
+ printf("b=%d\n", b);
+ printf("c=%d\n", c);
+
+ enum fred d;
+
+ typedef enum { e, f, g } h;
+ typedef enum { i, j, k } m;
+
+ printf("e=%d\n", e);
+ printf("f=%d\n", f);
+ printf("g=%d\n", g);
+
+ printf("i=%d\n", i);
+ printf("j=%d\n", j);
+ printf("k=%d\n", k);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/52_unnamed_enum.expect b/tests/tests2/52_unnamed_enum.expect
new file mode 100644
index 0000000..84f2ac8
--- /dev/null
+++ b/tests/tests2/52_unnamed_enum.expect
@@ -0,0 +1,9 @@
+a=0
+b=1
+c=2
+e=0
+f=1
+g=2
+i=0
+j=1
+k=2
diff --git a/tests/tests2/54_goto.c b/tests/tests2/54_goto.c
new file mode 100644
index 0000000..2e151bb
--- /dev/null
+++ b/tests/tests2/54_goto.c
@@ -0,0 +1,56 @@
+#include <stdio.h>
+
+void fred()
+{
+ printf("In fred()\n");
+ goto done;
+ printf("In middle\n");
+done:
+ printf("At end\n");
+}
+
+void joe()
+{
+ int b = 5678;
+
+ printf("In joe()\n");
+
+ {
+ int c = 1234;
+ printf("c = %d\n", c);
+ goto outer;
+ printf("uh-oh\n");
+ }
+
+outer:
+
+ printf("done\n");
+}
+
+void henry()
+{
+ int a;
+
+ printf("In henry()\n");
+ goto inner;
+
+ {
+ int b;
+inner:
+ b = 1234;
+ printf("b = %d\n", b);
+ }
+
+ printf("done\n");
+}
+
+int main()
+{
+ fred();
+ joe();
+ henry();
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/54_goto.expect b/tests/tests2/54_goto.expect
new file mode 100644
index 0000000..8e553fa
--- /dev/null
+++ b/tests/tests2/54_goto.expect
@@ -0,0 +1,8 @@
+In fred()
+At end
+In joe()
+c = 1234
+done
+In henry()
+b = 1234
+done
diff --git a/tests/tests2/55_lshift_type.c b/tests/tests2/55_lshift_type.c
new file mode 100644
index 0000000..aa3e51a
--- /dev/null
+++ b/tests/tests2/55_lshift_type.c
@@ -0,0 +1,52 @@
+/* $Id: lshift-type.c 53089 2012-07-06 11:18:26Z vinc17/ypig $
+
+Tests on left-shift type, written by Vincent Lefevre <vincent@vinc17.net>.
+
+ISO C99 TC3 says: [6.5.7#3] "The integer promotions are performed on
+each of the operands. The type of the result is that of the promoted
+left operand."
+*/
+
+#include <stdio.h>
+
+#define PTYPE(M) ((M) < 0 || -(M) < 0 ? -1 : 1) * (int) sizeof((M)+0)
+#define CHECK(X,T) check(#X, PTYPE(X), PTYPE((X) << (T) 1))
+#define TEST1(X,T) do { CHECK(X,T); CHECK(X,unsigned T); } while (0)
+#define TEST2(X) \
+ do \
+ { \
+ TEST1((X),short); \
+ TEST1((X),int); \
+ TEST1((X),long); \
+ TEST1((X),long long); \
+ } \
+ while (0)
+#define TEST3(X,T) do { TEST2((T)(X)); TEST2((unsigned T)(X)); } while (0)
+#define TEST4(X) \
+ do \
+ { \
+ TEST3((X),short); \
+ TEST3((X),int); \
+ TEST3((X),long); \
+ TEST3((X),long long); \
+ } \
+ while (0)
+
+static int debug, nfailed = 0;
+
+static void check (const char *s, int arg1, int shift)
+{
+ int failed = arg1 != shift;
+ if (debug || failed)
+ printf ("%s %d %d\n", s, arg1, shift);
+ nfailed += failed;
+}
+
+int main (int argc, char **argv)
+{
+ debug = argc > 1;
+ TEST4(1);
+ TEST4(-1);
+ printf ("%d test(s) failed\n", nfailed);
+ return nfailed != 0;
+}
diff --git a/tests/tests2/55_lshift_type.expect b/tests/tests2/55_lshift_type.expect
new file mode 100644
index 0000000..8523767
--- /dev/null
+++ b/tests/tests2/55_lshift_type.expect
@@ -0,0 +1 @@
+0 test(s) failed
diff --git a/tests/tests2/60_errors_and_warnings.c b/tests/tests2/60_errors_and_warnings.c
new file mode 100644
index 0000000..0028caf
--- /dev/null
+++ b/tests/tests2/60_errors_and_warnings.c
@@ -0,0 +1,51 @@
+#if defined test_56_btype_excess_1
+struct A {} int i;
+
+#elif defined test_57_btype_excess_2
+char int i;
+
+#elif defined test_58_function_redefinition
+int f(void) { return 0; }
+int f(void) { return 1; }
+
+#elif defined test_global_redefinition
+int xxx = 1;
+int xxx;
+int xxx = 2;
+
+#elif defined test_59_function_array
+int (*fct)[42](int x);
+
+#elif defined test_60_enum_redefinition
+enum color { RED, GREEN, BLUE };
+enum color { R, G, B };
+enum color c;
+
+#elif defined test_62_enumerator_redefinition
+enum color { RED, GREEN, BLUE };
+enum rgb { RED, G, B};
+enum color c = RED;
+
+#elif defined test_63_local_enumerator_redefinition
+enum {
+ FOO,
+ BAR
+};
+
+int main(void)
+{
+ enum {
+ FOO = 2,
+ BAR
+ };
+
+ return BAR - FOO;
+}
+
+#elif defined test_61_undefined_enum
+enum rgb3 c = 42;
+
+#elif defined test_74_non_const_init
+int i = i++;
+
+#endif
diff --git a/tests/tests2/60_errors_and_warnings.expect b/tests/tests2/60_errors_and_warnings.expect
new file mode 100644
index 0000000..ed6a690
--- /dev/null
+++ b/tests/tests2/60_errors_and_warnings.expect
@@ -0,0 +1,28 @@
+[test_56_btype_excess_1]
+60_errors_and_warnings.c:2: error: too many basic types
+
+[test_57_btype_excess_2]
+60_errors_and_warnings.c:5: error: too many basic types
+
+[test_58_function_redefinition]
+60_errors_and_warnings.c:9: error: redefinition of 'f'
+
+[test_global_redefinition]
+60_errors_and_warnings.c:14: error: redefinition of 'xxx'
+
+[test_59_function_array]
+60_errors_and_warnings.c:17: error: declaration of an array of functions
+
+[test_60_enum_redefinition]
+60_errors_and_warnings.c:21: error: struct/union/enum already defined
+
+[test_62_enumerator_redefinition]
+60_errors_and_warnings.c:26: error: redefinition of enumerator 'RED'
+
+[test_63_local_enumerator_redefinition]
+
+[test_61_undefined_enum]
+60_errors_and_warnings.c:46: error: unknown type size
+
+[test_74_non_const_init]
+60_errors_and_warnings.c:49: error: initializer element is not constant
diff --git a/tests/tests2/64_macro_nesting.c b/tests/tests2/64_macro_nesting.c
new file mode 100644
index 0000000..676e5d3
--- /dev/null
+++ b/tests/tests2/64_macro_nesting.c
@@ -0,0 +1,12 @@
+#include <stdio.h> // printf()
+
+#define CAT2(a,b) a##b
+#define CAT(a,b) CAT2(a,b)
+#define AB(x) CAT(x,y)
+
+int main(void)
+{
+ int xy = 42;
+ printf("%d\n", CAT(A,B)(x));
+ return 0;
+}
diff --git a/tests/tests2/64_macro_nesting.expect b/tests/tests2/64_macro_nesting.expect
new file mode 100644
index 0000000..d81cc07
--- /dev/null
+++ b/tests/tests2/64_macro_nesting.expect
@@ -0,0 +1 @@
+42
diff --git a/tests/tests2/67_macro_concat.c b/tests/tests2/67_macro_concat.c
new file mode 100644
index 0000000..c580d3a
--- /dev/null
+++ b/tests/tests2/67_macro_concat.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+#define P(A,B) A ## B ; bob
+#define Q(A,B) A ## B+
+
+int main(void)
+{
+ int bob, jim = 21;
+ bob = P(jim,) *= 2;
+ printf("jim: %d, bob: %d\n", jim, bob);
+ jim = 60 Q(+,)3;
+ printf("jim: %d\n", jim);
+ return 0;
+}
diff --git a/tests/tests2/67_macro_concat.expect b/tests/tests2/67_macro_concat.expect
new file mode 100644
index 0000000..8386c2d
--- /dev/null
+++ b/tests/tests2/67_macro_concat.expect
@@ -0,0 +1,2 @@
+jim: 21, bob: 42
+jim: 63
diff --git a/tests/tests2/70_floating_point_literals.c b/tests/tests2/70_floating_point_literals.c
new file mode 100644
index 0000000..012fb4f
--- /dev/null
+++ b/tests/tests2/70_floating_point_literals.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+
+int main()
+{
+ /* decimal floating constant */
+ float fa0 = .123f;
+ float fa1 = .123E12F;
+ float fa2 = .123e-12f;
+ float fa3 = .123e+12f;
+ printf("%f\n%f\n%f\n%f\n\n", fa0, fa1, fa2, fa3);
+
+ float fb0 = 123.123f;
+ float fb1 = 123.123E12F;
+ float fb2 = 123.123e-12f;
+ float fb3 = 123.123e+12f;
+ printf("%f\n%f\n%f\n%f\n\n", fb0, fb1, fb2, fb3);
+
+ float fc0 = 123.f;
+ float fc1 = 123.E12F;
+ float fc2 = 123.e-12f;
+ float fc3 = 123.e+12f;
+ printf("%f\n%f\n%f\n%f\n\n", fc0, fc1, fc2, fc3);
+
+ float fd0 = 123E12F;
+ float fd1 = 123e-12f;
+ float fd2 = 123e+12f;
+ printf("%f\n%f\n%f\n\n", fd0, fd1, fd2);
+ printf("\n");
+
+ /* hexadecimal floating constant */
+ double da0 = 0X.1ACP12;
+ double da1 = 0x.1acp-12;
+ double da2 = 0x.1acp+12;
+ printf("%f\n%f\n%f\n\n", da0, da1, da2);
+
+ double db0 = 0X1AC.BDP12;
+ double db1 = 0x1ac.bdp-12;
+ double db2 = 0x1ac.dbp+12;
+ printf("%f\n%f\n%f\n\n", db0, db1, db2);
+
+ double dc0 = 0X1AC.P12;
+ double dc1 = 0x1ac.p-12;
+ double dc2 = 0x1ac.p+12;
+ printf("%f\n%f\n%f\n\n", dc0, dc1, dc2);
+
+ double dd0 = 0X1ACP12;
+ double dd1 = 0x1acp-12;
+ double dd2 = 0x1acp+12;
+ printf("%f\n%f\n%f\n\n", dd0, dd1, dd2);
+ printf("\n");
+
+#ifdef __TINYC__
+ /* TCC extension
+ binary floating constant */
+ long double la0 = 0B.110101100P12L;
+ long double la1 = 0b.110101100p-12l;
+ long double la2 = 0b.110101100p+12l;
+ printf("%Lf\n%Lf\n%Lf\n\n", la0, la1, la2);
+
+ long double lb0 = 0B110101100.10111101P12L;
+ long double lb1 = 0b110101100.10111101p-12l;
+ long double lb2 = 0b110101100.10111101p+12l;
+ printf("%Lf\n%Lf\n%Lf\n\n", lb0, lb1, lb2);
+
+ long double lc0 = 0B110101100.P12L;
+ long double lc1 = 0b110101100.p-12l;
+ long double lc2 = 0b110101100.p+12l;
+ printf("%Lf\n%Lf\n%Lf\n\n", lc0, lc1, lc2);
+
+ long double ld0 = 0B110101100P12L;
+ long double ld1 = 0b110101100p-12l;
+ long double ld2 = 0b110101100p+12l;
+ printf("%Lf\n%Lf\n%Lf\n\n", ld0, ld1, ld2);
+#endif
+
+ return 0;
+}
diff --git a/tests/tests2/70_floating_point_literals.expect b/tests/tests2/70_floating_point_literals.expect
new file mode 100644
index 0000000..7eb1efb
--- /dev/null
+++ b/tests/tests2/70_floating_point_literals.expect
@@ -0,0 +1,53 @@
+0.123000
+122999996416.000000
+0.000000
+122999996416.000000
+
+123.123001
+123122997002240.000000
+0.000000
+123122997002240.000000
+
+123.000000
+123000003231744.000000
+0.000000
+123000003231744.000000
+
+123000003231744.000000
+0.000000
+123000003231744.000000
+
+
+428.000000
+0.000026
+428.000000
+
+1756112.000000
+0.104672
+1756592.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
+
+3424.000000
+0.000204
+3424.000000
+
+1756112.000000
+0.104672
+1756112.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
diff --git a/tests/tests2/71_macro_empty_arg.c b/tests/tests2/71_macro_empty_arg.c
new file mode 100644
index 0000000..f0d3511
--- /dev/null
+++ b/tests/tests2/71_macro_empty_arg.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+#define T(a,b,c) a b c
+
+int main(void)
+{
+ printf("%d", T(1,+,2) T(+,,) T(,2,*) T(,7,) T(,,));
+ return 0;
+}
diff --git a/tests/tests2/71_macro_empty_arg.expect b/tests/tests2/71_macro_empty_arg.expect
new file mode 100644
index 0000000..98d9bcb
--- /dev/null
+++ b/tests/tests2/71_macro_empty_arg.expect
@@ -0,0 +1 @@
+17
diff --git a/tests/tests2/72_long_long_constant.c b/tests/tests2/72_long_long_constant.c
new file mode 100644
index 0000000..6608213
--- /dev/null
+++ b/tests/tests2/72_long_long_constant.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+
+int main()
+{
+ long long int res = 0;
+
+ if (res < -2147483648LL) {
+ printf("Error: 0 < -2147483648\n");
+ return 1;
+ }
+ else
+ if (2147483647LL < res) {
+ printf("Error: 2147483647 < 0\n");
+ return 2;
+ }
+ else
+ printf("long long constant test ok.\n");
+ return 0;
+}
diff --git a/tests/tests2/72_long_long_constant.expect b/tests/tests2/72_long_long_constant.expect
new file mode 100644
index 0000000..dda9e66
--- /dev/null
+++ b/tests/tests2/72_long_long_constant.expect
@@ -0,0 +1 @@
+long long constant test ok.
diff --git a/tests/tests2/73_arm64.c b/tests/tests2/73_arm64.c
new file mode 100644
index 0000000..8de61b3
--- /dev/null
+++ b/tests/tests2/73_arm64.c
@@ -0,0 +1,527 @@
+// This program is designed to test some arm64-specific things, such as the
+// calling convention, but should give the same results on any architecture.
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+
+struct s1 { char x[1]; } s1 = { "0" };
+struct s2 { char x[2]; } s2 = { "12" };
+struct s3 { char x[3]; } s3 = { "345" };
+struct s4 { char x[4]; } s4 = { "6789" };
+struct s5 { char x[5]; } s5 = { "abcde" };
+struct s6 { char x[6]; } s6 = { "fghijk" };
+struct s7 { char x[7]; } s7 = { "lmnopqr" };
+struct s8 { char x[8]; } s8 = { "stuvwxyz" };
+struct s9 { char x[9]; } s9 = { "ABCDEFGHI" };
+struct s10 { char x[10]; } s10 = { "JKLMNOPQRS" };
+struct s11 { char x[11]; } s11 = { "TUVWXYZ0123" };
+struct s12 { char x[12]; } s12 = { "456789abcdef" };
+struct s13 { char x[13]; } s13 = { "ghijklmnopqrs" };
+struct s14 { char x[14]; } s14 = { "tuvwxyzABCDEFG" };
+struct s15 { char x[15]; } s15 = { "HIJKLMNOPQRSTUV" };
+struct s16 { char x[16]; } s16 = { "WXYZ0123456789ab" };
+struct s17 { char x[17]; } s17 = { "cdefghijklmnopqrs" };
+
+struct hfa11 { float a; } hfa11 = { 11.1 };
+struct hfa12 { float a, b; } hfa12 = { 12.1, 12.2 };
+struct hfa13 { float a, b, c; } hfa13 = { 13.1, 13.2, 13.3 };
+struct hfa14 { float a, b, c, d; } hfa14 = { 14.1, 14.2, 14.3, 14.4 };
+
+struct hfa21 { double a; } hfa21 = { 21.1 };
+struct hfa22 { double a, b; } hfa22 = { 22.1, 22.2 };
+struct hfa23 { double a, b, c; } hfa23 = { 23.1, 23.2, 23.3 };
+struct hfa24 { double a, b, c, d; } hfa24 = { 24.1, 24.2, 24.3, 24.4 };
+
+struct hfa31 { long double a; } hfa31 = { 31.1 };
+struct hfa32 { long double a, b; } hfa32 = { 32.1, 32.2 };
+struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 };
+struct hfa34 { long double a, b, c, d; } hfa34 = { 34.1, 34.2, 34.3, 34.4 };
+
+void fa_s1(struct s1 a) { printf("%.1s\n", a.x); }
+void fa_s2(struct s2 a) { printf("%.2s\n", a.x); }
+void fa_s3(struct s3 a) { printf("%.3s\n", a.x); }
+void fa_s4(struct s4 a) { printf("%.4s\n", a.x); }
+void fa_s5(struct s5 a) { printf("%.5s\n", a.x); }
+void fa_s6(struct s6 a) { printf("%.6s\n", a.x); }
+void fa_s7(struct s7 a) { printf("%.7s\n", a.x); }
+void fa_s8(struct s8 a) { printf("%.8s\n", a.x); }
+void fa_s9(struct s9 a) { printf("%.9s\n", a.x); }
+void fa_s10(struct s10 a) { printf("%.10s\n", a.x); }
+void fa_s11(struct s11 a) { printf("%.11s\n", a.x); }
+void fa_s12(struct s12 a) { printf("%.12s\n", a.x); }
+void fa_s13(struct s13 a) { printf("%.13s\n", a.x); }
+void fa_s14(struct s14 a) { printf("%.14s\n", a.x); }
+void fa_s15(struct s15 a) { printf("%.15s\n", a.x); }
+void fa_s16(struct s16 a) { printf("%.16s\n", a.x); }
+void fa_s17(struct s17 a) { printf("%.17s\n", a.x); }
+
+void fa_hfa11(struct hfa11 a)
+{ printf("%.1f\n", a.a); }
+void fa_hfa12(struct hfa12 a)
+{ printf("%.1f %.1f\n", a.a, a.a); }
+void fa_hfa13(struct hfa13 a)
+{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); }
+void fa_hfa14(struct hfa14 a)
+{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); }
+
+void fa_hfa21(struct hfa21 a)
+{ printf("%.1f\n", a.a); }
+void fa_hfa22(struct hfa22 a)
+{ printf("%.1f %.1f\n", a.a, a.a); }
+void fa_hfa23(struct hfa23 a)
+{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); }
+void fa_hfa24(struct hfa24 a)
+{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); }
+
+void fa_hfa31(struct hfa31 a)
+{ printf("%.1Lf\n", a.a); }
+void fa_hfa32(struct hfa32 a)
+{ printf("%.1Lf %.1Lf\n", a.a, a.a); }
+void fa_hfa33(struct hfa33 a)
+{ printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); }
+void fa_hfa34(struct hfa34 a)
+{ printf("%.1Lf %.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c, a.d); }
+
+void fa1(struct s8 a, struct s9 b, struct s10 c, struct s11 d,
+ struct s12 e, struct s13 f)
+{
+ printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x);
+}
+
+void fa2(struct s9 a, struct s10 b, struct s11 c, struct s12 d,
+ struct s13 e, struct s14 f)
+{
+ printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x);
+}
+
+void fa3(struct hfa14 a, struct hfa23 b, struct hfa32 c)
+{
+ printf("%.1f %.1f %.1f %.1f %.1Lf %.1Lf\n",
+ a.a, a.d, b.a, b.c, c.a, c.b);
+}
+
+void fa4(struct s1 a, struct hfa14 b, struct s2 c, struct hfa24 d,
+ struct s3 e, struct hfa34 f)
+{
+ printf("%.1s %.1f %.1f %.2s %.1f %.1f %.3s %.1Lf %.1Lf\n",
+ a.x, b.a, b.d, c.x, d.a, d.d, e.x, f.a, f.d);
+}
+
+void arg(void)
+{
+ printf("Arguments:\n");
+ fa_s1(s1);
+ fa_s2(s2);
+ fa_s3(s3);
+ fa_s4(s4);
+ fa_s5(s5);
+ fa_s6(s6);
+ fa_s7(s7);
+ fa_s8(s8);
+ fa_s9(s9);
+ fa_s10(s10);
+ fa_s11(s11);
+ fa_s12(s12);
+ fa_s13(s13);
+ fa_s14(s14);
+ fa_s15(s15);
+ fa_s16(s16);
+ fa_s17(s17);
+ fa_hfa11(hfa11);
+ fa_hfa12(hfa12);
+ fa_hfa13(hfa13);
+ fa_hfa14(hfa14);
+ fa_hfa21(hfa21);
+ fa_hfa22(hfa22);
+ fa_hfa23(hfa23);
+ fa_hfa24(hfa24);
+ fa_hfa31(hfa31);
+ fa_hfa32(hfa32);
+ fa_hfa33(hfa33);
+ fa_hfa34(hfa34);
+ fa1(s8, s9, s10, s11, s12, s13);
+ fa2(s9, s10, s11, s12, s13, s14);
+ fa3(hfa14, hfa23, hfa32);
+ fa4(s1, hfa14, s2, hfa24, s3, hfa34);
+}
+
+struct s1 fr_s1(void) { return s1; }
+struct s2 fr_s2(void) { return s2; }
+struct s3 fr_s3(void) { return s3; }
+struct s4 fr_s4(void) { return s4; }
+struct s5 fr_s5(void) { return s5; }
+struct s6 fr_s6(void) { return s6; }
+struct s7 fr_s7(void) { return s7; }
+struct s8 fr_s8(void) { return s8; }
+struct s9 fr_s9(void) { return s9; }
+struct s10 fr_s10(void) { return s10; }
+struct s11 fr_s11(void) { return s11; }
+struct s12 fr_s12(void) { return s12; }
+struct s13 fr_s13(void) { return s13; }
+struct s14 fr_s14(void) { return s14; }
+struct s15 fr_s15(void) { return s15; }
+struct s16 fr_s16(void) { return s16; }
+struct s17 fr_s17(void) { return s17; }
+
+struct hfa11 fr_hfa11(void) { return hfa11; }
+struct hfa12 fr_hfa12(void) { return hfa12; }
+struct hfa13 fr_hfa13(void) { return hfa13; }
+struct hfa14 fr_hfa14(void) { return hfa14; }
+
+struct hfa21 fr_hfa21(void) { return hfa21; }
+struct hfa22 fr_hfa22(void) { return hfa22; }
+struct hfa23 fr_hfa23(void) { return hfa23; }
+struct hfa24 fr_hfa24(void) { return hfa24; }
+
+struct hfa31 fr_hfa31(void) { return hfa31; }
+struct hfa32 fr_hfa32(void) { return hfa32; }
+struct hfa33 fr_hfa33(void) { return hfa33; }
+struct hfa34 fr_hfa34(void) { return hfa34; }
+
+void ret(void)
+{
+ struct s1 t1 = fr_s1();
+ struct s2 t2 = fr_s2();
+ struct s3 t3 = fr_s3();
+ struct s4 t4 = fr_s4();
+ struct s5 t5 = fr_s5();
+ struct s6 t6 = fr_s6();
+ struct s7 t7 = fr_s7();
+ struct s8 t8 = fr_s8();
+ struct s9 t9 = fr_s9();
+ struct s10 t10 = fr_s10();
+ struct s11 t11 = fr_s11();
+ struct s12 t12 = fr_s12();
+ struct s13 t13 = fr_s13();
+ struct s14 t14 = fr_s14();
+ struct s15 t15 = fr_s15();
+ struct s16 t16 = fr_s16();
+ struct s17 t17 = fr_s17();
+ printf("Return values:\n");
+ printf("%.1s\n", t1.x);
+ printf("%.2s\n", t2.x);
+ printf("%.3s\n", t3.x);
+ printf("%.4s\n", t4.x);
+ printf("%.5s\n", t5.x);
+ printf("%.6s\n", t6.x);
+ printf("%.7s\n", t7.x);
+ printf("%.8s\n", t8.x);
+ printf("%.9s\n", t9.x);
+ printf("%.10s\n", t10.x);
+ printf("%.11s\n", t11.x);
+ printf("%.12s\n", t12.x);
+ printf("%.13s\n", t13.x);
+ printf("%.14s\n", t14.x);
+ printf("%.15s\n", t15.x);
+ printf("%.16s\n", t16.x);
+ printf("%.17s\n", t17.x);
+ printf("%.1f\n", fr_hfa11().a);
+ printf("%.1f %.1f\n", fr_hfa12().a, fr_hfa12().b);
+ printf("%.1f %.1f\n", fr_hfa13().a, fr_hfa13().c);
+ printf("%.1f %.1f\n", fr_hfa14().a, fr_hfa14().d);
+ printf("%.1f\n", fr_hfa21().a);
+ printf("%.1f %.1f\n", fr_hfa22().a, fr_hfa22().b);
+ printf("%.1f %.1f\n", fr_hfa23().a, fr_hfa23().c);
+ printf("%.1f %.1f\n", fr_hfa24().a, fr_hfa24().d);
+ printf("%.1Lf\n", fr_hfa31().a);
+ printf("%.1Lf %.1Lf\n", fr_hfa32().a, fr_hfa32().b);
+ printf("%.1Lf %.1Lf\n", fr_hfa33().a, fr_hfa33().c);
+ printf("%.1Lf %.1Lf\n", fr_hfa34().a, fr_hfa34().d);
+}
+
+int match(const char **s, const char *f)
+{
+ const char *p = *s;
+ for (p = *s; *f && *f == *p; f++, p++)
+ ;
+ if (!*f) {
+ *s = p - 1;
+ return 1;
+ }
+ return 0;
+}
+
+void myprintf(const char *format, ...)
+{
+ const char *s;
+ va_list ap;
+ va_start(ap, format);
+ for (s = format; *s; s++) {
+ if (match(&s, "%7s")) {
+ struct s7 t7 = va_arg(ap, struct s7);
+ printf("%.7s", t7.x);
+ }
+ else if (match(&s, "%9s")) {
+ struct s9 t9 = va_arg(ap, struct s9);
+ printf("%.9s", t9.x);
+ }
+ else if (match(&s, "%hfa11")) {
+ struct hfa11 x = va_arg(ap, struct hfa11);
+ printf("%.1f,%.1f", x.a, x.a);
+ }
+ else if (match(&s, "%hfa12")) {
+ struct hfa12 x = va_arg(ap, struct hfa12);
+ printf("%.1f,%.1f", x.a, x.b);
+ }
+ else if (match(&s, "%hfa13")) {
+ struct hfa13 x = va_arg(ap, struct hfa13);
+ printf("%.1f,%.1f", x.a, x.c);
+ }
+ else if (match(&s, "%hfa14")) {
+ struct hfa14 x = va_arg(ap, struct hfa14);
+ printf("%.1f,%.1f", x.a, x.d);
+ }
+ else if (match(&s, "%hfa21")) {
+ struct hfa21 x = va_arg(ap, struct hfa21);
+ printf("%.1f,%.1f", x.a, x.a);
+ }
+ else if (match(&s, "%hfa22")) {
+ struct hfa22 x = va_arg(ap, struct hfa22);
+ printf("%.1f,%.1f", x.a, x.b);
+ }
+ else if (match(&s, "%hfa23")) {
+ struct hfa23 x = va_arg(ap, struct hfa23);
+ printf("%.1f,%.1f", x.a, x.c);
+ }
+ else if (match(&s, "%hfa24")) {
+ struct hfa24 x = va_arg(ap, struct hfa24);
+ printf("%.1f,%.1f", x.a, x.d);
+ }
+ else if (match(&s, "%hfa31")) {
+ struct hfa31 x = va_arg(ap, struct hfa31);
+ printf("%.1Lf,%.1Lf", x.a, x.a);
+ }
+ else if (match(&s, "%hfa32")) {
+ struct hfa32 x = va_arg(ap, struct hfa32);
+ printf("%.1Lf,%.1Lf", x.a, x.b);
+ }
+ else if (match(&s, "%hfa33")) {
+ struct hfa33 x = va_arg(ap, struct hfa33);
+ printf("%.1Lf,%.1Lf", x.a, x.c);
+ }
+ else if (match(&s, "%hfa34")) {
+ struct hfa34 x = va_arg(ap, struct hfa34);
+ printf("%.1Lf,%.1Lf", x.a, x.d);
+ }
+ else
+ putchar(*s);
+ }
+ putchar('\n');
+}
+
+void stdarg(void)
+{
+ printf("stdarg:\n");
+ myprintf("%9s %9s %9s %9s %9s %9s", s9, s9, s9, s9, s9, s9);
+ myprintf("%7s %9s %9s %9s %9s %9s", s7, s9, s9, s9, s9, s9);
+
+ myprintf("HFA long double:");
+ myprintf("%hfa34 %hfa34 %hfa34 %hfa34", hfa34, hfa34, hfa34, hfa34);
+ myprintf("%hfa33 %hfa34 %hfa34 %hfa34", hfa33, hfa34, hfa34, hfa34);
+ myprintf("%hfa32 %hfa34 %hfa34 %hfa34", hfa32, hfa34, hfa34, hfa34);
+ myprintf("%hfa31 %hfa34 %hfa34 %hfa34", hfa31, hfa34, hfa34, hfa34);
+
+ myprintf("%hfa32 %hfa33 %hfa33 %hfa33 %hfa33",
+ hfa32, hfa33, hfa33, hfa33, hfa33);
+ myprintf("%hfa31 %hfa33 %hfa33 %hfa33 %hfa33",
+ hfa31, hfa33, hfa33, hfa33, hfa33);
+ myprintf("%hfa33 %hfa33 %hfa33 %hfa33",
+ hfa33, hfa33, hfa33, hfa33);
+
+ myprintf("%hfa34 %hfa32 %hfa32 %hfa32 %hfa32",
+ hfa34, hfa32, hfa32, hfa32, hfa32);
+ myprintf("%hfa33 %hfa32 %hfa32 %hfa32 %hfa32",
+ hfa33, hfa32, hfa32, hfa32, hfa32);
+
+ myprintf("%hfa34 %hfa32 %hfa31 %hfa31 %hfa31 %hfa31",
+ hfa34, hfa32, hfa31, hfa31, hfa31, hfa31);
+
+ myprintf("HFA double:");
+ myprintf("%hfa24 %hfa24 %hfa24 %hfa24", hfa24, hfa24, hfa24, hfa24);
+ myprintf("%hfa23 %hfa24 %hfa24 %hfa24", hfa23, hfa24, hfa24, hfa24);
+ myprintf("%hfa22 %hfa24 %hfa24 %hfa24", hfa22, hfa24, hfa24, hfa24);
+ myprintf("%hfa21 %hfa24 %hfa24 %hfa24", hfa21, hfa24, hfa24, hfa24);
+
+ myprintf("%hfa22 %hfa23 %hfa23 %hfa23 %hfa23",
+ hfa22, hfa23, hfa23, hfa23, hfa23);
+ myprintf("%hfa21 %hfa23 %hfa23 %hfa23 %hfa23",
+ hfa21, hfa23, hfa23, hfa23, hfa23);
+ myprintf("%hfa23 %hfa23 %hfa23 %hfa23",
+ hfa23, hfa23, hfa23, hfa23);
+
+ myprintf("%hfa24 %hfa22 %hfa22 %hfa22 %hfa22",
+ hfa24, hfa22, hfa22, hfa22, hfa22);
+ myprintf("%hfa23 %hfa22 %hfa22 %hfa22 %hfa22",
+ hfa23, hfa22, hfa22, hfa22, hfa22);
+
+ myprintf("%hfa24 %hfa22 %hfa21 %hfa21 %hfa21 %hfa21",
+ hfa24, hfa22, hfa21, hfa21, hfa21, hfa21);
+
+ myprintf("HFA float:");
+ myprintf("%hfa14 %hfa14 %hfa14 %hfa14", hfa14, hfa14, hfa14, hfa14);
+ myprintf("%hfa13 %hfa14 %hfa14 %hfa14", hfa13, hfa14, hfa14, hfa14);
+ myprintf("%hfa12 %hfa14 %hfa14 %hfa14", hfa12, hfa14, hfa14, hfa14);
+ myprintf("%hfa11 %hfa14 %hfa14 %hfa14", hfa11, hfa14, hfa14, hfa14);
+
+ myprintf("%hfa12 %hfa13 %hfa13 %hfa13 %hfa13",
+ hfa12, hfa13, hfa13, hfa13, hfa13);
+ myprintf("%hfa11 %hfa13 %hfa13 %hfa13 %hfa13",
+ hfa11, hfa13, hfa13, hfa13, hfa13);
+ myprintf("%hfa13 %hfa13 %hfa13 %hfa13",
+ hfa13, hfa13, hfa13, hfa13);
+
+ myprintf("%hfa14 %hfa12 %hfa12 %hfa12 %hfa12",
+ hfa14, hfa12, hfa12, hfa12, hfa12);
+ myprintf("%hfa13 %hfa12 %hfa12 %hfa12 %hfa12",
+ hfa13, hfa12, hfa12, hfa12, hfa12);
+
+ myprintf("%hfa14 %hfa12 %hfa11 %hfa11 %hfa11 %hfa11",
+ hfa14, hfa12, hfa11, hfa11, hfa11, hfa11);
+}
+
+void pll(unsigned long long x)
+{
+ printf("%llx\n", x);
+}
+
+void movi(void)
+{
+ printf("MOVI:\n");
+ pll(0);
+ pll(0xabcd);
+ pll(0xabcd0000);
+ pll(0xabcd00000000);
+ pll(0xabcd000000000000);
+ pll(0xffffabcd);
+ pll(0xabcdffff);
+ pll(0xffffffffffffabcd);
+ pll(0xffffffffabcdffff);
+ pll(0xffffabcdffffffff);
+ pll(0xabcdffffffffffff);
+ pll(0xaaaaaaaa);
+ pll(0x5555555555555555);
+ pll(0x77777777);
+ pll(0x3333333333333333);
+ pll(0xf8f8f8f8);
+ pll(0x1e1e1e1e1e1e1e1e);
+ pll(0x3f803f80);
+ pll(0x01ff01ff01ff01ff);
+ pll(0x007fffc0);
+ pll(0x03fff80003fff800);
+ pll(0x0007fffffffffe00);
+
+ pll(0xabcd1234);
+ pll(0xabcd00001234);
+ pll(0xabcd000000001234);
+ pll(0xabcd12340000);
+ pll(0xabcd000012340000);
+ pll(0xabcd123400000000);
+ pll(0xffffffffabcd1234);
+ pll(0xffffabcdffff1234);
+ pll(0xabcdffffffff1234);
+ pll(0xffffabcd1234ffff);
+ pll(0xabcdffff1234ffff);
+ pll(0xabcd1234ffffffff);
+
+ pll(0xffffef0123456789);
+ pll(0xabcdef012345ffff);
+
+ pll(0xabcdef0123456789);
+}
+
+static uint32_t addip0(uint32_t x) { return x + 0; }
+static uint64_t sublp0(uint64_t x) { return x - 0; }
+static uint32_t addip123(uint32_t x) { return x + 123; }
+static uint64_t addlm123(uint64_t x) { return x + -123; }
+static uint64_t sublp4095(uint64_t x) { return x - 4095; }
+static uint32_t subim503808(uint32_t x) { return x - -503808; }
+static uint64_t addp12345(uint64_t x) { return x + 12345; }
+static uint32_t subp12345(uint32_t x) { return x - 12345; }
+
+static uint32_t mvni(uint32_t x) { return 0xffffffff - x; }
+static uint64_t negl(uint64_t x) { return 0 - x; }
+static uint32_t rsbi123(uint32_t x) { return 123 - x; }
+static uint64_t rsbl123(uint64_t x) { return 123 - x; }
+
+static uint32_t andi0(uint32_t x) { return x & 0; }
+static uint64_t andlm1(uint64_t x) { return x & -1; }
+static uint64_t orrl0(uint64_t x) { return x | 0; }
+static uint32_t orrim1(uint32_t x) { return x | -1; }
+static uint32_t eori0(uint32_t x) { return x ^ 0; }
+static uint64_t eorlm1(uint64_t x) { return x ^ -1; }
+static uint32_t and0xf0(uint32_t x) { return x & 0xf0; }
+static uint64_t orr0xf0(uint64_t x) { return x | 0xf0; }
+static uint64_t eor0xf0(uint64_t x) { return x ^ 0xf0; }
+
+static uint32_t lsli0(uint32_t x) { return x << 0; }
+static uint32_t lsri0(uint32_t x) { return x >> 0; }
+static int64_t asrl0(int64_t x) { return x >> 0; }
+static uint32_t lsli1(uint32_t x) { return x << 1; }
+static uint32_t lsli31(uint32_t x) { return x << 31; }
+static uint64_t lsll1(uint64_t x) { return x << 1; }
+static uint64_t lsll63(uint64_t x) { return x << 63; }
+static uint32_t lsri1(uint32_t x) { return x >> 1; }
+static uint32_t lsri31(uint32_t x) { return x >> 31; }
+static uint64_t lsrl1(uint64_t x) { return x >> 1; }
+static uint64_t lsrl63(uint64_t x) { return x >> 63; }
+static int32_t asri1(int32_t x) { return x >> 1; }
+static int32_t asri31(int32_t x) { return x >> 31; }
+static int64_t asrl1(int64_t x) { return x >> 1; }
+static int64_t asrl63(int64_t x) { return x >> 63; }
+
+void opi(void)
+{
+ int x = 1000;
+ pll(addip0(x));
+ pll(sublp0(x));
+ pll(addip123(x));
+ pll(addlm123(x));
+ pll(sublp4095(x));
+ pll(subim503808(x));
+ pll(addp12345(x));
+ pll(subp12345(x));
+ pll(mvni(x));
+ pll(negl(x));
+ pll(rsbi123(x));
+ pll(rsbl123(x));
+ pll(andi0(x));
+ pll(andlm1(x));
+ pll(orrl0(x));
+ pll(orrim1(x));
+ pll(eori0(x));
+ pll(eorlm1(x));
+ pll(and0xf0(x));
+ pll(orr0xf0(x));
+ pll(eor0xf0(x));
+ pll(lsli0(x));
+ pll(lsri0(x));
+ pll(asrl0(x));
+ pll(lsli1(x));
+ pll(lsli31(x));
+ pll(lsll1(x));
+ pll(lsll63(x));
+ pll(lsri1(x));
+ pll(lsri31(x));
+ pll(lsrl1(x));
+ pll(lsrl63(x));
+ pll(asri1(x));
+ pll(asri31(x));
+ pll(asrl1(x));
+ pll(asrl63(x));
+}
+
+void pcs(void)
+{
+ arg();
+ ret();
+ stdarg();
+ movi();
+ opi();
+}
+
+int main()
+{
+ pcs();
+ return 0;
+}
diff --git a/tests/tests2/73_arm64.expect b/tests/tests2/73_arm64.expect
new file mode 100644
index 0000000..7bdebd3
--- /dev/null
+++ b/tests/tests2/73_arm64.expect
@@ -0,0 +1,174 @@
+Arguments:
+0
+12
+345
+6789
+abcde
+fghijk
+lmnopqr
+stuvwxyz
+ABCDEFGHI
+JKLMNOPQRS
+TUVWXYZ0123
+456789abcdef
+ghijklmnopqrs
+tuvwxyzABCDEFG
+HIJKLMNOPQRSTUV
+WXYZ0123456789ab
+cdefghijklmnopqrs
+11.1
+12.1 12.1
+13.1 13.2 13.3
+14.1 14.2 14.3 14.4
+21.1
+22.1 22.1
+23.1 23.2 23.3
+24.1 24.2 24.3 24.4
+31.1
+32.1 32.1
+33.1 33.2 33.3
+34.1 34.2 34.3 34.4
+stu ABC JKL TUV 456 ghi
+ABC JKL TUV 456 ghi tuv
+14.1 14.4 23.1 23.3 32.1 32.2
+0 14.1 14.4 12 24.1 24.4 345 34.1 34.4
+Return values:
+0
+12
+345
+6789
+abcde
+fghijk
+lmnopqr
+stuvwxyz
+ABCDEFGHI
+JKLMNOPQRS
+TUVWXYZ0123
+456789abcdef
+ghijklmnopqrs
+tuvwxyzABCDEFG
+HIJKLMNOPQRSTUV
+WXYZ0123456789ab
+cdefghijklmnopqrs
+11.1
+12.1 12.2
+13.1 13.3
+14.1 14.4
+21.1
+22.1 22.2
+23.1 23.3
+24.1 24.4
+31.1
+32.1 32.2
+33.1 33.3
+34.1 34.4
+stdarg:
+ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI
+lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI
+HFA long double:
+34.1,34.4 34.1,34.4 34.1,34.4 34.1,34.4
+33.1,33.3 34.1,34.4 34.1,34.4 34.1,34.4
+32.1,32.2 34.1,34.4 34.1,34.4 34.1,34.4
+31.1,31.1 34.1,34.4 34.1,34.4 34.1,34.4
+32.1,32.2 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3
+31.1,31.1 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3
+33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3
+34.1,34.4 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2
+33.1,33.3 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2
+34.1,34.4 32.1,32.2 31.1,31.1 31.1,31.1 31.1,31.1 31.1,31.1
+HFA double:
+24.1,24.4 24.1,24.4 24.1,24.4 24.1,24.4
+23.1,23.3 24.1,24.4 24.1,24.4 24.1,24.4
+22.1,22.2 24.1,24.4 24.1,24.4 24.1,24.4
+21.1,21.1 24.1,24.4 24.1,24.4 24.1,24.4
+22.1,22.2 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3
+21.1,21.1 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3
+23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3
+24.1,24.4 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2
+23.1,23.3 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2
+24.1,24.4 22.1,22.2 21.1,21.1 21.1,21.1 21.1,21.1 21.1,21.1
+HFA float:
+14.1,14.4 14.1,14.4 14.1,14.4 14.1,14.4
+13.1,13.3 14.1,14.4 14.1,14.4 14.1,14.4
+12.1,12.2 14.1,14.4 14.1,14.4 14.1,14.4
+11.1,11.1 14.1,14.4 14.1,14.4 14.1,14.4
+12.1,12.2 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3
+11.1,11.1 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3
+13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3
+14.1,14.4 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2
+13.1,13.3 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2
+14.1,14.4 12.1,12.2 11.1,11.1 11.1,11.1 11.1,11.1 11.1,11.1
+MOVI:
+0
+abcd
+abcd0000
+abcd00000000
+abcd000000000000
+ffffabcd
+abcdffff
+ffffffffffffabcd
+ffffffffabcdffff
+ffffabcdffffffff
+abcdffffffffffff
+aaaaaaaa
+5555555555555555
+77777777
+3333333333333333
+f8f8f8f8
+1e1e1e1e1e1e1e1e
+3f803f80
+1ff01ff01ff01ff
+7fffc0
+3fff80003fff800
+7fffffffffe00
+abcd1234
+abcd00001234
+abcd000000001234
+abcd12340000
+abcd000012340000
+abcd123400000000
+ffffffffabcd1234
+ffffabcdffff1234
+abcdffffffff1234
+ffffabcd1234ffff
+abcdffff1234ffff
+abcd1234ffffffff
+ffffef0123456789
+abcdef012345ffff
+abcdef0123456789
+3e8
+3e8
+463
+36d
+fffffffffffff3e9
+7b3e8
+3421
+ffffd3af
+fffffc17
+fffffffffffffc18
+fffffc93
+fffffffffffffc93
+0
+3e8
+3e8
+ffffffff
+3e8
+fffffffffffffc17
+e0
+3f8
+318
+3e8
+3e8
+3e8
+7d0
+0
+7d0
+0
+1f4
+0
+1f4
+0
+1f4
+0
+1f4
+0
diff --git a/tests/tests2/75_array_in_struct_init.c b/tests/tests2/75_array_in_struct_init.c
new file mode 100644
index 0000000..234e3c4
--- /dev/null
+++ b/tests/tests2/75_array_in_struct_init.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+/* This test is a snippet from the J interpreter */
+
+typedef long I;
+typedef struct{I c[4];I b,e,k;} PT;
+
+PT cases[] = {
+ ((I)4194304L +(I)2097152L +(I)67108864L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), -1L, 1,2,1,
+ ((I)+4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L, (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 2,3,2,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,2,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)524288L, -1L, 1,2,1,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)1048576L, (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,1,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (I)262144L, 1,3,1,
+ ((I)4194304L +(I)2097152L +(I)67108864L), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 1,2,1,
+ (I)33554432L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)2097152L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 0,2,1,
+ (I)67108864L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)134217728L, -1L, 0,2,0,
+};
+
+int main() {
+ int i, j;
+
+ for(j=0; j < sizeof(cases)/sizeof(cases[0]); j++) {
+ for(i=0; i < sizeof(cases->c)/sizeof(cases->c[0]); i++)
+ printf("cases[%d].c[%d]=%ld\n", j, i, cases[j].c[i]);
+
+ printf("cases[%d].b=%ld\n", j, cases[j].b);
+ printf("cases[%d].e=%ld\n", j, cases[j].e);
+ printf("cases[%d].k=%ld\n", j, cases[j].k);
+ printf("\n");
+ }
+ return 0;
+}
diff --git a/tests/tests2/75_array_in_struct_init.expect b/tests/tests2/75_array_in_struct_init.expect
new file mode 100644
index 0000000..2b75aa5
--- /dev/null
+++ b/tests/tests2/75_array_in_struct_init.expect
@@ -0,0 +1,72 @@
+cases[0].c[0]=73400320
+cases[0].c[1]=262144
+cases[0].c[2]=805567999
+cases[0].c[3]=-1
+cases[0].b=1
+cases[0].e=2
+cases[0].k=1
+
+cases[1].c[0]=879754751
+cases[1].c[1]=262144
+cases[1].c[2]=262144
+cases[1].c[3]=805567999
+cases[1].b=2
+cases[1].e=3
+cases[1].k=2
+
+cases[2].c[0]=879754751
+cases[2].c[1]=805567999
+cases[2].c[2]=262144
+cases[2].c[3]=805567999
+cases[2].b=1
+cases[2].e=3
+cases[2].k=2
+
+cases[3].c[0]=879754751
+cases[3].c[1]=805830143
+cases[3].c[2]=524288
+cases[3].c[3]=-1
+cases[3].b=1
+cases[3].e=2
+cases[3].k=1
+
+cases[4].c[0]=879754751
+cases[4].c[1]=805830143
+cases[4].c[2]=1048576
+cases[4].c[3]=805830143
+cases[4].b=1
+cases[4].e=3
+cases[4].k=1
+
+cases[5].c[0]=879754751
+cases[5].c[1]=805830143
+cases[5].c[2]=262144
+cases[5].c[3]=262144
+cases[5].b=1
+cases[5].e=3
+cases[5].k=1
+
+cases[6].c[0]=73400320
+cases[6].c[1]=807403007
+cases[6].c[2]=807403007
+cases[6].c[3]=-1
+cases[6].b=1
+cases[6].e=2
+cases[6].k=1
+
+cases[7].c[0]=839122431
+cases[7].c[1]=2097152
+cases[7].c[2]=807403007
+cases[7].c[3]=-1
+cases[7].b=0
+cases[7].e=2
+cases[7].k=1
+
+cases[8].c[0]=67108864
+cases[8].c[1]=807403007
+cases[8].c[2]=134217728
+cases[8].c[3]=-1
+cases[8].b=0
+cases[8].e=2
+cases[8].k=0
+
diff --git a/tests/tests2/76_dollars_in_identifiers.c b/tests/tests2/76_dollars_in_identifiers.c
new file mode 100644
index 0000000..c5fcf99
--- /dev/null
+++ b/tests/tests2/76_dollars_in_identifiers.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+#define $(x) x
+#define $fred 10
+#define joe$ 20
+#define hen$y 30
+
+#define $10(x) x*10
+#define _$10(x) x/10
+
+int main()
+{
+ printf("fred=%d\n", $fred);
+ printf("joe=%d\n", joe$);
+ printf("henry=%d\n", hen$y);
+
+ printf("fred2=%d\n", $($fred));
+ printf("joe2=%d\n", $(joe$));
+ printf("henry2=%d\n", $(hen$y));
+
+ printf("fred10=%d\n", $10($fred));
+ printf("joe_10=%d\n", _$10(joe$));
+
+ int $ = 10;
+ int a100$ = 100;
+ int a$$ = 1000;
+ int a$c$b = 2121;
+ int $100 = 10000;
+ const char *$$$ = "money";
+
+ printf("local=%d\n", $);
+ printf("a100$=%d\n", a100$);
+ printf("a$$=%d\n", a$$);
+ printf("a$c$b=%d\n", a$c$b);
+ printf("$100=%d\n", $100);
+ printf("$$$=%s", $$$);
+
+ return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
diff --git a/tests/tests2/76_dollars_in_identifiers.expect b/tests/tests2/76_dollars_in_identifiers.expect
new file mode 100644
index 0000000..4a20a52
--- /dev/null
+++ b/tests/tests2/76_dollars_in_identifiers.expect
@@ -0,0 +1,14 @@
+fred=10
+joe=20
+henry=30
+fred2=10
+joe2=20
+henry2=30
+fred10=100
+joe_10=2
+local=10
+a100$=100
+a$$=1000
+a$c$b=2121
+$100=10000
+$$$=money
diff --git a/tests/tests2/77_push_pop_macro.c b/tests/tests2/77_push_pop_macro.c
new file mode 100644
index 0000000..d38e0bf
--- /dev/null
+++ b/tests/tests2/77_push_pop_macro.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+int main()
+{
+ /* must not affect how #pragma ppop_macro works */
+ #define pop_macro foobar1
+
+ /* must not affect how #pragma push_macro works */
+ #define push_macro foobar2
+
+ #undef abort
+ #define abort "111"
+ printf("abort = %s\n", abort);
+
+ #pragma push_macro("abort")
+ #undef abort
+ #define abort "222"
+ printf("abort = %s\n", abort);
+
+ #pragma push_macro("abort")
+ #undef abort
+ #define abort "333"
+ printf("abort = %s\n", abort);
+
+ #pragma pop_macro("abort")
+ printf("abort = %s\n", abort);
+
+ #pragma pop_macro("abort")
+ printf("abort = %s\n", abort);
+}
diff --git a/tests/tests2/77_push_pop_macro.expect b/tests/tests2/77_push_pop_macro.expect
new file mode 100644
index 0000000..d8a5530
--- /dev/null
+++ b/tests/tests2/77_push_pop_macro.expect
@@ -0,0 +1,5 @@
+abort = 111
+abort = 222
+abort = 333
+abort = 222
+abort = 111
diff --git a/tests/tests2/78_vla_label.c b/tests/tests2/78_vla_label.c
new file mode 100644
index 0000000..4096495
--- /dev/null
+++ b/tests/tests2/78_vla_label.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+
+/* This test segfaults as of April 27, 2015. */
+void f1(int argc)
+{
+ char test[argc];
+ if(0)
+ label:
+ printf("boom!\n");
+ if(argc-- == 0)
+ return;
+ goto label;
+}
+
+/* This segfaulted on 2015-11-19. */
+void f2(void)
+{
+ goto start;
+ {
+ int a[1 && 1]; /* not a variable-length array */
+ int b[1 || 1]; /* not a variable-length array */
+ int c[1 ? 1 : 1]; /* not a variable-length array */
+ start:
+ a[0] = 0;
+ b[0] = 0;
+ c[0] = 0;
+ }
+}
+
+void f3(void)
+{
+ printf("%d\n", 0 ? printf("x1\n") : 11);
+ printf("%d\n", 1 ? 12 : printf("x2\n"));
+ printf("%d\n", 0 && printf("x3\n"));
+ printf("%d\n", 1 || printf("x4\n"));
+}
+
+int main()
+{
+ f1(2);
+ f2();
+ f3();
+
+ return 0;
+}
diff --git a/tests/tests2/78_vla_label.expect b/tests/tests2/78_vla_label.expect
new file mode 100644
index 0000000..3f4063b
--- /dev/null
+++ b/tests/tests2/78_vla_label.expect
@@ -0,0 +1,6 @@
+boom!
+boom!
+11
+12
+0
+1
diff --git a/tests/tests2/79_vla_continue.c b/tests/tests2/79_vla_continue.c
new file mode 100644
index 0000000..91215c9
--- /dev/null
+++ b/tests/tests2/79_vla_continue.c
@@ -0,0 +1,116 @@
+#include <stdio.h>
+
+int f(void)
+{
+ return 5;
+}
+
+void test1()
+{
+ int count = 10;
+ void *addr[10];
+ for(;count--;) {
+ int a[f()];
+
+ addr[count] = a;
+
+ continue;
+ }
+
+ if(addr[9] == addr[0]) {
+ printf("OK\n");
+ } else {
+ printf("NOT OK\n");
+ }
+}
+
+void test2()
+{
+ int count = 10;
+ void *addr[count];
+ for(;count--;) {
+ int a[f()];
+
+ addr[count] = a;
+
+ continue;
+ }
+
+ if(addr[9] == addr[0]) {
+ printf("OK\n");
+ } else {
+ printf("NOT OK\n");
+ }
+}
+
+void test3()
+{
+ int count = 10;
+ void *addr[count];
+ while(count--) {
+ int a[f()];
+
+ addr[count] = a;
+
+ continue;
+ }
+
+ if(addr[9] == addr[0]) {
+ printf("OK\n");
+ } else {
+ printf("NOT OK\n");
+ }
+}
+
+void test4()
+{
+ int count = 10;
+ void *addr[count];
+ do {
+ int a[f()];
+
+ addr[--count] = a;
+
+ continue;
+ } while (count);
+
+ if(addr[9] == addr[0]) {
+ printf("OK\n");
+ } else {
+ printf("NOT OK\n");
+ }
+}
+
+void test5()
+{
+ int count = 10;
+ int a[f()];
+ int c[f()];
+
+ c[0] = 42;
+
+ for(;count--;) {
+ int b[f()];
+ int i;
+ for (i=0; i<f(); i++) {
+ b[i] = count;
+ }
+ }
+
+ if (c[0] == 42) {
+ printf("OK\n");
+ } else {
+ printf("NOT OK\n");
+ }
+}
+
+int main(void)
+{
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+
+ return 0;
+}
diff --git a/tests/tests2/79_vla_continue.expect b/tests/tests2/79_vla_continue.expect
new file mode 100644
index 0000000..21da4d2
--- /dev/null
+++ b/tests/tests2/79_vla_continue.expect
@@ -0,0 +1,5 @@
+OK
+OK
+OK
+OK
+OK
diff --git a/tests/tests2/80_flexarray.c b/tests/tests2/80_flexarray.c
new file mode 100644
index 0000000..1fc1a60
--- /dev/null
+++ b/tests/tests2/80_flexarray.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+struct wchar {
+ char *data; char mem[];
+};
+struct wint {
+ char *data; int mem[];
+};
+int f1char (void) {
+ char s[9]="nonono";
+ struct wchar q = {"bugs"};
+ return !s[0];
+}
+int f1int (void) {
+ char s[9]="nonono";
+ struct wint q = {"bugs"};
+ return !s[0];
+}
+int main (void) {
+ char s[9]="nonono";
+ static struct wchar q = {"bugs", {'c'}};
+ //printf ("tcc has %s %s\n", s, q.data);
+ if (f1char() || f1int())
+ printf ("bla\n");
+ return !s[0];
+}
diff --git a/tests/tests2/80_flexarray.expect b/tests/tests2/80_flexarray.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/tests2/80_flexarray.expect
diff --git a/tests/tests2/81_types.c b/tests/tests2/81_types.c
new file mode 100644
index 0000000..fd6d71b
--- /dev/null
+++ b/tests/tests2/81_types.c
@@ -0,0 +1,43 @@
+/* The following are all valid decls, even though some subtypes
+ are incomplete. */
+enum E *e;
+const enum E *e1;
+enum E const *e2;
+struct S *s;
+const struct S *s1;
+struct S const *s2;
+
+/* Various strangely looking declarators, which are all valid
+ and have to map to the same numbered typedefs. */
+typedef int (*fptr1)();
+int f1 (int (), int);
+typedef int (*fptr2)(int x);
+int f2 (int (int x), int);
+typedef int (*fptr3)(int);
+int f3 (int (int), int);
+typedef int (*fptr4[4])(int);
+int f4 (int (*[4])(int), int);
+typedef int (*fptr5)(fptr1);
+int f5 (int (int()), fptr1);
+int f1 (fptr1 fp, int i)
+{
+ return (*fp)(i);
+}
+int f2 (fptr2 fp, int i)
+{
+ return (*fp)(i);
+}
+int f3 (fptr3 fp, int i)
+{
+ return (*fp)(i);
+}
+int f4 (fptr4 fp, int i)
+{
+ return (*fp[i])(i);
+}
+int f5 (fptr5 fp, fptr1 i)
+{
+ return fp(i);
+}
+int f8 (int ([4]), int);
+int main () { return 0; }
diff --git a/tests/tests2/81_types.expect b/tests/tests2/81_types.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/tests2/81_types.expect
diff --git a/tests/tests2/82_attribs_position.c b/tests/tests2/82_attribs_position.c
new file mode 100644
index 0000000..7c9f987
--- /dev/null
+++ b/tests/tests2/82_attribs_position.c
@@ -0,0 +1,19 @@
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+
+typedef union Unaligned16a {
+ uint16_t u;
+ uint8_t b[2];
+} __attribute__((packed)) Unaligned16a;
+
+typedef union __attribute__((packed)) Unaligned16b {
+ uint16_t u;
+ uint8_t b[2];
+} Unaligned16b;
+
+extern void foo (void) __attribute__((stdcall));
+void __attribute__((stdcall)) foo (void)
+{
+}
+
+int main () { return 0; }
diff --git a/tests/tests2/82_attribs_position.expect b/tests/tests2/82_attribs_position.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/tests2/82_attribs_position.expect
diff --git a/tests/tests2/83_utf8_in_identifiers.c b/tests/tests2/83_utf8_in_identifiers.c
new file mode 100644
index 0000000..1f86095
--- /dev/null
+++ b/tests/tests2/83_utf8_in_identifiers.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+double привет=0.1;
+int Lefèvre=2;
+int main(){
+ printf("привет=%g\n",привет);
+ printf("Lefèvre=%d\n",Lefèvre);
+ return 0;
+}
+// pcc & tcc only
diff --git a/tests/tests2/83_utf8_in_identifiers.expect b/tests/tests2/83_utf8_in_identifiers.expect
new file mode 100644
index 0000000..1553f5f
--- /dev/null
+++ b/tests/tests2/83_utf8_in_identifiers.expect
@@ -0,0 +1,2 @@
+привет=0.1
+Lefèvre=2
diff --git a/tests/tests2/84_hex-float.c b/tests/tests2/84_hex-float.c
new file mode 100644
index 0000000..0ef09bf
--- /dev/null
+++ b/tests/tests2/84_hex-float.c
@@ -0,0 +1,12 @@
+extern int printf(const char *format, ...);
+
+#define ACPI_TYPE_INVALID 0x1E
+#define NUM_NS_TYPES ACPI_TYPE_INVALID+1
+int array[NUM_NS_TYPES];
+
+#define n 0xe
+int main()
+{
+ printf("n+1 = %d\n", n+1);
+// printf("n+1 = %d\n", 0xe+1);
+}
diff --git a/tests/tests2/84_hex-float.expect b/tests/tests2/84_hex-float.expect
new file mode 100644
index 0000000..2175385
--- /dev/null
+++ b/tests/tests2/84_hex-float.expect
@@ -0,0 +1 @@
+n+1 = 15
diff --git a/tests/tests2/85_asm-outside-function.c b/tests/tests2/85_asm-outside-function.c
new file mode 100644
index 0000000..dc5639a
--- /dev/null
+++ b/tests/tests2/85_asm-outside-function.c
@@ -0,0 +1,9 @@
+extern int printf (const char *, ...);
+extern void vide(void);
+__asm__("vide: ret");
+
+int main() {
+ vide();
+ printf ("okay\n");
+ return 0;
+}
diff --git a/tests/tests2/85_asm-outside-function.expect b/tests/tests2/85_asm-outside-function.expect
new file mode 100644
index 0000000..dcf02b2
--- /dev/null
+++ b/tests/tests2/85_asm-outside-function.expect
@@ -0,0 +1 @@
+okay
diff --git a/tests/tests2/86_memory-model.c b/tests/tests2/86_memory-model.c
new file mode 100644
index 0000000..744c3e2
--- /dev/null
+++ b/tests/tests2/86_memory-model.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+
+int
+main()
+{
+#if defined(__LLP64__)
+ if (sizeof(short) == 2
+ && sizeof(int) == 4
+ && sizeof(long int) == 4
+ && sizeof(long long int) == 8
+ && sizeof(void*) == 8) {
+ (void)printf("Ok\n");
+ } else {
+ (void)printf("KO __LLP64__\n");
+ }
+#elif defined(__LP64__)
+ if (sizeof(short) == 2
+ && sizeof(int) == 4
+ && sizeof(long int) == 8
+ && sizeof(long long int) == 8
+ && sizeof(void*) == 8) {
+ (void)printf("Ok\n");
+ } else {
+ (void)printf("KO __LP64__\n");
+ }
+#elif defined(__ILP32__)
+ if (sizeof(short) == 2
+ && sizeof(int) == 4
+ && sizeof(long int) == 4
+ && sizeof(void*) == 4) {
+ (void)printf("Ok\n");
+ } else {
+ (void)printf("KO __ILP32__\n");
+ }
+#else
+ (void)printf("KO no __*LP*__ defined.\n");
+#endif
+}
diff --git a/tests/tests2/86_memory-model.expect b/tests/tests2/86_memory-model.expect
new file mode 100644
index 0000000..7326d96
--- /dev/null
+++ b/tests/tests2/86_memory-model.expect
@@ -0,0 +1 @@
+Ok
diff --git a/tests/tests2/87_dead_code.c b/tests/tests2/87_dead_code.c
new file mode 100644
index 0000000..98d4566
--- /dev/null
+++ b/tests/tests2/87_dead_code.c
@@ -0,0 +1,122 @@
+/* This checks various ways of dead code inside if statements
+ where there are non-obvious ways of how the code is actually
+ not dead due to reachable by labels. */
+extern int printf (const char *, ...);
+static void kb_wait_1(void)
+{
+ unsigned long timeout = 2;
+ do {
+ /* Here the else arm is a statement expression that's supposed
+ to be suppressed. The label inside the while would unsuppress
+ code generation again if not handled correctly. And that
+ would wreak havoc to the cond-expression because there's no
+ jump-around emitted, the whole statement expression really
+ needs to not generate code (perhaps except useless forward jumps). */
+ (1 ?
+ printf("timeout=%ld\n", timeout) :
+ ({
+ int i = 1;
+ while (1)
+ while (i--)
+ some_label:
+ printf("error\n");
+ goto some_label;
+ })
+ );
+ timeout--;
+ } while (timeout);
+}
+int main (void)
+{
+ int i = 1;
+ kb_wait_1();
+
+ /* Simple test of dead code at first sight which isn't actually dead. */
+ if (0) {
+yeah:
+ printf ("yeah\n");
+ } else {
+ printf ("boo\n");
+ }
+ if (i--)
+ goto yeah;
+
+ /* Some more non-obvious uses where the problems are loops, so that even
+ the first loop statements aren't actually dead. */
+ i = 1;
+ if (0) {
+ while (i--) {
+ printf ("once\n");
+enterloop:
+ printf ("twice\n");
+ }
+ }
+ if (i >= 0)
+ goto enterloop;
+
+ /* The same with statement expressions. One might be tempted to
+ handle them specially by counting if inside statement exprs and
+ not unsuppressing code at loops at all then.
+ See kb_wait_1 for the other side of the medal where that wouldn't work. */
+ i = ({
+ int j = 1;
+ if (0) {
+ while (j--) {
+ printf ("SEonce\n");
+ enterexprloop:
+ printf ("SEtwice\n");
+ }
+ }
+ if (j >= 0)
+ goto enterexprloop;
+ j; });
+
+ /* The other two loop forms: */
+ i = 1;
+ if (0) {
+ for (i = 1; i--;) {
+ printf ("once2\n");
+enterloop2:
+ printf ("twice2\n");
+ }
+ }
+ if (i > 0)
+ goto enterloop2;
+
+ i = 1;
+ if (0) {
+ do {
+ printf ("once3\n");
+enterloop3:
+ printf ("twice3\n");
+ } while (i--);
+ }
+ if (i > 0)
+ goto enterloop3;
+
+ /* And check that case and default labels have the same effect
+ of disabling code suppression. */
+ i = 41;
+ switch (i) {
+ if (0) {
+ printf ("error\n");
+ case 42:
+ printf ("error2\n");
+ case 41:
+ printf ("caseok\n");
+ }
+ }
+
+ i = 41;
+ switch (i) {
+ if (0) {
+ printf ("error3\n");
+ default:
+ printf ("caseok2\n");
+ break;
+ case 42:
+ printf ("error4\n");
+ }
+ }
+ return 0;
+}
diff --git a/tests/tests2/87_dead_code.expect b/tests/tests2/87_dead_code.expect
new file mode 100644
index 0000000..0b3ec1d
--- /dev/null
+++ b/tests/tests2/87_dead_code.expect
@@ -0,0 +1,18 @@
+timeout=2
+timeout=1
+boo
+yeah
+twice
+once
+twice
+SEtwice
+SEonce
+SEtwice
+twice2
+once2
+twice2
+twice3
+once3
+twice3
+caseok
+caseok2
diff --git a/tests/tests2/88_codeopt.c b/tests/tests2/88_codeopt.c
new file mode 100644
index 0000000..647626f
--- /dev/null
+++ b/tests/tests2/88_codeopt.c
@@ -0,0 +1,68 @@
+/* Check some way in where code suppression caused various
+ miscompilations. */
+extern int printf (const char *, ...);
+typedef unsigned long size_t;
+
+size_t _brk_start, _brk_end;
+void * extend_brk(size_t size, size_t align)
+{
+ size_t mask = align - 1;
+ void *ret = 0;
+
+ do {
+ if (__builtin_expect(!!(_brk_start == 0), 0))
+ do {
+ printf("wrong1\n");
+ } while (0);
+ } while (0);
+ _brk_end = (_brk_end + mask) & ~mask;
+ ret = (void *)_brk_end;
+ _brk_end += size;
+
+ return ret;
+}
+
+static void get_args (int a, int b)
+{
+ if (a != 1)
+ printf("wrong2\n");
+ else
+ printf("okay\n");
+}
+
+void bla(void)
+{
+ int __ret = 42;
+ ({
+ if (__builtin_expect(!!(0), 0)) {
+ if (__builtin_expect(!!__ret, 0))
+ printf("wrong3\n");
+ int x = !!(__ret);
+ }
+ __ret;
+ });
+ get_args(!!__ret, sizeof(__ret));
+}
+
+_Bool chk(unsigned long addr, unsigned long limit, unsigned long size)
+{
+ _Bool ret;
+ /* This just needs to compile, no runtime test. (And it doesn't compile
+ only with certain internal checking added that's not committed). */
+ if (0)
+ ret = 0 != (!!(addr > limit - size));
+}
+
+int main()
+{
+ void *r;
+ _brk_start = 1024;
+ _brk_end = 1024;
+ r = extend_brk (4096, 16);
+ if (!r)
+ printf("wrong4\n");
+ else
+ printf("okay\n");
+ bla();
+ return 0;
+}
diff --git a/tests/tests2/88_codeopt.expect b/tests/tests2/88_codeopt.expect
new file mode 100644
index 0000000..439edfd
--- /dev/null
+++ b/tests/tests2/88_codeopt.expect
@@ -0,0 +1,2 @@
+okay
+okay
diff --git a/tests/tests2/89_nocode_wanted.c b/tests/tests2/89_nocode_wanted.c
new file mode 100644
index 0000000..73e0a4b
--- /dev/null
+++ b/tests/tests2/89_nocode_wanted.c
@@ -0,0 +1,112 @@
+extern int printf(const char *format, ...);
+static void kb_wait_1(void)
+{
+ unsigned long timeout = 2;
+ do {
+ (1 ?
+ printf("timeout=%ld\n", timeout) :
+ ({
+ while (1)
+ printf("error\n");
+ })
+ );
+ timeout--;
+ } while (timeout);
+}
+static void kb_wait_2(void)
+{
+ unsigned long timeout = 2;
+ do {
+ (1 ?
+ printf("timeout=%ld\n", timeout) :
+ ({
+ for (;;)
+ printf("error\n");
+ })
+ );
+ timeout--;
+ } while (timeout);
+}
+static void kb_wait_2_1(void)
+{
+ unsigned long timeout = 2;
+ do {
+ (1 ?
+ printf("timeout=%ld\n", timeout) :
+ ({
+ do {
+ printf("error\n");
+ } while (1);
+ })
+ );
+ timeout--;
+ } while (timeout);
+}
+static void kb_wait_2_2(void)
+{
+ unsigned long timeout = 2;
+ do {
+ (1 ?
+ printf("timeout=%ld\n", timeout) :
+ ({
+ label:
+ printf("error\n");
+ goto label;
+ })
+ );
+ timeout--;
+ } while (timeout);
+}
+static void kb_wait_3(void)
+{
+ unsigned long timeout = 2;
+ do {
+ (1 ?
+ printf("timeout=%ld\n", timeout) :
+ ({
+ int i = 1;
+ goto label;
+ i = i + 2;
+ label:
+ i = i + 3;
+ })
+ );
+ timeout--;
+ } while (timeout);
+}
+static void kb_wait_4(void)
+{
+ unsigned long timeout = 2;
+ do {
+ (1 ?
+ printf("timeout=%ld\n", timeout) :
+ ({
+ switch(timeout) {
+ case 2:
+ printf("timeout is 2");
+ break;
+ case 1:
+ printf("timeout is 1");
+ break;
+ default:
+ printf("timeout is 0?");
+ break;
+ };
+ // return;
+ })
+ );
+ timeout--;
+ } while (timeout);
+}
+int main()
+{
+ printf("begin\n");
+ kb_wait_1();
+ kb_wait_2();
+ kb_wait_2_1();
+ kb_wait_2_2();
+ kb_wait_3();
+ kb_wait_4();
+ printf("end\n");
+ return 0;
+}
diff --git a/tests/tests2/89_nocode_wanted.expect b/tests/tests2/89_nocode_wanted.expect
new file mode 100644
index 0000000..c44d4ea
--- /dev/null
+++ b/tests/tests2/89_nocode_wanted.expect
@@ -0,0 +1,14 @@
+begin
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+end
diff --git a/tests/tests2/90_struct-init.c b/tests/tests2/90_struct-init.c
new file mode 100644
index 0000000..d931e23
--- /dev/null
+++ b/tests/tests2/90_struct-init.c
@@ -0,0 +1,282 @@
+typedef unsigned char u8;
+typedef struct {} empty_s;
+struct contains_empty {
+ u8 a;
+ empty_s empty;
+ u8 b;
+};
+struct contains_empty ce = { { (1) }, (empty_s){}, 022, };
+/* The following decl of 'q' would demonstrate the TCC bug in init_putv when
+ handling copying compound literals. (Compound literals
+ aren't acceptable constant initializers in isoc99, but
+ we accept them like gcc, except for this case)
+//char *q = (char *){ "trara" }; */
+struct SS {u8 a[3], b; };
+struct SS sinit16[] = { { 1 }, 2 };
+struct S
+{
+ u8 a,b;
+ u8 c[2];
+};
+
+struct T
+{
+ u8 s[16];
+ u8 a;
+};
+
+struct U
+{
+ u8 a;
+ struct S s;
+ u8 b;
+ struct T t;
+};
+
+struct V
+{
+ struct S s;
+ struct T t;
+ u8 a;
+};
+
+struct W
+{
+ struct V t;
+ struct S s[];
+};
+
+struct S gs = ((struct S){1, 2, 3, 4});
+struct S gs2 = {1, 2, {3, 4}};
+struct T gt = {"hello", 42};
+struct U gu = {3, 5,6,7,8, 4, "huhu", 43};
+struct U gu2 = {3, {5,6,7,8}, 4, {"huhu", 43}};
+/* Optional braces around scalar initializers. Accepted, but with
+ a warning. */
+struct U gu3 = { {3}, {5,6,7,8,}, 4, {"huhu", 43}};
+/* Many superfluous braces and leaving out one initializer for U.s.c[1] */
+struct U gu4 = { 3, {5,6,7,}, 5, { "bla", {44}} };
+/* Superfluous braces and useless parens around values */
+struct S gs3 = { (1), {(2)}, {(((3))), {4}}};
+/* Superfluous braces, and leaving out braces for V.t, plus cast */
+struct V gv = {{{3},4,{5,6}}, "haha", (u8)45, 46};
+/* Compound literal */
+struct V gv2 = {(struct S){7,8,{9,10}}, {"hihi", 47}, 48};
+/* Parens around compound literal */
+struct V gv3 = {((struct S){7,8,{9,10}}), {"hoho", 49}, 50};
+/* Initialization of a flex array member (warns in GCC) */
+struct W gw = {{1,2,3,4}, {1,2,3,4,5}};
+
+union UU {
+ u8 a;
+ u8 b;
+};
+struct SU {
+ union UU u;
+ u8 c;
+};
+struct SU gsu = {5,6};
+
+/* Unnamed struct/union members aren't ISO C, but it's a widely accepted
+ extension. See below for further extensions to that under -fms-extension.*/
+union UV {
+ struct {u8 a,b;};
+ struct S s;
+};
+union UV guv = {{6,5}};
+union UV guv2 = {{.b = 7, .a = 8}};
+union UV guv3 = {.b = 8, .a = 7};
+
+/* Under -fms-extensions also the following is valid:
+union UV2 {
+ struct Anon {u8 a,b;}; // unnamed member, but tagged struct, ...
+ struct S s;
+};
+struct Anon gan = { 10, 11 }; // ... which makes it available here.
+union UV2 guv4 = {{4,3}}; // and the other inits from above as well
+*/
+
+struct in6_addr {
+ union {
+ u8 u6_addr8[16];
+ unsigned short u6_addr16[8];
+ } u;
+};
+struct flowi6 {
+ struct in6_addr saddr, daddr;
+};
+struct pkthdr {
+ struct in6_addr daddr, saddr;
+};
+struct pkthdr phdr = { { { 6,5,4,3 } }, { { 9,8,7,6 } } };
+
+struct Wrap {
+ void *func;
+};
+int global;
+void inc_global (void)
+{
+ global++;
+}
+
+struct Wrap global_wrap[] = {
+ ((struct Wrap) {inc_global}),
+ inc_global,
+};
+
+#include <stdio.h>
+void print_ (const char *name, const u8 *p, long size)
+{
+ printf ("%s:", name);
+ while (size--) {
+ printf (" %x", *p++);
+ }
+ printf ("\n");
+}
+#define print(x) print_(#x, (u8*)&x, sizeof (x))
+#if 1
+void foo (struct W *w, struct pkthdr *phdr_)
+{
+ struct S ls = {1, 2, 3, 4};
+ struct S ls2 = {1, 2, {3, 4}};
+ struct T lt = {"hello", 42};
+ struct U lu = {3, 5,6,7,8, 4, "huhu", 43};
+ struct U lu1 = {3, ls, 4, {"huhu", 43}};
+ struct U lu2 = {3, (ls), 4, {"huhu", 43}};
+ const struct S *pls = &ls;
+ struct S ls21 = *pls;
+ struct U lu22 = {3, *pls, 4, {"huhu", 43}};
+ /* Incomplete bracing. */
+ struct U lu21 = {3, ls, 4, "huhu", 43};
+ /* Optional braces around scalar initializers. Accepted, but with
+ a warning. */
+ struct U lu3 = { 3, {5,6,7,8,}, 4, {"huhu", 43}};
+ /* Many superfluous braces and leaving out one initializer for U.s.c[1] */
+ struct U lu4 = { 3, {5,6,7,}, 5, { "bla", 44} };
+ /* Superfluous braces and useless parens around values */
+ struct S ls3 = { (1), (2), {(((3))), 4}};
+ /* Superfluous braces, and leaving out braces for V.t, plus cast */
+ struct V lv = {{3,4,{5,6}}, "haha", (u8)45, 46};
+ /* Compound literal */
+ struct V lv2 = {(struct S)w->t.s, {"hihi", 47}, 48};
+ /* Parens around compound literal */
+ struct V lv3 = {((struct S){7,8,{9,10}}), ((const struct W *)w)->t.t, 50};
+ const struct pkthdr *phdr = phdr_;
+ struct flowi6 flow = { .daddr = phdr->daddr, .saddr = phdr->saddr };
+ int elt = 0x42;
+ /* Range init, overlapping */
+ struct T lt2 = { { [1 ... 5] = 9, [6 ... 10] = elt, [4 ... 7] = elt+1 }, 1 };
+ print(ls);
+ print(ls2);
+ print(lt);
+ print(lu);
+ print(lu1);
+ print(lu2);
+ print(ls21);
+ print(lu21);
+ print(lu22);
+ print(lu3);
+ print(lu4);
+ print(ls3);
+ print(lv);
+ print(lv2);
+ print(lv3);
+ print(lt2);
+ print(flow);
+}
+#endif
+
+void test_compound_with_relocs (void)
+{
+ struct Wrap local_wrap[] = {
+ ((struct Wrap) {inc_global}),
+ inc_global,
+ };
+ void (*p)(void);
+ p = global_wrap[0].func; p();
+ p = global_wrap[1].func; p();
+ p = local_wrap[0].func; p();
+ p = local_wrap[1].func; p();
+}
+
+void sys_ni(void) { printf("ni\n"); }
+void sys_one(void) { printf("one\n"); }
+void sys_two(void) { printf("two\n"); }
+void sys_three(void) { printf("three\n"); }
+typedef void (*fptr)(void);
+const fptr table[3] = {
+ [0 ... 2] = &sys_ni,
+ [0] = sys_one,
+ [1] = sys_two,
+ [2] = sys_three,
+};
+
+void test_multi_relocs(void)
+{
+ int i;
+ for (i = 0; i < sizeof(table)/sizeof(table[0]); i++)
+ table[i]();
+}
+
+/* Following is from GCC gcc.c-torture/execute/20050613-1.c. */
+
+struct SEA { int i; int j; int k; int l; };
+struct SEB { struct SEA a; int r[1]; };
+struct SEC { struct SEA a; int r[0]; };
+struct SED { struct SEA a; int r[]; };
+
+static void
+test_correct_filling (struct SEA *x)
+{
+ static int i;
+ if (x->i != 0 || x->j != 5 || x->k != 0 || x->l != 0)
+ printf("sea_fill%d: wrong\n", i);
+ else
+ printf("sea_fill%d: okay\n", i);
+ i++;
+}
+
+int
+test_zero_init (void)
+{
+ /* The peculiarity here is that only a.j is initialized. That
+ means that all other members must be zero initialized. TCC
+ once didn't do that for sub-level designators. */
+ struct SEB b = { .a.j = 5 };
+ struct SEC c = { .a.j = 5 };
+ struct SED d = { .a.j = 5 };
+ test_correct_filling (&b.a);
+ test_correct_filling (&c.a);
+ test_correct_filling (&d.a);
+ return 0;
+}
+
+int main()
+{
+ print(ce);
+ print(gs);
+ print(gs2);
+ print(gt);
+ print(gu);
+ print(gu2);
+ print(gu3);
+ print(gu4);
+ print(gs3);
+ print(gv);
+ print(gv2);
+ print(gv3);
+ print(sinit16);
+ print(gw);
+ print(gsu);
+ print(guv);
+ print(guv.b);
+ print(guv2);
+ print(guv3);
+ print(phdr);
+ foo(&gw, &phdr);
+ //printf("q: %s\n", q);
+ test_compound_with_relocs();
+ test_multi_relocs();
+ test_zero_init();
+ return 0;
+}
diff --git a/tests/tests2/90_struct-init.expect b/tests/tests2/90_struct-init.expect
new file mode 100644
index 0000000..e366121
--- /dev/null
+++ b/tests/tests2/90_struct-init.expect
@@ -0,0 +1,43 @@
+ce: 1 12
+gs: 1 2 3 4
+gs2: 1 2 3 4
+gt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a
+gu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+gu2: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+gu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+gu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c
+gs3: 1 2 3 4
+gv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e
+gv2: 7 8 9 a 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30
+gv3: 7 8 9 a 68 6f 68 6f 0 0 0 0 0 0 0 0 0 0 0 0 31 32
+sinit16: 1 0 0 0 2 0 0 0
+gw: 1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+gsu: 5 6
+guv: 6 5 0 0
+guv.b: 5
+guv2: 8 7 0 0
+guv3: 7 8 0 0
+phdr: 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0
+ls: 1 2 3 4
+ls2: 1 2 3 4
+lt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a
+lu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu1: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu2: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+ls21: 1 2 3 4
+lu21: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu22: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c
+ls3: 1 2 3 4
+lv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e
+lv2: 1 2 3 4 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30
+lv3: 7 8 9 a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32
+lt2: 0 9 9 9 43 43 43 43 42 42 42 0 0 0 0 0 1
+flow: 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0
+one
+two
+three
+sea_fill0: okay
+sea_fill1: okay
+sea_fill2: okay
diff --git a/tests/tests2/91_ptr_longlong_arith32.c b/tests/tests2/91_ptr_longlong_arith32.c
new file mode 100644
index 0000000..bf07915
--- /dev/null
+++ b/tests/tests2/91_ptr_longlong_arith32.c
@@ -0,0 +1,15 @@
+int printf(const char *, ...);
+char t[] = "012345678";
+
+int main(void)
+{
+ char *data = t;
+ unsigned long long r = 4;
+ unsigned a = 5;
+ unsigned long long b = 12;
+
+ *(unsigned*)(data + r) += a - b;
+
+ printf("data = \"%s\"\n", data);
+ return 0;
+}
diff --git a/tests/tests2/91_ptr_longlong_arith32.expect b/tests/tests2/91_ptr_longlong_arith32.expect
new file mode 100644
index 0000000..f91e4b4
--- /dev/null
+++ b/tests/tests2/91_ptr_longlong_arith32.expect
@@ -0,0 +1 @@
+data = "0123-5678"
diff --git a/tests/tests2/92_enum_bitfield.c b/tests/tests2/92_enum_bitfield.c
new file mode 100644
index 0000000..bb6dc35
--- /dev/null
+++ b/tests/tests2/92_enum_bitfield.c
@@ -0,0 +1,57 @@
+/* This checks if enums needing 8 bit but only having positive
+ values are correctly zero extended (instead of sign extended)
+ when stored into/loaded from a 8 bit bit-field of enum type (which
+ itself is implementation defined, so isn't necessarily supported by all
+ other compilers). */
+enum tree_code {
+ SOME_CODE = 148, /* has bit 7 set, and hence all further enum values as well */
+ LAST_AND_UNUSED_TREE_CODE
+};
+typedef union tree_node *tree;
+struct tree_common
+{
+ union tree_node *chain;
+ union tree_node *type;
+ enum tree_code code : 8;
+ unsigned side_effects_flag : 1;
+};
+union tree_node
+{
+ struct tree_common common;
+ };
+enum c_tree_code {
+ C_DUMMY_TREE_CODE = LAST_AND_UNUSED_TREE_CODE,
+ STMT_EXPR,
+ LAST_C_TREE_CODE
+};
+enum cplus_tree_code {
+ CP_DUMMY_TREE_CODE = LAST_C_TREE_CODE,
+ AMBIG_CONV,
+ LAST_CPLUS_TREE_CODE
+};
+
+extern int printf(const char *, ...);
+int blah(){return 0;}
+
+int convert_like_real (tree convs)
+{
+ switch (((enum tree_code) (convs)->common.code))
+ {
+ case AMBIG_CONV: /* This has bit 7 set, which must not be the sign
+ bit in tree_common.code, i.e. the bitfield must
+ be somehow marked unsigned. */
+ return blah();
+ default:
+ break;
+ };
+ printf("unsigned enum bit-fields broken\n");
+}
+
+int main()
+{
+ union tree_node convs;
+
+ convs.common.code = AMBIG_CONV;
+ convert_like_real (&convs);
+ return 0;
+}
diff --git a/tests/tests2/92_enum_bitfield.expect b/tests/tests2/92_enum_bitfield.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/tests2/92_enum_bitfield.expect
diff --git a/tests/tests2/93_integer_promotion.c b/tests/tests2/93_integer_promotion.c
new file mode 100644
index 0000000..a1176fc
--- /dev/null
+++ b/tests/tests2/93_integer_promotion.c
@@ -0,0 +1,71 @@
+/* integer promotion */
+
+int printf(const char*, ...);
+#define promote(s) printf(" %ssigned : %s\n", (s) - 100 < 0 ? " " : "un", #s);
+
+int main (void)
+{
+ struct {
+ unsigned ub:3;
+ unsigned u:32;
+ unsigned long long ullb:35;
+ unsigned long long ull:64;
+ unsigned char c;
+ } s = { 1, 1, 1 };
+
+ promote(s.ub);
+ promote(s.u);
+ promote(s.ullb);
+ promote(s.ull);
+ promote(s.c);
+ printf("\n");
+
+ promote((1 ? s.ub : 1));
+ promote((1 ? s.u : 1));
+ promote((1 ? s.ullb : 1));
+ promote((1 ? s.ull : 1));
+ promote((1 ? s.c : 1));
+ printf("\n");
+
+ promote(s.ub << 1);
+ promote(s.u << 1);
+ promote(s.ullb << 1);
+ promote(s.ull << 1);
+ promote(s.c << 1);
+ printf("\n");
+
+ promote(+s.ub);
+ promote(+s.u);
+ promote(+s.ullb);
+ promote(+s.ull);
+ promote(+s.c);
+ printf("\n");
+
+ promote(-s.ub);
+ promote(-s.u);
+ promote(-s.ullb);
+ promote(-s.ull);
+ promote(-s.c);
+ printf("\n");
+
+ promote(~s.ub);
+ promote(~s.u);
+ promote(~s.ullb);
+ promote(~s.ull);
+ promote(~s.c);
+ printf("\n");
+
+ promote(!s.ub);
+ promote(!s.u);
+ promote(!s.ullb);
+ promote(!s.ull);
+ promote(!s.c);
+ printf("\n");
+
+ promote(+(unsigned)s.ub);
+ promote(-(unsigned)s.ub);
+ promote(~(unsigned)s.ub);
+ promote(!(unsigned)s.ub);
+
+ return 0;
+}
diff --git a/tests/tests2/93_integer_promotion.expect b/tests/tests2/93_integer_promotion.expect
new file mode 100644
index 0000000..34b9c14
--- /dev/null
+++ b/tests/tests2/93_integer_promotion.expect
@@ -0,0 +1,46 @@
+ signed : s.ub
+ unsigned : s.u
+ signed : s.ullb
+ unsigned : s.ull
+ signed : s.c
+
+ signed : (1 ? s.ub : 1)
+ unsigned : (1 ? s.u : 1)
+ signed : (1 ? s.ullb : 1)
+ unsigned : (1 ? s.ull : 1)
+ signed : (1 ? s.c : 1)
+
+ signed : s.ub << 1
+ unsigned : s.u << 1
+ signed : s.ullb << 1
+ unsigned : s.ull << 1
+ signed : s.c << 1
+
+ signed : +s.ub
+ unsigned : +s.u
+ signed : +s.ullb
+ unsigned : +s.ull
+ signed : +s.c
+
+ signed : -s.ub
+ unsigned : -s.u
+ signed : -s.ullb
+ unsigned : -s.ull
+ signed : -s.c
+
+ signed : ~s.ub
+ unsigned : ~s.u
+ signed : ~s.ullb
+ unsigned : ~s.ull
+ signed : ~s.c
+
+ signed : !s.ub
+ signed : !s.u
+ signed : !s.ullb
+ signed : !s.ull
+ signed : !s.c
+
+ unsigned : +(unsigned)s.ub
+ unsigned : -(unsigned)s.ub
+ unsigned : ~(unsigned)s.ub
+ signed : !(unsigned)s.ub
diff --git a/tests/tests2/94_generic.c b/tests/tests2/94_generic.c
new file mode 100644
index 0000000..d7fb5fc
--- /dev/null
+++ b/tests/tests2/94_generic.c
@@ -0,0 +1,64 @@
+#include <stdio.h>
+
+const int a = 0;
+
+struct a {
+ int a;
+};
+
+struct b {
+ int a;
+};
+
+int a_f()
+{
+ return 20;
+}
+
+int b_f()
+{
+ return 10;
+}
+
+typedef int int_type1;
+
+#define gen_sw(a) _Generic(a, const char *: 1, default: 8, int: 123);
+
+int main()
+{
+ int i = 0;
+ signed long int l = 2;
+ struct b titi;
+ const int * const ptr;
+ const char *ti;
+ int_type1 i2;
+
+ i = _Generic(a, int: a_f, const int: b_f)();
+ printf("%d\n", i);
+ i = _Generic(a, int: a_f() / 2, const int: b_f() / 2);
+ printf("%d\n", i);
+ i = _Generic(ptr, int *:1, int * const:2, default:20);
+ printf("%d\n", i);
+ i = gen_sw(a);
+ printf("%d\n", i);
+ i = _Generic(titi, struct a:1, struct b:2, default:20);
+ printf("%d\n", i);
+ i = _Generic(i2, char: 1, int : 0);
+ printf("%d\n", i);
+ i = _Generic(a, char:1, int[4]:2, default:5);
+ printf("%d\n", i);
+ i = _Generic(17, int :1, int **:2);
+ printf("%d\n", i);
+ i = _Generic(17L, int :1, long :2, long long : 3);
+ printf("%d\n", i);
+ i = _Generic("17, io", char *: 3, const char *: 1);
+ printf("%d\n", i);
+ i = _Generic(ti, const unsigned char *:1, const char *:4, char *:3,
+ const signed char *:2);
+ printf("%d\n", i);
+ printf("%s\n", _Generic(i + 2L, long: "long", int: "int",
+ long long: "long long"));
+ i = _Generic(l, long: 1, int: 2);
+ printf("%d\n", i);
+ return 0;
+}
diff --git a/tests/tests2/94_generic.expect b/tests/tests2/94_generic.expect
new file mode 100644
index 0000000..9aa9275
--- /dev/null
+++ b/tests/tests2/94_generic.expect
@@ -0,0 +1,13 @@
+20
+10
+20
+123
+2
+0
+5
+1
+2
+3
+4
+long
+1 \ No newline at end of file
diff --git a/tests/tests2/95_bitfields.c b/tests/tests2/95_bitfields.c
new file mode 100644
index 0000000..f025c57
--- /dev/null
+++ b/tests/tests2/95_bitfields.c
@@ -0,0 +1,218 @@
+/* ----------------------------------------------------------------------- */
+#if TEST == 1
+{
+ struct M P A __s
+ {
+ unsigned x : 12;
+ unsigned char y : 7;
+ unsigned z : 28;
+ unsigned a: 4;
+ unsigned b: 5;
+ };
+ TEST_STRUCT(0x333,0x44,0x555555,6,7);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 2
+{
+ struct M P __s
+ {
+ int x: 12;
+ char y: 6;
+ long long z:63;
+ A char a:4;
+ long long b:2;
+
+ };
+ TEST_STRUCT(3,30,0x123456789abcdef0LL,5,2);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 3
+{
+ struct M P __s
+ {
+ unsigned x:5, y:5, :0, z:5; char a:5; A short b:5;
+ };
+ TEST_STRUCT(21,23,25,6,14);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 4
+{
+ struct M P __s {
+ int x : 3;
+ int : 2;
+ int y : 1;
+ int : 0;
+ int z : 5;
+ int a : 7;
+ unsigned int b : 7;
+ };
+ TEST_STRUCT(3,1,15,120,120);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 5
+{
+ struct M P __s {
+ long long x : 45;
+ long long : 2;
+ long long y : 30;
+ unsigned long long z : 38;
+ char a; short b;
+ };
+ TEST_STRUCT(0x123456789ULL, 120<<25, 120, 0x44, 0x77);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 6
+{
+ struct M P __s {
+ int a;
+ signed char b;
+ int x : 12, y : 4, : 0, : 4, z : 3;
+ char d;
+ };
+ TEST_STRUCT(1,2,3,4,-3);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif defined PACK
+
+#if PACK
+# pragma pack(push,1)
+# define P //_P
+#else
+# define P
+#endif
+
+printf("\n\n" + 2*top);
+#define TEST 1
+#include SELF
+top = 0;
+#define TEST 2
+#include SELF
+#define TEST 3
+#include SELF
+#define TEST 4
+#include SELF
+#define TEST 5
+#include SELF
+#define TEST 6
+#include SELF
+
+#if PACK
+# pragma pack(pop)
+#endif
+
+#undef P
+#undef PACK
+
+/* ----------------------------------------------------------------------- */
+#elif defined ALIGN
+
+#if ALIGN
+# define A _A(16)
+#else
+# define A
+#endif
+
+#define PACK 0
+#include SELF
+#define PACK 1
+#include SELF
+
+#undef A
+#undef ALIGN
+
+/* ----------------------------------------------------------------------- */
+#elif defined MS_BF
+
+#if MS_BF
+# ifdef __TINYC__
+# pragma comment(option, "-mms-bitfields")
+# elif defined __GNUC__
+# define M __attribute__((ms_struct))
+# endif
+#else
+# ifdef __TINYC__
+# pragma comment(option, "-mno-ms-bitfields")
+# elif defined __GNUC__
+# define M __attribute__((gcc_struct))
+# endif
+#endif
+#ifndef M
+# define M
+#endif
+
+#define ALIGN 0
+#include SELF
+#define ALIGN 1
+#include SELF
+
+#undef M
+#undef MS_BF
+
+/* ----------------------------------------------------------------------- */
+#else
+
+#include <stdio.h>
+#include <string.h>
+/* some gcc headers #define __attribute__ to empty if it's not gcc */
+#undef __attribute__
+
+void dump(void *p, int s)
+{
+ int i;
+ for (i = s; --i >= 0;)
+ printf("%02X", ((unsigned char*)p)[i]);
+ printf("\n");
+}
+
+#define pv(m) \
+ printf(sizeof (s->m + 0) == 8 ? " %016llx" : " %02x", s->m)
+
+#define TEST_STRUCT(v1,v2,v3,v4,v5) { \
+ struct __s _s, *s = & _s; \
+ printf("\n---- TEST %d%s%s%s ----\n" + top, \
+ TEST, MS_BF?" - MS-BITFIELDS":"", \
+ PACK?" - PACKED":"", \
+ ALIGN?" - WITH ALIGN":""); \
+ memset(s, 0, sizeof *s); \
+ s->x = -1, s->y = -1, s->z = -1, s->a = -1, s->b = -1; \
+ printf("bits in use : "), dump(s, sizeof *s); \
+ s->x = v1, s->y = v2, s->z = v3, s->a += v4, ++s->a, s->b = v5; \
+ printf("bits as set : "), dump(s, sizeof *s); \
+ printf("values :"), pv(x), pv(y), pv(z), pv(a), pv(b), printf("\n"); \
+ printf("align/size : %d %d\n", alignof(struct __s),sizeof(struct __s)); \
+ }
+
+#ifdef _MSC_VER
+# define _A(n) __declspec(align(n))
+# define _P
+# define alignof(x) __alignof(x)
+#else
+# define _A(n) __attribute__((aligned(n)))
+# define _P __attribute__((packed))
+# define alignof(x) __alignof__(x)
+#endif
+
+#ifndef MS_BITFIELDS
+# define MS_BITFIELDS 0
+#endif
+
+#define SELF "95_bitfields.c"
+
+int top = 1;
+
+int main()
+{
+#define MS_BF MS_BITFIELDS
+#include SELF
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+#endif
+#undef TEST
diff --git a/tests/tests2/95_bitfields.expect b/tests/tests2/95_bitfields.expect
new file mode 100644
index 0000000..6a8fd9a
--- /dev/null
+++ b/tests/tests2/95_bitfields.expect
@@ -0,0 +1,149 @@
+---- TEST 1 ----
+bits in use : 0000001FFFFFFFFF007F0FFF
+bits as set : 000000076055555500440333
+values : 333 44 555555 06 07
+align/size : 4 12
+
+---- TEST 2 ----
+bits in use : 000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF
+bits as set : 0000000000000025123456789ABCDEF000000000001E0003
+values : 03 1e 123456789abcdef0 05 fffffffe
+align/size : 8 24
+
+---- TEST 3 ----
+bits in use : 001F1F1F000003FF
+bits as set : 000E0619000002F5
+values : 15 17 19 06 0e
+align/size : 4 8
+
+---- TEST 4 ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values : 03 ffffffff 0f fffffff8 78
+align/size : 4 8
+
+---- TEST 5 ----
+bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000007800000000300000000000000123456789
+values : 0000000123456789 f0000000 0000000000000078 44 77
+align/size : 8 24
+
+---- TEST 6 ----
+bits in use : 0000007000FFFFFFFFFFFFFF
+bits as set : 00000030002001FD00000004
+values : 01 02 03 04 fffffffd
+align/size : 4 12
+
+
+
+---- TEST 1 - PACKED ----
+bits in use : FFFFFFFFFFFFFF
+bits as set : 3B02AAAAAC4333
+values : 333 44 555555 06 07
+align/size : 1 7
+
+---- TEST 2 - PACKED ----
+bits in use : 7FFFFFFFFFFFFFFFFFFFFF
+bits as set : 4A48D159E26AF37BC1E003
+values : 03 1e 123456789abcdef0 05 fffffffe
+align/size : 1 11
+
+---- TEST 3 - PACKED ----
+bits in use : 7FFF000003FF
+bits as set : 38D9000002F5
+values : 15 17 19 06 0e
+align/size : 1 6
+
+---- TEST 4 - PACKED ----
+bits in use : 07FFFF00000027
+bits as set : 078F0F00000023
+values : 03 ffffffff 0f fffffff8 78
+align/size : 1 7
+
+---- TEST 5 - PACKED ----
+bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF
+bits as set : 007744000000000F18000000000123456789
+values : 0000000123456789 f0000000 0000000000000078 44 77
+align/size : 1 18
+
+---- TEST 6 - PACKED ----
+bits in use : 007000FFFFFFFFFFFFFF
+bits as set : 0030002001FD00000004
+values : 01 02 03 04 fffffffd
+align/size : 1 10
+
+
+
+---- TEST 1 - WITH ALIGN ----
+bits in use : 000000000000001FFFFFFFFF007F0FFF
+bits as set : 00000000000000076055555500440333
+values : 333 44 555555 06 07
+align/size : 16 16
+
+---- TEST 2 - WITH ALIGN ----
+bits in use : 0000000000000000000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF
+bits as set : 00000000000000000000000000000025123456789ABCDEF000000000001E0003
+values : 03 1e 123456789abcdef0 05 fffffffe
+align/size : 16 32
+
+---- TEST 3 - WITH ALIGN ----
+bits in use : 0000000000000000000000000000001F000000000000000000001F1F000003FF
+bits as set : 0000000000000000000000000000000E000000000000000000000619000002F5
+values : 15 17 19 06 0e
+align/size : 16 32
+
+---- TEST 4 - WITH ALIGN ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values : 03 ffffffff 0f fffffff8 78
+align/size : 4 8
+
+---- TEST 5 - WITH ALIGN ----
+bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000007800000000300000000000000123456789
+values : 0000000123456789 f0000000 0000000000000078 44 77
+align/size : 8 24
+
+---- TEST 6 - WITH ALIGN ----
+bits in use : 0000007000FFFFFFFFFFFFFF
+bits as set : 00000030002001FD00000004
+values : 01 02 03 04 fffffffd
+align/size : 4 12
+
+
+
+---- TEST 1 - PACKED - WITH ALIGN ----
+bits in use : 000000000000000000FFFFFFFFFFFFFF
+bits as set : 0000000000000000003B02AAAAAC4333
+values : 333 44 555555 06 07
+align/size : 16 16
+
+---- TEST 2 - PACKED - WITH ALIGN ----
+bits in use : 3F01FFFFFFFFFFFFFFFFFFFF
+bits as set : 250048D159E26AF37BC1E003
+values : 03 1e 123456789abcdef0 05 fffffffe
+align/size : 1 12
+
+---- TEST 3 - PACKED - WITH ALIGN ----
+bits in use : 1F03FF000003FF
+bits as set : 0E00D9000002F5
+values : 15 17 19 06 0e
+align/size : 1 7
+
+---- TEST 4 - PACKED - WITH ALIGN ----
+bits in use : 07FFFF00000027
+bits as set : 078F0F00000023
+values : 03 ffffffff 0f fffffff8 78
+align/size : 1 7
+
+---- TEST 5 - PACKED - WITH ALIGN ----
+bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF
+bits as set : 007744000000000F18000000000123456789
+values : 0000000123456789 f0000000 0000000000000078 44 77
+align/size : 1 18
+
+---- TEST 6 - PACKED - WITH ALIGN ----
+bits in use : 007000FFFFFFFFFFFFFF
+bits as set : 0030002001FD00000004
+values : 01 02 03 04 fffffffd
+align/size : 1 10
diff --git a/tests/tests2/95_bitfields_ms.c b/tests/tests2/95_bitfields_ms.c
new file mode 100644
index 0000000..b196fbd
--- /dev/null
+++ b/tests/tests2/95_bitfields_ms.c
@@ -0,0 +1,2 @@
+#define MS_BITFIELDS 1
+#include "95_bitfields.c"
diff --git a/tests/tests2/95_bitfields_ms.expect b/tests/tests2/95_bitfields_ms.expect
new file mode 100644
index 0000000..8ccafb7
--- /dev/null
+++ b/tests/tests2/95_bitfields_ms.expect
@@ -0,0 +1,149 @@
+---- TEST 1 - MS-BITFIELDS ----
+bits in use : 0000001FFFFFFFFF0000007F00000FFF
+bits as set : 00000007605555550000004400000333
+values : 333 44 555555 06 07
+align/size : 4 16
+
+---- TEST 2 - MS-BITFIELDS ----
+bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF
+bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003
+values : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size : 8 32
+
+---- TEST 3 - MS-BITFIELDS ----
+bits in use : 001F001F0000001F000003FF
+bits as set : 000E000600000019000002F5
+values : 15 17 19 06 0e
+align/size : 4 12
+
+---- TEST 4 - MS-BITFIELDS ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values : 03 ffffffff 0f fffffff8 78
+align/size : 4 8
+
+---- TEST 5 - MS-BITFIELDS ----
+bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 0000000000770044000000000000007800000000300000000000000123456789
+values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size : 8 32
+
+---- TEST 6 - MS-BITFIELDS ----
+bits in use : 00000000000000700000FFFF000000FFFFFFFFFF
+bits as set : 000000000000003000002001000000FD00000004
+values : 01 02 03 04 fffffffd
+align/size : 4 20
+
+
+
+---- TEST 1 - MS-BITFIELDS - PACKED ----
+bits in use : 0000001FFFFFFFFF7F00000FFF
+bits as set : 00000007605555554400000333
+values : 333 44 555555 06 07
+align/size : 1 13
+
+---- TEST 2 - MS-BITFIELDS - PACKED ----
+bits in use : 00000000000000030F7FFFFFFFFFFFFFFF3F00000FFF
+bits as set : 000000000000000205123456789ABCDEF01E00000003
+values : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size : 1 22
+
+---- TEST 3 - MS-BITFIELDS - PACKED ----
+bits in use : 001F1F0000001F000003FF
+bits as set : 000E0600000019000002F5
+values : 15 17 19 06 0e
+align/size : 1 11
+
+---- TEST 4 - MS-BITFIELDS - PACKED ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values : 03 ffffffff 0f fffffff8 78
+align/size : 1 8
+
+---- TEST 5 - MS-BITFIELDS - PACKED ----
+bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000000000007800000000300000000000000123456789
+values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size : 1 27
+
+---- TEST 6 - MS-BITFIELDS - PACKED ----
+bits in use : 00000000700000FFFFFFFFFFFFFF
+bits as set : 000000003000002001FD00000004
+values : 01 02 03 04 fffffffd
+align/size : 1 14
+
+
+
+---- TEST 1 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0000001FFFFFFFFF0000007F00000FFF
+bits as set : 00000007605555550000004400000333
+values : 333 44 555555 06 07
+align/size : 16 16
+
+---- TEST 2 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF
+bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003
+values : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size : 16 32
+
+---- TEST 3 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0000000000000000000000000000001F000000000000001F0000001F000003FF
+bits as set : 0000000000000000000000000000000E000000000000000600000019000002F5
+values : 15 17 19 06 0e
+align/size : 16 32
+
+---- TEST 4 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values : 03 ffffffff 0f fffffff8 78
+align/size : 4 8
+
+---- TEST 5 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 0000000000770044000000000000007800000000300000000000000123456789
+values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size : 8 32
+
+---- TEST 6 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 00000000000000700000FFFF000000FFFFFFFFFF
+bits as set : 000000000000003000002001000000FD00000004
+values : 01 02 03 04 fffffffd
+align/size : 4 20
+
+
+
+---- TEST 1 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 0000000000001FFFFFFFFF7F00000FFF
+bits as set : 00000000000007605555554400000333
+values : 333 44 555555 06 07
+align/size : 16 16
+
+---- TEST 2 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 00000000000000030F0000007FFFFFFFFFFFFFFF3F00000FFF
+bits as set : 000000000000000205000000123456789ABCDEF01E00000003
+values : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size : 16 25
+
+---- TEST 3 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 001F000000000000001F0000001F000003FF
+bits as set : 000E000000000000000600000019000002F5
+values : 15 17 19 06 0e
+align/size : 16 18
+
+---- TEST 4 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values : 03 ffffffff 0f fffffff8 78
+align/size : 1 8
+
+---- TEST 5 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000000000007800000000300000000000000123456789
+values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size : 1 27
+
+---- TEST 6 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 00000000700000FFFFFFFFFFFFFF
+bits as set : 000000003000002001FD00000004
+values : 01 02 03 04 fffffffd
+align/size : 1 14
diff --git a/tests/tests2/96_nodata_wanted.c b/tests/tests2/96_nodata_wanted.c
new file mode 100644
index 0000000..cc211d3
--- /dev/null
+++ b/tests/tests2/96_nodata_wanted.c
@@ -0,0 +1,84 @@
+/*****************************************************************************/
+/* test 'nodata_wanted' data output suppression */
+
+#if defined test_static_data_error
+void foo() {
+ if (1) {
+ static short w = (int)&foo; /* initializer not computable */
+ }
+}
+
+#elif defined test_static_nodata_error
+void foo() {
+ if (0) {
+ static short w = (int)&foo; /* initializer not computable */
+ }
+}
+
+#elif defined test_global_data_error
+void foo();
+static short w = (int)&foo; /* initializer not computable */
+
+
+#elif defined test_local_data_noerror
+void foo() {
+ short w = &foo; /* 2 cast warnings */
+}
+
+#elif defined test_data_suppression_off || defined test_data_suppression_on
+
+#if defined test_data_suppression_on
+# define SKIP 1
+#else
+# define SKIP 0
+#endif
+
+#include <stdio.h>
+/* some gcc headers #define __attribute__ to empty if it's not gcc */
+#undef __attribute__
+
+int main()
+{
+ __label__ ts0, te0, ts1, te1;
+ int tl, dl;
+
+ static char ds0 = 0;
+ static char de0 = 0;
+ /* get reference size of empty jmp */
+ts0:;
+ if (!SKIP) {}
+te0:;
+ dl = -(&de0 - &ds0);
+ tl = -(&&te0 - &&ts0);
+
+ /* test data and code suppression */
+ static char ds1 = 0;
+ts1:;
+ if (!SKIP) {
+ static void *p = (void*)&main;
+ static char cc[] = "static string";
+ static double d = 8.0;
+
+ static struct __attribute__((packed)) {
+ unsigned x : 12;
+ unsigned char y : 7;
+ unsigned z : 28, a: 4, b: 5;
+ } s = { 0x333,0x44,0x555555,6,7 };
+
+ printf("data:\n");
+ printf(" %d - %.1f - %.1f - %s - %s\n",
+ sizeof 8.0, 8.0, d, __FUNCTION__, cc);
+ printf(" %x %x %x %x %x\n",
+ s.x, s.y, s.z, s.a, s.b);
+ }
+te1:;
+ static char de1 = 0;
+
+ dl += &de1 - &ds1;
+ tl += &&te1 - &&ts1;
+ printf("size of data/text:\n %s/%s\n",
+ dl ? "non-zero":"zero", tl ? "non-zero":"zero");
+ /*printf("# %d/%d\n", dl, tl);*/
+}
+
+#endif
diff --git a/tests/tests2/96_nodata_wanted.expect b/tests/tests2/96_nodata_wanted.expect
new file mode 100644
index 0000000..2749109
--- /dev/null
+++ b/tests/tests2/96_nodata_wanted.expect
@@ -0,0 +1,23 @@
+[test_static_data_error]
+96_nodata_wanted.c:7: error: initializer element is not computable at load time
+
+[test_static_nodata_error]
+96_nodata_wanted.c:14: error: initializer element is not computable at load time
+
+[test_global_data_error]
+96_nodata_wanted.c:20: error: initializer element is not computable at load time
+
+[test_local_data_noerror]
+96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast
+96_nodata_wanted.c:25: warning: nonportable conversion from pointer to char/short
+
+[test_data_suppression_off]
+data:
+ 8 - 8.0 - 8.0 - main - static string
+ 333 44 555555 6 7
+size of data/text:
+ non-zero/non-zero
+
+[test_data_suppression_on]
+size of data/text:
+ zero/zero
diff --git a/tests/tests2/97_utf8_string_literal.c b/tests/tests2/97_utf8_string_literal.c
new file mode 100644
index 0000000..96fbab0
--- /dev/null
+++ b/tests/tests2/97_utf8_string_literal.c
@@ -0,0 +1,12 @@
+// this file contains BMP chars encoded in UTF-8
+#include <stdio.h>
+#include <wchar.h>
+
+int main()
+{
+ wchar_t s[] = L"hello$$你好¢¢世界€€world";
+ wchar_t *p;
+ for (p = s; *p; p++) printf("%04X ", (unsigned) *p);
+ printf("\n");
+ return 0;
+}
diff --git a/tests/tests2/97_utf8_string_literal.expect b/tests/tests2/97_utf8_string_literal.expect
new file mode 100644
index 0000000..9a1593c
--- /dev/null
+++ b/tests/tests2/97_utf8_string_literal.expect
@@ -0,0 +1 @@
+0068 0065 006C 006C 006F 0024 0024 4F60 597D 00A2 00A2 4E16 754C 20AC 20AC 0077 006F 0072 006C 0064
diff --git a/tests/tests2/98_al_ax_extend.c b/tests/tests2/98_al_ax_extend.c
new file mode 100644
index 0000000..9b4e02f
--- /dev/null
+++ b/tests/tests2/98_al_ax_extend.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+asm (
+ ".text;"
+ ".globl _us;.globl _ss;.globl _uc;.globl _sc;"
+ "_us:;_ss:;_uc:;_sc:;"
+ "movl $0x1234ABCD, %eax;"
+ "ret;"
+);
+
+#if 1
+#define us _us
+#define ss _ss
+#define uc _uc
+#define sc _sc
+#endif
+
+int main()
+{
+ unsigned short us(void);
+ short ss(void);
+ unsigned char uc(void);
+ signed char sc(void);
+
+ unsigned short (*fpus)(void) = us;
+ short (*fpss)(void) = ss;
+ unsigned char (*fpuc)(void) = uc;
+ signed char (*fpsc)(void) = sc;
+
+ printf("%08X %08X\n", us() + 1, fpus() + 1);
+ printf("%08X %08X\n", ss() + 1, fpss() + 1);
+ printf("%08X %08X\n", uc() + 1, fpuc() + 1);
+ printf("%08X %08X\n", sc() + 1, fpsc() + 1);
+ printf("\n");
+ printf("%08X %08X\n", fpus() + 1, us() + 1);
+ printf("%08X %08X\n", fpss() + 1, ss() + 1);
+ printf("%08X %08X\n", fpuc() + 1, uc() + 1);
+ printf("%08X %08X\n", fpsc() + 1, sc() + 1);
+
+ return 0;
+}
diff --git a/tests/tests2/98_al_ax_extend.expect b/tests/tests2/98_al_ax_extend.expect
new file mode 100644
index 0000000..c5752e8
--- /dev/null
+++ b/tests/tests2/98_al_ax_extend.expect
@@ -0,0 +1,9 @@
+0000ABCE 0000ABCE
+FFFFABCE FFFFABCE
+000000CE 000000CE
+FFFFFFCE FFFFFFCE
+
+0000ABCE 0000ABCE
+FFFFABCE FFFFABCE
+000000CE 000000CE
+FFFFFFCE FFFFFFCE
diff --git a/tests/tests2/99_fastcall.c b/tests/tests2/99_fastcall.c
new file mode 100644
index 0000000..ee4b67d
--- /dev/null
+++ b/tests/tests2/99_fastcall.c
@@ -0,0 +1,276 @@
+#include <stdio.h>
+#include <assert.h>
+
+#ifndef _WIN32
+#define __fastcall __attribute((fastcall))
+#endif
+
+#if 1
+#define SYMBOL(x) _##x
+#else
+#define SYMBOL(x) x
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+////////// TRAP FRAMEWORK
+/////////////////////////////////////////////////////////////////////////
+// if you cast 'TRAP' to a function pointer and call it,
+// it will save all 8 registers,
+// and jump into C-code (previously set using 'SET_TRAP_HANDLER(x)'),
+// in C-code you can pop DWORDs from stack and modify registers
+//
+
+void *SYMBOL(trap_handler);
+
+extern unsigned char SYMBOL(trap)[];
+asm (
+ ".text;"
+ "_trap:;"
+ "pushl %esp;"
+ "pusha;"
+ "addl $0x4, 0xc(%esp);"
+ "pushl %esp;"
+ "call *_trap_handler;"
+ "addl $0x4, %esp;"
+ "movl 0xc(%esp), %eax;"
+ "movl %eax, 0x20(%esp);"
+ "popa;"
+ "popl %esp;"
+ "ret;"
+);
+
+struct trapframe {
+ unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax;
+};
+
+
+#define M_FLOAT(addr) (*(float *)(addr))
+#define M_DWORD(addr) (*(unsigned *)(addr))
+#define M_WORD(addr) (*(unsigned short *)(addr))
+#define M_BYTE(addr) (*(unsigned char *)(addr))
+#define R_EAX ((tf)->eax)
+#define R_ECX ((tf)->ecx)
+#define R_EDX ((tf)->edx)
+#define R_EBX ((tf)->ebx)
+#define R_ESP ((tf)->esp)
+#define R_EBP ((tf)->ebp)
+#define R_ESI ((tf)->esi)
+#define R_EDI ((tf)->edi)
+
+#define ARG(x) (M_DWORD(R_ESP + (x) * 4))
+
+#define RETN(x) do { \
+ M_DWORD(R_ESP + (x)) = M_DWORD(R_ESP); \
+ R_ESP += (x); \
+} while (0)
+
+#define DUMP() do { \
+ unsigned i; \
+ printf("EAX: %08X\n", R_EAX); \
+ printf("ECX: %08X\n", R_ECX); \
+ printf("EDX: %08X\n", R_EDX); \
+ printf("EBX: %08X\n", R_EBX); \
+ printf("ESP: %08X\n", R_ESP); \
+ printf("EBP: %08X\n", R_EBP); \
+ printf("ESI: %08X\n", R_ESI); \
+ printf("EDI: %08X\n", R_EDI); \
+ printf("\n"); \
+ printf("[RETADDR]: %08X\n", M_DWORD(R_ESP)); \
+ for (i = 1; i <= 8; i++) { \
+ printf("[ARG%4d]: %08X\n", i, ARG(i)); \
+ } \
+} while (0)
+
+#define SET_TRAP_HANDLER(x) ((SYMBOL(trap_handler)) = (x))
+#define TRAP ((void *) &SYMBOL(trap))
+
+
+
+/////////////////////////////////////////////////////////////////////////
+////////// SAFECALL FRAMEWORK
+/////////////////////////////////////////////////////////////////////////
+// this framework will convert any calling convention to cdecl
+// usage: first set call target with 'SET_SAFECALL_TARGET(x)'
+// then cast 'SAFECALL' to target function pointer type and invoke it
+// after calling, 'ESPDIFF' is the difference of old and new esp
+
+void *SYMBOL(sc_call_target);
+unsigned SYMBOL(sc_retn_addr);
+unsigned SYMBOL(sc_old_esp);
+unsigned SYMBOL(sc_new_esp);
+
+extern unsigned char SYMBOL(safecall)[];
+asm (
+ ".text;"
+ "_safecall:;"
+ "popl _sc_retn_addr;"
+ "movl %esp, _sc_old_esp;"
+ "call *_sc_call_target;"
+ "movl %esp, _sc_new_esp;"
+ "movl _sc_old_esp, %esp;"
+ "jmp *_sc_retn_addr;"
+);
+
+#define SET_SAFECALL_TARGET(x) ((SYMBOL(sc_call_target)) = (x))
+#define SAFECALL ((void *) &SYMBOL(safecall))
+#define ESPDIFF (SYMBOL(sc_new_esp) - SYMBOL(sc_old_esp))
+
+
+/////////////////////////////////////////////////////////////////////////
+////////// TEST FASTCALL INVOKE
+/////////////////////////////////////////////////////////////////////////
+
+void check_fastcall_invoke_0(struct trapframe *tf)
+{
+ //DUMP();
+ RETN(0);
+}
+
+void check_fastcall_invoke_1(struct trapframe *tf)
+{
+ //DUMP();
+ assert(R_ECX == 0x11111111);
+ RETN(0);
+}
+void check_fastcall_invoke_2(struct trapframe *tf)
+{
+ //DUMP();
+ assert(R_ECX == 0x11111111);
+ assert(R_EDX == 0x22222222);
+ RETN(0);
+}
+void check_fastcall_invoke_3(struct trapframe *tf)
+{
+ //DUMP();
+ assert(R_ECX == 0x11111111);
+ assert(R_EDX == 0x22222222);
+ assert(ARG(1) == 0x33333333);
+ RETN(1*4);
+}
+void check_fastcall_invoke_4(struct trapframe *tf)
+{
+ //DUMP();
+ assert(R_ECX == 0x11111111);
+ assert(R_EDX == 0x22222222);
+ assert(ARG(1) == 0x33333333);
+ assert(ARG(2) == 0x44444444);
+ RETN(2*4);
+}
+
+void check_fastcall_invoke_5(struct trapframe *tf)
+{
+ //DUMP();
+ assert(R_ECX == 0x11111111);
+ assert(R_EDX == 0x22222222);
+ assert(ARG(1) == 0x33333333);
+ assert(ARG(2) == 0x44444444);
+ assert(ARG(3) == 0x55555555);
+ RETN(3*4);
+}
+
+void test_fastcall_invoke()
+{
+ SET_TRAP_HANDLER(check_fastcall_invoke_0);
+ ((void __fastcall (*)(void)) TRAP)();
+
+ SET_TRAP_HANDLER(check_fastcall_invoke_1);
+ ((void __fastcall (*)(unsigned)) TRAP)(0x11111111);
+
+ SET_TRAP_HANDLER(check_fastcall_invoke_2);
+ ((void __fastcall (*)(unsigned, unsigned)) TRAP)(0x11111111, 0x22222222);
+
+ SET_TRAP_HANDLER(check_fastcall_invoke_3);
+ ((void __fastcall (*)(unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333);
+
+ SET_TRAP_HANDLER(check_fastcall_invoke_4);
+ ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444);
+
+ SET_TRAP_HANDLER(check_fastcall_invoke_5);
+ ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555);
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+////////// TEST FUNCTION CODE GENERATION
+/////////////////////////////////////////////////////////////////////////
+
+int __fastcall check_fastcall_espdiff_0(void)
+{
+ return 0;
+}
+
+int __fastcall check_fastcall_espdiff_1(int a)
+{
+ return a;
+}
+
+int __fastcall check_fastcall_espdiff_2(int a, int b)
+{
+ return a + b;
+}
+
+int __fastcall check_fastcall_espdiff_3(int a, int b, int c)
+{
+ return a + b + c;
+}
+
+int __fastcall check_fastcall_espdiff_4(int a, int b, int c, int d)
+{
+ return a + b + c + d;
+}
+
+int __fastcall check_fastcall_espdiff_5(int a, int b, int c, int d, int e)
+{
+ return a + b + c + d + e;
+}
+
+void test_fastcall_espdiff()
+{
+ int x;
+ SET_SAFECALL_TARGET(check_fastcall_espdiff_0);
+ x = ((typeof(&check_fastcall_espdiff_0))SAFECALL)();
+ assert(x == 0);
+ assert(ESPDIFF == 0);
+
+ SET_SAFECALL_TARGET(check_fastcall_espdiff_1);
+ x = ((typeof(&check_fastcall_espdiff_1))SAFECALL)(1);
+ assert(x == 1);
+ assert(ESPDIFF == 0);
+
+ SET_SAFECALL_TARGET(check_fastcall_espdiff_2);
+ x = ((typeof(&check_fastcall_espdiff_2))SAFECALL)(1, 2);
+ assert(x == 1 + 2);
+ assert(ESPDIFF == 0);
+
+ SET_SAFECALL_TARGET(check_fastcall_espdiff_3);
+ x = ((typeof(&check_fastcall_espdiff_3))SAFECALL)(1, 2, 3);
+ assert(x == 1 + 2 + 3);
+ assert(ESPDIFF == 1*4);
+
+ SET_SAFECALL_TARGET(check_fastcall_espdiff_4);
+ x = ((typeof(&check_fastcall_espdiff_4))SAFECALL)(1, 2, 3, 4);
+ assert(x == 1 + 2 + 3 + 4);
+ assert(ESPDIFF == 2*4);
+
+ SET_SAFECALL_TARGET(check_fastcall_espdiff_5);
+ x = ((typeof(&check_fastcall_espdiff_5))SAFECALL)(1, 2, 3, 4, 5);
+ assert(x == 1 + 2 + 3 + 4 + 5);
+ assert(ESPDIFF == 3*4);
+}
+
+int main()
+{
+#define N 10000
+ int i;
+
+ for (i = 1; i <= N; i++) {
+ test_fastcall_espdiff();
+ }
+
+ for (i = 1; i <= N; i++) {
+ test_fastcall_invoke();
+ }
+
+ puts("TEST OK");
+ return 0;
+}
diff --git a/tests/tests2/99_fastcall.expect b/tests/tests2/99_fastcall.expect
new file mode 100644
index 0000000..3835d63
--- /dev/null
+++ b/tests/tests2/99_fastcall.expect
@@ -0,0 +1 @@
+TEST OK
diff --git a/tests/tests2/LICENSE b/tests/tests2/LICENSE
new file mode 100644
index 0000000..b08a652
--- /dev/null
+++ b/tests/tests2/LICENSE
@@ -0,0 +1,37 @@
+The tests in this directory are either directly copied from the picoc project or
+are subsequently modified and added to for the purpose of TinyCC project. All
+these modifications are licensed under the same terms as TinyCC as specified in
+the file COPYING.
+
+=== picoc license ===
+
+Copyright (c) 2009-2011, Zik Saleeba
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of the Zik Saleeba nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile
new file mode 100644
index 0000000..190b2d9
--- /dev/null
+++ b/tests/tests2/Makefile
@@ -0,0 +1,112 @@
+TOP = ../..
+include $(TOP)/Makefile
+SRC = $(TOPSRC)/tests/tests2
+VPATH = $(SRC)
+
+TESTS = $(patsubst %.c,%.test,$(sort $(notdir $(wildcard $(SRC)/*.c))))
+
+# some tests do not pass on all platforms, remove them for now
+SKIP = 34_array_assignment.test # array assignment is not in C standard
+ifeq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
+ SKIP += 22_floating_point.test
+endif
+ifdef CONFIG_OSX
+ SKIP += 40_stdio.test 42_function_pointer.test
+ FLAGS += -w
+endif
+ifeq ($(ARCH),x86_64)
+ SKIP += 73_arm64.test
+endif
+ifeq (,$(filter i386,$(ARCH)))
+ SKIP += 98_al_ax_extend.test 99_fastcall.test
+endif
+ifeq (,$(filter i386 x86_64,$(ARCH)))
+ SKIP += 85_asm-outside-function.test
+endif
+ifeq (-$(findstring gcc,$(CC))-,--)
+ SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
+endif
+ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-)
+ SKIP += 95_bitfields%.test # type_align is different on 32bit-non-windows
+endif
+
+# Some tests might need arguments
+ARGS =
+31_args.test : ARGS = arg1 arg2 arg3 arg4 arg5
+46_grep.test : ARGS = '[^* ]*[:a:d: ]+\:\*-/: $$' $(SRC)/46_grep.c
+
+# And some tests don't test the right thing with -run
+NORUN =
+42_function_pointer.test : NORUN = true
+
+# Some tests might need different flags
+FLAGS =
+76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers
+
+# These tests run several snippets from the same file one by one
+60_errors_and_warnings.test : FLAGS += -dt
+96_nodata_wanted.test : FLAGS += -dt
+
+# Always generate certain .expects (don't put these in the GIT),
+GEN-ALWAYS =
+# GEN-ALWAYS += 95_bitfields.expect # does not work
+
+# using the ms compiler for the really ms-compatible bitfields
+95_bitfields_ms.test : GEN = $(GEN-MSC)
+
+# Filter source directory in warnings/errors (out-of-tree builds)
+FILTER = 2>&1 | sed 's,$(SRC)/,,g'
+# Filter some always-warning
+ifeq (-$(findstring arm,$(ARCH))-,-arm-)
+FILTER += 2>&1 | grep -v 'warning: soft float ABI currently not supported'
+endif
+
+all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ;
+
+%.test: %.c %.expect
+ @echo Test: $*...
+ @$(if $(NORUN),$(T1),$(T2)) $(if $(NODIFF),,$(T3))
+
+T1 = $(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS)
+T2 = $(TCC) $(FLAGS) -run $< $(ARGS)
+T3 = $(FILTER) >$*.output 2>&1 || true \
+ && diff -Nbu $(filter %.expect,$^) $*.output \
+ && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS))
+
+# run single test and update .expect file, e.g. "make tests2.37+"
+tests2.%+:
+ @$(MAKE) $(call F2,$(call F1,$*)) --no-print-directory
+
+# just run tcc to see the output, e.g. "make tests2.37-"
+tests2.%-:
+ @$(MAKE) $(call F1,$*) NODIFF=true --no-print-directory
+
+# run single test, e.g. "make tests2.37"
+tests2.%:
+ @$(MAKE) $(call F1,$*) --no-print-directory
+
+F1 = $(or $(filter $1_%,$(TESTS)),$1_???.test)
+F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)"
+
+# automatically generate .expect files with gcc:
+%.expect :
+ @echo Generating: $@
+ @$(call GEN,$(SRC)/$*.c) $(FILTER) >$@ 2>&1
+ @rm -f *.exe *.obj *.pdb
+
+# using TCC for .expect if -dt in FLAGS
+GEN = $(if $(filter -dt,$(FLAGS)),$(GEN-TCC),$(GEN-CC))
+GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o a.exe && ./a.exe $(ARGS)
+GEN-TCC = $(TCC) $(FLAGS) -run $1 $(ARGS)
+GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe
+MS-CC = cl
+
+# tell make not to delete
+.PRECIOUS: %.expect
+
+# force .expect generation for these files
+$(sort $(GEN-ALWAYS) $(UPDATE)) : force
+force:
+
+clean:
+ rm -f fred.txt *.output a.exe $(GEN-ALWAYS)
diff --git a/tests/vla_test.c b/tests/vla_test.c
new file mode 100644
index 0000000..3616c46
--- /dev/null
+++ b/tests/vla_test.c
@@ -0,0 +1,84 @@
+/*
+ * Test that allocating a variable length array in a loop
+ * does not use up a linear amount of memory
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define LOOP_COUNT 1000
+#define ARRAY_SIZE 100
+
+/* Overwrite a VLA. This will overwrite the return address if SP is incorrect */
+void smash(char *p, int n) {
+ memset(p, 0, n);
+}
+
+int test1(int n) {
+ int i;
+ char *array_ptrs[LOOP_COUNT];
+
+ for (i = 0; i < LOOP_COUNT; ++i) {
+ char test[n];
+ smash(test, n);
+ array_ptrs[i] = test;
+ }
+
+ return (array_ptrs[0]-array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1;
+}
+
+/* ensure goto does not circumvent array free */
+int test2(int n) {
+ char *array_ptrs[LOOP_COUNT];
+
+ int i = 0;
+loop:;
+ char test[n];
+ smash(test, n);
+ if (i >= LOOP_COUNT)
+ goto end;
+ array_ptrs[i] = test;
+ ++i;
+ goto loop;
+
+end:
+ smash(test, n);
+ char test2[n];
+ smash(test2, n);
+ return (array_ptrs[0] - array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1;
+}
+
+int test3(int n) {
+ char test[n];
+ smash(test, n);
+ goto label;
+label:
+ smash(test, n);
+ char test2[n];
+ smash(test2, n);
+ return (test-test2 >= n) ? 0 : 1;
+}
+
+#define RUN_TEST(t) \
+ if (!testname || (strcmp(#t, testname) == 0)) { \
+ fputs(#t "... ", stdout); \
+ fflush(stdout); \
+ if (t(ARRAY_SIZE) == 0) { \
+ fputs("success\n", stdout); \
+ } else { \
+ fputs("failure\n", stdout); \
+ retval = EXIT_FAILURE; \
+ } \
+ }
+
+int main(int argc, char **argv) {
+ const char *testname = NULL;
+ int retval = EXIT_SUCCESS;
+ if (argc > 1)
+ testname = argv[1];
+ RUN_TEST(test1)
+ RUN_TEST(test2)
+ RUN_TEST(test3)
+ return retval;
+}
diff --git a/texi2pod.pl b/texi2pod.pl
new file mode 100755
index 0000000..d86e176
--- /dev/null
+++ b/texi2pod.pl
@@ -0,0 +1,427 @@
+#! /usr/bin/perl -w
+
+# Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# This file is part of GNU CC.
+
+# GNU CC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# GNU CC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU CC; see the file COPYING. If not, write to
+# the Free Software Foundation, 59 Temple Place - Suite 330,
+# Boston MA 02111-1307, USA.
+
+# This does trivial (and I mean _trivial_) conversion of Texinfo
+# markup to Perl POD format. It's intended to be used to extract
+# something suitable for a manpage from a Texinfo document.
+
+$output = 0;
+$skipping = 0;
+%sects = ();
+$section = "";
+@icstack = ();
+@endwstack = ();
+@skstack = ();
+@instack = ();
+$shift = "";
+%defs = ();
+$fnno = 1;
+$inf = "";
+$ibase = "";
+
+while ($_ = shift) {
+ if (/^-D(.*)$/) {
+ if ($1 ne "") {
+ $flag = $1;
+ } else {
+ $flag = shift;
+ }
+ $value = "";
+ ($flag, $value) = ($flag =~ /^([^=]+)(?:=(.+))?/);
+ die "no flag specified for -D\n"
+ unless $flag ne "";
+ die "flags may only contain letters, digits, hyphens, dashes and underscores\n"
+ unless $flag =~ /^[a-zA-Z0-9_-]+$/;
+ $defs{$flag} = $value;
+ } elsif (/^-/) {
+ usage();
+ } else {
+ $in = $_, next unless defined $in;
+ $out = $_, next unless defined $out;
+ usage();
+ }
+}
+
+if (defined $in) {
+ $inf = gensym();
+ open($inf, "<$in") or die "opening \"$in\": $!\n";
+ $ibase = $1 if $in =~ m|^(.+)/[^/]+$|;
+} else {
+ $inf = \*STDIN;
+}
+
+if (defined $out) {
+ open(STDOUT, ">$out") or die "opening \"$out\": $!\n";
+}
+
+while(defined $inf) {
+while(<$inf>) {
+ # Certain commands are discarded without further processing.
+ /^\@(?:
+ [a-z]+index # @*index: useful only in complete manual
+ |need # @need: useful only in printed manual
+ |(?:end\s+)?group # @group .. @end group: ditto
+ |page # @page: ditto
+ |node # @node: useful only in .info file
+ |(?:end\s+)?ifnottex # @ifnottex .. @end ifnottex: use contents
+ )\b/x and next;
+
+ chomp;
+
+ # Look for filename and title markers.
+ /^\@setfilename\s+([^.]+)/ and $fn = $1, next;
+ /^\@settitle\s+([^.]+)/ and $tl = postprocess($1), next;
+
+ # Identify a man title but keep only the one we are interested in.
+ /^\@c\s+man\s+title\s+([A-Za-z0-9-]+)\s+(.+)/ and do {
+ if (exists $defs{$1}) {
+ $fn = $1;
+ $tl = postprocess($2);
+ }
+ next;
+ };
+
+ # Look for blocks surrounded by @c man begin SECTION ... @c man end.
+ # This really oughta be @ifman ... @end ifman and the like, but such
+ # would require rev'ing all other Texinfo translators.
+ /^\@c\s+man\s+begin\s+([A-Z]+)\s+([A-Za-z0-9-]+)/ and do {
+ $output = 1 if exists $defs{$2};
+ $sect = $1;
+ next;
+ };
+ /^\@c\s+man\s+begin\s+([A-Z]+)/ and $sect = $1, $output = 1, next;
+ /^\@c\s+man\s+end/ and do {
+ $sects{$sect} = "" unless exists $sects{$sect};
+ $sects{$sect} .= postprocess($section);
+ $section = "";
+ $output = 0;
+ next;
+ };
+
+ # handle variables
+ /^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and do {
+ $defs{$1} = $2;
+ next;
+ };
+ /^\@clear\s+([a-zA-Z0-9_-]+)/ and do {
+ delete $defs{$1};
+ next;
+ };
+
+ next unless $output;
+
+ # Discard comments. (Can't do it above, because then we'd never see
+ # @c man lines.)
+ /^\@c\b/ and next;
+
+ # End-block handler goes up here because it needs to operate even
+ # if we are skipping.
+ /^\@end\s+([a-z]+)/ and do {
+ # Ignore @end foo, where foo is not an operation which may
+ # cause us to skip, if we are presently skipping.
+ my $ended = $1;
+ next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex)$/;
+
+ die "\@end $ended without \@$ended at line $.\n" unless defined $endw;
+ die "\@$endw ended by \@end $ended at line $.\n" unless $ended eq $endw;
+
+ $endw = pop @endwstack;
+
+ if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) {
+ $skipping = pop @skstack;
+ next;
+ } elsif ($ended =~ /^(?:example|smallexample|display)$/) {
+ $shift = "";
+ $_ = ""; # need a paragraph break
+ } elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) {
+ $_ = "\n=back\n";
+ $ic = pop @icstack;
+ } else {
+ die "unknown command \@end $ended at line $.\n";
+ }
+ };
+
+ # We must handle commands which can cause skipping even while we
+ # are skipping, otherwise we will not process nested conditionals
+ # correctly.
+ /^\@ifset\s+([a-zA-Z0-9_-]+)/ and do {
+ push @endwstack, $endw;
+ push @skstack, $skipping;
+ $endw = "ifset";
+ $skipping = 1 unless exists $defs{$1};
+ next;
+ };
+
+ /^\@ifclear\s+([a-zA-Z0-9_-]+)/ and do {
+ push @endwstack, $endw;
+ push @skstack, $skipping;
+ $endw = "ifclear";
+ $skipping = 1 if exists $defs{$1};
+ next;
+ };
+
+ /^\@(ignore|menu|iftex)\b/ and do {
+ push @endwstack, $endw;
+ push @skstack, $skipping;
+ $endw = $1;
+ $skipping = 1;
+ next;
+ };
+
+ next if $skipping;
+
+ # Character entities. First the ones that can be replaced by raw text
+ # or discarded outright:
+ s/\@copyright\{\}/(c)/g;
+ s/\@dots\{\}/.../g;
+ s/\@enddots\{\}/..../g;
+ s/\@([.!? ])/$1/g;
+ s/\@[:-]//g;
+ s/\@bullet(?:\{\})?/*/g;
+ s/\@TeX\{\}/TeX/g;
+ s/\@pounds\{\}/\#/g;
+ s/\@minus(?:\{\})?/-/g;
+ s/\\,/,/g;
+
+ # Now the ones that have to be replaced by special escapes
+ # (which will be turned back into text by unmunge())
+ s/&/&amp;/g;
+ s/\@\{/&lbrace;/g;
+ s/\@\}/&rbrace;/g;
+ s/\@\@/&at;/g;
+
+ # Inside a verbatim block, handle @var specially.
+ if ($shift ne "") {
+ s/\@var\{([^\}]*)\}/<$1>/g;
+ }
+
+ # POD doesn't interpret E<> inside a verbatim block.
+ if ($shift eq "") {
+ s/</&lt;/g;
+ s/>/&gt;/g;
+ } else {
+ s/</&LT;/g;
+ s/>/&GT;/g;
+ }
+
+ # Single line command handlers.
+
+ /^\@include\s+(.+)$/ and do {
+ push @instack, $inf;
+ $inf = gensym();
+
+ # Try cwd and $ibase.
+ open($inf, "<" . $1)
+ or open($inf, "<" . $ibase . "/" . $1)
+ or die "cannot open $1 or $ibase/$1: $!\n";
+ next;
+ };
+
+ /^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/
+ and $_ = "\n=head2 $1\n";
+ /^\@subsection\s+(.+)$/
+ and $_ = "\n=head3 $1\n";
+
+ # Block command handlers:
+ /^\@itemize\s+(\@[a-z]+|\*|-)/ and do {
+ push @endwstack, $endw;
+ push @icstack, $ic;
+ $ic = $1;
+ $_ = "\n=over 4\n";
+ $endw = "itemize";
+ };
+
+ /^\@enumerate(?:\s+([a-zA-Z0-9]+))?/ and do {
+ push @endwstack, $endw;
+ push @icstack, $ic;
+ if (defined $1) {
+ $ic = $1 . ".";
+ } else {
+ $ic = "1.";
+ }
+ $_ = "\n=over 4\n";
+ $endw = "enumerate";
+ };
+
+ /^\@([fv]?table)\s+(\@[a-z]+)/ and do {
+ push @endwstack, $endw;
+ push @icstack, $ic;
+ $endw = $1;
+ $ic = $2;
+ $ic =~ s/\@(?:samp|strong|key|gcctabopt|option|env)/B/;
+ $ic =~ s/\@(?:code|kbd)/C/;
+ $ic =~ s/\@(?:dfn|var|emph|cite|i)/I/;
+ $ic =~ s/\@(?:file)/F/;
+ $_ = "\n=over 4\n";
+ };
+
+ /^\@((?:small)?example|display)/ and do {
+ push @endwstack, $endw;
+ $endw = $1;
+ $shift = "\t";
+ $_ = ""; # need a paragraph break
+ };
+
+ /^\@itemx?\s*(.+)?$/ and do {
+ if (defined $1) {
+ # Entity escapes prevent munging by the <> processing below.
+ $_ = "\n=item $ic\&LT;$1\&GT;\n";
+ } else {
+ $_ = "\n=item $ic\n";
+ $ic =~ y/A-Ya-y/B-Zb-z/;
+ $ic =~ s/(\d+)/$1 + 1/eg;
+ }
+ };
+
+ $section .= $shift.$_."\n";
+}
+# End of current file.
+close($inf);
+$inf = pop @instack;
+}
+
+die "No filename or title\n" unless defined $fn && defined $tl;
+
+$sects{NAME} = "$fn \- $tl\n";
+$sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES};
+
+for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS ENVIRONMENT FILES
+ BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) {
+ if(exists $sects{$sect}) {
+ $head = $sect;
+ $head =~ s/SEEALSO/SEE ALSO/;
+ print "=head1 $head\n\n";
+ print scalar unmunge ($sects{$sect});
+ print "\n";
+ }
+}
+
+sub usage
+{
+ die "usage: $0 [-D toggle...] [infile [outfile]]\n";
+}
+
+sub postprocess
+{
+ local $_ = $_[0];
+
+ # @value{foo} is replaced by whatever 'foo' is defined as.
+ while (m/(\@value\{([a-zA-Z0-9_-]+)\})/g) {
+ if (! exists $defs{$2}) {
+ print STDERR "Option $2 not defined\n";
+ s/\Q$1\E//;
+ } else {
+ $value = $defs{$2};
+ s/\Q$1\E/$value/;
+ }
+ }
+
+ # Formatting commands.
+ # Temporary escape for @r.
+ s/\@r\{([^\}]*)\}/R<$1>/g;
+ s/\@(?:dfn|var|emph|cite|i)\{([^\}]*)\}/I<$1>/g;
+ s/\@(?:code|kbd)\{([^\}]*)\}/C<$1>/g;
+ s/\@(?:gccoptlist|samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g;
+ s/\@sc\{([^\}]*)\}/\U$1/g;
+ s/\@file\{([^\}]*)\}/F<$1>/g;
+ s/\@w\{([^\}]*)\}/S<$1>/g;
+ s/\@(?:dmn|math)\{([^\}]*)\}/$1/g;
+
+ # Cross references are thrown away, as are @noindent and @refill.
+ # (@noindent is impossible in .pod, and @refill is unnecessary.)
+ # @* is also impossible in .pod; we discard it and any newline that
+ # follows it. Similarly, our macro @gol must be discarded.
+
+ s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g;
+ s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g;
+ s/;\s+\@pxref\{(?:[^\}]*)\}//g;
+ s/\@noindent\s*//g;
+ s/\@refill//g;
+ s/\@gol//g;
+ s/\@\*\s*\n?//g;
+
+ # @uref can take one, two, or three arguments, with different
+ # semantics each time. @url and @email are just like @uref with
+ # one argument, for our purposes.
+ s/\@(?:uref|url|email)\{([^\},]*)\}/&lt;B<$1>&gt;/g;
+ s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g;
+ s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g;
+
+ # Turn B<blah I<blah> blah> into B<blah> I<blah> B<blah> to
+ # match Texinfo semantics of @emph inside @samp. Also handle @r
+ # inside bold.
+ s/&LT;/</g;
+ s/&GT;/>/g;
+ 1 while s/B<((?:[^<>]|I<[^<>]*>)*)R<([^>]*)>/B<$1>${2}B</g;
+ 1 while (s/B<([^<>]*)I<([^>]+)>/B<$1>I<$2>B</g);
+ 1 while (s/I<([^<>]*)B<([^>]+)>/I<$1>B<$2>I</g);
+ s/[BI]<>//g;
+ s/([BI])<(\s+)([^>]+)>/$2$1<$3>/g;
+ s/([BI])<([^>]+?)(\s+)>/$1<$2>$3/g;
+
+ # Extract footnotes. This has to be done after all other
+ # processing because otherwise the regexp will choke on formatting
+ # inside @footnote.
+ while (/\@footnote/g) {
+ s/\@footnote\{([^\}]+)\}/[$fnno]/;
+ add_footnote($1, $fnno);
+ $fnno++;
+ }
+
+ return $_;
+}
+
+sub unmunge
+{
+ # Replace escaped symbols with their equivalents.
+ local $_ = $_[0];
+
+ s/&lt;/E<lt>/g;
+ s/&gt;/E<gt>/g;
+ s/&lbrace;/\{/g;
+ s/&rbrace;/\}/g;
+ s/&at;/\@/g;
+ s/&amp;/&/g;
+ return $_;
+}
+
+sub add_footnote
+{
+ unless (exists $sects{FOOTNOTES}) {
+ $sects{FOOTNOTES} = "\n=over 4\n\n";
+ }
+
+ $sects{FOOTNOTES} .= "=item $fnno.\n\n"; $fnno++;
+ $sects{FOOTNOTES} .= $_[0];
+ $sects{FOOTNOTES} .= "\n\n";
+}
+
+# stolen from Symbol.pm
+{
+ my $genseq = 0;
+ sub gensym
+ {
+ my $name = "GEN" . $genseq++;
+ my $ref = \*{$name};
+ delete $::{$name};
+ return $ref;
+ }
+}
diff --git a/win32/build-tcc.bat b/win32/build-tcc.bat
new file mode 100755
index 0000000..913b068
--- /dev/null
+++ b/win32/build-tcc.bat
@@ -0,0 +1,189 @@
+@rem ------------------------------------------------------
+@rem batch file to build tcc using mingw, msvc or tcc itself
+@rem ------------------------------------------------------
+
+@echo off
+setlocal
+if (%1)==(-clean) goto :cleanup
+set CC=gcc
+set /p VERSION= < ..\VERSION
+set INST=
+set BIN=
+set DOC=no
+set EXES_ONLY=no
+goto :a0
+:a2
+shift
+:a3
+shift
+:a0
+if not (%1)==(-c) goto :a1
+set CC=%~2
+if (%2)==(cl) set CC=@call :cl
+goto :a2
+:a1
+if (%1)==(-t) set T=%2&& goto :a2
+if (%1)==(-v) set VERSION=%~2&& goto :a2
+if (%1)==(-i) set INST=%2&& goto :a2
+if (%1)==(-b) set BIN=%2&& goto :a2
+if (%1)==(-d) set DOC=yes&& goto :a3
+if (%1)==(-x) set EXES_ONLY=yes&& goto :a3
+if (%1)==() goto :p1
+:usage
+echo usage: build-tcc.bat [ options ... ]
+echo options:
+echo -c prog use prog (gcc/tcc/cl) to compile tcc
+echo -c "prog options" use prog with options to compile tcc
+echo -t 32/64 force 32/64 bit default target
+echo -v "version" set tcc version
+echo -i tccdir install tcc into tccdir
+echo -b bindir optionally install binaries into bindir elsewhere
+echo -d create tcc-doc.html too (needs makeinfo)
+echo -x just create the executables
+echo -clean delete all previously produced files and directories
+exit /B 1
+
+@rem ------------------------------------------------------
+@rem sub-routines
+
+:cleanup
+set LOG=echo
+%LOG% removing files:
+for %%f in (*tcc.exe libtcc.dll lib\*.a) do call :del_file %%f
+for %%f in (..\config.h ..\config.texi) do call :del_file %%f
+for %%f in (include\*.h) do @if exist ..\%%f call :del_file %%f
+for %%f in (include\tcclib.h examples\libtcc_test.c) do call :del_file %%f
+for %%f in (*.o *.obj *.def *.pdb *.lib *.exp *.ilk) do call :del_file %%f
+%LOG% removing directories:
+for %%f in (doc libtcc) do call :del_dir %%f
+%LOG% done.
+exit /B 0
+:del_file
+if exist %1 del %1 && %LOG% %1
+exit /B 0
+:del_dir
+if exist %1 rmdir /Q/S %1 && %LOG% %1
+exit /B 0
+
+:cl
+@echo off
+set CMD=cl
+:c0
+set ARG=%1
+set ARG=%ARG:.dll=.lib%
+if (%1)==(-shared) set ARG=-LD
+if (%1)==(-o) shift && set ARG=-Fe%2
+set CMD=%CMD% %ARG%
+shift
+if not (%1)==() goto :c0
+echo on
+%CMD% -O1 -W2 -Zi -MT -GS- -nologo -link -opt:ref,icf
+@exit /B %ERRORLEVEL%
+
+@rem ------------------------------------------------------
+@rem main program
+
+:p1
+if not %T%_==_ goto :p2
+set T=32
+if %PROCESSOR_ARCHITECTURE%_==AMD64_ set T=64
+if %PROCESSOR_ARCHITEW6432%_==AMD64_ set T=64
+:p2
+if "%CC:~-3%"=="gcc" set CC=%CC% -Os -s -static
+set D32=-DTCC_TARGET_PE -DTCC_TARGET_I386
+set D64=-DTCC_TARGET_PE -DTCC_TARGET_X86_64
+set P32=i386-win32
+set P64=x86_64-win32
+if %T%==64 goto :t64
+set D=%D32%
+set DX=%D64%
+set PX=%P64%
+goto :p3
+:t64
+set D=%D64%
+set DX=%D32%
+set PX=%P32%
+goto :p3
+
+:p3
+@echo on
+
+:config.h
+echo>..\config.h #define TCC_VERSION "%VERSION%"
+echo>> ..\config.h #ifdef TCC_TARGET_X86_64
+echo>> ..\config.h #define TCC_LIBTCC1 "libtcc1-64.a"
+echo>> ..\config.h #else
+echo>> ..\config.h #define TCC_LIBTCC1 "libtcc1-32.a"
+echo>> ..\config.h #endif
+
+for %%f in (*tcc.exe *tcc.dll) do @del %%f
+
+:compiler
+%CC% -o libtcc.dll -shared ..\libtcc.c %D% -DLIBTCC_AS_DLL
+@if errorlevel 1 goto :the_end
+%CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0"
+%CC% -o %PX%-tcc.exe ..\tcc.c %DX%
+
+@if (%EXES_ONLY%)==(yes) goto :files-done
+
+if not exist libtcc mkdir libtcc
+if not exist doc mkdir doc
+copy>nul ..\include\*.h include
+copy>nul ..\tcclib.h include
+copy>nul ..\libtcc.h libtcc
+copy>nul ..\tests\libtcc_test.c examples
+copy>nul tcc-win32.txt doc
+
+.\tcc -impdef libtcc.dll -o libtcc\libtcc.def
+@if errorlevel 1 goto :the_end
+
+:libtcc1.a
+@set O1=libtcc1.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o bcheck.o
+.\tcc -m32 -c ../lib/libtcc1.c
+.\tcc -m32 -c lib/crt1.c
+.\tcc -m32 -c lib/crt1w.c
+.\tcc -m32 -c lib/wincrt1.c
+.\tcc -m32 -c lib/wincrt1w.c
+.\tcc -m32 -c lib/dllcrt1.c
+.\tcc -m32 -c lib/dllmain.c
+.\tcc -m32 -c lib/chkstk.S
+.\tcc -m32 -w -c ../lib/bcheck.c
+.\tcc -m32 -c ../lib/alloca86.S
+.\tcc -m32 -c ../lib/alloca86-bt.S
+.\tcc -m32 -ar lib/libtcc1-32.a %O1% alloca86.o alloca86-bt.o
+@if errorlevel 1 goto :the_end
+.\tcc -m64 -c ../lib/libtcc1.c
+.\tcc -m64 -c lib/crt1.c
+.\tcc -m64 -c lib/crt1w.c
+.\tcc -m64 -c lib/wincrt1.c
+.\tcc -m64 -c lib/wincrt1w.c
+.\tcc -m64 -c lib/dllcrt1.c
+.\tcc -m64 -c lib/dllmain.c
+.\tcc -m64 -c lib/chkstk.S
+.\tcc -m64 -w -c ../lib/bcheck.c
+.\tcc -m64 -c ../lib/alloca86_64.S
+.\tcc -m64 -c ../lib/alloca86_64-bt.S
+.\tcc -m64 -ar lib/libtcc1-64.a %O1% alloca86_64.o alloca86_64-bt.o
+@if errorlevel 1 goto :the_end
+
+:tcc-doc.html
+@if not (%DOC%)==(yes) goto :doc-done
+echo>..\config.texi @set VERSION %VERSION%
+cmd /c makeinfo --html --no-split ../tcc-doc.texi -o doc/tcc-doc.html
+:doc-done
+
+:files-done
+for %%f in (*.o *.def) do @del %%f
+
+:copy-install
+@if (%INST%)==() goto :the_end
+if not exist %INST% mkdir %INST%
+@if (%BIN%)==() set BIN=%INST%
+if not exist %BIN% mkdir %BIN%
+for %%f in (*tcc.exe *tcc.dll) do @copy>nul %%f %BIN%\%%f
+@if not exist %INST%\lib mkdir %INST%\lib
+for %%f in (lib\*.a lib\*.def) do @copy>nul %%f %INST%\%%f
+for %%f in (include examples libtcc doc) do @xcopy>nul /s/i/q/y %%f %INST%\%%f
+
+:the_end
+exit /B %ERRORLEVEL%
diff --git a/win32/examples/dll.c b/win32/examples/dll.c
new file mode 100644
index 0000000..052a056
--- /dev/null
+++ b/win32/examples/dll.c
@@ -0,0 +1,13 @@
+//+---------------------------------------------------------------------------
+//
+// dll.c - Windows DLL example - dynamically linked part
+//
+
+#include <windows.h>
+
+__declspec(dllexport) const char *hello_data = "(not set)";
+
+__declspec(dllexport) void hello_func (void)
+{
+ MessageBox (0, hello_data, "From DLL", MB_ICONINFORMATION);
+}
diff --git a/win32/examples/fib.c b/win32/examples/fib.c
new file mode 100644
index 0000000..8da26bc
--- /dev/null
+++ b/win32/examples/fib.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <stdlib.h> // atoi()
+
+int fib(n)
+{
+ if (n <= 2)
+ return 1;
+ else
+ return fib(n-1) + fib(n-2);
+}
+
+int main(int argc, char **argv)
+{
+ int n;
+ if (argc < 2) {
+ printf("usage: fib n\n"
+ "Compute nth Fibonacci number\n");
+ return 1;
+ }
+
+ n = atoi(argv[1]);
+ printf("fib(%d) = %d\n", n, fib(n));
+ return 0;
+}
diff --git a/win32/examples/hello_dll.c b/win32/examples/hello_dll.c
new file mode 100644
index 0000000..4813c5b
--- /dev/null
+++ b/win32/examples/hello_dll.c
@@ -0,0 +1,20 @@
+//+---------------------------------------------------------------------------
+//
+// HELLO_DLL.C - Windows DLL example - main application part
+//
+
+#include <windows.h>
+
+void hello_func (void);
+__declspec(dllimport) extern const char *hello_data;
+
+int WINAPI WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ hello_data = "Hello World!";
+ hello_func();
+ return 0;
+}
diff --git a/win32/examples/hello_win.c b/win32/examples/hello_win.c
new file mode 100644
index 0000000..96546e4
--- /dev/null
+++ b/win32/examples/hello_win.c
@@ -0,0 +1,163 @@
+//+---------------------------------------------------------------------------
+//
+// HELLO_WIN.C - Windows GUI 'Hello World!' Example
+//
+//+---------------------------------------------------------------------------
+
+#include <windows.h>
+
+#define APPNAME "HELLO_WIN"
+
+char szAppName[] = APPNAME; // The name of this application
+char szTitle[] = APPNAME; // The title bar text
+const char *pWindowText;
+
+void CenterWindow(HWND hWnd);
+
+//+---------------------------------------------------------------------------
+//
+// Function: WndProc
+//
+// Synopsis: very unusual type of function - gets called by system to
+// process windows messages.
+//
+// Arguments: same as always.
+//----------------------------------------------------------------------------
+
+LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message) {
+
+ // ----------------------- first and last
+ case WM_CREATE:
+ CenterWindow(hwnd);
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+
+ // ----------------------- get out of it...
+ case WM_RBUTTONUP:
+ DestroyWindow(hwnd);
+ break;
+
+ case WM_KEYDOWN:
+ if (VK_ESCAPE == wParam)
+ DestroyWindow(hwnd);
+ break;
+
+ // ----------------------- display our minimal info
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ HDC hdc;
+ RECT rc;
+ hdc = BeginPaint(hwnd, &ps);
+
+ GetClientRect(hwnd, &rc);
+ SetTextColor(hdc, RGB(240,240,96));
+ SetBkMode(hdc, TRANSPARENT);
+ DrawText(hdc, pWindowText, -1, &rc, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
+
+ EndPaint(hwnd, &ps);
+ break;
+ }
+
+ // ----------------------- let windows do all other stuff
+ default:
+ return DefWindowProc(hwnd, message, wParam, lParam);
+ }
+ return 0;
+}
+
+//+---------------------------------------------------------------------------
+//
+// Function: WinMain
+//
+// Synopsis: standard entrypoint for GUI Win32 apps
+//
+//----------------------------------------------------------------------------
+int APIENTRY WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow
+ )
+{
+ MSG msg;
+ WNDCLASS wc;
+ HWND hwnd;
+
+ pWindowText = lpCmdLine[0] ? lpCmdLine : "Hello Windows!";
+
+ // Fill in window class structure with parameters that describe
+ // the main window.
+
+ ZeroMemory(&wc, sizeof wc);
+ wc.hInstance = hInstance;
+ wc.lpszClassName = szAppName;
+ wc.lpfnWndProc = (WNDPROC)WndProc;
+ wc.style = CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW;
+ wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+
+ if (FALSE == RegisterClass(&wc))
+ return 0;
+
+ // create the browser
+ hwnd = CreateWindow(
+ szAppName,
+ szTitle,
+ WS_OVERLAPPEDWINDOW|WS_VISIBLE,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ 360,//CW_USEDEFAULT,
+ 240,//CW_USEDEFAULT,
+ 0,
+ 0,
+ hInstance,
+ 0);
+
+ if (NULL == hwnd)
+ return 0;
+
+ // Main message loop:
+ while (GetMessage(&msg, NULL, 0, 0) > 0) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return msg.wParam;
+}
+
+//+---------------------------------------------------------------------------
+
+//+---------------------------------------------------------------------------
+
+void CenterWindow(HWND hwnd_self)
+{
+ HWND hwnd_parent;
+ RECT rw_self, rc_parent, rw_parent;
+ int xpos, ypos;
+
+ hwnd_parent = GetParent(hwnd_self);
+ if (NULL == hwnd_parent)
+ hwnd_parent = GetDesktopWindow();
+
+ GetWindowRect(hwnd_parent, &rw_parent);
+ GetClientRect(hwnd_parent, &rc_parent);
+ GetWindowRect(hwnd_self, &rw_self);
+
+ xpos = rw_parent.left + (rc_parent.right + rw_self.left - rw_self.right) / 2;
+ ypos = rw_parent.top + (rc_parent.bottom + rw_self.top - rw_self.bottom) / 2;
+
+ SetWindowPos(
+ hwnd_self, NULL,
+ xpos, ypos, 0, 0,
+ SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE
+ );
+}
+
+//+---------------------------------------------------------------------------
diff --git a/win32/include/_mingw.h b/win32/include/_mingw.h
new file mode 100644
index 0000000..2fc9798
--- /dev/null
+++ b/win32/include/_mingw.h
@@ -0,0 +1,170 @@
+/*
+ * _mingw.h
+ *
+ * This file is for TinyCC and not part of the Mingw32 package.
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __MINGW_H
+#define __MINGW_H
+
+/* some winapi files define these before including _mingw.h --> */
+#undef __cdecl
+#undef _X86_
+#undef WIN32
+/* <-- */
+
+#include <stddef.h>
+#include <stdarg.h>
+
+#define __int8 char
+#define __int16 short
+#define __int32 int
+#define __int64 long long
+#define _HAVE_INT64
+
+#define __cdecl
+#define __declspec(x) __attribute__((x))
+#define __unaligned __attribute__((packed))
+#define __fastcall __attribute__((fastcall))
+
+#define __MSVCRT__ 1
+#undef _MSVCRT_
+#define __MINGW_IMPORT extern __declspec(dllimport)
+#define __MINGW_ATTRIB_NORETURN
+#define __MINGW_ATTRIB_CONST
+#define __MINGW_ATTRIB_DEPRECATED
+#define __MINGW_ATTRIB_MALLOC
+#define __MINGW_ATTRIB_PURE
+#define __MINGW_ATTRIB_NONNULL(arg)
+#define __MINGW_NOTHROW
+#define __GNUC_VA_LIST
+
+#define _CRTIMP extern
+#define __CRT_INLINE extern __inline__
+
+#define _CRT_ALIGN(x) __attribute__((aligned(x)))
+#define DECLSPEC_ALIGN(x) __attribute__((aligned(x)))
+#define _CRT_PACKING 8
+#define __CRT_UNALIGNED
+#define _CONST_RETURN
+
+#ifndef _TRUNCATE
+#define _TRUNCATE ((size_t)-1)
+#endif
+
+#define __CRT_STRINGIZE(_Value) #_Value
+#define _CRT_STRINGIZE(_Value) __CRT_STRINGIZE(_Value)
+#define __CRT_WIDE(_String) L ## _String
+#define _CRT_WIDE(_String) __CRT_WIDE(_String)
+
+#ifdef _WIN64
+#define __stdcall
+#define _AMD64_ 1
+#define __x86_64 1
+#define _M_X64 100 /* Visual Studio */
+#define _M_AMD64 100 /* Visual Studio */
+#define USE_MINGW_SETJMP_TWO_ARGS
+#define mingw_getsp tinyc_getbp
+#define __TRY__
+#else
+#define __stdcall __attribute__((__stdcall__))
+#define _X86_ 1
+#define _M_IX86 300 /* Visual Studio */
+#define WIN32 1
+#define _USE_32BIT_TIME_T
+#ifdef __arm__
+#define __TRY__
+#else
+#define __TRY__ void __try__(void**), *_sehrec[6]; __try__(_sehrec);
+#endif
+#endif
+
+/* in stddef.h */
+#define _SIZE_T_DEFINED
+#define _SSIZE_T_DEFINED
+#define _PTRDIFF_T_DEFINED
+#define _WCHAR_T_DEFINED
+#define _UINTPTR_T_DEFINED
+#define _INTPTR_T_DEFINED
+#define _INTEGRAL_MAX_BITS 64
+
+#ifndef _TIME32_T_DEFINED
+#define _TIME32_T_DEFINED
+typedef long __time32_t;
+#endif
+
+#ifndef _TIME64_T_DEFINED
+#define _TIME64_T_DEFINED
+typedef long long __time64_t;
+#endif
+
+#ifndef _TIME_T_DEFINED
+#define _TIME_T_DEFINED
+#ifdef _USE_32BIT_TIME_T
+typedef __time32_t time_t;
+#else
+typedef __time64_t time_t;
+#endif
+#endif
+
+#ifndef _WCTYPE_T_DEFINED
+#define _WCTYPE_T_DEFINED
+typedef wchar_t wctype_t;
+#endif
+
+#ifndef _WINT_T
+#define _WINT_T
+typedef __WINT_TYPE__ wint_t;
+#endif
+
+typedef int errno_t;
+#define _ERRCODE_DEFINED
+
+typedef struct threadlocaleinfostruct *pthreadlocinfo;
+typedef struct threadmbcinfostruct *pthreadmbcinfo;
+typedef struct localeinfo_struct _locale_tstruct,*_locale_t;
+
+/* for winapi */
+#define _ANONYMOUS_UNION
+#define _ANONYMOUS_STRUCT
+#define DECLSPEC_NORETURN
+#define DECLARE_STDCALL_P(type) __stdcall type
+#define NOSERVICE 1
+#define NOMCX 1
+#define NOIME 1
+#define __INTRIN_H_
+#ifndef DUMMYUNIONNAME
+# define DUMMYUNIONNAME
+# define DUMMYUNIONNAME1
+# define DUMMYUNIONNAME2
+# define DUMMYUNIONNAME3
+# define DUMMYUNIONNAME4
+# define DUMMYUNIONNAME5
+#endif
+#ifndef DUMMYSTRUCTNAME
+# define DUMMYSTRUCTNAME
+#endif
+#ifndef WINVER
+# define WINVER 0x0502
+#endif
+#ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x502
+#endif
+
+#define __C89_NAMELESS
+#define __MINGW_EXTENSION
+#define WINAPI_FAMILY_PARTITION(X) 1
+#define MINGW_HAS_SECURE_API
+
+#endif /* __MINGW_H */
diff --git a/win32/include/assert.h b/win32/include/assert.h
new file mode 100644
index 0000000..466d457
--- /dev/null
+++ b/win32/include/assert.h
@@ -0,0 +1,57 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef __ASSERT_H_
+#define __ASSERT_H_
+
+#include <_mingw.h>
+#ifdef __cplusplus
+#include <stdlib.h>
+#endif
+
+#ifdef NDEBUG
+#ifndef assert
+#define assert(_Expression) ((void)0)
+#endif
+#else
+
+#ifndef _CRT_TERMINATE_DEFINED
+#define _CRT_TERMINATE_DEFINED
+ void __cdecl __MINGW_NOTHROW exit(int _Code) __MINGW_ATTRIB_NORETURN;
+ _CRTIMP void __cdecl __MINGW_NOTHROW _exit(int _Code) __MINGW_ATTRIB_NORETURN;
+#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */
+/* C99 function name */
+void __cdecl _Exit(int) __MINGW_ATTRIB_NORETURN;
+__CRT_INLINE __MINGW_ATTRIB_NORETURN void __cdecl _Exit(int status)
+{ _exit(status); }
+#endif
+
+#pragma push_macro("abort")
+#undef abort
+ void __cdecl __declspec(noreturn) abort(void);
+#pragma pop_macro("abort")
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern void __cdecl _wassert(const wchar_t *_Message,const wchar_t *_File,unsigned _Line);
+extern void __cdecl _assert(const char *, const char *, unsigned);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef assert
+//#define assert(_Expression) (void)((!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression),_CRT_WIDE(__FILE__),__LINE__),0))
+#define assert(e) ((e) ? (void)0 : _assert(#e, __FILE__, __LINE__))
+#endif
+
+#endif
+
+#endif
diff --git a/win32/include/conio.h b/win32/include/conio.h
new file mode 100644
index 0000000..39f779e
--- /dev/null
+++ b/win32/include/conio.h
@@ -0,0 +1,409 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_CONIO
+#define _INC_CONIO
+
+#include <_mingw.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ _CRTIMP char *_cgets(char *_Buffer);
+ _CRTIMP int __cdecl _cprintf(const char *_Format,...);
+ _CRTIMP int __cdecl _cputs(const char *_Str);
+ _CRTIMP int __cdecl _cscanf(const char *_Format,...);
+ _CRTIMP int __cdecl _cscanf_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _getch(void);
+ _CRTIMP int __cdecl _getche(void);
+ _CRTIMP int __cdecl _vcprintf(const char *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _cprintf_p(const char *_Format,...);
+ _CRTIMP int __cdecl _vcprintf_p(const char *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _cprintf_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcprintf_l(const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _cprintf_p_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcprintf_p_l(const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _kbhit(void);
+
+#if defined(_X86_) && !defined(__x86_64)
+ int __cdecl _inp(unsigned short);
+ unsigned short __cdecl _inpw(unsigned short);
+ unsigned long __cdecl _inpd(unsigned short);
+ int __cdecl _outp(unsigned short,int);
+ unsigned short __cdecl _outpw(unsigned short,unsigned short);
+ unsigned long __cdecl _outpd(unsigned short,unsigned long);
+#endif
+
+ _CRTIMP int __cdecl _putch(int _Ch);
+ _CRTIMP int __cdecl _ungetch(int _Ch);
+ _CRTIMP int __cdecl _getch_nolock(void);
+ _CRTIMP int __cdecl _getche_nolock(void);
+ _CRTIMP int __cdecl _putch_nolock(int _Ch);
+ _CRTIMP int __cdecl _ungetch_nolock(int _Ch);
+
+#ifndef _WCONIO_DEFINED
+#define _WCONIO_DEFINED
+
+#ifndef WEOF
+#define WEOF (wint_t)(0xFFFF)
+#endif
+
+ _CRTIMP wchar_t *_cgetws(wchar_t *_Buffer);
+ _CRTIMP wint_t __cdecl _getwch(void);
+ _CRTIMP wint_t __cdecl _getwche(void);
+ _CRTIMP wint_t __cdecl _putwch(wchar_t _WCh);
+ _CRTIMP wint_t __cdecl _ungetwch(wint_t _WCh);
+ _CRTIMP int __cdecl _cputws(const wchar_t *_String);
+ _CRTIMP int __cdecl _cwprintf(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _cwscanf(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _cwscanf_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcwprintf(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _cwprintf_p(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vcwprintf_p(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _cwprintf_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _cwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP wint_t __cdecl _putwch_nolock(wchar_t _WCh);
+ _CRTIMP wint_t __cdecl _getwch_nolock(void);
+ _CRTIMP wint_t __cdecl _getwche_nolock(void);
+ _CRTIMP wint_t __cdecl _ungetwch_nolock(wint_t _WCh);
+#endif
+
+#ifndef NO_OLDNAMES
+ char *__cdecl cgets(char *_Buffer);
+ int __cdecl cprintf(const char *_Format,...);
+ int __cdecl cputs(const char *_Str);
+ int __cdecl cscanf(const char *_Format,...);
+ int __cdecl getch(void);
+ int __cdecl getche(void);
+ int __cdecl kbhit(void);
+ int __cdecl putch(int _Ch);
+ int __cdecl ungetch(int _Ch);
+
+#if (defined(_X86_) && !defined(__x86_64))
+ int __cdecl inp(unsigned short);
+ unsigned short __cdecl inpw(unsigned short);
+ int __cdecl outp(unsigned short,int);
+ unsigned short __cdecl outpw(unsigned short,unsigned short);
+#endif
+
+ /* I/O intrin functions. */
+ __CRT_INLINE unsigned char __inbyte(unsigned short Port)
+ {
+ unsigned char value;
+ __asm__ __volatile__ ("inb %w1,%b0"
+ : "=a" (value)
+ : "Nd" (Port));
+ return value;
+ }
+ __CRT_INLINE unsigned short __inword(unsigned short Port)
+ {
+ unsigned short value;
+ __asm__ __volatile__ ("inw %w1,%w0"
+ : "=a" (value)
+ : "Nd" (Port));
+ return value;
+ }
+ __CRT_INLINE unsigned long __indword(unsigned short Port)
+ {
+ unsigned long value;
+ __asm__ __volatile__ ("inl %w1,%0"
+ : "=a" (value)
+ : "Nd" (Port));
+ return value;
+ }
+ __CRT_INLINE void __outbyte(unsigned short Port,unsigned char Data)
+ {
+ __asm__ __volatile__ ("outb %b0,%w1"
+ :
+ : "a" (Data), "Nd" (Port));
+ }
+ __CRT_INLINE void __outword(unsigned short Port,unsigned short Data)
+ {
+ __asm__ __volatile__ ("outw %w0,%w1"
+ :
+ : "a" (Data), "Nd" (Port));
+ }
+ __CRT_INLINE void __outdword(unsigned short Port,unsigned long Data)
+ {
+ __asm__ __volatile__ ("outl %0,%w1"
+ :
+ : "a" (Data), "Nd" (Port));
+ }
+ __CRT_INLINE void __inbytestring(unsigned short Port,unsigned char *Buffer,unsigned long Count)
+ {
+ __asm__ __volatile__ (
+ "cld ; rep ; insb "
+ : "=D" (Buffer), "=c" (Count)
+ : "d"(Port), "0"(Buffer), "1" (Count)
+ );
+ }
+ __CRT_INLINE void __inwordstring(unsigned short Port,unsigned short *Buffer,unsigned long Count)
+ {
+ __asm__ __volatile__ (
+ "cld ; rep ; insw "
+ : "=D" (Buffer), "=c" (Count)
+ : "d"(Port), "0"(Buffer), "1" (Count)
+ );
+ }
+ __CRT_INLINE void __indwordstring(unsigned short Port,unsigned long *Buffer,unsigned long Count)
+ {
+ __asm__ __volatile__ (
+ "cld ; rep ; insl "
+ : "=D" (Buffer), "=c" (Count)
+ : "d"(Port), "0"(Buffer), "1" (Count)
+ );
+ }
+
+ __CRT_INLINE void __outbytestring(unsigned short Port,unsigned char *Buffer,unsigned long Count)
+ {
+ __asm__ __volatile__ (
+ "cld ; rep ; outsb "
+ : "=S" (Buffer), "=c" (Count)
+ : "d"(Port), "0"(Buffer), "1" (Count)
+ );
+ }
+ __CRT_INLINE void __outwordstring(unsigned short Port,unsigned short *Buffer,unsigned long Count)
+ {
+ __asm__ __volatile__ (
+ "cld ; rep ; outsw "
+ : "=S" (Buffer), "=c" (Count)
+ : "d"(Port), "0"(Buffer), "1" (Count)
+ );
+ }
+ __CRT_INLINE void __outdwordstring(unsigned short Port,unsigned long *Buffer,unsigned long Count)
+ {
+ __asm__ __volatile__ (
+ "cld ; rep ; outsl "
+ : "=S" (Buffer), "=c" (Count)
+ : "d"(Port), "0"(Buffer), "1" (Count)
+ );
+ }
+
+ __CRT_INLINE unsigned __int64 __readcr0(void)
+ {
+ unsigned __int64 value;
+ __asm__ __volatile__ (
+ "mov %%cr0, %[value]"
+ : [value] "=q" (value));
+ return value;
+ }
+
+ /* Register sizes are different between 32/64 bit mode. So we have to do this for _WIN64 and _WIN32
+ separately. */
+
+#ifdef _WIN64
+ __CRT_INLINE void __writecr0(unsigned __int64 Data)
+ {
+ __asm__ __volatile__ (
+ "mov %[Data], %%cr0"
+ :
+ : [Data] "q" (Data)
+ : "memory");
+ }
+
+ __CRT_INLINE unsigned __int64 __readcr2(void)
+ {
+ unsigned __int64 value;
+ __asm__ __volatile__ (
+ "mov %%cr2, %[value]"
+ : [value] "=q" (value));
+ return value;
+ }
+
+ __CRT_INLINE void __writecr2(unsigned __int64 Data)
+ {
+ __asm__ __volatile__ (
+ "mov %[Data], %%cr2"
+ :
+ : [Data] "q" (Data)
+ : "memory");
+ }
+
+ __CRT_INLINE unsigned __int64 __readcr3(void)
+ {
+ unsigned __int64 value;
+ __asm__ __volatile__ (
+ "mov %%cr3, %[value]"
+ : [value] "=q" (value));
+ return value;
+ }
+
+ __CRT_INLINE void __writecr3(unsigned __int64 Data)
+ {
+ __asm__ __volatile__ (
+ "mov %[Data], %%cr3"
+ :
+ : [Data] "q" (Data)
+ : "memory");
+ }
+
+ __CRT_INLINE unsigned __int64 __readcr4(void)
+ {
+ unsigned __int64 value;
+ __asm__ __volatile__ (
+ "mov %%cr4, %[value]"
+ : [value] "=q" (value));
+ return value;
+ }
+
+ __CRT_INLINE void __writecr4(unsigned __int64 Data)
+ {
+ __asm__ __volatile__ (
+ "mov %[Data], %%cr4"
+ :
+ : [Data] "q" (Data)
+ : "memory");
+ }
+
+ __CRT_INLINE unsigned __int64 __readcr8(void)
+ {
+ unsigned __int64 value;
+ __asm__ __volatile__ (
+ "mov %%cr8, %[value]"
+ : [value] "=q" (value));
+ return value;
+ }
+
+ __CRT_INLINE void __writecr8(unsigned __int64 Data)
+ {
+ __asm__ __volatile__ (
+ "mov %[Data], %%cr8"
+ :
+ : [Data] "q" (Data)
+ : "memory");
+ }
+
+#elif defined(_WIN32)
+
+ __CRT_INLINE void __writecr0(unsigned Data)
+ {
+ __asm__ __volatile__ (
+ "mov %[Data], %%cr0"
+ :
+ : [Data] "q" (Data)
+ : "memory");
+ }
+
+ __CRT_INLINE unsigned long __readcr2(void)
+ {
+ unsigned long value;
+ __asm__ __volatile__ (
+ "mov %%cr2, %[value]"
+ : [value] "=q" (value));
+ return value;
+ }
+
+ __CRT_INLINE void __writecr2(unsigned Data)
+ {
+ __asm__ __volatile__ (
+ "mov %[Data], %%cr2"
+ :
+ : [Data] "q" (Data)
+ : "memory");
+ }
+
+ __CRT_INLINE unsigned long __readcr3(void)
+ {
+ unsigned long value;
+ __asm__ __volatile__ (
+ "mov %%cr3, %[value]"
+ : [value] "=q" (value));
+ return value;
+ }
+
+ __CRT_INLINE void __writecr3(unsigned Data)
+ {
+ __asm__ __volatile__ (
+ "mov %[Data], %%cr3"
+ :
+ : [Data] "q" (Data)
+ : "memory");
+ }
+
+ __CRT_INLINE unsigned long __readcr4(void)
+ {
+ unsigned long value;
+ __asm__ __volatile__ (
+ "mov %%cr4, %[value]"
+ : [value] "=q" (value));
+ return value;
+ }
+
+ __CRT_INLINE void __writecr4(unsigned Data)
+ {
+ __asm__ __volatile__ (
+ "mov %[Data], %%cr4"
+ :
+ : [Data] "q" (Data)
+ : "memory");
+ }
+
+ __CRT_INLINE unsigned long __readcr8(void)
+ {
+ unsigned long value; __asm__ __volatile__ (
+ "mov %%cr8, %[value]"
+ : [value] "=q" (value));
+ return value;
+ }
+
+ __CRT_INLINE void __writecr8(unsigned Data)
+ {
+ __asm__ __volatile__ (
+ "mov %[Data], %%cr8"
+ :
+ : [Data] "q" (Data)
+ : "memory");
+ }
+
+#endif
+
+ __CRT_INLINE unsigned __int64 __readmsr(unsigned long msr)
+ {
+ unsigned __int64 val1, val2;
+ __asm__ __volatile__(
+ "rdmsr"
+ : "=a" (val1), "=d" (val2)
+ : "c" (msr));
+ return val1 | (val2 << 32);
+ }
+
+ __CRT_INLINE void __writemsr (unsigned long msr, unsigned __int64 Value)
+ {
+ unsigned long val1 = Value, val2 = Value >> 32;
+ __asm__ __volatile__ (
+ "wrmsr"
+ :
+ : "c" (msr), "a" (val1), "d" (val2));
+ }
+
+ __CRT_INLINE unsigned __int64 __rdtsc(void)
+ {
+ unsigned __int64 val1, val2;
+ __asm__ __volatile__ (
+ "rdtsc"
+ : "=a" (val1), "=d" (val2));
+ return val1 | (val2 << 32);
+ }
+
+ __CRT_INLINE void __cpuid(int CPUInfo[4], int InfoType)
+ {
+ __asm__ __volatile__ (
+ "cpuid"
+ : "=a" (CPUInfo [0]), "=b" (CPUInfo [1]), "=c" (CPUInfo [2]), "=d" (CPUInfo [3])
+ : "a" (InfoType));
+ }
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <sec_api/conio_s.h>
+
+#endif
diff --git a/win32/include/ctype.h b/win32/include/ctype.h
new file mode 100644
index 0000000..7e90100
--- /dev/null
+++ b/win32/include/ctype.h
@@ -0,0 +1,281 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_CTYPE
+#define _INC_CTYPE
+
+#include <_mingw.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WEOF
+#define WEOF (wint_t)(0xFFFF)
+#endif
+
+#ifndef _CRT_CTYPEDATA_DEFINED
+#define _CRT_CTYPEDATA_DEFINED
+#ifndef _CTYPE_DISABLE_MACROS
+
+#ifndef __PCTYPE_FUNC
+#define __PCTYPE_FUNC __pctype_func()
+#ifdef _MSVCRT_
+#define __pctype_func() (_pctype)
+#else
+#define __pctype_func() (*_imp___pctype)
+#endif
+#endif
+
+#ifndef _pctype
+#ifdef _MSVCRT_
+ extern unsigned short *_pctype;
+#else
+ extern unsigned short **_imp___pctype;
+#define _pctype (*_imp___pctype)
+#endif
+#endif
+
+#endif
+#endif
+
+#ifndef _CRT_WCTYPEDATA_DEFINED
+#define _CRT_WCTYPEDATA_DEFINED
+#ifndef _CTYPE_DISABLE_MACROS
+#ifndef _wctype
+#ifdef _MSVCRT_
+ extern unsigned short *_wctype;
+#else
+ extern unsigned short **_imp___wctype;
+#define _wctype (*_imp___wctype)
+#endif
+#endif
+#ifdef _MSVCRT_
+#define __pwctype_func() (_pwctype)
+#ifndef _pwctype
+ extern unsigned short *_pwctype;
+#endif
+#else
+#define __pwctype_func() (*_imp___pwctype)
+#ifndef _pwctype
+ extern unsigned short **_imp___pwctype;
+#define _pwctype (*_imp___pwctype)
+#endif
+#endif
+#endif
+#endif
+
+ /* CRT stuff */
+#if 1
+ extern const unsigned char __newclmap[];
+ extern const unsigned char __newcumap[];
+ extern pthreadlocinfo __ptlocinfo;
+ extern pthreadmbcinfo __ptmbcinfo;
+ extern int __globallocalestatus;
+ extern int __locale_changed;
+ extern struct threadlocaleinfostruct __initiallocinfo;
+ extern _locale_tstruct __initiallocalestructinfo;
+ pthreadlocinfo __cdecl __updatetlocinfo(void);
+ pthreadmbcinfo __cdecl __updatetmbcinfo(void);
+#endif
+
+#define _UPPER 0x1
+#define _LOWER 0x2
+#define _DIGIT 0x4
+#define _SPACE 0x8
+
+#define _PUNCT 0x10
+#define _CONTROL 0x20
+#define _BLANK 0x40
+#define _HEX 0x80
+
+#define _LEADBYTE 0x8000
+#define _ALPHA (0x0100|_UPPER|_LOWER)
+
+#ifndef _CTYPE_DEFINED
+#define _CTYPE_DEFINED
+
+ _CRTIMP int __cdecl _isctype(int _C,int _Type);
+ _CRTIMP int __cdecl _isctype_l(int _C,int _Type,_locale_t _Locale);
+ _CRTIMP int __cdecl isalpha(int _C);
+ _CRTIMP int __cdecl _isalpha_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl isupper(int _C);
+ _CRTIMP int __cdecl _isupper_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl islower(int _C);
+ _CRTIMP int __cdecl _islower_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl isdigit(int _C);
+ _CRTIMP int __cdecl _isdigit_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl isxdigit(int _C);
+ _CRTIMP int __cdecl _isxdigit_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl isspace(int _C);
+ _CRTIMP int __cdecl _isspace_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl ispunct(int _C);
+ _CRTIMP int __cdecl _ispunct_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl isalnum(int _C);
+ _CRTIMP int __cdecl _isalnum_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl isprint(int _C);
+ _CRTIMP int __cdecl _isprint_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl isgraph(int _C);
+ _CRTIMP int __cdecl _isgraph_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl iscntrl(int _C);
+ _CRTIMP int __cdecl _iscntrl_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl toupper(int _C);
+ _CRTIMP int __cdecl tolower(int _C);
+ _CRTIMP int __cdecl _tolower(int _C);
+ _CRTIMP int __cdecl _tolower_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl _toupper(int _C);
+ _CRTIMP int __cdecl _toupper_l(int _C,_locale_t _Locale);
+ _CRTIMP int __cdecl __isascii(int _C);
+ _CRTIMP int __cdecl __toascii(int _C);
+ _CRTIMP int __cdecl __iscsymf(int _C);
+ _CRTIMP int __cdecl __iscsym(int _C);
+
+#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined (NO_OLDNAMES)
+int __cdecl isblank(int _C);
+#endif
+#endif
+
+#ifndef _WCTYPE_DEFINED
+#define _WCTYPE_DEFINED
+
+ int __cdecl iswalpha(wint_t _C);
+ _CRTIMP int __cdecl _iswalpha_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswupper(wint_t _C);
+ _CRTIMP int __cdecl _iswupper_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswlower(wint_t _C);
+ _CRTIMP int __cdecl _iswlower_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswdigit(wint_t _C);
+ _CRTIMP int __cdecl _iswdigit_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswxdigit(wint_t _C);
+ _CRTIMP int __cdecl _iswxdigit_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswspace(wint_t _C);
+ _CRTIMP int __cdecl _iswspace_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswpunct(wint_t _C);
+ _CRTIMP int __cdecl _iswpunct_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswalnum(wint_t _C);
+ _CRTIMP int __cdecl _iswalnum_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswprint(wint_t _C);
+ _CRTIMP int __cdecl _iswprint_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswgraph(wint_t _C);
+ _CRTIMP int __cdecl _iswgraph_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswcntrl(wint_t _C);
+ _CRTIMP int __cdecl _iswcntrl_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswascii(wint_t _C);
+ int __cdecl isleadbyte(int _C);
+ _CRTIMP int __cdecl _isleadbyte_l(int _C,_locale_t _Locale);
+ wint_t __cdecl towupper(wint_t _C);
+ _CRTIMP wint_t __cdecl _towupper_l(wint_t _C,_locale_t _Locale);
+ wint_t __cdecl towlower(wint_t _C);
+ _CRTIMP wint_t __cdecl _towlower_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswctype(wint_t _C,wctype_t _Type);
+ _CRTIMP int __cdecl _iswctype_l(wint_t _C,wctype_t _Type,_locale_t _Locale);
+ _CRTIMP int __cdecl __iswcsymf(wint_t _C);
+ _CRTIMP int __cdecl _iswcsymf_l(wint_t _C,_locale_t _Locale);
+ _CRTIMP int __cdecl __iswcsym(wint_t _C);
+ _CRTIMP int __cdecl _iswcsym_l(wint_t _C,_locale_t _Locale);
+ int __cdecl is_wctype(wint_t _C,wctype_t _Type);
+
+#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined (NO_OLDNAMES)
+int __cdecl iswblank(wint_t _C);
+#endif
+#endif
+
+#ifndef _CTYPE_DISABLE_MACROS
+
+#ifndef MB_CUR_MAX
+#define MB_CUR_MAX ___mb_cur_max_func()
+#ifndef __mb_cur_max
+#ifdef _MSVCRT_
+ extern int __mb_cur_max;
+#else
+#define __mb_cur_max (*_imp____mb_cur_max)
+ extern int *_imp____mb_cur_max;
+#endif
+#endif
+#ifdef _MSVCRT_
+#define ___mb_cur_max_func() (__mb_cur_max)
+#else
+#define ___mb_cur_max_func() (*_imp____mb_cur_max)
+#endif
+#endif
+
+#define __chvalidchk(a,b) (__PCTYPE_FUNC[(a)] & (b))
+#define _chvalidchk_l(_Char,_Flag,_Locale) (!_Locale ? __chvalidchk(_Char,_Flag) : ((_locale_t)_Locale)->locinfo->pctype[_Char] & (_Flag))
+#define _ischartype_l(_Char,_Flag,_Locale) (((_Locale)!=NULL && (((_locale_t)(_Locale))->locinfo->mb_cur_max) > 1) ? _isctype_l(_Char,(_Flag),_Locale) : _chvalidchk_l(_Char,_Flag,_Locale))
+#define _isalpha_l(_Char,_Locale) _ischartype_l(_Char,_ALPHA,_Locale)
+#define _isupper_l(_Char,_Locale) _ischartype_l(_Char,_UPPER,_Locale)
+#define _islower_l(_Char,_Locale) _ischartype_l(_Char,_LOWER,_Locale)
+#define _isdigit_l(_Char,_Locale) _ischartype_l(_Char,_DIGIT,_Locale)
+#define _isxdigit_l(_Char,_Locale) _ischartype_l(_Char,_HEX,_Locale)
+#define _isspace_l(_Char,_Locale) _ischartype_l(_Char,_SPACE,_Locale)
+#define _ispunct_l(_Char,_Locale) _ischartype_l(_Char,_PUNCT,_Locale)
+#define _isalnum_l(_Char,_Locale) _ischartype_l(_Char,_ALPHA|_DIGIT,_Locale)
+#define _isprint_l(_Char,_Locale) _ischartype_l(_Char,_BLANK|_PUNCT|_ALPHA|_DIGIT,_Locale)
+#define _isgraph_l(_Char,_Locale) _ischartype_l(_Char,_PUNCT|_ALPHA|_DIGIT,_Locale)
+#define _iscntrl_l(_Char,_Locale) _ischartype_l(_Char,_CONTROL,_Locale)
+#define _tolower(_Char) ((_Char)-'A'+'a')
+#define _toupper(_Char) ((_Char)-'a'+'A')
+#define __isascii(_Char) ((unsigned)(_Char) < 0x80)
+#define __toascii(_Char) ((_Char) & 0x7f)
+
+#ifndef _WCTYPE_INLINE_DEFINED
+#define _WCTYPE_INLINE_DEFINED
+
+#undef _CRT_WCTYPE_NOINLINE
+#ifndef __cplusplus
+#define iswalpha(_c) (iswctype(_c,_ALPHA))
+#define iswupper(_c) (iswctype(_c,_UPPER))
+#define iswlower(_c) (iswctype(_c,_LOWER))
+#define iswdigit(_c) (iswctype(_c,_DIGIT))
+#define iswxdigit(_c) (iswctype(_c,_HEX))
+#define iswspace(_c) (iswctype(_c,_SPACE))
+#define iswpunct(_c) (iswctype(_c,_PUNCT))
+#define iswalnum(_c) (iswctype(_c,_ALPHA|_DIGIT))
+#define iswprint(_c) (iswctype(_c,_BLANK|_PUNCT|_ALPHA|_DIGIT))
+#define iswgraph(_c) (iswctype(_c,_PUNCT|_ALPHA|_DIGIT))
+#define iswcntrl(_c) (iswctype(_c,_CONTROL))
+#define iswascii(_c) ((unsigned)(_c) < 0x80)
+#define _iswalpha_l(_c,_p) (_iswctype_l(_c,_ALPHA,_p))
+#define _iswupper_l(_c,_p) (_iswctype_l(_c,_UPPER,_p))
+#define _iswlower_l(_c,_p) (_iswctype_l(_c,_LOWER,_p))
+#define _iswdigit_l(_c,_p) (_iswctype_l(_c,_DIGIT,_p))
+#define _iswxdigit_l(_c,_p) (_iswctype_l(_c,_HEX,_p))
+#define _iswspace_l(_c,_p) (_iswctype_l(_c,_SPACE,_p))
+#define _iswpunct_l(_c,_p) (_iswctype_l(_c,_PUNCT,_p))
+#define _iswalnum_l(_c,_p) (_iswctype_l(_c,_ALPHA|_DIGIT,_p))
+#define _iswprint_l(_c,_p) (_iswctype_l(_c,_BLANK|_PUNCT|_ALPHA|_DIGIT,_p))
+#define _iswgraph_l(_c,_p) (_iswctype_l(_c,_PUNCT|_ALPHA|_DIGIT,_p))
+#define _iswcntrl_l(_c,_p) (_iswctype_l(_c,_CONTROL,_p))
+#endif
+#endif
+
+#define __iscsymf(_c) (isalpha(_c) || ((_c)=='_'))
+#define __iscsym(_c) (isalnum(_c) || ((_c)=='_'))
+#define __iswcsymf(_c) (iswalpha(_c) || ((_c)=='_'))
+#define __iswcsym(_c) (iswalnum(_c) || ((_c)=='_'))
+#define _iscsymf_l(_c,_p) (_isalpha_l(_c,_p) || ((_c)=='_'))
+#define _iscsym_l(_c,_p) (_isalnum_l(_c,_p) || ((_c)=='_'))
+#define _iswcsymf_l(_c,_p) (_iswalpha_l(_c,_p) || ((_c)=='_'))
+#define _iswcsym_l(_c,_p) (_iswalnum_l(_c,_p) || ((_c)=='_'))
+#endif
+
+#ifndef NO_OLDNAMES
+#ifndef _CTYPE_DEFINED
+ int __cdecl isascii(int _C);
+ int __cdecl toascii(int _C);
+ int __cdecl iscsymf(int _C);
+ int __cdecl iscsym(int _C);
+#else
+#define isascii __isascii
+#define toascii __toascii
+#define iscsymf __iscsymf
+#define iscsym __iscsym
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/include/dir.h b/win32/include/dir.h
new file mode 100644
index 0000000..f38f750
--- /dev/null
+++ b/win32/include/dir.h
@@ -0,0 +1,31 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+/*
+ * dir.h
+ *
+ * This file OBSOLESCENT and only provided for backward compatibility.
+ * Please use io.h instead.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ * Mumit Khan <khan@xraylith.wisc.edu>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include <io.h>
+
diff --git a/win32/include/direct.h b/win32/include/direct.h
new file mode 100644
index 0000000..99ce69d
--- /dev/null
+++ b/win32/include/direct.h
@@ -0,0 +1,68 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_DIRECT
+#define _INC_DIRECT
+
+#include <_mingw.h>
+#include <io.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _DISKFREE_T_DEFINED
+#define _DISKFREE_T_DEFINED
+ struct _diskfree_t {
+ unsigned total_clusters;
+ unsigned avail_clusters;
+ unsigned sectors_per_cluster;
+ unsigned bytes_per_sector;
+ };
+#endif
+
+ _CRTIMP char *__cdecl _getcwd(char *_DstBuf,int _SizeInBytes);
+ _CRTIMP char *__cdecl _getdcwd(int _Drive,char *_DstBuf,int _SizeInBytes);
+ char *__cdecl _getdcwd_nolock(int _Drive,char *_DstBuf,int _SizeInBytes);
+ _CRTIMP int __cdecl _chdir(const char *_Path);
+ _CRTIMP int __cdecl _mkdir(const char *_Path);
+ _CRTIMP int __cdecl _rmdir(const char *_Path);
+ _CRTIMP int __cdecl _chdrive(int _Drive);
+ _CRTIMP int __cdecl _getdrive(void);
+ _CRTIMP unsigned long __cdecl _getdrives(void);
+
+#ifndef _GETDISKFREE_DEFINED
+#define _GETDISKFREE_DEFINED
+ _CRTIMP unsigned __cdecl _getdiskfree(unsigned _Drive,struct _diskfree_t *_DiskFree);
+#endif
+
+#ifndef _WDIRECT_DEFINED
+#define _WDIRECT_DEFINED
+ _CRTIMP wchar_t *__cdecl _wgetcwd(wchar_t *_DstBuf,int _SizeInWords);
+ _CRTIMP wchar_t *__cdecl _wgetdcwd(int _Drive,wchar_t *_DstBuf,int _SizeInWords);
+ wchar_t *__cdecl _wgetdcwd_nolock(int _Drive,wchar_t *_DstBuf,int _SizeInWords);
+ _CRTIMP int __cdecl _wchdir(const wchar_t *_Path);
+ _CRTIMP int __cdecl _wmkdir(const wchar_t *_Path);
+ _CRTIMP int __cdecl _wrmdir(const wchar_t *_Path);
+#endif
+
+#ifndef NO_OLDNAMES
+
+#define diskfree_t _diskfree_t
+
+ char *__cdecl getcwd(char *_DstBuf,int _SizeInBytes);
+ int __cdecl chdir(const char *_Path);
+ int __cdecl mkdir(const char *_Path);
+ int __cdecl rmdir(const char *_Path);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+#endif
diff --git a/win32/include/dirent.h b/win32/include/dirent.h
new file mode 100644
index 0000000..cd31f59
--- /dev/null
+++ b/win32/include/dirent.h
@@ -0,0 +1,135 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _DIRENT_H_
+#define _DIRENT_H_
+
+
+#pragma pack(push,_CRT_PACKING)
+
+#include <io.h>
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ struct dirent
+ {
+ long d_ino; /* Always zero. */
+ unsigned short d_reclen; /* Always zero. */
+ unsigned short d_namlen; /* Length of name in d_name. */
+ char* d_name; /* File name. */
+ /* NOTE: The name in the dirent structure points to the name in the
+ * finddata_t structure in the DIR. */
+ };
+
+ /*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ * dd_stat field is now int (was short in older versions).
+ */
+ typedef struct
+ {
+ /* disk transfer area for this dir */
+ struct _finddata_t dd_dta;
+
+ /* dirent struct to return from dir (NOTE: this makes this thread
+ * safe as long as only one thread uses a particular DIR struct at
+ * a time) */
+ struct dirent dd_dir;
+
+ /* _findnext handle */
+ long dd_handle;
+
+ /*
+ * Status of search:
+ * 0 = not started yet (next entry to read is first entry)
+ * -1 = off the end
+ * positive = 0 based index of next entry
+ */
+ int dd_stat;
+
+ /* given path for dir with search pattern (struct is extended) */
+ char dd_name[1];
+ } DIR;
+
+ DIR* __cdecl opendir (const char*);
+ struct dirent* __cdecl readdir (DIR*);
+ int __cdecl closedir (DIR*);
+ void __cdecl rewinddir (DIR*);
+ long __cdecl telldir (DIR*);
+ void __cdecl seekdir (DIR*, long);
+
+
+ /* wide char versions */
+
+ struct _wdirent
+ {
+ long d_ino; /* Always zero. */
+ unsigned short d_reclen; /* Always zero. */
+ unsigned short d_namlen; /* Length of name in d_name. */
+ wchar_t* d_name; /* File name. */
+ /* NOTE: The name in the dirent structure points to the name in the * wfinddata_t structure in the _WDIR. */
+ };
+
+ /*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ */
+ typedef struct
+ {
+ /* disk transfer area for this dir */
+ struct _wfinddata_t dd_dta;
+
+ /* dirent struct to return from dir (NOTE: this makes this thread
+ * safe as long as only one thread uses a particular DIR struct at
+ * a time) */
+ struct _wdirent dd_dir;
+
+ /* _findnext handle */
+ long dd_handle;
+
+ /*
+ * Status of search:
+ * 0 = not started yet (next entry to read is first entry)
+ * -1 = off the end
+ * positive = 0 based index of next entry
+ */
+ int dd_stat;
+
+ /* given path for dir with search pattern (struct is extended) */
+ wchar_t dd_name[1];
+ } _WDIR;
+
+
+
+ _WDIR* __cdecl _wopendir (const wchar_t*);
+ struct _wdirent* __cdecl _wreaddir (_WDIR*);
+ int __cdecl _wclosedir (_WDIR*);
+ void __cdecl _wrewinddir (_WDIR*);
+ long __cdecl _wtelldir (_WDIR*);
+ void __cdecl _wseekdir (_WDIR*, long);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Not RC_INVOKED */
+
+#pragma pack(pop)
+
+#endif /* Not _DIRENT_H_ */
+
+
+#endif /* Not __STRICT_ANSI__ */
+
diff --git a/win32/include/dos.h b/win32/include/dos.h
new file mode 100644
index 0000000..294e8fe
--- /dev/null
+++ b/win32/include/dos.h
@@ -0,0 +1,55 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_DOS
+#define _INC_DOS
+
+#include <_mingw.h>
+#include <io.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _DISKFREE_T_DEFINED
+#define _DISKFREE_T_DEFINED
+
+ struct _diskfree_t {
+ unsigned total_clusters;
+ unsigned avail_clusters;
+ unsigned sectors_per_cluster;
+ unsigned bytes_per_sector;
+ };
+#endif
+
+#define _A_NORMAL 0x00
+#define _A_RDONLY 0x01
+#define _A_HIDDEN 0x02
+#define _A_SYSTEM 0x04
+#define _A_SUBDIR 0x10
+#define _A_ARCH 0x20
+
+#ifndef _GETDISKFREE_DEFINED
+#define _GETDISKFREE_DEFINED
+ _CRTIMP unsigned __cdecl _getdiskfree(unsigned _Drive,struct _diskfree_t *_DiskFree);
+#endif
+
+#if (defined(_X86_) && !defined(__x86_64))
+ void __cdecl _disable(void);
+ void __cdecl _enable(void);
+#endif
+
+#ifndef NO_OLDNAMES
+#define diskfree_t _diskfree_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+#endif
diff --git a/win32/include/errno.h b/win32/include/errno.h
new file mode 100644
index 0000000..c2df015
--- /dev/null
+++ b/win32/include/errno.h
@@ -0,0 +1,75 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_ERRNO
+#define _INC_ERRNO
+
+#include <_mingw.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _CRT_ERRNO_DEFINED
+#define _CRT_ERRNO_DEFINED
+ _CRTIMP extern int *__cdecl _errno(void);
+#define errno (*_errno())
+
+ errno_t __cdecl _set_errno(int _Value);
+ errno_t __cdecl _get_errno(int *_Value);
+#endif
+
+#define EPERM 1
+#define ENOENT 2
+#define ESRCH 3
+#define EINTR 4
+#define EIO 5
+#define ENXIO 6
+#define E2BIG 7
+#define ENOEXEC 8
+#define EBADF 9
+#define ECHILD 10
+#define EAGAIN 11
+#define ENOMEM 12
+#define EACCES 13
+#define EFAULT 14
+#define EBUSY 16
+#define EEXIST 17
+#define EXDEV 18
+#define ENODEV 19
+#define ENOTDIR 20
+#define EISDIR 21
+#define ENFILE 23
+#define EMFILE 24
+#define ENOTTY 25
+#define EFBIG 27
+#define ENOSPC 28
+#define ESPIPE 29
+#define EROFS 30
+#define EMLINK 31
+#define EPIPE 32
+#define EDOM 33
+#define EDEADLK 36
+#define ENAMETOOLONG 38
+#define ENOLCK 39
+#define ENOSYS 40
+#define ENOTEMPTY 41
+
+#ifndef RC_INVOKED
+#if !defined(_SECURECRT_ERRCODE_VALUES_DEFINED)
+#define _SECURECRT_ERRCODE_VALUES_DEFINED
+#define EINVAL 22
+#define ERANGE 34
+#define EILSEQ 42
+#define STRUNCATE 80
+#endif
+#endif
+
+#define EDEADLOCK EDEADLK
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/include/excpt.h b/win32/include/excpt.h
new file mode 100644
index 0000000..26cc943
--- /dev/null
+++ b/win32/include/excpt.h
@@ -0,0 +1,123 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_EXCPT
+#define _INC_EXCPT
+
+#include <_mingw.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ struct _EXCEPTION_POINTERS;
+
+#ifndef EXCEPTION_DISPOSITION
+#define EXCEPTION_DISPOSITION int
+#endif
+#define ExceptionContinueExecution 0
+#define ExceptionContinueSearch 1
+#define ExceptionNestedException 2
+#define ExceptionCollidedUnwind 3
+
+#if (defined(_X86_) && !defined(__x86_64))
+ struct _EXCEPTION_RECORD;
+ struct _CONTEXT;
+
+ EXCEPTION_DISPOSITION __cdecl _except_handler(struct _EXCEPTION_RECORD *_ExceptionRecord,void *_EstablisherFrame,struct _CONTEXT *_ContextRecord,void *_DispatcherContext);
+#elif defined(__ia64__)
+
+ typedef struct _EXCEPTION_POINTERS *Exception_info_ptr;
+ struct _EXCEPTION_RECORD;
+ struct _CONTEXT;
+ struct _DISPATCHER_CONTEXT;
+
+ _CRTIMP EXCEPTION_DISPOSITION __cdecl __C_specific_handler (struct _EXCEPTION_RECORD *_ExceptionRecord,unsigned __int64 _MemoryStackFp,unsigned __int64 _BackingStoreFp,struct _CONTEXT *_ContextRecord,struct _DISPATCHER_CONTEXT *_DispatcherContext,unsigned __int64 _GlobalPointer);
+#elif defined(__x86_64)
+
+ struct _EXCEPTION_RECORD;
+ struct _CONTEXT;
+#endif
+
+#define GetExceptionCode _exception_code
+#define exception_code _exception_code
+#define GetExceptionInformation (struct _EXCEPTION_POINTERS *)_exception_info
+#define exception_info (struct _EXCEPTION_POINTERS *)_exception_info
+#define AbnormalTermination _abnormal_termination
+#define abnormal_termination _abnormal_termination
+
+ unsigned long __cdecl _exception_code(void);
+ void *__cdecl _exception_info(void);
+ int __cdecl _abnormal_termination(void);
+
+#define EXCEPTION_EXECUTE_HANDLER 1
+#define EXCEPTION_CONTINUE_SEARCH 0
+#define EXCEPTION_CONTINUE_EXECUTION -1
+
+ /* CRT stuff */
+ typedef void (__cdecl * _PHNDLR)(int);
+
+ struct _XCPT_ACTION {
+ unsigned long XcptNum;
+ int SigNum;
+ _PHNDLR XcptAction;
+ };
+
+ extern struct _XCPT_ACTION _XcptActTab[];
+ extern int _XcptActTabCount;
+ extern int _XcptActTabSize;
+ extern int _First_FPE_Indx;
+ extern int _Num_FPE;
+
+ int __cdecl __CppXcptFilter(unsigned long _ExceptionNum,struct _EXCEPTION_POINTERS * _ExceptionPtr);
+ int __cdecl _XcptFilter(unsigned long _ExceptionNum,struct _EXCEPTION_POINTERS * _ExceptionPtr);
+
+ /*
+ * The type of function that is expected as an exception handler to be
+ * installed with _try1.
+ */
+ typedef EXCEPTION_DISPOSITION (*PEXCEPTION_HANDLER)(struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
+
+#ifndef HAVE_NO_SEH
+ /*
+ * This is not entirely necessary, but it is the structure installed by
+ * the _try1 primitive below.
+ */
+ typedef struct _EXCEPTION_REGISTRATION {
+ struct _EXCEPTION_REGISTRATION *prev;
+ EXCEPTION_DISPOSITION (*handler)(struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
+ } EXCEPTION_REGISTRATION, *PEXCEPTION_REGISTRATION;
+
+ typedef EXCEPTION_REGISTRATION EXCEPTION_REGISTRATION_RECORD;
+ typedef PEXCEPTION_REGISTRATION PEXCEPTION_REGISTRATION_RECORD;
+#endif
+
+#if (defined(_X86_) && !defined(__x86_64))
+#define __try1(pHandler) \
+ __asm__ ("pushl %0;pushl %%fs:0;movl %%esp,%%fs:0;" : : "g" (pHandler));
+
+#define __except1 \
+ __asm__ ("movl (%%esp),%%eax;movl %%eax,%%fs:0;addl $8,%%esp;" \
+ : : : "%eax");
+#elif defined(__x86_64)
+#define __try1(pHandler) \
+ __asm__ ("pushq %0;pushq %%gs:0;movq %%rsp,%%gs:0;" : : "g" (pHandler));
+
+#define __except1 \
+ __asm__ ("movq (%%rsp),%%rax;movq %%rax,%%gs:0;addq $16,%%rsp;" \
+ : : : "%rax");
+#else
+#define __try1(pHandler)
+#define __except1
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+#endif
diff --git a/win32/include/fcntl.h b/win32/include/fcntl.h
new file mode 100644
index 0000000..9202b08
--- /dev/null
+++ b/win32/include/fcntl.h
@@ -0,0 +1,52 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#include <_mingw.h>
+
+#include <io.h>
+
+#ifndef _INC_FCNTL
+#define _INC_FCNTL
+
+#define _O_RDONLY 0x0000
+#define _O_WRONLY 0x0001
+#define _O_RDWR 0x0002
+#define _O_APPEND 0x0008
+#define _O_CREAT 0x0100
+#define _O_TRUNC 0x0200
+#define _O_EXCL 0x0400
+#define _O_TEXT 0x4000
+#define _O_BINARY 0x8000
+#define _O_WTEXT 0x10000
+#define _O_U16TEXT 0x20000
+#define _O_U8TEXT 0x40000
+#define _O_ACCMODE (_O_RDONLY|_O_WRONLY|_O_RDWR)
+
+#define _O_RAW _O_BINARY
+#define _O_NOINHERIT 0x0080
+#define _O_TEMPORARY 0x0040
+#define _O_SHORT_LIVED 0x1000
+
+#define _O_SEQUENTIAL 0x0020
+#define _O_RANDOM 0x0010
+
+#if !defined(NO_OLDNAMES) || defined(_POSIX)
+#define O_RDONLY _O_RDONLY
+#define O_WRONLY _O_WRONLY
+#define O_RDWR _O_RDWR
+#define O_APPEND _O_APPEND
+#define O_CREAT _O_CREAT
+#define O_TRUNC _O_TRUNC
+#define O_EXCL _O_EXCL
+#define O_TEXT _O_TEXT
+#define O_BINARY _O_BINARY
+#define O_RAW _O_BINARY
+#define O_TEMPORARY _O_TEMPORARY
+#define O_NOINHERIT _O_NOINHERIT
+#define O_SEQUENTIAL _O_SEQUENTIAL
+#define O_RANDOM _O_RANDOM
+#define O_ACCMODE _O_ACCMODE
+#endif
+#endif
diff --git a/win32/include/fenv.h b/win32/include/fenv.h
new file mode 100644
index 0000000..258f3a5
--- /dev/null
+++ b/win32/include/fenv.h
@@ -0,0 +1,108 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _FENV_H_
+#define _FENV_H_
+
+#include <_mingw.h>
+
+/* FPU status word exception flags */
+#define FE_INVALID 0x01
+#define FE_DENORMAL 0x02
+#define FE_DIVBYZERO 0x04
+#define FE_OVERFLOW 0x08
+#define FE_UNDERFLOW 0x10
+#define FE_INEXACT 0x20
+#define FE_ALL_EXCEPT (FE_INVALID | FE_DENORMAL | FE_DIVBYZERO \
+ | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
+
+/* FPU control word rounding flags */
+#define FE_TONEAREST 0x0000
+#define FE_DOWNWARD 0x0400
+#define FE_UPWARD 0x0800
+#define FE_TOWARDZERO 0x0c00
+
+/* The MXCSR exception flags are the same as the
+ FE flags. */
+#define __MXCSR_EXCEPT_FLAG_SHIFT 0
+
+/* How much to shift FE status word exception flags
+ to get MXCSR rounding flags, */
+#define __MXCSR_ROUND_FLAG_SHIFT 3
+
+#ifndef RC_INVOKED
+/*
+ For now, support only for the basic abstraction of flags that are
+ either set or clear. fexcept_t could be structure that holds more
+ info about the fp environment.
+*/
+typedef unsigned short fexcept_t;
+
+/* This 32-byte struct represents the entire floating point
+ environment as stored by fnstenv or fstenv, augmented by
+ the contents of the MXCSR register, as stored by stmxcsr
+ (if CPU supports it). */
+typedef struct
+{
+ unsigned short __control_word;
+ unsigned short __unused0;
+ unsigned short __status_word;
+ unsigned short __unused1;
+ unsigned short __tag_word;
+ unsigned short __unused2;
+ unsigned int __ip_offset; /* instruction pointer offset */
+ unsigned short __ip_selector;
+ unsigned short __opcode;
+ unsigned int __data_offset;
+ unsigned short __data_selector;
+ unsigned short __unused3;
+ unsigned int __mxcsr; /* contents of the MXCSR register */
+} fenv_t;
+
+
+/*The C99 standard (7.6.9) allows us to define implementation-specific macros for
+ different fp environments */
+
+/* The default Intel x87 floating point environment (64-bit mantissa) */
+#define FE_PC64_ENV ((const fenv_t *)-1)
+
+/* The floating point environment set by MSVCRT _fpreset (53-bit mantissa) */
+#define FE_PC53_ENV ((const fenv_t *)-2)
+
+/* The FE_DFL_ENV macro is required by standard.
+ fesetenv will use the environment set at app startup.*/
+#define FE_DFL_ENV ((const fenv_t *) 0)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*TODO: Some of these could be inlined */
+/* 7.6.2 Exception */
+
+extern int __cdecl feclearexcept (int);
+extern int __cdecl fegetexceptflag (fexcept_t * flagp, int excepts);
+extern int __cdecl feraiseexcept (int excepts );
+extern int __cdecl fesetexceptflag (const fexcept_t *, int);
+extern int __cdecl fetestexcept (int excepts);
+
+/* 7.6.3 Rounding */
+
+extern int __cdecl fegetround (void);
+extern int __cdecl fesetround (int mode);
+
+/* 7.6.4 Environment */
+
+extern int __cdecl fegetenv(fenv_t * envp);
+extern int __cdecl fesetenv(const fenv_t * );
+extern int __cdecl feupdateenv(const fenv_t *);
+extern int __cdecl feholdexcept(fenv_t *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* Not RC_INVOKED */
+
+#endif /* ndef _FENV_H */
diff --git a/win32/include/inttypes.h b/win32/include/inttypes.h
new file mode 100644
index 0000000..7360091
--- /dev/null
+++ b/win32/include/inttypes.h
@@ -0,0 +1,297 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+/* 7.8 Format conversion of integer types <inttypes.h> */
+
+#ifndef _INTTYPES_H_
+#define _INTTYPES_H_
+
+#include <_mingw.h>
+#include <stdint.h>
+#define __need_wchar_t
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ intmax_t quot;
+ intmax_t rem;
+ } imaxdiv_t;
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
+
+/* 7.8.1 Macros for format specifiers
+ *
+ * MS runtime does not yet understand C9x standard "ll"
+ * length specifier. It appears to treat "ll" as "l".
+ * The non-standard I64 length specifier causes warning in GCC,
+ * but understood by MS runtime functions.
+ */
+
+/* fprintf macros for signed types */
+#define PRId8 "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 "I64d"
+
+#define PRIdLEAST8 "d"
+#define PRIdLEAST16 "d"
+#define PRIdLEAST32 "d"
+#define PRIdLEAST64 "I64d"
+
+#define PRIdFAST8 "d"
+#define PRIdFAST16 "d"
+#define PRIdFAST32 "d"
+#define PRIdFAST64 "I64d"
+
+#define PRIdMAX "I64d"
+
+#define PRIi8 "i"
+#define PRIi16 "i"
+#define PRIi32 "i"
+#define PRIi64 "I64i"
+
+#define PRIiLEAST8 "i"
+#define PRIiLEAST16 "i"
+#define PRIiLEAST32 "i"
+#define PRIiLEAST64 "I64i"
+
+#define PRIiFAST8 "i"
+#define PRIiFAST16 "i"
+#define PRIiFAST32 "i"
+#define PRIiFAST64 "I64i"
+
+#define PRIiMAX "I64i"
+
+#define PRIo8 "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 "I64o"
+
+#define PRIoLEAST8 "o"
+#define PRIoLEAST16 "o"
+#define PRIoLEAST32 "o"
+#define PRIoLEAST64 "I64o"
+
+#define PRIoFAST8 "o"
+#define PRIoFAST16 "o"
+#define PRIoFAST32 "o"
+#define PRIoFAST64 "I64o"
+
+#define PRIoMAX "I64o"
+
+/* fprintf macros for unsigned types */
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "I64u"
+
+
+#define PRIuLEAST8 "u"
+#define PRIuLEAST16 "u"
+#define PRIuLEAST32 "u"
+#define PRIuLEAST64 "I64u"
+
+#define PRIuFAST8 "u"
+#define PRIuFAST16 "u"
+#define PRIuFAST32 "u"
+#define PRIuFAST64 "I64u"
+
+#define PRIuMAX "I64u"
+
+#define PRIx8 "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 "I64x"
+
+#define PRIxLEAST8 "x"
+#define PRIxLEAST16 "x"
+#define PRIxLEAST32 "x"
+#define PRIxLEAST64 "I64x"
+
+#define PRIxFAST8 "x"
+#define PRIxFAST16 "x"
+#define PRIxFAST32 "x"
+#define PRIxFAST64 "I64x"
+
+#define PRIxMAX "I64x"
+
+#define PRIX8 "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 "I64X"
+
+#define PRIXLEAST8 "X"
+#define PRIXLEAST16 "X"
+#define PRIXLEAST32 "X"
+#define PRIXLEAST64 "I64X"
+
+#define PRIXFAST8 "X"
+#define PRIXFAST16 "X"
+#define PRIXFAST32 "X"
+#define PRIXFAST64 "I64X"
+
+#define PRIXMAX "I64X"
+
+/*
+ * fscanf macros for signed int types
+ * NOTE: if 32-bit int is used for int_fast8_t and int_fast16_t
+ * (see stdint.h, 7.18.1.3), FAST8 and FAST16 should have
+ * no length identifiers
+ */
+
+#define SCNd16 "hd"
+#define SCNd32 "d"
+#define SCNd64 "I64d"
+
+#define SCNdLEAST16 "hd"
+#define SCNdLEAST32 "d"
+#define SCNdLEAST64 "I64d"
+
+#define SCNdFAST16 "hd"
+#define SCNdFAST32 "d"
+#define SCNdFAST64 "I64d"
+
+#define SCNdMAX "I64d"
+
+#define SCNi16 "hi"
+#define SCNi32 "i"
+#define SCNi64 "I64i"
+
+#define SCNiLEAST16 "hi"
+#define SCNiLEAST32 "i"
+#define SCNiLEAST64 "I64i"
+
+#define SCNiFAST16 "hi"
+#define SCNiFAST32 "i"
+#define SCNiFAST64 "I64i"
+
+#define SCNiMAX "I64i"
+
+#define SCNo16 "ho"
+#define SCNo32 "o"
+#define SCNo64 "I64o"
+
+#define SCNoLEAST16 "ho"
+#define SCNoLEAST32 "o"
+#define SCNoLEAST64 "I64o"
+
+#define SCNoFAST16 "ho"
+#define SCNoFAST32 "o"
+#define SCNoFAST64 "I64o"
+
+#define SCNoMAX "I64o"
+
+#define SCNx16 "hx"
+#define SCNx32 "x"
+#define SCNx64 "I64x"
+
+#define SCNxLEAST16 "hx"
+#define SCNxLEAST32 "x"
+#define SCNxLEAST64 "I64x"
+
+#define SCNxFAST16 "hx"
+#define SCNxFAST32 "x"
+#define SCNxFAST64 "I64x"
+
+#define SCNxMAX "I64x"
+
+/* fscanf macros for unsigned int types */
+
+#define SCNu16 "hu"
+#define SCNu32 "u"
+#define SCNu64 "I64u"
+
+#define SCNuLEAST16 "hu"
+#define SCNuLEAST32 "u"
+#define SCNuLEAST64 "I64u"
+
+#define SCNuFAST16 "hu"
+#define SCNuFAST32 "u"
+#define SCNuFAST64 "I64u"
+
+#define SCNuMAX "I64u"
+
+#ifdef _WIN64
+#define PRIdPTR "I64d"
+#define PRIiPTR "I64i"
+#define PRIoPTR "I64o"
+#define PRIuPTR "I64u"
+#define PRIxPTR "I64x"
+#define PRIXPTR "I64X"
+#define SCNdPTR "I64d"
+#define SCNiPTR "I64i"
+#define SCNoPTR "I64o"
+#define SCNxPTR "I64x"
+#define SCNuPTR "I64u"
+#else
+#define PRIdPTR "d"
+#define PRIiPTR "i"
+#define PRIoPTR "o"
+#define PRIuPTR "u"
+#define PRIxPTR "x"
+#define PRIXPTR "X"
+#define SCNdPTR "d"
+#define SCNiPTR "i"
+#define SCNoPTR "o"
+#define SCNxPTR "x"
+#define SCNuPTR "u"
+#endif
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+/*
+ * no length modifier for char types prior to C9x
+ * MS runtime scanf appears to treat "hh" as "h"
+ */
+
+/* signed char */
+#define SCNd8 "hhd"
+#define SCNdLEAST8 "hhd"
+#define SCNdFAST8 "hhd"
+
+#define SCNi8 "hhi"
+#define SCNiLEAST8 "hhi"
+#define SCNiFAST8 "hhi"
+
+#define SCNo8 "hho"
+#define SCNoLEAST8 "hho"
+#define SCNoFAST8 "hho"
+
+#define SCNx8 "hhx"
+#define SCNxLEAST8 "hhx"
+#define SCNxFAST8 "hhx"
+
+/* unsigned char */
+#define SCNu8 "hhu"
+#define SCNuLEAST8 "hhu"
+#define SCNuFAST8 "hhu"
+#endif /* __STDC_VERSION__ >= 199901 */
+
+#endif /* !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) */
+
+intmax_t __cdecl imaxabs (intmax_t j);
+__CRT_INLINE intmax_t __cdecl imaxabs (intmax_t j)
+ {return (j >= 0 ? j : -j);}
+imaxdiv_t __cdecl imaxdiv (intmax_t numer, intmax_t denom);
+
+/* 7.8.2 Conversion functions for greatest-width integer types */
+
+intmax_t __cdecl strtoimax (const char* __restrict__ nptr,
+ char** __restrict__ endptr, int base);
+uintmax_t __cdecl strtoumax (const char* __restrict__ nptr,
+ char** __restrict__ endptr, int base);
+
+intmax_t __cdecl wcstoimax (const wchar_t* __restrict__ nptr,
+ wchar_t** __restrict__ endptr, int base);
+uintmax_t __cdecl wcstoumax (const wchar_t* __restrict__ nptr,
+ wchar_t** __restrict__ endptr, int base);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ndef _INTTYPES_H */
diff --git a/win32/include/io.h b/win32/include/io.h
new file mode 100644
index 0000000..e2aeec3
--- /dev/null
+++ b/win32/include/io.h
@@ -0,0 +1,418 @@
+
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _IO_H_
+#define _IO_H_
+
+#include <_mingw.h>
+#include <string.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifndef _POSIX_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_CRTIMP char* __cdecl _getcwd (char*, int);
+#ifndef _FSIZE_T_DEFINED
+ typedef unsigned long _fsize_t;
+#define _FSIZE_T_DEFINED
+#endif
+
+#ifndef _FINDDATA_T_DEFINED
+
+ struct _finddata32_t {
+ unsigned attrib;
+ __time32_t time_create;
+ __time32_t time_access;
+ __time32_t time_write;
+ _fsize_t size;
+ char name[260];
+ };
+
+/*#if _INTEGRAL_MAX_BITS >= 64*/
+
+ struct _finddata32i64_t {
+ unsigned attrib;
+ __time32_t time_create;
+ __time32_t time_access;
+ __time32_t time_write;
+ __int64 size;
+ char name[260];
+ };
+
+ struct _finddata64i32_t {
+ unsigned attrib;
+ __time64_t time_create;
+ __time64_t time_access;
+ __time64_t time_write;
+ _fsize_t size;
+ char name[260];
+ };
+
+ struct __finddata64_t {
+ unsigned attrib;
+ __time64_t time_create;
+ __time64_t time_access;
+ __time64_t time_write;
+ __int64 size;
+ char name[260];
+ };
+/* #endif */
+
+#ifdef _USE_32BIT_TIME_T
+#define _finddata_t _finddata32_t
+#define _finddatai64_t _finddata32i64_t
+
+#ifdef _WIN64
+#define _findfirst _findfirst32
+#define _findnext _findnext32
+#else
+#define _findfirst32 _findfirst
+#define _findnext32 _findnext
+#endif
+#define _findfirsti64 _findfirst32i64
+#define _findnexti64 _findnext32i64
+#else
+#define _finddata_t _finddata64i32_t
+#define _finddatai64_t __finddata64_t
+
+#define _findfirst _findfirst64i32
+#define _findnext _findnext64i32
+#define _findfirsti64 _findfirst64
+#define _findnexti64 _findnext64
+#endif
+
+#define _FINDDATA_T_DEFINED
+#endif
+
+#ifndef _WFINDDATA_T_DEFINED
+
+ struct _wfinddata32_t {
+ unsigned attrib;
+ __time32_t time_create;
+ __time32_t time_access;
+ __time32_t time_write;
+ _fsize_t size;
+ wchar_t name[260];
+ };
+
+/* #if _INTEGRAL_MAX_BITS >= 64 */
+
+ struct _wfinddata32i64_t {
+ unsigned attrib;
+ __time32_t time_create;
+ __time32_t time_access;
+ __time32_t time_write;
+ __int64 size;
+ wchar_t name[260];
+ };
+
+ struct _wfinddata64i32_t {
+ unsigned attrib;
+ __time64_t time_create;
+ __time64_t time_access;
+ __time64_t time_write;
+ _fsize_t size;
+ wchar_t name[260];
+ };
+
+ struct _wfinddata64_t {
+ unsigned attrib;
+ __time64_t time_create;
+ __time64_t time_access;
+ __time64_t time_write;
+ __int64 size;
+ wchar_t name[260];
+ };
+/* #endif */
+
+#ifdef _USE_32BIT_TIME_T
+#define _wfinddata_t _wfinddata32_t
+#define _wfinddatai64_t _wfinddata32i64_t
+
+#define _wfindfirst _wfindfirst32
+#define _wfindnext _wfindnext32
+#define _wfindfirsti64 _wfindfirst32i64
+#define _wfindnexti64 _wfindnext32i64
+#else
+#define _wfinddata_t _wfinddata64i32_t
+#define _wfinddatai64_t _wfinddata64_t
+
+#define _wfindfirst _wfindfirst64i32
+#define _wfindnext _wfindnext64i32
+#define _wfindfirsti64 _wfindfirst64
+#define _wfindnexti64 _wfindnext64
+#endif
+
+#define _WFINDDATA_T_DEFINED
+#endif
+
+#define _A_NORMAL 0x00
+#define _A_RDONLY 0x01
+#define _A_HIDDEN 0x02
+#define _A_SYSTEM 0x04
+#define _A_SUBDIR 0x10
+#define _A_ARCH 0x20
+
+#ifndef _SIZE_T_DEFINED
+#define _SIZE_T_DEFINED
+#undef size_t
+#ifdef _WIN64
+#if defined(__GNUC__) && defined(__STRICT_ANSI__)
+ typedef unsigned int size_t __attribute__ ((mode (DI)));
+#else
+ typedef unsigned __int64 size_t;
+#endif
+#else
+ typedef unsigned int size_t;
+#endif
+#endif
+
+#ifndef _SSIZE_T_DEFINED
+#define _SSIZE_T_DEFINED
+#undef ssize_t
+#ifdef _WIN64
+#if defined(__GNUC__) && defined(__STRICT_ANSI__)
+ typedef int ssize_t __attribute__ ((mode (DI)));
+#else
+ typedef __int64 ssize_t;
+#endif
+#else
+ typedef int ssize_t;
+#endif
+#endif
+
+#ifndef _OFF_T_DEFINED
+#define _OFF_T_DEFINED
+#ifndef _OFF_T_
+#define _OFF_T_
+ typedef long _off_t;
+#if !defined(NO_OLDNAMES) || defined(_POSIX)
+ typedef long off_t;
+#endif
+#endif
+#endif
+
+#ifndef _OFF64_T_DEFINED
+#define _OFF64_T_DEFINED
+#if defined(__GNUC__) && defined(__STRICT_ANSI__)
+ typedef int _off64_t __attribute__ ((mode (DI)));
+#if !defined(NO_OLDNAMES) || defined(_POSIX)
+ typedef int off64_t __attribute__ ((mode (DI)));
+#endif
+#else
+ typedef long long _off64_t;
+#if !defined(NO_OLDNAMES) || defined(_POSIX)
+ typedef long long off64_t;
+#endif
+#endif
+#endif
+
+ /* Some defines for _access nAccessMode (MS doesn't define them, but
+ * it doesn't seem to hurt to add them). */
+#define F_OK 0 /* Check for file existence */
+#define X_OK 1 /* Check for execute permission. */
+#define W_OK 2 /* Check for write permission */
+#define R_OK 4 /* Check for read permission */
+
+ _CRTIMP int __cdecl _access(const char *_Filename,int _AccessMode);
+ _CRTIMP int __cdecl _chmod(const char *_Filename,int _Mode);
+ _CRTIMP int __cdecl _chsize(int _FileHandle,long _Size);
+ _CRTIMP int __cdecl _close(int _FileHandle);
+ _CRTIMP int __cdecl _commit(int _FileHandle);
+ _CRTIMP int __cdecl _creat(const char *_Filename,int _PermissionMode);
+ _CRTIMP int __cdecl _dup(int _FileHandle);
+ _CRTIMP int __cdecl _dup2(int _FileHandleSrc,int _FileHandleDst);
+ _CRTIMP int __cdecl _eof(int _FileHandle);
+ _CRTIMP long __cdecl _filelength(int _FileHandle);
+ _CRTIMP intptr_t __cdecl _findfirst32(const char *_Filename,struct _finddata32_t *_FindData);
+ _CRTIMP int __cdecl _findnext32(intptr_t _FindHandle,struct _finddata32_t *_FindData);
+ _CRTIMP int __cdecl _findclose(intptr_t _FindHandle);
+ _CRTIMP int __cdecl _isatty(int _FileHandle);
+ _CRTIMP int __cdecl _locking(int _FileHandle,int _LockMode,long _NumOfBytes);
+ _CRTIMP long __cdecl _lseek(int _FileHandle,long _Offset,int _Origin);
+ _off64_t lseek64(int fd,_off64_t offset, int whence);
+ _CRTIMP char *__cdecl _mktemp(char *_TemplateName);
+ _CRTIMP int __cdecl _pipe(int *_PtHandles,unsigned int _PipeSize,int _TextMode);
+ _CRTIMP int __cdecl _read(int _FileHandle,void *_DstBuf,unsigned int _MaxCharCount);
+
+#ifndef _CRT_DIRECTORY_DEFINED
+#define _CRT_DIRECTORY_DEFINED
+ int __cdecl remove(const char *_Filename);
+ int __cdecl rename(const char *_OldFilename,const char *_NewFilename);
+ _CRTIMP int __cdecl _unlink(const char *_Filename);
+#ifndef NO_OLDNAMES
+ int __cdecl unlink(const char *_Filename);
+#endif
+#endif
+
+ _CRTIMP int __cdecl _setmode(int _FileHandle,int _Mode);
+ _CRTIMP long __cdecl _tell(int _FileHandle);
+ _CRTIMP int __cdecl _umask(int _Mode);
+ _CRTIMP int __cdecl _write(int _FileHandle,const void *_Buf,unsigned int _MaxCharCount);
+
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP __int64 __cdecl _filelengthi64(int _FileHandle);
+ _CRTIMP intptr_t __cdecl _findfirst32i64(const char *_Filename,struct _finddata32i64_t *_FindData);
+ _CRTIMP intptr_t __cdecl _findfirst64(const char *_Filename,struct __finddata64_t *_FindData);
+#ifdef __cplusplus
+#include <string.h>
+#endif
+ intptr_t __cdecl _findfirst64i32(const char *_Filename,struct _finddata64i32_t *_FindData);
+ __CRT_INLINE intptr_t __cdecl _findfirst64i32(const char *_Filename,struct _finddata64i32_t *_FindData)
+ {
+ struct __finddata64_t fd;
+ intptr_t ret = _findfirst64(_Filename,&fd);
+ _FindData->attrib=fd.attrib;
+ _FindData->time_create=fd.time_create;
+ _FindData->time_access=fd.time_access;
+ _FindData->time_write=fd.time_write;
+ _FindData->size=(_fsize_t) fd.size;
+ strncpy(_FindData->name,fd.name,260);
+ return ret;
+ }
+ _CRTIMP int __cdecl _findnext32i64(intptr_t _FindHandle,struct _finddata32i64_t *_FindData);
+ _CRTIMP int __cdecl _findnext64(intptr_t _FindHandle,struct __finddata64_t *_FindData);
+ int __cdecl _findnext64i32(intptr_t _FindHandle,struct _finddata64i32_t *_FindData);
+ __CRT_INLINE int __cdecl _findnext64i32(intptr_t _FindHandle,struct _finddata64i32_t *_FindData)
+ {
+ struct __finddata64_t fd;
+ int ret = _findnext64(_FindHandle,&fd);
+ _FindData->attrib=fd.attrib;
+ _FindData->time_create=fd.time_create;
+ _FindData->time_access=fd.time_access;
+ _FindData->time_write=fd.time_write;
+ _FindData->size=(_fsize_t) fd.size;
+ strncpy(_FindData->name,fd.name,260);
+ return ret;
+ }
+ __int64 __cdecl _lseeki64(int _FileHandle,__int64 _Offset,int _Origin);
+ __int64 __cdecl _telli64(int _FileHandle);
+#endif
+#ifndef NO_OLDNAMES
+
+#ifndef _UWIN
+ int __cdecl chdir (const char *);
+ char *__cdecl getcwd (char *, int);
+ int __cdecl mkdir (const char *);
+ char *__cdecl mktemp(char *);
+ int __cdecl rmdir (const char*);
+ int __cdecl chmod (const char *, int);
+#endif /* _UWIN */
+
+#endif /* Not NO_OLDNAMES */
+
+ _CRTIMP errno_t __cdecl _sopen_s(int *_FileHandle,const char *_Filename,int _OpenFlag,int _ShareFlag,int _PermissionMode);
+
+#ifndef __cplusplus
+ _CRTIMP int __cdecl _open(const char *_Filename,int _OpenFlag,...);
+ _CRTIMP int __cdecl _sopen(const char *_Filename,int _OpenFlag,int _ShareFlag,...);
+#else
+ extern "C++" _CRTIMP int __cdecl _open(const char *_Filename,int _Openflag,int _PermissionMode = 0);
+ extern "C++" _CRTIMP int __cdecl _sopen(const char *_Filename,int _Openflag,int _ShareFlag,int _PermissionMode = 0);
+#endif
+
+#ifndef _WIO_DEFINED
+#define _WIO_DEFINED
+ _CRTIMP int __cdecl _waccess(const wchar_t *_Filename,int _AccessMode);
+ _CRTIMP int __cdecl _wchmod(const wchar_t *_Filename,int _Mode);
+ _CRTIMP int __cdecl _wcreat(const wchar_t *_Filename,int _PermissionMode);
+ _CRTIMP intptr_t __cdecl _wfindfirst32(const wchar_t *_Filename,struct _wfinddata32_t *_FindData);
+ _CRTIMP int __cdecl _wfindnext32(intptr_t _FindHandle,struct _wfinddata32_t *_FindData);
+ _CRTIMP int __cdecl _wunlink(const wchar_t *_Filename);
+ _CRTIMP int __cdecl _wrename(const wchar_t *_NewFilename,const wchar_t *_OldFilename);
+ _CRTIMP wchar_t *__cdecl _wmktemp(wchar_t *_TemplateName);
+
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP intptr_t __cdecl _wfindfirst32i64(const wchar_t *_Filename,struct _wfinddata32i64_t *_FindData);
+ intptr_t __cdecl _wfindfirst64i32(const wchar_t *_Filename,struct _wfinddata64i32_t *_FindData);
+ _CRTIMP intptr_t __cdecl _wfindfirst64(const wchar_t *_Filename,struct _wfinddata64_t *_FindData);
+ _CRTIMP int __cdecl _wfindnext32i64(intptr_t _FindHandle,struct _wfinddata32i64_t *_FindData);
+ int __cdecl _wfindnext64i32(intptr_t _FindHandle,struct _wfinddata64i32_t *_FindData);
+ _CRTIMP int __cdecl _wfindnext64(intptr_t _FindHandle,struct _wfinddata64_t *_FindData);
+#endif
+
+ _CRTIMP errno_t __cdecl _wsopen_s(int *_FileHandle,const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,int _PermissionFlag);
+
+#if !defined(__cplusplus) || !(defined(_X86_) && !defined(__x86_64))
+ _CRTIMP int __cdecl _wopen(const wchar_t *_Filename,int _OpenFlag,...);
+ _CRTIMP int __cdecl _wsopen(const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,...);
+#else
+ extern "C++" _CRTIMP int __cdecl _wopen(const wchar_t *_Filename,int _OpenFlag,int _PermissionMode = 0);
+ extern "C++" _CRTIMP int __cdecl _wsopen(const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,int _PermissionMode = 0);
+#endif
+
+#endif
+
+ int __cdecl __lock_fhandle(int _Filehandle);
+ void __cdecl _unlock_fhandle(int _Filehandle);
+ _CRTIMP intptr_t __cdecl _get_osfhandle(int _FileHandle);
+ _CRTIMP int __cdecl _open_osfhandle(intptr_t _OSFileHandle,int _Flags);
+
+#ifndef NO_OLDNAMES
+ int __cdecl access(const char *_Filename,int _AccessMode);
+ int __cdecl chmod(const char *_Filename,int _AccessMode);
+ int __cdecl chsize(int _FileHandle,long _Size);
+ int __cdecl close(int _FileHandle);
+ int __cdecl creat(const char *_Filename,int _PermissionMode);
+ int __cdecl dup(int _FileHandle);
+ int __cdecl dup2(int _FileHandleSrc,int _FileHandleDst);
+ int __cdecl eof(int _FileHandle);
+ long __cdecl filelength(int _FileHandle);
+ int __cdecl isatty(int _FileHandle);
+ int __cdecl locking(int _FileHandle,int _LockMode,long _NumOfBytes);
+ long __cdecl lseek(int _FileHandle,long _Offset,int _Origin);
+ char *__cdecl mktemp(char *_TemplateName);
+ int __cdecl open(const char *_Filename,int _OpenFlag,...);
+ int __cdecl read(int _FileHandle,void *_DstBuf,unsigned int _MaxCharCount);
+ int __cdecl setmode(int _FileHandle,int _Mode);
+ int __cdecl sopen(const char *_Filename,int _OpenFlag,int _ShareFlag,...);
+ long __cdecl tell(int _FileHandle);
+ int __cdecl umask(int _Mode);
+ int __cdecl write(int _Filehandle,const void *_Buf,unsigned int _MaxCharCount);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Misc stuff */
+char *getlogin(void);
+#ifdef __USE_MINGW_ALARM
+unsigned int alarm(unsigned int seconds);
+#endif
+
+#ifdef __USE_MINGW_ACCESS
+/* Old versions of MSVCRT access() just ignored X_OK, while the version
+ shipped with Vista, returns an error code. This will restore the
+ old behaviour */
+static inline int __mingw_access (const char *__fname, int __mode) {
+ return _access (__fname, __mode & ~X_OK);
+}
+
+#define access(__f,__m) __mingw_access (__f, __m)
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#pragma pack(pop)
+
+#include <sec_api/io_s.h>
+
+#endif /* End _IO_H_ */
+
diff --git a/win32/include/limits.h b/win32/include/limits.h
new file mode 100644
index 0000000..fafb04a
--- /dev/null
+++ b/win32/include/limits.h
@@ -0,0 +1,111 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#include <_mingw.h>
+
+#ifndef _INC_LIMITS
+#define _INC_LIMITS
+
+/*
+* File system limits
+*
+* TODO: NAME_MAX and OPEN_MAX are file system limits or not? Are they the
+* same as FILENAME_MAX and FOPEN_MAX from stdio.h?
+* NOTE: Apparently the actual size of PATH_MAX is 260, but a space is
+* required for the NUL. TODO: Test?
+*/
+#define PATH_MAX (259)
+
+#define CHAR_BIT 8
+#define SCHAR_MIN (-128)
+#define SCHAR_MAX 127
+#define UCHAR_MAX 0xff
+
+#define CHAR_MIN SCHAR_MIN
+#define CHAR_MAX SCHAR_MAX
+
+#define MB_LEN_MAX 5
+#define SHRT_MIN (-32768)
+#define SHRT_MAX 32767
+#define USHRT_MAX 0xffff
+#define INT_MIN (-2147483647 - 1)
+#define INT_MAX 2147483647
+#define UINT_MAX 0xffffffff
+#define LONG_MIN (-2147483647L - 1)
+#define LONG_MAX 2147483647L
+#define ULONG_MAX 0xffffffffUL
+#define LLONG_MAX 9223372036854775807ll
+#define LLONG_MIN (-9223372036854775807ll - 1)
+#define ULLONG_MAX 0xffffffffffffffffull
+
+#if _INTEGRAL_MAX_BITS >= 8
+#define _I8_MIN (-127 - 1)
+#define _I8_MAX 127i8
+#define _UI8_MAX 0xffu
+#endif
+
+#if _INTEGRAL_MAX_BITS >= 16
+#define _I16_MIN (-32767 - 1)
+#define _I16_MAX 32767i16
+#define _UI16_MAX 0xffffu
+#endif
+
+#if _INTEGRAL_MAX_BITS >= 32
+#define _I32_MIN (-2147483647 - 1)
+#define _I32_MAX 2147483647
+#define _UI32_MAX 0xffffffffu
+#endif
+
+#if defined(__GNUC__)
+#undef LONG_LONG_MAX
+#define LONG_LONG_MAX 9223372036854775807ll
+#undef LONG_LONG_MIN
+#define LONG_LONG_MIN (-LONG_LONG_MAX-1)
+#undef ULONG_LONG_MAX
+#define ULONG_LONG_MAX (2ull * LONG_LONG_MAX + 1ull)
+#endif
+
+#if _INTEGRAL_MAX_BITS >= 64
+#define _I64_MIN (-9223372036854775807ll - 1)
+#define _I64_MAX 9223372036854775807ll
+#define _UI64_MAX 0xffffffffffffffffull
+#endif
+
+#ifndef SIZE_MAX
+#ifdef _WIN64
+#define SIZE_MAX _UI64_MAX
+#else
+#define SIZE_MAX UINT_MAX
+#endif
+#endif
+
+#ifdef _POSIX_
+#define _POSIX_ARG_MAX 4096
+#define _POSIX_CHILD_MAX 6
+#define _POSIX_LINK_MAX 8
+#define _POSIX_MAX_CANON 255
+#define _POSIX_MAX_INPUT 255
+#define _POSIX_NAME_MAX 14
+#define _POSIX_NGROUPS_MAX 0
+#define _POSIX_OPEN_MAX 16
+#define _POSIX_PATH_MAX 255
+#define _POSIX_PIPE_BUF 512
+#define _POSIX_SSIZE_MAX 32767
+#define _POSIX_STREAM_MAX 8
+#define _POSIX_TZNAME_MAX 3
+#define ARG_MAX 14500
+#define LINK_MAX 1024
+#define MAX_CANON _POSIX_MAX_CANON
+#define MAX_INPUT _POSIX_MAX_INPUT
+#define NAME_MAX 255
+#define NGROUPS_MAX 16
+#define OPEN_MAX 32
+#define PATH_MAX 512
+#define PIPE_BUF _POSIX_PIPE_BUF
+#define SSIZE_MAX _POSIX_SSIZE_MAX
+#define STREAM_MAX 20
+#define TZNAME_MAX 10
+#endif
+#endif
diff --git a/win32/include/locale.h b/win32/include/locale.h
new file mode 100644
index 0000000..686aa9b
--- /dev/null
+++ b/win32/include/locale.h
@@ -0,0 +1,91 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_LOCALE
+#define _INC_LOCALE
+
+#include <_mingw.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#define LC_ALL 0
+#define LC_COLLATE 1
+#define LC_CTYPE 2
+#define LC_MONETARY 3
+#define LC_NUMERIC 4
+#define LC_TIME 5
+
+#define LC_MIN LC_ALL
+#define LC_MAX LC_TIME
+
+#ifndef _LCONV_DEFINED
+#define _LCONV_DEFINED
+ struct lconv {
+ char *decimal_point;
+ char *thousands_sep;
+ char *grouping;
+ char *int_curr_symbol;
+ char *currency_symbol;
+ char *mon_decimal_point;
+ char *mon_thousands_sep;
+ char *mon_grouping;
+ char *positive_sign;
+ char *negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ };
+#endif
+
+#ifndef _CONFIG_LOCALE_SWT
+#define _CONFIG_LOCALE_SWT
+
+#define _ENABLE_PER_THREAD_LOCALE 0x1
+#define _DISABLE_PER_THREAD_LOCALE 0x2
+#define _ENABLE_PER_THREAD_LOCALE_GLOBAL 0x10
+#define _DISABLE_PER_THREAD_LOCALE_GLOBAL 0x20
+#define _ENABLE_PER_THREAD_LOCALE_NEW 0x100
+#define _DISABLE_PER_THREAD_LOCALE_NEW 0x200
+
+#endif
+
+ int __cdecl _configthreadlocale(int _Flag);
+ char *__cdecl setlocale(int _Category,const char *_Locale);
+ _CRTIMP struct lconv *__cdecl localeconv(void);
+ _locale_t __cdecl _get_current_locale(void);
+ _locale_t __cdecl _create_locale(int _Category,const char *_Locale);
+ void __cdecl _free_locale(_locale_t _Locale);
+ _locale_t __cdecl __get_current_locale(void);
+ _locale_t __cdecl __create_locale(int _Category,const char *_Locale);
+ void __cdecl __free_locale(_locale_t _Locale);
+
+#ifndef _WLOCALE_DEFINED
+#define _WLOCALE_DEFINED
+ _CRTIMP wchar_t *__cdecl _wsetlocale(int _Category,const wchar_t *_Locale);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+#endif
diff --git a/win32/include/malloc.h b/win32/include/malloc.h
new file mode 100644
index 0000000..fc783a8
--- /dev/null
+++ b/win32/include/malloc.h
@@ -0,0 +1,181 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _MALLOC_H_
+#define _MALLOC_H_
+
+#include <_mingw.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifndef _MM_MALLOC_H_INCLUDED
+#define _MM_MALLOC_H_INCLUDED
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN64
+#define _HEAP_MAXREQ 0xFFFFFFFFFFFFFFE0
+#else
+#define _HEAP_MAXREQ 0xFFFFFFE0
+#endif
+
+#ifndef _STATIC_ASSERT
+#define _STATIC_ASSERT(expr) extern void __static_assert_t(int [(expr)?1:-1])
+#endif
+
+/* Return codes for _heapwalk() */
+#define _HEAPEMPTY (-1)
+#define _HEAPOK (-2)
+#define _HEAPBADBEGIN (-3)
+#define _HEAPBADNODE (-4)
+#define _HEAPEND (-5)
+#define _HEAPBADPTR (-6)
+
+/* Values for _heapinfo.useflag */
+#define _FREEENTRY 0
+#define _USEDENTRY 1
+
+#ifndef _HEAPINFO_DEFINED
+#define _HEAPINFO_DEFINED
+ /* The structure used to walk through the heap with _heapwalk. */
+ typedef struct _heapinfo {
+ int *_pentry;
+ size_t _size;
+ int _useflag;
+ } _HEAPINFO;
+#endif
+
+ extern unsigned int _amblksiz;
+
+#define _mm_free(a) _aligned_free(a)
+#define _mm_malloc(a,b) _aligned_malloc(a,b)
+
+#ifndef _CRT_ALLOCATION_DEFINED
+#define _CRT_ALLOCATION_DEFINED
+ void *__cdecl calloc(size_t _NumOfElements,size_t _SizeOfElements);
+ void __cdecl free(void *_Memory);
+ void *__cdecl malloc(size_t _Size);
+ void *__cdecl realloc(void *_Memory,size_t _NewSize);
+ _CRTIMP void *__cdecl _recalloc(void *_Memory,size_t _Count,size_t _Size);
+ /* _CRTIMP void __cdecl _aligned_free(void *_Memory);
+ _CRTIMP void *__cdecl _aligned_malloc(size_t _Size,size_t _Alignment); */
+ _CRTIMP void *__cdecl _aligned_offset_malloc(size_t _Size,size_t _Alignment,size_t _Offset);
+ _CRTIMP void *__cdecl _aligned_realloc(void *_Memory,size_t _Size,size_t _Alignment);
+ _CRTIMP void *__cdecl _aligned_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment);
+ _CRTIMP void *__cdecl _aligned_offset_realloc(void *_Memory,size_t _Size,size_t _Alignment,size_t _Offset);
+ _CRTIMP void *__cdecl _aligned_offset_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment,size_t _Offset);
+#endif
+
+#define _MAX_WAIT_MALLOC_CRT 60000
+
+ _CRTIMP int __cdecl _resetstkoflw (void);
+ _CRTIMP unsigned long __cdecl _set_malloc_crt_max_wait(unsigned long _NewValue);
+
+ _CRTIMP void *__cdecl _expand(void *_Memory,size_t _NewSize);
+ _CRTIMP size_t __cdecl _msize(void *_Memory);
+#ifdef __GNUC__
+#undef _alloca
+#define _alloca(x) __builtin_alloca((x))
+#else
+ /* tcc implements alloca internally and exposes it (since commit d778bde7).
+ /* alloca is declared at include/stddef.h (which is distributed with tcc).
+ */
+#ifdef _alloca
+#undef _alloca
+#endif
+#define _alloca(x) alloca((x))
+#endif
+ _CRTIMP size_t __cdecl _get_sbh_threshold(void);
+ _CRTIMP int __cdecl _set_sbh_threshold(size_t _NewValue);
+ _CRTIMP errno_t __cdecl _set_amblksiz(size_t _Value);
+ _CRTIMP errno_t __cdecl _get_amblksiz(size_t *_Value);
+ _CRTIMP int __cdecl _heapadd(void *_Memory,size_t _Size);
+ _CRTIMP int __cdecl _heapchk(void);
+ _CRTIMP int __cdecl _heapmin(void);
+ _CRTIMP int __cdecl _heapset(unsigned int _Fill);
+ _CRTIMP int __cdecl _heapwalk(_HEAPINFO *_EntryInfo);
+ _CRTIMP size_t __cdecl _heapused(size_t *_Used,size_t *_Commit);
+ _CRTIMP intptr_t __cdecl _get_heap_handle(void);
+
+#define _ALLOCA_S_THRESHOLD 1024
+#define _ALLOCA_S_STACK_MARKER 0xCCCC
+#define _ALLOCA_S_HEAP_MARKER 0xDDDD
+
+#if(defined(_X86_) && !defined(__x86_64))
+#define _ALLOCA_S_MARKER_SIZE 8
+#elif defined(__ia64__) || defined(__x86_64)
+#define _ALLOCA_S_MARKER_SIZE 16
+#endif
+
+#if !defined(RC_INVOKED)
+ static __inline void *_MarkAllocaS(void *_Ptr,unsigned int _Marker) {
+ if(_Ptr) {
+ *((unsigned int*)_Ptr) = _Marker;
+ _Ptr = (char*)_Ptr + _ALLOCA_S_MARKER_SIZE;
+ }
+ return _Ptr;
+ }
+#endif
+
+#undef _malloca
+#define _malloca(size) \
+ ((((size) + _ALLOCA_S_MARKER_SIZE) <= _ALLOCA_S_THRESHOLD) ? \
+ _MarkAllocaS(_alloca((size) + _ALLOCA_S_MARKER_SIZE),_ALLOCA_S_STACK_MARKER) : \
+ _MarkAllocaS(malloc((size) + _ALLOCA_S_MARKER_SIZE),_ALLOCA_S_HEAP_MARKER))
+#undef _FREEA_INLINE
+#define _FREEA_INLINE
+
+#ifndef RC_INVOKED
+#undef _freea
+ static __inline void __cdecl _freea(void *_Memory) {
+ unsigned int _Marker;
+ if(_Memory) {
+ _Memory = (char*)_Memory - _ALLOCA_S_MARKER_SIZE;
+ _Marker = *(unsigned int *)_Memory;
+ if(_Marker==_ALLOCA_S_HEAP_MARKER) {
+ free(_Memory);
+ }
+#ifdef _ASSERTE
+ else if(_Marker!=_ALLOCA_S_STACK_MARKER) {
+ _ASSERTE(("Corrupted pointer passed to _freea",0));
+ }
+#endif
+ }
+ }
+#endif /* RC_INVOKED */
+
+#ifndef NO_OLDNAMES
+#ifdef __GNUC__
+#undef alloca
+#define alloca(x) __builtin_alloca((x))
+#endif
+#endif
+
+#ifdef HEAPHOOK
+#ifndef _HEAPHOOK_DEFINED
+#define _HEAPHOOK_DEFINED
+ typedef int (__cdecl *_HEAPHOOK)(int,size_t,void *,void **);
+#endif
+
+ _CRTIMP _HEAPHOOK __cdecl _setheaphook(_HEAPHOOK _NewHook);
+
+#define _HEAP_MALLOC 1
+#define _HEAP_CALLOC 2
+#define _HEAP_FREE 3
+#define _HEAP_REALLOC 4
+#define _HEAP_MSIZE 5
+#define _HEAP_EXPAND 6
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+
+#endif /* _MALLOC_H_ */
diff --git a/win32/include/math.h b/win32/include/math.h
new file mode 100644
index 0000000..74add20
--- /dev/null
+++ b/win32/include/math.h
@@ -0,0 +1,737 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _MATH_H_
+#define _MATH_H_
+
+#if __GNUC__ >= 3
+#pragma GCC system_header
+#endif
+
+#include <_mingw.h>
+
+struct exception;
+
+#pragma pack(push,_CRT_PACKING)
+
+#define _DOMAIN 1
+#define _SING 2
+#define _OVERFLOW 3
+#define _UNDERFLOW 4
+#define _TLOSS 5
+#define _PLOSS 6
+
+#ifndef __STRICT_ANSI__
+#ifndef NO_OLDNAMES
+#define DOMAIN _DOMAIN
+#define SING _SING
+#define OVERFLOW _OVERFLOW
+#define UNDERFLOW _UNDERFLOW
+#define TLOSS _TLOSS
+#define PLOSS _PLOSS
+#endif
+#endif
+
+#ifndef __STRICT_ANSI__
+#define M_E 2.71828182845904523536
+#define M_LOG2E 1.44269504088896340736
+#define M_LOG10E 0.434294481903251827651
+#define M_LN2 0.693147180559945309417
+#define M_LN10 2.30258509299404568402
+#define M_PI 3.14159265358979323846
+#define M_PI_2 1.57079632679489661923
+#define M_PI_4 0.785398163397448309616
+#define M_1_PI 0.318309886183790671538
+#define M_2_PI 0.636619772367581343076
+#define M_2_SQRTPI 1.12837916709551257390
+#define M_SQRT2 1.41421356237309504880
+#define M_SQRT1_2 0.707106781186547524401
+#endif
+
+#ifndef __STRICT_ANSI__
+/* See also float.h */
+#ifndef __MINGW_FPCLASS_DEFINED
+#define __MINGW_FPCLASS_DEFINED 1
+#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */
+#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */
+#define _FPCLASS_NINF 0x0004 /* Negative Infinity */
+#define _FPCLASS_NN 0x0008 /* Negative Normal */
+#define _FPCLASS_ND 0x0010 /* Negative Denormal */
+#define _FPCLASS_NZ 0x0020 /* Negative Zero */
+#define _FPCLASS_PZ 0x0040 /* Positive Zero */
+#define _FPCLASS_PD 0x0080 /* Positive Denormal */
+#define _FPCLASS_PN 0x0100 /* Positive Normal */
+#define _FPCLASS_PINF 0x0200 /* Positive Infinity */
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _EXCEPTION_DEFINED
+#define _EXCEPTION_DEFINED
+ struct _exception {
+ int type;
+ char *name;
+ double arg1;
+ double arg2;
+ double retval;
+ };
+#endif
+
+#ifndef _COMPLEX_DEFINED
+#define _COMPLEX_DEFINED
+ struct _complex {
+ double x,y;
+ };
+#endif
+
+#define EDOM 33
+#define ERANGE 34
+
+#ifndef _HUGE
+#ifdef _MSVCRT_
+ extern double *_HUGE;
+#else
+ extern double *_imp___HUGE;
+#define _HUGE (*_imp___HUGE)
+#endif
+#endif
+
+#define HUGE_VAL _HUGE
+
+#ifndef _CRT_ABS_DEFINED
+#define _CRT_ABS_DEFINED
+ int __cdecl abs(int _X);
+ long __cdecl labs(long _X);
+#endif
+ double __cdecl acos(double _X);
+ double __cdecl asin(double _X);
+ double __cdecl atan(double _X);
+ double __cdecl atan2(double _Y,double _X);
+#ifndef _SIGN_DEFINED
+#define _SIGN_DEFINED
+ _CRTIMP double __cdecl _copysign (double _Number,double _Sign);
+ _CRTIMP double __cdecl _chgsign (double _X);
+#endif
+ double __cdecl cos(double _X);
+ double __cdecl cosh(double _X);
+ double __cdecl exp(double _X);
+ double __cdecl expm1(double _X);
+ double __cdecl fabs(double _X);
+ double __cdecl fmod(double _X,double _Y);
+ double __cdecl log(double _X);
+ double __cdecl log10(double _X);
+ double __cdecl pow(double _X,double _Y);
+ double __cdecl sin(double _X);
+ double __cdecl sinh(double _X);
+ double __cdecl tan(double _X);
+ double __cdecl tanh(double _X);
+ double __cdecl sqrt(double _X);
+#ifndef _CRT_ATOF_DEFINED
+#define _CRT_ATOF_DEFINED
+ double __cdecl atof(const char *_String);
+ double __cdecl _atof_l(const char *_String,_locale_t _Locale);
+#endif
+
+ _CRTIMP double __cdecl _cabs(struct _complex _ComplexA);
+ double __cdecl ceil(double _X);
+ double __cdecl floor(double _X);
+ double __cdecl frexp(double _X,int *_Y);
+ double __cdecl _hypot(double _X,double _Y);
+ _CRTIMP double __cdecl _j0(double _X);
+ _CRTIMP double __cdecl _j1(double _X);
+ _CRTIMP double __cdecl _jn(int _X,double _Y);
+ double __cdecl ldexp(double _X,int _Y);
+#ifndef _CRT_MATHERR_DEFINED
+#define _CRT_MATHERR_DEFINED
+ int __cdecl _matherr(struct _exception *_Except);
+#endif
+ double __cdecl modf(double _X,double *_Y);
+ _CRTIMP double __cdecl _y0(double _X);
+ _CRTIMP double __cdecl _y1(double _X);
+ _CRTIMP double __cdecl _yn(int _X,double _Y);
+
+#if(defined(_X86_) && !defined(__x86_64))
+ _CRTIMP int __cdecl _set_SSE2_enable(int _Flag);
+ /* from libmingwex */
+ float __cdecl _hypotf(float _X,float _Y);
+#endif
+
+ float frexpf(float _X,int *_Y);
+ float __cdecl ldexpf(float _X,int _Y);
+ long double __cdecl ldexpl(long double _X,int _Y);
+ float __cdecl acosf(float _X);
+ float __cdecl asinf(float _X);
+ float __cdecl atanf(float _X);
+ float __cdecl atan2f(float _X,float _Y);
+ float __cdecl cosf(float _X);
+ float __cdecl sinf(float _X);
+ float __cdecl tanf(float _X);
+ float __cdecl coshf(float _X);
+ float __cdecl sinhf(float _X);
+ float __cdecl tanhf(float _X);
+ float __cdecl expf(float _X);
+ float __cdecl expm1f(float _X);
+ float __cdecl logf(float _X);
+ float __cdecl log10f(float _X);
+ float __cdecl modff(float _X,float *_Y);
+ float __cdecl powf(float _X,float _Y);
+ float __cdecl sqrtf(float _X);
+ float __cdecl ceilf(float _X);
+ float __cdecl floorf(float _X);
+ float __cdecl fmodf(float _X,float _Y);
+ float __cdecl _hypotf(float _X,float _Y);
+ float __cdecl fabsf(float _X);
+#if !defined(__ia64__)
+ /* from libmingwex */
+ float __cdecl _copysignf (float _Number,float _Sign);
+ float __cdecl _chgsignf (float _X);
+ float __cdecl _logbf(float _X);
+ float __cdecl _nextafterf(float _X,float _Y);
+ int __cdecl _finitef(float _X);
+ int __cdecl _isnanf(float _X);
+ int __cdecl _fpclassf(float _X);
+#endif
+
+#ifndef __cplusplus
+ __CRT_INLINE long double __cdecl fabsl (long double x)
+ {
+ long double res;
+ __asm__ ("fabs;" : "=t" (res) : "0" (x));
+ return res;
+ }
+#define _hypotl(x,y) ((long double)_hypot((double)(x),(double)(y)))
+#define _matherrl _matherr
+ __CRT_INLINE long double _chgsignl(long double _Number) { return _chgsign((double)(_Number)); }
+ __CRT_INLINE long double _copysignl(long double _Number,long double _Sign) { return _copysign((double)(_Number),(double)(_Sign)); }
+ __CRT_INLINE float frexpf(float _X,int *_Y) { return ((float)frexp((double)_X,_Y)); }
+
+#if !defined (__ia64__)
+ __CRT_INLINE float __cdecl fabsf (float x)
+ {
+ float res;
+ __asm__ ("fabs;" : "=t" (res) : "0" (x));
+ return res;
+ }
+
+ __CRT_INLINE float __cdecl ldexpf (float x, int expn) { return (float) ldexp (x, expn); }
+#endif
+#else
+ // cplusplus
+ __CRT_INLINE long double __cdecl fabsl (long double x)
+ {
+ long double res;
+ __asm__ ("fabs;" : "=t" (res) : "0" (x));
+ return res;
+ }
+ __CRT_INLINE long double modfl(long double _X,long double *_Y) {
+ double _Di,_Df = modf((double)_X,&_Di);
+ *_Y = (long double)_Di;
+ return (_Df);
+ }
+ __CRT_INLINE long double _chgsignl(long double _Number) { return _chgsign(static_cast<double>(_Number)); }
+ __CRT_INLINE long double _copysignl(long double _Number,long double _Sign) { return _copysign(static_cast<double>(_Number),static_cast<double>(_Sign)); }
+ __CRT_INLINE float frexpf(float _X,int *_Y) { return ((float)frexp((double)_X,_Y)); }
+#ifndef __ia64__
+ __CRT_INLINE float __cdecl fabsf (float x)
+ {
+ float res;
+ __asm__ ("fabs;" : "=t" (res) : "0" (x));
+ return res;
+ }
+ __CRT_INLINE float __cdecl ldexpf (float x, int expn) { return (float) ldexp (x, expn); }
+#ifndef __x86_64
+ __CRT_INLINE float acosf(float _X) { return ((float)acos((double)_X)); }
+ __CRT_INLINE float asinf(float _X) { return ((float)asin((double)_X)); }
+ __CRT_INLINE float atanf(float _X) { return ((float)atan((double)_X)); }
+ __CRT_INLINE float atan2f(float _X,float _Y) { return ((float)atan2((double)_X,(double)_Y)); }
+ __CRT_INLINE float ceilf(float _X) { return ((float)ceil((double)_X)); }
+ __CRT_INLINE float cosf(float _X) { return ((float)cos((double)_X)); }
+ __CRT_INLINE float coshf(float _X) { return ((float)cosh((double)_X)); }
+ __CRT_INLINE float expf(float _X) { return ((float)exp((double)_X)); }
+ __CRT_INLINE float floorf(float _X) { return ((float)floor((double)_X)); }
+ __CRT_INLINE float fmodf(float _X,float _Y) { return ((float)fmod((double)_X,(double)_Y)); }
+ __CRT_INLINE float logf(float _X) { return ((float)log((double)_X)); }
+ __CRT_INLINE float log10f(float _X) { return ((float)log10((double)_X)); }
+ __CRT_INLINE float modff(float _X,float *_Y) {
+ double _Di,_Df = modf((double)_X,&_Di);
+ *_Y = (float)_Di;
+ return ((float)_Df);
+ }
+ __CRT_INLINE float powf(float _X,float _Y) { return ((float)pow((double)_X,(double)_Y)); }
+ __CRT_INLINE float sinf(float _X) { return ((float)sin((double)_X)); }
+ __CRT_INLINE float sinhf(float _X) { return ((float)sinh((double)_X)); }
+ __CRT_INLINE float sqrtf(float _X) { return ((float)sqrt((double)_X)); }
+ __CRT_INLINE float tanf(float _X) { return ((float)tan((double)_X)); }
+ __CRT_INLINE float tanhf(float _X) { return ((float)tanh((double)_X)); }
+#endif
+#endif
+#endif
+
+#ifndef NO_OLDNAMES
+#define matherr _matherr
+
+#define HUGE _HUGE
+ /* double __cdecl cabs(struct _complex _X); */
+ double __cdecl hypot(double _X,double _Y);
+ _CRTIMP double __cdecl j0(double _X);
+ _CRTIMP double __cdecl j1(double _X);
+ _CRTIMP double __cdecl jn(int _X,double _Y);
+ _CRTIMP double __cdecl y0(double _X);
+ _CRTIMP double __cdecl y1(double _X);
+ _CRTIMP double __cdecl yn(int _X,double _Y);
+#endif
+
+#ifndef __NO_ISOCEXT
+#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \
+ || !defined __STRICT_ANSI__ || defined __GLIBCPP__
+
+#define NAN (0.0F/0.0F)
+#define HUGE_VALF (1.0F/0.0F)
+#define HUGE_VALL (1.0L/0.0L)
+#define INFINITY (1.0F/0.0F)
+
+
+#define FP_NAN 0x0100
+#define FP_NORMAL 0x0400
+#define FP_INFINITE (FP_NAN | FP_NORMAL)
+#define FP_ZERO 0x4000
+#define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
+ /* 0x0200 is signbit mask */
+
+
+ /*
+ We can't __CRT_INLINE float or double, because we want to ensure truncation
+ to semantic type before classification.
+ (A normal long double value might become subnormal when
+ converted to double, and zero when converted to float.)
+ */
+
+ extern int __cdecl __fpclassifyf (float);
+ extern int __cdecl __fpclassify (double);
+ extern int __cdecl __fpclassifyl (long double);
+
+/* Implemented at tcc/tcc_libm.h */
+#define fpclassify(x) (sizeof (x) == sizeof (float) ? __fpclassifyf (x) \
+ : sizeof (x) == sizeof (double) ? __fpclassify (x) \
+ : __fpclassifyl (x))
+
+ /* 7.12.3.2 */
+#define isfinite(x) ((fpclassify(x) & FP_NAN) == 0)
+
+ /* 7.12.3.3 */
+#define isinf(x) (fpclassify(x) == FP_INFINITE)
+
+ /* 7.12.3.4 */
+ /* We don't need to worry about truncation here:
+ A NaN stays a NaN. */
+#define isnan(x) (fpclassify(x) == FP_NAN)
+
+ /* 7.12.3.5 */
+#define isnormal(x) (fpclassify(x) == FP_NORMAL)
+
+ /* 7.12.3.6 The signbit macro */
+
+ extern int __cdecl __signbitf (float);
+ extern int __cdecl __signbit (double);
+ extern int __cdecl __signbitl (long double);
+
+/* Implemented at tcc/tcc_libm.h */
+#define signbit(x) (sizeof (x) == sizeof (float) ? __signbitf (x) \
+ : sizeof (x) == sizeof (double) ? __signbit (x) \
+ : __signbitl (x))
+
+ extern double __cdecl exp2(double);
+ extern float __cdecl exp2f(float);
+ extern long double __cdecl exp2l(long double);
+
+#define FP_ILOGB0 ((int)0x80000000)
+#define FP_ILOGBNAN ((int)0x80000000)
+ extern int __cdecl ilogb (double);
+ extern int __cdecl ilogbf (float);
+ extern int __cdecl ilogbl (long double);
+
+ extern double __cdecl log1p(double);
+ extern float __cdecl log1pf(float);
+ extern long double __cdecl log1pl(long double);
+
+ extern double __cdecl log2 (double);
+ extern float __cdecl log2f (float);
+ extern long double __cdecl log2l (long double);
+
+ extern double __cdecl logb (double);
+ extern float __cdecl logbf (float);
+ extern long double __cdecl logbl (long double);
+
+ __CRT_INLINE double __cdecl logb (double x)
+ {
+ double res;
+ __asm__ ("fxtract\n\t"
+ "fstp %%st" : "=t" (res) : "0" (x));
+ return res;
+ }
+
+ __CRT_INLINE float __cdecl logbf (float x)
+ {
+ float res;
+ __asm__ ("fxtract\n\t"
+ "fstp %%st" : "=t" (res) : "0" (x));
+ return res;
+ }
+
+ __CRT_INLINE long double __cdecl logbl (long double x)
+ {
+ long double res;
+ __asm__ ("fxtract\n\t"
+ "fstp %%st" : "=t" (res) : "0" (x));
+ return res;
+ }
+
+ extern long double __cdecl modfl (long double, long double*);
+
+ /* 7.12.6.13 */
+ extern double __cdecl scalbn (double, int);
+ extern float __cdecl scalbnf (float, int);
+ extern long double __cdecl scalbnl (long double, int);
+
+ extern double __cdecl scalbln (double, long);
+ extern float __cdecl scalblnf (float, long);
+ extern long double __cdecl scalblnl (long double, long);
+
+ /* 7.12.7.1 */
+ /* Implementations adapted from Cephes versions */
+ extern double __cdecl cbrt (double);
+ extern float __cdecl cbrtf (float);
+ extern long double __cdecl cbrtl (long double);
+
+ __CRT_INLINE float __cdecl hypotf (float x, float y)
+ { return (float) hypot (x, y);}
+ extern long double __cdecl hypotl (long double, long double);
+
+ extern long double __cdecl powl (long double, long double);
+ extern long double __cdecl expl(long double);
+ extern long double __cdecl expm1l(long double);
+ extern long double __cdecl coshl(long double);
+ extern long double __cdecl fabsl (long double);
+ extern long double __cdecl acosl(long double);
+ extern long double __cdecl asinl(long double);
+ extern long double __cdecl atanl(long double);
+ extern long double __cdecl atan2l(long double,long double);
+ extern long double __cdecl sinhl(long double);
+ extern long double __cdecl tanhl(long double);
+
+ /* 7.12.8.1 The erf functions */
+ extern double __cdecl erf (double);
+ extern float __cdecl erff (float);
+ /* TODO
+ extern long double __cdecl erfl (long double);
+ */
+
+ /* 7.12.8.2 The erfc functions */
+ extern double __cdecl erfc (double);
+ extern float __cdecl erfcf (float);
+ /* TODO
+ extern long double __cdecl erfcl (long double);
+ */
+
+ /* 7.12.8.3 The lgamma functions */
+ extern double __cdecl lgamma (double);
+ extern float __cdecl lgammaf (float);
+ extern long double __cdecl lgammal (long double);
+
+ /* 7.12.8.4 The tgamma functions */
+ extern double __cdecl tgamma (double);
+ extern float __cdecl tgammaf (float);
+ extern long double __cdecl tgammal (long double);
+
+ extern long double __cdecl ceill (long double);
+ extern long double __cdecl floorl (long double);
+ extern long double __cdecl frexpl(long double,int *);
+ extern long double __cdecl log10l(long double);
+ extern long double __cdecl logl(long double);
+ extern long double __cdecl cosl(long double);
+ extern long double __cdecl sinl(long double);
+ extern long double __cdecl tanl(long double);
+ extern long double sqrtl(long double);
+
+ /* 7.12.9.3 */
+ extern double __cdecl nearbyint ( double);
+ extern float __cdecl nearbyintf (float);
+ extern long double __cdecl nearbyintl (long double);
+
+ /* 7.12.9.4 */
+ /* round, using fpu control word settings */
+ __CRT_INLINE double __cdecl rint (double x)
+ {
+ double retval;
+ __asm__ (
+ "fldl %1\n"
+ "frndint \n"
+ "fstl %0\n" : "=m" (retval) : "m" (x));
+ return retval;
+ }
+
+ __CRT_INLINE float __cdecl rintf (float x)
+ {
+ float retval;
+ __asm__ (
+ "flds %1\n"
+ "frndint \n"
+ "fsts %0\n" : "=m" (retval) : "m" (x));
+ return retval;
+ }
+
+ __CRT_INLINE long double __cdecl rintl (long double x)
+ {
+ long double retval;
+ __asm__ (
+ "fldt %1\n"
+ "frndint \n"
+ "fstt %0\n" : "=m" (retval) : "m" (x));
+ return retval;
+ }
+
+ /* 7.12.9.5 */
+ __CRT_INLINE long __cdecl lrint (double x)
+ {
+ long retval;
+ __asm__ __volatile__ \
+ ("fldl %1\n" \
+ "fistpl %0" : "=m" (retval) : "m" (x)); \
+ return retval;
+ }
+
+ __CRT_INLINE long __cdecl lrintf (float x)
+ {
+ long retval;
+ __asm__ __volatile__ \
+ ("flds %1\n" \
+ "fistpl %0" : "=m" (retval) : "m" (x)); \
+ return retval;
+ }
+
+ __CRT_INLINE long __cdecl lrintl (long double x)
+ {
+ long retval;
+ __asm__ __volatile__ \
+ ("fldt %1\n" \
+ "fistpl %0" : "=m" (retval) : "m" (x)); \
+ return retval;
+ }
+
+ __CRT_INLINE long long __cdecl llrint (double x)
+ {
+ long long retval;
+ __asm__ __volatile__ \
+ ("fldl %1\n" \
+ "fistpll %0" : "=m" (retval) : "m" (x)); \
+ return retval;
+ }
+
+ __CRT_INLINE long long __cdecl llrintf (float x)
+ {
+ long long retval;
+ __asm__ __volatile__ \
+ ("flds %1\n" \
+ "fistpll %0" : "=m" (retval) : "m" (x)); \
+ return retval;
+ }
+
+ __CRT_INLINE long long __cdecl llrintl (long double x)
+ {
+ long long retval;
+ __asm__ __volatile__ \
+ ("fldt %1\n" \
+ "fistpll %0" : "=m" (retval) : "m" (x)); \
+ return retval;
+ }
+
+ #define FE_TONEAREST 0x0000
+ #define FE_DOWNWARD 0x0400
+ #define FE_UPWARD 0x0800
+ #define FE_TOWARDZERO 0x0c00
+
+ __CRT_INLINE double trunc (double _x)
+ {
+ double retval;
+ unsigned short saved_cw;
+ unsigned short tmp_cw;
+ __asm__ ("fnstcw %0;" : "=m" (saved_cw)); /* save FPU control word */
+ tmp_cw = (saved_cw & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO))
+ | FE_TOWARDZERO;
+ __asm__ ("fldcw %0;" : : "m" (tmp_cw));
+ __asm__ ("fldl %1;"
+ "frndint;"
+ "fstl %0;" : "=m" (retval) : "m" (_x)); /* round towards zero */
+ __asm__ ("fldcw %0;" : : "m" (saved_cw) ); /* restore saved control word */
+ return retval;
+ }
+
+ /* 7.12.9.6 */
+ /* round away from zero, regardless of fpu control word settings */
+ extern double __cdecl round (double);
+ extern float __cdecl roundf (float);
+ extern long double __cdecl roundl (long double);
+
+ /* 7.12.9.7 */
+ extern long __cdecl lround (double);
+ extern long __cdecl lroundf (float);
+ extern long __cdecl lroundl (long double);
+
+ extern long long __cdecl llround (double);
+ extern long long __cdecl llroundf (float);
+ extern long long __cdecl llroundl (long double);
+
+ /* 7.12.9.8 */
+ /* round towards zero, regardless of fpu control word settings */
+ extern double __cdecl trunc (double);
+ extern float __cdecl truncf (float);
+ extern long double __cdecl truncl (long double);
+
+ extern long double __cdecl fmodl (long double, long double);
+
+ /* 7.12.10.2 */
+ extern double __cdecl remainder (double, double);
+ extern float __cdecl remainderf (float, float);
+ extern long double __cdecl remainderl (long double, long double);
+
+ /* 7.12.10.3 */
+ extern double __cdecl remquo(double, double, int *);
+ extern float __cdecl remquof(float, float, int *);
+ extern long double __cdecl remquol(long double, long double, int *);
+
+ /* 7.12.11.1 */
+ extern double __cdecl copysign (double, double); /* in libmoldname.a */
+ extern float __cdecl copysignf (float, float);
+ extern long double __cdecl copysignl (long double, long double);
+
+ /* 7.12.11.2 Return a NaN */
+ extern double __cdecl nan(const char *tagp);
+ extern float __cdecl nanf(const char *tagp);
+ extern long double __cdecl nanl(const char *tagp);
+
+#ifndef __STRICT_ANSI__
+#define _nan() nan("")
+#define _nanf() nanf("")
+#define _nanl() nanl("")
+#endif
+
+ /* 7.12.11.3 */
+ extern double __cdecl nextafter (double, double); /* in libmoldname.a */
+ extern float __cdecl nextafterf (float, float);
+ extern long double __cdecl nextafterl (long double, long double);
+
+ /* 7.12.11.4 The nexttoward functions: TODO */
+
+ /* 7.12.12.1 */
+ /* x > y ? (x - y) : 0.0 */
+ extern double __cdecl fdim (double x, double y);
+ extern float __cdecl fdimf (float x, float y);
+ extern long double __cdecl fdiml (long double x, long double y);
+
+ /* fmax and fmin.
+ NaN arguments are treated as missing data: if one argument is a NaN
+ and the other numeric, then these functions choose the numeric
+ value. */
+
+ /* 7.12.12.2 */
+ extern double __cdecl fmax (double, double);
+ extern float __cdecl fmaxf (float, float);
+ extern long double __cdecl fmaxl (long double, long double);
+
+ /* 7.12.12.3 */
+ extern double __cdecl fmin (double, double);
+ extern float __cdecl fminf (float, float);
+ extern long double __cdecl fminl (long double, long double);
+
+ /* 7.12.13.1 */
+ /* return x * y + z as a ternary op */
+ extern double __cdecl fma (double, double, double);
+ extern float __cdecl fmaf (float, float, float);
+ extern long double __cdecl fmal (long double, long double, long double);
+
+
+#if 0 // gr: duplicate, see below
+ /* 7.12.14 */
+ /*
+ * With these functions, comparisons involving quiet NaNs set the FP
+ * condition code to "unordered". The IEEE floating-point spec
+ * dictates that the result of floating-point comparisons should be
+ * false whenever a NaN is involved, with the exception of the != op,
+ * which always returns true: yes, (NaN != NaN) is true).
+ */
+
+#if __GNUC__ >= 3
+
+#define isgreater(x, y) __builtin_isgreater(x, y)
+#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
+#define isless(x, y) __builtin_isless(x, y)
+#define islessequal(x, y) __builtin_islessequal(x, y)
+#define islessgreater(x, y) __builtin_islessgreater(x, y)
+#define isunordered(x, y) __builtin_isunordered(x, y)
+
+#else
+ /* helper */
+ __CRT_INLINE int __cdecl
+ __fp_unordered_compare (long double x, long double y){
+ unsigned short retval;
+ __asm__ ("fucom %%st(1);"
+ "fnstsw;": "=a" (retval) : "t" (x), "u" (y));
+ return retval;
+ }
+
+#define isgreater(x, y) ((__fp_unordered_compare(x, y) \
+ & 0x4500) == 0)
+#define isless(x, y) ((__fp_unordered_compare (y, x) \
+ & 0x4500) == 0)
+#define isgreaterequal(x, y) ((__fp_unordered_compare (x, y) \
+ & FP_INFINITE) == 0)
+#define islessequal(x, y) ((__fp_unordered_compare(y, x) \
+ & FP_INFINITE) == 0)
+#define islessgreater(x, y) ((__fp_unordered_compare(x, y) \
+ & FP_SUBNORMAL) == 0)
+#define isunordered(x, y) ((__fp_unordered_compare(x, y) \
+ & 0x4500) == 0x4500)
+
+#endif
+#endif //0
+
+
+#endif /* __STDC_VERSION__ >= 199901L */
+#endif /* __NO_ISOCEXT */
+
+#ifdef __cplusplus
+}
+extern "C++" {
+ template<class _Ty> inline _Ty _Pow_int(_Ty _X,int _Y) {
+ unsigned int _N;
+ if(_Y >= 0) _N = (unsigned int)_Y;
+ else _N = (unsigned int)(-_Y);
+ for(_Ty _Z = _Ty(1);;_X *= _X) {
+ if((_N & 1)!=0) _Z *= _X;
+ if((_N >>= 1)==0) return (_Y < 0 ? _Ty(1) / _Z : _Z);
+ }
+ }
+}
+#endif
+
+#pragma pack(pop)
+
+/* 7.12.14 */
+/*
+ * With these functions, comparisons involving quiet NaNs set the FP
+ * condition code to "unordered". The IEEE floating-point spec
+ * dictates that the result of floating-point comparisons should be
+ * false whenever a NaN is involved, with the exception of the != op,
+ * which always returns true: yes, (NaN != NaN) is true).
+ */
+
+/* Mini libm (inline __fpclassify*, __signbit* and variants) */
+#include "tcc/tcc_libm.h"
+
+#endif /* End _MATH_H_ */
+
diff --git a/win32/include/mem.h b/win32/include/mem.h
new file mode 100644
index 0000000..2552023
--- /dev/null
+++ b/win32/include/mem.h
@@ -0,0 +1,13 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+/*
+ * This file is part of the Mingw32 package.
+ *
+ * mem.h maps to string.h
+ */
+#ifndef __STRICT_ANSI__
+#include <string.h>
+#endif
diff --git a/win32/include/memory.h b/win32/include/memory.h
new file mode 100644
index 0000000..90d88ae
--- /dev/null
+++ b/win32/include/memory.h
@@ -0,0 +1,40 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_MEMORY
+#define _INC_MEMORY
+
+#include <_mingw.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _CONST_RETURN
+#define _CONST_RETURN
+#endif
+
+#define _WConst_return _CONST_RETURN
+
+#ifndef _CRT_MEMORY_DEFINED
+#define _CRT_MEMORY_DEFINED
+ _CRTIMP void *__cdecl _memccpy(void *_Dst,const void *_Src,int _Val,size_t _MaxCount);
+ _CONST_RETURN void *__cdecl memchr(const void *_Buf ,int _Val,size_t _MaxCount);
+ _CRTIMP int __cdecl _memicmp(const void *_Buf1,const void *_Buf2,size_t _Size);
+ _CRTIMP int __cdecl _memicmp_l(const void *_Buf1,const void *_Buf2,size_t _Size,_locale_t _Locale);
+ int __cdecl memcmp(const void *_Buf1,const void *_Buf2,size_t _Size);
+ void *__cdecl memcpy(void *_Dst,const void *_Src,size_t _Size);
+ void *__cdecl memset(void *_Dst,int _Val,size_t _Size);
+
+#ifndef NO_OLDNAMES
+ void *__cdecl memccpy(void *_Dst,const void *_Src,int _Val,size_t _Size);
+ int __cdecl memicmp(const void *_Buf1,const void *_Buf2,size_t _Size);
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/include/process.h b/win32/include/process.h
new file mode 100644
index 0000000..dadaf2b
--- /dev/null
+++ b/win32/include/process.h
@@ -0,0 +1,176 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_PROCESS
+#define _INC_PROCESS
+
+#include <_mingw.h>
+
+/* Includes a definition of _pid_t and pid_t */
+#include <sys/types.h>
+
+#ifndef _POSIX_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _P_WAIT 0
+#define _P_NOWAIT 1
+#define _OLD_P_OVERLAY 2
+#define _P_NOWAITO 3
+#define _P_DETACH 4
+#define _P_OVERLAY 2
+
+#define _WAIT_CHILD 0
+#define _WAIT_GRANDCHILD 1
+
+ _CRTIMP uintptr_t __cdecl _beginthread(void (__cdecl *_StartAddress) (void *),unsigned _StackSize,void *_ArgList);
+ _CRTIMP void __cdecl _endthread(void);
+ _CRTIMP uintptr_t __cdecl _beginthreadex(void *_Security,unsigned _StackSize,unsigned (__stdcall *_StartAddress) (void *),void *_ArgList,unsigned _InitFlag,unsigned *_ThrdAddr);
+ _CRTIMP void __cdecl _endthreadex(unsigned _Retval);
+
+#ifndef _CRT_TERMINATE_DEFINED
+#define _CRT_TERMINATE_DEFINED
+ void __cdecl __MINGW_NOTHROW exit(int _Code) __MINGW_ATTRIB_NORETURN;
+ _CRTIMP void __cdecl __MINGW_NOTHROW _exit(int _Code) __MINGW_ATTRIB_NORETURN;
+
+#pragma push_macro("abort")
+#undef abort
+ void __cdecl __declspec(noreturn) abort(void);
+#pragma pop_macro("abort")
+
+#endif
+
+ _CRTIMP void __cdecl __MINGW_NOTHROW _cexit(void);
+ _CRTIMP void __cdecl __MINGW_NOTHROW _c_exit(void);
+ _CRTIMP int __cdecl _getpid(void);
+ _CRTIMP intptr_t __cdecl _cwait(int *_TermStat,intptr_t _ProcHandle,int _Action);
+ _CRTIMP intptr_t __cdecl _execl(const char *_Filename,const char *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _execle(const char *_Filename,const char *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _execlp(const char *_Filename,const char *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _execlpe(const char *_Filename,const char *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _execv(const char *_Filename,const char *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _execve(const char *_Filename,const char *const *_ArgList,const char *const *_Env);
+ _CRTIMP intptr_t __cdecl _execvp(const char *_Filename,const char *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _execvpe(const char *_Filename,const char *const *_ArgList,const char *const *_Env);
+ _CRTIMP intptr_t __cdecl _spawnl(int _Mode,const char *_Filename,const char *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _spawnle(int _Mode,const char *_Filename,const char *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _spawnlp(int _Mode,const char *_Filename,const char *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _spawnlpe(int _Mode,const char *_Filename,const char *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _spawnv(int _Mode,const char *_Filename,const char *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _spawnve(int _Mode,const char *_Filename,const char *const *_ArgList,const char *const *_Env);
+ _CRTIMP intptr_t __cdecl _spawnvp(int _Mode,const char *_Filename,const char *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _spawnvpe(int _Mode,const char *_Filename,const char *const *_ArgList,const char *const *_Env);
+
+#ifndef _CRT_SYSTEM_DEFINED
+#define _CRT_SYSTEM_DEFINED
+ int __cdecl system(const char *_Command);
+#endif
+
+#ifndef _WPROCESS_DEFINED
+#define _WPROCESS_DEFINED
+ _CRTIMP intptr_t __cdecl _wexecl(const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wexecle(const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wexeclp(const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wexeclpe(const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wexecv(const wchar_t *_Filename,const wchar_t *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _wexecve(const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env);
+ _CRTIMP intptr_t __cdecl _wexecvp(const wchar_t *_Filename,const wchar_t *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _wexecvpe(const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env);
+ _CRTIMP intptr_t __cdecl _wspawnl(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wspawnle(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wspawnlp(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wspawnlpe(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wspawnv(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _wspawnve(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env);
+ _CRTIMP intptr_t __cdecl _wspawnvp(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _wspawnvpe(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env);
+#ifndef _CRT_WSYSTEM_DEFINED
+#define _CRT_WSYSTEM_DEFINED
+ _CRTIMP int __cdecl _wsystem(const wchar_t *_Command);
+#endif
+#endif
+
+ void __cdecl __security_init_cookie(void);
+#if (defined(_X86_) && !defined(__x86_64))
+ void __fastcall __security_check_cookie(uintptr_t _StackCookie);
+ __declspec(noreturn) void __cdecl __report_gsfailure(void);
+#else
+ void __cdecl __security_check_cookie(uintptr_t _StackCookie);
+ __declspec(noreturn) void __cdecl __report_gsfailure(uintptr_t _StackCookie);
+#endif
+ extern uintptr_t __security_cookie;
+
+ intptr_t __cdecl _loaddll(char *_Filename);
+ int __cdecl _unloaddll(intptr_t _Handle);
+ int (__cdecl *__cdecl _getdllprocaddr(intptr_t _Handle,char *_ProcedureName,intptr_t _Ordinal))(void);
+
+#ifdef _DECL_DLLMAIN
+#ifdef _WINDOWS_
+ WINBOOL WINAPI DllMain(HANDLE _HDllHandle,DWORD _Reason,LPVOID _Reserved);
+ WINBOOL WINAPI _CRT_INIT(HANDLE _HDllHandle,DWORD _Reason,LPVOID _Reserved);
+ WINBOOL WINAPI _wCRT_INIT(HANDLE _HDllHandle,DWORD _Reason,LPVOID _Reserved);
+ extern WINBOOL (WINAPI *const _pRawDllMain)(HANDLE,DWORD,LPVOID);
+#else
+ int __stdcall DllMain(void *_HDllHandle,unsigned _Reason,void *_Reserved);
+ int __stdcall _CRT_INIT(void *_HDllHandle,unsigned _Reason,void *_Reserved);
+ int __stdcall _wCRT_INIT(void *_HDllHandle,unsigned _Reason,void *_Reserved);
+ extern int (__stdcall *const _pRawDllMain)(void *,unsigned,void *);
+#endif
+#endif
+
+#ifndef NO_OLDNAMES
+#define P_WAIT _P_WAIT
+#define P_NOWAIT _P_NOWAIT
+#define P_OVERLAY _P_OVERLAY
+#define OLD_P_OVERLAY _OLD_P_OVERLAY
+#define P_NOWAITO _P_NOWAITO
+#define P_DETACH _P_DETACH
+#define WAIT_CHILD _WAIT_CHILD
+#define WAIT_GRANDCHILD _WAIT_GRANDCHILD
+
+ intptr_t __cdecl cwait(int *_TermStat,intptr_t _ProcHandle,int _Action);
+#ifdef __GNUC__
+ int __cdecl execl(const char *_Filename,const char *_ArgList,...);
+ int __cdecl execle(const char *_Filename,const char *_ArgList,...);
+ int __cdecl execlp(const char *_Filename,const char *_ArgList,...);
+ int __cdecl execlpe(const char *_Filename,const char *_ArgList,...);
+#else
+ intptr_t __cdecl execl(const char *_Filename,const char *_ArgList,...);
+ intptr_t __cdecl execle(const char *_Filename,const char *_ArgList,...);
+ intptr_t __cdecl execlp(const char *_Filename,const char *_ArgList,...);
+ intptr_t __cdecl execlpe(const char *_Filename,const char *_ArgList,...);
+#endif
+ intptr_t __cdecl spawnl(int,const char *_Filename,const char *_ArgList,...);
+ intptr_t __cdecl spawnle(int,const char *_Filename,const char *_ArgList,...);
+ intptr_t __cdecl spawnlp(int,const char *_Filename,const char *_ArgList,...);
+ intptr_t __cdecl spawnlpe(int,const char *_Filename,const char *_ArgList,...);
+ int __cdecl getpid(void);
+#ifdef __GNUC__
+ /* Those methods are predefined by gcc builtins to return int. So to prevent
+ stupid warnings, define them in POSIX way. This is save, because those
+ methods do not return in success case, so that the return value is not
+ really dependent to its scalar width. */
+ int __cdecl execv(const char *_Filename,const char *const _ArgList[]);
+ int __cdecl execve(const char *_Filename,const char *const _ArgList[],const char *const _Env[]);
+ int __cdecl execvp(const char *_Filename,const char *const _ArgList[]);
+ int __cdecl execvpe(const char *_Filename,const char *const _ArgList[],const char *const _Env[]);
+#else
+ intptr_t __cdecl execv(const char *_Filename,const char *const _ArgList[]);
+ intptr_t __cdecl execve(const char *_Filename,const char *const _ArgList[],const char *const _Env[]);
+ intptr_t __cdecl execvp(const char *_Filename,const char *const _ArgList[]);
+ intptr_t __cdecl execvpe(const char *_Filename,const char *const _ArgList[],const char *const _Env[]);
+#endif
+ intptr_t __cdecl spawnv(int,const char *_Filename,const char *const _ArgList[]);
+ intptr_t __cdecl spawnve(int,const char *_Filename,const char *const _ArgList[],const char *const _Env[]);
+ intptr_t __cdecl spawnvp(int,const char *_Filename,const char *const _ArgList[]);
+ intptr_t __cdecl spawnvpe(int,const char *_Filename,const char *const _ArgList[],char *const _Env[]);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
diff --git a/win32/include/sec_api/conio_s.h b/win32/include/sec_api/conio_s.h
new file mode 100644
index 0000000..98d97ba
--- /dev/null
+++ b/win32/include/sec_api/conio_s.h
@@ -0,0 +1,42 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+
+#ifndef _INC_CONIO_S
+#define _INC_CONIO_S
+
+#include <conio.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ _CRTIMP errno_t __cdecl _cgets_s(char *_Buffer,size_t _Size,size_t *_SizeRead);
+ _CRTIMP int __cdecl _cprintf_s(const char *_Format,...);
+ _CRTIMP int __cdecl _cscanf_s(const char *_Format,...);
+ _CRTIMP int __cdecl _cscanf_s_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcprintf_s(const char *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _cprintf_s_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcprintf_s_l(const char *_Format,_locale_t _Locale,va_list _ArgList);
+
+#ifndef _WCONIO_DEFINED_S
+#define _WCONIO_DEFINED_S
+ _CRTIMP errno_t __cdecl _cgetws_s(wchar_t *_Buffer,size_t _SizeInWords,size_t *_SizeRead);
+ _CRTIMP int __cdecl _cwprintf_s(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _cwscanf_s(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _cwscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcwprintf_s(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _cwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+#endif
diff --git a/win32/include/sec_api/crtdbg_s.h b/win32/include/sec_api/crtdbg_s.h
new file mode 100644
index 0000000..4598b4f
--- /dev/null
+++ b/win32/include/sec_api/crtdbg_s.h
@@ -0,0 +1,19 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+
+#ifndef _INC_CRTDBG_S
+#define _INC_CRTDBG_S
+
+#include <crtdbg.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#define _dupenv_s_dbg(ps1,size,s2,t,f,l) _dupenv_s(ps1,size,s2)
+#define _wdupenv_s_dbg(ps1,size,s2,t,f,l) _wdupenv_s(ps1,size,s2)
+
+#endif
+
+#endif
diff --git a/win32/include/sec_api/io_s.h b/win32/include/sec_api/io_s.h
new file mode 100644
index 0000000..ec565a6
--- /dev/null
+++ b/win32/include/sec_api/io_s.h
@@ -0,0 +1,33 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_IO_S
+#define _INC_IO_S
+
+#include <io.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ _CRTIMP errno_t __cdecl _access_s(const char *_Filename,int _AccessMode);
+ _CRTIMP errno_t __cdecl _chsize_s(int _FileHandle,__int64 _Size);
+ _CRTIMP errno_t __cdecl _mktemp_s(char *_TemplateName,size_t _Size);
+ _CRTIMP errno_t __cdecl _umask_s(int _NewMode,int *_OldMode);
+
+#ifndef _WIO_S_DEFINED
+#define _WIO_S_DEFINED
+ _CRTIMP errno_t __cdecl _waccess_s(const wchar_t *_Filename,int _AccessMode);
+ _CRTIMP errno_t __cdecl _wmktemp_s(wchar_t *_TemplateName,size_t _SizeInWords);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+#endif
diff --git a/win32/include/sec_api/mbstring_s.h b/win32/include/sec_api/mbstring_s.h
new file mode 100644
index 0000000..6b2b188
--- /dev/null
+++ b/win32/include/sec_api/mbstring_s.h
@@ -0,0 +1,52 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_MBSTRING_S
+#define _INC_MBSTRING_S
+
+#include <mbstring.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _MBSTRING_S_DEFINED
+#define _MBSTRING_S_DEFINED
+ _CRTIMP errno_t __cdecl _mbscat_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src);
+ _CRTIMP errno_t __cdecl _mbscat_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _mbscpy_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src);
+ _CRTIMP errno_t __cdecl _mbscpy_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _mbslwr_s(unsigned char *_Str,size_t _SizeInBytes);
+ _CRTIMP errno_t __cdecl _mbslwr_s_l(unsigned char *_Str,size_t _SizeInBytes,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _mbsnbcat_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount);
+ _CRTIMP errno_t __cdecl _mbsnbcat_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _mbsnbcpy_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount);
+ _CRTIMP errno_t __cdecl _mbsnbcpy_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _mbsnbset_s(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Ch,size_t _MaxCount);
+ _CRTIMP errno_t __cdecl _mbsnbset_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Ch,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _mbsncat_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount);
+ _CRTIMP errno_t __cdecl _mbsncat_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _mbsncpy_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount);
+ _CRTIMP errno_t __cdecl _mbsncpy_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _mbsnset_s(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Val,size_t _MaxCount);
+ _CRTIMP errno_t __cdecl _mbsnset_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Val,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _mbsset_s(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Val);
+ _CRTIMP errno_t __cdecl _mbsset_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Val,_locale_t _Locale);
+ _CRTIMP unsigned char *__cdecl _mbstok_s(unsigned char *_Str,const unsigned char *_Delim,unsigned char **_Context);
+ _CRTIMP unsigned char *__cdecl _mbstok_s_l(unsigned char *_Str,const unsigned char *_Delim,unsigned char **_Context,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _mbsupr_s(unsigned char *_Str,size_t _SizeInBytes);
+ _CRTIMP errno_t __cdecl _mbsupr_s_l(unsigned char *_Str,size_t _SizeInBytes,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _mbccpy_s(unsigned char *_Dst,size_t _DstSizeInBytes,int *_PCopied,const unsigned char *_Src);
+ _CRTIMP errno_t __cdecl _mbccpy_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,int *_PCopied,const unsigned char *_Src,_locale_t _Locale);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+#endif
diff --git a/win32/include/sec_api/search_s.h b/win32/include/sec_api/search_s.h
new file mode 100644
index 0000000..cae8998
--- /dev/null
+++ b/win32/include/sec_api/search_s.h
@@ -0,0 +1,25 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_SEARCH_S
+#define _INC_SEARCH_S
+
+#include <search.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ _CRTIMP void *__cdecl _lfind_s(const void *_Key,const void *_Base,unsigned int *_NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(void *,const void *,const void *),void *_Context);
+ _CRTIMP void *__cdecl _lsearch_s(const void *_Key,void *_Base,unsigned int *_NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(void *,const void *,const void *),void *_Context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+#endif
diff --git a/win32/include/sec_api/stdio_s.h b/win32/include/sec_api/stdio_s.h
new file mode 100644
index 0000000..c9b803b
--- /dev/null
+++ b/win32/include/sec_api/stdio_s.h
@@ -0,0 +1,145 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_STDIO_S
+#define _INC_STDIO_S
+
+#include <stdio.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _STDIO_S_DEFINED
+#define _STDIO_S_DEFINED
+ _CRTIMP errno_t __cdecl clearerr_s(FILE *_File);
+ int __cdecl fprintf_s(FILE *_File,const char *_Format,...);
+ size_t __cdecl fread_s(void *_DstBuf,size_t _DstSize,size_t _ElementSize,size_t _Count,FILE *_File);
+ _CRTIMP int __cdecl _fscanf_s_l(FILE *_File,const char *_Format,_locale_t _Locale,...);
+ int __cdecl printf_s(const char *_Format,...);
+ _CRTIMP int __cdecl _scanf_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _scanf_s_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _snprintf_s(char *_DstBuf,size_t _DstSize,size_t _MaxCount,const char *_Format,...);
+ _CRTIMP int __cdecl _snprintf_c(char *_DstBuf,size_t _MaxCount,const char *_Format,...);
+ _CRTIMP int __cdecl _vsnprintf_c(char *_DstBuf,size_t _MaxCount,const char *_Format,va_list _ArgList);
+ int __cdecl sprintf_s(char *_DstBuf,size_t _DstSize,const char *_Format,...);
+ _CRTIMP int __cdecl _fscanf_l(FILE *_File,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _sscanf_l(const char *_Src,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _sscanf_s_l(const char *_Src,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _snscanf_s(const char *_Src,size_t _MaxCount,const char *_Format,...);
+ _CRTIMP int __cdecl _snscanf_l(const char *_Src,size_t _MaxCount,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _snscanf_s_l(const char *_Src,size_t _MaxCount,const char *_Format,_locale_t _Locale,...);
+ int __cdecl vfprintf_s(FILE *_File,const char *_Format,va_list _ArgList);
+ int __cdecl vprintf_s(const char *_Format,va_list _ArgList);
+ int __cdecl vsnprintf_s(char *_DstBuf,size_t _DstSize,size_t _MaxCount,const char *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _vsnprintf_s(char *_DstBuf,size_t _DstSize,size_t _MaxCount,const char *_Format,va_list _ArgList);
+ int __cdecl vsprintf_s(char *_DstBuf,size_t _Size,const char *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _fprintf_p(FILE *_File,const char *_Format,...);
+ _CRTIMP int __cdecl _printf_p(const char *_Format,...);
+ _CRTIMP int __cdecl _sprintf_p(char *_Dst,size_t _MaxCount,const char *_Format,...);
+ _CRTIMP int __cdecl _vfprintf_p(FILE *_File,const char *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _vprintf_p(const char *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _vsprintf_p(char *_Dst,size_t _MaxCount,const char *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _scprintf_p(const char *_Format,...);
+ _CRTIMP int __cdecl _vscprintf_p(const char *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _printf_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _printf_p_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vprintf_l(const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _vprintf_p_l(const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _fprintf_l(FILE *_File,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _fprintf_p_l(FILE *_File,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vfprintf_l(FILE *_File,const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _vfprintf_p_l(FILE *_File,const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _sprintf_l(char *_DstBuf,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _sprintf_p_l(char *_DstBuf,size_t _MaxCount,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vsprintf_l(char *_DstBuf,const char *_Format,_locale_t,va_list _ArgList);
+ _CRTIMP int __cdecl _vsprintf_p_l(char *_DstBuf,size_t _MaxCount,const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _scprintf_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _scprintf_p_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vscprintf_l(const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _vscprintf_p_l(const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _printf_s_l(const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vprintf_s_l(const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _fprintf_s_l(FILE *_File,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vfprintf_s_l(FILE *_File,const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _sprintf_s_l(char *_DstBuf,size_t _DstSize,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vsprintf_s_l(char *_DstBuf,size_t _DstSize,const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _snprintf_s_l(char *_DstBuf,size_t _DstSize,size_t _MaxCount,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vsnprintf_s_l(char *_DstBuf,size_t _DstSize,size_t _MaxCount,const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _snprintf_l(char *_DstBuf,size_t _MaxCount,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _snprintf_c_l(char *_DstBuf,size_t _MaxCount,const char *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vsnprintf_l(char *_DstBuf,size_t _MaxCount,const char *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _vsnprintf_c_l(char *_DstBuf,size_t _MaxCount,const char *,_locale_t _Locale,va_list _ArgList);
+
+#ifndef _WSTDIO_S_DEFINED
+#define _WSTDIO_S_DEFINED
+ _CRTIMP wchar_t *__cdecl _getws_s(wchar_t *_Str,size_t _SizeInWords);
+ int __cdecl fwprintf_s(FILE *_File,const wchar_t *_Format,...);
+ int __cdecl wprintf_s(const wchar_t *_Format,...);
+ int __cdecl vwprintf_s(const wchar_t *_Format,va_list _ArgList);
+ int __cdecl swprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,...);
+ int __cdecl vswprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _snwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vsnwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _wprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _fwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vfwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _swprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vswprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _snwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vsnwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _fwscanf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _swscanf_s_l(const wchar_t *_Src,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _snwscanf_s(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _snwscanf_s_l(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _wscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP errno_t __cdecl _wfopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode);
+ _CRTIMP errno_t __cdecl _wfreopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode,FILE *_OldFile);
+ _CRTIMP errno_t __cdecl _wtmpnam_s(wchar_t *_DstBuf,size_t _SizeInWords);
+ _CRTIMP int __cdecl _fwprintf_p(FILE *_File,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _wprintf_p(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vfwprintf_p(FILE *_File,const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _vwprintf_p(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _swprintf_p(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vswprintf_p(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _scwprintf_p(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vscwprintf_p(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _wprintf_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _wprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _vwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _fwprintf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _fwprintf_p_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vfwprintf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _vfwprintf_p_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _swprintf_c_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _swprintf_p_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vswprintf_c_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _vswprintf_p_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _scwprintf_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _scwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vscwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _snwprintf_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vsnwprintf_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl __swprintf_l(wchar_t *_Dest,const wchar_t *_Format,_locale_t _Plocinfo,...);
+ _CRTIMP int __cdecl __vswprintf_l(wchar_t *_Dest,const wchar_t *_Format,_locale_t _Plocinfo,va_list _Args);
+ _CRTIMP int __cdecl _vscwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _fwscanf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _swscanf_l(const wchar_t *_Src,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _snwscanf_l(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _wscanf_l(const wchar_t *_Format,_locale_t _Locale,...);
+#endif
+#endif
+
+ _CRTIMP size_t __cdecl _fread_nolock_s(void *_DstBuf,size_t _DstSize,size_t _ElementSize,size_t _Count,FILE *_File);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
diff --git a/win32/include/sec_api/stdlib_s.h b/win32/include/sec_api/stdlib_s.h
new file mode 100644
index 0000000..f98262c
--- /dev/null
+++ b/win32/include/sec_api/stdlib_s.h
@@ -0,0 +1,67 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_STDLIB_S
+#define _INC_STDLIB_S
+
+#include <stdlib.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ _CRTIMP errno_t __cdecl _dupenv_s(char **_PBuffer,size_t *_PBufferSizeInBytes,const char *_VarName);
+ _CRTIMP errno_t __cdecl _itoa_s(int _Value,char *_DstBuf,size_t _Size,int _Radix);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP errno_t __cdecl _i64toa_s(__int64 _Val,char *_DstBuf,size_t _Size,int _Radix);
+ _CRTIMP errno_t __cdecl _ui64toa_s(unsigned __int64 _Val,char *_DstBuf,size_t _Size,int _Radix);
+#endif
+ _CRTIMP errno_t __cdecl _ltoa_s(long _Val,char *_DstBuf,size_t _Size,int _Radix);
+ _CRTIMP errno_t __cdecl mbstowcs_s(size_t *_PtNumOfCharConverted,wchar_t *_DstBuf,size_t _SizeInWords,const char *_SrcBuf,size_t _MaxCount);
+ _CRTIMP errno_t __cdecl _mbstowcs_s_l(size_t *_PtNumOfCharConverted,wchar_t *_DstBuf,size_t _SizeInWords,const char *_SrcBuf,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _ultoa_s(unsigned long _Val,char *_DstBuf,size_t _Size,int _Radix);
+ _CRTIMP errno_t __cdecl _wctomb_s_l(int *_SizeConverted,char *_MbCh,size_t _SizeInBytes,wchar_t _WCh,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl wcstombs_s(size_t *_PtNumOfCharConverted,char *_Dst,size_t _DstSizeInBytes,const wchar_t *_Src,size_t _MaxCountInBytes);
+ _CRTIMP errno_t __cdecl _wcstombs_s_l(size_t *_PtNumOfCharConverted,char *_Dst,size_t _DstSizeInBytes,const wchar_t *_Src,size_t _MaxCountInBytes,_locale_t _Locale);
+
+#ifndef _WSTDLIB_S_DEFINED
+#define _WSTDLIB_S_DEFINED
+ _CRTIMP errno_t __cdecl _itow_s (int _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
+ _CRTIMP errno_t __cdecl _ltow_s (long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
+ _CRTIMP errno_t __cdecl _ultow_s (unsigned long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
+ _CRTIMP errno_t __cdecl _wgetenv_s(size_t *_ReturnSize,wchar_t *_DstBuf,size_t _DstSizeInWords,const wchar_t *_VarName);
+ _CRTIMP errno_t __cdecl _wdupenv_s(wchar_t **_Buffer,size_t *_BufferSizeInWords,const wchar_t *_VarName);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP errno_t __cdecl _i64tow_s(__int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
+ _CRTIMP errno_t __cdecl _ui64tow_s(unsigned __int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
+#endif
+#endif
+
+#ifndef _POSIX_
+ _CRTIMP errno_t __cdecl _ecvt_s(char *_DstBuf,size_t _Size,double _Val,int _NumOfDights,int *_PtDec,int *_PtSign);
+ _CRTIMP errno_t __cdecl _fcvt_s(char *_DstBuf,size_t _Size,double _Val,int _NumOfDec,int *_PtDec,int *_PtSign);
+ _CRTIMP errno_t __cdecl _gcvt_s(char *_DstBuf,size_t _Size,double _Val,int _NumOfDigits);
+ _CRTIMP errno_t __cdecl _makepath_s(char *_PathResult,size_t _Size,const char *_Drive,const char *_Dir,const char *_Filename,const char *_Ext);
+ _CRTIMP errno_t __cdecl _putenv_s(const char *_Name,const char *_Value);
+ _CRTIMP errno_t __cdecl _searchenv_s(const char *_Filename,const char *_EnvVar,char *_ResultPath,size_t _SizeInBytes);
+ _CRTIMP errno_t __cdecl _splitpath_s(const char *_FullPath,char *_Drive,size_t _DriveSize,char *_Dir,size_t _DirSize,char *_Filename,size_t _FilenameSize,char *_Ext,size_t _ExtSize);
+
+#ifndef _WSTDLIBP_S_DEFINED
+#define _WSTDLIBP_S_DEFINED
+ _CRTIMP errno_t __cdecl _wmakepath_s(wchar_t *_PathResult,size_t _SizeInWords,const wchar_t *_Drive,const wchar_t *_Dir,const wchar_t *_Filename,const wchar_t *_Ext);
+ _CRTIMP errno_t __cdecl _wputenv_s(const wchar_t *_Name,const wchar_t *_Value);
+ _CRTIMP errno_t __cdecl _wsearchenv_s(const wchar_t *_Filename,const wchar_t *_EnvVar,wchar_t *_ResultPath,size_t _SizeInWords);
+ _CRTIMP errno_t __cdecl _wsplitpath_s(const wchar_t *_FullPath,wchar_t *_Drive,size_t _DriveSizeInWords,wchar_t *_Dir,size_t _DirSizeInWords,wchar_t *_Filename,size_t _FilenameSizeInWords,wchar_t *_Ext,size_t _ExtSizeInWords);
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+#endif
diff --git a/win32/include/sec_api/stralign_s.h b/win32/include/sec_api/stralign_s.h
new file mode 100644
index 0000000..5b78f58
--- /dev/null
+++ b/win32/include/sec_api/stralign_s.h
@@ -0,0 +1,30 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef __STRALIGN_H_S_
+#define __STRALIGN_H_S_
+
+#include <stralign.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(I_X86_) && defined(_WSTRING_S_DEFINED)
+#if defined(__cplusplus) && defined(_WConst_Return)
+ static __inline PUWSTR ua_wcscpy_s(PUWSTR Destination,size_t DestinationSize,PCUWSTR Source) {
+ if(WSTR_ALIGNED(Source) && WSTR_ALIGNED(Destination)) return (wcscpy_s((PWSTR)Destination,DestinationSize,(PCWSTR)Source)==0 ? Destination : NULL);
+ return uaw_wcscpy((PCUWSTR)String,Character);
+ }
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
diff --git a/win32/include/sec_api/string_s.h b/win32/include/sec_api/string_s.h
new file mode 100644
index 0000000..9db70e7
--- /dev/null
+++ b/win32/include/sec_api/string_s.h
@@ -0,0 +1,41 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_STRING_S
+#define _INC_STRING_S
+
+#include <string.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ _CRTIMP errno_t __cdecl _strset_s(char *_Dst,size_t _DstSize,int _Value);
+ _CRTIMP errno_t __cdecl _strerror_s(char *_Buf,size_t _SizeInBytes,const char *_ErrMsg);
+ _CRTIMP errno_t __cdecl _strlwr_s(char *_Str,size_t _Size);
+ _CRTIMP errno_t __cdecl _strlwr_s_l(char *_Str,size_t _Size,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _strnset_s(char *_Str,size_t _Size,int _Val,size_t _MaxCount);
+ _CRTIMP errno_t __cdecl _strupr_s(char *_Str,size_t _Size);
+ _CRTIMP errno_t __cdecl _strupr_s_l(char *_Str,size_t _Size,_locale_t _Locale);
+#ifndef _WSTRING_S_DEFINED
+#define _WSTRING_S_DEFINED
+ _CRTIMP wchar_t *__cdecl wcstok_s(wchar_t *_Str,const wchar_t *_Delim,wchar_t **_Context);
+ _CRTIMP errno_t __cdecl _wcserror_s(wchar_t *_Buf,size_t _SizeInWords,int _ErrNum);
+ _CRTIMP errno_t __cdecl __wcserror_s(wchar_t *_Buffer,size_t _SizeInWords,const wchar_t *_ErrMsg);
+ _CRTIMP errno_t __cdecl _wcsnset_s(wchar_t *_Dst,size_t _DstSizeInWords,wchar_t _Val,size_t _MaxCount);
+ _CRTIMP errno_t __cdecl _wcsset_s(wchar_t *_Str,size_t _SizeInWords,wchar_t _Val);
+ _CRTIMP errno_t __cdecl _wcslwr_s(wchar_t *_Str,size_t _SizeInWords);
+ _CRTIMP errno_t __cdecl _wcslwr_s_l(wchar_t *_Str,size_t _SizeInWords,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _wcsupr_s(wchar_t *_Str,size_t _Size);
+ _CRTIMP errno_t __cdecl _wcsupr_s_l(wchar_t *_Str,size_t _Size,_locale_t _Locale);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
diff --git a/win32/include/sec_api/sys/timeb_s.h b/win32/include/sec_api/sys/timeb_s.h
new file mode 100644
index 0000000..af5ef09
--- /dev/null
+++ b/win32/include/sec_api/sys/timeb_s.h
@@ -0,0 +1,34 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+
+#ifndef _TIMEB_H_S
+#define _TIMEB_H_S
+
+#include <sys/timeb.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef _USE_32BIT_TIME_T
+#define _ftime_s _ftime32_s
+#else
+#define _ftime_s _ftime64_s
+#endif
+
+ _CRTIMP errno_t __cdecl _ftime32_s(struct __timeb32 *_Time);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP errno_t __cdecl _ftime64_s(struct __timeb64 *_Time);
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/win32/include/sec_api/tchar_s.h b/win32/include/sec_api/tchar_s.h
new file mode 100644
index 0000000..343d348
--- /dev/null
+++ b/win32/include/sec_api/tchar_s.h
@@ -0,0 +1,266 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_TCHAR_S
+#define _INC_TCHAR_S
+
+#include <tchar.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _UNICODE
+
+#define _tprintf_s wprintf_s
+#define _tprintf_s_l _wprintf_s_l
+#define _tcprintf_s _cwprintf_s
+#define _tcprintf_s_l _cwprintf_s_l
+#define _vtcprintf_s _vcwprintf_s
+#define _vtcprintf_s_l _vcwprintf_s_l
+#define _ftprintf_s fwprintf_s
+#define _ftprintf_s_l _fwprintf_s_l
+#define _stprintf_s swprintf_s
+#define _stprintf_s_l _swprintf_s_l
+#define _sntprintf_s _snwprintf_s
+#define _sntprintf_s_l _snwprintf_s_l
+#define _vtprintf_s vwprintf_s
+#define _vtprintf_s_l _vwprintf_s_l
+#define _vftprintf_s vfwprintf_s
+#define _vftprintf_s_l _vfwprintf_s_l
+#define _vstprintf_s vswprintf_s
+#define _vstprintf_s_l _vswprintf_s_l
+#define _vsntprintf_s _vsnwprintf_s
+#define _vsntprintf_s_l _vsnwprintf_s_l
+
+#define _tscanf_s wscanf_s
+#define _tscanf_s_l _wscanf_s_l
+#define _tcscanf_s _cwscanf_s
+#define _tcscanf_s_l _cwscanf_s_l
+#define _ftscanf_s fwscanf_s
+#define _ftscanf_s_l _fwscanf_s_l
+#define _stscanf_s swscanf_s
+#define _stscanf_s_l _swscanf_s_l
+#define _sntscanf_s _snwscanf_s
+#define _sntscanf_s_l _snwscanf_s_l
+
+#define _cgetts_s _cgetws_s
+#define _getts_s _getws_s
+
+#define _itot_s _itow_s
+#define _ltot_s _ltow_s
+#define _ultot_s _ultow_s
+#define _i64tot_s _i64tow_s
+#define _ui64tot_s _ui64tow_s
+
+#define _tcscat_s wcscat_s
+#define _tcscpy_s wcscpy_s
+#define _tcsncat_s wcsncat_s
+#define _tcsncat_s_l _wcsncat_s_l
+#define _tcsncpy_s wcsncpy_s
+#define _tcsncpy_s_l _wcsncpy_s_l
+#define _tcstok_s wcstok_s
+#define _tcstok_s_l _wcstok_s_l
+#define _tcserror_s _wcserror_s
+#define __tcserror_s __wcserror_s
+
+#define _tcsnset_s _wcsnset_s
+#define _tcsnset_s_l _wcsnset_s_l
+#define _tcsset_s _wcsset_s
+#define _tcsset_s_l _wcsset_s_l
+
+#define _tasctime_s _wasctime_s
+#define _tctime_s _wctime_s
+#define _tctime32_s _wctime32_s
+#define _tctime64_s _wctime64_s
+#define _tstrdate_s _wstrdate_s
+#define _tstrtime_s _wstrtime_s
+
+#define _tgetenv_s _wgetenv_s
+#define _tdupenv_s _wdupenv_s
+#define _tmakepath_s _wmakepath_s
+#define _tputenv_s _wputenv_s
+#define _tsearchenv_s _wsearchenv_s
+#define _tsplitpath_s _wsplitpath_s
+
+#define _tfopen_s _wfopen_s
+#define _tfreopen_s _wfreopen_s
+#define _ttmpnam_s _wtmpnam_s
+#define _taccess_s _waccess_s
+#define _tmktemp_s _wmktemp_s
+
+#define _tcsnccat_s wcsncat_s
+#define _tcsnccat_s_l _wcsncat_s_l
+#define _tcsnccpy_s wcsncpy_s
+#define _tcsnccpy_s_l _wcsncpy_s_l
+
+#define _tcslwr_s _wcslwr_s
+#define _tcslwr_s_l _wcslwr_s_l
+#define _tcsupr_s _wcsupr_s
+#define _tcsupr_s_l _wcsupr_s_l
+
+#define _wcstok_s_l(_String,_Delimiters,_Current_position,_Locale) (wcstok_s(_String,_Delimiters,_Current_position))
+#define _wcsnset_s_l(_Destination,_Destination_size_chars,_Value,_Count,_Locale) (_wcsnset_s(_Destination,_Destination_size_chars,_Value,_Count))
+#define _wcsset_s_l(_Destination,_Destination_size_chars,_Value,_Locale) (_wcsset_s(_Destination,_Destination_size_chars,_Value))
+
+#else
+
+#define _tprintf_s printf_s
+#define _tprintf_s_l _printf_s_l
+#define _tcprintf_s _cprintf_s
+#define _tcprintf_s_l _cprintf_s_l
+#define _vtcprintf_s _vcprintf_s
+#define _vtcprintf_s_l _vcprintf_s_l
+#define _ftprintf_s fprintf_s
+#define _ftprintf_s_l _fprintf_s_l
+#define _stprintf_s sprintf_s
+#define _stprintf_s_l _sprintf_s_l
+#define _sntprintf_s _snprintf_s
+#define _sntprintf_s_l _snprintf_s_l
+#define _vtprintf_s vprintf_s
+#define _vtprintf_s_l _vprintf_s_l
+#define _vftprintf_s vfprintf_s
+#define _vftprintf_s_l _vfprintf_s_l
+#define _vstprintf_s vsprintf_s
+#define _vstprintf_s_l _vsprintf_s_l
+#define _vsntprintf_s _vsnprintf_s
+#define _vsntprintf_s_l _vsnprintf_s_l
+#define _tscanf_s scanf_s
+#define _tscanf_s_l _scanf_s_l
+#define _tcscanf_s _cscanf_s
+#define _tcscanf_s_l _cscanf_s_l
+#define _ftscanf_s fscanf_s
+#define _ftscanf_s_l _fscanf_s_l
+#define _stscanf_s sscanf_s
+#define _stscanf_s_l _sscanf_s_l
+#define _sntscanf_s _snscanf_s
+#define _sntscanf_s_l _snscanf_s_l
+
+#define _getts_s gets_s
+#define _cgetts_s _cgets_s
+#define _itot_s _itoa_s
+#define _ltot_s _ltoa_s
+#define _ultot_s _ultoa_s
+#define _i64tot_s _i64toa_s
+#define _ui64tot_s _ui64toa_s
+
+#define _tcscat_s strcat_s
+#define _tcscpy_s strcpy_s
+#define _tcserror_s strerror_s
+#define __tcserror_s _strerror_s
+
+#define _tasctime_s asctime_s
+#define _tctime_s ctime_s
+#define _tctime32_s _ctime32_s
+#define _tctime64_s _ctime64_s
+#define _tstrdate_s _strdate_s
+#define _tstrtime_s _strtime_s
+
+#define _tgetenv_s getenv_s
+#define _tdupenv_s _dupenv_s
+#define _tmakepath_s _makepath_s
+#define _tputenv_s _putenv_s
+#define _tsearchenv_s _searchenv_s
+#define _tsplitpath_s _splitpath_s
+
+#define _tfopen_s fopen_s
+#define _tfreopen_s freopen_s
+#define _ttmpnam_s tmpnam_s
+#define _tmktemp_s _mktemp_s
+
+#ifndef _POSIX_
+#define _taccess_s _access_s
+#endif
+
+#define _tsopen_s _sopen_s
+
+#ifdef _MBCS
+
+#ifdef _MB_MAP_DIRECT
+
+#define _tcsncat_s _mbsnbcat_s
+#define _tcsncat_s_l _mbsnbcat_s_l
+#define _tcsncpy_s _mbsnbcpy_s
+#define _tcsncpy_s_l _mbsnbcpy_s_l
+#define _tcstok_s _mbstok_s
+#define _tcstok_s_l _mbstok_s_l
+
+#define _tcsnset_s _mbsnbset_s
+#define _tcsnset_s_l _mbsnbset_s_l
+#define _tcsset_s _mbsset_s
+#define _tcsset_s_l _mbsset_s_l
+
+#define _tcsnccat_s _mbsncat_s
+#define _tcsnccat_s_l _mbsncat_s_l
+#define _tcsnccpy_s _mbsncpy_s
+#define _tcsnccpy_s_l _mbsncpy_s_l
+#define _tcsncset_s _mbsnset_s
+#define _tcsncset_s_l _mbsnset_s_l
+
+#define _tcslwr_s _mbslwr_s
+#define _tcslwr_s_l _mbslwr_s_l
+#define _tcsupr_s _mbsupr_s
+#define _tcsupr_s_l _mbsupr_s_l
+
+#define _tccpy_s _mbccpy_s
+#define _tccpy_s_l _mbccpy_s_l
+#else
+
+ _CRTIMP char *__cdecl _tcsncat_s(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount);
+ _CRTIMP char *__cdecl _tcsncat_s_l(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcsncpy_s(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount);
+ _CRTIMP char *__cdecl _tcsncpy_s_l(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcstok_s(char *_Str,const char *_Delim,char **_Context);
+ _CRTIMP char *__cdecl _tcstok_s_l(char *_Str,const char *_Delim,char **_Context,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _tcsset_s(char *_Str,size_t _SizeInChars,unsigned int _Val);
+ _CRTIMP errno_t __cdecl _tcsset_s_l(char *_Str,size_t _SizeInChars,unsigned int,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcsnccat_s(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount);
+ _CRTIMP char *__cdecl _tcsnccat_s_l(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcsnccpy_s(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount);
+ _CRTIMP char *__cdecl _tcsnccpy_s_l(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcslwr_s(char *_Str,size_t _SizeInChars);
+ _CRTIMP char *__cdecl _tcslwr_s_l(char *_Str,size_t _SizeInChars,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcsupr_s(char *_Str,size_t _SizeInChars);
+ _CRTIMP char *__cdecl _tcsupr_s_l(char *_Str,size_t _SizeInChars,_locale_t _Locale);
+
+#endif
+
+#else
+
+#define _tcsncat_s strncat_s
+#define _tcsncat_s_l _strncat_s_l
+#define _tcsncpy_s strncpy_s
+#define _tcsncpy_s_l _strncpy_s_l
+#define _tcstok_s strtok_s
+#define _tcstok_s_l _strtok_s_l
+
+#define _tcsnset_s _strnset_s
+#define _tcsnset_s_l _strnset_s_l
+#define _tcsset_s _strset_s
+#define _tcsset_s _strset_s
+#define _tcsset_s_l _strset_s_l
+
+#define _tcsnccat_s strncat_s
+#define _tcsnccat_s_l _strncat_s_l
+#define _tcsnccpy_s strncpy_s
+#define _tcsnccpy_s_l _strncpy_s_l
+
+#define _tcslwr_s _strlwr_s
+#define _tcslwr_s_l _strlwr_s_l
+#define _tcsupr_s _strupr_s
+#define _tcsupr_s_l _strupr_s_l
+
+#define _strnset_s_l(_Destination,_Destination_size_chars,_Value,_Count,_Locale) (_strnset_s(_Destination,_Destination_size_chars,_Value,_Count))
+#define _strset_s_l(_Destination,_Destination_size_chars,_Value,_Locale) (_strset_s(_Destination,_Destination_size_chars,_Value))
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
diff --git a/win32/include/sec_api/time_s.h b/win32/include/sec_api/time_s.h
new file mode 100644
index 0000000..9603b94
--- /dev/null
+++ b/win32/include/sec_api/time_s.h
@@ -0,0 +1,61 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _TIME_H__S
+#define _TIME_H__S
+
+#include <time.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ _CRTIMP errno_t __cdecl _ctime32_s(char *_Buf,size_t _SizeInBytes,const __time32_t *_Time);
+ _CRTIMP errno_t __cdecl _gmtime32_s(struct tm *_Tm,const __time32_t *_Time);
+ _CRTIMP errno_t __cdecl _localtime32_s(struct tm *_Tm,const __time32_t *_Time);
+ _CRTIMP errno_t __cdecl _strdate_s(char *_Buf,size_t _SizeInBytes);
+ _CRTIMP errno_t __cdecl _strtime_s(char *_Buf ,size_t _SizeInBytes);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP errno_t __cdecl _ctime64_s(char *_Buf,size_t _SizeInBytes,const __time64_t *_Time);
+ _CRTIMP errno_t __cdecl _gmtime64_s(struct tm *_Tm,const __time64_t *_Time);
+ _CRTIMP errno_t __cdecl _localtime64_s(struct tm *_Tm,const __time64_t *_Time);
+#endif
+
+#ifndef _WTIME_S_DEFINED
+#define _WTIME_S_DEFINED
+ _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm);
+ _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time);
+ _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords);
+ _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time);
+#endif
+
+#if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL)
+#define _INC_WTIME_S_INL
+#ifdef _USE_32BIT_TIME_T
+__CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime32_s(_Buffer,_SizeInWords,_Time); }
+#else
+__CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime64_s(_Buffer,_SizeInWords,_Time); }
+#endif
+#endif
+#endif
+
+#ifndef RC_INVOKED
+#ifdef _USE_32BIT_TIME_T
+__CRT_INLINE errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime32_s(_Tm,_Time); }
+#else
+__CRT_INLINE errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime64_s(_Tm,_Time); }
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+#endif
diff --git a/win32/include/sec_api/wchar_s.h b/win32/include/sec_api/wchar_s.h
new file mode 100644
index 0000000..94251aa
--- /dev/null
+++ b/win32/include/sec_api/wchar_s.h
@@ -0,0 +1,128 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_WCHAR_S
+#define _INC_WCHAR_S
+
+#include <wchar.h>
+
+#if defined(MINGW_HAS_SECURE_API)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _WIO_S_DEFINED
+#define _WIO_S_DEFINED
+ _CRTIMP errno_t __cdecl _waccess_s(const wchar_t *_Filename,int _AccessMode);
+ _CRTIMP errno_t __cdecl _wmktemp_s(wchar_t *_TemplateName,size_t _SizeInWords);
+#endif
+
+#ifndef _WCONIO_S_DEFINED
+#define _WCONIO_S_DEFINED
+ _CRTIMP errno_t __cdecl _cgetws_s(wchar_t *_Buffer,size_t _SizeInWords,size_t *_SizeRead);
+ _CRTIMP int __cdecl _cwprintf_s(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _cwscanf_s(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _cwscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcwprintf_s(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _cwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+#endif
+
+#ifndef _WSTDIO_S_DEFINED
+#define _WSTDIO_S_DEFINED
+ _CRTIMP wchar_t *__cdecl _getws_s(wchar_t *_Str,size_t _SizeInWords);
+ int __cdecl fwprintf_s(FILE *_File,const wchar_t *_Format,...);
+ int __cdecl wprintf_s(const wchar_t *_Format,...);
+ int __cdecl vfwprintf_s(FILE *_File,const wchar_t *_Format,va_list _ArgList);
+ int __cdecl vwprintf_s(const wchar_t *_Format,va_list _ArgList);
+ int __cdecl swprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,...);
+ int __cdecl vswprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _snwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vsnwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _wprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _fwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vfwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _swprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vswprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _snwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vsnwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _fwscanf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _swscanf_s_l(const wchar_t *_Src,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _snwscanf_s(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _snwscanf_s_l(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _wscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP errno_t __cdecl _wfopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode);
+ _CRTIMP errno_t __cdecl _wfreopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode,FILE *_OldFile);
+ _CRTIMP errno_t __cdecl _wtmpnam_s(wchar_t *_DstBuf,size_t _SizeInWords);
+#endif
+
+#ifndef _WSTDLIB_S_DEFINED
+#define _WSTDLIB_S_DEFINED
+ _CRTIMP errno_t __cdecl _itow_s (int _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
+ _CRTIMP errno_t __cdecl _ltow_s (long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
+ _CRTIMP errno_t __cdecl _ultow_s (unsigned long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
+ _CRTIMP errno_t __cdecl _wgetenv_s(size_t *_ReturnSize,wchar_t *_DstBuf,size_t _DstSizeInWords,const wchar_t *_VarName);
+ _CRTIMP errno_t __cdecl _wdupenv_s(wchar_t **_Buffer,size_t *_BufferSizeInWords,const wchar_t *_VarName);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP errno_t __cdecl _i64tow_s(__int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
+ _CRTIMP errno_t __cdecl _ui64tow_s(unsigned __int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
+#endif
+#endif
+
+#ifndef _POSIX_
+#ifndef _WSTDLIBP_S_DEFINED
+#define _WSTDLIBP_S_DEFINED
+ _CRTIMP errno_t __cdecl _wmakepath_s(wchar_t *_PathResult,size_t _SizeInWords,const wchar_t *_Drive,const wchar_t *_Dir,const wchar_t *_Filename,const wchar_t *_Ext);
+ _CRTIMP errno_t __cdecl _wputenv_s(const wchar_t *_Name,const wchar_t *_Value);
+ _CRTIMP errno_t __cdecl _wsearchenv_s(const wchar_t *_Filename,const wchar_t *_EnvVar,wchar_t *_ResultPath,size_t _SizeInWords);
+ _CRTIMP errno_t __cdecl _wsplitpath_s(const wchar_t *_FullPath,wchar_t *_Drive,size_t _DriveSizeInWords,wchar_t *_Dir,size_t _DirSizeInWords,wchar_t *_Filename,size_t _FilenameSizeInWords,wchar_t *_Ext,size_t _ExtSizeInWords);
+#endif
+#endif
+
+#ifndef _WSTRING_S_DEFINED
+#define _WSTRING_S_DEFINED
+ _CRTIMP wchar_t *__cdecl wcstok_s(wchar_t *_Str,const wchar_t *_Delim,wchar_t **_Context);
+ _CRTIMP errno_t __cdecl _wcserror_s(wchar_t *_Buf,size_t _SizeInWords,int _ErrNum);
+ _CRTIMP errno_t __cdecl __wcserror_s(wchar_t *_Buffer,size_t _SizeInWords,const wchar_t *_ErrMsg);
+ _CRTIMP errno_t __cdecl _wcsnset_s(wchar_t *_Dst,size_t _DstSizeInWords,wchar_t _Val,size_t _MaxCount);
+ _CRTIMP errno_t __cdecl _wcsset_s(wchar_t *_Str,size_t _SizeInWords,wchar_t _Val);
+ _CRTIMP errno_t __cdecl _wcslwr_s(wchar_t *_Str,size_t _SizeInWords);
+ _CRTIMP errno_t __cdecl _wcslwr_s_l(wchar_t *_Str,size_t _SizeInWords,_locale_t _Locale);
+ _CRTIMP errno_t __cdecl _wcsupr_s(wchar_t *_Str,size_t _Size);
+ _CRTIMP errno_t __cdecl _wcsupr_s_l(wchar_t *_Str,size_t _Size,_locale_t _Locale);
+#endif
+
+#ifndef _WTIME_S_DEFINED
+#define _WTIME_S_DEFINED
+ _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm);
+ _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time);
+ _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords);
+ _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time);
+#endif
+
+#if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL)
+#define _INC_WTIME_S_INL
+#ifdef _USE_32BIT_TIME_T
+__CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime32_s(_Buffer,_SizeInWords,_Time); }
+#else
+__CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime64_s(_Buffer,_SizeInWords,_Time); }
+#endif
+#endif
+#endif
+
+ _CRTIMP errno_t __cdecl mbsrtowcs_s(size_t *_Retval,wchar_t *_Dst,size_t _SizeInWords,const char **_PSrc,size_t _N,mbstate_t *_State);
+ _CRTIMP errno_t __cdecl wcrtomb_s(size_t *_Retval,char *_Dst,size_t _SizeInBytes,wchar_t _Ch,mbstate_t *_State);
+ _CRTIMP errno_t __cdecl wcsrtombs_s(size_t *_Retval,char *_Dst,size_t _SizeInBytes,const wchar_t **_Src,size_t _Size,mbstate_t *_State);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+#endif
diff --git a/win32/include/setjmp.h b/win32/include/setjmp.h
new file mode 100644
index 0000000..e4f142a
--- /dev/null
+++ b/win32/include/setjmp.h
@@ -0,0 +1,160 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_SETJMP
+#define _INC_SETJMP
+
+#include <_mingw.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (defined(_X86_) && !defined(__x86_64))
+
+#define _JBLEN 16
+#define _JBTYPE int
+
+ typedef struct __JUMP_BUFFER {
+ unsigned long Ebp;
+ unsigned long Ebx;
+ unsigned long Edi;
+ unsigned long Esi;
+ unsigned long Esp;
+ unsigned long Eip;
+ unsigned long Registration;
+ unsigned long TryLevel;
+ unsigned long Cookie;
+ unsigned long UnwindFunc;
+ unsigned long UnwindData[6];
+ } _JUMP_BUFFER;
+#elif defined(__ia64__)
+ typedef _CRT_ALIGN(16) struct _SETJMP_FLOAT128 {
+ __int64 LowPart;
+ __int64 HighPart;
+ } SETJMP_FLOAT128;
+
+#define _JBLEN 33
+ typedef SETJMP_FLOAT128 _JBTYPE;
+
+ typedef struct __JUMP_BUFFER {
+
+ unsigned long iAReserved[6];
+
+ unsigned long Registration;
+ unsigned long TryLevel;
+ unsigned long Cookie;
+ unsigned long UnwindFunc;
+
+ unsigned long UnwindData[6];
+
+ SETJMP_FLOAT128 FltS0;
+ SETJMP_FLOAT128 FltS1;
+ SETJMP_FLOAT128 FltS2;
+ SETJMP_FLOAT128 FltS3;
+ SETJMP_FLOAT128 FltS4;
+ SETJMP_FLOAT128 FltS5;
+ SETJMP_FLOAT128 FltS6;
+ SETJMP_FLOAT128 FltS7;
+ SETJMP_FLOAT128 FltS8;
+ SETJMP_FLOAT128 FltS9;
+ SETJMP_FLOAT128 FltS10;
+ SETJMP_FLOAT128 FltS11;
+ SETJMP_FLOAT128 FltS12;
+ SETJMP_FLOAT128 FltS13;
+ SETJMP_FLOAT128 FltS14;
+ SETJMP_FLOAT128 FltS15;
+ SETJMP_FLOAT128 FltS16;
+ SETJMP_FLOAT128 FltS17;
+ SETJMP_FLOAT128 FltS18;
+ SETJMP_FLOAT128 FltS19;
+ __int64 FPSR;
+ __int64 StIIP;
+ __int64 BrS0;
+ __int64 BrS1;
+ __int64 BrS2;
+ __int64 BrS3;
+ __int64 BrS4;
+ __int64 IntS0;
+ __int64 IntS1;
+ __int64 IntS2;
+ __int64 IntS3;
+ __int64 RsBSP;
+ __int64 RsPFS;
+ __int64 ApUNAT;
+ __int64 ApLC;
+ __int64 IntSp;
+ __int64 IntNats;
+ __int64 Preds;
+
+ } _JUMP_BUFFER;
+#elif defined(__x86_64)
+ typedef _CRT_ALIGN(16) struct _SETJMP_FLOAT128 {
+ unsigned __int64 Part[2];
+ } SETJMP_FLOAT128;
+
+#define _JBLEN 16
+ typedef SETJMP_FLOAT128 _JBTYPE;
+
+ typedef struct _JUMP_BUFFER {
+ unsigned __int64 Frame;
+ unsigned __int64 Rbx;
+ unsigned __int64 Rsp;
+ unsigned __int64 Rbp;
+ unsigned __int64 Rsi;
+ unsigned __int64 Rdi;
+ unsigned __int64 R12;
+ unsigned __int64 R13;
+ unsigned __int64 R14;
+ unsigned __int64 R15;
+ unsigned __int64 Rip;
+ unsigned __int64 Spare;
+ SETJMP_FLOAT128 Xmm6;
+ SETJMP_FLOAT128 Xmm7;
+ SETJMP_FLOAT128 Xmm8;
+ SETJMP_FLOAT128 Xmm9;
+ SETJMP_FLOAT128 Xmm10;
+ SETJMP_FLOAT128 Xmm11;
+ SETJMP_FLOAT128 Xmm12;
+ SETJMP_FLOAT128 Xmm13;
+ SETJMP_FLOAT128 Xmm14;
+ SETJMP_FLOAT128 Xmm15;
+ } _JUMP_BUFFER;
+#endif
+#ifndef _JMP_BUF_DEFINED
+ typedef _JBTYPE jmp_buf[_JBLEN];
+#define _JMP_BUF_DEFINED
+#endif
+
+ void * __cdecl __attribute__ ((__nothrow__)) mingw_getsp(void);
+
+#ifdef USE_MINGW_SETJMP_TWO_ARGS
+#ifndef _INC_SETJMPEX
+#define setjmp(BUF) _setjmp((BUF),mingw_getsp())
+ int __cdecl __attribute__ ((__nothrow__)) _setjmp(jmp_buf _Buf,void *_Ctx);
+#else
+#undef setjmp
+#define setjmp(BUF) _setjmpex((BUF),mingw_getsp())
+#define setjmpex(BUF) _setjmpex((BUF),mingw_getsp())
+ int __cdecl __attribute__ ((__nothrow__)) _setjmpex(jmp_buf _Buf,void *_Ctx);
+#endif
+#else
+#ifndef _INC_SETJMPEX
+#define setjmp _setjmp
+#endif
+ int __cdecl __attribute__ ((__nothrow__)) setjmp(jmp_buf _Buf);
+#endif
+
+ __declspec(noreturn) __attribute__ ((__nothrow__)) void __cdecl ms_longjmp(jmp_buf _Buf,int _Value)/* throw(...)*/;
+ __declspec(noreturn) __attribute__ ((__nothrow__)) void __cdecl longjmp(jmp_buf _Buf,int _Value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+#endif
diff --git a/win32/include/share.h b/win32/include/share.h
new file mode 100644
index 0000000..358855f
--- /dev/null
+++ b/win32/include/share.h
@@ -0,0 +1,28 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_SHARE
+#define _INC_SHARE
+
+#ifndef _WIN32
+#error Only Win32 target is supported!
+#endif
+
+#define _SH_COMPAT 0x00
+#define _SH_DENYRW 0x10
+#define _SH_DENYWR 0x20
+#define _SH_DENYRD 0x30
+#define _SH_DENYNO 0x40
+#define _SH_SECURE 0x80
+
+#ifndef NO_OLDNAMES
+#define SH_COMPAT _SH_COMPAT
+#define SH_DENYRW _SH_DENYRW
+#define SH_DENYWR _SH_DENYWR
+#define SH_DENYRD _SH_DENYRD
+#define SH_DENYNO _SH_DENYNO
+#endif
+
+#endif
diff --git a/win32/include/signal.h b/win32/include/signal.h
new file mode 100644
index 0000000..a518f6b
--- /dev/null
+++ b/win32/include/signal.h
@@ -0,0 +1,63 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_SIGNAL
+#define _INC_SIGNAL
+
+#include <_mingw.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _SIG_ATOMIC_T_DEFINED
+#define _SIG_ATOMIC_T_DEFINED
+ typedef int sig_atomic_t;
+#endif
+
+#define NSIG 23
+
+#define SIGHUP 1 /* hangup */
+#define SIGINT 2
+#define SIGQUIT 3 /* quit */
+#define SIGILL 4
+#define SIGTRAP 5 /* trace trap (not reset when caught) */
+#define SIGIOT 6 /* IOT instruction */
+#define SIGABRT 6 /* used by abort, replace SIGIOT in the future */
+#define SIGEMT 7 /* EMT instruction */
+#define SIGFPE 8
+#define SIGKILL 9 /* kill (cannot be caught or ignored) */
+#define SIGBUS 10 /* bus error */
+#define SIGSEGV 11
+#define SIGSYS 12 /* bad argument to system call */
+#define SIGPIPE 13 /* write on a pipe with no one to read it */
+#ifdef __USE_MINGW_ALARM
+#define SIGALRM 14 /* alarm clock */
+#endif
+#define SIGTERM 15
+#define SIGBREAK 21
+#define SIGABRT2 22
+
+#define SIGABRT_COMPAT 6
+
+ typedef void (*__p_sig_fn_t)(int);
+
+#define SIG_DFL (__p_sig_fn_t)0
+#define SIG_IGN (__p_sig_fn_t)1
+#define SIG_GET (__p_sig_fn_t)2
+#define SIG_SGE (__p_sig_fn_t)3
+#define SIG_ACK (__p_sig_fn_t)4
+#define SIG_ERR (__p_sig_fn_t)-1
+
+ extern void **__cdecl __pxcptinfoptrs(void);
+#define _pxcptinfoptrs (*__pxcptinfoptrs())
+
+ __p_sig_fn_t __cdecl signal(int _SigNum,__p_sig_fn_t _Func);
+ int __cdecl raise(int _SigNum);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/include/stdint.h b/win32/include/stdint.h
new file mode 100644
index 0000000..cde32b6
--- /dev/null
+++ b/win32/include/stdint.h
@@ -0,0 +1,212 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+/* ISO C9x 7.18 Integer types <stdint.h>
+ * Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794)
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * Contributor: Danny Smith <danny_r_smith_2001@yahoo.co.nz>
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Date: 2000-12-02
+ */
+
+
+#ifndef _STDINT_H
+#define _STDINT_H
+
+#include <_mingw.h>
+
+#define __need_wint_t
+#define __need_wchar_t
+#include "stddef.h"
+
+#ifndef __int8_t_defined
+#define __int8_t_defined
+/* 7.18.1.1 Exact-width integer types */
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned uint32_t;
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#endif
+
+/* 7.18.1.2 Minimum-width integer types */
+typedef signed char int_least8_t;
+typedef unsigned char uint_least8_t;
+typedef short int_least16_t;
+typedef unsigned short uint_least16_t;
+typedef int int_least32_t;
+typedef unsigned uint_least32_t;
+typedef long long int_least64_t;
+typedef unsigned long long uint_least64_t;
+
+/* 7.18.1.3 Fastest minimum-width integer types
+ * Not actually guaranteed to be fastest for all purposes
+ * Here we use the exact-width types for 8 and 16-bit ints.
+ */
+typedef char int_fast8_t;
+typedef unsigned char uint_fast8_t;
+typedef short int_fast16_t;
+typedef unsigned short uint_fast16_t;
+typedef int int_fast32_t;
+typedef unsigned int uint_fast32_t;
+typedef long long int_fast64_t;
+typedef unsigned long long uint_fast64_t;
+
+/* 7.18.1.5 Greatest-width integer types */
+typedef long long intmax_t;
+typedef unsigned long long uintmax_t;
+
+/* 7.18.2 Limits of specified-width integer types */
+#if !defined ( __cplusplus) || defined (__STDC_LIMIT_MACROS)
+
+/* 7.18.2.1 Limits of exact-width integer types */
+#define INT8_MIN (-128)
+#define INT16_MIN (-32768)
+#define INT32_MIN (-2147483647 - 1)
+#define INT64_MIN (-9223372036854775807LL - 1)
+
+#define INT8_MAX 127
+#define INT16_MAX 32767
+#define INT32_MAX 2147483647
+#define INT64_MAX 9223372036854775807LL
+
+#define UINT8_MAX 0xff /* 255U */
+#define UINT16_MAX 0xffff /* 65535U */
+#define UINT32_MAX 0xffffffff /* 4294967295U */
+#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
+
+/* 7.18.2.2 Limits of minimum-width integer types */
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST64_MIN INT64_MIN
+
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MAX INT64_MAX
+
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+/* 7.18.2.3 Limits of fastest minimum-width integer types */
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST64_MIN INT64_MIN
+
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MAX INT64_MAX
+
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+/* 7.18.2.4 Limits of integer types capable of holding
+ object pointers */
+#ifdef _WIN64
+#define INTPTR_MIN INT64_MIN
+#define INTPTR_MAX INT64_MAX
+#define UINTPTR_MAX UINT64_MAX
+#else
+#define INTPTR_MIN INT32_MIN
+#define INTPTR_MAX INT32_MAX
+#define UINTPTR_MAX UINT32_MAX
+#endif
+
+/* 7.18.2.5 Limits of greatest-width integer types */
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+/* 7.18.3 Limits of other integer types */
+#ifdef _WIN64
+#define PTRDIFF_MIN INT64_MIN
+#define PTRDIFF_MAX INT64_MAX
+#else
+#define PTRDIFF_MIN INT32_MIN
+#define PTRDIFF_MAX INT32_MAX
+#endif
+
+#define SIG_ATOMIC_MIN INT32_MIN
+#define SIG_ATOMIC_MAX INT32_MAX
+
+#ifndef SIZE_MAX
+#ifdef _WIN64
+#define SIZE_MAX UINT64_MAX
+#else
+#define SIZE_MAX UINT32_MAX
+#endif
+#endif
+
+#ifndef WCHAR_MIN /* also in wchar.h */
+#define WCHAR_MIN 0
+#define WCHAR_MAX ((wchar_t)-1) /* UINT16_MAX */
+#endif
+
+/*
+ * wint_t is unsigned short for compatibility with MS runtime
+ */
+#define WINT_MIN 0
+#define WINT_MAX ((wint_t)-1) /* UINT16_MAX */
+
+#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */
+
+
+/* 7.18.4 Macros for integer constants */
+#if !defined ( __cplusplus) || defined (__STDC_CONSTANT_MACROS)
+
+/* 7.18.4.1 Macros for minimum-width integer constants
+
+ According to Douglas Gwyn <gwyn@arl.mil>:
+ "This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
+ 9899:1999 as initially published, the expansion was required
+ to be an integer constant of precisely matching type, which
+ is impossible to accomplish for the shorter types on most
+ platforms, because C99 provides no standard way to designate
+ an integer constant with width less than that of type int.
+ TC1 changed this to require just an integer constant
+ *expression* with *promoted* type."
+
+ The trick used here is from Clive D W Feather.
+*/
+
+#define INT8_C(val) (INT_LEAST8_MAX-INT_LEAST8_MAX+(val))
+#define INT16_C(val) (INT_LEAST16_MAX-INT_LEAST16_MAX+(val))
+#define INT32_C(val) (INT_LEAST32_MAX-INT_LEAST32_MAX+(val))
+/* The 'trick' doesn't work in C89 for long long because, without
+ suffix, (val) will be evaluated as int, not intmax_t */
+#define INT64_C(val) val##LL
+
+#define UINT8_C(val) (UINT_LEAST8_MAX-UINT_LEAST8_MAX+(val))
+#define UINT16_C(val) (UINT_LEAST16_MAX-UINT_LEAST16_MAX+(val))
+#define UINT32_C(val) (UINT_LEAST32_MAX-UINT_LEAST32_MAX+(val))
+#define UINT64_C(val) val##ULL
+
+/* 7.18.4.2 Macros for greatest-width integer constants */
+#define INTMAX_C(val) val##LL
+#define UINTMAX_C(val) val##ULL
+
+#endif /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */
+
+#endif
diff --git a/win32/include/stdio.h b/win32/include/stdio.h
new file mode 100644
index 0000000..da88793
--- /dev/null
+++ b/win32/include/stdio.h
@@ -0,0 +1,429 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_STDIO
+#define _INC_STDIO
+
+#include <_mingw.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BUFSIZ 512
+#define _NFILE _NSTREAM_
+#define _NSTREAM_ 512
+#define _IOB_ENTRIES 20
+#define EOF (-1)
+
+#ifndef _FILE_DEFINED
+ struct _iobuf {
+ char *_ptr;
+ int _cnt;
+ char *_base;
+ int _flag;
+ int _file;
+ int _charbuf;
+ int _bufsiz;
+ char *_tmpfname;
+ };
+ typedef struct _iobuf FILE;
+#define _FILE_DEFINED
+#endif
+
+#ifdef _POSIX_
+#define _P_tmpdir "/"
+#define _wP_tmpdir L"/"
+#else
+#define _P_tmpdir "\\"
+#define _wP_tmpdir L"\\"
+#endif
+
+#define L_tmpnam (sizeof(_P_tmpdir) + 12)
+
+#ifdef _POSIX_
+#define L_ctermid 9
+#define L_cuserid 32
+#endif
+
+#define SEEK_CUR 1
+#define SEEK_END 2
+#define SEEK_SET 0
+
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#define FILENAME_MAX 260
+#define FOPEN_MAX 20
+#define _SYS_OPEN 20
+#define TMP_MAX 32767
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#ifndef _OFF_T_DEFINED
+#define _OFF_T_DEFINED
+#ifndef _OFF_T_
+#define _OFF_T_
+ typedef long _off_t;
+#if !defined(NO_OLDNAMES) || defined(_POSIX)
+ typedef long off_t;
+#endif
+#endif
+#endif
+
+#ifndef _OFF64_T_DEFINED
+#define _OFF64_T_DEFINED
+ typedef long long _off64_t;
+#if !defined(NO_OLDNAMES) || defined(_POSIX)
+ typedef long long off64_t;
+#endif
+#endif
+
+#ifndef _STDIO_DEFINED
+#ifdef _WIN64
+ _CRTIMP FILE *__cdecl __iob_func(void);
+#else
+#ifdef _MSVCRT_
+extern FILE _iob[]; /* A pointer to an array of FILE */
+#define __iob_func() (_iob)
+#else
+extern FILE (*_imp___iob)[]; /* A pointer to an array of FILE */
+#define __iob_func() (*_imp___iob)
+#define _iob __iob_func()
+#endif
+#endif
+#endif
+
+#ifndef _FPOS_T_DEFINED
+#define _FPOS_T_DEFINED
+#undef _FPOSOFF
+
+#if (!defined(NO_OLDNAMES) || defined(__GNUC__)) && _INTEGRAL_MAX_BITS >= 64
+ typedef __int64 fpos_t;
+#define _FPOSOFF(fp) ((long)(fp))
+#else
+ typedef long long fpos_t;
+#define _FPOSOFF(fp) ((long)(fp))
+#endif
+
+#endif
+
+#ifndef _STDSTREAM_DEFINED
+#define _STDSTREAM_DEFINED
+
+#define stdin (&__iob_func()[0])
+#define stdout (&__iob_func()[1])
+#define stderr (&__iob_func()[2])
+#endif
+
+#define _IOREAD 0x0001
+#define _IOWRT 0x0002
+
+#define _IOFBF 0x0000
+#define _IOLBF 0x0040
+#define _IONBF 0x0004
+
+#define _IOMYBUF 0x0008
+#define _IOEOF 0x0010
+#define _IOERR 0x0020
+#define _IOSTRG 0x0040
+#define _IORW 0x0080
+#ifdef _POSIX_
+#define _IOAPPEND 0x0200
+#endif
+
+#define _TWO_DIGIT_EXPONENT 0x1
+
+#ifndef _STDIO_DEFINED
+
+ _CRTIMP int __cdecl _filbuf(FILE *_File);
+ _CRTIMP int __cdecl _flsbuf(int _Ch,FILE *_File);
+#ifdef _POSIX_
+ _CRTIMP FILE *__cdecl _fsopen(const char *_Filename,const char *_Mode);
+#else
+ _CRTIMP FILE *__cdecl _fsopen(const char *_Filename,const char *_Mode,int _ShFlag);
+#endif
+ void __cdecl clearerr(FILE *_File);
+ int __cdecl fclose(FILE *_File);
+ _CRTIMP int __cdecl _fcloseall(void);
+#ifdef _POSIX_
+ FILE *__cdecl fdopen(int _FileHandle,const char *_Mode);
+#else
+ _CRTIMP FILE *__cdecl _fdopen(int _FileHandle,const char *_Mode);
+#endif
+ int __cdecl feof(FILE *_File);
+ int __cdecl ferror(FILE *_File);
+ int __cdecl fflush(FILE *_File);
+ int __cdecl fgetc(FILE *_File);
+ _CRTIMP int __cdecl _fgetchar(void);
+ int __cdecl fgetpos(FILE *_File ,fpos_t *_Pos);
+ char *__cdecl fgets(char *_Buf,int _MaxCount,FILE *_File);
+#ifdef _POSIX_
+ int __cdecl fileno(FILE *_File);
+#else
+ _CRTIMP int __cdecl _fileno(FILE *_File);
+#endif
+ _CRTIMP char *__cdecl _tempnam(const char *_DirName,const char *_FilePrefix);
+ _CRTIMP int __cdecl _flushall(void);
+ FILE *__cdecl fopen(const char *_Filename,const char *_Mode);
+ FILE *fopen64(const char *filename,const char *mode);
+ int __cdecl fprintf(FILE *_File,const char *_Format,...);
+ int __cdecl fputc(int _Ch,FILE *_File);
+ _CRTIMP int __cdecl _fputchar(int _Ch);
+ int __cdecl fputs(const char *_Str,FILE *_File);
+ size_t __cdecl fread(void *_DstBuf,size_t _ElementSize,size_t _Count,FILE *_File);
+ FILE *__cdecl freopen(const char *_Filename,const char *_Mode,FILE *_File);
+ int __cdecl fscanf(FILE *_File,const char *_Format,...);
+ int __cdecl fsetpos(FILE *_File,const fpos_t *_Pos);
+ int __cdecl fseek(FILE *_File,long _Offset,int _Origin);
+ int fseeko64(FILE* stream, _off64_t offset, int whence);
+ long __cdecl ftell(FILE *_File);
+ _off64_t ftello64(FILE * stream);
+ int __cdecl _fseeki64(FILE *_File,__int64 _Offset,int _Origin);
+ __int64 __cdecl _ftelli64(FILE *_File);
+ size_t __cdecl fwrite(const void *_Str,size_t _Size,size_t _Count,FILE *_File);
+ int __cdecl getc(FILE *_File);
+ int __cdecl getchar(void);
+ _CRTIMP int __cdecl _getmaxstdio(void);
+ char *__cdecl gets(char *_Buffer);
+ int __cdecl _getw(FILE *_File);
+#ifndef _CRT_PERROR_DEFINED
+#define _CRT_PERROR_DEFINED
+ void __cdecl perror(const char *_ErrMsg);
+#endif
+ _CRTIMP int __cdecl _pclose(FILE *_File);
+ _CRTIMP FILE *__cdecl _popen(const char *_Command,const char *_Mode);
+#if !defined(NO_OLDNAMES) && !defined(popen)
+#define popen _popen
+#define pclose _pclose
+#endif
+ int __cdecl printf(const char *_Format,...);
+ int __cdecl putc(int _Ch,FILE *_File);
+ int __cdecl putchar(int _Ch);
+ int __cdecl puts(const char *_Str);
+ _CRTIMP int __cdecl _putw(int _Word,FILE *_File);
+#ifndef _CRT_DIRECTORY_DEFINED
+#define _CRT_DIRECTORY_DEFINED
+ int __cdecl remove(const char *_Filename);
+ int __cdecl rename(const char *_OldFilename,const char *_NewFilename);
+ _CRTIMP int __cdecl _unlink(const char *_Filename);
+#ifndef NO_OLDNAMES
+ int __cdecl unlink(const char *_Filename);
+#endif
+#endif
+ void __cdecl rewind(FILE *_File);
+ _CRTIMP int __cdecl _rmtmp(void);
+ int __cdecl scanf(const char *_Format,...);
+ void __cdecl setbuf(FILE *_File,char *_Buffer);
+ _CRTIMP int __cdecl _setmaxstdio(int _Max);
+ _CRTIMP unsigned int __cdecl _set_output_format(unsigned int _Format);
+ _CRTIMP unsigned int __cdecl _get_output_format(void);
+ int __cdecl setvbuf(FILE *_File,char *_Buf,int _Mode,size_t _Size);
+ _CRTIMP int __cdecl _scprintf(const char *_Format,...);
+ int __cdecl sscanf(const char *_Src,const char *_Format,...);
+ _CRTIMP int __cdecl _snscanf(const char *_Src,size_t _MaxCount,const char *_Format,...);
+ FILE *__cdecl tmpfile(void);
+ char *__cdecl tmpnam(char *_Buffer);
+ int __cdecl ungetc(int _Ch,FILE *_File);
+ int __cdecl vfprintf(FILE *_File,const char *_Format,va_list _ArgList);
+ int __cdecl vprintf(const char *_Format,va_list _ArgList);
+ /* Make sure macros are not defined. */
+#pragma push_macro("vsnprintf")
+#pragma push_macro("snprintf")
+# undef vsnprintf
+# undef snprintf
+ extern
+ __attribute__((format(gnu_printf, 3, 0))) __attribute__((nonnull (3)))
+ int __mingw_vsnprintf(char *_DstBuf,size_t _MaxCount,const char *_Format,va_list _ArgList);
+ extern
+ __attribute__((format(gnu_printf, 3, 4))) __attribute__((nonnull (3)))
+ int __mingw_snprintf(char* s, size_t n, const char* format, ...);
+ int __cdecl vsnprintf(char *_DstBuf,size_t _MaxCount,const char *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _snprintf(char *_Dest,size_t _Count,const char *_Format,...);
+ _CRTIMP int __cdecl _vsnprintf(char *_Dest,size_t _Count,const char *_Format,va_list _Args);
+ int __cdecl sprintf(char *_Dest,const char *_Format,...);
+ int __cdecl vsprintf(char *_Dest,const char *_Format,va_list _Args);
+#ifndef __NO_ISOCEXT /* externs in libmingwex.a */
+ int __cdecl snprintf(char* s, size_t n, const char* format, ...);
+ __CRT_INLINE int __cdecl vsnprintf (char* s, size_t n, const char* format,va_list arg) {
+ return _vsnprintf ( s, n, format, arg);
+ }
+ int __cdecl vscanf(const char * Format, va_list argp);
+ int __cdecl vfscanf (FILE * fp, const char * Format,va_list argp);
+ int __cdecl vsscanf (const char * _Str,const char * Format,va_list argp);
+#endif
+/* Restore may prior defined macros snprintf/vsnprintf. */
+#pragma pop_macro("snprintf")
+#pragma pop_macro("vsnprintf")
+/* Check if vsnprintf and snprintf are defaulting to gnu-style. */
+# if defined(USE_MINGW_GNU_SNPRINTF) && USE_MINGW_GNU_SNPRINTF
+# ifndef vsnprint
+# define vsnprintf __mingw_vsnprintf
+# endif
+# ifndef snprintf
+# define snprintf __mingw_snprintf
+# endif
+# endif
+ _CRTIMP int __cdecl _vscprintf(const char *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _set_printf_count_output(int _Value);
+ _CRTIMP int __cdecl _get_printf_count_output(void);
+
+#ifndef _WSTDIO_DEFINED
+
+#ifndef WEOF
+#define WEOF (wint_t)(0xFFFF)
+#endif
+
+#ifdef _POSIX_
+ _CRTIMP FILE *__cdecl _wfsopen(const wchar_t *_Filename,const wchar_t *_Mode);
+#else
+ _CRTIMP FILE *__cdecl _wfsopen(const wchar_t *_Filename,const wchar_t *_Mode,int _ShFlag);
+#endif
+ wint_t __cdecl fgetwc(FILE *_File);
+ _CRTIMP wint_t __cdecl _fgetwchar(void);
+ wint_t __cdecl fputwc(wchar_t _Ch,FILE *_File);
+ _CRTIMP wint_t __cdecl _fputwchar(wchar_t _Ch);
+ wint_t __cdecl getwc(FILE *_File);
+ wint_t __cdecl getwchar(void);
+ wint_t __cdecl putwc(wchar_t _Ch,FILE *_File);
+ wint_t __cdecl putwchar(wchar_t _Ch);
+ wint_t __cdecl ungetwc(wint_t _Ch,FILE *_File);
+ wchar_t *__cdecl fgetws(wchar_t *_Dst,int _SizeInWords,FILE *_File);
+ int __cdecl fputws(const wchar_t *_Str,FILE *_File);
+ _CRTIMP wchar_t *__cdecl _getws(wchar_t *_String);
+ _CRTIMP int __cdecl _putws(const wchar_t *_Str);
+ int __cdecl fwprintf(FILE *_File,const wchar_t *_Format,...);
+ int __cdecl wprintf(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _scwprintf(const wchar_t *_Format,...);
+ int __cdecl vfwprintf(FILE *_File,const wchar_t *_Format,va_list _ArgList);
+ int __cdecl vwprintf(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl swprintf(wchar_t*, const wchar_t*, ...);
+ _CRTIMP int __cdecl vswprintf(wchar_t*, const wchar_t*,va_list);
+ _CRTIMP int __cdecl _swprintf_c(wchar_t *_DstBuf,size_t _SizeInWords,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vswprintf_c(wchar_t *_DstBuf,size_t _SizeInWords,const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _snwprintf(wchar_t *_Dest,size_t _Count,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vsnwprintf(wchar_t *_Dest,size_t _Count,const wchar_t *_Format,va_list _Args);
+#ifndef __NO_ISOCEXT /* externs in libmingwex.a */
+ int __cdecl snwprintf (wchar_t* s, size_t n, const wchar_t* format, ...);
+ __CRT_INLINE int __cdecl vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, va_list arg) { return _vsnwprintf(s,n,format,arg); }
+ int __cdecl vwscanf (const wchar_t *, va_list);
+ int __cdecl vfwscanf (FILE *,const wchar_t *,va_list);
+ int __cdecl vswscanf (const wchar_t *,const wchar_t *,va_list);
+#endif
+ _CRTIMP int __cdecl _swprintf(wchar_t *_Dest,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vswprintf(wchar_t *_Dest,const wchar_t *_Format,va_list _Args);
+
+#ifndef RC_INVOKED
+#include <vadefs.h>
+#endif
+
+#ifdef _CRT_NON_CONFORMING_SWPRINTFS
+#ifndef __cplusplus
+#define swprintf _swprintf
+#define vswprintf _vswprintf
+#define _swprintf_l __swprintf_l
+#define _vswprintf_l __vswprintf_l
+#endif
+#endif
+
+ _CRTIMP wchar_t *__cdecl _wtempnam(const wchar_t *_Directory,const wchar_t *_FilePrefix);
+ _CRTIMP int __cdecl _vscwprintf(const wchar_t *_Format,va_list _ArgList);
+ int __cdecl fwscanf(FILE *_File,const wchar_t *_Format,...);
+ int __cdecl swscanf(const wchar_t *_Src,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _snwscanf(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,...);
+ int __cdecl wscanf(const wchar_t *_Format,...);
+ _CRTIMP FILE *__cdecl _wfdopen(int _FileHandle ,const wchar_t *_Mode);
+ _CRTIMP FILE *__cdecl _wfopen(const wchar_t *_Filename,const wchar_t *_Mode);
+ _CRTIMP FILE *__cdecl _wfreopen(const wchar_t *_Filename,const wchar_t *_Mode,FILE *_OldFile);
+#ifndef _CRT_WPERROR_DEFINED
+#define _CRT_WPERROR_DEFINED
+ _CRTIMP void __cdecl _wperror(const wchar_t *_ErrMsg);
+#endif
+ _CRTIMP FILE *__cdecl _wpopen(const wchar_t *_Command,const wchar_t *_Mode);
+#if !defined(NO_OLDNAMES) && !defined(wpopen)
+#define wpopen _wpopen
+#endif
+ _CRTIMP int __cdecl _wremove(const wchar_t *_Filename);
+ _CRTIMP wchar_t *__cdecl _wtmpnam(wchar_t *_Buffer);
+ _CRTIMP wint_t __cdecl _fgetwc_nolock(FILE *_File);
+ _CRTIMP wint_t __cdecl _fputwc_nolock(wchar_t _Ch,FILE *_File);
+ _CRTIMP wint_t __cdecl _ungetwc_nolock(wint_t _Ch,FILE *_File);
+
+#undef _CRT_GETPUTWCHAR_NOINLINE
+
+#if !defined(__cplusplus) || defined(_CRT_GETPUTWCHAR_NOINLINE)
+#define getwchar() fgetwc(stdin)
+#define putwchar(_c) fputwc((_c),stdout)
+#else
+ __CRT_INLINE wint_t __cdecl getwchar() { return (fgetwc(stdin)); }
+ __CRT_INLINE wint_t __cdecl putwchar(wchar_t _C) { return (fputwc(_C,stdout)); }
+#endif
+
+#define getwc(_stm) fgetwc(_stm)
+#define putwc(_c,_stm) fputwc(_c,_stm)
+#define _putwc_nolock(_c,_stm) _fputwc_nolock(_c,_stm)
+#define _getwc_nolock(_stm) _fgetwc_nolock(_stm)
+
+#define _WSTDIO_DEFINED
+#endif
+
+#define _STDIO_DEFINED
+#endif
+
+#define _fgetc_nolock(_stream) (--(_stream)->_cnt >= 0 ? 0xff & *(_stream)->_ptr++ : _filbuf(_stream))
+#define _fputc_nolock(_c,_stream) (--(_stream)->_cnt >= 0 ? 0xff & (*(_stream)->_ptr++ = (char)(_c)) : _flsbuf((_c),(_stream)))
+#define _getc_nolock(_stream) _fgetc_nolock(_stream)
+#define _putc_nolock(_c,_stream) _fputc_nolock(_c,_stream)
+#define _getchar_nolock() _getc_nolock(stdin)
+#define _putchar_nolock(_c) _putc_nolock((_c),stdout)
+#define _getwchar_nolock() _getwc_nolock(stdin)
+#define _putwchar_nolock(_c) _putwc_nolock((_c),stdout)
+
+ _CRTIMP void __cdecl _lock_file(FILE *_File);
+ _CRTIMP void __cdecl _unlock_file(FILE *_File);
+ _CRTIMP int __cdecl _fclose_nolock(FILE *_File);
+ _CRTIMP int __cdecl _fflush_nolock(FILE *_File);
+ _CRTIMP size_t __cdecl _fread_nolock(void *_DstBuf,size_t _ElementSize,size_t _Count,FILE *_File);
+ _CRTIMP int __cdecl _fseek_nolock(FILE *_File,long _Offset,int _Origin);
+ _CRTIMP long __cdecl _ftell_nolock(FILE *_File);
+ _CRTIMP int __cdecl _fseeki64_nolock(FILE *_File,__int64 _Offset,int _Origin);
+ _CRTIMP __int64 __cdecl _ftelli64_nolock(FILE *_File);
+ _CRTIMP size_t __cdecl _fwrite_nolock(const void *_DstBuf,size_t _Size,size_t _Count,FILE *_File);
+ _CRTIMP int __cdecl _ungetc_nolock(int _Ch,FILE *_File);
+
+#if !defined(NO_OLDNAMES) || !defined(_POSIX)
+#define P_tmpdir _P_tmpdir
+#define SYS_OPEN _SYS_OPEN
+
+ char *__cdecl tempnam(const char *_Directory,const char *_FilePrefix);
+ int __cdecl fcloseall(void);
+ FILE *__cdecl fdopen(int _FileHandle,const char *_Format);
+ int __cdecl fgetchar(void);
+ int __cdecl fileno(FILE *_File);
+ int __cdecl flushall(void);
+ int __cdecl fputchar(int _Ch);
+ int __cdecl getw(FILE *_File);
+ int __cdecl putw(int _Ch,FILE *_File);
+ int __cdecl rmtmp(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+
+#include <sec_api/stdio_s.h>
+
+#endif
diff --git a/win32/include/stdlib.h b/win32/include/stdlib.h
new file mode 100644
index 0000000..96765b2
--- /dev/null
+++ b/win32/include/stdlib.h
@@ -0,0 +1,580 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_STDLIB
+#define _INC_STDLIB
+
+#include <_mingw.h>
+#include <limits.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+
+#ifndef _ONEXIT_T_DEFINED
+#define _ONEXIT_T_DEFINED
+
+ typedef int (__cdecl *_onexit_t)(void);
+
+#ifndef NO_OLDNAMES
+#define onexit_t _onexit_t
+#endif
+#endif
+
+#ifndef _DIV_T_DEFINED
+#define _DIV_T_DEFINED
+
+ typedef struct _div_t {
+ int quot;
+ int rem;
+ } div_t;
+
+ typedef struct _ldiv_t {
+ long quot;
+ long rem;
+ } ldiv_t;
+#endif
+
+#ifndef _CRT_DOUBLE_DEC
+#define _CRT_DOUBLE_DEC
+
+#pragma pack(4)
+ typedef struct {
+ unsigned char ld[10];
+ } _LDOUBLE;
+#pragma pack()
+
+#define _PTR_LD(x) ((unsigned char *)(&(x)->ld))
+
+ typedef struct {
+ double x;
+ } _CRT_DOUBLE;
+
+ typedef struct {
+ float f;
+ } _CRT_FLOAT;
+
+#pragma push_macro("long")
+#undef long
+
+ typedef struct {
+ long double x;
+ } _LONGDOUBLE;
+
+#pragma pop_macro("long")
+
+#pragma pack(4)
+ typedef struct {
+ unsigned char ld12[12];
+ } _LDBL12;
+#pragma pack()
+#endif
+
+#define RAND_MAX 0x7fff
+
+#ifndef MB_CUR_MAX
+#define MB_CUR_MAX ___mb_cur_max_func()
+#ifndef __mb_cur_max
+#ifdef _MSVCRT_
+ extern int __mb_cur_max;
+#else
+#define __mb_cur_max (*_imp____mb_cur_max)
+ extern int *_imp____mb_cur_max;
+#endif
+#endif
+#ifdef _MSVCRT_
+ extern int __mbcur_max;
+#define ___mb_cur_max_func() (__mb_cur_max)
+#else
+ extern int* _imp____mbcur_max;
+#define ___mb_cur_max_func() (*_imp____mb_cur_max)
+#endif
+#endif
+
+#define __max(a,b) (((a) > (b)) ? (a) : (b))
+#define __min(a,b) (((a) < (b)) ? (a) : (b))
+
+#define _MAX_PATH 260
+#define _MAX_DRIVE 3
+#define _MAX_DIR 256
+#define _MAX_FNAME 256
+#define _MAX_EXT 256
+
+#define _OUT_TO_DEFAULT 0
+#define _OUT_TO_STDERR 1
+#define _OUT_TO_MSGBOX 2
+#define _REPORT_ERRMODE 3
+
+#define _WRITE_ABORT_MSG 0x1
+#define _CALL_REPORTFAULT 0x2
+
+#define _MAX_ENV 32767
+
+ typedef void (__cdecl *_purecall_handler)(void);
+
+ _CRTIMP _purecall_handler __cdecl _set_purecall_handler(_purecall_handler _Handler);
+ _CRTIMP _purecall_handler __cdecl _get_purecall_handler(void);
+
+ typedef void (__cdecl *_invalid_parameter_handler)(const wchar_t *,const wchar_t *,const wchar_t *,unsigned int,uintptr_t);
+ _invalid_parameter_handler __cdecl _set_invalid_parameter_handler(_invalid_parameter_handler _Handler);
+ _invalid_parameter_handler __cdecl _get_invalid_parameter_handler(void);
+
+#ifndef _CRT_ERRNO_DEFINED
+#define _CRT_ERRNO_DEFINED
+ _CRTIMP extern int *__cdecl _errno(void);
+#define errno (*_errno())
+ errno_t __cdecl _set_errno(int _Value);
+ errno_t __cdecl _get_errno(int *_Value);
+#endif
+ _CRTIMP unsigned long *__cdecl __doserrno(void);
+#define _doserrno (*__doserrno())
+ errno_t __cdecl _set_doserrno(unsigned long _Value);
+ errno_t __cdecl _get_doserrno(unsigned long *_Value);
+#ifdef _MSVCRT_
+ extern char *_sys_errlist[];
+ extern int _sys_nerr;
+#else
+ _CRTIMP char *_sys_errlist[1];
+ _CRTIMP int _sys_nerr;
+#endif
+#if (defined(_X86_) && !defined(__x86_64))
+ _CRTIMP int *__cdecl __p___argc(void);
+ _CRTIMP char ***__cdecl __p___argv(void);
+ _CRTIMP wchar_t ***__cdecl __p___wargv(void);
+ _CRTIMP char ***__cdecl __p__environ(void);
+ _CRTIMP wchar_t ***__cdecl __p__wenviron(void);
+ _CRTIMP char **__cdecl __p__pgmptr(void);
+ _CRTIMP wchar_t **__cdecl __p__wpgmptr(void);
+#endif
+#ifndef __argc
+#ifdef _MSVCRT_
+ extern int __argc;
+#else
+#define __argc (*_imp____argc)
+ extern int *_imp____argc;
+#endif
+#endif
+#ifndef __argv
+#ifdef _MSVCRT_
+ extern char **__argv;
+#else
+#define __argv (*_imp____argv)
+ extern char ***_imp____argv;
+#endif
+#endif
+#ifndef __wargv
+#ifdef _MSVCRT_
+ extern wchar_t **__wargv;
+#else
+#define __wargv (*_imp____wargv)
+ extern wchar_t ***_imp____wargv;
+#endif
+#endif
+
+#ifdef _POSIX_
+ extern char **environ;
+#else
+#ifndef _environ
+#ifdef _MSVCRT_
+ extern char **_environ;
+#else
+#define _environ (*_imp___environ)
+ extern char ***_imp___environ;
+#endif
+#endif
+
+#ifndef _wenviron
+#ifdef _MSVCRT_
+ extern wchar_t **_wenviron;
+#else
+#define _wenviron (*_imp___wenviron)
+ extern wchar_t ***_imp___wenviron;
+#endif
+#endif
+#endif
+#ifndef _pgmptr
+#ifdef _MSVCRT_
+ extern char *_pgmptr;
+#else
+#define _pgmptr (*_imp___pgmptr)
+ extern char **_imp___pgmptr;
+#endif
+#endif
+
+#ifndef _wpgmptr
+#ifdef _MSVCRT_
+ extern wchar_t *_wpgmptr;
+#else
+#define _wpgmptr (*_imp___wpgmptr)
+ extern wchar_t **_imp___wpgmptr;
+#endif
+#endif
+ errno_t __cdecl _get_pgmptr(char **_Value);
+ errno_t __cdecl _get_wpgmptr(wchar_t **_Value);
+#ifndef _fmode
+#ifdef _MSVCRT_
+ extern int _fmode;
+#else
+#define _fmode (*_imp___fmode)
+ extern int *_imp___fmode;
+#endif
+#endif
+ _CRTIMP errno_t __cdecl _set_fmode(int _Mode);
+ _CRTIMP errno_t __cdecl _get_fmode(int *_PMode);
+
+#ifndef _osplatform
+#ifdef _MSVCRT_
+ extern unsigned int _osplatform;
+#else
+#define _osplatform (*_imp___osplatform)
+ extern unsigned int *_imp___osplatform;
+#endif
+#endif
+
+#ifndef _osver
+#ifdef _MSVCRT_
+ extern unsigned int _osver;
+#else
+#define _osver (*_imp___osver)
+ extern unsigned int *_imp___osver;
+#endif
+#endif
+
+#ifndef _winver
+#ifdef _MSVCRT_
+ extern unsigned int _winver;
+#else
+#define _winver (*_imp___winver)
+ extern unsigned int *_imp___winver;
+#endif
+#endif
+
+#ifndef _winmajor
+#ifdef _MSVCRT_
+ extern unsigned int _winmajor;
+#else
+#define _winmajor (*_imp___winmajor)
+ extern unsigned int *_imp___winmajor;
+#endif
+#endif
+
+#ifndef _winminor
+#ifdef _MSVCRT_
+ extern unsigned int _winminor;
+#else
+#define _winminor (*_imp___winminor)
+ extern unsigned int *_imp___winminor;
+#endif
+#endif
+
+ errno_t __cdecl _get_osplatform(unsigned int *_Value);
+ errno_t __cdecl _get_osver(unsigned int *_Value);
+ errno_t __cdecl _get_winver(unsigned int *_Value);
+ errno_t __cdecl _get_winmajor(unsigned int *_Value);
+ errno_t __cdecl _get_winminor(unsigned int *_Value);
+#ifndef _countof
+#ifndef __cplusplus
+#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
+#else
+ extern "C++" {
+ template <typename _CountofType,size_t _SizeOfArray> char (*__countof_helper(UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];
+#define _countof(_Array) sizeof(*__countof_helper(_Array))
+ }
+#endif
+#endif
+
+#ifndef _CRT_TERMINATE_DEFINED
+#define _CRT_TERMINATE_DEFINED
+ void __cdecl __MINGW_NOTHROW exit(int _Code) __MINGW_ATTRIB_NORETURN;
+ _CRTIMP void __cdecl __MINGW_NOTHROW _exit(int _Code) __MINGW_ATTRIB_NORETURN;
+#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */
+ /* C99 function name */
+ void __cdecl _Exit(int) __MINGW_ATTRIB_NORETURN;
+ __CRT_INLINE __MINGW_ATTRIB_NORETURN void __cdecl _Exit(int status)
+ { _exit(status); }
+#endif
+
+#pragma push_macro("abort")
+#undef abort
+ void __cdecl __declspec(noreturn) abort(void);
+#pragma pop_macro("abort")
+
+#endif
+
+ _CRTIMP unsigned int __cdecl _set_abort_behavior(unsigned int _Flags,unsigned int _Mask);
+
+#ifndef _CRT_ABS_DEFINED
+#define _CRT_ABS_DEFINED
+ int __cdecl abs(int _X);
+ long __cdecl labs(long _X);
+#endif
+
+#if _INTEGRAL_MAX_BITS >= 64
+ __int64 __cdecl _abs64(__int64);
+#endif
+ int __cdecl atexit(void (__cdecl *)(void));
+#ifndef _CRT_ATOF_DEFINED
+#define _CRT_ATOF_DEFINED
+ double __cdecl atof(const char *_String);
+ double __cdecl _atof_l(const char *_String,_locale_t _Locale);
+#endif
+ int __cdecl atoi(const char *_Str);
+ _CRTIMP int __cdecl _atoi_l(const char *_Str,_locale_t _Locale);
+ long __cdecl atol(const char *_Str);
+ _CRTIMP long __cdecl _atol_l(const char *_Str,_locale_t _Locale);
+#ifndef _CRT_ALGO_DEFINED
+#define _CRT_ALGO_DEFINED
+ void *__cdecl bsearch(const void *_Key,const void *_Base,size_t _NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *));
+ void __cdecl qsort(void *_Base,size_t _NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *));
+#endif
+ unsigned short __cdecl _byteswap_ushort(unsigned short _Short);
+ /*unsigned long __cdecl _byteswap_ulong (unsigned long _Long); */
+#if _INTEGRAL_MAX_BITS >= 64
+ unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 _Int64);
+#endif
+ div_t __cdecl div(int _Numerator,int _Denominator);
+ char *__cdecl getenv(const char *_VarName);
+ _CRTIMP char *__cdecl _itoa(int _Value,char *_Dest,int _Radix);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP char *__cdecl _i64toa(__int64 _Val,char *_DstBuf,int _Radix);
+ _CRTIMP char *__cdecl _ui64toa(unsigned __int64 _Val,char *_DstBuf,int _Radix);
+ _CRTIMP __int64 __cdecl _atoi64(const char *_String);
+ _CRTIMP __int64 __cdecl _atoi64_l(const char *_String,_locale_t _Locale);
+ _CRTIMP __int64 __cdecl _strtoi64(const char *_String,char **_EndPtr,int _Radix);
+ _CRTIMP __int64 __cdecl _strtoi64_l(const char *_String,char **_EndPtr,int _Radix,_locale_t _Locale);
+ _CRTIMP unsigned __int64 __cdecl _strtoui64(const char *_String,char **_EndPtr,int _Radix);
+ _CRTIMP unsigned __int64 __cdecl _strtoui64_l(const char *_String,char **_EndPtr,int _Radix,_locale_t _Locale);
+#endif
+ ldiv_t __cdecl ldiv(long _Numerator,long _Denominator);
+ _CRTIMP char *__cdecl _ltoa(long _Value,char *_Dest,int _Radix);
+ int __cdecl mblen(const char *_Ch,size_t _MaxCount);
+ _CRTIMP int __cdecl _mblen_l(const char *_Ch,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP size_t __cdecl _mbstrlen(const char *_Str);
+ _CRTIMP size_t __cdecl _mbstrlen_l(const char *_Str,_locale_t _Locale);
+ _CRTIMP size_t __cdecl _mbstrnlen(const char *_Str,size_t _MaxCount);
+ _CRTIMP size_t __cdecl _mbstrnlen_l(const char *_Str,size_t _MaxCount,_locale_t _Locale);
+ int __cdecl mbtowc(wchar_t *_DstCh,const char *_SrcCh,size_t _SrcSizeInBytes);
+ _CRTIMP int __cdecl _mbtowc_l(wchar_t *_DstCh,const char *_SrcCh,size_t _SrcSizeInBytes,_locale_t _Locale);
+ size_t __cdecl mbstowcs(wchar_t *_Dest,const char *_Source,size_t _MaxCount);
+ _CRTIMP size_t __cdecl _mbstowcs_l(wchar_t *_Dest,const char *_Source,size_t _MaxCount,_locale_t _Locale);
+ int __cdecl rand(void);
+ _CRTIMP int __cdecl _set_error_mode(int _Mode);
+ void __cdecl srand(unsigned int _Seed);
+ double __cdecl strtod(const char *_Str,char **_EndPtr);
+ float __cdecl strtof(const char *nptr, char **endptr);
+#if !defined __NO_ISOCEXT /* in libmingwex.a */
+ float __cdecl strtof (const char * __restrict__, char ** __restrict__);
+ long double __cdecl strtold(const char * __restrict__, char ** __restrict__);
+#endif /* __NO_ISOCEXT */
+ _CRTIMP double __cdecl _strtod_l(const char *_Str,char **_EndPtr,_locale_t _Locale);
+ long __cdecl strtol(const char *_Str,char **_EndPtr,int _Radix);
+ _CRTIMP long __cdecl _strtol_l(const char *_Str,char **_EndPtr,int _Radix,_locale_t _Locale);
+ unsigned long __cdecl strtoul(const char *_Str,char **_EndPtr,int _Radix);
+ _CRTIMP unsigned long __cdecl _strtoul_l(const char *_Str,char **_EndPtr,int _Radix,_locale_t _Locale);
+#ifndef _CRT_SYSTEM_DEFINED
+#define _CRT_SYSTEM_DEFINED
+ int __cdecl system(const char *_Command);
+#endif
+ _CRTIMP char *__cdecl _ultoa(unsigned long _Value,char *_Dest,int _Radix);
+ int __cdecl wctomb(char *_MbCh,wchar_t _WCh);
+ _CRTIMP int __cdecl _wctomb_l(char *_MbCh,wchar_t _WCh,_locale_t _Locale);
+ size_t __cdecl wcstombs(char *_Dest,const wchar_t *_Source,size_t _MaxCount);
+ _CRTIMP size_t __cdecl _wcstombs_l(char *_Dest,const wchar_t *_Source,size_t _MaxCount,_locale_t _Locale);
+
+#ifndef _CRT_ALLOCATION_DEFINED
+#define _CRT_ALLOCATION_DEFINED
+ void *__cdecl calloc(size_t _NumOfElements,size_t _SizeOfElements);
+ void __cdecl free(void *_Memory);
+ void *__cdecl malloc(size_t _Size);
+ void *__cdecl realloc(void *_Memory,size_t _NewSize);
+ _CRTIMP void *__cdecl _recalloc(void *_Memory,size_t _Count,size_t _Size);
+ //_CRTIMP void __cdecl _aligned_free(void *_Memory);
+ //_CRTIMP void *__cdecl _aligned_malloc(size_t _Size,size_t _Alignment);
+ _CRTIMP void *__cdecl _aligned_offset_malloc(size_t _Size,size_t _Alignment,size_t _Offset);
+ _CRTIMP void *__cdecl _aligned_realloc(void *_Memory,size_t _Size,size_t _Alignment);
+ _CRTIMP void *__cdecl _aligned_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment);
+ _CRTIMP void *__cdecl _aligned_offset_realloc(void *_Memory,size_t _Size,size_t _Alignment,size_t _Offset);
+ _CRTIMP void *__cdecl _aligned_offset_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment,size_t _Offset);
+#endif
+
+#ifndef _WSTDLIB_DEFINED
+#define _WSTDLIB_DEFINED
+
+ _CRTIMP wchar_t *__cdecl _itow(int _Value,wchar_t *_Dest,int _Radix);
+ _CRTIMP wchar_t *__cdecl _ltow(long _Value,wchar_t *_Dest,int _Radix);
+ _CRTIMP wchar_t *__cdecl _ultow(unsigned long _Value,wchar_t *_Dest,int _Radix);
+ double __cdecl wcstod(const wchar_t *_Str,wchar_t **_EndPtr);
+ float __cdecl wcstof(const wchar_t *nptr, wchar_t **endptr);
+#if !defined __NO_ISOCEXT /* in libmingwex.a */
+ float __cdecl wcstof( const wchar_t * __restrict__, wchar_t ** __restrict__);
+ long double __cdecl wcstold(const wchar_t * __restrict__, wchar_t ** __restrict__);
+#endif /* __NO_ISOCEXT */
+ _CRTIMP double __cdecl _wcstod_l(const wchar_t *_Str,wchar_t **_EndPtr,_locale_t _Locale);
+ long __cdecl wcstol(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix);
+ _CRTIMP long __cdecl _wcstol_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale);
+ unsigned long __cdecl wcstoul(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix);
+ _CRTIMP unsigned long __cdecl _wcstoul_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale);
+ _CRTIMP wchar_t *__cdecl _wgetenv(const wchar_t *_VarName);
+#ifndef _CRT_WSYSTEM_DEFINED
+#define _CRT_WSYSTEM_DEFINED
+ _CRTIMP int __cdecl _wsystem(const wchar_t *_Command);
+#endif
+ _CRTIMP double __cdecl _wtof(const wchar_t *_Str);
+ _CRTIMP double __cdecl _wtof_l(const wchar_t *_Str,_locale_t _Locale);
+ _CRTIMP int __cdecl _wtoi(const wchar_t *_Str);
+ _CRTIMP int __cdecl _wtoi_l(const wchar_t *_Str,_locale_t _Locale);
+ _CRTIMP long __cdecl _wtol(const wchar_t *_Str);
+ _CRTIMP long __cdecl _wtol_l(const wchar_t *_Str,_locale_t _Locale);
+
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP wchar_t *__cdecl _i64tow(__int64 _Val,wchar_t *_DstBuf,int _Radix);
+ _CRTIMP wchar_t *__cdecl _ui64tow(unsigned __int64 _Val,wchar_t *_DstBuf,int _Radix);
+ _CRTIMP __int64 __cdecl _wtoi64(const wchar_t *_Str);
+ _CRTIMP __int64 __cdecl _wtoi64_l(const wchar_t *_Str,_locale_t _Locale);
+ _CRTIMP __int64 __cdecl _wcstoi64(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix);
+ _CRTIMP __int64 __cdecl _wcstoi64_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale);
+ _CRTIMP unsigned __int64 __cdecl _wcstoui64(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix);
+ _CRTIMP unsigned __int64 __cdecl _wcstoui64_l(const wchar_t *_Str ,wchar_t **_EndPtr,int _Radix,_locale_t _Locale);
+#endif
+#endif
+
+#ifndef _POSIX_
+#define _CVTBUFSIZE (309+40)
+ _CRTIMP char *__cdecl _fullpath(char *_FullPath,const char *_Path,size_t _SizeInBytes);
+ _CRTIMP char *__cdecl _ecvt(double _Val,int _NumOfDigits,int *_PtDec,int *_PtSign);
+ _CRTIMP char *__cdecl _fcvt(double _Val,int _NumOfDec,int *_PtDec,int *_PtSign);
+ _CRTIMP char *__cdecl _gcvt(double _Val,int _NumOfDigits,char *_DstBuf);
+ _CRTIMP int __cdecl _atodbl(_CRT_DOUBLE *_Result,char *_Str);
+ _CRTIMP int __cdecl _atoldbl(_LDOUBLE *_Result,char *_Str);
+ _CRTIMP int __cdecl _atoflt(_CRT_FLOAT *_Result,char *_Str);
+ _CRTIMP int __cdecl _atodbl_l(_CRT_DOUBLE *_Result,char *_Str,_locale_t _Locale);
+ _CRTIMP int __cdecl _atoldbl_l(_LDOUBLE *_Result,char *_Str,_locale_t _Locale);
+ _CRTIMP int __cdecl _atoflt_l(_CRT_FLOAT *_Result,char *_Str,_locale_t _Locale);
+ unsigned long __cdecl _lrotl(unsigned long _Val,int _Shift);
+ unsigned long __cdecl _lrotr(unsigned long _Val,int _Shift);
+ _CRTIMP void __cdecl _makepath(char *_Path,const char *_Drive,const char *_Dir,const char *_Filename,const char *_Ext);
+ _onexit_t __cdecl _onexit(_onexit_t _Func);
+
+#ifndef _CRT_PERROR_DEFINED
+#define _CRT_PERROR_DEFINED
+ void __cdecl perror(const char *_ErrMsg);
+#endif
+ _CRTIMP int __cdecl _putenv(const char *_EnvString);
+ unsigned int __cdecl _rotl(unsigned int _Val,int _Shift);
+#if _INTEGRAL_MAX_BITS >= 64
+ unsigned __int64 __cdecl _rotl64(unsigned __int64 _Val,int _Shift);
+#endif
+ unsigned int __cdecl _rotr(unsigned int _Val,int _Shift);
+#if _INTEGRAL_MAX_BITS >= 64
+ unsigned __int64 __cdecl _rotr64(unsigned __int64 _Val,int _Shift);
+#endif
+ _CRTIMP void __cdecl _searchenv(const char *_Filename,const char *_EnvVar,char *_ResultPath);
+ _CRTIMP void __cdecl _splitpath(const char *_FullPath,char *_Drive,char *_Dir,char *_Filename,char *_Ext);
+ _CRTIMP void __cdecl _swab(char *_Buf1,char *_Buf2,int _SizeInBytes);
+
+#ifndef _WSTDLIBP_DEFINED
+#define _WSTDLIBP_DEFINED
+ _CRTIMP wchar_t *__cdecl _wfullpath(wchar_t *_FullPath,const wchar_t *_Path,size_t _SizeInWords);
+ _CRTIMP void __cdecl _wmakepath(wchar_t *_ResultPath,const wchar_t *_Drive,const wchar_t *_Dir,const wchar_t *_Filename,const wchar_t *_Ext);
+#ifndef _CRT_WPERROR_DEFINED
+#define _CRT_WPERROR_DEFINED
+ _CRTIMP void __cdecl _wperror(const wchar_t *_ErrMsg);
+#endif
+ _CRTIMP int __cdecl _wputenv(const wchar_t *_EnvString);
+ _CRTIMP void __cdecl _wsearchenv(const wchar_t *_Filename,const wchar_t *_EnvVar,wchar_t *_ResultPath);
+ _CRTIMP void __cdecl _wsplitpath(const wchar_t *_FullPath,wchar_t *_Drive,wchar_t *_Dir,wchar_t *_Filename,wchar_t *_Ext);
+#endif
+
+ _CRTIMP void __cdecl _beep(unsigned _Frequency,unsigned _Duration) __MINGW_ATTRIB_DEPRECATED;
+ /* Not to be confused with _set_error_mode (int). */
+ _CRTIMP void __cdecl _seterrormode(int _Mode) __MINGW_ATTRIB_DEPRECATED;
+ _CRTIMP void __cdecl _sleep(unsigned long _Duration) __MINGW_ATTRIB_DEPRECATED;
+#endif
+
+#ifndef NO_OLDNAMES
+#ifndef _POSIX_
+#if 0
+#ifndef __cplusplus
+#ifndef NOMINMAX
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+#endif
+#endif
+#endif
+
+#define sys_errlist _sys_errlist
+#define sys_nerr _sys_nerr
+#define environ _environ
+ char *__cdecl ecvt(double _Val,int _NumOfDigits,int *_PtDec,int *_PtSign);
+ char *__cdecl fcvt(double _Val,int _NumOfDec,int *_PtDec,int *_PtSign);
+ char *__cdecl gcvt(double _Val,int _NumOfDigits,char *_DstBuf);
+ char *__cdecl itoa(int _Val,char *_DstBuf,int _Radix);
+ char *__cdecl ltoa(long _Val,char *_DstBuf,int _Radix);
+ int __cdecl putenv(const char *_EnvString);
+ void __cdecl swab(char *_Buf1,char *_Buf2,int _SizeInBytes);
+ char *__cdecl ultoa(unsigned long _Val,char *_Dstbuf,int _Radix);
+ onexit_t __cdecl onexit(onexit_t _Func);
+#endif
+#endif
+
+#if !defined __NO_ISOCEXT /* externs in static libmingwex.a */
+
+ typedef struct { long long quot, rem; } lldiv_t;
+
+ lldiv_t __cdecl lldiv(long long, long long);
+
+ __CRT_INLINE long long __cdecl llabs(long long _j) { return (_j >= 0 ? _j : -_j); }
+
+ long long __cdecl strtoll(const char* __restrict__, char** __restrict, int);
+ unsigned long long __cdecl strtoull(const char* __restrict__, char** __restrict__, int);
+
+ /* these are stubs for MS _i64 versions */
+ long long __cdecl atoll (const char *);
+
+#ifndef __STRICT_ANSI__
+ long long __cdecl wtoll (const wchar_t *);
+ char *__cdecl lltoa (long long, char *, int);
+ char *__cdecl ulltoa (unsigned long long , char *, int);
+ wchar_t *__cdecl lltow (long long, wchar_t *, int);
+ wchar_t *__cdecl ulltow (unsigned long long, wchar_t *, int);
+
+ /* __CRT_INLINE using non-ansi functions */
+ __CRT_INLINE long long __cdecl atoll (const char * _c) { return _atoi64 (_c); }
+ __CRT_INLINE char *__cdecl lltoa (long long _n, char * _c, int _i) { return _i64toa (_n, _c, _i); }
+ __CRT_INLINE char *__cdecl ulltoa (unsigned long long _n, char * _c, int _i) { return _ui64toa (_n, _c, _i); }
+ __CRT_INLINE long long __cdecl wtoll (const wchar_t * _w) { return _wtoi64 (_w); }
+ __CRT_INLINE wchar_t *__cdecl lltow (long long _n, wchar_t * _w, int _i) { return _i64tow (_n, _w, _i); }
+ __CRT_INLINE wchar_t *__cdecl ulltow (unsigned long long _n, wchar_t * _w, int _i) { return _ui64tow (_n, _w, _i); }
+#endif /* (__STRICT_ANSI__) */
+
+#endif /* !__NO_ISOCEXT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+
+#include <sec_api/stdlib_s.h>
+#include <malloc.h>
+
+#endif
diff --git a/win32/include/string.h b/win32/include/string.h
new file mode 100644
index 0000000..3249dc3
--- /dev/null
+++ b/win32/include/string.h
@@ -0,0 +1,164 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_STRING
+#define _INC_STRING
+
+#include <_mingw.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _NLSCMP_DEFINED
+#define _NLSCMP_DEFINED
+#define _NLSCMPERROR 2147483647
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#define _WConst_return _CONST_RETURN
+
+#ifndef _CRT_MEMORY_DEFINED
+#define _CRT_MEMORY_DEFINED
+ _CRTIMP void *__cdecl _memccpy(void *_Dst,const void *_Src,int _Val,size_t _MaxCount);
+ _CONST_RETURN void *__cdecl memchr(const void *_Buf ,int _Val,size_t _MaxCount);
+ _CRTIMP int __cdecl _memicmp(const void *_Buf1,const void *_Buf2,size_t _Size);
+ _CRTIMP int __cdecl _memicmp_l(const void *_Buf1,const void *_Buf2,size_t _Size,_locale_t _Locale);
+ int __cdecl memcmp(const void *_Buf1,const void *_Buf2,size_t _Size);
+ void *__cdecl memcpy(void *_Dst,const void *_Src,size_t _Size);
+ void *__cdecl memset(void *_Dst,int _Val,size_t _Size);
+#ifndef NO_OLDNAMES
+ void *__cdecl memccpy(void *_Dst,const void *_Src,int _Val,size_t _Size);
+ int __cdecl memicmp(const void *_Buf1,const void *_Buf2,size_t _Size);
+#endif
+#endif
+ char *__cdecl _strset(char *_Str,int _Val);
+ char *__cdecl strcpy(char *_Dest,const char *_Source);
+ char *__cdecl strcat(char *_Dest,const char *_Source);
+ int __cdecl strcmp(const char *_Str1,const char *_Str2);
+ size_t __cdecl strlen(const char *_Str);
+#if 0
+ size_t __cdecl strnlen(const char *_Str,size_t _MaxCount);
+#endif
+ void *__cdecl memmove(void *_Dst,const void *_Src,size_t _Size);
+ _CRTIMP char *__cdecl _strdup(const char *_Src);
+ _CONST_RETURN char *__cdecl strchr(const char *_Str,int _Val);
+ _CRTIMP int __cdecl _stricmp(const char *_Str1,const char *_Str2);
+ _CRTIMP int __cdecl _strcmpi(const char *_Str1,const char *_Str2);
+ _CRTIMP int __cdecl _stricmp_l(const char *_Str1,const char *_Str2,_locale_t _Locale);
+ int __cdecl strcoll(const char *_Str1,const char *_Str2);
+ _CRTIMP int __cdecl _strcoll_l(const char *_Str1,const char *_Str2,_locale_t _Locale);
+ _CRTIMP int __cdecl _stricoll(const char *_Str1,const char *_Str2);
+ _CRTIMP int __cdecl _stricoll_l(const char *_Str1,const char *_Str2,_locale_t _Locale);
+ _CRTIMP int __cdecl _strncoll (const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _strncoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP int __cdecl _strnicoll (const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _strnicoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale);
+ size_t __cdecl strcspn(const char *_Str,const char *_Control);
+ _CRTIMP char *__cdecl _strerror(const char *_ErrMsg);
+ char *__cdecl strerror(int);
+ _CRTIMP char *__cdecl _strlwr(char *_String);
+ char *strlwr_l(char *_String,_locale_t _Locale);
+ char *__cdecl strncat(char *_Dest,const char *_Source,size_t _Count);
+ int __cdecl strncmp(const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _strnicmp(const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _strnicmp_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale);
+ char *strncpy(char *_Dest,const char *_Source,size_t _Count);
+ _CRTIMP char *__cdecl _strnset(char *_Str,int _Val,size_t _MaxCount);
+ _CONST_RETURN char *__cdecl strpbrk(const char *_Str,const char *_Control);
+ _CONST_RETURN char *__cdecl strrchr(const char *_Str,int _Ch);
+ _CRTIMP char *__cdecl _strrev(char *_Str);
+ size_t __cdecl strspn(const char *_Str,const char *_Control);
+ _CONST_RETURN char *__cdecl strstr(const char *_Str,const char *_SubStr);
+ char *__cdecl strtok(char *_Str,const char *_Delim);
+ _CRTIMP char *__cdecl _strupr(char *_String);
+ _CRTIMP char *_strupr_l(char *_String,_locale_t _Locale);
+ size_t __cdecl strxfrm(char *_Dst,const char *_Src,size_t _MaxCount);
+ _CRTIMP size_t __cdecl _strxfrm_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale);
+
+#ifndef NO_OLDNAMES
+ char *__cdecl strdup(const char *_Src);
+ int __cdecl strcmpi(const char *_Str1,const char *_Str2);
+ int __cdecl stricmp(const char *_Str1,const char *_Str2);
+ char *__cdecl strlwr(char *_Str);
+ int __cdecl strnicmp(const char *_Str1,const char *_Str,size_t _MaxCount);
+ __CRT_INLINE int __cdecl strncasecmp (const char *__sz1, const char *__sz2, size_t __sizeMaxCompare) { return _strnicmp (__sz1, __sz2, __sizeMaxCompare); }
+ __CRT_INLINE int __cdecl strcasecmp (const char *__sz1, const char *__sz2) { return _stricmp (__sz1, __sz2); }
+ char *__cdecl strnset(char *_Str,int _Val,size_t _MaxCount);
+ char *__cdecl strrev(char *_Str);
+ char *__cdecl strset(char *_Str,int _Val);
+ char *__cdecl strupr(char *_Str);
+#endif
+
+#ifndef _WSTRING_DEFINED
+#define _WSTRING_DEFINED
+
+ _CRTIMP wchar_t *__cdecl _wcsdup(const wchar_t *_Str);
+ wchar_t *__cdecl wcscat(wchar_t *_Dest,const wchar_t *_Source);
+ _CONST_RETURN wchar_t *__cdecl wcschr(const wchar_t *_Str,wchar_t _Ch);
+ int __cdecl wcscmp(const wchar_t *_Str1,const wchar_t *_Str2);
+ wchar_t *__cdecl wcscpy(wchar_t *_Dest,const wchar_t *_Source);
+ size_t __cdecl wcscspn(const wchar_t *_Str,const wchar_t *_Control);
+ size_t __cdecl wcslen(const wchar_t *_Str);
+ size_t __cdecl wcsnlen(const wchar_t *_Src,size_t _MaxCount);
+ wchar_t *wcsncat(wchar_t *_Dest,const wchar_t *_Source,size_t _Count);
+ int __cdecl wcsncmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount);
+ wchar_t *wcsncpy(wchar_t *_Dest,const wchar_t *_Source,size_t _Count);
+ _CONST_RETURN wchar_t *__cdecl wcspbrk(const wchar_t *_Str,const wchar_t *_Control);
+ _CONST_RETURN wchar_t *__cdecl wcsrchr(const wchar_t *_Str,wchar_t _Ch);
+ size_t __cdecl wcsspn(const wchar_t *_Str,const wchar_t *_Control);
+ _CONST_RETURN wchar_t *__cdecl wcsstr(const wchar_t *_Str,const wchar_t *_SubStr);
+ wchar_t *__cdecl wcstok(wchar_t *_Str,const wchar_t *_Delim);
+ _CRTIMP wchar_t *__cdecl _wcserror(int _ErrNum);
+ _CRTIMP wchar_t *__cdecl __wcserror(const wchar_t *_Str);
+ _CRTIMP int __cdecl _wcsicmp(const wchar_t *_Str1,const wchar_t *_Str2);
+ _CRTIMP int __cdecl _wcsicmp_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale);
+ _CRTIMP int __cdecl _wcsnicmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _wcsnicmp_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP wchar_t *__cdecl _wcsnset(wchar_t *_Str,wchar_t _Val,size_t _MaxCount);
+ _CRTIMP wchar_t *__cdecl _wcsrev(wchar_t *_Str);
+ _CRTIMP wchar_t *__cdecl _wcsset(wchar_t *_Str,wchar_t _Val);
+ _CRTIMP wchar_t *__cdecl _wcslwr(wchar_t *_String);
+ _CRTIMP wchar_t *_wcslwr_l(wchar_t *_String,_locale_t _Locale);
+ _CRTIMP wchar_t *__cdecl _wcsupr(wchar_t *_String);
+ _CRTIMP wchar_t *_wcsupr_l(wchar_t *_String,_locale_t _Locale);
+ size_t __cdecl wcsxfrm(wchar_t *_Dst,const wchar_t *_Src,size_t _MaxCount);
+ _CRTIMP size_t __cdecl _wcsxfrm_l(wchar_t *_Dst,const wchar_t *_Src,size_t _MaxCount,_locale_t _Locale);
+ int __cdecl wcscoll(const wchar_t *_Str1,const wchar_t *_Str2);
+ _CRTIMP int __cdecl _wcscoll_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale);
+ _CRTIMP int __cdecl _wcsicoll(const wchar_t *_Str1,const wchar_t *_Str2);
+ _CRTIMP int __cdecl _wcsicoll_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale);
+ _CRTIMP int __cdecl _wcsncoll(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _wcsncoll_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP int __cdecl _wcsnicoll(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _wcsnicoll_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale);
+
+#ifndef NO_OLDNAMES
+ wchar_t *__cdecl wcsdup(const wchar_t *_Str);
+#define wcswcs wcsstr
+ int __cdecl wcsicmp(const wchar_t *_Str1,const wchar_t *_Str2);
+ int __cdecl wcsnicmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount);
+ wchar_t *__cdecl wcsnset(wchar_t *_Str,wchar_t _Val,size_t _MaxCount);
+ wchar_t *__cdecl wcsrev(wchar_t *_Str);
+ wchar_t *__cdecl wcsset(wchar_t *_Str,wchar_t _Val);
+ wchar_t *__cdecl wcslwr(wchar_t *_Str);
+ wchar_t *__cdecl wcsupr(wchar_t *_Str);
+ int __cdecl wcsicoll(const wchar_t *_Str1,const wchar_t *_Str2);
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <sec_api/string_s.h>
+#endif
diff --git a/win32/include/sys/fcntl.h b/win32/include/sys/fcntl.h
new file mode 100644
index 0000000..29fd55a
--- /dev/null
+++ b/win32/include/sys/fcntl.h
@@ -0,0 +1,13 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+/*
+ * This file is part of the Mingw32 package.
+ *
+ * This fcntl.h maps to the root fcntl.h
+ */
+#ifndef __STRICT_ANSI__
+#include <fcntl.h>
+#endif
diff --git a/win32/include/sys/file.h b/win32/include/sys/file.h
new file mode 100644
index 0000000..370f352
--- /dev/null
+++ b/win32/include/sys/file.h
@@ -0,0 +1,14 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+/*
+ * This file is part of the Mingw32 package.
+ *
+ * This file.h maps to the root fcntl.h
+ * TODO?
+ */
+#ifndef __STRICT_ANSI__
+#include <fcntl.h>
+#endif
diff --git a/win32/include/sys/locking.h b/win32/include/sys/locking.h
new file mode 100644
index 0000000..e3fc85b
--- /dev/null
+++ b/win32/include/sys/locking.h
@@ -0,0 +1,30 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_LOCKING
+#define _INC_LOCKING
+
+#ifndef _WIN32
+#error Only Win32 target is supported!
+#endif
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define _LK_UNLCK 0
+#define _LK_LOCK 1
+#define _LK_NBLCK 2
+#define _LK_RLCK 3
+#define _LK_NBRLCK 4
+
+#ifndef NO_OLDNAMES
+#define LK_UNLCK _LK_UNLCK
+#define LK_LOCK _LK_LOCK
+#define LK_NBLCK _LK_NBLCK
+#define LK_RLCK _LK_RLCK
+#define LK_NBRLCK _LK_NBRLCK
+#endif
+
+#endif
diff --git a/win32/include/sys/stat.h b/win32/include/sys/stat.h
new file mode 100644
index 0000000..344d4a2
--- /dev/null
+++ b/win32/include/sys/stat.h
@@ -0,0 +1,290 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_STAT
+#define _INC_STAT
+
+#ifndef _WIN32
+#error Only Win32 target is supported!
+#endif
+
+#include <_mingw.h>
+#include <io.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _CRTIMP
+#define _CRTIMP __declspec(dllimport)
+#endif
+
+#include <sys/types.h>
+
+#ifndef __TINYC__ /* gr */
+#ifdef _USE_32BIT_TIME_T
+#ifdef _WIN64
+#undef _USE_32BIT_TIME_T
+#endif
+#else
+#if _INTEGRAL_MAX_BITS < 64
+#define _USE_32BIT_TIME_T
+#endif
+#endif
+#endif
+
+#ifndef _TIME32_T_DEFINED
+ typedef long __time32_t;
+#define _TIME32_T_DEFINED
+#endif
+
+#ifndef _TIME64_T_DEFINED
+#if _INTEGRAL_MAX_BITS >= 64
+ typedef __int64 __time64_t;
+#endif
+#define _TIME64_T_DEFINED
+#endif
+
+#ifndef _TIME_T_DEFINED
+#ifdef _USE_32BIT_TIME_T
+ typedef __time32_t time_t;
+#else
+ typedef __time64_t time_t;
+#endif
+#define _TIME_T_DEFINED
+#endif
+
+#ifndef _WCHAR_T_DEFINED
+ typedef unsigned short wchar_t;
+#define _WCHAR_T_DEFINED
+#endif
+
+#ifndef _STAT_DEFINED
+
+#ifdef _USE_32BIT_TIME_T
+#ifndef _WIN64
+#define _fstat32 _fstat
+#define _stat32 _stat
+#define _wstat32 _wstat
+#else
+#define _fstat _fstat32
+#define _stat _stat32
+#define _wstat _wstat32
+#endif
+#define _fstati64 _fstat32i64
+#define _stati64 _stat32i64
+#define _wstati64 _wstat32i64
+#else
+#define _fstat _fstat64i32
+#define _fstati64 _fstat64
+#define _stat _stat64i32
+#define _stati64 _stat64
+#define _wstat _wstat64i32
+#define _wstati64 _wstat64
+#endif
+
+ struct _stat32 {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ _off_t st_size;
+ __time32_t st_atime;
+ __time32_t st_mtime;
+ __time32_t st_ctime;
+ };
+
+#ifndef NO_OLDNAMES
+ struct stat {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ _off_t st_size;
+ time_t st_atime;
+ time_t st_mtime;
+ time_t st_ctime;
+ };
+#endif
+
+#if _INTEGRAL_MAX_BITS >= 64
+ struct _stat32i64 {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ __int64 st_size;
+ __time32_t st_atime;
+ __time32_t st_mtime;
+ __time32_t st_ctime;
+ };
+
+ struct _stat64i32 {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ _off_t st_size;
+ __time64_t st_atime;
+ __time64_t st_mtime;
+ __time64_t st_ctime;
+ };
+
+ struct _stat64 {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ __int64 st_size;
+ __time64_t st_atime;
+ __time64_t st_mtime;
+ __time64_t st_ctime;
+ };
+#endif
+
+#define __stat64 _stat64
+
+#define _STAT_DEFINED
+#endif
+
+#define _S_IFMT 0xF000
+#define _S_IFDIR 0x4000
+#define _S_IFCHR 0x2000
+#define _S_IFIFO 0x1000
+#define _S_IFREG 0x8000
+#define _S_IREAD 0x0100
+#define _S_IWRITE 0x0080
+#define _S_IEXEC 0x0040
+
+ _CRTIMP int __cdecl _fstat32(int _FileDes,struct _stat32 *_Stat);
+ _CRTIMP int __cdecl _stat32(const char *_Name,struct _stat32 *_Stat);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP int __cdecl _fstat64(int _FileDes,struct _stat64 *_Stat);
+ _CRTIMP int __cdecl _fstat32i64(int _FileDes,struct _stat32i64 *_Stat);
+ int __cdecl _fstat64i32(int _FileDes,struct _stat64i32 *_Stat);
+ __CRT_INLINE int __cdecl _fstat64i32(int _FileDes,struct _stat64i32 *_Stat)
+ {
+ struct _stat64 st;
+ int ret=_fstat64(_FileDes,&st);
+ _Stat->st_dev=st.st_dev;
+ _Stat->st_ino=st.st_ino;
+ _Stat->st_mode=st.st_mode;
+ _Stat->st_nlink=st.st_nlink;
+ _Stat->st_uid=st.st_uid;
+ _Stat->st_gid=st.st_gid;
+ _Stat->st_rdev=st.st_rdev;
+ _Stat->st_size=(_off_t) st.st_size;
+ _Stat->st_atime=st.st_atime;
+ _Stat->st_mtime=st.st_mtime;
+ _Stat->st_ctime=st.st_ctime;
+ return ret;
+ }
+ _CRTIMP int __cdecl _stat64(const char *_Name,struct _stat64 *_Stat);
+ _CRTIMP int __cdecl _stat32i64(const char *_Name,struct _stat32i64 *_Stat);
+ int __cdecl _stat64i32(const char *_Name,struct _stat64i32 *_Stat);
+ __CRT_INLINE int __cdecl _stat64i32(const char *_Name,struct _stat64i32 *_Stat)
+ {
+ struct _stat64 st;
+ int ret=_stat64(_Name,&st);
+ _Stat->st_dev=st.st_dev;
+ _Stat->st_ino=st.st_ino;
+ _Stat->st_mode=st.st_mode;
+ _Stat->st_nlink=st.st_nlink;
+ _Stat->st_uid=st.st_uid;
+ _Stat->st_gid=st.st_gid;
+ _Stat->st_rdev=st.st_rdev;
+ _Stat->st_size=(_off_t) st.st_size;
+ _Stat->st_atime=st.st_atime;
+ _Stat->st_mtime=st.st_mtime;
+ _Stat->st_ctime=st.st_ctime;
+ return ret;
+ }
+#endif
+
+#ifndef _WSTAT_DEFINED
+#define _WSTAT_DEFINED
+ _CRTIMP int __cdecl _wstat32(const wchar_t *_Name,struct _stat32 *_Stat);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP int __cdecl _wstat32i64(const wchar_t *_Name,struct _stat32i64 *_Stat);
+ int __cdecl _wstat64i32(const wchar_t *_Name,struct _stat64i32 *_Stat);
+ _CRTIMP int __cdecl _wstat64(const wchar_t *_Name,struct _stat64 *_Stat);
+#endif
+#endif
+
+#ifndef NO_OLDNAMES
+#define _S_IFBLK 0x3000 /* Block: Is this ever set under w32? */
+
+#define S_IFMT _S_IFMT
+#define S_IFDIR _S_IFDIR
+#define S_IFCHR _S_IFCHR
+#define S_IFREG _S_IFREG
+#define S_IREAD _S_IREAD
+#define S_IWRITE _S_IWRITE
+#define S_IEXEC _S_IEXEC
+#define S_IFIFO _S_IFIFO
+#define S_IFBLK _S_IFBLK
+
+#define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC)
+#define _S_IXUSR _S_IEXEC
+#define _S_IWUSR _S_IWRITE
+
+#define S_IRWXU _S_IRWXU
+#define S_IXUSR _S_IXUSR
+#define S_IWUSR _S_IWUSR
+#define S_IRUSR _S_IRUSR
+#define _S_IRUSR _S_IREAD
+
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+
+#endif
+
+#if !defined (RC_INVOKED) && !defined (NO_OLDNAMES)
+int __cdecl stat(const char *_Filename,struct stat *_Stat);
+int __cdecl fstat(int _Desc,struct stat *_Stat);
+int __cdecl wstat(const wchar_t *_Filename,struct stat *_Stat);
+#ifdef _USE_32BIT_TIME_T
+__CRT_INLINE int __cdecl fstat(int _Desc,struct stat *_Stat) {
+ return _fstat32(_Desc,(struct _stat32 *)_Stat);
+}
+__CRT_INLINE int __cdecl stat(const char *_Filename,struct stat *_Stat) {
+ return _stat32(_Filename,(struct _stat32 *)_Stat);
+}
+#else
+__CRT_INLINE int __cdecl fstat(int _Desc,struct stat *_Stat) {
+ return _fstat64i32(_Desc,(struct _stat64i32 *)_Stat);
+}
+__CRT_INLINE int __cdecl stat(const char *_Filename,struct stat *_Stat) {
+ return _stat64i32(_Filename,(struct _stat64i32 *)_Stat);
+}
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+#endif
diff --git a/win32/include/sys/time.h b/win32/include/sys/time.h
new file mode 100644
index 0000000..8ccab83
--- /dev/null
+++ b/win32/include/sys/time.h
@@ -0,0 +1,69 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+
+#ifndef _SYS_TIME_H_
+#define _SYS_TIME_H_
+
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __STRICT_ANSI__
+#ifndef _TIMEVAL_DEFINED /* also in winsock[2].h */
+#define _TIMEVAL_DEFINED
+struct timeval {
+ long tv_sec;
+ long tv_usec;
+};
+#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+#define timercmp(tvp, uvp, cmp) \
+ (((tvp)->tv_sec != (uvp)->tv_sec) ? \
+ ((tvp)->tv_sec cmp (uvp)->tv_sec) : \
+ ((tvp)->tv_usec cmp (uvp)->tv_usec))
+#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
+#endif /* _TIMEVAL_DEFINED */
+
+#ifndef _TIMEZONE_DEFINED /* also in sys/time.h */
+#define _TIMEZONE_DEFINED
+/* Provided for compatibility with code that assumes that
+ the presence of gettimeofday function implies a definition
+ of struct timezone. */
+struct timezone
+{
+ int tz_minuteswest; /* of Greenwich */
+ int tz_dsttime; /* type of dst correction to apply */
+};
+
+ extern int __cdecl mingw_gettimeofday (struct timeval *p, struct timezone *z);
+
+#endif
+
+/*
+ Implementation as per:
+ The Open Group Base Specifications, Issue 6
+ IEEE Std 1003.1, 2004 Edition
+
+ The timezone pointer arg is ignored. Errors are ignored.
+*/
+#ifndef _GETTIMEOFDAY_DEFINED
+#define _GETTIMEOFDAY_DEFINED
+int __cdecl gettimeofday(struct timeval *__restrict__,
+ void *__restrict__ /* tzp (unused) */);
+#endif
+
+#endif /* __STRICT_ANSI__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Adding timespec definition. */
+#include <sys/timeb.h>
+
+
+#endif /* _SYS_TIME_H_ */
diff --git a/win32/include/sys/timeb.h b/win32/include/sys/timeb.h
new file mode 100644
index 0000000..3483773
--- /dev/null
+++ b/win32/include/sys/timeb.h
@@ -0,0 +1,133 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _TIMEB_H_
+#define _TIMEB_H_
+
+#include <_mingw.h>
+
+#ifndef _WIN32
+#error Only Win32 target is supported!
+#endif
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _CRTIMP
+#define _CRTIMP __declspec(dllimport)
+#endif
+
+#ifndef __TINYC__ /* gr */
+#ifdef _USE_32BIT_TIME_T
+#ifdef _WIN64
+#undef _USE_32BIT_TIME_T
+#endif
+#else
+#if _INTEGRAL_MAX_BITS < 64
+#define _USE_32BIT_TIME_T
+#endif
+#endif
+#endif
+
+#ifndef _TIME32_T_DEFINED
+ typedef long __time32_t;
+#define _TIME32_T_DEFINED
+#endif
+
+#ifndef _TIME64_T_DEFINED
+#if _INTEGRAL_MAX_BITS >= 64
+ typedef __int64 __time64_t;
+#endif
+#define _TIME64_T_DEFINED
+#endif
+
+#ifndef _TIME_T_DEFINED
+#ifdef _USE_32BIT_TIME_T
+ typedef __time32_t time_t;
+#else
+ typedef __time64_t time_t;
+#endif
+#define _TIME_T_DEFINED
+#endif
+
+#ifndef _TIMEB_DEFINED
+#define _TIMEB_DEFINED
+
+ struct __timeb32 {
+ __time32_t time;
+ unsigned short millitm;
+ short timezone;
+ short dstflag;
+ };
+
+#ifndef NO_OLDNAMES
+ struct timeb {
+ time_t time;
+ unsigned short millitm;
+ short timezone;
+ short dstflag;
+ };
+#endif
+
+#if _INTEGRAL_MAX_BITS >= 64
+ struct __timeb64 {
+ __time64_t time;
+ unsigned short millitm;
+ short timezone;
+ short dstflag;
+ };
+#endif
+
+#ifdef _USE_32BIT_TIME_T
+#define _timeb __timeb32
+//gr #define _ftime _ftime32
+#define _ftime32 _ftime
+#else
+#define _timeb __timeb64
+#define _ftime _ftime64
+#endif
+#endif
+
+ _CRTIMP void __cdecl _ftime32(struct __timeb32 *_Time);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP void __cdecl _ftime64(struct __timeb64 *_Time);
+#endif
+
+#ifndef _TIMESPEC_DEFINED
+#define _TIMESPEC_DEFINED
+struct timespec {
+ time_t tv_sec; /* Seconds */
+ long tv_nsec; /* Nanoseconds */
+};
+
+struct itimerspec {
+ struct timespec it_interval; /* Timer period */
+ struct timespec it_value; /* Timer expiration */
+};
+#endif
+
+#if !defined (RC_INVOKED) && !defined (NO_OLDNAMES)
+#ifdef _USE_32BIT_TIME_T
+__CRT_INLINE void __cdecl ftime(struct timeb *_Tmb) {
+ _ftime32((struct __timeb32 *)_Tmb);
+}
+#else
+__CRT_INLINE void __cdecl ftime(struct timeb *_Tmb) {
+ _ftime64((struct __timeb64 *)_Tmb);
+}
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+
+#include <sec_api/sys/timeb_s.h>
+#endif
diff --git a/win32/include/sys/types.h b/win32/include/sys/types.h
new file mode 100644
index 0000000..7379b0f
--- /dev/null
+++ b/win32/include/sys/types.h
@@ -0,0 +1,118 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_TYPES
+#define _INC_TYPES
+
+#ifndef _WIN32
+#error Only Win32 target is supported!
+#endif
+
+#include <_mingw.h>
+
+#ifndef __TINYC__ /* gr */
+#ifdef _USE_32BIT_TIME_T
+#ifdef _WIN64
+#undef _USE_32BIT_TIME_T
+#endif
+#else
+#if _INTEGRAL_MAX_BITS < 64
+#define _USE_32BIT_TIME_T
+#endif
+#endif
+#endif
+
+#ifndef _TIME32_T_DEFINED
+#define _TIME32_T_DEFINED
+typedef long __time32_t;
+#endif
+
+#ifndef _TIME64_T_DEFINED
+#define _TIME64_T_DEFINED
+#if _INTEGRAL_MAX_BITS >= 64
+typedef __int64 __time64_t;
+#endif
+#endif
+
+#ifndef _TIME_T_DEFINED
+#define _TIME_T_DEFINED
+#ifdef _USE_32BIT_TIME_T
+typedef __time32_t time_t;
+#else
+typedef __time64_t time_t;
+#endif
+#endif
+
+#ifndef _INO_T_DEFINED
+#define _INO_T_DEFINED
+typedef unsigned short _ino_t;
+#ifndef NO_OLDNAMES
+typedef unsigned short ino_t;
+#endif
+#endif
+
+#ifndef _DEV_T_DEFINED
+#define _DEV_T_DEFINED
+typedef unsigned int _dev_t;
+#ifndef NO_OLDNAMES
+typedef unsigned int dev_t;
+#endif
+#endif
+
+#ifndef _PID_T_
+#define _PID_T_
+#ifndef _WIN64
+typedef int _pid_t;
+#else
+typedef __int64 _pid_t;
+#endif
+
+#ifndef NO_OLDNAMES
+typedef _pid_t pid_t;
+#endif
+#endif /* Not _PID_T_ */
+
+#ifndef _MODE_T_
+#define _MODE_T_
+typedef unsigned short _mode_t;
+
+#ifndef NO_OLDNAMES
+typedef _mode_t mode_t;
+#endif
+#endif /* Not _MODE_T_ */
+
+#ifndef _OFF_T_DEFINED
+#define _OFF_T_DEFINED
+#ifndef _OFF_T_
+#define _OFF_T_
+ typedef long _off_t;
+#if !defined(NO_OLDNAMES) || defined(_POSIX)
+ typedef long off_t;
+#endif
+#endif
+#endif
+
+#ifndef _OFF64_T_DEFINED
+#define _OFF64_T_DEFINED
+ typedef long long _off64_t;
+#if !defined(NO_OLDNAMES) || defined(_POSIX)
+ typedef long long off64_t;
+#endif
+#endif
+
+#ifndef _TIMESPEC_DEFINED
+#define _TIMESPEC_DEFINED
+struct timespec {
+ time_t tv_sec; /* Seconds */
+ long tv_nsec; /* Nanoseconds */
+};
+
+struct itimerspec {
+ struct timespec it_interval; /* Timer period */
+ struct timespec it_value; /* Timer expiration */
+};
+#endif
+
+#endif
diff --git a/win32/include/sys/unistd.h b/win32/include/sys/unistd.h
new file mode 100644
index 0000000..31006d3
--- /dev/null
+++ b/win32/include/sys/unistd.h
@@ -0,0 +1,14 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+/*
+ * This file is part of the Mingw32 package.
+ *
+ * unistd.h maps (roughly) to io.h
+ */
+#ifndef __STRICT_ANSI__
+#include <io.h>
+#endif
+
diff --git a/win32/include/sys/utime.h b/win32/include/sys/utime.h
new file mode 100644
index 0000000..fec8304
--- /dev/null
+++ b/win32/include/sys/utime.h
@@ -0,0 +1,146 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_UTIME
+#define _INC_UTIME
+
+#ifndef _WIN32
+#error Only Win32 target is supported!
+#endif
+
+#include <_mingw.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _CRTIMP
+#define _CRTIMP __declspec(dllimport)
+#endif
+
+#ifndef _WCHAR_T_DEFINED
+ typedef unsigned short wchar_t;
+#define _WCHAR_T_DEFINED
+#endif
+
+#ifndef __TINYC__ /* gr */
+#ifdef _USE_32BIT_TIME_T
+#ifdef _WIN64
+#undef _USE_32BIT_TIME_T
+#endif
+#else
+#if _INTEGRAL_MAX_BITS < 64
+#define _USE_32BIT_TIME_T
+#endif
+#endif
+#endif
+
+#ifndef _TIME32_T_DEFINED
+#define _TIME32_T_DEFINED
+ typedef long __time32_t;
+#endif
+
+#ifndef _TIME64_T_DEFINED
+#define _TIME64_T_DEFINED
+#if _INTEGRAL_MAX_BITS >= 64
+ typedef __int64 __time64_t;
+#endif
+#endif
+
+#ifndef _TIME_T_DEFINED
+#define _TIME_T_DEFINED
+#ifdef _USE_32BIT_TIME_T
+ typedef __time32_t time_t;
+#else
+ typedef __time64_t time_t;
+#endif
+#endif
+
+#ifndef _UTIMBUF_DEFINED
+#define _UTIMBUF_DEFINED
+
+ struct _utimbuf {
+ time_t actime;
+ time_t modtime;
+ };
+
+ struct __utimbuf32 {
+ __time32_t actime;
+ __time32_t modtime;
+ };
+
+#if _INTEGRAL_MAX_BITS >= 64
+ struct __utimbuf64 {
+ __time64_t actime;
+ __time64_t modtime;
+ };
+#endif
+
+#ifndef NO_OLDNAMES
+ struct utimbuf {
+ time_t actime;
+ time_t modtime;
+ };
+
+ struct utimbuf32 {
+ __time32_t actime;
+ __time32_t modtime;
+ };
+#endif
+#endif
+
+ _CRTIMP int __cdecl _utime32(const char *_Filename,struct __utimbuf32 *_Time);
+ _CRTIMP int __cdecl _futime32(int _FileDes,struct __utimbuf32 *_Time);
+ _CRTIMP int __cdecl _wutime32(const wchar_t *_Filename,struct __utimbuf32 *_Time);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP int __cdecl _utime64(const char *_Filename,struct __utimbuf64 *_Time);
+ _CRTIMP int __cdecl _futime64(int _FileDes,struct __utimbuf64 *_Time);
+ _CRTIMP int __cdecl _wutime64(const wchar_t *_Filename,struct __utimbuf64 *_Time);
+#endif
+
+#ifndef RC_INVOKED
+#ifdef _USE_32BIT_TIME_T
+__CRT_INLINE int __cdecl _utime(const char *_Filename,struct _utimbuf *_Utimbuf) {
+ return _utime32(_Filename,(struct __utimbuf32 *)_Utimbuf);
+}
+__CRT_INLINE int __cdecl _futime(int _Desc,struct _utimbuf *_Utimbuf) {
+ return _futime32(_Desc,(struct __utimbuf32 *)_Utimbuf);
+}
+__CRT_INLINE int __cdecl _wutime(const wchar_t *_Filename,struct _utimbuf *_Utimbuf) {
+ return _wutime32(_Filename,(struct __utimbuf32 *)_Utimbuf);
+}
+#else
+__CRT_INLINE int __cdecl _utime(const char *_Filename,struct _utimbuf *_Utimbuf) {
+ return _utime64(_Filename,(struct __utimbuf64 *)_Utimbuf);
+}
+__CRT_INLINE int __cdecl _futime(int _Desc,struct _utimbuf *_Utimbuf) {
+ return _futime64(_Desc,(struct __utimbuf64 *)_Utimbuf);
+}
+__CRT_INLINE int __cdecl _wutime(const wchar_t *_Filename,struct _utimbuf *_Utimbuf) {
+ return _wutime64(_Filename,(struct __utimbuf64 *)_Utimbuf);
+}
+#endif
+
+#ifndef NO_OLDNAMES
+#ifdef _USE_32BIT_TIME_T
+__CRT_INLINE int __cdecl utime(const char *_Filename,struct utimbuf *_Utimbuf) {
+ return _utime32(_Filename,(struct __utimbuf32 *)_Utimbuf);
+}
+#else
+__CRT_INLINE int __cdecl utime(const char *_Filename,struct utimbuf *_Utimbuf) {
+ return _utime64(_Filename,(struct __utimbuf64 *)_Utimbuf);
+}
+#endif
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+#endif
diff --git a/win32/include/tcc/tcc_libm.h b/win32/include/tcc/tcc_libm.h
new file mode 100644
index 0000000..0a62e6f
--- /dev/null
+++ b/win32/include/tcc/tcc_libm.h
@@ -0,0 +1,201 @@
+#ifndef _TCC_LIBM_H_
+#define _TCC_LIBM_H_
+
+#include "../math.h"
+
+/* TCC uses 8 bytes for double and long double, so effectively the l variants
+ * are never used. For now, they just run the normal (double) variant.
+ */
+
+/*
+ * most of the code in this file is taken from MUSL rs-1.0 (MIT license)
+ * - musl-libc: http://git.musl-libc.org/cgit/musl/tree/src/math?h=rs-1.0
+ * - License: http://git.musl-libc.org/cgit/musl/tree/COPYRIGHT?h=rs-1.0
+ */
+
+/*******************************************************************************
+ Start of code based on MUSL
+*******************************************************************************/
+/*
+musl as a whole is licensed under the following standard MIT license:
+
+----------------------------------------------------------------------
+Copyright © 2005-2014 Rich Felker, et al.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+----------------------------------------------------------------------
+*/
+
+/* fpclassify */
+
+__CRT_INLINE int __cdecl __fpclassify (double x) {
+ union {double f; uint64_t i;} u = {x};
+ int e = u.i>>52 & 0x7ff;
+ if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
+ if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;
+ return FP_NORMAL;
+}
+
+__CRT_INLINE int __cdecl __fpclassifyf (float x) {
+ union {float f; uint32_t i;} u = {x};
+ int e = u.i>>23 & 0xff;
+ if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
+ if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;
+ return FP_NORMAL;
+}
+
+__CRT_INLINE int __cdecl __fpclassifyl (long double x) {
+ return __fpclassify(x);
+}
+
+
+/* signbit */
+
+__CRT_INLINE int __cdecl __signbit (double x) {
+ union {double d; uint64_t i;} y = { x };
+ return y.i>>63;
+}
+
+__CRT_INLINE int __cdecl __signbitf (float x) {
+ union {float f; uint32_t i; } y = { x };
+ return y.i>>31;
+}
+
+__CRT_INLINE int __cdecl __signbitl (long double x) {
+ return __signbit(x);
+}
+
+
+/* fmin*, fmax* */
+
+#define TCCFP_FMIN_EVAL (isnan(x) ? y : \
+ isnan(y) ? x : \
+ (signbit(x) != signbit(y)) ? (signbit(x) ? x : y) : \
+ x < y ? x : y)
+
+__CRT_INLINE double __cdecl fmin (double x, double y) {
+ return TCCFP_FMIN_EVAL;
+}
+
+__CRT_INLINE float __cdecl fminf (float x, float y) {
+ return TCCFP_FMIN_EVAL;
+}
+
+__CRT_INLINE long double __cdecl fminl (long double x, long double y) {
+ return TCCFP_FMIN_EVAL;
+}
+
+#define TCCFP_FMAX_EVAL (isnan(x) ? y : \
+ isnan(y) ? x : \
+ (signbit(x) != signbit(y)) ? (signbit(x) ? y : x) : \
+ x < y ? y : x)
+
+__CRT_INLINE double __cdecl fmax (double x, double y) {
+ return TCCFP_FMAX_EVAL;
+}
+
+__CRT_INLINE float __cdecl fmaxf (float x, float y) {
+ return TCCFP_FMAX_EVAL;
+}
+
+__CRT_INLINE long double __cdecl fmaxl (long double x, long double y) {
+ return TCCFP_FMAX_EVAL;
+}
+
+
+/* *round* */
+
+#define TCCFP_FORCE_EVAL(x) do { \
+if (sizeof(x) == sizeof(float)) { \
+ volatile float __x; \
+ __x = (x); \
+} else if (sizeof(x) == sizeof(double)) { \
+ volatile double __x; \
+ __x = (x); \
+} else { \
+ volatile long double __x; \
+ __x = (x); \
+} \
+} while(0)
+
+__CRT_INLINE double __cdecl round (double x) {
+ union {double f; uint64_t i;} u = {x};
+ int e = u.i >> 52 & 0x7ff;
+ double y;
+
+ if (e >= 0x3ff+52)
+ return x;
+ if (u.i >> 63)
+ x = -x;
+ if (e < 0x3ff-1) {
+ /* raise inexact if x!=0 */
+ TCCFP_FORCE_EVAL(x + 0x1p52);
+ return 0*u.f;
+ }
+ y = (double)(x + 0x1p52) - 0x1p52 - x;
+ if (y > 0.5)
+ y = y + x - 1;
+ else if (y <= -0.5)
+ y = y + x + 1;
+ else
+ y = y + x;
+ if (u.i >> 63)
+ y = -y;
+ return y;
+}
+
+__CRT_INLINE long __cdecl lround (double x) {
+ return round(x);
+}
+
+__CRT_INLINE long long __cdecl llround (double x) {
+ return round(x);
+}
+
+__CRT_INLINE float __cdecl roundf (float x) {
+ return round(x);
+}
+
+__CRT_INLINE long __cdecl lroundf (float x) {
+ return round(x);
+}
+
+__CRT_INLINE long long __cdecl llroundf (float x) {
+ return round(x);
+}
+
+__CRT_INLINE long double __cdecl roundl (long double x) {
+ return round(x);
+}
+
+__CRT_INLINE long __cdecl lroundl (long double x) {
+ return round(x);
+}
+
+__CRT_INLINE long long __cdecl llroundl (long double x) {
+ return round(x);
+}
+
+
+/*******************************************************************************
+ End of code based on MUSL
+*******************************************************************************/
+
+#endif /* _TCC_LIBM_H_ */
diff --git a/win32/include/tchar.h b/win32/include/tchar.h
new file mode 100644
index 0000000..cd44bec
--- /dev/null
+++ b/win32/include/tchar.h
@@ -0,0 +1,1102 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#include <_mingw.h>
+
+#ifndef _INC_TCHAR
+#define _INC_TCHAR
+
+#ifdef _STRSAFE_H_INCLUDED_
+#error Need to include strsafe.h after tchar.h
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _ftcscat _tcscat
+#define _ftcschr _tcschr
+#define _ftcscpy _tcscpy
+#define _ftcscspn _tcscspn
+#define _ftcslen _tcslen
+#define _ftcsncat _tcsncat
+#define _ftcsncpy _tcsncpy
+#define _ftcspbrk _tcspbrk
+#define _ftcsrchr _tcsrchr
+#define _ftcsspn _tcsspn
+#define _ftcsstr _tcsstr
+#define _ftcstok _tcstok
+
+#define _ftcsdup _tcsdup
+#define _ftcsnset _tcsnset
+#define _ftcsrev _tcsrev
+#define _ftcsset _tcsset
+
+#define _ftcscmp _tcscmp
+#define _ftcsicmp _tcsicmp
+#define _ftcsnccmp _tcsnccmp
+#define _ftcsncmp _tcsncmp
+#define _ftcsncicmp _tcsncicmp
+#define _ftcsnicmp _tcsnicmp
+
+#define _ftcscoll _tcscoll
+#define _ftcsicoll _tcsicoll
+#define _ftcsnccoll _tcsnccoll
+#define _ftcsncoll _tcsncoll
+#define _ftcsncicoll _tcsncicoll
+#define _ftcsnicoll _tcsnicoll
+
+#define _ftcsclen _tcsclen
+#define _ftcsnccat _tcsnccat
+#define _ftcsnccpy _tcsnccpy
+#define _ftcsncset _tcsncset
+
+#define _ftcsdec _tcsdec
+#define _ftcsinc _tcsinc
+#define _ftcsnbcnt _tcsnbcnt
+#define _ftcsnccnt _tcsnccnt
+#define _ftcsnextc _tcsnextc
+#define _ftcsninc _tcsninc
+#define _ftcsspnp _tcsspnp
+
+#define _ftcslwr _tcslwr
+#define _ftcsupr _tcsupr
+
+#define _ftclen _tclen
+#define _ftccpy _tccpy
+#define _ftccmp _tccmp
+
+#ifndef _CONST_RETURN
+#ifdef __cplusplus
+#define _CONST_RETURN const
+#define _CRT_CONST_CORRECT_OVERLOADS
+#else
+#define _CONST_RETURN
+#endif
+#endif
+
+#define _WConst_return _CONST_RETURN
+
+#ifdef _UNICODE
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <wchar.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _WCTYPE_T_DEFINED
+#define _WCTYPE_T_DEFINED
+ typedef unsigned short wint_t;
+ typedef unsigned short wctype_t;
+#endif
+
+#ifndef __TCHAR_DEFINED
+#define __TCHAR_DEFINED
+ typedef wchar_t _TCHAR;
+ typedef wchar_t _TSCHAR;
+ typedef wchar_t _TUCHAR;
+ typedef wchar_t _TXCHAR;
+ typedef wint_t _TINT;
+#endif
+
+#ifndef _TCHAR_DEFINED
+#define _TCHAR_DEFINED
+#ifndef NO_OLDNAMES
+ typedef wchar_t TCHAR;
+#endif
+#endif
+
+#define _TEOF WEOF
+
+#define __T(x) L##x
+
+#define _tmain wmain
+#define _tWinMain wWinMain
+#define _tenviron _wenviron
+#define __targv __wargv
+
+#define _tprintf wprintf
+#define _tprintf_l _wprintf_l
+#define _tprintf_p _wprintf_p
+#define _tprintf_p_l _wprintf_p_l
+#define _tcprintf _cwprintf
+#define _tcprintf_l _cwprintf_l
+#define _tcprintf_p _cwprintf_p
+#define _tcprintf_p_l _cwprintf_p_l
+#define _vtcprintf _vcwprintf
+#define _vtcprintf_l _vcwprintf_l
+#define _vtcprintf_p _vcwprintf_p
+#define _vtcprintf_p_l _vcwprintf_p_l
+#define _ftprintf fwprintf
+#define _ftprintf_l _fwprintf_l
+#define _ftprintf_p _fwprintf_p
+#define _ftprintf_p_l _fwprintf_p_l
+#define _stprintf swprintf
+#define _stprintf_l __swprintf_l
+#define _stprintf_p _swprintf_p
+#define _stprintf_p_l _swprintf_p_l
+#define _sctprintf _scwprintf
+#define _sctprintf_l _scwprintf_l
+#define _sctprintf_p _scwprintf_p
+#define _sctprintf_p_l _scwprintf_p_l
+#define _sntprintf _snwprintf
+#define _sntprintf_l _snwprintf_l
+#define _vtprintf vwprintf
+#define _vtprintf_l _vwprintf_l
+#define _vtprintf_p _vwprintf_p
+#define _vtprintf_p_l _vwprintf_p_l
+#define _vftprintf vfwprintf
+#define _vftprintf_l _vfwprintf_l
+#define _vftprintf_p _vfwprintf_p
+#define _vftprintf_p_l _vfwprintf_p_l
+#define _vstprintf vswprintf
+#define _vstprintf_l _vswprintf_l
+#define _vstprintf_p _vswprintf_p
+#define _vstprintf_p_l _vswprintf_p_l
+#define _vsctprintf _vscwprintf
+#define _vsctprintf_l _vscwprintf_l
+#define _vsctprintf_p _vscwprintf_p
+#define _vsctprintf_p_l _vscwprintf_p_l
+#define _vsntprintf _vsnwprintf
+#define _vsntprintf_l _vsnwprintf_l
+
+#define _tscanf wscanf
+#define _tscanf_l _wscanf_l
+#define _tcscanf _cwscanf
+#define _tcscanf_l _cwscanf_l
+#define _ftscanf fwscanf
+#define _ftscanf_l _fwscanf_l
+#define _stscanf swscanf
+#define _stscanf_l _swscanf_l
+#define _sntscanf _snwscanf
+#define _sntscanf_l _snwscanf_l
+
+#define _fgettc fgetwc
+#define _fgettc_nolock _fgetwc_nolock
+#define _fgettchar _fgetwchar
+#define _fgetts fgetws
+#define _fputtc fputwc
+#define _fputtc_nolock _fputwc_nolock
+#define _fputtchar _fputwchar
+#define _fputts fputws
+#define _cputts _cputws
+#define _cgetts _cgetws
+#define _gettc getwc
+#define _gettc_nolock _getwc_nolock
+#define _gettch _getwch
+#define _gettch_nolock _getwch_nolock
+#define _gettche _getwche
+#define _gettche_nolock _getwche_nolock
+#define _gettchar getwchar
+#define _gettchar_nolock _getwchar_nolock
+#define _getts _getws
+#define _puttc putwc
+#define _puttc_nolock _putwc_nolock
+#define _puttchar putwchar
+#define _puttchar_nolock _putwchar_nolock
+#define _puttch _putwch
+#define _puttch_nolock _putwch_nolock
+#define _putts _putws
+#define _ungettc ungetwc
+#define _ungettc_nolock _ungetwc_nolock
+#define _ungettch _ungetwch
+#define _ungettch_nolock _ungetwch_nolock
+
+#define _tcstod wcstod
+#define _tcstol wcstol
+#define _tcstoul wcstoul
+#define _tcstoi64 _wcstoi64
+#define _tcstoui64 _wcstoui64
+#define _tstof _wtof
+#define _tstol _wtol
+#define _tstoi _wtoi
+#define _tstoi64 _wtoi64
+#define _tcstod_l _wcstod_l
+#define _tcstol_l _wcstol_l
+#define _tcstoul_l _wcstoul_l
+#define _tcstoi64_l _wcstoi64_l
+#define _tcstoui64_l _wcstoui64_l
+#define _tstof_l _wtof_l
+#define _tstol_l _wtol_l
+#define _tstoi_l _wtoi_l
+#define _tstoi64_l _wtoi64_l
+
+#define _itot _itow
+#define _ltot _ltow
+#define _ultot _ultow
+#define _ttoi _wtoi
+#define _ttol _wtol
+
+#define _ttoi64 _wtoi64
+#define _i64tot _i64tow
+#define _ui64tot _ui64tow
+
+#define _tcscat wcscat
+#define _tcschr wcschr
+#define _tcscpy wcscpy
+#define _tcscspn wcscspn
+#define _tcslen wcslen
+#define _tcsnlen wcsnlen
+#define _tcsncat wcsncat
+#define _tcsncat_l _wcsncat_l
+#define _tcsncpy wcsncpy
+#define _tcsncpy_l _wcsncpy_l
+#define _tcspbrk wcspbrk
+#define _tcsrchr wcsrchr
+#define _tcsspn wcsspn
+#define _tcsstr wcsstr
+#define _tcstok wcstok
+#define _tcstok_l _wcstok_l
+#define _tcserror _wcserror
+#define __tcserror __wcserror
+
+#define _tcsdup _wcsdup
+#define _tcsnset _wcsnset
+#define _tcsnset_l _wcsnset_l
+#define _tcsrev _wcsrev
+#define _tcsset _wcsset
+#define _tcsset_l _wcsset_l
+
+#define _tcscmp wcscmp
+#define _tcsicmp _wcsicmp
+#define _tcsicmp_l _wcsicmp_l
+#define _tcsnccmp wcsncmp
+#define _tcsncmp wcsncmp
+#define _tcsncicmp _wcsnicmp
+#define _tcsncicmp_l _wcsnicmp_l
+#define _tcsnicmp _wcsnicmp
+#define _tcsnicmp_l _wcsnicmp_l
+
+#define _tcscoll wcscoll
+#define _tcscoll_l _wcscoll_l
+#define _tcsicoll _wcsicoll
+#define _tcsicoll_l _wcsicoll_l
+#define _tcsnccoll _wcsncoll
+#define _tcsnccoll_l _wcsncoll_l
+#define _tcsncoll _wcsncoll
+#define _tcsncoll_l _wcsncoll_l
+#define _tcsncicoll _wcsnicoll
+#define _tcsncicoll_l _wcsnicoll_l
+#define _tcsnicoll _wcsnicoll
+#define _tcsnicoll_l _wcsnicoll_l
+
+#define _texecl _wexecl
+#define _texecle _wexecle
+#define _texeclp _wexeclp
+#define _texeclpe _wexeclpe
+#define _texecv _wexecv
+#define _texecve _wexecve
+#define _texecvp _wexecvp
+#define _texecvpe _wexecvpe
+
+#define _tspawnl _wspawnl
+#define _tspawnle _wspawnle
+#define _tspawnlp _wspawnlp
+#define _tspawnlpe _wspawnlpe
+#define _tspawnv _wspawnv
+#define _tspawnve _wspawnve
+#define _tspawnvp _wspawnvp
+#define _tspawnvp _wspawnvp
+#define _tspawnvpe _wspawnvpe
+
+#define _tsystem _wsystem
+
+#define _tasctime _wasctime
+#define _tctime _wctime
+#define _tctime32 _wctime32
+#define _tctime64 _wctime64
+#define _tstrdate _wstrdate
+#define _tstrtime _wstrtime
+#define _tutime _wutime
+#define _tutime32 _wutime32
+#define _tutime64 _wutime64
+#define _tcsftime wcsftime
+#define _tcsftime_l _wcsftime_l
+
+#define _tchdir _wchdir
+#define _tgetcwd _wgetcwd
+#define _tgetdcwd _wgetdcwd
+#define _tgetdcwd_nolock _wgetdcwd_nolock
+#define _tmkdir _wmkdir
+#define _trmdir _wrmdir
+
+#define _tfullpath _wfullpath
+#define _tgetenv _wgetenv
+#define _tmakepath _wmakepath
+#define _tpgmptr _wpgmptr
+#define _get_tpgmptr _get_wpgmptr
+#define _tputenv _wputenv
+#define _tsearchenv _wsearchenv
+#define _tsplitpath _wsplitpath
+
+#define _tfdopen _wfdopen
+#define _tfsopen _wfsopen
+#define _tfopen _wfopen
+#define _tfreopen _wfreopen
+#define _tperror _wperror
+#define _tpopen _wpopen
+#define _ttempnam _wtempnam
+#define _ttmpnam _wtmpnam
+
+#define _taccess _waccess
+#define _tchmod _wchmod
+#define _tcreat _wcreat
+#define _tfindfirst _wfindfirst
+#define _tfindfirst32 _wfindfirst32
+#define _tfindfirst64 _wfindfirst64
+#define _tfindfirsti64 _wfindfirsti64
+#define _tfindfirst32i64 _wfindfirst32i64
+#define _tfindfirst64i32 _wfindfirst64i32
+#define _tfindnext _wfindnext
+#define _tfindnext32 _wfindnext32
+#define _tfindnext64 _wfindnext64
+#define _tfindnexti64 _wfindnexti64
+#define _tfindnext32i64 _wfindnext32i64
+#define _tfindnext64i32 _wfindnext64i32
+#define _tmktemp _wmktemp
+#define _topen _wopen
+#define _tremove _wremove
+#define _trename _wrename
+#define _tsopen _wsopen
+#define _tunlink _wunlink
+
+#define _tfinddata_t _wfinddata_t
+#define _tfinddata32_t _wfinddata32_t
+#define _tfinddata64_t _wfinddata64_t
+#define _tfinddatai64_t _wfinddatai64_t
+#define _tfinddata32i64_t _wfinddata32i64_t
+#define _tfinddata64i32_t _wfinddata64i32_t
+
+#define _tstat _wstat
+#define _tstat32 _wstat32
+#define _tstat32i64 _wstat32i64
+#define _tstat64 _wstat64
+#define _tstat64i32 _wstat64i32
+#define _tstati64 _wstati64
+
+#define _tsetlocale _wsetlocale
+
+#define _tcsclen wcslen
+#define _tcscnlen wcsnlen
+#define _tcsclen_l(_String,_Locale) wcslen(_String)
+#define _tcscnlen_l(_String,_Max_count,_Locale) wcsnlen_l((_String),(_Max_count))
+#define _tcsnccat wcsncat
+#define _tcsnccat_l _wcsncat_l
+#define _tcsnccpy wcsncpy
+#define _tcsnccpy_l _wcsncpy_l
+#define _tcsncset _wcsnset
+
+#define _tcsdec _wcsdec
+#define _tcsinc _wcsinc
+#define _tcsnbcnt _wcsncnt
+#define _tcsnccnt _wcsncnt
+#define _tcsnextc _wcsnextc
+#define _tcsninc _wcsninc
+#define _tcsspnp _wcsspnp
+
+#define _tcslwr _wcslwr
+#define _tcslwr_l _wcslwr_l
+#define _tcsupr _wcsupr
+#define _tcsupr_l _wcsupr_l
+#define _tcsxfrm wcsxfrm
+#define _tcsxfrm_l _wcsxfrm_l
+
+#define _tclen(_pc) (1)
+#define _tccpy(_pc1,_cpc2) ((*(_pc1) = *(_cpc2)))
+#define _tccmp(_cpc1,_cpc2) ((*(_cpc1))-(*(_cpc2)))
+
+#define _istalnum iswalnum
+#define _istalnum_l _iswalnum_l
+#define _istalpha iswalpha
+#define _istalpha_l _iswalpha_l
+#define _istascii iswascii
+#define _istcntrl iswcntrl
+#define _istcntrl_l _iswcntrl_l
+#define _istdigit iswdigit
+#define _istdigit_l _iswdigit_l
+#define _istgraph iswgraph
+#define _istgraph_l _iswgraph_l
+#define _istlower iswlower
+#define _istlower_l _iswlower_l
+#define _istprint iswprint
+#define _istprint_l _iswprint_l
+#define _istpunct iswpunct
+#define _istpunct_l _iswpunct_l
+#define _istspace iswspace
+#define _istspace_l _iswspace_l
+#define _istupper iswupper
+#define _istupper_l _iswupper_l
+#define _istxdigit iswxdigit
+#define _istxdigit_l _iswxdigit_l
+
+#define _totupper towupper
+#define _totupper_l _towupper_l
+#define _totlower towlower
+#define _totlower_l _towlower_l
+
+#define _istlegal(_Char) (1)
+#define _istlead(_Char) (0)
+#define _istleadbyte(_Char) (0)
+#define _istleadbyte_l(_Char,_Locale) (0)
+
+#define _wcsdec(_cpc1,_cpc2) ((_cpc1)>=(_cpc2) ? NULL : (_cpc2)-1)
+#define _wcsinc(_pc) ((_pc)+1)
+#define _wcsnextc(_cpc) ((unsigned int) *(_cpc))
+#define _wcsninc(_pc,_sz) (((_pc)+(_sz)))
+ _CRTIMP size_t __cdecl __wcsncnt(const wchar_t *_Str,size_t _MaxCount);
+#define _wcsncnt(_cpc,_sz) (__wcsncnt(_cpc,_sz))
+#define _wcsspnp(_cpc1,_cpc2) (!_cpc1 ? NULL : ((*((_cpc1)+wcsspn(_cpc1,_cpc2))) ? ((_cpc1)+wcsspn(_cpc1,_cpc2)) : NULL))
+#define _wcsncpy_l(_Destination,_Source,_Count,_Locale) (wcsncpy(_Destination,_Source,_Count))
+#define _wcsncat_l(_Destination,_Source,_Count,_Locale) (wcsncat(_Destination,_Source,_Count))
+#define _wcstok_l(_String,_Delimiters,_Locale) (wcstok(_String,_Delimiters))
+#define _wcsnset_l(_Destination,_Value,_Count,_Locale) (_wcsnset(_Destination,_Value,_Count))
+#define _wcsset_l(_Destination,_Value,_Locale) (_wcsset(_Destination,_Value))
+
+ /* dirent structures and functions */
+#define _tdirent _wdirent
+#define _TDIR _WDIR
+#define _topendir _wopendir
+#define _tclosedir _wclosedir
+#define _treaddir _wreaddir
+#define _trewinddir _wrewinddir
+#define _ttelldir _wtelldir
+#define _tseekdir _wseekdir
+
+#else
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _TEOF EOF
+
+#define __T(x) x
+
+#define _tmain main
+#define _tWinMain WinMain
+#ifdef _POSIX_
+#define _tenviron environ
+#else
+#define _tenviron _environ
+#endif
+#define __targv __argv
+
+#define _tprintf printf
+#define _tprintf_l _printf_l
+#define _tprintf_p _printf_p
+#define _tprintf_p_l _printf_p_l
+#define _tcprintf _cprintf
+#define _tcprintf_l _cprintf_l
+#define _tcprintf_p _cprintf_p
+#define _tcprintf_p_l _cprintf_p_l
+#define _vtcprintf _vcprintf
+#define _vtcprintf_l _vcprintf_l
+#define _vtcprintf_p _vcprintf_p
+#define _vtcprintf_p_l _vcprintf_p_l
+#define _ftprintf fprintf
+#define _ftprintf_l _fprintf_l
+#define _ftprintf_p _fprintf_p
+#define _ftprintf_p_l _fprintf_p_l
+#define _stprintf sprintf
+#define _stprintf_l _sprintf_l
+#define _stprintf_p _sprintf_p
+#define _stprintf_p_l _sprintf_p_l
+#define _sctprintf _scprintf
+#define _sctprintf_l _scprintf_l
+#define _sctprintf_p _scprintf_p
+#define _sctprintf_p_l _scprintf_p_l
+#define _sntprintf _snprintf
+#define _sntprintf_l _snprintf_l
+#define _vtprintf vprintf
+#define _vtprintf_l _vprintf_l
+#define _vtprintf_p _vprintf_p
+#define _vtprintf_p_l _vprintf_p_l
+#define _vftprintf vfprintf
+#define _vftprintf_l _vfprintf_l
+#define _vftprintf_p _vfprintf_p
+#define _vftprintf_p_l _vfprintf_p_l
+#define _vstprintf vsprintf
+#define _vstprintf_l _vsprintf_l
+#define _vstprintf_p _vsprintf_p
+#define _vstprintf_p_l _vsprintf_p_l
+#define _vsctprintf _vscprintf
+#define _vsctprintf_l _vscprintf_l
+#define _vsctprintf_p _vscprintf_p
+#define _vsctprintf_p_l _vscprintf_p_l
+#define _vsntprintf _vsnprintf
+#define _vsntprintf_l _vsnprintf_l
+
+#define _tscanf scanf
+#define _tscanf_l _scanf_l
+#define _tcscanf _cscanf
+#define _tcscanf_l _cscanf_l
+#define _ftscanf fscanf
+#define _ftscanf_l _fscanf_l
+#define _stscanf sscanf
+#define _stscanf_l _sscanf_l
+#define _sntscanf _snscanf
+#define _sntscanf_l _snscanf_l
+
+#define _fgettc fgetc
+#define _fgettc_nolock _fgetc_nolock
+#define _fgettchar _fgetchar
+#define _fgetts fgets
+#define _fputtc fputc
+#define _fputtc_nolock _fputc_nolock
+#define _fputtchar _fputchar
+#define _fputts fputs
+#define _cputts _cputs
+#define _gettc getc
+#define _gettc_nolock _getc_nolock
+#define _gettch _getch
+#define _gettch_nolock _getch_nolock
+#define _gettche _getche
+#define _gettche_nolock _getche_nolock
+#define _gettchar getchar
+#define _gettchar_nolock _getchar_nolock
+#define _getts gets
+#define _cgetts _cgets
+#define _puttc putc
+#define _puttc_nolock _putc_nolock
+#define _puttchar putchar
+#define _puttchar_nolock _putchar_nolock
+#define _puttch _putch
+#define _puttch_nolock _putch_nolock
+#define _putts puts
+#define _ungettc ungetc
+#define _ungettc_nolock _ungetc_nolock
+#define _ungettch _ungetch
+#define _ungettch_nolock _ungetch_nolock
+
+#define _tcstod strtod
+#define _tcstol strtol
+#define _tcstoul strtoul
+#define _tstof atof
+#define _tstol atol
+#define _tstoi atoi
+#define _tstoi64 _atoi64
+#define _tcstod_l _strtod_l
+#define _tcstol_l _strtol_l
+#define _tcstoul_l _strtoul_l
+#define _tstof_l _atof_l
+#define _tstol_l _atol_l
+#define _tstoi_l _atoi_l
+#define _tstoi64_l _atoi64_l
+
+#define _itot _itoa
+#define _ltot _ltoa
+#define _ultot _ultoa
+#define _ttoi atoi
+#define _ttol atol
+
+#define _ttoi64 _atoi64
+#define _tcstoi64 _strtoi64
+#define _tcstoi64_l _strtoi64_l
+#define _tcstoui64 _strtoui64
+#define _tcstoui64_l _strtoui64_l
+#define _i64tot _i64toa
+#define _ui64tot _ui64toa
+
+#define _tcscat strcat
+#define _tcscpy strcpy
+#define _tcsdup _strdup
+#define _tcslen strlen
+#if 0
+#define _tcsnlen strnlen
+#endif
+#define _tcsxfrm strxfrm
+#define _tcsxfrm_l _strxfrm_l
+#define _tcserror strerror
+#define __tcserror _strerror
+
+#define _texecl _execl
+#define _texecle _execle
+#define _texeclp _execlp
+#define _texeclpe _execlpe
+#define _texecv _execv
+#define _texecve _execve
+#define _texecvp _execvp
+#define _texecvpe _execvpe
+
+#define _tspawnl _spawnl
+#define _tspawnle _spawnle
+#define _tspawnlp _spawnlp
+#define _tspawnlpe _spawnlpe
+#define _tspawnv _spawnv
+#define _tspawnve _spawnve
+#define _tspawnvp _spawnvp
+#define _tspawnvpe _spawnvpe
+
+#define _tsystem system
+
+#define _tasctime asctime
+#define _tctime ctime
+#define _tctime32 _ctime32
+#define _tctime64 _ctime64
+#define _tstrdate _strdate
+#define _tstrtime _strtime
+#define _tutime _utime
+#define _tutime32 _utime32
+#define _tutime64 _utime64
+#define _tcsftime strftime
+#define _tcsftime_l _strftime_l
+
+#define _tchdir _chdir
+#define _tgetcwd _getcwd
+#define _tgetdcwd _getdcwd
+#define _tgetdcwd_nolock _getdcwd_nolock
+#define _tmkdir _mkdir
+#define _trmdir _rmdir
+
+#define _tfullpath _fullpath
+#define _tgetenv getenv
+#define _tmakepath _makepath
+#define _tpgmptr _pgmptr
+#define _get_tpgmptr _get_pgmptr
+#define _tputenv _putenv
+#define _tsearchenv _searchenv
+#define _tsplitpath _splitpath
+
+#ifdef _POSIX_
+#define _tfdopen fdopen
+#else
+#define _tfdopen _fdopen
+#endif
+#define _tfsopen _fsopen
+#define _tfopen fopen
+#define _tfreopen freopen
+#define _tperror perror
+#define _tpopen _popen
+#define _ttempnam _tempnam
+#define _ttmpnam tmpnam
+
+#define _tchmod _chmod
+#define _tcreat _creat
+#define _tfindfirst _findfirst
+#define _tfindfirst32 _findfirst32
+#define _tfindfirst64 _findfirst64
+#define _tfindfirsti64 _findfirsti64
+#define _tfindfirst32i64 _findfirst32i64
+#define _tfindfirst64i32 _findfirst64i32
+#define _tfindnext _findnext
+#define _tfindnext32 _findnext32
+#define _tfindnext64 _findnext64
+#define _tfindnexti64 _findnexti64
+#define _tfindnext32i64 _findnext32i64
+#define _tfindnext64i32 _findnext64i32
+#define _tmktemp _mktemp
+
+#ifdef _POSIX_
+#define _topen open
+#define _taccess access
+#else
+#define _topen _open
+#define _taccess _access
+#endif
+
+#define _tremove remove
+#define _trename rename
+#define _tsopen _sopen
+#define _tunlink _unlink
+
+#define _tfinddata_t _finddata_t
+#define _tfinddata32_t _finddata32_t
+#define _tfinddata64_t __finddata64_t
+#define _tfinddatai64_t _finddatai64_t
+#define _tfinddata32i64_t _finddata32i64_t
+#define _tfinddata64i32_t _finddata64i32_t
+
+#define _istascii __isascii
+#define _istcntrl iscntrl
+#define _istcntrl_l _iscntrl_l
+#define _istxdigit isxdigit
+#define _istxdigit_l _isxdigit_l
+
+#define _tstat _stat
+#define _tstat32 _stat32
+#define _tstat32i64 _stat32i64
+#define _tstat64 _stat64
+#define _tstat64i32 _stat64i32
+#define _tstati64 _stati64
+
+#define _tsetlocale setlocale
+
+#ifdef _MBCS
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <mbstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __TCHAR_DEFINED
+ typedef char _TCHAR;
+ typedef signed char _TSCHAR;
+ typedef unsigned char _TUCHAR;
+ typedef unsigned char _TXCHAR;
+ typedef unsigned int _TINT;
+#define __TCHAR_DEFINED
+#endif
+
+#ifndef _TCHAR_DEFINED
+#ifndef NO_OLDNAMES
+ typedef char TCHAR;
+#endif
+#define _TCHAR_DEFINED
+#endif
+
+#ifdef _MB_MAP_DIRECT
+
+#define _tcschr _mbschr
+#define _tcscspn _mbscspn
+#define _tcsncat _mbsnbcat
+#define _tcsncat_l _mbsnbcat_l
+#define _tcsncpy _mbsnbcpy
+#define _tcsncpy_l _mbsnbcpy_l
+#define _tcspbrk _mbspbrk
+#define _tcsrchr _mbsrchr
+#define _tcsspn _mbsspn
+#define _tcsstr _mbsstr
+#define _tcstok _mbstok
+#define _tcstok_l _mbstok_l
+
+#define _tcsnset _mbsnbset
+#define _tcsnset_l _mbsnbset_l
+#define _tcsrev _mbsrev
+#define _tcsset _mbsset
+#define _tcsset_l _mbsset_l
+
+#define _tcscmp _mbscmp
+#define _tcsicmp _mbsicmp
+#define _tcsicmp_l _mbsicmp_l
+#define _tcsnccmp _mbsncmp
+#define _tcsncmp _mbsnbcmp
+#define _tcsncicmp _mbsnicmp
+#define _tcsncicmp_l _mbsnicmp_l
+#define _tcsnicmp _mbsnbicmp
+#define _tcsnicmp_l _mbsnbicmp_l
+
+#define _tcscoll _mbscoll
+#define _tcscoll_l _mbscoll_l
+#define _tcsicoll _mbsicoll
+#define _tcsicoll_l _mbsicoll_l
+#define _tcsnccoll _mbsncoll
+#define _tcsnccoll_l _mbsncoll_l
+#define _tcsncoll _mbsnbcoll
+#define _tcsncoll_l _mbsnbcoll_l
+#define _tcsncicoll _mbsnicoll
+#define _tcsncicoll_l _mbsnicoll_l
+#define _tcsnicoll _mbsnbicoll
+#define _tcsnicoll_l _mbsnbicoll_l
+
+#define _tcsclen _mbslen
+#define _tcscnlen _mbsnlen
+#define _tcsclen_l _mbslen_l
+#define _tcscnlen_l _mbsnlen_l
+#define _tcsnccat _mbsncat
+#define _tcsnccat_l _mbsncat_l
+#define _tcsnccpy _mbsncpy
+#define _tcsnccpy_l _mbsncpy_l
+#define _tcsncset _mbsnset
+#define _tcsncset_l _mbsnset_l
+
+#define _tcsdec _mbsdec
+#define _tcsinc _mbsinc
+#define _tcsnbcnt _mbsnbcnt
+#define _tcsnccnt _mbsnccnt
+#define _tcsnextc _mbsnextc
+#define _tcsninc _mbsninc
+#define _tcsspnp _mbsspnp
+
+#define _tcslwr _mbslwr
+#define _tcslwr_l _mbslwr_l
+#define _tcsupr _mbsupr
+#define _tcsupr_l _mbsupr_l
+
+#define _tclen _mbclen
+#define _tccpy _mbccpy
+#define _tccpy_l _mbccpy_l
+#else
+
+ _CRTIMP _CONST_RETURN char *__cdecl _tcschr(const char *_Str,unsigned int _Val);
+ _CRTIMP size_t __cdecl _tcscspn(const char *_Str,const char *_Control);
+ _CRTIMP char *__cdecl _tcsncat(char *_Dst,const char *_Src,size_t _MaxCount);
+ _CRTIMP char *__cdecl _tcsncat_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcsncpy(char *_Dst,const char *_Src,size_t _MaxCount);
+ _CRTIMP char *__cdecl _tcsncpy_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP _CONST_RETURN char *__cdecl _tcspbrk(const char *_Str,const char *_Control);
+ _CRTIMP _CONST_RETURN char *__cdecl _tcsrchr(const char *_Str,unsigned int _Ch);
+ _CRTIMP size_t __cdecl _tcsspn(const char *_Str,const char *_Control);
+ _CRTIMP _CONST_RETURN char *__cdecl _tcsstr(const char *_Str,const char *_Substr);
+ _CRTIMP char *__cdecl _tcstok(char *_Str,const char *_Delim);
+ _CRTIMP char *__cdecl _tcstok_l(char *_Str,const char *_Delim,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcsnset(char *_Str,unsigned int _Val,size_t _MaxCount);
+ _CRTIMP char *__cdecl _tcsrev(char *_Str);
+ _CRTIMP char *__cdecl _tcsset(char *_Str,unsigned int _Val);
+ _CRTIMP char *__cdecl _tcsset_l(char *_Str,unsigned int _Val,_locale_t _Locale);
+ _CRTIMP int __cdecl _tcscmp(const char *_Str1,const char *_Str);
+ _CRTIMP int __cdecl _tcsicmp(const char *_Str1,const char *_Str2);
+ _CRTIMP int __cdecl _tcsicmp_l(const char *_Str1,const char *_Str2,_locale_t _Locale);
+ _CRTIMP int __cdecl _tcsnccmp(const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _tcsncmp(const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _tcsncicmp(const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _tcsncicmp_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP int __cdecl _tcsnicmp(const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _tcsnicmp_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP int __cdecl _tcscoll(const char *_Str1,const char *_Str2);
+ _CRTIMP int __cdecl _tcscoll_l(const char *_Str1,const char *_Str2,_locale_t _Locale);
+ _CRTIMP int __cdecl _tcsicoll(const char *_Str1,const char *_Str2);
+ _CRTIMP int __cdecl _tcsicoll_l(const char *_Str1,const char *_Str2,_locale_t _Locale);
+ _CRTIMP int __cdecl _tcsnccoll(const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _tcsnccoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP int __cdecl _tcsncoll(const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _tcsncoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP int __cdecl _tcsncicoll(const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _tcsncicoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP int __cdecl _tcsnicoll(const char *_Str1,const char *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _tcsnicoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP size_t __cdecl _tcsclen(const char *_Str);
+ _CRTIMP size_t __cdecl _tcscnlen(const char *_Str,size_t _MaxCount);
+ _CRTIMP size_t __cdecl _tcsclen_l(const char *_Str,_locale_t _Locale);
+ _CRTIMP size_t __cdecl _tcscnlen_l(const char *_Str,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcsnccat(char *_Dst,const char *_Src,size_t _MaxCount);
+ _CRTIMP char *__cdecl _tcsnccat_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcsnccpy(char *_Dst,const char *_Src,size_t _MaxCount);
+ _CRTIMP char *__cdecl _tcsnccpy_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcsncset(char *_Str,unsigned int _Val,size_t _MaxCount);
+ _CRTIMP char *__cdecl _tcsdec(const char *_Start,const char *_Pos);
+ _CRTIMP char *__cdecl _tcsinc(const char *_Ptr);
+ _CRTIMP size_t __cdecl _tcsnbcnt(const char *_Str,size_t _MaxCount);
+ _CRTIMP size_t __cdecl _tcsnccnt(const char *_Str,size_t _MaxCount);
+ _CRTIMP unsigned int __cdecl _tcsnextc (const char *_Str);
+ _CRTIMP char *__cdecl _tcsninc(const char *_Ptr,size_t _Count);
+ _CRTIMP char *__cdecl _tcsspnp(const char *_Str1,const char *_Str2);
+ _CRTIMP char *__cdecl _tcslwr(char *_Str);
+ _CRTIMP char *__cdecl _tcslwr_l(char *_Str,_locale_t _Locale);
+ _CRTIMP char *__cdecl _tcsupr(char *_Str);
+ _CRTIMP char *__cdecl _tcsupr_l(char *_Str,_locale_t _Locale);
+ _CRTIMP size_t __cdecl _tclen(const char *_Str);
+ _CRTIMP void __cdecl _tccpy(char *_DstCh,const char *_SrcCh);
+
+#ifdef __cplusplus
+#ifndef _CPP_TCHAR_INLINES_DEFINED
+#define _CPP_TCHAR_INLINES_DEFINED
+ extern "C++" {
+ extern inline char *__cdecl _tcschr(char *_S,unsigned int _C) { return ((char *)_tcschr((const char *)_S,_C)); }
+ extern inline char *__cdecl _tcspbrk(char *_S,const char *_P) { return ((char *)_tcspbrk((const char *)_S,_P)); }
+ extern inline char *__cdecl _tcsrchr(char *_S,unsigned int _C) { return ((char *)_tcsrchr((const char *)_S,_C)); }
+ extern inline char *__cdecl _tcsstr(char *_S,const char *_P) { return ((char *)_tcsstr((const char *)_S,_P)); }
+ }
+#endif
+#endif
+#endif
+
+#define _tccmp(_cp1,_cp2) _tcsnccmp(_cp1,_cp2,1)
+
+#define _istalnum _ismbcalnum
+#define _istalnum_l _ismbcalnum_l
+#define _istalpha _ismbcalpha
+#define _istalpha_l _ismbcalpha_l
+#define _istdigit _ismbcdigit
+#define _istdigit_l _ismbcdigit_l
+#define _istgraph _ismbcgraph
+#define _istgraph_l _ismbcgraph_l
+#define _istlegal _ismbclegal
+#define _istlegal_l _ismbclegal_l
+#define _istlower _ismbclower
+#define _istlower_l _ismbclower_l
+#define _istprint _ismbcprint
+#define _istprint_l _ismbcprint_l
+#define _istpunct _ismbcpunct
+#define _istpunct_l _ismbcpunct_l
+#define _istspace _ismbcspace
+#define _istspace_l _ismbcspace_l
+#define _istupper _ismbcupper
+#define _istupper_l _ismbcupper_l
+
+#define _totupper _mbctoupper
+#define _totupper_l _mbctoupper_l
+#define _totlower _mbctolower
+#define _totlower_l _mbctolower_l
+
+#define _istlead _ismbblead
+#define _istleadbyte isleadbyte
+#define _istleadbyte_l _isleadbyte_l
+#else
+
+#ifndef __TCHAR_DEFINED
+#define __TCHAR_DEFINED
+ typedef char _TCHAR;
+ typedef signed char _TSCHAR;
+ typedef unsigned char _TUCHAR;
+ typedef char _TXCHAR;
+ typedef int _TINT;
+#endif
+
+#ifndef _TCHAR_DEFINED
+#define _TCHAR_DEFINED
+#ifndef NO_OLDNAMES
+ typedef char TCHAR;
+#endif
+#endif
+
+#define _tcschr strchr
+#define _tcscspn strcspn
+#define _tcsncat strncat
+#define _tcsncat_l _strncat_l
+#define _tcsncpy strncpy
+#define _tcsncpy_l _strncpy_l
+#define _tcspbrk strpbrk
+#define _tcsrchr strrchr
+#define _tcsspn strspn
+#define _tcsstr strstr
+#define _tcstok strtok
+#define _tcstok_l _strtok_l
+
+#define _tcsnset _strnset
+#define _tcsnset_l _strnset_l
+#define _tcsrev _strrev
+#define _tcsset _strset
+
+#define _tcscmp strcmp
+#define _tcsicmp _stricmp
+#define _tcsicmp_l _stricmp_l
+#define _tcsnccmp strncmp
+#define _tcsncmp strncmp
+#define _tcsncicmp _strnicmp
+#define _tcsncicmp_l _strnicmp_l
+#define _tcsnicmp _strnicmp
+#define _tcsnicmp_l _strnicmp_l
+
+#define _tcscoll strcoll
+#define _tcscoll_l _strcoll_l
+#define _tcsicoll _stricoll
+#define _tcsicoll_l _stricoll_l
+#define _tcsnccoll _strncoll
+#define _tcsnccoll_l _strncoll_l
+#define _tcsncoll _strncoll
+#define _tcsncoll_l _strncoll_l
+#define _tcsncicoll _strnicoll
+#define _tcsncicoll_l _strnicoll_l
+#define _tcsnicoll _strnicoll
+#define _tcsnicoll_l _strnicoll_l
+
+#define _tcsclen strlen
+#define _tcscnlen strnlen
+#define _tcsclen_l(_String,_Locale) strlen(_String)
+#define _tcscnlen_l(_String,_Max_count,_Locale) strnlen_l((_String),(_Max_count))
+#define _tcsnccat strncat
+#define _tcsnccat_l _strncat_l
+#define _tcsnccpy strncpy
+#define _tcsnccpy_l _strncpy_l
+#define _tcsncset _strnset
+
+#define _tcsdec _strdec
+#define _tcsinc _strinc
+#define _tcsnbcnt _strncnt
+#define _tcsnccnt _strncnt
+#define _tcsnextc _strnextc
+#define _tcsninc _strninc
+#define _tcsspnp _strspnp
+
+#define _tcslwr _strlwr
+#define _tcslwr_l _strlwr_l
+#define _tcsupr _strupr
+#define _tcsupr_l _strupr_l
+#define _tcsxfrm strxfrm
+#define _tcsxfrm_l _strxfrm_l
+
+#define _istlead(_Char) (0)
+#define _istleadbyte(_Char) (0)
+#define _istleadbyte_l(_Char,_Locale) (0)
+
+#define _tclen(_pc) (1)
+#define _tccpy(_pc1,_cpc2) (*(_pc1) = *(_cpc2))
+#define _tccmp(_cpc1,_cpc2) (((unsigned char)*(_cpc1))-((unsigned char)*(_cpc2)))
+
+ /* dirent structures and functions */
+#define _tdirent dirent
+#define _TDIR DIR
+#define _topendir opendir
+#define _tclosedir closedir
+#define _treaddir readdir
+#define _trewinddir rewinddir
+#define _ttelldir telldir
+#define _tseekdir seekdir
+
+#define _istalnum isalnum
+#define _istalnum_l _isalnum_l
+#define _istalpha isalpha
+#define _istalpha_l _isalpha_l
+#define _istdigit isdigit
+#define _istdigit_l _isdigit_l
+#define _istgraph isgraph
+#define _istgraph_l _isgraph_l
+#define _istlower islower
+#define _istlower_l _islower_l
+#define _istprint isprint
+#define _istprint_l _isprint_l
+#define _istpunct ispunct
+#define _istpunct_l _ispunct_l
+#define _istspace isspace
+#define _istspace_l _isspace_l
+#define _istupper isupper
+#define _istupper_l _isupper_l
+
+#define _totupper toupper
+#define _totupper_l _toupper_l
+#define _totlower tolower
+#define _totlower_l _tolower_l
+
+#define _istlegal(_c) (1)
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#define _strdec(_cpc1,_cpc2) ((_cpc1)>=(_cpc2) ? NULL : (_cpc2)-1)
+#define _strinc(_pc) ((_pc)+1)
+#define _strnextc(_cpc) ((unsigned int) *(const unsigned char *)(_cpc))
+#define _strninc(_pc,_sz) (((_pc)+(_sz)))
+ _CRTIMP size_t __cdecl __strncnt(const char *_Str,size_t _Cnt);
+#define _strncnt(_cpc,_sz) (__strncnt(_cpc,_sz))
+#define _strspnp(_cpc1,_cpc2) (!_cpc1 ? NULL : ((*((_cpc1)+strspn(_cpc1,_cpc2))) ? ((_cpc1)+strspn(_cpc1,_cpc2)) : NULL))
+
+#define _strncpy_l(_Destination,_Source,_Count,_Locale) (strncpy(_Destination,_Source,_Count))
+#define _strncat_l(_Destination,_Source,_Count,_Locale) (strncat(_Destination,_Source,_Count))
+#define _strtok_l(_String,_Delimiters,_Locale) (strtok(_String,_Delimiters))
+#define _strnset_l(_Destination,_Value,_Count,_Locale) (_strnset(_Destination,_Value,_Count))
+#define _strset_l(_Destination,_Value,_Locale) (_strset(_Destination,_Value))
+#endif
+#endif
+
+#define _T(x) __T(x)
+#define _TEXT(x) __T(x)
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <sec_api/tchar_s.h>
+#endif
diff --git a/win32/include/time.h b/win32/include/time.h
new file mode 100644
index 0000000..6c72e26
--- /dev/null
+++ b/win32/include/time.h
@@ -0,0 +1,287 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _TIME_H_
+#define _TIME_H_
+
+#include <_mingw.h>
+
+#ifndef _WIN32
+#error Only Win32 target is supported!
+#endif
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _CRTIMP
+#define _CRTIMP __declspec(dllimport)
+#endif
+
+#ifndef _WCHAR_T_DEFINED
+#define _WCHAR_T_DEFINED
+ typedef unsigned short wchar_t;
+#endif
+
+#ifndef _TIME32_T_DEFINED
+#define _TIME32_T_DEFINED
+ typedef long __time32_t;
+#endif
+
+#ifndef _TIME64_T_DEFINED
+#define _TIME64_T_DEFINED
+#if _INTEGRAL_MAX_BITS >= 64
+#if defined(__GNUC__) && defined(__STRICT_ANSI__)
+ typedef int _time64_t __attribute__ ((mode (DI)));
+#else
+ typedef __int64 __time64_t;
+#endif
+#endif
+#endif
+
+#ifndef _TIME_T_DEFINED
+#define _TIME_T_DEFINED
+#ifdef _USE_32BIT_TIME_T
+ typedef __time32_t time_t;
+#else
+ typedef __time64_t time_t;
+#endif
+#endif
+
+#ifndef _CLOCK_T_DEFINED
+#define _CLOCK_T_DEFINED
+ typedef long clock_t;
+#endif
+
+#ifndef _SIZE_T_DEFINED
+#define _SIZE_T_DEFINED
+#undef size_t
+#ifdef _WIN64
+#if defined(__GNUC__) && defined(__STRICT_ANSI__)
+ typedef unsigned int size_t __attribute__ ((mode (DI)));
+#else
+ typedef unsigned __int64 size_t;
+#endif
+#else
+ typedef unsigned int size_t;
+#endif
+#endif
+
+#ifndef _SSIZE_T_DEFINED
+#define _SSIZE_T_DEFINED
+#undef ssize_t
+#ifdef _WIN64
+#if defined(__GNUC__) && defined(__STRICT_ANSI__)
+ typedef int ssize_t __attribute__ ((mode (DI)));
+#else
+ typedef __int64 ssize_t;
+#endif
+#else
+ typedef int ssize_t;
+#endif
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#ifdef _USE_32BIT_TIME_T
+#define _localtime32 localtime
+#define _difftime32 difftime
+#define _ctime32 ctime
+#define _gmtime32 gmtime
+#define _mktime32 mktime
+#define _time32 time
+#endif
+
+#ifndef _TM_DEFINED
+#define _TM_DEFINED
+ struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ };
+#endif
+
+#define CLOCKS_PER_SEC 1000
+
+ __MINGW_IMPORT int _daylight;
+ __MINGW_IMPORT long _dstbias;
+ __MINGW_IMPORT long _timezone;
+ __MINGW_IMPORT char * _tzname[2];
+ _CRTIMP errno_t __cdecl _get_daylight(int *_Daylight);
+ _CRTIMP errno_t __cdecl _get_dstbias(long *_Daylight_savings_bias);
+ _CRTIMP errno_t __cdecl _get_timezone(long *_Timezone);
+ _CRTIMP errno_t __cdecl _get_tzname(size_t *_ReturnValue,char *_Buffer,size_t _SizeInBytes,int _Index);
+ char *__cdecl asctime(const struct tm *_Tm);
+ _CRTIMP char *__cdecl _ctime32(const __time32_t *_Time);
+ clock_t __cdecl clock(void);
+ _CRTIMP double __cdecl _difftime32(__time32_t _Time1,__time32_t _Time2);
+ _CRTIMP struct tm *__cdecl _gmtime32(const __time32_t *_Time);
+ _CRTIMP struct tm *__cdecl _localtime32(const __time32_t *_Time);
+ size_t __cdecl strftime(char *_Buf,size_t _SizeInBytes,const char *_Format,const struct tm *_Tm);
+ _CRTIMP size_t __cdecl _strftime_l(char *_Buf,size_t _Max_size,const char *_Format,const struct tm *_Tm,_locale_t _Locale);
+ _CRTIMP char *__cdecl _strdate(char *_Buffer);
+ _CRTIMP char *__cdecl _strtime(char *_Buffer);
+ _CRTIMP __time32_t __cdecl _time32(__time32_t *_Time);
+ _CRTIMP __time32_t __cdecl _mktime32(struct tm *_Tm);
+ _CRTIMP __time32_t __cdecl _mkgmtime32(struct tm *_Tm);
+#if defined (_POSIX_) || defined(__GNUC__)
+ void __cdecl tzset(void);
+#else
+ _CRTIMP void __cdecl _tzset(void);
+#endif
+
+#if _INTEGRAL_MAX_BITS >= 64
+ double __cdecl _difftime64(__time64_t _Time1,__time64_t _Time2);
+ _CRTIMP char *__cdecl _ctime64(const __time64_t *_Time);
+ _CRTIMP struct tm *__cdecl _gmtime64(const __time64_t *_Time);
+ _CRTIMP struct tm *__cdecl _localtime64(const __time64_t *_Time);
+ _CRTIMP __time64_t __cdecl _mktime64(struct tm *_Tm);
+ _CRTIMP __time64_t __cdecl _mkgmtime64(struct tm *_Tm);
+ _CRTIMP __time64_t __cdecl _time64(__time64_t *_Time);
+#endif
+ unsigned __cdecl _getsystime(struct tm *_Tm);
+ unsigned __cdecl _setsystime(struct tm *_Tm,unsigned _MilliSec);
+
+#ifndef _SIZE_T_DEFINED
+#define _SIZE_T_DEFINED
+#ifdef _WIN64
+#if defined(__GNUC__) && defined(__STRICT_ANSI__)
+ typedef unsigned int size_t __attribute__ ((mode (DI)));
+#else
+ typedef unsigned __int64 size_t;
+#endif
+#else
+ typedef unsigned long size_t;
+#endif
+#endif
+
+#ifndef _SSIZE_T_DEFINED
+#define _SSIZE_T_DEFINED
+#ifdef _WIN64
+#if defined(__GNUC__) && defined(__STRICT_ANSI__)
+ typedef int ssize_t __attribute__ ((mode (DI)));
+#else
+ typedef __int64 ssize_t;
+#endif
+#else
+ typedef long ssize_t;
+#endif
+#endif
+
+#ifndef _WTIME_DEFINED
+ _CRTIMP wchar_t *__cdecl _wasctime(const struct tm *_Tm);
+ _CRTIMP wchar_t *__cdecl _wctime32(const __time32_t *_Time);
+ size_t __cdecl wcsftime(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm);
+ _CRTIMP size_t __cdecl _wcsftime_l(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm,_locale_t _Locale);
+ _CRTIMP wchar_t *__cdecl _wstrdate(wchar_t *_Buffer);
+ _CRTIMP wchar_t *__cdecl _wstrtime(wchar_t *_Buffer);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP wchar_t *__cdecl _wctime64(const __time64_t *_Time);
+#endif
+
+#if !defined (RC_INVOKED) && !defined (_INC_WTIME_INL)
+#define _INC_WTIME_INL
+#ifdef _USE_32BIT_TIME_T
+__CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime32(_Time); }
+#else
+__CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime64(_Time); }
+#endif
+#endif
+
+#define _WTIME_DEFINED
+#endif
+
+#ifndef RC_INVOKED
+double __cdecl difftime(time_t _Time1,time_t _Time2);
+char *__cdecl ctime(const time_t *_Time);
+struct tm *__cdecl gmtime(const time_t *_Time);
+struct tm *__cdecl localtime(const time_t *_Time);
+struct tm *__cdecl localtime_r(const time_t *_Time,struct tm *);
+
+time_t __cdecl mktime(struct tm *_Tm);
+time_t __cdecl _mkgmtime(struct tm *_Tm);
+time_t __cdecl time(time_t *_Time);
+
+#ifdef _USE_32BIT_TIME_T
+#if 0
+__CRT_INLINE double __cdecl difftime(time_t _Time1,time_t _Time2) { return _difftime32(_Time1,_Time2); }
+__CRT_INLINE char *__cdecl ctime(const time_t *_Time) { return _ctime32(_Time); }
+__CRT_INLINE struct tm *__cdecl gmtime(const time_t *_Time) { return _gmtime32(_Time); }
+__CRT_INLINE struct tm *__cdecl localtime(const time_t *_Time) { return _localtime32(_Time); }
+__CRT_INLINE time_t __cdecl mktime(struct tm *_Tm) { return _mktime32(_Tm); }
+__CRT_INLINE time_t __cdecl _mkgmtime(struct tm *_Tm) { return _mkgmtime32(_Tm); }
+__CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time32(_Time); }
+#endif
+#else
+__CRT_INLINE double __cdecl difftime(time_t _Time1,time_t _Time2) { return _difftime64(_Time1,_Time2); }
+__CRT_INLINE char *__cdecl ctime(const time_t *_Time) { return _ctime64(_Time); }
+__CRT_INLINE struct tm *__cdecl gmtime(const time_t *_Time) { return _gmtime64(_Time); }
+__CRT_INLINE struct tm *__cdecl localtime(const time_t *_Time) { return _localtime64(_Time); }
+__CRT_INLINE time_t __cdecl mktime(struct tm *_Tm) { return _mktime64(_Tm); }
+__CRT_INLINE time_t __cdecl _mkgmtime(struct tm *_Tm) { return _mkgmtime64(_Tm); }
+__CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time64(_Time); }
+#endif
+#endif
+
+#if !defined(NO_OLDNAMES) || defined(_POSIX)
+#define CLK_TCK CLOCKS_PER_SEC
+
+ __MINGW_IMPORT int daylight;
+ __MINGW_IMPORT long dstbias;
+ __MINGW_IMPORT long timezone;
+ __MINGW_IMPORT char *tzname[2];
+ void __cdecl tzset(void);
+#endif
+
+#ifndef _TIMEVAL_DEFINED /* also in winsock[2].h */
+#define _TIMEVAL_DEFINED
+struct timeval {
+ long tv_sec;
+ long tv_usec;
+};
+#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
+#define timercmp(tvp,uvp,cmp) ((tvp)->tv_sec cmp (uvp)->tv_sec || (tvp)->tv_sec==(uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
+#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
+#endif /* _TIMEVAL_DEFINED */
+
+#ifndef __STRICT_ANSI__
+#ifndef _TIMEZONE_DEFINED /* also in sys/time.h */
+#define _TIMEZONE_DEFINED
+struct timezone {
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+
+ extern int __cdecl mingw_gettimeofday (struct timeval *p, struct timezone *z);
+#endif
+#endif /* __STRICT_ANSI__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+
+#include <sec_api/time_s.h>
+
+/* Adding timespec definition. */
+#include <sys/timeb.h>
+
+#endif /* End _TIME_H_ */
+
diff --git a/win32/include/vadefs.h b/win32/include/vadefs.h
new file mode 100644
index 0000000..749b0bd
--- /dev/null
+++ b/win32/include/vadefs.h
@@ -0,0 +1,11 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_VADEFS
+#define _INC_VADEFS
+
+//!__TINYC__: GNUC specific stuff removed
+
+#endif
diff --git a/win32/include/values.h b/win32/include/values.h
new file mode 100644
index 0000000..1cd643c
--- /dev/null
+++ b/win32/include/values.h
@@ -0,0 +1,4 @@
+/*
+ * TODO: Nothing here yet. Should provide UNIX compatibility constants
+ * comparable to those in limits.h and float.h.
+ */
diff --git a/win32/include/wchar.h b/win32/include/wchar.h
new file mode 100644
index 0000000..389196f
--- /dev/null
+++ b/win32/include/wchar.h
@@ -0,0 +1,873 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_WCHAR
+#define _INC_WCHAR
+
+#include <_mingw.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WCHAR_MIN /* also at stdint.h */
+#define WCHAR_MIN 0
+#define WCHAR_MAX ((wchar_t) -1) /* UINT16_MAX */
+#endif
+
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+ typedef __builtin_va_list __gnuc_va_list;
+#endif
+
+#ifndef _VA_LIST_DEFINED
+#define _VA_LIST_DEFINED
+ typedef __gnuc_va_list va_list;
+#endif
+
+#ifndef WEOF
+#define WEOF (wint_t)(0xFFFF)
+#endif
+
+#ifndef _FILE_DEFINED
+ struct _iobuf {
+ char *_ptr;
+ int _cnt;
+ char *_base;
+ int _flag;
+ int _file;
+ int _charbuf;
+ int _bufsiz;
+ char *_tmpfname;
+ };
+ typedef struct _iobuf FILE;
+#define _FILE_DEFINED
+#endif
+
+#ifndef _STDIO_DEFINED
+#ifdef _WIN64
+ _CRTIMP FILE *__cdecl __iob_func(void);
+#else
+#ifdef _MSVCRT_
+extern FILE _iob[]; /* A pointer to an array of FILE */
+#define __iob_func() (_iob)
+#else
+extern FILE (*_imp___iob)[]; /* A pointer to an array of FILE */
+#define __iob_func() (*_imp___iob)
+#define _iob __iob_func()
+#endif
+#endif
+
+#define _iob __iob_func()
+#endif
+
+#ifndef _STDSTREAM_DEFINED
+#define stdin (&__iob_func()[0])
+#define stdout (&__iob_func()[1])
+#define stderr (&__iob_func()[2])
+#define _STDSTREAM_DEFINED
+#endif
+
+#ifndef _FSIZE_T_DEFINED
+ typedef unsigned long _fsize_t;
+#define _FSIZE_T_DEFINED
+#endif
+
+#ifndef _WFINDDATA_T_DEFINED
+ struct _wfinddata32_t {
+ unsigned attrib;
+ __time32_t time_create;
+ __time32_t time_access;
+ __time32_t time_write;
+ _fsize_t size;
+ wchar_t name[260];
+ };
+
+/* #if _INTEGRAL_MAX_BITS >= 64 */
+
+ struct _wfinddata32i64_t {
+ unsigned attrib;
+ __time32_t time_create;
+ __time32_t time_access;
+ __time32_t time_write;
+ __int64 size;
+ wchar_t name[260];
+ };
+
+ struct _wfinddata64i32_t {
+ unsigned attrib;
+ __time64_t time_create;
+ __time64_t time_access;
+ __time64_t time_write;
+ _fsize_t size;
+ wchar_t name[260];
+ };
+
+ struct _wfinddata64_t {
+ unsigned attrib;
+ __time64_t time_create;
+ __time64_t time_access;
+ __time64_t time_write;
+ __int64 size;
+ wchar_t name[260];
+ };
+/* #endif */
+
+#ifdef _USE_32BIT_TIME_T
+#define _wfinddata_t _wfinddata32_t
+#define _wfinddatai64_t _wfinddata32i64_t
+
+#define _wfindfirst _wfindfirst32
+#define _wfindnext _wfindnext32
+#define _wfindfirsti64 _wfindfirst32i64
+#define _wfindnexti64 _wfindnext32i64
+#else
+#define _wfinddata_t _wfinddata64i32_t
+#define _wfinddatai64_t _wfinddata64_t
+
+#define _wfindfirst _wfindfirst64i32
+#define _wfindnext _wfindnext64i32
+#define _wfindfirsti64 _wfindfirst64
+#define _wfindnexti64 _wfindnext64
+#endif
+
+#define _WFINDDATA_T_DEFINED
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#ifndef _CONST_RETURN
+#define _CONST_RETURN
+#endif
+
+#define _WConst_return _CONST_RETURN
+
+#ifndef _CRT_CTYPEDATA_DEFINED
+#define _CRT_CTYPEDATA_DEFINED
+#ifndef _CTYPE_DISABLE_MACROS
+
+#ifndef __PCTYPE_FUNC
+#define __PCTYPE_FUNC __pctype_func()
+#ifdef _MSVCRT_
+#define __pctype_func() (_pctype)
+#else
+#define __pctype_func() (*_imp___pctype)
+#endif
+#endif
+
+#ifndef _pctype
+#ifdef _MSVCRT_
+ extern unsigned short *_pctype;
+#else
+ extern unsigned short **_imp___pctype;
+#define _pctype (*_imp___pctype)
+#endif
+#endif
+#endif
+#endif
+
+#ifndef _CRT_WCTYPEDATA_DEFINED
+#define _CRT_WCTYPEDATA_DEFINED
+#ifndef _CTYPE_DISABLE_MACROS
+#ifndef _wctype
+#ifdef _MSVCRT_
+ extern unsigned short *_wctype;
+#else
+ extern unsigned short **_imp___wctype;
+#define _wctype (*_imp___wctype)
+#endif
+#endif
+
+#ifdef _MSVCRT_
+#define __pwctype_func() (_pwctype)
+#else
+#define __pwctype_func() (*_imp___pwctype)
+#endif
+
+#ifndef _pwctype
+#ifdef _MSVCRT_
+ extern unsigned short *_pwctype;
+#else
+ extern unsigned short **_imp___pwctype;
+#define _pwctype (*_imp___pwctype)
+#endif
+#endif
+
+#endif
+#endif
+
+#define _UPPER 0x1
+#define _LOWER 0x2
+#define _DIGIT 0x4
+#define _SPACE 0x8
+
+#define _PUNCT 0x10
+#define _CONTROL 0x20
+#define _BLANK 0x40
+#define _HEX 0x80
+
+#define _LEADBYTE 0x8000
+#define _ALPHA (0x0100|_UPPER|_LOWER)
+
+#ifndef _WCTYPE_DEFINED
+#define _WCTYPE_DEFINED
+
+ int __cdecl iswalpha(wint_t _C);
+ _CRTIMP int __cdecl _iswalpha_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswupper(wint_t _C);
+ _CRTIMP int __cdecl _iswupper_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswlower(wint_t _C);
+ _CRTIMP int __cdecl _iswlower_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswdigit(wint_t _C);
+ _CRTIMP int __cdecl _iswdigit_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswxdigit(wint_t _C);
+ _CRTIMP int __cdecl _iswxdigit_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswspace(wint_t _C);
+ _CRTIMP int __cdecl _iswspace_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswpunct(wint_t _C);
+ _CRTIMP int __cdecl _iswpunct_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswalnum(wint_t _C);
+ _CRTIMP int __cdecl _iswalnum_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswprint(wint_t _C);
+ _CRTIMP int __cdecl _iswprint_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswgraph(wint_t _C);
+ _CRTIMP int __cdecl _iswgraph_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswcntrl(wint_t _C);
+ _CRTIMP int __cdecl _iswcntrl_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswascii(wint_t _C);
+ int __cdecl isleadbyte(int _C);
+ _CRTIMP int __cdecl _isleadbyte_l(int _C,_locale_t _Locale);
+ wint_t __cdecl towupper(wint_t _C);
+ _CRTIMP wint_t __cdecl _towupper_l(wint_t _C,_locale_t _Locale);
+ wint_t __cdecl towlower(wint_t _C);
+ _CRTIMP wint_t __cdecl _towlower_l(wint_t _C,_locale_t _Locale);
+ int __cdecl iswctype(wint_t _C,wctype_t _Type);
+ _CRTIMP int __cdecl _iswctype_l(wint_t _C,wctype_t _Type,_locale_t _Locale);
+ _CRTIMP int __cdecl __iswcsymf(wint_t _C);
+ _CRTIMP int __cdecl _iswcsymf_l(wint_t _C,_locale_t _Locale);
+ _CRTIMP int __cdecl __iswcsym(wint_t _C);
+ _CRTIMP int __cdecl _iswcsym_l(wint_t _C,_locale_t _Locale);
+ int __cdecl is_wctype(wint_t _C,wctype_t _Type);
+#endif
+
+#ifndef _WDIRECT_DEFINED
+#define _WDIRECT_DEFINED
+
+ _CRTIMP wchar_t *__cdecl _wgetcwd(wchar_t *_DstBuf,int _SizeInWords);
+ _CRTIMP wchar_t *__cdecl _wgetdcwd(int _Drive,wchar_t *_DstBuf,int _SizeInWords);
+ wchar_t *__cdecl _wgetdcwd_nolock(int _Drive,wchar_t *_DstBuf,int _SizeInWords);
+ _CRTIMP int __cdecl _wchdir(const wchar_t *_Path);
+ _CRTIMP int __cdecl _wmkdir(const wchar_t *_Path);
+ _CRTIMP int __cdecl _wrmdir(const wchar_t *_Path);
+#endif
+
+#ifndef _WIO_DEFINED
+#define _WIO_DEFINED
+
+ _CRTIMP int __cdecl _waccess(const wchar_t *_Filename,int _AccessMode);
+ _CRTIMP int __cdecl _wchmod(const wchar_t *_Filename,int _Mode);
+ _CRTIMP int __cdecl _wcreat(const wchar_t *_Filename,int _PermissionMode);
+ _CRTIMP intptr_t __cdecl _wfindfirst32(const wchar_t *_Filename,struct _wfinddata32_t *_FindData);
+ _CRTIMP int __cdecl _wfindnext32(intptr_t _FindHandle,struct _wfinddata32_t *_FindData);
+ _CRTIMP int __cdecl _wunlink(const wchar_t *_Filename);
+ _CRTIMP int __cdecl _wrename(const wchar_t *_NewFilename,const wchar_t *_OldFilename);
+ _CRTIMP wchar_t *__cdecl _wmktemp(wchar_t *_TemplateName);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP intptr_t __cdecl _wfindfirst32i64(const wchar_t *_Filename,struct _wfinddata32i64_t *_FindData);
+ intptr_t __cdecl _wfindfirst64i32(const wchar_t *_Filename,struct _wfinddata64i32_t *_FindData);
+ _CRTIMP intptr_t __cdecl _wfindfirst64(const wchar_t *_Filename,struct _wfinddata64_t *_FindData);
+ _CRTIMP int __cdecl _wfindnext32i64(intptr_t _FindHandle,struct _wfinddata32i64_t *_FindData);
+ int __cdecl _wfindnext64i32(intptr_t _FindHandle,struct _wfinddata64i32_t *_FindData);
+ _CRTIMP int __cdecl _wfindnext64(intptr_t _FindHandle,struct _wfinddata64_t *_FindData);
+#endif
+ _CRTIMP errno_t __cdecl _wsopen_s(int *_FileHandle,const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,int _PermissionFlag);
+#if !defined(__cplusplus) || !(defined(_X86_) && !defined(__x86_64))
+ _CRTIMP int __cdecl _wopen(const wchar_t *_Filename,int _OpenFlag,...);
+ _CRTIMP int __cdecl _wsopen(const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,...);
+#else
+ extern "C++" _CRTIMP int __cdecl _wopen(const wchar_t *_Filename,int _OpenFlag,int _PermissionMode = 0);
+ extern "C++" _CRTIMP int __cdecl _wsopen(const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,int _PermissionMode = 0);
+#endif
+#endif
+
+#ifndef _WLOCALE_DEFINED
+#define _WLOCALE_DEFINED
+ _CRTIMP wchar_t *__cdecl _wsetlocale(int _Category,const wchar_t *_Locale);
+#endif
+
+#ifndef _WPROCESS_DEFINED
+#define _WPROCESS_DEFINED
+
+ _CRTIMP intptr_t __cdecl _wexecl(const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wexecle(const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wexeclp(const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wexeclpe(const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wexecv(const wchar_t *_Filename,const wchar_t *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _wexecve(const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env);
+ _CRTIMP intptr_t __cdecl _wexecvp(const wchar_t *_Filename,const wchar_t *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _wexecvpe(const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env);
+ _CRTIMP intptr_t __cdecl _wspawnl(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wspawnle(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wspawnlp(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wspawnlpe(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...);
+ _CRTIMP intptr_t __cdecl _wspawnv(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _wspawnve(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env);
+ _CRTIMP intptr_t __cdecl _wspawnvp(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList);
+ _CRTIMP intptr_t __cdecl _wspawnvpe(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env);
+#ifndef _CRT_WSYSTEM_DEFINED
+#define _CRT_WSYSTEM_DEFINED
+ _CRTIMP int __cdecl _wsystem(const wchar_t *_Command);
+#endif
+#endif
+
+#ifndef _WCTYPE_INLINE_DEFINED
+#undef _CRT_WCTYPE_NOINLINE
+#if !defined(__cplusplus) || defined(_CRT_WCTYPE_NOINLINE)
+#define iswalpha(_c) (iswctype(_c,_ALPHA))
+#define iswupper(_c) (iswctype(_c,_UPPER))
+#define iswlower(_c) (iswctype(_c,_LOWER))
+#define iswdigit(_c) (iswctype(_c,_DIGIT))
+#define iswxdigit(_c) (iswctype(_c,_HEX))
+#define iswspace(_c) (iswctype(_c,_SPACE))
+#define iswpunct(_c) (iswctype(_c,_PUNCT))
+#define iswalnum(_c) (iswctype(_c,_ALPHA|_DIGIT))
+#define iswprint(_c) (iswctype(_c,_BLANK|_PUNCT|_ALPHA|_DIGIT))
+#define iswgraph(_c) (iswctype(_c,_PUNCT|_ALPHA|_DIGIT))
+#define iswcntrl(_c) (iswctype(_c,_CONTROL))
+#define iswascii(_c) ((unsigned)(_c) < 0x80)
+
+#define _iswalpha_l(_c,_p) (_iswctype_l(_c,_ALPHA,_p))
+#define _iswupper_l(_c,_p) (_iswctype_l(_c,_UPPER,_p))
+#define _iswlower_l(_c,_p) (_iswctype_l(_c,_LOWER,_p))
+#define _iswdigit_l(_c,_p) (_iswctype_l(_c,_DIGIT,_p))
+#define _iswxdigit_l(_c,_p) (_iswctype_l(_c,_HEX,_p))
+#define _iswspace_l(_c,_p) (_iswctype_l(_c,_SPACE,_p))
+#define _iswpunct_l(_c,_p) (_iswctype_l(_c,_PUNCT,_p))
+#define _iswalnum_l(_c,_p) (_iswctype_l(_c,_ALPHA|_DIGIT,_p))
+#define _iswprint_l(_c,_p) (_iswctype_l(_c,_BLANK|_PUNCT|_ALPHA|_DIGIT,_p))
+#define _iswgraph_l(_c,_p) (_iswctype_l(_c,_PUNCT|_ALPHA|_DIGIT,_p))
+#define _iswcntrl_l(_c,_p) (_iswctype_l(_c,_CONTROL,_p))
+#ifndef _CTYPE_DISABLE_MACROS
+#define isleadbyte(_c) (__PCTYPE_FUNC[(unsigned char)(_c)] & _LEADBYTE)
+#endif
+#endif
+#define _WCTYPE_INLINE_DEFINED
+#endif
+
+#if !defined(_POSIX_) || defined(__GNUC__)
+#ifndef _INO_T_DEFINED
+#define _INO_T_DEFINED
+ typedef unsigned short _ino_t;
+#ifndef NO_OLDNAMES
+ typedef unsigned short ino_t;
+#endif
+#endif
+
+#ifndef _DEV_T_DEFINED
+#define _DEV_T_DEFINED
+ typedef unsigned int _dev_t;
+#ifndef NO_OLDNAMES
+ typedef unsigned int dev_t;
+#endif
+#endif
+
+#ifndef _OFF_T_DEFINED
+#define _OFF_T_DEFINED
+#ifndef _OFF_T_
+#define _OFF_T_
+ typedef long _off_t;
+#if !defined(NO_OLDNAMES) || defined(_POSIX)
+ typedef long off_t;
+#endif
+#endif
+#endif
+
+#ifndef _OFF64_T_DEFINED
+#define _OFF64_T_DEFINED
+ typedef long long _off64_t;
+#if !defined(NO_OLDNAMES) || defined(_POSIX)
+ typedef long long off64_t;
+#endif
+#endif
+
+#ifndef _STAT_DEFINED
+#define _STAT_DEFINED
+
+#ifdef _USE_32BIT_TIME_T
+#ifdef WIN64
+#define _fstat _fstat32
+#define _stat _stat32
+#define _wstat _wstat32
+#else
+#define _fstat32 _fstat
+#define _stat32 _stat
+#define _wstat32 _wstat
+#endif
+#define _fstati64 _fstat32i64
+#define _stati64 _stat32i64
+#define _wstati64 _wstat32i64
+#else
+#define _fstat _fstat64i32
+#define _fstati64 _fstat64
+#define _stat _stat64i32
+#define _stati64 _stat64
+#define _wstat _wstat64i32
+#define _wstati64 _wstat64
+#endif
+
+ struct _stat32 {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ _off_t st_size;
+ __time32_t st_atime;
+ __time32_t st_mtime;
+ __time32_t st_ctime;
+ };
+
+#ifndef NO_OLDNAMES
+ struct stat {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ _off_t st_size;
+ time_t st_atime;
+ time_t st_mtime;
+ time_t st_ctime;
+ };
+#endif
+
+#if _INTEGRAL_MAX_BITS >= 64
+
+ struct _stat32i64 {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ __int64 st_size;
+ __time32_t st_atime;
+ __time32_t st_mtime;
+ __time32_t st_ctime;
+ };
+
+ struct _stat64i32 {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ _off_t st_size;
+ __time64_t st_atime;
+ __time64_t st_mtime;
+ __time64_t st_ctime;
+ };
+
+ struct _stat64 {
+ _dev_t st_dev;
+ _ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ _dev_t st_rdev;
+ __int64 st_size;
+ __time64_t st_atime;
+ __time64_t st_mtime;
+ __time64_t st_ctime;
+ };
+#endif
+
+#define __stat64 _stat64
+
+#endif
+
+#ifndef _WSTAT_DEFINED
+#define _WSTAT_DEFINED
+
+ _CRTIMP int __cdecl _wstat32(const wchar_t *_Name,struct _stat32 *_Stat);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP int __cdecl _wstat32i64(const wchar_t *_Name,struct _stat32i64 *_Stat);
+ int __cdecl _wstat64i32(const wchar_t *_Name,struct _stat64i32 *_Stat);
+ _CRTIMP int __cdecl _wstat64(const wchar_t *_Name,struct _stat64 *_Stat);
+#endif
+#endif
+#endif
+
+#ifndef _WCONIO_DEFINED
+#define _WCONIO_DEFINED
+
+#ifndef WEOF
+#define WEOF (wint_t)(0xFFFF)
+#endif
+
+ _CRTIMP wchar_t *_cgetws(wchar_t *_Buffer);
+ _CRTIMP wint_t __cdecl _getwch(void);
+ _CRTIMP wint_t __cdecl _getwche(void);
+ _CRTIMP wint_t __cdecl _putwch(wchar_t _WCh);
+ _CRTIMP wint_t __cdecl _ungetwch(wint_t _WCh);
+ _CRTIMP int __cdecl _cputws(const wchar_t *_String);
+ _CRTIMP int __cdecl _cwprintf(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _cwscanf(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _cwscanf_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcwprintf(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _cwprintf_p(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vcwprintf_p(const wchar_t *_Format,va_list _ArgList);
+
+ _CRTIMP int __cdecl _cwprintf_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _cwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vcwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ wint_t __cdecl _putwch_nolock(wchar_t _WCh);
+ wint_t __cdecl _getwch_nolock(void);
+ wint_t __cdecl _getwche_nolock(void);
+ wint_t __cdecl _ungetwch_nolock(wint_t _WCh);
+#endif
+
+#ifndef _WSTDIO_DEFINED
+#define _WSTDIO_DEFINED
+
+#ifndef WEOF
+#define WEOF (wint_t)(0xFFFF)
+#endif
+
+#ifdef _POSIX_
+ _CRTIMP FILE *__cdecl _wfsopen(const wchar_t *_Filename,const wchar_t *_Mode);
+#else
+ _CRTIMP FILE *__cdecl _wfsopen(const wchar_t *_Filename,const wchar_t *_Mode,int _ShFlag);
+#endif
+
+ wint_t __cdecl fgetwc(FILE *_File);
+ _CRTIMP wint_t __cdecl _fgetwchar(void);
+ wint_t __cdecl fputwc(wchar_t _Ch,FILE *_File);
+ _CRTIMP wint_t __cdecl _fputwchar(wchar_t _Ch);
+ wint_t __cdecl getwc(FILE *_File);
+ wint_t __cdecl getwchar(void);
+ wint_t __cdecl putwc(wchar_t _Ch,FILE *_File);
+ wint_t __cdecl putwchar(wchar_t _Ch);
+ wint_t __cdecl ungetwc(wint_t _Ch,FILE *_File);
+ wchar_t *__cdecl fgetws(wchar_t *_Dst,int _SizeInWords,FILE *_File);
+ int __cdecl fputws(const wchar_t *_Str,FILE *_File);
+ _CRTIMP wchar_t *__cdecl _getws(wchar_t *_String);
+ _CRTIMP int __cdecl _putws(const wchar_t *_Str);
+ int __cdecl fwprintf(FILE *_File,const wchar_t *_Format,...);
+ int __cdecl wprintf(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _scwprintf(const wchar_t *_Format,...);
+ int __cdecl vfwprintf(FILE *_File,const wchar_t *_Format,va_list _ArgList);
+ int __cdecl vwprintf(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl swprintf(wchar_t*, const wchar_t*, ...);
+ _CRTIMP int __cdecl vswprintf(wchar_t*, const wchar_t*,va_list);
+ _CRTIMP int __cdecl _swprintf_c(wchar_t *_DstBuf,size_t _SizeInWords,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vswprintf_c(wchar_t *_DstBuf,size_t _SizeInWords,const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _snwprintf(wchar_t *_Dest,size_t _Count,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vsnwprintf(wchar_t *_Dest,size_t _Count,const wchar_t *_Format,va_list _Args);
+#ifndef __NO_ISOCEXT /* externs in libmingwex.a */
+ int __cdecl snwprintf (wchar_t *s, size_t n, const wchar_t * format, ...);
+ __CRT_INLINE int __cdecl vsnwprintf (wchar_t *s, size_t n, const wchar_t *format, va_list arg) { return _vsnwprintf(s,n,format,arg); }
+ int __cdecl vwscanf (const wchar_t *, va_list);
+ int __cdecl vfwscanf (FILE *,const wchar_t *,va_list);
+ int __cdecl vswscanf (const wchar_t *,const wchar_t *,va_list);
+#endif
+ _CRTIMP int __cdecl _fwprintf_p(FILE *_File,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _wprintf_p(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vfwprintf_p(FILE *_File,const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _vwprintf_p(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _swprintf_p(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vswprintf_p(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _scwprintf_p(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vscwprintf_p(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _wprintf_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _wprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _vwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _fwprintf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _fwprintf_p_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vfwprintf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _vfwprintf_p_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _swprintf_c_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _swprintf_p_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vswprintf_c_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _vswprintf_p_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _scwprintf_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _scwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vscwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _snwprintf_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _vsnwprintf_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ _CRTIMP int __cdecl _swprintf(wchar_t *_Dest,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _vswprintf(wchar_t *_Dest,const wchar_t *_Format,va_list _Args);
+ _CRTIMP int __cdecl __swprintf_l(wchar_t *_Dest,const wchar_t *_Format,_locale_t _Plocinfo,...);
+ _CRTIMP int __cdecl __vswprintf_l(wchar_t *_Dest,const wchar_t *_Format,_locale_t _Plocinfo,va_list _Args);
+#ifndef RC_INVOKED
+#include <vadefs.h>
+#endif
+
+#ifdef _CRT_NON_CONFORMING_SWPRINTFS
+#ifndef __cplusplus
+#define swprintf _swprintf
+#define vswprintf _vswprintf
+#define _swprintf_l __swprintf_l
+#define _vswprintf_l __vswprintf_l
+#endif
+#endif
+
+ _CRTIMP wchar_t *__cdecl _wtempnam(const wchar_t *_Directory,const wchar_t *_FilePrefix);
+ _CRTIMP int __cdecl _vscwprintf(const wchar_t *_Format,va_list _ArgList);
+ _CRTIMP int __cdecl _vscwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
+ int __cdecl fwscanf(FILE *_File,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _fwscanf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
+ int __cdecl swscanf(const wchar_t *_Src,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _swscanf_l(const wchar_t *_Src,const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP int __cdecl _snwscanf(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _snwscanf_l(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
+ int __cdecl wscanf(const wchar_t *_Format,...);
+ _CRTIMP int __cdecl _wscanf_l(const wchar_t *_Format,_locale_t _Locale,...);
+ _CRTIMP FILE *__cdecl _wfdopen(int _FileHandle ,const wchar_t *_Mode);
+ _CRTIMP FILE *__cdecl _wfopen(const wchar_t *_Filename,const wchar_t *_Mode);
+ _CRTIMP FILE *__cdecl _wfreopen(const wchar_t *_Filename,const wchar_t *_Mode,FILE *_OldFile);
+
+#ifndef _CRT_WPERROR_DEFINED
+#define _CRT_WPERROR_DEFINED
+ _CRTIMP void __cdecl _wperror(const wchar_t *_ErrMsg);
+#endif
+ _CRTIMP FILE *__cdecl _wpopen(const wchar_t *_Command,const wchar_t *_Mode);
+#if !defined(NO_OLDNAMES) && !defined(wpopen)
+#define wpopen _wpopen
+#endif
+ _CRTIMP int __cdecl _wremove(const wchar_t *_Filename);
+ _CRTIMP wchar_t *__cdecl _wtmpnam(wchar_t *_Buffer);
+ _CRTIMP wint_t __cdecl _fgetwc_nolock(FILE *_File);
+ _CRTIMP wint_t __cdecl _fputwc_nolock(wchar_t _Ch,FILE *_File);
+ _CRTIMP wint_t __cdecl _ungetwc_nolock(wint_t _Ch,FILE *_File);
+
+#undef _CRT_GETPUTWCHAR_NOINLINE
+
+#if !defined(__cplusplus) || defined(_CRT_GETPUTWCHAR_NOINLINE)
+#define getwchar() fgetwc(stdin)
+#define putwchar(_c) fputwc((_c),stdout)
+#else
+ __CRT_INLINE wint_t __cdecl getwchar() {return (fgetwc(stdin)); }
+ __CRT_INLINE wint_t __cdecl putwchar(wchar_t _C) {return (fputwc(_C,stdout)); }
+#endif
+
+#define getwc(_stm) fgetwc(_stm)
+#define putwc(_c,_stm) fputwc(_c,_stm)
+#define _putwc_nolock(_c,_stm) _fputwc_nolock(_c,_stm)
+#define _getwc_nolock(_c) _fgetwc_nolock(_c)
+#endif
+
+#ifndef _WSTDLIB_DEFINED
+#define _WSTDLIB_DEFINED
+
+ _CRTIMP wchar_t *__cdecl _itow(int _Value,wchar_t *_Dest,int _Radix);
+ _CRTIMP wchar_t *__cdecl _ltow(long _Value,wchar_t *_Dest,int _Radix);
+ _CRTIMP wchar_t *__cdecl _ultow(unsigned long _Value,wchar_t *_Dest,int _Radix);
+ double __cdecl wcstod(const wchar_t *_Str,wchar_t **_EndPtr);
+ _CRTIMP double __cdecl _wcstod_l(const wchar_t *_Str,wchar_t **_EndPtr,_locale_t _Locale);
+ float __cdecl wcstof( const wchar_t *nptr, wchar_t **endptr);
+#if !defined __NO_ISOCEXT /* in libmingwex.a */
+ float __cdecl wcstof (const wchar_t * __restrict__, wchar_t ** __restrict__);
+ long double __cdecl wcstold (const wchar_t * __restrict__, wchar_t ** __restrict__);
+#endif /* __NO_ISOCEXT */
+ long __cdecl wcstol(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix);
+ _CRTIMP long __cdecl _wcstol_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale);
+ unsigned long __cdecl wcstoul(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix);
+ _CRTIMP unsigned long __cdecl _wcstoul_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale);
+ _CRTIMP wchar_t *__cdecl _wgetenv(const wchar_t *_VarName);
+#ifndef _CRT_WSYSTEM_DEFINED
+#define _CRT_WSYSTEM_DEFINED
+ _CRTIMP int __cdecl _wsystem(const wchar_t *_Command);
+#endif
+ _CRTIMP double __cdecl _wtof(const wchar_t *_Str);
+ _CRTIMP double __cdecl _wtof_l(const wchar_t *_Str,_locale_t _Locale);
+ _CRTIMP int __cdecl _wtoi(const wchar_t *_Str);
+ _CRTIMP int __cdecl _wtoi_l(const wchar_t *_Str,_locale_t _Locale);
+ _CRTIMP long __cdecl _wtol(const wchar_t *_Str);
+ _CRTIMP long __cdecl _wtol_l(const wchar_t *_Str,_locale_t _Locale);
+
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP wchar_t *__cdecl _i64tow(__int64 _Val,wchar_t *_DstBuf,int _Radix);
+ _CRTIMP wchar_t *__cdecl _ui64tow(unsigned __int64 _Val,wchar_t *_DstBuf,int _Radix);
+ _CRTIMP __int64 __cdecl _wtoi64(const wchar_t *_Str);
+ _CRTIMP __int64 __cdecl _wtoi64_l(const wchar_t *_Str,_locale_t _Locale);
+ _CRTIMP __int64 __cdecl _wcstoi64(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix);
+ _CRTIMP __int64 __cdecl _wcstoi64_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale);
+ _CRTIMP unsigned __int64 __cdecl _wcstoui64(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix);
+ _CRTIMP unsigned __int64 __cdecl _wcstoui64_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale);
+#endif
+#endif
+
+#ifndef _POSIX_
+#ifndef _WSTDLIBP_DEFINED
+#define _WSTDLIBP_DEFINED
+ _CRTIMP wchar_t *__cdecl _wfullpath(wchar_t *_FullPath,const wchar_t *_Path,size_t _SizeInWords);
+ _CRTIMP void __cdecl _wmakepath(wchar_t *_ResultPath,const wchar_t *_Drive,const wchar_t *_Dir,const wchar_t *_Filename,const wchar_t *_Ext);
+#ifndef _CRT_WPERROR_DEFINED
+#define _CRT_WPERROR_DEFINED
+ _CRTIMP void __cdecl _wperror(const wchar_t *_ErrMsg);
+#endif
+ _CRTIMP int __cdecl _wputenv(const wchar_t *_EnvString);
+ _CRTIMP void __cdecl _wsearchenv(const wchar_t *_Filename,const wchar_t *_EnvVar,wchar_t *_ResultPath);
+ _CRTIMP void __cdecl _wsplitpath(const wchar_t *_FullPath,wchar_t *_Drive,wchar_t *_Dir,wchar_t *_Filename,wchar_t *_Ext);
+#endif
+#endif
+
+#ifndef _WSTRING_DEFINED
+#define _WSTRING_DEFINED
+ _CRTIMP wchar_t *__cdecl _wcsdup(const wchar_t *_Str);
+ wchar_t *__cdecl wcscat(wchar_t *_Dest,const wchar_t *_Source);
+ _CONST_RETURN wchar_t *__cdecl wcschr(const wchar_t *_Str,wchar_t _Ch);
+ int __cdecl wcscmp(const wchar_t *_Str1,const wchar_t *_Str2);
+ wchar_t *__cdecl wcscpy(wchar_t *_Dest,const wchar_t *_Source);
+ size_t __cdecl wcscspn(const wchar_t *_Str,const wchar_t *_Control);
+ size_t __cdecl wcslen(const wchar_t *_Str);
+ size_t __cdecl wcsnlen(const wchar_t *_Src,size_t _MaxCount);
+ wchar_t *__cdecl wcsncat(wchar_t *_Dest,const wchar_t *_Source,size_t _Count);
+ int __cdecl wcsncmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount);
+ wchar_t *__cdecl wcsncpy(wchar_t *_Dest,const wchar_t *_Source,size_t _Count);
+ _CONST_RETURN wchar_t *__cdecl wcspbrk(const wchar_t *_Str,const wchar_t *_Control);
+ _CONST_RETURN wchar_t *__cdecl wcsrchr(const wchar_t *_Str,wchar_t _Ch);
+ size_t __cdecl wcsspn(const wchar_t *_Str,const wchar_t *_Control);
+ _CONST_RETURN wchar_t *__cdecl wcsstr(const wchar_t *_Str,const wchar_t *_SubStr);
+ wchar_t *__cdecl wcstok(wchar_t *_Str,const wchar_t *_Delim);
+ _CRTIMP wchar_t *__cdecl _wcserror(int _ErrNum);
+ _CRTIMP wchar_t *__cdecl __wcserror(const wchar_t *_Str);
+ _CRTIMP int __cdecl _wcsicmp(const wchar_t *_Str1,const wchar_t *_Str2);
+ _CRTIMP int __cdecl _wcsicmp_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale);
+ _CRTIMP int __cdecl _wcsnicmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _wcsnicmp_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP wchar_t *__cdecl _wcsnset(wchar_t *_Str,wchar_t _Val,size_t _MaxCount);
+ _CRTIMP wchar_t *__cdecl _wcsrev(wchar_t *_Str);
+ _CRTIMP wchar_t *__cdecl _wcsset(wchar_t *_Str,wchar_t _Val);
+ _CRTIMP wchar_t *__cdecl _wcslwr(wchar_t *_String);
+ _CRTIMP wchar_t *_wcslwr_l(wchar_t *_String,_locale_t _Locale);
+ _CRTIMP wchar_t *__cdecl _wcsupr(wchar_t *_String);
+ _CRTIMP wchar_t *_wcsupr_l(wchar_t *_String,_locale_t _Locale);
+ size_t __cdecl wcsxfrm(wchar_t *_Dst,const wchar_t *_Src,size_t _MaxCount);
+ _CRTIMP size_t __cdecl _wcsxfrm_l(wchar_t *_Dst,const wchar_t *_Src,size_t _MaxCount,_locale_t _Locale);
+ int __cdecl wcscoll(const wchar_t *_Str1,const wchar_t *_Str2);
+ _CRTIMP int __cdecl _wcscoll_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale);
+ _CRTIMP int __cdecl _wcsicoll(const wchar_t *_Str1,const wchar_t *_Str2);
+ _CRTIMP int __cdecl _wcsicoll_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale);
+ _CRTIMP int __cdecl _wcsncoll(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _wcsncoll_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale);
+ _CRTIMP int __cdecl _wcsnicoll(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount);
+ _CRTIMP int __cdecl _wcsnicoll_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale);
+
+#ifndef NO_OLDNAMES
+ wchar_t *__cdecl wcsdup(const wchar_t *_Str);
+#define wcswcs wcsstr
+ int __cdecl wcsicmp(const wchar_t *_Str1,const wchar_t *_Str2);
+ int __cdecl wcsnicmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount);
+ wchar_t *__cdecl wcsnset(wchar_t *_Str,wchar_t _Val,size_t _MaxCount);
+ wchar_t *__cdecl wcsrev(wchar_t *_Str);
+ wchar_t *__cdecl wcsset(wchar_t *_Str,wchar_t _Val);
+ wchar_t *__cdecl wcslwr(wchar_t *_Str);
+ wchar_t *__cdecl wcsupr(wchar_t *_Str);
+ int __cdecl wcsicoll(const wchar_t *_Str1,const wchar_t *_Str2);
+#endif
+#endif
+
+#ifndef _TM_DEFINED
+#define _TM_DEFINED
+ struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ };
+#endif
+
+#ifndef _WTIME_DEFINED
+#define _WTIME_DEFINED
+
+ _CRTIMP wchar_t *__cdecl _wasctime(const struct tm *_Tm);
+ _CRTIMP wchar_t *__cdecl _wctime32(const __time32_t *_Time);
+ size_t __cdecl wcsftime(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm);
+ _CRTIMP size_t __cdecl _wcsftime_l(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm,_locale_t _Locale);
+ _CRTIMP wchar_t *__cdecl _wstrdate(wchar_t *_Buffer);
+ _CRTIMP wchar_t *__cdecl _wstrtime(wchar_t *_Buffer);
+#if _INTEGRAL_MAX_BITS >= 64
+ _CRTIMP wchar_t *__cdecl _wctime64(const __time64_t *_Time);
+#endif
+
+#if !defined (RC_INVOKED) && !defined (_INC_WTIME_INL)
+#define _INC_WTIME_INL
+#ifdef _USE_32BIT_TIME_T
+__CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime32(_Time); }
+#else
+__CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime64(_Time); }
+#endif
+#endif
+#endif
+
+ typedef int mbstate_t;
+ typedef wchar_t _Wint_t;
+
+ wint_t __cdecl btowc(int);
+ size_t __cdecl mbrlen(const char *_Ch,size_t _SizeInBytes,mbstate_t *_State);
+ size_t __cdecl mbrtowc(wchar_t *_DstCh,const char *_SrcCh,size_t _SizeInBytes,mbstate_t *_State);
+ size_t __cdecl mbsrtowcs(wchar_t *_Dest,const char **_PSrc,size_t _Count,mbstate_t *_State);
+ size_t __cdecl wcrtomb(char *_Dest,wchar_t _Source,mbstate_t *_State);
+ size_t __cdecl wcsrtombs(char *_Dest,const wchar_t **_PSource,size_t _Count,mbstate_t *_State);
+ int __cdecl wctob(wint_t _WCh);
+
+#ifndef __NO_ISOCEXT /* these need static lib libmingwex.a */
+ wchar_t *__cdecl wmemset(wchar_t *s, wchar_t c, size_t n);
+ _CONST_RETURN wchar_t *__cdecl wmemchr(const wchar_t *s, wchar_t c, size_t n);
+ int wmemcmp(const wchar_t *s1, const wchar_t *s2,size_t n);
+ wchar_t *__cdecl wmemcpy(wchar_t *s1,const wchar_t *s2,size_t n);
+ wchar_t *__cdecl wmemmove(wchar_t *s1, const wchar_t *s2, size_t n);
+ long long __cdecl wcstoll(const wchar_t *nptr,wchar_t **endptr, int base);
+ unsigned long long __cdecl wcstoull(const wchar_t *nptr,wchar_t **endptr, int base);
+#endif /* __NO_ISOCEXT */
+
+ void *__cdecl memmove(void *_Dst,const void *_Src,size_t _MaxCount);
+ void *__cdecl memcpy(void *_Dst,const void *_Src,size_t _MaxCount);
+ __CRT_INLINE int __cdecl fwide(FILE *_F,int _M) { (void)_F; return (_M); }
+ __CRT_INLINE int __cdecl mbsinit(const mbstate_t *_P) { return (!_P || *_P==0); }
+ __CRT_INLINE _CONST_RETURN wchar_t *__cdecl wmemchr(const wchar_t *_S,wchar_t _C,size_t _N) { for (;0<_N;++_S,--_N) if (*_S==_C) return (_CONST_RETURN wchar_t *)(_S); return (0); }
+ __CRT_INLINE int __cdecl wmemcmp(const wchar_t *_S1,const wchar_t *_S2,size_t _N) { for (; 0 < _N; ++_S1,++_S2,--_N) if (*_S1!=*_S2) return (*_S1 < *_S2 ? -1 : +1); return (0); }
+ __CRT_INLINE wchar_t *__cdecl wmemcpy(wchar_t *_S1,const wchar_t *_S2,size_t _N) { return (wchar_t *)memcpy(_S1,_S2,_N*sizeof(wchar_t)); }
+ __CRT_INLINE wchar_t *__cdecl wmemmove(wchar_t *_S1,const wchar_t *_S2,size_t _N) { return (wchar_t *)memmove(_S1,_S2,_N*sizeof(wchar_t)); }
+ __CRT_INLINE wchar_t *__cdecl wmemset(wchar_t *_S,wchar_t _C,size_t _N) {
+ wchar_t *_Su = _S;
+ for (;0<_N;++_Su,--_N) {
+ *_Su = _C;
+ }
+ return (_S);
+ }
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+
+#include <sec_api/wchar_s.h>
+#endif
diff --git a/win32/include/wctype.h b/win32/include/wctype.h
new file mode 100644
index 0000000..a44cb38
--- /dev/null
+++ b/win32/include/wctype.h
@@ -0,0 +1,172 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_WCTYPE
+#define _INC_WCTYPE
+
+#ifndef _WIN32
+#error Only Win32 target is supported!
+#endif
+
+#include <_mingw.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _CRTIMP
+#define _CRTIMP __declspec(dllimport)
+#endif
+
+#ifndef _WCHAR_T_DEFINED
+ typedef unsigned short wchar_t;
+#define _WCHAR_T_DEFINED
+#endif
+
+#ifndef _WCTYPE_T_DEFINED
+ typedef unsigned short wint_t;
+ typedef unsigned short wctype_t;
+#define _WCTYPE_T_DEFINED
+#endif
+
+#ifndef WEOF
+#define WEOF (wint_t)(0xFFFF)
+#endif
+
+#ifndef _CRT_CTYPEDATA_DEFINED
+#define _CRT_CTYPEDATA_DEFINED
+#ifndef _CTYPE_DISABLE_MACROS
+
+#ifndef __PCTYPE_FUNC
+#define __PCTYPE_FUNC __pctype_func()
+#ifdef _MSVCRT_
+#define __pctype_func() (_pctype)
+#else
+#define __pctype_func() (*_imp___pctype)
+#endif
+#endif
+
+#ifndef _pctype
+#ifdef _MSVCRT_
+ extern unsigned short *_pctype;
+#else
+ extern unsigned short **_imp___pctype;
+#define _pctype (*_imp___pctype)
+#endif
+#endif
+
+#endif
+#endif
+
+#ifndef _CRT_WCTYPEDATA_DEFINED
+#define _CRT_WCTYPEDATA_DEFINED
+#ifndef _CTYPE_DISABLE_MACROS
+#ifndef _wctype
+#ifdef _MSVCRT_
+ extern unsigned short *_wctype;
+#else
+ extern unsigned short **_imp___wctype;
+#define _wctype (*_imp___wctype)
+#endif
+#endif
+
+#ifndef _pwctype
+#ifdef _MSVCRT_
+ extern unsigned short *_pwctype;
+#else
+ extern unsigned short **_imp___pwctype;
+#define _pwctype (*_imp___pwctype)
+#define __pwctype_func() (*_imp___pwctype)
+#endif
+#endif
+#endif
+#endif
+
+#define _UPPER 0x1
+#define _LOWER 0x2
+#define _DIGIT 0x4
+#define _SPACE 0x8
+
+#define _PUNCT 0x10
+#define _CONTROL 0x20
+#define _BLANK 0x40
+#define _HEX 0x80
+
+#define _LEADBYTE 0x8000
+#define _ALPHA (0x0100|_UPPER|_LOWER)
+
+#ifndef _WCTYPE_DEFINED
+#define _WCTYPE_DEFINED
+
+ int __cdecl iswalpha(wint_t);
+ int __cdecl iswupper(wint_t);
+ int __cdecl iswlower(wint_t);
+ int __cdecl iswdigit(wint_t);
+ int __cdecl iswxdigit(wint_t);
+ int __cdecl iswspace(wint_t);
+ int __cdecl iswpunct(wint_t);
+ int __cdecl iswalnum(wint_t);
+ int __cdecl iswprint(wint_t);
+ int __cdecl iswgraph(wint_t);
+ int __cdecl iswcntrl(wint_t);
+ int __cdecl iswascii(wint_t);
+ int __cdecl isleadbyte(int);
+ wint_t __cdecl towupper(wint_t);
+ wint_t __cdecl towlower(wint_t);
+ int __cdecl iswctype(wint_t,wctype_t);
+ _CRTIMP int __cdecl __iswcsymf(wint_t);
+ _CRTIMP int __cdecl __iswcsym(wint_t);
+ int __cdecl is_wctype(wint_t,wctype_t);
+#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined (NO_OLDNAMES)
+int __cdecl isblank(int _C);
+#endif
+#endif
+
+#ifndef _WCTYPE_INLINE_DEFINED
+#define _WCTYPE_INLINE_DEFINED
+#ifndef __cplusplus
+#define iswalpha(_c) (iswctype(_c,_ALPHA))
+#define iswupper(_c) (iswctype(_c,_UPPER))
+#define iswlower(_c) (iswctype(_c,_LOWER))
+#define iswdigit(_c) (iswctype(_c,_DIGIT))
+#define iswxdigit(_c) (iswctype(_c,_HEX))
+#define iswspace(_c) (iswctype(_c,_SPACE))
+#define iswpunct(_c) (iswctype(_c,_PUNCT))
+#define iswalnum(_c) (iswctype(_c,_ALPHA|_DIGIT))
+#define iswprint(_c) (iswctype(_c,_BLANK|_PUNCT|_ALPHA|_DIGIT))
+#define iswgraph(_c) (iswctype(_c,_PUNCT|_ALPHA|_DIGIT))
+#define iswcntrl(_c) (iswctype(_c,_CONTROL))
+#define iswascii(_c) ((unsigned)(_c) < 0x80)
+#define isleadbyte(c) (__pctype_func()[(unsigned char)(c)] & _LEADBYTE)
+#else
+ __CRT_INLINE int __cdecl iswalpha(wint_t _C) {return (iswctype(_C,_ALPHA)); }
+ __CRT_INLINE int __cdecl iswupper(wint_t _C) {return (iswctype(_C,_UPPER)); }
+ __CRT_INLINE int __cdecl iswlower(wint_t _C) {return (iswctype(_C,_LOWER)); }
+ __CRT_INLINE int __cdecl iswdigit(wint_t _C) {return (iswctype(_C,_DIGIT)); }
+ __CRT_INLINE int __cdecl iswxdigit(wint_t _C) {return (iswctype(_C,_HEX)); }
+ __CRT_INLINE int __cdecl iswspace(wint_t _C) {return (iswctype(_C,_SPACE)); }
+ __CRT_INLINE int __cdecl iswpunct(wint_t _C) {return (iswctype(_C,_PUNCT)); }
+ __CRT_INLINE int __cdecl iswalnum(wint_t _C) {return (iswctype(_C,_ALPHA|_DIGIT)); }
+ __CRT_INLINE int __cdecl iswprint(wint_t _C) {return (iswctype(_C,_BLANK|_PUNCT|_ALPHA|_DIGIT)); }
+ __CRT_INLINE int __cdecl iswgraph(wint_t _C) {return (iswctype(_C,_PUNCT|_ALPHA|_DIGIT)); }
+ __CRT_INLINE int __cdecl iswcntrl(wint_t _C) {return (iswctype(_C,_CONTROL)); }
+ __CRT_INLINE int __cdecl iswascii(wint_t _C) {return ((unsigned)(_C) < 0x80); }
+ __CRT_INLINE int __cdecl isleadbyte(int _C) {return (__pctype_func()[(unsigned char)(_C)] & _LEADBYTE); }
+#endif
+#endif
+
+ typedef wchar_t wctrans_t;
+ wint_t __cdecl towctrans(wint_t,wctrans_t);
+ wctrans_t __cdecl wctrans(const char *);
+ wctype_t __cdecl wctype(const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+#endif
diff --git a/win32/include/winapi/basetsd.h b/win32/include/winapi/basetsd.h
new file mode 100644
index 0000000..47d78c4
--- /dev/null
+++ b/win32/include/winapi/basetsd.h
@@ -0,0 +1,149 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _BASETSD_H_
+#define _BASETSD_H_
+
+#if (defined(__x86_64) || defined(__ia64__)) && !defined(RC_INVOKED)
+typedef unsigned __int64 POINTER_64_INT;
+#else
+typedef unsigned long POINTER_64_INT;
+#endif
+
+#define POINTER_32
+#define POINTER_64
+#define FIRMWARE_PTR
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef signed char INT8,*PINT8;
+ typedef signed short INT16,*PINT16;
+ typedef signed int INT32,*PINT32;
+ typedef signed __int64 INT64,*PINT64;
+ typedef unsigned char UINT8,*PUINT8;
+ typedef unsigned short UINT16,*PUINT16;
+ typedef unsigned int UINT32,*PUINT32;
+ typedef unsigned __int64 UINT64,*PUINT64;
+ typedef signed int LONG32,*PLONG32;
+ typedef unsigned int ULONG32,*PULONG32;
+ typedef unsigned int DWORD32,*PDWORD32;
+
+#ifndef _W64
+#define _W64
+#endif
+
+#ifdef _WIN64
+ typedef __int64 INT_PTR,*PINT_PTR;
+ typedef unsigned __int64 UINT_PTR,*PUINT_PTR;
+ typedef __int64 LONG_PTR,*PLONG_PTR;
+ typedef unsigned __int64 ULONG_PTR,*PULONG_PTR;
+#define __int3264 __int64
+#else
+ typedef int INT_PTR,*PINT_PTR;
+ typedef unsigned int UINT_PTR,*PUINT_PTR;
+ typedef long LONG_PTR,*PLONG_PTR;
+ typedef unsigned long ULONG_PTR,*PULONG_PTR;
+#define __int3264 __int32
+#endif
+
+#ifdef _WIN64
+#define ADDRESS_TAG_BIT 0x40000000000ULL
+ typedef __int64 SHANDLE_PTR;
+ typedef unsigned __int64 HANDLE_PTR;
+ typedef unsigned int UHALF_PTR,*PUHALF_PTR;
+ typedef int HALF_PTR,*PHALF_PTR;
+
+ static __inline unsigned long HandleToULong(const void *h) { return((unsigned long) (ULONG_PTR) h); }
+ static __inline long HandleToLong(const void *h) { return((long) (LONG_PTR) h); }
+ static __inline void *ULongToHandle(const unsigned long h) { return((void *) (UINT_PTR) h); }
+ static __inline void *LongToHandle(const long h) { return((void *) (INT_PTR) h); }
+ static __inline unsigned long PtrToUlong(const void *p) { return((unsigned long) (ULONG_PTR) p); }
+ static __inline unsigned int PtrToUint(const void *p) { return((unsigned int) (UINT_PTR) p); }
+ static __inline unsigned short PtrToUshort(const void *p) { return((unsigned short) (unsigned long) (ULONG_PTR) p); }
+ static __inline long PtrToLong(const void *p) { return((long) (LONG_PTR) p); }
+ static __inline int PtrToInt(const void *p) { return((int) (INT_PTR) p); }
+ static __inline short PtrToShort(const void *p) { return((short) (long) (LONG_PTR) p); }
+ static __inline void *IntToPtr(const int i) { return((void *)(INT_PTR)i); }
+ static __inline void *UIntToPtr(const unsigned int ui) { return((void *)(UINT_PTR)ui); }
+ static __inline void *LongToPtr(const long l) { return((void *)(LONG_PTR)l); }
+ static __inline void *ULongToPtr(const unsigned long ul) { return((void *)(ULONG_PTR)ul); }
+
+#define PtrToPtr64(p) ((void *) p)
+#define Ptr64ToPtr(p) ((void *) p)
+#define HandleToHandle64(h) (PtrToPtr64(h))
+#define Handle64ToHandle(h) (Ptr64ToPtr(h))
+
+ static __inline void *Ptr32ToPtr(const void *p) { return (void *)p; }
+ static __inline void *Handle32ToHandle(const void *h) { return((void *) h); }
+ static __inline void *PtrToPtr32(const void *p) { return((void *) (ULONG_PTR) p); }
+
+#define HandleToHandle32(h) (PtrToPtr32(h))
+#else
+
+#define ADDRESS_TAG_BIT 0x80000000UL
+
+ typedef unsigned short UHALF_PTR,*PUHALF_PTR;
+ typedef short HALF_PTR,*PHALF_PTR;
+ typedef long SHANDLE_PTR;
+ typedef unsigned long HANDLE_PTR;
+
+#define HandleToULong(h) ((ULONG)(ULONG_PTR)(h))
+#define HandleToLong(h) ((LONG)(LONG_PTR) (h))
+#define ULongToHandle(ul) ((HANDLE)(ULONG_PTR) (ul))
+#define LongToHandle(h) ((HANDLE)(LONG_PTR) (h))
+#define PtrToUlong(p) ((ULONG)(ULONG_PTR) (p))
+#define PtrToLong(p) ((LONG)(LONG_PTR) (p))
+#define PtrToUint(p) ((UINT)(UINT_PTR) (p))
+#define PtrToInt(p) ((INT)(INT_PTR) (p))
+#define PtrToUshort(p) ((unsigned short)(ULONG_PTR)(p))
+#define PtrToShort(p) ((short)(LONG_PTR)(p))
+#define IntToPtr(i) ((VOID *)(INT_PTR)((int)i))
+#define UIntToPtr(ui) ((VOID *)(UINT_PTR)((unsigned int)ui))
+#define LongToPtr(l) ((VOID *)(LONG_PTR)((long)l))
+#define ULongToPtr(ul) ((VOID *)(ULONG_PTR)((unsigned long)ul))
+
+ static __inline void *PtrToPtr64(const void *p) { return((void *) (ULONG_PTR)p); }
+ static __inline void *Ptr64ToPtr(const void *p) { return((void *) (ULONG_PTR) p); }
+ static __inline void *HandleToHandle64(const void *h) { return((void *) h); }
+ static __inline void *Handle64ToHandle(const void *h) { return((void *) (ULONG_PTR) h); }
+
+#define Ptr32ToPtr(p) ((void *) p)
+#define Handle32ToHandle(h) (Ptr32ToPtr(h))
+#define PtrToPtr32(p) ((void *) p)
+#define HandleToHandle32(h) (PtrToPtr32(h))
+#endif
+
+#define HandleToUlong(h) HandleToULong(h)
+#define UlongToHandle(ul) ULongToHandle(ul)
+#define UlongToPtr(ul) ULongToPtr(ul)
+#define UintToPtr(ui) UIntToPtr(ui)
+
+#define MAXUINT_PTR (~((UINT_PTR)0))
+#define MAXINT_PTR ((INT_PTR)(MAXUINT_PTR >> 1))
+#define MININT_PTR (~MAXINT_PTR)
+
+#define MAXULONG_PTR (~((ULONG_PTR)0))
+#define MAXLONG_PTR ((LONG_PTR)(MAXULONG_PTR >> 1))
+#define MINLONG_PTR (~MAXLONG_PTR)
+
+#define MAXUHALF_PTR ((UHALF_PTR)~0)
+#define MAXHALF_PTR ((HALF_PTR)(MAXUHALF_PTR >> 1))
+#define MINHALF_PTR (~MAXHALF_PTR)
+
+ typedef ULONG_PTR SIZE_T,*PSIZE_T;
+ typedef LONG_PTR SSIZE_T,*PSSIZE_T;
+ typedef ULONG_PTR DWORD_PTR,*PDWORD_PTR;
+ typedef __int64 LONG64,*PLONG64;
+ typedef unsigned __int64 ULONG64,*PULONG64;
+ typedef unsigned __int64 DWORD64,*PDWORD64;
+ typedef ULONG_PTR KAFFINITY;
+ typedef KAFFINITY *PKAFFINITY;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/include/winapi/basetyps.h b/win32/include/winapi/basetyps.h
new file mode 100644
index 0000000..376665e
--- /dev/null
+++ b/win32/include/winapi/basetyps.h
@@ -0,0 +1,85 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#if !defined(_BASETYPS_H_)
+#define _BASETYPS_H_
+
+#ifdef __cplusplus
+#define EXTERN_C extern "C"
+#else
+#define EXTERN_C extern
+#endif
+
+#define STDMETHODCALLTYPE WINAPI
+#define STDMETHODVCALLTYPE __cdecl
+
+#define STDAPICALLTYPE WINAPI
+#define STDAPIVCALLTYPE __cdecl
+
+#define STDAPI EXTERN_C HRESULT WINAPI
+#define STDAPI_(type) EXTERN_C type WINAPI
+
+#define STDMETHODIMP HRESULT WINAPI
+#define STDMETHODIMP_(type) type WINAPI
+
+#define STDAPIV EXTERN_C HRESULT STDAPIVCALLTYPE
+#define STDAPIV_(type) EXTERN_C type STDAPIVCALLTYPE
+
+#define STDMETHODIMPV HRESULT STDMETHODVCALLTYPE
+#define STDMETHODIMPV_(type) type STDMETHODVCALLTYPE
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+#define __STRUCT__ struct
+#define STDMETHOD(method) virtual HRESULT WINAPI method
+#define STDMETHOD_(type,method) virtual type WINAPI method
+#define STDMETHODV(method) virtual HRESULT STDMETHODVCALLTYPE method
+#define STDMETHODV_(type,method) virtual type STDMETHODVCALLTYPE method
+#define PURE = 0
+#define THIS_
+#define THIS void
+#define DECLARE_INTERFACE(iface) __STRUCT__ iface
+#define DECLARE_INTERFACE_(iface,baseiface) __STRUCT__ iface : public baseiface
+#else
+
+#ifndef __OBJC__
+#define interface struct
+#endif
+
+#define STDMETHOD(method) HRESULT (WINAPI *method)
+#define STDMETHOD_(type,method) type (WINAPI *method)
+#define STDMETHODV(method) HRESULT (STDMETHODVCALLTYPE *method)
+#define STDMETHODV_(type,method) type (STDMETHODVCALLTYPE *method)
+
+#define PURE
+#define THIS_ INTERFACE *This,
+#define THIS INTERFACE *This
+#ifdef CONST_VTABLE
+#define DECLARE_INTERFACE(iface) typedef struct iface { \
+ const struct iface##Vtbl *lpVtbl; } iface; \
+ typedef const struct iface##Vtbl iface##Vtbl; \
+ const struct iface##Vtbl
+#else
+#define DECLARE_INTERFACE(iface) typedef struct iface { \
+ struct iface##Vtbl *lpVtbl; \
+ } iface; \
+ typedef struct iface##Vtbl iface##Vtbl; \
+ struct iface##Vtbl
+#endif
+#define DECLARE_INTERFACE_(iface,baseiface) DECLARE_INTERFACE(iface)
+#endif
+
+#include <guiddef.h>
+
+#ifndef _ERROR_STATUS_T_DEFINED
+#define _ERROR_STATUS_T_DEFINED
+typedef unsigned long error_status_t;
+#endif
+
+#ifndef _WCHAR_T_DEFINED
+typedef unsigned short wchar_t;
+#define _WCHAR_T_DEFINED
+#endif
+#endif
diff --git a/win32/include/winapi/guiddef.h b/win32/include/winapi/guiddef.h
new file mode 100644
index 0000000..4e7909a
--- /dev/null
+++ b/win32/include/winapi/guiddef.h
@@ -0,0 +1,156 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
+typedef struct _GUID {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8 ];
+} GUID;
+#endif
+
+#ifndef UUID_DEFINED
+#define UUID_DEFINED
+typedef GUID UUID;
+#endif
+
+#ifndef FAR
+#define FAR
+#endif
+
+#ifndef DECLSPEC_SELECTANY
+#define DECLSPEC_SELECTANY __declspec(selectany)
+#endif
+
+#ifndef EXTERN_C
+#ifdef __cplusplus
+#define EXTERN_C extern "C"
+#else
+#define EXTERN_C extern
+#endif
+#endif
+
+#ifdef DEFINE_GUID
+#undef DEFINE_GUID
+#endif
+
+#ifdef INITGUID
+#ifdef __cplusplus
+#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) EXTERN_C const GUID DECLSPEC_SELECTANY name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } }
+#else
+#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID DECLSPEC_SELECTANY name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } }
+#endif
+#else
+#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) EXTERN_C const GUID name
+#endif
+
+#define DEFINE_OLEGUID(name,l,w1,w2) DEFINE_GUID(name,l,w1,w2,0xC0,0,0,0,0,0,0,0x46)
+
+#ifndef _GUIDDEF_H_
+#define _GUIDDEF_H_
+
+#ifndef __LPGUID_DEFINED__
+#define __LPGUID_DEFINED__
+typedef GUID *LPGUID;
+#endif
+
+#ifndef __LPCGUID_DEFINED__
+#define __LPCGUID_DEFINED__
+typedef const GUID *LPCGUID;
+#endif
+
+#ifndef __IID_DEFINED__
+#define __IID_DEFINED__
+
+typedef GUID IID;
+typedef IID *LPIID;
+#define IID_NULL GUID_NULL
+#define IsEqualIID(riid1,riid2) IsEqualGUID(riid1,riid2)
+typedef GUID CLSID;
+typedef CLSID *LPCLSID;
+#define CLSID_NULL GUID_NULL
+#define IsEqualCLSID(rclsid1,rclsid2) IsEqualGUID(rclsid1,rclsid2)
+typedef GUID FMTID;
+typedef FMTID *LPFMTID;
+#define FMTID_NULL GUID_NULL
+#define IsEqualFMTID(rfmtid1,rfmtid2) IsEqualGUID(rfmtid1,rfmtid2)
+
+#ifdef __midl_proxy
+#define __MIDL_CONST
+#else
+#define __MIDL_CONST const
+#endif
+
+#ifndef _REFGUID_DEFINED
+#define _REFGUID_DEFINED
+#ifdef __cplusplus
+#define REFGUID const GUID &
+#else
+#define REFGUID const GUID *__MIDL_CONST
+#endif
+#endif
+
+#ifndef _REFIID_DEFINED
+#define _REFIID_DEFINED
+#ifdef __cplusplus
+#define REFIID const IID &
+#else
+#define REFIID const IID *__MIDL_CONST
+#endif
+#endif
+
+#ifndef _REFCLSID_DEFINED
+#define _REFCLSID_DEFINED
+#ifdef __cplusplus
+#define REFCLSID const IID &
+#else
+#define REFCLSID const IID *__MIDL_CONST
+#endif
+#endif
+
+#ifndef _REFFMTID_DEFINED
+#define _REFFMTID_DEFINED
+#ifdef __cplusplus
+#define REFFMTID const IID &
+#else
+#define REFFMTID const IID *__MIDL_CONST
+#endif
+#endif
+#endif
+
+#ifndef _SYS_GUID_OPERATORS_
+#define _SYS_GUID_OPERATORS_
+#include <string.h>
+
+#ifdef __cplusplus
+__inline int InlineIsEqualGUID(REFGUID rguid1,REFGUID rguid2) {
+ return (((unsigned long *) &rguid1)[0]==((unsigned long *) &rguid2)[0] && ((unsigned long *) &rguid1)[1]==((unsigned long *) &rguid2)[1] &&
+ ((unsigned long *) &rguid1)[2]==((unsigned long *) &rguid2)[2] && ((unsigned long *) &rguid1)[3]==((unsigned long *) &rguid2)[3]);
+}
+__inline int IsEqualGUID(REFGUID rguid1,REFGUID rguid2) { return !memcmp(&rguid1,&rguid2,sizeof(GUID)); }
+#else
+#define InlineIsEqualGUID(rguid1,rguid2) (((unsigned long *) rguid1)[0]==((unsigned long *) rguid2)[0] && ((unsigned long *) rguid1)[1]==((unsigned long *) rguid2)[1] && ((unsigned long *) rguid1)[2]==((unsigned long *) rguid2)[2] && ((unsigned long *) rguid1)[3]==((unsigned long *) rguid2)[3])
+#define IsEqualGUID(rguid1,rguid2) (!memcmp(rguid1,rguid2,sizeof(GUID)))
+#endif
+
+#ifdef __INLINE_ISEQUAL_GUID
+#undef IsEqualGUID
+#define IsEqualGUID(rguid1,rguid2) InlineIsEqualGUID(rguid1,rguid2)
+#endif
+
+#define IsEqualIID(riid1,riid2) IsEqualGUID(riid1,riid2)
+#define IsEqualCLSID(rclsid1,rclsid2) IsEqualGUID(rclsid1,rclsid2)
+
+#if !defined _SYS_GUID_OPERATOR_EQ_ && !defined _NO_SYS_GUID_OPERATOR_EQ_
+#define _SYS_GUID_OPERATOR_EQ_
+#ifdef __cplusplus
+__inline int operator==(REFGUID guidOne,REFGUID guidOther) { return IsEqualGUID(guidOne,guidOther); }
+__inline int operator!=(REFGUID guidOne,REFGUID guidOther) { return !(guidOne==guidOther); }
+#endif
+#endif
+#endif
+#endif
diff --git a/win32/include/winapi/poppack.h b/win32/include/winapi/poppack.h
new file mode 100644
index 0000000..b08cba2
--- /dev/null
+++ b/win32/include/winapi/poppack.h
@@ -0,0 +1,8 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#if !(defined(lint) || defined(RC_INVOKED))
+#pragma pack(pop)
+#endif
diff --git a/win32/include/winapi/pshpack1.h b/win32/include/winapi/pshpack1.h
new file mode 100644
index 0000000..d18d9e8
--- /dev/null
+++ b/win32/include/winapi/pshpack1.h
@@ -0,0 +1,8 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#if !(defined(lint) || defined(RC_INVOKED))
+#pragma pack(push,1)
+#endif
diff --git a/win32/include/winapi/pshpack2.h b/win32/include/winapi/pshpack2.h
new file mode 100644
index 0000000..7de16fd
--- /dev/null
+++ b/win32/include/winapi/pshpack2.h
@@ -0,0 +1,8 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#if !(defined(lint) || defined(RC_INVOKED))
+#pragma pack(push,2)
+#endif
diff --git a/win32/include/winapi/pshpack4.h b/win32/include/winapi/pshpack4.h
new file mode 100644
index 0000000..1c8e61d
--- /dev/null
+++ b/win32/include/winapi/pshpack4.h
@@ -0,0 +1,8 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#if !(defined(lint) || defined(RC_INVOKED))
+#pragma pack(push,4)
+#endif
diff --git a/win32/include/winapi/pshpack8.h b/win32/include/winapi/pshpack8.h
new file mode 100644
index 0000000..70a3c7f
--- /dev/null
+++ b/win32/include/winapi/pshpack8.h
@@ -0,0 +1,8 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#if !(defined(lint) || defined(RC_INVOKED))
+#pragma pack(push,8)
+#endif
diff --git a/win32/include/winapi/winbase.h b/win32/include/winapi/winbase.h
new file mode 100644
index 0000000..4a38006
--- /dev/null
+++ b/win32/include/winapi/winbase.h
@@ -0,0 +1,2951 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _WINBASE_
+#define _WINBASE_
+
+#define WINADVAPI DECLSPEC_IMPORT
+#define WINBASEAPI DECLSPEC_IMPORT
+#define ZAWPROXYAPI DECLSPEC_IMPORT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DefineHandleTable(w) ((w),TRUE)
+#define LimitEmsPages(dw)
+#define SetSwapAreaSize(w) (w)
+#define LockSegment(w) GlobalFix((HANDLE)(w))
+#define UnlockSegment(w) GlobalUnfix((HANDLE)(w))
+#define GetCurrentTime() GetTickCount()
+
+#define Yield()
+
+#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
+#define INVALID_FILE_SIZE ((DWORD)0xffffffff)
+#define INVALID_SET_FILE_POINTER ((DWORD)-1)
+#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+
+#define FILE_BEGIN 0
+#define FILE_CURRENT 1
+#define FILE_END 2
+
+#define TIME_ZONE_ID_INVALID ((DWORD)0xffffffff)
+
+#define WAIT_FAILED ((DWORD)0xffffffff)
+#define WAIT_OBJECT_0 ((STATUS_WAIT_0) + 0)
+#define WAIT_ABANDONED ((STATUS_ABANDONED_WAIT_0) + 0)
+#define WAIT_ABANDONED_0 ((STATUS_ABANDONED_WAIT_0) + 0)
+#define WAIT_IO_COMPLETION STATUS_USER_APC
+#define STILL_ACTIVE STATUS_PENDING
+#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION
+#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT
+#define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT
+#define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP
+#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED
+#define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND
+#define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO
+#define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT
+#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION
+#define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW
+#define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK
+#define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW
+#define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO
+#define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW
+#define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION
+#define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR
+#define EXCEPTION_ILLEGAL_INSTRUCTION STATUS_ILLEGAL_INSTRUCTION
+#define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION
+#define EXCEPTION_STACK_OVERFLOW STATUS_STACK_OVERFLOW
+#define EXCEPTION_INVALID_DISPOSITION STATUS_INVALID_DISPOSITION
+#define EXCEPTION_GUARD_PAGE STATUS_GUARD_PAGE_VIOLATION
+#define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE
+#define EXCEPTION_POSSIBLE_DEADLOCK STATUS_POSSIBLE_DEADLOCK
+#define CONTROL_C_EXIT STATUS_CONTROL_C_EXIT
+#define MoveMemory RtlMoveMemory
+#define CopyMemory RtlCopyMemory
+#define FillMemory RtlFillMemory
+#define ZeroMemory RtlZeroMemory
+#define SecureZeroMemory RtlSecureZeroMemory
+
+#define FILE_FLAG_WRITE_THROUGH 0x80000000
+#define FILE_FLAG_OVERLAPPED 0x40000000
+#define FILE_FLAG_NO_BUFFERING 0x20000000
+#define FILE_FLAG_RANDOM_ACCESS 0x10000000
+#define FILE_FLAG_SEQUENTIAL_SCAN 0x8000000
+#define FILE_FLAG_DELETE_ON_CLOSE 0x4000000
+#define FILE_FLAG_BACKUP_SEMANTICS 0x2000000
+#define FILE_FLAG_POSIX_SEMANTICS 0x1000000
+#define FILE_FLAG_OPEN_REPARSE_POINT 0x200000
+#define FILE_FLAG_OPEN_NO_RECALL 0x100000
+#define FILE_FLAG_FIRST_PIPE_INSTANCE 0x80000
+
+#define CREATE_NEW 1
+#define CREATE_ALWAYS 2
+#define OPEN_EXISTING 3
+#define OPEN_ALWAYS 4
+#define TRUNCATE_EXISTING 5
+
+#define PROGRESS_CONTINUE 0
+#define PROGRESS_CANCEL 1
+#define PROGRESS_STOP 2
+#define PROGRESS_QUIET 3
+
+#define CALLBACK_CHUNK_FINISHED 0x0
+#define CALLBACK_STREAM_SWITCH 0x1
+
+#define COPY_FILE_FAIL_IF_EXISTS 0x1
+#define COPY_FILE_RESTARTABLE 0x2
+#define COPY_FILE_OPEN_SOURCE_FOR_WRITE 0x4
+#define COPY_FILE_ALLOW_DECRYPTED_DESTINATION 0x8
+
+#define REPLACEFILE_WRITE_THROUGH 0x1
+#define REPLACEFILE_IGNORE_MERGE_ERRORS 0x2
+
+#define PIPE_ACCESS_INBOUND 0x1
+#define PIPE_ACCESS_OUTBOUND 0x2
+#define PIPE_ACCESS_DUPLEX 0x3
+
+#define PIPE_CLIENT_END 0x0
+#define PIPE_SERVER_END 0x1
+
+#define PIPE_WAIT 0x0
+#define PIPE_NOWAIT 0x1
+#define PIPE_READMODE_BYTE 0x0
+#define PIPE_READMODE_MESSAGE 0x2
+#define PIPE_TYPE_BYTE 0x0
+#define PIPE_TYPE_MESSAGE 0x4
+
+#define PIPE_UNLIMITED_INSTANCES 255
+
+#define SECURITY_ANONYMOUS (SecurityAnonymous << 16)
+#define SECURITY_IDENTIFICATION (SecurityIdentification << 16)
+#define SECURITY_IMPERSONATION (SecurityImpersonation << 16)
+#define SECURITY_DELEGATION (SecurityDelegation << 16)
+
+#define SECURITY_CONTEXT_TRACKING 0x40000
+#define SECURITY_EFFECTIVE_ONLY 0x80000
+
+#define SECURITY_SQOS_PRESENT 0x100000
+#define SECURITY_VALID_SQOS_FLAGS 0x1f0000
+
+ typedef struct _OVERLAPPED {
+ ULONG_PTR Internal;
+ ULONG_PTR InternalHigh;
+ union {
+ struct {
+ DWORD Offset;
+ DWORD OffsetHigh;
+ };
+ PVOID Pointer;
+ };
+ HANDLE hEvent;
+ } OVERLAPPED,*LPOVERLAPPED;
+
+ typedef struct _SECURITY_ATTRIBUTES {
+ DWORD nLength;
+ LPVOID lpSecurityDescriptor;
+ WINBOOL bInheritHandle;
+ } SECURITY_ATTRIBUTES,*PSECURITY_ATTRIBUTES,*LPSECURITY_ATTRIBUTES;
+
+ typedef struct _PROCESS_INFORMATION {
+ HANDLE hProcess;
+ HANDLE hThread;
+ DWORD dwProcessId;
+ DWORD dwThreadId;
+ } PROCESS_INFORMATION,*PPROCESS_INFORMATION,*LPPROCESS_INFORMATION;
+
+#ifndef _FILETIME_
+#define _FILETIME_
+ typedef struct _FILETIME {
+ DWORD dwLowDateTime;
+ DWORD dwHighDateTime;
+ } FILETIME,*PFILETIME,*LPFILETIME;
+#endif
+
+ typedef struct _SYSTEMTIME {
+ WORD wYear;
+ WORD wMonth;
+ WORD wDayOfWeek;
+ WORD wDay;
+ WORD wHour;
+ WORD wMinute;
+ WORD wSecond;
+ WORD wMilliseconds;
+ } SYSTEMTIME,*PSYSTEMTIME,*LPSYSTEMTIME;
+
+ typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
+ typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
+ typedef VOID (WINAPI *PFIBER_START_ROUTINE)(LPVOID lpFiberParameter);
+ typedef PFIBER_START_ROUTINE LPFIBER_START_ROUTINE;
+
+ typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;
+ typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION;
+ typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION;
+ typedef RTL_CRITICAL_SECTION_DEBUG CRITICAL_SECTION_DEBUG;
+ typedef PRTL_CRITICAL_SECTION_DEBUG PCRITICAL_SECTION_DEBUG;
+ typedef PRTL_CRITICAL_SECTION_DEBUG LPCRITICAL_SECTION_DEBUG;
+
+ WINBASEAPI PVOID WINAPI EncodePointer(PVOID Ptr);
+ WINBASEAPI PVOID WINAPI DecodePointer(PVOID Ptr);
+ WINBASEAPI PVOID WINAPI EncodeSystemPointer(PVOID Ptr);
+ WINBASEAPI PVOID WINAPI DecodeSystemPointer(PVOID Ptr);
+
+#ifdef I_X86_
+ typedef PLDT_ENTRY LPLDT_ENTRY;
+#else
+ typedef LPVOID LPLDT_ENTRY;
+#endif
+
+#define MUTEX_MODIFY_STATE MUTANT_QUERY_STATE
+#define MUTEX_ALL_ACCESS MUTANT_ALL_ACCESS
+
+#define SP_SERIALCOMM ((DWORD)0x1)
+
+#define PST_UNSPECIFIED ((DWORD)0x0)
+#define PST_RS232 ((DWORD)0x1)
+#define PST_PARALLELPORT ((DWORD)0x2)
+#define PST_RS422 ((DWORD)0x3)
+#define PST_RS423 ((DWORD)0x4)
+#define PST_RS449 ((DWORD)0x5)
+#define PST_MODEM ((DWORD)0x6)
+#define PST_FAX ((DWORD)0x21)
+#define PST_SCANNER ((DWORD)0x22)
+#define PST_NETWORK_BRIDGE ((DWORD)0x100)
+#define PST_LAT ((DWORD)0x101)
+#define PST_TCPIP_TELNET ((DWORD)0x102)
+#define PST_X25 ((DWORD)0x103)
+
+#define PCF_DTRDSR ((DWORD)0x1)
+#define PCF_RTSCTS ((DWORD)0x2)
+#define PCF_RLSD ((DWORD)0x4)
+#define PCF_PARITY_CHECK ((DWORD)0x8)
+#define PCF_XONXOFF ((DWORD)0x10)
+#define PCF_SETXCHAR ((DWORD)0x20)
+#define PCF_TOTALTIMEOUTS ((DWORD)0x40)
+#define PCF_INTTIMEOUTS ((DWORD)0x80)
+#define PCF_SPECIALCHARS ((DWORD)0x100)
+#define PCF_16BITMODE ((DWORD)0x200)
+
+#define SP_PARITY ((DWORD)0x1)
+#define SP_BAUD ((DWORD)0x2)
+#define SP_DATABITS ((DWORD)0x4)
+#define SP_STOPBITS ((DWORD)0x8)
+#define SP_HANDSHAKING ((DWORD)0x10)
+#define SP_PARITY_CHECK ((DWORD)0x20)
+#define SP_RLSD ((DWORD)0x40)
+
+#define BAUD_075 ((DWORD)0x1)
+#define BAUD_110 ((DWORD)0x2)
+#define BAUD_134_5 ((DWORD)0x4)
+#define BAUD_150 ((DWORD)0x8)
+#define BAUD_300 ((DWORD)0x10)
+#define BAUD_600 ((DWORD)0x20)
+#define BAUD_1200 ((DWORD)0x40)
+#define BAUD_1800 ((DWORD)0x80)
+#define BAUD_2400 ((DWORD)0x100)
+#define BAUD_4800 ((DWORD)0x200)
+#define BAUD_7200 ((DWORD)0x400)
+#define BAUD_9600 ((DWORD)0x800)
+#define BAUD_14400 ((DWORD)0x1000)
+#define BAUD_19200 ((DWORD)0x2000)
+#define BAUD_38400 ((DWORD)0x4000)
+#define BAUD_56K ((DWORD)0x8000)
+#define BAUD_128K ((DWORD)0x10000)
+#define BAUD_115200 ((DWORD)0x20000)
+#define BAUD_57600 ((DWORD)0x40000)
+#define BAUD_USER ((DWORD)0x10000000)
+
+#define DATABITS_5 ((WORD)0x1)
+#define DATABITS_6 ((WORD)0x2)
+#define DATABITS_7 ((WORD)0x4)
+#define DATABITS_8 ((WORD)0x8)
+#define DATABITS_16 ((WORD)0x10)
+#define DATABITS_16X ((WORD)0x20)
+
+#define STOPBITS_10 ((WORD)0x1)
+#define STOPBITS_15 ((WORD)0x2)
+#define STOPBITS_20 ((WORD)0x4)
+#define PARITY_NONE ((WORD)0x100)
+#define PARITY_ODD ((WORD)0x200)
+#define PARITY_EVEN ((WORD)0x400)
+#define PARITY_MARK ((WORD)0x800)
+#define PARITY_SPACE ((WORD)0x1000)
+
+ typedef struct _COMMPROP {
+ WORD wPacketLength;
+ WORD wPacketVersion;
+ DWORD dwServiceMask;
+ DWORD dwReserved1;
+ DWORD dwMaxTxQueue;
+ DWORD dwMaxRxQueue;
+ DWORD dwMaxBaud;
+ DWORD dwProvSubType;
+ DWORD dwProvCapabilities;
+ DWORD dwSettableParams;
+ DWORD dwSettableBaud;
+ WORD wSettableData;
+ WORD wSettableStopParity;
+ DWORD dwCurrentTxQueue;
+ DWORD dwCurrentRxQueue;
+ DWORD dwProvSpec1;
+ DWORD dwProvSpec2;
+ WCHAR wcProvChar[1];
+ } COMMPROP,*LPCOMMPROP;
+
+#define COMMPROP_INITIALIZED ((DWORD)0xE73CF52E)
+
+ typedef struct _COMSTAT {
+ DWORD fCtsHold : 1;
+ DWORD fDsrHold : 1;
+ DWORD fRlsdHold : 1;
+ DWORD fXoffHold : 1;
+ DWORD fXoffSent : 1;
+ DWORD fEof : 1;
+ DWORD fTxim : 1;
+ DWORD fReserved : 25;
+ DWORD cbInQue;
+ DWORD cbOutQue;
+ } COMSTAT,*LPCOMSTAT;
+
+#define DTR_CONTROL_DISABLE 0x0
+#define DTR_CONTROL_ENABLE 0x1
+#define DTR_CONTROL_HANDSHAKE 0x2
+
+#define RTS_CONTROL_DISABLE 0x0
+#define RTS_CONTROL_ENABLE 0x1
+#define RTS_CONTROL_HANDSHAKE 0x2
+#define RTS_CONTROL_TOGGLE 0x3
+
+ typedef struct _DCB {
+ DWORD DCBlength;
+ DWORD BaudRate;
+ DWORD fBinary: 1;
+ DWORD fParity: 1;
+ DWORD fOutxCtsFlow:1;
+ DWORD fOutxDsrFlow:1;
+ DWORD fDtrControl:2;
+ DWORD fDsrSensitivity:1;
+ DWORD fTXContinueOnXoff: 1;
+ DWORD fOutX: 1;
+ DWORD fInX: 1;
+ DWORD fErrorChar: 1;
+ DWORD fNull: 1;
+ DWORD fRtsControl:2;
+ DWORD fAbortOnError:1;
+ DWORD fDummy2:17;
+ WORD wReserved;
+ WORD XonLim;
+ WORD XoffLim;
+ BYTE ByteSize;
+ BYTE Parity;
+ BYTE StopBits;
+ char XonChar;
+ char XoffChar;
+ char ErrorChar;
+ char EofChar;
+ char EvtChar;
+ WORD wReserved1;
+ } DCB,*LPDCB;
+
+ typedef struct _COMMTIMEOUTS {
+ DWORD ReadIntervalTimeout;
+ DWORD ReadTotalTimeoutMultiplier;
+ DWORD ReadTotalTimeoutConstant;
+ DWORD WriteTotalTimeoutMultiplier;
+ DWORD WriteTotalTimeoutConstant;
+ } COMMTIMEOUTS,*LPCOMMTIMEOUTS;
+
+ typedef struct _COMMCONFIG {
+ DWORD dwSize;
+ WORD wVersion;
+ WORD wReserved;
+ DCB dcb;
+ DWORD dwProviderSubType;
+ DWORD dwProviderOffset;
+ DWORD dwProviderSize;
+ WCHAR wcProviderData[1];
+ } COMMCONFIG,*LPCOMMCONFIG;
+
+ typedef struct _SYSTEM_INFO {
+ union {
+ DWORD dwOemId;
+ struct {
+ WORD wProcessorArchitecture;
+ WORD wReserved;
+ };
+ };
+ DWORD dwPageSize;
+ LPVOID lpMinimumApplicationAddress;
+ LPVOID lpMaximumApplicationAddress;
+ DWORD_PTR dwActiveProcessorMask;
+ DWORD dwNumberOfProcessors;
+ DWORD dwProcessorType;
+ DWORD dwAllocationGranularity;
+ WORD wProcessorLevel;
+ WORD wProcessorRevision;
+ } SYSTEM_INFO,*LPSYSTEM_INFO;
+
+#define FreeModule(hLibModule) FreeLibrary((hLibModule))
+#define MakeProcInstance(lpProc,hInstance) (lpProc)
+#define FreeProcInstance(lpProc) (lpProc)
+
+#define GMEM_FIXED 0x0
+#define GMEM_MOVEABLE 0x2
+#define GMEM_NOCOMPACT 0x10
+#define GMEM_NODISCARD 0x20
+#define GMEM_ZEROINIT 0x40
+#define GMEM_MODIFY 0x80
+#define GMEM_DISCARDABLE 0x100
+#define GMEM_NOT_BANKED 0x1000
+#define GMEM_SHARE 0x2000
+#define GMEM_DDESHARE 0x2000
+#define GMEM_NOTIFY 0x4000
+#define GMEM_LOWER GMEM_NOT_BANKED
+#define GMEM_VALID_FLAGS 0x7F72
+#define GMEM_INVALID_HANDLE 0x8000
+
+#define GHND (GMEM_MOVEABLE | GMEM_ZEROINIT)
+#define GPTR (GMEM_FIXED | GMEM_ZEROINIT)
+
+#define GlobalLRUNewest(h) ((HANDLE)(h))
+#define GlobalLRUOldest(h) ((HANDLE)(h))
+#define GlobalDiscard(h) GlobalReAlloc((h),0,GMEM_MOVEABLE)
+
+#define GMEM_DISCARDED 0x4000
+#define GMEM_LOCKCOUNT 0xff
+
+ typedef struct _MEMORYSTATUS {
+ DWORD dwLength;
+ DWORD dwMemoryLoad;
+ SIZE_T dwTotalPhys;
+ SIZE_T dwAvailPhys;
+ SIZE_T dwTotalPageFile;
+ SIZE_T dwAvailPageFile;
+ SIZE_T dwTotalVirtual;
+ SIZE_T dwAvailVirtual;
+ } MEMORYSTATUS,*LPMEMORYSTATUS;
+
+#define LMEM_FIXED 0x0
+#define LMEM_MOVEABLE 0x2
+#define LMEM_NOCOMPACT 0x10
+#define LMEM_NODISCARD 0x20
+#define LMEM_ZEROINIT 0x40
+#define LMEM_MODIFY 0x80
+#define LMEM_DISCARDABLE 0xf00
+#define LMEM_VALID_FLAGS 0xf72
+#define LMEM_INVALID_HANDLE 0x8000
+
+#define LHND (LMEM_MOVEABLE | LMEM_ZEROINIT)
+#define LPTR (LMEM_FIXED | LMEM_ZEROINIT)
+
+#define NONZEROLHND (LMEM_MOVEABLE)
+#define NONZEROLPTR (LMEM_FIXED)
+
+#define LocalDiscard(h) LocalReAlloc((h),0,LMEM_MOVEABLE)
+
+#define LMEM_DISCARDED 0x4000
+#define LMEM_LOCKCOUNT 0xff
+
+#define DEBUG_PROCESS 0x1
+#define DEBUG_ONLY_THIS_PROCESS 0x2
+#define CREATE_SUSPENDED 0x4
+#define DETACHED_PROCESS 0x8
+#define CREATE_NEW_CONSOLE 0x10
+#define NORMAL_PRIORITY_CLASS 0x20
+#define IDLE_PRIORITY_CLASS 0x40
+#define HIGH_PRIORITY_CLASS 0x80
+#define REALTIME_PRIORITY_CLASS 0x100
+#define CREATE_NEW_PROCESS_GROUP 0x200
+#define CREATE_UNICODE_ENVIRONMENT 0x400
+#define CREATE_SEPARATE_WOW_VDM 0x800
+#define CREATE_SHARED_WOW_VDM 0x1000
+#define CREATE_FORCEDOS 0x2000
+#define BELOW_NORMAL_PRIORITY_CLASS 0x4000
+#define ABOVE_NORMAL_PRIORITY_CLASS 0x8000
+#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x10000
+
+#define CREATE_BREAKAWAY_FROM_JOB 0x1000000
+#define CREATE_PRESERVE_CODE_AUTHZ_LEVEL 0x2000000
+
+#define CREATE_DEFAULT_ERROR_MODE 0x4000000
+#define CREATE_NO_WINDOW 0x8000000
+
+#define PROFILE_USER 0x10000000
+#define PROFILE_KERNEL 0x20000000
+#define PROFILE_SERVER 0x40000000
+
+#define CREATE_IGNORE_SYSTEM_DEFAULT 0x80000000
+
+#define THREAD_PRIORITY_LOWEST THREAD_BASE_PRIORITY_MIN
+#define THREAD_PRIORITY_BELOW_NORMAL (THREAD_PRIORITY_LOWEST+1)
+#define THREAD_PRIORITY_NORMAL 0
+#define THREAD_PRIORITY_HIGHEST THREAD_BASE_PRIORITY_MAX
+#define THREAD_PRIORITY_ABOVE_NORMAL (THREAD_PRIORITY_HIGHEST-1)
+#define THREAD_PRIORITY_ERROR_RETURN (MAXLONG)
+
+#define THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT
+#define THREAD_PRIORITY_IDLE THREAD_BASE_PRIORITY_IDLE
+
+#define EXCEPTION_DEBUG_EVENT 1
+#define CREATE_THREAD_DEBUG_EVENT 2
+#define CREATE_PROCESS_DEBUG_EVENT 3
+#define EXIT_THREAD_DEBUG_EVENT 4
+#define EXIT_PROCESS_DEBUG_EVENT 5
+#define LOAD_DLL_DEBUG_EVENT 6
+#define UNLOAD_DLL_DEBUG_EVENT 7
+#define OUTPUT_DEBUG_STRING_EVENT 8
+#define RIP_EVENT 9
+
+ typedef struct _EXCEPTION_DEBUG_INFO {
+ EXCEPTION_RECORD ExceptionRecord;
+ DWORD dwFirstChance;
+ } EXCEPTION_DEBUG_INFO,*LPEXCEPTION_DEBUG_INFO;
+
+ typedef struct _CREATE_THREAD_DEBUG_INFO {
+ HANDLE hThread;
+ LPVOID lpThreadLocalBase;
+ LPTHREAD_START_ROUTINE lpStartAddress;
+ } CREATE_THREAD_DEBUG_INFO,*LPCREATE_THREAD_DEBUG_INFO;
+
+ typedef struct _CREATE_PROCESS_DEBUG_INFO {
+ HANDLE hFile;
+ HANDLE hProcess;
+ HANDLE hThread;
+ LPVOID lpBaseOfImage;
+ DWORD dwDebugInfoFileOffset;
+ DWORD nDebugInfoSize;
+ LPVOID lpThreadLocalBase;
+ LPTHREAD_START_ROUTINE lpStartAddress;
+ LPVOID lpImageName;
+ WORD fUnicode;
+ } CREATE_PROCESS_DEBUG_INFO,*LPCREATE_PROCESS_DEBUG_INFO;
+
+ typedef struct _EXIT_THREAD_DEBUG_INFO {
+ DWORD dwExitCode;
+ } EXIT_THREAD_DEBUG_INFO,*LPEXIT_THREAD_DEBUG_INFO;
+
+ typedef struct _EXIT_PROCESS_DEBUG_INFO {
+ DWORD dwExitCode;
+ } EXIT_PROCESS_DEBUG_INFO,*LPEXIT_PROCESS_DEBUG_INFO;
+
+ typedef struct _LOAD_DLL_DEBUG_INFO {
+ HANDLE hFile;
+ LPVOID lpBaseOfDll;
+ DWORD dwDebugInfoFileOffset;
+ DWORD nDebugInfoSize;
+ LPVOID lpImageName;
+ WORD fUnicode;
+ } LOAD_DLL_DEBUG_INFO,*LPLOAD_DLL_DEBUG_INFO;
+
+ typedef struct _UNLOAD_DLL_DEBUG_INFO {
+ LPVOID lpBaseOfDll;
+ } UNLOAD_DLL_DEBUG_INFO,*LPUNLOAD_DLL_DEBUG_INFO;
+
+ typedef struct _OUTPUT_DEBUG_STRING_INFO {
+ LPSTR lpDebugStringData;
+ WORD fUnicode;
+ WORD nDebugStringLength;
+ } OUTPUT_DEBUG_STRING_INFO,*LPOUTPUT_DEBUG_STRING_INFO;
+
+ typedef struct _RIP_INFO {
+ DWORD dwError;
+ DWORD dwType;
+ } RIP_INFO,*LPRIP_INFO;
+
+ typedef struct _DEBUG_EVENT {
+ DWORD dwDebugEventCode;
+ DWORD dwProcessId;
+ DWORD dwThreadId;
+ union {
+ EXCEPTION_DEBUG_INFO Exception;
+ CREATE_THREAD_DEBUG_INFO CreateThread;
+ CREATE_PROCESS_DEBUG_INFO CreateProcessInfo;
+ EXIT_THREAD_DEBUG_INFO ExitThread;
+ EXIT_PROCESS_DEBUG_INFO ExitProcess;
+ LOAD_DLL_DEBUG_INFO LoadDll;
+ UNLOAD_DLL_DEBUG_INFO UnloadDll;
+ OUTPUT_DEBUG_STRING_INFO DebugString;
+ RIP_INFO RipInfo;
+ } u;
+ } DEBUG_EVENT,*LPDEBUG_EVENT;
+
+ typedef PCONTEXT LPCONTEXT;
+ typedef PEXCEPTION_RECORD LPEXCEPTION_RECORD;
+ typedef PEXCEPTION_POINTERS LPEXCEPTION_POINTERS;
+
+#define DRIVE_UNKNOWN 0
+#define DRIVE_NO_ROOT_DIR 1
+#define DRIVE_REMOVABLE 2
+#define DRIVE_FIXED 3
+#define DRIVE_REMOTE 4
+#define DRIVE_CDROM 5
+#define DRIVE_RAMDISK 6
+
+#define GetFreeSpace(w) (0x100000L)
+#define FILE_TYPE_UNKNOWN 0x0
+#define FILE_TYPE_DISK 0x1
+#define FILE_TYPE_CHAR 0x2
+#define FILE_TYPE_PIPE 0x3
+#define FILE_TYPE_REMOTE 0x8000
+
+#define STD_INPUT_HANDLE ((DWORD)-10)
+#define STD_OUTPUT_HANDLE ((DWORD)-11)
+#define STD_ERROR_HANDLE ((DWORD)-12)
+
+#define NOPARITY 0
+#define ODDPARITY 1
+#define EVENPARITY 2
+#define MARKPARITY 3
+#define SPACEPARITY 4
+
+#define ONESTOPBIT 0
+#define ONE5STOPBITS 1
+#define TWOSTOPBITS 2
+
+#define IGNORE 0
+#define INFINITE 0xffffffff
+
+#define CBR_110 110
+#define CBR_300 300
+#define CBR_600 600
+#define CBR_1200 1200
+#define CBR_2400 2400
+#define CBR_4800 4800
+#define CBR_9600 9600
+#define CBR_14400 14400
+#define CBR_19200 19200
+#define CBR_38400 38400
+#define CBR_56000 56000
+#define CBR_57600 57600
+#define CBR_115200 115200
+#define CBR_128000 128000
+#define CBR_256000 256000
+
+#define CE_RXOVER 0x1
+#define CE_OVERRUN 0x2
+#define CE_RXPARITY 0x4
+#define CE_FRAME 0x8
+#define CE_BREAK 0x10
+#define CE_TXFULL 0x100
+#define CE_PTO 0x200
+#define CE_IOE 0x400
+#define CE_DNS 0x800
+#define CE_OOP 0x1000
+#define CE_MODE 0x8000
+
+#define IE_BADID (-1)
+#define IE_OPEN (-2)
+#define IE_NOPEN (-3)
+#define IE_MEMORY (-4)
+#define IE_DEFAULT (-5)
+#define IE_HARDWARE (-10)
+#define IE_BYTESIZE (-11)
+#define IE_BAUDRATE (-12)
+
+#define EV_RXCHAR 0x1
+#define EV_RXFLAG 0x2
+#define EV_TXEMPTY 0x4
+#define EV_CTS 0x8
+#define EV_DSR 0x10
+#define EV_RLSD 0x20
+#define EV_BREAK 0x40
+#define EV_ERR 0x80
+#define EV_RING 0x100
+#define EV_PERR 0x200
+#define EV_RX80FULL 0x400
+#define EV_EVENT1 0x800
+#define EV_EVENT2 0x1000
+
+#define SETXOFF 1
+#define SETXON 2
+#define SETRTS 3
+#define CLRRTS 4
+#define SETDTR 5
+#define CLRDTR 6
+#define RESETDEV 7
+#define SETBREAK 8
+#define CLRBREAK 9
+
+#define PURGE_TXABORT 0x1
+#define PURGE_RXABORT 0x2
+#define PURGE_TXCLEAR 0x4
+#define PURGE_RXCLEAR 0x8
+
+#define LPTx 0x80
+
+#define MS_CTS_ON ((DWORD)0x10)
+#define MS_DSR_ON ((DWORD)0x20)
+#define MS_RING_ON ((DWORD)0x40)
+#define MS_RLSD_ON ((DWORD)0x80)
+
+#define S_QUEUEEMPTY 0
+#define S_THRESHOLD 1
+#define S_ALLTHRESHOLD 2
+
+#define S_NORMAL 0
+#define S_LEGATO 1
+#define S_STACCATO 2
+
+#define S_PERIOD512 0
+#define S_PERIOD1024 1
+#define S_PERIOD2048 2
+#define S_PERIODVOICE 3
+#define S_WHITE512 4
+#define S_WHITE1024 5
+#define S_WHITE2048 6
+#define S_WHITEVOICE 7
+
+#define S_SERDVNA (-1)
+#define S_SEROFM (-2)
+#define S_SERMACT (-3)
+#define S_SERQFUL (-4)
+#define S_SERBDNT (-5)
+#define S_SERDLN (-6)
+#define S_SERDCC (-7)
+#define S_SERDTP (-8)
+#define S_SERDVL (-9)
+#define S_SERDMD (-10)
+#define S_SERDSH (-11)
+#define S_SERDPT (-12)
+#define S_SERDFQ (-13)
+#define S_SERDDR (-14)
+#define S_SERDSR (-15)
+#define S_SERDST (-16)
+
+#define NMPWAIT_WAIT_FOREVER 0xffffffff
+#define NMPWAIT_NOWAIT 0x1
+#define NMPWAIT_USE_DEFAULT_WAIT 0x0
+
+#define FS_CASE_IS_PRESERVED FILE_CASE_PRESERVED_NAMES
+#define FS_CASE_SENSITIVE FILE_CASE_SENSITIVE_SEARCH
+#define FS_UNICODE_STORED_ON_DISK FILE_UNICODE_ON_DISK
+#define FS_PERSISTENT_ACLS FILE_PERSISTENT_ACLS
+#define FS_VOL_IS_COMPRESSED FILE_VOLUME_IS_COMPRESSED
+#define FS_FILE_COMPRESSION FILE_FILE_COMPRESSION
+#define FS_FILE_ENCRYPTION FILE_SUPPORTS_ENCRYPTION
+
+#define FILE_MAP_COPY SECTION_QUERY
+#define FILE_MAP_WRITE SECTION_MAP_WRITE
+#define FILE_MAP_READ SECTION_MAP_READ
+#define FILE_MAP_ALL_ACCESS SECTION_ALL_ACCESS
+#define FILE_MAP_EXECUTE SECTION_MAP_EXECUTE_EXPLICIT
+
+#define OF_READ 0x0
+#define OF_WRITE 0x1
+#define OF_READWRITE 0x2
+#define OF_SHARE_COMPAT 0x0
+#define OF_SHARE_EXCLUSIVE 0x10
+#define OF_SHARE_DENY_WRITE 0x20
+#define OF_SHARE_DENY_READ 0x30
+#define OF_SHARE_DENY_NONE 0x40
+#define OF_PARSE 0x100
+#define OF_DELETE 0x200
+#define OF_VERIFY 0x400
+#define OF_CANCEL 0x800
+#define OF_CREATE 0x1000
+#define OF_PROMPT 0x2000
+#define OF_EXIST 0x4000
+#define OF_REOPEN 0x8000
+
+#define OFS_MAXPATHNAME 128
+ typedef struct _OFSTRUCT {
+ BYTE cBytes;
+ BYTE fFixedDisk;
+ WORD nErrCode;
+ WORD Reserved1;
+ WORD Reserved2;
+ CHAR szPathName[OFS_MAXPATHNAME];
+ } OFSTRUCT,*LPOFSTRUCT,*POFSTRUCT;
+
+#ifndef NOWINBASEINTERLOCK
+
+#ifndef _NTOS_
+
+#if defined(__ia64__) && !defined(RC_INVOKED)
+
+#define InterlockedIncrement _InterlockedIncrement
+#define InterlockedIncrementAcquire _InterlockedIncrement_acq
+#define InterlockedIncrementRelease _InterlockedIncrement_rel
+#define InterlockedDecrement _InterlockedDecrement
+#define InterlockedDecrementAcquire _InterlockedDecrement_acq
+#define InterlockedDecrementRelease _InterlockedDecrement_rel
+#define InterlockedExchange _InterlockedExchange
+#define InterlockedExchangeAdd _InterlockedExchangeAdd
+#define InterlockedCompareExchange _InterlockedCompareExchange
+#define InterlockedCompareExchangeAcquire _InterlockedCompareExchange_acq
+#define InterlockedCompareExchangeRelease _InterlockedCompareExchange_rel
+#define InterlockedExchangePointer _InterlockedExchangePointer
+#define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer
+#define InterlockedCompareExchangePointerRelease _InterlockedCompareExchangePointer_rel
+#define InterlockedCompareExchangePointerAcquire _InterlockedCompareExchangePointer_acq
+
+#define InterlockedIncrement64 _InterlockedIncrement64
+#define InterlockedDecrement64 _InterlockedDecrement64
+#define InterlockedExchange64 _InterlockedExchange64
+#define InterlockedExchangeAcquire64 _InterlockedExchange64_acq
+#define InterlockedExchangeAdd64 _InterlockedExchangeAdd64
+#define InterlockedCompareExchange64 _InterlockedCompareExchange64
+#define InterlockedCompareExchangeAcquire64 _InterlockedCompareExchange64_acq
+#define InterlockedCompareExchangeRelease64 _InterlockedCompareExchange64_rel
+
+ LONGLONG __cdecl InterlockedIncrement64(LONGLONG volatile *Addend);
+ LONGLONG __cdecl InterlockedDecrement64(LONGLONG volatile *Addend);
+ LONG __cdecl InterlockedIncrementAcquire(LONG volatile *Addend);
+ LONG __cdecl InterlockedDecrementAcquire(LONG volatile *Addend);
+ LONG __cdecl InterlockedIncrementRelease(LONG volatile *Addend);
+ LONG __cdecl InterlockedDecrementRelease(LONG volatile *Addend);
+ LONGLONG __cdecl InterlockedExchange64 (LONGLONG volatile *Target,LONGLONG Value);
+ LONGLONG __cdecl InterlockedExchangeAcquire64 (LONGLONG volatile *Target,LONGLONG Value);
+ LONGLONG __cdecl InterlockedExchangeAdd64 (LONGLONG volatile *Addend,LONGLONG Value);
+ LONGLONG __cdecl InterlockedCompareExchange64 (LONGLONG volatile *Destination,LONGLONG ExChange,LONGLONG Comperand);
+ LONGLONG __cdecl InterlockedCompareExchangeAcquire64 (LONGLONG volatile *Destination,LONGLONG ExChange,LONGLONG Comperand);
+ LONGLONG __cdecl InterlockedCompareExchangeRelease64 (LONGLONG volatile *Destination,LONGLONG ExChange,LONGLONG Comperand);
+ LONG __cdecl InterlockedIncrement(LONG volatile *lpAddend);
+ LONG __cdecl InterlockedDecrement(LONG volatile *lpAddend);
+ LONG __cdecl InterlockedExchange(LONG volatile *Target,LONG Value);
+ LONG __cdecl InterlockedExchangeAdd(LONG volatile *Addend,LONG Value);
+ LONG __cdecl InterlockedCompareExchange(LONG volatile *Destination,LONG ExChange,LONG Comperand);
+ LONG __cdecl InterlockedCompareExchangeRelease(LONG volatile *Destination,LONG ExChange,LONG Comperand);
+ LONG __cdecl InterlockedCompareExchangeAcquire(LONG volatile *Destination,LONG ExChange,LONG Comperand);
+ PVOID __cdecl InterlockedExchangePointer(PVOID volatile *Target,PVOID Value);
+ PVOID __cdecl InterlockedCompareExchangePointer(PVOID volatile *Destination,PVOID ExChange,PVOID Comperand);
+ PVOID __cdecl InterlockedCompareExchangePointerAcquire(PVOID volatile *Destination,PVOID Exchange,PVOID Comperand);
+ PVOID __cdecl InterlockedCompareExchangePointerRelease(PVOID volatile *Destination,PVOID Exchange,PVOID Comperand);
+
+#ifndef InterlockedAnd
+#define InterlockedAnd InterlockedAnd_Inline
+ __CRT_INLINE LONG InterlockedAnd_Inline(LONG volatile *Target,LONG Set) {
+ LONG i;
+ LONG j;
+ j = *Target;
+ do {
+ i = j;
+ j = InterlockedCompareExchange(Target,i & Set,i);
+ } while(i!=j);
+ return j;
+ }
+#endif
+
+#ifndef InterlockedOr
+#define InterlockedOr InterlockedOr_Inline
+
+ __CRT_INLINE LONG InterlockedOr_Inline(LONG volatile *Target,LONG Set) {
+ LONG i;
+ LONG j;
+ j = *Target;
+ do {
+ i = j;
+ j = InterlockedCompareExchange(Target,i | Set,i);
+ } while(i!=j);
+ return j;
+ }
+#endif
+
+#ifndef InterlockedXor
+#define InterlockedXor InterlockedXor_Inline
+
+ __CRT_INLINE LONG InterlockedXor_Inline(LONG volatile *Target,LONG Set) {
+ LONG i;
+ LONG j;
+ j = *Target;
+ do {
+ i = j;
+ j = InterlockedCompareExchange(Target,i ^ Set,i);
+ } while(i!=j);
+ return j;
+ }
+#endif
+
+#ifndef !defined (InterlockedAnd64)
+#define InterlockedAnd64 InterlockedAnd64_Inline
+
+ __CRT_INLINE LONGLONG InterlockedAnd64_Inline (LONGLONG volatile *Destination,LONGLONG Value) {
+ LONGLONG Old;
+ do {
+ Old = *Destination;
+ } while(InterlockedCompareExchange64(Destination,Old & Value,Old)!=Old);
+ return Old;
+ }
+#endif
+
+#ifndef InterlockedOr64
+#define InterlockedOr64 InterlockedOr64_Inline
+
+ __CRT_INLINE LONGLONG InterlockedOr64_Inline (LONGLONG volatile *Destination,LONGLONG Value) {
+ LONGLONG Old;
+ do {
+ Old = *Destination;
+ } while(InterlockedCompareExchange64(Destination,Old | Value,Old)!=Old);
+ return Old;
+ }
+#endif
+
+#ifndef InterlockedXor64
+#define InterlockedXor64 InterlockedXor64_Inline
+
+ __CRT_INLINE LONGLONG InterlockedXor64_Inline (LONGLONG volatile *Destination,LONGLONG Value) {
+ LONGLONG Old;
+ do {
+ Old = *Destination;
+ } while(InterlockedCompareExchange64(Destination,Old ^ Value,Old)!=Old);
+ return Old;
+ }
+#endif
+
+#ifndef InterlockedBitTestAndSet
+#define InterlockedBitTestAndSet InterlockedBitTestAndSet_Inline
+
+ __CRT_INLINE BOOLEAN InterlockedBitTestAndSet_Inline(LONG *Base,LONG Bit) {
+ LONG tBit;
+ tBit = 1<<(Bit & (sizeof (*Base)*8-1));
+ return (BOOLEAN)((InterlockedOr(&Base[Bit/(sizeof(*Base)*8)],tBit)&tBit)!=0);
+ }
+#endif
+
+#ifndef InterlockedBitTestAndReset
+#define InterlockedBitTestAndReset InterlockedBitTestAndReset_Inline
+
+ __CRT_INLINE BOOLEAN InterlockedBitTestAndReset_Inline(LONG *Base,LONG Bit) {
+ LONG tBit;
+ tBit = 1<<(Bit & (sizeof (*Base)*8-1));
+ return (BOOLEAN)((InterlockedAnd(&Base[Bit/(sizeof(*Base)*8)],~tBit)&tBit)!=0);
+ }
+#endif
+
+#ifndef InterlockedBitTestAndComplement
+#define InterlockedBitTestAndComplement InterlockedBitTestAndComplement_Inline
+
+ __CRT_INLINE BOOLEAN InterlockedBitTestAndComplement_Inline(LONG *Base,LONG Bit) {
+ LONG tBit;
+ tBit = 1<<(Bit & (sizeof (*Base)*8-1));
+ return (BOOLEAN)((InterlockedXor(&Base[Bit/(sizeof(*Base)*8)],tBit)&tBit)!=0);
+ }
+#endif
+#elif defined(__x86_64) && !defined(RC_INVOKED)
+
+#define InterlockedIncrement _InterlockedIncrement
+#define InterlockedIncrementAcquire InterlockedIncrement
+#define InterlockedIncrementRelease InterlockedIncrement
+#define InterlockedDecrement _InterlockedDecrement
+#define InterlockedDecrementAcquire InterlockedDecrement
+#define InterlockedDecrementRelease InterlockedDecrement
+#define InterlockedExchange _InterlockedExchange
+#define InterlockedExchangeAdd _InterlockedExchangeAdd
+#define InterlockedCompareExchange _InterlockedCompareExchange
+#define InterlockedCompareExchangeAcquire InterlockedCompareExchange
+#define InterlockedCompareExchangeRelease InterlockedCompareExchange
+#define InterlockedExchangePointer _InterlockedExchangePointer
+#define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer
+#define InterlockedCompareExchangePointerAcquire _InterlockedCompareExchangePointer
+#define InterlockedCompareExchangePointerRelease _InterlockedCompareExchangePointer
+#define InterlockedAnd64 _InterlockedAnd64
+#define InterlockedOr64 _InterlockedOr64
+#define InterlockedXor64 _InterlockedXor64
+#define InterlockedIncrement64 _InterlockedIncrement64
+#define InterlockedDecrement64 _InterlockedDecrement64
+#define InterlockedExchange64 _InterlockedExchange64
+#define InterlockedExchangeAdd64 _InterlockedExchangeAdd64
+#define InterlockedCompareExchange64 _InterlockedCompareExchange64
+#define InterlockedCompareExchangeAcquire64 InterlockedCompareExchange64
+#define InterlockedCompareExchangeRelease64 InterlockedCompareExchange64
+
+ LONG InterlockedIncrement(LONG volatile *Addend);
+ LONG InterlockedDecrement(LONG volatile *Addend);
+ LONG InterlockedExchange(LONG volatile *Target,LONG Value);
+ LONG InterlockedExchangeAdd(LONG volatile *Addend,LONG Value);
+ LONG InterlockedCompareExchange(LONG volatile *Destination,LONG ExChange,LONG Comperand);
+ PVOID InterlockedCompareExchangePointer(PVOID volatile *Destination,PVOID Exchange,PVOID Comperand);
+ PVOID InterlockedExchangePointer(PVOID volatile *Target,PVOID Value);
+ LONG64 InterlockedAnd64(LONG64 volatile *Destination,LONG64 Value);
+ LONG64 InterlockedOr64(LONG64 volatile *Destination,LONG64 Value);
+ LONG64 InterlockedXor64(LONG64 volatile *Destination,LONG64 Value);
+ LONG64 InterlockedIncrement64(LONG64 volatile *Addend);
+ LONG64 InterlockedDecrement64(LONG64 volatile *Addend);
+ LONG64 InterlockedExchange64(LONG64 volatile *Target,LONG64 Value);
+ LONG64 InterlockedExchangeAdd64(LONG64 volatile *Addend,LONG64 Value);
+ LONG64 InterlockedCompareExchange64(LONG64 volatile *Destination,LONG64 ExChange,LONG64 Comperand);
+#else
+ LONG WINAPI InterlockedIncrement(LONG volatile *lpAddend);
+ LONG WINAPI InterlockedDecrement(LONG volatile *lpAddend);
+ LONG WINAPI InterlockedExchange(LONG volatile *Target,LONG Value);
+
+#define InterlockedExchangePointer(Target,Value) (PVOID)InterlockedExchange((PLONG)(Target),(LONG)(Value))
+
+ LONG WINAPI InterlockedExchangeAdd(LONG volatile *Addend,LONG Value);
+ LONG WINAPI InterlockedCompareExchange(LONG volatile *Destination,LONG Exchange,LONG Comperand);
+ LONGLONG WINAPI InterlockedCompareExchange64(LONGLONG volatile *Destination,LONGLONG Exchange,LONGLONG Comperand);
+
+ __CRT_INLINE LONGLONG InterlockedAnd64 (LONGLONG volatile *Destination,LONGLONG Value) {
+ LONGLONG Old;
+ do {
+ Old = *Destination;
+ } while(InterlockedCompareExchange64(Destination,Old & Value,Old)!=Old);
+ return Old;
+ }
+
+ __CRT_INLINE LONGLONG InterlockedOr64 (LONGLONG volatile *Destination,LONGLONG Value) {
+ LONGLONG Old;
+ do {
+ Old = *Destination;
+ } while(InterlockedCompareExchange64(Destination,Old | Value,Old)!=Old);
+ return Old;
+ }
+
+ __CRT_INLINE LONGLONG InterlockedXor64 (LONGLONG volatile *Destination,LONGLONG Value) {
+ LONGLONG Old;
+ do {
+ Old = *Destination;
+ } while(InterlockedCompareExchange64(Destination,Old ^ Value,Old)!=Old);
+
+ return Old;
+ }
+
+ __CRT_INLINE LONGLONG InterlockedIncrement64(LONGLONG volatile *Addend) {
+ LONGLONG Old;
+ do {
+ Old = *Addend;
+ } while(InterlockedCompareExchange64(Addend,Old + 1,Old)!=Old);
+ return Old + 1;
+ }
+
+ __CRT_INLINE LONGLONG InterlockedDecrement64(LONGLONG volatile *Addend) {
+ LONGLONG Old;
+ do {
+ Old = *Addend;
+ } while(InterlockedCompareExchange64(Addend,Old - 1,Old)!=Old);
+ return Old - 1;
+ }
+
+ __CRT_INLINE LONGLONG InterlockedExchange64(LONGLONG volatile *Target,LONGLONG Value) {
+ LONGLONG Old;
+ do {
+ Old = *Target;
+ } while(InterlockedCompareExchange64(Target,Value,Old)!=Old);
+ return Old;
+ }
+
+ __CRT_INLINE LONGLONG InterlockedExchangeAdd64(LONGLONG volatile *Addend,LONGLONG Value) {
+ LONGLONG Old;
+ do {
+ Old = *Addend;
+ } while(InterlockedCompareExchange64(Addend,Old + Value,Old)!=Old);
+ return Old;
+ }
+
+#ifdef __cplusplus
+ __CRT_INLINE PVOID __cdecl __InlineInterlockedCompareExchangePointer(PVOID volatile *Destination,PVOID ExChange,PVOID Comperand) {
+ return((PVOID)(LONG_PTR)InterlockedCompareExchange((LONG volatile *)Destination,(LONG)(LONG_PTR)ExChange,(LONG)(LONG_PTR)Comperand));
+ }
+#define InterlockedCompareExchangePointer __InlineInterlockedCompareExchangePointer
+#else
+#define InterlockedCompareExchangePointer(Destination,ExChange,Comperand)(PVOID)(LONG_PTR)InterlockedCompareExchange((LONG volatile *)(Destination),(LONG)(LONG_PTR)(ExChange),(LONG)(LONG_PTR)(Comperand))
+#endif
+
+#define InterlockedIncrementAcquire InterlockedIncrement
+#define InterlockedIncrementRelease InterlockedIncrement
+#define InterlockedDecrementAcquire InterlockedDecrement
+#define InterlockedDecrementRelease InterlockedDecrement
+#define InterlockedIncrementAcquire InterlockedIncrement
+#define InterlockedIncrementRelease InterlockedIncrement
+#define InterlockedCompareExchangeAcquire InterlockedCompareExchange
+#define InterlockedCompareExchangeRelease InterlockedCompareExchange
+#define InterlockedCompareExchangeAcquire64 InterlockedCompareExchange64
+#define InterlockedCompareExchangeRelease64 InterlockedCompareExchange64
+#define InterlockedCompareExchangePointerAcquire InterlockedCompareExchangePointer
+#define InterlockedCompareExchangePointerRelease InterlockedCompareExchangePointer
+#endif
+
+#if defined(_SLIST_HEADER_) && !defined(_NTOSP_)
+ WINBASEAPI VOID WINAPI InitializeSListHead(PSLIST_HEADER ListHead);
+ WINBASEAPI PSLIST_ENTRY WINAPI InterlockedPopEntrySList(PSLIST_HEADER ListHead);
+ WINBASEAPI PSLIST_ENTRY WINAPI InterlockedPushEntrySList(PSLIST_HEADER ListHead,PSLIST_ENTRY ListEntry);
+ WINBASEAPI PSLIST_ENTRY WINAPI InterlockedFlushSList(PSLIST_HEADER ListHead);
+ WINBASEAPI USHORT WINAPI QueryDepthSList(PSLIST_HEADER ListHead);
+#endif
+#endif
+#endif
+
+ WINBASEAPI WINBOOL WINAPI FreeResource(HGLOBAL hResData);
+ WINBASEAPI LPVOID WINAPI LockResource(HGLOBAL hResData);
+
+#define UnlockResource(hResData) ((hResData),0)
+#define MAXINTATOM 0xC000
+#define MAKEINTATOM(i) (LPTSTR)((ULONG_PTR)((WORD)(i)))
+#define INVALID_ATOM ((ATOM)0)
+
+ int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd);
+ WINBASEAPI WINBOOL WINAPI FreeLibrary(HMODULE hLibModule);
+ WINBASEAPI DECLSPEC_NORETURN VOID WINAPI FreeLibraryAndExitThread(HMODULE hLibModule,DWORD dwExitCode);
+ WINBASEAPI WINBOOL WINAPI DisableThreadLibraryCalls(HMODULE hLibModule);
+ WINBASEAPI FARPROC WINAPI GetProcAddress(HMODULE hModule,LPCSTR lpProcName);
+ WINBASEAPI DWORD WINAPI GetVersion(VOID);
+ WINBASEAPI HGLOBAL WINAPI GlobalAlloc(UINT uFlags,SIZE_T dwBytes);
+ WINBASEAPI HGLOBAL WINAPI GlobalReAlloc(HGLOBAL hMem,SIZE_T dwBytes,UINT uFlags);
+ WINBASEAPI SIZE_T WINAPI GlobalSize(HGLOBAL hMem);
+ WINBASEAPI UINT WINAPI GlobalFlags(HGLOBAL hMem);
+ WINBASEAPI LPVOID WINAPI GlobalLock(HGLOBAL hMem);
+ WINBASEAPI HGLOBAL WINAPI GlobalHandle(LPCVOID pMem);
+ WINBASEAPI WINBOOL WINAPI GlobalUnlock(HGLOBAL hMem);
+ WINBASEAPI HGLOBAL WINAPI GlobalFree(HGLOBAL hMem);
+ WINBASEAPI SIZE_T WINAPI GlobalCompact(DWORD dwMinFree);
+ WINBASEAPI VOID WINAPI GlobalFix(HGLOBAL hMem);
+ WINBASEAPI VOID WINAPI GlobalUnfix(HGLOBAL hMem);
+ WINBASEAPI LPVOID WINAPI GlobalWire(HGLOBAL hMem);
+ WINBASEAPI WINBOOL WINAPI GlobalUnWire(HGLOBAL hMem);
+ WINBASEAPI VOID WINAPI GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer);
+
+ typedef struct _MEMORYSTATUSEX {
+ DWORD dwLength;
+ DWORD dwMemoryLoad;
+ DWORDLONG ullTotalPhys;
+ DWORDLONG ullAvailPhys;
+ DWORDLONG ullTotalPageFile;
+ DWORDLONG ullAvailPageFile;
+ DWORDLONG ullTotalVirtual;
+ DWORDLONG ullAvailVirtual;
+ DWORDLONG ullAvailExtendedVirtual;
+ } MEMORYSTATUSEX,*LPMEMORYSTATUSEX;
+
+ WINBASEAPI WINBOOL WINAPI GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer);
+ WINBASEAPI HLOCAL WINAPI LocalAlloc(UINT uFlags,SIZE_T uBytes);
+ WINBASEAPI HLOCAL WINAPI LocalReAlloc(HLOCAL hMem,SIZE_T uBytes,UINT uFlags);
+ WINBASEAPI LPVOID WINAPI LocalLock(HLOCAL hMem);
+ WINBASEAPI HLOCAL WINAPI LocalHandle(LPCVOID pMem);
+ WINBASEAPI WINBOOL WINAPI LocalUnlock(HLOCAL hMem);
+ WINBASEAPI SIZE_T WINAPI LocalSize(HLOCAL hMem);
+ WINBASEAPI UINT WINAPI LocalFlags(HLOCAL hMem);
+ WINBASEAPI HLOCAL WINAPI LocalFree(HLOCAL hMem);
+ WINBASEAPI SIZE_T WINAPI LocalShrink(HLOCAL hMem,UINT cbNewSize);
+ WINBASEAPI SIZE_T WINAPI LocalCompact(UINT uMinFree);
+ WINBASEAPI WINBOOL WINAPI FlushInstructionCache(HANDLE hProcess,LPCVOID lpBaseAddress,SIZE_T dwSize);
+ WINBASEAPI LPVOID WINAPI VirtualAlloc(LPVOID lpAddress,SIZE_T dwSize,DWORD flAllocationType,DWORD flProtect);
+ WINBASEAPI WINBOOL WINAPI VirtualFree(LPVOID lpAddress,SIZE_T dwSize,DWORD dwFreeType);
+ WINBASEAPI WINBOOL WINAPI VirtualProtect(LPVOID lpAddress,SIZE_T dwSize,DWORD flNewProtect,PDWORD lpflOldProtect);
+ WINBASEAPI SIZE_T WINAPI VirtualQuery(LPCVOID lpAddress,PMEMORY_BASIC_INFORMATION lpBuffer,SIZE_T dwLength);
+ WINBASEAPI LPVOID WINAPI VirtualAllocEx(HANDLE hProcess,LPVOID lpAddress,SIZE_T dwSize,DWORD flAllocationType,DWORD flProtect);
+ WINBASEAPI UINT WINAPI GetWriteWatch(DWORD dwFlags,PVOID lpBaseAddress,SIZE_T dwRegionSize,PVOID *lpAddresses,ULONG_PTR *lpdwCount,PULONG lpdwGranularity);
+ WINBASEAPI UINT WINAPI ResetWriteWatch(LPVOID lpBaseAddress,SIZE_T dwRegionSize);
+ WINBASEAPI SIZE_T WINAPI GetLargePageMinimum(VOID);
+ WINBASEAPI UINT WINAPI EnumSystemFirmwareTables(DWORD FirmwareTableProviderSignature,PVOID pFirmwareTableEnumBuffer,DWORD BufferSize);
+ WINBASEAPI UINT WINAPI GetSystemFirmwareTable(DWORD FirmwareTableProviderSignature,DWORD FirmwareTableID,PVOID pFirmwareTableBuffer,DWORD BufferSize);
+ WINBASEAPI WINBOOL WINAPI VirtualFreeEx(HANDLE hProcess,LPVOID lpAddress,SIZE_T dwSize,DWORD dwFreeType);
+ WINBASEAPI WINBOOL WINAPI VirtualProtectEx(HANDLE hProcess,LPVOID lpAddress,SIZE_T dwSize,DWORD flNewProtect,PDWORD lpflOldProtect);
+ WINBASEAPI SIZE_T WINAPI VirtualQueryEx(HANDLE hProcess,LPCVOID lpAddress,PMEMORY_BASIC_INFORMATION lpBuffer,SIZE_T dwLength);
+ WINBASEAPI HANDLE WINAPI HeapCreate(DWORD flOptions,SIZE_T dwInitialSize,SIZE_T dwMaximumSize);
+ WINBASEAPI WINBOOL WINAPI HeapDestroy(HANDLE hHeap);
+ WINBASEAPI LPVOID WINAPI HeapAlloc(HANDLE hHeap,DWORD dwFlags,SIZE_T dwBytes);
+ WINBASEAPI LPVOID WINAPI HeapReAlloc(HANDLE hHeap,DWORD dwFlags,LPVOID lpMem,SIZE_T dwBytes);
+ WINBASEAPI WINBOOL WINAPI HeapFree(HANDLE hHeap,DWORD dwFlags,LPVOID lpMem);
+ WINBASEAPI SIZE_T WINAPI HeapSize(HANDLE hHeap,DWORD dwFlags,LPCVOID lpMem);
+ WINBASEAPI WINBOOL WINAPI HeapValidate(HANDLE hHeap,DWORD dwFlags,LPCVOID lpMem);
+ WINBASEAPI SIZE_T WINAPI HeapCompact(HANDLE hHeap,DWORD dwFlags);
+ WINBASEAPI HANDLE WINAPI GetProcessHeap(VOID);
+ WINBASEAPI DWORD WINAPI GetProcessHeaps(DWORD NumberOfHeaps,PHANDLE ProcessHeaps);
+
+ typedef struct _PROCESS_HEAP_ENTRY {
+ PVOID lpData;
+ DWORD cbData;
+ BYTE cbOverhead;
+ BYTE iRegionIndex;
+ WORD wFlags;
+ union {
+ struct {
+ HANDLE hMem;
+ DWORD dwReserved[3];
+ } Block;
+ struct {
+ DWORD dwCommittedSize;
+ DWORD dwUnCommittedSize;
+ LPVOID lpFirstBlock;
+ LPVOID lpLastBlock;
+ } Region;
+ };
+ } PROCESS_HEAP_ENTRY,*LPPROCESS_HEAP_ENTRY,*PPROCESS_HEAP_ENTRY;
+
+#define PROCESS_HEAP_REGION 0x1
+#define PROCESS_HEAP_UNCOMMITTED_RANGE 0x2
+#define PROCESS_HEAP_ENTRY_BUSY 0x4
+#define PROCESS_HEAP_ENTRY_MOVEABLE 0x10
+#define PROCESS_HEAP_ENTRY_DDESHARE 0x20
+
+ WINBASEAPI WINBOOL WINAPI HeapLock(HANDLE hHeap);
+ WINBASEAPI WINBOOL WINAPI HeapUnlock(HANDLE hHeap);
+ WINBASEAPI WINBOOL WINAPI HeapWalk(HANDLE hHeap,LPPROCESS_HEAP_ENTRY lpEntry);
+ WINBASEAPI WINBOOL WINAPI HeapSetInformation(HANDLE HeapHandle,HEAP_INFORMATION_CLASS HeapInformationClass,PVOID HeapInformation,SIZE_T HeapInformationLength);
+ WINBASEAPI WINBOOL WINAPI HeapQueryInformation(HANDLE HeapHandle,HEAP_INFORMATION_CLASS HeapInformationClass,PVOID HeapInformation,SIZE_T HeapInformationLength,PSIZE_T ReturnLength);
+
+#define SCS_32BIT_BINARY 0
+#define SCS_DOS_BINARY 1
+#define SCS_WOW_BINARY 2
+#define SCS_PIF_BINARY 3
+#define SCS_POSIX_BINARY 4
+#define SCS_OS216_BINARY 5
+#define SCS_64BIT_BINARY 6
+
+#ifdef UNICODE
+#define GetBinaryType GetBinaryTypeW
+#define GetShortPathName GetShortPathNameW
+#define GetLongPathName GetLongPathNameW
+#define GetEnvironmentStrings GetEnvironmentStringsW
+#define SetEnvironmentStrings SetEnvironmentStringsW
+#define FreeEnvironmentStrings FreeEnvironmentStringsW
+#else
+#define GetBinaryType GetBinaryTypeA
+#define GetShortPathName GetShortPathNameA
+#define GetLongPathName GetLongPathNameA
+#define GetEnvironmentStringsA GetEnvironmentStrings
+#define SetEnvironmentStrings SetEnvironmentStringsA
+#define FreeEnvironmentStrings FreeEnvironmentStringsA
+#endif
+
+#ifdef _WIN64
+#define SCS_THIS_PLATFORM_BINARY SCS_64BIT_BINARY
+#else
+#define SCS_THIS_PLATFORM_BINARY SCS_32BIT_BINARY
+#endif
+
+ WINBASEAPI WINBOOL WINAPI GetBinaryTypeA(LPCSTR lpApplicationName,LPDWORD lpBinaryType);
+ WINBASEAPI WINBOOL WINAPI GetBinaryTypeW(LPCWSTR lpApplicationName,LPDWORD lpBinaryType);
+ WINBASEAPI DWORD WINAPI GetShortPathNameA(LPCSTR lpszLongPath,LPSTR lpszShortPath,DWORD cchBuffer);
+ WINBASEAPI DWORD WINAPI GetShortPathNameW(LPCWSTR lpszLongPath,LPWSTR lpszShortPath,DWORD cchBuffer);
+ WINBASEAPI DWORD WINAPI GetLongPathNameA(LPCSTR lpszShortPath,LPSTR lpszLongPath,DWORD cchBuffer);
+ WINBASEAPI DWORD WINAPI GetLongPathNameW(LPCWSTR lpszShortPath,LPWSTR lpszLongPath,DWORD cchBuffer);
+ WINBASEAPI WINBOOL WINAPI GetProcessAffinityMask(HANDLE hProcess,PDWORD_PTR lpProcessAffinityMask,PDWORD_PTR lpSystemAffinityMask);
+ WINBASEAPI WINBOOL WINAPI SetProcessAffinityMask(HANDLE hProcess,DWORD_PTR dwProcessAffinityMask);
+ WINBASEAPI WINBOOL WINAPI GetProcessHandleCount(HANDLE hProcess,PDWORD pdwHandleCount);
+ WINBASEAPI WINBOOL WINAPI GetProcessTimes(HANDLE hProcess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,LPFILETIME lpKernelTime,LPFILETIME lpUserTime);
+ WINBASEAPI WINBOOL WINAPI GetProcessIoCounters(HANDLE hProcess,PIO_COUNTERS lpIoCounters);
+ WINBASEAPI WINBOOL WINAPI GetProcessWorkingSetSize(HANDLE hProcess,PSIZE_T lpMinimumWorkingSetSize,PSIZE_T lpMaximumWorkingSetSize);
+ WINBASEAPI WINBOOL WINAPI GetProcessWorkingSetSizeEx(HANDLE hProcess,PSIZE_T lpMinimumWorkingSetSize,PSIZE_T lpMaximumWorkingSetSize,PDWORD Flags);
+ WINBASEAPI WINBOOL WINAPI SetProcessWorkingSetSize(HANDLE hProcess,SIZE_T dwMinimumWorkingSetSize,SIZE_T dwMaximumWorkingSetSize);
+ WINBASEAPI WINBOOL WINAPI SetProcessWorkingSetSizeEx(HANDLE hProcess,SIZE_T dwMinimumWorkingSetSize,SIZE_T dwMaximumWorkingSetSize,DWORD Flags);
+ WINBASEAPI HANDLE WINAPI OpenProcess(DWORD dwDesiredAccess,WINBOOL bInheritHandle,DWORD dwProcessId);
+ WINBASEAPI HANDLE WINAPI GetCurrentProcess(VOID);
+ WINBASEAPI DWORD WINAPI GetCurrentProcessId(VOID);
+ WINBASEAPI DECLSPEC_NORETURN VOID WINAPI ExitProcess(UINT uExitCode);
+ WINBASEAPI WINBOOL WINAPI TerminateProcess(HANDLE hProcess,UINT uExitCode);
+ WINBASEAPI WINBOOL WINAPI GetExitCodeProcess(HANDLE hProcess,LPDWORD lpExitCode);
+ WINBASEAPI VOID WINAPI FatalExit(int ExitCode);
+ /* WINBASEAPI LPCH WINAPI GetEnvironmentStrings(VOID); */
+ WINBASEAPI LPWCH WINAPI GetEnvironmentStringsW(VOID);
+ WINBASEAPI WINBOOL WINAPI SetEnvironmentStringsA(LPCH NewEnvironment);
+ WINBASEAPI WINBOOL WINAPI SetEnvironmentStringsW(LPWCH NewEnvironment);
+ WINBASEAPI WINBOOL WINAPI FreeEnvironmentStringsA(LPCH);
+ WINBASEAPI WINBOOL WINAPI FreeEnvironmentStringsW(LPWCH);
+ WINBASEAPI VOID WINAPI RaiseException(DWORD dwExceptionCode,DWORD dwExceptionFlags,DWORD nNumberOfArguments,CONST ULONG_PTR *lpArguments);
+ WINBASEAPI LONG WINAPI UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo);
+
+ typedef LONG (WINAPI *PTOP_LEVEL_EXCEPTION_FILTER)(struct _EXCEPTION_POINTERS *ExceptionInfo);
+ typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;
+
+ WINBASEAPI LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter);
+
+#define FIBER_FLAG_FLOAT_SWITCH 0x1
+
+ WINBASEAPI LPVOID WINAPI CreateFiber(SIZE_T dwStackSize,LPFIBER_START_ROUTINE lpStartAddress,LPVOID lpParameter);
+ WINBASEAPI LPVOID WINAPI CreateFiberEx(SIZE_T dwStackCommitSize,SIZE_T dwStackReserveSize,DWORD dwFlags,LPFIBER_START_ROUTINE lpStartAddress,LPVOID lpParameter);
+ WINBASEAPI VOID WINAPI DeleteFiber(LPVOID lpFiber);
+ WINBASEAPI LPVOID WINAPI ConvertThreadToFiber(LPVOID lpParameter);
+ WINBASEAPI LPVOID WINAPI ConvertThreadToFiberEx(LPVOID lpParameter,DWORD dwFlags);
+ WINBASEAPI WINBOOL WINAPI ConvertFiberToThread(VOID);
+ WINBASEAPI VOID WINAPI SwitchToFiber(LPVOID lpFiber);
+ WINBASEAPI WINBOOL WINAPI SwitchToThread(VOID);
+ WINBASEAPI HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);
+ WINBASEAPI HANDLE WINAPI CreateRemoteThread(HANDLE hProcess,LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);
+ WINBASEAPI HANDLE WINAPI GetCurrentThread(VOID);
+ WINBASEAPI DWORD WINAPI GetCurrentThreadId(VOID);
+ WINBASEAPI WINBOOL WINAPI SetThreadStackGuarantee (PULONG StackSizeInBytes);
+ WINBASEAPI DWORD WINAPI GetProcessIdOfThread(HANDLE Thread);
+ WINBASEAPI DWORD WINAPI GetThreadId(HANDLE Thread);
+ WINBASEAPI DWORD WINAPI GetProcessId(HANDLE Process);
+ WINBASEAPI DWORD WINAPI GetCurrentProcessorNumber(VOID);
+ WINBASEAPI DWORD_PTR WINAPI SetThreadAffinityMask(HANDLE hThread,DWORD_PTR dwThreadAffinityMask);
+ WINBASEAPI DWORD WINAPI SetThreadIdealProcessor(HANDLE hThread,DWORD dwIdealProcessor);
+ WINBASEAPI WINBOOL WINAPI SetProcessPriorityBoost(HANDLE hProcess,WINBOOL bDisablePriorityBoost);
+ WINBASEAPI WINBOOL WINAPI GetProcessPriorityBoost(HANDLE hProcess,PBOOL pDisablePriorityBoost);
+ WINBASEAPI WINBOOL WINAPI RequestWakeupLatency(LATENCY_TIME latency);
+ WINBASEAPI WINBOOL WINAPI IsSystemResumeAutomatic(VOID);
+ WINBASEAPI HANDLE WINAPI OpenThread(DWORD dwDesiredAccess,WINBOOL bInheritHandle,DWORD dwThreadId);
+ WINBASEAPI WINBOOL WINAPI SetThreadPriority(HANDLE hThread,int nPriority);
+ WINBASEAPI WINBOOL WINAPI SetThreadPriorityBoost(HANDLE hThread,WINBOOL bDisablePriorityBoost);
+ WINBASEAPI WINBOOL WINAPI GetThreadPriorityBoost(HANDLE hThread,PBOOL pDisablePriorityBoost);
+ WINBASEAPI int WINAPI GetThreadPriority(HANDLE hThread);
+ WINBASEAPI WINBOOL WINAPI GetThreadTimes(HANDLE hThread,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,LPFILETIME lpKernelTime,LPFILETIME lpUserTime);
+ WINBASEAPI WINBOOL WINAPI GetThreadIOPendingFlag(HANDLE hThread,PBOOL lpIOIsPending);
+ WINBASEAPI DECLSPEC_NORETURN VOID WINAPI ExitThread(DWORD dwExitCode);
+ WINBASEAPI WINBOOL WINAPI TerminateThread(HANDLE hThread,DWORD dwExitCode);
+ WINBASEAPI WINBOOL WINAPI GetExitCodeThread(HANDLE hThread,LPDWORD lpExitCode);
+ WINBASEAPI WINBOOL WINAPI GetThreadSelectorEntry(HANDLE hThread,DWORD dwSelector,LPLDT_ENTRY lpSelectorEntry);
+ WINBASEAPI EXECUTION_STATE WINAPI SetThreadExecutionState(EXECUTION_STATE esFlags);
+ WINBASEAPI DWORD WINAPI GetLastError(VOID);
+ WINBASEAPI VOID WINAPI SetLastError(DWORD dwErrCode);
+
+#ifndef RC_INVOKED
+#ifdef WINBASE_DECLARE_RESTORE_LAST_ERROR
+ WINBASEAPI VOID WINAPI RestoreLastError(DWORD dwErrCode);
+
+ typedef VOID (WINAPI *PRESTORE_LAST_ERROR)(DWORD);
+
+#define RESTORE_LAST_ERROR_NAME_A "RestoreLastError"
+#define RESTORE_LAST_ERROR_NAME_W L"RestoreLastError"
+#define RESTORE_LAST_ERROR_NAME TEXT("RestoreLastError")
+#endif
+#endif
+
+#define HasOverlappedIoCompleted(lpOverlapped) (((DWORD)(lpOverlapped)->Internal)!=STATUS_PENDING)
+
+ WINBASEAPI WINBOOL WINAPI GetOverlappedResult(HANDLE hFile,LPOVERLAPPED lpOverlapped,LPDWORD lpNumberOfBytesTransferred,WINBOOL bWait);
+ WINBASEAPI HANDLE WINAPI CreateIoCompletionPort(HANDLE FileHandle,HANDLE ExistingCompletionPort,ULONG_PTR CompletionKey,DWORD NumberOfConcurrentThreads);
+ WINBASEAPI WINBOOL WINAPI GetQueuedCompletionStatus(HANDLE CompletionPort,LPDWORD lpNumberOfBytesTransferred,PULONG_PTR lpCompletionKey,LPOVERLAPPED *lpOverlapped,DWORD dwMilliseconds);
+ WINBASEAPI WINBOOL WINAPI PostQueuedCompletionStatus(HANDLE CompletionPort,DWORD dwNumberOfBytesTransferred,ULONG_PTR dwCompletionKey,LPOVERLAPPED lpOverlapped);
+
+#define SEM_FAILCRITICALERRORS 0x1
+#define SEM_NOGPFAULTERRORBOX 0x2
+#define SEM_NOALIGNMENTFAULTEXCEPT 0x4
+#define SEM_NOOPENFILEERRORBOX 0x8000
+
+ WINBASEAPI UINT WINAPI SetErrorMode(UINT uMode);
+ WINBASEAPI WINBOOL WINAPI ReadProcessMemory(HANDLE hProcess,LPCVOID lpBaseAddress,LPVOID lpBuffer,SIZE_T nSize,SIZE_T *lpNumberOfBytesRead);
+ WINBASEAPI WINBOOL WINAPI WriteProcessMemory(HANDLE hProcess,LPVOID lpBaseAddress,LPCVOID lpBuffer,SIZE_T nSize,SIZE_T *lpNumberOfBytesWritten);
+ WINBASEAPI WINBOOL WINAPI GetThreadContext(HANDLE hThread,LPCONTEXT lpContext);
+ WINBASEAPI WINBOOL WINAPI SetThreadContext(HANDLE hThread,CONST CONTEXT *lpContext);
+ WINBASEAPI DWORD WINAPI SuspendThread(HANDLE hThread);
+ WINBASEAPI DWORD WINAPI ResumeThread(HANDLE hThread);
+
+ typedef VOID (WINAPI *PAPCFUNC)(ULONG_PTR dwParam);
+
+ WINBASEAPI DWORD WINAPI QueueUserAPC(PAPCFUNC pfnAPC,HANDLE hThread,ULONG_PTR dwData);
+ WINBASEAPI WINBOOL WINAPI IsDebuggerPresent(VOID);
+ WINBASEAPI WINBOOL WINAPI CheckRemoteDebuggerPresent(HANDLE hProcess,PBOOL pbDebuggerPresent);
+ WINBASEAPI VOID WINAPI DebugBreak(VOID);
+ WINBASEAPI WINBOOL WINAPI WaitForDebugEvent(LPDEBUG_EVENT lpDebugEvent,DWORD dwMilliseconds);
+ WINBASEAPI WINBOOL WINAPI ContinueDebugEvent(DWORD dwProcessId,DWORD dwThreadId,DWORD dwContinueStatus);
+ WINBASEAPI WINBOOL WINAPI DebugActiveProcess(DWORD dwProcessId);
+ WINBASEAPI WINBOOL WINAPI DebugActiveProcessStop(DWORD dwProcessId);
+ WINBASEAPI WINBOOL WINAPI DebugSetProcessKillOnExit(WINBOOL KillOnExit);
+ WINBASEAPI WINBOOL WINAPI DebugBreakProcess(HANDLE Process);
+ WINBASEAPI VOID WINAPI InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
+ WINBASEAPI VOID WINAPI EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
+ WINBASEAPI VOID WINAPI LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
+ WINBASEAPI WINBOOL WINAPI InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection,DWORD dwSpinCount);
+ WINBASEAPI DWORD WINAPI SetCriticalSectionSpinCount(LPCRITICAL_SECTION lpCriticalSection,DWORD dwSpinCount);
+ WINBASEAPI WINBOOL WINAPI TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
+ WINBASEAPI VOID WINAPI DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
+ WINBASEAPI WINBOOL WINAPI SetEvent(HANDLE hEvent);
+ WINBASEAPI WINBOOL WINAPI ResetEvent(HANDLE hEvent);
+ WINBASEAPI WINBOOL WINAPI PulseEvent(HANDLE hEvent);
+ WINBASEAPI WINBOOL WINAPI ReleaseSemaphore(HANDLE hSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount);
+ WINBASEAPI WINBOOL WINAPI ReleaseMutex(HANDLE hMutex);
+ WINBASEAPI DWORD WINAPI WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);
+ WINBASEAPI DWORD WINAPI WaitForMultipleObjects(DWORD nCount,CONST HANDLE *lpHandles,WINBOOL bWaitAll,DWORD dwMilliseconds);
+ WINBASEAPI VOID WINAPI Sleep(DWORD dwMilliseconds);
+ WINBASEAPI HGLOBAL WINAPI LoadResource(HMODULE hModule,HRSRC hResInfo);
+ WINBASEAPI DWORD WINAPI SizeofResource(HMODULE hModule,HRSRC hResInfo);
+ WINBASEAPI ATOM WINAPI GlobalDeleteAtom(ATOM nAtom);
+ WINBASEAPI WINBOOL WINAPI InitAtomTable(DWORD nSize);
+ WINBASEAPI ATOM WINAPI DeleteAtom(ATOM nAtom);
+ WINBASEAPI UINT WINAPI SetHandleCount(UINT uNumber);
+ WINBASEAPI DWORD WINAPI GetLogicalDrives(VOID);
+ WINBASEAPI WINBOOL WINAPI LockFile(HANDLE hFile,DWORD dwFileOffsetLow,DWORD dwFileOffsetHigh,DWORD nNumberOfBytesToLockLow,DWORD nNumberOfBytesToLockHigh);
+ WINBASEAPI WINBOOL WINAPI UnlockFile(HANDLE hFile,DWORD dwFileOffsetLow,DWORD dwFileOffsetHigh,DWORD nNumberOfBytesToUnlockLow,DWORD nNumberOfBytesToUnlockHigh);
+ WINBASEAPI WINBOOL WINAPI LockFileEx(HANDLE hFile,DWORD dwFlags,DWORD dwReserved,DWORD nNumberOfBytesToLockLow,DWORD nNumberOfBytesToLockHigh,LPOVERLAPPED lpOverlapped);
+
+#define LOCKFILE_FAIL_IMMEDIATELY 0x1
+#define LOCKFILE_EXCLUSIVE_LOCK 0x2
+
+ WINBASEAPI WINBOOL WINAPI UnlockFileEx(HANDLE hFile,DWORD dwReserved,DWORD nNumberOfBytesToUnlockLow,DWORD nNumberOfBytesToUnlockHigh,LPOVERLAPPED lpOverlapped);
+
+ typedef struct _BY_HANDLE_FILE_INFORMATION {
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD dwVolumeSerialNumber;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+ DWORD nNumberOfLinks;
+ DWORD nFileIndexHigh;
+ DWORD nFileIndexLow;
+ } BY_HANDLE_FILE_INFORMATION,*PBY_HANDLE_FILE_INFORMATION,*LPBY_HANDLE_FILE_INFORMATION;
+
+#ifdef UNICODE
+#define SetFileShortName SetFileShortNameW
+#else
+#define SetFileShortName SetFileShortNameA
+#endif
+
+ WINBASEAPI WINBOOL WINAPI GetFileInformationByHandle(HANDLE hFile,LPBY_HANDLE_FILE_INFORMATION lpFileInformation);
+ WINBASEAPI DWORD WINAPI GetFileType(HANDLE hFile);
+ WINBASEAPI DWORD WINAPI GetFileSize(HANDLE hFile,LPDWORD lpFileSizeHigh);
+ WINBASEAPI WINBOOL WINAPI GetFileSizeEx(HANDLE hFile,PLARGE_INTEGER lpFileSize);
+ WINBASEAPI HANDLE WINAPI GetStdHandle(DWORD nStdHandle);
+ WINBASEAPI WINBOOL WINAPI SetStdHandle(DWORD nStdHandle,HANDLE hHandle);
+ WINBASEAPI WINBOOL WINAPI WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped);
+ WINBASEAPI WINBOOL WINAPI ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped);
+ WINBASEAPI WINBOOL WINAPI FlushFileBuffers(HANDLE hFile);
+ WINBASEAPI WINBOOL WINAPI DeviceIoControl(HANDLE hDevice,DWORD dwIoControlCode,LPVOID lpInBuffer,DWORD nInBufferSize,LPVOID lpOutBuffer,DWORD nOutBufferSize,LPDWORD lpBytesReturned,LPOVERLAPPED lpOverlapped);
+ WINBASEAPI WINBOOL WINAPI RequestDeviceWakeup(HANDLE hDevice);
+ WINBASEAPI WINBOOL WINAPI CancelDeviceWakeupRequest(HANDLE hDevice);
+ WINBASEAPI WINBOOL WINAPI GetDevicePowerState(HANDLE hDevice,WINBOOL *pfOn);
+ WINBASEAPI WINBOOL WINAPI SetMessageWaitingIndicator(HANDLE hMsgIndicator,ULONG ulMsgCount);
+ WINBASEAPI WINBOOL WINAPI SetEndOfFile(HANDLE hFile);
+ WINBASEAPI DWORD WINAPI SetFilePointer(HANDLE hFile,LONG lDistanceToMove,PLONG lpDistanceToMoveHigh,DWORD dwMoveMethod);
+ WINBASEAPI WINBOOL WINAPI SetFilePointerEx(HANDLE hFile,LARGE_INTEGER liDistanceToMove,PLARGE_INTEGER lpNewFilePointer,DWORD dwMoveMethod);
+ WINBASEAPI WINBOOL WINAPI FindClose(HANDLE hFindFile);
+ WINBASEAPI WINBOOL WINAPI GetFileTime(HANDLE hFile,LPFILETIME lpCreationTime,LPFILETIME lpLastAccessTime,LPFILETIME lpLastWriteTime);
+ WINBASEAPI WINBOOL WINAPI SetFileTime(HANDLE hFile,CONST FILETIME *lpCreationTime,CONST FILETIME *lpLastAccessTime,CONST FILETIME *lpLastWriteTime);
+ WINBASEAPI WINBOOL WINAPI SetFileValidData(HANDLE hFile,LONGLONG ValidDataLength);
+ WINBASEAPI WINBOOL WINAPI SetFileShortNameA(HANDLE hFile,LPCSTR lpShortName);
+ WINBASEAPI WINBOOL WINAPI SetFileShortNameW(HANDLE hFile,LPCWSTR lpShortName);
+ WINBASEAPI WINBOOL WINAPI CloseHandle(HANDLE hObject);
+ WINBASEAPI WINBOOL WINAPI DuplicateHandle(HANDLE hSourceProcessHandle,HANDLE hSourceHandle,HANDLE hTargetProcessHandle,LPHANDLE lpTargetHandle,DWORD dwDesiredAccess,WINBOOL bInheritHandle,DWORD dwOptions);
+ WINBASEAPI WINBOOL WINAPI GetHandleInformation(HANDLE hObject,LPDWORD lpdwFlags);
+ WINBASEAPI WINBOOL WINAPI SetHandleInformation(HANDLE hObject,DWORD dwMask,DWORD dwFlags);
+
+#define HANDLE_FLAG_INHERIT 0x1
+#define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x2
+
+#define HINSTANCE_ERROR 32
+
+ WINBASEAPI DWORD WINAPI LoadModule(LPCSTR lpModuleName,LPVOID lpParameterBlock);
+ WINBASEAPI UINT WINAPI WinExec(LPCSTR lpCmdLine,UINT uCmdShow);
+ WINBASEAPI WINBOOL WINAPI ClearCommBreak(HANDLE hFile);
+ WINBASEAPI WINBOOL WINAPI ClearCommError(HANDLE hFile,LPDWORD lpErrors,LPCOMSTAT lpStat);
+ WINBASEAPI WINBOOL WINAPI SetupComm(HANDLE hFile,DWORD dwInQueue,DWORD dwOutQueue);
+ WINBASEAPI WINBOOL WINAPI EscapeCommFunction(HANDLE hFile,DWORD dwFunc);
+ WINBASEAPI WINBOOL WINAPI GetCommConfig(HANDLE hCommDev,LPCOMMCONFIG lpCC,LPDWORD lpdwSize);
+ WINBASEAPI WINBOOL WINAPI GetCommMask(HANDLE hFile,LPDWORD lpEvtMask);
+ WINBASEAPI WINBOOL WINAPI GetCommProperties(HANDLE hFile,LPCOMMPROP lpCommProp);
+ WINBASEAPI WINBOOL WINAPI GetCommModemStatus(HANDLE hFile,LPDWORD lpModemStat);
+ WINBASEAPI WINBOOL WINAPI GetCommState(HANDLE hFile,LPDCB lpDCB);
+ WINBASEAPI WINBOOL WINAPI GetCommTimeouts(HANDLE hFile,LPCOMMTIMEOUTS lpCommTimeouts);
+ WINBASEAPI WINBOOL WINAPI PurgeComm(HANDLE hFile,DWORD dwFlags);
+ WINBASEAPI WINBOOL WINAPI SetCommBreak(HANDLE hFile);
+ WINBASEAPI WINBOOL WINAPI SetCommConfig(HANDLE hCommDev,LPCOMMCONFIG lpCC,DWORD dwSize);
+ WINBASEAPI WINBOOL WINAPI SetCommMask(HANDLE hFile,DWORD dwEvtMask);
+ WINBASEAPI WINBOOL WINAPI SetCommState(HANDLE hFile,LPDCB lpDCB);
+ WINBASEAPI WINBOOL WINAPI SetCommTimeouts(HANDLE hFile,LPCOMMTIMEOUTS lpCommTimeouts);
+ WINBASEAPI WINBOOL WINAPI TransmitCommChar(HANDLE hFile,char cChar);
+ WINBASEAPI WINBOOL WINAPI WaitCommEvent(HANDLE hFile,LPDWORD lpEvtMask,LPOVERLAPPED lpOverlapped);
+ WINBASEAPI DWORD WINAPI SetTapePosition(HANDLE hDevice,DWORD dwPositionMethod,DWORD dwPartition,DWORD dwOffsetLow,DWORD dwOffsetHigh,WINBOOL bImmediate);
+ WINBASEAPI DWORD WINAPI GetTapePosition(HANDLE hDevice,DWORD dwPositionType,LPDWORD lpdwPartition,LPDWORD lpdwOffsetLow,LPDWORD lpdwOffsetHigh);
+ WINBASEAPI DWORD WINAPI PrepareTape(HANDLE hDevice,DWORD dwOperation,WINBOOL bImmediate);
+ WINBASEAPI DWORD WINAPI EraseTape(HANDLE hDevice,DWORD dwEraseType,WINBOOL bImmediate);
+ WINBASEAPI DWORD WINAPI CreateTapePartition(HANDLE hDevice,DWORD dwPartitionMethod,DWORD dwCount,DWORD dwSize);
+ WINBASEAPI DWORD WINAPI WriteTapemark(HANDLE hDevice,DWORD dwTapemarkType,DWORD dwTapemarkCount,WINBOOL bImmediate);
+ WINBASEAPI DWORD WINAPI GetTapeStatus(HANDLE hDevice);
+ WINBASEAPI DWORD WINAPI GetTapeParameters(HANDLE hDevice,DWORD dwOperation,LPDWORD lpdwSize,LPVOID lpTapeInformation);
+
+#define GET_TAPE_MEDIA_INFORMATION 0
+#define GET_TAPE_DRIVE_INFORMATION 1
+
+ WINBASEAPI DWORD WINAPI SetTapeParameters(HANDLE hDevice,DWORD dwOperation,LPVOID lpTapeInformation);
+
+#define SET_TAPE_MEDIA_INFORMATION 0
+#define SET_TAPE_DRIVE_INFORMATION 1
+
+ WINBASEAPI WINBOOL WINAPI Beep(DWORD dwFreq,DWORD dwDuration);
+ WINBASEAPI int WINAPI MulDiv(int nNumber,int nNumerator,int nDenominator);
+ WINBASEAPI VOID WINAPI GetSystemTime(LPSYSTEMTIME lpSystemTime);
+ WINBASEAPI VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime);
+ WINBASEAPI WINBOOL WINAPI SetSystemTime(CONST SYSTEMTIME *lpSystemTime);
+ WINBASEAPI VOID WINAPI GetLocalTime(LPSYSTEMTIME lpSystemTime);
+ WINBASEAPI WINBOOL WINAPI SetLocalTime(CONST SYSTEMTIME *lpSystemTime);
+ WINBASEAPI VOID WINAPI GetSystemInfo(LPSYSTEM_INFO lpSystemInfo);
+ WINBASEAPI WINBOOL WINAPI SetSystemFileCacheSize(SIZE_T MinimumFileCacheSize,SIZE_T MaximumFileCacheSize,DWORD Flags);
+ WINBASEAPI WINBOOL WINAPI GetSystemFileCacheSize(PSIZE_T lpMinimumFileCacheSize,PSIZE_T lpMaximumFileCacheSize,PDWORD lpFlags);
+ WINBASEAPI WINBOOL WINAPI GetSystemRegistryQuota(PDWORD pdwQuotaAllowed,PDWORD pdwQuotaUsed);
+ WINBOOL WINAPI GetSystemTimes(LPFILETIME lpIdleTime,LPFILETIME lpKernelTime,LPFILETIME lpUserTime);
+ WINBASEAPI VOID WINAPI GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo);
+ WINBASEAPI WINBOOL WINAPI IsProcessorFeaturePresent(DWORD ProcessorFeature);
+
+ typedef struct _TIME_ZONE_INFORMATION {
+ LONG Bias;
+ WCHAR StandardName[32];
+ SYSTEMTIME StandardDate;
+ LONG StandardBias;
+ WCHAR DaylightName[32];
+ SYSTEMTIME DaylightDate;
+ LONG DaylightBias;
+ } TIME_ZONE_INFORMATION,*PTIME_ZONE_INFORMATION,*LPTIME_ZONE_INFORMATION;
+
+#ifdef UNICODE
+#define FormatMessage FormatMessageW
+#else
+#define FormatMessage FormatMessageA
+#endif
+
+ WINBASEAPI WINBOOL WINAPI SystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION lpTimeZoneInformation,LPSYSTEMTIME lpUniversalTime,LPSYSTEMTIME lpLocalTime);
+ WINBASEAPI WINBOOL WINAPI TzSpecificLocalTimeToSystemTime(LPTIME_ZONE_INFORMATION lpTimeZoneInformation,LPSYSTEMTIME lpLocalTime,LPSYSTEMTIME lpUniversalTime);
+ WINBASEAPI DWORD WINAPI GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation);
+ WINBASEAPI WINBOOL WINAPI SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation);
+ WINBASEAPI WINBOOL WINAPI SystemTimeToFileTime(CONST SYSTEMTIME *lpSystemTime,LPFILETIME lpFileTime);
+ WINBASEAPI WINBOOL WINAPI FileTimeToLocalFileTime(CONST FILETIME *lpFileTime,LPFILETIME lpLocalFileTime);
+ WINBASEAPI WINBOOL WINAPI LocalFileTimeToFileTime(CONST FILETIME *lpLocalFileTime,LPFILETIME lpFileTime);
+ WINBASEAPI WINBOOL WINAPI FileTimeToSystemTime(CONST FILETIME *lpFileTime,LPSYSTEMTIME lpSystemTime);
+ WINBASEAPI LONG WINAPI CompareFileTime(CONST FILETIME *lpFileTime1,CONST FILETIME *lpFileTime2);
+ WINBASEAPI WINBOOL WINAPI FileTimeToDosDateTime(CONST FILETIME *lpFileTime,LPWORD lpFatDate,LPWORD lpFatTime);
+ WINBASEAPI WINBOOL WINAPI DosDateTimeToFileTime(WORD wFatDate,WORD wFatTime,LPFILETIME lpFileTime);
+ WINBASEAPI DWORD WINAPI GetTickCount(VOID);
+ WINBASEAPI WINBOOL WINAPI SetSystemTimeAdjustment(DWORD dwTimeAdjustment,WINBOOL bTimeAdjustmentDisabled);
+ WINBASEAPI WINBOOL WINAPI GetSystemTimeAdjustment(PDWORD lpTimeAdjustment,PDWORD lpTimeIncrement,PBOOL lpTimeAdjustmentDisabled);
+ WINBASEAPI DWORD WINAPI FormatMessageA(DWORD dwFlags,LPCVOID lpSource,DWORD dwMessageId,DWORD dwLanguageId,LPSTR lpBuffer,DWORD nSize,va_list *Arguments);
+ WINBASEAPI DWORD WINAPI FormatMessageW(DWORD dwFlags,LPCVOID lpSource,DWORD dwMessageId,DWORD dwLanguageId,LPWSTR lpBuffer,DWORD nSize,va_list *Arguments);
+
+#define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x100
+#define FORMAT_MESSAGE_IGNORE_INSERTS 0x200
+#define FORMAT_MESSAGE_FROM_STRING 0x400
+#define FORMAT_MESSAGE_FROM_HMODULE 0x800
+#define FORMAT_MESSAGE_FROM_SYSTEM 0x1000
+#define FORMAT_MESSAGE_ARGUMENT_ARRAY 0x2000
+#define FORMAT_MESSAGE_MAX_WIDTH_MASK 0xff
+
+#ifdef UNICODE
+#define CreateMailslot CreateMailslotW
+#define EncryptFile EncryptFileW
+#define DecryptFile DecryptFileW
+#define FileEncryptionStatus FileEncryptionStatusW
+#else
+#define CreateMailslot CreateMailslotA
+#define EncryptFile EncryptFileA
+#define DecryptFile DecryptFileA
+#define FileEncryptionStatus FileEncryptionStatusA
+#endif
+
+ WINBASEAPI WINBOOL WINAPI CreatePipe(PHANDLE hReadPipe,PHANDLE hWritePipe,LPSECURITY_ATTRIBUTES lpPipeAttributes,DWORD nSize);
+ WINBASEAPI WINBOOL WINAPI ConnectNamedPipe(HANDLE hNamedPipe,LPOVERLAPPED lpOverlapped);
+ WINBASEAPI WINBOOL WINAPI DisconnectNamedPipe(HANDLE hNamedPipe);
+ WINBASEAPI WINBOOL WINAPI SetNamedPipeHandleState(HANDLE hNamedPipe,LPDWORD lpMode,LPDWORD lpMaxCollectionCount,LPDWORD lpCollectDataTimeout);
+ WINBASEAPI WINBOOL WINAPI GetNamedPipeInfo(HANDLE hNamedPipe,LPDWORD lpFlags,LPDWORD lpOutBufferSize,LPDWORD lpInBufferSize,LPDWORD lpMaxInstances);
+ WINBASEAPI WINBOOL WINAPI PeekNamedPipe(HANDLE hNamedPipe,LPVOID lpBuffer,DWORD nBufferSize,LPDWORD lpBytesRead,LPDWORD lpTotalBytesAvail,LPDWORD lpBytesLeftThisMessage);
+ WINBASEAPI WINBOOL WINAPI TransactNamedPipe(HANDLE hNamedPipe,LPVOID lpInBuffer,DWORD nInBufferSize,LPVOID lpOutBuffer,DWORD nOutBufferSize,LPDWORD lpBytesRead,LPOVERLAPPED lpOverlapped);
+ WINBASEAPI HANDLE WINAPI CreateMailslotA(LPCSTR lpName,DWORD nMaxMessageSize,DWORD lReadTimeout,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ WINBASEAPI HANDLE WINAPI CreateMailslotW(LPCWSTR lpName,DWORD nMaxMessageSize,DWORD lReadTimeout,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ WINBASEAPI WINBOOL WINAPI GetMailslotInfo(HANDLE hMailslot,LPDWORD lpMaxMessageSize,LPDWORD lpNextSize,LPDWORD lpMessageCount,LPDWORD lpReadTimeout);
+ WINBASEAPI WINBOOL WINAPI SetMailslotInfo(HANDLE hMailslot,DWORD lReadTimeout);
+ WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE hFileMappingObject,DWORD dwDesiredAccess,DWORD dwFileOffsetHigh,DWORD dwFileOffsetLow,SIZE_T dwNumberOfBytesToMap);
+ WINBASEAPI WINBOOL WINAPI FlushViewOfFile(LPCVOID lpBaseAddress,SIZE_T dwNumberOfBytesToFlush);
+ WINBASEAPI WINBOOL WINAPI UnmapViewOfFile(LPCVOID lpBaseAddress);
+ WINADVAPI WINBOOL WINAPI EncryptFileA(LPCSTR lpFileName);
+ WINADVAPI WINBOOL WINAPI EncryptFileW(LPCWSTR lpFileName);
+ WINADVAPI WINBOOL WINAPI DecryptFileA(LPCSTR lpFileName,DWORD dwReserved);
+ WINADVAPI WINBOOL WINAPI DecryptFileW(LPCWSTR lpFileName,DWORD dwReserved);
+
+#define FILE_ENCRYPTABLE 0
+#define FILE_IS_ENCRYPTED 1
+#define FILE_SYSTEM_ATTR 2
+#define FILE_ROOT_DIR 3
+#define FILE_SYSTEM_DIR 4
+#define FILE_UNKNOWN 5
+#define FILE_SYSTEM_NOT_SUPPORT 6
+#define FILE_USER_DISALLOWED 7
+#define FILE_READ_ONLY 8
+#define FILE_DIR_DISALLOWED 9
+
+ WINADVAPI WINBOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName,LPDWORD lpStatus);
+ WINADVAPI WINBOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName,LPDWORD lpStatus);
+
+#define EFS_USE_RECOVERY_KEYS (0x1)
+
+ typedef DWORD (WINAPI *PFE_EXPORT_FUNC)(PBYTE pbData,PVOID pvCallbackContext,ULONG ulLength);
+ typedef DWORD (WINAPI *PFE_IMPORT_FUNC)(PBYTE pbData,PVOID pvCallbackContext,PULONG ulLength);
+
+#define CREATE_FOR_IMPORT (1)
+#define CREATE_FOR_DIR (2)
+#define OVERWRITE_HIDDEN (4)
+
+#ifdef UNICODE
+#define OpenEncryptedFileRaw OpenEncryptedFileRawW
+#define lstrcmp lstrcmpW
+#define lstrcmpi lstrcmpiW
+#define lstrcpyn lstrcpynW
+#define lstrcpy lstrcpyW
+#define lstrcat lstrcatW
+#define lstrlen lstrlenW
+#else
+#define OpenEncryptedFileRaw OpenEncryptedFileRawA
+#define lstrcmp lstrcmpA
+#define lstrcmpi lstrcmpiA
+#define lstrcpyn lstrcpynA
+#define lstrcpy lstrcpyA
+#define lstrcat lstrcatA
+#define lstrlen lstrlenA
+#endif
+
+ WINADVAPI DWORD WINAPI OpenEncryptedFileRawA(LPCSTR lpFileName,ULONG ulFlags,PVOID *pvContext);
+ WINADVAPI DWORD WINAPI OpenEncryptedFileRawW(LPCWSTR lpFileName,ULONG ulFlags,PVOID *pvContext);
+ WINADVAPI DWORD WINAPI ReadEncryptedFileRaw(PFE_EXPORT_FUNC pfExportCallback,PVOID pvCallbackContext,PVOID pvContext);
+ WINADVAPI DWORD WINAPI WriteEncryptedFileRaw(PFE_IMPORT_FUNC pfImportCallback,PVOID pvCallbackContext,PVOID pvContext);
+ WINADVAPI VOID WINAPI CloseEncryptedFileRaw(PVOID pvContext);
+ WINBASEAPI int WINAPI lstrcmpA(LPCSTR lpString1,LPCSTR lpString2);
+ WINBASEAPI int WINAPI lstrcmpW(LPCWSTR lpString1,LPCWSTR lpString2);
+ WINBASEAPI int WINAPI lstrcmpiA(LPCSTR lpString1,LPCSTR lpString2);
+ WINBASEAPI int WINAPI lstrcmpiW(LPCWSTR lpString1,LPCWSTR lpString2);
+ WINBASEAPI LPSTR WINAPI lstrcpynA(LPSTR lpString1,LPCSTR lpString2,int iMaxLength);
+ WINBASEAPI LPWSTR WINAPI lstrcpynW(LPWSTR lpString1,LPCWSTR lpString2,int iMaxLength);
+ WINBASEAPI LPSTR WINAPI lstrcpyA(LPSTR lpString1,LPCSTR lpString2);
+ WINBASEAPI LPWSTR WINAPI lstrcpyW(LPWSTR lpString1,LPCWSTR lpString2);
+ WINBASEAPI LPSTR WINAPI lstrcatA(LPSTR lpString1,LPCSTR lpString2);
+ WINBASEAPI LPWSTR WINAPI lstrcatW(LPWSTR lpString1,LPCWSTR lpString2);
+ WINBASEAPI int WINAPI lstrlenA(LPCSTR lpString);
+ WINBASEAPI int WINAPI lstrlenW(LPCWSTR lpString);
+ WINBASEAPI HFILE WINAPI OpenFile(LPCSTR lpFileName,LPOFSTRUCT lpReOpenBuff,UINT uStyle);
+ WINBASEAPI HFILE WINAPI _lopen(LPCSTR lpPathName,int iReadWrite);
+ WINBASEAPI HFILE WINAPI _lcreat(LPCSTR lpPathName,int iAttribute);
+ WINBASEAPI UINT WINAPI _lread(HFILE hFile,LPVOID lpBuffer,UINT uBytes);
+ WINBASEAPI UINT WINAPI _lwrite(HFILE hFile,LPCCH lpBuffer,UINT uBytes);
+ WINBASEAPI long WINAPI _hread(HFILE hFile,LPVOID lpBuffer,long lBytes);
+ WINBASEAPI long WINAPI _hwrite(HFILE hFile,LPCCH lpBuffer,long lBytes);
+ WINBASEAPI HFILE WINAPI _lclose(HFILE hFile);
+ WINBASEAPI LONG WINAPI _llseek(HFILE hFile,LONG lOffset,int iOrigin);
+ WINADVAPI WINBOOL WINAPI IsTextUnicode(CONST VOID *lpv,int iSize,LPINT lpiResult);
+
+#define FLS_OUT_OF_INDEXES ((DWORD)0xffffffff)
+
+ WINBASEAPI DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback);
+ WINBASEAPI PVOID WINAPI FlsGetValue(DWORD dwFlsIndex);
+ WINBASEAPI WINBOOL WINAPI FlsSetValue(DWORD dwFlsIndex,PVOID lpFlsData);
+ WINBASEAPI WINBOOL WINAPI FlsFree(DWORD dwFlsIndex);
+
+#define TLS_OUT_OF_INDEXES ((DWORD)0xffffffff)
+
+ WINBASEAPI DWORD WINAPI TlsAlloc(VOID);
+ WINBASEAPI LPVOID WINAPI TlsGetValue(DWORD dwTlsIndex);
+ WINBASEAPI WINBOOL WINAPI TlsSetValue(DWORD dwTlsIndex,LPVOID lpTlsValue);
+ WINBASEAPI WINBOOL WINAPI TlsFree(DWORD dwTlsIndex);
+
+ typedef VOID (WINAPI *LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD dwErrorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped);
+
+ WINBASEAPI DWORD WINAPI SleepEx(DWORD dwMilliseconds,WINBOOL bAlertable);
+ WINBASEAPI DWORD WINAPI WaitForSingleObjectEx(HANDLE hHandle,DWORD dwMilliseconds,WINBOOL bAlertable);
+ WINBASEAPI DWORD WINAPI WaitForMultipleObjectsEx(DWORD nCount,CONST HANDLE *lpHandles,WINBOOL bWaitAll,DWORD dwMilliseconds,WINBOOL bAlertable);
+ WINBASEAPI DWORD WINAPI SignalObjectAndWait(HANDLE hObjectToSignal,HANDLE hObjectToWaitOn,DWORD dwMilliseconds,WINBOOL bAlertable);
+ WINBASEAPI WINBOOL WINAPI ReadFileEx(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPOVERLAPPED lpOverlapped,LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
+ WINBASEAPI WINBOOL WINAPI WriteFileEx(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPOVERLAPPED lpOverlapped,LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
+ WINBASEAPI WINBOOL WINAPI BackupRead(HANDLE hFile,LPBYTE lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,WINBOOL bAbort,WINBOOL bProcessSecurity,LPVOID *lpContext);
+ WINBASEAPI WINBOOL WINAPI BackupSeek(HANDLE hFile,DWORD dwLowBytesToSeek,DWORD dwHighBytesToSeek,LPDWORD lpdwLowByteSeeked,LPDWORD lpdwHighByteSeeked,LPVOID *lpContext);
+ WINBASEAPI WINBOOL WINAPI BackupWrite(HANDLE hFile,LPBYTE lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,WINBOOL bAbort,WINBOOL bProcessSecurity,LPVOID *lpContext);
+
+ typedef struct _WIN32_STREAM_ID {
+ DWORD dwStreamId;
+ DWORD dwStreamAttributes;
+ LARGE_INTEGER Size;
+ DWORD dwStreamNameSize;
+ WCHAR cStreamName[ANYSIZE_ARRAY];
+ } WIN32_STREAM_ID,*LPWIN32_STREAM_ID;
+
+#define BACKUP_INVALID 0x0
+#define BACKUP_DATA 0x1
+#define BACKUP_EA_DATA 0x2
+#define BACKUP_SECURITY_DATA 0x3
+#define BACKUP_ALTERNATE_DATA 0x4
+#define BACKUP_LINK 0x5
+#define BACKUP_PROPERTY_DATA 0x6
+#define BACKUP_OBJECT_ID 0x7
+#define BACKUP_REPARSE_DATA 0x8
+#define BACKUP_SPARSE_BLOCK 0x9
+
+#define STREAM_NORMAL_ATTRIBUTE 0x0
+#define STREAM_MODIFIED_WHEN_READ 0x1
+#define STREAM_CONTAINS_SECURITY 0x2
+#define STREAM_CONTAINS_PROPERTIES 0x4
+#define STREAM_SPARSE_ATTRIBUTE 0x8
+
+ WINBASEAPI WINBOOL WINAPI ReadFileScatter(HANDLE hFile,FILE_SEGMENT_ELEMENT aSegmentArray[],DWORD nNumberOfBytesToRead,LPDWORD lpReserved,LPOVERLAPPED lpOverlapped);
+ WINBASEAPI WINBOOL WINAPI WriteFileGather(HANDLE hFile,FILE_SEGMENT_ELEMENT aSegmentArray[],DWORD nNumberOfBytesToWrite,LPDWORD lpReserved,LPOVERLAPPED lpOverlapped);
+
+#define STARTF_USESHOWWINDOW 0x1
+#define STARTF_USESIZE 0x2
+#define STARTF_USEPOSITION 0x4
+#define STARTF_USECOUNTCHARS 0x8
+#define STARTF_USEFILLATTRIBUTE 0x10
+#define STARTF_RUNFULLSCREEN 0x20
+#define STARTF_FORCEONFEEDBACK 0x40
+#define STARTF_FORCEOFFFEEDBACK 0x80
+#define STARTF_USESTDHANDLES 0x100
+
+#define STARTF_USEHOTKEY 0x200
+
+ typedef struct _STARTUPINFOA {
+ DWORD cb;
+ LPSTR lpReserved;
+ LPSTR lpDesktop;
+ LPSTR lpTitle;
+ DWORD dwX;
+ DWORD dwY;
+ DWORD dwXSize;
+ DWORD dwYSize;
+ DWORD dwXCountChars;
+ DWORD dwYCountChars;
+ DWORD dwFillAttribute;
+ DWORD dwFlags;
+ WORD wShowWindow;
+ WORD cbReserved2;
+ LPBYTE lpReserved2;
+ HANDLE hStdInput;
+ HANDLE hStdOutput;
+ HANDLE hStdError;
+ } STARTUPINFOA,*LPSTARTUPINFOA;
+
+ typedef struct _STARTUPINFOW {
+ DWORD cb;
+ LPWSTR lpReserved;
+ LPWSTR lpDesktop;
+ LPWSTR lpTitle;
+ DWORD dwX;
+ DWORD dwY;
+ DWORD dwXSize;
+ DWORD dwYSize;
+ DWORD dwXCountChars;
+ DWORD dwYCountChars;
+ DWORD dwFillAttribute;
+ DWORD dwFlags;
+ WORD wShowWindow;
+ WORD cbReserved2;
+ LPBYTE lpReserved2;
+ HANDLE hStdInput;
+ HANDLE hStdOutput;
+ HANDLE hStdError;
+ } STARTUPINFOW,*LPSTARTUPINFOW;
+
+#ifdef UNICODE
+ typedef STARTUPINFOW STARTUPINFO;
+ typedef LPSTARTUPINFOW LPSTARTUPINFO;
+#else
+ typedef STARTUPINFOA STARTUPINFO;
+ typedef LPSTARTUPINFOA LPSTARTUPINFO;
+#endif
+
+#define SHUTDOWN_NORETRY 0x1
+
+ typedef struct _WIN32_FIND_DATAA {
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+ DWORD dwReserved0;
+ DWORD dwReserved1;
+ CHAR cFileName[MAX_PATH];
+ CHAR cAlternateFileName[14];
+ } WIN32_FIND_DATAA,*PWIN32_FIND_DATAA,*LPWIN32_FIND_DATAA;
+
+ typedef struct _WIN32_FIND_DATAW {
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+ DWORD dwReserved0;
+ DWORD dwReserved1;
+ WCHAR cFileName[MAX_PATH];
+ WCHAR cAlternateFileName[14];
+ } WIN32_FIND_DATAW,*PWIN32_FIND_DATAW,*LPWIN32_FIND_DATAW;
+
+#ifdef UNICODE
+ typedef WIN32_FIND_DATAW WIN32_FIND_DATA;
+ typedef PWIN32_FIND_DATAW PWIN32_FIND_DATA;
+ typedef LPWIN32_FIND_DATAW LPWIN32_FIND_DATA;
+#else
+ typedef WIN32_FIND_DATAA WIN32_FIND_DATA;
+ typedef PWIN32_FIND_DATAA PWIN32_FIND_DATA;
+ typedef LPWIN32_FIND_DATAA LPWIN32_FIND_DATA;
+#endif
+
+ typedef struct _WIN32_FILE_ATTRIBUTE_DATA {
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+ } WIN32_FILE_ATTRIBUTE_DATA,*LPWIN32_FILE_ATTRIBUTE_DATA;
+
+#ifdef UNICODE
+#define CreateMutex CreateMutexW
+#define OpenMutex OpenMutexW
+#define CreateEvent CreateEventW
+#define OpenEvent OpenEventW
+#define CreateSemaphore CreateSemaphoreW
+#define OpenSemaphore OpenSemaphoreW
+#else
+#define CreateMutex CreateMutexA
+#define OpenMutex OpenMutexA
+#define CreateEvent CreateEventA
+#define OpenEvent OpenEventA
+#define CreateSemaphore CreateSemaphoreA
+#define OpenSemaphore OpenSemaphoreA
+#endif
+
+ WINBASEAPI HANDLE WINAPI CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes,WINBOOL bInitialOwner,LPCSTR lpName);
+ WINBASEAPI HANDLE WINAPI CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes,WINBOOL bInitialOwner,LPCWSTR lpName);
+ WINBASEAPI HANDLE WINAPI OpenMutexA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpName);
+ WINBASEAPI HANDLE WINAPI OpenMutexW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpName);
+ WINBASEAPI HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes,WINBOOL bManualReset,WINBOOL bInitialState,LPCSTR lpName);
+ WINBASEAPI HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes,WINBOOL bManualReset,WINBOOL bInitialState,LPCWSTR lpName);
+ WINBASEAPI HANDLE WINAPI OpenEventA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpName);
+ WINBASEAPI HANDLE WINAPI OpenEventW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpName);
+ WINBASEAPI HANDLE WINAPI CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCSTR lpName);
+ WINBASEAPI HANDLE WINAPI CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCWSTR lpName);
+ WINBASEAPI HANDLE WINAPI OpenSemaphoreA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpName);
+ WINBASEAPI HANDLE WINAPI OpenSemaphoreW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpName);
+
+ typedef VOID (WINAPI *PTIMERAPCROUTINE)(LPVOID lpArgToCompletionRoutine,DWORD dwTimerLowValue,DWORD dwTimerHighValue);
+
+#ifdef UNICODE
+#define CreateWaitableTimer CreateWaitableTimerW
+#define OpenWaitableTimer OpenWaitableTimerW
+#define CreateFileMapping CreateFileMappingW
+#define OpenFileMapping OpenFileMappingW
+#define GetLogicalDriveStrings GetLogicalDriveStringsW
+#define LoadLibrary LoadLibraryW
+#define LoadLibraryEx LoadLibraryExW
+#define GetModuleFileName GetModuleFileNameW
+#define GetModuleHandle GetModuleHandleW
+#else
+#define CreateWaitableTimer CreateWaitableTimerA
+#define OpenWaitableTimer OpenWaitableTimerA
+#define CreateFileMapping CreateFileMappingA
+#define OpenFileMapping OpenFileMappingA
+#define GetLogicalDriveStrings GetLogicalDriveStringsA
+#define LoadLibrary LoadLibraryA
+#define LoadLibraryEx LoadLibraryExA
+#define GetModuleFileName GetModuleFileNameA
+#define GetModuleHandle GetModuleHandleA
+#endif
+
+ WINBASEAPI HANDLE WINAPI CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes,WINBOOL bManualReset,LPCSTR lpTimerName);
+ WINBASEAPI HANDLE WINAPI CreateWaitableTimerW(LPSECURITY_ATTRIBUTES lpTimerAttributes,WINBOOL bManualReset,LPCWSTR lpTimerName);
+ WINBASEAPI HANDLE WINAPI OpenWaitableTimerA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpTimerName);
+ WINBASEAPI HANDLE WINAPI OpenWaitableTimerW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpTimerName);
+ WINBASEAPI WINBOOL WINAPI SetWaitableTimer(HANDLE hTimer,const LARGE_INTEGER *lpDueTime,LONG lPeriod,PTIMERAPCROUTINE pfnCompletionRoutine,LPVOID lpArgToCompletionRoutine,WINBOOL fResume);
+ WINBASEAPI WINBOOL WINAPI CancelWaitableTimer(HANDLE hTimer);
+ WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,LPCSTR lpName);
+ WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,LPCWSTR lpName);
+ WINBASEAPI HANDLE WINAPI OpenFileMappingA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpName);
+ WINBASEAPI HANDLE WINAPI OpenFileMappingW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpName);
+ WINBASEAPI DWORD WINAPI GetLogicalDriveStringsA(DWORD nBufferLength,LPSTR lpBuffer);
+ WINBASEAPI DWORD WINAPI GetLogicalDriveStringsW(DWORD nBufferLength,LPWSTR lpBuffer);
+
+ typedef enum _MEMORY_RESOURCE_NOTIFICATION_TYPE {
+ LowMemoryResourceNotification,HighMemoryResourceNotification
+ } MEMORY_RESOURCE_NOTIFICATION_TYPE;
+
+ WINBASEAPI HANDLE WINAPI CreateMemoryResourceNotification(MEMORY_RESOURCE_NOTIFICATION_TYPE NotificationType);
+ WINBASEAPI WINBOOL WINAPI QueryMemoryResourceNotification(HANDLE ResourceNotificationHandle,PBOOL ResourceState);
+ WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR lpLibFileName);
+ WINBASEAPI HMODULE WINAPI LoadLibraryW(LPCWSTR lpLibFileName);
+ WINBASEAPI HMODULE WINAPI LoadLibraryExA(LPCSTR lpLibFileName,HANDLE hFile,DWORD dwFlags);
+ WINBASEAPI HMODULE WINAPI LoadLibraryExW(LPCWSTR lpLibFileName,HANDLE hFile,DWORD dwFlags);
+
+#define DONT_RESOLVE_DLL_REFERENCES 0x1
+#define LOAD_LIBRARY_AS_DATAFILE 0x2
+#define LOAD_WITH_ALTERED_SEARCH_PATH 0x8
+#define LOAD_IGNORE_CODE_AUTHZ_LEVEL 0x10
+#define LOAD_LINRARY_AS_IMAGE_RESOURCE 0x20
+#define LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE 0x40
+
+ WINBASEAPI DWORD WINAPI GetModuleFileNameA(HMODULE hModule,LPCH lpFilename,DWORD nSize);
+ WINBASEAPI DWORD WINAPI GetModuleFileNameW(HMODULE hModule,LPWCH lpFilename,DWORD nSize);
+ WINBASEAPI HMODULE WINAPI GetModuleHandleA(LPCSTR lpModuleName);
+ WINBASEAPI HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName);
+
+#ifndef RC_INVOKED
+#define GET_MODULE_HANDLE_EX_FLAG_PIN (0x1)
+#define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT (0x2)
+#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS (0x4)
+
+ typedef WINBOOL (WINAPI *PGET_MODULE_HANDLE_EXA)(DWORD dwFlags,LPCSTR lpModuleName,HMODULE *phModule);
+ typedef WINBOOL (WINAPI *PGET_MODULE_HANDLE_EXW)(DWORD dwFlags,LPCWSTR lpModuleName,HMODULE *phModule);
+
+#ifdef UNICODE
+#define PGET_MODULE_HANDLE_EX PGET_MODULE_HANDLE_EXW
+#define GetModuleHandleEx GetModuleHandleExW
+#else
+#define PGET_MODULE_HANDLE_EX PGET_MODULE_HANDLE_EXA
+#define GetModuleHandleEx GetModuleHandleExA
+#endif
+
+ WINBASEAPI WINBOOL WINAPI GetModuleHandleExA(DWORD dwFlags,LPCSTR lpModuleName,HMODULE *phModule);
+ WINBASEAPI WINBOOL WINAPI GetModuleHandleExW(DWORD dwFlags,LPCWSTR lpModuleName,HMODULE *phModule);
+#endif
+
+#ifdef UNICODE
+#define NeedCurrentDirectoryForExePath NeedCurrentDirectoryForExePathW
+#define CreateProcess CreateProcessW
+#define FatalAppExit FatalAppExitW
+#define GetStartupInfo GetStartupInfoW
+#define GetCommandLine GetCommandLineW
+#define GetEnvironmentVariable GetEnvironmentVariableW
+#define SetEnvironmentVariable SetEnvironmentVariableW
+#define ExpandEnvironmentStrings ExpandEnvironmentStringsW
+#define GetFirmwareEnvironmentVariable GetFirmwareEnvironmentVariableW
+#define SetFirmwareEnvironmentVariable SetFirmwareEnvironmentVariableW
+#define OutputDebugString OutputDebugStringW
+#define FindResource FindResourceW
+#define FindResourceEx FindResourceExW
+#else
+#define NeedCurrentDirectoryForExePath NeedCurrentDirectoryForExePathA
+#define CreateProcess CreateProcessA
+#define FatalAppExit FatalAppExitA
+#define GetStartupInfo GetStartupInfoA
+#define GetCommandLine GetCommandLineA
+#define GetEnvironmentVariable GetEnvironmentVariableA
+#define SetEnvironmentVariable SetEnvironmentVariableA
+#define ExpandEnvironmentStrings ExpandEnvironmentStringsA
+#define GetFirmwareEnvironmentVariable GetFirmwareEnvironmentVariableA
+#define SetFirmwareEnvironmentVariable SetFirmwareEnvironmentVariableA
+#define OutputDebugString OutputDebugStringA
+#define FindResource FindResourceA
+#define FindResourceEx FindResourceExA
+#endif
+
+ WINBASEAPI WINBOOL WINAPI NeedCurrentDirectoryForExePathA(LPCSTR ExeName);
+ WINBASEAPI WINBOOL WINAPI NeedCurrentDirectoryForExePathW(LPCWSTR ExeName);
+ WINBASEAPI WINBOOL WINAPI CreateProcessA(LPCSTR lpApplicationName,LPSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,WINBOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCSTR lpCurrentDirectory,LPSTARTUPINFOA lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation);
+ WINBASEAPI WINBOOL WINAPI CreateProcessW(LPCWSTR lpApplicationName,LPWSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,WINBOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation);
+ WINBASEAPI DWORD WINAPI AddLocalAlternateComputerNameA(LPCSTR lpDnsFQHostname,ULONG ulFlags);
+ WINBASEAPI DWORD WINAPI AddLocalAlternateComputerNameW(LPCWSTR lpDnsFQHostname,ULONG ulFlags);
+ WINBASEAPI WINBOOL WINAPI SetProcessShutdownParameters(DWORD dwLevel,DWORD dwFlags);
+ WINBASEAPI WINBOOL WINAPI GetProcessShutdownParameters(LPDWORD lpdwLevel,LPDWORD lpdwFlags);
+ WINBASEAPI DWORD WINAPI GetProcessVersion(DWORD ProcessId);
+ WINBASEAPI VOID WINAPI FatalAppExitA(UINT uAction,LPCSTR lpMessageText);
+ WINBASEAPI VOID WINAPI FatalAppExitW(UINT uAction,LPCWSTR lpMessageText);
+ WINBASEAPI VOID WINAPI GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo);
+ WINBASEAPI VOID WINAPI GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo);
+ WINBASEAPI LPSTR WINAPI GetCommandLineA(VOID);
+ WINBASEAPI LPWSTR WINAPI GetCommandLineW(VOID);
+ WINBASEAPI DWORD WINAPI GetEnvironmentVariableA(LPCSTR lpName,LPSTR lpBuffer,DWORD nSize);
+ WINBASEAPI DWORD WINAPI GetEnvironmentVariableW(LPCWSTR lpName,LPWSTR lpBuffer,DWORD nSize);
+ WINBASEAPI WINBOOL WINAPI SetEnvironmentVariableA(LPCSTR lpName,LPCSTR lpValue);
+ WINBASEAPI WINBOOL WINAPI SetEnvironmentVariableW(LPCWSTR lpName,LPCWSTR lpValue);
+ WINBASEAPI DWORD WINAPI ExpandEnvironmentStringsA(LPCSTR lpSrc,LPSTR lpDst,DWORD nSize);
+ WINBASEAPI DWORD WINAPI ExpandEnvironmentStringsW(LPCWSTR lpSrc,LPWSTR lpDst,DWORD nSize);
+ WINBASEAPI DWORD WINAPI GetFirmwareEnvironmentVariableA(LPCSTR lpName,LPCSTR lpGuid,PVOID pBuffer,DWORD nSize);
+ WINBASEAPI DWORD WINAPI GetFirmwareEnvironmentVariableW(LPCWSTR lpName,LPCWSTR lpGuid,PVOID pBuffer,DWORD nSize);
+ WINBASEAPI WINBOOL WINAPI SetFirmwareEnvironmentVariableA(LPCSTR lpName,LPCSTR lpGuid,PVOID pValue,DWORD nSize);
+ WINBASEAPI WINBOOL WINAPI SetFirmwareEnvironmentVariableW(LPCWSTR lpName,LPCWSTR lpGuid,PVOID pValue,DWORD nSize);
+ WINBASEAPI VOID WINAPI OutputDebugStringA(LPCSTR lpOutputString);
+ WINBASEAPI VOID WINAPI OutputDebugStringW(LPCWSTR lpOutputString);
+ WINBASEAPI HRSRC WINAPI FindResourceA(HMODULE hModule,LPCSTR lpName,LPCSTR lpType);
+ WINBASEAPI HRSRC WINAPI FindResourceW(HMODULE hModule,LPCWSTR lpName,LPCWSTR lpType);
+ WINBASEAPI HRSRC WINAPI FindResourceExA(HMODULE hModule,LPCSTR lpType,LPCSTR lpName,WORD wLanguage);
+ WINBASEAPI HRSRC WINAPI FindResourceExW(HMODULE hModule,LPCWSTR lpType,LPCWSTR lpName,WORD wLanguage);
+
+#ifdef UNICODE
+#define ENUMRESTYPEPROC ENUMRESTYPEPROCW
+#define ENUMRESNAMEPROC ENUMRESNAMEPROCW
+#define ENUMRESLANGPROC ENUMRESLANGPROCW
+#define EnumResourceTypes EnumResourceTypesW
+#define EnumResourceNames EnumResourceNamesW
+#define EnumResourceLanguages EnumResourceLanguagesW
+#define BeginUpdateResource BeginUpdateResourceW
+#define UpdateResource UpdateResourceW
+#define EndUpdateResource EndUpdateResourceW
+#define GlobalAddAtom GlobalAddAtomW
+#define GlobalFindAtom GlobalFindAtomW
+#define GlobalGetAtomName GlobalGetAtomNameW
+#define AddAtom AddAtomW
+#define FindAtom FindAtomW
+#define GetAtomName GetAtomNameW
+#define GetProfileInt GetProfileIntW
+#define GetProfileString GetProfileStringW
+#define WriteProfileString WriteProfileStringW
+#define GetProfileSection GetProfileSectionW
+#define WriteProfileSection WriteProfileSectionW
+#define GetPrivateProfileInt GetPrivateProfileIntW
+#define GetPrivateProfileString GetPrivateProfileStringW
+#define WritePrivateProfileString WritePrivateProfileStringW
+#define GetPrivateProfileSection GetPrivateProfileSectionW
+#define WritePrivateProfileSection WritePrivateProfileSectionW
+#define GetPrivateProfileSectionNames GetPrivateProfileSectionNamesW
+#define GetPrivateProfileStruct GetPrivateProfileStructW
+#define WritePrivateProfileStruct WritePrivateProfileStructW
+#define GetDriveType GetDriveTypeW
+#define GetSystemDirectory GetSystemDirectoryW
+#define GetTempPath GetTempPathW
+#define GetTempFileName GetTempFileNameW
+#define GetWindowsDirectory GetWindowsDirectoryW
+#define GetSystemWindowsDirectory GetSystemWindowsDirectoryW
+#define AddLocalAlternateComputerName AddLocalAlternateComputerNameW
+#else
+#define ENUMRESTYPEPROC ENUMRESTYPEPROCA
+#define ENUMRESNAMEPROC ENUMRESNAMEPROCA
+#define ENUMRESLANGPROC ENUMRESLANGPROCA
+#define EnumResourceTypes EnumResourceTypesA
+#define EnumResourceNames EnumResourceNamesA
+#define EnumResourceLanguages EnumResourceLanguagesA
+#define BeginUpdateResource BeginUpdateResourceA
+#define UpdateResource UpdateResourceA
+#define EndUpdateResource EndUpdateResourceA
+#define GlobalAddAtom GlobalAddAtomA
+#define GlobalFindAtom GlobalFindAtomA
+#define GlobalGetAtomName GlobalGetAtomNameA
+#define AddAtom AddAtomA
+#define FindAtom FindAtomA
+#define GetAtomName GetAtomNameA
+#define GetProfileInt GetProfileIntA
+#define GetProfileString GetProfileStringA
+#define WriteProfileString WriteProfileStringA
+#define GetProfileSection GetProfileSectionA
+#define WriteProfileSection WriteProfileSectionA
+#define GetPrivateProfileInt GetPrivateProfileIntA
+#define GetPrivateProfileString GetPrivateProfileStringA
+#define WritePrivateProfileString WritePrivateProfileStringA
+#define GetPrivateProfileSection GetPrivateProfileSectionA
+#define WritePrivateProfileSection WritePrivateProfileSectionA
+#define GetPrivateProfileSectionNames GetPrivateProfileSectionNamesA
+#define GetPrivateProfileStruct GetPrivateProfileStructA
+#define WritePrivateProfileStruct WritePrivateProfileStructA
+#define GetDriveType GetDriveTypeA
+#define GetSystemDirectory GetSystemDirectoryA
+#define GetTempPath GetTempPathA
+#define GetTempFileName GetTempFileNameA
+#define GetWindowsDirectory GetWindowsDirectoryA
+#define GetSystemWindowsDirectory GetSystemWindowsDirectoryA
+#define AddLocalAlternateComputerName AddLocalAlternateComputerNameA
+#endif
+
+ typedef WINBOOL (CALLBACK *ENUMRESTYPEPROCA)(HMODULE hModule,LPSTR lpType,LONG_PTR lParam);
+ typedef WINBOOL (CALLBACK *ENUMRESTYPEPROCW)(HMODULE hModule,LPWSTR lpType,LONG_PTR lParam);
+ typedef WINBOOL (CALLBACK *ENUMRESNAMEPROCA)(HMODULE hModule,LPCSTR lpType,LPSTR lpName,LONG_PTR lParam);
+ typedef WINBOOL (CALLBACK *ENUMRESNAMEPROCW)(HMODULE hModule,LPCWSTR lpType,LPWSTR lpName,LONG_PTR lParam);
+ typedef WINBOOL (CALLBACK *ENUMRESLANGPROCA)(HMODULE hModule,LPCSTR lpType,LPCSTR lpName,WORD wLanguage,LONG_PTR lParam);
+ typedef WINBOOL (CALLBACK *ENUMRESLANGPROCW)(HMODULE hModule,LPCWSTR lpType,LPCWSTR lpName,WORD wLanguage,LONG_PTR lParam);
+
+ WINBASEAPI WINBOOL WINAPI EnumResourceTypesA(HMODULE hModule,ENUMRESTYPEPROCA lpEnumFunc,LONG_PTR lParam);
+ WINBASEAPI WINBOOL WINAPI EnumResourceTypesW(HMODULE hModule,ENUMRESTYPEPROCW lpEnumFunc,LONG_PTR lParam);
+ WINBASEAPI WINBOOL WINAPI EnumResourceNamesA(HMODULE hModule,LPCSTR lpType,ENUMRESNAMEPROCA lpEnumFunc,LONG_PTR lParam);
+ WINBASEAPI WINBOOL WINAPI EnumResourceNamesW(HMODULE hModule,LPCWSTR lpType,ENUMRESNAMEPROCW lpEnumFunc,LONG_PTR lParam);
+ WINBASEAPI WINBOOL WINAPI EnumResourceLanguagesA(HMODULE hModule,LPCSTR lpType,LPCSTR lpName,ENUMRESLANGPROCA lpEnumFunc,LONG_PTR lParam);
+ WINBASEAPI WINBOOL WINAPI EnumResourceLanguagesW(HMODULE hModule,LPCWSTR lpType,LPCWSTR lpName,ENUMRESLANGPROCW lpEnumFunc,LONG_PTR lParam);
+ WINBASEAPI HANDLE WINAPI BeginUpdateResourceA(LPCSTR pFileName,WINBOOL bDeleteExistingResources);
+ WINBASEAPI HANDLE WINAPI BeginUpdateResourceW(LPCWSTR pFileName,WINBOOL bDeleteExistingResources);
+ WINBASEAPI WINBOOL WINAPI UpdateResourceA(HANDLE hUpdate,LPCSTR lpType,LPCSTR lpName,WORD wLanguage,LPVOID lpData,DWORD cb);
+ WINBASEAPI WINBOOL WINAPI UpdateResourceW(HANDLE hUpdate,LPCWSTR lpType,LPCWSTR lpName,WORD wLanguage,LPVOID lpData,DWORD cb);
+ WINBASEAPI WINBOOL WINAPI EndUpdateResourceA(HANDLE hUpdate,WINBOOL fDiscard);
+ WINBASEAPI WINBOOL WINAPI EndUpdateResourceW(HANDLE hUpdate,WINBOOL fDiscard);
+ WINBASEAPI ATOM WINAPI GlobalAddAtomA(LPCSTR lpString);
+ WINBASEAPI ATOM WINAPI GlobalAddAtomW(LPCWSTR lpString);
+ WINBASEAPI ATOM WINAPI GlobalFindAtomA(LPCSTR lpString);
+ WINBASEAPI ATOM WINAPI GlobalFindAtomW(LPCWSTR lpString);
+ WINBASEAPI UINT WINAPI GlobalGetAtomNameA(ATOM nAtom,LPSTR lpBuffer,int nSize);
+ WINBASEAPI UINT WINAPI GlobalGetAtomNameW(ATOM nAtom,LPWSTR lpBuffer,int nSize);
+ WINBASEAPI ATOM WINAPI AddAtomA(LPCSTR lpString);
+ WINBASEAPI ATOM WINAPI AddAtomW(LPCWSTR lpString);
+ WINBASEAPI ATOM WINAPI FindAtomA(LPCSTR lpString);
+ WINBASEAPI ATOM WINAPI FindAtomW(LPCWSTR lpString);
+ WINBASEAPI UINT WINAPI GetAtomNameA(ATOM nAtom,LPSTR lpBuffer,int nSize);
+ WINBASEAPI UINT WINAPI GetAtomNameW(ATOM nAtom,LPWSTR lpBuffer,int nSize);
+ WINBASEAPI UINT WINAPI GetProfileIntA(LPCSTR lpAppName,LPCSTR lpKeyName,INT nDefault);
+ WINBASEAPI UINT WINAPI GetProfileIntW(LPCWSTR lpAppName,LPCWSTR lpKeyName,INT nDefault);
+ WINBASEAPI DWORD WINAPI GetProfileStringA(LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpDefault,LPSTR lpReturnedString,DWORD nSize);
+ WINBASEAPI DWORD WINAPI GetProfileStringW(LPCWSTR lpAppName,LPCWSTR lpKeyName,LPCWSTR lpDefault,LPWSTR lpReturnedString,DWORD nSize);
+ WINBASEAPI WINBOOL WINAPI WriteProfileStringA(LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpString);
+ WINBASEAPI WINBOOL WINAPI WriteProfileStringW(LPCWSTR lpAppName,LPCWSTR lpKeyName,LPCWSTR lpString);
+ WINBASEAPI DWORD WINAPI GetProfileSectionA(LPCSTR lpAppName,LPSTR lpReturnedString,DWORD nSize);
+ WINBASEAPI DWORD WINAPI GetProfileSectionW(LPCWSTR lpAppName,LPWSTR lpReturnedString,DWORD nSize);
+ WINBASEAPI WINBOOL WINAPI WriteProfileSectionA(LPCSTR lpAppName,LPCSTR lpString);
+ WINBASEAPI WINBOOL WINAPI WriteProfileSectionW(LPCWSTR lpAppName,LPCWSTR lpString);
+ WINBASEAPI UINT WINAPI GetPrivateProfileIntA(LPCSTR lpAppName,LPCSTR lpKeyName,INT nDefault,LPCSTR lpFileName);
+ WINBASEAPI UINT WINAPI GetPrivateProfileIntW(LPCWSTR lpAppName,LPCWSTR lpKeyName,INT nDefault,LPCWSTR lpFileName);
+ WINBASEAPI DWORD WINAPI GetPrivateProfileStringA(LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpDefault,LPSTR lpReturnedString,DWORD nSize,LPCSTR lpFileName);
+ WINBASEAPI DWORD WINAPI GetPrivateProfileStringW(LPCWSTR lpAppName,LPCWSTR lpKeyName,LPCWSTR lpDefault,LPWSTR lpReturnedString,DWORD nSize,LPCWSTR lpFileName);
+ WINBASEAPI WINBOOL WINAPI WritePrivateProfileStringA(LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpString,LPCSTR lpFileName);
+ WINBASEAPI WINBOOL WINAPI WritePrivateProfileStringW(LPCWSTR lpAppName,LPCWSTR lpKeyName,LPCWSTR lpString,LPCWSTR lpFileName);
+ WINBASEAPI DWORD WINAPI GetPrivateProfileSectionA(LPCSTR lpAppName,LPSTR lpReturnedString,DWORD nSize,LPCSTR lpFileName);
+ WINBASEAPI DWORD WINAPI GetPrivateProfileSectionW(LPCWSTR lpAppName,LPWSTR lpReturnedString,DWORD nSize,LPCWSTR lpFileName);
+ WINBASEAPI WINBOOL WINAPI WritePrivateProfileSectionA(LPCSTR lpAppName,LPCSTR lpString,LPCSTR lpFileName);
+ WINBASEAPI WINBOOL WINAPI WritePrivateProfileSectionW(LPCWSTR lpAppName,LPCWSTR lpString,LPCWSTR lpFileName);
+ WINBASEAPI DWORD WINAPI GetPrivateProfileSectionNamesA(LPSTR lpszReturnBuffer,DWORD nSize,LPCSTR lpFileName);
+ WINBASEAPI DWORD WINAPI GetPrivateProfileSectionNamesW(LPWSTR lpszReturnBuffer,DWORD nSize,LPCWSTR lpFileName);
+ WINBASEAPI WINBOOL WINAPI GetPrivateProfileStructA(LPCSTR lpszSection,LPCSTR lpszKey,LPVOID lpStruct,UINT uSizeStruct,LPCSTR szFile);
+ WINBASEAPI WINBOOL WINAPI GetPrivateProfileStructW(LPCWSTR lpszSection,LPCWSTR lpszKey,LPVOID lpStruct,UINT uSizeStruct,LPCWSTR szFile);
+ WINBASEAPI WINBOOL WINAPI WritePrivateProfileStructA(LPCSTR lpszSection,LPCSTR lpszKey,LPVOID lpStruct,UINT uSizeStruct,LPCSTR szFile);
+ WINBASEAPI WINBOOL WINAPI WritePrivateProfileStructW(LPCWSTR lpszSection,LPCWSTR lpszKey,LPVOID lpStruct,UINT uSizeStruct,LPCWSTR szFile);
+ WINBASEAPI UINT WINAPI GetDriveTypeA(LPCSTR lpRootPathName);
+ WINBASEAPI UINT WINAPI GetDriveTypeW(LPCWSTR lpRootPathName);
+ WINBASEAPI UINT WINAPI GetSystemDirectoryA(LPSTR lpBuffer,UINT uSize);
+ WINBASEAPI UINT WINAPI GetSystemDirectoryW(LPWSTR lpBuffer,UINT uSize);
+ WINBASEAPI DWORD WINAPI GetTempPathA(DWORD nBufferLength,LPSTR lpBuffer);
+ WINBASEAPI DWORD WINAPI GetTempPathW(DWORD nBufferLength,LPWSTR lpBuffer);
+ WINBASEAPI UINT WINAPI GetTempFileNameA(LPCSTR lpPathName,LPCSTR lpPrefixString,UINT uUnique,LPSTR lpTempFileName);
+ WINBASEAPI UINT WINAPI GetTempFileNameW(LPCWSTR lpPathName,LPCWSTR lpPrefixString,UINT uUnique,LPWSTR lpTempFileName);
+ WINBASEAPI UINT WINAPI GetWindowsDirectoryA(LPSTR lpBuffer,UINT uSize);
+ WINBASEAPI UINT WINAPI GetWindowsDirectoryW(LPWSTR lpBuffer,UINT uSize);
+ WINBASEAPI UINT WINAPI GetSystemWindowsDirectoryA(LPSTR lpBuffer,UINT uSize);
+ WINBASEAPI UINT WINAPI GetSystemWindowsDirectoryW(LPWSTR lpBuffer,UINT uSize);
+
+#ifndef RC_INVOKED
+#ifdef UNICODE
+#define GetSystemWow64Directory GetSystemWow64DirectoryW
+#else
+#define GetSystemWow64Directory GetSystemWow64DirectoryA
+#endif
+
+ WINBASEAPI UINT WINAPI GetSystemWow64DirectoryA(LPSTR lpBuffer,UINT uSize);
+ WINBASEAPI UINT WINAPI GetSystemWow64DirectoryW(LPWSTR lpBuffer,UINT uSize);
+ WINBASEAPI BOOLEAN WINAPI Wow64EnableWow64FsRedirection(BOOLEAN Wow64FsEnableRedirection);
+ WINBASEAPI WINBOOL WINAPI Wow64DisableWow64FsRedirection(PVOID *OldValue);
+ WINBASEAPI WINBOOL WINAPI Wow64RevertWow64FsRedirection(PVOID OlValue);
+
+ typedef UINT (WINAPI *PGET_SYSTEM_WOW64_DIRECTORY_A)(LPSTR lpBuffer,UINT uSize);
+ typedef UINT (WINAPI *PGET_SYSTEM_WOW64_DIRECTORY_W)(LPWSTR lpBuffer,UINT uSize);
+
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_A_A "GetSystemWow64DirectoryA"
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_A_W L"GetSystemWow64DirectoryA"
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_A_T TEXT("GetSystemWow64DirectoryA")
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_W_A "GetSystemWow64DirectoryW"
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_W_W L"GetSystemWow64DirectoryW"
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_W_T TEXT("GetSystemWow64DirectoryW")
+
+#ifdef UNICODE
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_A GET_SYSTEM_WOW64_DIRECTORY_NAME_W_A
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_W GET_SYSTEM_WOW64_DIRECTORY_NAME_W_W
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_T GET_SYSTEM_WOW64_DIRECTORY_NAME_W_T
+#else
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_A GET_SYSTEM_WOW64_DIRECTORY_NAME_A_A
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_W GET_SYSTEM_WOW64_DIRECTORY_NAME_A_W
+#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_T GET_SYSTEM_WOW64_DIRECTORY_NAME_A_T
+#endif
+#endif
+
+#ifdef UNICODE
+#define SetCurrentDirectory SetCurrentDirectoryW
+#define GetCurrentDirectory GetCurrentDirectoryW
+#define SetDllDirectory SetDllDirectoryW
+#define GetDllDirectory GetDllDirectoryW
+#define GetDiskFreeSpace GetDiskFreeSpaceW
+#define GetDiskFreeSpaceEx GetDiskFreeSpaceExW
+#define CreateDirectory CreateDirectoryW
+#define CreateDirectoryEx CreateDirectoryExW
+#define RemoveDirectory RemoveDirectoryW
+#define GetFullPathName GetFullPathNameW
+#define DefineDosDevice DefineDosDeviceW
+#define QueryDosDevice QueryDosDeviceW
+#define CreateFile CreateFileW
+#define SetFileAttributes SetFileAttributesW
+#define GetFileAttributes GetFileAttributesW
+#else
+#define SetCurrentDirectory SetCurrentDirectoryA
+#define GetCurrentDirectory GetCurrentDirectoryA
+#define SetDllDirectory SetDllDirectoryA
+#define GetDllDirectory GetDllDirectoryA
+#define GetDiskFreeSpace GetDiskFreeSpaceA
+#define GetDiskFreeSpaceEx GetDiskFreeSpaceExA
+#define CreateDirectory CreateDirectoryA
+#define CreateDirectoryEx CreateDirectoryExA
+#define RemoveDirectory RemoveDirectoryA
+#define GetFullPathName GetFullPathNameA
+#define DefineDosDevice DefineDosDeviceA
+#define QueryDosDevice QueryDosDeviceA
+#define CreateFile CreateFileA
+#define SetFileAttributes SetFileAttributesA
+#define GetFileAttributes GetFileAttributesA
+#endif
+
+ WINBASEAPI WINBOOL WINAPI SetCurrentDirectoryA(LPCSTR lpPathName);
+ WINBASEAPI WINBOOL WINAPI SetCurrentDirectoryW(LPCWSTR lpPathName);
+ WINBASEAPI DWORD WINAPI GetCurrentDirectoryA(DWORD nBufferLength,LPSTR lpBuffer);
+ WINBASEAPI DWORD WINAPI GetCurrentDirectoryW(DWORD nBufferLength,LPWSTR lpBuffer);
+ WINBASEAPI WINBOOL WINAPI SetDllDirectoryA(LPCSTR lpPathName);
+ WINBASEAPI WINBOOL WINAPI SetDllDirectoryW(LPCWSTR lpPathName);
+ WINBASEAPI DWORD WINAPI GetDllDirectoryA(DWORD nBufferLength,LPSTR lpBuffer);
+ WINBASEAPI DWORD WINAPI GetDllDirectoryW(DWORD nBufferLength,LPWSTR lpBuffer);
+ WINBASEAPI WINBOOL WINAPI GetDiskFreeSpaceA(LPCSTR lpRootPathName,LPDWORD lpSectorsPerCluster,LPDWORD lpBytesPerSector,LPDWORD lpNumberOfFreeClusters,LPDWORD lpTotalNumberOfClusters);
+ WINBASEAPI WINBOOL WINAPI GetDiskFreeSpaceW(LPCWSTR lpRootPathName,LPDWORD lpSectorsPerCluster,LPDWORD lpBytesPerSector,LPDWORD lpNumberOfFreeClusters,LPDWORD lpTotalNumberOfClusters);
+ WINBASEAPI WINBOOL WINAPI GetDiskFreeSpaceExA(LPCSTR lpDirectoryName,PULARGE_INTEGER lpFreeBytesAvailableToCaller,PULARGE_INTEGER lpTotalNumberOfBytes,PULARGE_INTEGER lpTotalNumberOfFreeBytes);
+ WINBASEAPI WINBOOL WINAPI GetDiskFreeSpaceExW(LPCWSTR lpDirectoryName,PULARGE_INTEGER lpFreeBytesAvailableToCaller,PULARGE_INTEGER lpTotalNumberOfBytes,PULARGE_INTEGER lpTotalNumberOfFreeBytes);
+ WINBASEAPI WINBOOL WINAPI CreateDirectoryA(LPCSTR lpPathName,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ WINBASEAPI WINBOOL WINAPI CreateDirectoryW(LPCWSTR lpPathName,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ WINBASEAPI WINBOOL WINAPI CreateDirectoryExA(LPCSTR lpTemplateDirectory,LPCSTR lpNewDirectory,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ WINBASEAPI WINBOOL WINAPI CreateDirectoryExW(LPCWSTR lpTemplateDirectory,LPCWSTR lpNewDirectory,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ WINBASEAPI WINBOOL WINAPI RemoveDirectoryA(LPCSTR lpPathName);
+ WINBASEAPI WINBOOL WINAPI RemoveDirectoryW(LPCWSTR lpPathName);
+ WINBASEAPI DWORD WINAPI GetFullPathNameA(LPCSTR lpFileName,DWORD nBufferLength,LPSTR lpBuffer,LPSTR *lpFilePart);
+ WINBASEAPI DWORD WINAPI GetFullPathNameW(LPCWSTR lpFileName,DWORD nBufferLength,LPWSTR lpBuffer,LPWSTR *lpFilePart);
+
+#define DDD_RAW_TARGET_PATH 0x1
+#define DDD_REMOVE_DEFINITION 0x2
+#define DDD_EXACT_MATCH_ON_REMOVE 0x4
+#define DDD_NO_BROADCAST_SYSTEM 0x8
+#define DDD_LUID_BROADCAST_DRIVE 0x10
+
+ WINBASEAPI WINBOOL WINAPI DefineDosDeviceA(DWORD dwFlags,LPCSTR lpDeviceName,LPCSTR lpTargetPath);
+ WINBASEAPI WINBOOL WINAPI DefineDosDeviceW(DWORD dwFlags,LPCWSTR lpDeviceName,LPCWSTR lpTargetPath);
+ WINBASEAPI DWORD WINAPI QueryDosDeviceA(LPCSTR lpDeviceName,LPSTR lpTargetPath,DWORD ucchMax);
+ WINBASEAPI DWORD WINAPI QueryDosDeviceW(LPCWSTR lpDeviceName,LPWSTR lpTargetPath,DWORD ucchMax);
+
+#define EXPAND_LOCAL_DRIVES
+
+ WINBASEAPI HANDLE WINAPI CreateFileA(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);
+ WINBASEAPI HANDLE WINAPI CreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);
+ WINBASEAPI HANDLE WINAPI ReOpenFile(HANDLE hOriginalFile,DWORD dwDesiredAccess,DWORD dwShareMode,DWORD dwFlagsAndAttributes);
+ WINBASEAPI WINBOOL WINAPI SetFileAttributesA(LPCSTR lpFileName,DWORD dwFileAttributes);
+ WINBASEAPI WINBOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName,DWORD dwFileAttributes);
+ WINBASEAPI DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName);
+ WINBASEAPI DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName);
+
+ typedef enum _GET_FILEEX_INFO_LEVELS {
+ GetFileExInfoStandard,GetFileExMaxInfoLevel
+ } GET_FILEEX_INFO_LEVELS;
+
+#ifdef UNICODE
+#define GetFileAttributesEx GetFileAttributesExW
+#define GetCompressedFileSize GetCompressedFileSizeW
+#define DeleteFile DeleteFileW
+#define CheckNameLegalDOS8Dot3 CheckNameLegalDOS8Dot3W
+#else
+#define GetFileAttributesEx GetFileAttributesExA
+#define GetCompressedFileSize GetCompressedFileSizeA
+#define DeleteFile DeleteFileA
+#define CheckNameLegalDOS8Dot3 CheckNameLegalDOS8Dot3A
+#endif
+
+ WINBASEAPI WINBOOL WINAPI GetFileAttributesExA(LPCSTR lpFileName,GET_FILEEX_INFO_LEVELS fInfoLevelId,LPVOID lpFileInformation);
+ WINBASEAPI WINBOOL WINAPI GetFileAttributesExW(LPCWSTR lpFileName,GET_FILEEX_INFO_LEVELS fInfoLevelId,LPVOID lpFileInformation);
+ WINBASEAPI DWORD WINAPI GetCompressedFileSizeA(LPCSTR lpFileName,LPDWORD lpFileSizeHigh);
+ WINBASEAPI DWORD WINAPI GetCompressedFileSizeW(LPCWSTR lpFileName,LPDWORD lpFileSizeHigh);
+ WINBASEAPI WINBOOL WINAPI DeleteFileA(LPCSTR lpFileName);
+ WINBASEAPI WINBOOL WINAPI DeleteFileW(LPCWSTR lpFileName);
+ WINBASEAPI WINBOOL WINAPI CheckNameLegalDOS8Dot3A(LPCSTR lpName,LPSTR lpOemName,DWORD OemNameSize,PBOOL pbNameContainsSpaces,PBOOL pbNameLegal);
+ WINBASEAPI WINBOOL WINAPI CheckNameLegalDOS8Dot3W(LPCWSTR lpName,LPSTR lpOemName,DWORD OemNameSize,PBOOL pbNameContainsSpaces,PBOOL pbNameLegal);
+
+ typedef enum _FINDEX_INFO_LEVELS {
+ FindExInfoStandard,FindExInfoMaxInfoLevel
+ } FINDEX_INFO_LEVELS;
+
+ typedef enum _FINDEX_SEARCH_OPS {
+ FindExSearchNameMatch,FindExSearchLimitToDirectories,FindExSearchLimitToDevices,FindExSearchMaxSearchOp
+ } FINDEX_SEARCH_OPS;
+
+#define FIND_FIRST_EX_CASE_SENSITIVE 0x1
+
+#ifdef UNICODE
+#define FindFirstFileEx FindFirstFileExW
+#define FindFirstFile FindFirstFileW
+#define FindNextFile FindNextFileW
+#define SearchPath SearchPathW
+#define CopyFile CopyFileW
+#define CopyFileEx CopyFileExW
+#define MoveFile MoveFileW
+#define MoveFileEx MoveFileExW
+#define MoveFileWithProgress MoveFileWithProgressW
+#define ReplaceFile ReplaceFileW
+#define CreateHardLink CreateHardLinkW
+#define CreateNamedPipe CreateNamedPipeW
+#define GetNamedPipeHandleState GetNamedPipeHandleStateW
+#define CallNamedPipe CallNamedPipeW
+#define WaitNamedPipe WaitNamedPipeW
+#define SetVolumeLabel SetVolumeLabelW
+#define GetVolumeInformation GetVolumeInformationW
+#define ClearEventLog ClearEventLogW
+#define BackupEventLog BackupEventLogW
+#define OpenEventLog OpenEventLogW
+#define RegisterEventSource RegisterEventSourceW
+#define OpenBackupEventLog OpenBackupEventLogW
+#define ReadEventLog ReadEventLogW
+#define ReportEvent ReportEventW
+#define AccessCheckAndAuditAlarm AccessCheckAndAuditAlarmW
+#define AccessCheckByTypeAndAuditAlarm AccessCheckByTypeAndAuditAlarmW
+#define AccessCheckByTypeResultListAndAuditAlarm AccessCheckByTypeResultListAndAuditAlarmW
+#define AccessCheckByTypeResultListAndAuditAlarmByHandle AccessCheckByTypeResultListAndAuditAlarmByHandleW
+#define ObjectOpenAuditAlarm ObjectOpenAuditAlarmW
+#define ObjectPrivilegeAuditAlarm ObjectPrivilegeAuditAlarmW
+#define ObjectCloseAuditAlarm ObjectCloseAuditAlarmW
+#define ObjectDeleteAuditAlarm ObjectDeleteAuditAlarmW
+#define PrivilegedServiceAuditAlarm PrivilegedServiceAuditAlarmW
+#define SetFileSecurity SetFileSecurityW
+#define GetFileSecurity GetFileSecurityW
+#define FindFirstChangeNotification FindFirstChangeNotificationW
+#define IsBadStringPtr IsBadStringPtrW
+#define LookupAccountSid LookupAccountSidW
+#define LookupAccountName LookupAccountNameW
+#define LookupPrivilegeValue LookupPrivilegeValueW
+#define LookupPrivilegeName LookupPrivilegeNameW
+#define LookupPrivilegeDisplayName LookupPrivilegeDisplayNameW
+#define BuildCommDCB BuildCommDCBW
+#define BuildCommDCBAndTimeouts BuildCommDCBAndTimeoutsW
+#define CommConfigDialog CommConfigDialogW
+#define GetDefaultCommConfig GetDefaultCommConfigW
+#define SetDefaultCommConfig SetDefaultCommConfigW
+#define GetComputerName GetComputerNameW
+#define SetComputerName SetComputerNameW
+#define GetComputerNameEx GetComputerNameExW
+#define SetComputerNameEx SetComputerNameExW
+#define DnsHostnameToComputerName DnsHostnameToComputerNameW
+#define GetUserName GetUserNameW
+#else
+#define FindFirstFileEx FindFirstFileExA
+#define FindFirstFile FindFirstFileA
+#define FindNextFile FindNextFileA
+#define SearchPath SearchPathA
+#define CopyFile CopyFileA
+#define CopyFileEx CopyFileExA
+#define MoveFile MoveFileA
+#define MoveFileEx MoveFileExA
+#define MoveFileWithProgress MoveFileWithProgressA
+#define ReplaceFile ReplaceFileA
+#define CreateHardLink CreateHardLinkA
+#define CreateNamedPipe CreateNamedPipeA
+#define GetNamedPipeHandleState GetNamedPipeHandleStateA
+#define CallNamedPipe CallNamedPipeA
+#define WaitNamedPipe WaitNamedPipeA
+#define SetVolumeLabel SetVolumeLabelA
+#define GetVolumeInformation GetVolumeInformationA
+#define ClearEventLog ClearEventLogA
+#define BackupEventLog BackupEventLogA
+#define OpenEventLog OpenEventLogA
+#define RegisterEventSource RegisterEventSourceA
+#define OpenBackupEventLog OpenBackupEventLogA
+#define ReadEventLog ReadEventLogA
+#define ReportEvent ReportEventA
+#define AccessCheckAndAuditAlarm AccessCheckAndAuditAlarmA
+#define AccessCheckByTypeAndAuditAlarm AccessCheckByTypeAndAuditAlarmA
+#define AccessCheckByTypeResultListAndAuditAlarm AccessCheckByTypeResultListAndAuditAlarmA
+#define AccessCheckByTypeResultListAndAuditAlarmByHandle AccessCheckByTypeResultListAndAuditAlarmByHandleA
+#define ObjectOpenAuditAlarm ObjectOpenAuditAlarmA
+#define ObjectPrivilegeAuditAlarm ObjectPrivilegeAuditAlarmA
+#define ObjectCloseAuditAlarm ObjectCloseAuditAlarmA
+#define ObjectDeleteAuditAlarm ObjectDeleteAuditAlarmA
+#define PrivilegedServiceAuditAlarm PrivilegedServiceAuditAlarmA
+#define SetFileSecurity SetFileSecurityA
+#define GetFileSecurity GetFileSecurityA
+#define FindFirstChangeNotification FindFirstChangeNotificationA
+#define IsBadStringPtr IsBadStringPtrA
+#define LookupAccountSid LookupAccountSidA
+#define LookupAccountName LookupAccountNameA
+#define LookupPrivilegeValue LookupPrivilegeValueA
+#define LookupPrivilegeName LookupPrivilegeNameA
+#define LookupPrivilegeDisplayName LookupPrivilegeDisplayNameA
+#define BuildCommDCB BuildCommDCBA
+#define BuildCommDCBAndTimeouts BuildCommDCBAndTimeoutsA
+#define CommConfigDialog CommConfigDialogA
+#define GetDefaultCommConfig GetDefaultCommConfigA
+#define SetDefaultCommConfig SetDefaultCommConfigA
+#define GetComputerName GetComputerNameA
+#define SetComputerName SetComputerNameA
+#define GetComputerNameEx GetComputerNameExA
+#define SetComputerNameEx SetComputerNameExA
+#define DnsHostnameToComputerName DnsHostnameToComputerNameA
+#define GetUserName GetUserNameA
+#endif
+
+ WINBASEAPI HANDLE WINAPI FindFirstFileExA(LPCSTR lpFileName,FINDEX_INFO_LEVELS fInfoLevelId,LPVOID lpFindFileData,FINDEX_SEARCH_OPS fSearchOp,LPVOID lpSearchFilter,DWORD dwAdditionalFlags);
+ WINBASEAPI HANDLE WINAPI FindFirstFileExW(LPCWSTR lpFileName,FINDEX_INFO_LEVELS fInfoLevelId,LPVOID lpFindFileData,FINDEX_SEARCH_OPS fSearchOp,LPVOID lpSearchFilter,DWORD dwAdditionalFlags);
+ WINBASEAPI HANDLE WINAPI FindFirstFileA(LPCSTR lpFileName,LPWIN32_FIND_DATAA lpFindFileData);
+ WINBASEAPI HANDLE WINAPI FindFirstFileW(LPCWSTR lpFileName,LPWIN32_FIND_DATAW lpFindFileData);
+ WINBASEAPI WINBOOL WINAPI FindNextFileA(HANDLE hFindFile,LPWIN32_FIND_DATAA lpFindFileData);
+ WINBASEAPI WINBOOL WINAPI FindNextFileW(HANDLE hFindFile,LPWIN32_FIND_DATAW lpFindFileData);
+ WINBASEAPI DWORD WINAPI SearchPathA(LPCSTR lpPath,LPCSTR lpFileName,LPCSTR lpExtension,DWORD nBufferLength,LPSTR lpBuffer,LPSTR *lpFilePart);
+ WINBASEAPI DWORD WINAPI SearchPathW(LPCWSTR lpPath,LPCWSTR lpFileName,LPCWSTR lpExtension,DWORD nBufferLength,LPWSTR lpBuffer,LPWSTR *lpFilePart);
+ WINBASEAPI WINBOOL WINAPI CopyFileA(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,WINBOOL bFailIfExists);
+ WINBASEAPI WINBOOL WINAPI CopyFileW(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName,WINBOOL bFailIfExists);
+
+ typedef DWORD (WINAPI *LPPROGRESS_ROUTINE)(LARGE_INTEGER TotalFileSize,LARGE_INTEGER TotalBytesTransferred,LARGE_INTEGER StreamSize,LARGE_INTEGER StreamBytesTransferred,DWORD dwStreamNumber,DWORD dwCallbackReason,HANDLE hSourceFile,HANDLE hDestinationFile,LPVOID lpData);
+
+ WINBASEAPI WINBOOL WINAPI CopyFileExA(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,LPPROGRESS_ROUTINE lpProgressRoutine,LPVOID lpData,LPBOOL pbCancel,DWORD dwCopyFlags);
+ WINBASEAPI WINBOOL WINAPI CopyFileExW(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName,LPPROGRESS_ROUTINE lpProgressRoutine,LPVOID lpData,LPBOOL pbCancel,DWORD dwCopyFlags);
+ WINBASEAPI WINBOOL WINAPI MoveFileA(LPCSTR lpExistingFileName,LPCSTR lpNewFileName);
+ WINBASEAPI WINBOOL WINAPI MoveFileW(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName);
+ WINBASEAPI WINBOOL WINAPI MoveFileExA(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,DWORD dwFlags);
+ WINBASEAPI WINBOOL WINAPI MoveFileExW(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName,DWORD dwFlags);
+ WINBASEAPI WINBOOL WINAPI MoveFileWithProgressA(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,LPPROGRESS_ROUTINE lpProgressRoutine,LPVOID lpData,DWORD dwFlags);
+ WINBASEAPI WINBOOL WINAPI MoveFileWithProgressW(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName,LPPROGRESS_ROUTINE lpProgressRoutine,LPVOID lpData,DWORD dwFlags);
+
+#define MOVEFILE_REPLACE_EXISTING 0x1
+#define MOVEFILE_COPY_ALLOWED 0x2
+#define MOVEFILE_DELAY_UNTIL_REBOOT 0x4
+#define MOVEFILE_WRITE_THROUGH 0x8
+#define MOVEFILE_CREATE_HARDLINK 0x10
+#define MOVEFILE_FAIL_IF_NOT_TRACKABLE 0x20
+
+ WINBASEAPI WINBOOL WINAPI ReplaceFileA(LPCSTR lpReplacedFileName,LPCSTR lpReplacementFileName,LPCSTR lpBackupFileName,DWORD dwReplaceFlags,LPVOID lpExclude,LPVOID lpReserved);
+ WINBASEAPI WINBOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName,LPCWSTR lpReplacementFileName,LPCWSTR lpBackupFileName,DWORD dwReplaceFlags,LPVOID lpExclude,LPVOID lpReserved);
+ WINBASEAPI WINBOOL WINAPI CreateHardLinkA(LPCSTR lpFileName,LPCSTR lpExistingFileName,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ WINBASEAPI WINBOOL WINAPI CreateHardLinkW(LPCWSTR lpFileName,LPCWSTR lpExistingFileName,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+
+ typedef enum _STREAM_INFO_LEVELS {
+ FindStreamInfoStandard,FindStreamInfoMaxInfoLevel
+ } STREAM_INFO_LEVELS;
+
+ typedef struct _WIN32_FIND_STREAM_DATA {
+ LARGE_INTEGER StreamSize;
+ WCHAR cStreamName[MAX_PATH + 36];
+ } WIN32_FIND_STREAM_DATA,*PWIN32_FIND_STREAM_DATA;
+
+ HANDLE WINAPI FindFirstStreamW(LPCWSTR lpFileName,STREAM_INFO_LEVELS InfoLevel,LPVOID lpFindStreamData,DWORD dwFlags);
+ WINBOOL WINAPI FindNextStreamW(HANDLE hFindStream,LPVOID lpFindStreamData);
+ WINBASEAPI HANDLE WINAPI CreateNamedPipeA(LPCSTR lpName,DWORD dwOpenMode,DWORD dwPipeMode,DWORD nMaxInstances,DWORD nOutBufferSize,DWORD nInBufferSize,DWORD nDefaultTimeOut,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ WINBASEAPI HANDLE WINAPI CreateNamedPipeW(LPCWSTR lpName,DWORD dwOpenMode,DWORD dwPipeMode,DWORD nMaxInstances,DWORD nOutBufferSize,DWORD nInBufferSize,DWORD nDefaultTimeOut,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ WINBASEAPI WINBOOL WINAPI GetNamedPipeHandleStateA(HANDLE hNamedPipe,LPDWORD lpState,LPDWORD lpCurInstances,LPDWORD lpMaxCollectionCount,LPDWORD lpCollectDataTimeout,LPSTR lpUserName,DWORD nMaxUserNameSize);
+ WINBASEAPI WINBOOL WINAPI GetNamedPipeHandleStateW(HANDLE hNamedPipe,LPDWORD lpState,LPDWORD lpCurInstances,LPDWORD lpMaxCollectionCount,LPDWORD lpCollectDataTimeout,LPWSTR lpUserName,DWORD nMaxUserNameSize);
+ WINBASEAPI WINBOOL WINAPI CallNamedPipeA(LPCSTR lpNamedPipeName,LPVOID lpInBuffer,DWORD nInBufferSize,LPVOID lpOutBuffer,DWORD nOutBufferSize,LPDWORD lpBytesRead,DWORD nTimeOut);
+ WINBASEAPI WINBOOL WINAPI CallNamedPipeW(LPCWSTR lpNamedPipeName,LPVOID lpInBuffer,DWORD nInBufferSize,LPVOID lpOutBuffer,DWORD nOutBufferSize,LPDWORD lpBytesRead,DWORD nTimeOut);
+ WINBASEAPI WINBOOL WINAPI WaitNamedPipeA(LPCSTR lpNamedPipeName,DWORD nTimeOut);
+ WINBASEAPI WINBOOL WINAPI WaitNamedPipeW(LPCWSTR lpNamedPipeName,DWORD nTimeOut);
+ WINBASEAPI WINBOOL WINAPI SetVolumeLabelA(LPCSTR lpRootPathName,LPCSTR lpVolumeName);
+ WINBASEAPI WINBOOL WINAPI SetVolumeLabelW(LPCWSTR lpRootPathName,LPCWSTR lpVolumeName);
+ WINBASEAPI VOID WINAPI SetFileApisToOEM(VOID);
+ WINBASEAPI VOID WINAPI SetFileApisToANSI(VOID);
+ WINBASEAPI WINBOOL WINAPI AreFileApisANSI(VOID);
+ WINBASEAPI WINBOOL WINAPI GetVolumeInformationA(LPCSTR lpRootPathName,LPSTR lpVolumeNameBuffer,DWORD nVolumeNameSize,LPDWORD lpVolumeSerialNumber,LPDWORD lpMaximumComponentLength,LPDWORD lpFileSystemFlags,LPSTR lpFileSystemNameBuffer,DWORD nFileSystemNameSize);
+ WINBASEAPI WINBOOL WINAPI GetVolumeInformationW(LPCWSTR lpRootPathName,LPWSTR lpVolumeNameBuffer,DWORD nVolumeNameSize,LPDWORD lpVolumeSerialNumber,LPDWORD lpMaximumComponentLength,LPDWORD lpFileSystemFlags,LPWSTR lpFileSystemNameBuffer,DWORD nFileSystemNameSize);
+ WINBASEAPI WINBOOL WINAPI CancelIo(HANDLE hFile);
+ WINADVAPI WINBOOL WINAPI ClearEventLogA(HANDLE hEventLog,LPCSTR lpBackupFileName);
+ WINADVAPI WINBOOL WINAPI ClearEventLogW(HANDLE hEventLog,LPCWSTR lpBackupFileName);
+ WINADVAPI WINBOOL WINAPI BackupEventLogA(HANDLE hEventLog,LPCSTR lpBackupFileName);
+ WINADVAPI WINBOOL WINAPI BackupEventLogW(HANDLE hEventLog,LPCWSTR lpBackupFileName);
+ WINADVAPI WINBOOL WINAPI CloseEventLog(HANDLE hEventLog);
+ WINADVAPI WINBOOL WINAPI DeregisterEventSource(HANDLE hEventLog);
+ WINADVAPI WINBOOL WINAPI NotifyChangeEventLog(HANDLE hEventLog,HANDLE hEvent);
+ WINADVAPI WINBOOL WINAPI GetNumberOfEventLogRecords(HANDLE hEventLog,PDWORD NumberOfRecords);
+ WINADVAPI WINBOOL WINAPI GetOldestEventLogRecord(HANDLE hEventLog,PDWORD OldestRecord);
+ WINADVAPI HANDLE WINAPI OpenEventLogA(LPCSTR lpUNCServerName,LPCSTR lpSourceName);
+ WINADVAPI HANDLE WINAPI OpenEventLogW(LPCWSTR lpUNCServerName,LPCWSTR lpSourceName);
+ WINADVAPI HANDLE WINAPI RegisterEventSourceA(LPCSTR lpUNCServerName,LPCSTR lpSourceName);
+ WINADVAPI HANDLE WINAPI RegisterEventSourceW(LPCWSTR lpUNCServerName,LPCWSTR lpSourceName);
+ WINADVAPI HANDLE WINAPI OpenBackupEventLogA(LPCSTR lpUNCServerName,LPCSTR lpFileName);
+ WINADVAPI HANDLE WINAPI OpenBackupEventLogW(LPCWSTR lpUNCServerName,LPCWSTR lpFileName);
+ WINADVAPI WINBOOL WINAPI ReadEventLogA(HANDLE hEventLog,DWORD dwReadFlags,DWORD dwRecordOffset,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,DWORD *pnBytesRead,DWORD *pnMinNumberOfBytesNeeded);
+ WINADVAPI WINBOOL WINAPI ReadEventLogW(HANDLE hEventLog,DWORD dwReadFlags,DWORD dwRecordOffset,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,DWORD *pnBytesRead,DWORD *pnMinNumberOfBytesNeeded);
+ WINADVAPI WINBOOL WINAPI ReportEventA(HANDLE hEventLog,WORD wType,WORD wCategory,DWORD dwEventID,PSID lpUserSid,WORD wNumStrings,DWORD dwDataSize,LPCSTR *lpStrings,LPVOID lpRawData);
+ WINADVAPI WINBOOL WINAPI ReportEventW(HANDLE hEventLog,WORD wType,WORD wCategory,DWORD dwEventID,PSID lpUserSid,WORD wNumStrings,DWORD dwDataSize,LPCWSTR *lpStrings,LPVOID lpRawData);
+
+#define EVENTLOG_FULL_INFO 0
+
+ typedef struct _EVENTLOG_FULL_INFORMATION {
+ DWORD dwFull;
+ } EVENTLOG_FULL_INFORMATION,*LPEVENTLOG_FULL_INFORMATION;
+
+ WINADVAPI WINBOOL WINAPI GetEventLogInformation(HANDLE hEventLog,DWORD dwInfoLevel,LPVOID lpBuffer,DWORD cbBufSize,LPDWORD pcbBytesNeeded);
+ WINADVAPI WINBOOL WINAPI DuplicateToken(HANDLE ExistingTokenHandle,SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,PHANDLE DuplicateTokenHandle);
+ WINADVAPI WINBOOL WINAPI GetKernelObjectSecurity(HANDLE Handle,SECURITY_INFORMATION RequestedInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor,DWORD nLength,LPDWORD lpnLengthNeeded);
+ WINADVAPI WINBOOL WINAPI ImpersonateNamedPipeClient(HANDLE hNamedPipe);
+ WINADVAPI WINBOOL WINAPI ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel);
+ WINADVAPI WINBOOL WINAPI RevertToSelf(VOID);
+ WINADVAPI WINBOOL WINAPI SetThreadToken (PHANDLE Thread,HANDLE Token);
+ WINADVAPI WINBOOL WINAPI AccessCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,HANDLE ClientToken,DWORD DesiredAccess,PGENERIC_MAPPING GenericMapping,PPRIVILEGE_SET PrivilegeSet,LPDWORD PrivilegeSetLength,LPDWORD GrantedAccess,LPBOOL AccessStatus);
+ WINADVAPI WINBOOL WINAPI AccessCheckByType(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID PrincipalSelfSid,HANDLE ClientToken,DWORD DesiredAccess,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,PPRIVILEGE_SET PrivilegeSet,LPDWORD PrivilegeSetLength,LPDWORD GrantedAccess,LPBOOL AccessStatus);
+ WINADVAPI WINBOOL WINAPI AccessCheckByTypeResultList(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID PrincipalSelfSid,HANDLE ClientToken,DWORD DesiredAccess,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,PPRIVILEGE_SET PrivilegeSet,LPDWORD PrivilegeSetLength,LPDWORD GrantedAccessList,LPDWORD AccessStatusList);
+ WINADVAPI WINBOOL WINAPI OpenProcessToken(HANDLE ProcessHandle,DWORD DesiredAccess,PHANDLE TokenHandle);
+ WINADVAPI WINBOOL WINAPI OpenThreadToken(HANDLE ThreadHandle,DWORD DesiredAccess,WINBOOL OpenAsSelf,PHANDLE TokenHandle);
+ WINADVAPI WINBOOL WINAPI GetTokenInformation(HANDLE TokenHandle,TOKEN_INFORMATION_CLASS TokenInformationClass,LPVOID TokenInformation,DWORD TokenInformationLength,PDWORD ReturnLength);
+ WINADVAPI WINBOOL WINAPI SetTokenInformation(HANDLE TokenHandle,TOKEN_INFORMATION_CLASS TokenInformationClass,LPVOID TokenInformation,DWORD TokenInformationLength);
+ WINADVAPI WINBOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle,WINBOOL DisableAllPrivileges,PTOKEN_PRIVILEGES NewState,DWORD BufferLength,PTOKEN_PRIVILEGES PreviousState,PDWORD ReturnLength);
+ WINADVAPI WINBOOL WINAPI AdjustTokenGroups(HANDLE TokenHandle,WINBOOL ResetToDefault,PTOKEN_GROUPS NewState,DWORD BufferLength,PTOKEN_GROUPS PreviousState,PDWORD ReturnLength);
+ WINADVAPI WINBOOL WINAPI PrivilegeCheck(HANDLE ClientToken,PPRIVILEGE_SET RequiredPrivileges,LPBOOL pfResult);
+ WINADVAPI WINBOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,LPSTR ObjectTypeName,LPSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,DWORD DesiredAccess,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPBOOL AccessStatus,LPBOOL pfGenerateOnClose);
+ WINADVAPI WINBOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,LPWSTR ObjectTypeName,LPWSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,DWORD DesiredAccess,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPBOOL AccessStatus,LPBOOL pfGenerateOnClose);
+ WINADVAPI WINBOOL WINAPI AccessCheckByTypeAndAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,LPCSTR ObjectTypeName,LPCSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPBOOL AccessStatus,LPBOOL pfGenerateOnClose);
+ WINADVAPI WINBOOL WINAPI AccessCheckByTypeAndAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,LPCWSTR ObjectTypeName,LPCWSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPBOOL AccessStatus,LPBOOL pfGenerateOnClose);
+ WINADVAPI WINBOOL WINAPI AccessCheckByTypeResultListAndAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,LPCSTR ObjectTypeName,LPCSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPDWORD AccessStatusList,LPBOOL pfGenerateOnClose);
+ WINADVAPI WINBOOL WINAPI AccessCheckByTypeResultListAndAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,LPCWSTR ObjectTypeName,LPCWSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPDWORD AccessStatusList,LPBOOL pfGenerateOnClose);
+ WINADVAPI WINBOOL WINAPI AccessCheckByTypeResultListAndAuditAlarmByHandleA(LPCSTR SubsystemName,LPVOID HandleId,HANDLE ClientToken,LPCSTR ObjectTypeName,LPCSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPDWORD AccessStatusList,LPBOOL pfGenerateOnClose);
+ WINADVAPI WINBOOL WINAPI AccessCheckByTypeResultListAndAuditAlarmByHandleW(LPCWSTR SubsystemName,LPVOID HandleId,HANDLE ClientToken,LPCWSTR ObjectTypeName,LPCWSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPDWORD AccessStatusList,LPBOOL pfGenerateOnClose);
+ WINADVAPI WINBOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,LPSTR ObjectTypeName,LPSTR ObjectName,PSECURITY_DESCRIPTOR pSecurityDescriptor,HANDLE ClientToken,DWORD DesiredAccess,DWORD GrantedAccess,PPRIVILEGE_SET Privileges,WINBOOL ObjectCreation,WINBOOL AccessGranted,LPBOOL GenerateOnClose);
+ WINADVAPI WINBOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,LPWSTR ObjectTypeName,LPWSTR ObjectName,PSECURITY_DESCRIPTOR pSecurityDescriptor,HANDLE ClientToken,DWORD DesiredAccess,DWORD GrantedAccess,PPRIVILEGE_SET Privileges,WINBOOL ObjectCreation,WINBOOL AccessGranted,LPBOOL GenerateOnClose);
+ WINADVAPI WINBOOL WINAPI ObjectPrivilegeAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,HANDLE ClientToken,DWORD DesiredAccess,PPRIVILEGE_SET Privileges,WINBOOL AccessGranted);
+ WINADVAPI WINBOOL WINAPI ObjectPrivilegeAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,HANDLE ClientToken,DWORD DesiredAccess,PPRIVILEGE_SET Privileges,WINBOOL AccessGranted);
+ WINADVAPI WINBOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,WINBOOL GenerateOnClose);
+ WINADVAPI WINBOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,WINBOOL GenerateOnClose);
+ WINADVAPI WINBOOL WINAPI ObjectDeleteAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,WINBOOL GenerateOnClose);
+ WINADVAPI WINBOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,WINBOOL GenerateOnClose);
+ WINADVAPI WINBOOL WINAPI PrivilegedServiceAuditAlarmA(LPCSTR SubsystemName,LPCSTR ServiceName,HANDLE ClientToken,PPRIVILEGE_SET Privileges,WINBOOL AccessGranted);
+ WINADVAPI WINBOOL WINAPI PrivilegedServiceAuditAlarmW(LPCWSTR SubsystemName,LPCWSTR ServiceName,HANDLE ClientToken,PPRIVILEGE_SET Privileges,WINBOOL AccessGranted);
+ WINADVAPI WINBOOL WINAPI IsWellKnownSid(PSID pSid,WELL_KNOWN_SID_TYPE WellKnownSidType);
+ WINADVAPI WINBOOL WINAPI CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType,PSID DomainSid,PSID pSid,DWORD *cbSid);
+ WINADVAPI WINBOOL WINAPI EqualDomainSid(PSID pSid1,PSID pSid2,WINBOOL *pfEqual);
+ WINADVAPI WINBOOL WINAPI GetWindowsAccountDomainSid(PSID pSid,PSID pDomainSid,DWORD *cbDomainSid);
+ WINADVAPI WINBOOL WINAPI IsValidSid(PSID pSid);
+ WINADVAPI WINBOOL WINAPI EqualSid(PSID pSid1,PSID pSid2);
+ WINADVAPI WINBOOL WINAPI EqualPrefixSid(PSID pSid1,PSID pSid2);
+ WINADVAPI DWORD WINAPI GetSidLengthRequired (UCHAR nSubAuthorityCount);
+ WINADVAPI WINBOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,BYTE nSubAuthorityCount,DWORD nSubAuthority0,DWORD nSubAuthority1,DWORD nSubAuthority2,DWORD nSubAuthority3,DWORD nSubAuthority4,DWORD nSubAuthority5,DWORD nSubAuthority6,DWORD nSubAuthority7,PSID *pSid);
+ WINADVAPI PVOID WINAPI FreeSid(PSID pSid);
+ WINADVAPI WINBOOL WINAPI InitializeSid(PSID Sid,PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,BYTE nSubAuthorityCount);
+ WINADVAPI PSID_IDENTIFIER_AUTHORITY WINAPI GetSidIdentifierAuthority(PSID pSid);
+ WINADVAPI PDWORD WINAPI GetSidSubAuthority(PSID pSid,DWORD nSubAuthority);
+ WINADVAPI PUCHAR WINAPI GetSidSubAuthorityCount(PSID pSid);
+ WINADVAPI DWORD WINAPI GetLengthSid(PSID pSid);
+ WINADVAPI WINBOOL WINAPI CopySid(DWORD nDestinationSidLength,PSID pDestinationSid,PSID pSourceSid);
+ WINADVAPI WINBOOL WINAPI AreAllAccessesGranted(DWORD GrantedAccess,DWORD DesiredAccess);
+ WINADVAPI WINBOOL WINAPI AreAnyAccessesGranted(DWORD GrantedAccess,DWORD DesiredAccess);
+ WINADVAPI VOID WINAPI MapGenericMask(PDWORD AccessMask,PGENERIC_MAPPING GenericMapping);
+ WINADVAPI WINBOOL WINAPI IsValidAcl(PACL pAcl);
+ WINADVAPI WINBOOL WINAPI InitializeAcl(PACL pAcl,DWORD nAclLength,DWORD dwAclRevision);
+ WINADVAPI WINBOOL WINAPI GetAclInformation(PACL pAcl,LPVOID pAclInformation,DWORD nAclInformationLength,ACL_INFORMATION_CLASS dwAclInformationClass);
+ WINADVAPI WINBOOL WINAPI SetAclInformation(PACL pAcl,LPVOID pAclInformation,DWORD nAclInformationLength,ACL_INFORMATION_CLASS dwAclInformationClass);
+ WINADVAPI WINBOOL WINAPI AddAce(PACL pAcl,DWORD dwAceRevision,DWORD dwStartingAceIndex,LPVOID pAceList,DWORD nAceListLength);
+ WINADVAPI WINBOOL WINAPI DeleteAce(PACL pAcl,DWORD dwAceIndex);
+ WINADVAPI WINBOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce);
+ WINADVAPI WINBOOL WINAPI AddAccessAllowedAce(PACL pAcl,DWORD dwAceRevision,DWORD AccessMask,PSID pSid);
+ WINADVAPI WINBOOL WINAPI AddAccessAllowedAceEx(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD AccessMask,PSID pSid);
+ WINADVAPI WINBOOL WINAPI AddAccessDeniedAce(PACL pAcl,DWORD dwAceRevision,DWORD AccessMask,PSID pSid);
+ WINADVAPI WINBOOL WINAPI AddAccessDeniedAceEx(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD AccessMask,PSID pSid);
+ WINADVAPI WINBOOL WINAPI AddAuditAccessAce(PACL pAcl,DWORD dwAceRevision,DWORD dwAccessMask,PSID pSid,WINBOOL bAuditSuccess,WINBOOL bAuditFailure);
+ WINADVAPI WINBOOL WINAPI AddAuditAccessAceEx(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD dwAccessMask,PSID pSid,WINBOOL bAuditSuccess,WINBOOL bAuditFailure);
+ WINADVAPI WINBOOL WINAPI AddAccessAllowedObjectAce(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD AccessMask,GUID *ObjectTypeGuid,GUID *InheritedObjectTypeGuid,PSID pSid);
+ WINADVAPI WINBOOL WINAPI AddAccessDeniedObjectAce(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD AccessMask,GUID *ObjectTypeGuid,GUID *InheritedObjectTypeGuid,PSID pSid);
+ WINADVAPI WINBOOL WINAPI AddAuditAccessObjectAce(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD AccessMask,GUID *ObjectTypeGuid,GUID *InheritedObjectTypeGuid,PSID pSid,WINBOOL bAuditSuccess,WINBOOL bAuditFailure);
+ WINADVAPI WINBOOL WINAPI FindFirstFreeAce(PACL pAcl,LPVOID *pAce);
+ WINADVAPI WINBOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor,DWORD dwRevision);
+ WINADVAPI WINBOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor);
+ WINADVAPI DWORD WINAPI GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR pSecurityDescriptor);
+ WINADVAPI WINBOOL WINAPI GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSECURITY_DESCRIPTOR_CONTROL pControl,LPDWORD lpdwRevision);
+ WINADVAPI WINBOOL WINAPI SetSecurityDescriptorControl(PSECURITY_DESCRIPTOR pSecurityDescriptor,SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet);
+ WINADVAPI WINBOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor,WINBOOL bDaclPresent,PACL pDacl,WINBOOL bDaclDefaulted);
+ WINADVAPI WINBOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor,LPBOOL lpbDaclPresent,PACL *pDacl,LPBOOL lpbDaclDefaulted);
+ WINADVAPI WINBOOL WINAPI SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR pSecurityDescriptor,WINBOOL bSaclPresent,PACL pSacl,WINBOOL bSaclDefaulted);
+ WINADVAPI WINBOOL WINAPI GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR pSecurityDescriptor,LPBOOL lpbSaclPresent,PACL *pSacl,LPBOOL lpbSaclDefaulted);
+ WINADVAPI WINBOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID pOwner,WINBOOL bOwnerDefaulted);
+ WINADVAPI WINBOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID *pOwner,LPBOOL lpbOwnerDefaulted);
+ WINADVAPI WINBOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID pGroup,WINBOOL bGroupDefaulted);
+ WINADVAPI WINBOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID *pGroup,LPBOOL lpbGroupDefaulted);
+ WINADVAPI DWORD WINAPI SetSecurityDescriptorRMControl(PSECURITY_DESCRIPTOR SecurityDescriptor,PUCHAR RMControl);
+ WINADVAPI DWORD WINAPI GetSecurityDescriptorRMControl(PSECURITY_DESCRIPTOR SecurityDescriptor,PUCHAR RMControl);
+ WINADVAPI WINBOOL WINAPI CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,PSECURITY_DESCRIPTOR CreatorDescriptor,PSECURITY_DESCRIPTOR *NewDescriptor,WINBOOL IsDirectoryObject,HANDLE Token,PGENERIC_MAPPING GenericMapping);
+ WINADVAPI WINBOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,PSECURITY_DESCRIPTOR CurrentSecurityDescriptor,PSECURITY_DESCRIPTOR *NewSecurityDescriptor,GUID *ObjectType,BOOLEAN IsDirectoryObject,PGENERIC_MAPPING GenericMapping);
+ WINADVAPI WINBOOL WINAPI CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,PSECURITY_DESCRIPTOR CreatorDescriptor,PSECURITY_DESCRIPTOR *NewDescriptor,GUID *ObjectType,WINBOOL IsContainerObject,ULONG AutoInheritFlags,HANDLE Token,PGENERIC_MAPPING GenericMapping);
+ WINADVAPI WINBOOL WINAPI CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,PSECURITY_DESCRIPTOR CreatorDescriptor,PSECURITY_DESCRIPTOR *NewDescriptor,GUID **ObjectTypes,ULONG GuidCount,WINBOOL IsContainerObject,ULONG AutoInheritFlags,HANDLE Token,PGENERIC_MAPPING GenericMapping);
+ WINADVAPI WINBOOL WINAPI SetPrivateObjectSecurity (SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR ModificationDescriptor,PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,PGENERIC_MAPPING GenericMapping,HANDLE Token);
+ WINADVAPI WINBOOL WINAPI SetPrivateObjectSecurityEx (SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR ModificationDescriptor,PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,ULONG AutoInheritFlags,PGENERIC_MAPPING GenericMapping,HANDLE Token);
+ WINADVAPI WINBOOL WINAPI GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR ResultantDescriptor,DWORD DescriptorLength,PDWORD ReturnLength);
+ WINADVAPI WINBOOL WINAPI DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor);
+ WINADVAPI WINBOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,LPDWORD lpdwBufferLength);
+ WINADVAPI WINBOOL WINAPI MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,LPDWORD lpdwAbsoluteSecurityDescriptorSize,PACL pDacl,LPDWORD lpdwDaclSize,PACL pSacl,LPDWORD lpdwSaclSize,PSID pOwner,LPDWORD lpdwOwnerSize,PSID pPrimaryGroup,LPDWORD lpdwPrimaryGroupSize);
+ WINADVAPI WINBOOL WINAPI MakeAbsoluteSD2(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,LPDWORD lpdwBufferSize);
+ WINADVAPI WINBOOL WINAPI SetFileSecurityA(LPCSTR lpFileName,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor);
+ WINADVAPI WINBOOL WINAPI SetFileSecurityW(LPCWSTR lpFileName,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor);
+ WINADVAPI WINBOOL WINAPI GetFileSecurityA(LPCSTR lpFileName,SECURITY_INFORMATION RequestedInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor,DWORD nLength,LPDWORD lpnLengthNeeded);
+ WINADVAPI WINBOOL WINAPI GetFileSecurityW(LPCWSTR lpFileName,SECURITY_INFORMATION RequestedInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor,DWORD nLength,LPDWORD lpnLengthNeeded);
+ WINADVAPI WINBOOL WINAPI SetKernelObjectSecurity(HANDLE Handle,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR SecurityDescriptor);
+ WINBASEAPI HANDLE WINAPI FindFirstChangeNotificationA(LPCSTR lpPathName,WINBOOL bWatchSubtree,DWORD dwNotifyFilter);
+ WINBASEAPI HANDLE WINAPI FindFirstChangeNotificationW(LPCWSTR lpPathName,WINBOOL bWatchSubtree,DWORD dwNotifyFilter);
+ WINBASEAPI WINBOOL WINAPI FindNextChangeNotification(HANDLE hChangeHandle);
+ WINBASEAPI WINBOOL WINAPI FindCloseChangeNotification(HANDLE hChangeHandle);
+ WINBASEAPI WINBOOL WINAPI ReadDirectoryChangesW(HANDLE hDirectory,LPVOID lpBuffer,DWORD nBufferLength,WINBOOL bWatchSubtree,DWORD dwNotifyFilter,LPDWORD lpBytesReturned,LPOVERLAPPED lpOverlapped,LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
+ WINBASEAPI WINBOOL WINAPI VirtualLock(LPVOID lpAddress,SIZE_T dwSize);
+ WINBASEAPI WINBOOL WINAPI VirtualUnlock(LPVOID lpAddress,SIZE_T dwSize);
+ WINBASEAPI LPVOID WINAPI MapViewOfFileEx(HANDLE hFileMappingObject,DWORD dwDesiredAccess,DWORD dwFileOffsetHigh,DWORD dwFileOffsetLow,SIZE_T dwNumberOfBytesToMap,LPVOID lpBaseAddress);
+ WINBASEAPI WINBOOL WINAPI SetPriorityClass(HANDLE hProcess,DWORD dwPriorityClass);
+ WINBASEAPI DWORD WINAPI GetPriorityClass(HANDLE hProcess);
+ WINBASEAPI WINBOOL WINAPI IsBadReadPtr(CONST VOID *lp,UINT_PTR ucb);
+ WINBASEAPI WINBOOL WINAPI IsBadWritePtr(LPVOID lp,UINT_PTR ucb);
+ WINBASEAPI WINBOOL WINAPI IsBadHugeReadPtr(CONST VOID *lp,UINT_PTR ucb);
+ WINBASEAPI WINBOOL WINAPI IsBadHugeWritePtr(LPVOID lp,UINT_PTR ucb);
+ WINBASEAPI WINBOOL WINAPI IsBadCodePtr(FARPROC lpfn);
+ WINBASEAPI WINBOOL WINAPI IsBadStringPtrA(LPCSTR lpsz,UINT_PTR ucchMax);
+ WINBASEAPI WINBOOL WINAPI IsBadStringPtrW(LPCWSTR lpsz,UINT_PTR ucchMax);
+ WINADVAPI WINBOOL WINAPI LookupAccountSidA(LPCSTR lpSystemName,PSID Sid,LPSTR Name,LPDWORD cchName,LPSTR ReferencedDomainName,LPDWORD cchReferencedDomainName,PSID_NAME_USE peUse);
+ WINADVAPI WINBOOL WINAPI LookupAccountSidW(LPCWSTR lpSystemName,PSID Sid,LPWSTR Name,LPDWORD cchName,LPWSTR ReferencedDomainName,LPDWORD cchReferencedDomainName,PSID_NAME_USE peUse);
+ WINADVAPI WINBOOL WINAPI LookupAccountNameA(LPCSTR lpSystemName,LPCSTR lpAccountName,PSID Sid,LPDWORD cbSid,LPSTR ReferencedDomainName,LPDWORD cchReferencedDomainName,PSID_NAME_USE peUse);
+ WINADVAPI WINBOOL WINAPI LookupAccountNameW(LPCWSTR lpSystemName,LPCWSTR lpAccountName,PSID Sid,LPDWORD cbSid,LPWSTR ReferencedDomainName,LPDWORD cchReferencedDomainName,PSID_NAME_USE peUse);
+ WINADVAPI WINBOOL WINAPI LookupPrivilegeValueA(LPCSTR lpSystemName,LPCSTR lpName,PLUID lpLuid);
+ WINADVAPI WINBOOL WINAPI LookupPrivilegeValueW(LPCWSTR lpSystemName,LPCWSTR lpName,PLUID lpLuid);
+ WINADVAPI WINBOOL WINAPI LookupPrivilegeNameA(LPCSTR lpSystemName,PLUID lpLuid,LPSTR lpName,LPDWORD cchName);
+ WINADVAPI WINBOOL WINAPI LookupPrivilegeNameW(LPCWSTR lpSystemName,PLUID lpLuid,LPWSTR lpName,LPDWORD cchName);
+ WINADVAPI WINBOOL WINAPI LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,LPCSTR lpName,LPSTR lpDisplayName,LPDWORD cchDisplayName,LPDWORD lpLanguageId);
+ WINADVAPI WINBOOL WINAPI LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,LPCWSTR lpName,LPWSTR lpDisplayName,LPDWORD cchDisplayName,LPDWORD lpLanguageId);
+ WINADVAPI WINBOOL WINAPI AllocateLocallyUniqueId(PLUID Luid);
+ WINBASEAPI WINBOOL WINAPI BuildCommDCBA(LPCSTR lpDef,LPDCB lpDCB);
+ WINBASEAPI WINBOOL WINAPI BuildCommDCBW(LPCWSTR lpDef,LPDCB lpDCB);
+ WINBASEAPI WINBOOL WINAPI BuildCommDCBAndTimeoutsA(LPCSTR lpDef,LPDCB lpDCB,LPCOMMTIMEOUTS lpCommTimeouts);
+ WINBASEAPI WINBOOL WINAPI BuildCommDCBAndTimeoutsW(LPCWSTR lpDef,LPDCB lpDCB,LPCOMMTIMEOUTS lpCommTimeouts);
+ WINBASEAPI WINBOOL WINAPI CommConfigDialogA(LPCSTR lpszName,HWND hWnd,LPCOMMCONFIG lpCC);
+ WINBASEAPI WINBOOL WINAPI CommConfigDialogW(LPCWSTR lpszName,HWND hWnd,LPCOMMCONFIG lpCC);
+ WINBASEAPI WINBOOL WINAPI GetDefaultCommConfigA(LPCSTR lpszName,LPCOMMCONFIG lpCC,LPDWORD lpdwSize);
+ WINBASEAPI WINBOOL WINAPI GetDefaultCommConfigW(LPCWSTR lpszName,LPCOMMCONFIG lpCC,LPDWORD lpdwSize);
+ WINBASEAPI WINBOOL WINAPI SetDefaultCommConfigA(LPCSTR lpszName,LPCOMMCONFIG lpCC,DWORD dwSize);
+ WINBASEAPI WINBOOL WINAPI SetDefaultCommConfigW(LPCWSTR lpszName,LPCOMMCONFIG lpCC,DWORD dwSize);
+
+#define MAX_COMPUTERNAME_LENGTH 15
+
+ WINBASEAPI WINBOOL WINAPI GetComputerNameA(LPSTR lpBuffer,LPDWORD nSize);
+ WINBASEAPI WINBOOL WINAPI GetComputerNameW(LPWSTR lpBuffer,LPDWORD nSize);
+ WINBASEAPI WINBOOL WINAPI SetComputerNameA(LPCSTR lpComputerName);
+ WINBASEAPI WINBOOL WINAPI SetComputerNameW(LPCWSTR lpComputerName);
+
+ typedef enum _COMPUTER_NAME_FORMAT {
+ ComputerNameNetBIOS,ComputerNameDnsHostname,ComputerNameDnsDomain,ComputerNameDnsFullyQualified,ComputerNamePhysicalNetBIOS,ComputerNamePhysicalDnsHostname,ComputerNamePhysicalDnsDomain,ComputerNamePhysicalDnsFullyQualified,ComputerNameMax
+ } COMPUTER_NAME_FORMAT;
+
+ WINBASEAPI WINBOOL WINAPI GetComputerNameExA(COMPUTER_NAME_FORMAT NameType,LPSTR lpBuffer,LPDWORD nSize);
+ WINBASEAPI WINBOOL WINAPI GetComputerNameExW(COMPUTER_NAME_FORMAT NameType,LPWSTR lpBuffer,LPDWORD nSize);
+ WINBASEAPI WINBOOL WINAPI SetComputerNameExA(COMPUTER_NAME_FORMAT NameType,LPCSTR lpBuffer);
+ WINBASEAPI WINBOOL WINAPI SetComputerNameExW(COMPUTER_NAME_FORMAT NameType,LPCWSTR lpBuffer);
+ WINBASEAPI WINBOOL WINAPI DnsHostnameToComputerNameA(LPCSTR Hostname,LPSTR ComputerName,LPDWORD nSize);
+ WINBASEAPI WINBOOL WINAPI DnsHostnameToComputerNameW(LPCWSTR Hostname,LPWSTR ComputerName,LPDWORD nSize);
+ WINADVAPI WINBOOL WINAPI GetUserNameA(LPSTR lpBuffer,LPDWORD pcbBuffer);
+ WINADVAPI WINBOOL WINAPI GetUserNameW(LPWSTR lpBuffer,LPDWORD pcbBuffer);
+
+#define LOGON32_LOGON_INTERACTIVE 2
+#define LOGON32_LOGON_NETWORK 3
+#define LOGON32_LOGON_BATCH 4
+#define LOGON32_LOGON_SERVICE 5
+#define LOGON32_LOGON_UNLOCK 7
+#define LOGON32_LOGON_NETWORK_CLEARTEXT 8
+#define LOGON32_LOGON_NEW_CREDENTIALS 9
+
+#define LOGON32_PROVIDER_DEFAULT 0
+#define LOGON32_PROVIDER_WINNT35 1
+#define LOGON32_PROVIDER_WINNT40 2
+#define LOGON32_PROVIDER_WINNT50 3
+
+#ifdef UNICODE
+#define LogonUser LogonUserW
+#define LogonUserEx LogonUserExW
+#define CreateProcessAsUser CreateProcessAsUserW
+#else
+#define LogonUser LogonUserA
+#define LogonUserEx LogonUserExA
+#define CreateProcessAsUser CreateProcessAsUserA
+#endif
+
+ WINADVAPI WINBOOL WINAPI LogonUserA(LPCSTR lpszUsername,LPCSTR lpszDomain,LPCSTR lpszPassword,DWORD dwLogonType,DWORD dwLogonProvider,PHANDLE phToken);
+ WINADVAPI WINBOOL WINAPI LogonUserW(LPCWSTR lpszUsername,LPCWSTR lpszDomain,LPCWSTR lpszPassword,DWORD dwLogonType,DWORD dwLogonProvider,PHANDLE phToken);
+ WINADVAPI WINBOOL WINAPI LogonUserExA(LPCSTR lpszUsername,LPCSTR lpszDomain,LPCSTR lpszPassword,DWORD dwLogonType,DWORD dwLogonProvider,PHANDLE phToken,PSID *ppLogonSid,PVOID *ppProfileBuffer,LPDWORD pdwProfileLength,PQUOTA_LIMITS pQuotaLimits);
+ WINADVAPI WINBOOL WINAPI LogonUserExW(LPCWSTR lpszUsername,LPCWSTR lpszDomain,LPCWSTR lpszPassword,DWORD dwLogonType,DWORD dwLogonProvider,PHANDLE phToken,PSID *ppLogonSid,PVOID *ppProfileBuffer,LPDWORD pdwProfileLength,PQUOTA_LIMITS pQuotaLimits);
+ WINADVAPI WINBOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken);
+ WINADVAPI WINBOOL WINAPI CreateProcessAsUserA(HANDLE hToken,LPCSTR lpApplicationName,LPSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,WINBOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCSTR lpCurrentDirectory,LPSTARTUPINFOA lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation);
+ WINADVAPI WINBOOL WINAPI CreateProcessAsUserW(HANDLE hToken,LPCWSTR lpApplicationName,LPWSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,WINBOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation);
+
+#define LOGON_WITH_PROFILE 0x1
+#define LOGON_NETCREDENTIALS_ONLY 0x2
+#define LOGON_ZERO_PASSWORD_BUFFER 0x80000000
+
+ WINADVAPI WINBOOL WINAPI CreateProcessWithLogonW(LPCWSTR lpUsername,LPCWSTR lpDomain,LPCWSTR lpPassword,DWORD dwLogonFlags,LPCWSTR lpApplicationName,LPWSTR lpCommandLine,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation);
+ WINADVAPI WINBOOL WINAPI CreateProcessWithTokenW(HANDLE hToken,DWORD dwLogonFlags,LPCWSTR lpApplicationName,LPWSTR lpCommandLine,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation);
+ WINADVAPI WINBOOL WINAPI ImpersonateAnonymousToken(HANDLE ThreadHandle);
+ WINADVAPI WINBOOL WINAPI DuplicateTokenEx(HANDLE hExistingToken,DWORD dwDesiredAccess,LPSECURITY_ATTRIBUTES lpTokenAttributes,SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,TOKEN_TYPE TokenType,PHANDLE phNewToken);
+ WINADVAPI WINBOOL WINAPI CreateRestrictedToken(HANDLE ExistingTokenHandle,DWORD Flags,DWORD DisableSidCount,PSID_AND_ATTRIBUTES SidsToDisable,DWORD DeletePrivilegeCount,PLUID_AND_ATTRIBUTES PrivilegesToDelete,DWORD RestrictedSidCount,PSID_AND_ATTRIBUTES SidsToRestrict,PHANDLE NewTokenHandle);
+ WINADVAPI WINBOOL WINAPI IsTokenRestricted(HANDLE TokenHandle);
+ WINADVAPI WINBOOL WINAPI IsTokenUntrusted(HANDLE TokenHandle);
+ WINADVAPI WINBOOL WINAPI CheckTokenMembership(HANDLE TokenHandle,PSID SidToCheck,PBOOL IsMember);
+
+ typedef WAITORTIMERCALLBACKFUNC WAITORTIMERCALLBACK;
+
+ WINBASEAPI WINBOOL WINAPI RegisterWaitForSingleObject(PHANDLE phNewWaitObject,HANDLE hObject,WAITORTIMERCALLBACK Callback,PVOID Context,ULONG dwMilliseconds,ULONG dwFlags);
+ WINBASEAPI HANDLE WINAPI RegisterWaitForSingleObjectEx(HANDLE hObject,WAITORTIMERCALLBACK Callback,PVOID Context,ULONG dwMilliseconds,ULONG dwFlags);
+ WINBASEAPI WINBOOL WINAPI UnregisterWait(HANDLE WaitHandle);
+ WINBASEAPI WINBOOL WINAPI UnregisterWaitEx(HANDLE WaitHandle,HANDLE CompletionEvent);
+ WINBASEAPI WINBOOL WINAPI QueueUserWorkItem(LPTHREAD_START_ROUTINE Function,PVOID Context,ULONG Flags);
+ WINBASEAPI WINBOOL WINAPI BindIoCompletionCallback(HANDLE FileHandle,LPOVERLAPPED_COMPLETION_ROUTINE Function,ULONG Flags);
+ WINBASEAPI HANDLE WINAPI CreateTimerQueue(VOID);
+ WINBASEAPI WINBOOL WINAPI CreateTimerQueueTimer(PHANDLE phNewTimer,HANDLE TimerQueue,WAITORTIMERCALLBACK Callback,PVOID Parameter,DWORD DueTime,DWORD Period,ULONG Flags);
+ WINBASEAPI WINBOOL WINAPI ChangeTimerQueueTimer(HANDLE TimerQueue,HANDLE Timer,ULONG DueTime,ULONG Period);
+ WINBASEAPI WINBOOL WINAPI DeleteTimerQueueTimer(HANDLE TimerQueue,HANDLE Timer,HANDLE CompletionEvent);
+ WINBASEAPI WINBOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue,HANDLE CompletionEvent);
+ WINBASEAPI HANDLE WINAPI SetTimerQueueTimer(HANDLE TimerQueue,WAITORTIMERCALLBACK Callback,PVOID Parameter,DWORD DueTime,DWORD Period,WINBOOL PreferIo);
+ WINBASEAPI WINBOOL WINAPI CancelTimerQueueTimer(HANDLE TimerQueue,HANDLE Timer);
+ WINBASEAPI WINBOOL WINAPI DeleteTimerQueue(HANDLE TimerQueue);
+
+#define HW_PROFILE_GUIDLEN 39
+#define MAX_PROFILE_LEN 80
+
+#define DOCKINFO_UNDOCKED (0x1)
+#define DOCKINFO_DOCKED (0x2)
+#define DOCKINFO_USER_SUPPLIED (0x4)
+#define DOCKINFO_USER_UNDOCKED (DOCKINFO_USER_SUPPLIED | DOCKINFO_UNDOCKED)
+#define DOCKINFO_USER_DOCKED (DOCKINFO_USER_SUPPLIED | DOCKINFO_DOCKED)
+
+ typedef struct tagHW_PROFILE_INFOA {
+ DWORD dwDockInfo;
+ CHAR szHwProfileGuid[HW_PROFILE_GUIDLEN];
+ CHAR szHwProfileName[MAX_PROFILE_LEN];
+ } HW_PROFILE_INFOA,*LPHW_PROFILE_INFOA;
+
+ typedef struct tagHW_PROFILE_INFOW {
+ DWORD dwDockInfo;
+ WCHAR szHwProfileGuid[HW_PROFILE_GUIDLEN];
+ WCHAR szHwProfileName[MAX_PROFILE_LEN];
+ } HW_PROFILE_INFOW,*LPHW_PROFILE_INFOW;
+
+#ifdef UNICODE
+ typedef HW_PROFILE_INFOW HW_PROFILE_INFO;
+ typedef LPHW_PROFILE_INFOW LPHW_PROFILE_INFO;
+#else
+ typedef HW_PROFILE_INFOA HW_PROFILE_INFO;
+ typedef LPHW_PROFILE_INFOA LPHW_PROFILE_INFO;
+#endif
+
+#ifdef UNICODE
+#define GetCurrentHwProfile GetCurrentHwProfileW
+#define GetVersionEx GetVersionExW
+#define VerifyVersionInfo VerifyVersionInfoW
+#else
+#define GetCurrentHwProfile GetCurrentHwProfileA
+#define GetVersionEx GetVersionExA
+#define VerifyVersionInfo VerifyVersionInfoA
+#endif
+
+ WINADVAPI WINBOOL WINAPI GetCurrentHwProfileA (LPHW_PROFILE_INFOA lpHwProfileInfo);
+ WINADVAPI WINBOOL WINAPI GetCurrentHwProfileW (LPHW_PROFILE_INFOW lpHwProfileInfo);
+ WINBASEAPI WINBOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);
+ WINBASEAPI WINBOOL WINAPI QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
+ WINBASEAPI WINBOOL WINAPI GetVersionExA(LPOSVERSIONINFOA lpVersionInformation);
+ WINBASEAPI WINBOOL WINAPI GetVersionExW(LPOSVERSIONINFOW lpVersionInformation);
+ WINBASEAPI WINBOOL WINAPI VerifyVersionInfoA(LPOSVERSIONINFOEXA lpVersionInformation,DWORD dwTypeMask,DWORDLONG dwlConditionMask);
+ WINBASEAPI WINBOOL WINAPI VerifyVersionInfoW(LPOSVERSIONINFOEXW lpVersionInformation,DWORD dwTypeMask,DWORDLONG dwlConditionMask);
+
+#include <winerror.h>
+
+#define TC_NORMAL 0
+#define TC_HARDERR 1
+#define TC_GP_TRAP 2
+#define TC_SIGNAL 3
+
+#define AC_LINE_OFFLINE 0x0
+#define AC_LINE_ONLINE 0x1
+#define AC_LINE_BACKUP_POWER 0x2
+#define AC_LINE_UNKNOWN 0xff
+
+#define BATTERY_FLAG_HIGH 0x1
+#define BATTERY_FLAG_LOW 0x2
+#define BATTERY_FLAG_CRITICAL 0x4
+#define BATTERY_FLAG_CHARGING 0x8
+#define BATTERY_FLAG_NO_BATTERY 0x80
+#define BATTERY_FLAG_UNKNOWN 0xff
+
+#define BATTERY_PERCENTAGE_UNKNOWN 0xff
+
+#define BATTERY_LIFE_UNKNOWN 0xffffffff
+
+ typedef struct _SYSTEM_POWER_STATUS {
+ BYTE ACLineStatus;
+ BYTE BatteryFlag;
+ BYTE BatteryLifePercent;
+ BYTE Reserved1;
+ DWORD BatteryLifeTime;
+ DWORD BatteryFullLifeTime;
+ } SYSTEM_POWER_STATUS,*LPSYSTEM_POWER_STATUS;
+
+#ifdef UNICODE
+#define CreateJobObject CreateJobObjectW
+#define OpenJobObject OpenJobObjectW
+#define FindFirstVolume FindFirstVolumeW
+#define FindNextVolume FindNextVolumeW
+#define FindFirstVolumeMountPoint FindFirstVolumeMountPointW
+#define FindNextVolumeMountPoint FindNextVolumeMountPointW
+#define SetVolumeMountPoint SetVolumeMountPointW
+#define DeleteVolumeMountPoint DeleteVolumeMountPointW
+#define GetVolumeNameForVolumeMountPoint GetVolumeNameForVolumeMountPointW
+#define GetVolumePathName GetVolumePathNameW
+#define GetVolumePathNamesForVolumeName GetVolumePathNamesForVolumeNameW
+#else
+#define CreateJobObject CreateJobObjectA
+#define OpenJobObject OpenJobObjectA
+#define FindFirstVolume FindFirstVolumeA
+#define FindNextVolume FindNextVolumeA
+#define FindFirstVolumeMountPoint FindFirstVolumeMountPointA
+#define FindNextVolumeMountPoint FindNextVolumeMountPointA
+#define SetVolumeMountPoint SetVolumeMountPointA
+#define DeleteVolumeMountPoint DeleteVolumeMountPointA
+#define GetVolumeNameForVolumeMountPoint GetVolumeNameForVolumeMountPointA
+#define GetVolumePathName GetVolumePathNameA
+#define GetVolumePathNamesForVolumeName GetVolumePathNamesForVolumeNameA
+#endif
+
+ WINBOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS lpSystemPowerStatus);
+ WINBOOL WINAPI SetSystemPowerState(WINBOOL fSuspend,WINBOOL fForce);
+ WINBASEAPI WINBOOL WINAPI AllocateUserPhysicalPages(HANDLE hProcess,PULONG_PTR NumberOfPages,PULONG_PTR PageArray);
+ WINBASEAPI WINBOOL WINAPI FreeUserPhysicalPages(HANDLE hProcess,PULONG_PTR NumberOfPages,PULONG_PTR PageArray);
+ WINBASEAPI WINBOOL WINAPI MapUserPhysicalPages(PVOID VirtualAddress,ULONG_PTR NumberOfPages,PULONG_PTR PageArray);
+ WINBASEAPI WINBOOL WINAPI MapUserPhysicalPagesScatter(PVOID *VirtualAddresses,ULONG_PTR NumberOfPages,PULONG_PTR PageArray);
+ WINBASEAPI HANDLE WINAPI CreateJobObjectA(LPSECURITY_ATTRIBUTES lpJobAttributes,LPCSTR lpName);
+ WINBASEAPI HANDLE WINAPI CreateJobObjectW(LPSECURITY_ATTRIBUTES lpJobAttributes,LPCWSTR lpName);
+ WINBASEAPI HANDLE WINAPI OpenJobObjectA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpName);
+ WINBASEAPI HANDLE WINAPI OpenJobObjectW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpName);
+ WINBASEAPI WINBOOL WINAPI AssignProcessToJobObject(HANDLE hJob,HANDLE hProcess);
+ WINBASEAPI WINBOOL WINAPI TerminateJobObject(HANDLE hJob,UINT uExitCode);
+ WINBASEAPI WINBOOL WINAPI QueryInformationJobObject(HANDLE hJob,JOBOBJECTINFOCLASS JobObjectInformationClass,LPVOID lpJobObjectInformation,DWORD cbJobObjectInformationLength,LPDWORD lpReturnLength);
+ WINBASEAPI WINBOOL WINAPI SetInformationJobObject(HANDLE hJob,JOBOBJECTINFOCLASS JobObjectInformationClass,LPVOID lpJobObjectInformation,DWORD cbJobObjectInformationLength);
+ WINBASEAPI WINBOOL WINAPI IsProcessInJob(HANDLE ProcessHandle,HANDLE JobHandle,PBOOL Result);
+ WINBASEAPI WINBOOL WINAPI CreateJobSet(ULONG NumJob,PJOB_SET_ARRAY UserJobSet,ULONG Flags);
+ WINBASEAPI PVOID WINAPI AddVectoredExceptionHandler (ULONG First,PVECTORED_EXCEPTION_HANDLER Handler);
+ WINBASEAPI ULONG WINAPI RemoveVectoredExceptionHandler(PVOID Handle);
+ WINBASEAPI PVOID WINAPI AddVectoredContinueHandler (ULONG First,PVECTORED_EXCEPTION_HANDLER Handler);
+ WINBASEAPI ULONG WINAPI RemoveVectoredContinueHandler(PVOID Handle);
+ WINBASEAPI HANDLE WINAPI FindFirstVolumeA(LPSTR lpszVolumeName,DWORD cchBufferLength);
+ WINBASEAPI HANDLE WINAPI FindFirstVolumeW(LPWSTR lpszVolumeName,DWORD cchBufferLength);
+ WINBASEAPI WINBOOL WINAPI FindNextVolumeA(HANDLE hFindVolume,LPSTR lpszVolumeName,DWORD cchBufferLength);
+ WINBASEAPI WINBOOL WINAPI FindNextVolumeW(HANDLE hFindVolume,LPWSTR lpszVolumeName,DWORD cchBufferLength);
+ WINBASEAPI WINBOOL WINAPI FindVolumeClose(HANDLE hFindVolume);
+ WINBASEAPI HANDLE WINAPI FindFirstVolumeMountPointA(LPCSTR lpszRootPathName,LPSTR lpszVolumeMountPoint,DWORD cchBufferLength);
+ WINBASEAPI HANDLE WINAPI FindFirstVolumeMountPointW(LPCWSTR lpszRootPathName,LPWSTR lpszVolumeMountPoint,DWORD cchBufferLength);
+ WINBASEAPI WINBOOL WINAPI FindNextVolumeMountPointA(HANDLE hFindVolumeMountPoint,LPSTR lpszVolumeMountPoint,DWORD cchBufferLength);
+ WINBASEAPI WINBOOL WINAPI FindNextVolumeMountPointW(HANDLE hFindVolumeMountPoint,LPWSTR lpszVolumeMountPoint,DWORD cchBufferLength);
+ WINBASEAPI WINBOOL WINAPI FindVolumeMountPointClose(HANDLE hFindVolumeMountPoint);
+ WINBASEAPI WINBOOL WINAPI SetVolumeMountPointA(LPCSTR lpszVolumeMountPoint,LPCSTR lpszVolumeName);
+ WINBASEAPI WINBOOL WINAPI SetVolumeMountPointW(LPCWSTR lpszVolumeMountPoint,LPCWSTR lpszVolumeName);
+ WINBASEAPI WINBOOL WINAPI DeleteVolumeMountPointA(LPCSTR lpszVolumeMountPoint);
+ WINBASEAPI WINBOOL WINAPI DeleteVolumeMountPointW(LPCWSTR lpszVolumeMountPoint);
+ WINBASEAPI WINBOOL WINAPI GetVolumeNameForVolumeMountPointA(LPCSTR lpszVolumeMountPoint,LPSTR lpszVolumeName,DWORD cchBufferLength);
+ WINBASEAPI WINBOOL WINAPI GetVolumeNameForVolumeMountPointW(LPCWSTR lpszVolumeMountPoint,LPWSTR lpszVolumeName,DWORD cchBufferLength);
+ WINBASEAPI WINBOOL WINAPI GetVolumePathNameA(LPCSTR lpszFileName,LPSTR lpszVolumePathName,DWORD cchBufferLength);
+ WINBASEAPI WINBOOL WINAPI GetVolumePathNameW(LPCWSTR lpszFileName,LPWSTR lpszVolumePathName,DWORD cchBufferLength);
+ WINBASEAPI WINBOOL WINAPI GetVolumePathNamesForVolumeNameA(LPCSTR lpszVolumeName,LPCH lpszVolumePathNames,DWORD cchBufferLength,PDWORD lpcchReturnLength);
+ WINBASEAPI WINBOOL WINAPI GetVolumePathNamesForVolumeNameW(LPCWSTR lpszVolumeName,LPWCH lpszVolumePathNames,DWORD cchBufferLength,PDWORD lpcchReturnLength);
+
+#define ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID 0x1
+#define ACTCTX_FLAG_LANGID_VALID 0x2
+#define ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID 0x4
+#define ACTCTX_FLAG_RESOURCE_NAME_VALID 0x8
+#define ACTCTX_FLAG_SET_PROCESS_DEFAULT 0x10
+#define ACTCTX_FLAG_APPLICATION_NAME_VALID 0x20
+#define ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF 0x40
+#define ACTCTX_FLAG_HMODULE_VALID 0x80
+
+ typedef struct tagACTCTXA {
+ ULONG cbSize;
+ DWORD dwFlags;
+ LPCSTR lpSource;
+ USHORT wProcessorArchitecture;
+ LANGID wLangId;
+ LPCSTR lpAssemblyDirectory;
+ LPCSTR lpResourceName;
+ LPCSTR lpApplicationName;
+ HMODULE hModule;
+ } ACTCTXA,*PACTCTXA;
+
+ typedef struct tagACTCTXW {
+ ULONG cbSize;
+ DWORD dwFlags;
+ LPCWSTR lpSource;
+ USHORT wProcessorArchitecture;
+ LANGID wLangId;
+ LPCWSTR lpAssemblyDirectory;
+ LPCWSTR lpResourceName;
+ LPCWSTR lpApplicationName;
+ HMODULE hModule;
+ } ACTCTXW,*PACTCTXW;
+
+ typedef const ACTCTXA *PCACTCTXA;
+ typedef const ACTCTXW *PCACTCTXW;
+
+#ifdef UNICODE
+ typedef ACTCTXW ACTCTX;
+ typedef PACTCTXW PACTCTX;
+ typedef PCACTCTXW PCACTCTX;
+#else
+ typedef ACTCTXA ACTCTX;
+ typedef PACTCTXA PACTCTX;
+ typedef PCACTCTXA PCACTCTX;
+#endif
+
+#ifdef UNICODE
+#define CreateActCtx CreateActCtxW
+#else
+#define CreateActCtx CreateActCtxA
+#endif
+
+ WINBASEAPI HANDLE WINAPI CreateActCtxA(PCACTCTXA pActCtx);
+ WINBASEAPI HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx);
+ WINBASEAPI VOID WINAPI AddRefActCtx(HANDLE hActCtx);
+ WINBASEAPI VOID WINAPI ReleaseActCtx(HANDLE hActCtx);
+ WINBASEAPI WINBOOL WINAPI ZombifyActCtx(HANDLE hActCtx);
+ WINBASEAPI WINBOOL WINAPI ActivateActCtx(HANDLE hActCtx,ULONG_PTR *lpCookie);
+
+#define DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION (0x1)
+
+ WINBASEAPI WINBOOL WINAPI DeactivateActCtx(DWORD dwFlags,ULONG_PTR ulCookie);
+ WINBASEAPI WINBOOL WINAPI GetCurrentActCtx(HANDLE *lphActCtx);
+
+ typedef struct tagACTCTX_SECTION_KEYED_DATA_2600 {
+ ULONG cbSize;
+ ULONG ulDataFormatVersion;
+ PVOID lpData;
+ ULONG ulLength;
+ PVOID lpSectionGlobalData;
+ ULONG ulSectionGlobalDataLength;
+ PVOID lpSectionBase;
+ ULONG ulSectionTotalLength;
+ HANDLE hActCtx;
+ ULONG ulAssemblyRosterIndex;
+ } ACTCTX_SECTION_KEYED_DATA_2600,*PACTCTX_SECTION_KEYED_DATA_2600;
+
+ typedef const ACTCTX_SECTION_KEYED_DATA_2600 *PCACTCTX_SECTION_KEYED_DATA_2600;
+
+ typedef struct tagACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA {
+ PVOID lpInformation;
+ PVOID lpSectionBase;
+ ULONG ulSectionLength;
+ PVOID lpSectionGlobalDataBase;
+ ULONG ulSectionGlobalDataLength;
+ } ACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA,*PACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA;
+
+ typedef const ACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA *PCACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA;
+
+ typedef struct tagACTCTX_SECTION_KEYED_DATA {
+ ULONG cbSize;
+ ULONG ulDataFormatVersion;
+ PVOID lpData;
+ ULONG ulLength;
+ PVOID lpSectionGlobalData;
+ ULONG ulSectionGlobalDataLength;
+ PVOID lpSectionBase;
+ ULONG ulSectionTotalLength;
+ HANDLE hActCtx;
+ ULONG ulAssemblyRosterIndex;
+
+ ULONG ulFlags;
+ ACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA AssemblyMetadata;
+ } ACTCTX_SECTION_KEYED_DATA,*PACTCTX_SECTION_KEYED_DATA;
+
+ typedef const ACTCTX_SECTION_KEYED_DATA *PCACTCTX_SECTION_KEYED_DATA;
+
+#define FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX 0x1
+#define FIND_ACTCTX_SECTION_KEY_RETURN_FLAGS 0x2
+#define FIND_ACTCTX_SECTION_KEY_RETURN_ASSEMBLY_METADATA 0x4
+
+#ifdef UNICODE
+#define FindActCtxSectionString FindActCtxSectionStringW
+#else
+#define FindActCtxSectionString FindActCtxSectionStringA
+#endif
+
+ WINBASEAPI WINBOOL WINAPI FindActCtxSectionStringA(DWORD dwFlags,const GUID *lpExtensionGuid,ULONG ulSectionId,LPCSTR lpStringToFind,PACTCTX_SECTION_KEYED_DATA ReturnedData);
+ WINBASEAPI WINBOOL WINAPI FindActCtxSectionStringW(DWORD dwFlags,const GUID *lpExtensionGuid,ULONG ulSectionId,LPCWSTR lpStringToFind,PACTCTX_SECTION_KEYED_DATA ReturnedData);
+ WINBASEAPI WINBOOL WINAPI FindActCtxSectionGuid(DWORD dwFlags,const GUID *lpExtensionGuid,ULONG ulSectionId,const GUID *lpGuidToFind,PACTCTX_SECTION_KEYED_DATA ReturnedData);
+
+#ifndef RC_INVOKED
+#ifndef ACTIVATION_CONTEXT_BASIC_INFORMATION_DEFINED
+
+ typedef struct _ACTIVATION_CONTEXT_BASIC_INFORMATION {
+ HANDLE hActCtx;
+ DWORD dwFlags;
+ } ACTIVATION_CONTEXT_BASIC_INFORMATION,*PACTIVATION_CONTEXT_BASIC_INFORMATION;
+
+ typedef const struct _ACTIVATION_CONTEXT_BASIC_INFORMATION *PCACTIVATION_CONTEXT_BASIC_INFORMATION;
+
+#define ACTIVATION_CONTEXT_BASIC_INFORMATION_DEFINED 1
+#endif
+#endif
+
+#define QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX 0x4
+#define QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE 0x8
+#define QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS 0x10
+#define QUERY_ACTCTX_FLAG_NO_ADDREF 0x80000000
+
+ WINBASEAPI WINBOOL WINAPI QueryActCtxW(DWORD dwFlags,HANDLE hActCtx,PVOID pvSubInstance,ULONG ulInfoClass,PVOID pvBuffer,SIZE_T cbBuffer,SIZE_T *pcbWrittenOrRequired);
+
+ typedef WINBOOL (WINAPI *PQUERYACTCTXW_FUNC)(DWORD dwFlags,HANDLE hActCtx,PVOID pvSubInstance,ULONG ulInfoClass,PVOID pvBuffer,SIZE_T cbBuffer,SIZE_T *pcbWrittenOrRequired);
+
+ WINBASEAPI WINBOOL WINAPI ProcessIdToSessionId(DWORD dwProcessId,DWORD *pSessionId);
+ WINBASEAPI DWORD WINAPI WTSGetActiveConsoleSessionId();
+ WINBASEAPI WINBOOL WINAPI IsWow64Process(HANDLE hProcess,PBOOL Wow64Process);
+ WINBASEAPI WINBOOL WINAPI GetLogicalProcessorInformation(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer,PDWORD ReturnedLength);
+ WINBASEAPI WINBOOL WINAPI GetNumaHighestNodeNumber(PULONG HighestNodeNumber);
+ WINBASEAPI WINBOOL WINAPI GetNumaProcessorNode(UCHAR Processor,PUCHAR NodeNumber);
+ WINBASEAPI WINBOOL WINAPI GetNumaNodeProcessorMask(UCHAR Node,PULONGLONG ProcessorMask);
+ WINBASEAPI WINBOOL WINAPI GetNumaAvailableMemoryNode(UCHAR Node,PULONGLONG AvailableBytes);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/include/winapi/wincon.h b/win32/include/winapi/wincon.h
new file mode 100644
index 0000000..a3501ee
--- /dev/null
+++ b/win32/include/winapi/wincon.h
@@ -0,0 +1,301 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _WINCON_
+#define _WINCON_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef struct _COORD {
+ SHORT X;
+ SHORT Y;
+ } COORD,*PCOORD;
+
+ typedef struct _SMALL_RECT {
+ SHORT Left;
+ SHORT Top;
+ SHORT Right;
+ SHORT Bottom;
+ } SMALL_RECT,*PSMALL_RECT;
+
+ typedef struct _KEY_EVENT_RECORD {
+ WINBOOL bKeyDown;
+ WORD wRepeatCount;
+ WORD wVirtualKeyCode;
+ WORD wVirtualScanCode;
+ union {
+ WCHAR UnicodeChar;
+ CHAR AsciiChar;
+ } uChar;
+ DWORD dwControlKeyState;
+ } KEY_EVENT_RECORD,*PKEY_EVENT_RECORD;
+
+#define RIGHT_ALT_PRESSED 0x1
+#define LEFT_ALT_PRESSED 0x2
+#define RIGHT_CTRL_PRESSED 0x4
+#define LEFT_CTRL_PRESSED 0x8
+#define SHIFT_PRESSED 0x10
+#define NUMLOCK_ON 0x20
+#define SCROLLLOCK_ON 0x40
+#define CAPSLOCK_ON 0x80
+#define ENHANCED_KEY 0x100
+#define NLS_DBCSCHAR 0x10000
+#define NLS_ALPHANUMERIC 0x0
+#define NLS_KATAKANA 0x20000
+#define NLS_HIRAGANA 0x40000
+#define NLS_ROMAN 0x400000
+#define NLS_IME_CONVERSION 0x800000
+#define NLS_IME_DISABLE 0x20000000
+
+ typedef struct _MOUSE_EVENT_RECORD {
+ COORD dwMousePosition;
+ DWORD dwButtonState;
+ DWORD dwControlKeyState;
+ DWORD dwEventFlags;
+ } MOUSE_EVENT_RECORD,*PMOUSE_EVENT_RECORD;
+
+#define FROM_LEFT_1ST_BUTTON_PRESSED 0x1
+#define RIGHTMOST_BUTTON_PRESSED 0x2
+#define FROM_LEFT_2ND_BUTTON_PRESSED 0x4
+#define FROM_LEFT_3RD_BUTTON_PRESSED 0x8
+#define FROM_LEFT_4TH_BUTTON_PRESSED 0x10
+
+#define MOUSE_MOVED 0x1
+#define DOUBLE_CLICK 0x2
+#define MOUSE_WHEELED 0x4
+
+ typedef struct _WINDOW_BUFFER_SIZE_RECORD {
+ COORD dwSize;
+ } WINDOW_BUFFER_SIZE_RECORD,*PWINDOW_BUFFER_SIZE_RECORD;
+
+ typedef struct _MENU_EVENT_RECORD {
+ UINT dwCommandId;
+ } MENU_EVENT_RECORD,*PMENU_EVENT_RECORD;
+
+ typedef struct _FOCUS_EVENT_RECORD {
+ WINBOOL bSetFocus;
+ } FOCUS_EVENT_RECORD,*PFOCUS_EVENT_RECORD;
+
+ typedef struct _INPUT_RECORD {
+ WORD EventType;
+ union {
+ KEY_EVENT_RECORD KeyEvent;
+ MOUSE_EVENT_RECORD MouseEvent;
+ WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
+ MENU_EVENT_RECORD MenuEvent;
+ FOCUS_EVENT_RECORD FocusEvent;
+ } Event;
+ } INPUT_RECORD,*PINPUT_RECORD;
+
+#define KEY_EVENT 0x1
+#define MOUSE_EVENT 0x2
+#define WINDOW_BUFFER_SIZE_EVENT 0x4
+#define MENU_EVENT 0x8
+#define FOCUS_EVENT 0x10
+
+ typedef struct _CHAR_INFO {
+ union {
+ WCHAR UnicodeChar;
+ CHAR AsciiChar;
+ } Char;
+ WORD Attributes;
+ } CHAR_INFO,*PCHAR_INFO;
+
+#define FOREGROUND_BLUE 0x1
+#define FOREGROUND_GREEN 0x2
+#define FOREGROUND_RED 0x4
+#define FOREGROUND_INTENSITY 0x8
+#define BACKGROUND_BLUE 0x10
+#define BACKGROUND_GREEN 0x20
+#define BACKGROUND_RED 0x40
+#define BACKGROUND_INTENSITY 0x80
+#define COMMON_LVB_LEADING_BYTE 0x100
+#define COMMON_LVB_TRAILING_BYTE 0x200
+#define COMMON_LVB_GRID_HORIZONTAL 0x400
+#define COMMON_LVB_GRID_LVERTICAL 0x800
+#define COMMON_LVB_GRID_RVERTICAL 0x1000
+#define COMMON_LVB_REVERSE_VIDEO 0x4000
+#define COMMON_LVB_UNDERSCORE 0x8000
+
+#define COMMON_LVB_SBCSDBCS 0x300
+
+ typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
+ COORD dwSize;
+ COORD dwCursorPosition;
+ WORD wAttributes;
+ SMALL_RECT srWindow;
+ COORD dwMaximumWindowSize;
+ } CONSOLE_SCREEN_BUFFER_INFO,*PCONSOLE_SCREEN_BUFFER_INFO;
+
+ typedef struct _CONSOLE_CURSOR_INFO {
+ DWORD dwSize;
+ WINBOOL bVisible;
+ } CONSOLE_CURSOR_INFO,*PCONSOLE_CURSOR_INFO;
+
+ typedef struct _CONSOLE_FONT_INFO {
+ DWORD nFont;
+ COORD dwFontSize;
+ } CONSOLE_FONT_INFO,*PCONSOLE_FONT_INFO;
+
+ typedef struct _CONSOLE_SELECTION_INFO {
+ DWORD dwFlags;
+ COORD dwSelectionAnchor;
+ SMALL_RECT srSelection;
+ } CONSOLE_SELECTION_INFO,*PCONSOLE_SELECTION_INFO;
+
+#define CONSOLE_NO_SELECTION 0x0
+#define CONSOLE_SELECTION_IN_PROGRESS 0x1
+#define CONSOLE_SELECTION_NOT_EMPTY 0x2
+#define CONSOLE_MOUSE_SELECTION 0x4
+#define CONSOLE_MOUSE_DOWN 0x8
+
+ typedef WINBOOL (WINAPI *PHANDLER_ROUTINE)(DWORD CtrlType);
+
+#define CTRL_C_EVENT 0
+#define CTRL_BREAK_EVENT 1
+#define CTRL_CLOSE_EVENT 2
+
+#define CTRL_LOGOFF_EVENT 5
+#define CTRL_SHUTDOWN_EVENT 6
+
+#define ENABLE_PROCESSED_INPUT 0x1
+#define ENABLE_LINE_INPUT 0x2
+#define ENABLE_ECHO_INPUT 0x4
+#define ENABLE_WINDOW_INPUT 0x8
+#define ENABLE_MOUSE_INPUT 0x10
+
+#define ENABLE_PROCESSED_OUTPUT 0x1
+#define ENABLE_WRAP_AT_EOL_OUTPUT 0x2
+
+#ifdef UNICODE
+#define PeekConsoleInput PeekConsoleInputW
+#define ReadConsoleInput ReadConsoleInputW
+#define WriteConsoleInput WriteConsoleInputW
+#define ReadConsoleOutput ReadConsoleOutputW
+#define WriteConsoleOutput WriteConsoleOutputW
+#define ReadConsoleOutputCharacter ReadConsoleOutputCharacterW
+#define WriteConsoleOutputCharacter WriteConsoleOutputCharacterW
+#define FillConsoleOutputCharacter FillConsoleOutputCharacterW
+#define ScrollConsoleScreenBuffer ScrollConsoleScreenBufferW
+#define GetConsoleTitle GetConsoleTitleW
+#define SetConsoleTitle SetConsoleTitleW
+#define ReadConsole ReadConsoleW
+#define WriteConsole WriteConsoleW
+#define AddConsoleAlias AddConsoleAliasW
+#define GetConsoleAlias GetConsoleAliasW
+#define GetConsoleAliasesLength GetConsoleAliasesLengthW
+#define GetConsoleAliasExesLength GetConsoleAliasExesLengthW
+#define GetConsoleAliases GetConsoleAliasesW
+#define GetConsoleAliasExes GetConsoleAliasExesW
+#else
+#define PeekConsoleInput PeekConsoleInputA
+#define ReadConsoleInput ReadConsoleInputA
+#define WriteConsoleInput WriteConsoleInputA
+#define ReadConsoleOutput ReadConsoleOutputA
+#define WriteConsoleOutput WriteConsoleOutputA
+#define ReadConsoleOutputCharacter ReadConsoleOutputCharacterA
+#define WriteConsoleOutputCharacter WriteConsoleOutputCharacterA
+#define FillConsoleOutputCharacter FillConsoleOutputCharacterA
+#define ScrollConsoleScreenBuffer ScrollConsoleScreenBufferA
+#define GetConsoleTitle GetConsoleTitleA
+#define SetConsoleTitle SetConsoleTitleA
+#define ReadConsole ReadConsoleA
+#define WriteConsole WriteConsoleA
+#define AddConsoleAlias AddConsoleAliasA
+#define GetConsoleAlias GetConsoleAliasA
+#define GetConsoleAliasesLength GetConsoleAliasesLengthA
+#define GetConsoleAliasExesLength GetConsoleAliasExesLengthA
+#define GetConsoleAliases GetConsoleAliasesA
+#define GetConsoleAliasExes GetConsoleAliasExesA
+#endif
+
+ WINBASEAPI WINBOOL WINAPI PeekConsoleInputA(HANDLE hConsoleInput,PINPUT_RECORD lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsRead);
+ WINBASEAPI WINBOOL WINAPI PeekConsoleInputW(HANDLE hConsoleInput,PINPUT_RECORD lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsRead);
+ WINBASEAPI WINBOOL WINAPI ReadConsoleInputA(HANDLE hConsoleInput,PINPUT_RECORD lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsRead);
+ WINBASEAPI WINBOOL WINAPI ReadConsoleInputW(HANDLE hConsoleInput,PINPUT_RECORD lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsRead);
+ WINBASEAPI WINBOOL WINAPI WriteConsoleInputA(HANDLE hConsoleInput,CONST INPUT_RECORD *lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsWritten);
+ WINBASEAPI WINBOOL WINAPI WriteConsoleInputW(HANDLE hConsoleInput,CONST INPUT_RECORD *lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsWritten);
+ WINBASEAPI WINBOOL WINAPI ReadConsoleOutputA(HANDLE hConsoleOutput,PCHAR_INFO lpBuffer,COORD dwBufferSize,COORD dwBufferCoord,PSMALL_RECT lpReadRegion);
+ WINBASEAPI WINBOOL WINAPI ReadConsoleOutputW(HANDLE hConsoleOutput,PCHAR_INFO lpBuffer,COORD dwBufferSize,COORD dwBufferCoord,PSMALL_RECT lpReadRegion);
+ WINBASEAPI WINBOOL WINAPI WriteConsoleOutputA(HANDLE hConsoleOutput,CONST CHAR_INFO *lpBuffer,COORD dwBufferSize,COORD dwBufferCoord,PSMALL_RECT lpWriteRegion);
+ WINBASEAPI WINBOOL WINAPI WriteConsoleOutputW(HANDLE hConsoleOutput,CONST CHAR_INFO *lpBuffer,COORD dwBufferSize,COORD dwBufferCoord,PSMALL_RECT lpWriteRegion);
+ WINBASEAPI WINBOOL WINAPI ReadConsoleOutputCharacterA(HANDLE hConsoleOutput,LPSTR lpCharacter,DWORD nLength,COORD dwReadCoord,LPDWORD lpNumberOfCharsRead);
+ WINBASEAPI WINBOOL WINAPI ReadConsoleOutputCharacterW(HANDLE hConsoleOutput,LPWSTR lpCharacter,DWORD nLength,COORD dwReadCoord,LPDWORD lpNumberOfCharsRead);
+ WINBASEAPI WINBOOL WINAPI ReadConsoleOutputAttribute(HANDLE hConsoleOutput,LPWORD lpAttribute,DWORD nLength,COORD dwReadCoord,LPDWORD lpNumberOfAttrsRead);
+ WINBASEAPI WINBOOL WINAPI WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,LPCSTR lpCharacter,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfCharsWritten);
+ WINBASEAPI WINBOOL WINAPI WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,LPCWSTR lpCharacter,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfCharsWritten);
+ WINBASEAPI WINBOOL WINAPI WriteConsoleOutputAttribute(HANDLE hConsoleOutput,CONST WORD *lpAttribute,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfAttrsWritten);
+ WINBASEAPI WINBOOL WINAPI FillConsoleOutputCharacterA(HANDLE hConsoleOutput,CHAR cCharacter,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfCharsWritten);
+ WINBASEAPI WINBOOL WINAPI FillConsoleOutputCharacterW(HANDLE hConsoleOutput,WCHAR cCharacter,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfCharsWritten);
+ WINBASEAPI WINBOOL WINAPI FillConsoleOutputAttribute(HANDLE hConsoleOutput,WORD wAttribute,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfAttrsWritten);
+ WINBASEAPI WINBOOL WINAPI GetConsoleMode(HANDLE hConsoleHandle,LPDWORD lpMode);
+ WINBASEAPI WINBOOL WINAPI GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,LPDWORD lpNumberOfEvents);
+ WINBASEAPI WINBOOL WINAPI GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
+ WINBASEAPI COORD WINAPI GetLargestConsoleWindowSize(HANDLE hConsoleOutput);
+ WINBASEAPI WINBOOL WINAPI GetConsoleCursorInfo(HANDLE hConsoleOutput,PCONSOLE_CURSOR_INFO lpConsoleCursorInfo);
+ WINBASEAPI WINBOOL WINAPI GetCurrentConsoleFont(HANDLE hConsoleOutput,WINBOOL bMaximumWindow,PCONSOLE_FONT_INFO lpConsoleCurrentFont);
+ WINBASEAPI COORD WINAPI GetConsoleFontSize(HANDLE hConsoleOutput,DWORD nFont);
+ WINBASEAPI WINBOOL WINAPI GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo);
+ WINBASEAPI WINBOOL WINAPI GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons);
+ WINBASEAPI WINBOOL WINAPI SetConsoleMode(HANDLE hConsoleHandle,DWORD dwMode);
+ WINBASEAPI WINBOOL WINAPI SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput);
+ WINBASEAPI WINBOOL WINAPI FlushConsoleInputBuffer(HANDLE hConsoleInput);
+ WINBASEAPI WINBOOL WINAPI SetConsoleScreenBufferSize(HANDLE hConsoleOutput,COORD dwSize);
+ WINBASEAPI WINBOOL WINAPI SetConsoleCursorPosition(HANDLE hConsoleOutput,COORD dwCursorPosition);
+ WINBASEAPI WINBOOL WINAPI SetConsoleCursorInfo(HANDLE hConsoleOutput,CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo);
+ WINBASEAPI WINBOOL WINAPI ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,CONST SMALL_RECT *lpScrollRectangle,CONST SMALL_RECT *lpClipRectangle,COORD dwDestinationOrigin,CONST CHAR_INFO *lpFill);
+ WINBASEAPI WINBOOL WINAPI ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,CONST SMALL_RECT *lpScrollRectangle,CONST SMALL_RECT *lpClipRectangle,COORD dwDestinationOrigin,CONST CHAR_INFO *lpFill);
+ WINBASEAPI WINBOOL WINAPI SetConsoleWindowInfo(HANDLE hConsoleOutput,WINBOOL bAbsolute,CONST SMALL_RECT *lpConsoleWindow);
+ WINBASEAPI WINBOOL WINAPI SetConsoleTextAttribute(HANDLE hConsoleOutput,WORD wAttributes);
+ WINBASEAPI WINBOOL WINAPI SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,WINBOOL Add);
+ WINBASEAPI WINBOOL WINAPI GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,DWORD dwProcessGroupId);
+ WINBASEAPI WINBOOL WINAPI AllocConsole(VOID);
+ WINBASEAPI WINBOOL WINAPI FreeConsole(VOID);
+ WINBASEAPI WINBOOL WINAPI AttachConsole(DWORD dwProcessId);
+
+#define ATTACH_PARENT_PROCESS ((DWORD)-1)
+
+ WINBASEAPI DWORD WINAPI GetConsoleTitleA(LPSTR lpConsoleTitle,DWORD nSize);
+ WINBASEAPI DWORD WINAPI GetConsoleTitleW(LPWSTR lpConsoleTitle,DWORD nSize);
+ WINBASEAPI WINBOOL WINAPI SetConsoleTitleA(LPCSTR lpConsoleTitle);
+ WINBASEAPI WINBOOL WINAPI SetConsoleTitleW(LPCWSTR lpConsoleTitle);
+ WINBASEAPI WINBOOL WINAPI ReadConsoleA(HANDLE hConsoleInput,LPVOID lpBuffer,DWORD nNumberOfCharsToRead,LPDWORD lpNumberOfCharsRead,LPVOID lpReserved);
+ WINBASEAPI WINBOOL WINAPI ReadConsoleW(HANDLE hConsoleInput,LPVOID lpBuffer,DWORD nNumberOfCharsToRead,LPDWORD lpNumberOfCharsRead,LPVOID lpReserved);
+ WINBASEAPI WINBOOL WINAPI WriteConsoleA(HANDLE hConsoleOutput,CONST VOID *lpBuffer,DWORD nNumberOfCharsToWrite,LPDWORD lpNumberOfCharsWritten,LPVOID lpReserved);
+ WINBASEAPI WINBOOL WINAPI WriteConsoleW(HANDLE hConsoleOutput,CONST VOID *lpBuffer,DWORD nNumberOfCharsToWrite,LPDWORD lpNumberOfCharsWritten,LPVOID lpReserved);
+
+#define CONSOLE_TEXTMODE_BUFFER 1
+
+ WINBASEAPI HANDLE WINAPI CreateConsoleScreenBuffer(DWORD dwDesiredAccess,DWORD dwShareMode,CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,DWORD dwFlags,LPVOID lpScreenBufferData);
+ WINBASEAPI UINT WINAPI GetConsoleCP(VOID);
+ WINBASEAPI WINBOOL WINAPI SetConsoleCP(UINT wCodePageID);
+ WINBASEAPI UINT WINAPI GetConsoleOutputCP(VOID);
+ WINBASEAPI WINBOOL WINAPI SetConsoleOutputCP(UINT wCodePageID);
+
+#define CONSOLE_FULLSCREEN 1
+#define CONSOLE_FULLSCREEN_HARDWARE 2
+
+ WINBASEAPI WINBOOL WINAPI GetConsoleDisplayMode(LPDWORD lpModeFlags);
+ WINBASEAPI HWND WINAPI GetConsoleWindow(VOID);
+ WINBASEAPI DWORD WINAPI GetConsoleProcessList(LPDWORD lpdwProcessList,DWORD dwProcessCount);
+ WINBASEAPI WINBOOL WINAPI AddConsoleAliasA(LPSTR Source,LPSTR Target,LPSTR ExeName);
+ WINBASEAPI WINBOOL WINAPI AddConsoleAliasW(LPWSTR Source,LPWSTR Target,LPWSTR ExeName);
+ WINBASEAPI DWORD WINAPI GetConsoleAliasA(LPSTR Source,LPSTR TargetBuffer,DWORD TargetBufferLength,LPSTR ExeName);
+ WINBASEAPI DWORD WINAPI GetConsoleAliasW(LPWSTR Source,LPWSTR TargetBuffer,DWORD TargetBufferLength,LPWSTR ExeName);
+ WINBASEAPI DWORD WINAPI GetConsoleAliasesLengthA(LPSTR ExeName);
+ WINBASEAPI DWORD WINAPI GetConsoleAliasesLengthW(LPWSTR ExeName);
+ WINBASEAPI DWORD WINAPI GetConsoleAliasExesLengthA(VOID);
+ WINBASEAPI DWORD WINAPI GetConsoleAliasExesLengthW(VOID);
+ WINBASEAPI DWORD WINAPI GetConsoleAliasesA(LPSTR AliasBuffer,DWORD AliasBufferLength,LPSTR ExeName);
+ WINBASEAPI DWORD WINAPI GetConsoleAliasesW(LPWSTR AliasBuffer,DWORD AliasBufferLength,LPWSTR ExeName);
+ WINBASEAPI DWORD WINAPI GetConsoleAliasExesA(LPSTR ExeNameBuffer,DWORD ExeNameBufferLength);
+ WINBASEAPI DWORD WINAPI GetConsoleAliasExesW(LPWSTR ExeNameBuffer,DWORD ExeNameBufferLength);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/include/winapi/windef.h b/win32/include/winapi/windef.h
new file mode 100644
index 0000000..d63bdef
--- /dev/null
+++ b/win32/include/winapi/windef.h
@@ -0,0 +1,293 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _WINDEF_
+#define _WINDEF_
+
+#ifndef STRICT
+#define STRICT 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WINVER
+#define WINVER 0x0502
+#endif
+
+#ifndef BASETYPES
+#define BASETYPES
+ typedef unsigned long ULONG;
+ typedef ULONG *PULONG;
+ typedef unsigned short USHORT;
+ typedef USHORT *PUSHORT;
+ typedef unsigned char UCHAR;
+ typedef UCHAR *PUCHAR;
+ typedef char *PSZ;
+#endif
+
+#define MAX_PATH 260
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef IN
+#define IN
+#endif
+
+#ifndef OUT
+#define OUT
+#endif
+
+#ifndef OPTIONAL
+#define OPTIONAL
+#endif
+
+#undef far
+#undef near
+#undef pascal
+
+#define far
+#define near
+#define pascal __stdcall
+
+#define cdecl
+#ifndef CDECL
+#define CDECL
+#endif
+#ifndef CALLBACK
+#define CALLBACK __stdcall
+#endif
+#ifndef WINAPI
+#define WINAPI __stdcall
+#endif
+#define WINAPIV __cdecl
+#define APIENTRY WINAPI
+#define APIPRIVATE WINAPI
+#define PASCAL WINAPI
+#define WINAPI_INLINE WINAPI
+
+#undef FAR
+#undef NEAR
+#define FAR
+#define NEAR
+#ifndef CONST
+#define CONST const
+#endif
+
+ typedef unsigned long DWORD;
+ typedef int WINBOOL;
+#define BOOL WINBOOL
+ typedef unsigned char BYTE;
+ typedef unsigned short WORD;
+ typedef float FLOAT;
+ typedef FLOAT *PFLOAT;
+ typedef WINBOOL *PBOOL;
+ typedef WINBOOL *LPBOOL;
+ typedef BYTE *PBYTE;
+ typedef BYTE *LPBYTE;
+ typedef int *PINT;
+ typedef int *LPINT;
+ typedef WORD *PWORD;
+ typedef WORD *LPWORD;
+ typedef long *LPLONG;
+ typedef DWORD *PDWORD;
+ typedef DWORD *LPDWORD;
+ typedef void *LPVOID;
+# ifndef _LPCVOID_DEFINED
+#define _LPCVOID_DEFINED
+typedef CONST void *LPCVOID;
+#endif
+ typedef int INT;
+ typedef unsigned int UINT;
+ typedef unsigned int *PUINT;
+
+#ifndef NT_INCLUDED
+#include <winnt.h>
+#endif
+
+//gr #include <specstrings.h>
+
+ typedef UINT_PTR WPARAM;
+ typedef LONG_PTR LPARAM;
+ typedef LONG_PTR LRESULT;
+
+#ifndef __cplusplus
+#ifndef NOMINMAX
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+#endif
+#endif
+
+#define MAKEWORD(a,b) ((WORD)(((BYTE)((DWORD_PTR)(a) & 0xff)) | ((WORD)((BYTE)((DWORD_PTR)(b) & 0xff))) << 8))
+#define MAKELONG(a,b) ((LONG)(((WORD)((DWORD_PTR)(a) & 0xffff)) | ((DWORD)((WORD)((DWORD_PTR)(b) & 0xffff))) << 16))
+#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xffff))
+#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16))
+#define LOBYTE(w) ((BYTE)((DWORD_PTR)(w) & 0xff))
+#define HIBYTE(w) ((BYTE)((DWORD_PTR)(w) >> 8))
+
+#ifndef WIN_INTERNAL
+ DECLARE_HANDLE (HWND);
+ DECLARE_HANDLE (HHOOK);
+#ifdef WINABLE
+ DECLARE_HANDLE (HEVENT);
+#endif
+#endif
+
+ typedef WORD ATOM;
+
+ typedef HANDLE *SPHANDLE;
+ typedef HANDLE *LPHANDLE;
+ typedef HANDLE HGLOBAL;
+ typedef HANDLE HLOCAL;
+ typedef HANDLE GLOBALHANDLE;
+ typedef HANDLE LOCALHANDLE;
+#ifdef _WIN64
+ typedef INT_PTR (WINAPI *FARPROC)();
+ typedef INT_PTR (WINAPI *NEARPROC)();
+ typedef INT_PTR (WINAPI *PROC)();
+#else
+ typedef int (WINAPI *FARPROC)();
+ typedef int (WINAPI *NEARPROC)();
+ typedef int (WINAPI *PROC)();
+#endif
+
+ typedef void *HGDIOBJ;
+
+ DECLARE_HANDLE(HKEY);
+ typedef HKEY *PHKEY;
+
+ DECLARE_HANDLE(HACCEL);
+ DECLARE_HANDLE(HBITMAP);
+ DECLARE_HANDLE(HBRUSH);
+ DECLARE_HANDLE(HCOLORSPACE);
+ DECLARE_HANDLE(HDC);
+ DECLARE_HANDLE(HGLRC);
+ DECLARE_HANDLE(HDESK);
+ DECLARE_HANDLE(HENHMETAFILE);
+ DECLARE_HANDLE(HFONT);
+ DECLARE_HANDLE(HICON);
+ DECLARE_HANDLE(HMENU);
+ DECLARE_HANDLE(HMETAFILE);
+ DECLARE_HANDLE(HINSTANCE);
+ typedef HINSTANCE HMODULE;
+ DECLARE_HANDLE(HPALETTE);
+ DECLARE_HANDLE(HPEN);
+ DECLARE_HANDLE(HRGN);
+ DECLARE_HANDLE(HRSRC);
+ DECLARE_HANDLE(HSTR);
+ DECLARE_HANDLE(HTASK);
+ DECLARE_HANDLE(HWINSTA);
+ DECLARE_HANDLE(HKL);
+ DECLARE_HANDLE(HMONITOR);
+ DECLARE_HANDLE(HWINEVENTHOOK);
+ DECLARE_HANDLE(HUMPD);
+
+ typedef int HFILE;
+ typedef HICON HCURSOR;
+ typedef DWORD COLORREF;
+ typedef DWORD *LPCOLORREF;
+
+#define HFILE_ERROR ((HFILE)-1)
+
+ typedef struct tagRECT {
+ LONG left;
+ LONG top;
+ LONG right;
+ LONG bottom;
+ } RECT,*PRECT,*NPRECT,*LPRECT;
+
+ typedef const RECT *LPCRECT;
+
+ typedef struct _RECTL {
+ LONG left;
+ LONG top;
+ LONG right;
+ LONG bottom;
+ } RECTL,*PRECTL,*LPRECTL;
+
+ typedef const RECTL *LPCRECTL;
+
+ typedef struct tagPOINT {
+ LONG x;
+ LONG y;
+ } POINT,*PPOINT,*NPPOINT,*LPPOINT;
+
+ typedef struct _POINTL {
+ LONG x;
+ LONG y;
+ } POINTL,*PPOINTL;
+
+ typedef struct tagSIZE {
+ LONG cx;
+ LONG cy;
+ } SIZE,*PSIZE,*LPSIZE;
+
+ typedef SIZE SIZEL;
+ typedef SIZE *PSIZEL,*LPSIZEL;
+
+ typedef struct tagPOINTS {
+ SHORT x;
+ SHORT y;
+ } POINTS,*PPOINTS,*LPPOINTS;
+
+ typedef struct _FILETIME {
+ DWORD dwLowDateTime;
+ DWORD dwHighDateTime;
+ } FILETIME,*PFILETIME,*LPFILETIME;
+#define _FILETIME_
+
+#define DM_UPDATE 1
+#define DM_COPY 2
+#define DM_PROMPT 4
+#define DM_MODIFY 8
+
+#define DM_IN_BUFFER DM_MODIFY
+#define DM_IN_PROMPT DM_PROMPT
+#define DM_OUT_BUFFER DM_COPY
+#define DM_OUT_DEFAULT DM_UPDATE
+
+#define DC_FIELDS 1
+#define DC_PAPERS 2
+#define DC_PAPERSIZE 3
+#define DC_MINEXTENT 4
+#define DC_MAXEXTENT 5
+#define DC_BINS 6
+#define DC_DUPLEX 7
+#define DC_SIZE 8
+#define DC_EXTRA 9
+#define DC_VERSION 10
+#define DC_DRIVER 11
+#define DC_BINNAMES 12
+#define DC_ENUMRESOLUTIONS 13
+#define DC_FILEDEPENDENCIES 14
+#define DC_TRUETYPE 15
+#define DC_PAPERNAMES 16
+#define DC_ORIENTATION 17
+#define DC_COPIES 18
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/include/winapi/windows.h b/win32/include/winapi/windows.h
new file mode 100644
index 0000000..2660d7f
--- /dev/null
+++ b/win32/include/winapi/windows.h
@@ -0,0 +1,127 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _WINDOWS_
+#define _WINDOWS_
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+
+#ifndef WINVER
+#define WINVER 0x0502
+#endif
+
+#include <_mingw.h>
+
+#ifndef _INC_WINDOWS
+#define _INC_WINDOWS
+
+#if defined(RC_INVOKED) && !defined(NOWINRES)
+
+#include <winresrc.h>
+#else
+
+#ifdef RC_INVOKED
+#define NOATOM
+#define NOGDI
+#define NOGDICAPMASKS
+#define NOMETAFILE
+#define NOMINMAX
+#define NOMSG
+#define NOOPENFILE
+#define NORASTEROPS
+#define NOSCROLL
+#define NOSOUND
+#define NOSYSMETRICS
+#define NOTEXTMETRIC
+#define NOWH
+#define NOCOMM
+#define NOKANJI
+#define NOCRYPT
+#define NOMCX
+#endif
+
+#if !defined(I_X86_) && !defined(_IA64_) && !defined(_AMD64_) && (defined(_X86_) && !defined(__x86_64))
+#define I_X86_
+#endif
+
+#if !defined(I_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(__x86_64)
+#define _AMD64_
+#endif
+
+#if !defined(I_X86_) && !(defined(_X86_) && !defined(__x86_64)) && !defined(_AMD64_) && defined(__ia64__)
+#if !defined(_IA64_)
+#define _IA64_
+#endif
+#endif
+
+#ifndef RC_INVOKED
+#include <excpt.h>
+#include <stdarg.h>
+#endif
+
+#include <windef.h>
+#include <winbase.h>
+#include <wingdi.h>
+#include <winuser.h>
+//gr #include <winnls.h>
+#include <wincon.h>
+#include <winver.h>
+#include <winreg.h>
+//gr #include <winnetwk.h>
+
+#ifndef WIN32_LEAN_AND_MEAN
+#include <cderr.h>
+#include <dde.h>
+#include <ddeml.h>
+#include <dlgs.h>
+#include <lzexpand.h>
+#include <mmsystem.h>
+#include <nb30.h>
+#include <rpc.h>
+#include <shellapi.h>
+#include <winperf.h>
+#include <winsock.h>
+#ifndef NOCRYPT
+#include <wincrypt.h>
+#include <winefs.h>
+#include <winscard.h>
+#endif
+
+#ifndef NOUSER
+#ifndef NOGDI
+#include <winspool.h>
+#ifdef INC_OLE1
+#include <ole.h>
+#else
+#include <ole2.h>
+#endif
+#include <commdlg.h>
+#endif
+#endif
+#endif
+
+//gr #include <stralign.h>
+
+#ifdef INC_OLE2
+#include <ole2.h>
+#endif
+
+#ifndef NOSERVICE
+#include <winsvc.h>
+#endif
+
+#ifndef NOMCX
+#include <mcx.h>
+#endif
+
+#ifndef NOIME
+#include <imm.h>
+#endif
+
+#endif
+#endif
+#endif
diff --git a/win32/include/winapi/winerror.h b/win32/include/winapi/winerror.h
new file mode 100644
index 0000000..77d85ed
--- /dev/null
+++ b/win32/include/winapi/winerror.h
@@ -0,0 +1,3166 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _WINERROR_
+#define _WINERROR_
+
+#define FACILITY_WINDOWSUPDATE 36
+#define FACILITY_WINDOWS_CE 24
+#define FACILITY_WINDOWS 8
+#define FACILITY_URT 19
+#define FACILITY_UMI 22
+#define FACILITY_SXS 23
+#define FACILITY_STORAGE 3
+#define FACILITY_STATE_MANAGEMENT 34
+#define FACILITY_SSPI 9
+#define FACILITY_SCARD 16
+#define FACILITY_SETUPAPI 15
+#define FACILITY_SECURITY 9
+#define FACILITY_RPC 1
+#define FACILITY_WIN32 7
+#define FACILITY_CONTROL 10
+#define FACILITY_NULL 0
+#define FACILITY_METADIRECTORY 35
+#define FACILITY_MSMQ 14
+#define FACILITY_MEDIASERVER 13
+#define FACILITY_INTERNET 12
+#define FACILITY_ITF 4
+#define FACILITY_HTTP 25
+#define FACILITY_DPLAY 21
+#define FACILITY_DISPATCH 2
+#define FACILITY_DIRECTORYSERVICE 37
+#define FACILITY_CONFIGURATION 33
+#define FACILITY_COMPLUS 17
+#define FACILITY_CERT 11
+#define FACILITY_BACKGROUNDCOPY 32
+#define FACILITY_ACS 20
+#define FACILITY_AAF 18
+#define ERROR_SUCCESS 0L
+#define NO_ERROR 0L
+#define SEC_E_OK ((HRESULT)0x00000000L)
+#define ERROR_INVALID_FUNCTION 1L
+#define ERROR_FILE_NOT_FOUND 2L
+#define ERROR_PATH_NOT_FOUND 3L
+#define ERROR_TOO_MANY_OPEN_FILES 4L
+#define ERROR_ACCESS_DENIED 5L
+#define ERROR_INVALID_HANDLE 6L
+#define ERROR_ARENA_TRASHED 7L
+#define ERROR_NOT_ENOUGH_MEMORY 8L
+#define ERROR_INVALID_BLOCK 9L
+#define ERROR_BAD_ENVIRONMENT 10L
+#define ERROR_BAD_FORMAT 11L
+#define ERROR_INVALID_ACCESS 12L
+#define ERROR_INVALID_DATA 13L
+#define ERROR_OUTOFMEMORY 14L
+#define ERROR_INVALID_DRIVE 15L
+#define ERROR_CURRENT_DIRECTORY 16L
+#define ERROR_NOT_SAME_DEVICE 17L
+#define ERROR_NO_MORE_FILES 18L
+#define ERROR_WRITE_PROTECT 19L
+#define ERROR_BAD_UNIT 20L
+#define ERROR_NOT_READY 21L
+#define ERROR_BAD_COMMAND 22L
+#define ERROR_CRC 23L
+#define ERROR_BAD_LENGTH 24L
+#define ERROR_SEEK 25L
+#define ERROR_NOT_DOS_DISK 26L
+#define ERROR_SECTOR_NOT_FOUND 27L
+#define ERROR_OUT_OF_PAPER 28L
+#define ERROR_WRITE_FAULT 29L
+#define ERROR_READ_FAULT 30L
+#define ERROR_GEN_FAILURE 31L
+#define ERROR_SHARING_VIOLATION 32L
+#define ERROR_LOCK_VIOLATION 33L
+#define ERROR_WRONG_DISK 34L
+#define ERROR_SHARING_BUFFER_EXCEEDED 36L
+#define ERROR_HANDLE_EOF 38L
+#define ERROR_HANDLE_DISK_FULL 39L
+#define ERROR_NOT_SUPPORTED 50L
+#define ERROR_REM_NOT_LIST 51L
+#define ERROR_DUP_NAME 52L
+#define ERROR_BAD_NETPATH 53L
+#define ERROR_NETWORK_BUSY 54L
+#define ERROR_DEV_NOT_EXIST 55L
+#define ERROR_TOO_MANY_CMDS 56L
+#define ERROR_ADAP_HDW_ERR 57L
+#define ERROR_BAD_NET_RESP 58L
+#define ERROR_UNEXP_NET_ERR 59L
+#define ERROR_BAD_REM_ADAP 60L
+#define ERROR_PRINTQ_FULL 61L
+#define ERROR_NO_SPOOL_SPACE 62L
+#define ERROR_PRINT_CANCELLED 63L
+#define ERROR_NETNAME_DELETED 64L
+#define ERROR_NETWORK_ACCESS_DENIED 65L
+#define ERROR_BAD_DEV_TYPE 66L
+#define ERROR_BAD_NET_NAME 67L
+#define ERROR_TOO_MANY_NAMES 68L
+#define ERROR_TOO_MANY_SESS 69L
+#define ERROR_SHARING_PAUSED 70L
+#define ERROR_REQ_NOT_ACCEP 71L
+#define ERROR_REDIR_PAUSED 72L
+#define ERROR_FILE_EXISTS 80L
+#define ERROR_CANNOT_MAKE 82L
+#define ERROR_FAIL_I24 83L
+#define ERROR_OUT_OF_STRUCTURES 84L
+#define ERROR_ALREADY_ASSIGNED 85L
+#define ERROR_INVALID_PASSWORD 86L
+#define ERROR_INVALID_PARAMETER 87L
+#define ERROR_NET_WRITE_FAULT 88L
+#define ERROR_NO_PROC_SLOTS 89L
+#define ERROR_TOO_MANY_SEMAPHORES 100L
+#define ERROR_EXCL_SEM_ALREADY_OWNED 101L
+#define ERROR_SEM_IS_SET 102L
+#define ERROR_TOO_MANY_SEM_REQUESTS 103L
+#define ERROR_INVALID_AT_INTERRUPT_TIME 104L
+#define ERROR_SEM_OWNER_DIED 105L
+#define ERROR_SEM_USER_LIMIT 106L
+#define ERROR_DISK_CHANGE 107L
+#define ERROR_DRIVE_LOCKED 108L
+#define ERROR_BROKEN_PIPE 109L
+#define ERROR_OPEN_FAILED 110L
+#define ERROR_BUFFER_OVERFLOW 111L
+#define ERROR_DISK_FULL 112L
+#define ERROR_NO_MORE_SEARCH_HANDLES 113L
+#define ERROR_INVALID_TARGET_HANDLE 114L
+#define ERROR_INVALID_CATEGORY 117L
+#define ERROR_INVALID_VERIFY_SWITCH 118L
+#define ERROR_BAD_DRIVER_LEVEL 119L
+#define ERROR_CALL_NOT_IMPLEMENTED 120L
+#define ERROR_SEM_TIMEOUT 121L
+#define ERROR_INSUFFICIENT_BUFFER 122L
+#define ERROR_INVALID_NAME 123L
+#define ERROR_INVALID_LEVEL 124L
+#define ERROR_NO_VOLUME_LABEL 125L
+#define ERROR_MOD_NOT_FOUND 126L
+#define ERROR_PROC_NOT_FOUND 127L
+#define ERROR_WAIT_NO_CHILDREN 128L
+#define ERROR_CHILD_NOT_COMPLETE 129L
+#define ERROR_DIRECT_ACCESS_HANDLE 130L
+#define ERROR_NEGATIVE_SEEK 131L
+#define ERROR_SEEK_ON_DEVICE 132L
+#define ERROR_IS_JOIN_TARGET 133L
+#define ERROR_IS_JOINED 134L
+#define ERROR_IS_SUBSTED 135L
+#define ERROR_NOT_JOINED 136L
+#define ERROR_NOT_SUBSTED 137L
+#define ERROR_JOIN_TO_JOIN 138L
+#define ERROR_SUBST_TO_SUBST 139L
+#define ERROR_JOIN_TO_SUBST 140L
+#define ERROR_SUBST_TO_JOIN 141L
+#define ERROR_BUSY_DRIVE 142L
+#define ERROR_SAME_DRIVE 143L
+#define ERROR_DIR_NOT_ROOT 144L
+#define ERROR_DIR_NOT_EMPTY 145L
+#define ERROR_IS_SUBST_PATH 146L
+#define ERROR_IS_JOIN_PATH 147L
+#define ERROR_PATH_BUSY 148L
+#define ERROR_IS_SUBST_TARGET 149L
+#define ERROR_SYSTEM_TRACE 150L
+#define ERROR_INVALID_EVENT_COUNT 151L
+#define ERROR_TOO_MANY_MUXWAITERS 152L
+#define ERROR_INVALID_LIST_FORMAT 153L
+#define ERROR_LABEL_TOO_LONG 154L
+#define ERROR_TOO_MANY_TCBS 155L
+#define ERROR_SIGNAL_REFUSED 156L
+#define ERROR_DISCARDED 157L
+#define ERROR_NOT_LOCKED 158L
+#define ERROR_BAD_THREADID_ADDR 159L
+#define ERROR_BAD_ARGUMENTS 160L
+#define ERROR_BAD_PATHNAME 161L
+#define ERROR_SIGNAL_PENDING 162L
+#define ERROR_MAX_THRDS_REACHED 164L
+#define ERROR_LOCK_FAILED 167L
+#define ERROR_BUSY 170L
+#define ERROR_CANCEL_VIOLATION 173L
+#define ERROR_ATOMIC_LOCKS_NOT_SUPPORTED 174L
+#define ERROR_INVALID_SEGMENT_NUMBER 180L
+#define ERROR_INVALID_ORDINAL 182L
+#define ERROR_ALREADY_EXISTS 183L
+#define ERROR_INVALID_FLAG_NUMBER 186L
+#define ERROR_SEM_NOT_FOUND 187L
+#define ERROR_INVALID_STARTING_CODESEG 188L
+#define ERROR_INVALID_STACKSEG 189L
+#define ERROR_INVALID_MODULETYPE 190L
+#define ERROR_INVALID_EXE_SIGNATURE 191L
+#define ERROR_EXE_MARKED_INVALID 192L
+#define ERROR_BAD_EXE_FORMAT 193L
+#define ERROR_ITERATED_DATA_EXCEEDS_64k 194L
+#define ERROR_INVALID_MINALLOCSIZE 195L
+#define ERROR_DYNLINK_FROM_INVALID_RING 196L
+#define ERROR_IOPL_NOT_ENABLED 197L
+#define ERROR_INVALID_SEGDPL 198L
+#define ERROR_AUTODATASEG_EXCEEDS_64k 199L
+#define ERROR_RING2SEG_MUST_BE_MOVABLE 200L
+#define ERROR_RELOC_CHAIN_XEEDS_SEGLIM 201L
+#define ERROR_INFLOOP_IN_RELOC_CHAIN 202L
+#define ERROR_ENVVAR_NOT_FOUND 203L
+#define ERROR_NO_SIGNAL_SENT 205L
+#define ERROR_FILENAME_EXCED_RANGE 206L
+#define ERROR_RING2_STACK_IN_USE 207L
+#define ERROR_META_EXPANSION_TOO_LONG 208L
+#define ERROR_INVALID_SIGNAL_NUMBER 209L
+#define ERROR_THREAD_1_INACTIVE 210L
+#define ERROR_LOCKED 212L
+#define ERROR_TOO_MANY_MODULES 214L
+#define ERROR_NESTING_NOT_ALLOWED 215L
+#define ERROR_EXE_MACHINE_TYPE_MISMATCH 216L
+#define ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY 217L
+#define ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY 218L
+#define ERROR_BAD_PIPE 230L
+#define ERROR_PIPE_BUSY 231L
+#define ERROR_NO_DATA 232L
+#define ERROR_PIPE_NOT_CONNECTED 233L
+#define ERROR_MORE_DATA 234L
+#define ERROR_VC_DISCONNECTED 240L
+#define ERROR_INVALID_EA_NAME 254L
+#define ERROR_EA_LIST_INCONSISTENT 255L
+#define WAIT_TIMEOUT 258L
+#define ERROR_NO_MORE_ITEMS 259L
+#define ERROR_CANNOT_COPY 266L
+#define ERROR_DIRECTORY 267L
+#define ERROR_EAS_DIDNT_FIT 275L
+#define ERROR_EA_FILE_CORRUPT 276L
+#define ERROR_EA_TABLE_FULL 277L
+#define ERROR_INVALID_EA_HANDLE 278L
+#define ERROR_EAS_NOT_SUPPORTED 282L
+#define ERROR_NOT_OWNER 288L
+#define ERROR_TOO_MANY_POSTS 298L
+#define ERROR_PARTIAL_COPY 299L
+#define ERROR_OPLOCK_NOT_GRANTED 300L
+#define ERROR_INVALID_OPLOCK_PROTOCOL 301L
+#define ERROR_DISK_TOO_FRAGMENTED 302L
+#define ERROR_DELETE_PENDING 303L
+#define ERROR_MR_MID_NOT_FOUND 317L
+#define ERROR_SCOPE_NOT_FOUND 318L
+#define ERROR_INVALID_ADDRESS 487L
+#define ERROR_ARITHMETIC_OVERFLOW 534L
+#define ERROR_PIPE_CONNECTED 535L
+#define ERROR_PIPE_LISTENING 536L
+#define ERROR_EA_ACCESS_DENIED 994L
+#define ERROR_OPERATION_ABORTED 995L
+#define ERROR_IO_INCOMPLETE 996L
+#define ERROR_IO_PENDING 997L
+#define ERROR_NOACCESS 998L
+#define ERROR_SWAPERROR 999L
+#define ERROR_STACK_OVERFLOW 1001L
+#define ERROR_INVALID_MESSAGE 1002L
+#define ERROR_CAN_NOT_COMPLETE 1003L
+#define ERROR_INVALID_FLAGS 1004L
+#define ERROR_UNRECOGNIZED_VOLUME 1005L
+#define ERROR_FILE_INVALID 1006L
+#define ERROR_FULLSCREEN_MODE 1007L
+#define ERROR_NO_TOKEN 1008L
+#define ERROR_BADDB 1009L
+#define ERROR_BADKEY 1010L
+#define ERROR_CANTOPEN 1011L
+#define ERROR_CANTREAD 1012L
+#define ERROR_CANTWRITE 1013L
+#define ERROR_REGISTRY_RECOVERED 1014L
+#define ERROR_REGISTRY_CORRUPT 1015L
+#define ERROR_REGISTRY_IO_FAILED 1016L
+#define ERROR_NOT_REGISTRY_FILE 1017L
+#define ERROR_KEY_DELETED 1018L
+#define ERROR_NO_LOG_SPACE 1019L
+#define ERROR_KEY_HAS_CHILDREN 1020L
+#define ERROR_CHILD_MUST_BE_VOLATILE 1021L
+#define ERROR_NOTIFY_ENUM_DIR 1022L
+#define ERROR_DEPENDENT_SERVICES_RUNNING 1051L
+#define ERROR_INVALID_SERVICE_CONTROL 1052L
+#define ERROR_SERVICE_REQUEST_TIMEOUT 1053L
+#define ERROR_SERVICE_NO_THREAD 1054L
+#define ERROR_SERVICE_DATABASE_LOCKED 1055L
+#define ERROR_SERVICE_ALREADY_RUNNING 1056L
+#define ERROR_INVALID_SERVICE_ACCOUNT 1057L
+#define ERROR_SERVICE_DISABLED 1058L
+#define ERROR_CIRCULAR_DEPENDENCY 1059L
+#define ERROR_SERVICE_DOES_NOT_EXIST 1060L
+#define ERROR_SERVICE_CANNOT_ACCEPT_CTRL 1061L
+#define ERROR_SERVICE_NOT_ACTIVE 1062L
+#define ERROR_FAILED_SERVICE_CONTROLLER_CONNECT 1063L
+#define ERROR_EXCEPTION_IN_SERVICE 1064L
+#define ERROR_DATABASE_DOES_NOT_EXIST 1065L
+#define ERROR_SERVICE_SPECIFIC_ERROR 1066L
+#define ERROR_PROCESS_ABORTED 1067L
+#define ERROR_SERVICE_DEPENDENCY_FAIL 1068L
+#define ERROR_SERVICE_LOGON_FAILED 1069L
+#define ERROR_SERVICE_START_HANG 1070L
+#define ERROR_INVALID_SERVICE_LOCK 1071L
+#define ERROR_SERVICE_MARKED_FOR_DELETE 1072L
+#define ERROR_SERVICE_EXISTS 1073L
+#define ERROR_ALREADY_RUNNING_LKG 1074L
+#define ERROR_SERVICE_DEPENDENCY_DELETED 1075L
+#define ERROR_BOOT_ALREADY_ACCEPTED 1076L
+#define ERROR_SERVICE_NEVER_STARTED 1077L
+#define ERROR_DUPLICATE_SERVICE_NAME 1078L
+#define ERROR_DIFFERENT_SERVICE_ACCOUNT 1079L
+#define ERROR_CANNOT_DETECT_DRIVER_FAILURE 1080L
+#define ERROR_CANNOT_DETECT_PROCESS_ABORT 1081L
+#define ERROR_NO_RECOVERY_PROGRAM 1082L
+#define ERROR_SERVICE_NOT_IN_EXE 1083L
+#define ERROR_NOT_SAFEBOOT_SERVICE 1084L
+#define ERROR_END_OF_MEDIA 1100L
+#define ERROR_FILEMARK_DETECTED 1101L
+#define ERROR_BEGINNING_OF_MEDIA 1102L
+#define ERROR_SETMARK_DETECTED 1103L
+#define ERROR_NO_DATA_DETECTED 1104L
+#define ERROR_PARTITION_FAILURE 1105L
+#define ERROR_INVALID_BLOCK_LENGTH 1106L
+#define ERROR_DEVICE_NOT_PARTITIONED 1107L
+#define ERROR_UNABLE_TO_LOCK_MEDIA 1108L
+#define ERROR_UNABLE_TO_UNLOAD_MEDIA 1109L
+#define ERROR_MEDIA_CHANGED 1110L
+#define ERROR_BUS_RESET 1111L
+#define ERROR_NO_MEDIA_IN_DRIVE 1112L
+#define ERROR_NO_UNICODE_TRANSLATION 1113L
+#define ERROR_DLL_INIT_FAILED 1114L
+#define ERROR_SHUTDOWN_IN_PROGRESS 1115L
+#define ERROR_NO_SHUTDOWN_IN_PROGRESS 1116L
+#define ERROR_IO_DEVICE 1117L
+#define ERROR_SERIAL_NO_DEVICE 1118L
+#define ERROR_IRQ_BUSY 1119L
+#define ERROR_MORE_WRITES 1120L
+#define ERROR_COUNTER_TIMEOUT 1121L
+#define ERROR_FLOPPY_ID_MARK_NOT_FOUND 1122L
+#define ERROR_FLOPPY_WRONG_CYLINDER 1123L
+#define ERROR_FLOPPY_UNKNOWN_ERROR 1124L
+#define ERROR_FLOPPY_BAD_REGISTERS 1125L
+#define ERROR_DISK_RECALIBRATE_FAILED 1126L
+#define ERROR_DISK_OPERATION_FAILED 1127L
+#define ERROR_DISK_RESET_FAILED 1128L
+#define ERROR_EOM_OVERFLOW 1129L
+#define ERROR_NOT_ENOUGH_SERVER_MEMORY 1130L
+#define ERROR_POSSIBLE_DEADLOCK 1131L
+#define ERROR_MAPPED_ALIGNMENT 1132L
+#define ERROR_SET_POWER_STATE_VETOED 1140L
+#define ERROR_SET_POWER_STATE_FAILED 1141L
+#define ERROR_TOO_MANY_LINKS 1142L
+#define ERROR_OLD_WIN_VERSION 1150L
+#define ERROR_APP_WRONG_OS 1151L
+#define ERROR_SINGLE_INSTANCE_APP 1152L
+#define ERROR_RMODE_APP 1153L
+#define ERROR_INVALID_DLL 1154L
+#define ERROR_NO_ASSOCIATION 1155L
+#define ERROR_DDE_FAIL 1156L
+#define ERROR_DLL_NOT_FOUND 1157L
+#define ERROR_NO_MORE_USER_HANDLES 1158L
+#define ERROR_MESSAGE_SYNC_ONLY 1159L
+#define ERROR_SOURCE_ELEMENT_EMPTY 1160L
+#define ERROR_DESTINATION_ELEMENT_FULL 1161L
+#define ERROR_ILLEGAL_ELEMENT_ADDRESS 1162L
+#define ERROR_MAGAZINE_NOT_PRESENT 1163L
+#define ERROR_DEVICE_REINITIALIZATION_NEEDED 1164L
+#define ERROR_DEVICE_REQUIRES_CLEANING 1165L
+#define ERROR_DEVICE_DOOR_OPEN 1166L
+#define ERROR_DEVICE_NOT_CONNECTED 1167L
+#define ERROR_NOT_FOUND 1168L
+#define ERROR_NO_MATCH 1169L
+#define ERROR_SET_NOT_FOUND 1170L
+#define ERROR_POINT_NOT_FOUND 1171L
+#define ERROR_NO_TRACKING_SERVICE 1172L
+#define ERROR_NO_VOLUME_ID 1173L
+#define ERROR_UNABLE_TO_REMOVE_REPLACED 1175L
+#define ERROR_UNABLE_TO_MOVE_REPLACEMENT 1176L
+#define ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 1177L
+#define ERROR_JOURNAL_DELETE_IN_PROGRESS 1178L
+#define ERROR_JOURNAL_NOT_ACTIVE 1179L
+#define ERROR_POTENTIAL_FILE_FOUND 1180L
+#define ERROR_JOURNAL_ENTRY_DELETED 1181L
+#define ERROR_BAD_DEVICE 1200L
+#define ERROR_CONNECTION_UNAVAIL 1201L
+#define ERROR_DEVICE_ALREADY_REMEMBERED 1202L
+#define ERROR_NO_NET_OR_BAD_PATH 1203L
+#define ERROR_BAD_PROVIDER 1204L
+#define ERROR_CANNOT_OPEN_PROFILE 1205L
+#define ERROR_BAD_PROFILE 1206L
+#define ERROR_NOT_CONTAINER 1207L
+#define ERROR_EXTENDED_ERROR 1208L
+#define ERROR_INVALID_GROUPNAME 1209L
+#define ERROR_INVALID_COMPUTERNAME 1210L
+#define ERROR_INVALID_EVENTNAME 1211L
+#define ERROR_INVALID_DOMAINNAME 1212L
+#define ERROR_INVALID_SERVICENAME 1213L
+#define ERROR_INVALID_NETNAME 1214L
+#define ERROR_INVALID_SHARENAME 1215L
+#define ERROR_INVALID_PASSWORDNAME 1216L
+#define ERROR_INVALID_MESSAGENAME 1217L
+#define ERROR_INVALID_MESSAGEDEST 1218L
+#define ERROR_SESSION_CREDENTIAL_CONFLICT 1219L
+#define ERROR_REMOTE_SESSION_LIMIT_EXCEEDED 1220L
+#define ERROR_DUP_DOMAINNAME 1221L
+#define ERROR_NO_NETWORK 1222L
+#define ERROR_CANCELLED 1223L
+#define ERROR_USER_MAPPED_FILE 1224L
+#define ERROR_CONNECTION_REFUSED 1225L
+#define ERROR_GRACEFUL_DISCONNECT 1226L
+#define ERROR_ADDRESS_ALREADY_ASSOCIATED 1227L
+#define ERROR_ADDRESS_NOT_ASSOCIATED 1228L
+#define ERROR_CONNECTION_INVALID 1229L
+#define ERROR_CONNECTION_ACTIVE 1230L
+#define ERROR_NETWORK_UNREACHABLE 1231L
+#define ERROR_HOST_UNREACHABLE 1232L
+#define ERROR_PROTOCOL_UNREACHABLE 1233L
+#define ERROR_PORT_UNREACHABLE 1234L
+#define ERROR_REQUEST_ABORTED 1235L
+#define ERROR_CONNECTION_ABORTED 1236L
+#define ERROR_RETRY 1237L
+#define ERROR_CONNECTION_COUNT_LIMIT 1238L
+#define ERROR_LOGIN_TIME_RESTRICTION 1239L
+#define ERROR_LOGIN_WKSTA_RESTRICTION 1240L
+#define ERROR_INCORRECT_ADDRESS 1241L
+#define ERROR_ALREADY_REGISTERED 1242L
+#define ERROR_SERVICE_NOT_FOUND 1243L
+#define ERROR_NOT_AUTHENTICATED 1244L
+#define ERROR_NOT_LOGGED_ON 1245L
+#define ERROR_CONTINUE 1246L
+#define ERROR_ALREADY_INITIALIZED 1247L
+#define ERROR_NO_MORE_DEVICES 1248L
+#define ERROR_NO_SUCH_SITE 1249L
+#define ERROR_DOMAIN_CONTROLLER_EXISTS 1250L
+#define ERROR_ONLY_IF_CONNECTED 1251L
+#define ERROR_OVERRIDE_NOCHANGES 1252L
+#define ERROR_BAD_USER_PROFILE 1253L
+#define ERROR_NOT_SUPPORTED_ON_SBS 1254L
+#define ERROR_SERVER_SHUTDOWN_IN_PROGRESS 1255L
+#define ERROR_HOST_DOWN 1256L
+#define ERROR_NON_ACCOUNT_SID 1257L
+#define ERROR_NON_DOMAIN_SID 1258L
+#define ERROR_APPHELP_BLOCK 1259L
+#define ERROR_ACCESS_DISABLED_BY_POLICY 1260L
+#define ERROR_REG_NAT_CONSUMPTION 1261L
+#define ERROR_CSCSHARE_OFFLINE 1262L
+#define ERROR_PKINIT_FAILURE 1263L
+#define ERROR_SMARTCARD_SUBSYSTEM_FAILURE 1264L
+#define ERROR_DOWNGRADE_DETECTED 1265L
+#define ERROR_MACHINE_LOCKED 1271L
+#define ERROR_CALLBACK_SUPPLIED_INVALID_DATA 1273L
+#define ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED 1274L
+#define ERROR_DRIVER_BLOCKED 1275L
+#define ERROR_INVALID_IMPORT_OF_NON_DLL 1276L
+#define ERROR_ACCESS_DISABLED_WEBBLADE 1277L
+#define ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER 1278L
+#define ERROR_RECOVERY_FAILURE 1279L
+#define ERROR_ALREADY_FIBER 1280L
+#define ERROR_ALREADY_THREAD 1281L
+#define ERROR_STACK_BUFFER_OVERRUN 1282L
+#define ERROR_PARAMETER_QUOTA_EXCEEDED 1283L
+#define ERROR_DEBUGGER_INACTIVE 1284L
+#define ERROR_DELAY_LOAD_FAILED 1285L
+#define ERROR_VDM_DISALLOWED 1286L
+#define ERROR_UNIDENTIFIED_ERROR 1287L
+#define ERROR_NOT_ALL_ASSIGNED 1300L
+#define ERROR_SOME_NOT_MAPPED 1301L
+#define ERROR_NO_QUOTAS_FOR_ACCOUNT 1302L
+#define ERROR_LOCAL_USER_SESSION_KEY 1303L
+#define ERROR_NULL_LM_PASSWORD 1304L
+#define ERROR_UNKNOWN_REVISION 1305L
+#define ERROR_REVISION_MISMATCH 1306L
+#define ERROR_INVALID_OWNER 1307L
+#define ERROR_INVALID_PRIMARY_GROUP 1308L
+#define ERROR_NO_IMPERSONATION_TOKEN 1309L
+#define ERROR_CANT_DISABLE_MANDATORY 1310L
+#define ERROR_NO_LOGON_SERVERS 1311L
+#define ERROR_NO_SUCH_LOGON_SESSION 1312L
+#define ERROR_NO_SUCH_PRIVILEGE 1313L
+#define ERROR_PRIVILEGE_NOT_HELD 1314L
+#define ERROR_INVALID_ACCOUNT_NAME 1315L
+#define ERROR_USER_EXISTS 1316L
+#define ERROR_NO_SUCH_USER 1317L
+#define ERROR_GROUP_EXISTS 1318L
+#define ERROR_NO_SUCH_GROUP 1319L
+#define ERROR_MEMBER_IN_GROUP 1320L
+#define ERROR_MEMBER_NOT_IN_GROUP 1321L
+#define ERROR_LAST_ADMIN 1322L
+#define ERROR_WRONG_PASSWORD 1323L
+#define ERROR_ILL_FORMED_PASSWORD 1324L
+#define ERROR_PASSWORD_RESTRICTION 1325L
+#define ERROR_LOGON_FAILURE 1326L
+#define ERROR_ACCOUNT_RESTRICTION 1327L
+#define ERROR_INVALID_LOGON_HOURS 1328L
+#define ERROR_INVALID_WORKSTATION 1329L
+#define ERROR_PASSWORD_EXPIRED 1330L
+#define ERROR_ACCOUNT_DISABLED 1331L
+#define ERROR_NONE_MAPPED 1332L
+#define ERROR_TOO_MANY_LUIDS_REQUESTED 1333L
+#define ERROR_LUIDS_EXHAUSTED 1334L
+#define ERROR_INVALID_SUB_AUTHORITY 1335L
+#define ERROR_INVALID_ACL 1336L
+#define ERROR_INVALID_SID 1337L
+#define ERROR_INVALID_SECURITY_DESCR 1338L
+#define ERROR_BAD_INHERITANCE_ACL 1340L
+#define ERROR_SERVER_DISABLED 1341L
+#define ERROR_SERVER_NOT_DISABLED 1342L
+#define ERROR_INVALID_ID_AUTHORITY 1343L
+#define ERROR_ALLOTTED_SPACE_EXCEEDED 1344L
+#define ERROR_INVALID_GROUP_ATTRIBUTES 1345L
+#define ERROR_BAD_IMPERSONATION_LEVEL 1346L
+#define ERROR_CANT_OPEN_ANONYMOUS 1347L
+#define ERROR_BAD_VALIDATION_CLASS 1348L
+#define ERROR_BAD_TOKEN_TYPE 1349L
+#define ERROR_NO_SECURITY_ON_OBJECT 1350L
+#define ERROR_CANT_ACCESS_DOMAIN_INFO 1351L
+#define ERROR_INVALID_SERVER_STATE 1352L
+#define ERROR_INVALID_DOMAIN_STATE 1353L
+#define ERROR_INVALID_DOMAIN_ROLE 1354L
+#define ERROR_NO_SUCH_DOMAIN 1355L
+#define ERROR_DOMAIN_EXISTS 1356L
+#define ERROR_DOMAIN_LIMIT_EXCEEDED 1357L
+#define ERROR_INTERNAL_DB_CORRUPTION 1358L
+#define ERROR_INTERNAL_ERROR 1359L
+#define ERROR_GENERIC_NOT_MAPPED 1360L
+#define ERROR_BAD_DESCRIPTOR_FORMAT 1361L
+#define ERROR_NOT_LOGON_PROCESS 1362L
+#define ERROR_LOGON_SESSION_EXISTS 1363L
+#define ERROR_NO_SUCH_PACKAGE 1364L
+#define ERROR_BAD_LOGON_SESSION_STATE 1365L
+#define ERROR_LOGON_SESSION_COLLISION 1366L
+#define ERROR_INVALID_LOGON_TYPE 1367L
+#define ERROR_CANNOT_IMPERSONATE 1368L
+#define ERROR_RXACT_INVALID_STATE 1369L
+#define ERROR_RXACT_COMMIT_FAILURE 1370L
+#define ERROR_SPECIAL_ACCOUNT 1371L
+#define ERROR_SPECIAL_GROUP 1372L
+#define ERROR_SPECIAL_USER 1373L
+#define ERROR_MEMBERS_PRIMARY_GROUP 1374L
+#define ERROR_TOKEN_ALREADY_IN_USE 1375L
+#define ERROR_NO_SUCH_ALIAS 1376L
+#define ERROR_MEMBER_NOT_IN_ALIAS 1377L
+#define ERROR_MEMBER_IN_ALIAS 1378L
+#define ERROR_ALIAS_EXISTS 1379L
+#define ERROR_LOGON_NOT_GRANTED 1380L
+#define ERROR_TOO_MANY_SECRETS 1381L
+#define ERROR_SECRET_TOO_LONG 1382L
+#define ERROR_INTERNAL_DB_ERROR 1383L
+#define ERROR_TOO_MANY_CONTEXT_IDS 1384L
+#define ERROR_LOGON_TYPE_NOT_GRANTED 1385L
+#define ERROR_NT_CROSS_ENCRYPTION_REQUIRED 1386L
+#define ERROR_NO_SUCH_MEMBER 1387L
+#define ERROR_INVALID_MEMBER 1388L
+#define ERROR_TOO_MANY_SIDS 1389L
+#define ERROR_LM_CROSS_ENCRYPTION_REQUIRED 1390L
+#define ERROR_NO_INHERITANCE 1391L
+#define ERROR_FILE_CORRUPT 1392L
+#define ERROR_DISK_CORRUPT 1393L
+#define ERROR_NO_USER_SESSION_KEY 1394L
+#define ERROR_LICENSE_QUOTA_EXCEEDED 1395L
+#define ERROR_WRONG_TARGET_NAME 1396L
+#define ERROR_MUTUAL_AUTH_FAILED 1397L
+#define ERROR_TIME_SKEW 1398L
+#define ERROR_CURRENT_DOMAIN_NOT_ALLOWED 1399L
+#define ERROR_INVALID_WINDOW_HANDLE 1400L
+#define ERROR_INVALID_MENU_HANDLE 1401L
+#define ERROR_INVALID_CURSOR_HANDLE 1402L
+#define ERROR_INVALID_ACCEL_HANDLE 1403L
+#define ERROR_INVALID_HOOK_HANDLE 1404L
+#define ERROR_INVALID_DWP_HANDLE 1405L
+#define ERROR_TLW_WITH_WSCHILD 1406L
+#define ERROR_CANNOT_FIND_WND_CLASS 1407L
+#define ERROR_WINDOW_OF_OTHER_THREAD 1408L
+#define ERROR_HOTKEY_ALREADY_REGISTERED 1409L
+#define ERROR_CLASS_ALREADY_EXISTS 1410L
+#define ERROR_CLASS_DOES_NOT_EXIST 1411L
+#define ERROR_CLASS_HAS_WINDOWS 1412L
+#define ERROR_INVALID_INDEX 1413L
+#define ERROR_INVALID_ICON_HANDLE 1414L
+#define ERROR_PRIVATE_DIALOG_INDEX 1415L
+#define ERROR_LISTBOX_ID_NOT_FOUND 1416L
+#define ERROR_NO_WILDCARD_CHARACTERS 1417L
+#define ERROR_CLIPBOARD_NOT_OPEN 1418L
+#define ERROR_HOTKEY_NOT_REGISTERED 1419L
+#define ERROR_WINDOW_NOT_DIALOG 1420L
+#define ERROR_CONTROL_ID_NOT_FOUND 1421L
+#define ERROR_INVALID_COMBOBOX_MESSAGE 1422L
+#define ERROR_WINDOW_NOT_COMBOBOX 1423L
+#define ERROR_INVALID_EDIT_HEIGHT 1424L
+#define ERROR_DC_NOT_FOUND 1425L
+#define ERROR_INVALID_HOOK_FILTER 1426L
+#define ERROR_INVALID_FILTER_PROC 1427L
+#define ERROR_HOOK_NEEDS_HMOD 1428L
+#define ERROR_GLOBAL_ONLY_HOOK 1429L
+#define ERROR_JOURNAL_HOOK_SET 1430L
+#define ERROR_HOOK_NOT_INSTALLED 1431L
+#define ERROR_INVALID_LB_MESSAGE 1432L
+#define ERROR_SETCOUNT_ON_BAD_LB 1433L
+#define ERROR_LB_WITHOUT_TABSTOPS 1434L
+#define ERROR_DESTROY_OBJECT_OF_OTHER_THREAD 1435L
+#define ERROR_CHILD_WINDOW_MENU 1436L
+#define ERROR_NO_SYSTEM_MENU 1437L
+#define ERROR_INVALID_MSGBOX_STYLE 1438L
+#define ERROR_INVALID_SPI_VALUE 1439L
+#define ERROR_SCREEN_ALREADY_LOCKED 1440L
+#define ERROR_HWNDS_HAVE_DIFF_PARENT 1441L
+#define ERROR_NOT_CHILD_WINDOW 1442L
+#define ERROR_INVALID_GW_COMMAND 1443L
+#define ERROR_INVALID_THREAD_ID 1444L
+#define ERROR_NON_MDICHILD_WINDOW 1445L
+#define ERROR_POPUP_ALREADY_ACTIVE 1446L
+#define ERROR_NO_SCROLLBARS 1447L
+#define ERROR_INVALID_SCROLLBAR_RANGE 1448L
+#define ERROR_INVALID_SHOWWIN_COMMAND 1449L
+#define ERROR_NO_SYSTEM_RESOURCES 1450L
+#define ERROR_NONPAGED_SYSTEM_RESOURCES 1451L
+#define ERROR_PAGED_SYSTEM_RESOURCES 1452L
+#define ERROR_WORKING_SET_QUOTA 1453L
+#define ERROR_PAGEFILE_QUOTA 1454L
+#define ERROR_COMMITMENT_LIMIT 1455L
+#define ERROR_MENU_ITEM_NOT_FOUND 1456L
+#define ERROR_INVALID_KEYBOARD_HANDLE 1457L
+#define ERROR_HOOK_TYPE_NOT_ALLOWED 1458L
+#define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION 1459L
+#define ERROR_TIMEOUT 1460L
+#define ERROR_INVALID_MONITOR_HANDLE 1461L
+#define ERROR_INCORRECT_SIZE 1462L
+#define ERROR_EVENTLOG_FILE_CORRUPT 1500L
+#define ERROR_EVENTLOG_CANT_START 1501L
+#define ERROR_LOG_FILE_FULL 1502L
+#define ERROR_EVENTLOG_FILE_CHANGED 1503L
+#define ERROR_INSTALL_SERVICE_FAILURE 1601L
+#define ERROR_INSTALL_USEREXIT 1602L
+#define ERROR_INSTALL_FAILURE 1603L
+#define ERROR_INSTALL_SUSPEND 1604L
+#define ERROR_UNKNOWN_PRODUCT 1605L
+#define ERROR_UNKNOWN_FEATURE 1606L
+#define ERROR_UNKNOWN_COMPONENT 1607L
+#define ERROR_UNKNOWN_PROPERTY 1608L
+#define ERROR_INVALID_HANDLE_STATE 1609L
+#define ERROR_BAD_CONFIGURATION 1610L
+#define ERROR_INDEX_ABSENT 1611L
+#define ERROR_INSTALL_SOURCE_ABSENT 1612L
+#define ERROR_INSTALL_PACKAGE_VERSION 1613L
+#define ERROR_PRODUCT_UNINSTALLED 1614L
+#define ERROR_BAD_QUERY_SYNTAX 1615L
+#define ERROR_INVALID_FIELD 1616L
+#define ERROR_DEVICE_REMOVED 1617L
+#define ERROR_INSTALL_ALREADY_RUNNING 1618L
+#define ERROR_INSTALL_PACKAGE_OPEN_FAILED 1619L
+#define ERROR_INSTALL_PACKAGE_INVALID 1620L
+#define ERROR_INSTALL_UI_FAILURE 1621L
+#define ERROR_INSTALL_LOG_FAILURE 1622L
+#define ERROR_INSTALL_LANGUAGE_UNSUPPORTED 1623L
+#define ERROR_INSTALL_TRANSFORM_FAILURE 1624L
+#define ERROR_INSTALL_PACKAGE_REJECTED 1625L
+#define ERROR_FUNCTION_NOT_CALLED 1626L
+#define ERROR_FUNCTION_FAILED 1627L
+#define ERROR_INVALID_TABLE 1628L
+#define ERROR_DATATYPE_MISMATCH 1629L
+#define ERROR_UNSUPPORTED_TYPE 1630L
+#define ERROR_CREATE_FAILED 1631L
+#define ERROR_INSTALL_TEMP_UNWRITABLE 1632L
+#define ERROR_INSTALL_PLATFORM_UNSUPPORTED 1633L
+#define ERROR_INSTALL_NOTUSED 1634L
+#define ERROR_PATCH_PACKAGE_OPEN_FAILED 1635L
+#define ERROR_PATCH_PACKAGE_INVALID 1636L
+#define ERROR_PATCH_PACKAGE_UNSUPPORTED 1637L
+#define ERROR_PRODUCT_VERSION 1638L
+#define ERROR_INVALID_COMMAND_LINE 1639L
+#define ERROR_INSTALL_REMOTE_DISALLOWED 1640L
+#define ERROR_SUCCESS_REBOOT_INITIATED 1641L
+#define ERROR_PATCH_TARGET_NOT_FOUND 1642L
+#define ERROR_PATCH_PACKAGE_REJECTED 1643L
+#define ERROR_INSTALL_TRANSFORM_REJECTED 1644L
+#define ERROR_INSTALL_REMOTE_PROHIBITED 1645L
+#define RPC_S_INVALID_STRING_BINDING 1700L
+#define RPC_S_WRONG_KIND_OF_BINDING 1701L
+#define RPC_S_INVALID_BINDING 1702L
+#define RPC_S_PROTSEQ_NOT_SUPPORTED 1703L
+#define RPC_S_INVALID_RPC_PROTSEQ 1704L
+#define RPC_S_INVALID_STRING_UUID 1705L
+#define RPC_S_INVALID_ENDPOINT_FORMAT 1706L
+#define RPC_S_INVALID_NET_ADDR 1707L
+#define RPC_S_NO_ENDPOINT_FOUND 1708L
+#define RPC_S_INVALID_TIMEOUT 1709L
+#define RPC_S_OBJECT_NOT_FOUND 1710L
+#define RPC_S_ALREADY_REGISTERED 1711L
+#define RPC_S_TYPE_ALREADY_REGISTERED 1712L
+#define RPC_S_ALREADY_LISTENING 1713L
+#define RPC_S_NO_PROTSEQS_REGISTERED 1714L
+#define RPC_S_NOT_LISTENING 1715L
+#define RPC_S_UNKNOWN_MGR_TYPE 1716L
+#define RPC_S_UNKNOWN_IF 1717L
+#define RPC_S_NO_BINDINGS 1718L
+#define RPC_S_NO_PROTSEQS 1719L
+#define RPC_S_CANT_CREATE_ENDPOINT 1720L
+#define RPC_S_OUT_OF_RESOURCES 1721L
+#define RPC_S_SERVER_UNAVAILABLE 1722L
+#define RPC_S_SERVER_TOO_BUSY 1723L
+#define RPC_S_INVALID_NETWORK_OPTIONS 1724L
+#define RPC_S_NO_CALL_ACTIVE 1725L
+#define RPC_S_CALL_FAILED 1726L
+#define RPC_S_CALL_FAILED_DNE 1727L
+#define RPC_S_PROTOCOL_ERROR 1728L
+#define RPC_S_UNSUPPORTED_TRANS_SYN 1730L
+#define RPC_S_UNSUPPORTED_TYPE 1732L
+#define RPC_S_INVALID_TAG 1733L
+#define RPC_S_INVALID_BOUND 1734L
+#define RPC_S_NO_ENTRY_NAME 1735L
+#define RPC_S_INVALID_NAME_SYNTAX 1736L
+#define RPC_S_UNSUPPORTED_NAME_SYNTAX 1737L
+#define RPC_S_UUID_NO_ADDRESS 1739L
+#define RPC_S_DUPLICATE_ENDPOINT 1740L
+#define RPC_S_UNKNOWN_AUTHN_TYPE 1741L
+#define RPC_S_MAX_CALLS_TOO_SMALL 1742L
+#define RPC_S_STRING_TOO_LONG 1743L
+#define RPC_S_PROTSEQ_NOT_FOUND 1744L
+#define RPC_S_PROCNUM_OUT_OF_RANGE 1745L
+#define RPC_S_BINDING_HAS_NO_AUTH 1746L
+#define RPC_S_UNKNOWN_AUTHN_SERVICE 1747L
+#define RPC_S_UNKNOWN_AUTHN_LEVEL 1748L
+#define RPC_S_INVALID_AUTH_IDENTITY 1749L
+#define RPC_S_UNKNOWN_AUTHZ_SERVICE 1750L
+#define EPT_S_INVALID_ENTRY 1751L
+#define EPT_S_CANT_PERFORM_OP 1752L
+#define EPT_S_NOT_REGISTERED 1753L
+#define RPC_S_NOTHING_TO_EXPORT 1754L
+#define RPC_S_INCOMPLETE_NAME 1755L
+#define RPC_S_INVALID_VERS_OPTION 1756L
+#define RPC_S_NO_MORE_MEMBERS 1757L
+#define RPC_S_NOT_ALL_OBJS_UNEXPORTED 1758L
+#define RPC_S_INTERFACE_NOT_FOUND 1759L
+#define RPC_S_ENTRY_ALREADY_EXISTS 1760L
+#define RPC_S_ENTRY_NOT_FOUND 1761L
+#define RPC_S_NAME_SERVICE_UNAVAILABLE 1762L
+#define RPC_S_INVALID_NAF_ID 1763L
+#define RPC_S_CANNOT_SUPPORT 1764L
+#define RPC_S_NO_CONTEXT_AVAILABLE 1765L
+#define RPC_S_INTERNAL_ERROR 1766L
+#define RPC_S_ZERO_DIVIDE 1767L
+#define RPC_S_ADDRESS_ERROR 1768L
+#define RPC_S_FP_DIV_ZERO 1769L
+#define RPC_S_FP_UNDERFLOW 1770L
+#define RPC_S_FP_OVERFLOW 1771L
+#define RPC_X_NO_MORE_ENTRIES 1772L
+#define RPC_X_SS_CHAR_TRANS_OPEN_FAIL 1773L
+#define RPC_X_SS_CHAR_TRANS_SHORT_FILE 1774L
+#define RPC_X_SS_IN_NULL_CONTEXT 1775L
+#define RPC_X_SS_CONTEXT_DAMAGED 1777L
+#define RPC_X_SS_HANDLES_MISMATCH 1778L
+#define RPC_X_SS_CANNOT_GET_CALL_HANDLE 1779L
+#define RPC_X_NULL_REF_POINTER 1780L
+#define RPC_X_ENUM_VALUE_OUT_OF_RANGE 1781L
+#define RPC_X_BYTE_COUNT_TOO_SMALL 1782L
+#define RPC_X_BAD_STUB_DATA 1783L
+#define ERROR_INVALID_USER_BUFFER 1784L
+#define ERROR_UNRECOGNIZED_MEDIA 1785L
+#define ERROR_NO_TRUST_LSA_SECRET 1786L
+#define ERROR_NO_TRUST_SAM_ACCOUNT 1787L
+#define ERROR_TRUSTED_DOMAIN_FAILURE 1788L
+#define ERROR_TRUSTED_RELATIONSHIP_FAILURE 1789L
+#define ERROR_TRUST_FAILURE 1790L
+#define RPC_S_CALL_IN_PROGRESS 1791L
+#define ERROR_NETLOGON_NOT_STARTED 1792L
+#define ERROR_ACCOUNT_EXPIRED 1793L
+#define ERROR_REDIRECTOR_HAS_OPEN_HANDLES 1794L
+#define ERROR_PRINTER_DRIVER_ALREADY_INSTALLED 1795L
+#define ERROR_UNKNOWN_PORT 1796L
+#define ERROR_UNKNOWN_PRINTER_DRIVER 1797L
+#define ERROR_UNKNOWN_PRINTPROCESSOR 1798L
+#define ERROR_INVALID_SEPARATOR_FILE 1799L
+#define ERROR_INVALID_PRIORITY 1800L
+#define ERROR_INVALID_PRINTER_NAME 1801L
+#define ERROR_PRINTER_ALREADY_EXISTS 1802L
+#define ERROR_INVALID_PRINTER_COMMAND 1803L
+#define ERROR_INVALID_DATATYPE 1804L
+#define ERROR_INVALID_ENVIRONMENT 1805L
+#define RPC_S_NO_MORE_BINDINGS 1806L
+#define ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 1807L
+#define ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT 1808L
+#define ERROR_NOLOGON_SERVER_TRUST_ACCOUNT 1809L
+#define ERROR_DOMAIN_TRUST_INCONSISTENT 1810L
+#define ERROR_SERVER_HAS_OPEN_HANDLES 1811L
+#define ERROR_RESOURCE_DATA_NOT_FOUND 1812L
+#define ERROR_RESOURCE_TYPE_NOT_FOUND 1813L
+#define ERROR_RESOURCE_NAME_NOT_FOUND 1814L
+#define ERROR_RESOURCE_LANG_NOT_FOUND 1815L
+#define ERROR_NOT_ENOUGH_QUOTA 1816L
+#define RPC_S_NO_INTERFACES 1817L
+#define RPC_S_CALL_CANCELLED 1818L
+#define RPC_S_BINDING_INCOMPLETE 1819L
+#define RPC_S_COMM_FAILURE 1820L
+#define RPC_S_UNSUPPORTED_AUTHN_LEVEL 1821L
+#define RPC_S_NO_PRINC_NAME 1822L
+#define RPC_S_NOT_RPC_ERROR 1823L
+#define RPC_S_UUID_LOCAL_ONLY 1824L
+#define RPC_S_SEC_PKG_ERROR 1825L
+#define RPC_S_NOT_CANCELLED 1826L
+#define RPC_X_INVALID_ES_ACTION 1827L
+#define RPC_X_WRONG_ES_VERSION 1828L
+#define RPC_X_WRONG_STUB_VERSION 1829L
+#define RPC_X_INVALID_PIPE_OBJECT 1830L
+#define RPC_X_WRONG_PIPE_ORDER 1831L
+#define RPC_X_WRONG_PIPE_VERSION 1832L
+#define RPC_S_GROUP_MEMBER_NOT_FOUND 1898L
+#define EPT_S_CANT_CREATE 1899L
+#define RPC_S_INVALID_OBJECT 1900L
+#define ERROR_INVALID_TIME 1901L
+#define ERROR_INVALID_FORM_NAME 1902L
+#define ERROR_INVALID_FORM_SIZE 1903L
+#define ERROR_ALREADY_WAITING 1904L
+#define ERROR_PRINTER_DELETED 1905L
+#define ERROR_INVALID_PRINTER_STATE 1906L
+#define ERROR_PASSWORD_MUST_CHANGE 1907L
+#define ERROR_DOMAIN_CONTROLLER_NOT_FOUND 1908L
+#define ERROR_ACCOUNT_LOCKED_OUT 1909L
+#define OR_INVALID_OXID 1910L
+#define OR_INVALID_OID 1911L
+#define OR_INVALID_SET 1912L
+#define RPC_S_SEND_INCOMPLETE 1913L
+#define RPC_S_INVALID_ASYNC_HANDLE 1914L
+#define RPC_S_INVALID_ASYNC_CALL 1915L
+#define RPC_X_PIPE_CLOSED 1916L
+#define RPC_X_PIPE_DISCIPLINE_ERROR 1917L
+#define RPC_X_PIPE_EMPTY 1918L
+#define ERROR_NO_SITENAME 1919L
+#define ERROR_CANT_ACCESS_FILE 1920L
+#define ERROR_CANT_RESOLVE_FILENAME 1921L
+#define RPC_S_ENTRY_TYPE_MISMATCH 1922L
+#define RPC_S_NOT_ALL_OBJS_EXPORTED 1923L
+#define RPC_S_INTERFACE_NOT_EXPORTED 1924L
+#define RPC_S_PROFILE_NOT_ADDED 1925L
+#define RPC_S_PRF_ELT_NOT_ADDED 1926L
+#define RPC_S_PRF_ELT_NOT_REMOVED 1927L
+#define RPC_S_GRP_ELT_NOT_ADDED 1928L
+#define RPC_S_GRP_ELT_NOT_REMOVED 1929L
+#define ERROR_KM_DRIVER_BLOCKED 1930L
+#define ERROR_CONTEXT_EXPIRED 1931L
+#define ERROR_PER_USER_TRUST_QUOTA_EXCEEDED 1932L
+#define ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED 1933L
+#define ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED 1934L
+#define ERROR_AUTHENTICATION_FIREWALL_FAILED 1935L
+#define ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED 1936L
+#define ERROR_INVALID_PIXEL_FORMAT 2000L
+#define ERROR_BAD_DRIVER 2001L
+#define ERROR_INVALID_WINDOW_STYLE 2002L
+#define ERROR_METAFILE_NOT_SUPPORTED 2003L
+#define ERROR_TRANSFORM_NOT_SUPPORTED 2004L
+#define ERROR_CLIPPING_NOT_SUPPORTED 2005L
+#define ERROR_INVALID_CMM 2010L
+#define ERROR_INVALID_PROFILE 2011L
+#define ERROR_TAG_NOT_FOUND 2012L
+#define ERROR_TAG_NOT_PRESENT 2013L
+#define ERROR_DUPLICATE_TAG 2014L
+#define ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE 2015L
+#define ERROR_PROFILE_NOT_FOUND 2016L
+#define ERROR_INVALID_COLORSPACE 2017L
+#define ERROR_ICM_NOT_ENABLED 2018L
+#define ERROR_DELETING_ICM_XFORM 2019L
+#define ERROR_INVALID_TRANSFORM 2020L
+#define ERROR_COLORSPACE_MISMATCH 2021L
+#define ERROR_INVALID_COLORINDEX 2022L
+#define ERROR_CONNECTED_OTHER_PASSWORD 2108L
+#define ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT 2109L
+#define ERROR_BAD_USERNAME 2202L
+#define ERROR_NOT_CONNECTED 2250L
+#define ERROR_OPEN_FILES 2401L
+#define ERROR_ACTIVE_CONNECTIONS 2402L
+#define ERROR_DEVICE_IN_USE 2404L
+#define ERROR_UNKNOWN_PRINT_MONITOR 3000L
+#define ERROR_PRINTER_DRIVER_IN_USE 3001L
+#define ERROR_SPOOL_FILE_NOT_FOUND 3002L
+#define ERROR_SPL_NO_STARTDOC 3003L
+#define ERROR_SPL_NO_ADDJOB 3004L
+#define ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED 3005L
+#define ERROR_PRINT_MONITOR_ALREADY_INSTALLED 3006L
+#define ERROR_INVALID_PRINT_MONITOR 3007L
+#define ERROR_PRINT_MONITOR_IN_USE 3008L
+#define ERROR_PRINTER_HAS_JOBS_QUEUED 3009L
+#define ERROR_SUCCESS_REBOOT_REQUIRED 3010L
+#define ERROR_SUCCESS_RESTART_REQUIRED 3011L
+#define ERROR_PRINTER_NOT_FOUND 3012L
+#define ERROR_PRINTER_DRIVER_WARNED 3013L
+#define ERROR_PRINTER_DRIVER_BLOCKED 3014L
+#define ERROR_WINS_INTERNAL 4000L
+#define ERROR_CAN_NOT_DEL_LOCAL_WINS 4001L
+#define ERROR_STATIC_INIT 4002L
+#define ERROR_INC_BACKUP 4003L
+#define ERROR_FULL_BACKUP 4004L
+#define ERROR_REC_NON_EXISTENT 4005L
+#define ERROR_RPL_NOT_ALLOWED 4006L
+#define ERROR_DHCP_ADDRESS_CONFLICT 4100L
+#define ERROR_WMI_GUID_NOT_FOUND 4200L
+#define ERROR_WMI_INSTANCE_NOT_FOUND 4201L
+#define ERROR_WMI_ITEMID_NOT_FOUND 4202L
+#define ERROR_WMI_TRY_AGAIN 4203L
+#define ERROR_WMI_DP_NOT_FOUND 4204L
+#define ERROR_WMI_UNRESOLVED_INSTANCE_REF 4205L
+#define ERROR_WMI_ALREADY_ENABLED 4206L
+#define ERROR_WMI_GUID_DISCONNECTED 4207L
+#define ERROR_WMI_SERVER_UNAVAILABLE 4208L
+#define ERROR_WMI_DP_FAILED 4209L
+#define ERROR_WMI_INVALID_MOF 4210L
+#define ERROR_WMI_INVALID_REGINFO 4211L
+#define ERROR_WMI_ALREADY_DISABLED 4212L
+#define ERROR_WMI_READ_ONLY 4213L
+#define ERROR_WMI_SET_FAILURE 4214L
+#define ERROR_INVALID_MEDIA 4300L
+#define ERROR_INVALID_LIBRARY 4301L
+#define ERROR_INVALID_MEDIA_POOL 4302L
+#define ERROR_DRIVE_MEDIA_MISMATCH 4303L
+#define ERROR_MEDIA_OFFLINE 4304L
+#define ERROR_LIBRARY_OFFLINE 4305L
+#define ERROR_EMPTY 4306L
+#define ERROR_NOT_EMPTY 4307L
+#define ERROR_MEDIA_UNAVAILABLE 4308L
+#define ERROR_RESOURCE_DISABLED 4309L
+#define ERROR_INVALID_CLEANER 4310L
+#define ERROR_UNABLE_TO_CLEAN 4311L
+#define ERROR_OBJECT_NOT_FOUND 4312L
+#define ERROR_DATABASE_FAILURE 4313L
+#define ERROR_DATABASE_FULL 4314L
+#define ERROR_MEDIA_INCOMPATIBLE 4315L
+#define ERROR_RESOURCE_NOT_PRESENT 4316L
+#define ERROR_INVALID_OPERATION 4317L
+#define ERROR_MEDIA_NOT_AVAILABLE 4318L
+#define ERROR_DEVICE_NOT_AVAILABLE 4319L
+#define ERROR_REQUEST_REFUSED 4320L
+#define ERROR_INVALID_DRIVE_OBJECT 4321L
+#define ERROR_LIBRARY_FULL 4322L
+#define ERROR_MEDIUM_NOT_ACCESSIBLE 4323L
+#define ERROR_UNABLE_TO_LOAD_MEDIUM 4324L
+#define ERROR_UNABLE_TO_INVENTORY_DRIVE 4325L
+#define ERROR_UNABLE_TO_INVENTORY_SLOT 4326L
+#define ERROR_UNABLE_TO_INVENTORY_TRANSPORT 4327L
+#define ERROR_TRANSPORT_FULL 4328L
+#define ERROR_CONTROLLING_IEPORT 4329L
+#define ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA 4330L
+#define ERROR_CLEANER_SLOT_SET 4331L
+#define ERROR_CLEANER_SLOT_NOT_SET 4332L
+#define ERROR_CLEANER_CARTRIDGE_SPENT 4333L
+#define ERROR_UNEXPECTED_OMID 4334L
+#define ERROR_CANT_DELETE_LAST_ITEM 4335L
+#define ERROR_MESSAGE_EXCEEDS_MAX_SIZE 4336L
+#define ERROR_VOLUME_CONTAINS_SYS_FILES 4337L
+#define ERROR_INDIGENOUS_TYPE 4338L
+#define ERROR_NO_SUPPORTING_DRIVES 4339L
+#define ERROR_CLEANER_CARTRIDGE_INSTALLED 4340L
+#define ERROR_IEPORT_FULL 4341L
+#define ERROR_FILE_OFFLINE 4350L
+#define ERROR_REMOTE_STORAGE_NOT_ACTIVE 4351L
+#define ERROR_REMOTE_STORAGE_MEDIA_ERROR 4352L
+#define ERROR_NOT_A_REPARSE_POINT 4390L
+#define ERROR_REPARSE_ATTRIBUTE_CONFLICT 4391L
+#define ERROR_INVALID_REPARSE_DATA 4392L
+#define ERROR_REPARSE_TAG_INVALID 4393L
+#define ERROR_REPARSE_TAG_MISMATCH 4394L
+#define ERROR_VOLUME_NOT_SIS_ENABLED 4500L
+#define ERROR_DEPENDENT_RESOURCE_EXISTS 5001L
+#define ERROR_DEPENDENCY_NOT_FOUND 5002L
+#define ERROR_DEPENDENCY_ALREADY_EXISTS 5003L
+#define ERROR_RESOURCE_NOT_ONLINE 5004L
+#define ERROR_HOST_NODE_NOT_AVAILABLE 5005L
+#define ERROR_RESOURCE_NOT_AVAILABLE 5006L
+#define ERROR_RESOURCE_NOT_FOUND 5007L
+#define ERROR_SHUTDOWN_CLUSTER 5008L
+#define ERROR_CANT_EVICT_ACTIVE_NODE 5009L
+#define ERROR_OBJECT_ALREADY_EXISTS 5010L
+#define ERROR_OBJECT_IN_LIST 5011L
+#define ERROR_GROUP_NOT_AVAILABLE 5012L
+#define ERROR_GROUP_NOT_FOUND 5013L
+#define ERROR_GROUP_NOT_ONLINE 5014L
+#define ERROR_HOST_NODE_NOT_RESOURCE_OWNER 5015L
+#define ERROR_HOST_NODE_NOT_GROUP_OWNER 5016L
+#define ERROR_RESMON_CREATE_FAILED 5017L
+#define ERROR_RESMON_ONLINE_FAILED 5018L
+#define ERROR_RESOURCE_ONLINE 5019L
+#define ERROR_QUORUM_RESOURCE 5020L
+#define ERROR_NOT_QUORUM_CAPABLE 5021L
+#define ERROR_CLUSTER_SHUTTING_DOWN 5022L
+#define ERROR_INVALID_STATE 5023L
+#define ERROR_RESOURCE_PROPERTIES_STORED 5024L
+#define ERROR_NOT_QUORUM_CLASS 5025L
+#define ERROR_CORE_RESOURCE 5026L
+#define ERROR_QUORUM_RESOURCE_ONLINE_FAILED 5027L
+#define ERROR_QUORUMLOG_OPEN_FAILED 5028L
+#define ERROR_CLUSTERLOG_CORRUPT 5029L
+#define ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE 5030L
+#define ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE 5031L
+#define ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND 5032L
+#define ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE 5033L
+#define ERROR_QUORUM_OWNER_ALIVE 5034L
+#define ERROR_NETWORK_NOT_AVAILABLE 5035L
+#define ERROR_NODE_NOT_AVAILABLE 5036L
+#define ERROR_ALL_NODES_NOT_AVAILABLE 5037L
+#define ERROR_RESOURCE_FAILED 5038L
+#define ERROR_CLUSTER_INVALID_NODE 5039L
+#define ERROR_CLUSTER_NODE_EXISTS 5040L
+#define ERROR_CLUSTER_JOIN_IN_PROGRESS 5041L
+#define ERROR_CLUSTER_NODE_NOT_FOUND 5042L
+#define ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND 5043L
+#define ERROR_CLUSTER_NETWORK_EXISTS 5044L
+#define ERROR_CLUSTER_NETWORK_NOT_FOUND 5045L
+#define ERROR_CLUSTER_NETINTERFACE_EXISTS 5046L
+#define ERROR_CLUSTER_NETINTERFACE_NOT_FOUND 5047L
+#define ERROR_CLUSTER_INVALID_REQUEST 5048L
+#define ERROR_CLUSTER_INVALID_NETWORK_PROVIDER 5049L
+#define ERROR_CLUSTER_NODE_DOWN 5050L
+#define ERROR_CLUSTER_NODE_UNREACHABLE 5051L
+#define ERROR_CLUSTER_NODE_NOT_MEMBER 5052L
+#define ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS 5053L
+#define ERROR_CLUSTER_INVALID_NETWORK 5054L
+#define ERROR_CLUSTER_NODE_UP 5056L
+#define ERROR_CLUSTER_IPADDR_IN_USE 5057L
+#define ERROR_CLUSTER_NODE_NOT_PAUSED 5058L
+#define ERROR_CLUSTER_NO_SECURITY_CONTEXT 5059L
+#define ERROR_CLUSTER_NETWORK_NOT_INTERNAL 5060L
+#define ERROR_CLUSTER_NODE_ALREADY_UP 5061L
+#define ERROR_CLUSTER_NODE_ALREADY_DOWN 5062L
+#define ERROR_CLUSTER_NETWORK_ALREADY_ONLINE 5063L
+#define ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE 5064L
+#define ERROR_CLUSTER_NODE_ALREADY_MEMBER 5065L
+#define ERROR_CLUSTER_LAST_INTERNAL_NETWORK 5066L
+#define ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS 5067L
+#define ERROR_INVALID_OPERATION_ON_QUORUM 5068L
+#define ERROR_DEPENDENCY_NOT_ALLOWED 5069L
+#define ERROR_CLUSTER_NODE_PAUSED 5070L
+#define ERROR_NODE_CANT_HOST_RESOURCE 5071L
+#define ERROR_CLUSTER_NODE_NOT_READY 5072L
+#define ERROR_CLUSTER_NODE_SHUTTING_DOWN 5073L
+#define ERROR_CLUSTER_JOIN_ABORTED 5074L
+#define ERROR_CLUSTER_INCOMPATIBLE_VERSIONS 5075L
+#define ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED 5076L
+#define ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED 5077L
+#define ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND 5078L
+#define ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED 5079L
+#define ERROR_CLUSTER_RESNAME_NOT_FOUND 5080L
+#define ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED 5081L
+#define ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST 5082L
+#define ERROR_CLUSTER_DATABASE_SEQMISMATCH 5083L
+#define ERROR_RESMON_INVALID_STATE 5084L
+#define ERROR_CLUSTER_GUM_NOT_LOCKER 5085L
+#define ERROR_QUORUM_DISK_NOT_FOUND 5086L
+#define ERROR_DATABASE_BACKUP_CORRUPT 5087L
+#define ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT 5088L
+#define ERROR_RESOURCE_PROPERTY_UNCHANGEABLE 5089L
+#define ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE 5890L
+#define ERROR_CLUSTER_QUORUMLOG_NOT_FOUND 5891L
+#define ERROR_CLUSTER_MEMBERSHIP_HALT 5892L
+#define ERROR_CLUSTER_INSTANCE_ID_MISMATCH 5893L
+#define ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP 5894L
+#define ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH 5895L
+#define ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP 5896L
+#define ERROR_CLUSTER_PARAMETER_MISMATCH 5897L
+#define ERROR_NODE_CANNOT_BE_CLUSTERED 5898L
+#define ERROR_CLUSTER_WRONG_OS_VERSION 5899L
+#define ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME 5900L
+#define ERROR_CLUSCFG_ALREADY_COMMITTED 5901L
+#define ERROR_CLUSCFG_ROLLBACK_FAILED 5902L
+#define ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT 5903L
+#define ERROR_CLUSTER_OLD_VERSION 5904L
+#define ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME 5905L
+#define ERROR_ENCRYPTION_FAILED 6000L
+#define ERROR_DECRYPTION_FAILED 6001L
+#define ERROR_FILE_ENCRYPTED 6002L
+#define ERROR_NO_RECOVERY_POLICY 6003L
+#define ERROR_NO_EFS 6004L
+#define ERROR_WRONG_EFS 6005L
+#define ERROR_NO_USER_KEYS 6006L
+#define ERROR_FILE_NOT_ENCRYPTED 6007L
+#define ERROR_NOT_EXPORT_FORMAT 6008L
+#define ERROR_FILE_READ_ONLY 6009L
+#define ERROR_DIR_EFS_DISALLOWED 6010L
+#define ERROR_EFS_SERVER_NOT_TRUSTED 6011L
+#define ERROR_BAD_RECOVERY_POLICY 6012L
+#define ERROR_EFS_ALG_BLOB_TOO_BIG 6013L
+#define ERROR_VOLUME_NOT_SUPPORT_EFS 6014L
+#define ERROR_EFS_DISABLED 6015L
+#define ERROR_EFS_VERSION_NOT_SUPPORT 6016L
+#define ERROR_NO_BROWSER_SERVERS_FOUND 6118L
+#define SCHED_E_SERVICE_NOT_LOCALSYSTEM 6200L
+#define ERROR_CTX_WINSTATION_NAME_INVALID 7001L
+#define ERROR_CTX_INVALID_PD 7002L
+#define ERROR_CTX_PD_NOT_FOUND 7003L
+#define ERROR_CTX_WD_NOT_FOUND 7004L
+#define ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY 7005L
+#define ERROR_CTX_SERVICE_NAME_COLLISION 7006L
+#define ERROR_CTX_CLOSE_PENDING 7007L
+#define ERROR_CTX_NO_OUTBUF 7008L
+#define ERROR_CTX_MODEM_INF_NOT_FOUND 7009L
+#define ERROR_CTX_INVALID_MODEMNAME 7010L
+#define ERROR_CTX_MODEM_RESPONSE_ERROR 7011L
+#define ERROR_CTX_MODEM_RESPONSE_TIMEOUT 7012L
+#define ERROR_CTX_MODEM_RESPONSE_NO_CARRIER 7013L
+#define ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE 7014L
+#define ERROR_CTX_MODEM_RESPONSE_BUSY 7015L
+#define ERROR_CTX_MODEM_RESPONSE_VOICE 7016L
+#define ERROR_CTX_TD_ERROR 7017L
+#define ERROR_CTX_WINSTATION_NOT_FOUND 7022L
+#define ERROR_CTX_WINSTATION_ALREADY_EXISTS 7023L
+#define ERROR_CTX_WINSTATION_BUSY 7024L
+#define ERROR_CTX_BAD_VIDEO_MODE 7025L
+#define ERROR_CTX_GRAPHICS_INVALID 7035L
+#define ERROR_CTX_LOGON_DISABLED 7037L
+#define ERROR_CTX_NOT_CONSOLE 7038L
+#define ERROR_CTX_CLIENT_QUERY_TIMEOUT 7040L
+#define ERROR_CTX_CONSOLE_DISCONNECT 7041L
+#define ERROR_CTX_CONSOLE_CONNECT 7042L
+#define ERROR_CTX_SHADOW_DENIED 7044L
+#define ERROR_CTX_WINSTATION_ACCESS_DENIED 7045L
+#define ERROR_CTX_INVALID_WD 7049L
+#define ERROR_CTX_SHADOW_INVALID 7050L
+#define ERROR_CTX_SHADOW_DISABLED 7051L
+#define ERROR_CTX_CLIENT_LICENSE_IN_USE 7052L
+#define ERROR_CTX_CLIENT_LICENSE_NOT_SET 7053L
+#define ERROR_CTX_LICENSE_NOT_AVAILABLE 7054L
+#define ERROR_CTX_LICENSE_CLIENT_INVALID 7055L
+#define ERROR_CTX_LICENSE_EXPIRED 7056L
+#define ERROR_CTX_SHADOW_NOT_RUNNING 7057L
+#define ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE 7058L
+#define ERROR_ACTIVATION_COUNT_EXCEEDED 7059L
+#define FRS_ERR_INVALID_API_SEQUENCE 8001L
+#define FRS_ERR_STARTING_SERVICE 8002L
+#define FRS_ERR_STOPPING_SERVICE 8003L
+#define FRS_ERR_INTERNAL_API 8004L
+#define FRS_ERR_INTERNAL 8005L
+#define FRS_ERR_SERVICE_COMM 8006L
+#define FRS_ERR_INSUFFICIENT_PRIV 8007L
+#define FRS_ERR_AUTHENTICATION 8008L
+#define FRS_ERR_PARENT_INSUFFICIENT_PRIV 8009L
+#define FRS_ERR_PARENT_AUTHENTICATION 8010L
+#define FRS_ERR_CHILD_TO_PARENT_COMM 8011L
+#define FRS_ERR_PARENT_TO_CHILD_COMM 8012L
+#define FRS_ERR_SYSVOL_POPULATE 8013L
+#define FRS_ERR_SYSVOL_POPULATE_TIMEOUT 8014L
+#define FRS_ERR_SYSVOL_IS_BUSY 8015L
+#define FRS_ERR_SYSVOL_DEMOTE 8016L
+#define FRS_ERR_INVALID_SERVICE_PARAMETER 8017L
+#define DS_S_SUCCESS NO_ERROR
+#define ERROR_DS_NOT_INSTALLED 8200L
+#define ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY 8201L
+#define ERROR_DS_NO_ATTRIBUTE_OR_VALUE 8202L
+#define ERROR_DS_INVALID_ATTRIBUTE_SYNTAX 8203L
+#define ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED 8204L
+#define ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS 8205L
+#define ERROR_DS_BUSY 8206L
+#define ERROR_DS_UNAVAILABLE 8207L
+#define ERROR_DS_NO_RIDS_ALLOCATED 8208L
+#define ERROR_DS_NO_MORE_RIDS 8209L
+#define ERROR_DS_INCORRECT_ROLE_OWNER 8210L
+#define ERROR_DS_RIDMGR_INIT_ERROR 8211L
+#define ERROR_DS_OBJ_CLASS_VIOLATION 8212L
+#define ERROR_DS_CANT_ON_NON_LEAF 8213L
+#define ERROR_DS_CANT_ON_RDN 8214L
+#define ERROR_DS_CANT_MOD_OBJ_CLASS 8215L
+#define ERROR_DS_CROSS_DOM_MOVE_ERROR 8216L
+#define ERROR_DS_GC_NOT_AVAILABLE 8217L
+#define ERROR_SHARED_POLICY 8218L
+#define ERROR_POLICY_OBJECT_NOT_FOUND 8219L
+#define ERROR_POLICY_ONLY_IN_DS 8220L
+#define ERROR_PROMOTION_ACTIVE 8221L
+#define ERROR_NO_PROMOTION_ACTIVE 8222L
+#define ERROR_DS_OPERATIONS_ERROR 8224L
+#define ERROR_DS_PROTOCOL_ERROR 8225L
+#define ERROR_DS_TIMELIMIT_EXCEEDED 8226L
+#define ERROR_DS_SIZELIMIT_EXCEEDED 8227L
+#define ERROR_DS_ADMIN_LIMIT_EXCEEDED 8228L
+#define ERROR_DS_COMPARE_FALSE 8229L
+#define ERROR_DS_COMPARE_TRUE 8230L
+#define ERROR_DS_AUTH_METHOD_NOT_SUPPORTED 8231L
+#define ERROR_DS_STRONG_AUTH_REQUIRED 8232L
+#define ERROR_DS_INAPPROPRIATE_AUTH 8233L
+#define ERROR_DS_AUTH_UNKNOWN 8234L
+#define ERROR_DS_REFERRAL 8235L
+#define ERROR_DS_UNAVAILABLE_CRIT_EXTENSION 8236L
+#define ERROR_DS_CONFIDENTIALITY_REQUIRED 8237L
+#define ERROR_DS_INAPPROPRIATE_MATCHING 8238L
+#define ERROR_DS_CONSTRAINT_VIOLATION 8239L
+#define ERROR_DS_NO_SUCH_OBJECT 8240L
+#define ERROR_DS_ALIAS_PROBLEM 8241L
+#define ERROR_DS_INVALID_DN_SYNTAX 8242L
+#define ERROR_DS_IS_LEAF 8243L
+#define ERROR_DS_ALIAS_DEREF_PROBLEM 8244L
+#define ERROR_DS_UNWILLING_TO_PERFORM 8245L
+#define ERROR_DS_LOOP_DETECT 8246L
+#define ERROR_DS_NAMING_VIOLATION 8247L
+#define ERROR_DS_OBJECT_RESULTS_TOO_LARGE 8248L
+#define ERROR_DS_AFFECTS_MULTIPLE_DSAS 8249L
+#define ERROR_DS_SERVER_DOWN 8250L
+#define ERROR_DS_LOCAL_ERROR 8251L
+#define ERROR_DS_ENCODING_ERROR 8252L
+#define ERROR_DS_DECODING_ERROR 8253L
+#define ERROR_DS_FILTER_UNKNOWN 8254L
+#define ERROR_DS_PARAM_ERROR 8255L
+#define ERROR_DS_NOT_SUPPORTED 8256L
+#define ERROR_DS_NO_RESULTS_RETURNED 8257L
+#define ERROR_DS_CONTROL_NOT_FOUND 8258L
+#define ERROR_DS_CLIENT_LOOP 8259L
+#define ERROR_DS_REFERRAL_LIMIT_EXCEEDED 8260L
+#define ERROR_DS_SORT_CONTROL_MISSING 8261L
+#define ERROR_DS_OFFSET_RANGE_ERROR 8262L
+#define ERROR_DS_ROOT_MUST_BE_NC 8301L
+#define ERROR_DS_ADD_REPLICA_INHIBITED 8302L
+#define ERROR_DS_ATT_NOT_DEF_IN_SCHEMA 8303L
+#define ERROR_DS_MAX_OBJ_SIZE_EXCEEDED 8304L
+#define ERROR_DS_OBJ_STRING_NAME_EXISTS 8305L
+#define ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA 8306L
+#define ERROR_DS_RDN_DOESNT_MATCH_SCHEMA 8307L
+#define ERROR_DS_NO_REQUESTED_ATTS_FOUND 8308L
+#define ERROR_DS_USER_BUFFER_TO_SMALL 8309L
+#define ERROR_DS_ATT_IS_NOT_ON_OBJ 8310L
+#define ERROR_DS_ILLEGAL_MOD_OPERATION 8311L
+#define ERROR_DS_OBJ_TOO_LARGE 8312L
+#define ERROR_DS_BAD_INSTANCE_TYPE 8313L
+#define ERROR_DS_MASTERDSA_REQUIRED 8314L
+#define ERROR_DS_OBJECT_CLASS_REQUIRED 8315L
+#define ERROR_DS_MISSING_REQUIRED_ATT 8316L
+#define ERROR_DS_ATT_NOT_DEF_FOR_CLASS 8317L
+#define ERROR_DS_ATT_ALREADY_EXISTS 8318L
+#define ERROR_DS_CANT_ADD_ATT_VALUES 8320L
+#define ERROR_DS_SINGLE_VALUE_CONSTRAINT 8321L
+#define ERROR_DS_RANGE_CONSTRAINT 8322L
+#define ERROR_DS_ATT_VAL_ALREADY_EXISTS 8323L
+#define ERROR_DS_CANT_REM_MISSING_ATT 8324L
+#define ERROR_DS_CANT_REM_MISSING_ATT_VAL 8325L
+#define ERROR_DS_ROOT_CANT_BE_SUBREF 8326L
+#define ERROR_DS_NO_CHAINING 8327L
+#define ERROR_DS_NO_CHAINED_EVAL 8328L
+#define ERROR_DS_NO_PARENT_OBJECT 8329L
+#define ERROR_DS_PARENT_IS_AN_ALIAS 8330L
+#define ERROR_DS_CANT_MIX_MASTER_AND_REPS 8331L
+#define ERROR_DS_CHILDREN_EXIST 8332L
+#define ERROR_DS_OBJ_NOT_FOUND 8333L
+#define ERROR_DS_ALIASED_OBJ_MISSING 8334L
+#define ERROR_DS_BAD_NAME_SYNTAX 8335L
+#define ERROR_DS_ALIAS_POINTS_TO_ALIAS 8336L
+#define ERROR_DS_CANT_DEREF_ALIAS 8337L
+#define ERROR_DS_OUT_OF_SCOPE 8338L
+#define ERROR_DS_OBJECT_BEING_REMOVED 8339L
+#define ERROR_DS_CANT_DELETE_DSA_OBJ 8340L
+#define ERROR_DS_GENERIC_ERROR 8341L
+#define ERROR_DS_DSA_MUST_BE_INT_MASTER 8342L
+#define ERROR_DS_CLASS_NOT_DSA 8343L
+#define ERROR_DS_INSUFF_ACCESS_RIGHTS 8344L
+#define ERROR_DS_ILLEGAL_SUPERIOR 8345L
+#define ERROR_DS_ATTRIBUTE_OWNED_BY_SAM 8346L
+#define ERROR_DS_NAME_TOO_MANY_PARTS 8347L
+#define ERROR_DS_NAME_TOO_LONG 8348L
+#define ERROR_DS_NAME_VALUE_TOO_LONG 8349L
+#define ERROR_DS_NAME_UNPARSEABLE 8350L
+#define ERROR_DS_NAME_TYPE_UNKNOWN 8351L
+#define ERROR_DS_NOT_AN_OBJECT 8352L
+#define ERROR_DS_SEC_DESC_TOO_SHORT 8353L
+#define ERROR_DS_SEC_DESC_INVALID 8354L
+#define ERROR_DS_NO_DELETED_NAME 8355L
+#define ERROR_DS_SUBREF_MUST_HAVE_PARENT 8356L
+#define ERROR_DS_NCNAME_MUST_BE_NC 8357L
+#define ERROR_DS_CANT_ADD_SYSTEM_ONLY 8358L
+#define ERROR_DS_CLASS_MUST_BE_CONCRETE 8359L
+#define ERROR_DS_INVALID_DMD 8360L
+#define ERROR_DS_OBJ_GUID_EXISTS 8361L
+#define ERROR_DS_NOT_ON_BACKLINK 8362L
+#define ERROR_DS_NO_CROSSREF_FOR_NC 8363L
+#define ERROR_DS_SHUTTING_DOWN 8364L
+#define ERROR_DS_UNKNOWN_OPERATION 8365L
+#define ERROR_DS_INVALID_ROLE_OWNER 8366L
+#define ERROR_DS_COULDNT_CONTACT_FSMO 8367L
+#define ERROR_DS_CROSS_NC_DN_RENAME 8368L
+#define ERROR_DS_CANT_MOD_SYSTEM_ONLY 8369L
+#define ERROR_DS_REPLICATOR_ONLY 8370L
+#define ERROR_DS_OBJ_CLASS_NOT_DEFINED 8371L
+#define ERROR_DS_OBJ_CLASS_NOT_SUBCLASS 8372L
+#define ERROR_DS_NAME_REFERENCE_INVALID 8373L
+#define ERROR_DS_CROSS_REF_EXISTS 8374L
+#define ERROR_DS_CANT_DEL_MASTER_CROSSREF 8375L
+#define ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD 8376L
+#define ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX 8377L
+#define ERROR_DS_DUP_RDN 8378L
+#define ERROR_DS_DUP_OID 8379L
+#define ERROR_DS_DUP_MAPI_ID 8380L
+#define ERROR_DS_DUP_SCHEMA_ID_GUID 8381L
+#define ERROR_DS_DUP_LDAP_DISPLAY_NAME 8382L
+#define ERROR_DS_SEMANTIC_ATT_TEST 8383L
+#define ERROR_DS_SYNTAX_MISMATCH 8384L
+#define ERROR_DS_EXISTS_IN_MUST_HAVE 8385L
+#define ERROR_DS_EXISTS_IN_MAY_HAVE 8386L
+#define ERROR_DS_NONEXISTENT_MAY_HAVE 8387L
+#define ERROR_DS_NONEXISTENT_MUST_HAVE 8388L
+#define ERROR_DS_AUX_CLS_TEST_FAIL 8389L
+#define ERROR_DS_NONEXISTENT_POSS_SUP 8390L
+#define ERROR_DS_SUB_CLS_TEST_FAIL 8391L
+#define ERROR_DS_BAD_RDN_ATT_ID_SYNTAX 8392L
+#define ERROR_DS_EXISTS_IN_AUX_CLS 8393L
+#define ERROR_DS_EXISTS_IN_SUB_CLS 8394L
+#define ERROR_DS_EXISTS_IN_POSS_SUP 8395L
+#define ERROR_DS_RECALCSCHEMA_FAILED 8396L
+#define ERROR_DS_TREE_DELETE_NOT_FINISHED 8397L
+#define ERROR_DS_CANT_DELETE 8398L
+#define ERROR_DS_ATT_SCHEMA_REQ_ID 8399L
+#define ERROR_DS_BAD_ATT_SCHEMA_SYNTAX 8400L
+#define ERROR_DS_CANT_CACHE_ATT 8401L
+#define ERROR_DS_CANT_CACHE_CLASS 8402L
+#define ERROR_DS_CANT_REMOVE_ATT_CACHE 8403L
+#define ERROR_DS_CANT_REMOVE_CLASS_CACHE 8404L
+#define ERROR_DS_CANT_RETRIEVE_DN 8405L
+#define ERROR_DS_MISSING_SUPREF 8406L
+#define ERROR_DS_CANT_RETRIEVE_INSTANCE 8407L
+#define ERROR_DS_CODE_INCONSISTENCY 8408L
+#define ERROR_DS_DATABASE_ERROR 8409L
+#define ERROR_DS_GOVERNSID_MISSING 8410L
+#define ERROR_DS_MISSING_EXPECTED_ATT 8411L
+#define ERROR_DS_NCNAME_MISSING_CR_REF 8412L
+#define ERROR_DS_SECURITY_CHECKING_ERROR 8413L
+#define ERROR_DS_SCHEMA_NOT_LOADED 8414L
+#define ERROR_DS_SCHEMA_ALLOC_FAILED 8415L
+#define ERROR_DS_ATT_SCHEMA_REQ_SYNTAX 8416L
+#define ERROR_DS_GCVERIFY_ERROR 8417L
+#define ERROR_DS_DRA_SCHEMA_MISMATCH 8418L
+#define ERROR_DS_CANT_FIND_DSA_OBJ 8419L
+#define ERROR_DS_CANT_FIND_EXPECTED_NC 8420L
+#define ERROR_DS_CANT_FIND_NC_IN_CACHE 8421L
+#define ERROR_DS_CANT_RETRIEVE_CHILD 8422L
+#define ERROR_DS_SECURITY_ILLEGAL_MODIFY 8423L
+#define ERROR_DS_CANT_REPLACE_HIDDEN_REC 8424L
+#define ERROR_DS_BAD_HIERARCHY_FILE 8425L
+#define ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED 8426L
+#define ERROR_DS_CONFIG_PARAM_MISSING 8427L
+#define ERROR_DS_COUNTING_AB_INDICES_FAILED 8428L
+#define ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED 8429L
+#define ERROR_DS_INTERNAL_FAILURE 8430L
+#define ERROR_DS_UNKNOWN_ERROR 8431L
+#define ERROR_DS_ROOT_REQUIRES_CLASS_TOP 8432L
+#define ERROR_DS_REFUSING_FSMO_ROLES 8433L
+#define ERROR_DS_MISSING_FSMO_SETTINGS 8434L
+#define ERROR_DS_UNABLE_TO_SURRENDER_ROLES 8435L
+#define ERROR_DS_DRA_GENERIC 8436L
+#define ERROR_DS_DRA_INVALID_PARAMETER 8437L
+#define ERROR_DS_DRA_BUSY 8438L
+#define ERROR_DS_DRA_BAD_DN 8439L
+#define ERROR_DS_DRA_BAD_NC 8440L
+#define ERROR_DS_DRA_DN_EXISTS 8441L
+#define ERROR_DS_DRA_INTERNAL_ERROR 8442L
+#define ERROR_DS_DRA_INCONSISTENT_DIT 8443L
+#define ERROR_DS_DRA_CONNECTION_FAILED 8444L
+#define ERROR_DS_DRA_BAD_INSTANCE_TYPE 8445L
+#define ERROR_DS_DRA_OUT_OF_MEM 8446L
+#define ERROR_DS_DRA_MAIL_PROBLEM 8447L
+#define ERROR_DS_DRA_REF_ALREADY_EXISTS 8448L
+#define ERROR_DS_DRA_REF_NOT_FOUND 8449L
+#define ERROR_DS_DRA_OBJ_IS_REP_SOURCE 8450L
+#define ERROR_DS_DRA_DB_ERROR 8451L
+#define ERROR_DS_DRA_NO_REPLICA 8452L
+#define ERROR_DS_DRA_ACCESS_DENIED 8453L
+#define ERROR_DS_DRA_NOT_SUPPORTED 8454L
+#define ERROR_DS_DRA_RPC_CANCELLED 8455L
+#define ERROR_DS_DRA_SOURCE_DISABLED 8456L
+#define ERROR_DS_DRA_SINK_DISABLED 8457L
+#define ERROR_DS_DRA_NAME_COLLISION 8458L
+#define ERROR_DS_DRA_SOURCE_REINSTALLED 8459L
+#define ERROR_DS_DRA_MISSING_PARENT 8460L
+#define ERROR_DS_DRA_PREEMPTED 8461L
+#define ERROR_DS_DRA_ABANDON_SYNC 8462L
+#define ERROR_DS_DRA_SHUTDOWN 8463L
+#define ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET 8464L
+#define ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA 8465L
+#define ERROR_DS_DRA_EXTN_CONNECTION_FAILED 8466L
+#define ERROR_DS_INSTALL_SCHEMA_MISMATCH 8467L
+#define ERROR_DS_DUP_LINK_ID 8468L
+#define ERROR_DS_NAME_ERROR_RESOLVING 8469L
+#define ERROR_DS_NAME_ERROR_NOT_FOUND 8470L
+#define ERROR_DS_NAME_ERROR_NOT_UNIQUE 8471L
+#define ERROR_DS_NAME_ERROR_NO_MAPPING 8472L
+#define ERROR_DS_NAME_ERROR_DOMAIN_ONLY 8473L
+#define ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING 8474L
+#define ERROR_DS_CONSTRUCTED_ATT_MOD 8475L
+#define ERROR_DS_WRONG_OM_OBJ_CLASS 8476L
+#define ERROR_DS_DRA_REPL_PENDING 8477L
+#define ERROR_DS_DS_REQUIRED 8478L
+#define ERROR_DS_INVALID_LDAP_DISPLAY_NAME 8479L
+#define ERROR_DS_NON_BASE_SEARCH 8480L
+#define ERROR_DS_CANT_RETRIEVE_ATTS 8481L
+#define ERROR_DS_BACKLINK_WITHOUT_LINK 8482L
+#define ERROR_DS_EPOCH_MISMATCH 8483L
+#define ERROR_DS_SRC_NAME_MISMATCH 8484L
+#define ERROR_DS_SRC_AND_DST_NC_IDENTICAL 8485L
+#define ERROR_DS_DST_NC_MISMATCH 8486L
+#define ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC 8487L
+#define ERROR_DS_SRC_GUID_MISMATCH 8488L
+#define ERROR_DS_CANT_MOVE_DELETED_OBJECT 8489L
+#define ERROR_DS_PDC_OPERATION_IN_PROGRESS 8490L
+#define ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD 8491L
+#define ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION 8492L
+#define ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS 8493L
+#define ERROR_DS_NC_MUST_HAVE_NC_PARENT 8494L
+#define ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE 8495L
+#define ERROR_DS_DST_DOMAIN_NOT_NATIVE 8496L
+#define ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER 8497L
+#define ERROR_DS_CANT_MOVE_ACCOUNT_GROUP 8498L
+#define ERROR_DS_CANT_MOVE_RESOURCE_GROUP 8499L
+#define ERROR_DS_INVALID_SEARCH_FLAG 8500L
+#define ERROR_DS_NO_TREE_DELETE_ABOVE_NC 8501L
+#define ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE 8502L
+#define ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE 8503L
+#define ERROR_DS_SAM_INIT_FAILURE 8504L
+#define ERROR_DS_SENSITIVE_GROUP_VIOLATION 8505L
+#define ERROR_DS_CANT_MOD_PRIMARYGROUPID 8506L
+#define ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD 8507L
+#define ERROR_DS_NONSAFE_SCHEMA_CHANGE 8508L
+#define ERROR_DS_SCHEMA_UPDATE_DISALLOWED 8509L
+#define ERROR_DS_CANT_CREATE_UNDER_SCHEMA 8510L
+#define ERROR_DS_INSTALL_NO_SRC_SCH_VERSION 8511L
+#define ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE 8512L
+#define ERROR_DS_INVALID_GROUP_TYPE 8513L
+#define ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN 8514L
+#define ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN 8515L
+#define ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER 8516L
+#define ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER 8517L
+#define ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER 8518L
+#define ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER 8519L
+#define ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER 8520L
+#define ERROR_DS_HAVE_PRIMARY_MEMBERS 8521L
+#define ERROR_DS_STRING_SD_CONVERSION_FAILED 8522L
+#define ERROR_DS_NAMING_MASTER_GC 8523L
+#define ERROR_DS_DNS_LOOKUP_FAILURE 8524L
+#define ERROR_DS_COULDNT_UPDATE_SPNS 8525L
+#define ERROR_DS_CANT_RETRIEVE_SD 8526L
+#define ERROR_DS_KEY_NOT_UNIQUE 8527L
+#define ERROR_DS_WRONG_LINKED_ATT_SYNTAX 8528L
+#define ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD 8529L
+#define ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY 8530L
+#define ERROR_DS_CANT_START 8531L
+#define ERROR_DS_INIT_FAILURE 8532L
+#define ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION 8533L
+#define ERROR_DS_SOURCE_DOMAIN_IN_FOREST 8534L
+#define ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST 8535L
+#define ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED 8536L
+#define ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN 8537L
+#define ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER 8538L
+#define ERROR_DS_SRC_SID_EXISTS_IN_FOREST 8539L
+#define ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH 8540L
+#define ERROR_SAM_INIT_FAILURE 8541L
+#define ERROR_DS_DRA_SCHEMA_INFO_SHIP 8542L
+#define ERROR_DS_DRA_SCHEMA_CONFLICT 8543L
+#define ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT 8544L
+#define ERROR_DS_DRA_OBJ_NC_MISMATCH 8545L
+#define ERROR_DS_NC_STILL_HAS_DSAS 8546L
+#define ERROR_DS_GC_REQUIRED 8547L
+#define ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY 8548L
+#define ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS 8549L
+#define ERROR_DS_CANT_ADD_TO_GC 8550L
+#define ERROR_DS_NO_CHECKPOINT_WITH_PDC 8551L
+#define ERROR_DS_SOURCE_AUDITING_NOT_ENABLED 8552L
+#define ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC 8553L
+#define ERROR_DS_INVALID_NAME_FOR_SPN 8554L
+#define ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS 8555L
+#define ERROR_DS_UNICODEPWD_NOT_IN_QUOTES 8556L
+#define ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED 8557L
+#define ERROR_DS_MUST_BE_RUN_ON_DST_DC 8558L
+#define ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER 8559L
+#define ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ 8560L
+#define ERROR_DS_INIT_FAILURE_CONSOLE 8561L
+#define ERROR_DS_SAM_INIT_FAILURE_CONSOLE 8562L
+#define ERROR_DS_FOREST_VERSION_TOO_HIGH 8563L
+#define ERROR_DS_DOMAIN_VERSION_TOO_HIGH 8564L
+#define ERROR_DS_FOREST_VERSION_TOO_LOW 8565L
+#define ERROR_DS_DOMAIN_VERSION_TOO_LOW 8566L
+#define ERROR_DS_INCOMPATIBLE_VERSION 8567L
+#define ERROR_DS_LOW_DSA_VERSION 8568L
+#define ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN 8569L
+#define ERROR_DS_NOT_SUPPORTED_SORT_ORDER 8570L
+#define ERROR_DS_NAME_NOT_UNIQUE 8571L
+#define ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4 8572L
+#define ERROR_DS_OUT_OF_VERSION_STORE 8573L
+#define ERROR_DS_INCOMPATIBLE_CONTROLS_USED 8574L
+#define ERROR_DS_NO_REF_DOMAIN 8575L
+#define ERROR_DS_RESERVED_LINK_ID 8576L
+#define ERROR_DS_LINK_ID_NOT_AVAILABLE 8577L
+#define ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER 8578L
+#define ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE 8579L
+#define ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC 8580L
+#define ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG 8581L
+#define ERROR_DS_MODIFYDN_WRONG_GRANDPARENT 8582L
+#define ERROR_DS_NAME_ERROR_TRUST_REFERRAL 8583L
+#define ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER 8584L
+#define ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD 8585L
+#define ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2 8586L
+#define ERROR_DS_THREAD_LIMIT_EXCEEDED 8587L
+#define ERROR_DS_NOT_CLOSEST 8588L
+#define ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF 8589L
+#define ERROR_DS_SINGLE_USER_MODE_FAILED 8590L
+#define ERROR_DS_NTDSCRIPT_SYNTAX_ERROR 8591L
+#define ERROR_DS_NTDSCRIPT_PROCESS_ERROR 8592L
+#define ERROR_DS_DIFFERENT_REPL_EPOCHS 8593L
+#define ERROR_DS_DRS_EXTENSIONS_CHANGED 8594L
+#define ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR 8595L
+#define ERROR_DS_NO_MSDS_INTID 8596L
+#define ERROR_DS_DUP_MSDS_INTID 8597L
+#define ERROR_DS_EXISTS_IN_RDNATTID 8598L
+#define ERROR_DS_AUTHORIZATION_FAILED 8599L
+#define ERROR_DS_INVALID_SCRIPT 8600L
+#define ERROR_DS_REMOTE_CROSSREF_OP_FAILED 8601L
+#define ERROR_DS_CROSS_REF_BUSY 8602L
+#define ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN 8603L
+#define ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC 8604L
+#define ERROR_DS_DUPLICATE_ID_FOUND 8605L
+#define ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT 8606L
+#define ERROR_DS_GROUP_CONVERSION_ERROR 8607L
+#define ERROR_DS_CANT_MOVE_APP_BASIC_GROUP 8608L
+#define ERROR_DS_CANT_MOVE_APP_QUERY_GROUP 8609L
+#define ERROR_DS_ROLE_NOT_VERIFIED 8610L
+#define ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL 8611L
+#define ERROR_DS_DOMAIN_RENAME_IN_PROGRESS 8612L
+#define ERROR_DS_EXISTING_AD_CHILD_NC 8613L
+#define ERROR_DS_REPL_LIFETIME_EXCEEDED 8614L
+#define ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER 8615L
+#define ERROR_DS_LDAP_SEND_QUEUE_FULL 8616L
+#define ERROR_DS_DRA_OUT_SCHEDULE_WINDOW 8617L
+#define DNS_ERROR_RESPONSE_CODES_BASE 9000
+#define DNS_ERROR_RCODE_NO_ERROR NO_ERROR
+#define DNS_ERROR_MASK 0x00002328
+#define DNS_ERROR_RCODE_FORMAT_ERROR 9001L
+#define DNS_ERROR_RCODE_SERVER_FAILURE 9002L
+#define DNS_ERROR_RCODE_NAME_ERROR 9003L
+#define DNS_ERROR_RCODE_NOT_IMPLEMENTED 9004L
+#define DNS_ERROR_RCODE_REFUSED 9005L
+#define DNS_ERROR_RCODE_YXDOMAIN 9006L
+#define DNS_ERROR_RCODE_YXRRSET 9007L
+#define DNS_ERROR_RCODE_NXRRSET 9008L
+#define DNS_ERROR_RCODE_NOTAUTH 9009L
+#define DNS_ERROR_RCODE_NOTZONE 9010L
+#define DNS_ERROR_RCODE_BADSIG 9016L
+#define DNS_ERROR_RCODE_BADKEY 9017L
+#define DNS_ERROR_RCODE_BADTIME 9018L
+#define DNS_ERROR_RCODE_LAST DNS_ERROR_RCODE_BADTIME
+#define DNS_ERROR_PACKET_FMT_BASE 9500
+#define DNS_INFO_NO_RECORDS 9501L
+#define DNS_ERROR_BAD_PACKET 9502L
+#define DNS_ERROR_NO_PACKET 9503L
+#define DNS_ERROR_RCODE 9504L
+#define DNS_ERROR_UNSECURE_PACKET 9505L
+#define DNS_STATUS_PACKET_UNSECURE DNS_ERROR_UNSECURE_PACKET
+#define DNS_ERROR_NO_MEMORY ERROR_OUTOFMEMORY
+#define DNS_ERROR_INVALID_NAME ERROR_INVALID_NAME
+#define DNS_ERROR_INVALID_DATA ERROR_INVALID_DATA
+#define DNS_ERROR_GENERAL_API_BASE 9550
+#define DNS_ERROR_INVALID_TYPE 9551L
+#define DNS_ERROR_INVALID_IP_ADDRESS 9552L
+#define DNS_ERROR_INVALID_PROPERTY 9553L
+#define DNS_ERROR_TRY_AGAIN_LATER 9554L
+#define DNS_ERROR_NOT_UNIQUE 9555L
+#define DNS_ERROR_NON_RFC_NAME 9556L
+#define DNS_STATUS_FQDN 9557L
+#define DNS_STATUS_DOTTED_NAME 9558L
+#define DNS_STATUS_SINGLE_PART_NAME 9559L
+#define DNS_ERROR_INVALID_NAME_CHAR 9560L
+#define DNS_ERROR_NUMERIC_NAME 9561L
+#define DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER 9562L
+#define DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION 9563L
+#define DNS_ERROR_CANNOT_FIND_ROOT_HINTS 9564L
+#define DNS_ERROR_INCONSISTENT_ROOT_HINTS 9565L
+#define DNS_ERROR_ZONE_BASE 9600
+#define DNS_ERROR_ZONE_DOES_NOT_EXIST 9601L
+#define DNS_ERROR_NO_ZONE_INFO 9602L
+#define DNS_ERROR_INVALID_ZONE_OPERATION 9603L
+#define DNS_ERROR_ZONE_CONFIGURATION_ERROR 9604L
+#define DNS_ERROR_ZONE_HAS_NO_SOA_RECORD 9605L
+#define DNS_ERROR_ZONE_HAS_NO_NS_RECORDS 9606L
+#define DNS_ERROR_ZONE_LOCKED 9607L
+#define DNS_ERROR_ZONE_CREATION_FAILED 9608L
+#define DNS_ERROR_ZONE_ALREADY_EXISTS 9609L
+#define DNS_ERROR_AUTOZONE_ALREADY_EXISTS 9610L
+#define DNS_ERROR_INVALID_ZONE_TYPE 9611L
+#define DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP 9612L
+#define DNS_ERROR_ZONE_NOT_SECONDARY 9613L
+#define DNS_ERROR_NEED_SECONDARY_ADDRESSES 9614L
+#define DNS_ERROR_WINS_INIT_FAILED 9615L
+#define DNS_ERROR_NEED_WINS_SERVERS 9616L
+#define DNS_ERROR_NBSTAT_INIT_FAILED 9617L
+#define DNS_ERROR_SOA_DELETE_INVALID 9618L
+#define DNS_ERROR_FORWARDER_ALREADY_EXISTS 9619L
+#define DNS_ERROR_ZONE_REQUIRES_MASTER_IP 9620L
+#define DNS_ERROR_ZONE_IS_SHUTDOWN 9621L
+#define DNS_ERROR_DATAFILE_BASE 9650
+#define DNS_ERROR_PRIMARY_REQUIRES_DATAFILE 9651L
+#define DNS_ERROR_INVALID_DATAFILE_NAME 9652L
+#define DNS_ERROR_DATAFILE_OPEN_FAILURE 9653L
+#define DNS_ERROR_FILE_WRITEBACK_FAILED 9654L
+#define DNS_ERROR_DATAFILE_PARSING 9655L
+#define DNS_ERROR_DATABASE_BASE 9700
+#define DNS_ERROR_RECORD_DOES_NOT_EXIST 9701L
+#define DNS_ERROR_RECORD_FORMAT 9702L
+#define DNS_ERROR_NODE_CREATION_FAILED 9703L
+#define DNS_ERROR_UNKNOWN_RECORD_TYPE 9704L
+#define DNS_ERROR_RECORD_TIMED_OUT 9705L
+#define DNS_ERROR_NAME_NOT_IN_ZONE 9706L
+#define DNS_ERROR_CNAME_LOOP 9707L
+#define DNS_ERROR_NODE_IS_CNAME 9708L
+#define DNS_ERROR_CNAME_COLLISION 9709L
+#define DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT 9710L
+#define DNS_ERROR_RECORD_ALREADY_EXISTS 9711L
+#define DNS_ERROR_SECONDARY_DATA 9712L
+#define DNS_ERROR_NO_CREATE_CACHE_DATA 9713L
+#define DNS_ERROR_NAME_DOES_NOT_EXIST 9714L
+#define DNS_WARNING_PTR_CREATE_FAILED 9715L
+#define DNS_WARNING_DOMAIN_UNDELETED 9716L
+#define DNS_ERROR_DS_UNAVAILABLE 9717L
+#define DNS_ERROR_DS_ZONE_ALREADY_EXISTS 9718L
+#define DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE 9719L
+#define DNS_ERROR_OPERATION_BASE 9750
+#define DNS_INFO_AXFR_COMPLETE 9751L
+#define DNS_ERROR_AXFR 9752L
+#define DNS_INFO_ADDED_LOCAL_WINS 9753L
+#define DNS_ERROR_SECURE_BASE 9800
+#define DNS_STATUS_CONTINUE_NEEDED 9801L
+#define DNS_ERROR_SETUP_BASE 9850
+#define DNS_ERROR_NO_TCPIP 9851L
+#define DNS_ERROR_NO_DNS_SERVERS 9852L
+#define DNS_ERROR_DP_BASE 9900
+#define DNS_ERROR_DP_DOES_NOT_EXIST 9901L
+#define DNS_ERROR_DP_ALREADY_EXISTS 9902L
+#define DNS_ERROR_DP_NOT_ENLISTED 9903L
+#define DNS_ERROR_DP_ALREADY_ENLISTED 9904L
+#define DNS_ERROR_DP_NOT_AVAILABLE 9905L
+#define DNS_ERROR_DP_FSMO_ERROR 9906L
+
+#ifndef WSABASEERR
+#define WSABASEERR 10000
+#define WSAEINTR 10004L
+#define WSAEBADF 10009L
+#define WSAEACCES 10013L
+#define WSAEFAULT 10014L
+#define WSAEINVAL 10022L
+#define WSAEMFILE 10024L
+#define WSAEWOULDBLOCK 10035L
+#define WSAEINPROGRESS 10036L
+#define WSAEALREADY 10037L
+#define WSAENOTSOCK 10038L
+#define WSAEDESTADDRREQ 10039L
+#define WSAEMSGSIZE 10040L
+#define WSAEPROTOTYPE 10041L
+#define WSAENOPROTOOPT 10042L
+#define WSAEPROTONOSUPPORT 10043L
+#define WSAESOCKTNOSUPPORT 10044L
+#define WSAEOPNOTSUPP 10045L
+#define WSAEPFNOSUPPORT 10046L
+#define WSAEAFNOSUPPORT 10047L
+#define WSAEADDRINUSE 10048L
+#define WSAEADDRNOTAVAIL 10049L
+#define WSAENETDOWN 10050L
+#define WSAENETUNREACH 10051L
+#define WSAENETRESET 10052L
+#define WSAECONNABORTED 10053L
+#define WSAECONNRESET 10054L
+#define WSAENOBUFS 10055L
+#define WSAEISCONN 10056L
+#define WSAENOTCONN 10057L
+#define WSAESHUTDOWN 10058L
+#define WSAETOOMANYREFS 10059L
+#define WSAETIMEDOUT 10060L
+#define WSAECONNREFUSED 10061L
+#define WSAELOOP 10062L
+#define WSAENAMETOOLONG 10063L
+#define WSAEHOSTDOWN 10064L
+#define WSAEHOSTUNREACH 10065L
+#define WSAENOTEMPTY 10066L
+#define WSAEPROCLIM 10067L
+#define WSAEUSERS 10068L
+#define WSAEDQUOT 10069L
+#define WSAESTALE 10070L
+#define WSAEREMOTE 10071L
+#define WSASYSNOTREADY 10091L
+#define WSAVERNOTSUPPORTED 10092L
+#define WSANOTINITIALISED 10093L
+#define WSAEDISCON 10101L
+#define WSAENOMORE 10102L
+#define WSAECANCELLED 10103L
+#define WSAEINVALIDPROCTABLE 10104L
+#define WSAEINVALIDPROVIDER 10105L
+#define WSAEPROVIDERFAILEDINIT 10106L
+#define WSASYSCALLFAILURE 10107L
+#define WSASERVICE_NOT_FOUND 10108L
+#define WSATYPE_NOT_FOUND 10109L
+#define WSA_E_NO_MORE 10110L
+#define WSA_E_CANCELLED 10111L
+#define WSAEREFUSED 10112L
+#ifndef WSAHOST_NOT_FOUND
+#define WSAHOST_NOT_FOUND 11001L
+#endif
+#ifndef WSATRY_AGAIN
+#define WSATRY_AGAIN 11002L
+#endif
+#ifndef WSANO_RECOVERY
+#define WSANO_RECOVERY 11003L
+#endif
+#ifndef WSANO_DATA
+#define WSANO_DATA 11004L
+#endif
+#ifndef WSA_QOS_RECEIVERS
+#define WSA_QOS_RECEIVERS 11005L
+#endif
+#ifndef WSA_QOS_SENDERS
+#define WSA_QOS_SENDERS 11006L
+#endif
+#ifndef WSA_QOS_NO_SENDERS
+#define WSA_QOS_NO_SENDERS 11007L
+#endif
+#ifndef WSA_QOS_NO_RECEIVERS
+#define WSA_QOS_NO_RECEIVERS 11008L
+#endif
+#ifndef WSA_QOS_REQUEST_CONFIRMED
+#define WSA_QOS_REQUEST_CONFIRMED 11009L
+#endif
+#ifndef WSA_QOS_ADMISSION_FAILURE
+#define WSA_QOS_ADMISSION_FAILURE 11010L
+#endif
+#ifndef WSA_QOS_POLICY_FAILURE
+#define WSA_QOS_POLICY_FAILURE 11011L
+#endif
+#ifndef WSA_QOS_BAD_STYLE
+#define WSA_QOS_BAD_STYLE 11012L
+#endif
+#ifndef WSA_QOS_BAD_OBJECT
+#define WSA_QOS_BAD_OBJECT 11013L
+#endif
+#ifndef WSA_QOS_TRAFFIC_CTRL_ERROR
+#define WSA_QOS_TRAFFIC_CTRL_ERROR 11014L
+#endif
+#ifndef WSA_QOS_GENERIC_ERROR
+#define WSA_QOS_GENERIC_ERROR 11015L
+#endif
+#ifndef WSA_QOS_ESERVICETYPE
+#define WSA_QOS_ESERVICETYPE 11016L
+#endif
+#ifndef WSA_QOS_EFLOWSPEC
+#define WSA_QOS_EFLOWSPEC 11017L
+#endif
+#ifndef WSA_QOS_EPROVSPECBUF
+#define WSA_QOS_EPROVSPECBUF 11018L
+#endif
+#ifndef WSA_QOS_EFILTERSTYLE
+#define WSA_QOS_EFILTERSTYLE 11019L
+#endif
+#ifndef WSA_QOS_EFILTERTYPE
+#define WSA_QOS_EFILTERTYPE 11020L
+#endif
+#ifndef WSA_QOS_EFILTERCOUNT
+#define WSA_QOS_EFILTERCOUNT 11021L
+#endif
+#ifndef WSA_QOS_EOBJLENGTH
+#define WSA_QOS_EOBJLENGTH 11022L
+#endif
+#ifndef WSA_QOS_EFLOWCOUNT
+#define WSA_QOS_EFLOWCOUNT 11023L
+#endif
+#ifndef WSA_QOS_EUNKNOWNPSOBJ
+#define WSA_QOS_EUNKNOWNPSOBJ 11024L
+#endif
+#ifndef WSA_QOS_EPOLICYOBJ
+#define WSA_QOS_EPOLICYOBJ 11025L
+#endif
+#ifndef WSA_QOS_EFLOWDESC
+#define WSA_QOS_EFLOWDESC 11026L
+#endif
+#ifndef WSA_QOS_EPSFLOWSPEC
+#define WSA_QOS_EPSFLOWSPEC 11027L
+#endif
+#ifndef WSA_QOS_EPSFILTERSPEC
+#define WSA_QOS_EPSFILTERSPEC 11028L
+#endif
+#ifndef WSA_QOS_ESDMODEOBJ
+#define WSA_QOS_ESDMODEOBJ 11029L
+#endif
+#ifndef WSA_QOS_ESHAPERATEOBJ
+#define WSA_QOS_ESHAPERATEOBJ 11030L
+#endif
+#ifndef WSA_QOS_RESERVED_PETYPE
+#define WSA_QOS_RESERVED_PETYPE 11031L
+#endif
+#endif /* WSABASEERR */
+
+#define ERROR_SXS_SECTION_NOT_FOUND 14000L
+#define ERROR_SXS_CANT_GEN_ACTCTX 14001L
+#define ERROR_SXS_INVALID_ACTCTXDATA_FORMAT 14002L
+#define ERROR_SXS_ASSEMBLY_NOT_FOUND 14003L
+#define ERROR_SXS_MANIFEST_FORMAT_ERROR 14004L
+#define ERROR_SXS_MANIFEST_PARSE_ERROR 14005L
+#define ERROR_SXS_ACTIVATION_CONTEXT_DISABLED 14006L
+#define ERROR_SXS_KEY_NOT_FOUND 14007L
+#define ERROR_SXS_VERSION_CONFLICT 14008L
+#define ERROR_SXS_WRONG_SECTION_TYPE 14009L
+#define ERROR_SXS_THREAD_QUERIES_DISABLED 14010L
+#define ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET 14011L
+#define ERROR_SXS_UNKNOWN_ENCODING_GROUP 14012L
+#define ERROR_SXS_UNKNOWN_ENCODING 14013L
+#define ERROR_SXS_INVALID_XML_NAMESPACE_URI 14014L
+#define ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED 14015L
+#define ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED 14016L
+#define ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE 14017L
+#define ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE 14018L
+#define ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE 14019L
+#define ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT 14020L
+#define ERROR_SXS_DUPLICATE_DLL_NAME 14021L
+#define ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME 14022L
+#define ERROR_SXS_DUPLICATE_CLSID 14023L
+#define ERROR_SXS_DUPLICATE_IID 14024L
+#define ERROR_SXS_DUPLICATE_TLBID 14025L
+#define ERROR_SXS_DUPLICATE_PROGID 14026L
+#define ERROR_SXS_DUPLICATE_ASSEMBLY_NAME 14027L
+#define ERROR_SXS_FILE_HASH_MISMATCH 14028L
+#define ERROR_SXS_POLICY_PARSE_ERROR 14029L
+#define ERROR_SXS_XML_E_MISSINGQUOTE 14030L
+#define ERROR_SXS_XML_E_COMMENTSYNTAX 14031L
+#define ERROR_SXS_XML_E_BADSTARTNAMECHAR 14032L
+#define ERROR_SXS_XML_E_BADNAMECHAR 14033L
+#define ERROR_SXS_XML_E_BADCHARINSTRING 14034L
+#define ERROR_SXS_XML_E_XMLDECLSYNTAX 14035L
+#define ERROR_SXS_XML_E_BADCHARDATA 14036L
+#define ERROR_SXS_XML_E_MISSINGWHITESPACE 14037L
+#define ERROR_SXS_XML_E_EXPECTINGTAGEND 14038L
+#define ERROR_SXS_XML_E_MISSINGSEMICOLON 14039L
+#define ERROR_SXS_XML_E_UNBALANCEDPAREN 14040L
+#define ERROR_SXS_XML_E_INTERNALERROR 14041L
+#define ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE 14042L
+#define ERROR_SXS_XML_E_INCOMPLETE_ENCODING 14043L
+#define ERROR_SXS_XML_E_MISSING_PAREN 14044L
+#define ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE 14045L
+#define ERROR_SXS_XML_E_MULTIPLE_COLONS 14046L
+#define ERROR_SXS_XML_E_INVALID_DECIMAL 14047L
+#define ERROR_SXS_XML_E_INVALID_HEXIDECIMAL 14048L
+#define ERROR_SXS_XML_E_INVALID_UNICODE 14049L
+#define ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK 14050L
+#define ERROR_SXS_XML_E_UNEXPECTEDENDTAG 14051L
+#define ERROR_SXS_XML_E_UNCLOSEDTAG 14052L
+#define ERROR_SXS_XML_E_DUPLICATEATTRIBUTE 14053L
+#define ERROR_SXS_XML_E_MULTIPLEROOTS 14054L
+#define ERROR_SXS_XML_E_INVALIDATROOTLEVEL 14055L
+#define ERROR_SXS_XML_E_BADXMLDECL 14056L
+#define ERROR_SXS_XML_E_MISSINGROOT 14057L
+#define ERROR_SXS_XML_E_UNEXPECTEDEOF 14058L
+#define ERROR_SXS_XML_E_BADPEREFINSUBSET 14059L
+#define ERROR_SXS_XML_E_UNCLOSEDSTARTTAG 14060L
+#define ERROR_SXS_XML_E_UNCLOSEDENDTAG 14061L
+#define ERROR_SXS_XML_E_UNCLOSEDSTRING 14062L
+#define ERROR_SXS_XML_E_UNCLOSEDCOMMENT 14063L
+#define ERROR_SXS_XML_E_UNCLOSEDDECL 14064L
+#define ERROR_SXS_XML_E_UNCLOSEDCDATA 14065L
+#define ERROR_SXS_XML_E_RESERVEDNAMESPACE 14066L
+#define ERROR_SXS_XML_E_INVALIDENCODING 14067L
+#define ERROR_SXS_XML_E_INVALIDSWITCH 14068L
+#define ERROR_SXS_XML_E_BADXMLCASE 14069L
+#define ERROR_SXS_XML_E_INVALID_STANDALONE 14070L
+#define ERROR_SXS_XML_E_UNEXPECTED_STANDALONE 14071L
+#define ERROR_SXS_XML_E_INVALID_VERSION 14072L
+#define ERROR_SXS_XML_E_MISSINGEQUALS 14073L
+#define ERROR_SXS_PROTECTION_RECOVERY_FAILED 14074L
+#define ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT 14075L
+#define ERROR_SXS_PROTECTION_CATALOG_NOT_VALID 14076L
+#define ERROR_SXS_UNTRANSLATABLE_HRESULT 14077L
+#define ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING 14078L
+#define ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE 14079L
+#define ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME 14080L
+#define ERROR_IPSEC_QM_POLICY_EXISTS 13000L
+#define ERROR_IPSEC_QM_POLICY_NOT_FOUND 13001L
+#define ERROR_IPSEC_QM_POLICY_IN_USE 13002L
+#define ERROR_IPSEC_MM_POLICY_EXISTS 13003L
+#define ERROR_IPSEC_MM_POLICY_NOT_FOUND 13004L
+#define ERROR_IPSEC_MM_POLICY_IN_USE 13005L
+#define ERROR_IPSEC_MM_FILTER_EXISTS 13006L
+#define ERROR_IPSEC_MM_FILTER_NOT_FOUND 13007L
+#define ERROR_IPSEC_TRANSPORT_FILTER_EXISTS 13008L
+#define ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND 13009L
+#define ERROR_IPSEC_MM_AUTH_EXISTS 13010L
+#define ERROR_IPSEC_MM_AUTH_NOT_FOUND 13011L
+#define ERROR_IPSEC_MM_AUTH_IN_USE 13012L
+#define ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND 13013L
+#define ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND 13014L
+#define ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND 13015L
+#define ERROR_IPSEC_TUNNEL_FILTER_EXISTS 13016L
+#define ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND 13017L
+#define ERROR_IPSEC_MM_FILTER_PENDING_DELETION 13018L
+#define ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION 13019L
+#define ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION 13020L
+#define ERROR_IPSEC_MM_POLICY_PENDING_DELETION 13021L
+#define ERROR_IPSEC_MM_AUTH_PENDING_DELETION 13022L
+#define ERROR_IPSEC_QM_POLICY_PENDING_DELETION 13023L
+#define WARNING_IPSEC_MM_POLICY_PRUNED 13024L
+#define WARNING_IPSEC_QM_POLICY_PRUNED 13025L
+#define ERROR_IPSEC_IKE_NEG_STATUS_BEGIN 13800L
+#define ERROR_IPSEC_IKE_AUTH_FAIL 13801L
+#define ERROR_IPSEC_IKE_ATTRIB_FAIL 13802L
+#define ERROR_IPSEC_IKE_NEGOTIATION_PENDING 13803L
+#define ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR 13804L
+#define ERROR_IPSEC_IKE_TIMED_OUT 13805L
+#define ERROR_IPSEC_IKE_NO_CERT 13806L
+#define ERROR_IPSEC_IKE_SA_DELETED 13807L
+#define ERROR_IPSEC_IKE_SA_REAPED 13808L
+#define ERROR_IPSEC_IKE_MM_ACQUIRE_DROP 13809L
+#define ERROR_IPSEC_IKE_QM_ACQUIRE_DROP 13810L
+#define ERROR_IPSEC_IKE_QUEUE_DROP_MM 13811L
+#define ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM 13812L
+#define ERROR_IPSEC_IKE_DROP_NO_RESPONSE 13813L
+#define ERROR_IPSEC_IKE_MM_DELAY_DROP 13814L
+#define ERROR_IPSEC_IKE_QM_DELAY_DROP 13815L
+#define ERROR_IPSEC_IKE_ERROR 13816L
+#define ERROR_IPSEC_IKE_CRL_FAILED 13817L
+#define ERROR_IPSEC_IKE_INVALID_KEY_USAGE 13818L
+#define ERROR_IPSEC_IKE_INVALID_CERT_TYPE 13819L
+#define ERROR_IPSEC_IKE_NO_PRIVATE_KEY 13820L
+#define ERROR_IPSEC_IKE_DH_FAIL 13822L
+#define ERROR_IPSEC_IKE_INVALID_HEADER 13824L
+#define ERROR_IPSEC_IKE_NO_POLICY 13825L
+#define ERROR_IPSEC_IKE_INVALID_SIGNATURE 13826L
+#define ERROR_IPSEC_IKE_KERBEROS_ERROR 13827L
+#define ERROR_IPSEC_IKE_NO_PUBLIC_KEY 13828L
+#define ERROR_IPSEC_IKE_PROCESS_ERR 13829L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_SA 13830L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_PROP 13831L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_TRANS 13832L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_KE 13833L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_ID 13834L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_CERT 13835L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ 13836L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_HASH 13837L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_SIG 13838L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_NONCE 13839L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY 13840L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_DELETE 13841L
+#define ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR 13842L
+#define ERROR_IPSEC_IKE_INVALID_PAYLOAD 13843L
+#define ERROR_IPSEC_IKE_LOAD_SOFT_SA 13844L
+#define ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN 13845L
+#define ERROR_IPSEC_IKE_INVALID_COOKIE 13846L
+#define ERROR_IPSEC_IKE_NO_PEER_CERT 13847L
+#define ERROR_IPSEC_IKE_PEER_CRL_FAILED 13848L
+#define ERROR_IPSEC_IKE_POLICY_CHANGE 13849L
+#define ERROR_IPSEC_IKE_NO_MM_POLICY 13850L
+#define ERROR_IPSEC_IKE_NOTCBPRIV 13851L
+#define ERROR_IPSEC_IKE_SECLOADFAIL 13852L
+#define ERROR_IPSEC_IKE_FAILSSPINIT 13853L
+#define ERROR_IPSEC_IKE_FAILQUERYSSP 13854L
+#define ERROR_IPSEC_IKE_SRVACQFAIL 13855L
+#define ERROR_IPSEC_IKE_SRVQUERYCRED 13856L
+#define ERROR_IPSEC_IKE_GETSPIFAIL 13857L
+#define ERROR_IPSEC_IKE_INVALID_FILTER 13858L
+#define ERROR_IPSEC_IKE_OUT_OF_MEMORY 13859L
+#define ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED 13860L
+#define ERROR_IPSEC_IKE_INVALID_POLICY 13861L
+#define ERROR_IPSEC_IKE_UNKNOWN_DOI 13862L
+#define ERROR_IPSEC_IKE_INVALID_SITUATION 13863L
+#define ERROR_IPSEC_IKE_DH_FAILURE 13864L
+#define ERROR_IPSEC_IKE_INVALID_GROUP 13865L
+#define ERROR_IPSEC_IKE_ENCRYPT 13866L
+#define ERROR_IPSEC_IKE_DECRYPT 13867L
+#define ERROR_IPSEC_IKE_POLICY_MATCH 13868L
+#define ERROR_IPSEC_IKE_UNSUPPORTED_ID 13869L
+#define ERROR_IPSEC_IKE_INVALID_HASH 13870L
+#define ERROR_IPSEC_IKE_INVALID_HASH_ALG 13871L
+#define ERROR_IPSEC_IKE_INVALID_HASH_SIZE 13872L
+#define ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG 13873L
+#define ERROR_IPSEC_IKE_INVALID_AUTH_ALG 13874L
+#define ERROR_IPSEC_IKE_INVALID_SIG 13875L
+#define ERROR_IPSEC_IKE_LOAD_FAILED 13876L
+#define ERROR_IPSEC_IKE_RPC_DELETE 13877L
+#define ERROR_IPSEC_IKE_BENIGN_REINIT 13878L
+#define ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY 13879L
+#define ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN 13881L
+#define ERROR_IPSEC_IKE_MM_LIMIT 13882L
+#define ERROR_IPSEC_IKE_NEGOTIATION_DISABLED 13883L
+#define ERROR_IPSEC_IKE_NEG_STATUS_END 13884L
+#define SEVERITY_SUCCESS 0
+#define SEVERITY_ERROR 1
+#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
+#define FAILED(hr) ((HRESULT)(hr) < 0)
+#define IS_ERROR(Status) ((unsigned long)(Status) >> 31==SEVERITY_ERROR)
+#define HRESULT_CODE(hr) ((hr) & 0xFFFF)
+#define SCODE_CODE(sc) ((sc) & 0xFFFF)
+#define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff)
+#define SCODE_FACILITY(sc) (((sc) >> 16) & 0x1fff)
+#define HRESULT_SEVERITY(hr) (((hr) >> 31) & 0x1)
+#define SCODE_SEVERITY(sc) (((sc) >> 31) & 0x1)
+#define MAKE_HRESULT(sev,fac,code) ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))))
+#define MAKE_SCODE(sev,fac,code) ((SCODE) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))))
+#define FACILITY_NT_BIT 0x10000000
+#define __HRESULT_FROM_WIN32(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)))
+#ifdef INLINE_HRESULT_FROM_WIN32
+#ifndef _HRESULT_DEFINED
+#define _HRESULT_DEFINED
+typedef long HRESULT;
+#endif
+__CRT_INLINE HRESULT HRESULT_FROM_WIN32(long x) { return x <= 0 ? (HRESULT)x : (HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000);}
+#else
+#define HRESULT_FROM_WIN32(x) __HRESULT_FROM_WIN32(x)
+#endif
+#define HRESULT_FROM_NT(x) ((HRESULT) ((x) | FACILITY_NT_BIT))
+#define GetScode(hr) ((SCODE) (hr))
+#define ResultFromScode(sc) ((HRESULT) (sc))
+#define PropagateResult(hrPrevious,scBase) ((HRESULT) scBase)
+#ifdef RC_INVOKED
+#define _HRESULT_TYPEDEF_(_sc) _sc
+#else
+#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)
+#endif
+#define NOERROR 0
+#define E_UNEXPECTED _HRESULT_TYPEDEF_(0x8000FFFFL)
+#define E_NOTIMPL _HRESULT_TYPEDEF_(0x80004001L)
+#define E_OUTOFMEMORY _HRESULT_TYPEDEF_(0x8007000EL)
+#define E_INVALIDARG _HRESULT_TYPEDEF_(0x80070057L)
+#define E_NOINTERFACE _HRESULT_TYPEDEF_(0x80004002L)
+#define E_POINTER _HRESULT_TYPEDEF_(0x80004003L)
+#define E_HANDLE _HRESULT_TYPEDEF_(0x80070006L)
+#define E_ABORT _HRESULT_TYPEDEF_(0x80004004L)
+#define E_FAIL _HRESULT_TYPEDEF_(0x80004005L)
+#define E_ACCESSDENIED _HRESULT_TYPEDEF_(0x80070005L)
+#define E_PENDING _HRESULT_TYPEDEF_(0x8000000AL)
+#define CO_E_INIT_TLS _HRESULT_TYPEDEF_(0x80004006L)
+#define CO_E_INIT_SHARED_ALLOCATOR _HRESULT_TYPEDEF_(0x80004007L)
+#define CO_E_INIT_MEMORY_ALLOCATOR _HRESULT_TYPEDEF_(0x80004008L)
+#define CO_E_INIT_CLASS_CACHE _HRESULT_TYPEDEF_(0x80004009L)
+#define CO_E_INIT_RPC_CHANNEL _HRESULT_TYPEDEF_(0x8000400AL)
+#define CO_E_INIT_TLS_SET_CHANNEL_CONTROL _HRESULT_TYPEDEF_(0x8000400BL)
+#define CO_E_INIT_TLS_CHANNEL_CONTROL _HRESULT_TYPEDEF_(0x8000400CL)
+#define CO_E_INIT_UNACCEPTED_USER_ALLOCATOR _HRESULT_TYPEDEF_(0x8000400DL)
+#define CO_E_INIT_SCM_MUTEX_EXISTS _HRESULT_TYPEDEF_(0x8000400EL)
+#define CO_E_INIT_SCM_FILE_MAPPING_EXISTS _HRESULT_TYPEDEF_(0x8000400FL)
+#define CO_E_INIT_SCM_MAP_VIEW_OF_FILE _HRESULT_TYPEDEF_(0x80004010L)
+#define CO_E_INIT_SCM_EXEC_FAILURE _HRESULT_TYPEDEF_(0x80004011L)
+#define CO_E_INIT_ONLY_SINGLE_THREADED _HRESULT_TYPEDEF_(0x80004012L)
+#define CO_E_CANT_REMOTE _HRESULT_TYPEDEF_(0x80004013L)
+#define CO_E_BAD_SERVER_NAME _HRESULT_TYPEDEF_(0x80004014L)
+#define CO_E_WRONG_SERVER_IDENTITY _HRESULT_TYPEDEF_(0x80004015L)
+#define CO_E_OLE1DDE_DISABLED _HRESULT_TYPEDEF_(0x80004016L)
+#define CO_E_RUNAS_SYNTAX _HRESULT_TYPEDEF_(0x80004017L)
+#define CO_E_CREATEPROCESS_FAILURE _HRESULT_TYPEDEF_(0x80004018L)
+#define CO_E_RUNAS_CREATEPROCESS_FAILURE _HRESULT_TYPEDEF_(0x80004019L)
+#define CO_E_RUNAS_LOGON_FAILURE _HRESULT_TYPEDEF_(0x8000401AL)
+#define CO_E_LAUNCH_PERMSSION_DENIED _HRESULT_TYPEDEF_(0x8000401BL)
+#define CO_E_START_SERVICE_FAILURE _HRESULT_TYPEDEF_(0x8000401CL)
+#define CO_E_REMOTE_COMMUNICATION_FAILURE _HRESULT_TYPEDEF_(0x8000401DL)
+#define CO_E_SERVER_START_TIMEOUT _HRESULT_TYPEDEF_(0x8000401EL)
+#define CO_E_CLSREG_INCONSISTENT _HRESULT_TYPEDEF_(0x8000401FL)
+#define CO_E_IIDREG_INCONSISTENT _HRESULT_TYPEDEF_(0x80004020L)
+#define CO_E_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80004021L)
+#define CO_E_RELOAD_DLL _HRESULT_TYPEDEF_(0x80004022L)
+#define CO_E_MSI_ERROR _HRESULT_TYPEDEF_(0x80004023L)
+#define CO_E_ATTEMPT_TO_CREATE_OUTSIDE_CLIENT_CONTEXT _HRESULT_TYPEDEF_(0x80004024L)
+#define CO_E_SERVER_PAUSED _HRESULT_TYPEDEF_(0x80004025L)
+#define CO_E_SERVER_NOT_PAUSED _HRESULT_TYPEDEF_(0x80004026L)
+#define CO_E_CLASS_DISABLED _HRESULT_TYPEDEF_(0x80004027L)
+#define CO_E_CLRNOTAVAILABLE _HRESULT_TYPEDEF_(0x80004028L)
+#define CO_E_ASYNC_WORK_REJECTED _HRESULT_TYPEDEF_(0x80004029L)
+#define CO_E_SERVER_INIT_TIMEOUT _HRESULT_TYPEDEF_(0x8000402AL)
+#define CO_E_NO_SECCTX_IN_ACTIVATE _HRESULT_TYPEDEF_(0x8000402BL)
+#define CO_E_TRACKER_CONFIG _HRESULT_TYPEDEF_(0x80004030L)
+#define CO_E_THREADPOOL_CONFIG _HRESULT_TYPEDEF_(0x80004031L)
+#define CO_E_SXS_CONFIG _HRESULT_TYPEDEF_(0x80004032L)
+#define CO_E_MALFORMED_SPN _HRESULT_TYPEDEF_(0x80004033L)
+#define S_OK ((HRESULT)0x00000000L)
+#define S_FALSE ((HRESULT)0x00000001L)
+#define OLE_E_FIRST ((HRESULT)0x80040000L)
+#define OLE_E_LAST ((HRESULT)0x800400FFL)
+#define OLE_S_FIRST ((HRESULT)0x00040000L)
+#define OLE_S_LAST ((HRESULT)0x000400FFL)
+#define OLE_E_OLEVERB _HRESULT_TYPEDEF_(0x80040000L)
+#define OLE_E_ADVF _HRESULT_TYPEDEF_(0x80040001L)
+#define OLE_E_ENUM_NOMORE _HRESULT_TYPEDEF_(0x80040002L)
+#define OLE_E_ADVISENOTSUPPORTED _HRESULT_TYPEDEF_(0x80040003L)
+#define OLE_E_NOCONNECTION _HRESULT_TYPEDEF_(0x80040004L)
+#define OLE_E_NOTRUNNING _HRESULT_TYPEDEF_(0x80040005L)
+#define OLE_E_NOCACHE _HRESULT_TYPEDEF_(0x80040006L)
+#define OLE_E_BLANK _HRESULT_TYPEDEF_(0x80040007L)
+#define OLE_E_CLASSDIFF _HRESULT_TYPEDEF_(0x80040008L)
+#define OLE_E_CANT_GETMONIKER _HRESULT_TYPEDEF_(0x80040009L)
+#define OLE_E_CANT_BINDTOSOURCE _HRESULT_TYPEDEF_(0x8004000AL)
+#define OLE_E_STATIC _HRESULT_TYPEDEF_(0x8004000BL)
+#define OLE_E_PROMPTSAVECANCELLED _HRESULT_TYPEDEF_(0x8004000CL)
+#define OLE_E_INVALIDRECT _HRESULT_TYPEDEF_(0x8004000DL)
+#define OLE_E_WRONGCOMPOBJ _HRESULT_TYPEDEF_(0x8004000EL)
+#define OLE_E_INVALIDHWND _HRESULT_TYPEDEF_(0x8004000FL)
+#define OLE_E_NOT_INPLACEACTIVE _HRESULT_TYPEDEF_(0x80040010L)
+#define OLE_E_CANTCONVERT _HRESULT_TYPEDEF_(0x80040011L)
+#define OLE_E_NOSTORAGE _HRESULT_TYPEDEF_(0x80040012L)
+#define DV_E_FORMATETC _HRESULT_TYPEDEF_(0x80040064L)
+#define DV_E_DVTARGETDEVICE _HRESULT_TYPEDEF_(0x80040065L)
+#define DV_E_STGMEDIUM _HRESULT_TYPEDEF_(0x80040066L)
+#define DV_E_STATDATA _HRESULT_TYPEDEF_(0x80040067L)
+#define DV_E_LINDEX _HRESULT_TYPEDEF_(0x80040068L)
+#define DV_E_TYMED _HRESULT_TYPEDEF_(0x80040069L)
+#define DV_E_CLIPFORMAT _HRESULT_TYPEDEF_(0x8004006AL)
+#define DV_E_DVASPECT _HRESULT_TYPEDEF_(0x8004006BL)
+#define DV_E_DVTARGETDEVICE_SIZE _HRESULT_TYPEDEF_(0x8004006CL)
+#define DV_E_NOIVIEWOBJECT _HRESULT_TYPEDEF_(0x8004006DL)
+#define DRAGDROP_E_FIRST 0x80040100L
+#define DRAGDROP_E_LAST 0x8004010FL
+#define DRAGDROP_S_FIRST 0x00040100L
+#define DRAGDROP_S_LAST 0x0004010FL
+#define DRAGDROP_E_NOTREGISTERED _HRESULT_TYPEDEF_(0x80040100L)
+#define DRAGDROP_E_ALREADYREGISTERED _HRESULT_TYPEDEF_(0x80040101L)
+#define DRAGDROP_E_INVALIDHWND _HRESULT_TYPEDEF_(0x80040102L)
+#define CLASSFACTORY_E_FIRST 0x80040110L
+#define CLASSFACTORY_E_LAST 0x8004011FL
+#define CLASSFACTORY_S_FIRST 0x00040110L
+#define CLASSFACTORY_S_LAST 0x0004011FL
+#define CLASS_E_NOAGGREGATION _HRESULT_TYPEDEF_(0x80040110L)
+#define CLASS_E_CLASSNOTAVAILABLE _HRESULT_TYPEDEF_(0x80040111L)
+#define CLASS_E_NOTLICENSED _HRESULT_TYPEDEF_(0x80040112L)
+#define MARSHAL_E_FIRST 0x80040120L
+#define MARSHAL_E_LAST 0x8004012FL
+#define MARSHAL_S_FIRST 0x00040120L
+#define MARSHAL_S_LAST 0x0004012FL
+#define DATA_E_FIRST 0x80040130L
+#define DATA_E_LAST 0x8004013FL
+#define DATA_S_FIRST 0x00040130L
+#define DATA_S_LAST 0x0004013FL
+#define VIEW_E_FIRST 0x80040140L
+#define VIEW_E_LAST 0x8004014FL
+#define VIEW_S_FIRST 0x00040140L
+#define VIEW_S_LAST 0x0004014FL
+#define VIEW_E_DRAW _HRESULT_TYPEDEF_(0x80040140L)
+#define REGDB_E_FIRST 0x80040150L
+#define REGDB_E_LAST 0x8004015FL
+#define REGDB_S_FIRST 0x00040150L
+#define REGDB_S_LAST 0x0004015FL
+#define REGDB_E_READREGDB _HRESULT_TYPEDEF_(0x80040150L)
+#define REGDB_E_WRITEREGDB _HRESULT_TYPEDEF_(0x80040151L)
+#define REGDB_E_KEYMISSING _HRESULT_TYPEDEF_(0x80040152L)
+#define REGDB_E_INVALIDVALUE _HRESULT_TYPEDEF_(0x80040153L)
+#define REGDB_E_CLASSNOTREG _HRESULT_TYPEDEF_(0x80040154L)
+#define REGDB_E_IIDNOTREG _HRESULT_TYPEDEF_(0x80040155L)
+#define REGDB_E_BADTHREADINGMODEL _HRESULT_TYPEDEF_(0x80040156L)
+#define CAT_E_FIRST 0x80040160L
+#define CAT_E_LAST 0x80040161L
+#define CAT_E_CATIDNOEXIST _HRESULT_TYPEDEF_(0x80040160L)
+#define CAT_E_NODESCRIPTION _HRESULT_TYPEDEF_(0x80040161L)
+#define CS_E_FIRST 0x80040164L
+#define CS_E_LAST 0x8004016FL
+#define CS_E_PACKAGE_NOTFOUND _HRESULT_TYPEDEF_(0x80040164L)
+#define CS_E_NOT_DELETABLE _HRESULT_TYPEDEF_(0x80040165L)
+#define CS_E_CLASS_NOTFOUND _HRESULT_TYPEDEF_(0x80040166L)
+#define CS_E_INVALID_VERSION _HRESULT_TYPEDEF_(0x80040167L)
+#define CS_E_NO_CLASSSTORE _HRESULT_TYPEDEF_(0x80040168L)
+#define CS_E_OBJECT_NOTFOUND _HRESULT_TYPEDEF_(0x80040169L)
+#define CS_E_OBJECT_ALREADY_EXISTS _HRESULT_TYPEDEF_(0x8004016AL)
+#define CS_E_INVALID_PATH _HRESULT_TYPEDEF_(0x8004016BL)
+#define CS_E_NETWORK_ERROR _HRESULT_TYPEDEF_(0x8004016CL)
+#define CS_E_ADMIN_LIMIT_EXCEEDED _HRESULT_TYPEDEF_(0x8004016DL)
+#define CS_E_SCHEMA_MISMATCH _HRESULT_TYPEDEF_(0x8004016EL)
+#define CS_E_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x8004016FL)
+#define CACHE_E_FIRST 0x80040170L
+#define CACHE_E_LAST 0x8004017FL
+#define CACHE_S_FIRST 0x00040170L
+#define CACHE_S_LAST 0x0004017FL
+#define CACHE_E_NOCACHE_UPDATED _HRESULT_TYPEDEF_(0x80040170L)
+#define OLEOBJ_E_FIRST 0x80040180L
+#define OLEOBJ_E_LAST 0x8004018FL
+#define OLEOBJ_S_FIRST 0x00040180L
+#define OLEOBJ_S_LAST 0x0004018FL
+#define OLEOBJ_E_NOVERBS _HRESULT_TYPEDEF_(0x80040180L)
+#define OLEOBJ_E_INVALIDVERB _HRESULT_TYPEDEF_(0x80040181L)
+#define CLIENTSITE_E_FIRST 0x80040190L
+#define CLIENTSITE_E_LAST 0x8004019FL
+#define CLIENTSITE_S_FIRST 0x00040190L
+#define CLIENTSITE_S_LAST 0x0004019FL
+#define INPLACE_E_NOTUNDOABLE _HRESULT_TYPEDEF_(0x800401A0L)
+#define INPLACE_E_NOTOOLSPACE _HRESULT_TYPEDEF_(0x800401A1L)
+#define INPLACE_E_FIRST 0x800401A0L
+#define INPLACE_E_LAST 0x800401AFL
+#define INPLACE_S_FIRST 0x000401A0L
+#define INPLACE_S_LAST 0x000401AFL
+#define ENUM_E_FIRST 0x800401B0L
+#define ENUM_E_LAST 0x800401BFL
+#define ENUM_S_FIRST 0x000401B0L
+#define ENUM_S_LAST 0x000401BFL
+#define CONVERT10_E_FIRST 0x800401C0L
+#define CONVERT10_E_LAST 0x800401CFL
+#define CONVERT10_S_FIRST 0x000401C0L
+#define CONVERT10_S_LAST 0x000401CFL
+#define CONVERT10_E_OLESTREAM_GET _HRESULT_TYPEDEF_(0x800401C0L)
+#define CONVERT10_E_OLESTREAM_PUT _HRESULT_TYPEDEF_(0x800401C1L)
+#define CONVERT10_E_OLESTREAM_FMT _HRESULT_TYPEDEF_(0x800401C2L)
+#define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB _HRESULT_TYPEDEF_(0x800401C3L)
+#define CONVERT10_E_STG_FMT _HRESULT_TYPEDEF_(0x800401C4L)
+#define CONVERT10_E_STG_NO_STD_STREAM _HRESULT_TYPEDEF_(0x800401C5L)
+#define CONVERT10_E_STG_DIB_TO_BITMAP _HRESULT_TYPEDEF_(0x800401C6L)
+#define CLIPBRD_E_FIRST 0x800401D0L
+#define CLIPBRD_E_LAST 0x800401DFL
+#define CLIPBRD_S_FIRST 0x000401D0L
+#define CLIPBRD_S_LAST 0x000401DFL
+#define CLIPBRD_E_CANT_OPEN _HRESULT_TYPEDEF_(0x800401D0L)
+#define CLIPBRD_E_CANT_EMPTY _HRESULT_TYPEDEF_(0x800401D1L)
+#define CLIPBRD_E_CANT_SET _HRESULT_TYPEDEF_(0x800401D2L)
+#define CLIPBRD_E_BAD_DATA _HRESULT_TYPEDEF_(0x800401D3L)
+#define CLIPBRD_E_CANT_CLOSE _HRESULT_TYPEDEF_(0x800401D4L)
+#define MK_E_FIRST 0x800401E0L
+#define MK_E_LAST 0x800401EFL
+#define MK_S_FIRST 0x000401E0L
+#define MK_S_LAST 0x000401EFL
+#define MK_E_CONNECTMANUALLY _HRESULT_TYPEDEF_(0x800401E0L)
+#define MK_E_EXCEEDEDDEADLINE _HRESULT_TYPEDEF_(0x800401E1L)
+#define MK_E_NEEDGENERIC _HRESULT_TYPEDEF_(0x800401E2L)
+#define MK_E_UNAVAILABLE _HRESULT_TYPEDEF_(0x800401E3L)
+#define MK_E_SYNTAX _HRESULT_TYPEDEF_(0x800401E4L)
+#define MK_E_NOOBJECT _HRESULT_TYPEDEF_(0x800401E5L)
+#define MK_E_INVALIDEXTENSION _HRESULT_TYPEDEF_(0x800401E6L)
+#define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED _HRESULT_TYPEDEF_(0x800401E7L)
+#define MK_E_NOTBINDABLE _HRESULT_TYPEDEF_(0x800401E8L)
+#define MK_E_NOTBOUND _HRESULT_TYPEDEF_(0x800401E9L)
+#define MK_E_CANTOPENFILE _HRESULT_TYPEDEF_(0x800401EAL)
+#define MK_E_MUSTBOTHERUSER _HRESULT_TYPEDEF_(0x800401EBL)
+#define MK_E_NOINVERSE _HRESULT_TYPEDEF_(0x800401ECL)
+#define MK_E_NOSTORAGE _HRESULT_TYPEDEF_(0x800401EDL)
+#define MK_E_NOPREFIX _HRESULT_TYPEDEF_(0x800401EEL)
+#define MK_E_ENUMERATION_FAILED _HRESULT_TYPEDEF_(0x800401EFL)
+#define CO_E_FIRST 0x800401F0L
+#define CO_E_LAST 0x800401FFL
+#define CO_S_FIRST 0x000401F0L
+#define CO_S_LAST 0x000401FFL
+#define CO_E_NOTINITIALIZED _HRESULT_TYPEDEF_(0x800401F0L)
+#define CO_E_ALREADYINITIALIZED _HRESULT_TYPEDEF_(0x800401F1L)
+#define CO_E_CANTDETERMINECLASS _HRESULT_TYPEDEF_(0x800401F2L)
+#define CO_E_CLASSSTRING _HRESULT_TYPEDEF_(0x800401F3L)
+#define CO_E_IIDSTRING _HRESULT_TYPEDEF_(0x800401F4L)
+#define CO_E_APPNOTFOUND _HRESULT_TYPEDEF_(0x800401F5L)
+#define CO_E_APPSINGLEUSE _HRESULT_TYPEDEF_(0x800401F6L)
+#define CO_E_ERRORINAPP _HRESULT_TYPEDEF_(0x800401F7L)
+#define CO_E_DLLNOTFOUND _HRESULT_TYPEDEF_(0x800401F8L)
+#define CO_E_ERRORINDLL _HRESULT_TYPEDEF_(0x800401F9L)
+#define CO_E_WRONGOSFORAPP _HRESULT_TYPEDEF_(0x800401FAL)
+#define CO_E_OBJNOTREG _HRESULT_TYPEDEF_(0x800401FBL)
+#define CO_E_OBJISREG _HRESULT_TYPEDEF_(0x800401FCL)
+#define CO_E_OBJNOTCONNECTED _HRESULT_TYPEDEF_(0x800401FDL)
+#define CO_E_APPDIDNTREG _HRESULT_TYPEDEF_(0x800401FEL)
+#define CO_E_RELEASED _HRESULT_TYPEDEF_(0x800401FFL)
+#define EVENT_E_FIRST 0x80040200L
+#define EVENT_E_LAST 0x8004021FL
+#define EVENT_S_FIRST 0x00040200L
+#define EVENT_S_LAST 0x0004021FL
+#define EVENT_S_SOME_SUBSCRIBERS_FAILED _HRESULT_TYPEDEF_(0x00040200L)
+#define EVENT_E_ALL_SUBSCRIBERS_FAILED _HRESULT_TYPEDEF_(0x80040201L)
+#define EVENT_S_NOSUBSCRIBERS _HRESULT_TYPEDEF_(0x00040202L)
+#define EVENT_E_QUERYSYNTAX _HRESULT_TYPEDEF_(0x80040203L)
+#define EVENT_E_QUERYFIELD _HRESULT_TYPEDEF_(0x80040204L)
+#define EVENT_E_INTERNALEXCEPTION _HRESULT_TYPEDEF_(0x80040205L)
+#define EVENT_E_INTERNALERROR _HRESULT_TYPEDEF_(0x80040206L)
+#define EVENT_E_INVALID_PER_USER_SID _HRESULT_TYPEDEF_(0x80040207L)
+#define EVENT_E_USER_EXCEPTION _HRESULT_TYPEDEF_(0x80040208L)
+#define EVENT_E_TOO_MANY_METHODS _HRESULT_TYPEDEF_(0x80040209L)
+#define EVENT_E_MISSING_EVENTCLASS _HRESULT_TYPEDEF_(0x8004020AL)
+#define EVENT_E_NOT_ALL_REMOVED _HRESULT_TYPEDEF_(0x8004020BL)
+#define EVENT_E_COMPLUS_NOT_INSTALLED _HRESULT_TYPEDEF_(0x8004020CL)
+#define EVENT_E_CANT_MODIFY_OR_DELETE_UNCONFIGURED_OBJECT _HRESULT_TYPEDEF_(0x8004020DL)
+#define EVENT_E_CANT_MODIFY_OR_DELETE_CONFIGURED_OBJECT _HRESULT_TYPEDEF_(0x8004020EL)
+#define EVENT_E_INVALID_EVENT_CLASS_PARTITION _HRESULT_TYPEDEF_(0x8004020FL)
+#define EVENT_E_PER_USER_SID_NOT_LOGGED_ON _HRESULT_TYPEDEF_(0x80040210L)
+#define XACT_E_FIRST 0x8004D000
+#define XACT_E_LAST 0x8004D029
+#define XACT_S_FIRST 0x0004D000
+#define XACT_S_LAST 0x0004D010
+#define XACT_E_ALREADYOTHERSINGLEPHASE _HRESULT_TYPEDEF_(0x8004D000L)
+#define XACT_E_CANTRETAIN _HRESULT_TYPEDEF_(0x8004D001L)
+#define XACT_E_COMMITFAILED _HRESULT_TYPEDEF_(0x8004D002L)
+#define XACT_E_COMMITPREVENTED _HRESULT_TYPEDEF_(0x8004D003L)
+#define XACT_E_HEURISTICABORT _HRESULT_TYPEDEF_(0x8004D004L)
+#define XACT_E_HEURISTICCOMMIT _HRESULT_TYPEDEF_(0x8004D005L)
+#define XACT_E_HEURISTICDAMAGE _HRESULT_TYPEDEF_(0x8004D006L)
+#define XACT_E_HEURISTICDANGER _HRESULT_TYPEDEF_(0x8004D007L)
+#define XACT_E_ISOLATIONLEVEL _HRESULT_TYPEDEF_(0x8004D008L)
+#define XACT_E_NOASYNC _HRESULT_TYPEDEF_(0x8004D009L)
+#define XACT_E_NOENLIST _HRESULT_TYPEDEF_(0x8004D00AL)
+#define XACT_E_NOISORETAIN _HRESULT_TYPEDEF_(0x8004D00BL)
+#define XACT_E_NORESOURCE _HRESULT_TYPEDEF_(0x8004D00CL)
+#define XACT_E_NOTCURRENT _HRESULT_TYPEDEF_(0x8004D00DL)
+#define XACT_E_NOTRANSACTION _HRESULT_TYPEDEF_(0x8004D00EL)
+#define XACT_E_NOTSUPPORTED _HRESULT_TYPEDEF_(0x8004D00FL)
+#define XACT_E_UNKNOWNRMGRID _HRESULT_TYPEDEF_(0x8004D010L)
+#define XACT_E_WRONGSTATE _HRESULT_TYPEDEF_(0x8004D011L)
+#define XACT_E_WRONGUOW _HRESULT_TYPEDEF_(0x8004D012L)
+#define XACT_E_XTIONEXISTS _HRESULT_TYPEDEF_(0x8004D013L)
+#define XACT_E_NOIMPORTOBJECT _HRESULT_TYPEDEF_(0x8004D014L)
+#define XACT_E_INVALIDCOOKIE _HRESULT_TYPEDEF_(0x8004D015L)
+#define XACT_E_INDOUBT _HRESULT_TYPEDEF_(0x8004D016L)
+#define XACT_E_NOTIMEOUT _HRESULT_TYPEDEF_(0x8004D017L)
+#define XACT_E_ALREADYINPROGRESS _HRESULT_TYPEDEF_(0x8004D018L)
+#define XACT_E_ABORTED _HRESULT_TYPEDEF_(0x8004D019L)
+#define XACT_E_LOGFULL _HRESULT_TYPEDEF_(0x8004D01AL)
+#define XACT_E_TMNOTAVAILABLE _HRESULT_TYPEDEF_(0x8004D01BL)
+#define XACT_E_CONNECTION_DOWN _HRESULT_TYPEDEF_(0x8004D01CL)
+#define XACT_E_CONNECTION_DENIED _HRESULT_TYPEDEF_(0x8004D01DL)
+#define XACT_E_REENLISTTIMEOUT _HRESULT_TYPEDEF_(0x8004D01EL)
+#define XACT_E_TIP_CONNECT_FAILED _HRESULT_TYPEDEF_(0x8004D01FL)
+#define XACT_E_TIP_PROTOCOL_ERROR _HRESULT_TYPEDEF_(0x8004D020L)
+#define XACT_E_TIP_PULL_FAILED _HRESULT_TYPEDEF_(0x8004D021L)
+#define XACT_E_DEST_TMNOTAVAILABLE _HRESULT_TYPEDEF_(0x8004D022L)
+#define XACT_E_TIP_DISABLED _HRESULT_TYPEDEF_(0x8004D023L)
+#define XACT_E_NETWORK_TX_DISABLED _HRESULT_TYPEDEF_(0x8004D024L)
+#define XACT_E_PARTNER_NETWORK_TX_DISABLED _HRESULT_TYPEDEF_(0x8004D025L)
+#define XACT_E_XA_TX_DISABLED _HRESULT_TYPEDEF_(0x8004D026L)
+#define XACT_E_UNABLE_TO_READ_DTC_CONFIG _HRESULT_TYPEDEF_(0x8004D027L)
+#define XACT_E_UNABLE_TO_LOAD_DTC_PROXY _HRESULT_TYPEDEF_(0x8004D028L)
+#define XACT_E_ABORTING _HRESULT_TYPEDEF_(0x8004D029L)
+#define XACT_E_CLERKNOTFOUND _HRESULT_TYPEDEF_(0x8004D080L)
+#define XACT_E_CLERKEXISTS _HRESULT_TYPEDEF_(0x8004D081L)
+#define XACT_E_RECOVERYINPROGRESS _HRESULT_TYPEDEF_(0x8004D082L)
+#define XACT_E_TRANSACTIONCLOSED _HRESULT_TYPEDEF_(0x8004D083L)
+#define XACT_E_INVALIDLSN _HRESULT_TYPEDEF_(0x8004D084L)
+#define XACT_E_REPLAYREQUEST _HRESULT_TYPEDEF_(0x8004D085L)
+#define XACT_S_ASYNC _HRESULT_TYPEDEF_(0x0004D000L)
+#define XACT_S_DEFECT _HRESULT_TYPEDEF_(0x0004D001L)
+#define XACT_S_READONLY _HRESULT_TYPEDEF_(0x0004D002L)
+#define XACT_S_SOMENORETAIN _HRESULT_TYPEDEF_(0x0004D003L)
+#define XACT_S_OKINFORM _HRESULT_TYPEDEF_(0x0004D004L)
+#define XACT_S_MADECHANGESCONTENT _HRESULT_TYPEDEF_(0x0004D005L)
+#define XACT_S_MADECHANGESINFORM _HRESULT_TYPEDEF_(0x0004D006L)
+#define XACT_S_ALLNORETAIN _HRESULT_TYPEDEF_(0x0004D007L)
+#define XACT_S_ABORTING _HRESULT_TYPEDEF_(0x0004D008L)
+#define XACT_S_SINGLEPHASE _HRESULT_TYPEDEF_(0x0004D009L)
+#define XACT_S_LOCALLY_OK _HRESULT_TYPEDEF_(0x0004D00AL)
+#define XACT_S_LASTRESOURCEMANAGER _HRESULT_TYPEDEF_(0x0004D010L)
+#define CONTEXT_E_FIRST 0x8004E000L
+#define CONTEXT_E_LAST 0x8004E02FL
+#define CONTEXT_S_FIRST 0x0004E000L
+#define CONTEXT_S_LAST 0x0004E02FL
+#define CONTEXT_E_ABORTED _HRESULT_TYPEDEF_(0x8004E002L)
+#define CONTEXT_E_ABORTING _HRESULT_TYPEDEF_(0x8004E003L)
+#define CONTEXT_E_NOCONTEXT _HRESULT_TYPEDEF_(0x8004E004L)
+#define CONTEXT_E_WOULD_DEADLOCK _HRESULT_TYPEDEF_(0x8004E005L)
+#define CONTEXT_E_SYNCH_TIMEOUT _HRESULT_TYPEDEF_(0x8004E006L)
+#define CONTEXT_E_OLDREF _HRESULT_TYPEDEF_(0x8004E007L)
+#define CONTEXT_E_ROLENOTFOUND _HRESULT_TYPEDEF_(0x8004E00CL)
+#define CONTEXT_E_TMNOTAVAILABLE _HRESULT_TYPEDEF_(0x8004E00FL)
+#define CO_E_ACTIVATIONFAILED _HRESULT_TYPEDEF_(0x8004E021L)
+#define CO_E_ACTIVATIONFAILED_EVENTLOGGED _HRESULT_TYPEDEF_(0x8004E022L)
+#define CO_E_ACTIVATIONFAILED_CATALOGERROR _HRESULT_TYPEDEF_(0x8004E023L)
+#define CO_E_ACTIVATIONFAILED_TIMEOUT _HRESULT_TYPEDEF_(0x8004E024L)
+#define CO_E_INITIALIZATIONFAILED _HRESULT_TYPEDEF_(0x8004E025L)
+#define CONTEXT_E_NOJIT _HRESULT_TYPEDEF_(0x8004E026L)
+#define CONTEXT_E_NOTRANSACTION _HRESULT_TYPEDEF_(0x8004E027L)
+#define CO_E_THREADINGMODEL_CHANGED _HRESULT_TYPEDEF_(0x8004E028L)
+#define CO_E_NOIISINTRINSICS _HRESULT_TYPEDEF_(0x8004E029L)
+#define CO_E_NOCOOKIES _HRESULT_TYPEDEF_(0x8004E02AL)
+#define CO_E_DBERROR _HRESULT_TYPEDEF_(0x8004E02BL)
+#define CO_E_NOTPOOLED _HRESULT_TYPEDEF_(0x8004E02CL)
+#define CO_E_NOTCONSTRUCTED _HRESULT_TYPEDEF_(0x8004E02DL)
+#define CO_E_NOSYNCHRONIZATION _HRESULT_TYPEDEF_(0x8004E02EL)
+#define CO_E_ISOLEVELMISMATCH _HRESULT_TYPEDEF_(0x8004E02FL)
+#define OLE_S_USEREG _HRESULT_TYPEDEF_(0x00040000L)
+#define OLE_S_STATIC _HRESULT_TYPEDEF_(0x00040001L)
+#define OLE_S_MAC_CLIPFORMAT _HRESULT_TYPEDEF_(0x00040002L)
+#define DRAGDROP_S_DROP _HRESULT_TYPEDEF_(0x00040100L)
+#define DRAGDROP_S_CANCEL _HRESULT_TYPEDEF_(0x00040101L)
+#define DRAGDROP_S_USEDEFAULTCURSORS _HRESULT_TYPEDEF_(0x00040102L)
+#define DATA_S_SAMEFORMATETC _HRESULT_TYPEDEF_(0x00040130L)
+#define VIEW_S_ALREADY_FROZEN _HRESULT_TYPEDEF_(0x00040140L)
+#define CACHE_S_FORMATETC_NOTSUPPORTED _HRESULT_TYPEDEF_(0x00040170L)
+#define CACHE_S_SAMECACHE _HRESULT_TYPEDEF_(0x00040171L)
+#define CACHE_S_SOMECACHES_NOTUPDATED _HRESULT_TYPEDEF_(0x00040172L)
+#define OLEOBJ_S_INVALIDVERB _HRESULT_TYPEDEF_(0x00040180L)
+#define OLEOBJ_S_CANNOT_DOVERB_NOW _HRESULT_TYPEDEF_(0x00040181L)
+#define OLEOBJ_S_INVALIDHWND _HRESULT_TYPEDEF_(0x00040182L)
+#define INPLACE_S_TRUNCATED _HRESULT_TYPEDEF_(0x000401A0L)
+#define CONVERT10_S_NO_PRESENTATION _HRESULT_TYPEDEF_(0x000401C0L)
+#define MK_S_REDUCED_TO_SELF _HRESULT_TYPEDEF_(0x000401E2L)
+#define MK_S_ME _HRESULT_TYPEDEF_(0x000401E4L)
+#define MK_S_HIM _HRESULT_TYPEDEF_(0x000401E5L)
+#define MK_S_US _HRESULT_TYPEDEF_(0x000401E6L)
+#define MK_S_MONIKERALREADYREGISTERED _HRESULT_TYPEDEF_(0x000401E7L)
+#define SCHED_S_TASK_READY _HRESULT_TYPEDEF_(0x00041300L)
+#define SCHED_S_TASK_RUNNING _HRESULT_TYPEDEF_(0x00041301L)
+#define SCHED_S_TASK_DISABLED _HRESULT_TYPEDEF_(0x00041302L)
+#define SCHED_S_TASK_HAS_NOT_RUN _HRESULT_TYPEDEF_(0x00041303L)
+#define SCHED_S_TASK_NO_MORE_RUNS _HRESULT_TYPEDEF_(0x00041304L)
+#define SCHED_S_TASK_NOT_SCHEDULED _HRESULT_TYPEDEF_(0x00041305L)
+#define SCHED_S_TASK_TERMINATED _HRESULT_TYPEDEF_(0x00041306L)
+#define SCHED_S_TASK_NO_VALID_TRIGGERS _HRESULT_TYPEDEF_(0x00041307L)
+#define SCHED_S_EVENT_TRIGGER _HRESULT_TYPEDEF_(0x00041308L)
+#define SCHED_E_TRIGGER_NOT_FOUND _HRESULT_TYPEDEF_(0x80041309L)
+#define SCHED_E_TASK_NOT_READY _HRESULT_TYPEDEF_(0x8004130AL)
+#define SCHED_E_TASK_NOT_RUNNING _HRESULT_TYPEDEF_(0x8004130BL)
+#define SCHED_E_SERVICE_NOT_INSTALLED _HRESULT_TYPEDEF_(0x8004130CL)
+#define SCHED_E_CANNOT_OPEN_TASK _HRESULT_TYPEDEF_(0x8004130DL)
+#define SCHED_E_INVALID_TASK _HRESULT_TYPEDEF_(0x8004130EL)
+#define SCHED_E_ACCOUNT_INFORMATION_NOT_SET _HRESULT_TYPEDEF_(0x8004130FL)
+#define SCHED_E_ACCOUNT_NAME_NOT_FOUND _HRESULT_TYPEDEF_(0x80041310L)
+#define SCHED_E_ACCOUNT_DBASE_CORRUPT _HRESULT_TYPEDEF_(0x80041311L)
+#define SCHED_E_NO_SECURITY_SERVICES _HRESULT_TYPEDEF_(0x80041312L)
+#define SCHED_E_UNKNOWN_OBJECT_VERSION _HRESULT_TYPEDEF_(0x80041313L)
+#define SCHED_E_UNSUPPORTED_ACCOUNT_OPTION _HRESULT_TYPEDEF_(0x80041314L)
+#define SCHED_E_SERVICE_NOT_RUNNING _HRESULT_TYPEDEF_(0x80041315L)
+#define CO_E_CLASS_CREATE_FAILED _HRESULT_TYPEDEF_(0x80080001L)
+#define CO_E_SCM_ERROR _HRESULT_TYPEDEF_(0x80080002L)
+#define CO_E_SCM_RPC_FAILURE _HRESULT_TYPEDEF_(0x80080003L)
+#define CO_E_BAD_PATH _HRESULT_TYPEDEF_(0x80080004L)
+#define CO_E_SERVER_EXEC_FAILURE _HRESULT_TYPEDEF_(0x80080005L)
+#define CO_E_OBJSRV_RPC_FAILURE _HRESULT_TYPEDEF_(0x80080006L)
+#define MK_E_NO_NORMALIZED _HRESULT_TYPEDEF_(0x80080007L)
+#define CO_E_SERVER_STOPPING _HRESULT_TYPEDEF_(0x80080008L)
+#define MEM_E_INVALID_ROOT _HRESULT_TYPEDEF_(0x80080009L)
+#define MEM_E_INVALID_LINK _HRESULT_TYPEDEF_(0x80080010L)
+#define MEM_E_INVALID_SIZE _HRESULT_TYPEDEF_(0x80080011L)
+#define CO_S_NOTALLINTERFACES _HRESULT_TYPEDEF_(0x00080012L)
+#define CO_S_MACHINENAMENOTFOUND _HRESULT_TYPEDEF_(0x00080013L)
+#define DISP_E_UNKNOWNINTERFACE _HRESULT_TYPEDEF_(0x80020001L)
+#define DISP_E_MEMBERNOTFOUND _HRESULT_TYPEDEF_(0x80020003L)
+#define DISP_E_PARAMNOTFOUND _HRESULT_TYPEDEF_(0x80020004L)
+#define DISP_E_TYPEMISMATCH _HRESULT_TYPEDEF_(0x80020005L)
+#define DISP_E_UNKNOWNNAME _HRESULT_TYPEDEF_(0x80020006L)
+#define DISP_E_NONAMEDARGS _HRESULT_TYPEDEF_(0x80020007L)
+#define DISP_E_BADVARTYPE _HRESULT_TYPEDEF_(0x80020008L)
+#define DISP_E_EXCEPTION _HRESULT_TYPEDEF_(0x80020009L)
+#define DISP_E_OVERFLOW _HRESULT_TYPEDEF_(0x8002000AL)
+#define DISP_E_BADINDEX _HRESULT_TYPEDEF_(0x8002000BL)
+#define DISP_E_UNKNOWNLCID _HRESULT_TYPEDEF_(0x8002000CL)
+#define DISP_E_ARRAYISLOCKED _HRESULT_TYPEDEF_(0x8002000DL)
+#define DISP_E_BADPARAMCOUNT _HRESULT_TYPEDEF_(0x8002000EL)
+#define DISP_E_PARAMNOTOPTIONAL _HRESULT_TYPEDEF_(0x8002000FL)
+#define DISP_E_BADCALLEE _HRESULT_TYPEDEF_(0x80020010L)
+#define DISP_E_NOTACOLLECTION _HRESULT_TYPEDEF_(0x80020011L)
+#define DISP_E_DIVBYZERO _HRESULT_TYPEDEF_(0x80020012L)
+#define DISP_E_BUFFERTOOSMALL _HRESULT_TYPEDEF_(0x80020013L)
+#define TYPE_E_BUFFERTOOSMALL _HRESULT_TYPEDEF_(0x80028016L)
+#define TYPE_E_FIELDNOTFOUND _HRESULT_TYPEDEF_(0x80028017L)
+#define TYPE_E_INVDATAREAD _HRESULT_TYPEDEF_(0x80028018L)
+#define TYPE_E_UNSUPFORMAT _HRESULT_TYPEDEF_(0x80028019L)
+#define TYPE_E_REGISTRYACCESS _HRESULT_TYPEDEF_(0x8002801CL)
+#define TYPE_E_LIBNOTREGISTERED _HRESULT_TYPEDEF_(0x8002801DL)
+#define TYPE_E_UNDEFINEDTYPE _HRESULT_TYPEDEF_(0x80028027L)
+#define TYPE_E_QUALIFIEDNAMEDISALLOWED _HRESULT_TYPEDEF_(0x80028028L)
+#define TYPE_E_INVALIDSTATE _HRESULT_TYPEDEF_(0x80028029L)
+#define TYPE_E_WRONGTYPEKIND _HRESULT_TYPEDEF_(0x8002802AL)
+#define TYPE_E_ELEMENTNOTFOUND _HRESULT_TYPEDEF_(0x8002802BL)
+#define TYPE_E_AMBIGUOUSNAME _HRESULT_TYPEDEF_(0x8002802CL)
+#define TYPE_E_NAMECONFLICT _HRESULT_TYPEDEF_(0x8002802DL)
+#define TYPE_E_UNKNOWNLCID _HRESULT_TYPEDEF_(0x8002802EL)
+#define TYPE_E_DLLFUNCTIONNOTFOUND _HRESULT_TYPEDEF_(0x8002802FL)
+#define TYPE_E_BADMODULEKIND _HRESULT_TYPEDEF_(0x800288BDL)
+#define TYPE_E_SIZETOOBIG _HRESULT_TYPEDEF_(0x800288C5L)
+#define TYPE_E_DUPLICATEID _HRESULT_TYPEDEF_(0x800288C6L)
+#define TYPE_E_INVALIDID _HRESULT_TYPEDEF_(0x800288CFL)
+#define TYPE_E_TYPEMISMATCH _HRESULT_TYPEDEF_(0x80028CA0L)
+#define TYPE_E_OUTOFBOUNDS _HRESULT_TYPEDEF_(0x80028CA1L)
+#define TYPE_E_IOERROR _HRESULT_TYPEDEF_(0x80028CA2L)
+#define TYPE_E_CANTCREATETMPFILE _HRESULT_TYPEDEF_(0x80028CA3L)
+#define TYPE_E_CANTLOADLIBRARY _HRESULT_TYPEDEF_(0x80029C4AL)
+#define TYPE_E_INCONSISTENTPROPFUNCS _HRESULT_TYPEDEF_(0x80029C83L)
+#define TYPE_E_CIRCULARTYPE _HRESULT_TYPEDEF_(0x80029C84L)
+#define STG_E_INVALIDFUNCTION _HRESULT_TYPEDEF_(0x80030001L)
+#define STG_E_FILENOTFOUND _HRESULT_TYPEDEF_(0x80030002L)
+#define STG_E_PATHNOTFOUND _HRESULT_TYPEDEF_(0x80030003L)
+#define STG_E_TOOMANYOPENFILES _HRESULT_TYPEDEF_(0x80030004L)
+#define STG_E_ACCESSDENIED _HRESULT_TYPEDEF_(0x80030005L)
+#define STG_E_INVALIDHANDLE _HRESULT_TYPEDEF_(0x80030006L)
+#define STG_E_INSUFFICIENTMEMORY _HRESULT_TYPEDEF_(0x80030008L)
+#define STG_E_INVALIDPOINTER _HRESULT_TYPEDEF_(0x80030009L)
+#define STG_E_NOMOREFILES _HRESULT_TYPEDEF_(0x80030012L)
+#define STG_E_DISKISWRITEPROTECTED _HRESULT_TYPEDEF_(0x80030013L)
+#define STG_E_SEEKERROR _HRESULT_TYPEDEF_(0x80030019L)
+#define STG_E_WRITEFAULT _HRESULT_TYPEDEF_(0x8003001DL)
+#define STG_E_READFAULT _HRESULT_TYPEDEF_(0x8003001EL)
+#define STG_E_SHAREVIOLATION _HRESULT_TYPEDEF_(0x80030020L)
+#define STG_E_LOCKVIOLATION _HRESULT_TYPEDEF_(0x80030021L)
+#define STG_E_FILEALREADYEXISTS _HRESULT_TYPEDEF_(0x80030050L)
+#define STG_E_INVALIDPARAMETER _HRESULT_TYPEDEF_(0x80030057L)
+#define STG_E_MEDIUMFULL _HRESULT_TYPEDEF_(0x80030070L)
+#define STG_E_PROPSETMISMATCHED _HRESULT_TYPEDEF_(0x800300F0L)
+#define STG_E_ABNORMALAPIEXIT _HRESULT_TYPEDEF_(0x800300FAL)
+#define STG_E_INVALIDHEADER _HRESULT_TYPEDEF_(0x800300FBL)
+#define STG_E_INVALIDNAME _HRESULT_TYPEDEF_(0x800300FCL)
+#define STG_E_UNKNOWN _HRESULT_TYPEDEF_(0x800300FDL)
+#define STG_E_UNIMPLEMENTEDFUNCTION _HRESULT_TYPEDEF_(0x800300FEL)
+#define STG_E_INVALIDFLAG _HRESULT_TYPEDEF_(0x800300FFL)
+#define STG_E_INUSE _HRESULT_TYPEDEF_(0x80030100L)
+#define STG_E_NOTCURRENT _HRESULT_TYPEDEF_(0x80030101L)
+#define STG_E_REVERTED _HRESULT_TYPEDEF_(0x80030102L)
+#define STG_E_CANTSAVE _HRESULT_TYPEDEF_(0x80030103L)
+#define STG_E_OLDFORMAT _HRESULT_TYPEDEF_(0x80030104L)
+#define STG_E_OLDDLL _HRESULT_TYPEDEF_(0x80030105L)
+#define STG_E_SHAREREQUIRED _HRESULT_TYPEDEF_(0x80030106L)
+#define STG_E_NOTFILEBASEDSTORAGE _HRESULT_TYPEDEF_(0x80030107L)
+#define STG_E_EXTANTMARSHALLINGS _HRESULT_TYPEDEF_(0x80030108L)
+#define STG_E_DOCFILECORRUPT _HRESULT_TYPEDEF_(0x80030109L)
+#define STG_E_BADBASEADDRESS _HRESULT_TYPEDEF_(0x80030110L)
+#define STG_E_DOCFILETOOLARGE _HRESULT_TYPEDEF_(0x80030111L)
+#define STG_E_NOTSIMPLEFORMAT _HRESULT_TYPEDEF_(0x80030112L)
+#define STG_E_INCOMPLETE _HRESULT_TYPEDEF_(0x80030201L)
+#define STG_E_TERMINATED _HRESULT_TYPEDEF_(0x80030202L)
+#define STG_S_CONVERTED _HRESULT_TYPEDEF_(0x00030200L)
+#define STG_S_BLOCK _HRESULT_TYPEDEF_(0x00030201L)
+#define STG_S_RETRYNOW _HRESULT_TYPEDEF_(0x00030202L)
+#define STG_S_MONITORING _HRESULT_TYPEDEF_(0x00030203L)
+#define STG_S_MULTIPLEOPENS _HRESULT_TYPEDEF_(0x00030204L)
+#define STG_S_CONSOLIDATIONFAILED _HRESULT_TYPEDEF_(0x00030205L)
+#define STG_S_CANNOTCONSOLIDATE _HRESULT_TYPEDEF_(0x00030206L)
+#define STG_E_STATUS_COPY_PROTECTION_FAILURE _HRESULT_TYPEDEF_(0x80030305L)
+#define STG_E_CSS_AUTHENTICATION_FAILURE _HRESULT_TYPEDEF_(0x80030306L)
+#define STG_E_CSS_KEY_NOT_PRESENT _HRESULT_TYPEDEF_(0x80030307L)
+#define STG_E_CSS_KEY_NOT_ESTABLISHED _HRESULT_TYPEDEF_(0x80030308L)
+#define STG_E_CSS_SCRAMBLED_SECTOR _HRESULT_TYPEDEF_(0x80030309L)
+#define STG_E_CSS_REGION_MISMATCH _HRESULT_TYPEDEF_(0x8003030AL)
+#define STG_E_RESETS_EXHAUSTED _HRESULT_TYPEDEF_(0x8003030BL)
+#define RPC_E_CALL_REJECTED _HRESULT_TYPEDEF_(0x80010001L)
+#define RPC_E_CALL_CANCELED _HRESULT_TYPEDEF_(0x80010002L)
+#define RPC_E_CANTPOST_INSENDCALL _HRESULT_TYPEDEF_(0x80010003L)
+#define RPC_E_CANTCALLOUT_INASYNCCALL _HRESULT_TYPEDEF_(0x80010004L)
+#define RPC_E_CANTCALLOUT_INEXTERNALCALL _HRESULT_TYPEDEF_(0x80010005L)
+#define RPC_E_CONNECTION_TERMINATED _HRESULT_TYPEDEF_(0x80010006L)
+#define RPC_E_SERVER_DIED _HRESULT_TYPEDEF_(0x80010007L)
+#define RPC_E_CLIENT_DIED _HRESULT_TYPEDEF_(0x80010008L)
+#define RPC_E_INVALID_DATAPACKET _HRESULT_TYPEDEF_(0x80010009L)
+#define RPC_E_CANTTRANSMIT_CALL _HRESULT_TYPEDEF_(0x8001000AL)
+#define RPC_E_CLIENT_CANTMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000BL)
+#define RPC_E_CLIENT_CANTUNMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000CL)
+#define RPC_E_SERVER_CANTMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000DL)
+#define RPC_E_SERVER_CANTUNMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000EL)
+#define RPC_E_INVALID_DATA _HRESULT_TYPEDEF_(0x8001000FL)
+#define RPC_E_INVALID_PARAMETER _HRESULT_TYPEDEF_(0x80010010L)
+#define RPC_E_CANTCALLOUT_AGAIN _HRESULT_TYPEDEF_(0x80010011L)
+#define RPC_E_SERVER_DIED_DNE _HRESULT_TYPEDEF_(0x80010012L)
+#define RPC_E_SYS_CALL_FAILED _HRESULT_TYPEDEF_(0x80010100L)
+#define RPC_E_OUT_OF_RESOURCES _HRESULT_TYPEDEF_(0x80010101L)
+#define RPC_E_ATTEMPTED_MULTITHREAD _HRESULT_TYPEDEF_(0x80010102L)
+#define RPC_E_NOT_REGISTERED _HRESULT_TYPEDEF_(0x80010103L)
+#define RPC_E_FAULT _HRESULT_TYPEDEF_(0x80010104L)
+#define RPC_E_SERVERFAULT _HRESULT_TYPEDEF_(0x80010105L)
+#define RPC_E_CHANGED_MODE _HRESULT_TYPEDEF_(0x80010106L)
+#define RPC_E_INVALIDMETHOD _HRESULT_TYPEDEF_(0x80010107L)
+#define RPC_E_DISCONNECTED _HRESULT_TYPEDEF_(0x80010108L)
+#define RPC_E_RETRY _HRESULT_TYPEDEF_(0x80010109L)
+#define RPC_E_SERVERCALL_RETRYLATER _HRESULT_TYPEDEF_(0x8001010AL)
+#define RPC_E_SERVERCALL_REJECTED _HRESULT_TYPEDEF_(0x8001010BL)
+#define RPC_E_INVALID_CALLDATA _HRESULT_TYPEDEF_(0x8001010CL)
+#define RPC_E_CANTCALLOUT_ININPUTSYNCCALL _HRESULT_TYPEDEF_(0x8001010DL)
+#define RPC_E_WRONG_THREAD _HRESULT_TYPEDEF_(0x8001010EL)
+#define RPC_E_THREAD_NOT_INIT _HRESULT_TYPEDEF_(0x8001010FL)
+#define RPC_E_VERSION_MISMATCH _HRESULT_TYPEDEF_(0x80010110L)
+#define RPC_E_INVALID_HEADER _HRESULT_TYPEDEF_(0x80010111L)
+#define RPC_E_INVALID_EXTENSION _HRESULT_TYPEDEF_(0x80010112L)
+#define RPC_E_INVALID_IPID _HRESULT_TYPEDEF_(0x80010113L)
+#define RPC_E_INVALID_OBJECT _HRESULT_TYPEDEF_(0x80010114L)
+#define RPC_S_CALLPENDING _HRESULT_TYPEDEF_(0x80010115L)
+#define RPC_S_WAITONTIMER _HRESULT_TYPEDEF_(0x80010116L)
+#define RPC_E_CALL_COMPLETE _HRESULT_TYPEDEF_(0x80010117L)
+#define RPC_E_UNSECURE_CALL _HRESULT_TYPEDEF_(0x80010118L)
+#define RPC_E_TOO_LATE _HRESULT_TYPEDEF_(0x80010119L)
+#define RPC_E_NO_GOOD_SECURITY_PACKAGES _HRESULT_TYPEDEF_(0x8001011AL)
+#define RPC_E_ACCESS_DENIED _HRESULT_TYPEDEF_(0x8001011BL)
+#define RPC_E_REMOTE_DISABLED _HRESULT_TYPEDEF_(0x8001011CL)
+#define RPC_E_INVALID_OBJREF _HRESULT_TYPEDEF_(0x8001011DL)
+#define RPC_E_NO_CONTEXT _HRESULT_TYPEDEF_(0x8001011EL)
+#define RPC_E_TIMEOUT _HRESULT_TYPEDEF_(0x8001011FL)
+#define RPC_E_NO_SYNC _HRESULT_TYPEDEF_(0x80010120L)
+#define RPC_E_FULLSIC_REQUIRED _HRESULT_TYPEDEF_(0x80010121L)
+#define RPC_E_INVALID_STD_NAME _HRESULT_TYPEDEF_(0x80010122L)
+#define CO_E_FAILEDTOIMPERSONATE _HRESULT_TYPEDEF_(0x80010123L)
+#define CO_E_FAILEDTOGETSECCTX _HRESULT_TYPEDEF_(0x80010124L)
+#define CO_E_FAILEDTOOPENTHREADTOKEN _HRESULT_TYPEDEF_(0x80010125L)
+#define CO_E_FAILEDTOGETTOKENINFO _HRESULT_TYPEDEF_(0x80010126L)
+#define CO_E_TRUSTEEDOESNTMATCHCLIENT _HRESULT_TYPEDEF_(0x80010127L)
+#define CO_E_FAILEDTOQUERYCLIENTBLANKET _HRESULT_TYPEDEF_(0x80010128L)
+#define CO_E_FAILEDTOSETDACL _HRESULT_TYPEDEF_(0x80010129L)
+#define CO_E_ACCESSCHECKFAILED _HRESULT_TYPEDEF_(0x8001012AL)
+#define CO_E_NETACCESSAPIFAILED _HRESULT_TYPEDEF_(0x8001012BL)
+#define CO_E_WRONGTRUSTEENAMESYNTAX _HRESULT_TYPEDEF_(0x8001012CL)
+#define CO_E_INVALIDSID _HRESULT_TYPEDEF_(0x8001012DL)
+#define CO_E_CONVERSIONFAILED _HRESULT_TYPEDEF_(0x8001012EL)
+#define CO_E_NOMATCHINGSIDFOUND _HRESULT_TYPEDEF_(0x8001012FL)
+#define CO_E_LOOKUPACCSIDFAILED _HRESULT_TYPEDEF_(0x80010130L)
+#define CO_E_NOMATCHINGNAMEFOUND _HRESULT_TYPEDEF_(0x80010131L)
+#define CO_E_LOOKUPACCNAMEFAILED _HRESULT_TYPEDEF_(0x80010132L)
+#define CO_E_SETSERLHNDLFAILED _HRESULT_TYPEDEF_(0x80010133L)
+#define CO_E_FAILEDTOGETWINDIR _HRESULT_TYPEDEF_(0x80010134L)
+#define CO_E_PATHTOOLONG _HRESULT_TYPEDEF_(0x80010135L)
+#define CO_E_FAILEDTOGENUUID _HRESULT_TYPEDEF_(0x80010136L)
+#define CO_E_FAILEDTOCREATEFILE _HRESULT_TYPEDEF_(0x80010137L)
+#define CO_E_FAILEDTOCLOSEHANDLE _HRESULT_TYPEDEF_(0x80010138L)
+#define CO_E_EXCEEDSYSACLLIMIT _HRESULT_TYPEDEF_(0x80010139L)
+#define CO_E_ACESINWRONGORDER _HRESULT_TYPEDEF_(0x8001013AL)
+#define CO_E_INCOMPATIBLESTREAMVERSION _HRESULT_TYPEDEF_(0x8001013BL)
+#define CO_E_FAILEDTOOPENPROCESSTOKEN _HRESULT_TYPEDEF_(0x8001013CL)
+#define CO_E_DECODEFAILED _HRESULT_TYPEDEF_(0x8001013DL)
+#define CO_E_ACNOTINITIALIZED _HRESULT_TYPEDEF_(0x8001013FL)
+#define CO_E_CANCEL_DISABLED _HRESULT_TYPEDEF_(0x80010140L)
+#define RPC_E_UNEXPECTED _HRESULT_TYPEDEF_(0x8001FFFFL)
+#define ERROR_AUDITING_DISABLED _HRESULT_TYPEDEF_(0xC0090001L)
+#define ERROR_ALL_SIDS_FILTERED _HRESULT_TYPEDEF_(0xC0090002L)
+#define NTE_BAD_UID _HRESULT_TYPEDEF_(0x80090001L)
+#define NTE_BAD_HASH _HRESULT_TYPEDEF_(0x80090002L)
+#define NTE_BAD_KEY _HRESULT_TYPEDEF_(0x80090003L)
+#define NTE_BAD_LEN _HRESULT_TYPEDEF_(0x80090004L)
+#define NTE_BAD_DATA _HRESULT_TYPEDEF_(0x80090005L)
+#define NTE_BAD_SIGNATURE _HRESULT_TYPEDEF_(0x80090006L)
+#define NTE_BAD_VER _HRESULT_TYPEDEF_(0x80090007L)
+#define NTE_BAD_ALGID _HRESULT_TYPEDEF_(0x80090008L)
+#define NTE_BAD_FLAGS _HRESULT_TYPEDEF_(0x80090009L)
+#define NTE_BAD_TYPE _HRESULT_TYPEDEF_(0x8009000AL)
+#define NTE_BAD_KEY_STATE _HRESULT_TYPEDEF_(0x8009000BL)
+#define NTE_BAD_HASH_STATE _HRESULT_TYPEDEF_(0x8009000CL)
+#define NTE_NO_KEY _HRESULT_TYPEDEF_(0x8009000DL)
+#define NTE_NO_MEMORY _HRESULT_TYPEDEF_(0x8009000EL)
+#define NTE_EXISTS _HRESULT_TYPEDEF_(0x8009000FL)
+#define NTE_PERM _HRESULT_TYPEDEF_(0x80090010L)
+#define NTE_NOT_FOUND _HRESULT_TYPEDEF_(0x80090011L)
+#define NTE_DOUBLE_ENCRYPT _HRESULT_TYPEDEF_(0x80090012L)
+#define NTE_BAD_PROVIDER _HRESULT_TYPEDEF_(0x80090013L)
+#define NTE_BAD_PROV_TYPE _HRESULT_TYPEDEF_(0x80090014L)
+#define NTE_BAD_PUBLIC_KEY _HRESULT_TYPEDEF_(0x80090015L)
+#define NTE_BAD_KEYSET _HRESULT_TYPEDEF_(0x80090016L)
+#define NTE_PROV_TYPE_NOT_DEF _HRESULT_TYPEDEF_(0x80090017L)
+#define NTE_PROV_TYPE_ENTRY_BAD _HRESULT_TYPEDEF_(0x80090018L)
+#define NTE_KEYSET_NOT_DEF _HRESULT_TYPEDEF_(0x80090019L)
+#define NTE_KEYSET_ENTRY_BAD _HRESULT_TYPEDEF_(0x8009001AL)
+#define NTE_PROV_TYPE_NO_MATCH _HRESULT_TYPEDEF_(0x8009001BL)
+#define NTE_SIGNATURE_FILE_BAD _HRESULT_TYPEDEF_(0x8009001CL)
+#define NTE_PROVIDER_DLL_FAIL _HRESULT_TYPEDEF_(0x8009001DL)
+#define NTE_PROV_DLL_NOT_FOUND _HRESULT_TYPEDEF_(0x8009001EL)
+#define NTE_BAD_KEYSET_PARAM _HRESULT_TYPEDEF_(0x8009001FL)
+#define NTE_FAIL _HRESULT_TYPEDEF_(0x80090020L)
+#define NTE_SYS_ERR _HRESULT_TYPEDEF_(0x80090021L)
+#define NTE_SILENT_CONTEXT _HRESULT_TYPEDEF_(0x80090022L)
+#define NTE_TOKEN_KEYSET_STORAGE_FULL _HRESULT_TYPEDEF_(0x80090023L)
+#define NTE_TEMPORARY_PROFILE _HRESULT_TYPEDEF_(0x80090024L)
+#define NTE_FIXEDPARAMETER _HRESULT_TYPEDEF_(0x80090025L)
+#define SEC_E_INSUFFICIENT_MEMORY _HRESULT_TYPEDEF_(0x80090300L)
+#define SEC_E_INVALID_HANDLE _HRESULT_TYPEDEF_(0x80090301L)
+#define SEC_E_UNSUPPORTED_FUNCTION _HRESULT_TYPEDEF_(0x80090302L)
+#define SEC_E_TARGET_UNKNOWN _HRESULT_TYPEDEF_(0x80090303L)
+#define SEC_E_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x80090304L)
+#define SEC_E_SECPKG_NOT_FOUND _HRESULT_TYPEDEF_(0x80090305L)
+#define SEC_E_NOT_OWNER _HRESULT_TYPEDEF_(0x80090306L)
+#define SEC_E_CANNOT_INSTALL _HRESULT_TYPEDEF_(0x80090307L)
+#define SEC_E_INVALID_TOKEN _HRESULT_TYPEDEF_(0x80090308L)
+#define SEC_E_CANNOT_PACK _HRESULT_TYPEDEF_(0x80090309L)
+#define SEC_E_QOP_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009030AL)
+#define SEC_E_NO_IMPERSONATION _HRESULT_TYPEDEF_(0x8009030BL)
+#define SEC_E_LOGON_DENIED _HRESULT_TYPEDEF_(0x8009030CL)
+#define SEC_E_UNKNOWN_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030DL)
+#define SEC_E_NO_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030EL)
+#define SEC_E_MESSAGE_ALTERED _HRESULT_TYPEDEF_(0x8009030FL)
+#define SEC_E_OUT_OF_SEQUENCE _HRESULT_TYPEDEF_(0x80090310L)
+#define SEC_E_NO_AUTHENTICATING_AUTHORITY _HRESULT_TYPEDEF_(0x80090311L)
+#define SEC_I_CONTINUE_NEEDED _HRESULT_TYPEDEF_(0x00090312L)
+#define SEC_I_COMPLETE_NEEDED _HRESULT_TYPEDEF_(0x00090313L)
+#define SEC_I_COMPLETE_AND_CONTINUE _HRESULT_TYPEDEF_(0x00090314L)
+#define SEC_I_LOCAL_LOGON _HRESULT_TYPEDEF_(0x00090315L)
+#define SEC_E_BAD_PKGID _HRESULT_TYPEDEF_(0x80090316L)
+#define SEC_E_CONTEXT_EXPIRED _HRESULT_TYPEDEF_(0x80090317L)
+#define SEC_I_CONTEXT_EXPIRED _HRESULT_TYPEDEF_(0x00090317L)
+#define SEC_E_INCOMPLETE_MESSAGE _HRESULT_TYPEDEF_(0x80090318L)
+#define SEC_E_INCOMPLETE_CREDENTIALS _HRESULT_TYPEDEF_(0x80090320L)
+#define SEC_E_BUFFER_TOO_SMALL _HRESULT_TYPEDEF_(0x80090321L)
+#define SEC_I_INCOMPLETE_CREDENTIALS _HRESULT_TYPEDEF_(0x00090320L)
+#define SEC_I_RENEGOTIATE _HRESULT_TYPEDEF_(0x00090321L)
+#define SEC_E_WRONG_PRINCIPAL _HRESULT_TYPEDEF_(0x80090322L)
+#define SEC_I_NO_LSA_CONTEXT _HRESULT_TYPEDEF_(0x00090323L)
+#define SEC_E_TIME_SKEW _HRESULT_TYPEDEF_(0x80090324L)
+#define SEC_E_UNTRUSTED_ROOT _HRESULT_TYPEDEF_(0x80090325L)
+#define SEC_E_ILLEGAL_MESSAGE _HRESULT_TYPEDEF_(0x80090326L)
+#define SEC_E_CERT_UNKNOWN _HRESULT_TYPEDEF_(0x80090327L)
+#define SEC_E_CERT_EXPIRED _HRESULT_TYPEDEF_(0x80090328L)
+#define SEC_E_ENCRYPT_FAILURE _HRESULT_TYPEDEF_(0x80090329L)
+#define SEC_E_DECRYPT_FAILURE _HRESULT_TYPEDEF_(0x80090330L)
+#define SEC_E_ALGORITHM_MISMATCH _HRESULT_TYPEDEF_(0x80090331L)
+#define SEC_E_SECURITY_QOS_FAILED _HRESULT_TYPEDEF_(0x80090332L)
+#define SEC_E_UNFINISHED_CONTEXT_DELETED _HRESULT_TYPEDEF_(0x80090333L)
+#define SEC_E_NO_TGT_REPLY _HRESULT_TYPEDEF_(0x80090334L)
+#define SEC_E_NO_IP_ADDRESSES _HRESULT_TYPEDEF_(0x80090335L)
+#define SEC_E_WRONG_CREDENTIAL_HANDLE _HRESULT_TYPEDEF_(0x80090336L)
+#define SEC_E_CRYPTO_SYSTEM_INVALID _HRESULT_TYPEDEF_(0x80090337L)
+#define SEC_E_MAX_REFERRALS_EXCEEDED _HRESULT_TYPEDEF_(0x80090338L)
+#define SEC_E_MUST_BE_KDC _HRESULT_TYPEDEF_(0x80090339L)
+#define SEC_E_STRONG_CRYPTO_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009033AL)
+#define SEC_E_TOO_MANY_PRINCIPALS _HRESULT_TYPEDEF_(0x8009033BL)
+#define SEC_E_NO_PA_DATA _HRESULT_TYPEDEF_(0x8009033CL)
+#define SEC_E_PKINIT_NAME_MISMATCH _HRESULT_TYPEDEF_(0x8009033DL)
+#define SEC_E_SMARTCARD_LOGON_REQUIRED _HRESULT_TYPEDEF_(0x8009033EL)
+#define SEC_E_SHUTDOWN_IN_PROGRESS _HRESULT_TYPEDEF_(0x8009033FL)
+#define SEC_E_KDC_INVALID_REQUEST _HRESULT_TYPEDEF_(0x80090340L)
+#define SEC_E_KDC_UNABLE_TO_REFER _HRESULT_TYPEDEF_(0x80090341L)
+#define SEC_E_KDC_UNKNOWN_ETYPE _HRESULT_TYPEDEF_(0x80090342L)
+#define SEC_E_UNSUPPORTED_PREAUTH _HRESULT_TYPEDEF_(0x80090343L)
+#define SEC_E_DELEGATION_REQUIRED _HRESULT_TYPEDEF_(0x80090345L)
+#define SEC_E_BAD_BINDINGS _HRESULT_TYPEDEF_(0x80090346L)
+#define SEC_E_MULTIPLE_ACCOUNTS _HRESULT_TYPEDEF_(0x80090347L)
+#define SEC_E_NO_KERB_KEY _HRESULT_TYPEDEF_(0x80090348L)
+#define SEC_E_CERT_WRONG_USAGE _HRESULT_TYPEDEF_(0x80090349L)
+#define SEC_E_DOWNGRADE_DETECTED _HRESULT_TYPEDEF_(0x80090350L)
+#define SEC_E_SMARTCARD_CERT_REVOKED _HRESULT_TYPEDEF_(0x80090351L)
+#define SEC_E_ISSUING_CA_UNTRUSTED _HRESULT_TYPEDEF_(0x80090352L)
+#define SEC_E_REVOCATION_OFFLINE_C _HRESULT_TYPEDEF_(0x80090353L)
+#define SEC_E_PKINIT_CLIENT_FAILURE _HRESULT_TYPEDEF_(0x80090354L)
+#define SEC_E_SMARTCARD_CERT_EXPIRED _HRESULT_TYPEDEF_(0x80090355L)
+#define SEC_E_NO_S4U_PROT_SUPPORT _HRESULT_TYPEDEF_(0x80090356L)
+#define SEC_E_CROSSREALM_DELEGATION_FAILURE _HRESULT_TYPEDEF_(0x80090357L)
+#define SEC_E_REVOCATION_OFFLINE_KDC _HRESULT_TYPEDEF_(0x80090358L)
+#define SEC_E_ISSUING_CA_UNTRUSTED_KDC _HRESULT_TYPEDEF_(0x80090359L)
+#define SEC_E_KDC_CERT_EXPIRED _HRESULT_TYPEDEF_(0x8009035AL)
+#define SEC_E_KDC_CERT_REVOKED _HRESULT_TYPEDEF_(0x8009035BL)
+#define SEC_E_NO_SPM SEC_E_INTERNAL_ERROR
+#define SEC_E_NOT_SUPPORTED SEC_E_UNSUPPORTED_FUNCTION
+#define CRYPT_E_MSG_ERROR _HRESULT_TYPEDEF_(0x80091001L)
+#define CRYPT_E_UNKNOWN_ALGO _HRESULT_TYPEDEF_(0x80091002L)
+#define CRYPT_E_OID_FORMAT _HRESULT_TYPEDEF_(0x80091003L)
+#define CRYPT_E_INVALID_MSG_TYPE _HRESULT_TYPEDEF_(0x80091004L)
+#define CRYPT_E_UNEXPECTED_ENCODING _HRESULT_TYPEDEF_(0x80091005L)
+#define CRYPT_E_AUTH_ATTR_MISSING _HRESULT_TYPEDEF_(0x80091006L)
+#define CRYPT_E_HASH_VALUE _HRESULT_TYPEDEF_(0x80091007L)
+#define CRYPT_E_INVALID_INDEX _HRESULT_TYPEDEF_(0x80091008L)
+#define CRYPT_E_ALREADY_DECRYPTED _HRESULT_TYPEDEF_(0x80091009L)
+#define CRYPT_E_NOT_DECRYPTED _HRESULT_TYPEDEF_(0x8009100AL)
+#define CRYPT_E_RECIPIENT_NOT_FOUND _HRESULT_TYPEDEF_(0x8009100BL)
+#define CRYPT_E_CONTROL_TYPE _HRESULT_TYPEDEF_(0x8009100CL)
+#define CRYPT_E_ISSUER_SERIALNUMBER _HRESULT_TYPEDEF_(0x8009100DL)
+#define CRYPT_E_SIGNER_NOT_FOUND _HRESULT_TYPEDEF_(0x8009100EL)
+#define CRYPT_E_ATTRIBUTES_MISSING _HRESULT_TYPEDEF_(0x8009100FL)
+#define CRYPT_E_STREAM_MSG_NOT_READY _HRESULT_TYPEDEF_(0x80091010L)
+#define CRYPT_E_STREAM_INSUFFICIENT_DATA _HRESULT_TYPEDEF_(0x80091011L)
+#define CRYPT_I_NEW_PROTECTION_REQUIRED _HRESULT_TYPEDEF_(0x00091012L)
+#define CRYPT_E_BAD_LEN _HRESULT_TYPEDEF_(0x80092001L)
+#define CRYPT_E_BAD_ENCODE _HRESULT_TYPEDEF_(0x80092002L)
+#define CRYPT_E_FILE_ERROR _HRESULT_TYPEDEF_(0x80092003L)
+#define CRYPT_E_NOT_FOUND _HRESULT_TYPEDEF_(0x80092004L)
+#define CRYPT_E_EXISTS _HRESULT_TYPEDEF_(0x80092005L)
+#define CRYPT_E_NO_PROVIDER _HRESULT_TYPEDEF_(0x80092006L)
+#define CRYPT_E_SELF_SIGNED _HRESULT_TYPEDEF_(0x80092007L)
+#define CRYPT_E_DELETED_PREV _HRESULT_TYPEDEF_(0x80092008L)
+#define CRYPT_E_NO_MATCH _HRESULT_TYPEDEF_(0x80092009L)
+#define CRYPT_E_UNEXPECTED_MSG_TYPE _HRESULT_TYPEDEF_(0x8009200AL)
+#define CRYPT_E_NO_KEY_PROPERTY _HRESULT_TYPEDEF_(0x8009200BL)
+#define CRYPT_E_NO_DECRYPT_CERT _HRESULT_TYPEDEF_(0x8009200CL)
+#define CRYPT_E_BAD_MSG _HRESULT_TYPEDEF_(0x8009200DL)
+#define CRYPT_E_NO_SIGNER _HRESULT_TYPEDEF_(0x8009200EL)
+#define CRYPT_E_PENDING_CLOSE _HRESULT_TYPEDEF_(0x8009200FL)
+#define CRYPT_E_REVOKED _HRESULT_TYPEDEF_(0x80092010L)
+#define CRYPT_E_NO_REVOCATION_DLL _HRESULT_TYPEDEF_(0x80092011L)
+#define CRYPT_E_NO_REVOCATION_CHECK _HRESULT_TYPEDEF_(0x80092012L)
+#define CRYPT_E_REVOCATION_OFFLINE _HRESULT_TYPEDEF_(0x80092013L)
+#define CRYPT_E_NOT_IN_REVOCATION_DATABASE _HRESULT_TYPEDEF_(0x80092014L)
+#define CRYPT_E_INVALID_NUMERIC_STRING _HRESULT_TYPEDEF_(0x80092020L)
+#define CRYPT_E_INVALID_PRINTABLE_STRING _HRESULT_TYPEDEF_(0x80092021L)
+#define CRYPT_E_INVALID_IA5_STRING _HRESULT_TYPEDEF_(0x80092022L)
+#define CRYPT_E_INVALID_X500_STRING _HRESULT_TYPEDEF_(0x80092023L)
+#define CRYPT_E_NOT_CHAR_STRING _HRESULT_TYPEDEF_(0x80092024L)
+#define CRYPT_E_FILERESIZED _HRESULT_TYPEDEF_(0x80092025L)
+#define CRYPT_E_SECURITY_SETTINGS _HRESULT_TYPEDEF_(0x80092026L)
+#define CRYPT_E_NO_VERIFY_USAGE_DLL _HRESULT_TYPEDEF_(0x80092027L)
+#define CRYPT_E_NO_VERIFY_USAGE_CHECK _HRESULT_TYPEDEF_(0x80092028L)
+#define CRYPT_E_VERIFY_USAGE_OFFLINE _HRESULT_TYPEDEF_(0x80092029L)
+#define CRYPT_E_NOT_IN_CTL _HRESULT_TYPEDEF_(0x8009202AL)
+#define CRYPT_E_NO_TRUSTED_SIGNER _HRESULT_TYPEDEF_(0x8009202BL)
+#define CRYPT_E_MISSING_PUBKEY_PARA _HRESULT_TYPEDEF_(0x8009202CL)
+#define CRYPT_E_OSS_ERROR _HRESULT_TYPEDEF_(0x80093000L)
+#define OSS_MORE_BUF _HRESULT_TYPEDEF_(0x80093001L)
+#define OSS_NEGATIVE_UINTEGER _HRESULT_TYPEDEF_(0x80093002L)
+#define OSS_PDU_RANGE _HRESULT_TYPEDEF_(0x80093003L)
+#define OSS_MORE_INPUT _HRESULT_TYPEDEF_(0x80093004L)
+#define OSS_DATA_ERROR _HRESULT_TYPEDEF_(0x80093005L)
+#define OSS_BAD_ARG _HRESULT_TYPEDEF_(0x80093006L)
+#define OSS_BAD_VERSION _HRESULT_TYPEDEF_(0x80093007L)
+#define OSS_OUT_MEMORY _HRESULT_TYPEDEF_(0x80093008L)
+#define OSS_PDU_MISMATCH _HRESULT_TYPEDEF_(0x80093009L)
+#define OSS_LIMITED _HRESULT_TYPEDEF_(0x8009300AL)
+#define OSS_BAD_PTR _HRESULT_TYPEDEF_(0x8009300BL)
+#define OSS_BAD_TIME _HRESULT_TYPEDEF_(0x8009300CL)
+#define OSS_INDEFINITE_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009300DL)
+#define OSS_MEM_ERROR _HRESULT_TYPEDEF_(0x8009300EL)
+#define OSS_BAD_TABLE _HRESULT_TYPEDEF_(0x8009300FL)
+#define OSS_TOO_LONG _HRESULT_TYPEDEF_(0x80093010L)
+#define OSS_CONSTRAINT_VIOLATED _HRESULT_TYPEDEF_(0x80093011L)
+#define OSS_FATAL_ERROR _HRESULT_TYPEDEF_(0x80093012L)
+#define OSS_ACCESS_SERIALIZATION_ERROR _HRESULT_TYPEDEF_(0x80093013L)
+#define OSS_NULL_TBL _HRESULT_TYPEDEF_(0x80093014L)
+#define OSS_NULL_FCN _HRESULT_TYPEDEF_(0x80093015L)
+#define OSS_BAD_ENCRULES _HRESULT_TYPEDEF_(0x80093016L)
+#define OSS_UNAVAIL_ENCRULES _HRESULT_TYPEDEF_(0x80093017L)
+#define OSS_CANT_OPEN_TRACE_WINDOW _HRESULT_TYPEDEF_(0x80093018L)
+#define OSS_UNIMPLEMENTED _HRESULT_TYPEDEF_(0x80093019L)
+#define OSS_OID_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009301AL)
+#define OSS_CANT_OPEN_TRACE_FILE _HRESULT_TYPEDEF_(0x8009301BL)
+#define OSS_TRACE_FILE_ALREADY_OPEN _HRESULT_TYPEDEF_(0x8009301CL)
+#define OSS_TABLE_MISMATCH _HRESULT_TYPEDEF_(0x8009301DL)
+#define OSS_TYPE_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009301EL)
+#define OSS_REAL_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009301FL)
+#define OSS_REAL_CODE_NOT_LINKED _HRESULT_TYPEDEF_(0x80093020L)
+#define OSS_OUT_OF_RANGE _HRESULT_TYPEDEF_(0x80093021L)
+#define OSS_COPIER_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093022L)
+#define OSS_CONSTRAINT_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093023L)
+#define OSS_COMPARATOR_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093024L)
+#define OSS_COMPARATOR_CODE_NOT_LINKED _HRESULT_TYPEDEF_(0x80093025L)
+#define OSS_MEM_MGR_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093026L)
+#define OSS_PDV_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093027L)
+#define OSS_PDV_CODE_NOT_LINKED _HRESULT_TYPEDEF_(0x80093028L)
+#define OSS_API_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093029L)
+#define OSS_BERDER_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009302AL)
+#define OSS_PER_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009302BL)
+#define OSS_OPEN_TYPE_ERROR _HRESULT_TYPEDEF_(0x8009302CL)
+#define OSS_MUTEX_NOT_CREATED _HRESULT_TYPEDEF_(0x8009302DL)
+#define OSS_CANT_CLOSE_TRACE_FILE _HRESULT_TYPEDEF_(0x8009302EL)
+#define CRYPT_E_ASN1_ERROR _HRESULT_TYPEDEF_(0x80093100L)
+#define CRYPT_E_ASN1_INTERNAL _HRESULT_TYPEDEF_(0x80093101L)
+#define CRYPT_E_ASN1_EOD _HRESULT_TYPEDEF_(0x80093102L)
+#define CRYPT_E_ASN1_CORRUPT _HRESULT_TYPEDEF_(0x80093103L)
+#define CRYPT_E_ASN1_LARGE _HRESULT_TYPEDEF_(0x80093104L)
+#define CRYPT_E_ASN1_CONSTRAINT _HRESULT_TYPEDEF_(0x80093105L)
+#define CRYPT_E_ASN1_MEMORY _HRESULT_TYPEDEF_(0x80093106L)
+#define CRYPT_E_ASN1_OVERFLOW _HRESULT_TYPEDEF_(0x80093107L)
+#define CRYPT_E_ASN1_BADPDU _HRESULT_TYPEDEF_(0x80093108L)
+#define CRYPT_E_ASN1_BADARGS _HRESULT_TYPEDEF_(0x80093109L)
+#define CRYPT_E_ASN1_BADREAL _HRESULT_TYPEDEF_(0x8009310AL)
+#define CRYPT_E_ASN1_BADTAG _HRESULT_TYPEDEF_(0x8009310BL)
+#define CRYPT_E_ASN1_CHOICE _HRESULT_TYPEDEF_(0x8009310CL)
+#define CRYPT_E_ASN1_RULE _HRESULT_TYPEDEF_(0x8009310DL)
+#define CRYPT_E_ASN1_UTF8 _HRESULT_TYPEDEF_(0x8009310EL)
+#define CRYPT_E_ASN1_PDU_TYPE _HRESULT_TYPEDEF_(0x80093133L)
+#define CRYPT_E_ASN1_NYI _HRESULT_TYPEDEF_(0x80093134L)
+#define CRYPT_E_ASN1_EXTENDED _HRESULT_TYPEDEF_(0x80093201L)
+#define CRYPT_E_ASN1_NOEOD _HRESULT_TYPEDEF_(0x80093202L)
+#define CERTSRV_E_BAD_REQUESTSUBJECT _HRESULT_TYPEDEF_(0x80094001L)
+#define CERTSRV_E_NO_REQUEST _HRESULT_TYPEDEF_(0x80094002L)
+#define CERTSRV_E_BAD_REQUESTSTATUS _HRESULT_TYPEDEF_(0x80094003L)
+#define CERTSRV_E_PROPERTY_EMPTY _HRESULT_TYPEDEF_(0x80094004L)
+#define CERTSRV_E_INVALID_CA_CERTIFICATE _HRESULT_TYPEDEF_(0x80094005L)
+#define CERTSRV_E_SERVER_SUSPENDED _HRESULT_TYPEDEF_(0x80094006L)
+#define CERTSRV_E_ENCODING_LENGTH _HRESULT_TYPEDEF_(0x80094007L)
+#define CERTSRV_E_ROLECONFLICT _HRESULT_TYPEDEF_(0x80094008L)
+#define CERTSRV_E_RESTRICTEDOFFICER _HRESULT_TYPEDEF_(0x80094009L)
+#define CERTSRV_E_KEY_ARCHIVAL_NOT_CONFIGURED _HRESULT_TYPEDEF_(0x8009400AL)
+#define CERTSRV_E_NO_VALID_KRA _HRESULT_TYPEDEF_(0x8009400BL)
+#define CERTSRV_E_BAD_REQUEST_KEY_ARCHIVAL _HRESULT_TYPEDEF_(0x8009400CL)
+#define CERTSRV_E_NO_CAADMIN_DEFINED _HRESULT_TYPEDEF_(0x8009400DL)
+#define CERTSRV_E_BAD_RENEWAL_CERT_ATTRIBUTE _HRESULT_TYPEDEF_(0x8009400EL)
+#define CERTSRV_E_NO_DB_SESSIONS _HRESULT_TYPEDEF_(0x8009400FL)
+#define CERTSRV_E_ALIGNMENT_FAULT _HRESULT_TYPEDEF_(0x80094010L)
+#define CERTSRV_E_ENROLL_DENIED _HRESULT_TYPEDEF_(0x80094011L)
+#define CERTSRV_E_TEMPLATE_DENIED _HRESULT_TYPEDEF_(0x80094012L)
+#define CERTSRV_E_DOWNLEVEL_DC_SSL_OR_UPGRADE _HRESULT_TYPEDEF_(0x80094013L)
+#define CERTSRV_E_UNSUPPORTED_CERT_TYPE _HRESULT_TYPEDEF_(0x80094800L)
+#define CERTSRV_E_NO_CERT_TYPE _HRESULT_TYPEDEF_(0x80094801L)
+#define CERTSRV_E_TEMPLATE_CONFLICT _HRESULT_TYPEDEF_(0x80094802L)
+#define CERTSRV_E_SUBJECT_ALT_NAME_REQUIRED _HRESULT_TYPEDEF_(0x80094803L)
+#define CERTSRV_E_ARCHIVED_KEY_REQUIRED _HRESULT_TYPEDEF_(0x80094804L)
+#define CERTSRV_E_SMIME_REQUIRED _HRESULT_TYPEDEF_(0x80094805L)
+#define CERTSRV_E_BAD_RENEWAL_SUBJECT _HRESULT_TYPEDEF_(0x80094806L)
+#define CERTSRV_E_BAD_TEMPLATE_VERSION _HRESULT_TYPEDEF_(0x80094807L)
+#define CERTSRV_E_TEMPLATE_POLICY_REQUIRED _HRESULT_TYPEDEF_(0x80094808L)
+#define CERTSRV_E_SIGNATURE_POLICY_REQUIRED _HRESULT_TYPEDEF_(0x80094809L)
+#define CERTSRV_E_SIGNATURE_COUNT _HRESULT_TYPEDEF_(0x8009480AL)
+#define CERTSRV_E_SIGNATURE_REJECTED _HRESULT_TYPEDEF_(0x8009480BL)
+#define CERTSRV_E_ISSUANCE_POLICY_REQUIRED _HRESULT_TYPEDEF_(0x8009480CL)
+#define CERTSRV_E_SUBJECT_UPN_REQUIRED _HRESULT_TYPEDEF_(0x8009480DL)
+#define CERTSRV_E_SUBJECT_DIRECTORY_GUID_REQUIRED _HRESULT_TYPEDEF_(0x8009480EL)
+#define CERTSRV_E_SUBJECT_DNS_REQUIRED _HRESULT_TYPEDEF_(0x8009480FL)
+#define CERTSRV_E_ARCHIVED_KEY_UNEXPECTED _HRESULT_TYPEDEF_(0x80094810L)
+#define CERTSRV_E_KEY_LENGTH _HRESULT_TYPEDEF_(0x80094811L)
+#define CERTSRV_E_SUBJECT_EMAIL_REQUIRED _HRESULT_TYPEDEF_(0x80094812L)
+#define CERTSRV_E_UNKNOWN_CERT_TYPE _HRESULT_TYPEDEF_(0x80094813L)
+#define CERTSRV_E_CERT_TYPE_OVERLAP _HRESULT_TYPEDEF_(0x80094814L)
+#define XENROLL_E_KEY_NOT_EXPORTABLE _HRESULT_TYPEDEF_(0x80095000L)
+#define XENROLL_E_CANNOT_ADD_ROOT_CERT _HRESULT_TYPEDEF_(0x80095001L)
+#define XENROLL_E_RESPONSE_KA_HASH_NOT_FOUND _HRESULT_TYPEDEF_(0x80095002L)
+#define XENROLL_E_RESPONSE_UNEXPECTED_KA_HASH _HRESULT_TYPEDEF_(0x80095003L)
+#define XENROLL_E_RESPONSE_KA_HASH_MISMATCH _HRESULT_TYPEDEF_(0x80095004L)
+#define XENROLL_E_KEYSPEC_SMIME_MISMATCH _HRESULT_TYPEDEF_(0x80095005L)
+#define TRUST_E_SYSTEM_ERROR _HRESULT_TYPEDEF_(0x80096001L)
+#define TRUST_E_NO_SIGNER_CERT _HRESULT_TYPEDEF_(0x80096002L)
+#define TRUST_E_COUNTER_SIGNER _HRESULT_TYPEDEF_(0x80096003L)
+#define TRUST_E_CERT_SIGNATURE _HRESULT_TYPEDEF_(0x80096004L)
+#define TRUST_E_TIME_STAMP _HRESULT_TYPEDEF_(0x80096005L)
+#define TRUST_E_BAD_DIGEST _HRESULT_TYPEDEF_(0x80096010L)
+#define TRUST_E_BASIC_CONSTRAINTS _HRESULT_TYPEDEF_(0x80096019L)
+#define TRUST_E_FINANCIAL_CRITERIA _HRESULT_TYPEDEF_(0x8009601EL)
+#define MSSIPOTF_E_OUTOFMEMRANGE _HRESULT_TYPEDEF_(0x80097001L)
+#define MSSIPOTF_E_CANTGETOBJECT _HRESULT_TYPEDEF_(0x80097002L)
+#define MSSIPOTF_E_NOHEADTABLE _HRESULT_TYPEDEF_(0x80097003L)
+#define MSSIPOTF_E_BAD_MAGICNUMBER _HRESULT_TYPEDEF_(0x80097004L)
+#define MSSIPOTF_E_BAD_OFFSET_TABLE _HRESULT_TYPEDEF_(0x80097005L)
+#define MSSIPOTF_E_TABLE_TAGORDER _HRESULT_TYPEDEF_(0x80097006L)
+#define MSSIPOTF_E_TABLE_LONGWORD _HRESULT_TYPEDEF_(0x80097007L)
+#define MSSIPOTF_E_BAD_FIRST_TABLE_PLACEMENT _HRESULT_TYPEDEF_(0x80097008L)
+#define MSSIPOTF_E_TABLES_OVERLAP _HRESULT_TYPEDEF_(0x80097009L)
+#define MSSIPOTF_E_TABLE_PADBYTES _HRESULT_TYPEDEF_(0x8009700AL)
+#define MSSIPOTF_E_FILETOOSMALL _HRESULT_TYPEDEF_(0x8009700BL)
+#define MSSIPOTF_E_TABLE_CHECKSUM _HRESULT_TYPEDEF_(0x8009700CL)
+#define MSSIPOTF_E_FILE_CHECKSUM _HRESULT_TYPEDEF_(0x8009700DL)
+#define MSSIPOTF_E_FAILED_POLICY _HRESULT_TYPEDEF_(0x80097010L)
+#define MSSIPOTF_E_FAILED_HINTS_CHECK _HRESULT_TYPEDEF_(0x80097011L)
+#define MSSIPOTF_E_NOT_OPENTYPE _HRESULT_TYPEDEF_(0x80097012L)
+#define MSSIPOTF_E_FILE _HRESULT_TYPEDEF_(0x80097013L)
+#define MSSIPOTF_E_CRYPT _HRESULT_TYPEDEF_(0x80097014L)
+#define MSSIPOTF_E_BADVERSION _HRESULT_TYPEDEF_(0x80097015L)
+#define MSSIPOTF_E_DSIG_STRUCTURE _HRESULT_TYPEDEF_(0x80097016L)
+#define MSSIPOTF_E_PCONST_CHECK _HRESULT_TYPEDEF_(0x80097017L)
+#define MSSIPOTF_E_STRUCTURE _HRESULT_TYPEDEF_(0x80097018L)
+#define NTE_OP_OK 0
+#define TRUST_E_PROVIDER_UNKNOWN _HRESULT_TYPEDEF_(0x800B0001L)
+#define TRUST_E_ACTION_UNKNOWN _HRESULT_TYPEDEF_(0x800B0002L)
+#define TRUST_E_SUBJECT_FORM_UNKNOWN _HRESULT_TYPEDEF_(0x800B0003L)
+#define TRUST_E_SUBJECT_NOT_TRUSTED _HRESULT_TYPEDEF_(0x800B0004L)
+#define DIGSIG_E_ENCODE _HRESULT_TYPEDEF_(0x800B0005L)
+#define DIGSIG_E_DECODE _HRESULT_TYPEDEF_(0x800B0006L)
+#define DIGSIG_E_EXTENSIBILITY _HRESULT_TYPEDEF_(0x800B0007L)
+#define DIGSIG_E_CRYPTO _HRESULT_TYPEDEF_(0x800B0008L)
+#define PERSIST_E_SIZEDEFINITE _HRESULT_TYPEDEF_(0x800B0009L)
+#define PERSIST_E_SIZEINDEFINITE _HRESULT_TYPEDEF_(0x800B000AL)
+#define PERSIST_E_NOTSELFSIZING _HRESULT_TYPEDEF_(0x800B000BL)
+#define TRUST_E_NOSIGNATURE _HRESULT_TYPEDEF_(0x800B0100L)
+#define CERT_E_EXPIRED _HRESULT_TYPEDEF_(0x800B0101L)
+#define CERT_E_VALIDITYPERIODNESTING _HRESULT_TYPEDEF_(0x800B0102L)
+#define CERT_E_ROLE _HRESULT_TYPEDEF_(0x800B0103L)
+#define CERT_E_PATHLENCONST _HRESULT_TYPEDEF_(0x800B0104L)
+#define CERT_E_CRITICAL _HRESULT_TYPEDEF_(0x800B0105L)
+#define CERT_E_PURPOSE _HRESULT_TYPEDEF_(0x800B0106L)
+#define CERT_E_ISSUERCHAINING _HRESULT_TYPEDEF_(0x800B0107L)
+#define CERT_E_MALFORMED _HRESULT_TYPEDEF_(0x800B0108L)
+#define CERT_E_UNTRUSTEDROOT _HRESULT_TYPEDEF_(0x800B0109L)
+#define CERT_E_CHAINING _HRESULT_TYPEDEF_(0x800B010AL)
+#define TRUST_E_FAIL _HRESULT_TYPEDEF_(0x800B010BL)
+#define CERT_E_REVOKED _HRESULT_TYPEDEF_(0x800B010CL)
+#define CERT_E_UNTRUSTEDTESTROOT _HRESULT_TYPEDEF_(0x800B010DL)
+#define CERT_E_REVOCATION_FAILURE _HRESULT_TYPEDEF_(0x800B010EL)
+#define CERT_E_CN_NO_MATCH _HRESULT_TYPEDEF_(0x800B010FL)
+#define CERT_E_WRONG_USAGE _HRESULT_TYPEDEF_(0x800B0110L)
+#define TRUST_E_EXPLICIT_DISTRUST _HRESULT_TYPEDEF_(0x800B0111L)
+#define CERT_E_UNTRUSTEDCA _HRESULT_TYPEDEF_(0x800B0112L)
+#define CERT_E_INVALID_POLICY _HRESULT_TYPEDEF_(0x800B0113L)
+#define CERT_E_INVALID_NAME _HRESULT_TYPEDEF_(0x800B0114L)
+#define HRESULT_FROM_SETUPAPI(x) ((((x) & (APPLICATION_ERROR_MASK|ERROR_SEVERITY_ERROR))==(APPLICATION_ERROR_MASK|ERROR_SEVERITY_ERROR)) ? ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_SETUPAPI << 16) | 0x80000000)) : HRESULT_FROM_WIN32(x))
+#define SPAPI_E_EXPECTED_SECTION_NAME _HRESULT_TYPEDEF_(0x800F0000L)
+#define SPAPI_E_BAD_SECTION_NAME_LINE _HRESULT_TYPEDEF_(0x800F0001L)
+#define SPAPI_E_SECTION_NAME_TOO_LONG _HRESULT_TYPEDEF_(0x800F0002L)
+#define SPAPI_E_GENERAL_SYNTAX _HRESULT_TYPEDEF_(0x800F0003L)
+#define SPAPI_E_WRONG_INF_STYLE _HRESULT_TYPEDEF_(0x800F0100L)
+#define SPAPI_E_SECTION_NOT_FOUND _HRESULT_TYPEDEF_(0x800F0101L)
+#define SPAPI_E_LINE_NOT_FOUND _HRESULT_TYPEDEF_(0x800F0102L)
+#define SPAPI_E_NO_BACKUP _HRESULT_TYPEDEF_(0x800F0103L)
+#define SPAPI_E_NO_ASSOCIATED_CLASS _HRESULT_TYPEDEF_(0x800F0200L)
+#define SPAPI_E_CLASS_MISMATCH _HRESULT_TYPEDEF_(0x800F0201L)
+#define SPAPI_E_DUPLICATE_FOUND _HRESULT_TYPEDEF_(0x800F0202L)
+#define SPAPI_E_NO_DRIVER_SELECTED _HRESULT_TYPEDEF_(0x800F0203L)
+#define SPAPI_E_KEY_DOES_NOT_EXIST _HRESULT_TYPEDEF_(0x800F0204L)
+#define SPAPI_E_INVALID_DEVINST_NAME _HRESULT_TYPEDEF_(0x800F0205L)
+#define SPAPI_E_INVALID_CLASS _HRESULT_TYPEDEF_(0x800F0206L)
+#define SPAPI_E_DEVINST_ALREADY_EXISTS _HRESULT_TYPEDEF_(0x800F0207L)
+#define SPAPI_E_DEVINFO_NOT_REGISTERED _HRESULT_TYPEDEF_(0x800F0208L)
+#define SPAPI_E_INVALID_REG_PROPERTY _HRESULT_TYPEDEF_(0x800F0209L)
+#define SPAPI_E_NO_INF _HRESULT_TYPEDEF_(0x800F020AL)
+#define SPAPI_E_NO_SUCH_DEVINST _HRESULT_TYPEDEF_(0x800F020BL)
+#define SPAPI_E_CANT_LOAD_CLASS_ICON _HRESULT_TYPEDEF_(0x800F020CL)
+#define SPAPI_E_INVALID_CLASS_INSTALLER _HRESULT_TYPEDEF_(0x800F020DL)
+#define SPAPI_E_DI_DO_DEFAULT _HRESULT_TYPEDEF_(0x800F020EL)
+#define SPAPI_E_DI_NOFILECOPY _HRESULT_TYPEDEF_(0x800F020FL)
+#define SPAPI_E_INVALID_HWPROFILE _HRESULT_TYPEDEF_(0x800F0210L)
+#define SPAPI_E_NO_DEVICE_SELECTED _HRESULT_TYPEDEF_(0x800F0211L)
+#define SPAPI_E_DEVINFO_LIST_LOCKED _HRESULT_TYPEDEF_(0x800F0212L)
+#define SPAPI_E_DEVINFO_DATA_LOCKED _HRESULT_TYPEDEF_(0x800F0213L)
+#define SPAPI_E_DI_BAD_PATH _HRESULT_TYPEDEF_(0x800F0214L)
+#define SPAPI_E_NO_CLASSINSTALL_PARAMS _HRESULT_TYPEDEF_(0x800F0215L)
+#define SPAPI_E_FILEQUEUE_LOCKED _HRESULT_TYPEDEF_(0x800F0216L)
+#define SPAPI_E_BAD_SERVICE_INSTALLSECT _HRESULT_TYPEDEF_(0x800F0217L)
+#define SPAPI_E_NO_CLASS_DRIVER_LIST _HRESULT_TYPEDEF_(0x800F0218L)
+#define SPAPI_E_NO_ASSOCIATED_SERVICE _HRESULT_TYPEDEF_(0x800F0219L)
+#define SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE _HRESULT_TYPEDEF_(0x800F021AL)
+#define SPAPI_E_DEVICE_INTERFACE_ACTIVE _HRESULT_TYPEDEF_(0x800F021BL)
+#define SPAPI_E_DEVICE_INTERFACE_REMOVED _HRESULT_TYPEDEF_(0x800F021CL)
+#define SPAPI_E_BAD_INTERFACE_INSTALLSECT _HRESULT_TYPEDEF_(0x800F021DL)
+#define SPAPI_E_NO_SUCH_INTERFACE_CLASS _HRESULT_TYPEDEF_(0x800F021EL)
+#define SPAPI_E_INVALID_REFERENCE_STRING _HRESULT_TYPEDEF_(0x800F021FL)
+#define SPAPI_E_INVALID_MACHINENAME _HRESULT_TYPEDEF_(0x800F0220L)
+#define SPAPI_E_REMOTE_COMM_FAILURE _HRESULT_TYPEDEF_(0x800F0221L)
+#define SPAPI_E_MACHINE_UNAVAILABLE _HRESULT_TYPEDEF_(0x800F0222L)
+#define SPAPI_E_NO_CONFIGMGR_SERVICES _HRESULT_TYPEDEF_(0x800F0223L)
+#define SPAPI_E_INVALID_PROPPAGE_PROVIDER _HRESULT_TYPEDEF_(0x800F0224L)
+#define SPAPI_E_NO_SUCH_DEVICE_INTERFACE _HRESULT_TYPEDEF_(0x800F0225L)
+#define SPAPI_E_DI_POSTPROCESSING_REQUIRED _HRESULT_TYPEDEF_(0x800F0226L)
+#define SPAPI_E_INVALID_COINSTALLER _HRESULT_TYPEDEF_(0x800F0227L)
+#define SPAPI_E_NO_COMPAT_DRIVERS _HRESULT_TYPEDEF_(0x800F0228L)
+#define SPAPI_E_NO_DEVICE_ICON _HRESULT_TYPEDEF_(0x800F0229L)
+#define SPAPI_E_INVALID_INF_LOGCONFIG _HRESULT_TYPEDEF_(0x800F022AL)
+#define SPAPI_E_DI_DONT_INSTALL _HRESULT_TYPEDEF_(0x800F022BL)
+#define SPAPI_E_INVALID_FILTER_DRIVER _HRESULT_TYPEDEF_(0x800F022CL)
+#define SPAPI_E_NON_WINDOWS_NT_DRIVER _HRESULT_TYPEDEF_(0x800F022DL)
+#define SPAPI_E_NON_WINDOWS_DRIVER _HRESULT_TYPEDEF_(0x800F022EL)
+#define SPAPI_E_NO_CATALOG_FOR_OEM_INF _HRESULT_TYPEDEF_(0x800F022FL)
+#define SPAPI_E_DEVINSTALL_QUEUE_NONNATIVE _HRESULT_TYPEDEF_(0x800F0230L)
+#define SPAPI_E_NOT_DISABLEABLE _HRESULT_TYPEDEF_(0x800F0231L)
+#define SPAPI_E_CANT_REMOVE_DEVINST _HRESULT_TYPEDEF_(0x800F0232L)
+#define SPAPI_E_INVALID_TARGET _HRESULT_TYPEDEF_(0x800F0233L)
+#define SPAPI_E_DRIVER_NONNATIVE _HRESULT_TYPEDEF_(0x800F0234L)
+#define SPAPI_E_IN_WOW64 _HRESULT_TYPEDEF_(0x800F0235L)
+#define SPAPI_E_SET_SYSTEM_RESTORE_POINT _HRESULT_TYPEDEF_(0x800F0236L)
+#define SPAPI_E_INCORRECTLY_COPIED_INF _HRESULT_TYPEDEF_(0x800F0237L)
+#define SPAPI_E_SCE_DISABLED _HRESULT_TYPEDEF_(0x800F0238L)
+#define SPAPI_E_UNKNOWN_EXCEPTION _HRESULT_TYPEDEF_(0x800F0239L)
+#define SPAPI_E_PNP_REGISTRY_ERROR _HRESULT_TYPEDEF_(0x800F023AL)
+#define SPAPI_E_REMOTE_REQUEST_UNSUPPORTED _HRESULT_TYPEDEF_(0x800F023BL)
+#define SPAPI_E_NOT_AN_INSTALLED_OEM_INF _HRESULT_TYPEDEF_(0x800F023CL)
+#define SPAPI_E_INF_IN_USE_BY_DEVICES _HRESULT_TYPEDEF_(0x800F023DL)
+#define SPAPI_E_DI_FUNCTION_OBSOLETE _HRESULT_TYPEDEF_(0x800F023EL)
+#define SPAPI_E_NO_AUTHENTICODE_CATALOG _HRESULT_TYPEDEF_(0x800F023FL)
+#define SPAPI_E_AUTHENTICODE_DISALLOWED _HRESULT_TYPEDEF_(0x800F0240L)
+#define SPAPI_E_AUTHENTICODE_TRUSTED_PUBLISHER _HRESULT_TYPEDEF_(0x800F0241L)
+#define SPAPI_E_AUTHENTICODE_TRUST_NOT_ESTABLISHED _HRESULT_TYPEDEF_(0x800F0242L)
+#define SPAPI_E_AUTHENTICODE_PUBLISHER_NOT_TRUSTED _HRESULT_TYPEDEF_(0x800F0243L)
+#define SPAPI_E_SIGNATURE_OSATTRIBUTE_MISMATCH _HRESULT_TYPEDEF_(0x800F0244L)
+#define SPAPI_E_ONLY_VALIDATE_VIA_AUTHENTICODE _HRESULT_TYPEDEF_(0x800F0245L)
+#define SPAPI_E_UNRECOVERABLE_STACK_OVERFLOW _HRESULT_TYPEDEF_(0x800F0300L)
+#define SPAPI_E_ERROR_NOT_INSTALLED _HRESULT_TYPEDEF_(0x800F1000L)
+#define SCARD_S_SUCCESS NO_ERROR
+#define SCARD_F_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x80100001L)
+#define SCARD_E_CANCELLED _HRESULT_TYPEDEF_(0x80100002L)
+#define SCARD_E_INVALID_HANDLE _HRESULT_TYPEDEF_(0x80100003L)
+#define SCARD_E_INVALID_PARAMETER _HRESULT_TYPEDEF_(0x80100004L)
+#define SCARD_E_INVALID_TARGET _HRESULT_TYPEDEF_(0x80100005L)
+#define SCARD_E_NO_MEMORY _HRESULT_TYPEDEF_(0x80100006L)
+#define SCARD_F_WAITED_TOO_LONG _HRESULT_TYPEDEF_(0x80100007L)
+#define SCARD_E_INSUFFICIENT_BUFFER _HRESULT_TYPEDEF_(0x80100008L)
+#define SCARD_E_UNKNOWN_READER _HRESULT_TYPEDEF_(0x80100009L)
+#define SCARD_E_TIMEOUT _HRESULT_TYPEDEF_(0x8010000AL)
+#define SCARD_E_SHARING_VIOLATION _HRESULT_TYPEDEF_(0x8010000BL)
+#define SCARD_E_NO_SMARTCARD _HRESULT_TYPEDEF_(0x8010000CL)
+#define SCARD_E_UNKNOWN_CARD _HRESULT_TYPEDEF_(0x8010000DL)
+#define SCARD_E_CANT_DISPOSE _HRESULT_TYPEDEF_(0x8010000EL)
+#define SCARD_E_PROTO_MISMATCH _HRESULT_TYPEDEF_(0x8010000FL)
+#define SCARD_E_NOT_READY _HRESULT_TYPEDEF_(0x80100010L)
+#define SCARD_E_INVALID_VALUE _HRESULT_TYPEDEF_(0x80100011L)
+#define SCARD_E_SYSTEM_CANCELLED _HRESULT_TYPEDEF_(0x80100012L)
+#define SCARD_F_COMM_ERROR _HRESULT_TYPEDEF_(0x80100013L)
+#define SCARD_F_UNKNOWN_ERROR _HRESULT_TYPEDEF_(0x80100014L)
+#define SCARD_E_INVALID_ATR _HRESULT_TYPEDEF_(0x80100015L)
+#define SCARD_E_NOT_TRANSACTED _HRESULT_TYPEDEF_(0x80100016L)
+#define SCARD_E_READER_UNAVAILABLE _HRESULT_TYPEDEF_(0x80100017L)
+#define SCARD_P_SHUTDOWN _HRESULT_TYPEDEF_(0x80100018L)
+#define SCARD_E_PCI_TOO_SMALL _HRESULT_TYPEDEF_(0x80100019L)
+#define SCARD_E_READER_UNSUPPORTED _HRESULT_TYPEDEF_(0x8010001AL)
+#define SCARD_E_DUPLICATE_READER _HRESULT_TYPEDEF_(0x8010001BL)
+#define SCARD_E_CARD_UNSUPPORTED _HRESULT_TYPEDEF_(0x8010001CL)
+#define SCARD_E_NO_SERVICE _HRESULT_TYPEDEF_(0x8010001DL)
+#define SCARD_E_SERVICE_STOPPED _HRESULT_TYPEDEF_(0x8010001EL)
+#define SCARD_E_UNEXPECTED _HRESULT_TYPEDEF_(0x8010001FL)
+#define SCARD_E_ICC_INSTALLATION _HRESULT_TYPEDEF_(0x80100020L)
+#define SCARD_E_ICC_CREATEORDER _HRESULT_TYPEDEF_(0x80100021L)
+#define SCARD_E_UNSUPPORTED_FEATURE _HRESULT_TYPEDEF_(0x80100022L)
+#define SCARD_E_DIR_NOT_FOUND _HRESULT_TYPEDEF_(0x80100023L)
+#define SCARD_E_FILE_NOT_FOUND _HRESULT_TYPEDEF_(0x80100024L)
+#define SCARD_E_NO_DIR _HRESULT_TYPEDEF_(0x80100025L)
+#define SCARD_E_NO_FILE _HRESULT_TYPEDEF_(0x80100026L)
+#define SCARD_E_NO_ACCESS _HRESULT_TYPEDEF_(0x80100027L)
+#define SCARD_E_WRITE_TOO_MANY _HRESULT_TYPEDEF_(0x80100028L)
+#define SCARD_E_BAD_SEEK _HRESULT_TYPEDEF_(0x80100029L)
+#define SCARD_E_INVALID_CHV _HRESULT_TYPEDEF_(0x8010002AL)
+#define SCARD_E_UNKNOWN_RES_MNG _HRESULT_TYPEDEF_(0x8010002BL)
+#define SCARD_E_NO_SUCH_CERTIFICATE _HRESULT_TYPEDEF_(0x8010002CL)
+#define SCARD_E_CERTIFICATE_UNAVAILABLE _HRESULT_TYPEDEF_(0x8010002DL)
+#define SCARD_E_NO_READERS_AVAILABLE _HRESULT_TYPEDEF_(0x8010002EL)
+#define SCARD_E_COMM_DATA_LOST _HRESULT_TYPEDEF_(0x8010002FL)
+#define SCARD_E_NO_KEY_CONTAINER _HRESULT_TYPEDEF_(0x80100030L)
+#define SCARD_E_SERVER_TOO_BUSY _HRESULT_TYPEDEF_(0x80100031L)
+#define SCARD_W_UNSUPPORTED_CARD _HRESULT_TYPEDEF_(0x80100065L)
+#define SCARD_W_UNRESPONSIVE_CARD _HRESULT_TYPEDEF_(0x80100066L)
+#define SCARD_W_UNPOWERED_CARD _HRESULT_TYPEDEF_(0x80100067L)
+#define SCARD_W_RESET_CARD _HRESULT_TYPEDEF_(0x80100068L)
+#define SCARD_W_REMOVED_CARD _HRESULT_TYPEDEF_(0x80100069L)
+#define SCARD_W_SECURITY_VIOLATION _HRESULT_TYPEDEF_(0x8010006AL)
+#define SCARD_W_WRONG_CHV _HRESULT_TYPEDEF_(0x8010006BL)
+#define SCARD_W_CHV_BLOCKED _HRESULT_TYPEDEF_(0x8010006CL)
+#define SCARD_W_EOF _HRESULT_TYPEDEF_(0x8010006DL)
+#define SCARD_W_CANCELLED_BY_USER _HRESULT_TYPEDEF_(0x8010006EL)
+#define SCARD_W_CARD_NOT_AUTHENTICATED _HRESULT_TYPEDEF_(0x8010006FL)
+#define COMADMIN_E_OBJECTERRORS _HRESULT_TYPEDEF_(0x80110401L)
+#define COMADMIN_E_OBJECTINVALID _HRESULT_TYPEDEF_(0x80110402L)
+#define COMADMIN_E_KEYMISSING _HRESULT_TYPEDEF_(0x80110403L)
+#define COMADMIN_E_ALREADYINSTALLED _HRESULT_TYPEDEF_(0x80110404L)
+#define COMADMIN_E_APP_FILE_WRITEFAIL _HRESULT_TYPEDEF_(0x80110407L)
+#define COMADMIN_E_APP_FILE_READFAIL _HRESULT_TYPEDEF_(0x80110408L)
+#define COMADMIN_E_APP_FILE_VERSION _HRESULT_TYPEDEF_(0x80110409L)
+#define COMADMIN_E_BADPATH _HRESULT_TYPEDEF_(0x8011040AL)
+#define COMADMIN_E_APPLICATIONEXISTS _HRESULT_TYPEDEF_(0x8011040BL)
+#define COMADMIN_E_ROLEEXISTS _HRESULT_TYPEDEF_(0x8011040CL)
+#define COMADMIN_E_CANTCOPYFILE _HRESULT_TYPEDEF_(0x8011040DL)
+#define COMADMIN_E_NOUSER _HRESULT_TYPEDEF_(0x8011040FL)
+#define COMADMIN_E_INVALIDUSERIDS _HRESULT_TYPEDEF_(0x80110410L)
+#define COMADMIN_E_NOREGISTRYCLSID _HRESULT_TYPEDEF_(0x80110411L)
+#define COMADMIN_E_BADREGISTRYPROGID _HRESULT_TYPEDEF_(0x80110412L)
+#define COMADMIN_E_AUTHENTICATIONLEVEL _HRESULT_TYPEDEF_(0x80110413L)
+#define COMADMIN_E_USERPASSWDNOTVALID _HRESULT_TYPEDEF_(0x80110414L)
+#define COMADMIN_E_CLSIDORIIDMISMATCH _HRESULT_TYPEDEF_(0x80110418L)
+#define COMADMIN_E_REMOTEINTERFACE _HRESULT_TYPEDEF_(0x80110419L)
+#define COMADMIN_E_DLLREGISTERSERVER _HRESULT_TYPEDEF_(0x8011041AL)
+#define COMADMIN_E_NOSERVERSHARE _HRESULT_TYPEDEF_(0x8011041BL)
+#define COMADMIN_E_DLLLOADFAILED _HRESULT_TYPEDEF_(0x8011041DL)
+#define COMADMIN_E_BADREGISTRYLIBID _HRESULT_TYPEDEF_(0x8011041EL)
+#define COMADMIN_E_APPDIRNOTFOUND _HRESULT_TYPEDEF_(0x8011041FL)
+#define COMADMIN_E_REGISTRARFAILED _HRESULT_TYPEDEF_(0x80110423L)
+#define COMADMIN_E_COMPFILE_DOESNOTEXIST _HRESULT_TYPEDEF_(0x80110424L)
+#define COMADMIN_E_COMPFILE_LOADDLLFAIL _HRESULT_TYPEDEF_(0x80110425L)
+#define COMADMIN_E_COMPFILE_GETCLASSOBJ _HRESULT_TYPEDEF_(0x80110426L)
+#define COMADMIN_E_COMPFILE_CLASSNOTAVAIL _HRESULT_TYPEDEF_(0x80110427L)
+#define COMADMIN_E_COMPFILE_BADTLB _HRESULT_TYPEDEF_(0x80110428L)
+#define COMADMIN_E_COMPFILE_NOTINSTALLABLE _HRESULT_TYPEDEF_(0x80110429L)
+#define COMADMIN_E_NOTCHANGEABLE _HRESULT_TYPEDEF_(0x8011042AL)
+#define COMADMIN_E_NOTDELETEABLE _HRESULT_TYPEDEF_(0x8011042BL)
+#define COMADMIN_E_SESSION _HRESULT_TYPEDEF_(0x8011042CL)
+#define COMADMIN_E_COMP_MOVE_LOCKED _HRESULT_TYPEDEF_(0x8011042DL)
+#define COMADMIN_E_COMP_MOVE_BAD_DEST _HRESULT_TYPEDEF_(0x8011042EL)
+#define COMADMIN_E_REGISTERTLB _HRESULT_TYPEDEF_(0x80110430L)
+#define COMADMIN_E_SYSTEMAPP _HRESULT_TYPEDEF_(0x80110433L)
+#define COMADMIN_E_COMPFILE_NOREGISTRAR _HRESULT_TYPEDEF_(0x80110434L)
+#define COMADMIN_E_COREQCOMPINSTALLED _HRESULT_TYPEDEF_(0x80110435L)
+#define COMADMIN_E_SERVICENOTINSTALLED _HRESULT_TYPEDEF_(0x80110436L)
+#define COMADMIN_E_PROPERTYSAVEFAILED _HRESULT_TYPEDEF_(0x80110437L)
+#define COMADMIN_E_OBJECTEXISTS _HRESULT_TYPEDEF_(0x80110438L)
+#define COMADMIN_E_COMPONENTEXISTS _HRESULT_TYPEDEF_(0x80110439L)
+#define COMADMIN_E_REGFILE_CORRUPT _HRESULT_TYPEDEF_(0x8011043BL)
+#define COMADMIN_E_PROPERTY_OVERFLOW _HRESULT_TYPEDEF_(0x8011043CL)
+#define COMADMIN_E_NOTINREGISTRY _HRESULT_TYPEDEF_(0x8011043EL)
+#define COMADMIN_E_OBJECTNOTPOOLABLE _HRESULT_TYPEDEF_(0x8011043FL)
+#define COMADMIN_E_APPLID_MATCHES_CLSID _HRESULT_TYPEDEF_(0x80110446L)
+#define COMADMIN_E_ROLE_DOES_NOT_EXIST _HRESULT_TYPEDEF_(0x80110447L)
+#define COMADMIN_E_START_APP_NEEDS_COMPONENTS _HRESULT_TYPEDEF_(0x80110448L)
+#define COMADMIN_E_REQUIRES_DIFFERENT_PLATFORM _HRESULT_TYPEDEF_(0x80110449L)
+#define COMADMIN_E_CAN_NOT_EXPORT_APP_PROXY _HRESULT_TYPEDEF_(0x8011044AL)
+#define COMADMIN_E_CAN_NOT_START_APP _HRESULT_TYPEDEF_(0x8011044BL)
+#define COMADMIN_E_CAN_NOT_EXPORT_SYS_APP _HRESULT_TYPEDEF_(0x8011044CL)
+#define COMADMIN_E_CANT_SUBSCRIBE_TO_COMPONENT _HRESULT_TYPEDEF_(0x8011044DL)
+#define COMADMIN_E_EVENTCLASS_CANT_BE_SUBSCRIBER _HRESULT_TYPEDEF_(0x8011044EL)
+#define COMADMIN_E_LIB_APP_PROXY_INCOMPATIBLE _HRESULT_TYPEDEF_(0x8011044FL)
+#define COMADMIN_E_BASE_PARTITION_ONLY _HRESULT_TYPEDEF_(0x80110450L)
+#define COMADMIN_E_START_APP_DISABLED _HRESULT_TYPEDEF_(0x80110451L)
+#define COMADMIN_E_CAT_DUPLICATE_PARTITION_NAME _HRESULT_TYPEDEF_(0x80110457L)
+#define COMADMIN_E_CAT_INVALID_PARTITION_NAME _HRESULT_TYPEDEF_(0x80110458L)
+#define COMADMIN_E_CAT_PARTITION_IN_USE _HRESULT_TYPEDEF_(0x80110459L)
+#define COMADMIN_E_FILE_PARTITION_DUPLICATE_FILES _HRESULT_TYPEDEF_(0x8011045AL)
+#define COMADMIN_E_CAT_IMPORTED_COMPONENTS_NOT_ALLOWED _HRESULT_TYPEDEF_(0x8011045BL)
+#define COMADMIN_E_AMBIGUOUS_APPLICATION_NAME _HRESULT_TYPEDEF_(0x8011045CL)
+#define COMADMIN_E_AMBIGUOUS_PARTITION_NAME _HRESULT_TYPEDEF_(0x8011045DL)
+#define COMADMIN_E_REGDB_NOTINITIALIZED _HRESULT_TYPEDEF_(0x80110472L)
+#define COMADMIN_E_REGDB_NOTOPEN _HRESULT_TYPEDEF_(0x80110473L)
+#define COMADMIN_E_REGDB_SYSTEMERR _HRESULT_TYPEDEF_(0x80110474L)
+#define COMADMIN_E_REGDB_ALREADYRUNNING _HRESULT_TYPEDEF_(0x80110475L)
+#define COMADMIN_E_MIG_VERSIONNOTSUPPORTED _HRESULT_TYPEDEF_(0x80110480L)
+#define COMADMIN_E_MIG_SCHEMANOTFOUND _HRESULT_TYPEDEF_(0x80110481L)
+#define COMADMIN_E_CAT_BITNESSMISMATCH _HRESULT_TYPEDEF_(0x80110482L)
+#define COMADMIN_E_CAT_UNACCEPTABLEBITNESS _HRESULT_TYPEDEF_(0x80110483L)
+#define COMADMIN_E_CAT_WRONGAPPBITNESS _HRESULT_TYPEDEF_(0x80110484L)
+#define COMADMIN_E_CAT_PAUSE_RESUME_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80110485L)
+#define COMADMIN_E_CAT_SERVERFAULT _HRESULT_TYPEDEF_(0x80110486L)
+#define COMQC_E_APPLICATION_NOT_QUEUED _HRESULT_TYPEDEF_(0x80110600L)
+#define COMQC_E_NO_QUEUEABLE_INTERFACES _HRESULT_TYPEDEF_(0x80110601L)
+#define COMQC_E_QUEUING_SERVICE_NOT_AVAILABLE _HRESULT_TYPEDEF_(0x80110602L)
+#define COMQC_E_NO_IPERSISTSTREAM _HRESULT_TYPEDEF_(0x80110603L)
+#define COMQC_E_BAD_MESSAGE _HRESULT_TYPEDEF_(0x80110604L)
+#define COMQC_E_UNAUTHENTICATED _HRESULT_TYPEDEF_(0x80110605L)
+#define COMQC_E_UNTRUSTED_ENQUEUER _HRESULT_TYPEDEF_(0x80110606L)
+#define MSDTC_E_DUPLICATE_RESOURCE _HRESULT_TYPEDEF_(0x80110701L)
+#define COMADMIN_E_OBJECT_PARENT_MISSING _HRESULT_TYPEDEF_(0x80110808L)
+#define COMADMIN_E_OBJECT_DOES_NOT_EXIST _HRESULT_TYPEDEF_(0x80110809L)
+#define COMADMIN_E_APP_NOT_RUNNING _HRESULT_TYPEDEF_(0x8011080AL)
+#define COMADMIN_E_INVALID_PARTITION _HRESULT_TYPEDEF_(0x8011080BL)
+#define COMADMIN_E_SVCAPP_NOT_POOLABLE_OR_RECYCLABLE _HRESULT_TYPEDEF_(0x8011080DL)
+#define COMADMIN_E_USER_IN_SET _HRESULT_TYPEDEF_(0x8011080EL)
+#define COMADMIN_E_CANTRECYCLELIBRARYAPPS _HRESULT_TYPEDEF_(0x8011080FL)
+#define COMADMIN_E_CANTRECYCLESERVICEAPPS _HRESULT_TYPEDEF_(0x80110811L)
+#define COMADMIN_E_PROCESSALREADYRECYCLED _HRESULT_TYPEDEF_(0x80110812L)
+#define COMADMIN_E_PAUSEDPROCESSMAYNOTBERECYCLED _HRESULT_TYPEDEF_(0x80110813L)
+#define COMADMIN_E_CANTMAKEINPROCSERVICE _HRESULT_TYPEDEF_(0x80110814L)
+#define COMADMIN_E_PROGIDINUSEBYCLSID _HRESULT_TYPEDEF_(0x80110815L)
+#define COMADMIN_E_DEFAULT_PARTITION_NOT_IN_SET _HRESULT_TYPEDEF_(0x80110816L)
+#define COMADMIN_E_RECYCLEDPROCESSMAYNOTBEPAUSED _HRESULT_TYPEDEF_(0x80110817L)
+#define COMADMIN_E_PARTITION_ACCESSDENIED _HRESULT_TYPEDEF_(0x80110818L)
+#define COMADMIN_E_PARTITION_MSI_ONLY _HRESULT_TYPEDEF_(0x80110819L)
+#define COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_1_0_FORMAT _HRESULT_TYPEDEF_(0x8011081AL)
+#define COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_NONBASE_PARTITIONS _HRESULT_TYPEDEF_(0x8011081BL)
+#define COMADMIN_E_COMP_MOVE_SOURCE _HRESULT_TYPEDEF_(0x8011081CL)
+#define COMADMIN_E_COMP_MOVE_DEST _HRESULT_TYPEDEF_(0x8011081DL)
+#define COMADMIN_E_COMP_MOVE_PRIVATE _HRESULT_TYPEDEF_(0x8011081EL)
+#define COMADMIN_E_BASEPARTITION_REQUIRED_IN_SET _HRESULT_TYPEDEF_(0x8011081FL)
+#define COMADMIN_E_CANNOT_ALIAS_EVENTCLASS _HRESULT_TYPEDEF_(0x80110820L)
+#define COMADMIN_E_PRIVATE_ACCESSDENIED _HRESULT_TYPEDEF_(0x80110821L)
+#define COMADMIN_E_SAFERINVALID _HRESULT_TYPEDEF_(0x80110822L)
+#define COMADMIN_E_REGISTRY_ACCESSDENIED _HRESULT_TYPEDEF_(0x80110823L)
+#define COMADMIN_E_PARTITIONS_DISABLED _HRESULT_TYPEDEF_(0x80110824L)
+#endif /* _WINERROR_ */
diff --git a/win32/include/winapi/wingdi.h b/win32/include/winapi/wingdi.h
new file mode 100644
index 0000000..63d3891
--- /dev/null
+++ b/win32/include/winapi/wingdi.h
@@ -0,0 +1,4080 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _WINGDI_
+#define _WINGDI_
+
+#define WINGDIAPI DECLSPEC_IMPORT
+#define WINSPOOLAPI DECLSPEC_IMPORT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WINVER
+#define WINVER 0x0502
+#endif
+
+#ifndef NOGDI
+#ifndef NORASTEROPS
+#define R2_BLACK 1
+#define R2_NOTMERGEPEN 2
+#define R2_MASKNOTPEN 3
+#define R2_NOTCOPYPEN 4
+#define R2_MASKPENNOT 5
+#define R2_NOT 6
+#define R2_XORPEN 7
+#define R2_NOTMASKPEN 8
+#define R2_MASKPEN 9
+#define R2_NOTXORPEN 10
+#define R2_NOP 11
+#define R2_MERGENOTPEN 12
+#define R2_COPYPEN 13
+#define R2_MERGEPENNOT 14
+#define R2_MERGEPEN 15
+#define R2_WHITE 16
+#define R2_LAST 16
+
+#define SRCCOPY (DWORD)0x00CC0020
+#define SRCPAINT (DWORD)0x00EE0086
+#define SRCAND (DWORD)0x008800C6
+#define SRCINVERT (DWORD)0x00660046
+#define SRCERASE (DWORD)0x00440328
+#define NOTSRCCOPY (DWORD)0x00330008
+#define NOTSRCERASE (DWORD)0x001100A6
+#define MERGECOPY (DWORD)0x00C000CA
+#define MERGEPAINT (DWORD)0x00BB0226
+#define PATCOPY (DWORD)0x00F00021
+#define PATPAINT (DWORD)0x00FB0A09
+#define PATINVERT (DWORD)0x005A0049
+#define DSTINVERT (DWORD)0x00550009
+#define BLACKNESS (DWORD)0x00000042
+#define WHITENESS (DWORD)0x00FF0062
+#define NOMIRRORBITMAP (DWORD)0x80000000
+#define CAPTUREBLT (DWORD)0x40000000
+#define MAKEROP4(fore,back) (DWORD)((((back) << 8) & 0xFF000000) | (fore))
+#endif
+
+#define GDI_ERROR (0xFFFFFFFFL)
+#define HGDI_ERROR (LongToHandle(0xFFFFFFFFL))
+
+#define ERROR 0
+#define NULLREGION 1
+#define SIMPLEREGION 2
+#define COMPLEXREGION 3
+#define RGN_ERROR ERROR
+
+#define RGN_AND 1
+#define RGN_OR 2
+#define RGN_XOR 3
+#define RGN_DIFF 4
+#define RGN_COPY 5
+#define RGN_MIN RGN_AND
+#define RGN_MAX RGN_COPY
+
+#define BLACKONWHITE 1
+#define WHITEONBLACK 2
+#define COLORONCOLOR 3
+#define HALFTONE 4
+#define MAXSTRETCHBLTMODE 4
+
+#define STRETCH_ANDSCANS BLACKONWHITE
+#define STRETCH_ORSCANS WHITEONBLACK
+#define STRETCH_DELETESCANS COLORONCOLOR
+#define STRETCH_HALFTONE HALFTONE
+
+#define ALTERNATE 1
+#define WINDING 2
+#define POLYFILL_LAST 2
+
+#define LAYOUT_RTL 0x00000001
+#define LAYOUT_BTT 0x00000002
+#define LAYOUT_VBH 0x00000004
+#define LAYOUT_ORIENTATIONMASK (LAYOUT_RTL | LAYOUT_BTT | LAYOUT_VBH)
+#define LAYOUT_BITMAPORIENTATIONPRESERVED 0x00000008
+
+#define TA_NOUPDATECP 0
+#define TA_UPDATECP 1
+
+#define TA_LEFT 0
+#define TA_RIGHT 2
+#define TA_CENTER 6
+
+#define TA_TOP 0
+#define TA_BOTTOM 8
+#define TA_BASELINE 24
+#define TA_RTLREADING 256
+#define TA_MASK (TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING)
+
+#define VTA_BASELINE TA_BASELINE
+#define VTA_LEFT TA_BOTTOM
+#define VTA_RIGHT TA_TOP
+#define VTA_CENTER TA_CENTER
+#define VTA_BOTTOM TA_RIGHT
+#define VTA_TOP TA_LEFT
+
+#define ETO_OPAQUE 0x0002
+#define ETO_CLIPPED 0x0004
+#define ETO_GLYPH_INDEX 0x0010
+#define ETO_RTLREADING 0x0080
+#define ETO_NUMERICSLOCAL 0x0400
+#define ETO_NUMERICSLATIN 0x0800
+#define ETO_IGNORELANGUAGE 0x1000
+#define ETO_PDY 0x2000
+
+#define ASPECT_FILTERING 0x0001
+
+#define DCB_RESET 0x0001
+#define DCB_ACCUMULATE 0x0002
+#define DCB_DIRTY DCB_ACCUMULATE
+#define DCB_SET (DCB_RESET | DCB_ACCUMULATE)
+#define DCB_ENABLE 0x0004
+#define DCB_DISABLE 0x0008
+
+#ifndef NOMETAFILE
+
+#define META_SETBKCOLOR 0x0201
+#define META_SETBKMODE 0x0102
+#define META_SETMAPMODE 0x0103
+#define META_SETROP2 0x0104
+#define META_SETRELABS 0x0105
+#define META_SETPOLYFILLMODE 0x0106
+#define META_SETSTRETCHBLTMODE 0x0107
+#define META_SETTEXTCHAREXTRA 0x0108
+#define META_SETTEXTCOLOR 0x0209
+#define META_SETTEXTJUSTIFICATION 0x020A
+#define META_SETWINDOWORG 0x020B
+#define META_SETWINDOWEXT 0x020C
+#define META_SETVIEWPORTORG 0x020D
+#define META_SETVIEWPORTEXT 0x020E
+#define META_OFFSETWINDOWORG 0x020F
+#define META_SCALEWINDOWEXT 0x0410
+#define META_OFFSETVIEWPORTORG 0x0211
+#define META_SCALEVIEWPORTEXT 0x0412
+#define META_LINETO 0x0213
+#define META_MOVETO 0x0214
+#define META_EXCLUDECLIPRECT 0x0415
+#define META_INTERSECTCLIPRECT 0x0416
+#define META_ARC 0x0817
+#define META_ELLIPSE 0x0418
+#define META_FLOODFILL 0x0419
+#define META_PIE 0x081A
+#define META_RECTANGLE 0x041B
+#define META_ROUNDRECT 0x061C
+#define META_PATBLT 0x061D
+#define META_SAVEDC 0x001E
+#define META_SETPIXEL 0x041F
+#define META_OFFSETCLIPRGN 0x0220
+#define META_TEXTOUT 0x0521
+#define META_BITBLT 0x0922
+#define META_STRETCHBLT 0x0B23
+#define META_POLYGON 0x0324
+#define META_POLYLINE 0x0325
+#define META_ESCAPE 0x0626
+#define META_RESTOREDC 0x0127
+#define META_FILLREGION 0x0228
+#define META_FRAMEREGION 0x0429
+#define META_INVERTREGION 0x012A
+#define META_PAINTREGION 0x012B
+#define META_SELECTCLIPREGION 0x012C
+#define META_SELECTOBJECT 0x012D
+#define META_SETTEXTALIGN 0x012E
+#define META_CHORD 0x0830
+#define META_SETMAPPERFLAGS 0x0231
+#define META_EXTTEXTOUT 0x0a32
+#define META_SETDIBTODEV 0x0d33
+#define META_SELECTPALETTE 0x0234
+#define META_REALIZEPALETTE 0x0035
+#define META_ANIMATEPALETTE 0x0436
+#define META_SETPALENTRIES 0x0037
+#define META_POLYPOLYGON 0x0538
+#define META_RESIZEPALETTE 0x0139
+#define META_DIBBITBLT 0x0940
+#define META_DIBSTRETCHBLT 0x0b41
+#define META_DIBCREATEPATTERNBRUSH 0x0142
+#define META_STRETCHDIB 0x0f43
+#define META_EXTFLOODFILL 0x0548
+#define META_SETLAYOUT 0x0149
+#define META_DELETEOBJECT 0x01f0
+#define META_CREATEPALETTE 0x00f7
+#define META_CREATEPATTERNBRUSH 0x01F9
+#define META_CREATEPENINDIRECT 0x02FA
+#define META_CREATEFONTINDIRECT 0x02FB
+#define META_CREATEBRUSHINDIRECT 0x02FC
+#define META_CREATEREGION 0x06FF
+
+ typedef struct _DRAWPATRECT {
+ POINT ptPosition;
+ POINT ptSize;
+ WORD wStyle;
+ WORD wPattern;
+ } DRAWPATRECT,*PDRAWPATRECT;
+#endif
+
+#define NEWFRAME 1
+#define ABORTDOC 2
+#define NEXTBAND 3
+#define SETCOLORTABLE 4
+#define GETCOLORTABLE 5
+#define FLUSHOUTPUT 6
+#define DRAFTMODE 7
+#define QUERYESCSUPPORT 8
+#define SETABORTPROC 9
+#define STARTDOC 10
+#define ENDDOC 11
+#define GETPHYSPAGESIZE 12
+#define GETPRINTINGOFFSET 13
+#define GETSCALINGFACTOR 14
+#define MFCOMMENT 15
+#define GETPENWIDTH 16
+#define SETCOPYCOUNT 17
+#define SELECTPAPERSOURCE 18
+#define DEVICEDATA 19
+#define PASSTHROUGH 19
+#define GETTECHNOLGY 20
+#define GETTECHNOLOGY 20
+#define SETLINECAP 21
+#define SETLINEJOIN 22
+#define SETMITERLIMIT 23
+#define BANDINFO 24
+#define DRAWPATTERNRECT 25
+#define GETVECTORPENSIZE 26
+#define GETVECTORBRUSHSIZE 27
+#define ENABLEDUPLEX 28
+#define GETSETPAPERBINS 29
+#define GETSETPRINTORIENT 30
+#define ENUMPAPERBINS 31
+#define SETDIBSCALING 32
+#define EPSPRINTING 33
+#define ENUMPAPERMETRICS 34
+#define GETSETPAPERMETRICS 35
+#define POSTSCRIPT_DATA 37
+#define POSTSCRIPT_IGNORE 38
+#define MOUSETRAILS 39
+#define GETDEVICEUNITS 42
+
+#define GETEXTENDEDTEXTMETRICS 256
+#define GETEXTENTTABLE 257
+#define GETPAIRKERNTABLE 258
+#define GETTRACKKERNTABLE 259
+#define EXTTEXTOUT 512
+#define GETFACENAME 513
+#define DOWNLOADFACE 514
+#define ENABLERELATIVEWIDTHS 768
+#define ENABLEPAIRKERNING 769
+#define SETKERNTRACK 770
+#define SETALLJUSTVALUES 771
+#define SETCHARSET 772
+
+#define STRETCHBLT 2048
+#define METAFILE_DRIVER 2049
+#define GETSETSCREENPARAMS 3072
+#define QUERYDIBSUPPORT 3073
+#define BEGIN_PATH 4096
+#define CLIP_TO_PATH 4097
+#define END_PATH 4098
+#define EXT_DEVICE_CAPS 4099
+#define RESTORE_CTM 4100
+#define SAVE_CTM 4101
+#define SET_ARC_DIRECTION 4102
+#define SET_BACKGROUND_COLOR 4103
+#define SET_POLY_MODE 4104
+#define SET_SCREEN_ANGLE 4105
+#define SET_SPREAD 4106
+#define TRANSFORM_CTM 4107
+#define SET_CLIP_BOX 4108
+#define SET_BOUNDS 4109
+#define SET_MIRROR_MODE 4110
+#define OPENCHANNEL 4110
+#define DOWNLOADHEADER 4111
+#define CLOSECHANNEL 4112
+#define POSTSCRIPT_PASSTHROUGH 4115
+#define ENCAPSULATED_POSTSCRIPT 4116
+
+#define POSTSCRIPT_IDENTIFY 4117
+#define POSTSCRIPT_INJECTION 4118
+
+#define CHECKJPEGFORMAT 4119
+#define CHECKPNGFORMAT 4120
+
+#define GET_PS_FEATURESETTING 4121
+
+#define SPCLPASSTHROUGH2 4568
+
+#define PSIDENT_GDICENTRIC 0
+#define PSIDENT_PSCENTRIC 1
+
+ typedef struct _PSINJECTDATA {
+ DWORD DataBytes;
+ WORD InjectionPoint;
+ WORD PageNumber;
+ } PSINJECTDATA,*PPSINJECTDATA;
+
+#define PSINJECT_BEGINSTREAM 1
+#define PSINJECT_PSADOBE 2
+#define PSINJECT_PAGESATEND 3
+#define PSINJECT_PAGES 4
+
+#define PSINJECT_DOCNEEDEDRES 5
+#define PSINJECT_DOCSUPPLIEDRES 6
+#define PSINJECT_PAGEORDER 7
+#define PSINJECT_ORIENTATION 8
+#define PSINJECT_BOUNDINGBOX 9
+#define PSINJECT_DOCUMENTPROCESSCOLORS 10
+
+#define PSINJECT_COMMENTS 11
+#define PSINJECT_BEGINDEFAULTS 12
+#define PSINJECT_ENDDEFAULTS 13
+#define PSINJECT_BEGINPROLOG 14
+#define PSINJECT_ENDPROLOG 15
+#define PSINJECT_BEGINSETUP 16
+#define PSINJECT_ENDSETUP 17
+#define PSINJECT_TRAILER 18
+#define PSINJECT_EOF 19
+#define PSINJECT_ENDSTREAM 20
+#define PSINJECT_DOCUMENTPROCESSCOLORSATEND 21
+
+#define PSINJECT_PAGENUMBER 100
+#define PSINJECT_BEGINPAGESETUP 101
+#define PSINJECT_ENDPAGESETUP 102
+#define PSINJECT_PAGETRAILER 103
+#define PSINJECT_PLATECOLOR 104
+
+#define PSINJECT_SHOWPAGE 105
+#define PSINJECT_PAGEBBOX 106
+#define PSINJECT_ENDPAGECOMMENTS 107
+
+#define PSINJECT_VMSAVE 200
+#define PSINJECT_VMRESTORE 201
+
+#define FEATURESETTING_NUP 0
+#define FEATURESETTING_OUTPUT 1
+#define FEATURESETTING_PSLEVEL 2
+#define FEATURESETTING_CUSTPAPER 3
+#define FEATURESETTING_MIRROR 4
+#define FEATURESETTING_NEGATIVE 5
+#define FEATURESETTING_PROTOCOL 6
+
+#define FEATURESETTING_PRIVATE_BEGIN 0x1000
+#define FEATURESETTING_PRIVATE_END 0x1FFF
+
+ typedef struct _PSFEATURE_OUTPUT {
+ WINBOOL bPageIndependent;
+ WINBOOL bSetPageDevice;
+ } PSFEATURE_OUTPUT,*PPSFEATURE_OUTPUT;
+
+ typedef struct _PSFEATURE_CUSTPAPER {
+ LONG lOrientation;
+ LONG lWidth;
+ LONG lHeight;
+ LONG lWidthOffset;
+ LONG lHeightOffset;
+ } PSFEATURE_CUSTPAPER,*PPSFEATURE_CUSTPAPER;
+
+#define PSPROTOCOL_ASCII 0
+#define PSPROTOCOL_BCP 1
+#define PSPROTOCOL_TBCP 2
+#define PSPROTOCOL_BINARY 3
+
+#define QDI_SETDIBITS 1
+#define QDI_GETDIBITS 2
+#define QDI_DIBTOSCREEN 4
+#define QDI_STRETCHDIB 8
+
+#define SP_NOTREPORTED 0x4000
+#define SP_ERROR (-1)
+#define SP_APPABORT (-2)
+#define SP_USERABORT (-3)
+#define SP_OUTOFDISK (-4)
+#define SP_OUTOFMEMORY (-5)
+
+#define PR_JOBSTATUS 0x0000
+
+#define OBJ_PEN 1
+#define OBJ_BRUSH 2
+#define OBJ_DC 3
+#define OBJ_METADC 4
+#define OBJ_PAL 5
+#define OBJ_FONT 6
+#define OBJ_BITMAP 7
+#define OBJ_REGION 8
+#define OBJ_METAFILE 9
+#define OBJ_MEMDC 10
+#define OBJ_EXTPEN 11
+#define OBJ_ENHMETADC 12
+#define OBJ_ENHMETAFILE 13
+#define OBJ_COLORSPACE 14
+
+#define MWT_IDENTITY 1
+#define MWT_LEFTMULTIPLY 2
+#define MWT_RIGHTMULTIPLY 3
+
+#define MWT_MIN MWT_IDENTITY
+#define MWT_MAX MWT_RIGHTMULTIPLY
+
+#define _XFORM_
+ typedef struct tagXFORM {
+ FLOAT eM11;
+ FLOAT eM12;
+ FLOAT eM21;
+ FLOAT eM22;
+ FLOAT eDx;
+ FLOAT eDy;
+ } XFORM,*PXFORM,*LPXFORM;
+
+ typedef struct tagBITMAP {
+ LONG bmType;
+ LONG bmWidth;
+ LONG bmHeight;
+ LONG bmWidthBytes;
+ WORD bmPlanes;
+ WORD bmBitsPixel;
+ LPVOID bmBits;
+ } BITMAP,*PBITMAP,*NPBITMAP,*LPBITMAP;
+
+#include <pshpack1.h>
+ typedef struct tagRGBTRIPLE {
+ BYTE rgbtBlue;
+ BYTE rgbtGreen;
+ BYTE rgbtRed;
+ } RGBTRIPLE;
+#include <poppack.h>
+
+ typedef struct tagRGBQUAD {
+ BYTE rgbBlue;
+ BYTE rgbGreen;
+ BYTE rgbRed;
+ BYTE rgbReserved;
+ } RGBQUAD;
+ typedef RGBQUAD *LPRGBQUAD;
+
+#define CS_ENABLE 0x00000001L
+#define CS_DISABLE 0x00000002L
+#define CS_DELETE_TRANSFORM 0x00000003L
+
+//!__TINYC__: #define LCS_SIGNATURE 'PSOC'
+//!__TINYC__: #define LCS_sRGB 'sRGB'
+//!__TINYC__: #define LCS_WINDOWS_COLOR_SPACE 'Win '
+
+ typedef LONG LCSCSTYPE;
+#define LCS_CALIBRATED_RGB 0x00000000L
+
+ typedef LONG LCSGAMUTMATCH;
+#define LCS_GM_BUSINESS 0x00000001L
+#define LCS_GM_GRAPHICS 0x00000002L
+#define LCS_GM_IMAGES 0x00000004L
+#define LCS_GM_ABS_COLORIMETRIC 0x00000008L
+
+#define CM_OUT_OF_GAMUT 255
+#define CM_IN_GAMUT 0
+
+#define ICM_ADDPROFILE 1
+#define ICM_DELETEPROFILE 2
+#define ICM_QUERYPROFILE 3
+#define ICM_SETDEFAULTPROFILE 4
+#define ICM_REGISTERICMATCHER 5
+#define ICM_UNREGISTERICMATCHER 6
+#define ICM_QUERYMATCH 7
+
+#define GetKValue(cmyk) ((BYTE)(cmyk))
+#define GetYValue(cmyk) ((BYTE)((cmyk)>> 8))
+#define GetMValue(cmyk) ((BYTE)((cmyk)>>16))
+#define GetCValue(cmyk) ((BYTE)((cmyk)>>24))
+
+#define CMYK(c,m,y,k) ((COLORREF)((((BYTE)(k)|((WORD)((BYTE)(y))<<8))|(((DWORD)(BYTE)(m))<<16))|(((DWORD)(BYTE)(c))<<24)))
+
+ typedef long FXPT16DOT16,*LPFXPT16DOT16;
+ typedef long FXPT2DOT30,*LPFXPT2DOT30;
+
+ typedef struct tagCIEXYZ {
+ FXPT2DOT30 ciexyzX;
+ FXPT2DOT30 ciexyzY;
+ FXPT2DOT30 ciexyzZ;
+ } CIEXYZ;
+ typedef CIEXYZ *LPCIEXYZ;
+
+ typedef struct tagICEXYZTRIPLE {
+ CIEXYZ ciexyzRed;
+ CIEXYZ ciexyzGreen;
+ CIEXYZ ciexyzBlue;
+ } CIEXYZTRIPLE;
+
+ typedef CIEXYZTRIPLE *LPCIEXYZTRIPLE;
+
+ typedef struct tagLOGCOLORSPACEA {
+ DWORD lcsSignature;
+ DWORD lcsVersion;
+ DWORD lcsSize;
+ LCSCSTYPE lcsCSType;
+ LCSGAMUTMATCH lcsIntent;
+ CIEXYZTRIPLE lcsEndpoints;
+ DWORD lcsGammaRed;
+ DWORD lcsGammaGreen;
+ DWORD lcsGammaBlue;
+ CHAR lcsFilename[MAX_PATH];
+ } LOGCOLORSPACEA,*LPLOGCOLORSPACEA;
+
+ typedef struct tagLOGCOLORSPACEW {
+ DWORD lcsSignature;
+ DWORD lcsVersion;
+ DWORD lcsSize;
+ LCSCSTYPE lcsCSType;
+ LCSGAMUTMATCH lcsIntent;
+ CIEXYZTRIPLE lcsEndpoints;
+ DWORD lcsGammaRed;
+ DWORD lcsGammaGreen;
+ DWORD lcsGammaBlue;
+ WCHAR lcsFilename[MAX_PATH];
+ } LOGCOLORSPACEW,*LPLOGCOLORSPACEW;
+
+#ifdef UNICODE
+ typedef LOGCOLORSPACEW LOGCOLORSPACE;
+ typedef LPLOGCOLORSPACEW LPLOGCOLORSPACE;
+#else
+ typedef LOGCOLORSPACEA LOGCOLORSPACE;
+ typedef LPLOGCOLORSPACEA LPLOGCOLORSPACE;
+#endif
+
+ typedef struct tagBITMAPCOREHEADER {
+ DWORD bcSize;
+ WORD bcWidth;
+ WORD bcHeight;
+ WORD bcPlanes;
+ WORD bcBitCount;
+ } BITMAPCOREHEADER,*LPBITMAPCOREHEADER,*PBITMAPCOREHEADER;
+
+ typedef struct tagBITMAPINFOHEADER {
+ DWORD biSize;
+ LONG biWidth;
+ LONG biHeight;
+ WORD biPlanes;
+ WORD biBitCount;
+ DWORD biCompression;
+ DWORD biSizeImage;
+ LONG biXPelsPerMeter;
+ LONG biYPelsPerMeter;
+ DWORD biClrUsed;
+ DWORD biClrImportant;
+ } BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;
+
+ typedef struct {
+ DWORD bV4Size;
+ LONG bV4Width;
+ LONG bV4Height;
+ WORD bV4Planes;
+ WORD bV4BitCount;
+ DWORD bV4V4Compression;
+ DWORD bV4SizeImage;
+ LONG bV4XPelsPerMeter;
+ LONG bV4YPelsPerMeter;
+ DWORD bV4ClrUsed;
+ DWORD bV4ClrImportant;
+ DWORD bV4RedMask;
+ DWORD bV4GreenMask;
+ DWORD bV4BlueMask;
+ DWORD bV4AlphaMask;
+ DWORD bV4CSType;
+ CIEXYZTRIPLE bV4Endpoints;
+ DWORD bV4GammaRed;
+ DWORD bV4GammaGreen;
+ DWORD bV4GammaBlue;
+ } BITMAPV4HEADER,*LPBITMAPV4HEADER,*PBITMAPV4HEADER;
+
+ typedef struct {
+ DWORD bV5Size;
+ LONG bV5Width;
+ LONG bV5Height;
+ WORD bV5Planes;
+ WORD bV5BitCount;
+ DWORD bV5Compression;
+ DWORD bV5SizeImage;
+ LONG bV5XPelsPerMeter;
+ LONG bV5YPelsPerMeter;
+ DWORD bV5ClrUsed;
+ DWORD bV5ClrImportant;
+ DWORD bV5RedMask;
+ DWORD bV5GreenMask;
+ DWORD bV5BlueMask;
+ DWORD bV5AlphaMask;
+ DWORD bV5CSType;
+ CIEXYZTRIPLE bV5Endpoints;
+ DWORD bV5GammaRed;
+ DWORD bV5GammaGreen;
+ DWORD bV5GammaBlue;
+ DWORD bV5Intent;
+ DWORD bV5ProfileData;
+ DWORD bV5ProfileSize;
+ DWORD bV5Reserved;
+ } BITMAPV5HEADER,*LPBITMAPV5HEADER,*PBITMAPV5HEADER;
+
+//!__TINYC__: #define PROFILE_LINKED 'LINK'
+//!__TINYC__: #define PROFILE_EMBEDDED 'MBED'
+
+#define BI_RGB 0L
+#define BI_RLE8 1L
+#define BI_RLE4 2L
+#define BI_BITFIELDS 3L
+#define BI_JPEG 4L
+#define BI_PNG 5L
+
+ typedef struct tagBITMAPINFO {
+ BITMAPINFOHEADER bmiHeader;
+ RGBQUAD bmiColors[1];
+ } BITMAPINFO,*LPBITMAPINFO,*PBITMAPINFO;
+
+ typedef struct tagBITMAPCOREINFO {
+ BITMAPCOREHEADER bmciHeader;
+ RGBTRIPLE bmciColors[1];
+ } BITMAPCOREINFO,*LPBITMAPCOREINFO,*PBITMAPCOREINFO;
+
+#include <pshpack2.h>
+ typedef struct tagBITMAPFILEHEADER {
+ WORD bfType;
+ DWORD bfSize;
+ WORD bfReserved1;
+ WORD bfReserved2;
+ DWORD bfOffBits;
+ } BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
+#include <poppack.h>
+
+#define MAKEPOINTS(l) (*((POINTS *)&(l)))
+
+#ifndef NOFONTSIG
+ typedef struct tagFONTSIGNATURE {
+ DWORD fsUsb[4];
+ DWORD fsCsb[2];
+ } FONTSIGNATURE,*PFONTSIGNATURE,*LPFONTSIGNATURE;
+
+ typedef struct tagCHARSETINFO {
+ UINT ciCharset;
+ UINT ciACP;
+ FONTSIGNATURE fs;
+ } CHARSETINFO,*PCHARSETINFO,*NPCHARSETINFO,*LPCHARSETINFO;
+
+#define TCI_SRCCHARSET 1
+#define TCI_SRCCODEPAGE 2
+#define TCI_SRCFONTSIG 3
+#define TCI_SRCLOCALE 0x1000
+
+ typedef struct tagLOCALESIGNATURE {
+ DWORD lsUsb[4];
+ DWORD lsCsbDefault[2];
+ DWORD lsCsbSupported[2];
+ } LOCALESIGNATURE,*PLOCALESIGNATURE,*LPLOCALESIGNATURE;
+#endif
+
+
+#ifndef NOMETAFILE
+ typedef struct tagHANDLETABLE {
+ HGDIOBJ objectHandle[1];
+ } HANDLETABLE,*PHANDLETABLE,*LPHANDLETABLE;
+
+ typedef struct tagMETARECORD {
+ DWORD rdSize;
+ WORD rdFunction;
+ WORD rdParm[1];
+ } METARECORD;
+ typedef struct tagMETARECORD UNALIGNED *PMETARECORD;
+ typedef struct tagMETARECORD UNALIGNED *LPMETARECORD;
+
+ typedef struct tagMETAFILEPICT {
+ LONG mm;
+ LONG xExt;
+ LONG yExt;
+ HMETAFILE hMF;
+ } METAFILEPICT,*LPMETAFILEPICT;
+
+#include <pshpack2.h>
+ typedef struct tagMETAHEADER {
+ WORD mtType;
+ WORD mtHeaderSize;
+ WORD mtVersion;
+ DWORD mtSize;
+ WORD mtNoObjects;
+ DWORD mtMaxRecord;
+ WORD mtNoParameters;
+ } METAHEADER;
+ typedef struct tagMETAHEADER UNALIGNED *PMETAHEADER;
+ typedef struct tagMETAHEADER UNALIGNED *LPMETAHEADER;
+
+#include <poppack.h>
+
+ typedef struct tagENHMETARECORD {
+ DWORD iType;
+ DWORD nSize;
+ DWORD dParm[1];
+ } ENHMETARECORD,*PENHMETARECORD,*LPENHMETARECORD;
+
+ typedef struct tagENHMETAHEADER {
+ DWORD iType;
+ DWORD nSize;
+ RECTL rclBounds;
+ RECTL rclFrame;
+ DWORD dSignature;
+ DWORD nVersion;
+ DWORD nBytes;
+ DWORD nRecords;
+ WORD nHandles;
+ WORD sReserved;
+ DWORD nDescription;
+ DWORD offDescription;
+ DWORD nPalEntries;
+ SIZEL szlDevice;
+ SIZEL szlMillimeters;
+ DWORD cbPixelFormat;
+ DWORD offPixelFormat;
+ DWORD bOpenGL;
+ SIZEL szlMicrometers;
+ } ENHMETAHEADER,*PENHMETAHEADER,*LPENHMETAHEADER;
+#endif
+
+#ifndef NOTEXTMETRIC
+#define TMPF_FIXED_PITCH 0x01
+#define TMPF_VECTOR 0x02
+#define TMPF_DEVICE 0x08
+#define TMPF_TRUETYPE 0x04
+
+#ifdef UNICODE
+ typedef WCHAR BCHAR;
+#else
+ typedef BYTE BCHAR;
+#endif
+
+#ifndef _TEXTMETRIC_DEFINED
+#define _TEXTMETRIC_DEFINED
+ typedef struct tagTEXTMETRICA {
+ LONG tmHeight;
+ LONG tmAscent;
+ LONG tmDescent;
+ LONG tmInternalLeading;
+ LONG tmExternalLeading;
+ LONG tmAveCharWidth;
+ LONG tmMaxCharWidth;
+ LONG tmWeight;
+ LONG tmOverhang;
+ LONG tmDigitizedAspectX;
+ LONG tmDigitizedAspectY;
+ BYTE tmFirstChar;
+ BYTE tmLastChar;
+ BYTE tmDefaultChar;
+ BYTE tmBreakChar;
+ BYTE tmItalic;
+ BYTE tmUnderlined;
+ BYTE tmStruckOut;
+ BYTE tmPitchAndFamily;
+ BYTE tmCharSet;
+ } TEXTMETRICA,*PTEXTMETRICA,*NPTEXTMETRICA,*LPTEXTMETRICA;
+
+ typedef struct tagTEXTMETRICW {
+ LONG tmHeight;
+ LONG tmAscent;
+ LONG tmDescent;
+ LONG tmInternalLeading;
+ LONG tmExternalLeading;
+ LONG tmAveCharWidth;
+ LONG tmMaxCharWidth;
+ LONG tmWeight;
+ LONG tmOverhang;
+ LONG tmDigitizedAspectX;
+ LONG tmDigitizedAspectY;
+ WCHAR tmFirstChar;
+ WCHAR tmLastChar;
+ WCHAR tmDefaultChar;
+ WCHAR tmBreakChar;
+ BYTE tmItalic;
+ BYTE tmUnderlined;
+ BYTE tmStruckOut;
+ BYTE tmPitchAndFamily;
+ BYTE tmCharSet;
+ } TEXTMETRICW,*PTEXTMETRICW,*NPTEXTMETRICW,*LPTEXTMETRICW;
+#ifdef UNICODE
+ typedef TEXTMETRICW TEXTMETRIC;
+ typedef PTEXTMETRICW PTEXTMETRIC;
+ typedef NPTEXTMETRICW NPTEXTMETRIC;
+ typedef LPTEXTMETRICW LPTEXTMETRIC;
+#else
+ typedef TEXTMETRICA TEXTMETRIC;
+ typedef PTEXTMETRICA PTEXTMETRIC;
+ typedef NPTEXTMETRICA NPTEXTMETRIC;
+ typedef LPTEXTMETRICA LPTEXTMETRIC;
+#endif
+#endif
+
+#define NTM_REGULAR 0x00000040L
+#define NTM_BOLD 0x00000020L
+#define NTM_ITALIC 0x00000001L
+
+#define NTM_NONNEGATIVE_AC 0x00010000
+#define NTM_PS_OPENTYPE 0x00020000
+#define NTM_TT_OPENTYPE 0x00040000
+#define NTM_MULTIPLEMASTER 0x00080000
+#define NTM_TYPE1 0x00100000
+#define NTM_DSIG 0x00200000
+
+#include <pshpack4.h>
+ typedef struct tagNEWTEXTMETRICA {
+ LONG tmHeight;
+ LONG tmAscent;
+ LONG tmDescent;
+ LONG tmInternalLeading;
+ LONG tmExternalLeading;
+ LONG tmAveCharWidth;
+ LONG tmMaxCharWidth;
+ LONG tmWeight;
+ LONG tmOverhang;
+ LONG tmDigitizedAspectX;
+ LONG tmDigitizedAspectY;
+ BYTE tmFirstChar;
+ BYTE tmLastChar;
+ BYTE tmDefaultChar;
+ BYTE tmBreakChar;
+ BYTE tmItalic;
+ BYTE tmUnderlined;
+ BYTE tmStruckOut;
+ BYTE tmPitchAndFamily;
+ BYTE tmCharSet;
+ DWORD ntmFlags;
+ UINT ntmSizeEM;
+ UINT ntmCellHeight;
+ UINT ntmAvgWidth;
+ } NEWTEXTMETRICA,*PNEWTEXTMETRICA,*NPNEWTEXTMETRICA,*LPNEWTEXTMETRICA;
+
+ typedef struct tagNEWTEXTMETRICW {
+ LONG tmHeight;
+ LONG tmAscent;
+ LONG tmDescent;
+ LONG tmInternalLeading;
+ LONG tmExternalLeading;
+ LONG tmAveCharWidth;
+ LONG tmMaxCharWidth;
+ LONG tmWeight;
+ LONG tmOverhang;
+ LONG tmDigitizedAspectX;
+ LONG tmDigitizedAspectY;
+ WCHAR tmFirstChar;
+ WCHAR tmLastChar;
+ WCHAR tmDefaultChar;
+ WCHAR tmBreakChar;
+ BYTE tmItalic;
+ BYTE tmUnderlined;
+ BYTE tmStruckOut;
+ BYTE tmPitchAndFamily;
+ BYTE tmCharSet;
+ DWORD ntmFlags;
+ UINT ntmSizeEM;
+ UINT ntmCellHeight;
+ UINT ntmAvgWidth;
+ } NEWTEXTMETRICW,*PNEWTEXTMETRICW,*NPNEWTEXTMETRICW,*LPNEWTEXTMETRICW;
+#ifdef UNICODE
+ typedef NEWTEXTMETRICW NEWTEXTMETRIC;
+ typedef PNEWTEXTMETRICW PNEWTEXTMETRIC;
+ typedef NPNEWTEXTMETRICW NPNEWTEXTMETRIC;
+ typedef LPNEWTEXTMETRICW LPNEWTEXTMETRIC;
+#else
+ typedef NEWTEXTMETRICA NEWTEXTMETRIC;
+ typedef PNEWTEXTMETRICA PNEWTEXTMETRIC;
+ typedef NPNEWTEXTMETRICA NPNEWTEXTMETRIC;
+ typedef LPNEWTEXTMETRICA LPNEWTEXTMETRIC;
+#endif
+#include <poppack.h>
+
+ typedef struct tagNEWTEXTMETRICEXA {
+ NEWTEXTMETRICA ntmTm;
+ FONTSIGNATURE ntmFontSig;
+ } NEWTEXTMETRICEXA;
+
+ typedef struct tagNEWTEXTMETRICEXW {
+ NEWTEXTMETRICW ntmTm;
+ FONTSIGNATURE ntmFontSig;
+ } NEWTEXTMETRICEXW;
+#ifdef UNICODE
+ typedef NEWTEXTMETRICEXW NEWTEXTMETRICEX;
+#else
+ typedef NEWTEXTMETRICEXA NEWTEXTMETRICEX;
+#endif
+#endif
+
+ typedef struct tagPELARRAY {
+ LONG paXCount;
+ LONG paYCount;
+ LONG paXExt;
+ LONG paYExt;
+ BYTE paRGBs;
+ } PELARRAY,*PPELARRAY,*NPPELARRAY,*LPPELARRAY;
+
+ typedef struct tagLOGBRUSH {
+ UINT lbStyle;
+ COLORREF lbColor;
+ ULONG_PTR lbHatch;
+ } LOGBRUSH,*PLOGBRUSH,*NPLOGBRUSH,*LPLOGBRUSH;
+
+ typedef struct tagLOGBRUSH32 {
+ UINT lbStyle;
+ COLORREF lbColor;
+ ULONG lbHatch;
+ } LOGBRUSH32,*PLOGBRUSH32,*NPLOGBRUSH32,*LPLOGBRUSH32;
+
+ typedef LOGBRUSH PATTERN;
+ typedef PATTERN *PPATTERN;
+ typedef PATTERN *NPPATTERN;
+ typedef PATTERN *LPPATTERN;
+
+ typedef struct tagLOGPEN {
+ UINT lopnStyle;
+ POINT lopnWidth;
+ COLORREF lopnColor;
+ } LOGPEN,*PLOGPEN,*NPLOGPEN,*LPLOGPEN;
+
+ typedef struct tagEXTLOGPEN {
+ DWORD elpPenStyle;
+ DWORD elpWidth;
+ UINT elpBrushStyle;
+ COLORREF elpColor;
+ ULONG_PTR elpHatch;
+ DWORD elpNumEntries;
+ DWORD elpStyleEntry[1];
+ } EXTLOGPEN,*PEXTLOGPEN,*NPEXTLOGPEN,*LPEXTLOGPEN;
+
+#ifndef _PALETTEENTRY_DEFINED
+#define _PALETTEENTRY_DEFINED
+ typedef struct tagPALETTEENTRY {
+ BYTE peRed;
+ BYTE peGreen;
+ BYTE peBlue;
+ BYTE peFlags;
+ } PALETTEENTRY,*PPALETTEENTRY,*LPPALETTEENTRY;
+#endif
+
+#ifndef _LOGPALETTE_DEFINED
+#define _LOGPALETTE_DEFINED
+
+ typedef struct tagLOGPALETTE {
+ WORD palVersion;
+ WORD palNumEntries;
+ PALETTEENTRY palPalEntry[1];
+ } LOGPALETTE,*PLOGPALETTE,*NPLOGPALETTE,*LPLOGPALETTE;
+#endif
+
+#define LF_FACESIZE 32
+
+ typedef struct tagLOGFONTA {
+ LONG lfHeight;
+ LONG lfWidth;
+ LONG lfEscapement;
+ LONG lfOrientation;
+ LONG lfWeight;
+ BYTE lfItalic;
+ BYTE lfUnderline;
+ BYTE lfStrikeOut;
+ BYTE lfCharSet;
+ BYTE lfOutPrecision;
+ BYTE lfClipPrecision;
+ BYTE lfQuality;
+ BYTE lfPitchAndFamily;
+ CHAR lfFaceName[LF_FACESIZE];
+ } LOGFONTA,*PLOGFONTA,*NPLOGFONTA,*LPLOGFONTA;
+
+ typedef struct tagLOGFONTW {
+ LONG lfHeight;
+ LONG lfWidth;
+ LONG lfEscapement;
+ LONG lfOrientation;
+ LONG lfWeight;
+ BYTE lfItalic;
+ BYTE lfUnderline;
+ BYTE lfStrikeOut;
+ BYTE lfCharSet;
+ BYTE lfOutPrecision;
+ BYTE lfClipPrecision;
+ BYTE lfQuality;
+ BYTE lfPitchAndFamily;
+ WCHAR lfFaceName[LF_FACESIZE];
+ } LOGFONTW,*PLOGFONTW,*NPLOGFONTW,*LPLOGFONTW;
+#ifdef UNICODE
+ typedef LOGFONTW LOGFONT;
+ typedef PLOGFONTW PLOGFONT;
+ typedef NPLOGFONTW NPLOGFONT;
+ typedef LPLOGFONTW LPLOGFONT;
+#else
+ typedef LOGFONTA LOGFONT;
+ typedef PLOGFONTA PLOGFONT;
+ typedef NPLOGFONTA NPLOGFONT;
+ typedef LPLOGFONTA LPLOGFONT;
+#endif
+
+#define LF_FULLFACESIZE 64
+
+ typedef struct tagENUMLOGFONTA {
+ LOGFONTA elfLogFont;
+ BYTE elfFullName[LF_FULLFACESIZE];
+ BYTE elfStyle[LF_FACESIZE];
+ } ENUMLOGFONTA,*LPENUMLOGFONTA;
+
+ typedef struct tagENUMLOGFONTW {
+ LOGFONTW elfLogFont;
+ WCHAR elfFullName[LF_FULLFACESIZE];
+ WCHAR elfStyle[LF_FACESIZE];
+ } ENUMLOGFONTW,*LPENUMLOGFONTW;
+#ifdef UNICODE
+ typedef ENUMLOGFONTW ENUMLOGFONT;
+ typedef LPENUMLOGFONTW LPENUMLOGFONT;
+#else
+ typedef ENUMLOGFONTA ENUMLOGFONT;
+ typedef LPENUMLOGFONTA LPENUMLOGFONT;
+#endif
+
+ typedef struct tagENUMLOGFONTEXA {
+ LOGFONTA elfLogFont;
+ BYTE elfFullName[LF_FULLFACESIZE];
+ BYTE elfStyle[LF_FACESIZE];
+ BYTE elfScript[LF_FACESIZE];
+ } ENUMLOGFONTEXA,*LPENUMLOGFONTEXA;
+
+ typedef struct tagENUMLOGFONTEXW {
+ LOGFONTW elfLogFont;
+ WCHAR elfFullName[LF_FULLFACESIZE];
+ WCHAR elfStyle[LF_FACESIZE];
+ WCHAR elfScript[LF_FACESIZE];
+ } ENUMLOGFONTEXW,*LPENUMLOGFONTEXW;
+#ifdef UNICODE
+ typedef ENUMLOGFONTEXW ENUMLOGFONTEX;
+ typedef LPENUMLOGFONTEXW LPENUMLOGFONTEX;
+#else
+ typedef ENUMLOGFONTEXA ENUMLOGFONTEX;
+ typedef LPENUMLOGFONTEXA LPENUMLOGFONTEX;
+#endif
+
+#define OUT_DEFAULT_PRECIS 0
+#define OUT_STRING_PRECIS 1
+#define OUT_CHARACTER_PRECIS 2
+#define OUT_STROKE_PRECIS 3
+#define OUT_TT_PRECIS 4
+#define OUT_DEVICE_PRECIS 5
+#define OUT_RASTER_PRECIS 6
+#define OUT_TT_ONLY_PRECIS 7
+#define OUT_OUTLINE_PRECIS 8
+#define OUT_SCREEN_OUTLINE_PRECIS 9
+#define OUT_PS_ONLY_PRECIS 10
+
+#define CLIP_DEFAULT_PRECIS 0
+#define CLIP_CHARACTER_PRECIS 1
+#define CLIP_STROKE_PRECIS 2
+#define CLIP_MASK 0xf
+#define CLIP_LH_ANGLES (1<<4)
+#define CLIP_TT_ALWAYS (2<<4)
+#define CLIP_DFA_DISABLE (4<<4)
+#define CLIP_EMBEDDED (8<<4)
+
+#define DEFAULT_QUALITY 0
+#define DRAFT_QUALITY 1
+#define PROOF_QUALITY 2
+#define NONANTIALIASED_QUALITY 3
+#define ANTIALIASED_QUALITY 4
+
+#define CLEARTYPE_QUALITY 5
+#define CLEARTYPE_NATURAL_QUALITY 6
+
+#define DEFAULT_PITCH 0
+#define FIXED_PITCH 1
+#define VARIABLE_PITCH 2
+#define MONO_FONT 8
+
+#define ANSI_CHARSET 0
+#define DEFAULT_CHARSET 1
+#define SYMBOL_CHARSET 2
+#define SHIFTJIS_CHARSET 128
+#define HANGEUL_CHARSET 129
+#define HANGUL_CHARSET 129
+#define GB2312_CHARSET 134
+#define CHINESEBIG5_CHARSET 136
+#define OEM_CHARSET 255
+#define JOHAB_CHARSET 130
+#define HEBREW_CHARSET 177
+#define ARABIC_CHARSET 178
+#define GREEK_CHARSET 161
+#define TURKISH_CHARSET 162
+#define VIETNAMESE_CHARSET 163
+#define THAI_CHARSET 222
+#define EASTEUROPE_CHARSET 238
+#define RUSSIAN_CHARSET 204
+
+#define MAC_CHARSET 77
+#define BALTIC_CHARSET 186
+
+#define FS_LATIN1 0x00000001L
+#define FS_LATIN2 0x00000002L
+#define FS_CYRILLIC 0x00000004L
+#define FS_GREEK 0x00000008L
+#define FS_TURKISH 0x00000010L
+#define FS_HEBREW 0x00000020L
+#define FS_ARABIC 0x00000040L
+#define FS_BALTIC 0x00000080L
+#define FS_VIETNAMESE 0x00000100L
+#define FS_THAI 0x00010000L
+#define FS_JISJAPAN 0x00020000L
+#define FS_CHINESESIMP 0x00040000L
+#define FS_WANSUNG 0x00080000L
+#define FS_CHINESETRAD 0x00100000L
+#define FS_JOHAB 0x00200000L
+#define FS_SYMBOL 0x80000000L
+
+#define FF_DONTCARE (0<<4)
+#define FF_ROMAN (1<<4)
+
+#define FF_SWISS (2<<4)
+
+#define FF_MODERN (3<<4)
+
+#define FF_SCRIPT (4<<4)
+#define FF_DECORATIVE (5<<4)
+
+#define FW_DONTCARE 0
+#define FW_THIN 100
+#define FW_EXTRALIGHT 200
+#define FW_LIGHT 300
+#define FW_NORMAL 400
+#define FW_MEDIUM 500
+#define FW_SEMIBOLD 600
+#define FW_BOLD 700
+#define FW_EXTRABOLD 800
+#define FW_HEAVY 900
+
+#define FW_ULTRALIGHT FW_EXTRALIGHT
+#define FW_REGULAR FW_NORMAL
+#define FW_DEMIBOLD FW_SEMIBOLD
+#define FW_ULTRABOLD FW_EXTRABOLD
+#define FW_BLACK FW_HEAVY
+
+#define PANOSE_COUNT 10
+#define PAN_FAMILYTYPE_INDEX 0
+#define PAN_SERIFSTYLE_INDEX 1
+#define PAN_WEIGHT_INDEX 2
+#define PAN_PROPORTION_INDEX 3
+#define PAN_CONTRAST_INDEX 4
+#define PAN_STROKEVARIATION_INDEX 5
+#define PAN_ARMSTYLE_INDEX 6
+#define PAN_LETTERFORM_INDEX 7
+#define PAN_MIDLINE_INDEX 8
+#define PAN_XHEIGHT_INDEX 9
+
+#define PAN_CULTURE_LATIN 0
+
+ typedef struct tagPANOSE {
+ BYTE bFamilyType;
+ BYTE bSerifStyle;
+ BYTE bWeight;
+ BYTE bProportion;
+ BYTE bContrast;
+ BYTE bStrokeVariation;
+ BYTE bArmStyle;
+ BYTE bLetterform;
+ BYTE bMidline;
+ BYTE bXHeight;
+ } PANOSE,*LPPANOSE;
+
+#define PAN_ANY 0
+#define PAN_NO_FIT 1
+
+#define PAN_FAMILY_TEXT_DISPLAY 2
+#define PAN_FAMILY_SCRIPT 3
+#define PAN_FAMILY_DECORATIVE 4
+#define PAN_FAMILY_PICTORIAL 5
+
+#define PAN_SERIF_COVE 2
+#define PAN_SERIF_OBTUSE_COVE 3
+#define PAN_SERIF_SQUARE_COVE 4
+#define PAN_SERIF_OBTUSE_SQUARE_COVE 5
+#define PAN_SERIF_SQUARE 6
+#define PAN_SERIF_THIN 7
+#define PAN_SERIF_BONE 8
+#define PAN_SERIF_EXAGGERATED 9
+#define PAN_SERIF_TRIANGLE 10
+#define PAN_SERIF_NORMAL_SANS 11
+#define PAN_SERIF_OBTUSE_SANS 12
+#define PAN_SERIF_PERP_SANS 13
+#define PAN_SERIF_FLARED 14
+#define PAN_SERIF_ROUNDED 15
+
+#define PAN_WEIGHT_VERY_LIGHT 2
+#define PAN_WEIGHT_LIGHT 3
+#define PAN_WEIGHT_THIN 4
+#define PAN_WEIGHT_BOOK 5
+#define PAN_WEIGHT_MEDIUM 6
+#define PAN_WEIGHT_DEMI 7
+#define PAN_WEIGHT_BOLD 8
+#define PAN_WEIGHT_HEAVY 9
+#define PAN_WEIGHT_BLACK 10
+#define PAN_WEIGHT_NORD 11
+
+#define PAN_PROP_OLD_STYLE 2
+#define PAN_PROP_MODERN 3
+#define PAN_PROP_EVEN_WIDTH 4
+#define PAN_PROP_EXPANDED 5
+#define PAN_PROP_CONDENSED 6
+#define PAN_PROP_VERY_EXPANDED 7
+#define PAN_PROP_VERY_CONDENSED 8
+#define PAN_PROP_MONOSPACED 9
+
+#define PAN_CONTRAST_NONE 2
+#define PAN_CONTRAST_VERY_LOW 3
+#define PAN_CONTRAST_LOW 4
+#define PAN_CONTRAST_MEDIUM_LOW 5
+#define PAN_CONTRAST_MEDIUM 6
+#define PAN_CONTRAST_MEDIUM_HIGH 7
+#define PAN_CONTRAST_HIGH 8
+#define PAN_CONTRAST_VERY_HIGH 9
+
+#define PAN_STROKE_GRADUAL_DIAG 2
+#define PAN_STROKE_GRADUAL_TRAN 3
+#define PAN_STROKE_GRADUAL_VERT 4
+#define PAN_STROKE_GRADUAL_HORZ 5
+#define PAN_STROKE_RAPID_VERT 6
+#define PAN_STROKE_RAPID_HORZ 7
+#define PAN_STROKE_INSTANT_VERT 8
+
+#define PAN_STRAIGHT_ARMS_HORZ 2
+#define PAN_STRAIGHT_ARMS_WEDGE 3
+#define PAN_STRAIGHT_ARMS_VERT 4
+#define PAN_STRAIGHT_ARMS_SINGLE_SERIF 5
+#define PAN_STRAIGHT_ARMS_DOUBLE_SERIF 6
+#define PAN_BENT_ARMS_HORZ 7
+#define PAN_BENT_ARMS_WEDGE 8
+#define PAN_BENT_ARMS_VERT 9
+#define PAN_BENT_ARMS_SINGLE_SERIF 10
+#define PAN_BENT_ARMS_DOUBLE_SERIF 11
+
+#define PAN_LETT_NORMAL_CONTACT 2
+#define PAN_LETT_NORMAL_WEIGHTED 3
+#define PAN_LETT_NORMAL_BOXED 4
+#define PAN_LETT_NORMAL_FLATTENED 5
+#define PAN_LETT_NORMAL_ROUNDED 6
+#define PAN_LETT_NORMAL_OFF_CENTER 7
+#define PAN_LETT_NORMAL_SQUARE 8
+#define PAN_LETT_OBLIQUE_CONTACT 9
+#define PAN_LETT_OBLIQUE_WEIGHTED 10
+#define PAN_LETT_OBLIQUE_BOXED 11
+#define PAN_LETT_OBLIQUE_FLATTENED 12
+#define PAN_LETT_OBLIQUE_ROUNDED 13
+#define PAN_LETT_OBLIQUE_OFF_CENTER 14
+#define PAN_LETT_OBLIQUE_SQUARE 15
+
+#define PAN_MIDLINE_STANDARD_TRIMMED 2
+#define PAN_MIDLINE_STANDARD_POINTED 3
+#define PAN_MIDLINE_STANDARD_SERIFED 4
+#define PAN_MIDLINE_HIGH_TRIMMED 5
+#define PAN_MIDLINE_HIGH_POINTED 6
+#define PAN_MIDLINE_HIGH_SERIFED 7
+#define PAN_MIDLINE_CONSTANT_TRIMMED 8
+#define PAN_MIDLINE_CONSTANT_POINTED 9
+#define PAN_MIDLINE_CONSTANT_SERIFED 10
+#define PAN_MIDLINE_LOW_TRIMMED 11
+#define PAN_MIDLINE_LOW_POINTED 12
+#define PAN_MIDLINE_LOW_SERIFED 13
+
+#define PAN_XHEIGHT_CONSTANT_SMALL 2
+#define PAN_XHEIGHT_CONSTANT_STD 3
+#define PAN_XHEIGHT_CONSTANT_LARGE 4
+#define PAN_XHEIGHT_DUCKING_SMALL 5
+#define PAN_XHEIGHT_DUCKING_STD 6
+#define PAN_XHEIGHT_DUCKING_LARGE 7
+
+#define ELF_VENDOR_SIZE 4
+
+ typedef struct tagEXTLOGFONTA {
+ LOGFONTA elfLogFont;
+ BYTE elfFullName[LF_FULLFACESIZE];
+ BYTE elfStyle[LF_FACESIZE];
+ DWORD elfVersion;
+ DWORD elfStyleSize;
+ DWORD elfMatch;
+ DWORD elfReserved;
+ BYTE elfVendorId[ELF_VENDOR_SIZE];
+ DWORD elfCulture;
+ PANOSE elfPanose;
+ } EXTLOGFONTA,*PEXTLOGFONTA,*NPEXTLOGFONTA,*LPEXTLOGFONTA;
+
+ typedef struct tagEXTLOGFONTW {
+ LOGFONTW elfLogFont;
+ WCHAR elfFullName[LF_FULLFACESIZE];
+ WCHAR elfStyle[LF_FACESIZE];
+ DWORD elfVersion;
+ DWORD elfStyleSize;
+ DWORD elfMatch;
+ DWORD elfReserved;
+ BYTE elfVendorId[ELF_VENDOR_SIZE];
+ DWORD elfCulture;
+ PANOSE elfPanose;
+ } EXTLOGFONTW,*PEXTLOGFONTW,*NPEXTLOGFONTW,*LPEXTLOGFONTW;
+#ifdef UNICODE
+ typedef EXTLOGFONTW EXTLOGFONT;
+ typedef PEXTLOGFONTW PEXTLOGFONT;
+ typedef NPEXTLOGFONTW NPEXTLOGFONT;
+ typedef LPEXTLOGFONTW LPEXTLOGFONT;
+#else
+ typedef EXTLOGFONTA EXTLOGFONT;
+ typedef PEXTLOGFONTA PEXTLOGFONT;
+ typedef NPEXTLOGFONTA NPEXTLOGFONT;
+ typedef LPEXTLOGFONTA LPEXTLOGFONT;
+#endif
+
+#define ELF_VERSION 0
+#define ELF_CULTURE_LATIN 0
+
+#define RASTER_FONTTYPE 0x0001
+#define DEVICE_FONTTYPE 0x002
+#define TRUETYPE_FONTTYPE 0x004
+
+#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
+#define PALETTERGB(r,g,b) (0x02000000 | RGB(r,g,b))
+#define PALETTEINDEX(i) ((COLORREF)(0x01000000 | (DWORD)(WORD)(i)))
+
+#define PC_RESERVED 0x01
+#define PC_EXPLICIT 0x02
+#define PC_NOCOLLAPSE 0x04
+
+#define GetRValue(rgb) (LOBYTE(rgb))
+#define GetGValue(rgb) (LOBYTE(((WORD)(rgb)) >> 8))
+#define GetBValue(rgb) (LOBYTE((rgb)>>16))
+
+#define TRANSPARENT 1
+#define OPAQUE 2
+#define BKMODE_LAST 2
+
+#define GM_COMPATIBLE 1
+#define GM_ADVANCED 2
+#define GM_LAST 2
+
+#define PT_CLOSEFIGURE 0x01
+#define PT_LINETO 0x02
+#define PT_BEZIERTO 0x04
+#define PT_MOVETO 0x06
+
+#define MM_TEXT 1
+#define MM_LOMETRIC 2
+#define MM_HIMETRIC 3
+#define MM_LOENGLISH 4
+#define MM_HIENGLISH 5
+#define MM_TWIPS 6
+#define MM_ISOTROPIC 7
+#define MM_ANISOTROPIC 8
+
+#define MM_MIN MM_TEXT
+#define MM_MAX MM_ANISOTROPIC
+#define MM_MAX_FIXEDSCALE MM_TWIPS
+
+#define ABSOLUTE 1
+#define RELATIVE 2
+
+#define WHITE_BRUSH 0
+#define LTGRAY_BRUSH 1
+#define GRAY_BRUSH 2
+#define DKGRAY_BRUSH 3
+#define BLACK_BRUSH 4
+#define NULL_BRUSH 5
+#define HOLLOW_BRUSH NULL_BRUSH
+#define WHITE_PEN 6
+#define BLACK_PEN 7
+#define NULL_PEN 8
+#define OEM_FIXED_FONT 10
+#define ANSI_FIXED_FONT 11
+#define ANSI_VAR_FONT 12
+#define SYSTEM_FONT 13
+#define DEVICE_DEFAULT_FONT 14
+#define DEFAULT_PALETTE 15
+#define SYSTEM_FIXED_FONT 16
+
+#define DEFAULT_GUI_FONT 17
+
+#define DC_BRUSH 18
+#define DC_PEN 19
+
+#define STOCK_LAST 19
+
+#define CLR_INVALID 0xFFFFFFFF
+
+#define BS_SOLID 0
+#define BS_NULL 1
+#define BS_HOLLOW BS_NULL
+#define BS_HATCHED 2
+#define BS_PATTERN 3
+#define BS_INDEXED 4
+#define BS_DIBPATTERN 5
+#define BS_DIBPATTERNPT 6
+#define BS_PATTERN8X8 7
+#define BS_DIBPATTERN8X8 8
+#define BS_MONOPATTERN 9
+
+#define HS_HORIZONTAL 0
+#define HS_VERTICAL 1
+#define HS_FDIAGONAL 2
+#define HS_BDIAGONAL 3
+#define HS_CROSS 4
+#define HS_DIAGCROSS 5
+
+#define PS_SOLID 0
+#define PS_DASH 1
+#define PS_DOT 2
+#define PS_DASHDOT 3
+#define PS_DASHDOTDOT 4
+#define PS_NULL 5
+#define PS_INSIDEFRAME 6
+#define PS_USERSTYLE 7
+#define PS_ALTERNATE 8
+#define PS_STYLE_MASK 0x0000000F
+
+#define PS_ENDCAP_ROUND 0x00000000
+#define PS_ENDCAP_SQUARE 0x00000100
+#define PS_ENDCAP_FLAT 0x00000200
+#define PS_ENDCAP_MASK 0x00000F00
+
+#define PS_JOIN_ROUND 0x00000000
+#define PS_JOIN_BEVEL 0x00001000
+#define PS_JOIN_MITER 0x00002000
+#define PS_JOIN_MASK 0x0000F000
+
+#define PS_COSMETIC 0x00000000
+#define PS_GEOMETRIC 0x00010000
+#define PS_TYPE_MASK 0x000F0000
+
+#define AD_COUNTERCLOCKWISE 1
+#define AD_CLOCKWISE 2
+
+#define DRIVERVERSION 0
+#define TECHNOLOGY 2
+#define HORZSIZE 4
+#define VERTSIZE 6
+#define HORZRES 8
+#define VERTRES 10
+#define BITSPIXEL 12
+#define PLANES 14
+#define NUMBRUSHES 16
+#define NUMPENS 18
+#define NUMMARKERS 20
+#define NUMFONTS 22
+#define NUMCOLORS 24
+#define PDEVICESIZE 26
+#define CURVECAPS 28
+#define LINECAPS 30
+#define POLYGONALCAPS 32
+#define TEXTCAPS 34
+#define CLIPCAPS 36
+#define RASTERCAPS 38
+#define ASPECTX 40
+#define ASPECTY 42
+#define ASPECTXY 44
+
+#define LOGPIXELSX 88
+#define LOGPIXELSY 90
+
+#define SIZEPALETTE 104
+#define NUMRESERVED 106
+#define COLORRES 108
+
+#define PHYSICALWIDTH 110
+#define PHYSICALHEIGHT 111
+#define PHYSICALOFFSETX 112
+#define PHYSICALOFFSETY 113
+#define SCALINGFACTORX 114
+#define SCALINGFACTORY 115
+
+#define VREFRESH 116
+
+#define DESKTOPVERTRES 117
+
+#define DESKTOPHORZRES 118
+
+#define BLTALIGNMENT 119
+
+#define SHADEBLENDCAPS 120
+#define COLORMGMTCAPS 121
+
+#ifndef NOGDICAPMASKS
+#define DT_PLOTTER 0
+#define DT_RASDISPLAY 1
+#define DT_RASPRINTER 2
+#define DT_RASCAMERA 3
+#define DT_CHARSTREAM 4
+#define DT_METAFILE 5
+#define DT_DISPFILE 6
+
+#define CC_NONE 0
+#define CC_CIRCLES 1
+#define CC_PIE 2
+#define CC_CHORD 4
+#define CC_ELLIPSES 8
+#define CC_WIDE 16
+#define CC_STYLED 32
+#define CC_WIDESTYLED 64
+#define CC_INTERIORS 128
+#define CC_ROUNDRECT 256
+
+#define LC_NONE 0
+#define LC_POLYLINE 2
+#define LC_MARKER 4
+#define LC_POLYMARKER 8
+#define LC_WIDE 16
+#define LC_STYLED 32
+#define LC_WIDESTYLED 64
+#define LC_INTERIORS 128
+
+#define PC_NONE 0
+#define PC_POLYGON 1
+#define PC_RECTANGLE 2
+#define PC_WINDPOLYGON 4
+#define PC_TRAPEZOID 4
+#define PC_SCANLINE 8
+#define PC_WIDE 16
+#define PC_STYLED 32
+#define PC_WIDESTYLED 64
+#define PC_INTERIORS 128
+#define PC_POLYPOLYGON 256
+#define PC_PATHS 512
+
+#define CP_NONE 0
+#define CP_RECTANGLE 1
+#define CP_REGION 2
+
+#define TC_OP_CHARACTER 0x00000001
+#define TC_OP_STROKE 0x00000002
+#define TC_CP_STROKE 0x00000004
+#define TC_CR_90 0x00000008
+#define TC_CR_ANY 0x00000010
+#define TC_SF_X_YINDEP 0x00000020
+#define TC_SA_DOUBLE 0x00000040
+#define TC_SA_INTEGER 0x00000080
+#define TC_SA_CONTIN 0x00000100
+#define TC_EA_DOUBLE 0x00000200
+#define TC_IA_ABLE 0x00000400
+#define TC_UA_ABLE 0x00000800
+#define TC_SO_ABLE 0x00001000
+#define TC_RA_ABLE 0x00002000
+#define TC_VA_ABLE 0x00004000
+#define TC_RESERVED 0x00008000
+#define TC_SCROLLBLT 0x00010000
+#endif
+
+#define RC_NONE
+#define RC_BITBLT 1
+#define RC_BANDING 2
+#define RC_SCALING 4
+#define RC_BITMAP64 8
+#define RC_GDI20_OUTPUT 0x0010
+#define RC_GDI20_STATE 0x0020
+#define RC_SAVEBITMAP 0x0040
+#define RC_DI_BITMAP 0x0080
+#define RC_PALETTE 0x0100
+#define RC_DIBTODEV 0x0200
+#define RC_BIGFONT 0x0400
+#define RC_STRETCHBLT 0x0800
+#define RC_FLOODFILL 0x1000
+#define RC_STRETCHDIB 0x2000
+#define RC_OP_DX_OUTPUT 0x4000
+#define RC_DEVBITS 0x8000
+
+#define SB_NONE 0x00000000
+#define SB_CONST_ALPHA 0x00000001
+#define SB_PIXEL_ALPHA 0x00000002
+#define SB_PREMULT_ALPHA 0x00000004
+
+#define SB_GRAD_RECT 0x00000010
+#define SB_GRAD_TRI 0x00000020
+
+#define CM_NONE 0x00000000
+#define CM_DEVICE_ICM 0x00000001
+#define CM_GAMMA_RAMP 0x00000002
+#define CM_CMYK_COLOR 0x00000004
+
+#define DIB_RGB_COLORS 0
+#define DIB_PAL_COLORS 1
+
+#define SYSPAL_ERROR 0
+#define SYSPAL_STATIC 1
+#define SYSPAL_NOSTATIC 2
+#define SYSPAL_NOSTATIC256 3
+
+#define CBM_INIT 0x04L
+
+#define FLOODFILLBORDER 0
+#define FLOODFILLSURFACE 1
+
+#define CCHDEVICENAME 32
+
+#define CCHFORMNAME 32
+
+ typedef struct _devicemodeA {
+ BYTE dmDeviceName[CCHDEVICENAME];
+ WORD dmSpecVersion;
+ WORD dmDriverVersion;
+ WORD dmSize;
+ WORD dmDriverExtra;
+ DWORD dmFields;
+ union {
+ struct {
+ short dmOrientation;
+ short dmPaperSize;
+ short dmPaperLength;
+ short dmPaperWidth;
+ short dmScale;
+ short dmCopies;
+ short dmDefaultSource;
+ short dmPrintQuality;
+ };
+ struct {
+ POINTL dmPosition;
+ DWORD dmDisplayOrientation;
+ DWORD dmDisplayFixedOutput;
+ };
+ };
+ short dmColor;
+ short dmDuplex;
+ short dmYResolution;
+ short dmTTOption;
+ short dmCollate;
+ BYTE dmFormName[CCHFORMNAME];
+ WORD dmLogPixels;
+ DWORD dmBitsPerPel;
+ DWORD dmPelsWidth;
+ DWORD dmPelsHeight;
+ union {
+ DWORD dmDisplayFlags;
+ DWORD dmNup;
+ };
+ DWORD dmDisplayFrequency;
+ DWORD dmICMMethod;
+ DWORD dmICMIntent;
+ DWORD dmMediaType;
+ DWORD dmDitherType;
+ DWORD dmReserved1;
+ DWORD dmReserved2;
+ DWORD dmPanningWidth;
+ DWORD dmPanningHeight;
+ } DEVMODEA,*PDEVMODEA,*NPDEVMODEA,*LPDEVMODEA;
+
+ typedef struct _devicemodeW {
+ WCHAR dmDeviceName[CCHDEVICENAME];
+ WORD dmSpecVersion;
+ WORD dmDriverVersion;
+ WORD dmSize;
+ WORD dmDriverExtra;
+ DWORD dmFields;
+ union {
+ struct {
+ short dmOrientation;
+ short dmPaperSize;
+ short dmPaperLength;
+ short dmPaperWidth;
+ short dmScale;
+ short dmCopies;
+ short dmDefaultSource;
+ short dmPrintQuality;
+ };
+ struct {
+ POINTL dmPosition;
+ DWORD dmDisplayOrientation;
+ DWORD dmDisplayFixedOutput;
+ };
+ };
+ short dmColor;
+ short dmDuplex;
+ short dmYResolution;
+ short dmTTOption;
+ short dmCollate;
+ WCHAR dmFormName[CCHFORMNAME];
+ WORD dmLogPixels;
+ DWORD dmBitsPerPel;
+ DWORD dmPelsWidth;
+ DWORD dmPelsHeight;
+ union {
+ DWORD dmDisplayFlags;
+ DWORD dmNup;
+ };
+ DWORD dmDisplayFrequency;
+ DWORD dmICMMethod;
+ DWORD dmICMIntent;
+ DWORD dmMediaType;
+ DWORD dmDitherType;
+ DWORD dmReserved1;
+ DWORD dmReserved2;
+ DWORD dmPanningWidth;
+ DWORD dmPanningHeight;
+ } DEVMODEW,*PDEVMODEW,*NPDEVMODEW,*LPDEVMODEW;
+#ifdef UNICODE
+ typedef DEVMODEW DEVMODE;
+ typedef PDEVMODEW PDEVMODE;
+ typedef NPDEVMODEW NPDEVMODE;
+ typedef LPDEVMODEW LPDEVMODE;
+#else
+ typedef DEVMODEA DEVMODE;
+ typedef PDEVMODEA PDEVMODE;
+ typedef NPDEVMODEA NPDEVMODE;
+ typedef LPDEVMODEA LPDEVMODE;
+#endif
+
+#define DM_SPECVERSION 0x0401
+
+#define DM_ORIENTATION 0x00000001L
+#define DM_PAPERSIZE 0x00000002L
+#define DM_PAPERLENGTH 0x00000004L
+#define DM_PAPERWIDTH 0x00000008L
+#define DM_SCALE 0x00000010L
+#define DM_POSITION 0x00000020L
+#define DM_NUP 0x00000040L
+#define DM_DISPLAYORIENTATION 0x00000080L
+#define DM_COPIES 0x00000100L
+#define DM_DEFAULTSOURCE 0x00000200L
+#define DM_PRINTQUALITY 0x00000400L
+#define DM_COLOR 0x00000800L
+#define DM_DUPLEX 0x00001000L
+#define DM_YRESOLUTION 0x00002000L
+#define DM_TTOPTION 0x00004000L
+#define DM_COLLATE 0x00008000L
+#define DM_FORMNAME 0x00010000L
+#define DM_LOGPIXELS 0x00020000L
+#define DM_BITSPERPEL 0x00040000L
+#define DM_PELSWIDTH 0x00080000L
+#define DM_PELSHEIGHT 0x00100000L
+#define DM_DISPLAYFLAGS 0x00200000L
+#define DM_DISPLAYFREQUENCY 0x00400000L
+#define DM_ICMMETHOD 0x00800000L
+#define DM_ICMINTENT 0x01000000L
+#define DM_MEDIATYPE 0x02000000L
+#define DM_DITHERTYPE 0x04000000L
+#define DM_PANNINGWIDTH 0x08000000L
+#define DM_PANNINGHEIGHT 0x10000000L
+#define DM_DISPLAYFIXEDOUTPUT 0x20000000L
+
+#define DMORIENT_PORTRAIT 1
+#define DMORIENT_LANDSCAPE 2
+
+#define DMPAPER_FIRST DMPAPER_LETTER
+#define DMPAPER_LETTER 1
+#define DMPAPER_LETTERSMALL 2
+#define DMPAPER_TABLOID 3
+#define DMPAPER_LEDGER 4
+#define DMPAPER_LEGAL 5
+#define DMPAPER_STATEMENT 6
+#define DMPAPER_EXECUTIVE 7
+#define DMPAPER_A3 8
+#define DMPAPER_A4 9
+#define DMPAPER_A4SMALL 10
+#define DMPAPER_A5 11
+#define DMPAPER_B4 12
+#define DMPAPER_B5 13
+#define DMPAPER_FOLIO 14
+#define DMPAPER_QUARTO 15
+#define DMPAPER_10X14 16
+#define DMPAPER_11X17 17
+#define DMPAPER_NOTE 18
+#define DMPAPER_ENV_9 19
+#define DMPAPER_ENV_10 20
+#define DMPAPER_ENV_11 21
+#define DMPAPER_ENV_12 22
+#define DMPAPER_ENV_14 23
+#define DMPAPER_CSHEET 24
+#define DMPAPER_DSHEET 25
+#define DMPAPER_ESHEET 26
+#define DMPAPER_ENV_DL 27
+#define DMPAPER_ENV_C5 28
+#define DMPAPER_ENV_C3 29
+#define DMPAPER_ENV_C4 30
+#define DMPAPER_ENV_C6 31
+#define DMPAPER_ENV_C65 32
+#define DMPAPER_ENV_B4 33
+#define DMPAPER_ENV_B5 34
+#define DMPAPER_ENV_B6 35
+#define DMPAPER_ENV_ITALY 36
+#define DMPAPER_ENV_MONARCH 37
+#define DMPAPER_ENV_PERSONAL 38
+#define DMPAPER_FANFOLD_US 39
+#define DMPAPER_FANFOLD_STD_GERMAN 40
+#define DMPAPER_FANFOLD_LGL_GERMAN 41
+#define DMPAPER_ISO_B4 42
+#define DMPAPER_JAPANESE_POSTCARD 43
+#define DMPAPER_9X11 44
+#define DMPAPER_10X11 45
+#define DMPAPER_15X11 46
+#define DMPAPER_ENV_INVITE 47
+#define DMPAPER_RESERVED_48 48
+#define DMPAPER_RESERVED_49 49
+#define DMPAPER_LETTER_EXTRA 50
+#define DMPAPER_LEGAL_EXTRA 51
+#define DMPAPER_TABLOID_EXTRA 52
+#define DMPAPER_A4_EXTRA 53
+#define DMPAPER_LETTER_TRANSVERSE 54
+#define DMPAPER_A4_TRANSVERSE 55
+#define DMPAPER_LETTER_EXTRA_TRANSVERSE 56
+#define DMPAPER_A_PLUS 57
+#define DMPAPER_B_PLUS 58
+#define DMPAPER_LETTER_PLUS 59
+#define DMPAPER_A4_PLUS 60
+#define DMPAPER_A5_TRANSVERSE 61
+#define DMPAPER_B5_TRANSVERSE 62
+#define DMPAPER_A3_EXTRA 63
+#define DMPAPER_A5_EXTRA 64
+#define DMPAPER_B5_EXTRA 65
+#define DMPAPER_A2 66
+#define DMPAPER_A3_TRANSVERSE 67
+#define DMPAPER_A3_EXTRA_TRANSVERSE 68
+#define DMPAPER_DBL_JAPANESE_POSTCARD 69
+#define DMPAPER_A6 70
+#define DMPAPER_JENV_KAKU2 71
+#define DMPAPER_JENV_KAKU3 72
+#define DMPAPER_JENV_CHOU3 73
+#define DMPAPER_JENV_CHOU4 74
+#define DMPAPER_LETTER_ROTATED 75
+#define DMPAPER_A3_ROTATED 76
+#define DMPAPER_A4_ROTATED 77
+#define DMPAPER_A5_ROTATED 78
+#define DMPAPER_B4_JIS_ROTATED 79
+#define DMPAPER_B5_JIS_ROTATED 80
+#define DMPAPER_JAPANESE_POSTCARD_ROTATED 81
+#define DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED 82
+#define DMPAPER_A6_ROTATED 83
+#define DMPAPER_JENV_KAKU2_ROTATED 84
+#define DMPAPER_JENV_KAKU3_ROTATED 85
+#define DMPAPER_JENV_CHOU3_ROTATED 86
+#define DMPAPER_JENV_CHOU4_ROTATED 87
+#define DMPAPER_B6_JIS 88
+#define DMPAPER_B6_JIS_ROTATED 89
+#define DMPAPER_12X11 90
+#define DMPAPER_JENV_YOU4 91
+#define DMPAPER_JENV_YOU4_ROTATED 92
+#define DMPAPER_P16K 93
+#define DMPAPER_P32K 94
+#define DMPAPER_P32KBIG 95
+#define DMPAPER_PENV_1 96
+#define DMPAPER_PENV_2 97
+#define DMPAPER_PENV_3 98
+#define DMPAPER_PENV_4 99
+#define DMPAPER_PENV_5 100
+#define DMPAPER_PENV_6 101
+#define DMPAPER_PENV_7 102
+#define DMPAPER_PENV_8 103
+#define DMPAPER_PENV_9 104
+#define DMPAPER_PENV_10 105
+#define DMPAPER_P16K_ROTATED 106
+#define DMPAPER_P32K_ROTATED 107
+#define DMPAPER_P32KBIG_ROTATED 108
+#define DMPAPER_PENV_1_ROTATED 109
+#define DMPAPER_PENV_2_ROTATED 110
+#define DMPAPER_PENV_3_ROTATED 111
+#define DMPAPER_PENV_4_ROTATED 112
+#define DMPAPER_PENV_5_ROTATED 113
+#define DMPAPER_PENV_6_ROTATED 114
+#define DMPAPER_PENV_7_ROTATED 115
+#define DMPAPER_PENV_8_ROTATED 116
+#define DMPAPER_PENV_9_ROTATED 117
+#define DMPAPER_PENV_10_ROTATED 118
+
+#define DMPAPER_LAST DMPAPER_PENV_10_ROTATED
+
+#define DMPAPER_USER 256
+
+#define DMBIN_FIRST DMBIN_UPPER
+#define DMBIN_UPPER 1
+#define DMBIN_ONLYONE 1
+#define DMBIN_LOWER 2
+#define DMBIN_MIDDLE 3
+#define DMBIN_MANUAL 4
+#define DMBIN_ENVELOPE 5
+#define DMBIN_ENVMANUAL 6
+#define DMBIN_AUTO 7
+#define DMBIN_TRACTOR 8
+#define DMBIN_SMALLFMT 9
+#define DMBIN_LARGEFMT 10
+#define DMBIN_LARGECAPACITY 11
+#define DMBIN_CASSETTE 14
+#define DMBIN_FORMSOURCE 15
+#define DMBIN_LAST DMBIN_FORMSOURCE
+
+#define DMBIN_USER 256
+
+#define DMRES_DRAFT (-1)
+#define DMRES_LOW (-2)
+#define DMRES_MEDIUM (-3)
+#define DMRES_HIGH (-4)
+
+#define DMCOLOR_MONOCHROME 1
+#define DMCOLOR_COLOR 2
+
+#define DMDUP_SIMPLEX 1
+#define DMDUP_VERTICAL 2
+#define DMDUP_HORIZONTAL 3
+
+#define DMTT_BITMAP 1
+#define DMTT_DOWNLOAD 2
+#define DMTT_SUBDEV 3
+#define DMTT_DOWNLOAD_OUTLINE 4
+
+#define DMCOLLATE_FALSE 0
+#define DMCOLLATE_TRUE 1
+
+#define DMDO_DEFAULT 0
+#define DMDO_90 1
+#define DMDO_180 2
+#define DMDO_270 3
+
+#define DMDFO_DEFAULT 0
+#define DMDFO_STRETCH 1
+#define DMDFO_CENTER 2
+
+#define DMDISPLAYFLAGS_TEXTMODE 0x00000004
+
+#define DMNUP_SYSTEM 1
+#define DMNUP_ONEUP 2
+
+#define DMICMMETHOD_NONE 1
+#define DMICMMETHOD_SYSTEM 2
+#define DMICMMETHOD_DRIVER 3
+#define DMICMMETHOD_DEVICE 4
+
+#define DMICMMETHOD_USER 256
+
+#define DMICM_SATURATE 1
+#define DMICM_CONTRAST 2
+#define DMICM_COLORIMETRIC 3
+#define DMICM_ABS_COLORIMETRIC 4
+
+#define DMICM_USER 256
+
+#define DMMEDIA_STANDARD 1
+#define DMMEDIA_TRANSPARENCY 2
+#define DMMEDIA_GLOSSY 3
+
+#define DMMEDIA_USER 256
+
+#define DMDITHER_NONE 1
+#define DMDITHER_COARSE 2
+#define DMDITHER_FINE 3
+#define DMDITHER_LINEART 4
+#define DMDITHER_ERRORDIFFUSION 5
+#define DMDITHER_RESERVED6 6
+#define DMDITHER_RESERVED7 7
+#define DMDITHER_RESERVED8 8
+#define DMDITHER_RESERVED9 9
+#define DMDITHER_GRAYSCALE 10
+
+#define DMDITHER_USER 256
+
+ typedef struct _DISPLAY_DEVICEA {
+ DWORD cb;
+ CHAR DeviceName[32];
+ CHAR DeviceString[128];
+ DWORD StateFlags;
+ CHAR DeviceID[128];
+ CHAR DeviceKey[128];
+ } DISPLAY_DEVICEA,*PDISPLAY_DEVICEA,*LPDISPLAY_DEVICEA;
+ typedef struct _DISPLAY_DEVICEW {
+ DWORD cb;
+ WCHAR DeviceName[32];
+ WCHAR DeviceString[128];
+ DWORD StateFlags;
+ WCHAR DeviceID[128];
+ WCHAR DeviceKey[128];
+ } DISPLAY_DEVICEW,*PDISPLAY_DEVICEW,*LPDISPLAY_DEVICEW;
+#ifdef UNICODE
+ typedef DISPLAY_DEVICEW DISPLAY_DEVICE;
+ typedef PDISPLAY_DEVICEW PDISPLAY_DEVICE;
+ typedef LPDISPLAY_DEVICEW LPDISPLAY_DEVICE;
+#else
+ typedef DISPLAY_DEVICEA DISPLAY_DEVICE;
+ typedef PDISPLAY_DEVICEA PDISPLAY_DEVICE;
+ typedef LPDISPLAY_DEVICEA LPDISPLAY_DEVICE;
+#endif
+
+#define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
+#define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002
+#define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004
+#define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008
+#define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010
+#define DISPLAY_DEVICE_REMOVABLE 0x00000020
+#define DISPLAY_DEVICE_MODESPRUNED 0x08000000
+#define DISPLAY_DEVICE_REMOTE 0x04000000
+#define DISPLAY_DEVICE_DISCONNECT 0x02000000
+
+#define DISPLAY_DEVICE_ACTIVE 0x00000001
+#define DISPLAY_DEVICE_ATTACHED 0x00000002
+
+#define RDH_RECTANGLES 1
+
+ typedef struct _RGNDATAHEADER {
+ DWORD dwSize;
+ DWORD iType;
+ DWORD nCount;
+ DWORD nRgnSize;
+ RECT rcBound;
+ } RGNDATAHEADER,*PRGNDATAHEADER;
+
+ typedef struct _RGNDATA {
+ RGNDATAHEADER rdh;
+ char Buffer[1];
+ } RGNDATA,*PRGNDATA,*NPRGNDATA,*LPRGNDATA;
+
+#define SYSRGN 4
+
+ typedef struct _ABC {
+ int abcA;
+ UINT abcB;
+ int abcC;
+ } ABC,*PABC,*NPABC,*LPABC;
+
+ typedef struct _ABCFLOAT {
+ FLOAT abcfA;
+ FLOAT abcfB;
+ FLOAT abcfC;
+ } ABCFLOAT,*PABCFLOAT,*NPABCFLOAT,*LPABCFLOAT;
+
+#ifndef NOTEXTMETRIC
+
+ typedef struct _OUTLINETEXTMETRICA {
+ UINT otmSize;
+ TEXTMETRICA otmTextMetrics;
+ BYTE otmFiller;
+ PANOSE otmPanoseNumber;
+ UINT otmfsSelection;
+ UINT otmfsType;
+ int otmsCharSlopeRise;
+ int otmsCharSlopeRun;
+ int otmItalicAngle;
+ UINT otmEMSquare;
+ int otmAscent;
+ int otmDescent;
+ UINT otmLineGap;
+ UINT otmsCapEmHeight;
+ UINT otmsXHeight;
+ RECT otmrcFontBox;
+ int otmMacAscent;
+ int otmMacDescent;
+ UINT otmMacLineGap;
+ UINT otmusMinimumPPEM;
+ POINT otmptSubscriptSize;
+ POINT otmptSubscriptOffset;
+ POINT otmptSuperscriptSize;
+ POINT otmptSuperscriptOffset;
+ UINT otmsStrikeoutSize;
+ int otmsStrikeoutPosition;
+ int otmsUnderscoreSize;
+ int otmsUnderscorePosition;
+ PSTR otmpFamilyName;
+ PSTR otmpFaceName;
+ PSTR otmpStyleName;
+ PSTR otmpFullName;
+ } OUTLINETEXTMETRICA,*POUTLINETEXTMETRICA,*NPOUTLINETEXTMETRICA,*LPOUTLINETEXTMETRICA;
+
+ typedef struct _OUTLINETEXTMETRICW {
+ UINT otmSize;
+ TEXTMETRICW otmTextMetrics;
+ BYTE otmFiller;
+ PANOSE otmPanoseNumber;
+ UINT otmfsSelection;
+ UINT otmfsType;
+ int otmsCharSlopeRise;
+ int otmsCharSlopeRun;
+ int otmItalicAngle;
+ UINT otmEMSquare;
+ int otmAscent;
+ int otmDescent;
+ UINT otmLineGap;
+ UINT otmsCapEmHeight;
+ UINT otmsXHeight;
+ RECT otmrcFontBox;
+ int otmMacAscent;
+ int otmMacDescent;
+ UINT otmMacLineGap;
+ UINT otmusMinimumPPEM;
+ POINT otmptSubscriptSize;
+ POINT otmptSubscriptOffset;
+ POINT otmptSuperscriptSize;
+ POINT otmptSuperscriptOffset;
+ UINT otmsStrikeoutSize;
+ int otmsStrikeoutPosition;
+ int otmsUnderscoreSize;
+ int otmsUnderscorePosition;
+ PSTR otmpFamilyName;
+ PSTR otmpFaceName;
+ PSTR otmpStyleName;
+ PSTR otmpFullName;
+ } OUTLINETEXTMETRICW,*POUTLINETEXTMETRICW,*NPOUTLINETEXTMETRICW,*LPOUTLINETEXTMETRICW;
+#ifdef UNICODE
+ typedef OUTLINETEXTMETRICW OUTLINETEXTMETRIC;
+ typedef POUTLINETEXTMETRICW POUTLINETEXTMETRIC;
+ typedef NPOUTLINETEXTMETRICW NPOUTLINETEXTMETRIC;
+ typedef LPOUTLINETEXTMETRICW LPOUTLINETEXTMETRIC;
+#else
+ typedef OUTLINETEXTMETRICA OUTLINETEXTMETRIC;
+ typedef POUTLINETEXTMETRICA POUTLINETEXTMETRIC;
+ typedef NPOUTLINETEXTMETRICA NPOUTLINETEXTMETRIC;
+ typedef LPOUTLINETEXTMETRICA LPOUTLINETEXTMETRIC;
+#endif
+#endif
+
+ typedef struct tagPOLYTEXTA {
+ int x;
+ int y;
+ UINT n;
+ LPCSTR lpstr;
+ UINT uiFlags;
+ RECT rcl;
+ int *pdx;
+ } POLYTEXTA,*PPOLYTEXTA,*NPPOLYTEXTA,*LPPOLYTEXTA;
+
+ typedef struct tagPOLYTEXTW {
+ int x;
+ int y;
+ UINT n;
+ LPCWSTR lpstr;
+ UINT uiFlags;
+ RECT rcl;
+ int *pdx;
+ } POLYTEXTW,*PPOLYTEXTW,*NPPOLYTEXTW,*LPPOLYTEXTW;
+#ifdef UNICODE
+ typedef POLYTEXTW POLYTEXT;
+ typedef PPOLYTEXTW PPOLYTEXT;
+ typedef NPPOLYTEXTW NPPOLYTEXT;
+ typedef LPPOLYTEXTW LPPOLYTEXT;
+#else
+ typedef POLYTEXTA POLYTEXT;
+ typedef PPOLYTEXTA PPOLYTEXT;
+ typedef NPPOLYTEXTA NPPOLYTEXT;
+ typedef LPPOLYTEXTA LPPOLYTEXT;
+#endif
+
+ typedef struct _FIXED {
+ WORD fract;
+ short value;
+ } FIXED;
+
+ typedef struct _MAT2 {
+ FIXED eM11;
+ FIXED eM12;
+ FIXED eM21;
+ FIXED eM22;
+ } MAT2,*LPMAT2;
+
+ typedef struct _GLYPHMETRICS {
+ UINT gmBlackBoxX;
+ UINT gmBlackBoxY;
+ POINT gmptGlyphOrigin;
+ short gmCellIncX;
+ short gmCellIncY;
+ } GLYPHMETRICS,*LPGLYPHMETRICS;
+
+#define GGO_METRICS 0
+#define GGO_BITMAP 1
+#define GGO_NATIVE 2
+#define GGO_BEZIER 3
+
+#define GGO_GRAY2_BITMAP 4
+#define GGO_GRAY4_BITMAP 5
+#define GGO_GRAY8_BITMAP 6
+#define GGO_GLYPH_INDEX 0x0080
+#define GGO_UNHINTED 0x0100
+
+#define TT_POLYGON_TYPE 24
+
+#define TT_PRIM_LINE 1
+#define TT_PRIM_QSPLINE 2
+#define TT_PRIM_CSPLINE 3
+
+ typedef struct tagPOINTFX {
+ FIXED x;
+ FIXED y;
+ } POINTFX,*LPPOINTFX;
+
+ typedef struct tagTTPOLYCURVE {
+ WORD wType;
+ WORD cpfx;
+ POINTFX apfx[1];
+ } TTPOLYCURVE,*LPTTPOLYCURVE;
+
+ typedef struct tagTTPOLYGONHEADER {
+ DWORD cb;
+ DWORD dwType;
+ POINTFX pfxStart;
+ } TTPOLYGONHEADER,*LPTTPOLYGONHEADER;
+
+#define GCP_DBCS 0x0001
+#define GCP_REORDER 0x0002
+#define GCP_USEKERNING 0x0008
+#define GCP_GLYPHSHAPE 0x0010
+#define GCP_LIGATE 0x0020
+
+#define GCP_DIACRITIC 0x0100
+#define GCP_KASHIDA 0x0400
+#define GCP_ERROR 0x8000
+#define FLI_MASK 0x103B
+
+#define GCP_JUSTIFY 0x00010000L
+
+#define FLI_GLYPHS 0x00040000L
+#define GCP_CLASSIN 0x00080000L
+#define GCP_MAXEXTENT 0x00100000L
+#define GCP_JUSTIFYIN 0x00200000L
+#define GCP_DISPLAYZWG 0x00400000L
+#define GCP_SYMSWAPOFF 0x00800000L
+#define GCP_NUMERICOVERRIDE 0x01000000L
+#define GCP_NEUTRALOVERRIDE 0x02000000L
+#define GCP_NUMERICSLATIN 0x04000000L
+#define GCP_NUMERICSLOCAL 0x08000000L
+
+#define GCPCLASS_LATIN 1
+#define GCPCLASS_HEBREW 2
+#define GCPCLASS_ARABIC 2
+#define GCPCLASS_NEUTRAL 3
+#define GCPCLASS_LOCALNUMBER 4
+#define GCPCLASS_LATINNUMBER 5
+#define GCPCLASS_LATINNUMERICTERMINATOR 6
+#define GCPCLASS_LATINNUMERICSEPARATOR 7
+#define GCPCLASS_NUMERICSEPARATOR 8
+#define GCPCLASS_PREBOUNDLTR 0x80
+#define GCPCLASS_PREBOUNDRTL 0x40
+#define GCPCLASS_POSTBOUNDLTR 0x20
+#define GCPCLASS_POSTBOUNDRTL 0x10
+
+#define GCPGLYPH_LINKBEFORE 0x8000
+#define GCPGLYPH_LINKAFTER 0x4000
+
+ typedef struct tagGCP_RESULTSA {
+ DWORD lStructSize;
+ LPSTR lpOutString;
+ UINT *lpOrder;
+ int *lpDx;
+ int *lpCaretPos;
+ LPSTR lpClass;
+ LPWSTR lpGlyphs;
+ UINT nGlyphs;
+ int nMaxFit;
+ } GCP_RESULTSA,*LPGCP_RESULTSA;
+ typedef struct tagGCP_RESULTSW {
+ DWORD lStructSize;
+ LPWSTR lpOutString;
+ UINT *lpOrder;
+ int *lpDx;
+ int *lpCaretPos;
+ LPSTR lpClass;
+ LPWSTR lpGlyphs;
+ UINT nGlyphs;
+ int nMaxFit;
+ } GCP_RESULTSW,*LPGCP_RESULTSW;
+#ifdef UNICODE
+ typedef GCP_RESULTSW GCP_RESULTS;
+ typedef LPGCP_RESULTSW LPGCP_RESULTS;
+#else
+ typedef GCP_RESULTSA GCP_RESULTS;
+ typedef LPGCP_RESULTSA LPGCP_RESULTS;
+#endif
+
+ typedef struct _RASTERIZER_STATUS {
+ short nSize;
+ short wFlags;
+ short nLanguageID;
+ } RASTERIZER_STATUS,*LPRASTERIZER_STATUS;
+
+#define TT_AVAILABLE 0x0001
+#define TT_ENABLED 0x0002
+
+ typedef struct tagPIXELFORMATDESCRIPTOR {
+ WORD nSize;
+ WORD nVersion;
+ DWORD dwFlags;
+ BYTE iPixelType;
+ BYTE cColorBits;
+ BYTE cRedBits;
+ BYTE cRedShift;
+ BYTE cGreenBits;
+ BYTE cGreenShift;
+ BYTE cBlueBits;
+ BYTE cBlueShift;
+ BYTE cAlphaBits;
+ BYTE cAlphaShift;
+ BYTE cAccumBits;
+ BYTE cAccumRedBits;
+ BYTE cAccumGreenBits;
+ BYTE cAccumBlueBits;
+ BYTE cAccumAlphaBits;
+ BYTE cDepthBits;
+ BYTE cStencilBits;
+ BYTE cAuxBuffers;
+ BYTE iLayerType;
+ BYTE bReserved;
+ DWORD dwLayerMask;
+ DWORD dwVisibleMask;
+ DWORD dwDamageMask;
+ } PIXELFORMATDESCRIPTOR,*PPIXELFORMATDESCRIPTOR,*LPPIXELFORMATDESCRIPTOR;
+
+#define PFD_TYPE_RGBA 0
+#define PFD_TYPE_COLORINDEX 1
+
+#define PFD_MAIN_PLANE 0
+#define PFD_OVERLAY_PLANE 1
+#define PFD_UNDERLAY_PLANE (-1)
+
+#define PFD_DOUBLEBUFFER 0x00000001
+#define PFD_STEREO 0x00000002
+#define PFD_DRAW_TO_WINDOW 0x00000004
+#define PFD_DRAW_TO_BITMAP 0x00000008
+#define PFD_SUPPORT_GDI 0x00000010
+#define PFD_SUPPORT_OPENGL 0x00000020
+#define PFD_GENERIC_FORMAT 0x00000040
+#define PFD_NEED_PALETTE 0x00000080
+#define PFD_NEED_SYSTEM_PALETTE 0x00000100
+#define PFD_SWAP_EXCHANGE 0x00000200
+#define PFD_SWAP_COPY 0x00000400
+#define PFD_SWAP_LAYER_BUFFERS 0x00000800
+#define PFD_GENERIC_ACCELERATED 0x00001000
+#define PFD_SUPPORT_DIRECTDRAW 0x00002000
+
+#define PFD_DEPTH_DONTCARE 0x20000000
+#define PFD_DOUBLEBUFFER_DONTCARE 0x40000000
+#define PFD_STEREO_DONTCARE 0x80000000
+
+#ifndef NOTEXTMETRIC
+ typedef int (CALLBACK *OLDFONTENUMPROCA)(CONST LOGFONTA *,CONST TEXTMETRICA *,DWORD,LPARAM);
+ typedef int (CALLBACK *OLDFONTENUMPROCW)(CONST LOGFONTW *,CONST TEXTMETRICW *,DWORD,LPARAM);
+#ifdef UNICODE
+#define OLDFONTENUMPROC OLDFONTENUMPROCW
+#else
+#define OLDFONTENUMPROC OLDFONTENUMPROCA
+#endif
+#else
+ typedef int (CALLBACK *OLDFONTENUMPROCA)(CONST LOGFONTA *,CONST VOID *,DWORD,LPARAM);
+ typedef int (CALLBACK *OLDFONTENUMPROCW)(CONST LOGFONTW *,CONST VOID *,DWORD,LPARAM);
+#ifdef UNICODE
+#define OLDFONTENUMPROC OLDFONTENUMPROCW
+#else
+#define OLDFONTENUMPROC OLDFONTENUMPROCA
+#endif
+#endif
+
+ typedef OLDFONTENUMPROCA FONTENUMPROCA;
+ typedef OLDFONTENUMPROCW FONTENUMPROCW;
+#ifdef UNICODE
+ typedef FONTENUMPROCW FONTENUMPROC;
+#else
+ typedef FONTENUMPROCA FONTENUMPROC;
+#endif
+
+ typedef int (CALLBACK *GOBJENUMPROC)(LPVOID,LPARAM);
+ typedef VOID (CALLBACK *LINEDDAPROC)(int,int,LPARAM);
+
+#ifdef UNICODE
+#define AddFontResource AddFontResourceW
+#define CopyMetaFile CopyMetaFileW
+#define CreateDC CreateDCW
+#define CreateFontIndirect CreateFontIndirectW
+#define CreateFont CreateFontW
+#define CreateIC CreateICW
+#define CreateMetaFile CreateMetaFileW
+#define CreateScalableFontResource CreateScalableFontResourceW
+#else
+#define AddFontResource AddFontResourceA
+#define CopyMetaFile CopyMetaFileA
+#define CreateDC CreateDCA
+#define CreateFontIndirect CreateFontIndirectA
+#define CreateFont CreateFontA
+#define CreateIC CreateICA
+#define CreateMetaFile CreateMetaFileA
+#define CreateScalableFontResource CreateScalableFontResourceA
+#endif
+
+ WINGDIAPI int WINAPI AddFontResourceA(LPCSTR);
+ WINGDIAPI int WINAPI AddFontResourceW(LPCWSTR);
+ WINGDIAPI WINBOOL WINAPI AnimatePalette(HPALETTE hPal,UINT iStartIndex,UINT cEntries,CONST PALETTEENTRY *ppe);
+ WINGDIAPI WINBOOL WINAPI Arc(HDC hdc,int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4);
+ WINGDIAPI WINBOOL WINAPI BitBlt(HDC hdc,int x,int y,int cx,int cy,HDC hdcSrc,int x1,int y1,DWORD rop);
+ WINGDIAPI WINBOOL WINAPI CancelDC(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI Chord(HDC hdc,int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4);
+ WINGDIAPI int WINAPI ChoosePixelFormat(HDC hdc,CONST PIXELFORMATDESCRIPTOR *ppfd);
+ WINGDIAPI HMETAFILE WINAPI CloseMetaFile(HDC hdc);
+ WINGDIAPI int WINAPI CombineRgn(HRGN hrgnDst,HRGN hrgnSrc1,HRGN hrgnSrc2,int iMode);
+ WINGDIAPI HMETAFILE WINAPI CopyMetaFileA(HMETAFILE,LPCSTR);
+ WINGDIAPI HMETAFILE WINAPI CopyMetaFileW(HMETAFILE,LPCWSTR);
+ WINGDIAPI HBITMAP WINAPI CreateBitmap(int nWidth,int nHeight,UINT nPlanes,UINT nBitCount,CONST VOID *lpBits);
+ WINGDIAPI HBITMAP WINAPI CreateBitmapIndirect(CONST BITMAP *pbm);
+ WINGDIAPI HBRUSH WINAPI CreateBrushIndirect(CONST LOGBRUSH *plbrush);
+ WINGDIAPI HBITMAP WINAPI CreateCompatibleBitmap(HDC hdc,int cx,int cy);
+ WINGDIAPI HBITMAP WINAPI CreateDiscardableBitmap(HDC hdc,int cx,int cy);
+ WINGDIAPI HDC WINAPI CreateCompatibleDC(HDC hdc);
+ WINGDIAPI HDC WINAPI CreateDCA(LPCSTR pwszDriver,LPCSTR pwszDevice,LPCSTR pszPort,CONST DEVMODEA *pdm);
+ WINGDIAPI HDC WINAPI CreateDCW(LPCWSTR pwszDriver,LPCWSTR pwszDevice,LPCWSTR pszPort,CONST DEVMODEW *pdm);
+ WINGDIAPI HBITMAP WINAPI CreateDIBitmap(HDC hdc,CONST BITMAPINFOHEADER *pbmih,DWORD flInit,CONST VOID *pjBits,CONST BITMAPINFO *pbmi,UINT iUsage);
+ WINGDIAPI HBRUSH WINAPI CreateDIBPatternBrush(HGLOBAL h,UINT iUsage);
+ WINGDIAPI HBRUSH WINAPI CreateDIBPatternBrushPt(CONST VOID *lpPackedDIB,UINT iUsage);
+ WINGDIAPI HRGN WINAPI CreateEllipticRgn(int x1,int y1,int x2,int y2);
+ WINGDIAPI HRGN WINAPI CreateEllipticRgnIndirect(CONST RECT *lprect);
+ WINGDIAPI HFONT WINAPI CreateFontIndirectA(CONST LOGFONTA *lplf);
+ WINGDIAPI HFONT WINAPI CreateFontIndirectW(CONST LOGFONTW *lplf);
+ WINGDIAPI HFONT WINAPI CreateFontA(int cHeight,int cWidth,int cEscapement,int cOrientation,int cWeight,DWORD bItalic,DWORD bUnderline,DWORD bStrikeOut,DWORD iCharSet,DWORD iOutPrecision,DWORD iClipPrecision,DWORD iQuality,DWORD iPitchAndFamily,LPCSTR pszFaceName);
+ WINGDIAPI HFONT WINAPI CreateFontW(int cHeight,int cWidth,int cEscapement,int cOrientation,int cWeight,DWORD bItalic,DWORD bUnderline,DWORD bStrikeOut,DWORD iCharSet,DWORD iOutPrecision,DWORD iClipPrecision,DWORD iQuality,DWORD iPitchAndFamily,LPCWSTR pszFaceName);
+ WINGDIAPI HBRUSH WINAPI CreateHatchBrush(int iHatch,COLORREF color);
+ WINGDIAPI HDC WINAPI CreateICA(LPCSTR pszDriver,LPCSTR pszDevice,LPCSTR pszPort,CONST DEVMODEA *pdm);
+ WINGDIAPI HDC WINAPI CreateICW(LPCWSTR pszDriver,LPCWSTR pszDevice,LPCWSTR pszPort,CONST DEVMODEW *pdm);
+ WINGDIAPI HDC WINAPI CreateMetaFileA(LPCSTR pszFile);
+ WINGDIAPI HDC WINAPI CreateMetaFileW(LPCWSTR pszFile);
+ WINGDIAPI HPALETTE WINAPI CreatePalette(CONST LOGPALETTE *plpal);
+ WINGDIAPI HPEN WINAPI CreatePen(int iStyle,int cWidth,COLORREF color);
+ WINGDIAPI HPEN WINAPI CreatePenIndirect(CONST LOGPEN *plpen);
+ WINGDIAPI HRGN WINAPI CreatePolyPolygonRgn(CONST POINT *pptl,CONST INT *pc,int cPoly,int iMode);
+ WINGDIAPI HBRUSH WINAPI CreatePatternBrush(HBITMAP hbm);
+ WINGDIAPI HRGN WINAPI CreateRectRgn(int x1,int y1,int x2,int y2);
+ WINGDIAPI HRGN WINAPI CreateRectRgnIndirect(CONST RECT *lprect);
+ WINGDIAPI HRGN WINAPI CreateRoundRectRgn(int x1,int y1,int x2,int y2,int w,int h);
+ WINGDIAPI WINBOOL WINAPI CreateScalableFontResourceA(DWORD fdwHidden,LPCSTR lpszFont,LPCSTR lpszFile,LPCSTR lpszPath);
+ WINGDIAPI WINBOOL WINAPI CreateScalableFontResourceW(DWORD fdwHidden,LPCWSTR lpszFont,LPCWSTR lpszFile,LPCWSTR lpszPath);
+ WINGDIAPI HBRUSH WINAPI CreateSolidBrush(COLORREF color);
+ WINGDIAPI WINBOOL WINAPI DeleteDC(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI DeleteMetaFile(HMETAFILE hmf);
+ WINGDIAPI WINBOOL WINAPI DeleteObject(HGDIOBJ ho);
+ WINGDIAPI int WINAPI DescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,LPPIXELFORMATDESCRIPTOR ppfd);
+
+ typedef UINT (CALLBACK *LPFNDEVMODE)(HWND,HMODULE,LPDEVMODE,LPSTR,LPSTR,LPDEVMODE,LPSTR,UINT);
+ typedef DWORD (CALLBACK *LPFNDEVCAPS)(LPSTR,LPSTR,UINT,LPSTR,LPDEVMODE);
+
+#define DM_UPDATE 1
+#define DM_COPY 2
+#define DM_PROMPT 4
+#define DM_MODIFY 8
+
+#define DM_IN_BUFFER DM_MODIFY
+#define DM_IN_PROMPT DM_PROMPT
+#define DM_OUT_BUFFER DM_COPY
+#define DM_OUT_DEFAULT DM_UPDATE
+
+#define DC_FIELDS 1
+#define DC_PAPERS 2
+#define DC_PAPERSIZE 3
+#define DC_MINEXTENT 4
+#define DC_MAXEXTENT 5
+#define DC_BINS 6
+#define DC_DUPLEX 7
+#define DC_SIZE 8
+#define DC_EXTRA 9
+#define DC_VERSION 10
+#define DC_DRIVER 11
+#define DC_BINNAMES 12
+#define DC_ENUMRESOLUTIONS 13
+#define DC_FILEDEPENDENCIES 14
+#define DC_TRUETYPE 15
+#define DC_PAPERNAMES 16
+#define DC_ORIENTATION 17
+#define DC_COPIES 18
+#define DC_BINADJUST 19
+#define DC_EMF_COMPLIANT 20
+#define DC_DATATYPE_PRODUCED 21
+#define DC_COLLATE 22
+#define DC_MANUFACTURER 23
+#define DC_MODEL 24
+#define DC_PERSONALITY 25
+#define DC_PRINTRATE 26
+#define DC_PRINTRATEUNIT 27
+#define PRINTRATEUNIT_PPM 1
+#define PRINTRATEUNIT_CPS 2
+#define PRINTRATEUNIT_LPM 3
+#define PRINTRATEUNIT_IPM 4
+#define DC_PRINTERMEM 28
+#define DC_MEDIAREADY 29
+#define DC_STAPLE 30
+#define DC_PRINTRATEPPM 31
+#define DC_COLORDEVICE 32
+#define DC_NUP 33
+#define DC_MEDIATYPENAMES 34
+#define DC_MEDIATYPES 35
+
+#define DCTT_BITMAP 0x0000001L
+#define DCTT_DOWNLOAD 0x0000002L
+#define DCTT_SUBDEV 0x0000004L
+#define DCTT_DOWNLOAD_OUTLINE 0x0000008L
+
+#define DCBA_FACEUPNONE 0x0000
+#define DCBA_FACEUPCENTER 0x0001
+#define DCBA_FACEUPLEFT 0x0002
+#define DCBA_FACEUPRIGHT 0x0003
+#define DCBA_FACEDOWNNONE 0x0100
+#define DCBA_FACEDOWNCENTER 0x0101
+#define DCBA_FACEDOWNLEFT 0x0102
+#define DCBA_FACEDOWNRIGHT 0x0103
+
+#ifdef UNICODE
+#define DeviceCapabilities DeviceCapabilitiesW
+#define EnumFontFamiliesEx EnumFontFamiliesExW
+#define EnumFontFamilies EnumFontFamiliesW
+#define EnumFonts EnumFontsW
+#define GetCharWidth GetCharWidthW
+#define GetCharWidth32 GetCharWidth32W
+#define GetCharWidthFloat GetCharWidthFloatW
+#define GetCharABCWidths GetCharABCWidthsW
+#define GetCharABCWidthsFloat GetCharABCWidthsFloatW
+#define GetGlyphOutline GetGlyphOutlineW
+#define GetMetaFile GetMetaFileW
+#else
+#define DeviceCapabilities DeviceCapabilitiesA
+#define EnumFontFamiliesEx EnumFontFamiliesExA
+#define EnumFontFamilies EnumFontFamiliesA
+#define EnumFonts EnumFontsA
+#define GetCharWidth GetCharWidthA
+#define GetCharWidth32 GetCharWidth32A
+#define GetCharWidthFloat GetCharWidthFloatA
+#define GetCharABCWidths GetCharABCWidthsA
+#define GetCharABCWidthsFloat GetCharABCWidthsFloatA
+#define GetGlyphOutline GetGlyphOutlineA
+#define GetMetaFile GetMetaFileA
+#endif
+
+ WINSPOOLAPI int WINAPI DeviceCapabilitiesA(LPCSTR pDevice,LPCSTR pPort,WORD fwCapability,LPSTR pOutput,CONST DEVMODEA *pDevMode);
+ WINSPOOLAPI int WINAPI DeviceCapabilitiesW(LPCWSTR pDevice,LPCWSTR pPort,WORD fwCapability,LPWSTR pOutput,CONST DEVMODEW *pDevMode);
+ WINGDIAPI int WINAPI DrawEscape(HDC hdc,int iEscape,int cjIn,LPCSTR lpIn);
+ WINGDIAPI WINBOOL WINAPI Ellipse(HDC hdc,int left,int top,int right,int bottom);
+ WINGDIAPI int WINAPI EnumFontFamiliesExA(HDC hdc,LPLOGFONTA lpLogfont,FONTENUMPROCA lpProc,LPARAM lParam,DWORD dwFlags);
+ WINGDIAPI int WINAPI EnumFontFamiliesExW(HDC hdc,LPLOGFONTW lpLogfont,FONTENUMPROCW lpProc,LPARAM lParam,DWORD dwFlags);
+ WINGDIAPI int WINAPI EnumFontFamiliesA(HDC hdc,LPCSTR lpLogfont,FONTENUMPROCA lpProc,LPARAM lParam);
+ WINGDIAPI int WINAPI EnumFontFamiliesW(HDC hdc,LPCWSTR lpLogfont,FONTENUMPROCW lpProc,LPARAM lParam);
+ WINGDIAPI int WINAPI EnumFontsA(HDC hdc,LPCSTR lpLogfont,FONTENUMPROCA lpProc,LPARAM lParam);
+ WINGDIAPI int WINAPI EnumFontsW(HDC hdc,LPCWSTR lpLogfont,FONTENUMPROCW lpProc,LPARAM lParam);
+ WINGDIAPI int WINAPI EnumObjects(HDC hdc,int nType,GOBJENUMPROC lpFunc,LPARAM lParam);
+ WINGDIAPI WINBOOL WINAPI EqualRgn(HRGN hrgn1,HRGN hrgn2);
+ WINGDIAPI int WINAPI Escape(HDC hdc,int iEscape,int cjIn,LPCSTR pvIn,LPVOID pvOut);
+ WINGDIAPI int WINAPI ExtEscape(HDC hdc,int iEscape,int cjInput,LPCSTR lpInData,int cjOutput,LPSTR lpOutData);
+ WINGDIAPI int WINAPI ExcludeClipRect(HDC hdc,int left,int top,int right,int bottom);
+ WINGDIAPI HRGN WINAPI ExtCreateRegion(CONST XFORM *lpx,DWORD nCount,CONST RGNDATA *lpData);
+ WINGDIAPI WINBOOL WINAPI ExtFloodFill(HDC hdc,int x,int y,COLORREF color,UINT type);
+ WINGDIAPI WINBOOL WINAPI FillRgn(HDC hdc,HRGN hrgn,HBRUSH hbr);
+ WINGDIAPI WINBOOL WINAPI FloodFill(HDC hdc,int x,int y,COLORREF color);
+ WINGDIAPI WINBOOL WINAPI FrameRgn(HDC hdc,HRGN hrgn,HBRUSH hbr,int w,int h);
+ WINGDIAPI int WINAPI GetROP2(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI GetAspectRatioFilterEx(HDC hdc,LPSIZE lpsize);
+ WINGDIAPI COLORREF WINAPI GetBkColor(HDC hdc);
+ WINGDIAPI COLORREF WINAPI GetDCBrushColor(HDC hdc);
+ WINGDIAPI COLORREF WINAPI GetDCPenColor(HDC hdc);
+ WINGDIAPI int WINAPI GetBkMode(HDC hdc);
+ WINGDIAPI LONG WINAPI GetBitmapBits(HBITMAP hbit,LONG cb,LPVOID lpvBits);
+ WINGDIAPI WINBOOL WINAPI GetBitmapDimensionEx(HBITMAP hbit,LPSIZE lpsize);
+ WINGDIAPI UINT WINAPI GetBoundsRect(HDC hdc,LPRECT lprect,UINT flags);
+ WINGDIAPI WINBOOL WINAPI GetBrushOrgEx(HDC hdc,LPPOINT lppt);
+ WINGDIAPI WINBOOL WINAPI GetCharWidthA(HDC hdc,UINT iFirst,UINT iLast,LPINT lpBuffer);
+ WINGDIAPI WINBOOL WINAPI GetCharWidthW(HDC hdc,UINT iFirst,UINT iLast,LPINT lpBuffer);
+ WINGDIAPI WINBOOL WINAPI GetCharWidth32A(HDC hdc,UINT iFirst,UINT iLast,LPINT lpBuffer);
+ WINGDIAPI WINBOOL WINAPI GetCharWidth32W(HDC hdc,UINT iFirst,UINT iLast,LPINT lpBuffer);
+ WINGDIAPI WINBOOL WINAPI GetCharWidthFloatA(HDC hdc,UINT iFirst,UINT iLast,PFLOAT lpBuffer);
+ WINGDIAPI WINBOOL WINAPI GetCharWidthFloatW(HDC hdc,UINT iFirst,UINT iLast,PFLOAT lpBuffer);
+ WINGDIAPI WINBOOL WINAPI GetCharABCWidthsA(HDC hdc,UINT wFirst,UINT wLast,LPABC lpABC);
+ WINGDIAPI WINBOOL WINAPI GetCharABCWidthsW(HDC hdc,UINT wFirst,UINT wLast,LPABC lpABC);
+ WINGDIAPI WINBOOL WINAPI GetCharABCWidthsFloatA(HDC hdc,UINT iFirst,UINT iLast,LPABCFLOAT lpABC);
+ WINGDIAPI WINBOOL WINAPI GetCharABCWidthsFloatW(HDC hdc,UINT iFirst,UINT iLast,LPABCFLOAT lpABC);
+ WINGDIAPI int WINAPI GetClipBox(HDC hdc,LPRECT lprect);
+ WINGDIAPI int WINAPI GetClipRgn(HDC hdc,HRGN hrgn);
+ WINGDIAPI int WINAPI GetMetaRgn(HDC hdc,HRGN hrgn);
+ WINGDIAPI HGDIOBJ WINAPI GetCurrentObject(HDC hdc,UINT type);
+ WINGDIAPI WINBOOL WINAPI GetCurrentPositionEx(HDC hdc,LPPOINT lppt);
+ WINGDIAPI int WINAPI GetDeviceCaps(HDC hdc,int index);
+ WINGDIAPI int WINAPI GetDIBits(HDC hdc,HBITMAP hbm,UINT start,UINT cLines,LPVOID lpvBits,LPBITMAPINFO lpbmi,UINT usage);
+ WINGDIAPI DWORD WINAPI GetFontData (HDC hdc,DWORD dwTable,DWORD dwOffset,PVOID pvBuffer,DWORD cjBuffer);
+ WINGDIAPI DWORD WINAPI GetGlyphOutlineA(HDC hdc,UINT uChar,UINT fuFormat,LPGLYPHMETRICS lpgm,DWORD cjBuffer,LPVOID pvBuffer,CONST MAT2 *lpmat2);
+ WINGDIAPI DWORD WINAPI GetGlyphOutlineW(HDC hdc,UINT uChar,UINT fuFormat,LPGLYPHMETRICS lpgm,DWORD cjBuffer,LPVOID pvBuffer,CONST MAT2 *lpmat2);
+ WINGDIAPI int WINAPI GetGraphicsMode(HDC hdc);
+ WINGDIAPI int WINAPI GetMapMode(HDC hdc);
+ WINGDIAPI UINT WINAPI GetMetaFileBitsEx(HMETAFILE hMF,UINT cbBuffer,LPVOID lpData);
+ WINGDIAPI HMETAFILE WINAPI GetMetaFileA(LPCSTR lpName);
+ WINGDIAPI HMETAFILE WINAPI GetMetaFileW(LPCWSTR lpName);
+ WINGDIAPI COLORREF WINAPI GetNearestColor(HDC hdc,COLORREF color);
+ WINGDIAPI UINT WINAPI GetNearestPaletteIndex(HPALETTE h,COLORREF color);
+ WINGDIAPI DWORD WINAPI GetObjectType(HGDIOBJ h);
+
+#ifndef NOTEXTMETRIC
+#ifdef UNICODE
+#define GetOutlineTextMetrics GetOutlineTextMetricsW
+#else
+#define GetOutlineTextMetrics GetOutlineTextMetricsA
+#endif
+
+ WINGDIAPI UINT WINAPI GetOutlineTextMetricsA(HDC hdc,UINT cjCopy,LPOUTLINETEXTMETRICA potm);
+ WINGDIAPI UINT WINAPI GetOutlineTextMetricsW(HDC hdc,UINT cjCopy,LPOUTLINETEXTMETRICW potm);
+#endif
+
+#ifdef UNICODE
+#define GetTextExtentPoint GetTextExtentPointW
+#define GetTextExtentPoint32 GetTextExtentPoint32W
+#define GetTextExtentExPoint GetTextExtentExPointW
+#define GetCharacterPlacement GetCharacterPlacementW
+#else
+#define GetTextExtentPoint GetTextExtentPointA
+#define GetTextExtentPoint32 GetTextExtentPoint32A
+#define GetTextExtentExPoint GetTextExtentExPointA
+#define GetCharacterPlacement GetCharacterPlacementA
+#endif
+
+ WINGDIAPI UINT WINAPI GetPaletteEntries(HPALETTE hpal,UINT iStart,UINT cEntries,LPPALETTEENTRY pPalEntries);
+ WINGDIAPI COLORREF WINAPI GetPixel(HDC hdc,int x,int y);
+ WINGDIAPI int WINAPI GetPixelFormat(HDC hdc);
+ WINGDIAPI int WINAPI GetPolyFillMode(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI GetRasterizerCaps(LPRASTERIZER_STATUS lpraststat,UINT cjBytes);
+ WINGDIAPI int WINAPI GetRandomRgn (HDC hdc,HRGN hrgn,INT i);
+ WINGDIAPI DWORD WINAPI GetRegionData(HRGN hrgn,DWORD nCount,LPRGNDATA lpRgnData);
+ WINGDIAPI int WINAPI GetRgnBox(HRGN hrgn,LPRECT lprc);
+ WINGDIAPI HGDIOBJ WINAPI GetStockObject(int i);
+ WINGDIAPI int WINAPI GetStretchBltMode(HDC hdc);
+ WINGDIAPI UINT WINAPI GetSystemPaletteEntries(HDC hdc,UINT iStart,UINT cEntries,LPPALETTEENTRY pPalEntries);
+ WINGDIAPI UINT WINAPI GetSystemPaletteUse(HDC hdc);
+ WINGDIAPI int WINAPI GetTextCharacterExtra(HDC hdc);
+ WINGDIAPI UINT WINAPI GetTextAlign(HDC hdc);
+ WINGDIAPI COLORREF WINAPI GetTextColor(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI GetTextExtentPointA(HDC hdc,LPCSTR lpString,int c,LPSIZE lpsz);
+ WINGDIAPI WINBOOL WINAPI GetTextExtentPointW(HDC hdc,LPCWSTR lpString,int c,LPSIZE lpsz);
+ WINGDIAPI WINBOOL WINAPI GetTextExtentPoint32A(HDC hdc,LPCSTR lpString,int c,LPSIZE psizl);
+ WINGDIAPI WINBOOL WINAPI GetTextExtentPoint32W(HDC hdc,LPCWSTR lpString,int c,LPSIZE psizl);
+ WINGDIAPI WINBOOL WINAPI GetTextExtentExPointA(HDC hdc,LPCSTR lpszString,int cchString,int nMaxExtent,LPINT lpnFit,LPINT lpnDx,LPSIZE lpSize);
+ WINGDIAPI WINBOOL WINAPI GetTextExtentExPointW(HDC hdc,LPCWSTR lpszString,int cchString,int nMaxExtent,LPINT lpnFit,LPINT lpnDx,LPSIZE lpSize);
+ WINGDIAPI int WINAPI GetTextCharset(HDC hdc);
+ WINGDIAPI int WINAPI GetTextCharsetInfo(HDC hdc,LPFONTSIGNATURE lpSig,DWORD dwFlags);
+ WINGDIAPI WINBOOL WINAPI TranslateCharsetInfo(DWORD *lpSrc,LPCHARSETINFO lpCs,DWORD dwFlags);
+ WINGDIAPI DWORD WINAPI GetFontLanguageInfo(HDC hdc);
+ WINGDIAPI DWORD WINAPI GetCharacterPlacementA(HDC hdc,LPCSTR lpString,int nCount,int nMexExtent,LPGCP_RESULTSA lpResults,DWORD dwFlags);
+ WINGDIAPI DWORD WINAPI GetCharacterPlacementW(HDC hdc,LPCWSTR lpString,int nCount,int nMexExtent,LPGCP_RESULTSW lpResults,DWORD dwFlags);
+
+ typedef struct tagWCRANGE {
+ WCHAR wcLow;
+ USHORT cGlyphs;
+ } WCRANGE,*PWCRANGE,*LPWCRANGE;
+
+ typedef struct tagGLYPHSET {
+ DWORD cbThis;
+ DWORD flAccel;
+ DWORD cGlyphsSupported;
+ DWORD cRanges;
+ WCRANGE ranges[1];
+ } GLYPHSET,*PGLYPHSET,*LPGLYPHSET;
+
+#define GS_8BIT_INDICES 0x00000001
+
+#define GGI_MARK_NONEXISTING_GLYPHS 0X0001
+
+#ifdef UNICODE
+#define GetGlyphIndices GetGlyphIndicesW
+#else
+#define GetGlyphIndices GetGlyphIndicesA
+#endif
+
+ WINGDIAPI DWORD WINAPI GetFontUnicodeRanges(HDC hdc,LPGLYPHSET lpgs);
+ WINGDIAPI DWORD WINAPI GetGlyphIndicesA(HDC hdc,LPCSTR lpstr,int c,LPWORD pgi,DWORD fl);
+ WINGDIAPI DWORD WINAPI GetGlyphIndicesW(HDC hdc,LPCWSTR lpstr,int c,LPWORD pgi,DWORD fl);
+ WINGDIAPI WINBOOL WINAPI GetTextExtentPointI(HDC hdc,LPWORD pgiIn,int cgi,LPSIZE psize);
+ WINGDIAPI WINBOOL WINAPI GetTextExtentExPointI (HDC hdc,LPWORD lpwszString,int cwchString,int nMaxExtent,LPINT lpnFit,LPINT lpnDx,LPSIZE lpSize);
+ WINGDIAPI WINBOOL WINAPI GetCharWidthI(HDC hdc,UINT giFirst,UINT cgi,LPWORD pgi,LPINT piWidths);
+ WINGDIAPI WINBOOL WINAPI GetCharABCWidthsI(HDC hdc,UINT giFirst,UINT cgi,LPWORD pgi,LPABC pabc);
+
+#define STAMP_DESIGNVECTOR (0x8000000 + 'd' + ('v' << 8))
+#define STAMP_AXESLIST (0x8000000 + 'a' + ('l' << 8))
+#define MM_MAX_NUMAXES 16
+
+ typedef struct tagDESIGNVECTOR {
+ DWORD dvReserved;
+ DWORD dvNumAxes;
+ LONG dvValues[MM_MAX_NUMAXES];
+ } DESIGNVECTOR,*PDESIGNVECTOR,*LPDESIGNVECTOR;
+
+#ifdef UNICODE
+#define AddFontResourceEx AddFontResourceExW
+#define RemoveFontResourceEx RemoveFontResourceExW
+#else
+#define AddFontResourceEx AddFontResourceExA
+#define RemoveFontResourceEx RemoveFontResourceExA
+#endif
+
+ WINGDIAPI int WINAPI AddFontResourceExA(LPCSTR name,DWORD fl,PVOID res);
+ WINGDIAPI int WINAPI AddFontResourceExW(LPCWSTR name,DWORD fl,PVOID res);
+ WINGDIAPI WINBOOL WINAPI RemoveFontResourceExA(LPCSTR name,DWORD fl,PVOID pdv);
+ WINGDIAPI WINBOOL WINAPI RemoveFontResourceExW(LPCWSTR name,DWORD fl,PVOID pdv);
+ WINGDIAPI HANDLE WINAPI AddFontMemResourceEx(PVOID pFileView,DWORD cjSize,PVOID pvResrved,DWORD *pNumFonts);
+ WINGDIAPI WINBOOL WINAPI RemoveFontMemResourceEx(HANDLE h);
+
+#define FR_PRIVATE 0x10
+#define FR_NOT_ENUM 0x20
+
+#define MM_MAX_AXES_NAMELEN 16
+
+ typedef struct tagAXISINFOA {
+ LONG axMinValue;
+ LONG axMaxValue;
+ BYTE axAxisName[MM_MAX_AXES_NAMELEN];
+ } AXISINFOA,*PAXISINFOA,*LPAXISINFOA;
+
+ typedef struct tagAXISINFOW {
+ LONG axMinValue;
+ LONG axMaxValue;
+ WCHAR axAxisName[MM_MAX_AXES_NAMELEN];
+ } AXISINFOW,*PAXISINFOW,*LPAXISINFOW;
+#ifdef UNICODE
+ typedef AXISINFOW AXISINFO;
+ typedef PAXISINFOW PAXISINFO;
+ typedef LPAXISINFOW LPAXISINFO;
+#else
+ typedef AXISINFOA AXISINFO;
+ typedef PAXISINFOA PAXISINFO;
+ typedef LPAXISINFOA LPAXISINFO;
+#endif
+
+ typedef struct tagAXESLISTA {
+ DWORD axlReserved;
+ DWORD axlNumAxes;
+ AXISINFOA axlAxisInfo[MM_MAX_NUMAXES];
+ } AXESLISTA,*PAXESLISTA,*LPAXESLISTA;
+
+ typedef struct tagAXESLISTW {
+ DWORD axlReserved;
+ DWORD axlNumAxes;
+ AXISINFOW axlAxisInfo[MM_MAX_NUMAXES];
+ } AXESLISTW,*PAXESLISTW,*LPAXESLISTW;
+#ifdef UNICODE
+ typedef AXESLISTW AXESLIST;
+ typedef PAXESLISTW PAXESLIST;
+ typedef LPAXESLISTW LPAXESLIST;
+#else
+ typedef AXESLISTA AXESLIST;
+ typedef PAXESLISTA PAXESLIST;
+ typedef LPAXESLISTA LPAXESLIST;
+#endif
+
+ typedef struct tagENUMLOGFONTEXDVA {
+ ENUMLOGFONTEXA elfEnumLogfontEx;
+ DESIGNVECTOR elfDesignVector;
+ } ENUMLOGFONTEXDVA,*PENUMLOGFONTEXDVA,*LPENUMLOGFONTEXDVA;
+
+ typedef struct tagENUMLOGFONTEXDVW {
+ ENUMLOGFONTEXW elfEnumLogfontEx;
+ DESIGNVECTOR elfDesignVector;
+ } ENUMLOGFONTEXDVW,*PENUMLOGFONTEXDVW,*LPENUMLOGFONTEXDVW;
+#ifdef UNICODE
+ typedef ENUMLOGFONTEXDVW ENUMLOGFONTEXDV;
+ typedef PENUMLOGFONTEXDVW PENUMLOGFONTEXDV;
+ typedef LPENUMLOGFONTEXDVW LPENUMLOGFONTEXDV;
+#else
+ typedef ENUMLOGFONTEXDVA ENUMLOGFONTEXDV;
+ typedef PENUMLOGFONTEXDVA PENUMLOGFONTEXDV;
+ typedef LPENUMLOGFONTEXDVA LPENUMLOGFONTEXDV;
+#endif
+
+#ifdef UNICODE
+#define CreateFontIndirectEx CreateFontIndirectExW
+#else
+#define CreateFontIndirectEx CreateFontIndirectExA
+#endif
+
+ WINGDIAPI HFONT WINAPI CreateFontIndirectExA(CONST ENUMLOGFONTEXDVA *);
+ WINGDIAPI HFONT WINAPI CreateFontIndirectExW(CONST ENUMLOGFONTEXDVW *);
+
+#ifndef NOTEXTMETRIC
+ typedef struct tagENUMTEXTMETRICA {
+ NEWTEXTMETRICEXA etmNewTextMetricEx;
+ AXESLISTA etmAxesList;
+ } ENUMTEXTMETRICA,*PENUMTEXTMETRICA,*LPENUMTEXTMETRICA;
+ typedef struct tagENUMTEXTMETRICW
+ {
+ NEWTEXTMETRICEXW etmNewTextMetricEx;
+ AXESLISTW etmAxesList;
+ } ENUMTEXTMETRICW,*PENUMTEXTMETRICW,*LPENUMTEXTMETRICW;
+#ifdef UNICODE
+ typedef ENUMTEXTMETRICW ENUMTEXTMETRIC;
+ typedef PENUMTEXTMETRICW PENUMTEXTMETRIC;
+ typedef LPENUMTEXTMETRICW LPENUMTEXTMETRIC;
+#else
+ typedef ENUMTEXTMETRICA ENUMTEXTMETRIC;
+ typedef PENUMTEXTMETRICA PENUMTEXTMETRIC;
+ typedef LPENUMTEXTMETRICA LPENUMTEXTMETRIC;
+#endif
+#endif
+
+#ifdef UNICODE
+#define ResetDC ResetDCW
+#define RemoveFontResource RemoveFontResourceW
+#else
+#define ResetDC ResetDCA
+#define RemoveFontResource RemoveFontResourceA
+#endif
+
+ WINGDIAPI WINBOOL WINAPI GetViewportExtEx(HDC hdc,LPSIZE lpsize);
+ WINGDIAPI WINBOOL WINAPI GetViewportOrgEx(HDC hdc,LPPOINT lppoint);
+ WINGDIAPI WINBOOL WINAPI GetWindowExtEx(HDC hdc,LPSIZE lpsize);
+ WINGDIAPI WINBOOL WINAPI GetWindowOrgEx(HDC hdc,LPPOINT lppoint);
+ WINGDIAPI int WINAPI IntersectClipRect(HDC hdc,int left,int top,int right,int bottom);
+ WINGDIAPI WINBOOL WINAPI InvertRgn(HDC hdc,HRGN hrgn);
+ WINGDIAPI WINBOOL WINAPI LineDDA(int xStart,int yStart,int xEnd,int yEnd,LINEDDAPROC lpProc,LPARAM data);
+ WINGDIAPI WINBOOL WINAPI LineTo(HDC hdc,int x,int y);
+ WINGDIAPI WINBOOL WINAPI MaskBlt(HDC hdcDest,int xDest,int yDest,int width,int height,HDC hdcSrc,int xSrc,int ySrc,HBITMAP hbmMask,int xMask,int yMask,DWORD rop);
+ WINGDIAPI WINBOOL WINAPI PlgBlt(HDC hdcDest,CONST POINT *lpPoint,HDC hdcSrc,int xSrc,int ySrc,int width,int height,HBITMAP hbmMask,int xMask,int yMask);
+ WINGDIAPI int WINAPI OffsetClipRgn(HDC hdc,int x,int y);
+ WINGDIAPI int WINAPI OffsetRgn(HRGN hrgn,int x,int y);
+ WINGDIAPI WINBOOL WINAPI PatBlt(HDC hdc,int x,int y,int w,int h,DWORD rop);
+ WINGDIAPI WINBOOL WINAPI Pie(HDC hdc,int left,int top,int right,int bottom,int xr1,int yr1,int xr2,int yr2);
+ WINGDIAPI WINBOOL WINAPI PlayMetaFile(HDC hdc,HMETAFILE hmf);
+ WINGDIAPI WINBOOL WINAPI PaintRgn(HDC hdc,HRGN hrgn);
+ WINGDIAPI WINBOOL WINAPI PolyPolygon(HDC hdc,CONST POINT *apt,CONST INT *asz,int csz);
+ WINGDIAPI WINBOOL WINAPI PtInRegion(HRGN hrgn,int x,int y);
+ WINGDIAPI WINBOOL WINAPI PtVisible(HDC hdc,int x,int y);
+ WINGDIAPI WINBOOL WINAPI RectInRegion(HRGN hrgn,CONST RECT *lprect);
+ WINGDIAPI WINBOOL WINAPI RectVisible(HDC hdc,CONST RECT *lprect);
+ WINGDIAPI WINBOOL WINAPI Rectangle(HDC hdc,int left,int top,int right,int bottom);
+ WINGDIAPI WINBOOL WINAPI RestoreDC(HDC hdc,int nSavedDC);
+ WINGDIAPI HDC WINAPI ResetDCA(HDC hdc,CONST DEVMODEA *lpdm);
+ WINGDIAPI HDC WINAPI ResetDCW(HDC hdc,CONST DEVMODEW *lpdm);
+ WINGDIAPI UINT WINAPI RealizePalette(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI RemoveFontResourceA(LPCSTR lpFileName);
+ WINGDIAPI WINBOOL WINAPI RemoveFontResourceW(LPCWSTR lpFileName);
+ WINGDIAPI WINBOOL WINAPI RoundRect(HDC hdc,int left,int top,int right,int bottom,int width,int height);
+ WINGDIAPI WINBOOL WINAPI ResizePalette(HPALETTE hpal,UINT n);
+ WINGDIAPI int WINAPI SaveDC(HDC hdc);
+ WINGDIAPI int WINAPI SelectClipRgn(HDC hdc,HRGN hrgn);
+ WINGDIAPI int WINAPI ExtSelectClipRgn(HDC hdc,HRGN hrgn,int mode);
+ WINGDIAPI int WINAPI SetMetaRgn(HDC hdc);
+ WINGDIAPI HGDIOBJ WINAPI SelectObject(HDC hdc,HGDIOBJ h);
+ WINGDIAPI HPALETTE WINAPI SelectPalette(HDC hdc,HPALETTE hPal,WINBOOL bForceBkgd);
+ WINGDIAPI COLORREF WINAPI SetBkColor(HDC hdc,COLORREF color);
+ WINGDIAPI COLORREF WINAPI SetDCBrushColor(HDC hdc,COLORREF color);
+ WINGDIAPI COLORREF WINAPI SetDCPenColor(HDC hdc,COLORREF color);
+ WINGDIAPI int WINAPI SetBkMode(HDC hdc,int mode);
+ WINGDIAPI LONG WINAPI SetBitmapBits(HBITMAP hbm,DWORD cb,CONST VOID *pvBits);
+ WINGDIAPI UINT WINAPI SetBoundsRect(HDC hdc,CONST RECT *lprect,UINT flags);
+ WINGDIAPI int WINAPI SetDIBits(HDC hdc,HBITMAP hbm,UINT start,UINT cLines,CONST VOID *lpBits,CONST BITMAPINFO *lpbmi,UINT ColorUse);
+ WINGDIAPI int WINAPI SetDIBitsToDevice(HDC hdc,int xDest,int yDest,DWORD w,DWORD h,int xSrc,int ySrc,UINT StartScan,UINT cLines,CONST VOID *lpvBits,CONST BITMAPINFO *lpbmi,UINT ColorUse);
+ WINGDIAPI DWORD WINAPI SetMapperFlags(HDC hdc,DWORD flags);
+ WINGDIAPI int WINAPI SetGraphicsMode(HDC hdc,int iMode);
+ WINGDIAPI int WINAPI SetMapMode(HDC hdc,int iMode);
+ WINGDIAPI DWORD WINAPI SetLayout(HDC hdc,DWORD l);
+ WINGDIAPI DWORD WINAPI GetLayout(HDC hdc);
+ WINGDIAPI HMETAFILE WINAPI SetMetaFileBitsEx(UINT cbBuffer,CONST BYTE *lpData);
+ WINGDIAPI UINT WINAPI SetPaletteEntries(HPALETTE hpal,UINT iStart,UINT cEntries,CONST PALETTEENTRY *pPalEntries);
+ WINGDIAPI COLORREF WINAPI SetPixel(HDC hdc,int x,int y,COLORREF color);
+ WINGDIAPI WINBOOL WINAPI SetPixelV(HDC hdc,int x,int y,COLORREF color);
+ WINGDIAPI WINBOOL WINAPI SetPixelFormat(HDC hdc,int format,CONST PIXELFORMATDESCRIPTOR *ppfd);
+ WINGDIAPI int WINAPI SetPolyFillMode(HDC hdc,int mode);
+ WINGDIAPI WINBOOL WINAPI StretchBlt(HDC hdcDest,int xDest,int yDest,int wDest,int hDest,HDC hdcSrc,int xSrc,int ySrc,int wSrc,int hSrc,DWORD rop);
+ WINGDIAPI WINBOOL WINAPI SetRectRgn(HRGN hrgn,int left,int top,int right,int bottom);
+ WINGDIAPI int WINAPI StretchDIBits(HDC hdc,int xDest,int yDest,int DestWidth,int DestHeight,int xSrc,int ySrc,int SrcWidth,int SrcHeight,CONST VOID *lpBits,CONST BITMAPINFO *lpbmi,UINT iUsage,DWORD rop);
+ WINGDIAPI int WINAPI SetROP2(HDC hdc,int rop2);
+ WINGDIAPI int WINAPI SetStretchBltMode(HDC hdc,int mode);
+ WINGDIAPI UINT WINAPI SetSystemPaletteUse(HDC hdc,UINT use);
+ WINGDIAPI int WINAPI SetTextCharacterExtra(HDC hdc,int extra);
+ WINGDIAPI COLORREF WINAPI SetTextColor(HDC hdc,COLORREF color);
+ WINGDIAPI UINT WINAPI SetTextAlign(HDC hdc,UINT align);
+ WINGDIAPI WINBOOL WINAPI SetTextJustification(HDC hdc,int extra,int count);
+ WINGDIAPI WINBOOL WINAPI UpdateColors(HDC hdc);
+
+ typedef USHORT COLOR16;
+
+ typedef struct _TRIVERTEX {
+ LONG x;
+ LONG y;
+ COLOR16 Red;
+ COLOR16 Green;
+ COLOR16 Blue;
+ COLOR16 Alpha;
+ } TRIVERTEX,*PTRIVERTEX,*LPTRIVERTEX;
+
+ typedef struct _GRADIENT_TRIANGLE {
+ ULONG Vertex1;
+ ULONG Vertex2;
+ ULONG Vertex3;
+ } GRADIENT_TRIANGLE,*PGRADIENT_TRIANGLE,*LPGRADIENT_TRIANGLE;
+
+ typedef struct _GRADIENT_RECT {
+ ULONG UpperLeft;
+ ULONG LowerRight;
+ } GRADIENT_RECT,*PGRADIENT_RECT,*LPGRADIENT_RECT;
+
+ typedef struct _BLENDFUNCTION {
+ BYTE BlendOp;
+ BYTE BlendFlags;
+ BYTE SourceConstantAlpha;
+ BYTE AlphaFormat;
+ } BLENDFUNCTION,*PBLENDFUNCTION;
+
+#define AC_SRC_OVER 0x00
+#define AC_SRC_ALPHA 0x01
+
+ WINGDIAPI WINBOOL WINAPI AlphaBlend(HDC hdcDest,int xoriginDest,int yoriginDest,int wDest,int hDest,HDC hdcSrc,int xoriginSrc,int yoriginSrc,int wSrc,int hSrc,BLENDFUNCTION ftn);
+ WINGDIAPI WINBOOL WINAPI TransparentBlt(HDC hdcDest,int xoriginDest,int yoriginDest,int wDest,int hDest,HDC hdcSrc,int xoriginSrc,int yoriginSrc,int wSrc,int hSrc,UINT crTransparent);
+
+#define GRADIENT_FILL_RECT_H 0x00000000
+#define GRADIENT_FILL_RECT_V 0x00000001
+#define GRADIENT_FILL_TRIANGLE 0x00000002
+#define GRADIENT_FILL_OP_FLAG 0x000000ff
+
+ WINGDIAPI WINBOOL WINAPI GradientFill(HDC hdc,PTRIVERTEX pVertex,ULONG nVertex,PVOID pMesh,ULONG nMesh,ULONG ulMode);
+
+#ifndef NOMETAFILE
+
+#ifdef UNICODE
+#define CopyEnhMetaFile CopyEnhMetaFileW
+#define CreateEnhMetaFile CreateEnhMetaFileW
+#define GetEnhMetaFile GetEnhMetaFileW
+#define GetEnhMetaFileDescription GetEnhMetaFileDescriptionW
+#else
+#define CopyEnhMetaFile CopyEnhMetaFileA
+#define CreateEnhMetaFile CreateEnhMetaFileA
+#define GetEnhMetaFile GetEnhMetaFileA
+#define GetEnhMetaFileDescription GetEnhMetaFileDescriptionA
+#endif
+
+ WINGDIAPI WINBOOL WINAPI PlayMetaFileRecord(HDC hdc,LPHANDLETABLE lpHandleTable,LPMETARECORD lpMR,UINT noObjs);
+
+ typedef int (CALLBACK *MFENUMPROC)(HDC hdc,HANDLETABLE *lpht,METARECORD *lpMR,int nObj,LPARAM param);
+
+ WINGDIAPI WINBOOL WINAPI EnumMetaFile(HDC hdc,HMETAFILE hmf,MFENUMPROC proc,LPARAM param);
+
+ typedef int (CALLBACK *ENHMFENUMPROC)(HDC hdc,HANDLETABLE *lpht,CONST ENHMETARECORD *lpmr,int hHandles,LPARAM data);
+
+ WINGDIAPI HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc);
+ WINGDIAPI HENHMETAFILE WINAPI CopyEnhMetaFileA(HENHMETAFILE hEnh,LPCSTR lpFileName);
+ WINGDIAPI HENHMETAFILE WINAPI CopyEnhMetaFileW(HENHMETAFILE hEnh,LPCWSTR lpFileName);
+ WINGDIAPI HDC WINAPI CreateEnhMetaFileA(HDC hdc,LPCSTR lpFilename,CONST RECT *lprc,LPCSTR lpDesc);
+ WINGDIAPI HDC WINAPI CreateEnhMetaFileW(HDC hdc,LPCWSTR lpFilename,CONST RECT *lprc,LPCWSTR lpDesc);
+ WINGDIAPI WINBOOL WINAPI DeleteEnhMetaFile(HENHMETAFILE hmf);
+ WINGDIAPI WINBOOL WINAPI EnumEnhMetaFile(HDC hdc,HENHMETAFILE hmf,ENHMFENUMPROC proc,LPVOID param,CONST RECT *lpRect);
+ WINGDIAPI HENHMETAFILE WINAPI GetEnhMetaFileA(LPCSTR lpName);
+ WINGDIAPI HENHMETAFILE WINAPI GetEnhMetaFileW(LPCWSTR lpName);
+ WINGDIAPI UINT WINAPI GetEnhMetaFileBits(HENHMETAFILE hEMF,UINT nSize,LPBYTE lpData);
+ WINGDIAPI UINT WINAPI GetEnhMetaFileDescriptionA(HENHMETAFILE hemf,UINT cchBuffer,LPSTR lpDescription);
+ WINGDIAPI UINT WINAPI GetEnhMetaFileDescriptionW(HENHMETAFILE hemf,UINT cchBuffer,LPWSTR lpDescription);
+ WINGDIAPI UINT WINAPI GetEnhMetaFileHeader(HENHMETAFILE hemf,UINT nSize,LPENHMETAHEADER lpEnhMetaHeader);
+ WINGDIAPI UINT WINAPI GetEnhMetaFilePaletteEntries(HENHMETAFILE hemf,UINT nNumEntries,LPPALETTEENTRY lpPaletteEntries);
+ WINGDIAPI UINT WINAPI GetEnhMetaFilePixelFormat(HENHMETAFILE hemf,UINT cbBuffer,PIXELFORMATDESCRIPTOR *ppfd);
+ WINGDIAPI UINT WINAPI GetWinMetaFileBits(HENHMETAFILE hemf,UINT cbData16,LPBYTE pData16,INT iMapMode,HDC hdcRef);
+ WINGDIAPI WINBOOL WINAPI PlayEnhMetaFile(HDC hdc,HENHMETAFILE hmf,CONST RECT *lprect);
+ WINGDIAPI WINBOOL WINAPI PlayEnhMetaFileRecord(HDC hdc,LPHANDLETABLE pht,CONST ENHMETARECORD *pmr,UINT cht);
+ WINGDIAPI HENHMETAFILE WINAPI SetEnhMetaFileBits(UINT nSize,CONST BYTE *pb);
+ WINGDIAPI HENHMETAFILE WINAPI SetWinMetaFileBits(UINT nSize,CONST BYTE *lpMeta16Data,HDC hdcRef,CONST METAFILEPICT *lpMFP);
+ WINGDIAPI WINBOOL WINAPI GdiComment(HDC hdc,UINT nSize,CONST BYTE *lpData);
+#endif
+
+#ifndef NOTEXTMETRIC
+#ifdef UNICODE
+#define GetTextMetrics GetTextMetricsW
+#else
+#define GetTextMetrics GetTextMetricsA
+#endif
+
+ WINGDIAPI WINBOOL WINAPI GetTextMetricsA(HDC hdc,LPTEXTMETRICA lptm);
+ WINGDIAPI WINBOOL WINAPI GetTextMetricsW(HDC hdc,LPTEXTMETRICW lptm);
+#endif
+
+ typedef struct tagDIBSECTION {
+ BITMAP dsBm;
+ BITMAPINFOHEADER dsBmih;
+ DWORD dsBitfields[3];
+ HANDLE dshSection;
+ DWORD dsOffset;
+ } DIBSECTION,*LPDIBSECTION,*PDIBSECTION;
+
+ WINGDIAPI WINBOOL WINAPI AngleArc(HDC hdc,int x,int y,DWORD r,FLOAT StartAngle,FLOAT SweepAngle);
+ WINGDIAPI WINBOOL WINAPI PolyPolyline(HDC hdc,CONST POINT *apt,CONST DWORD *asz,DWORD csz);
+ WINGDIAPI WINBOOL WINAPI GetWorldTransform(HDC hdc,LPXFORM lpxf);
+ WINGDIAPI WINBOOL WINAPI SetWorldTransform(HDC hdc,CONST XFORM *lpxf);
+ WINGDIAPI WINBOOL WINAPI ModifyWorldTransform(HDC hdc,CONST XFORM *lpxf,DWORD mode);
+ WINGDIAPI WINBOOL WINAPI CombineTransform(LPXFORM lpxfOut,CONST XFORM *lpxf1,CONST XFORM *lpxf2);
+ WINGDIAPI HBITMAP WINAPI CreateDIBSection(HDC hdc,CONST BITMAPINFO *lpbmi,UINT usage,VOID **ppvBits,HANDLE hSection,DWORD offset);
+ WINGDIAPI UINT WINAPI GetDIBColorTable(HDC hdc,UINT iStart,UINT cEntries,RGBQUAD *prgbq);
+ WINGDIAPI UINT WINAPI SetDIBColorTable(HDC hdc,UINT iStart,UINT cEntries,CONST RGBQUAD *prgbq);
+
+#define CA_NEGATIVE 0x0001
+#define CA_LOG_FILTER 0x0002
+
+#define ILLUMINANT_DEVICE_DEFAULT 0
+#define ILLUMINANT_A 1
+#define ILLUMINANT_B 2
+#define ILLUMINANT_C 3
+#define ILLUMINANT_D50 4
+#define ILLUMINANT_D55 5
+#define ILLUMINANT_D65 6
+#define ILLUMINANT_D75 7
+#define ILLUMINANT_F2 8
+#define ILLUMINANT_MAX_INDEX ILLUMINANT_F2
+
+#define ILLUMINANT_TUNGSTEN ILLUMINANT_A
+#define ILLUMINANT_DAYLIGHT ILLUMINANT_C
+#define ILLUMINANT_FLUORESCENT ILLUMINANT_F2
+#define ILLUMINANT_NTSC ILLUMINANT_C
+
+#define RGB_GAMMA_MIN (WORD)02500
+#define RGB_GAMMA_MAX (WORD)65000
+
+#define REFERENCE_WHITE_MIN (WORD)6000
+#define REFERENCE_WHITE_MAX (WORD)10000
+#define REFERENCE_BLACK_MIN (WORD)0
+#define REFERENCE_BLACK_MAX (WORD)4000
+
+#define COLOR_ADJ_MIN (SHORT)-100
+#define COLOR_ADJ_MAX (SHORT)100
+
+ typedef struct tagCOLORADJUSTMENT {
+ WORD caSize;
+ WORD caFlags;
+ WORD caIlluminantIndex;
+ WORD caRedGamma;
+ WORD caGreenGamma;
+ WORD caBlueGamma;
+ WORD caReferenceBlack;
+ WORD caReferenceWhite;
+ SHORT caContrast;
+ SHORT caBrightness;
+ SHORT caColorfulness;
+ SHORT caRedGreenTint;
+ } COLORADJUSTMENT,*PCOLORADJUSTMENT,*LPCOLORADJUSTMENT;
+
+ WINGDIAPI WINBOOL WINAPI SetColorAdjustment(HDC hdc,CONST COLORADJUSTMENT *lpca);
+ WINGDIAPI WINBOOL WINAPI GetColorAdjustment(HDC hdc,LPCOLORADJUSTMENT lpca);
+ WINGDIAPI HPALETTE WINAPI CreateHalftonePalette(HDC hdc);
+
+ typedef WINBOOL (CALLBACK *ABORTPROC)(HDC,int);
+
+ typedef struct _DOCINFOA {
+ int cbSize;
+ LPCSTR lpszDocName;
+ LPCSTR lpszOutput;
+ LPCSTR lpszDatatype;
+ DWORD fwType;
+ } DOCINFOA,*LPDOCINFOA;
+
+ typedef struct _DOCINFOW {
+ int cbSize;
+ LPCWSTR lpszDocName;
+ LPCWSTR lpszOutput;
+ LPCWSTR lpszDatatype;
+ DWORD fwType;
+ } DOCINFOW,*LPDOCINFOW;
+
+#ifdef UNICODE
+ typedef DOCINFOW DOCINFO;
+ typedef LPDOCINFOW LPDOCINFO;
+#else
+ typedef DOCINFOA DOCINFO;
+ typedef LPDOCINFOA LPDOCINFO;
+#endif
+
+#define DI_APPBANDING 0x00000001
+#define DI_ROPS_READ_DESTINATION 0x00000002
+
+#ifdef UNICODE
+#define StartDoc StartDocW
+#define GetObject GetObjectW
+#define TextOut TextOutW
+#define ExtTextOut ExtTextOutW
+#define PolyTextOut PolyTextOutW
+#define GetTextFace GetTextFaceW
+#else
+#define StartDoc StartDocA
+#define GetObject GetObjectA
+#define TextOut TextOutA
+#define ExtTextOut ExtTextOutA
+#define PolyTextOut PolyTextOutA
+#define GetTextFace GetTextFaceA
+#endif
+
+ WINGDIAPI int WINAPI StartDocA(HDC hdc,CONST DOCINFOA *lpdi);
+ WINGDIAPI int WINAPI StartDocW(HDC hdc,CONST DOCINFOW *lpdi);
+ WINGDIAPI int WINAPI EndDoc(HDC hdc);
+ WINGDIAPI int WINAPI StartPage(HDC hdc);
+ WINGDIAPI int WINAPI EndPage(HDC hdc);
+ WINGDIAPI int WINAPI AbortDoc(HDC hdc);
+ WINGDIAPI int WINAPI SetAbortProc(HDC hdc,ABORTPROC proc);
+ WINGDIAPI WINBOOL WINAPI AbortPath(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI ArcTo(HDC hdc,int left,int top,int right,int bottom,int xr1,int yr1,int xr2,int yr2);
+ WINGDIAPI WINBOOL WINAPI BeginPath(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI CloseFigure(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI EndPath(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI FillPath(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI FlattenPath(HDC hdc);
+ WINGDIAPI int WINAPI GetPath(HDC hdc,LPPOINT apt,LPBYTE aj,int cpt);
+ WINGDIAPI HRGN WINAPI PathToRegion(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI PolyDraw(HDC hdc,CONST POINT *apt,CONST BYTE *aj,int cpt);
+ WINGDIAPI WINBOOL WINAPI SelectClipPath(HDC hdc,int mode);
+ WINGDIAPI int WINAPI SetArcDirection(HDC hdc,int dir);
+ WINGDIAPI WINBOOL WINAPI SetMiterLimit(HDC hdc,FLOAT limit,PFLOAT old);
+ WINGDIAPI WINBOOL WINAPI StrokeAndFillPath(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI StrokePath(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI WidenPath(HDC hdc);
+ WINGDIAPI HPEN WINAPI ExtCreatePen(DWORD iPenStyle,DWORD cWidth,CONST LOGBRUSH *plbrush,DWORD cStyle,CONST DWORD *pstyle);
+ WINGDIAPI WINBOOL WINAPI GetMiterLimit(HDC hdc,PFLOAT plimit);
+ WINGDIAPI int WINAPI GetArcDirection(HDC hdc);
+ WINGDIAPI int WINAPI GetObjectA(HANDLE h,int c,LPVOID pv);
+ WINGDIAPI int WINAPI GetObjectW(HANDLE h,int c,LPVOID pv);
+ WINGDIAPI WINBOOL WINAPI MoveToEx(HDC hdc,int x,int y,LPPOINT lppt);
+ WINGDIAPI WINBOOL WINAPI TextOutA(HDC hdc,int x,int y,LPCSTR lpString,int c);
+ WINGDIAPI WINBOOL WINAPI TextOutW(HDC hdc,int x,int y,LPCWSTR lpString,int c);
+ WINGDIAPI WINBOOL WINAPI ExtTextOutA(HDC hdc,int x,int y,UINT options,CONST RECT *lprect,LPCSTR lpString,UINT c,CONST INT *lpDx);
+ WINGDIAPI WINBOOL WINAPI ExtTextOutW(HDC hdc,int x,int y,UINT options,CONST RECT *lprect,LPCWSTR lpString,UINT c,CONST INT *lpDx);
+ WINGDIAPI WINBOOL WINAPI PolyTextOutA(HDC hdc,CONST POLYTEXTA *ppt,int nstrings);
+ WINGDIAPI WINBOOL WINAPI PolyTextOutW(HDC hdc,CONST POLYTEXTW *ppt,int nstrings);
+ WINGDIAPI HRGN WINAPI CreatePolygonRgn(CONST POINT *pptl,int cPoint,int iMode);
+ WINGDIAPI WINBOOL WINAPI DPtoLP(HDC hdc,LPPOINT lppt,int c);
+ WINGDIAPI WINBOOL WINAPI LPtoDP(HDC hdc,LPPOINT lppt,int c);
+ WINGDIAPI WINBOOL WINAPI Polygon(HDC hdc,CONST POINT *apt,int cpt);
+ WINGDIAPI WINBOOL WINAPI Polyline(HDC hdc,CONST POINT *apt,int cpt);
+ WINGDIAPI WINBOOL WINAPI PolyBezier(HDC hdc,CONST POINT *apt,DWORD cpt);
+ WINGDIAPI WINBOOL WINAPI PolyBezierTo(HDC hdc,CONST POINT *apt,DWORD cpt);
+ WINGDIAPI WINBOOL WINAPI PolylineTo(HDC hdc,CONST POINT *apt,DWORD cpt);
+ WINGDIAPI WINBOOL WINAPI SetViewportExtEx(HDC hdc,int x,int y,LPSIZE lpsz);
+ WINGDIAPI WINBOOL WINAPI SetViewportOrgEx(HDC hdc,int x,int y,LPPOINT lppt);
+ WINGDIAPI WINBOOL WINAPI SetWindowExtEx(HDC hdc,int x,int y,LPSIZE lpsz);
+ WINGDIAPI WINBOOL WINAPI SetWindowOrgEx(HDC hdc,int x,int y,LPPOINT lppt);
+ WINGDIAPI WINBOOL WINAPI OffsetViewportOrgEx(HDC hdc,int x,int y,LPPOINT lppt);
+ WINGDIAPI WINBOOL WINAPI OffsetWindowOrgEx(HDC hdc,int x,int y,LPPOINT lppt);
+ WINGDIAPI WINBOOL WINAPI ScaleViewportExtEx(HDC hdc,int xn,int dx,int yn,int yd,LPSIZE lpsz);
+ WINGDIAPI WINBOOL WINAPI ScaleWindowExtEx(HDC hdc,int xn,int xd,int yn,int yd,LPSIZE lpsz);
+ WINGDIAPI WINBOOL WINAPI SetBitmapDimensionEx(HBITMAP hbm,int w,int h,LPSIZE lpsz);
+ WINGDIAPI WINBOOL WINAPI SetBrushOrgEx(HDC hdc,int x,int y,LPPOINT lppt);
+ WINGDIAPI int WINAPI GetTextFaceA(HDC hdc,int c,LPSTR lpName);
+ WINGDIAPI int WINAPI GetTextFaceW(HDC hdc,int c,LPWSTR lpName);
+
+#define FONTMAPPER_MAX 10
+
+ typedef struct tagKERNINGPAIR {
+ WORD wFirst;
+ WORD wSecond;
+ int iKernAmount;
+ } KERNINGPAIR,*LPKERNINGPAIR;
+
+#ifdef UNICODE
+#define GetKerningPairs GetKerningPairsW
+#else
+#define GetKerningPairs GetKerningPairsA
+#endif
+
+ WINGDIAPI DWORD WINAPI GetKerningPairsA(HDC hdc,DWORD nPairs,LPKERNINGPAIR lpKernPair);
+ WINGDIAPI DWORD WINAPI GetKerningPairsW(HDC hdc,DWORD nPairs,LPKERNINGPAIR lpKernPair);
+ WINGDIAPI WINBOOL WINAPI GetDCOrgEx(HDC hdc,LPPOINT lppt);
+ WINGDIAPI WINBOOL WINAPI FixBrushOrgEx(HDC hdc,int x,int y,LPPOINT ptl);
+ WINGDIAPI WINBOOL WINAPI UnrealizeObject(HGDIOBJ h);
+ WINGDIAPI WINBOOL WINAPI GdiFlush();
+ WINGDIAPI DWORD WINAPI GdiSetBatchLimit(DWORD dw);
+ WINGDIAPI DWORD WINAPI GdiGetBatchLimit();
+
+#define ICM_OFF 1
+#define ICM_ON 2
+#define ICM_QUERY 3
+#define ICM_DONE_OUTSIDEDC 4
+
+ typedef int (CALLBACK *ICMENUMPROCA)(LPSTR,LPARAM);
+ typedef int (CALLBACK *ICMENUMPROCW)(LPWSTR,LPARAM);
+
+#ifdef UNICODE
+#define ICMENUMPROC ICMENUMPROCW
+#define EnumICMProfiles EnumICMProfilesW
+#define UpdateICMRegKey UpdateICMRegKeyW
+#define GetLogColorSpace GetLogColorSpaceW
+#define CreateColorSpace CreateColorSpaceW
+#define GetICMProfile GetICMProfileW
+#define SetICMProfile SetICMProfileW
+#else
+#define ICMENUMPROC ICMENUMPROCA
+#define EnumICMProfiles EnumICMProfilesA
+#define UpdateICMRegKey UpdateICMRegKeyA
+#define GetLogColorSpace GetLogColorSpaceA
+#define CreateColorSpace CreateColorSpaceA
+#define GetICMProfile GetICMProfileA
+#define SetICMProfile SetICMProfileA
+#endif
+
+ WINGDIAPI int WINAPI SetICMMode(HDC hdc,int mode);
+ WINGDIAPI WINBOOL WINAPI CheckColorsInGamut(HDC hdc,LPVOID lpRGBTriple,LPVOID dlpBuffer,DWORD nCount);
+ WINGDIAPI HCOLORSPACE WINAPI GetColorSpace(HDC hdc);
+ WINGDIAPI WINBOOL WINAPI GetLogColorSpaceA(HCOLORSPACE hColorSpace,LPLOGCOLORSPACEA lpBuffer,DWORD nSize);
+ WINGDIAPI WINBOOL WINAPI GetLogColorSpaceW(HCOLORSPACE hColorSpace,LPLOGCOLORSPACEW lpBuffer,DWORD nSize);
+ WINGDIAPI HCOLORSPACE WINAPI CreateColorSpaceA(LPLOGCOLORSPACEA lplcs);
+ WINGDIAPI HCOLORSPACE WINAPI CreateColorSpaceW(LPLOGCOLORSPACEW lplcs);
+ WINGDIAPI HCOLORSPACE WINAPI SetColorSpace(HDC hdc,HCOLORSPACE hcs);
+ WINGDIAPI WINBOOL WINAPI DeleteColorSpace(HCOLORSPACE hcs);
+ WINGDIAPI WINBOOL WINAPI GetICMProfileA(HDC hdc,LPDWORD pBufSize,LPSTR pszFilename);
+ WINGDIAPI WINBOOL WINAPI GetICMProfileW(HDC hdc,LPDWORD pBufSize,LPWSTR pszFilename);
+ WINGDIAPI WINBOOL WINAPI SetICMProfileA(HDC hdc,LPSTR lpFileName);
+ WINGDIAPI WINBOOL WINAPI SetICMProfileW(HDC hdc,LPWSTR lpFileName);
+ WINGDIAPI WINBOOL WINAPI GetDeviceGammaRamp(HDC hdc,LPVOID lpRamp);
+ WINGDIAPI WINBOOL WINAPI SetDeviceGammaRamp(HDC hdc,LPVOID lpRamp);
+ WINGDIAPI WINBOOL WINAPI ColorMatchToTarget(HDC hdc,HDC hdcTarget,DWORD action);
+ WINGDIAPI int WINAPI EnumICMProfilesA(HDC hdc,ICMENUMPROCA proc,LPARAM param);
+ WINGDIAPI int WINAPI EnumICMProfilesW(HDC hdc,ICMENUMPROCW proc,LPARAM param);
+ WINGDIAPI WINBOOL WINAPI UpdateICMRegKeyA(DWORD reserved,LPSTR lpszCMID,LPSTR lpszFileName,UINT command);
+ WINGDIAPI WINBOOL WINAPI UpdateICMRegKeyW(DWORD reserved,LPWSTR lpszCMID,LPWSTR lpszFileName,UINT command);
+ WINGDIAPI WINBOOL WINAPI ColorCorrectPalette(HDC hdc,HPALETTE hPal,DWORD deFirst,DWORD num);
+
+#ifndef NOMETAFILE
+
+#define ENHMETA_SIGNATURE 0x464D4520
+#define ENHMETA_STOCK_OBJECT 0x80000000
+
+#define EMR_HEADER 1
+#define EMR_POLYBEZIER 2
+#define EMR_POLYGON 3
+#define EMR_POLYLINE 4
+#define EMR_POLYBEZIERTO 5
+#define EMR_POLYLINETO 6
+#define EMR_POLYPOLYLINE 7
+#define EMR_POLYPOLYGON 8
+#define EMR_SETWINDOWEXTEX 9
+#define EMR_SETWINDOWORGEX 10
+#define EMR_SETVIEWPORTEXTEX 11
+#define EMR_SETVIEWPORTORGEX 12
+#define EMR_SETBRUSHORGEX 13
+#define EMR_EOF 14
+#define EMR_SETPIXELV 15
+#define EMR_SETMAPPERFLAGS 16
+#define EMR_SETMAPMODE 17
+#define EMR_SETBKMODE 18
+#define EMR_SETPOLYFILLMODE 19
+#define EMR_SETROP2 20
+#define EMR_SETSTRETCHBLTMODE 21
+#define EMR_SETTEXTALIGN 22
+#define EMR_SETCOLORADJUSTMENT 23
+#define EMR_SETTEXTCOLOR 24
+#define EMR_SETBKCOLOR 25
+#define EMR_OFFSETCLIPRGN 26
+#define EMR_MOVETOEX 27
+#define EMR_SETMETARGN 28
+#define EMR_EXCLUDECLIPRECT 29
+#define EMR_INTERSECTCLIPRECT 30
+#define EMR_SCALEVIEWPORTEXTEX 31
+#define EMR_SCALEWINDOWEXTEX 32
+#define EMR_SAVEDC 33
+#define EMR_RESTOREDC 34
+#define EMR_SETWORLDTRANSFORM 35
+#define EMR_MODIFYWORLDTRANSFORM 36
+#define EMR_SELECTOBJECT 37
+#define EMR_CREATEPEN 38
+#define EMR_CREATEBRUSHINDIRECT 39
+#define EMR_DELETEOBJECT 40
+#define EMR_ANGLEARC 41
+#define EMR_ELLIPSE 42
+#define EMR_RECTANGLE 43
+#define EMR_ROUNDRECT 44
+#define EMR_ARC 45
+#define EMR_CHORD 46
+#define EMR_PIE 47
+#define EMR_SELECTPALETTE 48
+#define EMR_CREATEPALETTE 49
+#define EMR_SETPALETTEENTRIES 50
+#define EMR_RESIZEPALETTE 51
+#define EMR_REALIZEPALETTE 52
+#define EMR_EXTFLOODFILL 53
+#define EMR_LINETO 54
+#define EMR_ARCTO 55
+#define EMR_POLYDRAW 56
+#define EMR_SETARCDIRECTION 57
+#define EMR_SETMITERLIMIT 58
+#define EMR_BEGINPATH 59
+#define EMR_ENDPATH 60
+#define EMR_CLOSEFIGURE 61
+#define EMR_FILLPATH 62
+#define EMR_STROKEANDFILLPATH 63
+#define EMR_STROKEPATH 64
+#define EMR_FLATTENPATH 65
+#define EMR_WIDENPATH 66
+#define EMR_SELECTCLIPPATH 67
+#define EMR_ABORTPATH 68
+
+#define EMR_GDICOMMENT 70
+#define EMR_FILLRGN 71
+#define EMR_FRAMERGN 72
+#define EMR_INVERTRGN 73
+#define EMR_PAINTRGN 74
+#define EMR_EXTSELECTCLIPRGN 75
+#define EMR_BITBLT 76
+#define EMR_STRETCHBLT 77
+#define EMR_MASKBLT 78
+#define EMR_PLGBLT 79
+#define EMR_SETDIBITSTODEVICE 80
+#define EMR_STRETCHDIBITS 81
+#define EMR_EXTCREATEFONTINDIRECTW 82
+#define EMR_EXTTEXTOUTA 83
+#define EMR_EXTTEXTOUTW 84
+#define EMR_POLYBEZIER16 85
+#define EMR_POLYGON16 86
+#define EMR_POLYLINE16 87
+#define EMR_POLYBEZIERTO16 88
+#define EMR_POLYLINETO16 89
+#define EMR_POLYPOLYLINE16 90
+#define EMR_POLYPOLYGON16 91
+#define EMR_POLYDRAW16 92
+#define EMR_CREATEMONOBRUSH 93
+#define EMR_CREATEDIBPATTERNBRUSHPT 94
+#define EMR_EXTCREATEPEN 95
+#define EMR_POLYTEXTOUTA 96
+#define EMR_POLYTEXTOUTW 97
+
+#define EMR_SETICMMODE 98
+#define EMR_CREATECOLORSPACE 99
+#define EMR_SETCOLORSPACE 100
+#define EMR_DELETECOLORSPACE 101
+#define EMR_GLSRECORD 102
+#define EMR_GLSBOUNDEDRECORD 103
+#define EMR_PIXELFORMAT 104
+#define EMR_RESERVED_105 105
+#define EMR_RESERVED_106 106
+#define EMR_RESERVED_107 107
+#define EMR_RESERVED_108 108
+#define EMR_RESERVED_109 109
+#define EMR_RESERVED_110 110
+#define EMR_COLORCORRECTPALETTE 111
+#define EMR_SETICMPROFILEA 112
+#define EMR_SETICMPROFILEW 113
+#define EMR_ALPHABLEND 114
+#define EMR_SETLAYOUT 115
+#define EMR_TRANSPARENTBLT 116
+#define EMR_RESERVED_117 117
+#define EMR_GRADIENTFILL 118
+#define EMR_RESERVED_119 119
+#define EMR_RESERVED_120 120
+#define EMR_COLORMATCHTOTARGETW 121
+#define EMR_CREATECOLORSPACEW 122
+
+#define EMR_MIN 1
+
+#define EMR_MAX 122
+
+ typedef struct tagEMR {
+ DWORD iType;
+ DWORD nSize;
+ } EMR,*PEMR;
+
+ typedef struct tagEMRTEXT {
+ POINTL ptlReference;
+ DWORD nChars;
+ DWORD offString;
+ DWORD fOptions;
+ RECTL rcl;
+ DWORD offDx;
+ } EMRTEXT,*PEMRTEXT;
+
+ typedef struct tagABORTPATH {
+ EMR emr;
+ } EMRABORTPATH,*PEMRABORTPATH,EMRBEGINPATH,*PEMRBEGINPATH,EMRENDPATH,*PEMRENDPATH,EMRCLOSEFIGURE,*PEMRCLOSEFIGURE,EMRFLATTENPATH,*PEMRFLATTENPATH,EMRWIDENPATH,*PEMRWIDENPATH,EMRSETMETARGN,*PEMRSETMETARGN,EMRSAVEDC,*PEMRSAVEDC,EMRREALIZEPALETTE,*PEMRREALIZEPALETTE;
+
+ typedef struct tagEMRSELECTCLIPPATH {
+ EMR emr;
+ DWORD iMode;
+ } EMRSELECTCLIPPATH,*PEMRSELECTCLIPPATH,EMRSETBKMODE,*PEMRSETBKMODE,EMRSETMAPMODE,*PEMRSETMAPMODE,EMRSETLAYOUT,*PEMRSETLAYOUT,
+ EMRSETPOLYFILLMODE,*PEMRSETPOLYFILLMODE,EMRSETROP2,*PEMRSETROP2,EMRSETSTRETCHBLTMODE,*PEMRSETSTRETCHBLTMODE,EMRSETICMMODE,
+ *PEMRSETICMMODE,EMRSETTEXTALIGN,*PEMRSETTEXTALIGN;
+
+ typedef struct tagEMRSETMITERLIMIT {
+ EMR emr;
+ FLOAT eMiterLimit;
+ } EMRSETMITERLIMIT,*PEMRSETMITERLIMIT;
+
+ typedef struct tagEMRRESTOREDC {
+ EMR emr;
+ LONG iRelative;
+ } EMRRESTOREDC,*PEMRRESTOREDC;
+
+ typedef struct tagEMRSETARCDIRECTION {
+ EMR emr;
+ DWORD iArcDirection;
+
+ } EMRSETARCDIRECTION,*PEMRSETARCDIRECTION;
+
+ typedef struct tagEMRSETMAPPERFLAGS {
+ EMR emr;
+ DWORD dwFlags;
+ } EMRSETMAPPERFLAGS,*PEMRSETMAPPERFLAGS;
+
+ typedef struct tagEMRSETTEXTCOLOR {
+ EMR emr;
+ COLORREF crColor;
+ } EMRSETBKCOLOR,*PEMRSETBKCOLOR,EMRSETTEXTCOLOR,*PEMRSETTEXTCOLOR;
+
+ typedef struct tagEMRSELECTOBJECT {
+ EMR emr;
+ DWORD ihObject;
+ } EMRSELECTOBJECT,*PEMRSELECTOBJECT,EMRDELETEOBJECT,*PEMRDELETEOBJECT;
+
+ typedef struct tagEMRSELECTPALETTE {
+ EMR emr;
+ DWORD ihPal;
+ } EMRSELECTPALETTE,*PEMRSELECTPALETTE;
+
+ typedef struct tagEMRRESIZEPALETTE {
+ EMR emr;
+ DWORD ihPal;
+ DWORD cEntries;
+ } EMRRESIZEPALETTE,*PEMRRESIZEPALETTE;
+
+ typedef struct tagEMRSETPALETTEENTRIES {
+ EMR emr;
+ DWORD ihPal;
+ DWORD iStart;
+ DWORD cEntries;
+ PALETTEENTRY aPalEntries[1];
+ } EMRSETPALETTEENTRIES,*PEMRSETPALETTEENTRIES;
+
+ typedef struct tagEMRSETCOLORADJUSTMENT {
+ EMR emr;
+ COLORADJUSTMENT ColorAdjustment;
+ } EMRSETCOLORADJUSTMENT,*PEMRSETCOLORADJUSTMENT;
+
+ typedef struct tagEMRGDICOMMENT {
+ EMR emr;
+ DWORD cbData;
+ BYTE Data[1];
+ } EMRGDICOMMENT,*PEMRGDICOMMENT;
+
+ typedef struct tagEMREOF {
+ EMR emr;
+ DWORD nPalEntries;
+ DWORD offPalEntries;
+ DWORD nSizeLast;
+ } EMREOF,*PEMREOF;
+
+ typedef struct tagEMRLINETO {
+ EMR emr;
+ POINTL ptl;
+ } EMRLINETO,*PEMRLINETO,EMRMOVETOEX,*PEMRMOVETOEX;
+
+ typedef struct tagEMROFFSETCLIPRGN {
+ EMR emr;
+ POINTL ptlOffset;
+ } EMROFFSETCLIPRGN,*PEMROFFSETCLIPRGN;
+
+ typedef struct tagEMRFILLPATH {
+ EMR emr;
+ RECTL rclBounds;
+ } EMRFILLPATH,*PEMRFILLPATH,EMRSTROKEANDFILLPATH,*PEMRSTROKEANDFILLPATH,EMRSTROKEPATH,*PEMRSTROKEPATH;
+
+ typedef struct tagEMREXCLUDECLIPRECT {
+ EMR emr;
+ RECTL rclClip;
+ } EMREXCLUDECLIPRECT,*PEMREXCLUDECLIPRECT,EMRINTERSECTCLIPRECT,*PEMRINTERSECTCLIPRECT;
+
+ typedef struct tagEMRSETVIEWPORTORGEX {
+ EMR emr;
+ POINTL ptlOrigin;
+ } EMRSETVIEWPORTORGEX,*PEMRSETVIEWPORTORGEX,EMRSETWINDOWORGEX,*PEMRSETWINDOWORGEX,EMRSETBRUSHORGEX,*PEMRSETBRUSHORGEX;
+
+ typedef struct tagEMRSETVIEWPORTEXTEX {
+ EMR emr;
+ SIZEL szlExtent;
+ } EMRSETVIEWPORTEXTEX,*PEMRSETVIEWPORTEXTEX,EMRSETWINDOWEXTEX,*PEMRSETWINDOWEXTEX;
+
+ typedef struct tagEMRSCALEVIEWPORTEXTEX {
+ EMR emr;
+ LONG xNum;
+ LONG xDenom;
+ LONG yNum;
+ LONG yDenom;
+ } EMRSCALEVIEWPORTEXTEX,*PEMRSCALEVIEWPORTEXTEX,EMRSCALEWINDOWEXTEX,*PEMRSCALEWINDOWEXTEX;
+
+ typedef struct tagEMRSETWORLDTRANSFORM {
+ EMR emr;
+ XFORM xform;
+ } EMRSETWORLDTRANSFORM,*PEMRSETWORLDTRANSFORM;
+
+ typedef struct tagEMRMODIFYWORLDTRANSFORM {
+ EMR emr;
+ XFORM xform;
+ DWORD iMode;
+ } EMRMODIFYWORLDTRANSFORM,*PEMRMODIFYWORLDTRANSFORM;
+
+ typedef struct tagEMRSETPIXELV {
+ EMR emr;
+ POINTL ptlPixel;
+ COLORREF crColor;
+ } EMRSETPIXELV,*PEMRSETPIXELV;
+
+ typedef struct tagEMREXTFLOODFILL {
+ EMR emr;
+ POINTL ptlStart;
+ COLORREF crColor;
+ DWORD iMode;
+ } EMREXTFLOODFILL,*PEMREXTFLOODFILL;
+
+ typedef struct tagEMRELLIPSE {
+ EMR emr;
+ RECTL rclBox;
+ } EMRELLIPSE,*PEMRELLIPSE,EMRRECTANGLE,*PEMRRECTANGLE;
+
+ typedef struct tagEMRROUNDRECT {
+ EMR emr;
+ RECTL rclBox;
+ SIZEL szlCorner;
+ } EMRROUNDRECT,*PEMRROUNDRECT;
+
+ typedef struct tagEMRARC {
+ EMR emr;
+ RECTL rclBox;
+ POINTL ptlStart;
+ POINTL ptlEnd;
+ } EMRARC,*PEMRARC,EMRARCTO,*PEMRARCTO,EMRCHORD,*PEMRCHORD,EMRPIE,*PEMRPIE;
+
+ typedef struct tagEMRANGLEARC {
+ EMR emr;
+ POINTL ptlCenter;
+ DWORD nRadius;
+ FLOAT eStartAngle;
+ FLOAT eSweepAngle;
+ } EMRANGLEARC,*PEMRANGLEARC;
+
+ typedef struct tagEMRPOLYLINE {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD cptl;
+ POINTL aptl[1];
+ } EMRPOLYLINE,*PEMRPOLYLINE,EMRPOLYBEZIER,*PEMRPOLYBEZIER,EMRPOLYGON,*PEMRPOLYGON,EMRPOLYBEZIERTO,*PEMRPOLYBEZIERTO,EMRPOLYLINETO,*PEMRPOLYLINETO;
+
+ typedef struct tagEMRPOLYLINE16 {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD cpts;
+ POINTS apts[1];
+ } EMRPOLYLINE16,*PEMRPOLYLINE16,EMRPOLYBEZIER16,*PEMRPOLYBEZIER16,EMRPOLYGON16,*PEMRPOLYGON16,EMRPOLYBEZIERTO16,*PEMRPOLYBEZIERTO16,EMRPOLYLINETO16,*PEMRPOLYLINETO16;
+
+ typedef struct tagEMRPOLYDRAW {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD cptl;
+ POINTL aptl[1];
+ BYTE abTypes[1];
+ } EMRPOLYDRAW,*PEMRPOLYDRAW;
+
+ typedef struct tagEMRPOLYDRAW16 {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD cpts;
+ POINTS apts[1];
+ BYTE abTypes[1];
+ } EMRPOLYDRAW16,*PEMRPOLYDRAW16;
+
+ typedef struct tagEMRPOLYPOLYLINE {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD nPolys;
+ DWORD cptl;
+ DWORD aPolyCounts[1];
+ POINTL aptl[1];
+ } EMRPOLYPOLYLINE,*PEMRPOLYPOLYLINE,EMRPOLYPOLYGON,*PEMRPOLYPOLYGON;
+
+ typedef struct tagEMRPOLYPOLYLINE16 {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD nPolys;
+ DWORD cpts;
+ DWORD aPolyCounts[1];
+ POINTS apts[1];
+ } EMRPOLYPOLYLINE16,*PEMRPOLYPOLYLINE16,EMRPOLYPOLYGON16,*PEMRPOLYPOLYGON16;
+
+ typedef struct tagEMRINVERTRGN {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD cbRgnData;
+ BYTE RgnData[1];
+ } EMRINVERTRGN,*PEMRINVERTRGN,EMRPAINTRGN,*PEMRPAINTRGN;
+
+ typedef struct tagEMRFILLRGN {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD cbRgnData;
+ DWORD ihBrush;
+ BYTE RgnData[1];
+ } EMRFILLRGN,*PEMRFILLRGN;
+
+ typedef struct tagEMRFRAMERGN {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD cbRgnData;
+ DWORD ihBrush;
+ SIZEL szlStroke;
+ BYTE RgnData[1];
+ } EMRFRAMERGN,*PEMRFRAMERGN;
+
+ typedef struct tagEMREXTSELECTCLIPRGN {
+ EMR emr;
+ DWORD cbRgnData;
+ DWORD iMode;
+ BYTE RgnData[1];
+ } EMREXTSELECTCLIPRGN,*PEMREXTSELECTCLIPRGN;
+
+ typedef struct tagEMREXTTEXTOUTA {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD iGraphicsMode;
+ FLOAT exScale;
+ FLOAT eyScale;
+ EMRTEXT emrtext;
+ } EMREXTTEXTOUTA,*PEMREXTTEXTOUTA,EMREXTTEXTOUTW,*PEMREXTTEXTOUTW;
+
+ typedef struct tagEMRPOLYTEXTOUTA {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD iGraphicsMode;
+ FLOAT exScale;
+ FLOAT eyScale;
+ LONG cStrings;
+ EMRTEXT aemrtext[1];
+ } EMRPOLYTEXTOUTA,*PEMRPOLYTEXTOUTA,EMRPOLYTEXTOUTW,*PEMRPOLYTEXTOUTW;
+
+ typedef struct tagEMRBITBLT {
+ EMR emr;
+ RECTL rclBounds;
+ LONG xDest;
+ LONG yDest;
+ LONG cxDest;
+ LONG cyDest;
+ DWORD dwRop;
+ LONG xSrc;
+ LONG ySrc;
+ XFORM xformSrc;
+ COLORREF crBkColorSrc;
+ DWORD iUsageSrc;
+ DWORD offBmiSrc;
+ DWORD cbBmiSrc;
+ DWORD offBitsSrc;
+ DWORD cbBitsSrc;
+ } EMRBITBLT,*PEMRBITBLT;
+
+ typedef struct tagEMRSTRETCHBLT {
+ EMR emr;
+ RECTL rclBounds;
+ LONG xDest;
+ LONG yDest;
+ LONG cxDest;
+ LONG cyDest;
+ DWORD dwRop;
+ LONG xSrc;
+ LONG ySrc;
+ XFORM xformSrc;
+ COLORREF crBkColorSrc;
+ DWORD iUsageSrc;
+ DWORD offBmiSrc;
+ DWORD cbBmiSrc;
+ DWORD offBitsSrc;
+ DWORD cbBitsSrc;
+ LONG cxSrc;
+ LONG cySrc;
+ } EMRSTRETCHBLT,*PEMRSTRETCHBLT;
+
+ typedef struct tagEMRMASKBLT {
+ EMR emr;
+ RECTL rclBounds;
+ LONG xDest;
+ LONG yDest;
+ LONG cxDest;
+ LONG cyDest;
+ DWORD dwRop;
+ LONG xSrc;
+ LONG ySrc;
+ XFORM xformSrc;
+ COLORREF crBkColorSrc;
+ DWORD iUsageSrc;
+ DWORD offBmiSrc;
+ DWORD cbBmiSrc;
+ DWORD offBitsSrc;
+ DWORD cbBitsSrc;
+ LONG xMask;
+ LONG yMask;
+ DWORD iUsageMask;
+ DWORD offBmiMask;
+ DWORD cbBmiMask;
+ DWORD offBitsMask;
+ DWORD cbBitsMask;
+ } EMRMASKBLT,*PEMRMASKBLT;
+
+ typedef struct tagEMRPLGBLT {
+ EMR emr;
+ RECTL rclBounds;
+ POINTL aptlDest[3];
+ LONG xSrc;
+ LONG ySrc;
+ LONG cxSrc;
+ LONG cySrc;
+ XFORM xformSrc;
+ COLORREF crBkColorSrc;
+ DWORD iUsageSrc;
+ DWORD offBmiSrc;
+ DWORD cbBmiSrc;
+ DWORD offBitsSrc;
+ DWORD cbBitsSrc;
+ LONG xMask;
+ LONG yMask;
+ DWORD iUsageMask;
+ DWORD offBmiMask;
+ DWORD cbBmiMask;
+ DWORD offBitsMask;
+ DWORD cbBitsMask;
+ } EMRPLGBLT,*PEMRPLGBLT;
+
+ typedef struct tagEMRSETDIBITSTODEVICE {
+ EMR emr;
+ RECTL rclBounds;
+ LONG xDest;
+ LONG yDest;
+ LONG xSrc;
+ LONG ySrc;
+ LONG cxSrc;
+ LONG cySrc;
+ DWORD offBmiSrc;
+ DWORD cbBmiSrc;
+ DWORD offBitsSrc;
+ DWORD cbBitsSrc;
+ DWORD iUsageSrc;
+ DWORD iStartScan;
+ DWORD cScans;
+ } EMRSETDIBITSTODEVICE,*PEMRSETDIBITSTODEVICE;
+
+ typedef struct tagEMRSTRETCHDIBITS {
+ EMR emr;
+ RECTL rclBounds;
+ LONG xDest;
+ LONG yDest;
+ LONG xSrc;
+ LONG ySrc;
+ LONG cxSrc;
+ LONG cySrc;
+ DWORD offBmiSrc;
+ DWORD cbBmiSrc;
+ DWORD offBitsSrc;
+ DWORD cbBitsSrc;
+ DWORD iUsageSrc;
+ DWORD dwRop;
+ LONG cxDest;
+ LONG cyDest;
+ } EMRSTRETCHDIBITS,*PEMRSTRETCHDIBITS;
+
+ typedef struct tagEMREXTCREATEFONTINDIRECTW {
+ EMR emr;
+ DWORD ihFont;
+ EXTLOGFONTW elfw;
+ } EMREXTCREATEFONTINDIRECTW,*PEMREXTCREATEFONTINDIRECTW;
+
+ typedef struct tagEMRCREATEPALETTE {
+ EMR emr;
+ DWORD ihPal;
+ LOGPALETTE lgpl;
+ } EMRCREATEPALETTE,*PEMRCREATEPALETTE;
+
+ typedef struct tagEMRCREATEPEN {
+ EMR emr;
+ DWORD ihPen;
+ LOGPEN lopn;
+ } EMRCREATEPEN,*PEMRCREATEPEN;
+
+ typedef struct tagEMREXTCREATEPEN {
+ EMR emr;
+ DWORD ihPen;
+ DWORD offBmi;
+ DWORD cbBmi;
+ DWORD offBits;
+ DWORD cbBits;
+ EXTLOGPEN elp;
+ } EMREXTCREATEPEN,*PEMREXTCREATEPEN;
+
+ typedef struct tagEMRCREATEBRUSHINDIRECT {
+ EMR emr;
+ DWORD ihBrush;
+ LOGBRUSH32 lb;
+ } EMRCREATEBRUSHINDIRECT,*PEMRCREATEBRUSHINDIRECT;
+
+ typedef struct tagEMRCREATEMONOBRUSH {
+ EMR emr;
+ DWORD ihBrush;
+ DWORD iUsage;
+ DWORD offBmi;
+ DWORD cbBmi;
+ DWORD offBits;
+ DWORD cbBits;
+ } EMRCREATEMONOBRUSH,*PEMRCREATEMONOBRUSH;
+
+ typedef struct tagEMRCREATEDIBPATTERNBRUSHPT {
+ EMR emr;
+ DWORD ihBrush;
+ DWORD iUsage;
+ DWORD offBmi;
+ DWORD cbBmi;
+ DWORD offBits;
+ DWORD cbBits;
+ } EMRCREATEDIBPATTERNBRUSHPT,*PEMRCREATEDIBPATTERNBRUSHPT;
+
+ typedef struct tagEMRFORMAT {
+ DWORD dSignature;
+ DWORD nVersion;
+ DWORD cbData;
+ DWORD offData;
+ } EMRFORMAT,*PEMRFORMAT;
+
+ typedef struct tagEMRGLSRECORD {
+ EMR emr;
+ DWORD cbData;
+ BYTE Data[1];
+ } EMRGLSRECORD,*PEMRGLSRECORD;
+
+ typedef struct tagEMRGLSBOUNDEDRECORD {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD cbData;
+ BYTE Data[1];
+ } EMRGLSBOUNDEDRECORD,*PEMRGLSBOUNDEDRECORD;
+
+ typedef struct tagEMRPIXELFORMAT {
+ EMR emr;
+ PIXELFORMATDESCRIPTOR pfd;
+ } EMRPIXELFORMAT,*PEMRPIXELFORMAT;
+
+ typedef struct tagEMRCREATECOLORSPACE {
+ EMR emr;
+ DWORD ihCS;
+ LOGCOLORSPACEA lcs;
+ } EMRCREATECOLORSPACE,*PEMRCREATECOLORSPACE;
+
+ typedef struct tagEMRSETCOLORSPACE {
+ EMR emr;
+ DWORD ihCS;
+ } EMRSETCOLORSPACE,*PEMRSETCOLORSPACE,EMRSELECTCOLORSPACE,*PEMRSELECTCOLORSPACE,EMRDELETECOLORSPACE,*PEMRDELETECOLORSPACE;
+
+ typedef struct tagEMREXTESCAPE {
+ EMR emr;
+ INT iEscape;
+ INT cbEscData;
+ BYTE EscData[1];
+ } EMREXTESCAPE,*PEMREXTESCAPE,EMRDRAWESCAPE,*PEMRDRAWESCAPE;
+
+ typedef struct tagEMRNAMEDESCAPE {
+ EMR emr;
+ INT iEscape;
+ INT cbDriver;
+ INT cbEscData;
+ BYTE EscData[1];
+ } EMRNAMEDESCAPE,*PEMRNAMEDESCAPE;
+
+#define SETICMPROFILE_EMBEDED 0x00000001
+
+ typedef struct tagEMRSETICMPROFILE {
+ EMR emr;
+ DWORD dwFlags;
+ DWORD cbName;
+ DWORD cbData;
+ BYTE Data[1];
+ } EMRSETICMPROFILE,*PEMRSETICMPROFILE,EMRSETICMPROFILEA,*PEMRSETICMPROFILEA,EMRSETICMPROFILEW,*PEMRSETICMPROFILEW;
+
+#define CREATECOLORSPACE_EMBEDED 0x00000001
+
+ typedef struct tagEMRCREATECOLORSPACEW {
+ EMR emr;
+ DWORD ihCS;
+ LOGCOLORSPACEW lcs;
+ DWORD dwFlags;
+ DWORD cbData;
+ BYTE Data[1];
+ } EMRCREATECOLORSPACEW,*PEMRCREATECOLORSPACEW;
+
+#define COLORMATCHTOTARGET_EMBEDED 0x00000001
+
+ typedef struct tagCOLORMATCHTOTARGET {
+ EMR emr;
+ DWORD dwAction;
+ DWORD dwFlags;
+ DWORD cbName;
+ DWORD cbData;
+ BYTE Data[1];
+ } EMRCOLORMATCHTOTARGET,*PEMRCOLORMATCHTOTARGET;
+
+ typedef struct tagCOLORCORRECTPALETTE {
+ EMR emr;
+ DWORD ihPalette;
+ DWORD nFirstEntry;
+ DWORD nPalEntries;
+ DWORD nReserved;
+ } EMRCOLORCORRECTPALETTE,*PEMRCOLORCORRECTPALETTE;
+
+ typedef struct tagEMRALPHABLEND {
+ EMR emr;
+ RECTL rclBounds;
+ LONG xDest;
+ LONG yDest;
+ LONG cxDest;
+ LONG cyDest;
+ DWORD dwRop;
+ LONG xSrc;
+ LONG ySrc;
+ XFORM xformSrc;
+ COLORREF crBkColorSrc;
+ DWORD iUsageSrc;
+ DWORD offBmiSrc;
+ DWORD cbBmiSrc;
+ DWORD offBitsSrc;
+ DWORD cbBitsSrc;
+ LONG cxSrc;
+ LONG cySrc;
+ } EMRALPHABLEND,*PEMRALPHABLEND;
+
+ typedef struct tagEMRGRADIENTFILL {
+ EMR emr;
+ RECTL rclBounds;
+ DWORD nVer;
+ DWORD nTri;
+ ULONG ulMode;
+ TRIVERTEX Ver[1];
+ } EMRGRADIENTFILL,*PEMRGRADIENTFILL;
+
+ typedef struct tagEMRTRANSPARENTBLT {
+ EMR emr;
+ RECTL rclBounds;
+ LONG xDest;
+ LONG yDest;
+ LONG cxDest;
+ LONG cyDest;
+ DWORD dwRop;
+ LONG xSrc;
+ LONG ySrc;
+ XFORM xformSrc;
+ COLORREF crBkColorSrc;
+ DWORD iUsageSrc;
+ DWORD offBmiSrc;
+ DWORD cbBmiSrc;
+ DWORD offBitsSrc;
+ DWORD cbBitsSrc;
+ LONG cxSrc;
+ LONG cySrc;
+ } EMRTRANSPARENTBLT,*PEMRTRANSPARENTBLT;
+
+#define GDICOMMENT_IDENTIFIER 0x43494447
+#define GDICOMMENT_WINDOWS_METAFILE 0x80000001
+#define GDICOMMENT_BEGINGROUP 0x00000002
+#define GDICOMMENT_ENDGROUP 0x00000003
+#define GDICOMMENT_MULTIFORMATS 0x40000004
+#define EPS_SIGNATURE 0x46535045
+#define GDICOMMENT_UNICODE_STRING 0x00000040
+#define GDICOMMENT_UNICODE_END 0x00000080
+#endif
+
+#ifdef UNICODE
+#define wglUseFontBitmaps wglUseFontBitmapsW
+#else
+#define wglUseFontBitmaps wglUseFontBitmapsA
+#endif
+
+ WINGDIAPI WINBOOL WINAPI wglCopyContext(HGLRC,HGLRC,UINT);
+ WINGDIAPI HGLRC WINAPI wglCreateContext(HDC);
+ WINGDIAPI HGLRC WINAPI wglCreateLayerContext(HDC,int);
+ WINGDIAPI WINBOOL WINAPI wglDeleteContext(HGLRC);
+ WINGDIAPI HGLRC WINAPI wglGetCurrentContext(VOID);
+ WINGDIAPI HDC WINAPI wglGetCurrentDC(VOID);
+ WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR);
+ WINGDIAPI WINBOOL WINAPI wglMakeCurrent(HDC,HGLRC);
+ WINGDIAPI WINBOOL WINAPI wglShareLists(HGLRC,HGLRC);
+ WINGDIAPI WINBOOL WINAPI wglUseFontBitmapsA(HDC,DWORD,DWORD,DWORD);
+ WINGDIAPI WINBOOL WINAPI wglUseFontBitmapsW(HDC,DWORD,DWORD,DWORD);
+ WINGDIAPI WINBOOL WINAPI SwapBuffers(HDC);
+
+ typedef struct _POINTFLOAT {
+ FLOAT x;
+ FLOAT y;
+ } POINTFLOAT,*PPOINTFLOAT;
+
+ typedef struct _GLYPHMETRICSFLOAT {
+ FLOAT gmfBlackBoxX;
+ FLOAT gmfBlackBoxY;
+ POINTFLOAT gmfptGlyphOrigin;
+ FLOAT gmfCellIncX;
+ FLOAT gmfCellIncY;
+ } GLYPHMETRICSFLOAT,*PGLYPHMETRICSFLOAT,*LPGLYPHMETRICSFLOAT;
+
+#define WGL_FONT_LINES 0
+#define WGL_FONT_POLYGONS 1
+
+#ifdef UNICODE
+#define wglUseFontOutlines wglUseFontOutlinesW
+#else
+#define wglUseFontOutlines wglUseFontOutlinesA
+#endif
+
+ WINGDIAPI WINBOOL WINAPI wglUseFontOutlinesA(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT);
+ WINGDIAPI WINBOOL WINAPI wglUseFontOutlinesW(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT);
+
+ typedef struct tagLAYERPLANEDESCRIPTOR {
+ WORD nSize;
+ WORD nVersion;
+ DWORD dwFlags;
+ BYTE iPixelType;
+ BYTE cColorBits;
+ BYTE cRedBits;
+ BYTE cRedShift;
+ BYTE cGreenBits;
+ BYTE cGreenShift;
+ BYTE cBlueBits;
+ BYTE cBlueShift;
+ BYTE cAlphaBits;
+ BYTE cAlphaShift;
+ BYTE cAccumBits;
+ BYTE cAccumRedBits;
+ BYTE cAccumGreenBits;
+ BYTE cAccumBlueBits;
+ BYTE cAccumAlphaBits;
+ BYTE cDepthBits;
+ BYTE cStencilBits;
+ BYTE cAuxBuffers;
+ BYTE iLayerPlane;
+ BYTE bReserved;
+ COLORREF crTransparent;
+ } LAYERPLANEDESCRIPTOR,*PLAYERPLANEDESCRIPTOR,*LPLAYERPLANEDESCRIPTOR;
+
+#define LPD_DOUBLEBUFFER 0x00000001
+#define LPD_STEREO 0x00000002
+#define LPD_SUPPORT_GDI 0x00000010
+#define LPD_SUPPORT_OPENGL 0x00000020
+#define LPD_SHARE_DEPTH 0x00000040
+#define LPD_SHARE_STENCIL 0x00000080
+#define LPD_SHARE_ACCUM 0x00000100
+#define LPD_SWAP_EXCHANGE 0x00000200
+#define LPD_SWAP_COPY 0x00000400
+#define LPD_TRANSPARENT 0x00001000
+
+#define LPD_TYPE_RGBA 0
+#define LPD_TYPE_COLORINDEX 1
+
+#define WGL_SWAP_MAIN_PLANE 0x00000001
+#define WGL_SWAP_OVERLAY1 0x00000002
+#define WGL_SWAP_OVERLAY2 0x00000004
+#define WGL_SWAP_OVERLAY3 0x00000008
+#define WGL_SWAP_OVERLAY4 0x00000010
+#define WGL_SWAP_OVERLAY5 0x00000020
+#define WGL_SWAP_OVERLAY6 0x00000040
+#define WGL_SWAP_OVERLAY7 0x00000080
+#define WGL_SWAP_OVERLAY8 0x00000100
+#define WGL_SWAP_OVERLAY9 0x00000200
+#define WGL_SWAP_OVERLAY10 0x00000400
+#define WGL_SWAP_OVERLAY11 0x00000800
+#define WGL_SWAP_OVERLAY12 0x00001000
+#define WGL_SWAP_OVERLAY13 0x00002000
+#define WGL_SWAP_OVERLAY14 0x00004000
+#define WGL_SWAP_OVERLAY15 0x00008000
+#define WGL_SWAP_UNDERLAY1 0x00010000
+#define WGL_SWAP_UNDERLAY2 0x00020000
+#define WGL_SWAP_UNDERLAY3 0x00040000
+#define WGL_SWAP_UNDERLAY4 0x00080000
+#define WGL_SWAP_UNDERLAY5 0x00100000
+#define WGL_SWAP_UNDERLAY6 0x00200000
+#define WGL_SWAP_UNDERLAY7 0x00400000
+#define WGL_SWAP_UNDERLAY8 0x00800000
+#define WGL_SWAP_UNDERLAY9 0x01000000
+#define WGL_SWAP_UNDERLAY10 0x02000000
+#define WGL_SWAP_UNDERLAY11 0x04000000
+#define WGL_SWAP_UNDERLAY12 0x08000000
+#define WGL_SWAP_UNDERLAY13 0x10000000
+#define WGL_SWAP_UNDERLAY14 0x20000000
+#define WGL_SWAP_UNDERLAY15 0x40000000
+
+ WINGDIAPI WINBOOL WINAPI wglDescribeLayerPlane(HDC,int,int,UINT,LPLAYERPLANEDESCRIPTOR);
+ WINGDIAPI int WINAPI wglSetLayerPaletteEntries(HDC,int,int,int,CONST COLORREF *);
+ WINGDIAPI int WINAPI wglGetLayerPaletteEntries(HDC,int,int,int,COLORREF *);
+ WINGDIAPI WINBOOL WINAPI wglRealizeLayerPalette(HDC,int,WINBOOL);
+ WINGDIAPI WINBOOL WINAPI wglSwapLayerBuffers(HDC,UINT);
+
+ typedef struct _WGLSWAP {
+ HDC hdc;
+ UINT uiFlags;
+ } WGLSWAP,*PWGLSWAP,*LPWGLSWAP;
+
+#define WGL_SWAPMULTIPLE_MAX 16
+
+ WINGDIAPI DWORD WINAPI wglSwapMultipleBuffers(UINT,CONST WGLSWAP *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/include/winapi/winnt.h b/win32/include/winapi/winnt.h
new file mode 100644
index 0000000..4cf685d
--- /dev/null
+++ b/win32/include/winapi/winnt.h
@@ -0,0 +1,5835 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _WINNT_
+#define _WINNT_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <ctype.h>
+#define ANYSIZE_ARRAY 1
+
+//gr #include <specstrings.h>
+
+#define RESTRICTED_POINTER
+
+#ifndef __CRT_UNALIGNED
+#define __CRT_UNALIGNED
+#endif
+
+#if defined(__ia64__) || defined(__x86_64)
+#define UNALIGNED __CRT_UNALIGNED
+#ifdef _WIN64
+#define UNALIGNED64 __CRT_UNALIGNED
+#else
+#define UNALIGNED64
+#endif
+#else
+#define UNALIGNED
+#define UNALIGNED64
+#endif
+
+#if !defined(I_X86_) && !defined(_IA64_) && !defined(_AMD64_) && (defined(_X86_) && !defined(__x86_64))
+#define I_X86_
+#endif
+
+#if !defined(I_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(__x86_64)
+#define _AMD64_
+#endif
+
+#if !defined(I_X86_) && !(defined(_X86_) && !defined(__x86_64)) && !defined(_AMD64_) && defined(__ia64__)
+#if !defined(_IA64_)
+#define _IA64_
+#endif
+#endif
+
+
+#ifdef _WIN64
+#define MAX_NATURAL_ALIGNMENT sizeof(ULONGLONG)
+#define MEMORY_ALLOCATION_ALIGNMENT 16
+#else
+#define MAX_NATURAL_ALIGNMENT sizeof(DWORD)
+#define MEMORY_ALLOCATION_ALIGNMENT 8
+#endif
+
+#ifdef __cplusplus
+#define TYPE_ALIGNMENT(t) __alignof__ (t)
+#else
+#define TYPE_ALIGNMENT(t) FIELD_OFFSET(struct { char x; t test; },test)
+#endif
+
+#ifdef _WIN64
+#ifdef _AMD64_
+#define PROBE_ALIGNMENT(_s) TYPE_ALIGNMENT(DWORD)
+#elif defined(_IA64_)
+#define PROBE_ALIGNMENT(_s) (TYPE_ALIGNMENT(_s) > TYPE_ALIGNMENT(DWORD) ? TYPE_ALIGNMENT(_s) : TYPE_ALIGNMENT(DWORD))
+#else
+#error No Target Architecture
+#endif
+#define PROBE_ALIGNMENT32(_s) TYPE_ALIGNMENT(DWORD)
+#else
+#define PROBE_ALIGNMENT(_s) TYPE_ALIGNMENT(DWORD)
+#endif
+
+#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
+
+#include <basetsd.h>
+
+#if defined(_X86_) || defined(__ia64__) || defined(__x86_64)
+#define DECLSPEC_IMPORT __declspec(dllimport)
+#else
+#define DECLSPEC_IMPORT
+#endif
+
+#ifndef DECLSPEC_NORETURN
+#define DECLSPEC_NORETURN __declspec(noreturn)
+#endif
+
+#ifndef DECLSPEC_ALIGN
+#define DECLSPEC_ALIGN(x) __attribute__ ((aligned(x)))
+#endif
+
+#ifndef SYSTEM_CACHE_ALIGNMENT_SIZE
+#if defined(_AMD64_) || defined(I_X86_)
+#define SYSTEM_CACHE_ALIGNMENT_SIZE 64
+#else
+#define SYSTEM_CACHE_ALIGNMENT_SIZE 128
+#endif
+#endif
+
+#ifndef DECLSPEC_CACHEALIGN
+#define DECLSPEC_CACHEALIGN DECLSPEC_ALIGN(SYSTEM_CACHE_ALIGNMENT_SIZE)
+#endif
+
+#ifndef DECLSPEC_UUID
+#define DECLSPEC_UUID(x)
+#endif
+
+#ifndef DECLSPEC_NOVTABLE
+#define DECLSPEC_NOVTABLE
+#endif
+
+#ifndef DECLSPEC_SELECTANY
+#define DECLSPEC_SELECTANY __declspec(selectany)
+#endif
+
+#ifndef NOP_FUNCTION
+#define NOP_FUNCTION (void)0
+#endif
+
+#ifndef DECLSPEC_NOINLINE
+#define DECLSPEC_NOINLINE
+#endif
+
+#ifndef FORCEINLINE
+#define FORCEINLINE static __inline__
+#endif
+
+#ifndef DECLSPEC_DEPRECATED
+#define DECLSPEC_DEPRECATED __declspec(deprecated)
+#define DEPRECATE_SUPPORTED
+#endif
+
+#define DECLSPEC_DEPRECATED_DDK
+#define PRAGMA_DEPRECATED_DDK 0
+
+ typedef void *PVOID;
+ typedef void *PVOID64;
+
+#define NTAPI __stdcall
+#define NTSYSAPI DECLSPEC_IMPORT
+#define NTSYSCALLAPI DECLSPEC_IMPORT
+
+#ifndef VOID
+#define VOID void
+ typedef char CHAR;
+ typedef short SHORT;
+ typedef long LONG;
+#endif
+
+ typedef wchar_t WCHAR;
+ typedef WCHAR *PWCHAR,*LPWCH,*PWCH;
+ typedef CONST WCHAR *LPCWCH,*PCWCH;
+ typedef WCHAR *NWPSTR,*LPWSTR,*PWSTR;
+ typedef PWSTR *PZPWSTR;
+ typedef CONST PWSTR *PCZPWSTR;
+ typedef WCHAR UNALIGNED *LPUWSTR,*PUWSTR;
+ typedef CONST WCHAR *LPCWSTR,*PCWSTR;
+ typedef PCWSTR *PZPCWSTR;
+ typedef CONST WCHAR UNALIGNED *LPCUWSTR,*PCUWSTR;
+ typedef CHAR *PCHAR,*LPCH,*PCH;
+ typedef CONST CHAR *LPCCH,*PCCH;
+ typedef CHAR *NPSTR,*LPSTR,*PSTR;
+ typedef PSTR *PZPSTR;
+ typedef CONST PSTR *PCZPSTR;
+ typedef CONST CHAR *LPCSTR,*PCSTR;
+ typedef PCSTR *PZPCSTR;
+
+#ifdef UNICODE
+#ifndef _TCHAR_DEFINED
+#define _TCHAR_DEFINED
+ typedef WCHAR TCHAR,*PTCHAR;
+ typedef WCHAR TBYTE ,*PTBYTE;
+#endif
+
+ typedef LPWSTR LPTCH,PTCH;
+ typedef LPWSTR PTSTR,LPTSTR;
+ typedef LPCWSTR PCTSTR,LPCTSTR;
+ typedef LPUWSTR PUTSTR,LPUTSTR;
+ typedef LPCUWSTR PCUTSTR,LPCUTSTR;
+ typedef LPWSTR LP;
+#define __TEXT(quote) L##quote
+#else
+#ifndef _TCHAR_DEFINED
+#define _TCHAR_DEFINED
+ typedef char TCHAR,*PTCHAR;
+ typedef unsigned char TBYTE ,*PTBYTE;
+#endif
+
+ typedef LPSTR LPTCH,PTCH;
+ typedef LPSTR PTSTR,LPTSTR,PUTSTR,LPUTSTR;
+ typedef LPCSTR PCTSTR,LPCTSTR,PCUTSTR,LPCUTSTR;
+#define __TEXT(quote) quote
+#endif
+
+#define TEXT(quote) __TEXT(quote)
+
+ typedef SHORT *PSHORT;
+ typedef LONG *PLONG;
+
+ typedef void *HANDLE;
+#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
+ typedef HANDLE *PHANDLE;
+
+ typedef BYTE FCHAR;
+ typedef WORD FSHORT;
+ typedef DWORD FLONG;
+
+#ifndef _HRESULT_DEFINED
+#define _HRESULT_DEFINED
+ typedef LONG HRESULT;
+#endif
+
+#ifdef __cplusplus
+#define EXTERN_C extern "C"
+#else
+#define EXTERN_C extern
+#endif
+
+#define STDMETHODCALLTYPE WINAPI
+#define STDMETHODVCALLTYPE __cdecl
+#define STDAPICALLTYPE WINAPI
+#define STDAPIVCALLTYPE __cdecl
+#define STDAPI EXTERN_C HRESULT WINAPI
+#define STDAPI_(type) EXTERN_C type WINAPI
+#define STDMETHODIMP HRESULT WINAPI
+#define STDMETHODIMP_(type) type WINAPI
+#define STDAPIV EXTERN_C HRESULT STDAPIVCALLTYPE
+#define STDAPIV_(type) EXTERN_C type STDAPIVCALLTYPE
+#define STDMETHODIMPV HRESULT STDMETHODVCALLTYPE
+#define STDMETHODIMPV_(type) type STDMETHODVCALLTYPE
+
+ typedef char CCHAR;
+#ifndef _LCID_DEFINED
+#define _LCID_DEFINED
+typedef DWORD LCID;
+#endif
+ typedef PDWORD PLCID;
+#ifndef _LANGID_DEFINED
+#define _LANGID_DEFINED
+ typedef WORD LANGID;
+#endif
+#define APPLICATION_ERROR_MASK 0x20000000
+#define ERROR_SEVERITY_SUCCESS 0x00000000
+#define ERROR_SEVERITY_INFORMATIONAL 0x40000000
+#define ERROR_SEVERITY_WARNING 0x80000000
+#define ERROR_SEVERITY_ERROR 0xC0000000
+
+#ifdef __ia64__
+ __declspec(align(16))
+#endif
+ typedef struct _FLOAT128 {
+ __int64 LowPart;
+ __int64 HighPart;
+ } FLOAT128;
+
+ typedef FLOAT128 *PFLOAT128;
+
+#define _ULONGLONG_
+#if((!(defined(_X86_) && !defined(__x86_64)) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64)))
+ typedef __int64 LONGLONG;
+ typedef unsigned __int64 ULONGLONG;
+
+#define MAXLONGLONG (0x7fffffffffffffff)
+#else
+
+ typedef double LONGLONG;
+ typedef double ULONGLONG;
+#endif
+
+ typedef LONGLONG *PLONGLONG;
+ typedef ULONGLONG *PULONGLONG;
+
+ typedef LONGLONG USN;
+
+ typedef union _LARGE_INTEGER {
+ struct {
+ DWORD LowPart;
+ LONG HighPart;
+ };
+ struct {
+ DWORD LowPart;
+ LONG HighPart;
+ } u;
+ LONGLONG QuadPart;
+ } LARGE_INTEGER;
+
+ typedef LARGE_INTEGER *PLARGE_INTEGER;
+
+ typedef union _ULARGE_INTEGER {
+ struct {
+ DWORD LowPart;
+ DWORD HighPart;
+ };
+ struct {
+ DWORD LowPart;
+ DWORD HighPart;
+ } u;
+ ULONGLONG QuadPart;
+ } ULARGE_INTEGER;
+
+ typedef ULARGE_INTEGER *PULARGE_INTEGER;
+
+ typedef struct _LUID {
+ DWORD LowPart;
+ LONG HighPart;
+ } LUID,*PLUID;
+
+#define _DWORDLONG_
+ typedef ULONGLONG DWORDLONG;
+ typedef DWORDLONG *PDWORDLONG;
+
+#ifdef RC_INVOKED
+#define Int32x32To64(a,b) ((LONGLONG)((LONG)(a)) *(LONGLONG)((LONG)(b)))
+#define UInt32x32To64(a,b) ((ULONGLONG)((DWORD)(a)) *(ULONGLONG)((DWORD)(b)))
+#define Int64ShrlMod32(a,b) ((ULONGLONG)(a) >> (b))
+#elif (defined(_X86_) && !defined(__x86_64))
+#define Int32x32To64(a,b) (LONGLONG)((LONGLONG)(LONG)(a) *(LONG)(b))
+#define UInt32x32To64(a,b) (ULONGLONG)((ULONGLONG)(DWORD)(a) *(DWORD)(b))
+#define Int64ShrlMod32(a,b) ((DWORDLONG)(a)>>(b))
+#elif defined(__ia64__) || defined(__x86_64)
+#define Int32x32To64(a,b) ((LONGLONG)((LONG)(a)) *(LONGLONG)((LONG)(b)))
+#define UInt32x32To64(a,b) ((ULONGLONG)((DWORD)(a)) *(ULONGLONG)((DWORD)(b)))
+#define Int64ShrlMod32(a,b) ((ULONGLONG)(a) >> (b))
+#else
+#error Must define a target architecture.
+#endif
+
+#define Int64ShraMod32(a,b) ((LONGLONG)(a) >> (b))
+#define Int64ShllMod32(a,b) ((ULONGLONG)(a) << (b))
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifdef __x86_64
+
+#define RotateLeft8 _rotl8
+#define RotateLeft16 _rotl16
+#define RotateRight8 _rotr8
+#define RotateRight16 _rotr16
+
+ unsigned char __cdecl _rotl8(unsigned char Value,unsigned char Shift);
+ unsigned short __cdecl _rotl16(unsigned short Value,unsigned char Shift);
+ unsigned char __cdecl _rotr8(unsigned char Value,unsigned char Shift);
+ unsigned short __cdecl _rotr16(unsigned short Value,unsigned char Shift);
+#endif
+
+#define RotateLeft32 _rotl
+#define RotateLeft64 _rotl64
+#define RotateRight32 _rotr
+#define RotateRight64 _rotr64
+
+ unsigned int __cdecl _rotl(unsigned int Value,int Shift);
+ unsigned __int64 __cdecl _rotl64(unsigned __int64 Value,int Shift);
+ unsigned int __cdecl _rotr(unsigned int Value,int Shift);
+ unsigned __int64 __cdecl _rotr64(unsigned __int64 Value,int Shift);
+#ifdef __cplusplus
+ }
+#endif
+
+#define ANSI_NULL ((CHAR)0)
+#define UNICODE_NULL ((WCHAR)0)
+#define UNICODE_STRING_MAX_BYTES ((WORD) 65534)
+#define UNICODE_STRING_MAX_CHARS (32767)
+
+#ifndef _BOOLEAN_
+#define _BOOLEAN_
+ typedef BYTE BOOLEAN;
+#endif
+ typedef BOOLEAN *PBOOLEAN;
+
+ typedef struct _LIST_ENTRY {
+ struct _LIST_ENTRY *Flink;
+ struct _LIST_ENTRY *Blink;
+ } LIST_ENTRY,*PLIST_ENTRY,*RESTRICTED_POINTER PRLIST_ENTRY;
+
+ typedef struct _SINGLE_LIST_ENTRY {
+ struct _SINGLE_LIST_ENTRY *Next;
+ } SINGLE_LIST_ENTRY,*PSINGLE_LIST_ENTRY;
+
+ typedef struct LIST_ENTRY32 {
+ DWORD Flink;
+ DWORD Blink;
+ } LIST_ENTRY32;
+ typedef LIST_ENTRY32 *PLIST_ENTRY32;
+
+ typedef struct LIST_ENTRY64 {
+ ULONGLONG Flink;
+ ULONGLONG Blink;
+ } LIST_ENTRY64;
+ typedef LIST_ENTRY64 *PLIST_ENTRY64;
+
+#include <guiddef.h>
+
+#ifndef __OBJECTID_DEFINED
+#define __OBJECTID_DEFINED
+ typedef struct _OBJECTID {
+ GUID Lineage;
+ DWORD Uniquifier;
+ } OBJECTID;
+#endif
+
+#define MINCHAR 0x80
+#define MAXCHAR 0x7f
+#define MINSHORT 0x8000
+#define MAXSHORT 0x7fff
+#define MINLONG 0x80000000
+#define MAXLONG 0x7fffffff
+#define MAXBYTE 0xff
+#define MAXWORD 0xffff
+#define MAXDWORD 0xffffffff
+
+#define FIELD_OFFSET(type,field) ((LONG)(LONG_PTR)&(((type *)0)->field))
+#define RTL_FIELD_SIZE(type,field) (sizeof(((type *)0)->field))
+#define RTL_SIZEOF_THROUGH_FIELD(type,field) (FIELD_OFFSET(type,field) + RTL_FIELD_SIZE(type,field))
+#define RTL_CONTAINS_FIELD(Struct,Size,Field) ((((PCHAR)(&(Struct)->Field)) + sizeof((Struct)->Field)) <= (((PCHAR)(Struct))+(Size)))
+#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0]))
+#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A)
+
+#ifdef ENABLE_RTL_NUMBER_OF_V2
+#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V2(A)
+#else
+#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V1(A)
+#endif
+
+#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)
+#define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A)
+
+#define RTL_FIELD_TYPE(type,field) (((type*)0)->field)
+#define RTL_NUMBER_OF_FIELD(type,field) (RTL_NUMBER_OF(RTL_FIELD_TYPE(type,field)))
+#define RTL_PADDING_BETWEEN_FIELDS(T,F1,F2) ((FIELD_OFFSET(T,F2) > FIELD_OFFSET(T,F1)) ? (FIELD_OFFSET(T,F2) - FIELD_OFFSET(T,F1) - RTL_FIELD_SIZE(T,F1)) : (FIELD_OFFSET(T,F1) - FIELD_OFFSET(T,F2) - RTL_FIELD_SIZE(T,F2)))
+
+#ifdef __cplusplus
+#define RTL_CONST_CAST(type) const_cast<type>
+#else
+#define RTL_CONST_CAST(type) (type)
+#endif
+
+#define RTL_BITS_OF(sizeOfArg) (sizeof(sizeOfArg) *8)
+#define RTL_BITS_OF_FIELD(type,field) (RTL_BITS_OF(RTL_FIELD_TYPE(type,field)))
+#define CONTAINING_RECORD(address,type,field) ((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))
+
+#define VER_SERVER_NT 0x80000000
+#define VER_WORKSTATION_NT 0x40000000
+#define VER_SUITE_SMALLBUSINESS 0x00000001
+#define VER_SUITE_ENTERPRISE 0x00000002
+#define VER_SUITE_BACKOFFICE 0x00000004
+#define VER_SUITE_COMMUNICATIONS 0x00000008
+#define VER_SUITE_TERMINAL 0x00000010
+#define VER_SUITE_SMALLBUSINESS_RESTRICTED 0x00000020
+#define VER_SUITE_EMBEDDEDNT 0x00000040
+#define VER_SUITE_DATACENTER 0x00000080
+#define VER_SUITE_SINGLEUSERTS 0x00000100
+#define VER_SUITE_PERSONAL 0x00000200
+#define VER_SUITE_BLADE 0x00000400
+#define VER_SUITE_EMBEDDED_RESTRICTED 0x00000800
+#define VER_SUITE_SECURITY_APPLIANCE 0x00001000
+#define VER_SUITE_STORAGE_SERVER 0x00002000
+#define VER_SUITE_COMPUTE_SERVER 0x00004000
+
+#define PRODUCT_UNDEFINED 0x0
+
+#define PRODUCT_ULTIMATE 0x1
+#define PRODUCT_HOME_BASIC 0x2
+#define PRODUCT_HOME_PREMIUM 0x3
+#define PRODUCT_ENTERPRISE 0x4
+#define PRODUCT_HOME_BASIC_N 0x5
+#define PRODUCT_BUSINESS 0x6
+#define PRODUCT_STANDARD_SERVER 0x7
+#define PRODUCT_DATACENTER_SERVER 0x8
+#define PRODUCT_SMALLBUSINESS_SERVER 0x9
+#define PRODUCT_ENTERPRISE_SERVER 0xa
+#define PRODUCT_STARTER 0xb
+#define PRODUCT_DATACENTER_SERVER_CORE 0xc
+#define PRODUCT_STANDARD_SERVER_CORE 0xd
+#define PRODUCT_ENTERPRISE_SERVER_CORE 0xe
+#define PRODUCT_ENTERPRISE_SERVER_IA64 0xf
+#define PRODUCT_BUSINESS_N 0x10
+#define PRODUCT_WEB_SERVER 0x11
+#define PRODUCT_CLUSTER_SERVER 0x12
+#define PRODUCT_HOME_SERVER 0x13
+#define PRODUCT_STORAGE_EXPRESS_SERVER 0x14
+#define PRODUCT_STORAGE_STANDARD_SERVER 0x15
+#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x16
+#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x17
+#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x18
+#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x19
+
+#define PRODUCT_UNLICENSED 0xabcdabcd
+
+#define LANG_NEUTRAL 0x00
+#define LANG_INVARIANT 0x7f
+
+#define LANG_AFRIKAANS 0x36
+#define LANG_ALBANIAN 0x1c
+#define LANG_ALSATIAN 0x84
+#define LANG_AMHARIC 0x5e
+#define LANG_ARABIC 0x01
+#define LANG_ARMENIAN 0x2b
+#define LANG_ASSAMESE 0x4d
+#define LANG_AZERI 0x2c
+#define LANG_BASHKIR 0x6d
+#define LANG_BASQUE 0x2d
+#define LANG_BELARUSIAN 0x23
+#define LANG_BENGALI 0x45
+#define LANG_BRETON 0x7e
+#define LANG_BOSNIAN 0x1a
+#define LANG_BOSNIAN_NEUTRAL 0x781a
+#define LANG_BULGARIAN 0x02
+#define LANG_CATALAN 0x03
+#define LANG_CHINESE 0x04
+#define LANG_CHINESE_SIMPLIFIED 0x04
+#define LANG_CHINESE_TRADITIONAL 0x7c04
+#define LANG_CORSICAN 0x83
+#define LANG_CROATIAN 0x1a
+#define LANG_CZECH 0x05
+#define LANG_DANISH 0x06
+#define LANG_DARI 0x8c
+#define LANG_DIVEHI 0x65
+#define LANG_DUTCH 0x13
+#define LANG_ENGLISH 0x09
+#define LANG_ESTONIAN 0x25
+#define LANG_FAEROESE 0x38
+#define LANG_FARSI 0x29
+#define LANG_FILIPINO 0x64
+#define LANG_FINNISH 0x0b
+#define LANG_FRENCH 0x0c
+#define LANG_FRISIAN 0x62
+#define LANG_GALICIAN 0x56
+#define LANG_GEORGIAN 0x37
+#define LANG_GERMAN 0x07
+#define LANG_GREEK 0x08
+#define LANG_GREENLANDIC 0x6f
+#define LANG_GUJARATI 0x47
+#define LANG_HAUSA 0x68
+#define LANG_HEBREW 0x0d
+#define LANG_HINDI 0x39
+#define LANG_HUNGARIAN 0x0e
+#define LANG_ICELANDIC 0x0f
+#define LANG_IGBO 0x70
+#define LANG_INDONESIAN 0x21
+#define LANG_INUKTITUT 0x5d
+#define LANG_IRISH 0x3c
+#define LANG_ITALIAN 0x10
+#define LANG_JAPANESE 0x11
+#define LANG_KANNADA 0x4b
+#define LANG_KASHMIRI 0x60
+#define LANG_KAZAK 0x3f
+#define LANG_KHMER 0x53
+#define LANG_KICHE 0x86
+#define LANG_KINYARWANDA 0x87
+#define LANG_KONKANI 0x57
+#define LANG_KOREAN 0x12
+#define LANG_KYRGYZ 0x40
+#define LANG_LAO 0x54
+#define LANG_LATVIAN 0x26
+#define LANG_LITHUANIAN 0x27
+#define LANG_LOWER_SORBIAN 0x2e
+#define LANG_LUXEMBOURGISH 0x6e
+#define LANG_MACEDONIAN 0x2f
+#define LANG_MALAY 0x3e
+#define LANG_MALAYALAM 0x4c
+#define LANG_MALTESE 0x3a
+#define LANG_MANIPURI 0x58
+#define LANG_MAORI 0x81
+#define LANG_MAPUDUNGUN 0x7a
+#define LANG_MARATHI 0x4e
+#define LANG_MOHAWK 0x7c
+#define LANG_MONGOLIAN 0x50
+#define LANG_NEPALI 0x61
+#define LANG_NORWEGIAN 0x14
+#define LANG_OCCITAN 0x82
+#define LANG_ORIYA 0x48
+#define LANG_PASHTO 0x63
+#define LANG_PERSIAN 0x29
+#define LANG_POLISH 0x15
+#define LANG_PORTUGUESE 0x16
+#define LANG_PUNJABI 0x46
+#define LANG_QUECHUA 0x6b
+#define LANG_ROMANIAN 0x18
+#define LANG_RUSSIAN 0x19
+#define LANG_SAMI 0x3b
+#define LANG_ROMANSH 0x17
+#define LANG_SANSKRIT 0x4f
+#define LANG_SERBIAN 0x1a
+#define LANG_SERBIAN_NEUTRAL 0x7c1a
+#define LANG_SINDHI 0x59
+#define LANG_SINHALESE 0x5b
+#define LANG_SLOVAK 0x1b
+#define LANG_SLOVENIAN 0x24
+#define LANG_SOTHO 0x6c
+#define LANG_SPANISH 0x0a
+#define LANG_SWAHILI 0x41
+#define LANG_SWEDISH 0x1d
+#define LANG_SYRIAC 0x5a
+#define LANG_TAJIK 0x28
+#define LANG_TAMAZIGHT 0x5f
+#define LANG_TAMIL 0x49
+#define LANG_TATAR 0x44
+#define LANG_TELUGU 0x4a
+#define LANG_THAI 0x1e
+#define LANG_TIBETAN 0x51
+#define LANG_TIGRIGNA 0x73
+#define LANG_TSWANA 0x32
+#define LANG_TURKISH 0x1f
+#define LANG_TURKMEN 0x42
+#define LANG_UIGHUR 0x80
+#define LANG_UKRAINIAN 0x22
+#define LANG_UPPER_SORBIAN 0x2e
+#define LANG_URDU 0x20
+#define LANG_UZBEK 0x43
+#define LANG_VIETNAMESE 0x2a
+#define LANG_WELSH 0x52
+#define LANG_WOLOF 0x88
+#define LANG_XHOSA 0x34
+#define LANG_YAKUT 0x85
+#define LANG_YI 0x78
+#define LANG_YORUBA 0x6a
+#define LANG_ZULU 0x35
+
+#define SUBLANG_NEUTRAL 0x0
+#define SUBLANG_DEFAULT 0x1
+#define SUBLANG_SYS_DEFAULT 0x2
+#define SUBLANG_CUSTOM_DEFAULT 0x3
+#define SUBLANG_CUSTOM_UNSPECIFIED 0x4
+#define SUBLANG_UI_CUSTOM_DEFAULT 0x5
+
+#define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
+#define SUBLANG_ARABIC_IRAQ 0x02
+#define SUBLANG_ARABIC_EGYPT 0x03
+#define SUBLANG_ARABIC_LIBYA 0x04
+#define SUBLANG_ARABIC_ALGERIA 0x05
+#define SUBLANG_ARABIC_MOROCCO 0x06
+#define SUBLANG_ARABIC_TUNISIA 0x07
+#define SUBLANG_ARABIC_OMAN 0x08
+#define SUBLANG_ARABIC_YEMEN 0x09
+#define SUBLANG_ARABIC_SYRIA 0x0a
+#define SUBLANG_ARABIC_JORDAN 0x0b
+#define SUBLANG_ARABIC_LEBANON 0x0c
+#define SUBLANG_ARABIC_KUWAIT 0x0d
+#define SUBLANG_ARABIC_UAE 0x0e
+#define SUBLANG_ARABIC_BAHRAIN 0x0f
+#define SUBLANG_ARABIC_QATAR 0x10
+#define SUBLANG_AZERI_LATIN 0x01
+#define SUBLANG_AZERI_CYRILLIC 0x02
+#define SUBLANG_CHINESE_TRADITIONAL 0x01
+#define SUBLANG_CHINESE_SIMPLIFIED 0x02
+#define SUBLANG_CHINESE_HONGKONG 0x03
+#define SUBLANG_CHINESE_SINGAPORE 0x04
+#define SUBLANG_CHINESE_MACAU 0x05
+#define SUBLANG_DUTCH 0x01
+#define SUBLANG_DUTCH_BELGIAN 0x02
+#define SUBLANG_ENGLISH_US 0x01
+#define SUBLANG_ENGLISH_UK 0x02
+#define SUBLANG_ENGLISH_AUS 0x03
+#define SUBLANG_ENGLISH_CAN 0x04
+#define SUBLANG_ENGLISH_NZ 0x05
+#define SUBLANG_ENGLISH_EIRE 0x06
+#define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
+#define SUBLANG_ENGLISH_JAMAICA 0x08
+#define SUBLANG_ENGLISH_CARIBBEAN 0x09
+#define SUBLANG_ENGLISH_BELIZE 0x0a
+#define SUBLANG_ENGLISH_TRINIDAD 0x0b
+#define SUBLANG_ENGLISH_ZIMBABWE 0x0c
+#define SUBLANG_ENGLISH_PHILIPPINES 0x0d
+#define SUBLANG_FRENCH 0x01
+#define SUBLANG_FRENCH_BELGIAN 0x02
+#define SUBLANG_FRENCH_CANADIAN 0x03
+#define SUBLANG_FRENCH_SWISS 0x04
+#define SUBLANG_FRENCH_LUXEMBOURG 0x05
+#define SUBLANG_FRENCH_MONACO 0x06
+#define SUBLANG_GERMAN 0x01
+#define SUBLANG_GERMAN_SWISS 0x02
+#define SUBLANG_GERMAN_AUSTRIAN 0x03
+#define SUBLANG_GERMAN_LUXEMBOURG 0x04
+#define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
+#define SUBLANG_ITALIAN 0x01
+#define SUBLANG_ITALIAN_SWISS 0x02
+#define SUBLANG_KASHMIRI_SASIA 0x02
+#define SUBLANG_KASHMIRI_INDIA 0x02
+#define SUBLANG_KOREAN 0x01
+#define SUBLANG_LITHUANIAN 0x01
+#define SUBLANG_MALAY_MALAYSIA 0x01
+#define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
+#define SUBLANG_NEPALI_INDIA 0x02
+#define SUBLANG_NORWEGIAN_BOKMAL 0x01
+#define SUBLANG_NORWEGIAN_NYNORSK 0x02
+#define SUBLANG_PORTUGUESE 0x02
+#define SUBLANG_PORTUGUESE_BRAZILIAN 0x01
+#define SUBLANG_SERBIAN_LATIN 0x02
+#define SUBLANG_SERBIAN_CYRILLIC 0x03
+#define SUBLANG_SPANISH 0x01
+#define SUBLANG_SPANISH_MEXICAN 0x02
+#define SUBLANG_SPANISH_MODERN 0x03
+#define SUBLANG_SPANISH_GUATEMALA 0x04
+#define SUBLANG_SPANISH_COSTA_RICA 0x05
+#define SUBLANG_SPANISH_PANAMA 0x06
+#define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
+#define SUBLANG_SPANISH_VENEZUELA 0x08
+#define SUBLANG_SPANISH_COLOMBIA 0x09
+#define SUBLANG_SPANISH_PERU 0x0a
+#define SUBLANG_SPANISH_ARGENTINA 0x0b
+#define SUBLANG_SPANISH_ECUADOR 0x0c
+#define SUBLANG_SPANISH_CHILE 0x0d
+#define SUBLANG_SPANISH_URUGUAY 0x0e
+#define SUBLANG_SPANISH_PARAGUAY 0x0f
+#define SUBLANG_SPANISH_BOLIVIA 0x10
+#define SUBLANG_SPANISH_EL_SALVADOR 0x11
+#define SUBLANG_SPANISH_HONDURAS 0x12
+#define SUBLANG_SPANISH_NICARAGUA 0x13
+#define SUBLANG_SPANISH_PUERTO_RICO 0x14
+#define SUBLANG_SWEDISH 0x01
+#define SUBLANG_SWEDISH_FINLAND 0x02
+#define SUBLANG_URDU_PAKISTAN 0x01
+#define SUBLANG_URDU_INDIA 0x02
+#define SUBLANG_UZBEK_LATIN 0x01
+#define SUBLANG_UZBEK_CYRILLIC 0x02
+
+#define SORT_DEFAULT 0x0
+#define SORT_INVARIANT_MATH 0x1
+
+#define SORT_JAPANESE_XJIS 0x0
+#define SORT_JAPANESE_UNICODE 0x1
+#define SORT_JAPANESE_RADICALSTROKE 0x4
+
+#define SORT_CHINESE_BIG5 0x0
+#define SORT_CHINESE_PRCP 0x0
+#define SORT_CHINESE_UNICODE 0x1
+#define SORT_CHINESE_PRC 0x2
+#define SORT_CHINESE_BOPOMOFO 0x3
+
+#define SORT_KOREAN_KSC 0x0
+#define SORT_KOREAN_UNICODE 0x1
+
+#define SORT_GERMAN_PHONE_BOOK 0x1
+
+#define SORT_HUNGARIAN_DEFAULT 0x0
+#define SORT_HUNGARIAN_TECHNICAL 0x1
+
+#define SORT_GEORGIAN_TRADITIONAL 0x0
+#define SORT_GEORGIAN_MODERN 0x1
+
+#define MAKELANGID(p,s) ((((WORD)(s)) << 10) | (WORD)(p))
+#define PRIMARYLANGID(lgid) ((WORD)(lgid) & 0x3ff)
+#define SUBLANGID(lgid) ((WORD)(lgid) >> 10)
+
+#define NLS_VALID_LOCALE_MASK 0x000fffff
+
+#define MAKELCID(lgid,srtid) ((DWORD)((((DWORD)((WORD)(srtid))) << 16) | ((DWORD)((WORD)(lgid)))))
+#define MAKESORTLCID(lgid,srtid,ver) ((DWORD)((MAKELCID(lgid,srtid)) | (((DWORD)((WORD)(ver))) << 20)))
+#define LANGIDFROMLCID(lcid) ((WORD)(lcid))
+#define SORTIDFROMLCID(lcid) ((WORD)((((DWORD)(lcid)) >> 16) & 0xf))
+#define SORTVERSIONFROMLCID(lcid) ((WORD)((((DWORD)(lcid)) >> 20) & 0xf))
+
+#define LOCALE_NAME_MAX_LENGTH 85
+#define LANG_SYSTEM_DEFAULT (MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT))
+#define LANG_USER_DEFAULT (MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT))
+
+#define LOCALE_SYSTEM_DEFAULT (MAKELCID(LANG_SYSTEM_DEFAULT,SORT_DEFAULT))
+#define LOCALE_USER_DEFAULT (MAKELCID(LANG_USER_DEFAULT,SORT_DEFAULT))
+
+#define LOCALE_NEUTRAL (MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT))
+
+#define LOCALE_CUSTOM_DEFAULT (MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_CUSTOM_DEFAULT), SORT_DEFAULT))
+#define LOCALE_CUSTOM_UNSPECIFIED (MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_CUSTOM_UNSPECIFIED), SORT_DEFAULT))
+#define LOCALE_CUSTOM_UI_DEFAULT (MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_UI_CUSTOM_DEFAULT), SORT_DEFAULT))
+
+#define LOCALE_INVARIANT (MAKELCID(MAKELANGID(LANG_INVARIANT,SUBLANG_NEUTRAL),SORT_DEFAULT))
+
+#define UNREFERENCED_PARAMETER(P) (P)
+#define DBG_UNREFERENCED_PARAMETER(P) (P)
+#define DBG_UNREFERENCED_LOCAL_VARIABLE(V) (V)
+
+#define DEFAULT_UNREACHABLE
+
+#ifndef WIN32_NO_STATUS
+#define STATUS_WAIT_0 ((DWORD)0x00000000L)
+#define STATUS_ABANDONED_WAIT_0 ((DWORD)0x00000080L)
+#define STATUS_USER_APC ((DWORD)0x000000C0L)
+#define STATUS_TIMEOUT ((DWORD)0x00000102L)
+#define STATUS_PENDING ((DWORD)0x00000103L)
+#define DBG_EXCEPTION_HANDLED ((DWORD)0x00010001L)
+#define DBG_CONTINUE ((DWORD)0x00010002L)
+#define STATUS_SEGMENT_NOTIFICATION ((DWORD)0x40000005L)
+#define DBG_TERMINATE_THREAD ((DWORD)0x40010003L)
+#define DBG_TERMINATE_PROCESS ((DWORD)0x40010004L)
+#define DBG_CONTROL_C ((DWORD)0x40010005L)
+#define DBG_CONTROL_BREAK ((DWORD)0x40010008L)
+#define DBG_COMMAND_EXCEPTION ((DWORD)0x40010009L)
+#define STATUS_GUARD_PAGE_VIOLATION ((DWORD)0x80000001L)
+#define STATUS_DATATYPE_MISALIGNMENT ((DWORD)0x80000002L)
+#define STATUS_BREAKPOINT ((DWORD)0x80000003L)
+#define STATUS_SINGLE_STEP ((DWORD)0x80000004L)
+#define DBG_EXCEPTION_NOT_HANDLED ((DWORD)0x80010001L)
+#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L)
+#define STATUS_IN_PAGE_ERROR ((DWORD)0xC0000006L)
+#define STATUS_INVALID_HANDLE ((DWORD)0xC0000008L)
+#define STATUS_NO_MEMORY ((DWORD)0xC0000017L)
+#define STATUS_ILLEGAL_INSTRUCTION ((DWORD)0xC000001DL)
+#define STATUS_NONCONTINUABLE_EXCEPTION ((DWORD)0xC0000025L)
+#define STATUS_INVALID_DISPOSITION ((DWORD)0xC0000026L)
+#define STATUS_ARRAY_BOUNDS_EXCEEDED ((DWORD)0xC000008CL)
+#define STATUS_FLOAT_DENORMAL_OPERAND ((DWORD)0xC000008DL)
+#define STATUS_FLOAT_DIVIDE_BY_ZERO ((DWORD)0xC000008EL)
+#define STATUS_FLOAT_INEXACT_RESULT ((DWORD)0xC000008FL)
+#define STATUS_FLOAT_INVALID_OPERATION ((DWORD)0xC0000090L)
+#define STATUS_FLOAT_OVERFLOW ((DWORD)0xC0000091L)
+#define STATUS_FLOAT_STACK_CHECK ((DWORD)0xC0000092L)
+#define STATUS_FLOAT_UNDERFLOW ((DWORD)0xC0000093L)
+#define STATUS_INTEGER_DIVIDE_BY_ZERO ((DWORD)0xC0000094L)
+#define STATUS_INTEGER_OVERFLOW ((DWORD)0xC0000095L)
+#define STATUS_PRIVILEGED_INSTRUCTION ((DWORD)0xC0000096L)
+#define STATUS_STACK_OVERFLOW ((DWORD)0xC00000FDL)
+#define STATUS_CONTROL_C_EXIT ((DWORD)0xC000013AL)
+#define STATUS_FLOAT_MULTIPLE_FAULTS ((DWORD)0xC00002B4L)
+#define STATUS_FLOAT_MULTIPLE_TRAPS ((DWORD)0xC00002B5L)
+#define STATUS_REG_NAT_CONSUMPTION ((DWORD)0xC00002C9L)
+#define STATUS_SXS_EARLY_DEACTIVATION ((DWORD)0xC015000FL)
+#define STATUS_SXS_INVALID_DEACTIVATION ((DWORD)0xC0150010L)
+#endif
+
+#define MAXIMUM_WAIT_OBJECTS 64
+#define MAXIMUM_SUSPEND_COUNT MAXCHAR
+
+ typedef ULONG_PTR KSPIN_LOCK;
+ typedef KSPIN_LOCK *PKSPIN_LOCK;
+
+#ifdef _AMD64_
+
+#if defined(__x86_64) && !defined(RC_INVOKED)
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define BitTest _bittest
+#define BitTestAndComplement _bittestandcomplement
+#define BitTestAndSet _bittestandset
+#define BitTestAndReset _bittestandreset
+#define InterlockedBitTestAndSet _interlockedbittestandset
+#define InterlockedBitTestAndReset _interlockedbittestandreset
+#define BitTest64 _bittest64
+#define BitTestAndComplement64 _bittestandcomplement64
+#define BitTestAndSet64 _bittestandset64
+#define BitTestAndReset64 _bittestandreset64
+#define InterlockedBitTestAndSet64 _interlockedbittestandset64
+#define InterlockedBitTestAndReset64 _interlockedbittestandreset64
+
+ __CRT_INLINE BOOLEAN _bittest(LONG const *Base,LONG Offset) {
+ int old = 0;
+ __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN _bittestandcomplement(LONG *Base,LONG Offset) {
+ int old = 0;
+ __asm__ __volatile__("btcl %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN InterlockedBitTestAndComplement(LONG *Base,LONG Bit) {
+ int old = 0;
+ __asm__ __volatile__("lock ; btcl %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long *) Base))
+ :"Ir" (Bit));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN _bittestandset(LONG *Base,LONG Offset) {
+ int old = 0;
+ __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN _bittestandreset(LONG *Base,LONG Offset) {
+ int old = 0;
+ __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN _interlockedbittestandset(LONG *Base,LONG Offset) {
+ int old = 0;
+ __asm__ __volatile__("lock ; btsl %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN _interlockedbittestandreset(LONG *Base,LONG Offset) {
+ int old = 0;
+ __asm__ __volatile__("lock ; btrl %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN _bittest64(LONG64 const *Base,LONG64 Offset) {
+ int old = 0;
+ __asm__ __volatile__("btq %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN _bittestandcomplement64(LONG64 *Base,LONG64 Offset) {
+ int old = 0;
+ __asm__ __volatile__("btcq %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN _bittestandset64(LONG64 *Base,LONG64 Offset) {
+ int old = 0;
+ __asm__ __volatile__("btsq %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN _bittestandreset64(LONG64 *Base,LONG64 Offset) {
+ int old = 0;
+ __asm__ __volatile__("btrq %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN _interlockedbittestandset64(LONG64 *Base,LONG64 Offset) {
+ int old = 0;
+ __asm__ __volatile__("lock ; btsq %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+ __CRT_INLINE BOOLEAN _interlockedbittestandreset64(LONG64 *Base,LONG64 Offset) {
+ int old = 0;
+ __asm__ __volatile__("lock ; btrq %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long long *) Base))
+ :"Ir" (Offset));
+ return (BOOLEAN) (old!=0);
+ }
+#define BitScanForward _BitScanForward
+#define BitScanReverse _BitScanReverse
+#define BitScanForward64 _BitScanForward64
+#define BitScanReverse64 _BitScanReverse64
+
+ __CRT_INLINE BOOLEAN _BitScanForward(DWORD *Index,DWORD Mask) {
+ __asm__ __volatile__("bsfl %1,%0" : "=r" (Mask),"=m" ((*(volatile long *)Index)));
+ return Mask!=0;
+ }
+ __CRT_INLINE BOOLEAN _BitScanReverse(DWORD *Index,DWORD Mask) {
+ __asm__ __volatile__("bsrl %1,%0" : "=r" (Mask),"=m" ((*(volatile long *)Index)));
+ return Mask!=0;
+ }
+ __CRT_INLINE BOOLEAN _BitScanForward64(DWORD *Index,DWORD64 Mask) {
+ __asm__ __volatile__("bsfq %1,%0" : "=r" (Mask),"=m" ((*(volatile long long *)Index)));
+ return Mask!=0;
+ }
+ __CRT_INLINE BOOLEAN _BitScanReverse64(DWORD *Index,DWORD64 Mask) {
+ __asm__ __volatile__("bsrq %1,%0" : "=r" (Mask),"=m" ((*(volatile long long *)Index)));
+ return Mask!=0;
+ }
+
+#define InterlockedIncrement16 _InterlockedIncrement16
+#define InterlockedDecrement16 _InterlockedDecrement16
+#define InterlockedCompareExchange16 _InterlockedCompareExchange16
+
+#define InterlockedAnd _InterlockedAnd
+#define InterlockedOr _InterlockedOr
+#define InterlockedXor _InterlockedXor
+#define InterlockedIncrement _InterlockedIncrement
+#define InterlockedIncrementAcquire InterlockedIncrement
+#define InterlockedIncrementRelease InterlockedIncrement
+#define InterlockedDecrement _InterlockedDecrement
+#define InterlockedDecrementAcquire InterlockedDecrement
+#define InterlockedDecrementRelease InterlockedDecrement
+#define InterlockedAdd _InterlockedAdd
+#define InterlockedExchange _InterlockedExchange
+#define InterlockedExchangeAdd _InterlockedExchangeAdd
+#define InterlockedCompareExchange _InterlockedCompareExchange
+#define InterlockedCompareExchangeAcquire InterlockedCompareExchange
+#define InterlockedCompareExchangeRelease InterlockedCompareExchange
+
+#define InterlockedAnd64 _InterlockedAnd64
+#define InterlockedAndAffinity InterlockedAnd64
+#define InterlockedOr64 _InterlockedOr64
+#define InterlockedOrAffinity InterlockedOr64
+#define InterlockedXor64 _InterlockedXor64
+#define InterlockedIncrement64 _InterlockedIncrement64
+#define InterlockedDecrement64 _InterlockedDecrement64
+#define InterlockedAdd64 _InterlockedAdd64
+#define InterlockedExchange64 _InterlockedExchange64
+#define InterlockedExchangeAcquire64 InterlockedExchange64
+#define InterlockedExchangeAdd64 _InterlockedExchangeAdd64
+#define InterlockedCompareExchange64 _InterlockedCompareExchange64
+#define InterlockedCompareExchangeAcquire64 InterlockedCompareExchange64
+#define InterlockedCompareExchangeRelease64 InterlockedCompareExchange64
+
+#define InterlockedExchangePointer _InterlockedExchangePointer
+#define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer
+#define InterlockedCompareExchangePointerAcquire _InterlockedCompareExchangePointer
+#define InterlockedCompareExchangePointerRelease _InterlockedCompareExchangePointer
+
+#define InterlockedExchangeAddSizeT(a,b) InterlockedExchangeAdd64((LONG64 *)a,b)
+#define InterlockedIncrementSizeT(a) InterlockedIncrement64((LONG64 *)a)
+#define InterlockedDecrementSizeT(a) InterlockedDecrement64((LONG64 *)a)
+
+ __CRT_INLINE SHORT InterlockedIncrement16(SHORT volatile *Addend) {
+ unsigned char c;
+ unsigned char s;
+ __asm__ __volatile__(
+ "lock ; addw $1,%0; sete %1 ; sets %2"
+ :"=m" (*Addend), "=qm" (c), "=qm" (s)
+ :"m" (*Addend) : "memory");
+ return (c != 0 ? 0 : (s != 0 ? -1 : 1));
+ }
+ __CRT_INLINE SHORT InterlockedDecrement16(SHORT volatile *Addend) {
+ unsigned char c;
+ unsigned char s;
+ __asm__ __volatile__(
+ "lock ; subw $1,%0; sete %1 ; sets %2"
+ :"=m" (*Addend), "=qm" (c), "=qm" (s)
+ :"m" (*Addend) : "memory");
+ return (c != 0 ? 0 : (s != 0 ? -1 : 1));
+ }
+ __CRT_INLINE SHORT InterlockedCompareExchange16(SHORT volatile *Destination,SHORT ExChange,SHORT Comperand) {
+ SHORT prev;
+ __asm__ __volatile__("lock ; cmpxchgw %w1,%2"
+ :"=a"(prev)
+ :"q"(ExChange), "m"(*Destination), "0"(Comperand)
+ : "memory");
+ return prev;
+ }
+ __CRT_INLINE LONG InterlockedAnd(LONG volatile *Destination,LONG Value) {
+ __asm__ __volatile__("lock ; andl %0,%1"
+ : :"r"(Value),"m"(*Destination)
+ : "memory");
+ return *Destination;
+ }
+ __CRT_INLINE LONG InterlockedOr(LONG volatile *Destination,LONG Value) {
+ __asm__ __volatile__("lock ; orl %0,%1"
+ : : "r"(Value),"m"(*Destination) : "memory");
+ return *Destination;
+ }
+ __CRT_INLINE LONG InterlockedXor(LONG volatile *Destination,LONG Value) {
+ __asm__ __volatile__("lock ; xorl %0,%1"
+ : : "r"(Value),"m"(*Destination) : "memory");
+ return *Destination;
+ }
+ // $$$$
+ __CRT_INLINE LONG64 InterlockedAnd64(LONG64 volatile *Destination,LONG64 Value) {
+ __asm__ __volatile__("lock ; andq %0,%1"
+ : : "r"(Value),"m"(*Destination) : "memory");
+ return *Destination;
+ }
+ __CRT_INLINE LONG64 InterlockedOr64(LONG64 volatile *Destination,LONG64 Value) {
+ __asm__ __volatile__("lock ; orq %0,%1"
+ : : "r"(Value),"m"(*Destination) : "memory");
+ return *Destination;
+ }
+ __CRT_INLINE LONG64 InterlockedXor64(LONG64 volatile *Destination,LONG64 Value) {
+ __asm__ __volatile__("lock ; xorq %0,%1"
+ : : "r"(Value),"m"(*Destination) : "memory");
+ return *Destination;
+ }
+ __CRT_INLINE LONG InterlockedIncrement(LONG volatile *Addend) {
+ unsigned char c;
+ unsigned char s;
+ __asm__ __volatile__(
+ "lock ; addl $1,%0; sete %1 ; sets %2"
+ :"=m" (*Addend), "=qm" (c), "=qm" (s)
+ :"m" (*Addend) : "memory");
+ return (c != 0 ? 0 : (s != 0 ? -1 : 1));
+ }
+ __CRT_INLINE LONG InterlockedDecrement(LONG volatile *Addend) {
+ unsigned char c;
+ unsigned char s;
+ __asm__ __volatile__(
+ "lock ; subl $1,%0; sete %1 ; sets %2"
+ :"=m" (*Addend), "=qm" (c), "=qm" (s)
+ :"m" (*Addend) : "memory");
+ return (c != 0 ? 0 : (s != 0 ? -1 : 1));
+ }
+ __CRT_INLINE LONG InterlockedExchange(LONG volatile *Target,LONG Value) {
+ __asm__ __volatile("lock ; xchgl %0,%1"
+ : "=r"(Value)
+ : "m"(*Target),"0"(Value)
+ : "memory");
+ return Value;
+ }
+ LONG InterlockedExchangeAdd(LONG volatile *Addend,LONG Value);
+
+#ifndef _X86AMD64_
+ __CRT_INLINE LONG InterlockedAdd(LONG volatile *Addend,LONG Value) { return InterlockedExchangeAdd(Addend,Value) + Value; }
+#endif
+ __CRT_INLINE LONG InterlockedCompareExchange(LONG volatile *Destination,LONG ExChange,LONG Comperand) {
+ LONG prev;
+ __asm__ __volatile__("lock ; cmpxchgl %1,%2" : "=a" (prev) : "q" (ExChange),"m" (*Destination), "0" (Comperand) : "memory");
+ return prev;
+ }
+ __CRT_INLINE LONG64 InterlockedIncrement64(LONG64 volatile *Addend) {
+ unsigned char c;
+ unsigned char s;
+ __asm__ __volatile__(
+ "lock ; addq $1,%0; sete %1 ; sets %2"
+ :"=m" (*Addend), "=qm" (c), "=qm" (s)
+ :"m" (*Addend) : "memory");
+ return (c != 0 ? 0 : (s != 0 ? -1 : 1));
+ }
+ __CRT_INLINE LONG64 InterlockedDecrement64(LONG64 volatile *Addend) {
+ unsigned char c;
+ unsigned char s;
+ __asm__ __volatile__(
+ "lock ; subq $1,%0; sete %1 ; sets %2"
+ :"=m" (*Addend), "=qm" (c), "=qm" (s)
+ :"m" (*Addend) : "memory");
+ return (c != 0 ? 0 : (s != 0 ? -1 : 1));
+ }
+ __CRT_INLINE LONG64 InterlockedExchange64(LONG64 volatile *Target,LONG64 Value) {
+ __asm__ __volatile("lock ; xchgq %0,%1"
+ : "=r"(Value)
+ : "m"(*Target),"0"(Value)
+ : "memory");
+ return Value;
+ }
+ LONG64 InterlockedExchangeAdd64(LONG64 volatile *Addend,LONG64 Value);
+
+#ifndef _X86AMD64_
+ __CRT_INLINE LONG64 InterlockedAdd64(LONG64 volatile *Addend,LONG64 Value) { return InterlockedExchangeAdd64(Addend,Value) + Value; }
+#endif
+
+ __CRT_INLINE LONG64 InterlockedCompareExchange64(LONG64 volatile *Destination,LONG64 ExChange,LONG64 Comperand) {
+ LONG64 prev;
+ __asm__ __volatile__("lock ; cmpxchgq %1,%2" : "=a" (prev) : "q" (ExChange),"m" (*Destination), "0" (Comperand) : "memory");
+ return prev;
+ }
+ __CRT_INLINE PVOID InterlockedCompareExchangePointer(PVOID volatile *Destination,PVOID ExChange,PVOID Comperand) {
+ PVOID prev;
+ __asm__ __volatile__("lock ; cmpxchgq %1,%2" : "=a" (prev) : "q" (ExChange),"m" (*Destination), "0" (Comperand) : "memory");
+ return prev;
+ }
+ __CRT_INLINE PVOID InterlockedExchangePointer(PVOID volatile *Target,PVOID Value) {
+ __asm__ __volatile("lock ; xchgq %0,%1"
+ : "=r"(Value)
+ : "m"(*Target),"0"(Value)
+ : "memory");
+ return Value;
+ }
+
+#define CacheLineFlush(Address) _mm_clflush(Address)
+
+ VOID _ReadWriteBarrier(VOID);
+
+#define FastFence __faststorefence
+#define LoadFence _mm_lfence
+#define MemoryFence _mm_mfence
+#define StoreFence _mm_sfence
+
+ VOID __faststorefence(VOID);
+ VOID _m_prefetchw(volatile CONST VOID *Source);
+
+//!__TINYC__: #include <intrin.h>
+
+#define YieldProcessor _mm_pause
+#define MemoryBarrier __faststorefence
+#define PreFetchCacheLine(l,a) _mm_prefetch((CHAR CONST *) a,l)
+#define PrefetchForWrite(p) _m_prefetchw(p)
+#define ReadForWriteAccess(p) (_m_prefetchw(p),*(p))
+
+#define PF_TEMPORAL_LEVEL_1 _MM_HINT_T0
+#define PF_TEMPORAL_LEVEL_2 _MM_HINT_T1
+#define PF_TEMPORAL_LEVEL_3 _MM_HINT_T2
+#define PF_NON_TEMPORAL_LEVEL_ALL _MM_HINT_NTA
+
+#define ReadMxCsr _mm_getcsr
+#define WriteMxCsr _mm_setcsr
+
+ VOID __int2c(VOID);
+
+#define DbgRaiseAssertionFailure() __int2c()
+#define GetCallersEflags() __getcallerseflags()
+
+ unsigned __int32 __getcallerseflags(VOID);
+
+#define GetSegmentLimit __segmentlimit
+
+ DWORD __segmentlimit(DWORD Selector);
+
+#define ReadTimeStampCounter() __rdtsc()
+
+ DWORD64 __rdtsc(VOID);
+ VOID __movsb(PBYTE Destination,BYTE const *Source,SIZE_T Count);
+ VOID __movsw(PWORD Destination,WORD const *Source,SIZE_T Count);
+ VOID __movsd(PDWORD Destination,DWORD const *Source,SIZE_T Count);
+ VOID __movsq(PDWORD64 Destination,DWORD64 const *Source,SIZE_T Count);
+ VOID __stosb(PBYTE Destination,BYTE Value,SIZE_T Count);
+ VOID __stosw(PWORD Destination,WORD Value,SIZE_T Count);
+ VOID __stosd(PDWORD Destination,DWORD Value,SIZE_T Count);
+ VOID __stosq(PDWORD64 Destination,DWORD64 Value,SIZE_T Count);
+
+#define MultiplyHigh __mulh
+#define UnsignedMultiplyHigh __umulh
+
+ LONGLONG MultiplyHigh(LONGLONG Multiplier,LONGLONG Multiplicand);
+ ULONGLONG UnsignedMultiplyHigh(ULONGLONG Multiplier,ULONGLONG Multiplicand);
+
+#define ShiftLeft128 __shiftleft128
+#define ShiftRight128 __shiftright128
+
+ DWORD64 ShiftLeft128(DWORD64 LowPart,DWORD64 HighPart,BYTE Shift);
+ DWORD64 ShiftRight128(DWORD64 LowPart,DWORD64 HighPart,BYTE Shift);
+
+#define Multiply128 _mul128
+
+ LONG64 Multiply128(LONG64 Multiplier,LONG64 Multiplicand,LONG64 *HighProduct);
+
+#define UnsignedMultiply128 _umul128
+
+ DWORD64 UnsignedMultiply128(DWORD64 Multiplier,DWORD64 Multiplicand,DWORD64 *HighProduct);
+
+ __CRT_INLINE LONG64 MultiplyExtract128(LONG64 Multiplier,LONG64 Multiplicand,BYTE Shift) {
+ LONG64 extractedProduct;
+ LONG64 highProduct;
+ LONG64 lowProduct;
+ lowProduct = Multiply128(Multiplier,Multiplicand,&highProduct);
+ extractedProduct = (LONG64)ShiftRight128((LONG64)lowProduct,(LONG64)highProduct,Shift);
+ return extractedProduct;
+ }
+
+ __CRT_INLINE DWORD64 UnsignedMultiplyExtract128(DWORD64 Multiplier,DWORD64 Multiplicand,BYTE Shift) {
+ DWORD64 extractedProduct;
+ DWORD64 highProduct;
+ DWORD64 lowProduct;
+ lowProduct = UnsignedMultiply128(Multiplier,Multiplicand,&highProduct);
+ extractedProduct = ShiftRight128(lowProduct,highProduct,Shift);
+ return extractedProduct;
+ }
+
+ __CRT_INLINE BYTE __readgsbyte(DWORD Offset) {
+ BYTE ret;
+ __asm__ volatile ("movb %%gs:%1,%0"
+ : "=r" (ret) ,"=m" ((*(volatile long *) (DWORD64) Offset)));
+ return ret;
+ }
+ __CRT_INLINE WORD __readgsword(DWORD Offset) {
+ WORD ret;
+ __asm__ volatile ("movw %%gs:%1,%0"
+ : "=r" (ret) ,"=m" ((*(volatile long *) (DWORD64) Offset)));
+ return ret;
+ }
+ __CRT_INLINE DWORD __readgsdword(DWORD Offset) {
+ DWORD ret;
+ __asm__ volatile ("movl %%gs:%1,%0"
+ : "=r" (ret) ,"=m" ((*(volatile long *) (DWORD64) Offset)));
+ return ret;
+ }
+ __CRT_INLINE DWORD64 __readgsqword(DWORD Offset) {
+ void *ret;
+ __asm__ volatile ("movq %%gs:%1,%0"
+ : "=r" (ret) ,"=m" ((*(volatile long *) (DWORD64) Offset)));
+ return (DWORD64) ret;
+ }
+ __CRT_INLINE VOID __writegsbyte(DWORD Offset,BYTE Data) {
+ __asm__ volatile ("movb %0,%%gs:%1"
+ : "=r" (Data) ,"=m" ((*(volatile long *) (DWORD64) Offset)));
+ }
+ __CRT_INLINE VOID __writegsword(DWORD Offset,WORD Data) {
+ __asm__ volatile ("movw %0,%%gs:%1"
+ : "=r" (Data) ,"=m" ((*(volatile long *) (DWORD64) Offset)));
+ }
+ __CRT_INLINE VOID __writegsdword(DWORD Offset,DWORD Data) {
+ __asm__ volatile ("movl %0,%%gs:%1"
+ : "=r" (Data) ,"=m" ((*(volatile long *) (DWORD64) Offset)));
+ }
+ __CRT_INLINE VOID __writegsqword(DWORD Offset,DWORD64 Data) {
+ __asm__ volatile ("movq %0,%%gs:%1"
+ : "=r" (Data) ,"=m" ((*(volatile long *) (DWORD64) Offset)));
+ }
+
+#ifdef __cplusplus
+ }
+#endif
+#endif
+
+#define EXCEPTION_READ_FAULT 0
+#define EXCEPTION_WRITE_FAULT 1
+#define EXCEPTION_EXECUTE_FAULT 8
+
+#if !defined(RC_INVOKED)
+
+#define CONTEXT_AMD64 0x100000
+
+#define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x1L)
+#define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x2L)
+#define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x4L)
+#define CONTEXT_FLOATING_POINT (CONTEXT_AMD64 | 0x8L)
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L)
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
+#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
+
+#define CONTEXT_EXCEPTION_ACTIVE 0x8000000
+#define CONTEXT_SERVICE_ACTIVE 0x10000000
+#define CONTEXT_EXCEPTION_REQUEST 0x40000000
+#define CONTEXT_EXCEPTION_REPORTING 0x80000000
+#endif
+
+#define INITIAL_MXCSR 0x1f80
+#define INITIAL_FPCSR 0x027f
+
+ typedef DECLSPEC_ALIGN(16) struct _M128A {
+ ULONGLONG Low;
+ LONGLONG High;
+ } M128A,*PM128A;
+
+ typedef struct _XMM_SAVE_AREA32 {
+ WORD ControlWord;
+ WORD StatusWord;
+ BYTE TagWord;
+ BYTE Reserved1;
+ WORD ErrorOpcode;
+ DWORD ErrorOffset;
+ WORD ErrorSelector;
+ WORD Reserved2;
+ DWORD DataOffset;
+ WORD DataSelector;
+ WORD Reserved3;
+ DWORD MxCsr;
+ DWORD MxCsr_Mask;
+ M128A FloatRegisters[8];
+ M128A XmmRegisters[16];
+ BYTE Reserved4[96];
+ } XMM_SAVE_AREA32,*PXMM_SAVE_AREA32;
+
+#define LEGACY_SAVE_AREA_LENGTH sizeof(XMM_SAVE_AREA32)
+
+ typedef DECLSPEC_ALIGN(16) struct _CONTEXT {
+ DWORD64 P1Home;
+ DWORD64 P2Home;
+ DWORD64 P3Home;
+ DWORD64 P4Home;
+ DWORD64 P5Home;
+ DWORD64 P6Home;
+ DWORD ContextFlags;
+ DWORD MxCsr;
+ WORD SegCs;
+ WORD SegDs;
+ WORD SegEs;
+ WORD SegFs;
+ WORD SegGs;
+ WORD SegSs;
+ DWORD EFlags;
+ DWORD64 Dr0;
+ DWORD64 Dr1;
+ DWORD64 Dr2;
+ DWORD64 Dr3;
+ DWORD64 Dr6;
+ DWORD64 Dr7;
+ DWORD64 Rax;
+ DWORD64 Rcx;
+ DWORD64 Rdx;
+ DWORD64 Rbx;
+ DWORD64 Rsp;
+ DWORD64 Rbp;
+ DWORD64 Rsi;
+ DWORD64 Rdi;
+ DWORD64 R8;
+ DWORD64 R9;
+ DWORD64 R10;
+ DWORD64 R11;
+ DWORD64 R12;
+ DWORD64 R13;
+ DWORD64 R14;
+ DWORD64 R15;
+ DWORD64 Rip;
+ union {
+ XMM_SAVE_AREA32 FltSave;
+ XMM_SAVE_AREA32 FloatSave;
+ struct {
+ M128A Header[2];
+ M128A Legacy[8];
+ M128A Xmm0;
+ M128A Xmm1;
+ M128A Xmm2;
+ M128A Xmm3;
+ M128A Xmm4;
+ M128A Xmm5;
+ M128A Xmm6;
+ M128A Xmm7;
+ M128A Xmm8;
+ M128A Xmm9;
+ M128A Xmm10;
+ M128A Xmm11;
+ M128A Xmm12;
+ M128A Xmm13;
+ M128A Xmm14;
+ M128A Xmm15;
+ };
+ };
+ M128A VectorRegister[26];
+ DWORD64 VectorControl;
+ DWORD64 DebugControl;
+ DWORD64 LastBranchToRip;
+ DWORD64 LastBranchFromRip;
+ DWORD64 LastExceptionToRip;
+ DWORD64 LastExceptionFromRip;
+ } CONTEXT,*PCONTEXT;
+
+#define RUNTIME_FUNCTION_INDIRECT 0x1
+
+ typedef struct _RUNTIME_FUNCTION {
+ DWORD BeginAddress;
+ DWORD EndAddress;
+ DWORD UnwindData;
+ } RUNTIME_FUNCTION,*PRUNTIME_FUNCTION;
+
+ typedef PRUNTIME_FUNCTION (*PGET_RUNTIME_FUNCTION_CALLBACK)(DWORD64 ControlPc,PVOID Context);
+ typedef DWORD (*POUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK)(HANDLE Process,PVOID TableAddress,PDWORD Entries,PRUNTIME_FUNCTION *Functions);
+
+#define OUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK_EXPORT_NAME "OutOfProcessFunctionTableCallback"
+
+ NTSYSAPI VOID __cdecl RtlRestoreContext (PCONTEXT ContextRecord,struct _EXCEPTION_RECORD *ExceptionRecord);
+ NTSYSAPI BOOLEAN __cdecl RtlAddFunctionTable(PRUNTIME_FUNCTION FunctionTable,DWORD EntryCount,DWORD64 BaseAddress);
+ NTSYSAPI BOOLEAN __cdecl RtlInstallFunctionTableCallback(DWORD64 TableIdentifier,DWORD64 BaseAddress,DWORD Length,PGET_RUNTIME_FUNCTION_CALLBACK Callback,PVOID Context,PCWSTR OutOfProcessCallbackDll);
+ NTSYSAPI BOOLEAN __cdecl RtlDeleteFunctionTable(PRUNTIME_FUNCTION FunctionTable);
+#endif
+
+#ifdef I_X86_
+#if(defined(_X86_) && !defined(__x86_64)) && !defined(RC_INVOKED)
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ __CRT_INLINE BOOLEAN InterlockedBitTestAndSet(LONG *Base,LONG Bit) {
+ int old = 0;
+ __asm__ __volatile__("lock ; btsl %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long *) Base))
+ :"Ir" (Bit));
+ return (BOOLEAN) (old!=0);
+ }
+
+ __CRT_INLINE BOOLEAN InterlockedBitTestAndReset(LONG *Base,LONG Bit) {
+ int old = 0;
+ __asm__ __volatile__("lock ; btrl %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long *) Base))
+ :"Ir" (Bit));
+ return (BOOLEAN) (old!=0);
+ }
+
+ __CRT_INLINE BOOLEAN InterlockedBitTestAndComplement(LONG *Base,LONG Bit) {
+ int old = 0;
+ __asm__ __volatile__("lock ; btcl %2,%1\n\tsbbl %0,%0 "
+ :"=r" (old),"=m" ((*(volatile long *) Base))
+ :"Ir" (Bit));
+ return (BOOLEAN) (old!=0);
+ }
+
+#ifdef _PREFIX_
+ BYTE __readfsbyte(DWORD Offset);
+ WORD __readfsword(DWORD Offset);
+ DWORD __readfsdword(DWORD Offset);
+ VOID __writefsbyte(DWORD Offset,BYTE Data);
+ VOID __writefsword(DWORD Offset,WORD Data);
+ VOID __writefsdword(DWORD Offset,DWORD Data);
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+#endif
+
+#if(defined(_X86_) && !defined(__x86_64))
+ __CRT_INLINE VOID MemoryBarrier(VOID) {
+ LONG Barrier;
+ __asm__ __volatile__("xchgl %eax,%0 "
+ :"=r" (Barrier));
+ }
+#define YieldProcessor() __asm__ __volatile__("rep nop ");
+
+#define PreFetchCacheLine(l,a)
+#define ReadForWriteAccess(p) (*(p))
+
+#define PF_TEMPORAL_LEVEL_1
+#define PF_NON_TEMPORAL_LEVEL_ALL
+
+ __CRT_INLINE VOID DbgRaiseAssertionFailure(void) {
+ __asm__ __volatile__("int 0x2c ");
+ }
+ PVOID GetCurrentFiber(void);
+ __CRT_INLINE PVOID GetCurrentFiber(void)
+ {
+ void *ret;
+ __asm__ volatile ("movl %%fs:0x10,%0"
+ : "=r" (ret));
+ return ret;
+ }
+ PVOID GetFiberData(void);
+ __CRT_INLINE PVOID GetFiberData(void)
+ {
+ void *ret;
+ __asm__ volatile ("movl %%fs:0x10,%0\n"
+ "movl (%0),%0"
+ : "=r" (ret));
+ return ret;
+ }
+#endif
+
+#define EXCEPTION_READ_FAULT 0
+#define EXCEPTION_WRITE_FAULT 1
+#define EXCEPTION_EXECUTE_FAULT 8
+
+#define SIZE_OF_80387_REGISTERS 80
+
+#if !defined(RC_INVOKED)
+
+#define CONTEXT_i386 0x00010000
+#define CONTEXT_i486 0x00010000
+
+#define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L)
+#define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L)
+#define CONTEXT_SEGMENTS (CONTEXT_i386 | 0x00000004L)
+#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 0x00000008L)
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L)
+#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386 | 0x00000020L)
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS)
+
+#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS)
+#endif
+
+#define MAXIMUM_SUPPORTED_EXTENSION 512
+
+ typedef struct _FLOATING_SAVE_AREA {
+ DWORD ControlWord;
+ DWORD StatusWord;
+ DWORD TagWord;
+ DWORD ErrorOffset;
+ DWORD ErrorSelector;
+ DWORD DataOffset;
+ DWORD DataSelector;
+ BYTE RegisterArea[SIZE_OF_80387_REGISTERS];
+ DWORD Cr0NpxState;
+ } FLOATING_SAVE_AREA;
+
+ typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA;
+
+ typedef struct _CONTEXT {
+ DWORD ContextFlags;
+ DWORD Dr0;
+ DWORD Dr1;
+ DWORD Dr2;
+ DWORD Dr3;
+ DWORD Dr6;
+ DWORD Dr7;
+ FLOATING_SAVE_AREA FloatSave;
+ DWORD SegGs;
+ DWORD SegFs;
+ DWORD SegEs;
+ DWORD SegDs;
+
+ DWORD Edi;
+ DWORD Esi;
+ DWORD Ebx;
+ DWORD Edx;
+ DWORD Ecx;
+ DWORD Eax;
+ DWORD Ebp;
+ DWORD Eip;
+ DWORD SegCs;
+ DWORD EFlags;
+ DWORD Esp;
+ DWORD SegSs;
+ BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
+ } CONTEXT;
+
+ typedef CONTEXT *PCONTEXT;
+#endif
+
+#ifndef _LDT_ENTRY_DEFINED
+#define _LDT_ENTRY_DEFINED
+
+ typedef struct _LDT_ENTRY {
+ WORD LimitLow;
+ WORD BaseLow;
+ union {
+ struct {
+ BYTE BaseMid;
+ BYTE Flags1;
+ BYTE Flags2;
+ BYTE BaseHi;
+ } Bytes;
+ struct {
+ DWORD BaseMid : 8;
+ DWORD Type : 5;
+ DWORD Dpl : 2;
+ DWORD Pres : 1;
+ DWORD LimitHi : 4;
+ DWORD Sys : 1;
+ DWORD Reserved_0 : 1;
+ DWORD Default_Big : 1;
+ DWORD Granularity : 1;
+ DWORD BaseHi : 8;
+ } Bits;
+ } HighWord;
+ } LDT_ENTRY,*PLDT_ENTRY;
+#endif
+
+#if defined(__ia64__) && !defined(RC_INVOKED)
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ BOOLEAN BitScanForward64(DWORD *Index,DWORD64 Mask);
+ BOOLEAN BitScanReverse64(DWORD *Index,DWORD64 Mask);
+
+#ifdef __cplusplus
+ }
+#endif
+#endif
+
+#if !defined(GENUTIL) && !defined(_GENIA64_) && defined(_IA64_)
+
+ void *_cdecl _rdteb(void);
+#ifdef __ia64__
+
+#define NtCurrentTeb() ((struct _TEB *)_rdteb())
+#define GetCurrentFiber() (((PNT_TIB)NtCurrentTeb())->FiberData)
+#define GetFiberData() (*(PVOID *)(GetCurrentFiber()))
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ void __break(int);
+ void __yield(void);
+ void __mf(void);
+ void __lfetch(int Level,VOID CONST *Address);
+ void __lfetchfault(int Level,VOID CONST *Address);
+ void __lfetch_excl(int Level,VOID CONST *Address);
+ void __lfetchfault_excl(int Level,VOID CONST *Address);
+
+#define MD_LFHINT_NONE 0x00
+#define MD_LFHINT_NT1 0x01
+#define MD_LFHINT_NT2 0x02
+#define MD_LFHINT_NTA 0x03
+
+#ifdef __cplusplus
+ }
+#endif
+
+#define YieldProcessor __yield
+#define MemoryBarrier __mf
+#define PreFetchCacheLine __lfetch
+#define ReadForWriteAccess(p) (*(p))
+#define DbgRaiseAssertionFailure() __break(ASSERT_BREAKPOINT)
+
+#define PF_TEMPORAL_LEVEL_1 MD_LFHINT_NONE
+#define PF_NON_TEMPORAL_LEVEL_ALL MD_LFHINT_NTA
+
+#define UnsignedMultiplyHigh __UMULH
+
+ ULONGLONG UnsignedMultiplyHigh(ULONGLONG Multiplier,ULONGLONG Multiplicand);
+#else
+ struct _TEB *NtCurrentTeb(void);
+#endif
+#endif
+
+#ifdef _IA64_
+
+#define EXCEPTION_READ_FAULT 0
+#define EXCEPTION_WRITE_FAULT 1
+#define EXCEPTION_EXECUTE_FAULT 2
+
+#if !defined(RC_INVOKED)
+
+#define CONTEXT_IA64 0x00080000
+
+#define CONTEXT_CONTROL (CONTEXT_IA64 | 0x00000001L)
+#define CONTEXT_LOWER_FLOATING_POINT (CONTEXT_IA64 | 0x00000002L)
+#define CONTEXT_HIGHER_FLOATING_POINT (CONTEXT_IA64 | 0x00000004L)
+#define CONTEXT_INTEGER (CONTEXT_IA64 | 0x00000008L)
+#define CONTEXT_DEBUG (CONTEXT_IA64 | 0x00000010L)
+#define CONTEXT_IA32_CONTROL (CONTEXT_IA64 | 0x00000020L)
+
+#define CONTEXT_FLOATING_POINT (CONTEXT_LOWER_FLOATING_POINT | CONTEXT_HIGHER_FLOATING_POINT)
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER | CONTEXT_IA32_CONTROL)
+#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER | CONTEXT_DEBUG | CONTEXT_IA32_CONTROL)
+
+#define CONTEXT_EXCEPTION_ACTIVE 0x8000000
+#define CONTEXT_SERVICE_ACTIVE 0x10000000
+#define CONTEXT_EXCEPTION_REQUEST 0x40000000
+#define CONTEXT_EXCEPTION_REPORTING 0x80000000
+#endif
+
+ typedef struct _CONTEXT {
+ DWORD ContextFlags;
+ DWORD Fill1[3];
+ ULONGLONG DbI0;
+ ULONGLONG DbI1;
+ ULONGLONG DbI2;
+ ULONGLONG DbI3;
+ ULONGLONG DbI4;
+ ULONGLONG DbI5;
+ ULONGLONG DbI6;
+ ULONGLONG DbI7;
+ ULONGLONG DbD0;
+ ULONGLONG DbD1;
+ ULONGLONG DbD2;
+ ULONGLONG DbD3;
+ ULONGLONG DbD4;
+ ULONGLONG DbD5;
+ ULONGLONG DbD6;
+ ULONGLONG DbD7;
+ FLOAT128 FltS0;
+ FLOAT128 FltS1;
+ FLOAT128 FltS2;
+ FLOAT128 FltS3;
+ FLOAT128 FltT0;
+ FLOAT128 FltT1;
+ FLOAT128 FltT2;
+ FLOAT128 FltT3;
+ FLOAT128 FltT4;
+ FLOAT128 FltT5;
+ FLOAT128 FltT6;
+ FLOAT128 FltT7;
+ FLOAT128 FltT8;
+ FLOAT128 FltT9;
+ FLOAT128 FltS4;
+ FLOAT128 FltS5;
+ FLOAT128 FltS6;
+ FLOAT128 FltS7;
+ FLOAT128 FltS8;
+ FLOAT128 FltS9;
+ FLOAT128 FltS10;
+ FLOAT128 FltS11;
+ FLOAT128 FltS12;
+ FLOAT128 FltS13;
+ FLOAT128 FltS14;
+ FLOAT128 FltS15;
+ FLOAT128 FltS16;
+ FLOAT128 FltS17;
+ FLOAT128 FltS18;
+ FLOAT128 FltS19;
+ FLOAT128 FltF32;
+ FLOAT128 FltF33;
+ FLOAT128 FltF34;
+ FLOAT128 FltF35;
+ FLOAT128 FltF36;
+ FLOAT128 FltF37;
+ FLOAT128 FltF38;
+ FLOAT128 FltF39;
+ FLOAT128 FltF40;
+ FLOAT128 FltF41;
+ FLOAT128 FltF42;
+ FLOAT128 FltF43;
+ FLOAT128 FltF44;
+ FLOAT128 FltF45;
+ FLOAT128 FltF46;
+ FLOAT128 FltF47;
+ FLOAT128 FltF48;
+ FLOAT128 FltF49;
+ FLOAT128 FltF50;
+ FLOAT128 FltF51;
+ FLOAT128 FltF52;
+ FLOAT128 FltF53;
+ FLOAT128 FltF54;
+ FLOAT128 FltF55;
+ FLOAT128 FltF56;
+ FLOAT128 FltF57;
+ FLOAT128 FltF58;
+ FLOAT128 FltF59;
+ FLOAT128 FltF60;
+ FLOAT128 FltF61;
+ FLOAT128 FltF62;
+ FLOAT128 FltF63;
+ FLOAT128 FltF64;
+ FLOAT128 FltF65;
+ FLOAT128 FltF66;
+ FLOAT128 FltF67;
+ FLOAT128 FltF68;
+ FLOAT128 FltF69;
+ FLOAT128 FltF70;
+ FLOAT128 FltF71;
+ FLOAT128 FltF72;
+ FLOAT128 FltF73;
+ FLOAT128 FltF74;
+ FLOAT128 FltF75;
+ FLOAT128 FltF76;
+ FLOAT128 FltF77;
+ FLOAT128 FltF78;
+ FLOAT128 FltF79;
+ FLOAT128 FltF80;
+ FLOAT128 FltF81;
+ FLOAT128 FltF82;
+ FLOAT128 FltF83;
+ FLOAT128 FltF84;
+ FLOAT128 FltF85;
+ FLOAT128 FltF86;
+ FLOAT128 FltF87;
+ FLOAT128 FltF88;
+ FLOAT128 FltF89;
+ FLOAT128 FltF90;
+ FLOAT128 FltF91;
+ FLOAT128 FltF92;
+ FLOAT128 FltF93;
+ FLOAT128 FltF94;
+ FLOAT128 FltF95;
+ FLOAT128 FltF96;
+ FLOAT128 FltF97;
+ FLOAT128 FltF98;
+ FLOAT128 FltF99;
+ FLOAT128 FltF100;
+ FLOAT128 FltF101;
+ FLOAT128 FltF102;
+ FLOAT128 FltF103;
+ FLOAT128 FltF104;
+ FLOAT128 FltF105;
+ FLOAT128 FltF106;
+ FLOAT128 FltF107;
+ FLOAT128 FltF108;
+ FLOAT128 FltF109;
+ FLOAT128 FltF110;
+ FLOAT128 FltF111;
+ FLOAT128 FltF112;
+ FLOAT128 FltF113;
+ FLOAT128 FltF114;
+ FLOAT128 FltF115;
+ FLOAT128 FltF116;
+ FLOAT128 FltF117;
+ FLOAT128 FltF118;
+ FLOAT128 FltF119;
+ FLOAT128 FltF120;
+ FLOAT128 FltF121;
+ FLOAT128 FltF122;
+ FLOAT128 FltF123;
+ FLOAT128 FltF124;
+ FLOAT128 FltF125;
+ FLOAT128 FltF126;
+ FLOAT128 FltF127;
+ ULONGLONG StFPSR;
+ ULONGLONG IntGp;
+ ULONGLONG IntT0;
+ ULONGLONG IntT1;
+ ULONGLONG IntS0;
+ ULONGLONG IntS1;
+ ULONGLONG IntS2;
+ ULONGLONG IntS3;
+ ULONGLONG IntV0;
+ ULONGLONG IntT2;
+ ULONGLONG IntT3;
+ ULONGLONG IntT4;
+ ULONGLONG IntSp;
+ ULONGLONG IntTeb;
+ ULONGLONG IntT5;
+ ULONGLONG IntT6;
+ ULONGLONG IntT7;
+ ULONGLONG IntT8;
+ ULONGLONG IntT9;
+ ULONGLONG IntT10;
+ ULONGLONG IntT11;
+ ULONGLONG IntT12;
+ ULONGLONG IntT13;
+ ULONGLONG IntT14;
+ ULONGLONG IntT15;
+ ULONGLONG IntT16;
+ ULONGLONG IntT17;
+ ULONGLONG IntT18;
+ ULONGLONG IntT19;
+ ULONGLONG IntT20;
+ ULONGLONG IntT21;
+ ULONGLONG IntT22;
+ ULONGLONG IntNats;
+ ULONGLONG Preds;
+ ULONGLONG BrRp;
+ ULONGLONG BrS0;
+ ULONGLONG BrS1;
+ ULONGLONG BrS2;
+ ULONGLONG BrS3;
+ ULONGLONG BrS4;
+ ULONGLONG BrT0;
+ ULONGLONG BrT1;
+ ULONGLONG ApUNAT;
+ ULONGLONG ApLC;
+ ULONGLONG ApEC;
+ ULONGLONG ApCCV;
+ ULONGLONG ApDCR;
+ ULONGLONG RsPFS;
+ ULONGLONG RsBSP;
+ ULONGLONG RsBSPSTORE;
+ ULONGLONG RsRSC;
+ ULONGLONG RsRNAT;
+ ULONGLONG StIPSR;
+ ULONGLONG StIIP;
+ ULONGLONG StIFS;
+ ULONGLONG StFCR;
+ ULONGLONG Eflag;
+ ULONGLONG SegCSD;
+ ULONGLONG SegSSD;
+ ULONGLONG Cflag;
+ ULONGLONG StFSR;
+ ULONGLONG StFIR;
+ ULONGLONG StFDR;
+ ULONGLONG UNUSEDPACK;
+ } CONTEXT,*PCONTEXT;
+
+ typedef struct _PLABEL_DESCRIPTOR {
+ ULONGLONG EntryPoint;
+ ULONGLONG GlobalPointer;
+ } PLABEL_DESCRIPTOR,*PPLABEL_DESCRIPTOR;
+
+ typedef struct _RUNTIME_FUNCTION {
+ DWORD BeginAddress;
+ DWORD EndAddress;
+ DWORD UnwindInfoAddress;
+ } RUNTIME_FUNCTION,*PRUNTIME_FUNCTION;
+
+ typedef PRUNTIME_FUNCTION (*PGET_RUNTIME_FUNCTION_CALLBACK)(DWORD64 ControlPc,PVOID Context);
+ typedef DWORD (*POUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK)(HANDLE Process,PVOID TableAddress,PDWORD Entries,PRUNTIME_FUNCTION *Functions);
+
+#define OUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK_EXPORT_NAME "OutOfProcessFunctionTableCallback"
+
+ BOOLEAN RtlAddFunctionTable(PRUNTIME_FUNCTION FunctionTable,DWORD EntryCount,ULONGLONG BaseAddress,ULONGLONG TargetGp);
+ BOOLEAN RtlInstallFunctionTableCallback(DWORD64 TableIdentifier,DWORD64 BaseAddress,DWORD Length,DWORD64 TargetGp,PGET_RUNTIME_FUNCTION_CALLBACK Callback,PVOID Context,PCWSTR OutOfProcessCallbackDll);
+ BOOLEAN RtlDeleteFunctionTable(PRUNTIME_FUNCTION FunctionTable);
+ VOID RtlRestoreContext (PCONTEXT ContextRecord,struct _EXCEPTION_RECORD *ExceptionRecord);
+ VOID __jump_unwind(ULONGLONG TargetMsFrame,ULONGLONG TargetBsFrame,ULONGLONG TargetPc);
+#endif
+
+#define EXCEPTION_NONCONTINUABLE 0x1
+#define EXCEPTION_MAXIMUM_PARAMETERS 15
+
+ typedef struct _EXCEPTION_RECORD {
+ DWORD ExceptionCode;
+ DWORD ExceptionFlags;
+ struct _EXCEPTION_RECORD *ExceptionRecord;
+ PVOID ExceptionAddress;
+ DWORD NumberParameters;
+ ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+ } EXCEPTION_RECORD;
+
+ typedef EXCEPTION_RECORD *PEXCEPTION_RECORD;
+
+ typedef struct _EXCEPTION_RECORD32 {
+ DWORD ExceptionCode;
+ DWORD ExceptionFlags;
+ DWORD ExceptionRecord;
+ DWORD ExceptionAddress;
+ DWORD NumberParameters;
+ DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+ } EXCEPTION_RECORD32,*PEXCEPTION_RECORD32;
+
+ typedef struct _EXCEPTION_RECORD64 {
+ DWORD ExceptionCode;
+ DWORD ExceptionFlags;
+ DWORD64 ExceptionRecord;
+ DWORD64 ExceptionAddress;
+ DWORD NumberParameters;
+ DWORD __unusedAlignment;
+ DWORD64 ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+ } EXCEPTION_RECORD64,*PEXCEPTION_RECORD64;
+
+ typedef struct _EXCEPTION_POINTERS {
+ PEXCEPTION_RECORD ExceptionRecord;
+ PCONTEXT ContextRecord;
+ } EXCEPTION_POINTERS,*PEXCEPTION_POINTERS;
+
+#ifdef __x86_64
+
+ typedef EXCEPTION_DISPOSITION NTAPI EXCEPTION_ROUTINE (struct _EXCEPTION_RECORD *ExceptionRecord, PVOID EstablisherFrame, struct _CONTEXT *ContextRecord, PVOID DispatcherContext);
+#ifndef __PEXCEPTION_ROUTINE_DEFINED
+#define __PEXCEPTION_ROUTINE_DEFINED
+ typedef EXCEPTION_ROUTINE *PEXCEPTION_ROUTINE;
+#endif
+
+ /* http://msdn.microsoft.com/en-us/library/ms680597(VS.85).aspx */
+
+#define UNWIND_HISTORY_TABLE_SIZE 12
+
+ typedef struct _UNWIND_HISTORY_TABLE_ENTRY {
+ ULONG64 ImageBase;
+ PRUNTIME_FUNCTION FunctionEntry;
+ } UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY;
+
+#define UNWIND_HISTORY_TABLE_NONE 0
+#define UNWIND_HISTORY_TABLE_GLOBAL 1
+#define UNWIND_HISTORY_TABLE_LOCAL 2
+
+ typedef struct _UNWIND_HISTORY_TABLE {
+ ULONG Count;
+ UCHAR Search;
+ ULONG64 LowAddress;
+ ULONG64 HighAddress;
+ UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
+ } UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE;
+
+ /* http://msdn.microsoft.com/en-us/library/b6sf5kbd(VS.80).aspx */
+
+ struct _DISPATCHER_CONTEXT;
+ typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT;
+ typedef struct _DISPATCHER_CONTEXT *PDISPATCHER_CONTEXT;
+
+ struct _DISPATCHER_CONTEXT {
+ ULONG64 ControlPc;
+ ULONG64 ImageBase;
+ PRUNTIME_FUNCTION FunctionEntry;
+ ULONG64 EstablisherFrame;
+ ULONG64 TargetIp;
+ PCONTEXT ContextRecord;
+ PEXCEPTION_ROUTINE LanguageHandler;
+ PVOID HandlerData;
+ /* http://www.nynaeve.net/?p=99 */
+ PUNWIND_HISTORY_TABLE HistoryTable;
+ ULONG ScopeIndex;
+ ULONG Fill0;
+ };
+
+ /* http://msdn.microsoft.com/en-us/library/ms680617(VS.85).aspx */
+
+ typedef struct _KNONVOLATILE_CONTEXT_POINTERS
+ {
+ PM128A FloatingContext[16];
+ PULONG64 IntegerContext[16];
+ } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
+#endif /* defined(__x86_64) */
+
+ typedef PVOID PACCESS_TOKEN;
+ typedef PVOID PSECURITY_DESCRIPTOR;
+ typedef PVOID PSID;
+
+ typedef DWORD ACCESS_MASK;
+ typedef ACCESS_MASK *PACCESS_MASK;
+
+#define DELETE (0x00010000L)
+#define READ_CONTROL (0x00020000L)
+#define WRITE_DAC (0x00040000L)
+#define WRITE_OWNER (0x00080000L)
+#define SYNCHRONIZE (0x00100000L)
+
+#define STANDARD_RIGHTS_REQUIRED (0x000F0000L)
+#define STANDARD_RIGHTS_READ (READ_CONTROL)
+#define STANDARD_RIGHTS_WRITE (READ_CONTROL)
+#define STANDARD_RIGHTS_EXECUTE (READ_CONTROL)
+#define STANDARD_RIGHTS_ALL (0x001F0000L)
+
+#define SPECIFIC_RIGHTS_ALL (0x0000FFFFL)
+
+#define ACCESS_SYSTEM_SECURITY (0x01000000L)
+
+#define MAXIMUM_ALLOWED (0x02000000L)
+
+#define GENERIC_READ (0x80000000L)
+#define GENERIC_WRITE (0x40000000L)
+#define GENERIC_EXECUTE (0x20000000L)
+#define GENERIC_ALL (0x10000000L)
+
+ typedef struct _GENERIC_MAPPING {
+ ACCESS_MASK GenericRead;
+ ACCESS_MASK GenericWrite;
+ ACCESS_MASK GenericExecute;
+ ACCESS_MASK GenericAll;
+ } GENERIC_MAPPING;
+ typedef GENERIC_MAPPING *PGENERIC_MAPPING;
+
+#include <pshpack4.h>
+
+ typedef struct _LUID_AND_ATTRIBUTES {
+ LUID Luid;
+ DWORD Attributes;
+ } LUID_AND_ATTRIBUTES,*PLUID_AND_ATTRIBUTES;
+ typedef LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY];
+ typedef LUID_AND_ATTRIBUTES_ARRAY *PLUID_AND_ATTRIBUTES_ARRAY;
+
+#include <poppack.h>
+
+#ifndef SID_IDENTIFIER_AUTHORITY_DEFINED
+#define SID_IDENTIFIER_AUTHORITY_DEFINED
+ typedef struct _SID_IDENTIFIER_AUTHORITY {
+ BYTE Value[6];
+ } SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY;
+#endif
+
+#ifndef SID_DEFINED
+#define SID_DEFINED
+ typedef struct _SID {
+ BYTE Revision;
+ BYTE SubAuthorityCount;
+ SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
+ DWORD SubAuthority[ANYSIZE_ARRAY];
+ } SID,*PISID;
+#endif
+
+#define SID_REVISION (1)
+#define SID_MAX_SUB_AUTHORITIES (15)
+#define SID_RECOMMENDED_SUB_AUTHORITIES (1)
+
+#define SECURITY_MAX_SID_SIZE (sizeof(SID) - sizeof(DWORD) + (SID_MAX_SUB_AUTHORITIES *sizeof(DWORD)))
+
+ typedef enum _SID_NAME_USE {
+ SidTypeUser = 1,SidTypeGroup,SidTypeDomain,SidTypeAlias,SidTypeWellKnownGroup,SidTypeDeletedAccount,SidTypeInvalid,SidTypeUnknown,SidTypeComputer
+ } SID_NAME_USE,*PSID_NAME_USE;
+
+ typedef struct _SID_AND_ATTRIBUTES {
+ PSID Sid;
+ DWORD Attributes;
+ } SID_AND_ATTRIBUTES,*PSID_AND_ATTRIBUTES;
+
+ typedef SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY];
+ typedef SID_AND_ATTRIBUTES_ARRAY *PSID_AND_ATTRIBUTES_ARRAY;
+
+#define SECURITY_NULL_SID_AUTHORITY {0,0,0,0,0,0}
+#define SECURITY_WORLD_SID_AUTHORITY {0,0,0,0,0,1}
+#define SECURITY_LOCAL_SID_AUTHORITY {0,0,0,0,0,2}
+#define SECURITY_CREATOR_SID_AUTHORITY {0,0,0,0,0,3}
+#define SECURITY_NON_UNIQUE_AUTHORITY {0,0,0,0,0,4}
+#define SECURITY_RESOURCE_MANAGER_AUTHORITY {0,0,0,0,0,9}
+
+#define SECURITY_NULL_RID (0x00000000L)
+#define SECURITY_WORLD_RID (0x00000000L)
+#define SECURITY_LOCAL_RID (0x00000000L)
+
+#define SECURITY_CREATOR_OWNER_RID (0x00000000L)
+#define SECURITY_CREATOR_GROUP_RID (0x00000001L)
+
+#define SECURITY_CREATOR_OWNER_SERVER_RID (0x00000002L)
+#define SECURITY_CREATOR_GROUP_SERVER_RID (0x00000003L)
+
+#define SECURITY_NT_AUTHORITY {0,0,0,0,0,5}
+
+#define SECURITY_DIALUP_RID (0x00000001L)
+#define SECURITY_NETWORK_RID (0x00000002L)
+#define SECURITY_BATCH_RID (0x00000003L)
+#define SECURITY_INTERACTIVE_RID (0x00000004L)
+#define SECURITY_LOGON_IDS_RID (0x00000005L)
+#define SECURITY_LOGON_IDS_RID_COUNT (3L)
+#define SECURITY_SERVICE_RID (0x00000006L)
+#define SECURITY_ANONYMOUS_LOGON_RID (0x00000007L)
+#define SECURITY_PROXY_RID (0x00000008L)
+#define SECURITY_ENTERPRISE_CONTROLLERS_RID (0x00000009L)
+#define SECURITY_SERVER_LOGON_RID SECURITY_ENTERPRISE_CONTROLLERS_RID
+#define SECURITY_PRINCIPAL_SELF_RID (0x0000000AL)
+#define SECURITY_AUTHENTICATED_USER_RID (0x0000000BL)
+#define SECURITY_RESTRICTED_CODE_RID (0x0000000CL)
+#define SECURITY_TERMINAL_SERVER_RID (0x0000000DL)
+#define SECURITY_REMOTE_LOGON_RID (0x0000000EL)
+#define SECURITY_THIS_ORGANIZATION_RID (0x0000000FL)
+#define SECURITY_IUSER_RID (0x00000011L)
+
+#define SECURITY_LOCAL_SYSTEM_RID (0x00000012L)
+#define SECURITY_LOCAL_SERVICE_RID (0x00000013L)
+#define SECURITY_NETWORK_SERVICE_RID (0x00000014L)
+
+#define SECURITY_NT_NON_UNIQUE (0x00000015L)
+#define SECURITY_NT_NON_UNIQUE_SUB_AUTH_COUNT (3L)
+
+#define SECURITY_ENTERPRISE_READONLY_CONTROLLERS_RID (0x00000016L)
+
+#define SECURITY_BUILTIN_DOMAIN_RID (0x00000020L)
+#define SECURITY_WRITE_RESTRICTED_CODE_RID (0x00000021L)
+
+#define SECURITY_PACKAGE_BASE_RID (0x00000040L)
+#define SECURITY_PACKAGE_RID_COUNT (2L)
+#define SECURITY_PACKAGE_NTLM_RID (0x0000000AL)
+#define SECURITY_PACKAGE_SCHANNEL_RID (0x0000000EL)
+#define SECURITY_PACKAGE_DIGEST_RID (0x00000015L)
+
+#define SECURITY_SERVICE_ID_BASE_RID (0x00000050L)
+#define SECURITY_SERVICE_ID_RID_COUNT (6L)
+
+#define SECURITY_RESERVED_ID_BASE_RID (0x00000051L)
+
+#define SECURITY_MAX_ALWAYS_FILTERED (0x000003E7L)
+#define SECURITY_MIN_NEVER_FILTERED (0x000003E8L)
+
+#define SECURITY_OTHER_ORGANIZATION_RID (0x000003E8L)
+
+#define FOREST_USER_RID_MAX (0x000001F3L)
+
+#define DOMAIN_USER_RID_ADMIN (0x000001F4L)
+#define DOMAIN_USER_RID_GUEST (0x000001F5L)
+#define DOMAIN_USER_RID_KRBTGT (0x000001F6L)
+
+#define DOMAIN_USER_RID_MAX (0x000003E7L)
+
+#define DOMAIN_GROUP_RID_ADMINS (0x00000200L)
+#define DOMAIN_GROUP_RID_USERS (0x00000201L)
+#define DOMAIN_GROUP_RID_GUESTS (0x00000202L)
+#define DOMAIN_GROUP_RID_COMPUTERS (0x00000203L)
+#define DOMAIN_GROUP_RID_CONTROLLERS (0x00000204L)
+#define DOMAIN_GROUP_RID_CERT_ADMINS (0x00000205L)
+#define DOMAIN_GROUP_RID_SCHEMA_ADMINS (0x00000206L)
+#define DOMAIN_GROUP_RID_ENTERPRISE_ADMINS (0x00000207L)
+#define DOMAIN_GROUP_RID_POLICY_ADMINS (0x00000208L)
+#define DOMAIN_GROUP_RID_READONLY_CONTROLLERS (0x00000209L)
+
+#define DOMAIN_ALIAS_RID_ADMINS (0x00000220L)
+#define DOMAIN_ALIAS_RID_USERS (0x00000221L)
+#define DOMAIN_ALIAS_RID_GUESTS (0x00000222L)
+#define DOMAIN_ALIAS_RID_POWER_USERS (0x00000223L)
+
+#define DOMAIN_ALIAS_RID_ACCOUNT_OPS (0x00000224L)
+#define DOMAIN_ALIAS_RID_SYSTEM_OPS (0x00000225L)
+#define DOMAIN_ALIAS_RID_PRINT_OPS (0x00000226L)
+#define DOMAIN_ALIAS_RID_BACKUP_OPS (0x00000227L)
+
+#define DOMAIN_ALIAS_RID_REPLICATOR (0x00000228L)
+#define DOMAIN_ALIAS_RID_RAS_SERVERS (0x00000229L)
+#define DOMAIN_ALIAS_RID_PREW2KCOMPACCESS (0x0000022AL)
+#define DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS (0x0000022BL)
+#define DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS (0x0000022CL)
+#define DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS (0x0000022DL)
+
+#define DOMAIN_ALIAS_RID_MONITORING_USERS (0x0000022EL)
+#define DOMAIN_ALIAS_RID_LOGGING_USERS (0x0000022FL)
+#define DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS (0x00000230L)
+#define DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS (0x00000231L)
+#define DOMAIN_ALIAS_RID_DCOM_USERS (0x00000232L)
+
+#define DOMAIN_ALIAS_RID_IUSERS (0x00000238L)
+#define DOMAIN_ALIAS_RID_CRYPTO_OPERATORS (0x00000239L)
+#define DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP (0x0000023BL)
+#define DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP (0x0000023CL)
+#define DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP (0x0000023DL)
+
+#define SECURITY_MANDATORY_LABEL_AUTHORITY {0,0,0,0,0,16}
+#define SECURITY_MANDATORY_UNTRUSTED_RID (0x00000000L)
+#define SECURITY_MANDATORY_LOW_RID (0x00001000L)
+#define SECURITY_MANDATORY_MEDIUM_RID (0x00002000L)
+#define SECURITY_MANDATORY_HIGH_RID (0x00003000L)
+#define SECURITY_MANDATORY_SYSTEM_RID (0x00004000L)
+#define SECURITY_MANDATORY_PROTECTED_PROCESS_RID (0x00005000L)
+
+#define SECURITY_MANDATORY_MAXIMUM_USER_RID SECURITY_MANDATORY_SYSTEM_RID
+
+#define MANDATORY_LEVEL_TO_MANDATORY_RID(IL) (IL * 0x1000)
+
+ typedef enum {
+ WinNullSid = 0,WinWorldSid = 1,WinLocalSid = 2,WinCreatorOwnerSid = 3,WinCreatorGroupSid = 4,WinCreatorOwnerServerSid = 5,WinCreatorGroupServerSid = 6,WinNtAuthoritySid = 7,WinDialupSid = 8,WinNetworkSid = 9,WinBatchSid = 10,WinInteractiveSid = 11,WinServiceSid = 12,WinAnonymousSid = 13,WinProxySid = 14,WinEnterpriseControllersSid = 15,WinSelfSid = 16,WinAuthenticatedUserSid = 17,WinRestrictedCodeSid = 18,WinTerminalServerSid = 19,WinRemoteLogonIdSid = 20,WinLogonIdsSid = 21,WinLocalSystemSid = 22,WinLocalServiceSid = 23,WinNetworkServiceSid = 24,WinBuiltinDomainSid = 25,WinBuiltinAdministratorsSid = 26,WinBuiltinUsersSid = 27,WinBuiltinGuestsSid = 28,WinBuiltinPowerUsersSid = 29,WinBuiltinAccountOperatorsSid = 30,WinBuiltinSystemOperatorsSid = 31,WinBuiltinPrintOperatorsSid = 32,WinBuiltinBackupOperatorsSid = 33,WinBuiltinReplicatorSid = 34,WinBuiltinPreWindows2000CompatibleAccessSid = 35,WinBuiltinRemoteDesktopUsersSid = 36,WinBuiltinNetworkConfigurationOperatorsSid = 37,WinAccountAdministratorSid = 38,WinAccountGuestSid = 39,WinAccountKrbtgtSid = 40,WinAccountDomainAdminsSid = 41,WinAccountDomainUsersSid = 42,WinAccountDomainGuestsSid = 43,WinAccountComputersSid = 44,WinAccountControllersSid = 45,WinAccountCertAdminsSid = 46,WinAccountSchemaAdminsSid = 47,WinAccountEnterpriseAdminsSid = 48,WinAccountPolicyAdminsSid = 49,WinAccountRasAndIasServersSid = 50,WinNTLMAuthenticationSid = 51,WinDigestAuthenticationSid = 52,WinSChannelAuthenticationSid = 53,WinThisOrganizationSid = 54,WinOtherOrganizationSid = 55,WinBuiltinIncomingForestTrustBuildersSid = 56,WinBuiltinPerfMonitoringUsersSid = 57,WinBuiltinPerfLoggingUsersSid = 58,WinBuiltinAuthorizationAccessSid = 59,WinBuiltinTerminalServerLicenseServersSid = 60,WinBuiltinDCOMUsersSid = 61
+ } WELL_KNOWN_SID_TYPE;
+
+#define SYSTEM_LUID { 0x3E7,0x0 }
+#define ANONYMOUS_LOGON_LUID { 0x3e6,0x0 }
+#define LOCALSERVICE_LUID { 0x3e5,0x0 }
+#define NETWORKSERVICE_LUID { 0x3e4,0x0 }
+#define IUSER_LUID { 0x3e3, 0x0 }
+
+#define SE_GROUP_MANDATORY (0x00000001L)
+#define SE_GROUP_ENABLED_BY_DEFAULT (0x00000002L)
+#define SE_GROUP_ENABLED (0x00000004L)
+#define SE_GROUP_OWNER (0x00000008L)
+#define SE_GROUP_USE_FOR_DENY_ONLY (0x00000010L)
+#define SE_GROUP_INTEGRITY (0x00000020L)
+#define SE_GROUP_INTEGRITY_ENABLED (0x00000040L)
+#define SE_GROUP_LOGON_ID (0xC0000000L)
+#define SE_GROUP_RESOURCE (0x20000000L)
+
+#define ACL_REVISION (2)
+#define ACL_REVISION_DS (4)
+
+#define ACL_REVISION1 (1)
+#define MIN_ACL_REVISION ACL_REVISION2
+#define ACL_REVISION2 (2)
+#define ACL_REVISION3 (3)
+#define ACL_REVISION4 (4)
+#define MAX_ACL_REVISION ACL_REVISION4
+
+ typedef struct _ACL {
+ BYTE AclRevision;
+ BYTE Sbz1;
+ WORD AclSize;
+ WORD AceCount;
+ WORD Sbz2;
+ } ACL;
+ typedef ACL *PACL;
+
+ typedef struct _ACE_HEADER {
+ BYTE AceType;
+ BYTE AceFlags;
+ WORD AceSize;
+ } ACE_HEADER;
+ typedef ACE_HEADER *PACE_HEADER;
+
+#define ACCESS_MIN_MS_ACE_TYPE (0x0)
+#define ACCESS_ALLOWED_ACE_TYPE (0x0)
+#define ACCESS_DENIED_ACE_TYPE (0x1)
+#define SYSTEM_AUDIT_ACE_TYPE (0x2)
+#define SYSTEM_ALARM_ACE_TYPE (0x3)
+#define ACCESS_MAX_MS_V2_ACE_TYPE (0x3)
+
+#define ACCESS_ALLOWED_COMPOUND_ACE_TYPE (0x4)
+#define ACCESS_MAX_MS_V3_ACE_TYPE (0x4)
+
+#define ACCESS_MIN_MS_OBJECT_ACE_TYPE (0x5)
+#define ACCESS_ALLOWED_OBJECT_ACE_TYPE (0x5)
+#define ACCESS_DENIED_OBJECT_ACE_TYPE (0x6)
+#define SYSTEM_AUDIT_OBJECT_ACE_TYPE (0x7)
+#define SYSTEM_ALARM_OBJECT_ACE_TYPE (0x8)
+#define ACCESS_MAX_MS_OBJECT_ACE_TYPE (0x8)
+
+#define ACCESS_MAX_MS_V4_ACE_TYPE (0x8)
+#define ACCESS_MAX_MS_ACE_TYPE (0x8)
+
+#define ACCESS_ALLOWED_CALLBACK_ACE_TYPE (0x9)
+#define ACCESS_DENIED_CALLBACK_ACE_TYPE (0xA)
+#define ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE (0xB)
+#define ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE (0xC)
+#define SYSTEM_AUDIT_CALLBACK_ACE_TYPE (0xD)
+#define SYSTEM_ALARM_CALLBACK_ACE_TYPE (0xE)
+#define SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE (0xF)
+#define SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE (0x10)
+
+#define SYSTEM_MANDATORY_LABEL_ACE_TYPE (0x11)
+#define ACCESS_MAX_MS_V5_ACE_TYPE (0x11)
+
+#define OBJECT_INHERIT_ACE (0x1)
+#define CONTAINER_INHERIT_ACE (0x2)
+#define NO_PROPAGATE_INHERIT_ACE (0x4)
+#define INHERIT_ONLY_ACE (0x8)
+#define INHERITED_ACE (0x10)
+#define VALID_INHERIT_FLAGS (0x1F)
+
+#define SUCCESSFUL_ACCESS_ACE_FLAG (0x40)
+#define FAILED_ACCESS_ACE_FLAG (0x80)
+
+ typedef struct _ACCESS_ALLOWED_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+ } ACCESS_ALLOWED_ACE;
+
+ typedef ACCESS_ALLOWED_ACE *PACCESS_ALLOWED_ACE;
+
+ typedef struct _ACCESS_DENIED_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+ } ACCESS_DENIED_ACE;
+ typedef ACCESS_DENIED_ACE *PACCESS_DENIED_ACE;
+
+ typedef struct _SYSTEM_AUDIT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+ } SYSTEM_AUDIT_ACE;
+ typedef SYSTEM_AUDIT_ACE *PSYSTEM_AUDIT_ACE;
+
+ typedef struct _SYSTEM_ALARM_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+ } SYSTEM_ALARM_ACE;
+ typedef SYSTEM_ALARM_ACE *PSYSTEM_ALARM_ACE;
+
+ typedef struct _ACCESS_ALLOWED_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+ } ACCESS_ALLOWED_OBJECT_ACE,*PACCESS_ALLOWED_OBJECT_ACE;
+
+ typedef struct _ACCESS_DENIED_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+ } ACCESS_DENIED_OBJECT_ACE,*PACCESS_DENIED_OBJECT_ACE;
+
+ typedef struct _SYSTEM_AUDIT_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+ } SYSTEM_AUDIT_OBJECT_ACE,*PSYSTEM_AUDIT_OBJECT_ACE;
+
+ typedef struct _SYSTEM_ALARM_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+ } SYSTEM_ALARM_OBJECT_ACE,*PSYSTEM_ALARM_OBJECT_ACE;
+
+ typedef struct _ACCESS_ALLOWED_CALLBACK_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+
+ } ACCESS_ALLOWED_CALLBACK_ACE,*PACCESS_ALLOWED_CALLBACK_ACE;
+
+ typedef struct _ACCESS_DENIED_CALLBACK_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+
+ } ACCESS_DENIED_CALLBACK_ACE,*PACCESS_DENIED_CALLBACK_ACE;
+
+ typedef struct _SYSTEM_AUDIT_CALLBACK_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+
+ } SYSTEM_AUDIT_CALLBACK_ACE,*PSYSTEM_AUDIT_CALLBACK_ACE;
+
+ typedef struct _SYSTEM_ALARM_CALLBACK_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+
+ } SYSTEM_ALARM_CALLBACK_ACE,*PSYSTEM_ALARM_CALLBACK_ACE;
+
+ typedef struct _ACCESS_ALLOWED_CALLBACK_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+
+ } ACCESS_ALLOWED_CALLBACK_OBJECT_ACE,*PACCESS_ALLOWED_CALLBACK_OBJECT_ACE;
+
+ typedef struct _ACCESS_DENIED_CALLBACK_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+
+ } ACCESS_DENIED_CALLBACK_OBJECT_ACE,*PACCESS_DENIED_CALLBACK_OBJECT_ACE;
+
+ typedef struct _SYSTEM_AUDIT_CALLBACK_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+
+ } SYSTEM_AUDIT_CALLBACK_OBJECT_ACE,*PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE;
+
+ typedef struct _SYSTEM_ALARM_CALLBACK_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+
+ } SYSTEM_ALARM_CALLBACK_OBJECT_ACE,*PSYSTEM_ALARM_CALLBACK_OBJECT_ACE;
+
+#define ACE_OBJECT_TYPE_PRESENT 0x1
+#define ACE_INHERITED_OBJECT_TYPE_PRESENT 0x2
+
+ typedef enum _ACL_INFORMATION_CLASS {
+ AclRevisionInformation = 1,AclSizeInformation
+ } ACL_INFORMATION_CLASS;
+
+ typedef struct _ACL_REVISION_INFORMATION {
+ DWORD AclRevision;
+ } ACL_REVISION_INFORMATION;
+ typedef ACL_REVISION_INFORMATION *PACL_REVISION_INFORMATION;
+
+ typedef struct _ACL_SIZE_INFORMATION {
+ DWORD AceCount;
+ DWORD AclBytesInUse;
+ DWORD AclBytesFree;
+ } ACL_SIZE_INFORMATION;
+ typedef ACL_SIZE_INFORMATION *PACL_SIZE_INFORMATION;
+
+#define SECURITY_DESCRIPTOR_REVISION (1)
+#define SECURITY_DESCRIPTOR_REVISION1 (1)
+
+#define SECURITY_DESCRIPTOR_MIN_LENGTH (sizeof(SECURITY_DESCRIPTOR))
+
+ typedef WORD SECURITY_DESCRIPTOR_CONTROL,*PSECURITY_DESCRIPTOR_CONTROL;
+
+#define SE_OWNER_DEFAULTED (0x0001)
+#define SE_GROUP_DEFAULTED (0x0002)
+#define SE_DACL_PRESENT (0x0004)
+#define SE_DACL_DEFAULTED (0x0008)
+#define SE_SACL_PRESENT (0x0010)
+#define SE_SACL_DEFAULTED (0x0020)
+#define SE_DACL_AUTO_INHERIT_REQ (0x0100)
+#define SE_SACL_AUTO_INHERIT_REQ (0x0200)
+#define SE_DACL_AUTO_INHERITED (0x0400)
+#define SE_SACL_AUTO_INHERITED (0x0800)
+#define SE_DACL_PROTECTED (0x1000)
+#define SE_SACL_PROTECTED (0x2000)
+#define SE_RM_CONTROL_VALID (0x4000)
+#define SE_SELF_RELATIVE (0x8000)
+
+ typedef struct _SECURITY_DESCRIPTOR_RELATIVE {
+ BYTE Revision;
+ BYTE Sbz1;
+ SECURITY_DESCRIPTOR_CONTROL Control;
+ DWORD Owner;
+ DWORD Group;
+ DWORD Sacl;
+ DWORD Dacl;
+ } SECURITY_DESCRIPTOR_RELATIVE,*PISECURITY_DESCRIPTOR_RELATIVE;
+
+ typedef struct _SECURITY_DESCRIPTOR {
+ BYTE Revision;
+ BYTE Sbz1;
+ SECURITY_DESCRIPTOR_CONTROL Control;
+ PSID Owner;
+ PSID Group;
+ PACL Sacl;
+ PACL Dacl;
+
+ } SECURITY_DESCRIPTOR,*PISECURITY_DESCRIPTOR;
+
+ typedef struct _OBJECT_TYPE_LIST {
+ WORD Level;
+ WORD Sbz;
+ GUID *ObjectType;
+ } OBJECT_TYPE_LIST,*POBJECT_TYPE_LIST;
+
+#define ACCESS_OBJECT_GUID 0
+#define ACCESS_PROPERTY_SET_GUID 1
+#define ACCESS_PROPERTY_GUID 2
+
+#define ACCESS_MAX_LEVEL 4
+
+ typedef enum _AUDIT_EVENT_TYPE {
+ AuditEventObjectAccess,AuditEventDirectoryServiceAccess
+ } AUDIT_EVENT_TYPE,*PAUDIT_EVENT_TYPE;
+
+#define AUDIT_ALLOW_NO_PRIVILEGE 0x1
+
+#define ACCESS_DS_SOURCE_A "DS"
+#define ACCESS_DS_SOURCE_W L"DS"
+#define ACCESS_DS_OBJECT_TYPE_NAME_A "Directory Service Object"
+#define ACCESS_DS_OBJECT_TYPE_NAME_W L"Directory Service Object"
+
+#define SE_PRIVILEGE_ENABLED_BY_DEFAULT (0x00000001L)
+#define SE_PRIVILEGE_ENABLED (0x00000002L)
+#define SE_PRIVILEGE_REMOVED (0X00000004L)
+#define SE_PRIVILEGE_USED_FOR_ACCESS (0x80000000L)
+
+#define PRIVILEGE_SET_ALL_NECESSARY (1)
+
+ typedef struct _PRIVILEGE_SET {
+ DWORD PrivilegeCount;
+ DWORD Control;
+ LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
+ } PRIVILEGE_SET,*PPRIVILEGE_SET;
+
+#define SE_CREATE_TOKEN_NAME TEXT("SeCreateTokenPrivilege")
+#define SE_ASSIGNPRIMARYTOKEN_NAME TEXT("SeAssignPrimaryTokenPrivilege")
+#define SE_LOCK_MEMORY_NAME TEXT("SeLockMemoryPrivilege")
+#define SE_INCREASE_QUOTA_NAME TEXT("SeIncreaseQuotaPrivilege")
+#define SE_UNSOLICITED_INPUT_NAME TEXT("SeUnsolicitedInputPrivilege")
+#define SE_MACHINE_ACCOUNT_NAME TEXT("SeMachineAccountPrivilege")
+#define SE_TCB_NAME TEXT("SeTcbPrivilege")
+#define SE_SECURITY_NAME TEXT("SeSecurityPrivilege")
+#define SE_TAKE_OWNERSHIP_NAME TEXT("SeTakeOwnershipPrivilege")
+#define SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege")
+#define SE_SYSTEM_PROFILE_NAME TEXT("SeSystemProfilePrivilege")
+#define SE_SYSTEMTIME_NAME TEXT("SeSystemtimePrivilege")
+#define SE_PROF_SINGLE_PROCESS_NAME TEXT("SeProfileSingleProcessPrivilege")
+#define SE_INC_BASE_PRIORITY_NAME TEXT("SeIncreaseBasePriorityPrivilege")
+#define SE_CREATE_PAGEFILE_NAME TEXT("SeCreatePagefilePrivilege")
+#define SE_CREATE_PERMANENT_NAME TEXT("SeCreatePermanentPrivilege")
+#define SE_BACKUP_NAME TEXT("SeBackupPrivilege")
+#define SE_RESTORE_NAME TEXT("SeRestorePrivilege")
+#define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege")
+#define SE_DEBUG_NAME TEXT("SeDebugPrivilege")
+#define SE_AUDIT_NAME TEXT("SeAuditPrivilege")
+#define SE_SYSTEM_ENVIRONMENT_NAME TEXT("SeSystemEnvironmentPrivilege")
+#define SE_CHANGE_NOTIFY_NAME TEXT("SeChangeNotifyPrivilege")
+#define SE_REMOTE_SHUTDOWN_NAME TEXT("SeRemoteShutdownPrivilege")
+#define SE_UNDOCK_NAME TEXT("SeUndockPrivilege")
+#define SE_SYNC_AGENT_NAME TEXT("SeSyncAgentPrivilege")
+#define SE_ENABLE_DELEGATION_NAME TEXT("SeEnableDelegationPrivilege")
+#define SE_MANAGE_VOLUME_NAME TEXT("SeManageVolumePrivilege")
+#define SE_IMPERSONATE_NAME TEXT("SeImpersonatePrivilege")
+#define SE_CREATE_GLOBAL_NAME TEXT("SeCreateGlobalPrivilege")
+
+ typedef enum _SECURITY_IMPERSONATION_LEVEL {
+ SecurityAnonymous,SecurityIdentification,SecurityImpersonation,SecurityDelegation
+ } SECURITY_IMPERSONATION_LEVEL,*PSECURITY_IMPERSONATION_LEVEL;
+
+#define SECURITY_MAX_IMPERSONATION_LEVEL SecurityDelegation
+#define SECURITY_MIN_IMPERSONATION_LEVEL SecurityAnonymous
+#define DEFAULT_IMPERSONATION_LEVEL SecurityImpersonation
+#define VALID_IMPERSONATION_LEVEL(L) (((L) >= SECURITY_MIN_IMPERSONATION_LEVEL) && ((L) <= SECURITY_MAX_IMPERSONATION_LEVEL))
+
+#define TOKEN_ASSIGN_PRIMARY (0x0001)
+#define TOKEN_DUPLICATE (0x0002)
+#define TOKEN_IMPERSONATE (0x0004)
+#define TOKEN_QUERY (0x0008)
+#define TOKEN_QUERY_SOURCE (0x0010)
+#define TOKEN_ADJUST_PRIVILEGES (0x0020)
+#define TOKEN_ADJUST_GROUPS (0x0040)
+#define TOKEN_ADJUST_DEFAULT (0x0080)
+#define TOKEN_ADJUST_SESSIONID (0x0100)
+
+#define TOKEN_ALL_ACCESS_P (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT)
+#define TOKEN_ALL_ACCESS (TOKEN_ALL_ACCESS_P | TOKEN_ADJUST_SESSIONID)
+#define TOKEN_READ (STANDARD_RIGHTS_READ | TOKEN_QUERY)
+
+#define TOKEN_WRITE (STANDARD_RIGHTS_WRITE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT)
+
+#define TOKEN_EXECUTE (STANDARD_RIGHTS_EXECUTE)
+
+ typedef enum _TOKEN_TYPE {
+ TokenPrimary = 1,TokenImpersonation
+ } TOKEN_TYPE;
+ typedef TOKEN_TYPE *PTOKEN_TYPE;
+
+ typedef enum _TOKEN_INFORMATION_CLASS {
+ TokenUser = 1,TokenGroups,TokenPrivileges,TokenOwner,TokenPrimaryGroup,TokenDefaultDacl,TokenSource,TokenType,TokenImpersonationLevel,
+ TokenStatistics,TokenRestrictedSids,TokenSessionId,TokenGroupsAndPrivileges,TokenSessionReference,TokenSandBoxInert,TokenAuditPolicy,
+ TokenOrigin,MaxTokenInfoClass
+ } TOKEN_INFORMATION_CLASS,*PTOKEN_INFORMATION_CLASS;
+
+ typedef struct _TOKEN_USER {
+ SID_AND_ATTRIBUTES User;
+ } TOKEN_USER,*PTOKEN_USER;
+
+ typedef struct _TOKEN_GROUPS {
+ DWORD GroupCount;
+ SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
+ } TOKEN_GROUPS,*PTOKEN_GROUPS;
+
+ typedef struct _TOKEN_PRIVILEGES {
+ DWORD PrivilegeCount;
+ LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
+ } TOKEN_PRIVILEGES,*PTOKEN_PRIVILEGES;
+
+ typedef struct _TOKEN_OWNER {
+ PSID Owner;
+ } TOKEN_OWNER,*PTOKEN_OWNER;
+
+ typedef struct _TOKEN_PRIMARY_GROUP {
+ PSID PrimaryGroup;
+ } TOKEN_PRIMARY_GROUP,*PTOKEN_PRIMARY_GROUP;
+
+ typedef struct _TOKEN_DEFAULT_DACL {
+ PACL DefaultDacl;
+ } TOKEN_DEFAULT_DACL,*PTOKEN_DEFAULT_DACL;
+
+ typedef struct _TOKEN_GROUPS_AND_PRIVILEGES {
+ DWORD SidCount;
+ DWORD SidLength;
+ PSID_AND_ATTRIBUTES Sids;
+ DWORD RestrictedSidCount;
+ DWORD RestrictedSidLength;
+ PSID_AND_ATTRIBUTES RestrictedSids;
+ DWORD PrivilegeCount;
+ DWORD PrivilegeLength;
+ PLUID_AND_ATTRIBUTES Privileges;
+ LUID AuthenticationId;
+ } TOKEN_GROUPS_AND_PRIVILEGES,*PTOKEN_GROUPS_AND_PRIVILEGES;
+
+#define TOKEN_AUDIT_SUCCESS_INCLUDE 0x1
+#define TOKEN_AUDIT_SUCCESS_EXCLUDE 0x2
+#define TOKEN_AUDIT_FAILURE_INCLUDE 0x4
+#define TOKEN_AUDIT_FAILURE_EXCLUDE 0x8
+
+#define VALID_AUDIT_POLICY_BITS (TOKEN_AUDIT_SUCCESS_INCLUDE | TOKEN_AUDIT_SUCCESS_EXCLUDE | TOKEN_AUDIT_FAILURE_INCLUDE | TOKEN_AUDIT_FAILURE_EXCLUDE)
+#define VALID_TOKEN_AUDIT_POLICY_ELEMENT(P) ((((P).PolicyMask & ~VALID_AUDIT_POLICY_BITS)==0) && ((P).Category <= AuditEventMaxType))
+
+ typedef struct _TOKEN_AUDIT_POLICY_ELEMENT {
+ DWORD Category;
+ DWORD PolicyMask;
+ } TOKEN_AUDIT_POLICY_ELEMENT,*PTOKEN_AUDIT_POLICY_ELEMENT;
+
+ typedef struct _TOKEN_AUDIT_POLICY {
+ DWORD PolicyCount;
+ TOKEN_AUDIT_POLICY_ELEMENT Policy[ANYSIZE_ARRAY];
+ } TOKEN_AUDIT_POLICY,*PTOKEN_AUDIT_POLICY;
+
+#define PER_USER_AUDITING_POLICY_SIZE(p) (sizeof(TOKEN_AUDIT_POLICY) + (((p)->PolicyCount > ANYSIZE_ARRAY) ? (sizeof(TOKEN_AUDIT_POLICY_ELEMENT) *((p)->PolicyCount - ANYSIZE_ARRAY)) : 0))
+#define PER_USER_AUDITING_POLICY_SIZE_BY_COUNT(C) (sizeof(TOKEN_AUDIT_POLICY) + (((C) > ANYSIZE_ARRAY) ? (sizeof(TOKEN_AUDIT_POLICY_ELEMENT) *((C) - ANYSIZE_ARRAY)) : 0))
+
+#define TOKEN_SOURCE_LENGTH 8
+
+ typedef struct _TOKEN_SOURCE {
+ CHAR SourceName[TOKEN_SOURCE_LENGTH];
+ LUID SourceIdentifier;
+ } TOKEN_SOURCE,*PTOKEN_SOURCE;
+
+ typedef struct _TOKEN_STATISTICS {
+ LUID TokenId;
+ LUID AuthenticationId;
+ LARGE_INTEGER ExpirationTime;
+ TOKEN_TYPE TokenType;
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+ DWORD DynamicCharged;
+ DWORD DynamicAvailable;
+ DWORD GroupCount;
+ DWORD PrivilegeCount;
+ LUID ModifiedId;
+ } TOKEN_STATISTICS,*PTOKEN_STATISTICS;
+
+ typedef struct _TOKEN_CONTROL {
+ LUID TokenId;
+ LUID AuthenticationId;
+ LUID ModifiedId;
+ TOKEN_SOURCE TokenSource;
+ } TOKEN_CONTROL,*PTOKEN_CONTROL;
+
+ typedef struct _TOKEN_ORIGIN {
+ LUID OriginatingLogonSession;
+ } TOKEN_ORIGIN,*PTOKEN_ORIGIN;
+
+#define SECURITY_DYNAMIC_TRACKING (TRUE)
+#define SECURITY_STATIC_TRACKING (FALSE)
+
+ typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE,*PSECURITY_CONTEXT_TRACKING_MODE;
+
+ typedef struct _SECURITY_QUALITY_OF_SERVICE {
+ DWORD Length;
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+ SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
+ BOOLEAN EffectiveOnly;
+ } SECURITY_QUALITY_OF_SERVICE,*PSECURITY_QUALITY_OF_SERVICE;
+
+ typedef struct _SE_IMPERSONATION_STATE {
+ PACCESS_TOKEN Token;
+ BOOLEAN CopyOnOpen;
+ BOOLEAN EffectiveOnly;
+ SECURITY_IMPERSONATION_LEVEL Level;
+ } SE_IMPERSONATION_STATE,*PSE_IMPERSONATION_STATE;
+
+#define DISABLE_MAX_PRIVILEGE 0x1
+#define SANDBOX_INERT 0x2
+
+ typedef DWORD SECURITY_INFORMATION,*PSECURITY_INFORMATION;
+
+#define OWNER_SECURITY_INFORMATION (0x00000001L)
+#define GROUP_SECURITY_INFORMATION (0x00000002L)
+#define DACL_SECURITY_INFORMATION (0x00000004L)
+#define SACL_SECURITY_INFORMATION (0x00000008L)
+
+#define PROTECTED_DACL_SECURITY_INFORMATION (0x80000000L)
+#define PROTECTED_SACL_SECURITY_INFORMATION (0x40000000L)
+#define UNPROTECTED_DACL_SECURITY_INFORMATION (0x20000000L)
+#define UNPROTECTED_SACL_SECURITY_INFORMATION (0x10000000L)
+
+#define PROCESS_TERMINATE (0x0001)
+#define PROCESS_CREATE_THREAD (0x0002)
+#define PROCESS_SET_SESSIONID (0x0004)
+#define PROCESS_VM_OPERATION (0x0008)
+#define PROCESS_VM_READ (0x0010)
+#define PROCESS_VM_WRITE (0x0020)
+#define PROCESS_DUP_HANDLE (0x0040)
+#define PROCESS_CREATE_PROCESS (0x0080)
+#define PROCESS_SET_QUOTA (0x0100)
+#define PROCESS_SET_INFORMATION (0x0200)
+#define PROCESS_QUERY_INFORMATION (0x0400)
+#define PROCESS_SUSPEND_RESUME (0x0800)
+#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF)
+
+#ifdef _WIN64
+#define MAXIMUM_PROCESSORS 64
+#else
+#define MAXIMUM_PROCESSORS 32
+#endif
+
+#define THREAD_TERMINATE (0x0001)
+#define THREAD_SUSPEND_RESUME (0x0002)
+#define THREAD_GET_CONTEXT (0x0008)
+#define THREAD_SET_CONTEXT (0x0010)
+#define THREAD_SET_INFORMATION (0x0020)
+#define THREAD_QUERY_INFORMATION (0x0040)
+#define THREAD_SET_THREAD_TOKEN (0x0080)
+#define THREAD_IMPERSONATE (0x0100)
+#define THREAD_DIRECT_IMPERSONATION (0x0200)
+
+#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3FF)
+
+#define JOB_OBJECT_ASSIGN_PROCESS (0x0001)
+#define JOB_OBJECT_SET_ATTRIBUTES (0x0002)
+#define JOB_OBJECT_QUERY (0x0004)
+#define JOB_OBJECT_TERMINATE (0x0008)
+#define JOB_OBJECT_SET_SECURITY_ATTRIBUTES (0x0010)
+#define JOB_OBJECT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1F)
+
+ typedef struct _JOB_SET_ARRAY {
+ HANDLE JobHandle;
+ DWORD MemberLevel;
+ DWORD Flags;
+ } JOB_SET_ARRAY,*PJOB_SET_ARRAY;
+
+#define FLS_MAXIMUM_AVAILABLE 128
+#define TLS_MINIMUM_AVAILABLE 64
+
+#ifndef _NT_TIB_DEFINED
+#define _NT_TIB_DEFINED
+ typedef struct _NT_TIB {
+ struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
+ PVOID StackBase;
+ PVOID StackLimit;
+ PVOID SubSystemTib;
+ union {
+ PVOID FiberData;
+ DWORD Version;
+ };
+ PVOID ArbitraryUserPointer;
+ struct _NT_TIB *Self;
+ } NT_TIB;
+ typedef NT_TIB *PNT_TIB;
+#endif
+
+ typedef struct _NT_TIB32 {
+ DWORD ExceptionList;
+ DWORD StackBase;
+ DWORD StackLimit;
+ DWORD SubSystemTib;
+ union {
+ DWORD FiberData;
+ DWORD Version;
+ };
+ DWORD ArbitraryUserPointer;
+ DWORD Self;
+ } NT_TIB32,*PNT_TIB32;
+
+ typedef struct _NT_TIB64 {
+ DWORD64 ExceptionList;
+ DWORD64 StackBase;
+ DWORD64 StackLimit;
+ DWORD64 SubSystemTib;
+ union {
+ DWORD64 FiberData;
+ DWORD Version;
+ };
+ DWORD64 ArbitraryUserPointer;
+ DWORD64 Self;
+ } NT_TIB64,*PNT_TIB64;
+
+#if !defined(I_X86_) && !defined(_IA64_) && !defined(_AMD64_)
+#define WX86
+#endif
+
+#define THREAD_BASE_PRIORITY_LOWRT 15
+#define THREAD_BASE_PRIORITY_MAX 2
+#define THREAD_BASE_PRIORITY_MIN (-2)
+#define THREAD_BASE_PRIORITY_IDLE (-15)
+
+ typedef struct _QUOTA_LIMITS {
+ SIZE_T PagedPoolLimit;
+ SIZE_T NonPagedPoolLimit;
+ SIZE_T MinimumWorkingSetSize;
+ SIZE_T MaximumWorkingSetSize;
+ SIZE_T PagefileLimit;
+ LARGE_INTEGER TimeLimit;
+ } QUOTA_LIMITS,*PQUOTA_LIMITS;
+
+#define QUOTA_LIMITS_HARDWS_MIN_ENABLE 0x00000001
+#define QUOTA_LIMITS_HARDWS_MIN_DISABLE 0x00000002
+#define QUOTA_LIMITS_HARDWS_MAX_ENABLE 0x00000004
+#define QUOTA_LIMITS_HARDWS_MAX_DISABLE 0x00000008
+
+ typedef struct _QUOTA_LIMITS_EX {
+ SIZE_T PagedPoolLimit;
+ SIZE_T NonPagedPoolLimit;
+ SIZE_T MinimumWorkingSetSize;
+ SIZE_T MaximumWorkingSetSize;
+ SIZE_T PagefileLimit;
+ LARGE_INTEGER TimeLimit;
+ SIZE_T Reserved1;
+ SIZE_T Reserved2;
+ SIZE_T Reserved3;
+ SIZE_T Reserved4;
+ DWORD Flags;
+ DWORD Reserved5;
+ } QUOTA_LIMITS_EX,*PQUOTA_LIMITS_EX;
+
+ typedef struct _IO_COUNTERS {
+ ULONGLONG ReadOperationCount;
+ ULONGLONG WriteOperationCount;
+ ULONGLONG OtherOperationCount;
+ ULONGLONG ReadTransferCount;
+ ULONGLONG WriteTransferCount;
+ ULONGLONG OtherTransferCount;
+ } IO_COUNTERS;
+ typedef IO_COUNTERS *PIO_COUNTERS;
+
+ typedef struct _JOBOBJECT_BASIC_ACCOUNTING_INFORMATION {
+ LARGE_INTEGER TotalUserTime;
+ LARGE_INTEGER TotalKernelTime;
+ LARGE_INTEGER ThisPeriodTotalUserTime;
+ LARGE_INTEGER ThisPeriodTotalKernelTime;
+ DWORD TotalPageFaultCount;
+ DWORD TotalProcesses;
+ DWORD ActiveProcesses;
+ DWORD TotalTerminatedProcesses;
+ } JOBOBJECT_BASIC_ACCOUNTING_INFORMATION,*PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION;
+
+ typedef struct _JOBOBJECT_BASIC_LIMIT_INFORMATION {
+ LARGE_INTEGER PerProcessUserTimeLimit;
+ LARGE_INTEGER PerJobUserTimeLimit;
+ DWORD LimitFlags;
+ SIZE_T MinimumWorkingSetSize;
+ SIZE_T MaximumWorkingSetSize;
+ DWORD ActiveProcessLimit;
+ ULONG_PTR Affinity;
+ DWORD PriorityClass;
+ DWORD SchedulingClass;
+ } JOBOBJECT_BASIC_LIMIT_INFORMATION,*PJOBOBJECT_BASIC_LIMIT_INFORMATION;
+
+ typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
+ JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
+ IO_COUNTERS IoInfo;
+ SIZE_T ProcessMemoryLimit;
+ SIZE_T JobMemoryLimit;
+ SIZE_T PeakProcessMemoryUsed;
+ SIZE_T PeakJobMemoryUsed;
+ } JOBOBJECT_EXTENDED_LIMIT_INFORMATION,*PJOBOBJECT_EXTENDED_LIMIT_INFORMATION;
+
+ typedef struct _JOBOBJECT_BASIC_PROCESS_ID_LIST {
+ DWORD NumberOfAssignedProcesses;
+ DWORD NumberOfProcessIdsInList;
+ ULONG_PTR ProcessIdList[1];
+ } JOBOBJECT_BASIC_PROCESS_ID_LIST,*PJOBOBJECT_BASIC_PROCESS_ID_LIST;
+
+ typedef struct _JOBOBJECT_BASIC_UI_RESTRICTIONS {
+ DWORD UIRestrictionsClass;
+ } JOBOBJECT_BASIC_UI_RESTRICTIONS,*PJOBOBJECT_BASIC_UI_RESTRICTIONS;
+
+ typedef struct _JOBOBJECT_SECURITY_LIMIT_INFORMATION {
+ DWORD SecurityLimitFlags;
+ HANDLE JobToken;
+ PTOKEN_GROUPS SidsToDisable;
+ PTOKEN_PRIVILEGES PrivilegesToDelete;
+ PTOKEN_GROUPS RestrictedSids;
+ } JOBOBJECT_SECURITY_LIMIT_INFORMATION,*PJOBOBJECT_SECURITY_LIMIT_INFORMATION;
+
+ typedef struct _JOBOBJECT_END_OF_JOB_TIME_INFORMATION {
+ DWORD EndOfJobTimeAction;
+ } JOBOBJECT_END_OF_JOB_TIME_INFORMATION,*PJOBOBJECT_END_OF_JOB_TIME_INFORMATION;
+
+ typedef struct _JOBOBJECT_ASSOCIATE_COMPLETION_PORT {
+ PVOID CompletionKey;
+ HANDLE CompletionPort;
+ } JOBOBJECT_ASSOCIATE_COMPLETION_PORT,*PJOBOBJECT_ASSOCIATE_COMPLETION_PORT;
+
+ typedef struct _JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION {
+ JOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicInfo;
+ IO_COUNTERS IoInfo;
+ } JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION,*PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION;
+
+ typedef struct _JOBOBJECT_JOBSET_INFORMATION {
+ DWORD MemberLevel;
+ } JOBOBJECT_JOBSET_INFORMATION,*PJOBOBJECT_JOBSET_INFORMATION;
+
+#define JOB_OBJECT_TERMINATE_AT_END_OF_JOB 0
+#define JOB_OBJECT_POST_AT_END_OF_JOB 1
+
+#define JOB_OBJECT_MSG_END_OF_JOB_TIME 1
+#define JOB_OBJECT_MSG_END_OF_PROCESS_TIME 2
+#define JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT 3
+#define JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO 4
+#define JOB_OBJECT_MSG_NEW_PROCESS 6
+#define JOB_OBJECT_MSG_EXIT_PROCESS 7
+#define JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS 8
+#define JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT 9
+#define JOB_OBJECT_MSG_JOB_MEMORY_LIMIT 10
+
+#define JOB_OBJECT_LIMIT_WORKINGSET 0x00000001
+#define JOB_OBJECT_LIMIT_PROCESS_TIME 0x00000002
+#define JOB_OBJECT_LIMIT_JOB_TIME 0x00000004
+#define JOB_OBJECT_LIMIT_ACTIVE_PROCESS 0x00000008
+#define JOB_OBJECT_LIMIT_AFFINITY 0x00000010
+#define JOB_OBJECT_LIMIT_PRIORITY_CLASS 0x00000020
+#define JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME 0x00000040
+#define JOB_OBJECT_LIMIT_SCHEDULING_CLASS 0x00000080
+
+#define JOB_OBJECT_LIMIT_PROCESS_MEMORY 0x00000100
+#define JOB_OBJECT_LIMIT_JOB_MEMORY 0x00000200
+#define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x00000400
+#define JOB_OBJECT_LIMIT_BREAKAWAY_OK 0x00000800
+#define JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK 0x00001000
+#define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000
+
+#define JOB_OBJECT_LIMIT_RESERVED2 0x00004000
+#define JOB_OBJECT_LIMIT_RESERVED3 0x00008000
+#define JOB_OBJECT_LIMIT_RESERVED4 0x00010000
+#define JOB_OBJECT_LIMIT_RESERVED5 0x00020000
+#define JOB_OBJECT_LIMIT_RESERVED6 0x00040000
+
+#define JOB_OBJECT_LIMIT_VALID_FLAGS 0x0007ffff
+
+#define JOB_OBJECT_BASIC_LIMIT_VALID_FLAGS 0x000000ff
+#define JOB_OBJECT_EXTENDED_LIMIT_VALID_FLAGS 0x00003fff
+#define JOB_OBJECT_RESERVED_LIMIT_VALID_FLAGS 0x0007ffff
+
+#define JOB_OBJECT_UILIMIT_NONE 0x00000000
+
+#define JOB_OBJECT_UILIMIT_HANDLES 0x00000001
+#define JOB_OBJECT_UILIMIT_READCLIPBOARD 0x00000002
+#define JOB_OBJECT_UILIMIT_WRITECLIPBOARD 0x00000004
+#define JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS 0x00000008
+#define JOB_OBJECT_UILIMIT_DISPLAYSETTINGS 0x00000010
+#define JOB_OBJECT_UILIMIT_GLOBALATOMS 0x00000020
+#define JOB_OBJECT_UILIMIT_DESKTOP 0x00000040
+#define JOB_OBJECT_UILIMIT_EXITWINDOWS 0x00000080
+
+#define JOB_OBJECT_UILIMIT_ALL 0x000000FF
+
+#define JOB_OBJECT_UI_VALID_FLAGS 0x000000FF
+
+#define JOB_OBJECT_SECURITY_NO_ADMIN 0x00000001
+#define JOB_OBJECT_SECURITY_RESTRICTED_TOKEN 0x00000002
+#define JOB_OBJECT_SECURITY_ONLY_TOKEN 0x00000004
+#define JOB_OBJECT_SECURITY_FILTER_TOKENS 0x00000008
+
+#define JOB_OBJECT_SECURITY_VALID_FLAGS 0x0000000f
+
+ typedef enum _JOBOBJECTINFOCLASS {
+ JobObjectBasicAccountingInformation = 1,JobObjectBasicLimitInformation,JobObjectBasicProcessIdList,JobObjectBasicUIRestrictions,
+ JobObjectSecurityLimitInformation,JobObjectEndOfJobTimeInformation,JobObjectAssociateCompletionPortInformation,
+ JobObjectBasicAndIoAccountingInformation,JobObjectExtendedLimitInformation,JobObjectJobSetInformation,MaxJobObjectInfoClass
+ } JOBOBJECTINFOCLASS;
+
+#define EVENT_MODIFY_STATE 0x0002
+#define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
+
+#define MUTANT_QUERY_STATE 0x0001
+
+#define MUTANT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE| MUTANT_QUERY_STATE)
+#define SEMAPHORE_MODIFY_STATE 0x0002
+#define SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
+
+#define TIMER_QUERY_STATE 0x0001
+#define TIMER_MODIFY_STATE 0x0002
+
+#define TIMER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE| TIMER_QUERY_STATE|TIMER_MODIFY_STATE)
+
+#define TIME_ZONE_ID_UNKNOWN 0
+#define TIME_ZONE_ID_STANDARD 1
+#define TIME_ZONE_ID_DAYLIGHT 2
+
+ typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP {
+ RelationProcessorCore,RelationNumaNode,RelationCache
+ } LOGICAL_PROCESSOR_RELATIONSHIP;
+
+#define LTP_PC_SMT 0x1
+
+ typedef enum _PROCESSOR_CACHE_TYPE {
+ CacheUnified,CacheInstruction,CacheData,CacheTrace
+ } PROCESSOR_CACHE_TYPE;
+
+#define CACHE_FULLY_ASSOCIATIVE 0xFF
+
+ typedef struct _CACHE_DESCRIPTOR {
+ BYTE Level;
+ BYTE Associativity;
+ WORD LineSize;
+ DWORD Size;
+ PROCESSOR_CACHE_TYPE Type;
+ } CACHE_DESCRIPTOR,*PCACHE_DESCRIPTOR;
+
+ typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION {
+ ULONG_PTR ProcessorMask;
+ LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
+ union {
+ struct {
+ BYTE Flags;
+ } ProcessorCore;
+ struct {
+ DWORD NodeNumber;
+ } NumaNode;
+ CACHE_DESCRIPTOR Cache;
+ ULONGLONG Reserved[2];
+ };
+ } SYSTEM_LOGICAL_PROCESSOR_INFORMATION,*PSYSTEM_LOGICAL_PROCESSOR_INFORMATION;
+
+#define PROCESSOR_INTEL_386 386
+#define PROCESSOR_INTEL_486 486
+#define PROCESSOR_INTEL_PENTIUM 586
+#define PROCESSOR_INTEL_IA64 2200
+#define PROCESSOR_AMD_X8664 8664
+#define PROCESSOR_MIPS_R4000 4000
+#define PROCESSOR_ALPHA_21064 21064
+#define PROCESSOR_PPC_601 601
+#define PROCESSOR_PPC_603 603
+#define PROCESSOR_PPC_604 604
+#define PROCESSOR_PPC_620 620
+#define PROCESSOR_HITACHI_SH3 10003
+#define PROCESSOR_HITACHI_SH3E 10004
+#define PROCESSOR_HITACHI_SH4 10005
+#define PROCESSOR_MOTOROLA_821 821
+#define PROCESSOR_SHx_SH3 103
+#define PROCESSOR_SHx_SH4 104
+#define PROCESSOR_STRONGARM 2577
+#define PROCESSOR_ARM720 1824
+#define PROCESSOR_ARM820 2080
+#define PROCESSOR_ARM920 2336
+#define PROCESSOR_ARM_7TDMI 70001
+#define PROCESSOR_OPTIL 0x494f
+
+#define PROCESSOR_ARCHITECTURE_INTEL 0
+#define PROCESSOR_ARCHITECTURE_MIPS 1
+#define PROCESSOR_ARCHITECTURE_ALPHA 2
+#define PROCESSOR_ARCHITECTURE_PPC 3
+#define PROCESSOR_ARCHITECTURE_SHX 4
+#define PROCESSOR_ARCHITECTURE_ARM 5
+#define PROCESSOR_ARCHITECTURE_IA64 6
+#define PROCESSOR_ARCHITECTURE_ALPHA64 7
+#define PROCESSOR_ARCHITECTURE_MSIL 8
+#define PROCESSOR_ARCHITECTURE_AMD64 9
+#define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10
+
+#define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF
+
+#define PF_FLOATING_POINT_PRECISION_ERRATA 0
+#define PF_FLOATING_POINT_EMULATED 1
+#define PF_COMPARE_EXCHANGE_DOUBLE 2
+#define PF_MMX_INSTRUCTIONS_AVAILABLE 3
+#define PF_PPC_MOVEMEM_64BIT_OK 4
+#define PF_ALPHA_BYTE_INSTRUCTIONS 5
+#define PF_XMMI_INSTRUCTIONS_AVAILABLE 6
+#define PF_3DNOW_INSTRUCTIONS_AVAILABLE 7
+#define PF_RDTSC_INSTRUCTION_AVAILABLE 8
+#define PF_PAE_ENABLED 9
+#define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10
+#define PF_SSE_DAZ_MODE_AVAILABLE 11
+#define PF_NX_ENABLED 12
+
+ typedef struct _MEMORY_BASIC_INFORMATION {
+ PVOID BaseAddress;
+ PVOID AllocationBase;
+ DWORD AllocationProtect;
+ SIZE_T RegionSize;
+ DWORD State;
+ DWORD Protect;
+ DWORD Type;
+ } MEMORY_BASIC_INFORMATION,*PMEMORY_BASIC_INFORMATION;
+
+ typedef struct _MEMORY_BASIC_INFORMATION32 {
+ DWORD BaseAddress;
+ DWORD AllocationBase;
+ DWORD AllocationProtect;
+ DWORD RegionSize;
+ DWORD State;
+ DWORD Protect;
+ DWORD Type;
+ } MEMORY_BASIC_INFORMATION32,*PMEMORY_BASIC_INFORMATION32;
+
+ typedef DECLSPEC_ALIGN(16) struct _MEMORY_BASIC_INFORMATION64 {
+ ULONGLONG BaseAddress;
+ ULONGLONG AllocationBase;
+ DWORD AllocationProtect;
+ DWORD __alignment1;
+ ULONGLONG RegionSize;
+ DWORD State;
+ DWORD Protect;
+ DWORD Type;
+ DWORD __alignment2;
+ } MEMORY_BASIC_INFORMATION64,*PMEMORY_BASIC_INFORMATION64;
+
+#define SECTION_QUERY 0x0001
+#define SECTION_MAP_WRITE 0x0002
+#define SECTION_MAP_READ 0x0004
+#define SECTION_MAP_EXECUTE 0x0008
+#define SECTION_EXTEND_SIZE 0x0010
+#define SECTION_MAP_EXECUTE_EXPLICIT 0x0020
+
+#define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY| SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_EXTEND_SIZE)
+#define PAGE_NOACCESS 0x01
+#define PAGE_READONLY 0x02
+#define PAGE_READWRITE 0x04
+#define PAGE_WRITECOPY 0x08
+#define PAGE_EXECUTE 0x10
+#define PAGE_EXECUTE_READ 0x20
+#define PAGE_EXECUTE_READWRITE 0x40
+#define PAGE_EXECUTE_WRITECOPY 0x80
+#define PAGE_GUARD 0x100
+#define PAGE_NOCACHE 0x200
+#define PAGE_WRITECOMBINE 0x400
+#define MEM_COMMIT 0x1000
+#define MEM_RESERVE 0x2000
+#define MEM_DECOMMIT 0x4000
+#define MEM_RELEASE 0x8000
+#define MEM_FREE 0x10000
+#define MEM_PRIVATE 0x20000
+#define MEM_MAPPED 0x40000
+#define MEM_RESET 0x80000
+#define MEM_TOP_DOWN 0x100000
+#define MEM_WRITE_WATCH 0x200000
+#define MEM_PHYSICAL 0x400000
+#define MEM_LARGE_PAGES 0x20000000
+#define MEM_4MB_PAGES 0x80000000
+#define SEC_FILE 0x800000
+#define SEC_IMAGE 0x1000000
+#define SEC_RESERVE 0x4000000
+#define SEC_COMMIT 0x8000000
+#define SEC_NOCACHE 0x10000000
+#define SEC_LARGE_PAGES 0x80000000
+#define MEM_IMAGE SEC_IMAGE
+#define WRITE_WATCH_FLAG_RESET 0x01
+
+#define FILE_READ_DATA (0x0001)
+#define FILE_LIST_DIRECTORY (0x0001)
+
+#define FILE_WRITE_DATA (0x0002)
+#define FILE_ADD_FILE (0x0002)
+
+#define FILE_APPEND_DATA (0x0004)
+#define FILE_ADD_SUBDIRECTORY (0x0004)
+#define FILE_CREATE_PIPE_INSTANCE (0x0004)
+
+#define FILE_READ_EA (0x0008)
+
+#define FILE_WRITE_EA (0x0010)
+
+#define FILE_EXECUTE (0x0020)
+#define FILE_TRAVERSE (0x0020)
+
+#define FILE_DELETE_CHILD (0x0040)
+
+#define FILE_READ_ATTRIBUTES (0x0080)
+
+#define FILE_WRITE_ATTRIBUTES (0x0100)
+
+#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
+#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE)
+#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE)
+#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE)
+
+#define FILE_SHARE_READ 0x00000001
+#define FILE_SHARE_WRITE 0x00000002
+#define FILE_SHARE_DELETE 0x00000004
+#define FILE_ATTRIBUTE_READONLY 0x00000001
+#define FILE_ATTRIBUTE_HIDDEN 0x00000002
+#define FILE_ATTRIBUTE_SYSTEM 0x00000004
+#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
+#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
+#define FILE_ATTRIBUTE_DEVICE 0x00000040
+#define FILE_ATTRIBUTE_NORMAL 0x00000080
+#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
+#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
+#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
+#define FILE_ATTRIBUTE_COMPRESSED 0x00000800
+#define FILE_ATTRIBUTE_OFFLINE 0x00001000
+#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
+#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
+#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001
+#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002
+#define FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004
+#define FILE_NOTIFY_CHANGE_SIZE 0x00000008
+#define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010
+#define FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020
+#define FILE_NOTIFY_CHANGE_CREATION 0x00000040
+#define FILE_NOTIFY_CHANGE_SECURITY 0x00000100
+#define FILE_ACTION_ADDED 0x00000001
+#define FILE_ACTION_REMOVED 0x00000002
+#define FILE_ACTION_MODIFIED 0x00000003
+#define FILE_ACTION_RENAMED_OLD_NAME 0x00000004
+#define FILE_ACTION_RENAMED_NEW_NAME 0x00000005
+#define MAILSLOT_NO_MESSAGE ((DWORD)-1)
+#define MAILSLOT_WAIT_FOREVER ((DWORD)-1)
+#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
+#define FILE_CASE_PRESERVED_NAMES 0x00000002
+#define FILE_UNICODE_ON_DISK 0x00000004
+#define FILE_PERSISTENT_ACLS 0x00000008
+#define FILE_FILE_COMPRESSION 0x00000010
+#define FILE_VOLUME_QUOTAS 0x00000020
+#define FILE_SUPPORTS_SPARSE_FILES 0x00000040
+#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080
+#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100
+#define FILE_VOLUME_IS_COMPRESSED 0x00008000
+#define FILE_SUPPORTS_OBJECT_IDS 0x00010000
+#define FILE_SUPPORTS_ENCRYPTION 0x00020000
+#define FILE_NAMED_STREAMS 0x00040000
+#define FILE_READ_ONLY_VOLUME 0x00080000
+
+ typedef struct _FILE_NOTIFY_INFORMATION {
+ DWORD NextEntryOffset;
+ DWORD Action;
+ DWORD FileNameLength;
+ WCHAR FileName[1];
+ } FILE_NOTIFY_INFORMATION,*PFILE_NOTIFY_INFORMATION;
+
+ typedef union _FILE_SEGMENT_ELEMENT {
+ PVOID64 Buffer;
+ ULONGLONG Alignment;
+ }FILE_SEGMENT_ELEMENT,*PFILE_SEGMENT_ELEMENT;
+
+ typedef struct _REPARSE_GUID_DATA_BUFFER {
+ DWORD ReparseTag;
+ WORD ReparseDataLength;
+ WORD Reserved;
+ GUID ReparseGuid;
+ struct {
+ BYTE DataBuffer[1];
+ } GenericReparseBuffer;
+ } REPARSE_GUID_DATA_BUFFER,*PREPARSE_GUID_DATA_BUFFER;
+
+#define REPARSE_GUID_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_GUID_DATA_BUFFER,GenericReparseBuffer)
+
+#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE (16 *1024)
+
+#define IO_REPARSE_TAG_RESERVED_ZERO (0)
+#define IO_REPARSE_TAG_RESERVED_ONE (1)
+
+#define IO_REPARSE_TAG_RESERVED_RANGE IO_REPARSE_TAG_RESERVED_ONE
+
+#define IsReparseTagMicrosoft(_tag) (((_tag) & 0x80000000))
+#define IsReparseTagNameSurrogate(_tag) (((_tag) & 0x20000000))
+
+#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
+#define IO_REPARSE_TAG_HSM (0xC0000004L)
+#define IO_REPARSE_TAG_SIS (0x80000007L)
+#define IO_REPARSE_TAG_DFS (0x8000000AL)
+#define IO_REPARSE_TAG_FILTER_MANAGER (0x8000000BL)
+#define IO_COMPLETION_MODIFY_STATE 0x0002
+#define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
+#define DUPLICATE_CLOSE_SOURCE 0x00000001
+#define DUPLICATE_SAME_ACCESS 0x00000002
+
+ typedef enum _SYSTEM_POWER_STATE {
+ PowerSystemUnspecified = 0,PowerSystemWorking = 1,PowerSystemSleeping1 = 2,PowerSystemSleeping2 = 3,PowerSystemSleeping3 = 4,PowerSystemHibernate = 5,PowerSystemShutdown = 6,PowerSystemMaximum = 7
+ } SYSTEM_POWER_STATE,*PSYSTEM_POWER_STATE;
+
+#define POWER_SYSTEM_MAXIMUM 7
+
+ typedef enum {
+ PowerActionNone = 0,PowerActionReserved,PowerActionSleep,PowerActionHibernate,PowerActionShutdown,PowerActionShutdownReset,PowerActionShutdownOff,PowerActionWarmEject
+ } POWER_ACTION,*PPOWER_ACTION;
+
+ typedef enum _DEVICE_POWER_STATE {
+ PowerDeviceUnspecified = 0,PowerDeviceD0,PowerDeviceD1,PowerDeviceD2,PowerDeviceD3,PowerDeviceMaximum
+ } DEVICE_POWER_STATE,*PDEVICE_POWER_STATE;
+
+#define ES_SYSTEM_REQUIRED ((DWORD)0x00000001)
+#define ES_DISPLAY_REQUIRED ((DWORD)0x00000002)
+#define ES_USER_PRESENT ((DWORD)0x00000004)
+#define ES_CONTINUOUS ((DWORD)0x80000000)
+
+ typedef DWORD EXECUTION_STATE;
+
+ typedef enum {
+ LT_DONT_CARE,LT_LOWEST_LATENCY
+ } LATENCY_TIME;
+
+#define PDCAP_D0_SUPPORTED 0x00000001
+#define PDCAP_D1_SUPPORTED 0x00000002
+#define PDCAP_D2_SUPPORTED 0x00000004
+#define PDCAP_D3_SUPPORTED 0x00000008
+#define PDCAP_WAKE_FROM_D0_SUPPORTED 0x00000010
+#define PDCAP_WAKE_FROM_D1_SUPPORTED 0x00000020
+#define PDCAP_WAKE_FROM_D2_SUPPORTED 0x00000040
+#define PDCAP_WAKE_FROM_D3_SUPPORTED 0x00000080
+#define PDCAP_WARM_EJECT_SUPPORTED 0x00000100
+
+ typedef struct CM_Power_Data_s {
+ DWORD PD_Size;
+ DEVICE_POWER_STATE PD_MostRecentPowerState;
+ DWORD PD_Capabilities;
+ DWORD PD_D1Latency;
+ DWORD PD_D2Latency;
+ DWORD PD_D3Latency;
+ DEVICE_POWER_STATE PD_PowerStateMapping[POWER_SYSTEM_MAXIMUM];
+ SYSTEM_POWER_STATE PD_DeepestSystemWake;
+ } CM_POWER_DATA,*PCM_POWER_DATA;
+
+ typedef enum {
+ SystemPowerPolicyAc,SystemPowerPolicyDc,VerifySystemPolicyAc,VerifySystemPolicyDc,SystemPowerCapabilities,SystemBatteryState,SystemPowerStateHandler,ProcessorStateHandler,SystemPowerPolicyCurrent,AdministratorPowerPolicy,SystemReserveHiberFile,ProcessorInformation,SystemPowerInformation,ProcessorStateHandler2,LastWakeTime,LastSleepTime,SystemExecutionState,SystemPowerStateNotifyHandler,ProcessorPowerPolicyAc,ProcessorPowerPolicyDc,VerifyProcessorPowerPolicyAc,VerifyProcessorPowerPolicyDc,ProcessorPowerPolicyCurrent,SystemPowerStateLogging,SystemPowerLoggingEntry
+ } POWER_INFORMATION_LEVEL;
+
+ typedef struct {
+ DWORD Granularity;
+ DWORD Capacity;
+ } BATTERY_REPORTING_SCALE,*PBATTERY_REPORTING_SCALE;
+
+ typedef struct {
+ POWER_ACTION Action;
+ DWORD Flags;
+ DWORD EventCode;
+ } POWER_ACTION_POLICY,*PPOWER_ACTION_POLICY;
+
+#define POWER_ACTION_QUERY_ALLOWED 0x00000001
+#define POWER_ACTION_UI_ALLOWED 0x00000002
+#define POWER_ACTION_OVERRIDE_APPS 0x00000004
+#define POWER_ACTION_LIGHTEST_FIRST 0x10000000
+#define POWER_ACTION_LOCK_CONSOLE 0x20000000
+#define POWER_ACTION_DISABLE_WAKES 0x40000000
+#define POWER_ACTION_CRITICAL 0x80000000
+
+#define POWER_LEVEL_USER_NOTIFY_TEXT 0x00000001
+#define POWER_LEVEL_USER_NOTIFY_SOUND 0x00000002
+#define POWER_LEVEL_USER_NOTIFY_EXEC 0x00000004
+#define POWER_USER_NOTIFY_BUTTON 0x00000008
+#define POWER_USER_NOTIFY_SHUTDOWN 0x00000010
+#define POWER_FORCE_TRIGGER_RESET 0x80000000
+
+ typedef struct {
+ BOOLEAN Enable;
+ BYTE Spare[3];
+ DWORD BatteryLevel;
+ POWER_ACTION_POLICY PowerPolicy;
+ SYSTEM_POWER_STATE MinSystemState;
+ } SYSTEM_POWER_LEVEL,*PSYSTEM_POWER_LEVEL;
+
+#define NUM_DISCHARGE_POLICIES 4
+#define DISCHARGE_POLICY_CRITICAL 0
+#define DISCHARGE_POLICY_LOW 1
+
+#define PO_THROTTLE_NONE 0
+#define PO_THROTTLE_CONSTANT 1
+#define PO_THROTTLE_DEGRADE 2
+#define PO_THROTTLE_ADAPTIVE 3
+#define PO_THROTTLE_MAXIMUM 4
+
+ typedef struct _SYSTEM_POWER_POLICY {
+ DWORD Revision;
+ POWER_ACTION_POLICY PowerButton;
+ POWER_ACTION_POLICY SleepButton;
+ POWER_ACTION_POLICY LidClose;
+ SYSTEM_POWER_STATE LidOpenWake;
+ DWORD Reserved;
+ POWER_ACTION_POLICY Idle;
+ DWORD IdleTimeout;
+ BYTE IdleSensitivity;
+ BYTE DynamicThrottle;
+ BYTE Spare2[2];
+ SYSTEM_POWER_STATE MinSleep;
+ SYSTEM_POWER_STATE MaxSleep;
+ SYSTEM_POWER_STATE ReducedLatencySleep;
+ DWORD WinLogonFlags;
+ DWORD Spare3;
+ DWORD DozeS4Timeout;
+ DWORD BroadcastCapacityResolution;
+ SYSTEM_POWER_LEVEL DischargePolicy[NUM_DISCHARGE_POLICIES];
+ DWORD VideoTimeout;
+ BOOLEAN VideoDimDisplay;
+ DWORD VideoReserved[3];
+ DWORD SpindownTimeout;
+ BOOLEAN OptimizeForPower;
+ BYTE FanThrottleTolerance;
+ BYTE ForcedThrottle;
+ BYTE MinThrottle;
+ POWER_ACTION_POLICY OverThrottled;
+ } SYSTEM_POWER_POLICY,*PSYSTEM_POWER_POLICY;
+
+ typedef struct _PROCESSOR_POWER_POLICY_INFO {
+ DWORD TimeCheck;
+ DWORD DemoteLimit;
+ DWORD PromoteLimit;
+ BYTE DemotePercent;
+ BYTE PromotePercent;
+ BYTE Spare[2];
+ DWORD AllowDemotion:1;
+ DWORD AllowPromotion:1;
+ DWORD Reserved:30;
+ } PROCESSOR_POWER_POLICY_INFO,*PPROCESSOR_POWER_POLICY_INFO;
+
+ typedef struct _PROCESSOR_POWER_POLICY {
+ DWORD Revision;
+ BYTE DynamicThrottle;
+ BYTE Spare[3];
+ DWORD DisableCStates:1;
+ DWORD Reserved:31;
+ DWORD PolicyCount;
+ PROCESSOR_POWER_POLICY_INFO Policy[3];
+ } PROCESSOR_POWER_POLICY,*PPROCESSOR_POWER_POLICY;
+
+ typedef struct _ADMINISTRATOR_POWER_POLICY {
+ SYSTEM_POWER_STATE MinSleep;
+ SYSTEM_POWER_STATE MaxSleep;
+ DWORD MinVideoTimeout;
+ DWORD MaxVideoTimeout;
+ DWORD MinSpindownTimeout;
+ DWORD MaxSpindownTimeout;
+ } ADMINISTRATOR_POWER_POLICY,*PADMINISTRATOR_POWER_POLICY;
+
+ typedef struct {
+ BOOLEAN PowerButtonPresent;
+ BOOLEAN SleepButtonPresent;
+ BOOLEAN LidPresent;
+ BOOLEAN SystemS1;
+ BOOLEAN SystemS2;
+ BOOLEAN SystemS3;
+ BOOLEAN SystemS4;
+ BOOLEAN SystemS5;
+ BOOLEAN HiberFilePresent;
+ BOOLEAN FullWake;
+ BOOLEAN VideoDimPresent;
+ BOOLEAN ApmPresent;
+ BOOLEAN UpsPresent;
+ BOOLEAN ThermalControl;
+ BOOLEAN ProcessorThrottle;
+ BYTE ProcessorMinThrottle;
+ BYTE ProcessorMaxThrottle;
+ BYTE spare2[4];
+ BOOLEAN DiskSpinDown;
+ BYTE spare3[8];
+ BOOLEAN SystemBatteriesPresent;
+ BOOLEAN BatteriesAreShortTerm;
+ BATTERY_REPORTING_SCALE BatteryScale[3];
+ SYSTEM_POWER_STATE AcOnLineWake;
+ SYSTEM_POWER_STATE SoftLidWake;
+ SYSTEM_POWER_STATE RtcWake;
+ SYSTEM_POWER_STATE MinDeviceWakeState;
+ SYSTEM_POWER_STATE DefaultLowLatencyWake;
+ } SYSTEM_POWER_CAPABILITIES,*PSYSTEM_POWER_CAPABILITIES;
+
+ typedef struct {
+ BOOLEAN AcOnLine;
+ BOOLEAN BatteryPresent;
+ BOOLEAN Charging;
+ BOOLEAN Discharging;
+ BOOLEAN Spare1[4];
+ DWORD MaxCapacity;
+ DWORD RemainingCapacity;
+ DWORD Rate;
+ DWORD EstimatedTime;
+ DWORD DefaultAlert1;
+ DWORD DefaultAlert2;
+ } SYSTEM_BATTERY_STATE,*PSYSTEM_BATTERY_STATE;
+
+#include "pshpack4.h"
+
+#define IMAGE_DOS_SIGNATURE 0x5A4D
+#define IMAGE_OS2_SIGNATURE 0x454E
+#define IMAGE_OS2_SIGNATURE_LE 0x454C
+#define IMAGE_VXD_SIGNATURE 0x454C
+#define IMAGE_NT_SIGNATURE 0x00004550
+
+#include "pshpack2.h"
+
+ typedef struct _IMAGE_DOS_HEADER {
+ WORD e_magic;
+ WORD e_cblp;
+ WORD e_cp;
+ WORD e_crlc;
+ WORD e_cparhdr;
+ WORD e_minalloc;
+ WORD e_maxalloc;
+ WORD e_ss;
+ WORD e_sp;
+ WORD e_csum;
+ WORD e_ip;
+ WORD e_cs;
+ WORD e_lfarlc;
+ WORD e_ovno;
+ WORD e_res[4];
+ WORD e_oemid;
+ WORD e_oeminfo;
+ WORD e_res2[10];
+ LONG e_lfanew;
+ } IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
+
+ typedef struct _IMAGE_OS2_HEADER {
+ WORD ne_magic;
+ CHAR ne_ver;
+ CHAR ne_rev;
+ WORD ne_enttab;
+ WORD ne_cbenttab;
+ LONG ne_crc;
+ WORD ne_flags;
+ WORD ne_autodata;
+ WORD ne_heap;
+ WORD ne_stack;
+ LONG ne_csip;
+ LONG ne_sssp;
+ WORD ne_cseg;
+ WORD ne_cmod;
+ WORD ne_cbnrestab;
+ WORD ne_segtab;
+ WORD ne_rsrctab;
+ WORD ne_restab;
+ WORD ne_modtab;
+ WORD ne_imptab;
+ LONG ne_nrestab;
+ WORD ne_cmovent;
+ WORD ne_align;
+ WORD ne_cres;
+ BYTE ne_exetyp;
+ BYTE ne_flagsothers;
+ WORD ne_pretthunks;
+ WORD ne_psegrefbytes;
+ WORD ne_swaparea;
+ WORD ne_expver;
+ } IMAGE_OS2_HEADER,*PIMAGE_OS2_HEADER;
+
+ typedef struct _IMAGE_VXD_HEADER {
+ WORD e32_magic;
+ BYTE e32_border;
+ BYTE e32_worder;
+ DWORD e32_level;
+ WORD e32_cpu;
+ WORD e32_os;
+ DWORD e32_ver;
+ DWORD e32_mflags;
+ DWORD e32_mpages;
+ DWORD e32_startobj;
+ DWORD e32_eip;
+ DWORD e32_stackobj;
+ DWORD e32_esp;
+ DWORD e32_pagesize;
+ DWORD e32_lastpagesize;
+ DWORD e32_fixupsize;
+ DWORD e32_fixupsum;
+ DWORD e32_ldrsize;
+ DWORD e32_ldrsum;
+ DWORD e32_objtab;
+ DWORD e32_objcnt;
+ DWORD e32_objmap;
+ DWORD e32_itermap;
+ DWORD e32_rsrctab;
+ DWORD e32_rsrccnt;
+ DWORD e32_restab;
+ DWORD e32_enttab;
+ DWORD e32_dirtab;
+ DWORD e32_dircnt;
+ DWORD e32_fpagetab;
+ DWORD e32_frectab;
+ DWORD e32_impmod;
+ DWORD e32_impmodcnt;
+ DWORD e32_impproc;
+ DWORD e32_pagesum;
+ DWORD e32_datapage;
+ DWORD e32_preload;
+ DWORD e32_nrestab;
+ DWORD e32_cbnrestab;
+ DWORD e32_nressum;
+ DWORD e32_autodata;
+ DWORD e32_debuginfo;
+ DWORD e32_debuglen;
+ DWORD e32_instpreload;
+ DWORD e32_instdemand;
+ DWORD e32_heapsize;
+ BYTE e32_res3[12];
+ DWORD e32_winresoff;
+ DWORD e32_winreslen;
+ WORD e32_devid;
+ WORD e32_ddkver;
+ } IMAGE_VXD_HEADER,*PIMAGE_VXD_HEADER;
+
+#include "poppack.h"
+
+ typedef struct _IMAGE_FILE_HEADER {
+ WORD Machine;
+ WORD NumberOfSections;
+ DWORD TimeDateStamp;
+ DWORD PointerToSymbolTable;
+ DWORD NumberOfSymbols;
+ WORD SizeOfOptionalHeader;
+ WORD Characteristics;
+ } IMAGE_FILE_HEADER,*PIMAGE_FILE_HEADER;
+
+#define IMAGE_SIZEOF_FILE_HEADER 20
+
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
+#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010
+#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
+#define IMAGE_FILE_32BIT_MACHINE 0x0100
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
+#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400
+#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800
+#define IMAGE_FILE_SYSTEM 0x1000
+#define IMAGE_FILE_DLL 0x2000
+#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
+
+#define IMAGE_FILE_MACHINE_UNKNOWN 0
+#define IMAGE_FILE_MACHINE_I386 0x014c
+#define IMAGE_FILE_MACHINE_R3000 0x0162
+#define IMAGE_FILE_MACHINE_R4000 0x0166
+#define IMAGE_FILE_MACHINE_R10000 0x0168
+#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169
+#define IMAGE_FILE_MACHINE_ALPHA 0x0184
+#define IMAGE_FILE_MACHINE_SH3 0x01a2
+#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3
+#define IMAGE_FILE_MACHINE_SH3E 0x01a4
+#define IMAGE_FILE_MACHINE_SH4 0x01a6
+#define IMAGE_FILE_MACHINE_SH5 0x01a8
+#define IMAGE_FILE_MACHINE_ARM 0x01c0
+#define IMAGE_FILE_MACHINE_THUMB 0x01c2
+#define IMAGE_FILE_MACHINE_AM33 0x01d3
+#define IMAGE_FILE_MACHINE_POWERPC 0x01F0
+#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1
+#define IMAGE_FILE_MACHINE_IA64 0x0200
+#define IMAGE_FILE_MACHINE_MIPS16 0x0266
+#define IMAGE_FILE_MACHINE_ALPHA64 0x0284
+#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366
+#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466
+#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
+#define IMAGE_FILE_MACHINE_TRICORE 0x0520
+#define IMAGE_FILE_MACHINE_CEF 0x0CEF
+#define IMAGE_FILE_MACHINE_EBC 0x0EBC
+#define IMAGE_FILE_MACHINE_AMD64 0x8664
+#define IMAGE_FILE_MACHINE_M32R 0x9041
+#define IMAGE_FILE_MACHINE_CEE 0xC0EE
+
+ typedef struct _IMAGE_DATA_DIRECTORY {
+ DWORD VirtualAddress;
+ DWORD Size;
+ } IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
+
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+
+ typedef struct _IMAGE_OPTIONAL_HEADER {
+
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+ DWORD BaseOfData;
+ DWORD ImageBase;
+ DWORD SectionAlignment;
+ DWORD FileAlignment;
+ WORD MajorOperatingSystemVersion;
+ WORD MinorOperatingSystemVersion;
+ WORD MajorImageVersion;
+ WORD MinorImageVersion;
+ WORD MajorSubsystemVersion;
+ WORD MinorSubsystemVersion;
+ DWORD Win32VersionValue;
+ DWORD SizeOfImage;
+ DWORD SizeOfHeaders;
+ DWORD CheckSum;
+ WORD Subsystem;
+ WORD DllCharacteristics;
+ DWORD SizeOfStackReserve;
+ DWORD SizeOfStackCommit;
+ DWORD SizeOfHeapReserve;
+ DWORD SizeOfHeapCommit;
+ DWORD LoaderFlags;
+ DWORD NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+ } IMAGE_OPTIONAL_HEADER32,*PIMAGE_OPTIONAL_HEADER32;
+
+ typedef struct _IMAGE_ROM_OPTIONAL_HEADER {
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+ DWORD BaseOfData;
+ DWORD BaseOfBss;
+ DWORD GprMask;
+ DWORD CprMask[4];
+ DWORD GpValue;
+ } IMAGE_ROM_OPTIONAL_HEADER,*PIMAGE_ROM_OPTIONAL_HEADER;
+
+ typedef struct _IMAGE_OPTIONAL_HEADER64 {
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+ ULONGLONG ImageBase;
+ DWORD SectionAlignment;
+ DWORD FileAlignment;
+ WORD MajorOperatingSystemVersion;
+ WORD MinorOperatingSystemVersion;
+ WORD MajorImageVersion;
+ WORD MinorImageVersion;
+ WORD MajorSubsystemVersion;
+ WORD MinorSubsystemVersion;
+ DWORD Win32VersionValue;
+ DWORD SizeOfImage;
+ DWORD SizeOfHeaders;
+ DWORD CheckSum;
+ WORD Subsystem;
+ WORD DllCharacteristics;
+ ULONGLONG SizeOfStackReserve;
+ ULONGLONG SizeOfStackCommit;
+ ULONGLONG SizeOfHeapReserve;
+ ULONGLONG SizeOfHeapCommit;
+ DWORD LoaderFlags;
+ DWORD NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+ } IMAGE_OPTIONAL_HEADER64,*PIMAGE_OPTIONAL_HEADER64;
+
+#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
+#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
+#define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224
+#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240
+
+#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
+#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
+#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
+
+#ifdef _WIN64
+ typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER;
+ typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER;
+#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL64_HEADER
+#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC
+#else
+ typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER;
+ typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER;
+#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL32_HEADER
+#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC
+#endif
+
+ typedef struct _IMAGE_NT_HEADERS64 {
+ DWORD Signature;
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER64 OptionalHeader;
+ } IMAGE_NT_HEADERS64,*PIMAGE_NT_HEADERS64;
+
+ typedef struct _IMAGE_NT_HEADERS {
+ DWORD Signature;
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER32 OptionalHeader;
+ } IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;
+
+ typedef struct _IMAGE_ROM_HEADERS {
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
+ } IMAGE_ROM_HEADERS,*PIMAGE_ROM_HEADERS;
+
+#ifdef _WIN64
+ typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS;
+ typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS;
+#else
+ typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS;
+ typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS;
+#endif
+
+#define IMAGE_FIRST_SECTION(ntheader) ((PIMAGE_SECTION_HEADER) ((ULONG_PTR)ntheader + FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader) + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader))
+
+#define IMAGE_SUBSYSTEM_UNKNOWN 0
+#define IMAGE_SUBSYSTEM_NATIVE 1
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
+#define IMAGE_SUBSYSTEM_OS2_CUI 5
+#define IMAGE_SUBSYSTEM_POSIX_CUI 7
+#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8
+#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9
+#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10
+#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
+#define IMAGE_SUBSYSTEM_EFI_ROM 13
+#define IMAGE_SUBSYSTEM_XBOX 14
+
+#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200
+#define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400
+#define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800
+#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000
+#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
+
+#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
+#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
+#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
+#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
+
+#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
+#define IMAGE_DIRECTORY_ENTRY_TLS 9
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
+#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
+#define IMAGE_DIRECTORY_ENTRY_IAT 12
+#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
+#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
+
+ typedef struct ANON_OBJECT_HEADER {
+ WORD Sig1;
+ WORD Sig2;
+ WORD Version;
+ WORD Machine;
+ DWORD TimeDateStamp;
+ CLSID ClassID;
+ DWORD SizeOfData;
+ } ANON_OBJECT_HEADER;
+
+#define IMAGE_SIZEOF_SHORT_NAME 8
+
+ typedef struct _IMAGE_SECTION_HEADER {
+ BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ DWORD PhysicalAddress;
+ DWORD VirtualSize;
+ } Misc;
+ DWORD VirtualAddress;
+ DWORD SizeOfRawData;
+ DWORD PointerToRawData;
+ DWORD PointerToRelocations;
+ DWORD PointerToLinenumbers;
+ WORD NumberOfRelocations;
+ WORD NumberOfLinenumbers;
+ DWORD Characteristics;
+ } IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
+
+#define IMAGE_SIZEOF_SECTION_HEADER 40
+
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008
+
+#define IMAGE_SCN_CNT_CODE 0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
+#define IMAGE_SCN_LNK_OTHER 0x00000100
+#define IMAGE_SCN_LNK_INFO 0x00000200
+#define IMAGE_SCN_LNK_REMOVE 0x00000800
+#define IMAGE_SCN_LNK_COMDAT 0x00001000
+#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000
+#define IMAGE_SCN_GPREL 0x00008000
+#define IMAGE_SCN_MEM_FARDATA 0x00008000
+#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
+#define IMAGE_SCN_MEM_16BIT 0x00020000
+#define IMAGE_SCN_MEM_LOCKED 0x00040000
+#define IMAGE_SCN_MEM_PRELOAD 0x00080000
+
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
+#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
+#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
+#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000
+#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000
+#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000
+#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000
+#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000
+
+#define IMAGE_SCN_ALIGN_MASK 0x00F00000
+
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000
+#define IMAGE_SCN_MEM_SHARED 0x10000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_WRITE 0x80000000
+
+#define IMAGE_SCN_SCALE_INDEX 0x00000001
+
+#include "pshpack2.h"
+
+ typedef struct _IMAGE_SYMBOL {
+ union {
+ BYTE ShortName[8];
+ struct {
+ DWORD Short;
+ DWORD Long;
+ } Name;
+ DWORD LongName[2];
+ } N;
+ DWORD Value;
+ SHORT SectionNumber;
+ WORD Type;
+ BYTE StorageClass;
+ BYTE NumberOfAuxSymbols;
+ } IMAGE_SYMBOL;
+ typedef IMAGE_SYMBOL UNALIGNED *PIMAGE_SYMBOL;
+
+#define IMAGE_SIZEOF_SYMBOL 18
+
+#define IMAGE_SYM_UNDEFINED (SHORT)0
+#define IMAGE_SYM_ABSOLUTE (SHORT)-1
+#define IMAGE_SYM_DEBUG (SHORT)-2
+#define IMAGE_SYM_SECTION_MAX 0xFEFF
+
+#define IMAGE_SYM_TYPE_NULL 0x0000
+#define IMAGE_SYM_TYPE_VOID 0x0001
+#define IMAGE_SYM_TYPE_CHAR 0x0002
+#define IMAGE_SYM_TYPE_SHORT 0x0003
+#define IMAGE_SYM_TYPE_INT 0x0004
+#define IMAGE_SYM_TYPE_LONG 0x0005
+#define IMAGE_SYM_TYPE_FLOAT 0x0006
+#define IMAGE_SYM_TYPE_DOUBLE 0x0007
+#define IMAGE_SYM_TYPE_STRUCT 0x0008
+#define IMAGE_SYM_TYPE_UNION 0x0009
+#define IMAGE_SYM_TYPE_ENUM 0x000A
+#define IMAGE_SYM_TYPE_MOE 0x000B
+#define IMAGE_SYM_TYPE_BYTE 0x000C
+#define IMAGE_SYM_TYPE_WORD 0x000D
+#define IMAGE_SYM_TYPE_UINT 0x000E
+#define IMAGE_SYM_TYPE_DWORD 0x000F
+#define IMAGE_SYM_TYPE_PCODE 0x8000
+
+#define IMAGE_SYM_DTYPE_NULL 0
+#define IMAGE_SYM_DTYPE_POINTER 1
+#define IMAGE_SYM_DTYPE_FUNCTION 2
+#define IMAGE_SYM_DTYPE_ARRAY 3
+
+#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE)-1
+#define IMAGE_SYM_CLASS_NULL 0x0000
+#define IMAGE_SYM_CLASS_AUTOMATIC 0x0001
+#define IMAGE_SYM_CLASS_EXTERNAL 0x0002
+#define IMAGE_SYM_CLASS_STATIC 0x0003
+#define IMAGE_SYM_CLASS_REGISTER 0x0004
+#define IMAGE_SYM_CLASS_EXTERNAL_DEF 0x0005
+#define IMAGE_SYM_CLASS_LABEL 0x0006
+#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 0x0007
+#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 0x0008
+#define IMAGE_SYM_CLASS_ARGUMENT 0x0009
+#define IMAGE_SYM_CLASS_STRUCT_TAG 0x000A
+#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 0x000B
+#define IMAGE_SYM_CLASS_UNION_TAG 0x000C
+#define IMAGE_SYM_CLASS_TYPE_DEFINITION 0x000D
+#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 0x000E
+#define IMAGE_SYM_CLASS_ENUM_TAG 0x000F
+#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 0x0010
+#define IMAGE_SYM_CLASS_REGISTER_PARAM 0x0011
+#define IMAGE_SYM_CLASS_BIT_FIELD 0x0012
+#define IMAGE_SYM_CLASS_FAR_EXTERNAL 0x0044
+#define IMAGE_SYM_CLASS_BLOCK 0x0064
+#define IMAGE_SYM_CLASS_FUNCTION 0x0065
+#define IMAGE_SYM_CLASS_END_OF_STRUCT 0x0066
+#define IMAGE_SYM_CLASS_FILE 0x0067
+#define IMAGE_SYM_CLASS_SECTION 0x0068
+#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 0x0069
+#define IMAGE_SYM_CLASS_CLR_TOKEN 0x006B
+
+#define N_BTMASK 0x000F
+#define N_TMASK 0x0030
+#define N_TMASK1 0x00C0
+#define N_TMASK2 0x00F0
+#define N_BTSHFT 4
+#define N_TSHIFT 2
+
+#define BTYPE(x) ((x) & N_BTMASK)
+
+#ifndef ISPTR
+#define ISPTR(x) (((x) & N_TMASK)==(IMAGE_SYM_DTYPE_POINTER << N_BTSHFT))
+#endif
+
+#ifndef ISFCN
+#define ISFCN(x) (((x) & N_TMASK)==(IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT))
+#endif
+
+#ifndef ISARY
+#define ISARY(x) (((x) & N_TMASK)==(IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT))
+#endif
+
+#ifndef ISTAG
+#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG || (x)==IMAGE_SYM_CLASS_UNION_TAG || (x)==IMAGE_SYM_CLASS_ENUM_TAG)
+#endif
+
+#ifndef INCREF
+#define INCREF(x) ((((x)&~N_BTMASK)<<N_TSHIFT)|(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT)|((x)&N_BTMASK))
+#endif
+#ifndef DECREF
+#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
+#endif
+
+ typedef union _IMAGE_AUX_SYMBOL {
+ struct {
+ DWORD TagIndex;
+ union {
+ struct {
+ WORD Linenumber;
+ WORD Size;
+ } LnSz;
+ DWORD TotalSize;
+ } Misc;
+ union {
+ struct {
+ DWORD PointerToLinenumber;
+ DWORD PointerToNextFunction;
+ } Function;
+ struct {
+ WORD Dimension[4];
+ } Array;
+ } FcnAry;
+ WORD TvIndex;
+ } Sym;
+ struct {
+ BYTE Name[IMAGE_SIZEOF_SYMBOL];
+ } File;
+ struct {
+ DWORD Length;
+ WORD NumberOfRelocations;
+ WORD NumberOfLinenumbers;
+ DWORD CheckSum;
+ SHORT Number;
+ BYTE Selection;
+ } Section;
+ } IMAGE_AUX_SYMBOL;
+ typedef IMAGE_AUX_SYMBOL UNALIGNED *PIMAGE_AUX_SYMBOL;
+
+#define IMAGE_SIZEOF_AUX_SYMBOL 18
+
+ typedef enum IMAGE_AUX_SYMBOL_TYPE {
+ IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1
+ } IMAGE_AUX_SYMBOL_TYPE;
+
+#include <pshpack2.h>
+
+ typedef struct IMAGE_AUX_SYMBOL_TOKEN_DEF {
+ BYTE bAuxType;
+ BYTE bReserved;
+ DWORD SymbolTableIndex;
+ BYTE rgbReserved[12];
+ } IMAGE_AUX_SYMBOL_TOKEN_DEF;
+
+ typedef IMAGE_AUX_SYMBOL_TOKEN_DEF UNALIGNED *PIMAGE_AUX_SYMBOL_TOKEN_DEF;
+
+#include <poppack.h>
+
+#define IMAGE_COMDAT_SELECT_NODUPLICATES 1
+#define IMAGE_COMDAT_SELECT_ANY 2
+#define IMAGE_COMDAT_SELECT_SAME_SIZE 3
+#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4
+#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
+#define IMAGE_COMDAT_SELECT_LARGEST 6
+#define IMAGE_COMDAT_SELECT_NEWEST 7
+
+#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
+#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
+#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
+
+ typedef struct _IMAGE_RELOCATION {
+ union {
+ DWORD VirtualAddress;
+ DWORD RelocCount;
+ };
+ DWORD SymbolTableIndex;
+ WORD Type;
+ } IMAGE_RELOCATION;
+ typedef IMAGE_RELOCATION UNALIGNED *PIMAGE_RELOCATION;
+
+#define IMAGE_SIZEOF_RELOCATION 10
+
+#define IMAGE_REL_I386_ABSOLUTE 0x0000
+#define IMAGE_REL_I386_DIR16 0x0001
+#define IMAGE_REL_I386_REL16 0x0002
+#define IMAGE_REL_I386_DIR32 0x0006
+#define IMAGE_REL_I386_DIR32NB 0x0007
+#define IMAGE_REL_I386_SEG12 0x0009
+#define IMAGE_REL_I386_SECTION 0x000A
+#define IMAGE_REL_I386_SECREL 0x000B
+#define IMAGE_REL_I386_TOKEN 0x000C
+#define IMAGE_REL_I386_SECREL7 0x000D
+#define IMAGE_REL_I386_REL32 0x0014
+
+#define IMAGE_REL_MIPS_ABSOLUTE 0x0000
+#define IMAGE_REL_MIPS_REFHALF 0x0001
+#define IMAGE_REL_MIPS_REFWORD 0x0002
+#define IMAGE_REL_MIPS_JMPADDR 0x0003
+#define IMAGE_REL_MIPS_REFHI 0x0004
+#define IMAGE_REL_MIPS_REFLO 0x0005
+#define IMAGE_REL_MIPS_GPREL 0x0006
+#define IMAGE_REL_MIPS_LITERAL 0x0007
+#define IMAGE_REL_MIPS_SECTION 0x000A
+#define IMAGE_REL_MIPS_SECREL 0x000B
+#define IMAGE_REL_MIPS_SECRELLO 0x000C
+#define IMAGE_REL_MIPS_SECRELHI 0x000D
+#define IMAGE_REL_MIPS_TOKEN 0x000E
+#define IMAGE_REL_MIPS_JMPADDR16 0x0010
+#define IMAGE_REL_MIPS_REFWORDNB 0x0022
+#define IMAGE_REL_MIPS_PAIR 0x0025
+
+#define IMAGE_REL_ALPHA_ABSOLUTE 0x0000
+#define IMAGE_REL_ALPHA_REFLONG 0x0001
+#define IMAGE_REL_ALPHA_REFQUAD 0x0002
+#define IMAGE_REL_ALPHA_GPREL32 0x0003
+#define IMAGE_REL_ALPHA_LITERAL 0x0004
+#define IMAGE_REL_ALPHA_LITUSE 0x0005
+#define IMAGE_REL_ALPHA_GPDISP 0x0006
+#define IMAGE_REL_ALPHA_BRADDR 0x0007
+#define IMAGE_REL_ALPHA_HINT 0x0008
+#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x0009
+#define IMAGE_REL_ALPHA_REFHI 0x000A
+#define IMAGE_REL_ALPHA_REFLO 0x000B
+#define IMAGE_REL_ALPHA_PAIR 0x000C
+#define IMAGE_REL_ALPHA_MATCH 0x000D
+#define IMAGE_REL_ALPHA_SECTION 0x000E
+#define IMAGE_REL_ALPHA_SECREL 0x000F
+#define IMAGE_REL_ALPHA_REFLONGNB 0x0010
+#define IMAGE_REL_ALPHA_SECRELLO 0x0011
+#define IMAGE_REL_ALPHA_SECRELHI 0x0012
+#define IMAGE_REL_ALPHA_REFQ3 0x0013
+#define IMAGE_REL_ALPHA_REFQ2 0x0014
+#define IMAGE_REL_ALPHA_REFQ1 0x0015
+#define IMAGE_REL_ALPHA_GPRELLO 0x0016
+#define IMAGE_REL_ALPHA_GPRELHI 0x0017
+
+#define IMAGE_REL_PPC_ABSOLUTE 0x0000
+#define IMAGE_REL_PPC_ADDR64 0x0001
+#define IMAGE_REL_PPC_ADDR32 0x0002
+#define IMAGE_REL_PPC_ADDR24 0x0003
+#define IMAGE_REL_PPC_ADDR16 0x0004
+#define IMAGE_REL_PPC_ADDR14 0x0005
+#define IMAGE_REL_PPC_REL24 0x0006
+#define IMAGE_REL_PPC_REL14 0x0007
+#define IMAGE_REL_PPC_TOCREL16 0x0008
+#define IMAGE_REL_PPC_TOCREL14 0x0009
+#define IMAGE_REL_PPC_ADDR32NB 0x000A
+#define IMAGE_REL_PPC_SECREL 0x000B
+#define IMAGE_REL_PPC_SECTION 0x000C
+#define IMAGE_REL_PPC_IFGLUE 0x000D
+#define IMAGE_REL_PPC_IMGLUE 0x000E
+#define IMAGE_REL_PPC_SECREL16 0x000F
+#define IMAGE_REL_PPC_REFHI 0x0010
+#define IMAGE_REL_PPC_REFLO 0x0011
+#define IMAGE_REL_PPC_PAIR 0x0012
+#define IMAGE_REL_PPC_SECRELLO 0x0013
+#define IMAGE_REL_PPC_SECRELHI 0x0014
+#define IMAGE_REL_PPC_GPREL 0x0015
+#define IMAGE_REL_PPC_TOKEN 0x0016
+#define IMAGE_REL_PPC_TYPEMASK 0x00FF
+#define IMAGE_REL_PPC_NEG 0x0100
+#define IMAGE_REL_PPC_BRTAKEN 0x0200
+#define IMAGE_REL_PPC_BRNTAKEN 0x0400
+#define IMAGE_REL_PPC_TOCDEFN 0x0800
+
+#define IMAGE_REL_SH3_ABSOLUTE 0x0000
+#define IMAGE_REL_SH3_DIRECT16 0x0001
+#define IMAGE_REL_SH3_DIRECT32 0x0002
+#define IMAGE_REL_SH3_DIRECT8 0x0003
+#define IMAGE_REL_SH3_DIRECT8_WORD 0x0004
+#define IMAGE_REL_SH3_DIRECT8_LONG 0x0005
+#define IMAGE_REL_SH3_DIRECT4 0x0006
+#define IMAGE_REL_SH3_DIRECT4_WORD 0x0007
+#define IMAGE_REL_SH3_DIRECT4_LONG 0x0008
+#define IMAGE_REL_SH3_PCREL8_WORD 0x0009
+#define IMAGE_REL_SH3_PCREL8_LONG 0x000A
+#define IMAGE_REL_SH3_PCREL12_WORD 0x000B
+#define IMAGE_REL_SH3_STARTOF_SECTION 0x000C
+#define IMAGE_REL_SH3_SIZEOF_SECTION 0x000D
+#define IMAGE_REL_SH3_SECTION 0x000E
+#define IMAGE_REL_SH3_SECREL 0x000F
+#define IMAGE_REL_SH3_DIRECT32_NB 0x0010
+#define IMAGE_REL_SH3_GPREL4_LONG 0x0011
+#define IMAGE_REL_SH3_TOKEN 0x0012
+
+#define IMAGE_REL_SHM_PCRELPT 0x0013
+#define IMAGE_REL_SHM_REFLO 0x0014
+#define IMAGE_REL_SHM_REFHALF 0x0015
+#define IMAGE_REL_SHM_RELLO 0x0016
+#define IMAGE_REL_SHM_RELHALF 0x0017
+#define IMAGE_REL_SHM_PAIR 0x0018
+
+#define IMAGE_REL_SH_NOMODE 0x8000
+
+#define IMAGE_REL_ARM_ABSOLUTE 0x0000
+#define IMAGE_REL_ARM_ADDR32 0x0001
+#define IMAGE_REL_ARM_ADDR32NB 0x0002
+#define IMAGE_REL_ARM_BRANCH24 0x0003
+#define IMAGE_REL_ARM_BRANCH11 0x0004
+#define IMAGE_REL_ARM_TOKEN 0x0005
+#define IMAGE_REL_ARM_GPREL12 0x0006
+#define IMAGE_REL_ARM_GPREL7 0x0007
+#define IMAGE_REL_ARM_BLX24 0x0008
+#define IMAGE_REL_ARM_BLX11 0x0009
+#define IMAGE_REL_ARM_SECTION 0x000E
+#define IMAGE_REL_ARM_SECREL 0x000F
+
+#define IMAGE_REL_AM_ABSOLUTE 0x0000
+#define IMAGE_REL_AM_ADDR32 0x0001
+#define IMAGE_REL_AM_ADDR32NB 0x0002
+#define IMAGE_REL_AM_CALL32 0x0003
+#define IMAGE_REL_AM_FUNCINFO 0x0004
+#define IMAGE_REL_AM_REL32_1 0x0005
+#define IMAGE_REL_AM_REL32_2 0x0006
+#define IMAGE_REL_AM_SECREL 0x0007
+#define IMAGE_REL_AM_SECTION 0x0008
+#define IMAGE_REL_AM_TOKEN 0x0009
+
+#define IMAGE_REL_AMD64_ABSOLUTE 0x0000
+#define IMAGE_REL_AMD64_ADDR64 0x0001
+#define IMAGE_REL_AMD64_ADDR32 0x0002
+#define IMAGE_REL_AMD64_ADDR32NB 0x0003
+#define IMAGE_REL_AMD64_REL32 0x0004
+#define IMAGE_REL_AMD64_REL32_1 0x0005
+#define IMAGE_REL_AMD64_REL32_2 0x0006
+#define IMAGE_REL_AMD64_REL32_3 0x0007
+#define IMAGE_REL_AMD64_REL32_4 0x0008
+#define IMAGE_REL_AMD64_REL32_5 0x0009
+#define IMAGE_REL_AMD64_SECTION 0x000A
+#define IMAGE_REL_AMD64_SECREL 0x000B
+#define IMAGE_REL_AMD64_SECREL7 0x000C
+#define IMAGE_REL_AMD64_TOKEN 0x000D
+#define IMAGE_REL_AMD64_SREL32 0x000E
+#define IMAGE_REL_AMD64_PAIR 0x000F
+#define IMAGE_REL_AMD64_SSPAN32 0x0010
+
+#define IMAGE_REL_IA64_ABSOLUTE 0x0000
+#define IMAGE_REL_IA64_IMM14 0x0001
+#define IMAGE_REL_IA64_IMM22 0x0002
+#define IMAGE_REL_IA64_IMM64 0x0003
+#define IMAGE_REL_IA64_DIR32 0x0004
+#define IMAGE_REL_IA64_DIR64 0x0005
+#define IMAGE_REL_IA64_PCREL21B 0x0006
+#define IMAGE_REL_IA64_PCREL21M 0x0007
+#define IMAGE_REL_IA64_PCREL21F 0x0008
+#define IMAGE_REL_IA64_GPREL22 0x0009
+#define IMAGE_REL_IA64_LTOFF22 0x000A
+#define IMAGE_REL_IA64_SECTION 0x000B
+#define IMAGE_REL_IA64_SECREL22 0x000C
+#define IMAGE_REL_IA64_SECREL64I 0x000D
+#define IMAGE_REL_IA64_SECREL32 0x000E
+
+#define IMAGE_REL_IA64_DIR32NB 0x0010
+#define IMAGE_REL_IA64_SREL14 0x0011
+#define IMAGE_REL_IA64_SREL22 0x0012
+#define IMAGE_REL_IA64_SREL32 0x0013
+#define IMAGE_REL_IA64_UREL32 0x0014
+#define IMAGE_REL_IA64_PCREL60X 0x0015
+#define IMAGE_REL_IA64_PCREL60B 0x0016
+#define IMAGE_REL_IA64_PCREL60F 0x0017
+#define IMAGE_REL_IA64_PCREL60I 0x0018
+#define IMAGE_REL_IA64_PCREL60M 0x0019
+#define IMAGE_REL_IA64_IMMGPREL64 0x001A
+#define IMAGE_REL_IA64_TOKEN 0x001B
+#define IMAGE_REL_IA64_GPREL32 0x001C
+#define IMAGE_REL_IA64_ADDEND 0x001F
+
+#define IMAGE_REL_CEF_ABSOLUTE 0x0000
+#define IMAGE_REL_CEF_ADDR32 0x0001
+#define IMAGE_REL_CEF_ADDR64 0x0002
+#define IMAGE_REL_CEF_ADDR32NB 0x0003
+#define IMAGE_REL_CEF_SECTION 0x0004
+#define IMAGE_REL_CEF_SECREL 0x0005
+#define IMAGE_REL_CEF_TOKEN 0x0006
+
+#define IMAGE_REL_CEE_ABSOLUTE 0x0000
+#define IMAGE_REL_CEE_ADDR32 0x0001
+#define IMAGE_REL_CEE_ADDR64 0x0002
+#define IMAGE_REL_CEE_ADDR32NB 0x0003
+#define IMAGE_REL_CEE_SECTION 0x0004
+#define IMAGE_REL_CEE_SECREL 0x0005
+#define IMAGE_REL_CEE_TOKEN 0x0006
+
+#define IMAGE_REL_M32R_ABSOLUTE 0x0000
+#define IMAGE_REL_M32R_ADDR32 0x0001
+#define IMAGE_REL_M32R_ADDR32NB 0x0002
+#define IMAGE_REL_M32R_ADDR24 0x0003
+#define IMAGE_REL_M32R_GPREL16 0x0004
+#define IMAGE_REL_M32R_PCREL24 0x0005
+#define IMAGE_REL_M32R_PCREL16 0x0006
+#define IMAGE_REL_M32R_PCREL8 0x0007
+#define IMAGE_REL_M32R_REFHALF 0x0008
+#define IMAGE_REL_M32R_REFHI 0x0009
+#define IMAGE_REL_M32R_REFLO 0x000A
+#define IMAGE_REL_M32R_PAIR 0x000B
+#define IMAGE_REL_M32R_SECTION 0x000C
+#define IMAGE_REL_M32R_SECREL32 0x000D
+#define IMAGE_REL_M32R_TOKEN 0x000E
+
+#define EXT_IMM64(Value,Address,Size,InstPos,ValPos) Value |= (((ULONGLONG)((*(Address) >> InstPos) & (((ULONGLONG)1 << Size) - 1))) << ValPos)
+#define INS_IMM64(Value,Address,Size,InstPos,ValPos) *(PDWORD)Address = (*(PDWORD)Address & ~(((1 << Size) - 1) << InstPos)) | ((DWORD)((((ULONGLONG)Value >> ValPos) & (((ULONGLONG)1 << Size) - 1))) << InstPos)
+
+#define EMARCH_ENC_I17_IMM7B_INST_WORD_X 3
+#define EMARCH_ENC_I17_IMM7B_SIZE_X 7
+#define EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X 4
+#define EMARCH_ENC_I17_IMM7B_VAL_POS_X 0
+
+#define EMARCH_ENC_I17_IMM9D_INST_WORD_X 3
+#define EMARCH_ENC_I17_IMM9D_SIZE_X 9
+#define EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X 18
+#define EMARCH_ENC_I17_IMM9D_VAL_POS_X 7
+
+#define EMARCH_ENC_I17_IMM5C_INST_WORD_X 3
+#define EMARCH_ENC_I17_IMM5C_SIZE_X 5
+#define EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X 13
+#define EMARCH_ENC_I17_IMM5C_VAL_POS_X 16
+
+#define EMARCH_ENC_I17_IC_INST_WORD_X 3
+#define EMARCH_ENC_I17_IC_SIZE_X 1
+#define EMARCH_ENC_I17_IC_INST_WORD_POS_X 12
+#define EMARCH_ENC_I17_IC_VAL_POS_X 21
+
+#define EMARCH_ENC_I17_IMM41a_INST_WORD_X 1
+#define EMARCH_ENC_I17_IMM41a_SIZE_X 10
+#define EMARCH_ENC_I17_IMM41a_INST_WORD_POS_X 14
+#define EMARCH_ENC_I17_IMM41a_VAL_POS_X 22
+
+#define EMARCH_ENC_I17_IMM41b_INST_WORD_X 1
+#define EMARCH_ENC_I17_IMM41b_SIZE_X 8
+#define EMARCH_ENC_I17_IMM41b_INST_WORD_POS_X 24
+#define EMARCH_ENC_I17_IMM41b_VAL_POS_X 32
+
+#define EMARCH_ENC_I17_IMM41c_INST_WORD_X 2
+#define EMARCH_ENC_I17_IMM41c_SIZE_X 23
+#define EMARCH_ENC_I17_IMM41c_INST_WORD_POS_X 0
+#define EMARCH_ENC_I17_IMM41c_VAL_POS_X 40
+
+#define EMARCH_ENC_I17_SIGN_INST_WORD_X 3
+#define EMARCH_ENC_I17_SIGN_SIZE_X 1
+#define EMARCH_ENC_I17_SIGN_INST_WORD_POS_X 27
+#define EMARCH_ENC_I17_SIGN_VAL_POS_X 63
+
+#define X3_OPCODE_INST_WORD_X 3
+#define X3_OPCODE_SIZE_X 4
+#define X3_OPCODE_INST_WORD_POS_X 28
+#define X3_OPCODE_SIGN_VAL_POS_X 0
+
+#define X3_I_INST_WORD_X 3
+#define X3_I_SIZE_X 1
+#define X3_I_INST_WORD_POS_X 27
+#define X3_I_SIGN_VAL_POS_X 59
+
+#define X3_D_WH_INST_WORD_X 3
+#define X3_D_WH_SIZE_X 3
+#define X3_D_WH_INST_WORD_POS_X 24
+#define X3_D_WH_SIGN_VAL_POS_X 0
+
+#define X3_IMM20_INST_WORD_X 3
+#define X3_IMM20_SIZE_X 20
+#define X3_IMM20_INST_WORD_POS_X 4
+#define X3_IMM20_SIGN_VAL_POS_X 0
+
+#define X3_IMM39_1_INST_WORD_X 2
+#define X3_IMM39_1_SIZE_X 23
+#define X3_IMM39_1_INST_WORD_POS_X 0
+#define X3_IMM39_1_SIGN_VAL_POS_X 36
+
+#define X3_IMM39_2_INST_WORD_X 1
+#define X3_IMM39_2_SIZE_X 16
+#define X3_IMM39_2_INST_WORD_POS_X 16
+#define X3_IMM39_2_SIGN_VAL_POS_X 20
+
+#define X3_P_INST_WORD_X 3
+#define X3_P_SIZE_X 4
+#define X3_P_INST_WORD_POS_X 0
+#define X3_P_SIGN_VAL_POS_X 0
+
+#define X3_TMPLT_INST_WORD_X 0
+#define X3_TMPLT_SIZE_X 4
+#define X3_TMPLT_INST_WORD_POS_X 0
+#define X3_TMPLT_SIGN_VAL_POS_X 0
+
+#define X3_BTYPE_QP_INST_WORD_X 2
+#define X3_BTYPE_QP_SIZE_X 9
+#define X3_BTYPE_QP_INST_WORD_POS_X 23
+#define X3_BTYPE_QP_INST_VAL_POS_X 0
+
+#define X3_EMPTY_INST_WORD_X 1
+#define X3_EMPTY_SIZE_X 2
+#define X3_EMPTY_INST_WORD_POS_X 14
+#define X3_EMPTY_INST_VAL_POS_X 0
+
+ typedef struct _IMAGE_LINENUMBER {
+ union {
+ DWORD SymbolTableIndex;
+ DWORD VirtualAddress;
+ } Type;
+ WORD Linenumber;
+ } IMAGE_LINENUMBER;
+ typedef IMAGE_LINENUMBER UNALIGNED *PIMAGE_LINENUMBER;
+
+#define IMAGE_SIZEOF_LINENUMBER 6
+
+#include "poppack.h"
+
+ typedef struct _IMAGE_BASE_RELOCATION {
+ DWORD VirtualAddress;
+ DWORD SizeOfBlock;
+
+ } IMAGE_BASE_RELOCATION;
+ typedef IMAGE_BASE_RELOCATION UNALIGNED *PIMAGE_BASE_RELOCATION;
+
+#define IMAGE_SIZEOF_BASE_RELOCATION 8
+
+#define IMAGE_REL_BASED_ABSOLUTE 0
+#define IMAGE_REL_BASED_HIGH 1
+#define IMAGE_REL_BASED_LOW 2
+#define IMAGE_REL_BASED_HIGHLOW 3
+#define IMAGE_REL_BASED_HIGHADJ 4
+#define IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
+#define IMAGE_REL_BASED_IA64_IMM64 9
+#define IMAGE_REL_BASED_DIR64 10
+
+#define IMAGE_ARCHIVE_START_SIZE 8
+#define IMAGE_ARCHIVE_START "!<arch>\n"
+#define IMAGE_ARCHIVE_END "`\n"
+#define IMAGE_ARCHIVE_PAD "\n"
+#define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
+#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
+
+ typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER {
+ BYTE Name[16];
+ BYTE Date[12];
+ BYTE UserID[6];
+ BYTE GroupID[6];
+ BYTE Mode[8];
+ BYTE Size[10];
+ BYTE EndHeader[2];
+ } IMAGE_ARCHIVE_MEMBER_HEADER,*PIMAGE_ARCHIVE_MEMBER_HEADER;
+
+#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+
+ typedef struct _IMAGE_EXPORT_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD Name;
+ DWORD Base;
+ DWORD NumberOfFunctions;
+ DWORD NumberOfNames;
+ DWORD AddressOfFunctions;
+ DWORD AddressOfNames;
+ DWORD AddressOfNameOrdinals;
+ } IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
+
+ typedef struct _IMAGE_IMPORT_BY_NAME {
+ WORD Hint;
+ BYTE Name[1];
+ } IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
+
+#include "pshpack8.h"
+
+ typedef struct _IMAGE_THUNK_DATA64 {
+ union {
+ ULONGLONG ForwarderString;
+ ULONGLONG Function;
+ ULONGLONG Ordinal;
+ ULONGLONG AddressOfData;
+ } u1;
+ } IMAGE_THUNK_DATA64;
+ typedef IMAGE_THUNK_DATA64 *PIMAGE_THUNK_DATA64;
+
+#include "poppack.h"
+
+ typedef struct _IMAGE_THUNK_DATA32 {
+ union {
+ DWORD ForwarderString;
+ DWORD Function;
+ DWORD Ordinal;
+ DWORD AddressOfData;
+ } u1;
+ } IMAGE_THUNK_DATA32;
+ typedef IMAGE_THUNK_DATA32 *PIMAGE_THUNK_DATA32;
+
+#define IMAGE_ORDINAL_FLAG64 0x8000000000000000ull
+#define IMAGE_ORDINAL_FLAG32 0x80000000
+#define IMAGE_ORDINAL64(Ordinal) (Ordinal & 0xffffull)
+#define IMAGE_ORDINAL32(Ordinal) (Ordinal & 0xffff)
+#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64)!=0)
+#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG32)!=0)
+
+ typedef VOID
+ (NTAPI *PIMAGE_TLS_CALLBACK)(PVOID DllHandle,DWORD Reason,PVOID Reserved);
+
+ typedef struct _IMAGE_TLS_DIRECTORY64 {
+ ULONGLONG StartAddressOfRawData;
+ ULONGLONG EndAddressOfRawData;
+ ULONGLONG AddressOfIndex;
+ ULONGLONG AddressOfCallBacks;
+ DWORD SizeOfZeroFill;
+ DWORD Characteristics;
+ } IMAGE_TLS_DIRECTORY64;
+ typedef IMAGE_TLS_DIRECTORY64 *PIMAGE_TLS_DIRECTORY64;
+
+ typedef struct _IMAGE_TLS_DIRECTORY32 {
+ DWORD StartAddressOfRawData;
+ DWORD EndAddressOfRawData;
+ DWORD AddressOfIndex;
+ DWORD AddressOfCallBacks;
+ DWORD SizeOfZeroFill;
+ DWORD Characteristics;
+ } IMAGE_TLS_DIRECTORY32;
+ typedef IMAGE_TLS_DIRECTORY32 *PIMAGE_TLS_DIRECTORY32;
+
+#ifdef _WIN64
+#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG64
+#define IMAGE_ORDINAL(Ordinal) IMAGE_ORDINAL64(Ordinal)
+ typedef IMAGE_THUNK_DATA64 IMAGE_THUNK_DATA;
+ typedef PIMAGE_THUNK_DATA64 PIMAGE_THUNK_DATA;
+#define IMAGE_SNAP_BY_ORDINAL(Ordinal) IMAGE_SNAP_BY_ORDINAL64(Ordinal)
+ typedef IMAGE_TLS_DIRECTORY64 IMAGE_TLS_DIRECTORY;
+ typedef PIMAGE_TLS_DIRECTORY64 PIMAGE_TLS_DIRECTORY;
+#else
+#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG32
+#define IMAGE_ORDINAL(Ordinal) IMAGE_ORDINAL32(Ordinal)
+ typedef IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA;
+ typedef PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA;
+#define IMAGE_SNAP_BY_ORDINAL(Ordinal) IMAGE_SNAP_BY_ORDINAL32(Ordinal)
+ typedef IMAGE_TLS_DIRECTORY32 IMAGE_TLS_DIRECTORY;
+ typedef PIMAGE_TLS_DIRECTORY32 PIMAGE_TLS_DIRECTORY;
+#endif
+
+ typedef struct _IMAGE_IMPORT_DESCRIPTOR {
+ union {
+ DWORD Characteristics;
+ DWORD OriginalFirstThunk;
+ };
+ DWORD TimeDateStamp;
+
+ DWORD ForwarderChain;
+ DWORD Name;
+ DWORD FirstThunk;
+ } IMAGE_IMPORT_DESCRIPTOR;
+ typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
+
+ typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {
+ DWORD TimeDateStamp;
+ WORD OffsetModuleName;
+ WORD NumberOfModuleForwarderRefs;
+ } IMAGE_BOUND_IMPORT_DESCRIPTOR,*PIMAGE_BOUND_IMPORT_DESCRIPTOR;
+
+ typedef struct _IMAGE_BOUND_FORWARDER_REF {
+ DWORD TimeDateStamp;
+ WORD OffsetModuleName;
+ WORD Reserved;
+ } IMAGE_BOUND_FORWARDER_REF,*PIMAGE_BOUND_FORWARDER_REF;
+
+ typedef struct _IMAGE_RESOURCE_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ WORD NumberOfNamedEntries;
+ WORD NumberOfIdEntries;
+ } IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY;
+
+#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
+#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
+
+ typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
+ union {
+ struct {
+ DWORD NameOffset:31;
+ DWORD NameIsString:1;
+ };
+ DWORD Name;
+ WORD Id;
+ };
+ union {
+ DWORD OffsetToData;
+ struct {
+ DWORD OffsetToDirectory:31;
+ DWORD DataIsDirectory:1;
+ };
+ };
+ } IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY;
+
+ typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING {
+ WORD Length;
+ CHAR NameString[1];
+ } IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING;
+
+ typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
+ WORD Length;
+ WCHAR NameString[1];
+ } IMAGE_RESOURCE_DIR_STRING_U,*PIMAGE_RESOURCE_DIR_STRING_U;
+
+ typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
+ DWORD OffsetToData;
+ DWORD Size;
+ DWORD CodePage;
+ DWORD Reserved;
+ } IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY;
+
+ typedef struct {
+ DWORD Size;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD GlobalFlagsClear;
+ DWORD GlobalFlagsSet;
+ DWORD CriticalSectionDefaultTimeout;
+ DWORD DeCommitFreeBlockThreshold;
+ DWORD DeCommitTotalFreeThreshold;
+ DWORD LockPrefixTable;
+ DWORD MaximumAllocationSize;
+ DWORD VirtualMemoryThreshold;
+ DWORD ProcessHeapFlags;
+ DWORD ProcessAffinityMask;
+ WORD CSDVersion;
+ WORD Reserved1;
+ DWORD EditList;
+ DWORD SecurityCookie;
+ DWORD SEHandlerTable;
+ DWORD SEHandlerCount;
+ } IMAGE_LOAD_CONFIG_DIRECTORY32,*PIMAGE_LOAD_CONFIG_DIRECTORY32;
+
+ typedef struct {
+ DWORD Size;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD GlobalFlagsClear;
+ DWORD GlobalFlagsSet;
+ DWORD CriticalSectionDefaultTimeout;
+ ULONGLONG DeCommitFreeBlockThreshold;
+ ULONGLONG DeCommitTotalFreeThreshold;
+ ULONGLONG LockPrefixTable;
+ ULONGLONG MaximumAllocationSize;
+ ULONGLONG VirtualMemoryThreshold;
+ ULONGLONG ProcessAffinityMask;
+ DWORD ProcessHeapFlags;
+ WORD CSDVersion;
+ WORD Reserved1;
+ ULONGLONG EditList;
+ ULONGLONG SecurityCookie;
+ ULONGLONG SEHandlerTable;
+ ULONGLONG SEHandlerCount;
+ } IMAGE_LOAD_CONFIG_DIRECTORY64,*PIMAGE_LOAD_CONFIG_DIRECTORY64;
+
+#ifdef _WIN64
+ typedef IMAGE_LOAD_CONFIG_DIRECTORY64 IMAGE_LOAD_CONFIG_DIRECTORY;
+ typedef PIMAGE_LOAD_CONFIG_DIRECTORY64 PIMAGE_LOAD_CONFIG_DIRECTORY;
+#else
+ typedef IMAGE_LOAD_CONFIG_DIRECTORY32 IMAGE_LOAD_CONFIG_DIRECTORY;
+ typedef PIMAGE_LOAD_CONFIG_DIRECTORY32 PIMAGE_LOAD_CONFIG_DIRECTORY;
+#endif
+
+ typedef struct _IMAGE_CE_RUNTIME_FUNCTION_ENTRY {
+ DWORD FuncStart;
+ DWORD PrologLen : 8;
+ DWORD FuncLen : 22;
+ DWORD ThirtyTwoBit : 1;
+ DWORD ExceptionFlag : 1;
+ } IMAGE_CE_RUNTIME_FUNCTION_ENTRY,*PIMAGE_CE_RUNTIME_FUNCTION_ENTRY;
+
+ typedef struct _IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY {
+ ULONGLONG BeginAddress;
+ ULONGLONG EndAddress;
+ ULONGLONG ExceptionHandler;
+ ULONGLONG HandlerData;
+ ULONGLONG PrologEndAddress;
+ } IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY,*PIMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY;
+
+ typedef struct _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY {
+ DWORD BeginAddress;
+ DWORD EndAddress;
+ DWORD ExceptionHandler;
+ DWORD HandlerData;
+ DWORD PrologEndAddress;
+ } IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY,*PIMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY;
+
+ typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY {
+ DWORD BeginAddress;
+ DWORD EndAddress;
+ DWORD UnwindInfoAddress;
+ } _IMAGE_RUNTIME_FUNCTION_ENTRY,*_PIMAGE_RUNTIME_FUNCTION_ENTRY;
+
+ typedef _IMAGE_RUNTIME_FUNCTION_ENTRY IMAGE_IA64_RUNTIME_FUNCTION_ENTRY;
+ typedef _PIMAGE_RUNTIME_FUNCTION_ENTRY PIMAGE_IA64_RUNTIME_FUNCTION_ENTRY;
+
+ typedef _IMAGE_RUNTIME_FUNCTION_ENTRY IMAGE_RUNTIME_FUNCTION_ENTRY;
+ typedef _PIMAGE_RUNTIME_FUNCTION_ENTRY PIMAGE_RUNTIME_FUNCTION_ENTRY;
+
+ typedef struct _IMAGE_DEBUG_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD Type;
+ DWORD SizeOfData;
+ DWORD AddressOfRawData;
+ DWORD PointerToRawData;
+ } IMAGE_DEBUG_DIRECTORY,*PIMAGE_DEBUG_DIRECTORY;
+
+#define IMAGE_DEBUG_TYPE_UNKNOWN 0
+#define IMAGE_DEBUG_TYPE_COFF 1
+#define IMAGE_DEBUG_TYPE_CODEVIEW 2
+#define IMAGE_DEBUG_TYPE_FPO 3
+#define IMAGE_DEBUG_TYPE_MISC 4
+#define IMAGE_DEBUG_TYPE_EXCEPTION 5
+#define IMAGE_DEBUG_TYPE_FIXUP 6
+#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7
+#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8
+#define IMAGE_DEBUG_TYPE_BORLAND 9
+#define IMAGE_DEBUG_TYPE_RESERVED10 10
+#define IMAGE_DEBUG_TYPE_CLSID 11
+
+ typedef struct _IMAGE_COFF_SYMBOLS_HEADER {
+ DWORD NumberOfSymbols;
+ DWORD LvaToFirstSymbol;
+ DWORD NumberOfLinenumbers;
+ DWORD LvaToFirstLinenumber;
+ DWORD RvaToFirstByteOfCode;
+ DWORD RvaToLastByteOfCode;
+ DWORD RvaToFirstByteOfData;
+ DWORD RvaToLastByteOfData;
+ } IMAGE_COFF_SYMBOLS_HEADER,*PIMAGE_COFF_SYMBOLS_HEADER;
+
+#define FRAME_FPO 0
+#define FRAME_TRAP 1
+#define FRAME_TSS 2
+#define FRAME_NONFPO 3
+
+ typedef struct _FPO_DATA {
+ DWORD ulOffStart;
+ DWORD cbProcSize;
+ DWORD cdwLocals;
+ WORD cdwParams;
+ WORD cbProlog : 8;
+ WORD cbRegs : 3;
+ WORD fHasSEH : 1;
+ WORD fUseBP : 1;
+ WORD reserved : 1;
+ WORD cbFrame : 2;
+ } FPO_DATA,*PFPO_DATA;
+#define SIZEOF_RFPO_DATA 16
+
+#define IMAGE_DEBUG_MISC_EXENAME 1
+
+ typedef struct _IMAGE_DEBUG_MISC {
+ DWORD DataType;
+ DWORD Length;
+ BOOLEAN Unicode;
+ BYTE Reserved[3];
+ BYTE Data[1];
+ } IMAGE_DEBUG_MISC,*PIMAGE_DEBUG_MISC;
+
+ typedef struct _IMAGE_FUNCTION_ENTRY {
+ DWORD StartingAddress;
+ DWORD EndingAddress;
+ DWORD EndOfPrologue;
+ } IMAGE_FUNCTION_ENTRY,*PIMAGE_FUNCTION_ENTRY;
+
+ typedef struct _IMAGE_FUNCTION_ENTRY64 {
+ ULONGLONG StartingAddress;
+ ULONGLONG EndingAddress;
+ union {
+ ULONGLONG EndOfPrologue;
+ ULONGLONG UnwindInfoAddress;
+ };
+ } IMAGE_FUNCTION_ENTRY64,*PIMAGE_FUNCTION_ENTRY64;
+
+ typedef struct _IMAGE_SEPARATE_DEBUG_HEADER {
+ WORD Signature;
+ WORD Flags;
+ WORD Machine;
+ WORD Characteristics;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD ImageBase;
+ DWORD SizeOfImage;
+ DWORD NumberOfSections;
+ DWORD ExportedNamesSize;
+ DWORD DebugDirectorySize;
+ DWORD SectionAlignment;
+ DWORD Reserved[2];
+ } IMAGE_SEPARATE_DEBUG_HEADER,*PIMAGE_SEPARATE_DEBUG_HEADER;
+
+ typedef struct _NON_PAGED_DEBUG_INFO {
+ WORD Signature;
+ WORD Flags;
+ DWORD Size;
+ WORD Machine;
+ WORD Characteristics;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD SizeOfImage;
+ ULONGLONG ImageBase;
+
+ } NON_PAGED_DEBUG_INFO,*PNON_PAGED_DEBUG_INFO;
+
+#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
+#define NON_PAGED_DEBUG_SIGNATURE 0x494E
+
+#define IMAGE_SEPARATE_DEBUG_FLAGS_MASK 0x8000
+#define IMAGE_SEPARATE_DEBUG_MISMATCH 0x8000
+
+ typedef struct _ImageArchitectureHeader {
+ unsigned int AmaskValue: 1;
+ int Adummy1 :7;
+ unsigned int AmaskShift: 8;
+ int Adummy2 :16;
+ DWORD FirstEntryRVA;
+ } IMAGE_ARCHITECTURE_HEADER,*PIMAGE_ARCHITECTURE_HEADER;
+
+ typedef struct _ImageArchitectureEntry {
+ DWORD FixupInstRVA;
+ DWORD NewInst;
+ } IMAGE_ARCHITECTURE_ENTRY,*PIMAGE_ARCHITECTURE_ENTRY;
+
+#include "poppack.h"
+
+#define IMPORT_OBJECT_HDR_SIG2 0xffff
+
+ typedef struct IMPORT_OBJECT_HEADER {
+ WORD Sig1;
+ WORD Sig2;
+ WORD Version;
+ WORD Machine;
+ DWORD TimeDateStamp;
+ DWORD SizeOfData;
+ union {
+ WORD Ordinal;
+ WORD Hint;
+ };
+ WORD Type : 2;
+ WORD NameType : 3;
+ WORD Reserved : 11;
+ } IMPORT_OBJECT_HEADER;
+
+ typedef enum IMPORT_OBJECT_TYPE {
+ IMPORT_OBJECT_CODE = 0,IMPORT_OBJECT_DATA = 1,IMPORT_OBJECT_CONST = 2
+ } IMPORT_OBJECT_TYPE;
+
+ typedef enum IMPORT_OBJECT_NAME_TYPE {
+ IMPORT_OBJECT_ORDINAL = 0,IMPORT_OBJECT_NAME = 1,IMPORT_OBJECT_NAME_NO_PREFIX = 2,IMPORT_OBJECT_NAME_UNDECORATE = 3
+ } IMPORT_OBJECT_NAME_TYPE;
+
+#ifndef __IMAGE_COR20_HEADER_DEFINED__
+#define __IMAGE_COR20_HEADER_DEFINED__
+ typedef enum ReplacesCorHdrNumericDefines {
+ COMIMAGE_FLAGS_ILONLY =0x00000001,COMIMAGE_FLAGS_32BITREQUIRED =0x00000002,COMIMAGE_FLAGS_IL_LIBRARY =0x00000004,
+ COMIMAGE_FLAGS_STRONGNAMESIGNED =0x00000008,COMIMAGE_FLAGS_TRACKDEBUGDATA =0x00010000,COR_VERSION_MAJOR_V2 =2,
+ COR_VERSION_MAJOR =COR_VERSION_MAJOR_V2,COR_VERSION_MINOR =0,COR_DELETED_NAME_LENGTH =8,COR_VTABLEGAP_NAME_LENGTH =8,
+ NATIVE_TYPE_MAX_CB =1,COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE=0xFF,IMAGE_COR_MIH_METHODRVA =0x01,IMAGE_COR_MIH_EHRVA =0x02,
+ IMAGE_COR_MIH_BASICBLOCK =0x08,COR_VTABLE_32BIT =0x01,COR_VTABLE_64BIT =0x02,COR_VTABLE_FROM_UNMANAGED =0x04,
+ COR_VTABLE_CALL_MOST_DERIVED =0x10,IMAGE_COR_EATJ_THUNK_SIZE =32,MAX_CLASS_NAME =1024,MAX_PACKAGE_NAME =1024
+ } ReplacesCorHdrNumericDefines;
+
+ typedef struct IMAGE_COR20_HEADER {
+ DWORD cb;
+ WORD MajorRuntimeVersion;
+ WORD MinorRuntimeVersion;
+ IMAGE_DATA_DIRECTORY MetaData;
+ DWORD Flags;
+ DWORD EntryPointToken;
+ IMAGE_DATA_DIRECTORY Resources;
+ IMAGE_DATA_DIRECTORY StrongNameSignature;
+ IMAGE_DATA_DIRECTORY CodeManagerTable;
+ IMAGE_DATA_DIRECTORY VTableFixups;
+ IMAGE_DATA_DIRECTORY ExportAddressTableJumps;
+ IMAGE_DATA_DIRECTORY ManagedNativeHeader;
+ } IMAGE_COR20_HEADER,*PIMAGE_COR20_HEADER;
+#endif
+
+#if defined (__x86_64)
+ NTSYSAPI PRUNTIME_FUNCTION NTAPI RtlLookupFunctionEntry (DWORD64 ControlPc, PDWORD64 ImageBase, PUNWIND_HISTORY_TABLE HistoryTable);
+ NTSYSAPI VOID NTAPI RtlUnwindEx (PVOID TargetFrame, PVOID TargetIp, PEXCEPTION_RECORD ExceptionRecord, PVOID ReturnValue, PCONTEXT ContextRecord, PUNWIND_HISTORY_TABLE HistoryTable);
+#endif
+
+#include <string.h>
+
+#ifndef _SLIST_HEADER_
+#define _SLIST_HEADER_
+
+#ifdef _WIN64
+ typedef struct _SLIST_ENTRY *PSLIST_ENTRY;
+ typedef DECLSPEC_ALIGN(16) struct _SLIST_ENTRY {
+ PSLIST_ENTRY Next;
+ } SLIST_ENTRY;
+#else
+
+#define SLIST_ENTRY SINGLE_LIST_ENTRY
+#define _SLIST_ENTRY _SINGLE_LIST_ENTRY
+#define PSLIST_ENTRY PSINGLE_LIST_ENTRY
+#endif
+
+#if defined(_WIN64)
+
+ typedef DECLSPEC_ALIGN(16) struct _SLIST_HEADER {
+ ULONGLONG Alignment;
+ ULONGLONG Region;
+ } SLIST_HEADER;
+
+ typedef struct _SLIST_HEADER *PSLIST_HEADER;
+#else
+
+ typedef union _SLIST_HEADER {
+ ULONGLONG Alignment;
+ struct {
+ SLIST_ENTRY Next;
+ WORD Depth;
+ WORD Sequence;
+ };
+ } SLIST_HEADER,*PSLIST_HEADER;
+#endif
+#endif
+
+ NTSYSAPI VOID NTAPI RtlInitializeSListHead(PSLIST_HEADER ListHead);
+ NTSYSAPI PSLIST_ENTRY NTAPI RtlFirstEntrySList(const SLIST_HEADER *ListHead);
+ NTSYSAPI PSLIST_ENTRY NTAPI RtlInterlockedPopEntrySList(PSLIST_HEADER ListHead);
+ NTSYSAPI PSLIST_ENTRY NTAPI RtlInterlockedPushEntrySList(PSLIST_HEADER ListHead,PSLIST_ENTRY ListEntry);
+ NTSYSAPI PSLIST_ENTRY NTAPI RtlInterlockedFlushSList(PSLIST_HEADER ListHead);
+ NTSYSAPI WORD NTAPI RtlQueryDepthSList(PSLIST_HEADER ListHead);
+
+#define HEAP_NO_SERIALIZE 0x00000001
+#define HEAP_GROWABLE 0x00000002
+#define HEAP_GENERATE_EXCEPTIONS 0x00000004
+#define HEAP_ZERO_MEMORY 0x00000008
+#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010
+#define HEAP_TAIL_CHECKING_ENABLED 0x00000020
+#define HEAP_FREE_CHECKING_ENABLED 0x00000040
+#define HEAP_DISABLE_COALESCE_ON_FREE 0x00000080
+#define HEAP_CREATE_ALIGN_16 0x00010000
+#define HEAP_CREATE_ENABLE_TRACING 0x00020000
+#define HEAP_CREATE_ENABLE_EXECUTE 0x00040000
+#define HEAP_MAXIMUM_TAG 0x0FFF
+#define HEAP_PSEUDO_TAG_FLAG 0x8000
+#define HEAP_TAG_SHIFT 18
+#define HEAP_MAKE_TAG_FLAGS(b,o) ((DWORD)((b) + ((o) << 18)))
+
+ NTSYSAPI VOID NTAPI RtlCaptureContext(PCONTEXT ContextRecord);
+
+#define IS_TEXT_UNICODE_ASCII16 0x0001
+#define IS_TEXT_UNICODE_REVERSE_ASCII16 0x0010
+
+#define IS_TEXT_UNICODE_STATISTICS 0x0002
+#define IS_TEXT_UNICODE_REVERSE_STATISTICS 0x0020
+
+#define IS_TEXT_UNICODE_CONTROLS 0x0004
+#define IS_TEXT_UNICODE_REVERSE_CONTROLS 0x0040
+
+#define IS_TEXT_UNICODE_SIGNATURE 0x0008
+#define IS_TEXT_UNICODE_REVERSE_SIGNATURE 0x0080
+
+#define IS_TEXT_UNICODE_ILLEGAL_CHARS 0x0100
+#define IS_TEXT_UNICODE_ODD_LENGTH 0x0200
+#define IS_TEXT_UNICODE_DBCS_LEADBYTE 0x0400
+#define IS_TEXT_UNICODE_NULL_BYTES 0x1000
+
+#define IS_TEXT_UNICODE_UNICODE_MASK 0x000F
+#define IS_TEXT_UNICODE_REVERSE_MASK 0x00F0
+#define IS_TEXT_UNICODE_NOT_UNICODE_MASK 0x0F00
+#define IS_TEXT_UNICODE_NOT_ASCII_MASK 0xF000
+
+#define COMPRESSION_FORMAT_NONE (0x0000)
+#define COMPRESSION_FORMAT_DEFAULT (0x0001)
+#define COMPRESSION_FORMAT_LZNT1 (0x0002)
+#define COMPRESSION_ENGINE_STANDARD (0x0000)
+#define COMPRESSION_ENGINE_MAXIMUM (0x0100)
+#define COMPRESSION_ENGINE_HIBER (0x0200)
+
+#if _DBG_MEMCPY_INLINE_ && !defined(_MEMCPY_INLINE_) && !defined(_CRTBLD)
+#define _MEMCPY_INLINE_
+ __CRT_INLINE PVOID __cdecl memcpy_inline(void *dst,const void *src,size_t size) {
+ if(((char *)dst > (char *)src) && ((char *)dst < ((char *)src + size))) {
+ __debugbreak();
+ }
+ return memcpy(dst,src,size);
+ }
+#define memcpy memcpy_inline
+#endif
+
+ NTSYSAPI SIZE_T NTAPI RtlCompareMemory(const VOID *Source1,const VOID *Source2,SIZE_T Length);
+
+#define RtlEqualMemory(Destination,Source,Length) (!memcmp((Destination),(Source),(Length)))
+#define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
+#define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length))
+#define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
+#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
+
+ __CRT_INLINE PVOID RtlSecureZeroMemory(PVOID ptr,SIZE_T cnt) {
+ volatile char *vptr =(volatile char *)ptr;
+#ifdef __x86_64
+ __stosb((PBYTE)((DWORD64)vptr),0,cnt);
+#else
+ while(cnt) {
+ *vptr = 0;
+ vptr++;
+ cnt--;
+ }
+#endif
+ return ptr;
+ }
+
+ typedef struct _MESSAGE_RESOURCE_ENTRY {
+ WORD Length;
+ WORD Flags;
+ BYTE Text[1];
+ } MESSAGE_RESOURCE_ENTRY,*PMESSAGE_RESOURCE_ENTRY;
+
+#define MESSAGE_RESOURCE_UNICODE 0x0001
+
+ typedef struct _MESSAGE_RESOURCE_BLOCK {
+ DWORD LowId;
+ DWORD HighId;
+ DWORD OffsetToEntries;
+ } MESSAGE_RESOURCE_BLOCK,*PMESSAGE_RESOURCE_BLOCK;
+
+ typedef struct _MESSAGE_RESOURCE_DATA {
+ DWORD NumberOfBlocks;
+ MESSAGE_RESOURCE_BLOCK Blocks[1];
+ } MESSAGE_RESOURCE_DATA,*PMESSAGE_RESOURCE_DATA;
+
+ typedef struct _OSVERSIONINFOA {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ CHAR szCSDVersion[128];
+ } OSVERSIONINFOA,*POSVERSIONINFOA,*LPOSVERSIONINFOA;
+
+ typedef struct _OSVERSIONINFOW {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ WCHAR szCSDVersion[128];
+ } OSVERSIONINFOW,*POSVERSIONINFOW,*LPOSVERSIONINFOW,RTL_OSVERSIONINFOW,*PRTL_OSVERSIONINFOW;
+
+#ifdef UNICODE
+ typedef OSVERSIONINFOW OSVERSIONINFO;
+ typedef POSVERSIONINFOW POSVERSIONINFO;
+ typedef LPOSVERSIONINFOW LPOSVERSIONINFO;
+#else
+ typedef OSVERSIONINFOA OSVERSIONINFO;
+ typedef POSVERSIONINFOA POSVERSIONINFO;
+ typedef LPOSVERSIONINFOA LPOSVERSIONINFO;
+#endif
+
+ typedef struct _OSVERSIONINFOEXA {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ CHAR szCSDVersion[128];
+ WORD wServicePackMajor;
+ WORD wServicePackMinor;
+ WORD wSuiteMask;
+ BYTE wProductType;
+ BYTE wReserved;
+ } OSVERSIONINFOEXA,*POSVERSIONINFOEXA,*LPOSVERSIONINFOEXA;
+
+ typedef struct _OSVERSIONINFOEXW {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ WCHAR szCSDVersion[128];
+ WORD wServicePackMajor;
+ WORD wServicePackMinor;
+ WORD wSuiteMask;
+ BYTE wProductType;
+ BYTE wReserved;
+ } OSVERSIONINFOEXW,*POSVERSIONINFOEXW,*LPOSVERSIONINFOEXW,RTL_OSVERSIONINFOEXW,*PRTL_OSVERSIONINFOEXW;
+#ifdef UNICODE
+ typedef OSVERSIONINFOEXW OSVERSIONINFOEX;
+ typedef POSVERSIONINFOEXW POSVERSIONINFOEX;
+ typedef LPOSVERSIONINFOEXW LPOSVERSIONINFOEX;
+#else
+ typedef OSVERSIONINFOEXA OSVERSIONINFOEX;
+ typedef POSVERSIONINFOEXA POSVERSIONINFOEX;
+ typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX;
+#endif
+
+#define VER_EQUAL 1
+#define VER_GREATER 2
+#define VER_GREATER_EQUAL 3
+#define VER_LESS 4
+#define VER_LESS_EQUAL 5
+#define VER_AND 6
+#define VER_OR 7
+
+#define VER_CONDITION_MASK 7
+#define VER_NUM_BITS_PER_CONDITION_MASK 3
+
+#define VER_MINORVERSION 0x0000001
+#define VER_MAJORVERSION 0x0000002
+#define VER_BUILDNUMBER 0x0000004
+#define VER_PLATFORMID 0x0000008
+#define VER_SERVICEPACKMINOR 0x0000010
+#define VER_SERVICEPACKMAJOR 0x0000020
+#define VER_SUITENAME 0x0000040
+#define VER_PRODUCT_TYPE 0x0000080
+
+#define VER_NT_WORKSTATION 0x0000001
+#define VER_NT_DOMAIN_CONTROLLER 0x0000002
+#define VER_NT_SERVER 0x0000003
+
+#define VER_PLATFORM_WIN32s 0
+#define VER_PLATFORM_WIN32_WINDOWS 1
+#define VER_PLATFORM_WIN32_NT 2
+
+#define VER_SET_CONDITION(_m_,_t_,_c_) ((_m_)=VerSetConditionMask((_m_),(_t_),(_c_)))
+
+ NTSYSAPI ULONGLONG NTAPI VerSetConditionMask(ULONGLONG ConditionMask,DWORD TypeMask,BYTE Condition);
+
+ typedef struct _RTL_CRITICAL_SECTION_DEBUG {
+ WORD Type;
+ WORD CreatorBackTraceIndex;
+ struct _RTL_CRITICAL_SECTION *CriticalSection;
+ LIST_ENTRY ProcessLocksList;
+ DWORD EntryCount;
+ DWORD ContentionCount;
+ DWORD Spare[2];
+ } RTL_CRITICAL_SECTION_DEBUG,*PRTL_CRITICAL_SECTION_DEBUG,RTL_RESOURCE_DEBUG,*PRTL_RESOURCE_DEBUG;
+
+#define RTL_CRITSECT_TYPE 0
+#define RTL_RESOURCE_TYPE 1
+
+ typedef struct _RTL_CRITICAL_SECTION {
+ PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
+ LONG LockCount;
+ LONG RecursionCount;
+ HANDLE OwningThread;
+ HANDLE LockSemaphore;
+ ULONG_PTR SpinCount;
+ } RTL_CRITICAL_SECTION,*PRTL_CRITICAL_SECTION;
+
+ typedef VOID (NTAPI *RTL_VERIFIER_DLL_LOAD_CALLBACK) (PWSTR DllName,PVOID DllBase,SIZE_T DllSize,PVOID Reserved);
+ typedef VOID (NTAPI *RTL_VERIFIER_DLL_UNLOAD_CALLBACK) (PWSTR DllName,PVOID DllBase,SIZE_T DllSize,PVOID Reserved);
+ typedef VOID (NTAPI *RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK)(PVOID AllocationBase,SIZE_T AllocationSize);
+
+ typedef struct _RTL_VERIFIER_THUNK_DESCRIPTOR {
+ PCHAR ThunkName;
+ PVOID ThunkOldAddress;
+ PVOID ThunkNewAddress;
+ } RTL_VERIFIER_THUNK_DESCRIPTOR,*PRTL_VERIFIER_THUNK_DESCRIPTOR;
+
+ typedef struct _RTL_VERIFIER_DLL_DESCRIPTOR {
+ PWCHAR DllName;
+ DWORD DllFlags;
+ PVOID DllAddress;
+ PRTL_VERIFIER_THUNK_DESCRIPTOR DllThunks;
+ } RTL_VERIFIER_DLL_DESCRIPTOR,*PRTL_VERIFIER_DLL_DESCRIPTOR;
+
+ typedef struct _RTL_VERIFIER_PROVIDER_DESCRIPTOR {
+ DWORD Length;
+ PRTL_VERIFIER_DLL_DESCRIPTOR ProviderDlls;
+ RTL_VERIFIER_DLL_LOAD_CALLBACK ProviderDllLoadCallback;
+ RTL_VERIFIER_DLL_UNLOAD_CALLBACK ProviderDllUnloadCallback;
+ PWSTR VerifierImage;
+ DWORD VerifierFlags;
+ DWORD VerifierDebug;
+ PVOID RtlpGetStackTraceAddress;
+ PVOID RtlpDebugPageHeapCreate;
+ PVOID RtlpDebugPageHeapDestroy;
+ RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK ProviderNtdllHeapFreeCallback;
+ } RTL_VERIFIER_PROVIDER_DESCRIPTOR,*PRTL_VERIFIER_PROVIDER_DESCRIPTOR;
+
+#define RTL_VRF_FLG_FULL_PAGE_HEAP 0x00000001
+#define RTL_VRF_FLG_RESERVED_DONOTUSE 0x00000002
+#define RTL_VRF_FLG_HANDLE_CHECKS 0x00000004
+#define RTL_VRF_FLG_STACK_CHECKS 0x00000008
+#define RTL_VRF_FLG_APPCOMPAT_CHECKS 0x00000010
+#define RTL_VRF_FLG_TLS_CHECKS 0x00000020
+#define RTL_VRF_FLG_DIRTY_STACKS 0x00000040
+#define RTL_VRF_FLG_RPC_CHECKS 0x00000080
+#define RTL_VRF_FLG_COM_CHECKS 0x00000100
+#define RTL_VRF_FLG_DANGEROUS_APIS 0x00000200
+#define RTL_VRF_FLG_RACE_CHECKS 0x00000400
+#define RTL_VRF_FLG_DEADLOCK_CHECKS 0x00000800
+#define RTL_VRF_FLG_FIRST_CHANCE_EXCEPTION_CHECKS 0x00001000
+#define RTL_VRF_FLG_VIRTUAL_MEM_CHECKS 0x00002000
+#define RTL_VRF_FLG_ENABLE_LOGGING 0x00004000
+#define RTL_VRF_FLG_FAST_FILL_HEAP 0x00008000
+#define RTL_VRF_FLG_VIRTUAL_SPACE_TRACKING 0x00010000
+#define RTL_VRF_FLG_ENABLED_SYSTEM_WIDE 0x00020000
+#define RTL_VRF_FLG_MISCELLANEOUS_CHECKS 0x00020000
+#define RTL_VRF_FLG_LOCK_CHECKS 0x00040000
+
+#define APPLICATION_VERIFIER_INTERNAL_ERROR 0x80000000
+#define APPLICATION_VERIFIER_INTERNAL_WARNING 0x40000000
+#define APPLICATION_VERIFIER_NO_BREAK 0x20000000
+#define APPLICATION_VERIFIER_CONTINUABLE_BREAK 0x10000000
+
+#define APPLICATION_VERIFIER_UNKNOWN_ERROR 0x0001
+#define APPLICATION_VERIFIER_ACCESS_VIOLATION 0x0002
+#define APPLICATION_VERIFIER_UNSYNCHRONIZED_ACCESS 0x0003
+#define APPLICATION_VERIFIER_EXTREME_SIZE_REQUEST 0x0004
+#define APPLICATION_VERIFIER_BAD_HEAP_HANDLE 0x0005
+#define APPLICATION_VERIFIER_SWITCHED_HEAP_HANDLE 0x0006
+#define APPLICATION_VERIFIER_DOUBLE_FREE 0x0007
+#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK 0x0008
+#define APPLICATION_VERIFIER_DESTROY_PROCESS_HEAP 0x0009
+#define APPLICATION_VERIFIER_UNEXPECTED_EXCEPTION 0x000A
+#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_EXCEPTION_RAISED_FOR_HEADER 0x000B
+#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_EXCEPTION_RAISED_FOR_PROBING 0x000C
+#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_HEADER 0x000D
+#define APPLICATION_VERIFIER_CORRUPTED_FREED_HEAP_BLOCK 0x000E
+#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_SUFFIX 0x000F
+#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_START_STAMP 0x0010
+#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_END_STAMP 0x0011
+#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_PREFIX 0x0012
+#define APPLICATION_VERIFIER_FIRST_CHANCE_ACCESS_VIOLATION 0x0013
+#define APPLICATION_VERIFIER_CORRUPTED_HEAP_LIST 0x0014
+
+#define APPLICATION_VERIFIER_TERMINATE_THREAD_CALL 0x0100
+#define APPLICATION_VERIFIER_STACK_OVERFLOW 0x0101
+#define APPLICATION_VERIFIER_INVALID_EXIT_PROCESS_CALL 0x0102
+
+#define APPLICATION_VERIFIER_EXIT_THREAD_OWNS_LOCK 0x0200
+#define APPLICATION_VERIFIER_LOCK_IN_UNLOADED_DLL 0x0201
+#define APPLICATION_VERIFIER_LOCK_IN_FREED_HEAP 0x0202
+#define APPLICATION_VERIFIER_LOCK_DOUBLE_INITIALIZE 0x0203
+#define APPLICATION_VERIFIER_LOCK_IN_FREED_MEMORY 0x0204
+#define APPLICATION_VERIFIER_LOCK_CORRUPTED 0x0205
+#define APPLICATION_VERIFIER_LOCK_INVALID_OWNER 0x0206
+#define APPLICATION_VERIFIER_LOCK_INVALID_RECURSION_COUNT 0x0207
+#define APPLICATION_VERIFIER_LOCK_INVALID_LOCK_COUNT 0x0208
+#define APPLICATION_VERIFIER_LOCK_OVER_RELEASED 0x0209
+#define APPLICATION_VERIFIER_LOCK_NOT_INITIALIZED 0x0210
+#define APPLICATION_VERIFIER_LOCK_ALREADY_INITIALIZED 0x0211
+#define APPLICATION_VERIFIER_LOCK_IN_FREED_VMEM 0x0212
+#define APPLICATION_VERIFIER_LOCK_IN_UNMAPPED_MEM 0x0213
+#define APPLICATION_VERIFIER_THREAD_NOT_LOCK_OWNER 0x0214
+
+#define APPLICATION_VERIFIER_INVALID_HANDLE 0x0300
+#define APPLICATION_VERIFIER_INVALID_TLS_VALUE 0x0301
+#define APPLICATION_VERIFIER_INCORRECT_WAIT_CALL 0x0302
+#define APPLICATION_VERIFIER_NULL_HANDLE 0x0303
+#define APPLICATION_VERIFIER_WAIT_IN_DLLMAIN 0x0304
+
+#define APPLICATION_VERIFIER_COM_ERROR 0x0400
+#define APPLICATION_VERIFIER_COM_API_IN_DLLMAIN 0x0401
+#define APPLICATION_VERIFIER_COM_UNHANDLED_EXCEPTION 0x0402
+#define APPLICATION_VERIFIER_COM_UNBALANCED_COINIT 0x0403
+#define APPLICATION_VERIFIER_COM_UNBALANCED_OLEINIT 0x0404
+#define APPLICATION_VERIFIER_COM_UNBALANCED_SWC 0x0405
+#define APPLICATION_VERIFIER_COM_NULL_DACL 0x0406
+#define APPLICATION_VERIFIER_COM_UNSAFE_IMPERSONATION 0x0407
+#define APPLICATION_VERIFIER_COM_SMUGGLED_WRAPPER 0x0408
+#define APPLICATION_VERIFIER_COM_SMUGGLED_PROXY 0x0409
+#define APPLICATION_VERIFIER_COM_CF_SUCCESS_WITH_NULL 0x040A
+#define APPLICATION_VERIFIER_COM_GCO_SUCCESS_WITH_NULL 0x040B
+#define APPLICATION_VERIFIER_COM_OBJECT_IN_FREED_MEMORY 0x040C
+#define APPLICATION_VERIFIER_COM_OBJECT_IN_UNLOADED_DLL 0x040D
+#define APPLICATION_VERIFIER_COM_VTBL_IN_FREED_MEMORY 0x040E
+#define APPLICATION_VERIFIER_COM_VTBL_IN_UNLOADED_DLL 0x040F
+#define APPLICATION_VERIFIER_COM_HOLDING_LOCKS_ON_CALL 0x0410
+
+#define APPLICATION_VERIFIER_RPC_ERROR 0x0500
+
+#define APPLICATION_VERIFIER_INVALID_FREEMEM 0x0600
+#define APPLICATION_VERIFIER_INVALID_ALLOCMEM 0x0601
+#define APPLICATION_VERIFIER_INVALID_MAPVIEW 0x0602
+#define APPLICATION_VERIFIER_PROBE_INVALID_ADDRESS 0x0603
+#define APPLICATION_VERIFIER_PROBE_FREE_MEM 0x0604
+#define APPLICATION_VERIFIER_PROBE_GUARD_PAGE 0x0605
+#define APPLICATION_VERIFIER_PROBE_NULL 0x0606
+#define APPLICATION_VERIFIER_PROBE_INVALID_START_OR_SIZE 0x0607
+#define APPLICATION_VERIFIER_SIZE_HEAP_UNEXPECTED_EXCEPTION 0x0618
+
+#define VERIFIER_STOP(Code,Msg,P1,S1,P2,S2,P3,S3,P4,S4) { RtlApplicationVerifierStop ((Code),(Msg),(ULONG_PTR)(P1),(S1),(ULONG_PTR)(P2),(S2),(ULONG_PTR)(P3),(S3),(ULONG_PTR)(P4),(S4)); }
+
+ VOID NTAPI RtlApplicationVerifierStop(ULONG_PTR Code,PSTR Message,ULONG_PTR Param1,PSTR Description1,ULONG_PTR Param2,PSTR Description2,ULONG_PTR Param3,PSTR Description3,ULONG_PTR Param4,PSTR Description4);
+
+ typedef LONG (NTAPI *PVECTORED_EXCEPTION_HANDLER)(struct _EXCEPTION_POINTERS *ExceptionInfo);
+#define SEF_DACL_AUTO_INHERIT 0x01
+#define SEF_SACL_AUTO_INHERIT 0x02
+#define SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT 0x04
+#define SEF_AVOID_PRIVILEGE_CHECK 0x08
+#define SEF_AVOID_OWNER_CHECK 0x10
+#define SEF_DEFAULT_OWNER_FROM_PARENT 0x20
+#define SEF_DEFAULT_GROUP_FROM_PARENT 0x40
+
+ typedef enum _HEAP_INFORMATION_CLASS {
+ HeapCompatibilityInformation
+ } HEAP_INFORMATION_CLASS;
+
+ NTSYSAPI DWORD NTAPI RtlSetHeapInformation(PVOID HeapHandle,HEAP_INFORMATION_CLASS HeapInformationClass,PVOID HeapInformation,SIZE_T HeapInformationLength);
+ NTSYSAPI DWORD NTAPI RtlQueryHeapInformation(PVOID HeapHandle,HEAP_INFORMATION_CLASS HeapInformationClass,PVOID HeapInformation,SIZE_T HeapInformationLength,PSIZE_T ReturnLength);
+ DWORD NTAPI RtlMultipleAllocateHeap(PVOID HeapHandle,DWORD Flags,SIZE_T Size,DWORD Count,PVOID *Array);
+ DWORD NTAPI RtlMultipleFreeHeap(PVOID HeapHandle,DWORD Flags,DWORD Count,PVOID *Array);
+
+#define WT_EXECUTEDEFAULT 0x00000000
+#define WT_EXECUTEINIOTHREAD 0x00000001
+#define WT_EXECUTEINUITHREAD 0x00000002
+#define WT_EXECUTEINWAITTHREAD 0x00000004
+#define WT_EXECUTEONLYONCE 0x00000008
+#define WT_EXECUTEINTIMERTHREAD 0x00000020
+#define WT_EXECUTELONGFUNCTION 0x00000010
+#define WT_EXECUTEINPERSISTENTIOTHREAD 0x00000040
+#define WT_EXECUTEINPERSISTENTTHREAD 0x00000080
+#define WT_TRANSFER_IMPERSONATION 0x00000100
+#define WT_SET_MAX_THREADPOOL_THREADS(Flags,Limit) ((Flags) |= (Limit)<<16)
+ typedef VOID (NTAPI *WAITORTIMERCALLBACKFUNC)(PVOID,BOOLEAN);
+ typedef VOID (NTAPI *WORKERCALLBACKFUNC)(PVOID);
+ typedef VOID (NTAPI *APC_CALLBACK_FUNCTION)(DWORD ,PVOID,PVOID);
+ typedef
+ VOID
+ (NTAPI *PFLS_CALLBACK_FUNCTION)(PVOID lpFlsData);
+#define WT_EXECUTEINLONGTHREAD 0x00000010
+#define WT_EXECUTEDELETEWAIT 0x00000008
+
+ typedef enum _ACTIVATION_CONTEXT_INFO_CLASS {
+ ActivationContextBasicInformation = 1,ActivationContextDetailedInformation = 2,AssemblyDetailedInformationInActivationContext = 3,FileInformationInAssemblyOfAssemblyInActivationContext = 4,MaxActivationContextInfoClass,AssemblyDetailedInformationInActivationContxt = 3,FileInformationInAssemblyOfAssemblyInActivationContxt = 4
+ } ACTIVATION_CONTEXT_INFO_CLASS;
+
+#define ACTIVATIONCONTEXTINFOCLASS ACTIVATION_CONTEXT_INFO_CLASS
+
+ typedef struct _ACTIVATION_CONTEXT_QUERY_INDEX {
+ DWORD ulAssemblyIndex;
+ DWORD ulFileIndexInAssembly;
+ } ACTIVATION_CONTEXT_QUERY_INDEX,*PACTIVATION_CONTEXT_QUERY_INDEX;
+
+ typedef const struct _ACTIVATION_CONTEXT_QUERY_INDEX *PCACTIVATION_CONTEXT_QUERY_INDEX;
+
+#define ACTIVATION_CONTEXT_PATH_TYPE_NONE (1)
+#define ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE (2)
+#define ACTIVATION_CONTEXT_PATH_TYPE_URL (3)
+#define ACTIVATION_CONTEXT_PATH_TYPE_ASSEMBLYREF (4)
+
+ typedef struct _ASSEMBLY_FILE_DETAILED_INFORMATION {
+ DWORD ulFlags;
+ DWORD ulFilenameLength;
+ DWORD ulPathLength;
+
+ PCWSTR lpFileName;
+ PCWSTR lpFilePath;
+ } ASSEMBLY_FILE_DETAILED_INFORMATION,*PASSEMBLY_FILE_DETAILED_INFORMATION;
+ typedef const ASSEMBLY_FILE_DETAILED_INFORMATION *PCASSEMBLY_FILE_DETAILED_INFORMATION;
+
+#define _ASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION _ASSEMBLY_FILE_DETAILED_INFORMATION
+#define ASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION ASSEMBLY_FILE_DETAILED_INFORMATION
+#define PASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION PASSEMBLY_FILE_DETAILED_INFORMATION
+#define PCASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION PCASSEMBLY_FILE_DETAILED_INFORMATION
+
+ typedef struct _ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION {
+ DWORD ulFlags;
+ DWORD ulEncodedAssemblyIdentityLength;
+ DWORD ulManifestPathType;
+ DWORD ulManifestPathLength;
+ LARGE_INTEGER liManifestLastWriteTime;
+ DWORD ulPolicyPathType;
+ DWORD ulPolicyPathLength;
+ LARGE_INTEGER liPolicyLastWriteTime;
+ DWORD ulMetadataSatelliteRosterIndex;
+ DWORD ulManifestVersionMajor;
+ DWORD ulManifestVersionMinor;
+ DWORD ulPolicyVersionMajor;
+ DWORD ulPolicyVersionMinor;
+ DWORD ulAssemblyDirectoryNameLength;
+ PCWSTR lpAssemblyEncodedAssemblyIdentity;
+ PCWSTR lpAssemblyManifestPath;
+ PCWSTR lpAssemblyPolicyPath;
+ PCWSTR lpAssemblyDirectoryName;
+ DWORD ulFileCount;
+ } ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION,*PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION;
+
+ typedef const struct _ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *PCACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION;
+
+ typedef struct _ACTIVATION_CONTEXT_DETAILED_INFORMATION {
+ DWORD dwFlags;
+ DWORD ulFormatVersion;
+ DWORD ulAssemblyCount;
+ DWORD ulRootManifestPathType;
+ DWORD ulRootManifestPathChars;
+ DWORD ulRootConfigurationPathType;
+ DWORD ulRootConfigurationPathChars;
+ DWORD ulAppDirPathType;
+ DWORD ulAppDirPathChars;
+ PCWSTR lpRootManifestPath;
+ PCWSTR lpRootConfigurationPath;
+ PCWSTR lpAppDirPath;
+ } ACTIVATION_CONTEXT_DETAILED_INFORMATION,*PACTIVATION_CONTEXT_DETAILED_INFORMATION;
+
+ typedef const struct _ACTIVATION_CONTEXT_DETAILED_INFORMATION *PCACTIVATION_CONTEXT_DETAILED_INFORMATION;
+
+#define DLL_PROCESS_ATTACH 1
+#define DLL_THREAD_ATTACH 2
+#define DLL_THREAD_DETACH 3
+#define DLL_PROCESS_DETACH 0
+#define DLL_PROCESS_VERIFIER 4
+
+#define EVENTLOG_SEQUENTIAL_READ 0x0001
+#define EVENTLOG_SEEK_READ 0x0002
+#define EVENTLOG_FORWARDS_READ 0x0004
+#define EVENTLOG_BACKWARDS_READ 0x0008
+
+#define EVENTLOG_SUCCESS 0x0000
+#define EVENTLOG_ERROR_TYPE 0x0001
+#define EVENTLOG_WARNING_TYPE 0x0002
+#define EVENTLOG_INFORMATION_TYPE 0x0004
+#define EVENTLOG_AUDIT_SUCCESS 0x0008
+#define EVENTLOG_AUDIT_FAILURE 0x0010
+
+#define EVENTLOG_START_PAIRED_EVENT 0x0001
+#define EVENTLOG_END_PAIRED_EVENT 0x0002
+#define EVENTLOG_END_ALL_PAIRED_EVENTS 0x0004
+#define EVENTLOG_PAIRED_EVENT_ACTIVE 0x0008
+#define EVENTLOG_PAIRED_EVENT_INACTIVE 0x0010
+
+ typedef struct _EVENTLOGRECORD {
+ DWORD Length;
+ DWORD Reserved;
+ DWORD RecordNumber;
+ DWORD TimeGenerated;
+ DWORD TimeWritten;
+ DWORD EventID;
+ WORD EventType;
+ WORD NumStrings;
+ WORD EventCategory;
+ WORD ReservedFlags;
+ DWORD ClosingRecordNumber;
+ DWORD StringOffset;
+ DWORD UserSidLength;
+ DWORD UserSidOffset;
+ DWORD DataLength;
+ DWORD DataOffset;
+ } EVENTLOGRECORD,*PEVENTLOGRECORD;
+
+#define MAXLOGICALLOGNAMESIZE 256
+
+ typedef struct _EVENTSFORLOGFILE{
+ DWORD ulSize;
+ WCHAR szLogicalLogFile[MAXLOGICALLOGNAMESIZE];
+ DWORD ulNumRecords;
+ EVENTLOGRECORD pEventLogRecords[];
+ } EVENTSFORLOGFILE,*PEVENTSFORLOGFILE;
+
+ typedef struct _PACKEDEVENTINFO{
+ DWORD ulSize;
+ DWORD ulNumEventsForLogFile;
+ DWORD ulOffsets[];
+ } PACKEDEVENTINFO,*PPACKEDEVENTINFO;
+
+#define KEY_QUERY_VALUE (0x0001)
+#define KEY_SET_VALUE (0x0002)
+#define KEY_CREATE_SUB_KEY (0x0004)
+#define KEY_ENUMERATE_SUB_KEYS (0x0008)
+#define KEY_NOTIFY (0x0010)
+#define KEY_CREATE_LINK (0x0020)
+#define KEY_WOW64_32KEY (0x0200)
+#define KEY_WOW64_64KEY (0x0100)
+#define KEY_WOW64_RES (0x0300)
+
+#define KEY_READ ((STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & (~SYNCHRONIZE))
+#define KEY_WRITE ((STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY) & (~SYNCHRONIZE))
+#define KEY_EXECUTE ((KEY_READ) & (~SYNCHRONIZE))
+#define KEY_ALL_ACCESS ((STANDARD_RIGHTS_ALL | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_CREATE_LINK) & (~SYNCHRONIZE))
+#define REG_OPTION_RESERVED (0x00000000L)
+
+#define REG_OPTION_NON_VOLATILE (0x00000000L)
+#define REG_OPTION_VOLATILE (0x00000001L)
+#define REG_OPTION_CREATE_LINK (0x00000002L)
+#define REG_OPTION_BACKUP_RESTORE (0x00000004L)
+#define REG_OPTION_OPEN_LINK (0x00000008L)
+#define REG_LEGAL_OPTION (REG_OPTION_RESERVED | REG_OPTION_NON_VOLATILE | REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK | REG_OPTION_BACKUP_RESTORE | REG_OPTION_OPEN_LINK)
+#define REG_CREATED_NEW_KEY (0x00000001L)
+#define REG_OPENED_EXISTING_KEY (0x00000002L)
+#define REG_STANDARD_FORMAT 1
+#define REG_LATEST_FORMAT 2
+#define REG_NO_COMPRESSION 4
+#define REG_WHOLE_HIVE_VOLATILE (0x00000001L)
+#define REG_REFRESH_HIVE (0x00000002L)
+#define REG_NO_LAZY_FLUSH (0x00000004L)
+#define REG_FORCE_RESTORE (0x00000008L)
+#define REG_FORCE_UNLOAD 1
+
+#define REG_NOTIFY_CHANGE_NAME (0x00000001L)
+#define REG_NOTIFY_CHANGE_ATTRIBUTES (0x00000002L)
+#define REG_NOTIFY_CHANGE_LAST_SET (0x00000004L)
+#define REG_NOTIFY_CHANGE_SECURITY (0x00000008L)
+
+#define REG_LEGAL_CHANGE_FILTER (REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY)
+
+#define REG_NONE (0)
+#define REG_SZ (1)
+#define REG_EXPAND_SZ (2)
+
+#define REG_BINARY (3)
+#define REG_DWORD (4)
+#define REG_DWORD_LITTLE_ENDIAN (4)
+#define REG_DWORD_BIG_ENDIAN (5)
+#define REG_LINK (6)
+#define REG_MULTI_SZ (7)
+#define REG_RESOURCE_LIST (8)
+#define REG_FULL_RESOURCE_DESCRIPTOR (9)
+#define REG_RESOURCE_REQUIREMENTS_LIST (10)
+#define REG_QWORD (11)
+#define REG_QWORD_LITTLE_ENDIAN (11)
+
+#define SERVICE_KERNEL_DRIVER 0x00000001
+#define SERVICE_FILE_SYSTEM_DRIVER 0x00000002
+#define SERVICE_ADAPTER 0x00000004
+#define SERVICE_RECOGNIZER_DRIVER 0x00000008
+
+#define SERVICE_DRIVER (SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER)
+
+#define SERVICE_WIN32_OWN_PROCESS 0x00000010
+#define SERVICE_WIN32_SHARE_PROCESS 0x00000020
+#define SERVICE_WIN32 (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS)
+
+#define SERVICE_INTERACTIVE_PROCESS 0x00000100
+
+#define SERVICE_TYPE_ALL (SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS)
+
+#define SERVICE_BOOT_START 0x00000000
+#define SERVICE_SYSTEM_START 0x00000001
+#define SERVICE_AUTO_START 0x00000002
+#define SERVICE_DEMAND_START 0x00000003
+#define SERVICE_DISABLED 0x00000004
+
+#define SERVICE_ERROR_IGNORE 0x00000000
+#define SERVICE_ERROR_NORMAL 0x00000001
+#define SERVICE_ERROR_SEVERE 0x00000002
+#define SERVICE_ERROR_CRITICAL 0x00000003
+
+ typedef enum _CM_SERVICE_NODE_TYPE {
+ DriverType = SERVICE_KERNEL_DRIVER,FileSystemType = SERVICE_FILE_SYSTEM_DRIVER,Win32ServiceOwnProcess = SERVICE_WIN32_OWN_PROCESS,
+ Win32ServiceShareProcess = SERVICE_WIN32_SHARE_PROCESS,AdapterType = SERVICE_ADAPTER,RecognizerType = SERVICE_RECOGNIZER_DRIVER
+ } SERVICE_NODE_TYPE;
+
+ typedef enum _CM_SERVICE_LOAD_TYPE {
+ BootLoad = SERVICE_BOOT_START,SystemLoad = SERVICE_SYSTEM_START,AutoLoad = SERVICE_AUTO_START,DemandLoad = SERVICE_DEMAND_START,
+ DisableLoad = SERVICE_DISABLED
+ } SERVICE_LOAD_TYPE;
+
+ typedef enum _CM_ERROR_CONTROL_TYPE {
+ IgnoreError = SERVICE_ERROR_IGNORE,NormalError = SERVICE_ERROR_NORMAL,SevereError = SERVICE_ERROR_SEVERE,CriticalError = SERVICE_ERROR_CRITICAL
+ } SERVICE_ERROR_TYPE;
+
+#define TAPE_ERASE_SHORT 0L
+#define TAPE_ERASE_LONG 1L
+
+ typedef struct _TAPE_ERASE {
+ DWORD Type;
+ BOOLEAN Immediate;
+ } TAPE_ERASE,*PTAPE_ERASE;
+
+#define TAPE_LOAD 0L
+#define TAPE_UNLOAD 1L
+#define TAPE_TENSION 2L
+#define TAPE_LOCK 3L
+#define TAPE_UNLOCK 4L
+#define TAPE_FORMAT 5L
+
+ typedef struct _TAPE_PREPARE {
+ DWORD Operation;
+ BOOLEAN Immediate;
+ } TAPE_PREPARE,*PTAPE_PREPARE;
+
+#define TAPE_SETMARKS 0L
+#define TAPE_FILEMARKS 1L
+#define TAPE_SHORT_FILEMARKS 2L
+#define TAPE_LONG_FILEMARKS 3L
+
+ typedef struct _TAPE_WRITE_MARKS {
+ DWORD Type;
+ DWORD Count;
+ BOOLEAN Immediate;
+ } TAPE_WRITE_MARKS,*PTAPE_WRITE_MARKS;
+
+#define TAPE_ABSOLUTE_POSITION 0L
+#define TAPE_LOGICAL_POSITION 1L
+#define TAPE_PSEUDO_LOGICAL_POSITION 2L
+
+ typedef struct _TAPE_GET_POSITION {
+ DWORD Type;
+ DWORD Partition;
+ LARGE_INTEGER Offset;
+ } TAPE_GET_POSITION,*PTAPE_GET_POSITION;
+
+#define TAPE_REWIND 0L
+#define TAPE_ABSOLUTE_BLOCK 1L
+#define TAPE_LOGICAL_BLOCK 2L
+#define TAPE_PSEUDO_LOGICAL_BLOCK 3L
+#define TAPE_SPACE_END_OF_DATA 4L
+#define TAPE_SPACE_RELATIVE_BLOCKS 5L
+#define TAPE_SPACE_FILEMARKS 6L
+#define TAPE_SPACE_SEQUENTIAL_FMKS 7L
+#define TAPE_SPACE_SETMARKS 8L
+#define TAPE_SPACE_SEQUENTIAL_SMKS 9L
+
+ typedef struct _TAPE_SET_POSITION {
+ DWORD Method;
+ DWORD Partition;
+ LARGE_INTEGER Offset;
+ BOOLEAN Immediate;
+ } TAPE_SET_POSITION,*PTAPE_SET_POSITION;
+
+#define TAPE_DRIVE_FIXED 0x00000001
+#define TAPE_DRIVE_SELECT 0x00000002
+#define TAPE_DRIVE_INITIATOR 0x00000004
+
+#define TAPE_DRIVE_ERASE_SHORT 0x00000010
+#define TAPE_DRIVE_ERASE_LONG 0x00000020
+#define TAPE_DRIVE_ERASE_BOP_ONLY 0x00000040
+#define TAPE_DRIVE_ERASE_IMMEDIATE 0x00000080
+
+#define TAPE_DRIVE_TAPE_CAPACITY 0x00000100
+#define TAPE_DRIVE_TAPE_REMAINING 0x00000200
+#define TAPE_DRIVE_FIXED_BLOCK 0x00000400
+#define TAPE_DRIVE_VARIABLE_BLOCK 0x00000800
+
+#define TAPE_DRIVE_WRITE_PROTECT 0x00001000
+#define TAPE_DRIVE_EOT_WZ_SIZE 0x00002000
+
+#define TAPE_DRIVE_ECC 0x00010000
+#define TAPE_DRIVE_COMPRESSION 0x00020000
+#define TAPE_DRIVE_PADDING 0x00040000
+#define TAPE_DRIVE_REPORT_SMKS 0x00080000
+
+#define TAPE_DRIVE_GET_ABSOLUTE_BLK 0x00100000
+#define TAPE_DRIVE_GET_LOGICAL_BLK 0x00200000
+#define TAPE_DRIVE_SET_EOT_WZ_SIZE 0x00400000
+
+#define TAPE_DRIVE_EJECT_MEDIA 0x01000000
+#define TAPE_DRIVE_CLEAN_REQUESTS 0x02000000
+#define TAPE_DRIVE_SET_CMP_BOP_ONLY 0x04000000
+
+#define TAPE_DRIVE_RESERVED_BIT 0x80000000
+
+#define TAPE_DRIVE_LOAD_UNLOAD 0x80000001
+#define TAPE_DRIVE_TENSION 0x80000002
+#define TAPE_DRIVE_LOCK_UNLOCK 0x80000004
+#define TAPE_DRIVE_REWIND_IMMEDIATE 0x80000008
+
+#define TAPE_DRIVE_SET_BLOCK_SIZE 0x80000010
+#define TAPE_DRIVE_LOAD_UNLD_IMMED 0x80000020
+#define TAPE_DRIVE_TENSION_IMMED 0x80000040
+#define TAPE_DRIVE_LOCK_UNLK_IMMED 0x80000080
+
+#define TAPE_DRIVE_SET_ECC 0x80000100
+#define TAPE_DRIVE_SET_COMPRESSION 0x80000200
+#define TAPE_DRIVE_SET_PADDING 0x80000400
+#define TAPE_DRIVE_SET_REPORT_SMKS 0x80000800
+
+#define TAPE_DRIVE_ABSOLUTE_BLK 0x80001000
+#define TAPE_DRIVE_ABS_BLK_IMMED 0x80002000
+#define TAPE_DRIVE_LOGICAL_BLK 0x80004000
+#define TAPE_DRIVE_LOG_BLK_IMMED 0x80008000
+
+#define TAPE_DRIVE_END_OF_DATA 0x80010000
+#define TAPE_DRIVE_RELATIVE_BLKS 0x80020000
+#define TAPE_DRIVE_FILEMARKS 0x80040000
+#define TAPE_DRIVE_SEQUENTIAL_FMKS 0x80080000
+
+#define TAPE_DRIVE_SETMARKS 0x80100000
+#define TAPE_DRIVE_SEQUENTIAL_SMKS 0x80200000
+#define TAPE_DRIVE_REVERSE_POSITION 0x80400000
+#define TAPE_DRIVE_SPACE_IMMEDIATE 0x80800000
+
+#define TAPE_DRIVE_WRITE_SETMARKS 0x81000000
+#define TAPE_DRIVE_WRITE_FILEMARKS 0x82000000
+#define TAPE_DRIVE_WRITE_SHORT_FMKS 0x84000000
+#define TAPE_DRIVE_WRITE_LONG_FMKS 0x88000000
+
+#define TAPE_DRIVE_WRITE_MARK_IMMED 0x90000000
+#define TAPE_DRIVE_FORMAT 0xA0000000
+#define TAPE_DRIVE_FORMAT_IMMEDIATE 0xC0000000
+#define TAPE_DRIVE_HIGH_FEATURES 0x80000000
+
+ typedef struct _TAPE_GET_DRIVE_PARAMETERS {
+ BOOLEAN ECC;
+ BOOLEAN Compression;
+ BOOLEAN DataPadding;
+ BOOLEAN ReportSetmarks;
+ DWORD DefaultBlockSize;
+ DWORD MaximumBlockSize;
+ DWORD MinimumBlockSize;
+ DWORD MaximumPartitionCount;
+ DWORD FeaturesLow;
+ DWORD FeaturesHigh;
+ DWORD EOTWarningZoneSize;
+ } TAPE_GET_DRIVE_PARAMETERS,*PTAPE_GET_DRIVE_PARAMETERS;
+
+ typedef struct _TAPE_SET_DRIVE_PARAMETERS {
+ BOOLEAN ECC;
+ BOOLEAN Compression;
+ BOOLEAN DataPadding;
+ BOOLEAN ReportSetmarks;
+ DWORD EOTWarningZoneSize;
+ } TAPE_SET_DRIVE_PARAMETERS,*PTAPE_SET_DRIVE_PARAMETERS;
+
+ typedef struct _TAPE_GET_MEDIA_PARAMETERS {
+ LARGE_INTEGER Capacity;
+ LARGE_INTEGER Remaining;
+ DWORD BlockSize;
+ DWORD PartitionCount;
+ BOOLEAN WriteProtected;
+ } TAPE_GET_MEDIA_PARAMETERS,*PTAPE_GET_MEDIA_PARAMETERS;
+
+ typedef struct _TAPE_SET_MEDIA_PARAMETERS {
+ DWORD BlockSize;
+ } TAPE_SET_MEDIA_PARAMETERS,*PTAPE_SET_MEDIA_PARAMETERS;
+
+#define TAPE_FIXED_PARTITIONS 0L
+#define TAPE_SELECT_PARTITIONS 1L
+#define TAPE_INITIATOR_PARTITIONS 2L
+
+ typedef struct _TAPE_CREATE_PARTITION {
+ DWORD Method;
+ DWORD Count;
+ DWORD Size;
+ } TAPE_CREATE_PARTITION,*PTAPE_CREATE_PARTITION;
+
+#define TAPE_QUERY_DRIVE_PARAMETERS 0L
+#define TAPE_QUERY_MEDIA_CAPACITY 1L
+#define TAPE_CHECK_FOR_DRIVE_PROBLEM 2L
+#define TAPE_QUERY_IO_ERROR_DATA 3L
+#define TAPE_QUERY_DEVICE_ERROR_DATA 4L
+
+ typedef struct _TAPE_WMI_OPERATIONS {
+ DWORD Method;
+ DWORD DataBufferSize;
+ PVOID DataBuffer;
+ } TAPE_WMI_OPERATIONS,*PTAPE_WMI_OPERATIONS;
+
+ typedef enum _TAPE_DRIVE_PROBLEM_TYPE {
+ TapeDriveProblemNone,TapeDriveReadWriteWarning,TapeDriveReadWriteError,TapeDriveReadWarning,TapeDriveWriteWarning,TapeDriveReadError,TapeDriveWriteError,TapeDriveHardwareError,TapeDriveUnsupportedMedia,TapeDriveScsiConnectionError,TapeDriveTimetoClean,TapeDriveCleanDriveNow,TapeDriveMediaLifeExpired,TapeDriveSnappedTape
+ } TAPE_DRIVE_PROBLEM_TYPE;
+
+#if defined(__x86_64)
+ __CRT_INLINE struct _TEB *NtCurrentTeb(VOID) { return (struct _TEB *)__readgsqword(FIELD_OFFSET(NT_TIB,Self)); }
+ __CRT_INLINE PVOID GetCurrentFiber(VOID) { return(PVOID)__readgsqword(FIELD_OFFSET(NT_TIB,FiberData)); }
+ __CRT_INLINE PVOID GetFiberData(VOID) {
+ return *(PVOID *)GetCurrentFiber();
+ }
+#endif
+
+#if(defined(_X86_) && !defined(__x86_64))
+#define PcTeb 0x18
+ __CRT_INLINE struct _TEB *NtCurrentTeb(void) {
+ struct _TEB *ret;
+ __asm__ volatile ("movl %%fs:0x18,%0"
+ : "=r" (ret));
+ return ret;
+ }
+#endif
+
+#define ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION (1)
+#define ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION (2)
+#define ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION (3)
+#define ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION (4)
+#define ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION (5)
+#define ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION (6)
+#define ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION (7)
+#define ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE (8)
+#define ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES (9)
+#define ACTIVATION_CONTEXT_SECTION_APPLICATION_SETTINGS (10)
+
+#ifdef __cplusplus
+ }
+#endif
+#endif
diff --git a/win32/include/winapi/winreg.h b/win32/include/winapi/winreg.h
new file mode 100644
index 0000000..f158d28
--- /dev/null
+++ b/win32/include/winapi/winreg.h
@@ -0,0 +1,272 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _WINREG_
+#define _WINREG_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WINVER
+#define WINVER 0x0502
+#endif
+
+#define RRF_RT_REG_NONE 0x00000001
+#define RRF_RT_REG_SZ 0x00000002
+#define RRF_RT_REG_EXPAND_SZ 0x00000004
+#define RRF_RT_REG_BINARY 0x00000008
+#define RRF_RT_REG_DWORD 0x00000010
+#define RRF_RT_REG_MULTI_SZ 0x00000020
+#define RRF_RT_REG_QWORD 0x00000040
+
+#define RRF_RT_DWORD (RRF_RT_REG_BINARY | RRF_RT_REG_DWORD)
+#define RRF_RT_QWORD (RRF_RT_REG_BINARY | RRF_RT_REG_QWORD)
+#define RRF_RT_ANY 0x0000ffff
+
+#define RRF_NOEXPAND 0x10000000
+#define RRF_ZEROONFAILURE 0x20000000
+
+ typedef ACCESS_MASK REGSAM;
+
+#define HKEY_CLASSES_ROOT ((HKEY) (ULONG_PTR)((LONG)0x80000000))
+#define HKEY_CURRENT_USER ((HKEY) (ULONG_PTR)((LONG)0x80000001))
+#define HKEY_LOCAL_MACHINE ((HKEY) (ULONG_PTR)((LONG)0x80000002))
+#define HKEY_USERS ((HKEY) (ULONG_PTR)((LONG)0x80000003))
+#define HKEY_PERFORMANCE_DATA ((HKEY) (ULONG_PTR)((LONG)0x80000004))
+#define HKEY_PERFORMANCE_TEXT ((HKEY) (ULONG_PTR)((LONG)0x80000050))
+#define HKEY_PERFORMANCE_NLSTEXT ((HKEY) (ULONG_PTR)((LONG)0x80000060))
+#define HKEY_CURRENT_CONFIG ((HKEY) (ULONG_PTR)((LONG)0x80000005))
+#define HKEY_DYN_DATA ((HKEY) (ULONG_PTR)((LONG)0x80000006))
+
+#define REG_SECURE_CONNECTION 1
+
+#ifndef _PROVIDER_STRUCTS_DEFINED
+#define _PROVIDER_STRUCTS_DEFINED
+
+#define PROVIDER_KEEPS_VALUE_LENGTH 0x1
+ struct val_context {
+ int valuelen;
+ LPVOID value_context;
+ LPVOID val_buff_ptr;
+ };
+
+ typedef struct val_context *PVALCONTEXT;
+
+ typedef struct pvalueA {
+ LPSTR pv_valuename;
+ int pv_valuelen;
+ LPVOID pv_value_context;
+ DWORD pv_type;
+ }PVALUEA,*PPVALUEA;
+
+ typedef struct pvalueW {
+ LPWSTR pv_valuename;
+ int pv_valuelen;
+ LPVOID pv_value_context;
+ DWORD pv_type;
+ }PVALUEW,*PPVALUEW;
+
+#ifdef UNICODE
+ typedef PVALUEW PVALUE;
+ typedef PPVALUEW PPVALUE;
+#else
+ typedef PVALUEA PVALUE;
+ typedef PPVALUEA PPVALUE;
+#endif
+
+ typedef DWORD __cdecl QUERYHANDLER(LPVOID keycontext,PVALCONTEXT val_list,DWORD num_vals,LPVOID outputbuffer,DWORD *total_outlen,DWORD input_blen);
+
+ typedef QUERYHANDLER *PQUERYHANDLER;
+
+ typedef struct provider_info {
+ PQUERYHANDLER pi_R0_1val;
+ PQUERYHANDLER pi_R0_allvals;
+ PQUERYHANDLER pi_R3_1val;
+ PQUERYHANDLER pi_R3_allvals;
+ DWORD pi_flags;
+ LPVOID pi_key_context;
+ } REG_PROVIDER;
+
+ typedef struct provider_info *PPROVIDER;
+
+ typedef struct value_entA {
+ LPSTR ve_valuename;
+ DWORD ve_valuelen;
+ DWORD_PTR ve_valueptr;
+ DWORD ve_type;
+ } VALENTA,*PVALENTA;
+
+ typedef struct value_entW {
+ LPWSTR ve_valuename;
+ DWORD ve_valuelen;
+ DWORD_PTR ve_valueptr;
+ DWORD ve_type;
+ } VALENTW,*PVALENTW;
+
+#ifdef UNICODE
+ typedef VALENTW VALENT;
+ typedef PVALENTW PVALENT;
+#else
+ typedef VALENTA VALENT;
+ typedef PVALENTA PVALENT;
+#endif
+#endif
+
+#define WIN31_CLASS NULL
+
+#ifdef UNICODE
+#define RegConnectRegistry RegConnectRegistryW
+#define RegConnectRegistryEx RegConnectRegistryExW
+#define RegCreateKey RegCreateKeyW
+#define RegCreateKeyEx RegCreateKeyExW
+#define RegDeleteKey RegDeleteKeyW
+#define RegDeleteKeyEx RegDeleteKeyExW
+#define RegDeleteValue RegDeleteValueW
+#define RegEnumKey RegEnumKeyW
+#define RegEnumKeyEx RegEnumKeyExW
+#define RegEnumValue RegEnumValueW
+#define RegLoadKey RegLoadKeyW
+#define RegOpenKey RegOpenKeyW
+#define RegOpenKeyEx RegOpenKeyExW
+#define RegQueryInfoKey RegQueryInfoKeyW
+#define RegQueryValue RegQueryValueW
+#define RegQueryMultipleValues RegQueryMultipleValuesW
+#define RegQueryValueEx RegQueryValueExW
+#define RegReplaceKey RegReplaceKeyW
+#define RegRestoreKey RegRestoreKeyW
+#define RegSaveKey RegSaveKeyW
+#define RegSetValue RegSetValueW
+#define RegSetValueEx RegSetValueExW
+#define RegUnLoadKey RegUnLoadKeyW
+#define RegGetValue RegGetValueW
+#define InitiateSystemShutdown InitiateSystemShutdownW
+#define AbortSystemShutdown AbortSystemShutdownW
+#else
+#define RegConnectRegistry RegConnectRegistryA
+#define RegConnectRegistryEx RegConnectRegistryExA
+#define RegCreateKey RegCreateKeyA
+#define RegCreateKeyEx RegCreateKeyExA
+#define RegDeleteKey RegDeleteKeyA
+#define RegDeleteKeyEx RegDeleteKeyExA
+#define RegDeleteValue RegDeleteValueA
+#define RegEnumKey RegEnumKeyA
+#define RegEnumKeyEx RegEnumKeyExA
+#define RegEnumValue RegEnumValueA
+#define RegLoadKey RegLoadKeyA
+#define RegOpenKey RegOpenKeyA
+#define RegOpenKeyEx RegOpenKeyExA
+#define RegQueryInfoKey RegQueryInfoKeyA
+#define RegQueryValue RegQueryValueA
+#define RegQueryMultipleValues RegQueryMultipleValuesA
+#define RegQueryValueEx RegQueryValueExA
+#define RegReplaceKey RegReplaceKeyA
+#define RegRestoreKey RegRestoreKeyA
+#define RegSaveKey RegSaveKeyA
+#define RegSetValue RegSetValueA
+#define RegSetValueEx RegSetValueExA
+#define RegUnLoadKey RegUnLoadKeyA
+#define RegGetValue RegGetValueA
+#define InitiateSystemShutdown InitiateSystemShutdownA
+#define AbortSystemShutdown AbortSystemShutdownA
+#endif
+
+ WINADVAPI LONG WINAPI RegCloseKey(HKEY hKey);
+ WINADVAPI LONG WINAPI RegOverridePredefKey(HKEY hKey,HKEY hNewHKey);
+ WINADVAPI LONG WINAPI RegOpenUserClassesRoot(HANDLE hToken,DWORD dwOptions,REGSAM samDesired,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegOpenCurrentUser(REGSAM samDesired,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegDisablePredefinedCache();
+ WINADVAPI LONG WINAPI RegConnectRegistryA(LPCSTR lpMachineName,HKEY hKey,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegConnectRegistryW(LPCWSTR lpMachineName,HKEY hKey,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegConnectRegistryExA(LPCSTR lpMachineName,HKEY hKey,ULONG Flags,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegConnectRegistryExW(LPCWSTR lpMachineName,HKEY hKey,ULONG Flags,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegCreateKeyA(HKEY hKey,LPCSTR lpSubKey,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegCreateKeyW(HKEY hKey,LPCWSTR lpSubKey,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegCreateKeyExA(HKEY hKey,LPCSTR lpSubKey,DWORD Reserved,LPSTR lpClass,DWORD dwOptions,REGSAM samDesired,LPSECURITY_ATTRIBUTES lpSecurityAttributes,PHKEY phkResult,LPDWORD lpdwDisposition);
+ WINADVAPI LONG WINAPI RegCreateKeyExW(HKEY hKey,LPCWSTR lpSubKey,DWORD Reserved,LPWSTR lpClass,DWORD dwOptions,REGSAM samDesired,LPSECURITY_ATTRIBUTES lpSecurityAttributes,PHKEY phkResult,LPDWORD lpdwDisposition);
+ WINADVAPI LONG WINAPI RegDeleteKeyA(HKEY hKey,LPCSTR lpSubKey);
+ WINADVAPI LONG WINAPI RegDeleteKeyW(HKEY hKey,LPCWSTR lpSubKey);
+ WINADVAPI LONG WINAPI RegDeleteKeyExA(HKEY hKey,LPCSTR lpSubKey,REGSAM samDesired,DWORD Reserved);
+ WINADVAPI LONG WINAPI RegDeleteKeyExW(HKEY hKey,LPCWSTR lpSubKey,REGSAM samDesired,DWORD Reserved);
+ WINADVAPI LONG WINAPI RegDisableReflectionKey(HKEY hBase);
+ WINADVAPI LONG WINAPI RegEnableReflectionKey(HKEY hBase);
+ WINADVAPI LONG WINAPI RegQueryReflectionKey(HKEY hBase,WINBOOL *bIsReflectionDisabled);
+ WINADVAPI LONG WINAPI RegDeleteValueA(HKEY hKey,LPCSTR lpValueName);
+ WINADVAPI LONG WINAPI RegDeleteValueW(HKEY hKey,LPCWSTR lpValueName);
+ WINADVAPI LONG WINAPI RegEnumKeyA(HKEY hKey,DWORD dwIndex,LPSTR lpName,DWORD cchName);
+ WINADVAPI LONG WINAPI RegEnumKeyW(HKEY hKey,DWORD dwIndex,LPWSTR lpName,DWORD cchName);
+ WINADVAPI LONG WINAPI RegEnumKeyExA(HKEY hKey,DWORD dwIndex,LPSTR lpName,LPDWORD lpcchName,LPDWORD lpReserved,LPSTR lpClass,LPDWORD lpcchClass,PFILETIME lpftLastWriteTime);
+ WINADVAPI LONG WINAPI RegEnumKeyExW(HKEY hKey,DWORD dwIndex,LPWSTR lpName,LPDWORD lpcchName,LPDWORD lpReserved,LPWSTR lpClass,LPDWORD lpcchClass,PFILETIME lpftLastWriteTime);
+ WINADVAPI LONG WINAPI RegEnumValueA(HKEY hKey,DWORD dwIndex,LPSTR lpValueName,LPDWORD lpcchValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData);
+ WINADVAPI LONG WINAPI RegEnumValueW(HKEY hKey,DWORD dwIndex,LPWSTR lpValueName,LPDWORD lpcchValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData);
+ WINADVAPI LONG WINAPI RegFlushKey(HKEY hKey);
+ WINADVAPI LONG WINAPI RegGetKeySecurity(HKEY hKey,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor,LPDWORD lpcbSecurityDescriptor);
+ WINADVAPI LONG WINAPI RegLoadKeyA(HKEY hKey,LPCSTR lpSubKey,LPCSTR lpFile);
+ WINADVAPI LONG WINAPI RegLoadKeyW(HKEY hKey,LPCWSTR lpSubKey,LPCWSTR lpFile);
+ WINADVAPI LONG WINAPI RegNotifyChangeKeyValue(HKEY hKey,WINBOOL bWatchSubtree,DWORD dwNotifyFilter,HANDLE hEvent,WINBOOL fAsynchronous);
+ WINADVAPI LONG WINAPI RegOpenKeyA(HKEY hKey,LPCSTR lpSubKey,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegOpenKeyW(HKEY hKey,LPCWSTR lpSubKey,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegOpenKeyExA(HKEY hKey,LPCSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegOpenKeyExW(HKEY hKey,LPCWSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult);
+ WINADVAPI LONG WINAPI RegQueryInfoKeyA(HKEY hKey,LPSTR lpClass,LPDWORD lpcchClass,LPDWORD lpReserved,LPDWORD lpcSubKeys,LPDWORD lpcbMaxSubKeyLen,LPDWORD lpcbMaxClassLen,LPDWORD lpcValues,LPDWORD lpcbMaxValueNameLen,LPDWORD lpcbMaxValueLen,LPDWORD lpcbSecurityDescriptor,PFILETIME lpftLastWriteTime);
+ WINADVAPI LONG WINAPI RegQueryInfoKeyW(HKEY hKey,LPWSTR lpClass,LPDWORD lpcchClass,LPDWORD lpReserved,LPDWORD lpcSubKeys,LPDWORD lpcbMaxSubKeyLen,LPDWORD lpcbMaxClassLen,LPDWORD lpcValues,LPDWORD lpcbMaxValueNameLen,LPDWORD lpcbMaxValueLen,LPDWORD lpcbSecurityDescriptor,PFILETIME lpftLastWriteTime);
+ WINADVAPI LONG WINAPI RegQueryValueA(HKEY hKey,LPCSTR lpSubKey,LPSTR lpData,PLONG lpcbData);
+ WINADVAPI LONG WINAPI RegQueryValueW(HKEY hKey,LPCWSTR lpSubKey,LPWSTR lpData,PLONG lpcbData);
+ WINADVAPI LONG WINAPI RegQueryMultipleValuesA(HKEY hKey,PVALENTA val_list,DWORD num_vals,LPSTR lpValueBuf,LPDWORD ldwTotsize);
+ WINADVAPI LONG WINAPI RegQueryMultipleValuesW(HKEY hKey,PVALENTW val_list,DWORD num_vals,LPWSTR lpValueBuf,LPDWORD ldwTotsize);
+ WINADVAPI LONG WINAPI RegQueryValueExA(HKEY hKey,LPCSTR lpValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData);
+ WINADVAPI LONG WINAPI RegQueryValueExW(HKEY hKey,LPCWSTR lpValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData);
+ WINADVAPI LONG WINAPI RegReplaceKeyA(HKEY hKey,LPCSTR lpSubKey,LPCSTR lpNewFile,LPCSTR lpOldFile);
+ WINADVAPI LONG WINAPI RegReplaceKeyW(HKEY hKey,LPCWSTR lpSubKey,LPCWSTR lpNewFile,LPCWSTR lpOldFile);
+ WINADVAPI LONG WINAPI RegRestoreKeyA(HKEY hKey,LPCSTR lpFile,DWORD dwFlags);
+ WINADVAPI LONG WINAPI RegRestoreKeyW(HKEY hKey,LPCWSTR lpFile,DWORD dwFlags);
+ WINADVAPI LONG WINAPI RegSaveKeyA(HKEY hKey,LPCSTR lpFile,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ WINADVAPI LONG WINAPI RegSaveKeyW(HKEY hKey,LPCWSTR lpFile,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
+ WINADVAPI LONG WINAPI RegSetKeySecurity(HKEY hKey,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor);
+ WINADVAPI LONG WINAPI RegSetValueA(HKEY hKey,LPCSTR lpSubKey,DWORD dwType,LPCSTR lpData,DWORD cbData);
+ WINADVAPI LONG WINAPI RegSetValueW(HKEY hKey,LPCWSTR lpSubKey,DWORD dwType,LPCWSTR lpData,DWORD cbData);
+ WINADVAPI LONG WINAPI RegSetValueExA(HKEY hKey,LPCSTR lpValueName,DWORD Reserved,DWORD dwType,CONST BYTE *lpData,DWORD cbData);
+ WINADVAPI LONG WINAPI RegSetValueExW(HKEY hKey,LPCWSTR lpValueName,DWORD Reserved,DWORD dwType,CONST BYTE *lpData,DWORD cbData);
+ WINADVAPI LONG WINAPI RegUnLoadKeyA(HKEY hKey,LPCSTR lpSubKey);
+ WINADVAPI LONG WINAPI RegUnLoadKeyW(HKEY hKey,LPCWSTR lpSubKey);
+ WINADVAPI LONG WINAPI RegGetValueA(HKEY hkey,LPCSTR lpSubKey,LPCSTR lpValue,DWORD dwFlags,LPDWORD pdwType,PVOID pvData,LPDWORD pcbData);
+ WINADVAPI LONG WINAPI RegGetValueW(HKEY hkey,LPCWSTR lpSubKey,LPCWSTR lpValue,DWORD dwFlags,LPDWORD pdwType,PVOID pvData,LPDWORD pcbData);
+ WINADVAPI WINBOOL WINAPI InitiateSystemShutdownA(LPSTR lpMachineName,LPSTR lpMessage,DWORD dwTimeout,WINBOOL bForceAppsClosed,WINBOOL bRebootAfterShutdown);
+ WINADVAPI WINBOOL WINAPI InitiateSystemShutdownW(LPWSTR lpMachineName,LPWSTR lpMessage,DWORD dwTimeout,WINBOOL bForceAppsClosed,WINBOOL bRebootAfterShutdown);
+ WINADVAPI WINBOOL WINAPI AbortSystemShutdownA(LPSTR lpMachineName);
+ WINADVAPI WINBOOL WINAPI AbortSystemShutdownW(LPWSTR lpMachineName);
+
+//gr #include <reason.h>
+
+#define REASON_SWINSTALL SHTDN_REASON_MAJOR_SOFTWARE|SHTDN_REASON_MINOR_INSTALLATION
+#define REASON_HWINSTALL SHTDN_REASON_MAJOR_HARDWARE|SHTDN_REASON_MINOR_INSTALLATION
+#define REASON_SERVICEHANG SHTDN_REASON_MAJOR_SOFTWARE|SHTDN_REASON_MINOR_HUNG
+#define REASON_UNSTABLE SHTDN_REASON_MAJOR_SYSTEM|SHTDN_REASON_MINOR_UNSTABLE
+#define REASON_SWHWRECONF SHTDN_REASON_MAJOR_SOFTWARE|SHTDN_REASON_MINOR_RECONFIG
+#define REASON_OTHER SHTDN_REASON_MAJOR_OTHER|SHTDN_REASON_MINOR_OTHER
+#define REASON_UNKNOWN SHTDN_REASON_UNKNOWN
+#define REASON_LEGACY_API SHTDN_REASON_LEGACY_API
+#define REASON_PLANNED_FLAG SHTDN_REASON_FLAG_PLANNED
+
+#define MAX_SHUTDOWN_TIMEOUT (10*365*24*60*60)
+
+#ifdef UNICODE
+#define InitiateSystemShutdownEx InitiateSystemShutdownExW
+#define RegSaveKeyEx RegSaveKeyExW
+#else
+#define InitiateSystemShutdownEx InitiateSystemShutdownExA
+#define RegSaveKeyEx RegSaveKeyExA
+#endif
+
+ WINADVAPI WINBOOL WINAPI InitiateSystemShutdownExA(LPSTR lpMachineName,LPSTR lpMessage,DWORD dwTimeout,WINBOOL bForceAppsClosed,WINBOOL bRebootAfterShutdown,DWORD dwReason);
+ WINADVAPI WINBOOL WINAPI InitiateSystemShutdownExW(LPWSTR lpMachineName,LPWSTR lpMessage,DWORD dwTimeout,WINBOOL bForceAppsClosed,WINBOOL bRebootAfterShutdown,DWORD dwReason);
+ WINADVAPI LONG WINAPI RegSaveKeyExA(HKEY hKey,LPCSTR lpFile,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD Flags);
+ WINADVAPI LONG WINAPI RegSaveKeyExW(HKEY hKey,LPCWSTR lpFile,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD Flags);
+ WINADVAPI LONG WINAPI Wow64Win32ApiEntry (DWORD dwFuncNumber,DWORD dwFlag,DWORD dwRes);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/include/winapi/winuser.h b/win32/include/winapi/winuser.h
new file mode 100644
index 0000000..4cd9ffb
--- /dev/null
+++ b/win32/include/winapi/winuser.h
@@ -0,0 +1,5651 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _WINUSER_
+#define _WINUSER_
+
+#define WINUSERAPI DECLSPEC_IMPORT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WINVER
+#define WINVER 0x0502
+#endif
+
+#include <stdarg.h>
+
+#ifndef NOUSER
+ typedef HANDLE HDWP;
+ typedef VOID MENUTEMPLATEA;
+ typedef VOID MENUTEMPLATEW;
+ typedef PVOID LPMENUTEMPLATEA;
+ typedef PVOID LPMENUTEMPLATEW;
+
+#ifdef UNICODE
+ typedef MENUTEMPLATEW MENUTEMPLATE;
+ typedef LPMENUTEMPLATEW LPMENUTEMPLATE;
+#else
+ typedef MENUTEMPLATEA MENUTEMPLATE;
+ typedef LPMENUTEMPLATEA LPMENUTEMPLATE;
+#endif
+
+ typedef LRESULT (CALLBACK *WNDPROC)(HWND,UINT,WPARAM,LPARAM);
+ typedef INT_PTR (CALLBACK *DLGPROC)(HWND,UINT,WPARAM,LPARAM);
+ typedef VOID (CALLBACK *TIMERPROC)(HWND,UINT,UINT_PTR,DWORD);
+ typedef WINBOOL (CALLBACK *GRAYSTRINGPROC)(HDC,LPARAM,int);
+ typedef WINBOOL (CALLBACK *WNDENUMPROC)(HWND,LPARAM);
+ typedef LRESULT (CALLBACK *HOOKPROC)(int code,WPARAM wParam,LPARAM lParam);
+ typedef VOID (CALLBACK *SENDASYNCPROC)(HWND,UINT,ULONG_PTR,LRESULT);
+ typedef WINBOOL (CALLBACK *PROPENUMPROCA)(HWND,LPCSTR,HANDLE);
+ typedef WINBOOL (CALLBACK *PROPENUMPROCW)(HWND,LPCWSTR,HANDLE);
+ typedef WINBOOL (CALLBACK *PROPENUMPROCEXA)(HWND,LPSTR,HANDLE,ULONG_PTR);
+ typedef WINBOOL (CALLBACK *PROPENUMPROCEXW)(HWND,LPWSTR,HANDLE,ULONG_PTR);
+ typedef int (CALLBACK *EDITWORDBREAKPROCA)(LPSTR lpch,int ichCurrent,int cch,int code);
+ typedef int (CALLBACK *EDITWORDBREAKPROCW)(LPWSTR lpch,int ichCurrent,int cch,int code);
+ typedef WINBOOL (CALLBACK *DRAWSTATEPROC)(HDC hdc,LPARAM lData,WPARAM wData,int cx,int cy);
+
+#ifdef UNICODE
+ typedef PROPENUMPROCW PROPENUMPROC;
+ typedef PROPENUMPROCEXW PROPENUMPROCEX;
+ typedef EDITWORDBREAKPROCW EDITWORDBREAKPROC;
+#else
+ typedef PROPENUMPROCA PROPENUMPROC;
+ typedef PROPENUMPROCEXA PROPENUMPROCEX;
+ typedef EDITWORDBREAKPROCA EDITWORDBREAKPROC;
+#endif
+
+ typedef WINBOOL (CALLBACK *NAMEENUMPROCA)(LPSTR,LPARAM);
+ typedef WINBOOL (CALLBACK *NAMEENUMPROCW)(LPWSTR,LPARAM);
+ typedef NAMEENUMPROCA WINSTAENUMPROCA;
+ typedef NAMEENUMPROCA DESKTOPENUMPROCA;
+ typedef NAMEENUMPROCW WINSTAENUMPROCW;
+ typedef NAMEENUMPROCW DESKTOPENUMPROCW;
+
+#ifdef UNICODE
+ typedef WINSTAENUMPROCW WINSTAENUMPROC;
+ typedef DESKTOPENUMPROCW DESKTOPENUMPROC;
+#else
+ typedef WINSTAENUMPROCA WINSTAENUMPROC;
+ typedef DESKTOPENUMPROCA DESKTOPENUMPROC;
+#endif
+
+#define IS_INTRESOURCE(_r) ((((ULONG_PTR)(_r)) >> 16)==0)
+#define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
+#define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))
+#ifdef UNICODE
+#define MAKEINTRESOURCE MAKEINTRESOURCEW
+#else
+#define MAKEINTRESOURCE MAKEINTRESOURCEA
+#endif
+
+#ifndef NORESOURCE
+
+#define RT_CURSOR MAKEINTRESOURCE(1)
+#define RT_BITMAP MAKEINTRESOURCE(2)
+#define RT_ICON MAKEINTRESOURCE(3)
+#define RT_MENU MAKEINTRESOURCE(4)
+#define RT_DIALOG MAKEINTRESOURCE(5)
+#define RT_STRING MAKEINTRESOURCE(6)
+#define RT_FONTDIR MAKEINTRESOURCE(7)
+#define RT_FONT MAKEINTRESOURCE(8)
+#define RT_ACCELERATOR MAKEINTRESOURCE(9)
+#define RT_RCDATA MAKEINTRESOURCE(10)
+#define RT_MESSAGETABLE MAKEINTRESOURCE(11)
+
+#define DIFFERENCE 11
+#define RT_GROUP_CURSOR MAKEINTRESOURCE((ULONG_PTR)RT_CURSOR + DIFFERENCE)
+#define RT_GROUP_ICON MAKEINTRESOURCE((ULONG_PTR)RT_ICON + DIFFERENCE)
+#define RT_VERSION MAKEINTRESOURCE(16)
+#define RT_DLGINCLUDE MAKEINTRESOURCE(17)
+#define RT_PLUGPLAY MAKEINTRESOURCE(19)
+#define RT_VXD MAKEINTRESOURCE(20)
+#define RT_ANICURSOR MAKEINTRESOURCE(21)
+#define RT_ANIICON MAKEINTRESOURCE(22)
+#define RT_HTML MAKEINTRESOURCE(23)
+#ifdef RC_INVOKED
+#define RT_MANIFEST 24
+#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
+#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID 2
+#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID 3
+#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID 1
+#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID 16
+#else
+#define RT_MANIFEST MAKEINTRESOURCE(24)
+#define CREATEPROCESS_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1)
+#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(2)
+#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(3)
+#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1)
+#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(16)
+#endif
+#endif
+
+#ifdef UNICODE
+#define wvsprintf wvsprintfW
+#define wsprintf wsprintfW
+#else
+#define wvsprintf wvsprintfA
+#define wsprintf wsprintfA
+#endif
+
+ WINUSERAPI int WINAPI wvsprintfA(LPSTR,LPCSTR,va_list arglist);
+ WINUSERAPI int WINAPI wvsprintfW(LPWSTR,LPCWSTR,va_list arglist);
+ WINUSERAPI int WINAPIV wsprintfA(LPSTR,LPCSTR,...);
+ WINUSERAPI int WINAPIV wsprintfW(LPWSTR,LPCWSTR,...);
+
+#define SETWALLPAPER_DEFAULT ((LPWSTR)-1)
+
+#ifndef NOSCROLL
+#define SB_HORZ 0
+#define SB_VERT 1
+#define SB_CTL 2
+#define SB_BOTH 3
+
+#define SB_LINEUP 0
+#define SB_LINELEFT 0
+#define SB_LINEDOWN 1
+#define SB_LINERIGHT 1
+#define SB_PAGEUP 2
+#define SB_PAGELEFT 2
+#define SB_PAGEDOWN 3
+#define SB_PAGERIGHT 3
+#define SB_THUMBPOSITION 4
+#define SB_THUMBTRACK 5
+#define SB_TOP 6
+#define SB_LEFT 6
+#define SB_BOTTOM 7
+#define SB_RIGHT 7
+#define SB_ENDSCROLL 8
+#endif
+
+#ifndef NOSHOWWINDOW
+#define SW_HIDE 0
+#define SW_SHOWNORMAL 1
+#define SW_NORMAL 1
+#define SW_SHOWMINIMIZED 2
+#define SW_SHOWMAXIMIZED 3
+#define SW_MAXIMIZE 3
+#define SW_SHOWNOACTIVATE 4
+#define SW_SHOW 5
+#define SW_MINIMIZE 6
+#define SW_SHOWMINNOACTIVE 7
+#define SW_SHOWNA 8
+#define SW_RESTORE 9
+#define SW_SHOWDEFAULT 10
+#define SW_FORCEMINIMIZE 11
+#define SW_MAX 11
+
+#define HIDE_WINDOW 0
+#define SHOW_OPENWINDOW 1
+#define SHOW_ICONWINDOW 2
+#define SHOW_FULLSCREEN 3
+#define SHOW_OPENNOACTIVATE 4
+
+#define SW_PARENTCLOSING 1
+#define SW_OTHERZOOM 2
+#define SW_PARENTOPENING 3
+#define SW_OTHERUNZOOM 4
+#endif
+
+#define AW_HOR_POSITIVE 0x00000001
+#define AW_HOR_NEGATIVE 0x00000002
+#define AW_VER_POSITIVE 0x00000004
+#define AW_VER_NEGATIVE 0x00000008
+#define AW_CENTER 0x00000010
+#define AW_HIDE 0x00010000
+#define AW_ACTIVATE 0x00020000
+#define AW_SLIDE 0x00040000
+#define AW_BLEND 0x00080000
+
+#define KF_EXTENDED 0x0100
+#define KF_DLGMODE 0x0800
+#define KF_MENUMODE 0x1000
+#define KF_ALTDOWN 0x2000
+#define KF_REPEAT 0x4000
+#define KF_UP 0x8000
+
+#ifndef NOVIRTUALKEYCODES
+
+#define VK_LBUTTON 0x01
+#define VK_RBUTTON 0x02
+#define VK_CANCEL 0x03
+#define VK_MBUTTON 0x04
+#define VK_XBUTTON1 0x05
+#define VK_XBUTTON2 0x06
+#define VK_BACK 0x08
+#define VK_TAB 0x09
+#define VK_CLEAR 0x0C
+#define VK_RETURN 0x0D
+#define VK_SHIFT 0x10
+#define VK_CONTROL 0x11
+#define VK_MENU 0x12
+#define VK_PAUSE 0x13
+#define VK_CAPITAL 0x14
+#define VK_KANA 0x15
+#define VK_HANGEUL 0x15
+#define VK_HANGUL 0x15
+#define VK_JUNJA 0x17
+#define VK_FINAL 0x18
+#define VK_HANJA 0x19
+#define VK_KANJI 0x19
+#define VK_ESCAPE 0x1B
+#define VK_CONVERT 0x1C
+#define VK_NONCONVERT 0x1D
+#define VK_ACCEPT 0x1E
+#define VK_MODECHANGE 0x1F
+#define VK_SPACE 0x20
+#define VK_PRIOR 0x21
+#define VK_NEXT 0x22
+#define VK_END 0x23
+#define VK_HOME 0x24
+#define VK_LEFT 0x25
+#define VK_UP 0x26
+#define VK_RIGHT 0x27
+#define VK_DOWN 0x28
+#define VK_SELECT 0x29
+#define VK_PRINT 0x2A
+#define VK_EXECUTE 0x2B
+#define VK_SNAPSHOT 0x2C
+#define VK_INSERT 0x2D
+#define VK_DELETE 0x2E
+#define VK_HELP 0x2F
+
+#define VK_LWIN 0x5B
+#define VK_RWIN 0x5C
+#define VK_APPS 0x5D
+#define VK_SLEEP 0x5F
+#define VK_NUMPAD0 0x60
+#define VK_NUMPAD1 0x61
+#define VK_NUMPAD2 0x62
+#define VK_NUMPAD3 0x63
+#define VK_NUMPAD4 0x64
+#define VK_NUMPAD5 0x65
+#define VK_NUMPAD6 0x66
+#define VK_NUMPAD7 0x67
+#define VK_NUMPAD8 0x68
+#define VK_NUMPAD9 0x69
+#define VK_MULTIPLY 0x6A
+#define VK_ADD 0x6B
+#define VK_SEPARATOR 0x6C
+#define VK_SUBTRACT 0x6D
+#define VK_DECIMAL 0x6E
+#define VK_DIVIDE 0x6F
+#define VK_F1 0x70
+#define VK_F2 0x71
+#define VK_F3 0x72
+#define VK_F4 0x73
+#define VK_F5 0x74
+#define VK_F6 0x75
+#define VK_F7 0x76
+#define VK_F8 0x77
+#define VK_F9 0x78
+#define VK_F10 0x79
+#define VK_F11 0x7A
+#define VK_F12 0x7B
+#define VK_F13 0x7C
+#define VK_F14 0x7D
+#define VK_F15 0x7E
+#define VK_F16 0x7F
+#define VK_F17 0x80
+#define VK_F18 0x81
+#define VK_F19 0x82
+#define VK_F20 0x83
+#define VK_F21 0x84
+#define VK_F22 0x85
+#define VK_F23 0x86
+#define VK_F24 0x87
+#define VK_NUMLOCK 0x90
+#define VK_SCROLL 0x91
+#define VK_OEM_NEC_EQUAL 0x92
+#define VK_OEM_FJ_JISHO 0x92
+#define VK_OEM_FJ_MASSHOU 0x93
+#define VK_OEM_FJ_TOUROKU 0x94
+#define VK_OEM_FJ_LOYA 0x95
+#define VK_OEM_FJ_ROYA 0x96
+#define VK_LSHIFT 0xA0
+#define VK_RSHIFT 0xA1
+#define VK_LCONTROL 0xA2
+#define VK_RCONTROL 0xA3
+#define VK_LMENU 0xA4
+#define VK_RMENU 0xA5
+#define VK_BROWSER_BACK 0xA6
+#define VK_BROWSER_FORWARD 0xA7
+#define VK_BROWSER_REFRESH 0xA8
+#define VK_BROWSER_STOP 0xA9
+#define VK_BROWSER_SEARCH 0xAA
+#define VK_BROWSER_FAVORITES 0xAB
+#define VK_BROWSER_HOME 0xAC
+#define VK_VOLUME_MUTE 0xAD
+#define VK_VOLUME_DOWN 0xAE
+#define VK_VOLUME_UP 0xAF
+#define VK_MEDIA_NEXT_TRACK 0xB0
+#define VK_MEDIA_PREV_TRACK 0xB1
+#define VK_MEDIA_STOP 0xB2
+#define VK_MEDIA_PLAY_PAUSE 0xB3
+#define VK_LAUNCH_MAIL 0xB4
+#define VK_LAUNCH_MEDIA_SELECT 0xB5
+#define VK_LAUNCH_APP1 0xB6
+#define VK_LAUNCH_APP2 0xB7
+#define VK_OEM_1 0xBA
+#define VK_OEM_PLUS 0xBB
+#define VK_OEM_COMMA 0xBC
+#define VK_OEM_MINUS 0xBD
+#define VK_OEM_PERIOD 0xBE
+#define VK_OEM_2 0xBF
+#define VK_OEM_3 0xC0
+#define VK_OEM_4 0xDB
+#define VK_OEM_5 0xDC
+#define VK_OEM_6 0xDD
+#define VK_OEM_7 0xDE
+#define VK_OEM_8 0xDF
+#define VK_OEM_AX 0xE1
+#define VK_OEM_102 0xE2
+#define VK_ICO_HELP 0xE3
+#define VK_ICO_00 0xE4
+#define VK_PROCESSKEY 0xE5
+#define VK_ICO_CLEAR 0xE6
+#define VK_PACKET 0xE7
+#define VK_OEM_RESET 0xE9
+#define VK_OEM_JUMP 0xEA
+#define VK_OEM_PA1 0xEB
+#define VK_OEM_PA2 0xEC
+#define VK_OEM_PA3 0xED
+#define VK_OEM_WSCTRL 0xEE
+#define VK_OEM_CUSEL 0xEF
+#define VK_OEM_ATTN 0xF0
+#define VK_OEM_FINISH 0xF1
+#define VK_OEM_COPY 0xF2
+#define VK_OEM_AUTO 0xF3
+#define VK_OEM_ENLW 0xF4
+#define VK_OEM_BACKTAB 0xF5
+#define VK_ATTN 0xF6
+#define VK_CRSEL 0xF7
+#define VK_EXSEL 0xF8
+#define VK_EREOF 0xF9
+#define VK_PLAY 0xFA
+#define VK_ZOOM 0xFB
+#define VK_NONAME 0xFC
+#define VK_PA1 0xFD
+#define VK_OEM_CLEAR 0xFE
+#endif
+
+#ifndef NOWH
+
+#define WH_MIN (-1)
+#define WH_MSGFILTER (-1)
+#define WH_JOURNALRECORD 0
+#define WH_JOURNALPLAYBACK 1
+#define WH_KEYBOARD 2
+#define WH_GETMESSAGE 3
+#define WH_CALLWNDPROC 4
+#define WH_CBT 5
+#define WH_SYSMSGFILTER 6
+#define WH_MOUSE 7
+#define WH_HARDWARE 8
+#define WH_DEBUG 9
+#define WH_SHELL 10
+#define WH_FOREGROUNDIDLE 11
+#define WH_CALLWNDPROCRET 12
+
+#define WH_KEYBOARD_LL 13
+#define WH_MOUSE_LL 14
+
+#define WH_MAX 14
+
+#define WH_MINHOOK WH_MIN
+#define WH_MAXHOOK WH_MAX
+
+#define HC_ACTION 0
+#define HC_GETNEXT 1
+#define HC_SKIP 2
+#define HC_NOREMOVE 3
+#define HC_NOREM HC_NOREMOVE
+#define HC_SYSMODALON 4
+#define HC_SYSMODALOFF 5
+
+#define HCBT_MOVESIZE 0
+#define HCBT_MINMAX 1
+#define HCBT_QS 2
+#define HCBT_CREATEWND 3
+#define HCBT_DESTROYWND 4
+#define HCBT_ACTIVATE 5
+#define HCBT_CLICKSKIPPED 6
+#define HCBT_KEYSKIPPED 7
+#define HCBT_SYSCOMMAND 8
+#define HCBT_SETFOCUS 9
+
+ typedef struct tagCBT_CREATEWNDA {
+ struct tagCREATESTRUCTA *lpcs;
+ HWND hwndInsertAfter;
+ } CBT_CREATEWNDA,*LPCBT_CREATEWNDA;
+
+ typedef struct tagCBT_CREATEWNDW {
+ struct tagCREATESTRUCTW *lpcs;
+ HWND hwndInsertAfter;
+ } CBT_CREATEWNDW,*LPCBT_CREATEWNDW;
+#ifdef UNICODE
+ typedef CBT_CREATEWNDW CBT_CREATEWND;
+ typedef LPCBT_CREATEWNDW LPCBT_CREATEWND;
+#else
+ typedef CBT_CREATEWNDA CBT_CREATEWND;
+ typedef LPCBT_CREATEWNDA LPCBT_CREATEWND;
+#endif
+
+ typedef struct tagCBTACTIVATESTRUCT
+ {
+ WINBOOL fMouse;
+ HWND hWndActive;
+ } CBTACTIVATESTRUCT,*LPCBTACTIVATESTRUCT;
+
+ typedef struct tagWTSSESSION_NOTIFICATION {
+ DWORD cbSize;
+ DWORD dwSessionId;
+
+ } WTSSESSION_NOTIFICATION,*PWTSSESSION_NOTIFICATION;
+
+#define WTS_CONSOLE_CONNECT 0x1
+#define WTS_CONSOLE_DISCONNECT 0x2
+#define WTS_REMOTE_CONNECT 0x3
+#define WTS_REMOTE_DISCONNECT 0x4
+#define WTS_SESSION_LOGON 0x5
+#define WTS_SESSION_LOGOFF 0x6
+#define WTS_SESSION_LOCK 0x7
+#define WTS_SESSION_UNLOCK 0x8
+#define WTS_SESSION_REMOTE_CONTROL 0x9
+
+#define MSGF_DIALOGBOX 0
+#define MSGF_MESSAGEBOX 1
+#define MSGF_MENU 2
+#define MSGF_SCROLLBAR 5
+#define MSGF_NEXTWINDOW 6
+#define MSGF_MAX 8
+#define MSGF_USER 4096
+
+#define HSHELL_WINDOWCREATED 1
+#define HSHELL_WINDOWDESTROYED 2
+#define HSHELL_ACTIVATESHELLWINDOW 3
+
+#define HSHELL_WINDOWACTIVATED 4
+#define HSHELL_GETMINRECT 5
+#define HSHELL_REDRAW 6
+#define HSHELL_TASKMAN 7
+#define HSHELL_LANGUAGE 8
+#define HSHELL_SYSMENU 9
+#define HSHELL_ENDTASK 10
+#define HSHELL_ACCESSIBILITYSTATE 11
+#define HSHELL_APPCOMMAND 12
+#define HSHELL_WINDOWREPLACED 13
+#define HSHELL_WINDOWREPLACING 14
+#define HSHELL_HIGHBIT 0x8000
+#define HSHELL_FLASH (HSHELL_REDRAW|HSHELL_HIGHBIT)
+#define HSHELL_RUDEAPPACTIVATED (HSHELL_WINDOWACTIVATED|HSHELL_HIGHBIT)
+
+#define ACCESS_STICKYKEYS 0x0001
+#define ACCESS_FILTERKEYS 0x0002
+#define ACCESS_MOUSEKEYS 0x0003
+
+#define APPCOMMAND_BROWSER_BACKWARD 1
+#define APPCOMMAND_BROWSER_FORWARD 2
+#define APPCOMMAND_BROWSER_REFRESH 3
+#define APPCOMMAND_BROWSER_STOP 4
+#define APPCOMMAND_BROWSER_SEARCH 5
+#define APPCOMMAND_BROWSER_FAVORITES 6
+#define APPCOMMAND_BROWSER_HOME 7
+#define APPCOMMAND_VOLUME_MUTE 8
+#define APPCOMMAND_VOLUME_DOWN 9
+#define APPCOMMAND_VOLUME_UP 10
+#define APPCOMMAND_MEDIA_NEXTTRACK 11
+#define APPCOMMAND_MEDIA_PREVIOUSTRACK 12
+#define APPCOMMAND_MEDIA_STOP 13
+#define APPCOMMAND_MEDIA_PLAY_PAUSE 14
+#define APPCOMMAND_LAUNCH_MAIL 15
+#define APPCOMMAND_LAUNCH_MEDIA_SELECT 16
+#define APPCOMMAND_LAUNCH_APP1 17
+#define APPCOMMAND_LAUNCH_APP2 18
+#define APPCOMMAND_BASS_DOWN 19
+#define APPCOMMAND_BASS_BOOST 20
+#define APPCOMMAND_BASS_UP 21
+#define APPCOMMAND_TREBLE_DOWN 22
+#define APPCOMMAND_TREBLE_UP 23
+#define APPCOMMAND_MICROPHONE_VOLUME_MUTE 24
+#define APPCOMMAND_MICROPHONE_VOLUME_DOWN 25
+#define APPCOMMAND_MICROPHONE_VOLUME_UP 26
+#define APPCOMMAND_HELP 27
+#define APPCOMMAND_FIND 28
+#define APPCOMMAND_NEW 29
+#define APPCOMMAND_OPEN 30
+#define APPCOMMAND_CLOSE 31
+#define APPCOMMAND_SAVE 32
+#define APPCOMMAND_PRINT 33
+#define APPCOMMAND_UNDO 34
+#define APPCOMMAND_REDO 35
+#define APPCOMMAND_COPY 36
+#define APPCOMMAND_CUT 37
+#define APPCOMMAND_PASTE 38
+#define APPCOMMAND_REPLY_TO_MAIL 39
+#define APPCOMMAND_FORWARD_MAIL 40
+#define APPCOMMAND_SEND_MAIL 41
+#define APPCOMMAND_SPELL_CHECK 42
+#define APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE 43
+#define APPCOMMAND_MIC_ON_OFF_TOGGLE 44
+#define APPCOMMAND_CORRECTION_LIST 45
+#define APPCOMMAND_MEDIA_PLAY 46
+#define APPCOMMAND_MEDIA_PAUSE 47
+#define APPCOMMAND_MEDIA_RECORD 48
+#define APPCOMMAND_MEDIA_FAST_FORWARD 49
+#define APPCOMMAND_MEDIA_REWIND 50
+#define APPCOMMAND_MEDIA_CHANNEL_UP 51
+#define APPCOMMAND_MEDIA_CHANNEL_DOWN 52
+
+#define FAPPCOMMAND_MOUSE 0x8000
+#define FAPPCOMMAND_KEY 0
+#define FAPPCOMMAND_OEM 0x1000
+#define FAPPCOMMAND_MASK 0xF000
+
+#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
+#define GET_DEVICE_LPARAM(lParam) ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK))
+#define GET_MOUSEORKEY_LPARAM GET_DEVICE_LPARAM
+#define GET_FLAGS_LPARAM(lParam) (LOWORD(lParam))
+#define GET_KEYSTATE_LPARAM(lParam) GET_FLAGS_LPARAM(lParam)
+
+ typedef struct {
+ HWND hwnd;
+ RECT rc;
+ } SHELLHOOKINFO,*LPSHELLHOOKINFO;
+
+ typedef struct tagEVENTMSG {
+ UINT message;
+ UINT paramL;
+ UINT paramH;
+ DWORD time;
+ HWND hwnd;
+ } EVENTMSG,*PEVENTMSGMSG,*NPEVENTMSGMSG,*LPEVENTMSGMSG;
+
+ typedef struct tagEVENTMSG *PEVENTMSG,*NPEVENTMSG,*LPEVENTMSG;
+
+ typedef struct tagCWPSTRUCT {
+ LPARAM lParam;
+ WPARAM wParam;
+ UINT message;
+ HWND hwnd;
+ } CWPSTRUCT,*PCWPSTRUCT,*NPCWPSTRUCT,*LPCWPSTRUCT;
+
+ typedef struct tagCWPRETSTRUCT {
+ LRESULT lResult;
+ LPARAM lParam;
+ WPARAM wParam;
+ UINT message;
+ HWND hwnd;
+ } CWPRETSTRUCT,*PCWPRETSTRUCT,*NPCWPRETSTRUCT,*LPCWPRETSTRUCT;
+
+#define LLKHF_EXTENDED (KF_EXTENDED >> 8)
+#define LLKHF_INJECTED 0x00000010
+#define LLKHF_ALTDOWN (KF_ALTDOWN >> 8)
+#define LLKHF_UP (KF_UP >> 8)
+
+#define LLMHF_INJECTED 0x00000001
+
+ typedef struct tagKBDLLHOOKSTRUCT {
+ DWORD vkCode;
+ DWORD scanCode;
+ DWORD flags;
+ DWORD time;
+ ULONG_PTR dwExtraInfo;
+ } KBDLLHOOKSTRUCT,*LPKBDLLHOOKSTRUCT,*PKBDLLHOOKSTRUCT;
+
+ typedef struct tagMSLLHOOKSTRUCT {
+ POINT pt;
+ DWORD mouseData;
+ DWORD flags;
+ DWORD time;
+ ULONG_PTR dwExtraInfo;
+ } MSLLHOOKSTRUCT,*LPMSLLHOOKSTRUCT,*PMSLLHOOKSTRUCT;
+
+ typedef struct tagDEBUGHOOKINFO {
+ DWORD idThread;
+ DWORD idThreadInstaller;
+ LPARAM lParam;
+ WPARAM wParam;
+ int code;
+ } DEBUGHOOKINFO,*PDEBUGHOOKINFO,*NPDEBUGHOOKINFO,*LPDEBUGHOOKINFO;
+
+ typedef struct tagMOUSEHOOKSTRUCT {
+ POINT pt;
+ HWND hwnd;
+ UINT wHitTestCode;
+ ULONG_PTR dwExtraInfo;
+ } MOUSEHOOKSTRUCT,*LPMOUSEHOOKSTRUCT,*PMOUSEHOOKSTRUCT;
+
+#ifdef __cplusplus
+ typedef struct tagMOUSEHOOKSTRUCTEX : public tagMOUSEHOOKSTRUCT {
+ DWORD mouseData;
+ } MOUSEHOOKSTRUCTEX,*LPMOUSEHOOKSTRUCTEX,*PMOUSEHOOKSTRUCTEX;
+#else
+ typedef struct tagMOUSEHOOKSTRUCTEX {
+ MOUSEHOOKSTRUCT _unnamed;
+ DWORD mouseData;
+ } MOUSEHOOKSTRUCTEX,*LPMOUSEHOOKSTRUCTEX,*PMOUSEHOOKSTRUCTEX;
+#endif
+
+ typedef struct tagHARDWAREHOOKSTRUCT {
+ HWND hwnd;
+ UINT message;
+ WPARAM wParam;
+ LPARAM lParam;
+ } HARDWAREHOOKSTRUCT,*LPHARDWAREHOOKSTRUCT,*PHARDWAREHOOKSTRUCT;
+#endif
+
+#define HKL_PREV 0
+#define HKL_NEXT 1
+
+#define KLF_ACTIVATE 0x00000001
+#define KLF_SUBSTITUTE_OK 0x00000002
+#define KLF_REORDER 0x00000008
+#define KLF_REPLACELANG 0x00000010
+#define KLF_NOTELLSHELL 0x00000080
+#define KLF_SETFORPROCESS 0x00000100
+#define KLF_SHIFTLOCK 0x00010000
+#define KLF_RESET 0x40000000
+
+#define INPUTLANGCHANGE_SYSCHARSET 0x0001
+#define INPUTLANGCHANGE_FORWARD 0x0002
+#define INPUTLANGCHANGE_BACKWARD 0x0004
+
+#define KL_NAMELENGTH 9
+
+#ifdef UNICODE
+#define LoadKeyboardLayout LoadKeyboardLayoutW
+#define GetKeyboardLayoutName GetKeyboardLayoutNameW
+#else
+#define LoadKeyboardLayout LoadKeyboardLayoutA
+#define GetKeyboardLayoutName GetKeyboardLayoutNameA
+#endif
+
+ WINUSERAPI HKL WINAPI LoadKeyboardLayoutA(LPCSTR pwszKLID,UINT Flags);
+ WINUSERAPI HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID,UINT Flags);
+ WINUSERAPI HKL WINAPI ActivateKeyboardLayout(HKL hkl,UINT Flags);
+ WINUSERAPI int WINAPI ToUnicodeEx(UINT wVirtKey,UINT wScanCode,CONST BYTE *lpKeyState,LPWSTR pwszBuff,int cchBuff,UINT wFlags,HKL dwhkl);
+ WINUSERAPI WINBOOL WINAPI UnloadKeyboardLayout(HKL hkl);
+ WINUSERAPI WINBOOL WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID);
+ WINUSERAPI WINBOOL WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID);
+ WINUSERAPI int WINAPI GetKeyboardLayoutList(int nBuff,HKL *lpList);
+ WINUSERAPI HKL WINAPI GetKeyboardLayout(DWORD idThread);
+
+ typedef struct tagMOUSEMOVEPOINT {
+ int x;
+ int y;
+ DWORD time;
+ ULONG_PTR dwExtraInfo;
+ } MOUSEMOVEPOINT,*PMOUSEMOVEPOINT,*LPMOUSEMOVEPOINT;
+
+#define GMMP_USE_DISPLAY_POINTS 1
+#define GMMP_USE_HIGH_RESOLUTION_POINTS 2
+
+ WINUSERAPI int WINAPI GetMouseMovePointsEx(UINT cbSize,LPMOUSEMOVEPOINT lppt,LPMOUSEMOVEPOINT lpptBuf,int nBufPoints,DWORD resolution);
+
+#ifndef NODESKTOP
+
+#define DESKTOP_READOBJECTS 0x0001L
+#define DESKTOP_CREATEWINDOW 0x0002L
+#define DESKTOP_CREATEMENU 0x0004L
+#define DESKTOP_HOOKCONTROL 0x0008L
+#define DESKTOP_JOURNALRECORD 0x0010L
+#define DESKTOP_JOURNALPLAYBACK 0x0020L
+#define DESKTOP_ENUMERATE 0x0040L
+#define DESKTOP_WRITEOBJECTS 0x0080L
+#define DESKTOP_SWITCHDESKTOP 0x0100L
+
+#define DF_ALLOWOTHERACCOUNTHOOK 0x0001L
+
+#ifdef _WINGDI_
+#ifndef NOGDI
+#ifdef UNICODE
+#define CreateDesktop CreateDesktopW
+#else
+#define CreateDesktop CreateDesktopA
+#endif
+
+ WINUSERAPI HDESK WINAPI CreateDesktopA(LPCSTR lpszDesktop,LPCSTR lpszDevice,LPDEVMODEA pDevmode,DWORD dwFlags,ACCESS_MASK dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa);
+ WINUSERAPI HDESK WINAPI CreateDesktopW(LPCWSTR lpszDesktop,LPCWSTR lpszDevice,LPDEVMODEW pDevmode,DWORD dwFlags,ACCESS_MASK dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa);
+#endif
+#endif
+
+#ifdef UNICODE
+#define OpenDesktop OpenDesktopW
+#define EnumDesktops EnumDesktopsW
+#else
+#define OpenDesktop OpenDesktopA
+#define EnumDesktops EnumDesktopsA
+#endif
+
+ WINUSERAPI HDESK WINAPI OpenDesktopA(LPCSTR lpszDesktop,DWORD dwFlags,WINBOOL fInherit,ACCESS_MASK dwDesiredAccess);
+ WINUSERAPI HDESK WINAPI OpenDesktopW(LPCWSTR lpszDesktop,DWORD dwFlags,WINBOOL fInherit,ACCESS_MASK dwDesiredAccess);
+ WINUSERAPI HDESK WINAPI OpenInputDesktop(DWORD dwFlags,WINBOOL fInherit,ACCESS_MASK dwDesiredAccess);
+ WINUSERAPI WINBOOL WINAPI EnumDesktopsA(HWINSTA hwinsta,DESKTOPENUMPROCA lpEnumFunc,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI EnumDesktopsW(HWINSTA hwinsta,DESKTOPENUMPROCW lpEnumFunc,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI EnumDesktopWindows(HDESK hDesktop,WNDENUMPROC lpfn,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI SwitchDesktop(HDESK hDesktop);
+ WINUSERAPI WINBOOL WINAPI SetThreadDesktop(HDESK hDesktop);
+ WINUSERAPI WINBOOL WINAPI CloseDesktop(HDESK hDesktop);
+ WINUSERAPI HDESK WINAPI GetThreadDesktop(DWORD dwThreadId);
+#endif
+
+#ifndef NOWINDOWSTATION
+#define WINSTA_ENUMDESKTOPS 0x0001L
+#define WINSTA_READATTRIBUTES 0x0002L
+#define WINSTA_ACCESSCLIPBOARD 0x0004L
+#define WINSTA_CREATEDESKTOP 0x0008L
+#define WINSTA_WRITEATTRIBUTES 0x0010L
+#define WINSTA_ACCESSGLOBALATOMS 0x0020L
+#define WINSTA_EXITWINDOWS 0x0040L
+#define WINSTA_ENUMERATE 0x0100L
+#define WINSTA_READSCREEN 0x0200L
+#define WINSTA_ALL_ACCESS (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN)
+
+#define CWF_CREATE_ONLY 0x0001L
+
+#define WSF_VISIBLE 0x0001L
+
+#ifdef UNICODE
+#define CreateWindowStation CreateWindowStationW
+#define OpenWindowStation OpenWindowStationW
+#define EnumWindowStations EnumWindowStationsW
+#else
+#define CreateWindowStation CreateWindowStationA
+#define OpenWindowStation OpenWindowStationA
+#define EnumWindowStations EnumWindowStationsA
+#endif
+
+ WINUSERAPI HWINSTA WINAPI CreateWindowStationA(LPCSTR lpwinsta,DWORD dwFlags,ACCESS_MASK dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa);
+ WINUSERAPI HWINSTA WINAPI CreateWindowStationW(LPCWSTR lpwinsta,DWORD dwFlags,ACCESS_MASK dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa);
+ WINUSERAPI HWINSTA WINAPI OpenWindowStationA(LPCSTR lpszWinSta,WINBOOL fInherit,ACCESS_MASK dwDesiredAccess);
+ WINUSERAPI HWINSTA WINAPI OpenWindowStationW(LPCWSTR lpszWinSta,WINBOOL fInherit,ACCESS_MASK dwDesiredAccess);
+ WINUSERAPI WINBOOL WINAPI EnumWindowStationsA(WINSTAENUMPROCA lpEnumFunc,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI EnumWindowStationsW(WINSTAENUMPROCW lpEnumFunc,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI CloseWindowStation(HWINSTA hWinSta);
+ WINUSERAPI WINBOOL WINAPI SetProcessWindowStation(HWINSTA hWinSta);
+ WINUSERAPI HWINSTA WINAPI GetProcessWindowStation(VOID);
+#endif
+
+#ifndef NOSECURITY
+ WINUSERAPI WINBOOL WINAPI SetUserObjectSecurity(HANDLE hObj,PSECURITY_INFORMATION pSIRequested,PSECURITY_DESCRIPTOR pSID);
+ WINUSERAPI WINBOOL WINAPI GetUserObjectSecurity(HANDLE hObj,PSECURITY_INFORMATION pSIRequested,PSECURITY_DESCRIPTOR pSID,DWORD nLength,LPDWORD lpnLengthNeeded);
+
+#define UOI_FLAGS 1
+#define UOI_NAME 2
+#define UOI_TYPE 3
+#define UOI_USER_SID 4
+
+ typedef struct tagUSEROBJECTFLAGS {
+ WINBOOL fInherit;
+ WINBOOL fReserved;
+ DWORD dwFlags;
+ } USEROBJECTFLAGS,*PUSEROBJECTFLAGS;
+
+#ifdef UNICODE
+#define GetUserObjectInformation GetUserObjectInformationW
+#define SetUserObjectInformation SetUserObjectInformationW
+#else
+#define GetUserObjectInformation GetUserObjectInformationA
+#define SetUserObjectInformation SetUserObjectInformationA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI GetUserObjectInformationA(HANDLE hObj,int nIndex,PVOID pvInfo,DWORD nLength,LPDWORD lpnLengthNeeded);
+ WINUSERAPI WINBOOL WINAPI GetUserObjectInformationW(HANDLE hObj,int nIndex,PVOID pvInfo,DWORD nLength,LPDWORD lpnLengthNeeded);
+ WINUSERAPI WINBOOL WINAPI SetUserObjectInformationA(HANDLE hObj,int nIndex,PVOID pvInfo,DWORD nLength);
+ WINUSERAPI WINBOOL WINAPI SetUserObjectInformationW(HANDLE hObj,int nIndex,PVOID pvInfo,DWORD nLength);
+#endif
+
+ typedef struct tagWNDCLASSEXA {
+ UINT cbSize;
+ UINT style;
+ WNDPROC lpfnWndProc;
+ int cbClsExtra;
+ int cbWndExtra;
+ HINSTANCE hInstance;
+ HICON hIcon;
+ HCURSOR hCursor;
+ HBRUSH hbrBackground;
+ LPCSTR lpszMenuName;
+ LPCSTR lpszClassName;
+ HICON hIconSm;
+ } WNDCLASSEXA,*PWNDCLASSEXA,*NPWNDCLASSEXA,*LPWNDCLASSEXA;
+
+ typedef struct tagWNDCLASSEXW {
+ UINT cbSize;
+ UINT style;
+ WNDPROC lpfnWndProc;
+ int cbClsExtra;
+ int cbWndExtra;
+ HINSTANCE hInstance;
+ HICON hIcon;
+ HCURSOR hCursor;
+ HBRUSH hbrBackground;
+ LPCWSTR lpszMenuName;
+ LPCWSTR lpszClassName;
+
+ HICON hIconSm;
+ } WNDCLASSEXW,*PWNDCLASSEXW,*NPWNDCLASSEXW,*LPWNDCLASSEXW;
+
+#ifdef UNICODE
+ typedef WNDCLASSEXW WNDCLASSEX;
+ typedef PWNDCLASSEXW PWNDCLASSEX;
+ typedef NPWNDCLASSEXW NPWNDCLASSEX;
+ typedef LPWNDCLASSEXW LPWNDCLASSEX;
+#else
+ typedef WNDCLASSEXA WNDCLASSEX;
+ typedef PWNDCLASSEXA PWNDCLASSEX;
+ typedef NPWNDCLASSEXA NPWNDCLASSEX;
+ typedef LPWNDCLASSEXA LPWNDCLASSEX;
+#endif
+
+ typedef struct tagWNDCLASSA {
+ UINT style;
+ WNDPROC lpfnWndProc;
+ int cbClsExtra;
+ int cbWndExtra;
+ HINSTANCE hInstance;
+ HICON hIcon;
+ HCURSOR hCursor;
+ HBRUSH hbrBackground;
+ LPCSTR lpszMenuName;
+ LPCSTR lpszClassName;
+ } WNDCLASSA,*PWNDCLASSA,*NPWNDCLASSA,*LPWNDCLASSA;
+
+ typedef struct tagWNDCLASSW {
+ UINT style;
+ WNDPROC lpfnWndProc;
+ int cbClsExtra;
+ int cbWndExtra;
+ HINSTANCE hInstance;
+ HICON hIcon;
+ HCURSOR hCursor;
+ HBRUSH hbrBackground;
+ LPCWSTR lpszMenuName;
+ LPCWSTR lpszClassName;
+ } WNDCLASSW,*PWNDCLASSW,*NPWNDCLASSW,*LPWNDCLASSW;
+
+#ifdef UNICODE
+ typedef WNDCLASSW WNDCLASS;
+ typedef PWNDCLASSW PWNDCLASS;
+ typedef NPWNDCLASSW NPWNDCLASS;
+ typedef LPWNDCLASSW LPWNDCLASS;
+#else
+ typedef WNDCLASSA WNDCLASS;
+ typedef PWNDCLASSA PWNDCLASS;
+ typedef NPWNDCLASSA NPWNDCLASS;
+ typedef LPWNDCLASSA LPWNDCLASS;
+#endif
+
+ WINUSERAPI WINBOOL WINAPI IsHungAppWindow(HWND hwnd);
+ WINUSERAPI VOID WINAPI DisableProcessWindowsGhosting(VOID);
+
+#ifndef NOMSG
+ typedef struct tagMSG {
+ HWND hwnd;
+ UINT message;
+ WPARAM wParam;
+ LPARAM lParam;
+ DWORD time;
+ POINT pt;
+ } MSG,*PMSG,*NPMSG,*LPMSG;
+
+#define POINTSTOPOINT(pt,pts) { (pt).x = (LONG)(SHORT)LOWORD(*(LONG*)&pts); (pt).y = (LONG)(SHORT)HIWORD(*(LONG*)&pts); }
+
+#define POINTTOPOINTS(pt) (MAKELONG((short)((pt).x),(short)((pt).y)))
+#define MAKEWPARAM(l,h) ((WPARAM)(DWORD)MAKELONG(l,h))
+#define MAKELPARAM(l,h) ((LPARAM)(DWORD)MAKELONG(l,h))
+#define MAKELRESULT(l,h) ((LRESULT)(DWORD)MAKELONG(l,h))
+#endif
+
+#ifndef NOWINOFFSETS
+#define GWL_WNDPROC (-4)
+#define GWL_HINSTANCE (-6)
+#define GWL_HWNDPARENT (-8)
+#define GWL_STYLE (-16)
+#define GWL_EXSTYLE (-20)
+#define GWL_USERDATA (-21)
+#define GWL_ID (-12)
+
+#ifdef _WIN64
+#undef GWL_WNDPROC
+#undef GWL_HINSTANCE
+#undef GWL_HWNDPARENT
+#undef GWL_USERDATA
+#endif
+
+#define GWLP_WNDPROC (-4)
+#define GWLP_HINSTANCE (-6)
+#define GWLP_HWNDPARENT (-8)
+#define GWLP_USERDATA (-21)
+#define GWLP_ID (-12)
+
+#define GCL_MENUNAME (-8)
+#define GCL_HBRBACKGROUND (-10)
+#define GCL_HCURSOR (-12)
+#define GCL_HICON (-14)
+#define GCL_HMODULE (-16)
+#define GCL_CBWNDEXTRA (-18)
+#define GCL_CBCLSEXTRA (-20)
+#define GCL_WNDPROC (-24)
+#define GCL_STYLE (-26)
+#define GCW_ATOM (-32)
+#define GCL_HICONSM (-34)
+
+#ifdef _WIN64
+
+#undef GCL_MENUNAME
+#undef GCL_HBRBACKGROUND
+#undef GCL_HCURSOR
+#undef GCL_HICON
+#undef GCL_HMODULE
+#undef GCL_WNDPROC
+#undef GCL_HICONSM
+#endif
+
+#define GCLP_MENUNAME (-8)
+#define GCLP_HBRBACKGROUND (-10)
+#define GCLP_HCURSOR (-12)
+#define GCLP_HICON (-14)
+#define GCLP_HMODULE (-16)
+#define GCLP_WNDPROC (-24)
+#define GCLP_HICONSM (-34)
+#endif
+
+#ifndef NOWINMESSAGES
+
+#define WM_NULL 0x0000
+#define WM_CREATE 0x0001
+#define WM_DESTROY 0x0002
+#define WM_MOVE 0x0003
+#define WM_SIZE 0x0005
+
+#define WM_ACTIVATE 0x0006
+
+#define WA_INACTIVE 0
+#define WA_ACTIVE 1
+#define WA_CLICKACTIVE 2
+
+#define WM_SETFOCUS 0x0007
+#define WM_KILLFOCUS 0x0008
+#define WM_ENABLE 0x000A
+#define WM_SETREDRAW 0x000B
+#define WM_SETTEXT 0x000C
+#define WM_GETTEXT 0x000D
+#define WM_GETTEXTLENGTH 0x000E
+#define WM_PAINT 0x000F
+#define WM_CLOSE 0x0010
+#ifndef _WIN32_WCE
+#define WM_QUERYENDSESSION 0x0011
+#define WM_QUERYOPEN 0x0013
+#define WM_ENDSESSION 0x0016
+#endif
+#define WM_QUIT 0x0012
+#define WM_ERASEBKGND 0x0014
+#define WM_SYSCOLORCHANGE 0x0015
+#define WM_SHOWWINDOW 0x0018
+#define WM_WININICHANGE 0x001A
+#define WM_SETTINGCHANGE WM_WININICHANGE
+#define WM_DEVMODECHANGE 0x001B
+#define WM_ACTIVATEAPP 0x001C
+#define WM_FONTCHANGE 0x001D
+#define WM_TIMECHANGE 0x001E
+#define WM_CANCELMODE 0x001F
+#define WM_SETCURSOR 0x0020
+#define WM_MOUSEACTIVATE 0x0021
+#define WM_CHILDACTIVATE 0x0022
+#define WM_QUEUESYNC 0x0023
+
+#define WM_GETMINMAXINFO 0x0024
+
+ typedef struct tagMINMAXINFO {
+ POINT ptReserved;
+ POINT ptMaxSize;
+ POINT ptMaxPosition;
+ POINT ptMinTrackSize;
+ POINT ptMaxTrackSize;
+ } MINMAXINFO,*PMINMAXINFO,*LPMINMAXINFO;
+
+#define WM_PAINTICON 0x0026
+#define WM_ICONERASEBKGND 0x0027
+#define WM_NEXTDLGCTL 0x0028
+#define WM_SPOOLERSTATUS 0x002A
+#define WM_DRAWITEM 0x002B
+#define WM_MEASUREITEM 0x002C
+#define WM_DELETEITEM 0x002D
+#define WM_VKEYTOITEM 0x002E
+#define WM_CHARTOITEM 0x002F
+#define WM_SETFONT 0x0030
+#define WM_GETFONT 0x0031
+#define WM_SETHOTKEY 0x0032
+#define WM_GETHOTKEY 0x0033
+#define WM_QUERYDRAGICON 0x0037
+#define WM_COMPAREITEM 0x0039
+#ifndef _WIN32_WCE
+#define WM_GETOBJECT 0x003D
+#endif
+#define WM_COMPACTING 0x0041
+#define WM_COMMNOTIFY 0x0044
+#define WM_WINDOWPOSCHANGING 0x0046
+#define WM_WINDOWPOSCHANGED 0x0047
+
+#define WM_POWER 0x0048
+
+#define PWR_OK 1
+#define PWR_FAIL (-1)
+#define PWR_SUSPENDREQUEST 1
+#define PWR_SUSPENDRESUME 2
+#define PWR_CRITICALRESUME 3
+
+#define WM_COPYDATA 0x004A
+#define WM_CANCELJOURNAL 0x004B
+
+ typedef struct tagCOPYDATASTRUCT {
+ ULONG_PTR dwData;
+ DWORD cbData;
+ PVOID lpData;
+ } COPYDATASTRUCT,*PCOPYDATASTRUCT;
+
+ typedef struct tagMDINEXTMENU {
+ HMENU hmenuIn;
+ HMENU hmenuNext;
+ HWND hwndNext;
+ } MDINEXTMENU,*PMDINEXTMENU,*LPMDINEXTMENU;
+
+#define WM_NOTIFY 0x004E
+#define WM_INPUTLANGCHANGEREQUEST 0x0050
+#define WM_INPUTLANGCHANGE 0x0051
+#define WM_TCARD 0x0052
+#define WM_HELP 0x0053
+#define WM_USERCHANGED 0x0054
+#define WM_NOTIFYFORMAT 0x0055
+
+#define NFR_ANSI 1
+#define NFR_UNICODE 2
+#define NF_QUERY 3
+#define NF_REQUERY 4
+
+#define WM_CONTEXTMENU 0x007B
+#define WM_STYLECHANGING 0x007C
+#define WM_STYLECHANGED 0x007D
+#define WM_DISPLAYCHANGE 0x007E
+#define WM_GETICON 0x007F
+#define WM_SETICON 0x0080
+
+#define WM_NCCREATE 0x0081
+#define WM_NCDESTROY 0x0082
+#define WM_NCCALCSIZE 0x0083
+#define WM_NCHITTEST 0x0084
+#define WM_NCPAINT 0x0085
+#define WM_NCACTIVATE 0x0086
+#define WM_GETDLGCODE 0x0087
+#ifndef _WIN32_WCE
+#define WM_SYNCPAINT 0x0088
+#endif
+#define WM_NCMOUSEMOVE 0x00A0
+#define WM_NCLBUTTONDOWN 0x00A1
+#define WM_NCLBUTTONUP 0x00A2
+#define WM_NCLBUTTONDBLCLK 0x00A3
+#define WM_NCRBUTTONDOWN 0x00A4
+#define WM_NCRBUTTONUP 0x00A5
+#define WM_NCRBUTTONDBLCLK 0x00A6
+#define WM_NCMBUTTONDOWN 0x00A7
+#define WM_NCMBUTTONUP 0x00A8
+#define WM_NCMBUTTONDBLCLK 0x00A9
+
+#define WM_NCXBUTTONDOWN 0x00AB
+#define WM_NCXBUTTONUP 0x00AC
+#define WM_NCXBUTTONDBLCLK 0x00AD
+#define WM_INPUT 0x00FF
+#define WM_KEYFIRST 0x0100
+#define WM_KEYDOWN 0x0100
+#define WM_KEYUP 0x0101
+#define WM_CHAR 0x0102
+#define WM_DEADCHAR 0x0103
+#define WM_SYSKEYDOWN 0x0104
+#define WM_SYSKEYUP 0x0105
+#define WM_SYSCHAR 0x0106
+#define WM_SYSDEADCHAR 0x0107
+#define WM_UNICHAR 0x0109
+#define WM_KEYLAST 0x0109
+#define UNICODE_NOCHAR 0xFFFF
+#define WM_IME_STARTCOMPOSITION 0x010D
+#define WM_IME_ENDCOMPOSITION 0x010E
+#define WM_IME_COMPOSITION 0x010F
+#define WM_IME_KEYLAST 0x010F
+#define WM_INITDIALOG 0x0110
+#define WM_COMMAND 0x0111
+#define WM_SYSCOMMAND 0x0112
+#define WM_TIMER 0x0113
+#define WM_HSCROLL 0x0114
+#define WM_VSCROLL 0x0115
+#define WM_INITMENU 0x0116
+#define WM_INITMENUPOPUP 0x0117
+#define WM_MENUSELECT 0x011F
+#define WM_MENUCHAR 0x0120
+#define WM_ENTERIDLE 0x0121
+#ifndef _WIN32_WCE
+#define WM_MENURBUTTONUP 0x0122
+#define WM_MENUDRAG 0x0123
+#define WM_MENUGETOBJECT 0x0124
+#define WM_UNINITMENUPOPUP 0x0125
+#define WM_MENUCOMMAND 0x0126
+
+#ifndef _WIN32_WCE
+#define WM_CHANGEUISTATE 0x0127
+#define WM_UPDATEUISTATE 0x0128
+#define WM_QUERYUISTATE 0x0129
+
+#define UIS_SET 1
+#define UIS_CLEAR 2
+#define UIS_INITIALIZE 3
+
+#define UISF_HIDEFOCUS 0x1
+#define UISF_HIDEACCEL 0x2
+#define UISF_ACTIVE 0x4
+#endif
+#endif
+
+#define WM_CTLCOLORMSGBOX 0x0132
+#define WM_CTLCOLOREDIT 0x0133
+#define WM_CTLCOLORLISTBOX 0x0134
+#define WM_CTLCOLORBTN 0x0135
+#define WM_CTLCOLORDLG 0x0136
+#define WM_CTLCOLORSCROLLBAR 0x0137
+#define WM_CTLCOLORSTATIC 0x0138
+#define MN_GETHMENU 0x01E1
+
+#define WM_MOUSEFIRST 0x0200
+#define WM_MOUSEMOVE 0x0200
+#define WM_LBUTTONDOWN 0x0201
+#define WM_LBUTTONUP 0x0202
+#define WM_LBUTTONDBLCLK 0x0203
+#define WM_RBUTTONDOWN 0x0204
+#define WM_RBUTTONUP 0x0205
+#define WM_RBUTTONDBLCLK 0x0206
+#define WM_MBUTTONDOWN 0x0207
+#define WM_MBUTTONUP 0x0208
+#define WM_MBUTTONDBLCLK 0x0209
+#define WM_MOUSEWHEEL 0x020A
+#define WM_XBUTTONDOWN 0x020B
+#define WM_XBUTTONUP 0x020C
+#define WM_XBUTTONDBLCLK 0x020D
+#define WM_MOUSELAST 0x020D
+
+#define WHEEL_DELTA 120
+#define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
+
+#define WHEEL_PAGESCROLL (UINT_MAX)
+
+#define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam))
+#define GET_NCHITTEST_WPARAM(wParam) ((short)LOWORD(wParam))
+#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam))
+
+#define XBUTTON1 0x0001
+#define XBUTTON2 0x0002
+
+#define WM_PARENTNOTIFY 0x0210
+#define WM_ENTERMENULOOP 0x0211
+#define WM_EXITMENULOOP 0x0212
+
+#define WM_NEXTMENU 0x0213
+#define WM_SIZING 0x0214
+#define WM_CAPTURECHANGED 0x0215
+#define WM_MOVING 0x0216
+
+#define WM_POWERBROADCAST 0x0218
+
+#ifndef _WIN32_WCE
+#define PBT_APMQUERYSUSPEND 0x0000
+#define PBT_APMQUERYSTANDBY 0x0001
+
+#define PBT_APMQUERYSUSPENDFAILED 0x0002
+#define PBT_APMQUERYSTANDBYFAILED 0x0003
+
+#define PBT_APMSUSPEND 0x0004
+#define PBT_APMSTANDBY 0x0005
+
+#define PBT_APMRESUMECRITICAL 0x0006
+#define PBT_APMRESUMESUSPEND 0x0007
+#define PBT_APMRESUMESTANDBY 0x0008
+
+#define PBTF_APMRESUMEFROMFAILURE 0x00000001
+
+#define PBT_APMBATTERYLOW 0x0009
+#define PBT_APMPOWERSTATUSCHANGE 0x000A
+
+#define PBT_APMOEMEVENT 0x000B
+#define PBT_APMRESUMEAUTOMATIC 0x0012
+#endif
+
+#define WM_DEVICECHANGE 0x0219
+
+#define WM_MDICREATE 0x0220
+#define WM_MDIDESTROY 0x0221
+#define WM_MDIACTIVATE 0x0222
+#define WM_MDIRESTORE 0x0223
+#define WM_MDINEXT 0x0224
+#define WM_MDIMAXIMIZE 0x0225
+#define WM_MDITILE 0x0226
+#define WM_MDICASCADE 0x0227
+#define WM_MDIICONARRANGE 0x0228
+#define WM_MDIGETACTIVE 0x0229
+
+#define WM_MDISETMENU 0x0230
+#define WM_ENTERSIZEMOVE 0x0231
+#define WM_EXITSIZEMOVE 0x0232
+#define WM_DROPFILES 0x0233
+#define WM_MDIREFRESHMENU 0x0234
+
+#define WM_IME_SETCONTEXT 0x0281
+#define WM_IME_NOTIFY 0x0282
+#define WM_IME_CONTROL 0x0283
+#define WM_IME_COMPOSITIONFULL 0x0284
+#define WM_IME_SELECT 0x0285
+#define WM_IME_CHAR 0x0286
+#define WM_IME_REQUEST 0x0288
+#define WM_IME_KEYDOWN 0x0290
+#define WM_IME_KEYUP 0x0291
+
+#define WM_MOUSEHOVER 0x02A1
+#define WM_MOUSELEAVE 0x02A3
+#define WM_NCMOUSEHOVER 0x02A0
+#define WM_NCMOUSELEAVE 0x02A2
+#define WM_WTSSESSION_CHANGE 0x02B1
+#define WM_TABLET_FIRST 0x02c0
+#define WM_TABLET_LAST 0x02df
+#define WM_CUT 0x0300
+#define WM_COPY 0x0301
+#define WM_PASTE 0x0302
+#define WM_CLEAR 0x0303
+#define WM_UNDO 0x0304
+#define WM_RENDERFORMAT 0x0305
+#define WM_RENDERALLFORMATS 0x0306
+#define WM_DESTROYCLIPBOARD 0x0307
+#define WM_DRAWCLIPBOARD 0x0308
+#define WM_PAINTCLIPBOARD 0x0309
+#define WM_VSCROLLCLIPBOARD 0x030A
+#define WM_SIZECLIPBOARD 0x030B
+#define WM_ASKCBFORMATNAME 0x030C
+#define WM_CHANGECBCHAIN 0x030D
+#define WM_HSCROLLCLIPBOARD 0x030E
+#define WM_QUERYNEWPALETTE 0x030F
+#define WM_PALETTEISCHANGING 0x0310
+#define WM_PALETTECHANGED 0x0311
+#define WM_HOTKEY 0x0312
+#define WM_PRINT 0x0317
+#define WM_PRINTCLIENT 0x0318
+#define WM_APPCOMMAND 0x0319
+#define WM_THEMECHANGED 0x031A
+#define WM_HANDHELDFIRST 0x0358
+#define WM_HANDHELDLAST 0x035F
+#define WM_AFXFIRST 0x0360
+#define WM_AFXLAST 0x037F
+#define WM_PENWINFIRST 0x0380
+#define WM_PENWINLAST 0x038F
+#define WM_APP 0x8000
+#define WM_USER 0x0400
+
+#define WMSZ_LEFT 1
+#define WMSZ_RIGHT 2
+#define WMSZ_TOP 3
+#define WMSZ_TOPLEFT 4
+#define WMSZ_TOPRIGHT 5
+#define WMSZ_BOTTOM 6
+#define WMSZ_BOTTOMLEFT 7
+#define WMSZ_BOTTOMRIGHT 8
+
+#ifndef NONCMESSAGES
+
+#define HTERROR (-2)
+#define HTTRANSPARENT (-1)
+#define HTNOWHERE 0
+#define HTCLIENT 1
+#define HTCAPTION 2
+#define HTSYSMENU 3
+#define HTGROWBOX 4
+#define HTSIZE HTGROWBOX
+#define HTMENU 5
+#define HTHSCROLL 6
+#define HTVSCROLL 7
+#define HTMINBUTTON 8
+#define HTMAXBUTTON 9
+#define HTLEFT 10
+#define HTRIGHT 11
+#define HTTOP 12
+#define HTTOPLEFT 13
+#define HTTOPRIGHT 14
+#define HTBOTTOM 15
+#define HTBOTTOMLEFT 16
+#define HTBOTTOMRIGHT 17
+#define HTBORDER 18
+#define HTREDUCE HTMINBUTTON
+#define HTZOOM HTMAXBUTTON
+#define HTSIZEFIRST HTLEFT
+#define HTSIZELAST HTBOTTOMRIGHT
+#define HTOBJECT 19
+#define HTCLOSE 20
+#define HTHELP 21
+
+#define SMTO_NORMAL 0x0000
+#define SMTO_BLOCK 0x0001
+#define SMTO_ABORTIFHUNG 0x0002
+#define SMTO_NOTIMEOUTIFNOTHUNG 0x0008
+#endif
+
+#define MA_ACTIVATE 1
+#define MA_ACTIVATEANDEAT 2
+#define MA_NOACTIVATE 3
+#define MA_NOACTIVATEANDEAT 4
+
+#define ICON_SMALL 0
+#define ICON_BIG 1
+#define ICON_SMALL2 2
+
+#ifdef UNICODE
+#define RegisterWindowMessage RegisterWindowMessageW
+#else
+#define RegisterWindowMessage RegisterWindowMessageA
+#endif
+
+ WINUSERAPI UINT WINAPI RegisterWindowMessageA(LPCSTR lpString);
+ WINUSERAPI UINT WINAPI RegisterWindowMessageW(LPCWSTR lpString);
+
+#define SIZE_RESTORED 0
+#define SIZE_MINIMIZED 1
+#define SIZE_MAXIMIZED 2
+#define SIZE_MAXSHOW 3
+#define SIZE_MAXHIDE 4
+
+#define SIZENORMAL SIZE_RESTORED
+#define SIZEICONIC SIZE_MINIMIZED
+#define SIZEFULLSCREEN SIZE_MAXIMIZED
+#define SIZEZOOMSHOW SIZE_MAXSHOW
+#define SIZEZOOMHIDE SIZE_MAXHIDE
+
+ typedef struct tagWINDOWPOS {
+ HWND hwnd;
+ HWND hwndInsertAfter;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ UINT flags;
+ } WINDOWPOS,*LPWINDOWPOS,*PWINDOWPOS;
+
+ typedef struct tagNCCALCSIZE_PARAMS {
+ RECT rgrc[3];
+ PWINDOWPOS lppos;
+ } NCCALCSIZE_PARAMS,*LPNCCALCSIZE_PARAMS;
+
+#define WVR_ALIGNTOP 0x0010
+#define WVR_ALIGNLEFT 0x0020
+#define WVR_ALIGNBOTTOM 0x0040
+#define WVR_ALIGNRIGHT 0x0080
+#define WVR_HREDRAW 0x0100
+#define WVR_VREDRAW 0x0200
+#define WVR_REDRAW (WVR_HREDRAW | WVR_VREDRAW)
+#define WVR_VALIDRECTS 0x0400
+
+#ifndef NOKEYSTATES
+
+#define MK_LBUTTON 0x0001
+#define MK_RBUTTON 0x0002
+#define MK_SHIFT 0x0004
+#define MK_CONTROL 0x0008
+#define MK_MBUTTON 0x0010
+#define MK_XBUTTON1 0x0020
+#define MK_XBUTTON2 0x0040
+#endif
+
+#ifndef NOTRACKMOUSEEVENT
+#define TME_HOVER 0x00000001
+#define TME_LEAVE 0x00000002
+#define TME_NONCLIENT 0x00000010
+#define TME_QUERY 0x40000000
+#define TME_CANCEL 0x80000000
+
+#define HOVER_DEFAULT 0xFFFFFFFF
+#endif
+
+ typedef struct tagTRACKMOUSEEVENT {
+ DWORD cbSize;
+ DWORD dwFlags;
+ HWND hwndTrack;
+ DWORD dwHoverTime;
+ } TRACKMOUSEEVENT,*LPTRACKMOUSEEVENT;
+
+ WINUSERAPI WINBOOL WINAPI TrackMouseEvent(LPTRACKMOUSEEVENT lpEventTrack);
+#endif
+
+#ifndef NOWINSTYLES
+
+#define WS_OVERLAPPED 0x00000000L
+#define WS_POPUP 0x80000000L
+#define WS_CHILD 0x40000000L
+#define WS_MINIMIZE 0x20000000L
+#define WS_VISIBLE 0x10000000L
+#define WS_DISABLED 0x08000000L
+#define WS_CLIPSIBLINGS 0x04000000L
+#define WS_CLIPCHILDREN 0x02000000L
+#define WS_MAXIMIZE 0x01000000L
+#define WS_CAPTION 0x00C00000L
+#define WS_BORDER 0x00800000L
+#define WS_DLGFRAME 0x00400000L
+#define WS_VSCROLL 0x00200000L
+#define WS_HSCROLL 0x00100000L
+#define WS_SYSMENU 0x00080000L
+#define WS_THICKFRAME 0x00040000L
+#define WS_GROUP 0x00020000L
+#define WS_TABSTOP 0x00010000L
+#define WS_MINIMIZEBOX 0x00020000L
+#define WS_MAXIMIZEBOX 0x00010000L
+#define WS_TILED WS_OVERLAPPED
+#define WS_ICONIC WS_MINIMIZE
+#define WS_SIZEBOX WS_THICKFRAME
+#define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW
+#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
+#define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU)
+#define WS_CHILDWINDOW (WS_CHILD)
+
+#define WS_EX_DLGMODALFRAME 0x00000001L
+#define WS_EX_NOPARENTNOTIFY 0x00000004L
+#define WS_EX_TOPMOST 0x00000008L
+#define WS_EX_ACCEPTFILES 0x00000010L
+#define WS_EX_TRANSPARENT 0x00000020L
+#define WS_EX_MDICHILD 0x00000040L
+#define WS_EX_TOOLWINDOW 0x00000080L
+#define WS_EX_WINDOWEDGE 0x00000100L
+#define WS_EX_CLIENTEDGE 0x00000200L
+#define WS_EX_CONTEXTHELP 0x00000400L
+#define WS_EX_RIGHT 0x00001000L
+#define WS_EX_LEFT 0x00000000L
+#define WS_EX_RTLREADING 0x00002000L
+#define WS_EX_LTRREADING 0x00000000L
+#define WS_EX_LEFTSCROLLBAR 0x00004000L
+#define WS_EX_RIGHTSCROLLBAR 0x00000000L
+#define WS_EX_CONTROLPARENT 0x00010000L
+#define WS_EX_STATICEDGE 0x00020000L
+#define WS_EX_APPWINDOW 0x00040000L
+#define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE)
+#define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)
+#define WS_EX_LAYERED 0x00080000
+#define WS_EX_NOINHERITLAYOUT 0x00100000L
+#define WS_EX_LAYOUTRTL 0x00400000L
+#define WS_EX_COMPOSITED 0x02000000L
+#define WS_EX_NOACTIVATE 0x08000000L
+
+#define CS_VREDRAW 0x0001
+#define CS_HREDRAW 0x0002
+#define CS_DBLCLKS 0x0008
+#define CS_OWNDC 0x0020
+#define CS_CLASSDC 0x0040
+#define CS_PARENTDC 0x0080
+#define CS_NOCLOSE 0x0200
+#define CS_SAVEBITS 0x0800
+#define CS_BYTEALIGNCLIENT 0x1000
+#define CS_BYTEALIGNWINDOW 0x2000
+#define CS_GLOBALCLASS 0x4000
+#define CS_IME 0x00010000
+#define CS_DROPSHADOW 0x00020000
+#endif
+
+#define PRF_CHECKVISIBLE 0x00000001L
+#define PRF_NONCLIENT 0x00000002L
+#define PRF_CLIENT 0x00000004L
+#define PRF_ERASEBKGND 0x00000008L
+#define PRF_CHILDREN 0x00000010L
+#define PRF_OWNED 0x00000020L
+
+#define BDR_RAISEDOUTER 0x0001
+#define BDR_SUNKENOUTER 0x0002
+#define BDR_RAISEDINNER 0x0004
+#define BDR_SUNKENINNER 0x0008
+
+#define BDR_OUTER (BDR_RAISEDOUTER | BDR_SUNKENOUTER)
+#define BDR_INNER (BDR_RAISEDINNER | BDR_SUNKENINNER)
+#define BDR_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER)
+#define BDR_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER)
+
+#define EDGE_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER)
+#define EDGE_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER)
+#define EDGE_ETCHED (BDR_SUNKENOUTER | BDR_RAISEDINNER)
+#define EDGE_BUMP (BDR_RAISEDOUTER | BDR_SUNKENINNER)
+
+#define BF_LEFT 0x0001
+#define BF_TOP 0x0002
+#define BF_RIGHT 0x0004
+#define BF_BOTTOM 0x0008
+
+#define BF_TOPLEFT (BF_TOP | BF_LEFT)
+#define BF_TOPRIGHT (BF_TOP | BF_RIGHT)
+#define BF_BOTTOMLEFT (BF_BOTTOM | BF_LEFT)
+#define BF_BOTTOMRIGHT (BF_BOTTOM | BF_RIGHT)
+#define BF_RECT (BF_LEFT | BF_TOP | BF_RIGHT | BF_BOTTOM)
+
+#define BF_DIAGONAL 0x0010
+
+#define BF_DIAGONAL_ENDTOPRIGHT (BF_DIAGONAL | BF_TOP | BF_RIGHT)
+#define BF_DIAGONAL_ENDTOPLEFT (BF_DIAGONAL | BF_TOP | BF_LEFT)
+#define BF_DIAGONAL_ENDBOTTOMLEFT (BF_DIAGONAL | BF_BOTTOM | BF_LEFT)
+#define BF_DIAGONAL_ENDBOTTOMRIGHT (BF_DIAGONAL | BF_BOTTOM | BF_RIGHT)
+
+#define BF_MIDDLE 0x0800
+#define BF_SOFT 0x1000
+#define BF_ADJUST 0x2000
+#define BF_FLAT 0x4000
+#define BF_MONO 0x8000
+
+ WINUSERAPI WINBOOL WINAPI DrawEdge(HDC hdc,LPRECT qrc,UINT edge,UINT grfFlags);
+
+#define DFC_CAPTION 1
+#define DFC_MENU 2
+#define DFC_SCROLL 3
+#define DFC_BUTTON 4
+#define DFC_POPUPMENU 5
+
+#define DFCS_CAPTIONCLOSE 0x0000
+#define DFCS_CAPTIONMIN 0x0001
+#define DFCS_CAPTIONMAX 0x0002
+#define DFCS_CAPTIONRESTORE 0x0003
+#define DFCS_CAPTIONHELP 0x0004
+
+#define DFCS_MENUARROW 0x0000
+#define DFCS_MENUCHECK 0x0001
+#define DFCS_MENUBULLET 0x0002
+#define DFCS_MENUARROWRIGHT 0x0004
+#define DFCS_SCROLLUP 0x0000
+#define DFCS_SCROLLDOWN 0x0001
+#define DFCS_SCROLLLEFT 0x0002
+#define DFCS_SCROLLRIGHT 0x0003
+#define DFCS_SCROLLCOMBOBOX 0x0005
+#define DFCS_SCROLLSIZEGRIP 0x0008
+#define DFCS_SCROLLSIZEGRIPRIGHT 0x0010
+
+#define DFCS_BUTTONCHECK 0x0000
+#define DFCS_BUTTONRADIOIMAGE 0x0001
+#define DFCS_BUTTONRADIOMASK 0x0002
+#define DFCS_BUTTONRADIO 0x0004
+#define DFCS_BUTTON3STATE 0x0008
+#define DFCS_BUTTONPUSH 0x0010
+
+#define DFCS_INACTIVE 0x0100
+#define DFCS_PUSHED 0x0200
+#define DFCS_CHECKED 0x0400
+
+#define DFCS_TRANSPARENT 0x0800
+#define DFCS_HOT 0x1000
+
+#define DFCS_ADJUSTRECT 0x2000
+#define DFCS_FLAT 0x4000
+#define DFCS_MONO 0x8000
+
+ WINUSERAPI WINBOOL WINAPI DrawFrameControl(HDC,LPRECT,UINT,UINT);
+
+#define DC_ACTIVE 0x0001
+#define DC_SMALLCAP 0x0002
+#define DC_ICON 0x0004
+#define DC_TEXT 0x0008
+#define DC_INBUTTON 0x0010
+#define DC_GRADIENT 0x0020
+#define DC_BUTTONS 0x1000
+
+ WINUSERAPI WINBOOL WINAPI DrawCaption(HWND hwnd,HDC hdc,CONST RECT *lprect,UINT flags);
+
+#define IDANI_OPEN 1
+#define IDANI_CAPTION 3
+
+ WINUSERAPI WINBOOL WINAPI DrawAnimatedRects(HWND hwnd,int idAni,CONST RECT *lprcFrom,CONST RECT *lprcTo);
+
+#ifndef NOCLIPBOARD
+
+#define CF_TEXT 1
+#define CF_BITMAP 2
+#define CF_METAFILEPICT 3
+#define CF_SYLK 4
+#define CF_DIF 5
+#define CF_TIFF 6
+#define CF_OEMTEXT 7
+#define CF_DIB 8
+#define CF_PALETTE 9
+#define CF_PENDATA 10
+#define CF_RIFF 11
+#define CF_WAVE 12
+#define CF_UNICODETEXT 13
+#define CF_ENHMETAFILE 14
+#define CF_HDROP 15
+#define CF_LOCALE 16
+#define CF_DIBV5 17
+#define CF_MAX 18
+
+#define CF_OWNERDISPLAY 0x0080
+#define CF_DSPTEXT 0x0081
+#define CF_DSPBITMAP 0x0082
+#define CF_DSPMETAFILEPICT 0x0083
+#define CF_DSPENHMETAFILE 0x008E
+
+#define CF_PRIVATEFIRST 0x0200
+#define CF_PRIVATELAST 0x02FF
+
+#define CF_GDIOBJFIRST 0x0300
+#define CF_GDIOBJLAST 0x03FF
+#endif
+
+#define FVIRTKEY TRUE
+#define FNOINVERT 0x02
+#define FSHIFT 0x04
+#define FCONTROL 0x08
+#define FALT 0x10
+
+ typedef struct tagACCEL {
+ BYTE fVirt;
+ WORD key;
+ WORD cmd;
+ } ACCEL,*LPACCEL;
+
+ typedef struct tagPAINTSTRUCT {
+ HDC hdc;
+ WINBOOL fErase;
+ RECT rcPaint;
+ WINBOOL fRestore;
+ WINBOOL fIncUpdate;
+ BYTE rgbReserved[32];
+ } PAINTSTRUCT,*PPAINTSTRUCT,*NPPAINTSTRUCT,*LPPAINTSTRUCT;
+
+ typedef struct tagCREATESTRUCTA {
+ LPVOID lpCreateParams;
+ HINSTANCE hInstance;
+ HMENU hMenu;
+ HWND hwndParent;
+ int cy;
+ int cx;
+ int y;
+ int x;
+ LONG style;
+ LPCSTR lpszName;
+ LPCSTR lpszClass;
+ DWORD dwExStyle;
+ } CREATESTRUCTA,*LPCREATESTRUCTA;
+
+ typedef struct tagCREATESTRUCTW {
+ LPVOID lpCreateParams;
+ HINSTANCE hInstance;
+ HMENU hMenu;
+ HWND hwndParent;
+ int cy;
+ int cx;
+ int y;
+ int x;
+ LONG style;
+ LPCWSTR lpszName;
+ LPCWSTR lpszClass;
+ DWORD dwExStyle;
+ } CREATESTRUCTW,*LPCREATESTRUCTW;
+
+#ifdef UNICODE
+ typedef CREATESTRUCTW CREATESTRUCT;
+ typedef LPCREATESTRUCTW LPCREATESTRUCT;
+#else
+ typedef CREATESTRUCTA CREATESTRUCT;
+ typedef LPCREATESTRUCTA LPCREATESTRUCT;
+#endif
+
+ typedef struct tagWINDOWPLACEMENT {
+ UINT length;
+ UINT flags;
+ UINT showCmd;
+ POINT ptMinPosition;
+ POINT ptMaxPosition;
+ RECT rcNormalPosition;
+ } WINDOWPLACEMENT;
+ typedef WINDOWPLACEMENT *PWINDOWPLACEMENT,*LPWINDOWPLACEMENT;
+
+#define WPF_SETMINPOSITION 0x0001
+#define WPF_RESTORETOMAXIMIZED 0x0002
+#define WPF_ASYNCWINDOWPLACEMENT 0x0004
+
+ typedef struct tagNMHDR {
+ HWND hwndFrom;
+ UINT_PTR idFrom;
+ UINT code;
+ } NMHDR;
+
+ typedef NMHDR *LPNMHDR;
+
+ typedef struct tagSTYLESTRUCT {
+ DWORD styleOld;
+ DWORD styleNew;
+ } STYLESTRUCT,*LPSTYLESTRUCT;
+
+#define ODT_MENU 1
+#define ODT_LISTBOX 2
+#define ODT_COMBOBOX 3
+#define ODT_BUTTON 4
+#define ODT_STATIC 5
+
+#define ODA_DRAWENTIRE 0x0001
+#define ODA_SELECT 0x0002
+#define ODA_FOCUS 0x0004
+
+#define ODS_SELECTED 0x0001
+#define ODS_GRAYED 0x0002
+#define ODS_DISABLED 0x0004
+#define ODS_CHECKED 0x0008
+#define ODS_FOCUS 0x0010
+#define ODS_DEFAULT 0x0020
+#define ODS_COMBOBOXEDIT 0x1000
+#define ODS_HOTLIGHT 0x0040
+#define ODS_INACTIVE 0x0080
+#define ODS_NOACCEL 0x0100
+#define ODS_NOFOCUSRECT 0x0200
+
+ typedef struct tagMEASUREITEMSTRUCT {
+ UINT CtlType;
+ UINT CtlID;
+ UINT itemID;
+ UINT itemWidth;
+ UINT itemHeight;
+ ULONG_PTR itemData;
+ } MEASUREITEMSTRUCT,*PMEASUREITEMSTRUCT,*LPMEASUREITEMSTRUCT;
+
+ typedef struct tagDRAWITEMSTRUCT {
+ UINT CtlType;
+ UINT CtlID;
+ UINT itemID;
+ UINT itemAction;
+ UINT itemState;
+ HWND hwndItem;
+ HDC hDC;
+ RECT rcItem;
+ ULONG_PTR itemData;
+ } DRAWITEMSTRUCT,*PDRAWITEMSTRUCT,*LPDRAWITEMSTRUCT;
+
+ typedef struct tagDELETEITEMSTRUCT {
+ UINT CtlType;
+ UINT CtlID;
+ UINT itemID;
+ HWND hwndItem;
+ ULONG_PTR itemData;
+ } DELETEITEMSTRUCT,*PDELETEITEMSTRUCT,*LPDELETEITEMSTRUCT;
+
+ typedef struct tagCOMPAREITEMSTRUCT {
+ UINT CtlType;
+ UINT CtlID;
+ HWND hwndItem;
+ UINT itemID1;
+ ULONG_PTR itemData1;
+ UINT itemID2;
+ ULONG_PTR itemData2;
+ DWORD dwLocaleId;
+ } COMPAREITEMSTRUCT,*PCOMPAREITEMSTRUCT,*LPCOMPAREITEMSTRUCT;
+
+#ifndef NOMSG
+#ifdef UNICODE
+#define GetMessage GetMessageW
+#define DispatchMessage DispatchMessageW
+#define PeekMessage PeekMessageW
+#else
+#define GetMessage GetMessageA
+#define DispatchMessage DispatchMessageA
+#define PeekMessage PeekMessageA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI GetMessageA(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);
+ WINUSERAPI WINBOOL WINAPI GetMessageW(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);
+ WINUSERAPI WINBOOL WINAPI TranslateMessage(CONST MSG *lpMsg);
+ WINUSERAPI LRESULT WINAPI DispatchMessageA(CONST MSG *lpMsg);
+ WINUSERAPI LRESULT WINAPI DispatchMessageW(CONST MSG *lpMsg);
+ WINUSERAPI WINBOOL WINAPI SetMessageQueue(int cMessagesMax);
+ WINUSERAPI WINBOOL WINAPI PeekMessageA(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);
+ WINUSERAPI WINBOOL WINAPI PeekMessageW(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);
+
+#define PM_NOREMOVE 0x0000
+#define PM_REMOVE 0x0001
+#define PM_NOYIELD 0x0002
+#define PM_QS_INPUT (QS_INPUT << 16)
+#define PM_QS_POSTMESSAGE ((QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER) << 16)
+#define PM_QS_PAINT (QS_PAINT << 16)
+#define PM_QS_SENDMESSAGE (QS_SENDMESSAGE << 16)
+#endif
+
+ WINUSERAPI WINBOOL WINAPI RegisterHotKey(HWND hWnd,int id,UINT fsModifiers,UINT vk);
+ WINUSERAPI WINBOOL WINAPI UnregisterHotKey(HWND hWnd,int id);
+
+#define MOD_ALT 0x0001
+#define MOD_CONTROL 0x0002
+#define MOD_SHIFT 0x0004
+#define MOD_WIN 0x0008
+
+#define IDHOT_SNAPWINDOW (-1)
+#define IDHOT_SNAPDESKTOP (-2)
+
+#ifdef WIN_INTERNAL
+#ifndef LSTRING
+#define NOLSTRING
+#endif
+#ifndef LFILEIO
+#define NOLFILEIO
+#endif
+#endif
+
+#define ENDSESSION_LOGOFF 0x80000000
+
+#define EWX_LOGOFF 0
+#define EWX_SHUTDOWN 0x00000001
+#define EWX_REBOOT 0x00000002
+#define EWX_FORCE 0x00000004
+#define EWX_POWEROFF 0x00000008
+#define EWX_FORCEIFHUNG 0x00000010
+
+#define ExitWindows(dwReserved,Code) ExitWindowsEx(EWX_LOGOFF,0xFFFFFFFF)
+
+#ifdef UNICODE
+#define SendMessage SendMessageW
+#define SendMessageTimeout SendMessageTimeoutW
+#define SendNotifyMessage SendNotifyMessageW
+#define SendMessageCallback SendMessageCallbackW
+#else
+#define SendMessage SendMessageA
+#define SendMessageTimeout SendMessageTimeoutA
+#define SendNotifyMessage SendNotifyMessageA
+#define SendMessageCallback SendMessageCallbackA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI ExitWindowsEx(UINT uFlags,DWORD dwReason);
+ WINUSERAPI WINBOOL WINAPI SwapMouseButton(WINBOOL fSwap);
+ WINUSERAPI DWORD WINAPI GetMessagePos(VOID);
+ WINUSERAPI LONG WINAPI GetMessageTime(VOID);
+ WINUSERAPI LPARAM WINAPI GetMessageExtraInfo(VOID);
+ WINUSERAPI WINBOOL WINAPI IsWow64Message(VOID);
+ WINUSERAPI LPARAM WINAPI SetMessageExtraInfo(LPARAM lParam);
+ WINUSERAPI LRESULT WINAPI SendMessageA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI LRESULT WINAPI SendMessageW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI LRESULT WINAPI SendMessageTimeoutA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam,UINT fuFlags,UINT uTimeout,PDWORD_PTR lpdwResult);
+ WINUSERAPI LRESULT WINAPI SendMessageTimeoutW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam,UINT fuFlags,UINT uTimeout,PDWORD_PTR lpdwResult);
+ WINUSERAPI WINBOOL WINAPI SendNotifyMessageA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI SendNotifyMessageW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI SendMessageCallbackA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam,SENDASYNCPROC lpResultCallBack,ULONG_PTR dwData);
+ WINUSERAPI WINBOOL WINAPI SendMessageCallbackW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam,SENDASYNCPROC lpResultCallBack,ULONG_PTR dwData);
+
+ typedef struct {
+ UINT cbSize;
+ HDESK hdesk;
+ HWND hwnd;
+ LUID luid;
+ } BSMINFO,*PBSMINFO;
+
+#ifdef UNICODE
+#define BroadcastSystemMessageEx BroadcastSystemMessageExW
+#define BroadcastSystemMessage BroadcastSystemMessageW
+#else
+#define BroadcastSystemMessageEx BroadcastSystemMessageExA
+#define BroadcastSystemMessage BroadcastSystemMessageA
+#endif
+
+ WINUSERAPI long WINAPI BroadcastSystemMessageExA(DWORD flags,LPDWORD lpInfo,UINT Msg,WPARAM wParam,LPARAM lParam,PBSMINFO pbsmInfo);
+ WINUSERAPI long WINAPI BroadcastSystemMessageExW(DWORD flags,LPDWORD lpInfo,UINT Msg,WPARAM wParam,LPARAM lParam,PBSMINFO pbsmInfo);
+ WINUSERAPI long WINAPI BroadcastSystemMessageA(DWORD flags,LPDWORD lpInfo,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI long WINAPI BroadcastSystemMessageW(DWORD flags,LPDWORD lpInfo,UINT Msg,WPARAM wParam,LPARAM lParam);
+
+#define BSM_ALLCOMPONENTS 0x00000000
+#define BSM_VXDS 0x00000001
+#define BSM_NETDRIVER 0x00000002
+#define BSM_INSTALLABLEDRIVERS 0x00000004
+#define BSM_APPLICATIONS 0x00000008
+#define BSM_ALLDESKTOPS 0x00000010
+
+#define BSF_QUERY 0x00000001
+#define BSF_IGNORECURRENTTASK 0x00000002
+#define BSF_FLUSHDISK 0x00000004
+#define BSF_NOHANG 0x00000008
+#define BSF_POSTMESSAGE 0x00000010
+#define BSF_FORCEIFHUNG 0x00000020
+#define BSF_NOTIMEOUTIFNOTHUNG 0x00000040
+#define BSF_ALLOWSFW 0x00000080
+#define BSF_SENDNOTIFYMESSAGE 0x00000100
+#define BSF_RETURNHDESK 0x00000200
+#define BSF_LUID 0x00000400
+
+#define BROADCAST_QUERY_DENY 0x424D5144
+
+ typedef PVOID HDEVNOTIFY;
+ typedef HDEVNOTIFY *PHDEVNOTIFY;
+
+#define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000
+#define DEVICE_NOTIFY_SERVICE_HANDLE 0x00000001
+#define DEVICE_NOTIFY_ALL_INTERFACE_CLASSES 0x00000004
+
+#ifdef UNICODE
+#define RegisterDeviceNotification RegisterDeviceNotificationW
+#define PostMessage PostMessageW
+#define PostThreadMessage PostThreadMessageW
+#define PostAppMessage PostAppMessageW
+#define DefWindowProc DefWindowProcW
+#define CallWindowProc CallWindowProcW
+#define RegisterClass RegisterClassW
+#define UnregisterClass UnregisterClassW
+#define GetClassInfo GetClassInfoW
+#define RegisterClassEx RegisterClassExW
+#define GetClassInfoEx GetClassInfoExW
+#else
+#define RegisterDeviceNotification RegisterDeviceNotificationA
+#define PostMessage PostMessageA
+#define PostThreadMessage PostThreadMessageA
+#define PostAppMessage PostAppMessageA
+#define DefWindowProc DefWindowProcA
+#define CallWindowProc CallWindowProcA
+#define RegisterClass RegisterClassA
+#define UnregisterClass UnregisterClassA
+#define GetClassInfo GetClassInfoA
+#define RegisterClassEx RegisterClassExA
+#define GetClassInfoEx GetClassInfoExA
+#endif
+
+ WINUSERAPI HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hRecipient,LPVOID NotificationFilter,DWORD Flags);
+ WINUSERAPI HDEVNOTIFY WINAPI RegisterDeviceNotificationW(HANDLE hRecipient,LPVOID NotificationFilter,DWORD Flags);
+ WINUSERAPI WINBOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY Handle);
+ WINUSERAPI WINBOOL WINAPI PostMessageA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI PostMessageW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI PostThreadMessageA(DWORD idThread,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI PostThreadMessageW(DWORD idThread,UINT Msg,WPARAM wParam,LPARAM lParam);
+#define PostAppMessageA(idThread,wMsg,wParam,lParam) PostThreadMessageA((DWORD)idThread,wMsg,wParam,lParam)
+#define PostAppMessageW(idThread,wMsg,wParam,lParam) PostThreadMessageW((DWORD)idThread,wMsg,wParam,lParam)
+
+#define HWND_BROADCAST ((HWND)0xffff)
+#define HWND_MESSAGE ((HWND)-3)
+
+ WINUSERAPI WINBOOL WINAPI AttachThreadInput(DWORD idAttach,DWORD idAttachTo,WINBOOL fAttach);
+ WINUSERAPI WINBOOL WINAPI ReplyMessage(LRESULT lResult);
+ WINUSERAPI WINBOOL WINAPI WaitMessage(VOID);
+ WINUSERAPI DWORD WINAPI WaitForInputIdle(HANDLE hProcess,DWORD dwMilliseconds);
+ WINUSERAPI LRESULT WINAPI DefWindowProcA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI LRESULT WINAPI DefWindowProcW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI VOID WINAPI PostQuitMessage(int nExitCode);
+ WINUSERAPI LRESULT WINAPI CallWindowProcA(WNDPROC lpPrevWndFunc,HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI LRESULT WINAPI CallWindowProcW(WNDPROC lpPrevWndFunc,HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI InSendMessage(VOID);
+ WINUSERAPI DWORD WINAPI InSendMessageEx(LPVOID lpReserved);
+
+#define ISMEX_NOSEND 0x00000000
+#define ISMEX_SEND 0x00000001
+#define ISMEX_NOTIFY 0x00000002
+#define ISMEX_CALLBACK 0x00000004
+#define ISMEX_REPLIED 0x00000008
+
+ WINUSERAPI UINT WINAPI GetDoubleClickTime(VOID);
+ WINUSERAPI WINBOOL WINAPI SetDoubleClickTime(UINT);
+ WINUSERAPI ATOM WINAPI RegisterClassA(CONST WNDCLASSA *lpWndClass);
+ WINUSERAPI ATOM WINAPI RegisterClassW(CONST WNDCLASSW *lpWndClass);
+ WINUSERAPI WINBOOL WINAPI UnregisterClassA(LPCSTR lpClassName,HINSTANCE hInstance);
+ WINUSERAPI WINBOOL WINAPI UnregisterClassW(LPCWSTR lpClassName,HINSTANCE hInstance);
+ WINUSERAPI WINBOOL WINAPI GetClassInfoA(HINSTANCE hInstance,LPCSTR lpClassName,LPWNDCLASSA lpWndClass);
+ WINUSERAPI WINBOOL WINAPI GetClassInfoW(HINSTANCE hInstance,LPCWSTR lpClassName,LPWNDCLASSW lpWndClass);
+ WINUSERAPI ATOM WINAPI RegisterClassExA(CONST WNDCLASSEXA *);
+ WINUSERAPI ATOM WINAPI RegisterClassExW(CONST WNDCLASSEXW *);
+ WINUSERAPI WINBOOL WINAPI GetClassInfoExA(HINSTANCE hInstance,LPCSTR lpszClass,LPWNDCLASSEXA lpwcx);
+ WINUSERAPI WINBOOL WINAPI GetClassInfoExW(HINSTANCE hInstance,LPCWSTR lpszClass,LPWNDCLASSEXW lpwcx);
+
+#define CW_USEDEFAULT ((int)0x80000000)
+
+#define HWND_DESKTOP ((HWND)0)
+
+ typedef BOOLEAN (WINAPI *PREGISTERCLASSNAMEW)(LPCWSTR);
+
+#ifdef UNICODE
+#define CreateWindowEx CreateWindowExW
+#define CreateWindow CreateWindowW
+#else
+#define CreateWindowEx CreateWindowExA
+#define CreateWindow CreateWindowA
+#endif
+
+ WINUSERAPI HWND WINAPI CreateWindowExA(DWORD dwExStyle,LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam);
+ WINUSERAPI HWND WINAPI CreateWindowExW(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam);
+#define CreateWindowA(lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam) CreateWindowExA(0L,lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam)
+#define CreateWindowW(lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam) CreateWindowExW(0L,lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam)
+ WINUSERAPI WINBOOL WINAPI IsWindow(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI IsMenu(HMENU hMenu);
+ WINUSERAPI WINBOOL WINAPI IsChild(HWND hWndParent,HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI DestroyWindow(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI ShowWindow(HWND hWnd,int nCmdShow);
+ WINUSERAPI WINBOOL WINAPI AnimateWindow(HWND hWnd,DWORD dwTime,DWORD dwFlags);
+
+#if defined(_WINGDI_) && !defined(NOGDI)
+ WINUSERAPI WINBOOL WINAPI UpdateLayeredWindow(HWND hWnd,HDC hdcDst,POINT *pptDst,SIZE *psize,HDC hdcSrc,POINT *pptSrc,COLORREF crKey,BLENDFUNCTION *pblend,DWORD dwFlags);
+
+ typedef struct tagUPDATELAYEREDWINDOWINFO {
+ DWORD cbSize;
+ HDC hdcDst;
+ POINT CONST *pptDst;
+ SIZE CONST *psize;
+ HDC hdcSrc;
+ POINT CONST *pptSrc;
+ COLORREF crKey;
+ BLENDFUNCTION CONST *pblend;
+ DWORD dwFlags;
+ RECT CONST *prcDirty;
+ } UPDATELAYEREDWINDOWINFO,*PUPDATELAYEREDWINDOWINFO;
+
+ WINUSERAPI WINBOOL WINAPI UpdateLayeredWindowIndirect(HWND hWnd,UPDATELAYEREDWINDOWINFO CONST *pULWInfo);
+ WINUSERAPI WINBOOL WINAPI GetLayeredWindowAttributes(HWND hwnd,COLORREF *pcrKey,BYTE *pbAlpha,DWORD *pdwFlags);
+
+#define PW_CLIENTONLY 0x00000001
+
+ WINUSERAPI WINBOOL WINAPI PrintWindow(HWND hwnd,HDC hdcBlt,UINT nFlags);
+ WINUSERAPI WINBOOL WINAPI SetLayeredWindowAttributes(HWND hwnd,COLORREF crKey,BYTE bAlpha,DWORD dwFlags);
+
+#define LWA_COLORKEY 0x00000001
+#define LWA_ALPHA 0x00000002
+
+#define ULW_COLORKEY 0x00000001
+#define ULW_ALPHA 0x00000002
+#define ULW_OPAQUE 0x00000004
+
+#define ULW_EX_NORESIZE 0x00000008
+
+ WINUSERAPI WINBOOL WINAPI ShowWindowAsync(HWND hWnd,int nCmdShow);
+ WINUSERAPI WINBOOL WINAPI FlashWindow(HWND hWnd,WINBOOL bInvert);
+
+ typedef struct {
+ UINT cbSize;
+ HWND hwnd;
+ DWORD dwFlags;
+ UINT uCount;
+ DWORD dwTimeout;
+ } FLASHWINFO,*PFLASHWINFO;
+
+ WINUSERAPI WINBOOL WINAPI FlashWindowEx(PFLASHWINFO pfwi);
+
+#define FLASHW_STOP 0
+#define FLASHW_CAPTION 0x00000001
+#define FLASHW_TRAY 0x00000002
+#define FLASHW_ALL (FLASHW_CAPTION | FLASHW_TRAY)
+#define FLASHW_TIMER 0x00000004
+#define FLASHW_TIMERNOFG 0x0000000C
+
+ WINUSERAPI WINBOOL WINAPI ShowOwnedPopups(HWND hWnd,WINBOOL fShow);
+ WINUSERAPI WINBOOL WINAPI OpenIcon(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI CloseWindow(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI MoveWindow(HWND hWnd,int X,int Y,int nWidth,int nHeight,WINBOOL bRepaint);
+ WINUSERAPI WINBOOL WINAPI SetWindowPos(HWND hWnd,HWND hWndInsertAfter,int X,int Y,int cx,int cy,UINT uFlags);
+ WINUSERAPI WINBOOL WINAPI GetWindowPlacement(HWND hWnd,WINDOWPLACEMENT *lpwndpl);
+ WINUSERAPI WINBOOL WINAPI SetWindowPlacement(HWND hWnd,CONST WINDOWPLACEMENT *lpwndpl);
+
+#ifndef NODEFERWINDOWPOS
+ WINUSERAPI HDWP WINAPI BeginDeferWindowPos(int nNumWindows);
+ WINUSERAPI HDWP WINAPI DeferWindowPos(HDWP hWinPosInfo,HWND hWnd,HWND hWndInsertAfter,int x,int y,int cx,int cy,UINT uFlags);
+ WINUSERAPI WINBOOL WINAPI EndDeferWindowPos(HDWP hWinPosInfo);
+#endif
+
+ WINUSERAPI WINBOOL WINAPI IsWindowVisible(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI IsIconic(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI AnyPopup(VOID);
+ WINUSERAPI WINBOOL WINAPI BringWindowToTop(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI IsZoomed(HWND hWnd);
+
+#define SWP_NOSIZE 0x0001
+#define SWP_NOMOVE 0x0002
+#define SWP_NOZORDER 0x0004
+#define SWP_NOREDRAW 0x0008
+#define SWP_NOACTIVATE 0x0010
+#define SWP_FRAMECHANGED 0x0020
+#define SWP_SHOWWINDOW 0x0040
+#define SWP_HIDEWINDOW 0x0080
+#define SWP_NOCOPYBITS 0x0100
+#define SWP_NOOWNERZORDER 0x0200
+#define SWP_NOSENDCHANGING 0x0400
+
+#define SWP_DRAWFRAME SWP_FRAMECHANGED
+#define SWP_NOREPOSITION SWP_NOOWNERZORDER
+#define SWP_DEFERERASE 0x2000
+#define SWP_ASYNCWINDOWPOS 0x4000
+
+#define HWND_TOP ((HWND)0)
+#define HWND_BOTTOM ((HWND)1)
+#define HWND_TOPMOST ((HWND)-1)
+#define HWND_NOTOPMOST ((HWND)-2)
+
+#ifndef NOCTLMGR
+
+#include <pshpack2.h>
+
+ typedef struct {
+ DWORD style;
+ DWORD dwExtendedStyle;
+ WORD cdit;
+ short x;
+ short y;
+ short cx;
+ short cy;
+ } DLGTEMPLATE;
+
+ typedef DLGTEMPLATE *LPDLGTEMPLATEA;
+ typedef DLGTEMPLATE *LPDLGTEMPLATEW;
+
+#ifdef UNICODE
+ typedef LPDLGTEMPLATEW LPDLGTEMPLATE;
+#else
+ typedef LPDLGTEMPLATEA LPDLGTEMPLATE;
+#endif
+
+ typedef CONST DLGTEMPLATE *LPCDLGTEMPLATEA;
+ typedef CONST DLGTEMPLATE *LPCDLGTEMPLATEW;
+
+#ifdef UNICODE
+ typedef LPCDLGTEMPLATEW LPCDLGTEMPLATE;
+#else
+ typedef LPCDLGTEMPLATEA LPCDLGTEMPLATE;
+#endif
+
+ typedef struct {
+ DWORD style;
+ DWORD dwExtendedStyle;
+ short x;
+ short y;
+ short cx;
+ short cy;
+ WORD id;
+ } DLGITEMTEMPLATE;
+
+ typedef DLGITEMTEMPLATE *PDLGITEMTEMPLATEA;
+ typedef DLGITEMTEMPLATE *PDLGITEMTEMPLATEW;
+
+#ifdef UNICODE
+ typedef PDLGITEMTEMPLATEW PDLGITEMTEMPLATE;
+#else
+ typedef PDLGITEMTEMPLATEA PDLGITEMTEMPLATE;
+#endif
+
+ typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEA;
+ typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEW;
+
+#ifdef UNICODE
+ typedef LPDLGITEMTEMPLATEW LPDLGITEMTEMPLATE;
+#else
+ typedef LPDLGITEMTEMPLATEA LPDLGITEMTEMPLATE;
+#endif
+
+#include <poppack.h>
+
+#ifdef UNICODE
+#define CreateDialogParam CreateDialogParamW
+#define CreateDialogIndirectParam CreateDialogIndirectParamW
+#define CreateDialog CreateDialogW
+#define CreateDialogIndirect CreateDialogIndirectW
+#define DialogBoxParam DialogBoxParamW
+#define DialogBoxIndirectParam DialogBoxIndirectParamW
+#define DialogBox DialogBoxW
+#define DialogBoxIndirect DialogBoxIndirectW
+#define SetDlgItemText SetDlgItemTextW
+#define GetDlgItemText GetDlgItemTextW
+#define SendDlgItemMessage SendDlgItemMessageW
+#define DefDlgProc DefDlgProcW
+#else
+#define CreateDialogParam CreateDialogParamA
+#define CreateDialogIndirectParam CreateDialogIndirectParamA
+#define CreateDialog CreateDialogA
+#define CreateDialogIndirect CreateDialogIndirectA
+#define DialogBoxParam DialogBoxParamA
+#define DialogBoxIndirectParam DialogBoxIndirectParamA
+#define DialogBox DialogBoxA
+#define DialogBoxIndirect DialogBoxIndirectA
+#define SetDlgItemText SetDlgItemTextA
+#define GetDlgItemText GetDlgItemTextA
+#define SendDlgItemMessage SendDlgItemMessageA
+#define DefDlgProc DefDlgProcA
+#endif
+
+ WINUSERAPI HWND WINAPI CreateDialogParamA(HINSTANCE hInstance,LPCSTR lpTemplateName,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam);
+ WINUSERAPI HWND WINAPI CreateDialogParamW(HINSTANCE hInstance,LPCWSTR lpTemplateName,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam);
+ WINUSERAPI HWND WINAPI CreateDialogIndirectParamA(HINSTANCE hInstance,LPCDLGTEMPLATEA lpTemplate,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam);
+ WINUSERAPI HWND WINAPI CreateDialogIndirectParamW(HINSTANCE hInstance,LPCDLGTEMPLATEW lpTemplate,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam);
+#define CreateDialogA(hInstance,lpName,hWndParent,lpDialogFunc) CreateDialogParamA(hInstance,lpName,hWndParent,lpDialogFunc,0L)
+#define CreateDialogW(hInstance,lpName,hWndParent,lpDialogFunc) CreateDialogParamW(hInstance,lpName,hWndParent,lpDialogFunc,0L)
+#define CreateDialogIndirectA(hInstance,lpTemplate,hWndParent,lpDialogFunc) CreateDialogIndirectParamA(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L)
+#define CreateDialogIndirectW(hInstance,lpTemplate,hWndParent,lpDialogFunc) CreateDialogIndirectParamW(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L)
+ WINUSERAPI INT_PTR WINAPI DialogBoxParamA(HINSTANCE hInstance,LPCSTR lpTemplateName,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam);
+ WINUSERAPI INT_PTR WINAPI DialogBoxParamW(HINSTANCE hInstance,LPCWSTR lpTemplateName,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam);
+ WINUSERAPI INT_PTR WINAPI DialogBoxIndirectParamA(HINSTANCE hInstance,LPCDLGTEMPLATEA hDialogTemplate,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam);
+ WINUSERAPI INT_PTR WINAPI DialogBoxIndirectParamW(HINSTANCE hInstance,LPCDLGTEMPLATEW hDialogTemplate,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam);
+#define DialogBoxA(hInstance,lpTemplate,hWndParent,lpDialogFunc) DialogBoxParamA(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L)
+#define DialogBoxW(hInstance,lpTemplate,hWndParent,lpDialogFunc) DialogBoxParamW(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L)
+#define DialogBoxIndirectA(hInstance,lpTemplate,hWndParent,lpDialogFunc) DialogBoxIndirectParamA(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L)
+#define DialogBoxIndirectW(hInstance,lpTemplate,hWndParent,lpDialogFunc) DialogBoxIndirectParamW(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L)
+ WINUSERAPI WINBOOL WINAPI EndDialog(HWND hDlg,INT_PTR nResult);
+ WINUSERAPI HWND WINAPI GetDlgItem(HWND hDlg,int nIDDlgItem);
+ WINUSERAPI WINBOOL WINAPI SetDlgItemInt(HWND hDlg,int nIDDlgItem,UINT uValue,WINBOOL bSigned);
+ WINUSERAPI UINT WINAPI GetDlgItemInt(HWND hDlg,int nIDDlgItem,WINBOOL *lpTranslated,WINBOOL bSigned);
+ WINUSERAPI WINBOOL WINAPI SetDlgItemTextA(HWND hDlg,int nIDDlgItem,LPCSTR lpString);
+ WINUSERAPI WINBOOL WINAPI SetDlgItemTextW(HWND hDlg,int nIDDlgItem,LPCWSTR lpString);
+ WINUSERAPI UINT WINAPI GetDlgItemTextA(HWND hDlg,int nIDDlgItem,LPSTR lpString,int cchMax);
+ WINUSERAPI UINT WINAPI GetDlgItemTextW(HWND hDlg,int nIDDlgItem,LPWSTR lpString,int cchMax);
+ WINUSERAPI WINBOOL WINAPI CheckDlgButton(HWND hDlg,int nIDButton,UINT uCheck);
+ WINUSERAPI WINBOOL WINAPI CheckRadioButton(HWND hDlg,int nIDFirstButton,int nIDLastButton,int nIDCheckButton);
+ WINUSERAPI UINT WINAPI IsDlgButtonChecked(HWND hDlg,int nIDButton);
+ WINUSERAPI LRESULT WINAPI SendDlgItemMessageA(HWND hDlg,int nIDDlgItem,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI LRESULT WINAPI SendDlgItemMessageW(HWND hDlg,int nIDDlgItem,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI HWND WINAPI GetNextDlgGroupItem(HWND hDlg,HWND hCtl,WINBOOL bPrevious);
+ WINUSERAPI HWND WINAPI GetNextDlgTabItem(HWND hDlg,HWND hCtl,WINBOOL bPrevious);
+ WINUSERAPI int WINAPI GetDlgCtrlID(HWND hWnd);
+ WINUSERAPI long WINAPI GetDialogBaseUnits(VOID);
+ WINUSERAPI LRESULT WINAPI DefDlgProcA(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI LRESULT WINAPI DefDlgProcW(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam);
+
+#define DLGWINDOWEXTRA 30
+#endif
+
+#ifndef NOMSG
+
+#ifdef UNICODE
+#define CallMsgFilter CallMsgFilterW
+#else
+#define CallMsgFilter CallMsgFilterA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI CallMsgFilterA(LPMSG lpMsg,int nCode);
+ WINUSERAPI WINBOOL WINAPI CallMsgFilterW(LPMSG lpMsg,int nCode);
+#endif
+
+#ifndef NOCLIPBOARD
+
+#ifdef UNICODE
+#define RegisterClipboardFormat RegisterClipboardFormatW
+#define GetClipboardFormatName GetClipboardFormatNameW
+#else
+#define RegisterClipboardFormat RegisterClipboardFormatA
+#define GetClipboardFormatName GetClipboardFormatNameA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI OpenClipboard(HWND hWndNewOwner);
+ WINUSERAPI WINBOOL WINAPI CloseClipboard(VOID);
+ WINUSERAPI DWORD WINAPI GetClipboardSequenceNumber(VOID);
+ WINUSERAPI HWND WINAPI GetClipboardOwner(VOID);
+ WINUSERAPI HWND WINAPI SetClipboardViewer(HWND hWndNewViewer);
+ WINUSERAPI HWND WINAPI GetClipboardViewer(VOID);
+ WINUSERAPI WINBOOL WINAPI ChangeClipboardChain(HWND hWndRemove,HWND hWndNewNext);
+ WINUSERAPI HANDLE WINAPI SetClipboardData(UINT uFormat,HANDLE hMem);
+ WINUSERAPI HANDLE WINAPI GetClipboardData(UINT uFormat);
+ WINUSERAPI UINT WINAPI RegisterClipboardFormatA(LPCSTR lpszFormat);
+ WINUSERAPI UINT WINAPI RegisterClipboardFormatW(LPCWSTR lpszFormat);
+ WINUSERAPI int WINAPI CountClipboardFormats(VOID);
+ WINUSERAPI UINT WINAPI EnumClipboardFormats(UINT format);
+ WINUSERAPI int WINAPI GetClipboardFormatNameA(UINT format,LPSTR lpszFormatName,int cchMaxCount);
+ WINUSERAPI int WINAPI GetClipboardFormatNameW(UINT format,LPWSTR lpszFormatName,int cchMaxCount);
+ WINUSERAPI WINBOOL WINAPI EmptyClipboard(VOID);
+ WINUSERAPI WINBOOL WINAPI IsClipboardFormatAvailable(UINT format);
+ WINUSERAPI int WINAPI GetPriorityClipboardFormat(UINT *paFormatPriorityList,int cFormats);
+ WINUSERAPI HWND WINAPI GetOpenClipboardWindow(VOID);
+#endif
+
+#ifdef UNICODE
+#define CharToOem CharToOemW
+#define OemToChar OemToCharW
+#define CharToOemBuff CharToOemBuffW
+#define OemToCharBuff OemToCharBuffW
+#define CharUpper CharUpperW
+#define CharUpperBuff CharUpperBuffW
+#define CharLower CharLowerW
+#define CharLowerBuff CharLowerBuffW
+#define CharNext CharNextW
+#define CharPrev CharPrevW
+#else
+#define CharToOem CharToOemA
+#define OemToChar OemToCharA
+#define CharToOemBuff CharToOemBuffA
+#define OemToCharBuff OemToCharBuffA
+#define CharUpper CharUpperA
+#define CharUpperBuff CharUpperBuffA
+#define CharLower CharLowerA
+#define CharLowerBuff CharLowerBuffA
+#define CharNext CharNextA
+#define CharPrev CharPrevA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI CharToOemA(LPCSTR lpszSrc,LPSTR lpszDst);
+ WINUSERAPI WINBOOL WINAPI CharToOemW(LPCWSTR lpszSrc,LPSTR lpszDst);
+ WINUSERAPI WINBOOL WINAPI OemToCharA(LPCSTR lpszSrc,LPSTR lpszDst);
+ WINUSERAPI WINBOOL WINAPI OemToCharW(LPCSTR lpszSrc,LPWSTR lpszDst);
+ WINUSERAPI WINBOOL WINAPI CharToOemBuffA(LPCSTR lpszSrc,LPSTR lpszDst,DWORD cchDstLength);
+ WINUSERAPI WINBOOL WINAPI CharToOemBuffW(LPCWSTR lpszSrc,LPSTR lpszDst,DWORD cchDstLength);
+ WINUSERAPI WINBOOL WINAPI OemToCharBuffA(LPCSTR lpszSrc,LPSTR lpszDst,DWORD cchDstLength);
+ WINUSERAPI WINBOOL WINAPI OemToCharBuffW(LPCSTR lpszSrc,LPWSTR lpszDst,DWORD cchDstLength);
+ WINUSERAPI LPSTR WINAPI CharUpperA(LPSTR lpsz);
+ WINUSERAPI LPWSTR WINAPI CharUpperW(LPWSTR lpsz);
+ WINUSERAPI DWORD WINAPI CharUpperBuffA(LPSTR lpsz,DWORD cchLength);
+ WINUSERAPI DWORD WINAPI CharUpperBuffW(LPWSTR lpsz,DWORD cchLength);
+ WINUSERAPI LPSTR WINAPI CharLowerA(LPSTR lpsz);
+ WINUSERAPI LPWSTR WINAPI CharLowerW(LPWSTR lpsz);
+ WINUSERAPI DWORD WINAPI CharLowerBuffA(LPSTR lpsz,DWORD cchLength);
+ WINUSERAPI DWORD WINAPI CharLowerBuffW(LPWSTR lpsz,DWORD cchLength);
+ WINUSERAPI LPSTR WINAPI CharNextA(LPCSTR lpsz);
+ WINUSERAPI LPWSTR WINAPI CharNextW(LPCWSTR lpsz);
+ WINUSERAPI LPSTR WINAPI CharPrevA(LPCSTR lpszStart,LPCSTR lpszCurrent);
+ WINUSERAPI LPWSTR WINAPI CharPrevW(LPCWSTR lpszStart,LPCWSTR lpszCurrent);
+ WINUSERAPI LPSTR WINAPI CharNextExA(WORD CodePage,LPCSTR lpCurrentChar,DWORD dwFlags);
+ WINUSERAPI LPSTR WINAPI CharPrevExA(WORD CodePage,LPCSTR lpStart,LPCSTR lpCurrentChar,DWORD dwFlags);
+
+#define AnsiToOem CharToOemA
+#define OemToAnsi OemToCharA
+#define AnsiToOemBuff CharToOemBuffA
+#define OemToAnsiBuff OemToCharBuffA
+#define AnsiUpper CharUpperA
+#define AnsiUpperBuff CharUpperBuffA
+#define AnsiLower CharLowerA
+#define AnsiLowerBuff CharLowerBuffA
+#define AnsiNext CharNextA
+#define AnsiPrev CharPrevA
+
+#ifndef NOLANGUAGE
+
+#ifdef UNICODE
+#define IsCharAlpha IsCharAlphaW
+#define IsCharAlphaNumeric IsCharAlphaNumericW
+#define IsCharUpper IsCharUpperW
+#define IsCharLower IsCharLowerW
+#else
+#define IsCharAlpha IsCharAlphaA
+#define IsCharAlphaNumeric IsCharAlphaNumericA
+#define IsCharUpper IsCharUpperA
+#define IsCharLower IsCharLowerA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI IsCharAlphaA(CHAR ch);
+ WINUSERAPI WINBOOL WINAPI IsCharAlphaW(WCHAR ch);
+ WINUSERAPI WINBOOL WINAPI IsCharAlphaNumericA(CHAR ch);
+ WINUSERAPI WINBOOL WINAPI IsCharAlphaNumericW(WCHAR ch);
+ WINUSERAPI WINBOOL WINAPI IsCharUpperA(CHAR ch);
+ WINUSERAPI WINBOOL WINAPI IsCharUpperW(WCHAR ch);
+ WINUSERAPI WINBOOL WINAPI IsCharLowerA(CHAR ch);
+ WINUSERAPI WINBOOL WINAPI IsCharLowerW(WCHAR ch);
+#endif
+
+#ifdef UNICODE
+#define GetKeyNameText GetKeyNameTextW
+#define VkKeyScan VkKeyScanW
+#define VkKeyScanEx VkKeyScanExW
+#else
+#define GetKeyNameText GetKeyNameTextA
+#define VkKeyScan VkKeyScanA
+#define VkKeyScanEx VkKeyScanExA
+#endif
+
+ WINUSERAPI HWND WINAPI SetFocus(HWND hWnd);
+ WINUSERAPI HWND WINAPI GetActiveWindow(VOID);
+ WINUSERAPI HWND WINAPI GetFocus(VOID);
+ WINUSERAPI UINT WINAPI GetKBCodePage(VOID);
+ WINUSERAPI SHORT WINAPI GetKeyState(int nVirtKey);
+ WINUSERAPI SHORT WINAPI GetAsyncKeyState(int vKey);
+ WINUSERAPI WINBOOL WINAPI GetKeyboardState(PBYTE lpKeyState);
+ WINUSERAPI WINBOOL WINAPI SetKeyboardState(LPBYTE lpKeyState);
+ WINUSERAPI int WINAPI GetKeyNameTextA(LONG lParam,LPSTR lpString,int cchSize);
+ WINUSERAPI int WINAPI GetKeyNameTextW(LONG lParam,LPWSTR lpString,int cchSize);
+ WINUSERAPI int WINAPI GetKeyboardType(int nTypeFlag);
+ WINUSERAPI int WINAPI ToAscii(UINT uVirtKey,UINT uScanCode,CONST BYTE *lpKeyState,LPWORD lpChar,UINT uFlags);
+ WINUSERAPI int WINAPI ToAsciiEx(UINT uVirtKey,UINT uScanCode,CONST BYTE *lpKeyState,LPWORD lpChar,UINT uFlags,HKL dwhkl);
+ WINUSERAPI int WINAPI ToUnicode(UINT wVirtKey,UINT wScanCode,CONST BYTE *lpKeyState,LPWSTR pwszBuff,int cchBuff,UINT wFlags);
+ WINUSERAPI DWORD WINAPI OemKeyScan(WORD wOemChar);
+ WINUSERAPI SHORT WINAPI VkKeyScanA(CHAR ch);
+ WINUSERAPI SHORT WINAPI VkKeyScanW(WCHAR ch);
+ WINUSERAPI SHORT WINAPI VkKeyScanExA(CHAR ch,HKL dwhkl);
+ WINUSERAPI SHORT WINAPI VkKeyScanExW(WCHAR ch,HKL dwhkl);
+
+#define KEYEVENTF_EXTENDEDKEY 0x0001
+#define KEYEVENTF_KEYUP 0x0002
+#define KEYEVENTF_UNICODE 0x0004
+#define KEYEVENTF_SCANCODE 0x0008
+
+ WINUSERAPI VOID WINAPI keybd_event(BYTE bVk,BYTE bScan,DWORD dwFlags,ULONG_PTR dwExtraInfo);
+
+#define MOUSEEVENTF_MOVE 0x0001
+#define MOUSEEVENTF_LEFTDOWN 0x0002
+#define MOUSEEVENTF_LEFTUP 0x0004
+#define MOUSEEVENTF_RIGHTDOWN 0x0008
+#define MOUSEEVENTF_RIGHTUP 0x0010
+#define MOUSEEVENTF_MIDDLEDOWN 0x0020
+#define MOUSEEVENTF_MIDDLEUP 0x0040
+#define MOUSEEVENTF_XDOWN 0x0080
+#define MOUSEEVENTF_XUP 0x0100
+#define MOUSEEVENTF_WHEEL 0x0800
+#define MOUSEEVENTF_VIRTUALDESK 0x4000
+#define MOUSEEVENTF_ABSOLUTE 0x8000
+
+ WINUSERAPI VOID WINAPI mouse_event(DWORD dwFlags,DWORD dx,DWORD dy,DWORD dwData,ULONG_PTR dwExtraInfo);
+
+ typedef struct tagMOUSEINPUT {
+ LONG dx;
+ LONG dy;
+ DWORD mouseData;
+ DWORD dwFlags;
+ DWORD time;
+ ULONG_PTR dwExtraInfo;
+ } MOUSEINPUT,*PMOUSEINPUT,*LPMOUSEINPUT;
+
+ typedef struct tagKEYBDINPUT {
+ WORD wVk;
+ WORD wScan;
+ DWORD dwFlags;
+ DWORD time;
+ ULONG_PTR dwExtraInfo;
+ } KEYBDINPUT,*PKEYBDINPUT,*LPKEYBDINPUT;
+
+ typedef struct tagHARDWAREINPUT {
+ DWORD uMsg;
+ WORD wParamL;
+ WORD wParamH;
+ } HARDWAREINPUT,*PHARDWAREINPUT,*LPHARDWAREINPUT;
+
+#define INPUT_MOUSE 0
+#define INPUT_KEYBOARD 1
+#define INPUT_HARDWARE 2
+
+ typedef struct tagINPUT {
+ DWORD type;
+ union {
+ MOUSEINPUT mi;
+ KEYBDINPUT ki;
+ HARDWAREINPUT hi;
+ };
+ } INPUT,*PINPUT,*LPINPUT;
+
+ WINUSERAPI UINT WINAPI SendInput(UINT cInputs,LPINPUT pInputs,int cbSize);
+
+ typedef struct tagLASTINPUTINFO {
+ UINT cbSize;
+ DWORD dwTime;
+ } LASTINPUTINFO,*PLASTINPUTINFO;
+
+#ifdef UNICODE
+#define MapVirtualKey MapVirtualKeyW
+#define MapVirtualKeyEx MapVirtualKeyExW
+#else
+#define MapVirtualKey MapVirtualKeyA
+#define MapVirtualKeyEx MapVirtualKeyExA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI GetLastInputInfo(PLASTINPUTINFO plii);
+ WINUSERAPI UINT WINAPI MapVirtualKeyA(UINT uCode,UINT uMapType);
+ WINUSERAPI UINT WINAPI MapVirtualKeyW(UINT uCode,UINT uMapType);
+ WINUSERAPI UINT WINAPI MapVirtualKeyExA(UINT uCode,UINT uMapType,HKL dwhkl);
+ WINUSERAPI UINT WINAPI MapVirtualKeyExW(UINT uCode,UINT uMapType,HKL dwhkl);
+ WINUSERAPI WINBOOL WINAPI GetInputState(VOID);
+ WINUSERAPI DWORD WINAPI GetQueueStatus(UINT flags);
+ WINUSERAPI HWND WINAPI GetCapture(VOID);
+ WINUSERAPI HWND WINAPI SetCapture(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI ReleaseCapture(VOID);
+ WINUSERAPI DWORD WINAPI MsgWaitForMultipleObjects(DWORD nCount,CONST HANDLE *pHandles,WINBOOL fWaitAll,DWORD dwMilliseconds,DWORD dwWakeMask);
+ WINUSERAPI DWORD WINAPI MsgWaitForMultipleObjectsEx(DWORD nCount,CONST HANDLE *pHandles,DWORD dwMilliseconds,DWORD dwWakeMask,DWORD dwFlags);
+
+#define MWMO_WAITALL 0x0001
+#define MWMO_ALERTABLE 0x0002
+#define MWMO_INPUTAVAILABLE 0x0004
+
+#define QS_KEY 0x0001
+#define QS_MOUSEMOVE 0x0002
+#define QS_MOUSEBUTTON 0x0004
+#define QS_POSTMESSAGE 0x0008
+#define QS_TIMER 0x0010
+#define QS_PAINT 0x0020
+#define QS_SENDMESSAGE 0x0040
+#define QS_HOTKEY 0x0080
+#define QS_ALLPOSTMESSAGE 0x0100
+#define QS_RAWINPUT 0x0400
+#define QS_MOUSE (QS_MOUSEMOVE | QS_MOUSEBUTTON)
+#define QS_INPUT (QS_MOUSE | QS_KEY | QS_RAWINPUT)
+#define QS_ALLEVENTS (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY)
+#define QS_ALLINPUT (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE)
+
+#define USER_TIMER_MAXIMUM 0x7FFFFFFF
+#define USER_TIMER_MINIMUM 0x0000000A
+
+#ifdef UNICODE
+#define LoadAccelerators LoadAcceleratorsW
+#define CreateAcceleratorTable CreateAcceleratorTableW
+#define CopyAcceleratorTable CopyAcceleratorTableW
+#else
+#define LoadAccelerators LoadAcceleratorsA
+#define CreateAcceleratorTable CreateAcceleratorTableA
+#define CopyAcceleratorTable CopyAcceleratorTableA
+#endif
+
+ WINUSERAPI UINT_PTR WINAPI SetTimer(HWND hWnd,UINT_PTR nIDEvent,UINT uElapse,TIMERPROC lpTimerFunc);
+ WINUSERAPI WINBOOL WINAPI KillTimer(HWND hWnd,UINT_PTR uIDEvent);
+ WINUSERAPI WINBOOL WINAPI IsWindowUnicode(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI EnableWindow(HWND hWnd,WINBOOL bEnable);
+ WINUSERAPI WINBOOL WINAPI IsWindowEnabled(HWND hWnd);
+ WINUSERAPI HACCEL WINAPI LoadAcceleratorsA(HINSTANCE hInstance,LPCSTR lpTableName);
+ WINUSERAPI HACCEL WINAPI LoadAcceleratorsW(HINSTANCE hInstance,LPCWSTR lpTableName);
+ WINUSERAPI HACCEL WINAPI CreateAcceleratorTableA(LPACCEL paccel,int cAccel);
+ WINUSERAPI HACCEL WINAPI CreateAcceleratorTableW(LPACCEL paccel,int cAccel);
+ WINUSERAPI WINBOOL WINAPI DestroyAcceleratorTable(HACCEL hAccel);
+ WINUSERAPI int WINAPI CopyAcceleratorTableA(HACCEL hAccelSrc,LPACCEL lpAccelDst,int cAccelEntries);
+ WINUSERAPI int WINAPI CopyAcceleratorTableW(HACCEL hAccelSrc,LPACCEL lpAccelDst,int cAccelEntries);
+
+#ifndef NOMSG
+
+#ifdef UNICODE
+#define TranslateAccelerator TranslateAcceleratorW
+#else
+#define TranslateAccelerator TranslateAcceleratorA
+#endif
+
+ WINUSERAPI int WINAPI TranslateAcceleratorA(HWND hWnd,HACCEL hAccTable,LPMSG lpMsg);
+ WINUSERAPI int WINAPI TranslateAcceleratorW(HWND hWnd,HACCEL hAccTable,LPMSG lpMsg);
+#endif
+
+#ifndef NOSYSMETRICS
+
+#define SM_CXSCREEN 0
+#define SM_CYSCREEN 1
+#define SM_CXVSCROLL 2
+#define SM_CYHSCROLL 3
+#define SM_CYCAPTION 4
+#define SM_CXBORDER 5
+#define SM_CYBORDER 6
+#define SM_CXDLGFRAME 7
+#define SM_CYDLGFRAME 8
+#define SM_CYVTHUMB 9
+#define SM_CXHTHUMB 10
+#define SM_CXICON 11
+#define SM_CYICON 12
+#define SM_CXCURSOR 13
+#define SM_CYCURSOR 14
+#define SM_CYMENU 15
+#define SM_CXFULLSCREEN 16
+#define SM_CYFULLSCREEN 17
+#define SM_CYKANJIWINDOW 18
+#define SM_MOUSEPRESENT 19
+#define SM_CYVSCROLL 20
+#define SM_CXHSCROLL 21
+#define SM_DEBUG 22
+#define SM_SWAPBUTTON 23
+#define SM_RESERVED1 24
+#define SM_RESERVED2 25
+#define SM_RESERVED3 26
+#define SM_RESERVED4 27
+#define SM_CXMIN 28
+#define SM_CYMIN 29
+#define SM_CXSIZE 30
+#define SM_CYSIZE 31
+#define SM_CXFRAME 32
+#define SM_CYFRAME 33
+#define SM_CXMINTRACK 34
+#define SM_CYMINTRACK 35
+#define SM_CXDOUBLECLK 36
+#define SM_CYDOUBLECLK 37
+#define SM_CXICONSPACING 38
+#define SM_CYICONSPACING 39
+#define SM_MENUDROPALIGNMENT 40
+#define SM_PENWINDOWS 41
+#define SM_DBCSENABLED 42
+#define SM_CMOUSEBUTTONS 43
+
+#define SM_CXFIXEDFRAME SM_CXDLGFRAME
+#define SM_CYFIXEDFRAME SM_CYDLGFRAME
+#define SM_CXSIZEFRAME SM_CXFRAME
+#define SM_CYSIZEFRAME SM_CYFRAME
+
+#define SM_SECURE 44
+#define SM_CXEDGE 45
+#define SM_CYEDGE 46
+#define SM_CXMINSPACING 47
+#define SM_CYMINSPACING 48
+#define SM_CXSMICON 49
+#define SM_CYSMICON 50
+#define SM_CYSMCAPTION 51
+#define SM_CXSMSIZE 52
+#define SM_CYSMSIZE 53
+#define SM_CXMENUSIZE 54
+#define SM_CYMENUSIZE 55
+#define SM_ARRANGE 56
+#define SM_CXMINIMIZED 57
+#define SM_CYMINIMIZED 58
+#define SM_CXMAXTRACK 59
+#define SM_CYMAXTRACK 60
+#define SM_CXMAXIMIZED 61
+#define SM_CYMAXIMIZED 62
+#define SM_NETWORK 63
+#define SM_CLEANBOOT 67
+#define SM_CXDRAG 68
+#define SM_CYDRAG 69
+#define SM_SHOWSOUNDS 70
+#define SM_CXMENUCHECK 71
+#define SM_CYMENUCHECK 72
+#define SM_SLOWMACHINE 73
+#define SM_MIDEASTENABLED 74
+#define SM_MOUSEWHEELPRESENT 75
+#define SM_XVIRTUALSCREEN 76
+#define SM_YVIRTUALSCREEN 77
+#define SM_CXVIRTUALSCREEN 78
+#define SM_CYVIRTUALSCREEN 79
+#define SM_CMONITORS 80
+#define SM_SAMEDISPLAYFORMAT 81
+#define SM_IMMENABLED 82
+#define SM_CXFOCUSBORDER 83
+#define SM_CYFOCUSBORDER 84
+#define SM_TABLETPC 86
+#define SM_MEDIACENTER 87
+#define SM_STARTER 88
+#define SM_SERVERR2 89
+#define SM_CMETRICS 90
+#define SM_REMOTESESSION 0x1000
+#define SM_SHUTTINGDOWN 0x2000
+#define SM_REMOTECONTROL 0x2001
+#define SM_CARETBLINKINGENABLED 0x2002
+
+ WINUSERAPI int WINAPI GetSystemMetrics(int nIndex);
+#endif
+
+#ifndef NOMENUS
+
+#ifdef UNICODE
+#define LoadMenu LoadMenuW
+#define LoadMenuIndirect LoadMenuIndirectW
+#define ChangeMenu ChangeMenuW
+#define GetMenuString GetMenuStringW
+#define InsertMenu InsertMenuW
+#define AppendMenu AppendMenuW
+#define ModifyMenu ModifyMenuW
+#else
+#define LoadMenu LoadMenuA
+#define LoadMenuIndirect LoadMenuIndirectA
+#define ChangeMenu ChangeMenuA
+#define GetMenuString GetMenuStringA
+#define InsertMenu InsertMenuA
+#define AppendMenu AppendMenuA
+#define ModifyMenu ModifyMenuA
+#endif
+
+ WINUSERAPI HMENU WINAPI LoadMenuA(HINSTANCE hInstance,LPCSTR lpMenuName);
+ WINUSERAPI HMENU WINAPI LoadMenuW(HINSTANCE hInstance,LPCWSTR lpMenuName);
+ WINUSERAPI HMENU WINAPI LoadMenuIndirectA(CONST MENUTEMPLATEA *lpMenuTemplate);
+ WINUSERAPI HMENU WINAPI LoadMenuIndirectW(CONST MENUTEMPLATEW *lpMenuTemplate);
+ WINUSERAPI HMENU WINAPI GetMenu(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI SetMenu(HWND hWnd,HMENU hMenu);
+ WINUSERAPI WINBOOL WINAPI ChangeMenuA(HMENU hMenu,UINT cmd,LPCSTR lpszNewItem,UINT cmdInsert,UINT flags);
+ WINUSERAPI WINBOOL WINAPI ChangeMenuW(HMENU hMenu,UINT cmd,LPCWSTR lpszNewItem,UINT cmdInsert,UINT flags);
+ WINUSERAPI WINBOOL WINAPI HiliteMenuItem(HWND hWnd,HMENU hMenu,UINT uIDHiliteItem,UINT uHilite);
+ WINUSERAPI int WINAPI GetMenuStringA(HMENU hMenu,UINT uIDItem,LPSTR lpString,int cchMax,UINT flags);
+ WINUSERAPI int WINAPI GetMenuStringW(HMENU hMenu,UINT uIDItem,LPWSTR lpString,int cchMax,UINT flags);
+ WINUSERAPI UINT WINAPI GetMenuState(HMENU hMenu,UINT uId,UINT uFlags);
+ WINUSERAPI WINBOOL WINAPI DrawMenuBar(HWND hWnd);
+
+#define PMB_ACTIVE 0x00000001
+
+ WINUSERAPI HMENU WINAPI GetSystemMenu(HWND hWnd,WINBOOL bRevert);
+ WINUSERAPI HMENU WINAPI CreateMenu(VOID);
+ WINUSERAPI HMENU WINAPI CreatePopupMenu(VOID);
+ WINUSERAPI WINBOOL WINAPI DestroyMenu(HMENU hMenu);
+ WINUSERAPI DWORD WINAPI CheckMenuItem(HMENU hMenu,UINT uIDCheckItem,UINT uCheck);
+ WINUSERAPI WINBOOL WINAPI EnableMenuItem(HMENU hMenu,UINT uIDEnableItem,UINT uEnable);
+ WINUSERAPI HMENU WINAPI GetSubMenu(HMENU hMenu,int nPos);
+ WINUSERAPI UINT WINAPI GetMenuItemID(HMENU hMenu,int nPos);
+ WINUSERAPI int WINAPI GetMenuItemCount(HMENU hMenu);
+ WINUSERAPI WINBOOL WINAPI InsertMenuA(HMENU hMenu,UINT uPosition,UINT uFlags,UINT_PTR uIDNewItem,LPCSTR lpNewItem);
+ WINUSERAPI WINBOOL WINAPI InsertMenuW(HMENU hMenu,UINT uPosition,UINT uFlags,UINT_PTR uIDNewItem,LPCWSTR lpNewItem);
+ WINUSERAPI WINBOOL WINAPI AppendMenuA(HMENU hMenu,UINT uFlags,UINT_PTR uIDNewItem,LPCSTR lpNewItem);
+ WINUSERAPI WINBOOL WINAPI AppendMenuW(HMENU hMenu,UINT uFlags,UINT_PTR uIDNewItem,LPCWSTR lpNewItem);
+ WINUSERAPI WINBOOL WINAPI ModifyMenuA(HMENU hMnu,UINT uPosition,UINT uFlags,UINT_PTR uIDNewItem,LPCSTR lpNewItem);
+ WINUSERAPI WINBOOL WINAPI ModifyMenuW(HMENU hMnu,UINT uPosition,UINT uFlags,UINT_PTR uIDNewItem,LPCWSTR lpNewItem);
+ WINUSERAPI WINBOOL WINAPI RemoveMenu(HMENU hMenu,UINT uPosition,UINT uFlags);
+ WINUSERAPI WINBOOL WINAPI DeleteMenu(HMENU hMenu,UINT uPosition,UINT uFlags);
+ WINUSERAPI WINBOOL WINAPI SetMenuItemBitmaps(HMENU hMenu,UINT uPosition,UINT uFlags,HBITMAP hBitmapUnchecked,HBITMAP hBitmapChecked);
+ WINUSERAPI LONG WINAPI GetMenuCheckMarkDimensions(VOID);
+ WINUSERAPI WINBOOL WINAPI TrackPopupMenu(HMENU hMenu,UINT uFlags,int x,int y,int nReserved,HWND hWnd,CONST RECT *prcRect);
+
+#define MNC_IGNORE 0
+#define MNC_CLOSE 1
+#define MNC_EXECUTE 2
+#define MNC_SELECT 3
+
+ typedef struct tagTPMPARAMS {
+ UINT cbSize;
+ RECT rcExclude;
+ } TPMPARAMS;
+
+ typedef TPMPARAMS *LPTPMPARAMS;
+
+ WINUSERAPI WINBOOL WINAPI TrackPopupMenuEx(HMENU,UINT,int,int,HWND,LPTPMPARAMS);
+
+#define MNS_NOCHECK 0x80000000
+#define MNS_MODELESS 0x40000000
+#define MNS_DRAGDROP 0x20000000
+#define MNS_AUTODISMISS 0x10000000
+#define MNS_NOTIFYBYPOS 0x08000000
+#define MNS_CHECKORBMP 0x04000000
+
+#define MIM_MAXHEIGHT 0x00000001
+#define MIM_BACKGROUND 0x00000002
+#define MIM_HELPID 0x00000004
+#define MIM_MENUDATA 0x00000008
+#define MIM_STYLE 0x00000010
+#define MIM_APPLYTOSUBMENUS 0x80000000
+
+ typedef struct tagMENUINFO {
+ DWORD cbSize;
+ DWORD fMask;
+ DWORD dwStyle;
+ UINT cyMax;
+ HBRUSH hbrBack;
+ DWORD dwContextHelpID;
+ ULONG_PTR dwMenuData;
+ } MENUINFO,*LPMENUINFO;
+
+ typedef MENUINFO CONST *LPCMENUINFO;
+
+ WINUSERAPI WINBOOL WINAPI GetMenuInfo(HMENU,LPMENUINFO);
+ WINUSERAPI WINBOOL WINAPI SetMenuInfo(HMENU,LPCMENUINFO);
+ WINUSERAPI WINBOOL WINAPI EndMenu(VOID);
+
+#define MND_CONTINUE 0
+#define MND_ENDMENU 1
+
+ typedef struct tagMENUGETOBJECTINFO {
+ DWORD dwFlags;
+ UINT uPos;
+ HMENU hmenu;
+ PVOID riid;
+ PVOID pvObj;
+ } MENUGETOBJECTINFO,*PMENUGETOBJECTINFO;
+
+#define MNGOF_TOPGAP 0x00000001
+#define MNGOF_BOTTOMGAP 0x00000002
+
+#define MNGO_NOINTERFACE 0x00000000
+#define MNGO_NOERROR 0x00000001
+
+#define MIIM_STATE 0x00000001
+#define MIIM_ID 0x00000002
+#define MIIM_SUBMENU 0x00000004
+#define MIIM_CHECKMARKS 0x00000008
+#define MIIM_TYPE 0x00000010
+#define MIIM_DATA 0x00000020
+
+#define MIIM_STRING 0x00000040
+#define MIIM_BITMAP 0x00000080
+#define MIIM_FTYPE 0x00000100
+
+#define HBMMENU_CALLBACK ((HBITMAP) -1)
+#define HBMMENU_SYSTEM ((HBITMAP) 1)
+#define HBMMENU_MBAR_RESTORE ((HBITMAP) 2)
+#define HBMMENU_MBAR_MINIMIZE ((HBITMAP) 3)
+#define HBMMENU_MBAR_CLOSE ((HBITMAP) 5)
+#define HBMMENU_MBAR_CLOSE_D ((HBITMAP) 6)
+#define HBMMENU_MBAR_MINIMIZE_D ((HBITMAP) 7)
+#define HBMMENU_POPUP_CLOSE ((HBITMAP) 8)
+#define HBMMENU_POPUP_RESTORE ((HBITMAP) 9)
+#define HBMMENU_POPUP_MAXIMIZE ((HBITMAP) 10)
+#define HBMMENU_POPUP_MINIMIZE ((HBITMAP) 11)
+
+ typedef struct tagMENUITEMINFOA {
+ UINT cbSize;
+ UINT fMask;
+ UINT fType;
+ UINT fState;
+ UINT wID;
+ HMENU hSubMenu;
+ HBITMAP hbmpChecked;
+ HBITMAP hbmpUnchecked;
+ ULONG_PTR dwItemData;
+ LPSTR dwTypeData;
+ UINT cch;
+ HBITMAP hbmpItem;
+ } MENUITEMINFOA,*LPMENUITEMINFOA;
+
+ typedef struct tagMENUITEMINFOW {
+ UINT cbSize;
+ UINT fMask;
+ UINT fType;
+ UINT fState;
+ UINT wID;
+ HMENU hSubMenu;
+ HBITMAP hbmpChecked;
+ HBITMAP hbmpUnchecked;
+ ULONG_PTR dwItemData;
+ LPWSTR dwTypeData;
+ UINT cch;
+ HBITMAP hbmpItem;
+ } MENUITEMINFOW,*LPMENUITEMINFOW;
+
+#ifdef UNICODE
+ typedef MENUITEMINFOW MENUITEMINFO;
+ typedef LPMENUITEMINFOW LPMENUITEMINFO;
+#else
+ typedef MENUITEMINFOA MENUITEMINFO;
+ typedef LPMENUITEMINFOA LPMENUITEMINFO;
+#endif
+ typedef MENUITEMINFOA CONST *LPCMENUITEMINFOA;
+ typedef MENUITEMINFOW CONST *LPCMENUITEMINFOW;
+#ifdef UNICODE
+ typedef LPCMENUITEMINFOW LPCMENUITEMINFO;
+#else
+ typedef LPCMENUITEMINFOA LPCMENUITEMINFO;
+#endif
+
+#ifdef UNICODE
+#define InsertMenuItem InsertMenuItemW
+#define GetMenuItemInfo GetMenuItemInfoW
+#define SetMenuItemInfo SetMenuItemInfoW
+#else
+#define InsertMenuItem InsertMenuItemA
+#define GetMenuItemInfo GetMenuItemInfoA
+#define SetMenuItemInfo SetMenuItemInfoA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI InsertMenuItemA(HMENU hmenu,UINT item,WINBOOL fByPosition,LPCMENUITEMINFOA lpmi);
+ WINUSERAPI WINBOOL WINAPI InsertMenuItemW(HMENU hmenu,UINT item,WINBOOL fByPosition,LPCMENUITEMINFOW lpmi);
+ WINUSERAPI WINBOOL WINAPI GetMenuItemInfoA(HMENU hmenu,UINT item,WINBOOL fByPosition,LPMENUITEMINFOA lpmii);
+ WINUSERAPI WINBOOL WINAPI GetMenuItemInfoW(HMENU hmenu,UINT item,WINBOOL fByPosition,LPMENUITEMINFOW lpmii);
+ WINUSERAPI WINBOOL WINAPI SetMenuItemInfoA(HMENU hmenu,UINT item,WINBOOL fByPositon,LPCMENUITEMINFOA lpmii);
+ WINUSERAPI WINBOOL WINAPI SetMenuItemInfoW(HMENU hmenu,UINT item,WINBOOL fByPositon,LPCMENUITEMINFOW lpmii);
+
+#define GMDI_USEDISABLED 0x0001L
+#define GMDI_GOINTOPOPUPS 0x0002L
+
+ WINUSERAPI UINT WINAPI GetMenuDefaultItem(HMENU hMenu,UINT fByPos,UINT gmdiFlags);
+ WINUSERAPI WINBOOL WINAPI SetMenuDefaultItem(HMENU hMenu,UINT uItem,UINT fByPos);
+ WINUSERAPI WINBOOL WINAPI GetMenuItemRect(HWND hWnd,HMENU hMenu,UINT uItem,LPRECT lprcItem);
+ WINUSERAPI int WINAPI MenuItemFromPoint(HWND hWnd,HMENU hMenu,POINT ptScreen);
+
+#define TPM_LEFTBUTTON 0x0000L
+#define TPM_RIGHTBUTTON 0x0002L
+#define TPM_LEFTALIGN 0x0000L
+#define TPM_CENTERALIGN 0x0004L
+#define TPM_RIGHTALIGN 0x0008L
+#define TPM_TOPALIGN 0x0000L
+#define TPM_VCENTERALIGN 0x0010L
+#define TPM_BOTTOMALIGN 0x0020L
+
+#define TPM_HORIZONTAL 0x0000L
+#define TPM_VERTICAL 0x0040L
+#define TPM_NONOTIFY 0x0080L
+#define TPM_RETURNCMD 0x0100L
+#define TPM_RECURSE 0x0001L
+#define TPM_HORPOSANIMATION 0x0400L
+#define TPM_HORNEGANIMATION 0x0800L
+#define TPM_VERPOSANIMATION 0x1000L
+#define TPM_VERNEGANIMATION 0x2000L
+#define TPM_NOANIMATION 0x4000L
+#define TPM_LAYOUTRTL 0x8000L
+#endif
+
+ typedef struct tagDROPSTRUCT {
+ HWND hwndSource;
+ HWND hwndSink;
+ DWORD wFmt;
+ ULONG_PTR dwData;
+ POINT ptDrop;
+ DWORD dwControlData;
+ } DROPSTRUCT,*PDROPSTRUCT,*LPDROPSTRUCT;
+
+#define DOF_EXECUTABLE 0x8001
+#define DOF_DOCUMENT 0x8002
+#define DOF_DIRECTORY 0x8003
+#define DOF_MULTIPLE 0x8004
+#define DOF_PROGMAN 0x0001
+#define DOF_SHELLDATA 0x0002
+
+#define DO_DROPFILE 0x454C4946L
+#define DO_PRINTFILE 0x544E5250L
+
+ WINUSERAPI DWORD WINAPI DragObject(HWND hwndParent,HWND hwndFrom,UINT fmt,ULONG_PTR data,HCURSOR hcur);
+ WINUSERAPI WINBOOL WINAPI DragDetect(HWND hwnd,POINT pt);
+ WINUSERAPI WINBOOL WINAPI DrawIcon(HDC hDC,int X,int Y,HICON hIcon);
+
+#ifndef NODRAWTEXT
+
+#define DT_TOP 0x00000000
+#define DT_LEFT 0x00000000
+#define DT_CENTER 0x00000001
+#define DT_RIGHT 0x00000002
+#define DT_VCENTER 0x00000004
+#define DT_BOTTOM 0x00000008
+#define DT_WORDBREAK 0x00000010
+#define DT_SINGLELINE 0x00000020
+#define DT_EXPANDTABS 0x00000040
+#define DT_TABSTOP 0x00000080
+#define DT_NOCLIP 0x00000100
+#define DT_EXTERNALLEADING 0x00000200
+#define DT_CALCRECT 0x00000400
+#define DT_NOPREFIX 0x00000800
+#define DT_INTERNAL 0x00001000
+
+#define DT_EDITCONTROL 0x00002000
+#define DT_PATH_ELLIPSIS 0x00004000
+#define DT_END_ELLIPSIS 0x00008000
+#define DT_MODIFYSTRING 0x00010000
+#define DT_RTLREADING 0x00020000
+#define DT_WORD_ELLIPSIS 0x00040000
+#define DT_NOFULLWIDTHCHARBREAK 0x00080000
+#define DT_HIDEPREFIX 0x00100000
+#define DT_PREFIXONLY 0x00200000
+
+ typedef struct tagDRAWTEXTPARAMS {
+ UINT cbSize;
+ int iTabLength;
+ int iLeftMargin;
+ int iRightMargin;
+ UINT uiLengthDrawn;
+ } DRAWTEXTPARAMS,*LPDRAWTEXTPARAMS;
+
+#ifdef UNICODE
+#define DrawText DrawTextW
+#define DrawTextEx DrawTextExW
+#else
+#define DrawText DrawTextA
+#define DrawTextEx DrawTextExA
+#endif
+
+ WINUSERAPI int WINAPI DrawTextA(HDC hdc,LPCSTR lpchText,int cchText,LPRECT lprc,UINT format);
+ WINUSERAPI int WINAPI DrawTextW(HDC hdc,LPCWSTR lpchText,int cchText,LPRECT lprc,UINT format);
+ WINUSERAPI int WINAPI DrawTextExA(HDC hdc,LPSTR lpchText,int cchText,LPRECT lprc,UINT format,LPDRAWTEXTPARAMS lpdtp);
+ WINUSERAPI int WINAPI DrawTextExW(HDC hdc,LPWSTR lpchText,int cchText,LPRECT lprc,UINT format,LPDRAWTEXTPARAMS lpdtp);
+#endif
+
+#ifdef UNICODE
+#define GrayString GrayStringW
+#define DrawState DrawStateW
+#define TabbedTextOut TabbedTextOutW
+#define GetTabbedTextExtent GetTabbedTextExtentW
+#else
+#define GrayString GrayStringA
+#define DrawState DrawStateA
+#define TabbedTextOut TabbedTextOutA
+#define GetTabbedTextExtent GetTabbedTextExtentA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI GrayStringA(HDC hDC,HBRUSH hBrush,GRAYSTRINGPROC lpOutputFunc,LPARAM lpData,int nCount,int X,int Y,int nWidth,int nHeight);
+ WINUSERAPI WINBOOL WINAPI GrayStringW(HDC hDC,HBRUSH hBrush,GRAYSTRINGPROC lpOutputFunc,LPARAM lpData,int nCount,int X,int Y,int nWidth,int nHeight);
+
+#define DST_COMPLEX 0x0000
+#define DST_TEXT 0x0001
+#define DST_PREFIXTEXT 0x0002
+#define DST_ICON 0x0003
+#define DST_BITMAP 0x0004
+
+#define DSS_NORMAL 0x0000
+#define DSS_UNION 0x0010
+#define DSS_DISABLED 0x0020
+#define DSS_MONO 0x0080
+#define DSS_HIDEPREFIX 0x0200
+#define DSS_PREFIXONLY 0x0400
+#define DSS_RIGHT 0x8000
+
+ WINUSERAPI WINBOOL WINAPI DrawStateA(HDC hdc,HBRUSH hbrFore,DRAWSTATEPROC qfnCallBack,LPARAM lData,WPARAM wData,int x,int y,int cx,int cy,UINT uFlags);
+ WINUSERAPI WINBOOL WINAPI DrawStateW(HDC hdc,HBRUSH hbrFore,DRAWSTATEPROC qfnCallBack,LPARAM lData,WPARAM wData,int x,int y,int cx,int cy,UINT uFlags);
+ WINUSERAPI LONG WINAPI TabbedTextOutA(HDC hdc,int x,int y,LPCSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions,int nTabOrigin);
+ WINUSERAPI LONG WINAPI TabbedTextOutW(HDC hdc,int x,int y,LPCWSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions,int nTabOrigin);
+ WINUSERAPI DWORD WINAPI GetTabbedTextExtentA(HDC hdc,LPCSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions);
+ WINUSERAPI DWORD WINAPI GetTabbedTextExtentW(HDC hdc,LPCWSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions);
+ WINUSERAPI WINBOOL WINAPI UpdateWindow(HWND hWnd);
+ WINUSERAPI HWND WINAPI SetActiveWindow(HWND hWnd);
+ WINUSERAPI HWND WINAPI GetForegroundWindow(VOID);
+ WINUSERAPI WINBOOL WINAPI PaintDesktop(HDC hdc);
+ WINUSERAPI VOID WINAPI SwitchToThisWindow(HWND hwnd,WINBOOL fUnknown);
+ WINUSERAPI WINBOOL WINAPI SetForegroundWindow(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI AllowSetForegroundWindow(DWORD dwProcessId);
+
+#define ASFW_ANY ((DWORD)-1)
+
+ WINUSERAPI WINBOOL WINAPI LockSetForegroundWindow(UINT uLockCode);
+
+#define LSFW_LOCK 1
+#define LSFW_UNLOCK 2
+
+ WINUSERAPI HWND WINAPI WindowFromDC(HDC hDC);
+ WINUSERAPI HDC WINAPI GetDC(HWND hWnd);
+ WINUSERAPI HDC WINAPI GetDCEx(HWND hWnd,HRGN hrgnClip,DWORD flags);
+
+#define DCX_WINDOW 0x00000001L
+#define DCX_CACHE 0x00000002L
+#define DCX_NORESETATTRS 0x00000004L
+#define DCX_CLIPCHILDREN 0x00000008L
+#define DCX_CLIPSIBLINGS 0x00000010L
+#define DCX_PARENTCLIP 0x00000020L
+#define DCX_EXCLUDERGN 0x00000040L
+#define DCX_INTERSECTRGN 0x00000080L
+#define DCX_EXCLUDEUPDATE 0x00000100L
+#define DCX_INTERSECTUPDATE 0x00000200L
+#define DCX_LOCKWINDOWUPDATE 0x00000400L
+
+#define DCX_VALIDATE 0x00200000L
+
+ WINUSERAPI HDC WINAPI GetWindowDC(HWND hWnd);
+ WINUSERAPI int WINAPI ReleaseDC(HWND hWnd,HDC hDC);
+ WINUSERAPI HDC WINAPI BeginPaint(HWND hWnd,LPPAINTSTRUCT lpPaint);
+ WINUSERAPI WINBOOL WINAPI EndPaint(HWND hWnd,CONST PAINTSTRUCT *lpPaint);
+ WINUSERAPI WINBOOL WINAPI GetUpdateRect(HWND hWnd,LPRECT lpRect,WINBOOL bErase);
+ WINUSERAPI int WINAPI GetUpdateRgn(HWND hWnd,HRGN hRgn,WINBOOL bErase);
+ WINUSERAPI int WINAPI SetWindowRgn(HWND hWnd,HRGN hRgn,WINBOOL bRedraw);
+ WINUSERAPI int WINAPI GetWindowRgn(HWND hWnd,HRGN hRgn);
+ WINUSERAPI int WINAPI GetWindowRgnBox(HWND hWnd,LPRECT lprc);
+ WINUSERAPI int WINAPI ExcludeUpdateRgn(HDC hDC,HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI InvalidateRect(HWND hWnd,CONST RECT *lpRect,WINBOOL bErase);
+ WINUSERAPI WINBOOL WINAPI ValidateRect(HWND hWnd,CONST RECT *lpRect);
+ WINUSERAPI WINBOOL WINAPI InvalidateRgn(HWND hWnd,HRGN hRgn,WINBOOL bErase);
+ WINUSERAPI WINBOOL WINAPI ValidateRgn(HWND hWnd,HRGN hRgn);
+ WINUSERAPI WINBOOL WINAPI RedrawWindow(HWND hWnd,CONST RECT *lprcUpdate,HRGN hrgnUpdate,UINT flags);
+
+#define RDW_INVALIDATE 0x0001
+#define RDW_INTERNALPAINT 0x0002
+#define RDW_ERASE 0x0004
+
+#define RDW_VALIDATE 0x0008
+#define RDW_NOINTERNALPAINT 0x0010
+#define RDW_NOERASE 0x0020
+
+#define RDW_NOCHILDREN 0x0040
+#define RDW_ALLCHILDREN 0x0080
+
+#define RDW_UPDATENOW 0x0100
+#define RDW_ERASENOW 0x0200
+
+#define RDW_FRAME 0x0400
+#define RDW_NOFRAME 0x0800
+
+ WINUSERAPI WINBOOL WINAPI LockWindowUpdate(HWND hWndLock);
+ WINUSERAPI WINBOOL WINAPI ScrollWindow(HWND hWnd,int XAmount,int YAmount,CONST RECT *lpRect,CONST RECT *lpClipRect);
+ WINUSERAPI WINBOOL WINAPI ScrollDC(HDC hDC,int dx,int dy,CONST RECT *lprcScroll,CONST RECT *lprcClip,HRGN hrgnUpdate,LPRECT lprcUpdate);
+ WINUSERAPI int WINAPI ScrollWindowEx(HWND hWnd,int dx,int dy,CONST RECT *prcScroll,CONST RECT *prcClip,HRGN hrgnUpdate,LPRECT prcUpdate,UINT flags);
+
+#define SW_SCROLLCHILDREN 0x0001
+#define SW_INVALIDATE 0x0002
+#define SW_ERASE 0x0004
+#define SW_SMOOTHSCROLL 0x0010
+
+#ifndef NOSCROLL
+ WINUSERAPI int WINAPI SetScrollPos(HWND hWnd,int nBar,int nPos,WINBOOL bRedraw);
+ WINUSERAPI int WINAPI GetScrollPos(HWND hWnd,int nBar);
+ WINUSERAPI WINBOOL WINAPI SetScrollRange(HWND hWnd,int nBar,int nMinPos,int nMaxPos,WINBOOL bRedraw);
+ WINUSERAPI WINBOOL WINAPI GetScrollRange(HWND hWnd,int nBar,LPINT lpMinPos,LPINT lpMaxPos);
+ WINUSERAPI WINBOOL WINAPI ShowScrollBar(HWND hWnd,int wBar,WINBOOL bShow);
+ WINUSERAPI WINBOOL WINAPI EnableScrollBar(HWND hWnd,UINT wSBflags,UINT wArrows);
+
+#define ESB_ENABLE_BOTH 0x0000
+#define ESB_DISABLE_BOTH 0x0003
+
+#define ESB_DISABLE_LEFT 0x0001
+#define ESB_DISABLE_RIGHT 0x0002
+
+#define ESB_DISABLE_UP 0x0001
+#define ESB_DISABLE_DOWN 0x0002
+
+#define ESB_DISABLE_LTUP ESB_DISABLE_LEFT
+#define ESB_DISABLE_RTDN ESB_DISABLE_RIGHT
+#endif
+
+#ifdef UNICODE
+#define SetProp SetPropW
+#define GetProp GetPropW
+#define RemoveProp RemovePropW
+#define EnumPropsEx EnumPropsExW
+#define EnumProps EnumPropsW
+#define SetWindowText SetWindowTextW
+#define GetWindowText GetWindowTextW
+#define GetWindowTextLength GetWindowTextLengthW
+#else
+#define SetProp SetPropA
+#define GetProp GetPropA
+#define RemoveProp RemovePropA
+#define EnumPropsEx EnumPropsExA
+#define EnumProps EnumPropsA
+#define SetWindowText SetWindowTextA
+#define GetWindowText GetWindowTextA
+#define GetWindowTextLength GetWindowTextLengthA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI SetPropA(HWND hWnd,LPCSTR lpString,HANDLE hData);
+ WINUSERAPI WINBOOL WINAPI SetPropW(HWND hWnd,LPCWSTR lpString,HANDLE hData);
+ WINUSERAPI HANDLE WINAPI GetPropA(HWND hWnd,LPCSTR lpString);
+ WINUSERAPI HANDLE WINAPI GetPropW(HWND hWnd,LPCWSTR lpString);
+ WINUSERAPI HANDLE WINAPI RemovePropA(HWND hWnd,LPCSTR lpString);
+ WINUSERAPI HANDLE WINAPI RemovePropW(HWND hWnd,LPCWSTR lpString);
+ WINUSERAPI int WINAPI EnumPropsExA(HWND hWnd,PROPENUMPROCEXA lpEnumFunc,LPARAM lParam);
+ WINUSERAPI int WINAPI EnumPropsExW(HWND hWnd,PROPENUMPROCEXW lpEnumFunc,LPARAM lParam);
+ WINUSERAPI int WINAPI EnumPropsA(HWND hWnd,PROPENUMPROCA lpEnumFunc);
+ WINUSERAPI int WINAPI EnumPropsW(HWND hWnd,PROPENUMPROCW lpEnumFunc);
+ WINUSERAPI WINBOOL WINAPI SetWindowTextA(HWND hWnd,LPCSTR lpString);
+ WINUSERAPI WINBOOL WINAPI SetWindowTextW(HWND hWnd,LPCWSTR lpString);
+ WINUSERAPI int WINAPI GetWindowTextA(HWND hWnd,LPSTR lpString,int nMaxCount);
+ WINUSERAPI int WINAPI GetWindowTextW(HWND hWnd,LPWSTR lpString,int nMaxCount);
+ WINUSERAPI int WINAPI GetWindowTextLengthA(HWND hWnd);
+ WINUSERAPI int WINAPI GetWindowTextLengthW(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI GetClientRect(HWND hWnd,LPRECT lpRect);
+ WINUSERAPI WINBOOL WINAPI GetWindowRect(HWND hWnd,LPRECT lpRect);
+ WINUSERAPI WINBOOL WINAPI AdjustWindowRect(LPRECT lpRect,DWORD dwStyle,WINBOOL bMenu);
+ WINUSERAPI WINBOOL WINAPI AdjustWindowRectEx(LPRECT lpRect,DWORD dwStyle,WINBOOL bMenu,DWORD dwExStyle);
+
+#define HELPINFO_WINDOW 0x0001
+#define HELPINFO_MENUITEM 0x0002
+
+ typedef struct tagHELPINFO {
+ UINT cbSize;
+ int iContextType;
+ int iCtrlId;
+ HANDLE hItemHandle;
+ DWORD_PTR dwContextId;
+ POINT MousePos;
+ } HELPINFO,*LPHELPINFO;
+
+ WINUSERAPI WINBOOL WINAPI SetWindowContextHelpId(HWND,DWORD);
+ WINUSERAPI DWORD WINAPI GetWindowContextHelpId(HWND);
+ WINUSERAPI WINBOOL WINAPI SetMenuContextHelpId(HMENU,DWORD);
+ WINUSERAPI DWORD WINAPI GetMenuContextHelpId(HMENU);
+
+#ifndef NOMB
+
+#define MB_OK 0x00000000L
+#define MB_OKCANCEL 0x00000001L
+#define MB_ABORTRETRYIGNORE 0x00000002L
+#define MB_YESNOCANCEL 0x00000003L
+#define MB_YESNO 0x00000004L
+#define MB_RETRYCANCEL 0x00000005L
+#define MB_CANCELTRYCONTINUE 0x00000006L
+#define MB_ICONHAND 0x00000010L
+#define MB_ICONQUESTION 0x00000020L
+#define MB_ICONEXCLAMATION 0x00000030L
+#define MB_ICONASTERISK 0x00000040L
+#define MB_USERICON 0x00000080L
+#define MB_ICONWARNING MB_ICONEXCLAMATION
+#define MB_ICONERROR MB_ICONHAND
+#define MB_ICONINFORMATION MB_ICONASTERISK
+#define MB_ICONSTOP MB_ICONHAND
+#define MB_DEFBUTTON1 0x00000000L
+#define MB_DEFBUTTON2 0x00000100L
+#define MB_DEFBUTTON3 0x00000200L
+#define MB_DEFBUTTON4 0x00000300L
+#define MB_APPLMODAL 0x00000000L
+#define MB_SYSTEMMODAL 0x00001000L
+#define MB_TASKMODAL 0x00002000L
+#define MB_HELP 0x00004000L
+#define MB_NOFOCUS 0x00008000L
+#define MB_SETFOREGROUND 0x00010000L
+#define MB_DEFAULT_DESKTOP_ONLY 0x00020000L
+#define MB_TOPMOST 0x00040000L
+#define MB_RIGHT 0x00080000L
+#define MB_RTLREADING 0x00100000L
+#define MB_SERVICE_NOTIFICATION 0x00200000L
+#define MB_SERVICE_NOTIFICATION_NT3X 0x00040000L
+#define MB_TYPEMASK 0x0000000FL
+#define MB_ICONMASK 0x000000F0L
+#define MB_DEFMASK 0x00000F00L
+#define MB_MODEMASK 0x00003000L
+#define MB_MISCMASK 0x0000C000L
+
+#ifdef UNICODE
+#define MessageBox MessageBoxW
+#define MessageBoxEx MessageBoxExW
+#else
+#define MessageBox MessageBoxA
+#define MessageBoxEx MessageBoxExA
+#endif
+
+ WINUSERAPI int WINAPI MessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType);
+ WINUSERAPI int WINAPI MessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType);
+ WINUSERAPI int WINAPI MessageBoxExA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType,WORD wLanguageId);
+ WINUSERAPI int WINAPI MessageBoxExW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType,WORD wLanguageId);
+
+ typedef VOID (CALLBACK *MSGBOXCALLBACK)(LPHELPINFO lpHelpInfo);
+
+ typedef struct tagMSGBOXPARAMSA {
+ UINT cbSize;
+ HWND hwndOwner;
+ HINSTANCE hInstance;
+ LPCSTR lpszText;
+ LPCSTR lpszCaption;
+ DWORD dwStyle;
+ LPCSTR lpszIcon;
+ DWORD_PTR dwContextHelpId;
+ MSGBOXCALLBACK lpfnMsgBoxCallback;
+ DWORD dwLanguageId;
+ } MSGBOXPARAMSA,*PMSGBOXPARAMSA,*LPMSGBOXPARAMSA;
+
+ typedef struct tagMSGBOXPARAMSW {
+ UINT cbSize;
+ HWND hwndOwner;
+ HINSTANCE hInstance;
+ LPCWSTR lpszText;
+ LPCWSTR lpszCaption;
+ DWORD dwStyle;
+ LPCWSTR lpszIcon;
+ DWORD_PTR dwContextHelpId;
+ MSGBOXCALLBACK lpfnMsgBoxCallback;
+ DWORD dwLanguageId;
+ } MSGBOXPARAMSW,*PMSGBOXPARAMSW,*LPMSGBOXPARAMSW;
+
+#ifdef UNICODE
+ typedef MSGBOXPARAMSW MSGBOXPARAMS;
+ typedef PMSGBOXPARAMSW PMSGBOXPARAMS;
+ typedef LPMSGBOXPARAMSW LPMSGBOXPARAMS;
+#else
+ typedef MSGBOXPARAMSA MSGBOXPARAMS;
+ typedef PMSGBOXPARAMSA PMSGBOXPARAMS;
+ typedef LPMSGBOXPARAMSA LPMSGBOXPARAMS;
+#endif
+
+#ifdef UNICODE
+#define MessageBoxIndirect MessageBoxIndirectW
+#else
+#define MessageBoxIndirect MessageBoxIndirectA
+#endif
+
+ WINUSERAPI int WINAPI MessageBoxIndirectA(CONST MSGBOXPARAMSA *lpmbp);
+ WINUSERAPI int WINAPI MessageBoxIndirectW(CONST MSGBOXPARAMSW *lpmbp);
+ WINUSERAPI WINBOOL WINAPI MessageBeep(UINT uType);
+#endif
+
+ WINUSERAPI int WINAPI ShowCursor(WINBOOL bShow);
+ WINUSERAPI WINBOOL WINAPI SetCursorPos(int X,int Y);
+ WINUSERAPI HCURSOR WINAPI SetCursor(HCURSOR hCursor);
+ WINUSERAPI WINBOOL WINAPI GetCursorPos(LPPOINT lpPoint);
+ WINUSERAPI WINBOOL WINAPI ClipCursor(CONST RECT *lpRect);
+ WINUSERAPI WINBOOL WINAPI GetClipCursor(LPRECT lpRect);
+ WINUSERAPI HCURSOR WINAPI GetCursor(VOID);
+ WINUSERAPI WINBOOL WINAPI CreateCaret(HWND hWnd,HBITMAP hBitmap,int nWidth,int nHeight);
+ WINUSERAPI UINT WINAPI GetCaretBlinkTime(VOID);
+ WINUSERAPI WINBOOL WINAPI SetCaretBlinkTime(UINT uMSeconds);
+ WINUSERAPI WINBOOL WINAPI DestroyCaret(VOID);
+ WINUSERAPI WINBOOL WINAPI HideCaret(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI ShowCaret(HWND hWnd);
+ WINUSERAPI WINBOOL WINAPI SetCaretPos(int X,int Y);
+ WINUSERAPI WINBOOL WINAPI GetCaretPos(LPPOINT lpPoint);
+ WINUSERAPI WINBOOL WINAPI ClientToScreen(HWND hWnd,LPPOINT lpPoint);
+ WINUSERAPI WINBOOL WINAPI ScreenToClient(HWND hWnd,LPPOINT lpPoint);
+ WINUSERAPI int WINAPI MapWindowPoints(HWND hWndFrom,HWND hWndTo,LPPOINT lpPoints,UINT cPoints);
+ WINUSERAPI HWND WINAPI WindowFromPoint(POINT Point);
+ WINUSERAPI HWND WINAPI ChildWindowFromPoint(HWND hWndParent,POINT Point);
+
+#define CWP_ALL 0x0000
+#define CWP_SKIPINVISIBLE 0x0001
+#define CWP_SKIPDISABLED 0x0002
+#define CWP_SKIPTRANSPARENT 0x0004
+
+ WINUSERAPI HWND WINAPI ChildWindowFromPointEx(HWND hwnd,POINT pt,UINT flags);
+
+#ifndef NOCOLOR
+
+#define CTLCOLOR_MSGBOX 0
+#define CTLCOLOR_EDIT 1
+#define CTLCOLOR_LISTBOX 2
+#define CTLCOLOR_BTN 3
+#define CTLCOLOR_DLG 4
+#define CTLCOLOR_SCROLLBAR 5
+#define CTLCOLOR_STATIC 6
+#define CTLCOLOR_MAX 7
+
+#define COLOR_SCROLLBAR 0
+#define COLOR_BACKGROUND 1
+#define COLOR_ACTIVECAPTION 2
+#define COLOR_INACTIVECAPTION 3
+#define COLOR_MENU 4
+#define COLOR_WINDOW 5
+#define COLOR_WINDOWFRAME 6
+#define COLOR_MENUTEXT 7
+#define COLOR_WINDOWTEXT 8
+#define COLOR_CAPTIONTEXT 9
+#define COLOR_ACTIVEBORDER 10
+#define COLOR_INACTIVEBORDER 11
+#define COLOR_APPWORKSPACE 12
+#define COLOR_HIGHLIGHT 13
+#define COLOR_HIGHLIGHTTEXT 14
+#define COLOR_BTNFACE 15
+#define COLOR_BTNSHADOW 16
+#define COLOR_GRAYTEXT 17
+#define COLOR_BTNTEXT 18
+#define COLOR_INACTIVECAPTIONTEXT 19
+#define COLOR_BTNHIGHLIGHT 20
+
+#define COLOR_3DDKSHADOW 21
+#define COLOR_3DLIGHT 22
+#define COLOR_INFOTEXT 23
+#define COLOR_INFOBK 24
+
+#define COLOR_HOTLIGHT 26
+#define COLOR_GRADIENTACTIVECAPTION 27
+#define COLOR_GRADIENTINACTIVECAPTION 28
+#define COLOR_MENUHILIGHT 29
+#define COLOR_MENUBAR 30
+
+#define COLOR_DESKTOP COLOR_BACKGROUND
+#define COLOR_3DFACE COLOR_BTNFACE
+#define COLOR_3DSHADOW COLOR_BTNSHADOW
+#define COLOR_3DHIGHLIGHT COLOR_BTNHIGHLIGHT
+#define COLOR_3DHILIGHT COLOR_BTNHIGHLIGHT
+#define COLOR_BTNHILIGHT COLOR_BTNHIGHLIGHT
+
+ WINUSERAPI DWORD WINAPI GetSysColor(int nIndex);
+ WINUSERAPI HBRUSH WINAPI GetSysColorBrush(int nIndex);
+ WINUSERAPI WINBOOL WINAPI SetSysColors(int cElements,CONST INT *lpaElements,CONST COLORREF *lpaRgbValues);
+#endif
+
+ WINUSERAPI WINBOOL WINAPI DrawFocusRect(HDC hDC,CONST RECT *lprc);
+ WINUSERAPI int WINAPI FillRect(HDC hDC,CONST RECT *lprc,HBRUSH hbr);
+ WINUSERAPI int WINAPI FrameRect(HDC hDC,CONST RECT *lprc,HBRUSH hbr);
+ WINUSERAPI WINBOOL WINAPI InvertRect(HDC hDC,CONST RECT *lprc);
+ WINUSERAPI WINBOOL WINAPI SetRect(LPRECT lprc,int xLeft,int yTop,int xRight,int yBottom);
+ WINUSERAPI WINBOOL WINAPI SetRectEmpty(LPRECT lprc);
+ WINUSERAPI WINBOOL WINAPI CopyRect(LPRECT lprcDst,CONST RECT *lprcSrc);
+ WINUSERAPI WINBOOL WINAPI InflateRect(LPRECT lprc,int dx,int dy);
+ WINUSERAPI WINBOOL WINAPI IntersectRect(LPRECT lprcDst,CONST RECT *lprcSrc1,CONST RECT *lprcSrc2);
+ WINUSERAPI WINBOOL WINAPI UnionRect(LPRECT lprcDst,CONST RECT *lprcSrc1,CONST RECT *lprcSrc2);
+ WINUSERAPI WINBOOL WINAPI SubtractRect(LPRECT lprcDst,CONST RECT *lprcSrc1,CONST RECT *lprcSrc2);
+ WINUSERAPI WINBOOL WINAPI OffsetRect(LPRECT lprc,int dx,int dy);
+ WINUSERAPI WINBOOL WINAPI IsRectEmpty(CONST RECT *lprc);
+ WINUSERAPI WINBOOL WINAPI EqualRect(CONST RECT *lprc1,CONST RECT *lprc2);
+ WINUSERAPI WINBOOL WINAPI PtInRect(CONST RECT *lprc,POINT pt);
+
+#ifndef NOWINOFFSETS
+
+#ifdef UNICODE
+#define GetWindowLong GetWindowLongW
+#define SetWindowLong SetWindowLongW
+#else
+#define GetWindowLong GetWindowLongA
+#define SetWindowLong SetWindowLongA
+#endif
+
+ WINUSERAPI WORD WINAPI GetWindowWord(HWND hWnd,int nIndex);
+ WINUSERAPI WORD WINAPI SetWindowWord(HWND hWnd,int nIndex,WORD wNewWord);
+ WINUSERAPI LONG WINAPI GetWindowLongA(HWND hWnd,int nIndex);
+ WINUSERAPI LONG WINAPI GetWindowLongW(HWND hWnd,int nIndex);
+ WINUSERAPI LONG WINAPI SetWindowLongA(HWND hWnd,int nIndex,LONG dwNewLong);
+ WINUSERAPI LONG WINAPI SetWindowLongW(HWND hWnd,int nIndex,LONG dwNewLong);
+
+#ifdef _WIN64
+
+#ifdef UNICODE
+#define GetWindowLongPtr GetWindowLongPtrW
+#define SetWindowLongPtr SetWindowLongPtrW
+#else
+#define GetWindowLongPtr GetWindowLongPtrA
+#define SetWindowLongPtr SetWindowLongPtrA
+#endif
+
+ WINUSERAPI LONG_PTR WINAPI GetWindowLongPtrA(HWND hWnd,int nIndex);
+ WINUSERAPI LONG_PTR WINAPI GetWindowLongPtrW(HWND hWnd,int nIndex);
+ WINUSERAPI LONG_PTR WINAPI SetWindowLongPtrA(HWND hWnd,int nIndex,LONG_PTR dwNewLong);
+ WINUSERAPI LONG_PTR WINAPI SetWindowLongPtrW(HWND hWnd,int nIndex,LONG_PTR dwNewLong);
+#else
+
+#ifdef UNICODE
+#define GetWindowLongPtr GetWindowLongPtrW
+#define SetWindowLongPtr SetWindowLongPtrW
+#else
+#define GetWindowLongPtr GetWindowLongPtrA
+#define SetWindowLongPtr SetWindowLongPtrA
+#endif
+
+#define GetWindowLongPtrA GetWindowLongA
+#define GetWindowLongPtrW GetWindowLongW
+#define SetWindowLongPtrA SetWindowLongA
+#define SetWindowLongPtrW SetWindowLongW
+#endif
+
+#ifdef UNICODE
+#define GetClassLong GetClassLongW
+#define SetClassLong SetClassLongW
+#else
+#define GetClassLong GetClassLongA
+#define SetClassLong SetClassLongA
+#endif
+
+ WINUSERAPI WORD WINAPI GetClassWord(HWND hWnd,int nIndex);
+ WINUSERAPI WORD WINAPI SetClassWord(HWND hWnd,int nIndex,WORD wNewWord);
+ WINUSERAPI DWORD WINAPI GetClassLongA(HWND hWnd,int nIndex);
+ WINUSERAPI DWORD WINAPI GetClassLongW(HWND hWnd,int nIndex);
+ WINUSERAPI DWORD WINAPI SetClassLongA(HWND hWnd,int nIndex,LONG dwNewLong);
+ WINUSERAPI DWORD WINAPI SetClassLongW(HWND hWnd,int nIndex,LONG dwNewLong);
+
+#ifdef _WIN64
+
+#ifdef UNICODE
+#define GetClassLongPtr GetClassLongPtrW
+#define SetClassLongPtr SetClassLongPtrW
+#else
+#define GetClassLongPtr GetClassLongPtrA
+#define SetClassLongPtr SetClassLongPtrA
+#endif
+
+ WINUSERAPI ULONG_PTR WINAPI GetClassLongPtrA(HWND hWnd,int nIndex);
+ WINUSERAPI ULONG_PTR WINAPI GetClassLongPtrW(HWND hWnd,int nIndex);
+ WINUSERAPI ULONG_PTR WINAPI SetClassLongPtrA(HWND hWnd,int nIndex,LONG_PTR dwNewLong);
+ WINUSERAPI ULONG_PTR WINAPI SetClassLongPtrW(HWND hWnd,int nIndex,LONG_PTR dwNewLong);
+#else
+#ifdef UNICODE
+#define GetClassLongPtr GetClassLongPtrW
+#define SetClassLongPtr SetClassLongPtrW
+#else
+#define GetClassLongPtr GetClassLongPtrA
+#define SetClassLongPtr SetClassLongPtrA
+#endif
+
+#define GetClassLongPtrA GetClassLongA
+#define GetClassLongPtrW GetClassLongW
+#define SetClassLongPtrA SetClassLongA
+#define SetClassLongPtrW SetClassLongW
+#endif
+#endif
+
+#ifdef UNICODE
+#define FindWindow FindWindowW
+#define FindWindowEx FindWindowExW
+#define GetClassName GetClassNameW
+#else
+#define FindWindow FindWindowA
+#define FindWindowEx FindWindowExA
+#define GetClassName GetClassNameA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI GetProcessDefaultLayout(DWORD *pdwDefaultLayout);
+ WINUSERAPI WINBOOL WINAPI SetProcessDefaultLayout(DWORD dwDefaultLayout);
+ WINUSERAPI HWND WINAPI GetDesktopWindow(VOID);
+ WINUSERAPI HWND WINAPI GetParent(HWND hWnd);
+ WINUSERAPI HWND WINAPI SetParent(HWND hWndChild,HWND hWndNewParent);
+ WINUSERAPI WINBOOL WINAPI EnumChildWindows(HWND hWndParent,WNDENUMPROC lpEnumFunc,LPARAM lParam);
+ WINUSERAPI HWND WINAPI FindWindowA(LPCSTR lpClassName,LPCSTR lpWindowName);
+ WINUSERAPI HWND WINAPI FindWindowW(LPCWSTR lpClassName,LPCWSTR lpWindowName);
+ WINUSERAPI HWND WINAPI FindWindowExA(HWND hWndParent,HWND hWndChildAfter,LPCSTR lpszClass,LPCSTR lpszWindow);
+ WINUSERAPI HWND WINAPI FindWindowExW(HWND hWndParent,HWND hWndChildAfter,LPCWSTR lpszClass,LPCWSTR lpszWindow);
+ WINUSERAPI HWND WINAPI GetShellWindow(VOID);
+ WINUSERAPI WINBOOL WINAPI RegisterShellHookWindow(HWND hwnd);
+ WINUSERAPI WINBOOL WINAPI DeregisterShellHookWindow(HWND hwnd);
+ WINUSERAPI WINBOOL WINAPI EnumWindows(WNDENUMPROC lpEnumFunc,LPARAM lParam);
+ WINUSERAPI WINBOOL WINAPI EnumThreadWindows(DWORD dwThreadId,WNDENUMPROC lpfn,LPARAM lParam);
+
+#define EnumTaskWindows(hTask,lpfn,lParam) EnumThreadWindows(HandleToUlong(hTask),lpfn,lParam)
+
+ WINUSERAPI int WINAPI GetClassNameA(HWND hWnd,LPSTR lpClassName,int nMaxCount);
+ WINUSERAPI int WINAPI GetClassNameW(HWND hWnd,LPWSTR lpClassName,int nMaxCount);
+ WINUSERAPI HWND WINAPI GetTopWindow(HWND hWnd);
+
+#define GetNextWindow(hWnd,wCmd) GetWindow(hWnd,wCmd)
+#define GetSysModalWindow() (NULL)
+#define SetSysModalWindow(hWnd) (NULL)
+
+ WINUSERAPI DWORD WINAPI GetWindowThreadProcessId(HWND hWnd,LPDWORD lpdwProcessId);
+ WINUSERAPI WINBOOL WINAPI IsGUIThread(WINBOOL bConvert);
+
+#define GetWindowTask(hWnd) ((HANDLE)(DWORD_PTR)GetWindowThreadProcessId(hWnd,NULL))
+
+ WINUSERAPI HWND WINAPI GetLastActivePopup(HWND hWnd);
+
+#define GW_HWNDFIRST 0
+#define GW_HWNDLAST 1
+#define GW_HWNDNEXT 2
+#define GW_HWNDPREV 3
+#define GW_OWNER 4
+#define GW_CHILD 5
+#define GW_ENABLEDPOPUP 6
+#define GW_MAX 6
+
+ WINUSERAPI HWND WINAPI GetWindow(HWND hWnd,UINT uCmd);
+
+#ifndef NOWH
+
+#ifdef UNICODE
+#define SetWindowsHook SetWindowsHookW
+#define SetWindowsHookEx SetWindowsHookExW
+#else
+#define SetWindowsHook SetWindowsHookA
+#define SetWindowsHookEx SetWindowsHookExA
+#endif
+
+ WINUSERAPI HHOOK WINAPI SetWindowsHookA(int nFilterType,HOOKPROC pfnFilterProc);
+ WINUSERAPI HHOOK WINAPI SetWindowsHookW(int nFilterType,HOOKPROC pfnFilterProc);
+ WINUSERAPI WINBOOL WINAPI UnhookWindowsHook(int nCode,HOOKPROC pfnFilterProc);
+ WINUSERAPI HHOOK WINAPI SetWindowsHookExA(int idHook,HOOKPROC lpfn,HINSTANCE hmod,DWORD dwThreadId);
+ WINUSERAPI HHOOK WINAPI SetWindowsHookExW(int idHook,HOOKPROC lpfn,HINSTANCE hmod,DWORD dwThreadId);
+ WINUSERAPI WINBOOL WINAPI UnhookWindowsHookEx(HHOOK hhk);
+ WINUSERAPI LRESULT WINAPI CallNextHookEx(HHOOK hhk,int nCode,WPARAM wParam,LPARAM lParam);
+#define DefHookProc(nCode,wParam,lParam,phhk) CallNextHookEx(*phhk,nCode,wParam,lParam)
+#endif
+
+#ifndef NOMENUS
+
+#define MF_INSERT 0x00000000L
+#define MF_CHANGE 0x00000080L
+#define MF_APPEND 0x00000100L
+#define MF_DELETE 0x00000200L
+#define MF_REMOVE 0x00001000L
+#define MF_BYCOMMAND 0x00000000L
+#define MF_BYPOSITION 0x00000400L
+#define MF_SEPARATOR 0x00000800L
+#define MF_ENABLED 0x00000000L
+#define MF_GRAYED 0x00000001L
+#define MF_DISABLED 0x00000002L
+#define MF_UNCHECKED 0x00000000L
+#define MF_CHECKED 0x00000008L
+#define MF_USECHECKBITMAPS 0x00000200L
+#define MF_STRING 0x00000000L
+#define MF_BITMAP 0x00000004L
+#define MF_OWNERDRAW 0x00000100L
+#define MF_POPUP 0x00000010L
+#define MF_MENUBARBREAK 0x00000020L
+#define MF_MENUBREAK 0x00000040L
+#define MF_UNHILITE 0x00000000L
+#define MF_HILITE 0x00000080L
+#define MF_DEFAULT 0x00001000L
+#define MF_SYSMENU 0x00002000L
+#define MF_HELP 0x00004000L
+#define MF_RIGHTJUSTIFY 0x00004000L
+#define MF_MOUSESELECT 0x00008000L
+#define MF_END 0x00000080L
+
+#define MFT_STRING MF_STRING
+#define MFT_BITMAP MF_BITMAP
+#define MFT_MENUBARBREAK MF_MENUBARBREAK
+#define MFT_MENUBREAK MF_MENUBREAK
+#define MFT_OWNERDRAW MF_OWNERDRAW
+#define MFT_RADIOCHECK 0x00000200L
+#define MFT_SEPARATOR MF_SEPARATOR
+#define MFT_RIGHTORDER 0x00002000L
+#define MFT_RIGHTJUSTIFY MF_RIGHTJUSTIFY
+
+#define MFS_GRAYED 0x00000003L
+#define MFS_DISABLED MFS_GRAYED
+#define MFS_CHECKED MF_CHECKED
+#define MFS_HILITE MF_HILITE
+#define MFS_ENABLED MF_ENABLED
+#define MFS_UNCHECKED MF_UNCHECKED
+#define MFS_UNHILITE MF_UNHILITE
+#define MFS_DEFAULT MF_DEFAULT
+
+ WINUSERAPI WINBOOL WINAPI CheckMenuRadioItem(HMENU hmenu,UINT first,UINT last,UINT check,UINT flags);
+
+ typedef struct {
+ WORD versionNumber;
+ WORD offset;
+ } MENUITEMTEMPLATEHEADER,*PMENUITEMTEMPLATEHEADER;
+
+ typedef struct {
+ WORD mtOption;
+ WORD mtID;
+ WCHAR mtString[1];
+ } MENUITEMTEMPLATE,*PMENUITEMTEMPLATE;
+#define MF_END 0x00000080L
+#endif
+
+#ifndef NOSYSCOMMANDS
+
+#define SC_SIZE 0xF000
+#define SC_MOVE 0xF010
+#define SC_MINIMIZE 0xF020
+#define SC_MAXIMIZE 0xF030
+#define SC_NEXTWINDOW 0xF040
+#define SC_PREVWINDOW 0xF050
+#define SC_CLOSE 0xF060
+#define SC_VSCROLL 0xF070
+#define SC_HSCROLL 0xF080
+#define SC_MOUSEMENU 0xF090
+#define SC_KEYMENU 0xF100
+#define SC_ARRANGE 0xF110
+#define SC_RESTORE 0xF120
+#define SC_TASKLIST 0xF130
+#define SC_SCREENSAVE 0xF140
+#define SC_HOTKEY 0xF150
+#define SC_DEFAULT 0xF160
+#define SC_MONITORPOWER 0xF170
+#define SC_CONTEXTHELP 0xF180
+#define SC_SEPARATOR 0xF00F
+#define SC_ICON SC_MINIMIZE
+#define SC_ZOOM SC_MAXIMIZE
+#endif
+
+#ifdef UNICODE
+#define LoadBitmap LoadBitmapW
+#define LoadCursor LoadCursorW
+#define LoadCursorFromFile LoadCursorFromFileW
+#else
+#define LoadBitmap LoadBitmapA
+#define LoadCursor LoadCursorA
+#define LoadCursorFromFile LoadCursorFromFileA
+#endif
+
+ WINUSERAPI HBITMAP WINAPI LoadBitmapA(HINSTANCE hInstance,LPCSTR lpBitmapName);
+ WINUSERAPI HBITMAP WINAPI LoadBitmapW(HINSTANCE hInstance,LPCWSTR lpBitmapName);
+ WINUSERAPI HCURSOR WINAPI LoadCursorA(HINSTANCE hInstance,LPCSTR lpCursorName);
+ WINUSERAPI HCURSOR WINAPI LoadCursorW(HINSTANCE hInstance,LPCWSTR lpCursorName);
+ WINUSERAPI HCURSOR WINAPI LoadCursorFromFileA(LPCSTR lpFileName);
+ WINUSERAPI HCURSOR WINAPI LoadCursorFromFileW(LPCWSTR lpFileName);
+ WINUSERAPI HCURSOR WINAPI CreateCursor(HINSTANCE hInst,int xHotSpot,int yHotSpot,int nWidth,int nHeight,CONST VOID *pvANDPlane,CONST VOID *pvXORPlane);
+ WINUSERAPI WINBOOL WINAPI DestroyCursor(HCURSOR hCursor);
+
+#define CopyCursor(pcur) ((HCURSOR)CopyIcon((HICON)(pcur)))
+
+#define IDC_ARROW MAKEINTRESOURCE(32512)
+#define IDC_IBEAM MAKEINTRESOURCE(32513)
+#define IDC_WAIT MAKEINTRESOURCE(32514)
+#define IDC_CROSS MAKEINTRESOURCE(32515)
+#define IDC_UPARROW MAKEINTRESOURCE(32516)
+#define IDC_SIZE MAKEINTRESOURCE(32640)
+#define IDC_ICON MAKEINTRESOURCE(32641)
+#define IDC_SIZENWSE MAKEINTRESOURCE(32642)
+#define IDC_SIZENESW MAKEINTRESOURCE(32643)
+#define IDC_SIZEWE MAKEINTRESOURCE(32644)
+#define IDC_SIZENS MAKEINTRESOURCE(32645)
+#define IDC_SIZEALL MAKEINTRESOURCE(32646)
+#define IDC_NO MAKEINTRESOURCE(32648)
+#define IDC_HAND MAKEINTRESOURCE(32649)
+#define IDC_APPSTARTING MAKEINTRESOURCE(32650)
+#define IDC_HELP MAKEINTRESOURCE(32651)
+
+ WINUSERAPI WINBOOL WINAPI SetSystemCursor(HCURSOR hcur,DWORD id);
+
+ typedef struct _ICONINFO {
+ WINBOOL fIcon;
+ DWORD xHotspot;
+ DWORD yHotspot;
+ HBITMAP hbmMask;
+ HBITMAP hbmColor;
+ } ICONINFO;
+ typedef ICONINFO *PICONINFO;
+
+#ifdef UNICODE
+#define LoadIcon LoadIconW
+#define PrivateExtractIcons PrivateExtractIconsW
+#else
+#define LoadIcon LoadIconA
+#define PrivateExtractIcons PrivateExtractIconsA
+#endif
+
+ WINUSERAPI HICON WINAPI LoadIconA(HINSTANCE hInstance,LPCSTR lpIconName);
+ WINUSERAPI HICON WINAPI LoadIconW(HINSTANCE hInstance,LPCWSTR lpIconName);
+ WINUSERAPI UINT WINAPI PrivateExtractIconsA(LPCSTR szFileName,int nIconIndex,int cxIcon,int cyIcon,HICON *phicon,UINT *piconid,UINT nIcons,UINT flags);
+ WINUSERAPI UINT WINAPI PrivateExtractIconsW(LPCWSTR szFileName,int nIconIndex,int cxIcon,int cyIcon,HICON *phicon,UINT *piconid,UINT nIcons,UINT flags);
+ WINUSERAPI HICON WINAPI CreateIcon(HINSTANCE hInstance,int nWidth,int nHeight,BYTE cPlanes,BYTE cBitsPixel,CONST BYTE *lpbANDbits,CONST BYTE *lpbXORbits);
+ WINUSERAPI WINBOOL WINAPI DestroyIcon(HICON hIcon);
+ WINUSERAPI int WINAPI LookupIconIdFromDirectory(PBYTE presbits,WINBOOL fIcon);
+ WINUSERAPI int WINAPI LookupIconIdFromDirectoryEx(PBYTE presbits,WINBOOL fIcon,int cxDesired,int cyDesired,UINT Flags);
+ WINUSERAPI HICON WINAPI CreateIconFromResource(PBYTE presbits,DWORD dwResSize,WINBOOL fIcon,DWORD dwVer);
+ WINUSERAPI HICON WINAPI CreateIconFromResourceEx(PBYTE presbits,DWORD dwResSize,WINBOOL fIcon,DWORD dwVer,int cxDesired,int cyDesired,UINT Flags);
+
+ typedef struct tagCURSORSHAPE {
+ int xHotSpot;
+ int yHotSpot;
+ int cx;
+ int cy;
+ int cbWidth;
+ BYTE Planes;
+ BYTE BitsPixel;
+ } CURSORSHAPE,*LPCURSORSHAPE;
+
+#define IMAGE_BITMAP 0
+#define IMAGE_ICON 1
+#define IMAGE_CURSOR 2
+#define IMAGE_ENHMETAFILE 3
+
+#define LR_DEFAULTCOLOR 0x0000
+#define LR_MONOCHROME 0x0001
+#define LR_COLOR 0x0002
+#define LR_COPYRETURNORG 0x0004
+#define LR_COPYDELETEORG 0x0008
+#define LR_LOADFROMFILE 0x0010
+#define LR_LOADTRANSPARENT 0x0020
+#define LR_DEFAULTSIZE 0x0040
+#define LR_VGACOLOR 0x0080
+#define LR_LOADMAP3DCOLORS 0x1000
+#define LR_CREATEDIBSECTION 0x2000
+#define LR_COPYFROMRESOURCE 0x4000
+#define LR_SHARED 0x8000
+
+#ifdef UNICODE
+#define LoadImage LoadImageW
+#else
+#define LoadImage LoadImageA
+#endif
+
+ WINUSERAPI HANDLE WINAPI LoadImageA(HINSTANCE hInst,LPCSTR name,UINT type,int cx,int cy,UINT fuLoad);
+ WINUSERAPI HANDLE WINAPI LoadImageW(HINSTANCE hInst,LPCWSTR name,UINT type,int cx,int cy,UINT fuLoad);
+ WINUSERAPI HANDLE WINAPI CopyImage(HANDLE h,UINT type,int cx,int cy,UINT flags);
+
+#define DI_MASK 0x0001
+#define DI_IMAGE 0x0002
+#define DI_NORMAL 0x0003
+#define DI_COMPAT 0x0004
+#define DI_DEFAULTSIZE 0x0008
+#define DI_NOMIRROR 0x0010
+
+ WINUSERAPI WINBOOL WINAPI DrawIconEx(HDC hdc,int xLeft,int yTop,HICON hIcon,int cxWidth,int cyWidth,UINT istepIfAniCur,HBRUSH hbrFlickerFreeDraw,UINT diFlags);
+ WINUSERAPI HICON WINAPI CreateIconIndirect(PICONINFO piconinfo);
+ WINUSERAPI HICON WINAPI CopyIcon(HICON hIcon);
+ WINUSERAPI WINBOOL WINAPI GetIconInfo(HICON hIcon,PICONINFO piconinfo);
+
+#define RES_ICON 1
+#define RES_CURSOR 2
+
+#ifdef OEMRESOURCE
+
+#define OBM_CLOSE 32754
+#define OBM_UPARROW 32753
+#define OBM_DNARROW 32752
+#define OBM_RGARROW 32751
+#define OBM_LFARROW 32750
+#define OBM_REDUCE 32749
+#define OBM_ZOOM 32748
+#define OBM_RESTORE 32747
+#define OBM_REDUCED 32746
+#define OBM_ZOOMD 32745
+#define OBM_RESTORED 32744
+#define OBM_UPARROWD 32743
+#define OBM_DNARROWD 32742
+#define OBM_RGARROWD 32741
+#define OBM_LFARROWD 32740
+#define OBM_MNARROW 32739
+#define OBM_COMBO 32738
+#define OBM_UPARROWI 32737
+#define OBM_DNARROWI 32736
+#define OBM_RGARROWI 32735
+#define OBM_LFARROWI 32734
+
+#define OBM_OLD_CLOSE 32767
+#define OBM_SIZE 32766
+#define OBM_OLD_UPARROW 32765
+#define OBM_OLD_DNARROW 32764
+#define OBM_OLD_RGARROW 32763
+#define OBM_OLD_LFARROW 32762
+#define OBM_BTSIZE 32761
+#define OBM_CHECK 32760
+#define OBM_CHECKBOXES 32759
+#define OBM_BTNCORNERS 32758
+#define OBM_OLD_REDUCE 32757
+#define OBM_OLD_ZOOM 32756
+#define OBM_OLD_RESTORE 32755
+
+#define OCR_NORMAL 32512
+#define OCR_IBEAM 32513
+#define OCR_WAIT 32514
+#define OCR_CROSS 32515
+#define OCR_UP 32516
+#define OCR_SIZE 32640
+#define OCR_ICON 32641
+#define OCR_SIZENWSE 32642
+#define OCR_SIZENESW 32643
+#define OCR_SIZEWE 32644
+#define OCR_SIZENS 32645
+#define OCR_SIZEALL 32646
+#define OCR_ICOCUR 32647
+#define OCR_NO 32648
+#define OCR_HAND 32649
+#define OCR_APPSTARTING 32650
+
+#define OIC_SAMPLE 32512
+#define OIC_HAND 32513
+#define OIC_QUES 32514
+#define OIC_BANG 32515
+#define OIC_NOTE 32516
+#define OIC_WINLOGO 32517
+#define OIC_WARNING OIC_BANG
+#define OIC_ERROR OIC_HAND
+#define OIC_INFORMATION OIC_NOTE
+#endif
+
+#define ORD_LANGDRIVER 1
+
+#ifndef NOICONS
+
+#ifdef RC_INVOKED
+#define IDI_APPLICATION 32512
+#define IDI_HAND 32513
+#define IDI_QUESTION 32514
+#define IDI_EXCLAMATION 32515
+#define IDI_ASTERISK 32516
+#define IDI_WINLOGO 32517
+#else
+#define IDI_APPLICATION MAKEINTRESOURCE(32512)
+#define IDI_HAND MAKEINTRESOURCE(32513)
+#define IDI_QUESTION MAKEINTRESOURCE(32514)
+#define IDI_EXCLAMATION MAKEINTRESOURCE(32515)
+#define IDI_ASTERISK MAKEINTRESOURCE(32516)
+#define IDI_WINLOGO MAKEINTRESOURCE(32517)
+#endif
+
+#define IDI_WARNING IDI_EXCLAMATION
+#define IDI_ERROR IDI_HAND
+#define IDI_INFORMATION IDI_ASTERISK
+#endif
+
+#ifdef UNICODE
+#define LoadString LoadStringW
+#else
+#define LoadString LoadStringA
+#endif
+
+ WINUSERAPI int WINAPI LoadStringA(HINSTANCE hInstance,UINT uID,LPSTR lpBuffer,int cchBufferMax);
+ WINUSERAPI int WINAPI LoadStringW(HINSTANCE hInstance,UINT uID,LPWSTR lpBuffer,int cchBufferMax);
+
+#define IDOK 1
+#define IDCANCEL 2
+#define IDABORT 3
+#define IDRETRY 4
+#define IDIGNORE 5
+#define IDYES 6
+#define IDNO 7
+#define IDCLOSE 8
+#define IDHELP 9
+#define IDTRYAGAIN 10
+#define IDCONTINUE 11
+
+#ifndef IDTIMEOUT
+#define IDTIMEOUT 32000
+#endif
+
+#ifndef NOCTLMGR
+
+#ifndef NOWINSTYLES
+#define ES_LEFT 0x0000L
+#define ES_CENTER 0x0001L
+#define ES_RIGHT 0x0002L
+#define ES_MULTILINE 0x0004L
+#define ES_UPPERCASE 0x0008L
+#define ES_LOWERCASE 0x0010L
+#define ES_PASSWORD 0x0020L
+#define ES_AUTOVSCROLL 0x0040L
+#define ES_AUTOHSCROLL 0x0080L
+#define ES_NOHIDESEL 0x0100L
+#define ES_OEMCONVERT 0x0400L
+#define ES_READONLY 0x0800L
+#define ES_WANTRETURN 0x1000L
+#define ES_NUMBER 0x2000L
+#endif
+
+#define EN_SETFOCUS 0x0100
+#define EN_KILLFOCUS 0x0200
+#define EN_CHANGE 0x0300
+#define EN_UPDATE 0x0400
+#define EN_ERRSPACE 0x0500
+#define EN_MAXTEXT 0x0501
+#define EN_HSCROLL 0x0601
+#define EN_VSCROLL 0x0602
+#define EN_ALIGN_LTR_EC 0x0700
+#define EN_ALIGN_RTL_EC 0x0701
+
+#define EC_LEFTMARGIN 0x0001
+#define EC_RIGHTMARGIN 0x0002
+#define EC_USEFONTINFO 0xffff
+
+#define EMSIS_COMPOSITIONSTRING 0x0001
+
+#define EIMES_GETCOMPSTRATONCE 0x0001
+#define EIMES_CANCELCOMPSTRINFOCUS 0x0002
+#define EIMES_COMPLETECOMPSTRKILLFOCUS 0x0004
+
+#ifndef NOWINMESSAGES
+
+#define EM_GETSEL 0x00B0
+#define EM_SETSEL 0x00B1
+#define EM_GETRECT 0x00B2
+#define EM_SETRECT 0x00B3
+#define EM_SETRECTNP 0x00B4
+#define EM_SCROLL 0x00B5
+#define EM_LINESCROLL 0x00B6
+#define EM_SCROLLCARET 0x00B7
+#define EM_GETMODIFY 0x00B8
+#define EM_SETMODIFY 0x00B9
+#define EM_GETLINECOUNT 0x00BA
+#define EM_LINEINDEX 0x00BB
+#define EM_SETHANDLE 0x00BC
+#define EM_GETHANDLE 0x00BD
+#define EM_GETTHUMB 0x00BE
+#define EM_LINELENGTH 0x00C1
+#define EM_REPLACESEL 0x00C2
+#define EM_GETLINE 0x00C4
+#define EM_LIMITTEXT 0x00C5
+#define EM_CANUNDO 0x00C6
+#define EM_UNDO 0x00C7
+#define EM_FMTLINES 0x00C8
+#define EM_LINEFROMCHAR 0x00C9
+#define EM_SETTABSTOPS 0x00CB
+#define EM_SETPASSWORDCHAR 0x00CC
+#define EM_EMPTYUNDOBUFFER 0x00CD
+#define EM_GETFIRSTVISIBLELINE 0x00CE
+#define EM_SETREADONLY 0x00CF
+#define EM_SETWORDBREAKPROC 0x00D0
+#define EM_GETWORDBREAKPROC 0x00D1
+#define EM_GETPASSWORDCHAR 0x00D2
+#define EM_SETMARGINS 0x00D3
+#define EM_GETMARGINS 0x00D4
+#define EM_SETLIMITTEXT EM_LIMITTEXT
+#define EM_GETLIMITTEXT 0x00D5
+#define EM_POSFROMCHAR 0x00D6
+#define EM_CHARFROMPOS 0x00D7
+#define EM_SETIMESTATUS 0x00D8
+#define EM_GETIMESTATUS 0x00D9
+#endif
+
+#define WB_LEFT 0
+#define WB_RIGHT 1
+#define WB_ISDELIMITER 2
+
+#define BS_PUSHBUTTON 0x00000000L
+#define BS_DEFPUSHBUTTON 0x00000001L
+#define BS_CHECKBOX 0x00000002L
+#define BS_AUTOCHECKBOX 0x00000003L
+#define BS_RADIOBUTTON 0x00000004L
+#define BS_3STATE 0x00000005L
+#define BS_AUTO3STATE 0x00000006L
+#define BS_GROUPBOX 0x00000007L
+#define BS_USERBUTTON 0x00000008L
+#define BS_AUTORADIOBUTTON 0x00000009L
+#define BS_PUSHBOX 0x0000000AL
+#define BS_OWNERDRAW 0x0000000BL
+#define BS_TYPEMASK 0x0000000FL
+#define BS_LEFTTEXT 0x00000020L
+#define BS_TEXT 0x00000000L
+#define BS_ICON 0x00000040L
+#define BS_BITMAP 0x00000080L
+#define BS_LEFT 0x00000100L
+#define BS_RIGHT 0x00000200L
+#define BS_CENTER 0x00000300L
+#define BS_TOP 0x00000400L
+#define BS_BOTTOM 0x00000800L
+#define BS_VCENTER 0x00000C00L
+#define BS_PUSHLIKE 0x00001000L
+#define BS_MULTILINE 0x00002000L
+#define BS_NOTIFY 0x00004000L
+#define BS_FLAT 0x00008000L
+#define BS_RIGHTBUTTON BS_LEFTTEXT
+
+#define BN_CLICKED 0
+#define BN_PAINT 1
+#define BN_HILITE 2
+#define BN_UNHILITE 3
+#define BN_DISABLE 4
+#define BN_DOUBLECLICKED 5
+#define BN_PUSHED BN_HILITE
+#define BN_UNPUSHED BN_UNHILITE
+#define BN_DBLCLK BN_DOUBLECLICKED
+#define BN_SETFOCUS 6
+#define BN_KILLFOCUS 7
+
+#define BM_GETCHECK 0x00F0
+#define BM_SETCHECK 0x00F1
+#define BM_GETSTATE 0x00F2
+#define BM_SETSTATE 0x00F3
+#define BM_SETSTYLE 0x00F4
+#define BM_CLICK 0x00F5
+#define BM_GETIMAGE 0x00F6
+#define BM_SETIMAGE 0x00F7
+
+#define BST_UNCHECKED 0x0000
+#define BST_CHECKED 0x0001
+#define BST_INDETERMINATE 0x0002
+#define BST_PUSHED 0x0004
+#define BST_FOCUS 0x0008
+
+#define SS_LEFT 0x00000000L
+#define SS_CENTER 0x00000001L
+#define SS_RIGHT 0x00000002L
+#define SS_ICON 0x00000003L
+#define SS_BLACKRECT 0x00000004L
+#define SS_GRAYRECT 0x00000005L
+#define SS_WHITERECT 0x00000006L
+#define SS_BLACKFRAME 0x00000007L
+#define SS_GRAYFRAME 0x00000008L
+#define SS_WHITEFRAME 0x00000009L
+#define SS_USERITEM 0x0000000AL
+#define SS_SIMPLE 0x0000000BL
+#define SS_LEFTNOWORDWRAP 0x0000000CL
+#define SS_OWNERDRAW 0x0000000DL
+#define SS_BITMAP 0x0000000EL
+#define SS_ENHMETAFILE 0x0000000FL
+#define SS_ETCHEDHORZ 0x00000010L
+#define SS_ETCHEDVERT 0x00000011L
+#define SS_ETCHEDFRAME 0x00000012L
+#define SS_TYPEMASK 0x0000001FL
+#define SS_REALSIZECONTROL 0x00000040L
+#define SS_NOPREFIX 0x00000080L
+#define SS_NOTIFY 0x00000100L
+#define SS_CENTERIMAGE 0x00000200L
+#define SS_RIGHTJUST 0x00000400L
+#define SS_REALSIZEIMAGE 0x00000800L
+#define SS_SUNKEN 0x00001000L
+#define SS_EDITCONTROL 0x00002000L
+#define SS_ENDELLIPSIS 0x00004000L
+#define SS_PATHELLIPSIS 0x00008000L
+#define SS_WORDELLIPSIS 0x0000C000L
+#define SS_ELLIPSISMASK 0x0000C000L
+
+#ifndef NOWINMESSAGES
+
+#define STM_SETICON 0x0170
+#define STM_GETICON 0x0171
+#define STM_SETIMAGE 0x0172
+#define STM_GETIMAGE 0x0173
+#define STN_CLICKED 0
+#define STN_DBLCLK 1
+#define STN_ENABLE 2
+#define STN_DISABLE 3
+#define STM_MSGMAX 0x0174
+#endif
+
+#define WC_DIALOG (MAKEINTATOM(0x8002))
+
+#define DWL_MSGRESULT 0
+#define DWL_DLGPROC 4
+#define DWL_USER 8
+
+#ifdef _WIN64
+
+#undef DWL_MSGRESULT
+#undef DWL_DLGPROC
+#undef DWL_USER
+#endif
+
+#define DWLP_MSGRESULT 0
+#define DWLP_DLGPROC DWLP_MSGRESULT + sizeof(LRESULT)
+#define DWLP_USER DWLP_DLGPROC + sizeof(DLGPROC)
+
+#ifndef NOMSG
+
+#ifdef UNICODE
+#define IsDialogMessage IsDialogMessageW
+#else
+#define IsDialogMessage IsDialogMessageA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI IsDialogMessageA(HWND hDlg,LPMSG lpMsg);
+ WINUSERAPI WINBOOL WINAPI IsDialogMessageW(HWND hDlg,LPMSG lpMsg);
+#endif
+
+#ifdef UNICODE
+#define DlgDirList DlgDirListW
+#define DlgDirSelectEx DlgDirSelectExW
+#define DlgDirListComboBox DlgDirListComboBoxW
+#define DlgDirSelectComboBoxEx DlgDirSelectComboBoxExW
+#else
+#define DlgDirList DlgDirListA
+#define DlgDirSelectEx DlgDirSelectExA
+#define DlgDirListComboBox DlgDirListComboBoxA
+#define DlgDirSelectComboBoxEx DlgDirSelectComboBoxExA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI MapDialogRect(HWND hDlg,LPRECT lpRect);
+ WINUSERAPI int WINAPI DlgDirListA(HWND hDlg,LPSTR lpPathSpec,int nIDListBox,int nIDStaticPath,UINT uFileType);
+ WINUSERAPI int WINAPI DlgDirListW(HWND hDlg,LPWSTR lpPathSpec,int nIDListBox,int nIDStaticPath,UINT uFileType);
+
+#define DDL_READWRITE 0x0000
+#define DDL_READONLY 0x0001
+#define DDL_HIDDEN 0x0002
+#define DDL_SYSTEM 0x0004
+#define DDL_DIRECTORY 0x0010
+#define DDL_ARCHIVE 0x0020
+
+#define DDL_POSTMSGS 0x2000
+#define DDL_DRIVES 0x4000
+#define DDL_EXCLUSIVE 0x8000
+
+ WINUSERAPI WINBOOL WINAPI DlgDirSelectExA(HWND hwndDlg,LPSTR lpString,int chCount,int idListBox);
+ WINUSERAPI WINBOOL WINAPI DlgDirSelectExW(HWND hwndDlg,LPWSTR lpString,int chCount,int idListBox);
+ WINUSERAPI int WINAPI DlgDirListComboBoxA(HWND hDlg,LPSTR lpPathSpec,int nIDComboBox,int nIDStaticPath,UINT uFiletype);
+ WINUSERAPI int WINAPI DlgDirListComboBoxW(HWND hDlg,LPWSTR lpPathSpec,int nIDComboBox,int nIDStaticPath,UINT uFiletype);
+ WINUSERAPI WINBOOL WINAPI DlgDirSelectComboBoxExA(HWND hwndDlg,LPSTR lpString,int cchOut,int idComboBox);
+ WINUSERAPI WINBOOL WINAPI DlgDirSelectComboBoxExW(HWND hwndDlg,LPWSTR lpString,int cchOut,int idComboBox);
+
+#define DS_ABSALIGN 0x01L
+#define DS_SYSMODAL 0x02L
+#define DS_LOCALEDIT 0x20L
+#define DS_SETFONT 0x40L
+#define DS_MODALFRAME 0x80L
+#define DS_NOIDLEMSG 0x100L
+#define DS_SETFOREGROUND 0x200L
+
+#define DS_3DLOOK 0x0004L
+#define DS_FIXEDSYS 0x0008L
+#define DS_NOFAILCREATE 0x0010L
+#define DS_CONTROL 0x0400L
+#define DS_CENTER 0x0800L
+#define DS_CENTERMOUSE 0x1000L
+#define DS_CONTEXTHELP 0x2000L
+
+#define DS_SHELLFONT (DS_SETFONT | DS_FIXEDSYS)
+
+#if(_WIN32_WCE >= 0x0500)
+#define DS_USEPIXELS 0x8000L
+#endif
+
+#define DM_GETDEFID (WM_USER+0)
+#define DM_SETDEFID (WM_USER+1)
+#define DM_REPOSITION (WM_USER+2)
+
+#define DC_HASDEFID 0x534B
+
+#define DLGC_WANTARROWS 0x0001
+#define DLGC_WANTTAB 0x0002
+#define DLGC_WANTALLKEYS 0x0004
+#define DLGC_WANTMESSAGE 0x0004
+#define DLGC_HASSETSEL 0x0008
+#define DLGC_DEFPUSHBUTTON 0x0010
+#define DLGC_UNDEFPUSHBUTTON 0x0020
+#define DLGC_RADIOBUTTON 0x0040
+#define DLGC_WANTCHARS 0x0080
+#define DLGC_STATIC 0x0100
+#define DLGC_BUTTON 0x2000
+
+#define LB_CTLCODE 0L
+
+#define LB_OKAY 0
+#define LB_ERR (-1)
+#define LB_ERRSPACE (-2)
+
+#define LBN_ERRSPACE (-2)
+#define LBN_SELCHANGE 1
+#define LBN_DBLCLK 2
+#define LBN_SELCANCEL 3
+#define LBN_SETFOCUS 4
+#define LBN_KILLFOCUS 5
+
+#ifndef NOWINMESSAGES
+
+#define LB_ADDSTRING 0x0180
+#define LB_INSERTSTRING 0x0181
+#define LB_DELETESTRING 0x0182
+#define LB_SELITEMRANGEEX 0x0183
+#define LB_RESETCONTENT 0x0184
+#define LB_SETSEL 0x0185
+#define LB_SETCURSEL 0x0186
+#define LB_GETSEL 0x0187
+#define LB_GETCURSEL 0x0188
+#define LB_GETTEXT 0x0189
+#define LB_GETTEXTLEN 0x018A
+#define LB_GETCOUNT 0x018B
+#define LB_SELECTSTRING 0x018C
+#define LB_DIR 0x018D
+#define LB_GETTOPINDEX 0x018E
+#define LB_FINDSTRING 0x018F
+#define LB_GETSELCOUNT 0x0190
+#define LB_GETSELITEMS 0x0191
+#define LB_SETTABSTOPS 0x0192
+#define LB_GETHORIZONTALEXTENT 0x0193
+#define LB_SETHORIZONTALEXTENT 0x0194
+#define LB_SETCOLUMNWIDTH 0x0195
+#define LB_ADDFILE 0x0196
+#define LB_SETTOPINDEX 0x0197
+#define LB_GETITEMRECT 0x0198
+#define LB_GETITEMDATA 0x0199
+#define LB_SETITEMDATA 0x019A
+#define LB_SELITEMRANGE 0x019B
+#define LB_SETANCHORINDEX 0x019C
+#define LB_GETANCHORINDEX 0x019D
+#define LB_SETCARETINDEX 0x019E
+#define LB_GETCARETINDEX 0x019F
+#define LB_SETITEMHEIGHT 0x01A0
+#define LB_GETITEMHEIGHT 0x01A1
+#define LB_FINDSTRINGEXACT 0x01A2
+#define LB_SETLOCALE 0x01A5
+#define LB_GETLOCALE 0x01A6
+#define LB_SETCOUNT 0x01A7
+#define LB_INITSTORAGE 0x01A8
+#define LB_ITEMFROMPOINT 0x01A9
+#if(_WIN32_WCE >= 0x0400)
+#define LB_MULTIPLEADDSTRING 0x01B1
+#endif
+#define LB_GETLISTBOXINFO 0x01B2
+#define LB_MSGMAX 0x01B3
+#endif
+
+#ifndef NOWINSTYLES
+
+#define LBS_NOTIFY 0x0001L
+#define LBS_SORT 0x0002L
+#define LBS_NOREDRAW 0x0004L
+#define LBS_MULTIPLESEL 0x0008L
+#define LBS_OWNERDRAWFIXED 0x0010L
+#define LBS_OWNERDRAWVARIABLE 0x0020L
+#define LBS_HASSTRINGS 0x0040L
+#define LBS_USETABSTOPS 0x0080L
+#define LBS_NOINTEGRALHEIGHT 0x0100L
+#define LBS_MULTICOLUMN 0x0200L
+#define LBS_WANTKEYBOARDINPUT 0x0400L
+#define LBS_EXTENDEDSEL 0x0800L
+#define LBS_DISABLENOSCROLL 0x1000L
+#define LBS_NODATA 0x2000L
+#define LBS_NOSEL 0x4000L
+#define LBS_COMBOBOX 0x8000L
+
+#define LBS_STANDARD (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER)
+#endif
+
+#define CB_OKAY 0
+#define CB_ERR (-1)
+#define CB_ERRSPACE (-2)
+
+#define CBN_ERRSPACE (-1)
+#define CBN_SELCHANGE 1
+#define CBN_DBLCLK 2
+#define CBN_SETFOCUS 3
+#define CBN_KILLFOCUS 4
+#define CBN_EDITCHANGE 5
+#define CBN_EDITUPDATE 6
+#define CBN_DROPDOWN 7
+#define CBN_CLOSEUP 8
+#define CBN_SELENDOK 9
+#define CBN_SELENDCANCEL 10
+
+#ifndef NOWINSTYLES
+
+#define CBS_SIMPLE 0x0001L
+#define CBS_DROPDOWN 0x0002L
+#define CBS_DROPDOWNLIST 0x0003L
+#define CBS_OWNERDRAWFIXED 0x0010L
+#define CBS_OWNERDRAWVARIABLE 0x0020L
+#define CBS_AUTOHSCROLL 0x0040L
+#define CBS_OEMCONVERT 0x0080L
+#define CBS_SORT 0x0100L
+#define CBS_HASSTRINGS 0x0200L
+#define CBS_NOINTEGRALHEIGHT 0x0400L
+#define CBS_DISABLENOSCROLL 0x0800L
+#define CBS_UPPERCASE 0x2000L
+#define CBS_LOWERCASE 0x4000L
+#endif
+
+#ifndef NOWINMESSAGES
+#define CB_GETEDITSEL 0x0140
+#define CB_LIMITTEXT 0x0141
+#define CB_SETEDITSEL 0x0142
+#define CB_ADDSTRING 0x0143
+#define CB_DELETESTRING 0x0144
+#define CB_DIR 0x0145
+#define CB_GETCOUNT 0x0146
+#define CB_GETCURSEL 0x0147
+#define CB_GETLBTEXT 0x0148
+#define CB_GETLBTEXTLEN 0x0149
+#define CB_INSERTSTRING 0x014A
+#define CB_RESETCONTENT 0x014B
+#define CB_FINDSTRING 0x014C
+#define CB_SELECTSTRING 0x014D
+#define CB_SETCURSEL 0x014E
+#define CB_SHOWDROPDOWN 0x014F
+#define CB_GETITEMDATA 0x0150
+#define CB_SETITEMDATA 0x0151
+#define CB_GETDROPPEDCONTROLRECT 0x0152
+#define CB_SETITEMHEIGHT 0x0153
+#define CB_GETITEMHEIGHT 0x0154
+#define CB_SETEXTENDEDUI 0x0155
+#define CB_GETEXTENDEDUI 0x0156
+#define CB_GETDROPPEDSTATE 0x0157
+#define CB_FINDSTRINGEXACT 0x0158
+#define CB_SETLOCALE 0x0159
+#define CB_GETLOCALE 0x015A
+#define CB_GETTOPINDEX 0x015b
+#define CB_SETTOPINDEX 0x015c
+#define CB_GETHORIZONTALEXTENT 0x015d
+#define CB_SETHORIZONTALEXTENT 0x015e
+#define CB_GETDROPPEDWIDTH 0x015f
+#define CB_SETDROPPEDWIDTH 0x0160
+#define CB_INITSTORAGE 0x0161
+#if(_WIN32_WCE >= 0x0400)
+#define CB_MULTIPLEADDSTRING 0x0163
+#endif
+#define CB_GETCOMBOBOXINFO 0x0164
+#define CB_MSGMAX 0x0165
+#endif
+
+#ifndef NOWINSTYLES
+
+#define SBS_HORZ 0x0000L
+#define SBS_VERT 0x0001L
+#define SBS_TOPALIGN 0x0002L
+#define SBS_LEFTALIGN 0x0002L
+#define SBS_BOTTOMALIGN 0x0004L
+#define SBS_RIGHTALIGN 0x0004L
+#define SBS_SIZEBOXTOPLEFTALIGN 0x0002L
+#define SBS_SIZEBOXBOTTOMRIGHTALIGN 0x0004L
+#define SBS_SIZEBOX 0x0008L
+#define SBS_SIZEGRIP 0x0010L
+#endif
+
+#ifndef NOWINMESSAGES
+#define SBM_SETPOS 0x00E0
+#define SBM_GETPOS 0x00E1
+#define SBM_SETRANGE 0x00E2
+#define SBM_SETRANGEREDRAW 0x00E6
+#define SBM_GETRANGE 0x00E3
+#define SBM_ENABLE_ARROWS 0x00E4
+#define SBM_SETSCROLLINFO 0x00E9
+#define SBM_GETSCROLLINFO 0x00EA
+#define SBM_GETSCROLLBARINFO 0x00EB
+
+#define SIF_RANGE 0x0001
+#define SIF_PAGE 0x0002
+#define SIF_POS 0x0004
+#define SIF_DISABLENOSCROLL 0x0008
+#define SIF_TRACKPOS 0x0010
+#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
+
+ typedef struct tagSCROLLINFO {
+ UINT cbSize;
+ UINT fMask;
+ int nMin;
+ int nMax;
+ UINT nPage;
+ int nPos;
+ int nTrackPos;
+ } SCROLLINFO,*LPSCROLLINFO;
+ typedef SCROLLINFO CONST *LPCSCROLLINFO;
+
+ WINUSERAPI int WINAPI SetScrollInfo(HWND hwnd,int nBar,LPCSCROLLINFO lpsi,WINBOOL redraw);
+ WINUSERAPI WINBOOL WINAPI GetScrollInfo(HWND hwnd,int nBar,LPSCROLLINFO lpsi);
+#endif
+#endif
+
+#ifndef NOMDI
+
+#define MDIS_ALLCHILDSTYLES 0x0001
+
+#define MDITILE_VERTICAL 0x0000
+#define MDITILE_HORIZONTAL 0x0001
+#define MDITILE_SKIPDISABLED 0x0002
+#define MDITILE_ZORDER 0x0004
+
+ typedef struct tagMDICREATESTRUCTA {
+ LPCSTR szClass;
+ LPCSTR szTitle;
+ HANDLE hOwner;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ DWORD style;
+ LPARAM lParam;
+ } MDICREATESTRUCTA,*LPMDICREATESTRUCTA;
+
+ typedef struct tagMDICREATESTRUCTW {
+ LPCWSTR szClass;
+ LPCWSTR szTitle;
+ HANDLE hOwner;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ DWORD style;
+ LPARAM lParam;
+ } MDICREATESTRUCTW,*LPMDICREATESTRUCTW;
+
+#ifdef UNICODE
+ typedef MDICREATESTRUCTW MDICREATESTRUCT;
+ typedef LPMDICREATESTRUCTW LPMDICREATESTRUCT;
+#else
+ typedef MDICREATESTRUCTA MDICREATESTRUCT;
+ typedef LPMDICREATESTRUCTA LPMDICREATESTRUCT;
+#endif
+
+ typedef struct tagCLIENTCREATESTRUCT {
+ HANDLE hWindowMenu;
+ UINT idFirstChild;
+ } CLIENTCREATESTRUCT,*LPCLIENTCREATESTRUCT;
+
+#ifdef UNICODE
+#define DefFrameProc DefFrameProcW
+#define DefMDIChildProc DefMDIChildProcW
+#define CreateMDIWindow CreateMDIWindowW
+#else
+#define DefFrameProc DefFrameProcA
+#define DefMDIChildProc DefMDIChildProcA
+#define CreateMDIWindow CreateMDIWindowA
+#endif
+
+ WINUSERAPI LRESULT WINAPI DefFrameProcA(HWND hWnd,HWND hWndMDIClient,UINT uMsg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI LRESULT WINAPI DefFrameProcW(HWND hWnd,HWND hWndMDIClient,UINT uMsg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI LRESULT WINAPI DefMDIChildProcA(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
+ WINUSERAPI LRESULT WINAPI DefMDIChildProcW(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
+
+#ifndef NOMSG
+ WINUSERAPI WINBOOL WINAPI TranslateMDISysAccel(HWND hWndClient,LPMSG lpMsg);
+#endif
+
+ WINUSERAPI UINT WINAPI ArrangeIconicWindows(HWND hWnd);
+ WINUSERAPI HWND WINAPI CreateMDIWindowA(LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HINSTANCE hInstance,LPARAM lParam);
+ WINUSERAPI HWND WINAPI CreateMDIWindowW(LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HINSTANCE hInstance,LPARAM lParam);
+ WINUSERAPI WORD WINAPI TileWindows(HWND hwndParent,UINT wHow,CONST RECT *lpRect,UINT cKids,const HWND *lpKids);
+ WINUSERAPI WORD WINAPI CascadeWindows(HWND hwndParent,UINT wHow,CONST RECT *lpRect,UINT cKids,const HWND *lpKids);
+#endif
+#endif
+
+#ifndef NOHELP
+
+ typedef DWORD HELPPOLY;
+ typedef struct tagMULTIKEYHELPA {
+ DWORD mkSize;
+ CHAR mkKeylist;
+ CHAR szKeyphrase[1];
+ } MULTIKEYHELPA,*PMULTIKEYHELPA,*LPMULTIKEYHELPA;
+
+ typedef struct tagMULTIKEYHELPW {
+ DWORD mkSize;
+ WCHAR mkKeylist;
+ WCHAR szKeyphrase[1];
+ } MULTIKEYHELPW,*PMULTIKEYHELPW,*LPMULTIKEYHELPW;
+
+#ifdef UNICODE
+ typedef MULTIKEYHELPW MULTIKEYHELP;
+ typedef PMULTIKEYHELPW PMULTIKEYHELP;
+ typedef LPMULTIKEYHELPW LPMULTIKEYHELP;
+#else
+ typedef MULTIKEYHELPA MULTIKEYHELP;
+ typedef PMULTIKEYHELPA PMULTIKEYHELP;
+ typedef LPMULTIKEYHELPA LPMULTIKEYHELP;
+#endif
+
+ typedef struct tagHELPWININFOA {
+ int wStructSize;
+ int x;
+ int y;
+ int dx;
+ int dy;
+ int wMax;
+ CHAR rgchMember[2];
+ } HELPWININFOA,*PHELPWININFOA,*LPHELPWININFOA;
+
+ typedef struct tagHELPWININFOW {
+ int wStructSize;
+ int x;
+ int y;
+ int dx;
+ int dy;
+ int wMax;
+ WCHAR rgchMember[2];
+ } HELPWININFOW,*PHELPWININFOW,*LPHELPWININFOW;
+
+#ifdef UNICODE
+ typedef HELPWININFOW HELPWININFO;
+ typedef PHELPWININFOW PHELPWININFO;
+ typedef LPHELPWININFOW LPHELPWININFO;
+#else
+ typedef HELPWININFOA HELPWININFO;
+ typedef PHELPWININFOA PHELPWININFO;
+ typedef LPHELPWININFOA LPHELPWININFO;
+#endif
+
+#define HELP_CONTEXT 0x0001L
+#define HELP_QUIT 0x0002L
+#define HELP_INDEX 0x0003L
+#define HELP_CONTENTS 0x0003L
+#define HELP_HELPONHELP 0x0004L
+#define HELP_SETINDEX 0x0005L
+#define HELP_SETCONTENTS 0x0005L
+#define HELP_CONTEXTPOPUP 0x0008L
+#define HELP_FORCEFILE 0x0009L
+#define HELP_KEY 0x0101L
+#define HELP_COMMAND 0x0102L
+#define HELP_PARTIALKEY 0x0105L
+#define HELP_MULTIKEY 0x0201L
+#define HELP_SETWINPOS 0x0203L
+#define HELP_CONTEXTMENU 0x000a
+#define HELP_FINDER 0x000b
+#define HELP_WM_HELP 0x000c
+#define HELP_SETPOPUP_POS 0x000d
+
+#define HELP_TCARD 0x8000
+#define HELP_TCARD_DATA 0x0010
+#define HELP_TCARD_OTHER_CALLER 0x0011
+
+#define IDH_NO_HELP 28440
+#define IDH_MISSING_CONTEXT 28441
+#define IDH_GENERIC_HELP_BUTTON 28442
+#define IDH_OK 28443
+#define IDH_CANCEL 28444
+#define IDH_HELP 28445
+
+#ifdef UNICODE
+#define WinHelp WinHelpW
+#else
+#define WinHelp WinHelpA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI WinHelpA(HWND hWndMain,LPCSTR lpszHelp,UINT uCommand,ULONG_PTR dwData);
+ WINUSERAPI WINBOOL WINAPI WinHelpW(HWND hWndMain,LPCWSTR lpszHelp,UINT uCommand,ULONG_PTR dwData);
+#endif
+
+#define GR_GDIOBJECTS 0
+#define GR_USEROBJECTS 1
+
+ WINUSERAPI DWORD WINAPI GetGuiResources(HANDLE hProcess,DWORD uiFlags);
+
+#ifndef NOSYSPARAMSINFO
+
+#define SPI_GETBEEP 0x0001
+#define SPI_SETBEEP 0x0002
+#define SPI_GETMOUSE 0x0003
+#define SPI_SETMOUSE 0x0004
+#define SPI_GETBORDER 0x0005
+#define SPI_SETBORDER 0x0006
+#define SPI_GETKEYBOARDSPEED 0x000A
+#define SPI_SETKEYBOARDSPEED 0x000B
+#define SPI_LANGDRIVER 0x000C
+#define SPI_ICONHORIZONTALSPACING 0x000D
+#define SPI_GETSCREENSAVETIMEOUT 0x000E
+#define SPI_SETSCREENSAVETIMEOUT 0x000F
+#define SPI_GETSCREENSAVEACTIVE 0x0010
+#define SPI_SETSCREENSAVEACTIVE 0x0011
+#define SPI_GETGRIDGRANULARITY 0x0012
+#define SPI_SETGRIDGRANULARITY 0x0013
+#define SPI_SETDESKWALLPAPER 0x0014
+#define SPI_SETDESKPATTERN 0x0015
+#define SPI_GETKEYBOARDDELAY 0x0016
+#define SPI_SETKEYBOARDDELAY 0x0017
+#define SPI_ICONVERTICALSPACING 0x0018
+#define SPI_GETICONTITLEWRAP 0x0019
+#define SPI_SETICONTITLEWRAP 0x001A
+#define SPI_GETMENUDROPALIGNMENT 0x001B
+#define SPI_SETMENUDROPALIGNMENT 0x001C
+#define SPI_SETDOUBLECLKWIDTH 0x001D
+#define SPI_SETDOUBLECLKHEIGHT 0x001E
+#define SPI_GETICONTITLELOGFONT 0x001F
+#define SPI_SETDOUBLECLICKTIME 0x0020
+#define SPI_SETMOUSEBUTTONSWAP 0x0021
+#define SPI_SETICONTITLELOGFONT 0x0022
+#define SPI_GETFASTTASKSWITCH 0x0023
+#define SPI_SETFASTTASKSWITCH 0x0024
+#define SPI_SETDRAGFULLWINDOWS 0x0025
+#define SPI_GETDRAGFULLWINDOWS 0x0026
+#define SPI_GETNONCLIENTMETRICS 0x0029
+#define SPI_SETNONCLIENTMETRICS 0x002A
+#define SPI_GETMINIMIZEDMETRICS 0x002B
+#define SPI_SETMINIMIZEDMETRICS 0x002C
+#define SPI_GETICONMETRICS 0x002D
+#define SPI_SETICONMETRICS 0x002E
+#define SPI_SETWORKAREA 0x002F
+#define SPI_GETWORKAREA 0x0030
+#define SPI_SETPENWINDOWS 0x0031
+
+#define SPI_GETHIGHCONTRAST 0x0042
+#define SPI_SETHIGHCONTRAST 0x0043
+#define SPI_GETKEYBOARDPREF 0x0044
+#define SPI_SETKEYBOARDPREF 0x0045
+#define SPI_GETSCREENREADER 0x0046
+#define SPI_SETSCREENREADER 0x0047
+#define SPI_GETANIMATION 0x0048
+#define SPI_SETANIMATION 0x0049
+#define SPI_GETFONTSMOOTHING 0x004A
+#define SPI_SETFONTSMOOTHING 0x004B
+#define SPI_SETDRAGWIDTH 0x004C
+#define SPI_SETDRAGHEIGHT 0x004D
+#define SPI_SETHANDHELD 0x004E
+#define SPI_GETLOWPOWERTIMEOUT 0x004F
+#define SPI_GETPOWEROFFTIMEOUT 0x0050
+#define SPI_SETLOWPOWERTIMEOUT 0x0051
+#define SPI_SETPOWEROFFTIMEOUT 0x0052
+#define SPI_GETLOWPOWERACTIVE 0x0053
+#define SPI_GETPOWEROFFACTIVE 0x0054
+#define SPI_SETLOWPOWERACTIVE 0x0055
+#define SPI_SETPOWEROFFACTIVE 0x0056
+#define SPI_SETCURSORS 0x0057
+#define SPI_SETICONS 0x0058
+#define SPI_GETDEFAULTINPUTLANG 0x0059
+#define SPI_SETDEFAULTINPUTLANG 0x005A
+#define SPI_SETLANGTOGGLE 0x005B
+#define SPI_GETWINDOWSEXTENSION 0x005C
+#define SPI_SETMOUSETRAILS 0x005D
+#define SPI_GETMOUSETRAILS 0x005E
+#define SPI_SETSCREENSAVERRUNNING 0x0061
+#define SPI_SCREENSAVERRUNNING SPI_SETSCREENSAVERRUNNING
+#define SPI_GETFILTERKEYS 0x0032
+#define SPI_SETFILTERKEYS 0x0033
+#define SPI_GETTOGGLEKEYS 0x0034
+#define SPI_SETTOGGLEKEYS 0x0035
+#define SPI_GETMOUSEKEYS 0x0036
+#define SPI_SETMOUSEKEYS 0x0037
+#define SPI_GETSHOWSOUNDS 0x0038
+#define SPI_SETSHOWSOUNDS 0x0039
+#define SPI_GETSTICKYKEYS 0x003A
+#define SPI_SETSTICKYKEYS 0x003B
+#define SPI_GETACCESSTIMEOUT 0x003C
+#define SPI_SETACCESSTIMEOUT 0x003D
+#define SPI_GETSERIALKEYS 0x003E
+#define SPI_SETSERIALKEYS 0x003F
+#define SPI_GETSOUNDSENTRY 0x0040
+#define SPI_SETSOUNDSENTRY 0x0041
+#define SPI_GETSNAPTODEFBUTTON 0x005F
+#define SPI_SETSNAPTODEFBUTTON 0x0060
+#define SPI_GETMOUSEHOVERWIDTH 0x0062
+#define SPI_SETMOUSEHOVERWIDTH 0x0063
+#define SPI_GETMOUSEHOVERHEIGHT 0x0064
+#define SPI_SETMOUSEHOVERHEIGHT 0x0065
+#define SPI_GETMOUSEHOVERTIME 0x0066
+#define SPI_SETMOUSEHOVERTIME 0x0067
+#define SPI_GETWHEELSCROLLLINES 0x0068
+#define SPI_SETWHEELSCROLLLINES 0x0069
+#define SPI_GETMENUSHOWDELAY 0x006A
+#define SPI_SETMENUSHOWDELAY 0x006B
+#define SPI_GETSHOWIMEUI 0x006E
+#define SPI_SETSHOWIMEUI 0x006F
+#define SPI_GETMOUSESPEED 0x0070
+#define SPI_SETMOUSESPEED 0x0071
+#define SPI_GETSCREENSAVERRUNNING 0x0072
+#define SPI_GETDESKWALLPAPER 0x0073
+
+#define SPI_GETACTIVEWINDOWTRACKING 0x1000
+#define SPI_SETACTIVEWINDOWTRACKING 0x1001
+#define SPI_GETMENUANIMATION 0x1002
+#define SPI_SETMENUANIMATION 0x1003
+#define SPI_GETCOMBOBOXANIMATION 0x1004
+#define SPI_SETCOMBOBOXANIMATION 0x1005
+#define SPI_GETLISTBOXSMOOTHSCROLLING 0x1006
+#define SPI_SETLISTBOXSMOOTHSCROLLING 0x1007
+#define SPI_GETGRADIENTCAPTIONS 0x1008
+#define SPI_SETGRADIENTCAPTIONS 0x1009
+#define SPI_GETKEYBOARDCUES 0x100A
+#define SPI_SETKEYBOARDCUES 0x100B
+#define SPI_GETMENUUNDERLINES SPI_GETKEYBOARDCUES
+#define SPI_SETMENUUNDERLINES SPI_SETKEYBOARDCUES
+#define SPI_GETACTIVEWNDTRKZORDER 0x100C
+#define SPI_SETACTIVEWNDTRKZORDER 0x100D
+#define SPI_GETHOTTRACKING 0x100E
+#define SPI_SETHOTTRACKING 0x100F
+#define SPI_GETMENUFADE 0x1012
+#define SPI_SETMENUFADE 0x1013
+#define SPI_GETSELECTIONFADE 0x1014
+#define SPI_SETSELECTIONFADE 0x1015
+#define SPI_GETTOOLTIPANIMATION 0x1016
+#define SPI_SETTOOLTIPANIMATION 0x1017
+#define SPI_GETTOOLTIPFADE 0x1018
+#define SPI_SETTOOLTIPFADE 0x1019
+#define SPI_GETCURSORSHADOW 0x101A
+#define SPI_SETCURSORSHADOW 0x101B
+#define SPI_GETMOUSESONAR 0x101C
+#define SPI_SETMOUSESONAR 0x101D
+#define SPI_GETMOUSECLICKLOCK 0x101E
+#define SPI_SETMOUSECLICKLOCK 0x101F
+#define SPI_GETMOUSEVANISH 0x1020
+#define SPI_SETMOUSEVANISH 0x1021
+#define SPI_GETFLATMENU 0x1022
+#define SPI_SETFLATMENU 0x1023
+#define SPI_GETDROPSHADOW 0x1024
+#define SPI_SETDROPSHADOW 0x1025
+#define SPI_GETBLOCKSENDINPUTRESETS 0x1026
+#define SPI_SETBLOCKSENDINPUTRESETS 0x1027
+#define SPI_GETUIEFFECTS 0x103E
+#define SPI_SETUIEFFECTS 0x103F
+#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000
+#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001
+#define SPI_GETACTIVEWNDTRKTIMEOUT 0x2002
+#define SPI_SETACTIVEWNDTRKTIMEOUT 0x2003
+#define SPI_GETFOREGROUNDFLASHCOUNT 0x2004
+#define SPI_SETFOREGROUNDFLASHCOUNT 0x2005
+#define SPI_GETCARETWIDTH 0x2006
+#define SPI_SETCARETWIDTH 0x2007
+#define SPI_GETMOUSECLICKLOCKTIME 0x2008
+#define SPI_SETMOUSECLICKLOCKTIME 0x2009
+#define SPI_GETFONTSMOOTHINGTYPE 0x200A
+#define SPI_SETFONTSMOOTHINGTYPE 0x200B
+
+#define FE_FONTSMOOTHINGSTANDARD 0x0001
+#define FE_FONTSMOOTHINGCLEARTYPE 0x0002
+#define FE_FONTSMOOTHINGDOCKING 0x8000
+
+#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
+#define SPI_SETFONTSMOOTHINGCONTRAST 0x200D
+#define SPI_GETFOCUSBORDERWIDTH 0x200E
+#define SPI_SETFOCUSBORDERWIDTH 0x200F
+#define SPI_GETFOCUSBORDERHEIGHT 0x2010
+#define SPI_SETFOCUSBORDERHEIGHT 0x2011
+#define SPI_GETFONTSMOOTHINGORIENTATION 0x2012
+#define SPI_SETFONTSMOOTHINGORIENTATION 0x2013
+
+#define FE_FONTSMOOTHINGORIENTATIONBGR 0x0000
+#define FE_FONTSMOOTHINGORIENTATIONRGB 0x0001
+
+#define SPIF_UPDATEINIFILE 0x0001
+#define SPIF_SENDWININICHANGE 0x0002
+#define SPIF_SENDCHANGE SPIF_SENDWININICHANGE
+
+#define METRICS_USEDEFAULT -1
+#ifdef _WINGDI_
+#ifndef NOGDI
+ typedef struct tagNONCLIENTMETRICSA {
+ UINT cbSize;
+ int iBorderWidth;
+ int iScrollWidth;
+ int iScrollHeight;
+ int iCaptionWidth;
+ int iCaptionHeight;
+ LOGFONTA lfCaptionFont;
+ int iSmCaptionWidth;
+ int iSmCaptionHeight;
+ LOGFONTA lfSmCaptionFont;
+ int iMenuWidth;
+ int iMenuHeight;
+ LOGFONTA lfMenuFont;
+ LOGFONTA lfStatusFont;
+ LOGFONTA lfMessageFont;
+ } NONCLIENTMETRICSA,*PNONCLIENTMETRICSA,*LPNONCLIENTMETRICSA;
+
+ typedef struct tagNONCLIENTMETRICSW {
+ UINT cbSize;
+ int iBorderWidth;
+ int iScrollWidth;
+ int iScrollHeight;
+ int iCaptionWidth;
+ int iCaptionHeight;
+ LOGFONTW lfCaptionFont;
+ int iSmCaptionWidth;
+ int iSmCaptionHeight;
+ LOGFONTW lfSmCaptionFont;
+ int iMenuWidth;
+ int iMenuHeight;
+ LOGFONTW lfMenuFont;
+ LOGFONTW lfStatusFont;
+ LOGFONTW lfMessageFont;
+ } NONCLIENTMETRICSW,*PNONCLIENTMETRICSW,*LPNONCLIENTMETRICSW;
+
+#ifdef UNICODE
+ typedef NONCLIENTMETRICSW NONCLIENTMETRICS;
+ typedef PNONCLIENTMETRICSW PNONCLIENTMETRICS;
+ typedef LPNONCLIENTMETRICSW LPNONCLIENTMETRICS;
+#else
+ typedef NONCLIENTMETRICSA NONCLIENTMETRICS;
+ typedef PNONCLIENTMETRICSA PNONCLIENTMETRICS;
+ typedef LPNONCLIENTMETRICSA LPNONCLIENTMETRICS;
+#endif
+#endif
+#endif
+
+#define ARW_BOTTOMLEFT 0x0000L
+#define ARW_BOTTOMRIGHT 0x0001L
+#define ARW_TOPLEFT 0x0002L
+#define ARW_TOPRIGHT 0x0003L
+#define ARW_STARTMASK 0x0003L
+#define ARW_STARTRIGHT 0x0001L
+#define ARW_STARTTOP 0x0002L
+
+#define ARW_LEFT 0x0000L
+#define ARW_RIGHT 0x0000L
+#define ARW_UP 0x0004L
+#define ARW_DOWN 0x0004L
+#define ARW_HIDE 0x0008L
+
+ typedef struct tagMINIMIZEDMETRICS {
+ UINT cbSize;
+ int iWidth;
+ int iHorzGap;
+ int iVertGap;
+ int iArrange;
+ } MINIMIZEDMETRICS,*PMINIMIZEDMETRICS,*LPMINIMIZEDMETRICS;
+
+#ifdef _WINGDI_
+#ifndef NOGDI
+ typedef struct tagICONMETRICSA {
+ UINT cbSize;
+ int iHorzSpacing;
+ int iVertSpacing;
+ int iTitleWrap;
+ LOGFONTA lfFont;
+ } ICONMETRICSA,*PICONMETRICSA,*LPICONMETRICSA;
+
+ typedef struct tagICONMETRICSW {
+ UINT cbSize;
+ int iHorzSpacing;
+ int iVertSpacing;
+ int iTitleWrap;
+ LOGFONTW lfFont;
+ } ICONMETRICSW,*PICONMETRICSW,*LPICONMETRICSW;
+
+#ifdef UNICODE
+ typedef ICONMETRICSW ICONMETRICS;
+ typedef PICONMETRICSW PICONMETRICS;
+ typedef LPICONMETRICSW LPICONMETRICS;
+#else
+ typedef ICONMETRICSA ICONMETRICS;
+ typedef PICONMETRICSA PICONMETRICS;
+ typedef LPICONMETRICSA LPICONMETRICS;
+#endif
+#endif
+#endif
+
+ typedef struct tagANIMATIONINFO {
+ UINT cbSize;
+ int iMinAnimate;
+ } ANIMATIONINFO,*LPANIMATIONINFO;
+
+ typedef struct tagSERIALKEYSA {
+ UINT cbSize;
+ DWORD dwFlags;
+ LPSTR lpszActivePort;
+ LPSTR lpszPort;
+ UINT iBaudRate;
+ UINT iPortState;
+ UINT iActive;
+ } SERIALKEYSA,*LPSERIALKEYSA;
+
+ typedef struct tagSERIALKEYSW {
+ UINT cbSize;
+ DWORD dwFlags;
+ LPWSTR lpszActivePort;
+ LPWSTR lpszPort;
+ UINT iBaudRate;
+ UINT iPortState;
+ UINT iActive;
+ } SERIALKEYSW,*LPSERIALKEYSW;
+
+#ifdef UNICODE
+ typedef SERIALKEYSW SERIALKEYS;
+ typedef LPSERIALKEYSW LPSERIALKEYS;
+#else
+ typedef SERIALKEYSA SERIALKEYS;
+ typedef LPSERIALKEYSA LPSERIALKEYS;
+#endif
+
+#define SERKF_SERIALKEYSON 0x00000001
+#define SERKF_AVAILABLE 0x00000002
+#define SERKF_INDICATOR 0x00000004
+
+ typedef struct tagHIGHCONTRASTA {
+ UINT cbSize;
+ DWORD dwFlags;
+ LPSTR lpszDefaultScheme;
+ } HIGHCONTRASTA,*LPHIGHCONTRASTA;
+
+ typedef struct tagHIGHCONTRASTW {
+ UINT cbSize;
+ DWORD dwFlags;
+ LPWSTR lpszDefaultScheme;
+ } HIGHCONTRASTW,*LPHIGHCONTRASTW;
+
+#ifdef UNICODE
+ typedef HIGHCONTRASTW HIGHCONTRAST;
+ typedef LPHIGHCONTRASTW LPHIGHCONTRAST;
+#else
+ typedef HIGHCONTRASTA HIGHCONTRAST;
+ typedef LPHIGHCONTRASTA LPHIGHCONTRAST;
+#endif
+
+#define HCF_HIGHCONTRASTON 0x00000001
+#define HCF_AVAILABLE 0x00000002
+#define HCF_HOTKEYACTIVE 0x00000004
+#define HCF_CONFIRMHOTKEY 0x00000008
+#define HCF_HOTKEYSOUND 0x00000010
+#define HCF_INDICATOR 0x00000020
+#define HCF_HOTKEYAVAILABLE 0x00000040
+#define HCF_LOGONDESKTOP 0x00000100
+#define HCF_DEFAULTDESKTOP 0x00000200
+
+#define CDS_UPDATEREGISTRY 0x00000001
+#define CDS_TEST 0x00000002
+#define CDS_FULLSCREEN 0x00000004
+#define CDS_GLOBAL 0x00000008
+#define CDS_SET_PRIMARY 0x00000010
+#define CDS_VIDEOPARAMETERS 0x00000020
+#define CDS_RESET 0x40000000
+#define CDS_NORESET 0x10000000
+
+//gr #include <tvout.h>
+
+#define DISP_CHANGE_SUCCESSFUL 0
+#define DISP_CHANGE_RESTART 1
+#define DISP_CHANGE_FAILED -1
+#define DISP_CHANGE_BADMODE -2
+#define DISP_CHANGE_NOTUPDATED -3
+#define DISP_CHANGE_BADFLAGS -4
+#define DISP_CHANGE_BADPARAM -5
+#define DISP_CHANGE_BADDUALVIEW -6
+
+#ifdef _WINGDI_
+#ifndef NOGDI
+
+#ifdef UNICODE
+#define ChangeDisplaySettings ChangeDisplaySettingsW
+#define ChangeDisplaySettingsEx ChangeDisplaySettingsExW
+#define EnumDisplaySettings EnumDisplaySettingsW
+#define EnumDisplaySettingsEx EnumDisplaySettingsExW
+#define EnumDisplayDevices EnumDisplayDevicesW
+#else
+#define ChangeDisplaySettings ChangeDisplaySettingsA
+#define ChangeDisplaySettingsEx ChangeDisplaySettingsExA
+#define EnumDisplaySettings EnumDisplaySettingsA
+#define EnumDisplaySettingsEx EnumDisplaySettingsExA
+#define EnumDisplayDevices EnumDisplayDevicesA
+#endif
+
+ WINUSERAPI LONG WINAPI ChangeDisplaySettingsA(LPDEVMODEA lpDevMode,DWORD dwFlags);
+ WINUSERAPI LONG WINAPI ChangeDisplaySettingsW(LPDEVMODEW lpDevMode,DWORD dwFlags);
+ WINUSERAPI LONG WINAPI ChangeDisplaySettingsExA(LPCSTR lpszDeviceName,LPDEVMODEA lpDevMode,HWND hwnd,DWORD dwflags,LPVOID lParam);
+ WINUSERAPI LONG WINAPI ChangeDisplaySettingsExW(LPCWSTR lpszDeviceName,LPDEVMODEW lpDevMode,HWND hwnd,DWORD dwflags,LPVOID lParam);
+
+#define ENUM_CURRENT_SETTINGS ((DWORD)-1)
+#define ENUM_REGISTRY_SETTINGS ((DWORD)-2)
+
+ WINUSERAPI WINBOOL WINAPI EnumDisplaySettingsA(LPCSTR lpszDeviceName,DWORD iModeNum,LPDEVMODEA lpDevMode);
+ WINUSERAPI WINBOOL WINAPI EnumDisplaySettingsW(LPCWSTR lpszDeviceName,DWORD iModeNum,LPDEVMODEW lpDevMode);
+ WINUSERAPI WINBOOL WINAPI EnumDisplaySettingsExA(LPCSTR lpszDeviceName,DWORD iModeNum,LPDEVMODEA lpDevMode,DWORD dwFlags);
+ WINUSERAPI WINBOOL WINAPI EnumDisplaySettingsExW(LPCWSTR lpszDeviceName,DWORD iModeNum,LPDEVMODEW lpDevMode,DWORD dwFlags);
+
+#define EDS_RAWMODE 0x00000002
+
+ WINUSERAPI WINBOOL WINAPI EnumDisplayDevicesA(LPCSTR lpDevice,DWORD iDevNum,PDISPLAY_DEVICEA lpDisplayDevice,DWORD dwFlags);
+ WINUSERAPI WINBOOL WINAPI EnumDisplayDevicesW(LPCWSTR lpDevice,DWORD iDevNum,PDISPLAY_DEVICEW lpDisplayDevice,DWORD dwFlags);
+#endif
+#endif
+
+#ifdef UNICODE
+#define SystemParametersInfo SystemParametersInfoW
+#else
+#define SystemParametersInfo SystemParametersInfoA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI SystemParametersInfoA(UINT uiAction,UINT uiParam,PVOID pvParam,UINT fWinIni);
+ WINUSERAPI WINBOOL WINAPI SystemParametersInfoW(UINT uiAction,UINT uiParam,PVOID pvParam,UINT fWinIni);
+#endif
+
+ typedef struct tagFILTERKEYS {
+ UINT cbSize;
+ DWORD dwFlags;
+ DWORD iWaitMSec;
+ DWORD iDelayMSec;
+ DWORD iRepeatMSec;
+ DWORD iBounceMSec;
+ } FILTERKEYS,*LPFILTERKEYS;
+
+#define FKF_FILTERKEYSON 0x00000001
+#define FKF_AVAILABLE 0x00000002
+#define FKF_HOTKEYACTIVE 0x00000004
+#define FKF_CONFIRMHOTKEY 0x00000008
+#define FKF_HOTKEYSOUND 0x00000010
+#define FKF_INDICATOR 0x00000020
+#define FKF_CLICKON 0x00000040
+
+ typedef struct tagSTICKYKEYS {
+ UINT cbSize;
+ DWORD dwFlags;
+ } STICKYKEYS,*LPSTICKYKEYS;
+
+#define SKF_STICKYKEYSON 0x00000001
+#define SKF_AVAILABLE 0x00000002
+#define SKF_HOTKEYACTIVE 0x00000004
+#define SKF_CONFIRMHOTKEY 0x00000008
+#define SKF_HOTKEYSOUND 0x00000010
+#define SKF_INDICATOR 0x00000020
+#define SKF_AUDIBLEFEEDBACK 0x00000040
+#define SKF_TRISTATE 0x00000080
+#define SKF_TWOKEYSOFF 0x00000100
+#define SKF_LALTLATCHED 0x10000000
+#define SKF_LCTLLATCHED 0x04000000
+#define SKF_LSHIFTLATCHED 0x01000000
+#define SKF_RALTLATCHED 0x20000000
+#define SKF_RCTLLATCHED 0x08000000
+#define SKF_RSHIFTLATCHED 0x02000000
+#define SKF_LWINLATCHED 0x40000000
+#define SKF_RWINLATCHED 0x80000000
+#define SKF_LALTLOCKED 0x00100000
+#define SKF_LCTLLOCKED 0x00040000
+#define SKF_LSHIFTLOCKED 0x00010000
+#define SKF_RALTLOCKED 0x00200000
+#define SKF_RCTLLOCKED 0x00080000
+#define SKF_RSHIFTLOCKED 0x00020000
+#define SKF_LWINLOCKED 0x00400000
+#define SKF_RWINLOCKED 0x00800000
+
+ typedef struct tagMOUSEKEYS {
+ UINT cbSize;
+ DWORD dwFlags;
+ DWORD iMaxSpeed;
+ DWORD iTimeToMaxSpeed;
+ DWORD iCtrlSpeed;
+ DWORD dwReserved1;
+ DWORD dwReserved2;
+ } MOUSEKEYS,*LPMOUSEKEYS;
+
+#define MKF_MOUSEKEYSON 0x00000001
+#define MKF_AVAILABLE 0x00000002
+#define MKF_HOTKEYACTIVE 0x00000004
+#define MKF_CONFIRMHOTKEY 0x00000008
+#define MKF_HOTKEYSOUND 0x00000010
+#define MKF_INDICATOR 0x00000020
+#define MKF_MODIFIERS 0x00000040
+#define MKF_REPLACENUMBERS 0x00000080
+#define MKF_LEFTBUTTONSEL 0x10000000
+#define MKF_RIGHTBUTTONSEL 0x20000000
+#define MKF_LEFTBUTTONDOWN 0x01000000
+#define MKF_RIGHTBUTTONDOWN 0x02000000
+#define MKF_MOUSEMODE 0x80000000
+
+ typedef struct tagACCESSTIMEOUT {
+ UINT cbSize;
+ DWORD dwFlags;
+ DWORD iTimeOutMSec;
+ } ACCESSTIMEOUT,*LPACCESSTIMEOUT;
+
+#define ATF_TIMEOUTON 0x00000001
+#define ATF_ONOFFFEEDBACK 0x00000002
+
+#define SSGF_NONE 0
+#define SSGF_DISPLAY 3
+
+#define SSTF_NONE 0
+#define SSTF_CHARS 1
+#define SSTF_BORDER 2
+#define SSTF_DISPLAY 3
+
+#define SSWF_NONE 0
+#define SSWF_TITLE 1
+#define SSWF_WINDOW 2
+#define SSWF_DISPLAY 3
+#define SSWF_CUSTOM 4
+
+ typedef struct tagSOUNDSENTRYA {
+ UINT cbSize;
+ DWORD dwFlags;
+ DWORD iFSTextEffect;
+ DWORD iFSTextEffectMSec;
+ DWORD iFSTextEffectColorBits;
+ DWORD iFSGrafEffect;
+ DWORD iFSGrafEffectMSec;
+ DWORD iFSGrafEffectColor;
+ DWORD iWindowsEffect;
+ DWORD iWindowsEffectMSec;
+ LPSTR lpszWindowsEffectDLL;
+ DWORD iWindowsEffectOrdinal;
+ } SOUNDSENTRYA,*LPSOUNDSENTRYA;
+
+ typedef struct tagSOUNDSENTRYW {
+ UINT cbSize;
+ DWORD dwFlags;
+ DWORD iFSTextEffect;
+ DWORD iFSTextEffectMSec;
+ DWORD iFSTextEffectColorBits;
+ DWORD iFSGrafEffect;
+ DWORD iFSGrafEffectMSec;
+ DWORD iFSGrafEffectColor;
+ DWORD iWindowsEffect;
+ DWORD iWindowsEffectMSec;
+ LPWSTR lpszWindowsEffectDLL;
+ DWORD iWindowsEffectOrdinal;
+ } SOUNDSENTRYW,*LPSOUNDSENTRYW;
+
+#ifdef UNICODE
+ typedef SOUNDSENTRYW SOUNDSENTRY;
+ typedef LPSOUNDSENTRYW LPSOUNDSENTRY;
+#else
+ typedef SOUNDSENTRYA SOUNDSENTRY;
+ typedef LPSOUNDSENTRYA LPSOUNDSENTRY;
+#endif
+
+#define SSF_SOUNDSENTRYON 0x00000001
+#define SSF_AVAILABLE 0x00000002
+#define SSF_INDICATOR 0x00000004
+
+ typedef struct tagTOGGLEKEYS {
+ UINT cbSize;
+ DWORD dwFlags;
+ } TOGGLEKEYS,*LPTOGGLEKEYS;
+
+#define TKF_TOGGLEKEYSON 0x00000001
+#define TKF_AVAILABLE 0x00000002
+#define TKF_HOTKEYACTIVE 0x00000004
+#define TKF_CONFIRMHOTKEY 0x00000008
+#define TKF_HOTKEYSOUND 0x00000010
+#define TKF_INDICATOR 0x00000020
+
+ WINUSERAPI VOID WINAPI SetDebugErrorLevel(DWORD dwLevel);
+
+#define SLE_ERROR 0x00000001
+#define SLE_MINORERROR 0x00000002
+#define SLE_WARNING 0x00000003
+
+ WINUSERAPI VOID WINAPI SetLastErrorEx(DWORD dwErrCode,DWORD dwType);
+ WINUSERAPI int WINAPI InternalGetWindowText(HWND hWnd,LPWSTR pString,int cchMaxCount);
+
+#ifdef WINNT
+ WINUSERAPI WINBOOL WINAPI EndTask(HWND hWnd,WINBOOL fShutDown,WINBOOL fForce);
+#endif
+
+#define MONITOR_DEFAULTTONULL 0x00000000
+#define MONITOR_DEFAULTTOPRIMARY 0x00000001
+#define MONITOR_DEFAULTTONEAREST 0x00000002
+
+ WINUSERAPI HMONITOR WINAPI MonitorFromPoint(POINT pt,DWORD dwFlags);
+ WINUSERAPI HMONITOR WINAPI MonitorFromRect(LPCRECT lprc,DWORD dwFlags);
+ WINUSERAPI HMONITOR WINAPI MonitorFromWindow(HWND hwnd,DWORD dwFlags);
+
+#define MONITORINFOF_PRIMARY 0x00000001
+
+#ifndef CCHDEVICENAME
+#define CCHDEVICENAME 32
+#endif
+
+ typedef struct tagMONITORINFO {
+ DWORD cbSize;
+ RECT rcMonitor;
+ RECT rcWork;
+ DWORD dwFlags;
+ } MONITORINFO,*LPMONITORINFO;
+
+#ifdef __cplusplus
+ typedef struct tagMONITORINFOEXA : public tagMONITORINFO {
+ CHAR szDevice[CCHDEVICENAME];
+ } MONITORINFOEXA,*LPMONITORINFOEXA;
+
+ typedef struct tagMONITORINFOEXW : public tagMONITORINFO {
+ WCHAR szDevice[CCHDEVICENAME];
+ } MONITORINFOEXW,*LPMONITORINFOEXW;
+
+#ifdef UNICODE
+ typedef MONITORINFOEXW MONITORINFOEX;
+ typedef LPMONITORINFOEXW LPMONITORINFOEX;
+#else
+ typedef MONITORINFOEXA MONITORINFOEX;
+ typedef LPMONITORINFOEXA LPMONITORINFOEX;
+#endif
+#else
+ typedef struct tagMONITORINFOEXA {
+ MONITORINFO mi;
+ CHAR szDevice[CCHDEVICENAME];
+ } MONITORINFOEXA,*LPMONITORINFOEXA;
+
+ typedef struct tagMONITORINFOEXW {
+ MONITORINFO mi;
+ WCHAR szDevice[CCHDEVICENAME];
+ } MONITORINFOEXW,*LPMONITORINFOEXW;
+#ifdef UNICODE
+ typedef MONITORINFOEXW MONITORINFOEX;
+ typedef LPMONITORINFOEXW LPMONITORINFOEX;
+#else
+ typedef MONITORINFOEXA MONITORINFOEX;
+ typedef LPMONITORINFOEXA LPMONITORINFOEX;
+#endif
+#endif
+
+#ifdef UNICODE
+#define GetMonitorInfo GetMonitorInfoW
+#else
+#define GetMonitorInfo GetMonitorInfoA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor,LPMONITORINFO lpmi);
+ WINUSERAPI WINBOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor,LPMONITORINFO lpmi);
+
+ typedef WINBOOL (CALLBACK *MONITORENUMPROC)(HMONITOR,HDC,LPRECT,LPARAM);
+
+ WINUSERAPI WINBOOL WINAPI EnumDisplayMonitors(HDC hdc,LPCRECT lprcClip,MONITORENUMPROC lpfnEnum,LPARAM dwData);
+
+#ifndef NOWINABLE
+ WINUSERAPI VOID WINAPI NotifyWinEvent(DWORD event,HWND hwnd,LONG idObject,LONG idChild);
+
+ typedef VOID (CALLBACK *WINEVENTPROC)(HWINEVENTHOOK hWinEventHook,DWORD event,HWND hwnd,LONG idObject,LONG idChild,DWORD idEventThread,DWORD dwmsEventTime);
+
+ WINUSERAPI HWINEVENTHOOK WINAPI SetWinEventHook(DWORD eventMin,DWORD eventMax,HMODULE hmodWinEventProc,WINEVENTPROC pfnWinEventProc,DWORD idProcess,DWORD idThread,DWORD dwFlags);
+ WINUSERAPI WINBOOL WINAPI IsWinEventHookInstalled(DWORD event);
+
+#define WINEVENT_OUTOFCONTEXT 0x0000
+#define WINEVENT_SKIPOWNTHREAD 0x0001
+#define WINEVENT_SKIPOWNPROCESS 0x0002
+#define WINEVENT_INCONTEXT 0x0004
+
+ WINUSERAPI WINBOOL WINAPI UnhookWinEvent(HWINEVENTHOOK hWinEventHook);
+
+#define CHILDID_SELF 0
+#define INDEXID_OBJECT 0
+#define INDEXID_CONTAINER 0
+
+#define OBJID_WINDOW ((LONG)0x00000000)
+#define OBJID_SYSMENU ((LONG)0xFFFFFFFF)
+#define OBJID_TITLEBAR ((LONG)0xFFFFFFFE)
+#define OBJID_MENU ((LONG)0xFFFFFFFD)
+#define OBJID_CLIENT ((LONG)0xFFFFFFFC)
+#define OBJID_VSCROLL ((LONG)0xFFFFFFFB)
+#define OBJID_HSCROLL ((LONG)0xFFFFFFFA)
+#define OBJID_SIZEGRIP ((LONG)0xFFFFFFF9)
+#define OBJID_CARET ((LONG)0xFFFFFFF8)
+#define OBJID_CURSOR ((LONG)0xFFFFFFF7)
+#define OBJID_ALERT ((LONG)0xFFFFFFF6)
+#define OBJID_SOUND ((LONG)0xFFFFFFF5)
+#define OBJID_QUERYCLASSNAMEIDX ((LONG)0xFFFFFFF4)
+#define OBJID_NATIVEOM ((LONG)0xFFFFFFF0)
+
+#define EVENT_MIN 0x00000001
+#define EVENT_MAX 0x7FFFFFFF
+
+#define EVENT_SYSTEM_SOUND 0x0001
+#define EVENT_SYSTEM_ALERT 0x0002
+#define EVENT_SYSTEM_FOREGROUND 0x0003
+#define EVENT_SYSTEM_MENUSTART 0x0004
+#define EVENT_SYSTEM_MENUEND 0x0005
+#define EVENT_SYSTEM_MENUPOPUPSTART 0x0006
+#define EVENT_SYSTEM_MENUPOPUPEND 0x0007
+#define EVENT_SYSTEM_CAPTURESTART 0x0008
+#define EVENT_SYSTEM_CAPTUREEND 0x0009
+#define EVENT_SYSTEM_MOVESIZESTART 0x000A
+#define EVENT_SYSTEM_MOVESIZEEND 0x000B
+#define EVENT_SYSTEM_CONTEXTHELPSTART 0x000C
+#define EVENT_SYSTEM_CONTEXTHELPEND 0x000D
+#define EVENT_SYSTEM_DRAGDROPSTART 0x000E
+#define EVENT_SYSTEM_DRAGDROPEND 0x000F
+#define EVENT_SYSTEM_DIALOGSTART 0x0010
+#define EVENT_SYSTEM_DIALOGEND 0x0011
+#define EVENT_SYSTEM_SCROLLINGSTART 0x0012
+#define EVENT_SYSTEM_SCROLLINGEND 0x0013
+#define EVENT_SYSTEM_SWITCHSTART 0x0014
+#define EVENT_SYSTEM_SWITCHEND 0x0015
+#define EVENT_SYSTEM_MINIMIZESTART 0x0016
+#define EVENT_SYSTEM_MINIMIZEEND 0x0017
+
+#define EVENT_CONSOLE_CARET 0x4001
+#define EVENT_CONSOLE_UPDATE_REGION 0x4002
+#define EVENT_CONSOLE_UPDATE_SIMPLE 0x4003
+#define EVENT_CONSOLE_UPDATE_SCROLL 0x4004
+#define EVENT_CONSOLE_LAYOUT 0x4005
+#define EVENT_CONSOLE_START_APPLICATION 0x4006
+#define EVENT_CONSOLE_END_APPLICATION 0x4007
+
+#define CONSOLE_APPLICATION_16BIT 0x0001
+
+#define CONSOLE_CARET_SELECTION 0x0001
+#define CONSOLE_CARET_VISIBLE 0x0002
+
+#define EVENT_OBJECT_CREATE 0x8000
+#define EVENT_OBJECT_DESTROY 0x8001
+#define EVENT_OBJECT_SHOW 0x8002
+#define EVENT_OBJECT_HIDE 0x8003
+#define EVENT_OBJECT_REORDER 0x8004
+
+#define EVENT_OBJECT_FOCUS 0x8005
+#define EVENT_OBJECT_SELECTION 0x8006
+#define EVENT_OBJECT_SELECTIONADD 0x8007
+#define EVENT_OBJECT_SELECTIONREMOVE 0x8008
+#define EVENT_OBJECT_SELECTIONWITHIN 0x8009
+
+#define EVENT_OBJECT_STATECHANGE 0x800A
+
+#define EVENT_OBJECT_LOCATIONCHANGE 0x800B
+
+#define EVENT_OBJECT_NAMECHANGE 0x800C
+#define EVENT_OBJECT_DESCRIPTIONCHANGE 0x800D
+#define EVENT_OBJECT_VALUECHANGE 0x800E
+#define EVENT_OBJECT_PARENTCHANGE 0x800F
+#define EVENT_OBJECT_HELPCHANGE 0x8010
+#define EVENT_OBJECT_DEFACTIONCHANGE 0x8011
+#define EVENT_OBJECT_ACCELERATORCHANGE 0x8012
+
+#define SOUND_SYSTEM_STARTUP 1
+#define SOUND_SYSTEM_SHUTDOWN 2
+#define SOUND_SYSTEM_BEEP 3
+#define SOUND_SYSTEM_ERROR 4
+#define SOUND_SYSTEM_QUESTION 5
+#define SOUND_SYSTEM_WARNING 6
+#define SOUND_SYSTEM_INFORMATION 7
+#define SOUND_SYSTEM_MAXIMIZE 8
+#define SOUND_SYSTEM_MINIMIZE 9
+#define SOUND_SYSTEM_RESTOREUP 10
+#define SOUND_SYSTEM_RESTOREDOWN 11
+#define SOUND_SYSTEM_APPSTART 12
+#define SOUND_SYSTEM_FAULT 13
+#define SOUND_SYSTEM_APPEND 14
+#define SOUND_SYSTEM_MENUCOMMAND 15
+#define SOUND_SYSTEM_MENUPOPUP 16
+#define CSOUND_SYSTEM 16
+
+#define ALERT_SYSTEM_INFORMATIONAL 1
+#define ALERT_SYSTEM_WARNING 2
+#define ALERT_SYSTEM_ERROR 3
+#define ALERT_SYSTEM_QUERY 4
+#define ALERT_SYSTEM_CRITICAL 5
+#define CALERT_SYSTEM 6
+
+ typedef struct tagGUITHREADINFO {
+ DWORD cbSize;
+ DWORD flags;
+ HWND hwndActive;
+ HWND hwndFocus;
+ HWND hwndCapture;
+ HWND hwndMenuOwner;
+ HWND hwndMoveSize;
+ HWND hwndCaret;
+ RECT rcCaret;
+ } GUITHREADINFO,*PGUITHREADINFO,*LPGUITHREADINFO;
+
+#define GUI_CARETBLINKING 0x00000001
+#define GUI_INMOVESIZE 0x00000002
+#define GUI_INMENUMODE 0x00000004
+#define GUI_SYSTEMMENUMODE 0x00000008
+#define GUI_POPUPMENUMODE 0x00000010
+#define GUI_16BITTASK 0x00000020
+
+#ifdef UNICODE
+#define GetWindowModuleFileName GetWindowModuleFileNameW
+#else
+#define GetWindowModuleFileName GetWindowModuleFileNameA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI GetGUIThreadInfo(DWORD idThread,PGUITHREADINFO pgui);
+ WINUSERAPI UINT WINAPI GetWindowModuleFileNameA(HWND hwnd,LPSTR pszFileName,UINT cchFileNameMax);
+ WINUSERAPI UINT WINAPI GetWindowModuleFileNameW(HWND hwnd,LPWSTR pszFileName,UINT cchFileNameMax);
+
+#ifndef NO_STATE_FLAGS
+#define STATE_SYSTEM_UNAVAILABLE 0x00000001
+#define STATE_SYSTEM_SELECTED 0x00000002
+#define STATE_SYSTEM_FOCUSED 0x00000004
+#define STATE_SYSTEM_PRESSED 0x00000008
+#define STATE_SYSTEM_CHECKED 0x00000010
+#define STATE_SYSTEM_MIXED 0x00000020
+#define STATE_SYSTEM_INDETERMINATE STATE_SYSTEM_MIXED
+#define STATE_SYSTEM_READONLY 0x00000040
+#define STATE_SYSTEM_HOTTRACKED 0x00000080
+#define STATE_SYSTEM_DEFAULT 0x00000100
+#define STATE_SYSTEM_EXPANDED 0x00000200
+#define STATE_SYSTEM_COLLAPSED 0x00000400
+#define STATE_SYSTEM_BUSY 0x00000800
+#define STATE_SYSTEM_FLOATING 0x00001000
+#define STATE_SYSTEM_MARQUEED 0x00002000
+#define STATE_SYSTEM_ANIMATED 0x00004000
+#define STATE_SYSTEM_INVISIBLE 0x00008000
+#define STATE_SYSTEM_OFFSCREEN 0x00010000
+#define STATE_SYSTEM_SIZEABLE 0x00020000
+#define STATE_SYSTEM_MOVEABLE 0x00040000
+#define STATE_SYSTEM_SELFVOICING 0x00080000
+#define STATE_SYSTEM_FOCUSABLE 0x00100000
+#define STATE_SYSTEM_SELECTABLE 0x00200000
+#define STATE_SYSTEM_LINKED 0x00400000
+#define STATE_SYSTEM_TRAVERSED 0x00800000
+#define STATE_SYSTEM_MULTISELECTABLE 0x01000000
+#define STATE_SYSTEM_EXTSELECTABLE 0x02000000
+#define STATE_SYSTEM_ALERT_LOW 0x04000000
+#define STATE_SYSTEM_ALERT_MEDIUM 0x08000000
+#define STATE_SYSTEM_ALERT_HIGH 0x10000000
+#define STATE_SYSTEM_PROTECTED 0x20000000
+#define STATE_SYSTEM_VALID 0x3FFFFFFF
+#endif
+
+#define CCHILDREN_TITLEBAR 5
+#define CCHILDREN_SCROLLBAR 5
+
+ typedef struct tagCURSORINFO {
+ DWORD cbSize;
+ DWORD flags;
+ HCURSOR hCursor;
+ POINT ptScreenPos;
+ } CURSORINFO,*PCURSORINFO,*LPCURSORINFO;
+
+#define CURSOR_SHOWING 0x00000001
+
+ WINUSERAPI WINBOOL WINAPI GetCursorInfo(PCURSORINFO pci);
+
+ typedef struct tagWINDOWINFO {
+ DWORD cbSize;
+ RECT rcWindow;
+ RECT rcClient;
+ DWORD dwStyle;
+ DWORD dwExStyle;
+ DWORD dwWindowStatus;
+ UINT cxWindowBorders;
+ UINT cyWindowBorders;
+ ATOM atomWindowType;
+ WORD wCreatorVersion;
+ } WINDOWINFO,*PWINDOWINFO,*LPWINDOWINFO;
+
+#define WS_ACTIVECAPTION 0x0001
+
+ WINUSERAPI WINBOOL WINAPI GetWindowInfo(HWND hwnd,PWINDOWINFO pwi);
+
+ typedef struct tagTITLEBARINFO {
+ DWORD cbSize;
+ RECT rcTitleBar;
+ DWORD rgstate[CCHILDREN_TITLEBAR + 1];
+ } TITLEBARINFO,*PTITLEBARINFO,*LPTITLEBARINFO;
+
+ WINUSERAPI WINBOOL WINAPI GetTitleBarInfo(HWND hwnd,PTITLEBARINFO pti);
+
+ typedef struct tagMENUBARINFO {
+ DWORD cbSize;
+ RECT rcBar;
+ HMENU hMenu;
+ HWND hwndMenu;
+ WINBOOL fBarFocused:1;
+ WINBOOL fFocused:1;
+ } MENUBARINFO,*PMENUBARINFO,*LPMENUBARINFO;
+
+ WINUSERAPI WINBOOL WINAPI GetMenuBarInfo(HWND hwnd,LONG idObject,LONG idItem,PMENUBARINFO pmbi);
+
+ typedef struct tagSCROLLBARINFO {
+ DWORD cbSize;
+ RECT rcScrollBar;
+ int dxyLineButton;
+ int xyThumbTop;
+ int xyThumbBottom;
+ int reserved;
+ DWORD rgstate[CCHILDREN_SCROLLBAR + 1];
+ } SCROLLBARINFO,*PSCROLLBARINFO,*LPSCROLLBARINFO;
+
+ WINUSERAPI WINBOOL WINAPI GetScrollBarInfo(HWND hwnd,LONG idObject,PSCROLLBARINFO psbi);
+
+ typedef struct tagCOMBOBOXINFO {
+ DWORD cbSize;
+ RECT rcItem;
+ RECT rcButton;
+ DWORD stateButton;
+ HWND hwndCombo;
+ HWND hwndItem;
+ HWND hwndList;
+ } COMBOBOXINFO,*PCOMBOBOXINFO,*LPCOMBOBOXINFO;
+
+ WINUSERAPI WINBOOL WINAPI GetComboBoxInfo(HWND hwndCombo,PCOMBOBOXINFO pcbi);
+
+#define GA_PARENT 1
+#define GA_ROOT 2
+#define GA_ROOTOWNER 3
+
+ WINUSERAPI HWND WINAPI GetAncestor(HWND hwnd,UINT gaFlags);
+ WINUSERAPI HWND WINAPI RealChildWindowFromPoint(HWND hwndParent,POINT ptParentClientCoords);
+ WINUSERAPI UINT WINAPI RealGetWindowClassA(HWND hwnd,LPSTR ptszClassName,UINT cchClassNameMax);
+ WINUSERAPI UINT WINAPI RealGetWindowClassW(HWND hwnd,LPWSTR ptszClassName,UINT cchClassNameMax);
+#ifdef UNICODE
+#define RealGetWindowClass RealGetWindowClassW
+#else
+#define RealGetWindowClass RealGetWindowClassA
+#endif
+
+ typedef struct tagALTTABINFO {
+ DWORD cbSize;
+ int cItems;
+ int cColumns;
+ int cRows;
+ int iColFocus;
+ int iRowFocus;
+ int cxItem;
+ int cyItem;
+ POINT ptStart;
+ } ALTTABINFO,*PALTTABINFO,*LPALTTABINFO;
+
+#ifdef UNICODE
+#define GetAltTabInfo GetAltTabInfoW
+#else
+#define GetAltTabInfo GetAltTabInfoA
+#endif
+
+ WINUSERAPI WINBOOL WINAPI GetAltTabInfoA(HWND hwnd,int iItem,PALTTABINFO pati,LPSTR pszItemText,UINT cchItemText);
+ WINUSERAPI WINBOOL WINAPI GetAltTabInfoW(HWND hwnd,int iItem,PALTTABINFO pati,LPWSTR pszItemText,UINT cchItemText);
+ WINUSERAPI DWORD WINAPI GetListBoxInfo(HWND hwnd);
+#endif
+
+ WINUSERAPI WINBOOL WINAPI LockWorkStation(VOID);
+ WINUSERAPI WINBOOL WINAPI UserHandleGrantAccess(HANDLE hUserHandle,HANDLE hJob,WINBOOL bGrant);
+
+ DECLARE_HANDLE(HRAWINPUT);
+
+#define GET_RAWINPUT_CODE_WPARAM(wParam) ((wParam) & 0xff)
+
+#define RIM_INPUT 0
+#define RIM_INPUTSINK 1
+
+ typedef struct tagRAWINPUTHEADER {
+ DWORD dwType;
+ DWORD dwSize;
+ HANDLE hDevice;
+ WPARAM wParam;
+ } RAWINPUTHEADER,*PRAWINPUTHEADER,*LPRAWINPUTHEADER;
+
+#define RIM_TYPEMOUSE 0
+#define RIM_TYPEKEYBOARD 1
+#define RIM_TYPEHID 2
+
+ typedef struct tagRAWMOUSE {
+ USHORT usFlags;
+ union {
+ ULONG ulButtons;
+ struct {
+ USHORT usButtonFlags;
+ USHORT usButtonData;
+ };
+ };
+ ULONG ulRawButtons;
+ LONG lLastX;
+ LONG lLastY;
+ ULONG ulExtraInformation;
+ } RAWMOUSE,*PRAWMOUSE,*LPRAWMOUSE;
+
+#define RI_MOUSE_LEFT_BUTTON_DOWN 0x0001
+#define RI_MOUSE_LEFT_BUTTON_UP 0x0002
+#define RI_MOUSE_RIGHT_BUTTON_DOWN 0x0004
+#define RI_MOUSE_RIGHT_BUTTON_UP 0x0008
+#define RI_MOUSE_MIDDLE_BUTTON_DOWN 0x0010
+#define RI_MOUSE_MIDDLE_BUTTON_UP 0x0020
+
+#define RI_MOUSE_BUTTON_1_DOWN RI_MOUSE_LEFT_BUTTON_DOWN
+#define RI_MOUSE_BUTTON_1_UP RI_MOUSE_LEFT_BUTTON_UP
+#define RI_MOUSE_BUTTON_2_DOWN RI_MOUSE_RIGHT_BUTTON_DOWN
+#define RI_MOUSE_BUTTON_2_UP RI_MOUSE_RIGHT_BUTTON_UP
+#define RI_MOUSE_BUTTON_3_DOWN RI_MOUSE_MIDDLE_BUTTON_DOWN
+#define RI_MOUSE_BUTTON_3_UP RI_MOUSE_MIDDLE_BUTTON_UP
+
+#define RI_MOUSE_BUTTON_4_DOWN 0x0040
+#define RI_MOUSE_BUTTON_4_UP 0x0080
+#define RI_MOUSE_BUTTON_5_DOWN 0x0100
+#define RI_MOUSE_BUTTON_5_UP 0x0200
+
+#define RI_MOUSE_WHEEL 0x0400
+
+#define MOUSE_MOVE_RELATIVE 0
+#define MOUSE_MOVE_ABSOLUTE 1
+#define MOUSE_VIRTUAL_DESKTOP 0x02
+#define MOUSE_ATTRIBUTES_CHANGED 0x04
+
+ typedef struct tagRAWKEYBOARD {
+ USHORT MakeCode;
+ USHORT Flags;
+ USHORT Reserved;
+ USHORT VKey;
+ UINT Message;
+ ULONG ExtraInformation;
+ } RAWKEYBOARD,*PRAWKEYBOARD,*LPRAWKEYBOARD;
+
+#define KEYBOARD_OVERRUN_MAKE_CODE 0xFF
+
+#define RI_KEY_MAKE 0
+#define RI_KEY_BREAK 1
+#define RI_KEY_E0 2
+#define RI_KEY_E1 4
+#define RI_KEY_TERMSRV_SET_LED 8
+#define RI_KEY_TERMSRV_SHADOW 0x10
+
+ typedef struct tagRAWHID {
+ DWORD dwSizeHid;
+ DWORD dwCount;
+ BYTE bRawData[1];
+ } RAWHID,*PRAWHID,*LPRAWHID;
+
+ typedef struct tagRAWINPUT {
+ RAWINPUTHEADER header;
+ union {
+ RAWMOUSE mouse;
+ RAWKEYBOARD keyboard;
+ RAWHID hid;
+ } data;
+ } RAWINPUT,*PRAWINPUT,*LPRAWINPUT;
+
+#ifdef _WIN64
+#define RAWINPUT_ALIGN(x) (((x) + sizeof(QWORD) - 1) & ~(sizeof(QWORD) - 1))
+#else
+#define RAWINPUT_ALIGN(x) (((x) + sizeof(DWORD) - 1) & ~(sizeof(DWORD) - 1))
+#endif
+
+#define NEXTRAWINPUTBLOCK(ptr) ((PRAWINPUT)RAWINPUT_ALIGN((ULONG_PTR)((PBYTE)(ptr) + (ptr)->header.dwSize)))
+
+#define RID_INPUT 0x10000003
+#define RID_HEADER 0x10000005
+
+ WINUSERAPI UINT WINAPI GetRawInputData(HRAWINPUT hRawInput,UINT uiCommand,LPVOID pData,PUINT pcbSize,UINT cbSizeHeader);
+
+#define RIDI_PREPARSEDDATA 0x20000005
+#define RIDI_DEVICENAME 0x20000007
+#define RIDI_DEVICEINFO 0x2000000b
+
+ typedef struct tagRID_DEVICE_INFO_MOUSE {
+ DWORD dwId;
+ DWORD dwNumberOfButtons;
+ DWORD dwSampleRate;
+ } RID_DEVICE_INFO_MOUSE,*PRID_DEVICE_INFO_MOUSE;
+
+ typedef struct tagRID_DEVICE_INFO_KEYBOARD {
+ DWORD dwType;
+ DWORD dwSubType;
+ DWORD dwKeyboardMode;
+ DWORD dwNumberOfFunctionKeys;
+ DWORD dwNumberOfIndicators;
+ DWORD dwNumberOfKeysTotal;
+ } RID_DEVICE_INFO_KEYBOARD,*PRID_DEVICE_INFO_KEYBOARD;
+
+ typedef struct tagRID_DEVICE_INFO_HID {
+ DWORD dwVendorId;
+ DWORD dwProductId;
+ DWORD dwVersionNumber;
+ USHORT usUsagePage;
+ USHORT usUsage;
+ } RID_DEVICE_INFO_HID,*PRID_DEVICE_INFO_HID;
+
+ typedef struct tagRID_DEVICE_INFO {
+ DWORD cbSize;
+ DWORD dwType;
+ union {
+ RID_DEVICE_INFO_MOUSE mouse;
+ RID_DEVICE_INFO_KEYBOARD keyboard;
+ RID_DEVICE_INFO_HID hid;
+ };
+ } RID_DEVICE_INFO,*PRID_DEVICE_INFO,*LPRID_DEVICE_INFO;
+
+#ifdef UNICODE
+#define GetRawInputDeviceInfo GetRawInputDeviceInfoW
+#else
+#define GetRawInputDeviceInfo GetRawInputDeviceInfoA
+#endif
+
+ WINUSERAPI UINT WINAPI GetRawInputDeviceInfoA(HANDLE hDevice,UINT uiCommand,LPVOID pData,PUINT pcbSize);
+ WINUSERAPI UINT WINAPI GetRawInputDeviceInfoW(HANDLE hDevice,UINT uiCommand,LPVOID pData,PUINT pcbSize);
+ WINUSERAPI UINT WINAPI GetRawInputBuffer(PRAWINPUT pData,PUINT pcbSize,UINT cbSizeHeader);
+
+ typedef struct tagRAWINPUTDEVICE {
+ USHORT usUsagePage;
+ USHORT usUsage;
+ DWORD dwFlags;
+ HWND hwndTarget;
+ } RAWINPUTDEVICE,*PRAWINPUTDEVICE,*LPRAWINPUTDEVICE;
+
+ typedef CONST RAWINPUTDEVICE *PCRAWINPUTDEVICE;
+
+#define RIDEV_REMOVE 0x00000001
+#define RIDEV_EXCLUDE 0x00000010
+#define RIDEV_PAGEONLY 0x00000020
+#define RIDEV_NOLEGACY 0x00000030
+#define RIDEV_INPUTSINK 0x00000100
+#define RIDEV_CAPTUREMOUSE 0x00000200
+#define RIDEV_NOHOTKEYS 0x00000200
+#define RIDEV_APPKEYS 0x00000400
+#define RIDEV_EXMODEMASK 0x000000F0
+#define RIDEV_EXMODE(mode) ((mode) & RIDEV_EXMODEMASK)
+
+ WINUSERAPI WINBOOL WINAPI RegisterRawInputDevices(PCRAWINPUTDEVICE pRawInputDevices,UINT uiNumDevices,UINT cbSize);
+ WINUSERAPI UINT WINAPI GetRegisteredRawInputDevices(PRAWINPUTDEVICE pRawInputDevices,PUINT puiNumDevices,UINT cbSize);
+
+ typedef struct tagRAWINPUTDEVICELIST {
+ HANDLE hDevice;
+ DWORD dwType;
+ } RAWINPUTDEVICELIST,*PRAWINPUTDEVICELIST;
+
+ WINUSERAPI UINT WINAPI GetRawInputDeviceList(PRAWINPUTDEVICELIST pRawInputDeviceList,PUINT puiNumDevices,UINT cbSize);
+ WINUSERAPI LRESULT WINAPI DefRawInputProc(PRAWINPUT *paRawInput,INT nInput,UINT cbSizeHeader);
+
+#endif /* NOUSER */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/include/winapi/winver.h b/win32/include/winapi/winver.h
new file mode 100644
index 0000000..5c0f036
--- /dev/null
+++ b/win32/include/winapi/winver.h
@@ -0,0 +1,160 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef VER_H
+#define VER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define VS_FILE_INFO RT_VERSION
+#define VS_VERSION_INFO 1
+#define VS_USER_DEFINED 100
+
+#define VS_FFI_SIGNATURE 0xFEEF04BDL
+#define VS_FFI_STRUCVERSION 0x00010000L
+#define VS_FFI_FILEFLAGSMASK 0x0000003FL
+
+#define VS_FF_DEBUG 0x00000001L
+#define VS_FF_PRERELEASE 0x00000002L
+#define VS_FF_PATCHED 0x00000004L
+#define VS_FF_PRIVATEBUILD 0x00000008L
+#define VS_FF_INFOINFERRED 0x00000010L
+#define VS_FF_SPECIALBUILD 0x00000020L
+
+#define VOS_UNKNOWN 0x00000000L
+#define VOS_DOS 0x00010000L
+#define VOS_OS216 0x00020000L
+#define VOS_OS232 0x00030000L
+#define VOS_NT 0x00040000L
+#define VOS_WINCE 0x00050000L
+
+#define VOS__BASE 0x00000000L
+#define VOS__WINDOWS16 0x00000001L
+#define VOS__PM16 0x00000002L
+#define VOS__PM32 0x00000003L
+#define VOS__WINDOWS32 0x00000004L
+
+#define VOS_DOS_WINDOWS16 0x00010001L
+#define VOS_DOS_WINDOWS32 0x00010004L
+#define VOS_OS216_PM16 0x00020002L
+#define VOS_OS232_PM32 0x00030003L
+#define VOS_NT_WINDOWS32 0x00040004L
+
+#define VFT_UNKNOWN 0x00000000L
+#define VFT_APP 0x00000001L
+#define VFT_DLL 0x00000002L
+#define VFT_DRV 0x00000003L
+#define VFT_FONT 0x00000004L
+#define VFT_VXD 0x00000005L
+#define VFT_STATIC_LIB 0x00000007L
+
+#define VFT2_UNKNOWN 0x00000000L
+#define VFT2_DRV_PRINTER 0x00000001L
+#define VFT2_DRV_KEYBOARD 0x00000002L
+#define VFT2_DRV_LANGUAGE 0x00000003L
+#define VFT2_DRV_DISPLAY 0x00000004L
+#define VFT2_DRV_MOUSE 0x00000005L
+#define VFT2_DRV_NETWORK 0x00000006L
+#define VFT2_DRV_SYSTEM 0x00000007L
+#define VFT2_DRV_INSTALLABLE 0x00000008L
+#define VFT2_DRV_SOUND 0x00000009L
+#define VFT2_DRV_COMM 0x0000000AL
+#define VFT2_DRV_INPUTMETHOD 0x0000000BL
+#define VFT2_DRV_VERSIONED_PRINTER 0x0000000CL
+
+#define VFT2_FONT_RASTER 0x00000001L
+#define VFT2_FONT_VECTOR 0x00000002L
+#define VFT2_FONT_TRUETYPE 0x00000003L
+
+#define VFFF_ISSHAREDFILE 0x0001
+
+#define VFF_CURNEDEST 0x0001
+#define VFF_FILEINUSE 0x0002
+#define VFF_BUFFTOOSMALL 0x0004
+
+#define VIFF_FORCEINSTALL 0x0001
+#define VIFF_DONTDELETEOLD 0x0002
+
+#define VIF_TEMPFILE 0x00000001L
+#define VIF_MISMATCH 0x00000002L
+#define VIF_SRCOLD 0x00000004L
+
+#define VIF_DIFFLANG 0x00000008L
+#define VIF_DIFFCODEPG 0x00000010L
+#define VIF_DIFFTYPE 0x00000020L
+
+#define VIF_WRITEPROT 0x00000040L
+#define VIF_FILEINUSE 0x00000080L
+#define VIF_OUTOFSPACE 0x00000100L
+#define VIF_ACCESSVIOLATION 0x00000200L
+#define VIF_SHARINGVIOLATION 0x00000400L
+#define VIF_CANNOTCREATE 0x00000800L
+#define VIF_CANNOTDELETE 0x00001000L
+#define VIF_CANNOTRENAME 0x00002000L
+#define VIF_CANNOTDELETECUR 0x00004000L
+#define VIF_OUTOFMEMORY 0x00008000L
+
+#define VIF_CANNOTREADSRC 0x00010000L
+#define VIF_CANNOTREADDST 0x00020000L
+
+#define VIF_BUFFTOOSMALL 0x00040000L
+#define VIF_CANNOTLOADLZ32 0x00080000L
+#define VIF_CANNOTLOADCABINET 0x00100000L
+
+#ifndef RC_INVOKED
+
+ typedef struct tagVS_FIXEDFILEINFO
+ {
+ DWORD dwSignature;
+ DWORD dwStrucVersion;
+ DWORD dwFileVersionMS;
+ DWORD dwFileVersionLS;
+ DWORD dwProductVersionMS;
+ DWORD dwProductVersionLS;
+ DWORD dwFileFlagsMask;
+ DWORD dwFileFlags;
+ DWORD dwFileOS;
+ DWORD dwFileType;
+ DWORD dwFileSubtype;
+ DWORD dwFileDateMS;
+ DWORD dwFileDateLS;
+ } VS_FIXEDFILEINFO;
+
+#ifdef UNICODE
+#define VerFindFile VerFindFileW
+#define VerInstallFile VerInstallFileW
+#define GetFileVersionInfoSize GetFileVersionInfoSizeW
+#define GetFileVersionInfo GetFileVersionInfoW
+#define VerLanguageName VerLanguageNameW
+#define VerQueryValue VerQueryValueW
+#else
+#define VerFindFile VerFindFileA
+#define VerInstallFile VerInstallFileA
+#define GetFileVersionInfoSize GetFileVersionInfoSizeA
+#define GetFileVersionInfo GetFileVersionInfoA
+#define VerLanguageName VerLanguageNameA
+#define VerQueryValue VerQueryValueA
+#endif
+
+ DWORD WINAPI VerFindFileA(DWORD uFlags,LPSTR szFileName,LPSTR szWinDir,LPSTR szAppDir,LPSTR szCurDir,PUINT lpuCurDirLen,LPSTR szDestDir,PUINT lpuDestDirLen);
+ DWORD WINAPI VerFindFileW(DWORD uFlags,LPWSTR szFileName,LPWSTR szWinDir,LPWSTR szAppDir,LPWSTR szCurDir,PUINT lpuCurDirLen,LPWSTR szDestDir,PUINT lpuDestDirLen);
+ DWORD WINAPI VerInstallFileA(DWORD uFlags,LPSTR szSrcFileName,LPSTR szDestFileName,LPSTR szSrcDir,LPSTR szDestDir,LPSTR szCurDir,LPSTR szTmpFile,PUINT lpuTmpFileLen);
+ DWORD WINAPI VerInstallFileW(DWORD uFlags,LPWSTR szSrcFileName,LPWSTR szDestFileName,LPWSTR szSrcDir,LPWSTR szDestDir,LPWSTR szCurDir,LPWSTR szTmpFile,PUINT lpuTmpFileLen);
+ DWORD WINAPI GetFileVersionInfoSizeA(LPCSTR lptstrFilename,LPDWORD lpdwHandle);
+ DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR lptstrFilename,LPDWORD lpdwHandle);
+ WINBOOL WINAPI GetFileVersionInfoA(LPCSTR lptstrFilename,DWORD dwHandle,DWORD dwLen,LPVOID lpData);
+ WINBOOL WINAPI GetFileVersionInfoW(LPCWSTR lptstrFilename,DWORD dwHandle,DWORD dwLen,LPVOID lpData);
+ DWORD WINAPI VerLanguageNameA(DWORD wLang,LPSTR szLang,DWORD nSize);
+ DWORD WINAPI VerLanguageNameW(DWORD wLang,LPWSTR szLang,DWORD nSize);
+ WINBOOL WINAPI VerQueryValueA(const LPVOID pBlock,LPSTR lpSubBlock,LPVOID *lplpBuffer,PUINT puLen);
+ WINBOOL WINAPI VerQueryValueW(const LPVOID pBlock,LPWSTR lpSubBlock,LPVOID *lplpBuffer,PUINT puLen);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/win32/lib/chkstk.S b/win32/lib/chkstk.S
new file mode 100644
index 0000000..ec5c07f
--- /dev/null
+++ b/win32/lib/chkstk.S
@@ -0,0 +1,191 @@
+/* ---------------------------------------------- */
+/* chkstk86.s */
+
+/* ---------------------------------------------- */
+#ifndef __x86_64__
+/* ---------------------------------------------- */
+
+.globl __chkstk
+
+__chkstk:
+ xchg (%esp),%ebp /* store ebp, get ret.addr */
+ push %ebp /* push ret.addr */
+ lea 4(%esp),%ebp /* setup frame ptr */
+ push %ecx /* save ecx */
+ mov %ebp,%ecx
+P0:
+ sub $4096,%ecx
+ test %eax,(%ecx)
+ sub $4096,%eax
+ cmp $4096,%eax
+ jge P0
+ sub %eax,%ecx
+ test %eax,(%ecx)
+
+ mov %esp,%eax
+ mov %ecx,%esp
+ mov (%eax),%ecx /* restore ecx */
+ jmp *4(%eax)
+
+/* ---------------------------------------------- */
+#else
+/* ---------------------------------------------- */
+
+.globl __chkstk
+
+__chkstk:
+ xchg (%rsp),%rbp /* store ebp, get ret.addr */
+ push %rbp /* push ret.addr */
+ lea 8(%rsp),%rbp /* setup frame ptr */
+ push %rcx /* save ecx */
+ mov %rbp,%rcx
+ movslq %eax,%rax
+P0:
+ sub $4096,%rcx
+ test %rax,(%rcx)
+ sub $4096,%rax
+ cmp $4096,%rax
+ jge P0
+ sub %rax,%rcx
+ test %rax,(%rcx)
+
+ mov %rsp,%rax
+ mov %rcx,%rsp
+ mov (%rax),%rcx /* restore ecx */
+ jmp *8(%rax)
+
+/* ---------------------------------------------- */
+/* setjmp/longjmp support */
+
+.globl tinyc_getbp
+tinyc_getbp:
+ mov %rbp,%rax
+ ret
+
+/* ---------------------------------------------- */
+#endif
+/* ---------------------------------------------- */
+
+
+/* ---------------------------------------------- */
+#ifndef __x86_64__
+/* ---------------------------------------------- */
+
+/*
+ int _except_handler3(
+ PEXCEPTION_RECORD exception_record,
+ PEXCEPTION_REGISTRATION registration,
+ PCONTEXT context,
+ PEXCEPTION_REGISTRATION dispatcher
+ );
+
+ int __cdecl _XcptFilter(
+ unsigned long xcptnum,
+ PEXCEPTION_POINTERS pxcptinfoptrs
+ );
+
+ struct _sehrec {
+ void *esp; // 0
+ void *exception_pointers; // 1
+ void *prev; // 2
+ void *handler; // 3
+ void *scopetable; // 4
+ int trylevel; // 5
+ void *ebp // 6
+ };
+
+ // this is what the assembler code below means:
+ __try
+ {
+ // ...
+ }
+ __except (_XcptFilter(GetExceptionCode(), GetExceptionInformation()))
+ {
+ exit(GetExceptionCode());
+ }
+*/
+
+.globl _exception_info
+_exception_info:
+ mov 1*4-24(%ebp),%eax
+ ret
+
+.globl _exception_code
+_exception_code:
+ call _exception_info
+ mov (%eax),%eax
+ mov (%eax),%eax
+ ret
+
+seh_filter:
+ call _exception_info
+ push %eax
+ call _exception_code
+ push %eax
+ call _XcptFilter
+ add $ 8,%esp
+ ret
+
+seh_except:
+ mov 0*4-24(%ebp),%esp
+ call _exception_code
+ push %eax
+ call _exit
+
+// msvcrt wants scopetables aligned and in read-only segment (using .text)
+.align 4
+seh_scopetable:
+ .long -1
+ .long seh_filter
+ .long seh_except
+
+seh_handler:
+ jmp _except_handler3
+
+.globl ___try__
+___try__:
+.globl __try__
+__try__:
+ push %ebp
+ mov 8(%esp),%ebp
+
+// void *esp;
+ lea 12(%esp),%eax
+ mov %eax,0*4(%ebp)
+
+// void *exception_pointers;
+ xor %eax,%eax
+ mov %eax,1*4(%ebp)
+
+// void *prev;
+ mov %fs:0,%eax
+ mov %eax,2*4(%ebp)
+
+// void *handler;
+ mov $ seh_handler,%eax
+ mov %eax,3*4(%ebp)
+
+// void *scopetable;
+ mov $ seh_scopetable,%eax
+ mov %eax,4*4(%ebp)
+
+// int trylevel;
+ xor %eax,%eax
+ mov %eax,5*4(%ebp)
+
+// register new SEH
+ lea 2*4(%ebp),%eax
+ mov %eax,%fs:0
+
+ pop %ebp
+ ret
+
+/* ---------------------------------------------- */
+#else
+/* ---------------------------------------------- */
+
+/* SEH on x86-64 not implemented */
+
+/* ---------------------------------------------- */
+#endif
+/* ---------------------------------------------- */
diff --git a/win32/lib/crt1.c b/win32/lib/crt1.c
new file mode 100644
index 0000000..0e04fc0
--- /dev/null
+++ b/win32/lib/crt1.c
@@ -0,0 +1,79 @@
+// =============================================
+// crt1.c
+
+// _UNICODE for tchar.h, UNICODE for API
+#include <tchar.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define _UNKNOWN_APP 0
+#define _CONSOLE_APP 1
+#define _GUI_APP 2
+
+#define _MCW_PC 0x00030000 // Precision Control
+#define _PC_24 0x00020000 // 24 bits
+#define _PC_53 0x00010000 // 53 bits
+#define _PC_64 0x00000000 // 64 bits
+
+#ifdef _UNICODE
+#define __tgetmainargs __wgetmainargs
+#define _tstart _wstart
+#define _tmain wmain
+#define _runtmain _runwmain
+#else
+#define __tgetmainargs __getmainargs
+#define _tstart _start
+#define _tmain main
+#define _runtmain _runmain
+#endif
+
+typedef struct { int newmode; } _startupinfo;
+int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*);
+void __cdecl __set_app_type(int apptype);
+unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask);
+extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]);
+
+/* Allow command-line globbing with "int _dowildcard = 1;" in the user source */
+int _dowildcard;
+
+void _tstart(void)
+{
+ __TRY__
+ _startupinfo start_info = {0};
+
+ // Sets the current application type
+ __set_app_type(_CONSOLE_APP);
+
+ // Set default FP precision to 53 bits (8-byte double)
+ // _MCW_PC (Precision control) is not supported on ARM
+#if defined __i386__ || defined __x86_64__
+ _controlfp(_PC_53, _MCW_PC);
+#endif
+
+ __tgetmainargs( &__argc, &__targv, &_tenviron, _dowildcard, &start_info);
+ exit(_tmain(__argc, __targv, _tenviron));
+}
+
+int _runtmain(int argc, /* as tcc passed in */ char **argv)
+{
+#ifdef UNICODE
+ _startupinfo start_info = {0};
+
+ __tgetmainargs(&__argc, &__targv, &_tenviron, _dowildcard, &start_info);
+ /* may be wrong when tcc has received wildcards (*.c) */
+ if (argc < __argc) {
+ __targv += __argc - argc;
+ __argc = argc;
+ }
+#else
+ __argc = argc;
+ __targv = argv;
+#endif
+#if defined __i386__ || defined __x86_64__
+ _controlfp(_PC_53, _MCW_PC);
+#endif
+ return _tmain(__argc, __targv, _tenviron);
+}
+
+// =============================================
diff --git a/win32/lib/crt1w.c b/win32/lib/crt1w.c
new file mode 100644
index 0000000..2b8bbc8
--- /dev/null
+++ b/win32/lib/crt1w.c
@@ -0,0 +1,3 @@
+#define _UNICODE 1
+#define UNICODE 1
+#include "crt1.c"
diff --git a/win32/lib/dllcrt1.c b/win32/lib/dllcrt1.c
new file mode 100644
index 0000000..ba1dbd0
--- /dev/null
+++ b/win32/lib/dllcrt1.c
@@ -0,0 +1,13 @@
+//+---------------------------------------------------------------------------
+
+#include <windows.h>
+
+BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved);
+
+BOOL WINAPI _dllstart(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
+{
+ BOOL bRet;
+ bRet = DllMain (hDll, dwReason, lpReserved);
+ return bRet;
+}
+
diff --git a/win32/lib/dllmain.c b/win32/lib/dllmain.c
new file mode 100644
index 0000000..2c25b98
--- /dev/null
+++ b/win32/lib/dllmain.c
@@ -0,0 +1,9 @@
+//+---------------------------------------------------------------------------
+
+#include <windows.h>
+
+BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
+{
+ return TRUE;
+}
+
diff --git a/win32/lib/gdi32.def b/win32/lib/gdi32.def
new file mode 100644
index 0000000..02766da
--- /dev/null
+++ b/win32/lib/gdi32.def
@@ -0,0 +1,337 @@
+LIBRARY gdi32.dll
+
+EXPORTS
+AbortDoc
+AbortPath
+AddFontResourceA
+AddFontResourceW
+AngleArc
+AnimatePalette
+Arc
+ArcTo
+BeginPath
+BitBlt
+ByeByeGDI
+CancelDC
+CheckColorsInGamut
+ChoosePixelFormat
+Chord
+CloseEnhMetaFile
+CloseFigure
+CloseMetaFile
+ColorCorrectPalette
+ColorMatchToTarget
+CombineRgn
+CombineTransform
+CopyEnhMetaFileA
+CopyEnhMetaFileW
+CopyMetaFileA
+CopyMetaFileW
+CreateBitmap
+CreateBitmapIndirect
+CreateBrushIndirect
+CreateColorSpaceA
+CreateColorSpaceW
+CreateCompatibleBitmap
+CreateCompatibleDC
+CreateDCA
+CreateDCW
+CreateDIBPatternBrush
+CreateDIBPatternBrushPt
+CreateDIBSection
+CreateDIBitmap
+CreateDiscardableBitmap
+CreateEllipticRgn
+CreateEllipticRgnIndirect
+CreateEnhMetaFileA
+CreateEnhMetaFileW
+CreateFontA
+CreateFontIndirectA
+CreateFontIndirectW
+CreateFontW
+CreateHalftonePalette
+CreateHatchBrush
+CreateICA
+CreateICW
+CreateMetaFileA
+CreateMetaFileW
+CreatePalette
+CreatePatternBrush
+CreatePen
+CreatePenIndirect
+CreatePolyPolygonRgn
+CreatePolygonRgn
+CreateRectRgn
+CreateRectRgnIndirect
+CreateRoundRectRgn
+CreateScalableFontResourceA
+CreateScalableFontResourceW
+CreateSolidBrush
+DPtoLP
+DeleteColorSpace
+DeleteDC
+DeleteEnhMetaFile
+DeleteMetaFile
+DeleteObject
+DescribePixelFormat
+DeviceCapabilitiesEx
+DeviceCapabilitiesExA
+DeviceCapabilitiesExW
+DrawEscape
+Ellipse
+EnableEUDC
+EndDoc
+EndPage
+EndPath
+EnumEnhMetaFile
+EnumFontFamiliesA
+EnumFontFamiliesExA
+EnumFontFamiliesExW
+EnumFontFamiliesW
+EnumFontsA
+EnumFontsW
+EnumICMProfilesA
+EnumICMProfilesW
+EnumMetaFile
+EnumObjects
+EqualRgn
+Escape
+ExcludeClipRect
+ExtCreatePen
+ExtCreateRegion
+ExtEscape
+ExtFloodFill
+ExtSelectClipRgn
+ExtTextOutA
+ExtTextOutW
+FillPath
+FillRgn
+FixBrushOrgEx
+FlattenPath
+FloodFill
+FrameRgn
+GdiComment
+GdiFlush
+GdiGetBatchLimit
+GdiPlayDCScript
+GdiPlayJournal
+GdiPlayScript
+GdiSetBatchLimit
+GetArcDirection
+GetAspectRatioFilterEx
+GetBitmapBits
+GetBitmapDimensionEx
+GetBkColor
+GetBkMode
+GetBoundsRect
+GetBrushOrgEx
+GetCharABCWidthsA
+GetCharABCWidthsFloatA
+GetCharABCWidthsFloatW
+GetCharABCWidthsW
+GetCharWidth32A
+GetCharWidth32W
+GetCharWidthA
+GetCharWidthFloatA
+GetCharWidthFloatW
+GetCharWidthW
+GetCharacterPlacementA
+GetCharacterPlacementW
+GetClipBox
+GetClipRgn
+GetColorAdjustment
+GetColorSpace
+GetCurrentObject
+GetCurrentPositionEx
+GetDCOrgEx
+GetDIBColorTable
+GetDIBits
+GetDeviceCaps
+GetDeviceGammaRamp
+GetEnhMetaFileA
+GetEnhMetaFileBits
+GetEnhMetaFileDescriptionA
+GetEnhMetaFileDescriptionW
+GetEnhMetaFileHeader
+GetEnhMetaFilePaletteEntries
+GetEnhMetaFileW
+GetFontData
+GetFontLanguageInfo
+GetFontResourceInfo
+GetGlyphOutline
+GetGlyphOutlineA
+GetGlyphOutlineW
+GetGraphicsMode
+GetICMProfileA
+GetICMProfileW
+GetKerningPairs
+GetKerningPairsA
+GetKerningPairsW
+GetLayout
+GetLogColorSpaceA
+GetLogColorSpaceW
+GetMapMode
+GetMetaFileA
+GetMetaFileBitsEx
+GetMetaFileW
+GetMetaRgn
+GetMiterLimit
+GetNearestColor
+GetNearestPaletteIndex
+GetObjectA
+GetObjectType
+GetObjectW
+GetOutlineTextMetricsA
+GetOutlineTextMetricsW
+GetPaletteEntries
+GetPath
+GetPixel
+GetPixelFormat
+GetPolyFillMode
+GetROP2
+GetRandomRgn
+GetRasterizerCaps
+GetRegionData
+GetRgnBox
+GetStockObject
+GetStretchBltMode
+GetSystemPaletteEntries
+GetSystemPaletteUse
+GetTextAlign
+GetTextCharacterExtra
+GetTextCharset
+GetTextCharsetInfo
+GetTextColor
+GetTextExtentExPointA
+GetTextExtentExPointW
+GetTextExtentPoint32A
+GetTextExtentPoint32W
+GetTextExtentPointA
+GetTextExtentPointW
+GetTextFaceA
+GetTextFaceW
+GetTextMetricsA
+GetTextMetricsW
+GetViewportExtEx
+GetViewportOrgEx
+GetWinMetaFileBits
+GetWindowExtEx
+GetWindowOrgEx
+GetWorldTransform
+IntersectClipRect
+InvertRgn
+LPtoDP
+LineDDA
+LineTo
+MaskBlt
+ModifyWorldTransform
+MoveToEx
+OffsetClipRgn
+OffsetRgn
+OffsetViewportOrgEx
+OffsetWindowOrgEx
+PaintRgn
+PatBlt
+PathToRegion
+Pie
+PlayEnhMetaFile
+PlayEnhMetaFileRecord
+PlayMetaFile
+PlayMetaFileRecord
+PlgBlt
+PolyBezier
+PolyBezierTo
+PolyDraw
+PolyPolygon
+PolyPolyline
+PolyTextOutA
+PolyTextOutW
+Polygon
+Polyline
+PolylineTo
+PtInRegion
+PtVisible
+RealizePalette
+RectInRegion
+RectVisible
+Rectangle
+RemoveFontResourceA
+RemoveFontResourceW
+ResetDCA
+ResetDCW
+ResizePalette
+RestoreDC
+RoundRect
+SaveDC
+ScaleViewportExtEx
+ScaleWindowExtEx
+SelectClipPath
+SelectClipRgn
+SelectObject
+SelectPalette
+SetAbortProc
+SetArcDirection
+SetBitmapBits
+SetBitmapDimensionEx
+SetBkColor
+SetBkMode
+SetBoundsRect
+SetBrushOrgEx
+SetColorAdjustment
+SetColorSpace
+SetDIBColorTable
+SetDIBits
+SetDIBitsToDevice
+SetDeviceGammaRamp
+SetEnhMetaFileBits
+SetFontEnumeration
+SetGraphicsMode
+SetICMMode
+SetICMProfileA
+SetICMProfileW
+SetLayout
+SetMagicColors
+SetMapMode
+SetMapperFlags
+SetMetaFileBitsEx
+SetMetaRgn
+SetMiterLimit
+SetObjectOwner
+SetPaletteEntries
+SetPixel
+SetPixelFormat
+SetPixelV
+SetPolyFillMode
+SetROP2
+SetRectRgn
+SetStretchBltMode
+SetSystemPaletteUse
+SetTextAlign
+SetTextCharacterExtra
+SetTextColor
+SetTextJustification
+SetViewportExtEx
+SetViewportOrgEx
+SetWinMetaFileBits
+SetWindowExtEx
+SetWindowOrgEx
+SetWorldTransform
+StartDocA
+StartDocW
+StartPage
+StretchBlt
+StretchDIBits
+StrokeAndFillPath
+StrokePath
+SwapBuffers
+TextOutA
+TextOutW
+TranslateCharsetInfo
+UnrealizeObject
+UpdateColors
+UpdateICMRegKeyA
+UpdateICMRegKeyW
+WidenPath
+gdiPlaySpoolStream
+pfnRealizePalette
+pfnSelectPalette
diff --git a/win32/lib/kernel32.def b/win32/lib/kernel32.def
new file mode 100644
index 0000000..f03e17b
--- /dev/null
+++ b/win32/lib/kernel32.def
@@ -0,0 +1,770 @@
+LIBRARY kernel32.dll
+
+EXPORTS
+AddAtomA
+AddAtomW
+AllocConsole
+AllocLSCallback
+AllocSLCallback
+AreFileApisANSI
+BackupRead
+BackupSeek
+BackupWrite
+Beep
+BeginUpdateResourceA
+BeginUpdateResourceW
+BuildCommDCBA
+BuildCommDCBAndTimeoutsA
+BuildCommDCBAndTimeoutsW
+BuildCommDCBW
+CallNamedPipeA
+CallNamedPipeW
+Callback12
+Callback16
+Callback20
+Callback24
+Callback28
+Callback32
+Callback36
+Callback4
+Callback40
+Callback44
+Callback48
+Callback52
+Callback56
+Callback60
+Callback64
+Callback8
+CancelDeviceWakeupRequest
+CancelIo
+CancelWaitableTimer
+ClearCommBreak
+ClearCommError
+CloseHandle
+CloseProfileUserMapping
+CloseSystemHandle
+CommConfigDialogA
+CommConfigDialogW
+CompareFileTime
+CompareStringA
+CompareStringW
+ConnectNamedPipe
+ContinueDebugEvent
+ConvertDefaultLocale
+ConvertThreadToFiber
+ConvertToGlobalHandle
+CopyFileA
+CopyFileExA
+CopyFileExW
+CopyFileW
+CreateConsoleScreenBuffer
+CreateDirectoryA
+CreateDirectoryExA
+CreateDirectoryExW
+CreateDirectoryW
+CreateEventA
+CreateEventW
+CreateFiber
+CreateFileA
+CreateFileMappingA
+CreateFileMappingW
+CreateFileW
+CreateIoCompletionPort
+CreateKernelThread
+CreateMailslotA
+CreateMailslotW
+CreateMutexA
+CreateMutexW
+CreateNamedPipeA
+CreateNamedPipeW
+CreatePipe
+CreateProcessA
+CreateProcessW
+CreateRemoteThread
+CreateSemaphoreA
+CreateSemaphoreW
+CreateSocketHandle
+CreateTapePartition
+CreateThread
+CreateToolhelp32Snapshot
+CreateWaitableTimerA
+CreateWaitableTimerW
+DebugActiveProcess
+DebugBreak
+DefineDosDeviceA
+DefineDosDeviceW
+DeleteAtom
+DeleteCriticalSection
+DeleteFiber
+DeleteFileA
+DeleteFileW
+DeviceIoControl
+DisableThreadLibraryCalls
+DisconnectNamedPipe
+DosDateTimeToFileTime
+DuplicateHandle
+EndUpdateResourceA
+EndUpdateResourceW
+EnterCriticalSection
+EnumCalendarInfoA
+EnumCalendarInfoExA
+EnumCalendarInfoExW
+EnumCalendarInfoW
+EnumDateFormatsA
+EnumDateFormatsExA
+EnumDateFormatsExW
+EnumDateFormatsW
+EnumLanguageGroupLocalesA
+EnumLanguageGroupLocalesW
+EnumResourceLanguagesA
+EnumResourceLanguagesW
+EnumResourceNamesA
+EnumResourceNamesW
+EnumResourceTypesA
+EnumResourceTypesW
+EnumSystemCodePagesA
+EnumSystemCodePagesW
+EnumSystemGeoID
+EnumSystemLanguageGroupsA
+EnumSystemLanguageGroupsW
+EnumSystemLocalesA
+EnumSystemLocalesW
+EnumTimeFormatsA
+EnumTimeFormatsW
+EnumUILanguagesA
+EnumUILanguagesW
+EraseTape
+EscapeCommFunction
+ExitProcess
+ExitThread
+ExpandEnvironmentStringsA
+ExpandEnvironmentStringsW
+FT_Exit0
+FT_Exit12
+FT_Exit16
+FT_Exit20
+FT_Exit24
+FT_Exit28
+FT_Exit32
+FT_Exit36
+FT_Exit4
+FT_Exit40
+FT_Exit44
+FT_Exit48
+FT_Exit52
+FT_Exit56
+FT_Exit8
+FT_Prolog
+FT_Thunk
+FatalAppExitA
+FatalAppExitW
+FatalExit
+FileTimeToDosDateTime
+FileTimeToLocalFileTime
+FileTimeToSystemTime
+FillConsoleOutputAttribute
+FillConsoleOutputCharacterA
+FillConsoleOutputCharacterW
+FindAtomA
+FindAtomW
+FindClose
+FindCloseChangeNotification
+FindFirstChangeNotificationA
+FindFirstChangeNotificationW
+FindFirstFileA
+FindFirstFileExA
+FindFirstFileExW
+FindFirstFileW
+FindNextChangeNotification
+FindNextFileA
+FindNextFileW
+FindResourceA
+FindResourceExA
+FindResourceExW
+FindResourceW
+FlushConsoleInputBuffer
+FlushFileBuffers
+FlushInstructionCache
+FlushViewOfFile
+FoldStringA
+FoldStringW
+FormatMessageA
+FormatMessageW
+FreeConsole
+FreeEnvironmentStringsA
+FreeEnvironmentStringsW
+FreeLSCallback
+FreeLibrary
+FreeLibraryAndExitThread
+FreeResource
+FreeSLCallback
+GenerateConsoleCtrlEvent
+GetACP
+GetAtomNameA
+GetAtomNameW
+GetBinaryType
+GetBinaryTypeA
+GetBinaryTypeW
+GetCPInfo
+GetCPInfoExA
+GetCPInfoExW
+GetCalendarInfoA
+GetCalendarInfoW
+GetCommConfig
+GetCommMask
+GetCommModemStatus
+GetCommProperties
+GetCommState
+GetCommTimeouts
+GetCommandLineA
+GetCommandLineW
+GetCompressedFileSizeA
+GetCompressedFileSizeW
+GetComputerNameA
+GetComputerNameW
+GetConsoleCP
+GetConsoleCursorInfo
+GetConsoleMode
+GetConsoleOutputCP
+GetConsoleScreenBufferInfo
+GetConsoleTitleA
+GetConsoleTitleW
+GetCurrencyFormatA
+GetCurrencyFormatW
+GetCurrentDirectoryA
+GetCurrentDirectoryW
+GetCurrentProcess
+GetCurrentProcessId
+GetCurrentThread
+GetCurrentThreadId
+GetDateFormatA
+GetDateFormatW
+GetDaylightFlag
+GetDefaultCommConfigA
+GetDefaultCommConfigW
+GetDevicePowerState
+GetDiskFreeSpaceA
+GetDiskFreeSpaceExA
+GetDiskFreeSpaceExW
+GetDiskFreeSpaceW
+GetDriveTypeA
+GetDriveTypeW
+GetEnvironmentStrings
+GetEnvironmentStringsA
+GetEnvironmentStringsW
+GetEnvironmentVariableA
+GetEnvironmentVariableW
+GetErrorMode
+GetExitCodeProcess
+GetExitCodeThread
+GetFileAttributesA
+GetFileAttributesExA
+GetFileAttributesExW
+GetFileAttributesW
+GetFileInformationByHandle
+GetFileSize
+GetFileTime
+GetFileType
+GetFullPathNameA
+GetFullPathNameW
+GetGeoInfoA
+GetGeoInfoW
+GetHandleContext
+GetHandleInformation
+GetLSCallbackTarget
+GetLSCallbackTemplate
+GetLargestConsoleWindowSize
+GetLastError
+GetLocalTime
+GetLocaleInfoA
+GetLocaleInfoW
+GetLogicalDriveStringsA
+GetLogicalDriveStringsW
+GetLogicalDrives
+GetLongPathNameA
+GetLongPathNameW
+GetMailslotInfo
+GetModuleFileNameA
+GetModuleFileNameW
+GetModuleHandleA
+GetModuleHandleW
+GetModuleHandleExA
+GetModuleHandleExW
+GetNamedPipeHandleStateA
+GetNamedPipeHandleStateW
+GetNamedPipeInfo
+GetNumberFormatA
+GetNumberFormatW
+GetNumberOfConsoleInputEvents
+GetNumberOfConsoleMouseButtons
+GetOEMCP
+GetOverlappedResult
+GetPriorityClass
+GetPrivateProfileIntA
+GetPrivateProfileIntW
+GetPrivateProfileSectionA
+GetPrivateProfileSectionNamesA
+GetPrivateProfileSectionNamesW
+GetPrivateProfileSectionW
+GetPrivateProfileStringA
+GetPrivateProfileStringW
+GetPrivateProfileStructA
+GetPrivateProfileStructW
+GetProcAddress
+GetProcessAffinityMask
+GetProcessFlags
+GetProcessHeap
+GetProcessHeaps
+GetProcessPriorityBoost
+GetProcessShutdownParameters
+GetProcessTimes
+GetProcessVersion
+GetProcessWorkingSetSize
+GetProductName
+GetProfileIntA
+GetProfileIntW
+GetProfileSectionA
+GetProfileSectionW
+GetProfileStringA
+GetProfileStringW
+GetQueuedCompletionStatus
+GetSLCallbackTarget
+GetSLCallbackTemplate
+GetShortPathNameA
+GetShortPathNameW
+GetStartupInfoA
+GetStartupInfoW
+GetStdHandle
+GetStringTypeA
+GetStringTypeExA
+GetStringTypeExW
+GetStringTypeW
+GetSystemDefaultLCID
+GetSystemDefaultLangID
+GetSystemDefaultUILanguage
+GetSystemDirectoryA
+GetSystemDirectoryW
+GetSystemInfo
+GetSystemPowerStatus
+GetSystemTime
+GetSystemTimeAdjustment
+GetSystemTimeAsFileTime
+GetTapeParameters
+GetTapePosition
+GetTapeStatus
+GetTempFileNameA
+GetTempFileNameW
+GetTempPathA
+GetTempPathW
+GetThreadContext
+GetThreadLocale
+GetThreadPriority
+GetThreadPriorityBoost
+GetThreadSelectorEntry
+GetThreadTimes
+GetTickCount
+GetTimeFormatA
+GetTimeFormatW
+GetTimeZoneInformation
+GetUserDefaultLCID
+GetUserDefaultLangID
+GetUserDefaultUILanguage
+GetUserGeoID
+GetVersion
+GetVersionExA
+GetVersionExW
+GetVolumeInformationA
+GetVolumeInformationW
+GetWindowsDirectoryA
+GetWindowsDirectoryW
+GetWriteWatch
+GlobalAddAtomA
+GlobalAddAtomW
+GlobalAlloc
+GlobalCompact
+GlobalDeleteAtom
+GlobalFindAtomA
+GlobalFindAtomW
+GlobalFix
+GlobalFlags
+GlobalFree
+GlobalGetAtomNameA
+GlobalGetAtomNameW
+GlobalHandle
+GlobalLock
+GlobalMemoryStatus
+GlobalReAlloc
+GlobalSize
+GlobalUnWire
+GlobalUnfix
+GlobalUnlock
+GlobalWire
+Heap32First
+Heap32ListFirst
+Heap32ListNext
+Heap32Next
+HeapAlloc
+HeapCompact
+HeapCreate
+HeapDestroy
+HeapFree
+HeapLock
+HeapReAlloc
+HeapSetFlags
+HeapSize
+HeapUnlock
+HeapValidate
+HeapWalk
+InitAtomTable
+InitializeCriticalSection
+InitializeCriticalSectionAndSpinCount
+InterlockedCompareExchange
+InterlockedDecrement
+InterlockedExchange
+InterlockedExchangeAdd
+InterlockedIncrement
+InvalidateNLSCache
+IsBadCodePtr
+IsBadHugeReadPtr
+IsBadHugeWritePtr
+IsBadReadPtr
+IsBadStringPtrA
+IsBadStringPtrW
+IsBadWritePtr
+IsDBCSLeadByte
+IsDBCSLeadByteEx
+IsDebuggerPresent
+IsLSCallback
+IsProcessorFeaturePresent
+IsSLCallback
+IsSystemResumeAutomatic
+IsValidCodePage
+IsValidLanguageGroup
+IsValidLocale
+K32Thk1632Epilog
+K32Thk1632Prolog
+K32_NtCreateFile
+K32_RtlNtStatusToDosError
+LCMapStringA
+LCMapStringW
+LeaveCriticalSection
+LoadLibraryA
+LoadLibraryExA
+LoadLibraryExW
+LoadLibraryW
+LoadModule
+LoadResource
+LocalAlloc
+LocalCompact
+LocalFileTimeToFileTime
+LocalFlags
+LocalFree
+LocalHandle
+LocalLock
+LocalReAlloc
+LocalShrink
+LocalSize
+LocalUnlock
+LockFile
+LockFileEx
+LockResource
+MakeCriticalSectionGlobal
+MapHInstLS
+MapHInstLS_PN
+MapHInstSL
+MapHInstSL_PN
+MapHModuleLS
+MapHModuleSL
+MapLS
+MapSL
+MapSLFix
+MapViewOfFile
+MapViewOfFileEx
+Module32First
+Module32Next
+MoveFileA
+MoveFileExA
+MoveFileExW
+MoveFileW
+MulDiv
+MultiByteToWideChar
+NotifyNLSUserCache
+OpenEventA
+OpenEventW
+OpenFile
+OpenFileMappingA
+OpenFileMappingW
+OpenMutexA
+OpenMutexW
+OpenProcess
+OpenProfileUserMapping
+OpenSemaphoreA
+OpenSemaphoreW
+OpenThread
+OpenVxDHandle
+OpenWaitableTimerA
+OpenWaitableTimerW
+OutputDebugStringA
+OutputDebugStringW
+PeekConsoleInputA
+PeekConsoleInputW
+PeekNamedPipe
+PostQueuedCompletionStatus
+PrepareTape
+Process32First
+Process32Next
+PulseEvent
+PurgeComm
+QT_Thunk
+QueryDosDeviceA
+QueryDosDeviceW
+QueryNumberOfEventLogRecords
+QueryOldestEventLogRecord
+QueryPerformanceCounter
+QueryPerformanceFrequency
+QueueUserAPC
+RaiseException
+ReadConsoleA
+ReadConsoleInputA
+ReadConsoleInputW
+ReadConsoleOutputA
+ReadConsoleOutputAttribute
+ReadConsoleOutputCharacterA
+ReadConsoleOutputCharacterW
+ReadConsoleOutputW
+ReadConsoleW
+ReadDirectoryChangesW
+ReadFile
+ReadFileEx
+ReadFileScatter
+ReadProcessMemory
+RegisterServiceProcess
+RegisterSysMsgHandler
+ReinitializeCriticalSection
+ReleaseMutex
+ReleaseSemaphore
+RemoveDirectoryA
+RemoveDirectoryW
+RequestDeviceWakeup
+RequestWakeupLatency
+ResetEvent
+ResetNLSUserInfoCache
+ResetWriteWatch
+ResumeThread
+RtlAddFunctionTable
+RtlDeleteFunctionTable
+RtlFillMemory
+RtlInstallFunctionTableCallback
+RtlMoveMemory
+RtlUnwind
+RtlUnwindEx
+RtlZeroMemory
+SMapLS
+SMapLS_IP_EBP_12
+SMapLS_IP_EBP_16
+SMapLS_IP_EBP_20
+SMapLS_IP_EBP_24
+SMapLS_IP_EBP_28
+SMapLS_IP_EBP_32
+SMapLS_IP_EBP_36
+SMapLS_IP_EBP_40
+SMapLS_IP_EBP_8
+SUnMapLS
+SUnMapLS_IP_EBP_12
+SUnMapLS_IP_EBP_16
+SUnMapLS_IP_EBP_20
+SUnMapLS_IP_EBP_24
+SUnMapLS_IP_EBP_28
+SUnMapLS_IP_EBP_32
+SUnMapLS_IP_EBP_36
+SUnMapLS_IP_EBP_40
+SUnMapLS_IP_EBP_8
+ScrollConsoleScreenBufferA
+ScrollConsoleScreenBufferW
+SearchPathA
+SearchPathW
+SetCalendarInfoA
+SetCalendarInfoW
+SetCommBreak
+SetCommConfig
+SetCommMask
+SetCommState
+SetCommTimeouts
+SetComputerNameA
+SetComputerNameW
+SetConsoleActiveScreenBuffer
+SetConsoleCP
+SetConsoleCtrlHandler
+SetConsoleCursorInfo
+SetConsoleCursorPosition
+SetConsoleMode
+SetConsoleOutputCP
+SetConsoleScreenBufferSize
+SetConsoleTextAttribute
+SetConsoleTitleA
+SetConsoleTitleW
+SetConsoleWindowInfo
+SetCriticalSectionSpinCount
+SetCurrentDirectoryA
+SetCurrentDirectoryW
+SetDaylightFlag
+SetDefaultCommConfigA
+SetDefaultCommConfigW
+SetEndOfFile
+SetEnvironmentVariableA
+SetEnvironmentVariableW
+SetErrorMode
+SetEvent
+SetFileApisToANSI
+SetFileApisToOEM
+SetFileAttributesA
+SetFileAttributesW
+SetFilePointer
+SetFilePointerEx
+SetFileTime
+SetHandleContext
+SetHandleCount
+SetHandleInformation
+SetLastError
+SetLocalTime
+SetLocaleInfoA
+SetLocaleInfoW
+SetMailslotInfo
+SetMessageWaitingIndicator
+SetNamedPipeHandleState
+SetPriorityClass
+SetProcessAffinityMask
+SetProcessPriorityBoost
+SetProcessShutdownParameters
+SetProcessWorkingSetSize
+SetStdHandle
+SetSystemPowerState
+SetSystemTime
+SetSystemTimeAdjustment
+SetTapeParameters
+SetTapePosition
+SetThreadAffinityMask
+SetThreadContext
+SetThreadExecutionState
+SetThreadIdealProcessor
+SetThreadLocale
+SetThreadPriority
+SetThreadPriorityBoost
+SetTimeZoneInformation
+SetUnhandledExceptionFilter
+SetUserGeoID
+SetVolumeLabelA
+SetVolumeLabelW
+SetWaitableTimer
+SetupComm
+SignalObjectAndWait
+SignalSysMsgHandlers
+SizeofResource
+Sleep
+SleepEx
+SuspendThread
+SwitchToFiber
+SwitchToThread
+SystemTimeToFileTime
+SystemTimeToTzSpecificLocalTime
+TerminateProcess
+TerminateThread
+Thread32First
+Thread32Next
+ThunkConnect32
+TlsAlloc
+TlsAllocInternal
+TlsFree
+TlsFreeInternal
+TlsGetValue
+TlsSetValue
+Toolhelp32ReadProcessMemory
+TransactNamedPipe
+TransmitCommChar
+TryEnterCriticalSection
+UTRegister
+UTUnRegister
+UnMapLS
+UnMapSLFixArray
+UnhandledExceptionFilter
+UninitializeCriticalSection
+UnlockFile
+UnlockFileEx
+UnmapViewOfFile
+UpdateResourceA
+UpdateResourceW
+VerLanguageNameA
+VerLanguageNameW
+VirtualAlloc
+VirtualAllocEx
+VirtualFree
+VirtualFreeEx
+VirtualLock
+VirtualProtect
+VirtualProtectEx
+VirtualQuery
+VirtualQueryEx
+VirtualUnlock
+WaitCommEvent
+WaitForDebugEvent
+WaitForMultipleObjects
+WaitForMultipleObjectsEx
+WaitForSingleObject
+WaitForSingleObjectEx
+WaitNamedPipeA
+WaitNamedPipeW
+WideCharToMultiByte
+WinExec
+WriteConsoleA
+WriteConsoleInputA
+WriteConsoleInputW
+WriteConsoleOutputA
+WriteConsoleOutputAttribute
+WriteConsoleOutputCharacterA
+WriteConsoleOutputCharacterW
+WriteConsoleOutputW
+WriteConsoleW
+WriteFile
+WriteFileEx
+WriteFileGather
+WritePrivateProfileSectionA
+WritePrivateProfileSectionW
+WritePrivateProfileStringA
+WritePrivateProfileStringW
+WritePrivateProfileStructA
+WritePrivateProfileStructW
+WriteProcessMemory
+WriteProfileSectionA
+WriteProfileSectionW
+WriteProfileStringA
+WriteProfileStringW
+WriteTapemark
+_DebugOut
+_DebugPrintf
+_hread
+_hwrite
+_lclose
+_lcreat
+_llseek
+_lopen
+_lread
+_lwrite
+dprintf
+lstrcat
+lstrcatA
+lstrcatW
+lstrcmp
+lstrcmpA
+lstrcmpW
+lstrcmpi
+lstrcmpiA
+lstrcmpiW
+lstrcpy
+lstrcpyA
+lstrcpyW
+lstrcpyn
+lstrcpynA
+lstrcpynW
+lstrlen
+lstrlenA
+lstrlenW
diff --git a/win32/lib/msvcrt.def b/win32/lib/msvcrt.def
new file mode 100644
index 0000000..742acb8
--- /dev/null
+++ b/win32/lib/msvcrt.def
@@ -0,0 +1,1399 @@
+LIBRARY msvcrt.dll
+
+EXPORTS
+$I10_OUTPUT
+??0__non_rtti_object@@QAE@ABV0@@Z
+??0__non_rtti_object@@QAE@PBD@Z
+??0bad_cast@@AAE@PBQBD@Z
+??0bad_cast@@QAE@ABQBD@Z
+??0bad_cast@@QAE@ABV0@@Z
+??0bad_cast@@QAE@PBD@Z
+??0bad_typeid@@QAE@ABV0@@Z
+??0bad_typeid@@QAE@PBD@Z
+??0exception@@QAE@ABQBD@Z
+??0exception@@QAE@ABQBDH@Z
+??0exception@@QAE@ABV0@@Z
+??0exception@@QAE@XZ
+??1__non_rtti_object@@UAE@XZ
+??1bad_cast@@UAE@XZ
+??1bad_typeid@@UAE@XZ
+??1exception@@UAE@XZ
+??1type_info@@UAE@XZ
+??2@YAPAXI@Z
+??2@YAPAXIHPBDH@Z
+??3@YAXPAX@Z
+??4__non_rtti_object@@QAEAAV0@ABV0@@Z
+??4bad_cast@@QAEAAV0@ABV0@@Z
+??4bad_typeid@@QAEAAV0@ABV0@@Z
+??4exception@@QAEAAV0@ABV0@@Z
+??8type_info@@QBEHABV0@@Z
+??9type_info@@QBEHABV0@@Z
+??_7__non_rtti_object@@6B@
+??_7bad_cast@@6B@
+??_7bad_typeid@@6B@
+??_7exception@@6B@
+??_E__non_rtti_object@@UAEPAXI@Z
+??_Ebad_cast@@UAEPAXI@Z
+??_Ebad_typeid@@UAEPAXI@Z
+??_Eexception@@UAEPAXI@Z
+??_Fbad_cast@@QAEXXZ
+??_Fbad_typeid@@QAEXXZ
+??_G__non_rtti_object@@UAEPAXI@Z
+??_Gbad_cast@@UAEPAXI@Z
+??_Gbad_typeid@@UAEPAXI@Z
+??_Gexception@@UAEPAXI@Z
+??_U@YAPAXI@Z
+??_U@YAPAXIHPBDH@Z
+??_V@YAXPAX@Z
+?_query_new_handler@@YAP6AHI@ZXZ
+?_query_new_mode@@YAHXZ
+?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z
+?_set_new_mode@@YAHH@Z
+?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z
+?before@type_info@@QBEHABV1@@Z
+?name@type_info@@QBEPBDXZ
+?raw_name@type_info@@QBEPBDXZ
+?set_new_handler@@YAP6AXXZP6AXXZ@Z
+?set_terminate@@YAP6AXXZP6AXXZ@Z
+?set_unexpected@@YAP6AXXZP6AXXZ@Z
+?terminate@@YAXXZ
+?unexpected@@YAXXZ
+?what@exception@@UBEPBDXZ
+_CIacos
+_CIasin
+_CIatan
+_CIatan2
+_CIcos
+_CIcosh
+_CIexp
+_CIfmod
+_CIlog
+_CIlog10
+_CIpow
+_CIsin
+_CIsinh
+_CIsqrt
+_CItan
+_CItanh
+_CrtCheckMemory
+_CrtDbgBreak
+_CrtDbgReport
+_CrtDbgReportV
+_CrtDbgReportW
+_CrtDbgReportWV
+_CrtDoForAllClientObjects
+_CrtDumpMemoryLeaks
+_CrtIsMemoryBlock
+_CrtIsValidHeapPointer
+_CrtIsValidPointer
+_CrtMemCheckpoint
+_CrtMemDifference
+_CrtMemDumpAllObjectsSince
+_CrtMemDumpStatistics
+_CrtReportBlockType
+_CrtSetAllocHook
+_CrtSetBreakAlloc
+_CrtSetDbgBlockType
+_CrtSetDbgFlag
+_CrtSetDumpClient
+_CrtSetReportFile
+_CrtSetReportHook
+_CrtSetReportHook2
+_CrtSetReportMode
+_CxxThrowException
+_EH_prolog
+_Getdays
+_Getmonths
+_Gettnames
+_HUGE
+_Strftime
+_XcptFilter
+__CppXcptFilter
+__CxxCallUnwindDelDtor
+__CxxCallUnwindDtor
+__CxxCallUnwindVecDtor
+__CxxDetectRethrow
+__CxxExceptionFilter
+__CxxFrameHandler
+__CxxFrameHandler2
+__CxxFrameHandler3
+__CxxLongjmpUnwind
+__CxxQueryExceptionSize
+__CxxRegisterExceptionObject
+__CxxUnregisterExceptionObject
+__DestructExceptionObject
+__RTCastToVoid
+__RTDynamicCast
+__RTtypeid
+__STRINGTOLD
+___lc_codepage_func
+___lc_collate_cp_func
+___lc_handle_func
+___mb_cur_max_func
+___setlc_active_func
+___unguarded_readlc_active_add_func
+__argc
+__argv
+__badioinfo
+__crtCompareStringA
+__crtCompareStringW
+__crtGetLocaleInfoW
+__crtGetStringTypeW
+__crtLCMapStringA
+__crtLCMapStringW
+__daylight
+__dllonexit
+__doserrno
+__dstbias
+__fpecode
+__getmainargs
+__initenv
+__iob_func
+__isascii
+__iscsym
+__iscsymf
+__lc_codepage
+__lc_collate_cp
+__lc_handle
+__lconv_init
+__libm_sse2_acos
+__libm_sse2_acosf
+__libm_sse2_asin
+__libm_sse2_asinf
+__libm_sse2_atan
+__libm_sse2_atan2
+__libm_sse2_atanf
+__libm_sse2_cos
+__libm_sse2_cosf
+__libm_sse2_exp
+__libm_sse2_expf
+__libm_sse2_log
+__libm_sse2_log10
+__libm_sse2_log10f
+__libm_sse2_logf
+__libm_sse2_pow
+__libm_sse2_powf
+__libm_sse2_sin
+__libm_sse2_sinf
+__libm_sse2_tan
+__libm_sse2_tanf
+__mb_cur_max
+__p___argc
+__p___argv
+__p___initenv
+__p___mb_cur_max
+__p___wargv
+__p___winitenv
+__p__acmdln
+__p__amblksiz
+__p__commode
+__p__daylight
+__p__dstbias
+__p__environ
+__p__fileinfo
+__p__fmode
+__p__iob
+__p__mbcasemap
+__p__mbctype
+__p__osver
+__p__pctype
+__p__pgmptr
+__p__pwctype
+__p__timezone
+__p__tzname
+__p__wcmdln
+__p__wenviron
+__p__winmajor
+__p__winminor
+__p__winver
+__p__wpgmptr
+__pctype_func
+__pioinfo
+__pwctype_func
+__pxcptinfoptrs
+__set_app_type
+__setlc_active
+__setusermatherr
+__strncnt
+__threadhandle
+__threadid
+__toascii
+__unDName
+__unDNameEx
+__uncaught_exception
+__unguarded_readlc_active
+__wargv
+__wcserror
+__wcserror_s
+__wcsncnt
+__wgetmainargs
+__winitenv
+_abnormal_termination
+_abs64
+_access
+_access_s
+_acmdln
+_adj_fdiv_m16i
+_adj_fdiv_m32
+_adj_fdiv_m32i
+_adj_fdiv_m64
+_adj_fdiv_r
+_adj_fdivr_m16i
+_adj_fdivr_m32
+_adj_fdivr_m32i
+_adj_fdivr_m64
+_adj_fpatan
+_adj_fprem
+_adj_fprem1
+_adj_fptan
+_adjust_fdiv
+_aexit_rtn
+_aligned_free
+_aligned_free_dbg
+_aligned_malloc
+_aligned_malloc_dbg
+_aligned_offset_malloc
+_aligned_offset_malloc_dbg
+_aligned_offset_realloc
+_aligned_offset_realloc_dbg
+_aligned_realloc
+_aligned_realloc_dbg
+_amsg_exit
+_assert
+_atodbl
+_atodbl_l
+_atof_l
+_atoflt_l
+_atoi64
+_atoi64_l
+_atoi_l
+_atol_l
+_atoldbl
+_atoldbl_l
+_beep
+_beginthread
+_beginthreadex
+_c_exit
+_cabs
+_callnewh
+_calloc_dbg
+_cexit
+_cgets
+_cgets_s
+_cgetws
+_cgetws_s
+_chdir
+_chdrive
+_chgsign
+_chkesp
+_chmod
+_chsize
+_chsize_s
+_chvalidator
+_chvalidator_l
+_clearfp
+_close
+_commit
+_commode
+_control87
+_controlfp
+_controlfp_s
+_copysign
+_cprintf
+_cprintf_l
+_cprintf_p
+_cprintf_p_l
+_cprintf_s
+_cprintf_s_l
+_cputs
+_cputws
+_creat
+_crtAssertBusy
+_crtBreakAlloc
+_crtDbgFlag
+_cscanf
+_cscanf_l
+_cscanf_s
+_cscanf_s_l
+_ctime32
+_ctime32_s
+_ctime64
+_ctime64_s
+_ctype
+_cwait
+_cwprintf
+_cwprintf_l
+_cwprintf_p
+_cwprintf_p_l
+_cwprintf_s
+_cwprintf_s_l
+_cwscanf
+_cwscanf_l
+_cwscanf_s
+_cwscanf_s_l
+_daylight
+_difftime32
+_difftime64
+_dstbias
+_dup
+_dup2
+_ecvt
+_ecvt_s
+_endthread
+_endthreadex
+_environ
+_eof
+_errno
+_except_handler2
+_except_handler3
+_except_handler4_common
+_execl
+_execle
+_execlp
+_execlpe
+_execv
+_execve
+_execvp
+_execvpe
+_exit
+_expand
+_expand_dbg
+_fcloseall
+_fcvt
+_fcvt_s
+_fdopen
+_fgetchar
+_fgetwchar
+_filbuf
+_fileinfo
+_filelength
+_filelengthi64
+_fileno
+_findclose
+_findfirst
+_findfirst64
+_findfirsti64
+_findnext
+_findnext64
+_findnexti64
+_finite
+_flsbuf
+_flushall
+_fmode
+_fpclass
+_fpieee_flt
+_fpreset
+_fprintf_l
+_fprintf_p
+_fprintf_p_l
+_fprintf_s_l
+_fputchar
+_fputwchar
+_free_dbg
+_freea
+_freea_s
+_fscanf_l
+_fscanf_s_l
+_fseeki64
+_fsopen
+_fstat
+_fstat64
+_fstati64
+_ftime
+_ftime32
+_ftime32_s
+_ftime64
+_ftime64_s
+_ftol
+_ftol2
+_ftol2_sse
+_ftol2_sse_excpt
+_fullpath
+_fullpath_dbg
+_futime
+_futime32
+_futime64
+_fwprintf_l
+_fwprintf_p
+_fwprintf_p_l
+_fwprintf_s_l
+_fwscanf_l
+_fwscanf_s_l
+_gcvt
+_gcvt_s
+_get_doserrno
+_get_environ
+_get_errno
+_get_fileinfo
+_get_fmode
+_get_heap_handle
+_get_osfhandle
+_get_osplatform
+_get_osver
+_get_output_format
+_get_pgmptr
+_get_sbh_threshold
+_get_wenviron
+_get_winmajor
+_get_winminor
+_get_winver
+_get_wpgmptr
+_getch
+_getche
+_getcwd
+_getdcwd
+_getdiskfree
+_getdllprocaddr
+_getdrive
+_getdrives
+_getmaxstdio
+_getmbcp
+_getpid
+_getsystime
+_getw
+_getwch
+_getwche
+_getws
+_global_unwind2
+_gmtime32
+_gmtime32_s
+_gmtime64
+_gmtime64_s
+_heapadd
+_heapchk
+_heapmin
+_heapset
+_heapused
+_heapwalk
+_hypot
+_i64toa
+_i64toa_s
+_i64tow
+_i64tow_s
+_initterm
+_initterm_e
+_inp
+_inpd
+_inpw
+_invalid_parameter
+_iob
+_isalnum_l
+_isalpha_l
+_isatty
+_iscntrl_l
+_isctype
+_isctype_l
+_isdigit_l
+_isgraph_l
+_isleadbyte_l
+_islower_l
+_ismbbalnum
+_ismbbalnum_l
+_ismbbalpha
+_ismbbalpha_l
+_ismbbgraph
+_ismbbgraph_l
+_ismbbkalnum
+_ismbbkalnum_l
+_ismbbkana
+_ismbbkana_l
+_ismbbkprint
+_ismbbkprint_l
+_ismbbkpunct
+_ismbbkpunct_l
+_ismbblead
+_ismbblead_l
+_ismbbprint
+_ismbbprint_l
+_ismbbpunct
+_ismbbpunct_l
+_ismbbtrail
+_ismbbtrail_l
+_ismbcalnum
+_ismbcalnum_l
+_ismbcalpha
+_ismbcalpha_l
+_ismbcdigit
+_ismbcdigit_l
+_ismbcgraph
+_ismbcgraph_l
+_ismbchira
+_ismbchira_l
+_ismbckata
+_ismbckata_l
+_ismbcl0
+_ismbcl0_l
+_ismbcl1
+_ismbcl1_l
+_ismbcl2
+_ismbcl2_l
+_ismbclegal
+_ismbclegal_l
+_ismbclower
+_ismbclower_l
+_ismbcprint
+_ismbcprint_l
+_ismbcpunct
+_ismbcpunct_l
+_ismbcspace
+_ismbcspace_l
+_ismbcsymbol
+_ismbcsymbol_l
+_ismbcupper
+_ismbcupper_l
+_ismbslead
+_ismbslead_l
+_ismbstrail
+_ismbstrail_l
+_isnan
+_isprint_l
+_isspace_l
+_isupper_l
+_iswalnum_l
+_iswalpha_l
+_iswcntrl_l
+_iswctype_l
+_iswdigit_l
+_iswgraph_l
+_iswlower_l
+_iswprint_l
+_iswpunct_l
+_iswspace_l
+_iswupper_l
+_iswxdigit_l
+_isxdigit_l
+_itoa
+_itoa_s
+_itow
+_itow_s
+_j0
+_j1
+_jn
+_kbhit
+_lfind
+_lfind_s
+_loaddll
+_local_unwind2
+_local_unwind4
+_localtime32
+_localtime32_s
+_localtime64
+_localtime64_s
+_lock
+_locking
+_logb
+_longjmpex
+_lrotl
+_lrotr
+_lsearch
+_lsearch_s
+_lseek
+_lseeki64
+_ltoa
+_ltoa_s
+_ltow
+_ltow_s
+_makepath
+_makepath_s
+_malloc_dbg
+_mbbtombc
+_mbbtombc_l
+_mbbtype
+_mbcasemap
+_mbccpy
+_mbccpy_l
+_mbccpy_s
+_mbccpy_s_l
+_mbcjistojms
+_mbcjistojms_l
+_mbcjmstojis
+_mbcjmstojis_l
+_mbclen
+_mbclen_l
+_mbctohira
+_mbctohira_l
+_mbctokata
+_mbctokata_l
+_mbctolower
+_mbctolower_l
+_mbctombb
+_mbctombb_l
+_mbctoupper
+_mbctoupper_l
+_mbctype
+_mblen_l
+_mbsbtype
+_mbsbtype_l
+_mbscat
+_mbscat_s
+_mbscat_s_l
+_mbschr
+_mbschr_l
+_mbscmp
+_mbscmp_l
+_mbscoll
+_mbscoll_l
+_mbscpy
+_mbscpy_s
+_mbscpy_s_l
+_mbscspn
+_mbscspn_l
+_mbsdec
+_mbsdec_l
+_mbsdup
+_mbsicmp
+_mbsicmp_l
+_mbsicoll
+_mbsicoll_l
+_mbsinc
+_mbsinc_l
+_mbslen
+_mbslen_l
+_mbslwr
+_mbslwr_l
+_mbslwr_s
+_mbslwr_s_l
+_mbsnbcat
+_mbsnbcat_l
+_mbsnbcat_s
+_mbsnbcat_s_l
+_mbsnbcmp
+_mbsnbcmp_l
+_mbsnbcnt
+_mbsnbcnt_l
+_mbsnbcoll
+_mbsnbcoll_l
+_mbsnbcpy
+_mbsnbcpy_l
+_mbsnbcpy_s
+_mbsnbcpy_s_l
+_mbsnbicmp
+_mbsnbicmp_l
+_mbsnbicoll
+_mbsnbicoll_l
+_mbsnbset
+_mbsnbset_l
+_mbsnbset_s
+_mbsnbset_s_l
+_mbsncat
+_mbsncat_l
+_mbsncat_s
+_mbsncat_s_l
+_mbsnccnt
+_mbsnccnt_l
+_mbsncmp
+_mbsncmp_l
+_mbsncoll
+_mbsncoll_l
+_mbsncpy
+_mbsncpy_l
+_mbsncpy_s
+_mbsncpy_s_l
+_mbsnextc
+_mbsnextc_l
+_mbsnicmp
+_mbsnicmp_l
+_mbsnicoll
+_mbsnicoll_l
+_mbsninc
+_mbsninc_l
+_mbsnlen
+_mbsnlen_l
+_mbsnset
+_mbsnset_l
+_mbsnset_s
+_mbsnset_s_l
+_mbspbrk
+_mbspbrk_l
+_mbsrchr
+_mbsrchr_l
+_mbsrev
+_mbsrev_l
+_mbsset
+_mbsset_l
+_mbsset_s
+_mbsset_s_l
+_mbsspn
+_mbsspn_l
+_mbsspnp
+_mbsspnp_l
+_mbsstr
+_mbsstr_l
+_mbstok
+_mbstok_l
+_mbstok_s
+_mbstok_s_l
+_mbstowcs_l
+_mbstowcs_s_l
+_mbstrlen
+_mbstrlen_l
+_mbstrnlen
+_mbstrnlen_l
+_mbsupr
+_mbsupr_l
+_mbsupr_s
+_mbsupr_s_l
+_mbtowc_l
+_memccpy
+_memicmp
+_memicmp_l
+_mkdir
+_mkgmtime
+_mkgmtime32
+_mkgmtime64
+_mktemp
+_mktemp_s
+_mktime32
+_mktime64
+_msize
+_msize_debug
+_nextafter
+_onexit
+_open
+_open_osfhandle
+_osplatform
+_osver
+_outp
+_outpd
+_outpw
+_pclose
+_pctype
+_pgmptr
+_pipe
+_popen
+_printf_l
+_printf_p
+_printf_p_l
+_printf_s_l
+_purecall
+_putch
+_putenv
+_putenv_s
+_putw
+_putwch
+_putws
+_pwctype
+_read
+_realloc_dbg
+_resetstkoflw
+_rmdir
+_rmtmp
+_rotl
+_rotl64
+_rotr
+_rotr64
+_safe_fdiv
+_safe_fdivr
+_safe_fprem
+_safe_fprem1
+_scalb
+_scanf_l
+_scanf_s_l
+_scprintf
+_scprintf_l
+_scprintf_p_l
+_scwprintf
+_scwprintf_l
+_scwprintf_p_l
+_searchenv
+_searchenv_s
+_seh_longjmp_unwind
+_seh_longjmp_unwind4
+_set_SSE2_enable
+_set_controlfp
+_set_doserrno
+_set_errno
+_set_error_mode
+_set_fileinfo
+_set_fmode
+_set_output_format
+_set_sbh_threshold
+_seterrormode
+_setjmp
+_setjmp3
+_setmaxstdio
+_setmbcp
+_setmode
+_setsystime
+_sleep
+_snprintf
+_snprintf_c
+_snprintf_c_l
+_snprintf_l
+_snprintf_s
+_snprintf_s_l
+_snscanf
+_snscanf_l
+_snscanf_s
+_snscanf_s_l
+_snwprintf
+_snwprintf_l
+_snwprintf_s
+_snwprintf_s_l
+_snwscanf
+_snwscanf_l
+_snwscanf_s
+_snwscanf_s_l
+_sopen
+_sopen_s
+_spawnl
+_spawnle
+_spawnlp
+_spawnlpe
+_spawnv
+_spawnve
+_spawnvp
+_spawnvpe
+_splitpath
+_splitpath_s
+_sprintf_l
+_sprintf_p_l
+_sprintf_s_l
+_sscanf_l
+_sscanf_s_l
+_stat
+_stat64
+_stati64
+_statusfp
+_strcmpi
+_strcoll_l
+_strdate
+_strdate_s
+_strdup
+_strdup_dbg
+_strerror
+_strerror_s
+_stricmp
+_stricmp_l
+_stricoll
+_stricoll_l
+_strlwr
+_strlwr_l
+_strlwr_s
+_strlwr_s_l
+_strncoll
+_strncoll_l
+_strnicmp
+_strnicmp_l
+_strnicoll
+_strnicoll_l
+_strnset
+_strnset_s
+_strrev
+_strset
+_strset_s
+_strtime
+_strtime_s
+_strtod_l
+_strtoi64
+_strtoi64_l
+_strtol_l
+_strtoui64
+_strtoui64_l
+_strtoul_l
+_strupr
+_strupr_l
+_strupr_s
+_strupr_s_l
+_strxfrm_l
+_swab
+_swprintf
+_swprintf_c
+_swprintf_c_l
+_swprintf_p_l
+_swprintf_s_l
+_swscanf_l
+_swscanf_s_l
+_sys_errlist
+_sys_nerr
+_tell
+_telli64
+_tempnam
+_tempnam_dbg
+_time32
+_time64
+_timezone
+_tolower
+_tolower_l
+_toupper
+_toupper_l
+_towlower_l
+_towupper_l
+_tzname
+_tzset
+_ui64toa
+_ui64toa_s
+_ui64tow
+_ui64tow_s
+_ultoa
+_ultoa_s
+_ultow
+_ultow_s
+_umask
+_umask_s
+_ungetch
+_ungetwch
+_unlink
+_unloaddll
+_unlock
+_utime
+_utime32
+_utime64
+_vcprintf
+_vcprintf_l
+_vcprintf_p
+_vcprintf_p_l
+_vcprintf_s
+_vcprintf_s_l
+_vcwprintf
+_vcwprintf_l
+_vcwprintf_p
+_vcwprintf_p_l
+_vcwprintf_s
+_vcwprintf_s_l
+_vfprintf_l
+_vfprintf_p
+_vfprintf_p_l
+_vfprintf_s_l
+_vfwprintf_l
+_vfwprintf_p
+_vfwprintf_p_l
+_vfwprintf_s_l
+_vprintf_l
+_vprintf_p
+_vprintf_p_l
+_vprintf_s_l
+_vscprintf
+_vscprintf_l
+_vscprintf_p_l
+_vscwprintf
+_vscwprintf_l
+_vscwprintf_p_l
+_vsnprintf
+_vsnprintf_c
+_vsnprintf_c_l
+_vsnprintf_l
+_vsnprintf_s
+_vsnprintf_s_l
+_vsnwprintf
+_vsnwprintf_l
+_vsnwprintf_s
+_vsnwprintf_s_l
+_vsprintf_l
+_vsprintf_p
+_vsprintf_p_l
+_vsprintf_s_l
+_vswprintf
+_vswprintf_c
+_vswprintf_c_l
+_vswprintf_l
+_vswprintf_p_l
+_vswprintf_s_l
+_vwprintf_l
+_vwprintf_p
+_vwprintf_p_l
+_vwprintf_s_l
+_waccess
+_waccess_s
+_wasctime
+_wasctime_s
+_wassert
+_wchdir
+_wchmod
+_wcmdln
+_wcreat
+_wcscoll_l
+_wcsdup
+_wcsdup_dbg
+_wcserror
+_wcserror_s
+_wcsftime_l
+_wcsicmp
+_wcsicmp_l
+_wcsicoll
+_wcsicoll_l
+_wcslwr
+_wcslwr_l
+_wcslwr_s
+_wcslwr_s_l
+_wcsncoll
+_wcsncoll_l
+_wcsnicmp
+_wcsnicmp_l
+_wcsnicoll
+_wcsnicoll_l
+_wcsnset
+_wcsnset_s
+_wcsrev
+_wcsset
+_wcsset_s
+_wcstoi64
+_wcstoi64_l
+_wcstol_l
+_wcstombs_l
+_wcstombs_s_l
+_wcstoui64
+_wcstoui64_l
+_wcstoul_l
+_wcsupr
+_wcsupr_l
+_wcsupr_s
+_wcsupr_s_l
+_wcsxfrm_l
+_wctime
+_wctime32
+_wctime32_s
+_wctime64
+_wctime64_s
+_wctomb_l
+_wctomb_s_l
+_wctype
+_wenviron
+_wexecl
+_wexecle
+_wexeclp
+_wexeclpe
+_wexecv
+_wexecve
+_wexecvp
+_wexecvpe
+_wfdopen
+_wfindfirst
+_wfindfirst64
+_wfindfirsti64
+_wfindnext
+_wfindnext64
+_wfindnexti64
+_wfopen
+_wfopen_s
+_wfreopen
+_wfreopen_s
+_wfsopen
+_wfullpath
+_wfullpath_dbg
+_wgetcwd
+_wgetdcwd
+_wgetenv
+_wgetenv_s
+_winmajor
+_winminor
+_winput_s
+_winver
+_wmakepath
+_wmakepath_s
+_wmkdir
+_wmktemp
+_wmktemp_s
+_wopen
+_woutput_s
+_wperror
+_wpgmptr
+_wpopen
+_wprintf_l
+_wprintf_p
+_wprintf_p_l
+_wprintf_s_l
+_wputenv
+_wputenv_s
+_wremove
+_wrename
+_write
+_wrmdir
+_wscanf_l
+_wscanf_s_l
+_wsearchenv
+_wsearchenv_s
+_wsetlocale
+_wsopen
+_wsopen_s
+_wspawnl
+_wspawnle
+_wspawnlp
+_wspawnlpe
+_wspawnv
+_wspawnve
+_wspawnvp
+_wspawnvpe
+_wsplitpath
+_wsplitpath_s
+_wstat
+_wstat64
+_wstati64
+_wstrdate
+_wstrdate_s
+_wstrtime
+_wstrtime_s
+_wsystem
+_wtempnam
+_wtempnam_dbg
+_wtmpnam
+_wtmpnam_s
+_wtof
+_wtof_l
+_wtoi
+_wtoi64
+_wtoi64_l
+_wtoi_l
+_wtol
+_wtol_l
+_wunlink
+_wutime
+_wutime32
+_wutime64
+_y0
+_y1
+_yn
+abort
+abs
+acos
+asctime
+asctime_s
+asin
+atan
+atan2
+atexit
+atof
+atoi
+atol
+bsearch
+bsearch_s
+btowc
+calloc
+ceil
+clearerr
+clearerr_s
+clock
+cos
+cosh
+ctime
+difftime
+div
+exit
+exp
+fabs
+fclose
+feof
+ferror
+fflush
+fgetc
+fgetpos
+fgets
+fgetwc
+fgetws
+floor
+fmod
+fopen
+fopen_s
+fprintf
+fprintf_s
+fputc
+fputs
+fputwc
+fputws
+fread
+free
+freopen
+freopen_s
+frexp
+fscanf
+fscanf_s
+fseek
+fsetpos
+ftell
+fwprintf
+fwprintf_s
+fwrite
+fwscanf
+fwscanf_s
+getc
+getchar
+getenv
+getenv_s
+gets
+getwc
+getwchar
+gmtime
+is_wctype
+isalnum
+isalpha
+iscntrl
+isdigit
+isgraph
+isleadbyte
+islower
+isprint
+ispunct
+isspace
+isupper
+iswalnum
+iswalpha
+iswascii
+iswcntrl
+iswctype
+iswdigit
+iswgraph
+iswlower
+iswprint
+iswpunct
+iswspace
+iswupper
+iswxdigit
+isxdigit
+labs
+ldexp
+ldiv
+localeconv
+localtime
+log
+log10
+longjmp
+malloc
+mblen
+mbrlen
+mbrtowc
+mbsdup_dbg
+mbsrtowcs
+mbsrtowcs_s
+mbstowcs
+mbstowcs_s
+mbtowc
+memchr
+memcmp
+memcpy
+memcpy_s
+memmove
+memmove_s
+memset
+mktime
+modf
+perror
+pow
+printf
+printf_s
+putc
+putchar
+puts
+putwc
+putwchar
+qsort
+qsort_s
+raise
+rand
+rand_s
+realloc
+remove
+rename
+rewind
+scanf
+scanf_s
+setbuf
+setlocale
+setvbuf
+signal
+sin
+sinh
+sprintf
+sprintf_s
+sqrt
+srand
+sscanf
+sscanf_s
+strcat
+strcat_s
+strchr
+strcmp
+strcoll
+strcpy
+strcpy_s
+strcspn
+strerror
+strerror_s
+strftime
+strlen
+strncat
+strncat_s
+strncmp
+strncpy
+strncpy_s
+strnlen
+strpbrk
+strrchr
+strspn
+strstr
+strtod
+strtok
+strtok_s
+strtol
+strtoul
+strxfrm
+swprintf
+swprintf_s
+swscanf
+swscanf_s
+system
+tan
+tanh
+time
+tmpfile
+tmpfile_s
+tmpnam
+tmpnam_s
+tolower
+toupper
+towlower
+towupper
+ungetc
+ungetwc
+utime
+vfprintf
+vfprintf_s
+vfwprintf
+vfwprintf_s
+vprintf
+vprintf_s
+vsnprintf
+vsprintf
+vsprintf_s
+vswprintf
+vswprintf_s
+vwprintf
+vwprintf_s
+wcrtomb
+wcrtomb_s
+wcscat
+wcscat_s
+wcschr
+wcscmp
+wcscoll
+wcscpy
+wcscpy_s
+wcscspn
+wcsftime
+wcslen
+wcsncat
+wcsncat_s
+wcsncmp
+wcsncpy
+wcsncpy_s
+wcsnlen
+wcspbrk
+wcsrchr
+wcsrtombs
+wcsrtombs_s
+wcsspn
+wcsstr
+wcstod
+wcstok
+wcstok_s
+wcstol
+wcstombs
+wcstombs_s
+wcstoul
+wcsxfrm
+wctob
+wctomb
+wctomb_s
+wprintf
+wprintf_s
+wscanf
+wscanf_s
diff --git a/win32/lib/user32.def b/win32/lib/user32.def
new file mode 100644
index 0000000..a034dac
--- /dev/null
+++ b/win32/lib/user32.def
@@ -0,0 +1,658 @@
+LIBRARY user32.dll
+
+EXPORTS
+ActivateKeyboardLayout
+AdjustWindowRect
+AdjustWindowRectEx
+AlignRects
+AllowSetForegroundWindow
+AnimateWindow
+AnyPopup
+AppendMenuA
+AppendMenuW
+ArrangeIconicWindows
+AttachThreadInput
+BeginDeferWindowPos
+BeginPaint
+BlockInput
+BringWindowToTop
+BroadcastSystemMessage
+BroadcastSystemMessageA
+BroadcastSystemMessageW
+CalcChildScroll
+CallMsgFilter
+CallMsgFilterA
+CallMsgFilterW
+CallNextHookEx
+CallWindowProcA
+CallWindowProcW
+CascadeChildWindows
+CascadeWindows
+ChangeClipboardChain
+ChangeDisplaySettingsA
+ChangeDisplaySettingsExA
+ChangeDisplaySettingsExW
+ChangeDisplaySettingsW
+ChangeMenuA
+ChangeMenuW
+CharLowerA
+CharLowerBuffA
+CharLowerBuffW
+CharLowerW
+CharNextA
+CharNextExA
+CharNextExW
+CharNextW
+CharPrevA
+CharPrevExA
+CharPrevExW
+CharPrevW
+CharToOemA
+CharToOemBuffA
+CharToOemBuffW
+CharToOemW
+CharUpperA
+CharUpperBuffA
+CharUpperBuffW
+CharUpperW
+CheckDlgButton
+CheckMenuItem
+CheckMenuRadioItem
+CheckRadioButton
+ChildWindowFromPoint
+ChildWindowFromPointEx
+ClientThreadConnect
+ClientToScreen
+ClipCursor
+CloseClipboard
+CloseDesktop
+CloseWindow
+CloseWindowStation
+CopyAcceleratorTableA
+CopyAcceleratorTableW
+CopyIcon
+CopyImage
+CopyRect
+CountClipboardFormats
+CreateAcceleratorTableA
+CreateAcceleratorTableW
+CreateCaret
+CreateCursor
+CreateDesktopA
+CreateDesktopW
+CreateDialogIndirectParamA
+CreateDialogIndirectParamW
+CreateDialogParamA
+CreateDialogParamW
+CreateIcon
+CreateIconFromResource
+CreateIconFromResourceEx
+CreateIconIndirect
+CreateMDIWindowA
+CreateMDIWindowW
+CreateMenu
+CreatePopupMenu
+CreateWindowExA
+CreateWindowExW
+CreateWindowStationA
+CreateWindowStationW
+DdeAbandonTransaction
+DdeAccessData
+DdeAddData
+DdeClientTransaction
+DdeCmpStringHandles
+DdeConnect
+DdeConnectList
+DdeCreateDataHandle
+DdeCreateStringHandleA
+DdeCreateStringHandleW
+DdeDisconnect
+DdeDisconnectList
+DdeEnableCallback
+DdeFreeDataHandle
+DdeFreeStringHandle
+DdeGetData
+DdeGetLastError
+DdeImpersonateClient
+DdeInitializeA
+DdeInitializeW
+DdeKeepStringHandle
+DdeNameService
+DdePostAdvise
+DdeQueryConvInfo
+DdeQueryNextServer
+DdeQueryStringA
+DdeQueryStringW
+DdeReconnect
+DdeSetQualityOfService
+DdeSetUserHandle
+DdeUnaccessData
+DdeUninitialize
+DefDlgProcA
+DefDlgProcW
+DefFrameProcA
+DefFrameProcW
+DefMDIChildProcA
+DefMDIChildProcW
+DefWindowProcA
+DefWindowProcW
+DeferWindowPos
+DeleteMenu
+DestroyAcceleratorTable
+DestroyCaret
+DestroyCursor
+DestroyIcon
+DestroyMenu
+DestroyWindow
+DialogBoxIndirectParamA
+DialogBoxIndirectParamW
+DialogBoxParamA
+DialogBoxParamW
+DispatchMessageA
+DispatchMessageW
+DlgDirListA
+DlgDirListComboBoxA
+DlgDirListComboBoxW
+DlgDirListW
+DlgDirSelectComboBoxExA
+DlgDirSelectComboBoxExW
+DlgDirSelectExA
+DlgDirSelectExW
+DragDetect
+DragObject
+DrawAnimatedRects
+DrawCaption
+DrawCaptionTempA
+DrawCaptionTempW
+DrawEdge
+DrawFocusRect
+DrawFrame
+DrawFrameControl
+DrawIcon
+DrawIconEx
+DrawMenuBar
+DrawMenuBarTemp
+DrawStateA
+DrawStateW
+DrawTextA
+DrawTextExA
+DrawTextExW
+DrawTextW
+EditWndProc
+EmptyClipboard
+EnableMenuItem
+EnableScrollBar
+EnableWindow
+EndDeferWindowPos
+EndDialog
+EndMenu
+EndPaint
+EndTask
+EnumChildWindows
+EnumClipboardFormats
+EnumDesktopWindows
+EnumDesktopsA
+EnumDesktopsW
+EnumDisplayDevicesA
+EnumDisplayDevicesW
+EnumDisplayMonitors
+EnumDisplaySettingsA
+EnumDisplaySettingsExA
+EnumDisplaySettingsExW
+EnumDisplaySettingsW
+EnumPropsA
+EnumPropsExA
+EnumPropsExW
+EnumPropsW
+EnumThreadWindows
+EnumWindowStationsA
+EnumWindowStationsW
+EnumWindows
+EqualRect
+ExcludeUpdateRgn
+ExitWindowsEx
+FillRect
+FindWindowA
+FindWindowExA
+FindWindowExW
+FindWindowW
+FlashWindow
+FlashWindowEx
+FrameRect
+FreeDDElParam
+GetActiveWindow
+GetAltTabInfo
+GetAncestor
+GetAsyncKeyState
+GetCapture
+GetCaretBlinkTime
+GetCaretPos
+GetClassInfoA
+GetClassInfoExA
+GetClassInfoExW
+GetClassInfoW
+GetClassLongA
+GetClassLongW
+GetClassNameA
+GetClassNameW
+GetClassWord
+GetClientRect
+GetClipCursor
+GetClipboardData
+GetClipboardFormatNameA
+GetClipboardFormatNameW
+GetClipboardOwner
+GetClipboardSequenceNumber
+GetClipboardViewer
+GetComboBoxInfo
+GetCursor
+GetCursorInfo
+GetCursorPos
+GetDC
+GetDCEx
+GetDesktopWindow
+GetDialogBaseUnits
+GetDlgCtrlID
+GetDlgItem
+GetDlgItemInt
+GetDlgItemTextA
+GetDlgItemTextW
+GetDoubleClickTime
+GetFocus
+GetForegroundWindow
+GetGUIThreadInfo
+GetGuiResources
+GetIconInfo
+GetInputDesktop
+GetInputState
+GetInternalWindowPos
+GetKBCodePage
+GetKeyNameTextA
+GetKeyNameTextW
+GetKeyState
+GetKeyboardLayout
+GetKeyboardLayoutList
+GetKeyboardLayoutNameA
+GetKeyboardLayoutNameW
+GetKeyboardState
+GetKeyboardType
+GetLastActivePopup
+GetListBoxInfo
+GetMenu
+GetMenuBarInfo
+GetMenuCheckMarkDimensions
+GetMenuContextHelpId
+GetMenuDefaultItem
+GetMenuInfo
+GetMenuItemCount
+GetMenuItemID
+GetMenuItemInfoA
+GetMenuItemInfoW
+GetMenuItemRect
+GetMenuState
+GetMenuStringA
+GetMenuStringW
+GetMessageA
+GetMessageExtraInfo
+GetMessagePos
+GetMessageTime
+GetMessageW
+GetMonitorInfoA
+GetMonitorInfoW
+GetMouseMovePoints
+GetMouseMovePointsEx
+GetNextDlgGroupItem
+GetNextDlgTabItem
+GetNextQueueWindow
+GetOpenClipboardWindow
+GetParent
+GetPriorityClipboardFormat
+GetProcessDefaultLayout
+GetProcessWindowStation
+GetPropA
+GetPropW
+GetQueueStatus
+GetScrollBarInfo
+GetScrollInfo
+GetScrollPos
+GetScrollRange
+GetShellWindow
+GetSubMenu
+GetSysColor
+GetSysColorBrush
+GetSystemMenu
+GetSystemMetrics
+GetTabbedTextExtentA
+GetTabbedTextExtentW
+GetThreadDesktop
+GetTitleBarInfo
+GetTopWindow
+GetUpdateRect
+GetUpdateRgn
+GetUserObjectInformationA
+GetUserObjectInformationW
+GetUserObjectSecurity
+GetWindow
+GetWindowContextHelpId
+GetWindowDC
+GetWindowInfo
+GetWindowLongPtrA
+GetWindowLongPtrW
+SetWindowLongPtrA
+SetWindowLongPtrW
+GetWindowLongA
+GetWindowLongW
+GetWindowModuleFileNameA
+GetWindowModuleFileNameW
+GetWindowPlacement
+GetWindowRect
+GetWindowRgn
+GetWindowTextA
+GetWindowTextLengthA
+GetWindowTextLengthW
+GetWindowTextW
+GetWindowThreadProcessId
+GetWindowWord
+GrayStringA
+GrayStringW
+HasSystemSleepStarted
+HideCaret
+HiliteMenuItem
+IMPGetIMEA
+IMPGetIMEW
+IMPQueryIMEA
+IMPQueryIMEW
+IMPSetIMEA
+IMPSetIMEW
+ImpersonateDdeClientWindow
+InSendMessage
+InSendMessageEx
+InflateRect
+InitSharedTable
+InitTask
+InsertMenuA
+InsertMenuItemA
+InsertMenuItemW
+InsertMenuW
+InternalGetWindowText
+IntersectRect
+InvalidateRect
+InvalidateRgn
+InvertRect
+IsCharAlphaA
+IsCharAlphaNumericA
+IsCharAlphaNumericW
+IsCharAlphaW
+IsCharLowerA
+IsCharLowerW
+IsCharUpperA
+IsCharUpperW
+IsChild
+IsClipboardFormatAvailable
+IsDialogMessage
+IsDialogMessageA
+IsDialogMessageW
+IsDlgButtonChecked
+IsHungThread
+IsIconic
+IsMenu
+IsRectEmpty
+IsWindow
+IsWindowEnabled
+IsWindowUnicode
+IsWindowVisible
+IsZoomed
+KillTimer
+LoadAcceleratorsA
+LoadAcceleratorsW
+LoadBitmapA
+LoadBitmapW
+LoadCursorA
+LoadCursorFromFileA
+LoadCursorFromFileW
+LoadCursorW
+LoadIconA
+LoadIconW
+LoadImageA
+LoadImageW
+LoadKeyboardLayoutA
+LoadKeyboardLayoutW
+LoadMenuA
+LoadMenuIndirectA
+LoadMenuIndirectW
+LoadMenuW
+LoadStringA
+LoadStringW
+LockSetForegroundWindow
+LockWindowStation
+LockWindowUpdate
+LookupIconIdFromDirectory
+LookupIconIdFromDirectoryEx
+MapDialogRect
+MapVirtualKeyA
+MapVirtualKeyExA
+MapVirtualKeyExW
+MapVirtualKeyW
+MapWindowPoints
+MenuItemFromPoint
+MessageBeep
+MessageBoxA
+MessageBoxExA
+MessageBoxExW
+MessageBoxIndirectA
+MessageBoxIndirectW
+MessageBoxW
+ModifyAccess
+ModifyMenuA
+ModifyMenuW
+MonitorFromPoint
+MonitorFromRect
+MonitorFromWindow
+MoveWindow
+MsgWaitForMultipleObjects
+MsgWaitForMultipleObjectsEx
+NotifyWinEvent
+OemKeyScan
+OemToCharA
+OemToCharBuffA
+OemToCharBuffW
+OemToCharW
+OffsetRect
+OpenClipboard
+OpenDesktopA
+OpenDesktopW
+OpenIcon
+OpenInputDesktop
+OpenWindowStationA
+OpenWindowStationW
+PackDDElParam
+PaintDesktop
+PeekMessageA
+PeekMessageW
+PlaySoundEvent
+PostMessageA
+PostMessageW
+PostQuitMessage
+PostThreadMessageA
+PostThreadMessageW
+PtInRect
+RealChildWindowFromPoint
+RealGetWindowClass
+RedrawWindow
+RegisterClassA
+RegisterClassExA
+RegisterClassExW
+RegisterClassW
+RegisterClipboardFormatA
+RegisterClipboardFormatW
+RegisterDeviceNotificationA
+RegisterDeviceNotificationW
+RegisterHotKey
+RegisterLogonProcess
+RegisterNetworkCapabilities
+RegisterSystemThread
+RegisterTasklist
+RegisterWindowMessageA
+RegisterWindowMessageW
+ReleaseCapture
+ReleaseDC
+RemoveMenu
+RemovePropA
+RemovePropW
+ReplyMessage
+ReuseDDElParam
+ScreenToClient
+ScrollDC
+ScrollWindow
+ScrollWindowEx
+SendDlgItemMessageA
+SendDlgItemMessageW
+SendIMEMessageExA
+SendIMEMessageExW
+SendInput
+SendMessageA
+SendMessageCallbackA
+SendMessageCallbackW
+SendMessageTimeoutA
+SendMessageTimeoutW
+SendMessageW
+SendNotifyMessageA
+SendNotifyMessageW
+SetActiveWindow
+SetCapture
+SetCaretBlinkTime
+SetCaretPos
+SetClassLongA
+SetClassLongW
+SetClassWord
+SetClipboardData
+SetClipboardViewer
+SetCursor
+SetCursorPos
+SetDebugErrorLevel
+SetDeskWallpaper
+SetDesktopBitmap
+SetDlgItemInt
+SetDlgItemTextA
+SetDlgItemTextW
+SetDoubleClickTime
+SetFocus
+SetForegroundWindow
+SetInternalWindowPos
+SetKeyboardState
+SetLastErrorEx
+SetLogonNotifyWindow
+SetMenu
+SetMenuContextHelpId
+SetMenuDefaultItem
+SetMenuInfo
+SetMenuItemBitmaps
+SetMenuItemInfoA
+SetMenuItemInfoW
+SetMessageExtraInfo
+SetMessageQueue
+SetParent
+SetProcessDefaultLayout
+SetProcessWindowStation
+SetPropA
+SetPropW
+SetRect
+SetRectEmpty
+SetScrollInfo
+SetScrollPos
+SetScrollRange
+SetShellWindow
+SetSysColors
+SetSysColorsTemp
+SetSystemCursor
+SetThreadDesktop
+SetTimer
+SetUserObjectInformationA
+SetUserObjectInformationW
+SetUserObjectSecurity
+SetWinEventHook
+SetWindowContextHelpId
+SetWindowFullScreenState
+SetWindowLongA
+SetWindowLongW
+SetWindowPlacement
+SetWindowPos
+SetWindowRgn
+SetWindowTextA
+SetWindowTextW
+SetWindowWord
+SetWindowsHookA
+SetWindowsHookExA
+SetWindowsHookExW
+SetWindowsHookW
+ShowCaret
+ShowCursor
+ShowOwnedPopups
+ShowScrollBar
+ShowWindow
+ShowWindowAsync
+SubtractRect
+SwapMouseButton
+SwitchDesktop
+SwitchToThisWindow
+SysErrorBox
+SystemParametersInfoA
+SystemParametersInfoW
+TabbedTextOutA
+TabbedTextOutW
+TileChildWindows
+TileWindows
+ToAscii
+ToAsciiEx
+ToUnicode
+ToUnicodeEx
+TrackMouseEvent
+TrackPopupMenu
+TrackPopupMenuEx
+TranslateAccelerator
+TranslateAcceleratorA
+TranslateAcceleratorW
+TranslateMDISysAccel
+TranslateMessage
+UnhookWinEvent
+UnhookWindowsHook
+UnhookWindowsHookEx
+UnionRect
+UnloadKeyboardLayout
+UnlockWindowStation
+UnpackDDElParam
+UnregisterClassA
+UnregisterClassW
+UnregisterDeviceNotification
+UnregisterHotKey
+UpdateWindow
+UserClientDllInitialize
+UserIsSystemResumeAutomatic
+UserSetDeviceHoldState
+UserSignalProc
+UserTickleTimer
+ValidateRect
+ValidateRgn
+VkKeyScanA
+VkKeyScanExA
+VkKeyScanExW
+VkKeyScanW
+WINNLSEnableIME
+WINNLSGetEnableStatus
+WINNLSGetIMEHotkey
+WNDPROC_CALLBACK
+WaitForInputIdle
+WaitMessage
+WinHelpA
+WinHelpW
+WinOldAppHackoMatic
+WindowFromDC
+WindowFromPoint
+YieldTask
+_SetProcessDefaultLayout
+keybd_event
+mouse_event
+wsprintfA
+wsprintfW
+wvsprintfA
+wvsprintfW
diff --git a/win32/lib/wincrt1.c b/win32/lib/wincrt1.c
new file mode 100644
index 0000000..ce3a63f
--- /dev/null
+++ b/win32/lib/wincrt1.c
@@ -0,0 +1,75 @@
+//+---------------------------------------------------------------------------
+
+// _UNICODE for tchar.h, UNICODE for API
+#include <tchar.h>
+
+#include <windows.h>
+#include <stdlib.h>
+
+#define __UNKNOWN_APP 0
+#define __CONSOLE_APP 1
+#define __GUI_APP 2
+void __set_app_type(int);
+void _controlfp(unsigned a, unsigned b);
+
+#ifdef _UNICODE
+#define __tgetmainargs __wgetmainargs
+#define _twinstart _wwinstart
+#define _runtwinmain _runwwinmain
+int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
+#else
+#define __tgetmainargs __getmainargs
+#define _twinstart _winstart
+#define _runtwinmain _runwinmain
+#endif
+
+typedef struct { int newmode; } _startupinfo;
+int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*);
+
+static int go_winmain(TCHAR *arg1)
+{
+ STARTUPINFO si;
+ _TCHAR *szCmd, *p;
+ int fShow;
+
+ GetStartupInfo(&si);
+ if (si.dwFlags & STARTF_USESHOWWINDOW)
+ fShow = si.wShowWindow;
+ else
+ fShow = SW_SHOWDEFAULT;
+
+ szCmd = NULL, p = GetCommandLine();
+ if (arg1)
+ szCmd = _tcsstr(p, arg1);
+ if (NULL == szCmd)
+ szCmd = _tcsdup(__T(""));
+ else if (szCmd > p && szCmd[-1] == __T('"'))
+ --szCmd;
+#if defined __i386__ || defined __x86_64__
+ _controlfp(0x10000, 0x30000);
+#endif
+ return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow);
+}
+
+int _twinstart(void)
+{
+ __TRY__
+ _startupinfo start_info_con = {0};
+ __set_app_type(__GUI_APP);
+ __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info_con);
+ exit(go_winmain(__argc > 1 ? __targv[1] : NULL));
+}
+
+int _runtwinmain(int argc, /* as tcc passed in */ char **argv)
+{
+#ifdef UNICODE
+ _startupinfo start_info = {0};
+ __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info);
+ /* may be wrong when tcc has received wildcards (*.c) */
+ if (argc < __argc)
+ __targv += __argc - argc, __argc = argc;
+#else
+ __argc = argc, __targv = argv;
+#endif
+ return go_winmain(__argc > 1 ? __targv[1] : NULL);
+}
diff --git a/win32/lib/wincrt1w.c b/win32/lib/wincrt1w.c
new file mode 100644
index 0000000..a7d349e
--- /dev/null
+++ b/win32/lib/wincrt1w.c
@@ -0,0 +1,3 @@
+#define _UNICODE 1
+#define UNICODE 1
+#include "wincrt1.c"
diff --git a/win32/tcc-win32.txt b/win32/tcc-win32.txt
new file mode 100644
index 0000000..ab73007
--- /dev/null
+++ b/win32/tcc-win32.txt
@@ -0,0 +1,168 @@
+
+ TinyCC
+ ======
+
+ This file contains specific information for usage of TinyCC
+ under MS-Windows. See tcc-doc.html to have all the features.
+
+
+ Installation from the binary ZIP package:
+ -----------------------------------------
+ Unzip the package to a directory of your choice.
+
+
+ Set the system PATH:
+ --------------------
+ To be able to invoke the compiler from everywhere on your computer by
+ just typing "tcc", please add the directory containing tcc.exe to your
+ system PATH.
+
+
+ Include and library search paths
+ --------------------------------
+ On windows, the standard "include" and "lib" directories are searched
+ relatively from the location of the executables (tcc.exe, libtcc.dll).
+
+
+ Examples:
+ ---------
+ Open a console window (DOS box) and 'cd' to the examples directory.
+
+ For the 'Fibonacci' example type:
+
+ tcc fib.c
+
+ For the 'Hello Windows' GUI example type:
+
+ tcc hello_win.c
+
+ For the 'Hello DLL' example type
+
+ tcc -shared dll.c
+ tcc -impdef dll.dll (optional)
+ tcc hello_dll.c dll.def
+
+
+ Using libtcc as JIT compiler in your program
+ --------------------------------------------
+ Check out the 'libtcc_test' example:
+
+ - Running it from source:
+ tcc -I libtcc libtcc/libtcc.def -run examples/libtcc_test.c
+
+ - Compiling with TCC:
+ tcc examples/libtcc_test.c -I libtcc libtcc/libtcc.def
+
+ - Compiling with MinGW:
+ gcc examples/libtcc_test.c -I libtcc libtcc.dll -o libtcc_test.exe
+
+ - Compiling with MSVC:
+ lib /def:libtcc\libtcc.def /out:libtcc.lib
+ cl /MD examples/libtcc_test.c -I libtcc libtcc.lib
+
+
+ Import Definition Files:
+ ------------------------
+ To link with Windows system DLLs, TCC uses import definition
+ files (.def) instead of libraries.
+
+ The now built-in 'tiny_impdef' program may be used to make
+ additional .def files for any DLL. For example
+
+ tcc -impdef [-v] opengl32.dll [-o opengl32.def]
+
+ Put opengl32.def into the tcc/lib directory. Specify -lopengl32 at
+ the TCC commandline to link a program that uses opengl32.dll.
+
+
+ Header Files:
+ -------------
+ The system header files (except _mingw.h) are from the MinGW
+ distribution:
+
+ http://www.mingw.org/
+
+ From the windows headers, only a minimal set is included. If you need
+ more, get MinGW's "w32api" package. Extract the files from "include"
+ into your "tcc/include/winapi" directory.
+
+
+ Resource Files:
+ ---------------
+ TCC can link windows resources in coff format as generated by MinGW's
+ windres.exe. For example:
+
+ windres -O coff app.rc -o appres.o
+ tcc app.c appres.o -o app.exe
+
+
+ Tiny Libmaker:
+ --------------
+ The now built-in tiny_libmaker tool by Timovj Lahde can be used as
+ 'ar' replacement to make a library from several object files:
+
+ tcc -ar [rcsv] library objectfiles ...
+
+
+ Compilation from source:
+ ------------------------
+ * You can use the MinGW and MSYS tools available at
+ http://www.mingw.org
+ http://www.mingw-w64.org
+ http://www.msys2.org
+
+ Untar the TCC archive and type in the MSYS shell:
+ ./configure [--prefix installpath]
+ make
+ make install
+
+ The default install location is c:\Program Files\tcc
+
+ Cygwin can be used too with its mingw cross-compiler installed:
+ ./configure --cross-prefix=i686-w64-mingw32-
+ (the prefix may vary)
+
+ * Alternatively you can compile TCC with just GCC from MinGW using
+ > build-tcc.bat (from the win32 directory)
+
+ Also MSVC can be used with the "VSTools Developer Command Prompt":
+ > build-tcc.bat -c cl
+
+ or with an existing tcc (needs to be in a different directory)
+ > build-tcc.bat -c some-tcc-dir\tcc.exe
+
+ Also you can copy/install everything into another directory:
+ > build-tcc.bat -i <dir>
+
+ Limitations:
+ ------------
+ - On the object file level, currently TCC supports only the ELF format,
+ not COFF as used by MinGW and MSVC. It is not possible to exchange
+ object files or libraries between TCC and these compilers.
+
+ However libraries for TCC from objects by TCC can be made using
+ tcc -ar lib.a files.o ,,,
+
+ - No leading underscore is generated in the ELF symbols.
+
+ Documentation and License:
+ --------------------------
+ TCC is distributed under the GNU Lesser General Public License. (See
+ COPYING file or http://www.gnu.org/licenses/lgpl-2.1.html)
+
+ TinyCC homepage is at:
+
+ http://fabrice.bellard.free.fr/tcc/
+
+
+ WinAPI Help and 3rd-party tools:
+ --------------------------------
+ The Windows API documentation (Win95) in a single .hlp file is
+ available on the lcc-win32 site as "win32hlp.exe" or from other
+ locations as "win32hlp_big.zip".
+
+ A nice RAD tool to create windows resources (dialog boxes etc.) is
+ "ResEd", available at the RadASM website.
+
+
+ --- grischka
diff --git a/x86_64-asm.h b/x86_64-asm.h
new file mode 100644
index 0000000..cb9eb16
--- /dev/null
+++ b/x86_64-asm.h
@@ -0,0 +1,525 @@
+ DEF_ASM_OP0(clc, 0xf8) /* must be first OP0 */
+ DEF_ASM_OP0(cld, 0xfc)
+ DEF_ASM_OP0(cli, 0xfa)
+ DEF_ASM_OP0(clts, 0x0f06)
+ DEF_ASM_OP0(cmc, 0xf5)
+ DEF_ASM_OP0(lahf, 0x9f)
+ DEF_ASM_OP0(sahf, 0x9e)
+ DEF_ASM_OP0(pushfq, 0x9c)
+ DEF_ASM_OP0(popfq, 0x9d)
+ DEF_ASM_OP0(pushf, 0x9c)
+ DEF_ASM_OP0(popf, 0x9d)
+ DEF_ASM_OP0(stc, 0xf9)
+ DEF_ASM_OP0(std, 0xfd)
+ DEF_ASM_OP0(sti, 0xfb)
+ DEF_ASM_OP0(aaa, 0x37)
+ DEF_ASM_OP0(aas, 0x3f)
+ DEF_ASM_OP0(daa, 0x27)
+ DEF_ASM_OP0(das, 0x2f)
+ DEF_ASM_OP0(aad, 0xd50a)
+ DEF_ASM_OP0(aam, 0xd40a)
+ DEF_ASM_OP0(cbw, 0x6698)
+ DEF_ASM_OP0(cwd, 0x6699)
+ DEF_ASM_OP0(cwde, 0x98)
+ DEF_ASM_OP0(cdq, 0x99)
+ DEF_ASM_OP0(cbtw, 0x6698)
+ DEF_ASM_OP0(cwtl, 0x98)
+ DEF_ASM_OP0(cwtd, 0x6699)
+ DEF_ASM_OP0(cltd, 0x99)
+ DEF_ASM_OP0(cqto, 0x4899)
+ DEF_ASM_OP0(int3, 0xcc)
+ DEF_ASM_OP0(into, 0xce)
+ DEF_ASM_OP0(iret, 0xcf)
+ DEF_ASM_OP0(rsm, 0x0faa)
+ DEF_ASM_OP0(hlt, 0xf4)
+ DEF_ASM_OP0(wait, 0x9b)
+ DEF_ASM_OP0(nop, 0x90)
+ DEF_ASM_OP0(pause, 0xf390)
+ DEF_ASM_OP0(xlat, 0xd7)
+
+ /* strings */
+ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
+
+ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLX))
+
+ /* bits */
+
+ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+
+ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ /* prefixes */
+ DEF_ASM_OP0(lock, 0xf0)
+ DEF_ASM_OP0(rep, 0xf3)
+ DEF_ASM_OP0(repe, 0xf3)
+ DEF_ASM_OP0(repz, 0xf3)
+ DEF_ASM_OP0(repne, 0xf2)
+ DEF_ASM_OP0(repnz, 0xf2)
+
+ DEF_ASM_OP0(invd, 0x0f08)
+ DEF_ASM_OP0(wbinvd, 0x0f09)
+ DEF_ASM_OP0(cpuid, 0x0fa2)
+ DEF_ASM_OP0(wrmsr, 0x0f30)
+ DEF_ASM_OP0(rdtsc, 0x0f31)
+ DEF_ASM_OP0(rdmsr, 0x0f32)
+ DEF_ASM_OP0(rdpmc, 0x0f33)
+
+ DEF_ASM_OP0(syscall, 0x0f05)
+ DEF_ASM_OP0(sysret, 0x0f07)
+ DEF_ASM_OP0L(sysretq, 0x480f07, 0, 0)
+ DEF_ASM_OP0(ud2, 0x0f0b)
+
+ /* NOTE: we took the same order as gas opcode definition order */
+/* Right now we can't express the fact that 0xa1/0xa3 can't use $eax and a
+ 32 bit moffset as operands.
+ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLX, OPT_ADDR, OPT_EAX))
+ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLX, OPT_EAX, OPT_ADDR)) */
+ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+/* The moves are special: the 0xb8 form supports IM64 (the only insn that
+ does) with REG64. It doesn't support IM32 with REG64, it would use
+ the full movabs form (64bit immediate). For IM32->REG64 we prefer
+ the 0xc7 opcode. So disallow all 64bit forms and code the rest by hand. */
+ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLX, OPT_IM, OPT_REG))
+ALT(DEF_ASM_OP2(mov, 0xb8, 0, OPC_REG, OPT_IM64, OPT_REG64))
+ALT(DEF_ASM_OP2(movq, 0xb8, 0, OPC_REG, OPT_IM64, OPT_REG64))
+ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLX, OPT_SEG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_SEG))
+
+ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLX, OPT_CR, OPT_REG64))
+ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLX, OPT_DB, OPT_REG64))
+ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLX, OPT_REG64, OPT_CR))
+ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLX, OPT_REG64, OPT_DB))
+
+ALT(DEF_ASM_OP2(movsbw, 0x660fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG16))
+ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movsbq, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movswq, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP2(movslq, 0x63, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WLX, OPT_REG8 | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movzwq, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG))
+
+ALT(DEF_ASM_OP1(pushq, 0x6a, 0, 0, OPT_IM8S))
+ALT(DEF_ASM_OP1(push, 0x6a, 0, 0, OPT_IM8S))
+ALT(DEF_ASM_OP1(pushw, 0x666a, 0, 0, OPT_IM8S))
+ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REG64))
+ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REG16))
+ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLX, OPT_REG64 | OPT_EA))
+ALT(DEF_ASM_OP1(pushw, 0x6668, 0, 0, OPT_IM16))
+ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLX, OPT_IM32))
+ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REG64))
+ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REG16))
+ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_REGW, OPT_EAX))
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_EAX, OPT_REGW))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+
+ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
+ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
+ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
+ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
+
+ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
+ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
+ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
+ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
+
+ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLX, OPT_EA, OPT_REG))
+
+ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+
+ /* arith */
+ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
+ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW))
+ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW))
+
+ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
+ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
+
+ /* shifts */
+ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
+
+ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
+ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP))
+ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
+ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8))
+
+ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA))
+ DEF_ASM_OP1(ljmpw, 0x66ff, 5, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(ljmpl, 0xff, 5, OPC_MODRM, OPT_EA)
+
+ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
+ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
+ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
+ DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
+ DEF_ASM_OP0(leave, 0xc9)
+ DEF_ASM_OP0(ret, 0xc3)
+ DEF_ASM_OP0(retq, 0xc3)
+ALT(DEF_ASM_OP1(retq, 0xc2, 0, 0, OPT_IM16))
+ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
+ DEF_ASM_OP0(lret, 0xcb)
+ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
+
+ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8))
+ DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8)
+ DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8)
+ DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8)
+ DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8)
+ DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8)
+ DEF_ASM_OP1(jecxz, 0x67e3, 0, 0, OPT_DISP8)
+
+ /* float */
+ /* specific fcomp handling */
+ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
+
+ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
+ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
+ALT(DEF_ASM_OP2(fadd, 0xdcc0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP2(fmul, 0xdcc8, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
+ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
+ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
+ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
+ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+
+ DEF_ASM_OP0(fucompp, 0xdae9)
+ DEF_ASM_OP0(ftst, 0xd9e4)
+ DEF_ASM_OP0(fxam, 0xd9e5)
+ DEF_ASM_OP0(fld1, 0xd9e8)
+ DEF_ASM_OP0(fldl2t, 0xd9e9)
+ DEF_ASM_OP0(fldl2e, 0xd9ea)
+ DEF_ASM_OP0(fldpi, 0xd9eb)
+ DEF_ASM_OP0(fldlg2, 0xd9ec)
+ DEF_ASM_OP0(fldln2, 0xd9ed)
+ DEF_ASM_OP0(fldz, 0xd9ee)
+
+ DEF_ASM_OP0(f2xm1, 0xd9f0)
+ DEF_ASM_OP0(fyl2x, 0xd9f1)
+ DEF_ASM_OP0(fptan, 0xd9f2)
+ DEF_ASM_OP0(fpatan, 0xd9f3)
+ DEF_ASM_OP0(fxtract, 0xd9f4)
+ DEF_ASM_OP0(fprem1, 0xd9f5)
+ DEF_ASM_OP0(fdecstp, 0xd9f6)
+ DEF_ASM_OP0(fincstp, 0xd9f7)
+ DEF_ASM_OP0(fprem, 0xd9f8)
+ DEF_ASM_OP0(fyl2xp1, 0xd9f9)
+ DEF_ASM_OP0(fsqrt, 0xd9fa)
+ DEF_ASM_OP0(fsincos, 0xd9fb)
+ DEF_ASM_OP0(frndint, 0xd9fc)
+ DEF_ASM_OP0(fscale, 0xd9fd)
+ DEF_ASM_OP0(fsin, 0xd9fe)
+ DEF_ASM_OP0(fcos, 0xd9ff)
+ DEF_ASM_OP0(fchs, 0xd9e0)
+ DEF_ASM_OP0(fabs, 0xd9e1)
+ DEF_ASM_OP0(fninit, 0xdbe3)
+ DEF_ASM_OP0(fnclex, 0xdbe2)
+ DEF_ASM_OP0(fnop, 0xd9d0)
+ DEF_ASM_OP0(fwait, 0x9b)
+
+ /* fp load */
+ DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
+ DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
+ DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
+ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
+ DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
+ DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
+
+ /* fp store */
+ DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
+ DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
+ DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
+ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
+ DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
+
+ DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
+ DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
+
+ /* exchange */
+ DEF_ASM_OP0(fxch, 0xd9c9)
+ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
+
+ /* misc FPU */
+ DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
+ DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
+
+ DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
+ DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
+ DEF_ASM_OP0(fnstsw, 0xdfe0)
+ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
+ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
+ DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
+ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
+ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
+ DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
+ DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
+ DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
+ DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
+ DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
+ DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
+ DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
+ /* The *q forms of fxrstor/fxsave use a REX prefix.
+ If the operand would use extended registers we would have to modify
+ it instead of generating a second one. Currently that's no
+ problem with TCC, we don't use extended registers. */
+ DEF_ASM_OP1(fxsaveq, 0x0fae, 0, OPC_MODRM | OPC_48, OPT_EA )
+ DEF_ASM_OP1(fxrstorq, 0x0fae, 1, OPC_MODRM | OPC_48, OPT_EA )
+
+ /* segments */
+ DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
+ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
+ DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(lgdtq, 0x0f01, 2, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(lidtq, 0x0f01, 3, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
+ DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
+ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_REG))
+ DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG16)
+ DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(sgdtq, 0x0f01, 0, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(sidtq, 0x0f01, 1, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
+ DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
+ DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG32 | OPT_EA)
+ALT(DEF_ASM_OP1(str, 0x660f00, 1, OPC_MODRM, OPT_REG16))
+ALT(DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM | OPC_48, OPT_REG64))
+ DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
+ DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
+ DEF_ASM_OP0L(swapgs, 0x0f01, 7, OPC_MODRM)
+
+ /* 486 */
+ /* bswap can't be applied to 16bit regs */
+ DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
+ DEF_ASM_OP1(bswapl, 0x0fc8, 0, OPC_REG, OPT_REG32 )
+ DEF_ASM_OP1(bswapq, 0x0fc8, 0, OPC_REG | OPC_48, OPT_REG64 )
+
+ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
+ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
+ DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
+
+ /* pentium */
+ DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
+
+ /* AMD 64 */
+ DEF_ASM_OP1(cmpxchg16b, 0x0fc7, 1, OPC_MODRM | OPC_48, OPT_EA )
+
+ /* pentium pro */
+ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+
+ DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+
+ DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+ DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+
+ /* mmx */
+ DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
+ DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMXSSE )
+ /* movd shouldn't accept REG64, but AMD64 spec uses it for 32 and 64 bit
+ moves, so let's be compatible. */
+ALT(DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG64, OPT_MMXSSE ))
+ALT(DEF_ASM_OP2(movq, 0x0f6e, 0, OPC_MODRM | OPC_48, OPT_REG64, OPT_MMXSSE ))
+ALT(DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ))
+ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG32 ))
+ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG64 ))
+ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
+ALT(DEF_ASM_OP2(movq, 0x660fd6, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_SSE ))
+ALT(DEF_ASM_OP2(movq, 0xf30f7e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ))
+ALT(DEF_ASM_OP2(movq, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG64 ))
+
+ DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+ DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+
+ /* sse */
+ DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+ DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+ DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+ DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE )
+ DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+ DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+ DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+ DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+
+ DEF_ASM_OP1(prefetchnta, 0x0f18, 0, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(prefetcht0, 0x0f18, 1, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(prefetcht1, 0x0f18, 2, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(prefetcht2, 0x0f18, 3, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP1(prefetchw, 0x0f0d, 1, OPC_MODRM, OPT_EA)
+ DEF_ASM_OP0L(lfence, 0x0fae, 5, OPC_MODRM)
+ DEF_ASM_OP0L(mfence, 0x0fae, 6, OPC_MODRM)
+ DEF_ASM_OP0L(sfence, 0x0fae, 7, OPC_MODRM)
+ DEF_ASM_OP1(clflush, 0x0fae, 7, OPC_MODRM, OPT_EA)
+#undef ALT
+#undef DEF_ASM_OP0
+#undef DEF_ASM_OP0L
+#undef DEF_ASM_OP1
+#undef DEF_ASM_OP2
+#undef DEF_ASM_OP3
diff --git a/x86_64-gen.c b/x86_64-gen.c
new file mode 100644
index 0000000..e33a38a
--- /dev/null
+++ b/x86_64-gen.c
@@ -0,0 +1,2258 @@
+/*
+ * x86-64 code generator for TCC
+ *
+ * Copyright (c) 2008 Shinichiro Hamaji
+ *
+ * Based on i386-gen.c by Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+/* number of available registers */
+#define NB_REGS 25
+#define NB_ASM_REGS 16
+#define CONFIG_TCC_ASM
+
+/* a register can belong to several classes. The classes must be
+ sorted from more general to more precise (see gv2() code which does
+ assumptions on it). */
+#define RC_INT 0x0001 /* generic integer register */
+#define RC_FLOAT 0x0002 /* generic float register */
+#define RC_RAX 0x0004
+#define RC_RCX 0x0008
+#define RC_RDX 0x0010
+#define RC_ST0 0x0080 /* only for long double */
+#define RC_R8 0x0100
+#define RC_R9 0x0200
+#define RC_R10 0x0400
+#define RC_R11 0x0800
+#define RC_XMM0 0x1000
+#define RC_XMM1 0x2000
+#define RC_XMM2 0x4000
+#define RC_XMM3 0x8000
+#define RC_XMM4 0x10000
+#define RC_XMM5 0x20000
+#define RC_XMM6 0x40000
+#define RC_XMM7 0x80000
+#define RC_IRET RC_RAX /* function return: integer register */
+#define RC_LRET RC_RDX /* function return: second integer register */
+#define RC_FRET RC_XMM0 /* function return: float register */
+#define RC_QRET RC_XMM1 /* function return: second float register */
+
+/* pretty names for the registers */
+enum {
+ TREG_RAX = 0,
+ TREG_RCX = 1,
+ TREG_RDX = 2,
+ TREG_RSP = 4,
+ TREG_RSI = 6,
+ TREG_RDI = 7,
+
+ TREG_R8 = 8,
+ TREG_R9 = 9,
+ TREG_R10 = 10,
+ TREG_R11 = 11,
+
+ TREG_XMM0 = 16,
+ TREG_XMM1 = 17,
+ TREG_XMM2 = 18,
+ TREG_XMM3 = 19,
+ TREG_XMM4 = 20,
+ TREG_XMM5 = 21,
+ TREG_XMM6 = 22,
+ TREG_XMM7 = 23,
+
+ TREG_ST0 = 24,
+
+ TREG_MEM = 0x20
+};
+
+#define REX_BASE(reg) (((reg) >> 3) & 1)
+#define REG_VALUE(reg) ((reg) & 7)
+
+/* return registers for function */
+#define REG_IRET TREG_RAX /* single word int return register */
+#define REG_LRET TREG_RDX /* second word return register (for long long) */
+#define REG_FRET TREG_XMM0 /* float return register */
+#define REG_QRET TREG_XMM1 /* second float return register */
+
+/* defined if function parameters must be evaluated in reverse order */
+#define INVERT_FUNC_PARAMS
+
+/* pointer size, in bytes */
+#define PTR_SIZE 8
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE 16
+#define LDOUBLE_ALIGN 16
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN 16
+
+/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+#include <assert.h>
+
+ST_DATA const int reg_classes[NB_REGS] = {
+ /* eax */ RC_INT | RC_RAX,
+ /* ecx */ RC_INT | RC_RCX,
+ /* edx */ RC_INT | RC_RDX,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ RC_R8,
+ RC_R9,
+ RC_R10,
+ RC_R11,
+ 0,
+ 0,
+ 0,
+ 0,
+ /* xmm0 */ RC_FLOAT | RC_XMM0,
+ /* xmm1 */ RC_FLOAT | RC_XMM1,
+ /* xmm2 */ RC_FLOAT | RC_XMM2,
+ /* xmm3 */ RC_FLOAT | RC_XMM3,
+ /* xmm4 */ RC_FLOAT | RC_XMM4,
+ /* xmm5 */ RC_FLOAT | RC_XMM5,
+ /* xmm6 an xmm7 are included so gv() can be used on them,
+ but they are not tagged with RC_FLOAT because they are
+ callee saved on Windows */
+ RC_XMM6,
+ RC_XMM7,
+ /* st0 */ RC_ST0
+};
+
+static unsigned long func_sub_sp_offset;
+static int func_ret_sub;
+
+/* XXX: make it faster ? */
+ST_FUNC void g(int c)
+{
+ int ind1;
+ if (nocode_wanted)
+ return;
+ ind1 = ind + 1;
+ if (ind1 > cur_text_section->data_allocated)
+ section_realloc(cur_text_section, ind1);
+ cur_text_section->data[ind] = c;
+ ind = ind1;
+}
+
+ST_FUNC void o(unsigned int c)
+{
+ while (c) {
+ g(c);
+ c = c >> 8;
+ }
+}
+
+ST_FUNC void gen_le16(int v)
+{
+ g(v);
+ g(v >> 8);
+}
+
+ST_FUNC void gen_le32(int c)
+{
+ g(c);
+ g(c >> 8);
+ g(c >> 16);
+ g(c >> 24);
+}
+
+ST_FUNC void gen_le64(int64_t c)
+{
+ g(c);
+ g(c >> 8);
+ g(c >> 16);
+ g(c >> 24);
+ g(c >> 32);
+ g(c >> 40);
+ g(c >> 48);
+ g(c >> 56);
+}
+
+static void orex(int ll, int r, int r2, int b)
+{
+ if ((r & VT_VALMASK) >= VT_CONST)
+ r = 0;
+ if ((r2 & VT_VALMASK) >= VT_CONST)
+ r2 = 0;
+ if (ll || REX_BASE(r) || REX_BASE(r2))
+ o(0x40 | REX_BASE(r) | (REX_BASE(r2) << 2) | (ll << 3));
+ o(b);
+}
+
+/* output a symbol and patch all calls to it */
+ST_FUNC void gsym_addr(int t, int a)
+{
+ while (t) {
+ unsigned char *ptr = cur_text_section->data + t;
+ uint32_t n = read32le(ptr); /* next value */
+ write32le(ptr, a - t - 4);
+ t = n;
+ }
+}
+
+void gsym(int t)
+{
+ gsym_addr(t, ind);
+}
+
+
+static int is64_type(int t)
+{
+ return ((t & VT_BTYPE) == VT_PTR ||
+ (t & VT_BTYPE) == VT_FUNC ||
+ (t & VT_BTYPE) == VT_LLONG);
+}
+
+/* instruction + 4 bytes data. Return the address of the data */
+static int oad(int c, int s)
+{
+ int t;
+ if (nocode_wanted)
+ return s;
+ o(c);
+ t = ind;
+ gen_le32(s);
+ return t;
+}
+
+/* generate jmp to a label */
+#define gjmp2(instr,lbl) oad(instr,lbl)
+
+ST_FUNC void gen_addr32(int r, Sym *sym, int c)
+{
+ if (r & VT_SYM)
+ greloca(cur_text_section, sym, ind, R_X86_64_32S, c), c=0;
+ gen_le32(c);
+}
+
+/* output constant with relocation if 'r & VT_SYM' is true */
+ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c)
+{
+ if (r & VT_SYM)
+ greloca(cur_text_section, sym, ind, R_X86_64_64, c), c=0;
+ gen_le64(c);
+}
+
+/* output constant with relocation if 'r & VT_SYM' is true */
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
+{
+ if (r & VT_SYM)
+ greloca(cur_text_section, sym, ind, R_X86_64_PC32, c-4), c=4;
+ gen_le32(c-4);
+}
+
+/* output got address with relocation */
+static void gen_gotpcrel(int r, Sym *sym, int c)
+{
+#ifdef TCC_TARGET_PE
+ tcc_error("internal error: no GOT on PE: %s %x %x | %02x %02x %02x\n",
+ get_tok_str(sym->v, NULL), c, r,
+ cur_text_section->data[ind-3],
+ cur_text_section->data[ind-2],
+ cur_text_section->data[ind-1]
+ );
+#endif
+ greloca(cur_text_section, sym, ind, R_X86_64_GOTPCREL, -4);
+ gen_le32(0);
+ if (c) {
+ /* we use add c, %xxx for displacement */
+ orex(1, r, 0, 0x81);
+ o(0xc0 + REG_VALUE(r));
+ gen_le32(c);
+ }
+}
+
+static void gen_modrm_impl(int op_reg, int r, Sym *sym, int c, int is_got)
+{
+ op_reg = REG_VALUE(op_reg) << 3;
+ if ((r & VT_VALMASK) == VT_CONST) {
+ /* constant memory reference */
+ if (!(r & VT_SYM)) {
+ /* Absolute memory reference */
+ o(0x04 | op_reg); /* [sib] | destreg */
+ oad(0x25, c); /* disp32 */
+ } else {
+ o(0x05 | op_reg); /* (%rip)+disp32 | destreg */
+ if (is_got) {
+ gen_gotpcrel(r, sym, c);
+ } else {
+ gen_addrpc32(r, sym, c);
+ }
+ }
+ } else if ((r & VT_VALMASK) == VT_LOCAL) {
+ /* currently, we use only ebp as base */
+ if (c == (char)c) {
+ /* short reference */
+ o(0x45 | op_reg);
+ g(c);
+ } else {
+ oad(0x85 | op_reg, c);
+ }
+ } else if ((r & VT_VALMASK) >= TREG_MEM) {
+ if (c) {
+ g(0x80 | op_reg | REG_VALUE(r));
+ gen_le32(c);
+ } else {
+ g(0x00 | op_reg | REG_VALUE(r));
+ }
+ } else {
+ g(0x00 | op_reg | REG_VALUE(r));
+ }
+}
+
+/* generate a modrm reference. 'op_reg' contains the additional 3
+ opcode bits */
+static void gen_modrm(int op_reg, int r, Sym *sym, int c)
+{
+ gen_modrm_impl(op_reg, r, sym, c, 0);
+}
+
+/* generate a modrm reference. 'op_reg' contains the additional 3
+ opcode bits */
+static void gen_modrm64(int opcode, int op_reg, int r, Sym *sym, int c)
+{
+ int is_got;
+ is_got = (op_reg & TREG_MEM) && !(sym->type.t & VT_STATIC);
+ orex(1, r, op_reg, opcode);
+ gen_modrm_impl(op_reg, r, sym, c, is_got);
+}
+
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue *sv)
+{
+ int v, t, ft, fc, fr;
+ SValue v1;
+
+#ifdef TCC_TARGET_PE
+ SValue v2;
+ sv = pe_getimport(sv, &v2);
+#endif
+
+ fr = sv->r;
+ ft = sv->type.t & ~VT_DEFSIGN;
+ fc = sv->c.i;
+ if (fc != sv->c.i && (fr & VT_SYM))
+ tcc_error("64 bit addend in load");
+
+ ft &= ~(VT_VOLATILE | VT_CONSTANT);
+
+#ifndef TCC_TARGET_PE
+ /* we use indirect access via got */
+ if ((fr & VT_VALMASK) == VT_CONST && (fr & VT_SYM) &&
+ (fr & VT_LVAL) && !(sv->sym->type.t & VT_STATIC)) {
+ /* use the result register as a temporal register */
+ int tr = r | TREG_MEM;
+ if (is_float(ft)) {
+ /* we cannot use float registers as a temporal register */
+ tr = get_reg(RC_INT) | TREG_MEM;
+ }
+ gen_modrm64(0x8b, tr, fr, sv->sym, 0);
+
+ /* load from the temporal register */
+ fr = tr | VT_LVAL;
+ }
+#endif
+
+ v = fr & VT_VALMASK;
+ if (fr & VT_LVAL) {
+ int b, ll;
+ if (v == VT_LLOCAL) {
+ v1.type.t = VT_PTR;
+ v1.r = VT_LOCAL | VT_LVAL;
+ v1.c.i = fc;
+ fr = r;
+ if (!(reg_classes[fr] & (RC_INT|RC_R11)))
+ fr = get_reg(RC_INT);
+ load(fr, &v1);
+ }
+ if (fc != sv->c.i) {
+ /* If the addends doesn't fit into a 32bit signed
+ we must use a 64bit move. We've checked above
+ that this doesn't have a sym associated. */
+ v1.type.t = VT_LLONG;
+ v1.r = VT_CONST;
+ v1.c.i = sv->c.i;
+ fr = r;
+ if (!(reg_classes[fr] & (RC_INT|RC_R11)))
+ fr = get_reg(RC_INT);
+ load(fr, &v1);
+ fc = 0;
+ }
+ ll = 0;
+ /* Like GCC we can load from small enough properly sized
+ structs and unions as well.
+ XXX maybe move to generic operand handling, but should
+ occur only with asm, so tccasm.c might also be a better place */
+ if ((ft & VT_BTYPE) == VT_STRUCT) {
+ int align;
+ switch (type_size(&sv->type, &align)) {
+ case 1: ft = VT_BYTE; break;
+ case 2: ft = VT_SHORT; break;
+ case 4: ft = VT_INT; break;
+ case 8: ft = VT_LLONG; break;
+ default:
+ tcc_error("invalid aggregate type for register load");
+ break;
+ }
+ }
+ if ((ft & VT_BTYPE) == VT_FLOAT) {
+ b = 0x6e0f66;
+ r = REG_VALUE(r); /* movd */
+ } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+ b = 0x7e0ff3; /* movq */
+ r = REG_VALUE(r);
+ } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+ b = 0xdb, r = 5; /* fldt */
+ } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
+ b = 0xbe0f; /* movsbl */
+ } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
+ b = 0xb60f; /* movzbl */
+ } else if ((ft & VT_TYPE) == VT_SHORT) {
+ b = 0xbf0f; /* movswl */
+ } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
+ b = 0xb70f; /* movzwl */
+ } else {
+ assert(((ft & VT_BTYPE) == VT_INT)
+ || ((ft & VT_BTYPE) == VT_LLONG)
+ || ((ft & VT_BTYPE) == VT_PTR)
+ || ((ft & VT_BTYPE) == VT_FUNC)
+ );
+ ll = is64_type(ft);
+ b = 0x8b;
+ }
+ if (ll) {
+ gen_modrm64(b, r, fr, sv->sym, fc);
+ } else {
+ orex(ll, fr, r, b);
+ gen_modrm(r, fr, sv->sym, fc);
+ }
+ } else {
+ if (v == VT_CONST) {
+ if (fr & VT_SYM) {
+#ifdef TCC_TARGET_PE
+ orex(1,0,r,0x8d);
+ o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */
+ gen_addrpc32(fr, sv->sym, fc);
+#else
+ if (sv->sym->type.t & VT_STATIC) {
+ orex(1,0,r,0x8d);
+ o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */
+ gen_addrpc32(fr, sv->sym, fc);
+ } else {
+ orex(1,0,r,0x8b);
+ o(0x05 + REG_VALUE(r) * 8); /* mov xx(%rip), r */
+ gen_gotpcrel(r, sv->sym, fc);
+ }
+#endif
+ } else if (is64_type(ft)) {
+ orex(1,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */
+ gen_le64(sv->c.i);
+ } else {
+ orex(0,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */
+ gen_le32(fc);
+ }
+ } else if (v == VT_LOCAL) {
+ orex(1,0,r,0x8d); /* lea xxx(%ebp), r */
+ gen_modrm(r, VT_LOCAL, sv->sym, fc);
+ } else if (v == VT_CMP) {
+ orex(0,r,0,0);
+ if ((fc & ~0x100) != TOK_NE)
+ oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */
+ else
+ oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */
+ if (fc & 0x100)
+ {
+ /* This was a float compare. If the parity bit is
+ set the result was unordered, meaning false for everything
+ except TOK_NE, and true for TOK_NE. */
+ fc &= ~0x100;
+ o(0x037a + (REX_BASE(r) << 8));
+ }
+ orex(0,r,0, 0x0f); /* setxx %br */
+ o(fc);
+ o(0xc0 + REG_VALUE(r));
+ } else if (v == VT_JMP || v == VT_JMPI) {
+ t = v & 1;
+ orex(0,r,0,0);
+ oad(0xb8 + REG_VALUE(r), t); /* mov $1, r */
+ o(0x05eb + (REX_BASE(r) << 8)); /* jmp after */
+ gsym(fc);
+ orex(0,r,0,0);
+ oad(0xb8 + REG_VALUE(r), t ^ 1); /* mov $0, r */
+ } else if (v != r) {
+ if ((r >= TREG_XMM0) && (r <= TREG_XMM7)) {
+ if (v == TREG_ST0) {
+ /* gen_cvt_ftof(VT_DOUBLE); */
+ o(0xf0245cdd); /* fstpl -0x10(%rsp) */
+ /* movsd -0x10(%rsp),%xmmN */
+ o(0x100ff2);
+ o(0x44 + REG_VALUE(r)*8); /* %xmmN */
+ o(0xf024);
+ } else {
+ assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
+ if ((ft & VT_BTYPE) == VT_FLOAT) {
+ o(0x100ff3);
+ } else {
+ assert((ft & VT_BTYPE) == VT_DOUBLE);
+ o(0x100ff2);
+ }
+ o(0xc0 + REG_VALUE(v) + REG_VALUE(r)*8);
+ }
+ } else if (r == TREG_ST0) {
+ assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
+ /* gen_cvt_ftof(VT_LDOUBLE); */
+ /* movsd %xmmN,-0x10(%rsp) */
+ o(0x110ff2);
+ o(0x44 + REG_VALUE(r)*8); /* %xmmN */
+ o(0xf024);
+ o(0xf02444dd); /* fldl -0x10(%rsp) */
+ } else {
+ orex(1,r,v, 0x89);
+ o(0xc0 + REG_VALUE(r) + REG_VALUE(v) * 8); /* mov v, r */
+ }
+ }
+ }
+}
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue *v)
+{
+ int fr, bt, ft, fc;
+ int op64 = 0;
+ /* store the REX prefix in this variable when PIC is enabled */
+ int pic = 0;
+
+#ifdef TCC_TARGET_PE
+ SValue v2;
+ v = pe_getimport(v, &v2);
+#endif
+
+ fr = v->r & VT_VALMASK;
+ ft = v->type.t;
+ fc = v->c.i;
+ if (fc != v->c.i && (fr & VT_SYM))
+ tcc_error("64 bit addend in store");
+ ft &= ~(VT_VOLATILE | VT_CONSTANT);
+ bt = ft & VT_BTYPE;
+
+#ifndef TCC_TARGET_PE
+ /* we need to access the variable via got */
+ if (fr == VT_CONST && (v->r & VT_SYM)) {
+ /* mov xx(%rip), %r11 */
+ o(0x1d8b4c);
+ gen_gotpcrel(TREG_R11, v->sym, v->c.i);
+ pic = is64_type(bt) ? 0x49 : 0x41;
+ }
+#endif
+
+ /* XXX: incorrect if float reg to reg */
+ if (bt == VT_FLOAT) {
+ o(0x66);
+ o(pic);
+ o(0x7e0f); /* movd */
+ r = REG_VALUE(r);
+ } else if (bt == VT_DOUBLE) {
+ o(0x66);
+ o(pic);
+ o(0xd60f); /* movq */
+ r = REG_VALUE(r);
+ } else if (bt == VT_LDOUBLE) {
+ o(0xc0d9); /* fld %st(0) */
+ o(pic);
+ o(0xdb); /* fstpt */
+ r = 7;
+ } else {
+ if (bt == VT_SHORT)
+ o(0x66);
+ o(pic);
+ if (bt == VT_BYTE || bt == VT_BOOL)
+ orex(0, 0, r, 0x88);
+ else if (is64_type(bt))
+ op64 = 0x89;
+ else
+ orex(0, 0, r, 0x89);
+ }
+ if (pic) {
+ /* xxx r, (%r11) where xxx is mov, movq, fld, or etc */
+ if (op64)
+ o(op64);
+ o(3 + (r << 3));
+ } else if (op64) {
+ if (fr == VT_CONST || fr == VT_LOCAL || (v->r & VT_LVAL)) {
+ gen_modrm64(op64, r, v->r, v->sym, fc);
+ } else if (fr != r) {
+ /* XXX: don't we really come here? */
+ abort();
+ o(0xc0 + fr + r * 8); /* mov r, fr */
+ }
+ } else {
+ if (fr == VT_CONST || fr == VT_LOCAL || (v->r & VT_LVAL)) {
+ gen_modrm(r, v->r, v->sym, fc);
+ } else if (fr != r) {
+ /* XXX: don't we really come here? */
+ abort();
+ o(0xc0 + fr + r * 8); /* mov r, fr */
+ }
+ }
+}
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+ int r;
+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
+ ((vtop->r & VT_SYM) || (vtop->c.i-4) == (int)(vtop->c.i-4))) {
+ /* constant case */
+ if (vtop->r & VT_SYM) {
+ /* relocation case */
+#ifdef TCC_TARGET_PE
+ greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4));
+#else
+ greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4));
+#endif
+ } else {
+ /* put an empty PC32 relocation */
+ put_elf_reloca(symtab_section, cur_text_section,
+ ind + 1, R_X86_64_PC32, 0, (int)(vtop->c.i-4));
+ }
+ oad(0xe8 + is_jmp, 0); /* call/jmp im */
+ } else {
+ /* otherwise, indirect call */
+ r = TREG_R11;
+ load(r, vtop);
+ o(0x41); /* REX */
+ o(0xff); /* call/jmp *r */
+ o(0xd0 + REG_VALUE(r) + (is_jmp << 4));
+ }
+}
+
+#if defined(CONFIG_TCC_BCHECK)
+#ifndef TCC_TARGET_PE
+static addr_t func_bound_offset;
+static unsigned long func_bound_ind;
+#endif
+
+static void gen_static_call(int v)
+{
+ Sym *sym = external_global_sym(v, &func_old_type, 0);
+ oad(0xe8, 0);
+ greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
+}
+
+/* generate a bounded pointer addition */
+ST_FUNC void gen_bounded_ptr_add(void)
+{
+ /* save all temporary registers */
+ save_regs(0);
+
+ /* prepare fast x86_64 function call */
+ gv(RC_RAX);
+ o(0xc68948); // mov %rax,%rsi ## second arg in %rsi, this must be size
+ vtop--;
+
+ gv(RC_RAX);
+ o(0xc78948); // mov %rax,%rdi ## first arg in %rdi, this must be ptr
+ vtop--;
+
+ /* do a fast function call */
+ gen_static_call(TOK___bound_ptr_add);
+
+ /* returned pointer is in rax */
+ vtop++;
+ vtop->r = TREG_RAX | VT_BOUNDED;
+
+
+ /* relocation offset of the bounding function call point */
+ vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela)));
+}
+
+/* patch pointer addition in vtop so that pointer dereferencing is
+ also tested */
+ST_FUNC void gen_bounded_ptr_deref(void)
+{
+ addr_t func;
+ int size, align;
+ ElfW(Rela) *rel;
+ Sym *sym;
+
+ size = 0;
+ /* XXX: put that code in generic part of tcc */
+ if (!is_float(vtop->type.t)) {
+ if (vtop->r & VT_LVAL_BYTE)
+ size = 1;
+ else if (vtop->r & VT_LVAL_SHORT)
+ size = 2;
+ }
+ if (!size)
+ size = type_size(&vtop->type, &align);
+ switch(size) {
+ case 1: func = TOK___bound_ptr_indir1; break;
+ case 2: func = TOK___bound_ptr_indir2; break;
+ case 4: func = TOK___bound_ptr_indir4; break;
+ case 8: func = TOK___bound_ptr_indir8; break;
+ case 12: func = TOK___bound_ptr_indir12; break;
+ case 16: func = TOK___bound_ptr_indir16; break;
+ default:
+ tcc_error("unhandled size when dereferencing bounded pointer");
+ func = 0;
+ break;
+ }
+
+ sym = external_global_sym(func, &func_old_type, 0);
+ if (!sym->c)
+ put_extern_sym(sym, NULL, 0, 0);
+
+ /* patch relocation */
+ /* XXX: find a better solution ? */
+
+ rel = (ElfW(Rela) *)(cur_text_section->reloc->data + vtop->c.i);
+ rel->r_info = ELF64_R_INFO(sym->c, ELF64_R_TYPE(rel->r_info));
+}
+#endif
+
+#ifdef TCC_TARGET_PE
+
+#define REGN 4
+static const uint8_t arg_regs[REGN] = {
+ TREG_RCX, TREG_RDX, TREG_R8, TREG_R9
+};
+
+/* Prepare arguments in R10 and R11 rather than RCX and RDX
+ because gv() will not ever use these */
+static int arg_prepare_reg(int idx) {
+ if (idx == 0 || idx == 1)
+ /* idx=0: r10, idx=1: r11 */
+ return idx + 10;
+ else
+ return arg_regs[idx];
+}
+
+static int func_scratch, func_alloca;
+
+/* Generate function call. The function address is pushed first, then
+ all the parameters in call order. This functions pops all the
+ parameters and the function address. */
+
+static void gen_offs_sp(int b, int r, int d)
+{
+ orex(1,0,r & 0x100 ? 0 : r, b);
+ if (d == (char)d) {
+ o(0x2444 | (REG_VALUE(r) << 3));
+ g(d);
+ } else {
+ o(0x2484 | (REG_VALUE(r) << 3));
+ gen_le32(d);
+ }
+}
+
+static int using_regs(int size)
+{
+ return !(size > 8 || (size & (size - 1)));
+}
+
+/* Return the number of registers needed to return the struct, or 0 if
+ returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
+{
+ int size, align;
+ *ret_align = 1; // Never have to re-align return values for x86-64
+ *regsize = 8;
+ size = type_size(vt, &align);
+ if (!using_regs(size))
+ return 0;
+ if (size == 8)
+ ret->t = VT_LLONG;
+ else if (size == 4)
+ ret->t = VT_INT;
+ else if (size == 2)
+ ret->t = VT_SHORT;
+ else
+ ret->t = VT_BYTE;
+ ret->ref = NULL;
+ return 1;
+}
+
+static int is_sse_float(int t) {
+ int bt;
+ bt = t & VT_BTYPE;
+ return bt == VT_DOUBLE || bt == VT_FLOAT;
+}
+
+static int gfunc_arg_size(CType *type) {
+ int align;
+ if (type->t & (VT_ARRAY|VT_BITFIELD))
+ return 8;
+ return type_size(type, &align);
+}
+
+void gfunc_call(int nb_args)
+{
+ int size, r, args_size, i, d, bt, struct_size;
+ int arg;
+
+ args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE;
+ arg = nb_args;
+
+ /* for struct arguments, we need to call memcpy and the function
+ call breaks register passing arguments we are preparing.
+ So, we process arguments which will be passed by stack first. */
+ struct_size = args_size;
+ for(i = 0; i < nb_args; i++) {
+ SValue *sv;
+
+ --arg;
+ sv = &vtop[-i];
+ bt = (sv->type.t & VT_BTYPE);
+ size = gfunc_arg_size(&sv->type);
+
+ if (using_regs(size))
+ continue; /* arguments smaller than 8 bytes passed in registers or on stack */
+
+ if (bt == VT_STRUCT) {
+ /* align to stack align size */
+ size = (size + 15) & ~15;
+ /* generate structure store */
+ r = get_reg(RC_INT);
+ gen_offs_sp(0x8d, r, struct_size);
+ struct_size += size;
+
+ /* generate memcpy call */
+ vset(&sv->type, r | VT_LVAL, 0);
+ vpushv(sv);
+ vstore();
+ --vtop;
+ } else if (bt == VT_LDOUBLE) {
+ gv(RC_ST0);
+ gen_offs_sp(0xdb, 0x107, struct_size);
+ struct_size += 16;
+ }
+ }
+
+ if (func_scratch < struct_size)
+ func_scratch = struct_size;
+
+ arg = nb_args;
+ struct_size = args_size;
+
+ for(i = 0; i < nb_args; i++) {
+ --arg;
+ bt = (vtop->type.t & VT_BTYPE);
+
+ size = gfunc_arg_size(&vtop->type);
+ if (!using_regs(size)) {
+ /* align to stack align size */
+ size = (size + 15) & ~15;
+ if (arg >= REGN) {
+ d = get_reg(RC_INT);
+ gen_offs_sp(0x8d, d, struct_size);
+ gen_offs_sp(0x89, d, arg*8);
+ } else {
+ d = arg_prepare_reg(arg);
+ gen_offs_sp(0x8d, d, struct_size);
+ }
+ struct_size += size;
+ } else {
+ if (is_sse_float(vtop->type.t)) {
+ if (tcc_state->nosse)
+ tcc_error("SSE disabled");
+ gv(RC_XMM0); /* only use one float register */
+ if (arg >= REGN) {
+ /* movq %xmm0, j*8(%rsp) */
+ gen_offs_sp(0xd60f66, 0x100, arg*8);
+ } else {
+ /* movaps %xmm0, %xmmN */
+ o(0x280f);
+ o(0xc0 + (arg << 3));
+ d = arg_prepare_reg(arg);
+ /* mov %xmm0, %rxx */
+ o(0x66);
+ orex(1,d,0, 0x7e0f);
+ o(0xc0 + REG_VALUE(d));
+ }
+ } else {
+ if (bt == VT_STRUCT) {
+ vtop->type.ref = NULL;
+ vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
+ : size > 1 ? VT_SHORT : VT_BYTE;
+ }
+
+ r = gv(RC_INT);
+ if (arg >= REGN) {
+ gen_offs_sp(0x89, r, arg*8);
+ } else {
+ d = arg_prepare_reg(arg);
+ orex(1,d,r,0x89); /* mov */
+ o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
+ }
+ }
+ }
+ vtop--;
+ }
+ save_regs(0);
+
+ /* Copy R10 and R11 into RCX and RDX, respectively */
+ if (nb_args > 0) {
+ o(0xd1894c); /* mov %r10, %rcx */
+ if (nb_args > 1) {
+ o(0xda894c); /* mov %r11, %rdx */
+ }
+ }
+
+ gcall_or_jmp(0);
+
+ if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) {
+ /* need to add the "func_scratch" area after alloca */
+ o(0x0548), gen_le32(func_alloca), func_alloca = ind - 4;
+ }
+
+ /* other compilers don't clear the upper bits when returning char/short */
+ bt = vtop->type.ref->type.t & (VT_BTYPE | VT_UNSIGNED);
+ if (bt == (VT_BYTE | VT_UNSIGNED))
+ o(0xc0b60f); /* movzbl %al, %eax */
+ else if (bt == VT_BYTE)
+ o(0xc0be0f); /* movsbl %al, %eax */
+ else if (bt == VT_SHORT)
+ o(0x98); /* cwtl */
+ else if (bt == (VT_SHORT | VT_UNSIGNED))
+ o(0xc0b70f); /* movzbl %al, %eax */
+#if 0 /* handled in gen_cast() */
+ else if (bt == VT_INT)
+ o(0x9848); /* cltq */
+ else if (bt == (VT_INT | VT_UNSIGNED))
+ o(0xc089); /* mov %eax,%eax */
+#endif
+ vtop--;
+}
+
+
+#define FUNC_PROLOG_SIZE 11
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType *func_type)
+{
+ int addr, reg_param_index, bt, size;
+ Sym *sym;
+ CType *type;
+
+ func_ret_sub = 0;
+ func_scratch = 0;
+ func_alloca = 0;
+ loc = 0;
+
+ addr = PTR_SIZE * 2;
+ ind += FUNC_PROLOG_SIZE;
+ func_sub_sp_offset = ind;
+ reg_param_index = 0;
+
+ sym = func_type->ref;
+
+ /* if the function returns a structure, then add an
+ implicit pointer parameter */
+ func_vt = sym->type;
+ func_var = (sym->f.func_type == FUNC_ELLIPSIS);
+ size = gfunc_arg_size(&func_vt);
+ if (!using_regs(size)) {
+ gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
+ func_vc = addr;
+ reg_param_index++;
+ addr += 8;
+ }
+
+ /* define parameters */
+ while ((sym = sym->next) != NULL) {
+ type = &sym->type;
+ bt = type->t & VT_BTYPE;
+ size = gfunc_arg_size(type);
+ if (!using_regs(size)) {
+ if (reg_param_index < REGN) {
+ gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
+ }
+ sym_push(sym->v & ~SYM_FIELD, type, VT_LLOCAL | VT_LVAL, addr);
+ } else {
+ if (reg_param_index < REGN) {
+ /* save arguments passed by register */
+ if ((bt == VT_FLOAT) || (bt == VT_DOUBLE)) {
+ if (tcc_state->nosse)
+ tcc_error("SSE disabled");
+ o(0xd60f66); /* movq */
+ gen_modrm(reg_param_index, VT_LOCAL, NULL, addr);
+ } else {
+ gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
+ }
+ }
+ sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);
+ }
+ addr += 8;
+ reg_param_index++;
+ }
+
+ while (reg_param_index < REGN) {
+ if (func_type->ref->f.func_type == FUNC_ELLIPSIS) {
+ gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
+ addr += 8;
+ }
+ reg_param_index++;
+ }
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+ int v, saved_ind;
+
+ o(0xc9); /* leave */
+ if (func_ret_sub == 0) {
+ o(0xc3); /* ret */
+ } else {
+ o(0xc2); /* ret n */
+ g(func_ret_sub);
+ g(func_ret_sub >> 8);
+ }
+
+ saved_ind = ind;
+ ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
+ /* align local size to word & save local variables */
+ func_scratch = (func_scratch + 15) & -16;
+ v = (func_scratch + -loc + 15) & -16;
+
+ if (v >= 4096) {
+ Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
+ oad(0xb8, v); /* mov stacksize, %eax */
+ oad(0xe8, 0); /* call __chkstk, (does the stackframe too) */
+ greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
+ o(0x90); /* fill for FUNC_PROLOG_SIZE = 11 bytes */
+ } else {
+ o(0xe5894855); /* push %rbp, mov %rsp, %rbp */
+ o(0xec8148); /* sub rsp, stacksize */
+ gen_le32(v);
+ }
+
+ /* add the "func_scratch" area after each alloca seen */
+ while (func_alloca) {
+ unsigned char *ptr = cur_text_section->data + func_alloca;
+ func_alloca = read32le(ptr);
+ write32le(ptr, func_scratch);
+ }
+
+ cur_text_section->data_offset = saved_ind;
+ pe_add_unwind_data(ind, saved_ind, v);
+ ind = cur_text_section->data_offset;
+}
+
+#else
+
+static void gadd_sp(int val)
+{
+ if (val == (char)val) {
+ o(0xc48348);
+ g(val);
+ } else {
+ oad(0xc48148, val); /* add $xxx, %rsp */
+ }
+}
+
+typedef enum X86_64_Mode {
+ x86_64_mode_none,
+ x86_64_mode_memory,
+ x86_64_mode_integer,
+ x86_64_mode_sse,
+ x86_64_mode_x87
+} X86_64_Mode;
+
+static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b)
+{
+ if (a == b)
+ return a;
+ else if (a == x86_64_mode_none)
+ return b;
+ else if (b == x86_64_mode_none)
+ return a;
+ else if ((a == x86_64_mode_memory) || (b == x86_64_mode_memory))
+ return x86_64_mode_memory;
+ else if ((a == x86_64_mode_integer) || (b == x86_64_mode_integer))
+ return x86_64_mode_integer;
+ else if ((a == x86_64_mode_x87) || (b == x86_64_mode_x87))
+ return x86_64_mode_memory;
+ else
+ return x86_64_mode_sse;
+}
+
+static X86_64_Mode classify_x86_64_inner(CType *ty)
+{
+ X86_64_Mode mode;
+ Sym *f;
+
+ switch (ty->t & VT_BTYPE) {
+ case VT_VOID: return x86_64_mode_none;
+
+ case VT_INT:
+ case VT_BYTE:
+ case VT_SHORT:
+ case VT_LLONG:
+ case VT_BOOL:
+ case VT_PTR:
+ case VT_FUNC:
+ return x86_64_mode_integer;
+
+ case VT_FLOAT:
+ case VT_DOUBLE: return x86_64_mode_sse;
+
+ case VT_LDOUBLE: return x86_64_mode_x87;
+
+ case VT_STRUCT:
+ f = ty->ref;
+
+ mode = x86_64_mode_none;
+ for (f = f->next; f; f = f->next)
+ mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type));
+
+ return mode;
+ }
+ assert(0);
+ return 0;
+}
+
+static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)
+{
+ X86_64_Mode mode;
+ int size, align, ret_t = 0;
+
+ if (ty->t & (VT_BITFIELD|VT_ARRAY)) {
+ *psize = 8;
+ *palign = 8;
+ *reg_count = 1;
+ ret_t = ty->t;
+ mode = x86_64_mode_integer;
+ } else {
+ size = type_size(ty, &align);
+ *psize = (size + 7) & ~7;
+ *palign = (align + 7) & ~7;
+
+ if (size > 16) {
+ mode = x86_64_mode_memory;
+ } else {
+ mode = classify_x86_64_inner(ty);
+ switch (mode) {
+ case x86_64_mode_integer:
+ if (size > 8) {
+ *reg_count = 2;
+ ret_t = VT_QLONG;
+ } else {
+ *reg_count = 1;
+ ret_t = (size > 4) ? VT_LLONG : VT_INT;
+ }
+ break;
+
+ case x86_64_mode_x87:
+ *reg_count = 1;
+ ret_t = VT_LDOUBLE;
+ break;
+
+ case x86_64_mode_sse:
+ if (size > 8) {
+ *reg_count = 2;
+ ret_t = VT_QFLOAT;
+ } else {
+ *reg_count = 1;
+ ret_t = (size > 4) ? VT_DOUBLE : VT_FLOAT;
+ }
+ break;
+ default: break; /* nothing to be done for x86_64_mode_memory and x86_64_mode_none*/
+ }
+ }
+ }
+
+ if (ret) {
+ ret->ref = NULL;
+ ret->t = ret_t;
+ }
+
+ return mode;
+}
+
+ST_FUNC int classify_x86_64_va_arg(CType *ty)
+{
+ /* This definition must be synced with stdarg.h */
+ enum __va_arg_type {
+ __va_gen_reg, __va_float_reg, __va_stack
+ };
+ int size, align, reg_count;
+ X86_64_Mode mode = classify_x86_64_arg(ty, NULL, &size, &align, &reg_count);
+ switch (mode) {
+ default: return __va_stack;
+ case x86_64_mode_integer: return __va_gen_reg;
+ case x86_64_mode_sse: return __va_float_reg;
+ }
+}
+
+/* Return the number of registers needed to return the struct, or 0 if
+ returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
+{
+ int size, align, reg_count;
+ *ret_align = 1; // Never have to re-align return values for x86-64
+ *regsize = 8;
+ return (classify_x86_64_arg(vt, ret, &size, &align, &reg_count) != x86_64_mode_memory);
+}
+
+#define REGN 6
+static const uint8_t arg_regs[REGN] = {
+ TREG_RDI, TREG_RSI, TREG_RDX, TREG_RCX, TREG_R8, TREG_R9
+};
+
+static int arg_prepare_reg(int idx) {
+ if (idx == 2 || idx == 3)
+ /* idx=2: r10, idx=3: r11 */
+ return idx + 8;
+ else
+ return arg_regs[idx];
+}
+
+/* Generate function call. The function address is pushed first, then
+ all the parameters in call order. This functions pops all the
+ parameters and the function address. */
+void gfunc_call(int nb_args)
+{
+ X86_64_Mode mode;
+ CType type;
+ int size, align, r, args_size, stack_adjust, i, reg_count;
+ int nb_reg_args = 0;
+ int nb_sse_args = 0;
+ int sse_reg, gen_reg;
+ char _onstack[nb_args], *onstack = _onstack;
+
+ /* calculate the number of integer/float register arguments, remember
+ arguments to be passed via stack (in onstack[]), and also remember
+ if we have to align the stack pointer to 16 (onstack[i] == 2). Needs
+ to be done in a left-to-right pass over arguments. */
+ stack_adjust = 0;
+ for(i = nb_args - 1; i >= 0; i--) {
+ mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
+ if (mode == x86_64_mode_sse && nb_sse_args + reg_count <= 8) {
+ nb_sse_args += reg_count;
+ onstack[i] = 0;
+ } else if (mode == x86_64_mode_integer && nb_reg_args + reg_count <= REGN) {
+ nb_reg_args += reg_count;
+ onstack[i] = 0;
+ } else if (mode == x86_64_mode_none) {
+ onstack[i] = 0;
+ } else {
+ if (align == 16 && (stack_adjust &= 15)) {
+ onstack[i] = 2;
+ stack_adjust = 0;
+ } else
+ onstack[i] = 1;
+ stack_adjust += size;
+ }
+ }
+
+ if (nb_sse_args && tcc_state->nosse)
+ tcc_error("SSE disabled but floating point arguments passed");
+
+ /* fetch cpu flag before generating any code */
+ if (vtop >= vstack && (vtop->r & VT_VALMASK) == VT_CMP)
+ gv(RC_INT);
+
+ /* for struct arguments, we need to call memcpy and the function
+ call breaks register passing arguments we are preparing.
+ So, we process arguments which will be passed by stack first. */
+ gen_reg = nb_reg_args;
+ sse_reg = nb_sse_args;
+ args_size = 0;
+ stack_adjust &= 15;
+ for (i = 0; i < nb_args;) {
+ mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
+ if (!onstack[i]) {
+ ++i;
+ continue;
+ }
+ /* Possibly adjust stack to align SSE boundary. We're processing
+ args from right to left while allocating happens left to right
+ (stack grows down), so the adjustment needs to happen _after_
+ an argument that requires it. */
+ if (stack_adjust) {
+ o(0x50); /* push %rax; aka sub $8,%rsp */
+ args_size += 8;
+ stack_adjust = 0;
+ }
+ if (onstack[i] == 2)
+ stack_adjust = 1;
+
+ vrotb(i+1);
+
+ switch (vtop->type.t & VT_BTYPE) {
+ case VT_STRUCT:
+ /* allocate the necessary size on stack */
+ o(0x48);
+ oad(0xec81, size); /* sub $xxx, %rsp */
+ /* generate structure store */
+ r = get_reg(RC_INT);
+ orex(1, r, 0, 0x89); /* mov %rsp, r */
+ o(0xe0 + REG_VALUE(r));
+ vset(&vtop->type, r | VT_LVAL, 0);
+ vswap();
+ vstore();
+ break;
+
+ case VT_LDOUBLE:
+ gv(RC_ST0);
+ oad(0xec8148, size); /* sub $xxx, %rsp */
+ o(0x7cdb); /* fstpt 0(%rsp) */
+ g(0x24);
+ g(0x00);
+ break;
+
+ case VT_FLOAT:
+ case VT_DOUBLE:
+ assert(mode == x86_64_mode_sse);
+ r = gv(RC_FLOAT);
+ o(0x50); /* push $rax */
+ /* movq %xmmN, (%rsp) */
+ o(0xd60f66);
+ o(0x04 + REG_VALUE(r)*8);
+ o(0x24);
+ break;
+
+ default:
+ assert(mode == x86_64_mode_integer);
+ /* simple type */
+ /* XXX: implicit cast ? */
+ r = gv(RC_INT);
+ orex(0,r,0,0x50 + REG_VALUE(r)); /* push r */
+ break;
+ }
+ args_size += size;
+
+ vpop();
+ --nb_args;
+ onstack++;
+ }
+
+ /* XXX This should be superfluous. */
+ save_regs(0); /* save used temporary registers */
+
+ /* then, we prepare register passing arguments.
+ Note that we cannot set RDX and RCX in this loop because gv()
+ may break these temporary registers. Let's use R10 and R11
+ instead of them */
+ assert(gen_reg <= REGN);
+ assert(sse_reg <= 8);
+ for(i = 0; i < nb_args; i++) {
+ mode = classify_x86_64_arg(&vtop->type, &type, &size, &align, &reg_count);
+ /* Alter stack entry type so that gv() knows how to treat it */
+ vtop->type = type;
+ if (mode == x86_64_mode_sse) {
+ if (reg_count == 2) {
+ sse_reg -= 2;
+ gv(RC_FRET); /* Use pair load into xmm0 & xmm1 */
+ if (sse_reg) { /* avoid redundant movaps %xmm0, %xmm0 */
+ /* movaps %xmm0, %xmmN */
+ o(0x280f);
+ o(0xc0 + (sse_reg << 3));
+ /* movaps %xmm1, %xmmN */
+ o(0x280f);
+ o(0xc1 + ((sse_reg+1) << 3));
+ }
+ } else {
+ assert(reg_count == 1);
+ --sse_reg;
+ /* Load directly to register */
+ gv(RC_XMM0 << sse_reg);
+ }
+ } else if (mode == x86_64_mode_integer) {
+ /* simple type */
+ /* XXX: implicit cast ? */
+ int d;
+ gen_reg -= reg_count;
+ r = gv(RC_INT);
+ d = arg_prepare_reg(gen_reg);
+ orex(1,d,r,0x89); /* mov */
+ o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
+ if (reg_count == 2) {
+ d = arg_prepare_reg(gen_reg+1);
+ orex(1,d,vtop->r2,0x89); /* mov */
+ o(0xc0 + REG_VALUE(vtop->r2) * 8 + REG_VALUE(d));
+ }
+ }
+ vtop--;
+ }
+ assert(gen_reg == 0);
+ assert(sse_reg == 0);
+
+ /* We shouldn't have many operands on the stack anymore, but the
+ call address itself is still there, and it might be in %eax
+ (or edx/ecx) currently, which the below writes would clobber.
+ So evict all remaining operands here. */
+ save_regs(0);
+
+ /* Copy R10 and R11 into RDX and RCX, respectively */
+ if (nb_reg_args > 2) {
+ o(0xd2894c); /* mov %r10, %rdx */
+ if (nb_reg_args > 3) {
+ o(0xd9894c); /* mov %r11, %rcx */
+ }
+ }
+
+ if (vtop->type.ref->f.func_type != FUNC_NEW) /* implies FUNC_OLD or FUNC_ELLIPSIS */
+ oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */
+ gcall_or_jmp(0);
+ if (args_size)
+ gadd_sp(args_size);
+ vtop--;
+}
+
+
+#define FUNC_PROLOG_SIZE 11
+
+static void push_arg_reg(int i) {
+ loc -= 8;
+ gen_modrm64(0x89, arg_regs[i], VT_LOCAL, NULL, loc);
+}
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType *func_type)
+{
+ X86_64_Mode mode;
+ int i, addr, align, size, reg_count;
+ int param_addr = 0, reg_param_index, sse_param_index;
+ Sym *sym;
+ CType *type;
+
+ sym = func_type->ref;
+ addr = PTR_SIZE * 2;
+ loc = 0;
+ ind += FUNC_PROLOG_SIZE;
+ func_sub_sp_offset = ind;
+ func_ret_sub = 0;
+
+ if (sym->f.func_type == FUNC_ELLIPSIS) {
+ int seen_reg_num, seen_sse_num, seen_stack_size;
+ seen_reg_num = seen_sse_num = 0;
+ /* frame pointer and return address */
+ seen_stack_size = PTR_SIZE * 2;
+ /* count the number of seen parameters */
+ sym = func_type->ref;
+ while ((sym = sym->next) != NULL) {
+ type = &sym->type;
+ mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
+ switch (mode) {
+ default:
+ stack_arg:
+ seen_stack_size = ((seen_stack_size + align - 1) & -align) + size;
+ break;
+
+ case x86_64_mode_integer:
+ if (seen_reg_num + reg_count > REGN)
+ goto stack_arg;
+ seen_reg_num += reg_count;
+ break;
+
+ case x86_64_mode_sse:
+ if (seen_sse_num + reg_count > 8)
+ goto stack_arg;
+ seen_sse_num += reg_count;
+ break;
+ }
+ }
+
+ loc -= 16;
+ /* movl $0x????????, -0x10(%rbp) */
+ o(0xf045c7);
+ gen_le32(seen_reg_num * 8);
+ /* movl $0x????????, -0xc(%rbp) */
+ o(0xf445c7);
+ gen_le32(seen_sse_num * 16 + 48);
+ /* movl $0x????????, -0x8(%rbp) */
+ o(0xf845c7);
+ gen_le32(seen_stack_size);
+
+ /* save all register passing arguments */
+ for (i = 0; i < 8; i++) {
+ loc -= 16;
+ if (!tcc_state->nosse) {
+ o(0xd60f66); /* movq */
+ gen_modrm(7 - i, VT_LOCAL, NULL, loc);
+ }
+ /* movq $0, loc+8(%rbp) */
+ o(0x85c748);
+ gen_le32(loc + 8);
+ gen_le32(0);
+ }
+ for (i = 0; i < REGN; i++) {
+ push_arg_reg(REGN-1-i);
+ }
+ }
+
+ sym = func_type->ref;
+ reg_param_index = 0;
+ sse_param_index = 0;
+
+ /* if the function returns a structure, then add an
+ implicit pointer parameter */
+ func_vt = sym->type;
+ mode = classify_x86_64_arg(&func_vt, NULL, &size, &align, &reg_count);
+ if (mode == x86_64_mode_memory) {
+ push_arg_reg(reg_param_index);
+ func_vc = loc;
+ reg_param_index++;
+ }
+ /* define parameters */
+ while ((sym = sym->next) != NULL) {
+ type = &sym->type;
+ mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
+ switch (mode) {
+ case x86_64_mode_sse:
+ if (tcc_state->nosse)
+ tcc_error("SSE disabled but floating point arguments used");
+ if (sse_param_index + reg_count <= 8) {
+ /* save arguments passed by register */
+ loc -= reg_count * 8;
+ param_addr = loc;
+ for (i = 0; i < reg_count; ++i) {
+ o(0xd60f66); /* movq */
+ gen_modrm(sse_param_index, VT_LOCAL, NULL, param_addr + i*8);
+ ++sse_param_index;
+ }
+ } else {
+ addr = (addr + align - 1) & -align;
+ param_addr = addr;
+ addr += size;
+ }
+ break;
+
+ case x86_64_mode_memory:
+ case x86_64_mode_x87:
+ addr = (addr + align - 1) & -align;
+ param_addr = addr;
+ addr += size;
+ break;
+
+ case x86_64_mode_integer: {
+ if (reg_param_index + reg_count <= REGN) {
+ /* save arguments passed by register */
+ loc -= reg_count * 8;
+ param_addr = loc;
+ for (i = 0; i < reg_count; ++i) {
+ gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, param_addr + i*8);
+ ++reg_param_index;
+ }
+ } else {
+ addr = (addr + align - 1) & -align;
+ param_addr = addr;
+ addr += size;
+ }
+ break;
+ }
+ default: break; /* nothing to be done for x86_64_mode_none */
+ }
+ sym_push(sym->v & ~SYM_FIELD, type,
+ VT_LOCAL | VT_LVAL, param_addr);
+ }
+
+#ifdef CONFIG_TCC_BCHECK
+ /* leave some room for bound checking code */
+ if (tcc_state->do_bounds_check) {
+ func_bound_offset = lbounds_section->data_offset;
+ func_bound_ind = ind;
+ oad(0xb8, 0); /* lbound section pointer */
+ o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
+ oad(0xb8, 0); /* call to function */
+ }
+#endif
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+ int v, saved_ind;
+
+#ifdef CONFIG_TCC_BCHECK
+ if (tcc_state->do_bounds_check
+ && func_bound_offset != lbounds_section->data_offset)
+ {
+ addr_t saved_ind;
+ addr_t *bounds_ptr;
+ Sym *sym_data;
+
+ /* add end of table info */
+ bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
+ *bounds_ptr = 0;
+
+ /* generate bound local allocation */
+ sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
+ func_bound_offset, lbounds_section->data_offset);
+ saved_ind = ind;
+ ind = func_bound_ind;
+ greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0);
+ ind = ind + 5 + 3;
+ gen_static_call(TOK___bound_local_new);
+ ind = saved_ind;
+
+ /* generate bound check local freeing */
+ o(0x5250); /* save returned value, if any */
+ greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0);
+ oad(0xb8, 0); /* mov xxx, %rax */
+ o(0xc78948); /* mov %rax,%rdi # first arg in %rdi, this must be ptr */
+ gen_static_call(TOK___bound_local_delete);
+ o(0x585a); /* restore returned value, if any */
+ }
+#endif
+ o(0xc9); /* leave */
+ if (func_ret_sub == 0) {
+ o(0xc3); /* ret */
+ } else {
+ o(0xc2); /* ret n */
+ g(func_ret_sub);
+ g(func_ret_sub >> 8);
+ }
+ /* align local size to word & save local variables */
+ v = (-loc + 15) & -16;
+ saved_ind = ind;
+ ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
+ o(0xe5894855); /* push %rbp, mov %rsp, %rbp */
+ o(0xec8148); /* sub rsp, stacksize */
+ gen_le32(v);
+ ind = saved_ind;
+}
+
+#endif /* not PE */
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+ return gjmp2(0xe9, t);
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+ int r;
+ r = a - ind - 2;
+ if (r == (char)r) {
+ g(0xeb);
+ g(r);
+ } else {
+ oad(0xe9, a - ind - 5);
+ }
+}
+
+ST_FUNC void gtst_addr(int inv, int a)
+{
+ int v = vtop->r & VT_VALMASK;
+ if (v == VT_CMP) {
+ inv ^= (vtop--)->c.i;
+ a -= ind + 2;
+ if (a == (char)a) {
+ g(inv - 32);
+ g(a);
+ } else {
+ g(0x0f);
+ oad(inv - 16, a - 4);
+ }
+ } else if ((v & ~1) == VT_JMP) {
+ if ((v & 1) != inv) {
+ gjmp_addr(a);
+ gsym(vtop->c.i);
+ } else {
+ gsym(vtop->c.i);
+ o(0x05eb);
+ gjmp_addr(a);
+ }
+ vtop--;
+ }
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+ST_FUNC int gtst(int inv, int t)
+{
+ int v = vtop->r & VT_VALMASK;
+
+ if (nocode_wanted) {
+ ;
+ } else if (v == VT_CMP) {
+ /* fast case : can jump directly since flags are set */
+ if (vtop->c.i & 0x100)
+ {
+ /* This was a float compare. If the parity flag is set
+ the result was unordered. For anything except != this
+ means false and we don't jump (anding both conditions).
+ For != this means true (oring both).
+ Take care about inverting the test. We need to jump
+ to our target if the result was unordered and test wasn't NE,
+ otherwise if unordered we don't want to jump. */
+ vtop->c.i &= ~0x100;
+ if (inv == (vtop->c.i == TOK_NE))
+ o(0x067a); /* jp +6 */
+ else
+ {
+ g(0x0f);
+ t = gjmp2(0x8a, t); /* jp t */
+ }
+ }
+ g(0x0f);
+ t = gjmp2((vtop->c.i - 16) ^ inv, t);
+ } else if (v == VT_JMP || v == VT_JMPI) {
+ /* && or || optimization */
+ if ((v & 1) == inv) {
+ /* insert vtop->c jump list in t */
+ uint32_t n1, n = vtop->c.i;
+ if (n) {
+ while ((n1 = read32le(cur_text_section->data + n)))
+ n = n1;
+ write32le(cur_text_section->data + n, t);
+ t = vtop->c.i;
+ }
+ } else {
+ t = gjmp(t);
+ gsym(vtop->c.i);
+ }
+ }
+ vtop--;
+ return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+ int r, fr, opc, c;
+ int ll, uu, cc;
+
+ ll = is64_type(vtop[-1].type.t);
+ uu = (vtop[-1].type.t & VT_UNSIGNED) != 0;
+ cc = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+
+ switch(op) {
+ case '+':
+ case TOK_ADDC1: /* add with carry generation */
+ opc = 0;
+ gen_op8:
+ if (cc && (!ll || (int)vtop->c.i == vtop->c.i)) {
+ /* constant case */
+ vswap();
+ r = gv(RC_INT);
+ vswap();
+ c = vtop->c.i;
+ if (c == (char)c) {
+ /* XXX: generate inc and dec for smaller code ? */
+ orex(ll, r, 0, 0x83);
+ o(0xc0 | (opc << 3) | REG_VALUE(r));
+ g(c);
+ } else {
+ orex(ll, r, 0, 0x81);
+ oad(0xc0 | (opc << 3) | REG_VALUE(r), c);
+ }
+ } else {
+ gv2(RC_INT, RC_INT);
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ orex(ll, r, fr, (opc << 3) | 0x01);
+ o(0xc0 + REG_VALUE(r) + REG_VALUE(fr) * 8);
+ }
+ vtop--;
+ if (op >= TOK_ULT && op <= TOK_GT) {
+ vtop->r = VT_CMP;
+ vtop->c.i = op;
+ }
+ break;
+ case '-':
+ case TOK_SUBC1: /* sub with carry generation */
+ opc = 5;
+ goto gen_op8;
+ case TOK_ADDC2: /* add with carry use */
+ opc = 2;
+ goto gen_op8;
+ case TOK_SUBC2: /* sub with carry use */
+ opc = 3;
+ goto gen_op8;
+ case '&':
+ opc = 4;
+ goto gen_op8;
+ case '^':
+ opc = 6;
+ goto gen_op8;
+ case '|':
+ opc = 1;
+ goto gen_op8;
+ case '*':
+ gv2(RC_INT, RC_INT);
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ orex(ll, fr, r, 0xaf0f); /* imul fr, r */
+ o(0xc0 + REG_VALUE(fr) + REG_VALUE(r) * 8);
+ vtop--;
+ break;
+ case TOK_SHL:
+ opc = 4;
+ goto gen_shift;
+ case TOK_SHR:
+ opc = 5;
+ goto gen_shift;
+ case TOK_SAR:
+ opc = 7;
+ gen_shift:
+ opc = 0xc0 | (opc << 3);
+ if (cc) {
+ /* constant case */
+ vswap();
+ r = gv(RC_INT);
+ vswap();
+ orex(ll, r, 0, 0xc1); /* shl/shr/sar $xxx, r */
+ o(opc | REG_VALUE(r));
+ g(vtop->c.i & (ll ? 63 : 31));
+ } else {
+ /* we generate the shift in ecx */
+ gv2(RC_INT, RC_RCX);
+ r = vtop[-1].r;
+ orex(ll, r, 0, 0xd3); /* shl/shr/sar %cl, r */
+ o(opc | REG_VALUE(r));
+ }
+ vtop--;
+ break;
+ case TOK_UDIV:
+ case TOK_UMOD:
+ uu = 1;
+ goto divmod;
+ case '/':
+ case '%':
+ case TOK_PDIV:
+ uu = 0;
+ divmod:
+ /* first operand must be in eax */
+ /* XXX: need better constraint for second operand */
+ gv2(RC_RAX, RC_RCX);
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ vtop--;
+ save_reg(TREG_RDX);
+ orex(ll, 0, 0, uu ? 0xd231 : 0x99); /* xor %edx,%edx : cqto */
+ orex(ll, fr, 0, 0xf7); /* div fr, %eax */
+ o((uu ? 0xf0 : 0xf8) + REG_VALUE(fr));
+ if (op == '%' || op == TOK_UMOD)
+ r = TREG_RDX;
+ else
+ r = TREG_RAX;
+ vtop->r = r;
+ break;
+ default:
+ opc = 7;
+ goto gen_op8;
+ }
+}
+
+void gen_opl(int op)
+{
+ gen_opi(op);
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+ two operands are guaranteed to have the same floating point type */
+/* XXX: need to use ST1 too */
+void gen_opf(int op)
+{
+ int a, ft, fc, swapped, r;
+ int float_type =
+ (vtop->type.t & VT_BTYPE) == VT_LDOUBLE ? RC_ST0 : RC_FLOAT;
+
+ /* convert constants to memory references */
+ if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+ vswap();
+ gv(float_type);
+ vswap();
+ }
+ if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
+ gv(float_type);
+
+ /* must put at least one value in the floating point register */
+ if ((vtop[-1].r & VT_LVAL) &&
+ (vtop[0].r & VT_LVAL)) {
+ vswap();
+ gv(float_type);
+ vswap();
+ }
+ swapped = 0;
+ /* swap the stack if needed so that t1 is the register and t2 is
+ the memory reference */
+ if (vtop[-1].r & VT_LVAL) {
+ vswap();
+ swapped = 1;
+ }
+ if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+ if (op >= TOK_ULT && op <= TOK_GT) {
+ /* load on stack second operand */
+ load(TREG_ST0, vtop);
+ save_reg(TREG_RAX); /* eax is used by FP comparison code */
+ if (op == TOK_GE || op == TOK_GT)
+ swapped = !swapped;
+ else if (op == TOK_EQ || op == TOK_NE)
+ swapped = 0;
+ if (swapped)
+ o(0xc9d9); /* fxch %st(1) */
+ if (op == TOK_EQ || op == TOK_NE)
+ o(0xe9da); /* fucompp */
+ else
+ o(0xd9de); /* fcompp */
+ o(0xe0df); /* fnstsw %ax */
+ if (op == TOK_EQ) {
+ o(0x45e480); /* and $0x45, %ah */
+ o(0x40fC80); /* cmp $0x40, %ah */
+ } else if (op == TOK_NE) {
+ o(0x45e480); /* and $0x45, %ah */
+ o(0x40f480); /* xor $0x40, %ah */
+ op = TOK_NE;
+ } else if (op == TOK_GE || op == TOK_LE) {
+ o(0x05c4f6); /* test $0x05, %ah */
+ op = TOK_EQ;
+ } else {
+ o(0x45c4f6); /* test $0x45, %ah */
+ op = TOK_EQ;
+ }
+ vtop--;
+ vtop->r = VT_CMP;
+ vtop->c.i = op;
+ } else {
+ /* no memory reference possible for long double operations */
+ load(TREG_ST0, vtop);
+ swapped = !swapped;
+
+ switch(op) {
+ default:
+ case '+':
+ a = 0;
+ break;
+ case '-':
+ a = 4;
+ if (swapped)
+ a++;
+ break;
+ case '*':
+ a = 1;
+ break;
+ case '/':
+ a = 6;
+ if (swapped)
+ a++;
+ break;
+ }
+ ft = vtop->type.t;
+ fc = vtop->c.i;
+ o(0xde); /* fxxxp %st, %st(1) */
+ o(0xc1 + (a << 3));
+ vtop--;
+ }
+ } else {
+ if (op >= TOK_ULT && op <= TOK_GT) {
+ /* if saved lvalue, then we must reload it */
+ r = vtop->r;
+ fc = vtop->c.i;
+ if ((r & VT_VALMASK) == VT_LLOCAL) {
+ SValue v1;
+ r = get_reg(RC_INT);
+ v1.type.t = VT_PTR;
+ v1.r = VT_LOCAL | VT_LVAL;
+ v1.c.i = fc;
+ load(r, &v1);
+ fc = 0;
+ }
+
+ if (op == TOK_EQ || op == TOK_NE) {
+ swapped = 0;
+ } else {
+ if (op == TOK_LE || op == TOK_LT)
+ swapped = !swapped;
+ if (op == TOK_LE || op == TOK_GE) {
+ op = 0x93; /* setae */
+ } else {
+ op = 0x97; /* seta */
+ }
+ }
+
+ if (swapped) {
+ gv(RC_FLOAT);
+ vswap();
+ }
+ assert(!(vtop[-1].r & VT_LVAL));
+
+ if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+ o(0x66);
+ if (op == TOK_EQ || op == TOK_NE)
+ o(0x2e0f); /* ucomisd */
+ else
+ o(0x2f0f); /* comisd */
+
+ if (vtop->r & VT_LVAL) {
+ gen_modrm(vtop[-1].r, r, vtop->sym, fc);
+ } else {
+ o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8);
+ }
+
+ vtop--;
+ vtop->r = VT_CMP;
+ vtop->c.i = op | 0x100;
+ } else {
+ assert((vtop->type.t & VT_BTYPE) != VT_LDOUBLE);
+ switch(op) {
+ default:
+ case '+':
+ a = 0;
+ break;
+ case '-':
+ a = 4;
+ break;
+ case '*':
+ a = 1;
+ break;
+ case '/':
+ a = 6;
+ break;
+ }
+ ft = vtop->type.t;
+ fc = vtop->c.i;
+ assert((ft & VT_BTYPE) != VT_LDOUBLE);
+
+ r = vtop->r;
+ /* if saved lvalue, then we must reload it */
+ if ((vtop->r & VT_VALMASK) == VT_LLOCAL) {
+ SValue v1;
+ r = get_reg(RC_INT);
+ v1.type.t = VT_PTR;
+ v1.r = VT_LOCAL | VT_LVAL;
+ v1.c.i = fc;
+ load(r, &v1);
+ fc = 0;
+ }
+
+ assert(!(vtop[-1].r & VT_LVAL));
+ if (swapped) {
+ assert(vtop->r & VT_LVAL);
+ gv(RC_FLOAT);
+ vswap();
+ }
+
+ if ((ft & VT_BTYPE) == VT_DOUBLE) {
+ o(0xf2);
+ } else {
+ o(0xf3);
+ }
+ o(0x0f);
+ o(0x58 + a);
+
+ if (vtop->r & VT_LVAL) {
+ gen_modrm(vtop[-1].r, r, vtop->sym, fc);
+ } else {
+ o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8);
+ }
+
+ vtop--;
+ }
+ }
+}
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+ and 'long long' cases. */
+void gen_cvt_itof(int t)
+{
+ if ((t & VT_BTYPE) == VT_LDOUBLE) {
+ save_reg(TREG_ST0);
+ gv(RC_INT);
+ if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+ /* signed long long to float/double/long double (unsigned case
+ is handled generically) */
+ o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+ o(0x242cdf); /* fildll (%rsp) */
+ o(0x08c48348); /* add $8, %rsp */
+ } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
+ (VT_INT | VT_UNSIGNED)) {
+ /* unsigned int to float/double/long double */
+ o(0x6a); /* push $0 */
+ g(0x00);
+ o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+ o(0x242cdf); /* fildll (%rsp) */
+ o(0x10c48348); /* add $16, %rsp */
+ } else {
+ /* int to float/double/long double */
+ o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+ o(0x2404db); /* fildl (%rsp) */
+ o(0x08c48348); /* add $8, %rsp */
+ }
+ vtop->r = TREG_ST0;
+ } else {
+ int r = get_reg(RC_FLOAT);
+ gv(RC_INT);
+ o(0xf2 + ((t & VT_BTYPE) == VT_FLOAT?1:0));
+ if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
+ (VT_INT | VT_UNSIGNED) ||
+ (vtop->type.t & VT_BTYPE) == VT_LLONG) {
+ o(0x48); /* REX */
+ }
+ o(0x2a0f);
+ o(0xc0 + (vtop->r & VT_VALMASK) + REG_VALUE(r)*8); /* cvtsi2sd */
+ vtop->r = r;
+ }
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+ int ft, bt, tbt;
+
+ ft = vtop->type.t;
+ bt = ft & VT_BTYPE;
+ tbt = t & VT_BTYPE;
+
+ if (bt == VT_FLOAT) {
+ gv(RC_FLOAT);
+ if (tbt == VT_DOUBLE) {
+ o(0x140f); /* unpcklps */
+ o(0xc0 + REG_VALUE(vtop->r)*9);
+ o(0x5a0f); /* cvtps2pd */
+ o(0xc0 + REG_VALUE(vtop->r)*9);
+ } else if (tbt == VT_LDOUBLE) {
+ save_reg(RC_ST0);
+ /* movss %xmm0,-0x10(%rsp) */
+ o(0x110ff3);
+ o(0x44 + REG_VALUE(vtop->r)*8);
+ o(0xf024);
+ o(0xf02444d9); /* flds -0x10(%rsp) */
+ vtop->r = TREG_ST0;
+ }
+ } else if (bt == VT_DOUBLE) {
+ gv(RC_FLOAT);
+ if (tbt == VT_FLOAT) {
+ o(0x140f66); /* unpcklpd */
+ o(0xc0 + REG_VALUE(vtop->r)*9);
+ o(0x5a0f66); /* cvtpd2ps */
+ o(0xc0 + REG_VALUE(vtop->r)*9);
+ } else if (tbt == VT_LDOUBLE) {
+ save_reg(RC_ST0);
+ /* movsd %xmm0,-0x10(%rsp) */
+ o(0x110ff2);
+ o(0x44 + REG_VALUE(vtop->r)*8);
+ o(0xf024);
+ o(0xf02444dd); /* fldl -0x10(%rsp) */
+ vtop->r = TREG_ST0;
+ }
+ } else {
+ int r;
+ gv(RC_ST0);
+ r = get_reg(RC_FLOAT);
+ if (tbt == VT_DOUBLE) {
+ o(0xf0245cdd); /* fstpl -0x10(%rsp) */
+ /* movsd -0x10(%rsp),%xmm0 */
+ o(0x100ff2);
+ o(0x44 + REG_VALUE(r)*8);
+ o(0xf024);
+ vtop->r = r;
+ } else if (tbt == VT_FLOAT) {
+ o(0xf0245cd9); /* fstps -0x10(%rsp) */
+ /* movss -0x10(%rsp),%xmm0 */
+ o(0x100ff3);
+ o(0x44 + REG_VALUE(r)*8);
+ o(0xf024);
+ vtop->r = r;
+ }
+ }
+}
+
+/* convert fp to int 't' type */
+void gen_cvt_ftoi(int t)
+{
+ int ft, bt, size, r;
+ ft = vtop->type.t;
+ bt = ft & VT_BTYPE;
+ if (bt == VT_LDOUBLE) {
+ gen_cvt_ftof(VT_DOUBLE);
+ bt = VT_DOUBLE;
+ }
+
+ gv(RC_FLOAT);
+ if (t != VT_INT)
+ size = 8;
+ else
+ size = 4;
+
+ r = get_reg(RC_INT);
+ if (bt == VT_FLOAT) {
+ o(0xf3);
+ } else if (bt == VT_DOUBLE) {
+ o(0xf2);
+ } else {
+ assert(0);
+ }
+ orex(size == 8, r, 0, 0x2c0f); /* cvttss2si or cvttsd2si */
+ o(0xc0 + REG_VALUE(vtop->r) + REG_VALUE(r)*8);
+ vtop->r = r;
+}
+
+/* computed goto support */
+void ggoto(void)
+{
+ gcall_or_jmp(1);
+ vtop--;
+}
+
+/* Save the stack pointer onto the stack and return the location of its address */
+ST_FUNC void gen_vla_sp_save(int addr) {
+ /* mov %rsp,addr(%rbp)*/
+ gen_modrm64(0x89, TREG_RSP, VT_LOCAL, NULL, addr);
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+ gen_modrm64(0x8b, TREG_RSP, VT_LOCAL, NULL, addr);
+}
+
+#ifdef TCC_TARGET_PE
+/* Save result of gen_vla_alloc onto the stack */
+ST_FUNC void gen_vla_result(int addr) {
+ /* mov %rax,addr(%rbp)*/
+ gen_modrm64(0x89, TREG_RAX, VT_LOCAL, NULL, addr);
+}
+#endif
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+#ifdef TCC_TARGET_PE
+ /* alloca does more than just adjust %rsp on Windows */
+ vpush_global_sym(&func_old_type, TOK_alloca);
+ vswap(); /* Move alloca ref past allocation size */
+ gfunc_call(1);
+#else
+ int r;
+ r = gv(RC_INT); /* allocation size */
+ /* sub r,%rsp */
+ o(0x2b48);
+ o(0xe0 | REG_VALUE(r));
+ /* We align to 16 bytes rather than align */
+ /* and ~15, %rsp */
+ o(0xf0e48348);
+ vpop();
+#endif
+}
+
+
+/* end of x86-64 code generator */
+/*************************************************************/
+#endif /* ! TARGET_DEFS_ONLY */
+/******************************************************/
diff --git a/x86_64-link.c b/x86_64-link.c
new file mode 100644
index 0000000..a96144c
--- /dev/null
+++ b/x86_64-link.c
@@ -0,0 +1,298 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_X86_64
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32 R_X86_64_32S
+#define R_DATA_PTR R_X86_64_64
+#define R_JMP_SLOT R_X86_64_JUMP_SLOT
+#define R_GLOB_DAT R_X86_64_GLOB_DAT
+#define R_COPY R_X86_64_COPY
+#define R_RELATIVE R_X86_64_RELATIVE
+
+#define R_NUM R_X86_64_NUM
+
+#define ELF_START_ADDR 0x400000
+#define ELF_PAGE_SIZE 0x200000
+
+#define PCRELATIVE_DLLPLT 1
+#define RELOCATE_DLLPLT 1
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+ relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+ switch (reloc_type) {
+ case R_X86_64_32:
+ case R_X86_64_32S:
+ case R_X86_64_64:
+ case R_X86_64_GOTPC32:
+ case R_X86_64_GOTPC64:
+ case R_X86_64_GOTPCREL:
+ case R_X86_64_GOTPCRELX:
+ case R_X86_64_REX_GOTPCRELX:
+ case R_X86_64_GOTTPOFF:
+ case R_X86_64_GOT32:
+ case R_X86_64_GOT64:
+ case R_X86_64_GLOB_DAT:
+ case R_X86_64_COPY:
+ case R_X86_64_RELATIVE:
+ case R_X86_64_GOTOFF64:
+ return 0;
+
+ case R_X86_64_PC32:
+ case R_X86_64_PC64:
+ case R_X86_64_PLT32:
+ case R_X86_64_PLTOFF64:
+ case R_X86_64_JUMP_SLOT:
+ return 1;
+ }
+
+ tcc_error ("Unknown relocation type: %d", reloc_type);
+ return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+ GOT and/or PLT entry to be created. See tcc.h for a description of the
+ different values. */
+int gotplt_entry_type (int reloc_type)
+{
+ switch (reloc_type) {
+ case R_X86_64_GLOB_DAT:
+ case R_X86_64_JUMP_SLOT:
+ case R_X86_64_COPY:
+ case R_X86_64_RELATIVE:
+ return NO_GOTPLT_ENTRY;
+
+ /* The following relocs wouldn't normally need GOT or PLT
+ slots, but we need them for simplicity in the link
+ editor part. See our caller for comments. */
+ case R_X86_64_32:
+ case R_X86_64_32S:
+ case R_X86_64_64:
+ case R_X86_64_PC32:
+ case R_X86_64_PC64:
+ return AUTO_GOTPLT_ENTRY;
+
+ case R_X86_64_GOTTPOFF:
+ return BUILD_GOT_ONLY;
+
+ case R_X86_64_GOT32:
+ case R_X86_64_GOT64:
+ case R_X86_64_GOTPC32:
+ case R_X86_64_GOTPC64:
+ case R_X86_64_GOTOFF64:
+ case R_X86_64_GOTPCREL:
+ case R_X86_64_GOTPCRELX:
+ case R_X86_64_REX_GOTPCRELX:
+ case R_X86_64_PLT32:
+ case R_X86_64_PLTOFF64:
+ return ALWAYS_GOTPLT_ENTRY;
+ }
+
+ tcc_error ("Unknown relocation type: %d", reloc_type);
+ return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+ Section *plt = s1->plt;
+ uint8_t *p;
+ int modrm;
+ unsigned plt_offset, relofs;
+
+ modrm = 0x25;
+
+ /* empty PLT: create PLT0 entry that pushes the library identifier
+ (GOT + PTR_SIZE) and jumps to ld.so resolution routine
+ (GOT + 2 * PTR_SIZE) */
+ if (plt->data_offset == 0) {
+ p = section_ptr_add(plt, 16);
+ p[0] = 0xff; /* pushl got + PTR_SIZE */
+ p[1] = modrm + 0x10;
+ write32le(p + 2, PTR_SIZE);
+ p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
+ p[7] = modrm;
+ write32le(p + 8, PTR_SIZE * 2);
+ }
+ plt_offset = plt->data_offset;
+
+ /* The PLT slot refers to the relocation entry it needs via offset.
+ The reloc entry is created below, so its offset is the current
+ data_offset */
+ relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
+
+ /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
+ p = section_ptr_add(plt, 16);
+ p[0] = 0xff; /* jmp *(got + x) */
+ p[1] = modrm;
+ write32le(p + 2, got_offset);
+ p[6] = 0x68; /* push $xxx */
+ /* On x86-64, the relocation is referred to by _index_ */
+ write32le(p + 7, relofs / sizeof (ElfW_Rel));
+ p[11] = 0xe9; /* jmp plt_start */
+ write32le(p + 12, -(plt->data_offset));
+ return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+ address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+ uint8_t *p, *p_end;
+
+ if (!s1->plt)
+ return;
+
+ p = s1->plt->data;
+ p_end = p + s1->plt->data_offset;
+
+ if (p < p_end) {
+ int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
+ add32le(p + 2, x);
+ add32le(p + 8, x - 6);
+ p += 16;
+ while (p < p_end) {
+ add32le(p + 2, x + s1->plt->data - p);
+ p += 16;
+ }
+ }
+}
+
+static ElfW_Rel *qrel; /* ptr to next reloc entry reused */
+
+void relocate_init(Section *sr)
+{
+ qrel = (ElfW_Rel *) sr->data;
+}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+ int sym_index, esym_index;
+
+ sym_index = ELFW(R_SYM)(rel->r_info);
+
+ switch (type) {
+ case R_X86_64_64:
+ if (s1->output_type == TCC_OUTPUT_DLL) {
+ esym_index = s1->sym_attrs[sym_index].dyn_index;
+ qrel->r_offset = rel->r_offset;
+ if (esym_index) {
+ qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
+ qrel->r_addend = rel->r_addend;
+ qrel++;
+ break;
+ } else {
+ qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
+ qrel->r_addend = read64le(ptr) + val;
+ qrel++;
+ }
+ }
+ add64le(ptr, val);
+ break;
+ case R_X86_64_32:
+ case R_X86_64_32S:
+ if (s1->output_type == TCC_OUTPUT_DLL) {
+ /* XXX: this logic may depend on TCC's codegen
+ now TCC uses R_X86_64_32 even for a 64bit pointer */
+ qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
+ /* Use sign extension! */
+ qrel->r_addend = (int)read32le(ptr) + val;
+ qrel++;
+ }
+ add32le(ptr, val);
+ break;
+
+ case R_X86_64_PC32:
+ if (s1->output_type == TCC_OUTPUT_DLL) {
+ /* DLL relocation */
+ esym_index = s1->sym_attrs[sym_index].dyn_index;
+ if (esym_index) {
+ qrel->r_offset = rel->r_offset;
+ qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
+ /* Use sign extension! */
+ qrel->r_addend = (int)read32le(ptr) + rel->r_addend;
+ qrel++;
+ break;
+ }
+ }
+ goto plt32pc32;
+
+ case R_X86_64_PLT32:
+ /* fallthrough: val already holds the PLT slot address */
+
+ plt32pc32:
+ {
+ long long diff;
+ diff = (long long)val - addr;
+ if (diff < -2147483648LL || diff > 2147483647LL) {
+ tcc_error("internal error: relocation failed");
+ }
+ add32le(ptr, diff);
+ }
+ break;
+
+ case R_X86_64_PLTOFF64:
+ add64le(ptr, val - s1->got->sh_addr + rel->r_addend);
+ break;
+
+ case R_X86_64_PC64:
+ if (s1->output_type == TCC_OUTPUT_DLL) {
+ /* DLL relocation */
+ esym_index = s1->sym_attrs[sym_index].dyn_index;
+ if (esym_index) {
+ qrel->r_offset = rel->r_offset;
+ qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC64);
+ qrel->r_addend = read64le(ptr) + rel->r_addend;
+ qrel++;
+ break;
+ }
+ }
+ add64le(ptr, val - addr);
+ break;
+
+ case R_X86_64_GLOB_DAT:
+ case R_X86_64_JUMP_SLOT:
+ /* They don't need addend */
+ write64le(ptr, val - rel->r_addend);
+ break;
+ case R_X86_64_GOTPCREL:
+ case R_X86_64_GOTPCRELX:
+ case R_X86_64_REX_GOTPCRELX:
+ add32le(ptr, s1->got->sh_addr - addr +
+ s1->sym_attrs[sym_index].got_offset - 4);
+ break;
+ case R_X86_64_GOTPC32:
+ add32le(ptr, s1->got->sh_addr - addr + rel->r_addend);
+ break;
+ case R_X86_64_GOTPC64:
+ add64le(ptr, s1->got->sh_addr - addr + rel->r_addend);
+ break;
+ case R_X86_64_GOTTPOFF:
+ add32le(ptr, val - s1->got->sh_addr);
+ break;
+ case R_X86_64_GOT32:
+ /* we load the got offset */
+ add32le(ptr, s1->sym_attrs[sym_index].got_offset);
+ break;
+ case R_X86_64_GOT64:
+ /* we load the got offset */
+ add64le(ptr, s1->sym_attrs[sym_index].got_offset);
+ break;
+ case R_X86_64_GOTOFF64:
+ add64le(ptr, val - s1->got->sh_addr);
+ break;
+ case R_X86_64_RELATIVE:
+#ifdef TCC_TARGET_PE
+ add32le(ptr, val - s1->pe_imagebase);
+#endif
+ /* do nothing */
+ break;
+ }
+}
+
+#endif /* !TARGET_DEFS_ONLY */