#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "libdis.h"
#include "ia32_insn.h"
#include "ia32_invariant.h"
#include "x86_operand_list.h"


#ifdef _MSC_VER
        #define snprintf        _snprintf
        #define inline          __inline
#endif

unsigned int x86_disasm( unsigned char *buf, unsigned int buf_len,
                uint32_t buf_rva, unsigned int offset,
                x86_insn_t *insn ){
        int len, size;
	unsigned char bytes[MAX_INSTRUCTION_SIZE];

        if ( ! buf || ! insn || ! buf_len ) {
                /* caller screwed up somehow */
                return 0;
        }


	/* ensure we are all NULLed up */
	memset( insn, 0, sizeof(x86_insn_t) );
        insn->addr = buf_rva + offset;
        insn->offset = offset;
	/* default to invalid insn */
	insn->type = insn_invalid;
	insn->group = insn_none;

        if ( offset >= buf_len ) {
                /* another caller screwup ;) */
                x86_report_error(report_disasm_bounds, (void*)(long)(buf_rva+offset));
                return 0;
        }

        len = buf_len - offset;

	/* copy enough bytes for disassembly into buffer : this
	 * helps prevent buffer overruns at the end of a file */
	memset( bytes, 0, MAX_INSTRUCTION_SIZE );
	memcpy( bytes, &buf[offset], (len < MAX_INSTRUCTION_SIZE) ? len : 
		MAX_INSTRUCTION_SIZE );

        /* actually do the disassembly */
	/* TODO: allow switching when more disassemblers are added */
        size = ia32_disasm_addr( bytes, len, insn);

        /* check and see if we had an invalid instruction */
        if (! size ) {
                x86_report_error(report_invalid_insn, (void*)(long)(buf_rva+offset));
                return 0;
        }

        /* check if we overran the end of the buffer */
        if ( size > len ) {
                x86_report_error( report_insn_bounds, (void*)(long)(buf_rva + offset));
		MAKE_INVALID( insn, bytes );
		return 0;
	}

        /* fill bytes field of insn */
        memcpy( insn->bytes, bytes, size );

        return size;
}

unsigned int x86_disasm_range( unsigned char *buf, uint32_t buf_rva,
                      unsigned int offset, unsigned int len,
                      DISASM_CALLBACK func, void *arg ) {
        x86_insn_t insn;
        unsigned int buf_len, size, count = 0, bytes = 0;

        /* buf_len is implied by the arguments */
        buf_len = len + offset;

        while ( bytes < len ) {
                size = x86_disasm( buf, buf_len, buf_rva, offset + bytes,
                                   &insn );
                if ( size ) {
                        /* invoke callback if it exists */
                        if ( func ) {
                                (*func)( &insn, arg );
                        }
                        bytes += size;
                        count ++;
                } else {
                        /* error */
                        bytes++;        /* try next byte */
                }

		x86_oplist_free( &insn );
        }

        return( count );
}

static inline int follow_insn_dest( x86_insn_t *insn ) {
        if ( insn->type == insn_jmp || insn->type == insn_jcc ||
             insn->type == insn_call || insn->type == insn_callcc ) {
                return(1);
        }
        return(0);
}

static inline int insn_doesnt_return( x86_insn_t *insn ) {
        return( (insn->type == insn_jmp || insn->type == insn_return) ? 1: 0 );
}

static int32_t internal_resolver( x86_op_t *op, x86_insn_t *insn ){
        int32_t next_addr = -1;
        if ( x86_optype_is_address(op->type) ) {
                next_addr = op->data.sdword;
        } else if ( op->type == op_relative_near ) {
		next_addr = insn->addr + insn->size + op->data.relative_near;
        } else if ( op->type == op_relative_far ) {
		next_addr = insn->addr + insn->size + op->data.relative_far;
        }
        return( next_addr );
}

unsigned int x86_disasm_forward( unsigned char *buf, unsigned int buf_len,
                        uint32_t buf_rva, unsigned int offset,
                        DISASM_CALLBACK func, void *arg,
                        DISASM_RESOLVER resolver, void *r_arg ){
        x86_insn_t insn;
        x86_op_t *op;
        int32_t next_addr;
        uint32_t next_offset;
        unsigned int size, count = 0, bytes = 0, cont = 1;

        while ( cont && bytes < buf_len ) {
                size = x86_disasm( buf, buf_len, buf_rva, offset + bytes,
                           &insn );

                if ( size ) {
                        /* invoke callback if it exists */
                        if ( func ) {
                                (*func)( &insn, arg );
                        }
                        bytes += size;
                        count ++;
                } else {
                        /* error */
                        bytes++;        /* try next byte */
                }

                if ( follow_insn_dest(&insn) ) {
                        op = x86_get_dest_operand( &insn );
                        next_addr = -1;

                        /* if caller supplied a resolver, use it to determine
                         * the address to disassemble */
                        if ( resolver ) {
                                next_addr = resolver(op, &insn, r_arg);
                        } else {
                                next_addr = internal_resolver(op, &insn);
                        }

                        if (next_addr != -1 ) {
                                next_offset = next_addr - buf_rva;
                                /* if offset is in this buffer... */
                                if ( (uint32_t)next_addr >= buf_rva &&
                                     next_offset < buf_len ) {
                                        /* go ahead and disassemble */
                                        count += x86_disasm_forward( buf,
                                                            buf_len,
                                                            buf_rva,
                                                            next_offset,
                                                            func, arg,
                                                            resolver, r_arg );
                                } else  {
                                        /* report unresolved address */
                                        x86_report_error( report_disasm_bounds,
                                                     (void*)(long)next_addr );
                                }
                        }
                } /* end follow_insn */

                if ( insn_doesnt_return(&insn) ) {
                        /* stop disassembling */
                        cont = 0;
                }

		x86_oplist_free( &insn );
        }
        return( count );
}

/* invariant instruction representation */
size_t x86_invariant_disasm( unsigned char *buf, int buf_len, 
		x86_invariant_t *inv ){
	if (! buf || ! buf_len || ! inv  ) {
		return(0);
	}

	return ia32_disasm_invariant(buf, buf_len, inv);
}
size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len ) {
	if (! buf || ! buf_len  ) {
		return(0);
	}

	return ia32_disasm_size(buf, buf_len);
}
