wf77info.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,181 行 · 第 1/5 页
C
2,181 行
size = GetComBlkSize( cb );
while( size > MaxSegSize ) {
BESetSeg( segment );
SegBytes( MaxSegSize );
size -= MaxSegSize;
segment++;
}
BESetSeg( segment );
SegBytes( size );
}
static void SegBytes( unsigned_32 size ) {
//============================================
#if _CPU == 386
DGUBytes( size );
#else
if( size == MaxSegSize ) {
DGUBytes( size - 1 ); // back end can't handle value of 64k
DGUBytes( 1 );
} else {
DGUBytes( size );
}
#endif
}
static void DefineGlobalSeg( global_seg *seg ) {
//==========================================================
// Define a global segment.
int private;
char g_name[G_DATA_LEN+3];
seg->segment = AllocSegId();
memcpy( g_name, GData, G_DATA_LEN );
itoa( seg->segment - GlobalSeg->segment, &g_name[ G_DATA_LEN ], 10 );
#if _CPU == 386 || _CPU == 8086
if( _SmallDataModel( CGOpts ) ) {
if( seg->initialized ) {
private = INIT; // so segment doesn't get put in BSS class
} else {
private = 0;
}
} else {
private = PRIVATE;
}
#else
if( seg->initialized ) {
private = INIT; // so segment doesn't get put in BSS class
} else {
private = 0;
}
#endif
BEDefSeg( seg->segment, private, g_name, ALIGN_SEGMENT );
}
static void DefineGlobalSegs( void ) {
//==================================
// Define global segments.
global_seg *g_seg;
g_seg = GlobalSeg;
while( g_seg != NULL ) {
DefineGlobalSeg( g_seg );
g_seg = g_seg->link;
}
}
static void AllocGlobalSegs( void ) {
//=================================
// Allocate global segments.
global_seg *g_seg;
g_seg = GlobalSeg;
while( g_seg != NULL ) {
BESetSeg( g_seg->segment );
SegBytes( g_seg->size );
g_seg = g_seg->link;
}
}
static global_seg *GSegDesc( unsigned_32 g_offset ) {
//=========================================================
// Find global segment descriptor for given offset.
global_seg *g_seg;
unsigned_32 g_size;
g_seg = GlobalSeg;
g_size = 0;
for(;;) {
if( g_size + g_seg->size > g_offset ) break;
g_size += g_seg->size;
g_seg = g_seg->link;
}
return( g_seg );
}
void DtInit( segment_id seg, seg_offset offset ) {
//===================================================
// Set to do DATA initialization.
if( DtOffset >= MaxSegSize - offset ) {
seg++;
DtSegOffset = DtOffset - (MaxSegSize - offset);
while( DtSegOffset >= MaxSegSize ) {
seg++;
DtSegOffset -= MaxSegSize;
}
} else {
DtSegOffset = offset + DtOffset;
}
DtSegment = seg;
}
struct {
int seg;
seg_offset offset;
uint size;
char byte_value;
} CurrDt;
static void InitBytes( unsigned long size, byte value ) {
//===========================================================
#if _CPU == 386
DGIBytes( size, value );
#else
if( size == MaxSegSize ) {
// back end can't handle size of 64k
DGIBytes( MaxSegSize / 2, value );
DGIBytes( MaxSegSize / 2, value );
} else {
DGIBytes( size, value );
}
#endif
}
static void UndefBytes( unsigned long size, byte *data ) {
//============================================================
#if _CPU == 386
DGBytes( size, data );
#else
if( size == MaxSegSize ) {
// back end can't handle size of 64k
DGBytes( MaxSegSize / 2, data );
DGBytes( MaxSegSize / 2, data );
} else {
DGBytes( size, data );
}
#endif
}
static void FlushCurrDt( void ) {
//=============================
if( CurrDt.seg != WF77_NULLSEGID ) {
BESetSeg( CurrDt.seg );
DGSeek( CurrDt.offset );
InitBytes( CurrDt.size, CurrDt.byte_value );
}
}
static void InitCurrDt( void ) {
//============================
CurrDt.seg = WF77_NULLSEGID;
CurrDt.offset = 0;
CurrDt.byte_value = 0;
CurrDt.size = 0;
}
void DtIBytes( byte data, int size ) {
//=======================================
// Initialize with specified data.
if( (DtSegment == CurrDt.seg) &&
(DtSegOffset == CurrDt.offset + CurrDt.size) &&
(data == CurrDt.byte_value) &&
((MaxSegSize - (CurrDt.offset + CurrDt.size)) >= size ) ) {
// We are continuing where we left off
CurrDt.size += size;
DtSegOffset += size;
} else {
FlushCurrDt();
if( MaxSegSize - DtSegOffset > size ) {
CurrDt.seg = DtSegment;
CurrDt.offset = DtSegOffset;
CurrDt.byte_value = data;
CurrDt.size = size;
DtSegOffset += size;
} else {
BESetSeg( DtSegment );
DGSeek( DtSegOffset );
DGIBytes( MaxSegSize - DtSegOffset, data );
size -= MaxSegSize - DtSegOffset;
DtSegment++;
DtSegOffset = size;
CurrDt.seg = DtSegment;
CurrDt.offset = DtSegOffset;
CurrDt.byte_value = data;
CurrDt.size = size;
}
}
}
void DtStreamBytes( byte *data, int size ) {
//=============================================
// Initialize with specified data.
FlushCurrDt();
InitCurrDt();
BESetSeg( DtSegment );
DGSeek( DtSegOffset );
if( MaxSegSize - DtSegOffset > size ) {
UndefBytes( size, data );
DtSegOffset += size;
} else {
UndefBytes( MaxSegSize - DtSegOffset, data );
size -= MaxSegSize - DtSegOffset;
DtSegment++;
if( size != 0 ) {
BESetSeg( DtSegment );
DGSeek( 0 );
UndefBytes( size, data + MaxSegSize - DtSegOffset );
DtSegOffset = size;
} else {
DtSegOffset = 0;
}
}
}
void DtBytes( byte *data, int size ) {
//=======================================
// Initialize with specified data.
byte byte_value;
int i;
byte_value = *data;
for( i = 1; i < size; ++i ) {
if( data[i] != byte_value ) {
DtStreamBytes( data, size );
return;
}
}
DtIBytes( byte_value, size );
}
void DtStartSequence( void ) {
//=========================
InitCurrDt();
}
void DtFiniSequence( void ) {
//========================
FlushCurrDt();
}
segment_id GetComSeg( sym_id sym, unsigned_32 offset ) {
//===========================================================
// Get segment id of common block for variable in common.
int segment;
offset += sym->ns.si.va.vi.ec_ext->offset;
segment = sym->ns.si.va.vi.ec_ext->com_blk->ns.si.cb.seg_id;
while( offset > MaxSegSize ) {
segment++;
offset -= MaxSegSize;
}
return( segment );
}
segment_id GetDataSegId( sym_id sym ) {
//==========================================
// Get segment containing data for given variable.
segment_id id;
unsigned_32 offset;
com_eq *ce_ext;
if( sym->ns.flags & SY_IN_EQUIV ) {
offset = 0;
for(;;) {
ce_ext = sym->ns.si.va.vi.ec_ext;
if( ce_ext->ec_flags & LEADER ) break;
offset += ce_ext->offset;
sym = ce_ext->link_eqv;
}
if( ce_ext->ec_flags & MEMBER_IN_COMMON ) {
id = GetComSeg( sym, offset );
} else {
id = GetGlobalSeg( ce_ext->offset + offset );
}
} else if( sym->ns.flags & SY_IN_COMMON ) {
id = GetComSeg( sym, 0 );
} else if( sym->ns.flags & SY_SUBSCRIPTED ) {
id = sym->ns.si.va.vi.seg_id;
} else if( sym->ns.typ == TY_CHAR ) {
id = sym->ns.si.va.vi.seg_id;
} else if( sym->ns.typ == TY_STRUCTURE ) {
id = sym->ns.si.va.vi.seg_id;
} else if( sym->ns.flags & SY_DATA_INIT ) {
id = WF77_LDATA;
} else {
id = WF77_UDATA;
}
return( id );
}
seg_offset GetGlobalOffset( unsigned_32 g_offset ) {
//=======================================================
// Find offset in the global segment containing data at given offset.
global_seg *g_seg;
unsigned_32 g_size;
g_seg = GlobalSeg;
g_size = 0;
for(;;) {
if( g_size + g_seg->size > g_offset ) break;
g_size += g_seg->size;
g_seg = g_seg->link;
}
return( g_offset - g_size );
}
seg_offset GetComOffset( unsigned_32 offset ) {
//==================================================
// Get segment offset in common block for variable in common.
while( offset >= MaxSegSize ) {
offset -= MaxSegSize;
}
return( offset );
}
void *FEBack( sym_id sym ) {
//=============================
// Return the back handle for the given symbol.
void *back_handle;
if( ( sym->ns.flags & SY_CLASS ) == SY_COMMON ) {
back_handle = sym->ns.address;
} else {
if( sym->ns.address == NULL ) {
sym->ns.address = BENewBack( sym );
}
back_handle = sym->ns.address;
}
return( back_handle );
}
seg_offset GetDataOffset( sym_id sym ) {
//===========================================
// Get offset in segment containing data for given variable.
seg_offset seg_offset;
unsigned_32 offset;
com_eq *ce_ext;
if( sym->ns.flags & SY_IN_EQUIV ) {
offset = 0;
for(;;) {
ce_ext = sym->ns.si.va.vi.ec_ext;
if( ce_ext->ec_flags & LEADER ) break;
offset += ce_ext->offset;
sym = ce_ext->link_eqv;
}
if( ce_ext->ec_flags & MEMBER_IN_COMMON ) {
seg_offset = GetComOffset( ce_ext->offset + offset );
} else {
seg_offset = GetGlobalOffset( ce_ext->offset + offset );
}
} else if( sym->ns.flags & SY_IN_COMMON ) {
seg_offset = GetComOffset( sym->ns.si.va.vi.ec_ext->offset );
} else if( sym->ns.flags & SY_SUBSCRIPTED ) {
seg_offset = DGBackTell( FEBack( sym ) );
} else if( sym->ns.typ == TY_CHAR ) {
seg_offset = DGBackTell( sym->ns.si.va.bck_hdl );
} else {
seg_offset = DGBackTell( FEBack( sym ) );
}
return( seg_offset );
}
segment_id GetGlobalSeg( unsigned_32 g_offset ) {
//================================================
// Find global segment containing data at given offset.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?