objomf.c

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

C
1,112
字号
/****************************************************************************
*
*                            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:  Object file processing routines specific to OMF.
*
****************************************************************************/


#include <string.h>
#include "linkstd.h"
#include "msg.h"
#include "wlnkmsg.h"
#include "alloc.h"
#include <pcobj.h>
#include "obj2supp.h"
#include "objnode.h"
#include "objcalc.h"
#include "objio.h"
#include "objcache.h"
#include "wcomdef.h"
#include "cmdline.h"
#include "loadfile.h"
#include "dbgall.h"
#include "objpass1.h"
#include "objstrip.h"
#include "omfreloc.h"
#include "carve.h"
#include "strtab.h"
#include "permdata.h"
#include "virtmem.h"
#include "impexp.h"
#include "objomf.h"

/* forward declarations */

static void     Pass1Cmd( byte );
static void     ProcTHEADR( void );
static void     Comment( void );
static void     AddNames( void );
static void     ProcSegDef( void );
static void     ProcPubdef( bool static_sym );
static void     UseSymbols( bool static_sym, bool iscextdef );
static void     DefineGroup( void );
static void     ProcLinnum( void );
static void     ProcLxdata( bool islidata );
static void     ProcLxdata( bool islidata );
static void     ProcModuleEnd( void );
static void     ProcAlias( void );
static void     DoLazyExtdef( bool isweak );
static void     ProcVFTableRecord( bool ispure );
static void     ProcVFReference( void );
static void     GetObject( segdata * seg, unsigned_32 obj_offset, bool lidata );

byte            OMFAlignTab[] = {0,0,1,4,8,2,12};

enum dll_entry_type { DLL_RELOC_NAME, DLL_RELOC_ORDINAL };


void ResetObjOMF( void )
/**********************/
{
    ObjBuff = NULL;
    EOObjRec = NULL;
}

static unsigned long ProcObj( file_list * file, unsigned long loc,
                              void (*procrtn)( byte ) )
/****************************************************************/
/* Process an object file. */
{
    obj_record *        rec;
    byte                cmd;
    unsigned_16         len;

    RecNum = 0;
    do {
        ObjFormat &= ~FMT_MS_386;   // assume not a Microsoft 386 .obj file
        rec = CacheRead( file, loc, sizeof(obj_record) );
        if( rec == NULL ) {
            EarlyEOF();
            break;
        }
        loc += sizeof( obj_record );
        len = rec->length;
        cmd = rec->command;
        if( procrtn != NULL ) {
            RecNum++;
            ObjBuff = CacheRead( file, loc, len );
            if( ObjBuff == NULL ) {
                EarlyEOF();
                break;
            }
            EOObjRec = ObjBuff + len - 1;       // 1 for the checksum.
            (*procrtn)( cmd );
            if( ObjBuff > EOObjRec ) {
                BadObject();
                break;
            }
        }
        loc += len;
    } while( cmd != CMD_MODEND && cmd != CMD_MODE32 );
    return( loc );
}

static void CheckUninit( void *_seg, void *dummy )
/************************************************/
{
    segnode *seg = _seg;

    dummy = dummy;
    if( !(seg->info & SEG_LXDATA_SEEN) ) {
        seg->entry->isuninit = TRUE;
        if( seg->entry->data != NULL ) {
            ReleaseInfo( seg->entry->data );
            seg->entry->data = NULL;
        }
    }
}

extern unsigned long OMFPass1( void )
/***********************************/
// do pass 1 for OMF object files
{
    unsigned long retval;

    PermStartMod( CurrMod );
    if( LinkState & (HAVE_MACHTYPE_MASK & ~HAVE_I86_CODE) ) {
        LnkMsg( WRN+MSG_MACHTYPE_DIFFERENT, "s", CurrMod->f.source->file->name);
    } else {
        LinkState |= HAVE_I86_CODE;
    }
    CurrMod->omfdbg = OMF_DBG_CODEVIEW; // Assume MS style LINNUM records
    retval = ProcObj( CurrMod->f.source, CurrMod->location, &Pass1Cmd );
    IterateNodelist( SegNodes, CheckUninit, NULL );
    ResolveComdats();
    return retval;
}

static void Pass1Cmd( byte cmd )
/******************************/
/* Process an object record for pass 1 */
{
    bool isstatic;

    isstatic = FALSE;
    switch( cmd ) {
    case CMD_THEADR:
        ProcTHEADR();
        break;
    case CMD_COMENT:
        Comment();
        break;
    case CMD_LLNAME:
    case CMD_LNAMES:
        AddNames();
        break;
    case CMD_SEGD32:
        ObjFormat |= FMT_MS_386;
    case CMD_SEGDEF:
        CurrMod->modinfo |= MOD_NEED_PASS_2;
        ProcSegDef();
        break;
    case CMD_STATIC_PUBD32:
        ObjFormat |= FMT_MS_386;
    case CMD_STATIC_PUBDEF:
        ProcPubdef( TRUE );
        break;
    case CMD_PUBD32:
        ObjFormat |= FMT_MS_386;
    case CMD_PUBDEF:
        ProcPubdef( FALSE );
        break;
    case CMD_STATIC_EXTDEF:
    case CMD_STATIC_EXTD32:
        isstatic = TRUE;
    case CMD_EXTDEF:
        CurrMod->modinfo |= MOD_NEED_PASS_2;
        UseSymbols( isstatic, FALSE );
        break;
    case CMD_CEXTDF:
        CurrMod->modinfo |= MOD_NEED_PASS_2;
        UseSymbols( FALSE, TRUE );
        break;
    case CMD_GRPDEF:
        DefineGroup();
        break;
    case CMD_LINN32:
        ObjFormat |= FMT_MS_386;
    case CMD_LINNUM:
        if (CurrMod->omfdbg == OMF_DBG_CODEVIEW)
            ProcLinnum();
        break;
    case CMD_LINS32:
        ObjFormat |= FMT_MS_386;
    case CMD_LINSYM:
        ProcLinsym();
        break;
    case CMD_STATIC_COMDEF:
        isstatic = TRUE;
    case CMD_COMDEF:
        CurrMod->modinfo |= MOD_NEED_PASS_2;
        ProcComdef( isstatic );
        break;
    case CMD_COMD32:
        ObjFormat |= FMT_MS_386;
    case CMD_COMDAT:
        CurrMod->modinfo |= MOD_NEED_PASS_2;
        ProcComdat();
        break;
    case CMD_LEDA32:
        ObjFormat |= FMT_MS_386;
    case CMD_LEDATA:
        ProcLxdata( FALSE );
        break;
    case CMD_LIDA32:
        ObjFormat |= FMT_MS_386;
    case CMD_LIDATA:
        ProcLxdata( TRUE );
        break;
    case CMD_FIXU32:
        ObjFormat |= FMT_MS_386;
    case CMD_FIXUP:         /* count the fixups for each seg_leader */
        CurrMod->modinfo |= MOD_NEED_PASS_2;
        DoRelocs();
        ObjFormat &= ~FMT_UNSAFE_FIXUPP;
        break;
    case CMD_MODE32:
        ObjFormat |= FMT_MS_386;
    case CMD_MODEND:
        ProcModuleEnd();
        break;
    case CMD_ALIAS:
        ProcAlias();
        break;
    case CMD_VERNUM:
    case CMD_VENDEXT:
    case CMD_BAKPAT:
    case CMD_BAKP32:
    case CMD_NBKPAT:
    case CMD_NBKP32:    /* ignore bakpats in pass 1 */
    case CMD_LOCSYM:
    case CMD_TYPDEF:
    case CMD_DEBSYM:
    case CMD_BLKDEF:
    case CMD_BLKD32:
    case CMD_BLKEND:
    case CMD_BLKE32:
        /* ignore the Intel debugging records */
        break;
    case CMD_RHEADR:
    case CMD_REGINT:
    case CMD_REDATA:
    case CMD_RIDATA:
    case CMD_OVLDEF:
    case CMD_ENDREC:
    case CMD_LHEADR:
    case CMD_PEDATA:
    case CMD_PIDATA:
    case CMD_LIBHED:
    case CMD_LIBNAM:
    case CMD_LIBLOC:
    case CMD_LIBDIC:
        LnkMsg( LOC_REC+WRN+MSG_REC_NOT_DONE, "x", cmd );
        break;
    default:
        CurrMod->f.source->file->flags |= INSTAT_IOERR;
        LnkMsg( LOC_REC+ERR+MSG_BAD_REC_TYPE, "x", cmd );
        break;
    }
}

extern bool IsOMF( file_list * list, unsigned long loc )
/******************************************************/
{
    byte *      rec;

    rec = CacheRead( list, loc, sizeof(unsigned_8) );
    return rec != NULL && *rec == CMD_THEADR;
}

extern char * GetOMFName( file_list *list, unsigned long * loc )
/**************************************************************/
{
    obj_record *rec;
    char *      name;
    char *      newname;
    unsigned    len;

    rec = CacheRead( list, *loc, sizeof(obj_record) );
    if( rec == NULL ) return NULL;
    *loc += sizeof( obj_record );
    len = rec->length;
    name = CacheRead( list, *loc, rec->length );
    *loc += len;
    if( name == NULL ) return NULL;
    len = *name;        // get actual name length
    _ChkAlloc( newname, len + 1 );
    memcpy( newname, name + 1, len );
    *(newname + len) = '\0';
    return newname;
}

extern void OMFSkipObj( file_list *list, unsigned long *loc )
/***********************************************************/
{
    *loc = ProcObj( list, *loc, NULL );
}

static void ProcTHEADR( void )
/****************************/
{
}

static void LinkDirective( void )
/*******************************/
{
    char            directive;
    unsigned char   priority;
    segnode *       seg;

    directive = *(char *)ObjBuff;
    ObjBuff++;
    switch( directive ) {
    case LDIR_DEFAULT_LIBRARY:
        if( ObjBuff + 1 < EOObjRec ) {
            priority = *( char * )ObjBuff;
            ObjBuff++;
            AddCommentLib( ObjBuff, EOObjRec - ObjBuff, priority );
        }
        break;
    case LDIR_SOURCE_LANGUAGE:
        DBIP1Source( ObjBuff, EOObjRec );
        break;
    case LDIR_VF_PURE_DEF:
        ProcVFTableRecord( TRUE );
        break;
    case LDIR_VF_TABLE_DEF:
        ProcVFTableRecord( FALSE );
        break;
    case LDIR_VF_REFERENCE:
        ProcVFReference();
        break;
    case LDIR_PACKDATA:
        if( !(LinkFlags & PACKDATA_FLAG) ) {
            PackDataLimit = _GetU32UN( ObjBuff );
            LinkFlags |= PACKDATA_FLAG;
        }
        break;

⌨️ 快捷键说明

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