Unified · Split
| @@ -647,7 +647,7 @@ static int tcc_compile(TCCState *s1) · 646 unmodified lines | ||
| 647 | 647 | { |
| 648 | 648 | Sym *define_start; |
| 649 | 649 | |
| 650 | − preprocess_init(s1); | |
| 650 | + preprocess_start(s1); | |
| 651 | 651 | define_start = define_stack; |
| 652 | 652 | |
| 653 | 653 | if (setjmp(s1->error_jmp_buf) == 0) { |
| @@ -665,11 +665,11 @@ static int tcc_compile(TCCState *s1) · 11 unmodified lines | ||
| 665 | 665 | decl(VT_CONST); |
| 666 | 666 | if (tok != TOK_EOF) |
| 667 | 667 | expect("declaration"); |
| 668 | − gen_inline_functions(); | |
| 669 | 668 | tccgen_end(s1); |
| 670 | 669 | } |
| 671 | − | |
| 672 | 670 | s1->error_set_jmp_enabled = 0; |
| 671 | + | |
| 672 | + free_inline_functions(s1); | |
| 673 | 673 | /* reset define stack, but keep -D and built-ins */ |
| 674 | 674 | free_defines(define_start); |
| 675 | 675 | sym_pop(&global_stack, NULL); |
| @@ -730,10 +730,8 @@ static void tcc_cleanup(void) · 54 unmodified lines | ||
| 730 | 730 | { |
| 731 | 731 | if (NULL == tcc_state) |
| 732 | 732 | return; |
| 733 | + tccpp_delete(tcc_state); | |
| 733 | 734 | tcc_state = NULL; |
| 734 | − | |
| 735 | − preprocess_delete(); | |
| 736 | − | |
| 737 | 735 | /* free sym_pools */ |
| 738 | 736 | dynarray_reset(&sym_pools, &nb_sym_pools); |
| 739 | 737 | /* reset symbol stack */ |
| @@ -743,6 +741,7 @@ static void tcc_cleanup(void) · 3 unmodified lines | ||
| 743 | 741 | LIBTCCAPI TCCState *tcc_new(void) |
| 744 | 742 | { |
| 745 | 743 | TCCState *s; |
| 744 | + | |
| 746 | 745 | tcc_cleanup(); |
| 747 | 746 | |
| 748 | 747 | s = tcc_mallocz(sizeof(TCCState)); |
| @@ -772,10 +771,8 @@ LIBTCCAPI TCCState *tcc_new(void) · 23 unmodified lines | ||
| 772 | 771 | #else |
| 773 | 772 | tcc_set_lib_path(s, CONFIG_TCCDIR); |
| 774 | 773 | #endif |
| 775 | − | |
| 776 | 774 | tccelf_new(s); |
| 777 | − preprocess_new(); | |
| 778 | − s->include_stack_ptr = s->include_stack; | |
| 775 | + tccpp_new(s); | |
| 779 | 776 | |
| 780 | 777 | /* we add dummy defines for some special macros to speed up tests |
| 781 | 778 | and to have working defined() */ |
| @@ -830,12 +827,6 @@ LIBTCCAPI TCCState *tcc_new(void) · 48 unmodified lines | ||
| 830 | 827 | tcc_define_symbol(s, "_WIN32", NULL); |
| 831 | 828 | # ifdef TCC_TARGET_X86_64 |
| 832 | 829 | tcc_define_symbol(s, "_WIN64", NULL); |
| 833 | − /* Those are defined by Visual Studio */ | |
| 834 | − tcc_define_symbol(s, "_M_X64", "100"); | |
| 835 | − tcc_define_symbol(s, "_M_AMD64", "100"); | |
| 836 | −# else | |
| 837 | − /* Defined by Visual Studio. 300 == 80386. */ | |
| 838 | − tcc_define_symbol(s, "_M_IX86", "300"); | |
| 839 | 830 | # endif |
| 840 | 831 | #else |
| 841 | 832 | tcc_define_symbol(s, "__unix__", NULL); |
| @@ -894,10 +885,8 @@ LIBTCCAPI TCCState *tcc_new(void) · 52 unmodified lines | ||
| 894 | 885 | /* define __GNUC__ to have some useful stuff from sys/cdefs.h |
| 895 | 886 | that are unconditionally used in FreeBSDs other system headers :/ */ |
| 896 | 887 | tcc_define_symbol(s, "__GNUC__", "2"); |
| 897 | − tcc_define_symbol(s, "__GNUC_MINOR__", "1"); | |
| 888 | + tcc_define_symbol(s, "__GNUC_MINOR__", "7"); | |
| 898 | 889 | tcc_define_symbol(s, "__builtin_alloca", "alloca"); |
| 899 | − tcc_define_symbol(s, "__builtin_memcpy", "memcpy"); | |
| 900 | − tcc_define_symbol(s, "__USER_LABEL_PREFIX__", ""); | |
| 901 | 890 | # endif |
| 902 | 891 | # else |
| 903 | 892 | tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int"); |
| @@ -973,27 +962,16 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) · 69 unmodified lines | ||
| 973 | 962 | } |
| 974 | 963 | |
| 975 | 964 | #ifdef CONFIG_TCC_BCHECK |
| 976 | − /* if bound checking, then add corresponding sections */ | |
| 977 | 965 | if (s->do_bounds_check) { |
| 966 | + /* if bound checking, then add corresponding sections */ | |
| 967 | + tccelf_bounds_new(s); | |
| 978 | 968 | /* define symbol */ |
| 979 | 969 | tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL); |
| 980 | − /* create bounds sections */ | |
| 981 | − bounds_section = new_section(s, ".bounds", | |
| 982 | − SHT_PROGBITS, SHF_ALLOC); | |
| 983 | − lbounds_section = new_section(s, ".lbounds", | |
| 984 | − SHT_PROGBITS, SHF_ALLOC); | |
| 985 | 970 | } |
| 986 | 971 | #endif |
| 987 | − /* add debug sections */ | |
| 988 | 972 | if (s->do_debug) { |
| 989 | − /* stab symbols */ | |
| 990 | − stab_section = new_section(s, ".stab", SHT_PROGBITS, 0); | |
| 991 | − stab_section->sh_entsize = sizeof(Stab_Sym); | |
| 992 | − stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0); | |
| 993 | − put_elf_str(stabstr_section, ""); | |
| 994 | − stab_section->link = stabstr_section; | |
| 995 | − /* put first entry */ | |
| 996 | − put_stabs("", 0, 0, 0, 0); | |
| 973 | + /* add debug sections */ | |
| 974 | + tccelf_stab_new(s); | |
| 997 | 975 | } |
| 998 | 976 | |
| 999 | 977 | tcc_add_library_path(s, CONFIG_TCC_LIBPATHS); |
| @@ -1205,7 +1183,7 @@ PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname) · 205 unmodified lines | ||
| 1205 | 1183 | { |
| 1206 | 1184 | int ret = tcc_add_library(s, libname); |
| 1207 | 1185 | if (ret < 0) |
| 1208 | − tcc_error_noabort("cannot find library 'lib%s'", libname); | |
| 1186 | + tcc_error_noabort("library 'lib%s' not found", libname); | |
| 1209 | 1187 | return ret; |
| 1210 | 1188 | } |
| 1211 | 1189 | |
| @@ -1939,18 +1917,17 @@ LIBTCCAPI int tcc_set_options(TCCState *s, const char *r) · 727 unmodified lines | ||
| 1939 | 1917 | return ret; |
| 1940 | 1918 | } |
| 1941 | 1919 | |
| 1942 | −PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time) | |
| 1920 | +PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time) | |
| 1943 | 1921 | { |
| 1944 | − double tt; | |
| 1945 | − tt = (double)total_time / 1000000.0; | |
| 1946 | − if (tt < 0.001) | |
| 1947 | − tt = 0.001; | |
| 1922 | + if (total_time < 1) | |
| 1923 | + total_time = 1; | |
| 1948 | 1924 | if (total_bytes < 1) |
| 1949 | 1925 | total_bytes = 1; |
| 1950 | − fprintf(stderr, "%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n", | |
| 1926 | + fprintf(stderr, "%d idents, %d lines, %d bytes, %0.3f s, %u lines/s, %0.1f MB/s\n", | |
| 1951 | 1927 | tok_ident - TOK_IDENT, total_lines, total_bytes, |
| 1952 | − tt, (int)(total_lines / tt), | |
| 1953 | − total_bytes / tt / 1000000.0); | |
| 1928 | + (double)total_time/1000, | |
| 1929 | + (unsigned)total_lines*1000/total_time, | |
| 1930 | + (double)total_bytes/1000/total_time); | |
| 1954 | 1931 | } |
| 1955 | 1932 | |
| 1956 | 1933 | PUB_FUNC void tcc_set_environment(TCCState *s) |
| @@ -244,17 +244,14 @@ static char *default_outputfile(TCCState *s, const char *first_file) · 243 unmodified lines | ||
| 244 | 244 | return tcc_strdup(buf); |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | −static int64_t getclock_us(void) | |
| 247 | +static unsigned getclock_ms(void) | |
| 248 | 248 | { |
| 249 | 249 | #ifdef _WIN32 |
| 250 | − LARGE_INTEGER frequency, t1; | |
| 251 | − QueryPerformanceFrequency(&frequency); | |
| 252 | − QueryPerformanceCounter(&t1); | |
| 253 | − return t1.QuadPart * 1000000LL / frequency.QuadPart; | |
| 250 | + return GetTickCount(); | |
| 254 | 251 | #else |
| 255 | 252 | struct timeval tv; |
| 256 | 253 | gettimeofday(&tv, NULL); |
| 257 | − return tv.tv_sec * 1000000LL + tv.tv_usec; | |
| 254 | + return tv.tv_sec*1000 + (tv.tv_usec+500)/1000; | |
| 258 | 255 | #endif |
| 259 | 256 | } |
| 260 | 257 | |
| @@ -262,7 +259,7 @@ int main(int argc, char **argv) · 1 unmodified line | ||
| 262 | 259 | { |
| 263 | 260 | TCCState *s; |
| 264 | 261 | int ret, optind, i; |
| 265 | − int64_t start_time = 0; | |
| 262 | + unsigned start_time = 0; | |
| 266 | 263 | const char *first_file = NULL; |
| 267 | 264 | |
| 268 | 265 | s = tcc_new(); |
| @@ -322,7 +319,7 @@ int main(int argc, char **argv) · 53 unmodified lines | ||
| 322 | 319 | } |
| 323 | 320 | |
| 324 | 321 | if (s->do_bench) |
| 325 | − start_time = getclock_us(); | |
| 322 | + start_time = getclock_ms(); | |
| 326 | 323 | |
| 327 | 324 | /* compile or add each files or library */ |
| 328 | 325 | for(i = ret = 0; i < s->nb_files && ret == 0; i++) { |
| @@ -349,8 +346,6 @@ int main(int argc, char **argv) · 20 unmodified lines | ||
| 349 | 346 | fclose(s->ppfp); |
| 350 | 347 | |
| 351 | 348 | } else if (0 == ret) { |
| 352 | − if (s->do_bench) | |
| 353 | − tcc_print_stats(s, getclock_us() - start_time); | |
| 354 | 349 | if (s->output_type == TCC_OUTPUT_MEMORY) { |
| 355 | 350 | #ifdef TCC_IS_NATIVE |
| 356 | 351 | ret = tcc_run(s, argc - 1 - optind, argv + 1 + optind); |
| @@ -364,6 +359,8 @@ int main(int argc, char **argv) · 7 unmodified lines | ||
| 364 | 359 | } |
| 365 | 360 | } |
| 366 | 361 | |
| 362 | + if (s->do_bench) | |
| 363 | + tcc_print_stats(s, getclock_ms() - start_time); | |
| 367 | 364 | tcc_delete(s); |
| 368 | 365 | return ret; |
| 369 | 366 | } |
| @@ -30,35 +30,29 @@ · 29 unmodified lines | ||
| 30 | 30 | #include <string.h> |
| 31 | 31 | #include <errno.h> |
| 32 | 32 | #include <math.h> |
| 33 | −#include <signal.h> | |
| 34 | 33 | #include <fcntl.h> |
| 35 | 34 | #include <setjmp.h> |
| 36 | 35 | #include <time.h> |
| 37 | −#include <sys/stat.h> /* stat() */ | |
| 38 | 36 | |
| 39 | 37 | #ifndef _WIN32 |
| 40 | 38 | # include <unistd.h> |
| 41 | 39 | # include <sys/time.h> |
| 42 | −# ifndef __OpenBSD__ | |
| 43 | −# include <sys/ucontext.h> | |
| 44 | −# endif | |
| 45 | −# include <sys/mman.h> | |
| 46 | 40 | # ifndef CONFIG_TCC_STATIC |
| 47 | 41 | # include <dlfcn.h> |
| 48 | 42 | # endif |
| 49 | 43 | /* XXX: need to define this to use them in non ISOC99 context */ |
| 50 | 44 | extern float strtof (const char *__nptr, char **__endptr); |
| 51 | 45 | extern long double strtold (const char *__nptr, char **__endptr); |
| 46 | + | |
| 52 | 47 | #else /* on _WIN32: */ |
| 53 | 48 | # include <windows.h> |
| 54 | −# include <sys/timeb.h> | |
| 55 | 49 | # include <io.h> /* open, close etc. */ |
| 56 | 50 | # include <direct.h> /* getcwd */ |
| 57 | 51 | # ifdef __GNUC__ |
| 58 | 52 | # include <stdint.h> |
| 59 | 53 | # endif |
| 60 | 54 | # define inline __inline |
| 61 | −# define inp next_inp | |
| 55 | +# define inp next_inp /* inp is an intrinsic on msvc */ | |
| 62 | 56 | # define snprintf _snprintf |
| 63 | 57 | # define vsnprintf _vsnprintf |
| 64 | 58 | # ifndef __GNUC__ |
| @@ -109,30 +103,7 @@ · 44 unmodified lines | ||
| 109 | 103 | #define PATHSEP ':' |
| 110 | 104 | #endif |
| 111 | 105 | |
| 112 | −#include "elf.h" | |
| 113 | −#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) | |
| 114 | −# define ELFCLASSW ELFCLASS64 | |
| 115 | −# define ElfW(type) Elf##64##_##type | |
| 116 | −# define ELFW(type) ELF##64##_##type | |
| 117 | −# define ElfW_Rel ElfW(Rela) | |
| 118 | −# define SHT_RELX SHT_RELA | |
| 119 | −# define REL_SECTION_FMT ".rela%s" | |
| 120 | −/* XXX: DLL with PLT would only work with x86-64 for now */ | |
| 121 | −# define TCC_OUTPUT_DLL_WITH_PLT | |
| 122 | −#else | |
| 123 | −# define ELFCLASSW ELFCLASS32 | |
| 124 | −# define ElfW(type) Elf##32##_##type | |
| 125 | −# define ELFW(type) ELF##32##_##type | |
| 126 | −# define ElfW_Rel ElfW(Rel) | |
| 127 | −# define SHT_RELX SHT_REL | |
| 128 | −# define REL_SECTION_FMT ".rel%s" | |
| 129 | −#endif | |
| 130 | − | |
| 131 | −/* target address type */ | |
| 132 | −#define addr_t ElfW(Addr) | |
| 133 | − | |
| 134 | −#include "stab.h" | |
| 135 | −#include "libtcc.h" | |
| 106 | +/* -------------------------------------------- */ | |
| 136 | 107 | |
| 137 | 108 | /* parser debug */ |
| 138 | 109 | /* #define PARSE_DEBUG */ |
| @@ -292,6 +263,32 @@ · 153 unmodified lines | ||
| 292 | 263 | /* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */ |
| 293 | 264 | #define TCC_LIBGCC USE_MUADIR(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1" |
| 294 | 265 | |
| 266 | +/* -------------------------------------------- */ | |
| 267 | + | |
| 268 | +#include "libtcc.h" | |
| 269 | +#include "elf.h" | |
| 270 | +#include "stab.h" | |
| 271 | + | |
| 272 | +#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) | |
| 273 | +# define ELFCLASSW ELFCLASS64 | |
| 274 | +# define ElfW(type) Elf##64##_##type | |
| 275 | +# define ELFW(type) ELF##64##_##type | |
| 276 | +# define ElfW_Rel ElfW(Rela) | |
| 277 | +# define SHT_RELX SHT_RELA | |
| 278 | +# define REL_SECTION_FMT ".rela%s" | |
| 279 | +/* XXX: DLL with PLT would only work with x86-64 for now */ | |
| 280 | +# define TCC_OUTPUT_DLL_WITH_PLT | |
| 281 | +#else | |
| 282 | +# define ELFCLASSW ELFCLASS32 | |
| 283 | +# define ElfW(type) Elf##32##_##type | |
| 284 | +# define ELFW(type) ELF##32##_##type | |
| 285 | +# define ElfW_Rel ElfW(Rel) | |
| 286 | +# define SHT_RELX SHT_REL | |
| 287 | +# define REL_SECTION_FMT ".rel%s" | |
| 288 | +#endif | |
| 289 | +/* target address type */ | |
| 290 | +#define addr_t ElfW(Addr) | |
| 291 | + | |
| 295 | 292 | /* -------------------------------------------- */ |
| 296 | 293 | /* include the target specific definitions */ |
| 297 | 294 | |
| @@ -1137,7 +1134,7 @@ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags); · 839 unmodified lines | ||
| 1137 | 1134 | ST_FUNC void tcc_add_pragma_libs(TCCState *s1); |
| 1138 | 1135 | PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f); |
| 1139 | 1136 | |
| 1140 | −PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time); | |
| 1137 | +PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time); | |
| 1141 | 1138 | PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv); |
| 1142 | 1139 | PUB_FUNC void tcc_set_environment(TCCState *s); |
| 1143 | 1140 | #ifdef _WIN32 |
| @@ -1198,9 +1195,9 @@ ST_FUNC void preprocess(int is_bof); · 54 unmodified lines | ||
| 1198 | 1195 | ST_FUNC void next_nomacro(void); |
| 1199 | 1196 | ST_FUNC void next(void); |
| 1200 | 1197 | ST_INLN void unget_tok(int last_tok); |
| 1201 | −ST_FUNC void preprocess_init(TCCState *s1); | |
| 1202 | −ST_FUNC void preprocess_new(void); | |
| 1203 | −ST_FUNC void preprocess_delete(void); | |
| 1198 | +ST_FUNC void preprocess_start(TCCState *s1); | |
| 1199 | +ST_FUNC void tccpp_new(TCCState *s); | |
| 1200 | +ST_FUNC void tccpp_delete(TCCState *s); | |
| 1204 | 1201 | ST_FUNC int tcc_preprocess(TCCState *s1); |
| 1205 | 1202 | ST_FUNC void skip(int c); |
| 1206 | 1203 | ST_FUNC NORETURN void expect(const char *msg); |
| @@ -1250,8 +1247,9 @@ ST_DATA const char *funcname; · 43 unmodified lines | ||
| 1250 | 1247 | |
| 1251 | 1248 | ST_FUNC void tccgen_start(TCCState *s1); |
| 1252 | 1249 | ST_FUNC void tccgen_end(TCCState *s1); |
| 1253 | − | |
| 1250 | +ST_FUNC void free_inline_functions(TCCState *s); | |
| 1254 | 1251 | ST_FUNC void check_vstack(void); |
| 1252 | + | |
| 1255 | 1253 | ST_INLN int is_float(int t); |
| 1256 | 1254 | ST_FUNC int ieee_finite(double d); |
| 1257 | 1255 | ST_FUNC void test_lvalue(void); |
| @@ -1290,7 +1288,6 @@ ST_FUNC void expr_prod(void); · 32 unmodified lines | ||
| 1290 | 1288 | ST_FUNC void expr_sum(void); |
| 1291 | 1289 | ST_FUNC void gexpr(void); |
| 1292 | 1290 | ST_FUNC int expr_const(void); |
| 1293 | −ST_FUNC void gen_inline_functions(void); | |
| 1294 | 1291 | ST_FUNC void decl(int l); |
| 1295 | 1292 | #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67 |
| 1296 | 1293 | ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size); |
| @@ -1332,6 +1329,9 @@ ST_DATA Section *stab_section, *stabstr_section; · 35 unmodified lines | ||
| 1332 | 1329 | |
| 1333 | 1330 | ST_FUNC void tccelf_new(TCCState *s); |
| 1334 | 1331 | ST_FUNC void tccelf_delete(TCCState *s); |
| 1332 | +ST_FUNC void tccelf_bounds_new(TCCState *s); | |
| 1333 | +ST_FUNC void tccelf_stab_new(TCCState *s); | |
| 1334 | + | |
| 1335 | 1335 | ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags); |
| 1336 | 1336 | ST_FUNC void section_realloc(Section *sec, unsigned long new_size); |
| 1337 | 1337 | ST_FUNC void *section_ptr_add(Section *sec, addr_t size); |
| @@ -868,7 +868,7 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) · 867 unmodified lines | ||
| 868 | 868 | Sym *define_start; |
| 869 | 869 | int ret; |
| 870 | 870 | |
| 871 | − preprocess_init(s1); | |
| 871 | + preprocess_start(s1); | |
| 872 | 872 | |
| 873 | 873 | /* default section is text */ |
| 874 | 874 | cur_text_section = text_section; |
| @@ -69,6 +69,28 @@ ST_FUNC void tccelf_new(TCCState *s) · 68 unmodified lines | ||
| 69 | 69 | ".dynhashtab", SHF_PRIVATE); |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | +#ifdef CONFIG_TCC_BCHECK | |
| 73 | +ST_FUNC void tccelf_bounds_new(TCCState *s) | |
| 74 | +{ | |
| 75 | + /* create bounds sections */ | |
| 76 | + bounds_section = new_section(s, ".bounds", | |
| 77 | + SHT_PROGBITS, SHF_ALLOC); | |
| 78 | + lbounds_section = new_section(s, ".lbounds", | |
| 79 | + SHT_PROGBITS, SHF_ALLOC); | |
| 80 | +} | |
| 81 | +#endif | |
| 82 | + | |
| 83 | +ST_FUNC void tccelf_stab_new(TCCState *s) | |
| 84 | +{ | |
| 85 | + stab_section = new_section(s, ".stab", SHT_PROGBITS, 0); | |
| 86 | + stab_section->sh_entsize = sizeof(Stab_Sym); | |
| 87 | + stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0); | |
| 88 | + put_elf_str(stabstr_section, ""); | |
| 89 | + stab_section->link = stabstr_section; | |
| 90 | + /* put first entry */ | |
| 91 | + put_stabs("", 0, 0, 0, 0); | |
| 92 | +} | |
| 93 | + | |
| 72 | 94 | static void free_section(Section *s) |
| 73 | 95 | { |
| 74 | 96 | tcc_free(s->data); |
| @@ -616,7 +638,7 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) · 541 unmodified lines | ||
| 616 | 638 | name = (char *) strtab_section->data + sym->st_name; |
| 617 | 639 | /* Use ld.so to resolve symbol for us (for tcc -run) */ |
| 618 | 640 | if (do_resolve) { |
| 619 | −#if defined TCC_IS_NATIVE && !defined _WIN32 | |
| 641 | +#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE | |
| 620 | 642 | void *addr; |
| 621 | 643 | name = (char *) symtab_section->link->data + sym->st_name; |
| 622 | 644 | addr = dlsym(RTLD_DEFAULT, name); |
| @@ -1786,7 +1808,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 1163 unmodified lines | ||
| 1786 | 1808 | tcc_add_pragma_libs(s1); |
| 1787 | 1809 | /* add libc */ |
| 1788 | 1810 | if (!s1->nostdlib) { |
| 1789 | − tcc_add_library(s1, "c"); | |
| 1811 | + tcc_add_library_err(s1, "c"); | |
| 1790 | 1812 | #ifdef CONFIG_USE_LIBGCC |
| 1791 | 1813 | if (!s1->static_link) { |
| 1792 | 1814 | tcc_add_file(s1, TCC_LIBGCC); |
| @@ -90,6 +90,7 @@ ST_FUNC void vpush64(int ty, unsigned long long v); · 89 unmodified lines | ||
| 90 | 90 | ST_FUNC void vpush(CType *type); |
| 91 | 91 | ST_FUNC int gvtst(int inv, int t); |
| 92 | 92 | ST_FUNC int is_btype_size(int bt); |
| 93 | +static void gen_inline_functions(TCCState *s); | |
| 93 | 94 | |
| 94 | 95 | ST_INLN int is_float(int t) |
| 95 | 96 | { |
| @@ -182,24 +183,11 @@ ST_FUNC void tccgen_start(TCCState *s1) · 86 unmodified lines | ||
| 182 | 183 | #ifdef TCC_TARGET_ARM |
| 183 | 184 | arm_init(s1); |
| 184 | 185 | #endif |
| 185 | − | |
| 186 | −#if 0 | |
| 187 | − /* define 'void *alloca(unsigned int)' builtin function */ | |
| 188 | − { | |
| 189 | − Sym *s1; | |
| 190 | − | |
| 191 | − p = anon_sym++; | |
| 192 | − sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW); | |
| 193 | − s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0); | |
| 194 | − s1->next = NULL; | |
| 195 | − sym->next = s1; | |
| 196 | − sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0); | |
| 197 | − } | |
| 198 | −#endif | |
| 199 | 186 | } |
| 200 | 187 | |
| 201 | 188 | ST_FUNC void tccgen_end(TCCState *s1) |
| 202 | 189 | { |
| 190 | + gen_inline_functions(s1); | |
| 203 | 191 | check_vstack(); |
| 204 | 192 | /* end of translation unit info */ |
| 205 | 193 | if (s1->do_debug) { |
| @@ -6513,7 +6501,7 @@ static void gen_function(Sym *sym) · 6307 unmodified lines | ||
| 6513 | 6501 | check_vstack(); |
| 6514 | 6502 | } |
| 6515 | 6503 | |
| 6516 | −ST_FUNC void gen_inline_functions(void) | |
| 6504 | +static void gen_inline_functions(TCCState *s) | |
| 6517 | 6505 | { |
| 6518 | 6506 | Sym *sym; |
| 6519 | 6507 | int inline_generated, i, ln; |
| @@ -6523,8 +6511,8 @@ ST_FUNC void gen_inline_functions(void) · 3 unmodified lines | ||
| 6523 | 6511 | /* iterate while inline function are referenced */ |
| 6524 | 6512 | for(;;) { |
| 6525 | 6513 | inline_generated = 0; |
| 6526 | − for (i = 0; i < tcc_state->nb_inline_fns; ++i) { | |
| 6527 | − fn = tcc_state->inline_fns[i]; | |
| 6514 | + for (i = 0; i < s->nb_inline_fns; ++i) { | |
| 6515 | + fn = s->inline_fns[i]; | |
| 6528 | 6516 | sym = fn->sym; |
| 6529 | 6517 | if (sym && sym->c) { |
| 6530 | 6518 | /* the function was used: generate its code and |
| @@ -6548,13 +6536,18 @@ ST_FUNC void gen_inline_functions(void) · 17 unmodified lines | ||
| 6548 | 6536 | break; |
| 6549 | 6537 | } |
| 6550 | 6538 | file->line_num = ln; |
| 6539 | +} | |
| 6540 | + | |
| 6541 | +ST_FUNC void free_inline_functions(TCCState *s) | |
| 6542 | +{ | |
| 6543 | + int i; | |
| 6551 | 6544 | /* free tokens of unused inline functions */ |
| 6552 | − for (i = 0; i < tcc_state->nb_inline_fns; ++i) { | |
| 6553 | − fn = tcc_state->inline_fns[i]; | |
| 6545 | + for (i = 0; i < s->nb_inline_fns; ++i) { | |
| 6546 | + struct InlineFunc *fn = s->inline_fns[i]; | |
| 6554 | 6547 | if (fn->sym) |
| 6555 | 6548 | tok_str_free(fn->func_str.str); |
| 6556 | 6549 | } |
| 6557 | − dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns); | |
| 6550 | + dynarray_reset(&s->inline_fns, &s->nb_inline_fns); | |
| 6558 | 6551 | } |
| 6559 | 6552 | |
| 6560 | 6553 | /* 'l' is VT_LOCAL or VT_CONST to define default storage type */ |
| @@ -20,6 +20,9 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | #include "tcc.h" |
| 22 | 22 | |
| 23 | +#define PE_MERGE_DATA | |
| 24 | +/* #define PE_PRINT_SECTIONS */ | |
| 25 | + | |
| 23 | 26 | #ifndef _WIN32 |
| 24 | 27 | #define stricmp strcasecmp |
| 25 | 28 | #define strnicmp strncasecmp |
| @@ -29,9 +32,6 @@ · 3 unmodified lines | ||
| 29 | 32 | #define MAX_PATH 260 |
| 30 | 33 | #endif |
| 31 | 34 | |
| 32 | −#define PE_MERGE_DATA | |
| 33 | −/* #define PE_PRINT_SECTIONS */ | |
| 34 | − | |
| 35 | 35 | #ifdef TCC_TARGET_X86_64 |
| 36 | 36 | # define ADDR3264 ULONGLONG |
| 37 | 37 | # define REL_TYPE_DIRECT R_X86_64_64 |
| @@ -832,7 +832,7 @@ static void pe_build_imports(struct pe_info *pe) · 794 unmodified lines | ||
| 832 | 832 | if (dllref) { |
| 833 | 833 | if ( !dllref->handle ) |
| 834 | 834 | dllref->handle = LoadLibrary(dllref->name); |
| 835 | − v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(LPCSTR)NULL+ordinal:name); | |
| 835 | + v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(char*)0+ordinal:name); | |
| 836 | 836 | } |
| 837 | 837 | if (!v) |
| 838 | 838 | tcc_error_noabort("can't build symbol '%s'", name); |
| @@ -1074,6 +1074,9 @@ static int pe_assign_addresses (struct pe_info *pe) · 235 unmodified lines | ||
| 1074 | 1074 | struct section_info *si; |
| 1075 | 1075 | Section *s; |
| 1076 | 1076 | |
| 1077 | + if (PE_DLL == pe->type) | |
| 1078 | + pe->reloc = new_section(pe->s1, ".reloc", SHT_PROGBITS, 0); | |
| 1079 | + | |
| 1077 | 1080 | // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC); |
| 1078 | 1081 | |
| 1079 | 1082 | section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int)); |
| @@ -1801,7 +1804,54 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) · 721 unmodified lines | ||
| 1801 | 1804 | pe->type = pe_type; |
| 1802 | 1805 | } |
| 1803 | 1806 | |
| 1804 | −ST_FUNC int pe_output_file(TCCState * s1, const char *filename) | |
| 1807 | +static void pe_set_options(TCCState * s1, struct pe_info *pe) | |
| 1808 | +{ | |
| 1809 | + if (PE_DLL == pe->type) { | |
| 1810 | + /* XXX: check if is correct for arm-pe target */ | |
| 1811 | + pe->imagebase = 0x10000000; | |
| 1812 | + } else { | |
| 1813 | +#if defined(TCC_TARGET_ARM) | |
| 1814 | + pe->imagebase = 0x00010000; | |
| 1815 | +#else | |
| 1816 | + pe->imagebase = 0x00400000; | |
| 1817 | +#endif | |
| 1818 | + } | |
| 1819 | + | |
| 1820 | +#if defined(TCC_TARGET_ARM) | |
| 1821 | + /* we use "console" subsystem by default */ | |
| 1822 | + pe->subsystem = 9; | |
| 1823 | +#else | |
| 1824 | + if (PE_DLL == pe->type || PE_GUI == pe->type) | |
| 1825 | + pe->subsystem = 2; | |
| 1826 | + else | |
| 1827 | + pe->subsystem = 3; | |
| 1828 | +#endif | |
| 1829 | + /* Allow override via -Wl,-subsystem=... option */ | |
| 1830 | + if (s1->pe_subsystem != 0) | |
| 1831 | + pe->subsystem = s1->pe_subsystem; | |
| 1832 | + | |
| 1833 | + /* set default file/section alignment */ | |
| 1834 | + if (pe->subsystem == 1) { | |
| 1835 | + pe->section_align = 0x20; | |
| 1836 | + pe->file_align = 0x20; | |
| 1837 | + } else { | |
| 1838 | + pe->section_align = 0x1000; | |
| 1839 | + pe->file_align = 0x200; | |
| 1840 | + } | |
| 1841 | + | |
| 1842 | + if (s1->section_align != 0) | |
| 1843 | + pe->section_align = s1->section_align; | |
| 1844 | + if (s1->pe_file_align != 0) | |
| 1845 | + pe->file_align = s1->pe_file_align; | |
| 1846 | + | |
| 1847 | + if ((pe->subsystem >= 10) && (pe->subsystem <= 12)) | |
| 1848 | + pe->imagebase = 0; | |
| 1849 | + | |
| 1850 | + if (s1->has_text_addr) | |
| 1851 | + pe->imagebase = s1->text_addr; | |
| 1852 | +} | |
| 1853 | + | |
| 1854 | +ST_FUNC int pe_output_file(TCCState *s1, const char *filename) | |
| 1805 | 1855 | { |
| 1806 | 1856 | int ret; |
| 1807 | 1857 | struct pe_info pe; |
| @@ -1815,56 +1865,12 @@ ST_FUNC int pe_output_file(TCCState * s1, const char *filename) · 7 unmodified lines | ||
| 1815 | 1865 | pe_add_runtime(s1, &pe); |
| 1816 | 1866 | relocate_common_syms(); /* assign bss adresses */ |
| 1817 | 1867 | tcc_add_linker_symbols(s1); |
| 1868 | + pe_set_options(s1, &pe); | |
| 1818 | 1869 | |
| 1819 | 1870 | ret = pe_check_symbols(&pe); |
| 1820 | 1871 | if (ret) |
| 1821 | 1872 | ; |
| 1822 | 1873 | else if (filename) { |
| 1823 | − if (PE_DLL == pe.type) { | |
| 1824 | − pe.reloc = new_section(pe.s1, ".reloc", SHT_PROGBITS, 0); | |
| 1825 | − /* XXX: check if is correct for arm-pe target */ | |
| 1826 | − pe.imagebase = 0x10000000; | |
| 1827 | − } else { | |
| 1828 | −#if defined(TCC_TARGET_ARM) | |
| 1829 | − pe.imagebase = 0x00010000; | |
| 1830 | −#else | |
| 1831 | − pe.imagebase = 0x00400000; | |
| 1832 | −#endif | |
| 1833 | − } | |
| 1834 | − | |
| 1835 | −#if defined(TCC_TARGET_ARM) | |
| 1836 | − /* we use "console" subsystem by default */ | |
| 1837 | − pe.subsystem = 9; | |
| 1838 | −#else | |
| 1839 | − if (PE_DLL == pe.type || PE_GUI == pe.type) | |
| 1840 | − pe.subsystem = 2; | |
| 1841 | − else | |
| 1842 | − pe.subsystem = 3; | |
| 1843 | −#endif | |
| 1844 | − /* Allow override via -Wl,-subsystem=... option */ | |
| 1845 | − if (s1->pe_subsystem != 0) | |
| 1846 | − pe.subsystem = s1->pe_subsystem; | |
| 1847 | − | |
| 1848 | − /* set default file/section alignment */ | |
| 1849 | − if (pe.subsystem == 1) { | |
| 1850 | − pe.section_align = 0x20; | |
| 1851 | − pe.file_align = 0x20; | |
| 1852 | − } else { | |
| 1853 | − pe.section_align = 0x1000; | |
| 1854 | − pe.file_align = 0x200; | |
| 1855 | − } | |
| 1856 | − | |
| 1857 | − if (s1->section_align != 0) | |
| 1858 | − pe.section_align = s1->section_align; | |
| 1859 | − if (s1->pe_file_align != 0) | |
| 1860 | − pe.file_align = s1->pe_file_align; | |
| 1861 | − | |
| 1862 | − if ((pe.subsystem >= 10) && (pe.subsystem <= 12)) | |
| 1863 | − pe.imagebase = 0; | |
| 1864 | − | |
| 1865 | − if (s1->has_text_addr) | |
| 1866 | − pe.imagebase = s1->text_addr; | |
| 1867 | − | |
| 1868 | 1874 | pe_assign_addresses(&pe); |
| 1869 | 1875 | relocate_syms(s1, 0); |
| 1870 | 1876 | for (i = 1; i < s1->nb_sections; ++i) { |
| @@ -3458,7 +3458,7 @@ ST_INLN void unget_tok(int last_tok) · 3457 unmodified lines | ||
| 3458 | 3458 | tok = last_tok; |
| 3459 | 3459 | } |
| 3460 | 3460 | |
| 3461 | −ST_FUNC void preprocess_init(TCCState *s1) | |
| 3461 | +ST_FUNC void preprocess_start(TCCState *s1) | |
| 3462 | 3462 | { |
| 3463 | 3463 | s1->include_stack_ptr = s1->include_stack; |
| 3464 | 3464 | /* XXX: move that before to avoid having to initialize |
| @@ -3477,11 +3477,14 @@ ST_FUNC void preprocess_init(TCCState *s1) · 12 unmodified lines | ||
| 3477 | 3477 | (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0; |
| 3478 | 3478 | } |
| 3479 | 3479 | |
| 3480 | −ST_FUNC void preprocess_new(void) | |
| 3480 | +ST_FUNC void tccpp_new(TCCState *s) | |
| 3481 | 3481 | { |
| 3482 | 3482 | int i, c; |
| 3483 | 3483 | const char *p, *r; |
| 3484 | 3484 | |
| 3485 | + /* might be used in error() before preprocess_start() */ | |
| 3486 | + s->include_stack_ptr = s->include_stack; | |
| 3487 | + | |
| 3485 | 3488 | /* init isid table */ |
| 3486 | 3489 | for(i = CH_EOF; i<128; i++) |
| 3487 | 3490 | isidnum_table[i - CH_EOF] |
| @@ -3518,7 +3521,7 @@ ST_FUNC void preprocess_new(void) · 30 unmodified lines | ||
| 3518 | 3521 | } |
| 3519 | 3522 | } |
| 3520 | 3523 | |
| 3521 | −ST_FUNC void preprocess_delete(void) | |
| 3524 | +ST_FUNC void tccpp_delete(TCCState *s) | |
| 3522 | 3525 | { |
| 3523 | 3526 | int i, n; |
| 3524 | 3527 | |
| @@ -3683,7 +3686,7 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 158 unmodified lines | ||
| 3683 | 3686 | const char *p; |
| 3684 | 3687 | Sym *define_start; |
| 3685 | 3688 | |
| 3686 | − preprocess_init(s1); | |
| 3689 | + preprocess_start(s1); | |
| 3687 | 3690 | ch = file->buf_ptr[0]; |
| 3688 | 3691 | tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; |
| 3689 | 3692 | parse_flags = PARSE_FLAG_PREPROCESS |
| @@ -23,20 +23,28 @@ · 22 unmodified lines | ||
| 23 | 23 | /* only native compiler supports -run */ |
| 24 | 24 | #ifdef TCC_IS_NATIVE |
| 25 | 25 | |
| 26 | +#ifndef _WIN32 | |
| 27 | +# include <sys/mman.h> | |
| 28 | +#endif | |
| 29 | + | |
| 26 | 30 | #ifdef CONFIG_TCC_BACKTRACE |
| 31 | +# ifndef _WIN32 | |
| 32 | +# include <signal.h> | |
| 33 | +# ifndef __OpenBSD__ | |
| 34 | +# include <sys/ucontext.h> | |
| 35 | +# endif | |
| 36 | +# else | |
| 37 | +# define ucontext_t CONTEXT | |
| 38 | +# endif | |
| 27 | 39 | ST_DATA int rt_num_callers = 6; |
| 28 | 40 | ST_DATA const char **rt_bound_error_msg; |
| 29 | 41 | ST_DATA void *rt_prog_main; |
| 30 | −#endif | |
| 31 | − | |
| 32 | −#ifdef _WIN32 | |
| 33 | −#define ucontext_t CONTEXT | |
| 42 | +static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level); | |
| 43 | +static void rt_error(ucontext_t *uc, const char *fmt, ...); | |
| 44 | +static void set_exception_handler(void); | |
| 34 | 45 | #endif |
| 35 | 46 | |
| 36 | 47 | static void set_pages_executable(void *ptr, unsigned long length); |
| 37 | −static void set_exception_handler(void); | |
| 38 | −static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level); | |
| 39 | −static void rt_error(ucontext_t *uc, const char *fmt, ...); | |
| 40 | 48 | static int tcc_relocate_ex(TCCState *s1, void *ptr); |
| 41 | 49 | |
| 42 | 50 | #ifdef _WIN64 |
| @@ -31,8 +31,9 @@ · 30 unmodified lines | ||
| 31 | 31 | #define __int16 short |
| 32 | 32 | #define __int32 int |
| 33 | 33 | #define __int64 long long |
| 34 | +#define _HAVE_INT64 | |
| 34 | 35 | |
| 35 | −#define __cdecl __attribute__((__cdecl__)) | |
| 36 | +#define __cdecl | |
| 36 | 37 | #define __declspec(x) __attribute__((x)) |
| 37 | 38 | #define __unaligned __attribute__((packed)) |
| 38 | 39 | #define __fastcall __attribute__((fastcall)) |
| @@ -71,12 +72,15 @@ · 32 unmodified lines | ||
| 71 | 72 | #define __stdcall |
| 72 | 73 | #define _AMD64_ 1 |
| 73 | 74 | #define __x86_64 1 |
| 75 | +#define _M_X64 100 /* Visual Studio */ | |
| 76 | +#define _M_AMD64 100 /* Visual Studio */ | |
| 74 | 77 | #define USE_MINGW_SETJMP_TWO_ARGS |
| 75 | 78 | #define mingw_getsp tinyc_getbp |
| 76 | 79 | #define __TRY__ |
| 77 | 80 | #else |
| 78 | 81 | #define __stdcall __attribute__((__stdcall__)) |
| 79 | 82 | #define _X86_ 1 |
| 83 | +#define _M_IX86 300 /* Visual Studio */ | |
| 80 | 84 | #define WIN32 1 |
| 81 | 85 | #define _USE_32BIT_TIME_T |
| 82 | 86 | #define __TRY__ void __try__(void**), *_sehrec[6]; __try__(_sehrec); |
| @@ -89,34 +93,36 @@ · 6 unmodified lines | ||
| 89 | 93 | #define _WCHAR_T_DEFINED |
| 90 | 94 | #define _UINTPTR_T_DEFINED |
| 91 | 95 | #define _INTPTR_T_DEFINED |
| 92 | − | |
| 93 | 96 | #define _INTEGRAL_MAX_BITS 64 |
| 94 | 97 | |
| 95 | −typedef long __time32_t; | |
| 98 | +#ifndef _TIME32_T_DEFINED | |
| 96 | 99 | #define _TIME32_T_DEFINED |
| 97 | −typedef __int64 __time64_t; | |
| 100 | +typedef long __time32_t; | |
| 101 | +#endif | |
| 102 | + | |
| 103 | +#ifndef _TIME64_T_DEFINED | |
| 98 | 104 | #define _TIME64_T_DEFINED |
| 105 | +typedef long long __time64_t; | |
| 106 | +#endif | |
| 107 | + | |
| 108 | +#ifndef _TIME_T_DEFINED | |
| 109 | +#define _TIME_T_DEFINED | |
| 99 | 110 | #ifdef _USE_32BIT_TIME_T |
| 100 | 111 | typedef __time32_t time_t; |
| 101 | −#define _TIME_T_DEFINED | |
| 102 | 112 | #else |
| 103 | 113 | typedef __time64_t time_t; |
| 104 | −#define _TIME_T_DEFINED | |
| 105 | 114 | #endif |
| 106 | − | |
| 107 | −#if 0 // defined in stddef.h | |
| 108 | −typedef unsigned long size_t; | |
| 109 | −typedef long ssize_t; | |
| 110 | −typedef unsigned short wchar_t; | |
| 111 | 115 | #endif |
| 112 | −#define _SIZE_T_DEFINED | |
| 113 | −#define _SSIZE_T_DEFINED | |
| 114 | −#define _WCHAR_T_DEFINED | |
| 115 | 116 | |
| 116 | −typedef unsigned short wctype_t; | |
| 117 | −typedef unsigned int wint_t; | |
| 117 | +#ifndef _WCTYPE_T_DEFINED | |
| 118 | 118 | #define _WCTYPE_T_DEFINED |
| 119 | +typedef wchar_t wctype_t; | |
| 120 | +#endif | |
| 121 | + | |
| 122 | +#ifndef _WINT_T | |
| 119 | 123 | #define _WINT_T |
| 124 | +typedef __WINT_TYPE__ wint_t; | |
| 125 | +#endif | |
| 120 | 126 | |
| 121 | 127 | typedef int errno_t; |
| 122 | 128 | #define _ERRCODE_DEFINED |