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