procfile.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 713 行 · 第 1/2 页
C
713 行
{
mod_entry * mod;
mod_entry * next;
mod_entry * savemod;
file_list * list;
mod = Root->mods;
Root->mods = NULL;
for( list = Root->files; list != NULL; list = list->next_file ) {
if( mod == NULL ) break;
while( mod->modinfo & MOD_KILL ) {
next = mod->n.next_mod;
FreeModEntry( mod );
mod = next;
if( mod == NULL ) break;
}
if( mod == NULL ) break;
if( mod->f.source == list ) {
for(;;) {
next = mod->n.next_mod;
if( list->status & STAT_HAS_CHANGED ) {
memset( mod, 0, sizeof(mod_entry) );
DoPass1( mod, list );
} else {
SavedPass1( mod );
}
mod = next;
if( mod == NULL || mod->f.source != list ) break;
}
} else {
DoPass1( NULL, list );
}
}
while( mod != NULL ) {
next = mod->n.next_mod;
FreeModEntry( mod );
mod = next;
}
while( list != NULL ) {
DoPass1( NULL, list );
list = list->next_file;
}
mod = LibModules;
savemod = Root->mods; // pass1 routines will add new mods to this
Root->mods = NULL;
CurrMod = NULL;
while( mod != NULL ) {
next = mod->n.next_mod;
if( mod->modinfo & MOD_KILL
|| (mod->f.source != NULL && mod->f.source->status & STAT_HAS_CHANGED )) {
FreeModEntry( mod );
} else {
SavedPass1( mod );
}
mod = next;
}
LibModules = Root->mods;
Root->mods = savemod;
}
static void FreeModSegments( mod_entry *mod )
/*******************************************/
{
mod->publist = NULL;
Ring2CarveFree( CarveSegData, &mod->segs );
}
static void IncLoadObjFiles( void )
/*********************************/
{
PrepareModList();
SetStartAddr();
MarkDefaultSyms();
IncIterateMods( Root->mods, MarkRelocs, FALSE );
IncIterateMods( LibModules, MarkRelocs, FALSE );
IncIterateMods( Root->mods, FixModAltDefs, FALSE );
IncIterateMods( LibModules, FixModAltDefs, FALSE );
IncIterateMods( Root->mods, KillSyms, TRUE );
IncIterateMods( LibModules, KillSyms, TRUE );
PurgeSymbols();
IncIterateMods( Root->mods, FreeModSegments, TRUE );
IncIterateMods( LibModules, FreeModSegments, TRUE );
ProcessMods();
DoIncGroupDefs();
DoIncLibDefs();
}
extern void LoadObjFiles( section *sect )
/***************************************/
{
file_list * list;
CurrSect = sect;
CurrMod = NULL;
for( list = sect->files; list != NULL; list = list->next_file ) {
DoPass1( NULL, list );
}
}
static member_list * FindMember( file_list *list, char *name )
/************************************************************/
// see if name is in the member list of list
{
member_list ** memb;
member_list * foundmemb;
foundmemb = NULL;
memb = &list->u.member;
while( *memb != NULL ) {
if( ModNameCompare( name, (*memb)->name ) ) {
foundmemb = *memb;
*memb = (*memb)->next; // remove it from the list.
break;
}
memb = &(*memb)->next;
}
return foundmemb;
}
static void DoPass1( mod_entry *next, file_list *list )
/*****************************************************/
/* do pass 1 on the object file */
{
mod_entry * old;
member_list * member;
char * membname;
unsigned long loc;
unsigned long size;
unsigned reclength;
bool lastmod;
bool ignoreobj;
loc = 0;
lastmod = FALSE;
if( CacheOpen( list ) ) {
reclength = CheckLibraryType( list, &loc, FALSE );
for(;;) { /* there may be more than 1 object module in a file */
member = NULL;
ignoreobj = FALSE;
if( EndOfLib( list, loc ) ) break;
membname = IdentifyObject( list, &loc, &size );
if( list->status & STAT_IS_LIB ) {
if( list->status & STAT_HAS_MEMBER && list->u.member != NULL ) {
member = FindMember( list, membname );
if( member == NULL ) {
ignoreobj = TRUE;
} else if( list->u.member == NULL ) {
lastmod = TRUE;
}
}
}
if( ignoreobj ) {
_LnkFree( membname );
if( size != 0 ) {
loc += size;
} else {
SkipFile( list, &loc );
}
} else {
if( next == NULL ) {
next = NewModEntry();
}
next->n.next_mod = NULL;
next->f.source = list;
next->modtime = next->f.source->file->modtime;
if( member != NULL ) {
next->modinfo |= member->flags;
_LnkFree( member );
}
if( !(list->status & STAT_HAS_MEMBER) ) {
next->modinfo |= list->status & DBI_MASK;
if( list->status & STAT_LAST_SEG ) {
next->modinfo |= MOD_LAST_SEG;
}
}
old = CurrMod;
AddToModList( next );
next->location = loc;
if( membname == NULL ) {
membname = ChkStrDup( list->file->name );
}
next->name = membname;
loc = ObjPass1();
if( list->status & STAT_TRACE_SYMS ) {
TraceSymList( CurrMod->publist );
}
next = NULL;
}
ObjFormat = 0;
if( list->status & STAT_IS_LIB ) { // skip padding.
loc += CalcAlign( loc, reclength );
} else if( !IS_FMT_OMF(CurrMod->modinfo) ) {
break; // can only concat omf.
}
if( lastmod || CacheEnd( list, loc ) ) break;
}
if( list->u.member != NULL ) {
LnkMsg( ERR+MSG_CANT_FIND_MEMBER, "12", list->file->name,
list->u.member->name );
}
CacheClose( list, 1 );
}
CheckStop();
}
extern char * IdentifyObject( file_list * list, unsigned long *loc,
unsigned long *size )
/*****************************************************************/
{
ar_header * ar_hdr;
char * name;
name = NULL;
*size = 0;
if( list->status & STAT_AR_LIB ) {
ar_hdr = CacheRead( list, *loc, sizeof(ar_header) );
*loc += sizeof(ar_header);
name = GetARName( ar_hdr, list );
*size = GetARValue( ar_hdr->size, AR_SIZE_LEN );
}
if( !IsORL( list, *loc ) ) {
if( IsOMF( list, *loc ) ) {
ObjFormat |= FMT_OMF;
name = GetOMFName( list, loc );
}
}
return name;
}
static void BadSkip( file_list *list, unsigned long *loc )
/********************************************************/
{
list = list;
loc = loc;
BadObjFormat();
}
static void (*SkipObjFile[])(file_list *, unsigned long *) = {
BadSkip, OMFSkipObj, ORLSkipObj, ORLSkipObj };
static void SkipFile( file_list *list, unsigned long *loc )
/*********************************************************/
{
SkipObjFile[GET_FMT_IDX(ObjFormat)]( list, loc );
}
static bool EndOfLib( file_list *list, unsigned long loc )
/********************************************************/
{
unsigned_8 *id;
if( list->status & STAT_OMF_LIB) {
id = CacheRead( list, loc, sizeof(unsigned_8) );
return *id == LIB_TRAILER_REC;
} else {
return 0;
}
}
static unsigned long (*CallPass1[])() = {
BadObjFormat,
OMFPass1,
ORLPass1,
ORLPass1,
IncPass1,
BadObjFormat,
BadObjFormat,
BadObjFormat
};
extern unsigned long ObjPass1( void )
/***********************************/
/* Pass 1 of 8086 linker. */
{
unsigned long loc;
char * savename;
DEBUG(( DBG_BASE, "1 : file %s", CurrMod->f.source->file->name ));
CurrMod->modinfo |= MOD_DONE_PASS_1;
SymModStart();
DBIInitModule( CurrMod );
RelocStartMod();
P1Start();
loc = CallPass1[GET_FMT_IDX(ObjFormat)]();
CollapseLazyExtdefs();
SymModEnd();
if( !(CurrMod->modinfo & MOD_GOT_NAME) ) {
savename = CurrMod->name;
CurrMod->name = StringStringTable( &PermStrings, savename );
_LnkFree( savename );
CurrMod->modinfo |= MOD_GOT_NAME;
}
DBIP1ModuleScanned();
ReleaseNames();
PermEndMod( CurrMod );
FreeObjInfo();
ObjFormat = 0; //clear flags for processing obj file
return loc;
}
static bool ResolveVFExtdefs( void )
/**********************************/
/* go through the symbol table, and check if any conditional extdefs
* should turned into real extdefs */
{
bool resolved;
symbol * sym;
resolved = FALSE;
for( sym = HeadSym; sym != NULL; sym = sym->link ) {
if( IS_SYM_VF_REF(sym) ) {
resolved |= CheckVFList( sym );
}
}
return resolved;
}
extern void ResolveUndefined( void )
/**********************************/
{
symbol * sym;
file_list * lib;
bool keepgoing;
LnkMsg( INF+MSG_SEARCHING_LIBS, NULL );
if( FmtData.type & MK_OVERLAYS && FmtData.u.dos.distribute ) {
LinkState |= CAN_REMOVE_SEGMENTS;
InitModTable();
}
CurrSect = Root;
ResolveVFExtdefs();
do {
LinkState &= ~LIBRARIES_ADDED;
for( lib = ObjLibFiles; lib != NULL; lib = lib->next_file ) {
if( lib->status & STAT_SEEN_LIB ) {
lib->status |= STAT_OLD_LIB;
} else {
lib->status |= STAT_SEEN_LIB;
}
}
for( sym = HeadSym; sym != NULL; sym = sym->link ) {
if( ((!(sym->info & SYM_DEFINED) && !IS_SYM_WEAK_REF(sym))
|| (FmtData.type & MK_NOVELL && IS_SYM_IMPORTED(sym)
&& sym->info & (SYM_REFERENCED | SYM_LOCAL_REF)))
&& !(sym->info & SYM_IS_ALTDEF) ) {
LibFind( sym->name, (sym->info & SYM_CHECKED) != 0 );
}
sym->info |= SYM_CHECKED;
}
keepgoing = ResolveVFExtdefs();
} while( keepgoing || LinkState & LIBRARIES_ADDED );
BurnLibs();
PrintBadTraces();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?