⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcc.c

📁 Tiny C&C++,看看吧,也许用的着
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  TCC - Tiny C Compiler *  *  Copyright (c) 2001-2004 Fabrice Bellard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#define _GNU_SOURCE#include "config.h"#ifdef CONFIG_TCCBOOT#include "tccboot.h"#define CONFIG_TCC_STATIC#else#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <string.h>#include <errno.h>#include <math.h>#include <unistd.h>#include <signal.h>#include <unistd.h>#include <fcntl.h>#include <setjmp.h>#include <time.h>#ifdef WIN32#include <sys/timeb.h>#define CONFIG_TCC_STATIC#endif#ifndef WIN32#include <sys/time.h>#include <sys/ucontext.h>#endif#endif /* !CONFIG_TCCBOOT */#include "elf.h"#include "stab.h"#ifndef CONFIG_TCC_STATIC#include <dlfcn.h>#endif#ifndef O_BINARY#define O_BINARY 0#endif#include "libtcc.h"/* parser debug *///#define PARSE_DEBUG/* preprocessor debug *///#define PP_DEBUG/* include file debug *///#define INC_DEBUG//#define MEM_DEBUG/* assembler debug *///#define ASM_DEBUG/* target selection *///#define TCC_TARGET_I386   /* i386 code generator *///#define TCC_TARGET_ARM    /* ARMv4 code generator *///#define TCC_TARGET_C67    /* TMS320C67xx code generator *//* default target is I386 */#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \    !defined(TCC_TARGET_C67)#define TCC_TARGET_I386#endif#if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \    !defined(TCC_TARGET_C67)#define CONFIG_TCC_BCHECK /* enable bound checking code */#endif/* define it to include assembler support */#if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)#define CONFIG_TCC_ASM#endif/* object format selection */#if defined(TCC_TARGET_C67)#define TCC_TARGET_COFF#endif#define FALSE 0#define false 0#define TRUE 1#define true 1typedef int BOOL;/* path to find crt1.o, crti.o and crtn.o. Only needed when generating   executables or dlls */#define CONFIG_TCC_CRT_PREFIX "/usr/lib"#define INCLUDE_STACK_SIZE  32#define IFDEF_STACK_SIZE    64#define VSTACK_SIZE         256#define STRING_MAX_SIZE     1024#define TOK_HASH_SIZE       8192 /* must be a power of two */#define TOK_ALLOC_INCR      512  /* must be a power of two */#define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string *//* token symbol management */typedef struct TokenSym {    struct TokenSym *hash_next;    struct Sym *sym_define; /* direct pointer to define */    struct Sym *sym_label; /* direct pointer to label */    struct Sym *sym_struct; /* direct pointer to structure */    struct Sym *sym_identifier; /* direct pointer to identifier */    int tok; /* token number */    int len;    char str[1];} TokenSym;typedef struct CString {    int size; /* size in bytes */    void *data; /* either 'char *' or 'int *' */    int size_allocated;    void *data_allocated; /* if non NULL, data has been malloced */} CString;/* type definition */typedef struct CType {    int t;    struct Sym *ref;} CType;/* constant value */typedef union CValue {    long double ld;    double d;    float f;    int i;    unsigned int ui;    unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */    long long ll;    unsigned long long ull;    struct CString *cstr;    void *ptr;    int tab[1];} CValue;/* value on stack */typedef struct SValue {    CType type;      /* type */    unsigned short r;      /* register + flags */    unsigned short r2;     /* second register, used for 'long long'                              type. If not used, set to VT_CONST */    CValue c;              /* constant, if VT_CONST */    struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST) */} SValue;/* symbol management */typedef struct Sym {    int v;    /* symbol token */    int r;    /* associated register */    int c;    /* associated number */    CType type;    /* associated type */    struct Sym *next; /* next related symbol */    struct Sym *prev; /* prev symbol in stack */    struct Sym *prev_tok; /* previous symbol for this token */} Sym;/* section definition *//* XXX: use directly ELF structure for parameters ? *//* special flag to indicate that the section should not be linked to   the other ones */#define SHF_PRIVATE 0x80000000typedef struct Section {    unsigned long data_offset; /* current data offset */    unsigned char *data;       /* section data */    unsigned long data_allocated; /* used for realloc() handling */    int sh_name;             /* elf section name (only used during output) */    int sh_num;              /* elf section number */    int sh_type;             /* elf section type */    int sh_flags;            /* elf section flags */    int sh_info;             /* elf section info */    int sh_addralign;        /* elf section alignment */    int sh_entsize;          /* elf entry size */    unsigned long sh_size;   /* section size (only used during output) */    unsigned long sh_addr;      /* address at which the section is relocated */    unsigned long sh_offset;      /* address at which the section is relocated */    int nb_hashed_syms;      /* used to resize the hash table */    struct Section *link;    /* link to another section */    struct Section *reloc;   /* corresponding section for relocation, if any */    struct Section *hash;     /* hash table for symbols */    struct Section *next;    char name[1];           /* section name */} Section;typedef struct DLLReference {    int level;    char name[1];} DLLReference;/* GNUC attribute definition */typedef struct AttributeDef {    int aligned;    int packed;     Section *section;    unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */} AttributeDef;#define SYM_STRUCT     0x40000000 /* struct/union/enum symbol space */#define SYM_FIELD      0x20000000 /* struct/union field symbol space */#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym *//* stored in 'Sym.c' field */#define FUNC_NEW       1 /* ansi function prototype */#define FUNC_OLD       2 /* old function prototype */#define FUNC_ELLIPSIS  3 /* ansi function prototype with ... *//* stored in 'Sym.r' field */#define FUNC_CDECL     0 /* standard c call */#define FUNC_STDCALL   1 /* pascal c call */#define FUNC_FASTCALL1 2 /* first param in %eax */#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx *//* field 'Sym.t' for macros */#define MACRO_OBJ      0 /* object like macro */#define MACRO_FUNC     1 /* function like macro *//* field 'Sym.r' for C labels */#define LABEL_DEFINED  0 /* label is defined */#define LABEL_FORWARD  1 /* label is forward defined */#define LABEL_DECLARED 2 /* label is declared but never used *//* type_decl() types */#define TYPE_ABSTRACT  1 /* type without variable */#define TYPE_DIRECT    2 /* type with variable */#define IO_BUF_SIZE 8192typedef struct BufferedFile {    uint8_t *buf_ptr;    uint8_t *buf_end;    int fd;    int line_num;    /* current line number - here to simplify code */    int ifndef_macro;  /* #ifndef macro / #endif search */    int ifndef_macro_saved; /* saved ifndef_macro */    int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */    char inc_type;          /* type of include */    char inc_filename[512]; /* filename specified by the user */    char filename[1024];    /* current filename - here to simplify code */    unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */} BufferedFile;#define CH_EOB   '\\'       /* end of buffer or '\0' char in file */#define CH_EOF   (-1)   /* end of file *//* parsing state (used to save parser state to reparse part of the   source several times) */typedef struct ParseState {    int *macro_ptr;    int line_num;    int tok;    CValue tokc;} ParseState;/* used to record tokens */typedef struct TokenString {    int *str;    int len;    int allocated_len;    int last_line_num;} TokenString;/* include file cache, used to find files faster and also to eliminate   inclusion if the include file is protected by #ifndef ... #endif */typedef struct CachedInclude {    int ifndef_macro;    int hash_next; /* -1 if none */    char type; /* '"' or '>' to give include type */    char filename[1]; /* path specified in #include */} CachedInclude;#define CACHED_INCLUDES_HASH_SIZE 512/* parser */static struct BufferedFile *file;static int ch, tok;static CValue tokc;static CString tokcstr; /* current parsed string, if any *//* additional informations about token */static int tok_flags;#define TOK_FLAG_BOL   0x0001 /* beginning of line before */#define TOK_FLAG_BOF   0x0002 /* beginning of file before */#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */static int *macro_ptr, *macro_ptr_allocated;static int *unget_saved_macro_ptr;static int unget_saved_buffer[TOK_MAX_SIZE + 1];static int unget_buffer_enabled;static int parse_flags;#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */#define PARSE_FLAG_TOK_NUM    0x0002 /* return numbers instead of TOK_PPNUM */#define PARSE_FLAG_LINEFEED   0x0004 /* line feed is returned as a                                        token. line feed is also                                        returned at eof */#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */ static Section *text_section, *data_section, *bss_section; /* predefined sections */static Section *cur_text_section; /* current section where function code is                              generated */#ifdef CONFIG_TCC_ASMstatic Section *last_text_section; /* to handle .previous asm directive */#endif/* bound check related sections */static Section *bounds_section; /* contains global data bound description */static Section *lbounds_section; /* contains local data bound description *//* symbol sections */static Section *symtab_section, *strtab_section;/* debug sections */static Section *stab_section, *stabstr_section;/* loc : local variable index   ind : output code index   rsym: return symbol   anon_sym: anonymous symbol index*/static int rsym, anon_sym, ind, loc;/* expression generation modifiers */static int const_wanted; /* true if constant wanted */static int nocode_wanted; /* true if no code generation wanted for an expression */static int global_expr;  /* true if compound literals must be allocated                            globally (used during initializers parsing */static CType func_vt; /* current function return type (used by return                         instruction) */static int func_vc;static int last_line_num, last_ind, func_ind; /* debug last line number and pc */static int tok_ident;static TokenSym **table_ident;static TokenSym *hash_ident[TOK_HASH_SIZE];static char token_buf[STRING_MAX_SIZE + 1];static char *funcname;static Sym *global_stack, *local_stack;static Sym *define_stack;static Sym *global_label_stack, *local_label_stack;/* symbol allocator */#define SYM_POOL_NB (8192 / sizeof(Sym))static Sym *sym_free_first;static SValue vstack[VSTACK_SIZE], *vtop;/* some predefined types */static CType char_pointer_type, func_old_type, int_type;/* true if isid(c) || isnum(c) */static unsigned char isidnum_table[256];/* compile with debug symbol (and use them if error during execution) */static int do_debug = 0;/* compile with built-in memory and bounds checker */static int do_bounds_check = 0;/* display benchmark infos */#if !defined(LIBTCC)static int do_bench = 0;#endifstatic int total_lines;static int total_bytes;/* use GNU C extensions */static int gnu_ext = 1;/* use Tiny C extensions */static int tcc_ext = 1;/* max number of callers shown if error */static int num_callers = 6;static const char **rt_bound_error_msg;/* XXX: get rid of this ASAP */static struct TCCState *tcc_state;/* give the path of the tcc libraries */static const char *tcc_lib_path = CONFIG_TCC_LIBDIR "/tcc";struct TCCState {    int output_type;     BufferedFile **include_stack_ptr;    int *ifdef_stack_ptr;    /* include file handling */    char **include_paths;    int nb_include_paths;    char **sysinclude_paths;    int nb_sysinclude_paths;    CachedInclude **cached_includes;    int nb_cached_includes;    char **library_paths;    int nb_library_paths;    /* array of all loaded dlls (including those referenced by loaded       dlls) */    DLLReference **loaded_dlls;    int nb_loaded_dlls;    /* sections */    Section **sections;    int nb_sections; /* number of sections, including first dummy section */    /* got handling */    Section *got;    Section *plt;    unsigned long *got_offsets;    int nb_got_offsets;    /* give the correspondance from symtab indexes to dynsym indexes */    int *symtab_to_dynsym;    /* temporary dynamic symbol sections (for dll loading) */    Section *dynsymtab_section;    /* exported dynamic symbol section */    Section *dynsym;    int nostdinc; /* if true, no standard headers are added */    int nostdlib; /* if true, no standard libraries are added */    int nocommon; /* if true, do not use common symbols for .bss data */    /* if true, static linking is performed */    int static_link;    /* if true, all symbols are exported */    int rdynamic;    /* if true, only link in referenced objects from archive */    int alacarte_link;    /* address of text section */    unsigned long text_addr;    int has_text_addr;        /* output format, see TCC_OUTPUT_FORMAT_xxx */    int output_format;    /* C language options */    int char_is_unsigned;    /* warning switches */    int warn_write_strings;    int warn_unsupported;    int warn_error;    int warn_none;    int warn_implicit_function_declaration;    /* error handling */    void *error_opaque;    void (*error_func)(void *opaque, const char *msg);    int error_set_jmp_enabled;    jmp_buf error_jmp_buf;    int nb_errors;    /* tiny assembler state */    Sym *asm_labels;    /* see include_stack_ptr */    BufferedFile *include_stack[INCLUDE_STACK_SIZE];    /* see ifdef_stack_ptr */    int ifdef_stack[IFDEF_STACK_SIZE];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -