objprs.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 848 行 · 第 1/2 页
C
848 行
/****************************************************************************
*
* 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 <string.h>
#include "pcobj.h"
#include "watcom.h"
#include "womp.h"
#include "objprs.h"
#include "memutil.h"
#include "genutil.h"
#include "fixup.h"
#include "objio.h"
#include "myassert.h"
#include "queue.h"
#include "objrec.h"
#include "canmisc.h"
typedef struct jump_list jlist;
struct jump_list {
jlist *next;
pobj_filter func;
};
#define JUMP_OFFSET(cmd) ((cmd)-CMD_POBJ_MIN_CMD)
STATIC jlist *readJump[ CMD_MAX_CMD - CMD_POBJ_MIN_CMD + 1 ];
STATIC jlist *writeJump[ CMD_MAX_CMD - CMD_POBJ_MIN_CMD + 1 ];
STATIC struct {
qdesc records; /* queue of records from READ_PASS */
qdesc insert; /* queue of records after current rec */
qdesc pub; /* queue of pubdefs */
uint_16 segdef_idx; /* last segdef index */
uint_16 grpdef_idx; /* last grpdef index */
uint_16 extdef_idx; /* last extdef index */
uint_16 lnames_idx; /* last lnames index */
uint_16 dgroup_idx; /* DGROUP name index */
uint_16 flat_idx; /* FLAT name index */
obj_rec *last_defn; /* last defn (SEGDEF, GRPDEF, LNAMES,...) rec */
obj_rec *last_data_rec; /* pointer to obj_rec of last le/lidata */
fixinfo *fix_info; /* info for fixups */
size_t page_len; /* if is_lib then page size */
pobj_state state; /* state we'll pass to filters */
uint_8 is_phar : 1; /* is this a pharlap object deck? */
} loc;
#define DGROUP_NAME_VALUE "DGROUP"
#define DGROUP_NAME_LEN (6)
#define FLAT_NAME_VALUE "FLAT"
#define FLAT_NAME_LEN (4)
uint_16 ObjDGROUPIndex;
uint_16 ObjFLATIndex;
void PObjInit( void ) {
/*******************/
memset( readJump, 0, sizeof( readJump ) );
memset( writeJump, 0, sizeof( writeJump ) );
}
void PObjFini( void ) {
/*******************/
jlist *cur;
jlist *next;
unsigned i;
for( i = CMD_POBJ_MIN_CMD; i <= CMD_MAX_CMD; ++i ) {
cur = readJump[ JUMP_OFFSET( i ) ];
while( cur != NULL ) {
next = cur->next;
MemFree( cur );
cur = next;
}
cur = writeJump[ JUMP_OFFSET( i ) ];
while( cur != NULL ) {
next = cur->next;
MemFree( cur );
cur = next;
}
}
}
void PObjRegister( uint_8 command, uint_8 pass, pobj_filter func ) {
/****************************************************************/
jlist *new;
new = MemAlloc( sizeof( *new ) );
new->func = func;
switch( pass ) {
case POBJ_READ_PASS:
new->next = readJump[ JUMP_OFFSET( command ) ];
readJump[ JUMP_OFFSET( command ) ] = new;
break;
case POBJ_ALL_PASSES:
PObjRegister( command, POBJ_READ_PASS, func );
/* fall through */
case POBJ_WRITE_PASS:
new->next = writeJump[ JUMP_OFFSET( command ) ];
writeJump[ JUMP_OFFSET( command ) ] = new;
break;
default:
/**/ never_reach();
}
}
void PObjUnRegister( uint_8 command, uint_8 pass, pobj_filter func ) {
/******************************************************************/
jlist **walk;
jlist *old;
switch( pass ) {
case POBJ_READ_PASS:
walk = &readJump[ JUMP_OFFSET( command ) ];
break;
case POBJ_ALL_PASSES:
PObjUnRegister( command, POBJ_READ_PASS, func );
/* fall through */
case POBJ_WRITE_PASS:
walk = &writeJump[ JUMP_OFFSET( command ) ];
break;
default:
/**/ never_reach();
}
while( *walk != NULL ) {
if( (*walk)->func == func ) {
old = *walk;
*walk = old->next; /* unlink from list */
MemFree( old );
return;
}
walk = &(*walk)->next;
}
/**/never_reach();
}
void PObjEnqueue( obj_rec *objr ) {
/*******************************/
/**/myassert( objr != NULL );
/**/myassert( loc.state.pass == POBJ_WRITE_PASS );
QEnqueue( &loc.insert, objr );
}
void PObjJoinQueue( qdesc *src ) {
/******************************/
/**/myassert( src != NULL );
/**/myassert( loc.state.pass == POBJ_WRITE_PASS );
QJoinQueue( &loc.insert, src );
}
STATIC int pass1Coment( obj_rec *objr ) {
int ret;
uint_8 *p;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_COMENT );
ret = 0; /* we'll pass on in most cases */
objr->d.coment.attr = ObjGet8( objr );
objr->d.coment.class = ObjGet8( objr );
switch( objr->d.coment.class ) {
case CMT_EASY_OMF:
if( ObjRemain( objr ) >= 5 ) {
p = ObjGet( objr, 5 );
if( memcmp( p, EASY_OMF_SIGNATURE, 5 ) == 0 ) {
loc.is_phar = 1;
CanMisc.memory_model = CAN_MODEL_FLAT;
CanMisc.processor = CAN_PROC_80386;
ret = -1;
}
}
break;
case CMT_MS_OMF:
ret = -1; /* we always assume the presence of this coment record */
break;
case CMT_MS_END_PASS_1:
ret = -1; /* we trash these records */
break;
case CMT_DOSSEG:
loc.last_defn = objr;
break;
}
if( ret == -1 ) {
ObjKillRec( objr );
}
return( ret );
}
STATIC int pass1Modend( obj_rec *objr ) {
uint_8 mattr;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_MODEND );
mattr = ObjGet8( objr );
objr->d.modend.main_module = ( mattr & 0x80 ) != 0;
objr->d.modend.start_addrs = ( mattr & 0x40 ) != 0;
if( mattr & 0x40 ) { /* has start addrs */
objr->d.modend.is_logical = mattr & 1;
FixGetRef( loc.fix_info, objr, &objr->d.modend.ref, mattr & 1 );
}
/**/myassert( ObjEOR( objr ) );
ObjDetachData( objr );
return( 0 );
}
STATIC int pass1Extdef( obj_rec *objr ) {
uint_8 len;
unsigned count;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_EXTDEF ||
objr->command == CMD_STATIC_EXTDEF );
loc.last_defn = objr;
objr->d.extdef.first_idx = loc.extdef_idx + 1;
count = 0;
while( !ObjEOR( objr ) ) {
len = ObjGet8( objr );
ObjGet( objr, len ); /* name */
ObjGetIndex( objr ); /* type index */
++count;
}
objr->d.extdef.num_names = count;
loc.extdef_idx += count;
return( 0 );
}
STATIC int pass1Cextdf( obj_rec *objr ) {
unsigned count;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_CEXTDF );
loc.last_defn = objr;
objr->d.cextdf.first_idx = loc.extdef_idx + 1;
count = 0;
while( !ObjEOR( objr ) ) {
ObjGetIndex( objr ); /* skip the logical name index */
ObjGetIndex( objr ); /* skip the type index */
++count;
}
objr->d.cextdf.num_names = count;
loc.extdef_idx += count;
return( 0 );
}
STATIC int pass1Lnames( obj_rec *objr ) {
uint_8 len;
unsigned count;
const uint_8 *chk_name;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_LNAMES || objr->command == CMD_LLNAMES );
loc.last_defn = objr;
objr->d.lnames.first_idx = loc.lnames_idx + 1;
count = 0;
while( !ObjEOR( objr ) ) {
len = ObjGet8( objr );
chk_name = ObjGet( objr, len );
if( len == DGROUP_NAME_LEN ) {
if( memcmp( DGROUP_NAME_VALUE, chk_name, DGROUP_NAME_LEN ) == 0 ) {
loc.dgroup_idx = objr->d.lnames.first_idx + count;
}
} else if( len == FLAT_NAME_LEN ) {
if( memcmp( FLAT_NAME_VALUE, chk_name, FLAT_NAME_LEN ) == 0 ) {
loc.flat_idx = objr->d.lnames.first_idx + count;
}
}
++count;
}
objr->d.lnames.num_names = count;
loc.lnames_idx += count;
return( 0 );
}
STATIC int pass1Segdef( obj_rec *objr ) {
uint_8 acbp;
uint_8 align;
uint_8 phar_attr;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_SEGDEF );
loc.last_defn = objr;
objr->d.segdef.idx = ++loc.segdef_idx;
acbp = ObjGet8( objr );
switch( acbp >> 5 ) {
case ALIGN_ABS: align = SEGDEF_ALIGN_ABS; break;
case ALIGN_BYTE: align = SEGDEF_ALIGN_BYTE; break;
case ALIGN_WORD: align = SEGDEF_ALIGN_WORD; break;
case ALIGN_PARA: align = SEGDEF_ALIGN_PARA; break;
case ALIGN_PAGE: align = SEGDEF_ALIGN_PAGE; break;
case ALIGN_DWORD: align = SEGDEF_ALIGN_DWORD; break;
case ALIGN_LTRELOC:
if( objr->is_phar ) {
align = SEGDEF_ALIGN_4KPAGE;
} else {
Fatal( MSG_NO_SUPPORT_LTL );
/*align = SEGDEF_ALIGN_LTRELOC; */
}
break;
default:
Fatal( MSG_UNK_SEGDEF_ALIGN, acbp >> 5 );
}
objr->d.segdef.align = align;
objr->d.segdef.combine = ( acbp >> 2 ) & 0x07;
objr->d.segdef.use_32 = acbp & 0x01; /* MS386 use_32 flag */
if( align == SEGDEF_ALIGN_ABS ) {
FixGetPRef( loc.fix_info, objr, &objr->d.segdef.abs );
}
objr->d.segdef.seg_length = ObjGetEither( objr );
if( acbp & 0x02 ) {
if( objr->is_32 || objr->is_phar ) {
Fatal( MSG_NO_SUPPORT_BIG_32 ); /* FIXME */
}
objr->d.segdef.seg_length = 0x10000UL;
}
objr->d.segdef.seg_name_idx = ObjGetIndex( objr );
objr->d.segdef.class_name_idx = ObjGetIndex( objr );
objr->d.segdef.ovl_name_idx = ObjGetIndex( objr );
if( objr->is_phar ) {
if( !ObjEOR( objr ) ) {
phar_attr = ObjGet8( objr );
objr->d.segdef.use_32 = ( phar_attr & EASY_USE32_FIELD ) != 0;
objr->d.segdef.access_valid = 1;
objr->d.segdef.access_attr = phar_attr & EASY_PROTECT_FIELD;
} else {
objr->d.segdef.use_32 = 1;
objr->d.segdef.access_valid = 0;
}
} else {
objr->d.segdef.access_valid = 0;
}
/**/myassert( ObjEOR( objr ) );
ObjDetachData( objr ); /* no more need for this data */
return( 0 );
}
STATIC int pass1Grpdef( obj_rec *objr ) {
uint_16 name_idx;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_GRPDEF );
loc.last_defn = objr;
objr->d.grpdef.idx = ++loc.grpdef_idx;
name_idx = ObjGetIndex( objr );
if( name_idx == loc.dgroup_idx ) {
ObjDGROUPIndex = objr->d.grpdef.idx;
} else if( name_idx == loc.flat_idx ) {
ObjFLATIndex = objr->d.grpdef.idx;
}
return( 0 );
}
STATIC int pass1Fixup( obj_rec *objr ) {
fixup *head;
fixup *fix;
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_FIXUP );
objr->d.fixup.data_rec = loc.last_data_rec;
head = NULL;
objr->d.fixup.fixup = NULL;
while( !ObjEOR( objr ) ) {
fix = FixGetFix( loc.fix_info, objr );
if( fix != NULL ) { /* wasn't a thread fixup */
fix->next = head;
head = fix;
}
}
objr->d.fixup.fixup = head;
ObjDetachData( objr ); /* no more need for the data in this record */
/* if the entire record was thread fixups, then we won't pass it on */
if( head == NULL ) {
ObjKillRec( objr );
return( -1 );
}
return( 0 );
}
STATIC int pass1Ledata( obj_rec *objr ) {
/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_LEDATA || objr->command == CMD_LIDATA );
loc.last_data_rec = objr;
objr->d.ledata.idx = ObjGetIndex( objr );
objr->d.ledata.offset = ObjGetEither( objr );
return( 0 );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?