main.c

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

C
1,025
字号
            BufferStore( "Segment: %s at %08X %s %08X bytes", name, frame << 4,
                         getUse( flags ), size );
        }
    }
    BufferConcatNL();
    BufferPrint();
}


void PrintAssumeHeader( section_ptr sec )
{
    orl_group_handle    grp;
    char                *name;

    if( IsMasmOutput() && ( DFormat & DFF_ASM ) ) {
        grp = ORLSecGetGroup( sec->shnd );
        if( grp ) {
            name = ORLGroupName( grp );
        } else {
            name = sec->name;
        }
        BufferStore( "\t\tASSUME CS:%s, DS:DGROUP, SS:DGROUP", name );
        BufferConcatNL();
        BufferPrint();
    }
}


void PrintHeader( section_ptr sec )
{
    if( IsMasmOutput() ) {
        printMasmHeader( sec );
    } else {
        printUnixHeader( sec );
    }
}


void PrintTail( section_ptr sec )
{
    char        *name;

    if( IsMasmOutput() && ( DFormat & DFF_ASM ) ) {
        name = sec->name;
        if( !name ) {
            name = "";
        }
        BufferQuoteName( name );
        BufferStore( "\t\tENDS", name );
        BufferConcatNL();
        BufferPrint();
    }
}


static unsigned DoPrintLinePrefix( void *data, orl_sec_offset off, orl_sec_offset total,
                        unsigned item_size, unsigned len )
{
    unsigned    amount;
    unsigned    done;
    union {
        unsigned_8      u8;
        unsigned_16     u16;
        unsigned_32     u32;
    }           *p;


    if( total >= 0x10000 ) {
        amount = BufferStore( "%08X   ", off );
    } else {
        amount = BufferStore( "%04X   ", off );
    }
    for( done = 0; done < len; done += item_size ) {
        if( off >= total ) {
            item_size = 1;
            BufferConcat( "   " );
        } else {
            p = (void *)((unsigned_8 *)data + off);
            switch( item_size ) {
            case 1:
                amount += BufferStore( " %02X", p->u8 );
                break;
            case 2:
                amount += BufferStore( " %04X", p->u16 );
                break;
            case 4:
                amount += BufferStore( " %08X", p->u32 );
                break;
            }
        }
        off += item_size;
    }
    return( amount );
}

#define PREFIX_SIZE     30

void PrintLinePrefix( void *data, orl_sec_offset off, orl_sec_offset total,
                        unsigned item_size, unsigned len )
{
    unsigned amount;

    amount = DoPrintLinePrefix( data, off, total, item_size, len );
    if( amount >= PREFIX_SIZE ) {
        BufferStore( "\n" );
        amount = 0;
    }
    BufferStore( "%*s ", (PREFIX_SIZE - 1) - amount, "" );
}


static return_val disassembleSection( section_ptr sec, char * contents,
                orl_sec_size size, unsigned pass )
{
    hash_data *                 data_ptr;
    label_list                  sec_label_list;
    ref_list                    sec_ref_list;
    return_val                  error;
    externs                     sec_externs;
    num_errors                  disassembly_errors;

    data_ptr = HashTableQuery( HandleToLabelListTable, (hash_value) sec->shnd );
    if( data_ptr ) {
        sec_label_list = (label_list) *data_ptr;
    } else {
        sec_label_list = NULL;
    }
    data_ptr = HashTableQuery( HandleToRefListTable, (hash_value) sec->shnd );
    if( data_ptr ) {
        sec_ref_list = (ref_list) *data_ptr;
    } else {
        sec_ref_list = NULL;
    }
    if( pass == 1 ) {
        error = DoPass1( sec->shnd, contents, size, sec_ref_list, sec->scan );
        if( error != OKAY ) {
            PrintErrorMsg( error, WHERE_PASS_ONE );
        }
    } else {
        error = OKAY;
        disassembly_errors = DoPass2( sec, contents, size, sec_label_list, sec_ref_list );
        if( !(DFormat & DFF_ASM) ) {
            if( disassembly_errors > 0 ) {
                BufferStore( "%d ", disassembly_errors );
                BufferMsg( DIS_ERRORS );
            } else {
                BufferMsg( NO_DIS_ERRORS );
            }
                 BufferConcatNL();
                 BufferConcatNL();
            BufferPrint();
            if( Options & PRINT_EXTERNS ) {
                sec_externs = CreateExterns( sec_ref_list );
                if( sec_externs ) {
                    PrintExterns( sec_externs );
                    FreeExterns( sec_externs );
                } else {
                    error = OUT_OF_MEMORY;
                    PrintErrorMsg( error, WHERE_GEN_EXTERNS );
                }
            }
        }
    }
    return( error );
}

static label_entry dumpLabel( label_entry l_entry, section_ptr sec,
                              orl_sec_offset loop, orl_sec_offset end )
{
    while( l_entry != NULL
        && ( l_entry->type == LTYP_ABSOLUTE || l_entry->offset <= loop ) ) {
        switch( l_entry->type ){
        case LTYP_ABSOLUTE:
            break;
        case LTYP_UNNAMED:
            PrintLinePrefix( NULL, loop, end, 1, 0 );
            if( loop != l_entry->offset ) {
                BufferStore("%c$%d equ $-%d", LabelChar, l_entry->label.number, loop - l_entry->offset );
            } else {
                BufferStore("%c$%d:", LabelChar, l_entry->label.number );
            }
            BufferConcatNL();
            break;
        case LTYP_SECTION:
        case LTYP_NAMED:
            if( strcmp( l_entry->label.name, sec->name ) == 0 )
                break;
        default:
            PrintLinePrefix( NULL, loop, end, 1, 0 );
            if( loop != l_entry->offset ) {
                BufferStore("%s equ $-%d", l_entry->label.name, loop - l_entry->offset  );
            } else {
                BufferStore("%s:", l_entry->label.name );
            }
            BufferConcatNL();
            break;
        }
        l_entry = l_entry->next;
    }
    return( l_entry );
}

static orl_sec_offset checkForDupLines( char *contents, orl_sec_offset loop,
                                        orl_sec_size size, label_entry l_entry,
                                        ref_entry r_entry )
{
    char                        *cmp;
    orl_sec_offset              d;
    unsigned int                lines;

    cmp = &contents[loop - 16];
    if( l_entry && ( l_entry->offset < size ) ) size = l_entry->offset;
    if( r_entry && ( r_entry->offset < size ) ) size = r_entry->offset;
    if( ( size - loop ) < ( 16 * MIN_DUP_LINES ) ) return( 0 );

    for( d = loop; d < ( size - 16 ); d += 16 ) {
        if( memcmp( cmp, &contents[d], 16 ) ) break;
    }
    d -= loop;
    lines = d / 16;
    if( lines < MIN_DUP_LINES ) return( 0 );
    BufferConcatNL();
    BufferStore( "\t--- Above line repeats %d times ---", lines );
    return( d );
}

void DumpDataFromSection( char *contents, orl_sec_offset start,
                                 orl_sec_offset end, label_entry *labent,
                                 ref_entry *refent, section_ptr sec )
{
    orl_sec_offset              loop;
    unsigned                    loop2;
    unsigned                    amount;
    label_entry                 l_entry;
    ref_entry                   r_entry;

    l_entry = *labent;
    r_entry = *refent;

    for( loop = start; loop < end; ){
        /* Print a label if required */
        l_entry = dumpLabel( l_entry, sec, loop, end );

        if( l_entry != NULL ) {
            amount = l_entry->offset - loop;
            if( amount > 16 ) amount = 16;
        } else {
            amount = 16;
        }
        if( (loop + amount) > end ) amount = end - loop;
        /* Skip over pair relocs */
        while( r_entry && (r_entry->type == ORL_RELOC_TYPE_PAIR ||
                        r_entry->offset < loop) ) {
            r_entry = r_entry->next;
        }
        if( r_entry && r_entry->offset < loop + amount ) {
            if( r_entry->offset == loop ) {
                amount = RelocSize( r_entry );
            } else {
                amount = r_entry->offset - loop;
            }
        }

        /* This is a bit fake.  We want to print a full 16 columns,
           but we only want the amount of data specified, up to 16. */
        DoPrintLinePrefix( contents, loop, loop + amount, 1, 16 );
        BufferConcat( " " );
        if( r_entry && r_entry->offset == loop ) {
            HandleRefInData( r_entry, &(contents[loop]), TRUE );
            loop += amount;
        } else {
            for( loop2 = 0; loop2 < amount; loop2++, loop++ ) {
                if( contents[loop] >= ' ' && contents[loop] <= '~' ) {
                    BufferStore( "%c", contents[loop] );
                } else {
                    BufferConcat( "." );
                }
            }

            // We don't want to display a lot of duplicate lines
            // So we check this here.  We only do this is we have a
            // full 16 bytes displayed per line.
            if( amount == 16 ) {
                loop += checkForDupLines( contents, loop, end, l_entry,
                                          r_entry );
            }
        }
        BufferConcatNL();
        BufferPrint();
    }

    *labent = l_entry;
    *refent = r_entry;
}

static void dumpSection( section_ptr sec, char * contents, orl_sec_size size,
                        unsigned pass )
{
    hash_data *                 data_ptr;
    label_list                  sec_label_list;
    label_entry                 l_entry;
    ref_list                    sec_ref_list;
    ref_entry                   r_entry;

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

    /* Obtain the reloc table */
    data_ptr = HashTableQuery( HandleToRefListTable, (hash_value) sec->shnd );
    if( data_ptr ) {
        sec_ref_list = (ref_list) *data_ptr;
        if( sec_ref_list ) {
            r_entry = sec_ref_list->first;
        }
    } else {
        r_entry = NULL;
    }

    if( pass == 1 ) {
        DoPass1Relocs( contents, r_entry, 0, size );
        return;
    }

    PrintHeader( sec );

    DumpDataFromSection( contents, 0, size, &l_entry, &r_entry, sec );

    if( size > 0 ) {
        l_entry = dumpLabel( l_entry, sec, size, size );
    }

    BufferConcatNL();
    BufferPrint();
}

⌨️ 快捷键说明

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