/*
 * Bytecode utility functions
 *
 *  Copyright (C) 2001  Peter Johnson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#define YASM_LIB_INTERNAL
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");

#include "file.h"

#include "errwarn.h"
#include "intnum.h"
#include "expr.h"

#include "bytecode.h"
#include "objfmt.h"

#include "arch.h"

#include "bc-int.h"
#include "expr-int.h"


struct yasm_dataval {
    /*@reldef@*/ STAILQ_ENTRY(yasm_dataval) link;

    enum { DV_EMPTY, DV_EXPR, DV_STRING } type;

    union {
	/*@only@*/ yasm_expr *expn;
	/*@only@*/ char *str_val;
    } data;
};

typedef struct bytecode_data {
    yasm_bytecode bc;	/* base structure */

    /* non-converted data (linked list) */
    yasm_datavalhead datahead;

    /* final (converted) size of each element (in bytes) */
    unsigned char size;
} bytecode_data;

typedef struct bytecode_reserve {
    yasm_bytecode bc;   /* base structure */

    /*@only@*/ yasm_expr *numitems; /* number of items to reserve */
    unsigned char itemsize;	    /* size of each item (in bytes) */
} bytecode_reserve;

typedef struct bytecode_incbin {
    yasm_bytecode bc;   /* base structure */

    /*@only@*/ char *filename;		/* file to include data from */

    /* starting offset to read from (NULL=0) */
    /*@only@*/ /*@null@*/ yasm_expr *start;

    /* maximum number of bytes to read (NULL=no limit) */
    /*@only@*/ /*@null@*/ yasm_expr *maxlen;
} bytecode_incbin;

typedef struct bytecode_align {
    yasm_bytecode bc;   /* base structure */

    unsigned long boundary;	/* alignment boundary */
} bytecode_align;

typedef struct bytecode_objfmt_data {
    yasm_bytecode bc;   /* base structure */

    unsigned int type;			/* objfmt-specific type */
    /*@dependent@*/ yasm_objfmt *of;	/* objfmt that created the data */
    /*@only@*/ void *data;		/* objfmt-specific data */
} bytecode_objfmt_data;

/* Static structures for when NULL is passed to conversion functions. */
/*  for Convert*ToBytes() */
unsigned char bytes_static[16];

/*@dependent@*/ static yasm_arch *cur_arch;


void
yasm_bc_initialize(yasm_arch *a)
{
    cur_arch = a;
}

yasm_immval *
yasm_imm_new_int(unsigned long int_val, unsigned long lindex)
{
    return yasm_imm_new_expr(
	yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(int_val)),
			    lindex));
}

yasm_immval *
yasm_imm_new_expr(yasm_expr *expr_ptr)
{
    yasm_immval *im = yasm_xmalloc(sizeof(yasm_immval));

    im->val = expr_ptr;
    im->len = 0;
    im->sign = 0;

    return im;
}

const yasm_expr *
yasm_ea_get_disp(const yasm_effaddr *ptr)
{
    return ptr->disp;
}

void
yasm_ea_set_len(yasm_effaddr *ptr, unsigned int len)
{
    if (!ptr)
	return;

    /* Currently don't warn if length truncated, as this is called only from
     * an explicit override, where we expect the user knows what they're doing.
     */

    ptr->len = (unsigned char)len;
}

void
yasm_ea_set_nosplit(yasm_effaddr *ptr, unsigned int nosplit)
{
    if (!ptr)
	return;

    ptr->nosplit = (unsigned char)nosplit;
}

/*@-nullstate@*/
void
yasm_ea_delete(yasm_effaddr *ea)
{
    if (cur_arch->ea_data_delete)
	cur_arch->ea_data_delete(ea);
    yasm_expr_delete(ea->disp);
    yasm_xfree(ea);
}
/*@=nullstate@*/

/*@-nullstate@*/
void
yasm_ea_print(FILE *f, int indent_level, const yasm_effaddr *ea)
{
    fprintf(f, "%*sDisp=", indent_level, "");
    yasm_expr_print(f, ea->disp);
    fprintf(f, "\n%*sLen=%u\n", indent_level, "", (unsigned int)ea->len);
    fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit);
    if (cur_arch->ea_data_print)
	cur_arch->ea_data_print(f, indent_level, ea);
}
/*@=nullstate@*/

void
yasm_bc_set_multiple(yasm_bytecode *bc, yasm_expr *e)
{
    if (bc->multiple)
	bc->multiple = yasm_expr_new_tree(bc->multiple, YASM_EXPR_MUL, e,
					  e->line);
    else
	bc->multiple = e;
}

yasm_bytecode *
yasm_bc_new_common(yasm_bytecode_type type, size_t size, unsigned long lindex)
{
    yasm_bytecode *bc = yasm_xmalloc(size);

    bc->type = type;

    bc->multiple = (yasm_expr *)NULL;
    bc->len = 0;

    bc->line = lindex;

    bc->offset = 0;

    bc->opt_flags = 0;

    return bc;
}

yasm_bytecode *
yasm_bc_new_data(yasm_datavalhead *datahead, unsigned int size,
		 unsigned long lindex)
{
    bytecode_data *data;

    data = (bytecode_data *)
	yasm_bc_new_common(YASM_BC__DATA, sizeof(bytecode_data), lindex);

    data->datahead = *datahead;
    data->size = (unsigned char)size;

    return (yasm_bytecode *)data;
}

yasm_bytecode *
yasm_bc_new_reserve(yasm_expr *numitems, unsigned int itemsize,
		    unsigned long lindex)
{
    bytecode_reserve *reserve;

    reserve = (bytecode_reserve *)
	yasm_bc_new_common(YASM_BC__RESERVE, sizeof(bytecode_reserve), lindex);

    /*@-mustfree@*/
    reserve->numitems = numitems;
    /*@=mustfree@*/
    reserve->itemsize = (unsigned char)itemsize;

    return (yasm_bytecode *)reserve;
}

yasm_bytecode *
yasm_bc_new_incbin(char *filename, yasm_expr *start, yasm_expr *maxlen,
		   unsigned long lindex)
{
    bytecode_incbin *incbin;

    incbin = (bytecode_incbin *)
	yasm_bc_new_common(YASM_BC__INCBIN, sizeof(bytecode_incbin), lindex);

    /*@-mustfree@*/
    incbin->filename = filename;
    incbin->start = start;
    incbin->maxlen = maxlen;
    /*@=mustfree@*/

    return (yasm_bytecode *)incbin;
}

yasm_bytecode *
yasm_bc_new_align(unsigned long boundary, unsigned long lindex)
{
    bytecode_align *align;

    align = (bytecode_align *)
	yasm_bc_new_common(YASM_BC__ALIGN, sizeof(bytecode_align), lindex);

    align->boundary = boundary;

    return (yasm_bytecode *)align;
}

yasm_bytecode *
yasm_bc_new_objfmt_data(unsigned int type, unsigned long len, yasm_objfmt *of,
			void *data, unsigned long lindex)
{
    bytecode_objfmt_data *objfmt_data;

    objfmt_data = (bytecode_objfmt_data *)
	yasm_bc_new_common(YASM_BC__OBJFMT_DATA, sizeof(bytecode_objfmt_data),
			   lindex);

    objfmt_data->type = type;
    objfmt_data->of = of;
    /*@-mustfree@*/
    objfmt_data->data = data;
    /*@=mustfree@*/

    /* Yes, this breaks the paradigm just a little.  But this data is very
     * unlike other bytecode data--it's internally generated after the
     * other bytecodes have been resolved, and the length is ALWAYS known.
     */
    objfmt_data->bc.len = len;

    return (yasm_bytecode *)objfmt_data;
}

void
yasm_bc_delete(yasm_bytecode *bc)
{
    bytecode_data *data;
    bytecode_reserve *reserve;
    bytecode_incbin *incbin;
    bytecode_objfmt_data *objfmt_data;

    if (!bc)
	return;

    /*@-branchstate@*/
    switch (bc->type) {
	case YASM_BC__EMPTY:
	    break;
	case YASM_BC__DATA:
	    data = (bytecode_data *)bc;
	    yasm_dvs_delete(&data->datahead);
	    break;
	case YASM_BC__RESERVE:
	    reserve = (bytecode_reserve *)bc;
	    yasm_expr_delete(reserve->numitems);
	    break;
	case YASM_BC__INCBIN:
	    incbin = (bytecode_incbin *)bc;
	    yasm_xfree(incbin->filename);
	    yasm_expr_delete(incbin->start);
	    yasm_expr_delete(incbin->maxlen);
	    break;
	case YASM_BC__ALIGN:
	    break;
	case YASM_BC__OBJFMT_DATA:
	    objfmt_data = (bytecode_objfmt_data *)bc;
	    if (objfmt_data->of->bc_objfmt_data_delete)
		objfmt_data->of->bc_objfmt_data_delete(objfmt_data->type,
						       objfmt_data->data);
	    else
		yasm_internal_error(
		    N_("objfmt can't handle its own objfmt data bytecode"));
	    break;
	default:
	    if ((unsigned int)bc->type < (unsigned int)cur_arch->bc.type_max)
		cur_arch->bc.bc_delete(bc);
	    else
		yasm_internal_error(N_("Unknown bytecode type"));
	    break;
    }
    /*@=branchstate@*/

    yasm_expr_delete(bc->multiple);
    yasm_xfree(bc);
}

void
yasm_bc_print(FILE *f, int indent_level, const yasm_bytecode *bc)
{
    const bytecode_data *data;
    const bytecode_reserve *reserve;
    const bytecode_incbin *incbin;
    const bytecode_align *align;
    const bytecode_objfmt_data *objfmt_data;

    switch (bc->type) {
	case YASM_BC__EMPTY:
	    fprintf(f, "%*s_Empty_\n", indent_level, "");
	    break;
	case YASM_BC__DATA:
	    data = (const bytecode_data *)bc;
	    fprintf(f, "%*s_Data_\n", indent_level, "");
	    fprintf(f, "%*sFinal Element Size=%u\n", indent_level+1, "",
		    (unsigned int)data->size);
	    fprintf(f, "%*sElements:\n", indent_level+1, "");
	    yasm_dvs_print(f, indent_level+2, &data->datahead);
	    break;
	case YASM_BC__RESERVE:
	    reserve = (const bytecode_reserve *)bc;
	    fprintf(f, "%*s_Reserve_\n", indent_level, "");
	    fprintf(f, "%*sNum Items=", indent_level, "");
	    yasm_expr_print(f, reserve->numitems);
	    fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
		    (unsigned int)reserve->itemsize);
	    break;
	case YASM_BC__INCBIN:
	    incbin = (const bytecode_incbin *)bc;
	    fprintf(f, "%*s_IncBin_\n", indent_level, "");
	    fprintf(f, "%*sFilename=`%s'\n", indent_level, "",
		    incbin->filename);
	    fprintf(f, "%*sStart=", indent_level, "");
	    if (!incbin->start)
		fprintf(f, "nil (0)");
	    else
		yasm_expr_print(f, incbin->start);
	    fprintf(f, "%*sMax Len=", indent_level, "");
	    if (!incbin->maxlen)
		fprintf(f, "nil (unlimited)");
	    else
		yasm_expr_print(f, incbin->maxlen);
	    fprintf(f, "\n");
	    break;
	case YASM_BC__ALIGN:
	    align = (const bytecode_align *)bc;
	    fprintf(f, "%*s_Align_\n", indent_level, "");
	    fprintf(f, "%*sBoundary=%lu\n", indent_level, "", align->boundary);
	    break;
	case YASM_BC__OBJFMT_DATA:
	    objfmt_data = (const bytecode_objfmt_data *)bc;
	    fprintf(f, "%*s_ObjFmt_Data_\n", indent_level, "");
	    if (objfmt_data->of->bc_objfmt_data_print)
		objfmt_data->of->bc_objfmt_data_print(f, indent_level,
						      objfmt_data->type,
						      objfmt_data->data);
	    else
		fprintf(f, "%*sUNKNOWN\n", indent_level, "");
	    break;
	default:
	    if ((unsigned int)bc->type < (unsigned int)cur_arch->bc.type_max)
		cur_arch->bc.bc_print(f, indent_level, bc);
	    else
		fprintf(f, "%*s_Unknown_\n", indent_level, "");
	    break;
    }
    fprintf(f, "%*sMultiple=", indent_level, "");
    if (!bc->multiple)
	fprintf(f, "nil (1)");
    else
	yasm_expr_print(f, bc->multiple);
    fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
    fprintf(f, "%*sLine Index=%lu\n", indent_level, "", bc->line);
    fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
}

/*@null@*/ yasm_intnum *
yasm_common_calc_bc_dist(yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
			 /*@null@*/ yasm_bytecode *precbc2)
{
    unsigned int dist;
    yasm_intnum *intn;

    if (precbc2) {
	dist = precbc2->offset + precbc2->len;
	if (precbc1) {
	    if (dist < precbc1->offset + precbc1->len) {
		intn = yasm_intnum_new_uint(precbc1->offset + precbc1->len
					    - dist);
		yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
		return intn;
	    }
	    dist -= precbc1->offset + precbc1->len;
	}
	return yasm_intnum_new_uint(dist);
    } else {
	if (precbc1) {
	    intn = yasm_intnum_new_uint(precbc1->offset + precbc1->len);
	    yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
	    return intn;
	} else {
	    return yasm_intnum_new_uint(0);
	}
    }
}

static yasm_bc_resolve_flags
bc_resolve_data(bytecode_data *bc_data, unsigned long *len)
{
    yasm_dataval *dv;
    size_t slen;

    /* Count up element sizes, rounding up string length. */
    STAILQ_FOREACH(dv, &bc_data->datahead, link) {
	switch (dv->type) {
	    case DV_EMPTY:
		break;
	    case DV_EXPR:
		*len += bc_data->size;
		break;
	    case DV_STRING:
		slen = strlen(dv->data.str_val);
		/* find count, rounding up to nearest multiple of size */
		slen = (slen + bc_data->size - 1) / bc_data->size;
		*len += slen*bc_data->size;
		break;
	}
    }

    return YASM_BC_RESOLVE_MIN_LEN;
}

static yasm_bc_resolve_flags
bc_resolve_reserve(bytecode_reserve *reserve, unsigned long *len,
		   int save, unsigned long line, const yasm_section *sect,
		   yasm_calc_bc_dist_func calc_bc_dist)
{
    yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
    /*@null@*/ yasm_expr *temp;
    yasm_expr **tempp;
    /*@dependent@*/ /*@null@*/ const yasm_intnum *num;

    if (save) {
	temp = NULL;
	tempp = &reserve->numitems;
    } else {
	temp = yasm_expr_copy(reserve->numitems);
	assert(temp != NULL);
	tempp = &temp;
    }
    num = yasm_expr_get_intnum(tempp, calc_bc_dist);
    if (!num) {
	/* For reserve, just say non-constant quantity instead of allowing
	 * the circular reference error to filter through.
	 */
	if (temp && yasm_expr__contains(temp, YASM_EXPR_FLOAT))
	    yasm__error(line,
		N_("expression must not contain floating point value"));
	else
	    yasm__error(line,
		N_("attempt to reserve non-constant quantity of space"));
	retval = YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
    } else
	*len += yasm_intnum_get_uint(num)*reserve->itemsize;
    yasm_expr_delete(temp);
    return retval;
}

static yasm_bc_resolve_flags
bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
		  unsigned long line, const yasm_section *sect,
		  yasm_calc_bc_dist_func calc_bc_dist)
{
    FILE *f;
    /*@null@*/ yasm_expr *temp;
    yasm_expr **tempp;
    /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
    unsigned long start = 0, maxlen = 0xFFFFFFFFUL, flen;

    /* Try to convert start to integer value */
    if (incbin->start) {
	if (save) {
	    temp = NULL;
	    tempp = &incbin->start;
	} else {
	    temp = yasm_expr_copy(incbin->start);
	    assert(temp != NULL);
	    tempp = &temp;
	}
	num = yasm_expr_get_intnum(tempp, calc_bc_dist);
	if (num)
	    start = yasm_intnum_get_uint(num);
	yasm_expr_delete(temp);
	if (!num)
	    return YASM_BC_RESOLVE_UNKNOWN_LEN;
    }

    /* Try to convert maxlen to integer value */
    if (incbin->maxlen) {
	if (save) {
	    temp = NULL;
	    tempp = &incbin->maxlen;
	} else {
	    temp = yasm_expr_copy(incbin->maxlen);
	    assert(temp != NULL);
	    tempp = &temp;
	}
	num = yasm_expr_get_intnum(tempp, calc_bc_dist);
	if (num)
	    maxlen = yasm_intnum_get_uint(num);
	yasm_expr_delete(temp);
	if (!num)
	    return YASM_BC_RESOLVE_UNKNOWN_LEN;
    }

    /* FIXME: Search include path for filename.  Save full path back into
     * filename if save is true.
     */

    /* Open file and determine its length */
    f = fopen(incbin->filename, "rb");
    if (!f) {
	yasm__error(line, N_("`incbin': unable to open file `%s'"),
		    incbin->filename);
	return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
    }
    if (fseek(f, 0L, SEEK_END) < 0) {
	yasm__error(line, N_("`incbin': unable to seek on file `%s'"),
		    incbin->filename);
	return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
    }
    flen = (unsigned long)ftell(f);
    fclose(f);

    /* Compute length of incbin from start, maxlen, and len */
    if (start > flen) {
	yasm__warning(YASM_WARN_GENERAL, line,
		      N_("`incbin': start past end of file `%s'"),
		      incbin->filename);
	start = flen;
    }
    flen -= start;
    if (incbin->maxlen)
	if (maxlen < flen)
	    flen = maxlen;
    *len += flen;
    return YASM_BC_RESOLVE_MIN_LEN;
}

yasm_bc_resolve_flags
yasm_bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
		yasm_calc_bc_dist_func calc_bc_dist)
{
    yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
    /*@null@*/ yasm_expr *temp;
    yasm_expr **tempp;
    /*@dependent@*/ /*@null@*/ const yasm_intnum *num;

    bc->len = 0;	/* start at 0 */

    switch (bc->type) {
	case YASM_BC__EMPTY:
	    yasm_internal_error(N_("got empty bytecode in bc_calc_len"));
	    /*break;*/
	case YASM_BC__DATA:
	    retval = bc_resolve_data((bytecode_data *)bc, &bc->len);
	    break;
	case YASM_BC__RESERVE:
	    retval = bc_resolve_reserve((bytecode_reserve *)bc, &bc->len,
					save, bc->line, sect, calc_bc_dist);
	    break;
	case YASM_BC__INCBIN:
	    retval = bc_resolve_incbin((bytecode_incbin *)bc, &bc->len,
				       save, bc->line, sect, calc_bc_dist);
	    break;
	case YASM_BC__ALIGN:
	    /* TODO */
	    yasm_internal_error(N_("TODO: align bytecode not implemented!"));
	    /*break;*/
	case YASM_BC__OBJFMT_DATA:
	    yasm_internal_error(N_("resolving objfmt data bytecode?"));
	    /*break;*/
	default:
	    if ((unsigned int)bc->type < (unsigned int)cur_arch->bc.type_max)
		retval = cur_arch->bc.bc_resolve(bc, save, sect,
						 calc_bc_dist);
	    else
		yasm_internal_error(N_("Unknown bytecode type"));
    }

    /* Multiply len by number of multiples */
    if (bc->multiple) {
	if (save) {
	    temp = NULL;
	    tempp = &bc->multiple;
	} else {
	    temp = yasm_expr_copy(bc->multiple);
	    assert(temp != NULL);
	    tempp = &temp;
	}
	num = yasm_expr_get_intnum(tempp, calc_bc_dist);
	if (!num) {
	    retval = YASM_BC_RESOLVE_UNKNOWN_LEN;
	    if (temp && yasm_expr__contains(temp, YASM_EXPR_FLOAT)) {
		yasm__error(bc->line,
		    N_("expression must not contain floating point value"));
		retval |= YASM_BC_RESOLVE_ERROR;
	    }
	} else
	    bc->len *= yasm_intnum_get_uint(num);
	yasm_expr_delete(temp);
    }

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

    return retval;
}

static int
bc_tobytes_data(bytecode_data *bc_data, unsigned char **bufp,
		const yasm_section *sect, yasm_bytecode *bc, void *d,
		yasm_output_expr_func output_expr)
    /*@sets **bufp@*/
{
    yasm_dataval *dv;
    size_t slen;
    size_t i;
    unsigned char *bufp_orig = *bufp;

    STAILQ_FOREACH(dv, &bc_data->datahead, link) {
	switch (dv->type) {
	    case DV_EMPTY:
		break;
	    case DV_EXPR:
		if (output_expr(&dv->data.expn, bufp, bc_data->size,
				(unsigned long)(*bufp-bufp_orig), sect, bc, 0,
				d))
		    return 1;
		break;
	    case DV_STRING:
		slen = strlen(dv->data.str_val);
		strncpy((char *)*bufp, dv->data.str_val, slen);
		*bufp += slen;
		/* pad with 0's to nearest multiple of size */
		slen %= bc_data->size;
		if (slen > 0) {
		    slen = bc_data->size-slen;
		    for (i=0; i<slen; i++)
			YASM_WRITE_8(*bufp, 0);
		}
		break;
	}
    }

    return 0;
}

static int
bc_tobytes_incbin(bytecode_incbin *incbin, unsigned char **bufp,
		  unsigned long len, unsigned long line)
    /*@sets **bufp@*/
{
    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, NULL);
	if (!num)
	    yasm_internal_error(
		N_("could not determine start in bc_tobytes_incbin"));
	start = yasm_intnum_get_uint(num);
    }

    /* Open file */
    f = fopen(incbin->filename, "rb");
    if (!f) {
	yasm__error(line, 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(line, N_("`incbin': unable to seek on file `%s'"),
		    incbin->filename);
	fclose(f);
	return 1;
    }

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

    *bufp += len;
    fclose(f);
    return 0;
}

/*@null@*/ /*@only@*/ unsigned char *
yasm_bc_tobytes(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
		/*@out@*/ unsigned long *multiple, /*@out@*/ int *gap,
		const yasm_section *sect, void *d,
		yasm_output_expr_func output_expr,
		/*@null@*/ yasm_output_bc_objfmt_data_func
		    output_bc_objfmt_data)
    /*@sets *buf@*/
{
    /*@only@*/ /*@null@*/ unsigned char *mybuf = NULL;
    unsigned char *origbuf, *destbuf;
    /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
    bytecode_objfmt_data *objfmt_data;
    unsigned long datasize;
    int error = 0;

    if (bc->multiple) {
	num = yasm_expr_get_intnum(&bc->multiple, NULL);
	if (!num)
	    yasm_internal_error(
		N_("could not determine multiple in bc_tobytes"));
	*multiple = yasm_intnum_get_uint(num);
	if (*multiple == 0) {
	    *bufsize = 0;
	    return NULL;
	}
    } else
	*multiple = 1;

    datasize = bc->len / (*multiple);
    *bufsize = datasize;

    if (bc->type == YASM_BC__RESERVE) {
	*gap = 1;
	return NULL;	/* we didn't allocate a buffer */
    }

    *gap = 0;

    if (*bufsize < datasize) {
	mybuf = yasm_xmalloc(sizeof(bc->len));
	origbuf = mybuf;
	destbuf = mybuf;
    } else {
	origbuf = buf;
	destbuf = buf;
    }

    switch (bc->type) {
	case YASM_BC__EMPTY:
	    yasm_internal_error(N_("got empty bytecode in bc_tobytes"));
	    /*break;*/
	case YASM_BC__DATA:
	    error = bc_tobytes_data((bytecode_data *)bc, &destbuf, sect, bc, d,
				    output_expr);
	    break;
	case YASM_BC__INCBIN:
	    error = bc_tobytes_incbin((bytecode_incbin *)bc, &destbuf, bc->len,
				      bc->line);
	    break;
	case YASM_BC__ALIGN:
	    /* TODO */
	    yasm_internal_error(N_("TODO: align bytecode not implemented!"));
	    /*break;*/
	case YASM_BC__OBJFMT_DATA:
	    objfmt_data = (bytecode_objfmt_data *)bc;
	    if (output_bc_objfmt_data)
		error = output_bc_objfmt_data(objfmt_data->type,
					      objfmt_data->data, &destbuf);
	    else
		yasm_internal_error(
		    N_("Have objfmt data bytecode but no way to output it"));
	    break;
	default:
	    if ((unsigned int)bc->type < (unsigned int)cur_arch->bc.type_max)
		error = cur_arch->bc.bc_tobytes(bc, &destbuf, sect, d,
						output_expr);
	    else
		yasm_internal_error(N_("Unknown bytecode type"));
    }

    if (!error && ((unsigned long)(destbuf - origbuf) != datasize))
	yasm_internal_error(
	    N_("written length does not match optimized length"));
    return mybuf;
}

yasm_bytecode *
yasm_bcs_last(yasm_bytecodehead *headp)
{
    return STAILQ_LAST(headp, yasm_bytecode, link);
}

void
yasm_bcs_delete(yasm_bytecodehead *headp)
{
    yasm_bytecode *cur, *next;

    cur = STAILQ_FIRST(headp);
    while (cur) {
	next = STAILQ_NEXT(cur, link);
	yasm_bc_delete(cur);
	cur = next;
    }
    STAILQ_INIT(headp);
}

yasm_bytecode *
yasm_bcs_append(yasm_bytecodehead *headp, yasm_bytecode *bc)
{
    if (bc) {
	if (bc->type != YASM_BC__EMPTY) {
	    STAILQ_INSERT_TAIL(headp, bc, link);
	    return bc;
	} else {
	    yasm_xfree(bc);
	}
    }
    return (yasm_bytecode *)NULL;
}

void
yasm_bcs_print(FILE *f, int indent_level, const yasm_bytecodehead *headp)
{
    yasm_bytecode *cur;

    STAILQ_FOREACH(cur, headp, link) {
	fprintf(f, "%*sNext Bytecode:\n", indent_level, "");
	yasm_bc_print(f, indent_level+1, cur);
    }
}

int
yasm_bcs_traverse(yasm_bytecodehead *headp, void *d,
		  int (*func) (yasm_bytecode *bc, /*@null@*/ void *d))
{
    yasm_bytecode *cur;

    STAILQ_FOREACH(cur, headp, link) {
	int retval = func(cur, d);
	if (retval != 0)
	    return retval;
    }
    return 0;
}

yasm_dataval *
yasm_dv_new_expr(yasm_expr *expn)
{
    yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));

    retval->type = DV_EXPR;
    retval->data.expn = expn;

    return retval;
}

yasm_dataval *
yasm_dv_new_string(char *str_val)
{
    yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));

    retval->type = DV_STRING;
    retval->data.str_val = str_val;

    return retval;
}

void
yasm_dvs_delete(yasm_datavalhead *headp)
{
    yasm_dataval *cur, *next;

    cur = STAILQ_FIRST(headp);
    while (cur) {
	next = STAILQ_NEXT(cur, link);
	switch (cur->type) {
	    case DV_EXPR:
		yasm_expr_delete(cur->data.expn);
		break;
	    case DV_STRING:
		yasm_xfree(cur->data.str_val);
		break;
	    default:
		break;
	}
	yasm_xfree(cur);
	cur = next;
    }
    STAILQ_INIT(headp);
}

yasm_dataval *
yasm_dvs_append(yasm_datavalhead *headp, yasm_dataval *dv)
{
    if (dv) {
	STAILQ_INSERT_TAIL(headp, dv, link);
	return dv;
    }
    return (yasm_dataval *)NULL;
}

void
yasm_dvs_print(FILE *f, int indent_level, const yasm_datavalhead *head)
{
    yasm_dataval *cur;

    STAILQ_FOREACH(cur, head, link) {
	switch (cur->type) {
	    case DV_EMPTY:
		fprintf(f, "%*sEmpty\n", indent_level, "");
		break;
	    case DV_EXPR:
		fprintf(f, "%*sExpr=", indent_level, "");
		yasm_expr_print(f, cur->data.expn);
		fprintf(f, "\n");
		break;
	    case DV_STRING:
		fprintf(f, "%*sString=%s\n", indent_level, "",
			cur->data.str_val);
		break;
	}
    }
}

/* Non-macro yasm_bcs_initialize() for non-YASM_INTERNAL users. */
#undef yasm_bcs_initialize
void
yasm_bcs_initialize(yasm_bytecodehead *headp)
{
    STAILQ_INIT(headp);
}

/* Non-macro yasm_bcs_first() for non-YASM_INTERNAL users. */
#undef yasm_bcs_first
yasm_bytecode *
yasm_bcs_first(yasm_bytecodehead *headp)
{
    return STAILQ_FIRST(headp);
}

/* Non-macro yasm_dvs_initialize() for non-YASM_INTERNAL users. */
#undef yasm_dvs_initialize
void
yasm_dvs_initialize(yasm_datavalhead *headp)
{
    STAILQ_INIT(headp);
}
