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

#include <libyasm.h>

/* NOTE: For this code to generate relocation information, the relocations
 * have to be added by the object format to each section in program source
 * order.
 *
 * This should not be an issue, as program source order == section bytecode
 * order, so unless the object formats are very obtuse with their bytecode
 * iteration, this should just happen.
 */

#define REGULAR_BUF_SIZE    1024

yasm_listfmt_module yasm_nasm_LTX_listfmt;

typedef struct sectreloc {
    /*@reldef@*/ SLIST_ENTRY(sectreloc) link;
    yasm_section *sect;
    /*@null@*/ yasm_reloc *next_reloc;  /* next relocation in section */
    unsigned long next_reloc_addr;
} sectreloc;

typedef struct bcreloc {
    /*@reldef@*/ STAILQ_ENTRY(bcreloc) link;
    unsigned long offset;       /* start of reloc from start of bytecode */
    size_t size;                /* size of reloc in bytes */
    int rel;                    /* PC/IP-relative or "absolute" */
} bcreloc;

typedef struct nasm_listfmt_output_info {
    yasm_arch *arch;
    /*@reldef@*/ STAILQ_HEAD(bcrelochead, bcreloc) bcrelocs;
    /*@null@*/ yasm_reloc *next_reloc;  /* next relocation in section */
    unsigned long next_reloc_addr;
} nasm_listfmt_output_info;


static /*@null@*/ /*@only@*/ yasm_listfmt *
nasm_listfmt_create(const char *in_filename, const char *obj_filename)
{
    yasm_listfmt_base *listfmt = yasm_xmalloc(sizeof(yasm_listfmt_base));
    listfmt->module = &yasm_nasm_LTX_listfmt;
    return (yasm_listfmt *)listfmt;
}

static void
nasm_listfmt_destroy(/*@only@*/ yasm_listfmt *listfmt)
{
    yasm_xfree(listfmt);
}

static int
nasm_listfmt_output_value(yasm_value *value, unsigned char *buf,
                          unsigned int destsize, unsigned long offset,
                          yasm_bytecode *bc, int warn, /*@null@*/ void *d)
{
    /*@null@*/ nasm_listfmt_output_info *info = (nasm_listfmt_output_info *)d;
    /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
    unsigned int valsize = value->size;

    assert(info != NULL);

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

    /* Generate reloc if needed */
    if (info->next_reloc && info->next_reloc_addr == bc->offset+offset) {
        bcreloc *reloc = yasm_xmalloc(sizeof(bcreloc));
        reloc->offset = offset;
        reloc->size = destsize;
        reloc->rel = value->curpos_rel;
        STAILQ_INSERT_TAIL(&info->bcrelocs, reloc, link);

        /* Get next reloc's info */
        info->next_reloc = yasm_section_reloc_next(info->next_reloc);
        if (info->next_reloc) {
            yasm_intnum *addr;
            yasm_symrec *sym;
            yasm_reloc_get(info->next_reloc, &addr, &sym);
            info->next_reloc_addr = yasm_intnum_get_uint(addr);
        }
    }

    if (value->abs) {
        intn = yasm_expr_get_intnum(&value->abs, 0);
        if (intn)
            return yasm_arch_intnum_tobytes(info->arch, intn, buf, destsize,
                                            valsize, 0, bc, 0);
        else {
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("relocation too complex"));
            return 1;
        }
    } else {
        int retval;
        intn = yasm_intnum_create_uint(0);
        retval = yasm_arch_intnum_tobytes(info->arch, intn, buf, destsize,
                                          valsize, 0, bc, 0);
        yasm_intnum_destroy(intn);
        return retval;
    }

    return 0;
}

static void
nasm_listfmt_output(yasm_listfmt *listfmt, FILE *f, yasm_linemap *linemap,
                    yasm_arch *arch)
{
    yasm_bytecode *bc;
    const char *source;
    unsigned long line = 1;
    unsigned long listline = 1;
    /*@only@*/ unsigned char *buf;
    nasm_listfmt_output_info info;
    /*@reldef@*/ SLIST_HEAD(sectrelochead, sectreloc) reloc_hist;
    /*@null@*/ sectreloc *last_hist = NULL;
    /*@null@*/ bcreloc *reloc = NULL;
    yasm_section *sect;

    SLIST_INIT(&reloc_hist);

    info.arch = arch;

    buf = yasm_xmalloc(REGULAR_BUF_SIZE);

    while (!yasm_linemap_get_source(linemap, line, &bc, &source)) {
        if (!bc) {
            fprintf(f, "%6lu %*s%s\n", listline++, 32, "", source);
        } else {
            /* get the next relocation for the bytecode's section */
            sect = yasm_bc_get_section(bc);
            if (!last_hist || last_hist->sect != sect) {
                int found = 0;

                /* look through reloc_hist for matching section */
                SLIST_FOREACH(last_hist, &reloc_hist, link) {
                    if (last_hist->sect == sect) {
                        found = 1;
                        break;
                    }
                }

                if (!found) {
                    /* not found, add to list*/
                    last_hist = yasm_xmalloc(sizeof(sectreloc));
                    last_hist->sect = sect;
                    last_hist->next_reloc = yasm_section_relocs_first(sect);

                    if (last_hist->next_reloc) {
                        yasm_intnum *addr;
                        yasm_symrec *sym;
                        yasm_reloc_get(last_hist->next_reloc, &addr, &sym);
                        last_hist->next_reloc_addr =
                            yasm_intnum_get_uint(addr);
                    }

                    SLIST_INSERT_HEAD(&reloc_hist, last_hist, link);
                }
            }

            info.next_reloc = last_hist->next_reloc;
            info.next_reloc_addr = last_hist->next_reloc_addr;
            STAILQ_INIT(&info.bcrelocs);

            /* loop over bytecodes on this line (usually only one) */
            while (bc && bc->line == line) {
                /*@null@*/ /*@only@*/ unsigned char *bigbuf;
                unsigned long size = REGULAR_BUF_SIZE;
                long multiple;
                unsigned long offset = bc->offset;
                unsigned char *origp, *p;
                int gap;

                /* convert bytecode into bytes, recording relocs along the
                 * way
                 */
                bigbuf = yasm_bc_tobytes(bc, buf, &size, &gap, &info,
                                         nasm_listfmt_output_value, NULL);
                yasm_bc_get_multiple(bc, &multiple, 1);
                if (multiple <= 0)
                    size = 0;
                else
                    size /= multiple;

                /* output bytes with reloc information */
                origp = bigbuf ? bigbuf : buf;
                p = origp;
                reloc = STAILQ_FIRST(&info.bcrelocs);
                if (gap) {
                    fprintf(f, "%6lu %08lX <gap>%*s%s\n", listline++, offset,
                            18, "", source ? source : "");
                } else while (size > 0) {
                    int i;

                    fprintf(f, "%6lu %08lX ", listline++, offset);
                    for (i=0; i<18 && size > 0; size--) {
                        if (reloc && (unsigned long)(p-origp) ==
                                     reloc->offset) {
                            fprintf(f, "%c", reloc->rel ? '(' : '[');
                            i++;
                        }
                        fprintf(f, "%02X", *(p++));
                        i+=2;
                        if (reloc && (unsigned long)(p-origp) ==
                                     reloc->offset+reloc->size) {
                            fprintf(f, "%c", reloc->rel ? ')' : ']');
                            i++;
                            reloc = STAILQ_NEXT(reloc, link);
                        }
                    }
                    if (size > 0)
                        fprintf(f, "-");
                    else {
                        if (multiple > 1) {
                            fprintf(f, "<rept>");
                            i += 6;
                        }
                        fprintf(f, "%*s", 18-i+1, "");
                    }
                    if (source) {
                        fprintf(f, "    %s", source);
                        source = NULL;
                    }
                    fprintf(f, "\n");
                }

                if (bigbuf)
                    yasm_xfree(bigbuf);
                bc = STAILQ_NEXT(bc, link);
            }

            /* delete bcrelocs (newly generated next bytecode if any) */
            reloc = STAILQ_FIRST(&info.bcrelocs);
            while (reloc) {
                bcreloc *reloc2 = STAILQ_NEXT(reloc, link);
                yasm_xfree(reloc);
                reloc = reloc2;
            }

            /* save reloc context */
            last_hist->next_reloc = info.next_reloc;
            last_hist->next_reloc_addr = info.next_reloc_addr;
        }
        line++;
    }

    /* delete reloc history */
    while (!SLIST_EMPTY(&reloc_hist)) {
        last_hist = SLIST_FIRST(&reloc_hist);
        SLIST_REMOVE_HEAD(&reloc_hist, link);
        yasm_xfree(last_hist);
    }

    yasm_xfree(buf);
}

/* Define listfmt structure -- see listfmt.h for details */
yasm_listfmt_module yasm_nasm_LTX_listfmt = {
    "NASM-style list format",
    "nasm",
    nasm_listfmt_create,
    nasm_listfmt_destroy,
    nasm_listfmt_output
};
