omfutil.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 528 行 · 第 1/2 页

C
528
字号
                    lib_block[block].fflag = LIB_FULL_PAGE;
                    break;
                    }
                lib_block[block].htab[bucket] = lib_block[block].fflag;
                lib_block[block].fflag += entry_len / 2;
                loc -= NUM_BUCKETS + 1;
                lib_block[block].name[loc ] = len;
                loc ++;
                memcpy( &(lib_block[block].name[loc]), sym, len );
                loc += len;
                *((unsigned_16 *) &( lib_block[block].name[loc] ) ) = offset;
                return( TRUE );
                }
            bucket += dbucket;
            if( bucket >= NUM_BUCKETS ) {
                bucket -= NUM_BUCKETS;
            }
        }
        block += dblock;
        if( block >= num_blocks ){
            block -= num_blocks;
        }
   }
   return( FALSE );
}


static bool HashOmfSymbols( OmfLibBlock *lib_block, unsigned num_blocks, sym_file *file )
{
    bool        ret = TRUE;
    sym_entry   *sym;
    unsigned    str_len;
    char        *fname;

    for( ; file != NULL; file = file->next ){
        if( file->import ) {
            fname = file->import->symName;
        } else {
            fname = MakeFName( file->full_name);
        }
        str_len = strlen( fname );
        fname[ str_len ] ='!';
        ret = InsertOmfDict( lib_block, num_blocks, fname,
            str_len + 1, file->new_offset );
        fname[ str_len ] = 0;
        if( ret == FALSE ){
            return( ret );
        }
        for( sym = file->first; sym != NULL; sym = sym->next ){
            ret = InsertOmfDict( lib_block, num_blocks, sym->name,
                sym->len, file->new_offset );
            if( ret == FALSE ){
                return( ret );
            }
        }
    }
    return( ret );
}

//return size of dict
unsigned WriteOmfDict( sym_file *first )
{
    bool        done;
    unsigned    num_blocks;
    OmfLibBlock *lib_block;
    unsigned    dict_size;
    unsigned    int i;
    unsigned    int j;

    num_blocks = max( (symCount + NUM_BUCKETS - 1 ) / NUM_BUCKETS,
                    ( charCount + 3 + BLOCK_NAME_LEN - 1 ) / BLOCK_NAME_LEN ) -1;

    lib_block = NULL;
    do{
        num_blocks ++;
        num_blocks = NextPrime( num_blocks );
        if( num_blocks == 0 ){
            return( 0 );
        }
        dict_size = num_blocks * sizeof( OmfLibBlock );
        lib_block = MemRealloc( lib_block, dict_size );
        memset( lib_block, 0, dict_size );
        for( i = 0; i < num_blocks; i ++ ) {
            lib_block[i].fflag = (NUM_BUCKETS + 1 ) / 2;
        }
        done = HashOmfSymbols( lib_block, num_blocks, first );
    } while( done == FALSE );
    for( i = 0; i < num_blocks; i++ ) {
        for( j = 0; j < NUM_BUCKETS; j++ ) {
           if( lib_block[i].htab[j] == 0 ) {
               break;
           }
        }
    }
    WriteNew( lib_block, dict_size );
    MemFree( lib_block );
    return( num_blocks );
}

static void trimOmfHeader( void )
{
    char *new_name;
    unsigned_8  sum;
    unsigned    i;

    omfRec->basic.contents[ omfRec->basic.len - 1 ] = '\0';
    new_name = TrimPath( omfRec->basic.contents + 1 );
    omfRec->basic.contents[0] = strlen( new_name );
    omfRec->basic.len = omfRec->basic.contents[0] + 2;
    strcpy( omfRec->basic.contents + 1, new_name );
    sum = 0;
    for( i = 0; i < omfRec->basic.len + 2; ++i ) {
        sum += omfRec->chkcalc[i];
    }
    omfRec->basic.contents[ omfRec->basic.len - 1 ] = -sum;
}

void WriteOmfFile( sym_file *file )
{
    libfile     io;
    sym_entry   *sym;
    bool        time_stamp;
    char        new_line[] = { '\n' };
    file_offset current;

    symCount ++;
    //add one for ! after name and make sure odd so whole name record will
    //be word aligned
    current = LibTell(NewLibrary);
    CheckForOverflow(current);
    file->new_offset = current / Options.page_size ;
    if( file->import == NULL ) {
        charCount += ( strlen( MakeFName( file->arch.name ) ) + 1 ) | 1;
        // Options.page_size is always a power of 2 so someone should optimize
        //this sometime. maybe store page_size as a log
        time_stamp = FALSE;
        if( file->inlib_offset != 0 ) {
            io = InLibHandle( file->inlib );
            LibSeek( io, file->inlib_offset, SEEK_SET );
        } else {
            io = LibOpen( file->full_name, LIBOPEN_BINARY_READ );
        }
        do {
            ReadOmfRecord( io );
            switch( omfRec->basic.type ){
            case CMD_THEADR:
                trimOmfHeader();
                break;
            case CMD_LINSYM:
            case CMD_LINS32:
            case CMD_LINNUM:
            case CMD_LINN32:
                if( Options.strip_line ){
                    continue;
                }
                break;
            case CMD_COMENT:
                switch( omfRec->basic.contents[1] ) {
                case CMT_LINKER_DIRECTIVE:
                    if( omfRec->time.subclass == LDIR_OBJ_TIMESTAMP ){
                        time_stamp = TRUE;
                    }
                    break;
                case CMT_DLL_ENTRY:
                    if( omfRec->basic.contents[2] == DLL_EXPDEF ) {
                        if( ExportListFile != NULL ) {
                            LibWrite( ExportListFile,&( omfRec->basic.contents[5] ), omfRec->basic.contents[4] );
                            LibWrite( ExportListFile, new_line, sizeof( new_line ) );
                        }
                        if( Options.strip_expdef ) {
                            continue;
                        }
                    }
                    break;
                case CMT_DEPENDENCY:
                    if( Options.strip_dependency )
                        continue;
                    break;
                }
                break;
            case CMD_MODEND:
            case CMD_MODE32:
                if( !time_stamp ){
                    WriteTimeStamp( file );
                }
                break;
            }
            WriteOmfRecord();
            } while( omfRec->basic.type != CMD_MODEND && omfRec->basic.type != CMD_MODE32 );
        if( file->inlib_offset == 0 ) {
            LibClose( io );
        }
    } else {
        unsigned_8  sum;
        unsigned    sym_len;
        unsigned    file_len;
        unsigned    i;

        omfRec->basic.type = CMD_THEADR;
        sym_len = strlen( file->import->symName );
        omfRec->basic.len = sym_len + 2;
        omfRec->basic.contents[0] = sym_len;
        charCount += ( sym_len + 1 ) | 1;
        strcpy( omfRec->basic.contents + 1, file->import->symName );
        sum = 0;
        for( i = 0; i < sym_len + 4; ++i ) {
            sum += omfRec->chkcalc[i];
        }
        omfRec->basic.contents[ sym_len + 1 ] = -sum;
        WriteOmfRecord();
        file_len = strlen( file->import->DLLName );
        omfRec->basic.type = CMD_COMENT;
        omfRec->basic.len = 9 + file_len + sym_len;
        omfRec->basic.contents[0] = CMT_TNP;
        omfRec->basic.contents[1] = CMT_DLL_ENTRY;
        omfRec->basic.contents[2] = MOMF_IMPDEF;
        if( file->import->type == ORDINAL ) {
            omfRec->basic.contents[3] = 1;
        } else {
            omfRec->basic.contents[3] = 0;
        }
        omfRec->basic.contents[4] = sym_len;
        strcpy( omfRec->basic.contents + 5, file->import->symName );
        omfRec->basic.contents[5 + sym_len] = file_len;
        strcpy( omfRec->basic.contents + 6 + sym_len, file->import->DLLName );
        if( file->import->type == ORDINAL ) {
           *( (unsigned_16 *)&( omfRec->basic.contents[6 + sym_len + file_len ] ) ) = (unsigned_16)file->import->ordinal;
        } else {
            if( file->import->exportedName ) {
                i = strlen( file->import->exportedName );
                omfRec->basic.contents[ 6 + sym_len + file_len ] = i ;
                memcpy( omfRec->basic.contents + 7 + sym_len + file_len, file->import->exportedName, i + 1 ) ;
                sym_len += i + 1;
                omfRec->basic.len += i + 1;
            } else {
                omfRec->basic.contents[6 + sym_len + file_len] = 0;
                omfRec->basic.contents[7 + sym_len + file_len] = 0;
                }
        }
        sum = 0;
        for( i = 0; i < sym_len + file_len + 11; ++i ) {
            sum += omfRec->chkcalc[i];
        }
        omfRec->basic.contents[ sym_len + file_len +  8 ] = -sum;
        WriteOmfRecord();
        WriteTimeStamp( file );
        omfRec->basic.type = CMD_MODEND;
        omfRec->basic.len = 2;
        omfRec->basic.contents[0] = 0;
        omfRec->basic.contents[1] = 0;
        sum = 0;
        for( i = 0; i < 4; ++i ) {
            sum += omfRec->chkcalc[i];
        }
        omfRec->basic.contents[1] = -sum;
        WriteOmfRecord();
    }
    PadOmf( FALSE );
    for( sym = file->first; sym != NULL; sym = sym->next ) {
        ++symCount;
        charCount += sym->len | 1;
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?