s37txt.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,685 行 · 第 1/4 页
C
1,685 行
/****************************************************************************
*
* 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 <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "standard.h"
#include "sysmacro.h"
#include "cg.h"
#include "cgaux.h"
#include "bckdef.h"
#include "targsys.h"
#include "system.h"
#include "offset.h"
#include "s37bead.h"
#include "obj370.h"
#include "model.h"
#include "zoiks.h"
typedef int handle;
extern handle ObjFile;
extern pointer FEAuxInfo(pointer*,aux_class);
extern int Length( char* );
extern void PLBlip();
extern void CloseStream(handle );
extern void PutObjRec(int ,void *,uint );
typedef struct src_fi {
handle fi;
int curr_line;
char *curr;
char buff[80+1];
} src_fi;
extern src_fi *CGSrcOpen(src_fi *,char *);
extern int CGSrcGet(src_fi *,char *,int ,int );
extern void CGSrcClose(src_fi *);
typedef struct asm_fi asm_fi;
extern asm_fi *AsmOpen(char *,int ,bool );
extern void PutLine(asm_fi *,char *,int );
extern void AsmClose(asm_fi *);
extern void PutStream(handle ,byte *,uint );
extern int OpenObj(char *);
extern void CloseObj(void);
extern hwop_info const HWOpTable[];
extern int const HWOpICL[];
static char const BRMnem[16][4]={
"NOP",
"BO",
"BH",
"",
"BL",
"",
"",
"BNE",
"BE",
"",
"",
"BNL",
"",
"BNH",
"BNO",
"B"
};
static const rec_tag tag_ESD = { PUNCH_12_2_9, { 0xC5,0xE2,0xC4 } };
static const rec_tag tag_TXT = { PUNCH_12_2_9, { 0xE3,0xE7,0xE3 } };
static const rec_tag tag_RLD = { PUNCH_12_2_9, { 0xD9,0xD3,0xC4 } };
static const rec_tag tag_END = { PUNCH_12_2_9, { 0xC5,0xD5,0xC4 } };
typedef enum {
LST_NONE = 0x00,
LST_ASM = 0x01,
LST_SRC = 0x02,
LST_OBJ = 0x04
} lst_opts;
typedef struct asm_obj {
char label[8];
char sep1[1];
char code[5];
char sep2[1];
char ops[24];
char sep3[1];
char com[31];
char cont[1];
char id[8];
}asm_obj;
typedef struct obj_area {
char c[32];
}obj_area;
typedef struct use_info {
offset base_disp;
char base_reg;
}use_info;
typedef struct txt_obj {
offset address;
short int csect;
short int rem;
char *curr;
txt_record rec;
use_info using;
lst_opts opts;
src_fi *srcfi;
asm_fi *asmfi;
asm_obj *asm;
obj_area *ocodes;
int size;
char line[122];
} txt_obj;
#define TXT_MAX 56
typedef struct rld_obj {
short int csect;
short int rem;
char *curr;
rld_record rec;
} rld_obj;
#define RLD_MAX 56
#include "s37txt.def"
/* file types */
#if _HOSTOS & _CMS
#define TXT_SUFFIX " text"
#define ASM_SUFFIX " assemble"
#define LST_SUFFIX " lst"
#else
#define TXT_SUFFIX ".tex"
#define ASM_SUFFIX ".asm"
#define LST_SUFFIX ".lst"
#endif
extern void GenTXT( bead_xsym *entry, txtseg_rec *rec ) {
/*** generate ESD TXT RLD END for segment *************/
char datname[20];
if( rec->txtseg == TXT_DATA ) { /* abit crude for now */
CloseObj();
strcpy( datname, rec->csect->sym->name );
strcat( datname, TXT_SUFFIX );
ObjFile = OpenObj( datname );
}
EsdRecs( rec );
TxtRecs( entry, rec );
RldRecs( rec );
EndRecs( entry, rec );
}
static void ESDInitRec ( esd_record *rec ) {
/*************************************/
memset( rec, 0x40, sizeof( esd_record ) );
rec->tag= tag_ESD;
}
static void EsdRecs( txtseg_rec *rec ) {
/*** set psdid esdid's write ESDS, look for cross seg refs ***/
/*** also give local labels a name if a listing is being made ***/
esd_record esds;
esd_item *curr_item;
int pesdid;
int csectid;
int rec_set;
offset sym_off;
bead_def *bead;
int refno;
ESDInitRec( &esds );
pesdid = 1;
rec_set = FALSE;
csectid = 1;
bead = rec->first;
curr_item = &esds.items[0];
if( _IsModel( ASM_OUTPUT ) || _IsModel( ASM_LISTING ) ) {
refno = 1;
}else{
refno = 0;
}
while( bead ) {
if( bead->class == BEAD_XSYM ) {
if( curr_item >= &esds.items[3] ) {
Stick16( &esds.size,(char*)curr_item - (char*)&esds.items[0] );
PutObjRec( ObjFile, &esds, 80 );
ESDInitRec( &esds );
curr_item = &esds.items[0];
rec_set = FALSE;
}
memset( curr_item->name, 0x40, 8 );
TXTSym( curr_item->name, ((bead_xsym *)bead)->sym, TRUE );
switch( ((bead_xsym *)bead)->class ) {
case XSYM_CSECT:
((bead_xsym *)bead)->id = pesdid;
curr_item->type = ESDT_SD;
Stick24( &curr_item->addr, bead->address );
Stick24( &curr_item->extra, rec->location );
curr_item->align = ((bead_xsym*)bead)->armode;
if( !rec_set ) {
Stick16( &esds.esdid, pesdid );
rec_set = TRUE;
}
csectid = pesdid;
pesdid++;
break;
case XSYM_EXTRN:
/* in case of more than one extern */
((bead_xsym *)bead)->sym->def = bead;
((bead_xsym *)bead)->id = pesdid;
curr_item->type = ESDT_ER;
if( !rec_set ) {
Stick16( &esds.esdid, pesdid );
rec_set = TRUE;
}
pesdid++;
break;
case XSYM_ENTRY:
((bead_xsym *)bead)->id = csectid;
curr_item->type = ESDT_LD;
sym_off = ((bead_xsym *)bead)->sym->def->address;
Stick24( &curr_item->addr, sym_off );
Stick24( &curr_item->extra, csectid );
break;
}
curr_item++;
}else if( bead->class == BEAD_ADDR ) {
FixRef( rec, (bead_addr*)bead );
}else if( refno > 0 && bead->class == BEAD_LABEL ){
/** if a local sym doesn't have a name give it one ***/
hw_sym *sym;
sym = ((bead_label *)bead)->sym;
if( sym->name[0] == '\0' ){
sym->name[0] = '#';
itoa( refno, &sym->name[1], 10 );
++refno;
}
}
bead = bead->next;
}
if( curr_item > &esds.items[0] ) {
Stick16( &esds.size, (char *)curr_item - (char*)&esds.items[0] );
PutObjRec( ObjFile, &esds, 80 );
}
}
static void FixRef( txtseg_rec *rec, bead_addr *bead ) {
/*** change a ref to a sym in another CSECT to CSECT+offset ***/
hw_sym *sym;
sym = bead->ref;
if( !(sym->defflag & rec->txtseg) ) {
bead->val += sym->def->address;
bead->ref = rec->other->sym;
}
}
static void InitTxtObj( txt_obj *obj ) {
/*************************************/
memset( &obj->rec, 0x40, sizeof( obj->rec ) );
obj->rec.tag = tag_TXT;
obj->rem = TXT_MAX;
obj->address = 0;
obj->curr = obj->rec.info;
obj->opts = LST_NONE;
obj->using.base_reg = 0;
obj->using.base_disp = -1;
}
static void TxtFlush( txt_obj *obj ) {
/*************************************/
int size;
size = TXT_MAX - obj->rem;
if( size != 0 ) {
Stick16( &obj->rec.esdid, obj->csect );
Stick24( obj->rec.faddr, obj->address );
Stick16( obj->rec.size, size );
PutObjRec( ObjFile, &obj->rec, 80 );
obj->rem = TXT_MAX;
obj->curr = obj->rec.info;
obj->address += size;
memset( obj->rec.info, 0x40, sizeof( obj->rec.info ) );
}
}
static void PutAsm( txt_obj *obj ) {
/*************************************/
PutLine( obj->asmfi, obj->line, obj->size );
memset( &obj->line, ' ', obj->size );
}
static void TxtOut( txt_obj *obj, offset address, char *dat, int len ) {
/*****************************************************/
int size;
size = TXT_MAX- obj->rem;
if( obj->address+size != address ) { /* do an ORG */
TxtFlush( obj );
obj->address = address;
}
while( len > 0 ) {
if( obj->rem == 0 ) {
TxtFlush( obj );
}
*obj->curr++ = *dat++;
obj->rem--;
len--;
}
}
static void TxtRecs( bead_xsym *entry, txtseg_rec *rec ) {
/*****************************************/
txt_obj txt;
src_fi src_entry;
char datname[20];
InitTxtObj( &txt );
if( _IsModel( ASM_OUTPUT ) ) {
txt.opts = LST_ASM;
if( _IsModel( ASM_SOURCE ) ) {
txt.srcfi = CGSrcOpen( &src_entry, FEAuxInfo( NULL, SOURCE_NAME ) );
txt.opts |= LST_SRC;
}else{
txt.srcfi = NULL;
}
memset( &txt.line, ' ', sizeof( txt.line ) );
if( _IsModel( ASM_LISTING ) ) {
txt.opts |= LST_OBJ;
txt.asm = (asm_obj *)&txt.line[sizeof(obj_area)+1];
txt.ocodes = (obj_area *)&txt.line[0];
txt.size = 121;
} else {
txt.asm = (asm_obj *)&txt.line[0];
txt.size = 80;
}
if( rec->txtseg == TXT_DATA ) { /* abit crude for now */
strcpy( datname, rec->csect->sym->name );
strcat( datname, txt.opts & LST_OBJ ? LST_SUFFIX:ASM_SUFFIX );
txt.asmfi = AsmOpen( datname, txt.size, txt.opts & LST_OBJ );
} else {
txt.asmfi = AsmOpen( FEAuxInfo( NULL, ASM_NAME ), txt.size,
txt.opts & LST_OBJ );
}
}
PutBeads( &txt, rec->first );
if( txt.opts & LST_SRC ) {
CGSrcClose( txt.srcfi );
}
if( txt.opts & LST_ASM ) {
fmt_str( txt.asm->code, "END" );
if( entry != NULL ) {
OutSym( txt.asm->ops, entry->sym, TRUE );
}
PutAsm( &txt );
AsmClose( txt.asmfi );
}
TxtFlush( &txt );
}
static void PutBeads( txt_obj *obj, bead_def *bead ){
/************************/
while( bead != NULL ) {
PLBlip();
switch( bead->class ) {
case BEAD_HWINS:
case BEAD_BR:
DmpHwIns( obj, (any_bead_hwins*)bead );
break;
case BEAD_LABEL:
DmpLabel( obj, (bead_label*)bead );
break;
case BEAD_DATA:
DmpData( obj, (bead_data*)bead );
break;
case BEAD_BINDEX:
DmpBindex( obj, (bead_bindex*)bead );
break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?