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

📄 tcc.c

📁 tcc
💻 C
📖 第 1 页 / 共 5 页
字号:
    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);}/* 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)        sh_num = section->sh_num;    else        sh_num = SHN_UNDEF;    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)            break;        if (ts->len == len && !memcmp(ts->str, str, len))            return ts;        pts = &(ts->hash_next);    }    return tok_alloc_new(pts, str, len);}/* CString handling */static void cstr_realloc(CString *cstr, int new_size){    int size;    void *data;    size = cstr->size_allocated;    if (size == 0)        size = 8; /* no need to allocate a too small first string */    while (size < new_size)        size = size * 2;    data = tcc_realloc(cstr->data_allocated, size);    if (!data)        error("memory full");    cstr->data_allocated = data;    cstr->size_allocated = size;    cstr->data = data;}/* add a byte */static void cstr_ccat(CString *cstr, int ch){    int size;    size = cstr->size + 1;    if (size > cstr->size_allocated)        cstr_realloc(cstr, size);    ((unsigned char *)cstr->data)[size - 1] = ch;    cstr->size = size;}static void cstr_cat(CString *cstr, const char *str){    int c;    for(;;) {        c = *str;        if (c == '\0')            break;        cstr_ccat(cstr, c);        str++;    }}/* add a wide char */static void cstr_wccat(CString *cstr, int ch){    int size;    size = cstr->size + sizeof(int);    if (size > cstr->size_allocated)        cstr_realloc(cstr, size);    *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;    cstr->size = size;}static void cstr_new(CString *cstr){    memset(cstr, 0, sizeof(CString));}/* free string and reset it to NULL */static void cstr_free(CString *cstr){    tcc_free(cstr->data_allocated);    cstr_new(cstr);}#define cstr_reset(cstr) cstr_free(cstr)static CString *cstr_dup(CString *cstr1){    CString *cstr;    int size;    cstr = tcc_malloc(sizeof(CString));    size = cstr1->size;    cstr->size = size;    cstr->size_allocated = size;    cstr->data_allocated = tcc_malloc(size);    cstr->data = cstr->data_allocated;    memcpy(cstr->data_allocated, cstr1->data_allocated, size);    return cstr;}/* XXX: unicode ? */static void add_char(CString *cstr, int c){    if (c == '\'' || c == '\"' || c == '\\') {        /* XXX: could be more precise if char or string */        cstr_ccat(cstr, '\\');    }    if (c >= 32 && c <= 126) {        cstr_ccat(cstr, c);    } else {        cstr_ccat(cstr, '\\');        if (c == '\n') {            cstr_ccat(cstr, 'n');        } else {            cstr_ccat(cstr, '0' + ((c >> 6) & 7));            cstr_ccat(cstr, '0' + ((c >> 3) & 7));            cstr_ccat(cstr, '0' + (c & 7));        }    }}/* XXX: buffer overflow *//* XXX: float tokens */char *get_tok_str(int v, CValue *cv){    static char buf[STRING_MAX_SIZE + 1];    static CString cstr_buf;    CString *cstr;    unsigned char *q;    char *p;    int i, len;    /* NOTE: to go faster, we give a fixed buffer for small strings */    cstr_reset(&cstr_buf);    cstr_buf.data = buf;    cstr_buf.size_allocated = sizeof(buf);    p = buf;    switch(v) {    case TOK_CINT:    case TOK_CUINT:        /* XXX: not quite exact, but only useful for testing */        sprintf(p, "%u", cv->ui);        break;    case TOK_CLLONG:    case TOK_CULLONG:        /* XXX: not quite exact, but only useful for testing  */

⌨️ 快捷键说明

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