From c8f509e8cdb55246e9e291df22527fbf74692d67 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Thu, 16 Nov 2017 07:48:49 +0100 Subject: [PATCH] lotsa debug printing --- arm-gen.c | 8 + i386-asm.c | 2 + i386-gen.c | 41 ++++ libtcc.c | 194 ++++++++++++++++- tcc.c | 31 +++ tccasm.c | 12 +- tccelf.c | 342 +++++++++++++++++++++++++++++- tccgen.c | 609 ++++++++++++++++++++++++++++++++++++++++++++++++++--- tccpp.c | 473 ++++++++++++++++++++++++++++++++++++++--- 9 files changed, 1642 insertions(+), 70 deletions(-) diff --git a/arm-gen.c b/arm-gen.c index 8384781..d827fb7 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -225,12 +225,20 @@ void o(uint32_t i) if (ind1 > cur_text_section->data_allocated) section_realloc(cur_text_section, ind1); cur_text_section->data[ind++] = i&255; + trace ("o "); eputs (itoa (i&255)); eputs ("\n"); + trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n"); i>>=8; cur_text_section->data[ind++] = i&255; + trace ("o "); eputs (itoa (i&255)); eputs ("\n"); + trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n"); i>>=8; cur_text_section->data[ind++] = i&255; + trace ("o "); eputs (itoa (i&255)); eputs ("\n"); + trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n"); i>>=8; cur_text_section->data[ind++] = i; + trace ("o "); eputs (itoa (i)); eputs ("\n"); + trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n"); } static uint32_t stuff_const(uint32_t op, uint32_t c) diff --git a/i386-asm.c b/i386-asm.c index a194beb..d00bf50 100644 --- a/i386-asm.c +++ b/i386-asm.c @@ -1593,6 +1593,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, ASMOperand *op; int i, reg; + trace_enter ("asm_gen_code"); /* Strictly speaking %Xbp and %Xsp should be included in the call-preserved registers, but currently it doesn't matter. */ #ifdef TCC_TARGET_X86_64 @@ -1686,6 +1687,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, } } } + trace_exit ("asm_gen_code"); } ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) diff --git a/i386-gen.c b/i386-gen.c index a2895cf..4866b21 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -99,6 +99,8 @@ static unsigned long func_bound_ind; /* XXX: make it faster ? */ ST_FUNC void g(int c) { + trace_enter ("g"); + trace ("gen o c="); eputs (itoa (c)); eputs ("\n"); int ind1; if (nocode_wanted) return; @@ -106,7 +108,9 @@ ST_FUNC void g(int c) if (ind1 > cur_text_section->data_allocated) section_realloc(cur_text_section, ind1); cur_text_section->data[ind] = c; + trace ("gen o data="); eputs (itoa (cur_text_section->data[ind])); eputs ("\n"); ind = ind1; + trace_exit ("g"); } ST_FUNC void o(unsigned int c) @@ -206,6 +210,7 @@ ST_FUNC void load(int r, SValue *sv) int v, t, ft, fc, fr; SValue v1; + trace_enter ("load"); #ifdef TCC_TARGET_PE SValue v2; sv = pe_getimport(sv, &v2); @@ -277,6 +282,7 @@ ST_FUNC void load(int r, SValue *sv) o(0xc0 + r + v * 8); /* mov v, r */ } } + trace_exit ("load"); } /* store register 'r' in lvalue 'v' */ @@ -284,6 +290,7 @@ ST_FUNC void store(int r, SValue *v) { int fr, bt, ft, fc; + trace_enter ("store"); #ifdef TCC_TARGET_PE SValue v2; v = pe_getimport(v, &v2); @@ -320,6 +327,7 @@ ST_FUNC void store(int r, SValue *v) } else if (fr != r) { o(0xc0 + fr + r * 8); /* mov r, fr */ } + trace_exit ("store"); } static void gadd_sp(int val) @@ -430,6 +438,7 @@ ST_FUNC void gfunc_call(int nb_args) int size, align, r, args_size, i, func_call; Sym *func_sym; + trace_enter ("gfunc_call"); args_size = 0; for(i = 0;i < nb_args; i++) { if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { @@ -509,6 +518,7 @@ ST_FUNC void gfunc_call(int nb_args) if (args_size && func_call != FUNC_STDCALL) gadd_sp(args_size); vtop--; + trace_exit ("gfunc_call"); } #ifdef TCC_TARGET_PE @@ -526,30 +536,40 @@ ST_FUNC void gfunc_prolog(CType *func_type) Sym *sym; CType *type; + trace_enter ("gfunc_prolog"); sym = func_type->ref; func_call = sym->a.func_call; addr = 8; loc = 0; func_vc = 0; + trace ("gfunc_prolog 10\n"); if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) { + trace ("gfunc_prolog 11\n"); fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1; fastcall_regs_ptr = fastcall_regs; } else if (func_call == FUNC_FASTCALLW) { + trace ("gfunc_prolog 15\n"); fastcall_nb_regs = 2; fastcall_regs_ptr = fastcallw_regs; } else { + trace ("gfunc_prolog 18\n"); fastcall_nb_regs = 0; fastcall_regs_ptr = NULL; } param_index = 0; + trace ("gfunc_prolog 20\n"); ind += FUNC_PROLOG_SIZE; + trace ("gfunc_prolog 21\n"); func_sub_sp_offset = ind; + trace ("gfunc_prolog 22\n"); /* if the function returns a structure, then add an implicit pointer parameter */ func_vt = sym->type; + trace ("gfunc_prolog 23\n"); func_var = (sym->c == FUNC_ELLIPSIS); + trace ("gfunc_prolog 24\n"); #ifdef TCC_TARGET_PE size = type_size(&func_vt,&align); if (((func_vt.t & VT_BTYPE) == VT_STRUCT) @@ -557,29 +577,35 @@ ST_FUNC void gfunc_prolog(CType *func_type) #else if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { #endif + trace ("gfunc_prolog 25\n"); /* XXX: fastcall case ? */ func_vc = addr; addr += 4; param_index++; } + trace ("gfunc_prolog 30\n"); /* define parameters */ while ((sym = sym->next) != NULL) { + trace ("gfunc_prolog 31 param_index="); eputs (itoa (param_index)); eputs ("\n"); 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) { + trace ("gfunc_prolog 36\n"); size = 4; } #endif if (param_index < fastcall_nb_regs) { + trace ("gfunc_prolog 38\n"); /* save FASTCALL register */ loc -= 4; o(0x89); /* movl */ gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc); param_addr = loc; } else { + trace ("gfunc_prolog 39\n"); param_addr = addr; addr += size; } @@ -588,6 +614,7 @@ ST_FUNC void gfunc_prolog(CType *func_type) param_index++; } func_ret_sub = 0; + trace ("gfunc_prolog 50\n"); /* pascal type call ? */ if (func_call == FUNC_STDCALL) func_ret_sub = addr - 8; @@ -596,15 +623,18 @@ ST_FUNC void gfunc_prolog(CType *func_type) func_ret_sub = 4; #endif + trace ("gfunc_prolog 60\n"); #ifdef CONFIG_TCC_BCHECK /* leave some room for bound checking code */ if (tcc_state->do_bounds_check) { + trace ("gfunc_prolog 61\n"); func_bound_offset = lbounds_section->data_offset; func_bound_ind = ind; oad(0xb8, 0); /* lbound section pointer */ oad(0xb8, 0); /* call to function */ } #endif + trace_exit ("gfunc_prolog"); } /* generate function epilog */ @@ -612,9 +642,11 @@ ST_FUNC void gfunc_epilog(void) { addr_t v, saved_ind; + trace ("gfunc_epilog\n"); #ifdef CONFIG_TCC_BCHECK if (tcc_state->do_bounds_check && func_bound_offset != lbounds_section->data_offset) { + trace ("gfunc_epilog 01\n"); addr_t saved_ind; addr_t *bounds_ptr; Sym *sym_data; @@ -643,18 +675,22 @@ ST_FUNC void gfunc_epilog(void) } #endif + trace ("gfunc_epilog 20\n"); /* align local size to word & save local variables */ v = (-loc + 3) & -4; #if USE_EBX + trace ("gfunc_epilog 21\n"); o(0x8b); gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4)); #endif o(0xc9); /* leave */ if (func_ret_sub == 0) { + trace ("gfunc_epilog 23\n"); o(0xc3); /* ret */ } else { + trace ("gfunc_epilog 24\n"); o(0xc2); /* ret n */ g(func_ret_sub); g(func_ret_sub >> 8); @@ -668,6 +704,7 @@ ST_FUNC void gfunc_epilog(void) } else #endif { + trace ("gfunc_epilog 30\n"); o(0xe58955); /* push %ebp, mov %esp, %ebp */ o(0xec81); /* sub esp, stacksize */ gen_le32(v); @@ -760,6 +797,8 @@ ST_FUNC void gen_opi(int op) { int r, fr, opc, c; + trace_enter ("gen_opi"); + trace ("gen_opi op="); eputs (itoa (op)); eputs ("\n"); switch(op) { case '+': case TOK_ADDC1: /* add with carry generation */ @@ -771,6 +810,7 @@ ST_FUNC void gen_opi(int op) r = gv(RC_INT); vswap(); c = vtop->c.i; + trace ("gen_opi 14 c ="); eputs (itoa (c)); eputs ("\n"); #if __MESC__ char ch = c; if (c == ch && ((ch >= 0 && ch < 128) || c < 0)) { @@ -789,6 +829,7 @@ ST_FUNC void gen_opi(int op) g(c); } } else { + trace ("gen_opi 20\n"); o(0x81); oad(0xc0 | (opc << 3) | r, c); } diff --git a/libtcc.c b/libtcc.c index aeabff9..7fcc83f 100644 --- a/libtcc.c +++ b/libtcc.c @@ -233,10 +233,14 @@ PUB_FUNC void *tcc_mallocz(unsigned long size) PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size) { + trace_enter ("tcc_realloc"); + trace ("tcc_realloc size="); eputs (itoa (size)); eputs ("\n"); + void *ptr1; ptr1 = realloc(ptr, size); if (!ptr1 && size) tcc_error("memory full (realloc)"); + trace_exit ("tcc_realloc"); return ptr1; } @@ -446,11 +450,17 @@ ST_FUNC void dynarray_reset(void *pp, int *n) static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in) { const char *p; + //eputs ("sp in="); //eputs (in); //eputs ("\n"); do { int c; CString str; + //eputs ("sp in="); //eputs (in); //eputs ("\n"); + //if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 01 file[0]="); //eputs (f->name); //eputs ("\n");} + cstr_new(&str); + //if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 02 file[0]="); //eputs (f->name); //eputs ("\n");} + for (p = in; c = *p, c != '\0' && c != PATHSEP; ++p) { if (c == '{' && p[1] && p[2] == '}') { c = p[1], p += 2; @@ -462,11 +472,15 @@ static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char * } if (str.size) { cstr_ccat(&str, '\0'); + //if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 14 file[0]="); //eputs (f->name); //eputs ("\n");} dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data)); } + //if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 15 file[0]="); //eputs (f->name); //eputs ("\n");} cstr_free(&str); + //if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 16 file[0]="); //eputs (f->name); //eputs ("\n");} in = p+1; } while (*p); + //eputs ("sp 99\n"); } /********************************************************/ @@ -583,51 +597,77 @@ PUB_FUNC void tcc_warning(const char *fmt, ...) ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen) { + trace_enter ("tcc_open_bf"); BufferedFile *bf; int buflen = initlen ? initlen : IO_BUF_SIZE; bf = tcc_mallocz(sizeof(BufferedFile) + buflen); + trace ("tcc_open_bf buflen="); eputs (itoa (buflen)); eputs ("\n"); + //eputs ("tcc_open_bf bf size="); //eputs (itoa (sizeof (BufferedFile) + buflen)); //eputs ("\n"); + + trace ("tcc_open_bf 10\n"); bf->buf_ptr = bf->buffer; + trace ("tcc_open_bf 11\n"); bf->buf_end = bf->buffer + initlen; + trace ("tcc_open_bf 12\n"); bf->buf_end[0] = CH_EOB; /* put eob symbol */ + trace ("tcc_open_bf 13\n"); pstrcpy(bf->filename, sizeof(bf->filename), filename); + trace ("tcc_open_bf 14\n"); pstrcpy(bf->filename2, sizeof(bf->filename2), filename); + trace ("tcc_open_bf 15\n"); #ifdef _WIN32 normalize_slashes(bf->filename); #endif + trace ("tcc_open_bf 20\n"); bf->line_num = 1; bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; bf->fd = -1; bf->prev = file; file = bf; + trace_exit ("tcc_open_bf"); } ST_FUNC void tcc_close(void) { + trace_enter ("tcc_close"); BufferedFile *bf = file; + //eputs ("tcc_close file:"); //eputs (itoa (file)); //eputs ("\n"); + //eputs ("tcc_close bf->fd:"); //eputs (itoa (bf->fd)); //eputs ("\n"); + //eputs ("tcc_close bf->prev:"); //eputs (itoa (bf->prev)); //eputs ("\n"); if (bf->fd > 0) { + //eputs ("tcc_close bf->filename:"); //eputs (bf->filename); //eputs ("\n"); close(bf->fd); total_lines += bf->line_num; } + trace ("tcc_close file->buf_ptr="); eputs (file->buf_ptr); eputs ("\n"); file = bf->prev; tcc_free(bf); + trace_exit ("tcc_close"); } ST_FUNC int tcc_open(TCCState *s1, const char *filename) { int fd; + trace_enter ("tcc_open"); + trace ("tcc_open file-name="); eputs (filename); eputs ("\n"); if (strcmp(filename, "-") == 0) fd = 0, filename = ""; else fd = open(filename, O_RDONLY | O_BINARY); + trace ("tcc_open fd="); eputs (itoa (fd)); eputs ("\n"); 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) + if (fd < 0) { + trace_exit ("tcc_open"); return -1; - + } + eputs ("tcc_open 10\n"); tcc_open_bf(s1, filename, 0); + eputs ("tcc_open 11\n"); file->fd = fd; + trace_exit ("tcc_open"); return fd; } @@ -636,30 +676,42 @@ static int tcc_compile(TCCState *s1) { Sym *define_start; + trace_enter ("tcc_compile"); define_start = define_stack; if (setjmp(s1->error_jmp_buf) == 0) { s1->nb_errors = 0; s1->error_set_jmp_enabled = 1; + trace ("tcc_compile 05 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n"); preprocess_start(s1); + trace ("tcc_compile 06 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n"); + tccgen_start(s1); + trace ("tcc_compile 07 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n"); #ifdef INC_DEBUG printf("%s: **** new file\n", file->filename); #endif ch = file->buf_ptr[0]; + trace ("tcc_compile 08 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n"); tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; + trace ("tcc_compile 10 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n"); next(); + trace ("tcc_compile 11 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n"); decl(VT_CONST); + trace ("tcc_compile 12 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n"); if (tok != TOK_EOF) expect("declaration"); /* free defines here already on behalf of of M.M.'s possibly existing experimental preprocessor implementation. The normal call below is still there to free after error-longjmp */ + trace ("tcc_compile 13 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n"); free_defines(define_start); + trace ("tcc_compile 14 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n"); tccgen_end(s1); + trace ("tcc_compile 15 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n"); } s1->error_set_jmp_enabled = 0; @@ -668,6 +720,7 @@ static int tcc_compile(TCCState *s1) free_defines(define_start); sym_pop(&global_stack, NULL, 0); sym_pop(&local_stack, NULL, 0); + trace_exit ("tcc_compile"); return s1->nb_errors != 0 ? -1 : 0; } @@ -686,25 +739,37 @@ LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str) /* 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) { + trace_enter ("tcc_define_symbol"); + trace ("tcc_define_symbol value="); eputs (itoa (value)); eputs ("\n"); + int len1, len2; /* default value */ if (!value) value = "1"; + trace ("tcc_define_symbol 01\n"); len1 = strlen(sym); + trace ("tcc_define_symbol 02\n"); len2 = strlen(value); + trace ("tcc_define_symbol 03\n"); /* init file structure */ tcc_open_bf(s1, "", len1 + len2 + 1); + trace ("tcc_define_symbol 04\n"); memcpy(file->buffer, sym, len1); file->buffer[len1] = ' '; memcpy(file->buffer + len1 + 1, value, len2); + trace ("tcc_define_symbol X="); //eputs (file->buffer); //eputs ("\n"); /* parse with define parser */ ch = file->buf_ptr[0]; + trace ("tcc_define_symbol 08\n"); next_nomacro(); + trace ("tcc_define_symbol 09\n"); parse_define(); + trace ("tcc_define_symbol 10\n"); tcc_close(); + trace_exit ("tcc_define_symbol"); } /* undefine a preprocessor symbol */ @@ -722,12 +787,15 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym) /* cleanup all static data used during compilation */ static void tcc_cleanup(void) { + if (NULL == tcc_state) return; tccpp_delete(tcc_state); + //eputs ("tcc_cleanup01\n"); tcc_state = NULL; /* free sym_pools */ dynarray_reset(&sym_pools, &nb_sym_pools); + //eputs ("tcc_cleanup02\n"); /* reset symbol stack */ sym_free_first = NULL; } @@ -736,14 +804,25 @@ LIBTCCAPI TCCState *tcc_new(void) { TCCState *s; + //eputs ("tcc_new\n"); tcc_cleanup(); + //eputs ("tcc_new01\n"); s = tcc_mallocz(sizeof(TCCState)); + //eputs ("size:"); //eputs (itoa (sizeof(TCCState))); //eputs ("\n"); + //eputs ("tcc_new02\n"); + //eputs ("s="); //eputs (itoa (s)); //eputs ("\n"); + if (!s) return NULL; tcc_state = s; + + trace ("tccnew include_stack="); eputs (itoa (&s->include_stack[0])); eputs ("\n"); + ++nb_states; + //eputs ("tcc_new03\n"); + s->alacarte_link = 1; s->nocommon = 1; s->warn_implicit_function_declaration = 1; @@ -898,6 +977,8 @@ LIBTCCAPI TCCState *tcc_new(void) /* 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 */ + //eputs ("tcc_new99\n"); + return s; } @@ -1005,10 +1086,34 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) return 0; } +#if !__x86_64__ +#undef eputs +#endif + +#if !BOOTSTRAP // MESC +#define for_each_elem(sec, startoff, elem, type) \ + for (elem = (type *) sec->data + startoff; \ + elem < (type *) (sec->data + sec->data_offset); elem++) +#else +#define for_each_elem(sec, startoff, elem, type) \ + elem = sec->data + sizeof (type) * startoff; \ + for (;elem < ((type *) (sec->data + sec->data_offset)); elem++) +#endif + ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) { int ret, filetype; + trace_enter ("tcc_add_file_internal"); + char *name; + ElfW(Sym) *esym; + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("tcc_add_file_internal num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("tcc_add_file_internal name="); eputs (name); eputs ("\n"); + } + + trace ("tcc_add_file_internal file-name="); eputs (filename); eputs ("\n"); filetype = flags & 0x0F; if (filetype == 0) { /* use a file extension to detect a filetype */ @@ -1029,7 +1134,16 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) } /* open the file */ + trace ("tcc_add_file_internal filename="); eputs (filename); eputs ("\n"); ret = tcc_open(s1, filename); + trace ("tcc_add_file_internal 20 ret="); eputs (itoa (ret));; eputs ("\n"); + + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("tcc_add_file_internal num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("tcc_add_file_internal name="); eputs (name); eputs ("\n"); + } + if (ret < 0) { if (flags & AFF_PRINT_ERROR) tcc_error_noabort("file '%s' not found", filename); @@ -1040,6 +1154,13 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) dynarray_add(&s1->target_deps, &s1->nb_target_deps, tcc_strdup(filename)); + trace ("tcc_add_file_internal 21\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("tcc_add_file_internal num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("tcc_add_file_internal name="); eputs (name); eputs ("\n"); + } + parse_flags = 0; /* if .S file, define __ASSEMBLER__ like gcc does */ if (filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP) { @@ -1047,18 +1168,35 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) parse_flags = PARSE_FLAG_ASM_FILE; } + trace ("tcc_add_file_internal 22\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("tcc_add_file_internal num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("tcc_add_file_internal name="); eputs (name); eputs ("\n"); + } + if (flags & AFF_PREPROCESS) { ret = tcc_preprocess(s1); + trace ("tcc_add_file_internal 31 ret="); eputs (itoa (ret));; eputs ("\n"); } else if (filetype == AFF_TYPE_C) { + //eputs ("tcc_add_file_internal: compile\n"); ret = tcc_compile(s1); + trace ("tcc_add_file_internal 32 ret="); eputs (itoa (ret));; eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("tcc_add_file_internal num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("tcc_add_file_internal name="); eputs (name); eputs ("\n"); + } #ifdef CONFIG_TCC_ASM } else if (filetype == AFF_TYPE_ASMPP) { /* non preprocessed assembler */ ret = tcc_assemble(s1, 1); + trace ("tcc_add_file_internal 33 ret="); eputs (itoa (ret));; eputs ("\n"); } else if (filetype == AFF_TYPE_ASM) { /* preprocessed assembler */ ret = tcc_assemble(s1, 0); #endif + trace ("tcc_add_file_internal 34 ret="); eputs (itoa (ret));; eputs ("\n"); } else { ElfW(Ehdr) ehdr; int fd, obj_type; @@ -1077,43 +1215,60 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) switch (obj_type) { case AFF_BINTYPE_REL: + { ret = tcc_load_object_file(s1, fd, 0); + trace ("tcc_add_file_internal 41 ret="); eputs (itoa (ret));; eputs ("\n"); 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 + trace ("tcc_add_file_internal 42 ret="); eputs (itoa (ret));; eputs ("\n"); } else { ret = tcc_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0); + trace ("tcc_add_file_internal 43 ret="); eputs (itoa (ret));; eputs ("\n"); } break; #endif + } case AFF_BINTYPE_AR: + { ret = tcc_load_archive(s1, fd); + trace ("tcc_add_file_internal 51 ret="); eputs (itoa (ret));; eputs ("\n"); break; + } #ifdef TCC_TARGET_COFF case AFF_BINTYPE_C67: ret = tcc_load_coff(s1, fd); + trace ("tcc_add_file_internal 52 ret="); eputs (itoa (ret));; eputs ("\n"); 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); + trace ("tcc_add_file_internal 61 ret="); eputs (itoa (ret));; eputs ("\n"); #endif if (ret < 0) tcc_error_noabort("unrecognized file type"); break; + } } } + + trace ("tcc_add_file_internal 90\n"); tcc_close(); + trace_exit ("tcc_add_file_internal"); return ret; } @@ -1127,7 +1282,11 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) { + trace ("tcc_add_library_path path="); eputs (pathname); eputs ("\n"); tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname); + for(int i = 0; i < s->nb_library_paths; i++) { + trace ("tcc_add_library_path dir="); eputs (s->library_paths[i]); eputs ("\n"); + } return 0; } @@ -1137,8 +1296,11 @@ static int tcc_add_library_internal(TCCState *s, const char *fmt, char buf[1024]; int i; + trace ("tcc_add_library_internal file-name="); eputs (filename); eputs ("\n"); + trace ("tcc_add_library_internal nb_paths="); eputs (itoa (nb_paths)); eputs ("\n"); for(i = 0; i < nb_paths; i++) { snprintf(buf, sizeof(buf), fmt, paths[i], filename); + trace ("tcc_add_library_internal buf="); eputs (buf); eputs ("\n"); if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0) return 0; } @@ -1155,6 +1317,7 @@ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) ST_FUNC int tcc_add_crt(TCCState *s, const char *filename) { + trace ("tcc_add_crt file name="); eputs (filename); eputs ("\n"); 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); @@ -1195,6 +1358,7 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname) { + trace ("tcc_add_library_err libname="); eputs (libname); eputs ("\n"); int ret = tcc_add_library(s, libname); if (ret < 0) tcc_error_noabort("library '%s' not found", libname); @@ -1216,6 +1380,7 @@ LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val) So it is handled here as if it were in a DLL. */ pe_putimport(s, 0, name, (uintptr_t)val); #else + trace ("tcc_add_symbol name="); eputs (name); eputs ("\n"); set_elf_sym(symtab_section, (uintptr_t)val, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, SHN_ABS, name); @@ -1280,10 +1445,13 @@ ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name) static int strstart(const char *val, const char **str) { + //eputs ("strstart val:"); //eputs (val); //eputs ("\n"); + //eputs ("strstart *str:"); //eputs (*str); //eputs ("\n"); const char *p, *q; p = *str; q = val; while (*q) { + //eputs ("*q:"); //eputc (*q); //eputs ("\n"); if (*p != *q) return 0; p++; @@ -1643,10 +1811,16 @@ static void parse_option_D(TCCState *s1, const char *optarg) static void args_parser_add_file(TCCState *s, const char* filename, int filetype) { struct filespec *f = tcc_malloc(sizeof (struct filespec) + strlen(filename)); + trace ("arg_parser_add file name="); eputs (filename); eputs ("\n"); f->type = filetype; f->alacarte = s->alacarte_link; strcpy(f->name, filename); + trace ("arg_parser_add file f->name="); //eputs (f->name); //eputs ("\n"); + trace ("arg_parser_add nb_files="); //eputs (itoa (s->nb_files)); //eputs ("\n"); dynarray_add(&s->files, &s->nb_files, f); + //struct filespec *= s->files[s->nb_files - 1]; + struct filespec * fs = s->files[0]; + //eputs ("arg_parser_add file fs->name="); //eputs (fs->name); //eputs ("\n"); } static int args_parser_make_argv(const char *r, int *argc, char ***argv) @@ -1691,6 +1865,7 @@ static void args_parser_listfile(TCCState *s, int argc = 0; char **argv = NULL; + trace ("arg_parser_listfile filename="); eputs (filename); eputs ("\n"); fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) tcc_error("listfile '%s' not found", filename); @@ -1712,6 +1887,8 @@ static void args_parser_listfile(TCCState *s, PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) { + trace ("tcc_parse_args\n"); + const TCCOption *popt; const char *optarg, *r; const char *run = NULL; @@ -1726,7 +1903,11 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) cstr_new(&linker_arg); while (optind < argc) { + trace ("tcc_parse_args 02 arg:"); eputs (itoa (optind)); eputs ("\n"); + r = argv[optind]; + trace ("tcc_parse_args 03 r:"); eputs (r); eputs ("\n"); + if (r[0] == '@' && r[1] != '\0') { args_parser_listfile(s, r + 1, optind, &argc, &argv); continue; @@ -1749,10 +1930,17 @@ reparse: continue; } + trace ("tcc_parse_args 20\n"); + + trace ("tcc_parse_args 20 opt0="); eputs (tcc_options[0].name); eputs ("\n"); + trace ("tcc_parse_args 20 opt1="); eputs (tcc_options[1].name); eputs ("\n"); /* find option in table */ for(popt = tcc_options; ; ++popt) { + trace ("tcc_parse_args 21\n"); + trace ("tcc_parse_args 22 popt:"); eputs (popt->name); eputs ("\n"); const char *p1 = popt->name; const char *r1 = r + 1; + trace ("tcc_parse_args 23 r1:"); eputs (r1); eputs ("\n"); if (p1 == NULL) tcc_error("invalid option -- '%s'", r); if (!strstart(p1, &r1)) @@ -1770,6 +1958,8 @@ reparse: break; } + trace ("pars_arg 2\n"); + switch(popt->index) { case TCC_OPTION_HELP: return OPT_HELP; diff --git a/tcc.c b/tcc.c index 9b778d6..7bffcef 100644 --- a/tcc.c +++ b/tcc.c @@ -255,9 +255,21 @@ int main(int argc, char **argv) vstack = &__vstack[1]; #endif + trace_enter ("main"); redo: + trace ("main 01\n"); s = tcc_new(); + trace ("main 02\n"); opt = tcc_parse_args(s, &argc, &argv, 1); + trace ("main 03\n"); + + + if (s->nb_files) { + struct filespec *f = s->files[0]; + trace ("main 05 file[0]="); eputs (f->name); eputs ("\n"); + } + + trace ("main 06\n"); if (n == 0) { if (opt == OPT_HELP) @@ -309,19 +321,28 @@ redo: start_time = getclock_ms(); } + trace ("main 20\n"); set_environment(s); + trace ("main 21\n"); + if (s->output_type == 0) s->output_type = TCC_OUTPUT_EXE; tcc_set_output_type(s, s->output_type); + trace ("main 23\n"); + /* compile or add each files or library */ for (first_file = NULL, ret = 0;;) { + trace ("main 24 nb-files="); eputs (itoa (s->nb_files)); eputs ("\n"); + trace ("main 24 n="); eputs (itoa (n)); eputs ("\n"); struct filespec *f = s->files[s->nb_files - n]; + trace ("for f->name="); eputs (f->name); eputs ("\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; + trace ("main 32 ret="); eputs (itoa (ret)); eputs ("\n"); } else { if (1 == s->verbose) printf("-> %s\n", f->name); @@ -329,7 +350,9 @@ redo: first_file = f->name; if (tcc_add_file(s, f->name) < 0) ret = 1; + trace ("main 33 ret="); eputs (itoa (ret)); eputs ("\n"); } + trace ("ret="); eputs (itoa (ret)); eputs ("\n"); s->filetype = 0; s->alacarte_link = 1; if (ret || --n == 0 @@ -337,17 +360,24 @@ redo: break; } + trace ("main 40\n"); + if (s->output_type == TCC_OUTPUT_PREPROCESS) { + trace ("main 41\n"); if (s->outfile) fclose(s->ppfp); } else if (0 == ret) { + trace ("main 42 ret == 0\n"); if (s->output_type == TCC_OUTPUT_MEMORY) { + trace ("main RUN\n"); #ifdef TCC_IS_NATIVE ret = tcc_run(s, argc, argv); #endif } else { + trace ("main 44 gonna output_file\n"); if (!s->outfile) s->outfile = default_outputfile(s, first_file); + trace ("main 45 output_file\n"); if (tcc_output_file(s, s->outfile)) ret = 1; else if (s->gen_deps) @@ -360,5 +390,6 @@ redo: tcc_delete(s); if (ret == 0 && n) goto redo; /* compile more files with -c */ + trace_exit ("main"); return ret; } diff --git a/tccasm.c b/tccasm.c index 1bdf865..f294851 100644 --- a/tccasm.c +++ b/tccasm.c @@ -1155,9 +1155,12 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr, next(); skip(']'); } - parse_mult_str(&astr, "string constant"); + parse_mult_str(&astr, "parse_asm_operands string constant"); + trace ("parse arm_operands tokc.str.data="); eputs (tokc.str.data); eputs ("\n"); op->constraint = tcc_malloc(astr.size); + trace ("parse arm_operands tokc.str.data="); eputs (tokc.str.data); eputs ("\n"); strcpy(op->constraint, astr.data); + trace ("parse arm_operands tokc.str.data="); eputs (tokc.str.data); eputs ("\n"); cstr_free(&astr); skip('('); gexpr(); @@ -1196,13 +1199,17 @@ ST_FUNC void asm_instr(void) int nb_outputs, nb_operands, i, must_subst, out_reg; uint8_t clobber_regs[NB_ASM_REGS]; + trace_enter ("asm_instr"); next(); + trace ("asm_instr 01\n"); /* since we always generate the asm() instruction, we can ignore volatile */ if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) { next(); } + trace ("asm_instr 02\n"); parse_asm_str(&astr); + trace ("asm_instr astr.data="); eputs (astr.data); eputs ("\n"); nb_operands = 0; nb_outputs = 0; must_subst = 0; @@ -1255,6 +1262,7 @@ ST_FUNC void asm_instr(void) #ifdef ASM_DEBUG printf("asm: \"%s\"\n", (char *)astr.data); #endif + trace ("asm_instr asm:"); eputs (astr.data); eputs ("\n"); if (must_subst) { subst_asm_operands(operands, nb_operands, &astr1, &astr); cstr_free(&astr); @@ -1264,6 +1272,7 @@ ST_FUNC void asm_instr(void) #ifdef ASM_DEBUG printf("subst_asm: \"%s\"\n", (char *)astr1.data); #endif + trace ("asm_instr subst:"); eputs (astr1.data); eputs ("\n"); /* generate loads */ asm_gen_code(operands, nb_operands, nb_outputs, 0, @@ -1287,6 +1296,7 @@ ST_FUNC void asm_instr(void) vpop(); } cstr_free(&astr1); + trace_exit ("asm_instr"); } ST_FUNC void asm_global_instr(void) diff --git a/tccelf.c b/tccelf.c index 471ea30..4a5c477 100644 --- a/tccelf.c +++ b/tccelf.c @@ -51,28 +51,42 @@ static int new_undef_sym = 0; /* Is there a new undefined sym since last new_und ST_FUNC void tccelf_new(TCCState *s) { + //eputs ("tccelf_new00\n"); /* no section zero */ + //eputs ("tccelf_new00 nb_sections="); //eputs (itoa (s->nb_sections)); //eputs ("\n"); dynarray_add(&s->sections, &s->nb_sections, NULL); + //eputs ("tccelf_new01\n"); /* create standard sections */ text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); + //eputs ("tccelf_new02\n"); data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); + //eputs ("tccelf_new3\n"); bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); + //eputs ("tccelf_new04\n"); common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE); + //eputs ("tccelf_new05\n"); common_section->sh_num = SHN_COMMON; + //eputs ("tccelf_new06\n"); + /* symbols are always generated for linking stage */ symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, ".strtab", ".hashtab", SHF_PRIVATE); + //eputs ("tccelf_new07\n"); strtab_section = symtab_section->link; + //eputs ("tccelf_new08\n"); s->symtab = symtab_section; + //eputs ("tccelf_new09\n"); /* private symbol table for dynamic symbols */ s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE, ".dynstrtab", ".dynhashtab", SHF_PRIVATE); + //eputs ("tccelf_new10\n"); get_sym_attr(s, 0, 1); + //eputs ("tccelf_new99\n"); } #ifdef CONFIG_TCC_BCHECK @@ -136,10 +150,16 @@ ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh { Section *sec; + trace_enter ("new_section"); sec = tcc_mallocz(sizeof(Section) + strlen(name)); + trace ("size:"); eputs (itoa (sizeof(Section) + strlen (name))); eputs ("\n"); + trace ("new_section 01\n"); + trace ("name="); eputs (name); eputs ("\n"); strcpy(sec->name, name); + trace ("new_section 02\n"); sec->sh_type = sh_type; sec->sh_flags = sh_flags; + trace ("new_section 05\n"); switch(sh_type) { case SHT_HASH: case SHT_REL: @@ -157,13 +177,29 @@ ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh break; } + trace ("new_section 10\n"); if (sh_flags & SHF_PRIVATE) { + trace ("new_section 11\n"); dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec); } else { + trace ("new_section 12\n"); sec->sh_num = s1->nb_sections; dynarray_add(&s1->sections, &s1->nb_sections, sec); } + for (int i = 1; i < s1->nb_sections; i++) { + trace ("new_section i= "); eputs (itoa (i)); eputs ("\n"); + Section *s; +#if !BOOTSTRAP + s = s1->sections[i]; +#else + Section **ps = s1->sections; + s = ps[i]; +#endif + trace ("new_section name="); eputs (s->name); eputs ("\n"); + } + + trace_exit ("new_section"); return sec; } @@ -175,16 +211,26 @@ ST_FUNC Section *new_symtab(TCCState *s1, Section *symtab, *strtab, *hash; int *ptr, nb_buckets; + //eputs ("new_symtab00\n"); symtab = new_section(s1, symtab_name, sh_type, sh_flags); + //eputs ("new_symtab01\n"); + //eputs ("s->hash="); //eputs (itoa (symtab->hash)); //eputs ("\n"); symtab->sh_entsize = sizeof(ElfW(Sym)); + //eputs ("new_symtab02\n"); strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags); + //eputs ("new_symtab03\n"); put_elf_str(strtab, ""); + //eputs ("new_symtab04\n"); symtab->link = strtab; + //eputs ("new_symtab05\n"); put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL); + //eputs ("new_symtab06\n"); nb_buckets = 1; + //eputs ("new_symtab10\n"); hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags); + //eputs ("new_symtab11\n"); hash->sh_entsize = sizeof(int); symtab->hash = hash; hash->link = symtab; @@ -219,13 +265,19 @@ ST_FUNC size_t section_add(Section *sec, addr_t size, int align) { size_t offset, offset1; + trace_enter ("section_add"); offset = (sec->data_offset + align - 1) & -align; + trace ("section_add 01 offset="); eputs (itoa (offset)); eputs ("\n"); offset1 = offset + size; - if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated) + if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated) { + trace ("section_add 05\n"); section_realloc(sec, offset1); + } sec->data_offset = offset1; + trace ("section_add 08 offset1="); eputs (itoa (offset1)); eputs ("\n"); if (align > sec->sh_addralign) sec->sh_addralign = align; + trace_exit ("section_add"); return offset; } @@ -233,7 +285,9 @@ ST_FUNC size_t section_add(Section *sec, addr_t size, int align) sec->data_offset. */ ST_FUNC void *section_ptr_add(Section *sec, addr_t size) { + trace_enter ("section_ptr_add"); size_t offset = section_add(sec, size, 1); + trace_exit ("section_ptr_add"); return sec->data + offset; } @@ -268,6 +322,7 @@ ST_FUNC int put_elf_str(Section *s, const char *sym) int offset, len; char *ptr; + trace ("put_elf_str\n"); len = strlen(sym) + 1; offset = s->data_offset; ptr = section_ptr_add(s, len); @@ -333,6 +388,10 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, ElfW(Sym) *sym; Section *hs; + trace_enter ("put_elf_sym"); + if (name) { + trace ("put_elf_sym 00 name="); eputs (name); eputs ("\n"); + } sym = section_ptr_add(s, sizeof(ElfW(Sym))); if (name) name_offset = put_elf_str(s->link, name); @@ -347,12 +406,16 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, sym->st_shndx = shndx; sym_index = sym - (ElfW(Sym) *)s->data; hs = s->hash; + trace ("put_elf_sym20 size="); eputs (itoa (sizeof (ElfW(Sym)))); eputs ("\n"); + trace ("put_elf_sym21 sym_index="); eputs (itoa (sym_index)); eputs ("\n"); if (hs) { int *ptr, *base; + trace ("put_elf_sym 21\n"); ptr = section_ptr_add(hs, sizeof(int)); base = (int *)hs->data; /* only add global or weak symbols */ if (ELFW(ST_BIND)(info) != STB_LOCAL) { + trace ("put_elf_sym 25\n"); /* add another hashing entry */ nbuckets = base[0]; h = elf_hash((unsigned char *) name) % nbuckets; @@ -365,10 +428,12 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, rebuild_hash(s, 2 * nbuckets); } } else { + trace ("put_elf_sym 40\n"); *ptr = 0; base[1]++; } } + trace_exit ("put_elf_sym"); return sym_index; } @@ -381,19 +446,37 @@ ST_FUNC int find_elf_sym(Section *s, const char *name) int nbuckets, sym_index, h; const char *name1; + trace_enter ("find_elf_sym"); + trace ("find_elf_sym name="); eputs (name); eputs ("\n"); hs = s->hash; - if (!hs) + trace ("find_elf_sym 01\n"); + if (!hs) { + trace_exit ("find_elf_sym"); return 0; + } nbuckets = ((int *)hs->data)[0]; + trace ("find_elf_sym 10 nbuckets="); eputs (itoa (nbuckets)); eputs ("\n"); h = elf_hash((unsigned char *) name) % nbuckets; + trace ("find_elf_sym 11 h="); eputs (itoa (h)); eputs ("\n"); sym_index = ((int *)hs->data)[2 + h]; + trace ("find_elf_sym 12 sym_index="); eputs (itoa (sym_index)); eputs ("\n"); while (sym_index != 0) { sym = &((ElfW(Sym) *)s->data)[sym_index]; name1 = (char *) s->link->data + sym->st_name; - if (!strcmp(name, name1)) + trace ("find_elf_sym 13 sym->st_name="); eputs (itoa (sym->st_name)); eputs ("\n"); + trace ("find_elf_sym 14 name1= "); eputs (itoa ((int)name1 - (int)s->link->data)); eputs ("\n"); + //trace ("find_elf_sym 15 name= "); eputs (itoa (name)); eputs ("\n"); + trace ("find_elf_sym 16 *name= "); eputs (itoa (*name)); eputs ("\n"); + trace ("find_elf_sym 17 *name1="); eputs (itoa (name1 && sym->st_name >=0 && sym->st_name < 1000 ? *name1 : 0)); eputs ("\n"); + //trace ("find_elf_sym 19 name= "); eputs (name); eputs ("\n"); + //trace ("find_elf_sym 18 name1= "); eputs (name1); eputs ("\n"); + if (!strcmp(name, name1)) { + trace_exit ("find_elf_sym 20"); return sym_index; + } sym_index = ((int *)hs->data)[2 + nbuckets + sym_index]; } + trace_exit ("find_elf_sym"); return 0; } @@ -427,31 +510,53 @@ ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name) } #endif +#if !BOOTSTRAP // MESC +#define for_each_elem(sec, startoff, elem, type) \ + for (elem = (type *) sec->data + startoff; \ + elem < (type *) (sec->data + sec->data_offset); elem++) +#else +#define for_each_elem(sec, startoff, elem, type) \ + elem = sec->data + sizeof (type) * startoff; \ + for (;elem < ((type *) (sec->data + sec->data_offset)); elem++) +#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) { + trace_enter ("set_elf_sym"); ElfW(Sym) *esym; + trace ("set_elf_sym 01 name="); eputs (name); eputs ("\n"); int sym_bind, sym_index, sym_type, esym_bind; unsigned char sym_vis, esym_vis, new_vis; sym_bind = ELFW(ST_BIND)(info); + trace ("set_elf_sym 02\n"); sym_type = ELFW(ST_TYPE)(info); + trace ("set_elf_sym 03\n"); sym_vis = ELFW(ST_VISIBILITY)(other); + trace ("set_elf_sym 05\n"); sym_index = find_elf_sym(s, name); esym = &((ElfW(Sym) *)s->data)[sym_index]; + trace ("set_elf_sym 10\n"); if (sym_index && esym->st_value == value && esym->st_size == size && esym->st_info == info && esym->st_other == other && esym->st_shndx == shndx) + { + trace_exit ("set_elf_sym 11"); return sym_index; + } + trace ("set_elf_sym 12\n"); if (sym_bind != STB_LOCAL) { + trace ("set_elf_sym 13\n"); /* we search global or weak symbols */ if (!sym_index) goto do_def; if (esym->st_shndx != SHN_UNDEF) { + trace ("set_elf_sym 16\n"); esym_bind = ELFW(ST_BIND)(esym->st_info); /* propagate the most constraining visibility */ /* STV_DEFAULT(0)st_info = ELFW(ST_INFO)(sym_bind, sym_type); esym->st_shndx = shndx; new_undef_sym = 1; @@ -506,10 +612,31 @@ ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, } } else { do_def: + trace ("set_elf_sym 50\n"); sym_index = put_elf_sym(s, value, size, ELFW(ST_INFO)(sym_bind, sym_type), other, shndx, name); } + + trace ("set_elf_sym 90 name="); eputs (name); eputs ("\n"); + ElfW(Sym) *sym; +#if 1 + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { + trace ("set_elf_sym num="); eputs (itoa (sym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + sym->st_name; + trace ("set_elf_sym name="); eputs (name); eputs ("\n"); + } +#else + for (sym = symtab_section->data; sym < (symtab_section->data + symtab_section->data_offset); sym++) { + trace ("set_elf_sym num="); eputs (itoa (sym->st_shndx)); eputs ("\n"); + name = strtab_section->data; + name += sym->st_name; + //name = ((char *) strtab_section->data) + sym->st_name; + trace ("set_elf_sym name="); eputs (name); eputs ("\n"); + } +#endif + + trace_exit ("set_elf_sym"); return sym_index; } @@ -669,26 +796,39 @@ static void sort_syms(TCCState *s1, Section *s) Section *sr; int type, sym_index; + trace_enter ("sort_syms\n"); 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)); + trace ("sort_syms 05\n"); /* first pass for local symbols */ p = (ElfW(Sym) *)s->data; q = new_syms; + trace ("sort_syms 10\n"); for(i = 0; i < nb_syms; i++) { + trace ("sort_syms 11 i="); eputs (itoa (i)); eputs ("\n"); + unsigned char val = p->st_info; + trace ("val="); eputs (itoa (val)); eputs ("\n"); + val >>= 4; + trace ("val="); eputs (itoa (val)); eputs ("\n"); if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) { + trace ("sort_syms 12\n"); old_to_new_syms[i] = q - new_syms; *q++ = *p; + trace ("sort_syms 13\n"); } p++; } + trace ("sort_syms 20\n"); /* 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; + trace ("sort_syms 25\n"); for(i = 0; i < nb_syms; i++) { + trace ("sort_syms 31 i="); eputs (itoa (i)); eputs ("\n"); if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) { old_to_new_syms[i] = q - new_syms; *q++ = *p; @@ -696,12 +836,15 @@ static void sort_syms(TCCState *s1, Section *s) p++; } + trace ("sort_syms40\n"); /* we copy the new symbols to the old */ memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym))); tcc_free(new_syms); + trace ("sort_syms43\n"); /* now we modify all the relocations */ for(i = 1; i < s1->nb_sections; i++) { + trace ("sort_syms 43 i="); eputs (itoa (i)); eputs ("\n"); sr = s1->sections[i]; if (sr->sh_type == SHT_RELX && sr->link == s) { for_each_elem(sr, 0, rel, ElfW_Rel) { @@ -714,6 +857,7 @@ static void sort_syms(TCCState *s1, Section *s) } tcc_free(old_to_new_syms); + trace_exit ("sort_syms\n"); } /* relocate common symbols in the .bss section */ @@ -721,6 +865,7 @@ ST_FUNC void relocate_common_syms(void) { ElfW(Sym) *sym; + trace_enter ("relocate_common_syms"); for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { if (sym->st_shndx == SHN_COMMON) { /* symbol alignment is in st_value for SHN_COMMONs */ @@ -729,6 +874,15 @@ ST_FUNC void relocate_common_syms(void) sym->st_shndx = bss_section->sh_num; } } + trace ("relocate_common_syms 10\n"); + + char *name; + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { + trace ("tcc_add_linker_symbols num="); eputs (itoa (sym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + sym->st_name; + trace ("tcc_add_linker_symbols name="); eputs (name); eputs ("\n"); + } + trace_exit ("relocate_common_syms"); } /* relocate symbol table, resolve undefined symbols if do_resolve is @@ -741,10 +895,13 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) for_each_elem(symtab, 1, sym, ElfW(Sym)) { sh_num = sym->st_shndx; + trace ("relocate_syms 01 num="); eputs (itoa (sh_num)); eputs ("\n"); if (sh_num == SHN_UNDEF) { name = (char *) strtab_section->data + sym->st_name; + trace ("relocate_syms 02 name="); eputs (name); eputs ("\n"); /* Use ld.so to resolve symbol for us (for tcc -run) */ if (do_resolve) { + trace ("relocate_syms 03\n"); #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE void *addr = dlsym(RTLD_DEFAULT, name); if (addr) { @@ -756,25 +913,36 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) } #endif /* if dynamic symbol exist, it will be used in relocate_section */ - } else if (s1->dynsym && find_elf_sym(s1->dynsym, name)) + } else if (s1->dynsym && find_elf_sym(s1->dynsym, name)) { + trace ("relocate_syms 04\n"); goto found; + } /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */ - if (!strcmp(name, "_fp_hw")) + trace ("relocate_syms 05\n"); + if (!strcmp(name, "_fp_hw")) { + trace ("relocate_syms 06\n"); goto found; + } /* only weak symbols are accepted to be undefined. Their value is zero */ sym_bind = ELFW(ST_BIND)(sym->st_info); + trace ("relocate_syms 08\n"); if (sym_bind == STB_WEAK) sym->st_value = 0; else tcc_error_noabort("undefined symbol '%s'", name); } else if (sh_num < SHN_LORESERVE) { + trace ("relocate_syms 20\n"); + name = (char *) strtab_section->data + sym->st_name; + trace ("relocate_syms 02 name="); eputs (name); eputs ("\n"); /* add section base */ sym->st_value += s1->sections[sym->st_shndx]->sh_addr; + trace ("relocate_syms 22\n"); } found: ; } + trace_exit ("relocate_syms"); } /* relocate a given section (CPU dependent) by applying the relocations @@ -1173,18 +1341,37 @@ ST_FUNC void tcc_add_linker_symbols(TCCState *s1) int i; Section *s; + trace_enter ("tcc_add_linker_symbols"); set_elf_sym(symtab_section, text_section->data_offset, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, text_section->sh_num, "_etext"); + + ElfW(Sym) *sym; + char *name; + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { + trace ("tcc_add_linker_symbols num="); eputs (itoa (sym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + sym->st_name; + trace ("tcc_add_linker_symbols name="); eputs (name); eputs ("\n"); + } set_elf_sym(symtab_section, data_section->data_offset, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, data_section->sh_num, "_edata"); + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { + trace ("tcc_add_linker_symbols num="); eputs (itoa (sym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + sym->st_name; + trace ("tcc_add_linker_symbols name="); eputs (name); eputs ("\n"); + } set_elf_sym(symtab_section, bss_section->data_offset, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, bss_section->sh_num, "_end"); + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { + trace ("tcc_add_linker_symbols num="); eputs (itoa (sym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + sym->st_name; + trace ("tcc_add_linker_symbols name="); eputs (name); eputs ("\n"); + } #ifndef TCC_TARGET_PE /* horrible new standard ldscript defines */ add_init_array_defines(s1, ".preinit_array"); @@ -1224,6 +1411,12 @@ ST_FUNC void tcc_add_linker_symbols(TCCState *s1) } next_sec: ; } + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { + trace ("set_elf_sym num="); eputs (itoa (sym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + sym->st_name; + trace ("set_elf_sym name="); eputs (name); eputs ("\n"); + } + trace_exit ("tcc_add_linker_symbols"); } static void tcc_output_binary(TCCState *s1, FILE *f, @@ -1280,6 +1473,7 @@ ST_FUNC void fill_got(TCCState *s1) ElfW_Rel *rel; int i; + trace_enter ("fill_got"); for(i = 1; i < s1->nb_sections; i++) { s = s1->sections[i]; if (s->sh_type != SHT_RELX) @@ -1299,6 +1493,7 @@ ST_FUNC void fill_got(TCCState *s1) } } } + trace_exit ("fill_got"); } /* See put_got_entry for a description. This is the second stage @@ -1307,6 +1502,7 @@ static void fill_local_got_entries(TCCState *s1) { ElfW_Rel *rel; for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) { + trace_enter ("fill_local_got_entries"); if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) { int sym_index = ELFW(R_SYM) (rel->r_info); ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; @@ -1323,6 +1519,7 @@ static void fill_local_got_entries(TCCState *s1) #endif } } + trace_exit ("fill_local_got_entries"); } /* Bind symbols of executable: resolve undefined symbols from exported symbols @@ -1468,30 +1665,43 @@ static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec) int i; Section *s; + trace_enter ("alloc_sec_names"); /* Allocate strings for section names */ for(i = 1; i < s1->nb_sections; i++) { + trace ("alloc_sec_names i="); eputs (itoa (i)); eputs ("\n"); s = s1->sections[i]; + trace ("alloc_sec_names 02\n"); + trace ("alloc_sec_names name="); eputs (s->name); eputs ("\n"); /* 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) + if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) { + trace ("alloc_sec_names 07\n"); prepare_dynamic_rel(s1, s); + } else if (s1->do_debug) s->sh_size = s->data_offset; + trace ("alloc_sec_names 09\n"); } else if (s1->do_debug || file_type == TCC_OUTPUT_OBJ || (s->sh_flags & SHF_ALLOC) || i == (s1->nb_sections - 1)) { + trace ("alloc_sec_names 10\n"); /* we output all sections if debug or object file */ s->sh_size = s->data_offset; + trace ("alloc_sec_names 11\n"); } - if (s->sh_size || (s->sh_flags & SHF_ALLOC)) + trace ("alloc_sec_names 12\n"); + if (s->sh_size || (s->sh_flags & SHF_ALLOC)) { + trace ("alloc_sec_names 13\n"); s->sh_name = put_elf_str(strsec, s->name); + } } strsec->sh_size = strsec->data_offset; + trace_exit ("alloc_sec_names"); } /* Info to be copied in dynamic section */ @@ -1520,6 +1730,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, ElfW(Phdr) *ph; Section *s; + trace_enter ("layout_sections"); file_type = s1->output_type; sh_order_index = 1; file_offset = 0; @@ -1529,8 +1740,11 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, if (s1->section_align) s_align = s1->section_align; + trace ("layout_sections 10\n"); if (phnum > 0) { + trace ("layout_sections 11\n"); if (s1->has_text_addr) { + trace ("layout_sections 12\n"); int a_offset, p_offset; addr = s1->text_addr; /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset % @@ -1541,6 +1755,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, a_offset += s_align; file_offset += (a_offset - p_offset); } else { + trace ("layout_sections 20\n"); if (file_type == TCC_OUTPUT_DLL) addr = 0; else @@ -1549,6 +1764,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, addr += (file_offset & (s_align - 1)); } + trace ("layout_sections 30\n"); 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 @@ -1563,6 +1779,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, #endif for(j = 0; j < 2; j++) { + trace ("layout_sections j="); eputs (itoa (j)); eputs ("\n"); ph->p_type = PT_LOAD; if (j == 0) ph->p_flags = PF_R | PF_X; @@ -1576,8 +1793,10 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, symbol tables, relocations, progbits, nobits */ /* XXX: do faster and simpler sorting */ for(k = 0; k < 5; k++) { + trace ("layout_sections k="); eputs (itoa (k)); eputs ("\n"); for(i = 1; i < s1->nb_sections; i++) { s = s1->sections[i]; + trace ("layout_sections i="); eputs (itoa (i)); eputs ("\n"); /* compute if section should be included */ if (j == 0) { if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != @@ -1670,8 +1889,10 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, } } + trace ("layout_sections 80\n"); /* all other sections come after */ for(i = 1; i < s1->nb_sections; i++) { + trace ("layout_sections 80 i="); eputs (itoa (i)); eputs ("\n"); s = s1->sections[i]; if (phnum > 0 && (s->sh_flags & SHF_ALLOC)) continue; @@ -1679,11 +1900,14 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, file_offset = (file_offset + s->sh_addralign - 1) & ~(s->sh_addralign - 1); + trace ("layout_sections file_offset="); eputs (itoa (file_offset)); eputs ("\n"); s->sh_offset = file_offset; if (s->sh_type != SHT_NOBITS) file_offset += s->sh_size; + } + trace_exit ("layout_sections"); return file_offset; } @@ -1780,14 +2004,20 @@ static int final_sections_reloc(TCCState *s1) int i; Section *s; + trace_enter ("final_sections_reloc"); relocate_syms(s1, s1->symtab, 0); + trace ("final_sections_reloc 01\n"); - if (s1->nb_errors != 0) + if (s1->nb_errors != 0) { + trace_exit ("final_sections_reloc"); return -1; + } + trace ("final_sections_reloc 02\n"); /* relocate sections */ /* XXX: ignore sections with allocated relocations ? */ for(i = 1; i < s1->nb_sections; i++) { + trace ("final_sections_reloc 21\n"); s = s1->sections[i]; #if defined(TCC_TARGET_I386) || defined(TCC_MUSL) if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr @@ -1800,15 +2030,19 @@ static int final_sections_reloc(TCCState *s1) relocate_section(s1, s); } + trace ("final_sections_reloc 80\n"); /* relocate relocation entries if the relocation tables are allocated in the executable */ for(i = 1; i < s1->nb_sections; i++) { + trace ("final_sections_reloc 81\n"); s = s1->sections[i]; if ((s->sh_flags & SHF_ALLOC) && s->sh_type == SHT_RELX) { relocate_rel(s1, s); } } + + trace_exit ("final_sections_reloc"); return 0; } @@ -1822,6 +2056,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, ElfW(Ehdr) ehdr; ElfW(Shdr) shdr, *sh; + trace_enter ("tcc_output_elf"); file_type = s1->output_type; shnum = s1->nb_sections; @@ -1833,6 +2068,8 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, ehdr.e_phoff = sizeof(ElfW(Ehdr)); } + trace ("tcc_output_elf 10\n"); + /* align to 4 */ file_offset = (file_offset + 3) & -4; @@ -1861,6 +2098,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM; #endif #endif + trace ("tcc_output_elf 20\n"); switch(file_type) { case TCC_OUTPUT_DLL: ehdr.e_type = ET_DYN; @@ -1883,6 +2121,15 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, ehdr.e_shnum = shnum; ehdr.e_shstrndx = shnum - 1; + trace ("tcc_output_elf 50\n"); + trace ("tcc_output_elf ehdr.size="); eputs (itoa (sizeof(ElfW(Ehdr)))); eputs ("\n"); + trace ("tcc_output_elf ehdr.e_machine="); eputs (itoa (ehdr.e_machine)); eputs ("\n"); + trace ("tcc_output_elf ehdr.e_version="); eputs (itoa (ehdr.e_version)); eputs ("\n"); + unsigned char *p = &ehdr; + for (int i = 0; i < sizeof(ElfW(Ehdr)); i++) { + if (i < 10) eputs (" "); + trace (itoa (i)); eputs (": "); eputs (itoa (p[i])); eputs ("\n"); + } fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f); fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f); offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); @@ -1890,6 +2137,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, sort_syms(s1, symtab_section); for(i = 1; i < s1->nb_sections; i++) { s = s1->sections[sec_order[i]]; + trace ("tcc_output_elf 50 name="); eputs (s->name); eputs ("\n"); if (s->sh_type != SHT_NOBITS) { while (offset < s->sh_offset) { fputc(0, f); @@ -1902,31 +2150,44 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, } } + trace ("tcc_output_elf 60\n"); /* output section headers */ while (offset < ehdr.e_shoff) { fputc(0, f); offset++; } + trace ("tcc_output_elf 70\n"); for(i = 0; i < s1->nb_sections; i++) { + trace ("tcc_output_elf 70 i="); eputs (itoa (i)); eputs ("\n"); sh = &shdr; memset(sh, 0, sizeof(ElfW(Shdr))); + trace ("tcc_output_elf 72\n"); s = s1->sections[i]; if (s) { + trace ("tcc_output_elf 80\n"); + trace ("tcc_output_elf 80 name="); eputs (s->name ? s->name : ""); eputs ("\n"); 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) + trace ("tcc_output_elf 85\n"); + if (s->link) { sh->sh_link = s->link->sh_num; + trace ("tcc_output_elf 86 sh_num="); eputs (itoa (s->link->sh_num)); eputs ("\n"); + } + trace ("tcc_output_elf 87\n"); sh->sh_addralign = s->sh_addralign; sh->sh_addr = s->sh_addr; sh->sh_offset = s->sh_offset; sh->sh_size = s->sh_size; } + trace ("tcc_output_elf 90\n"); fwrite(sh, 1, sizeof(ElfW(Shdr)), f); + trace ("tcc_output_elf 91\n"); } + trace_exit ("tcc_output_elf"); } /* Write an elf, coff or "binary" file */ @@ -1936,18 +2197,24 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, int fd, mode, file_type; FILE *f; + trace_enter ("tcc_write_elf_file"); file_type = s1->output_type; if (file_type == TCC_OUTPUT_OBJ) mode = 0666; else mode = 0777; unlink(filename); + trace ("tcc_write_elf_file 06\n"); fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); + trace ("tcc_write_elf_file 07\n"); if (fd < 0) { + trace ("tcc_write_elf_file fd < 0\n"); tcc_error_noabort("could not write '%s'", filename); return -1; } + trace ("tcc_write_elf_file 09\n"); f = fdopen(fd, "wb"); + trace ("tcc_write_elf_file 10\n"); if (s1->verbose) printf("<- %s\n", filename); @@ -1962,6 +2229,7 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, tcc_output_binary(s1, f, sec_order); fclose(f); + trace_exit ("tcc_write_elf_file"); return 0; } @@ -1973,6 +2241,7 @@ static void tidy_section_headers(TCCState *s1, int *sec_order) Section **snew, *s; ElfW(Sym) *sym; + trace_enter ("tidy_section_headers"); snew = tcc_malloc(s1->nb_sections * sizeof(struct Section*)); backmap = tcc_malloc(s1->nb_sections * sizeof(int)); for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) { @@ -2008,6 +2277,7 @@ static void tidy_section_headers(TCCState *s1, int *sec_order) s1->sections = snew; s1->nb_sections = nnew; tcc_free(backmap); + trace_exit ("tidy_section_headers"); } /* Output an elf, coff or binary file */ @@ -2020,6 +2290,7 @@ static int elf_output_file(TCCState *s1, const char *filename) ElfW(Sym) *sym; Section *strsec, *interp, *dynamic, *dynstr; + trace_enter ("elf_output_file"); file_type = s1->output_type; s1->nb_errors = 0; @@ -2033,12 +2304,43 @@ static int elf_output_file(TCCState *s1, const char *filename) interp = dynamic = dynstr = NULL; /* avoid warning */ if (file_type != TCC_OUTPUT_OBJ) { + trace ("elf_output_file 10\n"); + + char *name; + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { + trace ("elf_output_file num="); eputs (itoa (sym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + sym->st_name; + trace ("elf_output_file name="); eputs (name); eputs ("\n"); + } + for (sym = symtab_section->data; sym < (symtab_section->data + symtab_section->data_offset); sym++) { + trace ("XXX num="); eputs (itoa (sym->st_shndx)); eputs ("\n"); + name = strtab_section->data; + name += sym->st_name; + //name = ((char *) strtab_section->data) + sym->st_name; + trace ("XXX name="); eputs (name); eputs ("\n"); + } relocate_common_syms(); + trace ("elf_output_file 11\n"); + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { + trace ("elf_output_file num="); eputs (itoa (sym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + sym->st_name; + trace ("elf_output_file name="); eputs (name); eputs ("\n"); + } + tcc_add_linker_symbols(s1); + trace ("elf_output_file 12\n"); + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { + trace ("elf_output_file num="); eputs (itoa (sym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + sym->st_name; + trace ("elf_output_file name="); eputs (name); eputs ("\n"); + } + if (!s1->static_link) { + trace ("elf_output_file 13\n"); if (file_type == TCC_OUTPUT_EXE) { + trace ("elf_output_file 14\n"); char *ptr; /* allow override the dynamic loader */ const char *elfint = getenv("LD_SO"); @@ -2050,6 +2352,7 @@ static int elf_output_file(TCCState *s1, const char *filename) ptr = section_ptr_add(interp, 1 + strlen(elfint)); strcpy(ptr, elfint); } + trace ("elf_output_file 20\n"); /* add dynamic symbol table */ s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC, @@ -2065,7 +2368,9 @@ static int elf_output_file(TCCState *s1, const char *filename) build_got(s1); + trace ("elf_output_file 30\n"); if (file_type == TCC_OUTPUT_EXE) { + trace ("elf_output_file 31\n"); bind_exe_dynsyms(s1); if (s1->nb_errors) { @@ -2105,14 +2410,18 @@ static int elf_output_file(TCCState *s1, const char *filename) dyninf.dyn_rel_off = dynamic->data_offset; dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS; } else { + trace ("elf_output_file 49\n"); /* still need to build got entries in case of static link */ build_got_entries(s1); } } + trace ("elf_output_file 50\n"); /* we add a section for symbols */ strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); + trace ("elf_output_file 51\n"); put_elf_str(strsec, ""); + trace ("elf_output_file 52\n"); /* compute number of sections */ shnum = s1->nb_sections; @@ -2138,16 +2447,20 @@ static int elf_output_file(TCCState *s1, const char *filename) break; } + trace ("elf_output_file 60\n"); /* Allocate strings for section names */ alloc_sec_names(s1, file_type, strsec); + trace ("elf_output_file 61\n"); /* allocate program segment headers */ phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); + trace ("elf_output_file 62\n"); /* compute section to program header mapping */ file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf, sec_order); + trace ("elf_output_file 63\n"); /* Fill remaining program header and finalize relocation related to dynamic linking. */ if (phnum > 0) { @@ -2174,14 +2487,20 @@ static int elf_output_file(TCCState *s1, const char *filename) } } + trace ("elf_output_file 80\n"); + /* if building executable or DLL, then relocate each section except the GOT which is already relocated */ if (file_type != TCC_OUTPUT_OBJ) { + trace ("elf_output_file 81\n"); ret = final_sections_reloc(s1); + trace ("elf_output_file 82\n"); if (ret) goto the_end; #if !BOOTSTRAP + trace ("elf_output_file 83\n"); tidy_section_headers(s1, sec_order); + trace ("elf_output_file 84\n"); #endif } @@ -2193,12 +2512,17 @@ static int elf_output_file(TCCState *s1, const char *filename) fill_local_got_entries(s1); #endif + trace ("elf_output_file 90\n"); /* Create the ELF file with name 'filename' */ ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order); + trace ("elf_output_file 91\n"); s1->nb_sections = shnum; the_end: + trace ("elf_output_file 92\n"); tcc_free(sec_order); + trace ("elf_output_file 93\n"); tcc_free(phdr); + trace_exit ("elf_output_file"); return ret; } diff --git a/tccgen.c b/tccgen.c index 37d0e9e..3be46b5 100644 --- a/tccgen.c +++ b/tccgen.c @@ -291,7 +291,7 @@ static void update_storage(Sym *sym) t = sym->type.t; esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; -#if 0 // __MESC__ +#if !BOOTSTRAP if (t & VT_VIS_MASK) esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | ((t & VT_VIS_MASK) >> VT_VIS_SHIFT); @@ -325,6 +325,8 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, char buf[32]; #endif + trace_enter ("put_extern_sym2"); + trace ("put_extern_sym2 c="); eputs (itoa (sym->c)); eputs ("\n"); if (section == NULL) sh_num = SHN_UNDEF; else if (section == SECTION_ABS) @@ -332,8 +334,14 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, else sh_num = section->sh_num; + trace ("put_extern_sym2 10\n"); + trace ("put_extern_sym2 c="); eputs (itoa (sym->c)); eputs ("\n"); if (!sym->c) { + trace ("put_extern_sym2 11\n"); + trace ("put_extern_sym2 sym->v="); eputs (itoa (sym->v)); eputs ("\n"); name = get_tok_str(sym->v, NULL); + trace ("put_extern_sym2 12 name="); eputs (name); eputs ("\n"); + trace ("put_extern_sym2 c="); eputs (itoa (sym->c)); eputs ("\n"); #ifdef CONFIG_TCC_BCHECK if (tcc_state->do_bounds_check) { /* XXX: avoid doing that for statics ? */ @@ -362,17 +370,30 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, } #endif t = sym->type.t; + trace ("put_extern_sym2 14 t="); eputs (itoa (t)); eputs ("\n"); + trace ("put_extern_sym2 14 VT_STATIC="); eputs (itoa (VT_STATIC)); eputs ("\n"); + trace ("put_extern_sym2 14 t & VT_STATIC="); eputs (itoa (t & VT_STATIC)); eputs ("\n"); + trace ("put_extern_sym2 c="); eputs (itoa (sym->c)); eputs ("\n"); if ((t & VT_BTYPE) == VT_FUNC) { + trace ("put_extern_sym2 15\n"); sym_type = STT_FUNC; } else if ((t & VT_BTYPE) == VT_VOID) { + trace ("put_extern_sym2 17\n"); sym_type = STT_NOTYPE; } else { + trace ("put_extern_sym2 19\n"); sym_type = STT_OBJECT; } - if (t & VT_STATIC) + if (t & VT_STATIC) { + trace ("put_extern_sym2 21\n"); sym_bind = STB_LOCAL; - else + } + else { + trace ("put_extern_sym2 23\n"); sym_bind = STB_GLOBAL; + } + trace ("put_extern_sym2 25\n"); + trace ("put_extern_sym2 c="); eputs (itoa (sym->c)); eputs ("\n"); other = 0; #ifdef TCC_TARGET_PE if (sym_type == STT_FUNC && sym->type.ref) { @@ -388,27 +409,57 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, other |= ST_PE_IMPORT; #endif if (tcc_state->leading_underscore && can_add_underscore) { + trace ("put_extern_sym2 30\n"); buf1[0] = '_'; pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); name = buf1; } if (sym->asm_label) name = get_tok_str(sym->asm_label, NULL); + trace ("put_extern_sym2 31\n"); + trace ("put_extern_sym2 c="); eputs (itoa (sym->c)); eputs ("\n"); info = ELFW(ST_INFO)(sym_bind, sym_type); + trace ("put_extern_sym2 32\n"); + trace ("put_extern_sym2 c="); eputs (itoa (sym->c)); eputs ("\n"); sym->c = set_elf_sym(symtab_section, value, size, info, other, sh_num, name); + trace ("put_extern_sym2 33\n"); + trace ("put_extern_sym2 c="); eputs (itoa (sym->c)); eputs ("\n"); } else { + //eputs ("put_extern_sym2 80\n"); esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; esym->st_value = value; esym->st_size = size; esym->st_shndx = sh_num; } + trace ("put_extern_sym2 90\n"); + trace ("put_extern_sym2 c="); eputs (itoa (sym->c)); eputs ("\n"); update_storage(sym); + trace ("put_extern_sym2 c="); eputs (itoa (sym->c)); eputs ("\n"); + trace_exit ("put_extern_sym2"); } +#if !BOOTSTRAP // MESC +#define for_each_elem(sec, startoff, elem, type) \ + for (elem = (type *) sec->data + startoff; \ + elem < (type *) (sec->data + sec->data_offset); elem++) +#else +#define for_each_elem(sec, startoff, elem, type) \ + elem = sec->data + sizeof (type) * startoff; \ + for (;elem < ((type *) (sec->data + sec->data_offset)); elem++) +#endif + ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size) { put_extern_sym2(sym, section, value, size, 1); + + char *name; + ElfW(Sym) *esym; + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("put_extern_sym num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("put_extern_sym name="); eputs (name); eputs ("\n"); + } } /* add a new relocation entry to symbol 'sym' in section 's' */ @@ -488,10 +539,14 @@ ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c) { Sym *s; + //eputs ("sym_push2 00\n"); s = sym_malloc(); + //eputs ("sym_push2 01\n"); s->scope = 0; + //eputs ("sym_push2 02\n"); s->v = v; s->type.t = t; + //eputs ("sym_push2 04\n"); s->type.ref = NULL; #ifdef _WIN64 s->d = NULL; @@ -521,26 +576,46 @@ ST_FUNC Sym *sym_find2(Sym *s, int v) /* structure lookup */ ST_INLN Sym *struct_find(int v) { + trace_enter ("struct_find"); + trace ("struct_find v="); eputs (itoa (v)); eputs ("\n"); v -= TOK_IDENT; + trace ("struct_find tok_ident="); eputs (itoa (tok_ident)); eputs ("\n"); + trace ("struct_find TOK_IDENT="); eputs (itoa (TOK_IDENT)); eputs ("\n"); + trace ("struct_find tok_ident - TOK_IDENT="); eputs (itoa (tok_ident - TOK_IDENT)); eputs ("\n"); #if __MESC__ - if (v <= 0) + if (v <= 0) { #else - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) + if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) { #endif + trace ("sym_find NULL\n"); + trace_exit ("sym_find"); return NULL; + } + trace ("struct_find v="); eputs (itoa (v)); eputs ("\n"); + trace_exit ("struct_find"); return table_ident[v]->sym_struct; } /* find an identifier */ ST_INLN Sym *sym_find(int v) { + trace_enter ("sym_find"); + trace ("sym_find v="); eputs (itoa (v)); eputs ("\n"); v -= TOK_IDENT; + trace ("sym_find tok_ident="); eputs (itoa (tok_ident)); eputs ("\n"); + trace ("sym_find TOK_IDENT="); eputs (itoa (TOK_IDENT)); eputs ("\n"); + trace ("sym_find tok_ident - TOK_IDENT="); eputs (itoa (tok_ident - TOK_IDENT)); eputs ("\n"); #if __MESC__ - if (v <= 0) + if (v <= 0) { #else - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) + if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) { #endif + trace ("sym_find NULL\n"); + trace_exit ("sym_find"); return NULL; + } + trace ("sym_find v="); eputs (itoa (v)); eputs ("\n"); + trace_exit ("sym_find"); return table_ident[v]->sym_identifier; } @@ -630,6 +705,7 @@ static void vsetc(CType *type, int r, CValue *vc) { int v; + trace_enter ("vsetc"); if (vtop >= vstack + (VSTACK_SIZE - 1)) tcc_error("memory full (vstack)"); /* cannot let cpu flags if other instruction are generated. Also @@ -651,16 +727,27 @@ static void vsetc(CType *type, int r, CValue *vc) gv(RC_INT); } + trace ("vsetc r="); eputs (itoa (r)); eputs ("\n"); + trace ("vsetc vc->f="); eputs (itoa (vc->f)); eputs ("\n"); + trace ("vsetc vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("vsetc vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); + trace ("vsetc vtop->r2="); eputs (itoa (vtop->r2)); eputs ("\n"); + vtop++; vtop->type = *type; vtop->r = r; vtop->r2 = VT_CONST; vtop->c = *vc; vtop->sym = NULL; + trace ("vsetc vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("vsetc vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); + trace ("vsetc vtop->r2="); eputs (itoa (vtop->r2)); eputs ("\n"); + trace_exit ("vsetc"); } ST_FUNC void vswap(void) { + trace_enter ("vswap"); SValue tmp; /* cannot vswap cpu flags. See comment at vsetc() above */ if (vtop >= vstack && !nocode_wanted) { @@ -671,11 +758,13 @@ ST_FUNC void vswap(void) tmp = vtop[0]; vtop[0] = vtop[-1]; vtop[-1] = tmp; + trace_exit ("vswap"); } /* pop stack value */ ST_FUNC void vpop(void) { + trace_enter ("vpop"); int v; v = vtop->r & VT_VALMASK; #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) @@ -689,21 +778,29 @@ ST_FUNC void vpop(void) gsym(vtop->c.i); } vtop--; + trace_exit ("vpop"); } /* push constant of type "type" with useless value */ ST_FUNC void vpush(CType *type) { + trace_enter ("vpush"); + trace ("vpush type->t="); eputs (itoa (type->t)); eputs ("\n"); + CValue cval; vsetc(type, VT_CONST, &cval); + trace_exit ("vpush"); } /* push integer constant */ ST_FUNC void vpushi(int v) { + trace_enter ("vpushi"); + trace ("vpushi v="); eputs (itoa (v)); eputs ("\n"); CValue cval; cval.i = v; vsetc(&int_type, VT_CONST, &cval); + trace_exit ("vpushi"); } /* push a pointer sized constant */ @@ -733,26 +830,34 @@ static inline void vpushll(long long v) ST_FUNC void vset(CType *type, int r, long v) { + trace_enter ("vset"); + trace ("vset v="); eputs (itoa (v)); eputs ("\n"); CValue cval; cval.i = v; vsetc(type, r, &cval); + trace_exit ("vset"); } static void vseti(int r, int v) { + trace_enter ("vseti"); + trace ("vseti v="); eputs (itoa (v)); eputs ("\n"); CType type; type.t = VT_INT; type.ref = 0; vset(&type, r, v); + trace_exit ("vseti"); } ST_FUNC void vpushv(SValue *v) { + trace_enter ("vpushv"); if (vtop >= vstack + (VSTACK_SIZE - 1)) tcc_error("memory full (vstack)"); vtop++; *vtop = *v; + trace_exit ("vpushv"); } static void vdup(void) @@ -793,16 +898,21 @@ ST_FUNC void vrote(SValue *e, int n) */ ST_FUNC void vrott(int n) { + trace_enter ("vrott"); vrote(vtop, n); + trace_exit ("vrott"); } /* push a symbol value of TYPE */ static inline void vpushsym(CType *type, Sym *sym) { + trace_enter ("vpushsym"); + trace ("vpushsym type->t="); eputs (itoa (type->t)); eputs ("\n"); CValue cval; cval.i = 0; vsetc(type, VT_CONST | VT_SYM, &cval); vtop->sym = sym; + trace_exit ("vpushsym"); } /* Return a static symbol pointing to a section */ @@ -895,15 +1005,19 @@ ST_FUNC void vpush_global_sym(CType *type, int v) /* save registers up to (vtop - n) stack entry */ ST_FUNC void save_regs(int n) { + trace_enter ("save_regs"); SValue *p, *p1; for(p = vstack, p1 = vtop - n; p <= p1; p++) save_reg(p->r); + trace_exit ("save_regs"); } /* save r to the memory stack, and mark it as being free */ ST_FUNC void save_reg(int r) { + trace_enter ("save_reg"); save_reg_upstack(r, 0); + trace_exit ("save_reg"); } /* save r to the memory stack, and mark it as being free, @@ -914,6 +1028,7 @@ ST_FUNC void save_reg_upstack(int r, int n) SValue *p, *p1, sv; CType *type; + trace_enter ("save_reg_upstack"); if ((r &= VT_VALMASK) >= VT_CONST) return; if (nocode_wanted) @@ -973,6 +1088,7 @@ ST_FUNC void save_reg_upstack(int r, int n) p->c.i = l; } } + trace_exit ("save_reg_upstack"); } #ifdef TCC_TARGET_ARM @@ -1006,26 +1122,51 @@ ST_FUNC int get_reg(int rc) int r; SValue *p; + trace_enter ("get_reg"); + trace ("vstack->r="); eputs (itoa (vstack->r)); eputs ("\n"); + trace ("vstack vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); + trace ("vstack->r2="); eputs (itoa (vstack->r2)); eputs ("\n"); + trace ("vstack vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("vstack vtop->r2="); eputs (itoa (vtop->r2)); eputs ("\n"); /* find a free register */ for(r=0;rr="); eputs (itoa (p->r)); eputs ("\n"); + //trace ("vstack->r2="); eputs (itoa (p->r2)); eputs ("\n"); + trace ("vstack->r="); eputs (itoa (vstack->r)); eputs ("\n"); + trace ("vstack->r2="); eputs (itoa (vstack->r2)); eputs ("\n"); + trace ("vstack vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("vstack vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); + trace ("vstack vtop->r2="); eputs (itoa (vtop->r2)); eputs ("\n"); for(p=vstack;p<=vtop;p++) { + trace ("get_reg 04\n"); if ((p->r & VT_VALMASK) == r || - (p->r2 & VT_VALMASK) == r) + (p->r2 & VT_VALMASK) == r) { + trace ("get_reg 05\n"); goto notfound; + } } + trace_exit ("get_reg 97"); return r; } notfound: ; } + trace ("get_reg 20 r="); eputs (itoa (r)); eputs ("\n"); /* 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) */ + trace ("get_reg 21\n"); r = p->r2 & VT_VALMASK; if (r < VT_CONST && (reg_classes[r] & rc)) goto save_found; @@ -1033,10 +1174,12 @@ ST_FUNC int get_reg(int rc) if (r < VT_CONST && (reg_classes[r] & rc)) { save_found: save_reg(r); + trace_exit ("get_reg 98"); return r; } } /* Should never comes here */ + trace_exit ("get_reg 99"); return -1; } @@ -1059,12 +1202,18 @@ static void move_reg(int r, int s, int t) /* get address of vtop (vtop MUST BE an lvalue) */ ST_FUNC void gaddrof(void) { + trace_enter ("gaddrof"); + trace ("gaddrof vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gaddrof vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); + 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; - + trace ("gaddrof vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gaddrof vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); + trace_exit ("gaddrof"); } #ifdef CONFIG_TCC_BCHECK @@ -1103,8 +1252,15 @@ ST_FUNC int gv(int rc) int r, bit_pos, bit_size, size, align; int rc2; + trace_enter ("gv"); + trace ("gv vstack->r="); eputs (itoa (vstack->r)); eputs ("\n"); + trace ("gv vstack->r2="); eputs (itoa (vstack->r2)); eputs ("\n"); + trace ("gv vtop->r2="); eputs (itoa (vtop->r2)); eputs ("\n"); + trace ("gv vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gv vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); /* NOTE: get_reg can modify vstack[] */ if (vtop->type.t & VT_BITFIELD) { + trace ("gv 01\n"); CType type; int bits = 32; bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; @@ -1131,8 +1287,15 @@ ST_FUNC int gv(int rc) gen_op(TOK_SAR); r = gv(rc); } else { + trace ("gv 20\n"); + trace ("gv vstack->r="); eputs (itoa (vstack->r)); eputs ("\n"); + trace ("gv vstack->r2="); eputs (itoa (vstack->r2)); eputs ("\n"); + trace ("gv vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gv vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); + trace ("gv vtop->r2="); eputs (itoa (vtop->r2)); eputs ("\n"); if (is_float(vtop->type.t) && (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { + trace ("gv 21\n"); unsigned long offset; /* CPUs usually cannot use float constants, so we store them generically in data segment */ @@ -1142,6 +1305,8 @@ ST_FUNC int gv(int rc) vswap(); init_putv(&vtop->type, data_section, offset); vtop->r |= VT_LVAL; + trace ("gv 21 vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gv 21 vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); } #ifdef CONFIG_TCC_BCHECK if (vtop->r & VT_MUSTBOUND) @@ -1173,6 +1338,12 @@ ST_FUNC int gv(int rc) #endif ) { + trace ("gv 40\n"); + trace ("gv 40 vstack->r="); eputs (itoa (vstack->r)); eputs ("\n"); + trace ("gv 40 vstack->r2="); eputs (itoa (vstack->r2)); eputs ("\n"); + trace ("gv 40 vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gv 40 vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); + trace ("gv 40 vtop->r2="); eputs (itoa (vtop->r2)); eputs ("\n"); r = get_reg(rc); #if PTR_SIZE == 8 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) { @@ -1193,10 +1364,13 @@ ST_FUNC int gv(int rc) vtop->c.i = ll; /* first word */ load(r, vtop); vtop->r = r; /* save register value */ + trace ("gv 50 vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gv 50 vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); vpushi(ll >> 32); /* second word */ } else #endif if (vtop->r & VT_LVAL) { + trace ("gv 60\n"); /* We do not want to modifier the long long pointer here, so the safest (and less efficient) is to save all the other registers @@ -1219,12 +1393,17 @@ ST_FUNC int gv(int rc) gen_op('+'); vtop->r |= VT_LVAL; vtop->type.t = load_type; + trace ("gv 70 vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gv 70 vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); } else { + trace ("gv 80\n"); /* move registers */ load(r, vtop); vdup(); vtop[-1].r = r; /* save register value */ vtop->r = vtop[-1].r2; + trace ("gv 80 vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gv 80 vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); } /* Allocate second register. Here we rely on the fact that get_reg() tries first to free r2 of an SValue. */ @@ -1235,23 +1414,36 @@ ST_FUNC int gv(int rc) vtop->r2 = r2; vtop->type.t = original_type; } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) { + trace ("gv 90\n"); int t1, t; /* lvalue of scalar type : need to use lvalue type because of possible cast */ t = vtop->type.t; + trace ("gv 91 t="); eputs (itoa (t)); eputs ("\n"); + trace ("gv 91 vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gv 91 vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); t1 = t; /* compute memory access type */ - if (vtop->r & VT_LVAL_BYTE) + if (vtop->r & VT_LVAL_BYTE) { t = VT_BYTE; - else if (vtop->r & VT_LVAL_SHORT) + trace ("gv 93 t="); eputs (itoa (t)); eputs ("\n"); + } + else if (vtop->r & VT_LVAL_SHORT) { t = VT_SHORT; - if (vtop->r & VT_LVAL_UNSIGNED) + trace ("gv 94 t="); eputs (itoa (t)); eputs ("\n"); + } + if (vtop->r & VT_LVAL_UNSIGNED) { t |= VT_UNSIGNED; + trace ("gv 95 t="); eputs (itoa (t)); eputs ("\n"); + } + trace ("gv 96 t="); eputs (itoa (t)); eputs ("\n"); vtop->type.t = t; + trace ("gv 96 vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); load(r, vtop); /* restore wanted type */ vtop->type.t = t1; } else { + trace ("gv 100\n"); /* one register type load */ load(r, vtop); } @@ -1262,7 +1454,10 @@ ST_FUNC int gv(int rc) if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) vtop->r2 = r+1; #endif + trace ("gv 110 vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gv 110 vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); } + trace_exit ("gv"); return r; } @@ -1388,6 +1583,7 @@ static void lbuild(int t) register */ static void gv_dup(void) { + trace_enter ("gv_dup"); int rc, t, r, r1; SValue sv; @@ -1432,6 +1628,9 @@ static void gv_dup(void) if (r != r1) vtop->r = r1; } + trace ("gv_dup vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gv_dup vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); + trace_exit ("gv_dup"); } /* Generate value test @@ -1458,6 +1657,7 @@ ST_FUNC int gvtst(int inv, int t) /* generate CPU independent (unsigned) long long operations */ static void gen_opl(int op) { + trace_enter ("gen_opl"); int t, a, b, op1, c, i; int func; unsigned short reg_iret = REG_IRET; @@ -1680,6 +1880,7 @@ static void gen_opl(int op) vseti(VT_JMPI, a); break; } + trace_exit ("gen_opl"); } #endif @@ -1706,6 +1907,7 @@ static int gen_opic_lt(uint64_t a, uint64_t b) independent opt */ static void gen_opic(int op) { + trace_enter ("gen_opic"); SValue *v1 = vtop - 1; SValue *v2 = vtop; int t1 = v1->type.t & VT_BTYPE; @@ -1851,6 +2053,7 @@ static void gen_opic(int op) gen_opi(op); } } + trace_exit ("gen_opic"); } #if HAVE_FLOAT @@ -1994,9 +2197,11 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op) /* generic gen_op: handles types problems */ ST_FUNC void gen_op(int op) { + trace_enter ("gen_op"); int u, t1, t2, bt1, bt2, t; CType type1; + trace ("gen_op op="); eputc (op); eputs (" ["); eputs (itoa (op)); eputs ("]\n"); redo: t1 = vtop[-1].type.t; t2 = vtop[0].type.t; @@ -2065,6 +2270,7 @@ redo: /* XXX: truncate here because gen_opl can't handle ptr + long long */ gen_cast(&int_type); #endif + trace ("gen_op 70\n"); type1 = vtop[-1].type; type1.t &= ~VT_ARRAY; if (vtop[-1].type.t & VT_VLA) @@ -2172,18 +2378,21 @@ redo: vswap(); type1.t = t; gen_cast(&type1); + trace ("gen_op 180\n"); 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); + trace ("gen_op 190\n"); #if HAVE_FLOAT if (is_float(t)) gen_opif(op); else #endif gen_opic(op); + trace ("gen_op 200\n"); if (op >= TOK_ULT && op <= TOK_GT) { /* relational op: the result is an int */ vtop->type.t = VT_INT; @@ -2194,6 +2403,7 @@ redo: // 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); + trace_exit ("gen_op"); } #ifndef TCC_TARGET_ARM @@ -2287,6 +2497,7 @@ static void force_charshort_cast(int t) /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */ static void gen_cast(CType *type) { + trace_enter ("gen_cast"); int sbt, dbt, sf, df, c, p; /* special delayed cast for char/short */ @@ -2295,6 +2506,8 @@ static void gen_cast(CType *type) if (vtop->r & VT_MUSTCAST) { vtop->r &= ~VT_MUSTCAST; force_charshort_cast(vtop->type.t); + trace ("gen_cast vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gen_cast vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); } /* bitfields first get cast to ints */ @@ -2380,6 +2593,8 @@ static void gen_cast(CType *type) } else if (p && dbt == VT_BOOL) { vtop->r = VT_CONST; vtop->c.i = 1; + trace ("gen_cast vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("gen_cast vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); } else { /* non constant case: generate code */ if (sf && df) { @@ -2485,6 +2700,7 @@ static void gen_cast(CType *type) | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE); } vtop->type = *type; + trace_exit ("gen_cast"); } /* return type size as known at compile time. Put alignment at 'a' */ @@ -2587,10 +2803,16 @@ static inline CType *pointed_type(CType *type) /* modify type so that its it is a pointer to type. */ ST_FUNC void mk_pointer(CType *type) { + trace_enter ("mk_pointer"); + trace ("mk_pointer type->t="); eputs (itoa (type->t)); eputs ("\n"); + Sym *s; s = sym_push(SYM_FIELD, type, 0, -1); type->t = VT_PTR | (type->t & ~VT_TYPE); type->ref = s; + + trace ("mk_pointer type->t="); eputs (itoa (type->t)); eputs ("\n"); + trace_exit ("mk_pointer"); } /* compare function types. OLD functions match any new functions */ @@ -2920,6 +3142,12 @@ ST_FUNC void vstore(void) { int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast; + trace_enter ("vstore"); + trace ("vstore vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("vstore vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); + trace ("vstore vtop[-1]"); eputs (itoa (vtop[-1].r)); eputs ("\n"); + trace ("vstore vtop[-1].type.t="); eputs (itoa (vtop[-1].type.t)); eputs ("\n"); + ft = vtop[-1].type.t; sbt = vtop->type.t & VT_BTYPE; dbt = ft & VT_BTYPE; @@ -3077,6 +3305,8 @@ ST_FUNC void vstore(void) vpushi(load_size); gen_op('+'); vtop->r |= VT_LVAL; + trace ("vstore vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("vstore vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); vswap(); vtop[-1].type.t = load_type; /* XXX: it works because r2 is spilled last ! */ @@ -3089,6 +3319,7 @@ ST_FUNC void vstore(void) vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ vtop->r |= delayed_cast; } + trace_exit ("vstore"); } /* post defines POST/PRE add. c is the token ++ or -- */ @@ -3111,6 +3342,8 @@ ST_FUNC void inc(int post, int c) ST_FUNC void parse_mult_str (CString *astr, const char *msg) { + trace ("parse_mult_str 00 msg="); eputs (msg); eputs ("\n"); + trace ("parse_mult_str tok="); eputs (itoa (tok)); eputs (tok == TOK_STR ? " TOK_STR" : ""); eputs ("\n"); /* read the string */ if (tok != TOK_STR) expect(msg); @@ -3118,9 +3351,11 @@ ST_FUNC void parse_mult_str (CString *astr, const char *msg) while (tok == TOK_STR) { /* XXX: add \0 handling too ? */ cstr_cat(astr, tokc.str.data, -1); + trace ("parse_mult_str astr->data="); eputs (astr->data); eputs ("\n"); next(); } cstr_ccat(astr, '\0'); + trace ("parse_mult_str 99 astr->data="); eputs (astr->data); eputs ("\n"); } /* If I is >= 1 and a power of two, returns log2(i)+1. @@ -3541,6 +3776,7 @@ static void struct_layout(CType *type, AttributeDef *ad) /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ static void struct_decl(CType *type, AttributeDef *ad, int u) { + trace_enter ("struct_decl"); int a, v, size, align, flexible, alignoverride; long c; int bit_size, bsize, bt; @@ -3747,6 +3983,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) struct_layout(type, ad); } } + trace_exit ("struct_decl"); } /* return 1 if basic type is a type size (short, long, long long) */ @@ -3759,11 +3996,13 @@ ST_FUNC int is_btype_size(int bt) are added to the element type, copied because it could be a typedef. */ static void parse_btype_qualify(CType *type, int qualifiers) { + trace_enter ("parse_btype_qualify"); 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; + trace_exit ("parse_btype_qualify"); } /* return 0 if no type declaration. otherwise, return the basic type @@ -3771,16 +4010,20 @@ static void parse_btype_qualify(CType *type, int qualifiers) */ static int parse_btype(CType *type, AttributeDef *ad) { + trace_enter ("parse_btype"); int t, u, bt_size, complete, type_found, typespec_found, g; Sym *s; CType type1; + trace ("parse_btype\n"); memset(ad, 0, sizeof(AttributeDef)); complete = 0; type_found = 0; typespec_found = 0; t = 0; while(1) { + trace ("parse_btype 15 t="); eputs (itoa (t)); eputs ("\n"); + trace ("parse_btype 15 tok="); eputs (itoa (tok)); eputs ("\n"); switch(tok) { case TOK_EXTENSION: /* currently, we really ignore extension */ @@ -3943,19 +4186,28 @@ static int parse_btype(CType *type, AttributeDef *ad) type1.t &= ~(VT_STORAGE&~VT_TYPEDEF); goto basic_type2; default: + { + trace ("parse_btype 180 default\n"); + if (typespec_found) goto the_end; s = sym_find(tok); if (!s || !(s->type.t & VT_TYPEDEF)) goto the_end; + trace ("parse_btype 188 default\n"); type->t = ((s->type.t & ~VT_TYPEDEF) | (t & ~(VT_CONSTANT | VT_VOLATILE))); + trace ("parse_btype 190 default\n"); type->ref = s->type.ref; - if (t & (VT_CONSTANT | VT_VOLATILE)) + trace ("parse_btype 192 default\n"); + if (t & (VT_CONSTANT | VT_VOLATILE)) { + trace ("parse_btype 193 default\n"); parse_btype_qualify(type, t & (VT_CONSTANT | VT_VOLATILE)); + } t = type->t; + trace ("parse_btype 196 default\n"); if (s->r) { /* get attributes from typedef */ if (0 == ad->a.aligned) @@ -3964,13 +4216,17 @@ static int parse_btype(CType *type, AttributeDef *ad) ad->a.func_call = s->a.func_call; ad->a.packed |= s->a.packed; } + trace ("parse_btype 205 default\n"); next(); + trace ("parse_btype 207 default\n"); typespec_found = 1; break; + } } type_found = 1; } the_end: + trace ("parse_btype 211 the end\n"); if (tcc_state->char_is_unsigned) { if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE) t |= VT_UNSIGNED; @@ -3984,6 +4240,8 @@ the_end: t = (t & ~VT_BTYPE) | VT_INT; #endif type->t = t; + trace ("parse_btype 99 t="); eputs (itoa (t)); eputs ("\n"); + trace_exit ("parse_btype"); return type_found; } @@ -4004,7 +4262,7 @@ static inline void convert_parameter_type(CType *pt) ST_FUNC void parse_asm_str(CString *astr) { skip('('); - parse_mult_str(astr, "string constant"); + parse_mult_str(astr, "parse_asm_str string constant"); } /* Parse an asm label and return the token */ @@ -4019,6 +4277,7 @@ static int asm_label_instr(void) #ifdef ASM_DEBUG printf("asm_alias: \"%s\"\n", (char *)astr.data); #endif + trace ("asm_label_instr alias:"); eputs (astr.data); eputs ("\n"); TokenSym *tk = tok_alloc(astr.data, astr.size - 1); v = tk->tok; cstr_free(&astr); @@ -4027,22 +4286,29 @@ static int asm_label_instr(void) static int post_type(CType *type, AttributeDef *ad, int storage, int td) { + trace_enter ("post_type"); int n, l, t1, arg_size, align; Sym **plast, *s, *first; AttributeDef ad1; CType pt; + trace ("post_type\n"); if (tok == '(') { + trace ("post_type 01\n"); /* function type, or recursive declarator (return if so) */ next(); - if (td && !(td & TYPE_ABSTRACT)) + if (td && !(td & TYPE_ABSTRACT)) { + trace_exit ("post_type"); return 0; + } if (tok == ')') l = 0; else if (parse_btype(&pt, &ad1)) l = FUNC_NEW; - else if (td) + else if (td) { + trace_exit ("post_type"); return 0; + } else l = FUNC_OLD; first = NULL; @@ -4083,6 +4349,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) } else /* if no parameters, then old type prototype */ l = FUNC_OLD; + trace ("post_type 02\n"); skip(')'); /* NOTE: const is ignored in returned type as it has a special meaning in gcc / C++ */ @@ -4159,6 +4426,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR; type->ref = s; } + trace_exit ("post_type"); return 1; } @@ -4174,6 +4442,8 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) CType *post, *ret; int qualifiers, storage; + trace_enter ("type decl"); + /* recursive type, remove storage bits first, apply them later again */ storage = type->t & VT_STORAGE; type->t &= ~VT_STORAGE; @@ -4181,7 +4451,9 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) while (tok == '*') { qualifiers = 0; redo: + trace ("type decl 01 tok="); eputc (tok); eputs (" ["); eputs (itoa (tok)); eputs ("]\n"); next(); + trace ("type decl 02 tok="); eputc (tok); eputs (" ["); eputs (itoa (tok)); eputs ("]\n"); switch(tok) { case TOK_CONST1: case TOK_CONST2: @@ -4205,15 +4477,20 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) } mk_pointer(type); type->t |= qualifiers; - if (ret == type) - /* innermost pointed to type is the one for the first derivation */ + if (ret == type) { + trace ("type decl 20\n"); + /* innermost pointed to type is the one for the first derivation */ ret = pointed_type(type); + } } + trace ("type decl 30\n"); if (tok == '(') { + trace ("type decl 40\n"); /* This is possibly a parameter type list for abstract declarators ('int ()'), use post_type for testing this. */ if (!post_type(type, ad, 0, td)) { + trace ("type decl 50\n"); /* 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 @@ -4224,64 +4501,97 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) skip(')'); } } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { + trace ("type decl 60\n"); /* type identifier */ *v = tok; next(); } else { - if (!(td & TYPE_ABSTRACT)) + if (!(td & TYPE_ABSTRACT)) { + trace ("type decl 80\n"); expect("identifier"); + } *v = 0; } + trace ("type decl 90\n"); post_type(post, ad, storage, 0); - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) + if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { + trace ("type decl 92\n"); parse_attribute(ad); + } type->t |= storage; + trace_exit ("type_decl"); return ret; } /* compute the lvalue VT_LVAL_xxx needed to match type t. */ ST_FUNC int lvalue_type(int t) { + trace_enter ("lvalue_type"); + trace ("t="); eputs (itoa (t)); eputs ("\n"); int bt, r; r = VT_LVAL; + trace ("lvalue_type r="); eputs (itoa (r)); eputs ("\n"); bt = t & VT_BTYPE; - if (bt == VT_BYTE || bt == VT_BOOL) + trace ("lvalue_type bt="); eputs (itoa (bt)); eputs ("\n"); + if (bt == VT_BYTE || bt == VT_BOOL) { + trace ("lvalue_type BYTE\n"); r |= VT_LVAL_BYTE; - else if (bt == VT_SHORT) + trace ("lvalue_type r="); eputs (itoa (r)); eputs ("\n"); + } + else if (bt == VT_SHORT) { + trace ("lvalue_type SHORT\n"); r |= VT_LVAL_SHORT; - else + trace ("lvalue_type r="); eputs (itoa (r)); eputs ("\n"); + } + else { + trace ("lvalue_type OTHER\n"); + trace ("lvalue_type r="); eputs (itoa (r)); eputs ("\n"); + trace_exit ("lvalue_type"); return r; + } if (t & VT_UNSIGNED) r |= VT_LVAL_UNSIGNED; + trace ("lvalue_type r="); eputs (itoa (r)); eputs ("\n"); + trace_exit ("lvalue_type"); return r; } /* indirection with full error checking and bound check */ ST_FUNC void indir(void) { + trace_enter ("indir"); + trace ("indir 00 vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("indir 00 vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); if ((vtop->type.t & VT_BTYPE) != VT_PTR) { if ((vtop->type.t & VT_BTYPE) == VT_FUNC) return; expect("pointer"); } - if (vtop->r & VT_LVAL) + if (vtop->r & VT_LVAL) { + trace ("indir 10\n"); gv(RC_INT); + } #if BOOTSTRAP CType *pt = pointed_type(&vtop->type); vtop->type = *pt; #else vtop->type = *pointed_type(&vtop->type); #endif + trace ("indir 20 vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("indir 20 vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); /* 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); + trace ("indir 30 vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("indir 30 vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); /* if bound checking, the referenced pointer must be checked */ #ifdef CONFIG_TCC_BCHECK if (tcc_state->do_bounds_check) vtop->r |= VT_MUSTBOUND; #endif } + trace_exit ("indir"); } /* pass a parameter to a function and do type checking and casting */ @@ -4375,6 +4685,9 @@ static void parse_builtin_params(int nc, const char *args) ST_FUNC void unary(void) { + trace_enter ("unary"); + trace ("unary tok="); eputc (tok); eputs ("\n"); + int n, t, align, size, r, sizeof_caller; CType type; Sym *s; @@ -4392,13 +4705,16 @@ ST_FUNC void unary(void) case TOK_CINT: case TOK_CCHAR: case TOK_LCHAR: + { t = VT_INT; push_tokc: type.t = t; + trace ("unary: push_tokc t="); eputs (itoa (t)); eputs ("\n"); type.ref = 0; vsetc(&type, VT_CONST, &tokc); next(); break; + } case TOK_CUINT: t = VT_INT | VT_UNSIGNED; goto push_tokc; @@ -4504,11 +4820,16 @@ ST_FUNC void unary(void) } break; case '*': + { + trace ("unary: *\n"); next(); unary(); indir(); break; + } case '&': + { + trace ("unary: &\n"); next(); unary(); /* functions names must be treated as function pointers, @@ -4522,6 +4843,7 @@ ST_FUNC void unary(void) mk_pointer(&vtop->type); gaddrof(); break; + } case '!': next(); unary(); @@ -4791,6 +5113,8 @@ ST_FUNC void unary(void) default: tok_identifier: + { + trace ("unary: identifier\n"); t = tok; next(); if (t < TOK_UIDENT) @@ -4812,6 +5136,8 @@ ST_FUNC void unary(void) tcc_warning("implicit declaration of function '%s'", name); s = external_global_sym(t, &func_old_type, 0); } + trace ("unary: s->r="); eputs (itoa (s->r)); eputs ("\n");; + trace ("unary: s->type.t="); eputs (itoa (s->type.t)); eputs ("\n"); r = s->r; /* A symbol that has a register is a local register variable, @@ -4828,6 +5154,7 @@ ST_FUNC void unary(void) vtop->c.i = 0; } break; + } } /* post operations */ @@ -4864,6 +5191,8 @@ ST_FUNC void unary(void) /* an array is never an lvalue */ if (!(vtop->type.t & VT_ARRAY)) { vtop->r |= lvalue_type(vtop->type.t); + trace ("unary vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("unary vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); #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) @@ -4900,6 +5229,8 @@ ST_FUNC void unary(void) } } else { vtop->r &= ~VT_LVAL; /* no lvalue */ + trace ("unary vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("unary vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); } /* get return type */ s = vtop->type.ref; @@ -5009,6 +5340,7 @@ ST_FUNC void unary(void) break; } } + trace_exit ("unary"); } ST_FUNC void expr_prod(void) @@ -5052,6 +5384,7 @@ static void expr_shift(void) static void expr_cmp(void) { + trace_enter ("expr_cmp"); int t; expr_shift(); @@ -5062,6 +5395,7 @@ static void expr_cmp(void) expr_shift(); gen_op(t); } + trace_exit ("expr_cmp"); } static void expr_cmpeq(void) @@ -5214,6 +5548,7 @@ static int condition_3way(void) static void expr_cond(void) { + trace_enter ("expr_cond"); int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g; SValue sv; CType type, type1, type2; @@ -5373,16 +5708,20 @@ static void expr_cond(void) r1 = gv(rc); move_reg(r2, r1, type.t); vtop->r = r2; + trace ("expr_cond vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("expr_cond vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); gsym(tt); if (islv) indir(); } } } + trace_exit ("expr_cond"); } static void expr_eq(void) { + trace_enter ("expr_eq"); int t; expr_cond(); @@ -5402,6 +5741,7 @@ static void expr_eq(void) } vstore(); } + trace_exit ("expr_eq"); } ST_FUNC void gexpr(void) @@ -5544,6 +5884,7 @@ static int case_cmp(const void *ppa, const void *ppb) static void gcase(struct case_t **base, int len, int *bsym) { + trace_enter ("gcase"); struct case_t *p; int e; int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG; @@ -5600,6 +5941,7 @@ static void gcase(struct case_t **base, int len, int *bsym) gsym(e); } } + trace_exit ("gcase"); } static void block(int *bsym, int *csym, int is_expr) @@ -5607,17 +5949,20 @@ static void block(int *bsym, int *csym, int is_expr) int a, b, c, d, cond; Sym *s; + trace_enter ("block"); /* generate line number info */ if (tcc_state->do_debug) tcc_debug_line(tcc_state); if (is_expr) { + trace ("block 10 is_expr\n"); /* default return value is (void) */ vpushi(0); vtop->type.t = VT_VOID; } if (tok == TOK_IF) { + trace_enter ("block IF"); /* if test */ int saved_nocode_wanted = nocode_wanted; next(); @@ -5647,6 +5992,7 @@ static void block(int *bsym, int *csym, int is_expr) nocode_wanted = saved_nocode_wanted; } else gsym(a); + trace_exit ("block IF"); } else if (tok == TOK_WHILE) { int saved_nocode_wanted; nocode_wanted &= ~0x20000000; @@ -5957,6 +6303,7 @@ static void block(int *bsym, int *csym, int is_expr) skip(';'); } } + trace_exit ("block"); } /* This skips over a stream of tokens containing balanced {} and () @@ -6533,6 +6880,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope) { + trace_enter ("decl_initializer_alloc"); int size, align, addr; ParseState saved_parse_state = {0}; TokenString *init_str = NULL; @@ -6705,6 +7053,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, sym = get_sym_ref(type, sec, addr, size); vpushsym(type, sym); vtop->r |= r; + trace ("decl_initializer_alloc vtop->r="); eputs (itoa (vtop->r)); eputs ("\n"); + trace ("decl_initializer_alloc vtop->type.t="); eputs (itoa (vtop->type.t)); eputs ("\n"); } #ifdef CONFIG_TCC_BCHECK @@ -6757,43 +7107,159 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, end_macro(); restore_parse_state(&saved_parse_state); } + trace_exit ("decl_initializer_alloc"); } /* parse a function defined by symbol 'sym' and generate its code in 'cur_text_section' */ static void gen_function(Sym *sym) { + trace_enter ("gen_function"); + + ElfW(Sym) *esym; + char *name; + trace ("gen_function c="); eputs (itoa (sym->c)); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } + + trace ("gen_function c="); eputs (itoa (sym->c)); eputs ("\n"); nocode_wanted = 0; + trace ("gen_function 01\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); ind = cur_text_section->data_offset; + trace ("gen_function 02\n"); + trace ("gen_function c="); eputs (itoa (sym->c)); eputs ("\n"); /* NOTE: we patch the symbol size later */ put_extern_sym(sym, cur_text_section, ind, 0); + trace ("gen_function 03\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + trace ("gen_function c="); eputs (itoa (sym->c)); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } funcname = get_tok_str(sym->v, NULL); + trace ("gen_function 04 funcname="); eputs (funcname); eputs ("\n"); + trace ("gen_function c="); eputs (itoa (sym->c)); eputs ("\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } func_ind = ind; /* Initialize VLA state */ vla_sp_loc = -1; vla_sp_root_loc = -1; /* put debug symbol */ + trace ("gen_function 09\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } tcc_debug_funcstart(tcc_state, sym); + trace ("gen_function 10\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } /* push a dummy symbol to enable local sym storage */ sym_push2(&local_stack, SYM_FIELD, 0, 0); + trace ("gen_function 11\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + trace ("gen_function c="); eputs (itoa (sym->c)); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } local_scope = 1; /* for function parameters */ gfunc_prolog(&sym->type); + trace ("gen_function 13\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } local_scope = 0; rsym = 0; block(NULL, NULL, 0); + trace ("gen_function 16\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } nocode_wanted = 0; gsym(rsym); + trace ("gen_function 18\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + trace ("gen_function c="); eputs (itoa (sym->c)); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } gfunc_epilog(); + trace ("gen_function 19\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } cur_text_section->data_offset = ind; label_pop(&global_label_stack, NULL); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + trace ("gen_function 21\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } /* reset local stack */ local_scope = 0; sym_pop(&local_stack, NULL, 0); + trace ("gen_function 23\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } + trace ("gen_function sym->c="); eputs (itoa (sym->c)); eputs ("\n"); + /* end of function */ /* patch symbol size */ ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = ind - func_ind; + trace ("gen_function c="); eputs (itoa (sym->c)); eputs ("\n"); + trace ("gen_function 25\n"); + + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } tcc_debug_funcend(tcc_state, ind - func_ind); + trace ("gen_function 30\n"); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } /* It's better to crash than to generate wrong code */ cur_text_section = NULL; funcname = ""; /* for safety */ @@ -6801,7 +7267,21 @@ static void gen_function(Sym *sym) func_var = 0; /* for safety */ ind = 0; /* for safety */ nocode_wanted = 1; + trace ("gen_function 33\n"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } check_vstack(); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + trace_exit ("gen_function"); + for_each_elem(symtab_section, 1, esym, ElfW(Sym)) { + trace ("gen_function num="); eputs (itoa (esym->st_shndx)); eputs ("\n"); + name = (char *) strtab_section->data + esym->st_name; + trace ("gen_function name="); eputs (name); eputs ("\n"); + } + trace_exit ("gen_function"); } static void gen_inline_functions(TCCState *s) @@ -6861,17 +7341,28 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) Sym *sym; AttributeDef ad; + trace_enter ("decl0"); + while (1) { + trace ("decl0 01\n"); if (!parse_btype(&btype, &ad)) { - if (is_for_loop_init) + trace ("decl0 4\n"); + trace ("*** btype.t="); eputs (itoa (btype.t)); eputs ("\n"); + if (is_for_loop_init) { + trace_exit ("decl0 4"); return 0; + } /* skip redundant ';' if not in old parameter decl scope */ if (tok == ';' && l != VT_CMP) { + trace ("decl0 10\n"); + trace ("decl0 10\n"); + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); next(); continue; } if (l == VT_CONST && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { + trace ("decl0 20\n"); /* global asm block */ asm_global_instr(); continue; @@ -6885,6 +7376,8 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) if (((btype.t & VT_BTYPE) == VT_ENUM || (btype.t & VT_BTYPE) == VT_STRUCT) && tok == ';') { + trace ("decl0 40\n"); + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); if ((btype.t & VT_BTYPE) == VT_STRUCT) { int v = btype.ref->v; if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM) @@ -6894,16 +7387,25 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) continue; } while (1) { /* iterate thru each declaration */ + trace ("decl0 50\n"); + trace ("*** btype.t="); eputs (itoa (btype.t)); eputs ("\n"); type = btype; + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); + /* 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) { + trace ("decl0 51\n"); + trace ("PUSH\n"); + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c); } type_decl(&type, &ad, &v, TYPE_DIRECT); + trace ("decl0 52\n"); + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); #if 0 { char buf[500]; @@ -6912,6 +7414,8 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) } #endif if ((type.t & VT_BTYPE) == VT_FUNC) { + trace ("decl0 54\n"); + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); if ((type.t & VT_STATIC) && (l == VT_LOCAL)) { tcc_error("function without file scope cannot be static"); } @@ -6922,6 +7426,9 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) decl0(VT_CMP, 0, sym); } + trace ("decl0 60\n"); + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); + 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 */ @@ -6942,30 +7449,52 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) type.t |= VT_IMPORT|VT_EXTERN; } #endif + trace ("decl0 80\n"); + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); type.t |= ad.a.visibility << VT_VIS_SHIFT; + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); if (tok == '{') { + trace ("decl0 100\n"); + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); if (l != VT_CONST) tcc_error("cannot use local functions"); if ((type.t & VT_BTYPE) != VT_FUNC) expect("function definition"); + trace ("decl0 110\n"); + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); /* 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)) + trace ("decl0 112\n"); + trace ("decl0 sym->v="); eputs (itoa (sym->v)); eputs ("\n"); + trace ("decl0 sym->v="); eputs (itoa (sym->v)); eputs ("\n"); + trace ("decl0 SYM_FIELD="); eputs (itoa (SYM_FIELD)); eputs ("\n"); + trace ("decl0 ~SYM_FIELD="); eputs (itoa (~SYM_FIELD)); eputs ("\n"); + trace ("decl0 sym->v & ~SYM_FIELD="); eputs (itoa (sym->v & ~SYM_FIELD)); eputs ("\n"); + trace ("decl0 !(sym->v & ~SYM_FIELD)="); eputs (itoa (!(sym->v & ~SYM_FIELD))); eputs ("\n"); + if (!(sym->v & ~SYM_FIELD)) { + trace ("decl0 113\n"); expect("identifier"); + } + trace ("decl0 115\n"); if (sym->type.t == VT_VOID) sym->type = int_type; + trace ("decl0 116 sym->next=");// eputs (itoa (sym->next)); eputs ("\n"); + if (!sym->next) break; } + trace ("decl0 120\n"); + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); /* 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) { + trace ("decl0 130\n"); Sym *ref; if ((sym->type.t & VT_BTYPE) != VT_FUNC) goto func_error1; @@ -7000,19 +7529,28 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) sym->type = type; } else { + trace ("decl0 140\n"); + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); /* put function symbol */ sym = global_identifier_push(v, type.t, 0); sym->type.ref = type.ref; + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); } sym->type.ref->a.func_body = 1; sym->r = VT_SYM | VT_CONST; + trace ("*** type.t="); eputs (itoa (type.t)); eputs ("\n"); + trace ("decl0 150\n"); + trace ("decl0 150 type.t="); eputs (itoa (type.t)); eputs ("\n"); + trace ("decl0 150 (VT_INLINE|VT_STATIC)="); eputs (itoa ((VT_INLINE | VT_STATIC))); eputs ("\n"); + trace ("decl0 150 type.t & (VT_INLINE|VT_STATIC)="); eputs (itoa (type.t & (VT_INLINE | VT_STATIC))); eputs ("\n"); /* 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)) { + trace ("decl0 151\n"); struct InlineFunc *fn; const char *filename; @@ -7024,14 +7562,20 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) dynarray_add(&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn); } else { + trace ("decl0 160\n"); /* compute text section */ cur_text_section = ad.section; - if (!cur_text_section) - cur_text_section = text_section; + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + trace ("decl0 161 cur_text_section="); eputs (cur_text_section ? cur_text_section->name : ""); eputs ("\n"); + cur_text_section = text_section; gen_function(sym); + trace ("*** text_section="); eputs (text_section ? text_section->name : ""); eputs ("\n"); + trace ("decl0 165\n"); } + trace ("decl0 100 98\n"); break; } else { + trace ("decl0 200\n"); if (l == VT_CMP) { /* find parameter in function parameter list */ for (sym = func_sym->next; sym; sym = sym->next) @@ -7108,8 +7652,10 @@ found: } } if (tok != ',') { - if (is_for_loop_init) + if (is_for_loop_init) { + trace_exit ("decl0 201"); return 1; + } skip(';'); break; } @@ -7118,12 +7664,15 @@ found: ad.a.aligned = 0; } } + trace_exit ("decl0"); return 0; } ST_FUNC void decl(int l) { + trace_enter ("decl"); decl0(l, 0, NULL); + trace_exit ("decl"); } /* ------------------------------------------------------------------------- */ diff --git a/tccpp.c b/tccpp.c index fd4b9c6..b41c928 100644 --- a/tccpp.c +++ b/tccpp.c @@ -260,12 +260,21 @@ static void *tal_realloc_impl(TinyAlloc **pal, void *p, unsigned size TAL_DEBUG_ unsigned adj_size = (size + 3) & -4; TinyAlloc *al = *pal; + //eputs ("tal_realloc_impl 00\n"); + //eputs ("tal_realloc_impl al="); //eputs (itoa (al)); //eputs ("\n"); + //eputs ("tal_realloc_impl al->p="); //eputs (itoa (&al->p)); //eputs ("\n"); + //header = al->p; + //eputs ("tal_realloc_impl al->p->size="); //eputs (itoa (header->size)); //eputs ("\n"); tail_call: is_own = (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size); if ((!p || is_own) && size <= al->limit) { + //eputs ("tal_realloc_impl 01\n"); if (al->p + adj_size + sizeof(tal_header_t) < al->buffer + al->size) { + //eputs ("tal_realloc_impl 02\n"); header = (tal_header_t *)al->p; + //eputs ("tal_realloc_impl 03\n"); header->size = adj_size; + //eputs ("tal_realloc_impl 04\n"); #ifdef TAL_DEBUG { int ofs = strlen(file) - TAL_DEBUG_FILE_LEN; strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), TAL_DEBUG_FILE_LEN); @@ -273,14 +282,20 @@ tail_call: header->line_num = line; } #endif ret = al->p + sizeof(tal_header_t); + //eputs ("tal_realloc_impl 05\n"); al->p += adj_size + sizeof(tal_header_t); + //eputs ("tal_realloc_impl 07\n"); if (is_own) { + //eputs ("tal_realloc_impl 08\n"); header = (((tal_header_t *)p) - 1); + //eputs ("tal_realloc_impl 09\n"); memcpy(ret, p, header->size); + //eputs ("tal_realloc_impl 10\n"); #ifdef TAL_DEBUG header->line_num = -header->line_num; #endif } else { + //eputs ("tal_realloc_impl 11\n"); al->nb_allocs++; } #ifdef TAL_INFO @@ -290,8 +305,10 @@ tail_call: al->peak_p = al->p; al->nb_total++; #endif + //eputs ("tal_realloc_impl 990\n"); return ret; } else if (is_own) { + //eputs ("tal_realloc_impl 10\n"); al->nb_allocs--; ret = tal_realloc(*pal, 0, size); header = (((tal_header_t *)p) - 1); @@ -299,11 +316,14 @@ tail_call: #ifdef TAL_DEBUG header->line_num = -header->line_num; #endif + //eputs ("tal_realloc_impl 991\n"); return ret; } if (al->next) { + //eputs ("tal_realloc_impl 20\n"); al = al->next; } else { + //eputs ("tal_realloc_impl 30\n"); TinyAlloc *bottom = al, *next = al->top ? al->top : al; al = tal_new(pal, next->limit, next->size * 2); @@ -313,6 +333,7 @@ tail_call: goto tail_call; } if (is_own) { + //eputs ("tal_realloc_impl 40\n"); al->nb_allocs--; ret = tcc_malloc(size); header = (((tal_header_t *)p) - 1); @@ -321,6 +342,7 @@ tail_call: header->line_num = -header->line_num; #endif } else if (al->next) { + //eputs ("tal_realloc_impl 50\n"); al = al->next; goto tail_call; } else @@ -328,6 +350,7 @@ tail_call: #ifdef TAL_INFO al->nb_missed++; #endif + //eputs ("tal_realloc_impl 999\n"); return ret; } @@ -339,22 +362,31 @@ static void cstr_realloc(CString *cstr, int new_size) { int size; + //eputs ("cstr_realloc 00\n"); size = cstr->size_allocated; if (size < 8) size = 8; /* no need to allocate a too small first string */ - while (size < new_size) + //eputs ("cstr_realloc 01\n"); + while (size < new_size) { + //eputs ("cstr_realloc 02\n"); size = size * 2; + } cstr->data = tal_realloc(cstr_alloc, cstr->data, size); + //eputs ("cstr_realloc 03\n"); cstr->size_allocated = size; + //eputs ("cstr_realloc 99\n"); } /* add a byte */ ST_INLN void cstr_ccat(CString *cstr, int ch) { int size; + //eputs ("cstr_ccat 00\n"); size = cstr->size + 1; - if (size > cstr->size_allocated) + if (size > cstr->size_allocated) { + //eputs ("cstr_ccat 01\n"); cstr_realloc(cstr, size); + } // FIXME unsigned char* p = cstr->data; p[size - 1] = ch; cstr->size = size; @@ -363,12 +395,22 @@ ST_INLN void cstr_ccat(CString *cstr, int ch) ST_FUNC void cstr_cat(CString *cstr, const char *str, int len) { int size; - if (len <= 0) + trace_enter ("cstr_cat"); + trace ("cstr_cat len="); eputs (itoa (len)); eputs ("\n"); + trace ("cstr_cat str="); eputs (str); eputs ("\n"); + if (len <= 0) { + trace ("cstr_cat 01\n"); len = strlen(str) + 1 + len; + trace ("cstr_cat 01 len="); eputs (itoa (len)); eputs ("\n"); + } size = cstr->size + len; - if (size > cstr->size_allocated) + trace ("cstr_cat 02 size="); eputs (itoa (size)); eputs ("\n"); + if (size > cstr->size_allocated) { + trace ("cstr_cat 03\n"); cstr_realloc(cstr, size); + } memmove(((unsigned char *)cstr->data) + cstr->size, str, len); + trace ("cstr_cat data="); eputs (cstr->data); eputs ("\n"); cstr->size = size; } @@ -429,18 +471,33 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) TokenSym *ts, **ptable; int i; + //eputs ("tok_alloc_new00\n"); if (tok_ident >= SYM_FIRST_ANOM) tcc_error("memory full (symbols)"); + //eputs ("tok_alloc_new01\n"); /* expand token table if needed */ i = tok_ident - TOK_IDENT; + //eputs ("tok_alloc_new i="); //eputs (itoa (i)); //eputs ("\n"); + //eputs ("tok_alloc_new TAI="); //eputs (itoa (TOK_ALLOC_INCR)); //eputs ("\n"); + //eputs ("tok_alloc_new02\n"); if ((i % TOK_ALLOC_INCR) == 0) { + //eputs ("tok_alloc_new002\n"); ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *)); + //eputs ("tok_alloc_new012\n"); table_ident = ptable; } + //eputs ("tok_alloc_new03\n"); + + //eputs ("tok_alloc_new03 al="); //eputs (itoa (toksym_alloc)); //eputs ("\n"); + //eputs ("tok_alloc_new03 al->p="); //eputs (itoa (&toksym_alloc->p)); //eputs ("\n"); + tal_header_t *h = (tal_header_t*)toksym_alloc->p; + //eputs ("tok_alloc_new03 al->p->size="); //eputs (itoa (h->size)); //eputs ("\n"); ts = tal_realloc(toksym_alloc, 0, sizeof(TokenSym) + len); + //eputs ("tok_alloc_new04\n"); table_ident[i] = ts; + //eputs ("tok_alloc_new05\n"); ts->tok = tok_ident++; ts->sym_define = NULL; ts->sym_label = NULL; @@ -451,6 +508,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) memcpy(ts->str, str, len); ts->str[len] = '\0'; *pts = ts; + //eputs ("tok_alloc_new99\n"); return ts; } @@ -465,20 +523,36 @@ ST_FUNC TokenSym *tok_alloc(const char *str, int len) int i; unsigned int h; + //eputs ("tok_alloc00\n"); + //eputs ("tok_alloc00 str="); //eputs (str); //eputs ("\n"); h = TOK_HASH_INIT; - for(i=0;ilen == len && !memcmp(ts->str, str, len)) + } + if (ts->len == len && !memcmp(ts->str, str, len)) { + //eputs ("tok_alloc 10\n"); return ts; + } pts = &(ts->hash_next); } + //eputs ("tok_alloc99\n"); return tok_alloc_new(pts, str, len); } @@ -492,6 +566,10 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv) cstr_reset(&cstr_buf); p = cstr_buf.data; + trace_enter ("get_tok_str"); + trace ("get_tok_str v="); eputs (itoa (v)); eputs ("\n"); + + switch(v) { case TOK_CINT: case TOK_CUINT: @@ -514,10 +592,15 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv) break; case TOK_PPNUM: case TOK_PPSTR: + { + trace ("get_tok_str 5r\n"); return (char*)cv->str.data; + } case TOK_LSTR: cstr_ccat(&cstr_buf, 'L'); case TOK_STR: + { + trace ("get_tok_str 7\n"); cstr_ccat(&cstr_buf, '\"'); if (v == TOK_STR) { len = cv->str.size - 1; @@ -531,7 +614,7 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv) cstr_ccat(&cstr_buf, '\"'); cstr_ccat(&cstr_buf, '\0'); break; - + } case TOK_CFLOAT: cstr_cat(&cstr_buf, "", 0); break; @@ -554,12 +637,23 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv) v = '>'; goto addv; case TOK_DOTS: + { + trace_exit ("get_tok_str"); return strcpy(p, "..."); + } case TOK_A_SHL: + { + trace_exit ("get_tok_str"); return strcpy(p, "<<="); + } case TOK_A_SAR: + { + trace_exit ("get_tok_str"); return strcpy(p, ">>="); + } default: + { + trace ("get_tok_str default\n"); if (v < TOK_IDENT) { /* search in two bytes table */ const unsigned char *q = tok_two_chars; @@ -568,28 +662,48 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv) *p++ = q[0]; *p++ = q[1]; *p = '\0'; + trace_exit ("get_tok_str 01"); return cstr_buf.data; } q += 3; } if (v >= 127) { sprintf(cstr_buf.data, "<%02x>", v); + trace_exit ("get_tok_str 02"); return cstr_buf.data; } addv: *p++ = v; *p = '\0'; } else if (v < tok_ident) { + trace ("get_tok_str 03\n"); + trace ("get_tok_str 03 v="); eputs (itoa (v)); eputs ("\n"); + trace ("get_tok_str 03 v - TOK_IDENT="); eputs (itoa (v - TOK_IDENT)); eputs ("\n"); +#if 1 + trace ("get_tok_str 03 str="); eputs (table_ident[v - TOK_IDENT]->str) ; eputs ("\n"); + trace_exit ("get_tok_str 03"); return table_ident[v - TOK_IDENT]->str; +#else + TokenSym *ts = table_ident[v - TOK_IDENT]; + char *s = ts->str; + trace ("get_tok_str 03 99 str="); eputs (s ? s : ""); eputs ("\n"); + trace_exit ("get_tok_str 03"); + return ts->str; +#endif } else if (v >= SYM_FIRST_ANOM) { + trace ("get_tok_str 04\n"); /* special name for anonymous symbol */ sprintf(p, "L.%u", v - SYM_FIRST_ANOM); } else { /* should never happen */ + trace ("get_tok_str 05\n"); + trace_exit ("get_tok_str 05"); return NULL; } break; + } } + trace_exit ("get_tok_str 06"); return cstr_buf.data; } @@ -664,12 +778,16 @@ static void handle_stray(void) tcc_error("stray '\\' in program"); } +#define eputc(c) + /* 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; + int x = *(char*)p; + trace ("handle_stray1 x="); eputc (x); eputs (" ["); eputs (itoa (x)); eputs ("]\n"); file->buf_ptr = p; if (p >= file->buf_end) { c = handle_eob(); @@ -836,7 +954,9 @@ ST_FUNC uint8_t *parse_comment(uint8_t *p) ST_FUNC void set_idnum(int c, int val) { + trace ("set_idnum c="); eputs (itoa (c)); eputs (": "); eputs (itoa (val)); eputs ("\n"); isidnum_table[c - CH_EOF] = val; + trace ("set_idnum[x]="); eputs (itoa (isidnum_table[c - CH_EOF])); eputs ("\n"); } #define cinp minp @@ -1155,6 +1275,9 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) { int len, *str; + //eputs ("tok_str_add2 00\n"); + //eputs ("tok_str_add2 t="); //eputs (itoa (t)); //eputs ("\n"); + len = s->len; str = s->str; @@ -1176,13 +1299,37 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) case TOK_STR: case TOK_LSTR: { + //eputs ("tok_str_add2 20\n"); /* Insert the string into the int array. */ + //eputs ("tok_str_add2 cv->str.size="); //eputs (itoa (cv->str.size)); //eputs ("\n"); size_t nb_words = 1 + (cv->str.size + sizeof(int) - 1) / sizeof(int); + //eputs ("tok_str_add2 len="); //eputs (itoa (len)); //eputs ("\n"); + //eputs ("tok_str_add2 size="); //eputs (itoa (cv->str.size)); //eputs ("\n"); + //eputs ("tok_str_add2 data="); //eputs (itoa (cv->str.data)); //eputs ("\n"); + //eputs ("tok_str_add2 nb_words="); //eputs (itoa (nb_words)); //eputs ("\n"); + //eputs ("tok_str_add2 allocated_len="); //eputs (itoa (s->allocated_len)); //eputs ("\n"); + //eputs ("tok_str_add2 len + nb_words >= s->allocated_len="); //eputs (itoa (len + nb_words >= s->allocated_len)); //eputs ("\n"); if (len + nb_words >= s->allocated_len) str = tok_str_realloc(s, len + nb_words + 1); str[len] = cv->str.size; + + //eputs ("tok_str_add2 22\n"); + int x = *(int*)cv->str.data; + //eputs ("tok_str_add2 23\n"); + int y = *(int*)(cv->str.data + 1); + //eputs ("tok_str_add2 24\n"); + //eputs ("tok_str_add2 25\n"); + + str[len+1] = 0; + //eputs ("tok_str_add2 26\n"); + str[len+2] = 0; + //eputs ("tok_str_add2 27\n"); + str[len+2] = 0; + memcpy(&str[len + 1], cv->str.data, cv->str.size); + + //eputs ("tok_str_add2 32\n"); len += nb_words; break; } @@ -1215,6 +1362,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) break; } s->len = len; + //eputs ("tok_str_add2 99\n"); } /* add the current parse token in token string 's' */ @@ -1240,21 +1388,25 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) tab = cv->tab; switch(*t = *p++) { + //eputs ("tok get i="); //eputs (itoa (i)); //eputs ("\n"); case TOK_CINT: case TOK_CUINT: case TOK_CCHAR: case TOK_LCHAR: case TOK_LINENUM: + //eputs ("tok get 1\n"); tab[0] = *p++; cv->i = (*t == TOK_CUINT) ? (unsigned)cv->i : (int)cv->i; break; case TOK_CFLOAT: + //eputs ("tok get 2\n"); tab[0] = *p++; break; case TOK_STR: case TOK_LSTR: case TOK_PPNUM: case TOK_PPSTR: + //eputs ("tok get 3"); cv->str.size = *p++; cv->str.data = p; p += (cv->str.size + sizeof(int) - 1) / sizeof(int); @@ -1262,9 +1414,11 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) case TOK_CDOUBLE: case TOK_CLLONG: case TOK_CULLONG: + //eputs ("tok get 4\n"); n = 2; goto copy; case TOK_CLDOUBLE: + //eputs ("tok get 5\n"); #if LDOUBLE_SIZE == 16 n = 4; #elif LDOUBLE_SIZE == 12 @@ -1280,6 +1434,7 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) while (--n); break; default: + //eputs ("tok get 6\n"); break; } *pp = p; @@ -1307,15 +1462,21 @@ static int macro_is_equal(const int *a, const int *b) return 1; while (*a && *b) { + //eputs ("macro_is_equal 01\n"); /* first time preallocate macro_equal_buf, next time only reset position to start */ cstr_reset(¯o_equal_buf); + //eputs ("macro_is_equal 02\n"); TOK_GET(&t, &a, &cv); char *s = get_tok_str(t, &cv); cstr_cat(¯o_equal_buf, s, 0); TOK_GET(&t, &b, &cv); - if (strcmp(macro_equal_buf.data, get_tok_str(t, &cv))) + //eputs ("macro_is_equal 05\n"); + if (strcmp(macro_equal_buf.data, get_tok_str(t, &cv))) { + //eputs ("macro_is_equal 099\n"); return 0; + } } + //eputs ("macro_is_equal 99\n"); return !(*a || *b); } @@ -1324,14 +1485,22 @@ ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg) { Sym *s, *o; + //eputs ("define_push00\n"); o = define_find(v); + //eputs ("define_push01\n"); + //eputs ("define_push01 define_stack="); //eputs (itoa (define_stack)); //eputs ("\n"); + //eputs ("define_push01 define_stack="); //eputs (itoa (&define_stack)); //eputs ("\n"); s = sym_push2(&define_stack, v, macro_type, 0); + //eputs ("define_push02\n"); s->d = str; + //eputs ("define_push03\n"); s->next = first_arg; + //eputs ("define_push04\n"); 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)); + //eputs ("define_push06\n"); } /* undefined a define symbol. Its name is just set to zero */ @@ -1345,6 +1514,11 @@ ST_FUNC void define_undef(Sym *s) ST_INLN Sym *define_find(int v) { v -= TOK_IDENT; + //eputs ("define_find TOK_IDENT="); //eputs (itoa (TOK_IDENT)); //eputs ("\n"); + //eputs ("define_find tok_ident="); //eputs (itoa (tok_ident)); //eputs ("\n"); + //eputs ("define_find v="); //eputs (itoa (v)); //eputs ("\n"); + //eputs ("define_find tok_ident - TOK_IDENT="); //eputs (itoa ((tok_ident - TOK_IDENT))); //eputs ("\n"); + if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) return NULL; TokenSym *t = table_ident[v]; @@ -1484,8 +1658,11 @@ ST_FUNC void parse_define(void) character. */ parse_flags = ((parse_flags & ~PARSE_FLAG_ASM_FILE) | PARSE_FLAG_SPACES); /* '(' must be just after macro definition for MACRO_FUNC */ + //eputs ("parse_define 01\n"); next_nomacro_spc(); + //eputs ("parse_define 02\n"); if (tok == '(') { + //eputs ("parse_define 03\n"); set_idnum('.', 0); next_nomacro(); ps = &first; @@ -1516,7 +1693,9 @@ ST_FUNC void parse_define(void) t = MACRO_FUNC; } + //eputs ("parse_define 20\n"); tokstr_buf.len = 0; + //eputs ("parse_define 21\n"); 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 @@ -1525,7 +1704,10 @@ ST_FUNC void parse_define(void) regarded as line comment leader, so still don't set ASM_FILE in parse_flags. */ set_idnum('.', (saved_parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0); + //eputs ("parse_define 23\n"); while (tok != TOK_LINEFEED && tok != TOK_EOF) { + //eputs ("parse_define 30\n"); + //eputs ("parse_define tok="); //eputc (tok); //eputs (" ["); //eputs (itoa (tok)); //eputs ("]\n"); /* remove spaces around ## and after '#' */ if (TOK_TWOSHARPS == tok) { if (2 == spc) @@ -1539,19 +1721,25 @@ ST_FUNC void parse_define(void) } else if (check_space(tok, &spc)) { goto skip; } + //eputs ("parse_define 37\n"); tok_str_add2(&tokstr_buf, tok, &tokc); + //eputs ("parse_define 38\n"); skip: next_nomacro_spc(); } + //eputs ("parse_define 40\n"); parse_flags = saved_parse_flags; if (spc == 1) --tokstr_buf.len; /* remove trailing space */ + //eputs ("parse_define 43\n"); tok_str_add(&tokstr_buf, 0); if (3 == spc) bad_twosharp: tcc_error("'##' cannot appear at either end of macro"); + //eputs ("parse_define 45\n"); define_push(v, t, tok_str_dup(&tokstr_buf), first); + //eputs ("parse_define 99\n"); } static CachedInclude *search_cached_include(TCCState *s1, const char *filename, int add) @@ -1713,6 +1901,7 @@ ST_FUNC void preprocess(int is_bof) char *q; Sym *s; + trace_enter ("preprocess"); saved_parse_flags = parse_flags; parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM @@ -1723,6 +1912,7 @@ ST_FUNC void preprocess(int is_bof) next_nomacro(); redo: + trace ("preprocess tok="); eputc (tok); eputs (" ["); eputs (itoa (tok)); eputs ("\n"); switch(tok) { case TOK_DEFINE: pp_debug_tok = tok; @@ -1793,40 +1983,62 @@ ST_FUNC void preprocess(int is_bof) buf[len - 2] = '\0'; } + trace ("preprocess 40 file="); eputs (file->filename); eputs ("\n"); +#if !__MESC__ if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) tcc_error("#include recursion too deep"); +#endif /* store current file in stack, but increment stack later below */ + trace ("preprocess 42\n"); + trace ("preprocess 42 include_stack_ptr="); eputs (itoa (s1->include_stack_ptr - s1->include_stack)); eputs ("\n"); *s1->include_stack_ptr = file; + trace ("preprocess 43\n"); i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0; + trace ("preprocess 44 i="); eputs (itoa (i)); eputs ("\n"); n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths; + trace ("preprocess 45 n="); eputs (itoa (n)); eputs ("\n"); for (; i < n; ++i) { + trace ("preprocess 46 n="); eputs (itoa (n)); eputs ("\n"); char buf1[sizeof file->filename]; + trace ("preprocess 47 sizeof buf1="); eputs (itoa (sizeof(buf1))); eputs ("\n"); CachedInclude *e; const char *path; if (i == 0) { + trace ("preprocess 50\n"); /* check absolute include path */ - if (!IS_ABSPATH(buf)) + trace ("preprocess 51 buf="); eputs (buf); eputs ("\n"); + if (!IS_ABSPATH(buf)) { + trace ("preprocess 52\n"); continue; + } + trace ("preprocess 53\n"); buf1[0] = 0; } else if (i == 1) { + trace ("preprocess 55\n"); /* search in file's dir if "header.h" */ if (c != '\"') continue; /* https://savannah.nongnu.org/bugs/index.php?50847 */ path = file->filename2; + trace ("preprocess path="); eputs (path); eputs ("\n"); pstrncpy(buf1, path, tcc_basename(path) - path); - + trace ("preprocess buf1="); eputs (buf1); eputs ("\n"); } else { + trace ("preprocess 60\n"); /* 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]; + trace ("preprocess path="); eputs (path); eputs ("\n"); pstrcpy(buf1, sizeof (file->filename), path); + trace ("preprocess buf1="); eputs (buf1); eputs ("\n"); pstrcat(buf1, sizeof (file->filename), "/"); + trace ("preprocess buf1="); eputs (buf1); eputs ("\n"); } pstrcat(buf1, sizeof (file->filename), buf); + trace ("preprocess 70 buf1="); eputs (buf1); eputs ("\n"); 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' @@ -1852,6 +2064,7 @@ ST_FUNC void preprocess(int is_bof) tcc_strdup(buf1)); /* push current file in stack */ ++s1->include_stack_ptr; + trace ("preprocess include_stack_ptr="); eputs (itoa (s1->include_stack_ptr - s1->include_stack)); eputs ("\n"); /* add include file debug info */ if (s1->do_debug) put_stabs(file->filename, N_BINCL, 0, 0, 0); @@ -2007,6 +2220,7 @@ include_done: next_nomacro(); the_end: parse_flags = saved_parse_flags; + trace_exit ("preprocess"); } /* evaluate escape codes in a string. */ @@ -2198,6 +2412,7 @@ static void parse_number(const char *p) double d; #endif // HAVE_FLOAT + trace_enter ("parse_number"); /* number */ q = token_buf; ch = *p++; @@ -2221,6 +2436,7 @@ static void parse_number(const char *p) /* parse all digits. cannot check octal numbers at this stage because of floating point constants */ while (1) { + trace ("parse_number 20\n"); if (ch >= 'a' && ch <= 'f') t = ch - 'a' + 10; else if (ch >= 'A' && ch <= 'F') @@ -2238,9 +2454,11 @@ static void parse_number(const char *p) *q++ = ch; ch = *p++; } + trace ("parse_number 30\n"); if (ch == '.' || ((ch == 'e' || ch == 'E') && b == 10) || ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) { + trace ("parse_number 31\n"); if (b != 10) { /* NOTE: strtox should support that for hexa numbers, but non ISOC99 libcs do not support it, so we prefer to do @@ -2340,6 +2558,7 @@ static void parse_number(const char *p) } #endif // HAVE_FLOAT } else { + trace ("parse_number 61\n"); /* decimal floats */ if (ch == '.') { if (q >= token_buf + STRING_MAX_SIZE) @@ -2404,6 +2623,7 @@ static void parse_number(const char *p) #endif // HAVE_FLOAT } } else { + trace ("parse_number 81\n"); unsigned long long n, n1; int lcount, ucount, must_64bit; const char *p1; @@ -2411,12 +2631,17 @@ static void parse_number(const char *p) /* integer number */ *q = '\0'; q = token_buf; + trace ("parse_number 82\n"); if (b == 10 && *q == '0') { + trace ("parse_number 83\n"); b = 8; q++; } + trace ("parse_number 84\n"); n = 0; + trace ("parse_number 85\n"); while(1) { + trace ("parse_number 86\n"); t = *q++; /* no need for checks except for base 10 / 8 errors */ if (t == '\0') @@ -2442,6 +2667,7 @@ static void parse_number(const char *p) lcount = ucount = must_64bit = 0; p1 = p; for(;;) { + trace ("parse_number 91\n"); t = toup(ch); if (t == 'L') { if (lcount >= 2) @@ -2464,36 +2690,50 @@ static void parse_number(const char *p) } } + trace ("parse_number 100\n"); #if !BOOTSTRAP //!__MESC__ /* Whether 64 bits are needed to hold the constant's value */ if (n & 0xffffffff00000000LL || must_64bit) { + trace ("parse_number 101\n"); tok = TOK_CLLONG; + trace ("parse_number 102\n"); n1 = n >> 32; + trace ("parse_number 103\n"); } else #endif { + trace ("parse_number 104\n"); tok = TOK_CINT; + trace ("parse_number 105\n"); n1 = n; + trace ("parse_number 106\n"); } + trace ("parse_number 107\n"); /* Whether type must be unsigned to hold the constant's value */ if (ucount || ((n1 >> 31) && (b != 10))) { + trace ("parse_number 108\n"); if (tok == TOK_CLLONG) tok = TOK_CULLONG; else tok = TOK_CUINT; + trace ("parse_number 109\n"); /* If decimal and no unsigned suffix, bump to 64 bits or throw error */ } else if (n1 >> 31) { + trace ("parse_number 110\n"); if (tok == TOK_CINT) tok = TOK_CLLONG; else tcc_error("integer constant overflow"); } + trace ("parse_number 120\n"); tokc.i = n; + trace ("parse_number 121\n"); } if (ch) tcc_error("invalid number\n"); + trace_exit ("parse_number"); } @@ -2510,6 +2750,10 @@ static void parse_number(const char *p) break; \ } +//#if BOOTSTRAP +//#define eputs(x) +//#endif + /* return next token without macro substitution */ static inline void next_nomacro1(void) { @@ -2518,8 +2762,14 @@ static inline void next_nomacro1(void) uint8_t *p, *p1; unsigned int h; + trace_enter ("next_nomacro1"); + p = file->buf_ptr; + trace ("next_nomacro1 01\n"); + trace ("next_nomacro1 file->buf_ptr"); eputs (file->buf_ptr); eputs ("\n"); + redo_no_start: + trace ("next_nomacro1 02\n"); c = *p; switch(c) { case ' ': @@ -2536,35 +2786,50 @@ static inline void next_nomacro1(void) case '\r': p++; goto redo_no_start; + case 0: case '\\': + { + trace ("next_nomacro1 backsles \n"); /* first look if it is in fact an end of buffer */ c = handle_stray1(p); p = file->buf_ptr; - if (c == '\\') + if (c == '\\') { + trace ("bs: SIMPLE\n"); goto parse_simple; - if (c != CH_EOF) + } + if (c != CH_EOF) { + trace ("bs EOF\n"); goto redo_no_start; + } { + trace ("HIERO\n"); TCCState *s1 = tcc_state; + trace ("preprocess include_stack_ptr="); eputs (itoa (s1->include_stack_ptr - s1->include_stack)); eputs ("\n"); if ((parse_flags & PARSE_FLAG_LINEFEED) && !(tok_flags & TOK_FLAG_EOF)) { + trace ("next_nomacro1 20\n"); tok_flags |= TOK_FLAG_EOF; tok = TOK_LINEFEED; goto keep_tok_flags; } else if (!(parse_flags & PARSE_FLAG_PREPROCESS)) { + trace ("next_nomacro1 25\n"); tok = TOK_EOF; } else if (s1->ifdef_stack_ptr != file->ifdef_stack_ptr) { + trace ("next_nomacro1 30\n"); tcc_error("missing #endif"); } else if (s1->include_stack_ptr == s1->include_stack) { + trace ("next_nomacro1 35\n"); /* no include left : end of file. */ tok = TOK_EOF; } else { + trace ("next_nomacro1 40\n"); 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) { + trace ("next_nomacro1 45\n"); #ifdef INC_DEBUG printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL)); #endif @@ -2580,13 +2845,16 @@ static inline void next_nomacro1(void) /* pop include stack */ tcc_close(); s1->include_stack_ptr--; + trace ("preprocess include_stack_ptr="); eputs (itoa (s1->include_stack_ptr - s1->include_stack)); eputs ("\n"); p = file->buf_ptr; goto redo_no_start; } } break; - + } case '\n': + { + trace ("next_nomacro1 newline \n"); file->line_num++; tok_flags |= TOK_FLAG_BOL; p++; @@ -2595,9 +2863,10 @@ maybe_newline: goto redo_no_start; tok = TOK_LINEFEED; goto keep_tok_flags; - + } case '#': { + trace ("next_nomacro1 # \n"); /* XXX: simplify */ PEEKC(c, p); if ((tok_flags & TOK_FLAG_BOL) && @@ -2642,21 +2911,34 @@ maybe_newline: 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); + trace ("next_nomacro1 _ 02\n"); + trace ("next_nomacro1 _03 c="); eputc (c); eputs ("\n"); + trace ("next_nomacro1 _ c - CH_EOF="); eputs (itoa (c-CH_EOF)); eputs ("\n"); + trace ("next_nomacro1 _(IS_ID|IS_NUM)="); eputs (itoa ((IS_ID|IS_NUM))); eputs ("\n"); + trace ("next_nomacro1 _isidnum="); eputs (itoa (isidnum_table[c - CH_EOF])); eputs ("\n"); + trace ("next_nomacro1 _ =>="); eputs (itoa (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))); eputs ("\n"); while (c = *++p, isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM)) h = TOK_HASH_FUNC(h, c); + trace ("next_nomacro1 _ 06\n"); len = p - p1; + trace ("next_nomacro1 _ 06 len="); eputs (itoa (len)); eputs ("]\n"); if (c != '\\') { + trace ("next_nomacro1 _ 07\n"); TokenSym **pts; /* fast case : no stray found, so we have the full token and we have already hashed it */ h &= (TOK_HASH_SIZE - 1); + trace ("next_nomacro1 _ 08 h="); eputs (itoa (h)); eputs ("\n"); pts = &hash_ident[h]; for(;;) { + //if (!*pts) {eputs ("next_nomacro1 _ 08 *pts="); eputs (itoa (*pts)); eputs ("\n");} + trace ("next_nomacro1 _ 09\n"); ts = *pts; if (!ts) break; @@ -2664,9 +2946,11 @@ maybe_newline: goto token_found; pts = &(ts->hash_next); } + trace ("next_nomacro1 _ 10 p1->tok="); eputc (itoa (*p1)); eputs (" ["); eputs (itoa (*p1)); eputs ("]\n"); ts = tok_alloc_new(pts, (char *) p1, len); token_found: ; } else { + trace ("next_nomacro1 _ 20\n"); /* slower case */ cstr_reset(&tokcstr); cstr_cat(&tokcstr, (char *) p1, len); @@ -2675,14 +2959,19 @@ maybe_newline: parse_ident_slow: while (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM)) { + trace ("next_nomacro1 _ 30\n"); cstr_ccat(&tokcstr, c); PEEKC(c, p); } ts = tok_alloc(tokcstr.data, tokcstr.size); } tok = ts->tok; + trace ("next_nomacro1 _ 98\n"); break; + } case 'L': + { + trace ("next_nomacro1 L \n"); t = p[1]; if (t != '\\' && t != '\'' && t != '\"') { /* fast case */ @@ -2699,10 +2988,12 @@ maybe_newline: } } break; - + } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + { + trace ("next_nomacro1 0-9\n"); t = c; PEEKC(c, p); /* after the first digit, accept digits, alpha, '.' or sign if @@ -2711,6 +3002,11 @@ maybe_newline: cstr_reset(&tokcstr); for(;;) { cstr_ccat(&tokcstr, t); + trace ("next_nomacro1 0-9 c="); eputs (itoa (c)); eputs ("\n"); + trace ("next_nomacro1 0-9 c - CH_EOF="); eputs (itoa (c-CH_EOF)); eputs ("\n"); + trace ("next_nomacro1 0-9 (IS_ID|IS_NUM)="); eputs (itoa ((IS_ID|IS_NUM))); eputs ("\n"); + trace ("next_nomacro1 0-9 isidnum[6]="); eputs (itoa (isidnum_table[6])); eputs ("\n"); + trace ("next_nomacro1 0-9 isidnum="); eputs (itoa (isidnum_table[c - CH_EOF])); eputs ("\n"); if (!((isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM)) || c == '.' || ((c == '+' || c == '-') @@ -2720,18 +3016,30 @@ maybe_newline: && ((char*)tokcstr.data)[0] == '0' && toup(((char*)tokcstr.data)[1]) == 'X')) || t == 'p' || t == 'P')))) + { + trace ("next_nomacro1 break\n"); break; + } + else + trace ("next_nomacro1 NObreak\n"); t = c; PEEKC(c, p); } + trace ("next_nomacro1 0-9 10\n"); /* We add a trailing '\0' to ease parsing */ cstr_ccat(&tokcstr, '\0'); + trace ("next_nomacro1 0-9 11\n"); tokc.str.size = tokcstr.size; + trace ("next_nomacro1 0-9 12\n"); tokc.str.data = tokcstr.data; + trace ("next_nomacro1 0-9 13\n"); tok = TOK_PPNUM; + trace ("next_nomacro1 98\n"); break; + } case '.': { + trace ("next_nomacro1 . \n"); /* special dot handling because it can also start a number */ PEEKC(c, p); if (isnum(c)) { @@ -2757,6 +3065,8 @@ maybe_newline: } case '\'': case '\"': + { + trace ("next_nomacro1 quote \n"); is_long = 0; str_const: cstr_reset(&tokcstr); @@ -2766,11 +3076,14 @@ maybe_newline: p = parse_pp_string(p, c, &tokcstr); cstr_ccat(&tokcstr, c); cstr_ccat(&tokcstr, '\0'); + trace ("next_nomacro1 tokcstr.data="); eputs (tokcstr.data); eputs ("\n"); + trace ("next_nomacro1 tokcstr.size="); eputs (itoa (tokcstr.size)); eputs ("\n"); tokc.str.size = tokcstr.size; tokc.str.data = tokcstr.data; + trace ("next_nomacro1 tokc.str.data="); eputs (tokc.str.data); eputs ("\n"); tok = TOK_PPSTR; break; - + } case '<': { PEEKC(c, p); @@ -2896,11 +3209,11 @@ maybe_newline: break; } /* simple tokens */ + case '{': case '(': case ')': case '[': case ']': - case '{': case '}': case ',': case ';': @@ -2908,17 +3221,31 @@ maybe_newline: case '?': case '~': case '@': /* only used in assembler */ + { parse_simple: + trace ("next_nomacro1 parse simple\n"); tok = c; p++; break; + } default: - if (c >= 0x80 && c <= 0xFF) /* utf8 identifiers */ + { + trace ("next_nomacro1 default\n"); + if (c >= 0x80 && c <= 0xFF) {/* utf8 identifiers */ + trace (" utf8 ==> fast\n"); goto parse_ident_fast; - if (parse_flags & PARSE_FLAG_ASM_FILE) + } + trace ("next_nomacro1 parse flags="); eputs (itoa (parse_flags)); eputs ("\n"); + trace ("next_nomacro1 PARSE_FLAG_ASM_FILE="); eputs (itoa (PARSE_FLAG_ASM_FILE)); eputs ("\n"); + trace ("next_nomacro1 PARSE_FLAG_ASM_FILE="); eputs (itoa (parse_flags & PARSE_FLAG_ASM_FILE)); eputs ("\n"); + if (parse_flags & PARSE_FLAG_ASM_FILE) { + trace (" ==> simple\n"); goto parse_simple; - tcc_error("unrecognized character \\x%02x", c); + } + //tcc_error("unrecognized character \\x%02x", c); + tcc_error("unrecognized character %d\n", c); break; + } } tok_flags = 0; keep_tok_flags: @@ -2926,16 +3253,22 @@ keep_tok_flags: #if defined(PARSE_DEBUG) printf("token = %s\n", get_tok_str(tok, &tokc)); #endif + + trace ("next_nomacro1 tok="); eputc (tok); eputs (" ["); eputs (itoa (tok)); eputs ("]\n"); + trace_exit ("next_nomacro1"); } /* return next token without macro substitution. Can read input from macro_ptr buffer */ static void next_nomacro_spc(void) { + trace_enter ("next_nomacro_spc"); if (macro_ptr) { redo: + trace ("next_nomacro_spc 01\n"); tok = *macro_ptr; if (tok) { + trace ("next_nomacro_spc 03\n"); TOK_GET(&tok, ¯o_ptr, &tokc); if (tok == TOK_LINENUM) { file->line_num = tokc.i; @@ -2943,17 +3276,33 @@ static void next_nomacro_spc(void) } } } else { + trace ("next_nomacro_spc 10\n"); next_nomacro1(); } + trace_exit ("next_nomacro_spc"); } ST_FUNC void next_nomacro(void) { + trace_enter ("next_nomacro"); do { + trace ("next_nomacro 01\n"); next_nomacro_spc(); + trace ("next_nomacro 02\n"); + trace ("next_nomacro 02 tok="); eputc (tok); eputs (" ["); eputs (itoa (tok)); eputs ("]\n"); + int i = tok - CH_EOF; + trace ("next_nomacro 02 i="); eputs (itoa (i)); eputs ("\n"); + if (tok < 256) { + trace ("next_nomacro 02 isidnum="); eputs (itoa (isidnum_table[i])); eputs ("\n"); + trace ("next_nomacro 02 isidnum &="); eputs (itoa (isidnum_table[i] & IS_SPC)); eputs ("]\n"); + } } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC)); + trace_exit ("next_nomacro"); } +#if BOOTSTRAP +#undef eputs +#endif static void macro_subst( TokenString *tok_str, @@ -3014,6 +3363,7 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) /* add string */ cval.str.size = cstr.size; cval.str.data = cstr.data; + //eputs ("macro_arg tokc.str.data="); //eputs (itoa (tokc.str.data)); //eputs ("\n"); tok_str_add2(&str, TOK_PPSTR, &cval); cstr_free(&cstr); } else { @@ -3478,16 +3828,29 @@ no_subst: } +//#define eputs(s) +//#define eputc(c) + /* return next token with macro substitution */ ST_FUNC void next(void) { + trace_enter ("next"); redo: - if (parse_flags & PARSE_FLAG_SPACES) + trace ("next tok="); eputc (tok); eputs (" ["); eputs (itoa (tok)); eputs ("]\n"); + if (parse_flags & PARSE_FLAG_SPACES) { + trace ("next 01\n"); next_nomacro_spc(); - else + trace ("next 02\n"); + } + else { + trace ("next 03\n"); next_nomacro(); + trace ("next 04\n"); + } + trace ("next 05\n"); if (macro_ptr) { + trace ("next 10\n"); if (tok == TOK_NOSUBST || tok == TOK_PLCHLDR) { /* discard preprocessor markers */ goto redo; @@ -3497,6 +3860,7 @@ ST_FUNC void next(void) goto redo; } } else if (tok >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) { + trace ("next 20\n"); Sym *s; /* if reading from file, try to substitute macros */ s = define_find(tok); @@ -3511,14 +3875,26 @@ ST_FUNC void next(void) } /* convert preprocessor tokens into C tokens */ if (tok == TOK_PPNUM) { - if (parse_flags & PARSE_FLAG_TOK_NUM) + trace ("next 30\n"); + if (parse_flags & PARSE_FLAG_TOK_NUM) { + trace ("next 31\n"); parse_number((char *)tokc.str.data); + trace ("next 32\n"); + } + trace ("next 33\n"); } else if (tok == TOK_PPSTR) { + trace ("next 40\n"); if (parse_flags & PARSE_FLAG_TOK_STR) parse_string((char *)tokc.str.data, tokc.str.size - 1); } + trace_exit ("next"); } +#if !__x86_64__ +#undef eputc +#undef eputs +#endif + /* 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) @@ -3535,7 +3911,9 @@ ST_FUNC void preprocess_start(TCCState *s1) { char *buf; + trace_enter ("preprocess_start"); s1->include_stack_ptr = s1->include_stack; + trace ("preprocess start include_stack_ptr="); eputs (itoa (s1->include_stack_ptr - s1->include_stack)); eputs ("\n"); s1->ifdef_stack_ptr = s1->ifdef_stack; file->ifdef_stack_ptr = s1->ifdef_stack_ptr; pp_once++; @@ -3565,6 +3943,8 @@ ST_FUNC void preprocess_start(TCCState *s1) memcpy(file->buffer, cstr.data, cstr.size); cstr_free(&cstr); } + trace ("preprocess start include_stack_ptr="); eputs (itoa (s1->include_stack_ptr - s1->include_stack)); eputs ("\n"); + trace_exit ("preprocess_start"); } ST_FUNC void tccpp_new(TCCState *s) @@ -3572,9 +3952,12 @@ ST_FUNC void tccpp_new(TCCState *s) int i, c; const char *p, *r; + trace_enter ("tccpp_new"); /* might be used in error() before preprocess_start() */ s->include_stack_ptr = s->include_stack; - + trace ("tccpp_new include_stack="); eputs (itoa (s->include_stack)); eputs ("\n"); + trace ("tccpp_new include_stack_ptr="); eputs (itoa (s->include_stack_ptr - s->include_stack)); eputs ("\n"); + //eputs ("tccpp_new01\n"); /* init isid table */ for(i = CH_EOF; i<128; i++) set_idnum(i, @@ -3582,55 +3965,88 @@ ST_FUNC void tccpp_new(TCCState *s) : isid(i) ? IS_ID : isnum(i) ? IS_NUM : 0); - + //eputs ("tccpp_new02\n"); for(i = 128; i<256; i++) set_idnum(i, IS_ID); + for(i=0;i<256;i++) { + trace ("idnum["); eputs (itoa (i+1)); eputs ("]: "); eputs (itoa (isidnum_table[i])); eputs ("\n"); + } + + //eputs ("tccpp_new03\n"); /* init allocators */ tal_new(&toksym_alloc, TOKSYM_TAL_LIMIT, TOKSYM_TAL_SIZE); + //eputs ("tccpp_new04\n"); tal_new(&tokstr_alloc, TOKSTR_TAL_LIMIT, TOKSTR_TAL_SIZE); + //eputs ("tccpp_new05\n"); tal_new(&cstr_alloc, CSTR_TAL_LIMIT, CSTR_TAL_SIZE); - + //eputs ("tccpp_new06\n"); + //eputs ("tccpp_new06 TOK_HASH_SIZE="); //eputs (itoa (TOK_HASH_SIZE)); //eputs ("\n"); + //eputs ("tccpp_new06 sizeof="); //eputs (itoa (sizeof(TokenSym *))); //eputs ("\n"); + //eputs ("tccpp_new06 count="); //eputs (itoa (TOK_HASH_SIZE * sizeof(TokenSym *))); //eputs ("\n"); + //eputs ("tccpp_new06 hash_ident="); //eputs (itoa (hash_ident)); //eputs ("\n"); memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *)); + //eputs ("tccpp_new07\n"); cstr_new(&cstr_buf); + //eputs ("tccpp_new08\n"); cstr_realloc(&cstr_buf, STRING_MAX_SIZE); + //eputs ("tccpp_new09\n"); tok_str_new(&tokstr_buf); + //eputs ("tccpp_new10\n"); tok_str_realloc(&tokstr_buf, TOKSTR_MAX_SIZE); + //eputs ("tccpp_new11\n"); tok_ident = TOK_IDENT; p = tcc_keywords; while (*p) { + //eputs ("tccpp_new011\n"); + //eputs ("tccpp_new011 p="); //eputs (p); //eputs ("\n"); r = p; while (1) { + //eputs ("tccpp_new111\n"); c = *r++; + //eputs ("tccpp_new211\n"); if (c == '\0') break; } + //eputs ("tccpp_new311\n"); tok_alloc(p, r - p - 1); + //eputs ("tccpp_new411\n"); p = r; + //eputs ("tccpp_new0411 p="); //eputs (p); //eputs ("\n"); } + trace ("tccpp_new include_stack_ptr="); eputs (itoa (s->include_stack_ptr - s->include_stack)); eputs ("\n"); + trace_exit ("tccpp_new"); } ST_FUNC void tccpp_delete(TCCState *s) { int i, n; + //eputs ("tccpp_delete\n"); + /* free -D and compiler defines */ free_defines(NULL); + //eputs ("tccpp_delete 01\n"); /* cleanup from error/setjmp */ while (macro_stack) end_macro(); macro_ptr = NULL; + //eputs ("tccpp_delete 02\n"); while (file) tcc_close(); + //eputs ("tccpp_delete 03\n"); + /* free tokens */ n = tok_ident - TOK_IDENT; for(i = 0; i < n; i++) tal_free(toksym_alloc, table_ident[i]); + //eputs ("tccpp_delete 04\n"); tcc_free(table_ident); + //eputs ("tccpp_delete 05\n"); table_ident = NULL; /* free static buffers */ @@ -3814,6 +4230,7 @@ ST_FUNC int tcc_preprocess(TCCState *s1) pp_line(s1, file, 0); for (;;) { + trace ("preprocess_start tok="); eputc (tok); eputs (" ["); eputs (itoa (tok)); eputs ("\n"); iptr = s1->include_stack_ptr; next(); if (tok == TOK_EOF)