/*
 * Win64 structured exception handling support
 *
 *  Copyright (C) 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: win64-except.c,v 1.1.1.1 2012/03/29 17:21:02 uid42307 Exp $");

#include <libyasm.h>

#include "coff-objfmt.h"


#define UNW_FLAG_EHANDLER   0x01
#define UNW_FLAG_UHANDLER   0x02
#define UNW_FLAG_CHAININFO  0x03

/* Bytecode callback function prototypes */
static void win64_uwinfo_bc_destroy(void *contents);
static void win64_uwinfo_bc_print(const void *contents, FILE *f,
                                  int indent_level);
static void win64_uwinfo_bc_finalize(yasm_bytecode *bc,
                                     yasm_bytecode *prev_bc);
static int win64_uwinfo_bc_calc_len
    (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
static int win64_uwinfo_bc_expand(yasm_bytecode *bc, int span, long old_val,
                                  long new_val, /*@out@*/ long *neg_thres,
                                  /*@out@*/ long *pos_thres);
static int win64_uwinfo_bc_tobytes
    (yasm_bytecode *bc, unsigned char **bufp, void *d,
     yasm_output_value_func output_value,
     /*@null@*/ yasm_output_reloc_func output_reloc);

static void win64_uwcode_bc_destroy(void *contents);
static void win64_uwcode_bc_print(const void *contents, FILE *f,
                                  int indent_level);
static void win64_uwcode_bc_finalize(yasm_bytecode *bc,
                                     yasm_bytecode *prev_bc);
static int win64_uwcode_bc_calc_len
    (yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
static int win64_uwcode_bc_expand(yasm_bytecode *bc, int span, long old_val,
                                  long new_val, /*@out@*/ long *neg_thres,
                                  /*@out@*/ long *pos_thres);
static int win64_uwcode_bc_tobytes
    (yasm_bytecode *bc, unsigned char **bufp, void *d,
     yasm_output_value_func output_value,
     /*@null@*/ yasm_output_reloc_func output_reloc);

/* Bytecode callback structures */
static const yasm_bytecode_callback win64_uwinfo_bc_callback = {
    win64_uwinfo_bc_destroy,
    win64_uwinfo_bc_print,
    win64_uwinfo_bc_finalize,
    win64_uwinfo_bc_calc_len,
    win64_uwinfo_bc_expand,
    win64_uwinfo_bc_tobytes,
    0
};

static const yasm_bytecode_callback win64_uwcode_bc_callback = {
    win64_uwcode_bc_destroy,
    win64_uwcode_bc_print,
    win64_uwcode_bc_finalize,
    win64_uwcode_bc_calc_len,
    win64_uwcode_bc_expand,
    win64_uwcode_bc_tobytes,
    0
};


coff_unwind_info *
yasm_win64__uwinfo_create(void)
{
    coff_unwind_info *info = yasm_xmalloc(sizeof(coff_unwind_info));
    info->proc = NULL;
    info->prolog = NULL;
    info->ehandler = NULL;
    info->framereg = 0;
    /* Frameoff is really a 4-bit value, scaled by 16 */
    yasm_value_initialize(&info->frameoff, NULL, 8);
    SLIST_INIT(&info->codes);
    yasm_value_initialize(&info->prolog_size, NULL, 8);
    yasm_value_initialize(&info->codes_count, NULL, 8);
    return info;
}

void
yasm_win64__uwinfo_destroy(coff_unwind_info *info)
{
    coff_unwind_code *code;

    yasm_value_delete(&info->frameoff);
    yasm_value_delete(&info->prolog_size);
    yasm_value_delete(&info->codes_count);

    while (!SLIST_EMPTY(&info->codes)) {
        code = SLIST_FIRST(&info->codes);
        SLIST_REMOVE_HEAD(&info->codes, link);
        yasm_value_delete(&code->off);
        yasm_xfree(code);
    }
    yasm_xfree(info);
}

void
yasm_win64__unwind_generate(yasm_section *xdata, coff_unwind_info *info,
                            unsigned long line)
{
    yasm_bytecode *infobc, *codebc = NULL;
    coff_unwind_code *code;

    /* 4-byte align the start of unwind info */
    yasm_section_bcs_append(xdata, yasm_bc_create_align(
        yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(4)),
                               line),
        NULL, NULL, NULL, line));

    /* Prolog size = end of prolog - start of procedure */
    yasm_value_initialize(&info->prolog_size,
        yasm_expr_create(YASM_EXPR_SUB, yasm_expr_sym(info->prolog),
                         yasm_expr_sym(info->proc), line),
        8);

    /* Unwind info */
    infobc = yasm_bc_create_common(&win64_uwinfo_bc_callback, info, line);
    yasm_section_bcs_append(xdata, infobc);

    /* Code array */
    SLIST_FOREACH(code, &info->codes, link) {
        codebc = yasm_bc_create_common(&win64_uwcode_bc_callback, code,
                                       yasm_symrec_get_def_line(code->loc));
        yasm_section_bcs_append(xdata, codebc);
    }

    /* Avoid double-free (by code destroy and uwinfo destroy). */
    SLIST_INIT(&info->codes);

    /* Number of codes = (Last code - end of info) >> 1 */
    if (!codebc) {
        yasm_value_initialize(&info->codes_count,
            yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)),
                                   line),
            8);
    } else {
        yasm_value_initialize(&info->codes_count,
            yasm_expr_create(YASM_EXPR_SHR, yasm_expr_expr(
                yasm_expr_create(YASM_EXPR_SUB, yasm_expr_precbc(codebc),
                                 yasm_expr_precbc(infobc), line)),
                yasm_expr_int(yasm_intnum_create_uint(1)), line),
            8);
    }

    /* 4-byte align */
    yasm_section_bcs_append(xdata, yasm_bc_create_align(
        yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(4)),
                               line),
        NULL, NULL, NULL, line));

    /* Exception handler, if present.  Use data bytecode. */
    if (info->ehandler) {
        yasm_datavalhead dvs;

        yasm_dvs_initialize(&dvs);
        yasm_dvs_append(&dvs, yasm_dv_create_expr(
            yasm_expr_create_ident(yasm_expr_sym(info->ehandler), line)));
        yasm_section_bcs_append(xdata,
                                yasm_bc_create_data(&dvs, 4, 0, NULL, line));
    }
}

static void
win64_uwinfo_bc_destroy(void *contents)
{
    yasm_win64__uwinfo_destroy((coff_unwind_info *)contents);
}

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

static void
win64_uwinfo_bc_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
{
    coff_unwind_info *info = (coff_unwind_info *)bc->contents;

    if (yasm_value_finalize(&info->prolog_size, prev_bc))
        yasm_internal_error(N_("prolog size expression too complex"));

    if (yasm_value_finalize(&info->codes_count, prev_bc))
        yasm_internal_error(N_("codes count expression too complex"));

    if (yasm_value_finalize(&info->frameoff, prev_bc))
        yasm_error_set(YASM_ERROR_VALUE,
                       N_("frame offset expression too complex"));
}

static int
win64_uwinfo_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                         void *add_span_data)
{
    coff_unwind_info *info = (coff_unwind_info *)bc->contents;
    /*@only@*/ /*@null@*/ yasm_intnum *intn;
    long intv;

    /* Want to make sure prolog size and codes count doesn't exceed
     * byte-size, and scaled frame offset doesn't exceed 4 bits.
     */
    add_span(add_span_data, bc, 1, &info->prolog_size, 0, 255);
    add_span(add_span_data, bc, 2, &info->codes_count, 0, 255);

    intn = yasm_value_get_intnum(&info->frameoff, bc, 0);
    if (intn) {
        intv = yasm_intnum_get_int(intn);
        if (intv < 0 || intv > 240)
            yasm_error_set(YASM_ERROR_VALUE,
                N_("frame offset of %ld bytes, must be between 0 and 240"),
                intv);
        else if ((intv & 0xF) != 0)
            yasm_error_set(YASM_ERROR_VALUE,
                N_("frame offset of %ld is not a multiple of 16"), intv);
        yasm_intnum_destroy(intn);
    } else
        add_span(add_span_data, bc, 3, &info->frameoff, 0, 240);

    bc->len += 4;
    return 0;
}

static int
win64_uwinfo_bc_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
                       /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
{
    coff_unwind_info *info = (coff_unwind_info *)bc->contents;
    switch (span) {
        case 1:
            yasm_error_set_xref(yasm_symrec_get_def_line(info->prolog),
                                N_("prologue ended here"));
            yasm_error_set(YASM_ERROR_VALUE,
                           N_("prologue %ld bytes, must be <256"), new_val);
            return -1;
        case 2:
            yasm_error_set(YASM_ERROR_VALUE,
                           N_("%ld unwind codes, maximum of 255"), new_val);
            return -1;
        case 3:
            yasm_error_set(YASM_ERROR_VALUE,
                N_("frame offset of %ld bytes, must be between 0 and 240"),
                new_val);
            return -1;
        default:
            yasm_internal_error(N_("unrecognized span id"));
    }
    return 0;
}

static int
win64_uwinfo_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
                        yasm_output_value_func output_value,
                        yasm_output_reloc_func output_reloc)
{
    coff_unwind_info *info = (coff_unwind_info *)bc->contents;
    unsigned char *buf = *bufp;
    /*@only@*/ /*@null@*/ yasm_intnum *frameoff;
    long intv;

    /* Version and flags */
    if (info->ehandler)
        YASM_WRITE_8(buf, 1 | (UNW_FLAG_EHANDLER << 3));
    else
        YASM_WRITE_8(buf, 1);

    /* Size of prolog */
    output_value(&info->prolog_size, buf, 1, (unsigned long)(buf-*bufp),
                 bc, 1, d);
    buf += 1;

    /* Count of codes */
    output_value(&info->codes_count, buf, 1, (unsigned long)(buf-*bufp),
                 bc, 1, d);
    buf += 1;

    /* Frame register and offset */
    frameoff = yasm_value_get_intnum(&info->frameoff, bc, 1);
    if (!frameoff) {
        yasm_error_set(YASM_ERROR_VALUE,
                       N_("frame offset expression too complex"));
        return 1;
    }
    intv = yasm_intnum_get_int(frameoff);
    if (intv < 0 || intv > 240)
        yasm_error_set(YASM_ERROR_VALUE,
            N_("frame offset of %ld bytes, must be between 0 and 240"), intv);
    else if ((intv & 0xF) != 0)
        yasm_error_set(YASM_ERROR_VALUE,
            N_("frame offset of %ld is not a multiple of 16"), intv);

    YASM_WRITE_8(buf, ((unsigned long)intv & 0xF0) | (info->framereg & 0x0F));
    yasm_intnum_destroy(frameoff);

    *bufp = buf;
    return 0;
}

static void
win64_uwcode_bc_destroy(void *contents)
{
    coff_unwind_code *code = (coff_unwind_code *)contents;
    yasm_value_delete(&code->off);
    yasm_xfree(contents);
}

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

static void
win64_uwcode_bc_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
{
    coff_unwind_code *code = (coff_unwind_code *)bc->contents;
    if (yasm_value_finalize(&code->off, prev_bc))
        yasm_error_set(YASM_ERROR_VALUE, N_("offset expression too complex"));
}

static int
win64_uwcode_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                         void *add_span_data)
{
    coff_unwind_code *code = (coff_unwind_code *)bc->contents;
    int span = 0;
    /*@only@*/ /*@null@*/ yasm_intnum *intn;
    long intv;
    long low, high, mask;

    bc->len += 2;   /* Prolog offset, code, and info */

    switch (code->opcode) {
        case UWOP_PUSH_NONVOL:
        case UWOP_SET_FPREG:
        case UWOP_PUSH_MACHFRAME:
            /* always 1 node */
            return 0;
        case UWOP_ALLOC_SMALL:
        case UWOP_ALLOC_LARGE:
            /* Start with smallest, then work our way up as necessary */
            code->opcode = UWOP_ALLOC_SMALL;
            code->info = 0;
            span = 1; low = 8; high = 128; mask = 0x7;
            break;
        case UWOP_SAVE_NONVOL:
        case UWOP_SAVE_NONVOL_FAR:
            /* Start with smallest, then work our way up as necessary */
            code->opcode = UWOP_SAVE_NONVOL;
            bc->len += 2;   /* Scaled offset */
            span = 2;
            low = 0;
            high = 8*64*1024-8;         /* 16-bit field, *8 scaling */
            mask = 0x7;
            break;
        case UWOP_SAVE_XMM128:
        case UWOP_SAVE_XMM128_FAR:
            /* Start with smallest, then work our way up as necessary */
            code->opcode = UWOP_SAVE_XMM128;
            bc->len += 2;   /* Scaled offset */
            span = 3;
            low = 0;
            high = 16*64*1024-16;       /* 16-bit field, *16 scaling */
            mask = 0xF;
            break;
        default:
            yasm_internal_error(N_("unrecognied unwind opcode"));
            /*@unreached@*/
            return 0;
    }

    intn = yasm_value_get_intnum(&code->off, bc, 0);
    if (intn) {
        intv = yasm_intnum_get_int(intn);
        if (intv > high) {
            /* Expand it ourselves here if we can and we're already larger */
            if (win64_uwcode_bc_expand(bc, span, intv, intv, &low, &high) > 0)
                add_span(add_span_data, bc, span, &code->off, low, high);
        }
        if (intv < low)
            yasm_error_set(YASM_ERROR_VALUE,
                           N_("negative offset not allowed"));
        if ((intv & mask) != 0)
            yasm_error_set(YASM_ERROR_VALUE,
                N_("offset of %ld is not a multiple of %ld"), intv, mask+1);
        yasm_intnum_destroy(intn);
    } else
        add_span(add_span_data, bc, span, &code->off, low, high);
    return 0;
}

static int
win64_uwcode_bc_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
                       /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
{
    coff_unwind_code *code = (coff_unwind_code *)bc->contents;

    if (new_val < 0) {
        yasm_error_set(YASM_ERROR_VALUE, N_("negative offset not allowed"));
        return -1;
    }

    if (span == 1) {
        /* 3 stages: SMALL, LARGE and info=0, LARGE and info=1 */
        if (code->opcode == UWOP_ALLOC_LARGE && code->info == 1)
            yasm_internal_error(N_("expansion on already largest alloc"));

        if (code->opcode == UWOP_ALLOC_SMALL && new_val > 128) {
            /* Overflowed small size */
            code->opcode = UWOP_ALLOC_LARGE;
            bc->len += 2;
        }
        if (new_val <= 8*64*1024-8) {
            /* Still can grow one more size */
            *pos_thres = 8*64*1024-8;
            return 1;
        }
        /* We're into the largest size */
        code->info = 1;
        bc->len += 2;
    } else if (code->opcode == UWOP_SAVE_NONVOL && span == 2) {
        code->opcode = UWOP_SAVE_NONVOL_FAR;
        bc->len += 2;
    } else if (code->opcode == UWOP_SAVE_XMM128 && span == 3) {
        code->opcode = UWOP_SAVE_XMM128_FAR;
        bc->len += 2;
    }
    return 0;
}

static int
win64_uwcode_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
                        yasm_output_value_func output_value,
                        yasm_output_reloc_func output_reloc)
{
    coff_unwind_code *code = (coff_unwind_code *)bc->contents;
    unsigned char *buf = *bufp;
    yasm_value val;
    unsigned int size;
    int shift;
    long intv, low, high, mask;
    yasm_intnum *intn;

    /* Offset in prolog */
    yasm_value_initialize(&val,
        yasm_expr_create(YASM_EXPR_SUB, yasm_expr_sym(code->loc),
                         yasm_expr_sym(code->proc), bc->line),
        8);
    output_value(&val, buf, 1, (unsigned long)(buf-*bufp), bc, 1, d);
    buf += 1;
    yasm_value_delete(&val);

    /* Offset value */
    switch (code->opcode) {
        case UWOP_PUSH_NONVOL:
        case UWOP_SET_FPREG:
        case UWOP_PUSH_MACHFRAME:
            /* just 1 node, no offset; write opcode and info and we're done */
            YASM_WRITE_8(buf, (code->info << 4) | (code->opcode & 0xF));
            *bufp = buf;
            return 0;
        case UWOP_ALLOC_SMALL:
            /* 1 node, but offset stored in info */
            size = 0; low = 8; high = 128; shift = 3; mask = 0x7;
            break;
        case UWOP_ALLOC_LARGE:
            if (code->info == 0) {
                size = 2; low = 136; high = 8*64*1024-8; shift = 3;
            } else {
                size = 4; low = high = 0; shift = 0;
            }
            mask = 0x7;
            break;
        case UWOP_SAVE_NONVOL:
            size = 2; low = 0; high = 8*64*1024-8; shift = 3; mask = 0x7;
            break;
        case UWOP_SAVE_XMM128:
            size = 2; low = 0; high = 16*64*1024-16; shift = 4; mask = 0xF;
            break;
        case UWOP_SAVE_NONVOL_FAR:
            size = 4; low = high = 0; shift = 0; mask = 0x7;
            break;
        case UWOP_SAVE_XMM128_FAR:
            size = 4; low = high = 0; shift = 0; mask = 0xF;
            break;
        default:
            yasm_internal_error(N_("unrecognied unwind opcode"));
            /*@unreached@*/
            return 1;
    }

    /* Check for overflow */
    intn = yasm_value_get_intnum(&code->off, bc, 1);
    if (!intn) {
        yasm_error_set(YASM_ERROR_VALUE, N_("offset expression too complex"));
        return 1;
    }
    intv = yasm_intnum_get_int(intn);
    if (size != 4 && (intv < low || intv > high)) {
        yasm_error_set(YASM_ERROR_VALUE,
            N_("offset of %ld bytes, must be between %ld and %ld"),
            intv, low, high);
        return 1;
    }
    if ((intv & mask) != 0) {
        yasm_error_set(YASM_ERROR_VALUE,
                       N_("offset of %ld is not a multiple of %ld"),
                       intv, mask+1);
        return 1;
    }

    /* Stored value in info instead of extra code space */
    if (size == 0)
        code->info = (yasm_intnum_get_uint(intn) >> shift)-1;

    /* Opcode and info */
    YASM_WRITE_8(buf, (code->info << 4) | (code->opcode & 0xF));

    if (size != 0) {
        yasm_intnum_get_sized(intn, buf, size, size*8, -shift, 0, 1);
        buf += size;
    }

    yasm_intnum_destroy(intn);

    *bufp = buf;
    return 0;
}
