Ignore:
Timestamp:
Jan 21, 2018, 12:10:09 AM (6 years ago)
Author:
coas-nagasima
Message:

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

Location:
EcnlProtoTool/trunk/tcc-0.9.27
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/tcc-0.9.27/tccasm.c

    r321 r331  
    3232}
    3333
    34 ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
     34static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global);
     35static Sym* asm_new_label(TCCState *s1, int label, int is_local);
     36static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value);
     37
     38static Sym *asm_label_find(int v)
     39{
     40    Sym *sym = sym_find(v);
     41    while (sym && sym->sym_scope)
     42        sym = sym->prev_tok;
     43    return sym;
     44}
     45
     46static Sym *asm_label_push(int v)
     47{
     48    /* We always add VT_EXTERN, for sym definition that's tentative
     49       (for .set, removed for real defs), for mere references it's correct
     50       as is.  */
     51    Sym *sym = global_identifier_push(v, VT_ASM | VT_EXTERN | VT_STATIC, 0);
     52    sym->r = VT_CONST | VT_SYM;
     53    return sym;
     54}
     55
     56/* Return a symbol we can use inside the assembler, having name NAME.
     57   Symbols from asm and C source share a namespace.  If we generate
     58   an asm symbol it's also a (file-global) C symbol, but it's
     59   either not accessible by name (like "L.123"), or its type information
     60   is such that it's not usable without a proper C declaration.
     61
     62   Sometimes we need symbols accessible by name from asm, which
     63   are anonymous in C, in this case CSYM can be used to transfer
     64   all information from that symbol to the (possibly newly created)
     65   asm symbol.  */
     66ST_FUNC Sym* get_asm_sym(int name, Sym *csym)
     67{
     68    Sym *sym = asm_label_find(name);
     69    if (!sym) {
     70        sym = asm_label_push(name);
     71        if (csym)
     72          sym->c = csym->c;
     73    }
     74    return sym;
     75}
     76
     77static Sym* asm_section_sym(TCCState *s1, Section *sec)
     78{
     79    char buf[100];
     80    int label = tok_alloc(buf,
     81        snprintf(buf, sizeof buf, "L.%s", sec->name)
     82        )->tok;
     83    Sym *sym = asm_label_find(label);
     84    return sym ? sym : asm_new_label1(s1, label, 1, sec->sh_num, 0);
     85}
    3586
    3687/* We do not use the C expression parser to handle symbols. Maybe the
     
    4091{
    4192    Sym *sym;
    42     int op, n, label;
     93    int op, label;
     94    uint64_t n;
    4395    const char *p;
    4496
    4597    switch(tok) {
    4698    case TOK_PPNUM:
    47         p = tokc.cstr->data;
    48         n = strtoul(p, (char **)&p, 0);
     99        p = tokc.str.data;
     100        n = strtoull(p, (char **)&p, 0);
    49101        if (*p == 'b' || *p == 'f') {
    50102            /* backward or forward label */
    51103            label = asm_get_local_label_name(s1, n);
    52             sym = label_find(label);
     104            sym = asm_label_find(label);
    53105            if (*p == 'b') {
    54106                /* backward : find the last corresponding defined label */
    55                 if (sym && sym->r == 0)
     107                if (sym && (!sym->c || elfsym(sym)->st_shndx == SHN_UNDEF))
    56108                    sym = sym->prev_tok;
    57109                if (!sym)
     
    59111            } else {
    60112                /* forward */
    61                 if (!sym || sym->r) {
     113                if (!sym || (sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)) {
    62114                    /* if the last label is defined, then define a new one */
    63                     sym = label_push(&s1->asm_labels, label, 0);
    64                     sym->type.t = VT_STATIC | VT_VOID;
     115                    sym = asm_label_push(label);
    65116                }
    66117            }
    67             pe->v = 0;
    68             pe->sym = sym;
     118            pe->v = 0;
     119            pe->sym = sym;
     120            pe->pcrel = 0;
    69121        } else if (*p == '\0') {
    70122            pe->v = n;
    71123            pe->sym = NULL;
     124            pe->pcrel = 0;
    72125        } else {
    73126            tcc_error("invalid number syntax");
     
    95148        pe->v = tokc.i;
    96149        pe->sym = NULL;
     150        pe->pcrel = 0;
    97151        next();
    98152        break;
     
    102156        skip(')');
    103157        break;
     158    case '.':
     159        pe->v = ind;
     160        pe->sym = asm_section_sym(s1, cur_text_section);
     161        pe->pcrel = 0;
     162        next();
     163        break;
    104164    default:
    105165        if (tok >= TOK_IDENT) {
     166            ElfSym *esym;
    106167            /* label case : if the label was not found, add one */
    107             sym = label_find(tok);
    108             if (!sym) {
    109                 sym = label_push(&s1->asm_labels, tok, 0);
    110                 /* NOTE: by default, the symbol is global */
    111                 sym->type.t = VT_VOID;
    112             }
    113             if (sym->r == SHN_ABS) {
     168            sym = get_asm_sym(tok, NULL);
     169            esym = elfsym(sym);
     170            if (esym && esym->st_shndx == SHN_ABS) {
    114171                /* if absolute symbol, no need to put a symbol value */
    115                 pe->v = sym->jnext;
     172                pe->v = esym->st_value;
    116173                pe->sym = NULL;
     174                pe->pcrel = 0;
    117175            } else {
    118176                pe->v = 0;
    119177                pe->sym = sym;
     178                pe->pcrel = 0;
    120179            }
    121180            next();
     
    220279            /* NOTE: we are less powerful than gas in that case
    221280               because we store only one symbol in the expression */
    222             if (!pe->sym && !e2.sym) {
    223                 /* OK */
    224             } else if (pe->sym && !e2.sym) {
    225                 /* OK */
    226             } else if (pe->sym && e2.sym) {
    227                 if (pe->sym == e2.sym) {
    228                     /* OK */
    229                 } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
    230                     /* we also accept defined symbols in the same section */
    231                     pe->v += pe->sym->jnext - e2.sym->jnext;
    232                 } else {
    233                     goto cannot_relocate;
    234                 }
    235                 pe->sym = NULL; /* same symbols can be substracted to NULL */
    236             } else {
    237             cannot_relocate:
    238                 tcc_error("invalid operation with label");
    239             }
    240         }
     281            if (!e2.sym) {
     282                /* OK */
     283            } else if (pe->sym == e2.sym) {
     284                /* OK */
     285                pe->sym = NULL; /* same symbols can be subtracted to NULL */
     286            } else {
     287                ElfSym *esym1, *esym2;
     288                esym1 = elfsym(pe->sym);
     289                esym2 = elfsym(e2.sym);
     290                if (esym1 && esym1->st_shndx == esym2->st_shndx
     291                    && esym1->st_shndx != SHN_UNDEF) {
     292                    /* we also accept defined symbols in the same section */
     293                    pe->v += esym1->st_value - esym2->st_value;
     294                    pe->sym = NULL;
     295                } else if (esym2->st_shndx == cur_text_section->sh_num) {
     296                    /* When subtracting a defined symbol in current section
     297                       this actually makes the value PC-relative.  */
     298                    pe->v -= esym2->st_value - ind - 4;
     299                    pe->pcrel = 1;
     300                    e2.sym = NULL;
     301                } else {
     302cannot_relocate:
     303                    tcc_error("invalid operation with label");
     304                }
     305            }
     306        }
     307    }
     308}
     309
     310static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)
     311{
     312    int op;
     313    ExprValue e2;
     314
     315    asm_expr_sum(s1, pe);
     316    for(;;) {
     317        op = tok;
     318        if (op != TOK_EQ && op != TOK_NE
     319            && (op > TOK_GT || op < TOK_ULE))
     320            break;
     321        next();
     322        asm_expr_sum(s1, &e2);
     323        if (pe->sym || e2.sym)
     324            tcc_error("invalid operation with label");
     325        switch(op) {
     326        case TOK_EQ:
     327            pe->v = pe->v == e2.v;
     328            break;
     329        case TOK_NE:
     330            pe->v = pe->v != e2.v;
     331            break;
     332        case TOK_LT:
     333            pe->v = (int64_t)pe->v < (int64_t)e2.v;
     334            break;
     335        case TOK_GE:
     336            pe->v = (int64_t)pe->v >= (int64_t)e2.v;
     337            break;
     338        case TOK_LE:
     339            pe->v = (int64_t)pe->v <= (int64_t)e2.v;
     340            break;
     341        case TOK_GT:
     342            pe->v = (int64_t)pe->v > (int64_t)e2.v;
     343            break;
     344        default:
     345            break;
     346        }
     347        /* GAS compare results are -1/0 not 1/0.  */
     348        pe->v = -(int64_t)pe->v;
    241349    }
    242350}
     
    244352ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)
    245353{
    246     asm_expr_sum(s1, pe);
     354    asm_expr_cmp(s1, pe);
    247355}
    248356
     
    256364}
    257365
    258 /* NOTE: the same name space as C labels is used to avoid using too
    259    much memory when storing labels in TokenStrings */
    260 static void asm_new_label1(TCCState *s1, int label, int is_local,
     366static Sym* asm_new_label1(TCCState *s1, int label, int is_local,
    261367                           int sh_num, int value)
    262368{
    263369    Sym *sym;
    264 
    265     sym = label_find(label);
     370    ElfSym *esym;
     371
     372    sym = asm_label_find(label);
    266373    if (sym) {
    267         if (sym->r) {
     374        esym = elfsym(sym);
     375        /* A VT_EXTERN symbol, even if it has a section is considered
     376           overridable.  This is how we "define" .set targets.  Real
     377           definitions won't have VT_EXTERN set.  */
     378        if (esym && esym->st_shndx != SHN_UNDEF) {
    268379            /* the label is already defined */
    269             if (!is_local) {
    270                 tcc_error("assembler label '%s' already defined",
    271                       get_tok_str(label, NULL));
    272             } else {
    273                 /* redefinition of local labels is possible */
     380            if (IS_ASM_SYM(sym)
     381                && (is_local == 1 || (sym->type.t & VT_EXTERN)))
    274382                goto new_label;
    275             }
     383            if (!(sym->type.t & VT_EXTERN))
     384                tcc_error("assembler label '%s' already defined",
     385                          get_tok_str(label, NULL));
    276386        }
    277387    } else {
    278388    new_label:
    279         sym = label_push(&s1->asm_labels, label, 0);
    280         sym->type.t = VT_STATIC | VT_VOID;
    281     }
    282     sym->r = sh_num;
    283     sym->jnext = value;
    284 }
    285 
    286 static void asm_new_label(TCCState *s1, int label, int is_local)
    287 {
    288     asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
    289 }
    290 
    291 static void asm_free_labels(TCCState *st)
    292 {
    293     Sym *s, *s1;
    294     Section *sec;
    295    
    296     for(s = st->asm_labels; s != NULL; s = s1) {
    297         s1 = s->prev;
    298         /* define symbol value in object file */
    299         if (s->r) {
    300             if (s->r == SHN_ABS)
    301                 sec = SECTION_ABS;
    302             else
    303                 sec = st->sections[s->r];
    304             put_extern_sym2(s, sec, s->jnext, 0, 0);
    305         }
    306         /* remove label */
    307         table_ident[s->v - TOK_IDENT]->sym_label = NULL;
    308         sym_free(s);
    309     }
    310     st->asm_labels = NULL;
     389        sym = asm_label_push(label);
     390    }
     391    if (!sym->c)
     392      put_extern_sym2(sym, SHN_UNDEF, 0, 0, 0);
     393    esym = elfsym(sym);
     394    esym->st_shndx = sh_num;
     395    esym->st_value = value;
     396    if (is_local != 2)
     397        sym->type.t &= ~VT_EXTERN;
     398    return sym;
     399}
     400
     401static Sym* asm_new_label(TCCState *s1, int label, int is_local)
     402{
     403    return asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
     404}
     405
     406/* Set the value of LABEL to that of some expression (possibly
     407   involving other symbols).  LABEL can be overwritten later still.  */
     408static Sym* set_symbol(TCCState *s1, int label)
     409{
     410    long n;
     411    ExprValue e;
     412    Sym *sym;
     413    ElfSym *esym;
     414    next();
     415    asm_expr(s1, &e);
     416    n = e.v;
     417    esym = elfsym(e.sym);
     418    if (esym)
     419        n += esym->st_value;
     420    sym = asm_new_label1(s1, label, 2, esym ? esym->st_shndx : SHN_ABS, n);
     421    elfsym(sym)->st_other |= ST_ASM_SET;
     422    return sym;
    311423}
    312424
     
    325437}
    326438
    327 static void asm_parse_directive(TCCState *s1)
     439static void push_section(TCCState *s1, const char *name)
     440{
     441    Section *sec = find_section(s1, name);
     442    sec->prev = cur_text_section;
     443    use_section1(s1, sec);
     444}
     445
     446static void pop_section(TCCState *s1)
     447{
     448    Section *prev = cur_text_section->prev;
     449    if (!prev)
     450        tcc_error(".popsection without .pushsection");
     451    cur_text_section->prev = NULL;
     452    use_section1(s1, prev);
     453}
     454
     455static void asm_parse_directive(TCCState *s1, int global)
    328456{
    329457    int n, offset, v, size, tok1;
     
    332460
    333461    /* assembler directive */
    334     next();
    335462    sec = cur_text_section;
    336463    switch(tok) {
    337     case TOK_ASM_align:
    338     case TOK_ASM_skip:
    339     case TOK_ASM_space:
     464    case TOK_ASMDIR_align:
     465    case TOK_ASMDIR_balign:
     466    case TOK_ASMDIR_p2align:
     467    case TOK_ASMDIR_skip:
     468    case TOK_ASMDIR_space:
    340469        tok1 = tok;
    341470        next();
    342471        n = asm_int_expr(s1);
    343         if (tok1 == TOK_ASM_align) {
     472        if (tok1 == TOK_ASMDIR_p2align)
     473        {
     474            if (n < 0 || n > 30)
     475                tcc_error("invalid p2align, must be between 0 and 30");
     476            n = 1 << n;
     477            tok1 = TOK_ASMDIR_align;
     478        }
     479        if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {
    344480            if (n < 0 || (n & (n-1)) != 0)
    345481                tcc_error("alignment must be a positive power of two");
     
    350486                sec->sh_addralign = n;
    351487        } else {
     488            if (n < 0)
     489                n = 0;
    352490            size = n;
    353491        }
     
    365503        ind += size;
    366504        break;
    367     case TOK_ASM_quad:
     505    case TOK_ASMDIR_quad:
     506#ifdef TCC_TARGET_X86_64
     507        size = 8;
     508        goto asm_data;
     509#else
    368510        next();
    369511        for(;;) {
     
    371513            const char *p;
    372514
    373             p = tokc.cstr->data;
     515            p = tokc.str.data;
    374516            if (tok != TOK_PPNUM) {
    375517            error_constant:
     
    392534        }
    393535        break;
    394     case TOK_ASM_byte:
     536#endif
     537    case TOK_ASMDIR_byte:
    395538        size = 1;
    396539        goto asm_data;
    397     case TOK_ASM_word:
    398     case TOK_SHORT:
     540    case TOK_ASMDIR_word:
     541    case TOK_ASMDIR_short:
    399542        size = 2;
    400543        goto asm_data;
    401     case TOK_LONG:
    402     case TOK_INT:
     544    case TOK_ASMDIR_long:
     545    case TOK_ASMDIR_int:
    403546        size = 4;
    404547    asm_data:
     
    410553                if (size == 4) {
    411554                    gen_expr32(&e);
     555#ifdef TCC_TARGET_X86_64
     556                } else if (size == 8) {
     557                    gen_expr64(&e);
     558#endif
    412559                } else {
    413560                    if (e.sym)
     
    426573        }
    427574        break;
    428     case TOK_ASM_fill:
     575    case TOK_ASMDIR_fill:
    429576        {
    430577            int repeat, size, val, i, j;
     
    468615        }
    469616        break;
    470     case TOK_ASM_org:
     617    case TOK_ASMDIR_rept:
     618        {
     619            int repeat;
     620            TokenString *init_str;
     621            next();
     622            repeat = asm_int_expr(s1);
     623            init_str = tok_str_alloc();
     624            while (next(), tok != TOK_ASMDIR_endr) {
     625                if (tok == CH_EOF)
     626                    tcc_error("we at end of file, .endr not found");
     627                tok_str_add_tok(init_str);
     628            }
     629            tok_str_add(init_str, -1);
     630            tok_str_add(init_str, 0);
     631            begin_macro(init_str, 1);
     632            while (repeat-- > 0) {
     633                tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS),
     634                                      global);
     635                macro_ptr = init_str->str;
     636            }
     637            end_macro();
     638            next();
     639            break;
     640        }
     641    case TOK_ASMDIR_org:
    471642        {
    472643            unsigned long n;
    473             next();
    474             /* XXX: handle section symbols too */
    475             n = asm_int_expr(s1);
     644            ExprValue e;
     645            ElfSym *esym;
     646            next();
     647            asm_expr(s1, &e);
     648            n = e.v;
     649            esym = elfsym(e.sym);
     650            if (esym) {
     651                if (esym->st_shndx != cur_text_section->sh_num)
     652                  expect("constant or same-section symbol");
     653                n += esym->st_value;
     654            }
    476655            if (n < ind)
    477656                tcc_error("attempt to .org backwards");
     
    481660        }
    482661        break;
    483     case TOK_ASM_globl:
    484     case TOK_ASM_global:
    485     case TOK_ASM_weak:
    486     tok1 = tok;
     662    case TOK_ASMDIR_set:
     663        next();
     664        tok1 = tok;
     665        next();
     666        /* Also accept '.set stuff', but don't do anything with this.
     667           It's used in GAS to set various features like '.set mips16'.  */
     668        if (tok == ',')
     669            set_symbol(s1, tok1);
     670        break;
     671    case TOK_ASMDIR_globl:
     672    case TOK_ASMDIR_global:
     673    case TOK_ASMDIR_weak:
     674    case TOK_ASMDIR_hidden:
     675        tok1 = tok;
    487676        do {
    488677            Sym *sym;
    489 
    490             next();
    491             sym = label_find(tok);
    492             if (!sym) {
    493                 sym = label_push(&s1->asm_labels, tok, 0);
    494                 sym->type.t = VT_VOID;
    495             }
    496             sym->type.t &= ~VT_STATIC;
    497             if (tok1 == TOK_ASM_weak)
    498                 sym->type.t |= VT_WEAK;
     678            next();
     679            sym = get_asm_sym(tok, NULL);
     680            if (tok1 != TOK_ASMDIR_hidden)
     681                sym->type.t &= ~VT_STATIC;
     682            if (tok1 == TOK_ASMDIR_weak)
     683                sym->a.weak = 1;
     684            else if (tok1 == TOK_ASMDIR_hidden)
     685                sym->a.visibility = STV_HIDDEN;
     686            update_storage(sym);
    499687            next();
    500688        } while (tok == ',');
    501689        break;
    502     case TOK_ASM_string:
    503     case TOK_ASM_ascii:
    504     case TOK_ASM_asciz:
     690    case TOK_ASMDIR_string:
     691    case TOK_ASMDIR_ascii:
     692    case TOK_ASMDIR_asciz:
    505693        {
    506694            const uint8_t *p;
     
    512700                if (tok != TOK_STR)
    513701                    expect("string constant");
    514                 p = tokc.cstr->data;
    515                 size = tokc.cstr->size;
    516                 if (t == TOK_ASM_ascii && size > 0)
     702                p = tokc.str.data;
     703                size = tokc.str.size;
     704                if (t == TOK_ASMDIR_ascii && size > 0)
    517705                    size--;
    518706                for(i = 0; i < size; i++)
     
    527715        }
    528716        break;
    529     case TOK_ASM_text:
    530     case TOK_ASM_data:
    531     case TOK_ASM_bss:
     717    case TOK_ASMDIR_text:
     718    case TOK_ASMDIR_data:
     719    case TOK_ASMDIR_bss:
    532720        {
    533721            char sname[64];
     
    539727                next();
    540728            }
    541             sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
     729            if (n)
     730                sprintf(sname, "%s%d", get_tok_str(tok1, NULL), n);
     731            else
     732                sprintf(sname, "%s", get_tok_str(tok1, NULL));
    542733            use_section(s1, sname);
    543734        }
    544735        break;
    545     case TOK_ASM_file:
     736    case TOK_ASMDIR_file:
    546737        {
    547738            char filename[512];
     
    551742
    552743            if (tok == TOK_STR)
    553                 pstrcat(filename, sizeof(filename), tokc.cstr->data);
     744                pstrcat(filename, sizeof(filename), tokc.str.data);
    554745            else
    555746                pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
     
    561752        }
    562753        break;
    563     case TOK_ASM_ident:
     754    case TOK_ASMDIR_ident:
    564755        {
    565756            char ident[256];
     
    569760
    570761            if (tok == TOK_STR)
    571                 pstrcat(ident, sizeof(ident), tokc.cstr->data);
     762                pstrcat(ident, sizeof(ident), tokc.str.data);
    572763            else
    573764                pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
     
    579770        }
    580771        break;
    581     case TOK_ASM_size:
     772    case TOK_ASMDIR_size:
    582773        {
    583774            Sym *sym;
    584775
    585776            next();
    586             sym = label_find(tok);
     777            sym = asm_label_find(tok);
    587778            if (!sym) {
    588779                tcc_error("label not found: %s", get_tok_str(tok, NULL));
    589780            }
    590781
    591             next();
    592             skip(',');
    593782            /* XXX .size name,label2-label1 */
    594783            if (s1->warn_unsupported)
    595784                tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL));
    596785
    597             while (tok != '\n' && tok != CH_EOF) {
     786            next();
     787            skip(',');
     788            while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {
    598789                next();
    599790            }
    600791        }
    601792        break;
    602     case TOK_ASM_type:
     793    case TOK_ASMDIR_type:
    603794        {
    604795            Sym *sym;
     
    606797
    607798            next();
    608             sym = label_find(tok);
    609             if (!sym) {
    610                 sym = label_push(&s1->asm_labels, tok, 0);
    611                 sym->type.t = VT_VOID;
    612             }
    613 
     799            sym = get_asm_sym(tok, NULL);
    614800            next();
    615801            skip(',');
    616802            if (tok == TOK_STR) {
    617                 newtype = tokc.cstr->data;
     803                newtype = tokc.str.data;
    618804            } else {
    619805                if (tok == '@' || tok == '%')
    620                     skip(tok);
     806                    next();
    621807                newtype = get_tok_str(tok, NULL);
    622808            }
    623809
    624810            if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
    625                 sym->type.t = VT_FUNC;
     811                sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
    626812            }
    627813            else if (s1->warn_unsupported)
     
    632818        }
    633819        break;
    634     case TOK_SECTION1:
     820    case TOK_ASMDIR_pushsection:
     821    case TOK_ASMDIR_section:
    635822        {
    636823            char sname[256];
    637 
     824            int old_nb_section = s1->nb_sections;
     825
     826            tok1 = tok;
    638827            /* XXX: support more options */
    639828            next();
     
    641830            while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
    642831                if (tok == TOK_STR)
    643                     pstrcat(sname, sizeof(sname), tokc.cstr->data);
     832                    pstrcat(sname, sizeof(sname), tokc.str.data);
    644833                else
    645834                    pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
     
    652841                    expect("string constant");
    653842                next();
     843                if (tok == ',') {
     844                    next();
     845                    if (tok == '@' || tok == '%')
     846                        next();
     847                    next();
     848                }
    654849            }
    655850            last_text_section = cur_text_section;
    656             use_section(s1, sname);
    657         }
    658         break;
    659     case TOK_ASM_previous:
     851            if (tok1 == TOK_ASMDIR_section)
     852                use_section(s1, sname);
     853            else
     854                push_section(s1, sname);
     855            /* If we just allocated a new section reset its alignment to
     856               1.  new_section normally acts for GCC compatibility and
     857               sets alignment to PTR_SIZE.  The assembler behaves different. */
     858            if (old_nb_section != s1->nb_sections)
     859                cur_text_section->sh_addralign = 1;
     860        }
     861        break;
     862    case TOK_ASMDIR_previous:
    660863        {
    661864            Section *sec;
     
    668871        }
    669872        break;
     873    case TOK_ASMDIR_popsection:
     874        next();
     875        pop_section(s1);
     876        break;
    670877#ifdef TCC_TARGET_I386
    671     case TOK_ASM_code16:
     878    case TOK_ASMDIR_code16:
    672879        {
    673880            next();
     
    675882        }
    676883        break;
    677     case TOK_ASM_code32:
     884    case TOK_ASMDIR_code32:
    678885        {
    679886            next();
     
    684891#ifdef TCC_TARGET_X86_64
    685892    /* added for compatibility with GAS */
    686     case TOK_ASM_code64:
     893    case TOK_ASMDIR_code64:
    687894        next();
    688895        break;
     
    696903
    697904/* assemble a file */
    698 static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
     905static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
    699906{
    700907    int opcode;
    701 
    702 #if 0
    703     /* print stats about opcodes */
    704     {
    705         const ASMInstr *pa;
    706         int freq[4];
    707         int op_vals[500];
    708         int nb_op_vals, i, j;
    709 
    710         nb_op_vals = 0;
    711         memset(freq, 0, sizeof(freq));
    712         for(pa = asm_instrs; pa->sym != 0; pa++) {
    713             freq[pa->nb_ops]++;
    714             for(i=0;i<pa->nb_ops;i++) {
    715                 for(j=0;j<nb_op_vals;j++) {
    716                     if (pa->op_type[i] == op_vals[j])
    717                         goto found;
    718                 }
    719                 op_vals[nb_op_vals++] = pa->op_type[i];
    720             found: ;
    721             }
    722         }
    723         for(i=0;i<nb_op_vals;i++) {
    724             int v = op_vals[i];
    725             if ((v & (v - 1)) != 0)
    726                 printf("%3d: %08x\n", i, v);
    727         }
    728         printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
    729                sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
    730                freq[0], freq[1], freq[2], freq[3]);
    731     }
    732 #endif
    733 
    734     /* XXX: undefine C labels */
    735 
    736     ch = file->buf_ptr[0];
    737     tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
    738     parse_flags = PARSE_FLAG_ASM_COMMENTS;
     908    int saved_parse_flags = parse_flags;
     909
     910    parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;
    739911    if (do_preprocess)
    740912        parse_flags |= PARSE_FLAG_PREPROCESS;
    741     next();
    742913    for(;;) {
     914        next();
    743915        if (tok == TOK_EOF)
    744916            break;
     917        /* generate line number info */
     918        if (global && s1->do_debug)
     919            tcc_debug_line(s1);
    745920        parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
    746921    redo:
     
    749924            while (tok != TOK_LINEFEED)
    750925                next();
    751         } else if (tok == '.') {
    752             asm_parse_directive(s1);
     926        } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) {
     927            asm_parse_directive(s1, global);
    753928        } else if (tok == TOK_PPNUM) {
    754929            const char *p;
    755930            int n;
    756             p = tokc.cstr->data;
     931            p = tokc.str.data;
    757932            n = strtoul(p, (char **)&p, 10);
    758933            if (*p != '\0')
     
    773948                goto redo;
    774949            } else if (tok == '=') {
    775                 int n;
    776                 next();
    777                 n = asm_int_expr(s1);
    778                 asm_new_label1(s1, opcode, 0, SHN_ABS, n);
     950                set_symbol(s1, opcode);
    779951                goto redo;
    780952            } else {
     
    783955        }
    784956        /* end of line */
    785         if (tok != ';' && tok != TOK_LINEFEED){
     957        if (tok != ';' && tok != TOK_LINEFEED)
    786958            expect("end of line");
    787         }
    788959        parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
    789         next();
    790     }
    791 
    792     asm_free_labels(s1);
    793 
     960    }
     961
     962    parse_flags = saved_parse_flags;
    794963    return 0;
    795964}
     
    798967ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
    799968{
    800     Sym *define_start;
    801969    int ret;
    802 
    803     preprocess_init(s1);
    804 
     970    tcc_debug_start(s1);
    805971    /* default section is text */
    806972    cur_text_section = text_section;
    807973    ind = cur_text_section->data_offset;
    808 
    809     define_start = define_stack;
    810 
    811     /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
    812        symbols can be safely used */
    813     put_elf_sym(symtab_section, 0, 0,
    814                 ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
    815                 SHN_ABS, file->filename);
    816 
    817     ret = tcc_assemble_internal(s1, do_preprocess);
    818 
     974    nocode_wanted = 0;
     975    ret = tcc_assemble_internal(s1, do_preprocess, 1);
    819976    cur_text_section->data_offset = ind;
    820 
    821     free_defines(define_start);
    822 
     977    tcc_debug_end(s1);
    823978    return ret;
    824979}
     
    830985   C preprocessing. NOTE: str is modified by modifying the '\0' at the
    831986   end */
    832 static void tcc_assemble_inline(TCCState *s1, char *str, int len)
    833 {
    834     int saved_parse_flags;
    835     const int *saved_macro_ptr;
    836 
    837     saved_parse_flags = parse_flags;
    838     saved_macro_ptr = macro_ptr;
     987static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)
     988{
     989    const int *saved_macro_ptr = macro_ptr;
     990    int dotid = set_idnum('.', IS_ID);
    839991
    840992    tcc_open_bf(s1, ":asm:", len);
    841993    memcpy(file->buffer, str, len);
    842 
    843994    macro_ptr = NULL;
    844     tcc_assemble_internal(s1, 0);
     995    tcc_assemble_internal(s1, 0, global);
    845996    tcc_close();
    846997
    847     parse_flags = saved_parse_flags;
     998    set_idnum('.', dotid);
    848999    macro_ptr = saved_macro_ptr;
    8491000}
     
    8911042
    8921043static void subst_asm_operands(ASMOperand *operands, int nb_operands,
    893                                int nb_outputs,
    8941044                               CString *out_str, CString *in_str)
    8951045{
     
    9101060            modifier = 0;
    9111061            if (*str == 'c' || *str == 'n' ||
    912                 *str == 'b' || *str == 'w' || *str == 'h')
     1062                *str == 'b' || *str == 'w' || *str == 'h' || *str == 'k' ||
     1063                *str == 'q' ||
     1064                /* P in GCC would add "@PLT" to symbol refs in PIC mode,
     1065                   and make literal operands not be decorated with '$'.  */
     1066                *str == 'P')
    9131067                modifier = *str++;
    9141068            index = find_constraint(operands, nb_operands, str, &str);
     
    9421096        nb_operands = *nb_operands_ptr;
    9431097        for(;;) {
     1098            CString astr;
    9441099            if (nb_operands >= MAX_ASM_OPERANDS)
    9451100                tcc_error("too many asm operands");
     
    9541109                skip(']');
    9551110            }
    956             if (tok != TOK_STR)
    957                 expect("string constant");
    958             op->constraint = tcc_malloc(tokc.cstr->size);
    959             strcpy(op->constraint, tokc.cstr->data);
    960             next();
     1111            parse_mult_str(&astr, "string constant");
     1112            op->constraint = tcc_malloc(astr.size);
     1113            strcpy(op->constraint, astr.data);
     1114            cstr_free(&astr);
    9611115            skip('(');
    9621116            gexpr();
    9631117            if (is_output) {
    964                 test_lvalue();
     1118                if (!(vtop->type.t & VT_ARRAY))
     1119                    test_lvalue();
    9651120            } else {
    9661121                /* we want to avoid LLOCAL case, except when the 'm'
     
    10241179                        if (tok != TOK_STR)
    10251180                            expect("string constant");
    1026                         asm_clobber(clobber_regs, tokc.cstr->data);
     1181                        asm_clobber(clobber_regs, tokc.str.data);
    10271182                        next();
    10281183                        if (tok == ',') {
     
    10551210#endif
    10561211    if (must_subst) {
    1057         subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr);
     1212        subst_asm_operands(operands, nb_operands, &astr1, &astr);
    10581213        cstr_free(&astr);
    10591214    } else {
     
    10691224
    10701225    /* assemble the string with tcc internal assembler */
    1071     tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
     1226    tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1, 0);
    10721227
    10731228    /* restore the current C token */
     
    10911246{
    10921247    CString astr;
    1093 
     1248    int saved_nocode_wanted = nocode_wanted;
     1249
     1250    /* Global asm blocks are always emitted.  */
     1251    nocode_wanted = 0;
    10941252    next();
    10951253    parse_asm_str(&astr);
     
    11071265
    11081266    /* assemble the string with tcc internal assembler */
    1109     tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
     1267    tcc_assemble_inline(tcc_state, astr.data, astr.size - 1, 1);
    11101268   
    11111269    cur_text_section->data_offset = ind;
     
    11151273
    11161274    cstr_free(&astr);
     1275    nocode_wanted = saved_nocode_wanted;
    11171276}
    11181277#endif /* CONFIG_TCC_ASM */
Note: See TracChangeset for help on using the changeset viewer.