mrinfo.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 324 行
CPP
324 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <wcvector.h>
#include <string.h>
#include <wstd.h>
#include <dwarf.h>
#include "dietree.h"
#include "mrcompnt.h"
#include "mrdie.h"
#include "mrfile.h"
#include "mrinfo.h"
#include "mrinfpp.h"
#include "mrabbrev.h"
#include "mrline.h"
#include "mrreloc.h"
static char * MagicCompunitName = "\01\02\03\04Magic Compunit Name";
MergeInfoSection::MergeInfoSection( int numFiles, MergeAbbrevSection& ab,
MergeLineSection& line )
: _abbrevs( ab )
, _line( line )
//---------------------------------------------------------------------------
{
_compunitHdr = new MergeCompunitHdr;
_relocator = new MergeRelocate( numFiles );
_diesByName = new DIETree;
}
MergeInfoSection::~MergeInfoSection()
//-----------------------------------
{
#if INSTRUMENTS
print();
#endif
MergeDIE::ragnarok();
delete _compunitHdr;
delete _relocator;
delete _diesByName;
}
uint_8 MergeInfoSection::getAddrSize()
//------------------------------------
{
return _compunitHdr->_addressSize;
}
#if INSTRUMENTS
void MergeInfoSection::print()
//----------------------------
{
Log.printf( "\nMergeInfoSection\n----------------\n" );
// Log.printf( " _diesByName: %u entries\n", _diesByName->entries() );
}
#endif
void MergeInfoSection::relocPass( MergeInfoPP & post )
//----------------------------------------------------
{
MergeDIE * die;
uint_32 offset = 0;
offset += sizeof( MergeCompunitHdr );
_diesByName->setToStart();
die = _diesByName->next(); // set to first
while( die ) {
if( !die->assigned() ) {
die->setNewOff( this, offset, post );
}
die = _diesByName->next();
}
post.addRequest( MergeOffset( 0, 0 ), offset, 0 );
_compunitHdr->_infoLength = offset - sizeof(uint_32);
_compunitHdr->_infoLength += 1; // for discarded compunit-terminator
}
void MergeInfoSection::writePass( MergeFile * outFile,
WCPtrOrderedVector<MergeFile> & inFiles )
//-------------------------------------------------------------------------
{
uint_32 len;
uint_32 size;
char * block;
const BufSize = 512;
MergeStringHdl::ragnarok();
_diesByName->freeDirectory();
MergeInfoPP postProcess( inFiles.entries() );
relocPass( postProcess );
block = new char [ BufSize ];
memset( block, 0, BufSize );
len = _compunitHdr->_infoLength + sizeof(uint_32);
while( len ) {
size = (BufSize < len) ? BufSize : len;
outFile->writeBlock( block, size );
len -= size;
}
delete [] block;
outFile->seekSect( DR_DEBUG_INFO, 0 );
outFile->writeBlock( _compunitHdr, sizeof(MergeCompunitHdr) );
postProcess.execute( this, *outFile, inFiles );
}
void MergeInfoSection::scanFile( MergeFile * file, uint_8 indx )
//--------------------------------------------------------------
{
uint_32 len;
MergeOffset moff( indx, 0 );
MergeOffset startOff;
len = file->getDRSizes()[ DR_DEBUG_INFO ];
readCompUnitHdr( file, moff );
while( moff.offset < len ) {
readCompUnitHdr( file, moff );
}
}
void MergeInfoSection::readCompUnitHdr( MergeFile * file, MergeOffset& moff )
//---------------------------------------------------------------------------
{
uint_32 abbCode;
MergeOffset startOff;
MergeOffset compunitStart = moff;
file->readBlock( DR_DEBUG_INFO, moff.offset, _compunitHdr,
sizeof( MergeCompunitHdr ) );
#if INSTRUMENTS
Log.printf( "%s: length %lx version %d abbrev %lx address size %hx\n", file->getFileName(), _compunitHdr->_infoLength, _compunitHdr->_version, _compunitHdr->_abbrevIdx, _compunitHdr->_addressSize );
#endif
// read the compunit and all its children
startOff = moff;
abbCode = file->readULEB128( DR_DEBUG_INFO, moff.offset );
readDIE( file, startOff, NULL, moff, abbCode );
// read the compunit terminator
while( moff.offset - compunitStart.offset <
_compunitHdr->_infoLength + sizeof( uint_32 ) ) {
abbCode = file->readULEB128( DR_DEBUG_INFO, moff.offset );
}
}
void MergeInfoSection::readDIE( MergeFile * file, MergeOffset& startOff,
MergeDIE * prt, MergeOffset& moff,
uint_32 abbCode )
//-------------------------------------------------------------------
// read a die and all its children, adding to _dies. return false when
// the abbrev code is zero (recursive)
{
MergeDIE * die; // one we read
MergeAbbrev * abbrev;
MergeOffset child; // offset of first child
MergeOffset sibling;
bool ext = TRUE; // external or static?
bool defn = TRUE; // is a definition?
const char * name = NULL;
int i;
DIELen_T length;
int lenDelta = 0; // delta from changing file idx
if( abbCode == 0 ) {
length = (DIELen_T) (moff.offset - startOff.offset);
MergeNameKey nmKey( abbCode, ext, NULL, 0 );
die = new MergeDIE( prt, startOff, nmKey, child, sibling, defn, length );
die = die->collision( _diesByName );
#if INSTRUMENTS
if( abbrev == NULL ) {
Log.printf( "zoiks! %s\n", startOff.getString() );
}
#endif
return; //<------------------- early return
}
abbrev = _abbrevs.getAbbrev( abbCode );
#if INSTRUMENTS
if( abbrev == NULL ) {
Log.printf( "ABBREV == NULL! offset is %s, %s\n", startOff.getString(), moff.getString() );
}
#endif
InfoAssert( abbrev != NULL ); // NYI throw
for( i = 0; i < abbrev->entries(); i += 1 ) {
MergeAttrib & att( (*abbrev)[ i ] );
switch( att.attrib() ) {
case DW_AT_name:
name = file->readString( DR_DEBUG_INFO, moff.offset );
if( abbrev->tag() == DW_TAG_compile_unit ) {
name = MagicCompunitName;
}
break;
case DW_AT_sibling:
sibling.fileIdx = moff.fileIdx;
sibling.offset = file->readDWord( DR_DEBUG_INFO, moff.offset );
break;
case DW_AT_external:
ext = file->readByte( DR_DEBUG_INFO, moff.offset );
break;
case DW_AT_declaration:
defn = !file->readByte( DR_DEBUG_INFO, moff.offset );
break;
case DW_AT_decl_file:
lenDelta = getFileLenDelta( file, moff, att.form() );
break;
default:
file->skipForm( DR_DEBUG_INFO, moff.offset, att.form(),
getAddrSize() );
}
}
if( abbrev->hasChildren() ) {
child = moff;
}
length = (DIELen_T)(moff.offset - startOff.offset + lenDelta);
MergeNameKey nmKey( abbrev->tag(), ext, name, 0 );
die = new MergeDIE( prt, startOff, nmKey, child, sibling, defn, length );
die = die->collision( _diesByName );
getReloc().addReloc( startOff, die );
if( abbrev->hasChildren() ) {
while( 1 ) {
startOff = moff;
abbCode = file->readULEB128( DR_DEBUG_INFO, moff.offset );
if( abbCode == 0 ) break;
readDIE( file, startOff, die, moff, abbCode );
}
}
if( !die->siblingSet() ) {
die->setSibling( moff );
}
}
int MergeInfoSection::getFileLenDelta( MergeFile * file,
MergeOffset& moff,
uint_32 form )
//-------------------------------------------------------------
{
uint_32 oldIdx;
uint_32 newIdx;
int delta;
switch( form ) {
case DW_FORM_udata:
oldIdx = file->readULEB128( DR_DEBUG_INFO, moff.offset );
break;
case DW_FORM_sdata:
oldIdx = file->readSLEB128( DR_DEBUG_INFO, moff.offset );
break;
default:
InternalAssert( 0 /* unknown form for fileLenDelta */ );
file->skipForm( DR_DEBUG_INFO, moff.offset, form, getAddrSize() );
return 0;
}
newIdx = _line.getNewFileIdx( moff.fileIdx, (uint_16) oldIdx );
delta = MergeFile::ULEB128Len( newIdx );
delta -= MergeFile::ULEB128Len( oldIdx );
#if ( INSTRUMENTS == INSTRUMENTS_FULL_LOGGING )
Log.printf( "FileLenDelta from %x to %x -- %d\n", oldIdx, newIdx, delta );
#endif
return (DIELen_T) delta;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?