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

📄 tcc.c

📁 Tiny C&C++,看看吧,也许用的着
💻 C
📖 第 1 页 / 共 5 页
字号:
        q++;    }    if (ptr)        *ptr = p;    return 1;}/* memory management */#ifdef MEM_DEBUGint mem_cur_size;int mem_max_size;#endifstatic inline void tcc_free(void *ptr){#ifdef MEM_DEBUG    mem_cur_size -= malloc_usable_size(ptr);#endif    free(ptr);}static void *tcc_malloc(unsigned long size){    void *ptr;    ptr = malloc(size);    if (!ptr && size)        error("memory full");#ifdef MEM_DEBUG    mem_cur_size += malloc_usable_size(ptr);    if (mem_cur_size > mem_max_size)        mem_max_size = mem_cur_size;#endif    return ptr;}static void *tcc_mallocz(unsigned long size){    void *ptr;    ptr = tcc_malloc(size);    memset(ptr, 0, size);    return ptr;}static inline void *tcc_realloc(void *ptr, unsigned long size){    void *ptr1;#ifdef MEM_DEBUG    mem_cur_size -= malloc_usable_size(ptr);#endif    ptr1 = realloc(ptr, size);#ifdef MEM_DEBUG    /* NOTE: count not correct if alloc error, but not critical */    mem_cur_size += malloc_usable_size(ptr1);    if (mem_cur_size > mem_max_size)        mem_max_size = mem_cur_size;#endif    return ptr1;}static char *tcc_strdup(const char *str){    char *ptr;    ptr = tcc_malloc(strlen(str) + 1);    strcpy(ptr, str);    return ptr;}#define free(p) use_tcc_free(p)#define malloc(s) use_tcc_malloc(s)#define realloc(p, s) use_tcc_realloc(p, s)static void dynarray_add(void ***ptab, int *nb_ptr, void *data){    int nb, nb_alloc;    void **pp;        nb = *nb_ptr;    pp = *ptab;    /* every power of two we double array size */    if ((nb & (nb - 1)) == 0) {        if (!nb)            nb_alloc = 1;        else            nb_alloc = nb * 2;        pp = tcc_realloc(pp, nb_alloc * sizeof(void *));        if (!pp)            error("memory full");        *ptab = pp;    }    pp[nb++] = data;    *nb_ptr = nb;}/* symbol allocator */static Sym *__sym_malloc(void){    Sym *sym_pool, *sym, *last_sym;    int i;    sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));    last_sym = sym_free_first;    sym = sym_pool;    for(i = 0; i < SYM_POOL_NB; i++) {        sym->next = last_sym;        last_sym = sym;        sym++;    }    sym_free_first = last_sym;    return last_sym;}static inline Sym *sym_malloc(void){    Sym *sym;    sym = sym_free_first;    if (!sym)        sym = __sym_malloc();    sym_free_first = sym->next;    return sym;}static inline void sym_free(Sym *sym){    sym->next = sym_free_first;    sym_free_first = sym;}Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags){    Section *sec;    sec = tcc_mallocz(sizeof(Section) + strlen(name));    strcpy(sec->name, name);    sec->sh_type = sh_type;    sec->sh_flags = sh_flags;    switch(sh_type) {    case SHT_HASH:    case SHT_REL:    case SHT_DYNSYM:    case SHT_SYMTAB:    case SHT_DYNAMIC:        sec->sh_addralign = 4;        break;    case SHT_STRTAB:        sec->sh_addralign = 1;        break;    default:        sec->sh_addralign = 32; /* default conservative alignment */        break;    }    /* only add section if not private */    if (!(sh_flags & SHF_PRIVATE)) {        sec->sh_num = s1->nb_sections;        dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);    }    return sec;}static void free_section(Section *s){    tcc_free(s->data);    tcc_free(s);}/* realloc section and set its content to zero */static void section_realloc(Section *sec, unsigned long new_size){    unsigned long size;    unsigned char *data;        size = sec->data_allocated;    if (size == 0)        size = 1;    while (size < new_size)        size = size * 2;    data = tcc_realloc(sec->data, size);    if (!data)        error("memory full");    memset(data + sec->data_allocated, 0, size - sec->data_allocated);    sec->data = data;    sec->data_allocated = size;}/* reserve at least 'size' bytes in section 'sec' from   sec->data_offset. */static void *section_ptr_add(Section *sec, unsigned long size){    unsigned long offset, offset1;    offset = sec->data_offset;    offset1 = offset + size;    if (offset1 > sec->data_allocated)        section_realloc(sec, offset1);    sec->data_offset = offset1;    return sec->data + offset;}/* return a reference to a section, and create it if it does not   exists */Section *find_section(TCCState *s1, const char *name){    Section *sec;    int i;    for(i = 1; i < s1->nb_sections; i++) {        sec = s1->sections[i];        if (!strcmp(name, sec->name))             return sec;    }    /* sections are created as PROGBITS */    return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);}#define SECTION_ABS ((void *)1)/* update sym->c so that it points to an external symbol in section   'section' with value 'value' */static void put_extern_sym(Sym *sym, Section *section,                            unsigned long value, unsigned long size){    int sym_type, sym_bind, sh_num, info;    Elf32_Sym *esym;    const char *name;    if (section == NULL)        sh_num = SHN_UNDEF;    else if (section == SECTION_ABS)         sh_num = SHN_ABS;    else        sh_num = section->sh_num;    if (!sym->c) {        if ((sym->type.t & VT_BTYPE) == VT_FUNC)            sym_type = STT_FUNC;        else            sym_type = STT_OBJECT;        if (sym->type.t & VT_STATIC)            sym_bind = STB_LOCAL;        else            sym_bind = STB_GLOBAL;                name = get_tok_str(sym->v, NULL);#ifdef CONFIG_TCC_BCHECK        if (do_bounds_check) {            char buf[32];            /* XXX: avoid doing that for statics ? */            /* if bound checking is activated, we change some function               names by adding the "__bound" prefix */            switch(sym->v) {#if 0            /* XXX: we rely only on malloc hooks */            case TOK_malloc:             case TOK_free:             case TOK_realloc:             case TOK_memalign:             case TOK_calloc: #endif            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, size, info, sh_num, name);    } else {        esym = &((Elf32_Sym *)symtab_section->data)[sym->c];        esym->st_value = value;        esym->st_size = size;        esym->st_shndx = sh_num;    }}/* add a new relocation entry to symbol 'sym' in section 's' */static void greloc(Section *s, Sym *sym, unsigned long offset, int type){    if (!sym->c)         put_extern_sym(sym, NULL, 0, 0);    /* now we can add ELF relocation info */    put_elf_reloc(symtab_section, s, offset, type, sym->c);}static inline int isid(int c){    return (c >= 'a' && c <= 'z') ||        (c >= 'A' && c <= 'Z') ||        c == '_';}static inline int isnum(int c){    return c >= '0' && c <= '9';}static inline int isoct(int c){    return c >= '0' && c <= '7';}static inline int toup(int c){    if (c >= 'a' && c <= 'z')        return c - 'a' + 'A';    else        return c;}static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap){    int len;    len = strlen(buf);    vsnprintf(buf + len, buf_size - len, fmt, ap);}static void strcat_printf(char *buf, int buf_size, const char *fmt, ...){    va_list ap;    va_start(ap, fmt);    strcat_vprintf(buf, buf_size, fmt, ap);    va_end(ap);}void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap){    char buf[2048];    BufferedFile **f;        buf[0] = '\0';    if (file) {        for(f = s1->include_stack; f < s1->include_stack_ptr; f++)            strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",                           (*f)->filename, (*f)->line_num);        if (file->line_num > 0) {            strcat_printf(buf, sizeof(buf),                           "%s:%d: ", file->filename, file->line_num);        } else {            strcat_printf(buf, sizeof(buf),                          "%s: ", file->filename);        }    } else {        strcat_printf(buf, sizeof(buf),                      "tcc: ");    }    if (is_warning)        strcat_printf(buf, sizeof(buf), "warning: ");    strcat_vprintf(buf, sizeof(buf), fmt, ap);    if (!s1->error_func) {        /* default case: stderr */        fprintf(stderr, "%s\n", buf);    } else {        s1->error_func(s1->error_opaque, buf);    }    if (!is_warning || s1->warn_error)        s1->nb_errors++;}#ifdef LIBTCCvoid tcc_set_error_func(TCCState *s, void *error_opaque,                        void (*error_func)(void *opaque, const char *msg)){    s->error_opaque = error_opaque;    s->error_func = error_func;}#endif/* error without aborting current compilation */void error_noabort(const char *fmt, ...){    TCCState *s1 = tcc_state;    va_list ap;    va_start(ap, fmt);    error1(s1, 0, fmt, ap);    va_end(ap);}void error(const char *fmt, ...){    TCCState *s1 = tcc_state;    va_list ap;    va_start(ap, fmt);    error1(s1, 0, fmt, ap);    va_end(ap);    /* better than nothing: in some cases, we accept to handle errors */    if (s1->error_set_jmp_enabled) {        longjmp(s1->error_jmp_buf, 1);    } else {        /* XXX: eliminate this someday */        exit(1);    }}void expect(const char *msg){    error("%s expected", msg);}void warning(const char *fmt, ...){    TCCState *s1 = tcc_state;    va_list ap;    if (s1->warn_none)        return;    va_start(ap, fmt);    error1(s1, 1, fmt, ap);    va_end(ap);}void skip(int c){    if (tok != c)        error("'%c' expected", c);    next();}static void test_lvalue(void){    if (!(vtop->r & VT_LVAL))        expect("lvalue");}/* allocate a new token */static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len){    TokenSym *ts, **ptable;    int i;    if (tok_ident >= SYM_FIRST_ANOM)         error("memory full");    /* expand token table if needed */    i = tok_ident - TOK_IDENT;    if ((i % TOK_ALLOC_INCR) == 0) {        ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));        if (!ptable)            error("memory full");        table_ident = ptable;    }    ts = tcc_malloc(sizeof(TokenSym) + len);    table_ident[i] = ts;    ts->tok = tok_ident++;    ts->sym_define = NULL;    ts->sym_label = NULL;    ts->sym_struct = NULL;    ts->sym_identifier = NULL;    ts->len = len;    ts->hash_next = NULL;    memcpy(ts->str, str, len);    ts->str[len] = '\0';    *pts = ts;    return ts;}#define TOK_HASH_INIT 1#define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))/* find a token and add it if not found */static TokenSym *tok_alloc(const char *str, int len){    TokenSym *ts, **pts;    int i;    unsigned int h;        h = TOK_HASH_INIT;    for(i=0;i<len;i++)        h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);    h &= (TOK_HASH_SIZE - 1);    pts = &hash_ident[h];    for(;;) {        ts = *pts;        if (!ts)

⌨️ 快捷键说明

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