/*
 * Dumping of NE binaries
 *
 * Copyright 2002 Alexandre Julliard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "wine/winbase16.h"
#include "winedump.h"

struct ne_segtable_entry
{
    WORD seg_data_offset;   /* Sector offset of segment data	*/
    WORD seg_data_length;   /* Length of segment data		*/
    WORD seg_flags;         /* Flags associated with this segment	*/
    WORD min_alloc;         /* Minimum allocation size for this	*/
};

struct relocation_entry
{
    BYTE address_type;    /* Relocation address type */
    BYTE relocation_type; /* Relocation type */
    WORD offset;          /* Offset in segment to fixup */
    WORD target1;         /* Target specification */
    WORD target2;         /* Target specification */
};

#define NE_RADDR_LOWBYTE      0
#define NE_RADDR_SELECTOR     2
#define NE_RADDR_POINTER32    3
#define NE_RADDR_OFFSET16     5
#define NE_RADDR_POINTER48    11
#define NE_RADDR_OFFSET32     13

#define NE_RELTYPE_INTERNAL  0
#define NE_RELTYPE_ORDINAL   1
#define NE_RELTYPE_NAME      2
#define NE_RELTYPE_OSFIXUP   3
#define NE_RELFLAG_ADDITIVE  4

static inline WORD get_word( const BYTE *ptr )
{
    return ptr[0] | (ptr[1] << 8);
}

static void dump_ne_header( const IMAGE_OS2_HEADER *ne )
{
    printf( "File header:\n" );
    printf( "Linker version:      %d.%d\n", ne->ne_ver, ne->ne_rev );
    printf( "Entry table:         %x len %d\n", ne->ne_enttab, ne->ne_cbenttab );
    printf( "Checksum:            %08x\n", ne->ne_crc );
    printf( "Flags:               %04x\n", ne->ne_flags );
    printf( "Auto data segment:   %x\n", ne->ne_autodata );
    printf( "Heap size:           %d bytes\n", ne->ne_heap );
    printf( "Stack size:          %d bytes\n", ne->ne_stack );
    printf( "Stack pointer:       %x:%04x\n", SELECTOROF(ne->ne_sssp), OFFSETOF(ne->ne_sssp) );
    printf( "Entry point:         %x:%04x\n", SELECTOROF(ne->ne_csip), OFFSETOF(ne->ne_csip) );
    printf( "Number of segments:  %d\n", ne->ne_cseg );
    printf( "Number of modrefs:   %d\n", ne->ne_cmod );
    printf( "Segment table:       %x\n", ne->ne_segtab );
    printf( "Resource table:      %x\n", ne->ne_rsrctab );
    printf( "Resident name table: %x\n", ne->ne_restab );
    printf( "Module table:        %x\n", ne->ne_modtab );
    printf( "Import table:        %x\n", ne->ne_imptab );
    printf( "Non-resident table:  %x\n", ne->ne_nrestab );
    printf( "Exe type:            %x\n", ne->ne_exetyp );
    printf( "Other flags:         %x\n", ne->ne_flagsothers );
    printf( "Fast load area:      %x-%x\n", ne->ne_pretthunks << ne->ne_align,
            (ne->ne_pretthunks+ne->ne_psegrefbytes) << ne->ne_align );
    printf( "Expected version:    %d.%d\n", HIBYTE(ne->ne_expver), LOBYTE(ne->ne_expver) );
}

static void dump_ne_names( const IMAGE_OS2_HEADER *ne )
{
    const unsigned char *pstr = (const unsigned char *)ne + ne->ne_restab;

    printf( "\nResident name table:\n" );
    while (*pstr)
    {
        printf( " %4d: %*.*s\n", get_word(pstr + *pstr + 1), *pstr, *pstr, pstr + 1 );
        pstr += *pstr + 1 + sizeof(WORD);
    }
    if (ne->ne_cbnrestab)
    {
        printf( "\nNon-resident name table:\n" );
        pstr = PRD(ne->ne_nrestab, 0);
        while (*pstr)
        {
            printf( " %4d: %*.*s\n", get_word(pstr + *pstr + 1), *pstr, *pstr, pstr + 1 );
            pstr += *pstr + 1 + sizeof(WORD);
        }
    }
}

static const char *get_resource_type( WORD id )
{
    static char buffer[5];
    switch(id)
    {
    case NE_RSCTYPE_CURSOR: return "CURSOR";
    case NE_RSCTYPE_BITMAP: return "BITMAP";
    case NE_RSCTYPE_ICON: return "ICON";
    case NE_RSCTYPE_MENU: return "MENU";
    case NE_RSCTYPE_DIALOG: return "DIALOG";
    case NE_RSCTYPE_STRING: return "STRING";
    case NE_RSCTYPE_FONTDIR: return "FONTDIR";
    case NE_RSCTYPE_FONT: return "FONT";
    case NE_RSCTYPE_ACCELERATOR: return "ACCELERATOR";
    case NE_RSCTYPE_RCDATA: return "RCDATA";
    case NE_RSCTYPE_GROUP_CURSOR: return "CURSOR_GROUP";
    case NE_RSCTYPE_GROUP_ICON: return "ICON_GROUP";
    default:
        sprintf( buffer, "%04x", id );
        return buffer;
    }
}

static void dump_ne_resources( const IMAGE_OS2_HEADER *ne )
{
    const NE_NAMEINFO *name;
    const void *res_ptr = (const char *)ne + ne->ne_rsrctab;
    WORD size_shift = get_word(res_ptr);
    const NE_TYPEINFO *info = (const NE_TYPEINFO *)((const WORD *)res_ptr + 1);
    int count;

    printf( "\nResources:\n" );
    while (info->type_id != 0 && (const char *)info < (const char *)ne + ne->ne_restab)
    {
        name = (const NE_NAMEINFO *)(info + 1);
        for (count = info->count; count > 0; count--, name++)
        {
            if (name->id & 0x8000) printf( "  %d", (name->id & ~0x8000) );
            else printf( "  %.*s", *((const unsigned char *)res_ptr + name->id),
                         (const char *)res_ptr + name->id + 1 );
            if (info->type_id & 0x8000) printf( " %s", get_resource_type(info->type_id) );
            else printf( " %.*s", *((const unsigned char *)res_ptr + info->type_id),
                         (const char *)res_ptr + info->type_id + 1 );
            printf(" flags %04x length %04x\n", name->flags, name->length << size_shift);
            dump_data( PRD(name->offset << size_shift, name->length << size_shift),
                       name->length << size_shift, "    " );
        }
        info = (const NE_TYPEINFO *)name;
    }
}

static const char *get_export_name( const IMAGE_OS2_HEADER *ne, int ordinal )
{
    static char name[256];
    const BYTE *pstr;
    int pass = 0;

    /* search the resident names */

    while (pass < 2)
    {
        if (pass == 0)  /* resident names */
        {
            pstr = (const BYTE *)ne + ne->ne_restab;
            if (*pstr) pstr += *pstr + 1 + sizeof(WORD);  /* skip first entry (module name) */
        }
        else  /* non-resident names */
        {
            if (!ne->ne_cbnrestab) break;
            pstr = PRD(ne->ne_nrestab, 0);
        }
        while (*pstr)
        {
            WORD ord = get_word(pstr + *pstr + 1);
            if (ord == ordinal)
            {
                memcpy( name, pstr + 1, *pstr );
                name[*pstr] = 0;
                return name;
            }
            pstr += *pstr + 1 + sizeof(WORD);
        }
        pass++;
    }
    name[0] = 0;
    return name;
}

static void dump_ne_exports( const IMAGE_OS2_HEADER *ne )
{
    const BYTE *ptr = (const BYTE *)ne + ne->ne_enttab;
    const BYTE *end = ptr + ne->ne_cbenttab;
    int i, ordinal = 1;

    if (!ne->ne_cbenttab || !*ptr) return;

    printf( "\nExported entry points:\n" );

    while (ptr < end && *ptr)
    {
        BYTE count = *ptr++;
        BYTE type = *ptr++;
        switch(type)
        {
        case 0:  /* next bundle */
            ordinal += count;
            break;
        case 0xff:  /* movable */
            for (i = 0; i < count; i++)
            {
                printf( " %4d MOVABLE %d:%04x %s\n",
                        ordinal + i, ptr[3], get_word(ptr + 4),
                        get_export_name( ne, ordinal + i ) );
                ptr += 6;
            }
            ordinal += count;
            break;
        case 0xfe:  /* constant */
            for (i = 0; i < count; i++)
            {
                printf( " %4d CONST     %04x %s\n",
                        ordinal + i, get_word(ptr + 1),
                        get_export_name( ne, ordinal + i ) );
                ptr += 3;
            }
            ordinal += count;
            break;
        default:  /* fixed */
            for (i = 0; i < count; i++)
            {
                printf( " %4d FIXED   %d:%04x %s\n",
                        ordinal + i, type, get_word(ptr + 1),
                        get_export_name( ne, ordinal + i ) );
                ptr += 3;
            }
            ordinal += count;
            break;
        }
    }
}

static const char *get_reloc_name( BYTE addr_type, int additive )
{
    switch(addr_type & 0x7f)
    {
    case NE_RADDR_LOWBYTE:   return additive ? "byte add" : "byte";
    case NE_RADDR_OFFSET16:  return additive ? "off16 add" : "off16";
    case NE_RADDR_POINTER32: return additive ? "ptr32 add" : "ptr32";
    case NE_RADDR_SELECTOR:  return additive ? "sel add" : "sel";
    case NE_RADDR_POINTER48: return additive ? "ptr48 add" : "ptr48";
    case NE_RADDR_OFFSET32:  return additive ? "off32 add" : "off32";
    }
    return "???";
}

static const char *get_seg_flags( WORD flags )
{
    static char buffer[256];

    buffer[0] = 0;
#define ADD_FLAG(x) if (flags & NE_SEGFLAGS_##x) strcat( buffer, " " #x );
    ADD_FLAG(DATA);
    ADD_FLAG(ALLOCATED);
    ADD_FLAG(LOADED);
    ADD_FLAG(ITERATED);
    ADD_FLAG(MOVEABLE);
    ADD_FLAG(SHAREABLE);
    ADD_FLAG(PRELOAD);
    ADD_FLAG(EXECUTEONLY);
    ADD_FLAG(READONLY);
    ADD_FLAG(RELOC_DATA);
    ADD_FLAG(SELFLOAD);
    ADD_FLAG(DISCARDABLE);
    ADD_FLAG(32BIT);
#undef ADD_FLAG
    if (buffer[0])
    {
        buffer[0] = '(';
        strcat( buffer, ")" );
    }
    return buffer;
}

static void dump_relocations( const IMAGE_OS2_HEADER *ne, WORD count,
                              const struct relocation_entry *rep )
{
    const WORD *modref = (const WORD *)((const BYTE *)ne + ne->ne_modtab);
    const BYTE *mod_name, *func_name;
    WORD i;

    for (i = 0; i < count; i++, rep++)
    {
        int additive = rep->relocation_type & NE_RELFLAG_ADDITIVE;
        switch (rep->relocation_type & 3)
        {
        case NE_RELTYPE_ORDINAL:
            mod_name = (const BYTE *)ne + ne->ne_imptab + modref[rep->target1 - 1];
            printf( "%6d: %s = %*.*s.%d\n", i + 1, get_reloc_name( rep->address_type, additive ),
                    *mod_name, *mod_name, mod_name + 1, rep->target2 );
            break;
        case NE_RELTYPE_NAME:
            mod_name = (const BYTE *)ne + ne->ne_imptab + modref[rep->target1 - 1];
            func_name = (const BYTE *)ne + ne->ne_imptab + rep->target2;
            printf( "%6d: %s = %*.*s.%*.*s\n", i + 1, get_reloc_name( rep->address_type, additive ),
                    *mod_name, *mod_name, mod_name + 1,
                    *func_name, *func_name, func_name + 1 );
            break;
        case NE_RELTYPE_INTERNAL:
            if ((rep->target1 & 0xff) == 0xff)
            {
                /* the module itself */
                mod_name = (const BYTE *)ne + ne->ne_restab;
                printf( "%6d: %s = %*.*s.%d\n", i + 1, get_reloc_name( rep->address_type, additive ),
                        *mod_name, *mod_name, mod_name + 1, rep->target2 );
            }
            else
                printf( "%6d: %s = %d:%04x\n", i + 1, get_reloc_name( rep->address_type, additive ),
                        rep->target1, rep->target2 );
            break;
        case NE_RELTYPE_OSFIXUP:
            /* Relocation type 7:
             *
             *    These appear to be used as fixups for the Windows
             * floating point emulator.  Let's just ignore them and
             * try to use the hardware floating point.  Linux should
             * successfully emulate the coprocessor if it doesn't
             * exist.
             */
            printf( "%6d: %s = TYPE %d, OFFSET %04x, TARGET %04x %04x\n",
                    i + 1, get_reloc_name( rep->address_type, additive ),
                    rep->relocation_type, rep->offset,
                    rep->target1, rep->target2 );
            break;
        }
    }
}

static void dump_ne_segment( const IMAGE_OS2_HEADER *ne, int segnum )
{
    const struct ne_segtable_entry *table = (const struct ne_segtable_entry *)((const BYTE *)ne + ne->ne_segtab);
    const struct ne_segtable_entry *seg = table + segnum - 1;

    printf( "\nSegment %d:\n", segnum );
    printf( "  File offset: %08x\n", seg->seg_data_offset << ne->ne_align );
    printf( "  Length:      %08x\n", seg->seg_data_length );
    printf( "  Flags:       %08x %s\n", seg->seg_flags, get_seg_flags(seg->seg_flags) );
    printf( "  Alloc size:  %08x\n", seg->min_alloc );
    if (seg->seg_flags & NE_SEGFLAGS_RELOC_DATA)
    {
        const BYTE *ptr = PRD((seg->seg_data_offset << ne->ne_align) + seg->seg_data_length, 0);
        WORD count = get_word(ptr);
        ptr += sizeof(WORD);
        printf( "  Relocations:\n" );
        dump_relocations( ne, count, (const struct relocation_entry *)ptr );
    }
}

void ne_dump( void )
{
    unsigned int i;
    const IMAGE_DOS_HEADER *dos;
    const IMAGE_OS2_HEADER *ne;

    dos = PRD(0, sizeof(*dos));
    if (!dos) return;
    ne = PRD(dos->e_lfanew, sizeof(*ne));

    if (globals.do_dumpheader || !globals.dumpsect)
        dump_ne_header( ne );
    if (globals.do_dumpheader)
        dump_ne_names( ne );
    if (globals.dumpsect)
    {
        BOOL	all = strcmp(globals.dumpsect, "ALL") == 0;

        if (all || !strcmp(globals.dumpsect, "resource"))
            dump_ne_resources( ne );
        if (all || !strcmp(globals.dumpsect, "export"))
            dump_ne_exports( ne );
    }
    if (globals.do_dumpheader)
        for (i = 1; i <= ne->ne_cseg; i++) dump_ne_segment( ne, i );
}
