subsect.cpp

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

CPP
429
字号
/*******************************************/
{
    uint seg = sym -> CodeSegment();
    if ( seg != NO_SEGMENT ) {
        if ( _lastStartSym[seg] == 0 ) {
            SymbolStruct* newSSym = new CSStartSearch(seg);
            _lastStartSym[seg] = newSSym;
            _symbolInfo.insert(newSSym);
        }
    }
    InsertOneRecord( sym );
    if ( sym -> IsStartSym() ) {
        if ( ! symStack.isEmpty() ) {
            sym -> SetParent( symStack.top() -> Offset() );
        } else {
            sym -> SetParent( 0 );
            assert( _lastStartSym[seg] );
            _lastStartSym[seg] -> SetNext( sym -> Offset() );
            _lastStartSym[seg] = sym;
        }
        symStack.push(sym);
        return;
    }
    if ( sym -> IsEndSym() ) {
        symStack.pop() -> SetEnd( sym -> Offset() );
    }
}

void SstAlignSym::Put( ExeMaker& eMaker ) const
/*********************************************/
{
    WCPtrConstSListIter<SymbolStruct> iter(_symbolInfo);
    eMaker.DumpToExe((unsigned_32) CV4_HEADER );
    while ( ++iter ) {
        iter.current() -> Put( eMaker );
    }
}

void SstGlobalSym::Put( ExeMaker& eMaker, const uint cSeg ) const
/***************************************************************/
{
    if ( _symbolInfo.isEmpty() ) {
        eMaker.DumpToExe( (unsigned_16) 0 );
        eMaker.DumpToExe( (unsigned_16) 0 );
        eMaker.DumpToExe( (unsigned_32) 0 );
        eMaker.DumpToExe( (unsigned_32) 0 );
        eMaker.DumpToExe( (unsigned_32) 0 );
        return;
    }
    unsigned_32 currentOffset = 0;
    eMaker.DumpToExe( (unsigned_16) DEFAULT_NAME_HASH );
    eMaker.DumpToExe( (unsigned_16) DEFAULT_ADDR_HASH );
    streampos pos = eMaker.TellPos();
    eMaker.Reserve(3*LONG_WORD);
    NameHashTable nameHash(_symbolInfo.entries());
    AddrHashTable addrHash(cSeg);

    WCPtrConstSListIter<SymbolStruct> iter(_symbolInfo);
    SymbolStruct* currentPtr = NULL;
    while ( ++iter ) {
        currentPtr = iter.current();
        currentPtr -> SetOffset(currentOffset);
        if ( currentPtr -> cSum() == NO_CHKSUM ) {
            if ( addrHash.TryToInsert(currentPtr) ) {
                currentOffset += SymbolSubsection::PageAlign(eMaker,currentPtr->Length(),currentOffset);
                currentOffset += currentPtr -> Length();
                currentPtr -> Put(eMaker);
            }
        } else if ( nameHash.TryToInsert(currentPtr) ) {
                currentOffset += SymbolSubsection::PageAlign(eMaker,currentPtr->Length(),currentOffset);
                currentOffset += currentPtr -> Length();
                currentPtr -> Put(eMaker);
                addrHash.TryToInsert(currentPtr);
        }
    }
    currentOffset += SymbolSubsection::DumpPageAlign(eMaker,LONG_WORD,0xff);
    unsigned_32 preNameHasPos = eMaker.TellPos();
    nameHash.Put(eMaker);
    unsigned_32 suNameHasPos = eMaker.TellPos();
    addrHash.Put(eMaker);
    unsigned_32 currentPos = eMaker.TellPos();
    eMaker.SeekTo(pos);
    eMaker.DumpToExe(currentOffset);
    eMaker.DumpToExe(suNameHasPos - preNameHasPos);
    eMaker.DumpToExe(currentPos - suNameHasPos);
    eMaker.SeekTo(currentPos);
}

SymbolStruct* NameHashTable::Find( const WCPtrSList<chain_table>& lst,
                                   const unsigned_32              cSum ) const
/****************************************************************************/
{
    WCPtrConstSListIter<chain_table> iter(lst);
    while ( ++iter ) {
        if ( iter.current() -> _checkSum == cSum ) {
            return iter.current() -> _symPtr;
        }
    }
    return NULL;
}

bool NameHashTable::TryToInsert( SymbolStruct* sym )
/**************************************************/
{
    unsigned_32 ckSum = sym -> cSum();
    if ( ckSum == NO_CHKSUM ) {
        return FALSE;
    }
    uint   bucket = ckSum % _cHash;
    SymbolStruct* eqSym = Find(_cTab[bucket],ckSum);
    if ( eqSym != NULL ) {
        const char* name = sym -> Name();
        if ( memcmp(name,eqSym->Name(),*name+1) != 0 ) {
            _cTab[bucket].append( new chain_table(sym,ckSum) );
            return TRUE;
        }
        return FALSE;
    }
    _cTab[bucket].append( new chain_table(sym,ckSum) );
    return TRUE;
}

void NameHashTable::Put( ExeMaker& eMaker ) const
/***********************************************/
{
    uint    i;

    eMaker.DumpToExe( (unsigned_16) _cHash);
    eMaker.DumpToExe((unsigned_16) 0);
    unsigned_32  chain_offset = 0;
    for ( i = 0; i < _cHash; i++ ) {
        eMaker.DumpToExe(chain_offset);
        chain_offset += _cTab[i].entries() * (2*LONG_WORD);
    }
    for ( i = 0; i < _cHash; i++ ) {
        eMaker.DumpToExe((unsigned_32) _cTab[i].entries());
    }
    chain_table* currentPtr;
    WCPtrConstSListIter<chain_table> iter;
    for ( i = 0; i < _cHash; i++ ) {
        iter.reset(_cTab[i]);
        while ( ++iter ) {
            currentPtr = iter.current();
            eMaker.DumpToExe(currentPtr -> _offset);
            eMaker.DumpToExe(currentPtr -> _checkSum);
        }
    }
}

bool AddrHashTable::TryToInsert( SymbolStruct* sym )
/**************************************************/
{
    uint seg = sym -> CodeSegment();
    if ( seg == NO_SEGMENT ) {
        seg = sym -> DataSegment();
        if ( seg == NO_SEGMENT ) {
            return FALSE;
        }
    }
    if ( seg > 0 ) {
        --seg; // segments are 1 based.
        _oTab[seg].append( new offset_table(sym->Offset(),sym->MemOffset()));
        return TRUE;
    }
    return FALSE;
}

int AddrHashTable::Compare( const void* op1, const void* op2 )
/************************************************************/
{
    offset_table* otPtr1 = * (offset_table **) op1;
    offset_table* otPtr2 = * (offset_table **) op2;
    if ( otPtr1 -> _memOffset > otPtr2 -> _memOffset ) {
        return 1;
    }
    if ( otPtr1 -> _memOffset < otPtr2 -> _memOffset ) {
        return -1;
    }
    return 0;
}

void AddrHashTable::Put( ExeMaker& eMaker ) const
/***********************************************/
{
    unsigned_32  chain_offset = 0;
    uint         i;
    uint         j;

    eMaker.DumpToExe( (unsigned_16) _cSeg);
    eMaker.DumpToExe((unsigned_16) 0);
    for ( i = 0; i < _cSeg; i++ ) {
        eMaker.DumpToExe(chain_offset);
        chain_offset += _oTab[i].entries() * (2*LONG_WORD);
    }
    for ( i = 0; i < _cSeg; i++ ) {
        eMaker.DumpToExe((unsigned_32) _oTab[i].entries());
    }
    offset_table** tempTable;
    WCPtrConstSListIter<offset_table> iter;
    for ( i = 0; i < _cSeg; i++ ) {
        tempTable = new offset_table* [_oTab[i].entries()];
        iter.reset(_oTab[i]);
        for ( j = 0; ++iter; j++ ) {
            tempTable[j] = iter.current();
        }
        qsort(tempTable,_oTab[i].entries(),sizeof(offset_table*),AddrHashTable::Compare);
        for ( j = 0; j < _oTab[i].entries(); j++ ) {
            eMaker.DumpToExe(tempTable[j] -> _fileOffset);
            eMaker.DumpToExe(tempTable[j] -> _memOffset);
        }
        delete [] tempTable;
    }
}

⌨️ 快捷键说明

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