records.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 535 行 · 第 1/2 页
C
535 行
/**************************************************/
{
while( list != NULL ) {
if( list->lnameidx == index ) {
return( TRUE );
}
list = list->next;
}
return( FALSE );
}
static void CheckSum( void )
/**************************/
{
BYTE cksum;
cksum = -SubTotal;
BuildRecord( &cksum, 1 );
SubTotal = 0;
}
static void procsegdef( bool is386 )
/**********************************/
{
BYTE acbp;
int segidx;
int classidx;
char * dataloc;
BYTE onebyte;
unsigned long fourbytes;
exclude_list * exclude;
WriteRecord();
++SegIndex;
dataloc = Rec1->u.anyobj.rest;
acbp = *dataloc;
dataloc++;
if( ( acbp & 0xE0 ) == 0 ) {
dataloc += 3; /* adjust for frame_number and offset */
}
dataloc += 2; // skip the length;
if( is386 || Easy32 ) { // if a 386 .obj file.......
dataloc += 2; // got more offset to skip.
}
segidx = GetIndex( &dataloc );
classidx = GetIndex( &dataloc );
GetIndex( &dataloc ); // skip the ovl_name
if( MatchIndex( ClassList, classidx ) || MatchIndex( SegList, segidx ) ) {
onebyte = COMENT;
BuildRecord( &onebyte, 1 );
if( SegIndex >= 128 ) { // then indicies are 2 bytes.
onebyte = 6; // includes checksum
} else {
onebyte = 5;
}
BuildRecord( &onebyte, 1 );
fourbytes = 0x4FFE8000; // 00 80 FE 4F
BuildRecord( &fourbytes, 4 ); // | | | ^-- 'O' optimize command
IndexRecord( SegIndex ); // | | +----- linker directive class
CheckSum(); // | +-------- attribute (nopurge)
} // +----------- high-order length
exclude = ExcludeList;
while( exclude != NULL ) { // set all seg indicies in the exclude
if( exclude->lnameidx == segidx ) { // list.
exclude->segidx = SegIndex;
}
exclude = exclude->next;
}
}
static void ProcDataRec( bool is386 )
/***********************************/
{
unsigned segidx;
char * dataloc;
exclude_list * exclude;
unsigned long offset;
unsigned long endoffset;
WriteRecord();
MakeUnsafe = FALSE;
dataloc = Rec1->u.anyobj.rest;
segidx = GetIndex( &dataloc );
if( is386 || Easy32 ) {
offset = *((unsigned_32 *)dataloc);
} else {
offset = *((unsigned_16 *)dataloc);
}
endoffset = offset + Rec1->head.length;
exclude = ExcludeList;
while( exclude != NULL ) {
if( segidx == exclude->segidx ) {
if( offset < exclude->start_off ) {
if( endoffset >= exclude->start_off ) {
MakeUnsafe = TRUE;
break;
}
} else {
if( exclude->end_off >= offset ) {
MakeUnsafe = TRUE;
break;
}
}
}
exclude = exclude->next;
}
}
// this shuts off optimization for the following fixupp. record is of the form
// Comment, low order length, high order length, attribute (nopurge),
// class (linker directive), unsafe fixupp command, checksum.
static BYTE UnsafeRec[] = { COMENT, 4, 0, 0x80, 0xFE, 'U', 0xA1 };
static void procfixupp( void )
/****************************/
{
if( MakeUnsafe ) {
BuildRecord( UnsafeRec, sizeof( UnsafeRec ) );
}
WriteRecord();
}
extern void ProcessRec( void )
/****************************/
{
bool is386;
is386 = FALSE;
switch( Rec1->head.class ) {
case SEGD32: is386 = TRUE; // note the fall through
case SEGDEF: procsegdef( is386 ); break;
case COMENT: proccoment(); break;
case LNAMES: proclnames(); break;
case LEDA32: is386 = TRUE; // even more fall through here.
case LIDA32: is386 = TRUE;
case LEDATA:
case LIDATA: ProcDataRec( is386 ); break;
case FIXU32:
case FIXUPP: procfixupp(); break;
default:
WriteRecord();
break;
}
}
extern int GetIndex( char **rec )
/*******************************/
{
char * ptr;
int index;
ptr = *rec;
index = *ptr;
ptr++;
if( index & 0x80 ) {
index &= 0x7f;
index <<= 8;
index += *ptr;
ptr++;
}
*rec = ptr;
return( index );
}
extern int ReadRec( void )
/************************/
{
int len;
int to_read;
long offset;
len = QRead( InFile, Rec1, sizeof( HEAD ) );
if( len == 0 ) {
return( ENDFILE );
}
if( len != sizeof( HEAD ) ) {
Error( "premature end of file" );
}
if( Rec1->head.class == LIBRARY_HEADER ) {
PageLen = Rec1->head.length + sizeof( HEAD );
QSeek( InFile, PageLen, SEEK_SET );
ReadRec();
return( LIBRARY );
} else if( Rec1->head.class == LIBRARY_TRAILER ) {
return( ENDLIBRARY );
} else {
to_read = Rec1->head.length;
if( to_read >= MAX_OBJECT_REC_SIZE ) {
Error( "object file record too long" );
}
len = QRead( InFile, &(Rec1->u.anyobj.rest), to_read );
if( len != to_read ) {
Error( "premature end of file encountered" );
}
if( Rec1->head.class == THEADR ) {
return( OBJECT );
} else if( Rec1->head.class == MODEND
|| Rec1->head.class == MODE32 ) {
if( PageLen != 0 ) { // skip padding in the library.
offset = tell( InFile );
offset = PageLen - offset % PageLen;
if( offset == PageLen ) offset = 0;
QSeek( InFile, offset, SEEK_CUR );
}
return( ENDMODULE );
}
}
return( OK );
}
static void AddToSubTotal( void * buff, int len )
/***********************************************/
{
char * data;
data = (char *) buff;
while( --len >= 0 ) {
SubTotal += *data++;
}
}
extern void BuildRecord( void *info, unsigned len )
/*************************************************/
{
int overlap;
char * data;
data = (char *) info;
AddToSubTotal( data, len );
overlap = len + InBuffer - MAX_OBJECT_REC_SIZE;
if( overlap > 0 ) {
memcpy( OutputBuffer + InBuffer, data, len - overlap );
QWrite( OutFile, OutputBuffer, MAX_OBJECT_REC_SIZE );
data += len - overlap;
InBuffer = 0;
len = overlap;
}
memcpy( OutputBuffer + InBuffer, data, len );
InBuffer += len;
}
extern void FlushBuffer( void )
/*****************************/
{
if( InBuffer > 0 ) {
QWrite( OutFile, OutputBuffer, InBuffer );
InBuffer = 0;
}
}
extern void IndexRecord( unsigned index )
/***************************************/
// note this assumes the intel byte ordering
{
BYTE onebyte;
if( index >= 128 ) {
index = (index << 8) | (index >> 8) | 0x80;
AddToSubTotal( &index, 2 );
BuildRecord( &index, 2 );
} else {
onebyte = index;
AddToSubTotal( &onebyte, 1 );
BuildRecord( &onebyte, 1 );
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?