From 826d1afd58c2e064a9c8fdb09eda1b08469de1a8 Mon Sep 17 00:00:00 2001 From: pommicket Date: Fri, 18 Feb 2022 12:36:57 -0500 Subject: newer version of tcc almost working --- 05/.gitignore | 1 + 05/macro_test.c | 40 - 05/main.c | 8 + 05/parse.b | 18 +- 05/stdc_common.h | 9 + 05/stdlib.h | 6 + 05/tcc-0.9.25/.cvsignore | 37 - 05/tcc-0.9.25/.gitignore | 4 - 05/tcc-0.9.25/COPYING | 504 -- 05/tcc-0.9.25/Changelog | 368 - 05/tcc-0.9.25/Makefile | 272 - 05/tcc-0.9.25/README | 90 - 05/tcc-0.9.25/TODO | 95 - 05/tcc-0.9.25/VERSION | 1 - 05/tcc-0.9.25/arm-gen.c | 1734 ----- 05/tcc-0.9.25/assert.h | 7 - 05/tcc-0.9.25/c67-gen.c | 2548 ------- 05/tcc-0.9.25/coff.h | 446 -- 05/tcc-0.9.25/config.h | 10 - 05/tcc-0.9.25/configure | 382 - 05/tcc-0.9.25/ctype.h | 92 - 05/tcc-0.9.25/elf.h | 1714 ----- 05/tcc-0.9.25/errno.h | 6 - 05/tcc-0.9.25/float.h | 34 - 05/tcc-0.9.25/i386-asm.c | 1211 ---- 05/tcc-0.9.25/i386-asm.h | 446 -- 05/tcc-0.9.25/i386-gen.c | 1034 --- 05/tcc-0.9.25/il-gen.c | 667 -- 05/tcc-0.9.25/il-opcodes.h | 251 - 05/tcc-0.9.25/include/float.h | 57 - 05/tcc-0.9.25/include/stdarg.h | 67 - 05/tcc-0.9.25/include/stdbool.h | 10 - 05/tcc-0.9.25/include/stddef.h | 20 - 05/tcc-0.9.25/include/tcclib.h | 78 - 05/tcc-0.9.25/include/varargs.h | 11 - 05/tcc-0.9.25/lib/alloca86-bt.S | 45 - 05/tcc-0.9.25/lib/alloca86.S | 33 - 05/tcc-0.9.25/lib/bcheck.c | 868 --- 05/tcc-0.9.25/lib/libtcc1.c | 607 -- 05/tcc-0.9.25/libtcc.c | 2276 ------ 05/tcc-0.9.25/libtcc.h | 108 - 05/tcc-0.9.25/limits.h | 6 - 05/tcc-0.9.25/locale.h | 60 - 05/tcc-0.9.25/math.h | 409 -- 05/tcc-0.9.25/setjmp.h | 21 - 05/tcc-0.9.25/signal.h | 253 - 05/tcc-0.9.25/stab.def | 238 - 05/tcc-0.9.25/stab.h | 17 - 05/tcc-0.9.25/stdarg.h | 10 - 05/tcc-0.9.25/stdc_common.h | 684 -- 05/tcc-0.9.25/stddef.h | 8 - 05/tcc-0.9.25/stdio.h | 2270 ------ 05/tcc-0.9.25/stdlib.h | 193 - 05/tcc-0.9.25/string.h | 185 - 05/tcc-0.9.25/tcc-doc.html | 2241 ------ 05/tcc-0.9.25/tcc-doc.texi | 1227 ---- 05/tcc-0.9.25/tcc.c | 556 -- 05/tcc-0.9.25/tcc.h | 764 -- 05/tcc-0.9.25/tccasm.c | 1021 --- 05/tcc-0.9.25/tcccoff.c | 957 --- 05/tcc-0.9.25/tccelf.c | 2732 -------- 05/tcc-0.9.25/tccgen.c | 5123 -------------- 05/tcc-0.9.25/tccpe.c | 1559 ----- 05/tcc-0.9.25/tccpp.c | 2936 -------- 05/tcc-0.9.25/tcctok.h | 469 -- 05/tcc-0.9.25/texi2pod.pl | 427 -- 05/tcc-0.9.25/time.h | 293 - 05/tcc-0.9.25/x86_64-gen.c | 1419 ---- 05/tcc-0.9.27/.gitignore | 57 + 05/tcc-0.9.27/COPYING | 504 ++ 05/tcc-0.9.27/Changelog | 439 ++ 05/tcc-0.9.27/CodingStyle | 71 + 05/tcc-0.9.27/Makefile | 403 ++ 05/tcc-0.9.27/README | 95 + 05/tcc-0.9.27/RELICENSING | 60 + 05/tcc-0.9.27/TODO | 100 + 05/tcc-0.9.27/VERSION | 1 + 05/tcc-0.9.27/arm-asm.c | 94 + 05/tcc-0.9.27/arm-gen.c | 2151 ++++++ 05/tcc-0.9.27/arm-link.c | 398 ++ 05/tcc-0.9.27/arm64-gen.c | 1837 +++++ 05/tcc-0.9.27/arm64-link.c | 256 + 05/tcc-0.9.27/assert.h | 7 + 05/tcc-0.9.27/c67-gen.c | 2540 +++++++ 05/tcc-0.9.27/c67-link.c | 131 + 05/tcc-0.9.27/coff.h | 446 ++ 05/tcc-0.9.27/configure | 527 ++ 05/tcc-0.9.27/ctype.h | 92 + 05/tcc-0.9.27/elf.h | 3240 +++++++++ 05/tcc-0.9.27/errno.h | 6 + 05/tcc-0.9.27/examples/ex1.c | 8 + 05/tcc-0.9.27/examples/ex2.c | 98 + 05/tcc-0.9.27/examples/ex3.c | 23 + 05/tcc-0.9.27/examples/ex4.c | 26 + 05/tcc-0.9.27/examples/ex5.c | 8 + 05/tcc-0.9.27/float.h | 34 + 05/tcc-0.9.27/i386-asm.c | 1725 +++++ 05/tcc-0.9.27/i386-asm.h | 480 ++ 05/tcc-0.9.27/i386-gen.c | 1164 +++ 05/tcc-0.9.27/i386-link.c | 247 + 05/tcc-0.9.27/i386-tok.h | 253 + 05/tcc-0.9.27/il-gen.c | 657 ++ 05/tcc-0.9.27/il-opcodes.h | 251 + 05/tcc-0.9.27/include/float.h | 57 + 05/tcc-0.9.27/include/stdarg.h | 79 + 05/tcc-0.9.27/include/stdbool.h | 11 + 05/tcc-0.9.27/include/stddef.h | 54 + 05/tcc-0.9.27/include/varargs.h | 12 + 05/tcc-0.9.27/lib/Makefile | 73 + 05/tcc-0.9.27/lib/alloca-arm.S | 17 + 05/tcc-0.9.27/lib/alloca86-bt.S | 47 + 05/tcc-0.9.27/lib/alloca86.S | 31 + 05/tcc-0.9.27/lib/alloca86_64-bt.S | 56 + 05/tcc-0.9.27/lib/alloca86_64.S | 34 + 05/tcc-0.9.27/lib/armeabi.c | 501 ++ 05/tcc-0.9.27/lib/armflush.c | 58 + 05/tcc-0.9.27/lib/bcheck.c | 979 +++ 05/tcc-0.9.27/lib/lib-arm64.c | 664 ++ 05/tcc-0.9.27/lib/libtcc1.c | 622 ++ 05/tcc-0.9.27/lib/va_list.c | 65 + 05/tcc-0.9.27/libtcc.c | 1998 ++++++ 05/tcc-0.9.27/libtcc.h | 100 + 05/tcc-0.9.27/limits.h | 6 + 05/tcc-0.9.27/locale.h | 60 + 05/tcc-0.9.27/math.h | 409 ++ 05/tcc-0.9.27/setjmp.h | 21 + 05/tcc-0.9.27/signal.h | 253 + 05/tcc-0.9.27/stab.def | 234 + 05/tcc-0.9.27/stab.h | 17 + 05/tcc-0.9.27/stdarg.h | 10 + 05/tcc-0.9.27/stdc_common.h | 693 ++ 05/tcc-0.9.27/stddef.h | 8 + 05/tcc-0.9.27/stdio.h | 2270 ++++++ 05/tcc-0.9.27/stdlib.h | 199 + 05/tcc-0.9.27/string.h | 185 + 05/tcc-0.9.27/tcc-doc.texi | 1326 ++++ 05/tcc-0.9.27/tcc.c | 371 + 05/tcc-0.9.27/tcc.h | 1754 +++++ 05/tcc-0.9.27/tccasm.c | 1277 ++++ 05/tcc-0.9.27/tcccoff.c | 948 +++ 05/tcc-0.9.27/tccelf.c | 3060 ++++++++ 05/tcc-0.9.27/tccgen.c | 7388 ++++++++++++++++++++ 05/tcc-0.9.27/tcclib.h | 80 + 05/tcc-0.9.27/tccpe.c | 1996 ++++++ 05/tcc-0.9.27/tccpp.c | 3907 +++++++++++ 05/tcc-0.9.27/tccrun.c | 844 +++ 05/tcc-0.9.27/tcctok.h | 1641 +++++ 05/tcc-0.9.27/tcctools.c | 546 ++ 05/tcc-0.9.27/tests/42test.h | 13 + 05/tcc-0.9.27/tests/Makefile | 289 + 05/tcc-0.9.27/tests/abitest.c | 691 ++ 05/tcc-0.9.27/tests/asm-c-connect-1.c | 57 + 05/tcc-0.9.27/tests/asm-c-connect-2.c | 36 + 05/tcc-0.9.27/tests/asmtest.S | 978 +++ 05/tcc-0.9.27/tests/boundtest.c | 285 + 05/tcc-0.9.27/tests/gcctestsuite.sh | 33 + 05/tcc-0.9.27/tests/libtcc_test.c | 96 + 05/tcc-0.9.27/tests/pp/01.c | 6 + 05/tcc-0.9.27/tests/pp/01.expect | 1 + 05/tcc-0.9.27/tests/pp/02.c | 28 + 05/tcc-0.9.27/tests/pp/02.expect | 5 + 05/tcc-0.9.27/tests/pp/03.c | 15 + 05/tcc-0.9.27/tests/pp/03.expect | 5 + 05/tcc-0.9.27/tests/pp/04.c | 4 + 05/tcc-0.9.27/tests/pp/04.expect | 1 + 05/tcc-0.9.27/tests/pp/05.c | 7 + 05/tcc-0.9.27/tests/pp/05.expect | 3 + 05/tcc-0.9.27/tests/pp/06.c | 5 + 05/tcc-0.9.27/tests/pp/06.expect | 1 + 05/tcc-0.9.27/tests/pp/07.c | 4 + 05/tcc-0.9.27/tests/pp/07.expect | 2 + 05/tcc-0.9.27/tests/pp/08.c | 4 + 05/tcc-0.9.27/tests/pp/08.expect | 1 + 05/tcc-0.9.27/tests/pp/09.c | 4 + 05/tcc-0.9.27/tests/pp/09.expect | 1 + 05/tcc-0.9.27/tests/pp/10.c | 10 + 05/tcc-0.9.27/tests/pp/10.expect | 5 + 05/tcc-0.9.27/tests/pp/11.c | 31 + 05/tcc-0.9.27/tests/pp/11.expect | 15 + 05/tcc-0.9.27/tests/pp/12.S | 8 + 05/tcc-0.9.27/tests/pp/12.expect | 2 + 05/tcc-0.9.27/tests/pp/13.S | 6 + 05/tcc-0.9.27/tests/pp/13.expect | 2 + 05/tcc-0.9.27/tests/pp/14.c | 13 + 05/tcc-0.9.27/tests/pp/14.expect | 3 + 05/tcc-0.9.27/tests/pp/15.c | 18 + 05/tcc-0.9.27/tests/pp/15.expect | 5 + 05/tcc-0.9.27/tests/pp/16.c | 3 + 05/tcc-0.9.27/tests/pp/16.expect | 2 + 05/tcc-0.9.27/tests/pp/17.c | 14 + 05/tcc-0.9.27/tests/pp/17.expect | 6 + 05/tcc-0.9.27/tests/pp/18.c | 15 + 05/tcc-0.9.27/tests/pp/18.expect | 3 + 05/tcc-0.9.27/tests/pp/19.c | 101 + 05/tcc-0.9.27/tests/pp/19.expect | 14 + 05/tcc-0.9.27/tests/pp/20.c | 13 + 05/tcc-0.9.27/tests/pp/20.expect | 6 + 05/tcc-0.9.27/tests/pp/21.c | 36 + 05/tcc-0.9.27/tests/pp/21.expect | 8 + 05/tcc-0.9.27/tests/pp/Makefile | 49 + 05/tcc-0.9.27/tests/pp/pp-counter.c | 27 + 05/tcc-0.9.27/tests/pp/pp-counter.expect | 15 + 05/tcc-0.9.27/tests/tcctest.c | 3871 ++++++++++ 05/tcc-0.9.27/tests/tcctest.h | 9 + 05/tcc-0.9.27/tests/testfp.c | 510 ++ 05/tcc-0.9.27/tests/tests2/00_assignment.c | 18 + 05/tcc-0.9.27/tests/tests2/00_assignment.expect | 3 + 05/tcc-0.9.27/tests/tests2/01_comment.c | 14 + 05/tcc-0.9.27/tests/tests2/01_comment.expect | 5 + 05/tcc-0.9.27/tests/tests2/02_printf.c | 18 + 05/tcc-0.9.27/tests/tests2/02_printf.expect | 15 + 05/tcc-0.9.27/tests/tests2/03_struct.c | 31 + 05/tcc-0.9.27/tests/tests2/03_struct.expect | 6 + 05/tcc-0.9.27/tests/tests2/04_for.c | 15 + 05/tcc-0.9.27/tests/tests2/04_for.expect | 10 + 05/tcc-0.9.27/tests/tests2/05_array.c | 21 + 05/tcc-0.9.27/tests/tests2/05_array.expect | 10 + 05/tcc-0.9.27/tests/tests2/06_case.c | 29 + 05/tcc-0.9.27/tests/tests2/06_case.expect | 8 + 05/tcc-0.9.27/tests/tests2/07_function.c | 30 + 05/tcc-0.9.27/tests/tests2/07_function.expect | 4 + 05/tcc-0.9.27/tests/tests2/08_while.c | 24 + 05/tcc-0.9.27/tests/tests2/08_while.expect | 11 + 05/tcc-0.9.27/tests/tests2/09_do_while.c | 24 + 05/tcc-0.9.27/tests/tests2/09_do_while.expect | 11 + 05/tcc-0.9.27/tests/tests2/10_pointer.c | 40 + 05/tcc-0.9.27/tests/tests2/10_pointer.expect | 8 + 05/tcc-0.9.27/tests/tests2/11_precedence.c | 40 + 05/tcc-0.9.27/tests/tests2/11_precedence.expect | 15 + 05/tcc-0.9.27/tests/tests2/12_hashdefine.c | 14 + 05/tcc-0.9.27/tests/tests2/12_hashdefine.expect | 2 + 05/tcc-0.9.27/tests/tests2/13_integer_literals.c | 20 + .../tests/tests2/13_integer_literals.expect | 5 + 05/tcc-0.9.27/tests/tests2/14_if.c | 21 + 05/tcc-0.9.27/tests/tests2/14_if.expect | 2 + 05/tcc-0.9.27/tests/tests2/15_recursion.c | 21 + 05/tcc-0.9.27/tests/tests2/15_recursion.expect | 10 + 05/tcc-0.9.27/tests/tests2/16_nesting.c | 21 + 05/tcc-0.9.27/tests/tests2/16_nesting.expect | 18 + 05/tcc-0.9.27/tests/tests2/17_enum.c | 72 + 05/tcc-0.9.27/tests/tests2/17_enum.expect | 4 + 05/tcc-0.9.27/tests/tests2/18_include.c | 12 + 05/tcc-0.9.27/tests/tests2/18_include.expect | 3 + 05/tcc-0.9.27/tests/tests2/18_include.h | 1 + 05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c | 28 + .../tests/tests2/19_pointer_arithmetic.expect | 3 + 05/tcc-0.9.27/tests/tests2/20_pointer_comparison.c | 24 + .../tests/tests2/20_pointer_comparison.expect | 6 + 05/tcc-0.9.27/tests/tests2/21_char_array.c | 33 + 05/tcc-0.9.27/tests/tests2/21_char_array.expect | 7 + 05/tcc-0.9.27/tests/tests2/22_floating_point.c | 50 + .../tests/tests2/22_floating_point.expect | 16 + 05/tcc-0.9.27/tests/tests2/23_type_coercion.c | 54 + 05/tcc-0.9.27/tests/tests2/23_type_coercion.expect | 12 + 05/tcc-0.9.27/tests/tests2/24_math_library.c | 30 + 05/tcc-0.9.27/tests/tests2/24_math_library.expect | 18 + 05/tcc-0.9.27/tests/tests2/25_quicksort.c | 83 + 05/tcc-0.9.27/tests/tests2/25_quicksort.expect | 2 + .../tests/tests2/26_character_constants.c | 17 + .../tests/tests2/26_character_constants.expect | 8 + 05/tcc-0.9.27/tests/tests2/27_sizeof.c | 18 + 05/tcc-0.9.27/tests/tests2/27_sizeof.expect | 4 + 05/tcc-0.9.27/tests/tests2/28_strings.c | 45 + 05/tcc-0.9.27/tests/tests2/28_strings.expect | 19 + 05/tcc-0.9.27/tests/tests2/29_array_address.c | 13 + 05/tcc-0.9.27/tests/tests2/29_array_address.expect | 1 + 05/tcc-0.9.27/tests/tests2/30_hanoi.c | 122 + 05/tcc-0.9.27/tests/tests2/30_hanoi.expect | 71 + 05/tcc-0.9.27/tests/tests2/31_args.c | 14 + 05/tcc-0.9.27/tests/tests2/31_args.expect | 6 + 05/tcc-0.9.27/tests/tests2/32_led.c | 266 + 05/tcc-0.9.27/tests/tests2/32_led.expect | 4 + 05/tcc-0.9.27/tests/tests2/33_ternary_op.c | 15 + 05/tcc-0.9.27/tests/tests2/33_ternary_op.expect | 10 + 05/tcc-0.9.27/tests/tests2/34_array_assignment.c | 23 + .../tests/tests2/34_array_assignment.expect | 2 + 05/tcc-0.9.27/tests/tests2/35_sizeof.c | 14 + 05/tcc-0.9.27/tests/tests2/35_sizeof.expect | 2 + 05/tcc-0.9.27/tests/tests2/36_array_initialisers.c | 21 + .../tests/tests2/36_array_initialisers.expect | 20 + 05/tcc-0.9.27/tests/tests2/37_sprintf.c | 17 + 05/tcc-0.9.27/tests/tests2/37_sprintf.expect | 20 + .../tests/tests2/38_multiple_array_index.c | 32 + .../tests/tests2/38_multiple_array_index.expect | 4 + 05/tcc-0.9.27/tests/tests2/39_typedef.c | 65 + 05/tcc-0.9.27/tests/tests2/39_typedef.expect | 3 + 05/tcc-0.9.27/tests/tests2/40_stdio.c | 52 + 05/tcc-0.9.27/tests/tests2/40_stdio.expect | 27 + 05/tcc-0.9.27/tests/tests2/41_hashif.c | 85 + 05/tcc-0.9.27/tests/tests2/41_hashif.expect | 6 + 05/tcc-0.9.27/tests/tests2/42_function_pointer.c | 22 + .../tests/tests2/42_function_pointer.expect | 2 + 05/tcc-0.9.27/tests/tests2/43_void_param.c | 15 + 05/tcc-0.9.27/tests/tests2/43_void_param.expect | 1 + .../tests/tests2/44_scoped_declarations.c | 17 + .../tests/tests2/44_scoped_declarations.expect | 1 + 05/tcc-0.9.27/tests/tests2/45_empty_for.c | 18 + 05/tcc-0.9.27/tests/tests2/45_empty_for.expect | 10 + 05/tcc-0.9.27/tests/tests2/46_grep.c | 568 ++ 05/tcc-0.9.27/tests/tests2/46_grep.expect | 3 + 05/tcc-0.9.27/tests/tests2/47_switch_return.c | 24 + 05/tcc-0.9.27/tests/tests2/47_switch_return.expect | 4 + 05/tcc-0.9.27/tests/tests2/48_nested_break.c | 26 + 05/tcc-0.9.27/tests/tests2/48_nested_break.expect | 1 + 05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c | 23 + .../tests/tests2/49_bracket_evaluation.expect | 1 + 05/tcc-0.9.27/tests/tests2/50_logical_second_arg.c | 29 + .../tests/tests2/50_logical_second_arg.expect | 20 + 05/tcc-0.9.27/tests/tests2/51_static.c | 30 + 05/tcc-0.9.27/tests/tests2/51_static.expect | 8 + 05/tcc-0.9.27/tests/tests2/52_unnamed_enum.c | 27 + 05/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect | 9 + 05/tcc-0.9.27/tests/tests2/54_goto.c | 56 + 05/tcc-0.9.27/tests/tests2/54_goto.expect | 8 + 05/tcc-0.9.27/tests/tests2/55_lshift_type.c | 52 + 05/tcc-0.9.27/tests/tests2/55_lshift_type.expect | 1 + .../tests/tests2/60_errors_and_warnings.c | 51 + .../tests/tests2/60_errors_and_warnings.expect | 28 + 05/tcc-0.9.27/tests/tests2/64_macro_nesting.c | 12 + 05/tcc-0.9.27/tests/tests2/64_macro_nesting.expect | 1 + 05/tcc-0.9.27/tests/tests2/67_macro_concat.c | 14 + 05/tcc-0.9.27/tests/tests2/67_macro_concat.expect | 2 + .../tests/tests2/70_floating_point_literals.c | 77 + .../tests/tests2/70_floating_point_literals.expect | 53 + 05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c | 9 + .../tests/tests2/71_macro_empty_arg.expect | 1 + 05/tcc-0.9.27/tests/tests2/72_long_long_constant.c | 19 + .../tests/tests2/72_long_long_constant.expect | 1 + 05/tcc-0.9.27/tests/tests2/73_arm64.c | 527 ++ 05/tcc-0.9.27/tests/tests2/73_arm64.expect | 174 + .../tests/tests2/75_array_in_struct_init.c | 33 + .../tests/tests2/75_array_in_struct_init.expect | 72 + .../tests/tests2/76_dollars_in_identifiers.c | 41 + .../tests/tests2/76_dollars_in_identifiers.expect | 14 + 05/tcc-0.9.27/tests/tests2/77_push_pop_macro.c | 30 + .../tests/tests2/77_push_pop_macro.expect | 5 + 05/tcc-0.9.27/tests/tests2/78_vla_label.c | 45 + 05/tcc-0.9.27/tests/tests2/78_vla_label.expect | 6 + 05/tcc-0.9.27/tests/tests2/79_vla_continue.c | 116 + 05/tcc-0.9.27/tests/tests2/79_vla_continue.expect | 5 + 05/tcc-0.9.27/tests/tests2/80_flexarray.c | 25 + 05/tcc-0.9.27/tests/tests2/80_flexarray.expect | 0 05/tcc-0.9.27/tests/tests2/81_types.c | 43 + 05/tcc-0.9.27/tests/tests2/81_types.expect | 0 05/tcc-0.9.27/tests/tests2/82_attribs_position.c | 19 + .../tests/tests2/82_attribs_position.expect | 0 .../tests/tests2/83_utf8_in_identifiers.c | 9 + .../tests/tests2/83_utf8_in_identifiers.expect | 2 + 05/tcc-0.9.27/tests/tests2/84_hex-float.c | 12 + 05/tcc-0.9.27/tests/tests2/84_hex-float.expect | 1 + .../tests/tests2/85_asm-outside-function.c | 9 + .../tests/tests2/85_asm-outside-function.expect | 1 + 05/tcc-0.9.27/tests/tests2/86_memory-model.c | 38 + 05/tcc-0.9.27/tests/tests2/86_memory-model.expect | 1 + 05/tcc-0.9.27/tests/tests2/87_dead_code.c | 122 + 05/tcc-0.9.27/tests/tests2/87_dead_code.expect | 18 + 05/tcc-0.9.27/tests/tests2/88_codeopt.c | 68 + 05/tcc-0.9.27/tests/tests2/88_codeopt.expect | 2 + 05/tcc-0.9.27/tests/tests2/89_nocode_wanted.c | 112 + 05/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect | 14 + 05/tcc-0.9.27/tests/tests2/90_struct-init.c | 282 + 05/tcc-0.9.27/tests/tests2/90_struct-init.expect | 43 + .../tests/tests2/91_ptr_longlong_arith32.c | 15 + .../tests/tests2/91_ptr_longlong_arith32.expect | 1 + 05/tcc-0.9.27/tests/tests2/92_enum_bitfield.c | 57 + 05/tcc-0.9.27/tests/tests2/92_enum_bitfield.expect | 0 05/tcc-0.9.27/tests/tests2/93_integer_promotion.c | 71 + .../tests/tests2/93_integer_promotion.expect | 46 + 05/tcc-0.9.27/tests/tests2/94_generic.c | 64 + 05/tcc-0.9.27/tests/tests2/94_generic.expect | 13 + 05/tcc-0.9.27/tests/tests2/95_bitfields.c | 218 + 05/tcc-0.9.27/tests/tests2/95_bitfields.expect | 149 + 05/tcc-0.9.27/tests/tests2/95_bitfields_ms.c | 2 + 05/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect | 149 + 05/tcc-0.9.27/tests/tests2/96_nodata_wanted.c | 84 + 05/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect | 23 + .../tests/tests2/97_utf8_string_literal.c | 12 + .../tests/tests2/97_utf8_string_literal.expect | 1 + 05/tcc-0.9.27/tests/tests2/98_al_ax_extend.c | 41 + 05/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect | 9 + 05/tcc-0.9.27/tests/tests2/99_fastcall.c | 276 + 05/tcc-0.9.27/tests/tests2/99_fastcall.expect | 1 + 05/tcc-0.9.27/tests/tests2/LICENSE | 37 + 05/tcc-0.9.27/tests/tests2/Makefile | 112 + 05/tcc-0.9.27/tests/vla_test.c | 84 + 05/tcc-0.9.27/texi2pod.pl | 427 ++ 05/tcc-0.9.27/time.h | 293 + 05/tcc-0.9.27/win32/build-tcc.bat | 189 + 05/tcc-0.9.27/win32/examples/dll.c | 13 + 05/tcc-0.9.27/win32/examples/fib.c | 24 + 05/tcc-0.9.27/win32/examples/hello_dll.c | 20 + 05/tcc-0.9.27/win32/examples/hello_win.c | 163 + 05/tcc-0.9.27/win32/include/_mingw.h | 170 + 05/tcc-0.9.27/win32/include/assert.h | 57 + 05/tcc-0.9.27/win32/include/conio.h | 409 ++ 05/tcc-0.9.27/win32/include/ctype.h | 281 + 05/tcc-0.9.27/win32/include/dir.h | 31 + 05/tcc-0.9.27/win32/include/direct.h | 68 + 05/tcc-0.9.27/win32/include/dirent.h | 135 + 05/tcc-0.9.27/win32/include/dos.h | 55 + 05/tcc-0.9.27/win32/include/errno.h | 75 + 05/tcc-0.9.27/win32/include/excpt.h | 123 + 05/tcc-0.9.27/win32/include/fcntl.h | 52 + 05/tcc-0.9.27/win32/include/fenv.h | 108 + 05/tcc-0.9.27/win32/include/inttypes.h | 297 + 05/tcc-0.9.27/win32/include/io.h | 418 ++ 05/tcc-0.9.27/win32/include/limits.h | 111 + 05/tcc-0.9.27/win32/include/locale.h | 91 + 05/tcc-0.9.27/win32/include/malloc.h | 181 + 05/tcc-0.9.27/win32/include/math.h | 737 ++ 05/tcc-0.9.27/win32/include/mem.h | 13 + 05/tcc-0.9.27/win32/include/memory.h | 40 + 05/tcc-0.9.27/win32/include/process.h | 176 + 05/tcc-0.9.27/win32/include/sec_api/conio_s.h | 42 + 05/tcc-0.9.27/win32/include/sec_api/crtdbg_s.h | 19 + 05/tcc-0.9.27/win32/include/sec_api/io_s.h | 33 + 05/tcc-0.9.27/win32/include/sec_api/mbstring_s.h | 52 + 05/tcc-0.9.27/win32/include/sec_api/search_s.h | 25 + 05/tcc-0.9.27/win32/include/sec_api/stdio_s.h | 145 + 05/tcc-0.9.27/win32/include/sec_api/stdlib_s.h | 67 + 05/tcc-0.9.27/win32/include/sec_api/stralign_s.h | 30 + 05/tcc-0.9.27/win32/include/sec_api/string_s.h | 41 + 05/tcc-0.9.27/win32/include/sec_api/sys/timeb_s.h | 34 + 05/tcc-0.9.27/win32/include/sec_api/tchar_s.h | 266 + 05/tcc-0.9.27/win32/include/sec_api/time_s.h | 61 + 05/tcc-0.9.27/win32/include/sec_api/wchar_s.h | 128 + 05/tcc-0.9.27/win32/include/setjmp.h | 160 + 05/tcc-0.9.27/win32/include/share.h | 28 + 05/tcc-0.9.27/win32/include/signal.h | 63 + 05/tcc-0.9.27/win32/include/stdint.h | 212 + 05/tcc-0.9.27/win32/include/stdio.h | 429 ++ 05/tcc-0.9.27/win32/include/stdlib.h | 580 ++ 05/tcc-0.9.27/win32/include/string.h | 164 + 05/tcc-0.9.27/win32/include/sys/fcntl.h | 13 + 05/tcc-0.9.27/win32/include/sys/file.h | 14 + 05/tcc-0.9.27/win32/include/sys/locking.h | 30 + 05/tcc-0.9.27/win32/include/sys/stat.h | 290 + 05/tcc-0.9.27/win32/include/sys/time.h | 69 + 05/tcc-0.9.27/win32/include/sys/timeb.h | 133 + 05/tcc-0.9.27/win32/include/sys/types.h | 118 + 05/tcc-0.9.27/win32/include/sys/unistd.h | 14 + 05/tcc-0.9.27/win32/include/sys/utime.h | 146 + 05/tcc-0.9.27/win32/include/tchar.h | 1102 +++ 05/tcc-0.9.27/win32/include/time.h | 287 + 05/tcc-0.9.27/win32/include/vadefs.h | 11 + 05/tcc-0.9.27/win32/include/values.h | 4 + 05/tcc-0.9.27/win32/include/wchar.h | 873 +++ 05/tcc-0.9.27/win32/include/wctype.h | 172 + 05/tcc-0.9.27/win32/include/winapi/basetsd.h | 149 + 05/tcc-0.9.27/win32/include/winapi/basetyps.h | 85 + 05/tcc-0.9.27/win32/include/winapi/guiddef.h | 156 + 05/tcc-0.9.27/win32/include/winapi/poppack.h | 8 + 05/tcc-0.9.27/win32/include/winapi/pshpack1.h | 8 + 05/tcc-0.9.27/win32/include/winapi/pshpack2.h | 8 + 05/tcc-0.9.27/win32/include/winapi/pshpack4.h | 8 + 05/tcc-0.9.27/win32/include/winapi/pshpack8.h | 8 + 05/tcc-0.9.27/win32/include/winapi/winbase.h | 2951 ++++++++ 05/tcc-0.9.27/win32/include/winapi/wincon.h | 301 + 05/tcc-0.9.27/win32/include/winapi/windef.h | 293 + 05/tcc-0.9.27/win32/include/winapi/windows.h | 127 + 05/tcc-0.9.27/win32/include/winapi/winerror.h | 3166 +++++++++ 05/tcc-0.9.27/win32/include/winapi/wingdi.h | 4080 +++++++++++ 05/tcc-0.9.27/win32/include/winapi/winnt.h | 5835 ++++++++++++++++ 05/tcc-0.9.27/win32/include/winapi/winreg.h | 272 + 05/tcc-0.9.27/win32/include/winapi/winuser.h | 5651 +++++++++++++++ 05/tcc-0.9.27/win32/include/winapi/winver.h | 160 + 05/tcc-0.9.27/win32/lib/chkstk.S | 191 + 05/tcc-0.9.27/win32/lib/crt1.c | 79 + 05/tcc-0.9.27/win32/lib/crt1w.c | 3 + 05/tcc-0.9.27/win32/lib/dllcrt1.c | 13 + 05/tcc-0.9.27/win32/lib/dllmain.c | 9 + 05/tcc-0.9.27/win32/lib/gdi32.def | 337 + 05/tcc-0.9.27/win32/lib/kernel32.def | 770 ++ 05/tcc-0.9.27/win32/lib/msvcrt.def | 1399 ++++ 05/tcc-0.9.27/win32/lib/user32.def | 658 ++ 05/tcc-0.9.27/win32/lib/wincrt1.c | 75 + 05/tcc-0.9.27/win32/lib/wincrt1w.c | 3 + 05/tcc-0.9.27/win32/tcc-win32.txt | 168 + 05/tcc-0.9.27/x86_64-asm.h | 525 ++ 05/tcc-0.9.27/x86_64-gen.c | 2227 ++++++ 05/tcc-0.9.27/x86_64-link.c | 298 + 05/test.c | 6 + 05/test.s | 21 + 05/tests/macros.c | 40 + 484 files changed, 108149 insertions(+), 42255 deletions(-) delete mode 100644 05/macro_test.c delete mode 100644 05/tcc-0.9.25/.cvsignore delete mode 100644 05/tcc-0.9.25/.gitignore delete mode 100644 05/tcc-0.9.25/COPYING delete mode 100644 05/tcc-0.9.25/Changelog delete mode 100644 05/tcc-0.9.25/Makefile delete mode 100644 05/tcc-0.9.25/README delete mode 100644 05/tcc-0.9.25/TODO delete mode 100644 05/tcc-0.9.25/VERSION delete mode 100644 05/tcc-0.9.25/arm-gen.c delete mode 100644 05/tcc-0.9.25/assert.h delete mode 100644 05/tcc-0.9.25/c67-gen.c delete mode 100644 05/tcc-0.9.25/coff.h delete mode 100644 05/tcc-0.9.25/config.h delete mode 100755 05/tcc-0.9.25/configure delete mode 100644 05/tcc-0.9.25/ctype.h delete mode 100644 05/tcc-0.9.25/elf.h delete mode 100644 05/tcc-0.9.25/errno.h delete mode 100644 05/tcc-0.9.25/float.h delete mode 100644 05/tcc-0.9.25/i386-asm.c delete mode 100644 05/tcc-0.9.25/i386-asm.h delete mode 100644 05/tcc-0.9.25/i386-gen.c delete mode 100644 05/tcc-0.9.25/il-gen.c delete mode 100644 05/tcc-0.9.25/il-opcodes.h delete mode 100644 05/tcc-0.9.25/include/float.h delete mode 100644 05/tcc-0.9.25/include/stdarg.h delete mode 100644 05/tcc-0.9.25/include/stdbool.h delete mode 100644 05/tcc-0.9.25/include/stddef.h delete mode 100644 05/tcc-0.9.25/include/tcclib.h delete mode 100644 05/tcc-0.9.25/include/varargs.h delete mode 100644 05/tcc-0.9.25/lib/alloca86-bt.S delete mode 100644 05/tcc-0.9.25/lib/alloca86.S delete mode 100644 05/tcc-0.9.25/lib/bcheck.c delete mode 100644 05/tcc-0.9.25/lib/libtcc1.c delete mode 100644 05/tcc-0.9.25/libtcc.c delete mode 100644 05/tcc-0.9.25/libtcc.h delete mode 100644 05/tcc-0.9.25/limits.h delete mode 100644 05/tcc-0.9.25/locale.h delete mode 100644 05/tcc-0.9.25/math.h delete mode 100644 05/tcc-0.9.25/setjmp.h delete mode 100644 05/tcc-0.9.25/signal.h delete mode 100644 05/tcc-0.9.25/stab.def delete mode 100644 05/tcc-0.9.25/stab.h delete mode 100644 05/tcc-0.9.25/stdarg.h delete mode 100644 05/tcc-0.9.25/stdc_common.h delete mode 100644 05/tcc-0.9.25/stddef.h delete mode 100644 05/tcc-0.9.25/stdio.h delete mode 100644 05/tcc-0.9.25/stdlib.h delete mode 100644 05/tcc-0.9.25/string.h delete mode 100644 05/tcc-0.9.25/tcc-doc.html delete mode 100644 05/tcc-0.9.25/tcc-doc.texi delete mode 100644 05/tcc-0.9.25/tcc.c delete mode 100644 05/tcc-0.9.25/tcc.h delete mode 100644 05/tcc-0.9.25/tccasm.c delete mode 100644 05/tcc-0.9.25/tcccoff.c delete mode 100644 05/tcc-0.9.25/tccelf.c delete mode 100644 05/tcc-0.9.25/tccgen.c delete mode 100644 05/tcc-0.9.25/tccpe.c delete mode 100644 05/tcc-0.9.25/tccpp.c delete mode 100644 05/tcc-0.9.25/tcctok.h delete mode 100755 05/tcc-0.9.25/texi2pod.pl delete mode 100644 05/tcc-0.9.25/time.h delete mode 100644 05/tcc-0.9.25/x86_64-gen.c create mode 100644 05/tcc-0.9.27/.gitignore create mode 100644 05/tcc-0.9.27/COPYING create mode 100644 05/tcc-0.9.27/Changelog create mode 100644 05/tcc-0.9.27/CodingStyle create mode 100644 05/tcc-0.9.27/Makefile create mode 100644 05/tcc-0.9.27/README create mode 100644 05/tcc-0.9.27/RELICENSING create mode 100644 05/tcc-0.9.27/TODO create mode 100644 05/tcc-0.9.27/VERSION create mode 100644 05/tcc-0.9.27/arm-asm.c create mode 100644 05/tcc-0.9.27/arm-gen.c create mode 100644 05/tcc-0.9.27/arm-link.c create mode 100644 05/tcc-0.9.27/arm64-gen.c create mode 100644 05/tcc-0.9.27/arm64-link.c create mode 100644 05/tcc-0.9.27/assert.h create mode 100644 05/tcc-0.9.27/c67-gen.c create mode 100644 05/tcc-0.9.27/c67-link.c create mode 100644 05/tcc-0.9.27/coff.h create mode 100755 05/tcc-0.9.27/configure create mode 100644 05/tcc-0.9.27/ctype.h create mode 100644 05/tcc-0.9.27/elf.h create mode 100644 05/tcc-0.9.27/errno.h create mode 100755 05/tcc-0.9.27/examples/ex1.c create mode 100644 05/tcc-0.9.27/examples/ex2.c create mode 100644 05/tcc-0.9.27/examples/ex3.c create mode 100755 05/tcc-0.9.27/examples/ex4.c create mode 100644 05/tcc-0.9.27/examples/ex5.c create mode 100644 05/tcc-0.9.27/float.h create mode 100644 05/tcc-0.9.27/i386-asm.c create mode 100644 05/tcc-0.9.27/i386-asm.h create mode 100644 05/tcc-0.9.27/i386-gen.c create mode 100644 05/tcc-0.9.27/i386-link.c create mode 100644 05/tcc-0.9.27/i386-tok.h create mode 100644 05/tcc-0.9.27/il-gen.c create mode 100644 05/tcc-0.9.27/il-opcodes.h create mode 100644 05/tcc-0.9.27/include/float.h create mode 100644 05/tcc-0.9.27/include/stdarg.h create mode 100644 05/tcc-0.9.27/include/stdbool.h create mode 100644 05/tcc-0.9.27/include/stddef.h create mode 100644 05/tcc-0.9.27/include/varargs.h create mode 100644 05/tcc-0.9.27/lib/Makefile create mode 100644 05/tcc-0.9.27/lib/alloca-arm.S create mode 100644 05/tcc-0.9.27/lib/alloca86-bt.S create mode 100644 05/tcc-0.9.27/lib/alloca86.S create mode 100644 05/tcc-0.9.27/lib/alloca86_64-bt.S create mode 100644 05/tcc-0.9.27/lib/alloca86_64.S create mode 100644 05/tcc-0.9.27/lib/armeabi.c create mode 100644 05/tcc-0.9.27/lib/armflush.c create mode 100644 05/tcc-0.9.27/lib/bcheck.c create mode 100644 05/tcc-0.9.27/lib/lib-arm64.c create mode 100644 05/tcc-0.9.27/lib/libtcc1.c create mode 100644 05/tcc-0.9.27/lib/va_list.c create mode 100644 05/tcc-0.9.27/libtcc.c create mode 100644 05/tcc-0.9.27/libtcc.h create mode 100644 05/tcc-0.9.27/limits.h create mode 100644 05/tcc-0.9.27/locale.h create mode 100644 05/tcc-0.9.27/math.h create mode 100644 05/tcc-0.9.27/setjmp.h create mode 100644 05/tcc-0.9.27/signal.h create mode 100644 05/tcc-0.9.27/stab.def create mode 100644 05/tcc-0.9.27/stab.h create mode 100644 05/tcc-0.9.27/stdarg.h create mode 100644 05/tcc-0.9.27/stdc_common.h create mode 100644 05/tcc-0.9.27/stddef.h create mode 100644 05/tcc-0.9.27/stdio.h create mode 100644 05/tcc-0.9.27/stdlib.h create mode 100644 05/tcc-0.9.27/string.h create mode 100644 05/tcc-0.9.27/tcc-doc.texi create mode 100644 05/tcc-0.9.27/tcc.c create mode 100644 05/tcc-0.9.27/tcc.h create mode 100644 05/tcc-0.9.27/tccasm.c create mode 100644 05/tcc-0.9.27/tcccoff.c create mode 100644 05/tcc-0.9.27/tccelf.c create mode 100644 05/tcc-0.9.27/tccgen.c create mode 100644 05/tcc-0.9.27/tcclib.h create mode 100644 05/tcc-0.9.27/tccpe.c create mode 100644 05/tcc-0.9.27/tccpp.c create mode 100644 05/tcc-0.9.27/tccrun.c create mode 100644 05/tcc-0.9.27/tcctok.h create mode 100644 05/tcc-0.9.27/tcctools.c create mode 100644 05/tcc-0.9.27/tests/42test.h create mode 100644 05/tcc-0.9.27/tests/Makefile create mode 100644 05/tcc-0.9.27/tests/abitest.c create mode 100644 05/tcc-0.9.27/tests/asm-c-connect-1.c create mode 100644 05/tcc-0.9.27/tests/asm-c-connect-2.c create mode 100644 05/tcc-0.9.27/tests/asmtest.S create mode 100644 05/tcc-0.9.27/tests/boundtest.c create mode 100755 05/tcc-0.9.27/tests/gcctestsuite.sh create mode 100644 05/tcc-0.9.27/tests/libtcc_test.c create mode 100644 05/tcc-0.9.27/tests/pp/01.c create mode 100644 05/tcc-0.9.27/tests/pp/01.expect create mode 100644 05/tcc-0.9.27/tests/pp/02.c create mode 100644 05/tcc-0.9.27/tests/pp/02.expect create mode 100644 05/tcc-0.9.27/tests/pp/03.c create mode 100644 05/tcc-0.9.27/tests/pp/03.expect create mode 100644 05/tcc-0.9.27/tests/pp/04.c create mode 100644 05/tcc-0.9.27/tests/pp/04.expect create mode 100644 05/tcc-0.9.27/tests/pp/05.c create mode 100644 05/tcc-0.9.27/tests/pp/05.expect create mode 100644 05/tcc-0.9.27/tests/pp/06.c create mode 100644 05/tcc-0.9.27/tests/pp/06.expect create mode 100644 05/tcc-0.9.27/tests/pp/07.c create mode 100644 05/tcc-0.9.27/tests/pp/07.expect create mode 100644 05/tcc-0.9.27/tests/pp/08.c create mode 100644 05/tcc-0.9.27/tests/pp/08.expect create mode 100644 05/tcc-0.9.27/tests/pp/09.c create mode 100644 05/tcc-0.9.27/tests/pp/09.expect create mode 100644 05/tcc-0.9.27/tests/pp/10.c create mode 100644 05/tcc-0.9.27/tests/pp/10.expect create mode 100644 05/tcc-0.9.27/tests/pp/11.c create mode 100644 05/tcc-0.9.27/tests/pp/11.expect create mode 100644 05/tcc-0.9.27/tests/pp/12.S create mode 100644 05/tcc-0.9.27/tests/pp/12.expect create mode 100644 05/tcc-0.9.27/tests/pp/13.S create mode 100644 05/tcc-0.9.27/tests/pp/13.expect create mode 100644 05/tcc-0.9.27/tests/pp/14.c create mode 100644 05/tcc-0.9.27/tests/pp/14.expect create mode 100644 05/tcc-0.9.27/tests/pp/15.c create mode 100644 05/tcc-0.9.27/tests/pp/15.expect create mode 100644 05/tcc-0.9.27/tests/pp/16.c create mode 100644 05/tcc-0.9.27/tests/pp/16.expect create mode 100644 05/tcc-0.9.27/tests/pp/17.c create mode 100644 05/tcc-0.9.27/tests/pp/17.expect create mode 100644 05/tcc-0.9.27/tests/pp/18.c create mode 100644 05/tcc-0.9.27/tests/pp/18.expect create mode 100644 05/tcc-0.9.27/tests/pp/19.c create mode 100644 05/tcc-0.9.27/tests/pp/19.expect create mode 100644 05/tcc-0.9.27/tests/pp/20.c create mode 100644 05/tcc-0.9.27/tests/pp/20.expect create mode 100644 05/tcc-0.9.27/tests/pp/21.c create mode 100644 05/tcc-0.9.27/tests/pp/21.expect create mode 100644 05/tcc-0.9.27/tests/pp/Makefile create mode 100644 05/tcc-0.9.27/tests/pp/pp-counter.c create mode 100644 05/tcc-0.9.27/tests/pp/pp-counter.expect create mode 100644 05/tcc-0.9.27/tests/tcctest.c create mode 100644 05/tcc-0.9.27/tests/tcctest.h create mode 100644 05/tcc-0.9.27/tests/testfp.c create mode 100644 05/tcc-0.9.27/tests/tests2/00_assignment.c create mode 100644 05/tcc-0.9.27/tests/tests2/00_assignment.expect create mode 100644 05/tcc-0.9.27/tests/tests2/01_comment.c create mode 100644 05/tcc-0.9.27/tests/tests2/01_comment.expect create mode 100644 05/tcc-0.9.27/tests/tests2/02_printf.c create mode 100644 05/tcc-0.9.27/tests/tests2/02_printf.expect create mode 100644 05/tcc-0.9.27/tests/tests2/03_struct.c create mode 100644 05/tcc-0.9.27/tests/tests2/03_struct.expect create mode 100644 05/tcc-0.9.27/tests/tests2/04_for.c create mode 100644 05/tcc-0.9.27/tests/tests2/04_for.expect create mode 100644 05/tcc-0.9.27/tests/tests2/05_array.c create mode 100644 05/tcc-0.9.27/tests/tests2/05_array.expect create mode 100644 05/tcc-0.9.27/tests/tests2/06_case.c create mode 100644 05/tcc-0.9.27/tests/tests2/06_case.expect create mode 100644 05/tcc-0.9.27/tests/tests2/07_function.c create mode 100644 05/tcc-0.9.27/tests/tests2/07_function.expect create mode 100644 05/tcc-0.9.27/tests/tests2/08_while.c create mode 100644 05/tcc-0.9.27/tests/tests2/08_while.expect create mode 100644 05/tcc-0.9.27/tests/tests2/09_do_while.c create mode 100644 05/tcc-0.9.27/tests/tests2/09_do_while.expect create mode 100644 05/tcc-0.9.27/tests/tests2/10_pointer.c create mode 100644 05/tcc-0.9.27/tests/tests2/10_pointer.expect create mode 100644 05/tcc-0.9.27/tests/tests2/11_precedence.c create mode 100644 05/tcc-0.9.27/tests/tests2/11_precedence.expect create mode 100644 05/tcc-0.9.27/tests/tests2/12_hashdefine.c create mode 100644 05/tcc-0.9.27/tests/tests2/12_hashdefine.expect create mode 100644 05/tcc-0.9.27/tests/tests2/13_integer_literals.c create mode 100644 05/tcc-0.9.27/tests/tests2/13_integer_literals.expect create mode 100644 05/tcc-0.9.27/tests/tests2/14_if.c create mode 100644 05/tcc-0.9.27/tests/tests2/14_if.expect create mode 100644 05/tcc-0.9.27/tests/tests2/15_recursion.c create mode 100644 05/tcc-0.9.27/tests/tests2/15_recursion.expect create mode 100644 05/tcc-0.9.27/tests/tests2/16_nesting.c create mode 100644 05/tcc-0.9.27/tests/tests2/16_nesting.expect create mode 100644 05/tcc-0.9.27/tests/tests2/17_enum.c create mode 100644 05/tcc-0.9.27/tests/tests2/17_enum.expect create mode 100644 05/tcc-0.9.27/tests/tests2/18_include.c create mode 100644 05/tcc-0.9.27/tests/tests2/18_include.expect create mode 100644 05/tcc-0.9.27/tests/tests2/18_include.h create mode 100644 05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c create mode 100644 05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect create mode 100644 05/tcc-0.9.27/tests/tests2/20_pointer_comparison.c create mode 100644 05/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect create mode 100644 05/tcc-0.9.27/tests/tests2/21_char_array.c create mode 100644 05/tcc-0.9.27/tests/tests2/21_char_array.expect create mode 100644 05/tcc-0.9.27/tests/tests2/22_floating_point.c create mode 100644 05/tcc-0.9.27/tests/tests2/22_floating_point.expect create mode 100644 05/tcc-0.9.27/tests/tests2/23_type_coercion.c create mode 100644 05/tcc-0.9.27/tests/tests2/23_type_coercion.expect create mode 100644 05/tcc-0.9.27/tests/tests2/24_math_library.c create mode 100644 05/tcc-0.9.27/tests/tests2/24_math_library.expect create mode 100644 05/tcc-0.9.27/tests/tests2/25_quicksort.c create mode 100644 05/tcc-0.9.27/tests/tests2/25_quicksort.expect create mode 100644 05/tcc-0.9.27/tests/tests2/26_character_constants.c create mode 100644 05/tcc-0.9.27/tests/tests2/26_character_constants.expect create mode 100644 05/tcc-0.9.27/tests/tests2/27_sizeof.c create mode 100644 05/tcc-0.9.27/tests/tests2/27_sizeof.expect create mode 100644 05/tcc-0.9.27/tests/tests2/28_strings.c create mode 100644 05/tcc-0.9.27/tests/tests2/28_strings.expect create mode 100644 05/tcc-0.9.27/tests/tests2/29_array_address.c create mode 100644 05/tcc-0.9.27/tests/tests2/29_array_address.expect create mode 100644 05/tcc-0.9.27/tests/tests2/30_hanoi.c create mode 100644 05/tcc-0.9.27/tests/tests2/30_hanoi.expect create mode 100644 05/tcc-0.9.27/tests/tests2/31_args.c create mode 100644 05/tcc-0.9.27/tests/tests2/31_args.expect create mode 100644 05/tcc-0.9.27/tests/tests2/32_led.c create mode 100644 05/tcc-0.9.27/tests/tests2/32_led.expect create mode 100644 05/tcc-0.9.27/tests/tests2/33_ternary_op.c create mode 100644 05/tcc-0.9.27/tests/tests2/33_ternary_op.expect create mode 100644 05/tcc-0.9.27/tests/tests2/34_array_assignment.c create mode 100644 05/tcc-0.9.27/tests/tests2/34_array_assignment.expect create mode 100644 05/tcc-0.9.27/tests/tests2/35_sizeof.c create mode 100644 05/tcc-0.9.27/tests/tests2/35_sizeof.expect create mode 100644 05/tcc-0.9.27/tests/tests2/36_array_initialisers.c create mode 100644 05/tcc-0.9.27/tests/tests2/36_array_initialisers.expect create mode 100644 05/tcc-0.9.27/tests/tests2/37_sprintf.c create mode 100644 05/tcc-0.9.27/tests/tests2/37_sprintf.expect create mode 100644 05/tcc-0.9.27/tests/tests2/38_multiple_array_index.c create mode 100644 05/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect create mode 100644 05/tcc-0.9.27/tests/tests2/39_typedef.c create mode 100644 05/tcc-0.9.27/tests/tests2/39_typedef.expect create mode 100644 05/tcc-0.9.27/tests/tests2/40_stdio.c create mode 100644 05/tcc-0.9.27/tests/tests2/40_stdio.expect create mode 100644 05/tcc-0.9.27/tests/tests2/41_hashif.c create mode 100644 05/tcc-0.9.27/tests/tests2/41_hashif.expect create mode 100644 05/tcc-0.9.27/tests/tests2/42_function_pointer.c create mode 100644 05/tcc-0.9.27/tests/tests2/42_function_pointer.expect create mode 100644 05/tcc-0.9.27/tests/tests2/43_void_param.c create mode 100644 05/tcc-0.9.27/tests/tests2/43_void_param.expect create mode 100644 05/tcc-0.9.27/tests/tests2/44_scoped_declarations.c create mode 100644 05/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect create mode 100644 05/tcc-0.9.27/tests/tests2/45_empty_for.c create mode 100644 05/tcc-0.9.27/tests/tests2/45_empty_for.expect create mode 100644 05/tcc-0.9.27/tests/tests2/46_grep.c create mode 100644 05/tcc-0.9.27/tests/tests2/46_grep.expect create mode 100644 05/tcc-0.9.27/tests/tests2/47_switch_return.c create mode 100644 05/tcc-0.9.27/tests/tests2/47_switch_return.expect create mode 100644 05/tcc-0.9.27/tests/tests2/48_nested_break.c create mode 100644 05/tcc-0.9.27/tests/tests2/48_nested_break.expect create mode 100644 05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c create mode 100644 05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect create mode 100644 05/tcc-0.9.27/tests/tests2/50_logical_second_arg.c create mode 100644 05/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect create mode 100644 05/tcc-0.9.27/tests/tests2/51_static.c create mode 100644 05/tcc-0.9.27/tests/tests2/51_static.expect create mode 100644 05/tcc-0.9.27/tests/tests2/52_unnamed_enum.c create mode 100644 05/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect create mode 100644 05/tcc-0.9.27/tests/tests2/54_goto.c create mode 100644 05/tcc-0.9.27/tests/tests2/54_goto.expect create mode 100644 05/tcc-0.9.27/tests/tests2/55_lshift_type.c create mode 100644 05/tcc-0.9.27/tests/tests2/55_lshift_type.expect create mode 100644 05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c create mode 100644 05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect create mode 100644 05/tcc-0.9.27/tests/tests2/64_macro_nesting.c create mode 100644 05/tcc-0.9.27/tests/tests2/64_macro_nesting.expect create mode 100644 05/tcc-0.9.27/tests/tests2/67_macro_concat.c create mode 100644 05/tcc-0.9.27/tests/tests2/67_macro_concat.expect create mode 100644 05/tcc-0.9.27/tests/tests2/70_floating_point_literals.c create mode 100644 05/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect create mode 100644 05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c create mode 100644 05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect create mode 100644 05/tcc-0.9.27/tests/tests2/72_long_long_constant.c create mode 100644 05/tcc-0.9.27/tests/tests2/72_long_long_constant.expect create mode 100644 05/tcc-0.9.27/tests/tests2/73_arm64.c create mode 100644 05/tcc-0.9.27/tests/tests2/73_arm64.expect create mode 100644 05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c create mode 100644 05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect create mode 100644 05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c create mode 100644 05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect create mode 100644 05/tcc-0.9.27/tests/tests2/77_push_pop_macro.c create mode 100644 05/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect create mode 100644 05/tcc-0.9.27/tests/tests2/78_vla_label.c create mode 100644 05/tcc-0.9.27/tests/tests2/78_vla_label.expect create mode 100644 05/tcc-0.9.27/tests/tests2/79_vla_continue.c create mode 100644 05/tcc-0.9.27/tests/tests2/79_vla_continue.expect create mode 100644 05/tcc-0.9.27/tests/tests2/80_flexarray.c create mode 100644 05/tcc-0.9.27/tests/tests2/80_flexarray.expect create mode 100644 05/tcc-0.9.27/tests/tests2/81_types.c create mode 100644 05/tcc-0.9.27/tests/tests2/81_types.expect create mode 100644 05/tcc-0.9.27/tests/tests2/82_attribs_position.c create mode 100644 05/tcc-0.9.27/tests/tests2/82_attribs_position.expect create mode 100644 05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c create mode 100644 05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect create mode 100644 05/tcc-0.9.27/tests/tests2/84_hex-float.c create mode 100644 05/tcc-0.9.27/tests/tests2/84_hex-float.expect create mode 100644 05/tcc-0.9.27/tests/tests2/85_asm-outside-function.c create mode 100644 05/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect create mode 100644 05/tcc-0.9.27/tests/tests2/86_memory-model.c create mode 100644 05/tcc-0.9.27/tests/tests2/86_memory-model.expect create mode 100644 05/tcc-0.9.27/tests/tests2/87_dead_code.c create mode 100644 05/tcc-0.9.27/tests/tests2/87_dead_code.expect create mode 100644 05/tcc-0.9.27/tests/tests2/88_codeopt.c create mode 100644 05/tcc-0.9.27/tests/tests2/88_codeopt.expect create mode 100644 05/tcc-0.9.27/tests/tests2/89_nocode_wanted.c create mode 100644 05/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect create mode 100644 05/tcc-0.9.27/tests/tests2/90_struct-init.c create mode 100644 05/tcc-0.9.27/tests/tests2/90_struct-init.expect create mode 100644 05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c create mode 100644 05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect create mode 100644 05/tcc-0.9.27/tests/tests2/92_enum_bitfield.c create mode 100644 05/tcc-0.9.27/tests/tests2/92_enum_bitfield.expect create mode 100644 05/tcc-0.9.27/tests/tests2/93_integer_promotion.c create mode 100644 05/tcc-0.9.27/tests/tests2/93_integer_promotion.expect create mode 100644 05/tcc-0.9.27/tests/tests2/94_generic.c create mode 100644 05/tcc-0.9.27/tests/tests2/94_generic.expect create mode 100644 05/tcc-0.9.27/tests/tests2/95_bitfields.c create mode 100644 05/tcc-0.9.27/tests/tests2/95_bitfields.expect create mode 100644 05/tcc-0.9.27/tests/tests2/95_bitfields_ms.c create mode 100644 05/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect create mode 100644 05/tcc-0.9.27/tests/tests2/96_nodata_wanted.c create mode 100644 05/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect create mode 100644 05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c create mode 100644 05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect create mode 100644 05/tcc-0.9.27/tests/tests2/98_al_ax_extend.c create mode 100644 05/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect create mode 100644 05/tcc-0.9.27/tests/tests2/99_fastcall.c create mode 100644 05/tcc-0.9.27/tests/tests2/99_fastcall.expect create mode 100644 05/tcc-0.9.27/tests/tests2/LICENSE create mode 100644 05/tcc-0.9.27/tests/tests2/Makefile create mode 100644 05/tcc-0.9.27/tests/vla_test.c create mode 100755 05/tcc-0.9.27/texi2pod.pl create mode 100644 05/tcc-0.9.27/time.h create mode 100755 05/tcc-0.9.27/win32/build-tcc.bat create mode 100644 05/tcc-0.9.27/win32/examples/dll.c create mode 100644 05/tcc-0.9.27/win32/examples/fib.c create mode 100644 05/tcc-0.9.27/win32/examples/hello_dll.c create mode 100644 05/tcc-0.9.27/win32/examples/hello_win.c create mode 100644 05/tcc-0.9.27/win32/include/_mingw.h create mode 100644 05/tcc-0.9.27/win32/include/assert.h create mode 100644 05/tcc-0.9.27/win32/include/conio.h create mode 100644 05/tcc-0.9.27/win32/include/ctype.h create mode 100644 05/tcc-0.9.27/win32/include/dir.h create mode 100644 05/tcc-0.9.27/win32/include/direct.h create mode 100644 05/tcc-0.9.27/win32/include/dirent.h create mode 100644 05/tcc-0.9.27/win32/include/dos.h create mode 100644 05/tcc-0.9.27/win32/include/errno.h create mode 100644 05/tcc-0.9.27/win32/include/excpt.h create mode 100644 05/tcc-0.9.27/win32/include/fcntl.h create mode 100644 05/tcc-0.9.27/win32/include/fenv.h create mode 100644 05/tcc-0.9.27/win32/include/inttypes.h create mode 100644 05/tcc-0.9.27/win32/include/io.h create mode 100644 05/tcc-0.9.27/win32/include/limits.h create mode 100644 05/tcc-0.9.27/win32/include/locale.h create mode 100644 05/tcc-0.9.27/win32/include/malloc.h create mode 100644 05/tcc-0.9.27/win32/include/math.h create mode 100644 05/tcc-0.9.27/win32/include/mem.h create mode 100644 05/tcc-0.9.27/win32/include/memory.h create mode 100644 05/tcc-0.9.27/win32/include/process.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/conio_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/crtdbg_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/io_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/mbstring_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/search_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/stdio_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/stdlib_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/stralign_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/string_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/sys/timeb_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/tchar_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/time_s.h create mode 100644 05/tcc-0.9.27/win32/include/sec_api/wchar_s.h create mode 100644 05/tcc-0.9.27/win32/include/setjmp.h create mode 100644 05/tcc-0.9.27/win32/include/share.h create mode 100644 05/tcc-0.9.27/win32/include/signal.h create mode 100644 05/tcc-0.9.27/win32/include/stdint.h create mode 100644 05/tcc-0.9.27/win32/include/stdio.h create mode 100644 05/tcc-0.9.27/win32/include/stdlib.h create mode 100644 05/tcc-0.9.27/win32/include/string.h create mode 100644 05/tcc-0.9.27/win32/include/sys/fcntl.h create mode 100644 05/tcc-0.9.27/win32/include/sys/file.h create mode 100644 05/tcc-0.9.27/win32/include/sys/locking.h create mode 100644 05/tcc-0.9.27/win32/include/sys/stat.h create mode 100644 05/tcc-0.9.27/win32/include/sys/time.h create mode 100644 05/tcc-0.9.27/win32/include/sys/timeb.h create mode 100644 05/tcc-0.9.27/win32/include/sys/types.h create mode 100644 05/tcc-0.9.27/win32/include/sys/unistd.h create mode 100644 05/tcc-0.9.27/win32/include/sys/utime.h create mode 100644 05/tcc-0.9.27/win32/include/tchar.h create mode 100644 05/tcc-0.9.27/win32/include/time.h create mode 100644 05/tcc-0.9.27/win32/include/vadefs.h create mode 100644 05/tcc-0.9.27/win32/include/values.h create mode 100644 05/tcc-0.9.27/win32/include/wchar.h create mode 100644 05/tcc-0.9.27/win32/include/wctype.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/basetsd.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/basetyps.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/guiddef.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/poppack.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/pshpack1.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/pshpack2.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/pshpack4.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/pshpack8.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/winbase.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/wincon.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/windef.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/windows.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/winerror.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/wingdi.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/winnt.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/winreg.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/winuser.h create mode 100644 05/tcc-0.9.27/win32/include/winapi/winver.h create mode 100644 05/tcc-0.9.27/win32/lib/chkstk.S create mode 100644 05/tcc-0.9.27/win32/lib/crt1.c create mode 100644 05/tcc-0.9.27/win32/lib/crt1w.c create mode 100644 05/tcc-0.9.27/win32/lib/dllcrt1.c create mode 100644 05/tcc-0.9.27/win32/lib/dllmain.c create mode 100644 05/tcc-0.9.27/win32/lib/gdi32.def create mode 100644 05/tcc-0.9.27/win32/lib/kernel32.def create mode 100644 05/tcc-0.9.27/win32/lib/msvcrt.def create mode 100644 05/tcc-0.9.27/win32/lib/user32.def create mode 100644 05/tcc-0.9.27/win32/lib/wincrt1.c create mode 100644 05/tcc-0.9.27/win32/lib/wincrt1w.c create mode 100644 05/tcc-0.9.27/win32/tcc-win32.txt create mode 100644 05/tcc-0.9.27/x86_64-asm.h create mode 100644 05/tcc-0.9.27/x86_64-gen.c create mode 100644 05/tcc-0.9.27/x86_64-link.c create mode 100644 05/test.c create mode 100644 05/test.s create mode 100644 05/tests/macros.c diff --git a/05/.gitignore b/05/.gitignore index fe7b7ab..7f437b0 100644 --- a/05/.gitignore +++ b/05/.gitignore @@ -1,2 +1,3 @@ in04 address_map.txt +*.o diff --git a/05/macro_test.c b/05/macro_test.c deleted file mode 100644 index 688c45e..0000000 --- a/05/macro_test.c +++ /dev/null @@ -1,40 +0,0 @@ - #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 - - f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); - g(x+(3,4)-w) | h 5) & m(f)^m(m); - - #undef x - #undef g - #undef z - #undef h - #undef m - #undef w - #undef t - #undef f - -#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 /* from previous #include example */ - #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/05/main.c b/05/main.c index 3c989d9..e669aec 100644 --- a/05/main.c +++ b/05/main.c @@ -12,6 +12,14 @@ int main(int argc, char **argv) { int *p = 0x100; p += 1; + switch (5) { + case 5: + switch (6) { + default:; + } + case 6: + ; + } printf("%p\n",p); return 0; } diff --git a/05/parse.b b/05/parse.b index dd6978a..f4af374 100644 --- a/05/parse.b +++ b/05/parse.b @@ -237,6 +237,10 @@ function parse_toplevel_declaration string No identifier in top-level declaration. byte 0 :tld_bad_stuff_after_decl + ;b = token - 160 + ;c = token + 160 + ;print_tokens(b, token) + ;print_tokens(token, c) token_error(token, .str_tld_bad_stuff_after_decl) :str_tld_bad_stuff_after_decl string Declarations should be immediately followed by a comma or semicolon. @@ -483,6 +487,12 @@ function parse_statement out = *8p_out token = *8p_token + ; needed so that: + ; if (something) + ; lbl: f(); + ; works + :parse_another_statement + c = *1token if c == SYMBOL_SEMICOLON goto stmt_empty if c == SYMBOL_LBRACE goto stmt_block @@ -538,7 +548,7 @@ function parse_statement *8out = *8token ; copy label name out += 32 token += 24 ; skip ident name, and colon - goto parse_statement_ret + goto parse_another_statement :stmt_switch write_statement_header(out, STATEMENT_SWITCH, token) token += 16 @@ -915,7 +925,7 @@ function parse_statement *8out = n out += 32 token = p + 16 - goto parse_statement_ret + goto parse_another_statement :case_no_colon token_error(token, .str_case_no_colon) :str_case_no_colon @@ -927,7 +937,7 @@ function parse_statement out += 40 if *1token != SYMBOL_COLON goto default_no_colon token += 16 - goto parse_statement_ret + goto parse_another_statement :default_no_colon token_error(token, .str_default_no_colon) :str_default_no_colon @@ -2454,7 +2464,7 @@ function parse_base_type out = types + types_bytes_used ; fix stuff in case there were any types in the enumerator expressions goto base_type_done :bad_enum_definition - token_error(base_type, .str_bad_enum_defn) + token_error(p, .str_bad_enum_defn) :str_bad_enum_defn string Bad enum definition. byte 0 diff --git a/05/stdc_common.h b/05/stdc_common.h index b9ffd9d..7c592c9 100644 --- a/05/stdc_common.h +++ b/05/stdc_common.h @@ -19,6 +19,7 @@ typedef unsigned long size_t; typedef long ptrdiff_t; typedef unsigned long uintptr_t; typedef long intptr_t; +typedef long ssize_t; #define INT8_MAX 0x7f #define INT8_MIN (-0x80) @@ -493,6 +494,14 @@ long strtol(const char *nptr, char **endptr, int base) { } } +long long strtoll(const char *nptr, char **endptr, int base) { + return strtol(nptr, endptr, base); +} + +unsigned long long strtoull(const char *nptr, char **endptr, int base) { + return strtoul(nptr, endptr, base); +} + long _strtol_clamped(const char *nptr, char **endptr, int base, int min, int max) { long l = strtol(nptr, endptr, base); if (l < min) return min; diff --git a/05/stdlib.h b/05/stdlib.h index c2f83eb..b93d4aa 100644 --- a/05/stdlib.h +++ b/05/stdlib.h @@ -18,6 +18,12 @@ typedef struct { long rem; } ldiv_t; + +int execvp(const char *pathname, char *const argv[]) { + return execve(pathname, argv, _envp); +} + + char *getenv(const char *name) { int i, j; for (i = 0; _envp[i]; ++i) { diff --git a/05/tcc-0.9.25/.cvsignore b/05/tcc-0.9.25/.cvsignore deleted file mode 100644 index 95daa1f..0000000 --- a/05/tcc-0.9.25/.cvsignore +++ /dev/null @@ -1,37 +0,0 @@ -tcc_g -tcc -tc2.c -doc -tc3s.c -p3.c -tc1.c -error.c -i386-gen1.c -test.out2 -test.out3 -web.sh -memdebug.c -bench -Makefile.uClibc -boundtest -prog.ref -test.ref -test.out -tcc-doc.html -ideas -tcctest.ref -linux.tcc -ldtest -libtcc_test -instr.S -p.c -p2.c -tcctest[1234] -test[1234].out -.gdb_history -tcc.1 -tcc.pod -config.h -config.mak -config.texi -tests \ No newline at end of file diff --git a/05/tcc-0.9.25/.gitignore b/05/tcc-0.9.25/.gitignore deleted file mode 100644 index aaa8247..0000000 --- a/05/tcc-0.9.25/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -tcc -examples -tests -win32 diff --git a/05/tcc-0.9.25/COPYING b/05/tcc-0.9.25/COPYING deleted file mode 100644 index 223ede7..0000000 --- a/05/tcc-0.9.25/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - 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. - - - Copyright (C) - - 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. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/05/tcc-0.9.25/Changelog b/05/tcc-0.9.25/Changelog deleted file mode 100644 index b271054..0000000 --- a/05/tcc-0.9.25/Changelog +++ /dev/null @@ -1,368 +0,0 @@ -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/05/tcc-0.9.25/Makefile b/05/tcc-0.9.25/Makefile deleted file mode 100644 index 1a2b5f7..0000000 --- a/05/tcc-0.9.25/Makefile +++ /dev/null @@ -1,272 +0,0 @@ -# -# Tiny C Compiler Makefile -# - -TOP ?= . -include $(TOP)/config.mak - -CFLAGS+=-g -Wall -CFLAGS_P=$(CFLAGS) -pg -static -DCONFIG_TCC_STATIC -LIBS_P= - -ifneq ($(GCC_MAJOR),2) -CFLAGS+=-fno-strict-aliasing -endif - -ifeq ($(ARCH),i386) -CFLAGS+=-mpreferred-stack-boundary=2 -ifeq ($(GCC_MAJOR),2) -CFLAGS+=-m386 -malign-functions=0 -else -CFLAGS+=-march=i386 -falign-functions=0 -ifneq ($(GCC_MAJOR),3) -CFLAGS+=-Wno-pointer-sign -Wno-sign-compare -D_FORTIFY_SOURCE=0 -endif -endif -endif - -ifeq ($(ARCH),x86-64) -CFLAGS+=-Wno-pointer-sign -endif - -ifndef CONFIG_WIN32 -LIBS=-lm -ifndef CONFIG_NOLDL -LIBS+=-ldl -endif -endif - -ifdef CONFIG_WIN32 -NATIVE_TARGET=-DTCC_TARGET_PE -LIBTCC1=libtcc1.a -else -ifeq ($(ARCH),i386) -NATIVE_TARGET=-DTCC_TARGET_I386 -LIBTCC1=libtcc1.a -BCHECK_O=bcheck.o -else -ifeq ($(ARCH),arm) -NATIVE_TARGET=-DTCC_TARGET_ARM -NATIVE_TARGET+=$(if $(wildcard /lib/ld-linux.so.3),-DTCC_ARM_EABI) -NATIVE_TARGET+=$(if $(shell grep -l "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo),-DTCC_ARM_VFP) -else -ifeq ($(ARCH),x86-64) -NATIVE_TARGET=-DTCC_TARGET_X86_64 -LIBTCC1=libtcc1.a -endif -endif -endif -endif - -ifneq ($(wildcard /lib/ld-uClibc.so.0),) -NATIVE_TARGET+=-DTCC_UCLIBC -BCHECK_O= -endif - -ifdef CONFIG_USE_LIBGCC -LIBTCC1= -endif - -ifeq ($(TOP),.) - -PROGS=tcc$(EXESUF) - -I386_CROSS = i386-tcc$(EXESUF) -WIN32_CROSS = i386-win32-tcc$(EXESUF) -X64_CROSS = x86_64-tcc$(EXESUF) -ARM_CROSS = arm-tcc-fpa$(EXESUF) arm-tcc-fpa-ld$(EXESUF) \ - arm-tcc-vfp$(EXESUF) arm-tcc-vfp-eabi$(EXESUF) -C67_CROSS = c67-tcc$(EXESUF) - -CORE_FILES = tcc.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c \ - tcc.h config.h libtcc.h tcctok.h -I386_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h -WIN32_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h tccpe.c -X86_64_FILES = $(CORE_FILES) x86_64-gen.c -ARM_FILES = $(CORE_FILES) arm-gen.c -C67_FILES = $(CORE_FILES) c67-gen.c tcccoff.c - -ifdef CONFIG_WIN32 -PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF) -NATIVE_FILES=$(WIN32_FILES) -PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(C67_CROSS) -else -ifeq ($(ARCH),i386) -NATIVE_FILES=$(I386_FILES) -PROGS_CROSS=$(X64_CROSS) $(WIN32_CROSS) $(ARM_CROSS) $(C67_CROSS) -else -ifeq ($(ARCH),x86-64) -NATIVE_FILES=$(X86_64_FILES) -PROGS_CROSS=$(I386_CROSS) $(WIN32_CROSS) $(ARM_CROSS) $(C67_CROSS) -else -ifeq ($(ARCH),arm) -NATIVE_FILES=$(ARM_FILES) -PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(C67_CROSS) -endif -endif -endif -endif - -ifdef CONFIG_CROSS -PROGS+=$(PROGS_CROSS) -endif - -all: $(PROGS) $(LIBTCC1) $(BCHECK_O) libtcc.a tcc-doc.html tcc.1 libtcc_test$(EXESUF) - -# Host Tiny C Compiler -tcc$(EXESUF): $(NATIVE_FILES) - $(CC) -o $@ $< $(NATIVE_TARGET) $(CFLAGS) $(LIBS) - -# Cross Tiny C Compilers -i386-tcc$(EXESUF): $(I386_FILES) - $(CC) -o $@ $< -DTCC_TARGET_I386 $(CFLAGS) $(LIBS) - -i386-win32-tcc$(EXESUF): $(WIN32_FILES) - $(CC) -o $@ $< -DTCC_TARGET_PE $(CFLAGS) $(LIBS) - -x86_64-tcc$(EXESUF): $(X86_64_FILES) - $(CC) -o $@ $< -DTCC_TARGET_X86_64 $(CFLAGS) $(LIBS) - -c67-tcc$(EXESUF): $(C67_FILES) - $(CC) -o $@ $< -DTCC_TARGET_C67 $(CFLAGS) $(LIBS) - -arm-tcc-fpa$(EXESUF): $(ARM_FILES) - $(CC) -o $@ $< -DTCC_TARGET_ARM $(CFLAGS) $(LIBS) - -arm-tcc-fpa-ld$(EXESUF): $(ARM_FILES) - $(CC) -o $@ $< -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12 $(CFLAGS) $(LIBS) - -arm-tcc-vfp$(EXESUF): $(ARM_FILES) - $(CC) -o $@ $< -DTCC_TARGET_ARM -DTCC_ARM_VFP $(CFLAGS) $(LIBS) - -arm-tcc-vfp-eabi$(EXESUF): $(ARM_FILES) - $(CC) -o $@ $< -DTCC_TARGET_ARM -DTCC_ARM_EABI $(CFLAGS) $(LIBS) - -# libtcc generation and test -libtcc.o: $(NATIVE_FILES) - $(CC) -o $@ -c libtcc.c $(NATIVE_TARGET) $(CFLAGS) - -libtcc.a: libtcc.o - $(AR) rcs $@ $^ - -libtcc_test$(EXESUF): tests/libtcc_test.c libtcc.a - $(CC) -o $@ $^ -I. $(CFLAGS) $(LIBS) - -libtest: libtcc_test$(EXESUF) $(LIBTCC1) - ./libtcc_test$(EXESUF) lib_path=. - -# profiling version -tcc_p$(EXESUF): $(NATIVE_FILES) - $(CC) -o $@ $< $(NATIVE_TARGET) $(CFLAGS_P) $(LIBS_P) - -# windows utilities -tiny_impdef$(EXESUF): win32/tools/tiny_impdef.c - $(CC) -o $@ $< $(CFLAGS) -tiny_libmaker$(EXESUF): win32/tools/tiny_libmaker.c - $(CC) -o $@ $< $(CFLAGS) - -# TinyCC runtime libraries -LIBTCC1_OBJS=libtcc1.o -LIBTCC1_CC=$(CC) -VPATH+=lib -ifdef CONFIG_WIN32 -# for windows, we must use TCC because we generate ELF objects -LIBTCC1_OBJS+=crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o -LIBTCC1_CC=./tcc.exe -Bwin32 -DTCC_TARGET_PE -VPATH+=win32/lib -endif -ifeq ($(ARCH),i386) -LIBTCC1_OBJS+=alloca86.o alloca86-bt.o -endif - -%.o: %.c - $(LIBTCC1_CC) -o $@ -c $< -O2 -Wall - -%.o: %.S - $(LIBTCC1_CC) -o $@ -c $< - -libtcc1.a: $(LIBTCC1_OBJS) - $(AR) rcs $@ $^ - -bcheck.o: bcheck.c - $(CC) -o $@ -c $< -O2 -Wall - -# install -TCC_INCLUDES = stdarg.h stddef.h stdbool.h float.h varargs.h tcclib.h -INSTALL=install - -ifndef CONFIG_WIN32 -install: $(PROGS) $(LIBTCC1) $(BCHECK_O) libtcc.a tcc.1 tcc-doc.html - mkdir -p "$(bindir)" - $(INSTALL) -s -m755 $(PROGS) "$(bindir)" - mkdir -p "$(mandir)/man1" - $(INSTALL) tcc.1 "$(mandir)/man1" - mkdir -p "$(tccdir)" - mkdir -p "$(tccdir)/include" -ifneq ($(LIBTCC1),) - $(INSTALL) -m644 $(LIBTCC1) "$(tccdir)" -endif -ifneq ($(BCHECK_O),) - $(INSTALL) -m644 $(BCHECK_O) "$(tccdir)" -endif - $(INSTALL) -m644 $(addprefix include/,$(TCC_INCLUDES)) "$(tccdir)/include" - mkdir -p "$(docdir)" - $(INSTALL) -m644 tcc-doc.html "$(docdir)" - mkdir -p "$(libdir)" - $(INSTALL) -m644 libtcc.a "$(libdir)" - mkdir -p "$(includedir)" - $(INSTALL) -m644 libtcc.h "$(includedir)" - -uninstall: - rm -fv $(foreach P,$(PROGS),"$(bindir)/$P") - rm -fv $(foreach P,$(LIBTCC1) $(BCHECK_O),"$(tccdir)/$P") - rm -fv $(foreach P,$(TCC_INCLUDES),"$(tccdir)/include/$P") - rm -fv "$(docdir)/tcc-doc.html" "$(mandir)/man1/tcc.1" - rm -fv "$(libdir)/libtcc.a" "$(includedir)/libtcc.h" - -else -install: $(PROGS) $(LIBTCC1) libtcc.a tcc-doc.html - mkdir -p "$(tccdir)" - mkdir -p "$(tccdir)/lib" - mkdir -p "$(tccdir)/include" - mkdir -p "$(tccdir)/examples" - mkdir -p "$(tccdir)/doc" - mkdir -p "$(tccdir)/libtcc" - $(INSTALL) -s -m755 $(PROGS) "$(tccdir)" - $(INSTALL) -m644 $(LIBTCC1) win32/lib/*.def "$(tccdir)/lib" - cp -r win32/include/. "$(tccdir)/include" - cp -r win32/examples/. "$(tccdir)/examples" -# $(INSTALL) -m644 $(addprefix include/,$(TCC_INCLUDES)) "$(tccdir)/include" - $(INSTALL) -m644 tcc-doc.html win32/tcc-win32.txt "$(tccdir)/doc" - $(INSTALL) -m644 libtcc.a libtcc.h "$(tccdir)/libtcc" -endif - -# documentation and man page -tcc-doc.html: tcc-doc.texi - -texi2html -monolithic -number $< - -tcc.1: tcc-doc.texi - -./texi2pod.pl $< tcc.pod - -pod2man --section=1 --center=" " --release=" " tcc.pod > $@ - -# tar release (use 'make -k tar' on a checkouted tree) -TCC-VERSION=tcc-$(shell cat VERSION) -tar: - rm -rf /tmp/$(TCC-VERSION) - cp -r . /tmp/$(TCC-VERSION) - ( cd /tmp ; tar zcvf ~/$(TCC-VERSION).tar.gz $(TCC-VERSION) --exclude CVS ) - rm -rf /tmp/$(TCC-VERSION) - -# in tests subdir -test clean : - $(MAKE) -C tests $@ - -# clean -clean: local_clean -local_clean: - rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.out libtcc_test$(EXESUF) - -distclean: clean - rm -vf config.h config.mak config.texi tcc.1 tcc-doc.html - -endif # ifeq ($(TOP),.) diff --git a/05/tcc-0.9.25/README b/05/tcc-0.9.25/README deleted file mode 100644 index bfaab39..0000000 --- a/05/tcc-0.9.25/README +++ /dev/null @@ -1,90 +0,0 @@ -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 Linux host (for Windows read tcc-win32.txt) - - ./configure - make - make test - make install - -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 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 ! - -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/05/tcc-0.9.25/TODO b/05/tcc-0.9.25/TODO deleted file mode 100644 index 6f49c5d..0000000 --- a/05/tcc-0.9.25/TODO +++ /dev/null @@ -1,95 +0,0 @@ -TODO list: - -Bugs: - -- fix macro substitution with nested definitions (ShangHongzhang) -- FPU st(0) is left unclean (kwisatz haderach). Incompatible with - optimized gcc/msc code - -- constructors -- cast bug (Peter Wang) -- define incomplete type if defined several times (Peter Wang). -- configure --cc=tcc (still one bug in libtcc1.c) -- test binutils/gcc compile -- tci patch + argument. -- see -lxxx bug (Michael Charity). -- 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 lcc test suite -> fix bitfield binary operations -- 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 -- sizeof, alignof, typeof can still generate code in some cases. -- Fix the remaining libtcc memory leaks. -- make libtcc fully reentrant (except for the compilation stage itself). - -Bound checking: - -- '-b' bug. -- 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() -- improve '-E' option. -- add '-MD' option -- atexit (Nigel Horne) -- packed attribute -- C99: add variable size arrays (gcc 3.2 testsuite issue) -- C99: add complex types (gcc 3.2 testsuite issue) -- postfix compound literals (see 20010124-1.c) - -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 or ARM code generator and improve codegen for RISC (need - to suppress VT_LOCAL and use a base register instead). -- interactive mode / integrated debugger -- fix preprocessor symbol redefinition -- better constant opt (&&, ||, ?:) -- 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)() - -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. diff --git a/05/tcc-0.9.25/VERSION b/05/tcc-0.9.25/VERSION deleted file mode 100644 index f5b38be..0000000 --- a/05/tcc-0.9.25/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.9.25 \ No newline at end of file diff --git a/05/tcc-0.9.25/arm-gen.c b/05/tcc-0.9.25/arm-gen.c deleted file mode 100644 index 42feecf..0000000 --- a/05/tcc-0.9.25/arm-gen.c +++ /dev/null @@ -1,1734 +0,0 @@ -/* - * ARMv4 code generator for TCC - * - * Copyright (c) 2003 Daniel Glöckner - * - * 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 TCC_ARM_EABI -#define TCC_ARM_VFP -#endif - - -/* number of available registers */ -#ifdef TCC_ARM_VFP -#define NB_REGS 13 -#else -#define NB_REGS 9 -#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 -}; - -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 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); -} - -#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 - -#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) -static CType float_type, double_type, func_float_type, func_double_type; -#define func_ldouble_type func_double_type -#else -#define func_float_type func_old_type -#define func_double_type func_old_type -#define func_ldouble_type func_old_type -#endif - -/* 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 - -/******************************************************/ -/* ELF defines */ - -#define EM_TCC_TARGET EM_ARM - -/* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_ARM_ABS32 -#define R_JMP_SLOT R_ARM_JUMP_SLOT -#define R_COPY R_ARM_COPY - -#define ELF_START_ADDR 0x00008000 -#define ELF_PAGE_SIZE 0x1000 - -/******************************************************/ -static unsigned long func_sub_sp_offset,last_itod_magic; -static int leaffunc; - -void o(unsigned long i) -{ - /* this is a good place to start adding big-endian support*/ - int ind1; - - ind1 = ind + 4; - if (!cur_text_section) - 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 unsigned long stuff_const(unsigned long op,unsigned long c) -{ - int try_neg=0; - unsigned long 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 { - unsigned long 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<>(32-i)); - } - op=negop; - c=nc; - } while(try_neg--); - return 0; -} - - -//only add,sub -void stuff_const_harder(unsigned long op,unsigned long v) { - unsigned long x; - x=stuff_const(op,v); - if(x) - o(x); - else { - unsigned long 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])); - } -} - -unsigned long encbranch(int pos,int addr,int fail) -{ - addr-=pos+8; - addr/=4; - if(addr>=0x1000000 || addr<-0x1000000) { - if(fail) - error("FIXME: function bigger than 32MB"); - return 0; - } - return 0x0A000000|(addr&0xffffff); -} - -int decbranch(int pos) -{ - int x; - x=*(int *)(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) -{ - unsigned long *x; - int lt; - while(t) { - x=(unsigned long *)(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 unsigned long vfpr(int r) -{ - if(rTREG_F7) - error("compiler error! register %i is no vfp register",r); - return r-5; -} -#else -static unsigned long fpr(int r) -{ - if(rTREG_F3) - error("compiler error! register %i is no fpa register",r); - return r-5; -} -#endif - -static unsigned long intr(int r) -{ - if(r==4) - return 12; - if((r<0 || r>4) && r!=14) - error("compiler error! register %i is no int register",r); - return r; -} - -static void calcaddr(unsigned long *base,int *off,int *sgn,int maxoff,unsigned shift) -{ - if(*off>maxoff || *off&((1<r; - ft = sv->type.t; - fc = sv->c.ul; - - if(fc>=0) - sign=0; - else { - sign=1; - fc=-fc; - } - - v = fr & VT_VALMASK; - if (fr & VT_LVAL) { - unsigned long base=0xB; // fp - if(v == VT_LLOCAL) { - v1.type.t = VT_PTR; - v1.r = VT_LOCAL | VT_LVAL; - v1.c.ul = sv->c.ul; - load(base=14 /* lr */, &v1); - fc=sign=0; - v=VT_LOCAL; - } else if(v == VT_CONST) { - v1.type.t = VT_PTR; - v1.r = fr&~VT_LVAL; - v1.c.ul = sv->c.ul; - v1.sym=sv->sym; - load(base=14, &v1); - 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) - 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.ul); - 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.ul); - } else - o(op); - return; - } else if (v == VT_LOCAL) { - op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.ul); - 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.ul); - o(0xE08B0000|(intr(r)<<12)|intr(r)); - } else - o(op); - return; - } else if(v == VT_CMP) { - o(mapcc(sv->c.ul)|0x3A00001|(intr(r)<<12)); - o(mapcc(negcc(sv->c.ul))|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.ul); - 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; - } - } - error("load unimplemented!"); -} - -/* store register 'r' in lvalue 'v' */ -void store(int r, SValue *sv) -{ - SValue v1; - int v, ft, fc, fr, sign; - unsigned long op; - - fr = sv->r; - ft = sv->type.t; - fc = sv->c.ul; - - if(fc>=0) - sign=0; - else { - sign=1; - fc=-fc; - } - - v = fr & VT_VALMASK; - if (fr & VT_LVAL || fr == VT_LOCAL) { - unsigned long base=0xb; - 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.ul = sv->c.ul; - v1.sym=sv->sym; - load(base=14, &v1); - 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) - op|=0x400000; - o(op|(intr(r)<<12)|fc|(base<<16)); - } - return; - } - } - 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) { - unsigned long x; - /* constant case */ - x=encbranch(ind,ind+vtop->c.ul,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.ul); - } - } else { - /* otherwise, indirect call */ - r = gv(RC_INT); - if(!is_jmp) - o(0xE1A0E00F); // mov lr,pc - o(0xE1A0F000|intr(r)); // mov pc,r - } -} - -/* 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 size, align, r, args_size, i; - Sym *func_sym; - signed char plan[4][2]={{-1,-1},{-1,-1},{-1,-1},{-1,-1}}; - int todo=0xf, keep, plan2[4]={0,0,0,0}; - - r = vtop->r & VT_VALMASK; - if (r == VT_CMP || (r & ~1) == VT_JMP) - gv(RC_INT); -#ifdef TCC_ARM_EABI - if((vtop[-nb_args].type.ref->type.t & VT_BTYPE) == VT_STRUCT - && type_size(&vtop[-nb_args].type, &align) <= 4) { - SValue tmp; - tmp=vtop[-nb_args]; - vtop[-nb_args]=vtop[-nb_args+1]; - vtop[-nb_args+1]=tmp; - --nb_args; - } - - vpushi(0); - vtop->type.t = VT_LLONG; - args_size = 0; - for(i = nb_args + 1 ; i-- ;) { - size = type_size(&vtop[-i].type, &align); - if(args_size & (align-1)) { - vpushi(0); - vtop->type.t = VT_VOID; /* padding */ - vrott(i+2); - args_size += 4; - ++nb_args; - } - args_size += (size + 3) & -4; - } - vtop--; -#endif - args_size = 0; - for(i = nb_args ; i-- && args_size < 16 ;) { - switch(vtop[-i].type.t & VT_BTYPE) { - case VT_STRUCT: - case VT_FLOAT: - case VT_DOUBLE: - case VT_LDOUBLE: - size = type_size(&vtop[-i].type, &align); - size = (size + 3) & -4; - args_size += size; - break; - default: - plan[nb_args-1-i][0]=args_size/4; - args_size += 4; - if ((vtop[-i].type.t & VT_BTYPE) == VT_LLONG && args_size < 16) { - plan[nb_args-1-i][1]=args_size/4; - args_size += 4; - } - } - } - args_size = keep = 0; - for(i = 0;i < nb_args; i++) { - vnrott(keep+1); - if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { - size = type_size(&vtop->type, &align); - /* align to stack align size */ - size = (size + 3) & -4; - /* allocate the necessary size on stack */ - gadd_sp(-size); - /* generate structure store */ - r = get_reg(RC_INT); - o(0xE1A0000D|(intr(r)<<12)); - vset(&vtop->type, r | VT_LVAL, 0); - vswap(); - vstore(); - vtop--; - args_size += size; - } else if (is_float(vtop->type.t)) { -#ifdef TCC_ARM_VFP - r=vfpr(gv(RC_FLOAT))<<12; - size=4; - if ((vtop->type.t & VT_BTYPE) != VT_FLOAT) - { - size=8; - r|=0x101; /* fstms -> fstmd */ - } - o(0xED2D0A01+r); -#else - r=fpr(gv(RC_FLOAT))<<12; - if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) - size = 4; - else if ((vtop->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)); -#endif - vtop--; - args_size += size; - } else { - int s; - /* simple type (currently always same size) */ - /* XXX: implicit cast ? */ - size=4; - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - lexpand_nr(); - s=RC_INT; - if(nb_args-i<5 && plan[nb_args-i-1][1]!=-1) { - s=regmask(plan[nb_args-i-1][1]); - todo&=~(1<type.t == VT_VOID) { - if(s == RC_INT) - o(0xE24DD004); /* sub sp,sp,#4 */ - vtop--; - } else -#endif - if(s == RC_INT) { - r = gv(s); - o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */ - vtop--; - } else { - plan2[keep]=s; - keep++; - } - args_size += size; - } - } - for(i=keep;i--;) { - gv(plan2[i]); - vrott(keep); - } -save_regs(keep); /* save used temporary registers */ - keep++; - if(args_size) { - int n; - n=args_size/4; - if(n>4) - n=4; - todo&=((1<r=i; - keep++; - } - } - args_size-=n*4; - } - vnrott(keep); - func_sym = vtop->type.ref; - gcall_or_jmp(0); - if (args_size) - gadd_sp(args_size); -#ifdef TCC_ARM_EABI - if((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT - && type_size(&vtop->type.ref->type, &align) <= 4) - { - store(REG_IRET,vtop-keep); - ++keep; - } -#ifdef TCC_ARM_VFP - else if(is_float(vtop->type.ref->type.t)) { - if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) { - o(0xEE000A10); /* fmsr s0,r0 */ - } else { - o(0xEE000B10); /* fmdlr d0,r0 */ - o(0xEE201B10); /* fmdhr d0,r1 */ - } - } -#endif -#endif - vtop-=keep; - leaffunc = 0; -} - -/* generate function prolog of type 't' */ -void gfunc_prolog(CType *func_type) -{ - Sym *sym,*sym2; - int n,addr,size,align; - - sym = func_type->ref; - func_vt = sym->type; - - n = 0; - addr = 0; - if((func_vt.t & VT_BTYPE) == VT_STRUCT - && type_size(&func_vt,&align) > 4) - { - func_vc = addr; - addr += 4; - n++; - } - for(sym2=sym->next;sym2 && n<4;sym2=sym2->next) { - size = type_size(&sym2->type, &align); - n += (size + 3) / 4; - } - o(0xE1A0C00D); /* mov ip,sp */ - if(func_type->ref->c == FUNC_ELLIPSIS) - n=4; - if(n) { - if(n>4) - n=4; -#ifdef TCC_ARM_EABI - n=(n+1)&-2; -#endif - o(0xE92D0000|((1<next)) { - CType *type; - type = &sym->type; - size = type_size(type, &align); - size = (size + 3) & -4; -#ifdef TCC_ARM_EABI - addr = (addr + align - 1) & -align; -#endif - sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr); - addr += size; - } - last_itod_magic=0; - leaffunc = 1; - loc = -12; -} - -/* generate function epilog */ -void gfunc_epilog(void) -{ - unsigned long x; - int diff; -#ifdef TCC_ARM_EABI - if(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(0xE91BA800); /* restore fp, sp, pc */ - diff = (-loc + 3) & -4; -#ifdef TCC_ARM_EABI - if(!leaffunc) - diff = (diff + 7) & -8; -#endif - if(diff > 12) { - x=stuff_const(0xE24BD000, diff); /* sub sp,fp,# */ - if(x) - *(unsigned long *)(cur_text_section->data + func_sub_sp_offset) = x; - else { - unsigned long addr; - addr=ind; - o(0xE59FC004); /* ldr ip,[pc+4] */ - o(0xE04BD00C); /* sub sp,fp,ip */ - o(0xE1A0F00E); /* mov pc,lr */ - o(diff); - *(unsigned long *)(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; - 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; - unsigned long op; - v = vtop->r & VT_VALMASK; - r=ind; - 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 { - unsigned long *x; - int p,lp; - if(t) { - p = vtop->c.i; - do { - p = decbranch(lp=p); - } while(p); - x = (unsigned long *)(cur_text_section->data + lp); - *x &= 0xff000000; - *x |= encbranch(lp,t,1); - } - t = vtop->c.i; - } - } else { - t = gjmp(t); - gsym(vtop->c.i); - } - } else { - if (is_float(vtop->type.t)) { - r=gv(RC_FLOAT); -#ifdef TCC_ARM_VFP - o(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */ - o(0xEEF1FA10); /* fmstat */ -#else - o(0xEE90F118|(fpr(r)<<16)); -#endif - vtop->r = VT_CMP; - vtop->c.i = TOK_NE; - return gtst(inv, t); - } else if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant jmp optimization */ - if ((vtop->c.i != 0) != inv) - t = gjmp(t); - } else { - v = gv(RC_INT); - o(0xE3300000|(intr(v)<<16)); - vtop->r = VT_CMP; - vtop->c.i = TOK_NE; - return gtst(inv, t); - } - } - vtop--; - return t; -} - -/* generate an integer binary operation */ -void gen_opi(int op) -{ - int c, func = 0; - unsigned long 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) { - unsigned long 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: - 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 guaranted to have the same floating point type */ -void gen_opf(int op) -{ - unsigned long 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) { - 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 int is_fconst() -{ - long double f; - int 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 guaranted to have the same floating point type */ -void gen_opf(int op) -{ - unsigned long x; - int 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: - error("unsigned comparision 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 { - 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. */ -void gen_cvt_itof1(int t) -{ - int r,r2,bt; - bt=vtop->type.t & VT_BTYPE; - if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) { -#ifndef TCC_ARM_VFP - unsigned int 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<<=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)) { - unsigned int 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; - } - } - error("unimplemented gen_cvt_itof %x!",vtop->type.t); -} - -/* convert fp to int 't' type */ -void gen_cvt_ftoi(int t) -{ - int r,r2,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(0xEEBC0A40|(r<<12)|r|T2CPR(r2)); /* ftoXiY */ - 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; - } - 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)) { - int 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--; -} - -/* end of ARM code generator */ -/*************************************************************/ - diff --git a/05/tcc-0.9.25/assert.h b/05/tcc-0.9.25/assert.h deleted file mode 100644 index 8cac979..0000000 --- a/05/tcc-0.9.25/assert.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _ASSERT_H -#define _ASSERT_H - -// assert is defined in stdc_common.h -#include - -#endif // _ASSERT_H diff --git a/05/tcc-0.9.25/c67-gen.c b/05/tcc-0.9.25/c67-gen.c deleted file mode 100644 index 04f8a12..0000000 --- a/05/tcc-0.9.25/c67-gen.c +++ /dev/null @@ -1,2548 +0,0 @@ -/* - * 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 - */ - -//#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, -}; - -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 -}; - -/* 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 */ - - -#define ALWAYS_ASSERT(x) \ -do {\ - if (!(x))\ - error("internal compiler error file at %s:%d", __FILE__, __LINE__);\ -} while (0) - -// 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; - -/* 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 - -/******************************************************/ -/* ELF defines */ - -#define EM_TCC_TARGET EM_C60 - -/* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_C60_32 -#define R_JMP_SLOT R_C60_JMP_SLOT -#define R_COPY R_C60_COPY - -#define ELF_START_ADDR 0x00000400 -#define ELF_PAGE_SIZE 0x1000 - -/******************************************************/ - -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; - -#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 asign them unique values so the mapping routines -// can distinquish 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.ul; - - 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.ul = fc; - load(r, &v1); - fr = r; - } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { - 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.ul; - fr = v->r & VT_VALMASK; - bt = ft & VT_BTYPE; - /* XXX: incorrect if float reg to reg */ - - if (bt == VT_LDOUBLE) { - 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 - } - } -} - -/* 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) { - 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 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) { - error("long long not supported"); - } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - 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->r; - addr = 8; - /* if the function returns a structure, then add an - implicit pointer parameter */ - func_vt = sym->type; - 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; - - 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 (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 */ - p = &vtop->c.i; - - // I guess the idea is to traverse to the - // null at the end of the list and store t - // there - - n = *p; - 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); - } - } else { - if (is_float(vtop->type.t)) { - 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); - } else { - // I think we need to get the value on the stack - // into a register, test it, and generate a branch - // return the address of the branch, so it can be - // later patched - - v = gv(RC_INT); // get value into a reg - ind1 = ind; - C67_MVKL(C67_A0, t); //r=reg to load, constant - C67_MVKH(C67_A0, t); //r=reg to load, constant - - if (v != TREG_EAX && // check if not already in a conditional test reg - v != TREG_EDX && v != TREG_ST0 && v != C67_B2) { - C67_MV(v, C67_B2); - v = C67_B2; - } - - C67_IREG_B_REG(inv, v, C67_A0); // [!R] B.S2x A0 - C67_NOP(5); - t = ind1; //return where we need to patch - ind1 = ind; - } - } - 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 bultiply 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 guaranted 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.ul; - r = vtop->r; - fr = vtop[-1].r; - - - if ((ft & VT_BTYPE) == VT_LDOUBLE) - 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) - 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--; -} - -/* end of X86 code generator */ -/*************************************************************/ diff --git a/05/tcc-0.9.25/coff.h b/05/tcc-0.9.25/coff.h deleted file mode 100644 index 38960b4..0000000 --- a/05/tcc-0.9.25/coff.h +++ /dev/null @@ -1,446 +0,0 @@ -/**************************************************************************/ -/* 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 nunbers 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 "!\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)&~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/05/tcc-0.9.25/config.h b/05/tcc-0.9.25/config.h deleted file mode 100644 index 7e4096c..0000000 --- a/05/tcc-0.9.25/config.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef CONFIG_TCCDIR -# define CONFIG_TCCDIR "/usr/local/lib/tcc-bootstrap" -#endif -#define TCC_VERSION "0.9.25" -#define CONFIG_TCC_STATIC 1 -#define TCC_TARGET_X86_64 1 -#define CONFIG_TCC_ELFINTERP "/XXX" -#define CONFIG_TCC_CRT_PREFIX "/XXX" -#define CONFIG_SYSROOT "/XXX" -#define inline diff --git a/05/tcc-0.9.25/configure b/05/tcc-0.9.25/configure deleted file mode 100755 index 5b38f28..0000000 --- a/05/tcc-0.9.25/configure +++ /dev/null @@ -1,382 +0,0 @@ -#!/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 - -TMPC="${TMPDIR1}/tcc-conf-${RANDOM}-$$-${RANDOM}.c" -TMPO="${TMPDIR1}/tcc-conf-${RANDOM}-$$-${RANDOM}.o" -TMPE="${TMPDIR1}/tcc-conf-${RANDOM}-$$-${RANDOM}" -TMPS="${TMPDIR1}/tcc-conf-${RANDOM}-$$-${RANDOM}.S" -TMPH="${TMPDIR1}/tcc-conf-${RANDOM}-$$-${RANDOM}.h" - -# default parameters -build_cross="no" -use_libgcc="no" -prefix="" -execprefix="" -bindir="" -libdir="" -tccdir="" -includedir="" -mandir="" -sysroot="" -cross_prefix="" -cc="gcc" -host_cc="gcc" -ar="ar" -strip="strip" -cpu=`uname -m` -case "$cpu" in - i386|i486|i586|i686|i86pc|BePC) - cpu="x86" - ;; - x86_64) - cpu="x86-64" - ;; - armv4l) - cpu="armv4l" - ;; - alpha) - cpu="alpha" - ;; - "Power Macintosh"|ppc|ppc64) - cpu="powerpc" - ;; - mips) - cpu="mips" - ;; - s390) - cpu="s390" - ;; - *) - cpu="unknown" - ;; -esac -gprof="no" -bigendian="no" -mingw32="no" -LIBSUF=".a" -EXESUF="" - -# OS specific -targetos=`uname -s` -case $targetos in -MINGW32*) -mingw32="yes" -;; -DragonFly) -noldl="yes" -;; -OpenBSD) -noldl="yes" -;; -*) ;; -esac - -# find source path -# XXX: we assume an absolute path is given when launching configure, -# except in './configure' case. -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 - case "$opt" in - --prefix=*) prefix=`echo $opt | cut -d '=' -f 2` - ;; - --exec-prefix=*) execprefix=`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` - ;; - --mandir=*) mandir=`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` - ;; - --extra-cflags=*) CFLAGS="${opt#--extra-cflags=}" - ;; - --extra-ldflags=*) LDFLAGS="${opt#--extra-ldflags=}" - ;; - --extra-libs=*) extralibs=${opt#--extra-libs=} - ;; - --cpu=*) cpu=`echo $opt | cut -d '=' -f 2` - ;; - --enable-gprof) gprof="yes" - ;; - --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-" - ;; - --enable-cross) build_cross="yes" - ;; - --with-libgcc) use_libgcc="yes" - ;; - esac -done - -# Checking for CFLAGS -if test -z "$CFLAGS"; then - CFLAGS="-O2" -fi - -cc="${cross_prefix}${cc}" -ar="${cross_prefix}${ar}" -strip="${cross_prefix}${strip}" - -if test "$mingw32" = "yes" ; then - LIBSUF=".lib" - EXESUF=".exe" -fi - -if test -z "$cross_prefix" ; then - -# --- -# big/little endian test -cat > $TMPC << EOF -#include -int main(int argc, char ** argv){ - volatile uint32_t i=0x01234567; - return (*((uint8_t*)(&i))) == 0x67; -} -EOF - -if $cc -o $TMPE $TMPC 2>/dev/null ; then - $TMPE && bigendian="yes" -else - echo big/little test failed -fi - -else - -# if cross compiling, cannot launch a program, so make a static guess -if test "$cpu" = "powerpc" -o "$cpu" = "mips" -o "$cpu" = "s390" ; then - bigendian="yes" -fi - -fi - -# check gcc version -cat > $TMPC < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2) -return 0; -#else -#error gcc < 3.2 -#endif -} -EOF - -gcc_major="2" -if $cc -o $TMPO $TMPC 2> /dev/null ; then - gcc_major="3" -fi -cat > $TMPC <= 4 -return 0; -#else -#error gcc < 4 -#endif -} -EOF - -if $cc -o $TMPO $TMPC 2> /dev/null ; then - gcc_major="4" -fi - -if test x"$1" = x"-h" -o x"$1" = x"--help" ; then -cat << EOF - -Usage: configure [options] -Options: [defaults in brackets after descriptions] - -EOF -echo "Standard options:" -echo " --help print this message" -echo " --prefix=PREFIX install in PREFIX [$prefix]" -echo " --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX" -echo " [same as prefix]" -echo " --bindir=DIR user executables in DIR [EPREFIX/bin]" -echo " --libdir=DIR object code libraries in DIR [EPREFIX/lib]" -echo " --includedir=DIR C header files in DIR [PREFIX/include]" -echo " --mandir=DIR man documentation in DIR [PREFIX/man]" -echo " --enable-cross build cross compilers" -echo "" -echo "Advanced options (experts only):" -echo " --source-path=PATH path of source code [$source_path]" -echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]" -echo " --sysroot=PREFIX prepend PREFIX to library/include paths []" -echo " --cc=CC use C compiler CC [$cc]" -echo " --with-libgcc use /lib/libgcc_s.so.1 instead of libtcc1.a" -echo "" -#echo "NOTE: The object files are build at the place where configure is launched" -exit 1 -fi - -if test "$mingw32" = "yes" ; then - if test -z "$prefix" ; then - prefix="C:/Program Files/tcc" - fi - execprefix="$prefix" - bindir="$prefix" - tccdir="$prefix" - docdir="$prefix/doc" -else - if test -z "$prefix" ; then - prefix="/usr/local" - fi - if test x"$execprefix" = x""; then - execprefix="${prefix}" - fi - if test x"$bindir" = x""; then - bindir="${execprefix}/bin" - fi - if test x"$docdir" = x""; then - docdir="$prefix/share/doc/tcc" - fi -fi # mingw32 - -if test x"$libdir" = x""; then -libdir="${execprefix}/lib" -fi -if test x"$tccdir" = x""; then -tccdir="${execprefix}/lib/tcc" -fi -if test x"$mandir" = x""; then -mandir="${prefix}/man" -fi -if test x"$includedir" = x""; then -includedir="${prefix}/include" -fi - -echo "Binary directory $bindir" -echo "TinyCC directory $tccdir" -echo "Library directory $libdir" -echo "Include directory $includedir" -echo "Manual directory $mandir" -echo "Doc directory $docdir" -echo "Target root prefix $sysroot" -echo "Source path $source_path" -echo "C compiler $cc" -echo "CPU $cpu" -echo "Big Endian $bigendian" -echo "gprof enabled $gprof" -echo "cross compilers $build_cross" -echo "use libgcc $use_libgcc" - -echo "Creating config.mak and config.h" - -echo "# Automatically generated by configure - do not modify" > config.mak -echo "/* Automatically generated by configure - do not modify */" > $TMPH - -echo "prefix=$prefix" >> config.mak -echo "bindir=$bindir" >> config.mak -echo "tccdir=$tccdir" >> config.mak -echo "libdir=$libdir" >> config.mak -echo "includedir=$includedir" >> config.mak -echo "mandir=$mandir" >> config.mak -echo "docdir=$docdir" >> config.mak -echo "#define CONFIG_SYSROOT \"$sysroot\"" >> $TMPH -echo "#define CONFIG_TCCDIR \"$tccdir\"" >> $TMPH -echo "CC=$cc" >> config.mak -echo "GCC_MAJOR=$gcc_major" >> config.mak -echo "#define GCC_MAJOR $gcc_major" >> $TMPH -echo "HOST_CC=$host_cc" >> config.mak -echo "AR=$ar" >> config.mak -echo "STRIP=$strip -s -R .comment -R .note" >> config.mak -echo "CFLAGS=$CFLAGS" >> config.mak -echo "LDFLAGS=$LDFLAGS" >> config.mak -echo "LIBSUF=$LIBSUF" >> config.mak -echo "EXESUF=$EXESUF" >> config.mak -if test "$cpu" = "x86" ; then - echo "ARCH=i386" >> config.mak - echo "#define HOST_I386 1" >> $TMPH -elif test "$cpu" = "x86-64" ; then - echo "ARCH=x86-64" >> config.mak - echo "#define HOST_X86_64 1" >> $TMPH -elif test "$cpu" = "armv4l" ; then - echo "ARCH=arm" >> config.mak - echo "#define HOST_ARM 1" >> $TMPH -elif test "$cpu" = "powerpc" ; then - echo "ARCH=ppc" >> config.mak - echo "#define HOST_PPC 1" >> $TMPH -elif test "$cpu" = "mips" ; then - echo "ARCH=mips" >> config.mak - echo "#define HOST_MIPS 1" >> $TMPH -elif test "$cpu" = "s390" ; then - echo "ARCH=s390" >> config.mak - echo "#define HOST_S390 1" >> $TMPH -elif test "$cpu" = "alpha" ; then - echo "ARCH=alpha" >> config.mak - echo "#define HOST_ALPHA 1" >> $TMPH -else - echo "Unsupported CPU" - exit 1 -fi -if test "$noldl" = "yes" ; then - echo "CONFIG_NOLDL=yes" >> config.mak -fi -if test "$mingw32" = "yes" ; then - echo "CONFIG_WIN32=yes" >> config.mak - echo "#define CONFIG_WIN32 1" >> $TMPH -fi -if test "$bigendian" = "yes" ; then - echo "WORDS_BIGENDIAN=yes" >> config.mak - echo "#define WORDS_BIGENDIAN 1" >> $TMPH -fi -if test "$gprof" = "yes" ; then - echo "TARGET_GPROF=yes" >> config.mak - echo "#define HAVE_GPROF 1" >> $TMPH -fi -if test "$build_cross" = "yes" ; then - echo "CONFIG_CROSS=yes" >> config.mak -fi -if test "$use_libgcc" = "yes" ; then - echo "#define CONFIG_USE_LIBGCC" >> $TMPH - echo "CONFIG_USE_LIBGCC=yes" >> config.mak -fi -version=`head $source_path/VERSION` -echo "VERSION=$version" >>config.mak -echo "#define TCC_VERSION \"$version\"" >> $TMPH -echo "@set VERSION $version" > config.texi - -# build tree in object directory if source path is different from current one -if test "$source_path_used" = "yes" ; then - DIRS="tests" - FILES="Makefile tests/Makefile" - for dir in $DIRS ; do - mkdir -p $dir - done - for f in $FILES ; do - ln -sf $source_path/$f $f - done -fi -echo "SRC_PATH=$source_path" >> config.mak - -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 $TMPO $TMPC $TMPE $TMPS $TMPH diff --git a/05/tcc-0.9.25/ctype.h b/05/tcc-0.9.25/ctype.h deleted file mode 100644 index ed6833d..0000000 --- a/05/tcc-0.9.25/ctype.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef _CTYPE_H -#define _CTYPE_H - -#include - -int islower(int c) { - return c >= 'a' && c <= 'z'; -} - -int isupper(int c) { - return c >= 'A' && c <= 'Z'; -} - -int isalpha(int c) { - return isupper(c) || islower(c); -} - -int isalnum(int c) { - return isalpha(c) || isdigit(c); -} - -int isprint(int c) { - if (isalnum(c)) return 1; - switch (c) { - case '!': return 1; - case '@': return 1; - case '#': return 1; - case '$': return 1; - case '%': return 1; - case '^': return 1; - case '&': return 1; - case '*': return 1; - case '(': return 1; - case ')': return 1; - case '-': return 1; - case '=': return 1; - case '_': return 1; - case '+': return 1; - case '`': return 1; - case '~': return 1; - case '[': return 1; - case '{': return 1; - case ']': return 1; - case '}': return 1; - case '\\': return 1; - case '|': return 1; - case ';': return 1; - case ':': return 1; - case '\'': return 1; - case '"': return 1; - case ',': return 1; - case '<': return 1; - case '.': return 1; - case '>': return 1; - case '/': return 1; - case '?': return 1; - } - return 0; -} - -int iscntrl(int c) { - return !isprint(c); -} - -int isgraph(int c) { - return isprint(c) && c != ' '; -} - -int ispunct(int c) { - return isprint(c) && c != ' ' && !isalnum(c); -} - -int isxdigit(int c) { - if (isdigit(c)) return 1; - if (c >= 'a' && c <= 'f') return 1; - if (c >= 'A' && c <= 'F') return 1; - return 0; -} - -int tolower(int c) { - if (c >= 'A' && c <= 'Z') - return c - 'A' + 'a'; - return c; -} - -int toupper(int c) { - if (c >= 'a' && c <= 'z') - return c - 'a' + 'A'; - return c; -} - -#endif // _CTYPE_H diff --git a/05/tcc-0.9.25/elf.h b/05/tcc-0.9.25/elf.h deleted file mode 100644 index d728766..0000000 --- a/05/tcc-0.9.25/elf.h +++ /dev/null @@ -1,1714 +0,0 @@ -/* This file defines standard ELF types, structures, and macros. - Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ian Lance Taylor . - - 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. */ - -#ifndef _ELF_H -#define _ELF_H 1 - -#ifndef _WIN32 -#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; -#endif - -typedef unsigned char uint8_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long int uint64_t; -#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 of symbol indices. */ -typedef uint32_t Elf32_Symndx; -typedef uint64_t Elf64_Symndx; - - -/* 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_SYSV 0 /* UNIX System V ABI */ -#define ELFOSABI_HPUX 1 /* HP-UX */ -#define ELFOSABI_FREEBSD 9 /* Free BSD */ -#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_LOPROC 0xff00 /* Processor-specific */ -#define ET_HIPROC 0xffff /* Processor-specific */ - -/* 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_486 6 /* Intel 80486 */ -#define EM_860 7 /* Intel 80860 */ -#define EM_MIPS 8 /* MIPS R3000 big-endian */ -#define EM_S370 9 /* Amdahl */ -#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ -#define EM_RS6000 11 /* RS6000 */ - -#define EM_PARISC 15 /* HPPA */ -#define EM_nCUBE 16 /* nCUBE */ -#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_V800 36 /* NEC V800 series */ -#define EM_FR20 37 /* Fujitsu FR20 */ -#define EM_RH32 38 /* TRW RH32 */ -#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 embeeded 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_NUM 95 - -/* 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_HIPROC 0xff1f /* End of processor-specific */ -#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ -#define SHN_COMMON 0xfff2 /* Associated symbol is common */ -#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_NUM 12 /* Number of defined types. */ -#define SHT_LOOS 0x60000000 /* Start OS-specific */ -#define SHT_LOSUNW 0x6ffffffb /* Sun-specific low bound. */ -#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_ARM_EXIDX 0x70000001 /* Exception Index table */ -#define SHT_ARM_PREEMPTMAP 0x70000002 /* dynamic linking pre-emption map */ -#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attrs */ -#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_MASKPROC 0xf0000000 /* Processor-specific */ - -/* 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; /* No defined meaning, 0 */ - 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; /* No defined meaning, 0 */ - 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 - - -/* Special section index. */ -#undef SHN_UNDEF -#define SHN_UNDEF 0 /* No section, undefined symbol. */ - -/* 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_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_NUM 5 /* Number of defined types. */ -#define STT_LOOS 11 /* Start of OS-specific */ -#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; - -/* 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_NUM 7 /* Number of defined types. */ -#define PT_LOOS 0x60000000 /* Start of OS-specific */ -#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_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_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_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 */ - -/* 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 */ -#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_NUM 29 /* Number used */ -#define DT_LOOS 0x60000000 /* Start of OS-specific */ -#define DT_HIOS 0x6fffffff /* 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_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 - -/* 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_SYMINFO 0x6ffffeff /* syminfo table */ -#define DT_ADDRRNGHI 0x6ffffeff - -/* The versioning entry types. The next are defined as part of the - GNU extension. */ -#define DT_VERSYM 0x6ffffff0 - -/* 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 - -/* 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. */ - -/* 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 */ - -/* Auxialiary 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. */ -#undef VER_FLG_WEAK -#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 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 -{ - int a_type; /* Entry type */ - union - { - long int a_val; /* Integer value */ - void *a_ptr; /* Pointer value */ - void (*a_fcn) (void); /* Function pointer value */ - } a_un; -} Elf32_auxv_t; - -typedef struct -{ - long int a_type; /* Entry type */ - union - { - long int a_val; /* Integer value */ - void *a_ptr; /* Pointer value */ - void (*a_fcn) (void); /* Function pointer value */ - } 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 */ - -/* 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 17 /* Used FPU control word. */ - - -/* 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 ELF_NOTE_ABI 1 - -/* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI - note section entry. */ -#define ELF_NOTE_OS_LINUX 0 -#define ELF_NOTE_OS_GNU 1 -#define ELF_NOTE_OS_SOLARIS2 2 - - -/* Motorola 68k specific definitions. */ - -/* 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 */ -/* Keep this the last entry. */ -#define R_68K_NUM 23 - -/* 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 */ -/* Keep this the last entry. */ -#define R_386_NUM 11 - -/* SUN SPARC specific definitions. */ - -/* 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_EXT_MASK 0xFFFF00 -#define EF_SPARC_SUN_US1 0x000200 -#define EF_SPARC_HAL_R1 0x000400 - -/* 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 /* ?? */ -#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 miggle 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_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 */ -/* Keep this the last entry. */ -#define R_SPARC_NUM 56 - -/* 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_NUM 24 - -/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ - -#define DT_SPARC_REGISTER 0x70000001 -#define DT_SPARC_NUM 2 - -/* Bits present in AT_HWCAP, primarily for Sparc32. */ - -#define HWCAP_SPARC_FLUSH 1 /* The cpu supports flush insn. */ -#define HWCAP_SPARC_STBAR 2 -#define HWCAP_SPARC_SWAP 4 -#define HWCAP_SPARC_MULDIV 8 -#define HWCAP_SPARC_V9 16 /* The cpu is v9, so v8plus is ok. */ - -/* 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. */ - -/* 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. */ - -/* 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_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 -/* Keep this the last entry. */ -#define R_MIPS_NUM 38 - -/* 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. */ -#define DT_MIPS_NUM 0x32 - -/* 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_TRAPNL 1 /* Trap nil pointer dereference. */ -#define EF_PARISC_EXT 2 /* Program uses arch. extensions. */ -#define EF_PARISC_ARCH 0xffff0000 /* Architecture version. */ -/* Defined values are: - 0x020b PA-RISC 1.0 big-endian - 0x0210 PA-RISC 1.1 big-endian - 0x028b PA-RISC 1.0 little-endian - 0x0290 PA-RISC 1.1 little-endian -*/ - -/* Legal values for sh_type field of Elf32_Shdr. */ - -#define SHT_PARISC_GOT 0x70000000 /* GOT for external data. */ -#define SHT_PARISC_ARCH 0x70000001 /* Architecture extensions. */ -#define SHT_PARISC_GLOBAL 0x70000002 /* Definition of $global$. */ -#define SHT_PARISC_MILLI 0x70000003 /* Millicode routines. */ -#define SHT_PARISC_UNWIND 0x70000004 /* Unwind information. */ -#define SHT_PARISC_PLT 0x70000005 /* Procedure linkage table. */ -#define SHT_PARISC_SDATA 0x70000006 /* Short initialized data. */ -#define SHT_PARISC_SBSS 0x70000007 /* Short uninitialized data. */ -#define SHT_PARISC_SYMEXTN 0x70000008 /* Argument/relocation info. */ -#define SHT_PARISC_STUBS 0x70000009 /* Linker stubs. */ - -/* Legal values for sh_flags field of Elf32_Shdr. */ - -#define SHF_PARISC_GLOBAL 0x10000000 /* Section defines dp. */ -#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ - -/* Legal values for ST_TYPE subfield of st_info (symbol type). */ - -#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ - -/* 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_DIR14R 4 /* Right 14 bits of eff. address. */ -#define R_PARISC_PCREL21L 5 /* PC-relative, left 21 bits. */ -#define R_PARISC_PCREL14R 6 /* PC-relative, right 14 bits. */ -#define R_PARISC_PCREL17C 7 /* Conditional PC-relative, ignore - if displacement > 17bits. */ -#define R_PARISC_PCREL17F 8 /* Conditional PC-relative, must - fit in 17bits. */ -#define R_PARISC_DPREL21L 9 /* DP-relative, left 21 bits. */ -#define R_PARISC_DPREL14R 10 /* DP-relative, right 14 bits. */ -#define R_PARISC_DPREL14F 11 /* DP-relative, must bit in 14 bits. */ -#define R_PARISC_DLTREL21L 12 /* DLT-relative, left 21 bits. */ -#define R_PARISC_DLTREL14R 13 /* DLT-relative, right 14 bits. */ -#define R_PARISC_DLTREL14F 14 /* DLT-relative, must fit in 14 bits.*/ -#define R_PARISC_DLTIND21L 15 /* DLT-relative indirect, left - 21 bits. */ -#define R_PARISC_DLTIND14R 16 /* DLT-relative indirect, right - 14 bits. */ -#define R_PARISC_DLTIND14F 17 /* DLT-relative indirect, must fit - int 14 bits. */ -#define R_PARISC_PLABEL32 18 /* Direct 32-bit reference to proc. */ - -/* 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 primerily 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_OP_PUSH 12 /* OP stack push */ -#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */ -#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */ -#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */ -#define R_ALPHA_GPVALUE 16 -#define R_ALPHA_GPRELHIGH 17 -#define R_ALPHA_GPRELLOW 18 -#define R_ALPHA_IMMED_GP_16 19 -#define R_ALPHA_IMMED_GP_HI32 20 -#define R_ALPHA_IMMED_SCN_HI32 21 -#define R_ALPHA_IMMED_BR_HI32 22 -#define R_ALPHA_IMMED_LO32 23 -#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 */ -/* Keep this the last entry. */ -#define R_ALPHA_NUM 28 - - -/* PowerPC specific declarations */ - -/* 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 -/* Keep this the last entry. */ -#define R_PPC_NUM 37 - -/* 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 */ - -/* This is a phony reloc to handle any old fashioned TOC16 references - that may still be in object files. */ -#define R_PPC_TOC16 255 - - -/* 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_ALIGN8 0x40 /* 8-bit structure alignment is in use */ -#define EF_NEW_ABI 0x80 -#define EF_OLD_ABI 0x100 - -/* Additional symbol types for Thumb */ -#define STT_ARM_TFUNC 0xd - -/* 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 */ - -/* 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 -#define R_ARM_THM_SWI8 14 -#define R_ARM_XPC25 15 -#define R_ARM_THM_XPC22 16 -#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_GOTOFF32 24 /* 32 bit offset to GOT */ -#define R_ARM_BASE_PREL 25 /* 32 bit PC relative offset to GOT */ -#define R_ARM_GOT_BREL 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_PREL31 42 -#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_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_C60HI16 0x55 // high 16 bit MVKH embedded -#define R_C60LO16 0x54 // low 16 bit MVKL embedded - -#ifdef TCC_TARGET_X86_64 -#define TCC_ELFCLASS ELFCLASS64 -#define ElfW(type) Elf##64##_##type -#define ELFW(type) ELF##64##_##type -#else -#define TCC_ELFCLASS ELFCLASS32 -#define ElfW(type) Elf##32##_##type -#define ELFW(type) ELF##32##_##type -#endif - -#endif /* elf.h */ diff --git a/05/tcc-0.9.25/errno.h b/05/tcc-0.9.25/errno.h deleted file mode 100644 index 426f351..0000000 --- a/05/tcc-0.9.25/errno.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ERRNO_H -#define _ERRNO_H - -#include // we define all the relevant things here - -#endif // _ERRNO_H diff --git a/05/tcc-0.9.25/float.h b/05/tcc-0.9.25/float.h deleted file mode 100644 index 6ae607d..0000000 --- a/05/tcc-0.9.25/float.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _FLOAT_H -#define _FLOAT_H - -#define DBL_DIG 15 -#define DBL_EPSILON 2.2204460492503131e-16 -#define DBL_MANT_DIG 53 -#define DBL_MAX 1.7976931348623157e+308 -#define DBL_MAX_10_EXP 308 -#define DBL_MAX_EXP 1024 -#define DBL_MIN 2.2250738585072027e-308 -#define DBL_MIN_10_EXP (-307) -#define DBL_MIN_EXP (-1021) -#define FLT_DIG 6 -#define FLT_EPSILON 1.19209290e-07 -#define FLT_MANT_DIG 24 -#define FLT_MAX 3.40282347e+38 -#define FLT_MAX_10_EXP +38 -#define FLT_MAX_EXP 128 -#define FLT_MIN 1.17549435e-38 -#define FLT_MIN_10_EXP (-37) -#define FLT_MIN_EXP (-125) -#define FLT_RADIX 2 -#define FLT_ROUNDS 1 -#define LDBL_DIG DBL_DIG -#define LDBL_EPSILON DBL_EPSILON -#define LDBL_MANT_DIG DBL_MANT_DIG -#define LDBL_MAX DBL_MAX -#define LDBL_MAX_10_EXP DBL_MAX_10_EXP -#define LDBL_MAX_EXP DBL_MAX_EXP -#define LDBL_MIN DBL_MIN -#define LDBL_MIN_10_EXP DBL_MIN_10_EXP -#define LDBL_MIN_EXP DBL_MIN_EXP - -#endif // _FLOAT_H diff --git a/05/tcc-0.9.25/i386-asm.c b/05/tcc-0.9.25/i386-asm.c deleted file mode 100644 index 21b28d7..0000000 --- a/05/tcc-0.9.25/i386-asm.c +++ /dev/null @@ -1,1211 +0,0 @@ -/* - * i386 specific functions for TCC assembler - * - * 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 - */ - -#define MAX_OPERANDS 3 - -typedef struct ASMInstr { - uint16_t sym; - uint16_t opcode; - uint16_t instr_type; -#define OPC_JMP 0x01 /* jmp operand */ -#define OPC_B 0x02 /* only used zith OPC_WL */ -#define OPC_WL 0x04 /* accepts w, l or no suffix */ -#define OPC_BWL (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */ -#define OPC_REG 0x08 /* register is added to opcode */ -#define OPC_MODRM 0x10 /* modrm encoding */ -#define OPC_FWAIT 0x20 /* add fwait opcode */ -#define OPC_TEST 0x40 /* test opcodes */ -#define OPC_SHIFT 0x80 /* shift opcodes */ -#define OPC_D16 0x0100 /* generate data16 prefix */ -#define OPC_ARITH 0x0200 /* arithmetic opcodes */ -#define OPC_SHORTJMP 0x0400 /* short jmp operand */ -#define OPC_FARITH 0x0800 /* FPU arithmetic opcodes */ -#define OPC_GROUP_SHIFT 13 - -/* in order to compress the operand type, we use specific operands and - we or only with EA */ -#define OPT_REG8 0 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_REG16 1 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_REG32 2 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_MMX 3 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_SSE 4 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_CR 5 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_TR 6 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_DB 7 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_SEG 8 -#define OPT_ST 9 -#define OPT_IM8 10 -#define OPT_IM8S 11 -#define OPT_IM16 12 -#define OPT_IM32 13 -#define OPT_EAX 14 /* %al, %ax or %eax register */ -#define OPT_ST0 15 /* %st(0) register */ -#define OPT_CL 16 /* %cl register */ -#define OPT_DX 17 /* %dx register */ -#define OPT_ADDR 18 /* OP_EA with only offset */ -#define OPT_INDIR 19 /* *(expr) */ - -/* composite types */ -#define OPT_COMPOSITE_FIRST 20 -#define OPT_IM 20 /* IM8 | IM16 | IM32 */ -#define OPT_REG 21 /* REG8 | REG16 | REG32 */ -#define OPT_REGW 22 /* REG16 | REG32 */ -#define OPT_IMW 23 /* IM16 | IM32 */ - -/* can be ored with any OPT_xxx */ -#define OPT_EA 0x80 - - uint8_t nb_ops; - uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */ -} ASMInstr; - -typedef struct Operand { - uint32_t type; -#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) - -#define OP_EA 0x40000000 -#define OP_REG (OP_REG8 | OP_REG16 | OP_REG32) -#define OP_IM OP_IM32 - 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[5] = { -/* - [OP_REG8] = 0, - [OP_REG16] = 1, - [OP_REG32] = 2, -*/ - 0, 0, 1, 0, 2 -}; - -#define WORD_PREFIX_OPCODE 0x66 - -#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 -#define DEF_ASM_OP0(name, opcode) -#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 }, -#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }}, -#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }}, -#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }}, -#include "i386-asm.h" - - /* 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) -#include "i386-asm.h" -}; - -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; -} - -static int asm_parse_reg(void) -{ - int reg; - if (tok != '%') - goto error_32; - next(); - if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) { - reg = tok - TOK_ASM_eax; - next(); - return reg; - } else { - error_32: - expect("32 bit register"); - return 0; - } -} - -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_EAX) - op->type |= OP_EAX; - else if (op->type == OP_REG8 && op->reg == TREG_ECX) - op->type |= OP_CL; - else if (op->type == OP_REG16 && op->reg == TREG_EDX) - 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.cstr->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; - } else { - reg_error: - error("unknown register"); - } - next(); - no_skip: ; - } else if (tok == '$') { - /* constant value */ - next(); - asm_expr(s1, &e); - op->type = OP_IM32; - op->e.v = e.v; - op->e.sym = e.sym; - 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; - } - } 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.v = e.v; - op->e.sym = e.sym; - } else { - op->e.v = 0; - op->e.sym = NULL; - } - if (tok == '(') { - next(); - if (tok != ',') { - op->reg = asm_parse_reg(); - } - if (tok == ',') { - next(); - if (tok != ',') { - op->reg2 = asm_parse_reg(); - } - if (tok == ',') { - next(); - op->shift = get_reg_shift(s1); - } - } - skip(')'); - } - if (op->reg == -1 && op->reg2 == -1) - op->type |= OP_ADDR; - } - op->type |= indir; -} - -/* XXX: unify with C code output ? */ -static void gen_expr32(ExprValue *pe) -{ - if (pe->sym) - greloc(cur_text_section, pe->sym, ind, R_386_32); - gen_le32(pe->v); -} - -/* XXX: unify with C code output ? */ -static void gen_disp32(ExprValue *pe) -{ - Sym *sym; - sym = pe->sym; - if (sym) { - if (sym->r == 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 + (long)sym->next - ind - 4); - } else { - greloc(cur_text_section, sym, ind, R_386_PC32); - gen_le32(pe->v - 4); - } - } else { - /* put an empty PC32 relocation */ - put_elf_reloc(symtab_section, cur_text_section, - ind, R_386_PC32, 0); - gen_le32(pe->v - 4); - } -} - - -static void gen_le16(int v) -{ - g(v); - g(v >> 8); -} - -/* generate the modrm operand */ -static inline void 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 */ - g(0x05 + (reg << 3)); - gen_expr32(&op->e); - } 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); - } - } -} - -static void asm_opcode(TCCState *s1, int opcode) -{ - const ASMInstr *pa; - int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix; - int nb_ops, s, ss; - Operand ops[MAX_OPERANDS], *pop; - int op_type[3]; /* decoded op type */ - - /* get operands */ - pop = ops; - nb_ops = 0; - seg_prefix = 0; - for(;;) { - if (tok == ';' || tok == TOK_LINEFEED) - break; - if (nb_ops >= MAX_OPERANDS) { - error("incorrect number of operands"); - } - parse_operand(s1, pop); - if (tok == ':') { - if (pop->type != OP_SEG || seg_prefix) { - error("incorrect prefix"); - } - seg_prefix = segment_prefixes[pop->reg]; - next(); - parse_operand(s1, pop); - if (!(pop->type & OP_EA)) { - error("segment prefix must be followed by memory reference"); - } - } - pop++; - nb_ops++; - if (tok != ',') - break; - next(); - } - - is_short_jmp = 0; - s = 0; /* avoid warning */ - - /* optimize matching by using a lookup table (no hashing is needed - !) */ - for(pa = asm_instrs; pa->sym != 0; pa++) { - s = 0; - if (pa->instr_type & OPC_FARITH) { - v = opcode - pa->sym; - if (!((unsigned)v < 8 * 6 && (v % 6) == 0)) - continue; - } else if (pa->instr_type & OPC_ARITH) { - if (!(opcode >= pa->sym && opcode < pa->sym + 8 * 4)) - continue; - goto compute_size; - } else if (pa->instr_type & OPC_SHIFT) { - if (!(opcode >= pa->sym && opcode < pa->sym + 7 * 4)) - continue; - goto compute_size; - } else if (pa->instr_type & OPC_TEST) { - if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES)) - continue; - } else if (pa->instr_type & OPC_B) { - if (!(opcode >= pa->sym && opcode <= pa->sym + 3)) - continue; - compute_size: - s = (opcode - pa->sym) & 3; - } else if (pa->instr_type & OPC_WL) { - if (!(opcode >= pa->sym && opcode <= pa->sym + 2)) - continue; - s = opcode - pa->sym + 1; - } else { - if (pa->sym != opcode) - continue; - } - if (pa->nb_ops != nb_ops) - continue; - /* now decode and check each operand */ - 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; - break; - case OPT_REGW: - v = OP_REG16 | OP_REG32; - break; - case OPT_IMW: - v = OP_IM16 | OP_IM32; - 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; - } - /* all is matching ! */ - break; - next: ; - } - if (pa->sym == 0) { - if (opcode >= TOK_ASM_pusha && opcode <= TOK_ASM_emms) { - int b; - b = op0_codes[opcode - TOK_ASM_pusha]; - if (b & 0xff00) - g(b >> 8); - g(b); - return; - } else { - error("unknown opcode '%s'", - get_tok_str(opcode, NULL)); - } - } - /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */ - if (s == 3) { - for(i = 0; s == 3 && i < nb_ops; 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 == 3) { - if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) && - (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32))) - s = 2; - else - error("cannot infer opcode suffix"); - } - } - - /* generate data16 prefix if needed */ - ss = s; - if (s == 1 || (pa->instr_type & OPC_D16)) - g(WORD_PREFIX_OPCODE); - else if (s == 2) - s = 1; - /* now generates the operation */ - if (pa->instr_type & OPC_FWAIT) - g(0x9b); - if (seg_prefix) - g(seg_prefix); - - v = pa->opcode; - if (v == 0x69 || v == 0x69) { - /* kludge for imul $im, %reg */ - nb_ops = 3; - ops[2] = ops[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) >> 2) << 3; - } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) { - /* fpu arith case */ - v += ((opcode - pa->sym) / 6) << 3; - } - if (pa->instr_type & OPC_REG) { - for(i = 0; i < nb_ops; i++) { - if (op_type[i] & (OP_REG | OP_ST)) { - v += ops[i].reg; - break; - } - } - /* mov $im, %reg case */ - if (pa->opcode == 0xb0 && s >= 1) - v += 7; - } - if (pa->instr_type & OPC_B) - v += s; - if (pa->instr_type & OPC_TEST) - v += test_bits[opcode - pa->sym]; - if (pa->instr_type & OPC_SHORTJMP) { - Sym *sym; - int jmp_disp; - - /* see if we can really generate the jump with a byte offset */ - sym = ops[0].e.sym; - if (!sym) - goto no_short_jump; - if (sym->r != cur_text_section->sh_num) - goto no_short_jump; - jmp_disp = ops[0].e.v + (long)sym->next - ind - 2; - if (jmp_disp == (int8_t)jmp_disp) { - /* OK to generate jump */ - is_short_jmp = 1; - ops[0].e.v = jmp_disp; - } else { - no_short_jump: - if (pa->instr_type & OPC_JMP) { - /* long jump will be allowed. need to modify the - opcode slightly */ - if (v == 0xeb) - v = 0xe9; - else - v += 0x0f10; - } else { - error("invalid displacement"); - } - } - } - op1 = v >> 8; - if (op1) - g(op1); - g(v); - - /* search which operand will used for modrm */ - modrm_index = 0; - if (pa->instr_type & OPC_SHIFT) { - reg = (opcode - pa->sym) >> 2; - if (reg == 6) - reg = 7; - } else if (pa->instr_type & OPC_ARITH) { - reg = (opcode - pa->sym) >> 2; - } else if (pa->instr_type & OPC_FARITH) { - reg = (opcode - pa->sym) / 6; - } else { - reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7; - } - if (pa->instr_type & OPC_MODRM) { - /* 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 - 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++) { - v = op_type[i]; - if (i != modrm_index && - (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) { - reg = ops[i].reg; - break; - } - } - - asm_modrm(reg, &ops[modrm_index]); - } - - /* emit constants */ - if (pa->opcode == 0x9a || pa->opcode == 0xea) { - /* ljmp or lcall kludge */ - gen_expr32(&ops[1].e); - if (ops[0].e.sym) - error("cannot relocate"); - gen_le16(ops[0].e.v); - } else { - for(i = 0;i < nb_ops; i++) { - v = op_type[i]; - if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM8S | OP_ADDR)) { - /* if multiple sizes are given it means we must look - at the op size */ - if (v == (OP_IM8 | OP_IM16 | OP_IM32) || - v == (OP_IM16 | OP_IM32)) { - if (ss == 0) - v = OP_IM8; - else if (ss == 1) - v = OP_IM16; - else - v = OP_IM32; - } - if (v & (OP_IM8 | OP_IM8S)) { - if (ops[i].e.sym) - goto error_relocate; - g(ops[i].e.v); - } else if (v & OP_IM16) { - if (ops[i].e.sym) { - error_relocate: - error("cannot relocate"); - } - gen_le16(ops[i].e.v); - } else { - if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) { - if (is_short_jmp) - g(ops[i].e.v); - else - gen_disp32(&ops[i].e); - } else { - gen_expr32(&ops[i].e); - } - } - } - } - } -} - -#define NB_SAVED_REGS 3 -#define NB_ASM_REGS 8 - -/* 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': - pr = 3; - break; - case 'N': - case 'M': - case 'I': - case 'i': - case 'm': - case 'g': - pr = 4; - break; - default: - 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; -} - -#define REG_OUT_MASK 0x01 -#define REG_IN_MASK 0x02 - -#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) - -static 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;iinput_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;iconstraint; - 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) - error("invalid reference in constraint %d ('%s')", - i, str); - op->ref_index = k; - if (operands[k].input_index >= 0) - error("cannot reference twice the same operand"); - operands[k].input_index = i; - op->priority = 5; - } else { - op->priority = constraint_priority(str); - } - } - - /* sort operands according to their priority */ - for(i=0;iconstraint; - /* 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; - } - try_next: - c = *str++; - switch(c) { - case '=': - goto try_next; - case '+': - op->is_rw = 1; - /* FALL THRU */ - case '&': - if (j >= nb_outputs) - 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_EAX) || - is_reg_allocated(TREG_EDX)) - goto try_next; - op->is_llong = 1; - op->reg = TREG_EAX; - regs_allocated[TREG_EAX] |= reg_mask; - regs_allocated[TREG_EDX] |= reg_mask; - break; - case 'a': - reg = TREG_EAX; - goto alloc_reg; - case 'b': - reg = 3; - goto alloc_reg; - case 'c': - reg = TREG_ECX; - goto alloc_reg; - case 'd': - reg = TREG_EDX; - 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': - /* 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 '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: - 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;ireg >= 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; - } - error("could not find free output register for reloading"); - reg_found2: - *pout_reg = reg; - break; - } - } - - /* print sorted constraints */ -#ifdef ASM_DEBUG - for(i=0;iid ? 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 -} - -static 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') - cstr_ccat(add_str, '$'); - if (r & VT_SYM) { - cstr_cat(add_str, get_tok_str(sv->sym->v, NULL)); - if (sv->c.i != 0) { - cstr_ccat(add_str, '+'); - } else { - return; - } - } - val = sv->c.i; - if (modifier == 'n') - val = -val; - snprintf(buf, sizeof(buf), "%d", sv->c.i); - cstr_cat(add_str, buf); - } else if ((r & VT_VALMASK) == VT_LOCAL) { - snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i); - cstr_cat(add_str, buf); - } else if (r & VT_LVAL) { - reg = r & VT_VALMASK; - if (reg >= VT_CONST) - error("internal compiler error"); - snprintf(buf, sizeof(buf), "(%%%s)", - get_tok_str(TOK_ASM_eax + reg, NULL)); - cstr_cat(add_str, buf); - } else { - /* register case */ - reg = r & VT_VALMASK; - if (reg >= VT_CONST) - error("internal compiler error"); - - /* choose register operand size */ - if ((sv->type.t & VT_BTYPE) == VT_BYTE) - size = 1; - else if ((sv->type.t & VT_BTYPE) == VT_SHORT) - size = 2; - else - size = 4; - if (size == 1 && reg >= 4) - size = 4; - - if (modifier == 'b') { - if (reg >= 4) - error("cannot use byte register"); - size = 1; - } else if (modifier == 'h') { - if (reg >= 4) - error("cannot use byte register"); - size = -1; - } else if (modifier == 'w') { - size = 2; - } - - 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; - } - snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL)); - cstr_cat(add_str, buf); - } -} - -/* generate prolog and epilog code for asm statment */ -static 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; - static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 }; - - /* 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 < NB_SAVED_REGS; i++) { - reg = reg_saved[i]; - if (regs_allocated[reg]) - 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; - 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.ul += 4; - load(TREG_EDX, &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; - load(out_reg, &sv); - - 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.ul += 4; - store(TREG_EDX, &sv); - } - } - } - } - /* generate reg restore code */ - for(i = NB_SAVED_REGS - 1; i >= 0; i--) { - reg = reg_saved[i]; - if (regs_allocated[reg]) - g(0x58 + reg); - } - } -} - -static void asm_clobber(uint8_t *clobber_regs, const char *str) -{ - int reg; - TokenSym *ts; - - if (!strcmp(str, "memory") || - !strcmp(str, "cc")) - 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; - } else { - error("invalid clobber register '%s'", str); - } - clobber_regs[reg] = 1; -} diff --git a/05/tcc-0.9.25/i386-asm.h b/05/tcc-0.9.25/i386-asm.h deleted file mode 100644 index a3b28d4..0000000 --- a/05/tcc-0.9.25/i386-asm.h +++ /dev/null @@ -1,446 +0,0 @@ - DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */ - DEF_ASM_OP0(popa, 0x61) - DEF_ASM_OP0(clc, 0xf8) - 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(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(wait, 0x9b) - DEF_ASM_OP0(nop, 0x90) - DEF_ASM_OP0(xlat, 0xd7) - - /* strings */ -ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL)) - -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_BWL)) -ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL)) - -ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL)) - -ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL)) - -ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL)) - - /* bits */ - -ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) - -ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) - -ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) - -ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) - -ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) - - /* prefixes */ - DEF_ASM_OP0(aword, 0x67) - DEF_ASM_OP0(addr16, 0x67) - 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_BWL, OPT_ADDR, OPT_EAX)) -ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR)) -ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG)) - -ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32)) -ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32)) -ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32)) -ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR)) -ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB)) -ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR)) - -ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, 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_WL, 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_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S)) -ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32)) -ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG)) - -ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG)) - -ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX)) -ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG)) -ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, 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_WL, 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_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ -ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX)) -ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG)) - -ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX)) -ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) - -ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG)) -ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW)) -ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW)) - -ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) -ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) - - /* shifts */ -ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG)) - -ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) - -ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) -ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) - -ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) -ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA)) -ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32)) -ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, 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)) - DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8) - DEF_ASM_OP0(leave, 0xc9) - DEF_ASM_OP0(ret, 0xc3) -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_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR)) - DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) - - /* 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_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 ) - - /* segments */ - DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA) - DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32) - 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_WL, 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_BWL, OPT_REG, OPT_REG | OPT_EA )) -ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, 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, 0x62, 0, OPC_MODRM | OPC_D16, 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, OPT_REG32 | OPT_EA, OPT_REG32)) - - 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_MMX ) -ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 )) - DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX )) - DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - -#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/05/tcc-0.9.25/i386-gen.c b/05/tcc-0.9.25/i386-gen.c deleted file mode 100644 index f958ab5..0000000 --- a/05/tcc-0.9.25/i386-gen.c +++ /dev/null @@ -1,1034 +0,0 @@ -/* - * 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 - */ - -/* number of available registers */ -#define NB_REGS 4 - -/* 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_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_ST0, -}; - -int reg_classes[NB_REGS] = { - /* eax */ RC_INT | RC_EAX, - /* ecx */ RC_INT | RC_ECX, - /* edx */ RC_INT | RC_EDX, - /* st0 */ RC_FLOAT | RC_ST0, -}; - -/* 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 - -/******************************************************/ -/* ELF defines */ - -#define EM_TCC_TARGET EM_386 - -/* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_386_32 -#define R_JMP_SLOT R_386_JMP_SLOT -#define R_COPY R_386_COPY - -#define ELF_START_ADDR 0x08048000 -#define ELF_PAGE_SIZE 0x1000 - -/******************************************************/ - -static unsigned long func_sub_sp_offset; -static unsigned long func_bound_offset; -static int func_ret_sub; - -/* XXX: make it faster ? */ -void g(int c) -{ - int ind1; - ind1 = ind + 1; - if (ind1 > cur_text_section->data_allocated) - section_realloc(cur_text_section, ind1); - cur_text_section->data[ind] = c; - ind = ind1; -} - -void o(unsigned int c) -{ - while (c) { - g(c); - c = c >> 8; - } -} - -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 */ -void gsym_addr(int t, int a) -{ - int n, *ptr; - while (t) { - ptr = (int *)(cur_text_section->data + t); - n = *ptr; /* next value */ - *ptr = a - t - 4; - t = n; - } -} - -void gsym(int t) -{ - gsym_addr(t, ind); -} - -/* psym is used to put an instruction with a data field which is a - reference to a symbol. It is in fact the same as oad ! */ -#define psym oad - -/* instruction + 4 bytes data. Return the address of the data */ -static int oad(int c, int s) -{ - int ind1; - - o(c); - ind1 = ind + 4; - if (ind1 > cur_text_section->data_allocated) - section_realloc(cur_text_section, ind1); - *(int *)(cur_text_section->data + ind) = s; - s = ind; - ind = ind1; - return s; -} - -/* output constant with relocation if 'r & VT_SYM' is true */ -static 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); -} - -/* generate a modrm reference. 'op_reg' contains the addtionnal 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' */ -void load(int r, SValue *sv) -{ - int v, t, ft, fc, fr; - SValue v1; - - fr = sv->r; - ft = sv->type.t; - fc = sv->c.ul; - - 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.ul = fc; - load(r, &v1); - fr = r; - } - 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) { - 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) { - o(0x8d); /* lea xxx(%ebp), r */ - gen_modrm(r, VT_LOCAL, sv->sym, fc); - } 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' */ -void store(int r, SValue *v) -{ - int fr, bt, ft, fc; - - ft = v->type.t; - fc = v->c.ul; - fr = v->r & VT_VALMASK; - 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 */ - } -} - -/* '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) { - /* constant case */ - if (vtop->r & VT_SYM) { - /* relocation case */ - greloc(cur_text_section, vtop->sym, - ind + 1, R_386_PC32); - } else { - /* put an empty PC32 relocation */ - put_elf_reloc(symtab_section, cur_text_section, - ind + 1, R_386_PC32, 0); - } - oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */ - } else { - /* otherwise, indirect call */ - r = gv(RC_INT); - o(0xff); /* call/jmp *r */ - o(0xd0 + r + (is_jmp << 4)); - } -} - -static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX }; -static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX }; - -/* 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 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_CALL(func_sym->r); - /* 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; - } - } - gcall_or_jmp(0); - if (args_size && func_call != FUNC_STDCALL) - gadd_sp(args_size); - vtop--; -} - -#ifdef TCC_TARGET_PE -#define FUNC_PROLOG_SIZE 10 -#else -#define FUNC_PROLOG_SIZE 9 -#endif - -/* generate function prolog of type 't' */ -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 = FUNC_CALL(sym->r); - addr = 8; - loc = 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; - if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { - /* 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 ? */ - if (func_call == FUNC_STDCALL) - func_ret_sub = addr - 8; - - /* leave some room for bound checking code */ - if (tcc_state->do_bounds_check) { - oad(0xb8, 0); /* lbound section pointer */ - oad(0xb8, 0); /* call to function */ - func_bound_offset = lbounds_section->data_offset; - } -} - -/* 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) { - int saved_ind; - int *bounds_ptr; - Sym *sym, *sym_data; - /* add end of table info */ - bounds_ptr = section_ptr_add(lbounds_section, sizeof(int)); - *bounds_ptr = 0; - /* generate bound local allocation */ - saved_ind = ind; - ind = func_sub_sp_offset; - 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 */ - sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0); - greloc(cur_text_section, sym, - ind + 1, R_386_PC32); - oad(0xe8, -4); - 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 */ - sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0); - greloc(cur_text_section, sym, - ind + 1, R_386_PC32); - oad(0xe8, -4); - 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 + 3) & -4; - saved_ind = ind; - ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; -#ifdef TCC_TARGET_PE - if (v >= 4096) { - Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0); - oad(0xb8, v); /* mov stacksize, %eax */ - oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */ - greloc(cur_text_section, sym, ind-4, R_386_PC32); - } else -#endif - { - o(0xe58955); /* push %ebp, mov %esp, %ebp */ - o(0xec81); /* sub esp, stacksize */ - gen_le32(v); -#if FUNC_PROLOG_SIZE == 10 - o(0x90); /* adjust to FUNC_PROLOG_SIZE */ -#endif - } - ind = saved_ind; -} - -/* generate a jump to a label */ -int gjmp(int t) -{ - return psym(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); - } -} - -/* generate a test. set 'inv' to invert test. Stack entry is popped */ -int gtst(int inv, int t) -{ - int v, *p; - - v = vtop->r & VT_VALMASK; - if (v == VT_CMP) { - /* fast case : can jump directly since flags are set */ - g(0x0f); - t = psym((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 */ - p = &vtop->c.i; - while (*p != 0) - p = (int *)(cur_text_section->data + *p); - *p = t; - t = vtop->c.i; - } else { - t = gjmp(t); - gsym(vtop->c.i); - } - } else { - if (is_float(vtop->type.t) || - (vtop->type.t & VT_BTYPE) == VT_LLONG) { - 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); - } else { - v = gv(RC_INT); - o(0x85); - o(0xc0 + v * 9); - g(0x0f); - t = psym(0x85 ^ inv, t); - } - } - vtop--; - return t; -} - -/* generate an integer binary operation */ -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) { - /* XXX: generate inc and dec for smaller code ? */ - 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); - 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 guaranted to have the same floating point type */ -/* XXX: need to use ST1 too */ -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) */ - o(0xe9da); /* fucompp */ - 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.ul; - 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.ul = 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. */ -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 */ -/* XXX: handle long long case */ -void gen_cvt_ftoi(int t) -{ - int r, r2, size; - Sym *sym; - CType ushort_type; - - ushort_type.t = VT_SHORT | VT_UNSIGNED; - - gv(RC_FLOAT); - if (t != VT_INT) - size = 8; - else - size = 4; - - o(0x2dd9); /* ldcw xxx */ - sym = external_global_sym(TOK___tcc_int_fpu_control, - &ushort_type, VT_LVAL); - greloc(cur_text_section, sym, - ind, R_386_32); - gen_le32(0); - - oad(0xec81, size); /* sub $xxx, %esp */ - if (size == 4) - o(0x1cdb); /* fistpl */ - else - o(0x3cdf); /* fistpll */ - o(0x24); - o(0x2dd9); /* ldcw xxx */ - sym = external_global_sym(TOK___tcc_fpu_control, - &ushort_type, VT_LVAL); - greloc(cur_text_section, sym, - ind, R_386_32); - gen_le32(0); - - r = get_reg(RC_INT); - o(0x58 + r); /* pop r */ - if (size == 8) { - if (t == VT_LLONG) { - vtop->r = r; /* mark reg as used */ - r2 = get_reg(RC_INT); - o(0x58 + r2); /* pop r2 */ - vtop->r2 = r2; - } else { - o(0x04c483); /* add $4, %esp */ - } - } - vtop->r = r; -} - -/* convert from one floating point type to another */ -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 */ -void ggoto(void) -{ - gcall_or_jmp(1); - vtop--; -} - -/* bound check support functions */ -#ifdef CONFIG_TCC_BCHECK - -/* generate a bounded pointer addition */ -void gen_bounded_ptr_add(void) -{ - Sym *sym; - - /* 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 */ - sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0); - greloc(cur_text_section, sym, - ind + 1, R_386_PC32); - oad(0xe8, -4); - /* returned pointer is in eax */ - vtop++; - vtop->r = TREG_EAX | VT_BOUNDED; - /* address of bounding function call point */ - vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); -} - -/* patch pointer addition in vtop so that pointer dereferencing is - also tested */ -void gen_bounded_ptr_deref(void) -{ - int 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: - error("unhandled size when derefencing bounded pointer"); - func = 0; - break; - } - - /* patch relocation */ - /* XXX: find a better solution ? */ - rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul); - 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 - -/* end of X86 code generator */ -/*************************************************************/ - diff --git a/05/tcc-0.9.25/il-gen.c b/05/tcc-0.9.25/il-gen.c deleted file mode 100644 index 29f0526..0000000 --- a/05/tcc-0.9.25/il-gen.c +++ /dev/null @@ -1,667 +0,0 @@ -/* - * 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 - */ - -/* 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, -}; - -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: - 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) { - 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; - 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); - } - } else { - if (is_float(vtop->t)) { - vpushi(0); - gen_op(TOK_NE); - } - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) { - /* constant jmp optimization */ - if ((vtop->c.i != 0) != inv) - t = gjmp(t); - } else { - v = gv(RC_INT); - t = out_opj(IL_OP_BRTRUE - inv, t); - } - } - 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 guaranted 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/05/tcc-0.9.25/il-opcodes.h b/05/tcc-0.9.25/il-opcodes.h deleted file mode 100644 index d53ffb2..0000000 --- a/05/tcc-0.9.25/il-opcodes.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * 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/05/tcc-0.9.25/include/float.h b/05/tcc-0.9.25/include/float.h deleted file mode 100644 index 5f1c6f7..0000000 --- a/05/tcc-0.9.25/include/float.h +++ /dev/null @@ -1,57 +0,0 @@ -#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 */ -#ifdef __i386__ - -#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/05/tcc-0.9.25/include/stdarg.h b/05/tcc-0.9.25/include/stdarg.h deleted file mode 100644 index 86e556c..0000000 --- a/05/tcc-0.9.25/include/stdarg.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _STDARG_H -#define _STDARG_H - -#ifdef __x86_64__ -#include - -/* GCC compatible definition of va_list. */ -struct __va_list_struct { - unsigned int gp_offset; - unsigned int fp_offset; - union { - unsigned int overflow_offset; - char *overflow_arg_area; - }; - char *reg_save_area; -}; - -typedef struct __va_list_struct *va_list; - -/* we use __builtin_(malloc|free) to avoid #define malloc tcc_malloc */ -/* XXX: this lacks the support of aggregated types. */ -#define va_start(ap, last) \ - (ap = (va_list)__builtin_malloc(sizeof(struct __va_list_struct)), \ - *ap = *(struct __va_list_struct*)( \ - (char*)__builtin_frame_address(0) - 16), \ - ap->overflow_arg_area = ((char *)__builtin_frame_address(0) + \ - ap->overflow_offset), \ - ap->reg_save_area = (char *)__builtin_frame_address(0) - 176 - 16 \ - ) -#define va_arg(ap, type) \ - (*(type*)(__builtin_types_compatible_p(type, long double) \ - ? (ap->overflow_arg_area += 16, \ - ap->overflow_arg_area - 16) \ - : __builtin_types_compatible_p(type, double) \ - ? (ap->fp_offset < 128 + 48 \ - ? (ap->fp_offset += 16, \ - ap->reg_save_area + ap->fp_offset - 16) \ - : (ap->overflow_arg_area += 8, \ - ap->overflow_arg_area - 8)) \ - : (ap->gp_offset < 48 \ - ? (ap->gp_offset += 8, \ - ap->reg_save_area + ap->gp_offset - 8) \ - : (ap->overflow_arg_area += 8, \ - ap->overflow_arg_area - 8)) \ - )) -#define va_copy(dest, src) \ - ((dest) = (va_list)malloc(sizeof(struct __va_list_struct)), \ - *(dest) = *(src)) -#define va_end(ap) __builtin_free(ap) - -#else - -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/05/tcc-0.9.25/include/stdbool.h b/05/tcc-0.9.25/include/stdbool.h deleted file mode 100644 index 6ed13a6..0000000 --- a/05/tcc-0.9.25/include/stdbool.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _STDBOOL_H -#define _STDBOOL_H - -/* ISOC99 boolean */ - -#define bool _Bool -#define true 1 -#define false 0 - -#endif /* _STDBOOL_H */ diff --git a/05/tcc-0.9.25/include/stddef.h b/05/tcc-0.9.25/include/stddef.h deleted file mode 100644 index aef5b39..0000000 --- a/05/tcc-0.9.25/include/stddef.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _STDDEF_H -#define _STDDEF_H - -#define NULL ((void *)0) -typedef __SIZE_TYPE__ size_t; -typedef __WCHAR_TYPE__ wchar_t; -typedef __PTRDIFF_TYPE__ ptrdiff_t; -#define offsetof(type, field) ((size_t) &((type *)0)->field) - -#ifndef __int8_t_defined -#define __int8_t_defined -typedef char int8_t; -typedef short int int16_t; -typedef int int32_t; -typedef long long int int64_t; -#endif - -void *alloca(size_t size); - -#endif diff --git a/05/tcc-0.9.25/include/tcclib.h b/05/tcc-0.9.25/include/tcclib.h deleted file mode 100644 index 42f8f3f..0000000 --- a/05/tcc-0.9.25/include/tcclib.h +++ /dev/null @@ -1,78 +0,0 @@ -/* 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 -#include - -/* 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 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); - -/* 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/05/tcc-0.9.25/include/varargs.h b/05/tcc-0.9.25/include/varargs.h deleted file mode 100644 index daee29e..0000000 --- a/05/tcc-0.9.25/include/varargs.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _VARARGS_H -#define _VARARGS_H - -#include - -#define va_dcl -#define va_alist __va_alist -#undef va_start -#define va_start(ap) ap = __builtin_varargs_start - -#endif diff --git a/05/tcc-0.9.25/lib/alloca86-bt.S b/05/tcc-0.9.25/lib/alloca86-bt.S deleted file mode 100644 index 994da20..0000000 --- a/05/tcc-0.9.25/lib/alloca86-bt.S +++ /dev/null @@ -1,45 +0,0 @@ -/* ---------------------------------------------- */ -/* alloca86b.S */ - -#include "../config.h" - -.globl __bound_alloca - -__bound_alloca: - pop %edx - pop %eax - mov %eax, %ecx - add $3,%eax - and $-4,%eax - jz p6 - -#ifdef TCC_TARGET_PE -p4: - cmp $4096,%eax - jle p5 - sub $4096,%esp - sub $4096,%eax - test %eax,(%esp) - 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 - -/* ---------------------------------------------- */ diff --git a/05/tcc-0.9.25/lib/alloca86.S b/05/tcc-0.9.25/lib/alloca86.S deleted file mode 100644 index fb208a0..0000000 --- a/05/tcc-0.9.25/lib/alloca86.S +++ /dev/null @@ -1,33 +0,0 @@ -/* ---------------------------------------------- */ -/* alloca86.S */ - -#include "../config.h" - -.globl alloca - -alloca: - pop %edx - pop %eax - add $3,%eax - and $-4,%eax - jz p3 - -#ifdef TCC_TARGET_PE -p1: - cmp $4096,%eax - jle p2 - sub $4096,%esp - sub $4096,%eax - test %eax,(%esp) - jmp p1 -p2: -#endif - - sub %eax,%esp - mov %esp,%eax -p3: - push %edx - push %edx - ret - -/* ---------------------------------------------- */ diff --git a/05/tcc-0.9.25/lib/bcheck.c b/05/tcc-0.9.25/lib/bcheck.c deleted file mode 100644 index 0ec2a4b..0000000 --- a/05/tcc-0.9.25/lib/bcheck.c +++ /dev/null @@ -1,868 +0,0 @@ -/* - * 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 -#include -#include -#include -#if !defined(__FreeBSD__) && !defined(__DragonFly__) && !defined(__OpenBSD__) -#include -#endif - -//#define BOUND_DEBUG - -/* 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(__DragonFly__) || defined(__dietlibc__) \ - || defined(__UCLIBC__) || defined(__OpenBSD__) -#warning Bound checking not fully supported 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 (32 - BOUND_T1_BITS - BOUND_T2_BITS) - -#define BOUND_T1_SIZE (1 << BOUND_T1_BITS) -#define BOUND_T2_SIZE (1 << BOUND_T2_BITS) -#define BOUND_T3_SIZE (1 << BOUND_T3_BITS) -#define BOUND_E_BITS 4 - -#define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS) -#define BOUND_T23_SIZE (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 0xffffffff -/* size of an invalid region */ -#define INVALID_SIZE 0 - -typedef struct BoundEntry { - unsigned long start; - unsigned long size; - struct BoundEntry *next; - unsigned long is_invalid; /* true if pointers outside region are invalid */ -} BoundEntry; - -/* external interface */ -void __bound_init(void); -void __bound_new_region(void *p, unsigned long size); -int __bound_delete_region(void *p); - -#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 - -/* linker definitions */ -extern char _end; - -/* 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(unsigned long 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) -{ - unsigned long addr, tmp; - BoundEntry *e; - - e = e1; - while (e != NULL) { - addr = (unsigned long)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; - *(int *)0 = 0; /* force a runtime error */ -} - -static void bound_alloc_error(void) -{ - bound_error("not enough memory for bound checking code"); -} - -/* currently, tcc cannot compile that because we use GNUC extensions */ -#if !defined(__TINYC__) - -/* 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, int offset) -{ - unsigned long addr = (unsigned long)p; - BoundEntry *e; -#if defined(BOUND_DEBUG) - printf("add: 0x%x %d\n", (int)p, offset); -#endif - - 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 = (unsigned long)p - e->start; - } - addr += offset; - if (addr > e->size) - 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, int offset) \ -{ \ - unsigned long addr = (unsigned long)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); \ - addr = (unsigned long)p - e->start; \ - } \ - addr += offset + dsize; \ - if (addr > e->size) \ - return INVALID_POINTER; /* return an invalid pointer */ \ - return p + offset; \ -} - -#ifdef __i386__ -/* return the frame pointer of the caller */ -#define GET_CALLER_FP(fp)\ -{\ - unsigned long *fp1;\ - __asm__ __volatile__ ("movl %%ebp,%0" :"=g" (fp1));\ - fp = fp1[0];\ -} -#else -#error put code to extract the calling frame pointer -#endif - -/* called when entering a function to add all the local regions */ -void FASTCALL __bound_local_new(void *p1) -{ - unsigned long addr, size, fp, *p = p1; - 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); - } -} - -/* called when leaving a function to delete all the local regions */ -void FASTCALL __bound_local_delete(void *p1) -{ - unsigned long 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); - } -} - -#else - -void __bound_local_new(void *p) -{ -} -void __bound_local_delete(void *p) -{ -} - -void *__bound_ptr_add(void *p, int offset) -{ - return p + offset; -} - -#define BOUND_PTR_INDIR(dsize) \ -void *__bound_ptr_indir ## dsize (void *p, int offset) \ -{ \ - return p + offset; \ -} -#endif - -BOUND_PTR_INDIR(1) -BOUND_PTR_INDIR(2) -BOUND_PTR_INDIR(4) -BOUND_PTR_INDIR(8) -BOUND_PTR_INDIR(12) -BOUND_PTR_INDIR(16) - -static BoundEntry *__bound_new_page(void) -{ - BoundEntry *page; - int i; - - page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE); - if (!page) - bound_alloc_error(); - for(i=0;i> BOUND_T3_BITS; - if (end != 0) - t2_end = end >> BOUND_T3_BITS; - else - t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS); - -#if 0 - printf("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) -{ - int i; - BoundEntry *page; - unsigned long start, size; - int *p; - - /* 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;istart == 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, unsigned long size) -{ - unsigned long start, end; - BoundEntry *page, *e, *e2; - int t1_start, t1_end, i, t2_start, t2_end; - - start = (unsigned long)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); -#ifdef BOUND_DEBUG - printf("new %lx %lx %x %x %x %x\n", - start, end, t1_start, t1_end, t2_start, t2_end); -#endif - - 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(;estart = start; - e->size = size; - } - add_region(e, start, size); - } - } else { - /* mark until end of page */ - e2 = page + BOUND_T2_SIZE; - e++; - for(;estart = start; - e->size = size; - } - /* mark intermediate pages, if any */ - for(i=t1_start+1;istart = start; - e->size = size; - } - } - /* last page */ - page = get_page(t1_end); - e2 = (BoundEntry *)((char *)page + t2_end); - for(e=page;estart = start; - e->size = size; - } - add_region(e, start, size); - } -} - -/* delete a region */ -static inline void delete_region(BoundEntry *e, - void *p, unsigned long empty_size) -{ - unsigned long addr; - BoundEntry *e1; - - addr = (unsigned long)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 = (unsigned long)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) -{ - unsigned long start, end, addr, size, empty_size; - BoundEntry *page, *e, *e2; - int t1_start, t1_end, t2_start, t2_end, i; - - start = (unsigned long)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 || (unsigned long)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(;estart = 0; - e->size = empty_size; - } - delete_region(e, p, empty_size); - } - } else { - /* mark until end of page */ - e2 = page + BOUND_T2_SIZE; - e++; - for(;estart = 0; - e->size = empty_size; - } - /* mark intermediate pages, if any */ - /* XXX: should free them */ - for(i=t1_start+1;istart = 0; - e->size = empty_size; - } - } - /* last page */ - page = get_page(t2_end); - e2 = (BoundEntry *)((char *)page + t2_end); - for(e=page;estart = 0; - e->size = empty_size; - } - delete_region(e, p, empty_size); - } - return 0; -} - -/* return the size of the region starting at p, or EMPTY_SIZE if non - existant region. */ -static unsigned long get_region_size(void *p) -{ - unsigned long addr = (unsigned long)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 != (unsigned long)p) - return EMPTY_SIZE; - return e->size; -} - -/* patched memory functions */ - -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; -#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; -#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; - __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; - __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; - int 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; - int i, j; - - printf("region dump:\n"); - for(i=0;isize != EMPTY_SIZE && e->start != 0) { - printf("%08x:", - (i << (BOUND_T2_BITS + BOUND_T3_BITS)) + - (j << BOUND_T3_BITS)); - do { - printf(" %08lx:%08lx", e->start, e->start + e->size); - e = e->next; - } while (e != NULL); - printf("\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); - if (p == INVALID_POINTER) - bound_error("invalid pointer"); -} - -void *__bound_memcpy(void *dst, const void *src, size_t 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()"); - return memcpy(dst, src, size); -} - -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; - int 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) -{ - int len; - len = __bound_strlen(src); - return __bound_memcpy(dst, src, len + 1); -} - diff --git a/05/tcc-0.9.25/lib/libtcc1.c b/05/tcc-0.9.25/lib/libtcc1.c deleted file mode 100644 index b079477..0000000 --- a/05/tcc-0.9.25/lib/libtcc1.c +++ /dev/null @@ -1,607 +0,0 @@ -/* 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; - long l; -}; - -/* XXX: we don't support several builtin supports for now */ -#ifndef __x86_64__ - -/* 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 !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 -} - -#if defined(__i386__) -/* FPU control word for rounding to nearest mode */ -unsigned short __tcc_fpu_control = 0x137f; -/* FPU control word for round to zero mode for int conversion */ -unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00; -#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; -} - -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; -} - -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; -} - diff --git a/05/tcc-0.9.25/libtcc.c b/05/tcc-0.9.25/libtcc.c deleted file mode 100644 index 3311357..0000000 --- a/05/tcc-0.9.25/libtcc.c +++ /dev/null @@ -1,2276 +0,0 @@ -/* - * 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 */ - -/* display benchmark infos */ -int total_lines; -int total_bytes; - -/* parser */ -static struct BufferedFile *file; -static int ch, tok; -static CValue tokc; -static CString tokcstr; /* current parsed string, if any */ -/* additional informations about token */ -static int tok_flags; -#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 */ - -static int *macro_ptr, *macro_ptr_allocated; -static int *unget_saved_macro_ptr; -static int unget_saved_buffer[TOK_MAX_SIZE + 1]; -static int unget_buffer_enabled; -static int parse_flags; -#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_COMMENTS 0x0008 /* '#' can be used for line comment */ -#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */ - -static Section *text_section, *data_section, *bss_section; /* predefined sections */ -static Section *cur_text_section; /* current section where function code is - generated */ -#ifdef CONFIG_TCC_ASM -static Section *last_text_section; /* to handle .previous asm directive */ -#endif -/* bound check related sections */ -static Section *bounds_section; /* contains global data bound description */ -static Section *lbounds_section; /* contains local data bound description */ -/* symbol sections */ -static Section *symtab_section, *strtab_section; - -/* debug sections */ -static Section *stab_section, *stabstr_section; - -/* loc : local variable index - ind : output code index - rsym: return symbol - anon_sym: anonymous symbol index -*/ -static int rsym, anon_sym, ind, loc; -/* expression generation modifiers */ -static int const_wanted; /* true if constant wanted */ -static int nocode_wanted; /* true if no code generation wanted for an expression */ -static int global_expr; /* true if compound literals must be allocated - globally (used during initializers parsing */ -static CType func_vt; /* current function return type (used by return - instruction) */ -static int func_vc; -static int last_line_num, last_ind, func_ind; /* debug last line number and pc */ -static int tok_ident; -static TokenSym **table_ident; -static TokenSym *hash_ident[TOK_HASH_SIZE]; -static char token_buf[STRING_MAX_SIZE + 1]; -static char *funcname; -static Sym *global_stack, *local_stack; -static Sym *define_stack; -static Sym *global_label_stack, *local_label_stack; -/* symbol allocator */ -#define SYM_POOL_NB (8192 / sizeof(Sym)) -static Sym *sym_free_first; -static void **sym_pools; -static int nb_sym_pools; - -static SValue vstack[VSTACK_SIZE], *vtop; -/* some predefined types */ -static CType char_pointer_type, func_old_type, int_type; - -/* use GNU C extensions */ -static int gnu_ext = 1; - -/* use Tiny C extensions */ -static int tcc_ext = 1; - -/* max number of callers shown if error */ -#ifdef CONFIG_TCC_BACKTRACE -int num_callers = 6; -const char **rt_bound_error_msg; -#endif - -/* XXX: get rid of this ASAP */ -static struct TCCState *tcc_state; - -/********************************************************/ -/* function prototypes */ - -/* tccpp.c */ -static void next(void); -char *get_tok_str(int v, CValue *cv); - -/* tccgen.c */ -static void parse_expr_type(CType *type); -static void expr_type(CType *type); -static void unary_type(CType *type); -static void block(int *bsym, int *csym, int *case_sym, int *def_sym, - int case_reg, int is_expr); -static int expr_const(void); -static void expr_eq(void); -static void gexpr(void); -static void gen_inline_functions(void); -static void decl(int l); -static void decl_initializer(CType *type, Section *sec, unsigned long c, - int first, int size_only); -static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, - int has_init, int v, int scope); -int gv(int rc); -void gv2(int rc1, int rc2); -void move_reg(int r, int s); -void save_regs(int n); -void save_reg(int r); -void vpop(void); -void vswap(void); -void vdup(void); -int get_reg(int rc); -int get_reg_ex(int rc,int rc2); - -void gen_op(int op); -void force_charshort_cast(int t); -static void gen_cast(CType *type); -void vstore(void); -static Sym *sym_find(int v); -static Sym *sym_push(int v, CType *type, int r, int c); - -/* type handling */ -static int type_size(CType *type, int *a); -static inline CType *pointed_type(CType *type); -static int pointed_size(CType *type); -static int lvalue_type(int t); -static int parse_btype(CType *type, AttributeDef *ad); -static void type_decl(CType *type, AttributeDef *ad, int *v, int td); -static int compare_types(CType *type1, CType *type2, int unqualified); -static int is_compatible_types(CType *type1, CType *type2); -static int is_compatible_parameter_types(CType *type1, CType *type2); - -int ieee_finite(double d); -void vpushi(int v); -void vpushll(long long v); -void vrott(int n); -void vnrott(int n); -void lexpand_nr(void); -static void vpush_global_sym(CType *type, int v); -void vset(CType *type, int r, int v); -void type_to_str(char *buf, int buf_size, - CType *type, const char *varstr); -static Sym *get_sym_ref(CType *type, Section *sec, - unsigned long offset, unsigned long size); -static Sym *external_global_sym(int v, CType *type, int r); - -/* section generation */ -static void section_realloc(Section *sec, unsigned long new_size); -static void *section_ptr_add(Section *sec, unsigned long size); -static void put_extern_sym(Sym *sym, Section *section, - unsigned long value, unsigned long size); -static void greloc(Section *s, Sym *sym, unsigned long addr, int type); -static int put_elf_str(Section *s, const char *sym); -static int put_elf_sym(Section *s, - unsigned long value, unsigned long size, - int info, int other, int shndx, const char *name); -static int add_elf_sym(Section *s, unsigned long value, unsigned long size, - int info, int other, int sh_num, const char *name); -static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, - int type, int symbol); -static void put_stabs(const char *str, int type, int other, int desc, - unsigned long value); -static void put_stabs_r(const char *str, int type, int other, int desc, - unsigned long value, Section *sec, int sym_index); -static void put_stabn(int type, int other, int desc, int value); -static void put_stabd(int type, int other, int desc); -static int tcc_add_dll(TCCState *s, const char *filename, int flags); - -#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */ -#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */ -#define AFF_PREPROCESS 0x0004 /* preprocess file */ -static int tcc_add_file_internal(TCCState *s, const char *filename, int flags); - -/* tcccoff.c */ -int tcc_output_coff(TCCState *s1, FILE *f); - -/* tccpe.c */ -void *resolve_sym(TCCState *s1, const char *sym, int type); -int pe_load_def_file(struct TCCState *s1, int fd); -int pe_test_res_file(void *v, int size); -int pe_load_res_file(struct TCCState *s1, int fd); -void pe_add_runtime(struct TCCState *s1); -void pe_guess_outfile(char *objfilename, int output_type); -int pe_output_file(struct TCCState *s1, const char *filename); - -/* tccasm.c */ -#ifdef CONFIG_TCC_ASM -static void asm_expr(TCCState *s1, ExprValue *pe); -static int asm_int_expr(TCCState *s1); -static int find_constraint(ASMOperand *operands, int nb_operands, - const char *name, const char **pp); - -static int tcc_assemble(TCCState *s1, int do_preprocess); -#endif - -static void asm_instr(void); -static void asm_global_instr(void); - -/********************************************************/ -/* global variables */ - -#ifdef TCC_TARGET_I386 -#include "i386-gen.c" -#endif - -#ifdef TCC_TARGET_ARM -#include "arm-gen.c" -#endif - -#ifdef TCC_TARGET_C67 -#include "c67-gen.c" -#endif - -#ifdef TCC_TARGET_X86_64 -#include "x86_64-gen.c" -#endif - -#ifdef CONFIG_TCC_STATIC - -#define RTLD_LAZY 0x001 -#define RTLD_NOW 0x002 -#define RTLD_GLOBAL 0x100 -#define RTLD_DEFAULT NULL - -/* dummy function for profiling */ -void *dlopen(const char *filename, int flag) -{ - return NULL; -} - -void dlclose(void *p) -{ -} - -const char *dlerror(void) -{ - return "error"; -} - -typedef struct TCCSyms { - char *str; - void *ptr; -} TCCSyms; - -#define TCCSYM(a) { #a, &a, }, - -/* add the symbol you want here if no dynamic linking is done */ -static TCCSyms tcc_syms[] = { - {"printf", 0}, - {"fprintf", 0}, - {"fopen", 0}, - {"fclose", 0}, - { NULL, NULL } -}; - -void _init_tcc_syms(void) { - tcc_syms[0].ptr = printf; - tcc_syms[1].ptr = fprintf; - tcc_syms[2].ptr = fopen; - tcc_syms[3].ptr = fclose; -} - -void *resolve_sym(TCCState *s1, const char *symbol, int type) -{ - TCCSyms *p; - p = tcc_syms; - while (p->str != NULL) { - if (!strcmp(p->str, symbol)) - return p->ptr; - p++; - } - return NULL; -} - -#elif !defined(_WIN32) - -#include - -void *resolve_sym(TCCState *s1, const char *sym, int type) -{ - return dlsym(RTLD_DEFAULT, sym); -} - -#endif - -/********************************************************/ - -/* we use our own 'finite' function to avoid potential problems with - non standard math libs */ -/* XXX: endianness dependent */ -int ieee_finite(double d) -{ - int *p = (int *)&d; - return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; -} - -/* copy a string and truncate it. */ -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. */ -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; -} - -/* extract the basename of a file */ -char *tcc_basename(const char *name) -{ - char *p = strchr(name, 0); - while (p > name && !IS_PATHSEP(p[-1])) - --p; - return p; -} - -char *tcc_fileextension (const char *name) -{ - char *b = tcc_basename(name); - char *e = strrchr(b, '.'); - return e ? e : strchr(b, 0); -} - -#ifdef _WIN32 -char *normalize_slashes(char *path) -{ - char *p; - for (p = path; *p; ++p) - if (*p == '\\') - *p = '/'; - return path; -} - -void tcc_set_lib_path_w32(TCCState *s) -{ - /* on win32, we suppose the lib and includes are at the location - of 'tcc.exe' */ - char path[1024], *p; - GetModuleFileNameA(NULL, path, sizeof path); - p = tcc_basename(normalize_slashes(strlwr(path))); - if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5)) - p -= 5; - else if (p > path) - p--; - *p = 0; - tcc_set_lib_path(s, path); -} -#endif - -void set_pages_executable(void *ptr, unsigned long length) -{ -#ifdef _WIN32 - unsigned long old_protect; - VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect); -#else - unsigned long start, end; - start = (unsigned long)ptr & ~(PAGESIZE - 1); - end = (unsigned long)ptr + length; - end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1); - mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC); -#endif -} - -/* memory management */ -#ifdef MEM_DEBUG -int mem_cur_size; -int mem_max_size; -unsigned malloc_usable_size(void*); -#endif - -void tcc_free(void *ptr) -{ -#ifdef MEM_DEBUG - mem_cur_size -= malloc_usable_size(ptr); -#endif - free(ptr); -} - -void *tcc_malloc(unsigned long size) -{ - void *ptr; - ptr = malloc(size); - if (!ptr && size) - error("memory full"); -#ifdef MEM_DEBUG - mem_cur_size += malloc_usable_size(ptr); - if (mem_cur_size > mem_max_size) - mem_max_size = mem_cur_size; -#endif - return ptr; -} - -void *tcc_mallocz(unsigned long size) -{ - void *ptr; - ptr = tcc_malloc(size); - memset(ptr, 0, size); - return ptr; -} - -void *tcc_realloc(void *ptr, unsigned long size) -{ - void *ptr1; -#ifdef MEM_DEBUG - mem_cur_size -= malloc_usable_size(ptr); -#endif - ptr1 = realloc(ptr, size); -#ifdef MEM_DEBUG - /* NOTE: count not correct if alloc error, but not critical */ - mem_cur_size += malloc_usable_size(ptr1); - if (mem_cur_size > mem_max_size) - mem_max_size = mem_cur_size; -#endif - return ptr1; -} - -char *tcc_strdup(const char *str) -{ - char *ptr; - ptr = tcc_malloc(strlen(str) + 1); - strcpy(ptr, str); - return ptr; -} - -#define free(p) use_tcc_free(p) -#define malloc(s) use_tcc_malloc(s) -#define realloc(p, s) use_tcc_realloc(p, s) - -void dynarray_add(void ***ptab, int *nb_ptr, void *data) -{ - int nb, nb_alloc; - void **pp; - - nb = *nb_ptr; - pp = *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 *)); - if (!pp) - error("memory full"); - *ptab = pp; - } - pp[nb++] = data; - *nb_ptr = nb; -} - -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; -} - -/* 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; - sym = sym_free_first; - if (!sym) - sym = __sym_malloc(); - sym_free_first = sym->next; - return sym; -} - -static inline void sym_free(Sym *sym) -{ - sym->next = sym_free_first; - sym_free_first = sym; -} - -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 = 32; /* default conservative alignment */ - break; - } - - if (sh_flags & SHF_PRIVATE) { - dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec); - } else { - sec->sh_num = s1->nb_sections; - dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec); - } - - return sec; -} - -static void free_section(Section *s) -{ - tcc_free(s->data); -} - -/* realloc section and set its content to zero */ -static 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); - if (!data) - error("memory full"); - memset(data + sec->data_allocated, 0, size - sec->data_allocated); - sec->data = data; - sec->data_allocated = size; -} - -/* reserve at least 'size' bytes in section 'sec' from - sec->data_offset. */ -static void *section_ptr_add(Section *sec, unsigned long size) -{ - unsigned long offset, offset1; - - offset = sec->data_offset; - offset1 = offset + size; - if (offset1 > sec->data_allocated) - section_realloc(sec, offset1); - sec->data_offset = offset1; - return sec->data + offset; -} - -/* return a reference to a section, and create it if it does not - exists */ -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); -} - -/* update sym->c so that it points to an external symbol in section - 'section' with value 'value' */ -static void put_extern_sym2(Sym *sym, Section *section, - unsigned long value, unsigned long size, - int can_add_underscore) -{ - int sym_type, sym_bind, sh_num, info, other, attr; - ElfW(Sym) *esym; - const char *name; - char buf1[256]; - - if (section == NULL) - sh_num = SHN_UNDEF; - else if (section == SECTION_ABS) - sh_num = SHN_ABS; - else - sh_num = section->sh_num; - - other = attr = 0; - - if ((sym->type.t & VT_BTYPE) == VT_FUNC) { - sym_type = STT_FUNC; -#ifdef TCC_TARGET_PE - if (sym->type.ref) - attr = sym->type.ref->r; - if (FUNC_EXPORT(attr)) - other |= 1; - if (FUNC_CALL(attr) == FUNC_STDCALL) - other |= 2; -#endif - } else { - sym_type = STT_OBJECT; - } - - if (sym->type.t & VT_STATIC) - sym_bind = STB_LOCAL; - else - sym_bind = STB_GLOBAL; - - if (!sym->c) { - name = get_tok_str(sym->v, NULL); -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) { - char buf[32]; - - /* XXX: avoid doing that for statics ? */ - /* if bound checking is activated, we change some function - names by adding the "__bound" prefix */ - switch(sym->v) { -#if 0 - /* 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 - -#ifdef TCC_TARGET_PE - if ((other & 2) && can_add_underscore) { - sprintf(buf1, "_%s@%d", name, FUNC_ARGS(attr)); - name = buf1; - } else -#endif - if (tcc_state->leading_underscore && can_add_underscore) { - buf1[0] = '_'; - pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); - name = buf1; - } - info = ELF64_ST_INFO(sym_bind, sym_type); - sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name); - } else { - esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; - esym->st_value = value; - esym->st_size = size; - esym->st_shndx = sh_num; - esym->st_other |= other; - } -} - -static void put_extern_sym(Sym *sym, Section *section, - unsigned long value, unsigned long size) -{ - put_extern_sym2(sym, section, value, size, 1); -} - -/* add a new relocation entry to symbol 'sym' in section 's' */ -static void greloc(Section *s, Sym *sym, unsigned long offset, int type) -{ - if (!sym->c) - put_extern_sym(sym, NULL, 0, 0); - /* now we can add ELF relocation info */ - put_elf_reloc(symtab_section, s, offset, type, sym->c); -} - -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) -{ - if (c >= 'a' && c <= 'z') - return c - 'a' + 'A'; - else - return c; -} - -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); -} - -void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) -{ - char buf[2048]; - BufferedFile **f; - - buf[0] = '\0'; - if (file) { - for(f = s1->include_stack; f < s1->include_stack_ptr; f++) - strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n", - (*f)->filename, (*f)->line_num); - if (file->line_num > 0) { - strcat_printf(buf, sizeof(buf), - "%s:%d: ", file->filename, file->line_num); - } else { - strcat_printf(buf, sizeof(buf), - "%s: ", file->filename); - } - } else { - strcat_printf(buf, sizeof(buf), - "tcc: "); - } - if (is_warning) - strcat_printf(buf, sizeof(buf), "warning: "); - strcat_vprintf(buf, sizeof(buf), fmt, ap); - - if (!s1->error_func) { - /* default case: stderr */ - fprintf(stderr, "%s\n", buf); - } else { - s1->error_func(s1->error_opaque, buf); - } - if (!is_warning || s1->warn_error) - s1->nb_errors++; -} - -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 */ -void error_noabort(const char *fmt, ...) -{ - TCCState *s1 = tcc_state; - va_list ap; - - va_start(ap, fmt); - error1(s1, 0, fmt, ap); - va_end(ap); -} - -void 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); - } -} - -void expect(const char *msg) -{ - error("%s expected", msg); -} - -void 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); -} - -void skip(int c) -{ - if (tok != c) - error("'%c' expected", c); - next(); -} - -static void test_lvalue(void) -{ - if (!(vtop->r & VT_LVAL)) - expect("lvalue"); -} - -/* CString handling */ - -static void cstr_realloc(CString *cstr, int new_size) -{ - int size; - void *data; - - size = cstr->size_allocated; - if (size == 0) - size = 8; /* no need to allocate a too small first string */ - while (size < new_size) - size = size * 2; - data = tcc_realloc(cstr->data_allocated, size); - if (!data) - error("memory full"); - cstr->data_allocated = data; - cstr->size_allocated = size; - cstr->data = data; -} - -/* add a byte */ -static inline 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; -} - -static void cstr_cat(CString *cstr, const char *str) -{ - int c; - for(;;) { - c = *str; - if (c == '\0') - break; - cstr_ccat(cstr, c); - str++; - } -} - -/* add a wide char */ -static 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; -} - -static void cstr_new(CString *cstr) -{ - memset(cstr, 0, sizeof(CString)); -} - -/* free string and reset it to NULL */ -static void cstr_free(CString *cstr) -{ - tcc_free(cstr->data_allocated); - cstr_new(cstr); -} - -#define cstr_reset(cstr) cstr_free(cstr) - -/* 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)); - } - } -} - -/* push, without hashing */ -static Sym *sym_push2(Sym **ps, int v, int t, long c) -{ - Sym *s; - s = sym_malloc(); - s->v = v; - s->type.t = t; - s->c = c; - s->next = NULL; - /* 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 */ -static Sym *sym_find2(Sym *s, int v) -{ - while (s) { - if (s->v == v) - return s; - s = s->prev; - } - return NULL; -} - -/* structure lookup */ -static inline 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 */ -static inline 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 */ -static 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; - } - return s; -} - -/* push a global identifier */ -static 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 = &(*ps)->prev_tok; - s->prev_tok = NULL; - *ps = s; - } - return s; -} - -/* pop symbols until top reaches 'b' */ -static void sym_pop(Sym **ptop, Sym *b) -{ - 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; - } - sym_free(s); - s = ss; - } - *ptop = b; -} - -/* I/O layer */ - -BufferedFile *tcc_open(TCCState *s1, const char *filename) -{ - int fd; - BufferedFile *bf; - - 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":"->", - (s1->include_stack_ptr - s1->include_stack), "", filename); - if (fd < 0) - return NULL; - bf = tcc_malloc(sizeof(BufferedFile)); - bf->fd = fd; - bf->buf_ptr = bf->buffer; - bf->buf_end = bf->buffer; - bf->buffer[0] = CH_EOB; /* put eob symbol */ - pstrcpy(bf->filename, sizeof(bf->filename), filename); -#ifdef _WIN32 - normalize_slashes(bf->filename); -#endif - bf->line_num = 1; - bf->ifndef_macro = 0; - bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; - // printf("opening '%s'\n", filename); - return bf; -} - -void tcc_close(BufferedFile *bf) -{ - total_lines += bf->line_num; - close(bf->fd); - tcc_free(bf); -} - -#include "tccpp.c" -#include "tccgen.c" - - -/* compile the C file opened in 'file'. Return non zero if errors. */ -static int tcc_compile(TCCState *s1) -{ - Sym *define_start; - char buf[512]; - volatile int section_sym; - -#ifdef INC_DEBUG - printf("%s: **** new file\n", file->filename); -#endif - preprocess_init(s1); - - cur_text_section = NULL; - funcname = ""; - anon_sym = SYM_FIRST_ANOM; - - /* file info: full path + filename */ - section_sym = 0; /* avoid warning */ - if (s1->do_debug) { - section_sym = put_elf_sym(symtab_section, 0, 0, - ELF64_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); - } - /* 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, - ELF64_ST_INFO(STB_LOCAL, STT_FILE), 0, - SHN_ABS, file->filename); - - /* define some often used types */ - int_type.t = VT_INT; - - char_pointer_type.t = VT_BYTE; - mk_pointer(&char_pointer_type); - - func_old_type.t = VT_FUNC; - func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD); - -#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) - 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); -#endif - -#if 0 - /* define 'void *alloca(unsigned int)' builtin function */ - { - Sym *s1; - - p = anon_sym++; - sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW); - s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0); - s1->next = NULL; - sym->next = s1; - sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0); - } -#endif - - define_start = define_stack; - nocode_wanted = 1; - - if (setjmp(s1->error_jmp_buf) == 0) { - s1->nb_errors = 0; - s1->error_set_jmp_enabled = 1; - - ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM; - next(); - decl(VT_CONST); - if (tok != TOK_EOF) - expect("declaration"); - - /* end of translation unit info */ - if (s1->do_debug) { - put_stabs_r(NULL, N_SO, 0, 0, - text_section->data_offset, text_section, section_sym); - } - } - s1->error_set_jmp_enabled = 0; - - /* reset define stack, but leave -Dsymbols (may be incorrect if - they are undefined) */ - free_defines(define_start); - - gen_inline_functions(); - - sym_pop(&global_stack, NULL); - sym_pop(&local_stack, NULL); - - return s1->nb_errors != 0 ? -1 : 0; -} - -int tcc_compile_string(TCCState *s, const char *str) -{ - BufferedFile bf1, *bf = &bf1; - int ret, len; - char *buf; - - /* init file structure */ - bf->fd = -1; - /* XXX: avoid copying */ - len = strlen(str); - buf = tcc_malloc(len + 1); - if (!buf) - return -1; - memcpy(buf, str, len); - buf[len] = CH_EOB; - bf->buf_ptr = buf; - bf->buf_end = buf + len; - pstrcpy(bf->filename, sizeof(bf->filename), ""); - bf->line_num = 1; - file = bf; - ret = tcc_compile(s); - file = NULL; - tcc_free(buf); - - /* currently, no need to close */ - return ret; -} - -/* define a preprocessor symbol. A value can also be provided with the '=' operator */ -void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) -{ - BufferedFile bf1, *bf = &bf1; - - pstrcpy(bf->buffer, IO_BUF_SIZE, sym); - pstrcat(bf->buffer, IO_BUF_SIZE, " "); - /* default value */ - if (!value) - value = "1"; - pstrcat(bf->buffer, IO_BUF_SIZE, value); - - /* init file structure */ - bf->fd = -1; - bf->buf_ptr = bf->buffer; - bf->buf_end = bf->buffer + strlen(bf->buffer); - *bf->buf_end = CH_EOB; - bf->filename[0] = '\0'; - bf->line_num = 1; - file = bf; - - s1->include_stack_ptr = s1->include_stack; - - /* parse with define parser */ - ch = file->buf_ptr[0]; - next_nomacro(); - parse_define(); - file = NULL; -} - -/* undefine a preprocessor symbol */ -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); -} - -#ifdef CONFIG_TCC_ASM - -#ifdef TCC_TARGET_I386 -#include "i386-asm.c" -#endif -#include "tccasm.c" - -#else -static void asm_instr(void) -{ - error("inline asm() not supported"); -} -static void asm_global_instr(void) -{ - error("inline asm() not supported"); -} -#endif - -#include "tccelf.c" - -#ifdef TCC_TARGET_COFF -#include "tcccoff.c" -#endif - -#ifdef TCC_TARGET_PE -#include "tccpe.c" -#endif - -#ifdef CONFIG_TCC_BACKTRACE -/* print the position in the source file of PC value 'pc' by reading - the stabs debug information */ -static void rt_printline(unsigned long wanted_pc) -{ - 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, i; - const char *str, *p; - - fprintf(stderr, "0x%08lx:", wanted_pc); - - 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); - while (sym < sym_end) { - 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 = 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; - } - 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 = 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 = stabstr_section->data + sym->n_strx; - /* do not add path */ - len = strlen(str); - if (len > 0 && str[len - 1] != '/') - goto add_incl; - } - break; - } - sym++; - } - - /* second pass: we try symtab symbols (no line number info) */ - incl_index = 0; - { - 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 = ELF64_ST_TYPE(sym->st_info); - if (type == STT_FUNC) { - if (wanted_pc >= sym->st_value && - wanted_pc < sym->st_value + sym->st_size) { - pstrcpy(last_func_name, sizeof(last_func_name), - strtab_section->data + sym->st_name); - goto found; - } - } - } - } - /* did not find any info: */ - fprintf(stderr, " ???\n"); - return; - found: - if (last_func_name[0] != '\0') { - fprintf(stderr, " %s()", last_func_name); - } - if (incl_index > 0) { - fprintf(stderr, " (%s:%d", - incl_files[incl_index - 1], last_line_num); - for(i = incl_index - 2; i >= 0; i--) - fprintf(stderr, ", included from %s", incl_files[i]); - fprintf(stderr, ")"); - } - fprintf(stderr, "\n"); -} - -#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 non zero if not found */ -static int rt_get_caller_pc(unsigned long *paddr, - ucontext_t *uc, int level) -{ - unsigned long fp; - int i; - - if (level == 0) { -#if defined(__FreeBSD__) - *paddr = uc->uc_mcontext.mc_eip; -#elif defined(__dietlibc__) - *paddr = uc->uc_mcontext.eip; -#else - *paddr = uc->uc_mcontext.gregs[REG_EIP]; -#endif - return 0; - } else { -#if defined(__FreeBSD__) - fp = uc->uc_mcontext.mc_ebp; -#elif defined(__dietlibc__) - fp = uc->uc_mcontext.ebp; -#else - fp = uc->uc_mcontext.gregs[REG_EBP]; -#endif - for(i=1;i= 0xc0000000) - return -1; - fp = ((unsigned long *)fp)[0]; - } - *paddr = ((unsigned long *)fp)[1]; - return 0; - } -} -#elif 1 -/* return the PC at frame level 'level'. Return non zero if not found */ -static int rt_get_caller_pc(unsigned long *paddr, - ucontext_t *uc, int level) -{ - unsigned long fp; - int i; - - if (level == 0) { - /* XXX: only support linux */ - *paddr = uc->uc_mcontext.gregs[REG_RIP]; - return 0; - } else { - fp = uc->uc_mcontext.gregs[REG_RBP]; - for(i=1;isi_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); -} - -#endif - -/* copy code into memory passed in by the caller and do all relocations - (needed before using tcc_get_symbol()). - returns -1 on error and required size if ptr is NULL */ -int tcc_relocate(TCCState *s1, void *ptr) -{ - Section *s; - unsigned long offset, length, mem; - int i; - - if (0 == s1->runtime_added) { - s1->runtime_added = 1; - s1->nb_errors = 0; -#ifdef TCC_TARGET_PE - pe_add_runtime(s1); - relocate_common_syms(); - tcc_add_linker_symbols(s1); -#else - tcc_add_runtime(s1); - relocate_common_syms(); - tcc_add_linker_symbols(s1); - build_got_entries(s1); -#endif - } - - offset = 0, mem = (unsigned long)ptr; - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (0 == (s->sh_flags & SHF_ALLOC)) - continue; - length = s->data_offset; - s->sh_addr = mem ? (mem + offset + 15) & ~15 : 0; - offset = (offset + length + 15) & ~15; - } - - /* relocate symbols */ - relocate_syms(s1, 1); - if (s1->nb_errors) - return -1; - -#ifdef TCC_TARGET_X86_64 - s1->runtime_plt_and_got_offset = 0; - s1->runtime_plt_and_got = (char *)(mem + offset); - /* double the size of the buffer for got and plt entries - XXX: calculate exact size for them? */ - offset *= 2; -#endif - - if (0 == mem) - return offset + 15; - - /* relocate each section */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (s->reloc) - relocate_section(s1, s); - } - - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (0 == (s->sh_flags & SHF_ALLOC)) - continue; - length = s->data_offset; - // printf("%-12s %08x %04x\n", s->name, s->sh_addr, length); - ptr = (void*)s->sh_addr; - 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(ptr, length); - } -#ifdef TCC_TARGET_X86_64 - set_pages_executable(s1->runtime_plt_and_got, - s1->runtime_plt_and_got_offset); -#endif - return 0; -} - -/* launch the compiled program with the given arguments */ -int tcc_run(TCCState *s1, int argc, char **argv) -{ - int (*prog_main)(int, char **); - void *ptr; - int ret; - - ret = tcc_relocate(s1, NULL); - if (ret < 0) - return -1; - ptr = tcc_malloc(ret); - tcc_relocate(s1, ptr); - - prog_main = tcc_get_symbol_err(s1, "main"); - - if (s1->do_debug) { -#ifdef CONFIG_TCC_BACKTRACE - 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); -#else - error("debug mode not available"); -#endif - } - -#ifdef CONFIG_TCC_BCHECK - if (s1->do_bounds_check) { - void (*bound_init)(void); - - /* 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 = (void *)tcc_get_symbol_err(s1, "__bound_init"); - bound_init(); - } -#endif - ret = (*prog_main)(argc, argv); - tcc_free(ptr); - return ret; -} - -void tcc_memstats(void) -{ -#ifdef MEM_DEBUG - printf("memory in use: %d\n", mem_cur_size); -#endif -} - -static void tcc_cleanup(void) -{ - int i, n; - - if (NULL == tcc_state) - return; - tcc_state = NULL; - - /* free -D defines */ - free_defines(NULL); - - /* free tokens */ - n = tok_ident - TOK_IDENT; - for(i = 0; i < n; i++) - tcc_free(table_ident[i]); - tcc_free(table_ident); - - /* free sym_pools */ - dynarray_reset(&sym_pools, &nb_sym_pools); - /* string buffer */ - cstr_free(&tokcstr); - /* reset symbol stack */ - sym_free_first = NULL; - /* cleanup from error/setjmp */ - macro_ptr = NULL; -} - -TCCState *tcc_new(void) -{ - TCCState *s; - - tcc_cleanup(); - - s = tcc_mallocz(sizeof(TCCState)); - if (!s) - return NULL; - tcc_state = s; - s->output_type = TCC_OUTPUT_MEMORY; - s->tcc_lib_path = CONFIG_TCCDIR; - - preprocess_new(); - - /* 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); - - /* standard defines */ - tcc_define_symbol(s, "__STDC__", NULL); - tcc_define_symbol(s, "__STDC_VERSION__", "199901L"); -#if defined(TCC_TARGET_I386) - tcc_define_symbol(s, "__i386__", NULL); -#endif -#if defined(TCC_TARGET_X86_64) - tcc_define_symbol(s, "__x86_64__", NULL); -#endif -#if 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); -#endif -#ifdef TCC_TARGET_PE - tcc_define_symbol(s, "_WIN32", NULL); -#else - 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 -#endif - /* tiny C specific defines */ - tcc_define_symbol(s, "__TINYC__", NULL); - - /* tiny C & gcc defines */ - tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int"); - tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int"); -#ifdef TCC_TARGET_PE - tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short"); -#else - tcc_define_symbol(s, "__WCHAR_TYPE__", "int"); -#endif - -#ifndef TCC_TARGET_PE - /* default library paths */ - tcc_add_library_path(s, CONFIG_SYSROOT "/usr/local/lib"); - tcc_add_library_path(s, CONFIG_SYSROOT "/usr/lib"); - tcc_add_library_path(s, CONFIG_SYSROOT "/lib"); -#endif - - /* no section zero */ - dynarray_add((void ***)&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); - - /* symbols are always generated for linking stage */ - symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, - ".strtab", - ".hashtab", SHF_PRIVATE); - strtab_section = symtab_section->link; - - /* private symbol table for dynamic symbols */ - s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE, - ".dynstrtab", - ".dynhashtab", SHF_PRIVATE); - s->alacarte_link = 1; - -#ifdef CHAR_IS_UNSIGNED - s->char_is_unsigned = 1; -#endif -#if defined(TCC_TARGET_PE) && 0 - /* XXX: currently the PE linker is not ready to support that */ - s->leading_underscore = 1; -#endif - return s; -} - -void tcc_delete(TCCState *s1) -{ - int i; - - tcc_cleanup(); - - /* 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 */ - for ( i = 0; i < s1->nb_loaded_dlls; i++) { - DLLReference *ref = s1->loaded_dlls[i]; - if ( ref->handle ) - dlclose(ref->handle); - } - - /* free loaded dlls array */ - dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls); - - /* free library paths */ - dynarray_reset(&s1->library_paths, &s1->nb_library_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); - - tcc_free(s1); -} - -int tcc_add_include_path(TCCState *s1, const char *pathname) -{ - char *pathname1; - - pathname1 = tcc_strdup(pathname); - dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1); - return 0; -} - -int tcc_add_sysinclude_path(TCCState *s1, const char *pathname) -{ - char *pathname1; - - pathname1 = tcc_strdup(pathname); - dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1); - return 0; -} - -static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) -{ - const char *ext; - ElfW(Ehdr) ehdr; - int fd, ret; - BufferedFile *saved_file; - - /* find source file type with extension */ - ext = tcc_fileextension(filename); - if (ext[0]) - ext++; - - /* open the file */ - saved_file = file; - file = tcc_open(s1, filename); - if (!file) { - if (flags & AFF_PRINT_ERROR) { - error_noabort("file '%s' not found", filename); - } - ret = -1; - goto fail1; - } - - if (flags & AFF_PREPROCESS) { - ret = tcc_preprocess(s1); - } else if (!ext[0] || !PATHCMP(ext, "c")) { - /* C file assumed */ - ret = tcc_compile(s1); - } else -#ifdef CONFIG_TCC_ASM - if (!strcmp(ext, "S")) { - /* preprocessed assembler */ - ret = tcc_assemble(s1, 1); - } else if (!strcmp(ext, "s")) { - /* non preprocessed assembler */ - ret = tcc_assemble(s1, 0); - } else -#endif -#ifdef TCC_TARGET_PE - if (!PATHCMP(ext, "def")) { - ret = pe_load_def_file(s1, file->fd); - } else -#endif - { - fd = file->fd; - /* assume executable format: auto guess file type */ - ret = read(fd, &ehdr, sizeof(ehdr)); - lseek(fd, 0, SEEK_SET); - if (ret <= 0) { - error_noabort("could not read header"); - goto fail; - } else if (ret != sizeof(ehdr)) { - goto try_load_script; - } - - if (ehdr.e_ident[0] == ELFMAG0 && - ehdr.e_ident[1] == ELFMAG1 && - ehdr.e_ident[2] == ELFMAG2 && - ehdr.e_ident[3] == ELFMAG3) { - file->line_num = 0; /* do not display line number if error */ - if (ehdr.e_type == ET_REL) { - ret = tcc_load_object_file(s1, fd, 0); - } else if (ehdr.e_type == ET_DYN) { - if (s1->output_type == TCC_OUTPUT_MEMORY) { -#ifdef TCC_TARGET_PE - ret = -1; -#else - void *h; - h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY); - if (h) - ret = 0; - else - ret = -1; -#endif - } else { - ret = tcc_load_dll(s1, fd, filename, - (flags & AFF_REFERENCED_DLL) != 0); - } - } else { - error_noabort("unrecognized ELF file"); - goto fail; - } - } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) { - file->line_num = 0; /* do not display line number if error */ - ret = tcc_load_archive(s1, fd); - } else -#ifdef TCC_TARGET_COFF - if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) { - ret = tcc_load_coff(s1, fd); - } else -#endif -#ifdef TCC_TARGET_PE - if (pe_test_res_file(&ehdr, ret)) { - ret = pe_load_res_file(s1, fd); - } else -#endif - { - /* as GNU ld, consider it is an ld script if not recognized */ - try_load_script: - ret = tcc_load_ldscript(s1); - if (ret < 0) { - error_noabort("unrecognized file type"); - goto fail; - } - } - } - the_end: - tcc_close(file); - fail1: - file = saved_file; - return ret; - fail: - ret = -1; - goto the_end; -} - -int tcc_add_file(TCCState *s, const char *filename) -{ - if (s->output_type == TCC_OUTPUT_PREPROCESS) - return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS); - else - return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR); -} - -int tcc_add_library_path(TCCState *s, const char *pathname) -{ - char *pathname1; - - pathname1 = tcc_strdup(pathname); - dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1); - return 0; -} - -/* find and load a dll. Return non zero if not found */ -/* XXX: add '-rpath' option support ? */ -static int tcc_add_dll(TCCState *s, const char *filename, int flags) -{ - char buf[1024]; - int i; - - for(i = 0; i < s->nb_library_paths; i++) { - snprintf(buf, sizeof(buf), "%s/%s", - s->library_paths[i], filename); - if (tcc_add_file_internal(s, buf, flags) == 0) - return 0; - } - return -1; -} - -/* the library name is the same as the argument of the '-l' option */ -int tcc_add_library(TCCState *s, const char *libraryname) -{ - char buf[1024]; - int i; - - /* first we look for the dynamic library if not static linking */ - if (!s->static_link) { -#ifdef TCC_TARGET_PE - snprintf(buf, sizeof(buf), "%s.def", libraryname); -#else - snprintf(buf, sizeof(buf), "lib%s.so", libraryname); -#endif - if (tcc_add_dll(s, buf, 0) == 0) - return 0; - } - - /* then we look for the static library */ - for(i = 0; i < s->nb_library_paths; i++) { - snprintf(buf, sizeof(buf), "%s/lib%s.a", - s->library_paths[i], libraryname); - if (tcc_add_file_internal(s, buf, 0) == 0) - return 0; - } - return -1; -} - -int tcc_add_symbol(TCCState *s, const char *name, void *val) -{ - add_elf_sym(symtab_section, (unsigned long)val, 0, - ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - SHN_ABS, name); - return 0; -} - -int tcc_set_output_type(TCCState *s, int output_type) -{ - char buf[1024]; - - s->output_type = output_type; - - if (!s->nostdinc) { - /* default include paths */ - /* XXX: reverse order needed if -isystem support */ -#ifndef TCC_TARGET_PE - tcc_add_sysinclude_path(s, CONFIG_SYSROOT "/usr/local/include"); - tcc_add_sysinclude_path(s, CONFIG_SYSROOT "/usr/include"); -#endif - snprintf(buf, sizeof(buf), "%s/include", s->tcc_lib_path); - tcc_add_sysinclude_path(s, buf); -#ifdef TCC_TARGET_PE - snprintf(buf, sizeof(buf), "%s/include/winapi", s->tcc_lib_path); - tcc_add_sysinclude_path(s, buf); -#endif - } - - /* if bound checking, then add corresponding sections */ -#ifdef CONFIG_TCC_BCHECK - if (s->do_bounds_check) { - /* define symbol */ - tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL); - /* create bounds sections */ - bounds_section = new_section(s, ".bounds", - SHT_PROGBITS, SHF_ALLOC); - lbounds_section = new_section(s, ".lbounds", - SHT_PROGBITS, SHF_ALLOC); - } -#endif - - if (s->char_is_unsigned) { - tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL); - } - - /* add debug sections */ - if (s->do_debug) { - /* stab symbols */ - 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); - } - - /* add libc crt1/crti objects */ -#ifndef TCC_TARGET_PE - if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && - !s->nostdlib) { - if (output_type != TCC_OUTPUT_DLL) - tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o"); - tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o"); - } -#endif - -#ifdef TCC_TARGET_PE - snprintf(buf, sizeof(buf), "%s/lib", s->tcc_lib_path); - tcc_add_library_path(s, buf); -#endif - - return 0; -} - -#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 FlagDef warning_defs[] = { - { 0, 0, "unsupported" }, - { 0, 0, "write-strings" }, - { 0, 0, "error" }, - { 0, WD_ALL, "implicit-function-declaration" } -}; - -void _init_warning_defs(void) { - warning_defs[0].offset = offsetof(TCCState, warn_unsupported); - warning_defs[1].offset = offsetof(TCCState, warn_write_strings); - warning_defs[2].offset = offsetof(TCCState, warn_error); - warning_defs[3].offset = offsetof(TCCState, warn_implicit_function_declaration); -} - -static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, - const char *name, int value) -{ - int i; - const FlagDef *p; - const char *r; - - r = name; - if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') { - r += 3; - value = !value; - } - for(i = 0, p = flags; i < nb_flags; i++, p++) { - if (!strcmp(r, p->name)) - goto found; - } - return -1; - found: - if (p->flags & FD_INVERT) - value = !value; - *(int *)((uint8_t *)s + p->offset) = value; - return 0; -} - - -/* set/reset a warning */ -int tcc_set_warning(TCCState *s, const char *warning_name, int value) -{ - int i; - const FlagDef *p; - - if (!strcmp(warning_name, "all")) { - for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) { - if (p->flags & WD_ALL) - *(int *)((uint8_t *)s + p->offset) = 1; - } - return 0; - } else { - return set_flag(s, warning_defs, countof(warning_defs), - warning_name, value); - } -} - -static FlagDef flag_defs[] = { - { 0, 0, "unsigned-char" }, - { 0, FD_INVERT, "signed-char" }, - { 0, FD_INVERT, "common" }, - { 0, 0, "leading-underscore" } -}; -void _init_flag_defs(void) { - flag_defs[0].offset = offsetof(TCCState, char_is_unsigned); - flag_defs[1].offset = offsetof(TCCState, char_is_unsigned); - flag_defs[2].offset = offsetof(TCCState, nocommon); - flag_defs[3].offset = offsetof(TCCState, leading_underscore); -} - -/* set/reset a flag */ -int tcc_set_flag(TCCState *s, const char *flag_name, int value) -{ - return set_flag(s, flag_defs, countof(flag_defs), - flag_name, value); -} - -/* set CONFIG_TCCDIR at runtime */ -void tcc_set_lib_path(TCCState *s, const char *path) -{ - s->tcc_lib_path = tcc_strdup(path); -} - -void tcc_print_stats(TCCState *s, int64_t total_time) -{ - double tt; - tt = (double)total_time / 1000000.0; - if (tt < 0.001) - tt = 0.001; - if (total_bytes < 1) - total_bytes = 1; - printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n", - tok_ident - TOK_IDENT, total_lines, total_bytes, - tt, (int)(total_lines / tt), - total_bytes / tt / 1000000.0); -} diff --git a/05/tcc-0.9.25/libtcc.h b/05/tcc-0.9.25/libtcc.h deleted file mode 100644 index 96070e2..0000000 --- a/05/tcc-0.9.25/libtcc.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef LIBTCC_H -#define LIBTCC_H - -#ifdef LIBTCC_AS_DLL -#define LIBTCCAPI __declspec(dllexport) -#else -#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); - -/* add debug information in the generated code */ -LIBTCCAPI void tcc_enable_debug(TCCState *s); - -/* 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/reset a warning */ -LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value); - -/*****************************/ -/* 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 (either a C file, dll, an object, a library or an ld - script). Return -1 if error. */ -LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename); - -/* compile a string containing a C source. Return non zero if - error. */ -LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf); - -/*****************************/ -/* linking commands */ - -/* set output type. MUST BE CALLED before any compilation */ -#define TCC_OUTPUT_MEMORY 0 /* output will be ran in memory (no - output file) (default) */ -#define TCC_OUTPUT_EXE 1 /* executable file */ -#define TCC_OUTPUT_DLL 2 /* dynamic library */ -#define TCC_OUTPUT_OBJ 3 /* object file */ -#define TCC_OUTPUT_PREPROCESS 4 /* preprocessed file (used internally) */ -LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type); - -#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 */ - -/* 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, 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); - -/* copy code into memory passed in by the caller and do all relocations - (needed before using tcc_get_symbol()). - returns -1 on error and required size if ptr is NULL */ -LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr); - -/* return symbol value or NULL if not found */ -LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name); - -/* set CONFIG_TCCDIR at runtime */ -LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/05/tcc-0.9.25/limits.h b/05/tcc-0.9.25/limits.h deleted file mode 100644 index 633e9ff..0000000 --- a/05/tcc-0.9.25/limits.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _LIMITS_H -#define _LIMITS_H - -#include // we define all the relevant constants here - -#endif // _LIMITS_H diff --git a/05/tcc-0.9.25/locale.h b/05/tcc-0.9.25/locale.h deleted file mode 100644 index af90729..0000000 --- a/05/tcc-0.9.25/locale.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef _LOCALE_H -#define _LOCALE_H - -#include - -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_MAX */ - char frac_digits; /* CHAR_MAX */ - char p_cs_precedes; /* CHAR_MAX */ - char p_sep_by_space; /* CHAR_MAX */ - char n_cs_precedes; /* CHAR_MAX */ - char n_sep_by_space; /* CHAR_MAX */ - char p_sign_posn; /* CHAR_MAX */ - char n_sign_posn; /* CHAR_MAX */ -}; - -// these are GCC's constants, but it doesn't really matter which constants we use. -#define LC_ALL 6 -#define LC_COLLATE 3 -#define LC_CTYPE 0 -#define LC_MONETARY 4 -#define LC_NUMERIC 1 -#define LC_TIME 2 - -char *setlocale(int category, char *locale) { - if (!locale) return "C"; - if (*locale == 'C' && !locale[1]) { - // yep - return "C"; - } - - // we only support the C locale - return NULL; - -} - -struct lconv *localeconv(void) { - static struct lconv conv = { - ".", - "", "", "", - "", "", "", - "", "", "", - CHAR_MAX, CHAR_MAX, CHAR_MAX, - CHAR_MAX, CHAR_MAX, CHAR_MAX, - CHAR_MAX, CHAR_MAX - }; - return &conv; -} - -#endif // _LOCALE_H diff --git a/05/tcc-0.9.25/math.h b/05/tcc-0.9.25/math.h deleted file mode 100644 index 7b029ac..0000000 --- a/05/tcc-0.9.25/math.h +++ /dev/null @@ -1,409 +0,0 @@ -#ifndef _MATH_H -#define _MATH_H - -#include -#define HUGE_VAL _INFINITY // glibc defines HUGE_VAL as infinity (the C standard only requires it to be positive, funnily enough) -#define _NAN (-(_INFINITY-_INFINITY)) -#define _PI 3.141592653589793 -#define _2PI 6.283185307179586 -#define _HALF_PI 1.5707963267948966 -#define _THREE_HALVES_PI 4.71238898038469 - -// NOTE: these functions are not IEEE 754-compliant (the C standard doesn't require them to be), but they're pretty good - -double frexp(double value, int *exp) { - if (value == 0) { - *exp = 0; - return 0; - } - unsigned long u = *(unsigned long *)&value, significand; - *exp = ((u >> 52) & 0x7ff) - 1022; - // replace exponent with 1022 - u &= 0x800fffffffffffff; - u |= 0x3fe0000000000000; - return *(double *)&u; -} - -double ldexp(double x, int exp) { - int e; - double y = frexp(x, &e); - // since x = y * 2^e, x * 2^exp = y * 2^(e+exp) - exp += e; - if (exp < -1022) return 0; - if (exp > 1023) return _INFINITY; - unsigned long pow2 = (unsigned long)(exp + 1023) << 52; - return y * *(double *)&pow2; -} - -double floor(double x) { - if (x >= 0.0) { - if (x > 1073741824.0 * 1073741824.0) - return x; // floats this big must be integers - return (unsigned long)x; - } else { - if (x < -1073741824.0 * 1073741824.0) - return x; // floats this big must be integers - double i = (long)x; - if (x == i) return x; - return i - 1.0; - } -} - -double ceil(double x) { - double f = floor(x); - if (x == f) return f; - return f + 1.; -} - -double fabs(double x) { - // this is better than x >= 0 ? x : -x because it deals with -0 properly - unsigned long u = *(unsigned long *)&x; - u &= 0x7fffffffffffffff; - return *(double *)&u; -} - -double fmod(double x, double y) { - if (y == 0.0) { - errno = EDOM; - return 0.0; - } - return x - (floor(x / y) * y); -} - -double _sin_taylor(double x) { - double i; - double term = x; - // taylor expansion for sin: x - x³/3! + xâµ/5! - ... - - // https://en.wikipedia.org/wiki/Kahan_summation_algorithm - double prev = -1.0; - double sum = 0.0; - double c = 0.0; - for (i = 0.0; i < 100.0 && sum != prev; ++i) { - prev = sum; - double y = term - c; - double t = sum + y; - c = (t - sum) - y; - sum = t; - term *= -(x * x) / ((2.0*i+2.0)*(2.0*i+3.0)); - } - return sum; -} - -double _cos_taylor(double x) { - double i; - double term = 1.0; - // taylor expansion for cos: 1 - x²/2! + xâ´/4! - ... - - // https://en.wikipedia.org/wiki/Kahan_summation_algorithm - double prev = -1.0; - double sum = 0.0; - double c = 0.0; - for (i = 0.0; i < 100.0 && sum != prev; ++i) { - prev = sum; - double y = term - c; - double t = sum + y; - c = (t - sum) - y; - sum = t; - term *= -(x * x) / ((2.0*i+1.0)*(2.0*i+2.0)); - } - return sum; -} - -double sin(double x) { - x = fmod(x, 2.0*_PI); - // the Taylor series works best for small inputs. so, provide _sin_taylor with a value in the range [0,Ï€/2] - if (x < _HALF_PI) - return _sin_taylor(x); - if (x < _PI) - return _sin_taylor(_PI - x); - if (x < _THREE_HALVES_PI) - return -_sin_taylor(x - _PI); - return -_sin_taylor(_2PI - x); -} - -double cos(double x) { - x = fmod(x, 2.0*_PI); - // the Taylor series works best for small inputs. so, provide _cos_taylor with a value in the range [0,Ï€/2] - if (x < _HALF_PI) - return _cos_taylor(x); - if (x < _PI) - return -_cos_taylor(_PI - x); - if (x < _THREE_HALVES_PI) - return -_cos_taylor(x - _PI); - return _cos_taylor(_2PI - x); -} - -double tan(double x) { - return sin(x)/cos(x); -} - -// for sqrt and the inverse trigonometric functions, we use Newton's method -// https://en.wikipedia.org/wiki/Newton%27s_method - -double sqrt(double x) { - if (x < 0.0) { - errno = EDOM; - return _NAN; - } - if (x == 0.0) return 0.0; - if (x == _INFINITY) return _INFINITY; - // we want to find the root of: f(t) = t² - x - // f'(t) = 2t - int exp; - double y = frexp(x, &exp); - if (exp & 1) { - y *= 2; - --exp; - } - // newton's method will be slow for very small or very large numbers. - // so we have ensured that - // 0.5 ≤ y < 2 - // and also x = y * 2^exp; sqrt(x) = sqrt(y) * 2^(exp/2) NB: we've ensured that exp is even - - // 7 iterations seems to be more than enough for any number - double t = y; - t = (y / t + t) * 0.5; - t = (y / t + t) * 0.5; - t = (y / t + t) * 0.5; - t = (y / t + t) * 0.5; - t = (y / t + t) * 0.5; - t = (y / t + t) * 0.5; - t = (y / t + t) * 0.5; - - return ldexp(t, exp>>1); - -} - -double _acos_newton(double x) { - // we want to find the root of: f(t) = cos(t) - x - // f'(t) = -sin(t) - double t = _HALF_PI - x; // reasonably good first approximation - double prev_t = -100.0; - int i; - - for (i = 0; i < 100 && prev_t != t; ++i) { - prev_t = t; - t += (cos(t) - x) / sin(t); - } - return t; -} - -double _asin_newton(double x) { - // we want to find the root of: f(t) = sin(t) - x - // f'(t) = cos(t) - double t = x; // reasonably good first approximation - double prev_t = -100.0; - int i; - - for (i = 0; i < 100 && prev_t != t; ++i) { - prev_t = t; - t += (x - sin(t)) / cos(t); - } - return t; -} - -double acos(double x) { - if (x > 1.0 || x < -1.0) { - errno = EDOM; - return _NAN; - } - // Newton's method doesn't work well near -1 and 1, because f(x) / f'(x) is very large. - if (x > 0.8) - return _asin_newton(sqrt(1-x*x)); - if (x < -0.8) - return _PI-_asin_newton(sqrt(1-x*x)); - - return _acos_newton(x); -} - -double asin(double x) { - if (x > 1.0 || x < -1.0) { - errno = EDOM; - return _NAN; - } - // Newton's method doesn't work well near -1 and 1, because f(x) / f'(x) is very large. - if (x > 0.8) - return _acos_newton(sqrt(1.0-x*x)); - if (x < -0.8) - return -_acos_newton(sqrt(1.0-x*x)); - - return _asin_newton(x); -} - -double atan(double x) { - // the formula below breaks for really large inputs; tan(10^20) as a double is indistinguishable from pi/2 anyways - if (x > 1e20) return _HALF_PI; - if (x < -1e20) return -_HALF_PI; - - // we can use a nice trigonometric identity here - return asin(x / sqrt(1+x*x)); -} - -double atan2(double y, double x) { - if (x == 0.0) { - if (y > 0.0) return _HALF_PI; - if (y < 0.0) return -_HALF_PI; - return 0.0; // this is what IEEE 754 does - } - - double a = atan(y/x); - if (x > 0.0) { - return a; - } else if (y > 0.0) { - return a + _PI; - } else { - return a - _PI; - } -} - -double _exp_taylor(double x) { - double i; - double term = 1.0; - // taylor expansion for exp: 1 + x/1! + x²/2! + ... - - // https://en.wikipedia.org/wiki/Kahan_summation_algorithm - double prev = -1.0; - double sum = 0.0; - double c = 0.0; - for (i = 1.0; i < 100.0 && sum != prev; ++i) { - prev = sum; - double y = term - c; - double t = sum + y; - c = (t - sum) - y; - sum = t; - term *= x / i; - } - return sum; -} - -double exp(double x) { - if (x > 709.782712893384) { - errno = ERANGE; - return _INFINITY; - } - if (x == 0.0) return 1; - if (x < -744.4400719213812) - return 0; - int i, e; - double y = frexp(x, &e); - if (e < 1.0) return _exp_taylor(x); - // the taylor series doesn't work well for large x (positive or negative), - // so we use the fact that exp(y*2^e) = exp(y)^(2^e) - double value = _exp_taylor(y); - for (i = 0; i < e; ++i) - value *= value; - return value; -} - -#define _LOG2 0.6931471805599453 - -double log(double x) { - if (x < 0.0) { - errno = EDOM; - return _NAN; - } - if (x == 0.0) return -_INFINITY; - if (x == 1.0) return 0.0; - int e; - double sum; - double a = frexp(x, &e); - // since x = a * 2^e, log(x) = log(a) + log(2^e) = log(a) + e log(2) - sum = e * _LOG2; - // now that a is in [1/2,1), the series log(a) = (a-1) - (a-1)²/2 + (a-1)³/3 - ... converges quickly - - a -= 1; - // https://en.wikipedia.org/wiki/Kahan_summation_algorithm - double prev = HUGE_VAL; - double c = 0; - double term = a; - double i; - for (i = 1.0; i < 100.0 && sum != prev; ++i) { - prev = sum; - double y = term / i - c; - double t = sum + y; - c = (t - sum) - y; - sum = t; - term *= -a; - } - return sum; -} - -#define _INVLOG10 0.43429448190325176 // = 1/log(10) -double log10(double x) { - return log(x) * _INVLOG10; -} - -double modf(double value, double *iptr) { - double m = fmod(value, 1.0); - if (value >= 0.0) { - *iptr = value - m; - return m; - } else if (m == 0.0) { - *iptr = value; - return 0.0; - } else { - *iptr = value - m + 1.0; - return m - 1.0; - } -} - -// double raised to the power of an integer -double _dpowi(double x, unsigned long y) { - double result = 1.0; - if (y & 1) { - --y; - result *= x; - } - if (y > 0) { - double p = _dpowi(x, y >> 1); - result *= p * p; - } - return result; -} - -double pow(double x, double y) { - if (x > 0.0) { - return exp(y * log(x)); - } else if (x < 0.0) { - if (fmod(y, 1.0) != 0) { - errno = EDOM; - return _NAN; - } - if (y > 1.6602069666338597e+19) - return x < -1. ? -_INFINITY : 0.; - if (y < -1.6602069666338597e+19) - return x < -1. ? 0. : -_INFINITY; - return _dpowi(x, (unsigned long)y); - } else { - if (y < 0) { - errno = EDOM; - return _NAN; - } - if (y > 0) { - // 0^x = 0 for x>0 - return 0.; - } - // 0^0 = 1 - return 1.; - } -} - -double cosh(double x) { - double e = exp(x); - return (e + 1./e) * 0.5; -} - -double sinh(double x) { - double e = exp(x); - return (e - 1./e) * 0.5; -} - -double tanh(double x) { - if (x > 20.0) return 1.; - if (x < -20.0) return -1.; - double e = exp(x); - double f = 1./e; - return (e - f) / (e + f); -} -#endif // _MATH_H diff --git a/05/tcc-0.9.25/setjmp.h b/05/tcc-0.9.25/setjmp.h deleted file mode 100644 index b3ffce1..0000000 --- a/05/tcc-0.9.25/setjmp.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _SETJMP_H -#define _SETJMP_H - -#include - -typedef long jmp_buf[3]; - -// @NONSTANDARD: we don't actually support setjmp - -int setjmp(jmp_buf env) { - return 0; -} - -void __longjmp(jmp_buf env, int val, const char *filename, int line) { - fprintf(stderr, "Error: Tried to longjmp from %s:%d with value %d\n", filename, line, val); - _Exit(-1); -} - -#define longjmp(env, val) __longjmp(env, val, __FILE__, __LINE__) - -#endif diff --git a/05/tcc-0.9.25/signal.h b/05/tcc-0.9.25/signal.h deleted file mode 100644 index ded960c..0000000 --- a/05/tcc-0.9.25/signal.h +++ /dev/null @@ -1,253 +0,0 @@ -#ifndef _SIGNAL_H -#define _SIGNAL_H - - -#include - -typedef long sig_atomic_t; // there are no "asynchronous interrupts" - -#define SIG_DFL ((void *)0) -#define SIG_IGN _sig_ign -#define SIG_ERR ((void *)-1) - -typedef void (*_Sighandler)(int); - -struct sigaction { - void (*sa_handler)(int); - #define sa_sigaction sa_handler - unsigned long sa_flags; - void (*sa_restorer)(void); - unsigned long sa_mask; -}; - -unsigned char _signal_restorer[] = { - 0x48,0xb8,15,0,0,0,0,0,0,0, // mov rax, 15 (sigreturn) - 0x0f,0x05 // syscall -}; - -#define _SIGNAL_HANDLERS 0xfff000 -#define _LE64(x) (x)&0xff, ((x)>> 8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff, \ - ((x)>>32)&0xff, ((x)>>40)&0xff, ((x)>>48)&0xff, (x)>>56 - -// we need to do this weird indirection because linux has a different -// calling convention from us. - -unsigned char _signal_handler[] = { - // signal # passed in rdi - 0x48,0x89,0xf8, // mov rax, rdi (signal #) - 0x50, // push rax - 0x50, // push rax (allocate space for return value) - 0x48,0xb8,_LE64(_SIGNAL_HANDLERS), // mov rax, _SIGNAL_HANDLERS - 0x48,0x89,0xc3, // mov rbx, rax - 0x48,0x89,0xf8, // mov rax, rdi (signal #) - 0x48,0xc1,0xe0,0x03, // shl rax, 3 - 0x48,0x01,0xd8, // add rax, rbx - 0x48,0x89,0xc3, // mov rbx, rax - 0x48,0x8b,0x03, // mov rax, [rbx] - 0xff,0xd0, // call rax - 0x48,0x81,0xc4,16,0,0,0, // add rsp, 16 - 0xc3 // ret -}; - -#define _SA_RESTORER 0x04000000 -#define SA_SIGINFO 4 -#define SA_RESETHAND 0x80000000 - -int __sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) { - return __syscall(13, signum, act, oldact, 8, 0, 0); -} - -void sigemptyset(unsigned long *set) { - *set = 0; -} - -void _sig_ign(int signal) { - return; -} - -static unsigned long _sig_mask = 0; - -_Sighandler signal(int sig, _Sighandler func) { - void **handlers = _SIGNAL_HANDLERS; - _Sighandler ret = handlers[sig]; - if (func == SIG_IGN) { - func = _sig_ign; - } - handlers[sig] = func; - - if (func == SIG_DFL) { - _sig_mask &= ~(1ul << (sig-1)); - } else { - _sig_mask |= 1ul << (sig-1); - } - struct sigaction act = {0}; - act.sa_handler = func == SIG_DFL ? SIG_DFL : (void*)_signal_handler; - act.sa_mask = _sig_mask; - act.sa_flags = _SA_RESTORER; - act.sa_restorer = _signal_restorer; - __sigaction(sig, &act, NULL); - return ret; -} - -int raise(int signal) { - return kill(getpid(), signal); -} - -#define FPE_INTDIV 1 -#define FPE_FLTDIV 3 - -#define __SI_MAX_SIZE 128 -#if __WORDSIZE == 64 -# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4) -#else -# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3) -#endif - -#ifndef __SI_ALIGNMENT -# define __SI_ALIGNMENT /* nothing */ -#endif -#ifndef __SI_BAND_TYPE -# define __SI_BAND_TYPE long int -#endif -#ifndef __SI_CLOCK_T -# define __SI_CLOCK_T __clock_t -#endif -#ifndef __SI_ERRNO_THEN_CODE -# define __SI_ERRNO_THEN_CODE 1 -#endif -#ifndef __SI_HAVE_SIGSYS -# define __SI_HAVE_SIGSYS 1 -#endif -#ifndef __SI_SIGFAULT_ADDL -# define __SI_SIGFAULT_ADDL /* nothing */ -#endif - -typedef int __pid_t; -typedef unsigned __uid_t; - -union __sigval -{ - int __sival_int; - void *__sival_ptr; -}; - -typedef union __sigval __sigval_t; -typedef long __clock_t; - -typedef struct - { - int si_signo; /* Signal number. */ -#if __SI_ERRNO_THEN_CODE - int si_errno; /* If non-zero, an errno value associated with - this signal, as defined in . */ - int si_code; /* Signal code. */ -#else - int si_code; - int si_errno; -#endif -#if __WORDSIZE == 64 - int __pad0; /* Explicit padding. */ -#endif - - union - { - int _pad[__SI_PAD_SIZE]; - - /* kill(). */ - struct - { - __pid_t si_pid; /* Sending process ID. */ - __uid_t si_uid; /* Real user ID of sending process. */ - } _kill; - - /* POSIX.1b timers. */ - struct - { - int si_tid; /* Timer ID. */ - int si_overrun; /* Overrun count. */ - __sigval_t si_sigval; /* Signal value. */ - } _timer; - - /* POSIX.1b signals. */ - struct - { - __pid_t si_pid; /* Sending process ID. */ - __uid_t si_uid; /* Real user ID of sending process. */ - __sigval_t si_sigval; /* Signal value. */ - } _rt; - - /* SIGCHLD. */ - struct - { - __pid_t si_pid; /* Which child. */ - __uid_t si_uid; /* Real user ID of sending process. */ - int si_status; /* Exit value or signal. */ - __SI_CLOCK_T si_utime; - __SI_CLOCK_T si_stime; - } _sigchld; - - /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */ - struct - { - void *si_addr; /* Faulting insn/memory ref. */ - __SI_SIGFAULT_ADDL - short int si_addr_lsb; /* Valid LSB of the reported address. */ - union - { - /* used when si_code=SEGV_BNDERR */ - struct - { - void *_lower; - void *_upper; - } _addr_bnd; - /* used when si_code=SEGV_PKUERR */ - uint32_t _pkey; - } _bounds; - } _sigfault; - - /* SIGPOLL. */ - struct - { - __SI_BAND_TYPE si_band; /* Band event for SIGPOLL. */ - int si_fd; - } _sigpoll; - - /* SIGSYS. */ -#if __SI_HAVE_SIGSYS - struct - { - void *_call_addr; /* Calling user insn. */ - int _syscall; /* Triggering system call number. */ - unsigned int _arch; /* AUDIT_ARCH_* of syscall. */ - } _sigsys; -#endif - } _sifields; - } siginfo_t __SI_ALIGNMENT; - - -/* X/Open requires some more fields with fixed names. */ -#define si_pid _sifields._kill.si_pid -#define si_uid _sifields._kill.si_uid -#define si_timerid _sifields._timer.si_tid -#define si_overrun _sifields._timer.si_overrun -#define si_status _sifields._sigchld.si_status -#define si_utime _sifields._sigchld.si_utime -#define si_stime _sifields._sigchld.si_stime -#define si_value _sifields._rt.si_sigval -#define si_int _sifields._rt.si_sigval.sival_int -#define si_ptr _sifields._rt.si_sigval.sival_ptr -#define si_addr _sifields._sigfault.si_addr -#define si_addr_lsb _sifields._sigfault.si_addr_lsb -#define si_lower _sifields._sigfault._bounds._addr_bnd._lower -#define si_upper _sifields._sigfault._bounds._addr_bnd._upper -#define si_pkey _sifields._sigfault._bounds._pkey -#define si_band _sifields._sigpoll.si_band -#define si_fd _sifields._sigpoll.si_fd -#if __SI_HAVE_SIGSYS -# define si_call_addr _sifields._sigsys._call_addr -# define si_syscall _sifields._sigsys._syscall -# define si_arch _sifields._sigsys._arch -#endif - - -#endif // _SIGNAL_H diff --git a/05/tcc-0.9.25/stab.def b/05/tcc-0.9.25/stab.def deleted file mode 100644 index 3d10ca6..0000000 --- a/05/tcc-0.9.25/stab.def +++ /dev/null @@ -1,238 +0,0 @@ -/* 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. */ -#if 0 - // random page break character for some reason -#endif -/* 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") -#if 0 - // random page break character for some reason -#endif -/* 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/05/tcc-0.9.25/stab.h b/05/tcc-0.9.25/stab.h deleted file mode 100644 index 80bd594..0000000 --- a/05/tcc-0.9.25/stab.h +++ /dev/null @@ -1,17 +0,0 @@ -#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/05/tcc-0.9.25/stdarg.h b/05/tcc-0.9.25/stdarg.h deleted file mode 100644 index 4df996f..0000000 --- a/05/tcc-0.9.25/stdarg.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _STDARG_H -#define _STDARG_H - -typedef unsigned long va_list; - -#define va_start(list, arg) ((list) = (unsigned long)&arg) -#define va_arg(list, type) (*((type *)(list += ((sizeof(type) + 7) & 0xfffffffffffffff8)))) -#define va_end(list) - -#endif // _STDARG_H diff --git a/05/tcc-0.9.25/stdc_common.h b/05/tcc-0.9.25/stdc_common.h deleted file mode 100644 index b9ffd9d..0000000 --- a/05/tcc-0.9.25/stdc_common.h +++ /dev/null @@ -1,684 +0,0 @@ -#ifndef _STDC_COMMON_H -#define _STDC_COMMON_H - -#define signed -#define volatile -#define register -#define const -#define NULL ((void*)0) - -typedef unsigned char uint8_t; -typedef char int8_t; -typedef unsigned short uint16_t; -typedef short int16_t; -typedef unsigned int uint32_t; -typedef int int32_t; -typedef unsigned long uint64_t; -typedef long int64_t; -typedef unsigned long size_t; -typedef long ptrdiff_t; -typedef unsigned long uintptr_t; -typedef long intptr_t; - -#define INT8_MAX 0x7f -#define INT8_MIN (-0x80) -#define INT16_MAX 0x7fff -#define INT16_MIN (-0x8000) -#define INT32_MAX 0x7fffffff -#define INT32_MIN (-0x80000000) -#define INT64_MAX 0x7fffffffffffffff -#define INT64_MIN (-0x8000000000000000) -#define UINT8_MAX 0xff -#define UINT16_MAX 0xffff -#define UINT32_MAX 0xffffffff -#define UINT64_MAX 0xffffffffffffffff -#define CHAR_BIT 8 -#define MB_LEN_MAX 4 -#define CHAR_MIN INT8_MIN -#define CHAR_MAX INT8_MAX -#define SCHAR_MIN INT8_MIN -#define SCHAR_MAX INT8_MAX -#define INT_MIN INT32_MIN -#define INT_MAX INT32_MAX -#define LONG_MIN INT64_MIN -#define LONG_MAX INT64_MAX -#define SHRT_MIN INT16_MIN -#define SHRT_MAX INT16_MAX -#define UCHAR_MAX UINT8_MAX -#define USHRT_MAX UINT16_MAX -#define UINT_MAX UINT32_MAX -#define ULONG_MAX UINT64_MAX - -static unsigned char __syscall_data[] = { - // mov rax, [rsp+24] - 0x48, 0x8b, 0x84, 0x24, 24, 0, 0, 0, - // mov rdi, rax - 0x48, 0x89, 0xc7, - // mov rax, [rsp+32] - 0x48, 0x8b, 0x84, 0x24, 32, 0, 0, 0, - // mov rsi, rax - 0x48, 0x89, 0xc6, - // mov rax, [rsp+40] - 0x48, 0x8b, 0x84, 0x24, 40, 0, 0, 0, - // mov rdx, rax - 0x48, 0x89, 0xc2, - // mov rax, [rsp+48] - 0x48, 0x8b, 0x84, 0x24, 48, 0, 0, 0, - // mov r10, rax - 0x49, 0x89, 0xc2, - // mov rax, [rsp+56] - 0x48, 0x8b, 0x84, 0x24, 56, 0, 0, 0, - // mov r8, rax - 0x49, 0x89, 0xc0, - // mov rax, [rsp+64] - 0x48, 0x8b, 0x84, 0x24, 64, 0, 0, 0, - // mov r9, rax - 0x49, 0x89, 0xc1, - // mov rax, [rsp+16] - 0x48, 0x8b, 0x84, 0x24, 16, 0, 0, 0, - // syscall - 0x0f, 0x05, - // mov [rsp+8], rax - 0x48, 0x89, 0x84, 0x24, 8, 0, 0, 0, - // ret - 0xc3 -}; - -#define __syscall(no, arg1, arg2, arg3, arg4, arg5, arg6)\ - (((unsigned long (*)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long))__syscall_data)\ - (no, arg1, arg2, arg3, arg4, arg5, arg6)) - -// we need to define ucontext_t -# define __ctx(fld) fld -typedef long long int greg_t; -#define __NGREG 23 -typedef greg_t gregset_t[__NGREG]; -#define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) -typedef struct -{ - unsigned long int __val[_SIGSET_NWORDS]; -} __sigset_t, sigset_t; -typedef struct -{ - void *ss_sp; - int ss_flags; - size_t ss_size; -} stack_t; -enum -{ - REG_R8 = 0, -# define REG_R8 REG_R8 - REG_R9, -# define REG_R9 REG_R9 - REG_R10, -# define REG_R10 REG_R10 - REG_R11, -# define REG_R11 REG_R11 - REG_R12, -# define REG_R12 REG_R12 - REG_R13, -# define REG_R13 REG_R13 - REG_R14, -# define REG_R14 REG_R14 - REG_R15, -# define REG_R15 REG_R15 - REG_RDI, -# define REG_RDI REG_RDI - REG_RSI, -# define REG_RSI REG_RSI - REG_RBP, -# define REG_RBP REG_RBP - REG_RBX, -# define REG_RBX REG_RBX - REG_RDX, -# define REG_RDX REG_RDX - REG_RAX, -# define REG_RAX REG_RAX - REG_RCX, -# define REG_RCX REG_RCX - REG_RSP, -# define REG_RSP REG_RSP - REG_RIP, -# define REG_RIP REG_RIP - REG_EFL, -# define REG_EFL REG_EFL - REG_CSGSFS, /* Actually short cs, gs, fs, __pad0. */ -# define REG_CSGSFS REG_CSGSFS - REG_ERR, -# define REG_ERR REG_ERR - REG_TRAPNO, -# define REG_TRAPNO REG_TRAPNO - REG_OLDMASK, -# define REG_OLDMASK REG_OLDMASK - REG_CR2 -# define REG_CR2 REG_CR2 -}; -struct _libc_fpxreg -{ - unsigned short int __ctx(significand)[4]; - unsigned short int __ctx(exponent); - unsigned short int __glibc_reserved1[3]; -}; -struct _libc_xmmreg -{ - uint32_t __ctx(element)[4]; -}; -struct _libc_fpstate -{ - uint16_t __ctx(cwd); - uint16_t __ctx(swd); - uint16_t __ctx(ftw); - uint16_t __ctx(fop); - uint64_t __ctx(rip); - uint64_t __ctx(rdp); - uint32_t __ctx(mxcsr); - uint32_t __ctx(mxcr_mask); - struct _libc_fpxreg _st[8]; - struct _libc_xmmreg _xmm[16]; - uint32_t __glibc_reserved1[24]; -}; -typedef struct _libc_fpstate *fpregset_t; -typedef struct { - gregset_t __ctx(gregs); - fpregset_t __ctx(fpregs); - unsigned long long __reserved1 [8]; -} mcontext_t; -typedef struct ucontext_t { - unsigned long int __ctx(uc_flags); - struct ucontext_t *uc_link; - stack_t uc_stack; - mcontext_t uc_mcontext; - sigset_t uc_sigmask; - struct _libc_fpstate __fpregs_mem; - unsigned long long int __ssp[4]; -} ucontext_t; - -long read(int fd, void *buf, size_t count) { - return __syscall(0, fd, buf, count, 0, 0, 0); -} - -long write(int fd, void *buf, size_t count) { - return __syscall(1, fd, buf, count, 0, 0, 0); -} - -void _Exit(int status) { - return __syscall(60, status, 0, 0, 0, 0, 0); -} - -int kill(int pid, int sig) { - return __syscall(62, pid, sig, 0, 0, 0, 0); -} - -int getpid(void) { - return __syscall(39, 0, 0, 0, 0, 0, 0); -} - -int fork(void) { - return __syscall(57, 0, 0, 0, 0, 0, 0); -} - -int execve(const char *pathname, char *const argv[], char *const envp[]) { - return __syscall(59, pathname, argv, envp, 0, 0, 0); -} - -int gettimeofday(struct timeval *tv, struct timezone *tz) { - return __syscall(96, tv, tz, 0, 0, 0, 0); -} - -typedef long time_t; - -struct timespec { - time_t tv_sec; - long tv_nsec; -}; - -struct timeval { - time_t tv_sec; - long tv_usec; -}; - -struct timezone { - int tz_minuteswest; - int tz_dsttime; -}; - -char *getcwd(char *buf, size_t size) { - long n = __syscall(79, buf, size, 0, 0, 0, 0); - if (n < 0) return NULL; - return buf; -} - -#define _WEXITSTATUS(status) (((status) & 0xff00) >> 8) -#define _WIFEXITED(status) (__WTERMSIG(status) == 0) -#define _WIFSIGNALED(status) \ - (((signed char) (((status) & 0x7f) + 1) >> 1) > 0) -int wait4(int pid, int *status, int options, struct rusage *rusage) { - return __syscall(61, pid, status, options, rusage, 0, 0); -} - -#define SIGABRT 6 -#define SIGFPE 8 -#define SIGKILL 9 -#define SIGILL 4 -#define SIGINT 2 -#define SIGSEGV 11 -#define SIGTERM 15 -#define SIGBUS 7 -#define SIGTRAP 5 -void abort(void) { - kill(getpid(), SIGABRT); -} - - -#define CLOCK_REALTIME 0 -#define CLOCK_MONOTONIC 1 -int clock_gettime(int clock, struct timespec *tp) { - return __syscall(228, clock, tp, 0, 0, 0, 0); -} - -#define F_OK 0 -#define R_OK 4 -#define W_OK 2 -#define X_OK 1 -int access(const char *pathname, int mode) { - return __syscall(21, pathname, mode, 0, 0, 0, 0); -} - -typedef struct { - int fd; - unsigned char eof; - unsigned char err; - unsigned char has_ungetc; - char ungetc; // character which was pushed by ungetc() -} FILE; - -int errno; -int printf(char *, ...); -int fprintf(FILE *, char *, ...); // needed now for assert() - -FILE _stdin = {0}, *stdin; -FILE _stdout = {1}, *stdout; -FILE _stderr = {2}, *stderr; - -#ifdef NDEBUG -#define assert(x) ((void)0) -#else -int __assert_failed(const char *file, int line, const char *expr) { - fprintf(stderr, "Assertion failed at %s:%d: %s\n", file, line, expr); - abort(); -} -#define assert(x) (void)((x) || __assert_failed(__FILE__, __LINE__, #x)) -#endif - - -int _clamp_long_to_int(long x) { - if (x < INT_MIN) return INT_MIN; - if (x > INT_MAX) return INT_MAX; - return x; -} - -short _clamp_long_to_short(long x) { - if (x < SHRT_MIN) return SHRT_MIN; - if (x > SHRT_MAX) return SHRT_MAX; - return x; -} - -unsigned _clamp_ulong_to_uint(unsigned long x) { - if (x > UINT_MAX) return UINT_MAX; - return x; -} - -unsigned short _clamp_ulong_to_ushort(unsigned long x) { - if (x > USHRT_MAX) return USHRT_MAX; - return x; -} - -#define EIO 5 -#define EDOM 33 -#define ERANGE 34 - -#define PROT_READ 1 -#define PROT_WRITE 2 -#define PROT_EXEC 4 -#define MAP_SHARED 0x01 -#define MAP_ANONYMOUS 0x20 -#define MAP_PRIVATE 0x02 -void *mmap(void *addr, size_t length, int prot, int flags, int fd, long offset) { - return __syscall(9, addr, length, prot, flags, fd, offset); -} - -int munmap(void *addr, size_t length) { - return __syscall(11, addr, length, 0, 0, 0, 0); -} - -int mprotect(void *addr, size_t len, int prot) { - return __syscall(10, addr, len, prot, 0, 0, 0); -} - -#define MREMAP_MAYMOVE 1 -void *_mremap(void *addr, size_t old_size, size_t new_size, int flags) { - return __syscall(25, addr, old_size, new_size, flags, 0, 0); -} - -void *malloc(size_t n) { - if (!n) return NULL; - void *memory; - size_t bytes = n + 16; - memory = mmap(0, bytes, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); - if ((uint64_t)memory > 0xffffffffffff0000) return NULL; - *(uint64_t *)memory = bytes; - return (char *)memory + 16; -} - -void free(void *ptr) { - if (!ptr) return; - uint64_t *memory = (char *)ptr - 16; - uint64_t size = *memory; - munmap(memory, size); -} - - -size_t strlen(char *s) { - char *t = s; - while (*t) ++t; - return t - s; -} - -void *memcpy(void *s1, const void *s2, size_t n) { - char *p = s1, *end = p + n, *q = s2; - while (p < end) - *p++ = *q++; - return s1; -} - -int isspace(int c) { - return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'; -} - -int isdigit(int c) { - return c >= '0' && c <= '9'; -} - -int _isdigit_in_base(int c, int base) { - if (c >= '0' && c <= '9') { - return c - '0' < base; - } else if (c >= 'a' && c <= 'z') { - return c - 'a' + 10 < base; - } else if (c >= 'A' && c <= 'Z') { - return c - 'A' + 10 < base; - } - return 0; -} - -void *memset(void *s, int c, size_t n) { - char *p = s, *end = p + n; - while (p < end) - *p++ = c; - return s; -} - -unsigned long strtoul(const char *nptr, char **endptr, int base) { - unsigned long value = 0, newvalue; - int overflow = 0; - - while (isspace(*nptr)) ++nptr; - if (*nptr == '+') ++nptr; - if (base == 0) { - if (*nptr == '0') { - ++nptr; - switch (*nptr) { - case 'x': - case 'X': - base = 16; - ++nptr; - break; - case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': - base = 8; - break; - default: - // this must just be the number 0. - if (endptr) *endptr = nptr; - return 0; - } - } else { - base = 10; - } - } - - while (1) { - int c = *nptr; - unsigned v; - if (c >= '0' && c <= '9') - v = c - '0'; - else if (c >= 'a' && c <= 'z') - v = c - 'a' + 10; - else if (c >= 'A' && c <= 'Z') - v = c - 'A' + 10; - else break; - if (v >= base) break; - unsigned long newvalue = value * base + v; - if (newvalue < value) overflow = 1; - value = newvalue; - ++nptr; - } - if (endptr) *endptr = nptr; - if (overflow) { - errno = ERANGE; - return ULONG_MAX; - } else { - return value; - } -} - -long strtol(const char *nptr, char **endptr, int base) { - int sign = 1; - while (isspace(*nptr)) ++nptr; - if (*nptr == '-') { - sign = -1; - ++nptr; - } - unsigned long mag = strtoul(nptr, endptr, base); - if (sign > 0) { - if (mag > LONG_MAX) { - errno = ERANGE; - return LONG_MAX; - } - return (long)mag; - } else { - if (mag > (unsigned long)LONG_MAX + 1) { - errno = ERANGE; - return LONG_MIN; - } - return -(long)mag; - } -} - -long _strtol_clamped(const char *nptr, char **endptr, int base, int min, int max) { - long l = strtol(nptr, endptr, base); - if (l < min) return min; - if (l > max) return max; - return l; -} - -#define _NPOW10 310 -#define _INFINITY 1e1000 -// non-negative floating-point number with more precision than a double -// its value is equal to fraction * 2^exponent -typedef struct { - unsigned long fraction; - int exponent; -} _Float; - -// ensure that f->fraction >= 2^64 / 2 -static void _normalize_float(_Float *f) { - if (!f->fraction) return; - while (f->fraction < 0x8000000000000000) { - f->exponent -= 1; - f->fraction <<= 1; - } -} - -static double _Float_to_double(_Float f) { - unsigned long dbl_fraction; - int dbl_exponent; - unsigned long dbl_value; - if (f.fraction == 0) return 0; - _normalize_float(&f); - f.fraction &= 0x7fffffffffffffff; // remove the "1." in 1.01101110111... to get 63-bit significand - dbl_fraction = (f.fraction + 0x3ff) >> 11; - dbl_exponent = f.exponent + 63; - if (dbl_exponent < -1022) return 0; - if (dbl_exponent > 1023) return _INFINITY; - dbl_exponent += 1023; - dbl_value = (unsigned long)dbl_exponent << 52 | dbl_fraction; - return *(double *)&dbl_value; -} - -static _Float _powers_of_10_dat[2*_NPOW10+1]; -static _Float *_powers_of_10; -static _Float _Float_ZERO = {0, 1}; -static _Float _Float_INFINITY = {0x8000000000000000, 100000}; - - -_Float _int_pow10(int x) { - if (x <= -_NPOW10) return _Float_ZERO; - if (x >= _NPOW10) return _Float_INFINITY; - return _powers_of_10[x]; -} - -double strtod(const char *nptr, char **endptr) { - const char *flt, *dot, *p, *number_end; - double sign = 1; - int exponent = 0; - while (isspace(*nptr)) ++nptr; - - flt = nptr; // start of float - if (*flt == '+') ++flt; - else if (*flt == '-') sign = -1, ++flt; - - if (*flt != '.' && (*flt < '0' || *flt > '9')) { - // this isn't a float - *endptr = nptr; - return 0; - } - - // find the decimal point, if any - dot = flt; - while (*dot >= '0' && *dot <= '9') ++dot; - - nptr = dot + (*dot == '.'); - // skip digits after the dot - while (*nptr >= '0' && *nptr <= '9') ++nptr; - number_end = nptr; - - if (*nptr == 'e') { - ++nptr; - exponent = 1; - if (*nptr == '+') ++nptr; - else if (*nptr == '-') ++nptr, exponent = -1; - exponent *= _strtol_clamped(nptr, &nptr, 10, -10000, 10000); // use _strtol_clamped to prevent problems with -LONG_MIN - } - - // construct the value using the Kahan summation algorithm (https://en.wikipedia.org/wiki/Kahan_summation_algorithm) - double sum = 0; - double c = 0; - for (p = flt; p < number_end; ++p) { - if (*p == '.') continue; - int n = *p - '0'; - assert(n >= 0 && n <= 9); - int pow10 = dot - p; - pow10 -= pow10 > 0; - pow10 += exponent; - _Float f_val = _int_pow10(pow10); - f_val.fraction >>= 4; - f_val.exponent += 4; - f_val.fraction *= n; - double value = _Float_to_double(f_val); - if (value == _INFINITY || sum == _INFINITY) { - sum = _INFINITY; - break; - } - double y = value - c; - double t = sum + y; - c = (t - sum) - y; - sum = t; - } - - if (sum == _INFINITY) errno = ERANGE; - if (endptr) *endptr = nptr; - return sum * sign; -} - -float strtof(const char *nptr, char **endptr) { - return strtod(nptr, endptr); -} - -long double strtold(const char *nptr, char **endptr) { - return strtod(nptr, endptr); -} - -char *strerror(int errnum) { - switch (errnum) { - case ERANGE: return "Range error"; - case EDOM: return "Domain error"; - case EIO: return "I/O error"; - } - return "Other error"; -} - -typedef void (*_ExitHandler)(void); -_ExitHandler _exit_handlers[33]; -int _n_exit_handlers; - -void exit(int status) { - int i; - for (i = _n_exit_handlers - 1; i >= 0; --i) - _exit_handlers[i](); - _Exit(status); -} - -int main(); - -static char **_envp; -static uint64_t _rand_seed; - -int _main(int argc, char **argv) { - int i; - _Float p = {1, 0}; - - _envp = argv + argc + 1; // this is where the environment variables will be - - stdin = &_stdin; - stdout = &_stdout; - stderr = &_stderr; - - /* - "If rand is called before any calls to srand have been made, - the same sequence shall be generated as when srand is first - called with a seed value of 1." C89 § 4.10.2.2 - */ - _rand_seed = 1; - // initialize powers of 10 - _powers_of_10 = _powers_of_10_dat + _NPOW10; - for (i = 0; i < _NPOW10; ++i) { - _normalize_float(&p); - _powers_of_10[i] = p; - p.exponent += 4; - p.fraction >>= 4; - p.fraction *= 10; - } - - p.fraction = 1; - p.exponent = 0; - for (i = 0; i > -_NPOW10; --i) { - _normalize_float(&p); - _powers_of_10[i] = p; - p.fraction /= 5; - p.exponent -= 1; - } - - exit(main(argc, argv)); -} - - -#endif // _STDC_COMMON_H diff --git a/05/tcc-0.9.25/stddef.h b/05/tcc-0.9.25/stddef.h deleted file mode 100644 index f012d95..0000000 --- a/05/tcc-0.9.25/stddef.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _STDDEF_H -#define _STDDEF_H - -#include -#define offsetof(struct, member) ((size_t)(&((struct *)NULL)->member)) -// @NONSTANDARD: we don't have wchar_t - -#endif // _STDDEF_H diff --git a/05/tcc-0.9.25/stdio.h b/05/tcc-0.9.25/stdio.h deleted file mode 100644 index 436dd62..0000000 --- a/05/tcc-0.9.25/stdio.h +++ /dev/null @@ -1,2270 +0,0 @@ -#ifndef _STDIO_H -#define _STDIO_H - -#include -#include - -int printf(const char *, ...); - -/* --- snprintf, adapted from github.com/nothings/stb stb_sprintf.h */ - -#ifndef STB_SPRINTF_MIN -#define STB_SPRINTF_MIN 512 // how many characters per callback -#endif -typedef char *_STBSP_SPRINTFCB(const char *buf, void *user, int len); - -// internal float utility functions -static int32_t _stbsp__real_to_str(char const **start, uint32_t *len, char *out, int32_t *decimal_pos, double value, uint32_t frac_digits); -static int32_t _stbsp__real_to_parts(int64_t *bits, int32_t *expo, double value); -#define STBSP__SPECIAL 0x7000 - -static char _stbsp__period = '.'; -static char _stbsp__comma = ','; -static struct -{ - short temp; // force next field to be 2-byte aligned - char pair[201]; -} _stbsp__digitpair = -{ - 0, - "00010203040506070809101112131415161718192021222324" - "25262728293031323334353637383940414243444546474849" - "50515253545556575859606162636465666768697071727374" - "75767778798081828384858687888990919293949596979899" -}; - -#define STBSP__LEFTJUST 1 -#define STBSP__LEADINGPLUS 2 -#define STBSP__LEADINGSPACE 4 -#define STBSP__LEADING_0X 8 -#define STBSP__LEADINGZERO 16 -#define STBSP__INTMAX 32 -#define STBSP__TRIPLET_COMMA 64 -#define STBSP__NEGATIVE 128 -#define STBSP__METRIC_SUFFIX 256 -#define STBSP__HALFWIDTH 512 -#define STBSP__METRIC_NOSPACE 1024 -#define STBSP__METRIC_1024 2048 -#define STBSP__METRIC_JEDEC 4096 - -static void _stbsp__lead_sign(uint32_t fl, char *sign) -{ - sign[0] = 0; - if (fl & STBSP__NEGATIVE) { - sign[0] = 1; - sign[1] = '-'; - } else if (fl & STBSP__LEADINGSPACE) { - sign[0] = 1; - sign[1] = ' '; - } else if (fl & STBSP__LEADINGPLUS) { - sign[0] = 1; - sign[1] = '+'; - } -} - -static uint32_t _stbsp__strlen_limited(char const *s, uint32_t limit) -{ - char const * sn = s; - - // get up to 4-byte alignment - for (;;) { - if (((uintptr_t)sn & 3) == 0) - break; - - if (!limit || *sn == 0) - return (uint32_t)(sn - s); - - ++sn; - --limit; - } - - // scan over 4 bytes at a time to find terminating 0 - // this will intentionally scan up to 3 bytes past the end of buffers, - // but becase it works 4B aligned, it will never cross page boundaries - // (hence the STBSP__ASAN markup; the over-read here is intentional - // and harmless) - while (limit >= 4) { - uint32_t v = *(uint32_t *)sn; - // bit hack to find if there's a 0 byte in there - if ((v - 0x01010101) & (~v) & 0x80808080UL) - break; - - sn += 4; - limit -= 4; - } - - // handle the last few characters to find actual size - while (limit && *sn) { - ++sn; - --limit; - } - - return (uint32_t)(sn - s); -} - -int __vsprintfcb(_STBSP_SPRINTFCB *callback, void *user, char *buf, char const *fmt, va_list va) -{ - static char hex[] = "0123456789abcdefxp"; - static char hexu[] = "0123456789ABCDEFXP"; - char *bf; - char const *f; - int tlen = 0; - - bf = buf; - f = fmt; - for (;;) { - int32_t fw, pr, tz; - uint32_t fl; - - // macros for the callback buffer stuff - #define stbsp__chk_cb_bufL(bytes) \ - { \ - int len = (int)(bf - buf); \ - if ((len + (bytes)) >= STB_SPRINTF_MIN) { \ - tlen += len; \ - if (0 == (bf = buf = callback(buf, user, len))) \ - goto done; \ - } \ - } - #define stbsp__chk_cb_buf(bytes) \ - { \ - if (callback) { \ - stbsp__chk_cb_bufL(bytes); \ - } \ - } - #define stbsp__flush_cb() \ - { \ - stbsp__chk_cb_bufL(STB_SPRINTF_MIN - 1); \ - } // flush if there is even one byte in the buffer - #define stbsp__cb_buf_clamp(cl, v) \ - cl = v; \ - if (callback) { \ - int lg = STB_SPRINTF_MIN - (int)(bf - buf); \ - if (cl > lg) \ - cl = lg; \ - } - - // fast copy everything up to the next % (or end of string) - for (;;) { - while (((uintptr_t)f) & 3) { - schk1: - if (f[0] == '%') - goto scandd; - schk2: - if (f[0] == 0) - goto endfmt; - stbsp__chk_cb_buf(1); - *bf++ = f[0]; - ++f; - } - for (;;) { - // Check if the next 4 bytes contain %(0x25) or end of string. - // Using the 'hasless' trick: - // https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord - uint32_t v, c; - v = *(uint32_t *)f; - c = (~v) & 0x80808080; - if (((v ^ 0x25252525) - 0x01010101) & c) - goto schk1; - if ((v - 0x01010101) & c) - goto schk2; - if (callback) - if ((STB_SPRINTF_MIN - (int)(bf - buf)) < 4) - goto schk1; - { - *(uint32_t *)bf = v; - } - bf += 4; - f += 4; - } - } - scandd: - - ++f; - - // ok, we have a percent, read the modifiers first - fw = 0; - pr = -1; - fl = 0; - tz = 0; - - // flags - for (;;) { - switch (f[0]) { - // if we have left justify - case '-': - fl |= STBSP__LEFTJUST; - ++f; - continue; - // if we have leading plus - case '+': - fl |= STBSP__LEADINGPLUS; - ++f; - continue; - // if we have leading space - case ' ': - fl |= STBSP__LEADINGSPACE; - ++f; - continue; - // if we have leading 0x - case '#': - fl |= STBSP__LEADING_0X; - ++f; - continue; - // if we have thousand commas - case '\'': - fl |= STBSP__TRIPLET_COMMA; - ++f; - continue; - // if we have kilo marker (none->kilo->kibi->jedec) - case '$': - if (fl & STBSP__METRIC_SUFFIX) { - if (fl & STBSP__METRIC_1024) { - fl |= STBSP__METRIC_JEDEC; - } else { - fl |= STBSP__METRIC_1024; - } - } else { - fl |= STBSP__METRIC_SUFFIX; - } - ++f; - continue; - // if we don't want space between metric suffix and number - case '_': - fl |= STBSP__METRIC_NOSPACE; - ++f; - continue; - // if we have leading zero - case '0': - fl |= STBSP__LEADINGZERO; - ++f; - goto flags_done; - default: goto flags_done; - } - } - flags_done: - - // get the field width - if (f[0] == '*') { - fw = va_arg(va, uint32_t); - ++f; - } else { - while ((f[0] >= '0') && (f[0] <= '9')) { - fw = fw * 10 + f[0] - '0'; - f++; - } - } - // get the precision - if (f[0] == '.') { - ++f; - if (f[0] == '*') { - pr = va_arg(va, uint32_t); - ++f; - } else { - pr = 0; - while ((f[0] >= '0') && (f[0] <= '9')) { - pr = pr * 10 + f[0] - '0'; - f++; - } - } - } - - // handle integer size overrides - switch (f[0]) { - // are we halfwidth? - case 'h': - fl |= STBSP__HALFWIDTH; - ++f; - if (f[0] == 'h') - ++f; // QUARTERWIDTH - break; - // are we 64-bit (unix style) - case 'l': - fl |= ((sizeof(long) == 8) ? STBSP__INTMAX : 0); - ++f; - if (f[0] == 'l') { - fl |= STBSP__INTMAX; - ++f; - } - break; - // are we 64-bit on intmax? (c99) - case 'j': - fl |= (sizeof(size_t) == 8) ? STBSP__INTMAX : 0; - ++f; - break; - // are we 64-bit on size_t or ptrdiff_t? (c99) - case 'z': - fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0; - ++f; - break; - case 't': - fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0; - ++f; - break; - // are we 64-bit (msft style) - case 'I': - if ((f[1] == '6') && (f[2] == '4')) { - fl |= STBSP__INTMAX; - f += 3; - } else if ((f[1] == '3') && (f[2] == '2')) { - f += 3; - } else { - fl |= ((sizeof(void *) == 8) ? STBSP__INTMAX : 0); - ++f; - } - break; - default: break; - } - - // handle each replacement - switch (f[0]) { - #define STBSP__NUMSZ 512 // big enough for e308 (with commas) or e-307 - char num[STBSP__NUMSZ]; - char lead[8]; - char tail[8]; - char *s; - char const *h; - uint32_t l, n, cs; - uint64_t n64; - double fv; - int32_t dp; - char const *sn; - - case 's': - // get the string - s = va_arg(va, char *); - if (s == 0) - s = (char *)"null"; - // get the length, limited to desired precision - // always limit to ~0u chars since our counts are 32b - l = _stbsp__strlen_limited(s, (pr >= 0) ? pr : ~0u); - lead[0] = 0; - tail[0] = 0; - pr = 0; - dp = 0; - cs = 0; - // copy the string in - goto scopy; - - case 'c': // char - // get the character - s = num + STBSP__NUMSZ - 1; - *s = (char)va_arg(va, int); - l = 1; - lead[0] = 0; - tail[0] = 0; - pr = 0; - dp = 0; - cs = 0; - goto scopy; - - case 'n': // weird write-bytes specifier - { - int *d = va_arg(va, int *); - *d = tlen + (int)(bf - buf); - } break; - - case 'A': // hex float - case 'a': // hex float - h = (f[0] == 'A') ? hexu : hex; - fv = va_arg(va, double); - if (pr == -1) - pr = 6; // default is 6 - // read the double into a string - if (_stbsp__real_to_parts((int64_t *)&n64, &dp, fv)) - fl |= STBSP__NEGATIVE; - - s = num + 64; - - _stbsp__lead_sign(fl, lead); - - if (dp == -1023) - dp = (n64) ? -1022 : 0; - else - n64 |= (((uint64_t)1) << 52); - n64 <<= (64 - 56); - if (pr < 15) - n64 += ((((uint64_t)8) << 56) >> (pr * 4)); -// add leading chars - lead[1 + lead[0]] = '0'; - lead[2 + lead[0]] = 'x'; - lead[0] += 2; - *s++ = h[(n64 >> 60) & 15]; - n64 <<= 4; - if (pr) - *s++ = _stbsp__period; - sn = s; - - // print the bits - n = pr; - if (n > 13) - n = 13; - if (pr > (int32_t)n) - tz = pr - n; - pr = 0; - while (n--) { - *s++ = h[(n64 >> 60) & 15]; - n64 <<= 4; - } - - // print the expo - tail[1] = h[17]; - if (dp < 0) { - tail[2] = '-'; - dp = -dp; - } else - tail[2] = '+'; - n = (dp >= 1000) ? 6 : ((dp >= 100) ? 5 : ((dp >= 10) ? 4 : 3)); - tail[0] = (char)n; - for (;;) { - tail[n] = '0' + dp % 10; - if (n <= 3) - break; - --n; - dp /= 10; - } - - dp = (int)(s - sn); - l = (int)(s - (num + 64)); - s = num + 64; - cs = 1 + (3 << 24); - goto scopy; - - case 'G': // float - case 'g': // float - h = (f[0] == 'G') ? hexu : hex; - fv = va_arg(va, double); - if (pr == -1) - pr = 6; - else if (pr == 0) - pr = 1; // default is 6 - // read the double into a string - if (_stbsp__real_to_str(&sn, &l, num, &dp, fv, (pr - 1) | 0x80000000)) - fl |= STBSP__NEGATIVE; - - // clamp the precision and delete extra zeros after clamp - n = pr; - if (l > (uint32_t)pr) - l = pr; - while ((l > 1) && (pr) && (sn[l - 1] == '0')) { - --pr; - --l; - } - - // should we use %e - if ((dp <= -4) || (dp > (int32_t)n)) { - if (pr > (int32_t)l) - pr = l - 1; - else if (pr) - --pr; // when using %e, there is one digit before the decimal - goto doexpfromg; - } - // this is the insane action to get the pr to match %g semantics for %f - if (dp > 0) { - pr = (dp < (int32_t)l) ? l - dp : 0; - } else { - pr = -dp + ((pr > (int32_t)l) ? (int32_t) l : pr); - } - goto dofloatfromg; - - case 'E': // float - case 'e': // float - h = (f[0] == 'E') ? hexu : hex; - fv = va_arg(va, double); - if (pr == -1) - pr = 6; // default is 6 - // read the double into a string - if (_stbsp__real_to_str(&sn, &l, num, &dp, fv, pr | 0x80000000)) - fl |= STBSP__NEGATIVE; - doexpfromg: - tail[0] = 0; - _stbsp__lead_sign(fl, lead); - if (dp == STBSP__SPECIAL) { - s = (char *)sn; - cs = 0; - pr = 0; - goto scopy; - } - s = num + 64; - // handle leading chars - *s++ = sn[0]; - - if (pr) - *s++ = _stbsp__period; - - // handle after decimal - if ((l - 1) > (uint32_t)pr) - l = pr + 1; - for (n = 1; n < l; n++) - *s++ = sn[n]; - // trailing zeros - tz = pr - (l - 1); - pr = 0; - // dump expo - tail[1] = h[0xe]; - dp -= 1; - if (dp < 0) { - tail[2] = '-'; - dp = -dp; - } else - tail[2] = '+'; - n = (dp >= 100) ? 5 : 4; - tail[0] = (char)n; - for (;;) { - tail[n] = '0' + dp % 10; - if (n <= 3) - break; - --n; - dp /= 10; - } - cs = 1 + (3 << 24); // how many tens - goto flt_lead; - - case 'f': // float - fv = va_arg(va, double); - doafloat: - // do kilos - if (fl & STBSP__METRIC_SUFFIX) { - double divisor; - divisor = 1000.0f; - if (fl & STBSP__METRIC_1024) - divisor = 1024.0; - while (fl < 0x4000000) { - if ((fv < divisor) && (fv > -divisor)) - break; - fv /= divisor; - fl += 0x1000000; - } - } - if (pr == -1) - pr = 6; // default is 6 - // read the double into a string - if (_stbsp__real_to_str(&sn, &l, num, &dp, fv, pr)) - fl |= STBSP__NEGATIVE; - dofloatfromg: - tail[0] = 0; - _stbsp__lead_sign(fl, lead); - if (dp == STBSP__SPECIAL) { - s = (char *)sn; - cs = 0; - pr = 0; - goto scopy; - } - s = num + 64; - - // handle the three decimal varieties - if (dp <= 0) { - int32_t i; - // handle 0.000*000xxxx - *s++ = '0'; - if (pr) - *s++ = _stbsp__period; - n = -dp; - if ((int32_t)n > pr) - n = pr; - i = n; - while (i) { - if ((((uintptr_t)s) & 3) == 0) - break; - *s++ = '0'; - --i; - } - while (i >= 4) { - *(uint32_t *)s = 0x30303030; - s += 4; - i -= 4; - } - while (i) { - *s++ = '0'; - --i; - } - if ((int32_t)(l + n) > pr) - l = pr - n; - i = l; - while (i) { - *s++ = *sn++; - --i; - } - tz = pr - (n + l); - cs = 1 + (3 << 24); // how many tens did we write (for commas below) - } else { - cs = (fl & STBSP__TRIPLET_COMMA) ? ((600 - (uint32_t)dp) % 3) : 0; - if ((uint32_t)dp >= l) { - // handle xxxx000*000.0 - n = 0; - for (;;) { - if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { - cs = 0; - *s++ = _stbsp__comma; - } else { - *s++ = sn[n]; - ++n; - if (n >= l) - break; - } - } - if (n < (uint32_t)dp) { - n = dp - n; - if ((fl & STBSP__TRIPLET_COMMA) == 0) { - while (n) { - if ((((uintptr_t)s) & 3) == 0) - break; - *s++ = '0'; - --n; - } - while (n >= 4) { - *(uint32_t *)s = 0x30303030; - s += 4; - n -= 4; - } - } - while (n) { - if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { - cs = 0; - *s++ = _stbsp__comma; - } else { - *s++ = '0'; - --n; - } - } - } - cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens - if (pr) { - *s++ = _stbsp__period; - tz = pr; - } - } else { - // handle xxxxx.xxxx000*000 - n = 0; - for (;;) { - if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { - cs = 0; - *s++ = _stbsp__comma; - } else { - *s++ = sn[n]; - ++n; - if (n >= (uint32_t)dp) - break; - } - } - cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens - if (pr) - *s++ = _stbsp__period; - if ((l - dp) > (uint32_t)pr) - l = pr + dp; - while (n < l) { - *s++ = sn[n]; - ++n; - } - tz = pr - (l - dp); - } - } - pr = 0; - - // handle k,m,g,t - if (fl & STBSP__METRIC_SUFFIX) { - char idx; - idx = 1; - if (fl & STBSP__METRIC_NOSPACE) - idx = 0; - tail[0] = idx; - tail[1] = ' '; - { - if (fl >> 24) { // SI kilo is 'k', JEDEC and SI kibits are 'K'. - if (fl & STBSP__METRIC_1024) - tail[idx + 1] = "_KMGT"[fl >> 24]; - else - tail[idx + 1] = "_kMGT"[fl >> 24]; - idx++; - // If printing kibits and not in jedec, add the 'i'. - if (fl & STBSP__METRIC_1024 && !(fl & STBSP__METRIC_JEDEC)) { - tail[idx + 1] = 'i'; - idx++; - } - tail[0] = idx; - } - } - }; - - flt_lead: - // get the length that we copied - l = (uint32_t)(s - (num + 64)); - s = num + 64; - goto scopy; - - case 'B': // upper binary - case 'b': // lower binary - h = (f[0] == 'B') ? hexu : hex; - lead[0] = 0; - if (fl & STBSP__LEADING_0X) { - lead[0] = 2; - lead[1] = '0'; - lead[2] = h[0xb]; - } - l = (8 << 4) | (1 << 8); - goto radixnum; - - case 'o': // octal - h = hexu; - lead[0] = 0; - if (fl & STBSP__LEADING_0X) { - lead[0] = 1; - lead[1] = '0'; - } - l = (3 << 4) | (3 << 8); - goto radixnum; - - case 'p': // pointer - fl |= (sizeof(void *) == 8) ? STBSP__INTMAX : 0; - pr = sizeof(void *) * 2; - fl &= ~STBSP__LEADINGZERO; // 'p' only prints the pointer with zeros - // fall through - to X - - case 'X': // upper hex - case 'x': // lower hex - h = (f[0] == 'X') ? hexu : hex; - l = (4 << 4) | (4 << 8); - lead[0] = 0; - if (fl & STBSP__LEADING_0X) { - lead[0] = 2; - lead[1] = '0'; - lead[2] = h[16]; - } - radixnum: - // get the number - if (fl & STBSP__INTMAX) - n64 = va_arg(va, uint64_t); - else - n64 = va_arg(va, uint32_t); - - s = num + STBSP__NUMSZ; - dp = 0; - // clear tail, and clear leading if value is zero - tail[0] = 0; - if (n64 == 0) { - lead[0] = 0; - if (pr == 0) { - l = 0; - cs = 0; - goto scopy; - } - } - // convert to string - for (;;) { - *--s = h[n64 & ((1 << (l >> 8)) - 1)]; - n64 >>= (l >> 8); - if (!((n64) || ((int32_t)((num + STBSP__NUMSZ) - s) < pr))) - break; - if (fl & STBSP__TRIPLET_COMMA) { - ++l; - if ((l & 15) == ((l >> 4) & 15)) { - l &= ~15; - *--s = _stbsp__comma; - } - } - }; - // get the tens and the comma pos - cs = (uint32_t)((num + STBSP__NUMSZ) - s) + ((((l >> 4) & 15)) << 24); - // get the length that we copied - l = (uint32_t)((num + STBSP__NUMSZ) - s); - // copy it - goto scopy; - - case 'u': // unsigned - case 'i': - case 'd': // integer - // get the integer and abs it - if (fl & STBSP__INTMAX) { - int64_t i64 = va_arg(va, int64_t); - n64 = (uint64_t)i64; - if ((f[0] != 'u') && (i64 < 0)) { - n64 = (uint64_t)-i64; - fl |= STBSP__NEGATIVE; - } - } else { - int32_t i = va_arg(va, int32_t); - n64 = (uint32_t)i; - if ((f[0] != 'u') && (i < 0)) { - n64 = (uint32_t)-i; - fl |= STBSP__NEGATIVE; - } - } - - if (fl & STBSP__METRIC_SUFFIX) { - if (n64 < 1024) - pr = 0; - else if (pr == -1) - pr = 1; - fv = (double)(int64_t)n64; - goto doafloat; - } - - // convert to string - s = num + STBSP__NUMSZ; - l = 0; - - for (;;) { - // do in 32-bit chunks (avoid lots of 64-bit divides even with constant denominators) - char *o = s - 8; - if (n64 >= 100000000) { - n = (uint32_t)(n64 % 100000000); - n64 /= 100000000; - } else { - n = (uint32_t)n64; - n64 = 0; - } - if ((fl & STBSP__TRIPLET_COMMA) == 0) { - do { - s -= 2; - *(uint16_t *)s = *(uint16_t *)&_stbsp__digitpair.pair[(n % 100) * 2]; - n /= 100; - } while (n); - } - while (n) { - if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) { - l = 0; - *--s = _stbsp__comma; - --o; - } else { - *--s = (char)(n % 10) + '0'; - n /= 10; - } - } - if (n64 == 0) { - if ((s[0] == '0') && (s != (num + STBSP__NUMSZ))) - ++s; - break; - } - while (s != o) - if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) { - l = 0; - *--s = _stbsp__comma; - --o; - } else { - *--s = '0'; - } - } - - tail[0] = 0; - _stbsp__lead_sign(fl, lead); - - // get the length that we copied - l = (uint32_t)((num + STBSP__NUMSZ) - s); - if (l == 0) { - *--s = '0'; - l = 1; - } - cs = l + (3 << 24); - if (pr < 0) - pr = 0; - - scopy: - // get fw=leading/trailing space, pr=leading zeros - if (pr < (int32_t)l) - pr = l; - n = pr + lead[0] + tail[0] + tz; - if (fw < (int32_t)n) - fw = n; - fw -= n; - pr -= l; - - // handle right justify and leading zeros - if ((fl & STBSP__LEFTJUST) == 0) { - if (fl & STBSP__LEADINGZERO) // if leading zeros, everything is in pr - { - pr = (fw > pr) ? fw : pr; - fw = 0; - } else { - fl &= ~STBSP__TRIPLET_COMMA; // if no leading zeros, then no commas - } - } - - // copy the spaces and/or zeros - if (fw + pr) { - int32_t i; - uint32_t c; - - // copy leading spaces (or when doing %8.4d stuff) - if ((fl & STBSP__LEFTJUST) == 0) - while (fw > 0) { - stbsp__cb_buf_clamp(i, fw); - fw -= i; - while (i) { - if ((((uintptr_t)bf) & 3) == 0) - break; - *bf++ = ' '; - --i; - } - while (i >= 4) { - *(uint32_t *)bf = 0x20202020; - bf += 4; - i -= 4; - } - while (i) { - *bf++ = ' '; - --i; - } - stbsp__chk_cb_buf(1); - } - - // copy leader - sn = lead + 1; - while (lead[0]) { - stbsp__cb_buf_clamp(i, lead[0]); - lead[0] -= (char)i; - while (i) { - *bf++ = *sn++; - --i; - } - stbsp__chk_cb_buf(1); - } - - // copy leading zeros - c = cs >> 24; - cs &= 0xffffff; - cs = (fl & STBSP__TRIPLET_COMMA) ? ((uint32_t)(c - ((pr + cs) % (c + 1)))) : 0; - while (pr > 0) { - stbsp__cb_buf_clamp(i, pr); - pr -= i; - if ((fl & STBSP__TRIPLET_COMMA) == 0) { - while (i) { - if ((((uintptr_t)bf) & 3) == 0) - break; - *bf++ = '0'; - --i; - } - while (i >= 4) { - *(uint32_t *)bf = 0x30303030; - bf += 4; - i -= 4; - } - } - while (i) { - if ((fl & STBSP__TRIPLET_COMMA) && (cs++ == c)) { - cs = 0; - *bf++ = _stbsp__comma; - } else - *bf++ = '0'; - --i; - } - stbsp__chk_cb_buf(1); - } - } - - // copy leader if there is still one - sn = lead + 1; - while (lead[0]) { - int32_t i; - stbsp__cb_buf_clamp(i, lead[0]); - lead[0] -= (char)i; - while (i) { - *bf++ = *sn++; - --i; - } - stbsp__chk_cb_buf(1); - } - - // copy the string - n = l; - while (n) { - int32_t i; - stbsp__cb_buf_clamp(i, n); - n -= i; - while (i >= 4) { - *(uint32_t volatile *)bf = *(uint32_t volatile *)s; - bf += 4; - s += 4; - i -= 4; - } - while (i) { - *bf++ = *s++; - --i; - } - stbsp__chk_cb_buf(1); - } - - // copy trailing zeros - while (tz) { - int32_t i; - stbsp__cb_buf_clamp(i, tz); - tz -= i; - while (i) { - if ((((uintptr_t)bf) & 3) == 0) - break; - *bf++ = '0'; - --i; - } - while (i >= 4) { - *(uint32_t *)bf = 0x30303030; - bf += 4; - i -= 4; - } - while (i) { - *bf++ = '0'; - --i; - } - stbsp__chk_cb_buf(1); - } - - // copy tail if there is one - sn = tail + 1; - while (tail[0]) { - int32_t i; - stbsp__cb_buf_clamp(i, tail[0]); - tail[0] -= (char)i; - while (i) { - *bf++ = *sn++; - --i; - } - stbsp__chk_cb_buf(1); - } - - // handle the left justify - if (fl & STBSP__LEFTJUST) - if (fw > 0) { - while (fw) { - int32_t i; - stbsp__cb_buf_clamp(i, fw); - fw -= i; - while (i) { - if ((((uintptr_t)bf) & 3) == 0) - break; - *bf++ = ' '; - --i; - } - while (i >= 4) { - *(uint32_t *)bf = 0x20202020; - bf += 4; - i -= 4; - } - while (i--) - *bf++ = ' '; - stbsp__chk_cb_buf(1); - } - } - break; - - default: // unknown, just copy code - s = num + STBSP__NUMSZ - 1; - *s = f[0]; - l = 1; - fw = fl = 0; - lead[0] = 0; - tail[0] = 0; - pr = 0; - dp = 0; - cs = 0; - goto scopy; - } - ++f; - } -endfmt: - - if (!callback) - *bf = 0; - else - stbsp__flush_cb(); - -done: - return tlen + (int)(bf - buf); -} - -// cleanup -#undef STBSP__LEFTJUST -#undef STBSP__LEADINGPLUS -#undef STBSP__LEADINGSPACE -#undef STBSP__LEADING_0X -#undef STBSP__LEADINGZERO -#undef STBSP__INTMAX -#undef STBSP__TRIPLET_COMMA -#undef STBSP__NEGATIVE -#undef STBSP__METRIC_SUFFIX -#undef STBSP__NUMSZ -#undef stbsp__chk_cb_bufL -#undef stbsp__chk_cb_buf -#undef stbsp__flush_cb -#undef stbsp__cb_buf_clamp - -// ============================================================================ -// wrapper functions - -int sprintf(char *buf, char const *fmt, ...) -{ - int result; - va_list va; - va_start(va, fmt); - result = __vsprintfcb(0, 0, buf, fmt, va); - va_end(va); - return result; -} - -typedef struct stbsp__context { - char *buf; - int count; - int length; - char tmp[STB_SPRINTF_MIN]; -} stbsp__context; - -static char *stbsp__clamp_callback(const char *buf, void *user, int len) -{ - stbsp__context *c = (stbsp__context *)user; - - c->length += len; - - if (len > c->count) - len = c->count; - - if (len) { - if (buf != c->buf) { - const char *s, *se; - char *d; - d = c->buf; - s = buf; - se = buf + len; - do { - *d++ = *s++; - } while (s < se); - } - c->buf += len; - c->count -= len; - } - - if (c->count <= 0) - return c->tmp; - return (c->count >= STB_SPRINTF_MIN) ? c->buf : c->tmp; // go direct into buffer if you can -} - -char * stbsp__count_clamp_callback( const char * buf, void * user, int len ) -{ - stbsp__context * c = (stbsp__context*)user; - (void) sizeof(buf); - - c->length += len; - return c->tmp; // go direct into buffer if you can -} - -int vsnprintf( char * buf, int count, char const * fmt, va_list va ) -{ - stbsp__context c; - if ( (count == 0) && !buf ) - { - c.length = 0; - - __vsprintfcb( stbsp__count_clamp_callback, &c, c.tmp, fmt, va ); - } - else - { - int l; - - c.buf = buf; - c.count = count; - c.length = 0; - - __vsprintfcb( stbsp__clamp_callback, &c, stbsp__clamp_callback(0,&c,0), fmt, va ); - - // zero-terminate - l = (int)( c.buf - buf ); - if ( l >= count ) // should never be greater, only equal (or less) than count - l = count - 1; - buf[l] = 0; - } - - return c.length; -} - -int snprintf(char *buf, int count, char const *fmt, ...) -{ - int result; - va_list va; - va_start(va, fmt); - - result = vsnprintf(buf, count, fmt, va); - va_end(va); - - return result; -} - -int vsprintf(char *buf, char const *fmt, va_list va) -{ - return __vsprintfcb(0, 0, buf, fmt, va); -} - -// ======================================================================= -// low level float utility functions - -// copies d to bits w/ strict aliasing (this compiles to nothing on /Ox) -#define STBSP__COPYFP(dest, src) { *(long *)&dest = *(long *)&src; } -/* - \ - { \ - int cn; \ - for (cn = 0; cn < 8; cn++) \ - ((char *)&dest)[cn] = ((char *)&src)[cn]; \ - } -*/ - -// get float info -int32_t _stbsp__real_to_parts(int64_t *bits, int32_t *expo, double value) -{ - double d; - int64_t b = 0; - - // load value and round at the frac_digits - d = value; - - STBSP__COPYFP(b, d); - - *bits = b & ((((uint64_t)1) << 52) - 1); - *expo = (int32_t)(((b >> 52) & 2047) - 1023); - - return (int32_t)((uint64_t) b >> 63); -} - -static double const stbsp__bot[23] = { - 1e+000, 1e+001, 1e+002, 1e+003, 1e+004, 1e+005, 1e+006, 1e+007, 1e+008, 1e+009, 1e+010, 1e+011, - 1e+012, 1e+013, 1e+014, 1e+015, 1e+016, 1e+017, 1e+018, 1e+019, 1e+020, 1e+021, 1e+022 -}; -static double const stbsp__negbot[22] = { - 1e-001, 1e-002, 1e-003, 1e-004, 1e-005, 1e-006, 1e-007, 1e-008, 1e-009, 1e-010, 1e-011, - 1e-012, 1e-013, 1e-014, 1e-015, 1e-016, 1e-017, 1e-018, 1e-019, 1e-020, 1e-021, 1e-022 -}; -static double const stbsp__negboterr[22] = { - -5.551115123125783e-018, -2.0816681711721684e-019, -2.0816681711721686e-020, -4.7921736023859299e-021, -8.1803053914031305e-022, 4.5251888174113741e-023, - 4.5251888174113739e-024, -2.0922560830128471e-025, -6.2281591457779853e-026, -3.6432197315497743e-027, 6.0503030718060191e-028, 2.0113352370744385e-029, - -3.0373745563400371e-030, 1.1806906454401013e-032, -7.7705399876661076e-032, 2.0902213275965398e-033, -7.1542424054621921e-034, -7.1542424054621926e-035, - 2.4754073164739869e-036, 5.4846728545790429e-037, 9.2462547772103625e-038, -4.8596774326570872e-039 -}; -static double const stbsp__top[13] = { - 1e+023, 1e+046, 1e+069, 1e+092, 1e+115, 1e+138, 1e+161, 1e+184, 1e+207, 1e+230, 1e+253, 1e+276, 1e+299 -}; -static double const stbsp__negtop[13] = { - 1e-023, 1e-046, 1e-069, 1e-092, 1e-115, 1e-138, 1e-161, 1e-184, 1e-207, 1e-230, 1e-253, 1e-276, 1e-299 -}; -static double const stbsp__toperr[13] = { - 8388608., - 6.8601809640529717e+028, - -7.253143638152921e+052, - -4.3377296974619174e+075, - -1.5559416129466825e+098, - -3.2841562489204913e+121, - -3.7745893248228135e+144, - -1.7356668416969134e+167, - -3.8893577551088374e+190, - -9.9566444326005119e+213, - 6.3641293062232429e+236, - -5.2069140800249813e+259, - -5.2504760255204387e+282 -}; -static double const stbsp__negtoperr[13] = { - 3.9565301985100693e-040, -2.299904345391321e-063, 3.6506201437945798e-086, 1.1875228833981544e-109, - -5.0644902316928607e-132, -6.7156837247865426e-155, -2.812077463003139e-178, -5.7778912386589953e-201, - 7.4997100559334532e-224, -4.6439668915134491e-247, -6.3691100762962136e-270, -9.436808465446358e-293, - 8.0970921678014997e-317 -}; - -static uint64_t const stbsp__powten[20] = { - 1, - 10, - 100, - 1000, - 10000, - 100000, - 1000000, - 10000000, - 100000000, - 1000000000, - 10000000000ULL, - 100000000000ULL, - 1000000000000ULL, - 10000000000000ULL, - 100000000000000ULL, - 1000000000000000ULL, - 10000000000000000ULL, - 100000000000000000ULL, - 1000000000000000000ULL, - 10000000000000000000ULL -}; -#define stbsp__tento19th (1000000000000000000ULL) - -#define stbsp__ddmulthi(oh, ol, xh, yh) \ - { \ - double ahi = 0, alo, bhi = 0, blo; \ - int64_t bt; \ - oh = xh * yh; \ - STBSP__COPYFP(bt, xh); \ - bt &= ((~(uint64_t)0) << 27); \ - STBSP__COPYFP(ahi, bt); \ - alo = xh - ahi; \ - STBSP__COPYFP(bt, yh); \ - bt &= ((~(uint64_t)0) << 27); \ - STBSP__COPYFP(bhi, bt); \ - blo = yh - bhi; \ - ol = ((ahi * bhi - oh) + ahi * blo + alo * bhi) + alo * blo; \ - } - -#define stbsp__ddtoS64(ob, xh, xl) \ - { \ - double ahi = 0, alo, vh, t; \ - ob = (int64_t)xh; \ - vh = (double)ob; \ - ahi = (xh - vh); \ - t = (ahi - xh); \ - alo = (xh - (ahi - t)) - (vh + t); \ - ob += (int64_t)(ahi + alo + xl); \ - } - -#define stbsp__ddrenorm(oh, ol) \ - { \ - double s; \ - s = oh + ol; \ - ol = ol - (s - oh); \ - oh = s; \ - } - -#define stbsp__ddmultlo(oh, ol, xh, xl, yh, yl) ol = ol + (xh * yl + xl * yh); - -#define stbsp__ddmultlos(oh, ol, xh, yl) ol = ol + (xh * yl); - -static void stbsp__raise_to_power10(double *ohi, double *olo, double d, int32_t power) // power can be -323 to +350 -{ - double ph, pl; - if ((power >= 0) && (power <= 22)) { - stbsp__ddmulthi(ph, pl, d, stbsp__bot[power]); - } else { - int32_t e, et, eb; - double p2h, p2l; - - e = power; - if (power < 0) - e = -e; - et = (e * 0x2c9) >> 14; /* %23 */ - if (et > 13) - et = 13; - eb = e - (et * 23); - - ph = d; - pl = 0.0; - if (power < 0) { - if (eb) { - --eb; - stbsp__ddmulthi(ph, pl, d, stbsp__negbot[eb]); - stbsp__ddmultlos(ph, pl, d, stbsp__negboterr[eb]); - } - if (et) { - stbsp__ddrenorm(ph, pl); - --et; - stbsp__ddmulthi(p2h, p2l, ph, stbsp__negtop[et]); - stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__negtop[et], stbsp__negtoperr[et]); - ph = p2h; - pl = p2l; - } - } else { - if (eb) { - e = eb; - if (eb > 22) - eb = 22; - e -= eb; - stbsp__ddmulthi(ph, pl, d, stbsp__bot[eb]); - if (e) { - stbsp__ddrenorm(ph, pl); - stbsp__ddmulthi(p2h, p2l, ph, stbsp__bot[e]); - stbsp__ddmultlos(p2h, p2l, stbsp__bot[e], pl); - ph = p2h; - pl = p2l; - } - } - if (et) { - stbsp__ddrenorm(ph, pl); - --et; - stbsp__ddmulthi(p2h, p2l, ph, stbsp__top[et]); - stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__top[et], stbsp__toperr[et]); - ph = p2h; - pl = p2l; - } - } - } - stbsp__ddrenorm(ph, pl); - *ohi = ph; - *olo = pl; -} - -// given a float value, returns the significant bits in bits, and the position of the -// decimal point in decimal_pos. +/-INF and NAN are specified by special values -// returned in the decimal_pos parameter. -// frac_digits is absolute normally, but if you want from first significant digits (got %g and %e), or in 0x80000000 -static int32_t _stbsp__real_to_str(char const **start, uint32_t *len, char *out, int32_t *decimal_pos, double value, uint32_t frac_digits) -{ - double d; - int64_t bits = 0; - int32_t expo, e, ng, tens; - - d = value; - STBSP__COPYFP(bits, d); - expo = (int32_t)((bits >> 52) & 2047); - ng = (int32_t)((uint64_t) bits >> 63); - if (ng) - d = -d; - - if (expo == 2047) // is nan or inf? - { - *start = (bits & ((((uint64_t)1) << 52) - 1)) ? "NaN" : "Inf"; - *decimal_pos = STBSP__SPECIAL; - *len = 3; - return ng; - } - - if (expo == 0) // is zero or denormal - { - if (((uint64_t) bits << 1) == 0) // do zero - { - *decimal_pos = 1; - *start = out; - out[0] = '0'; - *len = 1; - return ng; - } - // find the right expo for denormals - { - int64_t v = ((uint64_t)1) << 51; - while ((bits & v) == 0) { - --expo; - v >>= 1; - } - } - } - - // find the decimal exponent as well as the decimal bits of the value - { - double ph, pl; - - // log10 estimate - very specifically tweaked to hit or undershoot by no more than 1 of log10 of all expos 1..2046 - tens = expo - 1023; - tens = (tens < 0) ? ((tens * 617) / 2048) : (((tens * 1233) / 4096) + 1); - - // move the significant bits into position and stick them into an int - stbsp__raise_to_power10(&ph, &pl, d, 18 - tens); - - // get full as much precision from double-double as possible - stbsp__ddtoS64(bits, ph, pl); - - // check if we undershot - if (((uint64_t)bits) >= stbsp__tento19th) - ++tens; - } - - // now do the rounding in integer land - frac_digits = (frac_digits & 0x80000000) ? ((frac_digits & 0x7ffffff) + 1) : (tens + frac_digits); - if ((frac_digits < 24)) { - uint32_t dg = 1; - if ((uint64_t)bits >= stbsp__powten[9]) - dg = 10; - while ((uint64_t)bits >= stbsp__powten[dg]) { - ++dg; - if (dg == 20) - goto noround; - } - if (frac_digits < dg) { - uint64_t r; - // add 0.5 at the right position and round - e = dg - frac_digits; - if ((uint32_t)e >= 24) - goto noround; - r = stbsp__powten[e]; - bits = bits + (r / 2); - if ((uint64_t)bits >= stbsp__powten[dg]) - ++tens; - bits /= r; - } - noround:; - } - - // kill long trailing runs of zeros - if (bits) { - uint32_t n; - for (;;) { - if (bits <= 0xffffffff) - break; - if (bits % 1000) - goto donez; - bits /= 1000; - } - n = (uint32_t)bits; - while ((n % 1000) == 0) - n /= 1000; - bits = n; - donez:; - } - - // convert to string - out += 64; - e = 0; - for (;;) { - uint32_t n; - char *o = out - 8; - // do the conversion in chunks of U32s (avoid most 64-bit divides, worth it, constant denomiators be damned) - if (bits >= 100000000) { - n = (uint32_t)(bits % 100000000); - bits /= 100000000; - } else { - n = (uint32_t)bits; - bits = 0; - } - while (n) { - out -= 2; - *(uint16_t *)out = *(uint16_t *)&_stbsp__digitpair.pair[(n % 100) * 2]; - n /= 100; - e += 2; - } - if (bits == 0) { - if ((e) && (out[0] == '0')) { - ++out; - --e; - } - break; - } - while (out != o) { - *--out = '0'; - ++e; - } - } - - *decimal_pos = tens; - *start = out; - *len = e; - return ng; -} - -#undef stbsp__ddmulthi -#undef stbsp__ddrenorm -#undef stbsp__ddmultlo -#undef stbsp__ddmultlos -#undef STBSP__SPECIAL -#undef STBSP__COPYFP - -// these are the constants that gnu uses, but they don't really matter for us -#define _IOFBF 0 -#define _IOLBF 1 -#define _IONBF 2 -#define BUFSIZ 8192 - - -#define EOF (-1) -#define FILENAME_MAX 4096 -#define FOPEN_MAX 16 -typedef long fpos_t; -#define L_tmpnam 20 -#define SEEK_CUR 1 -#define SEEK_END 2 -#define SEEK_SET 0 -#define TMP_MAX 500 - -long lseek(int fd, long offset, int whence) { - return __syscall(8, fd, offset, whence, 0, 0, 0); -} - -size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { - size_t count; - if (nmemb > 0xffffffffffffffff / size) { - stream->err = 1; - return 0; - } - count = size * nmemb; - while (count > 0) { - long n = write(stream->fd, ptr, count); - if (n <= 0) break; - count -= n; - ptr = (char *)ptr + n; - } - if (count > 0) stream->err = 1; - return nmemb - count / size; -} - -size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { - size_t count; - long n = 1; - if (nmemb > 0xffffffffffffffff / size) { - stream->err = 1; - return 0; - } - if (size == 0 || nmemb == 0) return 0; - - count = size * nmemb; - - if (stream->has_ungetc) { - *(char *)ptr = stream->ungetc; - stream->has_ungetc = 0; - ptr = (char *)ptr + 1; - --count; - } - if (stream->eof) return 0; - - while (count > 0) { - n = read(stream->fd, ptr, count); - if (n <= 0) break; - count -= n; - ptr = (char *)ptr + n; - } - if (n == 0) stream->eof = 1; - if (n < 0) stream->err = 1; - return nmemb - count / size; -} - -static char *__fprintf_callback(const char *buf, void *user, int len) { - FILE *fp = user; - fwrite(buf, 1, len, fp); - return buf; -} - -int vfprintf(FILE *fp, const char *fmt, va_list args) { - char buf[STB_SPRINTF_MIN]; - return __vsprintfcb(__fprintf_callback, fp, buf, fmt, args); -} - -int fprintf(FILE *fp, const char *fmt, ...) { - va_list args; - int ret; - va_start(args, fmt); - ret = vfprintf(fp, fmt, args); - va_end(args); - return ret; -} - -int vprintf(const char *fmt, va_list args) { - return vfprintf(stdout, fmt, args); -} - -int printf(const char *fmt, ...) { - va_list args; - int ret; - va_start(args, fmt); - ret = vfprintf(stdout, fmt, args); - va_end(args); - return ret; -} - -#define O_RDONLY 0 -#define O_WRONLY 1 -#define O_RDWR 2 -#define O_CREAT 0100 -#define O_TRUNC 01000 -#define O_APPEND 02000 -#define O_DIRECTORY 0200000 -#define __O_TMPFILE 020000000 -#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) -int open(const char *path, int flags, int mode) { - return __syscall(2, path, flags, mode, 0, 0, 0); -} - -int close(int fd) { - return __syscall(3, fd, 0, 0, 0, 0, 0); -} - - -int _fopen_flags_from_mode(const char *mode) { - int flags; - if (mode[1] == '+' || (mode[1] && mode[2] == '+')) { - // open for updating - flags = O_RDWR; - switch (mode[0]) { - case 'r': break; - case 'w': flags |= O_TRUNC | O_CREAT; break; - case 'a': flags |= O_APPEND | O_CREAT; break; - default: return -1; - } - } else { - switch (mode[0]) { - case 'r': flags = O_RDONLY; break; - case 'w': flags = O_WRONLY | O_TRUNC | O_CREAT; break; - case 'a': flags = O_WRONLY | O_APPEND | O_CREAT; break; - default: return -1; - } - } - return flags; -} - -FILE *_FILE_from_fd(int fd) { - FILE *fp = malloc(sizeof(FILE)); - // NB: our malloc implementation returns zeroed memory - fp->fd = fd; - return fp; -} - -FILE *fopen(const char *filename, const char *mode) { - int flags = _fopen_flags_from_mode(mode); - if (flags < 0) return NULL; - int fd; - - fd = open(filename, flags, 0644); - if (fd < 0) return NULL; - return _FILE_from_fd(fd); -} - - -FILE *fdopen(int fd, const char *mode) { - // mode doesn't matter, hopefully - return _FILE_from_fd(fd); -} - -int fclose(FILE *stream) { - int ret = close(stream->fd); - free(stream); - return ret; -} - -int fflush(FILE *stream) { - // we don't buffer anything - return 0; -} - -FILE *freopen(const char *filename, const char *mode, FILE *stream) { - int flags = _fopen_flags_from_mode(mode); - close(stream->fd); - if (flags < 0) return NULL; - stream->eof = stream->err = 0; - stream->fd = open(filename, flags, 0644); - return stream; -} - -int unlink(const char *pathname) { - return __syscall(87, pathname, 0, 0, 0, 0, 0); -} - -int rmdir(const char *pathname) { - return __syscall(84, pathname, 0, 0, 0, 0, 0); -} - -int remove(const char *filename) { - return rmdir(filename) - ? unlink(filename) - : 0; -} - -int rename(const char *old, const char *new) { - return __syscall(82, old, new, 0, 0, 0, 0); -} - -char *tmpnam(char *s) { - struct timespec t = {0}; - do { - // NB: we can't use rand() here because - // "The implementation shall behave as if no library function calls the rand function." C89 § 4.10.2.1 - clock_gettime(CLOCK_MONOTONIC, &t); // use clock as a source of randomness - sprintf(s, "/tmp/C_%06u", t.tv_nsec % 1000000); - } while (access(s, F_OK) == 0); // if file exists, generate a new name - return s; -} - -FILE *tmpfile(void) { - int fd = open("/tmp", O_TMPFILE | O_RDWR, 0600); - if (fd < 0) return NULL; - return _FILE_from_fd(fd); -} - -int getc(FILE *stream) { - unsigned char c; - long n; - if (stream->eof) return EOF; - n = fread(&c, 1, 1, stream); - if (n != 1) return EOF; - return c; -} - -int fgetc(FILE *stream) { - return getc(stream); -} - -char *fgets(char *s, int n, FILE *stream) { - char *p = s, *end = p + (n-1); - - if (stream->eof) return NULL; - - while (p < end) { - size_t n = fread(p, 1, 1, stream); - if (n != 1) { - if (p == s) { - // end of file reached, and no characters were read - return NULL; - } - break; - } - if (*p == '\n') { - ++p; - break; - } - ++p; - } - *p = '\0'; - return s; -} - -int putc(int c, FILE *stream) { - size_t n = fwrite(&c, 1, 1, stream); - if (n == 1) return c; - return EOF; -} - -int fputc(int c, FILE *stream) { - return putc(c, stream); -} - -int fputs(const char *s, FILE *stream) { - size_t n = strlen(s); - if (fwrite(s, 1, n, stream) == n) - return n; - return EOF; -} - -int getchar(void) { - return getc(stdin); -} - -char *gets(char *s) { - char *p; - fgets(s, 1l<<20, stdin); - if (*s) { - p = s + strlen(s) - 1; - // remove newline - if (*p == '\n') - *p = '\0'; - } - return s; -} - -int putchar(int c) { - return putc(c, stdout); -} - -int puts(const char *s) { - fputs(s, stdout); - putchar('\n'); -} - -int ungetc(int c, FILE *stream) { - if (c == EOF || stream->has_ungetc) return EOF; - stream->has_ungetc = 1; - stream->ungetc = c; - stream->eof = 0; - return c; -} - - -int fgetpos(FILE *stream, fpos_t *pos) { - long off = lseek(stream->fd, 0, SEEK_CUR); - if (off < 0) { - errno = EIO; - return EIO; - } - *pos = off; - return 0; -} - -int fsetpos(FILE *stream, const fpos_t *pos) { - long off = lseek(stream->fd, *pos, SEEK_SET); - if (off < 0) { - errno = EIO; - return EIO; - } - stream->eof = 0; - return 0; -} - -int fseek(FILE *stream, long int offset, int whence) { - long off = lseek(stream->fd, offset, whence); - if (off < 0) { - return EIO; - } - stream->eof = 0; - return 0; -} - -long int ftell(FILE *stream) { - long off = lseek(stream->fd, 0, SEEK_CUR); - if (off < 0) { - errno = EIO; - return -1L; - } - return off; -} - -void rewind(FILE *stream) { - fseek(stream, 0, SEEK_SET); - stream->err = 0; -} - -void clearerr(FILE *stream) { - stream->err = 0; -} - -int feof(FILE *stream) { - return stream->eof; -} - -int ferror(FILE *stream) { - return stream->err; -} - -// we don't buffer anything -// we're allowed to do this: "The contents of the array at any time are indeterminate." C89 § 4.9.5.6 -void setbuf(FILE *stream, char *buf) { -} - -int setvbuf(FILE *stream, char *buf, int mode, size_t size) { - return 0; -} - -typedef int _VscanfNextChar(void *, long *); -typedef int _VscanfPeekChar(void *); -int _str_next_char(void *dat, long *pos) { - const char **s = dat; - int c = **s; - if (c == '\0') return c; - ++*pos; - ++*s; - return c; -} -int _file_next_char(void *dat, long *pos) { - int c = getc(dat); - if (c == EOF) return c; - ++*pos; - return c; -} -int _str_peek_char(void *dat) { - const char **s = dat; - return **s; -} -int _file_peek_char(void *dat) { - int c = getc(dat); - ungetc(c, dat); - return c; -} - -void _bad_scanf(void) { - fprintf(stderr, "bad scanf format.\n"); - abort(); -} - -char _parse_escape_sequence(char **p_str) { - char *str = *p_str; - if (*str == '\\') { - ++str; - switch (*str) { - case 'n': *p_str = str + 1; return '\n'; - case 'v': *p_str = str + 1; return '\v'; - case 't': *p_str = str + 1; return '\t'; - case 'a': *p_str = str + 1; return '\a'; - case 'f': *p_str = str + 1; return '\f'; - case 'r': *p_str = str + 1; return '\r'; - case 'b': *p_str = str + 1; return '\b'; - case 'x': - ++str; - return (char)strtoul(str, p_str, 16); - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7': { - int c = *str++ - '0'; - if (_isdigit_in_base(*str, 8)) c = (c << 3) + *str - '0', ++str; - if (_isdigit_in_base(*str, 8)) c = (c << 3) + *str - '0', ++str; - return c; - } break; - default: *p_str = str + 1; return *str; - } - } else { - *p_str += 1; - return *str; - } -} - -int _vscanf(_VscanfNextChar *__next_char, _VscanfPeekChar *__peek_char, int terminator, void *data, const char *fmt, va_list args) { - long pos = 0; // position in file/string (needed for %n) - int assignments = 0; - char number[128], *p_number; - unsigned char charset[256]; - int i; - - #define _next_char() (__next_char(data, &pos)) - #define _peek_char() (__peek_char(data)) - while (*fmt) { - if (*fmt == '%') { - int base = 10; - int assign = 1; - long field_width = LONG_MAX; - int modifier = 0; - char *end; - - ++fmt; - if (*fmt == '*') assign = 0, ++fmt; // assignment suppression - if (*fmt >= '0' && *fmt <= '9') - field_width = strtol(fmt, &fmt, 10); // field width - if (*fmt == 'l' || *fmt == 'L' || *fmt == 'h') - modifier = *fmt, ++fmt; - switch (*fmt) { - case 'd': { - while (isspace(_peek_char())) _next_char(); - // signed decimal integer - ++fmt; - if (field_width > 100) field_width = 100; // max number length - if (field_width == 0) goto vscanf_done; // number can't have size 0 - int c = _peek_char(); - p_number = number; - if (c == '-' || c == '+') { - if (field_width == 1) goto vscanf_done; - *p_number++ = _next_char(); - } - while ((p_number - number) < field_width && isdigit(_peek_char())) - *p_number++ = _next_char(); - *p_number = 0; - long value = strtol(number, &end, 10); - if (end == number) goto vscanf_done; // bad number - if (assign) { - switch (modifier) { - case 0: *va_arg(args, int*) = _clamp_long_to_int(value); break; - case 'h': *va_arg(args, short*) = _clamp_long_to_short(value); break; - case 'l': *va_arg(args, long*) = value; break; - default: _bad_scanf(); break; - } - ++assignments; - } - } break; - case 'i': { - while (isspace(_peek_char())) _next_char(); - // signed integer - long value = 0; - ++fmt; - if (field_width > 100) field_width = 100; // max number length - if (field_width == 0) goto vscanf_done; // number can't have size 0 - int c = _peek_char(); - p_number = number; - if (c == '-' || c == '+') { - if (field_width == 1) goto vscanf_done; - *p_number++ = _next_char(); - c = _peek_char(); - } - if (c == '0') { - *p_number++ = _next_char(); - if ((p_number - number) < field_width) { - c = _peek_char(); - if (c == 'x') { - if ((p_number - number) < field_width-1) - *p_number++ = _next_char(), base = 16; - else - goto emit_value; // e.g. 0x... width field width 2 - } else { - base = 8; - } - } else goto emit_value; - } - while ((p_number - number) < field_width && _isdigit_in_base(_peek_char(), base)) - *p_number++ = _next_char(); - *p_number = 0; - value = strtol(number, &end, 0); - if (end == number) goto vscanf_done; // bad number - emit_value: - if (assign) { - switch (modifier) { - case 0: *va_arg(args, int*) = _clamp_long_to_int(value); break; - case 'h': *va_arg(args, short*) = _clamp_long_to_short(value); break; - case 'l': *va_arg(args, long*) = value; break; - default: _bad_scanf(); break; - } - ++assignments; - } - } break; - case 'o': base = 8; goto vscanf_unsigned; - case 'u': goto vscanf_unsigned; - case 'p': modifier = 'l', base = 16; goto vscanf_unsigned; - case 'x': case 'X': base = 16; goto vscanf_unsigned; - vscanf_unsigned:{ - while (isspace(_peek_char())) _next_char(); - // unsigned integers - ++fmt; - if (field_width > 100) field_width = 100; // max number length - if (field_width == 0) goto vscanf_done; - int c = _peek_char(); - p_number = number; - if (c == '+') *p_number++ = _next_char(); - while ((p_number - number) < field_width && _isdigit_in_base(_peek_char(), base)) - *p_number++ = _next_char(); - *p_number = 0; - unsigned long value = strtoul(number, &end, base); - if (end == number) goto vscanf_done; // bad number - if (assign) { - switch (modifier) { - case 0: *va_arg(args, unsigned*) = _clamp_ulong_to_uint(value); break; - case 'h': *va_arg(args, unsigned short*) = _clamp_ulong_to_ushort(value); break; - case 'l': *va_arg(args, unsigned long*) = value; break; - default: _bad_scanf(); break; - } - ++assignments; - } - } break; - case 'e': - case 'f': - case 'g': - case 'E': - case 'G': { - while (isspace(_peek_char())) _next_char(); - // floats - ++fmt; - if (field_width > 100) field_width = 100; // max number length - if (field_width == 0) goto vscanf_done; - int c = _peek_char(); - p_number = number; - if (c == '-' || c == '+') { - if (field_width == 1) goto vscanf_done; - *p_number++ = _next_char(); - c = _peek_char(); - } - if (c != '.' && !isdigit(c)) - goto vscanf_done; - while ((p_number - number) < field_width && isdigit(_peek_char())) - *p_number++ = _next_char(); - if ((p_number - number) < field_width && _peek_char() == '.') { - *p_number++ = _next_char(); - while ((p_number - number) < field_width && isdigit(_peek_char())) - *p_number++ = _next_char(); - } - c = _peek_char(); - if ((p_number - number) < field_width && c == 'e' || c == 'E') { - *p_number++ = _next_char(); - c = _peek_char(); - if ((p_number - number) < field_width && c == '+') - *p_number++ = _next_char(); - else if ((p_number - number) < field_width && c == '-') - *p_number++ = _next_char(); - - while ((p_number - number) < field_width && isdigit(_peek_char())) - *p_number++ = _next_char(); - } - double value = strtod(number, &end); - if (end == number) goto vscanf_done; // bad number - if (assign) { - switch (modifier) { - case 0: *va_arg(args, float*) = value; break; - case 'l': case 'L': *va_arg(args, double*) = value; break; - default: _bad_scanf(); break; - } - - ++assignments; - } - } break; - case 's': { - while (isspace(_peek_char())) _next_char(); - // string of non-whitespace characters - ++fmt; - char *str = assign ? va_arg(args, char*) : NULL, *p = str; - for (i = 0; i < field_width && !isspace(_peek_char()); ++i) { - int c = _next_char(); - if (c == terminator) break; - if (p) *p++ = c; - } - if (i == 0) goto vscanf_done; // empty sequence - if (p) { - *p = 0; - ++assignments; - } - } break; - case '[': { - // string of characters in charset - int complement = 0; - ++fmt; - if (*fmt == '^') { - complement = 1; - ++fmt; - } - memset(charset, complement, sizeof charset); - do { // NB: this is a do-while loop and not a while loop, because []] matches strings of ]'s. - charset[(unsigned char)_parse_escape_sequence(&fmt)] = !complement; - } while (*fmt != ']'); - ++fmt; // skip ] - char *str = assign ? va_arg(args, char*) : NULL, *p = str; - for (i = 0; i < field_width && charset[(unsigned char)_peek_char()]; ++i) { - int c = _next_char(); - if (c == terminator) break; - if (p) *p++ = c; - } - if (i == 0) goto vscanf_done; // empty sequence - if (p) { - *p = 0; - ++assignments; - } - } break; - case 'c': { - // string of characters - ++fmt; - char *str = assign ? va_arg(args, char*) : NULL, *p = str; - if (field_width == LONG_MAX) field_width = 1; - for (i = 0; i < field_width; ++i) { - int c = _next_char(); - if (c == terminator) break; - if (p) *p++ = c; - } - if (i < field_width) goto vscanf_done; // end of file encountered - if (p) { - ++assignments; - } - } break; - case 'n': - ++fmt; - switch (modifier) { - case 0: *va_arg(args, int *) = pos; break; - case 'h': *va_arg(args, short *) = pos; break; - case 'l': *va_arg(args, long *) = pos; break; - default: _bad_scanf(); break; - } - break; - default: - _bad_scanf(); - break; - } - } else if (isspace(*fmt)) { - // skip spaces in input - ++fmt; - while (isspace(_peek_char())) _next_char(); - } else { - if (_peek_char() == *fmt) { - // format character matches input character - ++fmt; - _next_char(); - } else { - // format character doesn't match input character; stop parsing - break; - } - } - } - vscanf_done: - if (_peek_char() == terminator && assignments == 0) return EOF; - return assignments; - #undef _next_char - #undef _peek_char -} - -int fscanf(FILE *stream, const char *format, ...) { - va_list args; - va_start(args, format); - int ret = _vscanf(_file_next_char, _file_peek_char, EOF, stream, format, args); - va_end(args); - return ret; -} - -int sscanf(const char *s, const char *format, ...) { - va_list args; - va_start(args, format); - int ret = _vscanf(_str_next_char, _str_peek_char, 0, &s, format, args); - va_end(args); - return ret; -} - -int scanf(const char *format, ...) { - va_list args; - va_start(args, format); - int ret = _vscanf(_file_next_char, _file_peek_char, EOF, stdin, format, args); - va_end(args); - return ret; -} - - -void perror(const char *s) { - printf("%s: %s\n", s, strerror(errno)); -} - -#undef STB_SPRINTF_MIN - -#endif // _STDIO_H diff --git a/05/tcc-0.9.25/stdlib.h b/05/tcc-0.9.25/stdlib.h deleted file mode 100644 index c2f83eb..0000000 --- a/05/tcc-0.9.25/stdlib.h +++ /dev/null @@ -1,193 +0,0 @@ -#ifndef _STDLIB_H -#define _STDLIB_H - -#include - -#define EXIT_FAILURE (-1) -#define EXIT_SUCCESS 0 -#define RAND_MAX 2147483647 -// @NONSTANDARD: we don't define MB_CUR_MAX or any of the mbtowc functions - -typedef struct { - int quot; - int rem; -} div_t; - -typedef struct { - long quot; - long rem; -} ldiv_t; - -char *getenv(const char *name) { - int i, j; - for (i = 0; _envp[i]; ++i) { - char *key = _envp[i]; - for (j = 0; key[j] != '=' && name[j]; ++j) - if (name[j] != key[j]) - break; - if (key[j] == '=' && !name[j]) - return key + (j+1); - } - return NULL; -} - -double atof(const char *nptr) { - return strtod(nptr, NULL); -} - -int atoi(const char *nptr) { - return _clamp_long_to_int(strtol(nptr, NULL, 10)); -} - -long atol(const char *nptr) { - return strtol(nptr, NULL, 10); -} - -int rand(void) { - // https://en.wikipedia.org/wiki/Linear_congruential_generator - // we're using musl/newlib's constants - _rand_seed = 6364136223846793005 * _rand_seed + 1; - return _rand_seed >> 33; -} - -void srand(unsigned seed) { - _rand_seed = seed; -} - -void *calloc(size_t nmemb, size_t size) { - if (nmemb > 0xffffffffffffffff / size) - return NULL; - // NB: our malloc implementation returns zeroed memory - return malloc(nmemb * size); -} - -void *realloc(void *ptr, size_t size) { - if (!ptr) return malloc(size); - if (!size) { - free(ptr); - return NULL; - } - uint64_t *memory = (char *)ptr - 16; - uint64_t old_size = *memory; - uint64_t *new_memory = _mremap(memory, old_size, size, MREMAP_MAYMOVE); - if ((uint64_t)new_memory > 0xffffffffffff0000) return NULL; - *new_memory = size; - return (char *)new_memory + 16; -} - - -int atexit(void (*func)(void)) { - if (_n_exit_handlers >= 32) return -1; - _exit_handlers[_n_exit_handlers++] = func; - return 0; -} - -int system(const char *string) { - if (!string) return 1; - - int pid = fork(); - if (pid < 0) { - return -1; - } else if (pid == 0) { - // child - char *argv[] = { - "/bin/sh", - "-c", - 0, - 0 - }; - argv[2] = string; - execve("/bin/sh", argv, _envp); - // on success, execve does not return. - _Exit(-1); - } else { - // parent - int status = 0; - int ret = wait4(pid, &status, 0, NULL); - if (ret != pid) return -1; - if (_WIFSIGNALED(status)) return -1; - return _WEXITSTATUS(status); - } - -} - -void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { - size_t lo = 0; - size_t hi = nmemb; - while (lo < hi) { - size_t mid = (lo + hi) >> 1; - void *elem = (char *)base + mid * size; - int cmp = compar(key, elem); - if (cmp < 0) { - // key < elem - hi = mid; - } else if (cmp) { - // key > elem - lo = mid + 1; - } else { - return elem; - } - } - return NULL; -} - -void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { - // quicksort - if (nmemb < 2) return; - - void *temp = malloc(size); - void *mid = (char *)base + ((nmemb >> 1) * size); // choose middle element to speed up sorting an already-sorted array - size_t pivot_index = 0, i; - for (i = 0; i < nmemb; ++i) { - void *elem = (char *)base + i * size; - if (compar(elem, mid) < 0) - ++pivot_index; - } - void *pivot = (char *)base + pivot_index * size; - memcpy(temp, pivot, size); - memcpy(pivot, mid, size); - memcpy(mid, temp, size); - - char *l, *r = (char *)base + (nmemb-1) * size; - for (l = base; l < r;) { - if (compar(l, pivot) > 0) { - // swap l and r - memcpy(temp, l, size); - memcpy(l, r, size); - memcpy(r, temp, size); - r -= size; - } else { - // l is already in the right place - l += size; - } - } - - qsort(base, pivot_index, size, compar); - qsort((char *)pivot + size, nmemb - 1 - pivot_index, size, compar); - - free(temp); -} - -int abs(int x) { - return x >= 0 ? x : -x; -} - -long labs(long x) { - return x >= 0 ? x : -x; -} - -div_t div(int numer, int denom) { - div_t d; - d.quot = numer / denom; - d.rem = numer % denom; - return d; -} - -ldiv_t ldiv(long numer, long denom) { - ldiv_t d; - d.quot = numer / denom; - d.rem = numer % denom; - return d; -} - -#endif // _STDLIB_H diff --git a/05/tcc-0.9.25/string.h b/05/tcc-0.9.25/string.h deleted file mode 100644 index 4b73101..0000000 --- a/05/tcc-0.9.25/string.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef _STRING_H -#define _STRING_H - -#include - - -void *memmove(void *s1, const void *s2, size_t n) { - if (s1 < s2) return memcpy(s1, s2, n); // our memcpy does a forwards copy - // backwards copy - char *p = (char*)s1 + n, *q = (char*)s2 + n; - while (p > s1) - *--p = *--q; - return s1; -} - -char *strcpy(char *s1, const char *s2) { - char *p = s1 - 1, *q = s2 - 1; - while ((*++p = *++q)); - return s1; -} - -char *strncpy(char *s1, const char *s2, size_t n) { - char *p = s1 - 1, *q = s2 - 1; - size_t i; - for (i = 0; i < n; ++i) - if (!(*++p = *++q)) - break; - for (; i < n; ++i) - *++p = 0; - return s1; -} - -char *strcat(char *s1, const char *s2) { - return strcpy(s1 + strlen(s1), s2); -} - -char *strncat(char *s1, const char *s2, size_t n) { - // oddly, not equivalent to strncpy(s1 + strlen(s1), s2, n) - char *p = s1 + strlen(s1) - 1, *q = s2 - 1; - size_t i; - for (i = 0; i < n; ++i) - if (!(*++p = *++q)) - break; - *++p = 0; - return s1; -} - -int memcmp(const void *s1, const void *s2, size_t n) { - char *p = s1, *q = s2; - size_t i; - for (i = 0; i < n; ++i, ++p, ++q) { - if (*p > *q) - return 1; - if (*p < *q) - return -1; - } - return 0; -} - -int strcmp(const char *s1, const char *s2) { - char *p = s1, *q = s2; - for (; ; ++p, ++q) { - if (*p > *q) - return 1; - if (*p < *q) - return -1; - if (!*p) break; - } - return 0; -} - -int strcoll(const char *s1, const char *s2) { - // we only support the C locale - return strcmp(s1, s2); -} - -int strncmp(const char *s1, const char *s2, size_t n) { - char *p = s1, *q = s2; - size_t i; - for (i = 0; i < n; ++i, ++p, ++q) { - if (*p > *q) - return 1; - if (*p < *q) - return -1; - if (!*p) break; - } - return 0; -} - -size_t strxfrm(char *s1, const char *s2, size_t n) { - // we only support the C locale - size_t l = strlen(s2); - if (l >= n) return l; - strcpy(s1, s2); - return l; -} - -void *memchr(const void *s, int c, size_t n) { - char *p = s, *end = p + n; - while (p < end) { - if ((unsigned char)*p == c) - return p; - ++p; - } - return NULL; -} - -char *strchr(const char *s, int c) { - return memchr(s, c, strlen(s)+1); -} - - -size_t strcspn(const char *s1, const char *s2) { - const char *p, *q; - for (p = s1; *p; ++p) { - for (q = s2; *q; ++q) { - if (*p == *q) - goto ret; - } - } - ret: - return p - s1; -} - -char *strpbrk(const char *s1, const char *s2) { - const char *p, *q; - for (p = s1; *p; ++p) { - for (q = s2; *q; ++q) { - if (*p == *q) - return p; - } - } - return NULL; -} - -char *strrchr(const char *s, int c) { - char *p; - for (p = s + strlen(s); p >= s; --p) { - if (*p == c) - return p; - } - return NULL; -} - -size_t strspn(const char *s1, const char *s2) { - const char *p, *q; - for (p = s1; *p; ++p) { - for (q = s2; *q; ++q) { - if (*p == *q) break; - } - if (!*q) break; - } - return p - s1; -} - -char *strstr(const char *s1, const char *s2) { - char *p; - size_t l = strlen(s2); - for (p = s1; *p; ++p) { - if (memcmp(p, s2, l) == 0) - return p; - } - return NULL; -} - -char *strtok(char *s1, const char *s2) { - static char *str; - if (s1) str = s1; - if (!str) return NULL; - char *p = str + strspn(str, s2); - if (!*p) { - str = NULL; - return NULL; - } - char *q = strpbrk(p, s2); - if (q) { - *q = 0; - str = q + 1; - } else { - str = NULL; - } - return p; -} - -#endif // _STRING_H diff --git a/05/tcc-0.9.25/tcc-doc.html b/05/tcc-0.9.25/tcc-doc.html deleted file mode 100644 index e40532e..0000000 --- a/05/tcc-0.9.25/tcc-doc.html +++ /dev/null @@ -1,2241 +0,0 @@ - - - - - -Tiny C Compiler Reference Documentation - - - - - - - - - - - - - - - - - - - - - -
[Top][Contents][Index][ ? ]
-

Tiny C Compiler Reference Documentation

- -

This manual documents version of the Tiny C Compiler. -

- - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

1. 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 fast that even for big projects Makefiles 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 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 -(see section TinyCC Memory and Bound checks) while allowing all C pointers operations. TCC can do -these checks even if non patched libraries are used. -

-

With libtcc, you can use TCC as a backend for dynamic code -generation (see section The libtcc library). -

-

TCC mainly supports the i386 target on Linux and Windows. There are alpha -ports for the ARM (arm-tcc) and the TMS320C67xx targets -(c67-tcc). More information about the ARM port is available at -http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html. -

-

For usage on Windows, see also tcc-win32.txt. -

-
- - - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

2. Command line invocation

- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

2.1 Quick start

- -
 
usage: tcc [options] [infile1 infile2…] [‘-runinfile args…]
-
- -

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: -

-
-
tcc -run a.c
-

Compile ‘a.c’ and execute it directly -

-
-
tcc -run a.c arg1
-

Compile a.c and execute it directly. arg1 is given as first argument to -the main() of a.c. -

-
-
tcc a.c -run b.c arg1
-

Compile ‘a.c’ and ‘b.c’, link them together and execute them. arg1 is given -as first argument to the main() of the resulting program. -

-
-
tcc -o myprog a.c b.c
-

Compile ‘a.c’ and ‘b.c’, link them and generate the executable ‘myprog’. -

-
-
tcc -o myprog a.o b.o
-

link ‘a.o’ and ‘b.o’ together and generate the executable ‘myprog’. -

-
-
tcc -c a.c
-

Compile ‘a.c’ and generate object file ‘a.o’. -

-
-
tcc -c asmfile.S
-

Preprocess with C preprocess and assemble ‘asmfile.S’ and generate -object file ‘asmfile.o’. -

-
-
tcc -c asmfile.s
-

Assemble (but not preprocess) ‘asmfile.s’ and generate object file -‘asmfile.o’. -

-
-
tcc -r -o ab.o a.c b.c
-

Compile ‘a.c’ and ‘b.c’, link them together and generate the object file ‘ab.o’. -

-
-
- -

Scripting: -

-

TCC can be invoked from scripts, just as shell scripts. You just -need to add #!/usr/local/bin/tcc -run at the start of your C source: -

-
 
#!/usr/local/bin/tcc -run
-#include <stdio.h>
-
-int main() 
-{
-    printf("Hello World\n");
-    return 0;
-}
-
- -

TCC can read C source code from standard input when ‘-’ is used in -place of ‘infile’. Example: -

-
 
echo 'main(){puts("hello");}' | tcc -run -
-
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

2.2 Option summary

- -

General Options: -

-
-
-v
-

Display current TCC version, increase verbosity. -

-
-
-c
-

Generate an object file (‘-o’ option must also be given). -

-
-
-o outfile
-

Put object file, executable, or dll into output file ‘outfile’. -

-
-
-Bdir
-

Set the path where the tcc internal libraries can be found (default is -‘PREFIX/lib/tcc’). -

-
-
-bench
-

Output compilation statistics. -

-
-
-run source [args...]
-

Compile file source and run it with the command line arguments -args. In order to be able to give more than one argument to a -script, several TCC options can be given after the -‘-run’ option, separated by spaces. Example: -

-
 
tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
-
- -

In a script, it gives the following header: -

-
 
#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
-#include <stdlib.h>
-int main(int argc, char **argv)
-{
-    ...
-}
-
- -
-
- -

Preprocessor options: -

-
-
-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: ‘/usr/local/include’, ‘/usr/include’ -and ‘PREFIX/lib/tcc/include’. (‘PREFIX’ is usually -‘/usr’ or ‘/usr/local’). -

-
-
-Dsym[=val]
-

Define preprocessor symbol ‘sym’ to -val. If val is not present, its value is ‘1’. Function-like macros can -also be defined: ‘-DF(a)=a+1’ -

-
-
-Usym
-

Undefine preprocessor symbol ‘sym’. -

-
- -

Compilation flags: -

-

Note: each of the following warning options has a negative form beginning with -‘-fno-’. -

-
-
-funsigned-char
-

Let the char type be unsigned. -

-
-
-fsigned-char
-

Let the char type be signed. -

-
-
-fno-common
-

Do not generate common symbols for uninitialized data. -

-
-
-fleading-underscore
-

Add a leading underscore at the beginning of each C symbol. -

-
-
- -

Warning options: -

-
-
-w
-

Disable all warnings. -

-
-
- -

Note: each of the following warning options has a negative form beginning with -‘-Wno-’. -

-
-
-Wimplicit-function-declaration
-

Warn about implicit function declaration. -

-
-
-Wunsupported
-

Warn about unsupported GCC features that are ignored by TCC. -

-
-
-Wwrite-strings
-

Make string constants be of type const char * instead of char -*. -

-
-
-Werror
-

Abort compilation if warnings are issued. -

-
-
-Wall
-

Activate all warnings, except ‘-Werror’, ‘-Wunusupported’ and -‘-Wwrite-strings’. -

-
-
- -

Linker options: -

-
-
-Ldir
-

Specify an additional static library path for the ‘-l’ option. The -default library paths are ‘/usr/local/lib’, ‘/usr/lib’ and ‘/lib’. -

-
-
-lxxx
-

Link your program with dynamic library libxxx.so or static library -libxxx.a. The library is searched in the paths specified by the -‘-L’ option. -

-
-
-shared
-

Generate a shared library instead of an executable (‘-o’ option -must also be given). -

-
-
-static
-

Generate a statically linked executable (default is a shared linked -executable) (‘-o’ option must also be given). -

-
-
-rdynamic
-

Export global symbols to the dynamic linker. It is useful when a library -opened with dlopen() needs to access executable symbols. -

-
-
-r
-

Generate an object file combining all input files (‘-o’ option must -also be given). -

-
-
-Wl,-Ttext,address
-

Set the start of the .text section to address. -

-
-
-Wl,--oformat,fmt
-

Use fmt as output format. The supported output formats are: -

-
elf32-i386
-

ELF output format (default) -

-
binary
-

Binary image (only for executable output) -

-
coff
-

COFF output format (only for executable output for TMS320C67xx target) -

-
- -
-
- -

Debugger options: -

-
-
-g
-

Generate run time debug information so that you get clear run time -error messages: test.c:68: in function 'test5()': dereferencing -invalid pointer instead of the laconic Segmentation -fault. -

-
-
-b
-

Generate additional support code to check -memory allocations and array/pointer bounds. ‘-g’ is implied. Note -that the generated code is slower and bigger in this case. -

-
-
-bt N
-

Display N callers in stack traces. This is useful with ‘-g’ or -‘-b’. -

-
-
- -

Note: GCC options ‘-Ox’, ‘-fx’ and ‘-mx’ are -ignored. -

- -
- - - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

3. C language support

- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

3.1 ANSI C

- -

TCC implements all the ANSI C standard, including structure bit fields -and floating point numbers (long double, double, and -float fully supported). -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

3.2 ISOC99 extensions

- -

TCC implements many features of the new C standard: ISO C99. Currently -missing items are: complex and imaginary numbers and variable length -arrays. -

-

Currently implemented ISOC99 features: -

-
    -
  • 64 bit long long types are fully supported. - -
  • The boolean type _Bool is supported. - -
  • __func__ is a string variable containing the current -function name. - -
  • Variadic macros: __VA_ARGS__ can be used for - function-like macros: -
     
        #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__)
    -
    - -

    dprintf can then be used with a variable number of parameters. -

    -
  • Declarations can appear anywhere in a block (as in C++). - -
  • Array and struct/union elements can be initialized in any order by - using designators: -
     
        struct { int x, y; } st[10] = { [0].x = 1, [0].y = 2 };
    -
    -    int tab[10] = { 1, 2, [5] = 5, [9] = 9};
    -
    - -
  • Compound initializers are supported: -
     
        int *p = (int []){ 1, 2, 3 };
    -
    -

    to initialize a pointer pointing to an initialized array. The same -works for structures and strings. -

    -
  • Hexadecimal floating point constants are supported: -
     
              double d = 0x1234p10;
    -
    - -

    is the same as writing -

     
              double d = 4771840.0;
    -
    - -
  • inline keyword is ignored. - -
  • restrict keyword is ignored. -
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

3.3 GNU C extensions

- -

TCC implements some GNU C extensions: -

-
    -
  • array designators can be used without '=': -
     
        int a[10] = { [0] 1, [5] 2, 3, 4 };
    -
    - -
  • Structure field designators can be a label: -
     
        struct { int x, y; } st = { x: 1, y: 1};
    -
    -

    instead of -

     
        struct { int x, y; } st = { .x = 1, .y = 1};
    -
    - -
  • \e is ASCII character 27. - -
  • case ranges : ranges can be used in cases: -
     
        switch(a) {
    -    case 1 … 9:
    -          printf("range 1 to 9\n");
    -          break;
    -    default:
    -          printf("unexpected\n");
    -          break;
    -    }
    -
    - - - - - - - - - - -
  • The keyword __attribute__ is handled to specify variable or -function attributes. The following attributes are supported: - -
      -
    • aligned(n): align a variable or a structure field to n bytes -(must be a power of two). - -
    • packed: force alignment of a variable or a structure field to - 1. - -
    • section(name): generate function or data in assembly section -name (name is a string containing the section name) instead of the default -section. - -
    • unused: specify that the variable or the function is unused. - -
    • cdecl: use standard C calling convention (default). - -
    • stdcall: use Pascal-like calling convention. - -
    • regparm(n): use fast i386 calling convention. n must be -between 1 and 3. The first n function parameters are respectively put in -registers %eax, %edx and %ecx. - -
    • dllexport: export function from dll/executable (win32 only) - -
    - -

    Here are some examples: -

     
        int a __attribute__ ((aligned(8), section(".mysection")));
    -
    - -

    align variable a to 8 bytes and put it in section .mysection. -

    -
     
        int my_add(int a, int b) __attribute__ ((section(".mycodesection"))) 
    -    {
    -        return a + b;
    -    }
    -
    - -

    generate function my_add in section .mycodesection. -

    -
  • GNU style variadic macros: -
     
        #define dprintf(fmt, args…) printf(fmt, ## args)
    -
    -    dprintf("no arg\n");
    -    dprintf("one arg %d\n", 1);
    -
    - -
  • __FUNCTION__ is interpreted as C99 __func__ -(so it has not exactly the same semantics as string literal GNUC -where it is a string literal). - -
  • The __alignof__ keyword can be used as sizeof -to get the alignment of a type or an expression. - -
  • The typeof(x) returns the type of x. -x is an expression or a type. - -
  • Computed gotos: &&label returns a pointer of type -void * on the goto label label. goto *expr can be -used to jump on the pointer resulting from expr. - -
  • Inline assembly with asm instruction: - - - -
     
    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);
    -}
    -
    - - -

    TCC includes its own x86 inline assembler with a gas-like (GNU -assembler) syntax. No intermediate files are generated. GCC 3.x named -operands are supported. -

    -
  • __builtin_types_compatible_p() and __builtin_constant_p() -are supported. - -
  • #pragma pack is supported for win32 compatibility. - -
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

3.4 TinyCC extensions

- -
    -
  • __TINYC__ is a predefined macro to 1 to -indicate that you use TCC. - -
  • #! at the start of a line is ignored to allow scripting. - -
  • Binary digits can be entered (0b101 instead of -5). - -
  • __BOUNDS_CHECKING_ON is defined if bound checking is activated. - -
- -
- - - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

4. TinyCC Assembler

- -

Since version 0.9.16, TinyCC integrates its own assembler. TinyCC -assembler supports a gas-like syntax (GNU assembler). You can -desactivate 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 ‘.S’ (C -preprocessed assembler) and ‘.s’ extensions. It is also used to -handle the GNU inline assembler with the asm keyword. -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

4.1 Syntax

- -

TinyCC Assembler supports most of the gas syntax. The tokens are the -same as C. -

-
    -
  • C and C++ comments are supported. - -
  • Identifiers are the same as C, so you cannot use '.' or '$'. - -
  • Only 32 bit integer numbers are supported. - -
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

4.2 Expressions

- -
    -
  • Integers in decimal, octal and hexa are supported. - -
  • Unary operators: +, -, ~. - -
  • Binary operators in decreasing priority order: - -
      -
    1. *, /, % -
    2. &, |, ^ -
    3. +, - -
    - -
  • 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. - -
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

4.3 Labels

- -
    -
  • All labels are considered as local, except undefined ones. - -
  • Numeric labels can be used as local gas-like labels. -They can be defined several times in the same source. Use 'b' -(backward) or 'f' (forward) as suffix to reference them: - -
     
     1:
    -      jmp 1b /* jump to '1' label before */
    -      jmp 1f /* jump to '1' label after */
    - 1:
    -
    - -
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

4.4 Directives

- -

All directives are preceeded by a '.'. The following directives are -supported: -

-
    -
  • .align n[,value] -
  • .skip n[,value] -
  • .space n[,value] -
  • .byte value1[,...] -
  • .word value1[,...] -
  • .short value1[,...] -
  • .int value1[,...] -
  • .long value1[,...] -
  • .quad immediate_value1[,...] -
  • .globl symbol -
  • .global symbol -
  • .section section -
  • .text -
  • .data -
  • .bss -
  • .fill repeat[,size[,value]] -
  • .org n -
  • .previous -
  • .string string[,...] -
  • .asciz string[,...] -
  • .ascii string[,...] -
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

4.5 X86 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. -

-
- - - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

5. TinyCC Linker

- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

5.1 ELF file generation

- -

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 (‘--start-group’ and ‘--end-group’) are supported. -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

5.2 ELF file loader

- -

TCC can load ELF object files, archives (.a files) and dynamic -libraries (.so). -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

5.3 PE-i386 file generation

- -

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. -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

5.4 GNU Linker Scripts

- -

Because on many Linux systems some dynamic libraries (such as -‘/usr/lib/libc.so’) are in fact GNU ld link scripts (horrible!), -the TCC linker also supports a subset of GNU ld scripts. -

-

The GROUP and FILE commands are supported. OUTPUT_FORMAT -and TARGET are ignored. -

-

Example from ‘/usr/lib/libc.so’: -

 
/* 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 )
-
- -
- - - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

6. TinyCC Memory and Bound checks

- -

This feature is activated with the ‘-b’ (see section Command line invocation). -

-

Note that pointer size is unchanged and that code generated -with bound checks is 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 -http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html. -

-

Here are some examples of caught errors: -

-
-
Invalid range with standard string function:
-
 
{
-    char tab[10];
-    memset(tab, 0, 11);
-}
-
- -
-
Out of bounds-error in global or local arrays:
-
 
{
-    int tab[10];
-    for(i=0;i<11;i++) {
-        sum += tab[i];
-    }
-}
-
- -
-
Out of bounds-error in malloc'ed data:
-
 
{
-    int *tab;
-    tab = malloc(20 * sizeof(int));
-    for(i=0;i<21;i++) {
-        sum += tab4[i];
-    }
-    free(tab);
-}
-
- -
-
Access of freed memory:
-
 
{
-    int *tab;
-    tab = malloc(20 * sizeof(int));
-    free(tab);
-    for(i=0;i<20;i++) {
-        sum += tab4[i];
-    }
-}
-
- -
-
Double free:
-
 
{
-    int *tab;
-    tab = malloc(20 * sizeof(int));
-    free(tab);
-    free(tab);
-}
-
- -
-
- -
- - - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

7. The libtcc library

- -

The libtcc library enables you to use TCC as a backend for -dynamic code generation. -

-

Read the ‘libtcc.h’ to have an overview of the API. Read -‘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 libtcc. Then you can access to any global -symbol (function or variable) defined. -

-
- - - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8. 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. -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.1 File reading

- -

The BufferedFile structure contains the context needed to read a -file, including the current line number. tcc_open() opens a new -file and tcc_close() closes it. inp() returns the next -character. -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.2 Lexer

- -

next() reads the next token in the current -file. next_nomacro() reads the next token without macro -expansion. -

-

tok contains the current token (see TOK_xxx) -constants. Identifiers and keywords are also keywords. tokc -contains additional infos about the token (for example a constant value -if number or string token). -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.3 Parser

- -

The parser is hardcoded (yacc is not necessary). It does only one pass, -except: -

-
    -
  • For initialized arrays with unknown size, a first pass -is done to count the number of elements. - -
  • For architectures where arguments are evaluated in -reverse order, a first pass is done to reverse the argument order. - -
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.4 Types

- -

The types are stored in a single 'int' variable. It was choosen in the -first stages of development when tcc was much simpler. Now, it may not -be the best solution. -

-
 
#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_BITFIELD   0x0040  /* bitfield modifier */
-
-#define VT_STRUCT_SHIFT 16   /* structure/enum name shift (16 bits left) */
-
- -

When a reference to another type is needed (for pointers, functions and -structures), the 32 - VT_STRUCT_SHIFT high order bits are used to -store an identifier reference. -

-

The VT_UNSIGNED flag can be set for chars, shorts, ints and long -longs. -

-

Arrays are considered as pointers VT_PTR with the flag -VT_ARRAY set. -

-

The 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. -

-

VT_LONG is never used except during parsing. -

-

During parsing, the storage of an object is also stored in the type -integer: -

-
 
#define VT_EXTERN  0x00000080  /* extern definition */
-#define VT_STATIC  0x00000100  /* static variable */
-#define VT_TYPEDEF 0x00000200  /* typedef definition */
-
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.5 Symbols

- -

All symbols are stored in hashed symbol stacks. Each symbol stack -contains Sym structures. -

-

Sym.v contains the symbol name (remember -an idenfier is also a token, so a string is never necessary to store -it). Sym.t gives the type of the symbol. Sym.r is usually -the register in which the corresponding variable is stored. Sym.c is -usually a constant associated to the symbol. -

-

Four main symbol stacks are defined: -

-
-
define_stack
-

for the macros (#defines). -

-
-
global_stack
-

for the global variables, functions and types. -

-
-
local_stack
-

for the local variables, functions and types. -

-
-
global_label_stack
-

for the local labels (for goto). -

-
-
label_stack
-

for GCC block local labels (see the __label__ keyword). -

-
-
- -

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. -

-

sym_pop(st,b) pops symbols from the symbol stack st until -the symbol b is on the top of stack. If b is NULL, the stack -is emptied. -

-

sym_find(v) return the symbol associated to the identifier -v. The local stack is searched first from top to bottom, then the -global stack. -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.6 Sections

- -

The generated code and datas are written in sections. The structure -Section contains all the necessary information for a given -section. new_section() creates a new section. ELF file semantics -is assumed for each section. -

-

The following sections are predefined: -

-
-
text_section
-

is the section containing the generated code. ind contains the -current position in the code section. -

-
-
data_section
-

contains initialized data -

-
-
bss_section
-

contains uninitialized data -

-
-
bounds_section
-
lbounds_section
-

are used when bound checking is activated -

-
-
stab_section
-
stabstr_section
-

are used when debugging is actived to store debug information -

-
-
symtab_section
-
strtab_section
-

contain the exported symbols (currently only used for debugging). -

-
-
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.7 Code generation

- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.7.1 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 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. -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.7.2 The value stack

- -

When an expression is parsed, its value is pushed on the value stack -(vstack). The top of the value stack is vtop. Each value -stack entry is the structure SValue. -

-

SValue.t is the type. SValue.r indicates how the value is -currently stored in the generated code. It is usually a CPU register -index (REG_xxx constants), but additional values and flags are -defined: -

-
 
#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)
-
- -
-
VT_CONST
-

indicates that the value is a constant. It is stored in the union -SValue.c, depending on its type. -

-
-
VT_LOCAL
-

indicates a local variable pointer at offset SValue.c.i in the -stack. -

-
-
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 SValue.c.i. -

-

If any code is generated which destroys the CPU flags, this value MUST be -put in a normal register. -

-
-
VT_JMP
-
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 || and && 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. -

-
-
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 VT_LVAL is very important if you want to -understand how TCC works. -

-
-
VT_LVAL_BYTE
-
VT_LVAL_SHORT
-
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. -

-
-
VT_LLOCAL
-

is a saved lvalue on the stack. VT_LLOCAL should be eliminated -ASAP because its semantics are rather complicated. -

-
-
VT_MUSTCAST
-

indicates that a cast to the value type must be performed if the value -is used (lazy casting). -

-
-
VT_SYM
-

indicates that the symbol SValue.sym must be added to the constant. -

-
-
VT_MUSTBOUND
-
VT_BOUNDED
-

are only used for optional bound checking. -

-
-
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.7.3 Manipulating the value stack

- -

vsetc() and vset() pushes a new value on the value -stack. If the previous vtop was stored in a very unsafe place(for -example in the CPU flags), then some code is generated to put the -previous vtop in a safe storage. -

-

vpop() pops vtop. In some cases, it also generates cleanup -code (for example if stacked floating point registers are used as on -x86). -

-

The gv(rc) function generates code to evaluate vtop (the -top value of the stack) into registers. rc selects in which -register class the value should be put. gv() is the most -important function of the code generator. -

-

gv2() is the same as gv() but for the top two stack -entries. -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.7.4 CPU dependent code generation

-

See the ‘i386-gen.c’ file to have an example. -

-
-
load()
-

must generate the code needed to load a stack value into a register. -

-
-
store()
-

must generate the code needed to store a register into a stack value -lvalue. -

-
-
gfunc_start()
-
gfunc_param()
-
gfunc_call()
-

should generate a function call -

-
-
gfunc_prolog()
-
gfunc_epilog()
-

should generate a function prolog/epilog. -

-
-
gen_opi(op)
-

must generate the binary integer operation op on the two top -entries of the stack which are guaranted to contain integer types. -

-

The result value should be put on the stack. -

-
-
gen_opf(op)
-

same as gen_opi() for floating point operations. The two top -entries of the stack are guaranted to contain floating point values of -same types. -

-
-
gen_cvt_itof()
-

integer to floating point conversion. -

-
-
gen_cvt_ftoi()
-

floating point to integer conversion. -

-
-
gen_cvt_ftof()
-

floating point to floating point of different size conversion. -

-
-
gen_bounded_ptr_add()
-
gen_bounded_ptr_deref()
-

are only used for bounds checking. -

-
-
- -
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

8.8 Optimizations done

-

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. -

-
- - - - - - - - - - - - - - - - -
[ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
-

Concept Index

-
Jump to:   _ -   -
-A -   -B -   -C -   -D -   -E -   -F -   -G -   -I -   -J -   -L -   -M -   -O -   -P -   -Q -   -R -   -S -   -T -   -U -   -V -   -W -   -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Index Entry Section

_
__asm__3.3 GNU C extensions

A
align directive4.4 Directives
aligned attribute3.3 GNU C extensions
ascii directive4.4 Directives
asciz directive4.4 Directives
assembler4.5 X86 Assembler
assembler directives4.4 Directives
assembly, inline3.3 GNU C extensions

B
bound checks6. TinyCC Memory and Bound checks
bss directive4.4 Directives
byte directive4.4 Directives

C
caching processor flags8.8 Optimizations done
cdecl attribute3.3 GNU C extensions
code generation8.7 Code generation
comparison operators8.8 Optimizations done
constant propagation8.8 Optimizations done
CPU dependent8.7.4 CPU dependent code generation

D
data directive4.4 Directives
directives, assembler4.4 Directives
dllexport attribute3.3 GNU C extensions

E
ELF5.1 ELF file generation

F
FILE, linker command5.4 GNU Linker Scripts
fill directive4.4 Directives
flags, caching8.8 Optimizations done

G
gas3.3 GNU C extensions
global directive4.4 Directives
globl directive4.4 Directives
GROUP, linker command5.4 GNU Linker Scripts

I
inline assembly3.3 GNU C extensions
int directive4.4 Directives

J
jump optimization8.8 Optimizations done

L
linker5. TinyCC Linker
linker scripts5.4 GNU Linker Scripts
long directive4.4 Directives

M
memory checks6. TinyCC Memory and Bound checks

O
optimizations8.8 Optimizations done
org directive4.4 Directives
OUTPUT_FORMAT, linker command5.4 GNU Linker Scripts

P
packed attribute3.3 GNU C extensions
PE-i3865.3 PE-i386 file generation
previous directive4.4 Directives

Q
quad directive4.4 Directives

R
regparm attribute3.3 GNU C extensions

S
scripts, linker5.4 GNU Linker Scripts
section attribute3.3 GNU C extensions
section directive4.4 Directives
short directive4.4 Directives
skip directive4.4 Directives
space directive4.4 Directives
stdcall attribute3.3 GNU C extensions
strength reduction8.8 Optimizations done
string directive4.4 Directives

T
TARGET, linker command5.4 GNU Linker Scripts
text directive4.4 Directives

U
unused attribute3.3 GNU C extensions

V
value stack8.7.3 Manipulating the value stack
value stack, introduction8.7.2 The value stack

W
word directive4.4 Directives

-
Jump to:   _ -   -
-A -   -B -   -C -   -D -   -E -   -F -   -G -   -I -   -J -   -L -   -M -   -O -   -P -   -Q -   -R -   -S -   -T -   -U -   -V -   -W -   -
- -
- - - - - - -
[Top][Contents][Index][ ? ]
-

Table of Contents

- -
- - - - - - -
[Top][Contents][Index][ ? ]
-

About This Document

-

- This document was generated by gr on May, 18 2009 using texi2html 1.78. -

-

- The buttons in the navigation panels have the following meaning: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Button Name Go to From 1.2.3 go to
[ < ] BackPrevious section in reading order1.2.2
[ > ] ForwardNext section in reading order1.2.4
[ << ] FastBackBeginning of this chapter or previous chapter1
[ Up ] UpUp section1.2
[ >> ] FastForwardNext chapter2
[Top] TopCover (top) of document  
[Contents] ContentsTable of contents  
[Index] IndexIndex  
[ ? ] AboutAbout (help)  
- -

- where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure: -

- -
    -
  • 1. Section One -
      -
    • 1.1 Subsection One-One -
        -
      • ...
      • -
      -
    • -
    • 1.2 Subsection One-Two -
        -
      • 1.2.1 Subsubsection One-Two-One
      • -
      • 1.2.2 Subsubsection One-Two-Two
      • -
      • 1.2.3 Subsubsection One-Two-Three     - <== Current Position
      • -
      • 1.2.4 Subsubsection One-Two-Four
      • -
      -
    • -
    • 1.3 Subsection One-Three -
        -
      • ...
      • -
      -
    • -
    • 1.4 Subsection One-Four
    • -
    -
  • -
- -
-

- - This document was generated by gr on May, 18 2009 using texi2html 1.78. - -
- -

- - diff --git a/05/tcc-0.9.25/tcc-doc.texi b/05/tcc-0.9.25/tcc-doc.texi deleted file mode 100644 index 7cc61bb..0000000 --- a/05/tcc-0.9.25/tcc-doc.texi +++ /dev/null @@ -1,1227 +0,0 @@ -\input texinfo @c -*- texinfo -*- -@c %**start of header -@setfilename tcc-doc.info -@settitle Tiny C Compiler Reference Documentation -@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 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 - -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 -v -Display current TCC version, increase verbosity. - -@item -c -Generate an object file (@option{-o} option must also be given). - -@item -o outfile -Put object file, executable, or dll into output file @file{outfile}. - -@item -Bdir -Set the path where the tcc internal libraries can be found (default is -@file{PREFIX/lib/tcc}). - -@item -bench -Output compilation statistics. - -@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: - -@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 -#include -int main(int argc, char **argv) -@{ - ... -@} -@end example - -@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}. -@end table - -Compilation flags: - -Note: each of the following warning 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. - -@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. - -@item -shared -Generate a shared library instead of an executable (@option{-o} option -must also be given). - -@item -static -Generate a statically linked executable (default is a shared linked -executable) (@option{-o} option must also be given). - -@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 (@option{-o} option must -also be given). - -@item -Wl,-Ttext,address -Set the start of the .text section to @var{address}. - -@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 - -@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. - -@item -bt N -Display N callers in stack traces. This is useful with @option{-g} or -@option{-b}. - -@end table - -Note: GCC options @option{-Ox}, @option{-fx} and @option{-mx} are -ignored. -@c man end - -@ignore - -@setfilename tcc -@settitle Tiny C Compiler - -@c man begin SEEALSO -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 and variable length -arrays. - -Currently implemented ISOC99 features: - -@itemize - -@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 @code{1} 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 -desactivate 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 preceeded 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 choosen 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_BITFIELD 0x0040 /* bitfield modifier */ - -#define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 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. - -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 */ -@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 idenfier 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. - -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 datas 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 actived 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_LLOCAL} should be eliminated -ASAP because its semantics are rather complicated. - -@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 guaranted 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 guaranted 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/05/tcc-0.9.25/tcc.c b/05/tcc-0.9.25/tcc.c deleted file mode 100644 index 28c59a3..0000000 --- a/05/tcc-0.9.25/tcc.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * 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 "libtcc.c" - -void help(void) -{ - printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n" - "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n" - " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-soname name]\n" - " [-static] [infile1 infile2...] [-run infile args...]\n" - "\n" - "General options:\n" - " -v display current version, increase verbosity\n" - " -c compile only - generate an object file\n" - " -o outfile set output filename\n" - " -Bdir set tcc internal library path\n" - " -bench output compilation statistics\n" - " -run run compiled source\n" - " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n" - " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n" - " -w disable all warnings\n" - "Preprocessor options:\n" - " -E preprocess only\n" - " -Idir add include path 'dir'\n" - " -Dsym[=val] define 'sym' with value 'val'\n" - " -Usym undefine 'sym'\n" - "Linker options:\n" - " -Ldir add library path 'dir'\n" - " -llib link with dynamic or static library 'lib'\n" - " -shared generate a shared library\n" - " -soname set name for shared library to be used at runtime\n" - " -static static linking\n" - " -rdynamic export all global symbols to dynamic linker\n" - " -r generate (relocatable) object file\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 - ); -} - -static char **files; -static int nb_files, nb_libraries; -static int multiple_files; -static int print_search_dirs; -static int output_type; -static int reloc_output; -static const char *outfile; -static int do_bench = 0; - -#define TCC_OPTION_HAS_ARG 0x0001 -#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */ - -typedef struct TCCOption { - const char *name; - uint16_t index; - uint16_t flags; -} TCCOption; - -enum { - TCC_OPTION_HELP, - TCC_OPTION_I, - TCC_OPTION_D, - TCC_OPTION_U, - 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_static, - TCC_OPTION_shared, - TCC_OPTION_soname, - TCC_OPTION_o, - TCC_OPTION_r, - TCC_OPTION_Wl, - TCC_OPTION_W, - TCC_OPTION_O, - TCC_OPTION_m, - TCC_OPTION_f, - TCC_OPTION_nostdinc, - TCC_OPTION_nostdlib, - TCC_OPTION_print_search_dirs, - TCC_OPTION_rdynamic, - TCC_OPTION_run, - TCC_OPTION_v, - TCC_OPTION_w, - TCC_OPTION_pipe, - TCC_OPTION_E, -}; - -static const TCCOption tcc_options[] = { - { "h", TCC_OPTION_HELP, 0 }, - { "?", TCC_OPTION_HELP, 0 }, - { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, - { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, - { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, - { "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 }, - { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG }, -#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 }, - { "static", TCC_OPTION_static, 0 }, - { "shared", TCC_OPTION_shared, 0 }, - { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG }, - { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG }, - { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "rdynamic", TCC_OPTION_rdynamic, 0 }, - { "r", TCC_OPTION_r, 0 }, - { "Wl,", TCC_OPTION_Wl, 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 }, - { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG }, - { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "nostdinc", TCC_OPTION_nostdinc, 0 }, - { "nostdlib", TCC_OPTION_nostdlib, 0 }, - { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 }, - { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "w", TCC_OPTION_w, 0 }, - { "pipe", TCC_OPTION_pipe, 0}, - { "E", TCC_OPTION_E, 0}, - { NULL } -}; - -static int64_t getclock_us(void) -{ -#ifdef _WIN32 - struct _timeb tb; - _ftime(&tb); - return (tb.time * 1000LL + tb.millitm) * 1000LL; -#else - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec * 1000000LL + tv.tv_usec; -#endif -} - -static int strstart(const char *str, const char *val, const char **ptr) -{ - const char *p, *q; - p = str; - q = val; - while (*q != '\0') { - if (*p != *q) - return 0; - p++; - q++; - } - if (ptr) - *ptr = p; - return 1; -} - -/* convert 'str' into an array of space separated strings */ -static int expand_args(char ***pargv, const char *str) -{ - const char *s1; - char **argv, *arg; - int argc, len; - - argc = 0; - argv = NULL; - for(;;) { - while (is_space(*str)) - str++; - if (*str == '\0') - break; - s1 = str; - while (*str != '\0' && !is_space(*str)) - str++; - len = str - s1; - arg = tcc_malloc(len + 1); - memcpy(arg, s1, len); - arg[len] = '\0'; - dynarray_add((void ***)&argv, &argc, arg); - } - *pargv = argv; - return argc; -} - -int parse_args(TCCState *s, int argc, char **argv) -{ - int optind; - const TCCOption *popt; - const char *optarg, *p1, *r1; - char *r; - - optind = 0; - while (optind < argc) { - - r = argv[optind++]; - if (r[0] != '-' || r[1] == '\0') { - /* add a new file */ - dynarray_add((void ***)&files, &nb_files, r); - if (!multiple_files) { - optind--; - /* argv[0] will be this file */ - break; - } - } else { - /* find option in table (match only the first chars */ - popt = tcc_options; - for(;;) { - p1 = popt->name; - if (p1 == NULL) - error("invalid option -- '%s'", r); - r1 = r + 1; - for(;;) { - if (*p1 == '\0') - goto option_found; - if (*r1 != *p1) - break; - p1++; - r1++; - } - popt++; - } - option_found: - if (popt->flags & TCC_OPTION_HAS_ARG) { - if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) { - optarg = r1; - } else { - if (optind >= argc) - error("argument to '%s' is missing", r); - optarg = argv[optind++]; - } - } else { - if (*r1 != '\0') - return 0; - optarg = NULL; - } - - switch(popt->index) { - case TCC_OPTION_HELP: - return 0; - - case TCC_OPTION_I: - if (tcc_add_include_path(s, optarg) < 0) - error("too many include paths"); - break; - case TCC_OPTION_D: - { - char *sym, *value; - sym = (char *)optarg; - value = strchr(sym, '='); - if (value) { - *value = '\0'; - value++; - } - tcc_define_symbol(s, sym, value); - } - 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: - dynarray_add((void ***)&files, &nb_files, r); - nb_libraries++; - break; - case TCC_OPTION_bench: - do_bench = 1; - break; -#ifdef CONFIG_TCC_BACKTRACE - case TCC_OPTION_bt: - 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: - multiple_files = 1; - output_type = TCC_OUTPUT_OBJ; - break; - case TCC_OPTION_static: - s->static_link = 1; - break; - case TCC_OPTION_shared: - output_type = TCC_OUTPUT_DLL; - break; - case TCC_OPTION_soname: - s->soname = optarg; - break; - case TCC_OPTION_o: - multiple_files = 1; - outfile = optarg; - break; - case TCC_OPTION_r: - /* generate a .o merging several output files */ - reloc_output = 1; - output_type = TCC_OUTPUT_OBJ; - break; - case TCC_OPTION_nostdinc: - s->nostdinc = 1; - break; - case TCC_OPTION_nostdlib: - s->nostdlib = 1; - break; - case TCC_OPTION_print_search_dirs: - print_search_dirs = 1; - break; - case TCC_OPTION_run: - { - int argc1; - char **argv1; - argc1 = expand_args(&argv1, optarg); - if (argc1 > 0) { - parse_args(s, argc1, argv1); - } - multiple_files = 0; - output_type = TCC_OUTPUT_MEMORY; - } - break; - case TCC_OPTION_v: - do { - if (0 == s->verbose++) - printf("tcc version %s\n", TCC_VERSION); - } while (*optarg++ == 'v'); - break; - case TCC_OPTION_f: - if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported) - goto unsupported_option; - break; - case TCC_OPTION_W: - if (tcc_set_warning(s, optarg, 1) < 0 && - s->warn_unsupported) - 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: - { - const char *p; - if (strstart(optarg, "-Ttext,", &p)) { - s->text_addr = strtoul(p, NULL, 16); - s->has_text_addr = 1; - } else if (strstart(optarg, "--oformat,", &p)) { - if (strstart(p, "elf32-", NULL)) { - s->output_format = TCC_OUTPUT_FORMAT_ELF; - } else if (!strcmp(p, "binary")) { - s->output_format = TCC_OUTPUT_FORMAT_BINARY; - } else -#ifdef TCC_TARGET_COFF - if (!strcmp(p, "coff")) { - s->output_format = TCC_OUTPUT_FORMAT_COFF; - } else -#endif - { - error("target %s not found", p); - } - } else { - error("unsupported linker option '%s'", optarg); - } - } - break; - case TCC_OPTION_E: - output_type = TCC_OUTPUT_PREPROCESS; - break; - default: - if (s->warn_unsupported) { - unsupported_option: - warning("unsupported option '%s'", r); - } - break; - } - } - } - return optind + 1; -} - -int main(int argc, char **argv) -{ - int i; - TCCState *s; - int nb_objfiles, ret, optind; - char objfilename[1024]; - int64_t start_time = 0; - _init_tcc_syms(); - _init_warning_defs(); - _init_flag_defs(); - - s = tcc_new(); -#ifdef _WIN32 - tcc_set_lib_path_w32(s); -#endif - output_type = TCC_OUTPUT_EXE; - outfile = NULL; - multiple_files = 1; - files = NULL; - nb_files = 0; - nb_libraries = 0; - reloc_output = 0; - print_search_dirs = 0; - ret = 0; - - optind = parse_args(s, argc - 1, argv + 1); - if (print_search_dirs) { - /* enough for Linux kernel */ - printf("install: %s/\n", s->tcc_lib_path); - return 0; - } - if (optind == 0 || nb_files == 0) { - if (optind && s->verbose) - return 0; - help(); - return 1; - } - - nb_objfiles = nb_files - nb_libraries; - - /* if outfile provided without other options, we output an - executable */ - if (outfile && output_type == TCC_OUTPUT_MEMORY) - output_type = TCC_OUTPUT_EXE; - - /* check -c consistency : only single file handled. XXX: checks file type */ - if (output_type == TCC_OUTPUT_OBJ && !reloc_output) { - /* accepts only a single input file */ - if (nb_objfiles != 1) - error("cannot specify multiple files with -c"); - if (nb_libraries != 0) - error("cannot specify libraries with -c"); - } - - - if (output_type == TCC_OUTPUT_PREPROCESS) { - if (!outfile) { - s->outfile = stdout; - } else { - s->outfile = fopen(outfile, "w"); - if (!s->outfile) - error("could not open '%s", outfile); - } - } else if (output_type != TCC_OUTPUT_MEMORY) { - if (!outfile) { - /* compute default outfile name */ - char *ext; - const char *name = - strcmp(files[0], "-") == 0 ? "a" : tcc_basename(files[0]); - pstrcpy(objfilename, sizeof(objfilename), name); - ext = tcc_fileextension(objfilename); -#ifdef TCC_TARGET_PE - if (output_type == TCC_OUTPUT_DLL) - strcpy(ext, ".dll"); - else - if (output_type == TCC_OUTPUT_EXE) - strcpy(ext, ".exe"); - else -#endif - if (output_type == TCC_OUTPUT_OBJ && !reloc_output && *ext) - strcpy(ext, ".o"); - else - pstrcpy(objfilename, sizeof(objfilename), "a.out"); - outfile = objfilename; - } - } - - if (do_bench) { - start_time = getclock_us(); - } - - tcc_set_output_type(s, output_type); - - /* compile or add each files or library */ - for(i = 0; i < nb_files && ret == 0; i++) { - const char *filename; - - filename = files[i]; - if (filename[0] == '-' && filename[1]) { - if (tcc_add_library(s, filename + 2) < 0) { - error_noabort("cannot find %s", filename); - ret = 1; - } - } else { - if (1 == s->verbose) - printf("-> %s\n", filename); - if (tcc_add_file(s, filename) < 0) - ret = 1; - } - } - - /* free all files */ - tcc_free(files); - - if (ret) - goto the_end; - - if (do_bench) - tcc_print_stats(s, getclock_us() - start_time); - - if (s->output_type == TCC_OUTPUT_PREPROCESS) { - if (outfile) - fclose(s->outfile); - } else if (s->output_type == TCC_OUTPUT_MEMORY) { - ret = tcc_run(s, argc - optind, argv + optind); - } else - ret = tcc_output_file(s, outfile) ? 1 : 0; - the_end: - /* XXX: cannot do it with bound checking because of the malloc hooks */ - if (!s->do_bounds_check) - tcc_delete(s); - -#ifdef MEM_DEBUG - if (do_bench) { - printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size); - } -#endif - return ret; -} - diff --git a/05/tcc-0.9.25/tcc.h b/05/tcc-0.9.25/tcc.h deleted file mode 100644 index b4789da..0000000 --- a/05/tcc-0.9.25/tcc.h +++ /dev/null @@ -1,764 +0,0 @@ -/* - * 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 - */ - -#define _GNU_SOURCE -#include "config.h" - -#ifdef CONFIG_TCCBOOT - -#include "tccboot.h" -#define CONFIG_TCC_STATIC - -#else - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef __GNUC__ -#include -#include -#include -#include -#include -#endif - -#ifdef _WIN32 -#include -#include -#include /* open, close etc. */ -#include /* getcwd */ -#define inline __inline -#define inp next_inp -#endif - -#endif /* !CONFIG_TCCBOOT */ - -#ifndef PAGESIZE -#define PAGESIZE 4096 -#endif - -#include "elf.h" -#include "stab.h" - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -#include "libtcc.h" - -/* parser debug */ -//#define PARSE_DEBUG -/* preprocessor debug */ -//#define PP_DEBUG -/* include file debug */ -//#define INC_DEBUG - -//#define MEM_DEBUG - -/* assembler debug */ -//#define ASM_DEBUG - -/* target selection */ -//#define TCC_TARGET_I386 /* i386 code generator */ -//#define TCC_TARGET_ARM /* ARMv4 code generator */ -//#define TCC_TARGET_C67 /* TMS320C67xx code generator */ -//#define TCC_TARGET_X86_64 /* x86-64 code generator */ - -/* default target is I386 */ -#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ - !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64) -#define TCC_TARGET_I386 -#endif - -#if !defined(_WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \ - !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64) -#define CONFIG_TCC_BCHECK /* enable bound checking code */ -#endif - -#if defined(_WIN32) && !defined(TCC_TARGET_PE) -#define CONFIG_TCC_STATIC -#endif - -/* define it to include assembler support */ -#if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67) && \ - !defined(TCC_TARGET_X86_64) -#define CONFIG_TCC_ASM -#endif - -/* object format selection */ -#if defined(TCC_TARGET_C67) -#define TCC_TARGET_COFF -#endif - -#if !defined(_WIN32) && !defined(CONFIG_TCCBOOT) -//#define CONFIG_TCC_BACKTRACE// this uses sigaction() which we don't have -#endif - -#define FALSE 0 -#define false 0 -#define TRUE 1 -#define true 1 -typedef int BOOL; - -/* path to find crt1.o, crti.o and crtn.o. Only needed when generating - executables or dlls */ -#ifndef CONFIG_TCC_CRT_PREFIX -#define CONFIG_TCC_CRT_PREFIX CONFIG_SYSROOT "/usr/lib" -#endif - -#define INCLUDE_STACK_SIZE 32 -#define IFDEF_STACK_SIZE 64 -#define VSTACK_SIZE 256 -#define STRING_MAX_SIZE 1024 -#define PACK_STACK_SIZE 8 - -#define TOK_HASH_SIZE 8192 /* 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; - void *data_allocated; /* if non NULL, data has been malloced */ -} CString; - -/* type definition */ -typedef struct CType { - int t; - struct Sym *ref; -} CType; - -/* constant value */ -typedef union CValue { - long double ld; - double d; - float f; - int i; - unsigned int ui; - unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */ - long long ll; - unsigned long long ull; - struct CString *cstr; - void *ptr; - int tab[1]; -} 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) */ -} SValue; - -/* symbol management */ -typedef struct Sym { - int v; /* symbol token */ - long r; /* associated register */ - long c; /* associated number */ - CType type; /* associated type */ - struct Sym *next; /* next related symbol */ - struct Sym *prev; /* prev symbol in stack */ - struct Sym *prev_tok; /* previous symbol for this token */ -} Sym; - -/* section definition */ -/* XXX: use directly ELF structure for parameters ? */ -/* special flag to indicate that the section should not be linked to - the other ones */ -#define SHF_PRIVATE 0x80000000 - -/* special flag, too */ -#define SECTION_ABS ((void *)1) - -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) */ - unsigned long 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 *next; - char name[1]; /* section name */ -} Section; - -typedef struct DLLReference { - int level; - void *handle; - char name[1]; -} DLLReference; - -/* GNUC attribute definition */ -typedef struct AttributeDef { - int aligned; - int packed; - Section *section; - int func_attr; /* calling convention, exports, ... */ -} AttributeDef; - -/* -------------------------------------------------- */ -/* gr: wrappers for casting sym->r for other purposes */ -typedef struct { - unsigned char func_call, func_args, func_export; // should be equivalent to the bitfields that were here before -} func_attr_t; - -#define FUNC_CALL(r) (((func_attr_t*)&(r))->func_call) -#define FUNC_EXPORT(r) (((func_attr_t*)&(r))->func_export) -#define FUNC_ARGS(r) (((func_attr_t*)&(r))->func_args) -#define INLINE_DEF(r) (*(int **)&(r)) -/* -------------------------------------------------- */ - -#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.c' 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.r' 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; - int line_num; /* current line number - here to simplify code */ - 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 */ - char inc_type; /* type of include */ - char inc_filename[512]; /* filename specified by the user */ - char filename[1024]; /* current filename - here to simplify code */ - unsigned char buffer[IO_BUF_SIZE + 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 */ - -/* parsing state (used to save parser state to reparse part of the - source several times) */ -typedef struct ParseState { - int *macro_ptr; - int line_num; - int tok; - CValue tokc; -} ParseState; - -/* used to record tokens */ -typedef struct TokenString { - int *str; - int len; - int allocated_len; - int last_line_num; -} TokenString; - -/* 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 hash_next; /* -1 if none */ - char type; /* '"' or '>' to give include type */ - char filename[1]; /* path specified in #include */ -} CachedInclude; - -#define CACHED_INCLUDES_HASH_SIZE 512 - -#ifdef CONFIG_TCC_ASM -typedef struct ExprValue { - uint32_t v; - Sym *sym; -} ExprValue; - -#define MAX_ASM_OPERANDS 30 -typedef struct ASMOperand { - int id; /* GCC 3 optionnal 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 - -struct TCCState { - int output_type; - - BufferedFile **include_stack_ptr; - int *ifdef_stack_ptr; - - /* include file handling */ - char **include_paths; - int nb_include_paths; - char **sysinclude_paths; - int nb_sysinclude_paths; - CachedInclude **cached_includes; - int nb_cached_includes; - - char **library_paths; - int nb_library_paths; - - /* array of all loaded dlls (including those referenced by loaded - dlls) */ - DLLReference **loaded_dlls; - int nb_loaded_dlls; - - /* 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 handling */ - Section *got; - Section *plt; - unsigned long *got_offsets; - int nb_got_offsets; - /* give the correspondance from symtab indexes to dynsym indexes */ - int *symtab_to_dynsym; - - /* temporary dynamic symbol sections (for dll loading) */ - Section *dynsymtab_section; - /* exported dynamic symbol section */ - Section *dynsym; - - 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 */ - - /* if true, static linking is performed */ - int static_link; - - /* soname as specified on the command line (-soname) */ - const char *soname; - - /* if true, all symbols are exported */ - int rdynamic; - - /* if true, only link in referenced objects from archive */ - int alacarte_link; - - /* address of text section */ - unsigned long text_addr; - int has_text_addr; - - /* output format, see TCC_OUTPUT_FORMAT_xxx */ - int output_format; - - /* C language options */ - int char_is_unsigned; - int leading_underscore; - - /* warning switches */ - int warn_write_strings; - int warn_unsupported; - int warn_error; - int warn_none; - int warn_implicit_function_declaration; - - /* display some information during compilation */ - int verbose; - /* compile with debug symbol (and use them if error during execution) */ - int do_debug; - /* compile with built-in memory and bounds checker */ - int do_bounds_check; - /* give the path of the tcc libraries */ - const char *tcc_lib_path; - - /* 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; - - /* tiny assembler state */ - Sym *asm_labels; - - /* see include_stack_ptr */ - BufferedFile *include_stack[INCLUDE_STACK_SIZE]; - - /* see ifdef_stack_ptr */ - int ifdef_stack[IFDEF_STACK_SIZE]; - - /* see cached_includes */ - int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE]; - - /* pack stack */ - int pack_stack[PACK_STACK_SIZE]; - int *pack_stack_ptr; - - /* output file for preprocessing */ - FILE *outfile; - - /* for tcc_relocate */ - int runtime_added; - -#ifdef TCC_TARGET_X86_64 - /* write PLT and GOT here */ - char *runtime_plt_and_got; - unsigned int runtime_plt_and_got_offset; -#endif -}; - -/* The current value can be: */ -#define VT_VALMASK 0x00ff -#define VT_CONST 0x00f0 /* constant in vc - (must be first non register value) */ -#define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */ -#define VT_LOCAL 0x00f2 /* offset on stack */ -#define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */ -#define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */ -#define VT_JMPI 0x00f5 /* 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_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_BITFIELD 0x0040 /* bitfield modifier */ -#define VT_CONSTANT 0x0800 /* const modifier */ -#define VT_VOLATILE 0x1000 /* volatile modifier */ -#define VT_SIGNED 0x2000 /* signed type */ - -/* storage */ -#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_STRUCT_SHIFT 16 /* shift for bitfield shift values */ - -/* type mask (except storage) */ -#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE) -#define VT_TYPE (~(VT_STORAGE)) - -/* 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 */ -#define TOK_CINT 0xb3 /* number in tokc */ -#define TOK_CCHAR 0xb4 /* char constant in tokc */ -#define TOK_STR 0xb5 /* pointer to string in tokc */ -#define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */ -#define TOK_LCHAR 0xb7 -#define TOK_LSTR 0xb8 -#define TOK_CFLOAT 0xb9 /* float constant */ -#define TOK_LINENUM 0xba /* line number info */ -#define TOK_CDOUBLE 0xc0 /* double constant */ -#define TOK_CLDOUBLE 0xc1 /* long double constant */ -#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_CUINT 0xc8 /* unsigned int constant */ -#define TOK_CLLONG 0xc9 /* long long constant */ -#define TOK_CULLONG 0xca /* unsigned long long constant */ -#define TOK_ARROW 0xcb -#define TOK_DOTS 0xcc /* three dots */ -#define TOK_SHR 0xcd /* unsigned shift right */ -#define TOK_PPNUM 0xce /* preprocessor number */ - -#define TOK_SHL 0x01 /* shift left */ -#define TOK_SAR 0x02 /* signed shift right */ - -/* assignement 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 - -#ifndef offsetof -#define offsetof(type, field) ((size_t) &((type *)0)->field) -#endif - -#ifndef countof -#define countof(tab) (sizeof(tab) / sizeof((tab)[0])) -#endif - -#define TOK_EOF (-1) /* end of file */ -#define TOK_LINEFEED 10 /* line feed */ - -/* all identificators and strings have token above that */ -#define TOK_IDENT 256 - -/* only used for i386 asm opcodes definitions */ -#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x) - -#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) - -#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) \ - DEF_ASM(x ## o) \ - DEF_ASM(x ## no) \ - DEF_ASM(x ## b) \ - DEF_ASM(x ## c) \ - DEF_ASM(x ## nae) \ - DEF_ASM(x ## nb) \ - DEF_ASM(x ## nc) \ - DEF_ASM(x ## ae) \ - DEF_ASM(x ## e) \ - DEF_ASM(x ## z) \ - DEF_ASM(x ## ne) \ - DEF_ASM(x ## nz) \ - DEF_ASM(x ## be) \ - DEF_ASM(x ## na) \ - DEF_ASM(x ## nbe) \ - DEF_ASM(x ## a) \ - DEF_ASM(x ## s) \ - DEF_ASM(x ## ns) \ - DEF_ASM(x ## p) \ - DEF_ASM(x ## pe) \ - DEF_ASM(x ## np) \ - DEF_ASM(x ## po) \ - DEF_ASM(x ## l) \ - DEF_ASM(x ## nge) \ - DEF_ASM(x ## nl) \ - DEF_ASM(x ## ge) \ - DEF_ASM(x ## le) \ - DEF_ASM(x ## ng) \ - DEF_ASM(x ## nle) \ - DEF_ASM(x ## g) - -#define TOK_ASM_int TOK_INT - -enum tcc_token { - TOK_LAST = TOK_IDENT - 1, -#define DEF(id, str) id, -#include "tcctok.h" -#undef DEF -}; - -#define TOK_UIDENT TOK_DEFINE - -#ifdef _WIN32 -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#ifndef __GNUC__ - #define strtold (long double)strtod - #define strtof (float)strtod - #define strtoll (long long)strtol -#endif -#elif defined(TCC_UCLIBC) || defined(__FreeBSD__) || defined(__DragonFly__) \ - || defined(__OpenBSD__) -/* currently incorrect */ -long double strtold(const char *nptr, char **endptr) -{ - return (long double)strtod(nptr, endptr); -} -float strtof(const char *nptr, char **endptr) -{ - return (float)strtod(nptr, endptr); -} -#else -/* 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 -#define IS_PATHSEP(c) (c == '/' || c == '\\') -#define IS_ABSPATH(p) (IS_PATHSEP(p[0]) || (p[0] && p[1] == ':' && IS_PATHSEP(p[2]))) -#define PATHCMP stricmp -#else -#define IS_PATHSEP(c) (c == '/') -#define IS_ABSPATH(p) IS_PATHSEP(p[0]) -#define PATHCMP strcmp -#endif - -void error(const char *fmt, ...); -void error_noabort(const char *fmt, ...); -void warning(const char *fmt, ...); - -void tcc_set_lib_path_w32(TCCState *s); -int tcc_set_flag(TCCState *s, const char *flag_name, int value); -void tcc_print_stats(TCCState *s, int64_t total_time); - -void tcc_free(void *ptr); -void *tcc_malloc(unsigned long size); -void *tcc_mallocz(unsigned long size); -void *tcc_realloc(void *ptr, unsigned long size); -char *tcc_strdup(const char *str); - -char *tcc_basename(const char *name); -char *tcc_fileextension (const char *name); -char *pstrcpy(char *buf, int buf_size, const char *s); -char *pstrcat(char *buf, int buf_size, const char *s); -void dynarray_add(void ***ptab, int *nb_ptr, void *data); -void dynarray_reset(void *pp, int *n); - -#ifdef CONFIG_TCC_BACKTRACE -extern int num_callers; -extern const char **rt_bound_error_msg; -#endif - -/* true if float/double/long double type */ -static inline int is_float(int t) -{ - int bt; - bt = t & VT_BTYPE; - return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT; -} - -/* space exlcuding newline */ -static inline int is_space(int ch) -{ - return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r'; -} - diff --git a/05/tcc-0.9.25/tccasm.c b/05/tcc-0.9.25/tccasm.c deleted file mode 100644 index 8834b53..0000000 --- a/05/tcc-0.9.25/tccasm.c +++ /dev/null @@ -1,1021 +0,0 @@ -/* - * 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 - */ - -static 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 void asm_expr(TCCState *s1, ExprValue *pe); - -/* 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, n, label; - const char *p; - - switch(tok) { - case TOK_PPNUM: - p = tokc.cstr->data; - n = strtoul(p, (char **)&p, 0); - if (*p == 'b' || *p == 'f') { - /* backward or forward label */ - label = asm_get_local_label_name(s1, n); - sym = label_find(label); - if (*p == 'b') { - /* backward : find the last corresponding defined label */ - if (sym && sym->r == 0) - sym = sym->prev_tok; - if (!sym) - error("local label '%d' not found backward", n); - } else { - /* forward */ - if (!sym || sym->r) { - /* if the last label is defined, then define a new one */ - sym = label_push(&s1->asm_labels, label, 0); - sym->type.t = VT_STATIC | VT_VOID; - } - } - pe->v = 0; - pe->sym = sym; - } else if (*p == '\0') { - pe->v = n; - pe->sym = NULL; - } else { - 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) - 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; - next(); - break; - case '(': - next(); - asm_expr(s1, pe); - skip(')'); - break; - default: - if (tok >= TOK_IDENT) { - /* label case : if the label was not found, add one */ - sym = label_find(tok); - if (!sym) { - sym = label_push(&s1->asm_labels, tok, 0); - /* NOTE: by default, the symbol is global */ - sym->type.t = VT_VOID; - } - if (sym->r == SHN_ABS) { - /* if absolute symbol, no need to put a symbol value */ - pe->v = (long)sym->next; - pe->sym = NULL; - } else { - pe->v = 0; - pe->sym = sym; - } - next(); - } else { - 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) - error("invalid operation with label"); - switch(op) { - case '*': - pe->v *= e2.v; - break; - case '/': - if (e2.v == 0) { - div_error: - 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) - 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 (!pe->sym && !e2.sym) { - /* OK */ - } else if (pe->sym && !e2.sym) { - /* OK */ - } else if (pe->sym && e2.sym) { - if (pe->sym == e2.sym) { - /* OK */ - } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) { - /* we also accept defined symbols in the same section */ - pe->v += (long)pe->sym->next - (long)e2.sym->next; - } else { - goto cannot_relocate; - } - pe->sym = NULL; /* same symbols can be substracted to NULL */ - } else { - cannot_relocate: - error("invalid operation with label"); - } - } - } -} - -static void asm_expr(TCCState *s1, ExprValue *pe) -{ - asm_expr_sum(s1, pe); -} - -static int asm_int_expr(TCCState *s1) -{ - ExprValue e; - asm_expr(s1, &e); - if (e.sym) - expect("constant"); - return e.v; -} - -/* NOTE: the same name space as C labels is used to avoid using too - much memory when storing labels in TokenStrings */ -static void asm_new_label1(TCCState *s1, int label, int is_local, - int sh_num, int value) -{ - Sym *sym; - - sym = label_find(label); - if (sym) { - if (sym->r) { - /* the label is already defined */ - if (!is_local) { - error("assembler label '%s' already defined", - get_tok_str(label, NULL)); - } else { - /* redefinition of local labels is possible */ - goto new_label; - } - } - } else { - new_label: - sym = label_push(&s1->asm_labels, label, 0); - sym->type.t = VT_STATIC | VT_VOID; - } - sym->r = sh_num; - sym->next = (void *)value; -} - -static void asm_new_label(TCCState *s1, int label, int is_local) -{ - asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind); -} - -static void asm_free_labels(TCCState *st) -{ - Sym *s, *s1; - Section *sec; - - for(s = st->asm_labels; s != NULL; s = s1) { - s1 = s->prev; - /* define symbol value in object file */ - if (s->r) { - if (s->r == SHN_ABS) - sec = SECTION_ABS; - else - sec = st->sections[s->r]; - put_extern_sym2(s, sec, (long)s->next, 0, 0); - } - /* remove label */ - table_ident[s->v - TOK_IDENT]->sym_label = NULL; - sym_free(s); - } - st->asm_labels = NULL; -} - -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 asm_parse_directive(TCCState *s1) -{ - int n, offset, v, size, tok1; - Section *sec; - uint8_t *ptr; - - /* assembler directive */ - next(); - sec = cur_text_section; - switch(tok) { - case TOK_ASM_align: - case TOK_ASM_skip: - case TOK_ASM_space: - tok1 = tok; - next(); - n = asm_int_expr(s1); - if (tok1 == TOK_ASM_align) { - if (n < 0 || (n & (n-1)) != 0) - 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 { - 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_ASM_quad: - next(); - for(;;) { - uint64_t vl; - const char *p; - - p = tokc.cstr->data; - if (tok != TOK_PPNUM) { - error_constant: - 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; - case TOK_ASM_byte: - size = 1; - goto asm_data; - case TOK_ASM_word: - case TOK_SHORT: - size = 2; - goto asm_data; - case TOK_LONG: - case TOK_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); - } 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_ASM_fill: - { - int repeat, size, val, i, j; - uint8_t repeat_buf[8]; - next(); - repeat = asm_int_expr(s1); - if (repeat < 0) { - error("repeat < 0; .fill ignored"); - break; - } - size = 1; - val = 0; - if (tok == ',') { - next(); - size = asm_int_expr(s1); - if (size < 0) { - 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_ASM_org: - { - unsigned long n; - next(); - /* XXX: handle section symbols too */ - n = asm_int_expr(s1); - if (n < ind) - error("attempt to .org backwards"); - v = 0; - size = n - ind; - goto zero_pad; - } - break; - case TOK_ASM_globl: - case TOK_ASM_global: - { - Sym *sym; - - next(); - sym = label_find(tok); - if (!sym) { - sym = label_push(&s1->asm_labels, tok, 0); - sym->type.t = VT_VOID; - } - sym->type.t &= ~VT_STATIC; - next(); - } - break; - case TOK_ASM_string: - case TOK_ASM_ascii: - case TOK_ASM_asciz: - { - const uint8_t *p; - int i, size, t; - - t = tok; - next(); - for(;;) { - if (tok != TOK_STR) - expect("string constant"); - p = tokc.cstr->data; - size = tokc.cstr->size; - if (t == TOK_ASM_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_ASM_text: - case TOK_ASM_data: - case TOK_ASM_bss: - { - char sname[64]; - tok1 = tok; - n = 0; - next(); - if (tok != ';' && tok != TOK_LINEFEED) { - n = asm_int_expr(s1); - next(); - } - sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n); - use_section(s1, sname); - } - break; - case TOK_SECTION1: - { - char sname[256]; - - /* XXX: support more options */ - next(); - sname[0] = '\0'; - while (tok != ';' && tok != TOK_LINEFEED && tok != ',') { - if (tok == TOK_STR) - pstrcat(sname, sizeof(sname), tokc.cstr->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(); - } - last_text_section = cur_text_section; - use_section(s1, sname); - } - break; - case TOK_ASM_previous: - { - Section *sec; - next(); - if (!last_text_section) - error("no previous section referenced"); - sec = cur_text_section; - use_section1(s1, last_text_section); - last_text_section = sec; - } - break; - default: - 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 opcode; - -#if 0 - /* print stats about opcodes */ - { - const ASMInstr *pa; - int freq[4]; - int op_vals[500]; - int nb_op_vals, i, j; - - nb_op_vals = 0; - memset(freq, 0, sizeof(freq)); - for(pa = asm_instrs; pa->sym != 0; pa++) { - freq[pa->nb_ops]++; - for(i=0;inb_ops;i++) { - for(j=0;jop_type[i] == op_vals[j]) - goto found; - } - op_vals[nb_op_vals++] = pa->op_type[i]; - found: ; - } - } - for(i=0;ibuf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_ASM_COMMENTS; - if (do_preprocess) - parse_flags |= PARSE_FLAG_PREPROCESS; - next(); - for(;;) { - if (tok == TOK_EOF) - break; - parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ - redo: - if (tok == '#') { - /* horrible gas comment */ - while (tok != TOK_LINEFEED) - next(); - } else if (tok == '.') { - asm_parse_directive(s1); - } else if (tok == TOK_PPNUM) { - const char *p; - int n; - p = tokc.cstr->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 == '=') { - int n; - next(); - n = asm_int_expr(s1); - asm_new_label1(s1, opcode, 0, SHN_ABS, n); - 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 */ - next(); - } - - asm_free_labels(s1); - - return 0; -} - -/* Assemble the current file */ -static int tcc_assemble(TCCState *s1, int do_preprocess) -{ - Sym *define_start; - int ret; - - preprocess_init(s1); - - /* default section is text */ - cur_text_section = text_section; - ind = cur_text_section->data_offset; - - define_start = define_stack; - - ret = tcc_assemble_internal(s1, do_preprocess); - - cur_text_section->data_offset = ind; - - free_defines(define_start); - - 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) -{ - BufferedFile *bf, *saved_file; - int saved_parse_flags, *saved_macro_ptr; - - bf = tcc_malloc(sizeof(BufferedFile)); - memset(bf, 0, sizeof(BufferedFile)); - bf->fd = -1; - bf->buf_ptr = str; - bf->buf_end = str + len; - str[len] = CH_EOB; - /* same name as current file so that errors are correctly - reported */ - pstrcpy(bf->filename, sizeof(bf->filename), file->filename); - bf->line_num = file->line_num; - saved_file = file; - file = bf; - saved_parse_flags = parse_flags; - saved_macro_ptr = macro_ptr; - macro_ptr = NULL; - - tcc_assemble_internal(s1, 0); - - parse_flags = saved_parse_flags; - macro_ptr = saved_macro_ptr; - file = saved_file; - tcc_free(bf); -} - -/* 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 */ -static 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, - int nb_outputs, - 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') - modifier = *str++; - index = find_constraint(operands, nb_operands, str, &str); - if (index < 0) - 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(;;) { - if (nb_operands >= MAX_ASM_OPERANDS) - 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(']'); - } - if (tok != TOK_STR) - expect("string constant"); - op->constraint = tcc_malloc(tokc.cstr->size); - strcpy(op->constraint, tokc.cstr->data); - next(); - skip('('); - gexpr(); - if (is_output) { - 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; - } -} - -static void parse_asm_str(CString *astr) -{ - skip('('); - /* read the string */ - if (tok != TOK_STR) - expect("string constant"); - cstr_new(astr); - while (tok == TOK_STR) { - /* XXX: add \0 handling too ? */ - cstr_cat(astr, tokc.cstr->data); - next(); - } - cstr_ccat(astr, '\0'); -} - -/* parse the GCC asm() instruction */ -static void asm_instr(void) -{ - CString astr, astr1; - ASMOperand operands[MAX_ASM_OPERANDS]; - int nb_inputs, 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.cstr->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("';'"); - nb_inputs = nb_operands - nb_outputs; - - /* 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, nb_outputs, &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); - - /* 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;iconstraint); - vpop(); - } - cstr_free(&astr1); -} - -static void asm_global_instr(void) -{ - CString astr; - - 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); - - cur_text_section->data_offset = ind; - - /* restore the current C token */ - next(); - - cstr_free(&astr); -} diff --git a/05/tcc-0.9.25/tcccoff.c b/05/tcc-0.9.25/tcccoff.c deleted file mode 100644 index 0dcbe50..0000000 --- a/05/tcc-0.9.25/tcccoff.c +++ /dev/null @@ -1,957 +0,0 @@ -/* - * 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 "coff.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]; - -BOOL 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; - -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 = §ion_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 = §ion_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 = §ion_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 = §ion_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 = §ion_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 = §ion_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 = §ion_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 = §ion_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) - 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) { - char s[256]; - - sprintf(s, "debug info can't find function: %s", name); - - error(s); - } - // 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) { - char s[256]; - - sprintf(s, - "debug (sort) info can't find function: %s", - name2); - - error(s); - } - - 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) - 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 -} - -BOOL OutputTheSection(Section * sect) -{ - const char *s = sect->name; - - if (!strcmp(s, ".text")) - return true; - else if (!strcmp(s, ".data")) - return true; - 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; - } - - error("could not find section %s", sname); - return 0; -} - -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) { - error("Unable to open .out file for input"); - } - - if (fread(&file_hdr, FILHSZ, 1, f) != 1) - error("error reading .out file for input"); - - if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1) - 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)) - error("error reading .out file for input"); - - if (fread(&str_size, sizeof(int), 1, f) != 1) - 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) - 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)) - error("error reading .out file for input"); - - for (i = 0; i < file_hdr.f_nsyms; i++) { - if (fread(&csym, SYMESZ, 1, f) != 1) - 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*)csym.n_value); - } - // skip any aux records - - if (csym.n_numaux == 1) { - if (fread(&csym, SYMESZ, 1, f) != 1) - error("error reading .out file for input"); - i++; - } - } - - return 0; -} diff --git a/05/tcc-0.9.25/tccelf.c b/05/tcc-0.9.25/tccelf.c deleted file mode 100644 index 5da02e1..0000000 --- a/05/tcc-0.9.25/tccelf.c +++ /dev/null @@ -1,2732 +0,0 @@ -/* - * 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 - */ - -#ifdef TCC_TARGET_X86_64 -#define ElfW_Rel ElfW(Rela) -#define SHT_RELX SHT_RELA -#define REL_SECTION_FMT ".rela%s" -/* x86-64 requires PLT for DLLs */ -#define TCC_OUTPUT_DLL_WITH_PLT -#else -#define ElfW_Rel ElfW(Rel) -#define SHT_RELX SHT_REL -#define REL_SECTION_FMT ".rel%s" -#endif - -/* XXX: DLL with PLT would only work with x86-64 for now */ -//#define TCC_OUTPUT_DLL_WITH_PLT - -static 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); - memcpy(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; - char *strtab; - - strtab = s->link->data; - nb_syms = s->data_offset / sizeof(ElfW(Sym)); - - 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 (ELF64_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 */ -static int put_elf_sym(Section *s, - unsigned long 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_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 (ELF64_ST_BIND(info) != STB_LOCAL) { - /* add another hashing entry */ - nbuckets = base[0]; - h = elf_hash(name) % 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; -} - -/* find global ELF symbol 'name' and return its index. Return 0 if not - found. */ -static 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(name) % nbuckets; - sym_index = ((int *)hs->data)[2 + h]; - while (sym_index != 0) { - sym = &((ElfW(Sym) *)s->data)[sym_index]; - name1 = 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 or error */ -void *tcc_get_symbol(TCCState *s, const char *name) -{ - int sym_index; - ElfW(Sym) *sym; - sym_index = find_elf_sym(symtab_section, name); - if (!sym_index) - return NULL; - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - return (void*)(long)sym->st_value; -} - -void *tcc_get_symbol_err(TCCState *s, const char *name) -{ - void *sym; - sym = tcc_get_symbol(s, name); - if (!sym) - error("%s not defined", name); - return sym; -} - -/* add an elf symbol : check if it is already defined and patch - it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */ -static int add_elf_sym(Section *s, unsigned long value, unsigned long size, - int info, int other, int sh_num, 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 = ELF64_ST_BIND(info); - sym_type = ELF64_ST_TYPE(info); - sym_vis = ELF64_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_shndx != SHN_UNDEF) { - esym_bind = ELF64_ST_BIND(esym->st_info); - /* propagate the most constraining visibility */ - /* STV_DEFAULT(0)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 & ~ELF64_ST_VISIBILITY(-1)) - | new_vis; - other = esym->st_other; /* in case we have to patch esym */ - if (sh_num == 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_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) { - /* ignore hidden symbols after */ - } else if (esym->st_shndx == SHN_COMMON && sh_num < SHN_LORESERVE) { - /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01 - No idea if this is the correct solution ... */ - goto do_patch; - } else if (s == tcc_state->dynsymtab_section) { - /* we accept that two DLL define the same symbol */ - } else { -#if 1 - printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n", - sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis); -#endif - error_noabort("'%s' defined twice", name); - } - } else { - do_patch: - esym->st_info = ELF64_ST_INFO(sym_bind, sym_type); - esym->st_shndx = sh_num; - esym->st_value = value; - esym->st_size = size; - esym->st_other = other; - } - } else { - do_def: - sym_index = put_elf_sym(s, value, size, - ELF64_ST_INFO(sym_bind, sym_type), other, - sh_num, name); - } - return sym_index; -} - -/* put relocation */ -static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, - int type, int symbol) -{ - 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 = ELF64_R_INFO(symbol, type); -#ifdef TCC_TARGET_X86_64 - rel->r_addend = 0; -#endif -} - -/* put stab debug information */ - -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; - -static 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; -} - -static 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); -} - -static void put_stabn(int type, int other, int desc, int value) -{ - put_stabs(NULL, type, other, desc, value); -} - -static void put_stabd(int type, int other, int desc) -{ - put_stabs(NULL, type, other, desc, 0); -} - -/* 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, *rel_end; - 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 (ELF64_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 */ - 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 (ELF64_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) { - rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); - for(rel = (ElfW_Rel *)sr->data; - rel < rel_end; - rel++) { - sym_index = ELF64_R_SYM(rel->r_info); - type = ELF64_R_TYPE(rel->r_info); - sym_index = old_to_new_syms[sym_index]; - rel->r_info = ELF64_R_INFO(sym_index, type); - } - } - } - - tcc_free(old_to_new_syms); -} - -/* relocate common symbols in the .bss section */ -static void relocate_common_syms(void) -{ - ElfW(Sym) *sym, *sym_end; - unsigned long offset, align; - - sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); - for(sym = (ElfW(Sym) *)symtab_section->data + 1; - sym < sym_end; - sym++) { - if (sym->st_shndx == SHN_COMMON) { - /* align symbol */ - align = sym->st_value; - offset = bss_section->data_offset; - offset = (offset + align - 1) & -align; - sym->st_value = offset; - sym->st_shndx = bss_section->sh_num; - offset += sym->st_size; - bss_section->data_offset = offset; - } - } -} - -/* relocate symbol table, resolve undefined symbols if do_resolve is - true and output error if undefined symbol. */ -static void relocate_syms(TCCState *s1, int do_resolve) -{ - ElfW(Sym) *sym, *esym, *sym_end; - int sym_bind, sh_num, sym_index; - const char *name; - unsigned long addr; - - sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); - for(sym = (ElfW(Sym) *)symtab_section->data + 1; - sym < sym_end; - sym++) { - sh_num = sym->st_shndx; - if (sh_num == SHN_UNDEF) { - name = strtab_section->data + sym->st_name; - if (do_resolve) { - name = symtab_section->link->data + sym->st_name; - addr = (unsigned long)resolve_sym(s1, name, ELF64_ST_TYPE(sym->st_info)); - if (addr) { - sym->st_value = addr; - goto found; - } - } else if (s1->dynsym) { - /* if dynamic symbol exist, then use it */ - sym_index = find_elf_sym(s1->dynsym, name); - if (sym_index) { - esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index]; - sym->st_value = esym->st_value; - 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 = ELF64_ST_BIND(sym->st_info); - if (sym_bind == STB_WEAK) { - sym->st_value = 0; - } else { - 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: ; - } -} - -#ifdef TCC_TARGET_X86_64 -#define JMP_TABLE_ENTRY_SIZE 14 -static unsigned long add_jmp_table(TCCState *s1, unsigned long val) -{ - char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset; - s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE; - /* jmp *0x0(%rip) */ - p[0] = 0xff; - p[1] = 0x25; - *(int *)(p + 2) = 0; - *(unsigned long *)(p + 6) = val; - return (unsigned long)p; -} - -static unsigned long add_got_table(TCCState *s1, unsigned long val) -{ - unsigned long *p =(unsigned long *)(s1->runtime_plt_and_got + - s1->runtime_plt_and_got_offset); - s1->runtime_plt_and_got_offset += sizeof(void *); - *p = val; - return (unsigned long)p; -} -#endif - -/* relocate a given section (CPU dependent) */ -static void relocate_section(TCCState *s1, Section *s) -{ - Section *sr; - ElfW_Rel *rel, *rel_end, *qrel; - ElfW(Sym) *sym; - int type, sym_index; - unsigned char *ptr; - unsigned long val, addr; -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 - int esym_index; -#endif - - sr = s->reloc; - rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); - qrel = (ElfW_Rel *)sr->data; - for(rel = qrel; - rel < rel_end; - rel++) { - ptr = s->data + rel->r_offset; - - sym_index = ELF64_R_SYM(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - val = sym->st_value; -#ifdef TCC_TARGET_X86_64 - /* XXX: not tested */ - val += rel->r_addend; -#endif - type = ELF64_R_TYPE(rel->r_info); - addr = s->sh_addr + rel->r_offset; - - /* CPU specific */ - switch(type) { -#if defined(TCC_TARGET_I386) - case R_386_32: - if (s1->output_type == TCC_OUTPUT_DLL) { - esym_index = s1->symtab_to_dynsym[sym_index]; - qrel->r_offset = rel->r_offset; - if (esym_index) { - qrel->r_info = ELF64_R_INFO(esym_index, R_386_32); - qrel++; - break; - } else { - qrel->r_info = ELF64_R_INFO(0, R_386_RELATIVE); - qrel++; - } - } - *(int *)ptr += val; - break; - case R_386_PC32: - if (s1->output_type == TCC_OUTPUT_DLL) { - /* DLL relocation */ - esym_index = s1->symtab_to_dynsym[sym_index]; - if (esym_index) { - qrel->r_offset = rel->r_offset; - qrel->r_info = ELF64_R_INFO(esym_index, R_386_PC32); - qrel++; - break; - } - } - *(int *)ptr += val - addr; - break; - case R_386_PLT32: - *(int *)ptr += val - addr; - break; - case R_386_GLOB_DAT: - case R_386_JMP_SLOT: - *(int *)ptr = val; - break; - case R_386_GOTPC: - *(int *)ptr += s1->got->sh_addr - addr; - break; - case R_386_GOTOFF: - *(int *)ptr += val - s1->got->sh_addr; - break; - case R_386_GOT32: - /* we load the got offset */ - *(int *)ptr += s1->got_offsets[sym_index]; - break; -#elif defined(TCC_TARGET_ARM) - case R_ARM_PC24: - case R_ARM_CALL: - case R_ARM_JUMP24: - case R_ARM_PLT32: - { - int x; - x = (*(int *)ptr)&0xffffff; - (*(int *)ptr) &= 0xff000000; - if (x & 0x800000) - x -= 0x1000000; - x *= 4; - x += val - addr; - if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000) - error("can't relocate value at %x",addr); - x >>= 2; - x &= 0xffffff; - (*(int *)ptr) |= x; - } - break; - 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) - error("can't relocate value at %x",addr); - (*(int *)ptr) |= x & 0x7fffffff; - } - case R_ARM_ABS32: - *(int *)ptr += val; - break; - case R_ARM_BASE_PREL: - *(int *)ptr += s1->got->sh_addr - addr; - break; - case R_ARM_GOTOFF32: - *(int *)ptr += val - s1->got->sh_addr; - break; - case R_ARM_GOT_BREL: - /* we load the got offset */ - *(int *)ptr += s1->got_offsets[sym_index]; - break; - case R_ARM_COPY: - break; - default: - fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n", - type,addr,(unsigned int )ptr,val); - break; -#elif defined(TCC_TARGET_C67) - 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 %lx [%.8x] to %lx\n", - type,addr,(unsigned int )ptr,val); - break; -#elif defined(TCC_TARGET_X86_64) - case R_X86_64_64: - if (s1->output_type == TCC_OUTPUT_DLL) { - qrel->r_info = ELF64_R_INFO(0, R_X86_64_RELATIVE); - qrel->r_addend = *(long long *)ptr + val; - qrel++; - } - *(long long *)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 = ELF64_R_INFO(0, R_X86_64_RELATIVE); - qrel->r_addend = *(int *)ptr + val; - qrel++; - } - *(int *)ptr += val; - break; - case R_X86_64_PC32: { - if (s1->output_type == TCC_OUTPUT_DLL) { - /* DLL relocation */ - esym_index = s1->symtab_to_dynsym[sym_index]; - if (esym_index) { - qrel->r_offset = rel->r_offset; - qrel->r_info = ELF64_R_INFO(esym_index, R_X86_64_PC32); - qrel->r_addend = *(int *)ptr; - qrel++; - break; - } - } - long diff = val - addr; - if (diff <= -2147483647 || diff > 2147483647) { - /* XXX: naive support for over 32bit jump */ - if (s1->output_type == TCC_OUTPUT_MEMORY) { - val = add_jmp_table(s1, val); - diff = val - addr; - } - if (diff <= -2147483647 || diff > 2147483647) { - error("internal error: relocation failed"); - } - } - *(int *)ptr += diff; - } - break; - case R_X86_64_PLT32: - *(int *)ptr += val - addr; - break; - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: - *(int *)ptr = val; - break; - case R_X86_64_GOTPCREL: - if (s1->output_type == TCC_OUTPUT_MEMORY) { - val = add_got_table(s1, val - rel->r_addend) + rel->r_addend; - *(int *)ptr += val - addr; - break; - } - *(int *)ptr += (s1->got->sh_addr - addr + - s1->got_offsets[sym_index] - 4); - break; - case R_X86_64_GOTTPOFF: - *(int *)ptr += val - s1->got->sh_addr; - break; - case R_X86_64_GOT32: - /* we load the got offset */ - *(int *)ptr += s1->got_offsets[sym_index]; - break; -#else -#error unsupported processor -#endif - } - } - /* 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, *rel_end; - - s = s1->sections[sr->sh_info]; - rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); - for(rel = (ElfW_Rel *)sr->data; - rel < rel_end; - 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, *rel_end; - int sym_index, esym_index, type, count; - - count = 0; - rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); - for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) { - sym_index = ELF64_R_SYM(rel->r_info); - type = ELF64_R_TYPE(rel->r_info); - switch(type) { -#if defined(TCC_TARGET_I386) - case R_386_32: -#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 - esym_index = s1->symtab_to_dynsym[sym_index]; - if (esym_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 put_got_offset(TCCState *s1, int index, unsigned long val) -{ - int n; - unsigned long *tab; - - if (index >= s1->nb_got_offsets) { - /* find immediately bigger power of 2 and reallocate array */ - n = 1; - while (index >= n) - n *= 2; - tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long)); - if (!tab) - error("memory full"); - s1->got_offsets = tab; - memset(s1->got_offsets + s1->nb_got_offsets, 0, - (n - s1->nb_got_offsets) * sizeof(unsigned long)); - s1->nb_got_offsets = n; - } - s1->got_offsets[index] = val; -} - -/* XXX: suppress that */ -static void put32(unsigned char *p, uint32_t val) -{ - p[0] = val; - p[1] = val >> 8; - p[2] = val >> 16; - p[3] = val >> 24; -} - -#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \ - defined(TCC_TARGET_X86_64) -static uint32_t get32(unsigned char *p) -{ - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); -} -#endif - -static void build_got(TCCState *s1) -{ - unsigned char *ptr; - - /* if no got, then create it */ - s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); - s1->got->sh_entsize = 4; - add_elf_sym(symtab_section, 0, 4, ELF64_ST_INFO(STB_GLOBAL, STT_OBJECT), - 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_"); - ptr = section_ptr_add(s1->got, 3 * PTR_SIZE); -#if PTR_SIZE == 4 - /* keep space for _DYNAMIC pointer, if present */ - put32(ptr, 0); - /* two dummy got entries */ - put32(ptr + 4, 0); - put32(ptr + 8, 0); -#else - /* keep space for _DYNAMIC pointer, if present */ - put32(ptr, 0); - put32(ptr + 4, 0); - /* two dummy got entries */ - put32(ptr + 8, 0); - put32(ptr + 12, 0); - put32(ptr + 16, 0); - put32(ptr + 20, 0); -#endif -} - -/* put a got entry corresponding to a symbol in symtab_section. 'size' - and 'info' can be modifed if more precise info comes from the DLL */ -static void put_got_entry(TCCState *s1, - int reloc_type, unsigned long size, int info, - int sym_index) -{ - int index; - const char *name; - ElfW(Sym) *sym; - unsigned long offset; - int *ptr; - - if (!s1->got) - build_got(s1); - - /* if a got entry already exists for that symbol, no need to add one */ - if (sym_index < s1->nb_got_offsets && - s1->got_offsets[sym_index] != 0) - return; - - put_got_offset(s1, sym_index, s1->got->data_offset); - - if (s1->dynsym) { - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - name = symtab_section->link->data + sym->st_name; - offset = sym->st_value; -#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) - if (reloc_type == -#ifdef TCC_TARGET_X86_64 - R_X86_64_JUMP_SLOT -#else - R_386_JMP_SLOT -#endif - ) { - Section *plt; - uint8_t *p; - int modrm; - -#if defined(TCC_OUTPUT_DLL_WITH_PLT) - modrm = 0x25; -#else - /* if we build a DLL, we add a %ebx offset */ - if (s1->output_type == TCC_OUTPUT_DLL) - modrm = 0xa3; - else - modrm = 0x25; -#endif - - /* add a PLT entry */ - plt = s1->plt; - if (plt->data_offset == 0) { - /* first plt entry */ - p = section_ptr_add(plt, 16); - p[0] = 0xff; /* pushl got + PTR_SIZE */ - p[1] = modrm + 0x10; - put32(p + 2, PTR_SIZE); - p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */ - p[7] = modrm; - put32(p + 8, PTR_SIZE * 2); - } - - p = section_ptr_add(plt, 16); - p[0] = 0xff; /* jmp *(got + x) */ - p[1] = modrm; - put32(p + 2, s1->got->data_offset); - p[6] = 0x68; /* push $xxx */ - put32(p + 7, (plt->data_offset - 32) >> 1); - p[11] = 0xe9; /* jmp plt_start */ - put32(p + 12, -(plt->data_offset)); - - /* the symbol is modified so that it will be relocated to - the PLT */ -#if !defined(TCC_OUTPUT_DLL_WITH_PLT) - if (s1->output_type == TCC_OUTPUT_EXE) -#endif - offset = plt->data_offset - 16; - } -#elif defined(TCC_TARGET_ARM) - if (reloc_type == R_ARM_JUMP_SLOT) { - Section *plt; - uint8_t *p; - - /* if we build a DLL, we add a %ebx offset */ - if (s1->output_type == TCC_OUTPUT_DLL) - error("DLLs unimplemented!"); - - /* add a PLT entry */ - plt = s1->plt; - if (plt->data_offset == 0) { - /* first plt entry */ - p = section_ptr_add(plt, 16); - put32(p , 0xe52de004); - put32(p + 4, 0xe59fe010); - put32(p + 8, 0xe08fe00e); - put32(p + 12, 0xe5bef008); - } - - p = section_ptr_add(plt, 16); - put32(p , 0xe59fc004); - put32(p+4, 0xe08fc00c); - put32(p+8, 0xe59cf000); - put32(p+12, s1->got->data_offset); - - /* the symbol is modified so that it will be relocated to - the PLT */ - if (s1->output_type == TCC_OUTPUT_EXE) - offset = plt->data_offset - 16; - } -#elif defined(TCC_TARGET_C67) - error("C67 got not implemented"); -#else -#error unsupported CPU -#endif - index = put_elf_sym(s1->dynsym, offset, - size, info, 0, sym->st_shndx, name); - /* put a got entry */ - put_elf_reloc(s1->dynsym, s1->got, - s1->got->data_offset, - reloc_type, index); - } - ptr = section_ptr_add(s1->got, PTR_SIZE); - *ptr = 0; -} - -/* build GOT and PLT entries */ -static void build_got_entries(TCCState *s1) -{ - Section *s, *symtab; - ElfW_Rel *rel, *rel_end; - ElfW(Sym) *sym; - int i, type, reloc_type, sym_index; - - 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; - symtab = s->link; - rel_end = (ElfW_Rel *)(s->data + s->data_offset); - for(rel = (ElfW_Rel *)s->data; - rel < rel_end; - rel++) { - type = ELF64_R_TYPE(rel->r_info); - switch(type) { -#if defined(TCC_TARGET_I386) - case R_386_GOT32: - case R_386_GOTOFF: - case R_386_GOTPC: - case R_386_PLT32: - if (!s1->got) - build_got(s1); - if (type == R_386_GOT32 || type == R_386_PLT32) { - sym_index = ELF64_R_SYM(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - /* look at the symbol got offset. If none, then add one */ - if (type == R_386_GOT32) - reloc_type = R_386_GLOB_DAT; - else - reloc_type = R_386_JMP_SLOT; - put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -#elif defined(TCC_TARGET_ARM) - case R_ARM_GOT_BREL: - case R_ARM_GOTOFF32: - case R_ARM_BASE_PREL: - case R_ARM_PLT32: - if (!s1->got) - build_got(s1); - if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) { - sym_index = ELF64_R_SYM(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - /* look at the symbol got offset. If none, then add one */ - if (type == R_ARM_GOT_BREL) - reloc_type = R_ARM_GLOB_DAT; - else - reloc_type = R_ARM_JUMP_SLOT; - put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -#elif defined(TCC_TARGET_C67) - case R_C60_GOT32: - case R_C60_GOTOFF: - case R_C60_GOTPC: - case R_C60_PLT32: - if (!s1->got) - build_got(s1); - if (type == R_C60_GOT32 || type == R_C60_PLT32) { - sym_index = ELF64_R_SYM(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - /* look at the symbol got offset. If none, then add one */ - if (type == R_C60_GOT32) - reloc_type = R_C60_GLOB_DAT; - else - reloc_type = R_C60_JMP_SLOT; - put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -#elif defined(TCC_TARGET_X86_64) - case R_X86_64_GOT32: - case R_X86_64_GOTTPOFF: - case R_X86_64_GOTPCREL: - case R_X86_64_PLT32: - if (!s1->got) - build_got(s1); - if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL || - type == R_X86_64_PLT32) { - sym_index = ELF64_R_SYM(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - /* look at the symbol got offset. If none, then add one */ - if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL) - reloc_type = R_X86_64_GLOB_DAT; - else - reloc_type = R_X86_64_JUMP_SLOT; - put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -#else -#error unsupported CPU -#endif - default: - break; - } - } - } -} - -static 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; -} - -/* put dynamic tag */ -static void put_dt(Section *dynamic, int dt, unsigned long val) -{ - ElfW(Dyn) *dyn; - dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn))); - dyn->d_tag = dt; - dyn->d_un.d_val = val; -} - -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; - } - - add_elf_sym(symtab_section, - 0, 0, - ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, sym_start); - add_elf_sym(symtab_section, - end_offset, 0, - ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, sym_end); -} - -/* add tcc runtime libraries */ -static void tcc_add_runtime(TCCState *s1) -{ -#if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC) - char buf[1024]; -#endif - -#ifdef CONFIG_TCC_BCHECK - if (s1->do_bounds_check) { - unsigned long *ptr; - Section *init_section; - unsigned char *pinit; - int sym_index; - - /* XXX: add an object file to do that */ - ptr = section_ptr_add(bounds_section, sizeof(unsigned long)); - *ptr = 0; - add_elf_sym(symtab_section, 0, 0, - ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - bounds_section->sh_num, "__bounds_start"); - /* add bound check code */ - snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "bcheck.o"); - tcc_add_file(s1, buf); -#ifdef TCC_TARGET_I386 - if (s1->output_type != TCC_OUTPUT_MEMORY) { - /* add 'call __bound_init()' in .init section */ - init_section = find_section(s1, ".init"); - pinit = section_ptr_add(init_section, 5); - pinit[0] = 0xe8; - put32(pinit + 1, -4); - sym_index = find_elf_sym(symtab_section, "__bound_init"); - put_elf_reloc(symtab_section, init_section, - init_section->data_offset - 4, R_386_PC32, sym_index); - } -#endif - } -#endif - /* add libc */ - if (!s1->nostdlib) { - tcc_add_library(s1, "c"); - -#ifdef CONFIG_USE_LIBGCC - tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1"); -#else - snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "libtcc1.a"); - tcc_add_file(s1, buf); -#endif - } - /* add crt end if not memory output */ - if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) { - tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/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; - - add_elf_sym(symtab_section, - text_section->data_offset, 0, - ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - text_section->sh_num, "_etext"); - add_elf_sym(symtab_section, - data_section->data_offset, 0, - ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - data_section->sh_num, "_edata"); - add_elf_sym(symtab_section, - bss_section->data_offset, 0, - ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - bss_section->sh_num, "_end"); - /* 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"); - - /* 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); - add_elf_sym(symtab_section, - 0, 0, - ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, buf); - snprintf(buf, sizeof(buf), "__stop_%s", s->name); - add_elf_sym(symtab_section, - s->data_offset, 0, - ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - s->sh_num, buf); - } - next_sec: ; - } -} - -/* name of ELF interpreter */ -#if defined __FreeBSD__ -static char elf_interp[] = "/usr/libexec/ld-elf.so.1"; -#elif defined TCC_ARM_EABI -static char elf_interp[] = "/lib/ld-linux.so.3"; -#elif defined(TCC_TARGET_X86_64) -static char elf_interp[] = "/lib/ld-linux-x86-64.so.2"; -#elif defined(TCC_UCLIBC) -static char elf_interp[] = "/lib/ld-uClibc.so.0"; -#else -static char elf_interp[] = "/lib/ld-linux.so.2"; -#endif - -static void tcc_output_binary(TCCState *s1, FILE *f, - const int *section_order) -{ - Section *s; - int i, offset, size; - - offset = 0; - for(i=1;inb_sections;i++) { - s = s1->sections[section_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; - } - } -} - -/* output an ELF file */ -/* XXX: suppress unneeded sections */ -int elf_output_file(TCCState *s1, const char *filename) -{ - ElfW(Ehdr) ehdr; - FILE *f; - int fd, mode, ret; - int *section_order; - int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k; - unsigned long addr; - Section *strsec, *s; - ElfW(Shdr) shdr, *sh; - ElfW(Phdr) *phdr, *ph; - Section *interp, *dynamic, *dynstr; - unsigned long saved_dynamic_data_offset; - ElfW(Sym) *sym; - int type, file_type; - unsigned long rel_addr, rel_size; - - file_type = s1->output_type; - s1->nb_errors = 0; - - if (file_type != TCC_OUTPUT_OBJ) { - tcc_add_runtime(s1); - } - - phdr = NULL; - section_order = NULL; - interp = NULL; - dynamic = NULL; - dynstr = NULL; /* avoid warning */ - saved_dynamic_data_offset = 0; /* avoid warning */ - - if (file_type != TCC_OUTPUT_OBJ) { - relocate_common_syms(); - - tcc_add_linker_symbols(s1); - - if (!s1->static_link) { - const char *name; - int sym_index, index; - ElfW(Sym) *esym, *sym_end; - - if (file_type == TCC_OUTPUT_EXE) { - char *ptr; - /* add interpreter section only if executable */ - interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC); - interp->sh_addralign = 1; - ptr = section_ptr_add(interp, sizeof(elf_interp)); - strcpy(ptr, elf_interp); - } - - /* 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)); - - /* add PLT */ - s1->plt = new_section(s1, ".plt", SHT_PROGBITS, - SHF_ALLOC | SHF_EXECINSTR); - s1->plt->sh_entsize = 4; - - build_got(s1); - - /* scan for undefined symbols and see if they are in the - dynamic symbols. If a symbol STT_FUNC is found, then we - add it in the PLT. If a symbol STT_OBJECT is found, we - add it in the .bss section with a suitable relocation */ - sym_end = (ElfW(Sym) *)(symtab_section->data + - symtab_section->data_offset); - if (file_type == TCC_OUTPUT_EXE) { - for(sym = (ElfW(Sym) *)symtab_section->data + 1; - sym < sym_end; - sym++) { - if (sym->st_shndx == SHN_UNDEF) { - name = 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 = ELF64_ST_TYPE(esym->st_info); - if (type == STT_FUNC) { - put_got_entry(s1, R_JMP_SLOT, esym->st_size, - esym->st_info, - sym - (ElfW(Sym) *)symtab_section->data); - } else if (type == STT_OBJECT) { - unsigned long offset; - offset = bss_section->data_offset; - /* XXX: which alignment ? */ - offset = (offset + 16 - 1) & -16; - index = put_elf_sym(s1->dynsym, offset, esym->st_size, - esym->st_info, 0, - bss_section->sh_num, name); - 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 (ELF64_ST_BIND(sym->st_info) == STB_WEAK || - !strcmp(name, "_fp_hw")) { - } else { - error_noabort("undefined symbol '%s'", name); - } - } - } else if (s1->rdynamic && - ELF64_ST_BIND(sym->st_info) != STB_LOCAL) { - /* if -rdynamic option, then export all non - local symbols */ - name = symtab_section->link->data + sym->st_name; - put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, - sym->st_info, 0, - sym->st_shndx, name); - } - } - - if (s1->nb_errors) - goto fail; - - /* now look at unresolved dynamic symbols and export - corresponding symbol */ - sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data + - s1->dynsymtab_section->data_offset); - for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1; - esym < sym_end; - esym++) { - if (esym->st_shndx == SHN_UNDEF) { - name = s1->dynsymtab_section->link->data + esym->st_name; - sym_index = find_elf_sym(symtab_section, name); - if (sym_index) { - /* XXX: avoid adding a symbol if already - present because of -rdynamic ? */ - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, - sym->st_info, 0, - sym->st_shndx, name); - } else { - if (ELF64_ST_BIND(esym->st_info) == STB_WEAK) { - /* weak symbols can stay undefined */ - } else { - warning("undefined dynamic symbol '%s'", name); - } - } - } - } - } else { - int nb_syms; - /* shared library case : we simply export all the global symbols */ - nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym)); - s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms); - for(sym = (ElfW(Sym) *)symtab_section->data + 1; - sym < sym_end; - sym++) { - if (ELF64_ST_BIND(sym->st_info) != STB_LOCAL) { -#if defined(TCC_OUTPUT_DLL_WITH_PLT) - if (ELF64_ST_TYPE(sym->st_info) == STT_FUNC && - sym->st_shndx == SHN_UNDEF) { - put_got_entry(s1, R_JMP_SLOT, sym->st_size, - sym->st_info, - sym - (ElfW(Sym) *)symtab_section->data); - } - else if (ELF64_ST_TYPE(sym->st_info) == STT_OBJECT) { - put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size, - sym->st_info, - sym - (ElfW(Sym) *)symtab_section->data); - } - else -#endif - { - name = symtab_section->link->data + sym->st_name; - index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, - sym->st_info, 0, - sym->st_shndx, name); - s1->symtab_to_dynsym[sym - - (ElfW(Sym) *)symtab_section->data] = - index; - } - } - } - } - - build_got_entries(s1); - - /* 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)); - } - /* XXX: currently, since we do not handle PIC code, we - must relocate the readonly segments */ - if (file_type == TCC_OUTPUT_DLL) { - if (s1->soname) - put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname)); - put_dt(dynamic, DT_TEXTREL, 0); - } - - /* add necessary space for other entries */ - saved_dynamic_data_offset = dynamic->data_offset; - dynamic->data_offset += sizeof(ElfW(Dyn)) * 9; - } else { - /* still need to build got entries in case of static link */ - build_got_entries(s1); - } - } - - memset(&ehdr, 0, sizeof(ehdr)); - - /* we add a section for symbols */ - strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); - put_elf_str(strsec, ""); - - /* compute number of sections */ - shnum = s1->nb_sections; - - /* this array is used to reorder sections in the output file */ - section_order = tcc_malloc(sizeof(int) * shnum); - section_order[0] = 0; - sh_order_index = 1; - - /* compute number of program headers */ - switch(file_type) { - case TCC_OUTPUT_EXE: - if (!s1->static_link) - phnum = 4; - else - phnum = 2; - break; - case TCC_OUTPUT_DLL: - phnum = 3; - break; - case TCC_OUTPUT_OBJ: - default: - phnum = 0; - break; - } - - /* 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 ! */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - s->sh_name = put_elf_str(strsec, s->name); -#if 0 //gr - printf("section: f=%08x t=%08x i=%08x %s %s\n", - s->sh_flags, - s->sh_type, - s->sh_info, - s->name, - s->reloc ? s->reloc->name : "n" - ); -#endif - /* 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)) { - /* //gr: avoid bogus relocs for empty (debug) sections */ - if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) - prepare_dynamic_rel(s1, s); - else if (s1->do_debug) - s->sh_size = s->data_offset; - } 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; - } - } - - /* allocate program segment headers */ - phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); - - if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { - file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); - } else { - file_offset = 0; - } - if (phnum > 0) { - /* compute section to program header mapping */ - 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 = addr & (ELF_PAGE_SIZE - 1); - p_offset = file_offset & (ELF_PAGE_SIZE - 1); - if (a_offset < p_offset) - a_offset += ELF_PAGE_SIZE; - 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 & (ELF_PAGE_SIZE - 1)); - } - - /* dynamic relocation table information, for .dynamic section */ - rel_size = 0; - rel_addr = 0; - - /* leave one program header for the program interpreter */ - ph = &phdr[0]; - if (interp) - ph++; - - 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 = ELF_PAGE_SIZE; - - /* 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; - } - section_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 += 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 (rel_size == 0) - rel_addr = addr; - rel_size += s->sh_size; - } - addr += s->sh_size; - if (s->sh_type != SHT_NOBITS) - file_offset += s->sh_size; - } - } - 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 & (ELF_PAGE_SIZE - 1)) != 0) - addr += ELF_PAGE_SIZE; - } else { - addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1); - file_offset = (file_offset + ELF_PAGE_SIZE - 1) & - ~(ELF_PAGE_SIZE - 1); - } - } - } - - /* if interpreter, then add corresponing program header */ - if (interp) { - ph = &phdr[0]; - - 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 corresponing program header */ - if (dynamic) { - ElfW(Sym) *sym_end; - - 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; - - /* put GOT dynamic section address */ - put32(s1->got->data, dynamic->sh_addr); - - /* relocate the PLT */ - if (file_type == TCC_OUTPUT_EXE -#if defined(TCC_OUTPUT_DLL_WITH_PLT) - || file_type == TCC_OUTPUT_DLL -#endif - ) { - uint8_t *p, *p_end; - - p = s1->plt->data; - p_end = p + s1->plt->data_offset; - if (p < p_end) { -#if defined(TCC_TARGET_I386) - put32(p + 2, get32(p + 2) + s1->got->sh_addr); - put32(p + 8, get32(p + 8) + s1->got->sh_addr); - p += 16; - while (p < p_end) { - put32(p + 2, get32(p + 2) + s1->got->sh_addr); - p += 16; - } -#elif defined(TCC_TARGET_X86_64) - int x = s1->got->sh_addr - s1->plt->sh_addr - 6; - put32(p + 2, get32(p + 2) + x); - put32(p + 8, get32(p + 8) + x - 6); - p += 16; - while (p < p_end) { - put32(p + 2, get32(p + 2) + x + s1->plt->data - p); - p += 16; - } -#elif defined(TCC_TARGET_ARM) - int x; - x=s1->got->sh_addr - s1->plt->sh_addr - 12; - p +=16; - while (p < p_end) { - put32(p + 12, x + get32(p + 12) + s1->plt->data - p); - p += 16; - } -#elif defined(TCC_TARGET_C67) - /* XXX: TODO */ -#else -#error unsupported CPU -#endif - } - } - - /* relocate symbols in .dynsym */ - sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset); - for(sym = (ElfW(Sym) *)s1->dynsym->data + 1; - sym < sym_end; - sym++) { - if (sym->st_shndx == SHN_UNDEF) { - /* relocate to the PLT if the symbol corresponds - to a PLT entry */ - if (sym->st_value) - sym->st_value += s1->plt->sh_addr; - } else if (sym->st_shndx < SHN_LORESERVE) { - /* do symbol relocation */ - sym->st_value += s1->sections[sym->st_shndx]->sh_addr; - } - } - - /* put dynamic section entries */ - dynamic->data_offset = saved_dynamic_data_offset; - put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr); - put_dt(dynamic, DT_STRTAB, dynstr->sh_addr); - put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr); - put_dt(dynamic, DT_STRSZ, dynstr->data_offset); - put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym))); -#ifdef TCC_TARGET_X86_64 - put_dt(dynamic, DT_RELA, rel_addr); - put_dt(dynamic, DT_RELASZ, rel_size); - put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel)); -#else - put_dt(dynamic, DT_REL, rel_addr); - put_dt(dynamic, DT_RELSZ, rel_size); - put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel)); -#endif - if (s1->do_debug) - put_dt(dynamic, DT_DEBUG, 0); - put_dt(dynamic, DT_NULL, 0); - } - - ehdr.e_phentsize = sizeof(ElfW(Phdr)); - ehdr.e_phnum = phnum; - ehdr.e_phoff = sizeof(ElfW(Ehdr)); - } - - /* 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; - section_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; - } - - /* if building executable or DLL, then relocate each section - except the GOT which is already relocated */ - if (file_type != TCC_OUTPUT_OBJ) { - relocate_syms(s1, 0); - - if (s1->nb_errors != 0) { - fail: - ret = -1; - goto the_end; - } - - /* relocate sections */ - /* XXX: ignore sections with allocated relocations ? */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr - 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); - } - } - - /* get entry point address */ - if (file_type == TCC_OUTPUT_EXE) - ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start"); - else - ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ - } - - /* write elf file */ - if (file_type == TCC_OUTPUT_OBJ) - mode = 0666; - else - mode = 0777; - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); - if (fd < 0) { - error_noabort("could not write '%s'", filename); - goto fail; - } - 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) { - sort_syms(s1, symtab_section); - - /* 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] = TCC_ELFCLASS; - ehdr.e_ident[5] = ELFDATA2LSB; - ehdr.e_ident[6] = EV_CURRENT; -#ifdef __FreeBSD__ - 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 = 4 << 24; -#else - ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM; -#endif -#endif - switch(file_type) { - case TCC_OUTPUT_DLL: - ehdr.e_type = ET_DYN; - break; - case TCC_OUTPUT_OBJ: - ehdr.e_type = ET_REL; - break; - case TCC_OUTPUT_EXE: - default: - ehdr.e_type = ET_EXEC; - 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)); - - for(i=1;inb_sections;i++) { - s = s1->sections[section_order[i]]; - if (s->sh_type != SHT_NOBITS) { - while (offset < s->sh_offset) { - fputc(0, f); - offset++; - } - size = s->sh_size; - fwrite(s->data, 1, size, f); - offset += size; - } - } - - /* output section headers */ - while (offset < ehdr.e_shoff) { - fputc(0, f); - offset++; - } - - for(i=0;inb_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); - } - } else { - tcc_output_binary(s1, f, section_order); - } - fclose(f); - - ret = 0; - the_end: - tcc_free(s1->symtab_to_dynsym); - tcc_free(section_order); - tcc_free(phdr); - tcc_free(s1->got_offsets); - return ret; -} - -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; - -/* load an object file and merge it with current files */ -/* XXX: handle correctly stab (debug) info */ -static 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; - unsigned char *strsec, *strtab; - int *old_to_new_syms; - char *sh_name, *name; - SectionMergeInfo *sm_table, *sm; - ElfW(Sym) *sym, *symtab; - ElfW_Rel *rel, *rel_end; - Section *s; - - int stab_index; - int stabstr_index; - - stab_index = stabstr_index = 0; - - if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) - goto fail1; - if (ehdr.e_ident[0] != ELFMAG0 || - ehdr.e_ident[1] != ELFMAG1 || - ehdr.e_ident[2] != ELFMAG2 || - ehdr.e_ident[3] != ELFMAG3) - goto fail1; - /* test if object file */ - if (ehdr.e_type != ET_REL) - goto fail1; - /* test CPU specific stuff */ - if (ehdr.e_ident[5] != ELFDATA2LSB || - ehdr.e_machine != EM_TCC_TARGET) { - fail1: - 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; - for(i = 1; i < ehdr.e_shnum; i++) { - sh = &shdr[i]; - if (sh->sh_type == SHT_SYMTAB) { - if (symtab) { - 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); - } - } - - /* 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 = 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 && - strcmp(sh_name, ".stabstr") - ) - 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); - /* 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) { - 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 (ELF64_ST_BIND(sym->st_info) != STB_LOCAL) { - name = 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 = strtab + sym->st_name; - sym_index = add_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; - rel_end = (ElfW_Rel *)(s->data + s->data_offset); - for(rel = (ElfW_Rel *)(s->data + offset); - rel < rel_end; - rel++) { - int type; - unsigned sym_index; - /* convert symbol index */ - type = ELF64_R_TYPE(rel->r_info); - sym_index = ELF64_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) { - invalid_reloc: - error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x", - i, strsec + sh->sh_name, rel->r_offset); - goto fail; - } - rel->r_info = ELF64_R_INFO(sym_index, type); - /* offset the relocation offset */ - rel->r_offset += offseti; - } - 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; -} - -#define ARMAG "!\012" /* For COFF and a.out archives */ - -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); -} - -/* load only the objects which resolve undefined symbols */ -static int tcc_load_alacarte(TCCState *s1, int fd, int size) -{ - int 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 = get_be32(data); - ar_index = data + 4; - ar_names = ar_index + nsyms * 4; - - 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 = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader); -#if 0 - printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx); -#endif - ++bound; - lseek(fd, off, SEEK_SET); - 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 */ -static 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)) { - 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'; - // printf("name='%s' size=%d %s\n", ar_name, size, ar_size); - 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); - } else if (!strcmp(ar_name, "//") || - !strcmp(ar_name, "__.SYMDEF") || - !strcmp(ar_name, "__.SYMDEF/") || - !strcmp(ar_name, "ARFILENAMES/")) { - /* skip symbol table or archive names */ - } else { - if (tcc_load_object_file(s1, fd, file_offset) < 0) - return -1; - } - lseek(fd, file_offset + size, SEEK_SET); - } - return 0; -} - -/* 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) */ -static 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) { - 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 = 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; - } - } - - // printf("loading dll '%s'\n", soname); - - /* add the dll and its level */ - dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname)); - dllref->level = level; - strcpy(dllref->name, soname); - dynarray_add((void ***)&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 = ELF64_ST_BIND(sym->st_info); - if (sym_bind == STB_LOCAL) - continue; - name = dynstr + sym->st_name; - add_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 = 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) { - 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 '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 '$': - 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; - } -#if 0 - printf("tok=%c %d\n", c, c); - if (c == LD_TOK_NAME) - printf(" name=%s\n", name); -#endif - return c; -} - -static int ld_add_file_list(TCCState *s1, int as_needed) -{ - char filename[1024]; - int t, ret; - - t = ld_next(s1, filename, sizeof(filename)); - if (t != '(') - expect("("); - t = ld_next(s1, filename, sizeof(filename)); - for(;;) { - if (t == LD_TOK_EOF) { - error_noabort("unexpected end of file"); - return -1; - } else if (t == ')') { - break; - } else if (t != LD_TOK_NAME) { - error_noabort("filename expected"); - return -1; - } - if (!strcmp(filename, "AS_NEEDED")) { - ret = ld_add_file_list(s1, 1); - if (ret) - return ret; - } else { - /* TODO: Implement AS_NEEDED support. Ignore it for now */ - if (!as_needed) - tcc_add_file(s1, filename); - } - t = ld_next(s1, filename, sizeof(filename)); - if (t == ',') { - t = ld_next(s1, filename, sizeof(filename)); - } - } - return 0; -} - -/* interpret a subset of GNU ldscripts to handle the dummy libc.so - files */ -static int tcc_load_ldscript(TCCState *s1) -{ - char cmd[64]; - char filename[1024]; - int t, ret; - - ch = file->buf_ptr[0]; - 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, 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) { - error_noabort("unexpected end of file"); - return -1; - } else if (t == ')') { - break; - } - } - } else { - return -1; - } - } - return 0; -} diff --git a/05/tcc-0.9.25/tccgen.c b/05/tcc-0.9.25/tccgen.c deleted file mode 100644 index 860e580..0000000 --- a/05/tcc-0.9.25/tccgen.c +++ /dev/null @@ -1,5123 +0,0 @@ -/* - * 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 - */ - -void swap(int *p, int *q) -{ - int t; - t = *p; - *p = *q; - *q = t; -} - -void vsetc(CType *type, int r, CValue *vc) -{ - int v; - - if (vtop >= vstack + (VSTACK_SIZE - 1)) - error("memory full"); - /* 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. */ - if (vtop >= vstack) { - 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; -} - -/* push integer constant */ -void vpushi(int v) -{ - CValue cval; - cval.i = v; - vsetc(&int_type, VT_CONST, &cval); -} - -/* push long long constant */ -void vpushll(long long v) -{ - CValue cval; - CType ctype; - ctype.t = VT_LLONG; - cval.ull = v; - vsetc(&ctype, VT_CONST, &cval); -} - -/* Return a static symbol pointing to a section */ -static 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) -{ - CValue cval; - - cval.ul = 0; - vsetc(type, VT_CONST | VT_SYM, &cval); - vtop->sym = get_sym_ref(type, sec, offset, size); -} - -/* define a new external reference to a symbol 'v' of type 'u' */ -static 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; - } - return s; -} - -/* define a new external reference to a symbol 'v' of type 'u' */ -static Sym *external_sym(int v, CType *type, int r) -{ - 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; - } else { - if (!is_compatible_types(&s->type, type)) - error("incompatible types for redefinition of '%s'", - get_tok_str(v, NULL)); - } - return s; -} - -/* push a reference to global symbol v */ -static void vpush_global_sym(CType *type, int v) -{ - Sym *sym; - CValue cval; - - sym = external_global_sym(v, type, 0); - cval.ul = 0; - vsetc(type, VT_CONST | VT_SYM, &cval); - vtop->sym = sym; -} - -void vset(CType *type, int r, int v) -{ - CValue cval; - - cval.i = v; - vsetc(type, r, &cval); -} - -void vseti(int r, int v) -{ - CType type; - type.t = VT_INT; - vset(&type, r, v); -} - -void vswap(void) -{ - SValue tmp; - - tmp = vtop[0]; - vtop[0] = vtop[-1]; - vtop[-1] = tmp; -} - -void vpushv(SValue *v) -{ - if (vtop >= vstack + (VSTACK_SIZE - 1)) - error("memory full"); - vtop++; - *vtop = *v; -} - -void vdup(void) -{ - vpushv(vtop); -} - -/* save r to the memory stack, and mark it as being free */ -void save_reg(int r) -{ - int l, saved, size, align; - SValue *p, sv; - CType *type; - - /* modify all stack values */ - saved = 0; - l = 0; - for(p=vstack;p<=vtop;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)) -#ifdef TCC_TARGET_X86_64 - 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.ul = 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(0xd9dd); /* fstp %st(1) */ - } -#endif -#ifndef TCC_TARGET_X86_64 - /* special long long case */ - if ((type->t & VT_BTYPE) == VT_LLONG) { - sv.c.ul += 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.ul */ - 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.ul = l; - } - } -} - -/* find a register of class 'rc2' with at most one reference on stack. - * If none, call get_reg(rc) */ -int get_reg_ex(int rc, int rc2) -{ - int r; - SValue *p; - - for(r=0;rr & VT_VALMASK) == r || - (p->r2 & VT_VALMASK) == r) - n++; - } - if (n <= 1) - return r; - } - } - return get_reg(rc); -} - -/* find a free register of class 'rc'. If none, save one register */ -int get_reg(int rc) -{ - int r; - SValue *p; - - /* find a free register */ - for(r=0;rr & 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++) { - r = p->r & VT_VALMASK; - if (r < VT_CONST && (reg_classes[r] & rc)) - goto save_found; - /* also look at second register (if long long) */ - r = p->r2 & VT_VALMASK; - if (r < VT_CONST && (reg_classes[r] & rc)) { - save_found: - save_reg(r); - return r; - } - } - /* Should never comes here */ - return -1; -} - -/* save registers up to (vtop - n) stack entry */ -void save_regs(int n) -{ - int r; - SValue *p, *p1; - p1 = vtop - n; - for(p = vstack;p <= p1; p++) { - r = p->r & VT_VALMASK; - if (r < VT_CONST) { - save_reg(r); - } - } -} - -/* move register 's' to 'r', and flush previous value of r to memory - if needed */ -void move_reg(int r, int s) -{ - SValue sv; - - if (r != s) { - save_reg(r); - sv.type.t = VT_INT; - sv.r = s; - sv.c.ul = 0; - load(r, &sv); - } -} - -/* get address of vtop (vtop MUST BE an lvalue) */ -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 */ -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_INT; - gaddrof(); - vpushi(0); - gen_bounded_ptr_add(); - vtop->r |= lval_type; - vtop->type = type1; - } - /* then check for dereferencing */ - gen_bounded_ptr_deref(); - } -} -#endif - -/* 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). */ -int gv(int rc) -{ - int r, rc2, bit_pos, bit_size, size, align, i; - - /* NOTE: get_reg can modify vstack[] */ - if (vtop->type.t & VT_BITFIELD) { - CType type; - int bits = 32; - bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; - bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; - /* remove bit field info to avoid loops */ - vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); - /* cast to int to propagate signedness in following ops */ - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - type.t = VT_LLONG; - bits = 64; - } else - type.t = VT_INT; - if((vtop->type.t & VT_UNSIGNED) || - (vtop->type.t & VT_BTYPE) == VT_BOOL) - type.t |= VT_UNSIGNED; - 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) { - Sym *sym; - int *ptr; - unsigned long offset; -#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP) - CValue check; -#endif - - /* XXX: unify with initializers handling ? */ - /* CPUs usually cannot use float constants, so we store them - generically in data segment */ - size = type_size(&vtop->type, &align); - offset = (data_section->data_offset + align - 1) & -align; - data_section->data_offset = offset; - /* XXX: not portable yet */ -#if defined(__i386__) || defined(__x86_64__) - /* Zero pad x87 tenbyte long doubles */ - if (size == LDOUBLE_SIZE) - vtop->c.tab[2] &= 0xffff; -#endif - ptr = section_ptr_add(data_section, size); - size = size >> 2; -#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP) - check.d = 1; - if(check.tab[0]) - for(i=0;ic.tab[size-1-i]; - else -#endif - for(i=0;ic.tab[i]; - sym = get_sym_ref(&vtop->type, data_section, offset, size << 2); - vtop->r |= VT_LVAL | VT_SYM; - vtop->sym = sym; - vtop->c.ul = 0; - } -#ifdef CONFIG_TCC_BCHECK - if (vtop->r & VT_MUSTBOUND) - gbound(); -#endif - - r = vtop->r & VT_VALMASK; - rc2 = RC_INT; - if (rc == RC_IRET) - rc2 = RC_LRET; - /* 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) || - ((vtop->type.t & VT_BTYPE) == VT_LLONG && - !(reg_classes[vtop->r2] & rc2))) { - r = get_reg(rc); -#ifndef TCC_TARGET_X86_64 - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - int r2; - unsigned long long ll; - /* two register type load : expand to two words - temporarily */ - if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - /* load constant */ - ll = vtop->c.ull; - vtop->c.ui = ll; /* first word */ - load(r, vtop); - vtop->r = r; /* save register value */ - vpushi(ll >> 32); /* second word */ - } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */ - (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. */ - save_regs(1); - /* load from memory */ - load(r, vtop); - vdup(); - vtop[-1].r = r; /* save register value */ - /* increment pointer to get second word */ - vtop->type.t = VT_INT; - gaddrof(); - vpushi(4); - gen_op('+'); - vtop->r |= VT_LVAL; - } else { - /* move registers */ - load(r, vtop); - vdup(); - vtop[-1].r = r; /* save register value */ - vtop->r = vtop[-1].r2; - } - /* allocate second register */ - r2 = get_reg(rc2); - load(r2, vtop); - vpop(); - /* write second register */ - vtop->r2 = r2; - } else -#endif - 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 */ -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); - } - } -} - -/* wrapper around RC_FRET to return a register by type */ -int rc_fret(int t) -{ -#ifdef TCC_TARGET_X86_64 - if (t == VT_LDOUBLE) { - return RC_ST0; - } -#endif - return RC_FRET; -} - -/* wrapper around REG_FRET to return a register by type */ -int reg_fret(int t) -{ -#ifdef TCC_TARGET_X86_64 - if (t == VT_LDOUBLE) { - return TREG_ST0; - } -#endif - return REG_FRET; -} - -/* expand long long on stack in two int registers */ -void lexpand(void) -{ - int u; - - u = vtop->type.t & VT_UNSIGNED; - gv(RC_INT); - vdup(); - vtop[0].r = vtop[-1].r2; - vtop[0].r2 = VT_CONST; - vtop[-1].r2 = VT_CONST; - vtop[0].type.t = VT_INT | u; - vtop[-1].type.t = VT_INT | u; -} - -#ifdef TCC_TARGET_ARM -/* expand long long on stack */ -void lexpand_nr(void) -{ - int u,v; - - u = vtop->type.t & 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.ui = vtop->c.ull; - vtop->c.ui = vtop->c.ull >> 32; - vtop->r = VT_CONST; - } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) { - vtop->c.ui += 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 - -/* build a long long from two ints */ -void lbuild(int t) -{ - gv2(RC_INT, RC_INT); - vtop[-1].r2 = vtop[0].r; - vtop[-1].type.t = t; - vpop(); -} - -/* rotate n first stack elements to the bottom - I1 ... In -> I2 ... In I1 [top is right] -*/ -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 n first stack elements to the top - I1 ... In -> In I1 ... I(n-1) [top is right] - */ -void vrott(int n) -{ - int i; - SValue tmp; - - tmp = vtop[0]; - for(i = 0;i < n - 1; i++) - vtop[-i] = vtop[-i - 1]; - vtop[-n + 1] = tmp; -} - -#ifdef TCC_TARGET_ARM -/* like vrott but in other direction - In ... I1 -> I(n-1) ... I1 In [top is right] - */ -void vnrott(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; -} -#endif - -/* pop stack value */ -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 && !nocode_wanted) { - o(0xd9dd); /* fstp %st(1) */ - } else -#endif - if (v == VT_JMP || v == VT_JMPI) { - /* need to put correct jump if && or || without test */ - gsym(vtop->c.ul); - } - vtop--; -} - -/* convert stack entry to register and duplicate its value in another - register */ -void gv_dup(void) -{ - int rc, t, r, r1; - SValue sv; - - t = vtop->type.t; - if ((t & VT_BTYPE) == VT_LLONG) { - 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 { - /* 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.ul = 0; - load(r1, &sv); /* move r to r1 */ - vdup(); - /* duplicates value */ - vtop->r = r1; - } -} - -#ifndef TCC_TARGET_X86_64 -/* generate CPU independent (unsigned) long long operations */ -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 '-': - 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 */ - 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 swaping 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 (op1 != TOK_NE) { - a = gtst(1, 0); - } - if (op != TOK_EQ) { - /* generate non equal test */ - /* XXX: NOT PORTABLE yet */ - if (a == 0) { - b = gtst(0, 0); - } else { -#if defined(TCC_TARGET_I386) - b = psym(0x850f, 0); -#elif defined(TCC_TARGET_ARM) - b = ind; - o(0x1A000000 | encbranch(ind, 0, 1)); -#elif defined(TCC_TARGET_C67) - error("not implemented"); -#else -#error not supported -#endif - } - } - /* 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 = gtst(1, a); - gsym(b); - vseti(VT_JMPI, a); - break; - } -} -#endif - -typedef unsigned long long _U; - -/* handle integer constant optimizations and various machine - independent opt */ -void gen_opic(int op) -{ - int c1, c2, t1, t2, n; - SValue *v1, *v2; - long long l1, l2; - - v1 = vtop - 1; - v2 = vtop; - t1 = v1->type.t & VT_BTYPE; - t2 = v2->type.t & VT_BTYPE; - - if (t1 == VT_LLONG) - l1 = v1->c.ll; - else if (v1->type.t & VT_UNSIGNED) - l1 = v1->c.ui; - else - l1 = v1->c.i; - - if (t2 == VT_LLONG) - l2 = v2->c.ll; - else if (v2->type.t & VT_UNSIGNED) - l2 = v2->c.ui; - else - l2 = v2->c.i; - - /* 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) { - 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) - error("division by zero in constant"); - goto general_case; - } - switch(op) { - case '%': l1 %= l2; break; - case TOK_UDIV: l1 = (_U)l1 / l2; break; - case TOK_UMOD: l1 = (_U)l1 % l2; break; - default: l1 /= l2; break; - } - break; - case TOK_SHL: l1 <<= l2; break; - case TOK_SHR: l1 = (_U)l1 >> l2; break; - case TOK_SAR: l1 >>= l2; break; - /* tests */ - case TOK_ULT: l1 = (_U)l1 < (_U)l2; break; - case TOK_UGE: l1 = (_U)l1 >= (_U)l2; break; - case TOK_EQ: l1 = l1 == l2; break; - case TOK_NE: l1 = l1 != l2; break; - case TOK_ULE: l1 = (_U)l1 <= (_U)l2; break; - case TOK_UGT: l1 = (_U)l1 > (_U)l2; break; - case TOK_LT: l1 = l1 < l2; break; - case TOK_GE: l1 = l1 >= l2; break; - case TOK_LE: l1 = l1 <= l2; break; - case TOK_GT: l1 = l1 > l2; break; - /* logical */ - case TOK_LAND: l1 = l1 && l2; break; - case TOK_LOR: l1 = l1 || l2; break; - default: - goto general_case; - } - v1->c.ll = 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; - } - /* Filter out NOP operations like x*1, x-0, x&-1... */ - 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))) { - /* nothing to do */ - 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) { - n = -1; - while (l2) { - l2 >>= 1; - n++; - } - vtop->c.ll = 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; - vtop--; - vtop->c.ll += l2; - } else { - general_case: - if (!nocode_wanted) { - /* call low level op generator */ - if (t1 == VT_LLONG || t2 == VT_LLONG) - gen_opl(op); - else - gen_opi(op); - } else { - vtop--; - } - } - } -} - -/* generate a floating point operation with constant propagation */ -void gen_opif(int op) -{ - int c1, c2; - SValue *v1, *v2; - 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) - 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: - if (!nocode_wanted) { - gen_opf(op); - } else { - vtop--; - } - } -} - -static int pointed_size(CType *type) -{ - int align; - return 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 && p->c.i == 0) || - ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 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 substraction 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 ) - 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: - 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_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(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 - warning("comparison of distinct pointer types lacks a cast"); - } -} - -/* generic gen_op: handles types problems */ -void gen_op(int op) -{ - int u, t1, t2, bt1, bt2, t; - CType type1; - - t1 = vtop[-1].type.t; - t2 = vtop[0].type.t; - bt1 = t1 & VT_BTYPE; - bt2 = t2 & VT_BTYPE; - - if (bt1 == VT_PTR || bt2 == VT_PTR) { - /* at least one operand is a pointer */ - /* relationnal 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 */ -#ifdef TCC_TARGET_X86_64 - 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 != '-') - error("cannot use pointers here"); - check_comparison_pointer_types(vtop - 1, vtop, op); - /* XXX: check that types are compatible */ - u = pointed_size(&vtop[-1].type); - gen_opic(op); - /* set to integer type */ -#ifdef TCC_TARGET_X86_64 - vtop->type.t = VT_LLONG; -#else - vtop->type.t = VT_INT; -#endif - vpushi(u); - gen_op(TOK_PDIV); - } else { - /* exactly one pointer : must be '+' or '-'. */ - if (op != '-' && op != '+') - error("cannot use pointers here"); - /* Put pointer as first operand */ - if (bt2 == VT_PTR) { - vswap(); - swap(&t1, &t2); - } - type1 = vtop[-1].type; -#ifdef TCC_TARGET_X86_64 - vpushll(pointed_size(&vtop[-1].type)); -#else - /* XXX: cast to int ? (long long case) */ - vpushi(pointed_size(&vtop[-1].type)); -#endif - gen_op('*'); -#ifdef CONFIG_TCC_BCHECK - /* 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)) - error("invalid operands for binary operation"); - goto std_op; - } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { - /* cast to biggest op */ - t = VT_LLONG; - /* convert to unsigned if it does not fit in a long long */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) - t |= VT_UNSIGNED; - goto std_op; - } else { - /* integer operations */ - t = VT_INT; - /* convert to unsigned if it does not fit in an integer */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (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; - 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) { - /* relationnal op: the result is an int */ - vtop->type.t = VT_INT; - } else { - vtop->type.t = t; - } - } -} - -#ifndef TCC_TARGET_ARM -/* generic itof for unsigned long long case */ -void gen_cvt_itof1(int t) -{ - 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 - -/* generic ftoi for unsigned long long case */ -void gen_cvt_ftoi1(int t) -{ - 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); - } -} - -/* force char or short cast */ -void force_charshort_cast(int t) -{ - int bits, dbt; - 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 { - 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(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 (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.ld = vtop->c.ull; - else - vtop->c.ld = vtop->c.ll; - } else if(!sf) { - if (sbt & VT_UNSIGNED) - vtop->c.ld = vtop->c.ui; - else - vtop->c.ld = 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.ull = (unsigned long long)vtop->c.ld; - } else if (sf && dbt == VT_BOOL) { - vtop->c.i = (vtop->c.ld != 0); - } else { - if(sf) - vtop->c.ll = (long long)vtop->c.ld; - else if (sbt == (VT_LLONG|VT_UNSIGNED)) - vtop->c.ll = vtop->c.ull; - else if (sbt & VT_UNSIGNED) - vtop->c.ll = vtop->c.ui; - else if (sbt != VT_LLONG) - vtop->c.ll = vtop->c.i; - - if (dbt == (VT_LLONG|VT_UNSIGNED)) - vtop->c.ull = vtop->c.ll; - else if (dbt == VT_BOOL) - vtop->c.i = (vtop->c.ll != 0); - else if (dbt != VT_LLONG) { - int s = 0; - if ((dbt & VT_BTYPE) == VT_BYTE) - s = 24; - else if ((dbt & VT_BTYPE) == VT_SHORT) - s = 16; - - if(dbt & VT_UNSIGNED) - vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s; - else - vtop->c.i = ((int)vtop->c.ll << s) >> s; - } - } - } else if (p && dbt == VT_BOOL) { - vtop->r = VT_CONST; - vtop->c.i = 1; - } else if (!nocode_wanted) { - /* 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); - } - } -#ifndef TCC_TARGET_X86_64 - } 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(&int_type); - } - 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) { - /* XXX: not sure if this is perfect... need more tests */ - if ((sbt & VT_BTYPE) != VT_LLONG) { - int r = gv(RC_INT); - if (sbt != (VT_INT | VT_UNSIGNED) && - sbt != VT_PTR && sbt != VT_FUNC) { - /* x86_64 specific: movslq */ - o(0x6348); - o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r)); - } - } -#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; - warning("nonportable conversion from pointer to char/short"); - } - force_charshort_cast(dbt); - } else if ((dbt & VT_BTYPE) == VT_INT) { - /* scalar to int */ - if (sbt == 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) */ - } - } - } 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. Put alignment at 'a' */ -static 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 (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_ENUM || bt == VT_FLOAT) { - *a = 4; - return 4; - } else if (bt == VT_SHORT) { - *a = 2; - return 2; - } else { - /* char, void, function, _Bool */ - *a = 1; - return 1; - } -} - -/* 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. */ -static void mk_pointer(CType *type) -{ - Sym *s; - s = sym_push(SYM_FIELD, type, 0, -1); - type->t = VT_PTR | (type->t & ~VT_TYPE); - 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 (FUNC_CALL(s1->r) != FUNC_CALL(s2->r)) - return 0; - /* XXX: not complete */ - if (s1->c == FUNC_OLD || s2->c == FUNC_OLD) - return 1; - if (s1->c != s2->c) - return 0; - while (s1 != NULL) { - if (s2 == NULL) - return 0; - if (!is_compatible_parameter_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); - } - /* 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_parameter_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 */ -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 & VT_TYPE; - bt = t & VT_BTYPE; - buf[0] = '\0'; - if (t & VT_CONSTANT) - pstrcat(buf, buf_size, "const "); - if (t & VT_VOLATILE) - pstrcat(buf, buf_size, "volatile "); - 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 = "char"; - goto add_tstr; - case VT_SHORT: - tstr = "short"; - goto add_tstr; - case VT_INT: - tstr = "int"; - goto add_tstr; - case VT_LONG: - tstr = "long"; - goto add_tstr; - case VT_LLONG: - tstr = "long long"; - goto add_tstr; - 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_ENUM: - case VT_STRUCT: - if (bt == VT_STRUCT) - tstr = "struct "; - else - tstr = "enum "; - pstrcat(buf, buf_size, tstr); - v = type->ref->v & ~SYM_STRUCT; - if (v >= SYM_FIRST_ANOM) - pstrcat(buf, buf_size, ""); - 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; - pstrcpy(buf1, sizeof(buf1), "*"); - 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, tmp_type1, tmp_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 (dt->t & VT_CONSTANT) - 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)) { - warning("assignment makes pointer from integer without a cast"); - goto type_ok; - } - type1 = pointed_type(dt); - /* a function is implicitely a function pointer */ - if (sbt == VT_FUNC) { - if ((type1->t & VT_BTYPE) != VT_VOID && - !is_compatible_types(pointed_type(dt), st)) - goto error; - else - 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 { - /* exact type match, except for unsigned */ - tmp_type1 = *type1; - tmp_type2 = *type2; - tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - if (!is_compatible_types(&tmp_type1, &tmp_type2)) - 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))) - 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) { - warning("assignment makes integer from pointer without a cast"); - } - /* XXX: more tests */ - break; - case VT_STRUCT: - tmp_type1 = *dt; - tmp_type2 = *st; - tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE); - if (!is_compatible_types(&tmp_type1, &tmp_type2)) { - error: - type_to_str(buf1, sizeof(buf1), st, NULL); - type_to_str(buf2, sizeof(buf2), dt, NULL); - error("cannot cast '%s' to '%s'", buf1, buf2); - } - break; - } - type_ok: - gen_cast(dt); -} - -/* store vtop in lvalue pushed on stack */ -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)) { - /* optimize char/short casts */ - delayed_cast = VT_MUSTCAST; - vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT))); - /* XXX: factorize */ - if (ft & VT_CONSTANT) - 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 */ - if (!nocode_wanted) { - size = type_size(&vtop->type, &align); - -#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 - vpush_global_sym(&func_old_type, TOK_memcpy); - - /* destination */ - vpushv(vtop - 2); - vtop->type.t = VT_PTR; - gaddrof(); - /* source */ - vpushv(vtop - 2); - vtop->type.t = VT_PTR; - gaddrof(); - /* type size */ - vpushi(size); - gfunc_call(3); - - vswap(); - vpop(); - } else { - vswap(); - vpop(); - } - /* leave source on stack */ - } else if (ft & VT_BITFIELD) { - /* bitfield store handling */ - bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f; - bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f; - /* remove bit field info to avoid loops */ - vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); - - /* duplicate source into other register */ - gv_dup(); - vswap(); - vrott(3); - - 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); - } - - /* duplicate destination */ - vdup(); - vtop[-1] = vtop[-2]; - - /* mask and shift source */ - if((ft & VT_BTYPE) != VT_BOOL) { - if((ft & VT_BTYPE) == VT_LLONG) { - vpushll((1ULL << bit_size) - 1ULL); - } else { - vpushi((1 << bit_size) - 1); - } - gen_op('&'); - } - vpushi(bit_pos); - gen_op(TOK_SHL); - /* load destination, mask and or with source */ - vswap(); - if((ft & VT_BTYPE) == VT_LLONG) { - vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos)); - } else { - vpushi(~(((1 << bit_size) - 1) << bit_pos)); - } - gen_op('&'); - gen_op('|'); - /* store result */ - vstore(); - - /* pop off shifted source from "duplicate source..." above */ - vpop(); - - } else { -#ifdef CONFIG_TCC_BCHECK - /* bound check case */ - if (vtop[-1].r & VT_MUSTBOUND) { - vswap(); - gbound(); - vswap(); - } -#endif - if (!nocode_wanted) { - rc = RC_INT; - if (is_float(ft)) { - rc = RC_FLOAT; -#ifdef TCC_TARGET_X86_64 - if ((ft & VT_BTYPE) == VT_LDOUBLE) { - rc = RC_ST0; - } -#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); -#ifdef TCC_TARGET_X86_64 - sv.type.t = VT_PTR; -#else - sv.type.t = VT_INT; -#endif - sv.r = VT_LOCAL | VT_LVAL; - sv.c.ul = vtop[-1].c.ul; - load(t, &sv); - vtop[-1].r = t | VT_LVAL; - } - store(r, vtop - 1); -#ifndef TCC_TARGET_X86_64 - /* two word case handling : store second register at word + 4 */ - if ((ft & VT_BTYPE) == VT_LLONG) { - vswap(); - /* convert to int to increment easily */ - vtop->type.t = VT_INT; - gaddrof(); - vpushi(4); - gen_op('+'); - vtop->r |= VT_LVAL; - vswap(); - /* XXX: it works because r2 is spilled last ! */ - store(vtop->r2, vtop - 1); - } -#endif - } - 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 -- */ -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 */ -} - -/* Parse GNUC __attribute__ extension. Currently, the following - extensions are recognized: - - aligned(n) : set data/function alignment. - - packed : force data alignment to 1 - - section(x) : generate data/code in this section. - - unused : currently ignored, but may be used someday. - - regparm(n) : pass function parameters in registers (i386 only) - */ -static void parse_attribute(AttributeDef *ad) -{ - int t, n; - - while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { - next(); - skip('('); - skip('('); - while (tok != ')') { - if (tok < TOK_IDENT) - expect("attribute name"); - t = tok; - next(); - switch(t) { - case TOK_SECTION1: - case TOK_SECTION2: - skip('('); - if (tok != TOK_STR) - expect("section name"); - ad->section = find_section(tcc_state, (char *)tokc.cstr->data); - next(); - skip(')'); - break; - case TOK_ALIGNED1: - case TOK_ALIGNED2: - if (tok == '(') { - next(); - n = expr_const(); - if (n <= 0 || (n & (n - 1)) != 0) - error("alignment must be a positive power of two"); - skip(')'); - } else { - n = MAX_ALIGN; - } - ad->aligned = n; - break; - case TOK_PACKED1: - case TOK_PACKED2: - ad->packed = 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: - FUNC_CALL(ad->func_attr) = FUNC_CDECL; - break; - case TOK_STDCALL1: - case TOK_STDCALL2: - case TOK_STDCALL3: - FUNC_CALL(ad->func_attr) = 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) - FUNC_CALL(ad->func_attr) = FUNC_FASTCALL1 + n - 1; - skip(')'); - break; - case TOK_FASTCALL1: - case TOK_FASTCALL2: - case TOK_FASTCALL3: - FUNC_CALL(ad->func_attr) = FUNC_FASTCALLW; - break; -#endif - case TOK_DLLEXPORT: - FUNC_EXPORT(ad->func_attr) = 1; - break; - default: - if (tcc_state->warn_unsupported) - 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(')'); - } -} - -/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ -static void struct_decl(CType *type, int u) -{ - int a, v, size, align, maxalign, c, offset; - int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; - Sym *s, *ss, *ass, **ps; - AttributeDef ad; - CType type1, btype; - - a = tok; /* save decl type */ - next(); - 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) { - if (s->type.t != a) - error("invalid type"); - goto do_decl; - } - } else { - v = anon_sym++; - } - type1.t = a; - /* 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 */ - /* put struct/union/enum name in type */ - do_decl: - type->t = u; - type->ref = s; - - if (tok == '{') { - next(); - if (s->c != -1) - error("struct/union/enum already defined"); - /* cannot be empty */ - c = 0; - /* non empty enums are not allowed */ - if (a == TOK_ENUM) { - for(;;) { - v = tok; - if (v < TOK_UIDENT) - expect("identifier"); - next(); - if (tok == '=') { - next(); - c = expr_const(); - } - /* enum symbols have static storage */ - ss = sym_push(v, &int_type, VT_CONST, c); - ss->type.t |= VT_STATIC; - if (tok != ',') - break; - next(); - c++; - /* NOTE: we accept a trailing comma */ - if (tok == '}') - break; - } - skip('}'); - } else { - maxalign = 1; - ps = &s->next; - prevbt = VT_INT; - bit_pos = 0; - offset = 0; - while (tok != '}') { - parse_btype(&btype, &ad); - while (1) { - bit_size = -1; - v = 0; - type1 = btype; - if (tok != ':') { - type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); - if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT) - expect("identifier"); - if ((type1.t & VT_BTYPE) == VT_FUNC || - (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE))) - 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) - error("negative width in bit-field '%s'", - get_tok_str(v, NULL)); - if (v && bit_size == 0) - error("zero width for bit-field '%s'", - get_tok_str(v, NULL)); - } - size = type_size(&type1, &align); - if (ad.aligned) { - if (align < ad.aligned) - align = ad.aligned; - } else if (ad.packed) { - align = 1; - } else if (*tcc_state->pack_stack_ptr) { - if (align > *tcc_state->pack_stack_ptr) - align = *tcc_state->pack_stack_ptr; - } - lbit_pos = 0; - if (bit_size >= 0) { - bt = type1.t & VT_BTYPE; - if (bt != VT_INT && - bt != VT_BYTE && - bt != VT_SHORT && - bt != VT_BOOL && - bt != VT_ENUM && - bt != VT_LLONG) - error("bitfields must have scalar type"); - bsize = size * 8; - if (bit_size > bsize) { - error("width of '%s' exceeds its type", - get_tok_str(v, NULL)); - } else if (bit_size == bsize) { - /* no need for bit fields */ - bit_pos = 0; - } else if (bit_size == 0) { - /* XXX: what to do if only padding in a - structure ? */ - /* zero size: means to pad */ - bit_pos = 0; - } else { - /* we do not have enough room ? - did the type change? - is it a union? */ - if ((bit_pos + bit_size) > bsize || - bt != prevbt || a == TOK_UNION) - bit_pos = 0; - lbit_pos = bit_pos; - /* XXX: handle LSB first */ - type1.t |= VT_BITFIELD | - (bit_pos << VT_STRUCT_SHIFT) | - (bit_size << (VT_STRUCT_SHIFT + 6)); - bit_pos += bit_size; - } - prevbt = bt; - } else { - bit_pos = 0; - } - if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) { - /* add new memory data only if starting - bit field */ - if (lbit_pos == 0) { - if (a == TOK_STRUCT) { - c = (c + align - 1) & -align; - offset = c; - if (size > 0) - c += size; - } else { - offset = 0; - if (size > c) - c = size; - } - if (align > maxalign) - maxalign = align; - } -#if 0 - printf("add field %s offset=%d", - get_tok_str(v, NULL), offset); - if (type1.t & VT_BITFIELD) { - printf(" pos=%d size=%d", - (type1.t >> VT_STRUCT_SHIFT) & 0x3f, - (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f); - } - printf("\n"); -#endif - } - if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) { - ass = type1.ref; - while ((ass = ass->next) != NULL) { - ss = sym_push(ass->v, &ass->type, 0, offset + ass->c); - *ps = ss; - ps = &ss->next; - } - } else if (v) { - ss = sym_push(v | SYM_FIELD, &type1, 0, offset); - *ps = ss; - ps = &ss->next; - } - if (tok == ';' || tok == TOK_EOF) - break; - skip(','); - } - skip(';'); - } - skip('}'); - /* store size and alignment */ - s->c = (c + maxalign - 1) & -maxalign; - s->r = maxalign; - } - } -} - -/* 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, type_found, typespec_found, typedef_found; - Sym *s; - CType type1; - - memset(ad, 0, sizeof(AttributeDef)); - type_found = 0; - typespec_found = 0; - typedef_found = 0; - t = 0; - 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 ((t & VT_BTYPE) != 0) - error("too many basic types"); - t |= 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: - next(); - typespec_found = 1; - break; - case TOK_LONG: - next(); - if ((t & VT_BTYPE) == VT_DOUBLE) { - t = (t & ~VT_BTYPE) | VT_LDOUBLE; - } else if ((t & VT_BTYPE) == VT_LONG) { - t = (t & ~VT_BTYPE) | VT_LLONG; - } else { - u = VT_LONG; - goto basic_type1; - } - break; - case TOK_BOOL: - u = VT_BOOL; - goto basic_type; - case TOK_FLOAT: - u = VT_FLOAT; - goto basic_type; - case TOK_DOUBLE: - next(); - if ((t & VT_BTYPE) == VT_LONG) { - t = (t & ~VT_BTYPE) | VT_LDOUBLE; - } else { - u = VT_DOUBLE; - goto basic_type1; - } - break; - case TOK_ENUM: - struct_decl(&type1, VT_ENUM); - basic_type2: - u = type1.t; - type->ref = type1.ref; - goto basic_type1; - case TOK_STRUCT: - case TOK_UNION: - struct_decl(&type1, VT_STRUCT); - goto basic_type2; - - /* type modifiers */ - case TOK_CONST1: - case TOK_CONST2: - case TOK_CONST3: - t |= VT_CONSTANT; - next(); - break; - case TOK_VOLATILE1: - case TOK_VOLATILE2: - case TOK_VOLATILE3: - t |= VT_VOLATILE; - next(); - break; - case TOK_SIGNED1: - case TOK_SIGNED2: - case TOK_SIGNED3: - typespec_found = 1; - t |= VT_SIGNED; - next(); - break; - case TOK_REGISTER: - case TOK_AUTO: - case TOK_RESTRICT1: - case TOK_RESTRICT2: - case TOK_RESTRICT3: - next(); - break; - case TOK_UNSIGNED: - t |= VT_UNSIGNED; - next(); - typespec_found = 1; - break; - - /* storage */ - case TOK_EXTERN: - t |= VT_EXTERN; - next(); - break; - case TOK_STATIC: - t |= VT_STATIC; - next(); - break; - case TOK_TYPEDEF: - t |= VT_TYPEDEF; - 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); - break; - /* GNUC typeof */ - case TOK_TYPEOF1: - case TOK_TYPEOF2: - case TOK_TYPEOF3: - next(); - parse_expr_type(&type1); - goto basic_type2; - default: - if (typespec_found || typedef_found) - goto the_end; - s = sym_find(tok); - if (!s || !(s->type.t & VT_TYPEDEF)) - goto the_end; - typedef_found = 1; - t |= (s->type.t & ~VT_TYPEDEF); - type->ref = s->type.ref; - next(); - typespec_found = 1; - break; - } - type_found = 1; - } -the_end: - if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED)) - error("signed and unsigned modifier"); - if (tcc_state->char_is_unsigned) { - if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE) - t |= VT_UNSIGNED; - } - t &= ~VT_SIGNED; - - /* long is never used as type */ - if ((t & VT_BTYPE) == VT_LONG) -#ifndef TCC_TARGET_X86_64 - t = (t & ~VT_BTYPE) | VT_INT; -#else - t = (t & ~VT_BTYPE) | VT_LLONG; -#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); - } -} - -static void post_type(CType *type, AttributeDef *ad) -{ - int n, l, t1, arg_size, align; - Sym **plast, *s, *first; - AttributeDef ad1; - CType pt; - - if (tok == '(') { - /* function declaration */ - next(); - l = 0; - first = NULL; - plast = &first; - arg_size = 0; - if (tok != ')') { - for(;;) { - /* read param name and compute offset */ - if (l != FUNC_OLD) { - if (!parse_btype(&pt, &ad1)) { - if (l) { - error("invalid type"); - } else { - l = FUNC_OLD; - goto old_proto; - } - } - l = FUNC_NEW; - 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) - error("parameter declared as void"); - arg_size += (type_size(&pt, &align) + 3) & ~3; - } else { - old_proto: - n = tok; - if (n < TOK_UIDENT) - expect("identifier"); - pt.t = VT_INT; - 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 no parameters, then old type prototype */ - if (l == 0) - l = FUNC_OLD; - skip(')'); - t1 = type->t & VT_STORAGE; - /* NOTE: const is ignored in returned type as it has a special - meaning in gcc / C++ */ - type->t &= ~(VT_STORAGE | VT_CONSTANT); - post_type(type, ad); - /* we push a anonymous symbol which will contain the function prototype */ - FUNC_ARGS(ad->func_attr) = arg_size; - s = sym_push(SYM_FIELD, type, ad->func_attr, l); - s->next = first; - type->t = t1 | VT_FUNC; - type->ref = s; - } else if (tok == '[') { - /* array definition */ - next(); - if (tok == TOK_RESTRICT1) - next(); - n = -1; - if (tok != ']') { - n = expr_const(); - if (n < 0) - error("invalid array size"); - } - skip(']'); - /* parse next post type */ - t1 = type->t & VT_STORAGE; - type->t &= ~VT_STORAGE; - post_type(type, ad); - - /* we push a anonymous symbol which will contain the array - element type */ - s = sym_push(SYM_FIELD, type, 0, n); - type->t = t1 | VT_ARRAY | VT_PTR; - type->ref = s; - } -} - -/* Parse a type declaration (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(). - */ -static void type_decl(CType *type, AttributeDef *ad, int *v, int td) -{ - Sym *s; - CType type1, *type2; - int qualifiers; - - 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; - } - mk_pointer(type); - type->t |= qualifiers; - } - - /* XXX: clarify attribute handling */ - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) - parse_attribute(ad); - - /* recursive type */ - /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */ - type1.t = 0; /* XXX: same as int */ - if (tok == '(') { - next(); - /* XXX: this is not correct to modify 'ad' at this point, but - the syntax is not clear */ - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) - parse_attribute(ad); - type_decl(&type1, ad, v, td); - skip(')'); - } else { - /* type identifier */ - if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { - *v = tok; - next(); - } else { - if (!(td & TYPE_ABSTRACT)) - expect("identifier"); - *v = 0; - } - } - post_type(type, ad); - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) - parse_attribute(ad); - if (!type1.t) - return; - /* append type at the end of type1 */ - type2 = &type1; - for(;;) { - s = type2->ref; - type2 = &s->type; - if (!type2->t) { - *type2 = *type; - break; - } - } - *type = type1; -} - -/* compute the lvalue VT_LVAL_xxx needed to match type t. */ -static 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 */ -static 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) && !nocode_wanted) - 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_BTYPE) != VT_FUNC) { - vtop->r |= lvalue_type(vtop->type.t); - /* if bound checking, the referenced pointer must be checked */ - if (tcc_state->do_bounds_check) - vtop->r |= VT_MUSTBOUND; - } -} - -/* 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->c; - 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) { - type.t = VT_DOUBLE; - gen_cast(&type); - } - } else if (arg == NULL) { - 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 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); - } - 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 vpush_tokc(int t) -{ - CType type; - type.t = t; - vsetc(&type, VT_CONST, &tokc); -} - -static void unary(void) -{ - int n, t, align, size, r; - CType type; - Sym *s; - AttributeDef ad; - - /* 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_CINT: - case TOK_CCHAR: - case TOK_LCHAR: - vpushi(tokc.i); - next(); - break; - case TOK_CUINT: - vpush_tokc(VT_INT | VT_UNSIGNED); - next(); - break; - case TOK_CLLONG: - vpush_tokc(VT_LLONG); - next(); - break; - case TOK_CULLONG: - vpush_tokc(VT_LLONG | VT_UNSIGNED); - next(); - break; - case TOK_CFLOAT: - vpush_tokc(VT_FLOAT); - next(); - break; - case TOK_CDOUBLE: - vpush_tokc(VT_DOUBLE); - next(); - break; - case TOK_CLDOUBLE: - vpush_tokc(VT_LDOUBLE); - next(); - break; - 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); - 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; - 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 { - unary(); - gen_cast(&type); - } - } else if (tok == '{') { - /* save all registers */ - save_regs(0); - /* statement expression : we do not accept break/continue - inside as GCC does */ - block(NULL, NULL, NULL, NULL, 0, 1); - 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) && !(vtop->type.t & VT_LLOCAL)) - test_lvalue(); - mk_pointer(&vtop->type); - gaddrof(); - break; - case '!': - next(); - unary(); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - CType boolean; - boolean.t = VT_BOOL; - gen_cast(&boolean); - vtop->c.i = !vtop->c.i; - } else if ((vtop->r & VT_VALMASK) == VT_CMP) - vtop->c.i = vtop->c.i ^ 1; - else { - save_regs(1); - vseti(VT_JMP, gtst(1, 0)); - } - break; - case '~': - next(); - unary(); - vpushi(-1); - gen_op('^'); - break; - case '+': - next(); - /* in order to force cast, we add zero */ - unary(); - if ((vtop->type.t & VT_BTYPE) == VT_PTR) - error("pointer not accepted for unary plus"); - vpushi(0); - gen_op('+'); - break; - case TOK_SIZEOF: - case TOK_ALIGNOF1: - case TOK_ALIGNOF2: - t = tok; - next(); - if (tok == '(') { - parse_expr_type(&type); - } else { - unary_type(&type); - } - size = type_size(&type, &align); - if (t == TOK_SIZEOF) { - if (size < 0) - error("sizeof applied to an incomplete type"); - vpushi(size); - } else { - vpushi(align); - } - vtop->type.t |= VT_UNSIGNED; - break; - - case TOK_builtin_types_compatible_p: - { - CType type1, type2; - next(); - skip('('); - parse_type(&type1); - skip(','); - parse_type(&type2); - skip(')'); - type1.t &= ~(VT_CONSTANT | VT_VOLATILE); - type2.t &= ~(VT_CONSTANT | VT_VOLATILE); - vpushi(is_compatible_types(&type1, &type2)); - } - break; - case TOK_builtin_constant_p: - { - int saved_nocode_wanted, res; - next(); - skip('('); - saved_nocode_wanted = nocode_wanted; - nocode_wanted = 1; - gexpr(); - res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - vpop(); - nocode_wanted = saved_nocode_wanted; - skip(')'); - vpushi(res); - } - break; - case TOK_builtin_frame_address: - { - CType type; - next(); - skip('('); - if (tok != TOK_CINT) { - error("__builtin_frame_address only takes integers"); - } - if (tokc.i != 0) { - error("TCC only supports __builtin_frame_address(0)"); - } - next(); - skip(')'); - type.t = VT_VOID; - mk_pointer(&type); - vset(&type, VT_LOCAL, 0); - } - break; -#ifdef TCC_TARGET_X86_64 - case TOK_builtin_malloc: - tok = TOK_malloc; - goto tok_identifier; - case TOK_builtin_free: - tok = TOK_free; - goto tok_identifier; -#endif - case TOK_INC: - case TOK_DEC: - t = tok; - next(); - unary(); - inc(0, t); - break; - case '-': - next(); - vpushi(0); - unary(); - 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; - } - vset(&s->type, VT_CONST | VT_SYM, 0); - vtop->sym = s; - next(); - break; - default: - tok_identifier: - t = tok; - next(); - if (t < TOK_UIDENT) - expect("identifier"); - s = sym_find(t); - if (!s) { - if (tok != '(') - error("'%s' undeclared", get_tok_str(t, NULL)); - /* for simple function calls, we tolerate undeclared - external reference to int() function */ - if (tcc_state->warn_implicit_function_declaration) - warning("implicit declaration of function '%s'", - get_tok_str(t, NULL)); - s = external_global_sym(t, &func_old_type, 0); - } - if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) == - (VT_STATIC | VT_INLINE | VT_FUNC)) { - /* if referencing an inline function, then we generate a - symbol to it if not already done. It will have the - effect to generate code for it at the end of the - compilation unit. Inline function as always - generated in the text section. */ - if (!s->c) - put_extern_sym(s, text_section, 0, 0); - r = VT_SYM | VT_CONST; - } else { - r = s->r; - } - vset(&s->type, r, s->c); - /* if forward reference, we must point to s */ - if (vtop->r & VT_SYM) { - vtop->sym = s; - vtop->c.ul = 0; - } - break; - } - - /* post operations */ - while (1) { - if (tok == TOK_INC || tok == TOK_DEC) { - inc(1, tok); - next(); - } else if (tok == '.' || tok == TOK_ARROW) { - /* field */ - if (tok == TOK_ARROW) - indir(); - test_lvalue(); - gaddrof(); - next(); - /* expect pointer on structure */ - if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) - expect("struct or union"); - s = vtop->type.ref; - /* find field */ - tok |= SYM_FIELD; - while ((s = s->next) != NULL) { - if (s->v == tok) - break; - } - if (!s) - error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL)); - /* 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; - /* an array is never an lvalue */ - if (!(vtop->type.t & VT_ARRAY)) { - vtop->r |= lvalue_type(vtop->type.t); - /* if bound checking, the referenced pointer must be checked */ - if (tcc_state->do_bounds_check) - vtop->r |= VT_MUSTBOUND; - } - next(); - } else if (tok == '[') { - next(); - gexpr(); - gen_op('+'); - indir(); - skip(']'); - } else if (tok == '(') { - SValue ret; - Sym *sa; - int nb_args; - - /* 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 = 0; - ret.r2 = VT_CONST; - /* compute first implicit argument if a structure is returned */ - if ((s->type.t & VT_BTYPE) == VT_STRUCT) { - /* get some space for the returned structure */ - size = type_size(&s->type, &align); - 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.type = s->type; - /* return in register */ - if (is_float(ret.type.t)) { - ret.r = reg_fret(ret.type.t); - } else { - if ((ret.type.t & VT_BTYPE) == VT_LLONG) - ret.r2 = REG_LRET; - 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) - error("too few arguments to function"); - skip(')'); - if (!nocode_wanted) { - gfunc_call(nb_args); - } else { - vtop -= (nb_args + 1); - } - /* return value */ - vsetc(&ret.type, ret.r, &ret.c); - vtop->r2 = ret.r2; - } else { - break; - } - } -} - -static void uneq(void) -{ - int t; - - unary(); - 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(); - } -} - -static void expr_prod(void) -{ - int t; - - uneq(); - while (tok == '*' || tok == '/' || tok == '%') { - t = tok; - next(); - uneq(); - gen_op(t); - } -} - -static 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('|'); - } -} - -/* XXX: fix this mess */ -static void expr_land_const(void) -{ - expr_or(); - while (tok == TOK_LAND) { - next(); - expr_or(); - gen_op(TOK_LAND); - } -} - -/* XXX: fix this mess */ -static void expr_lor_const(void) -{ - expr_land_const(); - while (tok == TOK_LOR) { - next(); - expr_land_const(); - gen_op(TOK_LOR); - } -} - -/* only used if non constant */ -static void expr_land(void) -{ - int t; - - expr_or(); - if (tok == TOK_LAND) { - t = 0; - save_regs(1); - for(;;) { - t = gtst(1, t); - if (tok != TOK_LAND) { - vseti(VT_JMPI, t); - break; - } - next(); - expr_or(); - } - } -} - -static void expr_lor(void) -{ - int t; - - expr_land(); - if (tok == TOK_LOR) { - t = 0; - save_regs(1); - for(;;) { - t = gtst(0, t); - if (tok != TOK_LOR) { - vseti(VT_JMP, t); - break; - } - next(); - expr_land(); - } - } -} - -/* XXX: better constant handling */ -static void expr_eq(void) -{ - int tt, u, r1, r2, rc, t1, t2, bt1, bt2; - SValue sv; - CType type, type1, type2; - - if (const_wanted) { - expr_lor_const(); - if (tok == '?') { - CType boolean; - int c; - boolean.t = VT_BOOL; - vdup(); - gen_cast(&boolean); - c = vtop->c.i; - vpop(); - next(); - if (tok != ':' || !gnu_ext) { - vpop(); - gexpr(); - } - if (!c) - vpop(); - skip(':'); - expr_eq(); - if (c) - vpop(); - } - } else { - expr_lor(); - if (tok == '?') { - next(); - if (vtop != vstack) { - /* 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 (tok == ':' && gnu_ext) { - gv_dup(); - tt = gtst(1, 0); - } else { - tt = gtst(1, 0); - gexpr(); - } - type1 = vtop->type; - sv = *vtop; /* save value to handle it later */ - vtop--; /* no vpop so that FP stack is not flushed */ - skip(':'); - u = gjmp(0); - gsym(tt); - expr_eq(); - type2 = vtop->type; - - t1 = type1.t; - bt1 = t1 & VT_BTYPE; - t2 = type2.t; - bt2 = t2 & VT_BTYPE; - /* 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; - /* convert to unsigned if it does not fit in a long long */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) - type.t |= VT_UNSIGNED; - } else if (bt1 == VT_PTR || bt2 == VT_PTR) { - /* XXX: test pointer compatibility */ - type = type1; - } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) { - /* XXX: test function pointer compatibility */ - type = type1; - } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { - /* XXX: test structure compatibility */ - type = type1; - } 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; - /* convert to unsigned if it does not fit in an integer */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)) - type.t |= VT_UNSIGNED; - } - - /* now we convert second operand */ - gen_cast(&type); - 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; - } - - r2 = gv(rc); - /* this is horrible, but we must also convert first - operand */ - tt = gjmp(0); - gsym(u); - /* put again first value and cast it */ - *vtop = sv; - gen_cast(&type); - if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) - gaddrof(); - r1 = gv(rc); - move_reg(r2, r1); - vtop->r = r2; - gsym(tt); - } - } -} - -static void gexpr(void) -{ - while (1) { - expr_eq(); - if (tok != ',') - break; - vpop(); - next(); - } -} - -/* parse an expression and return its type without any side effect. */ -static void expr_type(CType *type) -{ - int saved_nocode_wanted; - - saved_nocode_wanted = nocode_wanted; - nocode_wanted = 1; - gexpr(); - *type = vtop->type; - vpop(); - nocode_wanted = saved_nocode_wanted; -} - -/* parse a unary expression and return its type without any side - effect. */ -static void unary_type(CType *type) -{ - int a; - - a = nocode_wanted; - nocode_wanted = 1; - unary(); - *type = vtop->type; - vpop(); - nocode_wanted = a; -} - -/* parse a constant expression and return value in vtop. */ -static void expr_const1(void) -{ - int a; - a = const_wanted; - const_wanted = 1; - expr_eq(); - const_wanted = a; -} - -/* parse an integer constant and return its value. */ -static int expr_const(void) -{ - int c; - expr_const1(); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) - expect("constant expression"); - c = vtop->c.i; - vpop(); - 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 == ':') { - next(); - return last_tok; - } else { - unget_tok(last_tok); - return 0; - } -} - -static void block(int *bsym, int *csym, int *case_sym, int *def_sym, - int case_reg, int is_expr) -{ - int a, b, c, d; - Sym *s; - - /* generate line number info */ - if (tcc_state->do_debug && - (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; - } - - if (is_expr) { - /* default return value is (void) */ - vpushi(0); - vtop->type.t = VT_VOID; - } - - if (tok == TOK_IF) { - /* if test */ - next(); - skip('('); - gexpr(); - skip(')'); - a = gtst(1, 0); - block(bsym, csym, case_sym, def_sym, case_reg, 0); - c = tok; - if (c == TOK_ELSE) { - next(); - d = gjmp(0); - gsym(a); - block(bsym, csym, case_sym, def_sym, case_reg, 0); - gsym(d); /* patch else jmp */ - } else - gsym(a); - } else if (tok == TOK_WHILE) { - next(); - d = ind; - skip('('); - gexpr(); - skip(')'); - a = gtst(1, 0); - b = 0; - block(&a, &b, case_sym, def_sym, case_reg, 0); - gjmp_addr(d); - gsym(a); - gsym_addr(b, d); - } else if (tok == '{') { - Sym *llabel; - - next(); - /* record local declaration stack position */ - s = local_stack; - llabel = local_label_stack; - /* 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 != '}') { - decl(VT_LOCAL); - if (tok != '}') { - if (is_expr) - vpop(); - block(bsym, csym, case_sym, def_sym, case_reg, is_expr); - } - } - /* pop locally defined labels */ - label_pop(&local_label_stack, llabel); - /* pop locally defined symbols */ - if(is_expr) { - /* XXX: this solution makes only valgrind happy... - triggered by gcc.c-torture/execute/20000917-1.c */ - Sym *p; - switch(vtop->type.t & VT_BTYPE) { - case VT_PTR: - case VT_STRUCT: - case VT_ENUM: - case VT_FUNC: - for(p=vtop->type.ref;p;p=p->prev) - if(p->prev==s) - error("unsupported expression type"); - } - } - sym_pop(&local_stack, s); - next(); - } else if (tok == TOK_RETURN) { - next(); - if (tok != ';') { - gexpr(); - gen_assign_cast(&func_vt); - if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { - CType type; - /* if returning structure, must copy it to implicit - first pointer arg location */ -#ifdef TCC_ARM_EABI - int align, size; - size = type_size(&func_vt,&align); - if(size <= 4) - { - if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3)) - && (align & 3)) - { - int addr; - loc = (loc - size) & -4; - addr = loc; - type = func_vt; - vset(&type, VT_LOCAL | VT_LVAL, addr); - vswap(); - vstore(); - vset(&int_type, VT_LOCAL | VT_LVAL, addr); - } - vtop->type = int_type; - gv(RC_IRET); - } else { -#endif - type = func_vt; - mk_pointer(&type); - vset(&type, VT_LOCAL | VT_LVAL, func_vc); - indir(); - vswap(); - /* copy structure value to pointer */ - vstore(); -#ifdef TCC_ARM_EABI - } -#endif - } else if (is_float(func_vt.t)) { - gv(rc_fret(func_vt.t)); - } else { - gv(RC_IRET); - } - vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ - } - skip(';'); - rsym = gjmp(rsym); /* jmp */ - } else if (tok == TOK_BREAK) { - /* compute jump */ - if (!bsym) - error("cannot break"); - *bsym = gjmp(*bsym); - next(); - skip(';'); - } else if (tok == TOK_CONTINUE) { - /* compute jump */ - if (!csym) - error("cannot continue"); - *csym = gjmp(*csym); - next(); - skip(';'); - } else if (tok == TOK_FOR) { - int e; - next(); - skip('('); - if (tok != ';') { - gexpr(); - vpop(); - } - skip(';'); - d = ind; - c = ind; - a = 0; - b = 0; - if (tok != ';') { - gexpr(); - a = gtst(1, 0); - } - skip(';'); - if (tok != ')') { - e = gjmp(0); - c = ind; - gexpr(); - vpop(); - gjmp_addr(d); - gsym(e); - } - skip(')'); - block(&a, &b, case_sym, def_sym, case_reg, 0); - gjmp_addr(c); - gsym(a); - gsym_addr(b, c); - } else - if (tok == TOK_DO) { - next(); - a = 0; - b = 0; - d = ind; - block(&a, &b, case_sym, def_sym, case_reg, 0); - skip(TOK_WHILE); - skip('('); - gsym(b); - gexpr(); - c = gtst(0, 0); - gsym_addr(c, d); - skip(')'); - gsym(a); - skip(';'); - } else - if (tok == TOK_SWITCH) { - next(); - skip('('); - gexpr(); - /* XXX: other types than integer */ - case_reg = gv(RC_INT); - vpop(); - skip(')'); - a = 0; - b = gjmp(0); /* jump to first case */ - c = 0; - block(&a, csym, &b, &c, case_reg, 0); - /* if no default, jmp after switch */ - if (c == 0) - c = ind; - /* default label */ - gsym_addr(b, c); - /* break label */ - gsym(a); - } else - if (tok == TOK_CASE) { - int v1, v2; - if (!case_sym) - expect("switch"); - next(); - v1 = expr_const(); - v2 = v1; - if (gnu_ext && tok == TOK_DOTS) { - next(); - v2 = expr_const(); - if (v2 < v1) - warning("empty case range"); - } - /* since a case is like a label, we must skip it with a jmp */ - b = gjmp(0); - gsym(*case_sym); - vseti(case_reg, 0); - vpushi(v1); - if (v1 == v2) { - gen_op(TOK_EQ); - *case_sym = gtst(1, 0); - } else { - gen_op(TOK_GE); - *case_sym = gtst(1, 0); - vseti(case_reg, 0); - vpushi(v2); - gen_op(TOK_LE); - *case_sym = gtst(1, *case_sym); - } - gsym(b); - skip(':'); - is_expr = 0; - goto block_after_label; - } else - if (tok == TOK_DEFAULT) { - next(); - skip(':'); - if (!def_sym) - expect("switch"); - if (*def_sym) - error("too many 'default'"); - *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; - } - /* label already defined */ - if (s->r & LABEL_FORWARD) - s->next = (void *)gjmp((long)s->next); - else - gjmp_addr((long)s->next); - 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 */ - s = label_find(b); - if (s) { - if (s->r == LABEL_DEFINED) - error("duplicate label '%s'", get_tok_str(s->v, NULL)); - gsym((long)s->next); - s->r = LABEL_DEFINED; - } else { - s = label_push(&global_label_stack, b, LABEL_DEFINED); - } - s->next = (void *)ind; - /* we accept this, but it is a mistake */ - block_after_label: - if (tok == '}') { - warning("deprecated use of label at end of compound statement"); - } else { - if (is_expr) - vpop(); - block(bsym, csym, case_sym, def_sym, case_reg, is_expr); - } - } else { - /* expression case */ - if (tok != ';') { - if (is_expr) { - vpop(); - gexpr(); - } else { - gexpr(); - vpop(); - } - } - skip(';'); - } - } -} - -/* t is the array or struct type. c is the array or struct - address. cur_index/cur_field is the pointer to the current - value. 'size_only' is true if only size info is needed (only used - in arrays) */ -static void decl_designator(CType *type, Section *sec, unsigned long c, - int *cur_index, Sym **cur_field, - int size_only) -{ - Sym *s, *f; - int notfirst, index, index_last, align, l, nb_elems, elem_size; - CType type1; - - notfirst = 0; - elem_size = 0; - nb_elems = 1; - if (gnu_ext && (l = is_label()) != 0) - goto struct_field; - while (tok == '[' || tok == '.') { - if (tok == '[') { - if (!(type->t & VT_ARRAY)) - expect("array type"); - s = type->ref; - next(); - index = expr_const(); - if (index < 0 || (s->c >= 0 && index >= s->c)) - expect("invalid index"); - if (tok == TOK_DOTS && gnu_ext) { - next(); - index_last = expr_const(); - if (index_last < 0 || - (s->c >= 0 && index_last >= s->c) || - index_last < index) - expect("invalid index"); - } else { - index_last = index; - } - skip(']'); - if (!notfirst) - *cur_index = index_last; - type = pointed_type(type); - elem_size = type_size(type, &align); - c += index * elem_size; - /* NOTE: we only support ranges for last designator */ - nb_elems = index_last - index + 1; - if (nb_elems != 1) { - notfirst = 1; - break; - } - } else { - next(); - l = tok; - next(); - struct_field: - if ((type->t & VT_BTYPE) != VT_STRUCT) - expect("struct/union type"); - s = type->ref; - l |= SYM_FIELD; - f = s->next; - while (f) { - if (f->v == l) - break; - f = f->next; - } - if (!f) - expect("field"); - if (!notfirst) - *cur_field = f; - /* XXX: fix this mess by using explicit storage field */ - type1 = f->type; - type1.t |= (type->t & ~VT_TYPE); - type = &type1; - c += f->c; - } - notfirst = 1; - } - if (notfirst) { - if (tok == '=') { - next(); - } else { - if (!gnu_ext) - expect("="); - } - } else { - if (type->t & VT_ARRAY) { - index = *cur_index; - type = pointed_type(type); - c += index * type_size(type, &align); - } else { - f = *cur_field; - if (!f) - error("too many field init"); - /* XXX: fix this mess by using explicit storage field */ - type1 = f->type; - type1.t |= (type->t & ~VT_TYPE); - type = &type1; - c += f->c; - } - } - 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) - error("range init not supported yet for dynamic storage"); - 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); - } - } -} - -#define EXPR_VAL 0 -#define EXPR_CONST 1 -#define EXPR_ANY 2 - -/* 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 v, int expr_type) -{ - int saved_global_expr, bt, bit_pos, bit_size; - void *ptr; - unsigned long long bit_mask; - CType dtype; - - switch(expr_type) { - case EXPR_VAL: - vpushi(v); - break; - 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 */ - if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST) - error("initializer element is not constant"); - break; - case EXPR_ANY: - expr_eq(); - break; - } - - dtype = *type; - dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ - - if (sec) { - /* XXX: not portable */ - /* XXX: generate error if incorrect relocation */ - gen_assign_cast(&dtype); - bt = type->t & VT_BTYPE; - /* we'll write at most 12 bytes */ - if (c + 12 > sec->data_allocated) { - section_realloc(sec, c + 12); - } - ptr = sec->data + c; - /* XXX: make code faster ? */ - if (!(type->t & VT_BITFIELD)) { - bit_pos = 0; - bit_size = 32; - bit_mask = -1LL; - } else { - bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; - bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; - bit_mask = (1LL << bit_size) - 1; - } - if ((vtop->r & VT_SYM) && - (bt == VT_BYTE || - bt == VT_SHORT || - bt == VT_DOUBLE || - bt == VT_LDOUBLE || - bt == VT_LLONG || - (bt == VT_INT && bit_size != 32))) - error("initializer element is not computable at load time"); - switch(bt) { - case VT_BOOL: - vtop->c.i = (vtop->c.i != 0); - case VT_BYTE: - *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos; - break; - case VT_SHORT: - *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos; - break; - case VT_DOUBLE: - *(double *)ptr = vtop->c.d; - break; - case VT_LDOUBLE: - *(long double *)ptr = vtop->c.ld; - break; - case VT_LLONG: - *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos; - break; - default: - if (vtop->r & VT_SYM) { - greloc(sec, vtop->sym, c, R_DATA_32); - } - *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos; - break; - } - vtop--; - } else { - vset(&dtype, VT_LOCAL|VT_LVAL, c); - vswap(); - vstore(); - vpop(); - } -} - -/* put zeros for variable based init */ -static void init_putz(CType *t, 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); - vpushi(0); - vpushi(size); - gfunc_call(3); - } -} - -/* '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 index, array_length, n, no_oblock, nb, parlevel, i; - int size1, align1, expr_type; - Sym *s, *f; - CType *t1; - - if (type->t & VT_ARRAY) { - s = type->ref; - n = s->c; - array_length = 0; - t1 = pointed_type(type); - size1 = type_size(t1, &align1); - - no_oblock = 1; - if ((first && tok != TOK_LSTR && tok != TOK_STR) || - tok == '{') { - 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)) { - while (tok == TOK_STR || tok == TOK_LSTR) { - int cstr_len, ch; - CString *cstr; - - cstr = tokc.cstr; - /* compute maximum number of chars wanted */ - if (tok == TOK_STR) - cstr_len = cstr->size; - else - cstr_len = cstr->size / sizeof(nwchar_t); - cstr_len--; - nb = cstr_len; - if (n >= 0 && nb > (n - array_length)) - nb = n - array_length; - if (!size_only) { - if (cstr_len > nb) - 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) { - memcpy(sec->data + c + array_length, cstr->data, nb); - } else { - for(i=0;idata)[i]; - else - ch = ((nwchar_t *)cstr->data)[i]; - init_putv(t1, sec, c + (array_length + i) * size1, - ch, EXPR_VAL); - } - } - } - array_length += nb; - next(); - } - /* only add trailing zero if enough storage (no - warning in this case since it is standard) */ - if (n < 0 || array_length < n) { - if (!size_only) { - init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL); - } - array_length++; - } - } else { - index = 0; - while (tok != '}') { - decl_designator(type, sec, c, &index, NULL, size_only); - if (n >= 0 && index >= n) - error("index too large"); - /* must put zero in holes (note that doing it that way - ensures that it even works with designators) */ - if (!size_only && array_length < index) { - init_putz(t1, sec, c + array_length * size1, - (index - array_length) * size1); - } - index++; - if (index > array_length) - array_length = index; - /* special test for multi dimensional arrays (may not - be strictly correct if designators are used at the - same time) */ - if (index >= n && no_oblock) - break; - if (tok == '}') - break; - skip(','); - } - } - if (!no_oblock) - skip('}'); - /* put zeros at the end */ - if (!size_only && n >= 0 && array_length < n) { - init_putz(t1, sec, c + array_length * size1, - (n - array_length) * size1); - } - /* patch type size if needed */ - if (n < 0) - s->c = array_length; - } else if ((type->t & VT_BTYPE) == VT_STRUCT && - (sec || !first || tok == '{')) { - int par_count; - - /* NOTE: the previous test is a specific case for automatic - struct/union init */ - /* XXX: union needs only one init */ - - /* XXX: this test is incorrect for local initializers - beginning with ( without {. It would be much more difficult - to do it correctly (ideally, the expression parser should - be used in all cases) */ - par_count = 0; - if (tok == '(') { - AttributeDef ad1; - CType type1; - next(); - while (tok == '(') { - par_count++; - next(); - } - if (!parse_btype(&type1, &ad1)) - expect("cast"); - type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); -#if 0 - if (!is_assignable_types(type, &type1)) - error("invalid type for cast"); -#endif - skip(')'); - } - no_oblock = 1; - if (first || tok == '{') { - skip('{'); - no_oblock = 0; - } - s = type->ref; - f = s->next; - array_length = 0; - index = 0; - n = s->c; - while (tok != '}') { - decl_designator(type, sec, c, NULL, &f, size_only); - index = f->c; - if (!size_only && array_length < index) { - init_putz(type, sec, c + array_length, - index - array_length); - } - index = index + type_size(&f->type, &align1); - if (index > array_length) - array_length = index; - f = f->next; - if (no_oblock && f == NULL) - break; - if (tok == '}') - break; - skip(','); - } - /* put zeros at the end */ - if (!size_only && array_length < n) { - init_putz(type, sec, c + array_length, - n - array_length); - } - if (!no_oblock) - skip('}'); - while (par_count) { - skip(')'); - par_count--; - } - } else if (tok == '{') { - next(); - decl_initializer(type, sec, c, first, size_only); - skip('}'); - } else if (size_only) { - /* just skip expression */ - parlevel = 0; - while ((parlevel > 0 || (tok != '}' && tok != ',')) && - tok != -1) { - if (tok == '(') - parlevel++; - else if (tok == ')') - parlevel--; - next(); - } - } else { - /* currently, we always use constant expression for globals - (may change for scripting case) */ - expr_type = EXPR_CONST; - if (!sec) - expr_type = EXPR_ANY; - init_putv(type, sec, c, 0, expr_type); - } -} - -/* 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, data_offset; - int level; - ParseState saved_parse_state = {0}; - TokenString init_str; - Section *sec; - - 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 */ - tok_str_new(&init_str); - if (size < 0) { - if (!has_init) - error("unknown type size"); - /* get all init string */ - if (has_init == 2) { - /* only get strings */ - while (tok == TOK_STR || tok == TOK_LSTR) { - tok_str_add_tok(&init_str); - next(); - } - } else { - level = 0; - while (level > 0 || (tok != ',' && tok != ';')) { - if (tok < 0) - error("unexpected end of file in initializer"); - tok_str_add_tok(&init_str); - if (tok == '{') - level++; - else if (tok == '}') { - level--; - if (level <= 0) { - next(); - break; - } - } - next(); - } - } - tok_str_add(&init_str, -1); - tok_str_add(&init_str, 0); - - /* compute size */ - save_parse_state(&saved_parse_state); - - macro_ptr = init_str.str; - 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) - error("unknown type size"); - } - /* take into account specified alignment if bigger */ - if (ad->aligned) { - if (ad->aligned > align) - align = ad->aligned; - } else if (ad->packed) { - align = 1; - } - if ((r & VT_VALMASK) == VT_LOCAL) { - sec = NULL; - if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) - loc--; - loc = (loc - size) & -align; - addr = loc; - /* handles bounds */ - /* XXX: currently, since we do only one pass, we cannot track - '&' operators, so we add only arrays */ - if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) { - unsigned long *bounds_ptr; - /* add padding between regions */ - loc--; - /* then add local bound info */ - bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long)); - bounds_ptr[0] = addr; - bounds_ptr[1] = size; - } - if (v) { - /* local variable */ - sym_push(v, type, r, addr); - } else { - /* push local reference */ - vset(type, r, addr); - } - } else { - Sym *sym; - - sym = NULL; - if (v && scope == VT_CONST) { - /* see if the symbol was already defined */ - sym = sym_find(v); - if (sym) { - if (!is_compatible_types(&sym->type, type)) - error("incompatible types for redefinition of '%s'", - get_tok_str(v, NULL)); - if (sym->type.t & VT_EXTERN) { - /* if the variable is extern, it was not allocated */ - sym->type.t &= ~VT_EXTERN; - /* set array size if it was ommited in extern - declaration */ - if ((sym->type.t & VT_ARRAY) && - sym->type.ref->c < 0 && - type->ref->c >= 0) - sym->type.ref->c = type->ref->c; - } else { - /* we accept several definitions of the same - global variable. this is tricky, because we - must play with the SHN_COMMON type of the symbol */ - /* XXX: should check if the variable was already - initialized. It is incorrect to initialized it - twice */ - /* no init data, we won't add more to the symbol */ - if (!has_init) - 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) { - data_offset = sec->data_offset; - data_offset = (data_offset + align - 1) & -align; - addr = data_offset; - /* very important to increment global pointer at this time - because initializers themselves can create new initializers */ - data_offset += size; - /* add padding if bound check */ - if (tcc_state->do_bounds_check) - data_offset++; - sec->data_offset = data_offset; - /* allocate section space to put the data */ - if (sec->sh_type != SHT_NOBITS && - data_offset > sec->data_allocated) - section_realloc(sec, data_offset); - /* align section if needed */ - if (align > sec->sh_addralign) - sec->sh_addralign = align; - } else { - addr = 0; /* avoid warning */ - } - - if (v) { - if (scope != VT_CONST || !sym) { - sym = sym_push(v, type, r | VT_SYM, 0); - } - /* update symbol definition */ - if (sec) { - put_extern_sym(sym, sec, addr, size); - } else { - ElfW(Sym) *esym; - /* put a common area */ - put_extern_sym(sym, NULL, align, size); - /* XXX: find a nicer way */ - esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; - esym->st_shndx = SHN_COMMON; - } - } else { - CValue cval; - - /* push global reference */ - sym = get_sym_ref(type, sec, addr, size); - cval.ul = 0; - vsetc(type, VT_CONST | VT_SYM, &cval); - vtop->sym = sym; - } - - /* handles bounds now because the symbol must be defined - before for the relocation */ - if (tcc_state->do_bounds_check) { - unsigned long *bounds_ptr; - - greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32); - /* then add global bound info */ - bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long)); - bounds_ptr[0] = 0; /* relocated */ - bounds_ptr[1] = size; - } - } - if (has_init) { - decl_initializer(type, sec, addr, 1, 0); - /* restore parse state if needed */ - if (init_str.str) { - tok_str_free(init_str.str); - restore_parse_state(&saved_parse_state); - } - } - no_alloc: ; -} - -void put_func_debug(Sym *sym) -{ - char buf[512]; - - /* 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; -} - -/* parse an old style function declaration list */ -/* XXX: check multiple parameter */ -static void func_decl_list(Sym *func_sym) -{ - AttributeDef ad; - int v; - Sym *s; - CType btype, type; - - /* parse each declaration */ - while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) { - if (!parse_btype(&btype, &ad)) - expect("declaration list"); - if (((btype.t & VT_BTYPE) == VT_ENUM || - (btype.t & VT_BTYPE) == VT_STRUCT) && - tok == ';') { - /* we accept no variable after */ - } else { - for(;;) { - type = btype; - type_decl(&type, &ad, &v, TYPE_DIRECT); - /* find parameter in function parameter list */ - s = func_sym->next; - while (s != NULL) { - if ((s->v & ~SYM_FIELD) == v) - goto found; - s = s->next; - } - error("declaration for parameter '%s' but no such parameter", - get_tok_str(v, NULL)); - found: - /* check that no storage specifier except 'register' was given */ - if (type.t & VT_STORAGE) - error("storage class specified for '%s'", get_tok_str(v, NULL)); - convert_parameter_type(&type); - /* we can add the type (NOTE: it could be local to the function) */ - s->type = type; - /* accept other parameters */ - if (tok == ',') - next(); - else - break; - } - } - skip(';'); - } -} - -/* parse a function defined by symbol 'sym' and generate its code in - 'cur_text_section' */ -static void gen_function(Sym *sym) -{ - int saved_nocode_wanted = nocode_wanted; - 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; - /* put debug symbol */ - if (tcc_state->do_debug) - put_func_debug(sym); - /* push a dummy symbol to enable local sym storage */ - sym_push2(&local_stack, SYM_FIELD, 0, 0); - gfunc_prolog(&sym->type); - rsym = 0; - block(NULL, NULL, NULL, NULL, 0, 0); - gsym(rsym); - gfunc_epilog(); - cur_text_section->data_offset = ind; - label_pop(&global_label_stack, NULL); - sym_pop(&local_stack, NULL); /* reset local stack */ - /* end of function */ - /* patch symbol size */ - ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = - ind - func_ind; - if (tcc_state->do_debug) { - put_stabn(N_FUN, 0, 0, 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 */ - ind = 0; /* for safety */ - nocode_wanted = saved_nocode_wanted; -} - -static void gen_inline_functions(void) -{ - Sym *sym; - CType *type; - int *str, inline_generated; - - /* iterate while inline function are referenced */ - for(;;) { - inline_generated = 0; - for(sym = global_stack; sym != NULL; sym = sym->prev) { - type = &sym->type; - if (((type->t & VT_BTYPE) == VT_FUNC) && - (type->t & (VT_STATIC | VT_INLINE)) == - (VT_STATIC | VT_INLINE) && - sym->c != 0) { - /* the function was used: generate its code and - convert it to a normal function */ - str = INLINE_DEF(sym->r); - sym->r = VT_SYM | VT_CONST; - sym->type.t &= ~VT_INLINE; - - macro_ptr = str; - next(); - cur_text_section = text_section; - gen_function(sym); - macro_ptr = NULL; /* fail safe */ - - tok_str_free(str); - inline_generated = 1; - } - } - if (!inline_generated) - break; - } - - /* free all remaining inline function tokens */ - for(sym = global_stack; sym != NULL; sym = sym->prev) { - type = &sym->type; - if (((type->t & VT_BTYPE) == VT_FUNC) && - (type->t & (VT_STATIC | VT_INLINE)) == - (VT_STATIC | VT_INLINE)) { - //gr printf("sym %d %s\n", sym->r, get_tok_str(sym->v, NULL)); - if (sym->r == (VT_SYM | VT_CONST)) //gr beware! - continue; - str = INLINE_DEF(sym->r); - tok_str_free(str); - sym->r = 0; /* fail safe */ - } - } -} - -/* 'l' is VT_LOCAL or VT_CONST to define default storage type */ -static void decl(int l) -{ - int v, has_init, r; - CType type, btype; - Sym *sym; - AttributeDef ad; - - while (1) { - if (!parse_btype(&btype, &ad)) { - /* skip redundant ';' */ - /* XXX: find more elegant solution */ - if (tok == ';') { - next(); - continue; - } - if (l == VT_CONST && - (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { - /* global asm block */ - asm_global_instr(); - continue; - } - /* special test for old K&R protos without explicit int - type. Only accepted when defining global data */ - if (l == VT_LOCAL || tok < TOK_DEFINE) - break; - btype.t = VT_INT; - } - if (((btype.t & VT_BTYPE) == VT_ENUM || - (btype.t & VT_BTYPE) == VT_STRUCT) && - tok == ';') { - /* we accept no variable after */ - next(); - continue; - } - while (1) { /* iterate thru each declaration */ - type = btype; - type_decl(&type, &ad, &v, TYPE_DIRECT); -#if 0 - { - char buf[500]; - type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL)); - printf("type = '%s'\n", buf); - } -#endif - if ((type.t & VT_BTYPE) == VT_FUNC) { - /* if old style function prototype, we accept a - declaration list */ - sym = type.ref; - if (sym->c == FUNC_OLD) - func_decl_list(sym); - } - - if (tok == '{') { - if (l == VT_LOCAL) - error("cannot use local functions"); - if ((type.t & VT_BTYPE) != VT_FUNC) - expect("function definition"); - - /* reject abstract declarators in function definition */ - sym = type.ref; - while ((sym = sym->next) != NULL) - if (!(sym->v & ~SYM_FIELD)) - expect("identifier"); - - /* 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; - - sym = sym_find(v); - if (sym) { - if ((sym->type.t & VT_BTYPE) != VT_FUNC) - goto func_error1; - /* specific case: if not func_call defined, we put - the one of the prototype */ - /* XXX: should have default value */ - r = sym->type.ref->r; - if (FUNC_CALL(r) != FUNC_CDECL - && FUNC_CALL(type.ref->r) == FUNC_CDECL) - FUNC_CALL(type.ref->r) = FUNC_CALL(r); - if (FUNC_EXPORT(r)) - FUNC_EXPORT(type.ref->r) = 1; - - if (!is_compatible_types(&sym->type, &type)) { - func_error1: - error("incompatible types for redefinition of '%s'", - get_tok_str(v, NULL)); - } - /* if symbol is already defined, then put complete type */ - sym->type = type; - } else { - /* put function symbol */ - sym = global_identifier_push(v, type.t, 0); - sym->type.ref = type.ref; - } - - /* 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)) { - TokenString func_str; - int block_level; - - tok_str_new(&func_str); - - block_level = 0; - for(;;) { - int t; - if (tok == TOK_EOF) - error("unexpected end of file"); - tok_str_add_tok(&func_str); - t = tok; - next(); - if (t == '{') { - block_level++; - } else if (t == '}') { - block_level--; - if (block_level == 0) - break; - } - } - tok_str_add(&func_str, -1); - tok_str_add(&func_str, 0); - INLINE_DEF(sym->r) = func_str.str; - } else { - /* compute text section */ - cur_text_section = ad.section; - if (!cur_text_section) - cur_text_section = text_section; - sym->r = VT_SYM | VT_CONST; - gen_function(sym); - } - break; - } else { - if (btype.t & VT_TYPEDEF) { - /* save typedefed type */ - /* XXX: test storage specifiers ? */ - sym = sym_push(v, &type, 0, 0); - sym->type.t |= VT_TYPEDEF; - } else if ((type.t & VT_BTYPE) == VT_FUNC) { - /* external function definition */ - /* specific case for func_call attribute */ - if (ad.func_attr) - type.ref->r = ad.func_attr; - external_sym(v, &type, 0); - } else { - /* not lvalue if array */ - r = 0; - if (!(type.t & VT_ARRAY)) - r |= lvalue_type(type.t); - has_init = (tok == '='); - if ((btype.t & VT_EXTERN) || - ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && - !has_init && l == VT_CONST && type.ref->c < 0)) { - /* external variable */ - /* NOTE: as GCC, uninitialized global static - arrays of null size are considered as - extern */ - external_sym(v, &type, r); - } else { - type.t |= (btype.t & VT_STATIC); /* Retain "static". */ - if (type.t & VT_STATIC) - r |= VT_CONST; - else - r |= l; - if (has_init) - next(); - decl_initializer_alloc(&type, &ad, r, - has_init, v, l); - } - } - if (tok != ',') { - skip(';'); - break; - } - next(); - } - } - } -} - diff --git a/05/tcc-0.9.25/tccpe.c b/05/tcc-0.9.25/tccpe.c deleted file mode 100644 index 1e3fdb3..0000000 --- a/05/tcc-0.9.25/tccpe.c +++ /dev/null @@ -1,1559 +0,0 @@ -/* - * 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 - */ - -#ifdef TCC_TARGET_PE - -#define ST_FN static -#define ST_DATA static -#define PUB_FN - -#ifndef _WIN32 -#define stricmp strcasecmp -#define strnicmp strncasecmp -#endif - -#ifndef MAX_PATH -#define MAX_PATH 260 -#endif - -#define PE_MERGE_DATA -// #define PE_PRINT_SECTIONS - -/* ----------------------------------------------------------- */ -#ifndef IMAGE_NT_SIGNATURE -/* ----------------------------------------------------------- */ -/* definitions below are from winnt.h */ - -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; -#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; - DWORD BaseOfData; - - /* NT additional fields. */ - 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[16]; - -} IMAGE_OPTIONAL_HEADER, *PIMAGE_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_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 - -#pragma pack(pop) - -/* ----------------------------------------------------------- */ -#endif /* ndef IMAGE_NT_SIGNATURE */ -/* ----------------------------------------------------------- */ - -#pragma pack(push, 1) - -struct pe_header -{ - IMAGE_DOS_HEADER doshdr; - BYTE dosstub[0x40]; - DWORD nt_sig; - IMAGE_FILE_HEADER filehdr; - IMAGE_OPTIONAL_HEADER opthdr; -}; - -struct pe_import_header { - DWORD first_entry; - DWORD time_date; - DWORD forwarder; - DWORD lib_name_offset; - DWORD first_thunk; -}; - -struct pe_export_header { - DWORD Characteristics; - DWORD TimeDateStamp; - DWORD Version; - DWORD Name; - DWORD Base; - DWORD NumberOfFunctions; - DWORD NumberOfNames; - DWORD AddressOfFunctions; - DWORD AddressOfNames; - DWORD AddressOfNameOrdinals; -}; - -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) - -/* ----------------------------------------------------------- */ -ST_DATA struct pe_header pe_header = { -{ - /* 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 */ - 0x014C, /*WORD Machine; */ - 0x0003, /*WORD NumberOfSections; */ - 0x00000000, /*DWORD TimeDateStamp; */ - 0x00000000, /*DWORD PointerToSymbolTable; */ - 0x00000000, /*DWORD NumberOfSymbols; */ - 0x00E0, /*WORD SizeOfOptionalHeader; */ - 0x030F /*WORD Characteristics; */ -},{ - /* IMAGE_OPTIONAL_HEADER opthdr */ - /* Standard fields. */ - 0x010B, /*WORD Magic; */ - 0x06, /*BYTE MajorLinkerVersion; */ - 0x00, /*BYTE MinorLinkerVersion; */ - 0x00000000, /*DWORD SizeOfCode; */ - 0x00000000, /*DWORD SizeOfInitializedData; */ - 0x00000000, /*DWORD SizeOfUninitializedData; */ - 0x00000000, /*DWORD AddressOfEntryPoint; */ - 0x00000000, /*DWORD BaseOfCode; */ - 0x00000000, /*DWORD BaseOfData; */ - - /* NT additional fields. */ - 0x00400000, /*DWORD ImageBase; */ - 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}} -}}; - -/* ------------------------------------------------------------- */ -/* 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_other , - sec_rsrc , - sec_stab , - sec_reloc , - sec_last -}; - -ST_DATA DWORD pe_sec_flags[] = { - 0x60000020, /* ".text" , */ - 0xC0000040, /* ".data" , */ - 0xC0000080, /* ".bss" , */ - 0x40000040, /* ".idata" , */ - 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; - DWORD imagebase; - DWORD start_addr; - DWORD imp_offs; - DWORD imp_size; - DWORD iat_offs; - DWORD iat_size; - DWORD exp_offs; - DWORD exp_size; - 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 - -void error_noabort(const char *, ...); - -#ifdef _WIN32 -void dbg_printf (const char *fmt, ...) -{ - char buffer[4000]; - va_list arg; - int x; - va_start(arg, fmt); - x = vsprintf (buffer, fmt, arg); - strcpy(buffer+x, "\n"); - OutputDebugString(buffer); -} -#endif - -/* --------------------------------------------*/ - -ST_FN const char* get_alt_symbol(char *buffer, const char *symbol) -{ - const char *p; - p = strrchr(symbol, '@'); - if (p && isnum(p[1]) && symbol[0] == '_') { /* stdcall decor */ - strcpy(buffer, symbol+1)[p-symbol-1] = 0; - } else if (symbol[0] != '_') { /* try non-ansi function */ - buffer[0] = '_', strcpy(buffer + 1, symbol); - } else if (0 == memcmp(symbol, "__imp__", 7)) { /* mingw 2.0 */ - strcpy(buffer, symbol + 6); - } else if (0 == memcmp(symbol, "_imp___", 7)) { /* mingw 3.7 */ - strcpy(buffer, symbol + 6); - } else { - return symbol; - } - return buffer; -} - -ST_FN int pe_find_import(TCCState * s1, const char *symbol) -{ - char buffer[200]; - const char *s; - int sym_index, n = 0; - do { - s = n ? get_alt_symbol(buffer, symbol) : symbol; - sym_index = find_elf_sym(s1->dynsymtab_section, s); - // printf("find %d %s\n", sym_index, s); - } while (0 == sym_index && ++n < 2); - return sym_index; -} - -#if defined _WIN32 || defined __CYGWIN__ - -#ifdef __CYGWIN__ -# include -# define LoadLibrary(s) dlopen(s, RTLD_NOW) -# define GetProcAddress(h,s) dlsym(h, s) -#else -# define dlclose(h) FreeLibrary(h) -#endif - -/* for the -run option: dynamically load symbol from dll */ -void *resolve_sym(struct TCCState *s1, const char *symbol, int type) -{ - char buffer[100]; - int sym_index, dll_index; - void *addr, **m; - DLLReference *dllref; - - sym_index = pe_find_import(s1, symbol); - if (0 == sym_index) - return NULL; - dll_index = ((Elf32_Sym *)s1->dynsymtab_section->data + sym_index)->st_value; - dllref = s1->loaded_dlls[dll_index-1]; - if ( !dllref->handle ) - { - dllref->handle = LoadLibrary(dllref->name); - } - addr = GetProcAddress(dllref->handle, symbol); - if (NULL == addr) - addr = GetProcAddress(dllref->handle, get_alt_symbol(buffer, symbol)); - - if (addr && STT_OBJECT == type) { - /* need to return a pointer to the address for data objects */ - m = (void**)tcc_malloc(sizeof addr), *m = addr, addr = m; -#ifdef MEM_DEBUG - /* yep, we don't free it */ - mem_cur_size -= sizeof (void*); -#endif - } - return addr; -} -#endif - -/*----------------------------------------------------------------------------*/ - -ST_FN 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 - -ST_FN DWORD umax(DWORD a, DWORD b) -{ - return a < b ? b : a; -} - -ST_FN void pe_fpad(FILE *fp, DWORD new_pos) -{ - DWORD pos = ftell(fp); - while (++pos <= new_pos) - fputc(0, fp); -} - -ST_FN DWORD pe_file_align(DWORD n) -{ - return (n + (0x200 - 1)) & ~(0x200 - 1); -} - -ST_FN DWORD pe_virtual_align(DWORD n) -{ - return (n + (0x1000 - 1)) & ~(0x1000 - 1); -} - -ST_FN void pe_align_section(Section *s, int a) -{ - int i = s->data_offset & (a-1); - if (i) - section_ptr_add(s, a - i); -} - -ST_FN void pe_set_datadir(int dir, DWORD addr, DWORD size) -{ - pe_header.opthdr.DataDirectory[dir].VirtualAddress = addr; - pe_header.opthdr.DataDirectory[dir].Size = size; -} - -/*----------------------------------------------------------------------------*/ -ST_FN int pe_write(struct pe_info *pe) -{ - int i; - FILE *op; - DWORD file_offset, r; - - op = fopen(pe->filename, "wb"); - if (NULL == op) { - error_noabort("could not write '%s': %s", pe->filename, strerror(errno)); - return 1; - } - - pe->sizeofheaders = pe_file_align( - sizeof pe_header - + pe->sec_count * sizeof (IMAGE_SECTION_HEADER) - ); - - file_offset = pe->sizeofheaders; - pe_fpad(op, file_offset); - - if (2 == pe->s1->verbose) - printf("-------------------------------" - "\n virt file size section" "\n"); - - for (i = 0; i < pe->sec_count; ++i) { - struct section_info *si = pe->sec_info + i; - const char *sh_name = si->name; - unsigned long addr = si->sh_addr - pe->imagebase; - unsigned long size = si->sh_size; - IMAGE_SECTION_HEADER *psh = &si->ish; - - if (2 == pe->s1->verbose) - printf("%6lx %6lx %6lx %s\n", - addr, file_offset, size, sh_name); - - switch (si->cls) { - case sec_text: - pe_header.opthdr.BaseOfCode = addr; - pe_header.opthdr.AddressOfEntryPoint = addr + pe->start_addr; - break; - - case sec_data: - pe_header.opthdr.BaseOfData = addr; - break; - - case sec_bss: - break; - - case sec_reloc: - pe_set_datadir(IMAGE_DIRECTORY_ENTRY_BASERELOC, addr, size); - break; - - case sec_rsrc: - pe_set_datadir(IMAGE_DIRECTORY_ENTRY_RESOURCE, addr, size); - break; - - case sec_stab: - break; - } - - if (pe->thunk == pe->s1->sections[si->ord]) { - if (pe->imp_size) { - pe_set_datadir(IMAGE_DIRECTORY_ENTRY_IMPORT, - pe->imp_offs + addr, pe->imp_size); - pe_set_datadir(IMAGE_DIRECTORY_ENTRY_IAT, - pe->iat_offs + addr, pe->iat_size); - } - if (pe->exp_size) { - pe_set_datadir(IMAGE_DIRECTORY_ENTRY_EXPORT, - pe->exp_offs + addr, pe->exp_size); - } - } - - strcpy((char*)psh->Name, sh_name); - - psh->Characteristics = pe_sec_flags[si->cls]; - psh->VirtualAddress = addr; - psh->Misc.VirtualSize = size; - pe_header.opthdr.SizeOfImage = - umax(pe_virtual_align(size + addr), pe_header.opthdr.SizeOfImage); - - if (si->data_size) { - psh->PointerToRawData = r = file_offset; - fwrite(si->data, 1, si->data_size, op); - file_offset = pe_file_align(file_offset + si->data_size); - psh->SizeOfRawData = file_offset - r; - pe_fpad(op, file_offset); - } - } - - // pe_header.filehdr.TimeDateStamp = time(NULL); - pe_header.filehdr.NumberOfSections = pe->sec_count; - pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders; - pe_header.opthdr.ImageBase = pe->imagebase; - if (PE_DLL == pe->type) - pe_header.filehdr.Characteristics = 0x230E; - else if (PE_GUI != pe->type) - pe_header.opthdr.Subsystem = 3; - - fseek(op, SEEK_SET, 0); - fwrite(&pe_header, 1, sizeof pe_header, op); - for (i = 0; i < pe->sec_count; ++i) - fwrite(&pe->sec_info[i].ish, 1, sizeof(IMAGE_SECTION_HEADER), op); - fclose (op); - - if (2 == pe->s1->verbose) - printf("-------------------------------\n"); - if (pe->s1->verbose) - printf("<- %s (%lu bytes)\n", pe->filename, file_offset); - - return 0; -} - -/*----------------------------------------------------------------------------*/ - -ST_FN 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; - - dll_index = ((Elf32_Sym *)pe->s1->dynsymtab_section->data + sym_index)->st_value; - if (0 == dll_index) - return NULL; - - 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((void***)&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((void***)&p->symbols, &p->sym_count, s); - s->sym_index = sym_index; - return s; -} - -/*----------------------------------------------------------------------------*/ -ST_FN 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(struct pe_import_header); - pe->iat_offs = dll_ptr + pe->imp_size; - pe->iat_size = (sym_cnt + ndlls) * sizeof(DWORD); - 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) { - struct pe_import_header *hdr; - int k, n, v; - struct pe_import_info *p = pe->imp_info[i]; - const char *name = pe->s1->loaded_dlls[p->dll_index-1]->name; - - /* put the dll name into the import header */ - v = put_elf_str(pe->thunk, name); - - hdr = (struct pe_import_header*)(pe->thunk->data + dll_ptr); - hdr->first_thunk = thk_ptr + rva_base; - hdr->first_entry = ent_ptr + rva_base; - hdr->lib_name_offset = v + rva_base; - - for (k = 0, n = p->sym_count; k <= n; ++k) { - if (k < n) { - DWORD iat_index = p->symbols[k]->iat_index; - int sym_index = p->symbols[k]->sym_index; - Elf32_Sym *imp_sym = (Elf32_Sym *)pe->s1->dynsymtab_section->data + sym_index; - Elf32_Sym *org_sym = (Elf32_Sym *)symtab_section->data + iat_index; - const char *name = pe->s1->dynsymtab_section->link->data + imp_sym->st_name; - - org_sym->st_value = thk_ptr; - org_sym->st_shndx = pe->thunk->sh_num; - 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 */ - } - *(DWORD*)(pe->thunk->data+thk_ptr) = - *(DWORD*)(pe->thunk->data+ent_ptr) = v; - thk_ptr += sizeof (DWORD); - ent_ptr += sizeof (DWORD); - } - dll_ptr += sizeof(struct pe_import_header); - dynarray_reset(&p->symbols, &p->sym_count); - } - dynarray_reset(&pe->imp_info, &pe->imp_count); -} - -/* ------------------------------------------------------------- */ -/* - For now only functions are exported. Export of data - would work, but import requires compiler support to - do an additional indirection. - - For instance: - __declspec(dllimport) extern int something; - - needs to be translated to: - - *(int*)something -*/ - -ST_FN int sym_cmp(const void *va, const void *vb) -{ - const char *ca = ((const char **)va)[1]; - const char *cb = ((const char **)vb)[1]; - return strcmp(ca, cb); -} - -ST_FN void pe_build_exports(struct pe_info *pe) -{ - Elf32_Sym *sym; - int sym_index, sym_end; - DWORD rva_base, func_o, name_o, ord_o, str_o; - struct pe_export_header *hdr; - int sym_count, n, ord, *sorted, *sp; - - FILE *op; - char buf[MAX_PATH]; - const char *dllname; - const char *name; - - rva_base = pe->thunk->sh_addr - pe->imagebase; - sym_count = 0, n = 1, sorted = NULL, op = NULL; - - sym_end = symtab_section->data_offset / sizeof(Elf32_Sym); - for (sym_index = 1; sym_index < sym_end; ++sym_index) { - sym = (Elf32_Sym*)symtab_section->data + sym_index; - name = symtab_section->link->data + sym->st_name; - if ((sym->st_other & 1) - /* export only symbols from actually written sections */ - && pe->s1->sections[sym->st_shndx]->sh_addr) { - dynarray_add((void***)&sorted, &sym_count, (void*)n); - dynarray_add((void***)&sorted, &sym_count, (void*)name); - } - ++n; -#if 0 - if (sym->st_other & 1) - printf("export: %s\n", name); - if (sym->st_other & 2) - printf("stdcall: %s\n", name); -#endif - } - - if (0 == sym_count) - return; - sym_count /= 2; - - qsort (sorted, sym_count, 2 * sizeof sorted[0], 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(struct pe_export_header); - 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 .def */ - strcpy(buf, pe->filename); - strcpy(tcc_fileextension(buf), ".def"); - op = fopen(buf, "w"); - if (NULL == op) { - 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 symbols)\n", buf, sym_count); - } -#endif - - for (sp = sorted, ord = 0; ord < sym_count; ++ord, sp += 2) - { - sym_index = sp[0], name = (const char *)sp[1]; - /* insert actual address later in pe_relocate_rva */ - put_elf_reloc(symtab_section, pe->thunk, - func_o, R_386_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; - tcc_free(sorted); -} - -/* ------------------------------------------------------------- */ -ST_FN void pe_build_reloc (struct pe_info *pe) -{ - DWORD offset, block_ptr, addr; - int count, i; - Elf32_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 = ELF32_R_TYPE(rel->r_info); - addr = rel->r_offset + s->sh_addr; - ++ rel; - if (type != R_386_32) - 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 | IMAGE_REL_BASED_HIGHLOW<<12; - ++count; - continue; - } - -- rel; - - } else if (i < pe->sec_count) { - sr = (s = pe->s1->sections[pe->sec_info[i++].ord])->reloc; - if (sr) { - rel = (Elf32_Rel *)sr->data; - rel_end = (Elf32_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; - } -} - -/* ------------------------------------------------------------- */ -ST_FN 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; - 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; -} - -ST_FN int pe_assign_addresses (struct pe_info *pe) -{ - int i, k, o, c; - DWORD addr; - int *section_order; - struct section_info *si; - Section *s; - - // 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) | 15) + 1; - addr += s->data_offset; - si[-1].sh_size = addr - si[-1].sh_addr; - continue; - } -#endif - strcpy(si->name, s->name); - si->cls = c; - si->ord = k; - si->sh_addr = s->sh_addr = addr = pe_virtual_align(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_REL ? "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; -} - -/* ------------------------------------------------------------- */ -ST_FN void pe_relocate_rva (struct pe_info *pe, Section *s) -{ - Section *sr = s->reloc; - Elf32_Rel *rel, *rel_end; - rel_end = (Elf32_Rel *)(sr->data + sr->data_offset); - for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) - if (ELF32_R_TYPE(rel->r_info) == R_386_RELATIVE) { - int sym_index = ELF32_R_SYM(rel->r_info); - DWORD addr = s->sh_addr; - if (sym_index) { - Elf32_Sym *sym = (Elf32_Sym *)symtab_section->data + sym_index; - addr = sym->st_value; - } - *(DWORD*)(s->data + rel->r_offset) += addr - pe->imagebase; - } -} - -/*----------------------------------------------------------------------------*/ -ST_FN int pe_check_symbols(struct pe_info *pe) -{ - Elf32_Sym *sym; - int sym_index, sym_end; - int ret = 0; - - pe_align_section(text_section, 8); - - sym_end = symtab_section->data_offset / sizeof(Elf32_Sym); - for (sym_index = 1; sym_index < sym_end; ++sym_index) { - - sym = (Elf32_Sym*)symtab_section->data + sym_index; - if (sym->st_shndx == SHN_UNDEF) { - - const char *name = symtab_section->link->data + sym->st_name; - unsigned type = ELF32_ST_TYPE(sym->st_info); - int imp_sym = pe_find_import(pe->s1, name); - struct import_symbol *is; - - if (0 == imp_sym) - goto not_found; - is = pe_add_import(pe, imp_sym); - if (!is) - goto not_found; - - if (type == STT_FUNC) { - unsigned long offset = is->thk_offset; - if (offset) { - /* got aliased symbol, like stricmp and _stricmp */ - - } else { - char buffer[100]; - - offset = text_section->data_offset; - /* add the 'jmp IAT[x]' instruction */ - *(WORD*)section_ptr_add(text_section, 8) = 0x25FF; - - /* 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), - ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), - 0, SHN_UNDEF, buffer); - put_elf_reloc(symtab_section, text_section, - offset + 2, R_386_32, is->iat_index); - is->thk_offset = offset; - } - - /* tcc_realloc might have altered sym's address */ - sym = (Elf32_Sym*)symtab_section->data + sym_index; - - /* patch the original symbol */ - sym->st_value = offset; - sym->st_shndx = text_section->sh_num; - sym->st_other &= ~1; /* 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: - error_noabort("undefined symbol '%s'", name); - ret = 1; - - } else if (pe->s1->rdynamic - && ELF32_ST_BIND(sym->st_info) != STB_LOCAL) { - /* if -rdynamic option, then export all non local symbols */ - sym->st_other |= 1; - } - } - return ret; -} - -/*----------------------------------------------------------------------------*/ -#ifdef PE_PRINT_SECTIONS -ST_FN void pe_print_section(FILE * f, Section * s) -{ - /* just if you'r 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", s->sh_addr); - fprintf(f, "\ncontents %08X", l); - fprintf(f, "\n\n"); - - if (s->sh_type == SHT_NOBITS) - return; - - if (0 == l) - return; - - if (s->sh_type == SHT_SYMTAB) - m = sizeof(Elf32_Sym); - if (s->sh_type == SHT_REL) - m = sizeof(Elf32_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_REL) { - 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) { - Elf32_Sym *sym = (Elf32_Sym *) (p + i); - const char *name = s->link->data + sym->st_name; - fprintf(f, " %04X %04X %04X %02X %02X %02X %04X \"%s\"", - sym->st_name, - sym->st_value, - sym->st_size, - ELF32_ST_BIND(sym->st_info), - ELF32_ST_TYPE(sym->st_info), - sym->st_other, sym->st_shndx, name); - - } else if (s->sh_type == SHT_REL) { - Elf32_Rel *rel = (Elf32_Rel *) (p + i); - Elf32_Sym *sym = - (Elf32_Sym *) s->link->data + ELF32_R_SYM(rel->r_info); - const char *name = s->link->link->data + sym->st_name; - fprintf(f, " %04X %02X %04X \"%s\"", - rel->r_offset, - ELF32_R_TYPE(rel->r_info), - ELF32_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"); -} - -ST_FN void pe_print_sections(TCCState *s1, const char *fname) -{ - Section *s; - FILE *f; - int i; - f = fopen(fname, "wt"); - 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 - -/* ------------------------------------------------------------- - * This is for compiled windows resources in 'coff' format - * as generated by 'windres.exe -O coff ...'. - */ - -PUB_FN int pe_test_res_file(void *v, int size) -{ - struct pe_rsrc_header *p = (struct pe_rsrc_header *)v; - return - size >= IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_SHORT_NAME /* = 28 */ - && p->filehdr.Machine == 0x014C - && 1 == p->filehdr.NumberOfSections - && 0 == strcmp(p->sectionhdr.Name, ".rsrc") - ; -} - -ST_FN int read_n(int fd, void *ptr, unsigned size) -{ - return size == read(fd, ptr, size); -} - -PUB_FN int pe_load_res_file(TCCState *s1, int fd) -{ - struct pe_rsrc_header hdr; - Section *rsrc_section; - int i, ret = -1; - BYTE *ptr; - - lseek (fd, 0, SEEK_SET); - if (!read_n(fd, &hdr, sizeof hdr)) - goto quit; - if (!pe_test_res_file(&hdr, sizeof hdr)) - goto quit; - - rsrc_section = new_section(s1, ".rsrc", SHT_PROGBITS, SHF_ALLOC); - ptr = section_ptr_add(rsrc_section, hdr.sectionhdr.SizeOfRawData); - lseek (fd, hdr.sectionhdr.PointerToRawData, SEEK_SET); - if (!read_n(fd, ptr, hdr.sectionhdr.SizeOfRawData)) - goto quit; - - lseek (fd, hdr.sectionhdr.PointerToRelocations, SEEK_SET); - for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i) - { - struct pe_rsrc_reloc rel; - if (!read_n(fd, &rel, sizeof rel)) - goto quit; - // printf("rsrc_reloc: %x %x %x\n", rel.offset, rel.size, rel.type); - if (rel.type != 7) /* DIR32NB */ - goto quit; - put_elf_reloc(symtab_section, rsrc_section, - rel.offset, R_386_RELATIVE, 0); - } - ret = 0; -quit: - if (ret) - error_noabort("unrecognized resource file format"); - return ret; -} - -/* ------------------------------------------------------------- */ -ST_FN char *trimfront(char *p) -{ - while (*p && (unsigned char)*p <= ' ') - ++p; - return p; -} - -ST_FN char *trimback(char *a, char *e) -{ - while (e > a && (unsigned char)e[-1] <= ' ') - --e; - *e = 0;; - return a; -} - -ST_FN char *get_line(char *line, int size, FILE *fp) -{ - if (NULL == fgets(line, size, fp)) - return NULL; - trimback(line, strchr(line, 0)); - return trimfront(line); -} - -/* ------------------------------------------------------------- */ -PUB_FN int pe_load_def_file(TCCState *s1, int fd) -{ - DLLReference *dllref; - int state = 0, ret = -1; - char line[400], dllname[80], *p; - FILE *fp = fdopen(dup(fd), "rb"); - - if (NULL == fp) - goto quit; - - for (;;) { - p = get_line(line, sizeof line, fp); - if (NULL == p) - break; - if (0 == *p || ';' == *p) - continue; - switch (state) { - case 0: - if (0 != strnicmp(p, "LIBRARY", 7)) - goto quit; - strcpy(dllname, trimfront(p+7)); - ++state; - continue; - - case 1: - if (0 != stricmp(p, "EXPORTS")) - goto quit; - ++state; - continue; - - case 2: - dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); - strcpy(dllref->name, dllname); - dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); - ++state; - - default: - add_elf_sym(s1->dynsymtab_section, - s1->nb_loaded_dlls, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), 0, - text_section->sh_num, p); - continue; - } - } - ret = 0; -quit: - if (fp) - fclose(fp); - if (ret) - error_noabort("unrecognized export definition file format"); - return ret; -} - -/* ------------------------------------------------------------- */ - -ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe) -{ - const char *start_symbol; - unsigned long addr = 0; - int pe_type = 0; - - if (find_elf_sym(symtab_section, "_WinMain@16")) - pe_type = 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; - } - - start_symbol = - TCC_OUTPUT_MEMORY == s1->output_type - ? PE_GUI == pe_type ? "_runwinmain" : NULL - : PE_DLL == pe_type ? "__dllstart@12" - : PE_GUI == pe_type ? "_winstart" : "_start" - ; - - /* grab the startup code from libtcc1 */ - if (start_symbol) - add_elf_sym(symtab_section, - 0, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - SHN_UNDEF, start_symbol); - - if (0 == s1->nostdlib) { - tcc_add_library(s1, "tcc1"); -#ifdef __CYGWIN__ - tcc_add_library(s1, "cygwin1"); -#else - tcc_add_library(s1, "msvcrt"); -#endif - tcc_add_library(s1, "kernel32"); - if (PE_DLL == pe_type || PE_GUI == pe_type) { - tcc_add_library(s1, "user32"); - tcc_add_library(s1, "gdi32"); - } - } - - if (start_symbol) { - addr = (unsigned long)tcc_get_symbol_err(s1, start_symbol); - if (s1->output_type == TCC_OUTPUT_MEMORY && addr) - /* for -run GUI's, put '_runwinmain' instead of 'main' */ - add_elf_sym(symtab_section, - addr, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - text_section->sh_num, "main"); - } - - if (pe) { - pe->type = pe_type; - pe->start_addr = addr; - } -} - -PUB_FN void pe_add_runtime(TCCState *s1) -{ - pe_add_runtime_ex(s1, NULL); -} - -PUB_FN 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; - - pe_add_runtime_ex(s1, &pe); - relocate_common_syms(); /* assign bss adresses */ - tcc_add_linker_symbols(s1); - - ret = pe_check_symbols(&pe); - if (0 == ret) { - if (PE_DLL == pe.type) { - pe.reloc = new_section(pe.s1, ".reloc", SHT_PROGBITS, 0); - pe.imagebase = 0x10000000; - } else { - pe.imagebase = 0x00400000; - } - pe_assign_addresses(&pe); - relocate_syms(s1, 0); - for (i = 1; i < s1->nb_sections; ++i) { - Section *s = s1->sections[i]; - if (s->reloc) { - relocate_section(s1, s); - pe_relocate_rva(&pe, s); - } - } - if (s1->nb_errors) - ret = 1; - else - ret = pe_write(&pe); - tcc_free(pe.sec_info); - } - -#ifdef PE_PRINT_SECTIONS - pe_print_sections(s1, "tcc.log"); -#endif - return ret; -} - -/* ------------------------------------------------------------- */ -#endif /* def TCC_TARGET_PE */ -/* ------------------------------------------------------------- */ diff --git a/05/tcc-0.9.25/tccpp.c b/05/tcc-0.9.25/tccpp.c deleted file mode 100644 index 9ae2a1e..0000000 --- a/05/tcc-0.9.25/tccpp.c +++ /dev/null @@ -1,2936 +0,0 @@ -/* - * 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 - */ - - -static const char tcc_keywords[] = -#define DEF(id, str) str "\n" -#include "tcctok.h" -#undef DEF -; - -/* WARNING: the content of this string encodes token numbers */ -static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266"; - -/* true if isid(c) || isnum(c) */ -static unsigned char isidnum_table[256-CH_EOF]; - - -struct macro_level { - struct macro_level *prev; - int *p; -}; - -static void next_nomacro(void); -static void next_nomacro_spc(void); -static void macro_subst(TokenString *tok_str, Sym **nested_list, - const int *macro_str, struct macro_level **can_read_stream); - - -/* 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) - error("memory full"); - - /* 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 *)); - if (!ptable) - error("memory full"); - table_ident = ptable; - } - - ts = tcc_malloc(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) * 263 + (c)) - -/* find a token and add it if not found */ -static TokenSym *tok_alloc(const char *str, int len) -{ - TokenSym *ts, **pts; - int i; - unsigned int h; - - h = TOK_HASH_INIT; - for(i=0;ilen == 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 */ -char *get_tok_str(int v, CValue *cv) -{ - static char buf[STRING_MAX_SIZE + 1]; - static CString cstr_buf; - CString *cstr; - unsigned char *q; - char *p; - int i, len; - - /* NOTE: to go faster, we give a fixed buffer for small strings */ - cstr_reset(&cstr_buf); - cstr_buf.data = buf; - cstr_buf.size_allocated = sizeof(buf); - p = buf; - - switch(v) { - case TOK_CINT: - case TOK_CUINT: - /* XXX: not quite exact, but only useful for testing */ - sprintf(p, "%u", cv->ui); - break; - case TOK_CLLONG: - case TOK_CULLONG: - /* XXX: not quite exact, but only useful for testing */ - sprintf(p, "%Lu", cv->ull); - 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: - cstr = cv->cstr; - len = cstr->size - 1; - for(i=0;idata)[i]); - cstr_ccat(&cstr_buf, '\0'); - break; - case TOK_LSTR: - cstr_ccat(&cstr_buf, 'L'); - case TOK_STR: - cstr = cv->cstr; - cstr_ccat(&cstr_buf, '\"'); - if (v == TOK_STR) { - len = cstr->size - 1; - for(i=0;idata)[i]); - } else { - len = (cstr->size / sizeof(nwchar_t)) - 1; - for(i=0;idata)[i]); - } - cstr_ccat(&cstr_buf, '\"'); - cstr_ccat(&cstr_buf, '\0'); - break; - 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, ">>="); - default: - if (v < TOK_IDENT) { - /* search in two bytes table */ - q = tok_two_chars; - while (*q) { - if (q[2] == v) { - *p++ = q[0]; - *p++ = q[1]; - *p = '\0'; - return buf; - } - q += 3; - } - 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; -} - -/* fill input buffer and peek next char */ -static int tcc_peekc_slow(BufferedFile *bf) -{ - int len; - /* only tries to read if really end of buffer */ - if (bf->buf_ptr >= bf->buf_end) { - if (bf->fd != -1) { -#if defined(PARSE_DEBUG) - len = 8; -#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; - } -} - -/* return the current character, handling end of block if necessary - (but not stray) */ -static int handle_eob(void) -{ - return tcc_peekc_slow(file); -} - -/* read next char from current input file and handle end of input buffer */ -static inline 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()) - 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; - - if (p >= file->buf_end) { - file->buf_ptr = p; - c = handle_eob(); - p = file->buf_ptr; - if (c == '\\') - goto parse_stray; - } else { - parse_stray: - file->buf_ptr = p; - ch = *p; - handle_stray(); - 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 */ -static 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 */ -static 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 == '\\') { - /* 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) { - error("unexpected end of file in comment"); - } else if (c == '\\') { - p++; - } - } - } - end_of_comment: - p++; - return p; -} - -#define cinp minp - -static inline void skip_spaces(void) -{ - while (is_space(ch)) - cinp(); -} - -static inline int check_space(int t, int *spc) -{ - if (is_space(t)) { - 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 */ - 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 */ -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; - } - break; -_default: - default: - p++; - break; - } - start_of_line = 0; - } - the_end: ; - file->buf_ptr = p; -} - -/* ParseState handling */ - -/* XXX: currently, no include file info is stored. Thus, we cannot display - accurate messages if the function or data definition spans multiple - files */ - -/* save current parse state in 's' */ -void save_parse_state(ParseState *s) -{ - s->line_num = file->line_num; - s->macro_ptr = macro_ptr; - s->tok = tok; - s->tokc = tokc; -} - -/* restore parse state from 's' */ -void restore_parse_state(ParseState *s) -{ - file->line_num = s->line_num; - macro_ptr = s->macro_ptr; - tok = s->tok; - tokc = s->tokc; -} - -/* return the number of additional 'ints' necessary to store the - token */ -static inline int tok_ext_size(int t) -{ - switch(t) { - /* 4 bytes */ - case TOK_CINT: - case TOK_CUINT: - case TOK_CCHAR: - case TOK_LCHAR: - case TOK_CFLOAT: - case TOK_LINENUM: - return 1; - case TOK_STR: - case TOK_LSTR: - case TOK_PPNUM: - error("unsupported token"); - return 1; - case TOK_CDOUBLE: - case TOK_CLLONG: - case TOK_CULLONG: - return 2; - case TOK_CLDOUBLE: - return LDOUBLE_SIZE / 4; - default: - return 0; - } -} - -/* token string handling */ - -static inline void tok_str_new(TokenString *s) -{ - s->str = NULL; - s->len = 0; - s->allocated_len = 0; - s->last_line_num = -1; -} - -static void tok_str_free(int *str) -{ - tcc_free(str); -} - -static int *tok_str_realloc(TokenString *s) -{ - int *str, len; - - if (s->allocated_len == 0) { - len = 8; - } else { - len = s->allocated_len * 2; - } - str = tcc_realloc(s->str, len * sizeof(int)); - if (!str) - error("memory full"); - s->allocated_len = len; - s->str = str; - return str; -} - -static 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); - str[len++] = t; - s->len = len; -} - -static void tok_str_add2(TokenString *s, int t, CValue *cv) -{ - int len, *str; - - len = s->len; - str = s->str; - - /* allocate space for worst case */ - if (len + TOK_MAX_SIZE > s->allocated_len) - str = tok_str_realloc(s); - str[len++] = t; - switch(t) { - case TOK_CINT: - case TOK_CUINT: - case TOK_CCHAR: - case TOK_LCHAR: - case TOK_CFLOAT: - case TOK_LINENUM: - str[len++] = cv->tab[0]; - break; - case TOK_PPNUM: - case TOK_STR: - case TOK_LSTR: - { - int nb_words; - CString *cstr; - - nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2; - while ((len + nb_words) > s->allocated_len) - str = tok_str_realloc(s); - cstr = (CString *)(str + len); - cstr->data = NULL; - cstr->size = cv->cstr->size; - cstr->data_allocated = NULL; - cstr->size_allocated = cstr->size; - memcpy((char *)cstr + sizeof(CString), - cv->cstr->data, cstr->size); - len += nb_words; - } - break; - case TOK_CDOUBLE: - case TOK_CLLONG: - case TOK_CULLONG: -#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' */ -static 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); -} - -#if LDOUBLE_SIZE == 16 -#define LDOUBLE_GET(p, cv) \ - cv.tab[0] = p[0]; \ - cv.tab[1] = p[1]; \ - cv.tab[2] = p[2]; \ - cv.tab[3] = p[3]; -#elif LDOUBLE_SIZE == 12 -#define LDOUBLE_GET(p, cv) \ - cv.tab[0] = p[0]; \ - cv.tab[1] = p[1]; \ - cv.tab[2] = p[2]; -#elif LDOUBLE_SIZE == 8 -#define LDOUBLE_GET(p, cv) \ - cv.tab[0] = p[0]; \ - cv.tab[1] = p[1]; -#else -#error add long double size support -#endif - - -/* get a token from an integer array and increment pointer - accordingly. we code it as a macro to avoid pointer aliasing. */ -#define TOK_GET(t, p, cv) \ -{ \ - t = *p++; \ - switch(t) { \ - case TOK_CINT: \ - case TOK_CUINT: \ - case TOK_CCHAR: \ - case TOK_LCHAR: \ - case TOK_CFLOAT: \ - case TOK_LINENUM: \ - cv.tab[0] = *p++; \ - break; \ - case TOK_STR: \ - case TOK_LSTR: \ - case TOK_PPNUM: \ - cv.cstr = (CString *)p; \ - cv.cstr->data = (char *)p + sizeof(CString);\ - p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\ - break; \ - case TOK_CDOUBLE: \ - case TOK_CLLONG: \ - case TOK_CULLONG: \ - cv.tab[0] = p[0]; \ - cv.tab[1] = p[1]; \ - p += 2; \ - break; \ - case TOK_CLDOUBLE: \ - LDOUBLE_GET(p, cv); \ - p += LDOUBLE_SIZE / 4; \ - break; \ - default: \ - break; \ - } \ -} - -/* defines handling */ -static inline void define_push(int v, int macro_type, int *str, Sym *first_arg) -{ - Sym *s; - - s = sym_push2(&define_stack, v, macro_type, (long)str); - s->next = first_arg; - - table_ident[v - TOK_IDENT]->sym_define = s; -} - -/* undefined a define symbol. Its name is just set to zero */ -static void define_undef(Sym *s) -{ - int v; - v = s->v; - if (v >= TOK_IDENT && v < tok_ident) - table_ident[v - TOK_IDENT]->sym_define = NULL; - s->v = 0; -} - -static inline 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' */ -static void free_defines(Sym *b) -{ - Sym *top, *top1; - int v; - - top = define_stack; - while (top != b) { - top1 = top->prev; - /* do not free args or predefined defines */ - if (top->c) - tok_str_free((int *)top->c); - v = top->v; - if (v >= TOK_IDENT && v < tok_ident) - table_ident[v - TOK_IDENT]->sym_define = NULL; - sym_free(top); - top = top1; - } - define_stack = b; -} - -/* label lookup */ -static Sym *label_find(int v) -{ - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) - return NULL; - return table_ident[v]->sym_label; -} - -static 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. */ -static void label_pop(Sym **ptop, Sym *slast) -{ - Sym *s, *s1; - for(s = *ptop; s != slast; s = s1) { - s1 = s->prev; - if (s->r == LABEL_DECLARED) { - warning("label '%s' declared but not used", get_tok_str(s->v, NULL)); - } else if (s->r == LABEL_FORWARD) { - 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, (long)s->next, 1); - } - } - /* remove label */ - table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok; - sym_free(s); - } - *ptop = slast; -} - -/* eval an expression for #if/#elif */ -static int expr_preprocess(void) -{ - int c, t; - TokenString str; - - tok_str_new(&str); - while (tok != TOK_LINEFEED && tok != TOK_EOF) { - next(); /* do macro subst */ - if (tok == TOK_DEFINED) { - next_nomacro(); - t = tok; - if (t == '(') - next_nomacro(); - c = define_find(tok) != 0; - if (t == '(') - next_nomacro(); - 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); - } - tok_str_add(&str, -1); /* simulate end of file */ - tok_str_add(&str, 0); - /* now evaluate C constant expression */ - macro_ptr = str.str; - next(); - c = expr_const(); - macro_ptr = NULL; - tok_str_free(str.str); - return c != 0; -} - -#if defined(PARSE_DEBUG) || defined(PP_DEBUG) -static void tok_print(int *str) -{ - int t; - CValue cval; - - printf("<"); - while (1) { - TOK_GET(t, str, cval); - if (!t) - break; - printf("%s", get_tok_str(t, &cval)); - } - printf(">\n"); -} -#endif - -/* parse after #define */ -static void parse_define(void) -{ - Sym *s, *first, **ps; - int v, t, varg, is_vaargs, spc; - TokenString str; - - v = tok; - if (v < TOK_IDENT) - error("invalid macro name '%s'", get_tok_str(tok, &tokc)); - /* XXX: should check if same macro (ANSI) */ - first = NULL; - t = MACRO_OBJ; - /* '(' must be just after macro definition for MACRO_FUNC */ - next_nomacro_spc(); - if (tok == '(') { - next_nomacro(); - ps = &first; - while (tok != ')') { - 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) - error("badly punctuated parameter list"); - s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0); - *ps = s; - ps = &s->next; - if (tok != ',') - break; - next_nomacro(); - } - if (tok == ')') - next_nomacro_spc(); - t = MACRO_FUNC; - } - tok_str_new(&str); - spc = 2; - /* EOF testing necessary for '-D' handling */ - while (tok != TOK_LINEFEED && tok != TOK_EOF) { - /* remove spaces around ## and after '#' */ - if (TOK_TWOSHARPS == tok) { - if (1 == spc) - --str.len; - spc = 2; - } else if ('#' == tok) { - spc = 2; - } else if (check_space(tok, &spc)) { - goto skip; - } - tok_str_add2(&str, tok, &tokc); - skip: - next_nomacro_spc(); - } - if (spc == 1) - --str.len; /* remove trailing space */ - tok_str_add(&str, 0); -#ifdef PP_DEBUG - printf("define %s %d: ", get_tok_str(v, NULL), t); - tok_print(str.str); -#endif - define_push(v, t, str.str, first); -} - -static inline int hash_cached_include(int type, const char *filename) -{ - const unsigned char *s; - unsigned int h; - - h = TOK_HASH_INIT; - h = TOK_HASH_FUNC(h, type); - s = filename; - while (*s) { - h = TOK_HASH_FUNC(h, *s); - s++; - } - h &= (CACHED_INCLUDES_HASH_SIZE - 1); - return h; -} - -/* XXX: use a token or a hash table to accelerate matching ? */ -static CachedInclude *search_cached_include(TCCState *s1, - int type, const char *filename) -{ - CachedInclude *e; - int i, h; - h = hash_cached_include(type, filename); - i = s1->cached_includes_hash[h]; - for(;;) { - if (i == 0) - break; - e = s1->cached_includes[i - 1]; - if (e->type == type && !PATHCMP(e->filename, filename)) - return e; - i = e->hash_next; - } - return NULL; -} - -static inline void add_cached_include(TCCState *s1, int type, - const char *filename, int ifndef_macro) -{ - CachedInclude *e; - int h; - - if (search_cached_include(s1, type, filename)) - return; -#ifdef INC_DEBUG - printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL)); -#endif - e = tcc_malloc(sizeof(CachedInclude) + strlen(filename)); - if (!e) - return; - e->type = type; - strcpy(e->filename, filename); - e->ifndef_macro = ifndef_macro; - dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e); - /* add in hash table */ - h = hash_cached_include(type, filename); - e->hash_next = s1->cached_includes_hash[h]; - s1->cached_includes_hash[h] = s1->nb_cached_includes; -} - -static void pragma_parse(TCCState *s1) -{ - int val; - - next(); - 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: - error("out of pack stack"); - } - s1->pack_stack_ptr--; - } else { - 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) { - pack_error: - error("invalid pack pragma"); - } - val = tokc.i; - if (val < 1 || val > 16 || (val & (val - 1)) != 0) - goto pack_error; - next(); - } - *s1->pack_stack_ptr = val; - skip(')'); - } - } -} - -/* is_bof is true if first non space token at beginning of file */ -static 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_LINEFEED; - next_nomacro(); - redo: - switch(tok) { - case TOK_DEFINE: - next_nomacro(); - parse_define(); - break; - case TOK_UNDEF: - next_nomacro(); - 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 { - /* computed #include : either we have only strings or - we have anything enclosed in '<>' */ - next(); - buf[0] = '\0'; - if (tok == TOK_STR) { - while (tok != TOK_LINEFEED) { - if (tok != TOK_STR) { - include_syntax: - error("'#include' expects \"FILENAME\" or "); - } - pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data); - next(); - } - c = '\"'; - } else { - int len; - 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] != '>') - goto include_syntax; - memmove(buf, buf + 1, len - 2); - buf[len - 2] = '\0'; - c = '>'; - } - } - - if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) - error("#include recursion too deep"); - - n = s1->nb_include_paths + s1->nb_sysinclude_paths; - for (i = -2; i < n; ++i) { - char buf1[sizeof file->filename]; - BufferedFile *f; - CachedInclude *e; - const char *path; - int size; - - if (i == -2) { - /* check absolute include path */ - if (!IS_ABSPATH(buf)) - continue; - buf1[0] = 0; - - } else if (i == -1) { - /* search in current dir if "header.h" */ - if (c != '\"') - continue; - size = tcc_basename(file->filename) - file->filename; - memcpy(buf1, file->filename, size); - buf1[size] = '\0'; - - } else { - /* search in all the include paths */ - if (i < s1->nb_include_paths) - path = s1->include_paths[i]; - else - path = s1->sysinclude_paths[i - s1->nb_include_paths]; - pstrcpy(buf1, sizeof(buf1), path); - pstrcat(buf1, sizeof(buf1), "/"); - } - - pstrcat(buf1, sizeof(buf1), buf); - - e = search_cached_include(s1, c, buf1); - if (e && define_find(e->ifndef_macro)) { - /* no need to parse the include because the 'ifndef macro' - is defined */ -#ifdef INC_DEBUG - printf("%s: skipping %s\n", file->filename, buf); -#endif - f = NULL; - } else { - f = tcc_open(s1, buf1); - if (!f) - continue; - } - - if (tok == TOK_INCLUDE_NEXT) { - tok = TOK_INCLUDE; - if (f) - tcc_close(f); - continue; - } - - if (!f) - goto include_done; - -#ifdef INC_DEBUG - printf("%s: including %s\n", file->filename, buf1); -#endif - - /* XXX: fix current line init */ - /* push current file in stack */ - *s1->include_stack_ptr++ = file; - f->inc_type = c; - pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf1); - file = f; - /* add include file debug info */ - if (tcc_state->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; - } - 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) - 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) - error("memory full"); - *s1->ifdef_stack_ptr++ = c; - goto test_skip; - case TOK_ELSE: - if (s1->ifdef_stack_ptr == s1->ifdef_stack) - error("#else without matching #if"); - if (s1->ifdef_stack_ptr[-1] & 2) - error("#else after #else"); - c = (s1->ifdef_stack_ptr[-1] ^= 3); - goto test_skip; - case TOK_ELIF: - if (s1->ifdef_stack_ptr == s1->ifdef_stack) - error("#elif without matching #if"); - c = s1->ifdef_stack_ptr[-1]; - if (c > 1) - error("#elif after #else"); - /* last #if/#elif expression was true: we skip */ - if (c == 1) - goto skip; - c = expr_preprocess(); - s1->ifdef_stack_ptr[-1] = c; - test_skip: - if (!(c & 1)) { - skip: - preprocess_skip(); - is_bof = 0; - goto redo; - } - break; - case TOK_ENDIF: - if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr) - 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_LINE: - next(); - if (tok != TOK_CINT) - error("#line"); - file->line_num = tokc.i - 1; /* the line number will be incremented after */ - next(); - if (tok != TOK_LINEFEED) { - if (tok != TOK_STR) - error("#line"); - pstrcpy(file->filename, sizeof(file->filename), - (char *)tokc.cstr->data); - } - 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) - error("#error %s", buf); - else - warning("#warning %s", buf); - break; - case TOK_PRAGMA: - pragma_parse(s1); - break; - default: - if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) { - /* '!' is ignored to allow C scripts. numbers are ignored - to emulate cpp behaviour */ - } else { - if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS)) - warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc)); - } - break; - } - /* 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 <= '~') - warning("unknown escape sequence: \'\\%c\'", c); - else - warning("unknown escape sequence: \'\\x%x\'", c); - break; - } - } - p++; - add_char_nonext: - if (!is_long) - cstr_ccat(outstr, c); - else - cstr_wccat(outstr, c); - } - /* add a trailing '\0' */ - if (!is_long) - cstr_ccat(outstr, '\0'); - else - cstr_wccat(outstr, '\0'); -} - -/* we use 64 bit numbers */ -#define BN_SIZE 2 - -/* bn = (bn << shift) | or_val */ -void bn_lshift(unsigned int *bn, int shift, int or_val) -{ - int i; - unsigned int v; - for(i=0;i> (32 - shift); - } -} - -void bn_zero(unsigned int *bn) -{ - int i; - for(i=0;i= '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: - 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 = 2; - 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) - 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++; - tok = TOK_CLDOUBLE; - /* XXX: not large enough */ - tokc.ld = (long double)d; - } 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++; - tok = TOK_CLDOUBLE; - tokc.ld = strtold(token_buf, NULL); - } else { - tok = TOK_CDOUBLE; - tokc.d = strtod(token_buf, NULL); - } - } - } else { - unsigned long long n, n1; - int lcount, ucount; - - /* 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) - error("invalid digit"); - } - n1 = n; - n = n * b + t; - /* detect overflow */ - /* XXX: this test is not reliable */ - if (n < n1) - error("integer constant overflow"); - } - - /* XXX: not exactly ANSI compliant */ - if ((n & 0xffffffff00000000LL) != 0) { - if ((n >> 63) != 0) - tok = TOK_CULLONG; - else - tok = TOK_CLLONG; - } else if (n > 0x7fffffff) { - tok = TOK_CUINT; - } else { - tok = TOK_CINT; - } - lcount = 0; - ucount = 0; - for(;;) { - t = toup(ch); - if (t == 'L') { - if (lcount >= 2) - error("three 'l's in integer constant"); - lcount++; - if (lcount == 2) { - if (tok == TOK_CINT) - tok = TOK_CLLONG; - else if (tok == TOK_CUINT) - tok = TOK_CULLONG; - } - ch = *p++; - } else if (t == 'U') { - if (ucount >= 1) - error("two 'u's in integer constant"); - ucount++; - if (tok == TOK_CINT) - tok = TOK_CUINT; - else if (tok == TOK_CLLONG) - tok = TOK_CULLONG; - ch = *p++; - } else { - break; - } - } - if (tok == TOK_CINT || tok == TOK_CUINT) - tokc.ui = n; - else - tokc.ull = n; - } - if (ch) - 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; - 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++; - goto keep_tok_flags; - case '\f': - case '\v': - case '\r': - p++; - goto redo_no_start; - case '\\': - /* first look if it is in fact an end of buffer */ - if (p >= file->buf_end) { - file->buf_ptr = p; - handle_eob(); - p = file->buf_ptr; - if (p >= file->buf_end) - goto parse_eof; - else - goto redo_no_start; - } else { - file->buf_ptr = p; - ch = *p; - handle_stray(); - p = file->buf_ptr; - goto redo_no_start; - } - parse_eof: - { - 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 (s1->include_stack_ptr == s1->include_stack || - !(parse_flags & PARSE_FLAG_PREPROCESS)) { - /* 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 - add_cached_include(s1, file->inc_type, file->inc_filename, - file->ifndef_macro_saved); - } - - /* add end of include file debug info */ - if (tcc_state->do_debug) { - put_stabd(N_EINCL, 0, 0); - } - /* pop include stack */ - tcc_close(file); - s1->include_stack_ptr--; - file = *s1->include_stack_ptr; - p = file->buf_ptr; - goto redo_no_start; - } - } - break; - - case '\n': - file->line_num++; - tok_flags |= TOK_FLAG_BOL; - p++; - 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 redo_no_start; - } else { - if (c == '#') { - p++; - tok = TOK_TWOSHARPS; - } else { - if (parse_flags & PARSE_FLAG_ASM_COMMENTS) { - p = parse_line_comment(p - 1); - goto redo_no_start; - } else { - tok = '#'; - } - } - } - break; - - 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); - p++; - for(;;) { - c = *p; - if (!isidnum_table[c-CH_EOF]) - break; - h = TOK_HASH_FUNC(h, c); - p++; - } - if (c != '\\') { - TokenSym **pts; - int len; - - /* fast case : no stray found, so we have the full token - and we have already hashed it */ - len = p - p1; - 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, p1, len); - token_found: ; - } else { - /* slower case */ - cstr_reset(&tokcstr); - - while (p1 < p) { - cstr_ccat(&tokcstr, *p1); - p1++; - } - p--; - PEEKC(c, p); - parse_ident_slow: - while (isidnum_table[c-CH_EOF]) { - 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': - - cstr_reset(&tokcstr); - /* after the first digit, accept digits, alpha, '.' or sign if - prefixed by 'eEpP' */ - parse_num: - for(;;) { - t = c; - cstr_ccat(&tokcstr, c); - PEEKC(c, p); - if (!(isnum(c) || isid(c) || c == '.' || - ((c == '+' || c == '-') && - (t == 'e' || t == 'E' || t == 'p' || t == 'P')))) - break; - } - /* We add a trailing '\0' to ease parsing */ - cstr_ccat(&tokcstr, '\0'); - tokc.cstr = &tokcstr; - tok = TOK_PPNUM; - break; - case '.': - /* special dot handling because it can also start a number */ - PEEKC(c, p); - if (isnum(c)) { - cstr_reset(&tokcstr); - cstr_ccat(&tokcstr, '.'); - goto parse_num; - } else if (c == '.') { - PEEKC(c, p); - if (c != '.') - expect("'.'"); - PEEKC(c, p); - tok = TOK_DOTS; - } else { - tok = '.'; - } - break; - case '\'': - case '\"': - is_long = 0; - str_const: - { - CString str; - int sep; - - sep = c; - - /* parse the string */ - cstr_new(&str); - p = parse_pp_string(p, sep, &str); - cstr_ccat(&str, '\0'); - - /* eval the escape (should be done as TOK_PPNUM) */ - cstr_reset(&tokcstr); - parse_escape_string(&tokcstr, str.data, is_long); - cstr_free(&str); - - if (sep == '\'') { - int char_size; - /* XXX: make it portable */ - if (!is_long) - char_size = 1; - else - char_size = sizeof(nwchar_t); - if (tokcstr.size <= char_size) - error("empty character constant"); - if (tokcstr.size > 2 * char_size) - warning("multi-character character constant"); - if (!is_long) { - tokc.i = *(int8_t *)tokcstr.data; - tok = TOK_CCHAR; - } else { - tokc.i = *(nwchar_t *)tokcstr.data; - tok = TOK_LCHAR; - } - } else { - tokc.cstr = &tokcstr; - if (!is_long) - tok = TOK_STR; - else - tok = TOK_LSTR; - } - } - 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); - goto redo_no_start; - } else if (c == '/') { - p = parse_line_comment(p); - goto redo_no_start; - } 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 */ - case '@': /* dito */ - tok = c; - p++; - break; - default: - error("unrecognized character \\x%02x", c); - break; - } - tok_flags = 0; -keep_tok_flags: - file->buf_ptr = p; -#if defined(PARSE_DEBUG) - printf("token = %s\n", 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(); - } -} - -static void next_nomacro(void) -{ - do { - next_nomacro_spc(); - } while (is_space(tok)); -} - -/* substitute args in macro_str and return allocated string */ -static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) -{ - int *st, last_tok, t, spc; - Sym *s; - CValue cval; - TokenString str; - CString cstr; - - tok_str_new(&str); - last_tok = 0; - while(1) { - TOK_GET(t, macro_str, cval); - if (!t) - break; - if (t == '#') { - /* stringize */ - TOK_GET(t, macro_str, cval); - if (!t) - break; - s = sym_find2(args, t); - if (s) { - cstr_new(&cstr); - st = (int *)s->c; - spc = 0; - while (*st) { - TOK_GET(t, st, cval); - if (!check_space(t, &spc)) - cstr_cat(&cstr, get_tok_str(t, &cval)); - } - cstr.size -= spc; - cstr_ccat(&cstr, '\0'); -#ifdef PP_DEBUG - printf("stringize: %s\n", (char *)cstr.data); -#endif - /* add string */ - cval.cstr = &cstr; - tok_str_add2(&str, TOK_STR, &cval); - cstr_free(&cstr); - } else { - tok_str_add2(&str, t, &cval); - } - } else if (t >= TOK_IDENT) { - s = sym_find2(args, t); - if (s) { - st = (int *)s->c; - /* if '##' is present before or after, no arg substitution */ - if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) { - /* special case for var arg macros : ## eats the - ',' if empty VA_ARGS variable. */ - /* XXX: test of the ',' is not 100% - reliable. should fix it to avoid security - problems */ - if (gnu_ext && s->type.t && - last_tok == TOK_TWOSHARPS && - str.len >= 2 && str.str[str.len - 2] == ',') { - if (*st == 0) { - /* suppress ',' '##' */ - str.len -= 2; - } else { - /* suppress '##' and add variable */ - str.len--; - goto add_var; - } - } else { - int t1; - add_var: - for(;;) { - TOK_GET(t1, st, cval); - if (!t1) - break; - tok_str_add2(&str, t1, &cval); - } - } - } else { - /* NOTE: the stream cannot be read when macro - substituing an argument */ - macro_subst(&str, nested_list, st, NULL); - } - } else { - tok_str_add(&str, t); - } - } else { - tok_str_add2(&str, t, &cval); - } - last_tok = 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" -}; - -/* 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, struct macro_level **can_read_stream) -{ - Sym *args, *sa, *sa1; - int mstr_allocated, parlevel, *mstr, t, t1, *p, 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__) { - snprintf(buf, sizeof(buf), "%d", file->line_num); - 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); - cstr_ccat(&cstr, '\0'); - cval.cstr = &cstr; - tok_str_add2(tok_str, t1, &cval); - cstr_free(&cstr); - } else { - mstr = (int *)s->c; - mstr_allocated = 0; - if (s->type.t == MACRO_FUNC) { - /* NOTE: we do not use next_nomacro to avoid eating the - next token. XXX: find better solution */ - redo: - if (macro_ptr) { - p = macro_ptr; - while (is_space(t = *p) || TOK_LINEFEED == t) - ++p; - if (t == 0 && can_read_stream) { - /* end of macro stream: we must look at the token - after in the file */ - struct macro_level *ml = *can_read_stream; - macro_ptr = NULL; - if (ml) - { - macro_ptr = ml->p; - ml->p = NULL; - *can_read_stream = ml -> prev; - } - goto redo; - } - } else { - /* XXX: incorrect with comments */ - ch = file->buf_ptr[0]; - while (is_space(ch) || ch == '\n') - cinp(); - t = ch; - } - if (t != '(') /* no macro subst */ - return -1; - - /* argument macro */ - next_nomacro(); - next_nomacro(); - args = NULL; - sa = s->next; - /* NOTE: empty args are allowed, except if no args */ - for(;;) { - /* handle '()' case */ - if (!args && !sa && tok == ')') - break; - if (!sa) - 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))) && - tok != -1) { - if (tok == '(') - parlevel++; - else if (tok == ')') - parlevel--; - if (tok == TOK_LINEFEED) - tok = ' '; - if (!check_space(tok, &spc)) - tok_str_add2(&str, tok, &tokc); - next_nomacro_spc(); - } - str.len -= spc; - tok_str_add(&str, 0); - sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)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) - continue; - else - break; - } - if (tok != ',') - expect(","); - next_nomacro(); - } - if (sa) { - error("macro '%s' used with too few args", - get_tok_str(s->v, 0)); - } - - /* now subst each arg */ - mstr = macro_arg_subst(nested_list, mstr, args); - /* free memory */ - sa = args; - while (sa) { - sa1 = sa->prev; - tok_str_free((int *)sa->c); - sym_free(sa); - sa = sa1; - } - mstr_allocated = 1; - } - sym_push2(nested_list, s->v, 0, 0); - macro_subst(tok_str, nested_list, mstr, can_read_stream); - /* pop nested defined symbol */ - sa1 = *nested_list; - *nested_list = sa1->prev; - sym_free(sa1); - if (mstr_allocated) - tok_str_free(mstr); - } - return 0; -} - -/* handle the '##' operator. Return NULL if no '##' seen. Otherwise - return the resulting string (which must be freed). */ -static inline int *macro_twosharps(const int *macro_str) -{ - TokenSym *ts; - const int *ptr, *saved_macro_ptr; - int t; - const char *p1, *p2; - CValue cval; - TokenString macro_str1; - CString cstr; - - /* we search the first '##' */ - for(ptr = macro_str;;) { - TOK_GET(t, ptr, cval); - if (t == TOK_TWOSHARPS) - break; - /* nothing more to do if end of string */ - if (t == 0) - return NULL; - } - - /* we saw '##', so we need more processing to handle it */ - cstr_new(&cstr); - tok_str_new(¯o_str1); - saved_macro_ptr = macro_ptr; - /* XXX: get rid of the use of macro_ptr here */ - macro_ptr = (int *)macro_str; - for(;;) { - next_nomacro_spc(); - if (tok == 0) - break; - if (tok == TOK_TWOSHARPS) - continue; - while (*macro_ptr == TOK_TWOSHARPS) { - t = *++macro_ptr; - if (t && t != TOK_TWOSHARPS) { - TOK_GET(t, macro_ptr, cval); - /* We concatenate the two tokens if we have an - identifier or a preprocessing number */ - cstr_reset(&cstr); - p1 = get_tok_str(tok, &tokc); - cstr_cat(&cstr, p1); - p2 = get_tok_str(t, &cval); - cstr_cat(&cstr, p2); - cstr_ccat(&cstr, '\0'); - - if ((tok >= TOK_IDENT || tok == TOK_PPNUM) && - (t >= TOK_IDENT || t == TOK_PPNUM)) { - if (tok == TOK_PPNUM) { - /* if number, then create a number token */ - /* NOTE: no need to allocate because - tok_str_add2() does it */ - cstr_reset(&tokcstr); - tokcstr = cstr; - cstr_new(&cstr); - tokc.cstr = &tokcstr; - } else { - /* if identifier, we must do a test to - validate we have a correct identifier */ - if (t == TOK_PPNUM) { - const char *p; - int c; - - p = p2; - for(;;) { - c = *p; - if (c == '\0') - break; - p++; - if (!isnum(c) && !isid(c)) - goto error_pasting; - } - } - ts = tok_alloc(cstr.data, strlen(cstr.data)); - tok = ts->tok; /* modify current token */ - } - } else { - const char *str = cstr.data; - const unsigned char *q; - - /* we look for a valid token */ - /* XXX: do more extensive checks */ - if (!strcmp(str, ">>=")) { - tok = TOK_A_SAR; - } else if (!strcmp(str, "<<=")) { - tok = TOK_A_SHL; - } else if (strlen(str) == 2) { - /* search in two bytes table */ - q = tok_two_chars; - for(;;) { - if (!*q) - goto error_pasting; - if (q[0] == str[0] && q[1] == str[1]) - break; - q += 3; - } - tok = q[2]; - } else { - error_pasting: - /* NOTE: because get_tok_str use a static buffer, - we must save it */ - cstr_reset(&cstr); - p1 = get_tok_str(tok, &tokc); - cstr_cat(&cstr, p1); - cstr_ccat(&cstr, '\0'); - p2 = get_tok_str(t, &cval); - warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2); - /* cannot merge tokens: just add them separately */ - tok_str_add2(¯o_str1, tok, &tokc); - /* XXX: free associated memory ? */ - tok = t; - tokc = cval; - } - } - } - } - tok_str_add2(¯o_str1, tok, &tokc); - } - macro_ptr = (int *)saved_macro_ptr; - cstr_free(&cstr); - tok_str_add(¯o_str1, 0); - return macro_str1.str; -} - - -/* 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, struct macro_level ** can_read_stream) -{ - Sym *s; - int *macro_str1; - const int *ptr; - int t, ret, spc; - CValue cval; - struct macro_level ml; - - /* first scan for '##' operator handling */ - ptr = macro_str; - macro_str1 = macro_twosharps(ptr); - if (macro_str1) - ptr = macro_str1; - spc = 0; - while (1) { - /* NOTE: ptr == NULL can only happen if tokens are read from - file stream due to a macro function call */ - if (ptr == NULL) - break; - TOK_GET(t, ptr, cval); - if (t == 0) - break; - s = define_find(t); - if (s != NULL) { - /* if nested substitution, do nothing */ - if (sym_find2(*nested_list, t)) - goto no_subst; - ml.p = macro_ptr; - if (can_read_stream) - ml.prev = *can_read_stream, *can_read_stream = &ml; - macro_ptr = (int *)ptr; - tok = t; - ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream); - ptr = (int *)macro_ptr; - macro_ptr = ml.p; - if (can_read_stream && *can_read_stream == &ml) - *can_read_stream = ml.prev; - if (ret != 0) - goto no_subst; - } else { - no_subst: - if (!check_space(t, &spc)) - tok_str_add2(tok_str, t, &cval); - } - } - if (macro_str1) - tok_str_free(macro_str1); -} - -/* return next token with macro substitution */ -static void next(void) -{ - Sym *nested_list, *s; - TokenString str; - struct macro_level *ml; - - redo: - if (parse_flags & PARSE_FLAG_SPACES) - next_nomacro_spc(); - else - next_nomacro(); - if (!macro_ptr) { - /* if not reading from macro substituted string, then try - to substitute macros */ - if (tok >= TOK_IDENT && - (parse_flags & PARSE_FLAG_PREPROCESS)) { - s = define_find(tok); - if (s) { - /* we have a macro: we try to substitute */ - tok_str_new(&str); - nested_list = NULL; - ml = NULL; - if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) { - /* substitution done, NOTE: maybe empty */ - tok_str_add(&str, 0); - macro_ptr = str.str; - macro_ptr_allocated = str.str; - goto redo; - } - } - } - } else { - if (tok == 0) { - /* end of macro or end of unget buffer */ - if (unget_buffer_enabled) { - macro_ptr = unget_saved_macro_ptr; - unget_buffer_enabled = 0; - } else { - /* end of macro string: free it */ - tok_str_free(macro_ptr_allocated); - macro_ptr = NULL; - } - goto redo; - } - } - - /* convert preprocessor tokens into C tokens */ - if (tok == TOK_PPNUM && - (parse_flags & PARSE_FLAG_TOK_NUM)) { - parse_number((char *)tokc.cstr->data); - } -} - -/* push back current token and set current token to 'last_tok'. Only - identifier case handled for labels. */ -static inline void unget_tok(int last_tok) -{ - int i, n; - int *q; - unget_saved_macro_ptr = macro_ptr; - unget_buffer_enabled = 1; - q = unget_saved_buffer; - macro_ptr = q; - *q++ = tok; - n = tok_ext_size(tok) - 1; - for(i=0;iinclude_stack_ptr = s1->include_stack; - /* XXX: move that before to avoid having to initialize - file->ifdef_stack_ptr ? */ - s1->ifdef_stack_ptr = s1->ifdef_stack; - file->ifdef_stack_ptr = s1->ifdef_stack_ptr; - - /* XXX: not ANSI compliant: bound checking says error */ - vtop = vstack - 1; - s1->pack_stack[0] = 0; - s1->pack_stack_ptr = s1->pack_stack; -} - -void preprocess_new() -{ - int i, c; - const char *p, *r; - TokenSym *ts; - - /* init isid table */ - for(i=CH_EOF;i<256;i++) - isidnum_table[i-CH_EOF] = isid(i) || isnum(i); - - /* add all tokens */ - table_ident = NULL; - memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *)); - - tok_ident = TOK_IDENT; - p = tcc_keywords; - while (*p) { - r = p; - for(;;) { - c = *r++; - if (c == '\n') - break; - } - ts = tok_alloc(p, r - p - 1); - p = r; - } -} - -/* Preprocess the current file */ -static int tcc_preprocess(TCCState *s1) -{ - Sym *define_start; - BufferedFile *file_ref; - int token_seen, line_ref; - - preprocess_init(s1); - define_start = define_stack; - ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS | - PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES; - token_seen = 0; - line_ref = 0; - file_ref = NULL; - - for (;;) { - next(); - if (tok == TOK_EOF) { - break; - } else if (tok == TOK_LINEFEED) { - if (!token_seen) - continue; - ++line_ref; - token_seen = 0; - } else if (!token_seen) { - int d = file->line_num - line_ref; - if (file != file_ref || d < 0 || d >= 8) - fprintf(s1->outfile, "# %d \"%s\"\n", file->line_num, file->filename); - else - while (d) - fputs("\n", s1->outfile), --d; - line_ref = (file_ref = file)->line_num; - token_seen = 1; - } - fputs(get_tok_str(tok, &tokc), s1->outfile); - } - free_defines(define_start); - return 0; -} - diff --git a/05/tcc-0.9.25/tcctok.h b/05/tcc-0.9.25/tcctok.h deleted file mode 100644 index 6dc4778..0000000 --- a/05/tcc-0.9.25/tcctok.h +++ /dev/null @@ -1,469 +0,0 @@ -/* 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_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__") - -/*********************************************************************/ -/* 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__") - -/* special identifiers */ - DEF(TOK___FUNC__, "__func__") - -/* 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_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_DLLEXPORT, "dllexport") - DEF(TOK_NORETURN1, "noreturn") - DEF(TOK_NORETURN2, "__noreturn__") - DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p") - DEF(TOK_builtin_constant_p, "__builtin_constant_p") - DEF(TOK_builtin_frame_address, "__builtin_frame_address") -#ifdef TCC_TARGET_X86_64 - DEF(TOK_builtin_malloc, "__builtin_malloc") - DEF(TOK_builtin_free, "__builtin_free") - DEF(TOK_malloc, "malloc") - DEF(TOK_free, "free") -#endif - DEF(TOK_REGPARM1, "regparm") - DEF(TOK_REGPARM2, "__regparm__") - -/* pragma */ - DEF(TOK_pack, "pack") -#if !defined(TCC_TARGET_I386) - /* already defined for assembler */ - DEF(TOK_ASM_push, "push") - DEF(TOK_ASM_pop, "pop") -#endif - -/* builtin functions or variables */ -#ifdef TCC_ARM_EABI - DEF(TOK_memcpy, "__aeabi_memcpy") - DEF(TOK_memcpy4, "__aeabi_memcpy4") - DEF(TOK_memcpy8, "__aeabi_memcpy8") - DEF(TOK_memset, "__aeabi_memset") - DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod") - DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod") -#else - DEF(TOK_memcpy, "memcpy") - DEF(TOK_memset, "memset") - DEF(TOK___divdi3, "__divdi3") - DEF(TOK___moddi3, "__moddi3") - DEF(TOK___udivdi3, "__udivdi3") - DEF(TOK___umoddi3, "__umoddi3") -#endif -#if defined(TCC_TARGET_ARM) -#ifdef TCC_ARM_EABI - 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") -#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 -#elif 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 -#ifdef TCC_TARGET_I386 - DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control") - DEF(TOK___tcc_fpu_control, "__tcc_fpu_control") -#endif -#ifdef TCC_ARM_EABI - 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___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 -#ifdef TCC_TARGET_PE - DEF(TOK___chkstk, "__chkstk") -#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_local_new, "__bound_local_new") - DEF(TOK___bound_local_delete, "__bound_local_delete") -#if 0 - DEF(TOK_malloc, "malloc") - DEF(TOK_free, "free") - DEF(TOK_realloc, "realloc") - DEF(TOK_memalign, "memalign") - DEF(TOK_calloc, "calloc") -#endif - DEF(TOK_memmove, "memmove") - DEF(TOK_strlen, "strlen") - DEF(TOK_strcpy, "strcpy") - DEF(TOK_alloca, "alloca") -#endif - -/* Tiny Assembler */ - - DEF_ASM(byte) - DEF_ASM(align) - DEF_ASM(skip) - DEF_ASM(space) - DEF_ASM(string) - DEF_ASM(asciz) - DEF_ASM(ascii) - DEF_ASM(globl) - DEF_ASM(global) - DEF_ASM(text) - DEF_ASM(data) - DEF_ASM(bss) - DEF_ASM(previous) - DEF_ASM(fill) - DEF_ASM(org) - DEF_ASM(quad) - -#ifdef TCC_TARGET_I386 - -/* WARNING: relative order of tokens is important. */ - 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) - 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_BWL(mov) - - /* generic two operands */ - DEF_BWL(add) - DEF_BWL(or) - DEF_BWL(adc) - DEF_BWL(sbb) - DEF_BWL(and) - DEF_BWL(sub) - DEF_BWL(xor) - DEF_BWL(cmp) - - /* unary ops */ - DEF_BWL(inc) - DEF_BWL(dec) - DEF_BWL(not) - DEF_BWL(neg) - DEF_BWL(mul) - DEF_BWL(imul) - DEF_BWL(div) - DEF_BWL(idiv) - - DEF_BWL(xchg) - DEF_BWL(test) - - /* shifts */ - DEF_BWL(rol) - DEF_BWL(ror) - DEF_BWL(rcl) - DEF_BWL(rcr) - DEF_BWL(shl) - DEF_BWL(shr) - DEF_BWL(sar) - - DEF_ASM(shldw) - DEF_ASM(shldl) - DEF_ASM(shld) - DEF_ASM(shrdw) - DEF_ASM(shrdl) - DEF_ASM(shrd) - - DEF_ASM(pushw) - DEF_ASM(pushl) - DEF_ASM(push) - DEF_ASM(popw) - DEF_ASM(popl) - DEF_ASM(pop) - DEF_BWL(in) - DEF_BWL(out) - - DEF_WL(movzb) - - DEF_ASM(movzwl) - DEF_ASM(movsbw) - DEF_ASM(movsbl) - DEF_ASM(movswl) - - DEF_WL(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(cmov) - - DEF_WL(bsf) - DEF_WL(bsr) - DEF_WL(bt) - DEF_WL(bts) - DEF_WL(btr) - DEF_WL(btc) - - DEF_WL(lsl) - - /* generic FP ops */ - DEF_FP(add) - DEF_FP(mul) - - DEF_ASM(fcom) - DEF_ASM(fcom_1) /* non existant 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_BWL(xadd) - DEF_BWL(cmpxchg) - - /* string ops */ - DEF_BWL(cmps) - DEF_BWL(scmp) - DEF_BWL(ins) - DEF_BWL(outs) - DEF_BWL(lods) - DEF_BWL(slod) - DEF_BWL(movs) - DEF_BWL(smov) - DEF_BWL(scas) - DEF_BWL(ssca) - DEF_BWL(stos) - DEF_BWL(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) -#include "i386-asm.h" - -#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) -#include "i386-asm.h" - -#endif diff --git a/05/tcc-0.9.25/texi2pod.pl b/05/tcc-0.9.25/texi2pod.pl deleted file mode 100755 index d86e176..0000000 --- a/05/tcc-0.9.25/texi2pod.pl +++ /dev/null @@ -1,427 +0,0 @@ -#! /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/&/&/g; - s/\@\{/{/g; - s/\@\}/}/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//>/g; - } else { - s//>/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\<$1\>\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)\{([^\},]*)\}/<B<$1>>/g; - s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g; - s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g; - - # Turn B blah> into B I B to - # match Texinfo semantics of @emph inside @samp. Also handle @r - # inside bold. - s/<//g; - 1 while s/B<((?:[^<>]|I<[^<>]*>)*)R<([^>]*)>/B<$1>${2}B]*)I<([^>]+)>/B<$1>I<$2>B]*)B<([^>]+)>/I<$1>B<$2>I//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/</E/g; - s/>/E/g; - s/{/\{/g; - s/}/\}/g; - s/&at;/\@/g; - s/&/&/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/05/tcc-0.9.25/time.h b/05/tcc-0.9.25/time.h deleted file mode 100644 index 8207156..0000000 --- a/05/tcc-0.9.25/time.h +++ /dev/null @@ -1,293 +0,0 @@ -#ifndef _TIME_H -#define _TIME_H - -#include -#define CLK_TCK 1000000000 // doesnt matter; clock() will always fail. - -typedef long clock_t; - -clock_t clock(void) { - // "If the processor time used is not available or its value cannot be represented, the function returns the value (clock_t)-1." C89 § 4.12.2.1 - return -1; -} - -double difftime(time_t time1, time_t time0) { - return (double)(time1 - time0); -} - -time_t time(time_t *timer) { - struct timespec ts = {0}; - if (clock_gettime(CLOCK_REALTIME, &ts) != 0) return -1; - if (timer) *timer = ts.tv_sec; - return ts.tv_sec; -} - - -// @NONSTANDARD(except in UTC+0): we don't support local time in timezones other than UTC+0. - -struct tm { - int tm_sec; /* seconds after the minute --- [0, 60] */ - int tm_min; /* minutes after the hour --- [0, 59] */ - int tm_hour; /* hours since midnight --- [0, 23] */ - int tm_mday; /* day of the month --- [1, 31] */ - int tm_mon; /* months since January --- [0, 11] */ - int tm_year; /* years since 1900 */ - int tm_wday; /* days since Sunday --- [0, 6] */ - int tm_yday; /* days since January 1 --- [0, 365] */ - int tm_isdst; /* Daylight Saving Time flag */ -}; - - -void _gmtime_r(const time_t *timer, struct tm *tm) { - time_t t = *timer; - int year = 1970; - int days = t / 86400; - int leap_year; - int month; - - tm->tm_isdst = 0; - tm->tm_wday = (4 + days) % 7; // jan 1 1970 was a thursday - while (1) { - leap_year = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); - int ydays = leap_year ? 366 : 365; - if (days < ydays) break; - days -= ydays; - ++year; - } - tm->tm_year = year - 1900; - tm->tm_yday = days; - for (month = 0; month < 12; ++month) { - int mdays; - switch (month) { - case 0: case 2: case 4: case 6: case 7: case 9: case 11: - mdays = 31; - break; - case 3: case 5: case 8: case 10: - mdays = 30; - break; - case 1: - mdays = 28 + leap_year; - break; - } - if (days < mdays) break; - days -= mdays; - } - tm->tm_mday = days + 1; - tm->tm_mon = month; - t %= 86400; - tm->tm_hour = t / 3600; - t %= 3600; - tm->tm_min = t / 60; - tm->tm_sec = t % 60; -} - -time_t mktime(struct tm *tm) { - // @NONSTANDARD-ish. - // not implementing this -- note that the implementation has to support tm_* values - // outside of their proper ranges. - return (time_t)-1; - -} - -struct tm *gmtime(const time_t *timer) { - static struct tm result; - _gmtime_r(timer, &result); - return &result; -} - -struct tm *localtime(const time_t *timer) { - static struct tm result; - _gmtime_r(timer, &result); - return &result; -} - -static const char _wday_name[7][4] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; -static const char _weekday_name[7][16] = { - "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" -}; -static const char _mon_name[12][4] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; -static const char _month_name[12][16] = { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" -}; - -char *asctime(const struct tm *timeptr) { - // lifted from the (draft of the) C standard - static char result[32]; - sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n", - _wday_name[timeptr->tm_wday], - _mon_name[timeptr->tm_mon], - timeptr->tm_mday, timeptr->tm_hour, - timeptr->tm_min, timeptr->tm_sec, - 1900 + timeptr->tm_year); - return result; -} - -char *ctime(const time_t *timer) { - return asctime(localtime(timer)); -} - -size_t strftime(char *s, size_t maxsize, const char *format, const struct tm *tm) { - size_t n = 0, l; - char *name; - - while (*format) { - if (*format == '%') { - ++format; - int c = *format++; - switch (c) { - case 'a': - if (n+4 >= maxsize) return 0; - strcpy(s, _wday_name[tm->tm_wday]); - s += 3; - n += 3; - break; - case 'A': - name = _weekday_name[tm->tm_wday]; - l = strlen(name); - if (n+l+1 >= maxsize) return 0; - strcpy(s, name); - s += l; - n += l; - break; - case 'b': - if (n+4 >= maxsize) return 0; - strcpy(s, _mon_name[tm->tm_mon]); - s += 3; - n += 3; - break; - case 'B': - name = _month_name[tm->tm_mon]; - l = strlen(name); - if (n+l+1 >= maxsize) return 0; - strcpy(s, name); - s += l; - n += l; - break; - case 'c': - if (n+32 >= maxsize) return 0; - sprintf(s, "%s %02d %s %d %02d:%02d:%02d %s UTC", - _wday_name[tm->tm_wday], tm->tm_mday, _mon_name[tm->tm_mon], - 1900+tm->tm_year, (tm->tm_hour + 11) % 12 + 1, tm->tm_min, tm->tm_sec, - tm->tm_hour >= 12 ? "PM" : "AM"); - s += 31; - n += 31; - break; - case 'd': - if (n+3 >= maxsize) return 0; - sprintf(s, "%02d", tm->tm_mday); - s += 2; - n += 2; - break; - case 'H': - if (n+3 >= maxsize) return 0; - sprintf(s, "%02d", tm->tm_hour); - s += 2; - n += 2; - break; - case 'I': - if (n+3 >= maxsize) return 0; - sprintf(s, "%02d", (tm->tm_hour + 11) % 12 + 1); - s += 2; - n += 2; - break; - case 'j': - if (n+4 >= maxsize) return 0; - sprintf(s, "%03d", tm->tm_yday + 1); - s += 3; - n += 3; - break; - case 'm': - if (n+3 >= maxsize) return 0; - sprintf(s, "%02d", tm->tm_mon + 1); - s += 2; - n += 2; - break; - case 'M': - if (n+3 >= maxsize) return 0; - sprintf(s, "%02d", tm->tm_min); - s += 2; - n += 2; - break; - case 'p': - if (n+3 >= maxsize) return 0; - sprintf(s, "%s", tm->tm_hour >= 12 ? "PM" : "AM"); - s += 2; - n += 2; - break; - case 'S': - if (n+3 >= maxsize) return 0; - sprintf(s, "%02d", tm->tm_sec); - s += 2; - n += 2; - break; - case 'w': - if (n+2 >= maxsize) return 0; - sprintf(s, "%d", tm->tm_wday); - s += 1; - n += 1; - break; - case 'x': - if (n+16 >= maxsize) return 0; - sprintf(s, "%s %02d %s %d", - _wday_name[tm->tm_wday], tm->tm_mday, _mon_name[tm->tm_mon], - 1900+tm->tm_year); - s += 15; - n += 15; - break; - case 'X': - if (n+16 >= maxsize) return 0; - sprintf(s, "%02d:%02d:%02d %s UTC", - (tm->tm_hour + 11) % 12 + 1, tm->tm_min, tm->tm_sec, - tm->tm_hour >= 12 ? "PM" : "AM"); - s += 15; - n += 15; - break; - case 'y': - if (n+3 >= maxsize) return 0; - sprintf(s, "%02d", tm->tm_year % 100); - s += 2; - n += 2; - break; - case 'Y': - if (n+5 >= maxsize) return 0; - sprintf(s, "%d", tm->tm_year + 1900); - s += 4; - n += 4; - break; - case 'Z': - if (n+4 >= maxsize) return 0; - strcpy(s, "UTC"); - s += 3; - n += 3; - break; - case '%': - if (n >= maxsize) return 0; - *s++ = '%'; - n += 1; - break; - case 'U': // WEEK NUMBER OF THE YEAR? WHO GIVES A SHIT? - case 'W': // WEEK NUMBER OF THE YEAR MONDAY-BASED EDITION. IF YOU DIDNT ALREADY GET ENOUGH WEEK NUMBERS. FUCK YOU - default: - fprintf(stderr, "Bad strftime format.\n"); - abort(); - - } - } else { - if (n >= maxsize) return 0; - *s++ = *format++; - n += 1; - } - } - if (n >= maxsize) return 0; - *s = 0; - #undef _Push_str - return n; -} - -#endif // _TIME_H diff --git a/05/tcc-0.9.25/x86_64-gen.c b/05/tcc-0.9.25/x86_64-gen.c deleted file mode 100644 index 6b6e2f1..0000000 --- a/05/tcc-0.9.25/x86_64-gen.c +++ /dev/null @@ -1,1419 +0,0 @@ -/* - * 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 - */ - -#include - -/* number of available registers */ -#define NB_REGS 5 - -/* 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_XMM0 0x0020 -#define RC_ST0 0x0040 /* only for long double */ -#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 */ - -/* pretty names for the registers */ -enum { - TREG_RAX = 0, - TREG_RCX = 1, - TREG_RDX = 2, - TREG_RSI = 6, - TREG_RDI = 7, - TREG_R8 = 8, - TREG_R9 = 9, - TREG_R10 = 10, - TREG_R11 = 11, - - TREG_XMM0 = 3, - TREG_ST0 = 4, - - TREG_MEM = 0x10, -}; - -#define REX_BASE(reg) (((reg) >> 3) & 1) -#define REG_VALUE(reg) ((reg) & 7) - -int reg_classes[NB_REGS] = { - /* eax */ RC_INT | RC_RAX, - /* ecx */ RC_INT | RC_RCX, - /* edx */ RC_INT | RC_RDX, - /* xmm0 */ RC_FLOAT | RC_XMM0, - /* st0 */ RC_ST0 -}; - -/* 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 */ - -/* 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 8 -/* maximum alignment (for aligned attribute support) */ -#define MAX_ALIGN 8 - -/******************************************************/ -/* ELF defines */ - -#define EM_TCC_TARGET EM_X86_64 - -/* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_X86_64_64 -#define R_JMP_SLOT R_X86_64_JUMP_SLOT -#define R_COPY R_X86_64_COPY - -#define ELF_START_ADDR 0x08048000 -#define ELF_PAGE_SIZE 0x1000 - -/******************************************************/ - -static unsigned long func_sub_sp_offset; -static int func_ret_sub; - -/* XXX: make it faster ? */ -void g(int c) -{ - int ind1; - ind1 = ind + 1; - if (ind1 > cur_text_section->data_allocated) - section_realloc(cur_text_section, ind1); - cur_text_section->data[ind] = c; - ind = ind1; -} - -void o(unsigned int c) -{ - while (c) { - g(c); - c = c >> 8; - } -} - -void gen_le32(int c) -{ - g(c); - g(c >> 8); - g(c >> 16); - g(c >> 24); -} - -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); -} - -/* 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); - n = *ptr; /* next value */ - *ptr = a - t - 4; - t = n; - } -} - -void gsym(int t) -{ - gsym_addr(t, ind); -} - -/* psym is used to put an instruction with a data field which is a - reference to a symbol. It is in fact the same as oad ! */ -#define psym oad - -static int is64_type(int t) -{ - return ((t & VT_BTYPE) == VT_PTR || - (t & VT_BTYPE) == VT_FUNC || - (t & VT_BTYPE) == VT_LLONG); -} - -static int is_sse_float(int t) { - int bt; - bt = t & VT_BTYPE; - return bt == VT_DOUBLE || bt == VT_FLOAT; -} - -/* instruction + 4 bytes data. Return the address of the data */ -static int oad(int c, int s) -{ - int ind1; - - o(c); - ind1 = ind + 4; - if (ind1 > cur_text_section->data_allocated) - section_realloc(cur_text_section, ind1); - *(int *)(cur_text_section->data + ind) = s; - s = ind; - ind = ind1; - return s; -} - -/* output constant with relocation if 'r & VT_SYM' is true */ -static void gen_addr64(int r, Sym *sym, int64_t c) -{ - if (r & VT_SYM) - greloc(cur_text_section, sym, ind, R_X86_64_64); - gen_le64(c); -} - -/* output constant with relocation if 'r & VT_SYM' is true */ -static void gen_addrpc32(int r, Sym *sym, int c) -{ - if (r & VT_SYM) - greloc(cur_text_section, sym, ind, R_X86_64_PC32); - gen_le32(c-4); -} - -/* output got address with relocation */ -static void gen_gotpcrel(int r, Sym *sym, int c) -{ - Section *sr; - ElfW(Rela) *rel; - greloc(cur_text_section, sym, ind, R_X86_64_GOTPCREL); - sr = cur_text_section->reloc; - rel = (ElfW(Rela) *)(sr->data + sr->data_offset - sizeof(ElfW(Rela))); - rel->r_addend = -4; - gen_le32(0); - - if (c) { - /* we use add c, %xxx for displacement */ - o(0x48 + REX_BASE(r)); - o(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 */ - o(0x05 | op_reg); - 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 | (r & VT_VALMASK)); - } -} - -/* generate a modrm reference. 'op_reg' contains the addtionnal 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 addtionnal 3 - opcode bits */ -static void gen_modrm64(int opcode, int op_reg, int r, Sym *sym, int c) -{ - int is_got; - int rex = 0x48 | (REX_BASE(op_reg) << 2); - if ((r & VT_VALMASK) != VT_CONST && - (r & VT_VALMASK) != VT_LOCAL) { - rex |= REX_BASE(VT_VALMASK & r); - } - o(rex); - o(opcode); - is_got = (op_reg & TREG_MEM) && !(sym->type.t & VT_STATIC); - 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; - - fr = sv->r; - ft = sv->type.t; - fc = sv->c.ul; - - /* 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; - } - - v = fr & VT_VALMASK; - if (fr & VT_LVAL) { - if (v == VT_LLOCAL) { - v1.type.t = VT_PTR; - v1.r = VT_LOCAL | VT_LVAL; - v1.c.ul = fc; - load(r, &v1); - fr = r; - } - if ((ft & VT_BTYPE) == VT_FLOAT) { - o(0x6e0f66); /* movd */ - r = 0; - } else if ((ft & VT_BTYPE) == VT_DOUBLE) { - o(0x7e0ff3); /* movq */ - r = 0; - } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { - o(0xdb); /* fldt */ - r = 5; - } else if ((ft & VT_TYPE) == VT_BYTE) { - 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 if (is64_type(ft)) { - gen_modrm64(0x8b, r, fr, sv->sym, fc); - return; - } else { - o(0x8b); /* movl */ - } - gen_modrm(r, fr, sv->sym, fc); - } else { - if (v == VT_CONST) { - if ((ft & VT_BTYPE) == VT_LLONG) { - assert(!(fr & VT_SYM)); - o(0x48); - o(0xb8 + REG_VALUE(r)); /* mov $xx, r */ - gen_addr64(fr, sv->sym, sv->c.ull); - } else { - if (fr & VT_SYM) { - if (sv->sym->type.t & VT_STATIC) { - o(0x8d48); - o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */ - gen_addrpc32(fr, sv->sym, fc); - } else { - o(0x8b48); - o(0x05 + REG_VALUE(r) * 8); /* mov xx(%rip), r */ - gen_gotpcrel(r, sv->sym, fc); - } - } else { - o(0xb8 + REG_VALUE(r)); /* mov $xx, r */ - gen_le32(fc); - } - } - } else if (v == VT_LOCAL) { - o(0x48 | REX_BASE(r)); - o(0x8d); /* lea xxx(%ebp), r */ - gen_modrm(r, VT_LOCAL, sv->sym, fc); - } 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) { - if (r == TREG_XMM0) { - assert(v == TREG_ST0); - /* gen_cvt_ftof(VT_DOUBLE); */ - o(0xf0245cdd); /* fstpl -0x10(%rsp) */ - /* movsd -0x10(%rsp),%xmm0 */ - o(0x44100ff2); - o(0xf024); - } else if (r == TREG_ST0) { - assert(v == TREG_XMM0); - /* gen_cvt_ftof(VT_LDOUBLE); */ - /* movsd %xmm0,-0x10(%rsp) */ - o(0x44110ff2); - o(0xf024); - o(0xf02444dd); /* fldl -0x10(%rsp) */ - } else { - o(0x48 | REX_BASE(r) | (REX_BASE(v) << 2)); - o(0x89); - o(0xc0 + r + 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; - - ft = v->type.t; - fc = v->c.ul; - fr = v->r & VT_VALMASK; - bt = ft & VT_BTYPE; - - /* 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.ul); - pic = is64_type(bt) ? 0x49 : 0x41; - } - - /* XXX: incorrect if float reg to reg */ - if (bt == VT_FLOAT) { - o(0x66); - o(pic); - o(0x7e0f); /* movd */ - r = 0; - } else if (bt == VT_DOUBLE) { - o(0x66); - o(pic); - o(0xd60f); /* movq */ - r = 0; - } 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) - o(0x88); - else if (is64_type(bt)) - op64 = 0x89; - else - o(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 */ - } - } -} - -static void gadd_sp(int val) -{ - if (val == (char)val) { - o(0xc48348); - g(val); - } else { - oad(0xc48148, val); /* add $xxx, %rsp */ - } -} - -/* '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) { - /* constant case */ - if (vtop->r & VT_SYM) { - /* relocation case */ - greloc(cur_text_section, vtop->sym, - ind + 1, R_X86_64_PC32); - } else { - /* put an empty PC32 relocation */ - put_elf_reloc(symtab_section, cur_text_section, - ind + 1, R_X86_64_PC32, 0); - } - oad(0xe8 + is_jmp, vtop->c.ul - 4); /* 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)); - } -} - -static uint8_t arg_regs[6] = { - TREG_RDI, TREG_RSI, TREG_RDX, TREG_RCX, TREG_R8, TREG_R9 -}; -/* 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 size, align, r, args_size, i, func_call; - Sym *func_sym; - SValue *orig_vtop; - int nb_reg_args = 0; - int nb_sse_args = 0; - int sse_reg, gen_reg; - - /* calculate the number of integer/float arguments */ - args_size = 0; - for(i = 0; i < nb_args; i++) { - if ((vtop[-i].type.t & VT_BTYPE) == VT_STRUCT) { - args_size += type_size(&vtop->type, &align); - } else if ((vtop[-i].type.t & VT_BTYPE) == VT_LDOUBLE) { - args_size += 16; - } else if (is_sse_float(vtop[-i].type.t)) { - nb_sse_args++; - if (nb_sse_args > 8) args_size += 8; - } else { - nb_reg_args++; - if (nb_reg_args > 6) args_size += 8; - } - } - - /* 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. */ - orig_vtop = vtop; - gen_reg = nb_reg_args; - sse_reg = nb_sse_args; - /* adjust stack to align SSE boundary */ - if (args_size &= 8) { - o(0x50); /* push $rax */ - } - 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 */ - o(0x48); - oad(0xec81, size); /* sub $xxx, %rsp */ - /* generate structure store */ - r = get_reg(RC_INT); - o(0x48 + REX_BASE(r)); - o(0x89); /* mov %rsp, r */ - o(0xe0 + r); - { - /* following code breaks vtop[1] */ - SValue tmp = vtop[1]; - vset(&vtop->type, r | VT_LVAL, 0); - vswap(); - vstore(); - vtop[1] = tmp; - } - args_size += size; - } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - gv(RC_ST0); - size = LDOUBLE_SIZE; - oad(0xec8148, size); /* sub $xxx, %rsp */ - o(0x7cdb); /* fstpt 0(%rsp) */ - g(0x24); - g(0x00); - args_size += size; - } else if (is_sse_float(vtop->type.t)) { - int j = --sse_reg; - if (j >= 8) { - gv(RC_FLOAT); - o(0x50); /* push $rax */ - /* movq %xmm0, (%rsp) */ - o(0x04d60f66); - o(0x24); - args_size += 8; - } - } else { - int j = --gen_reg; - /* simple type */ - /* XXX: implicit cast ? */ - if (j >= 6) { - r = gv(RC_INT); - o(0x50 + r); /* push r */ - args_size += 8; - } - } - vtop--; - } - vtop = orig_vtop; - - /* 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 */ - gen_reg = nb_reg_args; - sse_reg = nb_sse_args; - for(i = 0; i < nb_args; i++) { - if ((vtop->type.t & VT_BTYPE) == VT_STRUCT || - (vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - } else if (is_sse_float(vtop->type.t)) { - int j = --sse_reg; - if (j < 8) { - gv(RC_FLOAT); /* only one float register */ - /* movaps %xmm0, %xmmN */ - o(0x280f); - o(0xc0 + (sse_reg << 3)); - } - } else { - int j = --gen_reg; - /* simple type */ - /* XXX: implicit cast ? */ - if (j < 6) { - r = gv(RC_INT); - if (j < 2) { - o(0x8948); /* mov */ - o(0xc0 + r * 8 + arg_regs[j]); - } else if (j < 4) { - o(0x8949); /* mov */ - /* j=2: r10, j=3: r11 */ - o(0xc0 + r * 8 + j); - } else { - o(0x8949); /* mov */ - /* j=4: r8, j=5: r9 */ - o(0xc0 + r * 8 + j - 4); - } - } - } - vtop--; - } - - save_regs(0); /* save used temporary registers */ - - /* 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 */ - } - } - - func_sym = vtop->type.ref; - func_call = FUNC_CALL(func_sym->r); - 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--; -} - -#ifdef TCC_TARGET_PE -/* XXX: support PE? */ -#warning "PE isn't tested at all" -#define FUNC_PROLOG_SIZE 12 -#else -#define FUNC_PROLOG_SIZE 11 -#endif - -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) -{ - int i, addr, align, size, func_call; - int param_index, param_addr, reg_param_index, sse_param_index; - Sym *sym; - CType *type; - - func_ret_sub = 0; - - sym = func_type->ref; - func_call = FUNC_CALL(sym->r); - addr = PTR_SIZE * 2; - loc = 0; - ind += FUNC_PROLOG_SIZE; - func_sub_sp_offset = ind; - - if (func_type->ref->c == 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; - if (is_sse_float(type->t)) { - if (seen_sse_num < 8) { - seen_sse_num++; - } else { - seen_stack_size += 8; - } - } else if ((type->t & VT_BTYPE) == VT_STRUCT) { - size = type_size(type, &align); - size = (size + 3) & ~3; - seen_stack_size += size; - } else if ((type->t & VT_BTYPE) == VT_LDOUBLE) { - seen_stack_size += LDOUBLE_SIZE; - } else { - if (seen_reg_num < 6) { - seen_reg_num++; - } else { - seen_stack_size += 8; - } - } - } - - 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; - 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 < 6; i++) { - push_arg_reg(5 - i); - } - } - - sym = func_type->ref; - param_index = 0; - reg_param_index = 0; - sse_param_index = 0; - - /* if the function returns a structure, then add an - implicit pointer parameter */ - func_vt = sym->type; - if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { - push_arg_reg(reg_param_index); - param_addr = loc; - - func_vc = loc; - param_index++; - reg_param_index++; - } - /* define parameters */ - while ((sym = sym->next) != NULL) { - type = &sym->type; - size = type_size(type, &align); - size = (size + 3) & ~3; - if (is_sse_float(type->t)) { - if (sse_param_index < 8) { - /* save arguments passed by register */ - loc -= 8; - o(0xd60f66); /* movq */ - gen_modrm(sse_param_index, VT_LOCAL, NULL, loc); - param_addr = loc; - } else { - param_addr = addr; - addr += size; - } - sse_param_index++; - } else if ((type->t & VT_BTYPE) == VT_STRUCT || - (type->t & VT_BTYPE) == VT_LDOUBLE) { - param_addr = addr; - addr += size; - } else { - if (reg_param_index < 6) { - /* save arguments passed by register */ - push_arg_reg(reg_param_index); - param_addr = loc; - } else { - param_addr = addr; - addr += 8; - } - reg_param_index++; - } - sym_push(sym->v & ~SYM_FIELD, type, - VT_LOCAL | VT_LVAL, param_addr); - 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); - } - /* align local size to word & save local variables */ - v = (-loc + 15) & -16; - saved_ind = ind; - ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; -#ifdef TCC_TARGET_PE - if (v >= 4096) { - Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0); - oad(0xb8, v); /* mov stacksize, %eax */ - oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */ - greloc(cur_text_section, sym, ind-4, R_X86_64_PC32); - } else -#endif - { - o(0xe5894855); /* push %rbp, mov %rsp, %rbp */ - o(0xec8148); /* sub rsp, stacksize */ - gen_le32(v); -#if FUNC_PROLOG_SIZE == 12 - o(0x90); /* adjust to FUNC_PROLOG_SIZE */ -#endif - } - ind = saved_ind; -} - -/* generate a jump to a label */ -int gjmp(int t) -{ - return psym(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); - } -} - -/* generate a test. set 'inv' to invert test. Stack entry is popped */ -int gtst(int inv, int t) -{ - int v, *p; - - v = vtop->r & VT_VALMASK; - if (v == VT_CMP) { - /* fast case : can jump directly since flags are set */ - g(0x0f); - t = psym((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 */ - p = &vtop->c.i; - while (*p != 0) - p = (int *)(cur_text_section->data + *p); - *p = t; - t = vtop->c.i; - } else { - t = gjmp(t); - gsym(vtop->c.i); - } - } else { - if (is_float(vtop->type.t) || - (vtop->type.t & VT_BTYPE) == VT_LLONG) { - 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); - } else { - v = gv(RC_INT); - o(0x85); - o(0xc0 + v * 9); - g(0x0f); - t = psym(0x85 ^ inv, t); - } - } - vtop--; - return t; -} - -/* generate an integer binary operation */ -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 && - !is64_type(vtop->type.t)) { - /* constant case */ - vswap(); - r = gv(RC_INT); - if (is64_type(vtop->type.t)) { - o(0x48 | REX_BASE(r)); - } - vswap(); - c = vtop->c.i; - if (c == (char)c) { - /* XXX: generate inc and dec for smaller code ? */ - o(0x83); - o(0xc0 | (opc << 3) | REG_VALUE(r)); - g(c); - } else { - o(0x81); - oad(0xc0 | (opc << 3) | REG_VALUE(r), c); - } - } else { - gv2(RC_INT, RC_INT); - r = vtop[-1].r; - fr = vtop[0].r; - if (opc != 7 || - is64_type(vtop[0].type.t) || (vtop[0].type.t & VT_UNSIGNED) || - is64_type(vtop[-1].type.t) || (vtop[-1].type.t & VT_UNSIGNED)) { - o(0x48 | REX_BASE(r) | (REX_BASE(fr) << 2)); - } - o((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; - if (is64_type(vtop[0].type.t) || (vtop[0].type.t & VT_UNSIGNED) || - is64_type(vtop[-1].type.t) || (vtop[-1].type.t & VT_UNSIGNED)) { - o(0x48 | REX_BASE(fr) | (REX_BASE(r) << 2)); - } - 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); - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - o(0x48 | REX_BASE(r)); - c = 0x3f; - } else { - c = 0x1f; - } - vswap(); - c &= vtop->c.i; - o(0xc1); /* shl/shr/sar $xxx, r */ - o(opc | r); - g(c); - } else { - /* we generate the shift in ecx */ - gv2(RC_INT, RC_RCX); - r = vtop[-1].r; - if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG) { - o(0x48 | REX_BASE(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_RAX, RC_RCX); - r = vtop[-1].r; - fr = vtop[0].r; - vtop--; - save_reg(TREG_RDX); - if (op == TOK_UMULL) { - o(0xf7); /* mul fr */ - o(0xe0 + fr); - vtop->r2 = TREG_RDX; - r = TREG_RAX; - } else { - if (op == TOK_UDIV || op == TOK_UMOD) { - o(0xf7d231); /* xor %edx, %edx, div fr, %eax */ - o(0xf0 + fr); - } else { - if ((vtop->type.t & VT_BTYPE) & VT_LLONG) { - o(0x9948); /* cqto */ - o(0x48 + REX_BASE(fr)); - } else { - o(0x99); /* cltd */ - } - o(0xf7); /* idiv fr, %eax */ - o(0xf8 + 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 guaranted 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) */ - o(0xe9da); /* fucompp */ - 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) { - case '-': - a = 4; - if (swapped) - a++; - break; - case '*': - a = 1; - break; - case '/': - a = 6; - if (swapped) - a++; - break; - case '+': - default: - a = 0; - break; - } - ft = vtop->type.t; - fc = vtop->c.ul; - 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.ul; - 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.ul = 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) { - o(0x7e0ff3); /* movq */ - gen_modrm(1, r, vtop->sym, fc); - - if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) { - o(0x66); - } - o(0x2e0f); /* ucomisd %xmm0, %xmm1 */ - o(0xc8); - } else { - if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) { - o(0x66); - } - o(0x2e0f); /* ucomisd */ - gen_modrm(0, r, vtop->sym, fc); - } - - 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_XMM0, vtop); - swapped = !swapped; - } - switch(op) { - case '-': - a = 4; - break; - case '*': - a = 1; - break; - case '/': - a = 6; - break; - case '+': - default: - a = 0; - break; - } - ft = vtop->type.t; - fc = vtop->c.ul; - 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.ul = fc; - load(r, &v1); - fc = 0; - } - if (swapped) { - /* movq %xmm0,%xmm1 */ - o(0x7e0ff3); - o(0xc8); - load(TREG_XMM0, vtop); - /* subsd %xmm1,%xmm0 (f2 0f 5c c1) */ - if ((ft & VT_BTYPE) == VT_DOUBLE) { - o(0xf2); - } else { - o(0xf3); - } - o(0x0f); - o(0x58 + a); - o(0xc1); - } else { - if ((ft & VT_BTYPE) == VT_DOUBLE) { - o(0xf2); - } else { - o(0xf3); - } - o(0x0f); - o(0x58 + a); - gen_modrm(0, r, vtop->sym, fc); - } - } - 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 { - save_reg(TREG_XMM0); - gv(RC_INT); - o(0xf2 + ((t & VT_BTYPE) == VT_FLOAT)); - 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)); /* cvtsi2sd */ - vtop->r = TREG_XMM0; - } -} - -/* 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(0xc0140f); /* unpcklps */ - o(0xc05a0f); /* cvtps2pd */ - } else if (tbt == VT_LDOUBLE) { - /* movss %xmm0,-0x10(%rsp) */ - o(0x44110ff3); - o(0xf024); - o(0xf02444d9); /* flds -0x10(%rsp) */ - vtop->r = TREG_ST0; - } - } else if (bt == VT_DOUBLE) { - gv(RC_FLOAT); - if (tbt == VT_FLOAT) { - o(0xc0140f66); /* unpcklpd */ - o(0xc05a0f66); /* cvtpd2ps */ - } else if (tbt == VT_LDOUBLE) { - /* movsd %xmm0,-0x10(%rsp) */ - o(0x44110ff2); - o(0xf024); - o(0xf02444dd); /* fldl -0x10(%rsp) */ - vtop->r = TREG_ST0; - } - } else { - gv(RC_ST0); - if (tbt == VT_DOUBLE) { - o(0xf0245cdd); /* fstpl -0x10(%rsp) */ - /* movsd -0x10(%rsp),%xmm0 */ - o(0x44100ff2); - o(0xf024); - vtop->r = TREG_XMM0; - } else if (tbt == VT_FLOAT) { - o(0xf0245cd9); /* fstps -0x10(%rsp) */ - /* movss -0x10(%rsp),%xmm0 */ - o(0x44100ff3); - o(0xf024); - vtop->r = TREG_XMM0; - } - } -} - -/* 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); - } - if (size == 8) { - o(0x48 + REX_BASE(r)); - } - o(0x2c0f); /* cvttss2si or cvttsd2si */ - o(0xc0 + (REG_VALUE(r) << 3)); - vtop->r = r; -} - -/* computed goto support */ -void ggoto(void) -{ - gcall_or_jmp(1); - vtop--; -} - -/* end of x86-64 code generator */ -/*************************************************************/ diff --git a/05/tcc-0.9.27/.gitignore b/05/tcc-0.9.27/.gitignore new file mode 100644 index 0000000..c989b6b --- /dev/null +++ b/05/tcc-0.9.27/.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/05/tcc-0.9.27/COPYING b/05/tcc-0.9.27/COPYING new file mode 100644 index 0000000..223ede7 --- /dev/null +++ b/05/tcc-0.9.27/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. + + + Copyright (C) + + 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. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/05/tcc-0.9.27/Changelog b/05/tcc-0.9.27/Changelog new file mode 100644 index 0000000..17f5bde --- /dev/null +++ b/05/tcc-0.9.27/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 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/05/tcc-0.9.27/CodingStyle b/05/tcc-0.9.27/CodingStyle new file mode 100644 index 0000000..93d1324 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/Makefile b/05/tcc-0.9.27/Makefile new file mode 100644 index 0000000..3ae466f --- /dev/null +++ b/05/tcc-0.9.27/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 /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/05/tcc-0.9.27/README b/05/tcc-0.9.27/README new file mode 100644 index 0000000..3a3f90b --- /dev/null +++ b/05/tcc-0.9.27/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 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/05/tcc-0.9.27/RELICENSING b/05/tcc-0.9.27/RELICENSING new file mode 100644 index 0000000..20841a7 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/TODO b/05/tcc-0.9.27/TODO new file mode 100644 index 0000000..d810088 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/VERSION b/05/tcc-0.9.27/VERSION new file mode 100644 index 0000000..9a54223 --- /dev/null +++ b/05/tcc-0.9.27/VERSION @@ -0,0 +1 @@ +0.9.27 diff --git a/05/tcc-0.9.27/arm-asm.c b/05/tcc-0.9.27/arm-asm.c new file mode 100644 index 0000000..3b5ae66 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/arm-gen.c b/05/tcc-0.9.27/arm-gen.c new file mode 100644 index 0000000..f535a09 --- /dev/null +++ b/05/tcc-0.9.27/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<>(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(rTREG_F7) + tcc_error("compiler error! register %i is no vfp register",r); + return r - TREG_F0; +} +#else +static uint32_t fpr(int r) +{ + if(rTREG_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<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< 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<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/05/tcc-0.9.27/arm-link.c b/05/tcc-0.9.27/arm-link.c new file mode 100644 index 0000000..92a24eb --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/arm64-gen.c b/05/tcc-0.9.27/arm64-gen.c new file mode 100644 index 0000000..86b3af7 --- /dev/null +++ b/05/tcc-0.9.27/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 + +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/05/tcc-0.9.27/arm64-link.c b/05/tcc-0.9.27/arm64-link.c new file mode 100644 index 0000000..59322c5 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/assert.h b/05/tcc-0.9.27/assert.h new file mode 100644 index 0000000..8cac979 --- /dev/null +++ b/05/tcc-0.9.27/assert.h @@ -0,0 +1,7 @@ +#ifndef _ASSERT_H +#define _ASSERT_H + +// assert is defined in stdc_common.h +#include + +#endif // _ASSERT_H diff --git a/05/tcc-0.9.27/c67-gen.c b/05/tcc-0.9.27/c67-gen.c new file mode 100644 index 0000000..bcb4b0e --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/c67-link.c b/05/tcc-0.9.27/c67-link.c new file mode 100644 index 0000000..de72e44 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/coff.h b/05/tcc-0.9.27/coff.h new file mode 100644 index 0000000..e8e6185 --- /dev/null +++ b/05/tcc-0.9.27/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 "!\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)&~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/05/tcc-0.9.27/configure b/05/tcc-0.9.27/configure new file mode 100755 index 0000000..1ee3acb --- /dev/null +++ b/05/tcc-0.9.27/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 <> $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/05/tcc-0.9.27/ctype.h b/05/tcc-0.9.27/ctype.h new file mode 100644 index 0000000..ed6833d --- /dev/null +++ b/05/tcc-0.9.27/ctype.h @@ -0,0 +1,92 @@ +#ifndef _CTYPE_H +#define _CTYPE_H + +#include + +int islower(int c) { + return c >= 'a' && c <= 'z'; +} + +int isupper(int c) { + return c >= 'A' && c <= 'Z'; +} + +int isalpha(int c) { + return isupper(c) || islower(c); +} + +int isalnum(int c) { + return isalpha(c) || isdigit(c); +} + +int isprint(int c) { + if (isalnum(c)) return 1; + switch (c) { + case '!': return 1; + case '@': return 1; + case '#': return 1; + case '$': return 1; + case '%': return 1; + case '^': return 1; + case '&': return 1; + case '*': return 1; + case '(': return 1; + case ')': return 1; + case '-': return 1; + case '=': return 1; + case '_': return 1; + case '+': return 1; + case '`': return 1; + case '~': return 1; + case '[': return 1; + case '{': return 1; + case ']': return 1; + case '}': return 1; + case '\\': return 1; + case '|': return 1; + case ';': return 1; + case ':': return 1; + case '\'': return 1; + case '"': return 1; + case ',': return 1; + case '<': return 1; + case '.': return 1; + case '>': return 1; + case '/': return 1; + case '?': return 1; + } + return 0; +} + +int iscntrl(int c) { + return !isprint(c); +} + +int isgraph(int c) { + return isprint(c) && c != ' '; +} + +int ispunct(int c) { + return isprint(c) && c != ' ' && !isalnum(c); +} + +int isxdigit(int c) { + if (isdigit(c)) return 1; + if (c >= 'a' && c <= 'f') return 1; + if (c >= 'A' && c <= 'F') return 1; + return 0; +} + +int tolower(int c) { + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + return c; +} + +int toupper(int c) { + if (c >= 'a' && c <= 'z') + return c - 'a' + 'A'; + return c; +} + +#endif // _CTYPE_H diff --git a/05/tcc-0.9.27/elf.h b/05/tcc-0.9.27/elf.h new file mode 100644 index 0000000..6c2faed --- /dev/null +++ b/05/tcc-0.9.27/elf.h @@ -0,0 +1,3240 @@ +/* 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 + . */ + +#ifndef _ELF_H +#define _ELF_H 1 + +#ifndef _WIN32 +#ifdef __GNUC__ +#include +#endif +#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. */ +#undef VER_FLG_WEAK +#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 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/05/tcc-0.9.27/errno.h b/05/tcc-0.9.27/errno.h new file mode 100644 index 0000000..426f351 --- /dev/null +++ b/05/tcc-0.9.27/errno.h @@ -0,0 +1,6 @@ +#ifndef _ERRNO_H +#define _ERRNO_H + +#include // we define all the relevant things here + +#endif // _ERRNO_H diff --git a/05/tcc-0.9.27/examples/ex1.c b/05/tcc-0.9.27/examples/ex1.c new file mode 100755 index 0000000..3d2a3e1 --- /dev/null +++ b/05/tcc-0.9.27/examples/ex1.c @@ -0,0 +1,8 @@ +#!/usr/local/bin/tcc -run +#include + +int main() +{ + printf("Hello World\n"); + return 0; +} diff --git a/05/tcc-0.9.27/examples/ex2.c b/05/tcc-0.9.27/examples/ex2.c new file mode 100644 index 0000000..d415e39 --- /dev/null +++ b/05/tcc-0.9.27/examples/ex2.c @@ -0,0 +1,98 @@ +#include +#include + +#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 + +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/05/tcc-0.9.27/examples/ex4.c b/05/tcc-0.9.27/examples/ex4.c new file mode 100755 index 0000000..f92c0da --- /dev/null +++ b/05/tcc-0.9.27/examples/ex4.c @@ -0,0 +1,26 @@ +#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11 +#include +#include +#include + +/* 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/05/tcc-0.9.27/examples/ex5.c b/05/tcc-0.9.27/examples/ex5.c new file mode 100644 index 0000000..156425e --- /dev/null +++ b/05/tcc-0.9.27/examples/ex5.c @@ -0,0 +1,8 @@ +#include +#include + +int main() +{ + printf("Hello World\n"); + return 0; +} diff --git a/05/tcc-0.9.27/float.h b/05/tcc-0.9.27/float.h new file mode 100644 index 0000000..6ae607d --- /dev/null +++ b/05/tcc-0.9.27/float.h @@ -0,0 +1,34 @@ +#ifndef _FLOAT_H +#define _FLOAT_H + +#define DBL_DIG 15 +#define DBL_EPSILON 2.2204460492503131e-16 +#define DBL_MANT_DIG 53 +#define DBL_MAX 1.7976931348623157e+308 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define DBL_MIN 2.2250738585072027e-308 +#define DBL_MIN_10_EXP (-307) +#define DBL_MIN_EXP (-1021) +#define FLT_DIG 6 +#define FLT_EPSILON 1.19209290e-07 +#define FLT_MANT_DIG 24 +#define FLT_MAX 3.40282347e+38 +#define FLT_MAX_10_EXP +38 +#define FLT_MAX_EXP 128 +#define FLT_MIN 1.17549435e-38 +#define FLT_MIN_10_EXP (-37) +#define FLT_MIN_EXP (-125) +#define FLT_RADIX 2 +#define FLT_ROUNDS 1 +#define LDBL_DIG DBL_DIG +#define LDBL_EPSILON DBL_EPSILON +#define LDBL_MANT_DIG DBL_MANT_DIG +#define LDBL_MAX DBL_MAX +#define LDBL_MAX_10_EXP DBL_MAX_10_EXP +#define LDBL_MAX_EXP DBL_MAX_EXP +#define LDBL_MIN DBL_MIN +#define LDBL_MIN_10_EXP DBL_MIN_10_EXP +#define LDBL_MIN_EXP DBL_MIN_EXP + +#endif // _FLOAT_H diff --git a/05/tcc-0.9.27/i386-asm.c b/05/tcc-0.9.27/i386-asm.c new file mode 100644 index 0000000..0ebf782 --- /dev/null +++ b/05/tcc-0.9.27/i386-asm.c @@ -0,0 +1,1725 @@ +/* + * 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 + /* last operation */ + 0 +}; + +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;inb_ops;i++) { + for(j=0;jop_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= 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;iinput_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;iconstraint; + 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;iconstraint; + /* 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;ireg >= 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;iid ? 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; +#ifdef TCC_TARGET_X86_64 + case 8: + reg = TOK_ASM_rax + reg; + break; +#endif + default: + reg = TOK_ASM_eax + reg; + break; + } + 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/05/tcc-0.9.27/i386-asm.h b/05/tcc-0.9.27/i386-asm.h new file mode 100644 index 0000000..65d5179 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/i386-gen.c b/05/tcc-0.9.27/i386-gen.c new file mode 100644 index 0000000..b9c3599 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/i386-link.c b/05/tcc-0.9.27/i386-link.c new file mode 100644 index 0000000..aea3c21 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/i386-tok.h b/05/tcc-0.9.27/i386-tok.h new file mode 100644 index 0000000..cad97fe --- /dev/null +++ b/05/tcc-0.9.27/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_ASMTEST1(j) + + DEF_ASMTEST1(set) + DEF_ASMTEST(set,b) + DEF_ASMTEST1(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/05/tcc-0.9.27/il-gen.c b/05/tcc-0.9.27/il-gen.c new file mode 100644 index 0000000..bb670cc --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/il-opcodes.h b/05/tcc-0.9.27/il-opcodes.h new file mode 100644 index 0000000..d53ffb2 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/include/float.h b/05/tcc-0.9.27/include/float.h new file mode 100644 index 0000000..f16f1f0 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/include/stdarg.h b/05/tcc-0.9.27/include/stdarg.h new file mode 100644 index 0000000..10ce733 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/include/stdbool.h b/05/tcc-0.9.27/include/stdbool.h new file mode 100644 index 0000000..d2ee446 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/include/stddef.h b/05/tcc-0.9.27/include/stddef.h new file mode 100644 index 0000000..694d503 --- /dev/null +++ b/05/tcc-0.9.27/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 (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/05/tcc-0.9.27/include/varargs.h b/05/tcc-0.9.27/include/varargs.h new file mode 100644 index 0000000..d614366 --- /dev/null +++ b/05/tcc-0.9.27/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 ." +#error "Revise your code to use ." + +#endif diff --git a/05/tcc-0.9.27/lib/Makefile b/05/tcc-0.9.27/lib/Makefile new file mode 100644 index 0000000..0c1ec54 --- /dev/null +++ b/05/tcc-0.9.27/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 -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/05/tcc-0.9.27/lib/alloca-arm.S b/05/tcc-0.9.27/lib/alloca-arm.S new file mode 100644 index 0000000..68556e3 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/lib/alloca86-bt.S b/05/tcc-0.9.27/lib/alloca86-bt.S new file mode 100644 index 0000000..4f95cf1 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/lib/alloca86.S b/05/tcc-0.9.27/lib/alloca86.S new file mode 100644 index 0000000..bb7a2c2 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/lib/alloca86_64-bt.S b/05/tcc-0.9.27/lib/alloca86_64-bt.S new file mode 100644 index 0000000..4cbad90 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/lib/alloca86_64.S b/05/tcc-0.9.27/lib/alloca86_64.S new file mode 100644 index 0000000..ae3c97d --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/lib/armeabi.c b/05/tcc-0.9.27/lib/armeabi.c new file mode 100644 index 0000000..a59640d --- /dev/null +++ b/05/tcc-0.9.27/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 +#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/05/tcc-0.9.27/lib/armflush.c b/05/tcc-0.9.27/lib/armflush.c new file mode 100644 index 0000000..eae3260 --- /dev/null +++ b/05/tcc-0.9.27/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 +#include +#include + +#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/05/tcc-0.9.27/lib/bcheck.c b/05/tcc-0.9.27/lib/bcheck.c new file mode 100644 index 0000000..90f0ad2 --- /dev/null +++ b/05/tcc-0.9.27/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 +#include +#include +#include + +#if !defined(__FreeBSD__) \ + && !defined(__FreeBSD_kernel__) \ + && !defined(__DragonFly__) \ + && !defined(__OpenBSD__) \ + && !defined(__NetBSD__) +#include +#endif + +#if !defined(_WIN32) +#include +#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_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= 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(;estart = start; + e->size = size; + } + add_region(e, start, size); + } + } else { + /* mark until end of page */ + e2 = page + BOUND_T2_SIZE; + e++; + for(;estart = start; + e->size = size; + } + /* mark intermediate pages, if any */ + for(i=t1_start+1;istart = start; + e->size = size; + } + } + /* last page */ + page = get_page(t1_end); + e2 = (BoundEntry *)((char *)page + t2_end); + for(e=page;estart = 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(;estart = 0; + e->size = empty_size; + } + delete_region(e, p, empty_size); + } + } else { + /* mark until end of page */ + e2 = page + BOUND_T2_SIZE; + e++; + for(;estart = 0; + e->size = empty_size; + } + /* mark intermediate pages, if any */ + /* XXX: should free them */ + for(i=t1_start+1;istart = 0; + e->size = empty_size; + } + } + /* last page */ + page = get_page(t1_end); + e2 = (BoundEntry *)((char *)page + t2_end); + for(e=page;estart = 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;isize != 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/05/tcc-0.9.27/lib/lib-arm64.c b/05/tcc-0.9.27/lib/lib-arm64.c new file mode 100644 index 0000000..b8fd9e8 --- /dev/null +++ b/05/tcc-0.9.27/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 +#include +#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/05/tcc-0.9.27/lib/libtcc1.c b/05/tcc-0.9.27/lib/libtcc1.c new file mode 100644 index 0000000..0e46618 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/lib/va_list.c b/05/tcc-0.9.27/lib/va_list.c new file mode 100644 index 0000000..8749f46 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/libtcc.c b/05/tcc-0.9.27/libtcc.c new file mode 100644 index 0000000..3ff8a77 --- /dev/null +++ b/05/tcc-0.9.27/libtcc.c @@ -0,0 +1,1998 @@ +/* + * 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 = ""; + 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, "", 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, "", 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, + ELF64_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 FlagDef options_W[] = { + { 0, 0, "all" }, + { 0, 0, "unsupported" }, + { 0, 0, "write-strings" }, + { 0, 0, "error" }, + { 0, 0, "gcc-compat" }, + { 0, WD_ALL, "implicit-function-declaration" }, + { 0, 0, NULL } +}; + +static FlagDef options_f[] = { + { 0, 0, "unsigned-char" }, + { 0, FD_INVERT, "signed-char" }, + { 0, FD_INVERT, "common" }, + { 0, 0, "leading-underscore" }, + { 0, 0, "ms-extensions" }, + { 0, 0, "dollars-in-identifiers" }, + { 0, 0, NULL } +}; + +static FlagDef options_m[] = { + { 0, 0, "ms-bitfields" }, +#ifdef TCC_TARGET_X86_64 + { 0, FD_INVERT, "sse" }, +#endif + { 0, 0, NULL } +}; + +void _init_options(void) { + options_W[1].offset = offsetof(TCCState, warn_unsupported); + options_W[2].offset = offsetof(TCCState, warn_write_strings); + options_W[3].offset = offsetof(TCCState, warn_error); + options_W[4].offset = offsetof(TCCState, warn_gcc_compat); + options_W[5].offset = offsetof(TCCState, warn_implicit_function_declaration); + options_f[0].offset = offsetof(TCCState, char_is_unsigned); + options_f[1].offset = offsetof(TCCState, char_is_unsigned); + options_f[2].offset = offsetof(TCCState, nocommon); + options_f[3].offset = offsetof(TCCState, leading_underscore); + options_f[4].offset = offsetof(TCCState, ms_extensions); + options_f[5].offset = offsetof(TCCState, dollars_in_identifiers); + options_m[0].offset = offsetof(TCCState, ms_bitfields); +#ifdef TCC_TARGET_X86_64 + options_m[1].offset = offsetof(TCCState, nosse); +#endif +} + +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/05/tcc-0.9.27/libtcc.h b/05/tcc-0.9.27/libtcc.h new file mode 100644 index 0000000..a1b31e3 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/limits.h b/05/tcc-0.9.27/limits.h new file mode 100644 index 0000000..633e9ff --- /dev/null +++ b/05/tcc-0.9.27/limits.h @@ -0,0 +1,6 @@ +#ifndef _LIMITS_H +#define _LIMITS_H + +#include // we define all the relevant constants here + +#endif // _LIMITS_H diff --git a/05/tcc-0.9.27/locale.h b/05/tcc-0.9.27/locale.h new file mode 100644 index 0000000..af90729 --- /dev/null +++ b/05/tcc-0.9.27/locale.h @@ -0,0 +1,60 @@ +#ifndef _LOCALE_H +#define _LOCALE_H + +#include + +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_MAX */ + char frac_digits; /* CHAR_MAX */ + char p_cs_precedes; /* CHAR_MAX */ + char p_sep_by_space; /* CHAR_MAX */ + char n_cs_precedes; /* CHAR_MAX */ + char n_sep_by_space; /* CHAR_MAX */ + char p_sign_posn; /* CHAR_MAX */ + char n_sign_posn; /* CHAR_MAX */ +}; + +// these are GCC's constants, but it doesn't really matter which constants we use. +#define LC_ALL 6 +#define LC_COLLATE 3 +#define LC_CTYPE 0 +#define LC_MONETARY 4 +#define LC_NUMERIC 1 +#define LC_TIME 2 + +char *setlocale(int category, char *locale) { + if (!locale) return "C"; + if (*locale == 'C' && !locale[1]) { + // yep + return "C"; + } + + // we only support the C locale + return NULL; + +} + +struct lconv *localeconv(void) { + static struct lconv conv = { + ".", + "", "", "", + "", "", "", + "", "", "", + CHAR_MAX, CHAR_MAX, CHAR_MAX, + CHAR_MAX, CHAR_MAX, CHAR_MAX, + CHAR_MAX, CHAR_MAX + }; + return &conv; +} + +#endif // _LOCALE_H diff --git a/05/tcc-0.9.27/math.h b/05/tcc-0.9.27/math.h new file mode 100644 index 0000000..7b029ac --- /dev/null +++ b/05/tcc-0.9.27/math.h @@ -0,0 +1,409 @@ +#ifndef _MATH_H +#define _MATH_H + +#include +#define HUGE_VAL _INFINITY // glibc defines HUGE_VAL as infinity (the C standard only requires it to be positive, funnily enough) +#define _NAN (-(_INFINITY-_INFINITY)) +#define _PI 3.141592653589793 +#define _2PI 6.283185307179586 +#define _HALF_PI 1.5707963267948966 +#define _THREE_HALVES_PI 4.71238898038469 + +// NOTE: these functions are not IEEE 754-compliant (the C standard doesn't require them to be), but they're pretty good + +double frexp(double value, int *exp) { + if (value == 0) { + *exp = 0; + return 0; + } + unsigned long u = *(unsigned long *)&value, significand; + *exp = ((u >> 52) & 0x7ff) - 1022; + // replace exponent with 1022 + u &= 0x800fffffffffffff; + u |= 0x3fe0000000000000; + return *(double *)&u; +} + +double ldexp(double x, int exp) { + int e; + double y = frexp(x, &e); + // since x = y * 2^e, x * 2^exp = y * 2^(e+exp) + exp += e; + if (exp < -1022) return 0; + if (exp > 1023) return _INFINITY; + unsigned long pow2 = (unsigned long)(exp + 1023) << 52; + return y * *(double *)&pow2; +} + +double floor(double x) { + if (x >= 0.0) { + if (x > 1073741824.0 * 1073741824.0) + return x; // floats this big must be integers + return (unsigned long)x; + } else { + if (x < -1073741824.0 * 1073741824.0) + return x; // floats this big must be integers + double i = (long)x; + if (x == i) return x; + return i - 1.0; + } +} + +double ceil(double x) { + double f = floor(x); + if (x == f) return f; + return f + 1.; +} + +double fabs(double x) { + // this is better than x >= 0 ? x : -x because it deals with -0 properly + unsigned long u = *(unsigned long *)&x; + u &= 0x7fffffffffffffff; + return *(double *)&u; +} + +double fmod(double x, double y) { + if (y == 0.0) { + errno = EDOM; + return 0.0; + } + return x - (floor(x / y) * y); +} + +double _sin_taylor(double x) { + double i; + double term = x; + // taylor expansion for sin: x - x³/3! + xâµ/5! - ... + + // https://en.wikipedia.org/wiki/Kahan_summation_algorithm + double prev = -1.0; + double sum = 0.0; + double c = 0.0; + for (i = 0.0; i < 100.0 && sum != prev; ++i) { + prev = sum; + double y = term - c; + double t = sum + y; + c = (t - sum) - y; + sum = t; + term *= -(x * x) / ((2.0*i+2.0)*(2.0*i+3.0)); + } + return sum; +} + +double _cos_taylor(double x) { + double i; + double term = 1.0; + // taylor expansion for cos: 1 - x²/2! + xâ´/4! - ... + + // https://en.wikipedia.org/wiki/Kahan_summation_algorithm + double prev = -1.0; + double sum = 0.0; + double c = 0.0; + for (i = 0.0; i < 100.0 && sum != prev; ++i) { + prev = sum; + double y = term - c; + double t = sum + y; + c = (t - sum) - y; + sum = t; + term *= -(x * x) / ((2.0*i+1.0)*(2.0*i+2.0)); + } + return sum; +} + +double sin(double x) { + x = fmod(x, 2.0*_PI); + // the Taylor series works best for small inputs. so, provide _sin_taylor with a value in the range [0,Ï€/2] + if (x < _HALF_PI) + return _sin_taylor(x); + if (x < _PI) + return _sin_taylor(_PI - x); + if (x < _THREE_HALVES_PI) + return -_sin_taylor(x - _PI); + return -_sin_taylor(_2PI - x); +} + +double cos(double x) { + x = fmod(x, 2.0*_PI); + // the Taylor series works best for small inputs. so, provide _cos_taylor with a value in the range [0,Ï€/2] + if (x < _HALF_PI) + return _cos_taylor(x); + if (x < _PI) + return -_cos_taylor(_PI - x); + if (x < _THREE_HALVES_PI) + return -_cos_taylor(x - _PI); + return _cos_taylor(_2PI - x); +} + +double tan(double x) { + return sin(x)/cos(x); +} + +// for sqrt and the inverse trigonometric functions, we use Newton's method +// https://en.wikipedia.org/wiki/Newton%27s_method + +double sqrt(double x) { + if (x < 0.0) { + errno = EDOM; + return _NAN; + } + if (x == 0.0) return 0.0; + if (x == _INFINITY) return _INFINITY; + // we want to find the root of: f(t) = t² - x + // f'(t) = 2t + int exp; + double y = frexp(x, &exp); + if (exp & 1) { + y *= 2; + --exp; + } + // newton's method will be slow for very small or very large numbers. + // so we have ensured that + // 0.5 ≤ y < 2 + // and also x = y * 2^exp; sqrt(x) = sqrt(y) * 2^(exp/2) NB: we've ensured that exp is even + + // 7 iterations seems to be more than enough for any number + double t = y; + t = (y / t + t) * 0.5; + t = (y / t + t) * 0.5; + t = (y / t + t) * 0.5; + t = (y / t + t) * 0.5; + t = (y / t + t) * 0.5; + t = (y / t + t) * 0.5; + t = (y / t + t) * 0.5; + + return ldexp(t, exp>>1); + +} + +double _acos_newton(double x) { + // we want to find the root of: f(t) = cos(t) - x + // f'(t) = -sin(t) + double t = _HALF_PI - x; // reasonably good first approximation + double prev_t = -100.0; + int i; + + for (i = 0; i < 100 && prev_t != t; ++i) { + prev_t = t; + t += (cos(t) - x) / sin(t); + } + return t; +} + +double _asin_newton(double x) { + // we want to find the root of: f(t) = sin(t) - x + // f'(t) = cos(t) + double t = x; // reasonably good first approximation + double prev_t = -100.0; + int i; + + for (i = 0; i < 100 && prev_t != t; ++i) { + prev_t = t; + t += (x - sin(t)) / cos(t); + } + return t; +} + +double acos(double x) { + if (x > 1.0 || x < -1.0) { + errno = EDOM; + return _NAN; + } + // Newton's method doesn't work well near -1 and 1, because f(x) / f'(x) is very large. + if (x > 0.8) + return _asin_newton(sqrt(1-x*x)); + if (x < -0.8) + return _PI-_asin_newton(sqrt(1-x*x)); + + return _acos_newton(x); +} + +double asin(double x) { + if (x > 1.0 || x < -1.0) { + errno = EDOM; + return _NAN; + } + // Newton's method doesn't work well near -1 and 1, because f(x) / f'(x) is very large. + if (x > 0.8) + return _acos_newton(sqrt(1.0-x*x)); + if (x < -0.8) + return -_acos_newton(sqrt(1.0-x*x)); + + return _asin_newton(x); +} + +double atan(double x) { + // the formula below breaks for really large inputs; tan(10^20) as a double is indistinguishable from pi/2 anyways + if (x > 1e20) return _HALF_PI; + if (x < -1e20) return -_HALF_PI; + + // we can use a nice trigonometric identity here + return asin(x / sqrt(1+x*x)); +} + +double atan2(double y, double x) { + if (x == 0.0) { + if (y > 0.0) return _HALF_PI; + if (y < 0.0) return -_HALF_PI; + return 0.0; // this is what IEEE 754 does + } + + double a = atan(y/x); + if (x > 0.0) { + return a; + } else if (y > 0.0) { + return a + _PI; + } else { + return a - _PI; + } +} + +double _exp_taylor(double x) { + double i; + double term = 1.0; + // taylor expansion for exp: 1 + x/1! + x²/2! + ... + + // https://en.wikipedia.org/wiki/Kahan_summation_algorithm + double prev = -1.0; + double sum = 0.0; + double c = 0.0; + for (i = 1.0; i < 100.0 && sum != prev; ++i) { + prev = sum; + double y = term - c; + double t = sum + y; + c = (t - sum) - y; + sum = t; + term *= x / i; + } + return sum; +} + +double exp(double x) { + if (x > 709.782712893384) { + errno = ERANGE; + return _INFINITY; + } + if (x == 0.0) return 1; + if (x < -744.4400719213812) + return 0; + int i, e; + double y = frexp(x, &e); + if (e < 1.0) return _exp_taylor(x); + // the taylor series doesn't work well for large x (positive or negative), + // so we use the fact that exp(y*2^e) = exp(y)^(2^e) + double value = _exp_taylor(y); + for (i = 0; i < e; ++i) + value *= value; + return value; +} + +#define _LOG2 0.6931471805599453 + +double log(double x) { + if (x < 0.0) { + errno = EDOM; + return _NAN; + } + if (x == 0.0) return -_INFINITY; + if (x == 1.0) return 0.0; + int e; + double sum; + double a = frexp(x, &e); + // since x = a * 2^e, log(x) = log(a) + log(2^e) = log(a) + e log(2) + sum = e * _LOG2; + // now that a is in [1/2,1), the series log(a) = (a-1) - (a-1)²/2 + (a-1)³/3 - ... converges quickly + + a -= 1; + // https://en.wikipedia.org/wiki/Kahan_summation_algorithm + double prev = HUGE_VAL; + double c = 0; + double term = a; + double i; + for (i = 1.0; i < 100.0 && sum != prev; ++i) { + prev = sum; + double y = term / i - c; + double t = sum + y; + c = (t - sum) - y; + sum = t; + term *= -a; + } + return sum; +} + +#define _INVLOG10 0.43429448190325176 // = 1/log(10) +double log10(double x) { + return log(x) * _INVLOG10; +} + +double modf(double value, double *iptr) { + double m = fmod(value, 1.0); + if (value >= 0.0) { + *iptr = value - m; + return m; + } else if (m == 0.0) { + *iptr = value; + return 0.0; + } else { + *iptr = value - m + 1.0; + return m - 1.0; + } +} + +// double raised to the power of an integer +double _dpowi(double x, unsigned long y) { + double result = 1.0; + if (y & 1) { + --y; + result *= x; + } + if (y > 0) { + double p = _dpowi(x, y >> 1); + result *= p * p; + } + return result; +} + +double pow(double x, double y) { + if (x > 0.0) { + return exp(y * log(x)); + } else if (x < 0.0) { + if (fmod(y, 1.0) != 0) { + errno = EDOM; + return _NAN; + } + if (y > 1.6602069666338597e+19) + return x < -1. ? -_INFINITY : 0.; + if (y < -1.6602069666338597e+19) + return x < -1. ? 0. : -_INFINITY; + return _dpowi(x, (unsigned long)y); + } else { + if (y < 0) { + errno = EDOM; + return _NAN; + } + if (y > 0) { + // 0^x = 0 for x>0 + return 0.; + } + // 0^0 = 1 + return 1.; + } +} + +double cosh(double x) { + double e = exp(x); + return (e + 1./e) * 0.5; +} + +double sinh(double x) { + double e = exp(x); + return (e - 1./e) * 0.5; +} + +double tanh(double x) { + if (x > 20.0) return 1.; + if (x < -20.0) return -1.; + double e = exp(x); + double f = 1./e; + return (e - f) / (e + f); +} +#endif // _MATH_H diff --git a/05/tcc-0.9.27/setjmp.h b/05/tcc-0.9.27/setjmp.h new file mode 100644 index 0000000..b3ffce1 --- /dev/null +++ b/05/tcc-0.9.27/setjmp.h @@ -0,0 +1,21 @@ +#ifndef _SETJMP_H +#define _SETJMP_H + +#include + +typedef long jmp_buf[3]; + +// @NONSTANDARD: we don't actually support setjmp + +int setjmp(jmp_buf env) { + return 0; +} + +void __longjmp(jmp_buf env, int val, const char *filename, int line) { + fprintf(stderr, "Error: Tried to longjmp from %s:%d with value %d\n", filename, line, val); + _Exit(-1); +} + +#define longjmp(env, val) __longjmp(env, val, __FILE__, __LINE__) + +#endif diff --git a/05/tcc-0.9.27/signal.h b/05/tcc-0.9.27/signal.h new file mode 100644 index 0000000..ded960c --- /dev/null +++ b/05/tcc-0.9.27/signal.h @@ -0,0 +1,253 @@ +#ifndef _SIGNAL_H +#define _SIGNAL_H + + +#include + +typedef long sig_atomic_t; // there are no "asynchronous interrupts" + +#define SIG_DFL ((void *)0) +#define SIG_IGN _sig_ign +#define SIG_ERR ((void *)-1) + +typedef void (*_Sighandler)(int); + +struct sigaction { + void (*sa_handler)(int); + #define sa_sigaction sa_handler + unsigned long sa_flags; + void (*sa_restorer)(void); + unsigned long sa_mask; +}; + +unsigned char _signal_restorer[] = { + 0x48,0xb8,15,0,0,0,0,0,0,0, // mov rax, 15 (sigreturn) + 0x0f,0x05 // syscall +}; + +#define _SIGNAL_HANDLERS 0xfff000 +#define _LE64(x) (x)&0xff, ((x)>> 8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff, \ + ((x)>>32)&0xff, ((x)>>40)&0xff, ((x)>>48)&0xff, (x)>>56 + +// we need to do this weird indirection because linux has a different +// calling convention from us. + +unsigned char _signal_handler[] = { + // signal # passed in rdi + 0x48,0x89,0xf8, // mov rax, rdi (signal #) + 0x50, // push rax + 0x50, // push rax (allocate space for return value) + 0x48,0xb8,_LE64(_SIGNAL_HANDLERS), // mov rax, _SIGNAL_HANDLERS + 0x48,0x89,0xc3, // mov rbx, rax + 0x48,0x89,0xf8, // mov rax, rdi (signal #) + 0x48,0xc1,0xe0,0x03, // shl rax, 3 + 0x48,0x01,0xd8, // add rax, rbx + 0x48,0x89,0xc3, // mov rbx, rax + 0x48,0x8b,0x03, // mov rax, [rbx] + 0xff,0xd0, // call rax + 0x48,0x81,0xc4,16,0,0,0, // add rsp, 16 + 0xc3 // ret +}; + +#define _SA_RESTORER 0x04000000 +#define SA_SIGINFO 4 +#define SA_RESETHAND 0x80000000 + +int __sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) { + return __syscall(13, signum, act, oldact, 8, 0, 0); +} + +void sigemptyset(unsigned long *set) { + *set = 0; +} + +void _sig_ign(int signal) { + return; +} + +static unsigned long _sig_mask = 0; + +_Sighandler signal(int sig, _Sighandler func) { + void **handlers = _SIGNAL_HANDLERS; + _Sighandler ret = handlers[sig]; + if (func == SIG_IGN) { + func = _sig_ign; + } + handlers[sig] = func; + + if (func == SIG_DFL) { + _sig_mask &= ~(1ul << (sig-1)); + } else { + _sig_mask |= 1ul << (sig-1); + } + struct sigaction act = {0}; + act.sa_handler = func == SIG_DFL ? SIG_DFL : (void*)_signal_handler; + act.sa_mask = _sig_mask; + act.sa_flags = _SA_RESTORER; + act.sa_restorer = _signal_restorer; + __sigaction(sig, &act, NULL); + return ret; +} + +int raise(int signal) { + return kill(getpid(), signal); +} + +#define FPE_INTDIV 1 +#define FPE_FLTDIV 3 + +#define __SI_MAX_SIZE 128 +#if __WORDSIZE == 64 +# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4) +#else +# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3) +#endif + +#ifndef __SI_ALIGNMENT +# define __SI_ALIGNMENT /* nothing */ +#endif +#ifndef __SI_BAND_TYPE +# define __SI_BAND_TYPE long int +#endif +#ifndef __SI_CLOCK_T +# define __SI_CLOCK_T __clock_t +#endif +#ifndef __SI_ERRNO_THEN_CODE +# define __SI_ERRNO_THEN_CODE 1 +#endif +#ifndef __SI_HAVE_SIGSYS +# define __SI_HAVE_SIGSYS 1 +#endif +#ifndef __SI_SIGFAULT_ADDL +# define __SI_SIGFAULT_ADDL /* nothing */ +#endif + +typedef int __pid_t; +typedef unsigned __uid_t; + +union __sigval +{ + int __sival_int; + void *__sival_ptr; +}; + +typedef union __sigval __sigval_t; +typedef long __clock_t; + +typedef struct + { + int si_signo; /* Signal number. */ +#if __SI_ERRNO_THEN_CODE + int si_errno; /* If non-zero, an errno value associated with + this signal, as defined in . */ + int si_code; /* Signal code. */ +#else + int si_code; + int si_errno; +#endif +#if __WORDSIZE == 64 + int __pad0; /* Explicit padding. */ +#endif + + union + { + int _pad[__SI_PAD_SIZE]; + + /* kill(). */ + struct + { + __pid_t si_pid; /* Sending process ID. */ + __uid_t si_uid; /* Real user ID of sending process. */ + } _kill; + + /* POSIX.1b timers. */ + struct + { + int si_tid; /* Timer ID. */ + int si_overrun; /* Overrun count. */ + __sigval_t si_sigval; /* Signal value. */ + } _timer; + + /* POSIX.1b signals. */ + struct + { + __pid_t si_pid; /* Sending process ID. */ + __uid_t si_uid; /* Real user ID of sending process. */ + __sigval_t si_sigval; /* Signal value. */ + } _rt; + + /* SIGCHLD. */ + struct + { + __pid_t si_pid; /* Which child. */ + __uid_t si_uid; /* Real user ID of sending process. */ + int si_status; /* Exit value or signal. */ + __SI_CLOCK_T si_utime; + __SI_CLOCK_T si_stime; + } _sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */ + struct + { + void *si_addr; /* Faulting insn/memory ref. */ + __SI_SIGFAULT_ADDL + short int si_addr_lsb; /* Valid LSB of the reported address. */ + union + { + /* used when si_code=SEGV_BNDERR */ + struct + { + void *_lower; + void *_upper; + } _addr_bnd; + /* used when si_code=SEGV_PKUERR */ + uint32_t _pkey; + } _bounds; + } _sigfault; + + /* SIGPOLL. */ + struct + { + __SI_BAND_TYPE si_band; /* Band event for SIGPOLL. */ + int si_fd; + } _sigpoll; + + /* SIGSYS. */ +#if __SI_HAVE_SIGSYS + struct + { + void *_call_addr; /* Calling user insn. */ + int _syscall; /* Triggering system call number. */ + unsigned int _arch; /* AUDIT_ARCH_* of syscall. */ + } _sigsys; +#endif + } _sifields; + } siginfo_t __SI_ALIGNMENT; + + +/* X/Open requires some more fields with fixed names. */ +#define si_pid _sifields._kill.si_pid +#define si_uid _sifields._kill.si_uid +#define si_timerid _sifields._timer.si_tid +#define si_overrun _sifields._timer.si_overrun +#define si_status _sifields._sigchld.si_status +#define si_utime _sifields._sigchld.si_utime +#define si_stime _sifields._sigchld.si_stime +#define si_value _sifields._rt.si_sigval +#define si_int _sifields._rt.si_sigval.sival_int +#define si_ptr _sifields._rt.si_sigval.sival_ptr +#define si_addr _sifields._sigfault.si_addr +#define si_addr_lsb _sifields._sigfault.si_addr_lsb +#define si_lower _sifields._sigfault._bounds._addr_bnd._lower +#define si_upper _sifields._sigfault._bounds._addr_bnd._upper +#define si_pkey _sifields._sigfault._bounds._pkey +#define si_band _sifields._sigpoll.si_band +#define si_fd _sifields._sigpoll.si_fd +#if __SI_HAVE_SIGSYS +# define si_call_addr _sifields._sigsys._call_addr +# define si_syscall _sifields._sigsys._syscall +# define si_arch _sifields._sigsys._arch +#endif + + +#endif // _SIGNAL_H diff --git a/05/tcc-0.9.27/stab.def b/05/tcc-0.9.27/stab.def new file mode 100644 index 0000000..d583b2f --- /dev/null +++ b/05/tcc-0.9.27/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. */ +// random page break character for some reason +/* 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") +// random page break character for some reason +/* 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/05/tcc-0.9.27/stab.h b/05/tcc-0.9.27/stab.h new file mode 100644 index 0000000..80bd594 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/stdarg.h b/05/tcc-0.9.27/stdarg.h new file mode 100644 index 0000000..4df996f --- /dev/null +++ b/05/tcc-0.9.27/stdarg.h @@ -0,0 +1,10 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef unsigned long va_list; + +#define va_start(list, arg) ((list) = (unsigned long)&arg) +#define va_arg(list, type) (*((type *)(list += ((sizeof(type) + 7) & 0xfffffffffffffff8)))) +#define va_end(list) + +#endif // _STDARG_H diff --git a/05/tcc-0.9.27/stdc_common.h b/05/tcc-0.9.27/stdc_common.h new file mode 100644 index 0000000..7c592c9 --- /dev/null +++ b/05/tcc-0.9.27/stdc_common.h @@ -0,0 +1,693 @@ +#ifndef _STDC_COMMON_H +#define _STDC_COMMON_H + +#define signed +#define volatile +#define register +#define const +#define NULL ((void*)0) + +typedef unsigned char uint8_t; +typedef char int8_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned long uint64_t; +typedef long int64_t; +typedef unsigned long size_t; +typedef long ptrdiff_t; +typedef unsigned long uintptr_t; +typedef long intptr_t; +typedef long ssize_t; + +#define INT8_MAX 0x7f +#define INT8_MIN (-0x80) +#define INT16_MAX 0x7fff +#define INT16_MIN (-0x8000) +#define INT32_MAX 0x7fffffff +#define INT32_MIN (-0x80000000) +#define INT64_MAX 0x7fffffffffffffff +#define INT64_MIN (-0x8000000000000000) +#define UINT8_MAX 0xff +#define UINT16_MAX 0xffff +#define UINT32_MAX 0xffffffff +#define UINT64_MAX 0xffffffffffffffff +#define CHAR_BIT 8 +#define MB_LEN_MAX 4 +#define CHAR_MIN INT8_MIN +#define CHAR_MAX INT8_MAX +#define SCHAR_MIN INT8_MIN +#define SCHAR_MAX INT8_MAX +#define INT_MIN INT32_MIN +#define INT_MAX INT32_MAX +#define LONG_MIN INT64_MIN +#define LONG_MAX INT64_MAX +#define SHRT_MIN INT16_MIN +#define SHRT_MAX INT16_MAX +#define UCHAR_MAX UINT8_MAX +#define USHRT_MAX UINT16_MAX +#define UINT_MAX UINT32_MAX +#define ULONG_MAX UINT64_MAX + +static unsigned char __syscall_data[] = { + // mov rax, [rsp+24] + 0x48, 0x8b, 0x84, 0x24, 24, 0, 0, 0, + // mov rdi, rax + 0x48, 0x89, 0xc7, + // mov rax, [rsp+32] + 0x48, 0x8b, 0x84, 0x24, 32, 0, 0, 0, + // mov rsi, rax + 0x48, 0x89, 0xc6, + // mov rax, [rsp+40] + 0x48, 0x8b, 0x84, 0x24, 40, 0, 0, 0, + // mov rdx, rax + 0x48, 0x89, 0xc2, + // mov rax, [rsp+48] + 0x48, 0x8b, 0x84, 0x24, 48, 0, 0, 0, + // mov r10, rax + 0x49, 0x89, 0xc2, + // mov rax, [rsp+56] + 0x48, 0x8b, 0x84, 0x24, 56, 0, 0, 0, + // mov r8, rax + 0x49, 0x89, 0xc0, + // mov rax, [rsp+64] + 0x48, 0x8b, 0x84, 0x24, 64, 0, 0, 0, + // mov r9, rax + 0x49, 0x89, 0xc1, + // mov rax, [rsp+16] + 0x48, 0x8b, 0x84, 0x24, 16, 0, 0, 0, + // syscall + 0x0f, 0x05, + // mov [rsp+8], rax + 0x48, 0x89, 0x84, 0x24, 8, 0, 0, 0, + // ret + 0xc3 +}; + +#define __syscall(no, arg1, arg2, arg3, arg4, arg5, arg6)\ + (((unsigned long (*)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long))__syscall_data)\ + (no, arg1, arg2, arg3, arg4, arg5, arg6)) + +// we need to define ucontext_t +# define __ctx(fld) fld +typedef long long int greg_t; +#define __NGREG 23 +typedef greg_t gregset_t[__NGREG]; +#define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) +typedef struct +{ + unsigned long int __val[_SIGSET_NWORDS]; +} __sigset_t, sigset_t; +typedef struct +{ + void *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; +enum +{ + REG_R8 = 0, +# define REG_R8 REG_R8 + REG_R9, +# define REG_R9 REG_R9 + REG_R10, +# define REG_R10 REG_R10 + REG_R11, +# define REG_R11 REG_R11 + REG_R12, +# define REG_R12 REG_R12 + REG_R13, +# define REG_R13 REG_R13 + REG_R14, +# define REG_R14 REG_R14 + REG_R15, +# define REG_R15 REG_R15 + REG_RDI, +# define REG_RDI REG_RDI + REG_RSI, +# define REG_RSI REG_RSI + REG_RBP, +# define REG_RBP REG_RBP + REG_RBX, +# define REG_RBX REG_RBX + REG_RDX, +# define REG_RDX REG_RDX + REG_RAX, +# define REG_RAX REG_RAX + REG_RCX, +# define REG_RCX REG_RCX + REG_RSP, +# define REG_RSP REG_RSP + REG_RIP, +# define REG_RIP REG_RIP + REG_EFL, +# define REG_EFL REG_EFL + REG_CSGSFS, /* Actually short cs, gs, fs, __pad0. */ +# define REG_CSGSFS REG_CSGSFS + REG_ERR, +# define REG_ERR REG_ERR + REG_TRAPNO, +# define REG_TRAPNO REG_TRAPNO + REG_OLDMASK, +# define REG_OLDMASK REG_OLDMASK + REG_CR2 +# define REG_CR2 REG_CR2 +}; +struct _libc_fpxreg +{ + unsigned short int __ctx(significand)[4]; + unsigned short int __ctx(exponent); + unsigned short int __glibc_reserved1[3]; +}; +struct _libc_xmmreg +{ + uint32_t __ctx(element)[4]; +}; +struct _libc_fpstate +{ + uint16_t __ctx(cwd); + uint16_t __ctx(swd); + uint16_t __ctx(ftw); + uint16_t __ctx(fop); + uint64_t __ctx(rip); + uint64_t __ctx(rdp); + uint32_t __ctx(mxcsr); + uint32_t __ctx(mxcr_mask); + struct _libc_fpxreg _st[8]; + struct _libc_xmmreg _xmm[16]; + uint32_t __glibc_reserved1[24]; +}; +typedef struct _libc_fpstate *fpregset_t; +typedef struct { + gregset_t __ctx(gregs); + fpregset_t __ctx(fpregs); + unsigned long long __reserved1 [8]; +} mcontext_t; +typedef struct ucontext_t { + unsigned long int __ctx(uc_flags); + struct ucontext_t *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + sigset_t uc_sigmask; + struct _libc_fpstate __fpregs_mem; + unsigned long long int __ssp[4]; +} ucontext_t; + +long read(int fd, void *buf, size_t count) { + return __syscall(0, fd, buf, count, 0, 0, 0); +} + +long write(int fd, void *buf, size_t count) { + return __syscall(1, fd, buf, count, 0, 0, 0); +} + +void _Exit(int status) { + return __syscall(60, status, 0, 0, 0, 0, 0); +} + +int kill(int pid, int sig) { + return __syscall(62, pid, sig, 0, 0, 0, 0); +} + +int getpid(void) { + return __syscall(39, 0, 0, 0, 0, 0, 0); +} + +int fork(void) { + return __syscall(57, 0, 0, 0, 0, 0, 0); +} + +int execve(const char *pathname, char *const argv[], char *const envp[]) { + return __syscall(59, pathname, argv, envp, 0, 0, 0); +} + +int gettimeofday(struct timeval *tv, struct timezone *tz) { + return __syscall(96, tv, tz, 0, 0, 0, 0); +} + +typedef long time_t; + +struct timespec { + time_t tv_sec; + long tv_nsec; +}; + +struct timeval { + time_t tv_sec; + long tv_usec; +}; + +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; + +char *getcwd(char *buf, size_t size) { + long n = __syscall(79, buf, size, 0, 0, 0, 0); + if (n < 0) return NULL; + return buf; +} + +#define _WEXITSTATUS(status) (((status) & 0xff00) >> 8) +#define _WIFEXITED(status) (__WTERMSIG(status) == 0) +#define _WIFSIGNALED(status) \ + (((signed char) (((status) & 0x7f) + 1) >> 1) > 0) +int wait4(int pid, int *status, int options, struct rusage *rusage) { + return __syscall(61, pid, status, options, rusage, 0, 0); +} + +#define SIGABRT 6 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGILL 4 +#define SIGINT 2 +#define SIGSEGV 11 +#define SIGTERM 15 +#define SIGBUS 7 +#define SIGTRAP 5 +void abort(void) { + kill(getpid(), SIGABRT); +} + + +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 1 +int clock_gettime(int clock, struct timespec *tp) { + return __syscall(228, clock, tp, 0, 0, 0, 0); +} + +#define F_OK 0 +#define R_OK 4 +#define W_OK 2 +#define X_OK 1 +int access(const char *pathname, int mode) { + return __syscall(21, pathname, mode, 0, 0, 0, 0); +} + +typedef struct { + int fd; + unsigned char eof; + unsigned char err; + unsigned char has_ungetc; + char ungetc; // character which was pushed by ungetc() +} FILE; + +int errno; +int printf(char *, ...); +int fprintf(FILE *, char *, ...); // needed now for assert() + +FILE _stdin = {0}, *stdin; +FILE _stdout = {1}, *stdout; +FILE _stderr = {2}, *stderr; + +#ifdef NDEBUG +#define assert(x) ((void)0) +#else +int __assert_failed(const char *file, int line, const char *expr) { + fprintf(stderr, "Assertion failed at %s:%d: %s\n", file, line, expr); + abort(); +} +#define assert(x) (void)((x) || __assert_failed(__FILE__, __LINE__, #x)) +#endif + + +int _clamp_long_to_int(long x) { + if (x < INT_MIN) return INT_MIN; + if (x > INT_MAX) return INT_MAX; + return x; +} + +short _clamp_long_to_short(long x) { + if (x < SHRT_MIN) return SHRT_MIN; + if (x > SHRT_MAX) return SHRT_MAX; + return x; +} + +unsigned _clamp_ulong_to_uint(unsigned long x) { + if (x > UINT_MAX) return UINT_MAX; + return x; +} + +unsigned short _clamp_ulong_to_ushort(unsigned long x) { + if (x > USHRT_MAX) return USHRT_MAX; + return x; +} + +#define EIO 5 +#define EDOM 33 +#define ERANGE 34 + +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 +#define MAP_SHARED 0x01 +#define MAP_ANONYMOUS 0x20 +#define MAP_PRIVATE 0x02 +void *mmap(void *addr, size_t length, int prot, int flags, int fd, long offset) { + return __syscall(9, addr, length, prot, flags, fd, offset); +} + +int munmap(void *addr, size_t length) { + return __syscall(11, addr, length, 0, 0, 0, 0); +} + +int mprotect(void *addr, size_t len, int prot) { + return __syscall(10, addr, len, prot, 0, 0, 0); +} + +#define MREMAP_MAYMOVE 1 +void *_mremap(void *addr, size_t old_size, size_t new_size, int flags) { + return __syscall(25, addr, old_size, new_size, flags, 0, 0); +} + +void *malloc(size_t n) { + if (!n) return NULL; + void *memory; + size_t bytes = n + 16; + memory = mmap(0, bytes, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + if ((uint64_t)memory > 0xffffffffffff0000) return NULL; + *(uint64_t *)memory = bytes; + return (char *)memory + 16; +} + +void free(void *ptr) { + if (!ptr) return; + uint64_t *memory = (char *)ptr - 16; + uint64_t size = *memory; + munmap(memory, size); +} + + +size_t strlen(char *s) { + char *t = s; + while (*t) ++t; + return t - s; +} + +void *memcpy(void *s1, const void *s2, size_t n) { + char *p = s1, *end = p + n, *q = s2; + while (p < end) + *p++ = *q++; + return s1; +} + +int isspace(int c) { + return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'; +} + +int isdigit(int c) { + return c >= '0' && c <= '9'; +} + +int _isdigit_in_base(int c, int base) { + if (c >= '0' && c <= '9') { + return c - '0' < base; + } else if (c >= 'a' && c <= 'z') { + return c - 'a' + 10 < base; + } else if (c >= 'A' && c <= 'Z') { + return c - 'A' + 10 < base; + } + return 0; +} + +void *memset(void *s, int c, size_t n) { + char *p = s, *end = p + n; + while (p < end) + *p++ = c; + return s; +} + +unsigned long strtoul(const char *nptr, char **endptr, int base) { + unsigned long value = 0, newvalue; + int overflow = 0; + + while (isspace(*nptr)) ++nptr; + if (*nptr == '+') ++nptr; + if (base == 0) { + if (*nptr == '0') { + ++nptr; + switch (*nptr) { + case 'x': + case 'X': + base = 16; + ++nptr; + break; + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': + base = 8; + break; + default: + // this must just be the number 0. + if (endptr) *endptr = nptr; + return 0; + } + } else { + base = 10; + } + } + + while (1) { + int c = *nptr; + unsigned v; + if (c >= '0' && c <= '9') + v = c - '0'; + else if (c >= 'a' && c <= 'z') + v = c - 'a' + 10; + else if (c >= 'A' && c <= 'Z') + v = c - 'A' + 10; + else break; + if (v >= base) break; + unsigned long newvalue = value * base + v; + if (newvalue < value) overflow = 1; + value = newvalue; + ++nptr; + } + if (endptr) *endptr = nptr; + if (overflow) { + errno = ERANGE; + return ULONG_MAX; + } else { + return value; + } +} + +long strtol(const char *nptr, char **endptr, int base) { + int sign = 1; + while (isspace(*nptr)) ++nptr; + if (*nptr == '-') { + sign = -1; + ++nptr; + } + unsigned long mag = strtoul(nptr, endptr, base); + if (sign > 0) { + if (mag > LONG_MAX) { + errno = ERANGE; + return LONG_MAX; + } + return (long)mag; + } else { + if (mag > (unsigned long)LONG_MAX + 1) { + errno = ERANGE; + return LONG_MIN; + } + return -(long)mag; + } +} + +long long strtoll(const char *nptr, char **endptr, int base) { + return strtol(nptr, endptr, base); +} + +unsigned long long strtoull(const char *nptr, char **endptr, int base) { + return strtoul(nptr, endptr, base); +} + +long _strtol_clamped(const char *nptr, char **endptr, int base, int min, int max) { + long l = strtol(nptr, endptr, base); + if (l < min) return min; + if (l > max) return max; + return l; +} + +#define _NPOW10 310 +#define _INFINITY 1e1000 +// non-negative floating-point number with more precision than a double +// its value is equal to fraction * 2^exponent +typedef struct { + unsigned long fraction; + int exponent; +} _Float; + +// ensure that f->fraction >= 2^64 / 2 +static void _normalize_float(_Float *f) { + if (!f->fraction) return; + while (f->fraction < 0x8000000000000000) { + f->exponent -= 1; + f->fraction <<= 1; + } +} + +static double _Float_to_double(_Float f) { + unsigned long dbl_fraction; + int dbl_exponent; + unsigned long dbl_value; + if (f.fraction == 0) return 0; + _normalize_float(&f); + f.fraction &= 0x7fffffffffffffff; // remove the "1." in 1.01101110111... to get 63-bit significand + dbl_fraction = (f.fraction + 0x3ff) >> 11; + dbl_exponent = f.exponent + 63; + if (dbl_exponent < -1022) return 0; + if (dbl_exponent > 1023) return _INFINITY; + dbl_exponent += 1023; + dbl_value = (unsigned long)dbl_exponent << 52 | dbl_fraction; + return *(double *)&dbl_value; +} + +static _Float _powers_of_10_dat[2*_NPOW10+1]; +static _Float *_powers_of_10; +static _Float _Float_ZERO = {0, 1}; +static _Float _Float_INFINITY = {0x8000000000000000, 100000}; + + +_Float _int_pow10(int x) { + if (x <= -_NPOW10) return _Float_ZERO; + if (x >= _NPOW10) return _Float_INFINITY; + return _powers_of_10[x]; +} + +double strtod(const char *nptr, char **endptr) { + const char *flt, *dot, *p, *number_end; + double sign = 1; + int exponent = 0; + while (isspace(*nptr)) ++nptr; + + flt = nptr; // start of float + if (*flt == '+') ++flt; + else if (*flt == '-') sign = -1, ++flt; + + if (*flt != '.' && (*flt < '0' || *flt > '9')) { + // this isn't a float + *endptr = nptr; + return 0; + } + + // find the decimal point, if any + dot = flt; + while (*dot >= '0' && *dot <= '9') ++dot; + + nptr = dot + (*dot == '.'); + // skip digits after the dot + while (*nptr >= '0' && *nptr <= '9') ++nptr; + number_end = nptr; + + if (*nptr == 'e') { + ++nptr; + exponent = 1; + if (*nptr == '+') ++nptr; + else if (*nptr == '-') ++nptr, exponent = -1; + exponent *= _strtol_clamped(nptr, &nptr, 10, -10000, 10000); // use _strtol_clamped to prevent problems with -LONG_MIN + } + + // construct the value using the Kahan summation algorithm (https://en.wikipedia.org/wiki/Kahan_summation_algorithm) + double sum = 0; + double c = 0; + for (p = flt; p < number_end; ++p) { + if (*p == '.') continue; + int n = *p - '0'; + assert(n >= 0 && n <= 9); + int pow10 = dot - p; + pow10 -= pow10 > 0; + pow10 += exponent; + _Float f_val = _int_pow10(pow10); + f_val.fraction >>= 4; + f_val.exponent += 4; + f_val.fraction *= n; + double value = _Float_to_double(f_val); + if (value == _INFINITY || sum == _INFINITY) { + sum = _INFINITY; + break; + } + double y = value - c; + double t = sum + y; + c = (t - sum) - y; + sum = t; + } + + if (sum == _INFINITY) errno = ERANGE; + if (endptr) *endptr = nptr; + return sum * sign; +} + +float strtof(const char *nptr, char **endptr) { + return strtod(nptr, endptr); +} + +long double strtold(const char *nptr, char **endptr) { + return strtod(nptr, endptr); +} + +char *strerror(int errnum) { + switch (errnum) { + case ERANGE: return "Range error"; + case EDOM: return "Domain error"; + case EIO: return "I/O error"; + } + return "Other error"; +} + +typedef void (*_ExitHandler)(void); +_ExitHandler _exit_handlers[33]; +int _n_exit_handlers; + +void exit(int status) { + int i; + for (i = _n_exit_handlers - 1; i >= 0; --i) + _exit_handlers[i](); + _Exit(status); +} + +int main(); + +static char **_envp; +static uint64_t _rand_seed; + +int _main(int argc, char **argv) { + int i; + _Float p = {1, 0}; + + _envp = argv + argc + 1; // this is where the environment variables will be + + stdin = &_stdin; + stdout = &_stdout; + stderr = &_stderr; + + /* + "If rand is called before any calls to srand have been made, + the same sequence shall be generated as when srand is first + called with a seed value of 1." C89 § 4.10.2.2 + */ + _rand_seed = 1; + // initialize powers of 10 + _powers_of_10 = _powers_of_10_dat + _NPOW10; + for (i = 0; i < _NPOW10; ++i) { + _normalize_float(&p); + _powers_of_10[i] = p; + p.exponent += 4; + p.fraction >>= 4; + p.fraction *= 10; + } + + p.fraction = 1; + p.exponent = 0; + for (i = 0; i > -_NPOW10; --i) { + _normalize_float(&p); + _powers_of_10[i] = p; + p.fraction /= 5; + p.exponent -= 1; + } + + exit(main(argc, argv)); +} + + +#endif // _STDC_COMMON_H diff --git a/05/tcc-0.9.27/stddef.h b/05/tcc-0.9.27/stddef.h new file mode 100644 index 0000000..f012d95 --- /dev/null +++ b/05/tcc-0.9.27/stddef.h @@ -0,0 +1,8 @@ +#ifndef _STDDEF_H +#define _STDDEF_H + +#include +#define offsetof(struct, member) ((size_t)(&((struct *)NULL)->member)) +// @NONSTANDARD: we don't have wchar_t + +#endif // _STDDEF_H diff --git a/05/tcc-0.9.27/stdio.h b/05/tcc-0.9.27/stdio.h new file mode 100644 index 0000000..436dd62 --- /dev/null +++ b/05/tcc-0.9.27/stdio.h @@ -0,0 +1,2270 @@ +#ifndef _STDIO_H +#define _STDIO_H + +#include +#include + +int printf(const char *, ...); + +/* --- snprintf, adapted from github.com/nothings/stb stb_sprintf.h */ + +#ifndef STB_SPRINTF_MIN +#define STB_SPRINTF_MIN 512 // how many characters per callback +#endif +typedef char *_STBSP_SPRINTFCB(const char *buf, void *user, int len); + +// internal float utility functions +static int32_t _stbsp__real_to_str(char const **start, uint32_t *len, char *out, int32_t *decimal_pos, double value, uint32_t frac_digits); +static int32_t _stbsp__real_to_parts(int64_t *bits, int32_t *expo, double value); +#define STBSP__SPECIAL 0x7000 + +static char _stbsp__period = '.'; +static char _stbsp__comma = ','; +static struct +{ + short temp; // force next field to be 2-byte aligned + char pair[201]; +} _stbsp__digitpair = +{ + 0, + "00010203040506070809101112131415161718192021222324" + "25262728293031323334353637383940414243444546474849" + "50515253545556575859606162636465666768697071727374" + "75767778798081828384858687888990919293949596979899" +}; + +#define STBSP__LEFTJUST 1 +#define STBSP__LEADINGPLUS 2 +#define STBSP__LEADINGSPACE 4 +#define STBSP__LEADING_0X 8 +#define STBSP__LEADINGZERO 16 +#define STBSP__INTMAX 32 +#define STBSP__TRIPLET_COMMA 64 +#define STBSP__NEGATIVE 128 +#define STBSP__METRIC_SUFFIX 256 +#define STBSP__HALFWIDTH 512 +#define STBSP__METRIC_NOSPACE 1024 +#define STBSP__METRIC_1024 2048 +#define STBSP__METRIC_JEDEC 4096 + +static void _stbsp__lead_sign(uint32_t fl, char *sign) +{ + sign[0] = 0; + if (fl & STBSP__NEGATIVE) { + sign[0] = 1; + sign[1] = '-'; + } else if (fl & STBSP__LEADINGSPACE) { + sign[0] = 1; + sign[1] = ' '; + } else if (fl & STBSP__LEADINGPLUS) { + sign[0] = 1; + sign[1] = '+'; + } +} + +static uint32_t _stbsp__strlen_limited(char const *s, uint32_t limit) +{ + char const * sn = s; + + // get up to 4-byte alignment + for (;;) { + if (((uintptr_t)sn & 3) == 0) + break; + + if (!limit || *sn == 0) + return (uint32_t)(sn - s); + + ++sn; + --limit; + } + + // scan over 4 bytes at a time to find terminating 0 + // this will intentionally scan up to 3 bytes past the end of buffers, + // but becase it works 4B aligned, it will never cross page boundaries + // (hence the STBSP__ASAN markup; the over-read here is intentional + // and harmless) + while (limit >= 4) { + uint32_t v = *(uint32_t *)sn; + // bit hack to find if there's a 0 byte in there + if ((v - 0x01010101) & (~v) & 0x80808080UL) + break; + + sn += 4; + limit -= 4; + } + + // handle the last few characters to find actual size + while (limit && *sn) { + ++sn; + --limit; + } + + return (uint32_t)(sn - s); +} + +int __vsprintfcb(_STBSP_SPRINTFCB *callback, void *user, char *buf, char const *fmt, va_list va) +{ + static char hex[] = "0123456789abcdefxp"; + static char hexu[] = "0123456789ABCDEFXP"; + char *bf; + char const *f; + int tlen = 0; + + bf = buf; + f = fmt; + for (;;) { + int32_t fw, pr, tz; + uint32_t fl; + + // macros for the callback buffer stuff + #define stbsp__chk_cb_bufL(bytes) \ + { \ + int len = (int)(bf - buf); \ + if ((len + (bytes)) >= STB_SPRINTF_MIN) { \ + tlen += len; \ + if (0 == (bf = buf = callback(buf, user, len))) \ + goto done; \ + } \ + } + #define stbsp__chk_cb_buf(bytes) \ + { \ + if (callback) { \ + stbsp__chk_cb_bufL(bytes); \ + } \ + } + #define stbsp__flush_cb() \ + { \ + stbsp__chk_cb_bufL(STB_SPRINTF_MIN - 1); \ + } // flush if there is even one byte in the buffer + #define stbsp__cb_buf_clamp(cl, v) \ + cl = v; \ + if (callback) { \ + int lg = STB_SPRINTF_MIN - (int)(bf - buf); \ + if (cl > lg) \ + cl = lg; \ + } + + // fast copy everything up to the next % (or end of string) + for (;;) { + while (((uintptr_t)f) & 3) { + schk1: + if (f[0] == '%') + goto scandd; + schk2: + if (f[0] == 0) + goto endfmt; + stbsp__chk_cb_buf(1); + *bf++ = f[0]; + ++f; + } + for (;;) { + // Check if the next 4 bytes contain %(0x25) or end of string. + // Using the 'hasless' trick: + // https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord + uint32_t v, c; + v = *(uint32_t *)f; + c = (~v) & 0x80808080; + if (((v ^ 0x25252525) - 0x01010101) & c) + goto schk1; + if ((v - 0x01010101) & c) + goto schk2; + if (callback) + if ((STB_SPRINTF_MIN - (int)(bf - buf)) < 4) + goto schk1; + { + *(uint32_t *)bf = v; + } + bf += 4; + f += 4; + } + } + scandd: + + ++f; + + // ok, we have a percent, read the modifiers first + fw = 0; + pr = -1; + fl = 0; + tz = 0; + + // flags + for (;;) { + switch (f[0]) { + // if we have left justify + case '-': + fl |= STBSP__LEFTJUST; + ++f; + continue; + // if we have leading plus + case '+': + fl |= STBSP__LEADINGPLUS; + ++f; + continue; + // if we have leading space + case ' ': + fl |= STBSP__LEADINGSPACE; + ++f; + continue; + // if we have leading 0x + case '#': + fl |= STBSP__LEADING_0X; + ++f; + continue; + // if we have thousand commas + case '\'': + fl |= STBSP__TRIPLET_COMMA; + ++f; + continue; + // if we have kilo marker (none->kilo->kibi->jedec) + case '$': + if (fl & STBSP__METRIC_SUFFIX) { + if (fl & STBSP__METRIC_1024) { + fl |= STBSP__METRIC_JEDEC; + } else { + fl |= STBSP__METRIC_1024; + } + } else { + fl |= STBSP__METRIC_SUFFIX; + } + ++f; + continue; + // if we don't want space between metric suffix and number + case '_': + fl |= STBSP__METRIC_NOSPACE; + ++f; + continue; + // if we have leading zero + case '0': + fl |= STBSP__LEADINGZERO; + ++f; + goto flags_done; + default: goto flags_done; + } + } + flags_done: + + // get the field width + if (f[0] == '*') { + fw = va_arg(va, uint32_t); + ++f; + } else { + while ((f[0] >= '0') && (f[0] <= '9')) { + fw = fw * 10 + f[0] - '0'; + f++; + } + } + // get the precision + if (f[0] == '.') { + ++f; + if (f[0] == '*') { + pr = va_arg(va, uint32_t); + ++f; + } else { + pr = 0; + while ((f[0] >= '0') && (f[0] <= '9')) { + pr = pr * 10 + f[0] - '0'; + f++; + } + } + } + + // handle integer size overrides + switch (f[0]) { + // are we halfwidth? + case 'h': + fl |= STBSP__HALFWIDTH; + ++f; + if (f[0] == 'h') + ++f; // QUARTERWIDTH + break; + // are we 64-bit (unix style) + case 'l': + fl |= ((sizeof(long) == 8) ? STBSP__INTMAX : 0); + ++f; + if (f[0] == 'l') { + fl |= STBSP__INTMAX; + ++f; + } + break; + // are we 64-bit on intmax? (c99) + case 'j': + fl |= (sizeof(size_t) == 8) ? STBSP__INTMAX : 0; + ++f; + break; + // are we 64-bit on size_t or ptrdiff_t? (c99) + case 'z': + fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0; + ++f; + break; + case 't': + fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0; + ++f; + break; + // are we 64-bit (msft style) + case 'I': + if ((f[1] == '6') && (f[2] == '4')) { + fl |= STBSP__INTMAX; + f += 3; + } else if ((f[1] == '3') && (f[2] == '2')) { + f += 3; + } else { + fl |= ((sizeof(void *) == 8) ? STBSP__INTMAX : 0); + ++f; + } + break; + default: break; + } + + // handle each replacement + switch (f[0]) { + #define STBSP__NUMSZ 512 // big enough for e308 (with commas) or e-307 + char num[STBSP__NUMSZ]; + char lead[8]; + char tail[8]; + char *s; + char const *h; + uint32_t l, n, cs; + uint64_t n64; + double fv; + int32_t dp; + char const *sn; + + case 's': + // get the string + s = va_arg(va, char *); + if (s == 0) + s = (char *)"null"; + // get the length, limited to desired precision + // always limit to ~0u chars since our counts are 32b + l = _stbsp__strlen_limited(s, (pr >= 0) ? pr : ~0u); + lead[0] = 0; + tail[0] = 0; + pr = 0; + dp = 0; + cs = 0; + // copy the string in + goto scopy; + + case 'c': // char + // get the character + s = num + STBSP__NUMSZ - 1; + *s = (char)va_arg(va, int); + l = 1; + lead[0] = 0; + tail[0] = 0; + pr = 0; + dp = 0; + cs = 0; + goto scopy; + + case 'n': // weird write-bytes specifier + { + int *d = va_arg(va, int *); + *d = tlen + (int)(bf - buf); + } break; + + case 'A': // hex float + case 'a': // hex float + h = (f[0] == 'A') ? hexu : hex; + fv = va_arg(va, double); + if (pr == -1) + pr = 6; // default is 6 + // read the double into a string + if (_stbsp__real_to_parts((int64_t *)&n64, &dp, fv)) + fl |= STBSP__NEGATIVE; + + s = num + 64; + + _stbsp__lead_sign(fl, lead); + + if (dp == -1023) + dp = (n64) ? -1022 : 0; + else + n64 |= (((uint64_t)1) << 52); + n64 <<= (64 - 56); + if (pr < 15) + n64 += ((((uint64_t)8) << 56) >> (pr * 4)); +// add leading chars + lead[1 + lead[0]] = '0'; + lead[2 + lead[0]] = 'x'; + lead[0] += 2; + *s++ = h[(n64 >> 60) & 15]; + n64 <<= 4; + if (pr) + *s++ = _stbsp__period; + sn = s; + + // print the bits + n = pr; + if (n > 13) + n = 13; + if (pr > (int32_t)n) + tz = pr - n; + pr = 0; + while (n--) { + *s++ = h[(n64 >> 60) & 15]; + n64 <<= 4; + } + + // print the expo + tail[1] = h[17]; + if (dp < 0) { + tail[2] = '-'; + dp = -dp; + } else + tail[2] = '+'; + n = (dp >= 1000) ? 6 : ((dp >= 100) ? 5 : ((dp >= 10) ? 4 : 3)); + tail[0] = (char)n; + for (;;) { + tail[n] = '0' + dp % 10; + if (n <= 3) + break; + --n; + dp /= 10; + } + + dp = (int)(s - sn); + l = (int)(s - (num + 64)); + s = num + 64; + cs = 1 + (3 << 24); + goto scopy; + + case 'G': // float + case 'g': // float + h = (f[0] == 'G') ? hexu : hex; + fv = va_arg(va, double); + if (pr == -1) + pr = 6; + else if (pr == 0) + pr = 1; // default is 6 + // read the double into a string + if (_stbsp__real_to_str(&sn, &l, num, &dp, fv, (pr - 1) | 0x80000000)) + fl |= STBSP__NEGATIVE; + + // clamp the precision and delete extra zeros after clamp + n = pr; + if (l > (uint32_t)pr) + l = pr; + while ((l > 1) && (pr) && (sn[l - 1] == '0')) { + --pr; + --l; + } + + // should we use %e + if ((dp <= -4) || (dp > (int32_t)n)) { + if (pr > (int32_t)l) + pr = l - 1; + else if (pr) + --pr; // when using %e, there is one digit before the decimal + goto doexpfromg; + } + // this is the insane action to get the pr to match %g semantics for %f + if (dp > 0) { + pr = (dp < (int32_t)l) ? l - dp : 0; + } else { + pr = -dp + ((pr > (int32_t)l) ? (int32_t) l : pr); + } + goto dofloatfromg; + + case 'E': // float + case 'e': // float + h = (f[0] == 'E') ? hexu : hex; + fv = va_arg(va, double); + if (pr == -1) + pr = 6; // default is 6 + // read the double into a string + if (_stbsp__real_to_str(&sn, &l, num, &dp, fv, pr | 0x80000000)) + fl |= STBSP__NEGATIVE; + doexpfromg: + tail[0] = 0; + _stbsp__lead_sign(fl, lead); + if (dp == STBSP__SPECIAL) { + s = (char *)sn; + cs = 0; + pr = 0; + goto scopy; + } + s = num + 64; + // handle leading chars + *s++ = sn[0]; + + if (pr) + *s++ = _stbsp__period; + + // handle after decimal + if ((l - 1) > (uint32_t)pr) + l = pr + 1; + for (n = 1; n < l; n++) + *s++ = sn[n]; + // trailing zeros + tz = pr - (l - 1); + pr = 0; + // dump expo + tail[1] = h[0xe]; + dp -= 1; + if (dp < 0) { + tail[2] = '-'; + dp = -dp; + } else + tail[2] = '+'; + n = (dp >= 100) ? 5 : 4; + tail[0] = (char)n; + for (;;) { + tail[n] = '0' + dp % 10; + if (n <= 3) + break; + --n; + dp /= 10; + } + cs = 1 + (3 << 24); // how many tens + goto flt_lead; + + case 'f': // float + fv = va_arg(va, double); + doafloat: + // do kilos + if (fl & STBSP__METRIC_SUFFIX) { + double divisor; + divisor = 1000.0f; + if (fl & STBSP__METRIC_1024) + divisor = 1024.0; + while (fl < 0x4000000) { + if ((fv < divisor) && (fv > -divisor)) + break; + fv /= divisor; + fl += 0x1000000; + } + } + if (pr == -1) + pr = 6; // default is 6 + // read the double into a string + if (_stbsp__real_to_str(&sn, &l, num, &dp, fv, pr)) + fl |= STBSP__NEGATIVE; + dofloatfromg: + tail[0] = 0; + _stbsp__lead_sign(fl, lead); + if (dp == STBSP__SPECIAL) { + s = (char *)sn; + cs = 0; + pr = 0; + goto scopy; + } + s = num + 64; + + // handle the three decimal varieties + if (dp <= 0) { + int32_t i; + // handle 0.000*000xxxx + *s++ = '0'; + if (pr) + *s++ = _stbsp__period; + n = -dp; + if ((int32_t)n > pr) + n = pr; + i = n; + while (i) { + if ((((uintptr_t)s) & 3) == 0) + break; + *s++ = '0'; + --i; + } + while (i >= 4) { + *(uint32_t *)s = 0x30303030; + s += 4; + i -= 4; + } + while (i) { + *s++ = '0'; + --i; + } + if ((int32_t)(l + n) > pr) + l = pr - n; + i = l; + while (i) { + *s++ = *sn++; + --i; + } + tz = pr - (n + l); + cs = 1 + (3 << 24); // how many tens did we write (for commas below) + } else { + cs = (fl & STBSP__TRIPLET_COMMA) ? ((600 - (uint32_t)dp) % 3) : 0; + if ((uint32_t)dp >= l) { + // handle xxxx000*000.0 + n = 0; + for (;;) { + if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { + cs = 0; + *s++ = _stbsp__comma; + } else { + *s++ = sn[n]; + ++n; + if (n >= l) + break; + } + } + if (n < (uint32_t)dp) { + n = dp - n; + if ((fl & STBSP__TRIPLET_COMMA) == 0) { + while (n) { + if ((((uintptr_t)s) & 3) == 0) + break; + *s++ = '0'; + --n; + } + while (n >= 4) { + *(uint32_t *)s = 0x30303030; + s += 4; + n -= 4; + } + } + while (n) { + if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { + cs = 0; + *s++ = _stbsp__comma; + } else { + *s++ = '0'; + --n; + } + } + } + cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens + if (pr) { + *s++ = _stbsp__period; + tz = pr; + } + } else { + // handle xxxxx.xxxx000*000 + n = 0; + for (;;) { + if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { + cs = 0; + *s++ = _stbsp__comma; + } else { + *s++ = sn[n]; + ++n; + if (n >= (uint32_t)dp) + break; + } + } + cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens + if (pr) + *s++ = _stbsp__period; + if ((l - dp) > (uint32_t)pr) + l = pr + dp; + while (n < l) { + *s++ = sn[n]; + ++n; + } + tz = pr - (l - dp); + } + } + pr = 0; + + // handle k,m,g,t + if (fl & STBSP__METRIC_SUFFIX) { + char idx; + idx = 1; + if (fl & STBSP__METRIC_NOSPACE) + idx = 0; + tail[0] = idx; + tail[1] = ' '; + { + if (fl >> 24) { // SI kilo is 'k', JEDEC and SI kibits are 'K'. + if (fl & STBSP__METRIC_1024) + tail[idx + 1] = "_KMGT"[fl >> 24]; + else + tail[idx + 1] = "_kMGT"[fl >> 24]; + idx++; + // If printing kibits and not in jedec, add the 'i'. + if (fl & STBSP__METRIC_1024 && !(fl & STBSP__METRIC_JEDEC)) { + tail[idx + 1] = 'i'; + idx++; + } + tail[0] = idx; + } + } + }; + + flt_lead: + // get the length that we copied + l = (uint32_t)(s - (num + 64)); + s = num + 64; + goto scopy; + + case 'B': // upper binary + case 'b': // lower binary + h = (f[0] == 'B') ? hexu : hex; + lead[0] = 0; + if (fl & STBSP__LEADING_0X) { + lead[0] = 2; + lead[1] = '0'; + lead[2] = h[0xb]; + } + l = (8 << 4) | (1 << 8); + goto radixnum; + + case 'o': // octal + h = hexu; + lead[0] = 0; + if (fl & STBSP__LEADING_0X) { + lead[0] = 1; + lead[1] = '0'; + } + l = (3 << 4) | (3 << 8); + goto radixnum; + + case 'p': // pointer + fl |= (sizeof(void *) == 8) ? STBSP__INTMAX : 0; + pr = sizeof(void *) * 2; + fl &= ~STBSP__LEADINGZERO; // 'p' only prints the pointer with zeros + // fall through - to X + + case 'X': // upper hex + case 'x': // lower hex + h = (f[0] == 'X') ? hexu : hex; + l = (4 << 4) | (4 << 8); + lead[0] = 0; + if (fl & STBSP__LEADING_0X) { + lead[0] = 2; + lead[1] = '0'; + lead[2] = h[16]; + } + radixnum: + // get the number + if (fl & STBSP__INTMAX) + n64 = va_arg(va, uint64_t); + else + n64 = va_arg(va, uint32_t); + + s = num + STBSP__NUMSZ; + dp = 0; + // clear tail, and clear leading if value is zero + tail[0] = 0; + if (n64 == 0) { + lead[0] = 0; + if (pr == 0) { + l = 0; + cs = 0; + goto scopy; + } + } + // convert to string + for (;;) { + *--s = h[n64 & ((1 << (l >> 8)) - 1)]; + n64 >>= (l >> 8); + if (!((n64) || ((int32_t)((num + STBSP__NUMSZ) - s) < pr))) + break; + if (fl & STBSP__TRIPLET_COMMA) { + ++l; + if ((l & 15) == ((l >> 4) & 15)) { + l &= ~15; + *--s = _stbsp__comma; + } + } + }; + // get the tens and the comma pos + cs = (uint32_t)((num + STBSP__NUMSZ) - s) + ((((l >> 4) & 15)) << 24); + // get the length that we copied + l = (uint32_t)((num + STBSP__NUMSZ) - s); + // copy it + goto scopy; + + case 'u': // unsigned + case 'i': + case 'd': // integer + // get the integer and abs it + if (fl & STBSP__INTMAX) { + int64_t i64 = va_arg(va, int64_t); + n64 = (uint64_t)i64; + if ((f[0] != 'u') && (i64 < 0)) { + n64 = (uint64_t)-i64; + fl |= STBSP__NEGATIVE; + } + } else { + int32_t i = va_arg(va, int32_t); + n64 = (uint32_t)i; + if ((f[0] != 'u') && (i < 0)) { + n64 = (uint32_t)-i; + fl |= STBSP__NEGATIVE; + } + } + + if (fl & STBSP__METRIC_SUFFIX) { + if (n64 < 1024) + pr = 0; + else if (pr == -1) + pr = 1; + fv = (double)(int64_t)n64; + goto doafloat; + } + + // convert to string + s = num + STBSP__NUMSZ; + l = 0; + + for (;;) { + // do in 32-bit chunks (avoid lots of 64-bit divides even with constant denominators) + char *o = s - 8; + if (n64 >= 100000000) { + n = (uint32_t)(n64 % 100000000); + n64 /= 100000000; + } else { + n = (uint32_t)n64; + n64 = 0; + } + if ((fl & STBSP__TRIPLET_COMMA) == 0) { + do { + s -= 2; + *(uint16_t *)s = *(uint16_t *)&_stbsp__digitpair.pair[(n % 100) * 2]; + n /= 100; + } while (n); + } + while (n) { + if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) { + l = 0; + *--s = _stbsp__comma; + --o; + } else { + *--s = (char)(n % 10) + '0'; + n /= 10; + } + } + if (n64 == 0) { + if ((s[0] == '0') && (s != (num + STBSP__NUMSZ))) + ++s; + break; + } + while (s != o) + if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) { + l = 0; + *--s = _stbsp__comma; + --o; + } else { + *--s = '0'; + } + } + + tail[0] = 0; + _stbsp__lead_sign(fl, lead); + + // get the length that we copied + l = (uint32_t)((num + STBSP__NUMSZ) - s); + if (l == 0) { + *--s = '0'; + l = 1; + } + cs = l + (3 << 24); + if (pr < 0) + pr = 0; + + scopy: + // get fw=leading/trailing space, pr=leading zeros + if (pr < (int32_t)l) + pr = l; + n = pr + lead[0] + tail[0] + tz; + if (fw < (int32_t)n) + fw = n; + fw -= n; + pr -= l; + + // handle right justify and leading zeros + if ((fl & STBSP__LEFTJUST) == 0) { + if (fl & STBSP__LEADINGZERO) // if leading zeros, everything is in pr + { + pr = (fw > pr) ? fw : pr; + fw = 0; + } else { + fl &= ~STBSP__TRIPLET_COMMA; // if no leading zeros, then no commas + } + } + + // copy the spaces and/or zeros + if (fw + pr) { + int32_t i; + uint32_t c; + + // copy leading spaces (or when doing %8.4d stuff) + if ((fl & STBSP__LEFTJUST) == 0) + while (fw > 0) { + stbsp__cb_buf_clamp(i, fw); + fw -= i; + while (i) { + if ((((uintptr_t)bf) & 3) == 0) + break; + *bf++ = ' '; + --i; + } + while (i >= 4) { + *(uint32_t *)bf = 0x20202020; + bf += 4; + i -= 4; + } + while (i) { + *bf++ = ' '; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy leader + sn = lead + 1; + while (lead[0]) { + stbsp__cb_buf_clamp(i, lead[0]); + lead[0] -= (char)i; + while (i) { + *bf++ = *sn++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy leading zeros + c = cs >> 24; + cs &= 0xffffff; + cs = (fl & STBSP__TRIPLET_COMMA) ? ((uint32_t)(c - ((pr + cs) % (c + 1)))) : 0; + while (pr > 0) { + stbsp__cb_buf_clamp(i, pr); + pr -= i; + if ((fl & STBSP__TRIPLET_COMMA) == 0) { + while (i) { + if ((((uintptr_t)bf) & 3) == 0) + break; + *bf++ = '0'; + --i; + } + while (i >= 4) { + *(uint32_t *)bf = 0x30303030; + bf += 4; + i -= 4; + } + } + while (i) { + if ((fl & STBSP__TRIPLET_COMMA) && (cs++ == c)) { + cs = 0; + *bf++ = _stbsp__comma; + } else + *bf++ = '0'; + --i; + } + stbsp__chk_cb_buf(1); + } + } + + // copy leader if there is still one + sn = lead + 1; + while (lead[0]) { + int32_t i; + stbsp__cb_buf_clamp(i, lead[0]); + lead[0] -= (char)i; + while (i) { + *bf++ = *sn++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy the string + n = l; + while (n) { + int32_t i; + stbsp__cb_buf_clamp(i, n); + n -= i; + while (i >= 4) { + *(uint32_t volatile *)bf = *(uint32_t volatile *)s; + bf += 4; + s += 4; + i -= 4; + } + while (i) { + *bf++ = *s++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy trailing zeros + while (tz) { + int32_t i; + stbsp__cb_buf_clamp(i, tz); + tz -= i; + while (i) { + if ((((uintptr_t)bf) & 3) == 0) + break; + *bf++ = '0'; + --i; + } + while (i >= 4) { + *(uint32_t *)bf = 0x30303030; + bf += 4; + i -= 4; + } + while (i) { + *bf++ = '0'; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy tail if there is one + sn = tail + 1; + while (tail[0]) { + int32_t i; + stbsp__cb_buf_clamp(i, tail[0]); + tail[0] -= (char)i; + while (i) { + *bf++ = *sn++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // handle the left justify + if (fl & STBSP__LEFTJUST) + if (fw > 0) { + while (fw) { + int32_t i; + stbsp__cb_buf_clamp(i, fw); + fw -= i; + while (i) { + if ((((uintptr_t)bf) & 3) == 0) + break; + *bf++ = ' '; + --i; + } + while (i >= 4) { + *(uint32_t *)bf = 0x20202020; + bf += 4; + i -= 4; + } + while (i--) + *bf++ = ' '; + stbsp__chk_cb_buf(1); + } + } + break; + + default: // unknown, just copy code + s = num + STBSP__NUMSZ - 1; + *s = f[0]; + l = 1; + fw = fl = 0; + lead[0] = 0; + tail[0] = 0; + pr = 0; + dp = 0; + cs = 0; + goto scopy; + } + ++f; + } +endfmt: + + if (!callback) + *bf = 0; + else + stbsp__flush_cb(); + +done: + return tlen + (int)(bf - buf); +} + +// cleanup +#undef STBSP__LEFTJUST +#undef STBSP__LEADINGPLUS +#undef STBSP__LEADINGSPACE +#undef STBSP__LEADING_0X +#undef STBSP__LEADINGZERO +#undef STBSP__INTMAX +#undef STBSP__TRIPLET_COMMA +#undef STBSP__NEGATIVE +#undef STBSP__METRIC_SUFFIX +#undef STBSP__NUMSZ +#undef stbsp__chk_cb_bufL +#undef stbsp__chk_cb_buf +#undef stbsp__flush_cb +#undef stbsp__cb_buf_clamp + +// ============================================================================ +// wrapper functions + +int sprintf(char *buf, char const *fmt, ...) +{ + int result; + va_list va; + va_start(va, fmt); + result = __vsprintfcb(0, 0, buf, fmt, va); + va_end(va); + return result; +} + +typedef struct stbsp__context { + char *buf; + int count; + int length; + char tmp[STB_SPRINTF_MIN]; +} stbsp__context; + +static char *stbsp__clamp_callback(const char *buf, void *user, int len) +{ + stbsp__context *c = (stbsp__context *)user; + + c->length += len; + + if (len > c->count) + len = c->count; + + if (len) { + if (buf != c->buf) { + const char *s, *se; + char *d; + d = c->buf; + s = buf; + se = buf + len; + do { + *d++ = *s++; + } while (s < se); + } + c->buf += len; + c->count -= len; + } + + if (c->count <= 0) + return c->tmp; + return (c->count >= STB_SPRINTF_MIN) ? c->buf : c->tmp; // go direct into buffer if you can +} + +char * stbsp__count_clamp_callback( const char * buf, void * user, int len ) +{ + stbsp__context * c = (stbsp__context*)user; + (void) sizeof(buf); + + c->length += len; + return c->tmp; // go direct into buffer if you can +} + +int vsnprintf( char * buf, int count, char const * fmt, va_list va ) +{ + stbsp__context c; + if ( (count == 0) && !buf ) + { + c.length = 0; + + __vsprintfcb( stbsp__count_clamp_callback, &c, c.tmp, fmt, va ); + } + else + { + int l; + + c.buf = buf; + c.count = count; + c.length = 0; + + __vsprintfcb( stbsp__clamp_callback, &c, stbsp__clamp_callback(0,&c,0), fmt, va ); + + // zero-terminate + l = (int)( c.buf - buf ); + if ( l >= count ) // should never be greater, only equal (or less) than count + l = count - 1; + buf[l] = 0; + } + + return c.length; +} + +int snprintf(char *buf, int count, char const *fmt, ...) +{ + int result; + va_list va; + va_start(va, fmt); + + result = vsnprintf(buf, count, fmt, va); + va_end(va); + + return result; +} + +int vsprintf(char *buf, char const *fmt, va_list va) +{ + return __vsprintfcb(0, 0, buf, fmt, va); +} + +// ======================================================================= +// low level float utility functions + +// copies d to bits w/ strict aliasing (this compiles to nothing on /Ox) +#define STBSP__COPYFP(dest, src) { *(long *)&dest = *(long *)&src; } +/* + \ + { \ + int cn; \ + for (cn = 0; cn < 8; cn++) \ + ((char *)&dest)[cn] = ((char *)&src)[cn]; \ + } +*/ + +// get float info +int32_t _stbsp__real_to_parts(int64_t *bits, int32_t *expo, double value) +{ + double d; + int64_t b = 0; + + // load value and round at the frac_digits + d = value; + + STBSP__COPYFP(b, d); + + *bits = b & ((((uint64_t)1) << 52) - 1); + *expo = (int32_t)(((b >> 52) & 2047) - 1023); + + return (int32_t)((uint64_t) b >> 63); +} + +static double const stbsp__bot[23] = { + 1e+000, 1e+001, 1e+002, 1e+003, 1e+004, 1e+005, 1e+006, 1e+007, 1e+008, 1e+009, 1e+010, 1e+011, + 1e+012, 1e+013, 1e+014, 1e+015, 1e+016, 1e+017, 1e+018, 1e+019, 1e+020, 1e+021, 1e+022 +}; +static double const stbsp__negbot[22] = { + 1e-001, 1e-002, 1e-003, 1e-004, 1e-005, 1e-006, 1e-007, 1e-008, 1e-009, 1e-010, 1e-011, + 1e-012, 1e-013, 1e-014, 1e-015, 1e-016, 1e-017, 1e-018, 1e-019, 1e-020, 1e-021, 1e-022 +}; +static double const stbsp__negboterr[22] = { + -5.551115123125783e-018, -2.0816681711721684e-019, -2.0816681711721686e-020, -4.7921736023859299e-021, -8.1803053914031305e-022, 4.5251888174113741e-023, + 4.5251888174113739e-024, -2.0922560830128471e-025, -6.2281591457779853e-026, -3.6432197315497743e-027, 6.0503030718060191e-028, 2.0113352370744385e-029, + -3.0373745563400371e-030, 1.1806906454401013e-032, -7.7705399876661076e-032, 2.0902213275965398e-033, -7.1542424054621921e-034, -7.1542424054621926e-035, + 2.4754073164739869e-036, 5.4846728545790429e-037, 9.2462547772103625e-038, -4.8596774326570872e-039 +}; +static double const stbsp__top[13] = { + 1e+023, 1e+046, 1e+069, 1e+092, 1e+115, 1e+138, 1e+161, 1e+184, 1e+207, 1e+230, 1e+253, 1e+276, 1e+299 +}; +static double const stbsp__negtop[13] = { + 1e-023, 1e-046, 1e-069, 1e-092, 1e-115, 1e-138, 1e-161, 1e-184, 1e-207, 1e-230, 1e-253, 1e-276, 1e-299 +}; +static double const stbsp__toperr[13] = { + 8388608., + 6.8601809640529717e+028, + -7.253143638152921e+052, + -4.3377296974619174e+075, + -1.5559416129466825e+098, + -3.2841562489204913e+121, + -3.7745893248228135e+144, + -1.7356668416969134e+167, + -3.8893577551088374e+190, + -9.9566444326005119e+213, + 6.3641293062232429e+236, + -5.2069140800249813e+259, + -5.2504760255204387e+282 +}; +static double const stbsp__negtoperr[13] = { + 3.9565301985100693e-040, -2.299904345391321e-063, 3.6506201437945798e-086, 1.1875228833981544e-109, + -5.0644902316928607e-132, -6.7156837247865426e-155, -2.812077463003139e-178, -5.7778912386589953e-201, + 7.4997100559334532e-224, -4.6439668915134491e-247, -6.3691100762962136e-270, -9.436808465446358e-293, + 8.0970921678014997e-317 +}; + +static uint64_t const stbsp__powten[20] = { + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000ULL, + 100000000000ULL, + 1000000000000ULL, + 10000000000000ULL, + 100000000000000ULL, + 1000000000000000ULL, + 10000000000000000ULL, + 100000000000000000ULL, + 1000000000000000000ULL, + 10000000000000000000ULL +}; +#define stbsp__tento19th (1000000000000000000ULL) + +#define stbsp__ddmulthi(oh, ol, xh, yh) \ + { \ + double ahi = 0, alo, bhi = 0, blo; \ + int64_t bt; \ + oh = xh * yh; \ + STBSP__COPYFP(bt, xh); \ + bt &= ((~(uint64_t)0) << 27); \ + STBSP__COPYFP(ahi, bt); \ + alo = xh - ahi; \ + STBSP__COPYFP(bt, yh); \ + bt &= ((~(uint64_t)0) << 27); \ + STBSP__COPYFP(bhi, bt); \ + blo = yh - bhi; \ + ol = ((ahi * bhi - oh) + ahi * blo + alo * bhi) + alo * blo; \ + } + +#define stbsp__ddtoS64(ob, xh, xl) \ + { \ + double ahi = 0, alo, vh, t; \ + ob = (int64_t)xh; \ + vh = (double)ob; \ + ahi = (xh - vh); \ + t = (ahi - xh); \ + alo = (xh - (ahi - t)) - (vh + t); \ + ob += (int64_t)(ahi + alo + xl); \ + } + +#define stbsp__ddrenorm(oh, ol) \ + { \ + double s; \ + s = oh + ol; \ + ol = ol - (s - oh); \ + oh = s; \ + } + +#define stbsp__ddmultlo(oh, ol, xh, xl, yh, yl) ol = ol + (xh * yl + xl * yh); + +#define stbsp__ddmultlos(oh, ol, xh, yl) ol = ol + (xh * yl); + +static void stbsp__raise_to_power10(double *ohi, double *olo, double d, int32_t power) // power can be -323 to +350 +{ + double ph, pl; + if ((power >= 0) && (power <= 22)) { + stbsp__ddmulthi(ph, pl, d, stbsp__bot[power]); + } else { + int32_t e, et, eb; + double p2h, p2l; + + e = power; + if (power < 0) + e = -e; + et = (e * 0x2c9) >> 14; /* %23 */ + if (et > 13) + et = 13; + eb = e - (et * 23); + + ph = d; + pl = 0.0; + if (power < 0) { + if (eb) { + --eb; + stbsp__ddmulthi(ph, pl, d, stbsp__negbot[eb]); + stbsp__ddmultlos(ph, pl, d, stbsp__negboterr[eb]); + } + if (et) { + stbsp__ddrenorm(ph, pl); + --et; + stbsp__ddmulthi(p2h, p2l, ph, stbsp__negtop[et]); + stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__negtop[et], stbsp__negtoperr[et]); + ph = p2h; + pl = p2l; + } + } else { + if (eb) { + e = eb; + if (eb > 22) + eb = 22; + e -= eb; + stbsp__ddmulthi(ph, pl, d, stbsp__bot[eb]); + if (e) { + stbsp__ddrenorm(ph, pl); + stbsp__ddmulthi(p2h, p2l, ph, stbsp__bot[e]); + stbsp__ddmultlos(p2h, p2l, stbsp__bot[e], pl); + ph = p2h; + pl = p2l; + } + } + if (et) { + stbsp__ddrenorm(ph, pl); + --et; + stbsp__ddmulthi(p2h, p2l, ph, stbsp__top[et]); + stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__top[et], stbsp__toperr[et]); + ph = p2h; + pl = p2l; + } + } + } + stbsp__ddrenorm(ph, pl); + *ohi = ph; + *olo = pl; +} + +// given a float value, returns the significant bits in bits, and the position of the +// decimal point in decimal_pos. +/-INF and NAN are specified by special values +// returned in the decimal_pos parameter. +// frac_digits is absolute normally, but if you want from first significant digits (got %g and %e), or in 0x80000000 +static int32_t _stbsp__real_to_str(char const **start, uint32_t *len, char *out, int32_t *decimal_pos, double value, uint32_t frac_digits) +{ + double d; + int64_t bits = 0; + int32_t expo, e, ng, tens; + + d = value; + STBSP__COPYFP(bits, d); + expo = (int32_t)((bits >> 52) & 2047); + ng = (int32_t)((uint64_t) bits >> 63); + if (ng) + d = -d; + + if (expo == 2047) // is nan or inf? + { + *start = (bits & ((((uint64_t)1) << 52) - 1)) ? "NaN" : "Inf"; + *decimal_pos = STBSP__SPECIAL; + *len = 3; + return ng; + } + + if (expo == 0) // is zero or denormal + { + if (((uint64_t) bits << 1) == 0) // do zero + { + *decimal_pos = 1; + *start = out; + out[0] = '0'; + *len = 1; + return ng; + } + // find the right expo for denormals + { + int64_t v = ((uint64_t)1) << 51; + while ((bits & v) == 0) { + --expo; + v >>= 1; + } + } + } + + // find the decimal exponent as well as the decimal bits of the value + { + double ph, pl; + + // log10 estimate - very specifically tweaked to hit or undershoot by no more than 1 of log10 of all expos 1..2046 + tens = expo - 1023; + tens = (tens < 0) ? ((tens * 617) / 2048) : (((tens * 1233) / 4096) + 1); + + // move the significant bits into position and stick them into an int + stbsp__raise_to_power10(&ph, &pl, d, 18 - tens); + + // get full as much precision from double-double as possible + stbsp__ddtoS64(bits, ph, pl); + + // check if we undershot + if (((uint64_t)bits) >= stbsp__tento19th) + ++tens; + } + + // now do the rounding in integer land + frac_digits = (frac_digits & 0x80000000) ? ((frac_digits & 0x7ffffff) + 1) : (tens + frac_digits); + if ((frac_digits < 24)) { + uint32_t dg = 1; + if ((uint64_t)bits >= stbsp__powten[9]) + dg = 10; + while ((uint64_t)bits >= stbsp__powten[dg]) { + ++dg; + if (dg == 20) + goto noround; + } + if (frac_digits < dg) { + uint64_t r; + // add 0.5 at the right position and round + e = dg - frac_digits; + if ((uint32_t)e >= 24) + goto noround; + r = stbsp__powten[e]; + bits = bits + (r / 2); + if ((uint64_t)bits >= stbsp__powten[dg]) + ++tens; + bits /= r; + } + noround:; + } + + // kill long trailing runs of zeros + if (bits) { + uint32_t n; + for (;;) { + if (bits <= 0xffffffff) + break; + if (bits % 1000) + goto donez; + bits /= 1000; + } + n = (uint32_t)bits; + while ((n % 1000) == 0) + n /= 1000; + bits = n; + donez:; + } + + // convert to string + out += 64; + e = 0; + for (;;) { + uint32_t n; + char *o = out - 8; + // do the conversion in chunks of U32s (avoid most 64-bit divides, worth it, constant denomiators be damned) + if (bits >= 100000000) { + n = (uint32_t)(bits % 100000000); + bits /= 100000000; + } else { + n = (uint32_t)bits; + bits = 0; + } + while (n) { + out -= 2; + *(uint16_t *)out = *(uint16_t *)&_stbsp__digitpair.pair[(n % 100) * 2]; + n /= 100; + e += 2; + } + if (bits == 0) { + if ((e) && (out[0] == '0')) { + ++out; + --e; + } + break; + } + while (out != o) { + *--out = '0'; + ++e; + } + } + + *decimal_pos = tens; + *start = out; + *len = e; + return ng; +} + +#undef stbsp__ddmulthi +#undef stbsp__ddrenorm +#undef stbsp__ddmultlo +#undef stbsp__ddmultlos +#undef STBSP__SPECIAL +#undef STBSP__COPYFP + +// these are the constants that gnu uses, but they don't really matter for us +#define _IOFBF 0 +#define _IOLBF 1 +#define _IONBF 2 +#define BUFSIZ 8192 + + +#define EOF (-1) +#define FILENAME_MAX 4096 +#define FOPEN_MAX 16 +typedef long fpos_t; +#define L_tmpnam 20 +#define SEEK_CUR 1 +#define SEEK_END 2 +#define SEEK_SET 0 +#define TMP_MAX 500 + +long lseek(int fd, long offset, int whence) { + return __syscall(8, fd, offset, whence, 0, 0, 0); +} + +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { + size_t count; + if (nmemb > 0xffffffffffffffff / size) { + stream->err = 1; + return 0; + } + count = size * nmemb; + while (count > 0) { + long n = write(stream->fd, ptr, count); + if (n <= 0) break; + count -= n; + ptr = (char *)ptr + n; + } + if (count > 0) stream->err = 1; + return nmemb - count / size; +} + +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { + size_t count; + long n = 1; + if (nmemb > 0xffffffffffffffff / size) { + stream->err = 1; + return 0; + } + if (size == 0 || nmemb == 0) return 0; + + count = size * nmemb; + + if (stream->has_ungetc) { + *(char *)ptr = stream->ungetc; + stream->has_ungetc = 0; + ptr = (char *)ptr + 1; + --count; + } + if (stream->eof) return 0; + + while (count > 0) { + n = read(stream->fd, ptr, count); + if (n <= 0) break; + count -= n; + ptr = (char *)ptr + n; + } + if (n == 0) stream->eof = 1; + if (n < 0) stream->err = 1; + return nmemb - count / size; +} + +static char *__fprintf_callback(const char *buf, void *user, int len) { + FILE *fp = user; + fwrite(buf, 1, len, fp); + return buf; +} + +int vfprintf(FILE *fp, const char *fmt, va_list args) { + char buf[STB_SPRINTF_MIN]; + return __vsprintfcb(__fprintf_callback, fp, buf, fmt, args); +} + +int fprintf(FILE *fp, const char *fmt, ...) { + va_list args; + int ret; + va_start(args, fmt); + ret = vfprintf(fp, fmt, args); + va_end(args); + return ret; +} + +int vprintf(const char *fmt, va_list args) { + return vfprintf(stdout, fmt, args); +} + +int printf(const char *fmt, ...) { + va_list args; + int ret; + va_start(args, fmt); + ret = vfprintf(stdout, fmt, args); + va_end(args); + return ret; +} + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 +#define O_CREAT 0100 +#define O_TRUNC 01000 +#define O_APPEND 02000 +#define O_DIRECTORY 0200000 +#define __O_TMPFILE 020000000 +#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) +int open(const char *path, int flags, int mode) { + return __syscall(2, path, flags, mode, 0, 0, 0); +} + +int close(int fd) { + return __syscall(3, fd, 0, 0, 0, 0, 0); +} + + +int _fopen_flags_from_mode(const char *mode) { + int flags; + if (mode[1] == '+' || (mode[1] && mode[2] == '+')) { + // open for updating + flags = O_RDWR; + switch (mode[0]) { + case 'r': break; + case 'w': flags |= O_TRUNC | O_CREAT; break; + case 'a': flags |= O_APPEND | O_CREAT; break; + default: return -1; + } + } else { + switch (mode[0]) { + case 'r': flags = O_RDONLY; break; + case 'w': flags = O_WRONLY | O_TRUNC | O_CREAT; break; + case 'a': flags = O_WRONLY | O_APPEND | O_CREAT; break; + default: return -1; + } + } + return flags; +} + +FILE *_FILE_from_fd(int fd) { + FILE *fp = malloc(sizeof(FILE)); + // NB: our malloc implementation returns zeroed memory + fp->fd = fd; + return fp; +} + +FILE *fopen(const char *filename, const char *mode) { + int flags = _fopen_flags_from_mode(mode); + if (flags < 0) return NULL; + int fd; + + fd = open(filename, flags, 0644); + if (fd < 0) return NULL; + return _FILE_from_fd(fd); +} + + +FILE *fdopen(int fd, const char *mode) { + // mode doesn't matter, hopefully + return _FILE_from_fd(fd); +} + +int fclose(FILE *stream) { + int ret = close(stream->fd); + free(stream); + return ret; +} + +int fflush(FILE *stream) { + // we don't buffer anything + return 0; +} + +FILE *freopen(const char *filename, const char *mode, FILE *stream) { + int flags = _fopen_flags_from_mode(mode); + close(stream->fd); + if (flags < 0) return NULL; + stream->eof = stream->err = 0; + stream->fd = open(filename, flags, 0644); + return stream; +} + +int unlink(const char *pathname) { + return __syscall(87, pathname, 0, 0, 0, 0, 0); +} + +int rmdir(const char *pathname) { + return __syscall(84, pathname, 0, 0, 0, 0, 0); +} + +int remove(const char *filename) { + return rmdir(filename) + ? unlink(filename) + : 0; +} + +int rename(const char *old, const char *new) { + return __syscall(82, old, new, 0, 0, 0, 0); +} + +char *tmpnam(char *s) { + struct timespec t = {0}; + do { + // NB: we can't use rand() here because + // "The implementation shall behave as if no library function calls the rand function." C89 § 4.10.2.1 + clock_gettime(CLOCK_MONOTONIC, &t); // use clock as a source of randomness + sprintf(s, "/tmp/C_%06u", t.tv_nsec % 1000000); + } while (access(s, F_OK) == 0); // if file exists, generate a new name + return s; +} + +FILE *tmpfile(void) { + int fd = open("/tmp", O_TMPFILE | O_RDWR, 0600); + if (fd < 0) return NULL; + return _FILE_from_fd(fd); +} + +int getc(FILE *stream) { + unsigned char c; + long n; + if (stream->eof) return EOF; + n = fread(&c, 1, 1, stream); + if (n != 1) return EOF; + return c; +} + +int fgetc(FILE *stream) { + return getc(stream); +} + +char *fgets(char *s, int n, FILE *stream) { + char *p = s, *end = p + (n-1); + + if (stream->eof) return NULL; + + while (p < end) { + size_t n = fread(p, 1, 1, stream); + if (n != 1) { + if (p == s) { + // end of file reached, and no characters were read + return NULL; + } + break; + } + if (*p == '\n') { + ++p; + break; + } + ++p; + } + *p = '\0'; + return s; +} + +int putc(int c, FILE *stream) { + size_t n = fwrite(&c, 1, 1, stream); + if (n == 1) return c; + return EOF; +} + +int fputc(int c, FILE *stream) { + return putc(c, stream); +} + +int fputs(const char *s, FILE *stream) { + size_t n = strlen(s); + if (fwrite(s, 1, n, stream) == n) + return n; + return EOF; +} + +int getchar(void) { + return getc(stdin); +} + +char *gets(char *s) { + char *p; + fgets(s, 1l<<20, stdin); + if (*s) { + p = s + strlen(s) - 1; + // remove newline + if (*p == '\n') + *p = '\0'; + } + return s; +} + +int putchar(int c) { + return putc(c, stdout); +} + +int puts(const char *s) { + fputs(s, stdout); + putchar('\n'); +} + +int ungetc(int c, FILE *stream) { + if (c == EOF || stream->has_ungetc) return EOF; + stream->has_ungetc = 1; + stream->ungetc = c; + stream->eof = 0; + return c; +} + + +int fgetpos(FILE *stream, fpos_t *pos) { + long off = lseek(stream->fd, 0, SEEK_CUR); + if (off < 0) { + errno = EIO; + return EIO; + } + *pos = off; + return 0; +} + +int fsetpos(FILE *stream, const fpos_t *pos) { + long off = lseek(stream->fd, *pos, SEEK_SET); + if (off < 0) { + errno = EIO; + return EIO; + } + stream->eof = 0; + return 0; +} + +int fseek(FILE *stream, long int offset, int whence) { + long off = lseek(stream->fd, offset, whence); + if (off < 0) { + return EIO; + } + stream->eof = 0; + return 0; +} + +long int ftell(FILE *stream) { + long off = lseek(stream->fd, 0, SEEK_CUR); + if (off < 0) { + errno = EIO; + return -1L; + } + return off; +} + +void rewind(FILE *stream) { + fseek(stream, 0, SEEK_SET); + stream->err = 0; +} + +void clearerr(FILE *stream) { + stream->err = 0; +} + +int feof(FILE *stream) { + return stream->eof; +} + +int ferror(FILE *stream) { + return stream->err; +} + +// we don't buffer anything +// we're allowed to do this: "The contents of the array at any time are indeterminate." C89 § 4.9.5.6 +void setbuf(FILE *stream, char *buf) { +} + +int setvbuf(FILE *stream, char *buf, int mode, size_t size) { + return 0; +} + +typedef int _VscanfNextChar(void *, long *); +typedef int _VscanfPeekChar(void *); +int _str_next_char(void *dat, long *pos) { + const char **s = dat; + int c = **s; + if (c == '\0') return c; + ++*pos; + ++*s; + return c; +} +int _file_next_char(void *dat, long *pos) { + int c = getc(dat); + if (c == EOF) return c; + ++*pos; + return c; +} +int _str_peek_char(void *dat) { + const char **s = dat; + return **s; +} +int _file_peek_char(void *dat) { + int c = getc(dat); + ungetc(c, dat); + return c; +} + +void _bad_scanf(void) { + fprintf(stderr, "bad scanf format.\n"); + abort(); +} + +char _parse_escape_sequence(char **p_str) { + char *str = *p_str; + if (*str == '\\') { + ++str; + switch (*str) { + case 'n': *p_str = str + 1; return '\n'; + case 'v': *p_str = str + 1; return '\v'; + case 't': *p_str = str + 1; return '\t'; + case 'a': *p_str = str + 1; return '\a'; + case 'f': *p_str = str + 1; return '\f'; + case 'r': *p_str = str + 1; return '\r'; + case 'b': *p_str = str + 1; return '\b'; + case 'x': + ++str; + return (char)strtoul(str, p_str, 16); + case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7': { + int c = *str++ - '0'; + if (_isdigit_in_base(*str, 8)) c = (c << 3) + *str - '0', ++str; + if (_isdigit_in_base(*str, 8)) c = (c << 3) + *str - '0', ++str; + return c; + } break; + default: *p_str = str + 1; return *str; + } + } else { + *p_str += 1; + return *str; + } +} + +int _vscanf(_VscanfNextChar *__next_char, _VscanfPeekChar *__peek_char, int terminator, void *data, const char *fmt, va_list args) { + long pos = 0; // position in file/string (needed for %n) + int assignments = 0; + char number[128], *p_number; + unsigned char charset[256]; + int i; + + #define _next_char() (__next_char(data, &pos)) + #define _peek_char() (__peek_char(data)) + while (*fmt) { + if (*fmt == '%') { + int base = 10; + int assign = 1; + long field_width = LONG_MAX; + int modifier = 0; + char *end; + + ++fmt; + if (*fmt == '*') assign = 0, ++fmt; // assignment suppression + if (*fmt >= '0' && *fmt <= '9') + field_width = strtol(fmt, &fmt, 10); // field width + if (*fmt == 'l' || *fmt == 'L' || *fmt == 'h') + modifier = *fmt, ++fmt; + switch (*fmt) { + case 'd': { + while (isspace(_peek_char())) _next_char(); + // signed decimal integer + ++fmt; + if (field_width > 100) field_width = 100; // max number length + if (field_width == 0) goto vscanf_done; // number can't have size 0 + int c = _peek_char(); + p_number = number; + if (c == '-' || c == '+') { + if (field_width == 1) goto vscanf_done; + *p_number++ = _next_char(); + } + while ((p_number - number) < field_width && isdigit(_peek_char())) + *p_number++ = _next_char(); + *p_number = 0; + long value = strtol(number, &end, 10); + if (end == number) goto vscanf_done; // bad number + if (assign) { + switch (modifier) { + case 0: *va_arg(args, int*) = _clamp_long_to_int(value); break; + case 'h': *va_arg(args, short*) = _clamp_long_to_short(value); break; + case 'l': *va_arg(args, long*) = value; break; + default: _bad_scanf(); break; + } + ++assignments; + } + } break; + case 'i': { + while (isspace(_peek_char())) _next_char(); + // signed integer + long value = 0; + ++fmt; + if (field_width > 100) field_width = 100; // max number length + if (field_width == 0) goto vscanf_done; // number can't have size 0 + int c = _peek_char(); + p_number = number; + if (c == '-' || c == '+') { + if (field_width == 1) goto vscanf_done; + *p_number++ = _next_char(); + c = _peek_char(); + } + if (c == '0') { + *p_number++ = _next_char(); + if ((p_number - number) < field_width) { + c = _peek_char(); + if (c == 'x') { + if ((p_number - number) < field_width-1) + *p_number++ = _next_char(), base = 16; + else + goto emit_value; // e.g. 0x... width field width 2 + } else { + base = 8; + } + } else goto emit_value; + } + while ((p_number - number) < field_width && _isdigit_in_base(_peek_char(), base)) + *p_number++ = _next_char(); + *p_number = 0; + value = strtol(number, &end, 0); + if (end == number) goto vscanf_done; // bad number + emit_value: + if (assign) { + switch (modifier) { + case 0: *va_arg(args, int*) = _clamp_long_to_int(value); break; + case 'h': *va_arg(args, short*) = _clamp_long_to_short(value); break; + case 'l': *va_arg(args, long*) = value; break; + default: _bad_scanf(); break; + } + ++assignments; + } + } break; + case 'o': base = 8; goto vscanf_unsigned; + case 'u': goto vscanf_unsigned; + case 'p': modifier = 'l', base = 16; goto vscanf_unsigned; + case 'x': case 'X': base = 16; goto vscanf_unsigned; + vscanf_unsigned:{ + while (isspace(_peek_char())) _next_char(); + // unsigned integers + ++fmt; + if (field_width > 100) field_width = 100; // max number length + if (field_width == 0) goto vscanf_done; + int c = _peek_char(); + p_number = number; + if (c == '+') *p_number++ = _next_char(); + while ((p_number - number) < field_width && _isdigit_in_base(_peek_char(), base)) + *p_number++ = _next_char(); + *p_number = 0; + unsigned long value = strtoul(number, &end, base); + if (end == number) goto vscanf_done; // bad number + if (assign) { + switch (modifier) { + case 0: *va_arg(args, unsigned*) = _clamp_ulong_to_uint(value); break; + case 'h': *va_arg(args, unsigned short*) = _clamp_ulong_to_ushort(value); break; + case 'l': *va_arg(args, unsigned long*) = value; break; + default: _bad_scanf(); break; + } + ++assignments; + } + } break; + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': { + while (isspace(_peek_char())) _next_char(); + // floats + ++fmt; + if (field_width > 100) field_width = 100; // max number length + if (field_width == 0) goto vscanf_done; + int c = _peek_char(); + p_number = number; + if (c == '-' || c == '+') { + if (field_width == 1) goto vscanf_done; + *p_number++ = _next_char(); + c = _peek_char(); + } + if (c != '.' && !isdigit(c)) + goto vscanf_done; + while ((p_number - number) < field_width && isdigit(_peek_char())) + *p_number++ = _next_char(); + if ((p_number - number) < field_width && _peek_char() == '.') { + *p_number++ = _next_char(); + while ((p_number - number) < field_width && isdigit(_peek_char())) + *p_number++ = _next_char(); + } + c = _peek_char(); + if ((p_number - number) < field_width && c == 'e' || c == 'E') { + *p_number++ = _next_char(); + c = _peek_char(); + if ((p_number - number) < field_width && c == '+') + *p_number++ = _next_char(); + else if ((p_number - number) < field_width && c == '-') + *p_number++ = _next_char(); + + while ((p_number - number) < field_width && isdigit(_peek_char())) + *p_number++ = _next_char(); + } + double value = strtod(number, &end); + if (end == number) goto vscanf_done; // bad number + if (assign) { + switch (modifier) { + case 0: *va_arg(args, float*) = value; break; + case 'l': case 'L': *va_arg(args, double*) = value; break; + default: _bad_scanf(); break; + } + + ++assignments; + } + } break; + case 's': { + while (isspace(_peek_char())) _next_char(); + // string of non-whitespace characters + ++fmt; + char *str = assign ? va_arg(args, char*) : NULL, *p = str; + for (i = 0; i < field_width && !isspace(_peek_char()); ++i) { + int c = _next_char(); + if (c == terminator) break; + if (p) *p++ = c; + } + if (i == 0) goto vscanf_done; // empty sequence + if (p) { + *p = 0; + ++assignments; + } + } break; + case '[': { + // string of characters in charset + int complement = 0; + ++fmt; + if (*fmt == '^') { + complement = 1; + ++fmt; + } + memset(charset, complement, sizeof charset); + do { // NB: this is a do-while loop and not a while loop, because []] matches strings of ]'s. + charset[(unsigned char)_parse_escape_sequence(&fmt)] = !complement; + } while (*fmt != ']'); + ++fmt; // skip ] + char *str = assign ? va_arg(args, char*) : NULL, *p = str; + for (i = 0; i < field_width && charset[(unsigned char)_peek_char()]; ++i) { + int c = _next_char(); + if (c == terminator) break; + if (p) *p++ = c; + } + if (i == 0) goto vscanf_done; // empty sequence + if (p) { + *p = 0; + ++assignments; + } + } break; + case 'c': { + // string of characters + ++fmt; + char *str = assign ? va_arg(args, char*) : NULL, *p = str; + if (field_width == LONG_MAX) field_width = 1; + for (i = 0; i < field_width; ++i) { + int c = _next_char(); + if (c == terminator) break; + if (p) *p++ = c; + } + if (i < field_width) goto vscanf_done; // end of file encountered + if (p) { + ++assignments; + } + } break; + case 'n': + ++fmt; + switch (modifier) { + case 0: *va_arg(args, int *) = pos; break; + case 'h': *va_arg(args, short *) = pos; break; + case 'l': *va_arg(args, long *) = pos; break; + default: _bad_scanf(); break; + } + break; + default: + _bad_scanf(); + break; + } + } else if (isspace(*fmt)) { + // skip spaces in input + ++fmt; + while (isspace(_peek_char())) _next_char(); + } else { + if (_peek_char() == *fmt) { + // format character matches input character + ++fmt; + _next_char(); + } else { + // format character doesn't match input character; stop parsing + break; + } + } + } + vscanf_done: + if (_peek_char() == terminator && assignments == 0) return EOF; + return assignments; + #undef _next_char + #undef _peek_char +} + +int fscanf(FILE *stream, const char *format, ...) { + va_list args; + va_start(args, format); + int ret = _vscanf(_file_next_char, _file_peek_char, EOF, stream, format, args); + va_end(args); + return ret; +} + +int sscanf(const char *s, const char *format, ...) { + va_list args; + va_start(args, format); + int ret = _vscanf(_str_next_char, _str_peek_char, 0, &s, format, args); + va_end(args); + return ret; +} + +int scanf(const char *format, ...) { + va_list args; + va_start(args, format); + int ret = _vscanf(_file_next_char, _file_peek_char, EOF, stdin, format, args); + va_end(args); + return ret; +} + + +void perror(const char *s) { + printf("%s: %s\n", s, strerror(errno)); +} + +#undef STB_SPRINTF_MIN + +#endif // _STDIO_H diff --git a/05/tcc-0.9.27/stdlib.h b/05/tcc-0.9.27/stdlib.h new file mode 100644 index 0000000..b93d4aa --- /dev/null +++ b/05/tcc-0.9.27/stdlib.h @@ -0,0 +1,199 @@ +#ifndef _STDLIB_H +#define _STDLIB_H + +#include + +#define EXIT_FAILURE (-1) +#define EXIT_SUCCESS 0 +#define RAND_MAX 2147483647 +// @NONSTANDARD: we don't define MB_CUR_MAX or any of the mbtowc functions + +typedef struct { + int quot; + int rem; +} div_t; + +typedef struct { + long quot; + long rem; +} ldiv_t; + + +int execvp(const char *pathname, char *const argv[]) { + return execve(pathname, argv, _envp); +} + + +char *getenv(const char *name) { + int i, j; + for (i = 0; _envp[i]; ++i) { + char *key = _envp[i]; + for (j = 0; key[j] != '=' && name[j]; ++j) + if (name[j] != key[j]) + break; + if (key[j] == '=' && !name[j]) + return key + (j+1); + } + return NULL; +} + +double atof(const char *nptr) { + return strtod(nptr, NULL); +} + +int atoi(const char *nptr) { + return _clamp_long_to_int(strtol(nptr, NULL, 10)); +} + +long atol(const char *nptr) { + return strtol(nptr, NULL, 10); +} + +int rand(void) { + // https://en.wikipedia.org/wiki/Linear_congruential_generator + // we're using musl/newlib's constants + _rand_seed = 6364136223846793005 * _rand_seed + 1; + return _rand_seed >> 33; +} + +void srand(unsigned seed) { + _rand_seed = seed; +} + +void *calloc(size_t nmemb, size_t size) { + if (nmemb > 0xffffffffffffffff / size) + return NULL; + // NB: our malloc implementation returns zeroed memory + return malloc(nmemb * size); +} + +void *realloc(void *ptr, size_t size) { + if (!ptr) return malloc(size); + if (!size) { + free(ptr); + return NULL; + } + uint64_t *memory = (char *)ptr - 16; + uint64_t old_size = *memory; + uint64_t *new_memory = _mremap(memory, old_size, size, MREMAP_MAYMOVE); + if ((uint64_t)new_memory > 0xffffffffffff0000) return NULL; + *new_memory = size; + return (char *)new_memory + 16; +} + + +int atexit(void (*func)(void)) { + if (_n_exit_handlers >= 32) return -1; + _exit_handlers[_n_exit_handlers++] = func; + return 0; +} + +int system(const char *string) { + if (!string) return 1; + + int pid = fork(); + if (pid < 0) { + return -1; + } else if (pid == 0) { + // child + char *argv[] = { + "/bin/sh", + "-c", + 0, + 0 + }; + argv[2] = string; + execve("/bin/sh", argv, _envp); + // on success, execve does not return. + _Exit(-1); + } else { + // parent + int status = 0; + int ret = wait4(pid, &status, 0, NULL); + if (ret != pid) return -1; + if (_WIFSIGNALED(status)) return -1; + return _WEXITSTATUS(status); + } + +} + +void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { + size_t lo = 0; + size_t hi = nmemb; + while (lo < hi) { + size_t mid = (lo + hi) >> 1; + void *elem = (char *)base + mid * size; + int cmp = compar(key, elem); + if (cmp < 0) { + // key < elem + hi = mid; + } else if (cmp) { + // key > elem + lo = mid + 1; + } else { + return elem; + } + } + return NULL; +} + +void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) { + // quicksort + if (nmemb < 2) return; + + void *temp = malloc(size); + void *mid = (char *)base + ((nmemb >> 1) * size); // choose middle element to speed up sorting an already-sorted array + size_t pivot_index = 0, i; + for (i = 0; i < nmemb; ++i) { + void *elem = (char *)base + i * size; + if (compar(elem, mid) < 0) + ++pivot_index; + } + void *pivot = (char *)base + pivot_index * size; + memcpy(temp, pivot, size); + memcpy(pivot, mid, size); + memcpy(mid, temp, size); + + char *l, *r = (char *)base + (nmemb-1) * size; + for (l = base; l < r;) { + if (compar(l, pivot) > 0) { + // swap l and r + memcpy(temp, l, size); + memcpy(l, r, size); + memcpy(r, temp, size); + r -= size; + } else { + // l is already in the right place + l += size; + } + } + + qsort(base, pivot_index, size, compar); + qsort((char *)pivot + size, nmemb - 1 - pivot_index, size, compar); + + free(temp); +} + +int abs(int x) { + return x >= 0 ? x : -x; +} + +long labs(long x) { + return x >= 0 ? x : -x; +} + +div_t div(int numer, int denom) { + div_t d; + d.quot = numer / denom; + d.rem = numer % denom; + return d; +} + +ldiv_t ldiv(long numer, long denom) { + ldiv_t d; + d.quot = numer / denom; + d.rem = numer % denom; + return d; +} + +#endif // _STDLIB_H diff --git a/05/tcc-0.9.27/string.h b/05/tcc-0.9.27/string.h new file mode 100644 index 0000000..4b73101 --- /dev/null +++ b/05/tcc-0.9.27/string.h @@ -0,0 +1,185 @@ +#ifndef _STRING_H +#define _STRING_H + +#include + + +void *memmove(void *s1, const void *s2, size_t n) { + if (s1 < s2) return memcpy(s1, s2, n); // our memcpy does a forwards copy + // backwards copy + char *p = (char*)s1 + n, *q = (char*)s2 + n; + while (p > s1) + *--p = *--q; + return s1; +} + +char *strcpy(char *s1, const char *s2) { + char *p = s1 - 1, *q = s2 - 1; + while ((*++p = *++q)); + return s1; +} + +char *strncpy(char *s1, const char *s2, size_t n) { + char *p = s1 - 1, *q = s2 - 1; + size_t i; + for (i = 0; i < n; ++i) + if (!(*++p = *++q)) + break; + for (; i < n; ++i) + *++p = 0; + return s1; +} + +char *strcat(char *s1, const char *s2) { + return strcpy(s1 + strlen(s1), s2); +} + +char *strncat(char *s1, const char *s2, size_t n) { + // oddly, not equivalent to strncpy(s1 + strlen(s1), s2, n) + char *p = s1 + strlen(s1) - 1, *q = s2 - 1; + size_t i; + for (i = 0; i < n; ++i) + if (!(*++p = *++q)) + break; + *++p = 0; + return s1; +} + +int memcmp(const void *s1, const void *s2, size_t n) { + char *p = s1, *q = s2; + size_t i; + for (i = 0; i < n; ++i, ++p, ++q) { + if (*p > *q) + return 1; + if (*p < *q) + return -1; + } + return 0; +} + +int strcmp(const char *s1, const char *s2) { + char *p = s1, *q = s2; + for (; ; ++p, ++q) { + if (*p > *q) + return 1; + if (*p < *q) + return -1; + if (!*p) break; + } + return 0; +} + +int strcoll(const char *s1, const char *s2) { + // we only support the C locale + return strcmp(s1, s2); +} + +int strncmp(const char *s1, const char *s2, size_t n) { + char *p = s1, *q = s2; + size_t i; + for (i = 0; i < n; ++i, ++p, ++q) { + if (*p > *q) + return 1; + if (*p < *q) + return -1; + if (!*p) break; + } + return 0; +} + +size_t strxfrm(char *s1, const char *s2, size_t n) { + // we only support the C locale + size_t l = strlen(s2); + if (l >= n) return l; + strcpy(s1, s2); + return l; +} + +void *memchr(const void *s, int c, size_t n) { + char *p = s, *end = p + n; + while (p < end) { + if ((unsigned char)*p == c) + return p; + ++p; + } + return NULL; +} + +char *strchr(const char *s, int c) { + return memchr(s, c, strlen(s)+1); +} + + +size_t strcspn(const char *s1, const char *s2) { + const char *p, *q; + for (p = s1; *p; ++p) { + for (q = s2; *q; ++q) { + if (*p == *q) + goto ret; + } + } + ret: + return p - s1; +} + +char *strpbrk(const char *s1, const char *s2) { + const char *p, *q; + for (p = s1; *p; ++p) { + for (q = s2; *q; ++q) { + if (*p == *q) + return p; + } + } + return NULL; +} + +char *strrchr(const char *s, int c) { + char *p; + for (p = s + strlen(s); p >= s; --p) { + if (*p == c) + return p; + } + return NULL; +} + +size_t strspn(const char *s1, const char *s2) { + const char *p, *q; + for (p = s1; *p; ++p) { + for (q = s2; *q; ++q) { + if (*p == *q) break; + } + if (!*q) break; + } + return p - s1; +} + +char *strstr(const char *s1, const char *s2) { + char *p; + size_t l = strlen(s2); + for (p = s1; *p; ++p) { + if (memcmp(p, s2, l) == 0) + return p; + } + return NULL; +} + +char *strtok(char *s1, const char *s2) { + static char *str; + if (s1) str = s1; + if (!str) return NULL; + char *p = str + strspn(str, s2); + if (!*p) { + str = NULL; + return NULL; + } + char *q = strpbrk(p, s2); + if (q) { + *q = 0; + str = q + 1; + } else { + str = NULL; + } + return p; +} + +#endif // _STRING_H diff --git a/05/tcc-0.9.27/tcc-doc.texi b/05/tcc-0.9.27/tcc-doc.texi new file mode 100644 index 0000000..5e718a2 --- /dev/null +++ b/05/tcc-0.9.27/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 + +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/05/tcc-0.9.27/tcc.c b/05/tcc-0.9.27/tcc.c new file mode 100644 index 0000000..fdd9305 --- /dev/null +++ b/05/tcc-0.9.27/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; + _init_options(); +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/05/tcc-0.9.27/tcc.h b/05/tcc-0.9.27/tcc.h new file mode 100644 index 0000000..c7f6c72 --- /dev/null +++ b/05/tcc-0.9.27/tcc.h @@ -0,0 +1,1754 @@ +/* + * 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 +#include +#include +#include +#include +#include +#ifdef __GNUC__ +#include +#endif +#include +#include + +#ifndef _WIN32 +#ifdef __GNUC__ +# include +# include +#endif +# ifndef CONFIG_TCC_STATIC +# include +# 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 +# include /* open, close etc. */ +# include /* getcwd */ +# ifdef __GNUC__ +# include +# 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)) +#elif __GNUC__ +# define NORETURN __attribute__((noreturn)) +# define ALIGNED(x) __attribute__((aligned(x))) +#else +#define NORETURN +#define 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 { +#if 0 + unsigned short + aligned : 5, /* alignment as log2+1 (0 == unspecified) */ + packed : 1, + weak : 1, + visibility : 2, + dllexport : 1, + dllimport : 1, + unused : 5; +#else + // hopefully it didn't matter that these were bitfields + unsigned char aligned,packed,weak,visibility,dllexport,dllimport; +#endif +}; + +/* function attributes or temporary attributes for parsing */ +struct FuncAttr { +#if 0 + unsigned + func_call : 3, /* calling convention (0..5), see below */ + func_type : 2, /* FUNC_OLD/NEW/ELLIPSIS */ + func_args : 8; /* PE __stdcall args */ +#else + // hopefully it didn't matter that these were bitfields + unsigned char func_call,func_type,func_args; +#endif +}; + +/* 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_BWLX(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_WLX DEF_WLQ +# define DEF_WLX(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) +/* 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) +#define DEF_ASMTEST1(x) \ + DEF_ASM(x ## o) \ + DEF_ASM(x ## no) \ + DEF_ASM(x ## b) \ + DEF_ASM(x ## c) \ + DEF_ASM(x ## nae) \ + DEF_ASM(x ## nb) \ + DEF_ASM(x ## nc) \ + DEF_ASM(x ## ae) \ + DEF_ASM(x ## e) \ + DEF_ASM(x ## z) \ + DEF_ASM(x ## ne) \ + DEF_ASM(x ## nz) \ + DEF_ASM(x ## be) \ + DEF_ASM(x ## na) \ + DEF_ASM(x ## nbe) \ + DEF_ASM(x ## a) \ + DEF_ASM(x ## s) \ + DEF_ASM(x ## ns) \ + DEF_ASM(x ## p) \ + DEF_ASM(x ## pe) \ + DEF_ASM(x ## np) \ + DEF_ASM(x ## po) \ + DEF_ASM(x ## l) \ + DEF_ASM(x ## nge) \ + DEF_ASM(x ## nl) \ + DEF_ASM(x ## ge) \ + DEF_ASM(x ## le) \ + DEF_ASM(x ## ng) \ + DEF_ASM(x ## nle) \ + DEF_ASM(x ## g) + +#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 = 1; +/* use Tiny C extensions */ +ST_DATA int tcc_ext = 1; +/* 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 "!\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 ------------ */ + +#if 0 +ST_DATA const int reg_classes[NB_REGS]; +#else + +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 +}; +#endif + +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/05/tcc-0.9.27/tccasm.c b/05/tcc-0.9.27/tccasm.c new file mode 100644 index 0000000..5f4f948 --- /dev/null +++ b/05/tcc-0.9.27/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; + case TOK_SAR: + default: + 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; + case '^': + default: + 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;iconstraint); + 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/05/tcc-0.9.27/tcccoff.c b/05/tcc-0.9.27/tcccoff.c new file mode 100644 index 0000000..1421ca2 --- /dev/null +++ b/05/tcc-0.9.27/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 = §ion_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 = §ion_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 = §ion_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 = §ion_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 = §ion_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 = §ion_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 = §ion_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 = §ion_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/05/tcc-0.9.27/tccelf.c b/05/tcc-0.9.27/tccelf.c new file mode 100644 index 0000000..378f077 --- /dev/null +++ b/05/tcc-0.9.27/tccelf.c @@ -0,0 +1,3060 @@ +/* + * 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 */ + +#if 0 +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; +#endif + +/* 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 + && ELF64_ST_BIND(sym->st_info) == STB_LOCAL) + sym->st_info = ELF64_ST_INFO(STB_GLOBAL, ELF64_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 = ELF64_R_SYM(rel->r_info) - first_sym; + //if (n < 0) tcc_error("internal: invalid symbol index in relocation"); + rel->r_info = ELF64_R_INFO(tr[n], ELF64_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 (ELF64_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 (ELF64_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 = ELF64_ST_BIND(info); + sym_type = ELF64_ST_TYPE(info); + sym_vis = ELF64_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 = ELF64_ST_BIND(esym->st_info); + /* propagate the most constraining visibility */ + /* STV_DEFAULT(0)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 & ~ELF64_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 = ELF64_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, + ELF64_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 = ELF64_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 in section starting at elem + using variable */ +#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 (ELF64_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 (ELF64_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 = ELF64_R_SYM(rel->r_info); + type = ELF64_R_TYPE(rel->r_info); + sym_index = old_to_new_syms[sym_index]; + rel->r_info = ELF64_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 = ELF64_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 = ELF64_R_SYM(rel->r_info); + sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; + type = ELF64_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 = ELF64_R_SYM(rel->r_info); + type = ELF64_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 = ELF64_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, ELF64_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 (ELF64_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, + ELF64_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 = ELF64_R_TYPE(rel->r_info); + gotplt_entry = gotplt_entry_type(type); + sym_index = ELF64_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 + && (ELF64_ST_TYPE(esym->st_info) == STT_FUNC + || (ELF64_ST_TYPE(esym->st_info) == STT_NOTYPE + && ELF64_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) && + (ELF64_ST_VISIBILITY(sym->st_other) != STV_DEFAULT || + ELF64_ST_BIND(sym->st_info) == STB_LOCAL)) { + rel->r_info = ELF64_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 = ELF64_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, + ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, + s->sh_num, sym_start); + set_elf_sym(symtab_section, + end_offset, 0, + ELF64_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, + ELF64_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, + ELF64_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, + ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, + text_section->sh_num, "_etext"); + set_elf_sym(symtab_section, + data_section->data_offset, 0, + ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, + data_section->sh_num, "_edata"); + set_elf_sym(symtab_section, + bss_section->data_offset, 0, + ELF64_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, + ELF64_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, + ELF64_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;inb_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 = ELF64_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 (ELF64_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 (ELF64_R_TYPE(rel->r_info) == R_RELATIVE) { + int sym_index = ELF64_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 = ELF64_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 = ELF64_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, + ELF64_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 (ELF64_ST_BIND(esym->st_info) == STB_WEAK) { + for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) { + if ((dynsym->st_value == esym->st_value) + && (ELF64_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 (ELF64_ST_BIND(sym->st_info) == STB_WEAK || + !strcmp(name, "_fp_hw")) { + } else { + tcc_error_noabort("undefined symbol '%s'", name); + } + } + } else if (s1->rdynamic && ELF64_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 + && ELF64_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 (ELF64_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 (ELF64_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) { + 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; + case TCC_OUTPUT_EXE: + default: + ehdr.e_type = ET_EXEC; + ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1); + 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 (ELF64_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 = ELF64_R_TYPE(rel->r_info); + sym_index = ELF64_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 = ELF64_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 = ELF64_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/05/tcc-0.9.27/tccgen.c b/05/tcc-0.9.27/tccgen.c new file mode 100644 index 0000000..7f5d1e6 --- /dev/null +++ b/05/tcc-0.9.27/tccgen.c @@ -0,0 +1,7388 @@ +/* + * 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 */ +#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */ +#define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */ + +/* loc : local variable index + ind : output code index + rsym: return symbol + anon_sym: anonymous symbol index +*/ +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 */ + +#if 0 +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; + +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 */ +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; +#endif +ST_DATA CType 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, + ELF64_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, + ELF64_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 & ~ELF64_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 = ELF64_ST_BIND(esym->st_info); + if (sym_bind != old_sym_bind) { + esym->st_info = ELF64_ST_INFO(sym_bind, ELF64_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 = ELF64_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;rr & 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;rr & 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) { + case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break; + case TOK_UDIV: l1 = l1 / l2; break; + case TOK_UMOD: l1 = l1 % l2; break; + default: l1 = gen_opic_sdiv(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 + 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, ""); + 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, ®size); + 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, ®size); + 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, + ELF64_R_TYPE(rel->r_info), + ELF64_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;it & 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/05/tcc-0.9.27/tcclib.h b/05/tcc-0.9.27/tcclib.h new file mode 100644 index 0000000..8d59e4c --- /dev/null +++ b/05/tcc-0.9.27/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 +#include + +/* 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/05/tcc-0.9.27/tccpe.c b/05/tcc-0.9.27/tccpe.c new file mode 100644 index 0000000..a7266c9 --- /dev/null +++ b/05/tcc-0.9.27/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 /* 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 .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/05/tcc-0.9.27/tccpp.c b/05/tcc-0.9.27/tccpp.c new file mode 100644 index 0000000..9276659 --- /dev/null +++ b/05/tcc-0.9.27/tccpp.c @@ -0,0 +1,3907 @@ +/* + * 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 */ + +#if 0 +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; +#endif + +/* ------------------------------------------------------------------------- */ + +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 "\n" +#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;ilen == 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;istr.data)[i]); + } else { + len = (cv->str.size / sizeof(nwchar_t)) - 1; + for(i=0;istr.data)[i]); + } + cstr_ccat(&cstr_buf, '\"'); + cstr_ccat(&cstr_buf, '\0'); + break; + + case TOK_CFLOAT: + cstr_cat(&cstr_buf, "", 0); + break; + case TOK_CDOUBLE: + cstr_cat(&cstr_buf, "", 0); + break; + case TOK_CLDOUBLE: + cstr_cat(&cstr_buf, "", 0); + break; + case TOK_LINENUM: + cstr_cat(&cstr_buf, "", 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, ""); + 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(¯o_equal_buf); + TOK_GET(&t, &a, &cv); + cstr_cat(¯o_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 "); + 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> (32 - shift); + } +} + +static void bn_zero(unsigned int *bn) +{ + int i; + for(i=0;i= '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, ¯o_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, ¯o_str, &cval); + if (!t) + break; + if (t == '#') { + /* stringize */ + TOK_GET(&t, ¯o_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(¯o_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(¯o_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(¯o_str1, t, &cval); + } + tok_str_add(¯o_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, ¯o_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, "", 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 == '\n') + 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(¯o_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/05/tcc-0.9.27/tccrun.c b/05/tcc-0.9.27/tccrun.c new file mode 100644 index 0000000..9360164 --- /dev/null +++ b/05/tcc-0.9.27/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 +#endif + +#ifdef CONFIG_TCC_BACKTRACE +# ifndef _WIN32 +# include +# ifndef __OpenBSD__ +# include +# 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; inb_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;isi_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= 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;iuc_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= 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/05/tcc-0.9.27/tcctok.h b/05/tcc-0.9.27/tcctok.h new file mode 100644 index 0000000..e1de98f --- /dev/null +++ b/05/tcc-0.9.27/tcctok.h @@ -0,0 +1,1641 @@ +/* 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 + +/* 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_ASMTEST1(j) + + DEF_ASMTEST1(set) + DEF_ASMTEST(set,b) + DEF_ASMTEST1(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) + +#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) + 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 + +#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) + 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 + + +#endif // target i386 or x86 64 diff --git a/05/tcc-0.9.27/tcctools.c b/05/tcc-0.9.27/tcctools.c new file mode 100644 index 0000000..1d4424e --- /dev/null +++ b/05/tcc-0.9.27/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 "!\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("!\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 + +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; inb_target_deps; ++i) + fprintf(depout, " %s \\\n", s->target_deps[i]); + fprintf(depout, "\n"); + fclose(depout); +} + +/* -------------------------------------------------------------- */ diff --git a/05/tcc-0.9.27/tests/42test.h b/05/tcc-0.9.27/tests/42test.h new file mode 100644 index 0000000..5db7d1c --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/Makefile b/05/tcc-0.9.27/tests/Makefile new file mode 100644 index 0000000..5f6777d --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/abitest.c b/05/tcc-0.9.27/tests/abitest.c new file mode 100644 index 0000000..4a192bd --- /dev/null +++ b/05/tcc-0.9.27/tests/abitest.c @@ -0,0 +1,691 @@ +#include +#include +#include +#include +#include + +// 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 \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 \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 \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/05/tcc-0.9.27/tests/asm-c-connect-1.c b/05/tcc-0.9.27/tests/asm-c-connect-1.c new file mode 100644 index 0000000..8a28d78 --- /dev/null +++ b/05/tcc-0.9.27/tests/asm-c-connect-1.c @@ -0,0 +1,57 @@ +#include + +#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/05/tcc-0.9.27/tests/asm-c-connect-2.c b/05/tcc-0.9.27/tests/asm-c-connect-2.c new file mode 100644 index 0000000..3440b40 --- /dev/null +++ b/05/tcc-0.9.27/tests/asm-c-connect-2.c @@ -0,0 +1,36 @@ +#include + +#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/05/tcc-0.9.27/tests/asmtest.S b/05/tcc-0.9.27/tests/asmtest.S new file mode 100644 index 0000000..e9c0e32 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/boundtest.c b/05/tcc-0.9.27/tests/boundtest.c new file mode 100644 index 0000000..15bffb4 --- /dev/null +++ b/05/tcc-0.9.27/tests/boundtest.c @@ -0,0 +1,285 @@ +#include +#include +#include + +#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= 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/05/tcc-0.9.27/tests/gcctestsuite.sh b/05/tcc-0.9.27/tests/gcctestsuite.sh new file mode 100755 index 0000000..f3cc538 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/libtcc_test.c b/05/tcc-0.9.27/tests/libtcc_test.c new file mode 100644 index 0000000..480d314 --- /dev/null +++ b/05/tcc-0.9.27/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 +#include +#include + +#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 \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/05/tcc-0.9.27/tests/pp/01.c b/05/tcc-0.9.27/tests/pp/01.c new file mode 100644 index 0000000..2fc3d79 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/01.expect b/05/tcc-0.9.27/tests/pp/01.expect new file mode 100644 index 0000000..cf5b153 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/01.expect @@ -0,0 +1 @@ +char p[] = "x ## y"; diff --git a/05/tcc-0.9.27/tests/pp/02.c b/05/tcc-0.9.27/tests/pp/02.c new file mode 100644 index 0000000..feb1254 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/02.expect b/05/tcc-0.9.27/tests/pp/02.expect new file mode 100644 index 0000000..8ae2eb9 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/03.c b/05/tcc-0.9.27/tests/pp/03.c new file mode 100644 index 0000000..a659245 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/03.expect b/05/tcc-0.9.27/tests/pp/03.expect new file mode 100644 index 0000000..44aad0a --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/04.c b/05/tcc-0.9.27/tests/pp/04.c new file mode 100644 index 0000000..0068f37 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/04.expect b/05/tcc-0.9.27/tests/pp/04.expect new file mode 100644 index 0000000..7c67b01 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/04.expect @@ -0,0 +1 @@ +(1) diff --git a/05/tcc-0.9.27/tests/pp/05.c b/05/tcc-0.9.27/tests/pp/05.c new file mode 100644 index 0000000..7274941 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/05.expect b/05/tcc-0.9.27/tests/pp/05.expect new file mode 100644 index 0000000..9f9be37 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/06.c b/05/tcc-0.9.27/tests/pp/06.c new file mode 100644 index 0000000..28cfdde --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/06.c @@ -0,0 +1,5 @@ +#define X(a,b, \ + c,d) \ + foo + +X(1,2,3,4) diff --git a/05/tcc-0.9.27/tests/pp/06.expect b/05/tcc-0.9.27/tests/pp/06.expect new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/06.expect @@ -0,0 +1 @@ +foo diff --git a/05/tcc-0.9.27/tests/pp/07.c b/05/tcc-0.9.27/tests/pp/07.c new file mode 100644 index 0000000..b22b22b --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/07.c @@ -0,0 +1,4 @@ +#define a() YES +#define b() a +b() +b()() diff --git a/05/tcc-0.9.27/tests/pp/07.expect b/05/tcc-0.9.27/tests/pp/07.expect new file mode 100644 index 0000000..ad0e20a --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/07.expect @@ -0,0 +1,2 @@ +a +YES diff --git a/05/tcc-0.9.27/tests/pp/08.c b/05/tcc-0.9.27/tests/pp/08.c new file mode 100644 index 0000000..93018e1 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/08.expect b/05/tcc-0.9.27/tests/pp/08.expect new file mode 100644 index 0000000..2b2e3ee --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/08.expect @@ -0,0 +1 @@ +(hej.s_s.s_pos) diff --git a/05/tcc-0.9.27/tests/pp/09.c b/05/tcc-0.9.27/tests/pp/09.c new file mode 100644 index 0000000..315b297 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/09.expect b/05/tcc-0.9.27/tests/pp/09.expect new file mode 100644 index 0000000..adce0f9 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/09.expect @@ -0,0 +1 @@ +aaaaoooo diff --git a/05/tcc-0.9.27/tests/pp/10.c b/05/tcc-0.9.27/tests/pp/10.c new file mode 100644 index 0000000..f180eff --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/10.expect b/05/tcc-0.9.27/tests/pp/10.expect new file mode 100644 index 0000000..bd18e18 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/11.c b/05/tcc-0.9.27/tests/pp/11.c new file mode 100644 index 0000000..c0edf62 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/11.expect b/05/tcc-0.9.27/tests/pp/11.expect new file mode 100644 index 0000000..6b9806c --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/12.S b/05/tcc-0.9.27/tests/pp/12.S new file mode 100644 index 0000000..597ccb4 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/12.expect b/05/tcc-0.9.27/tests/pp/12.expect new file mode 100644 index 0000000..17a861c --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/12.expect @@ -0,0 +1,2 @@ + 9999: 1: movw (%esi), %bx; .section __ex_table, "a"; .long 9999b, 6001f ; +6001: diff --git a/05/tcc-0.9.27/tests/pp/13.S b/05/tcc-0.9.27/tests/pp/13.S new file mode 100644 index 0000000..bf0b525 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/13.expect b/05/tcc-0.9.27/tests/pp/13.expect new file mode 100644 index 0000000..c7a3230 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/13.expect @@ -0,0 +1,2 @@ +.text +endtext: diff --git a/05/tcc-0.9.27/tests/pp/14.c b/05/tcc-0.9.27/tests/pp/14.c new file mode 100644 index 0000000..e15468c --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/14.expect b/05/tcc-0.9.27/tests/pp/14.expect new file mode 100644 index 0000000..3786044 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/15.c b/05/tcc-0.9.27/tests/pp/15.c new file mode 100644 index 0000000..cf13f9a --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/15.expect b/05/tcc-0.9.27/tests/pp/15.expect new file mode 100644 index 0000000..b4f885e --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/16.c b/05/tcc-0.9.27/tests/pp/16.c new file mode 100644 index 0000000..8b5b642 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/16.c @@ -0,0 +1,3 @@ +/* The following should warn */ +#define A ... +#define A <<= diff --git a/05/tcc-0.9.27/tests/pp/16.expect b/05/tcc-0.9.27/tests/pp/16.expect new file mode 100644 index 0000000..695d6d4 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/16.expect @@ -0,0 +1,2 @@ + +16.c:3: warning: A redefined diff --git a/05/tcc-0.9.27/tests/pp/17.c b/05/tcc-0.9.27/tests/pp/17.c new file mode 100644 index 0000000..f12196f --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/17.expect b/05/tcc-0.9.27/tests/pp/17.expect new file mode 100644 index 0000000..e95aafe --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/18.c b/05/tcc-0.9.27/tests/pp/18.c new file mode 100644 index 0000000..0961426 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/18.expect b/05/tcc-0.9.27/tests/pp/18.expect new file mode 100644 index 0000000..447a9b2 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/18.expect @@ -0,0 +1,3 @@ +X181 1 +X182 0 +X183 yeah diff --git a/05/tcc-0.9.27/tests/pp/19.c b/05/tcc-0.9.27/tests/pp/19.c new file mode 100644 index 0000000..aa91abe --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/19.expect b/05/tcc-0.9.27/tests/pp/19.expect new file mode 100644 index 0000000..08c0858 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/20.c b/05/tcc-0.9.27/tests/pp/20.c new file mode 100644 index 0000000..7944d62 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/20.expect b/05/tcc-0.9.27/tests/pp/20.expect new file mode 100644 index 0000000..d19405d --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/21.c b/05/tcc-0.9.27/tests/pp/21.c new file mode 100644 index 0000000..1316226 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/21.expect b/05/tcc-0.9.27/tests/pp/21.expect new file mode 100644 index 0000000..5a1376b --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/21.expect @@ -0,0 +1,8 @@ +----- 1 ------ +OK +----- 2 ------ +OK +----- 3 ------ +OK +----- 4 ------ +OK diff --git a/05/tcc-0.9.27/tests/pp/Makefile b/05/tcc-0.9.27/tests/pp/Makefile new file mode 100644 index 0000000..687aa52 --- /dev/null +++ b/05/tcc-0.9.27/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 ignore lines matching RE diff --git a/05/tcc-0.9.27/tests/pp/pp-counter.c b/05/tcc-0.9.27/tests/pp/pp-counter.c new file mode 100644 index 0000000..3978e1a --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/pp/pp-counter.expect b/05/tcc-0.9.27/tests/pp/pp-counter.expect new file mode 100644 index 0000000..02fc535 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tcctest.c b/05/tcc-0.9.27/tests/tcctest.c new file mode 100644 index 0000000..57670be --- /dev/null +++ b/05/tcc-0.9.27/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 +#define TCCLIB_INC1 +#define TCCLIB_INC3 "tcclib.h" + +#include TCCLIB_INC + +#include TCCLIB_INC1.TCCLIB_INC2 + +#include TCCLIB_INC1.h> + +#include TCCLIB_INC3 + +#include + +#include "tcclib.h" + +#include "tcctest.h" + +/* Test two more ways to include a file named like a pp-number */ +#define INC(name) +#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 = # + (*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/05/tcc-0.9.27/tests/tcctest.h b/05/tcc-0.9.27/tests/tcctest.h new file mode 100644 index 0000000..b301c7c --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/testfp.c b/05/tcc-0.9.27/tests/testfp.c new file mode 100644 index 0000000..63342b4 --- /dev/null +++ b/05/tcc-0.9.27/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 +#include +#include +#include + +#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/05/tcc-0.9.27/tests/tests2/00_assignment.c b/05/tcc-0.9.27/tests/tests2/00_assignment.c new file mode 100644 index 0000000..c96109f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/00_assignment.c @@ -0,0 +1,18 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/00_assignment.expect b/05/tcc-0.9.27/tests/tests2/00_assignment.expect new file mode 100644 index 0000000..d4407f3 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/00_assignment.expect @@ -0,0 +1,3 @@ +42 +64 +12, 34 diff --git a/05/tcc-0.9.27/tests/tests2/01_comment.c b/05/tcc-0.9.27/tests/tests2/01_comment.c new file mode 100644 index 0000000..a2e6bc6 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/01_comment.c @@ -0,0 +1,14 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/01_comment.expect b/05/tcc-0.9.27/tests/tests2/01_comment.expect new file mode 100644 index 0000000..b1387ad --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/01_comment.expect @@ -0,0 +1,5 @@ +Hello +Hello +Hello +Hello +Hello diff --git a/05/tcc-0.9.27/tests/tests2/02_printf.c b/05/tcc-0.9.27/tests/tests2/02_printf.c new file mode 100644 index 0000000..4c34dd8 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/02_printf.c @@ -0,0 +1,18 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/02_printf.expect b/05/tcc-0.9.27/tests/tests2/02_printf.expect new file mode 100644 index 0000000..f67a0f6 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/03_struct.c b/05/tcc-0.9.27/tests/tests2/03_struct.c new file mode 100644 index 0000000..c5d48c5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/03_struct.c @@ -0,0 +1,31 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/03_struct.expect b/05/tcc-0.9.27/tests/tests2/03_struct.expect new file mode 100644 index 0000000..ecbf589 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/03_struct.expect @@ -0,0 +1,6 @@ +12 +34 +12 +34 +56 +78 diff --git a/05/tcc-0.9.27/tests/tests2/04_for.c b/05/tcc-0.9.27/tests/tests2/04_for.c new file mode 100644 index 0000000..312fed8 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/04_for.c @@ -0,0 +1,15 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/04_for.expect b/05/tcc-0.9.27/tests/tests2/04_for.expect new file mode 100644 index 0000000..f00c965 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/04_for.expect @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/05/tcc-0.9.27/tests/tests2/05_array.c b/05/tcc-0.9.27/tests/tests2/05_array.c new file mode 100644 index 0000000..c218f31 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/05_array.c @@ -0,0 +1,21 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/05_array.expect b/05/tcc-0.9.27/tests/tests2/05_array.expect new file mode 100644 index 0000000..bc7257c --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/05_array.expect @@ -0,0 +1,10 @@ +1 +4 +9 +16 +25 +36 +49 +64 +81 +100 diff --git a/05/tcc-0.9.27/tests/tests2/06_case.c b/05/tcc-0.9.27/tests/tests2/06_case.c new file mode 100644 index 0000000..c0191e2 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/06_case.c @@ -0,0 +1,29 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/06_case.expect b/05/tcc-0.9.27/tests/tests2/06_case.expect new file mode 100644 index 0000000..fab2c20 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/06_case.expect @@ -0,0 +1,8 @@ +0 +0 +1 +1 +2 +2 +3 +0 diff --git a/05/tcc-0.9.27/tests/tests2/07_function.c b/05/tcc-0.9.27/tests/tests2/07_function.c new file mode 100644 index 0000000..0477ce1 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/07_function.c @@ -0,0 +1,30 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/07_function.expect b/05/tcc-0.9.27/tests/tests2/07_function.expect new file mode 100644 index 0000000..8ffb0a7 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/07_function.expect @@ -0,0 +1,4 @@ +9 +16 +a=1234 +qfunc() diff --git a/05/tcc-0.9.27/tests/tests2/08_while.c b/05/tcc-0.9.27/tests/tests2/08_while.c new file mode 100644 index 0000000..602ffc7 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/08_while.c @@ -0,0 +1,24 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/08_while.expect b/05/tcc-0.9.27/tests/tests2/08_while.expect new file mode 100644 index 0000000..702d4c0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/08_while.expect @@ -0,0 +1,11 @@ +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 diff --git a/05/tcc-0.9.27/tests/tests2/09_do_while.c b/05/tcc-0.9.27/tests/tests2/09_do_while.c new file mode 100644 index 0000000..1d3315d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/09_do_while.c @@ -0,0 +1,24 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/09_do_while.expect b/05/tcc-0.9.27/tests/tests2/09_do_while.expect new file mode 100644 index 0000000..702d4c0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/09_do_while.expect @@ -0,0 +1,11 @@ +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 diff --git a/05/tcc-0.9.27/tests/tests2/10_pointer.c b/05/tcc-0.9.27/tests/tests2/10_pointer.c new file mode 100644 index 0000000..0177f4d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/10_pointer.c @@ -0,0 +1,40 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/10_pointer.expect b/05/tcc-0.9.27/tests/tests2/10_pointer.expect new file mode 100644 index 0000000..1e3c473 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/11_precedence.c b/05/tcc-0.9.27/tests/tests2/11_precedence.c new file mode 100644 index 0000000..db2049d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/11_precedence.c @@ -0,0 +1,40 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/11_precedence.expect b/05/tcc-0.9.27/tests/tests2/11_precedence.expect new file mode 100644 index 0000000..b692396 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/12_hashdefine.c b/05/tcc-0.9.27/tests/tests2/12_hashdefine.c new file mode 100644 index 0000000..5c521e0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/12_hashdefine.c @@ -0,0 +1,14 @@ +#include + +#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/05/tcc-0.9.27/tests/tests2/12_hashdefine.expect b/05/tcc-0.9.27/tests/tests2/12_hashdefine.expect new file mode 100644 index 0000000..99f2ed5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/12_hashdefine.expect @@ -0,0 +1,2 @@ +12 +12, 24, 36 diff --git a/05/tcc-0.9.27/tests/tests2/13_integer_literals.c b/05/tcc-0.9.27/tests/tests2/13_integer_literals.c new file mode 100644 index 0000000..7cee98b --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/13_integer_literals.c @@ -0,0 +1,20 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/13_integer_literals.expect b/05/tcc-0.9.27/tests/tests2/13_integer_literals.expect new file mode 100644 index 0000000..f5aca06 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/13_integer_literals.expect @@ -0,0 +1,5 @@ +24680 +342391 +2386092 +2386092 +1365 diff --git a/05/tcc-0.9.27/tests/tests2/14_if.c b/05/tcc-0.9.27/tests/tests2/14_if.c new file mode 100644 index 0000000..2bd2550 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/14_if.c @@ -0,0 +1,21 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/14_if.expect b/05/tcc-0.9.27/tests/tests2/14_if.expect new file mode 100644 index 0000000..c32c415 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/14_if.expect @@ -0,0 +1,2 @@ +a is true +b is false diff --git a/05/tcc-0.9.27/tests/tests2/15_recursion.c b/05/tcc-0.9.27/tests/tests2/15_recursion.c new file mode 100644 index 0000000..f79a00d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/15_recursion.c @@ -0,0 +1,21 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/15_recursion.expect b/05/tcc-0.9.27/tests/tests2/15_recursion.expect new file mode 100644 index 0000000..db47b28 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/15_recursion.expect @@ -0,0 +1,10 @@ +1 +2 +6 +24 +120 +720 +5040 +40320 +362880 +3628800 diff --git a/05/tcc-0.9.27/tests/tests2/16_nesting.c b/05/tcc-0.9.27/tests/tests2/16_nesting.c new file mode 100644 index 0000000..2b72cc0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/16_nesting.c @@ -0,0 +1,21 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/16_nesting.expect b/05/tcc-0.9.27/tests/tests2/16_nesting.expect new file mode 100644 index 0000000..5a3431e --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/17_enum.c b/05/tcc-0.9.27/tests/tests2/17_enum.c new file mode 100644 index 0000000..e2bc736 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/17_enum.c @@ -0,0 +1,72 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/17_enum.expect b/05/tcc-0.9.27/tests/tests2/17_enum.expect new file mode 100644 index 0000000..d453a61 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/18_include.c b/05/tcc-0.9.27/tests/tests2/18_include.c new file mode 100644 index 0000000..dbae3aa --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/18_include.c @@ -0,0 +1,12 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/18_include.expect b/05/tcc-0.9.27/tests/tests2/18_include.expect new file mode 100644 index 0000000..58c6d29 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/18_include.expect @@ -0,0 +1,3 @@ +including +included +done diff --git a/05/tcc-0.9.27/tests/tests2/18_include.h b/05/tcc-0.9.27/tests/tests2/18_include.h new file mode 100644 index 0000000..dc86080 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/18_include.h @@ -0,0 +1 @@ +printf("included\n"); diff --git a/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c b/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c new file mode 100644 index 0000000..aff65e5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c @@ -0,0 +1,28 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect b/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect new file mode 100644 index 0000000..0cf781b --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect @@ -0,0 +1,3 @@ +42 +b is not NULL +c is NULL diff --git a/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.c b/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.c new file mode 100644 index 0000000..825f778 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.c @@ -0,0 +1,24 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect b/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect new file mode 100644 index 0000000..5d1e5f5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect @@ -0,0 +1,6 @@ +12 +34 +0 +1 +1 +0 diff --git a/05/tcc-0.9.27/tests/tests2/21_char_array.c b/05/tcc-0.9.27/tests/tests2/21_char_array.c new file mode 100644 index 0000000..f22f527 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/21_char_array.c @@ -0,0 +1,33 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/21_char_array.expect b/05/tcc-0.9.27/tests/tests2/21_char_array.expect new file mode 100644 index 0000000..dbc6068 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/22_floating_point.c b/05/tcc-0.9.27/tests/tests2/22_floating_point.c new file mode 100644 index 0000000..e3491f5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/22_floating_point.c @@ -0,0 +1,50 @@ +#include +#include + +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/05/tcc-0.9.27/tests/tests2/22_floating_point.expect b/05/tcc-0.9.27/tests/tests2/22_floating_point.expect new file mode 100644 index 0000000..75ea3a7 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/23_type_coercion.c b/05/tcc-0.9.27/tests/tests2/23_type_coercion.c new file mode 100644 index 0000000..1fcc335 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/23_type_coercion.c @@ -0,0 +1,54 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/23_type_coercion.expect b/05/tcc-0.9.27/tests/tests2/23_type_coercion.expect new file mode 100644 index 0000000..d9076f0 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/24_math_library.c b/05/tcc-0.9.27/tests/tests2/24_math_library.c new file mode 100644 index 0000000..514a25f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/24_math_library.c @@ -0,0 +1,30 @@ +#define _ISOC99_SOURCE 1 + +#include +#include + +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/05/tcc-0.9.27/tests/tests2/24_math_library.expect b/05/tcc-0.9.27/tests/tests2/24_math_library.expect new file mode 100644 index 0000000..99f7299 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/25_quicksort.c b/05/tcc-0.9.27/tests/tests2/25_quicksort.c new file mode 100644 index 0000000..5cc08bd --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/25_quicksort.c @@ -0,0 +1,83 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/25_quicksort.expect b/05/tcc-0.9.27/tests/tests2/25_quicksort.expect new file mode 100644 index 0000000..2d39cd3 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/26_character_constants.c b/05/tcc-0.9.27/tests/tests2/26_character_constants.c new file mode 100644 index 0000000..95c4423 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/26_character_constants.c @@ -0,0 +1,17 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/26_character_constants.expect b/05/tcc-0.9.27/tests/tests2/26_character_constants.expect new file mode 100644 index 0000000..8f8bfa4 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/26_character_constants.expect @@ -0,0 +1,8 @@ +1 +8 +64 +1 +14 +16 +64 +test @ diff --git a/05/tcc-0.9.27/tests/tests2/27_sizeof.c b/05/tcc-0.9.27/tests/tests2/27_sizeof.c new file mode 100644 index 0000000..5ae0ede --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/27_sizeof.c @@ -0,0 +1,18 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/27_sizeof.expect b/05/tcc-0.9.27/tests/tests2/27_sizeof.expect new file mode 100644 index 0000000..a47ea3a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/27_sizeof.expect @@ -0,0 +1,4 @@ +1 +4 +8 +4 diff --git a/05/tcc-0.9.27/tests/tests2/28_strings.c b/05/tcc-0.9.27/tests/tests2/28_strings.c new file mode 100644 index 0000000..2db2298 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/28_strings.c @@ -0,0 +1,45 @@ +#include +#include + +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/05/tcc-0.9.27/tests/tests2/28_strings.expect b/05/tcc-0.9.27/tests/tests2/28_strings.expect new file mode 100644 index 0000000..fd9217a --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/29_array_address.c b/05/tcc-0.9.27/tests/tests2/29_array_address.c new file mode 100644 index 0000000..bda5ddd --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/29_array_address.c @@ -0,0 +1,13 @@ +#include +#include + +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/05/tcc-0.9.27/tests/tests2/29_array_address.expect b/05/tcc-0.9.27/tests/tests2/29_array_address.expect new file mode 100644 index 0000000..9bc8683 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/29_array_address.expect @@ -0,0 +1 @@ +bcdef diff --git a/05/tcc-0.9.27/tests/tests2/30_hanoi.c b/05/tcc-0.9.27/tests/tests2/30_hanoi.c new file mode 100644 index 0000000..7c0893b --- /dev/null +++ b/05/tcc-0.9.27/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 +#include + +#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 + +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/05/tcc-0.9.27/tests/tests2/31_args.expect b/05/tcc-0.9.27/tests/tests2/31_args.expect new file mode 100644 index 0000000..8c60bfc --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/32_led.c b/05/tcc-0.9.27/tests/tests2/32_led.c new file mode 100644 index 0000000..5596cbf --- /dev/null +++ b/05/tcc-0.9.27/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 +#include + +#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/05/tcc-0.9.27/tests/tests2/32_led.expect b/05/tcc-0.9.27/tests/tests2/32_led.expect new file mode 100644 index 0000000..c53b58a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/32_led.expect @@ -0,0 +1,4 @@ + _ _ _ _ + | _| _| |_| |_ |_ | + | |_ _| | _| |_| | + diff --git a/05/tcc-0.9.27/tests/tests2/33_ternary_op.c b/05/tcc-0.9.27/tests/tests2/33_ternary_op.c new file mode 100644 index 0000000..8579b50 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/33_ternary_op.c @@ -0,0 +1,15 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/33_ternary_op.expect b/05/tcc-0.9.27/tests/tests2/33_ternary_op.expect new file mode 100644 index 0000000..45ea507 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/33_ternary_op.expect @@ -0,0 +1,10 @@ +0 +1 +4 +9 +16 +15 +18 +21 +24 +27 diff --git a/05/tcc-0.9.27/tests/tests2/34_array_assignment.c b/05/tcc-0.9.27/tests/tests2/34_array_assignment.c new file mode 100644 index 0000000..5885c97 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/34_array_assignment.c @@ -0,0 +1,23 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/34_array_assignment.expect b/05/tcc-0.9.27/tests/tests2/34_array_assignment.expect new file mode 100644 index 0000000..9736bf5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/34_array_assignment.expect @@ -0,0 +1,2 @@ +12 23 34 45 +12 23 34 45 diff --git a/05/tcc-0.9.27/tests/tests2/35_sizeof.c b/05/tcc-0.9.27/tests/tests2/35_sizeof.c new file mode 100644 index 0000000..672e87e --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/35_sizeof.c @@ -0,0 +1,14 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/35_sizeof.expect b/05/tcc-0.9.27/tests/tests2/35_sizeof.expect new file mode 100644 index 0000000..534fb83 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/35_sizeof.expect @@ -0,0 +1,2 @@ +1 1 +2 2 diff --git a/05/tcc-0.9.27/tests/tests2/36_array_initialisers.c b/05/tcc-0.9.27/tests/tests2/36_array_initialisers.c new file mode 100644 index 0000000..1bc8ee0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/36_array_initialisers.c @@ -0,0 +1,21 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/36_array_initialisers.expect b/05/tcc-0.9.27/tests/tests2/36_array_initialisers.expect new file mode 100644 index 0000000..3ac6c77 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/37_sprintf.c b/05/tcc-0.9.27/tests/tests2/37_sprintf.c new file mode 100644 index 0000000..1dd1dce --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/37_sprintf.c @@ -0,0 +1,17 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/37_sprintf.expect b/05/tcc-0.9.27/tests/tests2/37_sprintf.expect new file mode 100644 index 0000000..a643da8 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/38_multiple_array_index.c b/05/tcc-0.9.27/tests/tests2/38_multiple_array_index.c new file mode 100644 index 0000000..4e1868e --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/38_multiple_array_index.c @@ -0,0 +1,32 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect b/05/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect new file mode 100644 index 0000000..747ad75 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/39_typedef.c b/05/tcc-0.9.27/tests/tests2/39_typedef.c new file mode 100644 index 0000000..da73f71 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/39_typedef.c @@ -0,0 +1,65 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/39_typedef.expect b/05/tcc-0.9.27/tests/tests2/39_typedef.expect new file mode 100644 index 0000000..b9050a9 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/39_typedef.expect @@ -0,0 +1,3 @@ +1 +12,34 +12,34 diff --git a/05/tcc-0.9.27/tests/tests2/40_stdio.c b/05/tcc-0.9.27/tests/tests2/40_stdio.c new file mode 100644 index 0000000..b986093 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/40_stdio.c @@ -0,0 +1,52 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/40_stdio.expect b/05/tcc-0.9.27/tests/tests2/40_stdio.expect new file mode 100644 index 0000000..e08167a --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/41_hashif.c b/05/tcc-0.9.27/tests/tests2/41_hashif.c new file mode 100644 index 0000000..cb37b9e --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/41_hashif.c @@ -0,0 +1,85 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/41_hashif.expect b/05/tcc-0.9.27/tests/tests2/41_hashif.expect new file mode 100644 index 0000000..5fd414b --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/41_hashif.expect @@ -0,0 +1,6 @@ +#include test +b +g +i +p +r diff --git a/05/tcc-0.9.27/tests/tests2/42_function_pointer.c b/05/tcc-0.9.27/tests/tests2/42_function_pointer.c new file mode 100644 index 0000000..697bd79 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/42_function_pointer.c @@ -0,0 +1,22 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/42_function_pointer.expect b/05/tcc-0.9.27/tests/tests2/42_function_pointer.expect new file mode 100644 index 0000000..6c8b6ce --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/42_function_pointer.expect @@ -0,0 +1,2 @@ +yo 24 +42 diff --git a/05/tcc-0.9.27/tests/tests2/43_void_param.c b/05/tcc-0.9.27/tests/tests2/43_void_param.c new file mode 100644 index 0000000..de17098 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/43_void_param.c @@ -0,0 +1,15 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/43_void_param.expect b/05/tcc-0.9.27/tests/tests2/43_void_param.expect new file mode 100644 index 0000000..092bfb9 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/43_void_param.expect @@ -0,0 +1 @@ +yo diff --git a/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.c b/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.c new file mode 100644 index 0000000..f38664f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.c @@ -0,0 +1,17 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect b/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect new file mode 100644 index 0000000..231ccc0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect @@ -0,0 +1 @@ +it's all good diff --git a/05/tcc-0.9.27/tests/tests2/45_empty_for.c b/05/tcc-0.9.27/tests/tests2/45_empty_for.c new file mode 100644 index 0000000..7cef513 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/45_empty_for.c @@ -0,0 +1,18 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/45_empty_for.expect b/05/tcc-0.9.27/tests/tests2/45_empty_for.expect new file mode 100644 index 0000000..f00c965 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/45_empty_for.expect @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/05/tcc-0.9.27/tests/tests2/46_grep.c b/05/tcc-0.9.27/tests/tests2/46_grep.c new file mode 100644 index 0000000..049dfb1 --- /dev/null +++ b/05/tcc-0.9.27/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 +#include +#include // 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/05/tcc-0.9.27/tests/tests2/46_grep.expect b/05/tcc-0.9.27/tests/tests2/46_grep.expect new file mode 100644 index 0000000..e8a6791 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/47_switch_return.c b/05/tcc-0.9.27/tests/tests2/47_switch_return.c new file mode 100644 index 0000000..1ec7924 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/47_switch_return.c @@ -0,0 +1,24 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/47_switch_return.expect b/05/tcc-0.9.27/tests/tests2/47_switch_return.expect new file mode 100644 index 0000000..b6deb7e --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/47_switch_return.expect @@ -0,0 +1,4 @@ +1 +2 +out +3 diff --git a/05/tcc-0.9.27/tests/tests2/48_nested_break.c b/05/tcc-0.9.27/tests/tests2/48_nested_break.c new file mode 100644 index 0000000..5bc5ba4 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/48_nested_break.c @@ -0,0 +1,26 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/48_nested_break.expect b/05/tcc-0.9.27/tests/tests2/48_nested_break.expect new file mode 100644 index 0000000..573541a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/48_nested_break.expect @@ -0,0 +1 @@ +0 diff --git a/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c b/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c new file mode 100644 index 0000000..0cbe57d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c @@ -0,0 +1,23 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect b/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect new file mode 100644 index 0000000..1da66db --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect @@ -0,0 +1 @@ +12.340000, 56.780000 diff --git a/05/tcc-0.9.27/tests/tests2/50_logical_second_arg.c b/05/tcc-0.9.27/tests/tests2/50_logical_second_arg.c new file mode 100644 index 0000000..ddec08c --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/50_logical_second_arg.c @@ -0,0 +1,29 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect b/05/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect new file mode 100644 index 0000000..d6174ae --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/51_static.c b/05/tcc-0.9.27/tests/tests2/51_static.c new file mode 100644 index 0000000..d6c0917 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/51_static.c @@ -0,0 +1,30 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/51_static.expect b/05/tcc-0.9.27/tests/tests2/51_static.expect new file mode 100644 index 0000000..18224fa --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/51_static.expect @@ -0,0 +1,8 @@ +1234 +4567 +4568 +4569 +4570 +1234 +8901 +2345 diff --git a/05/tcc-0.9.27/tests/tests2/52_unnamed_enum.c b/05/tcc-0.9.27/tests/tests2/52_unnamed_enum.c new file mode 100644 index 0000000..d0395b2 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/52_unnamed_enum.c @@ -0,0 +1,27 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect b/05/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect new file mode 100644 index 0000000..84f2ac8 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/54_goto.c b/05/tcc-0.9.27/tests/tests2/54_goto.c new file mode 100644 index 0000000..2e151bb --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/54_goto.c @@ -0,0 +1,56 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/54_goto.expect b/05/tcc-0.9.27/tests/tests2/54_goto.expect new file mode 100644 index 0000000..8e553fa --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/55_lshift_type.c b/05/tcc-0.9.27/tests/tests2/55_lshift_type.c new file mode 100644 index 0000000..aa3e51a --- /dev/null +++ b/05/tcc-0.9.27/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 . + +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 + +#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/05/tcc-0.9.27/tests/tests2/55_lshift_type.expect b/05/tcc-0.9.27/tests/tests2/55_lshift_type.expect new file mode 100644 index 0000000..8523767 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/55_lshift_type.expect @@ -0,0 +1 @@ +0 test(s) failed diff --git a/05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c b/05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c new file mode 100644 index 0000000..0028caf --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect b/05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect new file mode 100644 index 0000000..ed6a690 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/64_macro_nesting.c b/05/tcc-0.9.27/tests/tests2/64_macro_nesting.c new file mode 100644 index 0000000..676e5d3 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/64_macro_nesting.c @@ -0,0 +1,12 @@ +#include // 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/05/tcc-0.9.27/tests/tests2/64_macro_nesting.expect b/05/tcc-0.9.27/tests/tests2/64_macro_nesting.expect new file mode 100644 index 0000000..d81cc07 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/64_macro_nesting.expect @@ -0,0 +1 @@ +42 diff --git a/05/tcc-0.9.27/tests/tests2/67_macro_concat.c b/05/tcc-0.9.27/tests/tests2/67_macro_concat.c new file mode 100644 index 0000000..c580d3a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/67_macro_concat.c @@ -0,0 +1,14 @@ +#include + +#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/05/tcc-0.9.27/tests/tests2/67_macro_concat.expect b/05/tcc-0.9.27/tests/tests2/67_macro_concat.expect new file mode 100644 index 0000000..8386c2d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/67_macro_concat.expect @@ -0,0 +1,2 @@ +jim: 21, bob: 42 +jim: 63 diff --git a/05/tcc-0.9.27/tests/tests2/70_floating_point_literals.c b/05/tcc-0.9.27/tests/tests2/70_floating_point_literals.c new file mode 100644 index 0000000..012fb4f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/70_floating_point_literals.c @@ -0,0 +1,77 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect b/05/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect new file mode 100644 index 0000000..7eb1efb --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c b/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c new file mode 100644 index 0000000..f0d3511 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c @@ -0,0 +1,9 @@ +#include + +#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/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect b/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect new file mode 100644 index 0000000..98d9bcb --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect @@ -0,0 +1 @@ +17 diff --git a/05/tcc-0.9.27/tests/tests2/72_long_long_constant.c b/05/tcc-0.9.27/tests/tests2/72_long_long_constant.c new file mode 100644 index 0000000..6608213 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/72_long_long_constant.c @@ -0,0 +1,19 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/72_long_long_constant.expect b/05/tcc-0.9.27/tests/tests2/72_long_long_constant.expect new file mode 100644 index 0000000..dda9e66 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/72_long_long_constant.expect @@ -0,0 +1 @@ +long long constant test ok. diff --git a/05/tcc-0.9.27/tests/tests2/73_arm64.c b/05/tcc-0.9.27/tests/tests2/73_arm64.c new file mode 100644 index 0000000..8de61b3 --- /dev/null +++ b/05/tcc-0.9.27/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 +#include +#include + +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/05/tcc-0.9.27/tests/tests2/73_arm64.expect b/05/tcc-0.9.27/tests/tests2/73_arm64.expect new file mode 100644 index 0000000..7bdebd3 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c b/05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c new file mode 100644 index 0000000..234e3c4 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c @@ -0,0 +1,33 @@ +#include + +/* 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/05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect b/05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect new file mode 100644 index 0000000..2b75aa5 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c b/05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c new file mode 100644 index 0000000..c5fcf99 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c @@ -0,0 +1,41 @@ +#include + +#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/05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect b/05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect new file mode 100644 index 0000000..4a20a52 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.c b/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.c new file mode 100644 index 0000000..d38e0bf --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.c @@ -0,0 +1,30 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect b/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect new file mode 100644 index 0000000..d8a5530 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect @@ -0,0 +1,5 @@ +abort = 111 +abort = 222 +abort = 333 +abort = 222 +abort = 111 diff --git a/05/tcc-0.9.27/tests/tests2/78_vla_label.c b/05/tcc-0.9.27/tests/tests2/78_vla_label.c new file mode 100644 index 0000000..4096495 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/78_vla_label.c @@ -0,0 +1,45 @@ +#include + +/* 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/05/tcc-0.9.27/tests/tests2/78_vla_label.expect b/05/tcc-0.9.27/tests/tests2/78_vla_label.expect new file mode 100644 index 0000000..3f4063b --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/78_vla_label.expect @@ -0,0 +1,6 @@ +boom! +boom! +11 +12 +0 +1 diff --git a/05/tcc-0.9.27/tests/tests2/79_vla_continue.c b/05/tcc-0.9.27/tests/tests2/79_vla_continue.c new file mode 100644 index 0000000..91215c9 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/79_vla_continue.c @@ -0,0 +1,116 @@ +#include + +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 +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/05/tcc-0.9.27/tests/tests2/80_flexarray.expect b/05/tcc-0.9.27/tests/tests2/80_flexarray.expect new file mode 100644 index 0000000..e69de29 diff --git a/05/tcc-0.9.27/tests/tests2/81_types.c b/05/tcc-0.9.27/tests/tests2/81_types.c new file mode 100644 index 0000000..fd6d71b --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/81_types.expect b/05/tcc-0.9.27/tests/tests2/81_types.expect new file mode 100644 index 0000000..e69de29 diff --git a/05/tcc-0.9.27/tests/tests2/82_attribs_position.c b/05/tcc-0.9.27/tests/tests2/82_attribs_position.c new file mode 100644 index 0000000..7c9f987 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/82_attribs_position.expect b/05/tcc-0.9.27/tests/tests2/82_attribs_position.expect new file mode 100644 index 0000000..e69de29 diff --git a/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c b/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c new file mode 100644 index 0000000..1f86095 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c @@ -0,0 +1,9 @@ +#include +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/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect b/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect new file mode 100644 index 0000000..1553f5f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect @@ -0,0 +1,2 @@ +привет=0.1 +Lefèvre=2 diff --git a/05/tcc-0.9.27/tests/tests2/84_hex-float.c b/05/tcc-0.9.27/tests/tests2/84_hex-float.c new file mode 100644 index 0000000..0ef09bf --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/84_hex-float.expect b/05/tcc-0.9.27/tests/tests2/84_hex-float.expect new file mode 100644 index 0000000..2175385 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/84_hex-float.expect @@ -0,0 +1 @@ +n+1 = 15 diff --git a/05/tcc-0.9.27/tests/tests2/85_asm-outside-function.c b/05/tcc-0.9.27/tests/tests2/85_asm-outside-function.c new file mode 100644 index 0000000..dc5639a --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect b/05/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect new file mode 100644 index 0000000..dcf02b2 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect @@ -0,0 +1 @@ +okay diff --git a/05/tcc-0.9.27/tests/tests2/86_memory-model.c b/05/tcc-0.9.27/tests/tests2/86_memory-model.c new file mode 100644 index 0000000..744c3e2 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/86_memory-model.c @@ -0,0 +1,38 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/86_memory-model.expect b/05/tcc-0.9.27/tests/tests2/86_memory-model.expect new file mode 100644 index 0000000..7326d96 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/86_memory-model.expect @@ -0,0 +1 @@ +Ok diff --git a/05/tcc-0.9.27/tests/tests2/87_dead_code.c b/05/tcc-0.9.27/tests/tests2/87_dead_code.c new file mode 100644 index 0000000..98d4566 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/87_dead_code.expect b/05/tcc-0.9.27/tests/tests2/87_dead_code.expect new file mode 100644 index 0000000..0b3ec1d --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/88_codeopt.c b/05/tcc-0.9.27/tests/tests2/88_codeopt.c new file mode 100644 index 0000000..647626f --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/88_codeopt.expect b/05/tcc-0.9.27/tests/tests2/88_codeopt.expect new file mode 100644 index 0000000..439edfd --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/88_codeopt.expect @@ -0,0 +1,2 @@ +okay +okay diff --git a/05/tcc-0.9.27/tests/tests2/89_nocode_wanted.c b/05/tcc-0.9.27/tests/tests2/89_nocode_wanted.c new file mode 100644 index 0000000..73e0a4b --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect b/05/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect new file mode 100644 index 0000000..c44d4ea --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/90_struct-init.c b/05/tcc-0.9.27/tests/tests2/90_struct-init.c new file mode 100644 index 0000000..d931e23 --- /dev/null +++ b/05/tcc-0.9.27/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 +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/05/tcc-0.9.27/tests/tests2/90_struct-init.expect b/05/tcc-0.9.27/tests/tests2/90_struct-init.expect new file mode 100644 index 0000000..e366121 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c b/05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c new file mode 100644 index 0000000..bf07915 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect b/05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect new file mode 100644 index 0000000..f91e4b4 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect @@ -0,0 +1 @@ +data = "0123-5678" diff --git a/05/tcc-0.9.27/tests/tests2/92_enum_bitfield.c b/05/tcc-0.9.27/tests/tests2/92_enum_bitfield.c new file mode 100644 index 0000000..bb6dc35 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/92_enum_bitfield.expect b/05/tcc-0.9.27/tests/tests2/92_enum_bitfield.expect new file mode 100644 index 0000000..e69de29 diff --git a/05/tcc-0.9.27/tests/tests2/93_integer_promotion.c b/05/tcc-0.9.27/tests/tests2/93_integer_promotion.c new file mode 100644 index 0000000..a1176fc --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/93_integer_promotion.expect b/05/tcc-0.9.27/tests/tests2/93_integer_promotion.expect new file mode 100644 index 0000000..34b9c14 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/94_generic.c b/05/tcc-0.9.27/tests/tests2/94_generic.c new file mode 100644 index 0000000..d7fb5fc --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/94_generic.c @@ -0,0 +1,64 @@ +#include + +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/05/tcc-0.9.27/tests/tests2/94_generic.expect b/05/tcc-0.9.27/tests/tests2/94_generic.expect new file mode 100644 index 0000000..9aa9275 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/95_bitfields.c b/05/tcc-0.9.27/tests/tests2/95_bitfields.c new file mode 100644 index 0000000..f025c57 --- /dev/null +++ b/05/tcc-0.9.27/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 +#include +/* 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/05/tcc-0.9.27/tests/tests2/95_bitfields.expect b/05/tcc-0.9.27/tests/tests2/95_bitfields.expect new file mode 100644 index 0000000..6a8fd9a --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/95_bitfields_ms.c b/05/tcc-0.9.27/tests/tests2/95_bitfields_ms.c new file mode 100644 index 0000000..b196fbd --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/95_bitfields_ms.c @@ -0,0 +1,2 @@ +#define MS_BITFIELDS 1 +#include "95_bitfields.c" diff --git a/05/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect b/05/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect new file mode 100644 index 0000000..8ccafb7 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/96_nodata_wanted.c b/05/tcc-0.9.27/tests/tests2/96_nodata_wanted.c new file mode 100644 index 0000000..cc211d3 --- /dev/null +++ b/05/tcc-0.9.27/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 +/* 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/05/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect b/05/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect new file mode 100644 index 0000000..2749109 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c b/05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c new file mode 100644 index 0000000..96fbab0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c @@ -0,0 +1,12 @@ +// this file contains BMP chars encoded in UTF-8 +#include +#include + +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/05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect b/05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect new file mode 100644 index 0000000..9a1593c --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/98_al_ax_extend.c b/05/tcc-0.9.27/tests/tests2/98_al_ax_extend.c new file mode 100644 index 0000000..9b4e02f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/98_al_ax_extend.c @@ -0,0 +1,41 @@ +#include +#include +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/05/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect b/05/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect new file mode 100644 index 0000000..c5752e8 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/99_fastcall.c b/05/tcc-0.9.27/tests/tests2/99_fastcall.c new file mode 100644 index 0000000..ee4b67d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/99_fastcall.c @@ -0,0 +1,276 @@ +#include +#include + +#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/05/tcc-0.9.27/tests/tests2/99_fastcall.expect b/05/tcc-0.9.27/tests/tests2/99_fastcall.expect new file mode 100644 index 0000000..3835d63 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/99_fastcall.expect @@ -0,0 +1 @@ +TEST OK diff --git a/05/tcc-0.9.27/tests/tests2/LICENSE b/05/tcc-0.9.27/tests/tests2/LICENSE new file mode 100644 index 0000000..b08a652 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/tests2/Makefile b/05/tcc-0.9.27/tests/tests2/Makefile new file mode 100644 index 0000000..190b2d9 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/tests/vla_test.c b/05/tcc-0.9.27/tests/vla_test.c new file mode 100644 index 0000000..3616c46 --- /dev/null +++ b/05/tcc-0.9.27/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 +#include +#include + +#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/05/tcc-0.9.27/texi2pod.pl b/05/tcc-0.9.27/texi2pod.pl new file mode 100755 index 0000000..d86e176 --- /dev/null +++ b/05/tcc-0.9.27/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/&/&/g; + s/\@\{/{/g; + s/\@\}/}/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//>/g; + } else { + s//>/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\<$1\>\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)\{([^\},]*)\}/<B<$1>>/g; + s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g; + s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g; + + # Turn B blah> into B I B to + # match Texinfo semantics of @emph inside @samp. Also handle @r + # inside bold. + s/<//g; + 1 while s/B<((?:[^<>]|I<[^<>]*>)*)R<([^>]*)>/B<$1>${2}B]*)I<([^>]+)>/B<$1>I<$2>B]*)B<([^>]+)>/I<$1>B<$2>I//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/</E/g; + s/>/E/g; + s/{/\{/g; + s/}/\}/g; + s/&at;/\@/g; + s/&/&/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/05/tcc-0.9.27/time.h b/05/tcc-0.9.27/time.h new file mode 100644 index 0000000..8207156 --- /dev/null +++ b/05/tcc-0.9.27/time.h @@ -0,0 +1,293 @@ +#ifndef _TIME_H +#define _TIME_H + +#include +#define CLK_TCK 1000000000 // doesnt matter; clock() will always fail. + +typedef long clock_t; + +clock_t clock(void) { + // "If the processor time used is not available or its value cannot be represented, the function returns the value (clock_t)-1." C89 § 4.12.2.1 + return -1; +} + +double difftime(time_t time1, time_t time0) { + return (double)(time1 - time0); +} + +time_t time(time_t *timer) { + struct timespec ts = {0}; + if (clock_gettime(CLOCK_REALTIME, &ts) != 0) return -1; + if (timer) *timer = ts.tv_sec; + return ts.tv_sec; +} + + +// @NONSTANDARD(except in UTC+0): we don't support local time in timezones other than UTC+0. + +struct tm { + int tm_sec; /* seconds after the minute --- [0, 60] */ + int tm_min; /* minutes after the hour --- [0, 59] */ + int tm_hour; /* hours since midnight --- [0, 23] */ + int tm_mday; /* day of the month --- [1, 31] */ + int tm_mon; /* months since January --- [0, 11] */ + int tm_year; /* years since 1900 */ + int tm_wday; /* days since Sunday --- [0, 6] */ + int tm_yday; /* days since January 1 --- [0, 365] */ + int tm_isdst; /* Daylight Saving Time flag */ +}; + + +void _gmtime_r(const time_t *timer, struct tm *tm) { + time_t t = *timer; + int year = 1970; + int days = t / 86400; + int leap_year; + int month; + + tm->tm_isdst = 0; + tm->tm_wday = (4 + days) % 7; // jan 1 1970 was a thursday + while (1) { + leap_year = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); + int ydays = leap_year ? 366 : 365; + if (days < ydays) break; + days -= ydays; + ++year; + } + tm->tm_year = year - 1900; + tm->tm_yday = days; + for (month = 0; month < 12; ++month) { + int mdays; + switch (month) { + case 0: case 2: case 4: case 6: case 7: case 9: case 11: + mdays = 31; + break; + case 3: case 5: case 8: case 10: + mdays = 30; + break; + case 1: + mdays = 28 + leap_year; + break; + } + if (days < mdays) break; + days -= mdays; + } + tm->tm_mday = days + 1; + tm->tm_mon = month; + t %= 86400; + tm->tm_hour = t / 3600; + t %= 3600; + tm->tm_min = t / 60; + tm->tm_sec = t % 60; +} + +time_t mktime(struct tm *tm) { + // @NONSTANDARD-ish. + // not implementing this -- note that the implementation has to support tm_* values + // outside of their proper ranges. + return (time_t)-1; + +} + +struct tm *gmtime(const time_t *timer) { + static struct tm result; + _gmtime_r(timer, &result); + return &result; +} + +struct tm *localtime(const time_t *timer) { + static struct tm result; + _gmtime_r(timer, &result); + return &result; +} + +static const char _wday_name[7][4] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; +static const char _weekday_name[7][16] = { + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" +}; +static const char _mon_name[12][4] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; +static const char _month_name[12][16] = { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" +}; + +char *asctime(const struct tm *timeptr) { + // lifted from the (draft of the) C standard + static char result[32]; + sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n", + _wday_name[timeptr->tm_wday], + _mon_name[timeptr->tm_mon], + timeptr->tm_mday, timeptr->tm_hour, + timeptr->tm_min, timeptr->tm_sec, + 1900 + timeptr->tm_year); + return result; +} + +char *ctime(const time_t *timer) { + return asctime(localtime(timer)); +} + +size_t strftime(char *s, size_t maxsize, const char *format, const struct tm *tm) { + size_t n = 0, l; + char *name; + + while (*format) { + if (*format == '%') { + ++format; + int c = *format++; + switch (c) { + case 'a': + if (n+4 >= maxsize) return 0; + strcpy(s, _wday_name[tm->tm_wday]); + s += 3; + n += 3; + break; + case 'A': + name = _weekday_name[tm->tm_wday]; + l = strlen(name); + if (n+l+1 >= maxsize) return 0; + strcpy(s, name); + s += l; + n += l; + break; + case 'b': + if (n+4 >= maxsize) return 0; + strcpy(s, _mon_name[tm->tm_mon]); + s += 3; + n += 3; + break; + case 'B': + name = _month_name[tm->tm_mon]; + l = strlen(name); + if (n+l+1 >= maxsize) return 0; + strcpy(s, name); + s += l; + n += l; + break; + case 'c': + if (n+32 >= maxsize) return 0; + sprintf(s, "%s %02d %s %d %02d:%02d:%02d %s UTC", + _wday_name[tm->tm_wday], tm->tm_mday, _mon_name[tm->tm_mon], + 1900+tm->tm_year, (tm->tm_hour + 11) % 12 + 1, tm->tm_min, tm->tm_sec, + tm->tm_hour >= 12 ? "PM" : "AM"); + s += 31; + n += 31; + break; + case 'd': + if (n+3 >= maxsize) return 0; + sprintf(s, "%02d", tm->tm_mday); + s += 2; + n += 2; + break; + case 'H': + if (n+3 >= maxsize) return 0; + sprintf(s, "%02d", tm->tm_hour); + s += 2; + n += 2; + break; + case 'I': + if (n+3 >= maxsize) return 0; + sprintf(s, "%02d", (tm->tm_hour + 11) % 12 + 1); + s += 2; + n += 2; + break; + case 'j': + if (n+4 >= maxsize) return 0; + sprintf(s, "%03d", tm->tm_yday + 1); + s += 3; + n += 3; + break; + case 'm': + if (n+3 >= maxsize) return 0; + sprintf(s, "%02d", tm->tm_mon + 1); + s += 2; + n += 2; + break; + case 'M': + if (n+3 >= maxsize) return 0; + sprintf(s, "%02d", tm->tm_min); + s += 2; + n += 2; + break; + case 'p': + if (n+3 >= maxsize) return 0; + sprintf(s, "%s", tm->tm_hour >= 12 ? "PM" : "AM"); + s += 2; + n += 2; + break; + case 'S': + if (n+3 >= maxsize) return 0; + sprintf(s, "%02d", tm->tm_sec); + s += 2; + n += 2; + break; + case 'w': + if (n+2 >= maxsize) return 0; + sprintf(s, "%d", tm->tm_wday); + s += 1; + n += 1; + break; + case 'x': + if (n+16 >= maxsize) return 0; + sprintf(s, "%s %02d %s %d", + _wday_name[tm->tm_wday], tm->tm_mday, _mon_name[tm->tm_mon], + 1900+tm->tm_year); + s += 15; + n += 15; + break; + case 'X': + if (n+16 >= maxsize) return 0; + sprintf(s, "%02d:%02d:%02d %s UTC", + (tm->tm_hour + 11) % 12 + 1, tm->tm_min, tm->tm_sec, + tm->tm_hour >= 12 ? "PM" : "AM"); + s += 15; + n += 15; + break; + case 'y': + if (n+3 >= maxsize) return 0; + sprintf(s, "%02d", tm->tm_year % 100); + s += 2; + n += 2; + break; + case 'Y': + if (n+5 >= maxsize) return 0; + sprintf(s, "%d", tm->tm_year + 1900); + s += 4; + n += 4; + break; + case 'Z': + if (n+4 >= maxsize) return 0; + strcpy(s, "UTC"); + s += 3; + n += 3; + break; + case '%': + if (n >= maxsize) return 0; + *s++ = '%'; + n += 1; + break; + case 'U': // WEEK NUMBER OF THE YEAR? WHO GIVES A SHIT? + case 'W': // WEEK NUMBER OF THE YEAR MONDAY-BASED EDITION. IF YOU DIDNT ALREADY GET ENOUGH WEEK NUMBERS. FUCK YOU + default: + fprintf(stderr, "Bad strftime format.\n"); + abort(); + + } + } else { + if (n >= maxsize) return 0; + *s++ = *format++; + n += 1; + } + } + if (n >= maxsize) return 0; + *s = 0; + #undef _Push_str + return n; +} + +#endif // _TIME_H diff --git a/05/tcc-0.9.27/win32/build-tcc.bat b/05/tcc-0.9.27/win32/build-tcc.bat new file mode 100755 index 0000000..913b068 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/examples/dll.c b/05/tcc-0.9.27/win32/examples/dll.c new file mode 100644 index 0000000..052a056 --- /dev/null +++ b/05/tcc-0.9.27/win32/examples/dll.c @@ -0,0 +1,13 @@ +//+--------------------------------------------------------------------------- +// +// dll.c - Windows DLL example - dynamically linked part +// + +#include + +__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/05/tcc-0.9.27/win32/examples/fib.c b/05/tcc-0.9.27/win32/examples/fib.c new file mode 100644 index 0000000..8da26bc --- /dev/null +++ b/05/tcc-0.9.27/win32/examples/fib.c @@ -0,0 +1,24 @@ +#include +#include // 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/05/tcc-0.9.27/win32/examples/hello_dll.c b/05/tcc-0.9.27/win32/examples/hello_dll.c new file mode 100644 index 0000000..4813c5b --- /dev/null +++ b/05/tcc-0.9.27/win32/examples/hello_dll.c @@ -0,0 +1,20 @@ +//+--------------------------------------------------------------------------- +// +// HELLO_DLL.C - Windows DLL example - main application part +// + +#include + +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/05/tcc-0.9.27/win32/examples/hello_win.c b/05/tcc-0.9.27/win32/examples/hello_win.c new file mode 100644 index 0000000..96546e4 --- /dev/null +++ b/05/tcc-0.9.27/win32/examples/hello_win.c @@ -0,0 +1,163 @@ +//+--------------------------------------------------------------------------- +// +// HELLO_WIN.C - Windows GUI 'Hello World!' Example +// +//+--------------------------------------------------------------------------- + +#include + +#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/05/tcc-0.9.27/win32/include/_mingw.h b/05/tcc-0.9.27/win32/include/_mingw.h new file mode 100644 index 0000000..2fc9798 --- /dev/null +++ b/05/tcc-0.9.27/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 +#include + +#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/05/tcc-0.9.27/win32/include/assert.h b/05/tcc-0.9.27/win32/include/assert.h new file mode 100644 index 0000000..466d457 --- /dev/null +++ b/05/tcc-0.9.27/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 +#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/05/tcc-0.9.27/win32/include/conio.h b/05/tcc-0.9.27/win32/include/conio.h new file mode 100644 index 0000000..39f779e --- /dev/null +++ b/05/tcc-0.9.27/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 + +#endif diff --git a/05/tcc-0.9.27/win32/include/ctype.h b/05/tcc-0.9.27/win32/include/ctype.h new file mode 100644 index 0000000..7e90100 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/dir.h b/05/tcc-0.9.27/win32/include/dir.h new file mode 100644 index 0000000..f38f750 --- /dev/null +++ b/05/tcc-0.9.27/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 + * Mumit Khan + * + * 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 + diff --git a/05/tcc-0.9.27/win32/include/direct.h b/05/tcc-0.9.27/win32/include/direct.h new file mode 100644 index 0000000..99ce69d --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/dirent.h b/05/tcc-0.9.27/win32/include/dirent.h new file mode 100644 index 0000000..cd31f59 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/dos.h b/05/tcc-0.9.27/win32/include/dos.h new file mode 100644 index 0000000..294e8fe --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/errno.h b/05/tcc-0.9.27/win32/include/errno.h new file mode 100644 index 0000000..c2df015 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/excpt.h b/05/tcc-0.9.27/win32/include/excpt.h new file mode 100644 index 0000000..26cc943 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/fcntl.h b/05/tcc-0.9.27/win32/include/fcntl.h new file mode 100644 index 0000000..9202b08 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/fenv.h b/05/tcc-0.9.27/win32/include/fenv.h new file mode 100644 index 0000000..258f3a5 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/inttypes.h b/05/tcc-0.9.27/win32/include/inttypes.h new file mode 100644 index 0000000..7360091 --- /dev/null +++ b/05/tcc-0.9.27/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 */ + +#ifndef _INTTYPES_H_ +#define _INTTYPES_H_ + +#include <_mingw.h> +#include +#define __need_wchar_t +#include + +#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/05/tcc-0.9.27/win32/include/io.h b/05/tcc-0.9.27/win32/include/io.h new file mode 100644 index 0000000..e2aeec3 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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 +#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 + +#endif /* End _IO_H_ */ + diff --git a/05/tcc-0.9.27/win32/include/limits.h b/05/tcc-0.9.27/win32/include/limits.h new file mode 100644 index 0000000..fafb04a --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/locale.h b/05/tcc-0.9.27/win32/include/locale.h new file mode 100644 index 0000000..686aa9b --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/malloc.h b/05/tcc-0.9.27/win32/include/malloc.h new file mode 100644 index 0000000..fc783a8 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/math.h b/05/tcc-0.9.27/win32/include/math.h new file mode 100644 index 0000000..74add20 --- /dev/null +++ b/05/tcc-0.9.27/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(_Number)); } + __CRT_INLINE long double _copysignl(long double _Number,long double _Sign) { return _copysign(static_cast(_Number),static_cast(_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 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/05/tcc-0.9.27/win32/include/mem.h b/05/tcc-0.9.27/win32/include/mem.h new file mode 100644 index 0000000..2552023 --- /dev/null +++ b/05/tcc-0.9.27/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 +#endif diff --git a/05/tcc-0.9.27/win32/include/memory.h b/05/tcc-0.9.27/win32/include/memory.h new file mode 100644 index 0000000..90d88ae --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/process.h b/05/tcc-0.9.27/win32/include/process.h new file mode 100644 index 0000000..dadaf2b --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/conio_s.h b/05/tcc-0.9.27/win32/include/sec_api/conio_s.h new file mode 100644 index 0000000..98d97ba --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/crtdbg_s.h b/05/tcc-0.9.27/win32/include/sec_api/crtdbg_s.h new file mode 100644 index 0000000..4598b4f --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/io_s.h b/05/tcc-0.9.27/win32/include/sec_api/io_s.h new file mode 100644 index 0000000..ec565a6 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/mbstring_s.h b/05/tcc-0.9.27/win32/include/sec_api/mbstring_s.h new file mode 100644 index 0000000..6b2b188 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/search_s.h b/05/tcc-0.9.27/win32/include/sec_api/search_s.h new file mode 100644 index 0000000..cae8998 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/stdio_s.h b/05/tcc-0.9.27/win32/include/sec_api/stdio_s.h new file mode 100644 index 0000000..c9b803b --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/stdlib_s.h b/05/tcc-0.9.27/win32/include/sec_api/stdlib_s.h new file mode 100644 index 0000000..f98262c --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/stralign_s.h b/05/tcc-0.9.27/win32/include/sec_api/stralign_s.h new file mode 100644 index 0000000..5b78f58 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/string_s.h b/05/tcc-0.9.27/win32/include/sec_api/string_s.h new file mode 100644 index 0000000..9db70e7 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/sys/timeb_s.h b/05/tcc-0.9.27/win32/include/sec_api/sys/timeb_s.h new file mode 100644 index 0000000..af5ef09 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/tchar_s.h b/05/tcc-0.9.27/win32/include/sec_api/tchar_s.h new file mode 100644 index 0000000..343d348 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/time_s.h b/05/tcc-0.9.27/win32/include/sec_api/time_s.h new file mode 100644 index 0000000..9603b94 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/sec_api/wchar_s.h b/05/tcc-0.9.27/win32/include/sec_api/wchar_s.h new file mode 100644 index 0000000..94251aa --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/setjmp.h b/05/tcc-0.9.27/win32/include/setjmp.h new file mode 100644 index 0000000..e4f142a --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/share.h b/05/tcc-0.9.27/win32/include/share.h new file mode 100644 index 0000000..358855f --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/signal.h b/05/tcc-0.9.27/win32/include/signal.h new file mode 100644 index 0000000..a518f6b --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/stdint.h b/05/tcc-0.9.27/win32/include/stdint.h new file mode 100644 index 0000000..cde32b6 --- /dev/null +++ b/05/tcc-0.9.27/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 + * Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794) + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * Contributor: Danny Smith + * + * 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 : + "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/05/tcc-0.9.27/win32/include/stdio.h b/05/tcc-0.9.27/win32/include/stdio.h new file mode 100644 index 0000000..da88793 --- /dev/null +++ b/05/tcc-0.9.27/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 +#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 + +#endif diff --git a/05/tcc-0.9.27/win32/include/stdlib.h b/05/tcc-0.9.27/win32/include/stdlib.h new file mode 100644 index 0000000..96765b2 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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 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 +#include + +#endif diff --git a/05/tcc-0.9.27/win32/include/string.h b/05/tcc-0.9.27/win32/include/string.h new file mode 100644 index 0000000..3249dc3 --- /dev/null +++ b/05/tcc-0.9.27/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 +#endif diff --git a/05/tcc-0.9.27/win32/include/sys/fcntl.h b/05/tcc-0.9.27/win32/include/sys/fcntl.h new file mode 100644 index 0000000..29fd55a --- /dev/null +++ b/05/tcc-0.9.27/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 +#endif diff --git a/05/tcc-0.9.27/win32/include/sys/file.h b/05/tcc-0.9.27/win32/include/sys/file.h new file mode 100644 index 0000000..370f352 --- /dev/null +++ b/05/tcc-0.9.27/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 +#endif diff --git a/05/tcc-0.9.27/win32/include/sys/locking.h b/05/tcc-0.9.27/win32/include/sys/locking.h new file mode 100644 index 0000000..e3fc85b --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/sys/stat.h b/05/tcc-0.9.27/win32/include/sys/stat.h new file mode 100644 index 0000000..344d4a2 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#pragma pack(push,_CRT_PACKING) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _CRTIMP +#define _CRTIMP __declspec(dllimport) +#endif + +#include + +#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/05/tcc-0.9.27/win32/include/sys/time.h b/05/tcc-0.9.27/win32/include/sys/time.h new file mode 100644 index 0000000..8ccab83 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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 + + +#endif /* _SYS_TIME_H_ */ diff --git a/05/tcc-0.9.27/win32/include/sys/timeb.h b/05/tcc-0.9.27/win32/include/sys/timeb.h new file mode 100644 index 0000000..3483773 --- /dev/null +++ b/05/tcc-0.9.27/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 +#endif diff --git a/05/tcc-0.9.27/win32/include/sys/types.h b/05/tcc-0.9.27/win32/include/sys/types.h new file mode 100644 index 0000000..7379b0f --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/sys/unistd.h b/05/tcc-0.9.27/win32/include/sys/unistd.h new file mode 100644 index 0000000..31006d3 --- /dev/null +++ b/05/tcc-0.9.27/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 +#endif + diff --git a/05/tcc-0.9.27/win32/include/sys/utime.h b/05/tcc-0.9.27/win32/include/sys/utime.h new file mode 100644 index 0000000..fec8304 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/tchar.h b/05/tcc-0.9.27/win32/include/tchar.h new file mode 100644 index 0000000..cd44bec --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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 + +#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 + +#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 +#endif diff --git a/05/tcc-0.9.27/win32/include/time.h b/05/tcc-0.9.27/win32/include/time.h new file mode 100644 index 0000000..6c72e26 --- /dev/null +++ b/05/tcc-0.9.27/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 + +/* Adding timespec definition. */ +#include + +#endif /* End _TIME_H_ */ + diff --git a/05/tcc-0.9.27/win32/include/vadefs.h b/05/tcc-0.9.27/win32/include/vadefs.h new file mode 100644 index 0000000..749b0bd --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/values.h b/05/tcc-0.9.27/win32/include/values.h new file mode 100644 index 0000000..1cd643c --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/wchar.h b/05/tcc-0.9.27/win32/include/wchar.h new file mode 100644 index 0000000..389196f --- /dev/null +++ b/05/tcc-0.9.27/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 +#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 +#endif diff --git a/05/tcc-0.9.27/win32/include/wctype.h b/05/tcc-0.9.27/win32/include/wctype.h new file mode 100644 index 0000000..a44cb38 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/winapi/basetsd.h b/05/tcc-0.9.27/win32/include/winapi/basetsd.h new file mode 100644 index 0000000..47d78c4 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/winapi/basetyps.h b/05/tcc-0.9.27/win32/include/winapi/basetyps.h new file mode 100644 index 0000000..376665e --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/winapi/guiddef.h b/05/tcc-0.9.27/win32/include/winapi/guiddef.h new file mode 100644 index 0000000..4e7909a --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/winapi/poppack.h b/05/tcc-0.9.27/win32/include/winapi/poppack.h new file mode 100644 index 0000000..b08cba2 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/winapi/pshpack1.h b/05/tcc-0.9.27/win32/include/winapi/pshpack1.h new file mode 100644 index 0000000..d18d9e8 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/winapi/pshpack2.h b/05/tcc-0.9.27/win32/include/winapi/pshpack2.h new file mode 100644 index 0000000..7de16fd --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/winapi/pshpack4.h b/05/tcc-0.9.27/win32/include/winapi/pshpack4.h new file mode 100644 index 0000000..1c8e61d --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/winapi/pshpack8.h b/05/tcc-0.9.27/win32/include/winapi/pshpack8.h new file mode 100644 index 0000000..70a3c7f --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/winapi/winbase.h b/05/tcc-0.9.27/win32/include/winapi/winbase.h new file mode 100644 index 0000000..4a38006 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/winapi/wincon.h b/05/tcc-0.9.27/win32/include/winapi/wincon.h new file mode 100644 index 0000000..a3501ee --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/winapi/windef.h b/05/tcc-0.9.27/win32/include/winapi/windef.h new file mode 100644 index 0000000..d63bdef --- /dev/null +++ b/05/tcc-0.9.27/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 +#endif + +//gr #include + + 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/05/tcc-0.9.27/win32/include/winapi/windows.h b/05/tcc-0.9.27/win32/include/winapi/windows.h new file mode 100644 index 0000000..2660d7f --- /dev/null +++ b/05/tcc-0.9.27/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 +#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 +#include +#endif + +#include +#include +#include +#include +//gr #include +#include +#include +#include +//gr #include + +#ifndef WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef NOCRYPT +#include +#include +#include +#endif + +#ifndef NOUSER +#ifndef NOGDI +#include +#ifdef INC_OLE1 +#include +#else +#include +#endif +#include +#endif +#endif +#endif + +//gr #include + +#ifdef INC_OLE2 +#include +#endif + +#ifndef NOSERVICE +#include +#endif + +#ifndef NOMCX +#include +#endif + +#ifndef NOIME +#include +#endif + +#endif +#endif +#endif diff --git a/05/tcc-0.9.27/win32/include/winapi/winerror.h b/05/tcc-0.9.27/win32/include/winapi/winerror.h new file mode 100644 index 0000000..77d85ed --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/include/winapi/wingdi.h b/05/tcc-0.9.27/win32/include/winapi/wingdi.h new file mode 100644 index 0000000..63d3891 --- /dev/null +++ b/05/tcc-0.9.27/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 + typedef struct tagRGBTRIPLE { + BYTE rgbtBlue; + BYTE rgbtGreen; + BYTE rgbtRed; + } RGBTRIPLE; +#include + + 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 + typedef struct tagBITMAPFILEHEADER { + WORD bfType; + DWORD bfSize; + WORD bfReserved1; + WORD bfReserved2; + DWORD bfOffBits; + } BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER; +#include + +#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 + 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 + + 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 + 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 + + 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/05/tcc-0.9.27/win32/include/winapi/winnt.h b/05/tcc-0.9.27/win32/include/winapi/winnt.h new file mode 100644 index 0000000..4cf685d --- /dev/null +++ b/05/tcc-0.9.27/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 +#define ANYSIZE_ARRAY 1 + +//gr #include + +#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 + +#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 + +#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 +#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 + +#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 + + 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 + +#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)&~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 + + 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 + +#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 "!\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 + +#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/05/tcc-0.9.27/win32/include/winapi/winreg.h b/05/tcc-0.9.27/win32/include/winapi/winreg.h new file mode 100644 index 0000000..f158d28 --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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/05/tcc-0.9.27/win32/include/winapi/winuser.h b/05/tcc-0.9.27/win32/include/winapi/winuser.h new file mode 100644 index 0000000..4cd9ffb --- /dev/null +++ b/05/tcc-0.9.27/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 + +#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 + + 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 + +#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 + +#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/05/tcc-0.9.27/win32/include/winapi/winver.h b/05/tcc-0.9.27/win32/include/winapi/winver.h new file mode 100644 index 0000000..5c0f036 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/lib/chkstk.S b/05/tcc-0.9.27/win32/lib/chkstk.S new file mode 100644 index 0000000..ec5c07f --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/lib/crt1.c b/05/tcc-0.9.27/win32/lib/crt1.c new file mode 100644 index 0000000..0e04fc0 --- /dev/null +++ b/05/tcc-0.9.27/win32/lib/crt1.c @@ -0,0 +1,79 @@ +// ============================================= +// crt1.c + +// _UNICODE for tchar.h, UNICODE for API +#include + +#include +#include + +#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/05/tcc-0.9.27/win32/lib/crt1w.c b/05/tcc-0.9.27/win32/lib/crt1w.c new file mode 100644 index 0000000..2b8bbc8 --- /dev/null +++ b/05/tcc-0.9.27/win32/lib/crt1w.c @@ -0,0 +1,3 @@ +#define _UNICODE 1 +#define UNICODE 1 +#include "crt1.c" diff --git a/05/tcc-0.9.27/win32/lib/dllcrt1.c b/05/tcc-0.9.27/win32/lib/dllcrt1.c new file mode 100644 index 0000000..ba1dbd0 --- /dev/null +++ b/05/tcc-0.9.27/win32/lib/dllcrt1.c @@ -0,0 +1,13 @@ +//+--------------------------------------------------------------------------- + +#include + +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/05/tcc-0.9.27/win32/lib/dllmain.c b/05/tcc-0.9.27/win32/lib/dllmain.c new file mode 100644 index 0000000..2c25b98 --- /dev/null +++ b/05/tcc-0.9.27/win32/lib/dllmain.c @@ -0,0 +1,9 @@ +//+--------------------------------------------------------------------------- + +#include + +BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) +{ + return TRUE; +} + diff --git a/05/tcc-0.9.27/win32/lib/gdi32.def b/05/tcc-0.9.27/win32/lib/gdi32.def new file mode 100644 index 0000000..02766da --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/lib/kernel32.def b/05/tcc-0.9.27/win32/lib/kernel32.def new file mode 100644 index 0000000..f03e17b --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/lib/msvcrt.def b/05/tcc-0.9.27/win32/lib/msvcrt.def new file mode 100644 index 0000000..742acb8 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/lib/user32.def b/05/tcc-0.9.27/win32/lib/user32.def new file mode 100644 index 0000000..a034dac --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/win32/lib/wincrt1.c b/05/tcc-0.9.27/win32/lib/wincrt1.c new file mode 100644 index 0000000..ce3a63f --- /dev/null +++ b/05/tcc-0.9.27/win32/lib/wincrt1.c @@ -0,0 +1,75 @@ +//+--------------------------------------------------------------------------- + +// _UNICODE for tchar.h, UNICODE for API +#include + +#include +#include + +#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/05/tcc-0.9.27/win32/lib/wincrt1w.c b/05/tcc-0.9.27/win32/lib/wincrt1w.c new file mode 100644 index 0000000..a7d349e --- /dev/null +++ b/05/tcc-0.9.27/win32/lib/wincrt1w.c @@ -0,0 +1,3 @@ +#define _UNICODE 1 +#define UNICODE 1 +#include "wincrt1.c" diff --git a/05/tcc-0.9.27/win32/tcc-win32.txt b/05/tcc-0.9.27/win32/tcc-win32.txt new file mode 100644 index 0000000..ab73007 --- /dev/null +++ b/05/tcc-0.9.27/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 + + 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/05/tcc-0.9.27/x86_64-asm.h b/05/tcc-0.9.27/x86_64-asm.h new file mode 100644 index 0000000..cb9eb16 --- /dev/null +++ b/05/tcc-0.9.27/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/05/tcc-0.9.27/x86_64-gen.c b/05/tcc-0.9.27/x86_64-gen.c new file mode 100644 index 0000000..9060ae9 --- /dev/null +++ b/05/tcc-0.9.27/x86_64-gen.c @@ -0,0 +1,2227 @@ +/* + * 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 + +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; +} + +enum __va_arg_type { +__va_gen_reg, __va_float_reg, __va_stack +}; +ST_FUNC int classify_x86_64_va_arg(CType *ty) +{ + /* This definition must be synced with stdarg.h */ + int size, align, reg_count; + X86_64_Mode mode = classify_x86_64_arg(ty, NULL, &size, &align, ®_count); + switch (mode) { + case x86_64_mode_integer: return __va_gen_reg; + case x86_64_mode_sse: return __va_float_reg; + default: return __va_stack; + } +} + +/* 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, ®_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*/1000/*fucking vlas*/], *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, ®_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, ®_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, ®_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, ®_count); + switch (mode) { + 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; + default: + stack_arg: + seen_stack_size = ((seen_stack_size + align - 1) & -align) + size; + 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, ®_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, ®_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) { + case '-': + a = 4; + if (swapped) + a++; + break; + case '*': + a = 1; + break; + case '/': + a = 6; + if (swapped) + a++; + break; + case '+': + default: + a = 0; + 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) { + case '-': + a = 4; + break; + case '*': + a = 1; + break; + case '/': + a = 6; + break; + case '+': + default: + a = 0; + 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/05/tcc-0.9.27/x86_64-link.c b/05/tcc-0.9.27/x86_64-link.c new file mode 100644 index 0000000..7b354b5 --- /dev/null +++ b/05/tcc-0.9.27/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 = ELF64_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 = ELF64_R_INFO(esym_index, R_X86_64_64); + qrel->r_addend = rel->r_addend; + qrel++; + break; + } else { + qrel->r_info = ELF64_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 = ELF64_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 = ELF64_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 = ELF64_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 */ diff --git a/05/test.c b/05/test.c new file mode 100644 index 0000000..b287d99 --- /dev/null +++ b/05/test.c @@ -0,0 +1,6 @@ +// calling assembly functions from C is not working for some reason. +extern unsigned long __syscall(int, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); +int main(unsigned long (*_syscall)(int, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)) { + __syscall(1, 1, (unsigned long)"Hello, world!\n", 14, 0, 0, 0); + return 42; +} diff --git a/05/test.s b/05/test.s new file mode 100644 index 0000000..7379247 --- /dev/null +++ b/05/test.s @@ -0,0 +1,21 @@ +.global _start +.global __syscall + +__syscall: + # SysV calling convention: RDI, RSI, RDX, RCX, R8, R9, 8(%rsp) + # Linux syscall calling convention: RAX, RDI, RSI, RDX, R10, R8, R9 + mov %rdi, %rax + mov %rsi, %rdi + mov %rdx, %rsi + mov %rcx, %rdx + mov %r8, %r10 + mov %r9, %r8 + mov 8(%rsp), %r9 + syscall + ret + +_start: + lea __syscall, %rdi + call main + mov $60, %eax + syscall diff --git a/05/tests/macros.c b/05/tests/macros.c new file mode 100644 index 0000000..688c45e --- /dev/null +++ b/05/tests/macros.c @@ -0,0 +1,40 @@ + #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 + + f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); + g(x+(3,4)-w) | h 5) & m(f)^m(m); + + #undef x + #undef g + #undef z + #undef h + #undef m + #undef w + #undef t + #undef f + +#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 /* from previous #include example */ + #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) + -- cgit v1.2.3