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