static int
bc_align_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
                /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
{
    bytecode_align *align = (bytecode_align *)bc->contents;
    unsigned long end;
    unsigned long boundary =
        yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, 0));

    if (boundary == 0) {
        bc->len = 0;
        *pos_thres = new_val;
        return 0;
    }

    end = (unsigned long)new_val;
    if ((unsigned long)new_val & (boundary-1))
        end = ((unsigned long)new_val & ~(boundary-1)) + boundary;

    *pos_thres = (long)end;
    bc->len = end - (unsigned long)new_val;

    if (align->maxskip) {
        unsigned long maxskip =
            yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, 0));
        if (bc->len > maxskip) {
            *pos_thres = (long)end-maxskip-1;
            bc->len = 0;
        }
    }
    return 1;
}
static void
bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
{
    bytecode_align *align = (bytecode_align *)bc->contents;
    if (!yasm_expr_get_intnum(&align->boundary, 0))
        yasm_error_set(YASM_ERROR_NOT_CONSTANT,
                       N_("align boundary must be a constant"));
    if (align->fill && !yasm_expr_get_intnum(&align->fill, 0))
        yasm_error_set(YASM_ERROR_NOT_CONSTANT,
                       N_("align fill must be a constant"));
    if (align->maxskip && !yasm_expr_get_intnum(&align->maxskip, 0))
        yasm_error_set(YASM_ERROR_NOT_CONSTANT,
                       N_("align maximum skip must be a constant"));
}
Example #3
0
static void
x86_dir_cpu(yasm_object *object, yasm_valparamhead *valparams,
            yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)object->arch;

    yasm_valparam *vp;
    yasm_vps_foreach(vp, valparams) {
        /*@null@*/ /*@dependent@*/ const char *s = yasm_vp_string(vp);
        if (s)
            yasm_x86__parse_cpu(arch_x86, s, strlen(s));
        else if (vp->type == YASM_PARAM_EXPR) {
            const yasm_intnum *intcpu;
            intcpu = yasm_expr_get_intnum(&vp->param.e, 0);
            if (!intcpu)
                yasm_error_set(YASM_ERROR_SYNTAX,
                               N_("invalid argument to [%s]"), "CPU");
            else {
                char strcpu[16];
                sprintf(strcpu, "%lu", yasm_intnum_get_uint(intcpu));
                yasm_x86__parse_cpu(arch_x86, strcpu, strlen(strcpu));
            }
        } else
            yasm_error_set(YASM_ERROR_SYNTAX, N_("invalid argument to [%s]"),
                           "CPU");
    }
}
Example #4
0
static int
bc_incbin_tobytes(yasm_bytecode *bc, unsigned char **bufp,
                  unsigned char *bufstart, void *d,
                  yasm_output_value_func output_value,
                  /*@unused@*/ yasm_output_reloc_func output_reloc)
{
    bytecode_incbin *incbin = (bytecode_incbin *)bc->contents;
    FILE *f;
    /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
    unsigned long start = 0;

    /* Convert start to integer value */
    if (incbin->start) {
        num = yasm_expr_get_intnum(&incbin->start, 0);
        if (!num)
            yasm_internal_error(
                N_("could not determine start in bc_tobytes_incbin"));
        start = yasm_intnum_get_uint(num);
    }

    /* Open file */
    f = yasm_fopen_include(incbin->filename, incbin->from, "rb", NULL);
    if (!f) {
        yasm_error_set(YASM_ERROR_IO, N_("`incbin': unable to open file `%s'"),
                       incbin->filename);
        return 1;
    }

    /* Seek to start of data */
    if (fseek(f, (long)start, SEEK_SET) < 0) {
        yasm_error_set(YASM_ERROR_IO,
                       N_("`incbin': unable to seek on file `%s'"),
                       incbin->filename);
        fclose(f);
        return 1;
    }

    /* Read len bytes */
    if (fread(*bufp, 1, (size_t)bc->len, f) < (size_t)bc->len) {
        yasm_error_set(YASM_ERROR_IO,
                       N_("`incbin': unable to read %lu bytes from file `%s'"),
                       bc->len, incbin->filename);
        fclose(f);
        return 1;
    }

    *bufp += bc->len;
    fclose(f);
    return 0;
}
int
yasm_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                 void *add_span_data)
{
    int retval = 0;

    bc->len = 0;

    if (!bc->callback)
        yasm_internal_error(N_("got empty bytecode in yasm_bc_calc_len"));
    else
        retval = bc->callback->calc_len(bc, add_span, add_span_data);

    /* Check for multiples */
    bc->mult_int = 1;
    if (bc->multiple) {
        /*@dependent@*/ /*@null@*/ const yasm_intnum *num;

        num = yasm_expr_get_intnum(&bc->multiple, 0);
        if (num) {
            if (yasm_intnum_sign(num) < 0) {
                yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative"));
                retval = -1;
            } else
                bc->mult_int = yasm_intnum_get_int(num);
        } else {
            if (yasm_expr__contains(bc->multiple, YASM_EXPR_FLOAT)) {
                yasm_error_set(YASM_ERROR_VALUE,
                    N_("expression must not contain floating point value"));
                retval = -1;
            } else {
                yasm_value value;
                yasm_value_initialize(&value, bc->multiple, 0);
                add_span(add_span_data, bc, 0, &value, 0, 0);
                bc->mult_int = 0;   /* assume 0 to start */
            }
        }
    }

    /* If we got an error somewhere along the line, clear out any calc len */
    if (retval < 0)
        bc->len = 0;

    return retval;
}
int
yasm_bc_get_multiple(yasm_bytecode *bc, long *multiple, int calc_bc_dist)
{
    /*@dependent@*/ /*@null@*/ const yasm_intnum *num;

    *multiple = 1;
    if (bc->multiple) {
        num = yasm_expr_get_intnum(&bc->multiple, calc_bc_dist);
        if (!num) {
            yasm_error_set(YASM_ERROR_VALUE,
                           N_("could not determine multiple"));
            return 1;
        }
        if (yasm_intnum_sign(num) < 0) {
            yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative"));
            return 1;
        }
        *multiple = yasm_intnum_get_int(num);
    }
    return 0;
}
Example #7
0
static void
x86_dir_bits(yasm_object *object, yasm_valparamhead *valparams,
             yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)object->arch;
    yasm_valparam *vp;
    /*@only@*/ /*@null@*/ yasm_expr *e = NULL;
    const yasm_intnum *intn;
    long lval;

    if ((vp = yasm_vps_first(valparams)) && !vp->val &&
        (e = yasm_vp_expr(vp, object->symtab, line)) != NULL &&
        (intn = yasm_expr_get_intnum(&e, 0)) != NULL &&
        (lval = yasm_intnum_get_int(intn)) &&
        (lval == 16 || lval == 32 || lval == 64))
        arch_x86->mode_bits = (unsigned char)lval;
    else
        yasm_error_set(YASM_ERROR_VALUE, N_("invalid argument to [%s]"),
                       "BITS");
    if (e)
        yasm_expr_destroy(e);
}
Example #8
0
int
yasm_dir_helper_intn(void *obj, yasm_valparam *vp, unsigned long line,
                     void *data, uintptr_t arg)
{
    yasm_object *object = (yasm_object *)obj;
    /*@only@*/ /*@null@*/ yasm_expr *e;
    /*@dependent@*/ /*@null@*/ yasm_intnum *local;
    yasm_intnum **intn = (yasm_intnum **)data;

    if (*intn)
        yasm_intnum_destroy(*intn);
    if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
        !(local = yasm_expr_get_intnum(&e, 0))) {
        yasm_error_set(YASM_ERROR_NOT_CONSTANT,
                       N_("argument to `%s' is not an integer"),
                       vp->val);
        if (e)
            yasm_expr_destroy(e);
        return -1;
    }
    *intn = yasm_intnum_copy(local);
    yasm_expr_destroy(e);
    return 0;
}
Example #9
0
static int
bc_incbin_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                   void *add_span_data)
{
    bytecode_incbin *incbin = (bytecode_incbin *)bc->contents;
    FILE *f;
    /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
    unsigned long start = 0, maxlen = 0xFFFFFFFFUL, flen;

    /* Try to convert start to integer value */
    if (incbin->start) {
        num = yasm_expr_get_intnum(&incbin->start, 0);
        if (num)
            start = yasm_intnum_get_uint(num);
        if (!num) {
            /* FIXME */
            yasm_error_set(YASM_ERROR_NOT_IMPLEMENTED,
                           N_("incbin does not yet understand non-constant"));
            return -1;
        }
    }

    /* Try to convert maxlen to integer value */
    if (incbin->maxlen) {
        num = yasm_expr_get_intnum(&incbin->maxlen, 0);
        if (num)
            maxlen = yasm_intnum_get_uint(num);
        if (!num) {
            /* FIXME */
            yasm_error_set(YASM_ERROR_NOT_IMPLEMENTED,
                           N_("incbin does not yet understand non-constant"));
            return -1;
        }
    }

    /* Open file and determine its length */
    f = yasm_fopen_include(incbin->filename, incbin->from, "rb", NULL);
    if (!f) {
        yasm_error_set(YASM_ERROR_IO,
                       N_("`incbin': unable to open file `%s'"),
                       incbin->filename);
        return -1;
    }
    if (fseek(f, 0L, SEEK_END) < 0) {
        yasm_error_set(YASM_ERROR_IO,
                       N_("`incbin': unable to seek on file `%s'"),
                       incbin->filename);
        return -1;
    }
    flen = (unsigned long)ftell(f);
    fclose(f);

    /* Compute length of incbin from start, maxlen, and len */
    if (start > flen) {
        yasm_warn_set(YASM_WARN_GENERAL,
                      N_("`incbin': start past end of file `%s'"),
                      incbin->filename);
        start = flen;
    }
    flen -= start;
    if (incbin->maxlen)
        if (maxlen < flen)
            flen = maxlen;
    bc->len += flen;
    return 0;
}
Example #10
0
int
yasm_value_output_basic(yasm_value *value, /*@out@*/ unsigned char *buf,
                        size_t destsize, yasm_bytecode *bc, int warn,
                        yasm_arch *arch)
{
    /*@dependent@*/ /*@null@*/ yasm_intnum *intn = NULL;
    /*@only@*/ yasm_intnum *outval;
    int sym_local;
    int retval = 1;
    unsigned int valsize = value->size;

    if (value->no_warn)
        warn = 0;

    if (value->abs) {
        /* Handle floating point expressions */
        if (!value->rel && value->abs->op == YASM_EXPR_IDENT
            && value->abs->terms[0].type == YASM_EXPR_FLOAT) {
            if (yasm_arch_floatnum_tobytes(arch, value->abs->terms[0].data.flt,
                                           buf, destsize, valsize, 0, warn))
                return -1;
            else
                return 1;
        }

        /* Check for complex float expressions */
        if (yasm_expr__contains(value->abs, YASM_EXPR_FLOAT)) {
            yasm_error_set(YASM_ERROR_FLOATING_POINT,
                           N_("floating point expression too complex"));
            return -1;
        }

        /* Handle normal integer expressions */
        intn = yasm_expr_get_intnum(&value->abs, 1);

        if (!intn) {
            /* Second try before erroring: yasm_expr_get_intnum doesn't handle
             * SEG:OFF, so try simplifying out any to just the OFF portion,
             * then getting the intnum again.
             */
            yasm_expr *seg = yasm_expr_extract_deep_segoff(&value->abs);
            if (seg)
                yasm_expr_destroy(seg);
            intn = yasm_expr_get_intnum(&value->abs, 1);
        }

        if (!intn) {
            /* Still don't have an integer! */
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("expression too complex"));
            return -1;
        }
    }

    /* Adjust warn for signed/unsigned integer warnings */
    if (warn != 0)
        warn = value->sign ? -1 : 1;

    if (value->rel) {
        /* If relative portion is not in bc section, don't try to handle it
         * here.  Otherwise get the relative portion's offset.
         */
        /*@dependent@*/ yasm_bytecode *rel_prevbc;
        unsigned long dist;

        sym_local = yasm_symrec_get_label(value->rel, &rel_prevbc);
        if (value->wrt || value->seg_of || value->section_rel || !sym_local)
            return 0;       /* we can't handle SEG, WRT, or external symbols */
        if (rel_prevbc->section != bc->section)
            return 0;       /* not in this section */
        if (!value->curpos_rel)
            return 0;       /* not PC-relative */

        /* Calculate value relative to current assembly position */
        dist = yasm_bc_next_offset(rel_prevbc);
        if (dist < bc->offset) {
            outval = yasm_intnum_create_uint(bc->offset - dist);
            yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL);
        } else {
            dist -= bc->offset;
            outval = yasm_intnum_create_uint(dist);
        }

        if (value->rshift > 0) {
            /*@only@*/ yasm_intnum *shamt =
                yasm_intnum_create_uint((unsigned long)value->rshift);
            yasm_intnum_calc(outval, YASM_EXPR_SHR, shamt);
            yasm_intnum_destroy(shamt);
        }
        /* Add in absolute portion */
        if (intn)
            yasm_intnum_calc(outval, YASM_EXPR_ADD, intn);
        /* Output! */
        if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize, 0,
                                     bc, warn))
            retval = -1;
        yasm_intnum_destroy(outval);
        return retval;
    }

    if (value->seg_of || value->rshift || value->curpos_rel || value->ip_rel
        || value->section_rel)
        return 0;   /* We can't handle this with just an absolute */

    if (intn) {
        /* Output just absolute portion */
        if (yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, 0, bc,
                                     warn))
            retval = -1;
    } else {
        /* No absolute or relative portions: output 0 */
        outval = yasm_intnum_create_uint(0);
        if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize, 0,
                                     bc, warn))
            retval = -1;
        yasm_intnum_destroy(outval);
    }
    return retval;
}
Example #11
0
yasm_intnum *
yasm_value_get_intnum(yasm_value *value, yasm_bytecode *bc, int calc_bc_dist)
{
    /*@dependent@*/ /*@null@*/ yasm_intnum *intn = NULL;
    /*@only@*/ yasm_intnum *outval;
    int sym_local;

    if (value->abs) {
        /* Handle integer expressions, if non-integer or too complex, return
         * NULL.
         */
        intn = yasm_expr_get_intnum(&value->abs, calc_bc_dist);
        if (!intn)
            return NULL;
    }

    if (value->rel) {
        /* If relative portion is not in bc section, return NULL.
         * Otherwise get the relative portion's offset.
         */
        /*@dependent@*/ yasm_bytecode *rel_prevbc;
        unsigned long dist;

        if (!bc)
            return NULL;    /* Can't calculate relative value */

        sym_local = yasm_symrec_get_label(value->rel, &rel_prevbc);
        if (value->wrt || value->seg_of || value->section_rel || !sym_local)
            return NULL;    /* we can't handle SEG, WRT, or external symbols */
        if (rel_prevbc->section != bc->section)
            return NULL;    /* not in this section */
        if (!value->curpos_rel)
            return NULL;    /* not PC-relative */

        /* Calculate value relative to current assembly position */
        dist = yasm_bc_next_offset(rel_prevbc);
        if (dist < bc->offset) {
            outval = yasm_intnum_create_uint(bc->offset - dist);
            yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL);
        } else {
            dist -= bc->offset;
            outval = yasm_intnum_create_uint(dist);
        }

        if (value->rshift > 0) {
            /*@only@*/ yasm_intnum *shamt =
                yasm_intnum_create_uint((unsigned long)value->rshift);
            yasm_intnum_calc(outval, YASM_EXPR_SHR, shamt);
            yasm_intnum_destroy(shamt);
        }
        /* Add in absolute portion */
        if (intn)
            yasm_intnum_calc(outval, YASM_EXPR_ADD, intn);
        return outval;
    }

    if (intn)
        return yasm_intnum_copy(intn);
    
    /* No absolute or relative portions: output 0 */
    return yasm_intnum_create_uint(0);
}
Example #12
0
static int
xdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
{
    /*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d;
    yasm_sym_vis vis = yasm_symrec_get_visibility(sym);

    assert(info != NULL);

    if (info->all_syms || vis != YASM_SYM_LOCAL) {
        /*@only@*/ char *name = yasm_symrec_get_global_name(sym, info->object);
        const yasm_expr *equ_val;
        const yasm_intnum *intn;
        size_t len = strlen(name);
        unsigned long value = 0;
        long scnum = -3;        /* -3 = debugging symbol */
        /*@dependent@*/ /*@null@*/ yasm_section *sect;
        /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
        unsigned long flags = 0;
        unsigned char *localbuf;

        if (vis & YASM_SYM_GLOBAL)
            flags = XDF_SYM_GLOBAL;

        /* Look at symrec for value/scnum/etc. */
        if (yasm_symrec_get_label(sym, &precbc)) {
            if (precbc)
                sect = yasm_bc_get_section(precbc);
            else
                sect = NULL;
            /* it's a label: get value and offset.
             * If there is not a section, leave as debugging symbol.
             */
            if (sect) {
                /*@dependent@*/ /*@null@*/ xdf_section_data *csectd;
                csectd = yasm_section_get_data(sect, &xdf_section_data_cb);
                if (csectd)
                    scnum = csectd->scnum;
                else
                    yasm_internal_error(N_("didn't understand section"));
                if (precbc)
                    value += yasm_bc_next_offset(precbc);
            }
        } else if ((equ_val = yasm_symrec_get_equ(sym))) {
            yasm_expr *equ_val_copy = yasm_expr_copy(equ_val);
            intn = yasm_expr_get_intnum(&equ_val_copy, 1);
            if (!intn) {
                if (vis & YASM_SYM_GLOBAL) {
                    yasm_error_set(YASM_ERROR_NOT_CONSTANT,
                        N_("global EQU value not an integer expression"));
                    yasm_errwarn_propagate(info->errwarns, equ_val->line);
                }
            } else
                value = yasm_intnum_get_uint(intn);
            yasm_expr_destroy(equ_val_copy);

            flags |= XDF_SYM_EQU;
            scnum = -2;     /* -2 = absolute symbol */
        } else {
            if (vis & YASM_SYM_EXTERN) {
                flags = XDF_SYM_EXTERN;
                scnum = -1;
            }
        }

        localbuf = info->buf;
        YASM_WRITE_32_L(localbuf, scnum);       /* section number */
        YASM_WRITE_32_L(localbuf, value);       /* value */
        YASM_WRITE_32_L(localbuf, info->strtab_offset);
        info->strtab_offset += (unsigned long)(len+1);
        YASM_WRITE_32_L(localbuf, flags);       /* flags */
        fwrite(info->buf, 16, 1, info->f);
        yasm_xfree(name);
    }
    return 0;
}
Example #13
0
static int
xdf_objfmt_output_value(yasm_value *value, unsigned char *buf,
                        unsigned int destsize, unsigned long offset,
                        yasm_bytecode *bc, int warn, /*@null@*/ void *d)
{
    /*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d;
    yasm_objfmt_xdf *objfmt_xdf;
    /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
    unsigned long intn_minus;
    int retval;
    unsigned int valsize = value->size;

    assert(info != NULL);
    objfmt_xdf = info->objfmt_xdf;

    if (value->abs)
        value->abs = yasm_expr_simplify(value->abs, 1);

    /* Try to output constant and PC-relative section-local first.
     * Note this does NOT output any value with a SEG, WRT, external,
     * cross-section, or non-PC-relative reference (those are handled below).
     */
    switch (yasm_value_output_basic(value, buf, destsize, bc, warn,
                                    info->object->arch)) {
        case -1:
            return 1;
        case 0:
            break;
        default:
            return 0;
    }

    if (value->section_rel) {
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("xdf: relocation too complex"));
        return 1;
    }

    intn_minus = 0;
    if (value->rel) {
        xdf_reloc *reloc;

        reloc = yasm_xmalloc(sizeof(xdf_reloc));
        reloc->reloc.addr = yasm_intnum_create_uint(bc->offset + offset);
        reloc->reloc.sym = value->rel;
        reloc->base = NULL;
        reloc->size = valsize/8;
        reloc->shift = value->rshift;

        if (value->seg_of)
            reloc->type = XDF_RELOC_SEG;
        else if (value->wrt) {
            reloc->base = value->wrt;
            reloc->type = XDF_RELOC_WRT;
        } else if (value->curpos_rel) {
            reloc->type = XDF_RELOC_RIP;
            /* Adjust to start of section, so subtract out the bytecode
             * offset.
             */
            intn_minus = bc->offset;
        } else
            reloc->type = XDF_RELOC_REL;
        info->xsd->nreloc++;
        yasm_section_add_reloc(info->sect, (yasm_reloc *)reloc, yasm_xfree);
    }

    if (intn_minus > 0) {
        intn = yasm_intnum_create_uint(intn_minus);
        yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
    } else
        intn = yasm_intnum_create_uint(0);

    if (value->abs) {
        yasm_intnum *intn2 = yasm_expr_get_intnum(&value->abs, 0);
        if (!intn2) {
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("xdf: relocation too complex"));
            yasm_intnum_destroy(intn);
            return 1;
        }
        yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2);
    }

    retval = yasm_arch_intnum_tobytes(info->object->arch, intn, buf, destsize,
                                      valsize, 0, bc, warn);
    yasm_intnum_destroy(intn);
    return retval;
}
static int
bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
                 yasm_output_value_func output_value,
                 /*@unused@*/ yasm_output_reloc_func output_reloc)
{
    bytecode_align *align = (bytecode_align *)bc->contents;
    unsigned long len;
    unsigned long boundary =
        yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, 0));

    if (boundary == 0)
        return 0;
    else {
        unsigned long end = bc->offset;
        if (bc->offset & (boundary-1))
            end = (bc->offset & ~(boundary-1)) + boundary;
        len = end - bc->offset;
        if (len == 0)
            return 0;
        if (align->maxskip) {
            unsigned long maxskip =
                yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, 0));
            if (len > maxskip)
                return 0;
        }
    }

    if (align->fill) {
        unsigned long v;
        v = yasm_intnum_get_uint(yasm_expr_get_intnum(&align->fill, 0));
        memset(*bufp, (int)v, len);
        *bufp += len;
    } else if (align->code_fill) {
        unsigned long maxlen = 15;
        while (!align->code_fill[maxlen] && maxlen>0)
            maxlen--;
        if (maxlen == 0) {
            yasm_error_set(YASM_ERROR_GENERAL,
                           N_("could not find any code alignment size"));
            return 1;
        }

        /* Fill with maximum code fill as much as possible */
        while (len > maxlen) {
            memcpy(*bufp, align->code_fill[maxlen], maxlen);
            *bufp += maxlen;
            len -= maxlen;
        }

        if (!align->code_fill[len]) {
            yasm_error_set(YASM_ERROR_VALUE,
                           N_("invalid alignment size %d"), len);
            return 1;
        }
        /* Handle rest of code fill */
        memcpy(*bufp, align->code_fill[len], len);
        *bufp += len;
    } else {
        /* Just fill with 0 */
        memset(*bufp, 0, len);
        *bufp += len;
    }
    return 0;
}