rscobj.c

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

C
1,178
字号
/****************************************************************************
*
*                            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:  Object file output for RISC architectures.
*
****************************************************************************/


#include <unistd.h>
#include <assert.h>
#include <string.h>
#include "standard.h"
#include "coderep.h"
#include "cgaux.h"
#include "offset.h"
#include "optopts.h"
#include "optlbl.h"
#include "ocentry.h"
#include "sysmacro.h"
#include "reloc.h"
#include "cgswitch.h"
#include "model.h"
#include "dbcue.h"
#include "import.h"
#include "owl.h"
#include "rtclass.h"
#include "rscobj.h"
#include "autodep.h"
#include "procdef.h"
#include "axpencod.h"
#include "feprotos.h"

extern  pointer         CGAlloc( unsigned size );
extern  void            CGFree( pointer );
extern  void            CloseObj( void );
extern  void            OpenObj( void );
extern  void            PutObjBytes( const char *, uint );
extern  sym_handle      AskForLblSym( label_handle );
extern  label_handle    AskForSymLabel( sym_handle, cg_class );
extern  label_handle    AskForLabel( sym_handle );
extern  char            *AskRTName( int );
extern  void            TryScrapLabel( code_lbl * );
extern  char            *CopyStr(char*,char*);
extern  void            DoOutObjectName(sym_handle,void(*)(char*,void*),void*,import_type);
extern  bool            SymIsExported( sym_handle );
extern  bool            AskIfRTLabel( code_lbl * );
extern  code_lbl        *GetWeirdPPCDotDotLabel( code_lbl * );
extern  code_lbl        *RTLabel( int );
extern  void            TellAddress( code_lbl *, offset );
extern  type_length     TempLocation( name * );
extern  pointer         SymBack( pointer );
extern  void            EmptyQueue( void );
extern  void            TellUnreachLabels( void );
extern  void            *SortList( void *, unsigned, bool (*)( void *, void * ) );
extern  void            EmitInsReloc( axp_ins, pointer, owl_reloc_type );

/* DF interface */
extern  void            DFObjInitInfo( void );
extern  void            DFObjLineInitInfo( void );
extern  void            DFBegCCU( seg_id code, long sym );
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            CVDefSymNormal( void );
extern  void            CVDefSymComdat( owl_section_handle depof );
extern  void            CVLineNum( cue_state *, offset );
extern  void            CVObjFiniDbgInfo( void );

static  owl_section_handle      owlTocSect; // contributions to TOC for PPC
static  owl_section_handle      globalPdata;



static  owl_handle              owlHandle;
static  owl_file_handle         owlFile;

static  seg_id                  codeSection;
static  seg_id                  dataSection;
static  seg_id                  backSectIdx;

static  section_def             *currSection;

#define N_SECTIONS              16

static  section_def             *sectionDefs[ N_SECTIONS ];

extern  int                     ObjFile;
static  short                   CurrFNo;
extern  proc_def                *CurrProc;

extern section_def *FindSection( seg_id id ) {
/********************************************/

    section_def         *curr;

    curr = sectionDefs[ id % N_SECTIONS ];
    while( curr != NULL ) {
        if( curr->id == id ) break;
        curr = curr->next;
    }
    return( curr );
}

extern section_def *AddSection( seg_id id ) {
/*******************************************/

    section_def         *new;
    unsigned            bucket;

    _Alloc( new, sizeof( section_def ) );
    bucket = id % N_SECTIONS;
    new->id = id;
    new->next = sectionDefs[ bucket ];
    sectionDefs[ bucket ] = new;
    new->func  = NULL;
    new->is_start = TRUE;
    return( new );
}

static void DeleteSections( void ) {
/**********************************/

    unsigned            bucket;
    section_def         *ptr;
    section_def         *next;

    for( bucket = 0; bucket < N_SECTIONS; bucket++ ) {
        if( sectionDefs[ bucket ] != NULL ) {
            for( ptr = sectionDefs[ bucket ]; ptr != NULL; ptr = next ) {
                next = ptr->next;
                _Free( ptr, sizeof( section_def ) );
            }
            sectionDefs[ bucket ] = NULL;
        }
    }
}

extern owl_section_handle DbgSectDefComdat( char *str ){
/************************************************/
    owl_section_handle  owl_handle;

    owl_handle = OWLSectionInit( owlFile, str, OWL_SECTION_COMDAT_DEBUG, 1 );
    return( owl_handle );
}

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

    OpenObj();
    CurrFNo = 0;
    if( _IsModel( DBG_DF ) ) {
        if( _IsModel( DBG_LOCALS | DBG_TYPES ) ){
            DFDefSegs();
            DFObjInitInfo();
#if 0 //save for jimr
        }else if( _IsModel( NUMBERS ) ){
            DFDefSegs();
            DFObjLineInitInfo();
#endif
        }
    }else if( _IsModel( DBG_CV ) ) {
        CVDefSegs();
        CVObjInitInfo();
    }
}


#if 1
static  void    DefaultLibs( void ){
/***********************************/
    char               *lib;
    char               *name;
    owl_section_handle  comments;

    comments = NULL;
    lib = NULL;
    for(;;) {  //Library dependencies
        lib = FEAuxInfo( lib, NEXT_LIBRARY );
        if( lib == NULL ) break;
        name =  (char*)FEAuxInfo( lib, LIBRARY_NAME ) + 1;
        if( name == NULL || *name == '\0' ) continue;
        if( comments == NULL ){
            comments = OWLSectionInit( owlFile, ".drectve", OWL_SECTION_INFO, 1 );
            if( comments == NULL )break;
        }
        OWLEmitData( comments, COMMENTV( COFF_DRECTVE_DEFLIB ) );
        OWLEmitData( comments, name, strlen( name ) );
        OWLEmitData( comments, " ", 1 );
    }
    if( comments != NULL ) {
        OWLEmitData( comments, "", 1 );
    }
}
#endif

static void stringOut( char *name, void *data )
/*********************************************/
{
    *(char **)data = name;
}

static  void    EmitImports( void ) {
/***********************************/

    void        *auto_import;
    char        *name;

    auto_import = NULL;
    for(;;) {
        auto_import = FEAuxInfo( auto_import, NEXT_IMPORT );
        if( auto_import == NULL )
            break;
        OWLEmitImport( owlFile, FEAuxInfo( auto_import, IMPORT_NAME ) );
    }
    auto_import = NULL;
    for(;;) {
        auto_import = FEAuxInfo( auto_import, NEXT_IMPORT_S );
        if( auto_import == NULL )
            break;
        DoOutObjectName( FEAuxInfo( auto_import, IMPORT_NAME_S ),
                         stringOut, &name, NORMAL );
        OWLEmitImport( owlFile, name );
    }
}

// FIXME - should likely be different for ELF under OS/2 et al
// and should match stuff in langenv (except we need runtime dependency on OS,
// not compile time).
static char *dependSectionName = ".depend";

static  void    EmitDependencyInfo( void )
/****************************************/
{
    owl_section_handle  sect;
    void                *depend;
    char                *name;
    DepInfo             info;

    sect = NULL;
    depend = NULL;
    for(;;) {
        depend = FEAuxInfo( depend, NEXT_DEPENDENCY );
        if( depend == NULL ) break;
        if( sect == NULL ) {
            sect = OWLSectionInit( owlFile, dependSectionName, OWL_SECTION_INFO, 16 );
        }
        name = (char *)FEAuxInfo( depend, DEPENDENCY_NAME );
        info.time = *(time_t *)FEAuxInfo( depend, DEPENDENCY_TIMESTAMP );
        info.len = strlen( name ) + 1;
        OWLEmitData( sect, (char *)&info, sizeof( DepInfo ) - 1 );
        OWLEmitData( sect, (char *)name, strlen( name ) + 1 );
    }
    /* put out a handy little sentinel value at the end */
    if( sect != NULL ) {
        info.len = 0;
        OWLEmitData( sect, (char *)&info, sizeof( DepInfo ) );
    }
}


static void DoDFSegRange( void )
/******************************/
{
    unsigned            bucket;
    section_def         *ptr;
    section_def         *old;
    owl_section_type    tipe;

    old = currSection;
    for( bucket = 0; bucket < N_SECTIONS; bucket++ ) {
        if( sectionDefs[ bucket ] != NULL ) {
            for( ptr = sectionDefs[ bucket ]; ptr != NULL; ptr = ptr->next ) {

                tipe = OWLTellSectionType( ptr->owl_handle );
                switch( tipe ){
                case OWL_SECTION_INFO:
                case OWL_SECTION_DEBUG:
                case OWL_SECTION_PDATA:
                case OWL_SECTION_COMDAT_DEBUG:
                    break;
                case OWL_SECTION_COMDAT_PDATA:
                case OWL_SECTION_CODE:
                case OWL_SECTION_DATA:
                case OWL_SECTION_BSS:
                case OWL_SECTION_COMDAT_CODE:
                case OWL_SECTION_COMDAT_DATA:
                // took this out - can't drop a 2nd static label in a comdat bss
                // section - there can be only one!
                // case OWL_SECTION_COMDAT_BSS:
                    currSection = ptr;
                    DFSegRange();
                    break;
                }
            }
        }
    }
    currSection = old;
}

extern  void    ObjFini( void )
/*****************************/
{
    offset          code_size;
    section_def     *curr;

    curr = FindSection( codeSection );
    code_size = OWLTellSize( curr->owl_handle  );

    if( _IsModel( DBG_DF ) ) {
        if( _IsModel( DBG_LOCALS | DBG_TYPES ) ) {
            DoDFSegRange();
            DFObjFiniDbgInfo( code_size );
#if 0 // save for jimr
        } else if( _IsModel( NUMBERS ) ) {
            DFObjLineFiniDbgInfo();
#endif
        }
    } else if( _IsModel( DBG_CV ) ) {
        CVObjFiniDbgInfo();
    }
    DefaultLibs();
    EmitImports();
    EmitDependencyInfo();
    OWLFileFini( owlFile );
    OWLFini( owlHandle );
    DeleteSections();
    CloseObj();
    FEMessage( MSG_CODE_SIZE, (pointer)code_size );
//    FEMessage( MSG_DATA_SIZE, (pointer)data_size );
}

// FIXME: This sucks - but time runneth out
#define MAGIC_FLAG      0

static  int     PutBytes( void *handle, const char *buffer, uint len )
/********************************************************************/
{
    handle = handle;
#ifndef NDEBUG
    // enable OWL logging
    if( handle == MAGIC_FLAG ) {
        PutObjBytes( buffer, len );
    } else {
        write( (int)handle, buffer, len );
    }
#else
    PutObjBytes( buffer, len );
#endif
    return( len );
}


#define MAX_OBJ_NAME    1024

static  char            objName[ MAX_OBJ_NAME ];

static  void            NameGatherer( char *name, void *data )
/************************************************************/
{
    CopyStr( name, (char *)data );
}

static  char            *LabelName( code_lbl *label )
/***************************************************/

⌨️ 快捷键说明

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