- libtcc.c/tccpp.c: fix -U option for multiple input files - libtcc: remove decl of tcc_add_crt() for PE - tcc.h: define __i386__ and __x86_64__ for msvc - tcc.h: undef __attribute__ for __TINYC__ on gnu/linux platforms - tccelf.c: disable prepare_dynamic_rel unless x86/x64 - tccpe.c: construct rather than predefine PE section flags - tccpp.c: (alt.) fix access of dead stack variable after error/longjmp - x86_64-gen.c: fix func_alloca chain for nocode_wanted - tccpp.c/tccgen.c: improve file:line info for inline functions - winapi/winnt.h: correct position for DECLSPEC_ALIGN attribute - win32/lib/crt: simplify top exception handler (needed for signal) - arm64-gen.c: remove dprintf left from VT_CMP commit - tccgen.c: limit binary scan with gcase to > 8 (= smaller code) - tccgen.c: call save_regs(4) in gen_opl for cmp-ops (see test in tcctest.c)
Unified · Split
| @@ -91,9 +91,6 @@ static uint32_t fltr(int r) · 90 unmodified lines | |||
| 91 | return r - TREG_F(0); | 91 | return r - TREG_F(0); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | #define dprintf(x) ((void)(tcc_state->verbose == 2 && printf x)) | ||
| 95 | //#define dprintf(x) | ||
| 96 | |||
| 97 | // Add an instruction to text section: | 94 | // Add an instruction to text section: |
| 98 | ST_FUNC void o(unsigned int c) | 95 | ST_FUNC void o(unsigned int c) |
| 99 | { | 96 | { |
| @@ -103,7 +100,6 @@ ST_FUNC void o(unsigned int c) · 3 unmodified lines | |||
| 103 | if (ind1 > cur_text_section->data_allocated) | 100 | if (ind1 > cur_text_section->data_allocated) |
| 104 | section_realloc(cur_text_section, ind1); | 101 | section_realloc(cur_text_section, ind1); |
| 105 | write32le(cur_text_section->data + ind, c); | 102 | write32le(cur_text_section->data + ind, c); |
| 106 | dprintf(("o %04x : %08x\n", ind, c)); //gr | ||
| 107 | ind = ind1; | 103 | ind = ind1; |
| 108 | } | 104 | } |
| 109 | 105 | ||
| @@ -236,7 +232,6 @@ ST_FUNC void gsym_addr(int t_, int a_) · 126 unmodified lines | |||
| 236 | tcc_error("branch out of range"); | 232 | tcc_error("branch out of range"); |
| 237 | write32le(ptr, (a - t == 4 ? 0xd503201f : // nop | 233 | write32le(ptr, (a - t == 4 ? 0xd503201f : // nop |
| 238 | 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b | 234 | 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b |
| 239 | dprintf((". gsym TARG=%04x ADDR=%04x\n", t, a)); //gr | ||
| 240 | t = next; | 235 | t = next; |
| 241 | } | 236 | } |
| 242 | } | 237 | } |
| @@ -1296,7 +1291,6 @@ ST_FUNC void gen_fill_nops(int bytes) · 1053 unmodified lines | |||
| 1296 | ST_FUNC int gjmp(int t) | 1291 | ST_FUNC int gjmp(int t) |
| 1297 | { | 1292 | { |
| 1298 | int r = ind; | 1293 | int r = ind; |
| 1299 | dprintf((". gjmp T=%04x\n", t)); //gr | ||
| 1300 | if (nocode_wanted) | 1294 | if (nocode_wanted) |
| 1301 | return t; | 1295 | return t; |
| 1302 | o(t); | 1296 | o(t); |
| @@ -1308,7 +1302,6 @@ ST_FUNC void gjmp_addr(int a) · 5 unmodified lines | |||
| 1308 | { | 1302 | { |
| 1309 | assert(a - ind + 0x8000000 < 0x10000000); | 1303 | assert(a - ind + 0x8000000 < 0x10000000); |
| 1310 | o(0x14000000 | ((a - ind) >> 2 & 0x3ffffff)); | 1304 | o(0x14000000 | ((a - ind) >> 2 & 0x3ffffff)); |
| 1311 | dprintf((". gjmp_addr T=%04x\n", a)); //gr | ||
| 1312 | } | 1305 | } |
| 1313 | 1306 | ||
| 1314 | ST_FUNC int gjmp_append(int n, int t) | 1307 | ST_FUNC int gjmp_append(int n, int t) |
| @@ -1330,7 +1323,6 @@ void arm64_vset_VT_CMP(int op) · 15 unmodified lines | |||
| 1330 | if (op >= TOK_ULT && op <= TOK_GT) { | 1323 | if (op >= TOK_ULT && op <= TOK_GT) { |
| 1331 | vtop->cmp_r = vtop->r; | 1324 | vtop->cmp_r = vtop->r; |
| 1332 | vset_VT_CMP(0x80); | 1325 | vset_VT_CMP(0x80); |
| 1333 | dprintf((". set VT_CMP OP(%s) R=%x\n", get_tok_str(op, 0), vtop->cmp_r)); | ||
| 1334 | } | 1326 | } |
| 1335 | } | 1327 | } |
| 1336 | 1328 | ||
| @@ -1339,7 +1331,6 @@ static void arm64_gen_opil(int op, uint32_t l); · 2 unmodified lines | |||
| 1339 | static void arm64_load_cmp(int r, SValue *sv) | 1331 | static void arm64_load_cmp(int r, SValue *sv) |
| 1340 | { | 1332 | { |
| 1341 | sv->r = sv->cmp_r; | 1333 | sv->r = sv->cmp_r; |
| 1342 | dprintf((". load VT_CMP OP(%x), R=%x/%x\n", (int)sv->c.i, sv->r, r)); | ||
| 1343 | if (sv->c.i & 1) { | 1334 | if (sv->c.i & 1) { |
| 1344 | vpushi(1); | 1335 | vpushi(1); |
| 1345 | arm64_gen_opil('^', 0); | 1336 | arm64_gen_opil('^', 0); |
| @@ -1348,7 +1339,6 @@ static void arm64_load_cmp(int r, SValue *sv) · 2 unmodified lines | |||
| 1348 | load(r, sv); | 1339 | load(r, sv); |
| 1349 | sv->r = r; | 1340 | sv->r = r; |
| 1350 | } | 1341 | } |
| 1351 | dprintf((". load VT_CMP done\n")); //gr | ||
| 1352 | } | 1342 | } |
| 1353 | 1343 | ||
| 1354 | ST_FUNC int gjmp_cond(int op, int t) | 1344 | ST_FUNC int gjmp_cond(int op, int t) |
| @@ -1357,7 +1347,6 @@ ST_FUNC int gjmp_cond(int op, int t) · 2 unmodified lines | |||
| 1357 | 1347 | ||
| 1358 | int inv = op & 1; | 1348 | int inv = op & 1; |
| 1359 | vtop->r = vtop->cmp_r; | 1349 | vtop->r = vtop->cmp_r; |
| 1360 | dprintf((". gjmp_cond OP(%x) R=%x T=%04x\n", op, vtop->r, t)); //gr | ||
| 1361 | 1350 | ||
| 1362 | if (bt == VT_LDOUBLE) { | 1351 | if (bt == VT_LDOUBLE) { |
| 1363 | uint32_t a, b, f = fltr(gv(RC_FLOAT)); | 1352 | uint32_t a, b, f = fltr(gv(RC_FLOAT)); |
| @@ -700,9 +700,11 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym) · 699 unmodified lines | |||
| 700 | Sym *s; | 700 | Sym *s; |
| 701 | ts = tok_alloc(sym, strlen(sym)); | 701 | ts = tok_alloc(sym, strlen(sym)); |
| 702 | s = define_find(ts->tok); | 702 | s = define_find(ts->tok); |
| 703 | /* undefine symbol by putting an invalid name */ | 703 | if (s) { |
| 704 | if (s) | ||
| 705 | define_undef(s); | 704 | define_undef(s); |
| 705 | tok_str_free_str(s->d); | ||
| 706 | s->d = NULL; | ||
| 707 | } | ||
| 706 | } | 708 | } |
| 707 | 709 | ||
| 708 | /* cleanup all static data used during compilation */ | 710 | /* cleanup all static data used during compilation */ |
| @@ -1118,6 +1120,7 @@ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) · 409 unmodified lines | |||
| 1118 | s->library_paths, s->nb_library_paths); | 1120 | s->library_paths, s->nb_library_paths); |
| 1119 | } | 1121 | } |
| 1120 | 1122 | ||
| 1123 | #ifndef TCC_TARGET_PE | ||
| 1121 | ST_FUNC int tcc_add_crt(TCCState *s, const char *filename) | 1124 | ST_FUNC int tcc_add_crt(TCCState *s, const char *filename) |
| 1122 | { | 1125 | { |
| 1123 | if (-1 == tcc_add_library_internal(s, "%s/%s", | 1126 | if (-1 == tcc_add_library_internal(s, "%s/%s", |
| @@ -1125,6 +1128,7 @@ ST_FUNC int tcc_add_crt(TCCState *s, const char *filename) · 1 unmodified line | |||
| 1125 | tcc_error_noabort("file '%s' not found", filename); | 1128 | tcc_error_noabort("file '%s' not found", filename); |
| 1126 | return 0; | 1129 | return 0; |
| 1127 | } | 1130 | } |
| 1131 | #endif | ||
| 1128 | 1132 | ||
| 1129 | /* the library name is the same as the argument of the '-l' option */ | 1133 | /* the library name is the same as the argument of the '-l' option */ |
| 1130 | LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) | 1134 | LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) |
| @@ -73,6 +73,12 @@ extern long double strtold (const char *__nptr, char **__endptr); · 72 unmodified lines | |||
| 73 | # pragma warning (disable : 4018) // signed/unsigned mismatch | 73 | # pragma warning (disable : 4018) // signed/unsigned mismatch |
| 74 | # pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned | 74 | # pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned |
| 75 | # define ssize_t intptr_t | 75 | # define ssize_t intptr_t |
| 76 | # ifdef _X86_ | ||
| 77 | # define __i386__ 1 | ||
| 78 | # endif | ||
| 79 | # ifdef _AMD64_ | ||
| 80 | # define __x86_64__ 1 | ||
| 81 | # endif | ||
| 76 | # endif | 82 | # endif |
| 77 | # undef CONFIG_TCC_STATIC | 83 | # undef CONFIG_TCC_STATIC |
| 78 | #endif | 84 | #endif |
| @@ -97,6 +103,11 @@ extern long double strtold (const char *__nptr, char **__endptr); · 18 unmodified lines | |||
| 97 | # define ALIGNED(x) __attribute__((aligned(x))) | 103 | # define ALIGNED(x) __attribute__((aligned(x))) |
| 98 | #endif | 104 | #endif |
| 99 | 105 | ||
| 106 | /* gnu headers use to #define __attribute__ to empty for non-gcc compilers */ | ||
| 107 | #ifdef __TINYC__ | ||
| 108 | # undef __attribute__ | ||
| 109 | #endif | ||
| 110 | |||
| 100 | #ifdef _WIN32 | 111 | #ifdef _WIN32 |
| 101 | # define IS_DIRSEP(c) (c == '/' || c == '\\') | 112 | # define IS_DIRSEP(c) (c == '/' || c == '\\') |
| 102 | # define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2]))) | 113 | # define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2]))) |
| @@ -133,7 +144,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 30 unmodified lines | |||
| 133 | #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ | 144 | #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ |
| 134 | !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \ | 145 | !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \ |
| 135 | !defined(TCC_TARGET_X86_64) | 146 | !defined(TCC_TARGET_X86_64) |
| 136 | # if defined __x86_64__ || defined _AMD64_ | 147 | # if defined __x86_64__ |
| 137 | # define TCC_TARGET_X86_64 | 148 | # define TCC_TARGET_X86_64 |
| 138 | # elif defined __arm__ | 149 | # elif defined __arm__ |
| 139 | # define TCC_TARGET_ARM | 150 | # define TCC_TARGET_ARM |
| @@ -151,9 +162,9 @@ extern long double strtold (const char *__nptr, char **__endptr); · 11 unmodified lines | |||
| 151 | 162 | ||
| 152 | /* only native compiler supports -run */ | 163 | /* only native compiler supports -run */ |
| 153 | #if defined _WIN32 == defined TCC_TARGET_PE | 164 | #if defined _WIN32 == defined TCC_TARGET_PE |
| 154 | # if (defined __i386__ || defined _X86_) && defined TCC_TARGET_I386 | 165 | # if defined __i386__ && defined TCC_TARGET_I386 |
| 155 | # define TCC_IS_NATIVE | 166 | # define TCC_IS_NATIVE |
| 156 | # elif (defined __x86_64__ || defined _AMD64_) && defined TCC_TARGET_X86_64 | 167 | # elif defined __x86_64__ && defined TCC_TARGET_X86_64 |
| 157 | # define TCC_IS_NATIVE | 168 | # define TCC_IS_NATIVE |
| 158 | # elif defined __arm__ && defined TCC_TARGET_ARM | 169 | # elif defined __arm__ && defined TCC_TARGET_ARM |
| 159 | # define TCC_IS_NATIVE | 170 | # define TCC_IS_NATIVE |
| @@ -1179,7 +1190,9 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 1019 unmodified lines | |||
| 1179 | #define AFF_BINTYPE_C67 4 | 1190 | #define AFF_BINTYPE_C67 4 |
| 1180 | 1191 | ||
| 1181 | 1192 | ||
| 1193 | #ifndef TCC_TARGET_PE | ||
| 1182 | ST_FUNC int tcc_add_crt(TCCState *s, const char *filename); | 1194 | ST_FUNC int tcc_add_crt(TCCState *s, const char *filename); |
| 1195 | #endif | ||
| 1183 | ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags); | 1196 | ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags); |
| 1184 | ST_FUNC void tcc_add_pragma_libs(TCCState *s1); | 1197 | ST_FUNC void tcc_add_pragma_libs(TCCState *s1); |
| 1185 | PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f); | 1198 | PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f); |
| @@ -171,7 +171,7 @@ ST_FUNC void tccelf_end_file(TCCState *s1) · 170 unmodified lines | |||
| 171 | && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) | 171 | && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) |
| 172 | sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info)); | 172 | sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info)); |
| 173 | tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info, | 173 | tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info, |
| 174 | sym->st_other, sym->st_shndx, s->link->data + sym->st_name); | 174 | sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name); |
| 175 | } | 175 | } |
| 176 | /* now update relocations */ | 176 | /* now update relocations */ |
| 177 | for (i = 1; i < s1->nb_sections; i++) { | 177 | for (i = 1; i < s1->nb_sections; i++) { |
| @@ -865,17 +865,13 @@ static void relocate_rel(TCCState *s1, Section *sr) · 687 unmodified lines | |||
| 865 | their space */ | 865 | their space */ |
| 866 | static int prepare_dynamic_rel(TCCState *s1, Section *sr) | 866 | static int prepare_dynamic_rel(TCCState *s1, Section *sr) |
| 867 | { | 867 | { |
| 868 | int count = 0; | ||
| 869 | #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) | ||
| 868 | ElfW_Rel *rel; | 870 | ElfW_Rel *rel; |
| 869 | int type, count; | ||
| 870 | |||
| 871 | count = 0; | ||
| 872 | for_each_elem(sr, 0, rel, ElfW_Rel) { | 871 | for_each_elem(sr, 0, rel, ElfW_Rel) { |
| 873 | #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) | ||
| 874 | int sym_index = ELFW(R_SYM)(rel->r_info); | 872 | int sym_index = ELFW(R_SYM)(rel->r_info); |
| 875 | #endif | 873 | int type = ELFW(R_TYPE)(rel->r_info); |
| 876 | type = ELFW(R_TYPE)(rel->r_info); | ||
| 877 | switch(type) { | 874 | switch(type) { |
| 878 | #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) | ||
| 879 | #if defined(TCC_TARGET_I386) | 875 | #if defined(TCC_TARGET_I386) |
| 880 | case R_386_32: | 876 | case R_386_32: |
| 881 | if (!get_sym_attr(s1, sym_index, 0)->dyn_index | 877 | if (!get_sym_attr(s1, sym_index, 0)->dyn_index |
| @@ -899,7 +895,6 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 17 unmodified lines | |||
| 899 | if (get_sym_attr(s1, sym_index, 0)->dyn_index) | 895 | if (get_sym_attr(s1, sym_index, 0)->dyn_index) |
| 900 | count++; | 896 | count++; |
| 901 | break; | 897 | break; |
| 902 | #endif | ||
| 903 | default: | 898 | default: |
| 904 | break; | 899 | break; |
| 905 | } | 900 | } |
| @@ -909,6 +904,7 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 3 unmodified lines | |||
| 909 | sr->sh_flags |= SHF_ALLOC; | 904 | sr->sh_flags |= SHF_ALLOC; |
| 910 | sr->sh_size = count * sizeof(ElfW_Rel); | 905 | sr->sh_size = count * sizeof(ElfW_Rel); |
| 911 | } | 906 | } |
| 907 | #endif | ||
| 912 | return count; | 908 | return count; |
| 913 | } | 909 | } |
| 914 | 910 | ||
| @@ -1990,6 +1990,7 @@ static void gen_opl(int op) · 1989 unmodified lines | |||
| 1990 | vtop[-1] = vtop[-2]; | 1990 | vtop[-1] = vtop[-2]; |
| 1991 | vtop[-2] = tmp; | 1991 | vtop[-2] = tmp; |
| 1992 | /* stack: L1 L2 H1 H2 */ | 1992 | /* stack: L1 L2 H1 H2 */ |
| 1993 | save_regs(4); | ||
| 1993 | /* compare high */ | 1994 | /* compare high */ |
| 1994 | op1 = op; | 1995 | op1 = op; |
| 1995 | /* when values are equal, we need to compare low words. since | 1996 | /* when values are equal, we need to compare low words. since |
| @@ -2205,7 +2206,7 @@ static void gen_opif(int op) · 209 unmodified lines | |||
| 2205 | { | 2206 | { |
| 2206 | int c1, c2; | 2207 | int c1, c2; |
| 2207 | SValue *v1, *v2; | 2208 | SValue *v1, *v2; |
| 2208 | #if defined _MSC_VER && defined _AMD64_ | 2209 | #if defined _MSC_VER && defined __x86_64__ |
| 2209 | /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */ | 2210 | /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */ |
| 2210 | volatile | 2211 | volatile |
| 2211 | #endif | 2212 | #endif |
| @@ -4497,6 +4498,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 2285 unmodified lines | |||
| 4497 | if (n < TOK_UIDENT) | 4498 | if (n < TOK_UIDENT) |
| 4498 | expect("identifier"); | 4499 | expect("identifier"); |
| 4499 | pt.t = VT_VOID; /* invalid type */ | 4500 | pt.t = VT_VOID; /* invalid type */ |
| 4501 | pt.ref = NULL; | ||
| 4500 | next(); | 4502 | next(); |
| 4501 | } | 4503 | } |
| 4502 | convert_parameter_type(&pt); | 4504 | convert_parameter_type(&pt); |
| @@ -6113,7 +6115,7 @@ static void gcase(struct case_t **base, int len, int *bsym) · 1610 unmodified lines | |||
| 6113 | struct case_t *p; | 6115 | struct case_t *p; |
| 6114 | int e; | 6116 | int e; |
| 6115 | int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG; | 6117 | int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG; |
| 6116 | while (len > 4) { | 6118 | while (len > 8) { |
| 6117 | /* binary search */ | 6119 | /* binary search */ |
| 6118 | p = base[len/2]; | 6120 | p = base[len/2]; |
| 6119 | vdup(); | 6121 | vdup(); |
| @@ -7538,10 +7540,10 @@ static void gen_function(Sym *sym) · 1418 unmodified lines | |||
| 7538 | static void gen_inline_functions(TCCState *s) | 7540 | static void gen_inline_functions(TCCState *s) |
| 7539 | { | 7541 | { |
| 7540 | Sym *sym; | 7542 | Sym *sym; |
| 7541 | int inline_generated, i, ln; | 7543 | int inline_generated, i; |
| 7542 | struct InlineFunc *fn; | 7544 | struct InlineFunc *fn; |
| 7543 | 7545 | ||
| 7544 | ln = file->line_num; | 7546 | tcc_open_bf(s, ":inline:", 0); |
| 7545 | /* iterate while inline function are referenced */ | 7547 | /* iterate while inline function are referenced */ |
| 7546 | do { | 7548 | do { |
| 7547 | inline_generated = 0; | 7549 | inline_generated = 0; |
| @@ -7564,7 +7566,7 @@ static void gen_inline_functions(TCCState *s) · 16 unmodified lines | |||
| 7564 | } | 7566 | } |
| 7565 | } | 7567 | } |
| 7566 | } while (inline_generated); | 7568 | } while (inline_generated); |
| 7567 | file->line_num = ln; | 7569 | tcc_close(); |
| 7568 | } | 7570 | } |
| 7569 | 7571 | ||
| 7570 | ST_FUNC void free_inline_functions(TCCState *s) | 7572 | ST_FUNC void free_inline_functions(TCCState *s) |
| @@ -231,6 +231,17 @@ typedef struct _IMAGE_BASE_RELOCATION { · 230 unmodified lines | |||
| 231 | #define IMAGE_REL_BASED_REL32 7 | 231 | #define IMAGE_REL_BASED_REL32 7 |
| 232 | #define IMAGE_REL_BASED_DIR64 10 | 232 | #define IMAGE_REL_BASED_DIR64 10 |
| 233 | 233 | ||
| 234 | #define IMAGE_SCN_CNT_CODE 0x00000020 | ||
| 235 | #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 | ||
| 236 | #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 | ||
| 237 | #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 | ||
| 238 | #define IMAGE_SCN_MEM_SHARED 0x10000000 | ||
| 239 | #define IMAGE_SCN_MEM_EXECUTE 0x20000000 | ||
| 240 | #define IMAGE_SCN_MEM_READ 0x40000000 | ||
| 241 | #define IMAGE_SCN_MEM_WRITE 0x80000000 | ||
| 242 | #define IMAGE_SCN_TYPE_NOLOAD 0x00000002 | ||
| 243 | #define IMAGE_SCN_LNK_REMOVE 0x00000800 | ||
| 244 | |||
| 234 | #pragma pack(pop) | 245 | #pragma pack(pop) |
| 235 | 246 | ||
| 236 | /* ----------------------------------------------------------- */ | 247 | /* ----------------------------------------------------------- */ |
| @@ -279,17 +290,6 @@ struct pe_rsrc_reloc { · 42 unmodified lines | |||
| 279 | /* ------------------------------------------------------------- */ | 290 | /* ------------------------------------------------------------- */ |
| 280 | /* internal temporary structures */ | 291 | /* internal temporary structures */ |
| 281 | 292 | ||
| 282 | /* | ||
| 283 | #define IMAGE_SCN_CNT_CODE 0x00000020 | ||
| 284 | #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 | ||
| 285 | #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 | ||
| 286 | #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 | ||
| 287 | #define IMAGE_SCN_MEM_SHARED 0x10000000 | ||
| 288 | #define IMAGE_SCN_MEM_EXECUTE 0x20000000 | ||
| 289 | #define IMAGE_SCN_MEM_READ 0x40000000 | ||
| 290 | #define IMAGE_SCN_MEM_WRITE 0x80000000 | ||
| 291 | */ | ||
| 292 | |||
| 293 | enum { | 293 | enum { |
| 294 | sec_text = 0, | 294 | sec_text = 0, |
| 295 | sec_data , | 295 | sec_data , |
| @@ -303,6 +303,7 @@ enum { · 7 unmodified lines | |||
| 303 | sec_last | 303 | sec_last |
| 304 | }; | 304 | }; |
| 305 | 305 | ||
| 306 | #if 0 | ||
| 306 | static const DWORD pe_sec_flags[] = { | 307 | static const DWORD pe_sec_flags[] = { |
| 307 | 0x60000020, /* ".text" , */ | 308 | 0x60000020, /* ".text" , */ |
| 308 | 0xC0000040, /* ".data" , */ | 309 | 0xC0000040, /* ".data" , */ |
| @@ -314,13 +315,14 @@ static const DWORD pe_sec_flags[] = { · 5 unmodified lines | |||
| 314 | 0x42000802, /* ".stab" , */ | 315 | 0x42000802, /* ".stab" , */ |
| 315 | 0x42000040, /* ".reloc" , */ | 316 | 0x42000040, /* ".reloc" , */ |
| 316 | }; | 317 | }; |
| 318 | #endif | ||
| 317 | 319 | ||
| 318 | struct section_info { | 320 | struct section_info { |
| 319 | int cls, ord; | 321 | int cls, ord; |
| 320 | char name[32]; | 322 | char name[32]; |
| 321 | DWORD sh_addr; | 323 | DWORD sh_addr; |
| 322 | DWORD sh_size; | 324 | DWORD sh_size; |
| 323 | DWORD sh_flags; | 325 | DWORD pe_flags; |
| 324 | unsigned char *data; | 326 | unsigned char *data; |
| 325 | DWORD data_size; | 327 | DWORD data_size; |
| 326 | IMAGE_SECTION_HEADER ish; | 328 | IMAGE_SECTION_HEADER ish; |
| @@ -656,9 +658,6 @@ static int pe_write(struct pe_info *pe) · 329 unmodified lines | |||
| 656 | case sec_pdata: | 658 | case sec_pdata: |
| 657 | pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXCEPTION, addr, size); | 659 | pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXCEPTION, addr, size); |
| 658 | break; | 660 | break; |
| 659 | |||
| 660 | case sec_stab: | ||
| 661 | break; | ||
| 662 | } | 661 | } |
| 663 | 662 | ||
| 664 | if (pe->thunk == pe->s1->sections[si->ord]) { | 663 | if (pe->thunk == pe->s1->sections[si->ord]) { |
| @@ -676,7 +675,7 @@ static int pe_write(struct pe_info *pe) · 11 unmodified lines | |||
| 676 | 675 | ||
| 677 | strncpy((char*)psh->Name, sh_name, sizeof psh->Name); | 676 | strncpy((char*)psh->Name, sh_name, sizeof psh->Name); |
| 678 | 677 | ||
| 679 | psh->Characteristics = pe_sec_flags[si->cls]; | 678 | psh->Characteristics = si->pe_flags; |
| 680 | psh->VirtualAddress = addr; | 679 | psh->VirtualAddress = addr; |
| 681 | psh->Misc.VirtualSize = size; | 680 | psh->Misc.VirtualSize = size; |
| 682 | pe_header.opthdr.SizeOfImage = | 681 | pe_header.opthdr.SizeOfImage = |
| @@ -1064,15 +1063,15 @@ static int pe_section_class(Section *s) · 381 unmodified lines | |||
| 1064 | return sec_idata; | 1063 | return sec_idata; |
| 1065 | if (0 == strcmp(name, ".pdata")) | 1064 | if (0 == strcmp(name, ".pdata")) |
| 1066 | return sec_pdata; | 1065 | return sec_pdata; |
| 1067 | return sec_other; | ||
| 1068 | } else if (type == SHT_NOBITS) { | 1066 | } else if (type == SHT_NOBITS) { |
| 1069 | if (flags & SHF_WRITE) | 1067 | if (flags & SHF_WRITE) |
| 1070 | return sec_bss; | 1068 | return sec_bss; |
| 1071 | } | 1069 | } |
| 1070 | return sec_other; | ||
| 1072 | } else { | 1071 | } else { |
| 1073 | if (0 == strcmp(name, ".reloc")) | 1072 | if (0 == strcmp(name, ".reloc")) |
| 1074 | return sec_reloc; | 1073 | return sec_reloc; |
| 1075 | if (0 == strncmp(name, ".stab", 5)) /* .stab and .stabstr */ | 1074 | if (0 == memcmp(name, ".stab", 5)) |
| 1076 | return sec_stab; | 1075 | return sec_stab; |
| 1077 | } | 1076 | } |
| 1078 | return -1; | 1077 | return -1; |
| @@ -1129,7 +1128,21 @@ static int pe_assign_addresses (struct pe_info *pe) · 50 unmodified lines | |||
| 1129 | si->cls = c; | 1128 | si->cls = c; |
| 1130 | si->ord = k; | 1129 | si->ord = k; |
| 1131 | si->sh_addr = s->sh_addr = addr = pe_virtual_align(pe, addr); | 1130 | si->sh_addr = s->sh_addr = addr = pe_virtual_align(pe, addr); |
| 1132 | si->sh_flags = s->sh_flags; | 1131 | |
| 1132 | si->pe_flags = IMAGE_SCN_MEM_READ; | ||
| 1133 | if (s->sh_flags & SHF_EXECINSTR) | ||
| 1134 | si->pe_flags |= IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE; | ||
| 1135 | else if (s->sh_type == SHT_NOBITS) | ||
| 1136 | si->pe_flags |= IMAGE_SCN_CNT_UNINITIALIZED_DATA; | ||
| 1137 | else | ||
| 1138 | si->pe_flags |= IMAGE_SCN_CNT_INITIALIZED_DATA; | ||
| 1139 | if (s->sh_flags & SHF_WRITE) | ||
| 1140 | si->pe_flags |= IMAGE_SCN_MEM_WRITE; | ||
| 1141 | if (0 == (s->sh_flags & SHF_ALLOC)) { | ||
| 1142 | si->pe_flags |= IMAGE_SCN_MEM_DISCARDABLE; | ||
| 1143 | if (c == sec_stab) | ||
| 1144 | si->pe_flags |= 0x802; //IMAGE_SCN_TYPE_NOLOAD|IMAGE_SCN_LNK_REMOVE | ||
| 1145 | } | ||
| 1133 | 1146 | ||
| 1134 | if (c == sec_data && NULL == pe->thunk) | 1147 | if (c == sec_data && NULL == pe->thunk) |
| 1135 | pe->thunk = s; | 1148 | pe->thunk = s; |
| @@ -1153,9 +1166,8 @@ static int pe_assign_addresses (struct pe_info *pe) · 17 unmodified lines | |||
| 1153 | si->sh_size = s->data_offset; | 1166 | si->sh_size = s->data_offset; |
| 1154 | ++pe->sec_count; | 1167 | ++pe->sec_count; |
| 1155 | } | 1168 | } |
| 1156 | // printf("%08x %05x %s\n", si->sh_addr, si->sh_size, si->name); | 1169 | //printf("%08x %05x %s %08x\n", si->sh_addr, si->sh_size, si->name, si->pe_flags); |
| 1157 | } | 1170 | } |
| 1158 | |||
| 1159 | #if 0 | 1171 | #if 0 |
| 1160 | for (i = 1; i < pe->s1->nb_sections; ++i) { | 1172 | for (i = 1; i < pe->s1->nb_sections; ++i) { |
| 1161 | Section *s = pe->s1->sections[i]; | 1173 | Section *s = pe->s1->sections[i]; |
| @@ -1119,9 +1119,9 @@ ST_FUNC void end_macro(void) · 1118 unmodified lines | |||
| 1119 | macro_stack = str->prev; | 1119 | macro_stack = str->prev; |
| 1120 | macro_ptr = str->prev_ptr; | 1120 | macro_ptr = str->prev_ptr; |
| 1121 | file->line_num = str->save_line_num; | 1121 | file->line_num = str->save_line_num; |
| 1122 | if (str->alloc == 2) { | 1122 | if (str->alloc != 0) { |
| 1123 | str->alloc = 3; /* just mark as finished */ | 1123 | if (str->alloc == 2) |
| 1124 | } else { | 1124 | str->str = NULL; /* don't free */ |
| 1125 | tok_str_free(str); | 1125 | tok_str_free(str); |
| 1126 | } | 1126 | } |
| 1127 | } | 1127 | } |
| @@ -1345,7 +1345,7 @@ ST_FUNC void free_defines(Sym *b) · 217 unmodified lines | |||
| 1345 | int v = b->v; | 1345 | int v = b->v; |
| 1346 | if (v >= TOK_IDENT && v < tok_ident) { | 1346 | if (v >= TOK_IDENT && v < tok_ident) { |
| 1347 | Sym **d = &table_ident[v - TOK_IDENT]->sym_define; | 1347 | Sym **d = &table_ident[v - TOK_IDENT]->sym_define; |
| 1348 | if (!*d) | 1348 | if (!*d && b->d) |
| 1349 | *d = b; | 1349 | *d = b; |
| 1350 | } | 1350 | } |
| 1351 | b = b->prev; | 1351 | b = b->prev; |
| @@ -1799,9 +1799,9 @@ ST_FUNC void preprocess(int is_bof) · 447 unmodified lines | |||
| 1799 | 1799 | ||
| 1800 | if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) | 1800 | if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) |
| 1801 | tcc_error("#include recursion too deep"); | 1801 | tcc_error("#include recursion too deep"); |
| 1802 | /* store current file in stack, but increment stack later below */ | 1802 | /* push current file on stack */ |
| 1803 | *s1->include_stack_ptr = file; | 1803 | *s1->include_stack_ptr++ = file; |
| 1804 | i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0; | 1804 | i = tok == TOK_INCLUDE_NEXT ? file->include_next_index: 0; |
| 1805 | n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths; | 1805 | n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths; |
| 1806 | for (; i < n; ++i) { | 1806 | for (; i < n; ++i) { |
| 1807 | char buf1[sizeof file->filename]; | 1807 | char buf1[sizeof file->filename]; |
| @@ -1849,10 +1849,10 @@ ST_FUNC void preprocess(int is_bof) · 41 unmodified lines | |||
| 1849 | printf("%s: including %s\n", file->prev->filename, file->filename); | 1849 | printf("%s: including %s\n", file->prev->filename, file->filename); |
| 1850 | #endif | 1850 | #endif |
| 1851 | /* update target deps */ | 1851 | /* update target deps */ |
| 1852 | dynarray_add(&s1->target_deps, &s1->nb_target_deps, | 1852 | if (s1->gen_deps) { |
| 1853 | dynarray_add(&s1->target_deps, &s1->nb_target_deps, | ||
| 1853 | tcc_strdup(buf1)); | 1854 | tcc_strdup(buf1)); |
| 1854 | /* push current file in stack */ | 1855 | } |
| 1855 | ++s1->include_stack_ptr; | ||
| 1856 | /* add include file debug info */ | 1856 | /* add include file debug info */ |
| 1857 | if (s1->do_debug) | 1857 | if (s1->do_debug) |
| 1858 | put_stabs(file->filename, N_BINCL, 0, 0, 0); | 1858 | put_stabs(file->filename, N_BINCL, 0, 0, 0); |
| @@ -1862,6 +1862,7 @@ ST_FUNC void preprocess(int is_bof) · 3 unmodified lines | |||
| 1862 | } | 1862 | } |
| 1863 | tcc_error("include file '%s' not found", buf); | 1863 | tcc_error("include file '%s' not found", buf); |
| 1864 | include_done: | 1864 | include_done: |
| 1865 | --s1->include_stack_ptr; | ||
| 1865 | break; | 1866 | break; |
| 1866 | case TOK_IFNDEF: | 1867 | case TOK_IFNDEF: |
| 1867 | c = 1; | 1868 | c = 1; |
| @@ -3486,14 +3487,14 @@ static void macro_subst( · 1618 unmodified lines | |||
| 3486 | } | 3487 | } |
| 3487 | 3488 | ||
| 3488 | { | 3489 | { |
| 3489 | TokenString str; | 3490 | TokenString *str = tok_str_alloc(); |
| 3490 | str.str = (int*)macro_str; | 3491 | str->str = (int*)macro_str; |
| 3491 | begin_macro(&str, 2); | 3492 | begin_macro(str, 2); |
| 3492 | 3493 | ||
| 3493 | tok = t; | 3494 | tok = t; |
| 3494 | macro_subst_tok(tok_str, nested_list, s); | 3495 | macro_subst_tok(tok_str, nested_list, s); |
| 3495 | 3496 | ||
| 3496 | if (str.alloc == 3) { | 3497 | if (macro_stack != str) { |
| 3497 | /* already finished by reading function macro arguments */ | 3498 | /* already finished by reading function macro arguments */ |
| 3498 | break; | 3499 | break; |
| 3499 | } | 3500 | } |
| @@ -3554,7 +3555,7 @@ ST_FUNC void next(void) · 54 unmodified lines | |||
| 3554 | tokstr_buf.len = 0; | 3555 | tokstr_buf.len = 0; |
| 3555 | macro_subst_tok(&tokstr_buf, &nested_list, s); | 3556 | macro_subst_tok(&tokstr_buf, &nested_list, s); |
| 3556 | tok_str_add(&tokstr_buf, 0); | 3557 | tok_str_add(&tokstr_buf, 0); |
| 3557 | begin_macro(&tokstr_buf, 2); | 3558 | begin_macro(&tokstr_buf, 0); |
| 3558 | goto redo; | 3559 | goto redo; |
| 3559 | } | 3560 | } |
| 3560 | } | 3561 | } |
| @@ -3593,6 +3594,7 @@ ST_FUNC void preprocess_start(TCCState *s1, int is_asm) · 32 unmodified lines | |||
| 3593 | pp_debug_tok = pp_debug_symv = 0; | 3594 | pp_debug_tok = pp_debug_symv = 0; |
| 3594 | pp_once++; | 3595 | pp_once++; |
| 3595 | pvtop = vtop = vstack - 1; | 3596 | pvtop = vtop = vstack - 1; |
| 3597 | memset(vtop, 0, sizeof *vtop); | ||
| 3596 | s1->pack_stack[0] = 0; | 3598 | s1->pack_stack[0] = 0; |
| 3597 | s1->pack_stack_ptr = s1->pack_stack; | 3599 | s1->pack_stack_ptr = s1->pack_stack; |
| 3598 | 3600 | ||
| @@ -3628,13 +3630,8 @@ ST_FUNC void preprocess_start(TCCState *s1, int is_asm) · 29 unmodified lines | |||
| 3628 | /* cleanup from error/setjmp */ | 3630 | /* cleanup from error/setjmp */ |
| 3629 | ST_FUNC void preprocess_end(TCCState *s1) | 3631 | ST_FUNC void preprocess_end(TCCState *s1) |
| 3630 | { | 3632 | { |
| 3631 | /* Normally macro_stack is NULL here, except if an | 3633 | while (macro_stack) |
| 3632 | error was thrown; then it can point to allocated storage | 3634 | end_macro(); |
| 3633 | or to some stack variables, but those are unwound via | ||
| 3634 | setjmp already, so can't be accessed. Only two choices: | ||
| 3635 | either we leak memory or we access invalid memory. The | ||
| 3636 | former is the better choice. */ | ||
| 3637 | macro_stack = NULL; | ||
| 3638 | macro_ptr = NULL; | 3635 | macro_ptr = NULL; |
| 3639 | } | 3636 | } |
| 3640 | 3637 | ||
| @@ -2466,6 +2466,11 @@ long long llfunc2(long long x, long long y, int z) · 2465 unmodified lines | |||
| 2466 | return x * y * z; | 2466 | return x * y * z; |
| 2467 | } | 2467 | } |
| 2468 | 2468 | ||
| 2469 | void check_opl_save_regs(char *a, long long b, int c) | ||
| 2470 | { | ||
| 2471 | *a = b < 0 && !c; | ||
| 2472 | } | ||
| 2473 | |||
| 2469 | void longlong_test(void) | 2474 | void longlong_test(void) |
| 2470 | { | 2475 | { |
| 2471 | long long a, b, c; | 2476 | long long a, b, c; |
| @@ -2538,6 +2543,11 @@ void longlong_test(void) · 66 unmodified lines | |||
| 2538 | unsigned long long u = 0x8000000000000001ULL; | 2543 | unsigned long long u = 0x8000000000000001ULL; |
| 2539 | u = (unsigned)(u + 1); | 2544 | u = (unsigned)(u + 1); |
| 2540 | printf("long long u=" ULONG_LONG_FORMAT "\n", u); | 2545 | printf("long long u=" ULONG_LONG_FORMAT "\n", u); |
| 2546 | |||
| 2547 | /* was a problem with missing save_regs in gen_opl on 32-bit platforms */ | ||
| 2548 | char cc = 78; | ||
| 2549 | check_opl_save_regs(&cc, -1, 0); | ||
| 2550 | printf("check_opl_save_regs: %d\n", cc); | ||
| 2541 | } | 2551 | } |
| 2542 | 2552 | ||
| 2543 | void manyarg_test(void) | 2553 | void manyarg_test(void) |
| @@ -76,18 +76,12 @@ · 75 unmodified lines | |||
| 76 | #define _M_AMD64 100 /* Visual Studio */ | 76 | #define _M_AMD64 100 /* Visual Studio */ |
| 77 | #define USE_MINGW_SETJMP_TWO_ARGS | 77 | #define USE_MINGW_SETJMP_TWO_ARGS |
| 78 | #define mingw_getsp tinyc_getbp | 78 | #define mingw_getsp tinyc_getbp |
| 79 | #define __TRY__ | ||
| 80 | #else | 79 | #else |
| 81 | #define __stdcall __attribute__((__stdcall__)) | 80 | #define __stdcall __attribute__((__stdcall__)) |
| 82 | #define _X86_ 1 | 81 | #define _X86_ 1 |
| 83 | #define _M_IX86 300 /* Visual Studio */ | 82 | #define _M_IX86 300 /* Visual Studio */ |
| 84 | #define WIN32 1 | 83 | #define WIN32 1 |
| 85 | #define _USE_32BIT_TIME_T | 84 | #define _USE_32BIT_TIME_T |
| 86 | #ifdef __arm__ | ||
| 87 | #define __TRY__ | ||
| 88 | #else | ||
| 89 | #define __TRY__ void __try__(void**), *_sehrec[6]; __try__(_sehrec); | ||
| 90 | #endif | ||
| 91 | #endif | 85 | #endif |
| 92 | 86 | ||
| 93 | /* in stddef.h */ | 87 | /* in stddef.h */ |
| @@ -1310,7 +1310,7 @@ typedef DWORD LCID; · 1309 unmodified lines | |||
| 1310 | #define INITIAL_MXCSR 0x1f80 | 1310 | #define INITIAL_MXCSR 0x1f80 |
| 1311 | #define INITIAL_FPCSR 0x027f | 1311 | #define INITIAL_FPCSR 0x027f |
| 1312 | 1312 | ||
| 1313 | typedef DECLSPEC_ALIGN(16) struct _M128A { | 1313 | typedef struct DECLSPEC_ALIGN(16) _M128A { |
| 1314 | ULONGLONG Low; | 1314 | ULONGLONG Low; |
| 1315 | LONGLONG High; | 1315 | LONGLONG High; |
| 1316 | } M128A,*PM128A; | 1316 | } M128A,*PM128A; |
| @@ -1336,7 +1336,7 @@ typedef DWORD LCID; · 19 unmodified lines | |||
| 1336 | 1336 | ||
| 1337 | #define LEGACY_SAVE_AREA_LENGTH sizeof(XMM_SAVE_AREA32) | 1337 | #define LEGACY_SAVE_AREA_LENGTH sizeof(XMM_SAVE_AREA32) |
| 1338 | 1338 | ||
| 1339 | typedef DECLSPEC_ALIGN(16) struct _CONTEXT { | 1339 | typedef struct DECLSPEC_ALIGN(16) _CONTEXT { |
| 1340 | DWORD64 P1Home; | 1340 | DWORD64 P1Home; |
| 1341 | DWORD64 P2Home; | 1341 | DWORD64 P2Home; |
| 1342 | DWORD64 P3Home; | 1342 | DWORD64 P3Home; |
| @@ -3150,7 +3150,7 @@ typedef DWORD LCID; · 1807 unmodified lines | |||
| 3150 | DWORD Type; | 3150 | DWORD Type; |
| 3151 | } MEMORY_BASIC_INFORMATION32,*PMEMORY_BASIC_INFORMATION32; | 3151 | } MEMORY_BASIC_INFORMATION32,*PMEMORY_BASIC_INFORMATION32; |
| 3152 | 3152 | ||
| 3153 | typedef DECLSPEC_ALIGN(16) struct _MEMORY_BASIC_INFORMATION64 { | 3153 | typedef struct DECLSPEC_ALIGN(16) _MEMORY_BASIC_INFORMATION64 { |
| 3154 | ULONGLONG BaseAddress; | 3154 | ULONGLONG BaseAddress; |
| 3155 | ULONGLONG AllocationBase; | 3155 | ULONGLONG AllocationBase; |
| 3156 | DWORD AllocationProtect; | 3156 | DWORD AllocationProtect; |
| @@ -4949,7 +4949,7 @@ typedef DWORD LCID; · 1792 unmodified lines | |||
| 4949 | 4949 | ||
| 4950 | #ifdef _WIN64 | 4950 | #ifdef _WIN64 |
| 4951 | typedef struct _SLIST_ENTRY *PSLIST_ENTRY; | 4951 | typedef struct _SLIST_ENTRY *PSLIST_ENTRY; |
| 4952 | typedef DECLSPEC_ALIGN(16) struct _SLIST_ENTRY { | 4952 | typedef struct DECLSPEC_ALIGN(16) _SLIST_ENTRY { |
| 4953 | PSLIST_ENTRY Next; | 4953 | PSLIST_ENTRY Next; |
| 4954 | } SLIST_ENTRY; | 4954 | } SLIST_ENTRY; |
| 4955 | #else | 4955 | #else |
| @@ -4961,7 +4961,7 @@ typedef DWORD LCID; · 5 unmodified lines | |||
| 4961 | 4961 | ||
| 4962 | #if defined(_WIN64) | 4962 | #if defined(_WIN64) |
| 4963 | 4963 | ||
| 4964 | typedef DECLSPEC_ALIGN(16) struct _SLIST_HEADER { | 4964 | typedef struct DECLSPEC_ALIGN(16) _SLIST_HEADER { |
| 4965 | ULONGLONG Alignment; | 4965 | ULONGLONG Alignment; |
| 4966 | ULONGLONG Region; | 4966 | ULONGLONG Region; |
| 4967 | } SLIST_HEADER; | 4967 | } SLIST_HEADER; |
| @@ -67,125 +67,3 @@ tinyc_getbp: · 66 unmodified lines | |||
| 67 | /* ---------------------------------------------- */ | 67 | /* ---------------------------------------------- */ |
| 68 | 68 | ||
| 69 | 69 | ||
| 70 | /* ---------------------------------------------- */ | ||
| 71 | #ifndef __x86_64__ | ||
| 72 | /* ---------------------------------------------- */ | ||
| 73 | |||
| 74 | /* | ||
| 75 | int _except_handler3( | ||
| 76 | PEXCEPTION_RECORD exception_record, | ||
| 77 | PEXCEPTION_REGISTRATION registration, | ||
| 78 | PCONTEXT context, | ||
| 79 | PEXCEPTION_REGISTRATION dispatcher | ||
| 80 | ); | ||
| 81 | |||
| 82 | int __cdecl _XcptFilter( | ||
| 83 | unsigned long xcptnum, | ||
| 84 | PEXCEPTION_POINTERS pxcptinfoptrs | ||
| 85 | ); | ||
| 86 | |||
| 87 | struct _sehrec { | ||
| 88 | void *esp; // 0 | ||
| 89 | void *exception_pointers; // 1 | ||
| 90 | void *prev; // 2 | ||
| 91 | void *handler; // 3 | ||
| 92 | void *scopetable; // 4 | ||
| 93 | int trylevel; // 5 | ||
| 94 | void *ebp // 6 | ||
| 95 | }; | ||
| 96 | |||
| 97 | // this is what the assembler code below means: | ||
| 98 | __try | ||
| 99 | { | ||
| 100 | // ... | ||
| 101 | } | ||
| 102 | __except (_XcptFilter(GetExceptionCode(), GetExceptionInformation())) | ||
| 103 | { | ||
| 104 | exit(GetExceptionCode()); | ||
| 105 | } | ||
| 106 | */ | ||
| 107 | |||
| 108 | .globl _exception_info | ||
| 109 | _exception_info: | ||
| 110 | mov 1*4-24(%ebp),%eax | ||
| 111 | ret | ||
| 112 | |||
| 113 | .globl _exception_code | ||
| 114 | _exception_code: | ||
| 115 | call _exception_info | ||
| 116 | mov (%eax),%eax | ||
| 117 | mov (%eax),%eax | ||
| 118 | ret | ||
| 119 | |||
| 120 | seh_filter: | ||
| 121 | call _exception_info | ||
| 122 | push %eax | ||
| 123 | call _exception_code | ||
| 124 | push %eax | ||
| 125 | call _XcptFilter | ||
| 126 | add $ 8,%esp | ||
| 127 | ret | ||
| 128 | |||
| 129 | seh_except: | ||
| 130 | mov 0*4-24(%ebp),%esp | ||
| 131 | call _exception_code | ||
| 132 | push %eax | ||
| 133 | call _exit | ||
| 134 | |||
| 135 | // msvcrt wants scopetables aligned and in read-only segment (using .text) | ||
| 136 | .align 4 | ||
| 137 | seh_scopetable: | ||
| 138 | .long -1 | ||
| 139 | .long seh_filter | ||
| 140 | .long seh_except | ||
| 141 | |||
| 142 | seh_handler: | ||
| 143 | jmp _except_handler3 | ||
| 144 | |||
| 145 | .globl ___try__ | ||
| 146 | ___try__: | ||
| 147 | .globl __try__ | ||
| 148 | __try__: | ||
| 149 | push %ebp | ||
| 150 | mov 8(%esp),%ebp | ||
| 151 | |||
| 152 | // void *esp; | ||
| 153 | lea 12(%esp),%eax | ||
| 154 | mov %eax,0*4(%ebp) | ||
| 155 | |||
| 156 | // void *exception_pointers; | ||
| 157 | xor %eax,%eax | ||
| 158 | mov %eax,1*4(%ebp) | ||
| 159 | |||
| 160 | // void *prev; | ||
| 161 | mov %fs:0,%eax | ||
| 162 | mov %eax,2*4(%ebp) | ||
| 163 | |||
| 164 | // void *handler; | ||
| 165 | mov $ seh_handler,%eax | ||
| 166 | mov %eax,3*4(%ebp) | ||
| 167 | |||
| 168 | // void *scopetable; | ||
| 169 | mov $ seh_scopetable,%eax | ||
| 170 | mov %eax,4*4(%ebp) | ||
| 171 | |||
| 172 | // int trylevel; | ||
| 173 | xor %eax,%eax | ||
| 174 | mov %eax,5*4(%ebp) | ||
| 175 | |||
| 176 | // register new SEH | ||
| 177 | lea 2*4(%ebp),%eax | ||
| 178 | mov %eax,%fs:0 | ||
| 179 | |||
| 180 | pop %ebp | ||
| 181 | ret | ||
| 182 | |||
| 183 | /* ---------------------------------------------- */ | ||
| 184 | #else | ||
| 185 | /* ---------------------------------------------- */ | ||
| 186 | |||
| 187 | /* SEH on x86-64 not implemented */ | ||
| 188 | |||
| 189 | /* ---------------------------------------------- */ | ||
| 190 | #endif | ||
| 191 | /* ---------------------------------------------- */ | ||
| @@ -38,21 +38,15 @@ extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]); · 37 unmodified lines | |||
| 38 | /* Allow command-line globbing with "int _dowildcard = 1;" in the user source */ | 38 | /* Allow command-line globbing with "int _dowildcard = 1;" in the user source */ |
| 39 | int _dowildcard; | 39 | int _dowildcard; |
| 40 | 40 | ||
| 41 | #ifdef __x86_64__ | ||
| 42 | static LONG WINAPI catch_sig(EXCEPTION_POINTERS *ex) | 41 | static LONG WINAPI catch_sig(EXCEPTION_POINTERS *ex) |
| 43 | { | 42 | { |
| 44 | return _XcptFilter(ex->ExceptionRecord->ExceptionCode, ex); | 43 | return _XcptFilter(ex->ExceptionRecord->ExceptionCode, ex); |
| 45 | } | 44 | } |
| 46 | #endif | ||
| 47 | 45 | ||
| 48 | void _tstart(void) | 46 | void _tstart(void) |
| 49 | { | 47 | { |
| 50 | __TRY__ | ||
| 51 | #ifdef __x86_64__ | ||
| 52 | SetUnhandledExceptionFilter(catch_sig); | ||
| 53 | #endif | ||
| 54 | _startupinfo start_info = {0}; | 48 | _startupinfo start_info = {0}; |
| 55 | 49 | SetUnhandledExceptionFilter(catch_sig); | |
| 56 | // Sets the current application type | 50 | // Sets the current application type |
| 57 | __set_app_type(_CONSOLE_APP); | 51 | __set_app_type(_CONSOLE_APP); |
| 58 | 52 | ||
| @@ -26,13 +26,6 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); · 25 unmodified lines | |||
| 26 | typedef struct { int newmode; } _startupinfo; | 26 | typedef struct { int newmode; } _startupinfo; |
| 27 | int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*); | 27 | int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*); |
| 28 | 28 | ||
| 29 | #ifdef __x86_64__ | ||
| 30 | static LONG WINAPI catch_sig(EXCEPTION_POINTERS *ex) | ||
| 31 | { | ||
| 32 | return _XcptFilter(ex->ExceptionRecord->ExceptionCode, ex); | ||
| 33 | } | ||
| 34 | #endif | ||
| 35 | |||
| 36 | static int go_winmain(TCHAR *arg1) | 29 | static int go_winmain(TCHAR *arg1) |
| 37 | { | 30 | { |
| 38 | STARTUPINFO si; | 31 | STARTUPINFO si; |
| @@ -58,13 +51,15 @@ static int go_winmain(TCHAR *arg1) · 19 unmodified lines | |||
| 58 | return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow); | 51 | return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow); |
| 59 | } | 52 | } |
| 60 | 53 | ||
| 54 | static LONG WINAPI catch_sig(EXCEPTION_POINTERS *ex) | ||
| 55 | { | ||
| 56 | return _XcptFilter(ex->ExceptionRecord->ExceptionCode, ex); | ||
| 57 | } | ||
| 58 | |||
| 61 | int _twinstart(void) | 59 | int _twinstart(void) |
| 62 | { | 60 | { |
| 63 | __TRY__ | ||
| 64 | #ifdef __x86_64__ | ||
| 65 | SetUnhandledExceptionFilter(catch_sig); | ||
| 66 | #endif | ||
| 67 | _startupinfo start_info_con = {0}; | 61 | _startupinfo start_info_con = {0}; |
| 62 | SetUnhandledExceptionFilter(catch_sig); | ||
| 68 | __set_app_type(__GUI_APP); | 63 | __set_app_type(__GUI_APP); |
| 69 | __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info_con); | 64 | __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info_con); |
| 70 | exit(go_winmain(__argc > 1 ? __targv[1] : NULL)); | 65 | exit(go_winmain(__argc > 1 ? __targv[1] : NULL)); |
| @@ -206,7 +206,7 @@ ST_FUNC void gsym_addr(int t, int a) · 205 unmodified lines | |||
| 206 | while (t) { | 206 | while (t) { |
| 207 | unsigned char *ptr = cur_text_section->data + t; | 207 | unsigned char *ptr = cur_text_section->data + t; |
| 208 | uint32_t n = read32le(ptr); /* next value */ | 208 | uint32_t n = read32le(ptr); /* next value */ |
| 209 | write32le(ptr, a - t - 4); | 209 | write32le(ptr, a < 0 ? -a : a - t - 4); |
| 210 | t = n; | 210 | t = n; |
| 211 | } | 211 | } |
| 212 | } | 212 | } |
| @@ -909,7 +909,7 @@ void gfunc_call(int nb_args) · 696 unmodified lines | |||
| 909 | 909 | ||
| 910 | if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) { | 910 | if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) { |
| 911 | /* need to add the "func_scratch" area after alloca */ | 911 | /* need to add the "func_scratch" area after alloca */ |
| 912 | o(0x0548), gen_le32(func_alloca), func_alloca = ind - 4; | 912 | o(0x48); func_alloca = oad(0x05, func_alloca); /* sub $NN, %rax */ |
| 913 | } | 913 | } |
| 914 | 914 | ||
| 915 | /* other compilers don't clear the upper bits when returning char/short */ | 915 | /* other compilers don't clear the upper bits when returning char/short */ |
| @@ -1037,11 +1037,7 @@ void gfunc_epilog(void) · 121 unmodified lines | |||
| 1037 | } | 1037 | } |
| 1038 | 1038 | ||
| 1039 | /* add the "func_scratch" area after each alloca seen */ | 1039 | /* add the "func_scratch" area after each alloca seen */ |
| 1040 | while (func_alloca) { | 1040 | gsym_addr(func_alloca, -func_scratch); |
| 1041 | unsigned char *ptr = cur_text_section->data + func_alloca; | ||
| 1042 | func_alloca = read32le(ptr); | ||
| 1043 | write32le(ptr, func_scratch); | ||
| 1044 | } | ||
| 1045 | 1041 | ||
| 1046 | cur_text_section->data_offset = saved_ind; | 1042 | cur_text_section->data_offset = saved_ind; |
| 1047 | pe_add_unwind_data(ind, saved_ind, v); | 1043 | pe_add_unwind_data(ind, saved_ind, v); |