cmdall.c

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

C
1,562
字号
/****************************************************************************
*
*                            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:  Commands common to all executable formats
*
****************************************************************************/


#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
#include "walloca.h"
#include "linkstd.h"
#include "msg.h"
#include "alloc.h"
#include "command.h"
#include "wlnkmsg.h"
#include "strtab.h"
#include "dbgall.h"
#include "cmddos.h"
#include "cmdline.h"
#include "symtrace.h"
#include "objio.h"
#include "loadfile.h"
#include "carve.h"
#include "permdata.h"
#include "cmdall.h"

static void *       LastFile;
static file_list ** LastLibFile;

void ResetCmdAll( void )
/**********************/
{
    LastFile = NULL;
    LastLibFile = NULL;
    LibPath = NULL;
}

extern bool ProcDosSeg( void )
/****************************/
/* process DOSSEG option */
{
    LinkState |= DOSSEG_FLAG;
    DEBUG(( DBG_OLD, "dosseg" ));
    return( TRUE );
}

extern bool ProcName( void )
/**************************/
{
    if( !GetToken( SEP_NO, TOK_INCLUDE_DOT | TOK_IS_FILENAME ) ) return( FALSE );
    CmdFlags &= ~CF_UNNAMED;
    if( Name != NULL ) {
        _LnkFree( Name );
    }
    Name = tostring();   // just keep the name around for now.
    return( TRUE );
}

extern bool ProcFormat( void )
/****************************/
{
    if( LinkState & FMT_SPECIFIED ) {
        LnkMsg( LOC+LINE+FTL + MSG_MULTIPLE_MODES_FOUND, NULL );
    }
    LinkState |= FMT_SPECIFIED;
    return( ProcOne( Models, SEP_NO, TRUE ) );
}

static bool AddOption( void )
/***************************/
{
    Token.thumb = REJECT;
    if( ProcOne( MainOptions, SEP_NO, FALSE ) == FALSE ) return( FALSE );
    return TRUE;
}

extern bool ProcOptions( void )
/*****************************/
{
    return ProcArgList( AddOption, TOK_INCLUDE_DOT );
}

extern bool ProcDebug( void )
/***************************/
{
    bool        gotmod;

    if( CmdFlags & CF_FILES_BEFORE_DBI ) {
        LnkMsg( LOC+LINE+WRN+MSG_DEBUG_AFTER_FILES, NULL );
    }
    gotmod = ProcOne( DbgMods, SEP_NO, FALSE );
    DBIFlag &= ~DBI_MASK;
    if( ProcOne( PosDbgMods, SEP_NO, FALSE ) ) {
        while( ProcOne( PosDbgMods, SEP_COMMA, FALSE ) != FALSE ); /*null loop*/
    } else {
        DBIFlag |= DBI_ALL; //DBI_MASK;
        if( !gotmod ) {
            return FALSE;
        }
    }
    return TRUE;
}

extern bool ProcDwarfDBI( void )
/******************************/
{
    if( LinkFlags & (ANY_DBI_FLAG & ~DWARF_DBI_FLAG) ) {
        LnkMsg( LOC+LINE+WRN+MSG_MULT_DBI_FORMATS, NULL );
        return TRUE;
    }
    LinkFlags |= DWARF_DBI_FLAG;
    return( TRUE );
}

extern bool ProcWatcomDBI( void )
/*******************************/
{
    if( LinkFlags & (ANY_DBI_FLAG & ~OLD_DBI_FLAG) ) {
        LnkMsg( LOC+LINE+WRN+MSG_MULT_DBI_FORMATS, NULL );
        return TRUE;
    }
    LinkFlags |= OLD_DBI_FLAG;
    return( TRUE );
}

extern bool ProcCodeviewDBI( void )
/*********************************/
{
    if( LinkFlags & (ANY_DBI_FLAG & ~CV_DBI_FLAG) ) {
        LnkMsg( LOC+LINE+WRN+MSG_MULT_DBI_FORMATS, NULL );
        return TRUE;
    }
    LinkFlags |= CV_DBI_FLAG;
    return TRUE;
}

extern bool ProcLine( void )
/**************************/
{
    if( !(LinkFlags & ANY_DBI_FLAG) ) {
        LinkFlags |= DWARF_DBI_FLAG;
    }
    DBIFlag |= DBI_LINE;
    return( TRUE );
}

#if 0
extern bool ProcDBIStatic( void )
/*******************************/
{
    if( !(LinkFlags & ANY_DBI_FLAG) ) {
        LinkFlags |= DWARF_DBI_FLAG;
    }
    DBIFlag |= DBI_STATICS;
    return( TRUE );
}
#endif

extern bool ProcType( void )
/**************************/
{
    if( !(LinkFlags & ANY_DBI_FLAG) ) {
        LinkFlags |= DWARF_DBI_FLAG;
    }
    DBIFlag |= DBI_TYPE;
    return( TRUE );
}

extern bool ProcLocal( void )
/***************************/
{
    if( !(LinkFlags & ANY_DBI_FLAG) ) {
        LinkFlags |= DWARF_DBI_FLAG;
    }
    DBIFlag |= DBI_LOCAL;
    return( TRUE );
}

extern bool ProcAll( void )
/*************************/
{
    if( !(LinkFlags & ANY_DBI_FLAG) ) {
        LinkFlags |= DWARF_DBI_FLAG;
    }
    DBIFlag |= DBI_ALL;
    return( TRUE );
}

static bool AddAlias( void )
/**************************/
/* add an individual alias */
{
    char *      name;
    int         namelen;

    namelen = Token.len;
    name = alloca( namelen );
    memcpy( name, Token.this, namelen );
    if( !GetToken( SEP_EQUALS, TOK_INCLUDE_DOT ) ) {
        return( FALSE );
    }
    MakeSymAlias( name, namelen, tostring(), Token.len );
    return( TRUE );
}

extern bool ProcAlias( void )
/***************************/
{
    return( ProcArgList( &AddAlias, TOK_INCLUDE_DOT ) );
}

static bool AddReference( void )
/******************************/
{
    symbol *    sym;

    sym = SymXOp( ST_REFERENCE | ST_CREATE, Token.this, Token.len );
    sym->info |= SYM_DCE_REF;           /* make sure it stays around */
    return( TRUE );
}

extern bool ProcReference( void )
/*******************************/
{
    return( ProcArgList( &AddReference, TOK_INCLUDE_DOT ) );
}

extern bool ProcOSName( void )
/****************************/
{
    if( GetToken( SEP_EQUALS, TOK_INCLUDE_DOT ) ) {
        if( FmtData.osname != NULL ) {
            _LnkFree( FmtData.osname );
        }
        FmtData.osname = tostring();
        return( TRUE );
    }
    return( FALSE );
}

extern bool ProcEliminate( void )
/*******************************/
/* turn on dead code elimination */
{
    LinkFlags |= STRIP_CODE;
    return( TRUE );
}

extern bool ProcMaxErrors( void )
/*******************************/
/* set a maximum number of errors for the linker to generate */
{
    if( !GetLong( &MaxErrors ) ) return( FALSE );
    LinkFlags |= MAX_ERRORS_FLAG;
    return( TRUE );
}

extern bool ProcSymFile( void )
/*****************************/
{
    if( GetToken( SEP_EQUALS, TOK_INCLUDE_DOT | TOK_IS_FILENAME ) != FALSE ) {
        if( SymFileName != NULL ) {
            _LnkFree( SymFileName );
        }
        SymFileName = FileName( Token.this, Token.len, E_SYM, FALSE );

    }
    return( TRUE );
}

static file_list * AllocNewFile( member_list *member )
/****************************************************/
{
    file_list *     new_entry;

    _PermAlloc( new_entry, sizeof(file_list) );
    new_entry->next_file = NULL;
    new_entry->status = DBIFlag;
    new_entry->strtab = NULL;
    new_entry->u.member = member;
    if( member != NULL ) {
        new_entry->status |= STAT_HAS_MEMBER;
    }
    return( new_entry );
}

static void * AddObjFile( char *name, char *member, file_list **filelist )
/************************************************************************/
{
    file_list *     new_entry;
    member_list *   new_member;

    new_member = NULL;
    if( member != NULL ) {
        _ChkAlloc( new_member, offsetof(member_list,name) + strlen( member ) + 1 );
        new_member->flags = DBIFlag;
        strcpy( new_member->name, member );
        new_member->next = NULL;
        _LnkFree( member );
        new_entry = CurrSect->files;
        while( new_entry != NULL ) {
            if( FNAMECMPSTR( new_entry->file->name, name ) == 0 ) {
                CmdFlags |= CF_MEMBER_ADDED;
                if( new_entry->u.member != NULL ) {
                    LinkList( &new_entry->u.member, new_member );
                    return( new_member );
                } else {
                    _LnkFree( new_member );      // user did a stupid thing.
                    return( new_entry->u.member );
                }
            }
            new_entry = new_entry->next_file;
        }
    }
    new_entry = AllocNewFile( new_member );
    if( new_member != NULL ) {
        new_entry->file = AllocUniqueFileEntry( name, LibPath );
        new_entry->file->flags |= INSTAT_LIBRARY;
    } else {
        new_entry->file = AllocFileEntry( name, Path );
    }
    *filelist = new_entry;
    return( new_entry );
}

extern file_list *AddObjLib( char *name, unsigned char priority )
/***************************************************************/

 {
    file_list **next_owner;
    file_list **proc_owner;
    file_list * proc_curr;
    file_list * newproc;
    bool        added;

    DEBUG(( DBG_OLD, "Adding Object library name %s", name ));
    proc_owner = &ObjLibFiles;
    for(;;) {
        proc_curr = *proc_owner;
        if( proc_curr == NULL ) break;
        if( proc_curr->priority < priority ) break;
        /* if library already exists with a higher priority */
        if( FNAMECMPSTR( proc_curr->file->name, name ) == 0 ) return(proc_curr);
        proc_owner = &proc_curr->next_file;
    }

    added = TRUE;
    next_owner = proc_owner;            /* replace library if it exists */
    for(;;) {                           /* with a lower priority       */
        if( proc_curr == NULL ) break;
        if( FNAMECMPSTR( proc_curr->file->name, name ) == 0 ) {
            *next_owner = proc_curr->next_file;    /* move entry up */
            proc_curr->next_file = *proc_owner;
            *proc_owner = proc_curr;
            proc_curr->priority = priority;
            newproc = proc_curr;
            added = FALSE;
            break;
        }
        next_owner = &proc_curr->next_file;
        proc_curr = *next_owner;
    }
    if( added ) {   /* if we need to add one */
        newproc = AllocNewFile( NULL );
        newproc->file = AllocUniqueFileEntry( name, LibPath );
        newproc->file->flags |= INSTAT_LIBRARY | INSTAT_OPEN_WARNING;
        newproc->priority = priority;
        newproc->next_file = *proc_owner;
        *proc_owner = newproc;
        LinkState |= LIBRARIES_ADDED;
    }
    return( newproc );
}

static bool AddLibFile( void )
/****************************/
{
    char *      ptr;
    char *      membname;
    file_list * entry;

    CmdFlags &= ~CF_MEMBER_ADDED;
    ptr = GetFileName( &membname, FALSE );
    if( membname != NULL ) {
        LnkMsg( LOC+LINE+WRN+MSG_NO_MEMB_IN_LIBFILE, NULL );
        _LnkFree( membname );
        _LnkFree( ptr );
        return TRUE;
    }
    entry = AllocNewFile( NULL );
    entry->file = AllocFileEntry( ptr, LibPath );
    entry->next_file = *LastLibFile;
    *LastLibFile = entry;
    LastLibFile = &entry->next_file;
    if( *LastLibFile == NULL ) {        // no file directives found yet
        CurrFList = LastLibFile;
    }
    entry->file->flags |= INSTAT_USE_LIBPATH;
    _LnkFree( ptr );
    return( TRUE );
}

extern bool ProcLibFile( void )
/*****************************/
/* process FILE command */
{
    if( (LinkFlags & (DWARF_DBI_FLAG |OLD_DBI_FLAG | NOVELL_DBI_FLAG) ) == 0 ) {
        CmdFlags |= CF_FILES_BEFORE_DBI;
    }
    if( LastLibFile == NULL ) {
        LastLibFile = &Root->files;
    }
    return( ProcArgList( &AddLibFile, TOK_INCLUDE_DOT | TOK_IS_FILENAME ) );
}

static bool AddModFile( void )
/*****************************/
{
    char *      ptr;
    char *      membname;

    ptr = GetFileName( &membname, FALSE );
    AddHTableElem(Root->modFilesHashed, ptr);
    LinkFlags |= GOT_CHGD_FILES;
    return( TRUE );
}

static bool AddFile( void )
/*************************/
{
    char *          ptr;
    char *          membname;
    file_list **    temp;

    CmdFlags &= ~CF_MEMBER_ADDED;
    if( CmdFlags & CF_AUTOSECTION ) {
        if( CmdFlags & CF_SECTION_THERE ) {     // is section there already?
            CmdFlags &= ~CF_SECTION_THERE;
        } else {
            MakeNewSection();
        }
    }
    ptr = GetFileName( &membname, TRUE );
    temp = CurrFList;
    if( *CurrFList != NULL ) {
        CurrFList = &(*CurrFList)->next_file;
    }
    LastFile = AddObjFile( ptr, membname, CurrFList );
    if( CmdFlags & CF_MEMBER_ADDED ) {
        CurrFList = temp;   // go back to previous entry.
    } else if( membname != NULL ) {     // 1st member added
        LastFile = ((file_list *)LastFile)->u.member;
        CmdFlags |= CF_MEMBER_ADDED;
    }
    _LnkFree( ptr );
    return( TRUE );
}

extern bool ProcFiles( void )
/***************************/
/* process FILE command */
{
    if( (LinkFlags & (DWARF_DBI_FLAG|OLD_DBI_FLAG | NOVELL_DBI_FLAG) ) == 0 ) {
        CmdFlags |= CF_FILES_BEFORE_DBI;
    }
    return( ProcArgList( &AddFile, TOK_INCLUDE_DOT | TOK_IS_FILENAME ) );
}

extern bool ProcModFiles( void )
/***************************/
{
    return( ProcArgList( &AddModFile, TOK_INCLUDE_DOT | TOK_IS_FILENAME ) );
}


#define MAX_PRIORITY    255

static bool AddLib( void )
/************************/
{
    char *      ptr;
    file_list * result;

    ptr = FileName( Token.this, Token.len, E_LIBRARY, FALSE );
    result = AddObjLib( ptr, MAX_PRIORITY );
    result->status |= STAT_USER_SPECD;
    if( CmdFlags & CF_SET_SECTION ) {
        result->status |= STAT_LIB_FIXED;
        if( OvlLevel == 0 ) {
            result->ovlref = 0;
        } else {
            result->ovlref = OvlNum - 1;
        }
    }
    if( CmdFlags & CF_DOING_OPTLIB ) {

⌨️ 快捷键说明

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