From 9c06595a1e83aba45c757df3c232b3dc42aa0214 Mon Sep 17 00:00:00 2001 From: bellard Date: Sat, 12 Jan 2002 16:39:35 +0000 Subject: [PATCH] win32 defines + new internal file layer --- bcheck.c | 19 ++-- tcc.c | 262 ++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 193 insertions(+), 88 deletions(-) diff --git a/bcheck.c b/bcheck.c index f4351cf5..eff0525e 100644 --- a/bcheck.c +++ b/bcheck.c @@ -80,10 +80,12 @@ static void libc_free(void *ptr); static void install_malloc_hooks(void); static void restore_malloc_hooks(void); +#ifndef WIN32 static void *saved_malloc_hook; static void *saved_free_hook; static void *saved_realloc_hook; static void *saved_memalign_hook; +#endif extern char _end; @@ -123,8 +125,7 @@ static BoundEntry *__bound_find_region(BoundEntry *e1, void *p) return __bound_empty_t2; } -/* print a bound error and recurse thru 'nb_callers' to get the error - position */ +/* print a bound error message */ static void bound_error(const void *caller, const char *fmt, ...) { rt_error((unsigned long)caller, "%s", fmt); @@ -132,7 +133,7 @@ static void bound_error(const void *caller, const char *fmt, ...) static void bound_alloc_error(void) { - bound_error(NULL, "not enough memory for bound checking code\n"); + bound_error(NULL, "not enough memory for bound checking code"); } /* currently, tcc cannot compile that because we use GNUC extensions */ @@ -406,7 +407,7 @@ void __bound_init(void) size = BOUND_T23_SIZE; mark_invalid(start, size); -#if !defined(__TINYC__) +#if !defined(__TINYC__) && !defined(WIN32) /* malloc zone is also marked invalid */ start = (unsigned long)&_end; size = 128 * 0x100000; @@ -641,6 +642,7 @@ static unsigned long get_region_size(void *p) static void install_malloc_hooks(void) { +#ifndef WIN32 saved_malloc_hook = __malloc_hook; saved_free_hook = __free_hook; saved_realloc_hook = __realloc_hook; @@ -649,14 +651,17 @@ static void install_malloc_hooks(void) __free_hook = __bound_free; __realloc_hook = __bound_realloc; __memalign_hook = __bound_memalign; +#endif } static void restore_malloc_hooks(void) { +#ifndef WIN32 __malloc_hook = saved_malloc_hook; __free_hook = saved_free_hook; __realloc_hook = saved_realloc_hook; __memalign_hook = saved_memalign_hook; +#endif } static void *libc_malloc(size_t size) @@ -693,6 +698,7 @@ void *__bound_malloc(size_t size, const void *caller) return ptr; } +#ifndef WIN32 void *__bound_memalign(size_t size, size_t align, const void *caller) { void *ptr; @@ -711,6 +717,7 @@ void *__bound_memalign(size_t size, size_t align, const void *caller) __bound_new_region(ptr, size); return ptr; } +#endif void __bound_free(void *ptr, const void *caller) { @@ -773,7 +780,7 @@ static void bound_dump(void) /* some useful checked functions */ /* check that (p ... p + size - 1) lies inside 'p' region, if any */ -static void __bound_check(const void *p, ssize_t size) +static void __bound_check(const void *p, size_t size) { if (size == 0) return; @@ -805,7 +812,7 @@ void *__bound_memset(void *dst, int c, size_t size) return memset(dst, c, size); } -/* resolve check check syms */ +/* resolve bound check syms */ typedef struct BCSyms { char *str; void *ptr; diff --git a/tcc.c b/tcc.c index 21ad98b0..93c0c598 100644 --- a/tcc.c +++ b/tcc.c @@ -25,11 +25,15 @@ #include #include #include +#include +#include +#include +#ifndef WIN32 #include #include -#include -#include -#include +#endif +#include "elf.h" +#include "stab.h" #ifndef CONFIG_TCC_STATIC #include #endif @@ -145,15 +149,22 @@ typedef struct AttributeDef { #define TYPE_ABSTRACT 1 /* type without variable */ #define TYPE_DIRECT 2 /* type with variable */ -typedef struct { - FILE *file; - char *filename; - int line_num; -} IncludeFile; +#define IO_BUF_SIZE 8192 + +typedef struct BufferedFile { + unsigned char *buf_ptr; + unsigned char *buf_end; + int fd; + int line_num; /* current line number - here to simply code */ + char filename[1024]; /* current filename - here to simply code */ + unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */ +} BufferedFile; + +#define CH_EOB 0 /* end of buffer or '\0' char in file */ +#define CH_EOF (-1) /* end of file */ /* parser */ -FILE *file; -int line_num; +struct BufferedFile *file; int ch, ch1, tok, tok1; CValue tokc, tok1c; @@ -185,14 +196,14 @@ int tok_ident; TokenSym **table_ident; TokenSym *hash_ident[TOK_HASH_SIZE]; char token_buf[STRING_MAX_SIZE + 1]; -char *filename, *funcname; +char *funcname; /* contains global symbols which remain between each translation unit */ SymStack extern_stack; SymStack define_stack, global_stack, local_stack, label_stack; SValue vstack[VSTACK_SIZE], *vtop; int *macro_ptr, *macro_ptr_allocated; -IncludeFile include_stack[INCLUDE_STACK_SIZE], *include_stack_ptr; +BufferedFile *include_stack[INCLUDE_STACK_SIZE], **include_stack_ptr; int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr; char *include_paths[INCLUDE_PATHS_MAX]; int nb_include_paths; @@ -316,6 +327,8 @@ int tcc_ext = 1; #define TOK_A_SHL 0x81 #define TOK_A_SAR 0x82 +#define TOK_EOF (-1) /* end of file */ + /* all identificators and strings have token above that */ #define TOK_IDENT 256 @@ -344,8 +357,10 @@ enum { TOK_LONG, TOK_REGISTER, TOK_SIGNED, + TOK___SIGNED__, /* gcc keyword */ TOK_AUTO, TOK_INLINE, + TOK___INLINE__, /* gcc keyword */ TOK_RESTRICT, /* unsupported type */ @@ -392,9 +407,22 @@ enum { TOK___UNUSED__, }; +#ifdef WIN32 +#define snprintf _snprintf +/* currently incorrect */ +long double strtold(const char *nptr, char **endptr) +{ + return (long double)strtod(nptr, endptr); +} +float strtof(const char *nptr, char **endptr) +{ + return (float)strtod(nptr, endptr); +} +#else /* XXX: need to define this to use them in non ISOC99 context */ extern float strtof (const char *__nptr, char **__endptr); extern long double strtold (const char *__nptr, char **__endptr); +#endif void sum(int l); void next(void); @@ -495,7 +523,7 @@ static TCCSyms tcc_syms[] = { { NULL, NULL }, }; -void *dlsym(void *handle, char *symbol) +void *dlsym(void *handle, const char *symbol) { TCCSyms *p; p = tcc_syms; @@ -582,25 +610,27 @@ unsigned long long __ldtoull(long double a) /********************************************************/ -/* copy a string and truncate it */ +/* copy a string and truncate it. */ char *pstrcpy(char *buf, int buf_size, const char *s) { char *q, *q_end; int c; - q = buf; - q_end = buf + buf_size - 1; - while (q < q_end) { - c = *s++; - if (c == '\0') - break; - *q++ = c; + if (buf_size > 0) { + q = buf; + q_end = buf + buf_size - 1; + while (q < q_end) { + c = *s++; + if (c == '\0') + break; + *q++ = c; + } + *q = '\0'; } - *q = '\0'; return buf; } -/* strcat and truncate */ +/* strcat and truncate. */ char *pstrcat(char *buf, int buf_size, const char *s) { int len; @@ -624,12 +654,19 @@ Section *new_section(const char *name, int sh_type, int sh_flags) sec->sh_num = ++section_num; sec->sh_type = sh_type; sec->sh_flags = sh_flags; +#ifdef WIN32 + /* XXX: currently, a single malloc */ + data = malloc(SECTION_VSIZE); + if (data == NULL) + error("could not alloc section '%s'", name); +#else data = mmap(NULL, SECTION_VSIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (data == (void *)(-1)) error("could not mmap section '%s'", name); +#endif sec->data = data; sec->data_ptr = data; psec = &first_section; @@ -706,11 +743,11 @@ static inline int toup(int c) void printline(void) { - IncludeFile *f; + BufferedFile **f; for(f = include_stack; f < include_stack_ptr; f++) fprintf(stderr, "In file included from %s:%d:\n", - f->filename, f->line_num); - fprintf(stderr, "%s:%d: ", filename, line_num); + (*f)->filename, (*f)->line_num); + fprintf(stderr, "%s:%d: ", file->filename, file->line_num); } void error(const char *fmt, ...) @@ -976,39 +1013,94 @@ void sym_undef(SymStack *st, Sym *s) s->v = 0; } -/* no need to put that inline */ -int handle_eof(void) +/* I/O layer */ + +BufferedFile *tcc_open(const char *filename) { - if (include_stack_ptr == include_stack) - return -1; - /* add end of include file debug info */ - if (do_debug) { - put_stabd(N_EINCL, 0, 0); + int fd; + BufferedFile *bf; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return NULL; + bf = malloc(sizeof(BufferedFile)); + if (!bf) { + close(fd); + return NULL; + } + bf->fd = fd; + bf->buf_ptr = bf->buffer; + bf->buf_end = bf->buffer; + bf->buffer[0] = CH_EOB; /* put eob symbol */ + pstrcpy(bf->filename, sizeof(bf->filename), filename); + bf->line_num = 1; + return bf; +} + +void tcc_close(BufferedFile *bf) +{ + close(bf->fd); + free(bf); +} + +/* read one char. MUST call tcc_fillbuf if CH_EOB is read */ +#define TCC_GETC(bf) (*(bf)->buf_ptr++) + +/* fill input buffer and return next char */ +int tcc_getc_slow(BufferedFile *bf) +{ + int len; + /* only tries to read if really end of buffer */ + if (bf->buf_ptr >= bf->buf_end) { + if (bf->fd != -1) { + len = read(bf->fd, bf->buffer, IO_BUF_SIZE); + if (len < 0) + len = 0; + } else { + len = 0; + } + bf->buf_ptr = bf->buffer; + bf->buf_end = bf->buffer + len; + *bf->buf_end = CH_EOB; + } + if (bf->buf_ptr < bf->buf_end) { + return *bf->buf_ptr++; + } else { + bf->buf_ptr = bf->buf_end; + return CH_EOF; + } +} + +/* no need to put that inline */ +void handle_eob(void) +{ + for(;;) { + ch1 = tcc_getc_slow(file); + if (ch1 != CH_EOF) + return; + + if (include_stack_ptr == include_stack) + return; + /* add end of include file debug info */ + if (do_debug) { + put_stabd(N_EINCL, 0, 0); + } + /* pop include stack */ + tcc_close(file); + include_stack_ptr--; + file = *include_stack_ptr; } - /* pop include stack */ - fclose(file); - free(filename); - include_stack_ptr--; - file = include_stack_ptr->file; - filename = include_stack_ptr->filename; - line_num = include_stack_ptr->line_num; - return 0; } /* read next char from current input file */ static inline void inp(void) { - redo: - /* faster than fgetc */ - ch1 = getc_unlocked(file); - if (ch1 == -1) { - if (handle_eof() < 0) - return; - else - goto redo; - } + ch1 = TCC_GETC(file); + /* end of buffer/file handling */ + if (ch1 == CH_EOB) + handle_eob(); if (ch1 == '\n') - line_num++; + file->line_num++; // printf("ch1=%c 0x%x\n", ch1, ch1); } @@ -1219,7 +1311,7 @@ void preprocess(void) int size, i, c, v, t, *str, len; char buf[1024], *q, *p; char buf1[1024]; - FILE *f; + BufferedFile *f; Sym **ps, *first, *s; cinp(); @@ -1304,15 +1396,15 @@ void preprocess(void) if (c == '\"') { /* first search in current dir if "header.h" */ size = 0; - p = strrchr(filename, '/'); + p = strrchr(file->filename, '/'); if (p) - size = p + 1 - filename; + size = p + 1 - file->filename; if (size > sizeof(buf1) - 1) size = sizeof(buf1) - 1; - memcpy(buf1, filename, size); + memcpy(buf1, file->filename, size); buf1[size] = '\0'; pstrcat(buf1, sizeof(buf1), buf); - f = fopen(buf1, "r"); + f = tcc_open(buf1); if (f) goto found; } @@ -1321,7 +1413,7 @@ void preprocess(void) strcpy(buf1, include_paths[i]); strcat(buf1, "/"); strcat(buf1, buf); - f = fopen(buf1, "r"); + f = tcc_open(buf1); if (f) goto found; } @@ -1330,16 +1422,11 @@ void preprocess(void) found: /* push current file in stack */ /* XXX: fix current line init */ - include_stack_ptr->file = file; - include_stack_ptr->filename = filename; - include_stack_ptr->line_num = line_num; - include_stack_ptr++; + *include_stack_ptr++ = file; file = f; - filename = strdup(buf1); - line_num = 1; /* add include file debug info */ if (do_debug) { - put_stabs(filename, N_BINCL, 0, 0, 0); + put_stabs(file->filename, N_BINCL, 0, 0, 0); } } else if (tok == TOK_IFNDEF) { c = 1; @@ -1382,14 +1469,14 @@ void preprocess(void) next(); if (tok != TOK_CINT) error("#line"); - line_num = tokc.i; + file->line_num = tokc.i; skip_spaces(); if (ch != '\n') { next(); if (tok != TOK_STR) error("#line"); - /* XXX: potential memory leak */ - filename = strdup(get_tok_str(tok, &tokc)); + pstrcpy(file->filename, sizeof(file->filename), + get_tok_str(tok, &tokc)); } } else if (tok == TOK_ERROR) { error("#error"); @@ -2025,10 +2112,10 @@ void macro_subst(int **tok_str, int *tok_len, break; /* special macros */ if (tok == TOK___LINE__) { - cval.i = line_num; + cval.i = file->line_num; tok_add2(tok_str, tok_len, TOK_CINT, &cval); } else if (tok == TOK___FILE__) { - cval.ts = tok_alloc(filename, 0); + cval.ts = tok_alloc(file->filename, 0); tok_add2(tok_str, tok_len, TOK_STR, &cval); } else if (tok == TOK___DATE__) { cval.ts = tok_alloc("Jan 1 1970", 0); @@ -3912,8 +3999,10 @@ int parse_btype(int *type_ptr, AttributeDef *ad) case TOK_VOLATILE: case TOK_REGISTER: case TOK_SIGNED: + case TOK___SIGNED__: case TOK_AUTO: case TOK_INLINE: + case TOK___INLINE__: case TOK_RESTRICT: next(); break; @@ -4665,10 +4754,10 @@ void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg) /* generate line number info */ if (do_debug && - (last_line_num != line_num || last_ind != ind)) { - put_stabn(N_SLINE, 0, line_num, ind - func_ind); + (last_line_num != file->line_num || last_ind != ind)) { + put_stabn(N_SLINE, 0, file->line_num, ind - func_ind); last_ind = ind; - last_line_num = line_num; + last_line_num = file->line_num; } if (tok == TOK_IF) { @@ -5339,7 +5428,7 @@ void put_func_debug(int t) /* XXX: we put here a dummy type */ snprintf(buf, sizeof(buf), "%s:%c1", funcname, t & VT_STATIC ? 'f' : 'F'); - put_stabs(buf, N_FUN, 0, line_num, ind); + put_stabs(buf, N_FUN, 0, file->line_num, ind); func_ind = ind; last_ind = 0; last_line_num = 0; @@ -5533,13 +5622,11 @@ int tcc_compile_file(const char *filename1) Sym *define_start; char buf[512]; - line_num = 1; funcname = ""; - filename = (char *)filename1; - file = fopen(filename, "r"); + file = tcc_open(filename1); if (!file) - error("file '%s' not found", filename); + error("file '%s' not found", filename1); include_stack_ptr = include_stack; ifdef_stack_ptr = ifdef_stack; @@ -5551,7 +5638,8 @@ int tcc_compile_file(const char *filename1) getcwd(buf, sizeof(buf)); pstrcat(buf, sizeof(buf), "/"); put_stabs(buf, N_SO, 0, 0, (unsigned long)text_section->data_ptr); - put_stabs(filename, N_SO, 0, 0, (unsigned long)text_section->data_ptr); + put_stabs(file->filename, N_SO, 0, 0, + (unsigned long)text_section->data_ptr); } /* define common 'char *' type because it is often used internally for arrays and struct dereference */ @@ -5564,7 +5652,7 @@ int tcc_compile_file(const char *filename1) decl(VT_CONST); if (tok != -1) expect("declaration"); - fclose(file); + tcc_close(file); /* end of translation unit info */ if (do_debug) { @@ -5993,6 +6081,7 @@ void rt_error(unsigned long pc, const char *fmt, ...) va_end(ap); } +#ifndef WIN32 /* signal handler for fatal errors */ static void sig_error(int signum, siginfo_t *siginf, void *puc) { @@ -6033,19 +6122,23 @@ static void sig_error(int signum, siginfo_t *siginf, void *puc) } exit(255); } +#endif /* launch the compiled program with the given arguments */ int launch_exe(int argc, char **argv) { Sym *s; int (*t)(); - struct sigaction sigact; s = sym_find1(&extern_stack, TOK_MAIN); if (!s || (s->r & VT_FORWARD)) error("main() not defined"); if (do_debug) { +#ifdef WIN32 + error("debug mode currently not available for Windows"); +#else + struct sigaction sigact; /* install TCC signal handlers to print debug info on fatal runtime errors */ sigact.sa_flags = SA_SIGINFO | SA_ONESHOT; @@ -6056,9 +6149,13 @@ int launch_exe(int argc, char **argv) sigaction(SIGSEGV, &sigact, NULL); sigaction(SIGBUS, &sigact, NULL); sigaction(SIGABRT, &sigact, NULL); +#endif } if (do_bounds_check) { +#ifdef WIN32 + error("bound checking currently not available for Windows"); +#else int *p, *p_end; __bound_init(); /* add all known static regions */ @@ -6068,6 +6165,7 @@ int launch_exe(int argc, char **argv) __bound_new_region((void *)p[0], p[1]); p += 2; } +#endif } t = (int (*)())s->c; @@ -6077,7 +6175,7 @@ int launch_exe(int argc, char **argv) void help(void) { - printf("tcc version 0.9.3 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n" + printf("tcc version 0.9.4 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n" "usage: tcc [-Idir] [-Dsym[=val]] [-Usym] [-llib] [-g] [-b]\n" " [-i infile] infile [infile_args...]\n" "\n" @@ -6103,7 +6201,7 @@ int main(int argc, char **argv) /* add all tokens */ tok_ident = TOK_IDENT; - p = "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0register\0signed\0auto\0inline\0restrict\0float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0sizeof\0__attribute__\0define\0include\0ifdef\0ifndef\0elif\0endif\0defined\0undef\0error\0line\0__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0__func__\0main\0section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0"; + p = "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0sizeof\0__attribute__\0define\0include\0ifdef\0ifndef\0elif\0endif\0defined\0undef\0error\0line\0__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0__func__\0main\0section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0"; while (*p) { r = p; while (*r++);