distrib.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 553 行 · 第 1/2 页
C
553 行
/****************************************************************************
*
* 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: routines for distributing libraries over overlays
*
****************************************************************************/
#include <string.h>
#include "linkstd.h"
#include "alloc.h"
#include "msg.h"
#include "pcobj.h"
#include "wlnkmsg.h"
#include "objpass1.h"
#include "objpass2.h"
#include "objfree.h"
#include "wcomdef.h"
#include "overlays.h"
#include "ring.h"
#include "distrib.h"
#include "specials.h"
static unsigned_16 CurrModThere;
static arcdata * ArcBuffer;
static unsigned_32 ArcBufLen;
static mod_entry ** ModTable;
static unsigned_16 CurrModHandle;
section ** SectOvlTab;
/* forward declarations */
static bool NewRefVector( symbol *, unsigned_16, unsigned_16 );
static void ScanArcs( mod_entry *mod );
#define MOD_DEREF( x ) (ModTable[(x)])
#define INITIAL_MOD_ALLOC 32
#define INITIAL_ARC_ALLOC 32
#define MAX_NUM_MODULES (8 * 1024)
extern void ResetDistrib( void )
/******************************/
{
ArcBuffer = NULL;
ModTable = NULL;
SectOvlTab = NULL;
}
extern void InitModTable( void )
/******************************/
{
CurrModThere = INITIAL_MOD_ALLOC;
_ChkAlloc( ModTable, INITIAL_MOD_ALLOC * sizeof( mod_entry * ) );
CurrModHandle = 0;
ArcBufLen = INITIAL_ARC_ALLOC;
_ChkAlloc( ArcBuffer, sizeof(arcdata)
+ (INITIAL_ARC_ALLOC - 1) * sizeof(dist_arc));
MakePass1Blocks();
}
extern void AddModTable( mod_entry * lp, unsigned_16 libspot )
/************************************************************/
/* add this module to the table, and make the arclist field point to a
* scratch buffer */
// NYI: segdata changes have completely broken distributing libraries.
// fix this!
{
mod_entry ** new;
CurrModHandle++;
if( CurrModHandle == CurrModThere ) {
if( CurrModThere > MAX_NUM_MODULES ) {
LnkMsg( FTL+MSG_TOO_MANY_LIB_MODS, NULL );
}
_ChkAlloc( new, sizeof( mod_entry * ) * CurrModThere * 2 );
memcpy( new, ModTable, sizeof( mod_entry * ) * CurrModThere );
_LnkFree( ModTable );
ModTable = new;
CurrModThere *= 2;
}
ModTable[ CurrModHandle ] = lp;
lp->x.arclist = ArcBuffer;
ArcBuffer->numarcs = 0;
if( lp->modinfo & MOD_FIXED ) {
ArcBuffer->ovlref = libspot;
} else {
ArcBuffer->ovlref = NO_ARCS_YET;
}
}
extern void InitArcBuffer( mod_entry * mod )
/******************************************/
/* set up the mod_entry arcdata field for dead code elimination */
{
if( !( ( FmtData.type & MK_OVERLAYS ) && FmtData.u.dos.distribute
&& ( LinkState & SEARCHING_LIBRARIES ) ) ) {
_PermAlloc( mod->x.arclist, sizeof(arcdata) - DIST_ONLY_SIZE );
}
}
static void MarkDead( void *_seg )
/********************************/
{
segdata *seg = _seg;
if( seg->isrefd )
return;
if( seg->isdead )
return;
if( seg->iscode ) {
seg->isdead = 1;
} else {
if( FmtData.type & MK_PE ) {
char *segname = seg->u.leader->segname;
if( ( strcmp( segname, CoffPDataSegName ) == 0 )
|| ( strcmp(segname, CoffReldataSegName) == 0 ) ) {
seg->isdead = 1;
}
}
}
}
static void KillUnrefedSyms( void *_sym )
/***************************************/
{
symbol *sym = _sym;
segdata *seg;
seg = sym->p.seg;
if( ( seg != NULL ) && !IS_SYM_IMPORTED(sym) && !IS_SYM_ALIAS(sym)
&& seg->isdead ) {
if( seg->u.leader->combine == COMBINE_COMMON ) {
seg = RingFirst( seg->u.leader->pieces );
if( !seg->isdead ) {
return;
}
}
if( sym->e.def != NULL ) {
WeldSyms( sym, sym->e.def );
} else {
sym->info |= SYM_DEAD;
}
if( LinkFlags & SHOW_DEAD ) {
LnkMsg( MAP+MSG_SYMBOL_DEAD, "S", sym );
}
}
}
static void DefineOvlSegments( mod_entry *mod )
/*********************************************/
/* figure out which of the segments are live */
{
Ring2Walk( mod->segs, MarkDead );
Ring2Walk( mod->publist, KillUnrefedSyms );
}
extern void SetSegments( void )
/*****************************/
// now that we know where everything is, do all the processing that has been
// postponed until now.
{
if( !( LinkFlags & STRIP_CODE ) )
return;
LinkState &= ~CAN_REMOVE_SEGMENTS;
ObjFormat |= FMT_DEBUG_COMENT;
if( ( FmtData.type & MK_OVERLAYS ) && FmtData.u.dos.distribute ) {
_LnkFree( ArcBuffer );
ArcBuffer = NULL;
}
if( LinkFlags & STRIP_CODE ) {
WalkMods( DefineOvlSegments );
}
#if 0 // NYI: distributing libraries completely broken.
unsigned index;
mod_entry * mod;
unsigned_16 ovlref;
mod_entry ** currmod;
unsigned num_segdefs;
if( ( FmtData.type & MK_OVERLAYS ) && FmtData.u.dos.distribute ) {
for( index = 1; index <= CurrModHandle; index++ ) {
mod = ModTable[ index ];
CurrMod = mod;
ovlref = mod->x.arclist->ovlref;
if( ovlref == NO_ARCS_YET ) { // only data referenced
CurrSect = Root;
} else {
CurrSect = SectOvlTab[ ovlref ];
}
DefModSegments( mod );
mod->x.next = NULL;
currmod = &CurrSect->u.dist_mods;
while( *currmod != NULL ) {
currmod = &((*currmod)->x.next);
}
*currmod = mod;
mod->n.sect = CurrSect;
}
}
FixGroupProblems();
FindRedefs();
if( ( FmtData.type & MK_OVERLAYS ) && FmtData.u.dos.distribute ) {
_LnkFree( SectOvlTab );
SectOvlTab = NULL;
}
#endif
ReleasePass1();
}
extern void FreeDistStuff( void )
/*******************************/
{
unsigned index;
for( index = 1; index <= CurrModHandle; index++ ) {
FreeAMod( ModTable[ index ] );
}
_LnkFree( ModTable );
_LnkFree( ArcBuffer );
_LnkFree( SectOvlTab );
ReleasePass1();
}
extern void ProcDistMods( void )
/******************************/
{
unsigned_16 index;
mod_entry * mod;
for( index = 1; index <= CurrModHandle; index++ ) {
mod = ModTable[ index ];
CurrSect = mod->n.sect;
PModule( mod );
}
}
#define SECT_VISITED 0x8000
extern unsigned_16 LowestAncestor( unsigned_16 ovl1, section * sect )
/*******************************************************************/
/* find the lowest common ancestor of the two overlay values by marking all of
* the ancestors of the first overlay, and then looking for marked ancestors
* of the other overlay */
{
section * list;
list = sect;
while( list != NULL ) {
list->ovl_num |= SECT_VISITED;
list = list->parent;
}
list = SectOvlTab[ ovl1 ];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?