procfile.c

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

C
713
字号
/****************************************************************************
*
*                            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:  PROCFILES   : process object file.
*
****************************************************************************/

#include <string.h>
#include "linkstd.h"
#include "msg.h"
#include "alloc.h"
#include "wlnkmsg.h"
#include "pcobj.h"
#include "library.h"
#include <ar.h>
#include "objnode.h"
#include "obj2supp.h"
#include "fileio.h"
#include "objpass1.h"
#include "overlays.h"
#include "objio.h"
#include "distrib.h"
#include "symtrace.h"
#include "objcache.h"
#include "specials.h"
#include "objorl.h"
#include "objomf.h"
#include "loadfile.h"
#include "dbgall.h"
#include "objfree.h"
#include "cmdline.h"
#include "impexp.h"
#include "strtab.h"
#include "carve.h"
#include "permdata.h"
#include "ring.h"
#include "procfile.h"
#include "hash.h"

static bool             EndOfLib( file_list *, unsigned long );
static void             IncLoadObjFiles( void );
static void             DoPass1( mod_entry *next, file_list *list );
static void             SkipFile( file_list *list, unsigned long *loc );

extern void ProcObjFiles( void )
/******************************/
/* Perform Pass 1 on all object files */
{
    CurrMod = NULL;
    if( LinkFlags & INC_LINK_FLAG) {
        if((LinkFlags & DWARF_DBI_FLAG) == 0 && LinkFlags & ANY_DBI_FLAG) {
            LnkMsg( FTL+MSG_INC_ONLY_SUPPORTS_DWARF, NULL );
        }
        if( LinkFlags & STRIP_CODE ) {
            LnkMsg( FTL+MSG_INC_AND_DCE_NOT_ALLOWED, NULL );
        }
        if( LinkFlags & VF_REMOVAL ) {
            LnkMsg( FTL+MSG_INC_AND_VFR_NOT_ALLOWED, NULL );
        }
    }
    LnkMsg( INF+MSG_LOADING_OBJECT, NULL );
    if( LinkFlags & STRIP_CODE ) {
        LinkState |= CAN_REMOVE_SEGMENTS;
    }
    if( LinkState & GOT_PREV_STRUCTS ) {
        IncLoadObjFiles();
    } else {
        LoadObjFiles( Root );
        if( FmtData.type & MK_OVERLAYS ) {
            OvlPass1();
        }
    }
}

extern void SetupFakeModule( void )
/*********************************/
{
    if( FmtData.type & MK_PE ) {
        FakeModule = NewModEntry();
        FakeModule->modinfo = DBI_ALL|MOD_LAST_SEG|MOD_NEED_PASS_2|FMT_PE_XFER;
        FakeModule->name = StringStringTable( &PermStrings, LinkerModule );
        DBIInitModule( FakeModule );
    }
}

extern void LinkFakeModule( void )
/********************************/
{
    if( FmtData.type & MK_PE ) {
        // Unlike other modules, fake module goes to the beginning of the list
        FakeModule->n.next_mod = LibModules;
        LibModules = FakeModule;
    }
}

static void CheckNewFile( mod_entry *mod, file_list *list,
                          int AlwaysCheckUsingDate)
/*********************************************************/
{
    time_t      modtime;

    if( !(LinkFlags & GOT_CHGD_FILES) || AlwaysCheckUsingDate) {
        if( QModTime(list->file->name, &modtime) || modtime > mod->modtime ) {
            list->status |= STAT_HAS_CHANGED;
        }
    } else {
        if( FindHTableElem( Root->modFilesHashed, list->file->name ) ) {
            list->status |= STAT_HAS_CHANGED;
        }
    }
}

static void SetStartAddr( void )
/******************************/
{
    mod_entry * mod;

    if( StartInfo.user_specd || !StartInfo.from_inc ) return;
    mod = StartInfo.mod;
    if( mod == NULL ) return;
    if( mod->modinfo & MOD_KILL || mod->f.source->status & STAT_HAS_CHANGED ) {
        ClearStartAddr();
    }
}

static void SetupModule( mod_entry **mod, file_list *list )
/*********************************************************/
{
    char *      fname;
    mod_entry * currmod;

    currmod = *mod;

    CheckNewFile( currmod, list, 0 );
    fname = currmod->f.fname;
    for(;;) {
        currmod->f.source = list;
        currmod = currmod->n.next_mod;
        if( currmod == NULL ) break;
        if( currmod->f.fname != fname ) break;
    }
    *mod = currmod;
}

static void DoIncLibDefs( void )
/******************************/
{
    libnamelist *       lib;

    for( lib = SavedDefLibs; lib != NULL; lib = lib->next ) {
        AddObjLib( lib->name, 1 );
    }
}

static libnamelist * CalcLibBlacklist( void )
/*******************************************/
/* figure out if the user has changed any of the specified libraries, and
 * torch anything after a changed library */
{
    infilelist *        userlibs;
    libnamelist *       oldlibs;

    userlibs = CachedLibFiles;
    oldlibs = SavedUserLibs;
    while( oldlibs != NULL ) {
        if( userlibs == NULL ) return oldlibs;
        if( FNAMECMPSTR(userlibs->name, oldlibs->name) != 0 ) return oldlibs;
        oldlibs = oldlibs->next;
        userlibs = userlibs->next;
    }
    return NULL;
}

static void CheckBlacklist( file_list *list, libnamelist *blacklist )
/*******************************************************************/
{
    unsigned    length;
    unsigned    delta;

    if( list->status & STAT_HAS_CHANGED ) return;
    length = strlen( list->file->name );
    while( blacklist != NULL ) {
        if( length >= blacklist->namelen ) {
            delta = length - blacklist->namelen;
            if( FNAMECMPSTR(blacklist->name,list->file->name + delta) == 0 ) {
                list->status |= STAT_HAS_CHANGED;
                return;
            }
        }
        blacklist = blacklist->next;
    }
}

static void PrepareModList( void )
/********************************/
{
    file_list * list;
    mod_entry * mod;
    mod_entry * curr;
    libnamelist *blacklist;

    mod = Root->mods;
    for( list = Root->files; list != NULL; list = list->next_file ) {
        if( strcmp( list->file->name, mod->f.fname ) == 0 ) {
            SetupModule( &mod, list );
        } else if( mod->n.next_mod != NULL ) {
            if( FNAMECMPSTR( list->file->name, mod->n.next_mod->f.fname ) == 0){
                mod->modinfo |= MOD_KILL;
                mod = mod->n.next_mod;
                SetupModule( &mod, list );
            }
        }
        if( mod == NULL ) break;
    }
    while( mod != NULL ) {
        mod->modinfo |= MOD_KILL;               // no match found
        mod = mod->n.next_mod;
    }
    blacklist = CalcLibBlacklist();
    mod = LibModules;
    while( mod != NULL ) {
        if( mod->f.fname == NULL ) {
            mod->modinfo |= MOD_KILL;
        } else if( !(mod->modinfo & MOD_VISITED) ) {
            list = AddObjLib( mod->f.fname, 128 );
            CheckNewFile( mod, list, 1);
            CheckBlacklist( list, blacklist );
            for( curr = mod->n.next_mod; curr != NULL; curr = curr->n.next_mod){
                if( curr->f.fname == mod->f.fname ) {
                    curr->f.source = list;
                    curr->modinfo |= MOD_VISITED;
                }
            }
            mod->f.source = list;
        }
        mod->modinfo &= ~MOD_VISITED;
        mod = mod->n.next_mod;
    }
    FreeList( SavedUserLibs );
    SavedUserLibs = NULL;
}

static void MarkDefaultSyms( void )
/*********************************/
{
    symbol *sym;

    for( sym = HeadSym; sym != NULL; sym = sym->link ) {
        if( IS_SYM_ALIAS( sym ) && sym->info & SYM_WAS_LAZY ) {
            sym->e.def->info |= SYM_RELOC_REFD;
        }
    }
}

static void MarkRelocs( mod_entry *mod )
/**************************************/
{
    IterateModRelocs( mod->relocs, mod->sizerelocs, RelocMarkSyms );
}

static void KillASym( void *_sym )
/********************************/
{
    symbol *sym = _sym;

    sym->info |= SYM_KILL;
    if( IS_SYM_IMPORTED( sym ) ) {
        KillDependantSyms( sym );
    }
}

static void KillSyms( mod_entry *mod )
/************************************/
{
    Ring2Walk( mod->publist, KillASym );
}

static void SetAltDefData( void *_sym )
/*************************************/
{
    symbol *sym = _sym;

    if( sym->info & SYM_IS_ALTDEF && sym->info & SYM_COMDAT
                                  && !(sym->info & SYM_HAS_DATA) ) {
        sym->p.seg->data = sym->e.mainsym->p.seg->data;
    }
}

static void FixModAltDefs( mod_entry *mod )
/*****************************************/
{
    Ring2Walk( mod->publist, SetAltDefData );
}

static void IncIterateMods( mod_entry *mod, void (*proc_fn)(mod_entry *),
                            bool dochanged )
/***********************************************************************/
{
    bool haschanged;

    while( mod != NULL ) {
        haschanged = mod->modinfo & MOD_KILL
                        || mod->f.source->status & STAT_HAS_CHANGED;
        if( haschanged == dochanged ) {
            proc_fn( mod );
        }
        mod = mod->n.next_mod;
    }
}

static void AddToModList( mod_entry *mod )
/****************************************/
{
    mod->modinfo |= ObjFormat & FMT_OBJ_FMT_MASK;
    if( CurrMod == NULL ) {
        CurrSect->mods = mod;
    } else {
        CurrMod->n.next_mod = mod;
    }
    mod->n.next_mod = NULL;
    CurrMod = mod;
}

static void SavedPass1( mod_entry *mod )
/**************************************/
{
    ObjFormat = FMT_INCREMENTAL;
    mod->modinfo &= ~FMT_OBJ_FMT_MASK;
    AddToModList( mod );
    ObjPass1();
}

static void ProcessMods( void )
/*****************************/

⌨️ 快捷键说明

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