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