/*
 * COFF (DJGPP) 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>
#include <time.h>

#include <libyasm.h>

#include "coff-objfmt.h"


#define REGULAR_OUTBUF_SIZE     1024

/* Defining this to 0 sets all section VMA's to 0 rather than as the same as
 * the LMA.  According to the DJGPP COFF Spec, this should be set to 1
 * (VMA=LMA), and indeed DJGPP's GCC output shows VMA=LMA.  However, NASM
 * outputs VMA=0 (as if this was 0), and GNU objdump output looks a lot nicer
 * with VMA=0.  Who's right?  This is #defined as changing this setting affects
 * several places in the code.
 */
#define COFF_SET_VMA    (!objfmt_coff->win32)

#define COFF_MACHINE_I386       0x014C
#define COFF_MACHINE_AMD64      0x8664

#define COFF_F_LNNO     0x0004      /* line number info NOT present */
#define COFF_F_LSYMS    0x0008      /* local symbols NOT present */
#define COFF_F_AR32WR   0x0100      /* 32-bit little endian file */

typedef struct coff_reloc {
    yasm_reloc reloc;
    enum {
        COFF_RELOC_ABSOLUTE = 0,            /* absolute, no reloc needed */

        /* I386 relocations */
        COFF_RELOC_I386_ADDR16 = 0x1,       /* 16-bit absolute reference */
        COFF_RELOC_I386_REL16 = 0x2,        /* 16-bit PC-relative reference */
        COFF_RELOC_I386_ADDR32 = 0x6,       /* 32-bit absolute reference */
        COFF_RELOC_I386_ADDR32NB = 0x7,     /* 32-bit absolute ref w/o base */
        COFF_RELOC_I386_SEG12 = 0x9,        /* 16-bit absolute segment ref */
        COFF_RELOC_I386_SECTION = 0xA,      /* section index */
        COFF_RELOC_I386_SECREL = 0xB,       /* offset from start of segment */
        COFF_RELOC_I386_TOKEN = 0xC,        /* CLR metadata token */
        COFF_RELOC_I386_SECREL7 = 0xD,  /* 7-bit offset from base of sect */
        COFF_RELOC_I386_REL32 = 0x14,       /* 32-bit PC-relative reference */

        /* AMD64 relocations */
        COFF_RELOC_AMD64_ADDR64 = 0x1,      /* 64-bit address (VA) */
        COFF_RELOC_AMD64_ADDR32 = 0x2,      /* 32-bit address (VA) */
        COFF_RELOC_AMD64_ADDR32NB = 0x3,    /* 32-bit address w/o base (RVA) */
        COFF_RELOC_AMD64_REL32 = 0x4,       /* 32-bit relative (0 byte dist) */
        COFF_RELOC_AMD64_REL32_1 = 0x5,     /* 32-bit relative (1 byte dist) */
        COFF_RELOC_AMD64_REL32_2 = 0x6,     /* 32-bit relative (2 byte dist) */
        COFF_RELOC_AMD64_REL32_3 = 0x7,     /* 32-bit relative (3 byte dist) */
        COFF_RELOC_AMD64_REL32_4 = 0x8,     /* 32-bit relative (4 byte dist) */
        COFF_RELOC_AMD64_REL32_5 = 0x9,     /* 32-bit relative (5 byte dist) */
        COFF_RELOC_AMD64_SECTION = 0xA,     /* section index */
        COFF_RELOC_AMD64_SECREL = 0xB,  /* 32-bit offset from base of sect */
        COFF_RELOC_AMD64_SECREL7 = 0xC, /* 7-bit offset from base of sect */
        COFF_RELOC_AMD64_TOKEN = 0xD        /* CLR metadata token */
    } type;                         /* type of relocation */
} coff_reloc;

#define COFF_STYP_TEXT          0x00000020UL
#define COFF_STYP_DATA          0x00000040UL
#define COFF_STYP_BSS           0x00000080UL
#define COFF_STYP_INFO          0x00000200UL
#define COFF_STYP_STD_MASK      0x000003FFUL
#define COFF_STYP_ALIGN_MASK    0x00F00000UL
#define COFF_STYP_ALIGN_SHIFT   20
#define COFF_STYP_NRELOC_OVFL   0x01000000UL
#define COFF_STYP_DISCARD       0x02000000UL
#define COFF_STYP_NOCACHE       0x04000000UL
#define COFF_STYP_NOPAGE        0x08000000UL
#define COFF_STYP_SHARED        0x10000000UL
#define COFF_STYP_EXECUTE       0x20000000UL
#define COFF_STYP_READ          0x40000000UL
#define COFF_STYP_WRITE         0x80000000UL
#define COFF_STYP_WIN32_MASK    0xFF000000UL

#define COFF_FLAG_NOBASE        (1UL<<0)    /* Use no-base (NB) relocs */

typedef struct coff_section_data {
    /*@dependent@*/ yasm_symrec *sym;   /* symbol created for this section */
    unsigned int scnum;     /* section number (1=first section) */
    unsigned long flags;    /* section flags (see COFF_STYP_* above) */
    unsigned long addr;     /* starting memory address (first section -> 0) */
    unsigned long scnptr;   /* file ptr to raw data */
    unsigned long size;     /* size of raw data (section data) in bytes */
    unsigned long relptr;   /* file ptr to relocation */
    unsigned long nreloc;   /* number of relocation entries >64k -> error */
    unsigned long flags2;   /* internal flags (see COFF_FLAG_* above) */
    unsigned long strtab_name;  /* strtab offset of name if name > 8 chars */
    int isdebug;            /* is a debug section? */
} coff_section_data;

typedef enum coff_symrec_sclass {
    COFF_SCL_EFCN = 0xff,       /* physical end of function     */
    COFF_SCL_NULL = 0,
    COFF_SCL_AUTO = 1,          /* automatic variable           */
    COFF_SCL_EXT = 2,           /* external symbol              */
    COFF_SCL_STAT = 3,          /* static                       */
    COFF_SCL_REG = 4,           /* register variable            */
    COFF_SCL_EXTDEF = 5,        /* external definition          */
    COFF_SCL_LABEL = 6,         /* label                        */
    COFF_SCL_ULABEL = 7,        /* undefined label              */
    COFF_SCL_MOS = 8,           /* member of structure          */
    COFF_SCL_ARG = 9,           /* function argument            */
    COFF_SCL_STRTAG = 10,       /* structure tag                */
    COFF_SCL_MOU = 11,          /* member of union              */
    COFF_SCL_UNTAG = 12,        /* union tag                    */
    COFF_SCL_TPDEF = 13,        /* type definition              */
    COFF_SCL_USTATIC = 14,      /* undefined static             */
    COFF_SCL_ENTAG = 15,        /* enumeration tag              */
    COFF_SCL_MOE = 16,          /* member of enumeration        */
    COFF_SCL_REGPARM = 17,      /* register parameter           */
    COFF_SCL_FIELD = 18,        /* bit field                    */
    COFF_SCL_AUTOARG = 19,      /* auto argument                */
    COFF_SCL_LASTENT = 20,      /* dummy entry (end of block)   */
    COFF_SCL_BLOCK = 100,       /* ".bb" or ".eb"               */
    COFF_SCL_FCN = 101,         /* ".bf" or ".ef"               */
    COFF_SCL_EOS = 102,         /* end of structure             */
    COFF_SCL_FILE = 103,        /* file name                    */
    COFF_SCL_LINE = 104,        /* line # reformatted as symbol table entry */
    COFF_SCL_ALIAS = 105,       /* duplicate tag                */
    COFF_SCL_HIDDEN = 106       /* ext symbol in dmert public lib */
} coff_symrec_sclass;

typedef union coff_symtab_auxent {
    /* no data needed for section symbol auxent, all info avail from sym */
    /*@owned@*/ char *fname;        /* filename aux entry */
} coff_symtab_auxent;

typedef enum coff_symtab_auxtype {
    COFF_SYMTAB_AUX_NONE = 0,
    COFF_SYMTAB_AUX_SECT,
    COFF_SYMTAB_AUX_FILE
} coff_symtab_auxtype;

typedef struct coff_symrec_data {
    int forcevis;                       /* force visibility in symbol table */
    unsigned long index;                /* assigned COFF symbol table index */
    unsigned int type;                  /* type */
    coff_symrec_sclass sclass;          /* storage class */

    int numaux;                 /* number of auxiliary entries */
    coff_symtab_auxtype auxtype;    /* type of aux entries */
    coff_symtab_auxent aux[1];  /* actually may be any size (including 0) */
} coff_symrec_data;

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

    unsigned int parse_scnum;               /* sect numbering in parser */
    int win32;                              /* nonzero for win32/64 output */
    int win64;                              /* nonzero for win64 output */

    unsigned int machine;                   /* COFF machine to use */

    coff_symrec_data *filesym_data;         /* Data for .file symbol */

    /* data for .def/.endef and related directives */
    coff_symrec_data *def_sym;              /* symbol specified by .def */

    /* data for win64 proc_frame and related directives */
    unsigned long proc_frame;   /* Line number of start of proc, or 0 */
    unsigned long done_prolog;  /* Line number of end of prologue, or 0 */
    /*@null@*/ coff_unwind_info *unwind;        /* Unwind info */

    yasm_symrec *ssym_imagebase;            /* ..imagebase symbol for win64 */
} yasm_objfmt_coff;

typedef struct coff_objfmt_output_info {
    yasm_object *object;
    yasm_objfmt_coff *objfmt_coff;
    yasm_errwarns *errwarns;
    /*@dependent@*/ FILE *f;
    /*@only@*/ unsigned char *buf;
    yasm_section *sect;
    /*@dependent@*/ coff_section_data *csd;
    unsigned long addr;                 /* start of next section */

    unsigned long indx;                 /* current symbol index */
    int all_syms;                       /* outputting all symbols? */
    unsigned long strtab_offset;        /* current string table offset */
} coff_objfmt_output_info;

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

static const yasm_assoc_data_callback coff_section_data_cb = {
    coff_section_data_destroy,
    coff_section_data_print
};

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

static const yasm_assoc_data_callback coff_symrec_data_cb = {
    coff_symrec_data_destroy,
    coff_symrec_data_print
};

/* Bytecode callback function prototypes */
static void win32_sxdata_bc_destroy(void *contents);
static void win32_sxdata_bc_print(const void *contents, FILE *f,
                                  int indent_level);
static int win32_sxdata_bc_calc_len
    (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
static int win32_sxdata_bc_tobytes
    (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
     yasm_output_value_func output_value,
     /*@null@*/ yasm_output_reloc_func output_reloc);

/* Bytecode callback structures */
static const yasm_bytecode_callback win32_sxdata_bc_callback = {
    win32_sxdata_bc_destroy,
    win32_sxdata_bc_print,
    yasm_bc_finalize_common,
    NULL,
    win32_sxdata_bc_calc_len,
    yasm_bc_expand_common,
    win32_sxdata_bc_tobytes,
    0
};

yasm_objfmt_module yasm_coff_LTX_objfmt;
yasm_objfmt_module yasm_win32_LTX_objfmt;
yasm_objfmt_module yasm_win64_LTX_objfmt;


static /*@dependent@*/ coff_symrec_data *
coff_objfmt_sym_set_data(yasm_symrec *sym, coff_symrec_sclass sclass,
                         int numaux, coff_symtab_auxtype auxtype)
{
    coff_symrec_data *sym_data;

    sym_data = yasm_xmalloc(sizeof(coff_symrec_data) +
                            (numaux-1)*sizeof(coff_symtab_auxent));
    sym_data->forcevis = 0;
    sym_data->index = 0;
    sym_data->type = 0;
    sym_data->sclass = sclass;
    sym_data->numaux = numaux;
    sym_data->auxtype = auxtype;

    yasm_symrec_add_data(sym, &coff_symrec_data_cb, sym_data);

    return sym_data;
}

static yasm_objfmt_coff *
coff_common_create(yasm_object *object)
{
    yasm_objfmt_coff *objfmt_coff = yasm_xmalloc(sizeof(yasm_objfmt_coff));
    yasm_symrec *filesym;

    /* Only support x86 arch */
    if (yasm__strcasecmp(yasm_arch_keyword(object->arch), "x86") != 0) {
        yasm_xfree(objfmt_coff);
        return NULL;
    }

    objfmt_coff->parse_scnum = 1;    /* section numbering starts at 1 */

    /* FIXME: misuse of NULL bytecode here; it works, but only barely. */
    filesym = yasm_symtab_define_special(object->symtab, ".file",
                                         YASM_SYM_GLOBAL);
    objfmt_coff->filesym_data =
        coff_objfmt_sym_set_data(filesym, COFF_SCL_FILE, 1,
                                 COFF_SYMTAB_AUX_FILE);
    /* Filename is set in coff_objfmt_output */
    objfmt_coff->filesym_data->aux[0].fname = NULL;

    objfmt_coff->proc_frame = 0;
    objfmt_coff->done_prolog = 0;
    objfmt_coff->unwind = NULL;
    objfmt_coff->ssym_imagebase = NULL;

    return objfmt_coff;
}

static yasm_objfmt *
coff_objfmt_create(yasm_object *object)
{
    yasm_objfmt_coff *objfmt_coff = coff_common_create(object);

    if (objfmt_coff) {
        /* Support x86 and amd64 machines of x86 arch */
        if (yasm__strcasecmp(yasm_arch_get_machine(object->arch), "x86") == 0)
            objfmt_coff->machine = COFF_MACHINE_I386;
        else if (yasm__strcasecmp(yasm_arch_get_machine(object->arch),
                                  "amd64") == 0)
            objfmt_coff->machine = COFF_MACHINE_AMD64;
        else {
            yasm_xfree(objfmt_coff);
            return NULL;
        }

        objfmt_coff->objfmt.module = &yasm_coff_LTX_objfmt;
        objfmt_coff->win32 = 0;
        objfmt_coff->win64 = 0;
    }
    return (yasm_objfmt *)objfmt_coff;
}

static yasm_objfmt *
win32_objfmt_create(yasm_object *object)
{
    yasm_objfmt_coff *objfmt_coff = coff_common_create(object);

    if (objfmt_coff) {
        /* Support x86 and amd64 machines of x86 arch.
         * (amd64 machine supported for backwards compatibility)
         */
        if (yasm__strcasecmp(yasm_arch_get_machine(object->arch),
                             "x86") == 0) {
            objfmt_coff->machine = COFF_MACHINE_I386;
            objfmt_coff->objfmt.module = &yasm_win32_LTX_objfmt;
            objfmt_coff->win64 = 0;
        } else if (yasm__strcasecmp(yasm_arch_get_machine(object->arch),
                                    "amd64") == 0) {
            objfmt_coff->machine = COFF_MACHINE_AMD64;
            objfmt_coff->objfmt.module = &yasm_win64_LTX_objfmt;
            objfmt_coff->win64 = 1;
        } else {
            yasm_xfree(objfmt_coff);
            return NULL;
        }

        objfmt_coff->win32 = 1;
        /* Define a @feat.00 symbol for win32 safeseh handling */
        if (!objfmt_coff->win64) {
            yasm_symrec *feat00;
            coff_symrec_data *sym_data;
            feat00 = yasm_symtab_define_equ(object->symtab, "@feat.00",
                yasm_expr_create_ident(yasm_expr_int(
                    yasm_intnum_create_uint(1)), 0), 0);
            sym_data = coff_objfmt_sym_set_data(feat00, COFF_SCL_STAT, 0,
                                                COFF_SYMTAB_AUX_NONE);
            sym_data->forcevis = 1;
        }
    }
    return (yasm_objfmt *)objfmt_coff;
}

static yasm_objfmt *
win64_objfmt_create(yasm_object *object)
{
    yasm_objfmt_coff *objfmt_coff = coff_common_create(object);

    if (objfmt_coff) {
        /* Support amd64 machine of x86 arch */
        if (yasm__strcasecmp(yasm_arch_get_machine(object->arch),
                             "amd64") == 0) {
            objfmt_coff->machine = COFF_MACHINE_AMD64;
        } else {
            yasm_xfree(objfmt_coff);
            return NULL;
        }

        objfmt_coff->objfmt.module = &yasm_win64_LTX_objfmt;
        objfmt_coff->win32 = 1;
        objfmt_coff->win64 = 1;
        objfmt_coff->ssym_imagebase =
            yasm_symtab_define_label(object->symtab, "..imagebase", NULL, 0, 0);
    }
    return (yasm_objfmt *)objfmt_coff;
}

static void
coff_objfmt_init_new_section(yasm_section *sect, unsigned long line)
{
    yasm_object *object = yasm_section_get_object(sect);
    const char *sectname = yasm_section_get_name(sect);
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    coff_section_data *data;
    yasm_symrec *sym;

    data = yasm_xmalloc(sizeof(coff_section_data));
    data->scnum = objfmt_coff->parse_scnum++;
    data->flags = 0;
    data->addr = 0;
    data->scnptr = 0;
    data->size = 0;
    data->relptr = 0;
    data->nreloc = 0;
    data->flags2 = 0;
    data->strtab_name = 0;
    data->isdebug = 0;

    if (yasm__strncasecmp(sectname, ".debug", 6)==0) {
        data->flags = COFF_STYP_DATA;
        if (objfmt_coff->win32)
            data->flags |= COFF_STYP_DISCARD|COFF_STYP_READ;
        data->isdebug = 1;
    } else
        data->flags = COFF_STYP_TEXT;

    yasm_section_add_data(sect, &coff_section_data_cb, data);

    sym = yasm_symtab_define_label(object->symtab, sectname,
                                   yasm_section_bcs_first(sect), 1, line);
    yasm_symrec_declare(sym, YASM_SYM_GLOBAL, line);
    coff_objfmt_sym_set_data(sym, COFF_SCL_STAT, 1, COFF_SYMTAB_AUX_SECT);
    data->sym = sym;
}

static int
coff_objfmt_set_section_addr(yasm_section *sect, /*@null@*/ void *d)
{
    /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
    /*@dependent@*/ /*@null@*/ coff_section_data *csd;

    assert(info != NULL);
    csd = yasm_section_get_data(sect, &coff_section_data_cb);
    assert(csd != NULL);

    csd->addr = info->addr;
    info->addr += yasm_bc_next_offset(yasm_section_bcs_last(sect));

    return 0;
}

static int
coff_objfmt_output_value(yasm_value *value, unsigned char *buf,
                         unsigned int destsize, unsigned long offset,
                         yasm_bytecode *bc, int warn, /*@null@*/ void *d)
{
    /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
    yasm_objfmt_coff *objfmt_coff;
    /*@only@*/ /*@null@*/ yasm_intnum *dist = NULL;
    /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
    unsigned long intn_val, intn_minus;
    int retval;
    unsigned int valsize = value->size;

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

    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;
    }

    /* Handle other expressions, with relocation if necessary */
    if (value->rshift > 0
        || (value->seg_of && (value->wrt || value->curpos_rel))
        || (value->section_rel && (value->wrt || value->curpos_rel))) {
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("coff: relocation too complex"));
        return 1;
    }

    intn_val = 0;
    intn_minus = 0;
    if (value->rel) {
        yasm_sym_vis vis = yasm_symrec_get_visibility(value->rel);
        /*@dependent@*/ /*@null@*/ yasm_symrec *sym = value->rel;
        unsigned long addr;
        coff_reloc *reloc;
        int nobase = info->csd->flags2 & COFF_FLAG_NOBASE;

        /* Sometimes we want the relocation to be generated against one
         * symbol but the value generated correspond to a different symbol.
         * This is done through (sym being referenced) WRT (sym used for
         * reloc).  Note both syms need to be in the same section!
         */
        if (value->wrt && value->wrt == objfmt_coff->ssym_imagebase)
            nobase = 1;
        else if (value->wrt) {
            /*@dependent@*/ /*@null@*/ yasm_bytecode *rel_precbc, *wrt_precbc;

            if (!yasm_symrec_get_label(sym, &rel_precbc)
                || !yasm_symrec_get_label(value->wrt, &wrt_precbc)) {
                yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                               N_("coff: wrt expression too complex"));
                return 1;
            }
            dist = yasm_calc_bc_dist(wrt_precbc, rel_precbc);
            if (!dist) {
                yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                               N_("coff: cannot wrt across sections"));
                return 1;
            }
            sym = value->wrt;
        }

        if (vis & YASM_SYM_COMMON) {
            /* In standard COFF, COMMON symbols have their length added in */
            if (!objfmt_coff->win32) {
                /*@dependent@*/ /*@null@*/ yasm_expr **csize_expr;
                /*@dependent@*/ /*@null@*/ yasm_intnum *common_size;

                csize_expr = yasm_symrec_get_common_size(sym);
                assert(csize_expr != NULL);
                common_size = yasm_expr_get_intnum(csize_expr, 1);
                if (!common_size) {
                    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                                   N_("coff: common size too complex"));
                    return 1;
                }

                if (yasm_intnum_sign(common_size) < 0) {
                    yasm_error_set(YASM_ERROR_VALUE,
                                   N_("coff: common size is negative"));
                    return 1;
                }

                intn_val += yasm_intnum_get_uint(common_size);
            }
        } else if (!(vis & YASM_SYM_EXTERN) && !objfmt_coff->win64) {
            /*@dependent@*/ /*@null@*/ yasm_bytecode *sym_precbc;

            /* Local symbols need relocation to their section's start */
            if (yasm_symrec_get_label(sym, &sym_precbc)) {
                yasm_section *sym_sect = yasm_bc_get_section(sym_precbc);
                /*@null@*/ coff_section_data *sym_csd;
                sym_csd = yasm_section_get_data(sym_sect,
                                                &coff_section_data_cb);
                assert(sym_csd != NULL);
                sym = sym_csd->sym;
                intn_val = yasm_bc_next_offset(sym_precbc);
                if (COFF_SET_VMA)
                    intn_val += sym_csd->addr;
            }
        }

        if (value->curpos_rel) {
            /* For standard COFF, need to adjust to start of section, e.g.
             * subtract out the bytecode offset.
             * For Win32 COFF, need to adjust based on value size and position.
             * For Win64 COFF that's IP-relative, adjust to next bytecode;
             * the difference between the offset+destsize and BC length is
             * taken care of by special relocation types.
             */
            if (objfmt_coff->win64 && value->ip_rel)
                intn_val += bc->len*bc->mult_int;
            else if (objfmt_coff->win32)
                intn_val += offset+destsize;
            else
                intn_minus = bc->offset;
        }

        if (value->seg_of) {
            /* Segment generation; zero value. */
            intn_val = 0;
            intn_minus = 0;
        }

        /* Generate reloc */
        reloc = yasm_xmalloc(sizeof(coff_reloc));
        addr = bc->offset + offset;
        if (COFF_SET_VMA)
            addr += info->addr;
        reloc->reloc.addr = yasm_intnum_create_uint(addr);
        reloc->reloc.sym = sym;

        if (value->curpos_rel) {
            if (objfmt_coff->machine == COFF_MACHINE_I386) {
                if (valsize == 32)
                    reloc->type = COFF_RELOC_I386_REL32;
                else {
                    yasm_error_set(YASM_ERROR_TYPE,
                                   N_("coff: invalid relocation size"));
                    return 1;
                }
            } else if (objfmt_coff->machine == COFF_MACHINE_AMD64) {
                if (valsize != 32) {
                    yasm_error_set(YASM_ERROR_TYPE,
                                   N_("coff: invalid relocation size"));
                    return 1;
                }
                if (!value->ip_rel)
                    reloc->type = COFF_RELOC_AMD64_REL32;
                else switch (bc->len*bc->mult_int - (offset+destsize)) {
                    case 0:
                        reloc->type = COFF_RELOC_AMD64_REL32;
                        break;
                    case 1:
                        reloc->type = COFF_RELOC_AMD64_REL32_1;
                        break;
                    case 2:
                        reloc->type = COFF_RELOC_AMD64_REL32_2;
                        break;
                    case 3:
                        reloc->type = COFF_RELOC_AMD64_REL32_3;
                        break;
                    case 4:
                        reloc->type = COFF_RELOC_AMD64_REL32_4;
                        break;
                    case 5:
                        reloc->type = COFF_RELOC_AMD64_REL32_5;
                        break;
                    default:
                        yasm_error_set(YASM_ERROR_TYPE,
                                       N_("coff: invalid relocation size"));
                        return 1;
                }
            } else
                yasm_internal_error(N_("coff objfmt: unrecognized machine"));
        } else if (value->seg_of) {
            if (objfmt_coff->machine == COFF_MACHINE_I386)
                reloc->type = COFF_RELOC_I386_SECTION;
            else if (objfmt_coff->machine == COFF_MACHINE_AMD64)
                reloc->type = COFF_RELOC_AMD64_SECTION;
            else
                yasm_internal_error(N_("coff objfmt: unrecognized machine"));
        } else if (value->section_rel) {
            if (objfmt_coff->machine == COFF_MACHINE_I386)
                reloc->type = COFF_RELOC_I386_SECREL;
            else if (objfmt_coff->machine == COFF_MACHINE_AMD64)
                reloc->type = COFF_RELOC_AMD64_SECREL;
            else
                yasm_internal_error(N_("coff objfmt: unrecognized machine"));
        } else {
            if (objfmt_coff->machine == COFF_MACHINE_I386) {
                if (nobase)
                    reloc->type = COFF_RELOC_I386_ADDR32NB;
                else
                    reloc->type = COFF_RELOC_I386_ADDR32;
            } else if (objfmt_coff->machine == COFF_MACHINE_AMD64) {
                if (valsize == 32) {
                    if (nobase)
                        reloc->type = COFF_RELOC_AMD64_ADDR32NB;
                    else
                        reloc->type = COFF_RELOC_AMD64_ADDR32;
                } else if (valsize == 64)
                    reloc->type = COFF_RELOC_AMD64_ADDR64;
                else {
                    yasm_error_set(YASM_ERROR_TYPE,
                                   N_("coff: invalid relocation size"));
                    return 1;
                }
            } else
                yasm_internal_error(N_("coff objfmt: unrecognized machine"));
        }
        info->csd->nreloc++;
        yasm_section_add_reloc(info->sect, (yasm_reloc *)reloc, yasm_xfree);
    }

    /* Build up final integer output from intn_val, intn_minus, value->abs,
     * and dist.  We do all this at the end to avoid creating temporary
     * intnums above (except for dist).
     */
    if (intn_minus <= intn_val)
        intn = yasm_intnum_create_uint(intn_val-intn_minus);
    else {
        intn = yasm_intnum_create_uint(intn_minus-intn_val);
        yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
    }

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

    if (dist) {
        yasm_intnum_calc(intn, YASM_EXPR_ADD, dist);
        yasm_intnum_destroy(dist);
    }

    retval = yasm_arch_intnum_tobytes(info->object->arch, intn, buf, destsize,
                                      valsize, 0, bc, warn);
    yasm_intnum_destroy(intn);
    return retval;
}

static int
coff_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
{
    /*@null@*/ coff_objfmt_output_info *info = (coff_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,
                             coff_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;
    }

    info->csd->size += size;

    /* 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;
}

static int
coff_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
{
    /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
    /*@dependent@*/ /*@null@*/ coff_section_data *csd;
    long pos;
    coff_reloc *reloc;
    unsigned char *localbuf;

    assert(info != NULL);
    csd = yasm_section_get_data(sect, &coff_section_data_cb);
    assert(csd != NULL);

    /* Add to strtab if in win32 format and name > 8 chars */
    if (info->objfmt_coff->win32) {
        size_t namelen = strlen(yasm_section_get_name(sect));
        if (namelen > 8) {
            csd->strtab_name = info->strtab_offset;
            info->strtab_offset += (unsigned long)(namelen + 1);
        }
    }

    if (!csd->isdebug)
        csd->addr = info->addr;

    if ((csd->flags & COFF_STYP_STD_MASK) == COFF_STYP_BSS) {
        /* Don't output BSS sections.
         * TODO: Check for non-reserve bytecodes?
         */
        pos = 0;    /* position = 0 because it's not in the file */
        csd->size = yasm_bc_next_offset(yasm_section_bcs_last(sect));
    } else {
        pos = ftell(info->f);
        if (pos == -1) {
            yasm__fatal(N_("could not get file position on output file"));
            /*@notreached@*/
            return 1;
        }

        info->sect = sect;
        info->csd = csd;
        yasm_section_bcs_traverse(sect, info->errwarns, info,
                                  coff_objfmt_output_bytecode);

        /* Sanity check final section size */
        if (yasm_errwarns_num_errors(info->errwarns, 0) == 0 &&
            csd->size != yasm_bc_next_offset(yasm_section_bcs_last(sect)))
            yasm_internal_error(
                N_("coff: section computed size did not match actual size"));
    }

    /* Empty?  Go on to next section */
    if (csd->size == 0)
        return 0;

    if (!csd->isdebug)
        info->addr += csd->size;
    csd->scnptr = (unsigned long)pos;

    /* No relocations to output?  Go on to next section */
    if (csd->nreloc == 0)
        return 0;

    pos = ftell(info->f);
    if (pos == -1) {
        yasm__fatal(N_("could not get file position on output file"));
        /*@notreached@*/
        return 1;
    }
    csd->relptr = (unsigned long)pos;

    /* If >=64K relocs (for Win32/64), we set a flag in the section header
     * (NRELOC_OVFL) and the first relocation contains the number of relocs.
     */
    if (csd->nreloc >= 64*1024 && info->objfmt_coff->win32) {
        localbuf = info->buf;
        YASM_WRITE_32_L(localbuf, csd->nreloc+1);   /* address of relocation */
        YASM_WRITE_32_L(localbuf, 0);           /* relocated symbol */
        YASM_WRITE_16_L(localbuf, 0);           /* type of relocation */
        fwrite(info->buf, 10, 1, info->f);
    }

    reloc = (coff_reloc *)yasm_section_relocs_first(sect);
    while (reloc) {
        /*@null@*/ coff_symrec_data *csymd;
        localbuf = info->buf;

        csymd = yasm_symrec_get_data(reloc->reloc.sym, &coff_symrec_data_cb);
        if (!csymd)
            yasm_internal_error(
                N_("coff: no symbol data for relocated symbol"));

        yasm_intnum_get_sized(reloc->reloc.addr, localbuf, 4, 32, 0, 0, 0);
        localbuf += 4;                          /* address of relocation */
        YASM_WRITE_32_L(localbuf, csymd->index);    /* relocated symbol */
        YASM_WRITE_16_L(localbuf, reloc->type);     /* type of relocation */
        fwrite(info->buf, 10, 1, info->f);

        reloc = (coff_reloc *)yasm_section_reloc_next((yasm_reloc *)reloc);
    }

    return 0;
}

static int
coff_objfmt_output_sectstr(yasm_section *sect, /*@null@*/ void *d)
{
    /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
    const char *name;
    size_t len;

    /* Add to strtab if in win32 format and name > 8 chars */
    if (!info->objfmt_coff->win32)
       return 0;
    
    name = yasm_section_get_name(sect);
    len = strlen(name);
    if (len > 8)
        fwrite(name, len+1, 1, info->f);
    return 0;
}

static int
coff_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
{
    /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
    yasm_objfmt_coff *objfmt_coff;
    /*@dependent@*/ /*@null@*/ coff_section_data *csd;
    unsigned char *localbuf;
    unsigned long align = yasm_section_get_align(sect);

    assert(info != NULL);
    objfmt_coff = info->objfmt_coff;
    csd = yasm_section_get_data(sect, &coff_section_data_cb);
    assert(csd != NULL);

    /* Check to see if alignment is supported size */
    if (align > 8192)
        align = 8192;

    /* Convert alignment into flags setting */
    csd->flags &= ~COFF_STYP_ALIGN_MASK;
    while (align != 0) {
        csd->flags += 1<<COFF_STYP_ALIGN_SHIFT;
        align >>= 1;
    }

    /* section name */
    localbuf = info->buf;
    if (strlen(yasm_section_get_name(sect)) > 8) {
        char namenum[30];
        sprintf(namenum, "/%ld", csd->strtab_name);
        strncpy((char *)localbuf, namenum, 8);
    } else
        strncpy((char *)localbuf, yasm_section_get_name(sect), 8);
    localbuf += 8;
    if (csd->isdebug) {
        YASM_WRITE_32_L(localbuf, 0);           /* physical address */
        YASM_WRITE_32_L(localbuf, 0);           /* virtual address */
    } else {
        YASM_WRITE_32_L(localbuf, csd->addr);   /* physical address */
        if (COFF_SET_VMA)
            YASM_WRITE_32_L(localbuf, csd->addr);/* virtual address */
        else
            YASM_WRITE_32_L(localbuf, 0);       /* virtual address */
    }
    YASM_WRITE_32_L(localbuf, csd->size);       /* section size */
    YASM_WRITE_32_L(localbuf, csd->scnptr);     /* file ptr to data */
    YASM_WRITE_32_L(localbuf, csd->relptr);     /* file ptr to relocs */
    YASM_WRITE_32_L(localbuf, 0);               /* file ptr to line nums */
    if (csd->nreloc >= 64*1024) {
        /* Win32/64 has special handling for this case. */
        if (objfmt_coff->win32)
            csd->flags |= COFF_STYP_NRELOC_OVFL;
        else {
            yasm_warn_set(YASM_WARN_GENERAL,
                          N_("too many relocations in section `%s'"),
                          yasm_section_get_name(sect));
            yasm_errwarn_propagate(info->errwarns, 0);
        }
        YASM_WRITE_16_L(localbuf, 0xFFFF);      /* max out */
    } else
        YASM_WRITE_16_L(localbuf, csd->nreloc); /* num of relocation entries */
    YASM_WRITE_16_L(localbuf, 0);               /* num of line number entries */
    YASM_WRITE_32_L(localbuf, csd->flags);      /* flags */
    fwrite(info->buf, 40, 1, info->f);

    return 0;
}

static int
coff_objfmt_count_sym(yasm_symrec *sym, /*@null@*/ void *d)
{
    /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
    yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
    coff_symrec_data *sym_data;

    assert(info != NULL);

    sym_data = yasm_symrec_get_data(sym, &coff_symrec_data_cb);

    if (info->all_syms || vis != YASM_SYM_LOCAL || yasm_symrec_is_abs(sym) ||
        (sym_data && sym_data->forcevis)) {
        /* Save index in symrec data */
        if (!sym_data)
            sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_NULL, 0,
                                                COFF_SYMTAB_AUX_NONE);
        /* Set storage class based on visibility if not already set */
        if (sym_data->sclass == COFF_SCL_NULL) {
            if (vis & (YASM_SYM_EXTERN|YASM_SYM_GLOBAL|YASM_SYM_COMMON))
                sym_data->sclass = COFF_SCL_EXT;
            else
                sym_data->sclass = COFF_SCL_STAT;
        }

        sym_data->index = info->indx;

        info->indx += sym_data->numaux + 1;
    }
    return 0;
}

static int
coff_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
{
    /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
    yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
    int is_abs = yasm_symrec_is_abs(sym);
    /*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
    yasm_valparamhead *objext_valparams =
        yasm_symrec_get_objext_valparams(sym);
    csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);

    assert(info != NULL);

    /* Look for "function" flag on global syms */
    if (csymd && csymd->type == 0 && (vis & YASM_SYM_GLOBAL) != 0) {
        if (objext_valparams) {
            const char *id = yasm_vp_id(yasm_vps_first(objext_valparams));
            if (yasm__strcasecmp(id, "function") == 0)
                csymd->type = 0x20;
        }
    }

    /* Don't output local syms unless outputting all syms */
    if (info->all_syms || vis != YASM_SYM_LOCAL || is_abs ||
        (csymd && csymd->forcevis)) {
        /*@only*/ char *name;
        const yasm_expr *equ_val;
        const yasm_intnum *intn;
        unsigned char *localbuf;
        size_t len;
        int aux;
        unsigned long value = 0;
        unsigned int scnum = 0xfffe;    /* -2 = debugging symbol */
        /*@dependent@*/ /*@null@*/ yasm_section *sect;
        /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
        unsigned long scnlen = 0;   /* for sect auxent */
        unsigned long nreloc = 0;   /* for sect auxent */
        yasm_objfmt_coff *objfmt_coff = info->objfmt_coff;

        if (is_abs)
            name = yasm__xstrdup(".absolut");
        else
            name = yasm_symrec_get_global_name(sym, info->object);
        len = strlen(name);

        /* Get symrec's of_data (needed for storage class) */
        if (!csymd)
            yasm_internal_error(N_("coff: expected sym data to be present"));

        /* 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@*/ coff_section_data *csectd;
                csectd = yasm_section_get_data(sect, &coff_section_data_cb);
                if (csectd) {
                    scnum = csectd->scnum;
                    scnlen = csectd->size;
                    nreloc = csectd->nreloc;
                    if (COFF_SET_VMA)
                        value = csectd->addr;
                } 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);

            scnum = 0xffff;     /* -1 = absolute symbol */
        } else {
            if (vis & YASM_SYM_COMMON) {
                /*@dependent@*/ /*@null@*/ yasm_expr **csize_expr;
                csize_expr = yasm_symrec_get_common_size(sym);
                assert(csize_expr != NULL);
                intn = yasm_expr_get_intnum(csize_expr, 1);
                if (!intn) {
                    yasm_error_set(YASM_ERROR_NOT_CONSTANT,
                        N_("COMMON data size not an integer expression"));
                    yasm_errwarn_propagate(info->errwarns,
                                           (*csize_expr)->line);
                } else
                    value = yasm_intnum_get_uint(intn);
                scnum = 0;
            }
            if (vis & YASM_SYM_EXTERN)
                scnum = 0;
        }

        localbuf = info->buf;
        if (len > 8) {
            YASM_WRITE_32_L(localbuf, 0);       /* "zeros" field */
            YASM_WRITE_32_L(localbuf, info->strtab_offset); /* strtab offset */
            info->strtab_offset += (unsigned long)(len+1);
        } else {
            /* <8 chars, so no string table entry needed */
            strncpy((char *)localbuf, name, 8);
            localbuf += 8;
        }
        YASM_WRITE_32_L(localbuf, value);       /* value */
        YASM_WRITE_16_L(localbuf, scnum);       /* section number */
        YASM_WRITE_16_L(localbuf, csymd->type); /* type */
        YASM_WRITE_8(localbuf, csymd->sclass);  /* storage class */
        YASM_WRITE_8(localbuf, csymd->numaux);  /* number of aux entries */
        fwrite(info->buf, 18, 1, info->f);
        for (aux=0; aux<csymd->numaux; aux++) {
            localbuf = info->buf;
            memset(localbuf, 0, 18);
            switch (csymd->auxtype) {
                case COFF_SYMTAB_AUX_NONE:
                    break;
                case COFF_SYMTAB_AUX_SECT:
                    YASM_WRITE_32_L(localbuf, scnlen);  /* section length */
                    YASM_WRITE_16_L(localbuf, nreloc);  /* number relocs */
                    YASM_WRITE_16_L(localbuf, 0);       /* number line nums */
                    break;
                case COFF_SYMTAB_AUX_FILE:
                    len = strlen(csymd->aux[0].fname);
                    if (len > 14) {
                        YASM_WRITE_32_L(localbuf, 0);
                        YASM_WRITE_32_L(localbuf, info->strtab_offset);
                        info->strtab_offset += (unsigned long)(len+1);
                    } else
                        strncpy((char *)localbuf, csymd->aux[0].fname, 14);
                    break;
                default:
                    yasm_internal_error(
                        N_("coff: unrecognized aux symtab type"));
            }
            fwrite(info->buf, 18, 1, info->f);
        }
        yasm_xfree(name);
    }
    return 0;
}

static int
coff_objfmt_output_str(yasm_symrec *sym, /*@null@*/ void *d)
{
    /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
    yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
    /*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
    csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);

    assert(info != NULL);

    /* Don't output local syms unless outputting all syms */
    if (info->all_syms || vis != YASM_SYM_LOCAL ||
        (csymd && csymd->forcevis)) {
        /*@only@*/ char *name = yasm_symrec_get_global_name(sym, info->object);
        size_t len = strlen(name);
        int aux;

        if (!csymd)
            yasm_internal_error(N_("coff: expected sym data to be present"));

        if (len > 8)
            fwrite(name, len+1, 1, info->f);
        for (aux=0; aux<csymd->numaux; aux++) {
            switch (csymd->auxtype) {
                case COFF_SYMTAB_AUX_FILE:
                    len = strlen(csymd->aux[0].fname);
                    if (len > 14)
                        fwrite(csymd->aux[0].fname, len+1, 1, info->f);
                    break;
                default:
                    break;
            }
        }
        yasm_xfree(name);
    }
    return 0;
}

static void
coff_objfmt_output(yasm_object *object, FILE *f, int all_syms,
                   yasm_errwarns *errwarns)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    coff_objfmt_output_info info;
    unsigned char *localbuf;
    long pos;
    unsigned long symtab_pos;
    unsigned long symtab_count;
    unsigned int flags;
    unsigned long ts;

    if (objfmt_coff->proc_frame) {
        yasm_error_set_xref(objfmt_coff->proc_frame,
                            N_("procedure started here"));
        yasm_error_set(YASM_ERROR_GENERAL,
                       N_("end of file in procedure frame"));
        yasm_errwarn_propagate(errwarns, 0);
        return;
    }

    if (objfmt_coff->filesym_data->aux[0].fname)
        yasm_xfree(objfmt_coff->filesym_data->aux[0].fname);
    objfmt_coff->filesym_data->aux[0].fname =
        yasm__xstrdup(object->src_filename);

    /* Force all syms for win64 because they're needed for relocations.
     * FIXME: Not *all* syms need to be output, only the ones needed for
     * relocation.  Find a way to do that someday.
     */
    all_syms |= objfmt_coff->win64;

    info.strtab_offset = 4;
    info.object = object;
    info.objfmt_coff = objfmt_coff;
    info.errwarns = errwarns;
    info.f = f;
    info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);

    /* Allocate space for headers by seeking forward */
    if (fseek(f, (long)(20+40*(objfmt_coff->parse_scnum-1)), SEEK_SET) < 0) {
        yasm__fatal(N_("could not seek on output file"));
        /*@notreached@*/
        return;
    }

    /* Finalize symbol table (assign index to each symbol) */
    info.indx = 0;
    info.all_syms = all_syms;
    yasm_symtab_traverse(object->symtab, &info, coff_objfmt_count_sym);
    symtab_count = info.indx;

    /* Section data/relocs */
    if (COFF_SET_VMA) {
        /* If we're setting the VMA, we need to do a first section pass to
         * determine each section's addr value before actually outputting
         * relocations, as a relocation's section address is added into the
         * addends in the generated code.
         */
        info.addr = 0;
        if (yasm_object_sections_traverse(object, &info,
                                          coff_objfmt_set_section_addr))
            return;
    }
    info.addr = 0;
    if (yasm_object_sections_traverse(object, &info,
                                      coff_objfmt_output_section))
        return;

    /* Symbol table */
    pos = ftell(f);
    if (pos == -1) {
        yasm__fatal(N_("could not get file position on output file"));
        /*@notreached@*/
        return;
    }
    symtab_pos = (unsigned long)pos;
    yasm_symtab_traverse(object->symtab, &info, coff_objfmt_output_sym);

    /* String table */
    yasm_fwrite_32_l(info.strtab_offset, f); /* total length */
    yasm_object_sections_traverse(object, &info, coff_objfmt_output_sectstr);
    yasm_symtab_traverse(object->symtab, &info, coff_objfmt_output_str);

    /* Write headers */
    if (fseek(f, 0, SEEK_SET) < 0) {
        yasm__fatal(N_("could not seek on output file"));
        /*@notreached@*/
        return;
    }

    localbuf = info.buf;
    YASM_WRITE_16_L(localbuf, objfmt_coff->machine);    /* magic number */
    YASM_WRITE_16_L(localbuf, objfmt_coff->parse_scnum-1);/* number of sects */
    if (getenv("YASM_TEST_SUITE"))
        ts = 0;
    else
        ts = (unsigned long)time(NULL);
    YASM_WRITE_32_L(localbuf, ts);                      /* time/date stamp */
    YASM_WRITE_32_L(localbuf, symtab_pos);              /* file ptr to symtab */
    YASM_WRITE_32_L(localbuf, symtab_count);            /* number of symtabs */
    YASM_WRITE_16_L(localbuf, 0);       /* size of optional header (none) */
    /* flags */
    flags = 0;
    if (strcmp(yasm_dbgfmt_keyword(object->dbgfmt), "null")==0)
        flags = COFF_F_LNNO;
    if (!all_syms)
        flags |= COFF_F_LSYMS;
    if (objfmt_coff->machine != COFF_MACHINE_AMD64)
        flags |= COFF_F_AR32WR;
    YASM_WRITE_16_L(localbuf, flags);
    fwrite(info.buf, 20, 1, f);

    yasm_object_sections_traverse(object, &info, coff_objfmt_output_secthead);

    yasm_xfree(info.buf);
}

static void
coff_objfmt_destroy(yasm_objfmt *objfmt)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt;
    if (objfmt_coff->filesym_data->aux[0].fname)
        yasm_xfree(objfmt_coff->filesym_data->aux[0].fname);
    if (objfmt_coff->unwind)
        yasm_win64__uwinfo_destroy(objfmt_coff->unwind);
    yasm_xfree(objfmt);
}

static yasm_section *
coff_objfmt_add_default_section(yasm_object *object)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_section *retval;
    coff_section_data *csd;
    int isnew;

    retval = yasm_object_get_general(object, ".text", 16, 1, 0, &isnew, 0);
    if (isnew) {
        csd = yasm_section_get_data(retval, &coff_section_data_cb);
        csd->flags = COFF_STYP_TEXT;
        if (objfmt_coff->win32)
            csd->flags |= COFF_STYP_EXECUTE | COFF_STYP_READ;
        yasm_section_set_default(retval, 1);
    }
    return retval;
}

struct coff_section_switch_data {
    int isdefault;
    int gasflags;
    unsigned long flags;
    unsigned long flags2;
    /*@only@*/ /*@null@*/ yasm_intnum *align_intn;
};

/* GAS-style flags */
static int
coff_helper_gasflags(void *obj, yasm_valparam *vp, unsigned long line, void *d,
                     /*@unused@*/ uintptr_t arg)
{
    struct coff_section_switch_data *data =
        (struct coff_section_switch_data *)d;
    int alloc = 0, load = 0, readonly = 0, code = 0, datasect = 0;
    int shared = 0;
    const char *s = yasm_vp_string(vp);
    size_t i;

    if (!s) {
        yasm_error_set(YASM_ERROR_VALUE, N_("non-string section attribute"));
        return -1;
    }

    /* For GAS, default to read/write data */
    if (data->isdefault)
        data->flags = COFF_STYP_TEXT | COFF_STYP_READ | COFF_STYP_WRITE;

    for (i=0; i<strlen(s); i++) {
        switch (s[i]) {
            case 'a':
                break;
            case 'b':
                alloc = 1;
                load = 0;
                break;
            case 'n':
                load = 0;
                break;
            case 's':
                shared = 1;
                /*@fallthrough@*/
            case 'd':
                datasect = 1;
                load = 1;
                readonly = 0;
                break;
            case 'x':
                code = 1;
                load = 1;
                break;
            case 'r':
                datasect = 1;
                load = 1;
                readonly = 1;
                break;
            case 'w':
                readonly = 0;
                break;
            default:
                yasm_warn_set(YASM_WARN_GENERAL,
                              N_("unrecognized section attribute: `%c'"),
                              s[i]);
        }
    }

    if (code)
        data->flags = COFF_STYP_TEXT | COFF_STYP_EXECUTE | COFF_STYP_READ;
    else if (datasect)
        data->flags = COFF_STYP_DATA | COFF_STYP_READ | COFF_STYP_WRITE;
    else if (readonly)
        data->flags = COFF_STYP_DATA | COFF_STYP_READ;
    else if (load)
        data->flags = COFF_STYP_TEXT;
    else if (alloc)
        data->flags = COFF_STYP_BSS;

    if (shared)
        data->flags |= COFF_STYP_SHARED;

    data->gasflags = 1;
    return 0;
}

static /*@observer@*/ /*@null@*/ yasm_section *
coff_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
                            /*@unused@*/ /*@null@*/
                            yasm_valparamhead *objext_valparams,
                            unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_valparam *vp;
    yasm_section *retval;
    int isnew;
    int iscode = 0;
    int flags_override;
    const char *sectname;
    char *realname;
    int resonly = 0;
    unsigned long align = 0;
    coff_section_data *csd;

    struct coff_section_switch_data data;

    static const yasm_dir_help help[] = {
        { "code", 0, yasm_dir_helper_flag_set,
          offsetof(struct coff_section_switch_data, flags),
          COFF_STYP_TEXT | COFF_STYP_EXECUTE | COFF_STYP_READ },
        { "text", 0, yasm_dir_helper_flag_set,
          offsetof(struct coff_section_switch_data, flags),
          COFF_STYP_TEXT | COFF_STYP_EXECUTE | COFF_STYP_READ },
        { "data", 0, yasm_dir_helper_flag_set,
          offsetof(struct coff_section_switch_data, flags),
          COFF_STYP_DATA | COFF_STYP_READ | COFF_STYP_WRITE },
        { "rdata", 0, yasm_dir_helper_flag_set,
          offsetof(struct coff_section_switch_data, flags),
          COFF_STYP_DATA | COFF_STYP_READ },
        { "bss", 0, yasm_dir_helper_flag_set,
          offsetof(struct coff_section_switch_data, flags),
          COFF_STYP_BSS | COFF_STYP_READ | COFF_STYP_WRITE },
        { "info", 0, yasm_dir_helper_flag_set,
          offsetof(struct coff_section_switch_data, flags),
          COFF_STYP_INFO | COFF_STYP_DISCARD | COFF_STYP_READ },
        { "gasflags", 1, coff_helper_gasflags, 0, 0 },
        /* Win32 only below this point */
        { "discard", 0, yasm_dir_helper_flag_or,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_DISCARD},
        { "nodiscard", 0, yasm_dir_helper_flag_and,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_DISCARD},
        { "cache", 0, yasm_dir_helper_flag_and,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_NOCACHE},
        { "nocache", 0, yasm_dir_helper_flag_or,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_NOCACHE},
        { "page", 0, yasm_dir_helper_flag_and,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_NOPAGE },
        { "nopage", 0, yasm_dir_helper_flag_or,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_NOPAGE },
        { "share", 0, yasm_dir_helper_flag_or,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_SHARED },
        { "noshare", 0, yasm_dir_helper_flag_and,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_SHARED },
        { "execute", 0, yasm_dir_helper_flag_or,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_EXECUTE},
        { "noexecute", 0, yasm_dir_helper_flag_and,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_EXECUTE},
        { "read", 0, yasm_dir_helper_flag_or,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_READ },
        { "noread", 0, yasm_dir_helper_flag_and,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_READ },
        { "write", 0, yasm_dir_helper_flag_or,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_WRITE },
        { "nowrite", 0, yasm_dir_helper_flag_and,
          offsetof(struct coff_section_switch_data, flags), COFF_STYP_WRITE },
        { "base", 0, yasm_dir_helper_flag_and,
          offsetof(struct coff_section_switch_data, flags2), COFF_FLAG_NOBASE},
        { "nobase", 0, yasm_dir_helper_flag_or,
          offsetof(struct coff_section_switch_data, flags2), COFF_FLAG_NOBASE},
        { "align", 1, yasm_dir_helper_intn,
          offsetof(struct coff_section_switch_data, align_intn), 0 }
    };

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

    data.isdefault = 0;
    data.gasflags = 0;
    data.flags = 0;
    data.flags2 = 0;
    data.align_intn = NULL;

    if (strcmp(sectname, ".data") == 0) {
        data.flags = COFF_STYP_DATA | COFF_STYP_READ | COFF_STYP_WRITE;
        if (objfmt_coff->win32) {
            if (objfmt_coff->machine == COFF_MACHINE_AMD64)
                align = 16;
            else
                align = 4;
        }
    } else if (strcmp(sectname, ".bss") == 0) {
        data.flags = COFF_STYP_BSS | COFF_STYP_READ | COFF_STYP_WRITE;
        if (objfmt_coff->win32) {
            if (objfmt_coff->machine == COFF_MACHINE_AMD64)
                align = 16;
            else
                align = 4;
        }
        resonly = 1;
    } else if (strcmp(sectname, ".text") == 0) {
        data.flags = COFF_STYP_TEXT | COFF_STYP_EXECUTE | COFF_STYP_READ;
        if (objfmt_coff->win32)
            align = 16;
    } else if (strcmp(sectname, ".rdata") == 0
               || strncmp(sectname, ".rodata", 7) == 0
               || strncmp(sectname, ".rdata$", 7) == 0) {
        data.flags = COFF_STYP_DATA | COFF_STYP_READ;
        if (objfmt_coff->win32)
            align = 8;
        else
            yasm_warn_set(YASM_WARN_GENERAL,
                N_("Standard COFF does not support read-only data sections"));
    } else if (strcmp(sectname, ".drectve") == 0) {
        data.flags = COFF_STYP_INFO;
        if (objfmt_coff->win32)
            data.flags |= COFF_STYP_DISCARD | COFF_STYP_READ;
    } else if (objfmt_coff->win64 && strcmp(sectname, ".pdata") == 0) {
        data.flags = COFF_STYP_DATA | COFF_STYP_READ;
        align = 4;
        data.flags2 = COFF_FLAG_NOBASE;
    } else if (objfmt_coff->win64 && strcmp(sectname, ".xdata") == 0) {
        data.flags = COFF_STYP_DATA | COFF_STYP_READ;
        align = 8;
        data.flags2 = COFF_FLAG_NOBASE;
    } else if (objfmt_coff->win32 && strcmp(sectname, ".sxdata") == 0) {
        data.flags = COFF_STYP_INFO;
    } else if (strcmp(sectname, ".comment") == 0) {
        data.flags = COFF_STYP_INFO | COFF_STYP_DISCARD | COFF_STYP_READ;
    } else if (yasm__strncasecmp(sectname, ".debug", 6)==0) {
        data.flags = COFF_STYP_DATA | COFF_STYP_DISCARD | COFF_STYP_READ;
        align = 1;
    } else {
        /* Default to code, but set a flag so if we get gasflags we can
         * change it (NASM and GAS have different defaults).
         */
        data.isdefault = 1;
        data.flags = COFF_STYP_TEXT | COFF_STYP_EXECUTE | COFF_STYP_READ;
    }

    flags_override = yasm_dir_helper(object, vp, line, help,
                                     objfmt_coff->win32 ? NELEMS(help) : 7,
                                     &data, yasm_dir_helper_valparam_warn);
    if (flags_override < 0)
        return NULL;    /* error occurred */

    if (data.flags & COFF_STYP_EXECUTE)
        iscode = 1;

    if (!objfmt_coff->win32)
        data.flags &= ~COFF_STYP_WIN32_MASK;

    if (data.align_intn) {
        align = yasm_intnum_get_uint(data.align_intn);
        yasm_intnum_destroy(data.align_intn);

        /* 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;
        }

        /* Check to see if alignment is supported size */
        if (align > 8192) {
            yasm_error_set(YASM_ERROR_VALUE,
                N_("Win32 does not support alignments > 8192"));
            return NULL;
        }
    }

    realname = yasm__xstrdup(sectname);
    if (strlen(sectname) > 8 && !objfmt_coff->win32) {
        /* win32 format supports >8 character section names in object
         * files via "/nnnn" (where nnnn is decimal offset into string table),
         * so only warn for regular COFF.
         */
        yasm_warn_set(YASM_WARN_GENERAL,
            N_("COFF section names limited to 8 characters: truncating"));
        realname[8] = '\0';
    }

    retval = yasm_object_get_general(object, realname, align, iscode,
                                     resonly, &isnew, line);
    yasm_xfree(realname);

    csd = yasm_section_get_data(retval, &coff_section_data_cb);

    if (isnew || yasm_section_is_default(retval)) {
        yasm_section_set_default(retval, 0);
        csd->flags = data.flags;
        csd->flags2 = data.flags2;
        yasm_section_set_align(retval, align, line);
    } else if (flags_override && !data.gasflags)
        yasm_warn_set(YASM_WARN_GENERAL,
                      N_("section flags ignored on section redeclaration"));
    return retval;
}

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

static /*@observer@*/ /*@null@*/ yasm_symrec *
win64_objfmt_get_special_sym(yasm_object *object, const char *name,
                             const char *parser)
{
    if (yasm__strcasecmp(name, "imagebase") == 0) {
        yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
        return objfmt_coff->ssym_imagebase;
    }
    return NULL;
}

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

static void
coff_section_data_print(void *data, FILE *f, int indent_level)
{
    coff_section_data *csd = (coff_section_data *)data;

    fprintf(f, "%*ssym=\n", indent_level, "");
    yasm_symrec_print(csd->sym, f, indent_level+1);
    fprintf(f, "%*sscnum=%d\n", indent_level, "", csd->scnum);
    fprintf(f, "%*sflags=", indent_level, "");
    switch (csd->flags & COFF_STYP_STD_MASK) {
        case COFF_STYP_TEXT:
            fprintf(f, "TEXT");
            break;
        case COFF_STYP_DATA:
            fprintf(f, "DATA");
            break;
        case COFF_STYP_BSS:
            fprintf(f, "BSS");
            break;
        default:
            fprintf(f, "UNKNOWN");
            break;
    }
    fprintf(f, "\n%*saddr=0x%lx\n", indent_level, "", csd->addr);
    fprintf(f, "%*sscnptr=0x%lx\n", indent_level, "", csd->scnptr);
    fprintf(f, "%*ssize=%ld\n", indent_level, "", csd->size);
    fprintf(f, "%*srelptr=0x%lx\n", indent_level, "", csd->relptr);
    fprintf(f, "%*snreloc=%ld\n", indent_level, "", csd->nreloc);
    fprintf(f, "%*srelocs:\n", indent_level, "");
}

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

static void
coff_symrec_data_print(void *data, FILE *f, int indent_level)
{
    coff_symrec_data *csd = (coff_symrec_data *)data;

    fprintf(f, "%*ssymtab index=%lu\n", indent_level, "", csd->index);
    fprintf(f, "%*ssclass=%d\n", indent_level, "", csd->sclass);
}

static void
dir_export(yasm_object *object, yasm_valparamhead *valparams,
           yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_valparam *vp;
    /*@null@*/ const char *symname;
    int isnew;
    yasm_section *sect;
    yasm_datavalhead dvs;

    /* Reference exported symbol (to generate error if not declared) */
    vp = yasm_vps_first(valparams);
    symname = yasm_vp_id(vp);
    if (symname)
        yasm_symtab_use(object->symtab, symname, line);
    else {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("argument to EXPORT must be symbol name"));
        return;
    }

    /* Add to end of linker directives */
    sect = yasm_object_get_general(object, ".drectve", 0, 0, 0, &isnew, line);

    /* Initialize directive section if needed */
    if (isnew) {
        coff_section_data *csd;
        csd = yasm_section_get_data(sect, &coff_section_data_cb);
        csd->flags = COFF_STYP_INFO | COFF_STYP_DISCARD | COFF_STYP_READ;
    }

    /* Add text as data bytecode */
    yasm_dvs_initialize(&dvs);
    yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup("-export:"),
                                                strlen("-export:")));
    yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(symname),
                                                strlen(symname)));
    yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(" "), 1));
    yasm_section_bcs_append(sect, yasm_bc_create_data(&dvs, 1, 0, NULL, line));
}

static void
dir_safeseh(yasm_object *object, yasm_valparamhead *valparams,
            yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_valparam *vp;
    /*@null@*/ const char *symname;
    yasm_symrec *sym;
    int isnew;
    yasm_section *sect;

    /* Reference symbol (to generate error if not declared).
     * Also, symbol must be externally visible, so force it.
     */
    vp = yasm_vps_first(valparams);
    symname = yasm_vp_id(vp);
    if (symname) {
        coff_symrec_data *sym_data;
        sym = yasm_symtab_use(object->symtab, symname, line);
        sym_data = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
        if (!sym_data) {
            sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_NULL, 0,
                                                COFF_SYMTAB_AUX_NONE);
        }
        sym_data->forcevis = 1;
        sym_data->type = 0x20; /* function */
    } else {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("argument to SAFESEH must be symbol name"));
        return;
    }

    /*
     * Add symbol number to end of .sxdata section.
     */

    sect = yasm_object_get_general(object, ".sxdata", 0, 0, 0, &isnew, line);

    /* Initialize sxdata section if needed */
    if (isnew) {
        coff_section_data *csd;
        csd = yasm_section_get_data(sect, &coff_section_data_cb);
        csd->flags = COFF_STYP_INFO;
    }

    /* Add as sxdata bytecode */
    yasm_section_bcs_append(sect,
                            yasm_bc_create_common(&win32_sxdata_bc_callback,
                                                  sym, line));
}

static void
win32_sxdata_bc_destroy(void *contents)
{
    /* Contents is just the symbol pointer, so no need to delete */
}

static void
win32_sxdata_bc_print(const void *contents, FILE *f, int indent_level)
{
    /* TODO */
}

static int
win32_sxdata_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                         void *add_span_data)
{
    bc->len += 4;
    return 0;
}

static int
win32_sxdata_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
                        unsigned char *bufstart, void *d,
                        yasm_output_value_func output_value,
                        yasm_output_reloc_func output_reloc)
{
    yasm_symrec *sym = (yasm_symrec *)bc->contents;
    unsigned char *buf = *bufp;
    coff_symrec_data *csymd;

    csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
    if (!csymd)
        yasm_internal_error(N_("coff: no symbol data for SAFESEH symbol"));

    YASM_WRITE_32_L(buf, csymd->index);

    *bufp = buf;
    return 0;
}

static void
dir_ident(yasm_object *object, yasm_valparamhead *valparams,
          yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_valparamhead sect_vps;
    yasm_datavalhead dvs;
    yasm_section *comment;
    const char *sectname;
    yasm_valparam *vp, *vp2;

    /* Accept, but do nothing with empty ident */
    if (!valparams)
        return;

    vp = yasm_vps_first(valparams);
    if (!vp)
        return;

    if (objfmt_coff->win32) {
        /* Put ident data into .comment section for COFF, or .rdata$zzz
         * to be compatible with the GNU linker, which doesn't ignore
         * .comment (see binutils/gas/config/obj-coff.c:476-502).
         */
        sectname = ".rdata$zzz";
    } else {
        sectname = ".comment";
    }
    yasm_vps_initialize(&sect_vps);
    vp2 = yasm_vp_create_id(NULL, yasm__xstrdup(sectname), '\0');
    yasm_vps_append(&sect_vps, vp2);
    comment = coff_objfmt_section_switch(object, &sect_vps, NULL, line);
    yasm_vps_delete(&sect_vps);

    /* To match GAS output, if the comment section is empty, put an
     * initial 0 byte in the section.
     */
    if (yasm_section_bcs_first(comment) == yasm_section_bcs_last(comment)) {
        yasm_dvs_initialize(&dvs);
        yasm_dvs_append(&dvs, yasm_dv_create_expr(
            yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)),
                                   line)));
        yasm_section_bcs_append(comment,
            yasm_bc_create_data(&dvs, 1, 0, object->arch, line));
    }

    yasm_dvs_initialize(&dvs);
    do {
        const char *s = yasm_vp_string(vp);
        if (!s) {
            yasm_error_set(YASM_ERROR_VALUE,
                           N_(".comment requires string parameters"));
            yasm_dvs_delete(&dvs);
            return;
        }
        yasm_dvs_append(&dvs,
                        yasm_dv_create_string(yasm__xstrdup(s), strlen(s)));
    } while ((vp = yasm_vps_next(vp)));

    yasm_section_bcs_append(comment,
        yasm_bc_create_data(&dvs, 1, 1, object->arch, line));
}

static void
dir_secrel32(yasm_object *object, yasm_valparamhead *valparams,
             yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_datavalhead dvs;
    yasm_valparam *vp;

    if (!object->cur_section) {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_(".secrel32 can only be used inside of a section"));
        return;
    }

    vp = yasm_vps_first(valparams);
    yasm_dvs_initialize(&dvs);
    do {
        yasm_expr *e = yasm_vp_expr(vp, object->symtab, line);
        yasm_dataval *dv;
        if (!e) {
            yasm_error_set(YASM_ERROR_VALUE,
                           N_(".secrel32 requires expressions"));
            yasm_dvs_delete(&dvs);
            return;
        }
        dv = yasm_dv_create_expr(e);
        yasm_dv_get_value(dv)->section_rel = 1;
        yasm_dvs_append(&dvs, dv);
    } while ((vp = yasm_vps_next(vp)));

    yasm_section_bcs_append(object->cur_section,
        yasm_bc_create_data(&dvs, 4, 0, object->arch, line));
}

static void
dir_def(yasm_object *object, yasm_valparamhead *valparams,
        yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_valparam *vp;
    const char *symname;
    yasm_symrec *sym;
    coff_symrec_data *sym_data;

    if (objfmt_coff->def_sym) {
        yasm_warn_set(YASM_WARN_GENERAL,
                      N_(".def pseudo-op used inside of .def/.endef; ignored"));
        return;
    }

    vp = yasm_vps_first(valparams);
    symname = yasm_vp_id(vp);
    if (!symname) {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("argument to SAFESEH must be symbol name"));
        return;
    }

    sym = yasm_symtab_use(object->symtab, symname, line);
    sym_data = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
    if (!sym_data) {
        sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_NULL, 0,
                                            COFF_SYMTAB_AUX_NONE);
    }
    objfmt_coff->def_sym = sym_data;
}

static void
dir_scl(yasm_object *object, yasm_valparamhead *valparams,
        yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_intnum *intn = NULL;

    if (!objfmt_coff->def_sym) {
        yasm_warn_set(YASM_WARN_GENERAL,
                      N_("%s pseudo-op used outside of .def/.endef; ignored"),
                      ".scl");
        return;
    }

    if (yasm_dir_helper_intn(object, yasm_vps_first(valparams), line,
                             &intn, 0) < 0)
        return;
    if (!intn)
        return;
    objfmt_coff->def_sym->sclass = yasm_intnum_get_uint(intn);
    yasm_intnum_destroy(intn);
}

static void
dir_type(yasm_object *object, yasm_valparamhead *valparams,
         yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_intnum *intn = NULL;

    if (!objfmt_coff->def_sym) {
        yasm_warn_set(YASM_WARN_GENERAL,
                      N_("%s pseudo-op used outside of .def/.endef; ignored"),
                      ".type");
        return;
    }

    if (yasm_dir_helper_intn(object, yasm_vps_first(valparams), line,
                             &intn, 0) < 0)
        return;
    if (!intn)
        return;
    objfmt_coff->def_sym->type = yasm_intnum_get_uint(intn);
    yasm_intnum_destroy(intn);
}

static void
dir_endef(yasm_object *object, yasm_valparamhead *valparams,
          yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    if (!objfmt_coff->def_sym) {
        yasm_warn_set(YASM_WARN_GENERAL,
                      N_(".endef pseudo-op used before .def; ignored"));
        return;
    }
    objfmt_coff->def_sym = NULL;
}

static void
dir_proc_frame(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
               yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_valparam *vp = yasm_vps_first(valparams);
    const char *name = yasm_vp_id(vp);

    if (objfmt_coff->proc_frame) {
        yasm_error_set_xref(objfmt_coff->proc_frame,
                            N_("previous procedure started here"));
        yasm_error_set(YASM_ERROR_SYNTAX,
            N_("nested procedures not supported (didn't use [ENDPROC_FRAME]?)"));
        return;
    }
    objfmt_coff->proc_frame = line;
    objfmt_coff->done_prolog = 0;
    objfmt_coff->unwind = yasm_win64__uwinfo_create();
    objfmt_coff->unwind->proc = yasm_symtab_use(object->symtab, name, line);

    /* Optional error handler */
    vp = yasm_vps_next(vp);
    if (!vp || !(name = yasm_vp_id(vp)))
        return;
    objfmt_coff->unwind->ehandler =
        yasm_symtab_use(object->symtab, name, line);
}

static int
procframe_checkstate(yasm_objfmt_coff *objfmt_coff, const char *dirname)
{
    if (!objfmt_coff->proc_frame) {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("[%s] without preceding [PROC_FRAME]"), dirname);
        return 0;
    }
    if (objfmt_coff->done_prolog) {
        yasm_error_set_xref(objfmt_coff->done_prolog,
                            N_("prologue ended here"));
        yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] after end of prologue"),
                       dirname);
        return 0;
    }
    if (!objfmt_coff->unwind)
        yasm_internal_error(N_("unwind info not present"));
    return 1;
}

/* Get current assembly position.
 * XXX: There should be a better way to do this.
 */
static yasm_symrec *
get_curpos(yasm_object *object, const char *dirname, unsigned long line)
{
    if (!object->cur_section) {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("[%s] can only be used inside of a section"),
                       dirname);
        return NULL;
    }
    return yasm_symtab_define_curpos(object->symtab, "$",
        yasm_section_bcs_last(object->cur_section), line);
}

static void
dir_pushreg(yasm_object *object, yasm_valparamhead *valparams,
            yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_valparam *vp = yasm_vps_first(valparams);
    coff_unwind_code *code;
    const uintptr_t *reg;

    if (!procframe_checkstate(objfmt_coff, "PUSHREG"))
        return;

    if (vp->type != YASM_PARAM_EXPR ||
        !(reg = yasm_expr_get_reg(&vp->param.e, 0))) {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("[%s] requires a register as the first parameter"),
                       "PUSHREG");
        return;
    }

    /* Generate a PUSH_NONVOL unwind code. */
    code = yasm_xmalloc(sizeof(coff_unwind_code));
    code->proc = objfmt_coff->unwind->proc;
    code->loc = get_curpos(object, "PUSHREG", line);
    code->opcode = UWOP_PUSH_NONVOL;
    code->info = (unsigned int)(*reg & 0xF);
    yasm_value_initialize(&code->off, NULL, 0);
    SLIST_INSERT_HEAD(&objfmt_coff->unwind->codes, code, link);
}

static void
dir_setframe(yasm_object *object, yasm_valparamhead *valparams,
             yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_valparam *vp = yasm_vps_first(valparams);
    coff_unwind_code *code;
    const uintptr_t *reg;
    yasm_expr *off = NULL;

    if (!procframe_checkstate(objfmt_coff, "SETFRAME"))
        return;

    if (vp->type != YASM_PARAM_EXPR ||
        !(reg = yasm_expr_get_reg(&vp->param.e, 0))) {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("[%s] requires a register as the first parameter"),
                       "SETFRAME");
        return;
    }

    vp = yasm_vps_next(vp);
    if (vp)
        off = yasm_vp_expr(vp, object->symtab, line);

    /* Set the frame fields in the unwind info */
    objfmt_coff->unwind->framereg = (unsigned long)(*reg);
    yasm_value_initialize(&objfmt_coff->unwind->frameoff, off, 8);

    /* Generate a SET_FPREG unwind code */
    code = yasm_xmalloc(sizeof(coff_unwind_code));
    code->proc = objfmt_coff->unwind->proc;
    code->loc = get_curpos(object, "SETFRAME", line);
    code->opcode = UWOP_SET_FPREG;
    code->info = (unsigned int)(*reg & 0xF);
    yasm_value_initialize(&code->off, off ? yasm_expr_copy(off) : NULL, 8);
    SLIST_INSERT_HEAD(&objfmt_coff->unwind->codes, code, link);
}

static void
dir_allocstack(yasm_object *object, yasm_valparamhead *valparams,
               yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_valparam *vp = yasm_vps_first(valparams);
    /*@null@*/ /*@only@*/ yasm_expr *size;
    coff_unwind_code *code;

    if (!procframe_checkstate(objfmt_coff, "ALLOCSTACK"))
        return;

    size = yasm_vp_expr(vp, object->symtab, line);
    if (!size) {
        yasm_error_set(YASM_ERROR_SYNTAX, N_("[%s] requires a size"),
                       "ALLOCSTACK");
        return;
    }

    /* Generate an ALLOC_SMALL unwind code; this will get enlarged to an
     * ALLOC_LARGE if necessary.
     */
    code = yasm_xmalloc(sizeof(coff_unwind_code));
    code->proc = objfmt_coff->unwind->proc;
    code->loc = get_curpos(object, "ALLOCSTACK", line);
    code->opcode = UWOP_ALLOC_SMALL;
    code->info = 0;
    yasm_value_initialize(&code->off, size, 7);
    SLIST_INSERT_HEAD(&objfmt_coff->unwind->codes, code, link);
}

static void
dir_save_common(yasm_object *object, yasm_valparamhead *valparams,
                unsigned long line, const char *name, int op)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_valparam *vp = yasm_vps_first(valparams);
    coff_unwind_code *code;
    const uintptr_t *reg;
    /*@only@*/ /*@null@*/ yasm_expr *offset;

    if (!procframe_checkstate(objfmt_coff, name))
        return;

    if (vp->type != YASM_PARAM_EXPR ||
        !(reg = yasm_expr_get_reg(&vp->param.e, 0))) {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("[%s] requires a register as the first parameter"),
                       name);
        return;
    }

    vp = yasm_vps_next(vp);
    offset = yasm_vp_expr(vp, object->symtab, line);
    if (!offset) {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("[%s] requires an offset as the second parameter"),
                       name);
        return;
    }

    /* Generate a SAVE_XXX unwind code; this will get enlarged to a
     * SAVE_XXX_FAR if necessary.
     */
    code = yasm_xmalloc(sizeof(coff_unwind_code));
    code->proc = objfmt_coff->unwind->proc;
    code->loc = get_curpos(object, name, line);
    code->opcode = op;
    code->info = (unsigned int)(*reg & 0xF);
    yasm_value_initialize(&code->off, offset, 16);
    SLIST_INSERT_HEAD(&objfmt_coff->unwind->codes, code, link);
}

static void
dir_savereg(yasm_object *object, yasm_valparamhead *valparams,
            yasm_valparamhead *objext_valparams, unsigned long line)
{
    dir_save_common(object, valparams, line, "SAVEREG", UWOP_SAVE_NONVOL);
}

static void
dir_savexmm128(yasm_object *object, yasm_valparamhead *valparams,
               yasm_valparamhead *objext_valparams, unsigned long line)
{
    dir_save_common(object, valparams, line, "SAVEXMM128", UWOP_SAVE_XMM128);
}

static void
dir_pushframe(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
              yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_valparam *vp = yasm_vps_first(valparams);
    coff_unwind_code *code;

    if (!procframe_checkstate(objfmt_coff, "PUSHFRAME"))
        return;

    /* Generate a PUSH_MACHFRAME unwind code.  If there's any parameter,
     * we set info to 1.  Otherwise we set info to 0.
     */
    code = yasm_xmalloc(sizeof(coff_unwind_code));
    code->proc = objfmt_coff->unwind->proc;
    code->loc = get_curpos(object, "PUSHFRAME", line);
    code->opcode = UWOP_PUSH_MACHFRAME;
    code->info = vp != NULL;
    yasm_value_initialize(&code->off, NULL, 0);
    SLIST_INSERT_HEAD(&objfmt_coff->unwind->codes, code, link);
}

static void
dir_endprolog(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
              yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    if (!procframe_checkstate(objfmt_coff, "ENDPROLOG"))
        return;
    objfmt_coff->done_prolog = line;

    objfmt_coff->unwind->prolog = get_curpos(object, "ENDPROLOG", line);
}

static void
dir_endproc_frame(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
                  yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
    yasm_section *sect;
    coff_section_data *csd;
    yasm_datavalhead dvs;
    int isnew;
    /*@dependent@*/ yasm_symrec *curpos, *unwindpos, *proc_sym, *xdata_sym;

    if (!objfmt_coff->proc_frame) {
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("[%s] without preceding [PROC_FRAME]"),
                       "ENDPROC_FRAME");
        return;
    }
    if (!objfmt_coff->done_prolog) {
        yasm_error_set_xref(objfmt_coff->proc_frame,
                            N_("procedure started here"));
        yasm_error_set(YASM_ERROR_SYNTAX,
                       N_("ended procedure without ending prologue"),
                       "ENDPROC_FRAME");
        objfmt_coff->proc_frame = 0;
        yasm_win64__uwinfo_destroy(objfmt_coff->unwind);
        objfmt_coff->unwind = NULL;
        return;
    }
    if (!objfmt_coff->unwind)
        yasm_internal_error(N_("unwind info not present"));

    proc_sym = objfmt_coff->unwind->proc;

    curpos = get_curpos(object, "ENDPROC_FRAME", line);

    /*
     * Add unwind info to end of .xdata section.
     */

    sect = yasm_object_get_general(object, ".xdata", 0, 0, 0, &isnew, line);

    /* Initialize xdata section if needed */
    if (isnew) {
        csd = yasm_section_get_data(sect, &coff_section_data_cb);
        csd->flags = COFF_STYP_DATA | COFF_STYP_READ;
        yasm_section_set_align(sect, 8, line);
    }

    /* Get current position in .xdata section */
    unwindpos = yasm_symtab_define_curpos(object->symtab, "$",
        yasm_section_bcs_last(sect), line);
    /* Get symbol for .xdata as we'll want to reference it with WRT */
    csd = yasm_section_get_data(sect, &coff_section_data_cb);
    xdata_sym = csd->sym;

    /* Add unwind info.  Use line number of start of procedure. */
    yasm_win64__unwind_generate(sect, objfmt_coff->unwind,
                                objfmt_coff->proc_frame);
    objfmt_coff->unwind = NULL; /* generate keeps the unwind pointer */

    /*
     * Add function lookup to end of .pdata section.
     */

    sect = yasm_object_get_general(object, ".pdata", 0, 0, 0, &isnew, line);

    /* Initialize pdata section if needed */
    if (isnew) {
        csd = yasm_section_get_data(sect, &coff_section_data_cb);
        csd->flags = COFF_STYP_DATA | COFF_STYP_READ;
        csd->flags2 = COFF_FLAG_NOBASE;
        yasm_section_set_align(sect, 4, line);
    }

    /* Add function structure as data bytecode */
    yasm_dvs_initialize(&dvs);
    yasm_dvs_append(&dvs, yasm_dv_create_expr(
        yasm_expr_create_ident(yasm_expr_sym(proc_sym), line)));
    yasm_dvs_append(&dvs, yasm_dv_create_expr(
        yasm_expr_create(YASM_EXPR_WRT, yasm_expr_sym(curpos),
                         yasm_expr_sym(proc_sym), line)));
    yasm_dvs_append(&dvs, yasm_dv_create_expr(
        yasm_expr_create(YASM_EXPR_WRT, yasm_expr_sym(unwindpos),
                         yasm_expr_sym(xdata_sym), line)));
    yasm_section_bcs_append(sect, yasm_bc_create_data(&dvs, 4, 0, NULL, line));

    objfmt_coff->proc_frame = 0;
    objfmt_coff->done_prolog = 0;
}

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

static const yasm_directive coff_objfmt_directives[] = {
    { ".ident",         "gas",  dir_ident,      YASM_DIR_ANY },
    { "ident",          "nasm", dir_ident,      YASM_DIR_ANY },
    { ".def",           "gas",  dir_def,        YASM_DIR_ID_REQUIRED },
    { ".endef",         "gas",  dir_endef,      YASM_DIR_ANY },
    { ".scl",           "gas",  dir_scl,        YASM_DIR_ARG_REQUIRED },
    { ".type",          "gas",  dir_type,       YASM_DIR_ARG_REQUIRED },
    { ".secrel32",      "gas",  dir_secrel32,   YASM_DIR_ARG_REQUIRED },
    { NULL, NULL, NULL, 0 }
};

/* Define objfmt structure -- see objfmt.h for details */
yasm_objfmt_module yasm_coff_LTX_objfmt = {
    "COFF (DJGPP)",
    "coff",
    "o",
    32,
    0,
    coff_objfmt_dbgfmt_keywords,
    "null",
    coff_objfmt_directives,
    NULL,   /* no standard macros */
    coff_objfmt_create,
    coff_objfmt_output,
    coff_objfmt_destroy,
    coff_objfmt_add_default_section,
    coff_objfmt_init_new_section,
    coff_objfmt_section_switch,
    coff_objfmt_get_special_sym
};

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

static const yasm_directive win32_objfmt_directives[] = {
    { ".ident",         "gas",  dir_ident,      YASM_DIR_ANY },
    { "ident",          "nasm", dir_ident,      YASM_DIR_ANY },
    { ".def",           "gas",  dir_def,        YASM_DIR_ID_REQUIRED },
    { ".endef",         "gas",  dir_endef,      YASM_DIR_ANY },
    { ".scl",           "gas",  dir_scl,        YASM_DIR_ARG_REQUIRED },
    { ".type",          "gas",  dir_type,       YASM_DIR_ARG_REQUIRED },
    { ".secrel32",      "gas",  dir_secrel32,   YASM_DIR_ARG_REQUIRED },
    { ".export",        "gas",  dir_export,     YASM_DIR_ID_REQUIRED },
    { "export",         "nasm", dir_export,     YASM_DIR_ID_REQUIRED },
    { ".safeseh",       "gas",  dir_safeseh,    YASM_DIR_ID_REQUIRED },
    { "safeseh",        "nasm", dir_safeseh,    YASM_DIR_ID_REQUIRED },
    { NULL, NULL, NULL, 0 }
};

static const char *win32_nasm_stdmac[] = {
    "%imacro export 1+.nolist",
    "[export %1]",
    "%endmacro",
    "%imacro safeseh 1+.nolist",
    "[safeseh %1]",
    "%endmacro",
    NULL
};

static const yasm_stdmac win32_objfmt_stdmacs[] = {
    { "nasm", "nasm", win32_nasm_stdmac },
    { NULL, NULL, NULL }
};

/* Define objfmt structure -- see objfmt.h for details */
yasm_objfmt_module yasm_win32_LTX_objfmt = {
    "Win32",
    "win32",
    "obj",
    32,
    1,
    winXX_objfmt_dbgfmt_keywords,
    "null",
    win32_objfmt_directives,
    win32_objfmt_stdmacs,
    win32_objfmt_create,
    coff_objfmt_output,
    coff_objfmt_destroy,
    coff_objfmt_add_default_section,
    coff_objfmt_init_new_section,
    coff_objfmt_section_switch,
    coff_objfmt_get_special_sym
};

static const yasm_directive win64_objfmt_directives[] = {
    { ".ident",         "gas",  dir_ident,      YASM_DIR_ANY },
    { "ident",          "nasm", dir_ident,      YASM_DIR_ANY },
    { ".def",           "gas",  dir_def,        YASM_DIR_ID_REQUIRED },
    { ".endef",         "gas",  dir_endef,      YASM_DIR_ANY },
    { ".scl",           "gas",  dir_scl,        YASM_DIR_ARG_REQUIRED },
    { ".type",          "gas",  dir_type,       YASM_DIR_ARG_REQUIRED },
    { ".secrel32",      "gas",  dir_secrel32,   YASM_DIR_ARG_REQUIRED },
    { ".export",        "gas",  dir_export,     YASM_DIR_ID_REQUIRED },
    { "export",         "nasm", dir_export,     YASM_DIR_ID_REQUIRED },
    { ".proc_frame",    "gas",  dir_proc_frame, YASM_DIR_ID_REQUIRED },
    { "proc_frame",     "nasm", dir_proc_frame, YASM_DIR_ID_REQUIRED },
    { ".pushreg",       "gas",  dir_pushreg,    YASM_DIR_ARG_REQUIRED },
    { "pushreg",        "nasm", dir_pushreg,    YASM_DIR_ARG_REQUIRED },
    { ".setframe",      "gas",  dir_setframe,   YASM_DIR_ARG_REQUIRED },
    { "setframe",       "nasm", dir_setframe,   YASM_DIR_ARG_REQUIRED },
    { ".allocstack",    "gas",  dir_allocstack, YASM_DIR_ARG_REQUIRED },
    { "allocstack",     "nasm", dir_allocstack, YASM_DIR_ARG_REQUIRED },
    { ".savereg",       "gas",  dir_savereg,    YASM_DIR_ARG_REQUIRED },
    { "savereg",        "nasm", dir_savereg,    YASM_DIR_ARG_REQUIRED },
    { ".savexmm128",    "gas",  dir_savexmm128, YASM_DIR_ARG_REQUIRED },
    { "savexmm128",     "nasm", dir_savexmm128, YASM_DIR_ARG_REQUIRED },
    { ".pushframe",     "gas",  dir_pushframe,  YASM_DIR_ANY },
    { "pushframe",      "nasm", dir_pushframe,  YASM_DIR_ANY },
    { ".endprolog",     "gas",  dir_endprolog,  YASM_DIR_ANY },
    { "endprolog",      "nasm", dir_endprolog,  YASM_DIR_ANY },
    { ".endproc_frame", "gas",  dir_endproc_frame, YASM_DIR_ANY },
    { "endproc_frame",  "nasm", dir_endproc_frame, YASM_DIR_ANY },
    { NULL, NULL, NULL, 0 }
};

#include "win64-nasm.c"
#include "win64-gas.c"

static const yasm_stdmac win64_objfmt_stdmacs[] = {
    { "nasm", "nasm", win64_nasm_stdmac },
    { "gas", "nasm", win64_gas_stdmac },
    { NULL, NULL, NULL }
};

/* Define objfmt structure -- see objfmt.h for details */
yasm_objfmt_module yasm_win64_LTX_objfmt = {
    "Win64",
    "win64",
    "obj",
    64,
    1,
    winXX_objfmt_dbgfmt_keywords,
    "null",
    win64_objfmt_directives,
    win64_objfmt_stdmacs,
    win64_objfmt_create,
    coff_objfmt_output,
    coff_objfmt_destroy,
    coff_objfmt_add_default_section,
    coff_objfmt_init_new_section,
    coff_objfmt_section_switch,
    win64_objfmt_get_special_sym
};
yasm_objfmt_module yasm_x64_LTX_objfmt = {
    "Win64",
    "x64",
    "obj",
    64,
    1,
    winXX_objfmt_dbgfmt_keywords,
    "null",
    win64_objfmt_directives,
    win64_objfmt_stdmacs,
    win64_objfmt_create,
    coff_objfmt_output,
    coff_objfmt_destroy,
    coff_objfmt_add_default_section,
    coff_objfmt_init_new_section,
    coff_objfmt_section_switch,
    win64_objfmt_get_special_sym
};
