i86obj.c

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

C
2,113
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <string.h>
#include "standard.h"
#include "sysmacro.h"
#include "cg.h"
#include "bckdef.h"
#include "cgaux.h"
#include "objrep.h"
#include "system.h"
#include "i86obj.h"
#include "model.h"
#include "hostsys.h"
#include "zoiks.h"
#include "fppatch.h"
#include "ocentry.h"
#include "dbcue.h"
#include "import.h"
#include "feprotos.h"


#ifdef _PHAR_LAP /* This is a misnomer. Let's rename it */
    #define _OMF_32
#endif

#define _CopyTrans( src, dst, len )        Copy( src, dst, len )

extern  pointer         Copy(pointer,pointer,uint);
extern  char            *AskRTName(int);
extern  void            TellRTHandle(int,import_handle);
extern  import_handle   AskRTHandle(int);
extern  void            TellImportHandle(sym_handle,import_handle);
extern  import_handle   AskImportHandle(sym_handle);
extern  void            TellDonePatch(label_handle);
extern  pointer         AskLblPatch(label_handle);
extern  void            TellAddress(label_handle,offset);
extern  sym_handle      AskForLblSym(label_handle);
extern  void            FatalError(char *);
extern  void            CloseObj( void );
extern  void            PatchObj(objhandle,uint,byte*,int);
extern  void            GetFromObj(objhandle,uint,byte*,int);
extern  void            ScratchObj( void );
extern  objhandle       AskObjHandle( void );
extern  void            PutObjRec(byte,byte*,uint);
extern  void            OpenObj( void );
extern  char            *CopyStr(char*,char*);
extern  void            EmptyQueue( void );
extern  uint            Length(pointer);
extern  void            TellCommonLabel(label_handle, int );
extern  void            TellUnreachLabels(void);
extern  void            KillLblRedirects( void );
/* DF interface */
extern  void            DFObjInitInfo( void );
extern  void            DFObjLineInitInfo( void );
extern  void            DFBegCCU( seg_id code, long dbg_pch );
extern  void            DFDefSegs( void );
extern  void            DFObjFiniDbgInfo( offset codesize );
extern  void            DFObjLineFiniDbgInfo( void );
extern  void            DFLineNum( cue_state *, offset );
extern  void            DFSegRange( void );
extern  void            DFSymRange( sym_handle, offset );
/* CV interface */
extern  void            CVObjInitInfo( void );
extern  void            CVDefSegs( void );
extern  void            CVLineNum( cue_state *, offset );
extern  void            CVObjFiniDbgInfo( void );
/* WV interface */
extern  void            WVObjInitInfo( void );
extern  void            WVTypesEof( void );
extern  void            WVDmpCueInfo( long_offset here );

/* Forward ref's */
static  array_control   *InitArray(int ,int ,int );
extern  seg_id          SetOP(seg_id );
extern  offset          AskLocation(void);
static  void            OutOffset(offset );
static  void            OutInt(int );
extern  void            IncLocation(offset );
static  void            DecLocation(offset );
extern  void            OutDataInt(int );
static  void            ChangeObjSrc( char *fname );
static  void            OutName( char *name, void *dest );
static  void            DoSegment( segdef *seg, array_control *dgroup_def,
                                   array_control *tgroup_def, bool use_16 );
static  void            NeedMore( array_control *arr, int more );
static  void            InitFPPatches(void);
static  void            OutIdx( int value, array_control *dest );
static  void            KillArray( array_control *arr );
static  void            DoSegGrpNames( array_control *dgroup_def,
                                       array_control *tgroup_def );
static  void            OutModel( array_control *dest );
static  void            OutString( char *name, array_control *dest );
static  void            DoASegDef( index_rec *rec, bool use_16 );
static  void            FillArray( array_control *res, int size,
                                   int starting, int increment );
static  void            OutCGroup( int sidx );
static  void            OutGroup( int sidx, array_control *group_def, int *index_p );
static  void            FiniTarg( void );
static  void            NormalData( void );
static  void            KillStatic( array_control *arr );
static  void            FlushObject( void );
static  void            EndModule( void );
static  void            FiniAbsPatches( void );
static  void            OutByte( byte value );
static  void            CheckLEDataSize( int max_size, bool need_init );
static  void            EjectLEData( void );
static  import_handle   GenImport( sym_handle sym, import_type kind );
static  void            FlushSelect( void );
static  void            FlushLineNum( void );
static  void            OutObjectName( sym_handle sym, array_control *dest );
static  void            EjectExports( void );
extern  void            OutSelect( bool starts );
extern  void            OutRTImportRel( int rtindex, fix_class class, bool rel );
extern  void            OutDataByte( byte value );
extern  void            OutDataLong( long value );
static  void            DoFix( int idx, bool rel, base_type base,
                               fix_class class, int sidx );
extern  void            OutDLLExport( uint words, sym_handle sym );
static  void            CheckImportSwitch( bool next_is_static );
static  void            InitLineInfo( void );
static  void            EjectImports( void );
static  void            OutLEDataStart( bool iterated );
#ifndef _OMF_32
static  void            OutLongOffset( long_offset value );
#endif

extern  seg_id          DbgLocals;
extern  seg_id          DbgTypes;

extern  bool            Used87;
extern  byte            OptForSize;


static    array_control *Out;
static    byte          *OutBuff;
static    bool          GenStaticImports;
static    import_handle ImportHdl;
static    array_control *Imports;
static    array_control *SegInfo;
static    abspatch      *AbsPatches;
static    seg_id        CodeSeg = BACKSEGS;
static    seg_id        BackSeg;
static    segdef        *SegDefs;
static    long_offset   CodeSize;
static    long_offset   DataSize;
static    long_offset   DbgTypeSize;
static    index_rec     *CurrSeg;
static    int           GroupIndex;
static    int           DGroupIndex;
static    int           SegmentIndex;
static    int           PrivateIndexRW;
static    int           PrivateIndexRO;
static    int           CodeGroupGIdx;
static    int           CodeGroupNIdx;
static    char          CodeGroup[80];
static    char          DataGroup[80];
static    offset        SelStart;
static    unsigned_16   SelIdx;
static    unsigned      BackSegIdx = BACKSEGS;
static    import_handle FPPatchImp[FPP_NUMBER_OF_TYPES];
static    int           SegsDefd;
static    bool          NoDGroup;
static    short         CurrFNo;
#ifdef _OMF_32
static    int           FlatGIndex;
static    int           FlatNIndex;
#endif
static    int           TLSGIndex;
extern    void          DoOutObjectName(sym_handle,void(*)(char*,void*),void*,import_type);

typedef struct lname_cache lname_cache;

struct lname_cache {
    lname_cache         *next;
    unsigned            idx;
    unsigned_8          name[1];        /* var sized, first byte is length */
};

static  unsigned        NameIndex;
static  lname_cache     *NameCache;
static  lname_cache     *NameCacheDumped;

static char *FPPatchName[] = {
    NULL,
    "FIWRQQ",
    "FIDRQQ",
    "FIERQQ",
    "FICRQQ",
    "FISRQQ",
    "FIARQQ",
    "FIFRQQ",
    "FIGRQQ"
};

static char *FPPatchAltName[] = {
    NULL,
    NULL,
    NULL,
    NULL,
    "FJCRQQ",
    "FJSRQQ",
    "FJARQQ",
    "FJFRQQ",
    "FJGRQQ"
};

typedef struct virt_func_ref_list {
    struct virt_func_ref_list   *next;
    void                        *cookie;
} virt_func_ref_list;

#define _ARRAY( what, type )    (*(type *)((char*)(what)->array + (what)->used))
#define _ARRAYOF( what, type )  ((type *)(what)->array)
#define _CHGTYPE( what, type )  (*(type *)&(what))

extern  void    InitSegDefs( void ) {
/*****************************/

    SegDefs = NULL;
    NameCache = NULL;
    NameCacheDumped = NULL;
    NameIndex = 0;
    GroupIndex = 0;
    DGroupIndex = 0;
    TLSGIndex = 0;
#ifdef _OMF_32
    FlatGIndex = 0;
#endif
    SegsDefd = 0;
    CodeSeg = BACKSEGS; /* just so it doesn't match a FE seg_id */
    BackSegIdx = BACKSEGS;
}

static unsigned GetNameIdx( char *name, char *suff, bool alloc )
{
    lname_cache         **owner;
    lname_cache         *curr;
    unsigned            name_len;
    unsigned            suff_len;

    name_len = Length( name );
    suff_len = Length( suff );
    owner = &NameCache;
    for( ;; ) {
        curr = *owner;
        if( curr == NULL )
            break;
        if( (name_len + suff_len) == curr->name[0]
          && memcmp( name, &curr->name[1], name_len ) == 0
          && memcmp( suff, &curr->name[name_len+1], suff_len ) == 0 ) {
            return( curr->idx );
        }
        owner = &curr->next;
    }
    if( !alloc )
        return( 0 );
    _Alloc( curr, sizeof( *curr ) + name_len + suff_len );
    *owner = curr;
    curr->next = NULL;
    curr->idx = ++NameIndex;
    assert(( name_len + suff_len ) < 256 );
    curr->name[0] = name_len + suff_len;
    memcpy( &curr->name[1], name, name_len );
    memcpy( &curr->name[name_len+1], suff, suff_len );
    return( NameIndex );
}

static void FlushNames( void )
{
    /*
        don't want to allocate memory because we might be in a low memory
        situation
    */
    unsigned_8          buff[512];
    unsigned            i;
    lname_cache         *dmp;

    i = 0;
    dmp = NameCacheDumped != NULL ? NameCacheDumped->next : NameCache;
    for( ; dmp != NULL; dmp = dmp->next ) {
        if( (i + dmp->name[0]) > (sizeof( buff ) - 1) ) {
            PutObjRec( CMD_LNAMES, buff, i );
            i = 0;
        }
        buff[i++] = dmp->name[0];
        _CopyTrans( &dmp->name[1], &buff[i], dmp->name[0] );
        i += dmp->name[0];
        NameCacheDumped = dmp;
    }
    if( i > 0 ) {
        PutObjRec( CMD_LNAMES, buff, i );
    }
}

bool FreeObjCache( void )
{
    lname_cache         *tmp;

    if( NameCache == NULL )
        return( FALSE );
    FlushNames();
    while( NameCache != NULL ) {
        tmp = NameCache->next;
        _Free( NameCache, sizeof( *NameCache ) + NameCache->name[0] );
        NameCache = tmp;
    }
    NameCacheDumped = NULL;
    return( TRUE );
}

extern  void    DefSegment( seg_id id, seg_attr attr, char *str, uint align, bool use_16 ) {
/******************************************************************************************/

    segdef              *new;
    segdef              **owner;
    seg_id              first_code;

    _Alloc( new, sizeof( segdef ) );
    new->id = id;
    new->attr = attr;
    new->align = align;
    _Alloc( new->str, Length( str ) + 1 );
    CopyStr( str, new->str );
    owner = &SegDefs;
    while( *owner != NULL ) {
        owner = &(*owner)->next;
    }
    first_code = BACKSEGS;
    *owner = new;
    new->next = NULL;
    if( attr & EXEC ) {
        if( CodeSeg == BACKSEGS ) {
            CodeSeg = id;
            first_code = id;
        }
        if( OptForSize == 0 && new->align < 16 ) {
            new->align = 16;
        }
    }
    if( attr & BACK ) {
        BackSeg = id;
    }
    if( NameIndex != 0 ) {    /* already dumped out segments*/
        DoSegment( new, NULL, NULL, use_16 ); /* don't allow DGROUP after BEStart */
        SegDefs = NULL;
    }
    if( first_code != BACKSEGS && _IsModel( DBG_DF ) ) {
        DFBegCCU( first_code, 0 );
    }
}

static void DoEmptyQueue( void )
/*******************/
{
    EmptyQueue();
    TellUnreachLabels();
}

static  index_rec       *AskSegIndex( seg_id seg ) {
/**************************************************/

    index_rec   *rec;
    int         i;

    i = 0;
    rec = SegInfo->array;
    for( ;; ) {
        if( ++i > SegInfo->used )
            return( NULL );
        if( rec->seg == seg )
            return( rec );
        ++rec;
    }
}



extern  void    ObjInit( void ) {
/*************************/

    array_control       *names; /* for LNAMES*/
    array_control       *dgroup_def;
    array_control       *tgroup_def;
    void                *depend;

#define MODEST_HDR 50
#define INCREMENT_HDR 50

#define MODEST_INFO 5
#define INCREMENT_INFO 5

    InitFPPatches();
    CodeSize = 0;

⌨️ 快捷键说明

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