/*
 * Flat-format binary object format
 *
 *  Copyright (C) 2002-2007  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.
 */
#include <util.h>
/*@unused@*/ RCSID("$Id: bin-objfmt.c,v 1.1.1.1 2012/03/29 17:21:03 uid42307 Exp $");

#include <libyasm.h>


#define REGULAR_OUTBUF_SIZE     1024

typedef struct bin_section_data {
    int bss;                    /* aka nobits */

    /* User-provided alignment */
    yasm_intnum *align, *valign;

    /* User-provided starts */
    /*@null@*/ /*@owned@*/ yasm_expr *start, *vstart;

    /* User-provided follows */
    /*@null@*/ /*@owned@*/ char *follows, *vfollows;

    /* Calculated (final) starts, used only during output() */
    /*@null@*/ /*@owned@*/ yasm_intnum *istart, *ivstart;

    /* Calculated (final) length, used only during output() */
    /*@null@*/ /*@owned@*/ yasm_intnum *length;
} bin_section_data;

typedef struct yasm_objfmt_bin {
    yasm_objfmt_base objfmt;            /* base structure */

    enum {
        NO_MAP = 0,
        MAP_NONE = 0x01,
        MAP_BRIEF = 0x02,
        MAP_SECTIONS = 0x04,
        MAP_SYMBOLS = 0x08
    } map_flags;
    /*@null@*/ /*@only@*/ char *map_filename;

    /*@null@*/ /*@only@*/ yasm_expr *org;
} yasm_objfmt_bin;

/* symrec data is used only for the special symbols section<sectname>.start,
 * section<sectname>.vstart, and section<sectname>.length
 */
typedef struct bin_symrec_data {
    yasm_section *section;          /* referenced section */
    enum bin_ssym {
        SSYM_START,
        SSYM_VSTART,
        SSYM_LENGTH
    } which;
} bin_symrec_data;

static void bin_section_data_destroy(/*@only@*/ void *d);
static void bin_section_data_print(void *data, FILE *f, int indent_level);

static const yasm_assoc_data_callback bin_section_data_cb = {
    bin_section_data_destroy,
    bin_section_data_print
};

static void bin_symrec_data_destroy(/*@only@*/ void *d);
static void bin_symrec_data_print(void *data, FILE *f, int indent_level);

static const yasm_assoc_data_callback bin_symrec_data_cb = {
    bin_symrec_data_destroy,
    bin_symrec_data_print
};

yasm_objfmt_module yasm_bin_LTX_objfmt;


static yasm_objfmt *
bin_objfmt_create(yasm_object *object)
{
    yasm_objfmt_bin *objfmt_bin = yasm_xmalloc(sizeof(yasm_objfmt_bin));
    objfmt_bin->objfmt.module = &yasm_bin_LTX_objfmt;

    objfmt_bin->map_flags = NO_MAP;
    objfmt_bin->map_filename = NULL;
    objfmt_bin->org = NULL;

    return (yasm_objfmt *)objfmt_bin;
}

typedef TAILQ_HEAD(, bin_group) bin_groups;

typedef struct bin_group {
    TAILQ_ENTRY(bin_group) link;
    yasm_section *section;
    bin_section_data *bsd;

    /* Groups that (in parallel) logically come immediately after this
     * group's section.
     */
    bin_groups follow_groups;
} bin_group;

/* Recursive function to find group containing named section. */
static bin_group *
find_group_by_name(bin_groups *groups, const char *name)
{
    bin_group *group, *found;
    TAILQ_FOREACH(group, groups, link) {
        if (strcmp(yasm_section_get_name(group->section), name) == 0)
            return group;
        /* Recurse to loop through follow groups */
        found = find_group_by_name(&group->follow_groups, name);
        if (found)
            return found;
    }
    return NULL;
}

/* Recursive function to find group.  Returns NULL if not found. */
static bin_group *
find_group_by_section(bin_groups *groups, yasm_section *section)
{
    bin_group *group, *found;
    TAILQ_FOREACH(group, groups, link) {
        if (group->section == section)
            return group;
        /* Recurse to loop through follow groups */
        found = find_group_by_section(&group->follow_groups, section);
        if (found)
            return found;
    }
    return NULL;
}

static void
print_groups(const bin_groups *groups, int indent_level)
{
    bin_group *group;
    TAILQ_FOREACH(group, groups, link) {
        printf("%*sSection `%s':\n", indent_level, "",
               yasm_section_get_name(group->section));
        bin_section_data_print(group->bsd, stdout, indent_level+1);
        if (!TAILQ_EMPTY(&group->follow_groups)) {
            printf("%*sFollowing groups:\n", indent_level, "");
            print_groups(&group->follow_groups, indent_level+1);
        }
    }
}

static void
bin_group_destroy(/*@only@*/ bin_group *group)
{
    bin_group *follow, *group_temp;
    TAILQ_FOREACH_SAFE(follow, &group->follow_groups, link, group_temp)
        bin_group_destroy(follow);
    yasm_xfree(group);
}

typedef struct bin_objfmt_output_info {
    yasm_object *object;
    yasm_errwarns *errwarns;
    /*@dependent@*/ FILE *f;
    /*@only@*/ unsigned char *buf;
    /*@observer@*/ const yasm_section *sect;
    unsigned long start;        /* what normal variables go against */

    yasm_intnum *origin;
    yasm_intnum *tmp_intn;      /* temporary working intnum */

    bin_groups lma_groups, vma_groups;
} bin_objfmt_output_info;

static int
bin_objfmt_check_sym(yasm_symrec *sym, /*@null@*/ void *d)
{
    /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d;
    yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
    assert(info != NULL);

    /* Don't check internally-generated symbols.  Only internally generated
     * symbols have symrec data, so simply check for its presence.
     */
    if (yasm_symrec_get_data(sym, &bin_symrec_data_cb))
        return 0;

    if (vis & YASM_SYM_EXTERN) {
        yasm_warn_set(YASM_WARN_GENERAL,
            N_("binary object format does not support extern variables"));
        yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym));
    } else if (vis & YASM_SYM_GLOBAL) {
        yasm_warn_set(YASM_WARN_GENERAL,
            N_("binary object format does not support global variables"));
        yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym));
    } else if (vis & YASM_SYM_COMMON) {
        yasm_error_set(YASM_ERROR_TYPE,
            N_("binary object format does not support common variables"));
        yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym));
    }
    return 0;
}

static int
bin_lma_create_group(yasm_section *sect, /*@null@*/ void *d)
{
    bin_objfmt_output_info *info = (bin_objfmt_output_info *)d;
    bin_section_data *bsd = yasm_section_get_data(sect, &bin_section_data_cb);
    unsigned long align = yasm_section_get_align(sect);
    bin_group *group;

    assert(info != NULL);
    assert(bsd != NULL);

    group = yasm_xmalloc(sizeof(bin_group));
    group->section = sect;
    group->bsd = bsd;
    TAILQ_INIT(&group->follow_groups);

    /* Determine section alignment as necessary. */
    if (!bsd->align)
        bsd->align = yasm_intnum_create_uint(align > 4 ? align : 4);
    else {
        yasm_intnum *align_intn = yasm_intnum_create_uint(align);
        if (yasm_intnum_compare(align_intn, bsd->align) > 0) {
            yasm_warn_set(YASM_WARN_GENERAL,
                N_("section `%s' internal align of %lu is greater than `%s' of %lu; using `%s'"),
                yasm_section_get_name(sect),
                yasm_intnum_get_uint(align_intn),
                N_("align"),
                yasm_intnum_get_uint(bsd->align),
                N_("align"));
            yasm_errwarn_propagate(info->errwarns, 0);
        }
        yasm_intnum_destroy(align_intn);
    }

    /* Calculate section integer start. */
    if (bsd->start) {
        bsd->istart = yasm_expr_get_intnum(&bsd->start, 0);
        if (!bsd->istart) {
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("start expression is too complex"));
            yasm_errwarn_propagate(info->errwarns, bsd->start->line);
            return 1;
        } else
            bsd->istart = yasm_intnum_copy(bsd->istart);
    } else
        bsd->istart = NULL;

    /* Calculate section integer vstart. */
    if (bsd->vstart) {
        bsd->ivstart = yasm_expr_get_intnum(&bsd->vstart, 0);
        if (!bsd->ivstart) {
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("vstart expression is too complex"));
            yasm_errwarn_propagate(info->errwarns, bsd->vstart->line);
            return 1;
        } else
            bsd->ivstart = yasm_intnum_copy(bsd->ivstart);
    } else
        bsd->ivstart = NULL;

    /* Calculate section integer length. */
    bsd->length = yasm_calc_bc_dist(yasm_section_bcs_first(sect),
                                    yasm_section_bcs_last(sect));

    TAILQ_INSERT_TAIL(&info->lma_groups, group, link);
    return 0;
}

static int
bin_vma_create_group(yasm_section *sect, /*@null@*/ void *d)
{
    bin_objfmt_output_info *info = (bin_objfmt_output_info *)d;
    bin_section_data *bsd = yasm_section_get_data(sect, &bin_section_data_cb);
    bin_group *group;

    assert(info != NULL);
    assert(bsd != NULL);

    group = yasm_xmalloc(sizeof(bin_group));
    group->section = sect;
    group->bsd = bsd;
    TAILQ_INIT(&group->follow_groups);

    TAILQ_INSERT_TAIL(&info->vma_groups, group, link);
    return 0;
}

/* Calculates new start address based on alignment constraint.
 * Start is modified (rounded up) to the closest aligned value greater than
 * what was passed in.
 * Align must be a power of 2.
 */
static void
bin_objfmt_align(yasm_intnum *start, const yasm_intnum *align)
{
    /* Because alignment is always a power of two, we can use some bit
     * trickery to do this easily.
     */
    yasm_intnum *align_intn =
        yasm_intnum_create_uint(yasm_intnum_get_uint(align)-1);
    yasm_intnum_calc(align_intn, YASM_EXPR_AND, start);
    if (!yasm_intnum_is_zero(align_intn)) {
        /* start = (start & ~(align-1)) + align; */
        yasm_intnum_set_uint(align_intn, yasm_intnum_get_uint(align)-1);
        yasm_intnum_calc(align_intn, YASM_EXPR_NOT, NULL);
        yasm_intnum_calc(align_intn, YASM_EXPR_AND, start);
        yasm_intnum_set(start, align);
        yasm_intnum_calc(start, YASM_EXPR_ADD, align_intn);
    }
    yasm_intnum_destroy(align_intn);
}

/* Recursive function to assign start addresses.
 * Updates start, last, and vdelta parameters as it goes along.
 * The tmp parameter is just a working intnum so one doesn't have to be
 * locally allocated for this purpose.
 */
static void
group_assign_start_recurse(bin_group *group, yasm_intnum *start,
                           yasm_intnum *last, yasm_intnum *vdelta,
                           yasm_intnum *tmp, yasm_errwarns *errwarns)
{
    bin_group *follow_group;

    /* Determine LMA */
    if (group->bsd->istart) {
        yasm_intnum_set(group->bsd->istart, start);
        if (group->bsd->align) {
            bin_objfmt_align(group->bsd->istart, group->bsd->align);
            if (yasm_intnum_compare(start, group->bsd->istart) != 0) {
                yasm_warn_set(YASM_WARN_GENERAL,
                    N_("start inconsistent with align; using aligned value"));
                yasm_errwarn_propagate(errwarns, group->bsd->start->line);
            }
        }
    } else {
        group->bsd->istart = yasm_intnum_copy(start);
        if (group->bsd->align != 0)
            bin_objfmt_align(group->bsd->istart, group->bsd->align);
    }

    /* Determine VMA if either just valign specified or if no v* specified */
    if (!group->bsd->vstart) {
        if (!group->bsd->vfollows && !group->bsd->valign) {
            /* No v* specified, set VMA=LMA+vdelta. */
            group->bsd->ivstart = yasm_intnum_copy(group->bsd->istart);
            yasm_intnum_calc(group->bsd->ivstart, YASM_EXPR_ADD, vdelta);
        } else if (!group->bsd->vfollows) {
            /* Just valign specified: set VMA=LMA+vdelta, align VMA, then add
             * delta between unaligned and aligned to vdelta parameter.
             */
            group->bsd->ivstart = yasm_intnum_copy(group->bsd->istart);
            yasm_intnum_calc(group->bsd->ivstart, YASM_EXPR_ADD, vdelta);
            yasm_intnum_set(tmp, group->bsd->ivstart);
            bin_objfmt_align(group->bsd->ivstart, group->bsd->valign);
            yasm_intnum_calc(vdelta, YASM_EXPR_ADD, group->bsd->ivstart);
            yasm_intnum_calc(vdelta, YASM_EXPR_SUB, tmp);
        }
    }

    /* Find the maximum end value */
    yasm_intnum_set(tmp, group->bsd->istart);
    yasm_intnum_calc(tmp, YASM_EXPR_ADD, group->bsd->length);
    if (yasm_intnum_compare(tmp, last) > 0)     /* tmp > last */
        yasm_intnum_set(last, tmp);

    /* Recurse for each following group. */
    TAILQ_FOREACH(follow_group, &group->follow_groups, link) {
        /* Following sections have to follow this one,
         * so add length to start.
         */
        yasm_intnum_set(start, group->bsd->istart);
        yasm_intnum_calc(start, YASM_EXPR_ADD, group->bsd->length);

        group_assign_start_recurse(follow_group, start, last, vdelta, tmp,
                                   errwarns);
    }
}

/* Recursive function to assign start addresses.
 * Updates start parameter as it goes along.
 * The tmp parameter is just a working intnum so one doesn't have to be
 * locally allocated for this purpose.
 */
static void
group_assign_vstart_recurse(bin_group *group, yasm_intnum *start,
                            yasm_errwarns *errwarns)
{
    bin_group *follow_group;

    /* Determine VMA section alignment as necessary.
     * Default to LMA alignment if not specified.
     */
    if (!group->bsd->valign)
        group->bsd->valign = yasm_intnum_copy(group->bsd->align);
    else {
        unsigned long align = yasm_section_get_align(group->section);
        yasm_intnum *align_intn = yasm_intnum_create_uint(align);
        if (yasm_intnum_compare(align_intn, group->bsd->valign) > 0) {
            yasm_warn_set(YASM_WARN_GENERAL,
                N_("section `%s' internal align of %lu is greater than `%s' of %lu; using `%s'"),
                yasm_section_get_name(group->section),
                yasm_intnum_get_uint(align_intn),
                N_("valign"),
                yasm_intnum_get_uint(group->bsd->valign),
                N_("valign"));
            yasm_errwarn_propagate(errwarns, 0);
        }
        yasm_intnum_destroy(align_intn);
    }

    /* Determine VMA */
    if (group->bsd->ivstart) {
        yasm_intnum_set(group->bsd->ivstart, start);
        if (group->bsd->valign) {
            bin_objfmt_align(group->bsd->ivstart, group->bsd->valign);
            if (yasm_intnum_compare(start, group->bsd->ivstart) != 0) {
                yasm_error_set(YASM_ERROR_VALUE,
                               N_("vstart inconsistent with valign"));
                yasm_errwarn_propagate(errwarns, group->bsd->vstart->line);
            }
        }
    } else {
        group->bsd->ivstart = yasm_intnum_copy(start);
        if (group->bsd->valign)
            bin_objfmt_align(group->bsd->ivstart, group->bsd->valign);
    }

    /* Recurse for each following group. */
    TAILQ_FOREACH(follow_group, &group->follow_groups, link) {
        /* Following sections have to follow this one,
         * so add length to start.
         */
        yasm_intnum_set(start, group->bsd->ivstart);
        yasm_intnum_calc(start, YASM_EXPR_ADD, group->bsd->length);

        group_assign_vstart_recurse(follow_group, start, errwarns);
    }
}

static /*@null@*/ const yasm_intnum *
get_ssym_value(yasm_symrec *sym)
{
    bin_symrec_data *bsymd = yasm_symrec_get_data(sym, &bin_symrec_data_cb);
    bin_section_data *bsd;

    if (!bsymd)
        return NULL;

    bsd = yasm_section_get_data(bsymd->section, &bin_section_data_cb);
    assert(bsd != NULL);

    switch (bsymd->which) {
        case SSYM_START: return bsd->istart;
        case SSYM_VSTART: return bsd->ivstart;
        case SSYM_LENGTH: return bsd->length;
    }
    return NULL;
}

static /*@only@*/ yasm_expr *
bin_objfmt_expr_xform(/*@returned@*/ /*@only@*/ yasm_expr *e,
                      /*@unused@*/ /*@null@*/ void *d)
{
    int i;
    for (i=0; i<e->numterms; i++) {
        /*@dependent@*/ yasm_section *sect;
        /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
        /*@null@*/ yasm_intnum *dist;
        /*@null@*/ const yasm_intnum *ssymval;

        /* Transform symrecs or precbcs that reference sections into
         * vstart + intnum(dist).
         */
        if (((e->terms[i].type == YASM_EXPR_SYM &&
             yasm_symrec_get_label(e->terms[i].data.sym, &precbc)) ||
            (e->terms[i].type == YASM_EXPR_PRECBC &&
             (precbc = e->terms[i].data.precbc))) &&
            (sect = yasm_bc_get_section(precbc)) &&
            (dist = yasm_calc_bc_dist(yasm_section_bcs_first(sect), precbc))) {
            bin_section_data *bsd;
            bsd = yasm_section_get_data(sect, &bin_section_data_cb);
            assert(bsd != NULL);
            yasm_intnum_calc(dist, YASM_EXPR_ADD, bsd->ivstart);
            e->terms[i].type = YASM_EXPR_INT;
            e->terms[i].data.intn = dist;
        }

        /* Transform our special symrecs into the appropriate value */
        if (e->terms[i].type == YASM_EXPR_SYM &&
            (ssymval = get_ssym_value(e->terms[i].data.sym))) {
            e->terms[i].type = YASM_EXPR_INT;
            e->terms[i].data.intn = yasm_intnum_copy(ssymval);
        }
    }

    return e;
}

typedef struct map_output_info {
    /* address width */
    int bytes;

    /* intnum output static data areas */
    unsigned char *buf;
    yasm_intnum *intn;

    /* symrec output information */
    unsigned long count;
    yasm_section *section;  /* NULL for EQUs */

    yasm_object *object;    /* object */
    FILE *f;                /* map output file */
} map_output_info;

static int
map_prescan_bytes(yasm_section *sect, void *d)
{
    bin_section_data *bsd = yasm_section_get_data(sect, &bin_section_data_cb);
    map_output_info *info = (map_output_info *)d;

    assert(bsd != NULL);
    assert(info != NULL);

    while (!yasm_intnum_check_size(bsd->length, info->bytes * 8, 0, 0))
        info->bytes *= 2;
    while (!yasm_intnum_check_size(bsd->istart, info->bytes * 8, 0, 0))
        info->bytes *= 2;
    while (!yasm_intnum_check_size(bsd->ivstart, info->bytes * 8, 0, 0))
        info->bytes *= 2;

    return 0;
}

static void
map_print_intnum(const yasm_intnum *intn, map_output_info *info)
{
    size_t i;
    yasm_intnum_get_sized(intn, info->buf, info->bytes, info->bytes*8, 0, 0,
                          0);
    for (i=info->bytes; i != 0; i--)
        fprintf(info->f, "%02X", info->buf[i-1]);
}

static void
map_sections_summary(bin_groups *groups, map_output_info *info)
{
    bin_group *group;
    TAILQ_FOREACH(group, groups, link) {
        bin_section_data *bsd = group->bsd;

        assert(bsd != NULL);
        assert(info != NULL);

        map_print_intnum(bsd->ivstart, info);
        fprintf(info->f, "  ");

        yasm_intnum_set(info->intn, bsd->ivstart);
        yasm_intnum_calc(info->intn, YASM_EXPR_ADD, bsd->length);
        map_print_intnum(info->intn, info);
        fprintf(info->f, "  ");

        map_print_intnum(bsd->istart, info);
        fprintf(info->f, "  ");

        yasm_intnum_set(info->intn, bsd->istart);
        yasm_intnum_calc(info->intn, YASM_EXPR_ADD, bsd->length);
        map_print_intnum(info->intn, info);
        fprintf(info->f, "  ");

        map_print_intnum(bsd->length, info);
        fprintf(info->f, "  ");

        fprintf(info->f, "%-*s", 10, bsd->bss ? "nobits" : "progbits");
        fprintf(info->f, "%s\n", yasm_section_get_name(group->section));

        /* Recurse to loop through follow groups */
        map_sections_summary(&group->follow_groups, info);
    }
}

static void
map_sections_detail(bin_groups *groups, map_output_info *info)
{
    bin_group *group;
    TAILQ_FOREACH(group, groups, link) {
        bin_section_data *bsd = group->bsd;
        size_t i;
        const char *s;

        s = yasm_section_get_name(group->section);
        fprintf(info->f, "---- Section %s ", s);
        for (i=0; i<(65-strlen(s)); i++)
            fputc('-', info->f);

        fprintf(info->f, "\n\nclass:     %s",
                bsd->bss ? "nobits" : "progbits");
        fprintf(info->f, "\nlength:    ");
        map_print_intnum(bsd->length, info);
        fprintf(info->f, "\nstart:     ");
        map_print_intnum(bsd->istart, info);
        fprintf(info->f, "\nalign:     ");
        map_print_intnum(bsd->align, info);
        fprintf(info->f, "\nfollows:   %s",
                bsd->follows ? bsd->follows : "not defined");
        fprintf(info->f, "\nvstart:    ");
        map_print_intnum(bsd->ivstart, info);
        fprintf(info->f, "\nvalign:    ");
        map_print_intnum(bsd->valign, info);
        fprintf(info->f, "\nvfollows:  %s\n\n",
                bsd->vfollows ? bsd->vfollows : "not defined");

        /* Recurse to loop through follow groups */
        map_sections_detail(&group->follow_groups, info);
    }
}

static int
map_symrec_count(yasm_symrec *sym, void *d)
{
    map_output_info *info = (map_output_info *)d;
    /*@dependent@*/ yasm_bytecode *precbc;

    assert(info != NULL);

    /* TODO: autodetect wider size */
    if (!info->section && yasm_symrec_get_equ(sym)) {
        info->count++;
    } else if (yasm_symrec_get_label(sym, &precbc) &&
               yasm_bc_get_section(precbc) == info->section) {
        info->count++;
    }
    return 0;
}

static int
map_symrec_output(yasm_symrec *sym, void *d)
{
    map_output_info *info = (map_output_info *)d;
    const yasm_expr *equ;
    /*@dependent@*/ yasm_bytecode *precbc;

    assert(info != NULL);

    if (!info->section && (equ = yasm_symrec_get_equ(sym))) {
        yasm_expr *realequ = yasm_expr_copy(equ);
        realequ = yasm_expr__level_tree
            (realequ, 1, 1, 1, 0, bin_objfmt_expr_xform, NULL);
        yasm_intnum_set(info->intn, yasm_expr_get_intnum(&realequ, 0));
        yasm_expr_destroy(realequ);
        map_print_intnum(info->intn, info);
        fprintf(info->f, "  %s\n", yasm_symrec_get_name(sym));
    } else if (yasm_symrec_get_label(sym, &precbc) &&
               yasm_bc_get_section(precbc) == info->section) {
        bin_section_data *bsd =
            yasm_section_get_data(info->section, &bin_section_data_cb);

        /* Real address */
        yasm_intnum_set_uint(info->intn, precbc->offset);
        yasm_intnum_calc(info->intn, YASM_EXPR_ADD, bsd->istart);
        map_print_intnum(info->intn, info);
        fprintf(info->f, "  ");

        /* Virtual address */
        yasm_intnum_set_uint(info->intn, precbc->offset);
        yasm_intnum_calc(info->intn, YASM_EXPR_ADD, bsd->ivstart);
        map_print_intnum(info->intn, info);

        /* Name */
        fprintf(info->f, "  %s\n", yasm_symrec_get_name(sym));
    }
    return 0;
}

static void
map_sections_symbols(bin_groups *groups, map_output_info *info)
{
    bin_group *group;
    TAILQ_FOREACH(group, groups, link) {
        info->count = 0;
        info->section = group->section;
        yasm_symtab_traverse(info->object->symtab, info, map_symrec_count);

        if (info->count > 0) {
            const char *s = yasm_section_get_name(group->section);
            size_t i;
            fprintf(info->f, "---- Section %s ", s);
            for (i=0; i<(65-strlen(s)); i++)
                fputc('-', info->f);
            fprintf(info->f, "\n\n%-*s%-*s%s\n",
                    info->bytes*2+2, "Real",
                    info->bytes*2+2, "Virtual",
                    "Name");
            yasm_symtab_traverse(info->object->symtab, info,
                                 map_symrec_output);
            fprintf(info->f, "\n\n");
        }

        /* Recurse to loop through follow groups */
        map_sections_symbols(&group->follow_groups, info);
    }
}

static void
output_map(bin_objfmt_output_info *info)
{
    yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)info->object->objfmt;
    FILE *f;
    int i;
    map_output_info mapinfo;

    if (objfmt_bin->map_flags == NO_MAP)
        return;

    if (objfmt_bin->map_flags == MAP_NONE)
        objfmt_bin->map_flags = MAP_BRIEF;          /* default to brief */

    if (!objfmt_bin->map_filename)
        f = stdout;                                 /* default to stdout */
    else {
        f = fopen(objfmt_bin->map_filename, "wt");
        if (!f) {
            yasm_warn_set(YASM_WARN_GENERAL,
                          N_("unable to open map file `%s'"),
                          objfmt_bin->map_filename);
            yasm_errwarn_propagate(info->errwarns, 0);
            return;
        }
    }

    mapinfo.object = info->object;
    mapinfo.f = f;

    /* Temporary intnum */
    mapinfo.intn = info->tmp_intn;

    /* Prescan all values to figure out what width we should make the output
     * fields.  Start with a minimum of 4.
     */
    mapinfo.bytes = 4;
    while (!yasm_intnum_check_size(info->origin, mapinfo.bytes * 8, 0, 0))
        mapinfo.bytes *= 2;
    yasm_object_sections_traverse(info->object, &mapinfo, map_prescan_bytes);
    mapinfo.buf = yasm_xmalloc(mapinfo.bytes);

    fprintf(f, "\n- YASM Map file ");
    for (i=0; i<63; i++)
        fputc('-', f);
    fprintf(f, "\n\nSource file:  %s\n", info->object->src_filename);
    fprintf(f, "Output file:  %s\n\n", info->object->obj_filename);

    fprintf(f, "-- Program origin ");
    for (i=0; i<61; i++)
        fputc('-', f);
    fprintf(f, "\n\n");
    map_print_intnum(info->origin, &mapinfo);
    fprintf(f, "\n\n");

    if (objfmt_bin->map_flags & MAP_BRIEF) {
        fprintf(f, "-- Sections (summary) ");
        for (i=0; i<57; i++)
            fputc('-', f);
        fprintf(f, "\n\n%-*s%-*s%-*s%-*s%-*s%-*s%s\n",
                mapinfo.bytes*2+2, "Vstart",
                mapinfo.bytes*2+2, "Vstop",
                mapinfo.bytes*2+2, "Start",
                mapinfo.bytes*2+2, "Stop",
                mapinfo.bytes*2+2, "Length",
                10, "Class", "Name");

        map_sections_summary(&info->lma_groups, &mapinfo);
        fprintf(f, "\n");
    }

    if (objfmt_bin->map_flags & MAP_SECTIONS) {
        fprintf(f, "-- Sections (detailed) ");
        for (i=0; i<56; i++)
            fputc('-', f);
        fprintf(f, "\n\n");
        map_sections_detail(&info->lma_groups, &mapinfo);
    }

    if (objfmt_bin->map_flags & MAP_SYMBOLS) {
        fprintf(f, "-- Symbols ");
        for (i=0; i<68; i++)
            fputc('-', f);
        fprintf(f, "\n\n");

        /* We do two passes for EQU and each section; the first pass
         * determines the byte width to use for the value and whether any
         * symbols are present, the second pass actually outputs the text.
         */

        /* EQUs */
        mapinfo.count = 0;
        mapinfo.section = NULL;
        yasm_symtab_traverse(info->object->symtab, &mapinfo, map_symrec_count);

        if (mapinfo.count > 0) {
            fprintf(f, "---- No Section ");
            for (i=0; i<63; i++)
                fputc('-', f);
            fprintf(f, "\n\n%-*s%s\n", mapinfo.bytes*2+2, "Value", "Name");
            yasm_symtab_traverse(info->object->symtab, &mapinfo,
                                 map_symrec_output);
            fprintf(f, "\n\n");
        }

        /* Other sections */
        map_sections_symbols(&info->lma_groups, &mapinfo);
    }

    if (f != stdout)
        fclose(f);

    yasm_xfree(mapinfo.buf);
}

/* Check for LMA overlap using a simple N^2 algorithm. */
static int
check_lma_overlap(yasm_section *sect, /*@null@*/ void *d)
{
    bin_section_data *bsd, *bsd2;
    yasm_section *other = (yasm_section *)d;
    yasm_intnum *overlap;

    if (!d)
        return yasm_object_sections_traverse(yasm_section_get_object(sect),
                                             sect, check_lma_overlap);
    if (sect == other)
        return 0;

    bsd = yasm_section_get_data(sect, &bin_section_data_cb);
    bsd2 = yasm_section_get_data(other, &bin_section_data_cb);

    if (yasm_intnum_is_zero(bsd->length) ||
        yasm_intnum_is_zero(bsd2->length))
        return 0;

    if (yasm_intnum_compare(bsd->istart, bsd2->istart) <= 0) {
        overlap = yasm_intnum_copy(bsd->istart);
        yasm_intnum_calc(overlap, YASM_EXPR_ADD, bsd->length);
        yasm_intnum_calc(overlap, YASM_EXPR_SUB, bsd2->istart);
    } else {
        overlap = yasm_intnum_copy(bsd2->istart);
        yasm_intnum_calc(overlap, YASM_EXPR_ADD, bsd2->length);
        yasm_intnum_calc(overlap, YASM_EXPR_SUB, bsd->istart);
    }

    if (yasm_intnum_sign(overlap) > 0) {
        yasm_error_set(YASM_ERROR_GENERAL,
                       N_("sections `%s' and `%s' overlap by %lu bytes"),
                       yasm_section_get_name(sect),
                       yasm_section_get_name(other),
                       yasm_intnum_get_uint(overlap));
        yasm_intnum_destroy(overlap);
        return -1;
    }

    yasm_intnum_destroy(overlap);
    return 0;
}

static int
bin_objfmt_output_value(yasm_value *value, unsigned char *buf,
                        unsigned int destsize,
                        /*@unused@*/ unsigned long offset, yasm_bytecode *bc,
                        int warn, /*@null@*/ void *d)
{
    /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d;
    /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
    /*@dependent@*/ yasm_section *sect;

    assert(info != NULL);

    /* Binary objects we need to resolve against object, not against section. */
    if (value->rel) {
        unsigned int rshift = (unsigned int)value->rshift;
        yasm_expr *syme;
        /*@null@*/ const yasm_intnum *ssymval;

        if (yasm_symrec_is_abs(value->rel)) {
            syme = yasm_expr_create_ident(yasm_expr_int(
                yasm_intnum_create_uint(0)), bc->line);
        } else if (yasm_symrec_get_label(value->rel, &precbc)
                   && (sect = yasm_bc_get_section(precbc))) {
            syme = yasm_expr_create_ident(yasm_expr_sym(value->rel), bc->line);
        } else if ((ssymval = get_ssym_value(value->rel))) {
            syme = yasm_expr_create_ident(yasm_expr_int(
                yasm_intnum_copy(ssymval)), bc->line);
        } else
            goto done;

        /* Handle PC-relative */
        if (value->curpos_rel) {
            yasm_expr *sube;
            sube = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_precbc(bc),
                yasm_expr_int(yasm_intnum_create_uint(bc->len*bc->mult_int)),
                bc->line);
            syme = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(syme),
                                    yasm_expr_expr(sube), bc->line);
            value->curpos_rel = 0;
            value->ip_rel = 0;
        }

        if (value->rshift > 0)
            syme = yasm_expr_create(YASM_EXPR_SHR, yasm_expr_expr(syme),
                yasm_expr_int(yasm_intnum_create_uint(rshift)), bc->line);

        /* Add into absolute portion */
        if (!value->abs)
            value->abs = syme;
        else
            value->abs =
                yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(value->abs),
                                 yasm_expr_expr(syme), bc->line);
        value->rel = NULL;
        value->rshift = 0;
    }
done:
    /* Simplify absolute portion of value, transforming symrecs */
    if (value->abs)
        value->abs = yasm_expr__level_tree
            (value->abs, 1, 1, 1, 0, bin_objfmt_expr_xform, NULL);

    /* Output */
    switch (yasm_value_output_basic(value, buf, destsize, bc, warn,
                                    info->object->arch)) {
        case -1:
            return 1;
        case 0:
            break;
        default:
            return 0;
    }

    /* Couldn't output, assume it contains an external reference. */
    yasm_error_set(YASM_ERROR_GENERAL,
        N_("binary object format does not support external references"));
    return 1;
}

static int
bin_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
{
    /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d;
    /*@null@*/ /*@only@*/ unsigned char *bigbuf;
    unsigned long size = REGULAR_OUTBUF_SIZE;
    int gap;

    assert(info != NULL);

    bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &gap, info,
                             bin_objfmt_output_value, NULL);

    /* Don't bother doing anything else if size ended up being 0. */
    if (size == 0) {
        if (bigbuf)
            yasm_xfree(bigbuf);
        return 0;
    }

    /* Warn that gaps are converted to 0 and write out the 0's. */
    if (gap) {
        unsigned long left;
        yasm_warn_set(YASM_WARN_UNINIT_CONTENTS,
            N_("uninitialized space declared in code/data section: zeroing"));
        /* Write out in chunks */
        memset(info->buf, 0, REGULAR_OUTBUF_SIZE);
        left = size;
        while (left > REGULAR_OUTBUF_SIZE) {
            fwrite(info->buf, REGULAR_OUTBUF_SIZE, 1, info->f);
            left -= REGULAR_OUTBUF_SIZE;
        }
        fwrite(info->buf, left, 1, info->f);
    } else {
        /* Output buf (or bigbuf if non-NULL) to file */
        fwrite(bigbuf ? bigbuf : info->buf, (size_t)size, 1, info->f);
    }

    /* If bigbuf was allocated, free it */
    if (bigbuf)
        yasm_xfree(bigbuf);

    return 0;
}

/* Check to ensure bytecode is res* (for BSS sections) */
static int
bin_objfmt_no_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
{
    /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d;
    /*@null@*/ /*@only@*/ unsigned char *bigbuf;
    unsigned long size = REGULAR_OUTBUF_SIZE;
    int gap;

    assert(info != NULL);

    bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &gap, info,
                             bin_objfmt_output_value, NULL);

    /* If bigbuf was allocated, free it */
    if (bigbuf)
        yasm_xfree(bigbuf);

    /* Don't bother doing anything else if size ended up being 0. */
    if (size == 0)
        return 0;

    /* Warn if not a gap. */
    if (!gap) {
        yasm_warn_set(YASM_WARN_GENERAL,
            N_("initialized space declared in nobits section: ignoring"));
    }

    return 0;
}

static int
bin_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
{
    bin_section_data *bsd = yasm_section_get_data(sect, &bin_section_data_cb);
    /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d;

    assert(bsd != NULL);
    assert(info != NULL);

    if (bsd->bss) {
        yasm_section_bcs_traverse(sect, info->errwarns,
                                  info, bin_objfmt_no_output_bytecode);
    } else {
        yasm_intnum_set(info->tmp_intn, bsd->istart);
        yasm_intnum_calc(info->tmp_intn, YASM_EXPR_SUB, info->origin);
        if (yasm_intnum_sign(info->tmp_intn) < 0) {
            yasm_error_set(YASM_ERROR_VALUE,
                           N_("section `%s' starts before origin (ORG)"),
                           yasm_section_get_name(sect));
            yasm_errwarn_propagate(info->errwarns, 0);
            return 0;
        }
        if (!yasm_intnum_check_size(info->tmp_intn, sizeof(long)*8, 0, 1)) {
            yasm_error_set(YASM_ERROR_VALUE,
                           N_("section `%s' start value too large"),
                           yasm_section_get_name(sect));
            yasm_errwarn_propagate(info->errwarns, 0);
            return 0;
        }
        if (fseek(info->f, yasm_intnum_get_int(info->tmp_intn), SEEK_SET) < 0)
            yasm__fatal(N_("could not seek on output file"));
        yasm_section_bcs_traverse(sect, info->errwarns,
                                  info, bin_objfmt_output_bytecode);
    }

    return 0;
}

static void
bin_objfmt_cleanup(bin_objfmt_output_info *info)
{
    bin_group *group, *group_temp;

    yasm_xfree(info->buf);
    yasm_intnum_destroy(info->origin);
    yasm_intnum_destroy(info->tmp_intn);

    TAILQ_FOREACH_SAFE(group, &info->lma_groups, link, group_temp)
        bin_group_destroy(group);

    TAILQ_FOREACH_SAFE(group, &info->vma_groups, link, group_temp)
        bin_group_destroy(group);
}

static void
bin_objfmt_output(yasm_object *object, FILE *f, /*@unused@*/ int all_syms,
                  yasm_errwarns *errwarns)
{
    yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)object->objfmt;
    bin_objfmt_output_info info;
    bin_group *group, *lma_group, *vma_group, *group_temp;
    yasm_intnum *start, *last, *vdelta;
    bin_groups unsorted_groups, bss_groups;

    /* Set ORG to 0 unless otherwise specified */
    if (objfmt_bin->org) {
        info.origin = yasm_expr_get_intnum(&objfmt_bin->org, 0);
        if (!info.origin) {
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("ORG expression is too complex"));
            yasm_errwarn_propagate(errwarns, objfmt_bin->org->line);
            return;
        }
        if (yasm_intnum_sign(info.origin) < 0) {
            yasm_error_set(YASM_ERROR_VALUE, N_("ORG expression is negative"));
            yasm_errwarn_propagate(errwarns, objfmt_bin->org->line);
            return;
        }
        info.origin = yasm_intnum_copy(info.origin);
    } else
        info.origin = yasm_intnum_create_uint(0);

    info.object = object;
    info.errwarns = errwarns;
    info.f = f;
    info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);
    info.tmp_intn = yasm_intnum_create_uint(0);
    TAILQ_INIT(&info.lma_groups);
    TAILQ_INIT(&info.vma_groups);

    /* Check symbol table */
    yasm_symtab_traverse(object->symtab, &info, bin_objfmt_check_sym);

    /* Create section groups */
    if (yasm_object_sections_traverse(object, &info, bin_lma_create_group)) {
        bin_objfmt_cleanup(&info);
        return;     /* error detected */
    }

    /* Determine section order according to LMA.
     * Sections can be ordered either by (priority):
     *  - follows
     *  - start
     *  - progbits/nobits setting
     *  - order in the input file
     */

    /* Look at each group with follows specified, and find the section
     * that group is supposed to follow.
     */
    TAILQ_FOREACH_SAFE(lma_group, &info.lma_groups, link, group_temp) {
        if (lma_group->bsd->follows) {
            bin_group *found;
            /* Need to find group containing section this section follows. */
            found =
                find_group_by_name(&info.lma_groups, lma_group->bsd->follows);
            if (!found) {
                yasm_error_set(YASM_ERROR_VALUE,
                               N_("section `%s' follows an invalid or unknown section `%s'"),
                               yasm_section_get_name(lma_group->section),
                               lma_group->bsd->follows);
                yasm_errwarn_propagate(errwarns, 0);
                bin_objfmt_cleanup(&info);
                return;
            }

            /* Check for loops */
            if (lma_group->section == found->section ||
                find_group_by_section(&lma_group->follow_groups,
                                      found->section)) {
                yasm_error_set(YASM_ERROR_VALUE,
                               N_("follows loop between section `%s' and section `%s'"),
                               yasm_section_get_name(lma_group->section),
                               yasm_section_get_name(found->section));
                yasm_errwarn_propagate(errwarns, 0);
                bin_objfmt_cleanup(&info);
                return;
            }

            /* Remove this section from main lma groups list */
            TAILQ_REMOVE(&info.lma_groups, lma_group, link);
            /* Add it after the section it's supposed to follow. */
            TAILQ_INSERT_TAIL(&found->follow_groups, lma_group, link);
        }
    }

    /* Sort the top-level groups according to their start address.
     * Use Shell sort for ease of implementation.
     * If no start address is specified for a section, don't change the order,
     * and move BSS sections to a separate list so they can be moved to the
     * end of the lma list after all other sections are sorted.
     */
    unsorted_groups = info.lma_groups;  /* structure copy */
    TAILQ_INIT(&info.lma_groups);
    TAILQ_INIT(&bss_groups);
    TAILQ_FOREACH_SAFE(lma_group, &unsorted_groups, link, group_temp) {
        bin_group *before;

        if (!lma_group->bsd->istart) {
            if (lma_group->bsd->bss)
                TAILQ_INSERT_TAIL(&bss_groups, lma_group, link);
            else
                TAILQ_INSERT_TAIL(&info.lma_groups, lma_group, link);
            continue;
        }

        before = NULL;
        TAILQ_FOREACH(group, &info.lma_groups, link) {
            if (!group->bsd->istart)
                continue;
            if (yasm_intnum_compare(group->bsd->istart,
                                    lma_group->bsd->istart) > 0) {
                before = group;
                break;
            }
        }
        if (before)
            TAILQ_INSERT_BEFORE(before, lma_group, link);
        else
            TAILQ_INSERT_TAIL(&info.lma_groups, lma_group, link);
    }

    /* Move the pure-BSS sections to the end of the LMA list. */
    TAILQ_FOREACH_SAFE(group, &bss_groups, link, group_temp)
        TAILQ_INSERT_TAIL(&info.lma_groups, group, link);
    TAILQ_INIT(&bss_groups);    /* For sanity */

    /* Assign a LMA start address to every section.
     * Also assign VMA=LMA unless otherwise specified.
     *
     * We need to assign VMA=LMA here (while walking the tree) for the case:
     *  sect1 start=0 (size=0x11)
     *  sect2 follows=sect1 valign=16 (size=0x104)
     *  sect3 follows=sect2 valign=16
     * Where the valign of sect2 will result in a sect3 vaddr higher than a
     * naive segment-by-segment interpretation (where sect3 and sect2 would
     * have a VMA overlap).
     *
     * Algorithm for VMA=LMA setting:
     * Start with delta=0.
     * If there's no virtual attributes, we simply set VMA = LMA+delta.
     * If there's only valign specified, we set VMA = aligned LMA, and add
     * any new alignment difference to delta.
     *
     * We could do the LMA start and VMA=LMA steps in two separate steps,
     * but it's easier to just recurse once.
     */
    start = yasm_intnum_copy(info.origin);
    last = yasm_intnum_copy(info.origin);
    vdelta = yasm_intnum_create_uint(0);
    TAILQ_FOREACH(lma_group, &info.lma_groups, link) {
        if (lma_group->bsd->istart)
            yasm_intnum_set(start, lma_group->bsd->istart);
        group_assign_start_recurse(lma_group, start, last, vdelta,
                                   info.tmp_intn, errwarns);
        yasm_intnum_set(start, last);
    }
    yasm_intnum_destroy(last);
    yasm_intnum_destroy(vdelta);

    /*
     * Determine section order according to VMA
     */

    /* Create section groups */
    if (yasm_object_sections_traverse(object, &info, bin_vma_create_group)) {
        yasm_intnum_destroy(start);
        bin_objfmt_cleanup(&info);
        return;     /* error detected */
    }

    /* Look at each group with vfollows specified, and find the section
     * that group is supposed to follow.
     */
    TAILQ_FOREACH_SAFE(vma_group, &info.vma_groups, link, group_temp) {
        if (vma_group->bsd->vfollows) {
            bin_group *found;
            /* Need to find group containing section this section follows. */
            found = find_group_by_name(&info.vma_groups,
                                       vma_group->bsd->vfollows);
            if (!found) {
                yasm_error_set(YASM_ERROR_VALUE,
                               N_("section `%s' vfollows an invalid or unknown section `%s'"),
                               yasm_section_get_name(vma_group->section),
                               vma_group->bsd->vfollows);
                yasm_errwarn_propagate(errwarns, 0);
                yasm_intnum_destroy(start);
                bin_objfmt_cleanup(&info);
                return;
            }

            /* Check for loops */
            if (vma_group->section == found->section ||
                find_group_by_section(&vma_group->follow_groups,
                                      found->section)) {
                yasm_error_set(YASM_ERROR_VALUE,
                               N_("vfollows loop between section `%s' and section `%s'"),
                               yasm_section_get_name(vma_group->section),
                               yasm_section_get_name(found->section));
                yasm_errwarn_propagate(errwarns, 0);
                bin_objfmt_cleanup(&info);
                return;
            }

            /* Remove this section from main lma groups list */
            TAILQ_REMOVE(&info.vma_groups, vma_group, link);
            /* Add it after the section it's supposed to follow. */
            TAILQ_INSERT_TAIL(&found->follow_groups, vma_group, link);
        }
    }

    /* Due to the combination of steps above, we now know that all top-level
     * groups have integer ivstart:
     * Vstart Vfollows Valign   Handled by
     *     No       No     No   group_assign_start_recurse()
     *     No       No    Yes   group_assign_start_recurse()
     *     No      Yes    -     vfollows loop (above)
     *    Yes      -      -     bin_lma_create_group()
     */
    TAILQ_FOREACH(vma_group, &info.vma_groups, link) {
        yasm_intnum_set(start, vma_group->bsd->ivstart);
        group_assign_vstart_recurse(vma_group, start, errwarns);
    }

    /* Output map file */
    output_map(&info);

    /* Ensure we don't have overlapping progbits LMAs.
     * Use a dumb O(N^2) algorithm as the number of sections is essentially
     * always low.
     */
    if (yasm_object_sections_traverse(object, NULL, check_lma_overlap)) {
        yasm_errwarn_propagate(errwarns, 0);
        yasm_intnum_destroy(start);
        bin_objfmt_cleanup(&info);
        return;
    }

    /* Output sections */
    yasm_object_sections_traverse(object, &info, bin_objfmt_output_section);

    /* Clean up */
    yasm_intnum_destroy(start);
    bin_objfmt_cleanup(&info);
}

static void
bin_objfmt_destroy(yasm_objfmt *objfmt)
{
    yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt;
    if (objfmt_bin->map_filename)
        yasm_xfree(objfmt_bin->map_filename);
    yasm_expr_destroy(objfmt_bin->org);
    yasm_xfree(objfmt);
}

static void
define_section_symbol(yasm_symtab *symtab, yasm_section *sect,
                      const char *sectname, const char *suffix,
                      enum bin_ssym which, unsigned long line)
{
    yasm_symrec *sym;
    bin_symrec_data *bsymd = yasm_xmalloc(sizeof(bin_symrec_data));
    char *symname = yasm_xmalloc(8+strlen(sectname)+strlen(suffix)+1);

    strcpy(symname, "section.");
    strcat(symname, sectname);
    strcat(symname, suffix);

    bsymd->section = sect;
    bsymd->which = which;

    sym = yasm_symtab_declare(symtab, symname, YASM_SYM_EXTERN, line);
    yasm_xfree(symname);
    yasm_symrec_add_data(sym, &bin_symrec_data_cb, bsymd);
}

static bin_section_data *
bin_objfmt_init_new_section(yasm_object *object, yasm_section *sect,
                            const char *sectname, unsigned long line)
{
    /*yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)object->objfmt;*/
    bin_section_data *data;

    data = yasm_xmalloc(sizeof(bin_section_data));
    data->bss = 0;
    data->align = NULL;
    data->valign = NULL;
    data->start = NULL;
    data->vstart = NULL;
    data->follows = NULL;
    data->vfollows = NULL;
    data->istart = NULL;
    data->ivstart = NULL;
    data->length = NULL;
    yasm_section_add_data(sect, &bin_section_data_cb, data);

    define_section_symbol(object->symtab, sect, sectname, ".start",
                          SSYM_START, line);
    define_section_symbol(object->symtab, sect, sectname, ".vstart",
                          SSYM_VSTART, line);
    define_section_symbol(object->symtab, sect, sectname, ".length",
                          SSYM_LENGTH, line);

    return data;
}

static yasm_section *
bin_objfmt_add_default_section(yasm_object *object)
{
    yasm_section *retval;
    int isnew;

    retval = yasm_object_get_general(object, ".text", 0, 1, 0, &isnew, 0);
    if (isnew) {
        bin_objfmt_init_new_section(object, retval, ".text", 0);
        yasm_section_set_default(retval, 1);
    }
    return retval;
}

static /*@observer@*/ /*@null@*/ yasm_section *
bin_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
                          /*@unused@*/ /*@null@*/
                          yasm_valparamhead *objext_valparams,
                          unsigned long line)
{
    yasm_valparam *vp;
    yasm_section *retval;
    int isnew;
    int flags_override = 0;
    const char *sectname;
    bin_section_data *bsd = NULL;

    struct bin_section_switch_data {
        /*@only@*/ /*@null@*/ char *follows;
        /*@only@*/ /*@null@*/ char *vfollows;
        /*@only@*/ /*@null@*/ yasm_expr *start;
        /*@only@*/ /*@null@*/ yasm_expr *vstart;
        /*@only@*/ /*@null@*/ yasm_intnum *align;
        /*@only@*/ /*@null@*/ yasm_intnum *valign;
        unsigned long bss;
        unsigned long code;
    } data;

    static const yasm_dir_help help[] = {
        { "follows", 1, yasm_dir_helper_string,
          offsetof(struct bin_section_switch_data, follows), 0 },
        { "vfollows", 1, yasm_dir_helper_string,
          offsetof(struct bin_section_switch_data, vfollows), 0 },
        { "start", 1, yasm_dir_helper_expr,
          offsetof(struct bin_section_switch_data, start), 0 },
        { "vstart", 1, yasm_dir_helper_expr,
          offsetof(struct bin_section_switch_data, vstart), 0 },
        { "align", 1, yasm_dir_helper_intn,
          offsetof(struct bin_section_switch_data, align), 0 },
        { "valign", 1, yasm_dir_helper_intn,
          offsetof(struct bin_section_switch_data, valign), 0 },
        { "nobits", 0, yasm_dir_helper_flag_set,
          offsetof(struct bin_section_switch_data, bss), 1 },
        { "progbits", 0, yasm_dir_helper_flag_set,
          offsetof(struct bin_section_switch_data, bss), 0 },
        { "code", 0, yasm_dir_helper_flag_set,
          offsetof(struct bin_section_switch_data, code), 1 },
        { "data", 0, yasm_dir_helper_flag_set,
          offsetof(struct bin_section_switch_data, code), 0 },
        { "execute", 0, yasm_dir_helper_flag_set,
          offsetof(struct bin_section_switch_data, code), 1 },
        { "noexecute", 0, yasm_dir_helper_flag_set,
          offsetof(struct bin_section_switch_data, code), 0 }
    };

    vp = yasm_vps_first(valparams);
    sectname = yasm_vp_string(vp);
    if (!sectname)
        return NULL;
    vp = yasm_vps_next(vp);

    retval = yasm_object_find_general(object, sectname);
    if (retval) {
        bsd = yasm_section_get_data(retval, &bin_section_data_cb);
        assert(bsd != NULL);
        data.follows = bsd->follows;
        data.vfollows = bsd->vfollows;
        data.start = bsd->start;
        data.vstart = bsd->vstart;
        data.align = NULL;
        data.valign = NULL;
        data.bss = bsd->bss;
        data.code = yasm_section_is_code(retval);
    } else {
        data.follows = NULL;
        data.vfollows = NULL;
        data.start = NULL;
        data.vstart = NULL;
        data.align = NULL;
        data.valign = NULL;
        data.bss = strcmp(sectname, ".bss") == 0;
        data.code = strcmp(sectname, ".text") == 0;
    }

    flags_override = yasm_dir_helper(object, vp, line, help, NELEMS(help),
                                     &data, yasm_dir_helper_valparam_warn);
    if (flags_override < 0)
        return NULL;    /* error occurred */

    if (data.start && data.follows) {
        yasm_error_set(YASM_ERROR_GENERAL,
            N_("cannot combine `start' and `follows' section attributes"));
        return NULL;
    }

    if (data.vstart && data.vfollows) {
        yasm_error_set(YASM_ERROR_GENERAL,
            N_("cannot combine `vstart' and `vfollows' section attributes"));
        return NULL;
    }

    if (data.align) {
        unsigned long align = yasm_intnum_get_uint(data.align);

        /* Alignments must be a power of two. */
        if (!is_exp2(align)) {
            yasm_error_set(YASM_ERROR_VALUE,
                           N_("argument to `%s' is not a power of two"),
                           "align");
            return NULL;
        }
    } else
        data.align = bsd ? bsd->align : NULL;

    if (data.valign) {
        unsigned long valign = yasm_intnum_get_uint(data.valign);

        /* Alignments must be a power of two. */
        if (!is_exp2(valign)) {
            yasm_error_set(YASM_ERROR_VALUE,
                           N_("argument to `%s' is not a power of two"),
                           "valign");
            return NULL;
        }
    } else
        data.valign = bsd ? bsd->valign : NULL;

    retval = yasm_object_get_general(object, sectname, 0, (int)data.code,
                                     (int)data.bss, &isnew, line);

    if (isnew)
        bsd = bin_objfmt_init_new_section(object, retval, sectname, line);
    else
        bsd = yasm_section_get_data(retval, &bin_section_data_cb);

    if (isnew || yasm_section_is_default(retval)) {
        yasm_section_set_default(retval, 0);
    }

    /* Update section flags */
    bsd->bss = data.bss;
    bsd->align = data.align;
    bsd->valign = data.valign;
    bsd->start = data.start;
    bsd->vstart = data.vstart;
    bsd->follows = data.follows;
    bsd->vfollows = data.vfollows;

    return retval;
}

static /*@observer@*/ /*@null@*/ yasm_symrec *
bin_objfmt_get_special_sym(yasm_object *object, const char *name,
                           const char *parser)
{
    return NULL;
}

static void
bin_objfmt_dir_org(yasm_object *object,
                   /*@null@*/ yasm_valparamhead *valparams,
                   /*@unused@*/ /*@null@*/
                   yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)object->objfmt;
    yasm_valparam *vp;

    /* We only allow a single ORG in a program. */
    if (objfmt_bin->org) {
        yasm_error_set(YASM_ERROR_GENERAL, N_("program origin redefined"));
        return;
    }

    /* ORG takes just a simple expression as param */
    vp = yasm_vps_first(valparams);
    objfmt_bin->org = yasm_vp_expr(vp, object->symtab, line);
    if (!objfmt_bin->org) {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("argument to ORG must be expression"));
        return;
    }
}

struct bin_dir_map_data {
    unsigned long flags;
    /*@only@*/ /*@null@*/ char *filename;
};

static int
dir_map_filename(void *obj, yasm_valparam *vp, unsigned long line, void *data)
{
    struct bin_dir_map_data *mdata = (struct bin_dir_map_data *)data;
    const char *filename;

    if (mdata->filename) {
        yasm_warn_set(YASM_WARN_GENERAL, N_("map file already specified"));
        return 0;
    }

    filename = yasm_vp_string(vp);
    if (!filename) {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("unexpected expression in [map]"));
        return -1;
    }
    mdata->filename = yasm__xstrdup(filename);

    return 1;
}

static void
bin_objfmt_dir_map(yasm_object *object,
                   /*@null@*/ yasm_valparamhead *valparams,
                   /*@unused@*/ /*@null@*/
                   yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)object->objfmt;

    struct bin_dir_map_data data;

    static const yasm_dir_help help[] = {
        { "all", 0, yasm_dir_helper_flag_or,
          offsetof(struct bin_dir_map_data, flags),
          MAP_BRIEF|MAP_SECTIONS|MAP_SYMBOLS },
        { "brief", 0, yasm_dir_helper_flag_or,
          offsetof(struct bin_dir_map_data, flags), MAP_BRIEF },
        { "sections", 0, yasm_dir_helper_flag_or,
          offsetof(struct bin_dir_map_data, flags), MAP_SECTIONS },
        { "segments", 0, yasm_dir_helper_flag_or,
          offsetof(struct bin_dir_map_data, flags), MAP_SECTIONS },
        { "symbols", 0, yasm_dir_helper_flag_or,
          offsetof(struct bin_dir_map_data, flags), MAP_SYMBOLS }
    };

    data.flags = objfmt_bin->map_flags | MAP_NONE;
    data.filename = objfmt_bin->map_filename;

    if (valparams && yasm_dir_helper(object, yasm_vps_first(valparams), line, help,
                                     NELEMS(help), &data, dir_map_filename) < 0)
        return;     /* error occurred */

    objfmt_bin->map_flags = data.flags;
    objfmt_bin->map_filename = data.filename;
}

static void
bin_section_data_destroy(void *data)
{
    bin_section_data *bsd = (bin_section_data *)data;
    if (bsd->start)
        yasm_expr_destroy(bsd->start);
    if (bsd->vstart)
        yasm_expr_destroy(bsd->vstart);
    if (bsd->follows)
        yasm_xfree(bsd->follows);
    if (bsd->vfollows)
        yasm_xfree(bsd->vfollows);
    if (bsd->istart)
        yasm_intnum_destroy(bsd->istart);
    if (bsd->ivstart)
        yasm_intnum_destroy(bsd->ivstart);
    if (bsd->length)
        yasm_intnum_destroy(bsd->length);
    yasm_xfree(data);
}

static void
bin_section_data_print(void *data, FILE *f, int indent_level)
{
    bin_section_data *bsd = (bin_section_data *)data;

    fprintf(f, "%*sbss=%d\n", indent_level, "", bsd->bss);

    fprintf(f, "%*salign=", indent_level, "");
    if (bsd->align)
        yasm_intnum_print(bsd->align, f);
    else
        fprintf(f, "(nil)");
    fprintf(f, "\n%*svalign=", indent_level, "");
    if (bsd->valign)
        yasm_intnum_print(bsd->valign, f);
    else
        fprintf(f, "(nil)");

    fprintf(f, "\n%*sstart=", indent_level, "");
    yasm_expr_print(bsd->start, f);
    fprintf(f, "\n%*svstart=", indent_level, "");
    yasm_expr_print(bsd->vstart, f);

    fprintf(f, "\n%*sfollows=", indent_level, "");
    if (bsd->follows)
        fprintf(f, "\"%s\"", bsd->follows);
    else
        fprintf(f, "(nil)");
    fprintf(f, "\n%*svfollows=", indent_level, "");
    if (bsd->vfollows)
        fprintf(f, "\"%s\"", bsd->vfollows);
    else
        fprintf(f, "(nil)");

    fprintf(f, "\n%*sistart=", indent_level, "");
    if (bsd->istart)
        yasm_intnum_print(bsd->istart, f);
    else
        fprintf(f, "(nil)");
    fprintf(f, "\n%*sivstart=", indent_level, "");
    if (bsd->ivstart)
        yasm_intnum_print(bsd->ivstart, f);
    else
        fprintf(f, "(nil)");

    fprintf(f, "\n%*slength=", indent_level, "");
    if (bsd->length)
        yasm_intnum_print(bsd->length, f);
    else
        fprintf(f, "(nil)");
    fprintf(f, "\n");
}

static void
bin_symrec_data_destroy(void *data)
{
    yasm_xfree(data);
}

static void
bin_symrec_data_print(void *data, FILE *f, int indent_level)
{
    bin_symrec_data *bsymd = (bin_symrec_data *)data;

    fprintf(f, "%*ssection=\"%s\"\n", indent_level, "",
            yasm_section_get_name(bsymd->section));
    fprintf(f, "%*swhich=", indent_level, "");
    switch (bsymd->which) {
        case SSYM_START: fprintf(f, "START"); break;
        case SSYM_VSTART: fprintf(f, "VSTART"); break;
        case SSYM_LENGTH: fprintf(f, "LENGTH"); break;
    }
    fprintf(f, "\n");
}


/* Define valid debug formats to use with this object format */
static const char *bin_objfmt_dbgfmt_keywords[] = {
    "null",
    NULL
};

static const yasm_directive bin_objfmt_directives[] = {
    { "org",    "nasm", bin_objfmt_dir_org,     YASM_DIR_ARG_REQUIRED },
    { "map",    "nasm", bin_objfmt_dir_map,     YASM_DIR_ANY },
    { NULL, NULL, NULL, 0 }
};

/* Define objfmt structure -- see objfmt.h for details */
yasm_objfmt_module yasm_bin_LTX_objfmt = {
    "Flat format binary",
    "bin",
    NULL,
    16,
    bin_objfmt_dbgfmt_keywords,
    "null",
    bin_objfmt_directives,
    bin_objfmt_create,
    bin_objfmt_output,
    bin_objfmt_destroy,
    bin_objfmt_add_default_section,
    bin_objfmt_section_switch,
    bin_objfmt_get_special_sym
};
