main.c

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

C
1,025
字号
static void bssSection( section_ptr sec, orl_sec_size size, unsigned pass )
{
    hash_data *                 data_ptr;
    label_list                  sec_label_list;
    label_entry                 l_entry;

    if( pass == 1 )
        return;

    /* Obtain the Symbol Table */
    data_ptr = HashTableQuery( HandleToLabelListTable, (hash_value) sec->shnd );
    if( data_ptr ) {
        sec_label_list = (label_list) *data_ptr;
    } else {
        sec_label_list = NULL;
    }
    l_entry = sec_label_list->first;

    PrintHeader( sec );

    while( l_entry != NULL ){
        switch( l_entry->type ){
        case LTYP_UNNAMED:
            PrintLinePrefix( NULL, l_entry->offset, size, 1, 0 );
            BufferStore("%c$%d:\n", LabelChar, l_entry->label.number );
            break;
        case LTYP_SECTION:
            if( strcmp( l_entry->label.name, sec->name ) == 0 )
                break;
            /* Fall through */
        case LTYP_NAMED:
            PrintLinePrefix( NULL, l_entry->offset, size, 1, 0 );
            BufferStore("%s:\n", l_entry->label.name );
            break;
        }
        BufferPrint();
        l_entry = l_entry->next;
    }
    BufferConcatNL();
    BufferMsg( BSS_SIZE );
    BufferStore(" %d ", size );
    BufferMsg( BYTES );
    BufferConcatNL();
    BufferConcatNL();
    BufferPrint();
}

static return_val DealWithSection( section_ptr sec, unsigned pass )
{
    orl_sec_size        size;
    char *              contents;
    return_val          error = OKAY;

    switch( sec->type ) {
    case SECTION_TYPE_TEXT:
        ORLSecGetContents( sec->shnd, &contents );
        size = ORLSecGetSize( sec->shnd );
        error = disassembleSection( sec, contents, size, pass );
        break;
    case SECTION_TYPE_DRECTVE:
    case SECTION_TYPE_DATA:
        ORLSecGetContents( sec->shnd, &contents );
        size = ORLSecGetSize( sec->shnd );
        if( DFormat & DFF_ASM ) {
            error = DumpASMSection( sec, contents, size, pass );
        } else {
            dumpSection( sec, contents, size, pass );
        }
        break;
    case SECTION_TYPE_BSS:
        size = ORLSecGetSize( sec->shnd );
        if( DFormat & DFF_ASM ) {
            error = BssASMSection( sec, size, pass );
        } else {
            bssSection( sec, size, pass );
        }
        break;
    case SECTION_TYPE_PDATA:
        ORLSecGetContents( sec->shnd, &contents );
        size = ORLSecGetSize( sec->shnd );
        error = DumpPDataSection( sec, contents, size, pass );
        break;
    }
    return( error );
}

static void numberUnnamedLabels( label_entry l_entry )
{
    static label_number labNum = 1;

    while( l_entry ) {
        if( l_entry->type == LTYP_UNNAMED ) {
            l_entry->label.number = labNum;
            labNum++;
        }
        l_entry = l_entry->next;
    }
}

static hash_table emitGlobls( void )
{
    section_ptr         sec;
    hash_data *         data_ptr;
    label_list          sec_label_list;
    label_entry         l_entry;
    char                *globl;
    hash_table          hash;
    char                *name;

    hash = HashTableCreate( TMP_TABLE_SIZE, HASH_STRING,
                            (hash_table_comparison_func) strcmp );
    if( !hash ) return( NULL );

    if( IsMasmOutput() ) {
        globl = "\t\tPUBLIC\t";
    } else {
        globl = ".globl\t\t";
    }

    for( sec = Sections.first; sec != NULL; sec = sec->next ) {
        data_ptr = HashTableQuery( HandleToLabelListTable, (hash_value) sec->shnd );
        if( data_ptr != NULL ) {
            sec_label_list = (label_list) *data_ptr;
            if( sec_label_list != NULL ) {
                for( l_entry = sec_label_list->first; l_entry != NULL;
                                                l_entry = l_entry->next ) {
                    name = l_entry->label.name;
                    if( ( l_entry->binding != ORL_SYM_BINDING_LOCAL ) &&
                        (l_entry->type == LTYP_NAMED) &&
                        strcmp( name, sec->name ) ) {
                        BufferConcat( globl );
                        BufferConcat( name );
                        BufferConcatNL();
                        BufferPrint();
                        HashTableInsert(hash,(hash_value)name,(hash_data)name);
                    }
                }
            }
        }
    }
    return( hash );
}

static void emitExtrns( hash_table hash )
{
    section_ptr         sec;
    hash_data           *dp;
    ref_list            r_list;
    ref_entry           r_entry;
    label_entry         l_entry;
    label_list          l_list;
    char                *extrn;
    char                *name;

    if( !hash ) {
        hash = HashTableCreate( TMP_TABLE_SIZE, HASH_STRING,
                                (hash_table_comparison_func) strcmp );
    }

    if( IsMasmOutput() ) {
        extrn = "\t\tEXTRN\t%s:BYTE";
    } else {
        extrn = ".extern\t\t%s";
    }

    for( sec = Sections.first; sec != NULL; sec = sec->next ) {
        dp = HashTableQuery( HandleToRefListTable, (hash_value) sec->shnd );
        if( dp && *dp ) {
            r_list = (ref_list) *dp;
            for( r_entry = r_list->first; r_entry; r_entry = r_entry->next ) {
                if( !r_entry->label->shnd ) {
                    name = r_entry->label->label.name;
                    if( !name ) continue;
                    dp = HashTableQuery( hash, (hash_value)name );
                    if( !dp ) {
                        HashTableInsert( hash, (hash_value)name,
                                         (hash_data)name );
                        if( ( r_entry->label->type != LTYP_GROUP ) &&
                          (r_entry->label->binding != ORL_SYM_BINDING_LOCAL) ) {
                            BufferStore( extrn, name );
                            BufferConcatNL();
                            BufferPrint();
                        }
                    }
                }
            }
        }
    }

    /* emit all externs not used but defined
     */
    dp = HashTableQuery( HandleToLabelListTable, (hash_value) NULL );
    if( dp ) {
        l_list = (label_list) *dp;
        if( l_list ) {
            for( l_entry = l_list->first; l_entry; l_entry = l_entry->next ) {
                name = l_entry->label.name;
                dp = HashTableQuery( hash, (hash_value)name );
                if( !dp ) {
                    HashTableInsert( hash, (hash_value)name, (hash_data)name );
                    if( ( l_entry->binding != ORL_SYM_BINDING_LOCAL ) &&
                        ( l_entry->type == LTYP_EXTERNAL_NAMED ) ) {
                        BufferStore( extrn, name );
                        BufferConcatNL();
                        BufferPrint();
                    }
                }
            }
        }
    }
    HashTableFree( hash );
}

static orl_return       groupWalker( orl_group_handle grp )
{
    char                *name;
    orl_table_index     size;
    orl_table_index     idx;

    name = ORLGroupName( grp );
    size = ORLGroupSize( grp );
    if( !name || ( size < 1 ) ) return( ORL_OKAY );
    DumpASMGroupName( name, ( DFormat & DFF_ASM ) != 0 );
    for( idx = 0; idx < size; idx++ ) {
        name = ORLGroupMember( grp, idx );
        if( name ) {
            DumpASMGroupMember( name );
        }
    }
    DumpASMGroupFini();

    return( ORL_OKAY );
}

void UseFlatModel( void )
{
    if( !flatModel && ( GetMachineType() == ORL_MACHINE_TYPE_I386 ) ) {
        flatModel = 1;
    }
}

static void doPrologue( void )
{
    int         masm;

    masm = IsMasmOutput();

    /* output the listing */
    if( masm ) {
        if( DFormat & DFF_ASM ) {
            BufferConcat( ".387" );
            BufferConcatNL();
            BufferPrint();
            if( GetMachineType() == ORL_MACHINE_TYPE_I386 ) {
                BufferConcat( ".386p" );
                BufferConcatNL();
                BufferPrint();
                if( flatModel ) {
                    BufferConcat( ".model flat" );
                    BufferConcatNL();
                    BufferPrint();
                }
            }
        } else if( SourceFileInObject ) {
            BufferStore( "Module: %s", SourceFileInObject );
            BufferConcatNL();
            BufferPrint();
        }
    }

    if( DFormat & DFF_ASM ) {
        emitExtrns( emitGlobls() );
    }

    if( masm ) {
        ORLGroupsScan( ObjFileHnd, groupWalker );
        if( !( DFormat & DFF_ASM ) ) {
            BufferConcatNL();
        }
    }
}

static void    doEpilogue( void )
{
    if( IsMasmOutput() ) {
        if( DFormat & DFF_ASM ) {
            BufferConcat( "\t\tEND" );
            BufferConcatNL();
            BufferPrint();
        }
    }
}

#if !defined( __WATCOMC__ )
char    **_argv;
#endif

int main( int argc, char *argv[] )
{
    section_ptr         sec;
    return_val          error;
    hash_data *         data_ptr;
    label_list          sec_label_list;

#if !defined( __WATCOMC__ )
    _argv = argv;
#endif

    Init();
    /* build the symbol table */
    for( sec = Sections.first; sec != NULL; sec = sec->next ) {
        error = DealWithSection( sec, 1 );
        if( error != OKAY ) {
            return( EXIT_FAILURE );
        }
    }
    /* number all the anonymous labels */
    for( sec = Sections.first; sec != NULL; sec = sec->next ) {
        data_ptr = HashTableQuery( HandleToLabelListTable, (hash_value) sec->shnd );
        if( data_ptr != NULL ) {
            sec_label_list = (label_list) *data_ptr;
            if( sec_label_list != NULL ) {
                numberUnnamedLabels( sec_label_list->first );
            }
        }
    }
    doPrologue();
    for( sec = Sections.first; sec != NULL; sec = sec->next ) {
        error = DealWithSection( sec, 2 );
        if( error != OKAY ) {
            return( EXIT_FAILURE );
        }
    }
    doEpilogue();
    if( Options & PRINT_PUBLICS ) {
        PrintPublics();
    }
    Fini();
    return( EXIT_SUCCESS );
}

⌨️ 快捷键说明

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