asmsym.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 707 行 · 第 1/2 页

C
707
字号
        if( fixup == NULL )
            break;
        FixupHead = fixup->next;
        AsmFree( fixup );
    }
#endif
}

#if defined( _STANDALONE_ )

static int compare_fn( const void *p1, const void *p2 )
/*****************************************************/
{
    struct asm_sym * const  *sym1 = p1;
    struct asm_sym * const  *sym2 = p2;

    return( strcmp( (*sym1)->name, (*sym2)->name ) );
}

static struct asm_sym **SortAsmSyms( void )
/*****************************************/
{
    struct asm_sym      **syms;
    struct asm_sym      *sym;
    unsigned            i, j;

    syms = AsmAlloc( AsmSymCount * sizeof( struct asm_sym * ) );
    if( syms ) {
        /* copy symbols to table */
        for( i = j = 0; i < HASH_TABLE_SIZE; i++ ) {
            struct asm_sym  *next;

            next = sym_table[i];
            for( ;; ) {
                sym = next;
                if( sym == NULL )
                    break;
                next = sym->next;
                syms[j++] = sym;
            }
        }
        /* sort 'em */
        qsort( syms, AsmSymCount, sizeof( struct asm_sym * ), compare_fn );
    }
    return( syms );
}

const char *get_seg_align( seg_info *seg )
/****************************************/
{
    switch( seg->segrec->d.segdef.align ) {
    case ALIGN_ABS:
    case ALIGN_BYTE:
        return( "Byte " );
    case ALIGN_WORD:
        return( "Word " );
    case ALIGN_DWORD:
        return( "DWord" );
    case ALIGN_PARA:
        return( "Para " );
    case ALIGN_PAGE:
        return( "Page " );
    case ALIGN_4KPAGE:
        return( "4K   " );
    default:
        return( "?    " );
    }
}

static const char *get_seg_combine( seg_info *seg )
/*************************************************/
{
    switch( seg->segrec->d.segdef.combine ) {
    case COMB_INVALID:
        return( "Private " );
    case COMB_STACK:
        return( "Stack   " );
    case COMB_ADDOFF:
        return( "Public  " );
    default:
        return( "?       " );
    }
}

static void log_segment( struct asm_sym *sym )
/********************************************/
{
    if( sym->state == SYM_SEG ) {
        dir_node    *dir = (dir_node *)sym;
        seg_info    *seg = dir->e.seginfo;

        LstMsg( "%s %s        ", sym->name, dots + strlen( sym->name ) + 1 );
        if( seg->segrec->d.segdef.use_32 ) {
            LstMsg( "32 Bit   %08lX ", seg->current_loc );
        } else {
            LstMsg( "16 Bit   %04lX     ", seg->current_loc );
        }
        LstMsg( "%s   %s", get_seg_align( seg ), get_seg_combine( seg ) );
        LstMsg( "'%s'\n", GetLname( seg->segrec->d.segdef.class_name_idx ) );
    } else if( sym->state == SYM_GRP ) {
        LstMsg( "%s %s        ", sym->name, dots + strlen( sym->name ) + 1 );
        LstMsg( "GROUP\n" );
    }
}

static const char *get_sym_type( struct asm_sym *sym )
/****************************************************/
{
    switch( sym->mem_type ) {
    case MT_BYTE:
        return( "Byte   " );
    case MT_WORD:
        return( "Word   " );
    case MT_DWORD:
        return( "DWord  " );
    case MT_QWORD:
        return( "QWord  " );
    case MT_FWORD:
        return( "FWord  " );
    case MT_NEAR:
        return( "L Near " );
    case MT_FAR:
        return( "L Far  " );
    default:
        return( "?      " );
    }
}

static void log_symbol( struct asm_sym *sym )
/*******************************************/
{
    if( sym->state == SYM_CONST ) {
        dir_node    *dir = (dir_node *)sym;
        const_info  *cst = dir->e.constinfo;

        LstMsg( "%s %s        ", sym->name, dots + strlen( sym->name ) + 1 );
        if( cst->count && cst->data[0].token != T_NUM ) {
            LstMsg( "Text     %s\n", cst->data[0].string_ptr );
        } else {
            LstMsg( "Number   %04Xh\n", cst->count ? cst->data[0].value : 0 );
        }
    } else if( sym->state == SYM_INTERNAL && !IS_SYM_COUNTER( sym->name ) ) {
        LstMsg( "%s %s        ", sym->name, dots + strlen( sym->name ) + 1 );
        LstMsg( "%s  %04X     ", get_sym_type( sym ), sym->offset );
        if( sym->segment ) {
            LstMsg( "%s", sym->segment->name );
        } else {
            LstMsg( "No Seg" );
        }
        if( sym->public ) {
            LstMsg( "\tPublic" );
        }
        LstMsg( "\n" );
    } else if( sym->state == SYM_EXTERNAL ) {
        LstMsg( "%s %s        ", sym->name, dots + strlen( sym->name ) + 1 );
        LstMsg( "%s  %04X     ", get_sym_type( sym ), sym->offset );
        LstMsg( "External" );
        LstMsg( "\n" );
    }
}

void WriteListing( void )
/***********************/
{
    struct asm_sym  **syms;
    unsigned        i;

    if( AsmFiles.file[LST] == NULL ) {
        return; // no point going through the motions if lst file isn't open
    }
    syms = SortAsmSyms();
    if( syms ) {
        /* first write out the segments */
        LstMsg( "\n\nSegments and Groups:\n\n" );
        LstMsg( "                N a m e                 Size" );
        LstMsg( "     Length   Align   Combine Class\n\n" );
        for( i = 0; i < AsmSymCount; ++i ) {
            log_segment( syms[i] );
        }
        LstMsg( "\n" );

        /* next write out procedures and stuff */

        /* next write out symbols */
        LstMsg( "\n\nSymbols:\n\n" );
        LstMsg( "                N a m e                 Type" );
        LstMsg( "     Value    Attr\n\n" );
        for( i = 0; i < AsmSymCount; ++i ) {
            log_symbol( syms[i] );
        }
        LstMsg( "\n" );

        /* free the sorted symbols */
        AsmFree( syms );
    }
}

#if defined( DEBUG_OUT )

static void DumpSymbol( struct asm_sym *sym )
/*******************************************/
{
    dir_node    *dir;
    char        *type;
    char        value[512];
    char        *langtype;
    char        *public;

    dir = (dir_node *)sym;
    *value = 0;
    switch( sym->state ) {
    case SYM_SEG:
        type = "SEGMENT";
//        dir->e.seginfo->lname_idx = 0;
//        dir->e.seginfo->grpidx = 0;
//        dir->e.seginfo->segrec = NULL;
        break;
    case SYM_GRP:
        type = "GROUP";
//        dir->e.grpinfo = AsmAlloc( sizeof( grp_info ) );
//        dir->e.grpinfo->idx = grpdefidx;
//        dir->e.grpinfo->seglist = NULL;
//        dir->e.grpinfo->numseg = 0;
//        dir->e.grpinfo->lname_idx = 0;
        break;
    case SYM_EXTERNAL:
        type = "EXTERNAL";
//        dir->e.extinfo = AsmAlloc( sizeof( ext_info ) );
//        dir->e.extinfo->idx = ++extdefidx;
//        dir->e.extinfo->use32 = Use32;
//        dir->e.extinfo->comm = 0;
        break;
//    case TAB_COMM:
//        sym->state = SYM_EXTERNAL;
//        dir->e.comminfo = AsmAlloc( sizeof( comm_info ) );
//        dir->e.comminfo->idx = ++extdefidx;
//        dir->e.comminfo->use32 = Use32;
//        dir->e.comminfo->comm = 1;
//        break;
    case SYM_CONST:
        type = "CONSTANT";
//        dir->e.constinfo = AsmAlloc( sizeof( const_info ) );
//        dir->e.constinfo->data = NULL;
//        dir->e.constinfo->count = 0;
        break;
    case SYM_PROC:
        type = "PROCEDURE";
//        dir->e.procinfo = AsmAlloc( sizeof( proc_info ) );
//        dir->e.procinfo->regslist = NULL;
//        dir->e.procinfo->paralist = NULL;
//        dir->e.procinfo->locallist = NULL;
        break;
    case SYM_MACRO:
        type = "MACRO";
//        dir->e.macroinfo = AsmAlloc( sizeof( macro_info ) );
//        dir->e.macroinfo->parmlist = NULL;
//        dir->e.macroinfo->data = NULL;
//        dir->e.macroinfo->filename = NULL;
        break;
    case SYM_CLASS_LNAME:
        type = "CLASS";
        break;
    case SYM_LNAME:
        type = "LNAME";
//        dir->e.lnameinfo = AsmAlloc( sizeof( lname_info ) );
//        dir->e.lnameinfo->idx = ++LnamesIdx;
        break;
//    case TAB_PUB:
//        sym->public = TRUE;
//        return;
//    case TAB_GLOBAL:
//        break;
    case SYM_STRUCT:
        type = "STRUCTURE";
//        dir->e.structinfo = AsmAlloc( sizeof( struct_info ) );
//        dir->e.structinfo->size = 0;
//        dir->e.structinfo->alignment = 0;
//        dir->e.structinfo->head = NULL;
//        dir->e.structinfo->tail = NULL;
        break;
    case SYM_STRUCT_FIELD:
        type = "STRUCTURE FIELD";
        break;
    case SYM_LIB:
        type = "LIBRARY";
        break;
    case SYM_UNDEFINED:
        type = "UNDEFINED";
        break;
    case SYM_INTERNAL:
        type = "INTERNAL";
        break;
    default:
        type = "UNKNOWN";
        break;
    }
    if( sym->public ) {
        public = "PUBLIC ";
    } else {
        public = "";
    }
    switch( sym->langtype ) {
    case LANG_C:
        langtype = "C";
        break;
    case LANG_BASIC:
        langtype = "BASIC";
        break;
    case LANG_FORTRAN:
        langtype = "FORTRAN";
        break;
    case LANG_PASCAL:
        langtype = "PASCAL";
        break;
    case LANG_WATCOM_C:
        langtype = "WATCOM_C";
        break;
    case LANG_STDCALL:
        langtype = "STDCALL";
        break;
    case LANG_SYSCALL:
        langtype = "SYSCALL";
        break;
    default:
        langtype = "";
        break;
    }
    DoDebugMsg( "%-30s\t%s\t%s%s\t%8X\t%s\n", sym->name, type, public, langtype, sym->offset, value );
}

void DumpASym( void )
/*******************/
{
    struct asm_sym      *sym;
    unsigned            i;

    LstMsg( "\n" );
    for( i = 0; i < HASH_TABLE_SIZE; i++ ) {
        struct asm_sym  *next;
        next = sym_table[i];
        for( ;; ) {
            sym = next;
            if( sym == NULL )
                break;
            next = sym->next;
            DumpSymbol( sym );
        }
    }
}
#endif

#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?