s37obj.c

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

C
1,459
字号
/****************************************************************************
*
*                            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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "standard.h"
#include "sysmacro.h"
#include "cg.h"
#include "cgaux.h"
#include "bckdef.h"
#include "offset.h"
#include "model.h"
#include "s37bead.h"
#include "s37page.h"

#include "s37obj.def"

static    index_rec     *CurrIndex;
static    index_rec     *IndexRecs;
static    hw_sym        *HWSyms;
static    segdef        *SegDefs;
static    seg_id        CodeSeg;
static    seg_id        BackSeg;

extern  pointer         FEAuxInfo(pointer*,aux_class);
extern  void            FEMessage(msg_class,pointer);
extern  double          CFToF( pointer );
extern void GenTXT(bead_xsym *, txtseg_rec * );
extern void DbgIO( txtseg_rec * );
extern void HWMakePages( bead_def *start );

extern hwop_info const HWOpTable[] = {
    #define _ENC_OP( op, cl, cd ) #op, HWOP_##op, cl, cd,
    #include "s37ops.h"
    #undef _ENC_OP
};

static int const HwLength[] = {
    sizeof( bead_hwins_rr ),
    sizeof( bead_hwins_rx ),
    sizeof( bead_hwins_rs1 ),
    sizeof( bead_hwins_rs2 ),
    sizeof( bead_hwins_si ),
    sizeof( bead_hwins_s ),
    sizeof( bead_hwins_ss1 ),
    sizeof( bead_hwins_ss2 ),
    sizeof( bead_hwins_ssp )
};

int const HWOpICL[]= {
     2  /* rr  */,
     4  /* rx  */,
     4  /* rs1 */,
     4  /* rs2 */,
     4  /* si  */,
     4  /* s   */,
     6  /* ss1 */,
     6  /* ss2 */,
     6  /* ssp */
};


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



extern void AbortObj() {
/**********************/

}

extern void SetDataOffsets( offset location ) {
/*********************************
 Need to collect and set addr on all data that is
 fixed at codegen time so we can base off temp in code
*/

    segdef *curr;
    index_rec *rec;
    bead_def  *bead;

    curr = SegDefs;
    while( curr != NULL ) { /* link segments to correct txtseg */
        if( !(curr->attr & ( ROM | EXEC ))  ) { /* if not code */
            rec =  AskSegIndex( curr->id );
            location = HWCalcAddr( rec->first, location );
            bead = rec->first;
            while( bead != NULL ){
                if( bead->class == BEAD_LABEL ){
                    ((bead_label *)bead)->sym->class = HW_FIXED;
                }
                bead = bead->next;
            }
        }
        curr = curr->next;
    }
}

extern  void    ObjFini() {
/**************************/
    index_rec *rec;
    txtseg_rec  code;
    txtseg_rec  data;
    bead_xsym *entry;
    bead_startproc *last;

    rec =  AskSegIndex( AskCodeSeg() );
    last = LinkProcs( rec->first );
    if( !(_IsModel( DBG_LOCALS ) || _IsModel( DBG_TYPES )) ) {
        PeepS370( last );
    }
    HWMakePages( rec->first );
    if(  FEAuxInfo( NULL, AUX_HAS_MAIN ) ) {
        entry = MKMain( &rec->first->next );
    } else {
        entry = NULL;
    }
   MKTxtSegs( &code, &data );
   if( _IsModel( DBG_LOCALS ) || _IsModel( DBG_TYPES ) ) {
       DbgIO( &code ); /* adds to code txtseg_rec */
   }
// HWShortRefs( last );
   GenTXT( entry, &code );
   FreeBeads( code.first );
   if( _IsModel( CODE_SPLIT ) || _IsModel( CODE_RENT ) ) {
       GenTXT( NULL, &data );
       FreeBeads( data.first );
   }
   FreeHWSyms( HWSyms );
   FEMessage( MSG_CODE_SIZE, (pointer)code.location );
// FEMessage( MSG_DATA_SIZE, (pointer)data.location );
}

static void MKTxtSegs( txtseg_rec *code, txtseg_rec *data ) {
/*** collect CODE and DATA segements add CSECTS ******/
    segdef *curr;
    index_rec *rec;
    bead_xsym *xcode;

    InitTxtSeg( code, TXT_CODE );
    InitTxtSeg( data, TXT_DATA );
    curr = SegDefs;
    while( curr != NULL ) { /* link segments to correct txtseg */
        rec =  AskSegIndex( curr->id );
        if( rec->first != NULL ) {
            if( rec->txtseg == code->txtseg ) {
                *code->end_lnk = rec->first;
                code->end_lnk  = rec->end_lnk;
            } else {
                *data->end_lnk = rec->first;
                data->end_lnk  = rec->end_lnk;
            }
        }
        curr = curr->next;
    }
    code->csect = MakeCsect( &code->first, TXT_CODE );
    if( _IsModel( CODE_SPLIT ) || _IsModel( CODE_RENT ) ) {
        data->csect = MakeCsect( &data->first, TXT_DATA );
        xcode = HWMKExSym( &data->first->next, HW_EXTERN );
        xcode->sym = code->csect->sym;
        data->other = xcode;
        xcode = HWMKExSym( &code->first->next, HW_EXTERN );
        xcode->sym = data->csect->sym;
        code->other = xcode;
        data->location = HWCalcAddr( data->first, 0 );
    } else if( data->first != NULL )  {/* if not split link up code to data */
        *code->end_lnk = data->first;
        code->end_lnk  = data->end_lnk;
        code->other = code->csect;
    }
    code->location = HWCalcAddr( code->first, 0 );
}

static void InitTxtSeg( txtseg_rec *rec, txtseg_class txtseg ) {
/*** Init a txt segment i.e  code or data***/
    rec->txtseg = txtseg;
    rec->first = NULL;
    rec->end_lnk = &rec->first;
    rec->csect = NULL;
    rec->other = NULL;
    rec->location = 0;
}

static bead_xsym *MakeCsect( bead_def **end_lnk, txtseg_class txtseg ) {
/***********************/
    char       fname[8+1];
    bead_xsym *bead;
    hw_sym    *sym;
    csect_mode armode;

    bead = HWMKExSym( end_lnk, XSYM_CSECT );  /* an CSECT defines a sym */
    GetCsectName( fname, txtseg );
    sym = HWSymAdd( &HWSyms, fname );
    sym->def = (bead_def *)bead;
    sym->defflag = txtseg;
    if( _IsModel( AMODE_24 ) ) {
        armode = CSECT_AMODE_24;
    }else if( _IsModel( AMODE_31 ) ) {
        armode = CSECT_AMODE_31;
    } else {
        armode = CSECT_AMODE_ANY;
    }
    if( _IsntModel( RMODE_24 ) ) {
        armode |= CSECT_RMODE_ANY;
    }
    bead->armode = armode;
    bead->sym = sym;
    return( bead );
}

static void GetCsectName( char *fname, txtseg_class txtseg ) {
/**** make a CSECT name ************************************/
    char *curr, *path;
    char *end;

    path =  FEAuxInfo( NULL, CSECT_NAME  );
    curr = fname;
    if( txtseg == TXT_CODE ) {
        *curr++ = '@';
        end = &fname[8];
    } else {
        end = &fname[7];
    }
    while( curr < end && *path != '\0' ) {
        *curr++ = *path++;
    }
    if( txtseg == TXT_DATA ) {
        *curr++ = '@';
    }
    *curr = '\0';
}

static bead_xsym *MKMain( bead_def **end_lnk ) {
/***make ENTRY  $MAIN 0 in csect with branch to $STARTUP **/
/***assume code txtsegment ***/
    hwins_op_any hwop1;
    hwins_op_any hwop2;
    hw_sym    *sym;
    bead_xsym  *entry;
    bead_xsym  *startup;

    sym = HWSymAdd( &HWSyms, "#MAIN" );
    HWMKLabel( end_lnk, sym );
    sym->class = HW_ENTRY;
    end_lnk = &(*end_lnk)->next; /*after added bead */
    entry = HWMKExSym( end_lnk, XSYM_ENTRY  );
    entry->sym = sym;
    end_lnk = &(*end_lnk)->next;
    hwop1.r = 15;    /*assume BALR 14,15 linkage **/
    hwop2.sx.ref = NULL;
    hwop2.sx.disp = 6;
    hwop2.sx.b = 0;
    hwop2.sx.a = 15; /*addressability off R15   **/
    HWMKInsGen( end_lnk, HWOP_L, &hwop1, &hwop2, NULL );
    end_lnk = &(*end_lnk)->next;
    hwop1.r = 15;    /*CC unconditional        ***/
    hwop2.r = 15;    /* 15 linkage **/
    HWMKInsGen( end_lnk, HWOP_BCR, &hwop1, &hwop2, NULL );
    end_lnk = &(*end_lnk)->next;
    sym = HWSymAdd( &HWSyms, "$STARTUP" );
    sym->class = HW_EXTERN;
    sym->defflag = TXT_CODE;
    startup = HWMKExSym( end_lnk, XSYM_EXTRN );
    startup->sym = sym;
    end_lnk = &(*end_lnk)->next;
    HWMKAddrGen( end_lnk, sym, 0 );
    return( entry );
}

extern  void    InitSegDefs() {
/**********************************************/
/* object segments */
    SegDefs = NULL;
    CodeSeg = 0;
    BackSeg = 0;
    IndexRecs = NULL;
    HWSyms = NULL;
}

extern  void    DefSegment( seg_id id, seg_attr attr, char *str, uint align ) {
/**********************************************/
    segdef              *new;
    segdef              **owner;

    _Alloc( new, sizeof( *new ) );
    new->id = id;
    new->attr = attr;
    new->align = align;
    _Alloc( new->str, strlen( str ) + 1 );
    strcpy( new->str,str );
    owner = &SegDefs;
    while( *owner != NULL ) { /* keep in a sorted order */
        if( (*owner)->id >= id )break;
        owner = &(*owner)->next;
    }
    new->next = *owner;
    *owner = new;
    if( AskSegIndex( id ) == NULL ){
        DoASegDef( new );
    }
    if( ( attr & EXEC ) != 0 && CodeSeg == 0 ) {
        CodeSeg = id;
    }
    if( attr & BACK ) {
        BackSeg = id;
    }

}

static void DoASegDef( segdef *seg ) {
/*****************************************/

    index_rec   *rec;
    bead_seg    *first;

    _Alloc( rec, sizeof( *rec ) );
    if( _IsModel( CODE_SPLIT ) || _IsModel( CODE_RENT ) ) {
        if( seg->attr & ( ROM | EXEC )  ) { /* put all read only in code */
            rec->txtseg = TXT_CODE;
        } else { /* rw goes into data */
            rec->txtseg = TXT_DATA;
        }
    } else { /* no split all in code*/
        rec->txtseg = TXT_CODE;
    }
    rec->location = 0;
    first = MKSeg( seg->str, seg->id, seg->align );
    rec->end_lnk  = &first->common.next;
    rec->first = (bead_def *)first;
    rec->next = IndexRecs;
    IndexRecs   = rec;
    rec->seg = seg->id;
}

extern  seg_id  AskCodeSeg() {
/****************************/

    return( CodeSeg );
}


extern  seg_id  AskBackSeg() {
/****************************/
/* returns backend data segment id */
     return( BackSeg );
}


extern  seg_id  SetOP( seg_id seg ) {
/***********************************/

    seg_id      old;

    if( CurrIndex == NULL ) {
        old = (seg_id)-1;
    } else {
        old = CurrIndex->seg;
    }
    if( seg == (seg_id)-1 ) {
        CurrIndex = NULL;
    } else {
        CurrIndex = AskSegIndex( seg );
    }
    return( old );
}

extern  seg_id  AskOP() {
/************************/

    return( CurrIndex->seg );
}


extern  void    FlushOP( seg_id id ) {
/************************************/
/* flush segment out to file */
    id = 0;
}


extern        bool    AskSegBlank( segment_id id )
/************************************************/
{   id = 0;
    return( FALSE );
}


extern        bool    AskSegROM( segment_id id )
/**********************************************/
{
    return( _IsModel( CODE_RENT ) && AskSegIndex( id )->txtseg == TXT_CODE );
}


extern  offset  AskLocation() {
/*****************************/
/* return current offset in segment */

    return( CurrIndex->location );
}


extern  void    SetLocation( offset loc ) {
/**********************************************/
/* seek to loc in segment extend if past end */
    offset curloc;
    char fill = 0;

    curloc = CurrIndex->location;
    if( curloc < loc ) {
        if( _IsModel( NO_ZERO_INIT ) ) {
            HWStoreGen( loc-curloc );
        }else{
            HWDataGen( 1, loc-curloc, &fill );
        }
    }

}

extern  void    TellObjNewProc( sym_handle proc ) {
/***************************************************/
    proc = proc;
}

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

    index_rec   *rec;

    rec = IndexRecs;
    while( rec != NULL ) {
        if( rec->seg == seg ) break;
        rec = rec->next;
    }
    return( rec );
}


extern  void            *InitPatch() {
/**********************************************/
/* ??? */

    return( NULL );
}



extern void             AbsPatch(void * patch,offset lc) {
/**********************************************/
patch = 0;
lc = 0;
}



⌨️ 快捷键说明

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