From b12e91aa01dfc73a23cacae59bdf6967dc63608c Mon Sep 17 00:00:00 2001 From: bellard Date: Wed, 24 Jul 2002 22:10:59 +0000 Subject: [PATCH] fixed command line help - added -B option - moved bcheck.c outside of tcc --- tcc.c | 148 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 110 insertions(+), 38 deletions(-) diff --git a/tcc.c b/tcc.c index 8bfc50b..f37b687 100644 --- a/tcc.c +++ b/tcc.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #ifndef WIN32 @@ -307,6 +306,9 @@ int tcc_ext = 1; /* if true, static linking is performed */ int static_link = 0; +/* give the path of the tcc libraries */ +static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc"; + struct TCCState { int output_type; }; @@ -586,6 +588,8 @@ void type_to_str(char *buf, int buf_size, int t, const char *varstr); char *get_tok_str(int v, CValue *cv); Sym *external_sym(int v, int u, int r); +static Sym *get_sym_ref(int t, Section *sec, + unsigned long offset, unsigned long size); /* section generation */ void put_extern_sym(Sym *sym, Section *section, unsigned long value); @@ -613,10 +617,6 @@ static inline int is_float(int t) return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT; } -#ifdef CONFIG_TCC_BCHECK -#include "bcheck.c" -#endif - #ifdef TCC_TARGET_I386 #include "i386-gen.c" #endif @@ -2494,18 +2494,27 @@ void vpushi(int v) vsetc(VT_INT, VT_CONST, &cval); } -/* push a reference to a section offset by adding a dummy symbol */ -void vpush_ref(int t, Section *sec, unsigned long offset) +/* Return a static symbol pointing to a section */ +static Sym *get_sym_ref(int t, Section *sec, + unsigned long offset, unsigned long size) { int v; Sym *sym; - CValue cval; v = anon_sym++; sym = sym_push1(&global_stack, v, t | VT_STATIC, 0); sym->r = VT_CONST | VT_SYM; put_extern_sym(sym, sec, offset); - cval.sym = sym; + return sym; +} + +/* push a reference to a section offset by adding a dummy symbol */ +/* XXX: add size */ +void vpush_ref(int t, Section *sec, unsigned long offset) +{ + CValue cval; + + cval.sym = get_sym_ref(t, sec, offset, 0); vsetc(t, VT_CONST | VT_SYM, &cval); } @@ -6397,7 +6406,8 @@ void put_extern_sym(Sym *sym, Section *section, unsigned long value) int sym_type, sym_bind, sh_num, info; Elf32_Sym *esym; const char *name; - + char buf[32]; + if (section) sh_num = section->sh_num; else @@ -6411,7 +6421,30 @@ void put_extern_sym(Sym *sym, Section *section, unsigned long value) sym_bind = STB_LOCAL; else sym_bind = STB_GLOBAL; + name = get_tok_str(sym->v, NULL); +#ifdef CONFIG_TCC_BCHECK + if (do_bounds_check) { + /* if bound checking is activated, we change some function + names by adding the "__bound" prefix */ + switch(sym->v) { + case TOK_malloc: + case TOK_free: + case TOK_realloc: + case TOK_memalign: + case TOK_calloc: + case TOK_memcpy: + case TOK_memmove: + case TOK_memset: + case TOK_strlen: + case TOK_strcpy: + strcpy(buf, "__bound_"); + strcat(buf, name); + name = buf; + break; + } + } +#endif info = ELF32_ST_INFO(sym_bind, sym_type); sym->c = add_elf_sym(symtab_section, value, 0, info, sh_num, name); } else { @@ -6576,14 +6609,6 @@ static void relocate_common_syms(void) static void *resolve_sym(const char *sym) { -#ifdef CONFIG_TCC_BCHECK - if (do_bounds_check) { - void *ptr; - ptr = bound_resolve_sym(sym); - if (ptr) - return ptr; - } -#endif return dlsym(NULL, sym); } @@ -6867,7 +6892,44 @@ static void put_dt(Section *dynamic, int dt, unsigned long val) /* add tcc runtime libraries */ static void tcc_add_runtime(TCCState *s1) { - tcc_add_file(s1, CONFIG_TCC_PREFIX "/lib/tcc/libtcc1.o"); + char buf[1024]; + + snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.o"); + tcc_add_file(s1, buf); +#ifdef CONFIG_TCC_BCHECK + if (do_bounds_check) { + /* XXX: add an object file to do that */ + *(int *)bounds_section->data_ptr = 0; + bounds_section->data_ptr += sizeof(int); + add_elf_sym(symtab_section, 0, 0, + ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), + bounds_section->sh_num, "__bounds_start"); + add_elf_sym(symtab_section, (long)&rt_error, 0, + ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), + SHN_ABS, "rt_error"); + /* add bound check code */ + snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o"); + tcc_add_file(s1, buf); + } +#endif + /* add libc if not memory output */ + if (s1->output_type != TCC_OUTPUT_MEMORY) { + tcc_add_library(s1, "c"); + tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o"); + } + /* add various standard linker symbols */ + add_elf_sym(symtab_section, + text_section->data_ptr - text_section->data, 0, + ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), + text_section->sh_num, "_etext"); + add_elf_sym(symtab_section, + data_section->data_ptr - data_section->data, 0, + ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), + data_section->sh_num, "_edata"); + add_elf_sym(symtab_section, + bss_section->data_ptr - bss_section->data, 0, + ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), + bss_section->sh_num, "_end"); } /* add dynamic sections so that the executable is dynamically linked */ @@ -6898,12 +6960,8 @@ int tcc_output_file(TCCState *s1, const char *filename) file_type = s1->output_type; - /* add libc crtn object */ - if (file_type != TCC_OUTPUT_OBJ) { + if (file_type != TCC_OUTPUT_OBJ) tcc_add_runtime(s1); - tcc_add_library(s1, "c"); - tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o"); - } interp = NULL; dynamic = NULL; @@ -8012,6 +8070,7 @@ int tcc_run(TCCState *s1, int argc, char **argv) { Section *s; int (*prog_main)(int, char **); + void (*bound_init)(void); int i; tcc_add_runtime(s1); @@ -8056,18 +8115,11 @@ int tcc_run(TCCState *s1, int argc, char **argv) #ifdef CONFIG_TCC_BCHECK if (do_bounds_check) { - int *p, *p_end; - __bound_init(); - /* add all known static regions */ - p = (int *)bounds_section->data; - p_end = (int *)bounds_section->data_ptr; - while (p < p_end) { - __bound_new_region((void *)p[0], p[1]); - p += 2; - } + /* XXX: use .init section so that it also work in binary ? */ + bound_init = (void *)get_elf_sym_val("__bound_init"); + bound_init(); } #endif - return (*prog_main)(argc, argv); } @@ -8283,6 +8335,14 @@ int tcc_add_library(TCCState *s, const char *libraryname) return -1; } +int tcc_add_symbol(TCCState *s, const char *name, unsigned long val) +{ + add_elf_sym(symtab_section, val, 0, + ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), + SHN_ABS, name); + return 0; +} + int tcc_set_output_type(TCCState *s, int output_type) { s->output_type = output_type; @@ -8302,16 +8362,17 @@ int tcc_set_output_type(TCCState *s, int output_type) void help(void) { printf("tcc version 0.9.8 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n" - "usage: tcc [-c] [-o outfile] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n" + "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n" " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n" " [--] infile1 [infile2... --] [infile_args...]\n" "\n" "General options:\n" " -c compile only - generate an object file\n" - " -o outfile set output filename (NOT WORKING YET)\n" - " -bench output compilation statistics\n" + " -o outfile set output filename\n" " -- allows multiples input files if no -o option given. Also\n" " separate input files from runtime arguments\n" + " -Bdir set tcc internal library path\n" + " -bench output compilation statistics\n" "Preprocessor options:\n" " -Idir add include path 'dir'\n" " -Dsym[=val] define 'sym' with value 'val'\n" @@ -8325,7 +8386,7 @@ void help(void) " -Ldir add library path 'dir'\n" " -llib link with dynamic library 'lib'\n" " -shared generate a shared library (NOT WORKING YET)\n" - " -static static linking (NOT WORKING YET)\n" + " -static static linking\n" ); } @@ -8376,6 +8437,9 @@ int main(int argc, char **argv) tcc_undefine_symbol(s, r + 2); } else if (r[1] == 'L') { tcc_add_library_path(s, r + 2); + } else if (r[1] == 'B') { + /* set tcc utilities path (mainly for tcc development) */ + tcc_lib_path = r + 2; } else if (r[1] == 'l') { dynarray_add((void ***)&libraries, &nb_libraries, r + 2); } else if (!strcmp(r + 1, "bench")) { @@ -8436,6 +8500,14 @@ int main(int argc, char **argv) if (outfile && output_type == TCC_OUTPUT_MEMORY) output_type = TCC_OUTPUT_EXE; + /* warning if not supported features */ + if (output_type == TCC_OUTPUT_DLL) + warning("dll output is currently not supported"); +#ifdef CONFIG_TCC_BCHECK + if (do_bounds_check && output_type != TCC_OUTPUT_MEMORY) + warning("bounds checking is currently only supported for in-memory execution"); +#endif + tcc_set_output_type(s, output_type); tcc_add_file(s, argv[optind]);