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