main.c

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

C
1,025
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Standalone disassembler mainline. 
*
****************************************************************************/


#include <stdlib.h>
#include <string.h>
#include "global.h"
#include "dis.h"
#include "main.h"
#include "init.h"
#include "fini.h"
#include "externs.h"
#include "pass1.h"
#include "pass2.h"
#include "publics.h"
#include "buffer.h"
#include "formasm.h"
#include "hashtabl.h"
#include "pdata.h"
#include "groups.h"
#include "demangle.h"


#define SMALL_STRING_LEN        8
#define TMP_TABLE_SIZE          29

wd_options      Options;
char            LabelChar = 0;
char            QuoteChar = '\\';

int             OutputDest;

char *          ObjFileName = NULL;
char *          ListFileName = NULL;

hash_table      HandleToSectionTable;
hash_table      HandleToLabelListTable;
hash_table      HandleToRefListTable;
hash_table      SymbolToLabelTable;
hash_table      NameRecognitionTable;
hash_table      SkipRefTable = NULL;

orl_handle              ORLHnd;
orl_file_handle         ObjFileHnd;
orl_sec_handle          debugHnd;
dis_handle              DHnd;
dis_format_flags        DFormat;

section_list_struct     Sections;
publics_struct          Publics;

static int              flatModel = 0;

extern char *           SourceFileInObject;

static void printUnixHeader( section_ptr sec )
{
    orl_sec_alignment   alignment;
    orl_sec_flags       flags;
    orl_sec_type        type;
    char                attributes[10];
    char *              ca;

    alignment = ORLSecGetAlignment( sec->shnd );
    type = ORLSecGetType( sec->shnd );
    flags = ORLSecGetFlags( sec->shnd );

    ca = attributes;
    if( !(Options & METAWARE_COMPATIBLE) ) {
        if( (flags & ORL_SEC_FLAG_EXEC) || sec->type == SECTION_TYPE_TEXT ) {
            *ca++ = 'c';
        }
        if( (flags & ORL_SEC_FLAG_INITIALIZED_DATA) || sec->type == SECTION_TYPE_DATA || sec->type == SECTION_TYPE_PDATA ) {
            *ca++ = 'd';
        }
        if( (flags & ORL_SEC_FLAG_UNINITIALIZED_DATA) || sec->type == SECTION_TYPE_BSS ) {
            *ca++ = 'u';
        }
        if( (type == ORL_SEC_TYPE_NOTE) || sec->type == SECTION_TYPE_DRECTVE ) {
            *ca++ = 'i';
        }
        if( flags & ORL_SEC_FLAG_DISCARDABLE ) {
            *ca++ = 'n';
        }
        if( flags & ORL_SEC_FLAG_REMOVE ) {
            *ca++ = 'R';
        }
        if( flags & ORL_SEC_FLAG_READ_PERMISSION ) {
            *ca++ = 'r';
        }
        if( flags & ORL_SEC_FLAG_WRITE_PERMISSION ) {
            *ca++ = 'w';
        }
        if( flags & ORL_SEC_FLAG_EXECUTE_PERMISSION ) {
            *ca++ = 'x';
        }
        if( flags & ORL_SEC_FLAG_SHARED ) {
            *ca++ = 's';
        }
        *ca++ = '0' + alignment;
        *ca = '\0';

        if( !( DFormat & DFF_ASM ) ){
            BufferConcat("\t\t\t\t");
        }
        BufferStore(".new_section %s, \"%s\"", sec->name, attributes );
    } else {
        if( !(flags & ORL_SEC_FLAG_REMOVE ) ) {
            *ca++ = 'a';
        }
        if( flags & ORL_SEC_FLAG_EXEC ) {
            *ca++ = 'x';
        }
        if( flags & ORL_SEC_FLAG_WRITE_PERMISSION ) {
            *ca++ = 'w';
        }
        *ca++ = '\0';
        if( !( DFormat & DFF_ASM ) ) {
            BufferConcat("\t\t\t\t");
        }
        BufferStore(".section %s, \"%s\"", sec->name, attributes );
        BufferConcatNL();
        if( !( DFormat & DFF_ASM ) ) {
            BufferConcat("\t\t\t\t");
        }
        BufferStore(".align %d", alignment );
    }

    BufferConcatNL();
    BufferPrint();
}

static char *getAlignment( orl_sec_alignment alignment )
{
    switch( alignment ) {
    case( 0 ):
        return( "BYTE" );
    case( 1 ):
        return( "WORD" );
    case( 2 ):
        return( "DWORD" );
    case( 4 ):
        return( "PARA" );
    case( 8 ):
    case( 12 ):
        return( "PAGE" );
    default:
        return( "" );
    }
}


static char *getUse( orl_sec_flags flags )
{
    if( flags & ORL_SEC_FLAG_USE_32 ) {
        return( "USE32" );
    } else {
        return( "USE16" );
    }
}


static char *getAlloc( orl_sec_combine combine )
{
    switch( combine & ORL_SEC_COMBINE_COMDAT_ALLOC_MASK ) {
    case( ORL_SEC_COMBINE_COMDAT_ALLOC_EXPLIC ):
        return( "EXPLICIT" );
    case( ORL_SEC_COMBINE_COMDAT_ALLOC_CODE16 ):
        return( "CODE16" );
    case( ORL_SEC_COMBINE_COMDAT_ALLOC_CODE32 ):
        return( "CODE32" );
    case( ORL_SEC_COMBINE_COMDAT_ALLOC_DATA16 ):
        return( "DATA16" );
    case( ORL_SEC_COMBINE_COMDAT_ALLOC_DATA32 ):
        return( "DATA32" );
    default:
        return( "" );
    }
}


static char *getPick( orl_sec_combine combine )
{
    switch( combine & ORL_SEC_COMBINE_COMDAT_PICK_MASK ) {
    case( ORL_SEC_COMBINE_COMDAT_PICK_NONE ):
        return( "NONE" );
    case( ORL_SEC_COMBINE_COMDAT_PICK_ANY ):
        return( "ANY" );
    case( ORL_SEC_COMBINE_COMDAT_PICK_SAME ):
        return( "SAME" );
    case( ORL_SEC_COMBINE_COMDAT_PICK_EXACT ):
        return( "EXACT" );
    default:
        return( "" );
    }
}


static char *getCombine( orl_sec_combine combine )
{
    switch( combine & ORL_SEC_COMBINE_MASK ) {
    case( ORL_SEC_COMBINE_PRIVATE ):
        return( "PRIVATE" );
    case( ORL_SEC_COMBINE_PUBLIC ):
        return( "PUBLIC" );
    case( ORL_SEC_COMBINE_STACK ):
        return( "STACK" );
    case( ORL_SEC_COMBINE_COMMON ):
        return( "COMMON" );
    default:
        return( "" );
    }
}


static void printMasmHeader( section_ptr sec )
{
    orl_sec_alignment   alignment;
    orl_sec_flags       flags;
    orl_sec_type        type;
    orl_sec_frame       frame;
    orl_sec_combine     combine;
    orl_sec_size        size;
    char                *name;
    char                *class;
    char                *gname;
    char                *astr;
    orl_sec_handle      sh;
    orl_group_handle    grp = NULL;
    char                comname[ MAX_LINE_LEN ];

    size = ORLSecGetSize( sec->shnd );

    // Load all necessary information
    name = sec->name;
    if( !name ) {
        name = "";
    }
    type = ORLSecGetType( sec->shnd );
    flags = ORLSecGetFlags( sec->shnd );
    frame = ORLSecGetAbsFrame( sec->shnd );

    if( DFormat & DFF_ASM ) {
        class = ORLSecGetClassName( sec->shnd );
        if( !class ) {
            class = "";
        }
        if( flags & ORL_SEC_FLAG_COMDAT ) {
            BufferConcat( "; ERROR: Comdat symbols cannot be assembled." );
        } else if( frame == ORL_SEC_NO_ABS_FRAME ) {
            alignment = ORLSecGetAlignment( sec->shnd );
            combine = ORLSecGetCombine( sec->shnd );
            BufferQuoteName( name );
            BufferStore( "\t\tSEGMENT\t%s %s %s '%s'",
                         getAlignment( alignment ), getCombine( combine ),
                         getUse( flags ), class );
        } else {
            BufferQuoteName( name );
            BufferStore( "\t\tSEGMENT\t at %08X %s '%s'", frame << 4,
                         getUse( flags ), class );
        }
    } else {
        if( flags & ORL_SEC_FLAG_COMDAT ) {
            if( Options & NODEMANGLE_NAMES ) {
                strncpy( comname, name, MAX_LINE_LEN );
            } else {
                __demangle_l( name, 0, comname, MAX_LINE_LEN );
            }
            combine = ORLSecGetCombine( sec->shnd );
            if( ( combine & ORL_SEC_COMBINE_COMDAT_ALLOC_MASK ) ==
                                         ORL_SEC_COMBINE_COMDAT_ALLOC_EXPLIC ) {
                sh = ORLSecGetAssociated( sec->shnd );
                grp = ORLSecGetGroup( sec->shnd );
                astr = "SEGMENT";
            } else {
                sh = NULL;
                alignment = ORLSecGetAlignment( sec->shnd );
                astr = getAlignment( alignment );
            }
            if( sh || grp ) {
                name = NULL;
                gname = NULL;
                if( grp ) {
                    gname = ORLGroupName( grp );
                }
                if( sh ) {
                    name = ORLSecGetName( sh );
                    if( !name ) {
                        if( gname ) {
                            name = gname;
                            gname = NULL;
                        } else {
                            name = "";
                        }
                    }
                } else {
                    name = gname;
                    gname = NULL;
                }
                if( gname ) {
                    BufferStore( "Comdat: %s %s %s '%s:%s' %08X bytes", comname,
                                 astr, getPick( combine ), gname, name, size );
                } else {
                    BufferStore( "Comdat: %s %s %s '%s' %08X bytes", comname,
                                 astr, getPick( combine ), name, size );
                }
            } else {
                BufferStore( "Comdat: %s %s %s %s %08X bytes", name, astr,
                         getPick( combine ), getAlloc( combine ), size );
            }
        } else if( frame == ORL_SEC_NO_ABS_FRAME ) {
            alignment = ORLSecGetAlignment( sec->shnd );
            BufferStore( "Segment: %s %s %s %08X bytes", name,
                         getAlignment( alignment ), getUse( flags ), size );
        } else {

⌨️ 快捷键说明

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