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