Ejemplo n.º 1
0
void
yasm_linemap_set(yasm_linemap *linemap, const char *filename,
                 unsigned long virtual_line, unsigned long file_line,
                 unsigned long line_inc)
{
    char *copy;
    unsigned long i;
    int replace = 0;
    line_mapping *mapping = NULL;

    if (virtual_line == 0) {
        virtual_line = linemap->current;
    }

    /* Replace all existing mappings that have line numbers >= this one. */
    for (i = linemap->map_size; i > 0; i--) {
        if (linemap->map_vector[i-1].line < virtual_line) {
            if (i < linemap->map_size) {
                mapping = &linemap->map_vector[i];
                linemap->map_size = i + 1;
            }
            break;
        }
    }

    if (mapping == NULL) {
        /* Create a new mapping in the map */
        if (linemap->map_size >= linemap->map_allocated) {
            /* allocate another size bins when full for 2x space */
            linemap->map_vector = yasm_xrealloc(linemap->map_vector,
                2*linemap->map_allocated*sizeof(line_mapping));
            linemap->map_allocated *= 2;
        }
        mapping = &linemap->map_vector[linemap->map_size];
        linemap->map_size++;
    }

    /* Fill it */

    if (!filename) {
        if (linemap->map_size >= 2)
            mapping->filename =
                linemap->map_vector[linemap->map_size-2].filename;
        else
            filename = "unknown";
    }
    if (filename) {
        /* Copy the filename (via shared storage) */
        copy = yasm__xstrdup(filename);
        /*@-aliasunique@*/
        mapping->filename = HAMT_insert(linemap->filenames, copy, copy,
                                        &replace, filename_delete_one);
        /*@=aliasunique@*/
    }

    mapping->line = virtual_line;
    mapping->file_line = file_line;
    mapping->line_inc = line_inc;
}
Ejemplo n.º 2
0
static void
strbuf_append(size_t count, YYCTYPE *cursor, yasm_scanner *s, int ch)
{
    if (count >= strbuf_size) {
        strbuf = yasm_xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
        strbuf_size += STRBUF_ALLOC_SIZE;
    }
    strbuf[count] = ch;
}
void
yasm_register_module(yasm_module_type type, const char *keyword, void *data)
{
    loaded_modules =
        yasm_xrealloc(loaded_modules,
                      (num_loaded_modules+1)*sizeof(loaded_module));
    loaded_modules[num_loaded_modules].type = type;
    loaded_modules[num_loaded_modules].keyword = keyword;
    loaded_modules[num_loaded_modules].data = data;
    num_loaded_modules++;
}
Ejemplo n.º 4
0
static char *
cpp_preproc_get_line(yasm_preproc *preproc)
{
    yasm_preproc_cpp *pp = (yasm_preproc_cpp *)preproc;
    int bufsize = BSIZE;
    char *buf, *p;

    if (! (pp->flags & CPP_HAS_BEEN_INVOKED) ) {
        pp->flags |= CPP_HAS_BEEN_INVOKED;

        cpp_invoke(pp);
    }

    /*
        Once the preprocessor has been run, we're just dealing with a normal
        file.
    */

    /* Loop to ensure entire line is read (don't want to limit line length). */
    buf = yasm_xmalloc((size_t)bufsize);
    p = buf;
    for (;;) {
        if (!fgets(p, bufsize-(p-buf), pp->f)) {
            if (ferror(pp->f)) {
                yasm_error_set(YASM_ERROR_IO,
                               N_("error when reading from file"));
                yasm_errwarn_propagate(pp->errwarns,
                    yasm_linemap_get_current(pp->cur_lm));
            }
            break;
        }
        p += strlen(p);
        if (p > buf && p[-1] == '\n')
            break;
        if ((p-buf) >= bufsize) {
            /* Increase size of buffer */
            char *oldbuf = buf;
            bufsize *= 2;
            buf = yasm_xrealloc(buf, (size_t)bufsize);
            p = buf + (p-oldbuf);
        }
    }

    if (p == buf) {
        /* No data; must be at EOF */
        yasm_xfree(buf);
        return NULL;
    }

    /* Strip the line ending */
    buf[strcspn(buf, "\r\n")] = '\0';

    return buf;
}
Ejemplo n.º 5
0
static char *
raw_preproc_get_line(yasm_preproc *preproc)
{
    yasm_preproc_raw *preproc_raw = (yasm_preproc_raw *)preproc;
    int bufsize = BSIZE;
    char *buf = yasm_xmalloc((size_t)bufsize);
    char *p;

    /* Loop to ensure entire line is read (don't want to limit line length). */
    p = buf;
    for (;;) {
        if (!fgets(p, bufsize-(p-buf), preproc_raw->in)) {
            if (ferror(preproc_raw->in)) {
                yasm_error_set(YASM_ERROR_IO,
                               N_("error when reading from file"));
                yasm_errwarn_propagate(preproc_raw->errwarns,
                    yasm_linemap_get_current(preproc_raw->cur_lm));
            }
            break;
        }
        p += strlen(p);
        if (p > buf && p[-1] == '\n')
            break;
        if ((p-buf)+1 >= bufsize) {
            /* Increase size of buffer */
            char *oldbuf = buf;
            bufsize *= 2;
            buf = yasm_xrealloc(buf, (size_t)bufsize);
            p = buf + (p-oldbuf);
        }
    }

    if (p == buf) {
        /* No data; must be at EOF */
        yasm_xfree(buf);
        return NULL;
    }

    /* Strip the line ending */
    buf[strcspn(buf, "\r\n")] = '\0';

    return buf;
}
Ejemplo n.º 6
0
void
yasm_bc__add_symrec(yasm_bytecode *bc, yasm_symrec *sym)
{
    if (!bc->symrecs) {
        bc->symrecs = yasm_xmalloc(2*sizeof(yasm_symrec *));
        bc->symrecs[0] = sym;
        bc->symrecs[1] = NULL;
    } else {
        /* Very inefficient implementation for large numbers of symbols.  But
         * that would be very unusual, so use the simple algorithm instead.
         */
        size_t count = 1;
        while (bc->symrecs[count])
            count++;
        bc->symrecs = yasm_xrealloc(bc->symrecs,
                                    (count+2)*sizeof(yasm_symrec *));
        bc->symrecs[count] = sym;
        bc->symrecs[count+1] = NULL;
    }
}
Ejemplo n.º 7
0
void
yasm_linemap_add_source(yasm_linemap *linemap, yasm_bytecode *bc,
                        const char *source)
{
    size_t i;

    while (linemap->current > linemap->source_info_size) {
        /* allocate another size bins when full for 2x space */
        linemap->source_info = yasm_xrealloc(linemap->source_info,
            2*linemap->source_info_size*sizeof(line_source_info));
        for (i=linemap->source_info_size; i<linemap->source_info_size*2; i++) {
            linemap->source_info[i].bc = NULL;
            linemap->source_info[i].source = NULL;
        }
        linemap->source_info_size *= 2;
    }

    /* Delete existing info for that line (if any) */
    if (linemap->source_info[linemap->current-1].source)
        yasm_xfree(linemap->source_info[linemap->current-1].source);

    linemap->source_info[linemap->current-1].bc = bc;
    linemap->source_info[linemap->current-1].source = yasm__xstrdup(source);
}
Ejemplo n.º 8
0
/*@-mustfree@*/
static /*@only@*/ yasm_expr *
expr_level_op(/*@returned@*/ /*@only@*/ yasm_expr *e, int fold_const,
              int simplify_ident, int simplify_reg_mul)
{
    int i, j, o, fold_numterms, level_numterms, level_fold_numterms;
    int first_int_term = -1;

    /* Determine how many operands will need to be brought up (for leveling).
     * Go ahead and bring up any IDENT'ed values.
     */
    while (e->op == YASM_EXPR_IDENT && e->terms[0].type == YASM_EXPR_EXPR) {
        yasm_expr *sube = e->terms[0].data.expn;
        yasm_xfree(e);
        e = sube;
    }

    /* If non-numeric expression, don't fold constants. */
    if (e->op > YASM_EXPR_NONNUM)
        fold_const = 0;

    level_numterms = e->numterms;
    level_fold_numterms = 0;
    for (i=0; i<e->numterms; i++) {
        /* Search downward until we find something *other* than an
         * IDENT, then bring it up to the current level.
         */
        while (e->terms[i].type == YASM_EXPR_EXPR &&
               e->terms[i].data.expn->op == YASM_EXPR_IDENT) {
            yasm_expr *sube = e->terms[i].data.expn;
            e->terms[i] = sube->terms[0];
            yasm_xfree(sube);
        }

        if (e->terms[i].type == YASM_EXPR_EXPR &&
            e->terms[i].data.expn->op == e->op) {
                /* It's an expression w/the same operator, add in its numterms.
                 * But don't forget to subtract one for the expr itself!
                 */
                level_numterms += e->terms[i].data.expn->numterms - 1;

                /* If we're folding constants, count up the number of constants
                 * that will be merged in.
                 */
                if (fold_const)
                    for (j=0; j<e->terms[i].data.expn->numterms; j++)
                        if (e->terms[i].data.expn->terms[j].type ==
                            YASM_EXPR_INT)
                            level_fold_numterms++;
        }

        /* Find the first integer term (if one is present) if we're folding
         * constants.
         */
        if (fold_const && first_int_term == -1 &&
            e->terms[i].type == YASM_EXPR_INT)
            first_int_term = i;
    }

    /* Look for other integer terms if there's one and combine.
     * Also eliminate empty spaces when combining and adjust numterms
     * variables.
     */
    fold_numterms = e->numterms;
    if (first_int_term != -1) {
        for (i=first_int_term+1, o=first_int_term+1; i<e->numterms; i++) {
            if (e->terms[i].type == YASM_EXPR_INT) {
                yasm_intnum_calc(e->terms[first_int_term].data.intn, e->op,
                                 e->terms[i].data.intn);
                fold_numterms--;
                level_numterms--;
                /* make sure to delete folded intnum */
                yasm_intnum_destroy(e->terms[i].data.intn);
            } else if (o != i) {
                /* copy term if it changed places */
                e->terms[o++] = e->terms[i];
            } else
                o++;
        }

        if (simplify_ident) {
            int new_fold_numterms;
            /* Simplify identities and make IDENT if possible. */
            new_fold_numterms =
                expr_simplify_identity(e, fold_numterms, &first_int_term,
                                       simplify_reg_mul);
            level_numterms -= fold_numterms-new_fold_numterms;
            fold_numterms = new_fold_numterms;
        }
        if (fold_numterms == 1)
            e->op = YASM_EXPR_IDENT;
    }

    /* Only level operators that allow more than two operand terms.
     * Also don't bother leveling if it's not necessary to bring up any terms.
     */
    if ((e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_MUL &&
         e->op != YASM_EXPR_OR && e->op != YASM_EXPR_AND &&
         e->op != YASM_EXPR_LOR && e->op != YASM_EXPR_LAND &&
         e->op != YASM_EXPR_LXOR && e->op != YASM_EXPR_XOR) ||
        level_numterms <= fold_numterms) {
        /* Downsize e if necessary */
        if (fold_numterms < e->numterms && e->numterms > 2)
            e = yasm_xrealloc(e, sizeof(yasm_expr)+((fold_numterms<2) ? 0 :
                              sizeof(yasm_expr__item)*(fold_numterms-2)));
        /* Update numterms */
        e->numterms = fold_numterms;
        return e;
    }

    /* Adjust numterms for constant folding from terms being "pulled up".
     * Careful: if there's no integer term in e, then save space for it.
     */
    if (fold_const) {
        level_numterms -= level_fold_numterms;
        if (first_int_term == -1 && level_fold_numterms != 0)
            level_numterms++;
    }

    /* Alloc more (or conceivably less, but not usually) space for e */
    e = yasm_xrealloc(e, sizeof(yasm_expr)+((level_numterms<2) ? 0 :
                      sizeof(yasm_expr__item)*(level_numterms-2)));

    /* Copy up ExprItem's.  Iterate from right to left to keep the same
     * ordering as was present originally.
     * Combine integer terms as necessary.
     */
    for (i=fold_numterms-1, o=level_numterms-1; i>=0; i--) {
        if (e->terms[i].type == YASM_EXPR_EXPR &&
            e->terms[i].data.expn->op == e->op) {
            /* bring up subexpression */
            yasm_expr *sube = e->terms[i].data.expn;

            /* copy terms right to left */
            for (j=sube->numterms-1; j>=0; j--) {
                if (fold_const && sube->terms[j].type == YASM_EXPR_INT) {
                    /* Need to fold it in.. but if there's no int term already,
                     * just copy into a new one.
                     */
                    if (first_int_term == -1) {
                        first_int_term = o--;
                        e->terms[first_int_term] = sube->terms[j];  /* struc */
                    } else {
                        yasm_intnum_calc(e->terms[first_int_term].data.intn,
                                         e->op, sube->terms[j].data.intn);
                        /* make sure to delete folded intnum */
                        yasm_intnum_destroy(sube->terms[j].data.intn);
                    }
                } else {
                    if (o == first_int_term)
                        o--;
                    e->terms[o--] = sube->terms[j];     /* structure copy */
                }
            }

            /* delete subexpression, but *don't delete nodes* (as we've just
             * copied them!)
             */
            yasm_xfree(sube);
        } else if (o != i) {
            /* copy operand if it changed places */
            if (o == first_int_term)
                o--;
            e->terms[o] = e->terms[i];
            /* If we moved the first_int_term, change first_int_num too */
            if (i == first_int_term)
                first_int_term = o;
            o--;
        } else
            o--;
    }

    /* Simplify identities, make IDENT if possible, and save to e->numterms. */
    if (simplify_ident && first_int_term != -1) {
        e->numterms = expr_simplify_identity(e, level_numterms,
                                             &first_int_term, simplify_reg_mul);
    } else {
        e->numterms = level_numterms;
        if (level_numterms == 1)
            e->op = YASM_EXPR_IDENT;
    }

    return e;
}
Ejemplo n.º 9
0
/* Transforms instances of symrec-symrec [symrec+(-1*symrec)] into single
 * expritems if possible.  Uses a simple n^2 algorithm because n is usually
 * quite small.  Also works for precbc-precbc (or symrec-precbc,
 * precbc-symrec).
 */
static /*@only@*/ yasm_expr *
expr_xform_bc_dist_base(/*@returned@*/ /*@only@*/ yasm_expr *e,
                        /*@null@*/ void *cbd,
                        int (*callback) (yasm_expr__item *ei,
                                         yasm_bytecode *precbc,
                                         yasm_bytecode *precbc2,
                                         void *cbd))
{
    int i;
    /*@dependent@*/ yasm_section *sect;
    /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
    int numterms;

    /* Handle symrec-symrec in ADD exprs by looking for (-1*symrec) and
     * symrec term pairs (where both symrecs are in the same segment).
     */
    if (e->op != YASM_EXPR_ADD)
        return e;

    for (i=0; i<e->numterms; i++) {
        int j;
        yasm_expr *sube;
        yasm_intnum *intn;
        yasm_symrec *sym = NULL;
        /*@dependent@*/ yasm_section *sect2;
        /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc2;

        /* First look for an (-1*symrec) term */
        if (e->terms[i].type != YASM_EXPR_EXPR)
            continue;
        sube = e->terms[i].data.expn;
        if (sube->op != YASM_EXPR_MUL || sube->numterms != 2)
            continue;

        if (sube->terms[0].type == YASM_EXPR_INT &&
            (sube->terms[1].type == YASM_EXPR_SYM ||
             sube->terms[1].type == YASM_EXPR_PRECBC)) {
            intn = sube->terms[0].data.intn;
            if (sube->terms[1].type == YASM_EXPR_PRECBC)
                precbc = sube->terms[1].data.precbc;
            else
                sym = sube->terms[1].data.sym;
        } else if ((sube->terms[0].type == YASM_EXPR_SYM ||
                    sube->terms[0].type == YASM_EXPR_PRECBC) &&
                   sube->terms[1].type == YASM_EXPR_INT) {
            if (sube->terms[0].type == YASM_EXPR_PRECBC)
                precbc = sube->terms[0].data.precbc;
            else
                sym = sube->terms[0].data.sym;
            intn = sube->terms[1].data.intn;
        } else
            continue;

        if (!yasm_intnum_is_neg1(intn))
            continue;

        if (sym && !yasm_symrec_get_label(sym, &precbc))
            continue;
        sect2 = yasm_bc_get_section(precbc);

        /* Now look for a symrec term in the same segment */
        for (j=0; j<e->numterms; j++) {
            if (((e->terms[j].type == YASM_EXPR_SYM &&
                  yasm_symrec_get_label(e->terms[j].data.sym, &precbc2)) ||
                 (e->terms[j].type == YASM_EXPR_PRECBC &&
                  (precbc2 = e->terms[j].data.precbc))) &&
                (sect = yasm_bc_get_section(precbc2)) &&
                sect == sect2 &&
                callback(&e->terms[j], precbc, precbc2, cbd)) {
                /* Delete the matching (-1*symrec) term */
                yasm_expr_destroy(sube);
                e->terms[i].type = YASM_EXPR_NONE;
                break;  /* stop looking for matching symrec term */
            }
        }
    }

    /* Clean up any deleted (EXPR_NONE) terms */
    numterms = 0;
    for (i=0; i<e->numterms; i++) {
        if (e->terms[i].type != YASM_EXPR_NONE)
            e->terms[numterms++] = e->terms[i]; /* structure copy */
    }
    if (e->numterms != numterms) {
        e->numterms = numterms;
        e = yasm_xrealloc(e, sizeof(yasm_expr)+((numterms<2) ? 0 :
                          sizeof(yasm_expr__item)*(numterms-2)));
        if (numterms == 1)
            e->op = YASM_EXPR_IDENT;
    }

    return e;
}