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 + -
显示快捷键?