/*
 * ELF object format
 *
 *  Copyright (C) 2003-2007  Michael Urman
 *
 * 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: elf-objfmt.c,v 1.1.1.1 2012/03/29 17:21:02 uid42307 Exp $");

/* Notes
 *
 * elf-objfmt uses the "linking" view of an ELF file:
 * ELF header, an optional program header table, several sections,
 * and a section header table
 *
 * The ELF header tells us some overall program information,
 *   where to find the PHT (if it exists) with phnum and phentsize, 
 *   and where to find the SHT with shnum and shentsize
 *
 * The PHT doesn't seem to be generated by NASM for elftest.asm
 *
 * The SHT
 *
 * Each Section is spatially disjoint, and has exactly one SHT entry.
 */

#include <libyasm.h>

#include "elf.h"
#include "elf-machine.h"

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

    elf_symtab_head* elf_symtab;        /* symbol table of indexed syms */
    elf_strtab_head* shstrtab;          /* section name strtab */
    elf_strtab_head* strtab;            /* strtab entries */

    elf_strtab_entry *file_strtab_entry;/* .file symbol associated string */
    yasm_symrec *dotdotsym;             /* ..sym symbol */
} yasm_objfmt_elf;

typedef struct {
    yasm_objfmt_elf *objfmt_elf;
    yasm_errwarns *errwarns;
    FILE *f;
    elf_secthead *shead;
    yasm_section *sect;
    yasm_object *object;
    unsigned long sindex;
} elf_objfmt_output_info;

typedef struct {
    yasm_object *object;
    yasm_objfmt_elf *objfmt_elf;
    yasm_errwarns *errwarns;
    int local_names;
} build_symtab_info;

yasm_objfmt_module yasm_elf_LTX_objfmt;
yasm_objfmt_module yasm_elf32_LTX_objfmt;
yasm_objfmt_module yasm_elf64_LTX_objfmt;


static elf_symtab_entry *
elf_objfmt_symtab_append(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym,
                         elf_section_index sectidx, elf_symbol_binding bind,
                         elf_symbol_type type, elf_symbol_vis vis,
                         yasm_expr *size, elf_address *value)
{
    elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data);

    if (!entry) {
        elf_strtab_entry *name =
            elf_strtab_append_str(objfmt_elf->strtab,
                                  yasm_symrec_get_name(sym));
        entry = elf_symtab_entry_create(name, sym);
        yasm_symrec_add_data(sym, &elf_symrec_data, entry);
    }

    /* Only append to table if not already appended */
    if (!elf_sym_in_table(entry))
        elf_symtab_append_entry(objfmt_elf->elf_symtab, entry);

    elf_symtab_set_nonzero(entry, NULL, sectidx, bind, type, size, value);
    elf_sym_set_visibility(entry, vis);

    return entry;
}

static elf_symtab_entry *
build_extern(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym)
{
    yasm_valparamhead *objext_valparams =
        yasm_symrec_get_objext_valparams(sym);

    if (objext_valparams) {
        yasm_valparam *vp = yasm_vps_first(objext_valparams);
        for (; vp; vp = yasm_vps_next(vp)) {
            if (yasm_vp_string(vp))
                yasm_error_set(YASM_ERROR_TYPE,
                               N_("unrecognized symbol type `%s'"),
                               yasm_vp_string(vp));
        }
    }

    return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL, 0,
                                    STV_DEFAULT, NULL, NULL);
}

struct elf_build_global_data {
    yasm_expr *size;
    unsigned long type; /* elf_symbol_type */
    elf_symbol_vis vis;
    unsigned int vis_overrides;
};

static int
elf_global_helper_valparam(void *obj, yasm_valparam *vp, unsigned long line,
                           void *d)

{
    struct elf_build_global_data *data = (struct elf_build_global_data *)d;
    const char *s;

    if (!vp->val && (s = yasm_vp_id(vp))) {
        yasm_error_set(YASM_ERROR_TYPE, N_("unrecognized symbol type `%s'"),
                       s);
        return -1;
    } else if (!vp->val && vp->type == YASM_PARAM_EXPR && !data->size) {
        data->size = yasm_expr_copy(vp->param.e);
        return 0;
    } else
        return yasm_dir_helper_valparam_warn(obj, vp, line, d);
}

static int
elf_global_helper_vis(void *obj, yasm_valparam *vp, unsigned long line,
                      void *d, uintptr_t vis)
{
    struct elf_build_global_data *data = (struct elf_build_global_data *)d;
    data->vis = vis;
    data->vis_overrides++;
    return 0;
}


static elf_symtab_entry *
build_global(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym)
{
    yasm_valparamhead *objext_valparams =
        yasm_symrec_get_objext_valparams(sym);

    struct elf_build_global_data data;

    static const yasm_dir_help help[] = {
        { "function", 0, yasm_dir_helper_flag_set,
          offsetof(struct elf_build_global_data, type), STT_FUNC },
        { "data", 0, yasm_dir_helper_flag_set,
          offsetof(struct elf_build_global_data, type), STT_OBJECT },
        { "object", 0, yasm_dir_helper_flag_set,
          offsetof(struct elf_build_global_data, type), STT_OBJECT },
        { "internal", 0, elf_global_helper_vis, 0, STV_INTERNAL },
        { "hidden", 0, elf_global_helper_vis, 0, STV_HIDDEN },
        { "protected", 0, elf_global_helper_vis, 0, STV_PROTECTED },
    };

    data.size = NULL;
    data.type = 0;
    data.vis = STV_DEFAULT;
    data.vis_overrides = 0;

    if (objext_valparams)
        yasm_dir_helper(sym, yasm_vps_first(objext_valparams),
                        yasm_symrec_get_decl_line(sym), help, NELEMS(help),
                        &data, elf_global_helper_valparam);

    if (data.vis_overrides > 1) {
        yasm_warn_set(YASM_WARN_GENERAL,
            N_("More than one symbol visibility provided; using last"));
    }

    return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL,
                                    data.type, data.vis, data.size, NULL);
}

static /*@null@*/ elf_symtab_entry *
build_common(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, yasm_object *object)
{
    yasm_expr **size = yasm_symrec_get_common_size(sym);
    yasm_valparamhead *objext_valparams =
        yasm_symrec_get_objext_valparams(sym);
    unsigned long addralign = 0;

    if (objext_valparams) {
        yasm_valparam *vp = yasm_vps_first(objext_valparams);
        for (; vp; vp = yasm_vps_next(vp)) {
            if (!vp->val) {
                /*@only@*/ /*@null@*/ yasm_expr *align_expr;
                /*@dependent@*/ /*@null@*/ const yasm_intnum *align_intn;

                if (!(align_expr = yasm_vp_expr(vp, object->symtab,
                                                yasm_symrec_get_def_line(sym)))
                    || !(align_intn = yasm_expr_get_intnum(&align_expr, 0))) {
                    yasm_error_set(YASM_ERROR_VALUE,
                        N_("alignment constraint is not an integer"));
                    if (align_expr)
                        yasm_expr_destroy(align_expr);
                    return NULL;
                }
                addralign = yasm_intnum_get_uint(align_intn);
                yasm_expr_destroy(align_expr);

                /* Alignments must be a power of two. */
                if (!is_exp2(addralign)) {
                    yasm_error_set(YASM_ERROR_VALUE,
                        N_("alignment constraint is not a power of two"));
                    return NULL;
                }
            } else
                yasm_warn_set(YASM_WARN_GENERAL,
                              N_("Unrecognized qualifier `%s'"), vp->val);
        }
    }

    return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_COMMON, STB_GLOBAL,
                                    0, STV_DEFAULT, *size, &addralign);
}

static int
elf_objfmt_build_symtab(yasm_symrec *sym, /*@null@*/ void *d)
{
    build_symtab_info *info = (build_symtab_info *)d;
    yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
    yasm_sym_status status = yasm_symrec_get_status(sym);
    elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data);
    elf_address value=0;
    yasm_section *sect=NULL;
    yasm_bytecode *precbc=NULL;

    assert(info != NULL);

    if (vis & YASM_SYM_EXTERN) {
        entry = build_extern(info->objfmt_elf, sym);
        yasm_errwarn_propagate(info->errwarns,
                               yasm_symrec_get_decl_line(sym));
        return 0;
    }

    if (vis & YASM_SYM_COMMON) {
        entry = build_common(info->objfmt_elf, sym, info->object);
        yasm_errwarn_propagate(info->errwarns,
                               yasm_symrec_get_decl_line(sym));
        /* If the COMMON variable was actually defined, fall through. */
        if (!(status & YASM_SYM_DEFINED))
            return 0;
    }

    /* Ignore any undefined at this point. */
    if (!(status & YASM_SYM_DEFINED))
        return 0;

    if (!yasm_symrec_get_label(sym, &precbc)) {
        if (!yasm_symrec_get_equ(sym) && !yasm_symrec_is_abs(sym))
            return 0;
        precbc = NULL;
    }

    if (precbc)
        sect = yasm_bc_get_section(precbc);

    if (entry && elf_sym_in_table(entry))
        ;
    else if (vis & YASM_SYM_GLOBAL) {
        entry = build_global(info->objfmt_elf, sym);
        yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym));
    } else {
        int is_sect = 0;

        /* Locals (except when debugging) do not need to be
         * in the symbol table, unless they're a section.
         */
        if (sect &&
            strcmp(yasm_symrec_get_name(sym), yasm_section_get_name(sect))==0)
            is_sect = 1;
#if 0
        /* FIXME: to enable this we must have handling in place for special
         * symbols.
         */
        if (!info->local_names && !is_sect)
            return 0;
#else
        if (yasm_symrec_get_equ(sym) && !yasm_symrec_is_abs(sym))
            return 0;
#endif
        entry = yasm_symrec_get_data(sym, &elf_symrec_data);
        if (!entry) {
            elf_strtab_entry *name = !info->local_names || is_sect ? NULL :
                elf_strtab_append_str(info->objfmt_elf->strtab,
                                      yasm_symrec_get_name(sym));
            entry = elf_symtab_entry_create(name, sym);
            yasm_symrec_add_data(sym, &elf_symrec_data, entry);
        }

        if (!elf_sym_in_table(entry))
            elf_symtab_insert_local_sym(info->objfmt_elf->elf_symtab, entry);

        elf_symtab_set_nonzero(entry, sect, 0, STB_LOCAL,
                               is_sect ? STT_SECTION : 0, NULL, 0);

        if (is_sect)
            return 0;
    }

    if (precbc)
        value = yasm_bc_next_offset(precbc);
    elf_symtab_set_nonzero(entry, sect, 0, 0, 0, NULL, &value);

    return 0;
}

static yasm_objfmt *
elf_objfmt_create_common(yasm_object *object, yasm_objfmt_module *module,
                         int bits_pref,
                         const elf_machine_handler **elf_march_out)
{
    yasm_objfmt_elf *objfmt_elf = yasm_xmalloc(sizeof(yasm_objfmt_elf));
    yasm_symrec *filesym;
    elf_symtab_entry *entry;
    const elf_machine_handler *elf_march;

    objfmt_elf->objfmt.module = module;
    elf_march = elf_set_arch(object->arch, object->symtab, bits_pref);
    if (!elf_march) {
        yasm_xfree(objfmt_elf);
        return NULL;
    }
    if (elf_march_out)
        *elf_march_out = elf_march;

    objfmt_elf->shstrtab = elf_strtab_create();
    objfmt_elf->strtab = elf_strtab_create();
    objfmt_elf->elf_symtab = elf_symtab_create();

    /* FIXME: misuse of NULL bytecode here; it works, but only barely. */
    filesym = yasm_symtab_define_label(object->symtab, ".file", NULL, 0, 0);
    /* Put in current input filename; we'll replace it in output() */
    objfmt_elf->file_strtab_entry =
        elf_strtab_append_str(objfmt_elf->strtab, object->src_filename);
    entry = elf_symtab_entry_create(objfmt_elf->file_strtab_entry, filesym);
    yasm_symrec_add_data(filesym, &elf_symrec_data, entry);
    elf_symtab_set_nonzero(entry, NULL, SHN_ABS, STB_LOCAL, STT_FILE, NULL,
                           NULL);
    elf_symtab_append_entry(objfmt_elf->elf_symtab, entry);

    /* FIXME: misuse of NULL bytecode */
    objfmt_elf->dotdotsym =
        yasm_symtab_define_label(object->symtab, "..sym", NULL, 0, 0);

    return (yasm_objfmt *)objfmt_elf;
}

static yasm_objfmt *
elf_objfmt_create(yasm_object *object)
{
    const elf_machine_handler *elf_march;
    yasm_objfmt *objfmt;
    yasm_objfmt_elf *objfmt_elf;

    objfmt = elf_objfmt_create_common(object, &yasm_elf_LTX_objfmt, 0,
                                      &elf_march);
    if (objfmt) {
        objfmt_elf = (yasm_objfmt_elf *)objfmt;
        /* Figure out which bitness of object format to use */
        if (elf_march->bits == 32)
            objfmt_elf->objfmt.module = &yasm_elf32_LTX_objfmt;
        else if (elf_march->bits == 64)
            objfmt_elf->objfmt.module = &yasm_elf64_LTX_objfmt;
    }
    return objfmt;
}

static yasm_objfmt *
elf32_objfmt_create(yasm_object *object)
{
    return elf_objfmt_create_common(object, &yasm_elf32_LTX_objfmt, 32, NULL);
}

static yasm_objfmt *
elf64_objfmt_create(yasm_object *object)
{
    return elf_objfmt_create_common(object, &yasm_elf64_LTX_objfmt, 64, NULL);
}

static long
elf_objfmt_output_align(FILE *f, unsigned int align)
{
    long pos;
    unsigned long delta;
    if (!is_exp2(align))
        yasm_internal_error("requested alignment not a power of two");

    pos = ftell(f);
    if (pos == -1) {
        yasm_error_set(YASM_ERROR_IO,
                       N_("could not get file position on output file"));
        return -1;
    }
    delta = align - (pos & (align-1)); 
    if (delta != align) {
        pos += delta;
        if (fseek(f, pos, SEEK_SET) < 0) {
            yasm_error_set(YASM_ERROR_IO,
                           N_("could not set file position on output file"));
            return -1;
        }
    }
    return pos;
}

static int
elf_objfmt_output_reloc(yasm_symrec *sym, yasm_bytecode *bc,
                        unsigned char *buf, unsigned int destsize,
                        unsigned int valsize, int warn, void *d)
{
    elf_reloc_entry *reloc;
    elf_objfmt_output_info *info = d;
    yasm_intnum *zero;
    int retval;

    reloc = elf_reloc_entry_create(sym, NULL,
        yasm_intnum_create_uint(bc->offset), 0, valsize);
    if (reloc == NULL) {
        yasm_error_set(YASM_ERROR_TYPE, N_("elf: invalid relocation size"));
        return 1;
    }
    /* allocate .rel[a] sections on a need-basis */
    elf_secthead_append_reloc(info->sect, info->shead, reloc);

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

static int
elf_objfmt_output_value(yasm_value *value, unsigned char *buf,
                        unsigned int destsize, unsigned long offset,
                        yasm_bytecode *bc, int warn, /*@null@*/ void *d)
{
    /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;
    /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
    unsigned long intn_val;
    /*@null@*/ elf_reloc_entry *reloc = NULL;
    int retval;
    unsigned int valsize = value->size;

    if (info == NULL)
        yasm_internal_error("null info struct");

    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->seg_of || value->section_rel || value->rshift > 0) {
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("elf: relocation too complex"));
        return 1;
    }

    intn_val = 0;
    if (value->rel) {
        yasm_sym_vis vis = yasm_symrec_get_visibility(value->rel);
        /*@dependent@*/ /*@null@*/ yasm_symrec *sym = value->rel;
        /*@dependent@*/ /*@null@*/ yasm_symrec *wrt = value->wrt;

        if (wrt == info->objfmt_elf->dotdotsym)
            wrt = NULL;
        else if (wrt && elf_is_wrt_sym_relative(wrt))
            ;
        else if (wrt && elf_is_wrt_pos_adjusted(wrt))
            intn_val = offset + bc->offset;
        else if (vis == YASM_SYM_LOCAL) {
            yasm_bytecode *sym_precbc;
            /* Local symbols need relocation to their section's start, and
             * add in the offset of the bytecode (within the target section)
             * into the abs portion.
             *
             * This is only done if the symbol is relocated against the
             * section instead of the symbol itself.
             */
            if (yasm_symrec_get_label(sym, &sym_precbc)) {
                /* Relocate to section start */
                yasm_section *sym_sect = yasm_bc_get_section(sym_precbc);
                /*@null@*/ elf_secthead *sym_shead;
                sym_shead = yasm_section_get_data(sym_sect, &elf_section_data);
                assert(sym_shead != NULL);
                sym = elf_secthead_get_sym(sym_shead);

                intn_val = yasm_bc_next_offset(sym_precbc);
            }
        }
        
        /* For PC-relative, need to add offset of expression within bc. */
        if (value->curpos_rel)
            intn_val += offset;

        reloc = elf_reloc_entry_create(sym, wrt,
            yasm_intnum_create_uint(bc->offset + offset), value->curpos_rel,
            valsize);
        if (reloc == NULL) {
            yasm_error_set(YASM_ERROR_TYPE,
                           N_("elf: invalid relocation (WRT or size)"));
            return 1;
        }
        /* allocate .rel[a] sections on a need-basis */
        elf_secthead_append_reloc(info->sect, info->shead, reloc);
    }

    intn = yasm_intnum_create_uint(intn_val);

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

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

static int
elf_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
{
    /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;
    unsigned char buf[256];
    /*@null@*/ /*@only@*/ unsigned char *bigbuf;
    unsigned long size = 256;
    int gap;

    if (info == NULL)
        yasm_internal_error("null info struct");

    bigbuf = yasm_bc_tobytes(bc, buf, &size, &gap, info,
                             elf_objfmt_output_value, elf_objfmt_output_reloc);

    /* Don't bother doing anything else if size ended up being 0. */
    if (size == 0) {
        if (bigbuf)
            yasm_xfree(bigbuf);
        return 0;
    }
    else {
        yasm_intnum *bcsize = yasm_intnum_create_uint(size);
        elf_secthead_add_size(info->shead, bcsize);
        yasm_intnum_destroy(bcsize);
    }

    /* 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(buf, 0, 256);
        left = size;
        while (left > 256) {
            fwrite(buf, 256, 1, info->f);
            left -= 256;
        }
        fwrite(buf, left, 1, info->f);
    } else {
        /* Output buf (or bigbuf if non-NULL) to file */
        fwrite(bigbuf ? bigbuf : buf, (size_t)size, 1, info->f);
    }

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

    return 0;
}

static int
elf_objfmt_create_dbg_secthead(yasm_section *sect, /*@null@*/ void *d)
{
    /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;
    elf_secthead *shead;
    elf_section_type type=SHT_PROGBITS;
    elf_size entsize=0;
    const char *sectname;
    /*@dependent@*/ yasm_symrec *sym;
    elf_strtab_entry *name;

    shead = yasm_section_get_data(sect, &elf_section_data);
    if (shead)
        return 0;   /* only create new secthead if missing */

    sectname = yasm_section_get_name(sect);
    name = elf_strtab_append_str(info->objfmt_elf->shstrtab, sectname);

    if (yasm__strcasecmp(sectname, ".stab")==0) {
        entsize = 12;
    } else if (yasm__strcasecmp(sectname, ".stabstr")==0) {
        type = SHT_STRTAB;
    } else if (yasm__strncasecmp(sectname, ".debug_", 7)==0) {
        ;
    } else
        yasm_internal_error(N_("Unrecognized section without data"));

    shead = elf_secthead_create(name, type, 0, 0, 0);
    elf_secthead_set_entsize(shead, entsize);

    sym = yasm_symtab_define_label(info->object->symtab, sectname,
                                   yasm_section_bcs_first(sect), 1, 0);
    elf_secthead_set_sym(shead, sym);

    yasm_section_add_data(sect, &elf_section_data, shead);

    return 0;
}

static int
elf_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
{
    /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;
    /*@dependent@*/ /*@null@*/ elf_secthead *shead;
    long pos;
    char *relname;
    const char *sectname;

    if (info == NULL)
        yasm_internal_error("null info struct");
    shead = yasm_section_get_data(sect, &elf_section_data);
    if (shead == NULL)
        yasm_internal_error("no associated data");

    if (elf_secthead_get_align(shead) == 0)
        elf_secthead_set_align(shead, yasm_section_get_align(sect));

    /* don't output header-only sections */
    if ((elf_secthead_get_type(shead) & SHT_NOBITS) == SHT_NOBITS)
    {
        yasm_bytecode *last = yasm_section_bcs_last(sect);
        if (last) {
            yasm_intnum *sectsize;
            sectsize = yasm_intnum_create_uint(yasm_bc_next_offset(last));
            elf_secthead_add_size(shead, sectsize);
            yasm_intnum_destroy(sectsize);
        }
        elf_secthead_set_index(shead, ++info->sindex);
        return 0;
    }

    if ((pos = ftell(info->f)) == -1) {
        yasm_error_set(YASM_ERROR_IO,
                       N_("couldn't read position on output stream"));
        yasm_errwarn_propagate(info->errwarns, 0);
    }
    pos = elf_secthead_set_file_offset(shead, pos);
    if (fseek(info->f, pos, SEEK_SET) < 0) {
        yasm_error_set(YASM_ERROR_IO, N_("couldn't seek on output stream"));
        yasm_errwarn_propagate(info->errwarns, 0);
    }

    info->sect = sect;
    info->shead = shead;
    yasm_section_bcs_traverse(sect, info->errwarns, info,
                              elf_objfmt_output_bytecode);

    elf_secthead_set_index(shead, ++info->sindex);

    /* No relocations to output?  Go on to next section */
    if (elf_secthead_write_relocs_to_file(info->f, sect, shead,
                                          info->errwarns) == 0)
        return 0;
    elf_secthead_set_rel_index(shead, ++info->sindex);

    /* name the relocation section .rel[a].foo */
    sectname = yasm_section_get_name(sect);
    relname = elf_secthead_name_reloc_section(sectname);
    elf_secthead_set_rel_name(shead,
        elf_strtab_append_str(info->objfmt_elf->shstrtab, relname));
    yasm_xfree(relname);

    return 0;
}

static int
elf_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
{
    /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;
    /*@dependent@*/ /*@null@*/ elf_secthead *shead;

    if (info == NULL)
        yasm_internal_error("null info struct");
    shead = yasm_section_get_data(sect, &elf_section_data);
    if (shead == NULL)
        yasm_internal_error("no section header attached to section");

    if(elf_secthead_write_to_file(info->f, shead, info->sindex+1))
        info->sindex++;

    /* output strtab headers here? */

    /* relocation entries for .foo are stored in section .rel[a].foo */
    if(elf_secthead_write_rel_to_file(info->f, 3, sect, shead,
                                      info->sindex+1))
        info->sindex++;

    return 0;
}

static void
elf_objfmt_output(yasm_object *object, FILE *f, int all_syms,
                  yasm_errwarns *errwarns)
{
    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
    elf_objfmt_output_info info;
    build_symtab_info buildsym_info;
    long pos;
    unsigned long elf_shead_addr;
    elf_secthead *esdn;
    unsigned long elf_strtab_offset, elf_shstrtab_offset, elf_symtab_offset;
    unsigned long elf_strtab_size, elf_shstrtab_size, elf_symtab_size;
    elf_strtab_entry *elf_strtab_name, *elf_shstrtab_name, *elf_symtab_name;
    unsigned long elf_symtab_nlocal;

    info.object = object;
    info.objfmt_elf = objfmt_elf;
    info.errwarns = errwarns;
    info.f = f;

    /* Update filename strtab */
    elf_strtab_entry_set_str(objfmt_elf->file_strtab_entry,
                             object->src_filename);

    /* Allocate space for Ehdr by seeking forward */
    if (fseek(f, (long)(elf_proghead_get_size()), SEEK_SET) < 0) {
        yasm_error_set(YASM_ERROR_IO, N_("could not seek on output file"));
        yasm_errwarn_propagate(errwarns, 0);
        return;
    }

    /* Create missing section headers */
    if (yasm_object_sections_traverse(object, &info,
                                      elf_objfmt_create_dbg_secthead))
        return;

    /* add all (local) syms to symtab because relocation needs a symtab index
     * if all_syms, register them by name.  if not, use strtab entry 0 */
    buildsym_info.object = object;
    buildsym_info.objfmt_elf = objfmt_elf;
    buildsym_info.errwarns = errwarns;
    buildsym_info.local_names = all_syms;
    yasm_symtab_traverse(object->symtab, &buildsym_info,
                         elf_objfmt_build_symtab);
    elf_symtab_nlocal = elf_symtab_assign_indices(objfmt_elf->elf_symtab);

    /* output known sections - includes reloc sections which aren't in yasm's
     * list.  Assign indices as we go. */
    info.sindex = 3;
    if (yasm_object_sections_traverse(object, &info,
                                      elf_objfmt_output_section))
        return;

    /* add final sections to the shstrtab */
    elf_strtab_name = elf_strtab_append_str(objfmt_elf->shstrtab, ".strtab");
    elf_symtab_name = elf_strtab_append_str(objfmt_elf->shstrtab, ".symtab");
    elf_shstrtab_name = elf_strtab_append_str(objfmt_elf->shstrtab,
                                              ".shstrtab");

    /* output .shstrtab */
    if ((pos = elf_objfmt_output_align(f, 4)) == -1) {
        yasm_errwarn_propagate(errwarns, 0);
        return;
    }
    elf_shstrtab_offset = (unsigned long) pos;
    elf_shstrtab_size = elf_strtab_output_to_file(f, objfmt_elf->shstrtab);

    /* output .strtab */
    if ((pos = elf_objfmt_output_align(f, 4)) == -1) {
        yasm_errwarn_propagate(errwarns, 0);
        return;
    }
    elf_strtab_offset = (unsigned long) pos;
    elf_strtab_size = elf_strtab_output_to_file(f, objfmt_elf->strtab);

    /* output .symtab - last section so all others have indexes */
    if ((pos = elf_objfmt_output_align(f, 4)) == -1) {
        yasm_errwarn_propagate(errwarns, 0);
        return;
    }
    elf_symtab_offset = (unsigned long) pos;
    elf_symtab_size = elf_symtab_write_to_file(f, objfmt_elf->elf_symtab,
                                               errwarns);

    /* output section header table */
    if ((pos = elf_objfmt_output_align(f, 16)) == -1) {
        yasm_errwarn_propagate(errwarns, 0);
        return;
    }
    elf_shead_addr = (unsigned long) pos;

    /* stabs debugging support */
    if (strcmp(yasm_dbgfmt_keyword(object->dbgfmt), "stabs")==0) {
        yasm_section *stabsect = yasm_object_find_general(object, ".stab");
        yasm_section *stabstrsect =
            yasm_object_find_general(object, ".stabstr");
        if (stabsect && stabstrsect) {
            elf_secthead *stab =
                yasm_section_get_data(stabsect, &elf_section_data);
            elf_secthead *stabstr =
                yasm_section_get_data(stabstrsect, &elf_section_data);
            if (stab && stabstr) {
                elf_secthead_set_link(stab, elf_secthead_get_index(stabstr));
            }
            else
                yasm_internal_error(N_("missing .stab or .stabstr section/data"));
        }
    }
    
    /* output dummy section header - 0 */
    info.sindex = 0;

    esdn = elf_secthead_create(NULL, SHT_NULL, 0, 0, 0);
    elf_secthead_set_index(esdn, 0);
    elf_secthead_write_to_file(f, esdn, 0);
    elf_secthead_destroy(esdn);

    esdn = elf_secthead_create(elf_shstrtab_name, SHT_STRTAB, 0,
                               elf_shstrtab_offset, elf_shstrtab_size);
    elf_secthead_set_index(esdn, 1);
    elf_secthead_write_to_file(f, esdn, 1);
    elf_secthead_destroy(esdn);

    esdn = elf_secthead_create(elf_strtab_name, SHT_STRTAB, 0,
                               elf_strtab_offset, elf_strtab_size);
    elf_secthead_set_index(esdn, 2);
    elf_secthead_write_to_file(f, esdn, 2);
    elf_secthead_destroy(esdn);

    esdn = elf_secthead_create(elf_symtab_name, SHT_SYMTAB, 0,
                               elf_symtab_offset, elf_symtab_size);
    elf_secthead_set_index(esdn, 3);
    elf_secthead_set_info(esdn, elf_symtab_nlocal);
    elf_secthead_set_link(esdn, 2);     /* for .strtab, which is index 2 */
    elf_secthead_write_to_file(f, esdn, 3);
    elf_secthead_destroy(esdn);

    info.sindex = 3;
    /* output remaining section headers */
    yasm_object_sections_traverse(object, &info, elf_objfmt_output_secthead);

    /* output Ehdr */
    if (fseek(f, 0, SEEK_SET) < 0) {
        yasm_error_set(YASM_ERROR_IO, N_("could not seek on output file"));
        yasm_errwarn_propagate(errwarns, 0);
        return;
    }

    elf_proghead_write_to_file(f, elf_shead_addr, info.sindex+1, 1);
}

static void
elf_objfmt_destroy(yasm_objfmt *objfmt)
{
    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt;
    elf_symtab_destroy(objfmt_elf->elf_symtab);
    elf_strtab_destroy(objfmt_elf->shstrtab);
    elf_strtab_destroy(objfmt_elf->strtab);
    yasm_xfree(objfmt);
}

static elf_secthead *
elf_objfmt_init_new_section(yasm_object *object, yasm_section *sect,
                            const char *sectname, unsigned long type,
                            unsigned long flags, unsigned long line)
{
    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
    elf_secthead *esd;
    yasm_symrec *sym;
    elf_strtab_entry *name = elf_strtab_append_str(objfmt_elf->shstrtab,
                                                   sectname);

    esd = elf_secthead_create(name, type, flags, 0, 0);
    yasm_section_add_data(sect, &elf_section_data, esd);
    sym = yasm_symtab_define_label(object->symtab, sectname,
                                   yasm_section_bcs_first(sect), 1, line);

    elf_secthead_set_sym(esd, sym);

    return esd;
}

static yasm_section *
elf_objfmt_add_default_section(yasm_object *object)
{
    yasm_section *retval;
    int isnew;
    elf_secthead *esd;

    retval = yasm_object_get_general(object, ".text", 16, 1, 0, &isnew, 0);
    esd = elf_objfmt_init_new_section(object, retval, ".text", SHT_PROGBITS,
                                      SHF_ALLOC + SHF_EXECINSTR, 0);
    yasm_section_set_default(retval, 1);
    return retval;
}

struct elf_section_switch_data {
    /*@only@*/ /*@null@*/ yasm_intnum *align_intn;
    unsigned long flags;
    unsigned long type;
    int gasflags;
};

/* GAS-style flags */
static int
elf_helper_gasflags(void *obj, yasm_valparam *vp, unsigned long line, void *d,
                    /*@unused@*/ uintptr_t arg)
{
    struct elf_section_switch_data *data = (struct elf_section_switch_data *)d;
    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;
    }

    data->flags = 0;
    for (i=0; i<strlen(s); i++) {
        switch (s[i]) {
            case 'a':
                data->flags |= SHF_ALLOC;
                break;
            case 'w':
                data->flags |= SHF_WRITE;
                break;
            case 'x':
                data->flags |= SHF_EXECINSTR;
                break;
            case 'M':
                data->flags |= SHF_MERGE;
                break;
            case 'S':
                data->flags |= SHF_STRINGS;
                break;
            case 'G':
                data->flags |= SHF_GROUP;
                break;
            case 'T':
                data->flags |= SHF_TLS;
                break;
            default:
                yasm_warn_set(YASM_WARN_GENERAL,
                              N_("unrecognized section attribute: `%c'"),
                              s[i]);
        }
    }

    data->gasflags = 1;
    return 0;
}

static /*@observer@*/ /*@null@*/ yasm_section *
elf_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
                          /*@null@*/ yasm_valparamhead *objext_valparams,
                          unsigned long line)
{
    yasm_valparam *vp;
    yasm_section *retval;
    int isnew;
    unsigned long align = 4;
    int flags_override = 0;
    const char *sectname;
    int resonly = 0;

    struct elf_section_switch_data data;

    static const yasm_dir_help help[] = {
        { "alloc", 0, yasm_dir_helper_flag_or,
          offsetof(struct elf_section_switch_data, flags), SHF_ALLOC },
        { "exec", 0, yasm_dir_helper_flag_or,
          offsetof(struct elf_section_switch_data, flags), SHF_EXECINSTR },
        { "write", 0, yasm_dir_helper_flag_or,
          offsetof(struct elf_section_switch_data, flags), SHF_WRITE },
        { "tls", 0, yasm_dir_helper_flag_or,
          offsetof(struct elf_section_switch_data, flags), SHF_TLS },
        { "progbits", 0, yasm_dir_helper_flag_set,
          offsetof(struct elf_section_switch_data, type), SHT_PROGBITS },
        { "noalloc", 0, yasm_dir_helper_flag_and,
          offsetof(struct elf_section_switch_data, flags), SHF_ALLOC },
        { "noexec", 0, yasm_dir_helper_flag_and,
          offsetof(struct elf_section_switch_data, flags), SHF_EXECINSTR },
        { "nowrite",  0, yasm_dir_helper_flag_and,
          offsetof(struct elf_section_switch_data, flags), SHF_WRITE },
        { "notls",  0, yasm_dir_helper_flag_and,
          offsetof(struct elf_section_switch_data, flags), SHF_TLS },
        { "noprogbits", 0, yasm_dir_helper_flag_set,
          offsetof(struct elf_section_switch_data, type), SHT_NOBITS },
        { "nobits", 0, yasm_dir_helper_flag_set,
          offsetof(struct elf_section_switch_data, type), SHT_NOBITS },
        { "gasflags", 1, elf_helper_gasflags, 0, 0 },
        { "align", 1, yasm_dir_helper_intn,
          offsetof(struct elf_section_switch_data, align_intn), 0 }
    };
    /*@only@*/ /*@null@*/ yasm_expr *merge_expr = NULL;
    /*@dependent@*/ /*@null@*/ const yasm_intnum *merge_intn = NULL;
    elf_secthead *esd;

    data.align_intn = NULL;
    data.flags = SHF_ALLOC;
    data.type = SHT_PROGBITS;
    data.gasflags = 0;

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

    if (strcmp(sectname, ".bss") == 0) {
        data.type = SHT_NOBITS;
        data.flags = SHF_ALLOC + SHF_WRITE;
        resonly = 1;
    } else if (strcmp(sectname, ".data") == 0) {
        data.type = SHT_PROGBITS;
        data.flags = SHF_ALLOC + SHF_WRITE;
    } else if (strcmp(sectname, ".tdata") == 0) {
        data.type = SHT_PROGBITS;
        data.flags = SHF_ALLOC + SHF_WRITE + SHF_TLS;
    } else if (strcmp(sectname, ".rodata") == 0) {
        data.type = SHT_PROGBITS;
        data.flags = SHF_ALLOC;
    } else if (strcmp(sectname, ".text") == 0) {
        align = 16;
        data.type = SHT_PROGBITS;
        data.flags = SHF_ALLOC + SHF_EXECINSTR;
    } else if (strcmp(sectname, ".comment") == 0) {
        align = 0;
        data.type = SHT_PROGBITS;
        data.flags = 0;
    } else {
        /* Default to code */
        align = 1;
    }

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

    /* Handle merge entity size */
    if (data.flags & SHF_MERGE) {
        if (objext_valparams && (vp = yasm_vps_first(objext_valparams))
            && !vp->val) {
            if (!(merge_expr = yasm_vp_expr(vp, object->symtab, line)) ||
                !(merge_intn = yasm_expr_get_intnum(&merge_expr, 0)))
                yasm_warn_set(YASM_WARN_GENERAL,
                              N_("invalid merge entity size"));
        } else {
            yasm_warn_set(YASM_WARN_GENERAL,
                          N_("entity size for SHF_MERGE not specified"));
            data.flags &= ~SHF_MERGE;
        }
    }

    retval = yasm_object_get_general(object, sectname, align,
                                     (data.flags & SHF_EXECINSTR) != 0,
                                     resonly, &isnew, line);

    if (isnew)
        esd = elf_objfmt_init_new_section(object, retval, sectname, data.type,
                                          data.flags, line);
    else
        esd = yasm_section_get_data(retval, &elf_section_data);

    if (isnew || yasm_section_is_default(retval)) {
        yasm_section_set_default(retval, 0);
        elf_secthead_set_typeflags(esd, data.type, data.flags);
        if (merge_intn)
            elf_secthead_set_entsize(esd, yasm_intnum_get_uint(merge_intn));
        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"));
    if (merge_expr)
        yasm_expr_destroy(merge_expr);
    return retval;
}

static /*@observer@*/ /*@null@*/ yasm_symrec *
elf_objfmt_get_special_sym(yasm_object *object, const char *name,
                           const char *parser)
{
    if (yasm__strcasecmp(name, "sym") == 0) {
        yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
        return objfmt_elf->dotdotsym;
    }
    return elf_get_special_sym(name, parser);
}

static void
dir_type(yasm_object *object, yasm_valparamhead *valparams,
         yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
    yasm_valparam *vp = yasm_vps_first(valparams);
    const char *symname = yasm_vp_id(vp);
    /* Get symbol elf data */
    yasm_symrec *sym = yasm_symtab_use(object->symtab, symname, line);
    elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data);
    /*@null@*/ const char *type;

    /* Create entry if necessary */
    if (!entry) {
        entry = elf_symtab_entry_create(
            elf_strtab_append_str(objfmt_elf->strtab, symname), sym);
        yasm_symrec_add_data(sym, &elf_symrec_data, entry);
    }

    /* Pull new type from param */
    vp = yasm_vps_next(vp);
    if (vp && !vp->val && (type = yasm_vp_id(vp))) {
        if (yasm__strcasecmp(type, "function") == 0)
            elf_sym_set_type(entry, STT_FUNC);
        else if (yasm__strcasecmp(type, "object") == 0)
            elf_sym_set_type(entry, STT_OBJECT);
        else if (yasm__strcasecmp(type, "tls_object") == 0)
            elf_sym_set_type(entry, STT_TLS);
        else if (yasm__strcasecmp(type, "notype") == 0)
            elf_sym_set_type(entry, STT_NOTYPE);
        else
            yasm_warn_set(YASM_WARN_GENERAL,
                          N_("unrecognized symbol type `%s'"), type);
    } else
        yasm_error_set(YASM_ERROR_SYNTAX, N_("no type specified"));
}

static void
dir_size(yasm_object *object, yasm_valparamhead *valparams,
         yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
    yasm_valparam *vp = yasm_vps_first(valparams);
    const char *symname = yasm_vp_id(vp);
    /* Get symbol elf data */
    yasm_symrec *sym = yasm_symtab_use(object->symtab, symname, line);
    elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data);
    /*@only@*/ /*@null@*/ yasm_expr *size;

    /* Create entry if necessary */
    if (!entry) {
        entry = elf_symtab_entry_create(
            elf_strtab_append_str(objfmt_elf->strtab, symname), sym);
        yasm_symrec_add_data(sym, &elf_symrec_data, entry);
    }

    /* Pull new size from param */
    vp = yasm_vps_next(vp);
    if (vp && !vp->val && (size = yasm_vp_expr(vp, object->symtab, line)))
        elf_sym_set_size(entry, size);
    else
        yasm_error_set(YASM_ERROR_SYNTAX, N_("no size specified"));
}

static void
dir_weak(yasm_object *object, yasm_valparamhead *valparams,
         yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt;
    yasm_valparam *vp = yasm_vps_first(valparams);
    const char *symname = yasm_vp_id(vp);
    yasm_symrec *sym = yasm_symtab_declare(object->symtab, symname,
                                           YASM_SYM_GLOBAL, line);
    elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_WEAK, 0,
                             STV_DEFAULT, NULL, NULL);
}

static void
dir_ident(yasm_object *object, yasm_valparamhead *valparams,
          yasm_valparamhead *objext_valparams, unsigned long line)
{
    yasm_valparamhead sect_vps;
    yasm_datavalhead dvs;
    yasm_section *comment;
    yasm_valparam *vp;
    yasm_valparam *vp2;

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

    /* Put ident data into .comment section */
    yasm_vps_initialize(&sect_vps);
    vp2 = yasm_vp_create_string(NULL, yasm__xstrdup(".comment"));
    yasm_vps_append(&sect_vps, vp2);
    comment = elf_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));
}

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

static const yasm_directive elf_objfmt_directives[] = {
    { ".type",          "gas",  dir_type,       YASM_DIR_ID_REQUIRED },
    { ".size",          "gas",  dir_size,       YASM_DIR_ID_REQUIRED },
    { ".weak",          "gas",  dir_weak,       YASM_DIR_ID_REQUIRED },
    { ".ident",         "gas",  dir_ident,      YASM_DIR_ANY },
    { "type",           "nasm", dir_type,       YASM_DIR_ID_REQUIRED },
    { "size",           "nasm", dir_size,       YASM_DIR_ID_REQUIRED },
    { "weak",           "nasm", dir_weak,       YASM_DIR_ID_REQUIRED },
    { "ident",          "nasm", dir_ident,      YASM_DIR_ANY },
    { NULL, NULL, NULL, 0 }
};

/* Define objfmt structure -- see objfmt.h for details */
yasm_objfmt_module yasm_elf_LTX_objfmt = {
    "ELF",
    "elf",
    "o",
    32,
    elf_objfmt_dbgfmt_keywords,
    "null",
    elf_objfmt_directives,
    elf_objfmt_create,
    elf_objfmt_output,
    elf_objfmt_destroy,
    elf_objfmt_add_default_section,
    elf_objfmt_section_switch,
    elf_objfmt_get_special_sym
};

yasm_objfmt_module yasm_elf32_LTX_objfmt = {
    "ELF (32-bit)",
    "elf32",
    "o",
    32,
    elf_objfmt_dbgfmt_keywords,
    "null",
    elf_objfmt_directives,
    elf32_objfmt_create,
    elf_objfmt_output,
    elf_objfmt_destroy,
    elf_objfmt_add_default_section,
    elf_objfmt_section_switch,
    elf_objfmt_get_special_sym
};

yasm_objfmt_module yasm_elf64_LTX_objfmt = {
    "ELF (64-bit)",
    "elf64",
    "o",
    64,
    elf_objfmt_dbgfmt_keywords,
    "null",
    elf_objfmt_directives,
    elf64_objfmt_create,
    elf_objfmt_output,
    elf_objfmt_destroy,
    elf_objfmt_add_default_section,
    elf_objfmt_section_switch,
    elf_objfmt_get_special_sym
};
