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