pcorec.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 899 行 · 第 1/2 页
C
899 行
return( fix );
}
static void FindTarget( char method, thread *trd )
/**************************************************/
{
trd->datum = NULL;
trd->address = NULL;
if( method <= 3 ) {
if( method == T_SEGWD ) {
trd->datum = GetTab( GetIndex(), SegTab, TRUE );
} else if( method == T_GRPWD ) {
trd->datum = GetTab( GetIndex(), GrpTab, TRUE );
} else if( method == T_EXTWD ) {
trd->datum = GetTab( GetIndex(), ExtTab, TRUE );
} else { /* method == T_ABSWD */
trd->address = GetWord();
}
}
}
void THeadr()
/************/
{
Mod = NewModule();
Mod->name = GetName( MAX_NAME_LEN );
if( Options & FORM_ASSEMBLER ) {
Mod->imp_lookup = HashTableCreate( IMPORT_LOOKUP_TABLE_SIZE,
HASH_STRING, (hash_table_comparison_func)stricmp );
if( !Mod->imp_lookup ) {
SysError( ERR_OUT_OF_MEM, FALSE );
}
}
}
void LName()
/***********/
{
while( EndOfRecord == FALSE ) {
PutTab( ++NameIndex, NameTab, GetName( MAX_NAME_LEN ) );
}
}
void SegDef()
/************/
{
uint_32 seg_len;
segment *seg;
char A;
char attr;
seg = NewSegment();
PutTab( ++SegIndex, SegTab, seg );
seg->id = SegIndex;
seg->attr = GetByte();
A = _SegAlign( seg );
if( A == ALIGN_ABS ) {
seg->address = GetWord();
if( IsPharLap ) {
seg->offset = GetLong();
} else {
seg->offset = GetWord();
}
}
if( IsPharLap || Is32Record ) {
seg_len = GetLong();
} else {
seg_len = GetWord();
}
if( _Size64K( seg ) ) {
/* FIXME if Is32Record then should be 2 ** 32 */
seg_len = 0x10000; /* exactly 64K */
}
seg->name = GetTab( GetIndex(), NameTab, FALSE );
if( strstr( seg->name, WTLSEGStr ) != NULL ) {
WtlsegPresent = TRUE;
}
seg->u.seg.class_name = GetTab( GetIndex(), NameTab, FALSE );
seg->u.seg.overlay_id = GetIndex();
seg->size = seg_len;
seg->start = seg_len;
if( !IsPharLap ) {
seg->use_32 = ( seg->attr & 0x01 ) != 0;
} else if( !EndOfRecord ) {
attr = GetByte();
seg->use_32 = ( attr & EASY_USE32_FIELD ) != 0;
seg->access_attr = attr & EASY_PROTECT_FIELD;
seg->access_valid = TRUE;
} else {
seg->use_32 = TRUE;
seg->access_valid = FALSE;
}
}
void ComDat()
/***********/
{
segment *seg;
uint_8 flags;
uint_8 attr;
uint_8 align;
unsigned grp_id;
unsigned seg_id;
unsigned lname;
flags = GetByte();
attr = GetByte();
align = GetByte();
if( IsPharLap || Is32Record ) {
Offset = GetLong();
} else {
Offset = GetWord();
}
GetIndex(); /* skip type index */
grp_id = 0;
seg_id = 0;
if( (attr & COMDAT_ALLOC_MASK) == COMDAT_EXPLICIT ) {
grp_id = GetIndex();
seg_id = GetIndex();
if( grp_id == 0 && seg_id == 0 ) {
GetWord();
}
}
lname = GetIndex();
if( flags & COMDAT_CONTINUE ) {
/* old comdat */
seg = FindComdat( lname );
} else {
seg = NewSegment();
seg->name = GetTab( lname, NameTab, FALSE );
seg->class = TYPE_COMDAT;
seg->id = lname;
seg->attr = attr;
seg->u.com.align = align;
if( seg_id != 0 ) seg->u.com.seg = GetTab( seg_id, SegTab, TRUE );
if( grp_id != 0 ) seg->u.com.grp = GetTab( grp_id, GrpTab, TRUE );
switch( attr & COMDAT_ALLOC_MASK ) {
case COMDAT_EXPLICIT:
seg->use_32 = seg->u.com.seg->use_32;
break;
case COMDAT_FAR_CODE:
case COMDAT_FAR_DATA:
seg->use_32 = FALSE;
break;
case COMDAT_CODE32:
case COMDAT_DATA32:
seg->use_32 = TRUE;
break;
}
if( !(flags & COMDAT_LOCAL) ) seg->public = TRUE;
}
Segment = seg;
if( flags & COMDAT_ITERATED ) {
DoLIData();
} else {
DoLEData();
}
if( seg->size < DataOffset ) seg->size = DataOffset;
}
static void DoBackPatch( unsigned loc_type )
/******************************************/
{
uint_32 offset;
uint_32 value;
while( EndOfRecord == FALSE ) {
if( IsPharLap || Is32Record ) {
offset = GetLong();
value = GetLong();
} else {
offset = GetWord();
value = GetWord();
}
switch( loc_type ) {
case 0: /* 8-bit lobyte */
PutSegByte( offset, GetSegByte( offset ) + value );
break;
case 1: /* 16-bit offset */
PutSegWord( offset, GetSegWord( offset ) + value );
break;
case 2: /* 32-bit offset */
PutSegDWord( offset, GetSegDWord( offset ) + value );
break;
}
}
}
void BackPatch()
/**************/
{
unsigned seg_id;
seg_id = GetIndex();
Segment = GetTab( seg_id, SegTab, TRUE );
DoBackPatch( GetByte() );
}
void NBackPatch()
/***************/
{
unsigned loc_type;
loc_type = GetByte();
Segment = FindComdat( GetIndex() );
DoBackPatch( loc_type );
}
static void DoLEData()
/********************/
{
MarkBegData();
DataOffset = Offset;
if( DataOffset < Segment->start ) {
Segment->start = DataOffset;
}
while( EndOfRecord == FALSE ) {
PutSegByte( DataOffset++, GetByte() );
}
}
void LEData()
/************/
{
uint_16 seg_id;
seg_id = GetIndex();
if( IsPharLap || Is32Record ) {
Offset = GetLong();
} else {
Offset = GetWord();
}
Segment = GetTab( seg_id, SegTab, TRUE );
DoLEData();
if( DataOffset > Segment->size ) {
Error( ERR_TOO_MUCH_LEDATA, TRUE );
}
}
static void DoLIData()
/********************/
{
code_block *block;
MarkBegData();
DataOffset = Offset;
if( DataOffset < Segment->start ) {
Segment->start = DataOffset;
}
while( !EndOfRecord ) {
block = IteratedData();
DecodeLIData( block );
}
}
void LIData()
/************/
{
uint_16 seg_id;
seg_id = GetIndex();
Segment = GetTab( seg_id, SegTab, TRUE );
if( IsPharLap || Is32Record ) {
Offset = GetLong();
} else {
Offset = GetWord();
}
DoLIData();
if( DataOffset > Segment->size ) {
Error( ERR_TOO_MUCH_LIDATA, TRUE );
}
}
static code_block *IteratedData()
/*********************************/
{
uint_32 rpt_count;
uint_16 blk_count;
char num_bytes;
code_block *block;
uint_16 i;
if( Is32Record ) {
rpt_count = GetLong();
} else {
rpt_count = GetWord();
}
blk_count = GetWord();
if( blk_count == 0 ) {
num_bytes = GetByte();
block = AllocMem( sizeof( code_block ) + num_bytes );
i = 1;
do {
block->data[ i ] = GetByte();
} while( ++i <= num_bytes );
block->data[ 0 ] = num_bytes;
} else {
block = AllocMem( sizeof( code_block ) + blk_count * sizeof( char * )
- sizeof( char ) );
i = 0;
do {
((ptr_table)block->data)[ i ] = IteratedData();
} while( ++i != blk_count );
}
block->rpt_count = rpt_count;
block->blk_count = blk_count;
return( block );
}
static void DecodeLIData( code_block *block )
/*********************************************/
{
uint_16 num;
uint_32 i;
i = 0;
do {
if( block->blk_count == 0 ) {
num = 1;
do {
PutSegByte( DataOffset++, block->data[ num ] );
} while( ++num <= block->data[ 0 ] );
} else {
num = 0;
do {
DecodeLIData( ( (ptr_table) block->data )[ num ] );
} while( ++num != block->blk_count );
}
} while( ++i != block->rpt_count );
}
void ModEnd()
/************/
{
char mod_typ;
char mattr;
fixup *fix;
mod_typ = GetByte();
mattr = ( mod_typ & 192 ) >> 6;
if( mattr & 1 ) { /* has start address */
if( mod_typ & 1 ) {
fix = FixField( TYPE_MODULE, 0, SEG_RELATIVE );
} else {
fix = NewFixup( TYPE_MODULE | SEG_RELATIVE );
fix->seg_address = GetWord();
fix->imp_address = GetByte();
}
Mod->start = fix;
}
if( mattr > 1 ) {
Mod->main = TRUE;
} else {
Mod->main = FALSE;
}
}
static void Add2List( handle **list, handle *hndl )
/***************************************************/
{
handle *tmp;
for( ;; ) {
tmp = *list;
if( tmp == NULL ) break;
list = &tmp->next_hndl;
}
*list = hndl;
}
void Coment()
/***********/
{
char attr;
char class;
int len;
int i;
segment *seg;
scan_table *scan_tab;
int sidx;
char name[ 80 ];
attr = GetByte();
class = GetByte();
if( ( attr == CMT_SOURCE_NAME && class == 0x80 ) ||
( attr == 0x80 && class == CMT_SOURCE_NAME ) ) {
len = RecLen - 3; /* class, attr, chksum */
for( i = 0; i < len; ++i ) {
name[ i ] = GetByte();
}
CommentName = NameAlloc( name, len );
} else if( attr == 0x80 && class == CMT_DISASM_DIRECTIVE ) {
class = GetByte();
if( class == DDIR_SCAN_TABLE ||
class == DDIR_SCAN_TABLE_32 ) { /* 'S'can table indices */
sidx = GetIndex();
if( sidx == 0 ) {
/* select table in a COMDAT record */
seg = FindComdat( GetIndex() );
} else {
seg = GetTab( sidx, SegTab, TRUE );
}
scan_tab = AllocMem( sizeof( scan_table ) );
if( class == DDIR_SCAN_TABLE_32 ) {
scan_tab->starts = GetLong();
scan_tab->ends = GetLong();
} else {
scan_tab->starts = GetWord();
scan_tab->ends = GetWord();
}
scan_tab->next = seg->scan_tabs;
seg->scan_tabs = scan_tab;
} else {
SkipPcoRec();
}
} else if( attr == 0x80 && class == CMT_EASY_OMF ) {
len = RecLen - 3; /* class, attr, chksum */
for( i = 0; i < len; ++i ) {
name[ i ] = GetByte();
}
if( memcmp( name, EASY_OMF_SIGNATURE, 5 ) == 0 ) {
IsPharLap = TRUE;
Is32BitObj = TRUE;
}
} else {
SkipPcoRec();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?