drinit.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 294 行
C
294 行
/****************************************************************************
*
* 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: Initialize DWARF debug info for a module and distil
* the .debug_abbrev section.
*
****************************************************************************/
#include "drpriv.h"
#include "drgettab.h"
#include <string.h>
struct dr_dbg_info *DWRCurrNode = NULL;
/* function prototypes */
static void ReadCUAbbrevTable( struct dr_dbg_info *dbg, compunit_info *compunit )
/*******************************************************************************/
/* this reads in the abbrev. table for a compilation unit, and fills in an
* array of pointers to it.
*/
{
unsigned maxnum;
unsigned sizealloc;
unsigned oldsize;
dr_handle start;
dr_handle finish;
dr_handle *abbrevs;
unsigned code;
compunit_info *cu;
// if a previous compilation unit shares the same table, reuse it
for( cu = &(dbg->compunit); cu != compunit; cu = cu->next ) {
if( cu->abbrev_start == compunit->abbrev_start ) {
compunit->numabbrevs = cu->numabbrevs;
compunit->abbrevs = cu->abbrevs;
compunit->abbrev_refs = cu->abbrev_refs;
++(*compunit->abbrev_refs); // increase abbrevs reference count
return;
}
}
sizealloc = ABBREV_TABLE_GUESS;
abbrevs = DWRALLOC( sizealloc * sizeof(dr_handle) );
memset( abbrevs, 0, sizealloc * sizeof(dr_handle) );
maxnum = 0;
start = dbg->sections[DR_DEBUG_ABBREV].base + compunit->abbrev_start;
finish = dbg->sections[DR_DEBUG_ABBREV].base + dbg->sections[DR_DEBUG_ABBREV].size;
while( start < finish ) {
code = DWRVMReadULEB128( &start );
if( code == 0 ) break; // indicates end of table
if( code > maxnum ) maxnum = code;
if( code >= sizealloc ) {
oldsize = sizealloc;
sizealloc = code + ABBREV_TABLE_INCREMENT;
abbrevs = DWRREALLOC( abbrevs, sizealloc * sizeof(dr_handle) );
memset( &abbrevs[oldsize], 0, (sizealloc - oldsize) * sizeof(dr_handle) );
}
if( abbrevs[code] == 0 ) {
abbrevs[code] = start;
}
DWRVMSkipLEB128( &start ); // skip tag
start++; // skip child indicator
do {
code = DWRVMReadULEB128( &start ); // read attribute
DWRVMSkipLEB128( &start ); // skip form
} while( code != 0 );
}
if( sizealloc > maxnum ) { // reduce size to actual amount needed
/* abbrev[0] not used but we want abbrev[code] = start to work */
abbrevs = DWRREALLOC( abbrevs, (maxnum + 1) * sizeof(dr_handle) );
}
compunit->numabbrevs = maxnum + 1;
compunit->abbrevs = abbrevs;
compunit->abbrev_refs = DWRALLOC( sizeof(unsigned) );
*compunit->abbrev_refs = 1;
}
static dr_dbg_handle InitDbgHandle( void *file, unsigned long *sizes, int byteswap )
/***********************************************************************************/
{
dr_dbg_handle dbg;
int i;
dbg = DWRALLOC( sizeof(struct dr_dbg_info) );
DWRCurrNode = dbg; /* must be set for DWRVMAlloc in virtstub.c */
if( dbg == NULL ) return( NULL );
dbg->next = NULL;
dbg->file = file;
dbg->addr_size = 0;
dbg->wat_version = 0; /* zero means not Watcom DWARF */
dbg->byte_swap = byteswap;
dbg->last_ccu = &dbg->compunit;
for( i = 0; i < DR_DEBUG_NUM_SECTS; i++ ) {
dbg->sections[i].size = *sizes;
if( *sizes != 0 ) {
dbg->sections[i].base = DWRVMAlloc( *sizes, i );
if( dbg->sections[i].base == NULL ) {
DWRFREE( dbg );
return( NULL );
}
} else {
dbg->sections[i].base = NULL;
}
sizes++;
}
return( dbg );
}
extern int DRDbgClear( dr_dbg_handle dbg )
/*****************************************/
{
int ret;
int i;
ret = FALSE;
for( i = 0; i < DR_DEBUG_NUM_SECTS; i++ ) {
DWRVMSwap( dbg->sections[i].base, dbg->sections[i].size, &ret );
}
return( ret );
}
extern void DRDbgDone( dr_dbg_handle dbg )
/****************************************/
{
int i;
for( i = 0; i < DR_DEBUG_NUM_SECTS; i++ ) {
DWRVMSectDone( dbg->sections[i].base, dbg->sections[i].size );
dbg->sections[i].base = 0;
dbg->sections[i].size = 0;
}
}
extern void DRDbgOldVersion( dr_dbg_handle dbg, int version )
/***********************************************************/
{
dbg->wat_version = version;
}
static void ReadCompUnits( struct dr_dbg_info *dbg, int read_ftab )
/*****************************************************************/
{
compunit_info *compunit;
compunit_info *next;
dr_handle start;
dr_handle finish;
unsigned_32 length;
unsigned_32 abbrev_offset;
unsigned_16 version;
unsigned_8 addr_size;
unsigned_8 curr_addr_size;
compunit = &DWRCurrNode->compunit;
start = DWRCurrNode->sections[DR_DEBUG_INFO].base;
finish = start + DWRCurrNode->sections[DR_DEBUG_INFO].size;
addr_size = DWRVMReadByte( start + 10 );
for( ;; ) {
compunit->next = NULL;
compunit->start = start;
length = DWRVMReadDWord( start );
compunit->end = start + length + sizeof(unsigned_32);
version = DWRVMReadWord( start + sizeof(unsigned_32) );
if( version != DWARF_VERSION ) DWREXCEPT( DREXCEP_BAD_DBG_VERSION );
abbrev_offset = DWRVMReadDWord( start + sizeof(unsigned_32) + sizeof(unsigned_16) );
curr_addr_size = DWRVMReadByte( start + 10 );
if( curr_addr_size != addr_size ) {
addr_size = 0;
}
compunit->abbrev_start = abbrev_offset;
ReadCUAbbrevTable( dbg, compunit );
if( read_ftab ) {
DWRInitFileTable( &compunit->filetab );
DWRScanFileTable( start, &FileNameTable, &compunit->filetab );
} else {
compunit->filetab.len = 0;
compunit->filetab.tab = NULL;
}
start += length + sizeof(unsigned_32);
if( start >= finish ) break;
next = DWRALLOC( sizeof(compunit_info) );
compunit->next = next;
compunit = next;
}
DWRCurrNode->addr_size = addr_size;
}
dr_dbg_handle DRDbgInitNFT( void * file, unsigned long * sizes, int byteswap )
/****************************************************************************/
{
dr_dbg_handle dbg;
dbg = InitDbgHandle( file, sizes, byteswap );
if( dbg != NULL ) {
ReadCompUnits( dbg, FALSE );
}
return( dbg );
}
dr_dbg_handle DRDbgInit( void * file, unsigned long * sizes, int byteswap )
/*************************************************************************/
{
dr_dbg_handle dbg;
dbg = InitDbgHandle( file, sizes, byteswap );
if( dbg != NULL ) {
ReadCompUnits( dbg, TRUE );
}
return( dbg );
}
void DRDbgFini( dr_dbg_handle dbg )
/**********************************/
/* don't have a way of deallocating virtual memory space. Assume that any
* pages that are allocated to this module will eventually be swapped out
*/
{
compunit_info *compunit;
compunit_info *next;
compunit = dbg->compunit.next;
while( compunit != NULL ) {
next = compunit->next;
DWRFiniFileTable( &compunit->filetab, FALSE );
if( compunit->abbrevs != NULL ) {
if( --(*compunit->abbrev_refs) == 0 ) {
DWRFREE( compunit->abbrevs );
DWRFREE( compunit->abbrev_refs );
}
compunit->abbrevs = NULL;
compunit->abbrev_refs = NULL;
}
DWRFREE( compunit );
compunit = next;
}
DWRFiniFileTable( &dbg->compunit.filetab, FALSE );
DWRFREE( dbg );
}
dr_dbg_handle DRSetDebug( dr_dbg_handle dbg )
/********************************************/
{
dr_dbg_handle old;
old = DWRCurrNode;
DWRCurrNode = dbg;
return( old );
}
dr_dbg_handle DRGetDebug( void )
/*******************************/
{
return( DWRCurrNode );
}
void DRInit( void )
/*****************/
{
DWRVMInit();
DWRInitFileTable( &FileNameTable.fnametab );
DWRInitFileTable( &FileNameTable.pathtab );
}
void DRFini( void )
/*****************/
{
DWRVMDestroy();
DWRFiniFileTable( &FileNameTable.fnametab, TRUE );
DWRFiniFileTable( &FileNameTable.pathtab, TRUE );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?